From ce5a5b71cb687e2309acce1c5a00150618412582 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Tue, 27 Apr 2021 12:39:27 +0800 Subject: [PATCH] New upstream version 4.4 --- .mailmap | 8 +- Changelog | 377 +- MAINTAINERS | 16 +- Makefile | 12 +- RELEASE | 2 +- RELEASE_NOTES | 6 +- VERSION | 2 +- compat/cuda/cuda_runtime.h | 75 +- configure | 304 +- doc/APIchanges | 128 + doc/Doxyfile | 2 +- doc/bitstream_filters.texi | 57 + doc/codecs.texi | 134 +- doc/decoders.texi | 36 +- doc/dev_community/community.md | 79 + doc/dev_community/resolution_process.md | 91 + doc/encoders.texi | 369 +- doc/examples/decode_video.c | 2 +- doc/examples/demuxing_decoding.c | 25 +- doc/examples/hw_decode.c | 2 +- doc/examples/muxing.c | 45 +- doc/examples/transcode_aac.c | 46 +- doc/examples/transcoding.c | 163 +- doc/examples/vaapi_encode.c | 16 +- doc/examples/vaapi_transcode.c | 42 +- doc/ffmpeg.texi | 199 +- doc/ffplay.texi | 1 + doc/ffprobe.texi | 1 + doc/ffprobe.xsd | 5 - doc/fftools-common-opts.texi | 17 +- doc/filters.texi | 1707 +++- doc/general.texi | 1401 +-- doc/general_contents.texi | 1440 +++ doc/indevs.texi | 61 +- doc/multithreading.txt | 3 +- doc/muxers.texi | 54 +- doc/outdevs.texi | 46 + doc/protocols.texi | 126 +- doc/texi2pod.pl | 9 + doc/utils.texi | 6 +- ffbuild/common.mak | 12 +- fftools/cmdutils.c | 32 +- fftools/cmdutils.h | 2 +- fftools/ffmpeg.c | 643 +- fftools/ffmpeg.h | 35 +- fftools/ffmpeg_filter.c | 51 +- fftools/ffmpeg_opt.c | 179 +- fftools/ffplay.c | 265 +- fftools/ffprobe.c | 215 +- libavcodec/4xm.c | 5 +- libavcodec/8bps.c | 2 +- libavcodec/Makefile | 162 +- libavcodec/a64multienc.c | 13 +- libavcodec/aac.h | 1 + libavcodec/aac_ac3_parser.c | 10 +- libavcodec/aac_ac3_parser.h | 1 + libavcodec/aac_defines.h | 2 + libavcodec/aacdec.c | 5 + libavcodec/aacdec_fixed.c | 5 +- libavcodec/aacdec_template.c | 263 +- libavcodec/aacdectab.h | 23 +- libavcodec/aacenc.c | 44 +- libavcodec/aacenc.h | 2 + libavcodec/aacenctab.c | 4 +- libavcodec/aacenctab.h | 4 +- libavcodec/aacps.c | 384 +- libavcodec/aacps.h | 20 +- libavcodec/aacps_common.c | 336 + libavcodec/aacps_fixed_tablegen.h | 7 +- libavcodec/aacps_tablegen_template.c | 1 + libavcodec/aacpsdata.c | 9 +- libavcodec/aacsbr.c | 2 +- libavcodec/aacsbr_fixed.c | 1 - libavcodec/aacsbr_template.c | 8 +- libavcodec/aacsbrdata.h | 169 +- libavcodec/aactab.c | 77 +- libavcodec/aactab.h | 62 +- libavcodec/aarch64/Makefile | 3 + libavcodec/aarch64/hevcdsp_idct_neon.S | 621 ++ libavcodec/aarch64/hevcdsp_init_aarch64.c | 92 + libavcodec/aarch64/hevcdsp_sao_neon.S | 87 + libavcodec/aarch64/neontest.c | 32 +- .../vp9dsp_init_16bpp_aarch64_template.c | 1 + libavcodec/aarch64/vp9dsp_init_aarch64.c | 1 + libavcodec/ac3.h | 1 - libavcodec/ac3dec.c | 16 +- libavcodec/ac3dec.h | 2 + libavcodec/ac3dec_fixed.c | 4 +- libavcodec/ac3dec_float.c | 8 +- libavcodec/ac3dsp.c | 62 +- libavcodec/ac3dsp.h | 47 - libavcodec/ac3enc.c | 239 +- libavcodec/ac3enc.h | 52 +- libavcodec/ac3enc_fixed.c | 73 +- libavcodec/ac3enc_float.c | 32 +- libavcodec/ac3enc_template.c | 84 +- libavcodec/ac3tab.c | 71 +- libavcodec/ac3tab.h | 11 +- libavcodec/acelp_pitch_delay.c | 41 - libavcodec/acelp_pitch_delay.h | 45 +- libavcodec/acelp_vectors.c | 11 - libavcodec/acelp_vectors.h | 1 - libavcodec/adpcm.c | 241 +- libavcodec/adpcm.h | 4 +- libavcodec/adpcm_data.c | 12 + libavcodec/adpcmenc.c | 335 +- libavcodec/adxdec.c | 19 +- libavcodec/agm.c | 4 +- libavcodec/aic.c | 2 + libavcodec/alac.c | 19 +- libavcodec/alacenc.c | 22 +- libavcodec/allcodecs.c | 29 +- libavcodec/alsdec.c | 8 +- libavcodec/amfenc.c | 57 +- libavcodec/amfenc.h | 5 +- libavcodec/amfenc_h264.c | 5 +- libavcodec/amfenc_hevc.c | 9 +- libavcodec/amrnbdata.h | 5 - libavcodec/amrnbdec.c | 2 +- libavcodec/amrwbdec.c | 2 +- libavcodec/apedec.c | 81 +- libavcodec/argo.c | 740 ++ libavcodec/arm/Makefile | 9 +- libavcodec/arm/ac3dsp_init_arm.c | 9 - libavcodec/arm/neontest.c | 32 +- libavcodec/arm/sbcdsp_init_arm.c | 1 + .../arm/vp9dsp_init_16bpp_arm_template.c | 1 + libavcodec/arm/vp9dsp_init_arm.c | 1 + libavcodec/ass_split.c | 2 +- libavcodec/asv.c | 46 +- libavcodec/asv.h | 4 +- libavcodec/asvdec.c | 112 +- libavcodec/asvenc.c | 41 +- libavcodec/atrac.c | 27 +- libavcodec/atrac1.c | 20 +- libavcodec/atrac3.c | 64 +- libavcodec/atrac3data.h | 104 +- libavcodec/atrac3plus.c | 163 +- libavcodec/atrac3plus.h | 6 +- libavcodec/atrac3plus_data.h | 1671 ++- libavcodec/atrac3plusdec.c | 19 +- libavcodec/atrac3plusdsp.c | 10 +- libavcodec/atrac9dec.c | 129 +- libavcodec/atrac9tab.h | 2124 ++-- libavcodec/atsc_a53.c | 119 + libavcodec/atsc_a53.h | 56 + libavcodec/audiotoolboxdec.c | 9 +- libavcodec/audiotoolboxenc.c | 2 +- libavcodec/av1.h | 8 + libavcodec/av1_frame_merge_bsf.c | 29 +- libavcodec/av1_frame_split_bsf.c | 12 +- libavcodec/av1_metadata_bsf.c | 179 +- libavcodec/av1_parse.h | 5 +- libavcodec/av1_parser.c | 46 +- libavcodec/av1dec.c | 1158 +++ libavcodec/av1dec.h | 88 + libavcodec/avcodec.c | 851 ++ libavcodec/avcodec.h | 186 +- libavcodec/avpacket.c | 160 +- libavcodec/avrndec.c | 75 +- libavcodec/avs2_parser.c | 16 +- libavcodec/avs3.h | 118 + libavcodec/avs3_parser.c | 179 + libavcodec/bink.c | 37 +- libavcodec/binkaudio.c | 26 +- libavcodec/bitpacked.c | 6 +- libavcodec/bitstream.c | 184 +- libavcodec/bitstream_filters.c | 15 + libavcodec/bmvaudio.c | 2 +- libavcodec/bsf.c | 42 +- libavcodec/bsf.h | 2 +- libavcodec/bsf_internal.h | 4 + libavcodec/bytestream.h | 6 +- libavcodec/c93.c | 6 +- libavcodec/cabac.c | 13 +- libavcodec/cabac.h | 5 - libavcodec/cabac_functions.h | 1 + libavcodec/cavs.c | 2 + libavcodec/cavs.h | 2 + libavcodec/cavsdec.c | 2 +- libavcodec/cbs.c | 382 +- libavcodec/cbs.h | 79 +- libavcodec/cbs_av1.c | 196 +- libavcodec/cbs_av1.h | 83 +- libavcodec/cbs_av1_syntax_template.c | 164 +- libavcodec/cbs_bsf.c | 159 + libavcodec/cbs_bsf.h | 131 + libavcodec/cbs_h264.h | 97 +- libavcodec/cbs_h2645.c | 650 +- libavcodec/cbs_h264_syntax_template.c | 271 +- libavcodec/cbs_h265.h | 85 +- libavcodec/cbs_h265_syntax_template.c | 393 +- libavcodec/cbs_internal.h | 95 + libavcodec/cbs_jpeg.c | 10 +- libavcodec/cbs_jpeg.h | 2 +- libavcodec/cbs_mpeg2.c | 74 +- libavcodec/cbs_mpeg2.h | 10 +- libavcodec/cbs_sei.c | 369 + libavcodec/cbs_sei.h | 199 + libavcodec/cbs_sei_syntax_template.c | 322 + libavcodec/cbs_vp9.c | 31 +- libavcodec/cbs_vp9.h | 2 +- libavcodec/ccaption_dec.c | 294 +- libavcodec/cdgraphics.c | 13 + libavcodec/cdtoons.c | 1 + libavcodec/cdxl.c | 31 +- libavcodec/celp_math.c | 2 + libavcodec/cfhd.c | 1260 ++- libavcodec/cfhd.h | 95 +- libavcodec/cfhddsp.c | 118 + libavcodec/cfhddsp.h | 44 + libavcodec/cfhdenc.c | 866 ++ libavcodec/cfhdencdsp.c | 79 + libavcodec/cfhdencdsp.h | 41 + libavcodec/cinepak.c | 3 +- libavcodec/cinepakenc.c | 36 +- libavcodec/clearvideo.c | 289 +- libavcodec/clearvideodata.h | 2412 ++--- libavcodec/cljrdec.c | 1 + libavcodec/cllc.c | 25 +- libavcodec/cngdec.c | 2 +- libavcodec/cngenc.c | 9 +- libavcodec/codec.h | 50 +- libavcodec/codec2utils.c | 10 +- libavcodec/codec2utils.h | 21 +- libavcodec/codec_desc.c | 111 +- libavcodec/codec_id.h | 15 + libavcodec/codec_par.c | 202 + libavcodec/cook.c | 46 +- libavcodec/cookdata.h | 556 +- libavcodec/cpia.c | 1 + libavcodec/cri.c | 438 + libavcodec/cri_parser.c | 105 + libavcodec/crystalhd.c | 2 - libavcodec/cuviddec.c | 33 +- libavcodec/dca_core.h | 2 +- libavcodec/dca_lbr.c | 1 + libavcodec/dca_lbr.h | 2 +- libavcodec/dca_xll.h | 2 +- libavcodec/dcadata.c | 2 +- libavcodec/dcadsp.c | 3 +- libavcodec/dcaenc.c | 9 +- libavcodec/decode.c | 434 +- libavcodec/decode.h | 11 +- libavcodec/dirac_arith.c | 6 +- libavcodec/dirac_arith.h | 1 - libavcodec/dirac_vlc.c | 10 +- libavcodec/diracdec.c | 1 + libavcodec/diracdsp.c | 2 +- libavcodec/dnxhddata.c | 46 +- libavcodec/dnxhddata.h | 4 +- libavcodec/dnxhddec.c | 15 +- libavcodec/dnxhdenc.c | 74 +- libavcodec/dnxhdenc.h | 2 + libavcodec/dolby_e.c | 817 +- libavcodec/dolby_e.h | 636 +- libavcodec/dolby_e_parse.c | 180 + libavcodec/dolby_e_parser.c | 69 + libavcodec/dpx.c | 289 +- libavcodec/dsd.c | 8 +- libavcodec/dsddec.c | 9 +- libavcodec/dsicinaudio.c | 2 +- libavcodec/dsicinvideo.c | 1 - libavcodec/dss_sp.c | 3 +- libavcodec/dstdec.c | 2 + libavcodec/dv_profile.c | 10 +- libavcodec/dvbsub_parser.c | 18 +- libavcodec/dvbsubdec.c | 137 +- libavcodec/dvbsubenc.c | 515 + libavcodec/dvdec.c | 1 + libavcodec/dvdsub_parser.c | 6 - libavcodec/dvdsubenc.c | 25 +- libavcodec/dvenc.c | 24 +- libavcodec/dxa.c | 2 +- libavcodec/dxtory.c | 365 +- libavcodec/dxva2.c | 10 +- libavcodec/dxva2_av1.c | 506 + libavcodec/dynamic_hdr10_plus.c | 198 + libavcodec/dynamic_hdr10_plus.h | 35 + libavcodec/eac3enc.c | 10 +- libavcodec/eacmv.c | 6 +- libavcodec/eamad.c | 3 + libavcodec/eatgq.c | 3 + libavcodec/eatqi.c | 3 + libavcodec/encode.c | 878 +- libavcodec/encode.h | 53 + libavcodec/escape130.c | 4 +- libavcodec/evrcdec.c | 2 +- libavcodec/exif.c | 19 +- libavcodec/exr.c | 1070 +- libavcodec/exrenc.c | 552 + libavcodec/extract_extradata_bsf.c | 24 +- libavcodec/fastaudio.c | 202 + libavcodec/faxcompr.c | 13 +- libavcodec/fft-internal.h | 29 +- libavcodec/fft.h | 28 +- libavcodec/fft_init_table.c | 24 +- libavcodec/fft_table.h | 2 +- libavcodec/fft_template.c | 28 +- libavcodec/ffv1.c | 22 +- libavcodec/ffv1dec.c | 6 +- libavcodec/ffv1enc.c | 1 + libavcodec/ffwavesynth.c | 16 +- libavcodec/fic.c | 1 + libavcodec/filter_units_bsf.c | 8 +- libavcodec/fitsdec.c | 2 +- libavcodec/flacdec.c | 14 +- libavcodec/flacenc.c | 1 + libavcodec/flashsv.c | 2 +- libavcodec/flashsv2enc.c | 101 +- libavcodec/flashsvenc.c | 13 +- libavcodec/float2half.h | 67 + libavcodec/flvenc.c | 2 +- libavcodec/fmvc.c | 2 + libavcodec/frame_thread_encoder.c | 127 +- libavcodec/frame_thread_encoder.h | 3 +- libavcodec/fraps.c | 4 + libavcodec/g2meet.c | 47 +- libavcodec/g722dec.c | 2 +- libavcodec/g722enc.c | 32 +- libavcodec/g723_1.c | 1099 +- libavcodec/g723_1.h | 1195 +-- libavcodec/g723_1dec.c | 84 +- libavcodec/g723_1enc.c | 70 +- libavcodec/g726.c | 4 +- libavcodec/gdv.c | 5 +- libavcodec/gif.c | 99 +- libavcodec/golomb.h | 12 +- libavcodec/gsmdec.c | 4 +- libavcodec/h261.c | 13 - libavcodec/h261.h | 3 - libavcodec/h261dec.c | 49 +- libavcodec/h261enc.c | 21 +- libavcodec/h263.h | 2 + libavcodec/h263data.c | 16 +- libavcodec/h263data.h | 2 +- libavcodec/h263dec.c | 5 +- libavcodec/h2645_parse.c | 32 +- libavcodec/h264_cavlc.c | 161 +- libavcodec/h264_direct.c | 2 +- libavcodec/h264_levels.c | 12 - libavcodec/h264_levels.h | 3 - libavcodec/h264_loopfilter.c | 1 + libavcodec/h264_metadata_bsf.c | 595 +- libavcodec/h264_mvpred.h | 1 + libavcodec/h264_parse.c | 4 +- libavcodec/h264_ps.c | 24 +- libavcodec/h264_redundant_pps_bsf.c | 114 +- libavcodec/h264_sei.c | 131 +- libavcodec/h264_sei.h | 20 +- libavcodec/h264_slice.c | 176 +- libavcodec/h264dec.c | 84 +- libavcodec/h264dec.h | 1 + libavcodec/h265_metadata_bsf.c | 193 +- libavcodec/h265_profile_level.c | 12 - libavcodec/h265_profile_level.h | 2 - libavcodec/half2float.h | 74 + libavcodec/hca_data.h | 14 +- libavcodec/hcadec.c | 6 +- libavcodec/hcom.c | 9 +- libavcodec/hevc_cabac.c | 15 +- libavcodec/hevc_mvs.c | 4 +- libavcodec/hevc_parser.c | 2 +- libavcodec/hevc_ps.c | 2 +- libavcodec/hevc_ps_enc.c | 3 +- libavcodec/hevc_sei.c | 240 +- libavcodec/hevc_sei.h | 66 +- libavcodec/hevcdec.c | 218 +- libavcodec/hevcdec.h | 12 +- libavcodec/hevcdsp.c | 2 + libavcodec/hevcdsp.h | 3 + libavcodec/hevcpred_template.c | 2 +- libavcodec/hnm4video.c | 21 +- libavcodec/hq_hqa.h | 2 + libavcodec/hq_hqadata.c | 6 +- libavcodec/hqx.c | 6 +- libavcodec/hqx.h | 4 +- libavcodec/hqxvlc.c | 2 +- libavcodec/hwaccels.h | 5 + libavcodec/idcinvideo.c | 3 +- libavcodec/iirfilter.c | 15 +- libavcodec/ilbcdata.h | 4 - libavcodec/ilbcdec.c | 2 +- libavcodec/imc.c | 64 +- libavcodec/imcdata.h | 66 +- libavcodec/imgconvert.c | 6 +- libavcodec/imm4.c | 103 +- libavcodec/imm5.c | 4 +- libavcodec/imx.c | 197 + libavcodec/indeo2.c | 29 +- libavcodec/indeo2data.h | 67 +- libavcodec/indeo3.c | 7 +- libavcodec/indeo4.c | 1 + libavcodec/indeo5.c | 2 + libavcodec/internal.h | 46 +- libavcodec/interplayvideo.c | 13 +- libavcodec/intrax8.c | 100 +- libavcodec/intrax8huf.h | 1670 ++- libavcodec/ipu_parser.c | 77 + libavcodec/ituh263dec.c | 15 +- libavcodec/ituh263enc.c | 23 +- libavcodec/ivi.c | 39 +- libavcodec/j2kenc.c | 848 +- libavcodec/jpeg2000.c | 30 +- libavcodec/jpeg2000.h | 19 +- libavcodec/jpeg2000dec.c | 233 +- libavcodec/jpegls.h | 6 +- libavcodec/jpeglsdec.c | 5 +- libavcodec/jpeglsenc.c | 197 +- libavcodec/jpegtables.c | 32 - libavcodec/jpegtables.h | 4 - libavcodec/kmvc.c | 2 +- libavcodec/lcldec.c | 8 +- libavcodec/libaomdec.c | 11 +- libavcodec/libaomenc.c | 237 +- libavcodec/libcodec2.c | 18 +- libavcodec/libdav1d.c | 89 +- libavcodec/libdavs2.c | 4 +- libavcodec/libgsmdec.c | 4 +- libavcodec/libilbc.c | 19 +- libavcodec/libkvazaar.c | 45 +- libavcodec/libopencore-amr.c | 4 +- libavcodec/libopenh264enc.c | 16 +- libavcodec/libopusdec.c | 2 +- libavcodec/libopusenc.c | 11 +- libavcodec/librav1e.c | 96 +- libavcodec/libspeexdec.c | 2 +- libavcodec/libsvtav1.c | 572 ++ libavcodec/libuavs3d.c | 263 + libavcodec/libvorbisdec.c | 2 +- libavcodec/libvorbisenc.c | 13 +- libavcodec/libvpxdec.c | 9 +- libavcodec/libvpxenc.c | 139 +- libavcodec/libx264.c | 99 +- libavcodec/libx265.c | 7 +- libavcodec/libxavs.c | 3 +- libavcodec/libxavs2.c | 9 +- libavcodec/libxvid.c | 20 +- libavcodec/ljpegenc.c | 7 +- libavcodec/loco.c | 1 + libavcodec/lpc.c | 1 + libavcodec/lscrdec.c | 279 + libavcodec/lzw.h | 6 +- libavcodec/lzwenc.c | 28 +- libavcodec/magicyuv.c | 261 +- libavcodec/magicyuvenc.c | 50 +- libavcodec/mdct15.h | 2 + libavcodec/mdec.c | 5 +- libavcodec/me_cmp.c | 24 +- libavcodec/me_cmp.h | 2 - libavcodec/mediacodec_wrapper.c | 132 +- libavcodec/mediacodecdec.c | 15 +- libavcodec/metasound.c | 14 +- libavcodec/metasound_data.c | 481 +- libavcodec/metasound_data.h | 9 +- libavcodec/mfenc.c | 63 +- libavcodec/mimic.c | 84 +- libavcodec/mips/Makefile | 3 +- libavcodec/mips/aacdec_mips.c | 2 +- libavcodec/mips/aacpsdsp_mips.c | 13 +- libavcodec/mips/aacpsy_mips.h | 14 +- libavcodec/mips/aacsbr_mips.c | 3 +- libavcodec/mips/blockdsp_init_mips.c | 46 +- libavcodec/mips/cabac.h | 4 +- libavcodec/mips/compute_antialias_fixed.h | 3 +- libavcodec/mips/compute_antialias_float.h | 2 +- libavcodec/mips/constants.c | 2 +- libavcodec/mips/fft_mips.c | 16 +- libavcodec/mips/h263dsp_init_mips.c | 18 +- libavcodec/mips/h264chroma_init_mips.c | 61 +- libavcodec/mips/h264dsp_init_mips.c | 227 +- libavcodec/mips/h264dsp_mips.h | 42 +- libavcodec/mips/h264dsp_mmi.c | 57 +- libavcodec/mips/h264dsp_msa.c | 94 +- libavcodec/mips/h264pred_init_mips.c | 231 +- libavcodec/mips/h264pred_mmi.c | 8 +- libavcodec/mips/h264qpel_init_mips.c | 436 +- libavcodec/mips/hevcdsp_init_mips.c | 996 +- libavcodec/mips/hevcpred_init_mips.c | 40 +- libavcodec/mips/hpeldsp_init_mips.c | 180 +- libavcodec/mips/idctdsp_init_mips.c | 80 +- libavcodec/mips/me_cmp_init_mips.c | 58 +- libavcodec/mips/mpegaudiodsp_mips_float.c | 492 +- libavcodec/mips/mpegvideo_init_mips.c | 54 +- libavcodec/mips/mpegvideoencdsp_init_mips.c | 21 +- libavcodec/mips/pixblockdsp_init_mips.c | 71 +- libavcodec/mips/qpeldsp_init_mips.c | 280 +- libavcodec/mips/sbrdsp_mips.c | 19 +- libavcodec/mips/simple_idct_mmi.c | 1 + libavcodec/mips/vc1dsp_init_mips.c | 186 +- libavcodec/mips/vc1dsp_mmi.c | 3 + libavcodec/mips/videodsp_init.c | 10 +- libavcodec/mips/vp3dsp_init_mips.c | 50 +- libavcodec/mips/vp8dsp_init_mips.c | 240 +- libavcodec/mips/vp8dsp_mmi.c | 1 + libavcodec/mips/vp9dsp_init_mips.c | 16 +- libavcodec/mips/wmv2dsp_init_mips.c | 18 +- libavcodec/mips/wmv2dsp_mips.h | 4 +- libavcodec/mips/wmv2dsp_mmi.c | 4 +- libavcodec/mips/xvid_idct_mmi.c | 6 +- libavcodec/mips/xvididct_init_mips.c | 33 +- libavcodec/mips/xvididct_mips.h | 4 +- libavcodec/mjpegbdec.c | 2 +- libavcodec/mjpegdec.c | 284 +- libavcodec/mjpegdec.h | 25 +- libavcodec/mjpegdec_common.c | 57 + libavcodec/mjpegenc.c | 201 +- libavcodec/mjpegenc.h | 1 + libavcodec/mjpegenc_common.c | 211 +- libavcodec/mjpegenc_common.h | 8 +- libavcodec/mlp.c | 17 +- libavcodec/mlpdec.c | 29 +- libavcodec/mlpenc.c | 62 +- libavcodec/mmaldec.c | 5 +- libavcodec/mobiclip.c | 1355 +++ libavcodec/motion_est.c | 58 +- libavcodec/motion_est.h | 4 +- libavcodec/motion_est_template.c | 19 +- libavcodec/motionpixels.c | 54 +- libavcodec/motionpixels_tablegen.h | 3 +- libavcodec/movtextdec.c | 284 +- libavcodec/movtextenc.c | 310 +- libavcodec/mpc.c | 5 - libavcodec/mpc.h | 2 +- libavcodec/mpc7.c | 91 +- libavcodec/mpc7data.h | 194 +- libavcodec/mpc8.c | 174 +- libavcodec/mpc8huff.h | 670 +- libavcodec/mpeg12.c | 67 +- libavcodec/mpeg12.h | 7 +- libavcodec/mpeg12dec.c | 273 +- libavcodec/mpeg12enc.c | 172 +- libavcodec/mpeg12vlc.h | 2 +- libavcodec/mpeg2_metadata_bsf.c | 96 +- libavcodec/mpeg4audio.c | 23 +- libavcodec/mpeg4audio.h | 4 +- libavcodec/mpeg4data.h | 150 +- libavcodec/mpeg4video.h | 12 +- libavcodec/mpeg4videodec.c | 440 +- libavcodec/mpeg4videoenc.c | 11 +- libavcodec/mpegaudio_tablegen.c | 3 +- libavcodec/mpegaudio_tablegen.h | 40 +- libavcodec/mpegaudiodata.h | 39 + libavcodec/mpegaudiodec_common.c | 482 + libavcodec/mpegaudiodec_common_tablegen.c | 40 + libavcodec/mpegaudiodec_common_tablegen.h | 72 + libavcodec/mpegaudiodec_fixed.c | 40 +- libavcodec/mpegaudiodec_float.c | 57 +- libavcodec/mpegaudiodec_template.c | 325 +- libavcodec/mpegaudiodsp.c | 57 +- libavcodec/mpegaudiodsp.h | 8 +- libavcodec/mpegaudiodsp_template.c | 54 +- libavcodec/mpegpicture.c | 53 +- libavcodec/mpegpicture.h | 1 + libavcodec/mpegutils.c | 128 - libavcodec/mpegutils.h | 1 + libavcodec/mpegvideo.c | 307 +- libavcodec/mpegvideo.h | 20 +- libavcodec/mpegvideo_enc.c | 265 +- libavcodec/mpegvideo_motion.c | 132 +- libavcodec/mqc.h | 3 - libavcodec/mqcenc.c | 5 - libavcodec/mscc.c | 2 +- libavcodec/msmpeg4.h | 4 +- libavcodec/msmpeg4data.c | 6 +- libavcodec/msmpeg4data.h | 2 +- libavcodec/msmpeg4dec.c | 44 +- libavcodec/msmpeg4enc.c | 31 +- libavcodec/msp2dec.c | 103 + libavcodec/msrle.c | 2 +- libavcodec/mss12.c | 17 +- libavcodec/mss3.c | 10 +- libavcodec/mss4.c | 135 +- libavcodec/msvideo1.c | 2 +- libavcodec/mv30.c | 15 +- libavcodec/mxpegdec.c | 6 +- libavcodec/nellymoserdec.c | 21 +- libavcodec/nellymoserenc.c | 57 +- libavcodec/notchlc.c | 95 +- libavcodec/nvdec.c | 51 +- libavcodec/nvdec.h | 4 + libavcodec/nvdec_av1.c | 352 + libavcodec/nvenc.c | 234 +- libavcodec/nvenc.h | 35 +- libavcodec/nvenc_h264.c | 58 +- libavcodec/nvenc_hevc.c | 47 +- libavcodec/on2avc.c | 46 +- libavcodec/on2avcdata.c | 8976 ++++------------- libavcodec/on2avcdata.h | 15 +- libavcodec/options.c | 18 + libavcodec/options_table.h | 65 +- libavcodec/opus.h | 25 +- libavcodec/opus_celt.h | 1 + libavcodec/opus_pvq.h | 2 + libavcodec/opusdec.c | 143 +- libavcodec/opusenc.c | 1 + libavcodec/opusenc_psy.h | 2 + libavcodec/opustab.c | 16 +- libavcodec/opustab.h | 3 +- libavcodec/packet.h | 64 +- libavcodec/packet_internal.h | 46 + libavcodec/pafaudio.c | 1 + libavcodec/pafvideo.c | 5 +- libavcodec/parser.c | 6 +- libavcodec/parsers.c | 20 +- libavcodec/pcm-bluray.c | 2 +- libavcodec/pcm-dvd.c | 22 +- libavcodec/pcm-dvdenc.c | 7 +- libavcodec/pcm.c | 60 +- libavcodec/pgxdec.c | 168 + libavcodec/photocd.c | 473 + libavcodec/pixlet.c | 36 +- libavcodec/png.h | 5 + libavcodec/pngdec.c | 512 +- libavcodec/pngenc.c | 2 +- libavcodec/pnm.c | 8 +- libavcodec/pnm_parser.c | 2 +- libavcodec/pnmdec.c | 24 + libavcodec/pnmenc.c | 49 +- libavcodec/ppc/h264chroma_template.c | 2 +- libavcodec/ppc/h264dsp.c | 2 +- libavcodec/ppc/h264qpel.c | 1 + libavcodec/ppc/mpegaudiodsp_altivec.c | 1 + libavcodec/ppc/mpegvideo_altivec.c | 1 + libavcodec/ppc/mpegvideodsp.c | 2 +- libavcodec/ppc/vp8dsp_altivec.c | 2 +- libavcodec/profiles.c | 6 + libavcodec/profiles.h | 6 + libavcodec/proresdec2.c | 20 +- libavcodec/proresenc_anatoliy.c | 20 +- libavcodec/proresenc_kostya.c | 1 + libavcodec/pthread.c | 2 +- libavcodec/pthread_frame.c | 398 +- libavcodec/pthread_slice.c | 2 +- libavcodec/put_bits.h | 149 +- libavcodec/qcelpdec.c | 2 +- libavcodec/qdm2.c | 22 +- libavcodec/qdm2_tablegen.h | 165 +- libavcodec/qdm2data.h | 240 +- libavcodec/qdmc.c | 148 +- libavcodec/qpeg.c | 13 +- libavcodec/qsv.c | 7 +- libavcodec/qsv_internal.h | 2 + libavcodec/qsvdec.c | 316 +- libavcodec/qsvenc.c | 14 +- libavcodec/qsvenc.h | 2 +- libavcodec/qsvenc_h264.c | 1 + libavcodec/qsvenc_hevc.c | 2 + libavcodec/qtrle.c | 3 +- libavcodec/qtrleenc.c | 23 +- libavcodec/ra144.h | 3 + libavcodec/ra144dec.c | 2 +- libavcodec/ra144enc.c | 5 +- libavcodec/ra288.c | 27 +- libavcodec/ra288.h | 1 + libavcodec/ralf.c | 3 +- libavcodec/rangecoder.c | 19 - libavcodec/rangecoder.h | 9 - libavcodec/rasc.c | 14 +- libavcodec/raw.c | 1 + libavcodec/rawdec.c | 4 +- libavcodec/rkmppdec.c | 2 +- libavcodec/rl.c | 53 +- libavcodec/rl.h | 19 +- libavcodec/roqaudioenc.c | 10 +- libavcodec/roqvideo.h | 29 +- libavcodec/roqvideodec.c | 70 +- libavcodec/roqvideoenc.c | 487 +- libavcodec/rpzaenc.c | 858 ++ libavcodec/rscc.c | 2 +- libavcodec/rtjpeg.h | 2 +- libavcodec/rv10.c | 258 +- libavcodec/rv10enc.c | 2 +- libavcodec/rv34.c | 131 +- libavcodec/rv34.h | 2 + libavcodec/rv34data.h | 21 +- libavcodec/rv40.c | 83 +- libavcodec/rv40vlc2.h | 1139 +-- libavcodec/s302m.c | 3 +- libavcodec/sbc.h | 1 + libavcodec/sbc_parser.c | 2 - libavcodec/sbcdec.c | 3 +- libavcodec/sbcdsp.h | 2 + libavcodec/sbcdsp_data.c | 2 + libavcodec/sbr.h | 3 + libavcodec/scpr3.c | 24 +- libavcodec/sei.h | 140 + libavcodec/setts_bsf.c | 221 + libavcodec/sga.c | 534 + libavcodec/sgidec.c | 1 + libavcodec/sgienc.c | 17 +- libavcodec/sgirledec.c | 1 + libavcodec/sheervideo.c | 516 +- libavcodec/sheervideodata.h | 1166 +-- libavcodec/shorten.c | 6 +- libavcodec/sinewin.c | 1 - libavcodec/sinewin.h | 20 +- libavcodec/sinewin_fixed_tablegen.c | 22 +- libavcodec/sinewin_fixed_tablegen.h | 67 + libavcodec/sinewin_tablegen.c | 25 +- libavcodec/sinewin_tablegen.h | 78 +- libavcodec/sipr.c | 3 +- libavcodec/sipr.h | 2 +- libavcodec/siren.c | 30 +- libavcodec/smacker.c | 372 +- libavcodec/smc.c | 3 +- libavcodec/snow.c | 44 +- libavcodec/snowdec.c | 13 +- libavcodec/snowenc.c | 5 + libavcodec/sonic.c | 83 +- libavcodec/sp5x.h | 92 +- libavcodec/sp5xdec.c | 39 +- libavcodec/speedhq.c | 160 +- libavcodec/speedhqenc.c | 308 + libavcodec/speedhqenc.h | 48 + libavcodec/srtdec.c | 3 +- libavcodec/svq1_cb.h | 2 +- libavcodec/svq1dec.c | 75 +- libavcodec/svq1enc.c | 8 +- libavcodec/svq1enc.h | 1 + libavcodec/svq3.c | 81 +- libavcodec/takdec.c | 3 +- libavcodec/tdsc.c | 29 +- libavcodec/tests/avpacket.c | 19 +- libavcodec/tests/cabac.c | 93 +- libavcodec/tests/dct.c | 1 + libavcodec/tests/rangecoder.c | 28 +- libavcodec/tests/x86/dct.c | 2 + libavcodec/thread.h | 6 +- libavcodec/tiff.c | 434 +- libavcodec/tiff_common.h | 20 - libavcodec/tiff_data.h | 1841 +++- libavcodec/tiffenc.c | 4 +- libavcodec/tmv.c | 1 + libavcodec/trace_headers_bsf.c | 6 +- libavcodec/truemotion1.c | 5 +- libavcodec/truemotion2.c | 104 +- libavcodec/truespeech.c | 2 + libavcodec/tscc.c | 2 +- libavcodec/tscc2.c | 93 +- libavcodec/tscc2data.h | 1249 +-- libavcodec/tta.c | 2 +- libavcodec/ttmlenc.c | 210 + libavcodec/ttmlenc.h | 28 + libavcodec/twinvq.c | 26 +- libavcodec/twinvq_data.h | 790 -- libavcodec/twinvqdec.c | 19 +- libavcodec/ulti.c | 1 + libavcodec/utils.c | 1268 +-- libavcodec/utvideo.h | 13 - libavcodec/utvideodec.c | 110 +- libavcodec/utvideoenc.c | 25 +- libavcodec/v308enc.c | 6 - libavcodec/v408enc.c | 7 - libavcodec/v4l2_buffers.c | 8 +- libavcodec/v4l2_context.c | 2 +- libavcodec/v4l2_m2m.c | 27 +- libavcodec/v4l2_m2m.h | 3 + libavcodec/v4l2_m2m_dec.c | 47 +- libavcodec/v4l2_m2m_enc.c | 20 +- libavcodec/vaapi_av1.c | 319 + libavcodec/vaapi_decode.c | 6 + libavcodec/vaapi_encode.c | 363 +- libavcodec/vaapi_encode.h | 22 +- libavcodec/vaapi_encode_h264.c | 104 +- libavcodec/vaapi_encode_h265.c | 148 +- libavcodec/vaapi_encode_mjpeg.c | 17 +- libavcodec/vaapi_encode_mpeg2.c | 30 +- libavcodec/vaapi_encode_vp8.c | 4 +- libavcodec/vaapi_encode_vp9.c | 4 +- libavcodec/vb.c | 6 +- libavcodec/vble.c | 1 - libavcodec/vc1.c | 32 +- libavcodec/vc1_block.c | 12 - libavcodec/vc1dec.c | 26 +- libavcodec/vc2enc.c | 23 +- libavcodec/vdpau.c | 4 + libavcodec/vdpau_hevc.c | 89 +- libavcodec/version.h | 39 +- libavcodec/videotoolbox.c | 8 +- libavcodec/videotoolboxenc.c | 144 +- libavcodec/vima.c | 2 +- libavcodec/vlc.h | 88 +- libavcodec/vmdvideo.c | 19 +- libavcodec/vorbis.h | 1 - libavcodec/vorbis_data.c | 14 +- libavcodec/vorbisdec.c | 2 +- libavcodec/vp3.c | 331 +- libavcodec/vp3data.h | 3174 +----- libavcodec/vp4data.h | 1556 ++- libavcodec/vp56.h | 2 + libavcodec/vp8.c | 12 +- libavcodec/vp8.h | 1 + libavcodec/vp8data.h | 6 - libavcodec/vp9.c | 11 +- libavcodec/vp9_metadata_bsf.c | 61 +- libavcodec/vp9dec.h | 1 + libavcodec/vp9dsp.c | 2 + libavcodec/vp9recon.c | 1 + libavcodec/wavpack.c | 12 +- libavcodec/wavpack.h | 45 +- libavcodec/wavpackdata.c | 60 + libavcodec/wavpackenc.c | 4 +- libavcodec/webp.c | 79 +- libavcodec/wma.c | 8 +- libavcodec/wma.h | 4 +- libavcodec/wmadata.h | 20 +- libavcodec/wmadec.c | 20 +- libavcodec/wmaenc.c | 4 +- libavcodec/wmalosslessdec.c | 5 +- libavcodec/wmaprodec.c | 6 +- libavcodec/wmavoice.c | 17 +- libavcodec/wmv2.h | 2 + libavcodec/wmv2dec.c | 21 +- libavcodec/wnv1.c | 88 +- libavcodec/ws-snd1.c | 3 +- libavcodec/x86/Makefile | 4 + libavcodec/x86/ac3dsp.asm | 258 - libavcodec/x86/ac3dsp_init.c | 52 +- libavcodec/x86/cabac.h | 2 + libavcodec/x86/cavsdsp.c | 1 + libavcodec/x86/cfhddsp.asm | 697 ++ libavcodec/x86/cfhddsp_init.c | 52 + libavcodec/x86/cfhdencdsp.asm | 432 + libavcodec/x86/cfhdencdsp_init.c | 48 + libavcodec/x86/constants.c | 3 +- libavcodec/x86/diracdsp_init.c | 102 +- libavcodec/x86/fdct.c | 1 + libavcodec/x86/h264_intrapred.asm | 4 - libavcodec/x86/h264_qpel.c | 1 + libavcodec/x86/hevcdsp_init.c | 1 + libavcodec/x86/me_cmp_init.c | 1 + libavcodec/x86/mpegaudiodsp.c | 10 +- libavcodec/x86/mpegvideoenc.c | 1 + libavcodec/x86/mpegvideoenc_template.c | 1 + libavcodec/x86/rv40dsp_init.c | 1 + libavcodec/x86/vc1dsp_mmx.c | 1 + libavcodec/x86/vp8dsp_init.c | 1 + libavcodec/x86/vp9dsp_init.h | 2 + libavcodec/x86/w64xmmtest.c | 32 +- libavcodec/xan.c | 9 +- libavcodec/xbm_parser.c | 106 + libavcodec/xbmdec.c | 57 +- libavcodec/xbmenc.c | 36 +- libavcodec/xfacedec.c | 1 + libavcodec/xl.c | 1 + libavcodec/xsubdec.c | 2 + libavcodec/xsubenc.c | 5 +- libavcodec/xxan.c | 9 +- libavcodec/y41pdec.c | 1 + libavcodec/y41penc.c | 7 +- libavcodec/ylc.c | 97 +- libavcodec/yop.c | 1 + libavcodec/yuv4dec.c | 1 + libavcodec/yuv4enc.c | 12 - libavdevice/Makefile | 1 + libavdevice/alldevices.c | 73 + libavdevice/alsa.c | 5 + libavdevice/alsa.h | 1 + libavdevice/alsa_dec.c | 22 +- libavdevice/audiotoolbox.m | 308 + libavdevice/avdevice.c | 117 +- libavdevice/avdevice.h | 5 + libavdevice/bktr.c | 4 +- libavdevice/caca.c | 2 +- libavdevice/decklink_common.cpp | 29 +- libavdevice/decklink_common.h | 27 +- libavdevice/decklink_common_c.h | 3 + libavdevice/decklink_dec.cpp | 248 +- libavdevice/decklink_dec_c.c | 21 +- libavdevice/decklink_enc.cpp | 9 +- libavdevice/decklink_enc_c.c | 2 +- libavdevice/dshow.c | 34 +- libavdevice/dshow_capture.h | 225 +- libavdevice/dshow_crossbar.c | 8 +- libavdevice/dshow_enummediatypes.c | 51 +- libavdevice/dshow_enumpins.c | 62 +- libavdevice/dshow_filter.c | 117 +- libavdevice/dshow_pin.c | 225 +- libavdevice/fbdev_dec.c | 6 +- libavdevice/gdigrab.c | 6 +- libavdevice/kmsgrab.c | 438 +- libavdevice/lavfi.c | 59 +- libavdevice/pulse_audio_dec.c | 86 +- libavdevice/timefilter.h | 15 +- libavdevice/version.h | 5 +- libavdevice/vfwcap.c | 13 +- libavdevice/xcbgrab.c | 229 +- libavfilter/Makefile | 44 +- libavfilter/aeval.c | 9 +- libavfilter/af_acrossover.c | 452 +- libavfilter/af_acrusher.c | 19 +- libavfilter/af_adeclick.c | 32 +- libavfilter/af_adenorm.c | 332 + libavfilter/af_aemphasis.c | 144 +- libavfilter/af_aexciter.c | 317 + libavfilter/af_afade.c | 106 +- libavfilter/af_afftfilt.c | 2 +- libavfilter/af_afir.c | 72 +- libavfilter/af_aformat.c | 25 +- libavfilter/af_afreqshift.c | 427 + libavfilter/af_agate.c | 16 +- libavfilter/af_aiir.c | 449 +- libavfilter/af_amerge.c | 29 +- libavfilter/af_amix.c | 46 +- libavfilter/af_anequalizer.c | 77 +- libavfilter/af_anlmdn.c | 105 +- libavfilter/af_aresample.c | 26 +- libavfilter/af_arnndn.c | 239 +- libavfilter/af_asetrate.c | 2 +- libavfilter/af_asoftclip.c | 254 +- libavfilter/af_astats.c | 4 +- libavfilter/af_asubboost.c | 105 +- libavfilter/af_asupercut.c | 448 + libavfilter/af_biquads.c | 603 +- libavfilter/af_channelmap.c | 24 +- libavfilter/af_channelsplit.c | 4 +- libavfilter/af_compensationdelay.c | 2 +- libavfilter/af_crossfeed.c | 15 +- libavfilter/af_crystalizer.c | 173 +- libavfilter/af_dynaudnorm.c | 5 +- libavfilter/af_earwax.c | 126 +- libavfilter/af_hdcd.c | 12 +- libavfilter/af_headphone.c | 359 +- libavfilter/af_join.c | 4 +- libavfilter/af_ladspa.c | 74 +- libavfilter/af_loudnorm.c | 4 +- libavfilter/af_lv2.c | 6 +- libavfilter/af_mcompand.c | 19 +- libavfilter/af_pan.c | 4 +- libavfilter/af_resample.c | 24 +- libavfilter/af_rubberband.c | 1 + libavfilter/af_sidechaincompress.c | 10 +- libavfilter/af_sofalizer.c | 31 +- libavfilter/af_speechnorm.c | 579 ++ libavfilter/af_stereotools.c | 50 +- libavfilter/af_surround.c | 4 +- libavfilter/af_tremolo.c | 2 +- libavfilter/af_vibrato.c | 4 +- libavfilter/af_volume.c | 4 - libavfilter/allfilters.c | 27 +- libavfilter/asrc_afirsrc.c | 2 +- libavfilter/asrc_anoisesrc.c | 2 +- libavfilter/asrc_anullsrc.c | 53 +- libavfilter/asrc_hilbert.c | 2 +- libavfilter/asrc_sinc.c | 2 +- libavfilter/asrc_sine.c | 4 +- libavfilter/atadenoise.h | 10 +- libavfilter/audio.h | 18 - libavfilter/avf_abitscope.c | 8 +- libavfilter/avf_ahistogram.c | 8 +- libavfilter/avf_aphasemeter.c | 151 +- libavfilter/avf_avectorscope.c | 8 +- libavfilter/avf_concat.c | 16 +- libavfilter/avf_showcqt.c | 20 +- libavfilter/avf_showfreqs.c | 49 +- libavfilter/avf_showspatial.c | 8 +- libavfilter/avf_showspectrum.c | 8 +- libavfilter/avf_showvolume.c | 8 +- libavfilter/avf_showwaves.c | 33 +- libavfilter/avfilter.c | 84 +- libavfilter/avfilter.h | 78 +- libavfilter/avfiltergraph.c | 401 +- libavfilter/bbox.c | 115 +- libavfilter/bbox.h | 2 +- libavfilter/buffersink.c | 26 +- libavfilter/buffersink.h | 42 +- libavfilter/buffersrc.c | 38 +- libavfilter/convolution.h | 2 +- libavfilter/cuda/vector_helpers.cuh | 112 + libavfilter/dnn/Makefile | 6 + libavfilter/dnn/dnn_backend_native.c | 353 +- libavfilter/dnn/dnn_backend_native.h | 31 +- .../dnn/dnn_backend_native_layer_avgpool.c | 147 + .../dnn/dnn_backend_native_layer_avgpool.h | 40 + .../dnn/dnn_backend_native_layer_conv2d.c | 137 +- .../dnn/dnn_backend_native_layer_conv2d.h | 10 +- .../dnn/dnn_backend_native_layer_dense.c | 151 + .../dnn/dnn_backend_native_layer_dense.h | 37 + .../dnn_backend_native_layer_depth2space.c | 22 +- .../dnn_backend_native_layer_depth2space.h | 6 +- .../dnn/dnn_backend_native_layer_mathbinary.c | 193 +- .../dnn/dnn_backend_native_layer_mathbinary.h | 7 +- .../dnn/dnn_backend_native_layer_mathunary.c | 85 +- .../dnn/dnn_backend_native_layer_mathunary.h | 21 +- .../dnn/dnn_backend_native_layer_maximum.c | 20 +- .../dnn/dnn_backend_native_layer_maximum.h | 6 +- .../dnn/dnn_backend_native_layer_pad.c | 22 +- .../dnn/dnn_backend_native_layer_pad.h | 6 +- libavfilter/dnn/dnn_backend_native_layers.c | 18 +- libavfilter/dnn/dnn_backend_native_layers.h | 4 +- libavfilter/dnn/dnn_backend_openvino.c | 814 ++ libavfilter/dnn/dnn_backend_openvino.h | 43 + libavfilter/dnn/dnn_backend_tf.c | 453 +- libavfilter/dnn/dnn_backend_tf.h | 5 +- libavfilter/dnn/dnn_interface.c | 16 +- libavfilter/dnn/dnn_io_proc.c | 219 + libavfilter/dnn/dnn_io_proc.h | 36 + libavfilter/dnn/queue.c | 192 + libavfilter/dnn/queue.h | 41 + libavfilter/dnn/safe_queue.c | 116 + libavfilter/dnn/safe_queue.h | 36 + libavfilter/dnn_filter_common.c | 106 + libavfilter/dnn_filter_common.h | 59 + libavfilter/dnn_interface.h | 57 +- libavfilter/drawutils.c | 102 +- libavfilter/drawutils.h | 13 - libavfilter/ebur128.c | 55 +- libavfilter/ebur128.h | 69 +- libavfilter/f_drawgraph.c | 2 +- libavfilter/f_ebur128.c | 32 +- libavfilter/f_graphmonitor.c | 11 +- libavfilter/f_interleave.c | 32 +- libavfilter/f_perms.c | 2 + libavfilter/f_select.c | 3 - libavfilter/f_sendcmd.c | 3 - libavfilter/f_sidedata.c | 2 + libavfilter/fifo.c | 148 +- libavfilter/formats.c | 379 +- libavfilter/formats.h | 93 +- libavfilter/framepool.c | 4 +- libavfilter/framepool.h | 5 +- libavfilter/framesync.c | 7 + libavfilter/framesync.h | 3 + libavfilter/gblur.h | 3 + libavfilter/glslang.cpp | 4 +- libavfilter/graphparser.c | 27 +- libavfilter/hflip.h | 1 + libavfilter/internal.h | 36 +- libavfilter/lavfutils.c | 27 +- libavfilter/lavfutils.h | 3 +- libavfilter/qp_table.c | 72 + libavfilter/qp_table.h | 33 + libavfilter/qsvvpp.c | 125 +- libavfilter/qsvvpp.h | 9 + libavfilter/setpts.c | 22 +- libavfilter/src_movie.c | 194 +- libavfilter/tests/filtfmts.c | 6 +- libavfilter/tinterlace.h | 1 - libavfilter/unsharp.h | 3 + libavfilter/v360.h | 18 +- libavfilter/vaapi_vpp.c | 4 +- libavfilter/vaf_spectrumsynth.c | 79 +- libavfilter/version.h | 8 +- libavfilter/vf_addroi.c | 10 +- libavfilter/vf_alphamerge.c | 202 +- libavfilter/vf_atadenoise.c | 148 +- libavfilter/vf_bbox.c | 48 +- libavfilter/vf_bilateral.c | 69 +- libavfilter/vf_blackdetect.c | 159 +- libavfilter/vf_blend.c | 185 +- libavfilter/vf_bm3d.c | 19 +- libavfilter/vf_chromanr.c | 275 + libavfilter/vf_ciescope.c | 4 +- libavfilter/vf_codecview.c | 20 +- libavfilter/vf_colorbalance.c | 26 +- libavfilter/vf_colorchannelmixer.c | 397 +- libavfilter/vf_colorcontrast.c | 408 + libavfilter/vf_colorcorrect.c | 217 + libavfilter/vf_colorize.c | 306 + libavfilter/vf_colorlevels.c | 209 +- libavfilter/vf_colorspace.c | 7 +- libavfilter/vf_colortemperature.c | 370 + libavfilter/vf_convolution.c | 306 +- libavfilter/vf_copy.c | 15 +- libavfilter/vf_coreimage.m | 6 +- libavfilter/vf_cropdetect.c | 10 +- libavfilter/vf_curves.c | 74 +- libavfilter/vf_datascope.c | 129 +- libavfilter/vf_dblur.c | 1 - libavfilter/vf_dctdnoiz.c | 1 + libavfilter/vf_deband.c | 22 +- libavfilter/vf_deblock.c | 19 +- libavfilter/vf_decimate.c | 181 +- libavfilter/vf_deinterlace_qsv.c | 36 +- libavfilter/vf_delogo.c | 1 - libavfilter/vf_derain.c | 96 +- libavfilter/vf_despill.c | 3 +- libavfilter/vf_detelecine.c | 21 +- libavfilter/vf_dnn_processing.c | 478 +- libavfilter/vf_drawbox.c | 2 +- libavfilter/vf_drawtext.c | 12 +- libavfilter/vf_edgedetect.c | 2 +- libavfilter/vf_elbg.c | 4 +- libavfilter/vf_epx.c | 287 + libavfilter/vf_eq.c | 2 - libavfilter/vf_estdif.c | 591 ++ libavfilter/vf_exposure.c | 144 + libavfilter/vf_extractplanes.c | 28 +- libavfilter/vf_fade.c | 30 +- libavfilter/vf_fieldhint.c | 21 +- libavfilter/vf_fieldmatch.c | 29 +- libavfilter/vf_fieldorder.c | 4 +- libavfilter/vf_fillborders.c | 237 +- libavfilter/vf_framepack.c | 70 +- libavfilter/vf_frei0r.c | 20 +- libavfilter/vf_fspp.c | 60 +- libavfilter/vf_fspp.h | 4 +- libavfilter/vf_gblur.c | 50 +- libavfilter/vf_geq.c | 4 +- libavfilter/vf_gradfun.c | 1 + libavfilter/vf_hflip.c | 4 +- libavfilter/vf_histogram.c | 54 +- libavfilter/vf_hue.c | 3 - libavfilter/vf_hwdownload.c | 23 +- libavfilter/vf_hwmap.c | 4 +- libavfilter/vf_hwupload.c | 4 +- libavfilter/vf_hwupload_cuda.c | 6 +- libavfilter/vf_identity.c | 453 + libavfilter/vf_il.c | 15 +- libavfilter/vf_lagfun.c | 161 +- libavfilter/vf_lenscorrection.c | 340 +- libavfilter/vf_lensfun.c | 72 +- libavfilter/vf_libvmaf.c | 2 +- libavfilter/vf_limiter.c | 19 +- libavfilter/vf_lut.c | 26 +- libavfilter/vf_lut2.c | 37 +- libavfilter/vf_lut3d.c | 187 +- libavfilter/vf_maskedclamp.c | 3 +- libavfilter/vf_maskedmerge.c | 5 +- libavfilter/vf_maskedminmax.c | 6 +- libavfilter/vf_maskedthreshold.c | 3 +- libavfilter/vf_maskfun.c | 98 +- libavfilter/vf_mcdeint.c | 15 +- libavfilter/vf_mergeplanes.c | 4 +- libavfilter/vf_minterpolate.c | 47 +- libavfilter/vf_mix.c | 115 +- libavfilter/vf_monochrome.c | 314 + libavfilter/vf_neighbor.c | 42 +- libavfilter/vf_nnedi.c | 1758 ++-- libavfilter/vf_normalize.c | 4 +- libavfilter/vf_ocr.c | 2 +- libavfilter/vf_overlay.c | 556 +- libavfilter/vf_overlay.h | 2 + libavfilter/vf_overlay_cuda.c | 5 +- libavfilter/vf_overlay_qsv.c | 6 +- libavfilter/vf_owdenoise.c | 1 + libavfilter/vf_palettegen.c | 4 +- libavfilter/vf_paletteuse.c | 23 +- libavfilter/vf_phase.c | 3 +- libavfilter/vf_pp.c | 18 +- libavfilter/vf_pp7.c | 15 +- libavfilter/vf_premultiply.c | 136 +- libavfilter/vf_pseudocolor.c | 386 +- libavfilter/vf_psnr.c | 129 +- libavfilter/vf_qp.c | 69 +- libavfilter/vf_readeia608.c | 319 +- libavfilter/vf_remap.c | 28 +- libavfilter/vf_removelogo.c | 4 +- libavfilter/vf_rotate.c | 2 - libavfilter/vf_scale.c | 25 +- libavfilter/vf_scale_cuda.c | 289 +- libavfilter/vf_scale_cuda.cu | 270 +- libavfilter/vf_scale_cuda.h | 28 + libavfilter/vf_scale_cuda_bicubic.cu | 224 + libavfilter/vf_scale_qsv.c | 30 +- libavfilter/vf_selectivecolor.c | 2 +- libavfilter/vf_shear.c | 330 + libavfilter/vf_showinfo.c | 198 +- libavfilter/vf_showpalette.c | 33 +- libavfilter/vf_shufflepixels.c | 456 + libavfilter/vf_shuffleplanes.c | 1 - libavfilter/vf_signature.c | 19 +- libavfilter/vf_spp.c | 68 +- libavfilter/vf_spp.h | 2 +- libavfilter/vf_sr.c | 204 +- libavfilter/vf_ssim.c | 192 +- libavfilter/vf_stack.c | 21 +- libavfilter/vf_subtitles.c | 28 +- libavfilter/vf_super2xsai.c | 62 +- libavfilter/vf_swaprect.c | 3 +- libavfilter/vf_telecine.c | 21 +- libavfilter/vf_threshold.c | 4 +- libavfilter/vf_thumbnail.c | 77 +- libavfilter/vf_tile.c | 2 +- libavfilter/vf_tinterlace.c | 7 +- libavfilter/vf_tmidequalizer.c | 440 + libavfilter/vf_tonemap_opencl.c | 6 +- libavfilter/vf_unsharp.c | 166 +- libavfilter/vf_uspp.c | 81 +- libavfilter/vf_v360.c | 812 +- libavfilter/vf_vaguedenoiser.c | 2 +- libavfilter/vf_vectorscope.c | 12 +- libavfilter/vf_vflip.c | 34 + libavfilter/vf_vibrance.c | 138 + libavfilter/vf_vif.c | 657 ++ libavfilter/vf_vignette.c | 3 - libavfilter/vf_vpp_qsv.c | 13 +- libavfilter/vf_w3fdif.c | 52 +- libavfilter/vf_waveform.c | 21 +- libavfilter/vf_weave.c | 77 +- libavfilter/vf_xfade.c | 386 +- libavfilter/vf_xmedian.c | 51 +- libavfilter/vf_yadif_cuda.c | 4 +- libavfilter/vf_yaepblur.c | 6 +- libavfilter/vf_zoompan.c | 12 +- libavfilter/vf_zscale.c | 13 +- libavfilter/vif.h | 32 + libavfilter/vsrc_gradients.c | 77 +- libavfilter/vsrc_testsrc.c | 120 +- libavfilter/x86/vf_atadenoise_init.c | 18 +- libavfilter/x86/vf_convolution_init.c | 4 +- libavfilter/x86/vf_gblur.asm | 46 + libavfilter/x86/vf_gblur_init.c | 17 +- libavfilter/x86/vf_v360_init.c | 3 +- libavformat/3dostr.c | 62 +- libavformat/Makefile | 58 +- libavformat/aadec.c | 23 +- libavformat/aaxdec.c | 415 + libavformat/acedec.c | 114 + libavformat/adp.c | 8 +- libavformat/adtsenc.c | 7 +- libavformat/adxdec.c | 26 +- libavformat/aiff.c | 54 + libavformat/aiff.h | 30 +- libavformat/aiffdec.c | 6 +- libavformat/aiffenc.c | 13 +- libavformat/allformats.c | 29 +- libavformat/alp.c | 198 +- libavformat/amvenc.c | 422 + libavformat/ape.c | 75 +- libavformat/apm.c | 243 +- libavformat/apngdec.c | 44 +- libavformat/apngenc.c | 2 +- libavformat/argo_asf.c | 462 +- libavformat/argo_asf.h | 71 + libavformat/argo_brp.c | 423 + libavformat/asf.c | 6 - libavformat/asf.h | 1 - libavformat/asfdec_f.c | 10 +- libavformat/asfdec_o.c | 93 +- libavformat/asfenc.c | 14 +- libavformat/ast.c | 5 +- libavformat/ast.h | 1 + libavformat/astdec.c | 2 +- libavformat/astenc.c | 2 +- libavformat/async.c | 10 +- libavformat/au.c | 84 +- libavformat/av1.c | 32 +- libavformat/av1dec.c | 312 +- libavformat/avc.c | 4 +- libavformat/avformat.h | 251 +- libavformat/avidec.c | 99 +- libavformat/avienc.c | 26 +- libavformat/avio.c | 15 +- libavformat/avio_internal.h | 4 +- libavformat/aviobuf.c | 127 +- libavformat/avisynth.c | 59 +- libavformat/avlanguage.c | 7 - libavformat/avlanguage.h | 7 - libavformat/avs2dec.c | 71 + libavformat/avs3dec.c | 68 + libavformat/binka.c | 100 + libavformat/brstm.c | 46 +- libavformat/caf.c | 1 + libavformat/caf.h | 1 + libavformat/cafdec.c | 25 +- libavformat/cafenc.c | 2 +- libavformat/cdg.c | 23 +- libavformat/cdxl.c | 141 +- libavformat/chromaprint.c | 2 +- libavformat/cinedec.c | 2 +- libavformat/codec2.c | 98 +- libavformat/concat.c | 7 +- libavformat/concatdec.c | 2 +- libavformat/crypto.c | 12 +- libavformat/dashdec.c | 813 +- libavformat/dashenc.c | 43 +- libavformat/daudenc.c | 8 +- libavformat/dcstr.c | 2 + libavformat/dhav.c | 19 +- libavformat/dss.c | 37 +- libavformat/dump.c | 157 +- libavformat/dv.c | 104 +- libavformat/dvenc.c | 50 +- libavformat/electronicarts.c | 4 +- libavformat/ffmetadec.c | 7 +- libavformat/fifo.c | 59 +- libavformat/fitsenc.c | 39 +- libavformat/flac_picture.c | 2 +- libavformat/flacdec.c | 15 +- libavformat/flacenc.c | 13 +- libavformat/flic.c | 38 +- libavformat/flvdec.c | 35 +- libavformat/flvenc.c | 2 +- libavformat/framecrcenc.c | 71 +- libavformat/frmdec.c | 20 +- libavformat/gifdec.c | 2 +- libavformat/gopher.c | 46 +- libavformat/hashenc.c | 29 +- libavformat/hevc.c | 18 +- libavformat/hls.c | 186 +- libavformat/hlsenc.c | 276 +- libavformat/hlsproto.c | 2 +- libavformat/http.c | 85 +- libavformat/icecast.c | 6 +- libavformat/id3v2.c | 4 +- libavformat/img2.c | 2 + libavformat/img2dec.c | 55 +- libavformat/img2enc.c | 2 +- libavformat/imx.c | 168 + libavformat/internal.h | 227 +- libavformat/ipmovie.c | 8 +- libavformat/ipudec.c | 89 + libavformat/ircamdec.c | 4 +- libavformat/isom.c | 513 +- libavformat/isom.h | 6 + libavformat/isom_tags.c | 346 + libavformat/ivfenc.c | 10 +- libavformat/jacosubdec.c | 19 +- libavformat/kvag.c | 12 +- libavformat/latmenc.c | 25 +- libavformat/libamqp.c | 37 +- libavformat/libgme.c | 48 +- libavformat/libmodplug.c | 37 +- libavformat/libopenmpt.c | 2 +- libavformat/librist.c | 244 + libavformat/libsrt.c | 93 +- libavformat/luodatdec.c | 126 + libavformat/lxfdec.c | 4 +- libavformat/matroska.h | 5 + libavformat/matroskadec.c | 522 +- libavformat/matroskaenc.c | 89 +- libavformat/mca.c | 229 + libavformat/mccdec.c | 238 + libavformat/microdvddec.c | 4 +- libavformat/mlvdec.c | 31 +- libavformat/mods.c | 102 + libavformat/moflex.c | 392 + libavformat/mov.c | 436 +- libavformat/movenc.c | 436 +- libavformat/movenc.h | 4 +- libavformat/movenccenc.c | 2 + libavformat/movenchint.c | 19 +- libavformat/mp3dec.c | 8 +- libavformat/mp3enc.c | 14 +- libavformat/mpc8.c | 6 +- libavformat/mpeg.c | 6 +- libavformat/mpegenc.c | 41 +- libavformat/mpegts.c | 254 +- libavformat/mpegts.h | 33 + libavformat/mpegtsenc.c | 214 +- libavformat/mpjpegdec.c | 11 +- libavformat/mpl2dec.c | 3 +- libavformat/mpsubdec.c | 4 +- libavformat/mspdec.c | 117 + libavformat/musx.c | 13 +- libavformat/mux.c | 184 +- libavformat/mvdec.c | 10 +- libavformat/mvi.c | 4 + libavformat/mxf.c | 51 + libavformat/mxf.h | 19 + libavformat/mxfdec.c | 230 +- libavformat/mxfenc.c | 585 +- libavformat/nut.c | 2 + libavformat/nutdec.c | 4 +- libavformat/oggdec.h | 2 +- libavformat/oma.c | 18 +- libavformat/oma.h | 4 +- libavformat/omadec.c | 20 +- libavformat/omaenc.c | 2 +- libavformat/options.c | 92 +- libavformat/paf.c | 10 +- libavformat/pcmdec.c | 140 +- libavformat/pcmenc.c | 93 +- libavformat/pjsdec.c | 3 +- libavformat/pp_bnk.c | 78 +- libavformat/protocols.c | 18 + libavformat/qtpalette.c | 304 +- libavformat/qtpalette.h | 294 +- libavformat/r3d.c | 5 +- libavformat/rawdec.c | 2 + libavformat/rawenc.c | 60 +- libavformat/rdt.c | 2 +- libavformat/realtextdec.c | 14 +- libavformat/riff.c | 12 + libavformat/riff.h | 6 +- libavformat/riffenc.c | 15 +- libavformat/rmdec.c | 56 +- libavformat/rso.c | 2 + libavformat/rso.h | 1 + libavformat/rsodec.c | 2 +- libavformat/rsoenc.c | 2 +- libavformat/rtmppkt.c | 10 +- libavformat/rtmppkt.h | 9 - libavformat/rtmpproto.c | 22 +- libavformat/rtpdec.c | 113 +- libavformat/rtpdec.h | 2 - libavformat/rtpdec_jpeg.c | 2 +- libavformat/rtpdec_qt.c | 66 +- libavformat/rtpenc.c | 2 +- libavformat/rtpenc_mpegts.c | 72 +- libavformat/rtpproto.c | 12 +- libavformat/rtsp.c | 154 +- libavformat/rtsp.h | 13 +- libavformat/rtspdec.c | 84 +- libavformat/rtspenc.c | 5 +- libavformat/samidec.c | 2 + libavformat/sbgdec.c | 11 +- libavformat/sccdec.c | 110 +- libavformat/sdp.c | 4 + libavformat/segafilm.c | 2 +- libavformat/segafilmenc.c | 234 +- libavformat/segment.c | 140 +- libavformat/sga.c | 479 + libavformat/sierravmd.c | 4 + libavformat/smacker.c | 231 +- libavformat/smoothstreamingenc.c | 49 +- libavformat/spdifenc.c | 6 +- libavformat/srtenc.c | 3 +- libavformat/subtitles.c | 69 +- libavformat/subtitles.h | 2 +- libavformat/svs.c | 96 + libavformat/swf.c | 8 +- libavformat/swf.h | 33 - libavformat/swfdec.c | 72 +- libavformat/swfenc.c | 104 +- libavformat/tedcaptionsdec.c | 77 +- libavformat/tee.c | 2 +- libavformat/tests/fifo_muxer.c | 56 +- libavformat/tests/movenc.c | 77 +- libavformat/tests/url.c | 33 +- libavformat/tls.c | 2 +- libavformat/tls.h | 4 +- libavformat/tls_gnutls.c | 7 + libavformat/tls_libtls.c | 7 + libavformat/tls_mbedtls.c | 7 + libavformat/tls_openssl.c | 7 + libavformat/tls_schannel.c | 7 + libavformat/tls_securetransport.c | 9 +- libavformat/ttaenc.c | 11 +- libavformat/ttmlenc.c | 174 + libavformat/ty.c | 68 +- libavformat/udp.c | 100 +- libavformat/url.c | 34 +- libavformat/url.h | 23 +- libavformat/utils.c | 804 +- libavformat/version.h | 11 +- libavformat/vividas.c | 49 +- libavformat/voc.c | 7 +- libavformat/voc.h | 1 + libavformat/voc_packet.c | 16 +- libavformat/vocdec.c | 2 +- libavformat/vocenc.c | 2 +- libavformat/vpk.c | 5 +- libavformat/wavdec.c | 117 +- libavformat/wavenc.c | 72 +- libavformat/wc3movie.c | 21 +- libavformat/webmdashenc.c | 292 +- libavformat/webpenc.c | 29 +- libavformat/webvttdec.c | 2 +- libavformat/webvttenc.c | 2 +- libavformat/wsddec.c | 2 +- libavformat/wtvdec.c | 7 + libavformat/wtvenc.c | 5 +- libavformat/yuv4mpegenc.c | 50 +- libavutil/Makefile | 2 + libavutil/aarch64/timer.h | 8 +- libavutil/adler32.c | 4 + libavutil/adler32.h | 16 +- libavutil/aes_internal.h | 4 +- libavutil/arm/timer.h | 8 +- libavutil/avsscanf.c | 2 +- libavutil/avstring.c | 11 +- libavutil/avstring.h | 19 + libavutil/base64.c | 9 +- libavutil/bprint.c | 29 + libavutil/buffer.c | 66 +- libavutil/buffer.h | 48 + libavutil/buffer_internal.h | 9 +- libavutil/channel_layout.c | 6 + libavutil/channel_layout.h | 6 + libavutil/common.h | 158 +- libavutil/cpu.c | 10 + libavutil/cpu.h | 3 + libavutil/cpu_internal.h | 2 + libavutil/cuda_check.h | 2 + libavutil/eval.c | 2 +- libavutil/film_grain_params.c | 42 + libavutil/film_grain_params.h | 168 + libavutil/frame.c | 61 +- libavutil/frame.h | 26 +- libavutil/hash.c | 2 + libavutil/hash.h | 1 + libavutil/hwcontext_cuda.c | 33 +- libavutil/hwcontext_d3d11va.c | 2 +- libavutil/hwcontext_drm.c | 38 +- libavutil/hwcontext_dxva2.c | 2 +- libavutil/hwcontext_opencl.c | 2 +- libavutil/hwcontext_qsv.c | 2 +- libavutil/hwcontext_vaapi.c | 70 +- libavutil/hwcontext_vdpau.c | 61 +- libavutil/hwcontext_vulkan.c | 595 +- libavutil/imgutils.c | 100 +- libavutil/imgutils.h | 14 + libavutil/internal.h | 85 +- libavutil/lls.h | 2 +- libavutil/log.h | 18 + libavutil/mathematics.c | 2 +- libavutil/mem.h | 6 + libavutil/mem_internal.h | 112 + libavutil/mips/Makefile | 2 +- libavutil/mips/asmdefs.h | 42 + libavutil/mips/cpu.c | 134 + libavutil/mips/cpu.h | 28 + libavutil/mips/generic_macros_msa.h | 14 +- libavutil/mips/mmiutils.h | 2 + libavutil/murmur3.c | 2 + libavutil/murmur3.h | 1 + libavutil/opt.c | 29 +- libavutil/opt.h | 31 +- libavutil/parseutils.c | 4 +- libavutil/pixdesc.c | 59 +- libavutil/pixdesc.h | 2 + libavutil/pixfmt.h | 57 +- libavutil/ripemd.c | 1 + libavutil/ripemd.h | 1 + libavutil/spherical.c | 6 +- libavutil/stereo3d.c | 5 +- libavutil/tests/aes_ctr.c | 1 + libavutil/tests/avstring.c | 4 + libavutil/tests/cpu.c | 3 + libavutil/tests/des.c | 1 + libavutil/tests/imgutils.c | 38 + libavutil/tests/lls.c | 1 + libavutil/time.c | 4 +- libavutil/timecode.c | 117 +- libavutil/timecode.h | 67 +- libavutil/timer.h | 2 +- libavutil/tx.c | 41 +- libavutil/tx.h | 24 +- libavutil/tx_priv.h | 17 +- libavutil/tx_template.c | 136 +- libavutil/version.h | 15 +- libavutil/video_enc_params.c | 7 +- libavutil/video_enc_params.h | 10 +- libpostproc/postprocess_altivec_template.c | 1 + libpostproc/postprocess_internal.h | 1 + libpostproc/postprocess_template.c | 1 + libpostproc/version.h | 2 +- libswresample/audioconvert.c | 6 +- libswresample/rematrix.c | 12 +- libswresample/version.h | 2 +- libswscale/Makefile | 1 + libswscale/aarch64/swscale_unscaled.c | 31 +- libswscale/aarch64/yuv2rgb_neon.S | 2 + libswscale/bayer_template.c | 102 + libswscale/input.c | 36 +- libswscale/output.c | 34 +- libswscale/ppc/swscale_ppc_template.c | 2 + libswscale/ppc/swscale_vsx.c | 1 + libswscale/ppc/yuv2rgb_altivec.c | 19 +- libswscale/rgb2rgb_template.c | 4 +- libswscale/slice.c | 12 +- libswscale/swscale.c | 1 + libswscale/swscale_internal.h | 14 +- libswscale/swscale_unscaled.c | 56 +- libswscale/tests/floatimg_cmp.c | 296 + libswscale/tests/swscale.c | 8 +- libswscale/utils.c | 160 +- libswscale/version.h | 2 +- libswscale/vscale.c | 2 +- libswscale/x86/Makefile | 1 + libswscale/x86/hscale_fast_bilinear_simd.c | 1 + libswscale/x86/output.asm | 128 +- libswscale/x86/rgb2rgb.c | 10 +- libswscale/x86/swscale.c | 187 +- libswscale/x86/swscale_template.c | 83 - libswscale/x86/yuv2rgb.c | 12 - libswscale/x86/yuv2yuvX.asm | 136 + libswscale/yuv2rgb.c | 29 +- tests/api/Makefile | 1 - tests/api/api-band-test.c | 93 +- tests/api/api-flac-test.c | 113 +- tests/api/api-h264-test.c | 86 +- tests/api/api-seek-test.c | 109 +- tests/audiomatch.c | 18 +- tests/checkasm/Makefile | 2 +- tests/checkasm/aacpsdsp.c | 1 + tests/checkasm/af_afir.c | 1 + tests/checkasm/alacdsp.c | 1 + tests/checkasm/audiodsp.c | 1 + tests/checkasm/blockdsp.c | 1 + tests/checkasm/bswapdsp.c | 1 + tests/checkasm/checkasm.c | 13 + tests/checkasm/checkasm.h | 10 + tests/checkasm/exrdsp.c | 1 + tests/checkasm/fixed_dsp.c | 1 + tests/checkasm/flacdsp.c | 1 + tests/checkasm/float_dsp.c | 2 + tests/checkasm/fmtconvert.c | 2 + tests/checkasm/h264dsp.c | 1 + tests/checkasm/h264pred.c | 1 + tests/checkasm/h264qpel.c | 1 + tests/checkasm/hevc_add_res.c | 1 + tests/checkasm/hevc_idct.c | 1 + tests/checkasm/hevc_pel.c | 524 + tests/checkasm/hevc_sao.c | 1 + tests/checkasm/jpeg2000dsp.c | 1 + tests/checkasm/llviddspenc.c | 1 + tests/checkasm/opusdsp.c | 2 + tests/checkasm/pixblockdsp.c | 1 + tests/checkasm/sbrdsp.c | 2 + tests/checkasm/sw_rgb.c | 1 + tests/checkasm/sw_scale.c | 102 + tests/checkasm/synth_filter.c | 2 + tests/checkasm/utvideodsp.c | 1 + tests/checkasm/v210enc.c | 1 + tests/checkasm/vf_colorspace.c | 1 + tests/checkasm/vf_eq.c | 1 + tests/checkasm/vf_gblur.c | 52 +- tests/checkasm/vf_hflip.c | 2 + tests/checkasm/vf_threshold.c | 1 + tests/checkasm/videodsp.c | 1 + tests/checkasm/vp8dsp.c | 1 + tests/checkasm/vp9dsp.c | 1 + tests/dnn/Makefile | 2 + tests/dnn/dnn-layer-avgpool-test.c | 197 + tests/dnn/dnn-layer-conv2d-test.c | 12 +- tests/dnn/dnn-layer-dense-test.c | 131 + tests/dnn/dnn-layer-depth2space-test.c | 2 +- tests/dnn/dnn-layer-mathbinary-test.c | 11 +- tests/dnn/dnn-layer-mathunary-test.c | 73 +- tests/dnn/dnn-layer-maximum-test.c | 2 +- tests/dnn/dnn-layer-pad-test.c | 6 +- tests/fate-run.sh | 84 +- tests/fate/aac.mak | 12 +- tests/fate/ac3.mak | 4 +- tests/fate/acodec.mak | 32 +- tests/fate/adpcm.mak | 43 +- tests/fate/api.mak | 8 - tests/fate/apng.mak | 3 + tests/fate/audio.mak | 10 +- tests/fate/bmp.mak | 24 +- tests/fate/canopus.mak | 4 +- tests/fate/cbs.mak | 18 +- tests/fate/cdxl.mak | 4 +- tests/fate/dca.mak | 18 +- tests/fate/demux.mak | 7 +- tests/fate/dfa.mak | 22 +- tests/fate/dnn.mak | 12 +- tests/fate/dnxhd.mak | 6 +- tests/fate/ea.mak | 8 +- tests/fate/ffmpeg.mak | 22 +- tests/fate/fft.mak | 30 +- tests/fate/filter-audio.mak | 50 +- tests/fate/filter-video.mak | 184 +- tests/fate/fits.mak | 11 +- tests/fate/gif.mak | 12 +- tests/fate/h264.mak | 344 +- tests/fate/hevc.mak | 20 +- tests/fate/hlsenc.mak | 33 +- tests/fate/image.mak | 73 +- tests/fate/lavf-audio.mak | 5 + tests/fate/libavcodec.mak | 4 - tests/fate/libswresample.mak | 2 +- tests/fate/libswscale.mak | 4 + tests/fate/lossless-audio.mak | 16 +- tests/fate/lossless-video.mak | 7 +- tests/fate/matroska.mak | 53 + tests/fate/microsoft.mak | 8 +- tests/fate/monkeysaudio.mak | 6 +- tests/fate/mov.mak | 9 +- tests/fate/mp3.mak | 16 +- tests/fate/mpc.mak | 7 + tests/fate/mxf.mak | 12 +- tests/fate/opus.mak | 2 +- tests/fate/pcm.mak | 10 +- tests/fate/pixlet.mak | 2 +- tests/fate/prores.mak | 18 +- tests/fate/qt.mak | 18 +- tests/fate/qtrle.mak | 10 +- tests/fate/screen.mak | 22 +- tests/fate/seek.mak | 1 + tests/fate/subtitles.mak | 6 + tests/fate/utvideo.mak | 2 +- tests/fate/vcodec.mak | 4 +- tests/fate/video.mak | 129 +- tests/fate/voice.mak | 16 +- tests/fate/vpx.mak | 8 +- tests/fate/wavpack.mak | 52 +- tests/filtergraphs/overlay_yuv420p10 | 5 + tests/filtergraphs/overlay_yuv422p10 | 5 + tests/ref/acodec/adpcm-argo | 4 + tests/ref/acodec/adpcm-ima_alp | 4 + tests/ref/acodec/adpcm-ima_apm | 4 + tests/ref/acodec/adpcm-swf | 8 +- tests/ref/acodec/adpcm-swf-trellis | 8 +- tests/ref/acodec/adpcm-swf-wav | 4 + tests/ref/fate/aa-demux | 283 + tests/ref/fate/adpcm-ima-amv | 312 +- tests/ref/fate/adpcm-ima-cunning-stereo | 1 + tests/ref/fate/adtstoasc_ticket3715 | 2 +- tests/ref/fate/apng-dispose-previous | 139 + tests/ref/fate/asf-repldata | 28 +- tests/ref/fate/av1-annexb-demux | 2 +- tests/ref/fate/avid-interlaced | 7 + tests/ref/fate/avid-meridian | 15 + tests/ref/fate/cdxl-bitline-ham6 | 2 +- tests/ref/fate/cdxl-demux | 24 +- tests/ref/fate/cdxl-ham6 | 2 +- tests/ref/fate/cdxl-ham8 | 2 +- tests/ref/fate/cdxl-pal8 | 2 +- tests/ref/fate/cdxl-pal8-small | 2 +- tests/ref/fate/cfhd-3 | 20 +- .../ref/fate/concat-demuxer-extended-lavf-mxf | 2 +- .../fate/concat-demuxer-extended-lavf-mxf_d10 | 2 +- .../ref/fate/concat-demuxer-simple1-lavf-mxf | 206 +- .../fate/concat-demuxer-simple1-lavf-mxf_d10 | 144 +- tests/ref/fate/concat-demuxer-simple2-lavf-ts | 302 +- tests/ref/fate/copy-trac236 | 4 +- tests/ref/fate/copy-trac3074 | 4 +- tests/ref/fate/copy-trac4914 | 2 +- tests/ref/fate/dpx-probe | 16 + tests/ref/fate/exif-image-embedded | 10 +- tests/ref/fate/exif-image-jpg | 6 - .../fate/exr-rgb-scanline-float-zip-dw-large | 6 + .../fate/exr-rgb-scanline-half-piz-dw-large | 6 + .../fate/exr-rgb-scanline-half-zip-dw-large | 6 + .../fate/exr-rgb-scanline-half-zip-dw-outside | 6 + .../exr-rgb-scanline-pxr24-half-uint32-13x9 | 2 +- .../fate/exr-rgb-scanline-uint32-piz-dw-large | 6 + .../fate/exr-rgb-scanline-zip-half-0x0-0xFFFF | 6 + tests/ref/fate/exr-rgb-tile-half-piz-dw-large | 6 + tests/ref/fate/exr-rgb-tile-half-zip | 6 + .../ref/fate/exr-rgb-tile-half-zip-dw-outside | 6 + .../ref/fate/exr-rgb-tile-uint32-piz-dw-large | 6 + .../ref/fate/exr-rgba-multiscanline-half-b44 | 2 +- tests/ref/fate/exr-slice-raw | 2 +- tests/ref/fate/exr-slice-rle | 2 +- tests/ref/fate/exr-slice-zip1 | 2 +- tests/ref/fate/exr-slice-zip16 | 2 +- tests/ref/fate/exr-ya-scanline-zip-half-12x8 | 6 + tests/ref/fate/ffmpeg-attached_pics | 2 +- tests/ref/fate/ffmpeg-streamloop | 2 +- tests/ref/fate/ffprobe_compact | 34 +- tests/ref/fate/ffprobe_csv | 34 +- tests/ref/fate/ffprobe_default | 33 - tests/ref/fate/ffprobe_flat | 33 - tests/ref/fate/ffprobe_ini | 33 - tests/ref/fate/ffprobe_json | 3 - tests/ref/fate/ffprobe_xml | 8 +- tests/ref/fate/filter-colorbalance | 6 +- tests/ref/fate/filter-colorbalance-gbrap | 6 +- tests/ref/fate/filter-colorbalance-gbrap-16 | 6 +- tests/ref/fate/filter-colorbalance-rgba64 | 6 +- tests/ref/fate/filter-earwax | 40 +- tests/ref/fate/filter-edgedetect | 2 +- tests/ref/fate/filter-edgedetect-colormix | 2 +- tests/ref/fate/filter-fps-down | 1 + tests/ref/fate/filter-fps-up | 2 + tests/ref/fate/filter-fps-up-round-down | 3 + tests/ref/fate/filter-fps-up-round-up | 2 + tests/ref/fate/filter-minterpolate-up | 16 +- tests/ref/fate/filter-mpdecimate | 1 + tests/ref/fate/filter-overlay_yuv420p10 | 8 + tests/ref/fate/filter-overlay_yuv422p10 | 8 + tests/ref/fate/filter-pixdesc-x2rgb10le | 1 + tests/ref/fate/filter-pixfmts-copy | 1 + tests/ref/fate/filter-pixfmts-crop | 1 + tests/ref/fate/filter-pixfmts-field | 1 + tests/ref/fate/filter-pixfmts-fieldorder | 1 + tests/ref/fate/filter-pixfmts-hflip | 1 + tests/ref/fate/filter-pixfmts-il | 1 + tests/ref/fate/filter-pixfmts-null | 1 + tests/ref/fate/filter-pixfmts-pad | 1 + tests/ref/fate/filter-pixfmts-scale | 41 +- tests/ref/fate/filter-pixfmts-transpose | 1 + tests/ref/fate/filter-pixfmts-vflip | 1 + tests/ref/fate/filter-thumbnail | 2 +- tests/ref/fate/filter-unsharp-yuv420p10 | 25 + tests/ref/fate/fits-demux | 10 +- tests/ref/fate/fitsdec-gray | 2 +- tests/ref/fate/flcl1905 | 34 +- tests/ref/fate/g2m2 | 320 +- tests/ref/fate/gaplessenc-itunes-to-ipod-aac | 2 +- tests/ref/fate/gaplessenc-pcm-to-mov-aac | 2 +- tests/ref/fate/gaplessinfo-itunes1 | 2 +- tests/ref/fate/gaplessinfo-itunes2 | 2 +- .../fate/h264-conformance-cabac_mot_fld0_full | 60 +- .../h264-conformance-cabac_mot_picaff0_full | 60 +- .../ref/fate/h264-conformance-cabref3_sand_d | 100 +- tests/ref/fate/h264-conformance-cafi1_sva_c | 66 +- .../ref/fate/h264-conformance-capa1_toshiba_b | 180 +- .../ref/fate/h264-conformance-capama3_sand_f | 100 +- .../h264-conformance-cavlc_mot_fld0_full_b | 60 +- .../h264-conformance-cavlc_mot_picaff0_full_b | 60 +- tests/ref/fate/h264-conformance-cvfi1_sony_d | 34 +- tests/ref/fate/h264-conformance-cvfi1_sva_c | 14 +- tests/ref/fate/h264-conformance-cvfi2_sony_h | 34 +- tests/ref/fate/h264-conformance-cvfi2_sva_c | 26 +- .../fate/h264-conformance-cvmapaqp3_sony_e | 14 +- .../fate/h264-conformance-cvmp_mot_fld_l30_b | 60 +- .../fate/h264-conformance-cvmp_mot_frm_l31_b | 60 +- .../ref/fate/h264-conformance-cvnlfi1_sony_c | 34 +- .../ref/fate/h264-conformance-cvnlfi2_sony_h | 34 +- .../ref/fate/h264-conformance-cvpa1_toshiba_b | 180 +- tests/ref/fate/h264-conformance-fi1_sony_e | 34 +- .../fate/h264-conformance-frext-bcrm_freh10 | 200 +- .../fate/h264-conformance-frext-brcm_freh11 | 200 +- .../fate/h264-conformance-frext-brcm_freh4 | 200 +- tests/ref/fate/h264-conformance-frext-freh6 | 200 +- tests/ref/fate/h264-conformance-frext-freh7_b | 200 +- .../fate/h264-conformance-frext-hcaff1_hhi_b | 20 +- .../fate/h264-conformance-frext-hpcafl_bcrm_c | 600 +- .../h264-conformance-frext-hpcaflnl_bcrm_c | 600 +- .../h264-conformance-frext-hpcamapalq_bcrm_b | 316 +- .../fate/h264-conformance-frext-hpcvfl_bcrm_a | 600 +- .../h264-conformance-frext-hpcvflnl_bcrm_a | 600 +- .../ref/fate/h264-conformance-mr3_tandberg_b | 582 +- tests/ref/fate/h264-conformance-mr6_bt_b | 120 +- tests/ref/fate/h264-conformance-mr7_bt_b | 100 +- tests/ref/fate/h264-conformance-mr8_bt_b | 116 +- tests/ref/fate/h264-conformance-mr9_bt_b | 96 +- .../fate/h264-conformance-sharp_mp_field_1_b | 30 +- .../fate/h264-conformance-sharp_mp_field_2_b | 30 +- .../fate/h264-conformance-sharp_mp_field_3_b | 30 +- .../fate/h264-conformance-sharp_mp_paff_1r2 | 26 +- .../fate/h264-conformance-sharp_mp_paff_2r | 26 +- ...hapqa-extract-nosnappy-to-hapalphaonly-mov | 5 +- .../fate/hapqa-extract-nosnappy-to-hapq-mov | 5 +- .../hevc-conformance-BUMPING_A_ericsson_1 | 90 +- .../fate/hevc-conformance-CIP_A_Panasonic_3 | 4 +- .../fate/hevc-conformance-CIP_C_Panasonic_2 | 4 +- .../fate/hevc-conformance-DELTAQP_A_BRCM_4 | 2 +- .../fate/hevc-conformance-NUT_A_ericsson_5 | 24 +- .../hevc-conformance-NoOutPrior_A_Qualcomm_1 | 36 +- .../hevc-conformance-NoOutPrior_B_Qualcomm_1 | 50 +- .../fate/hevc-conformance-OPFLAG_B_Qualcomm_1 | 118 +- .../fate/hevc-conformance-OPFLAG_C_Qualcomm_1 | 162 +- .../ref/fate/hevc-conformance-RAP_A_docomo_4 | 172 +- .../ref/fate/hevc-conformance-RAP_B_Bossen_1 | 26 +- .../ref/fate/hevc-conformance-SDH_A_Orange_3 | 4 +- tests/ref/fate/hevc-hdr10-plus-metadata | 62 + tests/ref/fate/hevc-monochrome-crop | 3 + tests/ref/fate/hevc-small422chroma | 6 + tests/ref/fate/hls-fmp4_ac3 | 8 + tests/ref/fate/iff-byterun1 | 2 +- tests/ref/fate/iff-ilbm | 2 +- tests/ref/fate/imgutils | 183 + tests/ref/fate/iv8-demux | 50 +- tests/ref/fate/lscr | 21 + .../fate/matroska-mastering-display-metadata | 97 + tests/ref/fate/matroska-mpegts-remux | 52 + tests/ref/fate/matroska-spherical-mono-remux | 66 + tests/ref/fate/matroska-vp8-alpha-remux | 33 + tests/ref/fate/matroska-zero-length-block | 10 + tests/ref/fate/mimic | 152 +- tests/ref/fate/mov-aac-2048-priming | 434 +- tests/ref/fate/mov-init-nonkeyframe | 240 +- tests/ref/fate/mov-mp4-extended-atom | 1 + tests/ref/fate/mov-zombie | 329 +- tests/ref/fate/movenc | 12 +- tests/ref/fate/mpeg2-ticket6677 | 14 +- tests/ref/fate/mss2-pal | 4 +- tests/ref/fate/mss2-pals | 4 +- tests/ref/fate/mss2-rgb555 | 4 +- tests/ref/fate/mss2-rgb555s | 4 +- tests/ref/fate/mxf-d10-user-comments | 29 +- tests/ref/fate/mxf-opatom-user-comments | 2 +- tests/ref/fate/mxf-probe-applehdr10 | 166 + tests/ref/fate/mxf-probe-d10 | 5 +- tests/ref/fate/mxf-probe-dnxhd | 10 +- tests/ref/fate/mxf-probe-dv25 | 8 +- tests/ref/fate/mxf-reel_name | 2 +- tests/ref/fate/mxf-user-comments | 2 +- tests/ref/fate/nuv-rtjpeg | 16 +- tests/ref/fate/opt | 54 +- tests/ref/fate/psd-rgb48 | 2 +- tests/ref/fate/psd-rgba64 | 2 +- tests/ref/fate/rgb24-mkv | 4 +- tests/ref/fate/segment-mp4-to-ts | 58 +- tests/ref/fate/smjpeg-demux | 82 +- tests/ref/fate/smvjpeg | 2 +- tests/ref/fate/sub-dvb | 75 + tests/ref/fate/sub-ttmlenc | 122 + tests/ref/fate/sws-floatimg-cmp | 120 + tests/ref/fate/sws-pixdesc-query | 11 + tests/ref/fate/time_base | 2 +- tests/ref/fate/unknown_layout-ac3 | 2 +- tests/ref/fate/url | 20 + tests/ref/fate/vp9-tiling-pedestrian | 4 +- tests/ref/fate/wav-chapters | 45 + tests/ref/lavf-fate/av1.mkv | 4 +- tests/ref/lavf-fate/av1.mp4 | 4 +- tests/ref/lavf-fate/h264.mp4 | 4 +- tests/ref/lavf-fate/vp8.ogg | 4 +- tests/ref/lavf/gbrap.fits | 2 +- tests/ref/lavf/gbrap16be.fits | 2 +- tests/ref/lavf/gbrp.fits | 2 +- tests/ref/lavf/gbrp16be.fits | 2 +- tests/ref/lavf/gray.fits | 2 +- tests/ref/lavf/gray16be.fits | 4 +- tests/ref/lavf/ismv | 6 +- tests/ref/lavf/mp4 | 12 +- tests/ref/lavf/mxf | 6 +- tests/ref/lavf/mxf_d10 | 2 +- tests/ref/lavf/mxf_dv25 | 2 +- tests/ref/lavf/mxf_dvcpro50 | 2 +- tests/ref/lavf/mxf_opatom | 2 +- tests/ref/lavf/mxf_opatom_audio | 2 +- tests/ref/lavf/rm | 2 +- tests/ref/lavf/xbm | 4 +- tests/ref/seek/acodec-adpcm-swf | 46 +- tests/ref/seek/acodec-adpcm-swf-trellis | 46 +- tests/ref/seek/lavf-al | 13 +- tests/ref/seek/lavf-dv | 18 +- tests/ref/seek/lavf-ul | 13 +- tests/ref/vsynth/vsynth1-dv-hd | 2 +- tests/ref/vsynth/vsynth1-ffv1-v3-rgb48 | 4 +- tests/ref/vsynth/vsynth1-jpeg2000 | 8 +- tests/ref/vsynth/vsynth1-jpeg2000-97 | 6 +- tests/ref/vsynth/vsynth1-mpeg4 | 4 +- tests/ref/vsynth/vsynth1-r210 | 4 +- tests/ref/vsynth/vsynth2-dv-hd | 2 +- tests/ref/vsynth/vsynth2-ffv1-v3-rgb48 | 4 +- tests/ref/vsynth/vsynth2-jpeg2000 | 8 +- tests/ref/vsynth/vsynth2-jpeg2000-97 | 8 +- tests/ref/vsynth/vsynth2-mpeg4 | 4 +- tests/ref/vsynth/vsynth2-r210 | 4 +- tests/ref/vsynth/vsynth3-dv-hd | 2 +- tests/ref/vsynth/vsynth3-ffv1-v3-rgb48 | 4 +- tests/ref/vsynth/vsynth3-jpeg2000 | 8 +- tests/ref/vsynth/vsynth3-jpeg2000-97 | 8 +- tests/ref/vsynth/vsynth3-mpeg4 | 4 +- tests/ref/vsynth/vsynth3-r210 | 4 +- tests/ref/vsynth/vsynth_lena-dv-hd | 2 +- tests/ref/vsynth/vsynth_lena-ffv1-v3-rgb48 | 4 +- tests/ref/vsynth/vsynth_lena-jpeg2000 | 8 +- tests/ref/vsynth/vsynth_lena-jpeg2000-97 | 8 +- tests/ref/vsynth/vsynth_lena-mpeg4 | 4 +- tests/ref/vsynth/vsynth_lena-r210 | 4 +- tools/Makefile | 10 +- tools/enum_options.c | 26 +- tools/ffescape.c | 7 +- tools/pktdumper.c | 23 +- tools/python/convert_from_tensorflow.py | 167 +- tools/python/convert_header.py | 2 +- tools/target_bsf_fuzzer.c | 51 +- tools/target_dec_fuzzer.c | 143 +- tools/target_dem_fuzzer.c | 80 +- 1941 files changed, 106954 insertions(+), 65480 deletions(-) create mode 100644 doc/dev_community/community.md create mode 100644 doc/dev_community/resolution_process.md create mode 100644 doc/general_contents.texi create mode 100644 libavcodec/aacps_common.c create mode 100644 libavcodec/aarch64/hevcdsp_idct_neon.S create mode 100644 libavcodec/aarch64/hevcdsp_init_aarch64.c create mode 100644 libavcodec/aarch64/hevcdsp_sao_neon.S create mode 100644 libavcodec/argo.c create mode 100644 libavcodec/atsc_a53.c create mode 100644 libavcodec/atsc_a53.h create mode 100644 libavcodec/av1dec.c create mode 100644 libavcodec/av1dec.h create mode 100644 libavcodec/avcodec.c create mode 100644 libavcodec/avs3.h create mode 100644 libavcodec/avs3_parser.c create mode 100644 libavcodec/cbs_bsf.c create mode 100644 libavcodec/cbs_bsf.h create mode 100644 libavcodec/cbs_sei.c create mode 100644 libavcodec/cbs_sei.h create mode 100644 libavcodec/cbs_sei_syntax_template.c create mode 100644 libavcodec/cfhddsp.c create mode 100644 libavcodec/cfhddsp.h create mode 100644 libavcodec/cfhdenc.c create mode 100644 libavcodec/cfhdencdsp.c create mode 100644 libavcodec/cfhdencdsp.h create mode 100644 libavcodec/codec_par.c create mode 100644 libavcodec/cri.c create mode 100644 libavcodec/cri_parser.c create mode 100644 libavcodec/dolby_e_parse.c create mode 100644 libavcodec/dolby_e_parser.c create mode 100644 libavcodec/dvbsubenc.c create mode 100644 libavcodec/dxva2_av1.c create mode 100644 libavcodec/dynamic_hdr10_plus.c create mode 100644 libavcodec/dynamic_hdr10_plus.h create mode 100644 libavcodec/encode.h create mode 100644 libavcodec/exrenc.c create mode 100644 libavcodec/fastaudio.c create mode 100644 libavcodec/float2half.h create mode 100644 libavcodec/half2float.h create mode 100644 libavcodec/imx.c create mode 100644 libavcodec/ipu_parser.c create mode 100644 libavcodec/libsvtav1.c create mode 100644 libavcodec/libuavs3d.c create mode 100644 libavcodec/lscrdec.c create mode 100644 libavcodec/mjpegdec_common.c create mode 100644 libavcodec/mobiclip.c create mode 100644 libavcodec/mpegaudiodec_common.c create mode 100644 libavcodec/mpegaudiodec_common_tablegen.c create mode 100644 libavcodec/mpegaudiodec_common_tablegen.h create mode 100644 libavcodec/msp2dec.c create mode 100644 libavcodec/nvdec_av1.c create mode 100644 libavcodec/pgxdec.c create mode 100644 libavcodec/photocd.c create mode 100644 libavcodec/rpzaenc.c create mode 100644 libavcodec/sei.h create mode 100644 libavcodec/setts_bsf.c create mode 100644 libavcodec/sga.c create mode 100644 libavcodec/sinewin_fixed_tablegen.h create mode 100644 libavcodec/speedhqenc.c create mode 100644 libavcodec/speedhqenc.h create mode 100644 libavcodec/ttmlenc.c create mode 100644 libavcodec/ttmlenc.h create mode 100644 libavcodec/vaapi_av1.c create mode 100644 libavcodec/wavpackdata.c create mode 100644 libavcodec/x86/cfhddsp.asm create mode 100644 libavcodec/x86/cfhddsp_init.c create mode 100644 libavcodec/x86/cfhdencdsp.asm create mode 100644 libavcodec/x86/cfhdencdsp_init.c create mode 100644 libavcodec/xbm_parser.c create mode 100644 libavdevice/audiotoolbox.m create mode 100644 libavfilter/af_adenorm.c create mode 100644 libavfilter/af_aexciter.c create mode 100644 libavfilter/af_afreqshift.c create mode 100644 libavfilter/af_asupercut.c create mode 100644 libavfilter/af_speechnorm.c create mode 100644 libavfilter/cuda/vector_helpers.cuh create mode 100644 libavfilter/dnn/dnn_backend_native_layer_avgpool.c create mode 100644 libavfilter/dnn/dnn_backend_native_layer_avgpool.h create mode 100644 libavfilter/dnn/dnn_backend_native_layer_dense.c create mode 100644 libavfilter/dnn/dnn_backend_native_layer_dense.h create mode 100644 libavfilter/dnn/dnn_backend_openvino.c create mode 100644 libavfilter/dnn/dnn_backend_openvino.h create mode 100644 libavfilter/dnn/dnn_io_proc.c create mode 100644 libavfilter/dnn/dnn_io_proc.h create mode 100644 libavfilter/dnn/queue.c create mode 100644 libavfilter/dnn/queue.h create mode 100644 libavfilter/dnn/safe_queue.c create mode 100644 libavfilter/dnn/safe_queue.h create mode 100644 libavfilter/dnn_filter_common.c create mode 100644 libavfilter/dnn_filter_common.h create mode 100644 libavfilter/qp_table.c create mode 100644 libavfilter/qp_table.h create mode 100644 libavfilter/vf_chromanr.c create mode 100644 libavfilter/vf_colorcontrast.c create mode 100644 libavfilter/vf_colorcorrect.c create mode 100644 libavfilter/vf_colorize.c create mode 100644 libavfilter/vf_colortemperature.c create mode 100644 libavfilter/vf_epx.c create mode 100644 libavfilter/vf_estdif.c create mode 100644 libavfilter/vf_exposure.c create mode 100644 libavfilter/vf_identity.c create mode 100644 libavfilter/vf_monochrome.c create mode 100644 libavfilter/vf_scale_cuda.h create mode 100644 libavfilter/vf_scale_cuda_bicubic.cu create mode 100644 libavfilter/vf_shear.c create mode 100644 libavfilter/vf_shufflepixels.c create mode 100644 libavfilter/vf_tmidequalizer.c create mode 100644 libavfilter/vf_vif.c create mode 100644 libavfilter/vif.h create mode 100644 libavformat/aaxdec.c create mode 100644 libavformat/acedec.c create mode 100644 libavformat/aiff.c create mode 100644 libavformat/amvenc.c create mode 100644 libavformat/argo_asf.h create mode 100644 libavformat/argo_brp.c create mode 100644 libavformat/avs2dec.c create mode 100644 libavformat/avs3dec.c create mode 100644 libavformat/binka.c create mode 100644 libavformat/imx.c create mode 100644 libavformat/ipudec.c create mode 100644 libavformat/isom_tags.c create mode 100644 libavformat/librist.c create mode 100644 libavformat/luodatdec.c create mode 100644 libavformat/mca.c create mode 100644 libavformat/mccdec.c create mode 100644 libavformat/mods.c create mode 100644 libavformat/moflex.c create mode 100644 libavformat/mspdec.c create mode 100644 libavformat/sga.c create mode 100644 libavformat/svs.c create mode 100644 libavformat/ttmlenc.c create mode 100644 libavutil/film_grain_params.c create mode 100644 libavutil/film_grain_params.h create mode 100644 libavutil/mips/cpu.c create mode 100644 libavutil/mips/cpu.h create mode 100644 libswscale/tests/floatimg_cmp.c create mode 100644 libswscale/x86/yuv2yuvX.asm create mode 100644 tests/checkasm/hevc_pel.c create mode 100644 tests/dnn/dnn-layer-avgpool-test.c create mode 100644 tests/dnn/dnn-layer-dense-test.c create mode 100644 tests/filtergraphs/overlay_yuv420p10 create mode 100644 tests/filtergraphs/overlay_yuv422p10 create mode 100644 tests/ref/acodec/adpcm-argo create mode 100644 tests/ref/acodec/adpcm-ima_alp create mode 100644 tests/ref/acodec/adpcm-ima_apm create mode 100644 tests/ref/acodec/adpcm-swf-wav create mode 100644 tests/ref/fate/aa-demux create mode 100644 tests/ref/fate/adpcm-ima-cunning-stereo create mode 100644 tests/ref/fate/apng-dispose-previous create mode 100644 tests/ref/fate/avid-interlaced create mode 100644 tests/ref/fate/avid-meridian create mode 100644 tests/ref/fate/dpx-probe create mode 100644 tests/ref/fate/exr-rgb-scanline-float-zip-dw-large create mode 100644 tests/ref/fate/exr-rgb-scanline-half-piz-dw-large create mode 100644 tests/ref/fate/exr-rgb-scanline-half-zip-dw-large create mode 100644 tests/ref/fate/exr-rgb-scanline-half-zip-dw-outside create mode 100644 tests/ref/fate/exr-rgb-scanline-uint32-piz-dw-large create mode 100644 tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF create mode 100644 tests/ref/fate/exr-rgb-tile-half-piz-dw-large create mode 100644 tests/ref/fate/exr-rgb-tile-half-zip create mode 100644 tests/ref/fate/exr-rgb-tile-half-zip-dw-outside create mode 100644 tests/ref/fate/exr-rgb-tile-uint32-piz-dw-large create mode 100644 tests/ref/fate/exr-ya-scanline-zip-half-12x8 create mode 100644 tests/ref/fate/filter-overlay_yuv420p10 create mode 100644 tests/ref/fate/filter-overlay_yuv422p10 create mode 100644 tests/ref/fate/filter-pixdesc-x2rgb10le create mode 100644 tests/ref/fate/filter-unsharp-yuv420p10 create mode 100644 tests/ref/fate/hevc-hdr10-plus-metadata create mode 100644 tests/ref/fate/hevc-small422chroma create mode 100644 tests/ref/fate/hls-fmp4_ac3 create mode 100644 tests/ref/fate/lscr create mode 100644 tests/ref/fate/matroska-mastering-display-metadata create mode 100644 tests/ref/fate/matroska-mpegts-remux create mode 100644 tests/ref/fate/matroska-spherical-mono-remux create mode 100644 tests/ref/fate/matroska-vp8-alpha-remux create mode 100644 tests/ref/fate/matroska-zero-length-block create mode 100644 tests/ref/fate/mov-mp4-extended-atom create mode 100644 tests/ref/fate/mxf-probe-applehdr10 create mode 100644 tests/ref/fate/sub-dvb create mode 100644 tests/ref/fate/sub-ttmlenc create mode 100644 tests/ref/fate/sws-floatimg-cmp create mode 100644 tests/ref/fate/wav-chapters diff --git a/.mailmap b/.mailmap index 50b8c0452..ba072f38c 100644 --- a/.mailmap +++ b/.mailmap @@ -10,12 +10,16 @@ - + + - + + rcombs + + diff --git a/Changelog b/Changelog index 28d79ea1a..a96e350e0 100644 --- a/Changelog +++ b/Changelog @@ -1,303 +1,90 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. -version 4.3.2: - avcodec/hapdec: Change compressed_offset to unsigned 32bit - avformat/rmdec: Check codec_length without overflow - avformat/mov: Check element count in mov_metadata_hmmt() - avcodec/vp8: Move end check into MB loop in vp78_decode_mv_mb_modes() - avcodec/fits: Check gcount and pcount being non negative - avformat/nutdec: Check timebase count against main header length - avformat/electronicarts: Clear partial_packet on error - avformat/r3d: Check samples before computing duration - avcodec/pnm_parser: Check av_image_get_buffer_size() for failure - avformat/wavdec: Consider AV_INPUT_BUFFER_PADDING_SIZE in set_spdif() - avformat/rmdec: Check remaining space in debug av_log() loop - avformat/flvdec: Treat high ts byte as unsigned - avformat/samidec: Sanity check pts - avcodec/jpeg2000dec: Check atom_size in jp2_find_codestream() - avformat/avidec: Use 64bit in get_duration() - avformat/mov: Check for duplicate st3d - avformat/mvdec: Check for EOF in read_index() - avcodec/jpeglsdec: Fix k=16 in ls_get_code_regular() - avformat/id3v2: Check the return from avio_get_str() - avcodec/hevc_sei: Check payload size in decode_nal_sei_message() - libavutil/eval: Remove CONFIG_TRAPV special handling - avformat/wtvdec: Check len in parse_chunks() to avoid overflow - avformat/asfdec_f: Add an additional check for the extradata size - avformat/3dostr: Check sample_rate - avformat/4xm: Make audio_frame_count 64bit - avformat/mov: Use av_mul_q() to avoid integer overflows - avcodec/vp9dsp_template: Fix integer overflows in itxfm_wrapper - avformat/rmdec: Reorder operations to avoid overflow - avcodec/mxpegdec: fix SOF counting - avcodec/rscc: Check inflated_buf size whan it is used - avformat/mvdec: Sanity check SAMPLE_WIDTH - avcodec/nvenc: fix timestamp offset ticks logic - avformat/rmdec: Fix codecdata_length overflow check - avcodec/simple_idct: Fix undefined integer overflow in idct4row() - avformat/wavdec: Check block_align vs. channels before combining them - avformat/tta: Use 64bit intermediate for index - avformat/soxdec: Check channels to be positive - avformat/smacker: Check for too small pts_inc - avformat/sbgdec: Use av_sat_add64() in str_to_time() - avcodec/cscd: Check output len in zlib as in lzo - avcodec/vp3: Check input amount in theora_decode_header() - avformat/wavdec: Check avio_get_str16le() for failure - avformat/flvdec: Check for EOF in amf_skip_tag() - avformat/aiffdec: Check size before subtraction in get_aiff_header() - avformat/electronicarts: More chunk_size checks - avcodec/cfhd: check peak.offset - avformat/tedcaptionsdec: Check for overflow in parse_int() - avformat/nuv: Check channels - avcodec/siren: Increase noise category 5 and 6 - avformat/mpc8: Check size before implicitly converting to int - avformat/nutdec: Fix integer overflow in count computation - avformat/mvi: Use 64bit for testing dimensions - avformat/utils: Check dts in update_initial_timestamps() more - avformat/mpsubdec: Use av_sat_add/sub64() in fracval handling - avformat/flvdec: Check for avio_read() failure in amf_get_string() - avformat/flvdec: Check for nesting depth in amf_skip_tag() - avformat/flvdec: Check for nesting depth in amf_parse_object() - avformat/asfdec_o: Check for EOF in asf_read_marker() - avformat/flvdec: Use av_sat_add64() for pts computation - avformat/utils: Check dts - (1<: +- AudioToolbox output device +- MacCaption demuxer +- PGX decoder +- chromanr video filter +- VDPAU accelerated HEVC 10/12bit decoding +- ADPCM IMA Ubisoft APM encoder +- Rayman 2 APM muxer +- AV1 encoding support SVT-AV1 +- Cineform HD encoder +- ADPCM Argonaut Games encoder +- Argonaut Games ASF muxer +- AV1 Low overhead bitstream format demuxer +- RPZA video encoder +- ADPCM IMA MOFLEX decoder +- MobiClip FastAudio decoder +- MobiClip video decoder +- MOFLEX demuxer +- MODS demuxer +- PhotoCD decoder +- MCA demuxer +- AV1 decoder (Hardware acceleration used only) +- SVS demuxer +- Argonaut Games BRP demuxer +- DAT demuxer +- aax demuxer +- IPU decoder, parser and demuxer +- Intel QSV-accelerated AV1 decoding +- Argonaut Games Video decoder +- libwavpack encoder removed +- ACE demuxer +- AVS3 demuxer +- AVS3 video decoder via libuavs3d +- Cintel RAW decoder +- VDPAU accelerated VP9 10/12bit decoding +- afreqshift and aphaseshift filters +- High Voltage Software ADPCM encoder +- LEGO Racers ALP (.tun & .pcm) muxer +- AV1 VAAPI decoder +- adenorm filter +- ADPCM IMA AMV encoder +- AMV muxer +- NVDEC AV1 hwaccel +- DXVA2/D3D11VA hardware accelerated AV1 decoding +- speechnorm filter +- SpeedHQ encoder +- asupercut filter +- asubcut filter +- Microsoft Paint (MSP) version 2 decoder +- Microsoft Paint (MSP) demuxer +- AV1 monochrome encoding support via libaom >= 2.0.1 +- asuperpass and asuperstop filter +- shufflepixels filter +- tmidequalizer filter +- estdif filter +- epx filter +- Dolby E parser +- shear filter +- kirsch filter +- colortemperature filter +- colorcontrast filter +- PFM encoder +- colorcorrect filter +- binka demuxer +- XBM parser +- xbm_pipe demuxer +- colorize filter +- CRI parser +- aexciter audio filter +- exposure video filter +- monochrome video filter +- setts bitstream filter +- vif video filter +- OpenEXR image encoder +- Simbiosis IMX decoder +- Simbiosis IMX demuxer +- Digital Pictures SGA demuxer and decoders +- TTML subtitle encoder and muxer +- identity video filter +- msad video filter +- gophers protocol +- RIST protocol via librist -version 4.3.1: - avcodec/tiff: Check input space in dng_decode_jpeg() - avcodec/mjpeg_parser: Adjust size rejection threshold - avcodec/cbs_jpeg: Fix uninitialized end index in cbs_jpeg_split_fragment() - avformat/sdp: Fix potential write beyond end of buffer - avformat/mm: Check for existence of audio stream - avformat/mov: Fix unaligned read of uint32_t and endian-dependance in mov_read_default - avcodec/apedec: Fix undefined integer overflow with 24bit - avcodec/loco: Fix integer overflow with large values from loco_get_rice() - avformat/smjpegdec: Check the existence of referred streams - avcodec/tiff: Check frame parameters before blit for DNG - avcodec/mjpegdec: Limit bayer to single plane outputting format - avcodec/pnmdec: Fix misaligned reads - avcodec/mv30: Fix integer overflows in idct2_1d() - avcodec/hcadec: Check total_band_count against imdct_in size - avcodec/scpr3: Fix out of array access with dectab - avcodec/tiff: Do not overrun the array ends in dng_blit() - avcodec/dstdec: Replace AC overread check by sample rate check - dnn_backend_native: Add overflow check for length calculation. - avcodec/h264_metadata_bsf: Fix invalid av_freep - avcodec/cbs_h265: set default VUI parameters when vui_parameters_present_flag is false - avcodec/av1_parser: initialize avctx->pix_fmt - avcodec/av1_parser: add missing parsing for RGB pixel format signaling - avcodec/av1_parser: set context values outside the OBU parsing loop - avutil/avsscanf: Add () to avoid integer overflow in scanexp() - avformat/utils: reorder duration computation to avoid overflow - avcodec/pngdec: Check for fctl after idat - avformat/hls: Pass a copy of the URL for probing - avutil/common: Fix integer overflow in av_ceil_log2_c() - avcodec/wmalosslessdec: fix overflow with pred in revert_cdlms - avformat/mvdec: Fix integer overflow with billions of channels - avformat/microdvddec: skip malformed lines without frame number. - dnn_backend_native: check operand index - dnn_backend_native.c: refine code for fail case - avformat/mov: fix memleaks - libavformat/mov: Fix memleaks when demuxing DV audio - avcodec/cbs_av1: Fix writing uvlc numbers >= INT_MAX - avformat/avc, mxfenc: Avoid allocation of H264 SPS structure, fix memleak - avcodec/bitstream: Don't check for undefined behaviour after it happened - avformat/aviobuf: Also return truncated buffer in avio_get_dyn_buf() - avformat/aviobuf: Don't check for overflow after it happened - version 4.3: - v360 filter - Intel QSV-accelerated MJPEG decoding diff --git a/MAINTAINERS b/MAINTAINERS index af02cf00a..3b6cfad4f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -55,9 +55,9 @@ fate.ffmpeg.org Timothy Gu Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos Patchwork Andriy Gelman mailing lists Baptiste Coudurier -Twitter Lou Logan, Reynaldo H. Verdejo Pinochet +Twitter Reynaldo H. Verdejo Pinochet Launchpad Timothy Gu -ffmpeg-security Andreas Cadhalpun, Carl Eugen Hoyos, Clément Bœsch, Michael Niedermayer, Reimar Doeffinger, Rodger Combs, wm4 +ffmpeg-security Andreas Cadhalpun, Carl Eugen Hoyos, Clément Bœsch, Michael Niedermayer, Reimar Doeffinger, rcombs, wm4 libavutil @@ -144,7 +144,7 @@ Codecs: ass* Aurelien Jacobs asv* Michael Niedermayer atrac3plus* Maxim Poliakovski - audiotoolbox* Rodger Combs + audiotoolbox* rcombs avs2* Huiwen Ren bgmc.c, bgmc.h Thilo Borgmann binkaudio.c Peter Ross @@ -235,7 +235,6 @@ Codecs: rv10.c Michael Niedermayer s3tc* Ivo van Poorten smc.c Mike Melanson - smvjpegdec.c Ash Hughes snow* Michael Niedermayer, Loren Merritt sonic.c Alex Beregszaszi speedhq.c Steinar H. Gunderson @@ -393,7 +392,12 @@ Muxers/Demuxers: afc.c Paul B Mahol aiffdec.c Baptiste Coudurier, Matthieu Bouron aiffenc.c Baptiste Coudurier, Matthieu Bouron + alp.c Zane van Iperen + amvenc.c Zane van Iperen + apm.c Zane van Iperen apngdec.c Benoit Fouet + argo_asf.c Zane van Iperen + argo_brp.c Zane van Iperen ass* Aurelien Jacobs astdec.c Paul B Mahol astenc.c James Almer @@ -431,6 +435,7 @@ Muxers/Demuxers: ircam* Paul B Mahol iss.c Stefan Gehrer jvdec.c Peter Ross + kvag.c Zane van Iperen libmodplug.c Clément Bœsch libopenmpt.c Josh de Kock lmlm4.c Ivo van Poorten @@ -463,6 +468,7 @@ Muxers/Demuxers: oggparse*.c David Conrad oma.c Maxim Poliakovski paf.c Paul B Mahol + pp_bnk.c Zane van Iperen psxstr.c Mike Melanson pva.c Ivo van Poorten pvfdec.c Paul B Mahol @@ -607,7 +613,6 @@ Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368 James Almer 7751 2E8C FD94 A169 57E6 9A7A 1463 01AD 7376 59E0 Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE -Lou Logan (llogan) 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A Lynne FE50 139C 6805 72CA FD52 1F8D A2FE A5F0 3F03 4464 Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93 @@ -629,3 +634,4 @@ Tiancheng "Timothy" Gu 9456 AFC0 814A 8139 E994 8351 7FE6 B095 B582 B0D4 Tim Nicholson 38CF DB09 3ED0 F607 8B67 6CED 0C0B FC44 8B0B FC83 Tomas Härdin (thardin) A79D 4E3D F38F 763F 91F5 8B33 A01E 8AE0 41BB 2551 Wei Gao 4269 7741 857A 0E60 9EC5 08D2 4744 4EFA 62C1 87B9 +Zane van Iperen (zane) 61AE D40F 368B 6F26 9DAE 3892 6861 6B2D 8AC4 DCC5 diff --git a/Makefile b/Makefile index 45a22b0cb..7e9d8b08c 100644 --- a/Makefile +++ b/Makefile @@ -53,13 +53,23 @@ target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS) tools/target_bsf_%_fuzzer$(EXESUF): tools/target_bsf_%_fuzzer.o $(FF_DEP_LIBS) $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH) +target_dem_%_fuzzer$(EXESUF): target_dem_%_fuzzer.o $(FF_DEP_LIBS) + $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH) + tools/target_dem_fuzzer$(EXESUF): tools/target_dem_fuzzer.o $(FF_DEP_LIBS) $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH) +tools/target_io_dem_fuzzer$(EXESUF): tools/target_io_dem_fuzzer.o $(FF_DEP_LIBS) + $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH) + + +tools/enum_options$(EXESUF): ELIBS = $(FF_EXTRALIBS) +tools/enum_options$(EXESUF): $(FF_DEP_LIBS) tools/sofa2wavs$(EXESUF): ELIBS = $(FF_EXTRALIBS) tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS) tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS) tools/target_dec_%_fuzzer$(EXESUF): $(FF_DEP_LIBS) +tools/target_dem_%_fuzzer$(EXESUF): $(FF_DEP_LIBS) CONFIGURABLE_COMPONENTS = \ $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \ @@ -100,7 +110,7 @@ include $(SRC_PATH)/fftools/Makefile include $(SRC_PATH)/doc/Makefile include $(SRC_PATH)/doc/examples/Makefile -libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h +libavcodec/avcodec.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h $(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF) ifeq ($(STRIPTYPE),direct) diff --git a/RELEASE b/RELEASE index cc2fbe89b..515be8f91 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -4.3.2 +4.4 diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 2511706d5..67339dca8 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,10 +1,10 @@ ┌────────────────────────────────────┐ - │ RELEASE NOTES for FFmpeg 4.3 "4:3" │ + │ RELEASE NOTES for FFmpeg 4.4 "Rao" │ └────────────────────────────────────┘ - The FFmpeg Project proudly presents FFmpeg 4.3 "4:3", about 10 - months after the release of FFmpeg 4.2. + The FFmpeg Project proudly presents FFmpeg 4.4 "Rao", about 10 + months after the release of FFmpeg 4.3. A complete Changelog is available at the root of the project, and the complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git diff --git a/VERSION b/VERSION index cc2fbe89b..515be8f91 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.3.2 +4.4 diff --git a/compat/cuda/cuda_runtime.h b/compat/cuda/cuda_runtime.h index 92c55ad85..c5450b254 100644 --- a/compat/cuda/cuda_runtime.h +++ b/compat/cuda/cuda_runtime.h @@ -1,7 +1,7 @@ /* * Minimum CUDA compatibility definitions header * - * Copyright (c) 2019 Rodger Combs + * Copyright (c) 2019 rcombs * * This file is part of FFmpeg. * @@ -49,6 +49,16 @@ typedef struct __device_builtin__ __align__(4) ushort2 unsigned short x, y; } ushort2; +typedef struct __device_builtin__ __align__(8) float2 +{ + float x, y; +} float2; + +typedef struct __device_builtin__ __align__(8) int2 +{ + int x, y; +} int2; + typedef struct __device_builtin__ uint3 { unsigned int x, y, z; @@ -56,11 +66,6 @@ typedef struct __device_builtin__ uint3 typedef struct uint3 dim3; -typedef struct __device_builtin__ __align__(8) int2 -{ - int x, y; -} int2; - typedef struct __device_builtin__ __align__(4) uchar4 { unsigned char x, y, z, w; @@ -68,7 +73,7 @@ typedef struct __device_builtin__ __align__(4) uchar4 typedef struct __device_builtin__ __align__(8) ushort4 { - unsigned char x, y, z, w; + unsigned short x, y, z, w; } ushort4; typedef struct __device_builtin__ __align__(16) int4 @@ -76,6 +81,11 @@ typedef struct __device_builtin__ __align__(16) int4 int x, y, z, w; } int4; +typedef struct __device_builtin__ __align__(16) float4 +{ + float x, y, z, w; +} float4; + // Accessors for special registers #define GETCOMP(reg, comp) \ asm("mov.u32 %0, %%" #reg "." #comp ";" : "=r"(tmp)); \ @@ -100,24 +110,31 @@ GET(getThreadIdx, tid) #define threadIdx (getThreadIdx()) // Basic initializers (simple macros rather than inline functions) +#define make_int2(a, b) ((int2){.x = a, .y = b}) #define make_uchar2(a, b) ((uchar2){.x = a, .y = b}) #define make_ushort2(a, b) ((ushort2){.x = a, .y = b}) +#define make_float2(a, b) ((float2){.x = a, .y = b}) +#define make_int4(a, b, c, d) ((int4){.x = a, .y = b, .z = c, .w = d}) #define make_uchar4(a, b, c, d) ((uchar4){.x = a, .y = b, .z = c, .w = d}) #define make_ushort4(a, b, c, d) ((ushort4){.x = a, .y = b, .z = c, .w = d}) +#define make_float4(a, b, c, d) ((float4){.x = a, .y = b, .z = c, .w = d}) // Conversions from the tex instruction's 4-register output to various types #define TEX2D(type, ret) static inline __device__ void conv(type* out, unsigned a, unsigned b, unsigned c, unsigned d) {*out = (ret);} TEX2D(unsigned char, a & 0xFF) TEX2D(unsigned short, a & 0xFFFF) +TEX2D(float, a) TEX2D(uchar2, make_uchar2(a & 0xFF, b & 0xFF)) TEX2D(ushort2, make_ushort2(a & 0xFFFF, b & 0xFFFF)) +TEX2D(float2, make_float2(a, b)) TEX2D(uchar4, make_uchar4(a & 0xFF, b & 0xFF, c & 0xFF, d & 0xFF)) TEX2D(ushort4, make_ushort4(a & 0xFFFF, b & 0xFFFF, c & 0xFFFF, d & 0xFFFF)) +TEX2D(float4, make_float4(a, b, c, d)) // Template calling tex instruction and converting the output to the selected type -template -static inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y) +template +inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y) { T ret; unsigned ret1, ret2, ret3, ret4; @@ -128,4 +145,44 @@ static inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y return ret; } +template<> +inline __device__ float4 tex2D(cudaTextureObject_t texObject, float x, float y) +{ + float4 ret; + asm("tex.2d.v4.f32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" : + "=r"(ret.x), "=r"(ret.y), "=r"(ret.z), "=r"(ret.w) : + "l"(texObject), "f"(x), "f"(y)); + return ret; +} + +template<> +inline __device__ float tex2D(cudaTextureObject_t texObject, float x, float y) +{ + return tex2D(texObject, x, y).x; +} + +template<> +inline __device__ float2 tex2D(cudaTextureObject_t texObject, float x, float y) +{ + float4 ret = tex2D(texObject, x, y); + return make_float2(ret.x, ret.y); +} + +// Math helper functions +static inline __device__ float floorf(float a) { return __builtin_floorf(a); } +static inline __device__ float floor(float a) { return __builtin_floorf(a); } +static inline __device__ double floor(double a) { return __builtin_floor(a); } +static inline __device__ float ceilf(float a) { return __builtin_ceilf(a); } +static inline __device__ float ceil(float a) { return __builtin_ceilf(a); } +static inline __device__ double ceil(double a) { return __builtin_ceil(a); } +static inline __device__ float truncf(float a) { return __builtin_truncf(a); } +static inline __device__ float trunc(float a) { return __builtin_truncf(a); } +static inline __device__ double trunc(double a) { return __builtin_trunc(a); } +static inline __device__ float fabsf(float a) { return __builtin_fabsf(a); } +static inline __device__ float fabs(float a) { return __builtin_fabsf(a); } +static inline __device__ double fabs(double a) { return __builtin_fabs(a); } + +static inline __device__ float __sinf(float a) { return __nvvm_sin_approx_f(a); } +static inline __device__ float __cosf(float a) { return __nvvm_cos_approx_f(a); } + #endif /* COMPAT_CUDA_CUDA_RUNTIME_H */ diff --git a/configure b/configure index 36713ab65..d7a3f507e 100755 --- a/configure +++ b/configure @@ -190,9 +190,9 @@ External library support: Using any of the following switches will allow FFmpeg to link to the corresponding external library. All the components depending on that library will become enabled, if all their other dependencies are met and they are not - explicitly disabled. E.g. --enable-libwavpack will enable linking to - libwavpack and allow the libwavpack encoder to be built, unless it is - specifically disabled with --disable-encoder=libwavpack. + explicitly disabled. E.g. --enable-libopus will enable linking to + libopus and allow the libopus encoder to be built, unless it is + specifically disabled with --disable-encoder=libopus. Note that only the system libraries are auto-detected. All the other external libraries must be explicitly enabled. @@ -253,10 +253,13 @@ External library support: --enable-libopenh264 enable H.264 encoding via OpenH264 [no] --enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no] --enable-libopenmpt enable decoding tracked files via libopenmpt [no] + --enable-libopenvino enable OpenVINO as a DNN module backend + for DNN based filters like dnn_processing [no] --enable-libopus enable Opus de/encoding via libopus [no] --enable-libpulse enable Pulseaudio input via libpulse [no] --enable-librabbitmq enable RabbitMQ library [no] --enable-librav1e enable AV1 encoding via rav1e [no] + --enable-librist enable RIST via librist [no] --enable-librsvg enable SVG rasterization via librsvg [no] --enable-librubberband enable rubberband needed for rubberband filter [no] --enable-librtmp enable RTMP[E] support via librtmp [no] @@ -267,6 +270,7 @@ External library support: --enable-libspeex enable Speex de/encoding via libspeex [no] --enable-libsrt enable Haivision SRT protocol via libsrt [no] --enable-libssh enable SFTP protocol via libssh [no] + --enable-libsvtav1 enable AV1 encoding via SVT [no] --enable-libtensorflow enable TensorFlow as a DNN module backend for DNN based filters like sr [no] --enable-libtesseract enable Tesseract, needed for ocr filter [no] @@ -274,6 +278,7 @@ External library support: --enable-libtls enable LibreSSL (via libtls), needed for https support if openssl, gnutls or mbedtls is not used [no] --enable-libtwolame enable MP2 encoding via libtwolame [no] + --enable-libuavs3d enable AVS3 decoding via libuavs3d [no] --enable-libv4l2 enable libv4l2/v4l-utils [no] --enable-libvidstab enable video stabilization using vid.stab [no] --enable-libvmaf enable vmaf filter via libvmaf [no] @@ -281,7 +286,6 @@ External library support: --enable-libvorbis enable Vorbis en/decoding via libvorbis, native implementation exists [no] --enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no] - --enable-libwavpack enable wavpack encoding via libwavpack [no] --enable-libwebp enable WebP encoding via libwebp [no] --enable-libx264 enable H.264 encoding via x264 [no] --enable-libx265 enable HEVC encoding via x265 [no] @@ -1741,7 +1745,6 @@ EXTERNAL_LIBRARY_VERSION3_LIST=" liblensfun libopencore_amrnb libopencore_amrwb - libvmaf libvo_amrwbenc mbedtls rkmpp @@ -1790,10 +1793,12 @@ EXTERNAL_LIBRARY_LIST=" libopenh264 libopenjpeg libopenmpt + libopenvino libopus libpulse librabbitmq librav1e + librist librsvg librtmp libshine @@ -1803,14 +1808,16 @@ EXTERNAL_LIBRARY_LIST=" libspeex libsrt libssh + libsvtav1 libtensorflow libtesseract libtheora libtwolame + libuavs3d libv4l2 + libvmaf libvorbis libvpx - libwavpack libwebp libxml2 libzimg @@ -2120,6 +2127,7 @@ HEADERS_LIST=" ES2_gl_h gsm_h io_h + linux_dma_buf_h linux_perf_event_h machine_ioctl_bt848_h machine_ioctl_meteor_h @@ -2282,6 +2290,7 @@ TOOLCHAIN_FEATURES=" TYPES_LIST=" kCMVideoCodecType_HEVC + kCMVideoCodecType_HEVCWithAlpha kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ kCVImageBufferTransferFunction_ITU_R_2100_HLG @@ -2320,6 +2329,7 @@ HAVE_LIST=" $THREADS_LIST $TOOLCHAIN_FEATURES $TYPES_LIST + libdrm_getfb2 makeinfo makeinfo_html opencl_d3d11 @@ -2338,6 +2348,7 @@ CONFIG_EXTRA=" aandcttables ac3dsp adts_header + atsc_a53 audio_frame_queue audiodsp blockdsp @@ -2551,7 +2562,7 @@ mips64r6_deps="mips" mipsfpu_deps="mips" mipsdsp_deps="mips" mipsdspr2_deps="mips" -mmi_deps="mips" +mmi_deps_any="loongson2 loongson3" msa_deps="mipsfpu" msa2_deps="msa" @@ -2620,14 +2631,15 @@ cbs_mpeg2_select="cbs" cbs_vp9_select="cbs" dct_select="rdft" dirac_parse_select="golomb" -dnn_suggest="libtensorflow" +dnn_suggest="libtensorflow libopenvino" +dnn_deps="swscale" error_resilience_select="me_cmp" faandct_deps="faan" faandct_select="fdctdsp" faanidct_deps="faan" faanidct_select="idctdsp" h264dsp_select="startcode" -hevcparse_select="golomb" +hevcparse_select="atsc_a53 golomb" frame_thread_encoder_deps="encoders threads" intrax8_select="blockdsp idctdsp" mdct_select="fft" @@ -2643,7 +2655,7 @@ rdft_select="fft" # decoders / encoders aac_decoder_select="adts_header mdct15 mdct sinewin" -aac_fixed_decoder_select="adts_header mdct sinewin" +aac_fixed_decoder_select="adts_header mdct" aac_encoder_select="audio_frame_queue iirfilter lpc mdct sinewin" aac_latm_decoder_select="aac_decoder aac_latm_parser" ac3_decoder_select="ac3_parser ac3dsp bswapdsp fmtconvert mdct" @@ -2678,7 +2690,7 @@ atrac3al_decoder_select="mdct" atrac3p_decoder_select="mdct sinewin" atrac3pal_decoder_select="mdct sinewin" atrac9_decoder_select="mdct" -avrn_decoder_select="exif jpegtables" +av1_decoder_select="cbs_av1" bink_decoder_select="blockdsp hpeldsp" binkaudio_dct_decoder_select="mdct rdft dct sinewin wma_freqs" binkaudio_rdft_decoder_select="mdct rdft sinewin wma_freqs" @@ -2706,6 +2718,7 @@ eamad_decoder_select="aandcttables blockdsp bswapdsp idctdsp mpegvideo" eatgq_decoder_select="aandcttables" eatqi_decoder_select="aandcttables blockdsp bswapdsp idctdsp" exr_decoder_deps="zlib" +exr_encoder_deps="zlib" ffv1_decoder_select="rangecoder" ffv1_encoder_select="rangecoder" ffvhuff_decoder_select="huffyuv_decoder" @@ -2731,12 +2744,12 @@ h263_encoder_select="h263dsp mpegvideoenc" h263i_decoder_select="h263_decoder" h263p_decoder_select="h263_decoder" h263p_encoder_select="h263_encoder" -h264_decoder_select="cabac golomb h264chroma h264dsp h264parse h264pred h264qpel videodsp" +h264_decoder_select="atsc_a53 cabac golomb h264chroma h264dsp h264parse h264pred h264qpel videodsp" h264_decoder_suggest="error_resilience" hap_decoder_select="snappy texturedsp" hap_encoder_deps="libsnappy" hap_encoder_select="texturedspenc" -hevc_decoder_select="bswapdsp cabac golomb hevcparse videodsp" +hevc_decoder_select="atsc_a53 bswapdsp cabac golomb hevcparse videodsp" huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp" huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp" hymt_decoder_select="huffyuv_decoder" @@ -2751,7 +2764,7 @@ interplay_video_decoder_select="hpeldsp" jpegls_decoder_select="mjpeg_decoder" jv_decoder_select="blockdsp" lagarith_decoder_select="llviddsp" -ljpeg_encoder_select="idctdsp jpegtables mpegvideoenc" +ljpeg_encoder_select="idctdsp jpegtables" lscr_decoder_deps="zlib" magicyuv_decoder_select="llviddsp" magicyuv_encoder_select="llvidencdsp" @@ -2763,6 +2776,7 @@ mjpeg_encoder_select="jpegtables mpegvideoenc" mjpegb_decoder_select="mjpeg_decoder" mlp_decoder_select="mlp_parser" mlp_encoder_select="lpc audio_frame_queue" +mobiclip_decoder_select="bswapdsp golomb" motionpixels_decoder_select="bswapdsp" mp1_decoder_select="mpegaudio" mp1float_decoder_select="mpegaudio" @@ -2791,7 +2805,7 @@ msmpeg4v2_encoder_select="h263_encoder" msmpeg4v3_decoder_select="h263_decoder" msmpeg4v3_encoder_select="h263_encoder" mss2_decoder_select="mpegvideo qpeldsp vc1_decoder" -mts2_decoder_select="mss34dsp" +mts2_decoder_select="jpegtables mss34dsp" mv30_decoder_select="aandcttables blockdsp" mvha_decoder_deps="zlib" mvha_decoder_select="llviddsp" @@ -2828,6 +2842,7 @@ rv40_decoder_select="golomb h264pred h264qpel mpegvideo rv34dsp" screenpresso_decoder_deps="zlib" shorten_decoder_select="bswapdsp" sipr_decoder_select="lsp" +smvjpeg_decoder_select="mjpeg_decoder" snow_decoder_select="dwt h264qpel hpeldsp me_cmp rangecoder videodsp" snow_encoder_select="dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder" sonic_decoder_select="golomb rangecoder" @@ -2835,6 +2850,7 @@ sonic_encoder_select="golomb rangecoder" sonic_ls_encoder_select="golomb rangecoder" sp5x_decoder_select="mjpeg_decoder" speedhq_decoder_select="mpegvideo" +speedhq_encoder_select="mpegvideoenc" srgc_decoder_deps="zlib" svq1_decoder_select="hpeldsp" svq1_encoder_select="hpeldsp me_cmp mpegvideoenc" @@ -2908,6 +2924,16 @@ videotoolbox_hwaccel_deps="videotoolbox pthreads" videotoolbox_hwaccel_extralibs="-framework QuartzCore" xvmc_deps="X11_extensions_XvMClib_h" +av1_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_AV1" +av1_d3d11va_hwaccel_select="av1_decoder" +av1_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_AV1" +av1_d3d11va2_hwaccel_select="av1_decoder" +av1_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_AV1" +av1_dxva2_hwaccel_select="av1_decoder" +av1_nvdec_hwaccel_deps="nvdec CUVIDAV1PICPARAMS" +av1_nvdec_hwaccel_select="av1_decoder" +av1_vaapi_hwaccel_deps="vaapi VADecPictureParameterBufferAV1_bit_depth_idx" +av1_vaapi_hwaccel_select="av1_decoder" h263_vaapi_hwaccel_deps="vaapi" h263_vaapi_hwaccel_select="h263_decoder" h263_videotoolbox_hwaccel_deps="videotoolbox" @@ -3042,6 +3068,7 @@ nvenc_encoder_deps="nvenc" aac_mf_encoder_deps="mediafoundation" ac3_mf_encoder_deps="mediafoundation" +av1_cuvid_decoder_deps="cuvid CUVIDAV1PICPARAMS" h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m" h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m" h264_amf_encoder_deps="amf" @@ -3053,9 +3080,10 @@ h264_mediacodec_decoder_select="h264_mp4toannexb_bsf h264_parser" h264_mf_encoder_deps="mediafoundation" h264_mmal_decoder_deps="mmal" h264_nvenc_encoder_deps="nvenc" +h264_nvenc_encoder_select="atsc_a53" h264_omx_encoder_deps="omx" h264_qsv_decoder_select="h264_mp4toannexb_bsf qsvdec" -h264_qsv_encoder_select="qsvenc" +h264_qsv_encoder_select="atsc_a53 qsvenc" h264_rkmpp_decoder_deps="rkmpp" h264_rkmpp_decoder_select="h264_mp4toannexb_bsf" h264_vaapi_encoder_select="cbs_h264 vaapi_encode" @@ -3069,6 +3097,7 @@ hevc_mediacodec_decoder_deps="mediacodec" hevc_mediacodec_decoder_select="hevc_mp4toannexb_bsf hevc_parser" hevc_mf_encoder_deps="mediafoundation" hevc_nvenc_encoder_deps="nvenc" +hevc_nvenc_encoder_select="atsc_a53" hevc_qsv_decoder_select="hevc_mp4toannexb_bsf qsvdec" hevc_qsv_encoder_select="hevcparse qsvenc" hevc_rkmpp_decoder_deps="rkmpp" @@ -3128,11 +3157,12 @@ vp9_qsv_encoder_deps="libmfx MFX_CODEC_VP9" vp9_qsv_encoder_select="qsvenc" vp9_v4l2m2m_decoder_deps="v4l2_m2m vp9_v4l2_m2m" wmv3_crystalhd_decoder_select="crystalhd" +av1_qsv_decoder_select="qsvdec" # parsers aac_parser_select="adts_header" av1_parser_select="cbs_av1" -h264_parser_select="golomb h264dsp h264parse" +h264_parser_select="atsc_a53 golomb h264dsp h264parse" hevc_parser_select="hevcparse" mpegaudio_parser_select="mpegaudioheader" mpegvideo_parser_select="mpegvideo" @@ -3193,9 +3223,9 @@ pcm_mulaw_at_encoder_deps="audiotoolbox" pcm_mulaw_at_encoder_select="audio_frame_queue" chromaprint_muxer_deps="chromaprint" h264_videotoolbox_encoder_deps="pthreads" -h264_videotoolbox_encoder_select="videotoolbox_encoder" +h264_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder" hevc_videotoolbox_encoder_deps="pthreads" -hevc_videotoolbox_encoder_select="videotoolbox_encoder" +hevc_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder" libaom_av1_decoder_deps="libaom" libaom_av1_encoder_deps="libaom" libaom_av1_encoder_select="extract_extradata_bsf" @@ -3204,6 +3234,7 @@ libcelt_decoder_deps="libcelt" libcodec2_decoder_deps="libcodec2" libcodec2_encoder_deps="libcodec2" libdav1d_decoder_deps="libdav1d" +libdav1d_decoder_select="atsc_a53" libdavs2_decoder_deps="libdavs2" libfdk_aac_decoder_deps="libfdk_aac" libfdk_aac_encoder_deps="libfdk_aac" @@ -3240,8 +3271,10 @@ libshine_encoder_select="audio_frame_queue" libspeex_decoder_deps="libspeex" libspeex_encoder_deps="libspeex" libspeex_encoder_select="audio_frame_queue" +libsvtav1_encoder_deps="libsvtav1" libtheora_encoder_deps="libtheora" libtwolame_encoder_deps="libtwolame" +libuavs3d_decoder_deps="libuavs3d" libvo_amrwbenc_encoder_deps="libvo_amrwbenc" libvorbis_decoder_deps="libvorbis" libvorbis_encoder_deps="libvorbis libvorbisenc" @@ -3250,12 +3283,11 @@ libvpx_vp8_decoder_deps="libvpx" libvpx_vp8_encoder_deps="libvpx" libvpx_vp9_decoder_deps="libvpx" libvpx_vp9_encoder_deps="libvpx" -libwavpack_encoder_deps="libwavpack" -libwavpack_encoder_select="audio_frame_queue" libwebp_encoder_deps="libwebp" libwebp_anim_encoder_deps="libwebp" libx262_encoder_deps="libx262" libx264_encoder_deps="libx264" +libx264_encoder_select="atsc_a53" libx264rgb_encoder_deps="libx264 x264_csp_bgr" libx264rgb_encoder_select="libx264_encoder" libx265_encoder_deps="libx265" @@ -3277,9 +3309,9 @@ asf_o_demuxer_select="riffdec" asf_muxer_select="riffenc" asf_stream_muxer_select="asf_muxer" av1_demuxer_select="av1_frame_merge_bsf av1_parser" -avi_demuxer_select="iso_media riffdec exif" +avi_demuxer_select="riffdec exif" avi_muxer_select="riffenc" -caf_demuxer_select="iso_media riffdec" +caf_demuxer_select="iso_media" caf_muxer_select="iso_media" dash_muxer_select="mp4_muxer" dash_demuxer_deps="libxml2" @@ -3305,9 +3337,9 @@ ismv_muxer_select="mov_muxer" ivf_muxer_select="av1_metadata_bsf vp9_superframe_bsf" latm_muxer_select="aac_adtstoasc_bsf" matroska_audio_muxer_select="matroska_muxer" -matroska_demuxer_select="iso_media riffdec" +matroska_demuxer_select="riffdec" matroska_demuxer_suggest="bzlib lzo zlib" -matroska_muxer_select="iso_media riffenc vp9_superframe_bsf aac_adtstoasc_bsf" +matroska_muxer_select="riffenc vp9_superframe_bsf aac_adtstoasc_bsf" mlp_demuxer_select="mlp_parser" mmf_muxer_select="riffenc" mov_demuxer_select="iso_media riffdec" @@ -3317,13 +3349,14 @@ mp3_demuxer_select="mpegaudio_parser" mp3_muxer_select="mpegaudioheader" mp4_muxer_select="mov_muxer" mpegts_demuxer_select="iso_media" -mpegts_muxer_select="adts_muxer latm_muxer h264_mp4toannexb_bsf hevc_mp4toannexb_bsf" +mpegts_muxer_select="ac3_parser adts_muxer latm_muxer h264_mp4toannexb_bsf hevc_mp4toannexb_bsf" mpegtsraw_demuxer_select="mpegts_demuxer" mxf_muxer_select="golomb pcm_rechunk_bsf" mxf_d10_muxer_select="mxf_muxer" mxf_opatom_muxer_select="mxf_muxer" nut_muxer_select="riffenc" nuv_demuxer_select="riffdec" +obu_demuxer_select="av1_frame_merge_bsf av1_parser" oga_muxer_select="ogg_muxer" ogg_demuxer_select="dirac_parse" ogv_muxer_select="ogg_muxer" @@ -3331,6 +3364,7 @@ opus_muxer_select="ogg_muxer" psp_muxer_select="mov_muxer" rtp_demuxer_select="sdp_demuxer" rtp_muxer_select="golomb jpegtables" +rtp_mpegts_muxer_select="mpegts_muxer rtp_muxer" rtpdec_select="asf_demuxer jpegtables mov_demuxer mpegts_demuxer rm_demuxer rtp_protocol srtp" rtsp_demuxer_select="http_protocol rtpdec" rtsp_muxer_select="rtp_muxer http_protocol rtp_protocol rtpenc_chain" @@ -3352,7 +3386,7 @@ w64_muxer_select="wav_muxer" wav_demuxer_select="riffdec" wav_muxer_select="riffenc" webm_chunk_muxer_select="webm_muxer" -webm_muxer_select="iso_media riffenc" +webm_muxer_select="riffenc" webm_dash_manifest_demuxer_select="matroska_demuxer" wtv_demuxer_select="mpegts_demuxer riffdec" wtv_muxer_select="mpegts_muxer riffenc" @@ -3367,6 +3401,8 @@ alsa_outdev_deps="alsa" avfoundation_indev_deps="avfoundation corevideo coremedia pthreads" avfoundation_indev_suggest="coregraphics applicationservices" avfoundation_indev_extralibs="-framework Foundation" +audiotoolbox_outdev_deps="audiotoolbox pthreads" +audiotoolbox_outdev_extralibs="-framework AudioToolbox -framework CoreAudio" bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h" caca_outdev_deps="libcaca" decklink_deps_any="libdl LoadLibrary" @@ -3417,7 +3453,8 @@ ffrtmpcrypt_protocol_select="tcp_protocol" ffrtmphttp_protocol_conflict="librtmp_protocol" ffrtmphttp_protocol_select="http_protocol" ftp_protocol_select="tcp_protocol" -gopher_protocol_select="network" +gopher_protocol_select="tcp_protocol" +gophers_protocol_select="tls_protocol" http_protocol_select="tcp_protocol" http_protocol_suggest="zlib" httpproxy_protocol_select="tcp_protocol" @@ -3458,6 +3495,8 @@ unix_protocol_select="network" # external library protocols libamqp_protocol_deps="librabbitmq" libamqp_protocol_select="network" +librist_protocol_deps="librist" +librist_protocol_select="network" librtmp_protocol_deps="librtmp" librtmpe_protocol_deps="librtmp" librtmps_protocol_deps="librtmp" @@ -3480,6 +3519,7 @@ afir_filter_deps="avcodec" afir_filter_select="rdft" amovie_filter_deps="avcodec avformat" aresample_filter_deps="swresample" +asoftclip_filter_deps="swresample" asr_filter_deps="pocketsphinx" ass_filter_deps="libass" atempo_filter_deps="avcodec" @@ -3515,7 +3555,6 @@ derain_filter_select="dnn" deshake_filter_select="pixelutils" deshake_opencl_filter_deps="opencl" dilation_opencl_filter_deps="opencl" -dnn_processing_filter_deps="swscale" dnn_processing_filter_select="dnn" drawtext_filter_deps="libfreetype" drawtext_filter_suggest="libfontconfig libfribidi" @@ -4236,7 +4275,7 @@ case "$toolchain" in ld_default="$source_path/compat/windows/mslink" nm_default="dumpbin.exe -symbols" ar_default="lib.exe" - case "$arch" in + case "${arch:-$arch_default}" in aarch64|arm64) as_default="armasm64.exe" ;; @@ -5000,8 +5039,6 @@ elif enabled bfin; then elif enabled mips; then - cpuflags="-march=$cpu" - if [ "$cpu" != "generic" ]; then disable mips32r2 disable mips32r5 @@ -5010,81 +5047,40 @@ elif enabled mips; then disable mips64r6 disable loongson2 disable loongson3 + disable mipsdsp + disable mipsdspr2 + + cpuflags="-march=$cpu" case $cpu in - 24kc|24kf*|24kec|34kc|1004kc|24kef*|34kf*|1004kf*|74kc|74kf) + # General ISA levels + mips1|mips3) + ;; + mips32r2) enable mips32r2 - disable msa ;; - p5600|i6400|p6600) - disable mipsdsp - disable mipsdspr2 + mips32r5) + enable mips32r2 + enable mips32r5 ;; - loongson*) - enable loongson2 + mips64r2|mips64r5) + enable mips64r2 enable loongson3 - enable local_aligned - enable simd_align_16 - enable fast_64bit - enable fast_clz - enable fast_cmov - enable fast_unaligned - disable aligned_stack - disable mipsdsp - disable mipsdspr2 - # When gcc version less than 5.3.0, add -fno-expensive-optimizations flag. - if [ $cc == gcc ]; then - gcc_version=$(gcc -dumpversion) - if [ "$(echo "$gcc_version 5.3.0" | tr " " "\n" | sort -rV | head -n 1)" == "$gcc_version" ]; then - expensive_optimization_flag="" - else - expensive_optimization_flag="-fno-expensive-optimizations" - fi - fi - case $cpu in - loongson3*) - cpuflags="-march=loongson3a -mhard-float $expensive_optimization_flag" - ;; - loongson2e) - cpuflags="-march=loongson2e -mhard-float $expensive_optimization_flag" - ;; - loongson2f) - cpuflags="-march=loongson2f -mhard-float $expensive_optimization_flag" - ;; - esac ;; - *) - # Unknown CPU. Disable everything. - warn "unknown CPU. Disabling all MIPS optimizations." - disable mipsfpu - disable mipsdsp - disable mipsdspr2 - disable msa - disable mmi - ;; - esac - - case $cpu in + # Cores from MIPS(MTI) 24kc) disable mipsfpu - disable mipsdsp - disable mipsdspr2 + enable mips32r2 ;; - 24kf*) - disable mipsdsp - disable mipsdspr2 - ;; - 24kec|34kc|1004kc) - disable mipsfpu - disable mipsdspr2 + 24kf*|24kec|34kc|74Kc|1004kc) + enable mips32r2 ;; 24kef*|34kf*|1004kf*) - disable mipsdspr2 - ;; - 74kc) - disable mipsfpu + enable mipsdsp + enable mips32r2 ;; p5600) + enable mips32r2 enable mips32r5 check_cflags "-mtune=p5600" && check_cflags "-msched-weight -mload-store-pairs -funroll-loops" ;; @@ -5096,9 +5092,51 @@ elif enabled mips; then enable mips64r6 check_cflags "-mtune=p6600 -mabi=64" && check_cflags "-msched-weight -mload-store-pairs -funroll-loops" && check_ldflags "-mabi=64" ;; + # Cores from Loongson + loongson2e|loongson2f|loongson3*) + enable local_aligned + enable simd_align_16 + enable fast_64bit + enable fast_clz + enable fast_cmov + enable fast_unaligned + disable aligned_stack + # When gcc version less than 5.3.0, add -fno-expensive-optimizations flag. + if test "$cc_type" = "gcc"; then + case $gcc_basever in + 2|2.*|3.*|4.*|5.0|5.1|5.2) + expensive_optimization_flag="-fno-expensive-optimizations" + ;; + *) + expensive_optimization_flag="" + ;; + esac + fi + + case $cpu in + loongson3*) + enable loongson3 + cpuflags="-march=loongson3a -mhard-float $expensive_optimization_flag" + ;; + loongson2e) + enable loongson2 + cpuflags="-march=loongson2e -mhard-float $expensive_optimization_flag" + ;; + loongson2f) + enable loongson2 + cpuflags="-march=loongson2f -mhard-float $expensive_optimization_flag" + ;; + esac + ;; + *) + warn "unknown MIPS CPU" + ;; esac + else - # We do not disable anything. Is up to the user to disable the unwanted features. + disable mipsdsp + disable mipsdspr2 + # Disable DSP stuff for generic CPU, it can't be detected at runtime. warn 'generic cpu selected' fi @@ -5845,28 +5883,42 @@ EOF elif enabled mips; then - enabled loongson2 && check_inline_asm loongson2 '"dmult.g $8, $9, $10"' - enabled loongson3 && check_inline_asm loongson3 '"gsldxc1 $f0, 0($2, $3)"' - enabled mmi && check_inline_asm mmi '"punpcklhw $f0, $f0, $f0"' - - # Enable minimum ISA based on selected options + # Check toolchain ISA level if enabled mips64; then - enabled mips64r6 && check_inline_asm_flags mips64r6 '"dlsa $0, $0, $0, 1"' '-mips64r6' - enabled mips64r2 && check_inline_asm_flags mips64r2 '"dext $0, $0, 0, 1"' '-mips64r2' - disabled mips64r6 && disabled mips64r2 && check_inline_asm_flags mips64r1 '"daddi $0, $0, 0"' '-mips64' + enabled mips64r6 && check_inline_asm mips64r6 '"dlsa $0, $0, $0, 1"' && + disable mips64r2 + + enabled mips64r2 && check_inline_asm mips64r2 '"dext $0, $0, 0, 1"' + + disable mips32r6 && disable mips32r5 && disable mips32r2 else - enabled mips32r6 && check_inline_asm_flags mips32r6 '"aui $0, $0, 0"' '-mips32r6' - enabled mips32r5 && check_inline_asm_flags mips32r5 '"eretnc"' '-mips32r5' - enabled mips32r2 && check_inline_asm_flags mips32r2 '"ext $0, $0, 0, 1"' '-mips32r2' - disabled mips32r6 && disabled mips32r5 && disabled mips32r2 && check_inline_asm_flags mips32r1 '"addi $0, $0, 0"' '-mips32' + enabled mips32r6 && check_inline_asm mips32r6 '"aui $0, $0, 0"' && + disable mips32r5 && disable mips32r2 + + enabled mips32r5 && check_inline_asm mips32r5 '"eretnc"' + enabled mips32r2 && check_inline_asm mips32r2 '"ext $0, $0, 0, 1"' + + disable mips64r6 && disable mips64r5 && disable mips64r2 fi - enabled mipsfpu && check_inline_asm_flags mipsfpu '"cvt.d.l $f0, $f2"' '-mhard-float' + enabled mipsfpu && check_inline_asm mipsfpu '"cvt.d.l $f0, $f2"' enabled mipsfpu && (enabled mips32r5 || enabled mips32r6 || enabled mips64r6) && check_inline_asm_flags mipsfpu '"cvt.d.l $f0, $f1"' '-mfp64' - enabled mipsfpu && enabled msa && check_inline_asm_flags msa '"addvi.b $w0, $w1, 1"' '-mmsa' && check_headers msa.h || disable msa + enabled mipsdsp && check_inline_asm_flags mipsdsp '"addu.qb $t0, $t1, $t2"' '-mdsp' enabled mipsdspr2 && check_inline_asm_flags mipsdspr2 '"absq_s.qb $t0, $t1"' '-mdspr2' - enabled msa && enabled msa2 && check_inline_asm_flags msa2 '"nxbits.any.b $w0, $w0"' '-mmsa2' && check_headers msa2.h || disable msa2 + + # MSA and MSA2 can be detected at runtime so we supply extra flags here + enabled mipsfpu && enabled msa && check_inline_asm msa '"addvi.b $w0, $w1, 1"' '-mmsa' && append MSAFLAGS '-mmsa' + enabled msa && enabled msa2 && check_inline_asm msa2 '"nxbits.any.b $w0, $w0"' '-mmsa2' && append MSAFLAGS '-mmsa2' + + # loongson2 have no switch cflag so we can only probe toolchain ability + enabled loongson2 && check_inline_asm loongson2 '"dmult.g $8, $9, $10"' && disable loongson3 + + # loongson3 is paired with MMI + enabled loongson3 && check_inline_asm loongson3 '"gsldxc1 $f0, 0($2, $3)"' '-mloongson-ext' && append MMIFLAGS '-mloongson-ext' + + # MMI can be detected at runtime too + enabled mmi && check_inline_asm mmi '"punpcklhw $f0, $f0, $f0"' '-mloongson-mmi' && append MMIFLAGS '-mloongson-mmi' if enabled bigendian && enabled msa; then disable msa @@ -6108,6 +6160,9 @@ check_headers dxgidebug.h check_headers dxva.h check_headers dxva2api.h -D_WIN32_WINNT=0x0600 check_headers io.h +enabled libdrm && + check_headers linux/dma-buf.h + check_headers linux/perf_event.h check_headers libcrystalhd/libcrystalhd_if.h check_headers malloc.h @@ -6152,6 +6207,7 @@ enabled videotoolbox && check_apple_framework VideoToolbox check_apple_framework CoreFoundation check_apple_framework CoreMedia check_apple_framework CoreVideo +check_apple_framework CoreAudio enabled avfoundation && { disable coregraphics applicationservices @@ -6161,6 +6217,7 @@ enabled avfoundation && { enabled videotoolbox && { check_lib coreservices CoreServices/CoreServices.h UTGetOSTypeFromString "-framework CoreServices" check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVC "-framework CoreMedia" + check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVCWithAlpha "-framework CoreMedia" check_func_headers CoreVideo/CVPixelBuffer.h kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange "-framework CoreVideo" check_func_headers CoreVideo/CVImageBuffer.h kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ "-framework CoreVideo" check_func_headers CoreVideo/CVImageBuffer.h kCVImageBufferTransferFunction_ITU_R_2100_HLG "-framework CoreVideo" @@ -6169,6 +6226,7 @@ enabled videotoolbox && { check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss +check_type "windows.h dxva.h" "DXVA_PicParams_AV1" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0 check_type "windows.h dxva.h" "DXVA_PicParams_HEVC" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0 check_type "windows.h dxva.h" "DXVA_PicParams_VP9" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0 check_type "windows.h d3d11.h" "ID3D11VideoDecoder" @@ -6192,7 +6250,7 @@ fi if enabled cuda_nvcc; then nvccflags="$nvccflags -ptx" else - nvccflags="$nvccflags -S -nocudalib -nocudainc --cuda-device-only -include ${source_link}/compat/cuda/cuda_runtime.h" + nvccflags="$nvccflags -S -nocudalib -nocudainc --cuda-device-only -Wno-c++11-narrowing -include ${source_link}/compat/cuda/cuda_runtime.h" check_nvcc cuda_llvm fi @@ -6275,7 +6333,7 @@ enabled avisynth && require_headers "avisynth/avisynth_c.h" enabled cuda_nvcc && { check_nvcc cuda_nvcc || die "ERROR: failed checking for nvcc."; } enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint enabled decklink && { require_headers DeckLinkAPI.h && - { test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a090500" || die "ERROR: Decklink API version must be >= 10.9.5."; } } + { test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a0a0000" || die "ERROR: Decklink API version must be >= 10.10"; } } enabled frei0r && require_headers "frei0r.h dlfcn.h" enabled gmp && require gmp gmp.h mpz_export -lgmp enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init @@ -6295,7 +6353,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && die "ERROR: libcelt must be installed and version must be >= 0.11.0."; } enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2 -enabled libdav1d && require_pkg_config libdav1d "dav1d >= 0.4.0" "dav1d/dav1d.h" dav1d_version +enabled libdav1d && require_pkg_config libdav1d "dav1d >= 0.5.0" "dav1d/dav1d.h" dav1d_version enabled libdavs2 && require_pkg_config libdavs2 "davs2 >= 1.6.0" davs2.h davs2_decoder_open enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdrm && require_pkg_config libdrm libdrm xf86drm.h drmGetVersion @@ -6308,7 +6366,7 @@ enabled fontconfig && enable libfontconfig enabled libfontconfig && require_pkg_config libfontconfig fontconfig "fontconfig/fontconfig.h" FcInit enabled libfreetype && require_pkg_config libfreetype freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType enabled libfribidi && require_pkg_config libfribidi fribidi fribidi.h fribidi_version_info -enabled libglslang && require_cpp libglslang glslang/SPIRV/GlslangToSpv.h "glslang::TIntermediate*" -lglslang -lOSDependent -lHLSL -lOGLCompiler -lSPVRemapper -lSPIRV -lSPIRV-Tools-opt -lSPIRV-Tools -lpthread -lstdc++ +enabled libglslang && require_cpp libglslang glslang/SPIRV/GlslangToSpv.h "glslang::TIntermediate*" -lglslang -lMachineIndependent -lOSDependent -lHLSL -lOGLCompiler -lGenericCodeGen -lSPVRemapper -lSPIRV -lSPIRV-Tools-opt -lSPIRV-Tools -lpthread -lstdc++ enabled libgme && { check_pkg_config libgme libgme gme/gme.h gme_new_emu || require libgme gme/gme.h gme_new_emu -lgme -lstdc++; } enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do @@ -6347,6 +6405,7 @@ enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_ enabled libopenjpeg && { check_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version || { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } } enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++" +enabled libopenvino && require libopenvino c_api/ie_c_api.h ie_c_api_version -linference_engine_c_api enabled libopus && { enabled libopus_decoder && { require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create @@ -6357,7 +6416,8 @@ enabled libopus && { } enabled libpulse && require_pkg_config libpulse libpulse pulse/pulseaudio.h pa_context_new enabled librabbitmq && require_pkg_config librabbitmq "librabbitmq >= 0.7.1" amqp.h amqp_new_connection -enabled librav1e && require_pkg_config librav1e "rav1e >= 0.1.0" rav1e.h rav1e_context_new +enabled librav1e && require_pkg_config librav1e "rav1e >= 0.4.0" rav1e.h rav1e_context_new +enabled librist && require_pkg_config librist "librist >= 0.2" librist/librist.h rist_receiver_create enabled librsvg && require_pkg_config librsvg librsvg-2.0 librsvg-2.0/librsvg/rsvg.h rsvg_handle_render_cairo enabled librtmp && require_pkg_config librtmp librtmp librtmp/rtmp.h RTMP_Socket enabled librubberband && require_pkg_config librubberband "rubberband >= 1.8.1" rubberband/rubberband-c.h rubberband_new -lstdc++ && append librubberband_extralibs "-lstdc++" @@ -6369,6 +6429,7 @@ enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr enabled libssh && require_pkg_config libssh libssh libssh/sftp.h sftp_init enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init enabled libsrt && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket +enabled libsvtav1 && require_pkg_config libsvtav1 "SvtAv1Enc >= 0.8.4" EbSvtAv1Enc.h svt_av1_enc_init_handle enabled libtensorflow && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg @@ -6376,9 +6437,10 @@ enabled libtls && require_pkg_config libtls libtls tls.h tls_configur enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame && { check_lib libtwolame twolame.h twolame_encode_buffer_float32_interleaved -ltwolame || die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; } +enabled libuavs3d && require_pkg_config libuavs3d "uavs3d >= 1.1.41" uavs3d.h uavs3d_decode enabled libv4l2 && require_pkg_config libv4l2 libv4l2 libv4l2.h v4l2_ioctl enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit -enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 1.3.9" libvmaf.h compute_vmaf +enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 1.5.2" libvmaf.h compute_vmaf enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc enabled libvorbis && require_pkg_config libvorbis vorbis vorbis/codec.h vorbis_info_init && require_pkg_config libvorbisenc vorbisenc vorbis/vorbisenc.h vorbis_encode_init @@ -6405,7 +6467,6 @@ enabled libvpx && { fi } -enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack enabled libwebp && { enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; } @@ -6624,6 +6685,9 @@ test_cpp <= 0.35.0" "va/va.h" vaInitialize @@ -6638,6 +6702,7 @@ if enabled vaapi; then check_type "va/va.h va/va_dec_hevc.h" "VAPictureParameterBufferHEVC" check_struct "va/va.h" "VADecPictureParameterBufferVP9" bit_depth + check_struct "va/va.h" "VADecPictureParameterBufferAV1" bit_depth_idx check_type "va/va.h va/va_vpp.h" "VAProcFilterParameterBufferHDRToneMapping" check_struct "va/va.h va/va_vpp.h" "VAProcPipelineCaps" rotation_flags check_type "va/va.h va/va_enc_hevc.h" "VAEncPictureParameterBufferHEVC" @@ -6713,6 +6778,10 @@ void f(void) { struct { const GUID guid; } s[] = { { NV_ENC_PRESET_HQ_GUID } }; int main(void) { return 0; } EOF +if enabled_any nvdec cuvid; then + check_type "ffnvcodec/dynlink_cuda.h ffnvcodec/dynlink_cuviddec.h" "CUVIDAV1PICPARAMS" +fi + enabled amf && check_cpp_condition amf "AMF/core/Version.h" \ "(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400090000" @@ -7440,6 +7509,8 @@ LDSOFLAGS=$LDSOFLAGS SHFLAGS=$(echo $($ldflags_filter $SHFLAGS)) ASMSTRIPFLAGS=$ASMSTRIPFLAGS X86ASMFLAGS=$X86ASMFLAGS +MSAFLAGS=$MSAFLAGS +MMIFLAGS=$MMIFLAGS BUILDSUF=$build_suffix PROGSSUF=$progs_suffix FULLNAME=$FULLNAME @@ -7517,6 +7588,7 @@ cat > $TMPH <= v2.0.0) +Enable rectangular partitions. Default is true. + +@item enable-1to4-partitions (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable 1:4/4:1 partitions. Default is true. + +@item enable-ab-partitions (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable AB shape partitions. Default is true. + +@item enable-angle-delta (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable angle delta intra prediction. Default is true. + +@item enable-cfl-intra (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable chroma predicted from luma intra prediction. Default is true. + +@item enable-filter-intra (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable filter intra predictor. Default is true. + +@item enable-intra-edge-filter (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable intra edge filter. Default is true. + +@item enable-smooth-intra (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable smooth intra prediction mode. Default is true. + +@item enable-paeth-intra (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable paeth predictor in intra prediction. Default is true. + +@item enable-palette (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable palette prediction mode. Default is true. + +@item enable-flip-idtx (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable extended transform type, including FLIPADST_DCT, DCT_FLIPADST, +FLIPADST_FLIPADST, ADST_FLIPADST, FLIPADST_ADST, IDTX, V_DCT, H_DCT, +V_ADST, H_ADST, V_FLIPADST, H_FLIPADST. Default is true. + +@item enable-tx64 (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable 64-pt transform. Default is true. + +@item reduced-tx-type-set (@emph{boolean}) (Requires libaom >= v2.0.0) +Use reduced set of transform types. Default is false. + +@item use-intra-dct-only (@emph{boolean}) (Requires libaom >= v2.0.0) +Use DCT only for INTRA modes. Default is false. + +@item use-inter-dct-only (@emph{boolean}) (Requires libaom >= v2.0.0) +Use DCT only for INTER modes. Default is false. + +@item use-intra-default-tx-only (@emph{boolean}) (Requires libaom >= v2.0.0) +Use Default-transform only for INTRA modes. Default is false. + +@item enable-ref-frame-mvs (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable temporal mv prediction. Default is true. + +@item enable-reduced-reference-set (@emph{boolean}) (Requires libaom >= v2.0.0) +Use reduced set of single and compound references. Default is false. + +@item enable-obmc (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable obmc. Default is true. + +@item enable-dual-filter (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable dual filter. Default is true. + +@item enable-diff-wtd-comp (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable difference-weighted compound. Default is true. + +@item enable-dist-wtd-comp (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable distance-weighted compound. Default is true. + +@item enable-onesided-comp (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable one sided compound. Default is true. + +@item enable-interinter-wedge (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable interinter wedge compound. Default is true. + +@item enable-interintra-wedge (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable interintra wedge compound. Default is true. + +@item enable-masked-comp (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable masked compound. Default is true. + +@item enable-interintra-comp (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable interintra compound. Default is true. + +@item enable-smooth-interintra (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable smooth interintra mode. Default is true. + +@item aom-params +Set libaom options using a list of @var{key}=@var{value} pairs separated +by ":". For a list of supported options, see @command{aomenc --help} under the +section "AV1 Specific Options". + +For example to specify libaom encoding options with @option{-aom-params}: + +@example +ffmpeg -i input -c:v libaom-av1 -b:v 500K -aom-params tune=psnr:enable-tpl-model=1 output.mp4 +@end example + +@end table + +@section libsvtav1 + +SVT-AV1 encoder wrapper. + +Requires the presence of the SVT-AV1 headers and library during configuration. +You need to explicitly configure the build with @code{--enable-libsvtav1}. + +@subsection Options + +@table @option +@item profile +Set the encoding profile. + +@item level +Set the operating point level. + +@item tier +Set the operating point tier. + +@item rc +Set the rate control mode to use. + +Possible modes: +@table @option +@item cqp +Constant quantizer: use fixed values of qindex (dependent on the frame type) +throughout the stream. This mode is the default. + +@item vbr +Variable bitrate: use a target bitrate for the whole stream. + +@item cvbr +Constrained variable bitrate: use a target bitrate for each GOP. +@end table + +@item qmax +Set the maximum quantizer to use when using a bitrate mode. + +@item qmin +Set the minimum quantizer to use when using a bitrate mode. + +@item qp +Set the quantizer used in cqp rate control mode (0-63). + +@item sc_detection +Enable scene change detection. + +@item la_depth +Set number of frames to look ahead (0-120). + +@item preset +Set the quality-speed tradeoff, in the range 0 to 8. Higher values are +faster but lower quality. Defaults to 8 (highest speed). + +@item tile_rows +Set log2 of the number of rows of tiles to use (0-6). + +@item tile_columns +Set log2 of the number of columns of tiles to use (0-4). + @end table @section libkvazaar @@ -1981,6 +2177,38 @@ midpoint is passed in rather than calculated for a specific clip or chunk. The valid range is [0, 10000]. 0 (default) uses standard VBR. @item enable-tpl @var{boolean} Enable temporal dependency model. +@item ref-frame-config +Using per-frame metadata, set members of the structure @code{vpx_svc_ref_frame_config_t} in @code{vpx/vp8cx.h} to fine-control referencing schemes and frame buffer management. +@*Use a :-separated list of key=value pairs. +For example, +@example +av_dict_set(&av_frame->metadata, "ref-frame-config", \ +"rfc_update_buffer_slot=7:rfc_lst_fb_idx=0:rfc_gld_fb_idx=1:rfc_alt_fb_idx=2:rfc_reference_last=0:rfc_reference_golden=0:rfc_reference_alt_ref=0"); +@end example +@table @option +@item rfc_update_buffer_slot +Indicates the buffer slot number to update +@item rfc_update_last +Indicates whether to update the LAST frame +@item rfc_update_golden +Indicates whether to update GOLDEN frame +@item rfc_update_alt_ref +Indicates whether to update ALT_REF frame +@item rfc_lst_fb_idx +LAST frame buffer index +@item rfc_gld_fb_idx +GOLDEN frame buffer index +@item rfc_alt_fb_idx +ALT_REF frame buffer index +@item rfc_reference_last +Indicates whether to reference LAST frame +@item rfc_reference_golden +Indicates whether to reference GOLDEN frame +@item rfc_reference_alt_ref +Indicates whether to reference ALT_REF frame +@item rfc_reference_duration +Indicates frame duration +@end table @end table @end table @@ -2077,9 +2305,7 @@ pixel formats as input instead of YUV. @subsection Supported Pixel Formats x264 supports 8- to 10-bit color spaces. The exact bit depth is controlled at -x264's configure time. FFmpeg only supports one bit depth in one particular -build. In other words, it is not possible to build one FFmpeg with multiple -versions of x264 with different bit depths. +x264's configure time. @subsection Options @@ -2740,20 +2966,30 @@ MPEG-2 video encoder. @subsection Options @table @option -@item profile @var{integer} +@item profile Select the mpeg2 profile to encode: @table @samp @item 422 -@item main +@item high @item ss Spatially Scalable @item snr SNR Scalable -@item high +@item main @item simple @end table +@item level +Select the mpeg2 level to encode: + +@table @samp +@item high +@item high1440 +@item main +@item low +@end table + @item seq_disp_ext @var{integer} Specifies if the encoder should write a sequence_display_extension to the output. @@ -3115,6 +3351,11 @@ Include HDR metadata if the input frames have it messages). @end table +@item tiles +Set the number of tiles to encode the input video with, as columns x rows. +Larger numbers allow greater parallelism in both encoding and decoding, but +may decrease coding efficiency. + @end table @item mjpeg_vaapi diff --git a/doc/examples/decode_video.c b/doc/examples/decode_video.c index 169188a4b..18ee90a6c 100644 --- a/doc/examples/decode_video.c +++ b/doc/examples/decode_video.c @@ -41,7 +41,7 @@ static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, FILE *f; int i; - f = fopen(filename,"w"); + f = fopen(filename,"wb"); fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255); for (i = 0; i < ysize; i++) fwrite(buf + i * wrap, 1, xsize, f); diff --git a/doc/examples/demuxing_decoding.c b/doc/examples/demuxing_decoding.c index 803e35d25..db5e0cb95 100644 --- a/doc/examples/demuxing_decoding.c +++ b/doc/examples/demuxing_decoding.c @@ -51,7 +51,7 @@ static int video_dst_bufsize; static int video_stream_idx = -1, audio_stream_idx = -1; static AVFrame *frame = NULL; -static AVPacket pkt; +static AVPacket *pkt = NULL; static int video_frame_count = 0; static int audio_frame_count = 0; @@ -303,10 +303,12 @@ int main (int argc, char **argv) goto end; } - /* initialize packet, set data to NULL, let the demuxer fill it */ - av_init_packet(&pkt); - pkt.data = NULL; - pkt.size = 0; + pkt = av_packet_alloc(); + if (!pkt) { + fprintf(stderr, "Could not allocate packet\n"); + ret = AVERROR(ENOMEM); + goto end; + } if (video_stream) printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename); @@ -314,14 +316,14 @@ int main (int argc, char **argv) printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename); /* read frames from the file */ - while (av_read_frame(fmt_ctx, &pkt) >= 0) { + while (av_read_frame(fmt_ctx, pkt) >= 0) { // check if the packet belongs to a stream we are interested in, otherwise // skip it - if (pkt.stream_index == video_stream_idx) - ret = decode_packet(video_dec_ctx, &pkt); - else if (pkt.stream_index == audio_stream_idx) - ret = decode_packet(audio_dec_ctx, &pkt); - av_packet_unref(&pkt); + if (pkt->stream_index == video_stream_idx) + ret = decode_packet(video_dec_ctx, pkt); + else if (pkt->stream_index == audio_stream_idx) + ret = decode_packet(audio_dec_ctx, pkt); + av_packet_unref(pkt); if (ret < 0) break; } @@ -372,6 +374,7 @@ end: fclose(video_dst_file); if (audio_dst_file) fclose(audio_dst_file); + av_packet_free(&pkt); av_frame_free(&frame); av_free(video_dst_data[0]); diff --git a/doc/examples/hw_decode.c b/doc/examples/hw_decode.c index f3286f472..71be6e670 100644 --- a/doc/examples/hw_decode.c +++ b/doc/examples/hw_decode.c @@ -223,7 +223,7 @@ int main(int argc, char *argv[]) } /* open the file to dump raw data */ - output_file = fopen(argv[3], "w+"); + output_file = fopen(argv[3], "w+b"); /* actual decoding and dump the raw data */ while (ret >= 0) { diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c index bd16486a2..42f704c25 100644 --- a/doc/examples/muxing.c +++ b/doc/examples/muxing.c @@ -200,7 +200,7 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc, * the motion of the chroma plane does not match the luma plane. */ c->mb_decision = 2; } - break; + break; default: break; @@ -284,25 +284,25 @@ static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, A } /* create resampler context */ - ost->swr_ctx = swr_alloc(); - if (!ost->swr_ctx) { - fprintf(stderr, "Could not allocate resampler context\n"); - exit(1); - } + ost->swr_ctx = swr_alloc(); + if (!ost->swr_ctx) { + fprintf(stderr, "Could not allocate resampler context\n"); + exit(1); + } - /* set options */ - av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0); - av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0); - av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); - av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0); - av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0); - av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0); + /* set options */ + av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0); + av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0); + av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); + av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0); + av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0); + av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0); - /* initialize the resampling context */ - if ((ret = swr_init(ost->swr_ctx)) < 0) { - fprintf(stderr, "Failed to initialize the resampling context\n"); - exit(1); - } + /* initialize the resampling context */ + if ((ret = swr_init(ost->swr_ctx)) < 0) { + fprintf(stderr, "Failed to initialize the resampling context\n"); + exit(1); + } } /* Prepare a 16 bit dummy audio frame of 'frame_size' samples and @@ -349,10 +349,10 @@ static int write_audio_frame(AVFormatContext *oc, OutputStream *ost) if (frame) { /* convert samples from native format to destination codec format, using the resampler */ - /* compute destination number of samples */ - dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples, - c->sample_rate, c->sample_rate, AV_ROUND_UP); - av_assert0(dst_nb_samples == frame->nb_samples); + /* compute destination number of samples */ + dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples, + c->sample_rate, c->sample_rate, AV_ROUND_UP); + av_assert0(dst_nb_samples == frame->nb_samples); /* when we pass a frame to the encoder, it may keep a reference to it * internally; @@ -519,7 +519,6 @@ static AVFrame *get_video_frame(OutputStream *ost) static int write_video_frame(AVFormatContext *oc, OutputStream *ost) { return write_frame(oc, ost->enc, ost->st, get_video_frame(ost)); - } static void close_stream(AVFormatContext *oc, OutputStream *ost) diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c index e0c76f5b3..73786ab59 100644 --- a/doc/examples/transcode_aac.c +++ b/doc/examples/transcode_aac.c @@ -245,14 +245,16 @@ cleanup: /** * Initialize one data packet for reading or writing. - * @param packet Packet to be initialized + * @param[out] packet Packet to be initialized + * @return Error code (0 if successful) */ -static void init_packet(AVPacket *packet) +static int init_packet(AVPacket **packet) { - av_init_packet(packet); - /* Set the packet data and size so that it is recognized as being empty. */ - packet->data = NULL; - packet->size = 0; + if (!(*packet = av_packet_alloc())) { + fprintf(stderr, "Could not allocate packet\n"); + return AVERROR(ENOMEM); + } + return 0; } /** @@ -371,28 +373,31 @@ static int decode_audio_frame(AVFrame *frame, int *data_present, int *finished) { /* Packet used for temporary storage. */ - AVPacket input_packet; + AVPacket *input_packet; int error; - init_packet(&input_packet); + + error = init_packet(&input_packet); + if (error < 0) + return error; /* Read one audio frame from the input file into a temporary packet. */ - if ((error = av_read_frame(input_format_context, &input_packet)) < 0) { + if ((error = av_read_frame(input_format_context, input_packet)) < 0) { /* If we are at the end of the file, flush the decoder below. */ if (error == AVERROR_EOF) *finished = 1; else { fprintf(stderr, "Could not read frame (error '%s')\n", av_err2str(error)); - return error; + goto cleanup; } } /* Send the audio frame stored in the temporary packet to the decoder. * The input audio stream decoder is used to do this. */ - if ((error = avcodec_send_packet(input_codec_context, &input_packet)) < 0) { + if ((error = avcodec_send_packet(input_codec_context, input_packet)) < 0) { fprintf(stderr, "Could not send packet for decoding (error '%s')\n", av_err2str(error)); - return error; + goto cleanup; } /* Receive one frame from the decoder. */ @@ -418,7 +423,7 @@ static int decode_audio_frame(AVFrame *frame, } cleanup: - av_packet_unref(&input_packet); + av_packet_free(&input_packet); return error; } @@ -661,9 +666,12 @@ static int encode_audio_frame(AVFrame *frame, int *data_present) { /* Packet used for temporary storage. */ - AVPacket output_packet; + AVPacket *output_packet; int error; - init_packet(&output_packet); + + error = init_packet(&output_packet); + if (error < 0) + return error; /* Set a timestamp based on the sample rate for the container. */ if (frame) { @@ -681,11 +689,11 @@ static int encode_audio_frame(AVFrame *frame, } else if (error < 0) { fprintf(stderr, "Could not send packet for encoding (error '%s')\n", av_err2str(error)); - return error; + goto cleanup; } /* Receive one encoded frame from the encoder. */ - error = avcodec_receive_packet(output_codec_context, &output_packet); + error = avcodec_receive_packet(output_codec_context, output_packet); /* If the encoder asks for more data to be able to provide an * encoded frame, return indicating that no data is present. */ if (error == AVERROR(EAGAIN)) { @@ -706,14 +714,14 @@ static int encode_audio_frame(AVFrame *frame, /* Write one audio frame from the temporary packet to the output file. */ if (*data_present && - (error = av_write_frame(output_format_context, &output_packet)) < 0) { + (error = av_write_frame(output_format_context, output_packet)) < 0) { fprintf(stderr, "Could not write frame (error '%s')\n", av_err2str(error)); goto cleanup; } cleanup: - av_packet_unref(&output_packet); + av_packet_free(&output_packet); return error; } diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c index e48837cbd..6ca308933 100644 --- a/doc/examples/transcoding.c +++ b/doc/examples/transcoding.c @@ -41,12 +41,17 @@ typedef struct FilteringContext { AVFilterContext *buffersink_ctx; AVFilterContext *buffersrc_ctx; AVFilterGraph *filter_graph; + + AVPacket *enc_pkt; + AVFrame *filtered_frame; } FilteringContext; static FilteringContext *filter_ctx; typedef struct StreamContext { AVCodecContext *dec_ctx; AVCodecContext *enc_ctx; + + AVFrame *dec_frame; } StreamContext; static StreamContext *stream_ctx; @@ -102,6 +107,10 @@ static int open_input_file(const char *filename) } } stream_ctx[i].dec_ctx = codec_ctx; + + stream_ctx[i].dec_frame = av_frame_alloc(); + if (!stream_ctx[i].dec_frame) + return AVERROR(ENOMEM); } av_dump_format(ifmt_ctx, 0, filename, 0); @@ -398,54 +407,63 @@ static int init_filters(void) stream_ctx[i].enc_ctx, filter_spec); if (ret) return ret; + + filter_ctx[i].enc_pkt = av_packet_alloc(); + if (!filter_ctx[i].enc_pkt) + return AVERROR(ENOMEM); + + filter_ctx[i].filtered_frame = av_frame_alloc(); + if (!filter_ctx[i].filtered_frame) + return AVERROR(ENOMEM); } return 0; } -static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) { +static int encode_write_frame(unsigned int stream_index, int flush) +{ + StreamContext *stream = &stream_ctx[stream_index]; + FilteringContext *filter = &filter_ctx[stream_index]; + AVFrame *filt_frame = flush ? NULL : filter->filtered_frame; + AVPacket *enc_pkt = filter->enc_pkt; int ret; - int got_frame_local; - AVPacket enc_pkt; - int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) = - (ifmt_ctx->streams[stream_index]->codecpar->codec_type == - AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2; - - if (!got_frame) - got_frame = &got_frame_local; av_log(NULL, AV_LOG_INFO, "Encoding frame\n"); /* encode filtered frame */ - enc_pkt.data = NULL; - enc_pkt.size = 0; - av_init_packet(&enc_pkt); - ret = enc_func(stream_ctx[stream_index].enc_ctx, &enc_pkt, - filt_frame, got_frame); - av_frame_free(&filt_frame); + av_packet_unref(enc_pkt); + + ret = avcodec_send_frame(stream->enc_ctx, filt_frame); + if (ret < 0) return ret; - if (!(*got_frame)) - return 0; - /* prepare packet for muxing */ - enc_pkt.stream_index = stream_index; - av_packet_rescale_ts(&enc_pkt, - stream_ctx[stream_index].enc_ctx->time_base, - ofmt_ctx->streams[stream_index]->time_base); + while (ret >= 0) { + ret = avcodec_receive_packet(stream->enc_ctx, enc_pkt); + + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return 0; + + /* prepare packet for muxing */ + enc_pkt->stream_index = stream_index; + av_packet_rescale_ts(enc_pkt, + stream->enc_ctx->time_base, + ofmt_ctx->streams[stream_index]->time_base); + + av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n"); + /* mux encoded frame */ + ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt); + } - av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n"); - /* mux encoded frame */ - ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt); return ret; } static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) { + FilteringContext *filter = &filter_ctx[stream_index]; int ret; - AVFrame *filt_frame; av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n"); /* push the decoded frame into the filtergraph */ - ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx, + ret = av_buffersrc_add_frame_flags(filter->buffersrc_ctx, frame, 0); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n"); @@ -454,14 +472,9 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) /* pull filtered frames from the filtergraph */ while (1) { - filt_frame = av_frame_alloc(); - if (!filt_frame) { - ret = AVERROR(ENOMEM); - break; - } av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n"); - ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx, - filt_frame); + ret = av_buffersink_get_frame(filter->buffersink_ctx, + filter->filtered_frame); if (ret < 0) { /* if no more frames for output - returns AVERROR(EAGAIN) * if flushed and no more frames for output - returns AVERROR_EOF @@ -469,12 +482,12 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) */ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ret = 0; - av_frame_free(&filt_frame); break; } - filt_frame->pict_type = AV_PICTURE_TYPE_NONE; - ret = encode_write_frame(filt_frame, stream_index, NULL); + filter->filtered_frame->pict_type = AV_PICTURE_TYPE_NONE; + ret = encode_write_frame(stream_index, 0); + av_frame_unref(filter->filtered_frame); if (ret < 0) break; } @@ -484,34 +497,20 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) static int flush_encoder(unsigned int stream_index) { - int ret; - int got_frame; - if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities & AV_CODEC_CAP_DELAY)) return 0; - while (1) { - av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index); - ret = encode_write_frame(NULL, stream_index, &got_frame); - if (ret < 0) - break; - if (!got_frame) - return 0; - } - return ret; + av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index); + return encode_write_frame(stream_index, 1); } int main(int argc, char **argv) { int ret; - AVPacket packet = { .data = NULL, .size = 0 }; - AVFrame *frame = NULL; - enum AVMediaType type; + AVPacket *packet = NULL; unsigned int stream_index; unsigned int i; - int got_frame; - int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *); if (argc != 3) { av_log(NULL, AV_LOG_ERROR, "Usage: %s \n", argv[0]); @@ -524,56 +523,54 @@ int main(int argc, char **argv) goto end; if ((ret = init_filters()) < 0) goto end; + if (!(packet = av_packet_alloc())) + goto end; /* read all packets */ while (1) { - if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0) + if ((ret = av_read_frame(ifmt_ctx, packet)) < 0) break; - stream_index = packet.stream_index; - type = ifmt_ctx->streams[packet.stream_index]->codecpar->codec_type; + stream_index = packet->stream_index; av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n", stream_index); if (filter_ctx[stream_index].filter_graph) { + StreamContext *stream = &stream_ctx[stream_index]; + av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n"); - frame = av_frame_alloc(); - if (!frame) { - ret = AVERROR(ENOMEM); - break; - } - av_packet_rescale_ts(&packet, + + av_packet_rescale_ts(packet, ifmt_ctx->streams[stream_index]->time_base, - stream_ctx[stream_index].dec_ctx->time_base); - dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 : - avcodec_decode_audio4; - ret = dec_func(stream_ctx[stream_index].dec_ctx, frame, - &got_frame, &packet); + stream->dec_ctx->time_base); + ret = avcodec_send_packet(stream->dec_ctx, packet); if (ret < 0) { - av_frame_free(&frame); av_log(NULL, AV_LOG_ERROR, "Decoding failed\n"); break; } - if (got_frame) { - frame->pts = frame->best_effort_timestamp; - ret = filter_encode_write_frame(frame, stream_index); - av_frame_free(&frame); + while (ret >= 0) { + ret = avcodec_receive_frame(stream->dec_ctx, stream->dec_frame); + if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) + break; + else if (ret < 0) + goto end; + + stream->dec_frame->pts = stream->dec_frame->best_effort_timestamp; + ret = filter_encode_write_frame(stream->dec_frame, stream_index); if (ret < 0) goto end; - } else { - av_frame_free(&frame); } } else { /* remux this frame without reencoding */ - av_packet_rescale_ts(&packet, + av_packet_rescale_ts(packet, ifmt_ctx->streams[stream_index]->time_base, ofmt_ctx->streams[stream_index]->time_base); - ret = av_interleaved_write_frame(ofmt_ctx, &packet); + ret = av_interleaved_write_frame(ofmt_ctx, packet); if (ret < 0) goto end; } - av_packet_unref(&packet); + av_packet_unref(packet); } /* flush filters and encoders */ @@ -597,14 +594,18 @@ int main(int argc, char **argv) av_write_trailer(ofmt_ctx); end: - av_packet_unref(&packet); - av_frame_free(&frame); + av_packet_free(&packet); for (i = 0; i < ifmt_ctx->nb_streams; i++) { avcodec_free_context(&stream_ctx[i].dec_ctx); if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && stream_ctx[i].enc_ctx) avcodec_free_context(&stream_ctx[i].enc_ctx); - if (filter_ctx && filter_ctx[i].filter_graph) + if (filter_ctx && filter_ctx[i].filter_graph) { avfilter_graph_free(&filter_ctx[i].filter_graph); + av_packet_free(&filter_ctx[i].enc_pkt); + av_frame_free(&filter_ctx[i].filtered_frame); + } + + av_frame_free(&stream_ctx[i].dec_frame); } av_free(filter_ctx); av_free(stream_ctx); diff --git a/doc/examples/vaapi_encode.c b/doc/examples/vaapi_encode.c index 707939db3..46bca1b3f 100644 --- a/doc/examples/vaapi_encode.c +++ b/doc/examples/vaapi_encode.c @@ -74,27 +74,27 @@ static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx) static int encode_write(AVCodecContext *avctx, AVFrame *frame, FILE *fout) { int ret = 0; - AVPacket enc_pkt; + AVPacket *enc_pkt; - av_init_packet(&enc_pkt); - enc_pkt.data = NULL; - enc_pkt.size = 0; + if (!(enc_pkt = av_packet_alloc())) + return AVERROR(ENOMEM); if ((ret = avcodec_send_frame(avctx, frame)) < 0) { fprintf(stderr, "Error code: %s\n", av_err2str(ret)); goto end; } while (1) { - ret = avcodec_receive_packet(avctx, &enc_pkt); + ret = avcodec_receive_packet(avctx, enc_pkt); if (ret) break; - enc_pkt.stream_index = 0; - ret = fwrite(enc_pkt.data, enc_pkt.size, 1, fout); - av_packet_unref(&enc_pkt); + enc_pkt->stream_index = 0; + ret = fwrite(enc_pkt->data, enc_pkt->size, 1, fout); + av_packet_unref(enc_pkt); } end: + av_packet_free(&enc_pkt); ret = ((ret == AVERROR(EAGAIN)) ? 0 : -1); return ret; } diff --git a/doc/examples/vaapi_transcode.c b/doc/examples/vaapi_transcode.c index 279d20f63..5a1a704a8 100644 --- a/doc/examples/vaapi_transcode.c +++ b/doc/examples/vaapi_transcode.c @@ -109,28 +109,25 @@ static int open_input_file(const char *filename) return ret; } -static int encode_write(AVFrame *frame) +static int encode_write(AVPacket *enc_pkt, AVFrame *frame) { int ret = 0; - AVPacket enc_pkt; - av_init_packet(&enc_pkt); - enc_pkt.data = NULL; - enc_pkt.size = 0; + av_packet_unref(enc_pkt); if ((ret = avcodec_send_frame(encoder_ctx, frame)) < 0) { fprintf(stderr, "Error during encoding. Error code: %s\n", av_err2str(ret)); goto end; } while (1) { - ret = avcodec_receive_packet(encoder_ctx, &enc_pkt); + ret = avcodec_receive_packet(encoder_ctx, enc_pkt); if (ret) break; - enc_pkt.stream_index = 0; - av_packet_rescale_ts(&enc_pkt, ifmt_ctx->streams[video_stream]->time_base, + enc_pkt->stream_index = 0; + av_packet_rescale_ts(enc_pkt, ifmt_ctx->streams[video_stream]->time_base, ofmt_ctx->streams[0]->time_base); - ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt); + ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt); if (ret < 0) { fprintf(stderr, "Error during writing data to output file. " "Error code: %s\n", av_err2str(ret)); @@ -216,7 +213,7 @@ static int dec_enc(AVPacket *pkt, AVCodec *enc_codec) initialized = 1; } - if ((ret = encode_write(frame)) < 0) + if ((ret = encode_write(pkt, frame)) < 0) fprintf(stderr, "Error during encoding and writing.\n"); fail: @@ -230,7 +227,7 @@ fail: int main(int argc, char **argv) { int ret = 0; - AVPacket dec_pkt; + AVPacket *dec_pkt; AVCodec *enc_codec; if (argc != 4) { @@ -246,6 +243,12 @@ int main(int argc, char **argv) return -1; } + dec_pkt = av_packet_alloc(); + if (!dec_pkt) { + fprintf(stderr, "Failed to allocate decode packet\n"); + goto end; + } + if ((ret = open_input_file(argv[1])) < 0) goto end; @@ -275,23 +278,21 @@ int main(int argc, char **argv) /* read all packets and only transcoding video */ while (ret >= 0) { - if ((ret = av_read_frame(ifmt_ctx, &dec_pkt)) < 0) + if ((ret = av_read_frame(ifmt_ctx, dec_pkt)) < 0) break; - if (video_stream == dec_pkt.stream_index) - ret = dec_enc(&dec_pkt, enc_codec); + if (video_stream == dec_pkt->stream_index) + ret = dec_enc(dec_pkt, enc_codec); - av_packet_unref(&dec_pkt); + av_packet_unref(dec_pkt); } /* flush decoder */ - dec_pkt.data = NULL; - dec_pkt.size = 0; - ret = dec_enc(&dec_pkt, enc_codec); - av_packet_unref(&dec_pkt); + av_packet_unref(dec_pkt); + ret = dec_enc(dec_pkt, enc_codec); /* flush encoder */ - ret = encode_write(NULL); + ret = encode_write(dec_pkt, NULL); /* write the trailer for output stream */ av_write_trailer(ofmt_ctx); @@ -302,5 +303,6 @@ end: avcodec_free_context(&decoder_ctx); avcodec_free_context(&encoder_ctx); av_buffer_unref(&hw_device_ctx); + av_packet_free(&dec_pkt); return ret; } diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 76fafdcf7..a1820af2a 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -617,6 +617,102 @@ they do not conflict with the standard, as in: ffmpeg -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg @end example +The parameters set for each target are as follows. + +@strong{VCD} +@example +@var{pal}: +-f vcd -muxrate 1411200 -muxpreload 0.44 -packetsize 2324 +-s 352x288 -r 25 +-codec:v mpeg1video -g 15 -b:v 1150k -maxrate:v 1150v -minrate:v 1150k -bufsize:v 327680 +-ar 44100 -ac 2 +-codec:a mp2 -b:a 224k + +@var{ntsc}: +-f vcd -muxrate 1411200 -muxpreload 0.44 -packetsize 2324 +-s 352x240 -r 30000/1001 +-codec:v mpeg1video -g 18 -b:v 1150k -maxrate:v 1150v -minrate:v 1150k -bufsize:v 327680 +-ar 44100 -ac 2 +-codec:a mp2 -b:a 224k + +@var{film}: +-f vcd -muxrate 1411200 -muxpreload 0.44 -packetsize 2324 +-s 352x240 -r 24000/1001 +-codec:v mpeg1video -g 18 -b:v 1150k -maxrate:v 1150v -minrate:v 1150k -bufsize:v 327680 +-ar 44100 -ac 2 +-codec:a mp2 -b:a 224k +@end example + +@strong{SVCD} +@example +@var{pal}: +-f svcd -packetsize 2324 +-s 480x576 -pix_fmt yuv420p -r 25 +-codec:v mpeg2video -g 15 -b:v 2040k -maxrate:v 2516k -minrate:v 0 -bufsize:v 1835008 -scan_offset 1 +-ar 44100 +-codec:a mp2 -b:a 224k + +@var{ntsc}: +-f svcd -packetsize 2324 +-s 480x480 -pix_fmt yuv420p -r 30000/1001 +-codec:v mpeg2video -g 18 -b:v 2040k -maxrate:v 2516k -minrate:v 0 -bufsize:v 1835008 -scan_offset 1 +-ar 44100 +-codec:a mp2 -b:a 224k + +@var{film}: +-f svcd -packetsize 2324 +-s 480x480 -pix_fmt yuv420p -r 24000/1001 +-codec:v mpeg2video -g 18 -b:v 2040k -maxrate:v 2516k -minrate:v 0 -bufsize:v 1835008 -scan_offset 1 +-ar 44100 +-codec:a mp2 -b:a 224k +@end example + +@strong{DVD} +@example +@var{pal}: +-f dvd -muxrate 10080k -packetsize 2048 +-s 720x576 -pix_fmt yuv420p -r 25 +-codec:v mpeg2video -g 15 -b:v 6000k -maxrate:v 9000k -minrate:v 0 -bufsize:v 1835008 +-ar 48000 +-codec:a ac3 -b:a 448k + +@var{ntsc}: +-f dvd -muxrate 10080k -packetsize 2048 +-s 720x480 -pix_fmt yuv420p -r 30000/1001 +-codec:v mpeg2video -g 18 -b:v 6000k -maxrate:v 9000k -minrate:v 0 -bufsize:v 1835008 +-ar 48000 +-codec:a ac3 -b:a 448k + +@var{film}: +-f dvd -muxrate 10080k -packetsize 2048 +-s 720x480 -pix_fmt yuv420p -r 24000/1001 +-codec:v mpeg2video -g 18 -b:v 6000k -maxrate:v 9000k -minrate:v 0 -bufsize:v 1835008 +-ar 48000 +-codec:a ac3 -b:a 448k +@end example + +@strong{DV} +@example +@var{pal}: +-f dv +-s 720x576 -pix_fmt yuv420p -r 25 +-ar 48000 -ac 2 + +@var{ntsc}: +-f dv +-s 720x480 -pix_fmt yuv411p -r 30000/1001 +-ar 48000 -ac 2 + +@var{film}: +-f dv +-s 720x480 -pix_fmt yuv411p -r 24000/1001 +-ar 48000 -ac 2 +@end example +The @code{dv50} target is identical to the @code{dv} target except that the pixel format set is @code{yuv422p} for all three standards. + +Any user-set value for a parameter above will override the target preset value. In that case, the output may +not comply with the target standard. + @item -dn (@emph{input/output}) As an input option, blocks all data streams of a file from being filtered or being automatically selected or mapped for any output. See @code{-discard} @@ -675,14 +771,19 @@ Specify the preset for matching stream(s). Print encoding progress/statistics. It is on by default, to explicitly disable it you need to specify @code{-nostats}. +@item -stats_period @var{time} (@emph{global}) +Set period at which encoding progress/statistics are updated. Default is 0.5 seconds. + @item -progress @var{url} (@emph{global}) Send program-friendly progress information to @var{url}. -Progress information is written approximately every second and at the end of +Progress information is written periodically and at the end of the encoding process. It is made of "@var{key}=@var{value}" lines. @var{key} consists of only alphanumeric characters. The last key of a sequence of progress information is always "progress". +The update period is set using @code{-stats_period}. + @anchor{stdin option} @item -stdin Enable interaction on standard input. On by default unless standard input is @@ -734,10 +835,6 @@ ffmpeg -dump_attachment:t "" -i INPUT Technical note -- attachments are implemented as codec extradata, so this option can actually be used to extract extradata from any stream, not just attachments. - -@item -noautorotate -Disable automatically rotating video based on file metadata. - @end table @section Video Options @@ -758,6 +855,13 @@ If in doubt use @option{-framerate} instead of the input option @option{-r}. As an output option, duplicate or drop input frames to achieve constant output frame rate @var{fps}. +@item -fpsmax[:@var{stream_specifier}] @var{fps} (@emph{output,per-stream}) +Set maximum frame rate (Hz value, fraction or abbreviation). + +Clamps output frame rate when output framerate is auto-set and is higher than this value. +Useful in batch processing or when input framerate is wrongly detected as very high. +It cannot be set together with @code{-r}. It is ignored during streamcopy. + @item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream}) Set frame size. @@ -819,6 +923,18 @@ Create the filtergraph specified by @var{filtergraph} and use it to filter the stream. This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter option}. + +@item -autorotate +Automatically rotate the video according to file metadata. Enabled by +default, use @option{-noautorotate} to disable it. + +@item -autoscale +Automatically scale the video according to the resolution of first frame. +Enabled by default, use @option{-noautoscale} to disable it. When autoscale is +disabled, all output frames of filter graph might not be in the same resolution +and may be inadequate for some encoder/muxer. Therefore, it is not recommended +to disable it unless you really know what you are doing. +Disable autoscale at your own risk. @end table @section Advanced Video options @@ -848,8 +964,8 @@ factor if negative. Force interlacing support in encoder (MPEG-2 and MPEG-4 only). Use this option if your input file is interlaced and you want to keep the interlaced format for minimum losses. -The alternative is to deinterlace the input stream with -@option{-deinterlace}, but deinterlacing introduces losses. +The alternative is to deinterlace the input stream by use of a filter +such as @code{yadif} or @code{bwdif}, but deinterlacing introduces losses. @item -psnr Calculate PSNR of compressed frames. @item -vstats @@ -1492,6 +1608,17 @@ is enabled. This option has been deprecated. Use the @code{aresample} audio filter instead. +@item -adrift_threshold @var{time} +Set the minimum difference between timestamps and audio data (in seconds) to trigger +adding/dropping samples to make it match the timestamps. This option effectively is +a threshold to select between hard (add/drop) and soft (squeeze/stretch) compensation. +@code{-async} must be set to a positive value. + +@item -apad @var{parameters} (@emph{output,per-stream}) +Pad the output audio stream(s). This is the same as applying @code{-af apad}. +Argument is a string of filter parameters composed the same as with the @code{apad} filter. +@code{-shortest} must be set for this output for the option to take effect. + @item -copyts Do not process input timestamps, but keep their values without trying to sanitize them. In particular, do not remove the initial start time @@ -1646,6 +1773,22 @@ graph will be added to the output file automatically, so we can simply write ffmpeg -i video.mkv -i image.png -filter_complex 'overlay' out.mkv @end example +As a special exception, you can use a bitmap subtitle stream as input: it +will be converted into a video with the same size as the largest video in +the file, or 720x576 if no video is present. Note that this is an +experimental and temporary solution. It will be removed once libavfilter has +proper support for subtitles. + +For example, to hardcode subtitles on top of a DVB-T recording stored in +MPEG-TS format, delaying the subtitles by 1 second: +@example +ffmpeg -i input.ts -filter_complex \ + '[#0x2ef] setpts=PTS+1/TB [sub] ; [#0x2d0] [sub] overlay' \ + -sn -map '#0x2dc' output.mkv +@end example +(0x2d0, 0x2dc and 0x2ef are the MPEG-TS PIDs of respectively the video, +audio and subtitles streams; 0:0, 0:3 and 0:7 would have worked too) + To generate 5 seconds of pure red video using lavfi @code{color} source: @example ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv @@ -1681,8 +1824,9 @@ not start from timestamp 0, such as transport streams. @item -thread_queue_size @var{size} (@emph{input}) This option sets the maximum number of queued packets when reading from the file or device. With low latency / high rate live streams, packets may be -discarded if they are not read in a timely manner; raising this value can -avoid it. +discarded if they are not read in a timely manner; setting this value can +force ffmpeg to use a separate input thread and read packets as soon as they +arrive. By default ffmpeg only do this if multiple inputs are specified. @item -sdp_file @var{file} (@emph{global}) Print sdp information for an output stream to @var{file}. @@ -1725,6 +1869,11 @@ No packets were passed to the muxer, the output is empty. No packets were passed to the muxer in some of the output streams. @end table +@item -max_error_rate (@emph{global}) +Set fraction of decoding frame failures across all inputs which when crossed +ffmpeg will return exit code 69. Crossing this threshold does not terminate +processing. Range is a floating-point number between 0 to 1. Default is 2/3. + @item -xerror (@emph{global}) Stop and exit on error @@ -1737,24 +1886,23 @@ this buffer, in packets, for the matching output stream. The default value of this option should be high enough for most uses, so only touch this option if you are sure that you need it. +@item -muxing_queue_data_threshold @var{bytes} (@emph{output,per-stream}) +This is a minimum threshold until which the muxing queue size is not taken into +account. Defaults to 50 megabytes per stream, and is based on the overall size +of packets passed to the muxer. + +@item -auto_conversion_filters (@emph{global}) +Enable automatically inserting format conversion filters in all filter +graphs, including those defined by @option{-vf}, @option{-af}, +@option{-filter_complex} and @option{-lavfi}. If filter format negotiation +requires a conversion, the initialization of the filters will fail. +Conversions can still be performed by inserting the relevant conversion +filter (scale, aresample) in the graph. +On by default, to explicitly disable it you need to specify +@code{-noauto_conversion_filters}. + @end table -As a special exception, you can use a bitmap subtitle stream as input: it -will be converted into a video with the same size as the largest video in -the file, or 720x576 if no video is present. Note that this is an -experimental and temporary solution. It will be removed once libavfilter has -proper support for subtitles. - -For example, to hardcode subtitles on top of a DVB-T recording stored in -MPEG-TS format, delaying the subtitles by 1 second: -@example -ffmpeg -i input.ts -filter_complex \ - '[#0x2ef] setpts=PTS+1/TB [sub] ; [#0x2d0] [sub] overlay' \ - -sn -map '#0x2dc' output.mkv -@end example -(0x2d0, 0x2dc and 0x2ef are the MPEG-TS PIDs of respectively the video, -audio and subtitles streams; 0:0, 0:3 and 0:7 would have worked too) - @section Preset files A preset file contains a sequence of @var{option}=@var{value} pairs, one for each line, specifying a sequence of options which would be @@ -2031,6 +2179,7 @@ ffmpeg -i src.ext -lmax 21*QP2LAMBDA dst.ext @ifset config-avfilter @include filters.texi @end ifset +@include general_contents.texi @end ifset @chapter See Also diff --git a/doc/ffplay.texi b/doc/ffplay.texi index f3761bb12..e187b5852 100644 --- a/doc/ffplay.texi +++ b/doc/ffplay.texi @@ -295,6 +295,7 @@ Toggle full screen. @ifset config-avfilter @include filters.texi @end ifset +@include general_contents.texi @end ifset @chapter See Also diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi index 28371cee5..d7fab4ff4 100644 --- a/doc/ffprobe.texi +++ b/doc/ffprobe.texi @@ -642,6 +642,7 @@ DV, GXF and AVI timecodes are available in format metadata @ifset config-avfilter @include filters.texi @end ifset +@include general_contents.texi @end ifset @chapter See Also diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd index 71cbd23ec..4427d02d7 100644 --- a/doc/ffprobe.xsd +++ b/doc/ffprobe.xsd @@ -61,8 +61,6 @@ - - @@ -215,7 +213,6 @@ - @@ -238,7 +235,6 @@ - @@ -358,7 +354,6 @@ - diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi index f339e0d76..5260ecb8f 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -107,17 +107,24 @@ Print detailed information about the muxer named @var{muxer_name}. Use the @option{-formats} option to get a list of all muxers and demuxers. @item filter=@var{filter_name} -Print detailed information about the filter name @var{filter_name}. Use the +Print detailed information about the filter named @var{filter_name}. Use the @option{-filters} option to get a list of all filters. @item bsf=@var{bitstream_filter_name} -Print detailed information about the bitstream filter name @var{bitstream_filter_name}. +Print detailed information about the bitstream filter named @var{bitstream_filter_name}. Use the @option{-bsfs} option to get a list of all bitstream filters. + +@item protocol=@var{protocol_name} +Print detailed information about the protocol named @var{protocol_name}. +Use the @option{-protocols} option to get a list of all protocols. @end table @item -version Show version. +@item -buildconf +Show the build configuration, one option per line. + @item -formats Show available formats (including devices). @@ -345,6 +352,12 @@ Possible flags for this option are: @item k8 @end table @end table + +@item -max_alloc @var{bytes} +Set the maximum size limit for allocating a block on the heap by ffmpeg's +family of malloc functions. Exercise @strong{extreme caution} when using +this option. Don't use if you do not understand the full consequence of doing so. +Default is INT_MAX. @end table @section AVOptions diff --git a/doc/filters.texi b/doc/filters.texi index 84567dec1..621b5f7eb 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -523,10 +523,65 @@ The filter accepts the following options: Set split frequencies. Those must be positive and increasing. @item order -Set filter order, can be @var{2nd}, @var{4th} or @var{8th}. -Default is @var{4th}. +Set filter order for each band split. This controls filter roll-off or steepness +of filter transfer function. +Available values are: + +@table @samp +@item 2nd +12 dB per octave. +@item 4th +24 dB per octave. +@item 6th +36 dB per octave. +@item 8th +48 dB per octave. +@item 10th +60 dB per octave. +@item 12th +72 dB per octave. +@item 14th +84 dB per octave. +@item 16th +96 dB per octave. +@item 18th +108 dB per octave. +@item 20th +120 dB per octave. @end table +Default is @var{4th}. + +@item level +Set input gain level. Allowed range is from 0 to 1. Default value is 1. + +@item gains +Set output gain for each band. Default value is 1 for all bands. +@end table + +@subsection Examples + +@itemize +@item +Split input audio stream into two bands (low and high) with split frequency of 1500 Hz, +each band will be in separate stream: +@example +ffmpeg -i in.flac -filter_complex 'acrossover=split=1500[LOW][HIGH]' -map '[LOW]' low.wav -map '[HIGH]' high.wav +@end example + +@item +Same as above, but with higher filter order: +@example +ffmpeg -i in.flac -filter_complex 'acrossover=split=1500:order=8th[LOW][HIGH]' -map '[LOW]' low.wav -map '[HIGH]' high.wav +@end example + +@item +Same as above, but also with additional middle band (frequencies between 1500 and 8000): +@example +ffmpeg -i in.flac -filter_complex 'acrossover=split=1500 8000:order=8th[LOW][MID][HIGH]' -map '[LOW]' low.wav -map '[MID]' mid.wav -map '[HIGH]' high.wav +@end example +@end itemize + @section acrusher Reduce audio bit resolution. @@ -585,6 +640,10 @@ Set LFO range. Set LFO rate. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section acue Delay audio filtering until a given wallclock timestamp. See the @ref{cue} @@ -597,44 +656,44 @@ Samples detected as impulsive noise are replaced by interpolated samples using autoregressive modelling. @table @option -@item w +@item window, w Set window size, in milliseconds. Allowed range is from @code{10} to @code{100}. Default value is @code{55} milliseconds. This sets size of window which will be processed at once. -@item o +@item overlap, o Set window overlap, in percentage of window size. Allowed range is from @code{50} to @code{95}. Default value is @code{75} percent. Setting this to a very high value increases impulsive noise removal but makes whole process much slower. -@item a +@item arorder, a Set autoregression order, in percentage of window size. Allowed range is from @code{0} to @code{25}. Default value is @code{2} percent. This option also controls quality of interpolated samples using neighbour good samples. -@item t +@item threshold, t Set threshold value. Allowed range is from @code{1} to @code{100}. Default value is @code{2}. This controls the strength of impulsive noise which is going to be removed. The lower value, the more samples will be detected as impulsive noise. -@item b +@item burst, b Set burst fusion, in percentage of window size. Allowed range is @code{0} to @code{10}. Default value is @code{2}. If any two samples detected as noise are spaced less than this value then any sample between those two samples will be also detected as noise. -@item m +@item method, m Set overlap method. It accepts the following values: @table @option -@item a +@item add, a Select overlap-add method. Even not interpolated samples are slightly changed with this method. -@item s +@item save, s Select overlap-save method. Not interpolated samples remain unchanged. @end table @@ -648,38 +707,38 @@ Samples detected as clipped are replaced by interpolated samples using autoregressive modelling. @table @option -@item w +@item window, w Set window size, in milliseconds. Allowed range is from @code{10} to @code{100}. Default value is @code{55} milliseconds. This sets size of window which will be processed at once. -@item o +@item overlap, o Set window overlap, in percentage of window size. Allowed range is from @code{50} to @code{95}. Default value is @code{75} percent. -@item a +@item arorder, a Set autoregression order, in percentage of window size. Allowed range is from @code{0} to @code{25}. Default value is @code{8} percent. This option also controls quality of interpolated samples using neighbour good samples. -@item t +@item threshold, t Set threshold value. Allowed range is from @code{1} to @code{100}. Default value is @code{10}. Higher values make clip detection less aggressive. -@item n +@item hsize, n Set size of histogram used to detect clips. Allowed range is from @code{100} to @code{9999}. Default value is @code{1000}. Higher values make clip detection less aggressive. -@item m +@item method, m Set overlap method. It accepts the following values: @table @option -@item a +@item add, a Select overlap-add method. Even not interpolated samples are slightly changed with this method. -@item s +@item save, s Select overlap-save method. Not interpolated samples remain unchanged. @end table @@ -731,6 +790,39 @@ adelay=delays=64S:all=1 @end example @end itemize +@section adenorm +Remedy denormals in audio by adding extremely low-level noise. + +This filter shall be placed before any filter that can produce denormals. + +A description of the accepted parameters follows. + +@table @option +@item level +Set level of added noise in dB. Default is @code{-351}. +Allowed range is from -451 to -90. + +@item type +Set type of added noise. + +@table @option +@item dc +Add DC signal. +@item ac +Add AC signal. +@item square +Add square signal. +@item pulse +Add pulse signal. +@end table + +Default is @code{dc}. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section aderivative, aintegral Compute derivative/integral of audio stream. @@ -843,6 +935,10 @@ select 75µs (FM-KF). @end table @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section aeval Modify an audio signal according to the specified expressions. @@ -907,6 +1003,62 @@ aeval=val(0)|-val(1) @end example @end itemize +@section aexciter + +An exciter is used to produce high sound that is not present in the +original signal. This is done by creating harmonic distortions of the +signal which are restricted in range and added to the original signal. +An Exciter raises the upper end of an audio signal without simply raising +the higher frequencies like an equalizer would do to create a more +"crisp" or "brilliant" sound. + +The filter accepts the following options: + +@table @option +@item level_in +Set input level prior processing of signal. +Allowed range is from 0 to 64. +Default value is 1. + +@item level_out +Set output level after processing of signal. +Allowed range is from 0 to 64. +Default value is 1. + +@item amount +Set the amount of harmonics added to original signal. +Allowed range is from 0 to 64. +Default value is 1. + +@item drive +Set the amount of newly created harmonics. +Allowed range is from 0.1 to 10. +Default value is 8.5. + +@item blend +Set the octave of newly created harmonics. +Allowed range is from -10 to 10. +Default value is 0. + +@item freq +Set the lower frequency limit of producing harmonics in Hz. +Allowed range is from 2000 to 12000 Hz. +Default is 7500 Hz. + +@item ceil +Set the upper frequency limit of producing harmonics. +Allowed range is from 9999 to 20000 Hz. +If value is lower than 10000 Hz no limit is applied. + +@item listen +Mute the original signal and output only added harmonics. +By default is disabled. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @anchor{afade} @section afade @@ -985,11 +1137,19 @@ select double-exponential seat select double-exponential sigmoid @item losi select logistic sigmoid +@item sinc +select sine cardinal function +@item isinc +select inverted sine cardinal function @item nofade no fade applied @end table @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @subsection Examples @itemize @@ -1314,6 +1474,25 @@ Force the output to either unsigned 8-bit or signed 16-bit stereo aformat=sample_fmts=u8|s16:channel_layouts=stereo @end example +@section afreqshift +Apply frequency shift to input audio samples. + +The filter accepts the following options: + +@table @option +@item shift +Specify frequency shift. Allowed range is -INT_MAX to INT_MAX. +Default value is 0.0. + +@item level +Set output gain applied to final output. Allowed range is from 0.0 to 1.0. +Default value is 1.0. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section agate A gate is mainly used to reduce lower parts of a signal. This kind of signal @@ -1382,6 +1561,10 @@ the reduction. Default is @code{average}. Can be @code{average} or @code{maximum}. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section aiir Apply an arbitrary Infinite Impulse Response filter. @@ -1390,10 +1573,10 @@ It accepts the following parameters: @table @option @item zeros, z -Set numerator/zeros coefficients. +Set B/numerator/zeros/reflection coefficients. @item poles, p -Set denominator/poles coefficients. +Set A/denominator/poles/ladder coefficients. @item gains, k Set channels gains. @@ -1408,6 +1591,10 @@ Set output gain. Set coefficients format. @table @samp +@item ll +lattice-ladder function +@item sf +analog transfer function @item tf digital transfer function @item zp @@ -1421,8 +1608,16 @@ S-plane zeros/poles @end table @item process, r -Set kind of processing. -Can be @code{d} - direct or @code{s} - serial cascading. Default is @code{s}. +Set type of processing. + +@table @samp +@item d +direct processing +@item s +serial processing +@item p +parallel processing +@end table @item precision, e Set filtering precision. @@ -1458,7 +1653,7 @@ displayed. This option is used only when @var{response} is enabled. Set video stream size. This option is used only when @var{response} is enabled. @end table -Coefficients in @code{tf} format are separated by spaces and are in ascending +Coefficients in @code{tf} and @code{sf} format are separated by spaces and are in ascending order. Coefficients in @code{zp} format are separated by spaces and order of coefficients @@ -1483,6 +1678,12 @@ Same as above but in @code{zp} format: @example aiir=k=0.79575848078096756:z=0.80918701+0.58773007i 0.80918701-0.58773007i 0.80884700+0.58784055i 0.80884700-0.58784055i:p=0.63892345+0.59951235i 0.63892345-0.59951235i 0.79582691+0.44198673i 0.79582691-0.44198673i:f=zp:r=s @end example + +@item +Apply 3-rd order analog normalized Butterworth low-pass filter, using analog transfer function format: +@example +aiir=z=1.3057 0 0 0:p=1.3057 2.3892 2.1860 1:f=sf:r=d +@end example @end itemize @section alimiter @@ -1573,6 +1774,30 @@ Enabling it will normalize magnitude response at DC to 0dB. @item order, o Set the filter order, can be 1 or 2. Default is 2. + +@item transform, a +Set transform type of IIR filter. +@table @option +@item di +@item dii +@item tdii +@item latt +@end table + +@item precision, r +Set precison of filtering. +@table @option +@item auto +Pick automatic sample format depending on surround filters. +@item s16 +Always use signed 16-bit. +@item s32 +Always use signed 32-bit. +@item f32 +Always use float 32-bit. +@item f64 +Always use float 64-bit. +@end table @end table @subsection Commands @@ -1710,6 +1935,11 @@ stream ends. The default value is 2 seconds. @item weights Specify weight of each input audio stream as sequence. Each weight is separated by space. By default all inputs have same weight. + +@item normalize +Always scale inputs instead of only doing summation of samples. +Beware of heavy clipping if inputs are not normalized prior or after filtering +by this filter if this option is disabled. By default is enabled. @end table @subsection Commands @@ -1717,6 +1947,7 @@ Each weight is separated by space. By default all inputs have same weight. This filter supports the following commands: @table @option @item weights +@item sum Syntax is same as option with same name. @end table @@ -1751,7 +1982,7 @@ Set central frequency for band. If input doesn't have that frequency the entry is ignored. @item w -Set band width in hertz. +Set band width in Hertz. @item g Set band gain in dB. @@ -1816,7 +2047,7 @@ Syntax for the commands is : "@var{fN}|f=@var{freq}|w=@var{width}|g=@var{gain}" @var{fN} is existing filter number, starting from 0, if no such filter is available error is returned. @var{freq} set new frequency parameter. -@var{width} set new width parameter in herz. +@var{width} set new width parameter in Hertz. @var{gain} set new gain parameter in dB. Full filter invocation with asendcmd may look like this: @@ -1868,16 +2099,7 @@ Set smooth factor. Default value is @var{11}. Allowed range is from @var{1} to @ @subsection Commands -This filter supports the following commands: -@table @option -@item s -Change denoise strength. Argument is single float number. -Syntax for the command is : "@var{s}" - -@item o -Change output mode. -Syntax for the command is : "i", "o" or "n" string. -@end table +This filter supports the all above options as @ref{commands}. @section anlms Apply Normalized Least-Mean-Squares algorithm to the first audio stream using the second audio stream. @@ -2040,6 +2262,25 @@ It accepts the following values: @end table @end table +@section aphaseshift +Apply phase shift to input audio samples. + +The filter accepts the following options: + +@table @option +@item shift +Specify phase shift. Allowed range is from -1.0 to 1.0. +Default value is 0.0. + +@item level +Set output gain applied to final output. Allowed range is from 0.0 to 1.0. +Default value is 1.0. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section apulsator Audio pulsator is something between an autopanner and a tremolo. @@ -2159,8 +2400,19 @@ This filter accepts the following options: @table @option @item model, m Set train model file to load. This option is always required. + +@item mix +Set how much to mix filtered samples into final output. +Allowed range is from -1 to 1. Default value is 1. +Negative values are special, they set how much to keep filtered noise +in the final filter output. Set this option to -1 to hear actual +noise removed from input signal. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section asetnsamples Set the number of samples per each output audio frame. @@ -2261,6 +2513,7 @@ Set type of soft-clipping. It accepts the following values: @table @option +@item hard @item tanh @item atan @item cubic @@ -2268,10 +2521,20 @@ It accepts the following values: @item alg @item quintic @item sin +@item erf @end table +@item threshold +Set threshold from where to start clipping. Default value is 0dB or 1. + +@item output +Set gain applied to output. Default value is 0dB or 1. + @item param Set additional parameter which controls sigmoid function. + +@item oversample +Set oversampling factor. @end table @subsection Commands @@ -2471,11 +2734,11 @@ The filter accepts the following options: @table @option @item dry Set dry gain, how much of original signal is kept. Allowed range is from 0 to 1. -Default value is 0.5. +Default value is 0.7. @item wet Set wet gain, how much of filtered signal is kept. Allowed range is from 0 to 1. -Default value is 0.8. +Default value is 0.7. @item decay Set delay line decay gain value. Allowed range is from 0 to 1. @@ -2483,10 +2746,10 @@ Default value is 0.7. @item feedback Set delay line feedback gain value. Allowed range is from 0 to 1. -Default value is 0.5. +Default value is 0.9. @item cutoff -Set cutoff frequency in herz. Allowed range is 50 to 900. +Set cutoff frequency in Hertz. Allowed range is 50 to 900. Default value is 100. @item slope @@ -2502,6 +2765,104 @@ Default value is 20. This filter supports the all above options as @ref{commands}. +@section asubcut +Cut subwoofer frequencies. + +This filter allows to set custom, steeper +roll off than highpass filter, and thus is able to more attenuate +frequency content in stop-band. + +The filter accepts the following options: + +@table @option +@item cutoff +Set cutoff frequency in Hertz. Allowed range is 2 to 200. +Default value is 20. + +@item order +Set filter order. Available values are from 3 to 20. +Default value is 10. + +@item level +Set input gain level. Allowed range is from 0 to 1. Default value is 1. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + +@section asupercut +Cut super frequencies. + +The filter accepts the following options: + +@table @option +@item cutoff +Set cutoff frequency in Hertz. Allowed range is 20000 to 192000. +Default value is 20000. + +@item order +Set filter order. Available values are from 3 to 20. +Default value is 10. + +@item level +Set input gain level. Allowed range is from 0 to 1. Default value is 1. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + +@section asuperpass +Apply high order Butterworth band-pass filter. + +The filter accepts the following options: + +@table @option +@item centerf +Set center frequency in Hertz. Allowed range is 2 to 999999. +Default value is 1000. + +@item order +Set filter order. Available values are from 4 to 20. +Default value is 4. + +@item qfactor +Set Q-factor. Allowed range is from 0.01 to 100. Default value is 1. + +@item level +Set input gain level. Allowed range is from 0 to 2. Default value is 1. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + +@section asuperstop +Apply high order Butterworth band-stop filter. + +The filter accepts the following options: + +@table @option +@item centerf +Set center frequency in Hertz. Allowed range is 2 to 999999. +Default value is 1000. + +@item order +Set filter order. Available values are from 4 to 20. +Default value is 4. + +@item qfactor +Set Q-factor. Allowed range is from 0.01 to 100. Default value is 1. + +@item level +Set input gain level. Allowed range is from 0 to 2. Default value is 1. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section atempo Adjust audio tempo. @@ -2693,6 +3054,30 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item transform, a +Set transform type of IIR filter. +@table @option +@item di +@item dii +@item tdii +@item latt +@end table + +@item precision, r +Set precison of filtering. +@table @option +@item auto +Pick automatic sample format depending on surround filters. +@item s16 +Always use signed 16-bit. +@item s32 +Always use signed 32-bit. +@item f32 +Always use float 32-bit. +@item f64 +Always use float 64-bit. +@end table @end table @subsection Commands @@ -2756,6 +3141,30 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item transform, a +Set transform type of IIR filter. +@table @option +@item di +@item dii +@item tdii +@item latt +@end table + +@item precision, r +Set precison of filtering. +@table @option +@item auto +Pick automatic sample format depending on surround filters. +@item s16 +Always use signed 16-bit. +@item s32 +Always use signed 32-bit. +@item f32 +Always use float 32-bit. +@item f64 +Always use float 64-bit. +@end table @end table @subsection Commands @@ -2816,6 +3225,9 @@ kHz @item width, w Determine how steep is the filter's shelf transition. +@item poles, p +Set number of poles. Default is 2. + @item mix, m How much to use filtered signal in output. Default is 1. Range is between 0 and 1. @@ -2826,6 +3238,30 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item transform, a +Set transform type of IIR filter. +@table @option +@item di +@item dii +@item tdii +@item latt +@end table + +@item precision, r +Set precison of filtering. +@table @option +@item auto +Pick automatic sample format depending on surround filters. +@item s16 +Always use signed 16-bit. +@item s32 +Always use signed 32-bit. +@item f32 +Always use float 32-bit. +@item f64 +Always use float 64-bit. +@end table @end table @subsection Commands @@ -2884,6 +3320,30 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item transform, a +Set transform type of IIR filter. +@table @option +@item di +@item dii +@item tdii +@item latt +@end table + +@item precision, r +Set precison of filtering. +@table @option +@item auto +Pick automatic sample format depending on surround filters. +@item s16 +Always use signed 16-bit. +@item s32 +Always use signed 32-bit. +@item f32 +Always use float 32-bit. +@item f64 +Always use float 64-bit. +@end table @end table @section bs2b @@ -3292,14 +3752,17 @@ Set output gain. Default is 1. This filter supports the all above options as @ref{commands}. @section crystalizer -Simple algorithm to expand audio dynamic range. +Simple algorithm for audio noise sharpening. + +This filter linearly increases differences betweeen each audio sample. The filter accepts the following options: @table @option @item i -Sets the intensity of effect (default: 2.0). Must be in range between 0.0 +Sets the intensity of effect (default: 2.0). Must be in range between -10.0 to 0 (unchanged sound) to 10.0 (maximum effect). +To inverse filtering use negative value. @item c Enable clipping. By default is enabled. @@ -3607,6 +4070,30 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item transform, a +Set transform type of IIR filter. +@table @option +@item di +@item dii +@item tdii +@item latt +@end table + +@item precision, r +Set precison of filtering. +@table @option +@item auto +Pick automatic sample format depending on surround filters. +@item s16 +Always use signed 16-bit. +@item s32 +Always use signed 32-bit. +@item f32 +Always use float 32-bit. +@item f64 +Always use float 64-bit. +@end table @end table @subsection Examples @@ -4084,6 +4571,30 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item transform, a +Set transform type of IIR filter. +@table @option +@item di +@item dii +@item tdii +@item latt +@end table + +@item precision, r +Set precison of filtering. +@table @option +@item auto +Pick automatic sample format depending on surround filters. +@item s16 +Always use signed 16-bit. +@item s32 +Always use signed 32-bit. +@item f32 +Always use float 32-bit. +@item f64 +Always use float 64-bit. +@end table @end table @subsection Commands @@ -4197,6 +4708,9 @@ If not specified, or the expressed duration is negative, the audio is supposed to be generated forever. Only used if plugin have zero inputs. +@item latency, l +Enable latency compensation, by default is disabled. +Only used if plugin have inputs. @end table @subsection Examples @@ -4407,6 +4921,30 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item transform, a +Set transform type of IIR filter. +@table @option +@item di +@item dii +@item tdii +@item latt +@end table + +@item precision, r +Set precison of filtering. +@table @option +@item auto +Pick automatic sample format depending on surround filters. +@item s16 +Always use signed 16-bit. +@item s32 +Always use signed 32-bit. +@item f32 +Always use float 32-bit. +@item f64 +Always use float 64-bit. +@end table @end table @subsection Examples @@ -4862,6 +5400,10 @@ Default is average. Can be average or maximum. Set sidechain gain. Default is 1. Range is from 0.015625 to 64. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section silencedetect Detect silence in an audio stream. @@ -5123,6 +5665,69 @@ and also with custom gain: @end example @end itemize +@section speechnorm +Speech Normalizer. + +This filter expands or compresses each half-cycle of audio samples +(local set of samples all above or all below zero and between two nearest zero crossings) depending +on threshold value, so audio reaches target peak value under conditions controlled by below options. + +The filter accepts the following options: + +@table @option +@item peak, p +Set the expansion target peak value. This specifies the highest allowed absolute amplitude +level for the normalized audio input. Default value is 0.95. Allowed range is from 0.0 to 1.0. + +@item expansion, e +Set the maximum expansion factor. Allowed range is from 1.0 to 50.0. Default value is 2.0. +This option controls maximum local half-cycle of samples expansion. The maximum expansion +would be such that local peak value reaches target peak value but never to surpass it and that +ratio between new and previous peak value does not surpass this option value. + +@item compression, c +Set the maximum compression factor. Allowed range is from 1.0 to 50.0. Default value is 2.0. +This option controls maximum local half-cycle of samples compression. This option is used +only if @option{threshold} option is set to value greater than 0.0, then in such cases +when local peak is lower or same as value set by @option{threshold} all samples belonging to +that peak's half-cycle will be compressed by current compression factor. + +@item threshold, t +Set the threshold value. Default value is 0.0. Allowed range is from 0.0 to 1.0. +This option specifies which half-cycles of samples will be compressed and which will be expanded. +Any half-cycle samples with their local peak value below or same as this option value will be +compressed by current compression factor, otherwise, if greater than threshold value they will be +expanded with expansion factor so that it could reach peak target value but never surpass it. + +@item raise, r +Set the expansion raising amount per each half-cycle of samples. Default value is 0.001. +Allowed range is from 0.0 to 1.0. This controls how fast expansion factor is raised per +each new half-cycle until it reaches @option{expansion} value. +Setting this options too high may lead to distortions. + +@item fall, f +Set the compression raising amount per each half-cycle of samples. Default value is 0.001. +Allowed range is from 0.0 to 1.0. This controls how fast compression factor is raised per +each new half-cycle until it reaches @option{compression} value. + +@item channels, h +Specify which channels to filter, by default all available channels are filtered. + +@item invert, i +Enable inverted filtering, by default is disabled. This inverts interpretation of @option{threshold} +option. When enabled any half-cycle of samples with their local peak value below or same as +@option{threshold} option will be expanded otherwise it will be compressed. + +@item link, l +Link channels when calculating gain applied to each filtered channel sample, by default is disabled. +When disabled each filtered channel gain calculation is independent, otherwise when this option +is enabled the minimum of all possible gains for each filtered channel is used. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section stereotools This filter has some handy utilities to manage stereo signals, for converting @@ -5194,6 +5799,12 @@ Mid/Side to Left/Left. @item ms>rr Mid/Side to Right/Right. + +@item ms>rl +Mid/Side to Right/Left. + +@item lr>l-r +Left/Right to Left - Right. @end table @item slev @@ -5243,6 +5854,10 @@ Equal power distribution, from -6dB to +6dB range. @end table @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @subsection Examples @itemize @@ -5517,6 +6132,9 @@ kHz @item width, w Determine how steep is the filter's shelf transition. +@item poles, p +Set number of poles. Default is 2. + @item mix, m How much to use filtered signal in output. Default is 1. Range is between 0 and 1. @@ -5527,6 +6145,30 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item transform, a +Set transform type of IIR filter. +@table @option +@item di +@item dii +@item tdii +@item latt +@end table + +@item precision, r +Set precison of filtering. +@table @option +@item auto +Pick automatic sample format depending on surround filters. +@item s16 +Always use signed 16-bit. +@item s32 +Always use signed 32-bit. +@item f32 +Always use float 32-bit. +@item f64 +Always use float 64-bit. +@end table @end table @subsection Commands @@ -5795,7 +6437,7 @@ Below is a description of the currently available audio sources. Buffer audio frames, and make them available to the filter chain. This source is mainly intended for a programmatic use, in particular -through the interface defined in @file{libavfilter/asrc_abuffer.h}. +through the interface defined in @file{libavfilter/buffersrc.h}. It accepts the following parameters: @table @option @@ -6001,6 +6643,13 @@ Specifies the sample rate, and defaults to 44100. @item nb_samples, n Set the number of samples per requested frames. +@item duration, d +Set the duration of the sourced audio. See +@ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils} +for the accepted syntax. + +If not specified, or the expressed duration is negative, the audio is +supposed to be generated forever. @end table @subsection Examples @@ -6395,12 +7044,6 @@ and a separate video created with @var{alphaextract}, you might use: movie=in_alpha.mkv [alpha]; [in][alpha] alphamerge [out] @end example -Since this filter is designed for reconstruction, it operates on frame -sequences without considering timestamps, and terminates when either -input reaches end of stream. This will cause problems if your encoding -pipeline drops frames. If you're trying to apply an image as an -overlay to a video stream, consider the @var{overlay} filter instead. - @section amplify Amplify differences between current pixel and pixels of adjacent frames in @@ -6522,7 +7165,16 @@ Alternatively can be set to @code{s} serial. Parallel can be faster then serial, while other way around is never true. Parallel will abort early on first change being greater then thresholds, while serial -will continue processing other side of frames if they are equal or bellow thresholds. +will continue processing other side of frames if they are equal or below thresholds. + +@item 0s +@item 1s +@item 2s +Set sigma for 1st plane, 2nd plane or 3rd plane. Default is 32767. +Valid range is from 0 to 32767. +This options controls weight for each pixel in radius defined by size. +Default value means every pixel have same weight. +Setting this option to 0 effectively disables filtering. @end table @subsection Commands @@ -6571,6 +7223,10 @@ The filter accepts the following option: Set the minimal luminance value. Default is @code{16}. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section bilateral Apply bilateral filter, spatial smoothing while preserving edges. @@ -6578,7 +7234,7 @@ The filter accepts the following options: @table @option @item sigmaS Set sigma of gaussian function to calculate spatial weight. -Allowed range is 0 to 10. Default is 0.1. +Allowed range is 0 to 512. Default is 0.1. @item sigmaR Set sigma of gaussian function to calculate range weight. @@ -6588,6 +7244,10 @@ Allowed range is 0 to 1. Default is 0.1. Set planes to filter. Default is first only. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section bitplanenoise Show and measure bit plane noise. @@ -6855,6 +7515,9 @@ tblend=all_mode=grainextract @end example @end itemize +@subsection Commands +This filter supports same @ref{commands} as options. + @section bm3d Denoise frames using Block-Matching 3D algorithm. @@ -7096,6 +7759,9 @@ Set planes to filter. Default value is to filter all planes except alpha plane. @end table +@subsection Commands +This filter supports same @ref{commands} as options. + @section chromahold Remove all color information for all colors except for certain one. @@ -7180,6 +7846,60 @@ ffmpeg -f lavfi -i color=c=black:s=1280x720 -i video.mp4 -shortest -filter_compl @end example @end itemize +@section chromanr +Reduce chrominance noise. + +The filter accepts the following options: + +@table @option +@item thres +Set threshold for averaging chrominance values. +Sum of absolute difference of Y, U and V pixel components of current +pixel and neighbour pixels lower than this threshold will be used in +averaging. Luma component is left unchanged and is copied to output. +Default value is 30. Allowed range is from 1 to 200. + +@item sizew +Set horizontal radius of rectangle used for averaging. +Allowed range is from 1 to 100. Default value is 5. + +@item sizeh +Set vertical radius of rectangle used for averaging. +Allowed range is from 1 to 100. Default value is 5. + +@item stepw +Set horizontal step when averaging. Default value is 1. +Allowed range is from 1 to 50. +Mostly useful to speed-up filtering. + +@item steph +Set vertical step when averaging. Default value is 1. +Allowed range is from 1 to 50. +Mostly useful to speed-up filtering. + +@item threy +Set Y threshold for averaging chrominance values. +Set finer control for max allowed difference between Y components +of current pixel and neigbour pixels. +Default value is 200. Allowed range is from 1 to 200. + +@item threu +Set U threshold for averaging chrominance values. +Set finer control for max allowed difference between U components +of current pixel and neigbour pixels. +Default value is 200. Allowed range is from 1 to 200. + +@item threv +Set V threshold for averaging chrominance values. +Set finer control for max allowed difference between V components +of current pixel and neigbour pixels. +Default value is 200. Allowed range is from 1 to 200. +@end table + +@subsection Commands +This filter supports same @ref{commands} as options. +The command accepts the same syntax of the corresponding option. + @section chromashift Shift chroma pixels horizontally and/or vertically. @@ -7375,6 +8095,69 @@ colorbalance=rs=.3 This filter supports the all above options as @ref{commands}. +@section colorcontrast + +Adjust color contrast between RGB components. + +The filter accepts the following options: + +@table @option +@item rc +Set the red-cyan contrast. Defaults is 0.0. Allowed range is from -1.0 to 1.0. + +@item gm +Set the green-magenta contrast. Defaults is 0.0. Allowed range is from -1.0 to 1.0. + +@item by +Set the blue-yellow contrast. Defaults is 0.0. Allowed range is from -1.0 to 1.0. + +@item rcw +@item gmw +@item byw +Set the weight of each @code{rc}, @code{gm}, @code{by} option value. Default value is 0.0. +Allowed range is from 0.0 to 1.0. If all weights are 0.0 filtering is disabled. + +@item pl +Set the amount of preserving lightness. Default value is 0.0. Allowed range is from 0.0 to 1.0. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + +@section colorcorrect + +Adjust color white balance selectively for blacks and whites. +This filter operates in YUV colorspace. + +The filter accepts the following options: + +@table @option +@item rl +Set the red shadow spot. Allowed range is from -1.0 to 1.0. +Default value is 0. + +@item bl +Set the blue shadow spot. Allowed range is from -1.0 to 1.0. +Default value is 0. + +@item rh +Set the red highlight spot. Allowed range is from -1.0 to 1.0. +Default value is 0. + +@item bh +Set the red highlight spot. Allowed range is from -1.0 to 1.0. +Default value is 0. + +@item saturation +Set the amount of saturation. Allowed range is from -3.0 to 3.0. +Default value is 1. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section colorchannelmixer Adjust video input frames by re-mixing color channels. @@ -7418,6 +8201,10 @@ Adjust contribution of input red, green, blue and alpha channels for output alph Default is @code{1} for @var{aa}, and @code{0} for @var{ar}, @var{ag} and @var{ab}. Allowed ranges for options are @code{[-2.0, 2.0]}. + +@item pl +Preserve lightness when changing colors. Allowed range is from @code{[0.0, 1.0]}. +Default is @code{0.0}, thus disabled. @end table @subsection Examples @@ -7439,6 +8226,33 @@ colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131 This filter supports the all above options as @ref{commands}. +@section colorize +Overlay a solid color on the video stream. + +The filter accepts the following options: + +@table @option +@item hue +Set the color hue. Allowed range is from 0 to 360. +Default value is 0. + +@item saturation +Set the color saturation. Allowed range is from 0 to 1. +Default value is 0.5. + +@item lightness +Set the color lightness. Allowed range is from 0 to 1. +Default value is 0.5. + +@item mix +Set the mix of source lightness. By default is set to 1.0. +Allowed range is from 0.0 to 1.0. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section colorkey RGB colorspace color keying. @@ -7899,6 +8713,28 @@ For example to convert the input to SMPTE-240M, use the command: colorspace=smpte240m @end example +@section colortemperature +Adjust color temperature in video to simulate variations in ambient color temperature. + +The filter accepts the following options: + +@table @option +@item temperature +Set the temperature in Kelvin. Allowed range is from 1000 to 40000. +Default value is 6500 K. + +@item mix +Set mixing with filtered output. Allowed range is from 0 to 1. +Default value is 1. + +@item pl +Set the amount of preserving lightness. Allowed range is from 0 to 1. +Default value is 0. +@end table + +@subsection Commands +This filter supports same @ref{commands} as options. + @section convolution Apply convolution of 3x3, 5x5, 7x7 or horizontal/vertical up to 49 elements. @@ -7936,6 +8772,10 @@ Set matrix mode for each plane. Can be @var{square}, @var{row} or @var{column}. Default is @var{square}. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @subsection Examples @itemize @@ -8359,6 +9199,10 @@ The value which the width/height should be divisible by. It defaults to get only even dimensions (needed for 4:2:2 video). 16 is best when encoding to most video codecs. +@item skip +Set the number of initial frames for which evaluation is skipped. +Default is 2. Range is 0 to INT_MAX. + @item reset_count, reset Set the counter that determines after how many frames cropdetect will reset the previously detected largest video area and start over to @@ -8469,6 +9313,10 @@ Save Gnuplot script of the curves in specified file. To avoid some filtergraph syntax conflicts, each key points list need to be defined using the following syntax: @code{x0/y0 x1/y1 x2/y2 ...}. +@subsection Commands + +This filter supports same @ref{commands} as options. + @subsection Examples @itemize @@ -8561,8 +9409,15 @@ Set background opacity. @item format Set display number format. Can be @code{hex}, or @code{dec}. Default is @code{hex}. + +@item components +Set pixel components to display. By default all pixel components are displayed. @end table +@subsection Commands + +This filter supports same @ref{commands} as options excluding @code{size} option. + @section dblur Apply Directional blur filter. @@ -8695,6 +9550,10 @@ e.g. banding detection threshold is triggered for all color components. The default is disabled. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section deblock Remove blocking artifacts from input video. @@ -8754,6 +9613,10 @@ deblock=filter=strong:block=4:alpha=0.12:beta=0.07:gamma=0.06:delta=0.05:planes= @end example @end itemize +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @anchor{decimate} @section decimate @@ -8955,12 +9818,6 @@ specified. Specify the width and height of the logo to clear. They must be specified. -@item band, t -Specify the thickness of the fuzzy edge of the rectangle (added to -@var{w} and @var{h}). The default value is 1. This option is -deprecated, setting higher values should no longer be necessary and -is not recommended. - @item show When set to 1, a green rectangle is drawn on the screen to simplify finding the right @var{x}, @var{y}, @var{w}, and @var{h} parameters. @@ -8978,9 +9835,9 @@ compute the interpolated pixel values inside the rectangle. @itemize @item Set a rectangle covering the area with top left corner coordinates 0,0 -and size 100x77, and a band of size 10: +and size 100x77: @example -delogo=x=0:y=0:w=100:h=77:band=10 +delogo=x=0:y=0:w=100:h=77 @end example @end itemize @@ -9153,6 +10010,10 @@ Controls brightness of spill area, preserving colors. Modify alpha from generated spillmap. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section detelecine Apply an exact inverse of the telecine operation. It requires a predefined @@ -9288,13 +10149,21 @@ TensorFlow backend. To enable this backend you need to install the TensorFlow for C library (see @url{https://www.tensorflow.org/install/install_c}) and configure FFmpeg with @code{--enable-libtensorflow} + +@item openvino +OpenVINO backend. To enable this backend you +need to build and install the OpenVINO for C library (see +@url{https://github.com/openvinotoolkit/openvino/blob/master/build-instruction.md}) and configure FFmpeg with +@code{--enable-libopenvino} (--extra-cflags=-I... --extra-ldflags=-L... might +be needed if the header files and libraries are not installed into system path) + @end table Default value is @samp{native}. @item model Set path to model file specifying network architecture and its parameters. -Note that different backends use different file formats. TensorFlow and native +Note that different backends use different file formats. TensorFlow, OpenVINO and native backend can load files for only its format. Native model file (.model) can be generated from TensorFlow model file (.pb) by using tools/python/convert.py @@ -9305,6 +10174,10 @@ Set the input name of the dnn network. @item output Set the output name of the dnn network. +@item async +use DNN async execution if set (default: set), +roll back to sync execution if the backend does not support async. + @end table @subsection Examples @@ -10114,6 +10987,12 @@ Use fontconfig to set the font. Note that the colons need to be escaped. drawtext='fontfile=Linux Libertine O-40\:style=Semibold:text=FFmpeg' @end example +@item +Draw "Test Text" with font size dependent on height of the video. +@example +drawtext="text='Test Text': fontsize=h/30: x=(w-text_w)/2: y=(h-text_h*2)" +@end example + @item Print the date of a real-time encoding (see strftime(3)): @example @@ -10260,6 +11139,18 @@ Can be either @var{normal} or @var{diff}. Default is @var{normal}. between neighbour histogram values. @end table +@section epx +Apply the EPX magnification filter which is designed for pixel art. + +It accepts the following option: + +@table @option +@item n +Set the scaling dimension: @code{2} for @code{2xEPX}, @code{3} for +@code{3xEPX}. +Default is @code{3}. +@end table + @section eq Set brightness, contrast, saturation and approximate gamma adjustment. @@ -10401,6 +11292,102 @@ Flags to local 3x3 coordinates maps like this: This filter supports the all above options as @ref{commands}. +@section estdif + +Deinterlace the input video ("estdif" stands for "Edge Slope +Tracing Deinterlacing Filter"). + +Spatial only filter that uses edge slope tracing algorithm +to interpolate missing lines. +It accepts the following parameters: + +@table @option +@item mode +The interlacing mode to adopt. It accepts one of the following values: + +@table @option +@item frame +Output one frame for each frame. +@item field +Output one frame for each field. +@end table + +The default value is @code{field}. + +@item parity +The picture field parity assumed for the input interlaced video. It accepts one +of the following values: + +@table @option +@item tff +Assume the top field is first. +@item bff +Assume the bottom field is first. +@item auto +Enable automatic detection of field parity. +@end table + +The default value is @code{auto}. +If the interlacing is unknown or the decoder does not export this information, +top field first will be assumed. + +@item deint +Specify which frames to deinterlace. Accepts one of the following +values: + +@table @option +@item all +Deinterlace all frames. +@item interlaced +Only deinterlace frames marked as interlaced. +@end table + +The default value is @code{all}. + +@item rslope +Specify the search radius for edge slope tracing. Default value is 1. +Allowed range is from 1 to 15. + +@item redge +Specify the search radius for best edge matching. Default value is 2. +Allowed range is from 0 to 15. + +@item interp +Specify the interpolation used. Default is 4-point interpolation. It accepts one +of the following values: + +@table @option +@item 2p +Two-point interpolation. +@item 4p +Four-point interpolation. +@item 6p +Six-point interpolation. +@end table +@end table + +@subsection Commands +This filter supports same @ref{commands} as options. + +@section exposure +Adjust exposure of the video stream. + +The filter accepts the following options: + +@table @option +@item exposure +Set the exposure correction in EV. Allowed range is from -3.0 to 3.0 EV +Default value is 0 EV. + +@item black +Set the black level correction. Allowed range is from -1.0 to 1.0. +Default value is 0. +@end table + +@subsection Commands + +This filter supports same @ref{commands} as options. + @section extractplanes Extract color channel components from input video stream into @@ -11106,16 +12093,25 @@ It accepts the following values: fill pixels using outermost pixels @item mirror -fill pixels using mirroring +fill pixels using mirroring (half sample symmetric) @item fixed fill pixels with constant value + +@item reflect +fill pixels using reflecting (whole sample symmetric) + +@item wrap +fill pixels using wrapping + +@item fade +fade pixels to constant value @end table Default is @var{smear}. @item color -Set color for pixels in fixed mode. Default is @var{black}. +Set color for pixels in fixed or fade mode. Default is @var{black}. @end table @subsection Commands @@ -11509,6 +12505,10 @@ frei0r=perspective:0.2/0.2|0.8/0.2 For more information, see @url{http://frei0r.dyne.org} +@subsection Commands + +This filter supports the @option{filter_params} option as @ref{commands}. + @section fspp Apply fast and simple postprocessing. It is a faster version of @ref{spp}. @@ -11817,6 +12817,9 @@ Display video size or number of audio channels in case of audio used by filter l @item rate Display video frame rate or sample rate in case of audio used by filter link. + +@item eof +Display link output status. @end table @item rate, r @@ -11892,6 +12895,10 @@ This filter also supports the @ref{framesync} options. More information about the Hald CLUT can be found on Eskil Steenberg's website (Hald CLUT author) at @url{http://www.quelsolaar.com/technology/clut.html}. +@subsection Commands + +This filter supports the @code{interp} option as @ref{commands}. + @subsection Workflow examples @subsubsection Hald CLUT video stream @@ -12369,6 +13376,28 @@ By default value is 0. The @code{hysteresis} filter also supports the @ref{framesync} options. +@section identity + +Obtain the identity score between two input videos. + +This filter takes two input videos. + +Both input videos must have the same resolution and pixel format for +this filter to work correctly. Also it assumes that both inputs +have the same number of frames, which are compared one by one. + +The obtained per component, average, min and max identity score is printed through +the logging system. + +The filter stores the calculated identity scores of each frame in frame metadata. + +In the below example the input file @file{main.mpg} being processed is compared +with the reference file @file{ref.mpg}. + +@example +ffmpeg -i main.mpg -i ref.mpg -lavfi identity -f null - +@end example + @section idet Detect video interlacing type. @@ -12611,6 +13640,27 @@ kerndeint=map=1 @end example @end itemize +@section kirsch +Apply kirsch operator to input video stream. + +The filter accepts the following option: + +@table @option +@item planes +Set which planes will be processed, unprocessed planes will be copied. +By default value 0xf, all planes will be processed. + +@item scale +Set value which will be multiplied with filtered result. + +@item delta +Set value which will be added to filtered result. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section lagfun Slowly update darker pixels. @@ -12626,6 +13676,10 @@ Set factor for decaying. Default is .95. Allowed range is from 0 to 1. Set which planes to filter. Default is all. Allowed range is from 0 to 15. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section lenscorrection Correct radial lens distortion @@ -12664,6 +13718,13 @@ no correction. Default is 0. @item k2 Coefficient of the double quadratic correction term. This value has a range [-1,1]. 0 means no correction. Default is 0. +@item i +Set interpolation type. Can be @code{nearest} or @code{bilinear}. +Default is @code{nearest}. +@item fc +Specify the color of the unmapped pixels. For the syntax of this option, +check the @ref{color syntax,,"Color" section in the ffmpeg-utils +manual,ffmpeg-utils}. Default color is @code{black@@0}. @end table The formula that generates the correction is: @@ -12673,6 +13734,10 @@ The formula that generates the correction is: where @var{r_0} is halve of the image diagonal and @var{r_src} and @var{r_tgt} are the distances from the focal point in the source and target images, respectively. +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section lensfun Apply lens correction via the lensfun library (@url{http://lensfun.sourceforge.net/}). @@ -12809,7 +13874,7 @@ The obtained VMAF score is printed through the logging system. It requires Netflix's vmaf library (libvmaf) as a pre-requisite. After installing the library it can be enabled using: -@code{./configure --enable-libvmaf --enable-version3}. +@code{./configure --enable-libvmaf}. If no model path is specified it uses the default model: @code{vmaf_v0.6.1.pkl}. The filter has following options: @@ -12823,7 +13888,7 @@ Default value: @code{"/usr/local/share/model/vmaf_v0.6.1.pkl"} Set the file path to be used to store logs. @item log_fmt -Set the format of the log file (xml or json). +Set the format of the log file (csv, json or xml). @item enable_transform This option can enable/disable the @code{score_transform} applied to the final predicted VMAF score, @@ -12906,6 +13971,10 @@ Upper bound. Defaults to the highest allowed value for the input. Specify which planes will be processed. Defaults to all available. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section loop Loop video frames. @@ -12983,6 +14052,10 @@ Interpolate values using the spline interpolation. @end table @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @anchor{lut3d} @section lut3d @@ -13019,9 +14092,17 @@ Use values from the nearest defined point. Interpolate values using the 8 points defining a cube. @item tetrahedral Interpolate values using a tetrahedron. +@item pyramid +Interpolate values using a pyramid. +@item prism +Interpolate values using a prism. @end table @end table +@subsection Commands + +This filter supports the @code{interp} option as @ref{commands}. + @section lumakey Turn certain luma values into transparency. @@ -13132,6 +14213,10 @@ expression All expressions default to "val". +@subsection Commands + +This filter supports same @ref{commands} as options. + @subsection Examples @itemize @@ -13251,6 +14336,10 @@ The second input video bit depth. All expressions default to "x". +@subsection Commands + +This filter supports the all above options as @ref{commands} except option @code{d}. + @subsection Examples @itemize @@ -13294,6 +14383,10 @@ copied from first stream. By default value 0xf, all planes will be processed. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section maskedmax Merge the second and third input stream into output stream using absolute differences @@ -13310,6 +14403,10 @@ copied from first stream. By default value 0xf, all planes will be processed. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section maskedmerge Merge the first input stream with the second input stream using per pixel @@ -13329,6 +14426,10 @@ copied from first stream. By default value 0xf, all planes will be processed. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section maskedmin Merge the second and third input stream into output stream using absolute differences @@ -13345,6 +14446,10 @@ copied from first stream. By default value 0xf, all planes will be processed. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section maskedthreshold Pick pixels comparing absolute difference of two video streams with fixed threshold. @@ -13366,6 +14471,10 @@ copied from second stream. By default value 0xf, all planes will be processed. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section maskfun Create mask from input video. @@ -13393,6 +14502,10 @@ average, output frame will be completely filled with value set by @var{fill} opt Typically useful for scene changes when used in combination with @code{tblend} filter. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section mcdeint Apply motion-compensation deinterlacing. @@ -13710,6 +14823,42 @@ The duration of the first input. @end table @end table +@subsection Commands + +This filter supports the following commands: +@table @option +@item weights +@item scale +Syntax is same as option with same name. +@end table + +@section monochrome +Convert video to gray using custom color filter. + +A description of the accepted options follows. + +@table @option +@item cb +Set the chroma blue spot. Allowed range is from -1 to 1. +Default value is 0. + +@item cr +Set the chroma red spot. Allowed range is from -1 to 1. +Default value is 0. + +@item size +Set the color filter size. Allowed range is from .1 to 10. +Default value is 1. + +@item high +Set the highlights strength. Allowed range is from 0 to 1. +Default value is 0. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section mpdecimate Drop frames that do not differ greatly from the previous frame in @@ -13748,6 +14897,27 @@ Default value for @option{hi} is 64*12, default value for @option{lo} is 64*5, and default value for @option{frac} is 0.33. @end table +@section msad + +Obtain the MSAD (Mean Sum of Absolute Differences) between two input videos. + +This filter takes two input videos. + +Both input videos must have the same resolution and pixel format for +this filter to work correctly. Also it assumes that both inputs +have the same number of frames, which are compared one by one. + +The obtained per component, average, min and max MSAD is printed through +the logging system. + +The filter stores the calculated MSAD of each frame in frame metadata. + +In the below example the input file @file{main.mpg} being processed is compared +with the reference file @file{ref.mpg}. + +@example +ffmpeg -i main.mpg -i ref.mpg -lavfi msad -f null - +@end example @section negate @@ -13761,6 +14931,10 @@ It accepts the following option: With value 1, it negates the alpha component, if present. Default value is 0. @end table +@subsection Commands + +This filter supports same @ref{commands} as options. + @anchor{nlmeans} @section nlmeans @@ -13874,9 +15048,9 @@ Set which set of weights to use in the predictor. Can be one of the following: @table @samp -@item a +@item a, abs weights trained to minimize absolute error -@item s +@item s, mse weights trained to minimize squared error @end table @@ -13898,14 +15072,16 @@ Can be one of the following: @item none @item original @item new +@item new2 +@item new3 @end table Default is @code{new}. - -@item fapprox -Set various debugging flags. @end table +@subsection Commands +This filter supports same @ref{commands} as options, excluding @var{weights} option. + @section noformat Force libavfilter not to use any of the specified pixel formats for the @@ -14342,9 +15518,15 @@ It accepts the following values: @item yuv420 force YUV420 output +@item yuv420p10 +force YUV420p10 output + @item yuv422 force YUV422 output +@item yuv422p10 +force YUV422p10 output + @item yuv444 force YUV444 output @@ -14523,7 +15705,7 @@ testsrc=s=100x100, split=4 [in0][in1][in2][in3]; Overlay one video on top of another. -This is the CUDA cariant of the @ref{overlay} filter. +This is the CUDA variant of the @ref{overlay} filter. It only accepts CUDA frames. The underlying input pixel formats have to match. It takes two inputs and has one output. The first input is the "main" @@ -15007,6 +16189,10 @@ Filter selects among @samp{t}, @samp{b} and @samp{p} using image analysis only. @end table @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section photosensitivity Reduce various flashes in video, so to help users with epilepsy. @@ -15069,6 +16255,10 @@ Set window X position, relative offset on X axis. Set window Y position, relative offset on Y axis. @end table +@subsection Commands + +This filter supports same @ref{commands} as options. + @section pp Enable the specified chain of postprocessing subfilters using libpostproc. This @@ -15304,6 +16494,10 @@ Set value which will be multiplied with filtered result. Set value which will be added to filtered result. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section pseudocolor Alter frame colors in video with pseudocolors. @@ -15323,12 +16517,33 @@ set pixel third component expression @item c3 set pixel fourth component expression, corresponds to the alpha component -@item i +@item index, i set component to use as base for altering colors + +@item preset, p +Pick one of built-in LUTs. By default is set to none. + +Available LUTs: +@table @samp +@item magma +@item inferno +@item plasma +@item viridis +@item turbo +@item cividis +@item range1 +@item range2 +@item shadows +@item highlights @end table -Each of them specifies the expression to use for computing the lookup table for -the corresponding pixel component values. +@item opacity +Set opacity of output colors. Allowed range is from 0 to 1. +Default value is set to 1. +@end table + +Each of the expression options specifies the expression to use for computing +the lookup table for the corresponding pixel component values. The expressions can contain the following constants and functions: @@ -15349,6 +16564,10 @@ The maximum allowed component value. All expressions default to "val". +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @subsection Examples @itemize @@ -15620,6 +16839,10 @@ Enable checking the parity bit. In the event of a parity error, the filter will Lowpass lines prior to further processing. Default is enabled. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @subsection Examples @itemize @@ -15892,6 +17115,10 @@ Set value which will be multiplied with filtered result. Set value which will be added to filtered result. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section rotate Rotate video by an arbitrary angle expressed in radians. @@ -16975,6 +18202,37 @@ Keep the same colorspace property (default). @end table @end table +@section shear +Apply shear transform to input video. + +This filter supports the following options: + +@table @option +@item shx +Shear factor in X-direction. Default value is 0. +Allowed range is from -2 to 2. + +@item shy +Shear factor in Y-direction. Default value is 0. +Allowed range is from -2 to 2. + +@item fillcolor, c +Set the color used to fill the output area not covered by the transformed +video. For the general syntax of this option, check the +@ref{color syntax,,"Color" section in the ffmpeg-utils manual,ffmpeg-utils}. +If the special value "none" is selected then no +background is printed (useful for example if the background is never shown). + +Default value is "black". + +@item interp +Set interpolation type. Can be @code{bilinear} or @code{nearest}. Default is @code{bilinear}. +@end table + +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section showinfo Show a line containing various information for each input video frame. @@ -17095,6 +18353,33 @@ ffmpeg -i INPUT -vf "shuffleframes=9 1 2 3 4 5 6 7 8 0" OUTPUT @end example @end itemize +@section shufflepixels + +Reorder pixels in video frames. + +This filter accepts the following options: + +@table @option +@item direction, d +Set shuffle direction. Can be forward or inverse direction. +Default direction is forward. + +@item mode, m +Set shuffle mode. Can be horizontal, vertical or block mode. + +@item width, w +@item height, h +Set shuffle block_size. In case of horizontal shuffle mode only width +part of size is used, and in case of vertical shuffle mode only height +part of size is used. + +@item seed, s +Set random seed used with shuffling pixels. Mainly useful to set to be able +to reverse filtering process to get original input. +For example, to reverse forward shuffle you need to use same parameters +and exact same seed and to set direction to inverse. +@end table + @section shuffleplanes Reorder and/or duplicate video planes. @@ -17478,6 +18763,10 @@ Set value which will be multiplied with filtered result. Set value which will be added to filtered result. @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @anchor{spp} @section spp @@ -17971,7 +19260,7 @@ subtitles=video.mkv:si=1 To make the subtitles stream from @file{sub.srt} appear in 80% transparent blue @code{DejaVu Serif}, use: @example -subtitles=sub.srt:force_style='FontName=DejaVu Serif,PrimaryColour=&HCCFF0000' +subtitles=sub.srt:force_style='Fontname=DejaVu Serif,PrimaryColour=&HCCFF0000' @end example @section super2xsai @@ -18035,6 +19324,10 @@ The timestamp expressed in seconds. It's NAN if the input timestamp is unknown. the position in the file of the input frame, NAN if unknown @end table +@subsection Commands + +This filter supports the all above options as @ref{commands}. + @section swapuv Swap U & V plane. @@ -18135,6 +19428,29 @@ Show envelope. Default is disabled. @item ecolor, ec Set envelope color. Default is @code{gold}. + +@item slide +Set slide mode. + +Available values for slide is: +@table @samp +@item frame +Draw new frame when right border is reached. + +@item replace +Replace old columns with new ones. + +@item scroll +Scroll from right to left. + +@item rscroll +Scroll from left to right. + +@item picture +Draw single picture. +@end table + +Default is @code{replace}. @end table @section threshold @@ -18547,6 +19863,32 @@ Default value of @code{0.5} will pick always median values, while @code{0} will minimum values, and @code{1} maximum values. @end table +@subsection Commands + +This filter supports all above options as @ref{commands}, excluding option @code{radius}. + +@section tmidequalizer + +Apply Temporal Midway Video Equalization effect. + +Midway Video Equalization adjusts a sequence of video frames to have the same +histograms, while maintaining their dynamics as much as possible. It's +useful for e.g. matching exposures from a video frames sequence. + +This filter accepts the following option: + +@table @option +@item radius +Set filtering radius. Default is @code{5}. Allowed range is from 1 to 127. + +@item sigma +Set filtering sigma. Default is @code{0.5}. This controls strength of filtering. +Setting this option to 0 effectively does nothing. + +@item planes +Set which planes to process. Default is @code{15}, which is all available planes. +@end table + @section tmix Mix successive video frames. @@ -18591,6 +19933,15 @@ tmix=frames=3:weights="-1 2 -1":scale=1 @end example @end itemize +@subsection Commands + +This filter supports the following commands: +@table @option +@item weights +@item scale +Syntax is same as option with same name. +@end table + @anchor{tonemap} @section tonemap Tone map colors from different dynamic ranges. @@ -19313,6 +20664,49 @@ Truncated square pyramid projection. @item he @item hequirect Half equirectangular projection. + +@item equisolid +Equisolid format. + +Format specific options: +@table @option +@item h_fov +@item v_fov +@item d_fov +Set output horizontal/vertical/diagonal field of view. Values in degrees. + +If diagonal field of view is set it overrides horizontal and vertical field of view. + +@item ih_fov +@item iv_fov +@item id_fov +Set input horizontal/vertical/diagonal field of view. Values in degrees. + +If diagonal field of view is set it overrides horizontal and vertical field of view. +@end table + +@item og +Orthographic format. + +Format specific options: +@table @option +@item h_fov +@item v_fov +@item d_fov +Set output horizontal/vertical/diagonal field of view. Values in degrees. + +If diagonal field of view is set it overrides horizontal and vertical field of view. + +@item ih_fov +@item iv_fov +@item id_fov +Set input horizontal/vertical/diagonal field of view. Values in degrees. + +If diagonal field of view is set it overrides horizontal and vertical field of view. +@end table + +@item octahedron +Octahedron projection. @end table @item interp @@ -19342,6 +20736,8 @@ Spline16 interpolation. @item gauss @item gaussian Gaussian interpolation. +@item mitchell +Mitchell interpolation. @end table Default value is @b{@samp{line}}. @@ -19907,6 +21303,27 @@ otherwise colors will be less saturated, more towards gray. This filter supports the all above options as @ref{commands}. +@section vif + +Obtain the average VIF (Visual Information Fidelity) between two input videos. + +This filter takes two input videos. + +Both input videos must have the same resolution and pixel format for +this filter to work correctly. Also it assumes that both inputs +have the same number of frames, which are compared one by one. + +The obtained average VIF score is printed through the logging system. + +The filter stores the calculated VIF score of each frame. + +In the below example the input file @file{main.mpg} being processed is compared +with the reference file @file{ref.mpg}. + +@example +ffmpeg -i main.mpg -i ref.mpg -lavfi vif -f null - +@end example + @anchor{vignette} @section vignette @@ -20088,6 +21505,35 @@ More-complex filter coefficient set. @end table Default value is @samp{complex}. +@item mode +The interlacing mode to adopt. It accepts one of the following values: + +@table @option +@item frame +Output one frame for each frame. +@item field +Output one frame for each field. +@end table + +The default value is @code{field}. + +@item parity +The picture field parity assumed for the input interlaced video. It accepts one +of the following values: + +@table @option +@item tff +Assume the top field is first. +@item bff +Assume the bottom field is first. +@item auto +Enable automatic detection of field parity. +@end table + +The default value is @code{auto}. +If the interlacing is unknown or the decoder does not export this information, +top field first will be assumed. + @item deint Specify which frames to deinterlace. Accepts one of the following values: @@ -20101,6 +21547,9 @@ Only deinterlace frames marked as interlaced. Default value is @samp{all}. @end table +@subsection Commands +This filter supports same @ref{commands} as options. + @section waveform Video waveform monitor. @@ -20354,6 +21803,14 @@ Set one of available transition effects: @item hrslice @item vuslice @item vdslice +@item hblur +@item fadegrays +@item wipetl +@item wipetr +@item wipebl +@item wipebr +@item squeezeh +@item squeezev @end table Default transition effect is fade. @@ -20438,6 +21895,10 @@ Default value of @code{0.5} will pick always median values, while @code{0} will minimum values, and @code{1} maximum values. @end table +@subsection Commands + +This filter supports all above options as @ref{commands}, excluding option @code{inputs}. + @section xstack Stack video inputs into custom layout. @@ -20703,7 +22164,7 @@ Set the x and y expression. Default is 0. @item d Set the duration expression in number of frames. This sets for how many number of frames effect will last for -single input image. +single input image. Default is 90. @item s Set the output image size, default is 'hd720'. @@ -20733,6 +22194,12 @@ Input frame count. @item on Output frame count. +@item in_time, it +The input timestamp expressed in seconds. It's NAN if the input timestamp is unknown. + +@item out_time, time, ot +The output timestamp expressed in seconds. + @item x @item y Last calculated 'x' and 'y' position from 'x' and 'y' expression @@ -20771,13 +22238,13 @@ display aspect ratio @itemize @item -Zoom-in up to 1.5 and pan at same time to some spot near center of picture: +Zoom in up to 1.5x and pan at same time to some spot near center of picture: @example zoompan=z='min(zoom+0.0015,1.5)':d=700:x='if(gte(zoom,1.5),x,x+1/a)':y='if(gte(zoom,1.5),y,y+1)':s=640x360 @end example @item -Zoom-in up to 1.5 and pan always at center of picture: +Zoom in up to 1.5x and pan always at center of picture: @example zoompan=z='min(zoom+0.0015,1.5)':d=700:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)' @end example @@ -20787,6 +22254,13 @@ Same as above but without pausing: @example zoompan=z='min(max(zoom,pzoom)+0.0015,1.5)':d=1:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)' @end example + +@item +Zoom in 2x into center of picture only for the first second of the input video: +@example +zoompan=z='if(between(in_time,0,1),2,1)':d=1:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)' +@end example + @end itemize @anchor{zscale} @@ -21008,6 +22482,13 @@ Possible values are: @item npl Set the nominal peak luminance. + +@item param_a +Parameter A for scaling filters. Parameter "b" for bicubic, and the number of +filter taps for lanczos. + +@item param_b +Parameter B for scaling filters. Parameter "c" for bicubic. @end table The values of the @option{w} and @option{h} options are expressions @@ -22125,7 +23606,7 @@ Below is a description of the currently available video sources. Buffer video frames, and make them available to the filter chain. This source is mainly intended for a programmatic use, in particular -through the interface defined in @file{libavfilter/vsrc_buffer.h}. +through the interface defined in @file{libavfilter/buffersrc.h}. It accepts the following parameters: @@ -22385,6 +23866,17 @@ Set number of colors to use at once. Allowed range is from 2 to 8. Default value @item seed Set seed for picking gradient line points. + +@item duration, d +Set the duration of the sourced video. See +@ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils} +for the accepted syntax. + +If not specified, or the expressed duration is negative, the video is +supposed to be generated forever. + +@item speed +Set speed of gradients rotation. @end table @@ -22774,6 +24266,10 @@ for the accepted syntax. If not specified, or the expressed duration is negative, the video is supposed to be generated forever. +Since the frame rate is used as time base, all frames including the last one +will have their full duration. If the specified duration is not a multiple +of the frame duration, it will be rounded up. + @item sar Set the sample aspect ratio of the sourced video. @@ -23103,6 +24599,39 @@ Set color which will be used for drawing median phase. If color is Enable video output. Default is enabled. @end table +@subsection phasing detection + +The filter also detects out of phase and mono sequences in stereo streams. +It logs the sequence start, end and duration when it lasts longer or as long as the minimum set. + +The filter accepts the following options for this detection: + +@table @option +@item phasing +Enable mono and out of phase detection. Default is disabled. + +@item tolerance, t +Set phase tolerance for mono detection, in amplitude ratio. Default is @code{0}. +Allowed range is @code{[0, 1]}. + +@item angle, a +Set angle threshold for out of phase detection, in degree. Default is @code{170}. +Allowed range is @code{[90, 180]}. + +@item duration, d +Set mono or out of phase duration until notification, expressed in seconds. Default is @code{2}. +@end table + +@subsection Examples + +@itemize +@item +Complete example with @command{ffmpeg} to detect 1 second of mono with 0.001 phase tolerance: +@example +ffmpeg -i stereo.wav -af aphasemeter=video=0:phasing=1:duration=1:tolerance=0.001 -f null - +@end example +@end itemize + @section avectorscope Convert input audio to a video output, representing the audio vector @@ -24727,6 +26256,16 @@ Default is @code{combined}. @item minamp Set minimum amplitude used in @code{log} amplitude scaler. +@item data +Set data display mode. + +It accepts the following values: +@table @samp +@item magnitude +@item phase +@item delay +@end table +Default is @code{magnitude}. @end table @section showspatial @@ -25377,6 +26916,20 @@ Draw every sample directly. @end table Default value is @code{scale}. + +@item filter +Set the filter mode. + +Available values are: +@table @samp +@item average +Use average samples values for each drawn sample. + +@item peak +Use peak samples values for each drawn sample. +@end table + +Default value is @code{average}. @end table @subsection Examples diff --git a/doc/general.texi b/doc/general.texi index 9b0ee9675..253c0ba5a 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -10,1405 +10,6 @@ @contents -@chapter External libraries - -FFmpeg can be hooked up with a number of external libraries to add support -for more formats. None of them are used by default, their use has to be -explicitly requested by passing the appropriate flags to -@command{./configure}. - -@section Alliance for Open Media (AOM) - -FFmpeg can make use of the AOM library for AV1 decoding and encoding. - -Go to @url{http://aomedia.org/} and follow the instructions for -installing the library. Then pass @code{--enable-libaom} to configure to -enable it. - -@section AMD AMF/VCE - -FFmpeg can use the AMD Advanced Media Framework library -for accelerated H.264 and HEVC(only windows) encoding on hardware with Video Coding Engine (VCE). - -To enable support you must obtain the AMF framework header files(version 1.4.9+) from -@url{https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git}. - -Create an @code{AMF/} directory in the system include path. -Copy the contents of @code{AMF/amf/public/include/} into that directory. -Then configure FFmpeg with @code{--enable-amf}. - -Initialization of amf encoder occurs in this order: -1) trying to initialize through dx11(only windows) -2) trying to initialize through dx9(only windows) -3) trying to initialize through vulkan - -To use h.264(AMD VCE) encoder on linux amdgru-pro version 19.20+ and amf-amdgpu-pro -package(amdgru-pro contains, but does not install automatically) are required. - -This driver can be installed using amdgpu-pro-install script in official amd driver archive. - -@section AviSynth - -FFmpeg can read AviSynth scripts as input. To enable support, pass -@code{--enable-avisynth} to configure after installing the headers -provided by @url{https://github.com/AviSynth/AviSynthPlus, AviSynth+}. -AviSynth+ can be configured to install only the headers by either -passing @code{-DHEADERS_ONLY:bool=on} to the normal CMake-based build -system, or by using the supplied @code{GNUmakefile}. - -For Windows, supported AviSynth variants are -@url{http://avisynth.nl, AviSynth 2.6 RC1 or higher} for 32-bit builds and -@url{http://avisynth.nl/index.php/AviSynth+, AviSynth+ r1718 or higher} for 32-bit and 64-bit builds. - -For Linux, macOS, and BSD, the only supported AviSynth variant is -@url{https://github.com/AviSynth/AviSynthPlus, AviSynth+}, starting with version 3.5. - -@float NOTE -In 2016, AviSynth+ added support for building with GCC. However, due to -the eccentricities of Windows' calling conventions, 32-bit GCC builds -of AviSynth+ are not compatible with typical 32-bit builds of FFmpeg. - -By default, FFmpeg assumes compatibility with 32-bit MSVC builds of -AviSynth+ since that is the most widely-used and entrenched build -configuration. Users can override this and enable support for 32-bit -GCC builds of AviSynth+ by passing @code{-DAVSC_WIN32_GCC32} to -@code{--extra-cflags} when configuring FFmpeg. - -64-bit builds of FFmpeg are not affected, and can use either MSVC or -GCC builds of AviSynth+ without any special flags. -@end float - -@float NOTE -AviSynth(+) is loaded dynamically. Distributors can build FFmpeg -with @code{--enable-avisynth}, and the binaries will work regardless -of the end user having AviSynth installed. If/when an end user -would like to use AviSynth scripts, then they can install AviSynth(+) -and FFmpeg will be able to find and use it to open scripts. -@end float - -@section Chromaprint - -FFmpeg can make use of the Chromaprint library for generating audio fingerprints. -Pass @code{--enable-chromaprint} to configure to -enable it. See @url{https://acoustid.org/chromaprint}. - -@section codec2 - -FFmpeg can make use of the codec2 library for codec2 decoding and encoding. -There is currently no native decoder, so libcodec2 must be used for decoding. - -Go to @url{http://freedv.org/}, download "Codec 2 source archive". -Build and install using CMake. Debian users can install the libcodec2-dev package instead. -Once libcodec2 is installed you can pass @code{--enable-libcodec2} to configure to enable it. - -The easiest way to use codec2 is with .c2 files, since they contain the mode information required for decoding. -To encode such a file, use a .c2 file extension and give the libcodec2 encoder the -mode option: -@code{ffmpeg -i input.wav -mode 700C output.c2}. -Playback is as simple as @code{ffplay output.c2}. -For a list of supported modes, run @code{ffmpeg -h encoder=libcodec2}. -Raw codec2 files are also supported. -To make sense of them the mode in use needs to be specified as a format option: -@code{ffmpeg -f codec2raw -mode 1300 -i input.raw output.wav}. - -@section dav1d - -FFmpeg can make use of the dav1d library for AV1 video decoding. - -Go to @url{https://code.videolan.org/videolan/dav1d} and follow the instructions for -installing the library. Then pass @code{--enable-libdav1d} to configure to enable it. - -@section davs2 - -FFmpeg can make use of the davs2 library for AVS2-P2/IEEE1857.4 video decoding. - -Go to @url{https://github.com/pkuvcl/davs2} and follow the instructions for -installing the library. Then pass @code{--enable-libdavs2} to configure to -enable it. - -@float NOTE -libdavs2 is under the GNU Public License Version 2 or later -(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for -details), you must upgrade FFmpeg's license to GPL in order to use it. -@end float - -@section Game Music Emu - -FFmpeg can make use of the Game Music Emu library to read audio from supported video game -music file formats. Pass @code{--enable-libgme} to configure to -enable it. See @url{https://bitbucket.org/mpyne/game-music-emu/overview}. - -@section Intel QuickSync Video - -FFmpeg can use Intel QuickSync Video (QSV) for accelerated decoding and encoding -of multiple codecs. To use QSV, FFmpeg must be linked against the @code{libmfx} -dispatcher, which loads the actual decoding libraries. - -The dispatcher is open source and can be downloaded from -@url{https://github.com/lu-zero/mfx_dispatch.git}. FFmpeg needs to be configured -with the @code{--enable-libmfx} option and @code{pkg-config} needs to be able to -locate the dispatcher's @code{.pc} files. - -@section Kvazaar - -FFmpeg can make use of the Kvazaar library for HEVC encoding. - -Go to @url{https://github.com/ultravideo/kvazaar} and follow the -instructions for installing the library. Then pass -@code{--enable-libkvazaar} to configure to enable it. - -@section LAME - -FFmpeg can make use of the LAME library for MP3 encoding. - -Go to @url{http://lame.sourceforge.net/} and follow the -instructions for installing the library. -Then pass @code{--enable-libmp3lame} to configure to enable it. - -@section libilbc - -iLBC is a narrowband speech codec that has been made freely available -by Google as part of the WebRTC project. libilbc is a packaging friendly -copy of the iLBC codec. FFmpeg can make use of the libilbc library for -iLBC decoding and encoding. - -Go to @url{https://github.com/TimothyGu/libilbc} and follow the instructions for -installing the library. Then pass @code{--enable-libilbc} to configure to -enable it. - -@section libvpx - -FFmpeg can make use of the libvpx library for VP8/VP9 decoding and encoding. - -Go to @url{http://www.webmproject.org/} and follow the instructions for -installing the library. Then pass @code{--enable-libvpx} to configure to -enable it. - -@section ModPlug - -FFmpeg can make use of this library, originating in Modplug-XMMS, to read from MOD-like music files. -See @url{https://github.com/Konstanty/libmodplug}. Pass @code{--enable-libmodplug} to configure to -enable it. - -@section OpenCORE, VisualOn, and Fraunhofer libraries - -Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer -libraries provide encoders for a number of audio codecs. - -@float NOTE -OpenCORE and VisualOn libraries are under the Apache License 2.0 -(see @url{http://www.apache.org/licenses/LICENSE-2.0} for details), which is -incompatible to the LGPL version 2.1 and GPL version 2. You have to -upgrade FFmpeg's license to LGPL version 3 (or if you have enabled -GPL components, GPL version 3) by passing @code{--enable-version3} to configure in -order to use it. - -The license of the Fraunhofer AAC library is incompatible with the GPL. -Therefore, for GPL builds, you have to pass @code{--enable-nonfree} to -configure in order to use it. To the best of our knowledge, it is -compatible with the LGPL. -@end float - -@subsection OpenCORE AMR - -FFmpeg can make use of the OpenCORE libraries for AMR-NB -decoding/encoding and AMR-WB decoding. - -Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the -instructions for installing the libraries. -Then pass @code{--enable-libopencore-amrnb} and/or -@code{--enable-libopencore-amrwb} to configure to enable them. - -@subsection VisualOn AMR-WB encoder library - -FFmpeg can make use of the VisualOn AMR-WBenc library for AMR-WB encoding. - -Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the -instructions for installing the library. -Then pass @code{--enable-libvo-amrwbenc} to configure to enable it. - -@subsection Fraunhofer AAC library - -FFmpeg can make use of the Fraunhofer AAC library for AAC decoding & encoding. - -Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the -instructions for installing the library. -Then pass @code{--enable-libfdk-aac} to configure to enable it. - -@section OpenH264 - -FFmpeg can make use of the OpenH264 library for H.264 decoding and encoding. - -Go to @url{http://www.openh264.org/} and follow the instructions for -installing the library. Then pass @code{--enable-libopenh264} to configure to -enable it. - -For decoding, this library is much more limited than the built-in decoder -in libavcodec; currently, this library lacks support for decoding B-frames -and some other main/high profile features. (It currently only supports -constrained baseline profile and CABAC.) Using it is mostly useful for -testing and for taking advantage of Cisco's patent portfolio license -(@url{http://www.openh264.org/BINARY_LICENSE.txt}). - -@section OpenJPEG - -FFmpeg can use the OpenJPEG libraries for decoding/encoding J2K videos. Go to -@url{http://www.openjpeg.org/} to get the libraries and follow the installation -instructions. To enable using OpenJPEG in FFmpeg, pass @code{--enable-libopenjpeg} to -@file{./configure}. - -@section rav1e - -FFmpeg can make use of rav1e (Rust AV1 Encoder) via its C bindings to encode videos. -Go to @url{https://github.com/xiph/rav1e/} and follow the instructions to build -the C library. To enable using rav1e in FFmpeg, pass @code{--enable-librav1e} -to @file{./configure}. - -@section TwoLAME - -FFmpeg can make use of the TwoLAME library for MP2 encoding. - -Go to @url{http://www.twolame.org/} and follow the -instructions for installing the library. -Then pass @code{--enable-libtwolame} to configure to enable it. - -@section VapourSynth - -FFmpeg can read VapourSynth scripts as input. To enable support, pass -@code{--enable-vapoursynth} to configure. Vapoursynth is detected via -@code{pkg-config}. Versions 42 or greater supported. -See @url{http://www.vapoursynth.com/}. - -Due to security concerns, Vapoursynth scripts will not -be autodetected so the input format has to be forced. For ff* CLI tools, -add @code{-f vapoursynth} before the input @code{-i yourscript.vpy}. - -@section WavPack - -FFmpeg can make use of the libwavpack library for WavPack encoding. - -Go to @url{http://www.wavpack.com/} and follow the instructions for -installing the library. Then pass @code{--enable-libwavpack} to configure to -enable it. - -@section x264 - -FFmpeg can make use of the x264 library for H.264 encoding. - -Go to @url{http://www.videolan.org/developers/x264.html} and follow the -instructions for installing the library. Then pass @code{--enable-libx264} to -configure to enable it. - -@float NOTE -x264 is under the GNU Public License Version 2 or later -(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for -details), you must upgrade FFmpeg's license to GPL in order to use it. -@end float - -@section x265 - -FFmpeg can make use of the x265 library for HEVC encoding. - -Go to @url{http://x265.org/developers.html} and follow the instructions -for installing the library. Then pass @code{--enable-libx265} to configure -to enable it. - -@float NOTE -x265 is under the GNU Public License Version 2 or later -(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for -details), you must upgrade FFmpeg's license to GPL in order to use it. -@end float - -@section xavs - -FFmpeg can make use of the xavs library for AVS encoding. - -Go to @url{http://xavs.sf.net/} and follow the instructions for -installing the library. Then pass @code{--enable-libxavs} to configure to -enable it. - -@section xavs2 - -FFmpeg can make use of the xavs2 library for AVS2-P2/IEEE1857.4 video encoding. - -Go to @url{https://github.com/pkuvcl/xavs2} and follow the instructions for -installing the library. Then pass @code{--enable-libxavs2} to configure to -enable it. - -@float NOTE -libxavs2 is under the GNU Public License Version 2 or later -(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for -details), you must upgrade FFmpeg's license to GPL in order to use it. -@end float - -@section ZVBI - -ZVBI is a VBI decoding library which can be used by FFmpeg to decode DVB -teletext pages and DVB teletext subtitles. - -Go to @url{http://sourceforge.net/projects/zapping/} and follow the instructions for -installing the library. Then pass @code{--enable-libzvbi} to configure to -enable it. - -@chapter Supported File Formats, Codecs or Features - -You can use the @code{-formats} and @code{-codecs} options to have an exhaustive list. - -@section File Formats - -FFmpeg supports the following file formats through the @code{libavformat} -library: - -@multitable @columnfractions .4 .1 .1 .4 -@item Name @tab Encoding @tab Decoding @tab Comments -@item 3dostr @tab @tab X -@item 4xm @tab @tab X - @tab 4X Technologies format, used in some games. -@item 8088flex TMV @tab @tab X -@item AAX @tab @tab X - @tab Audible Enhanced Audio format, used in audiobooks. -@item AA @tab @tab X - @tab Audible Format 2, 3, and 4, used in audiobooks. -@item ACT Voice @tab @tab X - @tab contains G.729 audio -@item Adobe Filmstrip @tab X @tab X -@item Audio IFF (AIFF) @tab X @tab X -@item American Laser Games MM @tab @tab X - @tab Multimedia format used in games like Mad Dog McCree. -@item 3GPP AMR @tab X @tab X -@item Amazing Studio Packed Animation File @tab @tab X - @tab Multimedia format used in game Heart Of Darkness. -@item Apple HTTP Live Streaming @tab @tab X -@item Artworx Data Format @tab @tab X -@item Interplay ACM @tab @tab X - @tab Audio only format used in some Interplay games. -@item ADP @tab @tab X - @tab Audio format used on the Nintendo Gamecube. -@item AFC @tab @tab X - @tab Audio format used on the Nintendo Gamecube. -@item ADS/SS2 @tab @tab X - @tab Audio format used on the PS2. -@item APNG @tab X @tab X -@item ASF @tab X @tab X -@item AST @tab X @tab X - @tab Audio format used on the Nintendo Wii. -@item AVI @tab X @tab X -@item AviSynth @tab @tab X -@item AVR @tab @tab X - @tab Audio format used on Mac. -@item AVS @tab @tab X - @tab Multimedia format used by the Creature Shock game. -@item Beam Software SIFF @tab @tab X - @tab Audio and video format used in some games by Beam Software. -@item Bethesda Softworks VID @tab @tab X - @tab Used in some games from Bethesda Softworks. -@item Binary text @tab @tab X -@item Bink @tab @tab X - @tab Multimedia format used by many games. -@item Bitmap Brothers JV @tab @tab X - @tab Used in Z and Z95 games. -@item Brute Force & Ignorance @tab @tab X - @tab Used in the game Flash Traffic: City of Angels. -@item BFSTM @tab @tab X - @tab Audio format used on the Nintendo WiiU (based on BRSTM). -@item BRSTM @tab @tab X - @tab Audio format used on the Nintendo Wii. -@item BWF @tab X @tab X -@item codec2 (raw) @tab X @tab X - @tab Must be given -mode format option to decode correctly. -@item codec2 (.c2 files) @tab X @tab X - @tab Contains header with version and mode info, simplifying playback. -@item CRI ADX @tab X @tab X - @tab Audio-only format used in console video games. -@item CRI AIX @tab @tab X -@item CRI HCA @tab @tab X - @tab Audio-only format used in console video games. -@item Discworld II BMV @tab @tab X -@item Interplay C93 @tab @tab X - @tab Used in the game Cyberia from Interplay. -@item Delphine Software International CIN @tab @tab X - @tab Multimedia format used by Delphine Software games. -@item Digital Speech Standard (DSS) @tab @tab X -@item Canopus HQ @tab @tab X -@item Canopus HQA @tab @tab X -@item Canopus HQX @tab @tab X -@item CD+G @tab @tab X - @tab Video format used by CD+G karaoke disks -@item Phantom Cine @tab @tab X -@item Cineform HD @tab @tab X -@item Commodore CDXL @tab @tab X - @tab Amiga CD video format -@item Core Audio Format @tab X @tab X - @tab Apple Core Audio Format -@item CRC testing format @tab X @tab -@item Creative Voice @tab X @tab X - @tab Created for the Sound Blaster Pro. -@item CRYO APC @tab @tab X - @tab Audio format used in some games by CRYO Interactive Entertainment. -@item D-Cinema audio @tab X @tab X -@item Deluxe Paint Animation @tab @tab X -@item DCSTR @tab @tab X -@item DFA @tab @tab X - @tab This format is used in Chronomaster game -@item DirectDraw Surface @tab @tab X -@item DSD Stream File (DSF) @tab @tab X -@item DV video @tab X @tab X -@item DXA @tab @tab X - @tab This format is used in the non-Windows version of the Feeble Files - game and different game cutscenes repacked for use with ScummVM. -@item Electronic Arts cdata @tab @tab X -@item Electronic Arts Multimedia @tab @tab X - @tab Used in various EA games; files have extensions like WVE and UV2. -@item Ensoniq Paris Audio File @tab @tab X -@item FFM (FFserver live feed) @tab X @tab X -@item Flash (SWF) @tab X @tab X -@item Flash 9 (AVM2) @tab X @tab X - @tab Only embedded audio is decoded. -@item FLI/FLC/FLX animation @tab @tab X - @tab .fli/.flc files -@item Flash Video (FLV) @tab X @tab X - @tab Macromedia Flash video files -@item framecrc testing format @tab X @tab -@item FunCom ISS @tab @tab X - @tab Audio format used in various games from FunCom like The Longest Journey. -@item G.723.1 @tab X @tab X -@item G.726 @tab @tab X @tab Both left- and right-justified. -@item G.729 BIT @tab X @tab X -@item G.729 raw @tab @tab X -@item GENH @tab @tab X - @tab Audio format for various games. -@item GIF Animation @tab X @tab X -@item GXF @tab X @tab X - @tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley - playout servers. -@item HNM @tab @tab X - @tab Only version 4 supported, used in some games from Cryo Interactive -@item iCEDraw File @tab @tab X -@item ICO @tab X @tab X - @tab Microsoft Windows ICO -@item id Quake II CIN video @tab @tab X -@item id RoQ @tab X @tab X - @tab Used in Quake III, Jedi Knight 2 and other computer games. -@item IEC61937 encapsulation @tab X @tab X -@item IFF @tab @tab X - @tab Interchange File Format -@item IFV @tab @tab X - @tab A format used by some old CCTV DVRs. -@item iLBC @tab X @tab X -@item Interplay MVE @tab @tab X - @tab Format used in various Interplay computer games. -@item Iterated Systems ClearVideo @tab @tab X - @tab I-frames only -@item IV8 @tab @tab X - @tab A format generated by IndigoVision 8000 video server. -@item IVF (On2) @tab X @tab X - @tab A format used by libvpx -@item Internet Video Recording @tab @tab X -@item IRCAM @tab X @tab X -@item LATM @tab X @tab X -@item LMLM4 @tab @tab X - @tab Used by Linux Media Labs MPEG-4 PCI boards -@item LOAS @tab @tab X - @tab contains LATM multiplexed AAC audio -@item LRC @tab X @tab X -@item LVF @tab @tab X -@item LXF @tab @tab X - @tab VR native stream format, used by Leitch/Harris' video servers. -@item Magic Lantern Video (MLV) @tab @tab X -@item Matroska @tab X @tab X -@item Matroska audio @tab X @tab -@item FFmpeg metadata @tab X @tab X - @tab Metadata in text format. -@item MAXIS XA @tab @tab X - @tab Used in Sim City 3000; file extension .xa. -@item MD Studio @tab @tab X -@item Metal Gear Solid: The Twin Snakes @tab @tab X -@item Megalux Frame @tab @tab X - @tab Used by Megalux Ultimate Paint -@item Mobotix .mxg @tab @tab X -@item Monkey's Audio @tab @tab X -@item Motion Pixels MVI @tab @tab X -@item MOV/QuickTime/MP4 @tab X @tab X - @tab 3GP, 3GP2, PSP, iPod variants supported -@item MP2 @tab X @tab X -@item MP3 @tab X @tab X -@item MPEG-1 System @tab X @tab X - @tab muxed audio and video, VCD format supported -@item MPEG-PS (program stream) @tab X @tab X - @tab also known as @code{VOB} file, SVCD and DVD format supported -@item MPEG-TS (transport stream) @tab X @tab X - @tab also known as DVB Transport Stream -@item MPEG-4 @tab X @tab X - @tab MPEG-4 is a variant of QuickTime. -@item MSF @tab @tab X - @tab Audio format used on the PS3. -@item Mirillis FIC video @tab @tab X - @tab No cursor rendering. -@item MIDI Sample Dump Standard @tab @tab X -@item MIME multipart JPEG @tab X @tab -@item MSN TCP webcam @tab @tab X - @tab Used by MSN Messenger webcam streams. -@item MTV @tab @tab X -@item Musepack @tab @tab X -@item Musepack SV8 @tab @tab X -@item Material eXchange Format (MXF) @tab X @tab X - @tab SMPTE 377M, used by D-Cinema, broadcast industry. -@item Material eXchange Format (MXF), D-10 Mapping @tab X @tab X - @tab SMPTE 386M, D-10/IMX Mapping. -@item NC camera feed @tab @tab X - @tab NC (AVIP NC4600) camera streams -@item NIST SPeech HEader REsources @tab @tab X -@item Computerized Speech Lab NSP @tab @tab X -@item NTT TwinVQ (VQF) @tab @tab X - @tab Nippon Telegraph and Telephone Corporation TwinVQ. -@item Nullsoft Streaming Video @tab @tab X -@item NuppelVideo @tab @tab X -@item NUT @tab X @tab X - @tab NUT Open Container Format -@item Ogg @tab X @tab X -@item Playstation Portable PMP @tab @tab X -@item Portable Voice Format @tab @tab X -@item TechnoTrend PVA @tab @tab X - @tab Used by TechnoTrend DVB PCI boards. -@item QCP @tab @tab X -@item raw ADTS (AAC) @tab X @tab X -@item raw AC-3 @tab X @tab X -@item raw AMR-NB @tab @tab X -@item raw AMR-WB @tab @tab X -@item raw aptX @tab X @tab X -@item raw aptX HD @tab X @tab X -@item raw Chinese AVS video @tab X @tab X -@item raw Dirac @tab X @tab X -@item raw DNxHD @tab X @tab X -@item raw DTS @tab X @tab X -@item raw DTS-HD @tab @tab X -@item raw E-AC-3 @tab X @tab X -@item raw FLAC @tab X @tab X -@item raw GSM @tab @tab X -@item raw H.261 @tab X @tab X -@item raw H.263 @tab X @tab X -@item raw H.264 @tab X @tab X -@item raw HEVC @tab X @tab X -@item raw Ingenient MJPEG @tab @tab X -@item raw MJPEG @tab X @tab X -@item raw MLP @tab @tab X -@item raw MPEG @tab @tab X -@item raw MPEG-1 @tab @tab X -@item raw MPEG-2 @tab @tab X -@item raw MPEG-4 @tab X @tab X -@item raw NULL @tab X @tab -@item raw video @tab X @tab X -@item raw id RoQ @tab X @tab -@item raw SBC @tab X @tab X -@item raw Shorten @tab @tab X -@item raw TAK @tab @tab X -@item raw TrueHD @tab X @tab X -@item raw VC-1 @tab X @tab X -@item raw PCM A-law @tab X @tab X -@item raw PCM mu-law @tab X @tab X -@item raw PCM Archimedes VIDC @tab X @tab X -@item raw PCM signed 8 bit @tab X @tab X -@item raw PCM signed 16 bit big-endian @tab X @tab X -@item raw PCM signed 16 bit little-endian @tab X @tab X -@item raw PCM signed 24 bit big-endian @tab X @tab X -@item raw PCM signed 24 bit little-endian @tab X @tab X -@item raw PCM signed 32 bit big-endian @tab X @tab X -@item raw PCM signed 32 bit little-endian @tab X @tab X -@item raw PCM signed 64 bit big-endian @tab X @tab X -@item raw PCM signed 64 bit little-endian @tab X @tab X -@item raw PCM unsigned 8 bit @tab X @tab X -@item raw PCM unsigned 16 bit big-endian @tab X @tab X -@item raw PCM unsigned 16 bit little-endian @tab X @tab X -@item raw PCM unsigned 24 bit big-endian @tab X @tab X -@item raw PCM unsigned 24 bit little-endian @tab X @tab X -@item raw PCM unsigned 32 bit big-endian @tab X @tab X -@item raw PCM unsigned 32 bit little-endian @tab X @tab X -@item raw PCM 16.8 floating point little-endian @tab @tab X -@item raw PCM 24.0 floating point little-endian @tab @tab X -@item raw PCM floating-point 32 bit big-endian @tab X @tab X -@item raw PCM floating-point 32 bit little-endian @tab X @tab X -@item raw PCM floating-point 64 bit big-endian @tab X @tab X -@item raw PCM floating-point 64 bit little-endian @tab X @tab X -@item RDT @tab @tab X -@item REDCODE R3D @tab @tab X - @tab File format used by RED Digital cameras, contains JPEG 2000 frames and PCM audio. -@item RealMedia @tab X @tab X -@item Redirector @tab @tab X -@item RedSpark @tab @tab X -@item Renderware TeXture Dictionary @tab @tab X -@item Resolume DXV @tab @tab X -@item RL2 @tab @tab X - @tab Audio and video format used in some games by Entertainment Software Partners. -@item RPL/ARMovie @tab @tab X -@item Lego Mindstorms RSO @tab X @tab X -@item RSD @tab @tab X -@item RTMP @tab X @tab X - @tab Output is performed by publishing stream to RTMP server -@item RTP @tab X @tab X -@item RTSP @tab X @tab X -@item Sample Dump eXchange @tab @tab X -@item SAP @tab X @tab X -@item SBG @tab @tab X -@item SDP @tab @tab X -@item SER @tab @tab X -@item Sega FILM/CPK @tab X @tab X - @tab Used in many Sega Saturn console games. -@item Silicon Graphics Movie @tab @tab X -@item Sierra SOL @tab @tab X - @tab .sol files used in Sierra Online games. -@item Sierra VMD @tab @tab X - @tab Used in Sierra CD-ROM games. -@item Smacker @tab @tab X - @tab Multimedia format used by many games. -@item SMJPEG @tab X @tab X - @tab Used in certain Loki game ports. -@item SMPTE 337M encapsulation @tab @tab X -@item Smush @tab @tab X - @tab Multimedia format used in some LucasArts games. -@item Sony OpenMG (OMA) @tab X @tab X - @tab Audio format used in Sony Sonic Stage and Sony Vegas. -@item Sony PlayStation STR @tab @tab X -@item Sony Wave64 (W64) @tab X @tab X -@item SoX native format @tab X @tab X -@item SUN AU format @tab X @tab X -@item SUP raw PGS subtitles @tab X @tab X -@item SVAG @tab @tab X - @tab Audio format used in Konami PS2 games. -@item TDSC @tab @tab X -@item Text files @tab @tab X -@item THP @tab @tab X - @tab Used on the Nintendo GameCube. -@item Tiertex Limited SEQ @tab @tab X - @tab Tiertex .seq files used in the DOS CD-ROM version of the game Flashback. -@item True Audio @tab X @tab X -@item VAG @tab @tab X - @tab Audio format used in many Sony PS2 games. -@item VC-1 test bitstream @tab X @tab X -@item Vidvox Hap @tab X @tab X -@item Vivo @tab @tab X -@item VPK @tab @tab X - @tab Audio format used in Sony PS games. -@item WAV @tab X @tab X -@item WavPack @tab X @tab X -@item WebM @tab X @tab X -@item Windows Televison (WTV) @tab X @tab X -@item Wing Commander III movie @tab @tab X - @tab Multimedia format used in Origin's Wing Commander III computer game. -@item Westwood Studios audio @tab @tab X - @tab Multimedia format used in Westwood Studios games. -@item Westwood Studios VQA @tab @tab X - @tab Multimedia format used in Westwood Studios games. -@item Wideband Single-bit Data (WSD) @tab @tab X -@item WVE @tab @tab X -@item XMV @tab @tab X - @tab Microsoft video container used in Xbox games. -@item XVAG @tab @tab X - @tab Audio format used on the PS3. -@item xWMA @tab @tab X - @tab Microsoft audio container used by XAudio 2. -@item eXtended BINary text (XBIN) @tab @tab X -@item YUV4MPEG pipe @tab X @tab X -@item Psygnosis YOP @tab @tab X -@end multitable - -@code{X} means that the feature in that column (encoding / decoding) is supported. - -@section Image Formats - -FFmpeg can read and write images for each frame of a video sequence. The -following image formats are supported: - -@multitable @columnfractions .4 .1 .1 .4 -@item Name @tab Encoding @tab Decoding @tab Comments -@item .Y.U.V @tab X @tab X - @tab one raw file per component -@item Alias PIX @tab X @tab X - @tab Alias/Wavefront PIX image format -@item animated GIF @tab X @tab X -@item APNG @tab X @tab X -@item BMP @tab X @tab X - @tab Microsoft BMP image -@item BRender PIX @tab @tab X - @tab Argonaut BRender 3D engine image format. -@item DPX @tab X @tab X - @tab Digital Picture Exchange -@item EXR @tab @tab X - @tab OpenEXR -@item FITS @tab X @tab X - @tab Flexible Image Transport System -@item JPEG @tab X @tab X - @tab Progressive JPEG is not supported. -@item JPEG 2000 @tab X @tab X -@item JPEG-LS @tab X @tab X -@item LJPEG @tab X @tab - @tab Lossless JPEG -@item PAM @tab X @tab X - @tab PAM is a PNM extension with alpha support. -@item PBM @tab X @tab X - @tab Portable BitMap image -@item PCX @tab X @tab X - @tab PC Paintbrush -@item PGM @tab X @tab X - @tab Portable GrayMap image -@item PGMYUV @tab X @tab X - @tab PGM with U and V components in YUV 4:2:0 -@item PIC @tab @tab X - @tab Pictor/PC Paint -@item PNG @tab X @tab X -@item PPM @tab X @tab X - @tab Portable PixelMap image -@item PSD @tab @tab X - @tab Photoshop -@item PTX @tab @tab X - @tab V.Flash PTX format -@item SGI @tab X @tab X - @tab SGI RGB image format -@item Sun Rasterfile @tab X @tab X - @tab Sun RAS image format -@item TIFF @tab X @tab X - @tab YUV, JPEG and some extension is not supported yet. -@item Truevision Targa @tab X @tab X - @tab Targa (.TGA) image format -@item WebP @tab E @tab X - @tab WebP image format, encoding supported through external library libwebp -@item XBM @tab X @tab X - @tab X BitMap image format -@item XFace @tab X @tab X - @tab X-Face image format -@item XPM @tab @tab X - @tab X PixMap image format -@item XWD @tab X @tab X - @tab X Window Dump image format -@end multitable - -@code{X} means that the feature in that column (encoding / decoding) is supported. - -@code{E} means that support is provided through an external library. - -@section Video Codecs - -@multitable @columnfractions .4 .1 .1 .4 -@item Name @tab Encoding @tab Decoding @tab Comments -@item 4X Movie @tab @tab X - @tab Used in certain computer games. -@item 8088flex TMV @tab @tab X -@item A64 multicolor @tab X @tab - @tab Creates video suitable to be played on a commodore 64 (multicolor mode). -@item Amazing Studio PAF Video @tab @tab X -@item American Laser Games MM @tab @tab X - @tab Used in games like Mad Dog McCree. -@item AMV Video @tab X @tab X - @tab Used in Chinese MP3 players. -@item ANSI/ASCII art @tab @tab X -@item Apple Intermediate Codec @tab @tab X -@item Apple MJPEG-B @tab @tab X -@item Apple Pixlet @tab @tab X -@item Apple ProRes @tab X @tab X -@item Apple QuickDraw @tab @tab X - @tab fourcc: qdrw -@item Asus v1 @tab X @tab X - @tab fourcc: ASV1 -@item Asus v2 @tab X @tab X - @tab fourcc: ASV2 -@item ATI VCR1 @tab @tab X - @tab fourcc: VCR1 -@item ATI VCR2 @tab @tab X - @tab fourcc: VCR2 -@item Auravision Aura @tab @tab X -@item Auravision Aura 2 @tab @tab X -@item Autodesk Animator Flic video @tab @tab X -@item Autodesk RLE @tab @tab X - @tab fourcc: AASC -@item AV1 @tab E @tab E - @tab Supported through external libraries libaom, libdav1d and librav1e -@item Avid 1:1 10-bit RGB Packer @tab X @tab X - @tab fourcc: AVrp -@item AVS (Audio Video Standard) video @tab @tab X - @tab Video encoding used by the Creature Shock game. -@item AVS2-P2/IEEE1857.4 @tab E @tab E - @tab Supported through external libraries libxavs2 and libdavs2 -@item AYUV @tab X @tab X - @tab Microsoft uncompressed packed 4:4:4:4 -@item Beam Software VB @tab @tab X -@item Bethesda VID video @tab @tab X - @tab Used in some games from Bethesda Softworks. -@item Bink Video @tab @tab X -@item BitJazz SheerVideo @tab @tab X -@item Bitmap Brothers JV video @tab @tab X -@item y41p Brooktree uncompressed 4:1:1 12-bit @tab X @tab X -@item Brute Force & Ignorance @tab @tab X - @tab Used in the game Flash Traffic: City of Angels. -@item C93 video @tab @tab X - @tab Codec used in Cyberia game. -@item CamStudio @tab @tab X - @tab fourcc: CSCD -@item CD+G @tab @tab X - @tab Video codec for CD+G karaoke disks -@item CDXL @tab @tab X - @tab Amiga CD video codec -@item Chinese AVS video @tab E @tab X - @tab AVS1-P2, JiZhun profile, encoding through external library libxavs -@item Delphine Software International CIN video @tab @tab X - @tab Codec used in Delphine Software International games. -@item Discworld II BMV Video @tab @tab X -@item Canopus Lossless Codec @tab @tab X -@item CDToons @tab @tab X - @tab Codec used in various Broderbund games. -@item Cinepak @tab @tab X -@item Cirrus Logic AccuPak @tab X @tab X - @tab fourcc: CLJR -@item CPiA Video Format @tab @tab X -@item Creative YUV (CYUV) @tab @tab X -@item DFA @tab @tab X - @tab Codec used in Chronomaster game. -@item Dirac @tab E @tab X - @tab supported though the native vc2 (Dirac Pro) encoder -@item Deluxe Paint Animation @tab @tab X -@item DNxHD @tab X @tab X - @tab aka SMPTE VC3 -@item Duck TrueMotion 1.0 @tab @tab X - @tab fourcc: DUCK -@item Duck TrueMotion 2.0 @tab @tab X - @tab fourcc: TM20 -@item Duck TrueMotion 2.0 RT @tab @tab X - @tab fourcc: TR20 -@item DV (Digital Video) @tab X @tab X -@item Dxtory capture format @tab @tab X -@item Feeble Files/ScummVM DXA @tab @tab X - @tab Codec originally used in Feeble Files game. -@item Electronic Arts CMV video @tab @tab X - @tab Used in NHL 95 game. -@item Electronic Arts Madcow video @tab @tab X -@item Electronic Arts TGV video @tab @tab X -@item Electronic Arts TGQ video @tab @tab X -@item Electronic Arts TQI video @tab @tab X -@item Escape 124 @tab @tab X -@item Escape 130 @tab @tab X -@item FFmpeg video codec #1 @tab X @tab X - @tab lossless codec (fourcc: FFV1) -@item Flash Screen Video v1 @tab X @tab X - @tab fourcc: FSV1 -@item Flash Screen Video v2 @tab X @tab X -@item Flash Video (FLV) @tab X @tab X - @tab Sorenson H.263 used in Flash -@item FM Screen Capture Codec @tab @tab X -@item Forward Uncompressed @tab @tab X -@item Fraps @tab @tab X -@item Go2Meeting @tab @tab X - @tab fourcc: G2M2, G2M3 -@item Go2Webinar @tab @tab X - @tab fourcc: G2M4 -@item Gremlin Digital Video @tab @tab X -@item H.261 @tab X @tab X -@item H.263 / H.263-1996 @tab X @tab X -@item H.263+ / H.263-1998 / H.263 version 2 @tab X @tab X -@item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 @tab E @tab X - @tab encoding supported through external library libx264 and OpenH264 -@item HEVC @tab X @tab X - @tab encoding supported through external library libx265 and libkvazaar -@item HNM version 4 @tab @tab X -@item HuffYUV @tab X @tab X -@item HuffYUV FFmpeg variant @tab X @tab X -@item IBM Ultimotion @tab @tab X - @tab fourcc: ULTI -@item id Cinematic video @tab @tab X - @tab Used in Quake II. -@item id RoQ video @tab X @tab X - @tab Used in Quake III, Jedi Knight 2, other computer games. -@item IFF ILBM @tab @tab X - @tab IFF interleaved bitmap -@item IFF ByteRun1 @tab @tab X - @tab IFF run length encoded bitmap -@item Infinity IMM4 @tab @tab X -@item Intel H.263 @tab @tab X -@item Intel Indeo 2 @tab @tab X -@item Intel Indeo 3 @tab @tab X -@item Intel Indeo 4 @tab @tab X -@item Intel Indeo 5 @tab @tab X -@item Interplay C93 @tab @tab X - @tab Used in the game Cyberia from Interplay. -@item Interplay MVE video @tab @tab X - @tab Used in Interplay .MVE files. -@item J2K @tab X @tab X -@item Karl Morton's video codec @tab @tab X - @tab Codec used in Worms games. -@item Kega Game Video (KGV1) @tab @tab X - @tab Kega emulator screen capture codec. -@item Lagarith @tab @tab X -@item LCL (LossLess Codec Library) MSZH @tab @tab X -@item LCL (LossLess Codec Library) ZLIB @tab E @tab E -@item LOCO @tab @tab X -@item LucasArts SANM/Smush @tab @tab X - @tab Used in LucasArts games / SMUSH animations. -@item lossless MJPEG @tab X @tab X -@item MagicYUV Video @tab X @tab X -@item Mandsoft Screen Capture Codec @tab @tab X -@item Microsoft ATC Screen @tab @tab X - @tab Also known as Microsoft Screen 3. -@item Microsoft Expression Encoder Screen @tab @tab X - @tab Also known as Microsoft Titanium Screen 2. -@item Microsoft RLE @tab @tab X -@item Microsoft Screen 1 @tab @tab X - @tab Also known as Windows Media Video V7 Screen. -@item Microsoft Screen 2 @tab @tab X - @tab Also known as Windows Media Video V9 Screen. -@item Microsoft Video 1 @tab @tab X -@item Mimic @tab @tab X - @tab Used in MSN Messenger Webcam streams. -@item Miro VideoXL @tab @tab X - @tab fourcc: VIXL -@item MJPEG (Motion JPEG) @tab X @tab X -@item Mobotix MxPEG video @tab @tab X -@item Motion Pixels video @tab @tab X -@item MPEG-1 video @tab X @tab X -@item MPEG-2 video @tab X @tab X -@item MPEG-4 part 2 @tab X @tab X - @tab libxvidcore can be used alternatively for encoding. -@item MPEG-4 part 2 Microsoft variant version 1 @tab @tab X -@item MPEG-4 part 2 Microsoft variant version 2 @tab X @tab X -@item MPEG-4 part 2 Microsoft variant version 3 @tab X @tab X -@item Newtek SpeedHQ @tab @tab X -@item Nintendo Gamecube THP video @tab @tab X -@item NuppelVideo/RTjpeg @tab @tab X - @tab Video encoding used in NuppelVideo files. -@item On2 VP3 @tab @tab X - @tab still experimental -@item On2 VP4 @tab @tab X - @tab fourcc: VP40 -@item On2 VP5 @tab @tab X - @tab fourcc: VP50 -@item On2 VP6 @tab @tab X - @tab fourcc: VP60,VP61,VP62 -@item On2 VP7 @tab @tab X - @tab fourcc: VP70,VP71 -@item VP8 @tab E @tab X - @tab fourcc: VP80, encoding supported through external library libvpx -@item VP9 @tab E @tab X - @tab encoding supported through external library libvpx -@item Pinnacle TARGA CineWave YUV16 @tab @tab X - @tab fourcc: Y216 -@item Prores @tab @tab X - @tab fourcc: apch,apcn,apcs,apco -@item Q-team QPEG @tab @tab X - @tab fourccs: QPEG, Q1.0, Q1.1 -@item QuickTime 8BPS video @tab @tab X -@item QuickTime Animation (RLE) video @tab X @tab X - @tab fourcc: 'rle ' -@item QuickTime Graphics (SMC) @tab @tab X - @tab fourcc: 'smc ' -@item QuickTime video (RPZA) @tab @tab X - @tab fourcc: rpza -@item R10K AJA Kona 10-bit RGB Codec @tab X @tab X -@item R210 Quicktime Uncompressed RGB 10-bit @tab X @tab X -@item Raw Video @tab X @tab X -@item RealVideo 1.0 @tab X @tab X -@item RealVideo 2.0 @tab X @tab X -@item RealVideo 3.0 @tab @tab X - @tab still far from ideal -@item RealVideo 4.0 @tab @tab X -@item Renderware TXD (TeXture Dictionary) @tab @tab X - @tab Texture dictionaries used by the Renderware Engine. -@item RL2 video @tab @tab X - @tab used in some games by Entertainment Software Partners -@item ScreenPressor @tab @tab X -@item Screenpresso @tab @tab X -@item Screen Recorder Gold Codec @tab @tab X -@item Sierra VMD video @tab @tab X - @tab Used in Sierra VMD files. -@item Silicon Graphics Motion Video Compressor 1 (MVC1) @tab @tab X -@item Silicon Graphics Motion Video Compressor 2 (MVC2) @tab @tab X -@item Silicon Graphics RLE 8-bit video @tab @tab X -@item Smacker video @tab @tab X - @tab Video encoding used in Smacker. -@item SMPTE VC-1 @tab @tab X -@item Snow @tab X @tab X - @tab experimental wavelet codec (fourcc: SNOW) -@item Sony PlayStation MDEC (Motion DECoder) @tab @tab X -@item Sorenson Vector Quantizer 1 @tab X @tab X - @tab fourcc: SVQ1 -@item Sorenson Vector Quantizer 3 @tab @tab X - @tab fourcc: SVQ3 -@item Sunplus JPEG (SP5X) @tab @tab X - @tab fourcc: SP5X -@item TechSmith Screen Capture Codec @tab @tab X - @tab fourcc: TSCC -@item TechSmith Screen Capture Codec 2 @tab @tab X - @tab fourcc: TSC2 -@item Theora @tab E @tab X - @tab encoding supported through external library libtheora -@item Tiertex Limited SEQ video @tab @tab X - @tab Codec used in DOS CD-ROM FlashBack game. -@item Ut Video @tab X @tab X -@item v210 QuickTime uncompressed 4:2:2 10-bit @tab X @tab X -@item v308 QuickTime uncompressed 4:4:4 @tab X @tab X -@item v408 QuickTime uncompressed 4:4:4:4 @tab X @tab X -@item v410 QuickTime uncompressed 4:4:4 10-bit @tab X @tab X -@item VBLE Lossless Codec @tab @tab X -@item VMware Screen Codec / VMware Video @tab @tab X - @tab Codec used in videos captured by VMware. -@item Westwood Studios VQA (Vector Quantized Animation) video @tab @tab X -@item Windows Media Image @tab @tab X -@item Windows Media Video 7 @tab X @tab X -@item Windows Media Video 8 @tab X @tab X -@item Windows Media Video 9 @tab @tab X - @tab not completely working -@item Wing Commander III / Xan @tab @tab X - @tab Used in Wing Commander III .MVE files. -@item Wing Commander IV / Xan @tab @tab X - @tab Used in Wing Commander IV. -@item Winnov WNV1 @tab @tab X -@item WMV7 @tab X @tab X -@item YAMAHA SMAF @tab X @tab X -@item Psygnosis YOP Video @tab @tab X -@item yuv4 @tab X @tab X - @tab libquicktime uncompressed packed 4:2:0 -@item ZeroCodec Lossless Video @tab @tab X -@item ZLIB @tab X @tab X - @tab part of LCL, encoder experimental -@item Zip Motion Blocks Video @tab X @tab X - @tab Encoder works only in PAL8. -@end multitable - -@code{X} means that the feature in that column (encoding / decoding) is supported. - -@code{E} means that support is provided through an external library. - -@section Audio Codecs - -@multitable @columnfractions .4 .1 .1 .4 -@item Name @tab Encoding @tab Decoding @tab Comments -@item 8SVX exponential @tab @tab X -@item 8SVX fibonacci @tab @tab X -@item AAC @tab EX @tab X - @tab encoding supported through internal encoder and external library libfdk-aac -@item AAC+ @tab E @tab IX - @tab encoding supported through external library libfdk-aac -@item AC-3 @tab IX @tab IX -@item ACELP.KELVIN @tab @tab X -@item ADPCM 4X Movie @tab @tab X -@item APDCM Yamaha AICA @tab @tab X -@item ADPCM Argonaut Games @tab @tab X -@item ADPCM CDROM XA @tab @tab X -@item ADPCM Creative Technology @tab @tab X - @tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2 -@item ADPCM Electronic Arts @tab @tab X - @tab Used in various EA titles. -@item ADPCM Electronic Arts Maxis CDROM XS @tab @tab X - @tab Used in Sim City 3000. -@item ADPCM Electronic Arts R1 @tab @tab X -@item ADPCM Electronic Arts R2 @tab @tab X -@item ADPCM Electronic Arts R3 @tab @tab X -@item ADPCM Electronic Arts XAS @tab @tab X -@item ADPCM G.722 @tab X @tab X -@item ADPCM G.726 @tab X @tab X -@item ADPCM IMA AMV @tab @tab X - @tab Used in AMV files -@item ADPCM IMA Cunning Developments @tab @tab X -@item ADPCM IMA Electronic Arts EACS @tab @tab X -@item ADPCM IMA Electronic Arts SEAD @tab @tab X -@item ADPCM IMA Funcom @tab @tab X -@item ADPCM IMA High Voltage Software ALP @tab @tab X -@item ADPCM IMA QuickTime @tab X @tab X -@item ADPCM IMA Simon & Schuster Interactive @tab X @tab X -@item ADPCM IMA Ubisoft APM @tab @tab X -@item ADPCM IMA Loki SDL MJPEG @tab @tab X -@item ADPCM IMA WAV @tab X @tab X -@item ADPCM IMA Westwood @tab @tab X -@item ADPCM ISS IMA @tab @tab X - @tab Used in FunCom games. -@item ADPCM IMA Dialogic @tab @tab X -@item ADPCM IMA Duck DK3 @tab @tab X - @tab Used in some Sega Saturn console games. -@item ADPCM IMA Duck DK4 @tab @tab X - @tab Used in some Sega Saturn console games. -@item ADPCM IMA Radical @tab @tab X -@item ADPCM Microsoft @tab X @tab X -@item ADPCM MS IMA @tab X @tab X -@item ADPCM Nintendo Gamecube AFC @tab @tab X -@item ADPCM Nintendo Gamecube DTK @tab @tab X -@item ADPCM Nintendo THP @tab @tab X -@item APDCM Playstation @tab @tab X -@item ADPCM QT IMA @tab X @tab X -@item ADPCM SEGA CRI ADX @tab X @tab X - @tab Used in Sega Dreamcast games. -@item ADPCM Shockwave Flash @tab X @tab X -@item ADPCM Sound Blaster Pro 2-bit @tab @tab X -@item ADPCM Sound Blaster Pro 2.6-bit @tab @tab X -@item ADPCM Sound Blaster Pro 4-bit @tab @tab X -@item ADPCM VIMA @tab @tab X - @tab Used in LucasArts SMUSH animations. -@item ADPCM Westwood Studios IMA @tab @tab X - @tab Used in Westwood Studios games like Command and Conquer. -@item ADPCM Yamaha @tab X @tab X -@item ADPCM Zork @tab @tab X -@item AMR-NB @tab E @tab X - @tab encoding supported through external library libopencore-amrnb -@item AMR-WB @tab E @tab X - @tab encoding supported through external library libvo-amrwbenc -@item Amazing Studio PAF Audio @tab @tab X -@item Apple lossless audio @tab X @tab X - @tab QuickTime fourcc 'alac' -@item aptX @tab X @tab X - @tab Used in Bluetooth A2DP -@item aptX HD @tab X @tab X - @tab Used in Bluetooth A2DP -@item ATRAC1 @tab @tab X -@item ATRAC3 @tab @tab X -@item ATRAC3+ @tab @tab X -@item ATRAC9 @tab @tab X -@item Bink Audio @tab @tab X - @tab Used in Bink and Smacker files in many games. -@item CELT @tab @tab E - @tab decoding supported through external library libcelt -@item codec2 @tab E @tab E - @tab en/decoding supported through external library libcodec2 -@item CRI HCA @tab @tab X -@item Delphine Software International CIN audio @tab @tab X - @tab Codec used in Delphine Software International games. -@item Digital Speech Standard - Standard Play mode (DSS SP) @tab @tab X -@item Discworld II BMV Audio @tab @tab X -@item COOK @tab @tab X - @tab All versions except 5.1 are supported. -@item DCA (DTS Coherent Acoustics) @tab X @tab X - @tab supported extensions: XCh, XXCH, X96, XBR, XLL, LBR (partially) -@item Dolby E @tab @tab X -@item DPCM Gremlin @tab @tab X -@item DPCM id RoQ @tab X @tab X - @tab Used in Quake III, Jedi Knight 2 and other computer games. -@item DPCM Interplay @tab @tab X - @tab Used in various Interplay computer games. -@item DPCM Squareroot-Delta-Exact @tab @tab X - @tab Used in various games. -@item DPCM Sierra Online @tab @tab X - @tab Used in Sierra Online game audio files. -@item DPCM Sol @tab @tab X -@item DPCM Xan @tab @tab X - @tab Used in Origin's Wing Commander IV AVI files. -@item DPCM Xilam DERF @tab @tab X -@item DSD (Direct Stream Digital), least significant bit first @tab @tab X -@item DSD (Direct Stream Digital), most significant bit first @tab @tab X -@item DSD (Direct Stream Digital), least significant bit first, planar @tab @tab X -@item DSD (Direct Stream Digital), most significant bit first, planar @tab @tab X -@item DSP Group TrueSpeech @tab @tab X -@item DST (Direct Stream Transfer) @tab @tab X -@item DV audio @tab @tab X -@item Enhanced AC-3 @tab X @tab X -@item EVRC (Enhanced Variable Rate Codec) @tab @tab X -@item FLAC (Free Lossless Audio Codec) @tab X @tab IX -@item G.723.1 @tab X @tab X -@item G.729 @tab @tab X -@item GSM @tab E @tab X - @tab encoding supported through external library libgsm -@item GSM Microsoft variant @tab E @tab X - @tab encoding supported through external library libgsm -@item IAC (Indeo Audio Coder) @tab @tab X -@item iLBC (Internet Low Bitrate Codec) @tab E @tab E - @tab encoding and decoding supported through external library libilbc -@item IMC (Intel Music Coder) @tab @tab X -@item Interplay ACM @tab @tab X -@item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X -@item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X -@item MLP (Meridian Lossless Packing) @tab X @tab X - @tab Used in DVD-Audio discs. -@item Monkey's Audio @tab @tab X -@item MP1 (MPEG audio layer 1) @tab @tab IX -@item MP2 (MPEG audio layer 2) @tab IX @tab IX - @tab encoding supported also through external library TwoLAME -@item MP3 (MPEG audio layer 3) @tab E @tab IX - @tab encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported -@item MPEG-4 Audio Lossless Coding (ALS) @tab @tab X -@item Musepack SV7 @tab @tab X -@item Musepack SV8 @tab @tab X -@item Nellymoser Asao @tab X @tab X -@item On2 AVC (Audio for Video Codec) @tab @tab X -@item Opus @tab E @tab X - @tab encoding supported through external library libopus -@item PCM A-law @tab X @tab X -@item PCM mu-law @tab X @tab X -@item PCM Archimedes VIDC @tab X @tab X -@item PCM signed 8-bit planar @tab X @tab X -@item PCM signed 16-bit big-endian planar @tab X @tab X -@item PCM signed 16-bit little-endian planar @tab X @tab X -@item PCM signed 24-bit little-endian planar @tab X @tab X -@item PCM signed 32-bit little-endian planar @tab X @tab X -@item PCM 32-bit floating point big-endian @tab X @tab X -@item PCM 32-bit floating point little-endian @tab X @tab X -@item PCM 64-bit floating point big-endian @tab X @tab X -@item PCM 64-bit floating point little-endian @tab X @tab X -@item PCM D-Cinema audio signed 24-bit @tab X @tab X -@item PCM signed 8-bit @tab X @tab X -@item PCM signed 16-bit big-endian @tab X @tab X -@item PCM signed 16-bit little-endian @tab X @tab X -@item PCM signed 24-bit big-endian @tab X @tab X -@item PCM signed 24-bit little-endian @tab X @tab X -@item PCM signed 32-bit big-endian @tab X @tab X -@item PCM signed 32-bit little-endian @tab X @tab X -@item PCM signed 16/20/24-bit big-endian in MPEG-TS @tab @tab X -@item PCM unsigned 8-bit @tab X @tab X -@item PCM unsigned 16-bit big-endian @tab X @tab X -@item PCM unsigned 16-bit little-endian @tab X @tab X -@item PCM unsigned 24-bit big-endian @tab X @tab X -@item PCM unsigned 24-bit little-endian @tab X @tab X -@item PCM unsigned 32-bit big-endian @tab X @tab X -@item PCM unsigned 32-bit little-endian @tab X @tab X -@item QCELP / PureVoice @tab @tab X -@item QDesign Music Codec 1 @tab @tab X -@item QDesign Music Codec 2 @tab @tab X - @tab There are still some distortions. -@item RealAudio 1.0 (14.4K) @tab X @tab X - @tab Real 14400 bit/s codec -@item RealAudio 2.0 (28.8K) @tab @tab X - @tab Real 28800 bit/s codec -@item RealAudio 3.0 (dnet) @tab IX @tab X - @tab Real low bitrate AC-3 codec -@item RealAudio Lossless @tab @tab X -@item RealAudio SIPR / ACELP.NET @tab @tab X -@item SBC (low-complexity subband codec) @tab X @tab X - @tab Used in Bluetooth A2DP -@item Shorten @tab @tab X -@item Sierra VMD audio @tab @tab X - @tab Used in Sierra VMD files. -@item Smacker audio @tab @tab X -@item SMPTE 302M AES3 audio @tab X @tab X -@item Sonic @tab X @tab X - @tab experimental codec -@item Sonic lossless @tab X @tab X - @tab experimental codec -@item Speex @tab E @tab E - @tab supported through external library libspeex -@item TAK (Tom's lossless Audio Kompressor) @tab @tab X -@item True Audio (TTA) @tab X @tab X -@item TrueHD @tab X @tab X - @tab Used in HD-DVD and Blu-Ray discs. -@item TwinVQ (VQF flavor) @tab @tab X -@item VIMA @tab @tab X - @tab Used in LucasArts SMUSH animations. -@item Vorbis @tab E @tab X - @tab A native but very primitive encoder exists. -@item Voxware MetaSound @tab @tab X -@item WavPack @tab X @tab X -@item Westwood Audio (SND1) @tab @tab X -@item Windows Media Audio 1 @tab X @tab X -@item Windows Media Audio 2 @tab X @tab X -@item Windows Media Audio Lossless @tab @tab X -@item Windows Media Audio Pro @tab @tab X -@item Windows Media Audio Voice @tab @tab X -@item Xbox Media Audio 1 @tab @tab X -@item Xbox Media Audio 2 @tab @tab X -@end multitable - -@code{X} means that the feature in that column (encoding / decoding) is supported. - -@code{E} means that support is provided through an external library. - -@code{I} means that an integer-only version is available, too (ensures high -performance on systems without hardware floating point support). - -@section Subtitle Formats - -@multitable @columnfractions .4 .1 .1 .1 .1 -@item Name @tab Muxing @tab Demuxing @tab Encoding @tab Decoding -@item 3GPP Timed Text @tab @tab @tab X @tab X -@item AQTitle @tab @tab X @tab @tab X -@item DVB @tab X @tab X @tab X @tab X -@item DVB teletext @tab @tab X @tab @tab E -@item DVD @tab X @tab X @tab X @tab X -@item JACOsub @tab X @tab X @tab @tab X -@item MicroDVD @tab X @tab X @tab @tab X -@item MPL2 @tab @tab X @tab @tab X -@item MPsub (MPlayer) @tab @tab X @tab @tab X -@item PGS @tab @tab @tab @tab X -@item PJS (Phoenix) @tab @tab X @tab @tab X -@item RealText @tab @tab X @tab @tab X -@item SAMI @tab @tab X @tab @tab X -@item Spruce format (STL) @tab @tab X @tab @tab X -@item SSA/ASS @tab X @tab X @tab X @tab X -@item SubRip (SRT) @tab X @tab X @tab X @tab X -@item SubViewer v1 @tab @tab X @tab @tab X -@item SubViewer @tab @tab X @tab @tab X -@item TED Talks captions @tab @tab X @tab @tab X -@item VobSub (IDX+SUB) @tab @tab X @tab @tab X -@item VPlayer @tab @tab X @tab @tab X -@item WebVTT @tab X @tab X @tab X @tab X -@item XSUB @tab @tab @tab X @tab X -@end multitable - -@code{X} means that the feature is supported. - -@code{E} means that support is provided through an external library. - -@section Network Protocols - -@multitable @columnfractions .4 .1 -@item Name @tab Support -@item AMQP @tab E -@item file @tab X -@item FTP @tab X -@item Gopher @tab X -@item HLS @tab X -@item HTTP @tab X -@item HTTPS @tab X -@item Icecast @tab X -@item MMSH @tab X -@item MMST @tab X -@item pipe @tab X -@item Pro-MPEG FEC @tab X -@item RTMP @tab X -@item RTMPE @tab X -@item RTMPS @tab X -@item RTMPT @tab X -@item RTMPTE @tab X -@item RTMPTS @tab X -@item RTP @tab X -@item SAMBA @tab E -@item SCTP @tab X -@item SFTP @tab E -@item TCP @tab X -@item TLS @tab X -@item UDP @tab X -@item ZMQ @tab E -@end multitable - -@code{X} means that the protocol is supported. - -@code{E} means that support is provided through an external library. - - -@section Input/Output Devices - -@multitable @columnfractions .4 .1 .1 -@item Name @tab Input @tab Output -@item ALSA @tab X @tab X -@item BKTR @tab X @tab -@item caca @tab @tab X -@item DV1394 @tab X @tab -@item Lavfi virtual device @tab X @tab -@item Linux framebuffer @tab X @tab X -@item JACK @tab X @tab -@item LIBCDIO @tab X -@item LIBDC1394 @tab X @tab -@item OpenAL @tab X -@item OpenGL @tab @tab X -@item OSS @tab X @tab X -@item PulseAudio @tab X @tab X -@item SDL @tab @tab X -@item Video4Linux2 @tab X @tab X -@item VfW capture @tab X @tab -@item X11 grabbing @tab X @tab -@item Win32 grabbing @tab X @tab -@end multitable - -@code{X} means that input/output is supported. - -@section Timecode - -@multitable @columnfractions .4 .1 .1 -@item Codec/format @tab Read @tab Write -@item AVI @tab X @tab X -@item DV @tab X @tab X -@item GXF @tab X @tab X -@item MOV @tab X @tab X -@item MPEG1/2 @tab X @tab X -@item MXF @tab X @tab X -@end multitable +@include general_contents.texi @bye diff --git a/doc/general_contents.texi b/doc/general_contents.texi new file mode 100644 index 000000000..33ece6e88 --- /dev/null +++ b/doc/general_contents.texi @@ -0,0 +1,1440 @@ +@chapter External libraries + +FFmpeg can be hooked up with a number of external libraries to add support +for more formats. None of them are used by default, their use has to be +explicitly requested by passing the appropriate flags to +@command{./configure}. + +@section Alliance for Open Media (AOM) + +FFmpeg can make use of the AOM library for AV1 decoding and encoding. + +Go to @url{http://aomedia.org/} and follow the instructions for +installing the library. Then pass @code{--enable-libaom} to configure to +enable it. + +@section AMD AMF/VCE + +FFmpeg can use the AMD Advanced Media Framework library +for accelerated H.264 and HEVC(only windows) encoding on hardware with Video Coding Engine (VCE). + +To enable support you must obtain the AMF framework header files(version 1.4.9+) from +@url{https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git}. + +Create an @code{AMF/} directory in the system include path. +Copy the contents of @code{AMF/amf/public/include/} into that directory. +Then configure FFmpeg with @code{--enable-amf}. + +Initialization of amf encoder occurs in this order: +1) trying to initialize through dx11(only windows) +2) trying to initialize through dx9(only windows) +3) trying to initialize through vulkan + +To use h.264(AMD VCE) encoder on linux amdgru-pro version 19.20+ and amf-amdgpu-pro +package(amdgru-pro contains, but does not install automatically) are required. + +This driver can be installed using amdgpu-pro-install script in official amd driver archive. + +@section AviSynth + +FFmpeg can read AviSynth scripts as input. To enable support, pass +@code{--enable-avisynth} to configure after installing the headers +provided by @url{https://github.com/AviSynth/AviSynthPlus, AviSynth+}. +AviSynth+ can be configured to install only the headers by either +passing @code{-DHEADERS_ONLY:bool=on} to the normal CMake-based build +system, or by using the supplied @code{GNUmakefile}. + +For Windows, supported AviSynth variants are +@url{http://avisynth.nl, AviSynth 2.6 RC1 or higher} for 32-bit builds and +@url{http://avisynth.nl/index.php/AviSynth+, AviSynth+ r1718 or higher} for 32-bit and 64-bit builds. + +For Linux, macOS, and BSD, the only supported AviSynth variant is +@url{https://github.com/AviSynth/AviSynthPlus, AviSynth+}, starting with version 3.5. + +@float NOTE +In 2016, AviSynth+ added support for building with GCC. However, due to +the eccentricities of Windows' calling conventions, 32-bit GCC builds +of AviSynth+ are not compatible with typical 32-bit builds of FFmpeg. + +By default, FFmpeg assumes compatibility with 32-bit MSVC builds of +AviSynth+ since that is the most widely-used and entrenched build +configuration. Users can override this and enable support for 32-bit +GCC builds of AviSynth+ by passing @code{-DAVSC_WIN32_GCC32} to +@code{--extra-cflags} when configuring FFmpeg. + +64-bit builds of FFmpeg are not affected, and can use either MSVC or +GCC builds of AviSynth+ without any special flags. +@end float + +@float NOTE +AviSynth(+) is loaded dynamically. Distributors can build FFmpeg +with @code{--enable-avisynth}, and the binaries will work regardless +of the end user having AviSynth installed. If/when an end user +would like to use AviSynth scripts, then they can install AviSynth(+) +and FFmpeg will be able to find and use it to open scripts. +@end float + +@section Chromaprint + +FFmpeg can make use of the Chromaprint library for generating audio fingerprints. +Pass @code{--enable-chromaprint} to configure to +enable it. See @url{https://acoustid.org/chromaprint}. + +@section codec2 + +FFmpeg can make use of the codec2 library for codec2 decoding and encoding. +There is currently no native decoder, so libcodec2 must be used for decoding. + +Go to @url{http://freedv.org/}, download "Codec 2 source archive". +Build and install using CMake. Debian users can install the libcodec2-dev package instead. +Once libcodec2 is installed you can pass @code{--enable-libcodec2} to configure to enable it. + +The easiest way to use codec2 is with .c2 files, since they contain the mode information required for decoding. +To encode such a file, use a .c2 file extension and give the libcodec2 encoder the -mode option: +@code{ffmpeg -i input.wav -mode 700C output.c2}. +Playback is as simple as @code{ffplay output.c2}. +For a list of supported modes, run @code{ffmpeg -h encoder=libcodec2}. +Raw codec2 files are also supported. +To make sense of them the mode in use needs to be specified as a format option: +@code{ffmpeg -f codec2raw -mode 1300 -i input.raw output.wav}. + +@section dav1d + +FFmpeg can make use of the dav1d library for AV1 video decoding. + +Go to @url{https://code.videolan.org/videolan/dav1d} and follow the instructions for +installing the library. Then pass @code{--enable-libdav1d} to configure to enable it. + +@section davs2 + +FFmpeg can make use of the davs2 library for AVS2-P2/IEEE1857.4 video decoding. + +Go to @url{https://github.com/pkuvcl/davs2} and follow the instructions for +installing the library. Then pass @code{--enable-libdavs2} to configure to +enable it. + +@float NOTE +libdavs2 is under the GNU Public License Version 2 or later +(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for +details), you must upgrade FFmpeg's license to GPL in order to use it. +@end float + +@section uavs3d + +FFmpeg can make use of the uavs3d library for AVS3-P2/IEEE1857.10 video decoding. + +Go to @url{https://github.com/uavs3/uavs3d} and follow the instructions for +installing the library. Then pass @code{--enable-libuavs3d} to configure to +enable it. + +@section Game Music Emu + +FFmpeg can make use of the Game Music Emu library to read audio from supported video game +music file formats. Pass @code{--enable-libgme} to configure to +enable it. See @url{https://bitbucket.org/mpyne/game-music-emu/overview}. + +@section Intel QuickSync Video + +FFmpeg can use Intel QuickSync Video (QSV) for accelerated decoding and encoding +of multiple codecs. To use QSV, FFmpeg must be linked against the @code{libmfx} +dispatcher, which loads the actual decoding libraries. + +The dispatcher is open source and can be downloaded from +@url{https://github.com/lu-zero/mfx_dispatch.git}. FFmpeg needs to be configured +with the @code{--enable-libmfx} option and @code{pkg-config} needs to be able to +locate the dispatcher's @code{.pc} files. + +@section Kvazaar + +FFmpeg can make use of the Kvazaar library for HEVC encoding. + +Go to @url{https://github.com/ultravideo/kvazaar} and follow the +instructions for installing the library. Then pass +@code{--enable-libkvazaar} to configure to enable it. + +@section LAME + +FFmpeg can make use of the LAME library for MP3 encoding. + +Go to @url{http://lame.sourceforge.net/} and follow the +instructions for installing the library. +Then pass @code{--enable-libmp3lame} to configure to enable it. + +@section libilbc + +iLBC is a narrowband speech codec that has been made freely available +by Google as part of the WebRTC project. libilbc is a packaging friendly +copy of the iLBC codec. FFmpeg can make use of the libilbc library for +iLBC decoding and encoding. + +Go to @url{https://github.com/TimothyGu/libilbc} and follow the instructions for +installing the library. Then pass @code{--enable-libilbc} to configure to +enable it. + +@section libvpx + +FFmpeg can make use of the libvpx library for VP8/VP9 decoding and encoding. + +Go to @url{http://www.webmproject.org/} and follow the instructions for +installing the library. Then pass @code{--enable-libvpx} to configure to +enable it. + +@section ModPlug + +FFmpeg can make use of this library, originating in Modplug-XMMS, to read from MOD-like music files. +See @url{https://github.com/Konstanty/libmodplug}. Pass @code{--enable-libmodplug} to configure to +enable it. + +@section OpenCORE, VisualOn, and Fraunhofer libraries + +Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer +libraries provide encoders for a number of audio codecs. + +@float NOTE +OpenCORE and VisualOn libraries are under the Apache License 2.0 +(see @url{http://www.apache.org/licenses/LICENSE-2.0} for details), which is +incompatible to the LGPL version 2.1 and GPL version 2. You have to +upgrade FFmpeg's license to LGPL version 3 (or if you have enabled +GPL components, GPL version 3) by passing @code{--enable-version3} to configure in +order to use it. + +The license of the Fraunhofer AAC library is incompatible with the GPL. +Therefore, for GPL builds, you have to pass @code{--enable-nonfree} to +configure in order to use it. To the best of our knowledge, it is +compatible with the LGPL. +@end float + +@subsection OpenCORE AMR + +FFmpeg can make use of the OpenCORE libraries for AMR-NB +decoding/encoding and AMR-WB decoding. + +Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the +instructions for installing the libraries. +Then pass @code{--enable-libopencore-amrnb} and/or +@code{--enable-libopencore-amrwb} to configure to enable them. + +@subsection VisualOn AMR-WB encoder library + +FFmpeg can make use of the VisualOn AMR-WBenc library for AMR-WB encoding. + +Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the +instructions for installing the library. +Then pass @code{--enable-libvo-amrwbenc} to configure to enable it. + +@subsection Fraunhofer AAC library + +FFmpeg can make use of the Fraunhofer AAC library for AAC decoding & encoding. + +Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the +instructions for installing the library. +Then pass @code{--enable-libfdk-aac} to configure to enable it. + +@section OpenH264 + +FFmpeg can make use of the OpenH264 library for H.264 decoding and encoding. + +Go to @url{http://www.openh264.org/} and follow the instructions for +installing the library. Then pass @code{--enable-libopenh264} to configure to +enable it. + +For decoding, this library is much more limited than the built-in decoder +in libavcodec; currently, this library lacks support for decoding B-frames +and some other main/high profile features. (It currently only supports +constrained baseline profile and CABAC.) Using it is mostly useful for +testing and for taking advantage of Cisco's patent portfolio license +(@url{http://www.openh264.org/BINARY_LICENSE.txt}). + +@section OpenJPEG + +FFmpeg can use the OpenJPEG libraries for decoding/encoding J2K videos. Go to +@url{http://www.openjpeg.org/} to get the libraries and follow the installation +instructions. To enable using OpenJPEG in FFmpeg, pass @code{--enable-libopenjpeg} to +@file{./configure}. + +@section rav1e + +FFmpeg can make use of rav1e (Rust AV1 Encoder) via its C bindings to encode videos. +Go to @url{https://github.com/xiph/rav1e/} and follow the instructions to build +the C library. To enable using rav1e in FFmpeg, pass @code{--enable-librav1e} +to @file{./configure}. + +@section SVT-AV1 + +FFmpeg can make use of the Scalable Video Technology for AV1 library for AV1 encoding. + +Go to @url{https://github.com/OpenVisualCloud/SVT-AV1/} and follow the instructions +for installing the library. Then pass @code{--enable-libsvtav1} to configure to +enable it. + +@section TwoLAME + +FFmpeg can make use of the TwoLAME library for MP2 encoding. + +Go to @url{http://www.twolame.org/} and follow the +instructions for installing the library. +Then pass @code{--enable-libtwolame} to configure to enable it. + +@section VapourSynth + +FFmpeg can read VapourSynth scripts as input. To enable support, pass +@code{--enable-vapoursynth} to configure. Vapoursynth is detected via +@code{pkg-config}. Versions 42 or greater supported. +See @url{http://www.vapoursynth.com/}. + +Due to security concerns, Vapoursynth scripts will not +be autodetected so the input format has to be forced. For ff* CLI tools, +add @code{-f vapoursynth} before the input @code{-i yourscript.vpy}. + +@section x264 + +FFmpeg can make use of the x264 library for H.264 encoding. + +Go to @url{http://www.videolan.org/developers/x264.html} and follow the +instructions for installing the library. Then pass @code{--enable-libx264} to +configure to enable it. + +@float NOTE +x264 is under the GNU Public License Version 2 or later +(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for +details), you must upgrade FFmpeg's license to GPL in order to use it. +@end float + +@section x265 + +FFmpeg can make use of the x265 library for HEVC encoding. + +Go to @url{http://x265.org/developers.html} and follow the instructions +for installing the library. Then pass @code{--enable-libx265} to configure +to enable it. + +@float NOTE +x265 is under the GNU Public License Version 2 or later +(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for +details), you must upgrade FFmpeg's license to GPL in order to use it. +@end float + +@section xavs + +FFmpeg can make use of the xavs library for AVS encoding. + +Go to @url{http://xavs.sf.net/} and follow the instructions for +installing the library. Then pass @code{--enable-libxavs} to configure to +enable it. + +@section xavs2 + +FFmpeg can make use of the xavs2 library for AVS2-P2/IEEE1857.4 video encoding. + +Go to @url{https://github.com/pkuvcl/xavs2} and follow the instructions for +installing the library. Then pass @code{--enable-libxavs2} to configure to +enable it. + +@float NOTE +libxavs2 is under the GNU Public License Version 2 or later +(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for +details), you must upgrade FFmpeg's license to GPL in order to use it. +@end float + +@section ZVBI + +ZVBI is a VBI decoding library which can be used by FFmpeg to decode DVB +teletext pages and DVB teletext subtitles. + +Go to @url{http://sourceforge.net/projects/zapping/} and follow the instructions for +installing the library. Then pass @code{--enable-libzvbi} to configure to +enable it. + +@chapter Supported File Formats, Codecs or Features + +You can use the @code{-formats} and @code{-codecs} options to have an exhaustive list. + +@section File Formats + +FFmpeg supports the following file formats through the @code{libavformat} +library: + +@multitable @columnfractions .4 .1 .1 .4 +@item Name @tab Encoding @tab Decoding @tab Comments +@item 3dostr @tab @tab X +@item 4xm @tab @tab X + @tab 4X Technologies format, used in some games. +@item 8088flex TMV @tab @tab X +@item AAX @tab @tab X + @tab Audible Enhanced Audio format, used in audiobooks. +@item AA @tab @tab X + @tab Audible Format 2, 3, and 4, used in audiobooks. +@item ACT Voice @tab @tab X + @tab contains G.729 audio +@item Adobe Filmstrip @tab X @tab X +@item Audio IFF (AIFF) @tab X @tab X +@item American Laser Games MM @tab @tab X + @tab Multimedia format used in games like Mad Dog McCree. +@item 3GPP AMR @tab X @tab X +@item Amazing Studio Packed Animation File @tab @tab X + @tab Multimedia format used in game Heart Of Darkness. +@item Apple HTTP Live Streaming @tab @tab X +@item Artworx Data Format @tab @tab X +@item Interplay ACM @tab @tab X + @tab Audio only format used in some Interplay games. +@item ADP @tab @tab X + @tab Audio format used on the Nintendo Gamecube. +@item AFC @tab @tab X + @tab Audio format used on the Nintendo Gamecube. +@item ADS/SS2 @tab @tab X + @tab Audio format used on the PS2. +@item APNG @tab X @tab X +@item ASF @tab X @tab X + @tab Advanced / Active Streaming Format. +@item AST @tab X @tab X + @tab Audio format used on the Nintendo Wii. +@item AVI @tab X @tab X +@item AviSynth @tab @tab X +@item AVR @tab @tab X + @tab Audio format used on Mac. +@item AVS @tab @tab X + @tab Multimedia format used by the Creature Shock game. +@item Beam Software SIFF @tab @tab X + @tab Audio and video format used in some games by Beam Software. +@item Bethesda Softworks VID @tab @tab X + @tab Used in some games from Bethesda Softworks. +@item Binary text @tab @tab X +@item Bink @tab @tab X + @tab Multimedia format used by many games. +@item Bink Audio @tab @tab X + @tab Audio only multimedia format used by some games. +@item Bitmap Brothers JV @tab @tab X + @tab Used in Z and Z95 games. +@item BRP @tab @tab X + @tab Argonaut Games format. +@item Brute Force & Ignorance @tab @tab X + @tab Used in the game Flash Traffic: City of Angels. +@item BFSTM @tab @tab X + @tab Audio format used on the Nintendo WiiU (based on BRSTM). +@item BRSTM @tab @tab X + @tab Audio format used on the Nintendo Wii. +@item BW64 @tab @tab X + @tab Broadcast Wave 64bit. +@item BWF @tab X @tab X +@item codec2 (raw) @tab X @tab X + @tab Must be given -mode format option to decode correctly. +@item codec2 (.c2 files) @tab X @tab X + @tab Contains header with version and mode info, simplifying playback. +@item CRI ADX @tab X @tab X + @tab Audio-only format used in console video games. +@item CRI AIX @tab @tab X +@item CRI HCA @tab @tab X + @tab Audio-only format used in console video games. +@item Discworld II BMV @tab @tab X +@item Interplay C93 @tab @tab X + @tab Used in the game Cyberia from Interplay. +@item Delphine Software International CIN @tab @tab X + @tab Multimedia format used by Delphine Software games. +@item Digital Speech Standard (DSS) @tab @tab X +@item CD+G @tab @tab X + @tab Video format used by CD+G karaoke disks +@item Phantom Cine @tab @tab X +@item Commodore CDXL @tab @tab X + @tab Amiga CD video format +@item Core Audio Format @tab X @tab X + @tab Apple Core Audio Format +@item CRC testing format @tab X @tab +@item Creative Voice @tab X @tab X + @tab Created for the Sound Blaster Pro. +@item CRYO APC @tab @tab X + @tab Audio format used in some games by CRYO Interactive Entertainment. +@item D-Cinema audio @tab X @tab X +@item Deluxe Paint Animation @tab @tab X +@item DCSTR @tab @tab X +@item DFA @tab @tab X + @tab This format is used in Chronomaster game +@item DirectDraw Surface @tab @tab X +@item DSD Stream File (DSF) @tab @tab X +@item DV video @tab X @tab X +@item DXA @tab @tab X + @tab This format is used in the non-Windows version of the Feeble Files + game and different game cutscenes repacked for use with ScummVM. +@item Electronic Arts cdata @tab @tab X +@item Electronic Arts Multimedia @tab @tab X + @tab Used in various EA games; files have extensions like WVE and UV2. +@item Ensoniq Paris Audio File @tab @tab X +@item FFM (FFserver live feed) @tab X @tab X +@item Flash (SWF) @tab X @tab X +@item Flash 9 (AVM2) @tab X @tab X + @tab Only embedded audio is decoded. +@item FLI/FLC/FLX animation @tab @tab X + @tab .fli/.flc files +@item Flash Video (FLV) @tab X @tab X + @tab Macromedia Flash video files +@item framecrc testing format @tab X @tab +@item FunCom ISS @tab @tab X + @tab Audio format used in various games from FunCom like The Longest Journey. +@item G.723.1 @tab X @tab X +@item G.726 @tab @tab X @tab Both left- and right-justified. +@item G.729 BIT @tab X @tab X +@item G.729 raw @tab @tab X +@item GENH @tab @tab X + @tab Audio format for various games. +@item GIF Animation @tab X @tab X +@item GXF @tab X @tab X + @tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley + playout servers. +@item HNM @tab @tab X + @tab Only version 4 supported, used in some games from Cryo Interactive +@item iCEDraw File @tab @tab X +@item ICO @tab X @tab X + @tab Microsoft Windows ICO +@item id Quake II CIN video @tab @tab X +@item id RoQ @tab X @tab X + @tab Used in Quake III, Jedi Knight 2 and other computer games. +@item IEC61937 encapsulation @tab X @tab X +@item IFF @tab @tab X + @tab Interchange File Format +@item IFV @tab @tab X + @tab A format used by some old CCTV DVRs. +@item iLBC @tab X @tab X +@item Interplay MVE @tab @tab X + @tab Format used in various Interplay computer games. +@item Iterated Systems ClearVideo @tab @tab X + @tab I-frames only +@item IV8 @tab @tab X + @tab A format generated by IndigoVision 8000 video server. +@item IVF (On2) @tab X @tab X + @tab A format used by libvpx +@item Internet Video Recording @tab @tab X +@item IRCAM @tab X @tab X +@item LATM @tab X @tab X +@item LMLM4 @tab @tab X + @tab Used by Linux Media Labs MPEG-4 PCI boards +@item LOAS @tab @tab X + @tab contains LATM multiplexed AAC audio +@item LRC @tab X @tab X +@item LVF @tab @tab X +@item LXF @tab @tab X + @tab VR native stream format, used by Leitch/Harris' video servers. +@item Magic Lantern Video (MLV) @tab @tab X +@item Matroska @tab X @tab X +@item Matroska audio @tab X @tab +@item FFmpeg metadata @tab X @tab X + @tab Metadata in text format. +@item MAXIS XA @tab @tab X + @tab Used in Sim City 3000; file extension .xa. +@item MCA @tab @tab X + @tab Used in some games from Capcom; file extension .mca. +@item MD Studio @tab @tab X +@item Metal Gear Solid: The Twin Snakes @tab @tab X +@item Megalux Frame @tab @tab X + @tab Used by Megalux Ultimate Paint +@item Mobotix .mxg @tab @tab X +@item Monkey's Audio @tab @tab X +@item Motion Pixels MVI @tab @tab X +@item MOV/QuickTime/MP4 @tab X @tab X + @tab 3GP, 3GP2, PSP, iPod variants supported +@item MP2 @tab X @tab X +@item MP3 @tab X @tab X +@item MPEG-1 System @tab X @tab X + @tab muxed audio and video, VCD format supported +@item MPEG-PS (program stream) @tab X @tab X + @tab also known as @code{VOB} file, SVCD and DVD format supported +@item MPEG-TS (transport stream) @tab X @tab X + @tab also known as DVB Transport Stream +@item MPEG-4 @tab X @tab X + @tab MPEG-4 is a variant of QuickTime. +@item MSF @tab @tab X + @tab Audio format used on the PS3. +@item Mirillis FIC video @tab @tab X + @tab No cursor rendering. +@item MIDI Sample Dump Standard @tab @tab X +@item MIME multipart JPEG @tab X @tab +@item MSN TCP webcam @tab @tab X + @tab Used by MSN Messenger webcam streams. +@item MTV @tab @tab X +@item Musepack @tab @tab X +@item Musepack SV8 @tab @tab X +@item Material eXchange Format (MXF) @tab X @tab X + @tab SMPTE 377M, used by D-Cinema, broadcast industry. +@item Material eXchange Format (MXF), D-10 Mapping @tab X @tab X + @tab SMPTE 386M, D-10/IMX Mapping. +@item NC camera feed @tab @tab X + @tab NC (AVIP NC4600) camera streams +@item NIST SPeech HEader REsources @tab @tab X +@item Computerized Speech Lab NSP @tab @tab X +@item NTT TwinVQ (VQF) @tab @tab X + @tab Nippon Telegraph and Telephone Corporation TwinVQ. +@item Nullsoft Streaming Video @tab @tab X +@item NuppelVideo @tab @tab X +@item NUT @tab X @tab X + @tab NUT Open Container Format +@item Ogg @tab X @tab X +@item Playstation Portable PMP @tab @tab X +@item Portable Voice Format @tab @tab X +@item TechnoTrend PVA @tab @tab X + @tab Used by TechnoTrend DVB PCI boards. +@item QCP @tab @tab X +@item raw ADTS (AAC) @tab X @tab X +@item raw AC-3 @tab X @tab X +@item raw AMR-NB @tab @tab X +@item raw AMR-WB @tab @tab X +@item raw aptX @tab X @tab X +@item raw aptX HD @tab X @tab X +@item raw Chinese AVS video @tab X @tab X +@item raw Dirac @tab X @tab X +@item raw DNxHD @tab X @tab X +@item raw DTS @tab X @tab X +@item raw DTS-HD @tab @tab X +@item raw E-AC-3 @tab X @tab X +@item raw FLAC @tab X @tab X +@item raw GSM @tab @tab X +@item raw H.261 @tab X @tab X +@item raw H.263 @tab X @tab X +@item raw H.264 @tab X @tab X +@item raw HEVC @tab X @tab X +@item raw Ingenient MJPEG @tab @tab X +@item raw MJPEG @tab X @tab X +@item raw MLP @tab @tab X +@item raw MPEG @tab @tab X +@item raw MPEG-1 @tab @tab X +@item raw MPEG-2 @tab @tab X +@item raw MPEG-4 @tab X @tab X +@item raw NULL @tab X @tab +@item raw video @tab X @tab X +@item raw id RoQ @tab X @tab +@item raw SBC @tab X @tab X +@item raw Shorten @tab @tab X +@item raw TAK @tab @tab X +@item raw TrueHD @tab X @tab X +@item raw VC-1 @tab X @tab X +@item raw PCM A-law @tab X @tab X +@item raw PCM mu-law @tab X @tab X +@item raw PCM Archimedes VIDC @tab X @tab X +@item raw PCM signed 8 bit @tab X @tab X +@item raw PCM signed 16 bit big-endian @tab X @tab X +@item raw PCM signed 16 bit little-endian @tab X @tab X +@item raw PCM signed 24 bit big-endian @tab X @tab X +@item raw PCM signed 24 bit little-endian @tab X @tab X +@item raw PCM signed 32 bit big-endian @tab X @tab X +@item raw PCM signed 32 bit little-endian @tab X @tab X +@item raw PCM signed 64 bit big-endian @tab X @tab X +@item raw PCM signed 64 bit little-endian @tab X @tab X +@item raw PCM unsigned 8 bit @tab X @tab X +@item raw PCM unsigned 16 bit big-endian @tab X @tab X +@item raw PCM unsigned 16 bit little-endian @tab X @tab X +@item raw PCM unsigned 24 bit big-endian @tab X @tab X +@item raw PCM unsigned 24 bit little-endian @tab X @tab X +@item raw PCM unsigned 32 bit big-endian @tab X @tab X +@item raw PCM unsigned 32 bit little-endian @tab X @tab X +@item raw PCM 16.8 floating point little-endian @tab @tab X +@item raw PCM 24.0 floating point little-endian @tab @tab X +@item raw PCM floating-point 32 bit big-endian @tab X @tab X +@item raw PCM floating-point 32 bit little-endian @tab X @tab X +@item raw PCM floating-point 64 bit big-endian @tab X @tab X +@item raw PCM floating-point 64 bit little-endian @tab X @tab X +@item RDT @tab @tab X +@item REDCODE R3D @tab @tab X + @tab File format used by RED Digital cameras, contains JPEG 2000 frames and PCM audio. +@item RealMedia @tab X @tab X +@item Redirector @tab @tab X +@item RedSpark @tab @tab X +@item Renderware TeXture Dictionary @tab @tab X +@item Resolume DXV @tab @tab X +@item RF64 @tab @tab X +@item RL2 @tab @tab X + @tab Audio and video format used in some games by Entertainment Software Partners. +@item RPL/ARMovie @tab @tab X +@item Lego Mindstorms RSO @tab X @tab X +@item RSD @tab @tab X +@item RTMP @tab X @tab X + @tab Output is performed by publishing stream to RTMP server +@item RTP @tab X @tab X +@item RTSP @tab X @tab X +@item Sample Dump eXchange @tab @tab X +@item SAP @tab X @tab X +@item SBG @tab @tab X +@item SDP @tab @tab X +@item SER @tab @tab X +@item Sega FILM/CPK @tab X @tab X + @tab Used in many Sega Saturn console games. +@item Silicon Graphics Movie @tab @tab X +@item Sierra SOL @tab @tab X + @tab .sol files used in Sierra Online games. +@item Sierra VMD @tab @tab X + @tab Used in Sierra CD-ROM games. +@item Smacker @tab @tab X + @tab Multimedia format used by many games. +@item SMJPEG @tab X @tab X + @tab Used in certain Loki game ports. +@item SMPTE 337M encapsulation @tab @tab X +@item Smush @tab @tab X + @tab Multimedia format used in some LucasArts games. +@item Sony OpenMG (OMA) @tab X @tab X + @tab Audio format used in Sony Sonic Stage and Sony Vegas. +@item Sony PlayStation STR @tab @tab X +@item Sony Wave64 (W64) @tab X @tab X +@item SoX native format @tab X @tab X +@item SUN AU format @tab X @tab X +@item SUP raw PGS subtitles @tab X @tab X +@item SVAG @tab @tab X + @tab Audio format used in Konami PS2 games. +@item TDSC @tab @tab X +@item Text files @tab @tab X +@item THP @tab @tab X + @tab Used on the Nintendo GameCube. +@item Tiertex Limited SEQ @tab @tab X + @tab Tiertex .seq files used in the DOS CD-ROM version of the game Flashback. +@item True Audio @tab X @tab X +@item VAG @tab @tab X + @tab Audio format used in many Sony PS2 games. +@item VC-1 test bitstream @tab X @tab X +@item Vidvox Hap @tab X @tab X +@item Vivo @tab @tab X +@item VPK @tab @tab X + @tab Audio format used in Sony PS games. +@item WAV @tab X @tab X +@item WavPack @tab X @tab X +@item WebM @tab X @tab X +@item Windows Televison (WTV) @tab X @tab X +@item Wing Commander III movie @tab @tab X + @tab Multimedia format used in Origin's Wing Commander III computer game. +@item Westwood Studios audio @tab @tab X + @tab Multimedia format used in Westwood Studios games. +@item Westwood Studios VQA @tab @tab X + @tab Multimedia format used in Westwood Studios games. +@item Wideband Single-bit Data (WSD) @tab @tab X +@item WVE @tab @tab X +@item XMV @tab @tab X + @tab Microsoft video container used in Xbox games. +@item XVAG @tab @tab X + @tab Audio format used on the PS3. +@item xWMA @tab @tab X + @tab Microsoft audio container used by XAudio 2. +@item eXtended BINary text (XBIN) @tab @tab X +@item YUV4MPEG pipe @tab X @tab X +@item Psygnosis YOP @tab @tab X +@end multitable + +@code{X} means that the feature in that column (encoding / decoding) is supported. + +@section Image Formats + +FFmpeg can read and write images for each frame of a video sequence. The +following image formats are supported: + +@multitable @columnfractions .4 .1 .1 .4 +@item Name @tab Encoding @tab Decoding @tab Comments +@item .Y.U.V @tab X @tab X + @tab one raw file per component +@item Alias PIX @tab X @tab X + @tab Alias/Wavefront PIX image format +@item animated GIF @tab X @tab X +@item APNG @tab X @tab X + @tab Animated Portable Network Graphics +@item BMP @tab X @tab X + @tab Microsoft BMP image +@item BRender PIX @tab @tab X + @tab Argonaut BRender 3D engine image format. +@item CRI @tab @tab X + @tab Cintel RAW +@item DPX @tab X @tab X + @tab Digital Picture Exchange +@item EXR @tab @tab X + @tab OpenEXR +@item FITS @tab X @tab X + @tab Flexible Image Transport System +@item JPEG @tab X @tab X + @tab Progressive JPEG is not supported. +@item JPEG 2000 @tab X @tab X +@item JPEG-LS @tab X @tab X +@item LJPEG @tab X @tab + @tab Lossless JPEG +@item MSP @tab @tab X + @tab Microsoft Paint image +@item PAM @tab X @tab X + @tab PAM is a PNM extension with alpha support. +@item PBM @tab X @tab X + @tab Portable BitMap image +@item PCD @tab @tab X + @tab PhotoCD +@item PCX @tab X @tab X + @tab PC Paintbrush +@item PFM @tab X @tab X + @tab Portable FloatMap image +@item PGM @tab X @tab X + @tab Portable GrayMap image +@item PGMYUV @tab X @tab X + @tab PGM with U and V components in YUV 4:2:0 +@item PGX @tab @tab X + @tab PGX file decoder +@item PIC @tab @tab X + @tab Pictor/PC Paint +@item PNG @tab X @tab X + @tab Portable Network Graphics image +@item PPM @tab X @tab X + @tab Portable PixelMap image +@item PSD @tab @tab X + @tab Photoshop +@item PTX @tab @tab X + @tab V.Flash PTX format +@item SGI @tab X @tab X + @tab SGI RGB image format +@item Sun Rasterfile @tab X @tab X + @tab Sun RAS image format +@item TIFF @tab X @tab X + @tab YUV, JPEG and some extension is not supported yet. +@item Truevision Targa @tab X @tab X + @tab Targa (.TGA) image format +@item WebP @tab E @tab X + @tab WebP image format, encoding supported through external library libwebp +@item XBM @tab X @tab X + @tab X BitMap image format +@item XFace @tab X @tab X + @tab X-Face image format +@item XPM @tab @tab X + @tab X PixMap image format +@item XWD @tab X @tab X + @tab X Window Dump image format +@end multitable + +@code{X} means that the feature in that column (encoding / decoding) is supported. + +@code{E} means that support is provided through an external library. + +@section Video Codecs + +@multitable @columnfractions .4 .1 .1 .4 +@item Name @tab Encoding @tab Decoding @tab Comments +@item 4X Movie @tab @tab X + @tab Used in certain computer games. +@item 8088flex TMV @tab @tab X +@item A64 multicolor @tab X @tab + @tab Creates video suitable to be played on a commodore 64 (multicolor mode). +@item Amazing Studio PAF Video @tab @tab X +@item American Laser Games MM @tab @tab X + @tab Used in games like Mad Dog McCree. +@item Amuse Graphics Movie @tab @tab X +@item AMV Video @tab X @tab X + @tab Used in Chinese MP3 players. +@item ANSI/ASCII art @tab @tab X +@item Apple Intermediate Codec @tab @tab X +@item Apple MJPEG-B @tab @tab X +@item Apple Pixlet @tab @tab X +@item Apple ProRes @tab X @tab X + @tab fourcc: apch,apcn,apcs,apco,ap4h,ap4x +@item Apple QuickDraw @tab @tab X + @tab fourcc: qdrw +@item Argonaut Video @tab @tab X + @tab Used in some Argonaut games. +@item Asus v1 @tab X @tab X + @tab fourcc: ASV1 +@item Asus v2 @tab X @tab X + @tab fourcc: ASV2 +@item ATI VCR1 @tab @tab X + @tab fourcc: VCR1 +@item ATI VCR2 @tab @tab X + @tab fourcc: VCR2 +@item Auravision Aura @tab @tab X +@item Auravision Aura 2 @tab @tab X +@item Autodesk Animator Flic video @tab @tab X +@item Autodesk RLE @tab @tab X + @tab fourcc: AASC +@item AV1 @tab E @tab E + @tab Supported through external libraries libaom, libdav1d, librav1e and libsvtav1 +@item Avid 1:1 10-bit RGB Packer @tab X @tab X + @tab fourcc: AVrp +@item AVS (Audio Video Standard) video @tab @tab X + @tab Video encoding used by the Creature Shock game. +@item AVS2-P2/IEEE1857.4 @tab E @tab E + @tab Supported through external libraries libxavs2 and libdavs2 +@item AVS3-P2/IEEE1857.10 @tab @tab E + @tab Supported through external library libuavs3d +@item AYUV @tab X @tab X + @tab Microsoft uncompressed packed 4:4:4:4 +@item Beam Software VB @tab @tab X +@item Bethesda VID video @tab @tab X + @tab Used in some games from Bethesda Softworks. +@item Bink Video @tab @tab X +@item BitJazz SheerVideo @tab @tab X +@item Bitmap Brothers JV video @tab @tab X +@item y41p Brooktree uncompressed 4:1:1 12-bit @tab X @tab X +@item Brooktree ProSumer Video @tab @tab X + @tab fourcc: BT20 +@item Brute Force & Ignorance @tab @tab X + @tab Used in the game Flash Traffic: City of Angels. +@item C93 video @tab @tab X + @tab Codec used in Cyberia game. +@item CamStudio @tab @tab X + @tab fourcc: CSCD +@item CD+G @tab @tab X + @tab Video codec for CD+G karaoke disks +@item CDXL @tab @tab X + @tab Amiga CD video codec +@item Chinese AVS video @tab E @tab X + @tab AVS1-P2, JiZhun profile, encoding through external library libxavs +@item Delphine Software International CIN video @tab @tab X + @tab Codec used in Delphine Software International games. +@item Discworld II BMV Video @tab @tab X +@item CineForm HD @tab X @tab X +@item Canopus HQ @tab @tab X +@item Canopus HQA @tab @tab X +@item Canopus HQX @tab @tab X +@item Canopus Lossless Codec @tab @tab X +@item CDToons @tab @tab X + @tab Codec used in various Broderbund games. +@item Cinepak @tab @tab X +@item Cirrus Logic AccuPak @tab X @tab X + @tab fourcc: CLJR +@item CPiA Video Format @tab @tab X +@item Creative YUV (CYUV) @tab @tab X +@item DFA @tab @tab X + @tab Codec used in Chronomaster game. +@item Dirac @tab E @tab X + @tab supported though the native vc2 (Dirac Pro) encoder +@item Deluxe Paint Animation @tab @tab X +@item DNxHD @tab X @tab X + @tab aka SMPTE VC3 +@item Duck TrueMotion 1.0 @tab @tab X + @tab fourcc: DUCK +@item Duck TrueMotion 2.0 @tab @tab X + @tab fourcc: TM20 +@item Duck TrueMotion 2.0 RT @tab @tab X + @tab fourcc: TR20 +@item DV (Digital Video) @tab X @tab X +@item Dxtory capture format @tab @tab X +@item Feeble Files/ScummVM DXA @tab @tab X + @tab Codec originally used in Feeble Files game. +@item Electronic Arts CMV video @tab @tab X + @tab Used in NHL 95 game. +@item Electronic Arts Madcow video @tab @tab X +@item Electronic Arts TGV video @tab @tab X +@item Electronic Arts TGQ video @tab @tab X +@item Electronic Arts TQI video @tab @tab X +@item Escape 124 @tab @tab X +@item Escape 130 @tab @tab X +@item FFmpeg video codec #1 @tab X @tab X + @tab lossless codec (fourcc: FFV1) +@item Flash Screen Video v1 @tab X @tab X + @tab fourcc: FSV1 +@item Flash Screen Video v2 @tab X @tab X +@item Flash Video (FLV) @tab X @tab X + @tab Sorenson H.263 used in Flash +@item FM Screen Capture Codec @tab @tab X +@item Forward Uncompressed @tab @tab X +@item Fraps @tab @tab X +@item Go2Meeting @tab @tab X + @tab fourcc: G2M2, G2M3 +@item Go2Webinar @tab @tab X + @tab fourcc: G2M4 +@item Gremlin Digital Video @tab @tab X +@item H.261 @tab X @tab X +@item H.263 / H.263-1996 @tab X @tab X +@item H.263+ / H.263-1998 / H.263 version 2 @tab X @tab X +@item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 @tab E @tab X + @tab encoding supported through external library libx264 and OpenH264 +@item HEVC @tab X @tab X + @tab encoding supported through external library libx265 and libkvazaar +@item HNM version 4 @tab @tab X +@item HuffYUV @tab X @tab X +@item HuffYUV FFmpeg variant @tab X @tab X +@item IBM Ultimotion @tab @tab X + @tab fourcc: ULTI +@item id Cinematic video @tab @tab X + @tab Used in Quake II. +@item id RoQ video @tab X @tab X + @tab Used in Quake III, Jedi Knight 2, other computer games. +@item IFF ILBM @tab @tab X + @tab IFF interleaved bitmap +@item IFF ByteRun1 @tab @tab X + @tab IFF run length encoded bitmap +@item Infinity IMM4 @tab @tab X +@item Intel H.263 @tab @tab X +@item Intel Indeo 2 @tab @tab X +@item Intel Indeo 3 @tab @tab X +@item Intel Indeo 4 @tab @tab X +@item Intel Indeo 5 @tab @tab X +@item Interplay C93 @tab @tab X + @tab Used in the game Cyberia from Interplay. +@item Interplay MVE video @tab @tab X + @tab Used in Interplay .MVE files. +@item J2K @tab X @tab X +@item Karl Morton's video codec @tab @tab X + @tab Codec used in Worms games. +@item Kega Game Video (KGV1) @tab @tab X + @tab Kega emulator screen capture codec. +@item Lagarith @tab @tab X +@item LCL (LossLess Codec Library) MSZH @tab @tab X +@item LCL (LossLess Codec Library) ZLIB @tab E @tab E +@item LOCO @tab @tab X +@item LucasArts SANM/Smush @tab @tab X + @tab Used in LucasArts games / SMUSH animations. +@item lossless MJPEG @tab X @tab X +@item MagicYUV Video @tab X @tab X +@item Mandsoft Screen Capture Codec @tab @tab X +@item Microsoft ATC Screen @tab @tab X + @tab Also known as Microsoft Screen 3. +@item Microsoft Expression Encoder Screen @tab @tab X + @tab Also known as Microsoft Titanium Screen 2. +@item Microsoft RLE @tab @tab X +@item Microsoft Screen 1 @tab @tab X + @tab Also known as Windows Media Video V7 Screen. +@item Microsoft Screen 2 @tab @tab X + @tab Also known as Windows Media Video V9 Screen. +@item Microsoft Video 1 @tab @tab X +@item Mimic @tab @tab X + @tab Used in MSN Messenger Webcam streams. +@item Miro VideoXL @tab @tab X + @tab fourcc: VIXL +@item MJPEG (Motion JPEG) @tab X @tab X +@item Mobotix MxPEG video @tab @tab X +@item Motion Pixels video @tab @tab X +@item MPEG-1 video @tab X @tab X +@item MPEG-2 video @tab X @tab X +@item MPEG-4 part 2 @tab X @tab X + @tab libxvidcore can be used alternatively for encoding. +@item MPEG-4 part 2 Microsoft variant version 1 @tab @tab X +@item MPEG-4 part 2 Microsoft variant version 2 @tab X @tab X +@item MPEG-4 part 2 Microsoft variant version 3 @tab X @tab X +@item Newtek SpeedHQ @tab X @tab X +@item Nintendo Gamecube THP video @tab @tab X +@item NotchLC @tab @tab X +@item NuppelVideo/RTjpeg @tab @tab X + @tab Video encoding used in NuppelVideo files. +@item On2 VP3 @tab @tab X + @tab still experimental +@item On2 VP4 @tab @tab X + @tab fourcc: VP40 +@item On2 VP5 @tab @tab X + @tab fourcc: VP50 +@item On2 VP6 @tab @tab X + @tab fourcc: VP60,VP61,VP62 +@item On2 VP7 @tab @tab X + @tab fourcc: VP70,VP71 +@item VP8 @tab E @tab X + @tab fourcc: VP80, encoding supported through external library libvpx +@item VP9 @tab E @tab X + @tab encoding supported through external library libvpx +@item Pinnacle TARGA CineWave YUV16 @tab @tab X + @tab fourcc: Y216 +@item Q-team QPEG @tab @tab X + @tab fourccs: QPEG, Q1.0, Q1.1 +@item QuickTime 8BPS video @tab @tab X +@item QuickTime Animation (RLE) video @tab X @tab X + @tab fourcc: 'rle ' +@item QuickTime Graphics (SMC) @tab @tab X + @tab fourcc: 'smc ' +@item QuickTime video (RPZA) @tab X @tab X + @tab fourcc: rpza +@item R10K AJA Kona 10-bit RGB Codec @tab X @tab X +@item R210 Quicktime Uncompressed RGB 10-bit @tab X @tab X +@item Raw Video @tab X @tab X +@item RealVideo 1.0 @tab X @tab X +@item RealVideo 2.0 @tab X @tab X +@item RealVideo 3.0 @tab @tab X + @tab still far from ideal +@item RealVideo 4.0 @tab @tab X +@item Renderware TXD (TeXture Dictionary) @tab @tab X + @tab Texture dictionaries used by the Renderware Engine. +@item RL2 video @tab @tab X + @tab used in some games by Entertainment Software Partners +@item ScreenPressor @tab @tab X +@item Screenpresso @tab @tab X +@item Screen Recorder Gold Codec @tab @tab X +@item Sierra VMD video @tab @tab X + @tab Used in Sierra VMD files. +@item Silicon Graphics Motion Video Compressor 1 (MVC1) @tab @tab X +@item Silicon Graphics Motion Video Compressor 2 (MVC2) @tab @tab X +@item Silicon Graphics RLE 8-bit video @tab @tab X +@item Smacker video @tab @tab X + @tab Video encoding used in Smacker. +@item SMPTE VC-1 @tab @tab X +@item Snow @tab X @tab X + @tab experimental wavelet codec (fourcc: SNOW) +@item Sony PlayStation MDEC (Motion DECoder) @tab @tab X +@item Sorenson Vector Quantizer 1 @tab X @tab X + @tab fourcc: SVQ1 +@item Sorenson Vector Quantizer 3 @tab @tab X + @tab fourcc: SVQ3 +@item Sunplus JPEG (SP5X) @tab @tab X + @tab fourcc: SP5X +@item TechSmith Screen Capture Codec @tab @tab X + @tab fourcc: TSCC +@item TechSmith Screen Capture Codec 2 @tab @tab X + @tab fourcc: TSC2 +@item Theora @tab E @tab X + @tab encoding supported through external library libtheora +@item Tiertex Limited SEQ video @tab @tab X + @tab Codec used in DOS CD-ROM FlashBack game. +@item Ut Video @tab X @tab X +@item v210 QuickTime uncompressed 4:2:2 10-bit @tab X @tab X +@item v308 QuickTime uncompressed 4:4:4 @tab X @tab X +@item v408 QuickTime uncompressed 4:4:4:4 @tab X @tab X +@item v410 QuickTime uncompressed 4:4:4 10-bit @tab X @tab X +@item VBLE Lossless Codec @tab @tab X +@item VMware Screen Codec / VMware Video @tab @tab X + @tab Codec used in videos captured by VMware. +@item Westwood Studios VQA (Vector Quantized Animation) video @tab @tab X +@item Windows Media Image @tab @tab X +@item Windows Media Video 7 @tab X @tab X +@item Windows Media Video 8 @tab X @tab X +@item Windows Media Video 9 @tab @tab X + @tab not completely working +@item Wing Commander III / Xan @tab @tab X + @tab Used in Wing Commander III .MVE files. +@item Wing Commander IV / Xan @tab @tab X + @tab Used in Wing Commander IV. +@item Winnov WNV1 @tab @tab X +@item WMV7 @tab X @tab X +@item YAMAHA SMAF @tab X @tab X +@item Psygnosis YOP Video @tab @tab X +@item yuv4 @tab X @tab X + @tab libquicktime uncompressed packed 4:2:0 +@item ZeroCodec Lossless Video @tab @tab X +@item ZLIB @tab X @tab X + @tab part of LCL, encoder experimental +@item Zip Motion Blocks Video @tab X @tab X + @tab Encoder works only in PAL8. +@end multitable + +@code{X} means that the feature in that column (encoding / decoding) is supported. + +@code{E} means that support is provided through an external library. + +@section Audio Codecs + +@multitable @columnfractions .4 .1 .1 .4 +@item Name @tab Encoding @tab Decoding @tab Comments +@item 8SVX exponential @tab @tab X +@item 8SVX fibonacci @tab @tab X +@item AAC @tab EX @tab X + @tab encoding supported through internal encoder and external library libfdk-aac +@item AAC+ @tab E @tab IX + @tab encoding supported through external library libfdk-aac +@item AC-3 @tab IX @tab IX +@item ACELP.KELVIN @tab @tab X +@item ADPCM 4X Movie @tab @tab X +@item ADPCM Yamaha AICA @tab @tab X +@item ADPCM AmuseGraphics Movie @tab @tab X +@item ADPCM Argonaut Games @tab X @tab X +@item ADPCM CDROM XA @tab @tab X +@item ADPCM Creative Technology @tab @tab X + @tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2 +@item ADPCM Electronic Arts @tab @tab X + @tab Used in various EA titles. +@item ADPCM Electronic Arts Maxis CDROM XS @tab @tab X + @tab Used in Sim City 3000. +@item ADPCM Electronic Arts R1 @tab @tab X +@item ADPCM Electronic Arts R2 @tab @tab X +@item ADPCM Electronic Arts R3 @tab @tab X +@item ADPCM Electronic Arts XAS @tab @tab X +@item ADPCM G.722 @tab X @tab X +@item ADPCM G.726 @tab X @tab X +@item ADPCM IMA AMV @tab X @tab X + @tab Used in AMV files +@item ADPCM IMA Cunning Developments @tab @tab X +@item ADPCM IMA Electronic Arts EACS @tab @tab X +@item ADPCM IMA Electronic Arts SEAD @tab @tab X +@item ADPCM IMA Funcom @tab @tab X +@item ADPCM IMA High Voltage Software ALP @tab X @tab X +@item ADPCM IMA QuickTime @tab X @tab X +@item ADPCM IMA Simon & Schuster Interactive @tab X @tab X +@item ADPCM IMA Ubisoft APM @tab X @tab X +@item ADPCM IMA Loki SDL MJPEG @tab @tab X +@item ADPCM IMA WAV @tab X @tab X +@item ADPCM IMA Westwood @tab @tab X +@item ADPCM ISS IMA @tab @tab X + @tab Used in FunCom games. +@item ADPCM IMA Dialogic @tab @tab X +@item ADPCM IMA Duck DK3 @tab @tab X + @tab Used in some Sega Saturn console games. +@item ADPCM IMA Duck DK4 @tab @tab X + @tab Used in some Sega Saturn console games. +@item ADPCM IMA Radical @tab @tab X +@item ADPCM Microsoft @tab X @tab X +@item ADPCM MS IMA @tab X @tab X +@item ADPCM Nintendo Gamecube AFC @tab @tab X +@item ADPCM Nintendo Gamecube DTK @tab @tab X +@item ADPCM Nintendo THP @tab @tab X +@item ADPCM Playstation @tab @tab X +@item ADPCM QT IMA @tab X @tab X +@item ADPCM SEGA CRI ADX @tab X @tab X + @tab Used in Sega Dreamcast games. +@item ADPCM Shockwave Flash @tab X @tab X +@item ADPCM Sound Blaster Pro 2-bit @tab @tab X +@item ADPCM Sound Blaster Pro 2.6-bit @tab @tab X +@item ADPCM Sound Blaster Pro 4-bit @tab @tab X +@item ADPCM VIMA @tab @tab X + @tab Used in LucasArts SMUSH animations. +@item ADPCM Westwood Studios IMA @tab @tab X + @tab Used in Westwood Studios games like Command and Conquer. +@item ADPCM Yamaha @tab X @tab X +@item ADPCM Zork @tab @tab X +@item AMR-NB @tab E @tab X + @tab encoding supported through external library libopencore-amrnb +@item AMR-WB @tab E @tab X + @tab encoding supported through external library libvo-amrwbenc +@item Amazing Studio PAF Audio @tab @tab X +@item Apple lossless audio @tab X @tab X + @tab QuickTime fourcc 'alac' +@item aptX @tab X @tab X + @tab Used in Bluetooth A2DP +@item aptX HD @tab X @tab X + @tab Used in Bluetooth A2DP +@item ATRAC1 @tab @tab X +@item ATRAC3 @tab @tab X +@item ATRAC3+ @tab @tab X +@item ATRAC9 @tab @tab X +@item Bink Audio @tab @tab X + @tab Used in Bink and Smacker files in many games. +@item CELT @tab @tab E + @tab decoding supported through external library libcelt +@item codec2 @tab E @tab E + @tab en/decoding supported through external library libcodec2 +@item CRI HCA @tab @tab X +@item Delphine Software International CIN audio @tab @tab X + @tab Codec used in Delphine Software International games. +@item Digital Speech Standard - Standard Play mode (DSS SP) @tab @tab X +@item Discworld II BMV Audio @tab @tab X +@item COOK @tab @tab X + @tab All versions except 5.1 are supported. +@item DCA (DTS Coherent Acoustics) @tab X @tab X + @tab supported extensions: XCh, XXCH, X96, XBR, XLL, LBR (partially) +@item Dolby E @tab @tab X +@item DPCM Gremlin @tab @tab X +@item DPCM id RoQ @tab X @tab X + @tab Used in Quake III, Jedi Knight 2 and other computer games. +@item DPCM Interplay @tab @tab X + @tab Used in various Interplay computer games. +@item DPCM Squareroot-Delta-Exact @tab @tab X + @tab Used in various games. +@item DPCM Sierra Online @tab @tab X + @tab Used in Sierra Online game audio files. +@item DPCM Sol @tab @tab X +@item DPCM Xan @tab @tab X + @tab Used in Origin's Wing Commander IV AVI files. +@item DPCM Xilam DERF @tab @tab X +@item DSD (Direct Stream Digital), least significant bit first @tab @tab X +@item DSD (Direct Stream Digital), most significant bit first @tab @tab X +@item DSD (Direct Stream Digital), least significant bit first, planar @tab @tab X +@item DSD (Direct Stream Digital), most significant bit first, planar @tab @tab X +@item DSP Group TrueSpeech @tab @tab X +@item DST (Direct Stream Transfer) @tab @tab X +@item DV audio @tab @tab X +@item Enhanced AC-3 @tab X @tab X +@item EVRC (Enhanced Variable Rate Codec) @tab @tab X +@item FLAC (Free Lossless Audio Codec) @tab X @tab IX +@item G.723.1 @tab X @tab X +@item G.729 @tab @tab X +@item GSM @tab E @tab X + @tab encoding supported through external library libgsm +@item GSM Microsoft variant @tab E @tab X + @tab encoding supported through external library libgsm +@item IAC (Indeo Audio Coder) @tab @tab X +@item iLBC (Internet Low Bitrate Codec) @tab E @tab E + @tab encoding and decoding supported through external library libilbc +@item IMC (Intel Music Coder) @tab @tab X +@item Interplay ACM @tab @tab X +@item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X +@item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X +@item MLP (Meridian Lossless Packing) @tab X @tab X + @tab Used in DVD-Audio discs. +@item Monkey's Audio @tab @tab X +@item MP1 (MPEG audio layer 1) @tab @tab IX +@item MP2 (MPEG audio layer 2) @tab IX @tab IX + @tab encoding supported also through external library TwoLAME +@item MP3 (MPEG audio layer 3) @tab E @tab IX + @tab encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported +@item MPEG-4 Audio Lossless Coding (ALS) @tab @tab X +@item Musepack SV7 @tab @tab X +@item Musepack SV8 @tab @tab X +@item Nellymoser Asao @tab X @tab X +@item On2 AVC (Audio for Video Codec) @tab @tab X +@item Opus @tab E @tab X + @tab encoding supported through external library libopus +@item PCM A-law @tab X @tab X +@item PCM mu-law @tab X @tab X +@item PCM Archimedes VIDC @tab X @tab X +@item PCM signed 8-bit planar @tab X @tab X +@item PCM signed 16-bit big-endian planar @tab X @tab X +@item PCM signed 16-bit little-endian planar @tab X @tab X +@item PCM signed 24-bit little-endian planar @tab X @tab X +@item PCM signed 32-bit little-endian planar @tab X @tab X +@item PCM 32-bit floating point big-endian @tab X @tab X +@item PCM 32-bit floating point little-endian @tab X @tab X +@item PCM 64-bit floating point big-endian @tab X @tab X +@item PCM 64-bit floating point little-endian @tab X @tab X +@item PCM D-Cinema audio signed 24-bit @tab X @tab X +@item PCM signed 8-bit @tab X @tab X +@item PCM signed 16-bit big-endian @tab X @tab X +@item PCM signed 16-bit little-endian @tab X @tab X +@item PCM signed 24-bit big-endian @tab X @tab X +@item PCM signed 24-bit little-endian @tab X @tab X +@item PCM signed 32-bit big-endian @tab X @tab X +@item PCM signed 32-bit little-endian @tab X @tab X +@item PCM signed 16/20/24-bit big-endian in MPEG-TS @tab @tab X +@item PCM unsigned 8-bit @tab X @tab X +@item PCM unsigned 16-bit big-endian @tab X @tab X +@item PCM unsigned 16-bit little-endian @tab X @tab X +@item PCM unsigned 24-bit big-endian @tab X @tab X +@item PCM unsigned 24-bit little-endian @tab X @tab X +@item PCM unsigned 32-bit big-endian @tab X @tab X +@item PCM unsigned 32-bit little-endian @tab X @tab X +@item QCELP / PureVoice @tab @tab X +@item QDesign Music Codec 1 @tab @tab X +@item QDesign Music Codec 2 @tab @tab X + @tab There are still some distortions. +@item RealAudio 1.0 (14.4K) @tab X @tab X + @tab Real 14400 bit/s codec +@item RealAudio 2.0 (28.8K) @tab @tab X + @tab Real 28800 bit/s codec +@item RealAudio 3.0 (dnet) @tab IX @tab X + @tab Real low bitrate AC-3 codec +@item RealAudio Lossless @tab @tab X +@item RealAudio SIPR / ACELP.NET @tab @tab X +@item SBC (low-complexity subband codec) @tab X @tab X + @tab Used in Bluetooth A2DP +@item Shorten @tab @tab X +@item Sierra VMD audio @tab @tab X + @tab Used in Sierra VMD files. +@item Smacker audio @tab @tab X +@item SMPTE 302M AES3 audio @tab X @tab X +@item Sonic @tab X @tab X + @tab experimental codec +@item Sonic lossless @tab X @tab X + @tab experimental codec +@item Speex @tab E @tab E + @tab supported through external library libspeex +@item TAK (Tom's lossless Audio Kompressor) @tab @tab X +@item True Audio (TTA) @tab X @tab X +@item TrueHD @tab X @tab X + @tab Used in HD-DVD and Blu-Ray discs. +@item TwinVQ (VQF flavor) @tab @tab X +@item VIMA @tab @tab X + @tab Used in LucasArts SMUSH animations. +@item Vorbis @tab E @tab X + @tab A native but very primitive encoder exists. +@item Voxware MetaSound @tab @tab X +@item WavPack @tab X @tab X +@item Westwood Audio (SND1) @tab @tab X +@item Windows Media Audio 1 @tab X @tab X +@item Windows Media Audio 2 @tab X @tab X +@item Windows Media Audio Lossless @tab @tab X +@item Windows Media Audio Pro @tab @tab X +@item Windows Media Audio Voice @tab @tab X +@item Xbox Media Audio 1 @tab @tab X +@item Xbox Media Audio 2 @tab @tab X +@end multitable + +@code{X} means that the feature in that column (encoding / decoding) is supported. + +@code{E} means that support is provided through an external library. + +@code{I} means that an integer-only version is available, too (ensures high +performance on systems without hardware floating point support). + +@section Subtitle Formats + +@multitable @columnfractions .4 .1 .1 .1 .1 +@item Name @tab Muxing @tab Demuxing @tab Encoding @tab Decoding +@item 3GPP Timed Text @tab @tab @tab X @tab X +@item AQTitle @tab @tab X @tab @tab X +@item DVB @tab X @tab X @tab X @tab X +@item DVB teletext @tab @tab X @tab @tab E +@item DVD @tab X @tab X @tab X @tab X +@item JACOsub @tab X @tab X @tab @tab X +@item MicroDVD @tab X @tab X @tab @tab X +@item MPL2 @tab @tab X @tab @tab X +@item MPsub (MPlayer) @tab @tab X @tab @tab X +@item PGS @tab @tab @tab @tab X +@item PJS (Phoenix) @tab @tab X @tab @tab X +@item RealText @tab @tab X @tab @tab X +@item SAMI @tab @tab X @tab @tab X +@item Spruce format (STL) @tab @tab X @tab @tab X +@item SSA/ASS @tab X @tab X @tab X @tab X +@item SubRip (SRT) @tab X @tab X @tab X @tab X +@item SubViewer v1 @tab @tab X @tab @tab X +@item SubViewer @tab @tab X @tab @tab X +@item TED Talks captions @tab @tab X @tab @tab X +@item TTML @tab X @tab @tab X @tab +@item VobSub (IDX+SUB) @tab @tab X @tab @tab X +@item VPlayer @tab @tab X @tab @tab X +@item WebVTT @tab X @tab X @tab X @tab X +@item XSUB @tab @tab @tab X @tab X +@end multitable + +@code{X} means that the feature is supported. + +@code{E} means that support is provided through an external library. + +@section Network Protocols + +@multitable @columnfractions .4 .1 +@item Name @tab Support +@item AMQP @tab E +@item file @tab X +@item FTP @tab X +@item Gopher @tab X +@item Gophers @tab X +@item HLS @tab X +@item HTTP @tab X +@item HTTPS @tab X +@item Icecast @tab X +@item MMSH @tab X +@item MMST @tab X +@item pipe @tab X +@item Pro-MPEG FEC @tab X +@item RTMP @tab X +@item RTMPE @tab X +@item RTMPS @tab X +@item RTMPT @tab X +@item RTMPTE @tab X +@item RTMPTS @tab X +@item RTP @tab X +@item SAMBA @tab E +@item SCTP @tab X +@item SFTP @tab E +@item TCP @tab X +@item TLS @tab X +@item UDP @tab X +@item ZMQ @tab E +@end multitable + +@code{X} means that the protocol is supported. + +@code{E} means that support is provided through an external library. + + +@section Input/Output Devices + +@multitable @columnfractions .4 .1 .1 +@item Name @tab Input @tab Output +@item ALSA @tab X @tab X +@item BKTR @tab X @tab +@item caca @tab @tab X +@item DV1394 @tab X @tab +@item Lavfi virtual device @tab X @tab +@item Linux framebuffer @tab X @tab X +@item JACK @tab X @tab +@item LIBCDIO @tab X +@item LIBDC1394 @tab X @tab +@item OpenAL @tab X +@item OpenGL @tab @tab X +@item OSS @tab X @tab X +@item PulseAudio @tab X @tab X +@item SDL @tab @tab X +@item Video4Linux2 @tab X @tab X +@item VfW capture @tab X @tab +@item X11 grabbing @tab X @tab +@item Win32 grabbing @tab X @tab +@end multitable + +@code{X} means that input/output is supported. + +@section Timecode + +@multitable @columnfractions .4 .1 .1 +@item Codec/format @tab Read @tab Write +@item AVI @tab X @tab X +@item DV @tab X @tab X +@item GXF @tab X @tab X +@item MOV @tab X @tab X +@item MPEG1/2 @tab X @tab X +@item MXF @tab X @tab X +@end multitable diff --git a/doc/indevs.texi b/doc/indevs.texi index 6f5afaf34..b377924c2 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -296,16 +296,31 @@ supports it. Set the pixel format of the captured video. Available values are: @table @samp +@item auto + +This is the default which means 8-bit YUV 422 or 8-bit ARGB if format +autodetection is used, 8-bit YUV 422 otherwise. + @item uyvy422 +8-bit YUV 422. + @item yuv422p10 +10-bit YUV 422. + @item argb +8-bit RGB. + @item bgra +8-bit RGB. + @item rgb10 +10-bit RGB. + @end table @item teletext_lines @@ -335,8 +350,13 @@ Defaults to @samp{unset}. @item timecode_format Timecode type to include in the frame and video stream metadata. Must be @samp{none}, @samp{rp188vitc}, @samp{rp188vitc2}, @samp{rp188ltc}, -@samp{rp188any}, @samp{vitc}, @samp{vitc2}, or @samp{serial}. Defaults to -@samp{none} (not included). +@samp{rp188hfr}, @samp{rp188any}, @samp{vitc}, @samp{vitc2}, or @samp{serial}. +Defaults to @samp{none} (not included). + +In order to properly support 50/60 fps timecodes, the ordering of the queried +timecode types for @samp{rp188any} is HFR, VITC1, VITC2 and LTC for >30 fps +content. Note that this is slightly different to the ordering used by the +DeckLink API, which is HFR, VITC1, LTC, VITC2. @item video_input Sets the video input source. Must be @samp{unset}, @samp{sdi}, @samp{hdmi}, @@ -398,6 +418,12 @@ are dropped till a frame with timecode is received. Option @var{timecode_format} must be specified. Defaults to @option{false}. +@item enable_klv(@emph{bool}) +If set to @option{true}, extracts KLV data from VANC and outputs KLV packets. +KLV VANC packets are joined based on MID and PSC fields and aggregated into +one KLV packet. +Defaults to @option{false}. + @end table @subsection Examples @@ -883,11 +909,15 @@ If you don't understand what all of that means, you probably don't want this. L DRM device to capture on. Defaults to @option{/dev/dri/card0}. @item format -Pixel format of the framebuffer. Defaults to @option{bgr0}. +Pixel format of the framebuffer. This can be autodetected if you are running Linux 5.7 +or later, but needs to be provided for earlier versions. Defaults to @option{bgr0}, +which is the most common format used by the Linux console and Xorg X server. @item format_modifier Format modifier to signal on output frames. This is necessary to import correctly into -some APIs, but can't be autodetected. See the libdrm documentation for possible values. +some APIs. It can be autodetected if you are running Linux 5.7 or later, but will need +to be provided explicitly when needed in earlier versions. See the libdrm documentation +for possible values. @item crtc_id KMS CRTC ID to define the capture source. The first active plane on the given CRTC @@ -1478,6 +1508,14 @@ ffmpeg -f x11grab -framerate 25 -video_size cif -i :0.0+10,20 out.mpg @subsection Options @table @option +@item select_region +Specify whether to select the grabbing area graphically using the pointer. +A value of @code{1} prompts the user to select the grabbing area graphically +by clicking and dragging. A single click with no dragging will select the +whole screen. A region with zero width or height will also select the whole +screen. This option overwrites the @var{video_size}, @var{grab_x}, and +@var{grab_y} options. Default value is @code{0}. + @item draw_mouse Specify whether to draw the mouse pointer. A value of @code{0} specifies not to draw the pointer. Default value is @code{1}. @@ -1526,8 +1564,21 @@ With @var{follow_mouse}: ffmpeg -f x11grab -follow_mouse centered -show_region 1 -framerate 25 -video_size cif -i :0.0 out.mpg @end example +@item window_id +Grab this window, instead of the whole screen. Default value is 0, which maps to +the whole screen (root window). + +The id of a window can be found using the @command{xwininfo} program, possibly with options -tree and +-root. + +If the window is later enlarged, the new area is not recorded. Video ends when +the window is closed, unmapped (i.e., iconified) or shrunk beyond the video +size (which defaults to the initial window size). + +This option disables options @option{follow_mouse} and @option{select_region}. + @item video_size -Set the video frame size. Default is the full desktop. +Set the video frame size. Default is the full desktop or window. @item grab_x @item grab_y diff --git a/doc/multithreading.txt b/doc/multithreading.txt index 4f645dc14..470194ff8 100644 --- a/doc/multithreading.txt +++ b/doc/multithreading.txt @@ -20,8 +20,7 @@ Slice threading - Frame threading - * Restrictions with slice threading also apply. -* For best performance, the client should set thread_safe_callbacks if it - provides a thread-safe get_buffer() callback. +* Custom get_buffer2() and get_format() callbacks must be thread-safe. * There is one frame of delay added for every thread beyond the first one. Clients must be able to handle this; the pkt_dts and pkt_pts fields in AVFrame will work as usual. diff --git a/doc/muxers.texi b/doc/muxers.texi index c598abbe6..74833d761 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -89,6 +89,12 @@ specific scenarios, e.g. when merging multiple audio streams into one for compatibility with software that only supports a single audio stream in AVI (see @ref{amerge,,the "amerge" section in the ffmpeg-filters manual,ffmpeg-filters}). +@item flipped_raw_rgb +If set to true, store positive height for raw RGB bitmaps, which indicates +bitmap is stored bottom-up. Note that this option does not flip the bitmap +which has to be done manually beforehand, e.g. by using the vflip filter. +Default is @var{false} and indicates bitmap is stored top down. + @end table @anchor{chromaprint} @@ -236,6 +242,8 @@ This is a deprecated option to set the segment length in microseconds, use @var{ @item seg_duration @var{duration} Set the segment length in seconds (fractional value can be set). The value is treated as average segment duration when @var{use_template} is enabled and +@var{use_timeline} is disabled and as minimum segment duration for all the other +use cases. @item frag_duration @var{duration} Set the length in seconds of fragments within segments (fractional value can be set). @item frag_type @var{type} @@ -267,8 +275,10 @@ Override User-Agent field in HTTP header. Applicable only for HTTP output. @item http_persistent @var{http_persistent} Use persistent HTTP connections. Applicable only for HTTP output. @item hls_playlist @var{hls_playlist} -Generate HLS playlist files as well. The master playlist is generated with the filename master.m3u8. +Generate HLS playlist files as well. The master playlist is generated with the filename @var{hls_master_name}. One media playlist file is generated for each stream with filenames media_0.m3u8, media_1.m3u8, etc. +@item hls_master_name @var{file_name} +HLS master playlist name. Default is "master.m3u8". @item streaming @var{streaming} Enable (1) or disable (0) chunk streaming mode of output. In chunk streaming mode, each frame will be a moof fragment which forms a chunk. @@ -364,6 +374,10 @@ adjusting playback latency and buffer occupancy during normal playback by client Set the maximum playback rate indicated as appropriate for the purposes of automatically adjusting playback latency and buffer occupancy during normal playback by clients. +@item update_period @var{update_period} + Set the mpd update period ,for dynamic content. + The unit is second. + @end table @anchor{framecrc} @@ -597,14 +611,21 @@ segmentation. This muxer supports the following options: @table @option -@item hls_init_time @var{seconds} -Set the initial target segment length in seconds. Default value is @var{0}. +@item hls_init_time @var{duration} +Set the initial target segment length. Default value is @var{0}. + +@var{duration} must be a time duration specification, +see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}. + Segment will be cut on the next key frame after this time has passed on the first m3u8 list. After the initial playlist is filled @command{ffmpeg} will cut segments at duration equal to @code{hls_time} -@item hls_time @var{seconds} -Set the target segment length in seconds. Default value is 2. +@item hls_time @var{duration} +Set the target segment length. Default value is 2. + +@var{duration} must be a time duration specification, +see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}. Segment will be cut on the next key frame after this time has passed. @item hls_list_size @var{size} @@ -819,7 +840,7 @@ When enabled every segment generated is encrypted and the encryption key is saved as @var{playlist name}.key. @item -hls_enc_key @var{key} -Hex-coded 16byte key to encrypt the segments, by default it +16-octet key to encrypt the segments, by default it is randomly generated. @item -hls_enc_key_url @var{keyurl} @@ -827,7 +848,7 @@ If set, @var{keyurl} is prepended instead of @var{baseurl} to the key filename in the playlist. @item -hls_enc_iv @var{iv} -Hex-coded 16byte initialization vector for every segment instead +16-octet initialization vector for every segment instead of the autogenerated ones. @item hls_segment_type @var{flags} @@ -847,6 +868,13 @@ fmp4 files may be used in HLS version 7 and above. @item hls_fmp4_init_filename @var{filename} Set filename to the fragment files header file, default filename is @file{init.mp4}. +Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime. +@example +ffmpeg -i in.nut -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8 +@end example +This will produce init like this +@file{1602678741_init.mp4} + @item hls_fmp4_init_resend Resend init file after m3u8 file refresh every time, default is @var{0}. @@ -1407,6 +1435,13 @@ disposition default exists, no subtitle track will be marked as default. In this mode the FlagDefault is set if and only if the AV_DISPOSITION_DEFAULT flag is set in the disposition of the corresponding stream. @end table + +@item flipped_raw_rgb +If set to true, store positive height for raw RGB bitmaps, which indicates +bitmap is stored bottom-up. Note that this option does not flip the bitmap +which has to be done manually beforehand, e.g. by using the vflip filter. +Default is @var{false} and indicates bitmap is stored top down. + @end table @anchor{md5} @@ -2275,6 +2310,11 @@ certain (usually permanent) errors the recovery is not attempted even when Specify whether to wait for the keyframe after recovering from queue overflow or failure. This option is set to 0 (false) by default. +@item timeshift @var{duration} +Buffer the specified amount of packets and delay writing the output. Note that +@var{queue_size} must be big enough to store the packets for timeshift. At the +end of the input the fifo buffer is flushed at realtime speed. + @end table @subsection Examples diff --git a/doc/outdevs.texi b/doc/outdevs.texi index 60606eb6e..aaf247995 100644 --- a/doc/outdevs.texi +++ b/doc/outdevs.texi @@ -38,6 +38,52 @@ ffmpeg -i INPUT -f alsa hw:1,7 @end example @end itemize +@section AudioToolbox + +AudioToolbox output device. + +Allows native output to CoreAudio devices on OSX. + +The output filename can be empty (or @code{-}) to refer to the default system output device or a number that refers to the device index as shown using: @code{-list_devices true}. + +Alternatively, the audio input device can be chosen by index using the +@option{ + -audio_device_index +} +, overriding any device name or index given in the input filename. + +All available devices can be enumerated by using @option{-list_devices true}, listing +all device names, UIDs and corresponding indices. + +@subsection Options + +AudioToolbox supports the following options: + +@table @option + +@item -audio_device_index +Specify the audio device by its index. Overrides anything given in the output filename. + +@end table + +@subsection Examples + +@itemize + +@item +Print the list of supported devices and output a sine wave to the default device: +@example +$ ffmpeg -f lavfi -i sine=r=44100 -f audiotoolbox -list_devices true - +@end example + +@item +Output a sine wave to the device with the index 2, overriding any output filename: +@example +$ ffmpeg -f lavfi -i sine=r=44100 -f audiotoolbox -audio_device_index 2 - +@end example + +@end itemize + @section caca CACA output device. diff --git a/doc/protocols.texi b/doc/protocols.texi index 7aa758541..d3f6cbefc 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -63,16 +63,17 @@ After starting the broker, an FFmpeg client may stream data to the broker using the command: @example -ffmpeg -re -i input -f mpegts amqp://[[user]:[password]@@]hostname[:port] +ffmpeg -re -i input -f mpegts amqp://[[user]:[password]@@]hostname[:port][/vhost] @end example Where hostname and port (default is 5672) is the address of the broker. The client may also set a user/password for authentication. The default for both -fields is "guest". +fields is "guest". Name of virtual host on broker can be set with vhost. The +default value is "/". Muliple subscribers may stream from the broker using the command: @example -ffplay amqp://[[user]:[password]@@]hostname[:port] +ffplay amqp://[[user]:[password]@@]hostname[:port][/vhost] @end example In RabbitMQ all data published to the broker flows through a specific exchange, @@ -109,6 +110,21 @@ the received message may be truncated causing decoding errors. The timeout in seconds during the initial connection to the broker. The default value is rw_timeout, or 5 seconds if rw_timeout is not set. +@item delivery_mode @var{mode} +Sets the delivery mode of each message sent to broker. +The following values are accepted: +@table @samp +@item persistent +Delivery mode set to "persistent" (2). This is the default value. +Messages may be written to the broker's disk depending on its setup. + +@item non-persistent +Delivery mode set to "non-persistent" (1). +Messages will stay in broker's memory unless the broker is under memory +pressure. + +@end table + @end table @section async @@ -159,6 +175,16 @@ Caching wrapper for input stream. Cache the input stream to temporary file. It brings seeking capability to live streams. +The accepted options are: +@table @option + +@item read_ahead_limit +Amount in bytes that may be read ahead when seeking isn't supported. Range is -1 to INT_MAX. +-1 for unlimited. Default is 65536. + +@end table + +URL Syntax is @example cache:@var{URL} @end example @@ -315,6 +341,12 @@ operation. ff* tools may produce incomplete content due to server limitations. Gopher protocol. +@section gophers + +Gophers protocol. + +The Gopher protocol with TLS encapsulation. + @section hls Read Apple HTTP Live Streaming compliant segmented stream as @@ -377,11 +409,6 @@ string describing the libavformat build. ("Lavf/") @item user-agent This is a deprecated option, you can use user_agent instead it. -@item timeout -Set timeout in microseconds of socket I/O operations used by the underlying low level -operation. By default it is set to -1, which means that the timeout is -not specified. - @item reconnect_at_eof If set then eof is treated like an error and causes reconnection, this is useful for live / endless streams. @@ -389,6 +416,13 @@ for live / endless streams. @item reconnect_streamed If set then even streamed/non seekable streams will be reconnected on errors. +@item reconnect_on_network_error +Reconnect automatically in case of TCP/TLS errors during connect. + +@item reconnect_on_http_error +A comma separated list of HTTP status codes to reconnect on. The list can +include specific status codes (e.g. '503') or the strings '4xx' / '5xx'. + @item reconnect_delay_max Sets the maximum delay in seconds after which to give up reconnecting @@ -466,6 +500,28 @@ Send an Expect: 100-continue header for POST. If set to 1 it will send, if set to 0 it won't, if set to -1 it will try to send if it is applicable. Default value is -1. +@item auth_type + +Set HTTP authentication type. No option for Digest, since this method requires +getting nonce parameters from the server first and can't be used straight away like +Basic. + +@table @option +@item none +Choose the HTTP authentication type automatically. This is the default. +@item basic + +Choose the HTTP basic authentication. + +Basic authentication sends a Base64-encoded string that contains a user name and password +for the client. Base64 is not a form of encryption and should be considered the same as +sending the user name and password in clear text (Base64 is a reversible encoding). +If a resource needs to be protected, strongly consider using an authentication scheme +other than basic authentication. HTTPS/TLS should be used with basic authentication. +Without these additional security enhancements, basic authentication should not be used +to protect sensitive or valuable information. +@end table + @end table @subsection HTTP Cookies @@ -520,6 +576,9 @@ audio/mpeg. This enables support for Icecast versions < 2.4.0, that do not support the HTTP PUT method but the SOURCE method. +@item tls +Establish a TLS (HTTPS) connection to Icecast. + @end table @example @@ -637,6 +696,42 @@ Example usage: -f rtp_mpegts -fec prompeg=l=8:d=4 rtp://@var{hostname}:@var{port} @end example +@section rist + +Reliable Internet Streaming Transport protocol + +The accepted options are: +@table @option +@item rist_profile +Supported values: +@table @samp +@item simple +@item main +This one is default. +@item advanced +@end table + +@item buffer_size +Set internal RIST buffer size in milliseconds for retransmission of data. +Default value is 0 which means the librist default (1 sec). Maximum value is 30 +seconds. + +@item pkt_size +Set maximum packet size for sending data. 1316 by default. + +@item log_level +Set loglevel for RIST logging messages. You only need to set this if you +explicitly want to enable debug level messages or packet loss simulation, +otherwise the regular loglevel is respected. + +@item secret +Set override of encryption secret, by default is unset. + +@item encryption +Set encryption type, by default is disabled. +Acceptable values are 128 and 256. +@end table + @section rtmp Real-Time Messaging Protocol. @@ -938,6 +1033,9 @@ Set the local RTCP port to @var{n}. @item pkt_size=@var{n} Set max packet size (in bytes) to @var{n}. +@item buffer_size=@var{size} +Set the maximum UDP socket buffer size in bytes. + @item connect=0|1 Do a @code{connect()} on the UDP socket (if set to 1) or not (if set to 0). @@ -955,6 +1053,9 @@ set to 1) or to a default remote address (if set to 0). @item localport=@var{n} Set the local RTP port to @var{n}. +@item timeout=@var{n} +Set timeout (in microseconds) of socket I/O operations to @var{n}. + This is a deprecated option. Instead, @option{localrtpport} should be used. @@ -1596,8 +1697,9 @@ tcp://@var{hostname}:@var{port}[?@var{options}] The list of supported options follows. @table @option -@item listen=@var{1|0} -Listen for an incoming connection. Default value is 0. +@item listen=@var{2|1|0} +Listen for an incoming connection. 0 disables listen, 1 enables listen in +single client mode, 2 enables listen in multi-client mode. Default value is 0. @item timeout=@var{microseconds} Set raise error timeout, expressed in microseconds. @@ -1673,6 +1775,10 @@ A file containing the private key for the certificate. If enabled, listen for connections on the provided port, and assume the server role in the handshake instead of the client role. +@item http_proxy +The HTTP proxy to tunnel through, e.g. @code{http://example.com:1234}. +The proxy must support the CONNECT method. + @end table Example command lines: diff --git a/doc/texi2pod.pl b/doc/texi2pod.pl index 9a9b34fc1..c7f67afe8 100644 --- a/doc/texi2pod.pl +++ b/doc/texi2pod.pl @@ -172,6 +172,9 @@ INF: while(<$inf>) { } elsif ($ended =~ /^(?:itemize|enumerate|(?:multi|[fv])?table)$/) { $_ = "\n=back\n"; $ic = pop @icstack; + } elsif ($ended =~ /^float$/) { + $_ = "\n=back\n"; + $ic = pop @icstack; } else { die "unknown command \@end $ended at line $.\n"; } @@ -297,6 +300,12 @@ INF: while(<$inf>) { $_ = ""; # need a paragraph break }; + /^\@(float)\s+\w+/ and do { + push @endwstack, $endw; + $endw = $1; + $_ = "\n=over 4\n"; + }; + /^\@item\s+(.*\S)\s*$/ and $endw eq "multitable" and do { my $columns = $1; $columns =~ s/\@tab/ : /; diff --git a/doc/utils.texi b/doc/utils.texi index e7a9b40b3..44ce285d2 100644 --- a/doc/utils.texi +++ b/doc/utils.texi @@ -110,11 +110,13 @@ maximum of 2 digits. The @var{m} at the end expresses decimal value for @emph{or} @example -[-]@var{S}+[.@var{m}...] +[-]@var{S}+[.@var{m}...][s|ms|us] @end example @var{S} expresses the number of seconds, with the optional decimal part -@var{m}. +@var{m}. The optional literal suffixes @samp{s}, @samp{ms} or @samp{us} +indicate to interpret the value as seconds, milliseconds or microseconds, +respectively. In both expressions, the optional @samp{-} indicates negative duration. diff --git a/ffbuild/common.mak b/ffbuild/common.mak index a60d27c9b..e070b6b5e 100644 --- a/ffbuild/common.mak +++ b/ffbuild/common.mak @@ -44,7 +44,7 @@ LDFLAGS := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS) define COMPILE $(call $(1)DEP,$(1)) - $($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) + $($(1)) $($(1)FLAGS) $($(2)) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) endef COMPILE_C = $(call COMPILE,CC) @@ -54,6 +54,14 @@ COMPILE_M = $(call COMPILE,OBJCC) COMPILE_X86ASM = $(call COMPILE,X86ASM) COMPILE_HOSTC = $(call COMPILE,HOSTCC) COMPILE_NVCC = $(call COMPILE,NVCC) +COMPILE_MMI = $(call COMPILE,CC,MMIFLAGS) +COMPILE_MSA = $(call COMPILE,CC,MSAFLAGS) + +%_mmi.o: %_mmi.c + $(COMPILE_MMI) + +%_msa.o: %_msa.c + $(COMPILE_MSA) %.o: %.c $(COMPILE_C) @@ -99,7 +107,7 @@ COMPILE_NVCC = $(call COMPILE,NVCC) %.c %.h %.pc %.ver %.version: TAG = GEN # Dummy rule to stop make trying to rebuild removed or renamed headers -%.h: +%.h %_template.c: @: # Disable suffix rules. Most of the builtin rules are suffix rules, diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index 13567a777..fe424b6a4 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -202,23 +202,22 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags, void show_help_children(const AVClass *class, int flags) { - const AVClass *child = NULL; + void *iter = NULL; + const AVClass *child; if (class->option) { av_opt_show2(&class, NULL, flags, 0); printf("\n"); } - while (child = av_opt_child_class_next(class, child)) + while (child = av_opt_child_class_iterate(class, &iter)) show_help_children(child, flags); } static const OptionDef *find_option(const OptionDef *po, const char *name) { - const char *p = strchr(name, ':'); - int len = p ? p - name : strlen(name); - while (po->name) { - if (!strncmp(name, po->name, len) && strlen(po->name) == len) + const char *end; + if (av_strstart(name, po->name, &end) && (!*end || *end == ':')) break; po++; } @@ -1164,13 +1163,13 @@ static void print_buildconf(int flags, int level) // Change all the ' --' strings to '~--' so that // they can be identified as tokens. while ((conflist = strstr(str, " --")) != NULL) { - strncpy(conflist, "~--", 3); + conflist[0] = '~'; } // Compensate for the weirdness this would cause // when passing 'pkg-config --static'. while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) { - strncpy(remove_tilde, "pkg-config ", 11); + remove_tilde[sizeof("pkg-config~") - 2] = ' '; } splitconf = strtok(str, "~"); @@ -1416,7 +1415,7 @@ static void print_codec(const AVCodec *c) printf("variable "); if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS | - AV_CODEC_CAP_AUTO_THREADS)) + AV_CODEC_CAP_OTHER_THREADS)) printf("threads "); if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING) printf("avoidprobe "); @@ -1433,12 +1432,12 @@ static void print_codec(const AVCodec *c) printf(" Threading capabilities: "); switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS | - AV_CODEC_CAP_AUTO_THREADS)) { + AV_CODEC_CAP_OTHER_THREADS)) { case AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break; case AV_CODEC_CAP_FRAME_THREADS: printf("frame"); break; case AV_CODEC_CAP_SLICE_THREADS: printf("slice"); break; - case AV_CODEC_CAP_AUTO_THREADS : printf("auto"); break; + case AV_CODEC_CAP_OTHER_THREADS: printf("other"); break; default: printf("none"); break; } printf("\n"); @@ -2102,7 +2101,7 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec) } AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, - AVFormatContext *s, AVStream *st, AVCodec *codec) + AVFormatContext *s, AVStream *st, const AVCodec *codec) { AVDictionary *ret = NULL; AVDictionaryEntry *t = NULL; @@ -2131,6 +2130,7 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, } while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) { + const AVClass *priv_class; char *p = strchr(t->key, ':'); /* check stream specification in opt name */ @@ -2143,8 +2143,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) || !codec || - (codec->priv_class && - av_opt_find(&codec->priv_class, t->key, NULL, flags, + ((priv_class = codec->priv_class) && + av_opt_find(&priv_class, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))) av_dict_set(&ret, t->key, t->value, 0); else if (t->key[0] == prefix && @@ -2307,7 +2307,7 @@ int show_sources(void *optctx, const char *opt, const char *arg) int ret = 0; int error_level = av_log_get_level(); - av_log_set_level(AV_LOG_ERROR); + av_log_set_level(AV_LOG_WARNING); if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0) goto fail; @@ -2345,7 +2345,7 @@ int show_sinks(void *optctx, const char *opt, const char *arg) int ret = 0; int error_level = av_log_get_level(); - av_log_set_level(AV_LOG_ERROR); + av_log_set_level(AV_LOG_WARNING); if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0) goto fail; diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h index 191751058..5da9f4c88 100644 --- a/fftools/cmdutils.h +++ b/fftools/cmdutils.h @@ -414,7 +414,7 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec); * @return a pointer to the created dictionary */ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, - AVFormatContext *s, AVStream *st, AVCodec *codec); + AVFormatContext *s, AVStream *st, const AVCodec *codec); /** * Setup AVCodecContext options for avformat_find_stream_info(). diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 2e9448ea2..46bb014de 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -136,6 +136,7 @@ static int nb_frames_dup = 0; static unsigned dup_warning = 1000; static int nb_frames_drop = 0; static int64_t decode_error_stat[2]; +static unsigned nb_output_dumped = 0; static int want_sdp = 1; @@ -344,6 +345,7 @@ static volatile int received_nb_signals = 0; static atomic_int transcode_init_done = ATOMIC_VAR_INIT(0); static volatile int ffmpeg_exited = 0; static int main_return_code = 0; +static int64_t copy_ts_first_pts = AV_NOPTS_VALUE; static void sigterm_handler(int sig) @@ -392,8 +394,30 @@ static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) } #endif +#ifdef __linux__ +#define SIGNAL(sig, func) \ + do { \ + action.sa_handler = func; \ + sigaction(sig, &action, NULL); \ + } while (0) +#else +#define SIGNAL(sig, func) \ + signal(sig, func) +#endif + void term_init(void) { +#if defined __linux__ + struct sigaction action = {0}; + action.sa_handler = sigterm_handler; + + /* block other interrupts while processing this one */ + sigfillset(&action.sa_mask); + + /* restart interruptible functions (i.e. don't fail with EINTR) */ + action.sa_flags = SA_RESTART; +#endif + #if HAVE_TERMIOS_H if (!run_as_daemon && stdin_interaction) { struct termios tty; @@ -412,14 +436,14 @@ void term_init(void) tcsetattr (0, TCSANOW, &tty); } - signal(SIGQUIT, sigterm_handler); /* Quit (POSIX). */ + SIGNAL(SIGQUIT, sigterm_handler); /* Quit (POSIX). */ } #endif - signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */ - signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */ + SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */ + SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */ #ifdef SIGXCPU - signal(SIGXCPU, sigterm_handler); + SIGNAL(SIGXCPU, sigterm_handler); #endif #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */ @@ -528,6 +552,7 @@ static void ffmpeg_cleanup(int ret) for (j = 0; j < fg->nb_outputs; j++) { OutputFilter *ofilter = fg->outputs[j]; + avfilter_inout_free(&ofilter->out_tmp); av_freep(&ofilter->name); av_freep(&ofilter->formats); av_freep(&ofilter->channel_layouts); @@ -567,6 +592,7 @@ static void ffmpeg_cleanup(int ret) av_frame_free(&ost->filtered_frame); av_frame_free(&ost->last_frame); + av_packet_free(&ost->pkt); av_dict_free(&ost->encoder_opts); av_freep(&ost->forced_keyframes); @@ -585,9 +611,9 @@ static void ffmpeg_cleanup(int ret) if (ost->muxing_queue) { while (av_fifo_size(ost->muxing_queue)) { - AVPacket pkt; + AVPacket *pkt; av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL); - av_packet_unref(&pkt); + av_packet_free(&pkt); } av_fifo_freep(&ost->muxing_queue); } @@ -599,6 +625,7 @@ static void ffmpeg_cleanup(int ret) #endif for (i = 0; i < nb_input_files; i++) { avformat_close_input(&input_files[i]->ctx); + av_packet_free(&input_files[i]->pkt); av_freep(&input_files[i]); } for (i = 0; i < nb_input_streams; i++) { @@ -606,6 +633,7 @@ static void ffmpeg_cleanup(int ret) av_frame_free(&ist->decoded_frame); av_frame_free(&ist->filter_frame); + av_packet_free(&ist->pkt); av_dict_free(&ist->decoder_opts); avsubtitle_free(&ist->prev_sub.subtitle); av_frame_free(&ist->sub2video.frame); @@ -663,7 +691,7 @@ void assert_avoptions(AVDictionary *m) } } -static void abort_codec_experimental(AVCodec *c, int encoder) +static void abort_codec_experimental(const AVCodec *c, int encoder) { exit_program(1); } @@ -721,11 +749,16 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int u } if (!of->header_written) { - AVPacket tmp_pkt = {0}; + AVPacket *tmp_pkt; /* the muxer is not initialized yet, buffer the packet */ if (!av_fifo_space(ost->muxing_queue)) { - int new_size = FFMIN(2 * av_fifo_size(ost->muxing_queue), - ost->max_muxing_queue_size); + unsigned int are_we_over_size = + (ost->muxing_queue_data_size + pkt->size) > ost->muxing_queue_data_threshold; + int new_size = are_we_over_size ? + FFMIN(2 * av_fifo_size(ost->muxing_queue), + ost->max_muxing_queue_size) : + 2 * av_fifo_size(ost->muxing_queue); + if (new_size <= av_fifo_size(ost->muxing_queue)) { av_log(NULL, AV_LOG_ERROR, "Too many packets buffered for output stream %d:%d.\n", @@ -739,7 +772,11 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int u ret = av_packet_make_refcounted(pkt); if (ret < 0) exit_program(1); - av_packet_move_ref(&tmp_pkt, pkt); + tmp_pkt = av_packet_alloc(); + if (!tmp_pkt) + exit_program(1); + av_packet_move_ref(tmp_pkt, pkt); + ost->muxing_queue_data_size += tmp_pkt->size; av_fifo_generic_write(ost->muxing_queue, &tmp_pkt, sizeof(tmp_pkt), NULL); return; } @@ -896,16 +933,82 @@ static int check_recording_time(OutputStream *ost) return 1; } +static double adjust_frame_pts_to_encoder_tb(OutputFile *of, OutputStream *ost, + AVFrame *frame) +{ + double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision + AVCodecContext *enc = ost->enc_ctx; + if (!frame || frame->pts == AV_NOPTS_VALUE || + !enc || !ost->filter || !ost->filter->graph->graph) + goto early_exit; + + { + AVFilterContext *filter = ost->filter->filter; + + int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; + AVRational filter_tb = av_buffersink_get_time_base(filter); + AVRational tb = enc->time_base; + int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16); + + tb.den <<= extra_bits; + float_pts = + av_rescale_q(frame->pts, filter_tb, tb) - + av_rescale_q(start_time, AV_TIME_BASE_Q, tb); + float_pts /= 1 << extra_bits; + // avoid exact midoints to reduce the chance of rounding differences, this can be removed in case the fps code is changed to work with integers + float_pts += FFSIGN(float_pts) * 1.0 / (1<<17); + + frame->pts = + av_rescale_q(frame->pts, filter_tb, enc->time_base) - + av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base); + } + +early_exit: + + if (debug_ts) { + av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n", + frame ? av_ts2str(frame->pts) : "NULL", + frame ? av_ts2timestr(frame->pts, &enc->time_base) : "NULL", + float_pts, + enc ? enc->time_base.num : -1, + enc ? enc->time_base.den : -1); + } + + return float_pts; +} + +static int init_output_stream(OutputStream *ost, AVFrame *frame, + char *error, int error_len); + +static int init_output_stream_wrapper(OutputStream *ost, AVFrame *frame, + unsigned int fatal) +{ + int ret = AVERROR_BUG; + char error[1024] = {0}; + + if (ost->initialized) + return 0; + + ret = init_output_stream(ost, frame, error, sizeof(error)); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error initializing output stream %d:%d -- %s\n", + ost->file_index, ost->index, error); + + if (fatal) + exit_program(1); + } + + return ret; +} + static void do_audio_out(OutputFile *of, OutputStream *ost, AVFrame *frame) { AVCodecContext *enc = ost->enc_ctx; - AVPacket pkt; + AVPacket *pkt = ost->pkt; int ret; - av_init_packet(&pkt); - pkt.data = NULL; - pkt.size = 0; + adjust_frame_pts_to_encoder_tb(of, ost, frame); if (!check_recording_time(ost)) return; @@ -916,7 +1019,6 @@ static void do_audio_out(OutputFile *of, OutputStream *ost, ost->samples_encoded += frame->nb_samples; ost->frames_encoded++; - av_assert0(pkt.size || !pkt.data); update_benchmark(NULL); if (debug_ts) { av_log(NULL, AV_LOG_INFO, "encoder <- type:audio " @@ -930,7 +1032,8 @@ static void do_audio_out(OutputFile *of, OutputStream *ost, goto error; while (1) { - ret = avcodec_receive_packet(enc, &pkt); + av_packet_unref(pkt); + ret = avcodec_receive_packet(enc, pkt); if (ret == AVERROR(EAGAIN)) break; if (ret < 0) @@ -938,16 +1041,16 @@ static void do_audio_out(OutputFile *of, OutputStream *ost, update_benchmark("encode_audio %d.%d", ost->file_index, ost->index); - av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase); + av_packet_rescale_ts(pkt, enc->time_base, ost->mux_timebase); if (debug_ts) { av_log(NULL, AV_LOG_INFO, "encoder -> type:audio " "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n", - av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &enc->time_base), - av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &enc->time_base)); + av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base), + av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base)); } - output_packet(of, &pkt, ost, 0); + output_packet(of, pkt, ost, 0); } return; @@ -963,7 +1066,7 @@ static void do_subtitle_out(OutputFile *of, int subtitle_out_max_size = 1024 * 1024; int subtitle_out_size, nb, i; AVCodecContext *enc; - AVPacket pkt; + AVPacket *pkt = ost->pkt; int64_t pts; if (sub->pts == AV_NOPTS_VALUE) { @@ -1021,41 +1124,43 @@ static void do_subtitle_out(OutputFile *of, exit_program(1); } - av_init_packet(&pkt); - pkt.data = subtitle_out; - pkt.size = subtitle_out_size; - pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->mux_timebase); - pkt.duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase); + av_packet_unref(pkt); + pkt->data = subtitle_out; + pkt->size = subtitle_out_size; + pkt->pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->mux_timebase); + pkt->duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase); if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { /* XXX: the pts correction is handled here. Maybe handling it in the codec would be better */ if (i == 0) - pkt.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase); + pkt->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase); else - pkt.pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase); + pkt->pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase); } - pkt.dts = pkt.pts; - output_packet(of, &pkt, ost, 0); + pkt->dts = pkt->pts; + output_packet(of, pkt, ost, 0); } } static void do_video_out(OutputFile *of, OutputStream *ost, - AVFrame *next_picture, - double sync_ipts) + AVFrame *next_picture) { int ret, format_video_sync; - AVPacket pkt; + AVPacket *pkt = ost->pkt; AVCodecContext *enc = ost->enc_ctx; - AVCodecParameters *mux_par = ost->st->codecpar; AVRational frame_rate; int nb_frames, nb0_frames, i; double delta, delta0; double duration = 0; + double sync_ipts = AV_NOPTS_VALUE; int frame_size = 0; InputStream *ist = NULL; AVFilterContext *filter = ost->filter->filter; + init_output_stream_wrapper(ost, next_picture, 1); + sync_ipts = adjust_frame_pts_to_encoder_tb(of, ost, next_picture); + if (ost->source_index >= 0) ist = input_streams[ost->source_index]; @@ -1188,9 +1293,6 @@ static void do_video_out(OutputFile *of, AVFrame *in_picture; int forced_keyframe = 0; double pts_time; - av_init_packet(&pkt); - pkt.data = NULL; - pkt.size = 0; if (i < nb0_frames && ost->last_frame) { in_picture = ost->last_frame; @@ -1205,18 +1307,6 @@ static void do_video_out(OutputFile *of, if (!check_recording_time(ost)) return; - if (enc->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) && - ost->top_field_first >= 0) - in_picture->top_field_first = !!ost->top_field_first; - - if (in_picture->interlaced_frame) { - if (enc->codec->id == AV_CODEC_ID_MJPEG) - mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TT:AV_FIELD_BB; - else - mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT; - } else - mux_par->field_order = AV_FIELD_PROGRESSIVE; - in_picture->quality = enc->global_quality; in_picture->pict_type = 0; @@ -1281,7 +1371,8 @@ static void do_video_out(OutputFile *of, av_frame_remove_side_data(in_picture, AV_FRAME_DATA_A53_CC); while (1) { - ret = avcodec_receive_packet(enc, &pkt); + av_packet_unref(pkt); + ret = avcodec_receive_packet(enc, pkt); update_benchmark("encode_video %d.%d", ost->file_index, ost->index); if (ret == AVERROR(EAGAIN)) break; @@ -1291,24 +1382,24 @@ static void do_video_out(OutputFile *of, if (debug_ts) { av_log(NULL, AV_LOG_INFO, "encoder -> type:video " "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n", - av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &enc->time_base), - av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &enc->time_base)); + av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base), + av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base)); } - if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & AV_CODEC_CAP_DELAY)) - pkt.pts = ost->sync_opts; + if (pkt->pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & AV_CODEC_CAP_DELAY)) + pkt->pts = ost->sync_opts; - av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase); + av_packet_rescale_ts(pkt, enc->time_base, ost->mux_timebase); if (debug_ts) { av_log(NULL, AV_LOG_INFO, "encoder -> type:video " "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n", - av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->mux_timebase), - av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->mux_timebase)); + av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->mux_timebase), + av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->mux_timebase)); } - frame_size = pkt.size; - output_packet(of, &pkt, ost, 0); + frame_size = pkt->size; + output_packet(of, pkt, ost, 0); /* if two pass, output log */ if (ost->logfile && enc->stats_out) { @@ -1389,8 +1480,6 @@ static void do_video_stats(OutputStream *ost, int frame_size) } } -static int init_output_stream(OutputStream *ost, char *error, int error_len); - static void finish_output_stream(OutputStream *ost) { OutputFile *of = output_files[ost->file_index]; @@ -1427,23 +1516,27 @@ static int reap_filters(int flush) continue; filter = ost->filter->filter; - if (!ost->initialized) { - char error[1024] = ""; - ret = init_output_stream(ost, error, sizeof(error)); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error initializing output stream %d:%d -- %s\n", - ost->file_index, ost->index, error); - exit_program(1); - } - } + /* + * Unlike video, with audio the audio frame size matters. + * Currently we are fully reliant on the lavfi filter chain to + * do the buffering deed for us, and thus the frame size parameter + * needs to be set accordingly. Where does one get the required + * frame size? From the initialized AVCodecContext of an audio + * encoder. Thus, if we have gotten to an audio stream, initialize + * the encoder earlier than receiving the first AVFrame. + */ + if (av_buffersink_get_type(filter) == AVMEDIA_TYPE_AUDIO) + init_output_stream_wrapper(ost, NULL, 1); + if (!ost->pkt && !(ost->pkt = av_packet_alloc())) { + return AVERROR(ENOMEM); + } if (!ost->filtered_frame && !(ost->filtered_frame = av_frame_alloc())) { return AVERROR(ENOMEM); } filtered_frame = ost->filtered_frame; while (1) { - double float_pts = AV_NOPTS_VALUE; // this is identical to filtered_frame.pts but with higher precision ret = av_buffersink_get_frame_flags(filter, filtered_frame, AV_BUFFERSINK_FLAG_NO_REQUEST); if (ret < 0) { @@ -1452,7 +1545,7 @@ static int reap_filters(int flush) "Error in av_buffersink_get_frame_flags(): %s\n", av_err2str(ret)); } else if (flush && ret == AVERROR_EOF) { if (av_buffersink_get_type(filter) == AVMEDIA_TYPE_VIDEO) - do_video_out(of, ost, NULL, AV_NOPTS_VALUE); + do_video_out(of, ost, NULL); } break; } @@ -1460,38 +1553,13 @@ static int reap_filters(int flush) av_frame_unref(filtered_frame); continue; } - if (filtered_frame->pts != AV_NOPTS_VALUE) { - int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; - AVRational filter_tb = av_buffersink_get_time_base(filter); - AVRational tb = enc->time_base; - int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16); - - tb.den <<= extra_bits; - float_pts = - av_rescale_q(filtered_frame->pts, filter_tb, tb) - - av_rescale_q(start_time, AV_TIME_BASE_Q, tb); - float_pts /= 1 << extra_bits; - // avoid exact midoints to reduce the chance of rounding differences, this can be removed in case the fps code is changed to work with integers - float_pts += FFSIGN(float_pts) * 1.0 / (1<<17); - - filtered_frame->pts = - av_rescale_q(filtered_frame->pts, filter_tb, enc->time_base) - - av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base); - } switch (av_buffersink_get_type(filter)) { case AVMEDIA_TYPE_VIDEO: if (!ost->frame_aspect_ratio.num) enc->sample_aspect_ratio = filtered_frame->sample_aspect_ratio; - if (debug_ts) { - av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n", - av_ts2str(filtered_frame->pts), av_ts2timestr(filtered_frame->pts, &enc->time_base), - float_pts, - enc->time_base.num, enc->time_base.den); - } - - do_video_out(of, ost, filtered_frame, float_pts); + do_video_out(of, ost, filtered_frame); break; case AVMEDIA_TYPE_AUDIO: if (!(enc->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE) && @@ -1643,6 +1711,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti double speed; int64_t pts = INT64_MIN + 1; static int64_t last_time = -1; + static int first_report = 1; static int qp_histogram[52]; int hours, mins, secs, us; const char *hours_sign; @@ -1655,9 +1724,9 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti if (!is_last_report) { if (last_time == -1) { last_time = cur_time; - return; } - if ((cur_time - last_time) < 500000) + if (((cur_time - last_time) < stats_period && !first_report) || + (first_report && nb_output_dumped < nb_output_files)) return; last_time = cur_time; } @@ -1740,9 +1809,17 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti vid = 1; } /* compute min output value */ - if (av_stream_get_end_pts(ost->st) != AV_NOPTS_VALUE) + if (av_stream_get_end_pts(ost->st) != AV_NOPTS_VALUE) { pts = FFMAX(pts, av_rescale_q(av_stream_get_end_pts(ost->st), ost->st->time_base, AV_TIME_BASE_Q)); + if (copy_ts) { + if (copy_ts_first_pts == AV_NOPTS_VALUE && pts > 1) + copy_ts_first_pts = pts; + if (copy_ts_first_pts != AV_NOPTS_VALUE) + pts -= copy_ts_first_pts; + } + } + if (is_last_report) nb_frames_drop += ost->last_dropped; } @@ -1826,6 +1903,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti } } + first_report = 0; + if (is_last_report) print_final_stats(total_size); } @@ -1859,7 +1938,6 @@ static void flush_encoders(void) // Maybe we should just let encoding fail instead. if (!ost->initialized) { FilterGraph *fg = ost->filter->graph; - char error[1024] = ""; av_log(NULL, AV_LOG_WARNING, "Finishing stream %d:%d without any data written to it.\n", @@ -1885,12 +1963,7 @@ static void flush_encoders(void) finish_output_stream(ost); } - ret = init_output_stream(ost, error, sizeof(error)); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error initializing output stream %d:%d -- %s\n", - ost->file_index, ost->index, error); - exit_program(1); - } + init_output_stream_wrapper(ost, NULL, 1); } if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO) @@ -1898,7 +1971,7 @@ static void flush_encoders(void) for (;;) { const char *desc = NULL; - AVPacket pkt; + AVPacket *pkt = ost->pkt; int pkt_size; switch (enc->codec_type) { @@ -1912,13 +1985,10 @@ static void flush_encoders(void) av_assert0(0); } - av_init_packet(&pkt); - pkt.data = NULL; - pkt.size = 0; - update_benchmark(NULL); - while ((ret = avcodec_receive_packet(enc, &pkt)) == AVERROR(EAGAIN)) { + av_packet_unref(pkt); + while ((ret = avcodec_receive_packet(enc, pkt)) == AVERROR(EAGAIN)) { ret = avcodec_send_frame(enc, NULL); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "%s encoding failed: %s\n", @@ -1939,16 +2009,16 @@ static void flush_encoders(void) fprintf(ost->logfile, "%s", enc->stats_out); } if (ret == AVERROR_EOF) { - output_packet(of, &pkt, ost, 1); + output_packet(of, pkt, ost, 1); break; } if (ost->finished & MUXER_FINISHED) { - av_packet_unref(&pkt); + av_packet_unref(pkt); continue; } - av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase); - pkt_size = pkt.size; - output_packet(of, &pkt, ost, 0); + av_packet_rescale_ts(pkt, enc->time_base, ost->mux_timebase); + pkt_size = pkt->size; + output_packet(of, pkt, ost, 0); if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) { do_video_stats(ost, pkt_size); } @@ -1982,14 +2052,12 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p InputFile *f = input_files [ist->file_index]; int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->mux_timebase); - AVPacket opkt; + AVPacket *opkt = ost->pkt; + av_packet_unref(opkt); // EOF: flush output bitstream filters. if (!pkt) { - av_init_packet(&opkt); - opkt.data = NULL; - opkt.size = 0; - output_packet(of, &opkt, ost, 1); + output_packet(of, opkt, ost, 1); return; } @@ -2027,30 +2095,30 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) ost->sync_opts++; - if (av_packet_ref(&opkt, pkt) < 0) + if (av_packet_ref(opkt, pkt) < 0) exit_program(1); if (pkt->pts != AV_NOPTS_VALUE) - opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->mux_timebase) - ost_tb_start_time; + opkt->pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->mux_timebase) - ost_tb_start_time; if (pkt->dts == AV_NOPTS_VALUE) { - opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->mux_timebase); + opkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->mux_timebase); } else if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { int duration = av_get_audio_frame_duration(ist->dec_ctx, pkt->size); if(!duration) duration = ist->dec_ctx->frame_size; - opkt.dts = av_rescale_delta(ist->st->time_base, pkt->dts, + opkt->dts = av_rescale_delta(ist->st->time_base, pkt->dts, (AVRational){1, ist->dec_ctx->sample_rate}, duration, &ist->filter_in_rescale_delta_last, ost->mux_timebase); /* dts will be set immediately afterwards to what pts is now */ - opkt.pts = opkt.dts - ost_tb_start_time; + opkt->pts = opkt->dts - ost_tb_start_time; } else - opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->mux_timebase); - opkt.dts -= ost_tb_start_time; + opkt->dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->mux_timebase); + opkt->dts -= ost_tb_start_time; - opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->mux_timebase); + opkt->duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->mux_timebase); - output_packet(of, &opkt, ost, 0); + output_packet(of, opkt, ost, 0); } int guess_input_channel_layout(InputStream *ist) @@ -2325,7 +2393,6 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_ int i, ret = 0, err = 0; int64_t best_effort_timestamp; int64_t dts = AV_NOPTS_VALUE; - AVPacket avpkt; // With fate-indeo3-2, we're getting 0-sized packets before EOF for some // reason. This seems like a semi-critical bug. Don't trigger EOF, and @@ -2341,8 +2408,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_ if (ist->dts != AV_NOPTS_VALUE) dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ist->st->time_base); if (pkt) { - avpkt = *pkt; - avpkt.dts = dts; // ffmpeg.c probably shouldn't do this + pkt->dts = dts; // ffmpeg.c probably shouldn't do this } // The old code used to set dts on the drain packet, which does not work @@ -2356,7 +2422,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_ } update_benchmark(NULL); - ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt ? &avpkt : NULL); + ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt); update_benchmark("decode_video %d.%d", ist->file_index, ist->st->index); if (ret < 0) *decode_failed = 1; @@ -2515,6 +2581,8 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; + if (!ost->pkt && !(ost->pkt = av_packet_alloc())) + exit_program(1); if (!check_output_constraints(ist, ost) || !ost->encoding_needed || ost->enc->type != AVMEDIA_TYPE_SUBTITLE) continue; @@ -2550,7 +2618,12 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo int repeating = 0; int eof_reached = 0; - AVPacket avpkt; + AVPacket *avpkt; + + if (!ist->pkt && !(ist->pkt = av_packet_alloc())) + return AVERROR(ENOMEM); + avpkt = ist->pkt; + if (!ist->saw_first_ts) { ist->dts = ist->st->avg_frame_rate.num ? - ist->dec_ctx->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0; ist->pts = 0; @@ -2566,13 +2639,11 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo if (ist->next_pts == AV_NOPTS_VALUE) ist->next_pts = ist->pts; - if (!pkt) { - /* EOF handling */ - av_init_packet(&avpkt); - avpkt.data = NULL; - avpkt.size = 0; - } else { - avpkt = *pkt; + if (pkt) { + av_packet_unref(avpkt); + ret = av_packet_ref(avpkt, pkt); + if (ret < 0) + return ret; } if (pkt && pkt->dts != AV_NOPTS_VALUE) { @@ -2593,11 +2664,12 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo switch (ist->dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: - ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output, + ret = decode_audio (ist, repeating ? NULL : avpkt, &got_output, &decode_failed); + av_packet_unref(avpkt); break; case AVMEDIA_TYPE_VIDEO: - ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output, &duration_pts, !pkt, + ret = decode_video (ist, repeating ? NULL : avpkt, &got_output, &duration_pts, !pkt, &decode_failed); if (!repeating || !pkt || got_output) { if (pkt && pkt->duration) { @@ -2622,13 +2694,15 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo ist->next_pts += duration_dts; } } + av_packet_unref(avpkt); break; case AVMEDIA_TYPE_SUBTITLE: if (repeating) break; - ret = transcode_subtitles(ist, &avpkt, &got_output, &decode_failed); + ret = transcode_subtitles(ist, avpkt, &got_output, &decode_failed); if (!pkt && ret >= 0) ret = AVERROR_EOF; + av_packet_unref(avpkt); break; default: return -1; @@ -2717,6 +2791,8 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; + if (!ost->pkt && !(ost->pkt = av_packet_alloc())) + exit_program(1); if (!check_output_constraints(ist, ost) || ost->encoding_needed) continue; @@ -2873,7 +2949,7 @@ static int init_input_stream(int ist_index, char *error, int error_len) InputStream *ist = input_streams[ist_index]; if (ist->decoding_needed) { - AVCodec *codec = ist->dec; + const AVCodec *codec = ist->dec; if (!codec) { snprintf(error, error_len, "Decoder (codec %s) not found for input stream #%d:%d", avcodec_get_name(ist->dec_ctx->codec_id), ist->file_index, ist->st->index); @@ -2883,9 +2959,10 @@ static int init_input_stream(int ist_index, char *error, int error_len) ist->dec_ctx->opaque = ist; ist->dec_ctx->get_format = get_format; ist->dec_ctx->get_buffer2 = get_buffer; +#if LIBAVCODEC_VERSION_MAJOR < 60 ist->dec_ctx->thread_safe_callbacks = 1; +#endif - av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); if (ist->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE && (ist->decoding_needed & DECODING_FOR_OST)) { av_dict_set(&ist->decoder_opts, "compute_edt", "1", AV_DICT_DONT_OVERWRITE); @@ -2969,6 +3046,7 @@ static int check_init_output_file(OutputFile *of, int file_index) of->header_written = 1; av_dump_format(of->ctx, file_index, of->ctx->url, 1); + nb_output_dumped++; if (sdp_filename || want_sdp) print_sdp(); @@ -2982,9 +3060,11 @@ static int check_init_output_file(OutputFile *of, int file_index) ost->mux_timebase = ost->st->time_base; while (av_fifo_size(ost->muxing_queue)) { - AVPacket pkt; + AVPacket *pkt; av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL); - write_packet(of, &pkt, ost, 1); + ost->muxing_queue_data_size -= pkt->size; + write_packet(of, pkt, ost, 1); + av_packet_free(&pkt); } } @@ -3262,7 +3342,7 @@ static void init_encoder_time_base(OutputStream *ost, AVRational default_time_ba enc_ctx->time_base = default_time_base; } -static int init_output_stream_encode(OutputStream *ost) +static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) { InputStream *ist = get_input_stream(ost); AVCodecContext *enc_ctx = ost->enc_ctx; @@ -3302,7 +3382,7 @@ static int init_output_stream_encode(OutputStream *ost) ost->frame_rate = ist->framerate; if (ist && !ost->frame_rate.num) ost->frame_rate = ist->st->r_frame_rate; - if (ist && !ost->frame_rate.num) { + if (ist && !ost->frame_rate.num && !ost->max_frame_rate.num) { ost->frame_rate = (AVRational){25, 1}; av_log(NULL, AV_LOG_WARNING, "No information " @@ -3312,6 +3392,11 @@ static int init_output_stream_encode(OutputStream *ost) ost->file_index, ost->index); } + if (ost->max_frame_rate.num && + (av_q2d(ost->frame_rate) > av_q2d(ost->max_frame_rate) || + !ost->frame_rate.den)) + ost->frame_rate = ost->max_frame_rate; + if (ost->enc->supported_framerates && !ost->force_fps) { int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates); ost->frame_rate = ost->enc->supported_framerates[idx]; @@ -3359,6 +3444,14 @@ static int init_output_stream_encode(OutputStream *ost) enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample, av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth); + if (frame) { + enc_ctx->color_range = frame->color_range; + enc_ctx->color_primaries = frame->color_primaries; + enc_ctx->color_trc = frame->color_trc; + enc_ctx->colorspace = frame->colorspace; + enc_ctx->chroma_sample_location = frame->chroma_location; + } + enc_ctx->framerate = ost->frame_rate; ost->st->avg_frame_rate = ost->frame_rate; @@ -3376,6 +3469,20 @@ static int init_output_stream_encode(OutputStream *ost) enc_ctx->field_order = AV_FIELD_TT; } + if (frame) { + if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) && + ost->top_field_first >= 0) + frame->top_field_first = !!ost->top_field_first; + + if (frame->interlaced_frame) { + if (enc_ctx->codec->id == AV_CODEC_ID_MJPEG) + enc_ctx->field_order = frame->top_field_first ? AV_FIELD_TT:AV_FIELD_BB; + else + enc_ctx->field_order = frame->top_field_first ? AV_FIELD_TB:AV_FIELD_BT; + } else + enc_ctx->field_order = AV_FIELD_PROGRESSIVE; + } + if (ost->forced_keyframes) { if (!strncmp(ost->forced_keyframes, "expr:", 5)) { ret = av_expr_parse(&ost->forced_keyframes_pexpr, ost->forced_keyframes+5, @@ -3416,16 +3523,17 @@ static int init_output_stream_encode(OutputStream *ost) return 0; } -static int init_output_stream(OutputStream *ost, char *error, int error_len) +static int init_output_stream(OutputStream *ost, AVFrame *frame, + char *error, int error_len) { int ret = 0; if (ost->encoding_needed) { - AVCodec *codec = ost->enc; + const AVCodec *codec = ost->enc; AVCodecContext *dec = NULL; InputStream *ist; - ret = init_output_stream_encode(ost); + ret = init_output_stream_encode(ost, frame); if (ret < 0) return ret; @@ -3498,12 +3606,6 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) "Error initializing the output stream codec context.\n"); exit_program(1); } - /* - * FIXME: ost->st->codec should't be needed here anymore. - */ - ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx); - if (ret < 0) - return ret; if (ost->enc_ctx->nb_coded_side_data) { int i; @@ -3548,8 +3650,6 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) // copy estimated duration as a hint to the muxer if (ost->st->duration <= 0 && ist && ist->st->duration > 0) ost->st->duration = av_rescale_q(ist->st->duration, ist->st->time_base, ost->st->time_base); - - ost->st->codec->codec= ost->enc_ctx->codec; } else if (ost->stream_copy) { ret = init_output_stream_streamcopy(ost); if (ret < 0) @@ -3662,13 +3762,22 @@ static int transcode_init(void) goto dump_format; } - /* open each encoder */ + /* + * initialize stream copy and subtitle/data streams. + * Encoded AVFrame based streams will get initialized as follows: + * - when the first AVFrame is received in do_video_out + * - just before the first AVFrame is received in either transcode_step + * or reap_filters due to us requiring the filter chain buffer sink + * to be configured with the correct audio frame size, which is only + * known after the encoder is initialized. + */ for (i = 0; i < nb_output_streams; i++) { - // skip streams fed from filtergraphs until we have a frame for them - if (output_streams[i]->filter) + if (!output_streams[i]->stream_copy && + (output_streams[i]->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO || + output_streams[i]->enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO)) continue; - ret = init_output_stream(output_streams[i], error, sizeof(error)); + ret = init_output_stream_wrapper(output_streams[i], NULL, 0); if (ret < 0) goto dump_format; } @@ -3932,13 +4041,9 @@ static int check_keyboard_interaction(int64_t cur_time) if (key == 'd' || key == 'D'){ int debug=0; if(key == 'D') { - debug = input_streams[0]->st->codec->debug<<1; + debug = input_streams[0]->dec_ctx->debug << 1; if(!debug) debug = 1; - while(debug & (FF_DEBUG_DCT_COEFF -#if FF_API_DEBUG_MV - |FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE -#endif - )) //unsupported, would just crash + while (debug & FF_DEBUG_DCT_COEFF) //unsupported, would just crash debug += debug; }else{ char buf[32]; @@ -3955,7 +4060,7 @@ static int check_keyboard_interaction(int64_t cur_time) fprintf(stderr,"error parsing debug value\n"); } for(i=0;ist->codec->debug = debug; + input_streams[i]->dec_ctx->debug = debug; } for(i=0;ipkt, *queue_pkt; unsigned flags = f->non_blocking ? AV_THREAD_MESSAGE_NONBLOCK : 0; int ret = 0; while (1) { - AVPacket pkt; - ret = av_read_frame(f->ctx, &pkt); + ret = av_read_frame(f->ctx, pkt); if (ret == AVERROR(EAGAIN)) { av_usleep(10000); @@ -3999,10 +4104,17 @@ static void *input_thread(void *arg) av_thread_message_queue_set_err_recv(f->in_thread_queue, ret); break; } - ret = av_thread_message_queue_send(f->in_thread_queue, &pkt, flags); + queue_pkt = av_packet_alloc(); + if (!queue_pkt) { + av_packet_unref(pkt); + av_thread_message_queue_set_err_recv(f->in_thread_queue, AVERROR(ENOMEM)); + break; + } + av_packet_move_ref(queue_pkt, pkt); + ret = av_thread_message_queue_send(f->in_thread_queue, &queue_pkt, flags); if (flags && ret == AVERROR(EAGAIN)) { flags = 0; - ret = av_thread_message_queue_send(f->in_thread_queue, &pkt, flags); + ret = av_thread_message_queue_send(f->in_thread_queue, &queue_pkt, flags); av_log(f->ctx, AV_LOG_WARNING, "Thread message queue blocking; consider raising the " "thread_queue_size option (current value: %d)\n", @@ -4013,7 +4125,7 @@ static void *input_thread(void *arg) av_log(f->ctx, AV_LOG_ERROR, "Unable to send packet to main thread: %s\n", av_err2str(ret)); - av_packet_unref(&pkt); + av_packet_free(&queue_pkt); av_thread_message_queue_set_err_recv(f->in_thread_queue, ret); break; } @@ -4025,13 +4137,13 @@ static void *input_thread(void *arg) static void free_input_thread(int i) { InputFile *f = input_files[i]; - AVPacket pkt; + AVPacket *pkt; if (!f || !f->in_thread_queue) return; av_thread_message_queue_set_err_send(f->in_thread_queue, AVERROR_EOF); while (av_thread_message_queue_recv(f->in_thread_queue, &pkt, 0) >= 0) - av_packet_unref(&pkt); + av_packet_free(&pkt); pthread_join(f->thread, NULL); f->joined = 1; @@ -4051,14 +4163,16 @@ static int init_input_thread(int i) int ret; InputFile *f = input_files[i]; - if (nb_input_files == 1) + if (f->thread_queue_size < 0) + f->thread_queue_size = (nb_input_files > 1 ? 8 : 0); + if (!f->thread_queue_size) return 0; if (f->ctx->pb ? !f->ctx->pb->seekable : strcmp(f->ctx->iformat->name, "lavfi")) f->non_blocking = 1; ret = av_thread_message_queue_alloc(&f->in_thread_queue, - f->thread_queue_size, sizeof(AVPacket)); + f->thread_queue_size, sizeof(f->pkt)); if (ret < 0) return ret; @@ -4083,7 +4197,7 @@ static int init_input_threads(void) return 0; } -static int get_input_packet_mt(InputFile *f, AVPacket *pkt) +static int get_input_packet_mt(InputFile *f, AVPacket **pkt) { return av_thread_message_queue_recv(f->in_thread_queue, pkt, f->non_blocking ? @@ -4091,7 +4205,7 @@ static int get_input_packet_mt(InputFile *f, AVPacket *pkt) } #endif -static int get_input_packet(InputFile *f, AVPacket *pkt) +static int get_input_packet(InputFile *f, AVPacket **pkt) { if (f->rate_emu) { int i; @@ -4105,10 +4219,11 @@ static int get_input_packet(InputFile *f, AVPacket *pkt) } #if HAVE_THREADS - if (nb_input_files > 1) + if (f->thread_queue_size) return get_input_packet_mt(f, pkt); #endif - return av_read_frame(f->ctx, pkt); + *pkt = f->pkt; + return av_read_frame(f->ctx, *pkt); } static int got_eagain(void) @@ -4220,7 +4335,7 @@ static int process_input(int file_index) InputFile *ifile = input_files[file_index]; AVFormatContext *is; InputStream *ist; - AVPacket pkt; + AVPacket *pkt; int ret, thread_ret, i, j; int64_t duration; int64_t pkt_dts; @@ -4295,27 +4410,27 @@ static int process_input(int file_index) reset_eagain(); if (do_pkt_dump) { - av_pkt_dump_log2(NULL, AV_LOG_INFO, &pkt, do_hex_dump, - is->streams[pkt.stream_index]); + av_pkt_dump_log2(NULL, AV_LOG_INFO, pkt, do_hex_dump, + is->streams[pkt->stream_index]); } /* the following test is needed in case new streams appear dynamically in stream : we ignore them */ - if (pkt.stream_index >= ifile->nb_streams) { - report_new_stream(file_index, &pkt); + if (pkt->stream_index >= ifile->nb_streams) { + report_new_stream(file_index, pkt); goto discard_packet; } - ist = input_streams[ifile->ist_index + pkt.stream_index]; + ist = input_streams[ifile->ist_index + pkt->stream_index]; - ist->data_size += pkt.size; + ist->data_size += pkt->size; ist->nb_packets++; if (ist->discard) goto discard_packet; - if (pkt.flags & AV_PKT_FLAG_CORRUPT) { + if (pkt->flags & AV_PKT_FLAG_CORRUPT) { av_log(NULL, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING, - "%s: corrupt input packet in stream %d\n", is->url, pkt.stream_index); + "%s: corrupt input packet in stream %d\n", is->url, pkt->stream_index); if (exit_on_error) exit_program(1); } @@ -4323,11 +4438,11 @@ static int process_input(int file_index) if (debug_ts) { av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d type:%s " "next_dts:%s next_dts_time:%s next_pts:%s next_pts_time:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%s off_time:%s\n", - ifile->ist_index + pkt.stream_index, av_get_media_type_string(ist->dec_ctx->codec_type), + ifile->ist_index + pkt->stream_index, av_get_media_type_string(ist->dec_ctx->codec_type), av_ts2str(ist->next_dts), av_ts2timestr(ist->next_dts, &AV_TIME_BASE_Q), av_ts2str(ist->next_pts), av_ts2timestr(ist->next_pts, &AV_TIME_BASE_Q), - av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ist->st->time_base), - av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ist->st->time_base), + av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base), + av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base), av_ts2str(input_files[ist->file_index]->ts_offset), av_ts2timestr(input_files[ist->file_index]->ts_offset, &AV_TIME_BASE_Q)); } @@ -4357,12 +4472,12 @@ static int process_input(int file_index) stime2= stime + (1ULL<st->pts_wrap_bits); ist->wrap_correction_done = 1; - if(stime2 > stime && pkt.dts != AV_NOPTS_VALUE && pkt.dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) { - pkt.dts -= 1ULL<st->pts_wrap_bits; + if(stime2 > stime && pkt->dts != AV_NOPTS_VALUE && pkt->dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) { + pkt->dts -= 1ULL<st->pts_wrap_bits; ist->wrap_correction_done = 0; } - if(stime2 > stime && pkt.pts != AV_NOPTS_VALUE && pkt.pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) { - pkt.pts -= 1ULL<st->pts_wrap_bits; + if(stime2 > stime && pkt->pts != AV_NOPTS_VALUE && pkt->pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) { + pkt->pts -= 1ULL<st->pts_wrap_bits; ist->wrap_correction_done = 0; } } @@ -4376,10 +4491,10 @@ static int process_input(int file_index) if (src_sd->type == AV_PKT_DATA_DISPLAYMATRIX) continue; - if (av_packet_get_side_data(&pkt, src_sd->type, NULL)) + if (av_packet_get_side_data(pkt, src_sd->type, NULL)) continue; - dst_data = av_packet_new_side_data(&pkt, src_sd->type, src_sd->size); + dst_data = av_packet_new_side_data(pkt, src_sd->type, src_sd->size); if (!dst_data) exit_program(1); @@ -4387,17 +4502,17 @@ static int process_input(int file_index) } } - if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); - if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); + if (pkt->dts != AV_NOPTS_VALUE) + pkt->dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); - if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts *= ist->ts_scale; - if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts *= ist->ts_scale; + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts *= ist->ts_scale; + if (pkt->dts != AV_NOPTS_VALUE) + pkt->dts *= ist->ts_scale; - pkt_dts = av_rescale_q_rnd(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); + pkt_dts = av_rescale_q_rnd(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) && pkt_dts != AV_NOPTS_VALUE && ist->next_dts == AV_NOPTS_VALUE && !copy_ts @@ -4409,27 +4524,27 @@ static int process_input(int file_index) av_log(NULL, AV_LOG_DEBUG, "Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, ifile->ts_offset); - pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); - if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); + pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); } } duration = av_rescale_q(ifile->duration, ifile->time_base, ist->st->time_base); - if (pkt.pts != AV_NOPTS_VALUE) { - pkt.pts += duration; - ist->max_pts = FFMAX(pkt.pts, ist->max_pts); - ist->min_pts = FFMIN(pkt.pts, ist->min_pts); + if (pkt->pts != AV_NOPTS_VALUE) { + pkt->pts += duration; + ist->max_pts = FFMAX(pkt->pts, ist->max_pts); + ist->min_pts = FFMIN(pkt->pts, ist->min_pts); } - if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts += duration; + if (pkt->dts != AV_NOPTS_VALUE) + pkt->dts += duration; - pkt_dts = av_rescale_q_rnd(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); + pkt_dts = av_rescale_q_rnd(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); if (copy_ts && pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE && (is->iformat->flags & AVFMT_TS_DISCONT) && ist->st->pts_wrap_bits < 60) { - int64_t wrap_dts = av_rescale_q_rnd(pkt.dts + (1LL<st->pts_wrap_bits), + int64_t wrap_dts = av_rescale_q_rnd(pkt->dts + (1LL<st->pts_wrap_bits), ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - ist->next_dts)/10) @@ -4452,46 +4567,51 @@ static int process_input(int file_index) ist->file_index, ist->st->index, ist->st->id, av_get_media_type_string(ist->dec_ctx->codec_type), delta, ifile->ts_offset); - pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); - if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); + pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); } } else { if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE || delta > 1LL*dts_error_threshold*AV_TIME_BASE) { - av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt.dts, ist->next_dts, pkt.stream_index); - pkt.dts = AV_NOPTS_VALUE; + av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt->dts, ist->next_dts, pkt->stream_index); + pkt->dts = AV_NOPTS_VALUE; } - if (pkt.pts != AV_NOPTS_VALUE){ - int64_t pkt_pts = av_rescale_q(pkt.pts, ist->st->time_base, AV_TIME_BASE_Q); + if (pkt->pts != AV_NOPTS_VALUE){ + int64_t pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q); delta = pkt_pts - ist->next_dts; if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE || delta > 1LL*dts_error_threshold*AV_TIME_BASE) { - av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt.pts, ist->next_dts, pkt.stream_index); - pkt.pts = AV_NOPTS_VALUE; + av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt->pts, ist->next_dts, pkt->stream_index); + pkt->pts = AV_NOPTS_VALUE; } } } } - if (pkt.dts != AV_NOPTS_VALUE) - ifile->last_ts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q); + if (pkt->dts != AV_NOPTS_VALUE) + ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); if (debug_ts) { av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%s off_time:%s\n", - ifile->ist_index + pkt.stream_index, av_get_media_type_string(ist->dec_ctx->codec_type), - av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ist->st->time_base), - av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ist->st->time_base), + ifile->ist_index + pkt->stream_index, av_get_media_type_string(ist->dec_ctx->codec_type), + av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base), + av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base), av_ts2str(input_files[ist->file_index]->ts_offset), av_ts2timestr(input_files[ist->file_index]->ts_offset, &AV_TIME_BASE_Q)); } - sub2video_heartbeat(ist, pkt.pts); + sub2video_heartbeat(ist, pkt->pts); - process_input_packet(ist, &pkt, 0); + process_input_packet(ist, pkt, 0); discard_packet: - av_packet_unref(&pkt); +#if HAVE_THREADS + if (ifile->thread_queue_size) + av_packet_free(&pkt); + else +#endif + av_packet_unref(pkt); return 0; } @@ -4577,15 +4697,30 @@ static int transcode_step(void) } if (ost->filter && ost->filter->graph->graph) { - if (!ost->initialized) { - char error[1024] = {0}; - ret = init_output_stream(ost, error, sizeof(error)); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error initializing output stream %d:%d -- %s\n", - ost->file_index, ost->index, error); - exit_program(1); - } - } + /* + * Similar case to the early audio initialization in reap_filters. + * Audio is special in ffmpeg.c currently as we depend on lavfi's + * audio frame buffering/creation to get the output audio frame size + * in samples correct. The audio frame size for the filter chain is + * configured during the output stream initialization. + * + * Apparently avfilter_graph_request_oldest (called in + * transcode_from_filter just down the line) peeks. Peeking already + * puts one frame "ready to be given out", which means that any + * update in filter buffer sink configuration afterwards will not + * help us. And yes, even if it would be utilized, + * av_buffersink_get_samples is affected, as it internally utilizes + * the same early exit for peeked frames. + * + * In other words, if avfilter_graph_request_oldest would not make + * further filter chain configuration or usage of + * av_buffersink_get_samples useless (by just causing the return + * of the peeked AVFrame as-is), we could get rid of this additional + * early encoder initialization. + */ + if (av_buffersink_get_type(ost->filter->filter) == AVMEDIA_TYPE_AUDIO) + init_output_stream_wrapper(ost, NULL, 1); + if ((ret = transcode_from_filter(ost->filter->graph, &ist)) < 0) return ret; if (!ist) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 828cb2a4f..606f2afe0 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -108,6 +108,8 @@ typedef struct OptionsContext { int nb_audio_sample_rate; SpecifierOpt *frame_rates; int nb_frame_rates; + SpecifierOpt *max_frame_rates; + int nb_max_frame_rates; SpecifierOpt *frame_sizes; int nb_frame_sizes; SpecifierOpt *frame_pix_fmts; @@ -215,6 +217,8 @@ typedef struct OptionsContext { int nb_passlogfiles; SpecifierOpt *max_muxing_queue_size; int nb_max_muxing_queue_size; + SpecifierOpt *muxing_queue_data_threshold; + int nb_muxing_queue_data_threshold; SpecifierOpt *guess_layout_max; int nb_guess_layout_max; SpecifierOpt *apad; @@ -229,6 +233,8 @@ typedef struct OptionsContext { int nb_time_bases; SpecifierOpt *enc_time_bases; int nb_enc_time_bases; + SpecifierOpt *autoscale; + int nb_autoscale; } OptionsContext; typedef struct InputFilter { @@ -301,9 +307,10 @@ typedef struct InputStream { #define DECODING_FOR_FILTER 2 AVCodecContext *dec_ctx; - AVCodec *dec; + const AVCodec *dec; AVFrame *decoded_frame; AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */ + AVPacket *pkt; int64_t start; /* time when read started */ /* predicted dts of the next packet read for this stream or (when there are @@ -412,6 +419,8 @@ typedef struct InputFile { int rate_emu; int accurate_seek; + AVPacket *pkt; + #if HAVE_THREADS AVThreadMessageQueue *in_thread_queue; pthread_t thread; /* thread reading from this file */ @@ -464,10 +473,11 @@ typedef struct OutputStream { AVCodecContext *enc_ctx; AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */ - AVCodec *enc; + const AVCodec *enc; int64_t max_frames; AVFrame *filtered_frame; AVFrame *last_frame; + AVPacket *pkt; int last_dropped; int last_nb0_frames[3]; @@ -475,10 +485,12 @@ typedef struct OutputStream { /* video only */ AVRational frame_rate; + AVRational max_frame_rate; int is_cfr; int force_fps; int top_field_first; int rotate_overridden; + int autoscale; double rotate_override_value; AVRational frame_aspect_ratio; @@ -544,6 +556,15 @@ typedef struct OutputStream { /* the packets are buffered here until the muxer is ready to be initialized */ AVFifoBuffer *muxing_queue; + /* + * The size of the AVPackets' buffers in queue. + * Updated when a packet is either pushed or pulled from the queue. + */ + size_t muxing_queue_data_size; + + /* Threshold after which max_muxing_queue_size will be in effect */ + size_t muxing_queue_data_threshold; + /* packet picture type */ int pict_type; @@ -600,6 +621,7 @@ extern int debug_ts; extern int exit_on_error; extern int abort_on_flags; extern int print_stats; +extern int64_t stats_period; extern int qp_hist; extern int stdin_interaction; extern int frame_bits_per_raw_sample; @@ -610,6 +632,7 @@ extern char *videotoolbox_pixfmt; extern int filter_nbthreads; extern int filter_complex_nbthreads; extern int vstats_version; +extern int auto_conversion_filters; extern const AVIOInterruptCB int_cb; @@ -624,23 +647,15 @@ extern HWDevice *filter_hw_device; void term_init(void); void term_exit(void); -void reset_options(OptionsContext *o, int is_input); void show_usage(void); -void opt_output_file(void *optctx, const char *filename); - void remove_avoptions(AVDictionary **a, AVDictionary *b); void assert_avoptions(AVDictionary *m); int guess_input_channel_layout(InputStream *ist); -enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *avctx, AVCodec *codec, enum AVPixelFormat target); -void choose_sample_fmt(AVStream *st, AVCodec *codec); - int configure_filtergraph(FilterGraph *fg); -int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out); void check_filter_outputs(void); -int ist_in_filtergraph(FilterGraph *fg, InputStream *ist); int filtergraph_is_simple(FilterGraph *fg); int init_simple_filtergraph(InputStream *ist, OutputStream *ost); int init_complex_filtergraph(FilterGraph *fg); diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 422e1268e..4ab769c07 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -60,7 +60,8 @@ static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum AVCodec } } -enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCodec *codec, enum AVPixelFormat target) +static enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, + const AVCodec *codec, enum AVPixelFormat target) { if (codec && codec->pix_fmts) { const enum AVPixelFormat *p = codec->pix_fmts; @@ -73,7 +74,7 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCod p = get_compliance_unofficial_pix_fmts(enc_ctx->codec_id, p); } for (; *p != AV_PIX_FMT_NONE; p++) { - best= avcodec_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL); + best = av_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL); if (*p == target) break; } @@ -90,29 +91,6 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCod return target; } -void choose_sample_fmt(AVStream *st, AVCodec *codec) -{ - if (codec && codec->sample_fmts) { - const enum AVSampleFormat *p = codec->sample_fmts; - for (; *p != -1; p++) { - if (*p == st->codecpar->format) - break; - } - if (*p == -1) { - const AVCodecDescriptor *desc = avcodec_descriptor_get(codec->id); - if(desc && (desc->props & AV_CODEC_PROP_LOSSLESS) && av_get_sample_fmt_name(st->codecpar->format) > av_get_sample_fmt_name(codec->sample_fmts[0])) - av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n"); - if(av_get_sample_fmt_name(st->codecpar->format)) - av_log(NULL, AV_LOG_WARNING, - "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n", - av_get_sample_fmt_name(st->codecpar->format), - codec->name, - av_get_sample_fmt_name(codec->sample_fmts[0])); - st->codecpar->format = codec->sample_fmts[0]; - } - } -} - static char *choose_pix_fmts(OutputFilter *ofilter) { OutputStream *ost = ofilter->ost; @@ -470,7 +448,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, if (ret < 0) return ret; - if (ofilter->width || ofilter->height) { + if ((ofilter->width || ofilter->height) && ofilter->ost->autoscale) { char args[255]; AVFilterContext *filter; AVDictionaryEntry *e = NULL; @@ -640,13 +618,6 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, pad_idx = 0; } - if (audio_volume != 256 && 0) { - char args[256]; - - snprintf(args, sizeof(args), "%f", audio_volume / 256.); - AUTO_INSERT_FILTER("-vol", "volume", args); - } - if (ost->apad && of->shortest) { char args[256]; int i; @@ -674,7 +645,8 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, return 0; } -int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out) +static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, + AVFilterInOut *out) { if (!ofilter->ost) { av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", ofilter->name); @@ -1104,6 +1076,8 @@ int configure_filtergraph(FilterGraph *fg) configure_output_filter(fg, fg->outputs[i], cur); avfilter_inout_free(&outputs); + if (!auto_conversion_filters) + avfilter_graph_set_auto_convert(fg->graph, AVFILTER_AUTO_CONVERT_NONE); if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) goto fail; @@ -1203,15 +1177,6 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame) return 0; } -int ist_in_filtergraph(FilterGraph *fg, InputStream *ist) -{ - int i; - for (i = 0; i < fg->nb_inputs; i++) - if (fg->inputs[i]->ist == ist) - return 1; - return 0; -} - int filtergraph_is_simple(FilterGraph *fg) { return !fg->graph_desc; diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 2eb4e1c97..807e78342 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -51,47 +51,50 @@ #define SPECIFIER_OPT_FMT_f "%f" #define SPECIFIER_OPT_FMT_dbl "%lf" -static const char *opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL}; -static const char *opt_name_audio_channels[] = {"ac", NULL}; -static const char *opt_name_audio_sample_rate[] = {"ar", NULL}; -static const char *opt_name_frame_rates[] = {"r", NULL}; -static const char *opt_name_frame_sizes[] = {"s", NULL}; -static const char *opt_name_frame_pix_fmts[] = {"pix_fmt", NULL}; -static const char *opt_name_ts_scale[] = {"itsscale", NULL}; -static const char *opt_name_hwaccels[] = {"hwaccel", NULL}; -static const char *opt_name_hwaccel_devices[] = {"hwaccel_device", NULL}; -static const char *opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL}; -static const char *opt_name_autorotate[] = {"autorotate", NULL}; -static const char *opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL}; -static const char *opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL}; -static const char *opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL}; -static const char *opt_name_sample_fmts[] = {"sample_fmt", NULL}; -static const char *opt_name_qscale[] = {"q", "qscale", NULL}; -static const char *opt_name_forced_key_frames[] = {"forced_key_frames", NULL}; -static const char *opt_name_force_fps[] = {"force_fps", NULL}; -static const char *opt_name_frame_aspect_ratios[] = {"aspect", NULL}; -static const char *opt_name_rc_overrides[] = {"rc_override", NULL}; -static const char *opt_name_intra_matrices[] = {"intra_matrix", NULL}; -static const char *opt_name_inter_matrices[] = {"inter_matrix", NULL}; -static const char *opt_name_chroma_intra_matrices[] = {"chroma_intra_matrix", NULL}; -static const char *opt_name_top_field_first[] = {"top", NULL}; -static const char *opt_name_presets[] = {"pre", "apre", "vpre", "spre", NULL}; -static const char *opt_name_copy_initial_nonkeyframes[] = {"copyinkfr", NULL}; -static const char *opt_name_copy_prior_start[] = {"copypriorss", NULL}; -static const char *opt_name_filters[] = {"filter", "af", "vf", NULL}; -static const char *opt_name_filter_scripts[] = {"filter_script", NULL}; -static const char *opt_name_reinit_filters[] = {"reinit_filter", NULL}; -static const char *opt_name_fix_sub_duration[] = {"fix_sub_duration", NULL}; -static const char *opt_name_canvas_sizes[] = {"canvas_size", NULL}; -static const char *opt_name_pass[] = {"pass", NULL}; -static const char *opt_name_passlogfiles[] = {"passlogfile", NULL}; -static const char *opt_name_max_muxing_queue_size[] = {"max_muxing_queue_size", NULL}; -static const char *opt_name_guess_layout_max[] = {"guess_layout_max", NULL}; -static const char *opt_name_apad[] = {"apad", NULL}; -static const char *opt_name_discard[] = {"discard", NULL}; -static const char *opt_name_disposition[] = {"disposition", NULL}; -static const char *opt_name_time_bases[] = {"time_base", NULL}; -static const char *opt_name_enc_time_bases[] = {"enc_time_base", NULL}; +static const char *const opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL}; +static const char *const opt_name_audio_channels[] = {"ac", NULL}; +static const char *const opt_name_audio_sample_rate[] = {"ar", NULL}; +static const char *const opt_name_frame_rates[] = {"r", NULL}; +static const char *const opt_name_max_frame_rates[] = {"fpsmax", NULL}; +static const char *const opt_name_frame_sizes[] = {"s", NULL}; +static const char *const opt_name_frame_pix_fmts[] = {"pix_fmt", NULL}; +static const char *const opt_name_ts_scale[] = {"itsscale", NULL}; +static const char *const opt_name_hwaccels[] = {"hwaccel", NULL}; +static const char *const opt_name_hwaccel_devices[] = {"hwaccel_device", NULL}; +static const char *const opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL}; +static const char *const opt_name_autorotate[] = {"autorotate", NULL}; +static const char *const opt_name_autoscale[] = {"autoscale", NULL}; +static const char *const opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL}; +static const char *const opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL}; +static const char *const opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL}; +static const char *const opt_name_sample_fmts[] = {"sample_fmt", NULL}; +static const char *const opt_name_qscale[] = {"q", "qscale", NULL}; +static const char *const opt_name_forced_key_frames[] = {"forced_key_frames", NULL}; +static const char *const opt_name_force_fps[] = {"force_fps", NULL}; +static const char *const opt_name_frame_aspect_ratios[] = {"aspect", NULL}; +static const char *const opt_name_rc_overrides[] = {"rc_override", NULL}; +static const char *const opt_name_intra_matrices[] = {"intra_matrix", NULL}; +static const char *const opt_name_inter_matrices[] = {"inter_matrix", NULL}; +static const char *const opt_name_chroma_intra_matrices[] = {"chroma_intra_matrix", NULL}; +static const char *const opt_name_top_field_first[] = {"top", NULL}; +static const char *const opt_name_presets[] = {"pre", "apre", "vpre", "spre", NULL}; +static const char *const opt_name_copy_initial_nonkeyframes[] = {"copyinkfr", NULL}; +static const char *const opt_name_copy_prior_start[] = {"copypriorss", NULL}; +static const char *const opt_name_filters[] = {"filter", "af", "vf", NULL}; +static const char *const opt_name_filter_scripts[] = {"filter_script", NULL}; +static const char *const opt_name_reinit_filters[] = {"reinit_filter", NULL}; +static const char *const opt_name_fix_sub_duration[] = {"fix_sub_duration", NULL}; +static const char *const opt_name_canvas_sizes[] = {"canvas_size", NULL}; +static const char *const opt_name_pass[] = {"pass", NULL}; +static const char *const opt_name_passlogfiles[] = {"passlogfile", NULL}; +static const char *const opt_name_max_muxing_queue_size[] = {"max_muxing_queue_size", NULL}; +static const char *const opt_name_muxing_queue_data_threshold[] = {"muxing_queue_data_threshold", NULL}; +static const char *const opt_name_guess_layout_max[] = {"guess_layout_max", NULL}; +static const char *const opt_name_apad[] = {"apad", NULL}; +static const char *const opt_name_discard[] = {"discard", NULL}; +static const char *const opt_name_disposition[] = {"disposition", NULL}; +static const char *const opt_name_time_bases[] = {"time_base", NULL}; +static const char *const opt_name_enc_time_bases[] = {"enc_time_base", NULL}; #define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\ {\ @@ -171,6 +174,8 @@ float max_error_rate = 2.0/3; int filter_nbthreads = 0; int filter_complex_nbthreads = 0; int vstats_version = 2; +int auto_conversion_filters = 1; +int64_t stats_period = 500000; static int intra_only = 0; @@ -227,6 +232,7 @@ static void init_options(OptionsContext *o) o->limit_filesize = UINT64_MAX; o->chapters_input_file = INT_MAX; o->accurate_seek = 1; + o->thread_queue_size = -1; } static int show_hwaccels(void *optctx, const char *opt, const char *arg) @@ -278,6 +284,21 @@ static int opt_abort_on(void *optctx, const char *opt, const char *arg) return av_opt_eval_flags(&pclass, &opts[0], arg, &abort_on_flags); } +static int opt_stats_period(void *optctx, const char *opt, const char *arg) +{ + int64_t user_stats_period = parse_time_or_die(opt, arg, 1); + + if (user_stats_period <= 0) { + av_log(NULL, AV_LOG_ERROR, "stats_period %s must be positive.\n", arg); + return AVERROR(EINVAL); + } + + stats_period = user_stats_period; + av_log(NULL, AV_LOG_INFO, "ffmpeg stats and -progress period set to %s.\n", arg); + + return 0; +} + static int opt_sameq(void *optctx, const char *opt, const char *arg) { av_log(NULL, AV_LOG_ERROR, "Option '%s' was removed. " @@ -745,13 +766,13 @@ static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int e return codec; } -static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st) +static const AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st) { char *codec_name = NULL; MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st); if (codec_name) { - AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0); + const AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0); st->codecpar->codec_id = codec->id; return codec; } else @@ -847,15 +868,6 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) case AVMEDIA_TYPE_VIDEO: if(!ist->dec) ist->dec = avcodec_find_decoder(par->codec_id); -#if FF_API_LOWRES - if (st->codec->lowres) { - ist->dec_ctx->lowres = st->codec->lowres; - ist->dec_ctx->width = st->codec->width; - ist->dec_ctx->height = st->codec->height; - ist->dec_ctx->coded_width = st->codec->coded_width; - ist->dec_ctx->coded_height = st->codec->coded_height; - } -#endif // avformat_find_stream_info() doesn't set this for us anymore. ist->dec_ctx->framerate = st->avg_frame_rate; @@ -1268,8 +1280,11 @@ static int open_input_file(OptionsContext *o, const char *filename) f->loop = o->loop; f->duration = 0; f->time_base = (AVRational){ 1, 1 }; + f->pkt = av_packet_alloc(); + if (!f->pkt) + exit_program(1); #if HAVE_THREADS - f->thread_queue_size = o->thread_queue_size > 0 ? o->thread_queue_size : 8; + f->thread_queue_size = o->thread_queue_size; #endif /* check if all codec options have been used */ @@ -1462,6 +1477,8 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc); MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); + ost->autoscale = 1; + MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st); if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) { do { buf = get_line(s); @@ -1557,7 +1574,12 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->max_muxing_queue_size = 128; MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st); - ost->max_muxing_queue_size *= sizeof(AVPacket); + ost->max_muxing_queue_size *= sizeof(ost->pkt); + + ost->muxing_queue_data_size = 0; + + ost->muxing_queue_data_threshold = 50*1024*1024; + MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, ost->muxing_queue_data_threshold, oc, st); if (oc->oformat->flags & AVFMT_GLOBALHEADER) ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; @@ -1670,7 +1692,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in AVStream *st; OutputStream *ost; AVCodecContext *video_enc; - char *frame_rate = NULL, *frame_aspect_ratio = NULL; + char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL; ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index); st = ost->st; @@ -1681,8 +1703,21 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate); exit_program(1); } - if (frame_rate && video_sync_method == VSYNC_PASSTHROUGH) - av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r can produce invalid output files\n"); + + MATCH_PER_STREAM_OPT(max_frame_rates, str, max_frame_rate, oc, st); + if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, max_frame_rate) < 0) { + av_log(NULL, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate); + exit_program(1); + } + + if (frame_rate && max_frame_rate) { + av_log(NULL, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n"); + exit_program(1); + } + + if ((frame_rate || max_frame_rate) && + video_sync_method == VSYNC_PASSTHROUGH) + av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r/-fpsmax can produce invalid output files\n"); MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st); if (frame_aspect_ratio) { @@ -2205,22 +2240,23 @@ static int open_output_file(OptionsContext *o, const char *filename) /* video: highest resolution */ if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) { - int area = 0, idx = -1; + int best_score = 0, idx = -1; int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0); for (i = 0; i < nb_input_streams; i++) { - int new_area; + int score; ist = input_streams[i]; - new_area = ist->st->codecpar->width * ist->st->codecpar->height + 100000000*!!ist->st->codec_info_nb_frames + score = ist->st->codecpar->width * ist->st->codecpar->height + + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS) + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT); if (ist->user_set_discard == AVDISCARD_ALL) continue; if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) - new_area = 1; + score = 1; if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && - new_area > area) { + score > best_score) { if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) continue; - area = new_area; + best_score = score; idx = i; } } @@ -2622,6 +2658,9 @@ loop_end: if(o->recording_time != INT64_MAX) av_dict_set(&oc->metadata, "duration", NULL, 0); av_dict_set(&oc->metadata, "creation_time", NULL, 0); + av_dict_set(&oc->metadata, "company_name", NULL, 0); + av_dict_set(&oc->metadata, "product_name", NULL, 0); + av_dict_set(&oc->metadata, "product_version", NULL, 0); } if (!o->metadata_streams_manual) for (i = of->ost_index; i < nb_output_streams; i++) { @@ -3541,8 +3580,12 @@ const OptionDef options[] = { "create a complex filtergraph", "graph_description" }, { "filter_complex_script", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex_script }, "read complex filtergraph description from a file", "filename" }, + { "auto_conversion_filters", OPT_BOOL | OPT_EXPERT, { &auto_conversion_filters }, + "enable automatic conversion filters globally" }, { "stats", OPT_BOOL, { &print_stats }, "print progress report during encoding", }, + { "stats_period", HAS_ARG | OPT_EXPERT, { .func_arg = opt_stats_period }, + "set the period at which ffmpeg updates stats and -progress output", "time" }, { "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT | OPT_OUTPUT, { .func_arg = opt_attach }, "add an attachment to the output file", "filename" }, @@ -3554,7 +3597,7 @@ const OptionDef options[] = { { "debug_ts", OPT_BOOL | OPT_EXPERT, { &debug_ts }, "print timestamp debugging info" }, { "max_error_rate", HAS_ARG | OPT_FLOAT, { &max_error_rate }, - "ratio of errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success.", "maximum error rate" }, + "ratio of decoding errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success.", "maximum error rate" }, { "discard", OPT_STRING | HAS_ARG | OPT_SPEC | OPT_INPUT, { .off = OFFSET(discard) }, "discard", "" }, @@ -3573,6 +3616,9 @@ const OptionDef options[] = { { "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_rates) }, "set frame rate (Hz value, fraction or abbreviation)", "rate" }, + { "fpsmax", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC | + OPT_OUTPUT, { .off = OFFSET(max_frame_rates) }, + "set max frame rate (Hz value, fraction or abbreviation)", "rate" }, { "s", OPT_VIDEO | HAS_ARG | OPT_SUBTITLE | OPT_STRING | OPT_SPEC | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_sizes) }, "set frame size (WxH or abbreviation)", "size" }, @@ -3664,6 +3710,9 @@ const OptionDef options[] = { { "autorotate", HAS_ARG | OPT_BOOL | OPT_SPEC | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(autorotate) }, "automatically insert correct rotate filters" }, + { "autoscale", HAS_ARG | OPT_BOOL | OPT_SPEC | + OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(autoscale) }, + "automatically insert a scale filter at the end of the filter graph" }, /* audio options */ { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames }, @@ -3750,6 +3799,8 @@ const OptionDef options[] = { { "max_muxing_queue_size", HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(max_muxing_queue_size) }, "maximum number of packets that can be buffered while waiting for all streams to initialize", "packets" }, + { "muxing_queue_data_threshold", HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(muxing_queue_data_threshold) }, + "set the threshold after which max_muxing_queue_size is taken into account", "bytes" }, /* data codec support */ { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec }, diff --git a/fftools/ffplay.c b/fftools/ffplay.c index d673b8049..e14c800b8 100644 --- a/fftools/ffplay.c +++ b/fftools/ffplay.c @@ -36,6 +36,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" #include "libavutil/dict.h" +#include "libavutil/fifo.h" #include "libavutil/parseutils.h" #include "libavutil/samplefmt.h" #include "libavutil/avassert.h" @@ -111,13 +112,12 @@ const int program_birth_year = 2003; static unsigned sws_flags = SWS_BICUBIC; typedef struct MyAVPacketList { - AVPacket pkt; - struct MyAVPacketList *next; + AVPacket *pkt; int serial; } MyAVPacketList; typedef struct PacketQueue { - MyAVPacketList *first_pkt, *last_pkt; + AVFifoBuffer *pkt_list; int nb_packets; int size; int64_t duration; @@ -187,7 +187,7 @@ enum { }; typedef struct Decoder { - AVPacket pkt; + AVPacket *pkt; PacketQueue *queue; AVCodecContext *avctx; int pkt_serial; @@ -361,8 +361,6 @@ static int filter_nbthreads = 0; static int is_full_screen; static int64_t audio_callback_time; -static AVPacket flush_pkt; - #define FF_QUIT_EVENT (SDL_USEREVENT + 2) static SDL_Window *window; @@ -427,28 +425,23 @@ int64_t get_valid_channel_layout(int64_t channel_layout, int channels) static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt) { - MyAVPacketList *pkt1; + MyAVPacketList pkt1; if (q->abort_request) return -1; - pkt1 = av_malloc(sizeof(MyAVPacketList)); - if (!pkt1) - return -1; - pkt1->pkt = *pkt; - pkt1->next = NULL; - if (pkt == &flush_pkt) - q->serial++; - pkt1->serial = q->serial; + if (av_fifo_space(q->pkt_list) < sizeof(pkt1)) { + if (av_fifo_grow(q->pkt_list, sizeof(pkt1)) < 0) + return -1; + } - if (!q->last_pkt) - q->first_pkt = pkt1; - else - q->last_pkt->next = pkt1; - q->last_pkt = pkt1; + pkt1.pkt = pkt; + pkt1.serial = q->serial; + + av_fifo_generic_write(q->pkt_list, &pkt1, sizeof(pkt1), NULL); q->nb_packets++; - q->size += pkt1->pkt.size + sizeof(*pkt1); - q->duration += pkt1->pkt.duration; + q->size += pkt1.pkt->size + sizeof(pkt1); + q->duration += pkt1.pkt->duration; /* XXX: should duplicate packet data in DV case */ SDL_CondSignal(q->cond); return 0; @@ -456,24 +449,28 @@ static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt) static int packet_queue_put(PacketQueue *q, AVPacket *pkt) { + AVPacket *pkt1; int ret; + pkt1 = av_packet_alloc(); + if (!pkt1) { + av_packet_unref(pkt); + return -1; + } + av_packet_move_ref(pkt1, pkt); + SDL_LockMutex(q->mutex); - ret = packet_queue_put_private(q, pkt); + ret = packet_queue_put_private(q, pkt1); SDL_UnlockMutex(q->mutex); - if (pkt != &flush_pkt && ret < 0) - av_packet_unref(pkt); + if (ret < 0) + av_packet_free(&pkt1); return ret; } -static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index) +static int packet_queue_put_nullpacket(PacketQueue *q, AVPacket *pkt, int stream_index) { - AVPacket pkt1, *pkt = &pkt1; - av_init_packet(pkt); - pkt->data = NULL; - pkt->size = 0; pkt->stream_index = stream_index; return packet_queue_put(q, pkt); } @@ -482,6 +479,9 @@ static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index) static int packet_queue_init(PacketQueue *q) { memset(q, 0, sizeof(PacketQueue)); + q->pkt_list = av_fifo_alloc(sizeof(MyAVPacketList)); + if (!q->pkt_list) + return AVERROR(ENOMEM); q->mutex = SDL_CreateMutex(); if (!q->mutex) { av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError()); @@ -498,25 +498,24 @@ static int packet_queue_init(PacketQueue *q) static void packet_queue_flush(PacketQueue *q) { - MyAVPacketList *pkt, *pkt1; + MyAVPacketList pkt1; SDL_LockMutex(q->mutex); - for (pkt = q->first_pkt; pkt; pkt = pkt1) { - pkt1 = pkt->next; - av_packet_unref(&pkt->pkt); - av_freep(&pkt); + while (av_fifo_size(q->pkt_list) >= sizeof(pkt1)) { + av_fifo_generic_read(q->pkt_list, &pkt1, sizeof(pkt1), NULL); + av_packet_free(&pkt1.pkt); } - q->last_pkt = NULL; - q->first_pkt = NULL; q->nb_packets = 0; q->size = 0; q->duration = 0; + q->serial++; SDL_UnlockMutex(q->mutex); } static void packet_queue_destroy(PacketQueue *q) { packet_queue_flush(q); + av_fifo_freep(&q->pkt_list); SDL_DestroyMutex(q->mutex); SDL_DestroyCond(q->cond); } @@ -536,14 +535,14 @@ static void packet_queue_start(PacketQueue *q) { SDL_LockMutex(q->mutex); q->abort_request = 0; - packet_queue_put_private(q, &flush_pkt); + q->serial++; SDL_UnlockMutex(q->mutex); } /* return < 0 if aborted, 0 if no packet and > 0 if packet. */ static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial) { - MyAVPacketList *pkt1; + MyAVPacketList pkt1; int ret; SDL_LockMutex(q->mutex); @@ -554,18 +553,15 @@ static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *seria break; } - pkt1 = q->first_pkt; - if (pkt1) { - q->first_pkt = pkt1->next; - if (!q->first_pkt) - q->last_pkt = NULL; + if (av_fifo_size(q->pkt_list) >= sizeof(pkt1)) { + av_fifo_generic_read(q->pkt_list, &pkt1, sizeof(pkt1), NULL); q->nb_packets--; - q->size -= pkt1->pkt.size + sizeof(*pkt1); - q->duration -= pkt1->pkt.duration; - *pkt = pkt1->pkt; + q->size -= pkt1.pkt->size + sizeof(pkt1); + q->duration -= pkt1.pkt->duration; + av_packet_move_ref(pkt, pkt1.pkt); if (serial) - *serial = pkt1->serial; - av_free(pkt1); + *serial = pkt1.serial; + av_packet_free(&pkt1.pkt); ret = 1; break; } else if (!block) { @@ -579,21 +575,23 @@ static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *seria return ret; } -static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) { +static int decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) { memset(d, 0, sizeof(Decoder)); + d->pkt = av_packet_alloc(); + if (!d->pkt) + return AVERROR(ENOMEM); d->avctx = avctx; d->queue = queue; d->empty_queue_cond = empty_queue_cond; d->start_pts = AV_NOPTS_VALUE; d->pkt_serial = -1; + return 0; } static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) { int ret = AVERROR(EAGAIN); for (;;) { - AVPacket pkt; - if (d->queue->serial == d->pkt_serial) { do { if (d->queue->abort_request) @@ -639,49 +637,48 @@ static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) { if (d->queue->nb_packets == 0) SDL_CondSignal(d->empty_queue_cond); if (d->packet_pending) { - av_packet_move_ref(&pkt, &d->pkt); d->packet_pending = 0; } else { - if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0) + int old_serial = d->pkt_serial; + if (packet_queue_get(d->queue, d->pkt, 1, &d->pkt_serial) < 0) return -1; + if (old_serial != d->pkt_serial) { + avcodec_flush_buffers(d->avctx); + d->finished = 0; + d->next_pts = d->start_pts; + d->next_pts_tb = d->start_pts_tb; + } } if (d->queue->serial == d->pkt_serial) break; - av_packet_unref(&pkt); + av_packet_unref(d->pkt); } while (1); - if (pkt.data == flush_pkt.data) { - avcodec_flush_buffers(d->avctx); - d->finished = 0; - d->next_pts = d->start_pts; - d->next_pts_tb = d->start_pts_tb; - } else { - if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) { - int got_frame = 0; - ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt); - if (ret < 0) { - ret = AVERROR(EAGAIN); - } else { - if (got_frame && !pkt.data) { - d->packet_pending = 1; - av_packet_move_ref(&d->pkt, &pkt); - } - ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF); - } + if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) { + int got_frame = 0; + ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, d->pkt); + if (ret < 0) { + ret = AVERROR(EAGAIN); } else { - if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) { - av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n"); + if (got_frame && !d->pkt->data) { d->packet_pending = 1; - av_packet_move_ref(&d->pkt, &pkt); } + ret = got_frame ? 0 : (d->pkt->data ? AVERROR(EAGAIN) : AVERROR_EOF); + } + av_packet_unref(d->pkt); + } else { + if (avcodec_send_packet(d->avctx, d->pkt) == AVERROR(EAGAIN)) { + av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n"); + d->packet_pending = 1; + } else { + av_packet_unref(d->pkt); } - av_packet_unref(&pkt); } } } static void decoder_destroy(Decoder *d) { - av_packet_unref(&d->pkt); + av_packet_free(&d->pkt); avcodec_free_context(&d->avctx); } @@ -1151,6 +1148,8 @@ static void video_audio_display(VideoState *s) if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0) return; + if (s->xpos >= s->width) + s->xpos = 0; nb_display_channels= FFMIN(nb_display_channels, 2); if (rdft_bits != s->rdft_bits) { av_rdft_end(s->rdft); @@ -1200,8 +1199,6 @@ static void video_audio_display(VideoState *s) } if (!s->paused) s->xpos++; - if (s->xpos >= s->width) - s->xpos= s->xleft; } } @@ -1647,37 +1644,37 @@ retry: } if (is->subtitle_st) { - while (frame_queue_nb_remaining(&is->subpq) > 0) { - sp = frame_queue_peek(&is->subpq); + while (frame_queue_nb_remaining(&is->subpq) > 0) { + sp = frame_queue_peek(&is->subpq); - if (frame_queue_nb_remaining(&is->subpq) > 1) - sp2 = frame_queue_peek_next(&is->subpq); - else - sp2 = NULL; + if (frame_queue_nb_remaining(&is->subpq) > 1) + sp2 = frame_queue_peek_next(&is->subpq); + else + sp2 = NULL; - if (sp->serial != is->subtitleq.serial - || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000))) - || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000)))) - { - if (sp->uploaded) { - int i; - for (i = 0; i < sp->sub.num_rects; i++) { - AVSubtitleRect *sub_rect = sp->sub.rects[i]; - uint8_t *pixels; - int pitch, j; + if (sp->serial != is->subtitleq.serial + || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000))) + || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000)))) + { + if (sp->uploaded) { + int i; + for (i = 0; i < sp->sub.num_rects; i++) { + AVSubtitleRect *sub_rect = sp->sub.rects[i]; + uint8_t *pixels; + int pitch, j; - if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) { - for (j = 0; j < sub_rect->h; j++, pixels += pitch) - memset(pixels, 0, sub_rect->w << 2); - SDL_UnlockTexture(is->sub_texture); - } + if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) { + for (j = 0; j < sub_rect->h; j++, pixels += pitch) + memset(pixels, 0, sub_rect->w << 2); + SDL_UnlockTexture(is->sub_texture); } } - frame_queue_next(&is->subpq); - } else { - break; } + frame_queue_next(&is->subpq); + } else { + break; } + } } frame_queue_next(&is->pictq); @@ -2008,7 +2005,7 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for if (force_output_format) { channel_layouts[0] = is->audio_tgt.channel_layout; - channels [0] = is->audio_tgt.channels; + channels [0] = is->audio_tgt.channel_layout ? -1 : is->audio_tgt.channels; sample_rates [0] = is->audio_tgt.freq; if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0) goto end; @@ -2576,7 +2573,7 @@ static int stream_component_open(VideoState *is, int stream_index) { AVFormatContext *ic = is->ic; AVCodecContext *avctx; - AVCodec *codec; + const AVCodec *codec; const char *forced_codec_name = NULL; AVDictionary *opts = NULL; AVDictionaryEntry *t = NULL; @@ -2631,8 +2628,6 @@ static int stream_component_open(VideoState *is, int stream_index) av_dict_set(&opts, "threads", "auto", 0); if (stream_lowres) av_dict_set_int(&opts, "lowres", stream_lowres, 0); - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO) - av_dict_set(&opts, "refcounted_frames", "1", 0); if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) { goto fail; } @@ -2685,7 +2680,8 @@ static int stream_component_open(VideoState *is, int stream_index) is->audio_stream = stream_index; is->audio_st = ic->streams[stream_index]; - decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread); + if ((ret = decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread)) < 0) + goto fail; if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) { is->auddec.start_pts = is->audio_st->start_time; is->auddec.start_pts_tb = is->audio_st->time_base; @@ -2698,7 +2694,8 @@ static int stream_component_open(VideoState *is, int stream_index) is->video_stream = stream_index; is->video_st = ic->streams[stream_index]; - decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread); + if ((ret = decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread)) < 0) + goto fail; if ((ret = decoder_start(&is->viddec, video_thread, "video_decoder", is)) < 0) goto out; is->queue_attachments_req = 1; @@ -2707,7 +2704,8 @@ static int stream_component_open(VideoState *is, int stream_index) is->subtitle_stream = stream_index; is->subtitle_st = ic->streams[stream_index]; - decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread); + if ((ret = decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread)) < 0) + goto fail; if ((ret = decoder_start(&is->subdec, subtitle_thread, "subtitle_decoder", is)) < 0) goto out; break; @@ -2760,7 +2758,7 @@ static int read_thread(void *arg) AVFormatContext *ic = NULL; int err, i, ret; int st_index[AVMEDIA_TYPE_NB]; - AVPacket pkt1, *pkt = &pkt1; + AVPacket *pkt = NULL; int64_t stream_start_time; int pkt_in_play_range = 0; AVDictionaryEntry *t; @@ -2777,6 +2775,12 @@ static int read_thread(void *arg) memset(st_index, -1, sizeof(st_index)); is->eof = 0; + pkt = av_packet_alloc(); + if (!pkt) { + av_log(NULL, AV_LOG_FATAL, "Could not allocate packet.\n"); + ret = AVERROR(ENOMEM); + goto fail; + } ic = avformat_alloc_context(); if (!ic) { av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n"); @@ -2960,18 +2964,12 @@ static int read_thread(void *arg) av_log(NULL, AV_LOG_ERROR, "%s: error while seeking\n", is->ic->url); } else { - if (is->audio_stream >= 0) { + if (is->audio_stream >= 0) packet_queue_flush(&is->audioq); - packet_queue_put(&is->audioq, &flush_pkt); - } - if (is->subtitle_stream >= 0) { + if (is->subtitle_stream >= 0) packet_queue_flush(&is->subtitleq); - packet_queue_put(&is->subtitleq, &flush_pkt); - } - if (is->video_stream >= 0) { + if (is->video_stream >= 0) packet_queue_flush(&is->videoq); - packet_queue_put(&is->videoq, &flush_pkt); - } if (is->seek_flags & AVSEEK_FLAG_BYTE) { set_clock(&is->extclk, NAN, 0); } else { @@ -2986,11 +2984,10 @@ static int read_thread(void *arg) } if (is->queue_attachments_req) { if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) { - AVPacket copy; - if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0) + if ((ret = av_packet_ref(pkt, &is->video_st->attached_pic)) < 0) goto fail; - packet_queue_put(&is->videoq, ©); - packet_queue_put_nullpacket(&is->videoq, is->video_stream); + packet_queue_put(&is->videoq, pkt); + packet_queue_put_nullpacket(&is->videoq, pkt, is->video_stream); } is->queue_attachments_req = 0; } @@ -3021,15 +3018,19 @@ static int read_thread(void *arg) if (ret < 0) { if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) { if (is->video_stream >= 0) - packet_queue_put_nullpacket(&is->videoq, is->video_stream); + packet_queue_put_nullpacket(&is->videoq, pkt, is->video_stream); if (is->audio_stream >= 0) - packet_queue_put_nullpacket(&is->audioq, is->audio_stream); + packet_queue_put_nullpacket(&is->audioq, pkt, is->audio_stream); if (is->subtitle_stream >= 0) - packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream); + packet_queue_put_nullpacket(&is->subtitleq, pkt, is->subtitle_stream); is->eof = 1; } - if (ic->pb && ic->pb->error) - break; + if (ic->pb && ic->pb->error) { + if (autoexit) + goto fail; + else + break; + } SDL_LockMutex(wait_mutex); SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10); SDL_UnlockMutex(wait_mutex); @@ -3062,6 +3063,7 @@ static int read_thread(void *arg) if (ic && !is->ic) avformat_close_input(&ic); + av_packet_free(&pkt); if (ret != 0) { SDL_Event event; @@ -3734,9 +3736,6 @@ int main(int argc, char **argv) SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); SDL_EventState(SDL_USEREVENT, SDL_IGNORE); - av_init_packet(&flush_pkt); - flush_pkt.data = (uint8_t *)&flush_pkt; - if (!display_disable) { int flags = SDL_WINDOW_HIDDEN; if (alwaysontop) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 5515e1b31..11e3cbd6c 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -35,6 +35,7 @@ #include "libavutil/bprint.h" #include "libavutil/display.h" #include "libavutil/hash.h" +#include "libavutil/hdr_dynamic_metadata.h" #include "libavutil/mastering_display_metadata.h" #include "libavutil/dovi_meta.h" #include "libavutil/opt.h" @@ -1671,24 +1672,6 @@ static av_cold int xml_init(WriterContext *wctx) return 0; } -static const char *xml_escape_str(AVBPrint *dst, const char *src, void *log_ctx) -{ - const char *p; - - for (p = src; *p; p++) { - switch (*p) { - case '&' : av_bprintf(dst, "%s", "&"); break; - case '<' : av_bprintf(dst, "%s", "<"); break; - case '>' : av_bprintf(dst, "%s", ">"); break; - case '"' : av_bprintf(dst, "%s", """); break; - case '\'': av_bprintf(dst, "%s", "'"); break; - default: av_bprint_chars(dst, *p, 1); - } - } - - return dst->str; -} - #define XML_INDENT() printf("%*c", xml->indent_level * 4, ' ') static void xml_print_section_header(WriterContext *wctx) @@ -1760,14 +1743,22 @@ static void xml_print_str(WriterContext *wctx, const char *key, const char *valu if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) { XML_INDENT(); + av_bprint_escape(&buf, key, NULL, + AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); printf("<%s key=\"%s\"", - section->element_name, xml_escape_str(&buf, key, wctx)); + section->element_name, buf.str); av_bprint_clear(&buf); - printf(" value=\"%s\"/>\n", xml_escape_str(&buf, value, wctx)); + + av_bprint_escape(&buf, value, NULL, + AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); + printf(" value=\"%s\"/>\n", buf.str); } else { if (wctx->nb_item[wctx->level]) printf(" "); - printf("%s=\"%s\"", key, xml_escape_str(&buf, value, wctx)); + + av_bprint_escape(&buf, value, NULL, + AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); + printf("%s=\"%s\"", key, buf.str); } av_bprint_finalize(&buf, NULL); @@ -1860,6 +1851,105 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id return ret; } +static void print_dynamic_hdr10_plus(WriterContext *w, const AVDynamicHDRPlus *metadata) +{ + if (!metadata) + return; + print_int("application version", metadata->application_version); + print_int("num_windows", metadata->num_windows); + for (int n = 1; n < metadata->num_windows; n++) { + const AVHDRPlusColorTransformParams *params = &metadata->params[n]; + print_q("window_upper_left_corner_x", + params->window_upper_left_corner_x,'/'); + print_q("window_upper_left_corner_y", + params->window_upper_left_corner_y,'/'); + print_q("window_lower_right_corner_x", + params->window_lower_right_corner_x,'/'); + print_q("window_lower_right_corner_y", + params->window_lower_right_corner_y,'/'); + print_q("window_upper_left_corner_x", + params->window_upper_left_corner_x,'/'); + print_q("window_upper_left_corner_y", + params->window_upper_left_corner_y,'/'); + print_int("center_of_ellipse_x", + params->center_of_ellipse_x ) ; + print_int("center_of_ellipse_y", + params->center_of_ellipse_y ); + print_int("rotation_angle", + params->rotation_angle); + print_int("semimajor_axis_internal_ellipse", + params->semimajor_axis_internal_ellipse); + print_int("semimajor_axis_external_ellipse", + params->semimajor_axis_external_ellipse); + print_int("semiminor_axis_external_ellipse", + params->semiminor_axis_external_ellipse); + print_int("overlap_process_option", + params->overlap_process_option); + } + print_q("targeted_system_display_maximum_luminance", + metadata->targeted_system_display_maximum_luminance,'/'); + if (metadata->targeted_system_display_actual_peak_luminance_flag) { + print_int("num_rows_targeted_system_display_actual_peak_luminance", + metadata->num_rows_targeted_system_display_actual_peak_luminance); + print_int("num_cols_targeted_system_display_actual_peak_luminance", + metadata->num_cols_targeted_system_display_actual_peak_luminance); + for (int i = 0; i < metadata->num_rows_targeted_system_display_actual_peak_luminance; i++) { + for (int j = 0; j < metadata->num_cols_targeted_system_display_actual_peak_luminance; j++) { + print_q("targeted_system_display_actual_peak_luminance", + metadata->targeted_system_display_actual_peak_luminance[i][j],'/'); + } + } + } + for (int n = 0; n < metadata->num_windows; n++) { + const AVHDRPlusColorTransformParams *params = &metadata->params[n]; + for (int i = 0; i < 3; i++) { + print_q("maxscl",params->maxscl[i],'/'); + } + print_q("average_maxrgb", + params->average_maxrgb,'/'); + print_int("num_distribution_maxrgb_percentiles", + params->num_distribution_maxrgb_percentiles); + for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) { + print_int("distribution_maxrgb_percentage", + params->distribution_maxrgb[i].percentage); + print_q("distribution_maxrgb_percentile", + params->distribution_maxrgb[i].percentile,'/'); + } + print_q("fraction_bright_pixels", + params->fraction_bright_pixels,'/'); + } + if (metadata->mastering_display_actual_peak_luminance_flag) { + print_int("num_rows_mastering_display_actual_peak_luminance", + metadata->num_rows_mastering_display_actual_peak_luminance); + print_int("num_cols_mastering_display_actual_peak_luminance", + metadata->num_cols_mastering_display_actual_peak_luminance); + for (int i = 0; i < metadata->num_rows_mastering_display_actual_peak_luminance; i++) { + for (int j = 0; j < metadata->num_cols_mastering_display_actual_peak_luminance; j++) { + print_q("mastering_display_actual_peak_luminance", + metadata->mastering_display_actual_peak_luminance[i][j],'/'); + } + } + } + + for (int n = 0; n < metadata->num_windows; n++) { + const AVHDRPlusColorTransformParams *params = &metadata->params[n]; + if (params->tone_mapping_flag) { + print_q("knee_point_x", params->knee_point_x,'/'); + print_q("knee_point_y", params->knee_point_y,'/'); + print_int("num_bezier_curve_anchors", + params->num_bezier_curve_anchors ); + for (int i = 0; i < params->num_bezier_curve_anchors; i++) { + print_q("bezier_curve_anchors", + params->bezier_curve_anchors[i],'/'); + } + } + if (params->color_saturation_mapping_flag) { + print_q("color_saturation_weight", + params->color_saturation_weight,'/'); + } + } +} + static void print_pkt_side_data(WriterContext *w, AVCodecParameters *par, const AVPacketSideData *side_data, @@ -2068,8 +2158,6 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p print_time("dts_time", pkt->dts, &st->time_base); print_duration_ts("duration", pkt->duration); print_duration_time("duration_time", pkt->duration, &st->time_base); - print_duration_ts("convergence_duration", pkt->convergence_duration); - print_duration_time("convergence_duration_time", pkt->convergence_duration, &st->time_base); print_val("size", pkt->size, unit_byte_str); if (pkt->pos != -1) print_fmt ("pos", "%"PRId64, pkt->pos); else print_str_opt("pos", "N/A"); @@ -2225,7 +2313,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST); for (int j = 1; j <= m ; j++) { char tcbuf[AV_TIMECODE_STR_SIZE]; - av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); + av_timecode_make_smpte_tc_string2(tcbuf, stream->avg_frame_rate, tc[j], 0, 0); writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE); print_str("value", tcbuf); writer_print_section_footer(w); @@ -2250,6 +2338,9 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, print_q("min_luminance", metadata->min_luminance, '/'); print_q("max_luminance", metadata->max_luminance, '/'); } + } else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_PLUS) { + AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data; + print_dynamic_hdr10_plus(w, metadata); } else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) { AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; print_int("max_content", metadata->MaxCLL); @@ -2362,14 +2453,12 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile, const ReadInterval *interval, int64_t *cur_ts) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; - AVPacket pkt; + AVPacket *pkt = NULL; AVFrame *frame = NULL; int ret = 0, i = 0, frame_count = 0; int64_t start = -INT64_MAX, end = interval->end; int has_start = 0, has_end = interval->has_end && !interval->end_is_offset; - av_init_packet(&pkt); - av_log(NULL, AV_LOG_VERBOSE, "Processing read interval "); log_read_interval(interval, NULL, AV_LOG_VERBOSE); @@ -2402,18 +2491,23 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile, ret = AVERROR(ENOMEM); goto end; } - while (!av_read_frame(fmt_ctx, &pkt)) { + pkt = av_packet_alloc(); + if (!pkt) { + ret = AVERROR(ENOMEM); + goto end; + } + while (!av_read_frame(fmt_ctx, pkt)) { if (fmt_ctx->nb_streams > nb_streams) { REALLOCZ_ARRAY_STREAM(nb_streams_frames, nb_streams, fmt_ctx->nb_streams); REALLOCZ_ARRAY_STREAM(nb_streams_packets, nb_streams, fmt_ctx->nb_streams); REALLOCZ_ARRAY_STREAM(selected_streams, nb_streams, fmt_ctx->nb_streams); nb_streams = fmt_ctx->nb_streams; } - if (selected_streams[pkt.stream_index]) { - AVRational tb = ifile->streams[pkt.stream_index].st->time_base; + if (selected_streams[pkt->stream_index]) { + AVRational tb = ifile->streams[pkt->stream_index].st->time_base; - if (pkt.pts != AV_NOPTS_VALUE) - *cur_ts = av_rescale_q(pkt.pts, tb, AV_TIME_BASE_Q); + if (pkt->pts != AV_NOPTS_VALUE) + *cur_ts = av_rescale_q(pkt->pts, tb, AV_TIME_BASE_Q); if (!has_start && *cur_ts != AV_NOPTS_VALUE) { start = *cur_ts; @@ -2435,26 +2529,27 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile, frame_count++; if (do_read_packets) { if (do_show_packets) - show_packet(w, ifile, &pkt, i++); - nb_streams_packets[pkt.stream_index]++; + show_packet(w, ifile, pkt, i++); + nb_streams_packets[pkt->stream_index]++; } if (do_read_frames) { int packet_new = 1; - while (process_frame(w, ifile, frame, &pkt, &packet_new) > 0); + while (process_frame(w, ifile, frame, pkt, &packet_new) > 0); } } - av_packet_unref(&pkt); + av_packet_unref(pkt); } - av_packet_unref(&pkt); + av_packet_unref(pkt); //Flush remaining frames that are cached in the decoder for (i = 0; i < fmt_ctx->nb_streams; i++) { - pkt.stream_index = i; + pkt->stream_index = i; if (do_read_frames) - while (process_frame(w, ifile, frame, &pkt, &(int){1}) > 0); + while (process_frame(w, ifile, frame, pkt, &(int){1}) > 0); } end: av_frame_free(&frame); + av_packet_free(&pkt); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Could not read packets in interval "); log_read_interval(interval, NULL, AV_LOG_ERROR); @@ -2530,10 +2625,6 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id s = av_get_media_type_string(par->codec_type); if (s) print_str ("codec_type", s); else print_str_opt("codec_type", "unknown"); -#if FF_API_LAVF_AVCTX - if (dec_ctx) - print_q("codec_time_base", dec_ctx->time_base, '/'); -#endif /* print AVI/FourCC tag */ print_str("codec_tag_string", av_fourcc2str(par->codec_tag)); @@ -2543,13 +2634,11 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id case AVMEDIA_TYPE_VIDEO: print_int("width", par->width); print_int("height", par->height); -#if FF_API_LAVF_AVCTX if (dec_ctx) { print_int("coded_width", dec_ctx->coded_width); print_int("coded_height", dec_ctx->coded_height); print_int("closed_captions", !!(dec_ctx->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS)); } -#endif print_int("has_b_frames", par->video_delay); sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, NULL); if (sar.num) { @@ -2587,15 +2676,6 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id else print_str_opt("field_order", "unknown"); -#if FF_API_PRIVATE_OPT - if (dec_ctx && dec_ctx->timecode_frame_start >= 0) { - char tcbuf[AV_TIMECODE_STR_SIZE]; - av_timecode_make_mpeg_tc_string(tcbuf, dec_ctx->timecode_frame_start); - print_str("timecode", tcbuf); - } else { - print_str_opt("timecode", "N/A"); - } -#endif if (dec_ctx) print_int("refs", dec_ctx->refs); break; @@ -2653,10 +2733,10 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id print_time("duration", stream->duration, &stream->time_base); if (par->bit_rate > 0) print_val ("bit_rate", par->bit_rate, unit_bit_per_second_str); else print_str_opt("bit_rate", "N/A"); -#if FF_API_LAVF_AVCTX - if (stream->codec->rc_max_rate > 0) print_val ("max_bit_rate", stream->codec->rc_max_rate, unit_bit_per_second_str); - else print_str_opt("max_bit_rate", "N/A"); -#endif + if (dec_ctx && dec_ctx->rc_max_rate > 0) + print_val ("max_bit_rate", dec_ctx->rc_max_rate, unit_bit_per_second_str); + else + print_str_opt("max_bit_rate", "N/A"); if (dec_ctx && dec_ctx->bits_per_raw_sample > 0) print_fmt("bits_per_raw_sample", "%d", dec_ctx->bits_per_raw_sample); else print_str_opt("bits_per_raw_sample", "N/A"); if (stream->nb_frames) print_fmt ("nb_frames", "%"PRId64, stream->nb_frames); @@ -2854,7 +2934,7 @@ static int open_input_file(InputFile *ifile, const char *filename, { int err, i; AVFormatContext *fmt_ctx = NULL; - AVDictionaryEntry *t; + AVDictionaryEntry *t = NULL; int scan_all_pmts_set = 0; fmt_ctx = avformat_alloc_context(); @@ -2879,10 +2959,8 @@ static int open_input_file(InputFile *ifile, const char *filename, ifile->fmt_ctx = fmt_ctx; if (scan_all_pmts_set) av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE); - if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { - av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); - return AVERROR_OPTION_NOT_FOUND; - } + while ((t = av_dict_get(format_opts, "", t, AV_DICT_IGNORE_SUFFIX))) + av_log(NULL, AV_LOG_WARNING, "Option %s skipped - not known to demuxer.\n", t->key); if (find_stream_info) { AVDictionary **opts = setup_find_stream_info_opts(fmt_ctx, codec_opts); @@ -2912,7 +2990,7 @@ static int open_input_file(InputFile *ifile, const char *filename, for (i = 0; i < fmt_ctx->nb_streams; i++) { InputStream *ist = &ifile->streams[i]; AVStream *stream = fmt_ctx->streams[i]; - AVCodec *codec; + const AVCodec *codec; ist->st = stream; @@ -2950,12 +3028,6 @@ static int open_input_file(InputFile *ifile, const char *filename, } ist->dec_ctx->pkt_timebase = stream->time_base; - ist->dec_ctx->framerate = stream->avg_frame_rate; -#if FF_API_LAVF_AVCTX - ist->dec_ctx->properties = stream->codec->properties; - ist->dec_ctx->coded_width = stream->codec->coded_width; - ist->dec_ctx->coded_height = stream->codec->coded_height; -#endif if (avcodec_open2(ist->dec_ctx, codec, &opts) < 0) { av_log(NULL, AV_LOG_WARNING, "Could not open codec for input stream %d\n", @@ -3156,9 +3228,6 @@ static void ffprobe_show_pixel_formats(WriterContext *w) PRINT_PIX_FMT_FLAG(HWACCEL, "hwaccel"); PRINT_PIX_FMT_FLAG(PLANAR, "planar"); PRINT_PIX_FMT_FLAG(RGB, "rgb"); -#if FF_API_PSEUDOPAL - PRINT_PIX_FMT_FLAG(PSEUDOPAL, "pseudopal"); -#endif PRINT_PIX_FMT_FLAG(ALPHA, "alpha"); writer_print_section_footer(w); } diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index 336c651d3..cbd863776 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -30,6 +30,7 @@ #include "libavutil/frame.h" #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "blockdsp.h" #include "bswapdsp.h" @@ -498,8 +499,8 @@ static int decode_i_block(FourXContext *f, int16_t *block) { int code, i, j, level, val; - if (get_bits_left(&f->gb) < 2){ - av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->gb)); + if (get_bits_left(&f->pre_gb) < 2) { + av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->pre_gb)); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c index aa2318fa2..53e939d35 100644 --- a/libavcodec/8bps.c +++ b/libavcodec/8bps.c @@ -122,7 +122,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, } if (avctx->bits_per_coded_sample <= 8) { - int size; + buffer_size_t size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 5a6ea5971..33a280cf6 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -29,6 +29,7 @@ HEADERS = ac3_parser.h \ OBJS = ac3_parser.o \ adts_parser.o \ allcodecs.o \ + avcodec.o \ avdct.o \ avpacket.o \ avpicture.o \ @@ -37,6 +38,7 @@ OBJS = ac3_parser.o \ bitstream_filters.o \ bsf.o \ codec_desc.o \ + codec_par.o \ d3d11va.o \ decode.o \ dirac.o \ @@ -48,7 +50,6 @@ OBJS = ac3_parser.o \ mediacodec.o \ mpeg12framerate.o \ options.o \ - mjpegenc_huffman.o \ parser.o \ parsers.o \ profiles.o \ @@ -64,14 +65,15 @@ OBJS-$(CONFIG_AC3DSP) += ac3dsp.o ac3.o ac3tab.o OBJS-$(CONFIG_ADTS_HEADER) += adts_header.o mpeg4audio.o OBJS-$(CONFIG_AMF) += amfenc.o OBJS-$(CONFIG_AUDIO_FRAME_QUEUE) += audio_frame_queue.o +OBJS-$(CONFIG_ATSC_A53) += atsc_a53.o OBJS-$(CONFIG_AUDIODSP) += audiodsp.o OBJS-$(CONFIG_BLOCKDSP) += blockdsp.o OBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o OBJS-$(CONFIG_CABAC) += cabac.o -OBJS-$(CONFIG_CBS) += cbs.o +OBJS-$(CONFIG_CBS) += cbs.o cbs_bsf.o OBJS-$(CONFIG_CBS_AV1) += cbs_av1.o -OBJS-$(CONFIG_CBS_H264) += cbs_h2645.o h2645_parse.o -OBJS-$(CONFIG_CBS_H265) += cbs_h2645.o h2645_parse.o +OBJS-$(CONFIG_CBS_H264) += cbs_h2645.o cbs_sei.o h2645_parse.o +OBJS-$(CONFIG_CBS_H265) += cbs_h2645.o cbs_sei.o h2645_parse.o OBJS-$(CONFIG_CBS_JPEG) += cbs_jpeg.o OBJS-$(CONFIG_CBS_MPEG2) += cbs_mpeg2.o OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o @@ -82,10 +84,9 @@ OBJS-$(CONFIG_EXIF) += exif.o tiff_common.o OBJS-$(CONFIG_FAANDCT) += faandct.o OBJS-$(CONFIG_FAANIDCT) += faanidct.o OBJS-$(CONFIG_FDCTDSP) += fdctdsp.o jfdctfst.o jfdctint.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) +FFT-OBJS-$(CONFIG_HARDCODED_TABLES) += cos_tables.o +OBJS-$(CONFIG_FFT) += avfft.o fft_float.o fft_fixed_32.o \ + fft_init_table.o $(FFT-OBJS-yes) OBJS-$(CONFIG_FLACDSP) += flacdsp.o OBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o OBJS-$(CONFIG_GOLOMB) += golomb.o @@ -95,7 +96,8 @@ OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o OBJS-$(CONFIG_H264PARSE) += h264_parse.o h2645_parse.o h264_ps.o OBJS-$(CONFIG_H264PRED) += h264pred.o OBJS-$(CONFIG_H264QPEL) += h264qpel.o -OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o h2645_parse.o hevc_ps.o hevc_sei.o hevc_data.o +OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o h2645_parse.o hevc_ps.o hevc_sei.o hevc_data.o \ + dynamic_hdr10_plus.o OBJS-$(CONFIG_HPELDSP) += hpeldsp.o OBJS-$(CONFIG_HUFFMAN) += huffman.o OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o @@ -113,11 +115,11 @@ OBJS-$(CONFIG_LLVIDENCDSP) += lossless_videoencdsp.o OBJS-$(CONFIG_LPC) += lpc.o OBJS-$(CONFIG_LSP) += lsp.o OBJS-$(CONFIG_LZF) += lzf.o -OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o mdct_fixed_32.o +OBJS-$(CONFIG_MDCT) += mdct_float.o mdct_fixed_32.o OBJS-$(CONFIG_ME_CMP) += me_cmp.o OBJS-$(CONFIG_MEDIACODEC) += mediacodecdec_common.o mediacodec_surface.o mediacodec_wrapper.o mediacodec_sw_buffer.o OBJS-$(CONFIG_MPEG_ER) += mpeg_er.o -OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o +OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o mpegaudiodec_common.o OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \ mpegaudiodsp_data.o \ mpegaudiodsp_fixed.o \ @@ -140,7 +142,7 @@ OBJS-$(CONFIG_RANGECODER) += rangecoder.o OBJS-$(CONFIG_RDFT) += rdft.o OBJS-$(CONFIG_RV34DSP) += rv34dsp.o OBJS-$(CONFIG_SHARED) += log2_tab.o reverse.o -OBJS-$(CONFIG_SINEWIN) += sinewin.o sinewin_fixed.o +OBJS-$(CONFIG_SINEWIN) += sinewin.o OBJS-$(CONFIG_SNAPPY) += snappy.o OBJS-$(CONFIG_STARTCODE) += startcode.o OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o @@ -160,10 +162,10 @@ OBJS-$(CONFIG_WMV2DSP) += wmv2dsp.o OBJS-$(CONFIG_ZERO12V_DECODER) += 012v.o OBJS-$(CONFIG_A64MULTI_ENCODER) += a64multienc.o elbg.o OBJS-$(CONFIG_A64MULTI5_ENCODER) += a64multienc.o elbg.o -OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o aacsbr.o aacps_float.o \ +OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o aacsbr.o aacps_common.o aacps_float.o \ mpeg4audio.o kbdwin.o \ sbrdsp.o aacpsdsp_float.o cbrt_data.o -OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aactab.o aacsbr_fixed.o aacps_fixed.o \ +OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aactab.o aacsbr_fixed.o aacps_common.o aacps_fixed.o \ mpeg4audio.o kbdwin.o \ sbrdsp_fixed.o aacpsdsp_fixed.o cbrt_data_fixed.o OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \ @@ -172,14 +174,14 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \ aacenc_tns.o \ aacenc_ltp.o \ aacenc_pred.o \ - psymodel.o mpeg4audio.o kbdwin.o cbrt_data.o + psymodel.o mpeg4audio.o kbdwin.o OBJS-$(CONFIG_AAC_MF_ENCODER) += mfenc.o mf_utils.o OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o kbdwin.o ac3tab.o OBJS-$(CONFIG_AC3_FIXED_DECODER) += ac3dec_fixed.o ac3dec_data.o ac3.o kbdwin.o ac3tab.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_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o kbdwin.o OBJS-$(CONFIG_AC3_MF_ENCODER) += mfenc.o mf_utils.o OBJS-$(CONFIG_ACELP_KELVIN_DECODER) += g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o OBJS-$(CONFIG_AGM_DECODER) += agm.o @@ -209,6 +211,7 @@ OBJS-$(CONFIG_APTX_HD_ENCODER) += aptxenc.o aptx.o OBJS-$(CONFIG_APNG_DECODER) += png.o pngdec.o pngdsp.o OBJS-$(CONFIG_APNG_ENCODER) += png.o pngenc.o OBJS-$(CONFIG_ARBC_DECODER) += arbc.o +OBJS-$(CONFIG_ARGO_DECODER) += argo.o OBJS-$(CONFIG_SSA_DECODER) += assdec.o ass.o OBJS-$(CONFIG_SSA_ENCODER) += assenc.o ass.o OBJS-$(CONFIG_ASS_DECODER) += assdec.o ass.o @@ -227,7 +230,9 @@ OBJS-$(CONFIG_ATRAC3PAL_DECODER) += atrac3plusdec.o atrac3plus.o \ OBJS-$(CONFIG_ATRAC9_DECODER) += atrac9dec.o OBJS-$(CONFIG_AURA_DECODER) += cyuv.o OBJS-$(CONFIG_AURA2_DECODER) += aura.o -OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o mjpegdec.o +OBJS-$(CONFIG_AV1_DECODER) += av1dec.o +OBJS-$(CONFIG_AV1_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o OBJS-$(CONFIG_AVS_DECODER) += avs.o @@ -254,7 +259,8 @@ OBJS-$(CONFIG_CCAPTION_DECODER) += ccaption_dec.o ass.o OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o OBJS-$(CONFIG_CDTOONS_DECODER) += cdtoons.o OBJS-$(CONFIG_CDXL_DECODER) += cdxl.o -OBJS-$(CONFIG_CFHD_DECODER) += cfhd.o cfhddata.o +OBJS-$(CONFIG_CFHD_DECODER) += cfhd.o cfhddata.o cfhddsp.o +OBJS-$(CONFIG_CFHD_ENCODER) += cfhdenc.o cfhddata.o cfhdencdsp.o OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o OBJS-$(CONFIG_CINEPAK_ENCODER) += cinepakenc.o elbg.o OBJS-$(CONFIG_CLEARVIDEO_DECODER) += clearvideo.o @@ -265,12 +271,13 @@ OBJS-$(CONFIG_COMFORTNOISE_DECODER) += cngdec.o celp_filters.o OBJS-$(CONFIG_COMFORTNOISE_ENCODER) += cngenc.o OBJS-$(CONFIG_COOK_DECODER) += cook.o OBJS-$(CONFIG_CPIA_DECODER) += cpia.o +OBJS-$(CONFIG_CRI_DECODER) += cri.o OBJS-$(CONFIG_CSCD_DECODER) += cscd.o OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o OBJS-$(CONFIG_DCA_DECODER) += dcadec.o dca.o dcadata.o dcahuff.o \ dca_core.o dca_exss.o dca_xll.o dca_lbr.o \ dcadsp.o dcadct.o synth_filter.o -OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dca.o dcadata.o dcahuff.o \ +OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dcadata.o dcahuff.o \ dcaadpcm.o OBJS-$(CONFIG_DDS_DECODER) += dds.o OBJS-$(CONFIG_DERF_DPCM_DECODER) += dpcm.o @@ -279,7 +286,7 @@ OBJS-$(CONFIG_DIRAC_DECODER) += diracdec.o dirac.o diracdsp.o diractab OBJS-$(CONFIG_DFA_DECODER) += dfa.o OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o -OBJS-$(CONFIG_DOLBY_E_DECODER) += dolby_e.o kbdwin.o +OBJS-$(CONFIG_DOLBY_E_DECODER) += dolby_e.o dolby_e_parse.o kbdwin.o OBJS-$(CONFIG_DPX_DECODER) += dpx.o OBJS-$(CONFIG_DPX_ENCODER) += dpxenc.o OBJS-$(CONFIG_DSD_LSBF_DECODER) += dsddec.o dsd.o @@ -291,7 +298,7 @@ OBJS-$(CONFIG_DSICINVIDEO_DECODER) += dsicinvideo.o OBJS-$(CONFIG_DSS_SP_DECODER) += dss_sp.o OBJS-$(CONFIG_DST_DECODER) += dstdec.o dsd.o OBJS-$(CONFIG_DVBSUB_DECODER) += dvbsubdec.o -OBJS-$(CONFIG_DVBSUB_ENCODER) += dvbsub.o +OBJS-$(CONFIG_DVBSUB_ENCODER) += dvbsubenc.o OBJS-$(CONFIG_DVDSUB_DECODER) += dvdsubdec.o dvdsub.o OBJS-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.o dvdsub.o OBJS-$(CONFIG_DVAUDIO_DECODER) += dvaudiodec.o @@ -315,6 +322,8 @@ OBJS-$(CONFIG_ESCAPE124_DECODER) += escape124.o OBJS-$(CONFIG_ESCAPE130_DECODER) += escape130.o OBJS-$(CONFIG_EVRC_DECODER) += evrcdec.o acelp_vectors.o lsp.o OBJS-$(CONFIG_EXR_DECODER) += exr.o exrdsp.o +OBJS-$(CONFIG_EXR_ENCODER) += exrenc.o +OBJS-$(CONFIG_FASTAUDIO_DECODER) += fastaudio.o OBJS-$(CONFIG_FFV1_DECODER) += ffv1dec.o ffv1.o OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o @@ -322,17 +331,19 @@ OBJS-$(CONFIG_FIC_DECODER) += fic.o OBJS-$(CONFIG_FITS_DECODER) += fitsdec.o fits.o OBJS-$(CONFIG_FITS_ENCODER) += fitsenc.o OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o vorbis_data.o +OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o OBJS-$(CONFIG_FLASHSV2_ENCODER) += flashsv2enc.o OBJS-$(CONFIG_FLASHSV2_DECODER) += flashsv.o OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o +OBJS-$(CONFIG_FLV_DECODER) += flvdec.o +OBJS-$(CONFIG_FLV_ENCODER) += flvenc.o OBJS-$(CONFIG_FMVC_DECODER) += fmvc.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 elsdec.o +OBJS-$(CONFIG_G2M_DECODER) += g2meet.o elsdec.o mjpegdec_common.o OBJS-$(CONFIG_G723_1_DECODER) += g723_1dec.o g723_1.o \ acelp_vectors.o celp_filters.o celp_math.o OBJS-$(CONFIG_G723_1_ENCODER) += g723_1enc.o g723_1.o \ @@ -347,10 +358,11 @@ OBJS-$(CONFIG_GSM_MS_DECODER) += gsmdec.o gsmdec_data.o msgsmdec.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 h263data.o -OBJS-$(CONFIG_H263_ENCODER) += mpeg4videoenc.o mpeg4video.o \ - h263.o ituh263enc.o flvenc.o h263data.o + mpeg4video.o mpeg4videodec.o \ + h263data.o +OBJS-$(CONFIG_H263I_DECODER) += intelh263dec.o +OBJS-$(CONFIG_H263_ENCODER) += mpeg4video.o \ + h263.o ituh263enc.o h263data.o OBJS-$(CONFIG_H263_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_H263_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \ @@ -367,7 +379,7 @@ OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o OBJS-$(CONFIG_NVENC_ENCODER) += nvenc_h264.o OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc_h264.o OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o -OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o +OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o @@ -387,7 +399,7 @@ OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc_hevc.o -OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o +OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \ hevc_data.o OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o @@ -415,6 +427,7 @@ OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi.o OBJS-$(CONFIG_INTERPLAY_ACM_DECODER) += interplayacm.o OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER) += dpcm.o OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o +OBJS-$(CONFIG_IPU_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o OBJS-$(CONFIG_JPEG2000_ENCODER) += j2kenc.o mqcenc.o mqc.o jpeg2000.o \ jpeg2000dwt.o @@ -428,7 +441,7 @@ OBJS-$(CONFIG_KMVC_DECODER) += kmvc.o OBJS-$(CONFIG_LAGARITH_DECODER) += lagarith.o lagarithrac.o OBJS-$(CONFIG_LJPEG_ENCODER) += ljpegenc.o mjpegenc_common.o OBJS-$(CONFIG_LOCO_DECODER) += loco.o -OBJS-$(CONFIG_LSCR_DECODER) += png.o pngdec.o pngdsp.o +OBJS-$(CONFIG_LSCR_DECODER) += lscrdec.o png.o pngdec.o pngdsp.o OBJS-$(CONFIG_M101_DECODER) += m101.o OBJS-$(CONFIG_MACE3_DECODER) += mace.o OBJS-$(CONFIG_MACE6_DECODER) += mace.o @@ -439,8 +452,8 @@ 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 -OBJS-$(CONFIG_MJPEG_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpegdec_common.o +OBJS-$(CONFIG_MJPEG_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpegenc_common.o \ mjpegenc_huffman.o OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o @@ -450,6 +463,7 @@ OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o mlp.o OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o +OBJS-$(CONFIG_MOBICLIP_DECODER) += mobiclip.o OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o OBJS-$(CONFIG_MOVTEXT_ENCODER) += movtextenc.o ass_split.o @@ -476,7 +490,7 @@ OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o OBJS-$(CONFIG_MPEG1_CUVID_DECODER) += cuviddec.o OBJS-$(CONFIG_MPEG1_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_MPEG2_MMAL_DECODER) += mmaldec.o -OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o @@ -485,6 +499,7 @@ OBJS-$(CONFIG_MPEG2_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_MPEG2_VAAPI_ENCODER) += vaapi_encode_mpeg2.o OBJS-$(CONFIG_MPEG2_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_MPEG4_DECODER) += xvididct.o +OBJS-$(CONFIG_MPEG4_ENCODER) += mpeg4videoenc.o OBJS-$(CONFIG_MPEG4_CUVID_DECODER) += cuviddec.o OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_MPEG4_OMX_ENCODER) += omx.o @@ -498,6 +513,7 @@ OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_MSP2_DECODER) += msp2dec.o OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o OBJS-$(CONFIG_MSS1_DECODER) += mss1.o mss12.o OBJS-$(CONFIG_MSS2_DECODER) += mss2.o mss12.o mss2dsp.o wmv2data.o @@ -531,11 +547,14 @@ OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o OBJS-$(CONFIG_PCX_DECODER) += pcx.o OBJS-$(CONFIG_PCX_ENCODER) += pcxenc.o OBJS-$(CONFIG_PFM_DECODER) += pnmdec.o pnm.o +OBJS-$(CONFIG_PFM_ENCODER) += pnmenc.o OBJS-$(CONFIG_PGM_DECODER) += pnmdec.o pnm.o OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o +OBJS-$(CONFIG_PGX_DECODER) += pgxdec.o +OBJS-$(CONFIG_PHOTOCD_DECODER) += photocd.o OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o OBJS-$(CONFIG_PIXLET_DECODER) += pixlet.o OBJS-$(CONFIG_PJS_DECODER) += textdec.o ass.o @@ -577,6 +596,7 @@ OBJS-$(CONFIG_ROQ_ENCODER) += roqvideoenc.o roqvideo.o elbg.o OBJS-$(CONFIG_ROQ_DPCM_DECODER) += dpcm.o OBJS-$(CONFIG_ROQ_DPCM_ENCODER) += roqaudioenc.o OBJS-$(CONFIG_RPZA_DECODER) += rpza.o +OBJS-$(CONFIG_RPZA_ENCODER) += rpzaenc.o OBJS-$(CONFIG_RSCC_DECODER) += rscc.o OBJS-$(CONFIG_RV10_DECODER) += rv10.o OBJS-$(CONFIG_RV10_ENCODER) += rv10enc.o @@ -591,6 +611,7 @@ OBJS-$(CONFIG_SANM_DECODER) += sanm.o OBJS-$(CONFIG_SCPR_DECODER) += scpr.o OBJS-$(CONFIG_SCREENPRESSO_DECODER) += screenpresso.o OBJS-$(CONFIG_SDX2_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_SGA_DECODER) += sga.o OBJS-$(CONFIG_SGI_DECODER) += sgidec.o OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o OBJS-$(CONFIG_SGIRLE_DECODER) += sgirledec.o @@ -601,10 +622,10 @@ OBJS-$(CONFIG_SIPR_DECODER) += sipr.o acelp_pitch_delay.o \ acelp_filters.o celp_filters.o \ sipr16k.o OBJS-$(CONFIG_SIREN_DECODER) += siren.o +OBJS-$(CONFIG_SIMBIOSIS_IMX_DECODER) += imx.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 h263data.o ituh263enc.o @@ -613,6 +634,7 @@ OBJS-$(CONFIG_SONIC_DECODER) += sonic.o OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhq.o mpeg12.o mpeg12data.o simple_idct.o +OBJS-$(CONFIG_SPEEDHQ_ENCODER) += speedhq.o mpeg12data.o mpeg12enc.o speedhqenc.o OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o OBJS-$(CONFIG_SRGC_DECODER) += mscc.o OBJS-$(CONFIG_SRT_DECODER) += srtdec.o ass.o htmlsubtitles.o @@ -639,8 +661,8 @@ OBJS-$(CONFIG_TARGA_ENCODER) += targaenc.o rle.o OBJS-$(CONFIG_TARGA_Y216_DECODER) += targa_y216dec.o OBJS-$(CONFIG_TDSC_DECODER) += tdsc.o OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o -OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o tiff_data.o tiff_common.o mjpegdec.o -OBJS-$(CONFIG_TIFF_ENCODER) += tiffenc.o rle.o lzwenc.o tiff_data.o +OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o tiff_common.o +OBJS-$(CONFIG_TIFF_ENCODER) += tiffenc.o rle.o lzwenc.o OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o OBJS-$(CONFIG_TRUEHD_DECODER) += mlpdec.o mlpdsp.o OBJS-$(CONFIG_TRUEHD_ENCODER) += mlpenc.o mlp.o @@ -652,11 +674,12 @@ OBJS-$(CONFIG_TSCC_DECODER) += tscc.o msrledec.o OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o OBJS-$(CONFIG_TTA_DECODER) += tta.o ttadata.o ttadsp.o OBJS-$(CONFIG_TTA_ENCODER) += ttaenc.o ttaencdsp.o ttadata.o -OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o +OBJS-$(CONFIG_TTML_ENCODER) += ttmlenc.o ass_split.o +OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o metasound_data.o OBJS-$(CONFIG_TXD_DECODER) += txd.o OBJS-$(CONFIG_ULTI_DECODER) += ulti.o -OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideo.o utvideodsp.o -OBJS-$(CONFIG_UTVIDEO_ENCODER) += utvideoenc.o utvideo.o +OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideodsp.o +OBJS-$(CONFIG_UTVIDEO_ENCODER) += utvideoenc.o OBJS-$(CONFIG_V210_DECODER) += v210dec.o OBJS-$(CONFIG_V210_ENCODER) += v210enc.o OBJS-$(CONFIG_V210X_DECODER) += v210x.o @@ -674,7 +697,7 @@ OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1_loopfilter.o wmv2dsp.o wmv2data.o OBJS-$(CONFIG_VC1_CUVID_DECODER) += cuviddec.o OBJS-$(CONFIG_VC1_MMAL_DECODER) += mmaldec.o -OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_VC1_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_VC2_ENCODER) += vc2enc.o vc2enc_dwt.o diractab.o OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o @@ -693,7 +716,7 @@ OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp56rac.o OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuviddec.o OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o -OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_VP8_RKMPP_DECODER) += rkmppdec.o OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o OBJS-$(CONFIG_VP8_V4L2M2M_DECODER) += v4l2_m2m_dec.o @@ -709,8 +732,8 @@ OBJS-$(CONFIG_VP9_QSV_ENCODER) += qsvenc_vp9.o OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o -OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o dsd.o -OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackenc.o +OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o wavpackdata.o dsd.o +OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackdata.o wavpackenc.o OBJS-$(CONFIG_WCMV_DECODER) += wcmv.o OBJS-$(CONFIG_WEBP_DECODER) += webp.o OBJS-$(CONFIG_WEBVTT_DECODER) += webvttdec.o ass.o @@ -811,6 +834,7 @@ OBJS-$(CONFIG_PCM_S64BE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S64BE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_S64LE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S64LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_SGA_DECODER) += pcm.o OBJS-$(CONFIG_PCM_U8_DECODER) += pcm.o OBJS-$(CONFIG_PCM_U8_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_U16BE_DECODER) += pcm.o @@ -835,6 +859,7 @@ OBJS-$(CONFIG_ADPCM_AFC_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_AGM_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_AICA_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_ARGO_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_ARGO_ENCODER) += adpcm.o adpcmenc.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 @@ -851,8 +876,10 @@ OBJS-$(CONFIG_ADPCM_G726LE_DECODER) += g726.o OBJS-$(CONFIG_ADPCM_G726LE_ENCODER) += g726.o OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_ALP_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_ALP_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_APM_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_APM_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_CUNNING_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_DAT4_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o adpcm_data.o @@ -860,6 +887,7 @@ OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_MOFLEX_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_MTF_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 @@ -896,21 +924,25 @@ OBJS-$(CONFIG_VAAPI) += vaapi_decode.o OBJS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.o OBJS-$(CONFIG_VDPAU) += vdpau.o +OBJS-$(CONFIG_AV1_D3D11VA_HWACCEL) += dxva2_av1.o +OBJS-$(CONFIG_AV1_DXVA2_HWACCEL) += dxva2_av1.o +OBJS-$(CONFIG_AV1_NVDEC_HWACCEL) += nvdec_av1.o +OBJS-$(CONFIG_AV1_VAAPI_HWACCEL) += vaapi_av1.o OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o OBJS-$(CONFIG_H263_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o OBJS-$(CONFIG_H264_NVDEC_HWACCEL) += nvdec_h264.o -OBJS-$(CONFIG_H264_QSV_HWACCEL) += qsvdec_h2645.o +OBJS-$(CONFIG_H264_QSV_HWACCEL) += qsvdec.o OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o OBJS-$(CONFIG_H264_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o -OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o +OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec.o OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o h265_profile_level.o -OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o +OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o h265_profile_level.o OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o OBJS-$(CONFIG_MJPEG_VAAPI_HWACCEL) += vaapi_mjpeg.o OBJS-$(CONFIG_MPEG1_NVDEC_HWACCEL) += nvdec_mpeg12.o @@ -920,7 +952,7 @@ OBJS-$(CONFIG_MPEG1_XVMC_HWACCEL) += mpegvideo_xvmc.o OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o OBJS-$(CONFIG_MPEG2_NVDEC_HWACCEL) += nvdec_mpeg12.o -OBJS-$(CONFIG_MPEG2_QSV_HWACCEL) += qsvdec_other.o +OBJS-$(CONFIG_MPEG2_QSV_HWACCEL) += qsvdec.o OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o OBJS-$(CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o @@ -932,7 +964,7 @@ OBJS-$(CONFIG_MPEG4_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o OBJS-$(CONFIG_VC1_D3D11VA_HWACCEL) += dxva2_vc1.o OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o OBJS-$(CONFIG_VC1_NVDEC_HWACCEL) += nvdec_vc1.o -OBJS-$(CONFIG_VC1_QSV_HWACCEL) += qsvdec_other.o +OBJS-$(CONFIG_VC1_QSV_HWACCEL) += qsvdec.o OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o OBJS-$(CONFIG_VP8_NVDEC_HWACCEL) += nvdec_vp8.o @@ -942,26 +974,24 @@ OBJS-$(CONFIG_VP9_DXVA2_HWACCEL) += dxva2_vp9.o OBJS-$(CONFIG_VP9_NVDEC_HWACCEL) += nvdec_vp9.o OBJS-$(CONFIG_VP9_VAAPI_HWACCEL) += vaapi_vp9.o OBJS-$(CONFIG_VP9_VDPAU_HWACCEL) += vdpau_vp9.o -OBJS-$(CONFIG_VP8_QSV_HWACCEL) += qsvdec_other.o +OBJS-$(CONFIG_VP8_QSV_HWACCEL) += qsvdec.o # libavformat dependencies OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o -OBJS-$(CONFIG_CAF_DEMUXER) += ac3tab.o OBJS-$(CONFIG_CODEC2_DEMUXER) += codec2utils.o OBJS-$(CONFIG_CODEC2_MUXER) += codec2utils.o OBJS-$(CONFIG_CODEC2RAW_DEMUXER) += codec2utils.o OBJS-$(CONFIG_DNXHD_DEMUXER) += dnxhddata.o OBJS-$(CONFIG_FITS_DEMUXER) += fits.o -OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o OBJS-$(CONFIG_LATM_MUXER) += mpeg4audio.o OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += mpeg4audio.o OBJS-$(CONFIG_MATROSKA_MUXER) += mpeg4audio.o OBJS-$(CONFIG_MOV_DEMUXER) += ac3tab.o +OBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio.o OBJS-$(CONFIG_MXF_MUXER) += dnxhddata.o OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o -OBJS-$(CONFIG_NUT_DEMUXER) += mpegaudiodata.o mpeg4audio.o OBJS-$(CONFIG_RTP_MUXER) += mpeg4audio.o OBJS-$(CONFIG_SPDIF_MUXER) += dca.o OBJS-$(CONFIG_TAK_DEMUXER) += tak.o @@ -1024,8 +1054,10 @@ OBJS-$(CONFIG_LIBRAV1E_ENCODER) += librav1e.o OBJS-$(CONFIG_LIBSHINE_ENCODER) += libshine.o OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o +OBJS-$(CONFIG_LIBSVTAV1_ENCODER) += libsvtav1.o OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o +OBJS-$(CONFIG_LIBUAVS3D_DECODER) += libuavs3d.o OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o OBJS-$(CONFIG_LIBVORBIS_DECODER) += libvorbisdec.o OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o \ @@ -1034,7 +1066,6 @@ OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o OBJS-$(CONFIG_LIBVPX_VP8_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_common.o libwebpenc.o OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o @@ -1053,19 +1084,21 @@ OBJS-$(CONFIG_AC3_PARSER) += ac3tab.o aac_ac3_parser.o OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o av1_parse.o OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o +OBJS-$(CONFIG_AVS3_PARSER) += avs3_parser.o OBJS-$(CONFIG_BMP_PARSER) += bmp_parser.o OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o OBJS-$(CONFIG_COOK_PARSER) += cook_parser.o +OBJS-$(CONFIG_CRI_PARSER) += cri_parser.o OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o dca_exss.o dca.o OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o OBJS-$(CONFIG_DNXHD_PARSER) += dnxhd_parser.o dnxhddata.o +OBJS-$(CONFIG_DOLBY_E_PARSER) += dolby_e_parser.o dolby_e_parse.o OBJS-$(CONFIG_DPX_PARSER) += dpx_parser.o OBJS-$(CONFIG_DVAUDIO_PARSER) += dvaudio_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 -OBJS-$(CONFIG_FLAC_PARSER) += flac_parser.o flacdata.o flac.o \ - vorbis_data.o +OBJS-$(CONFIG_FLAC_PARSER) += flac_parser.o flacdata.o flac.o OBJS-$(CONFIG_G723_1_PARSER) += g723_1_parser.o OBJS-$(CONFIG_G729_PARSER) += g729_parser.o OBJS-$(CONFIG_GIF_PARSER) += gif_parser.o @@ -1074,6 +1107,7 @@ OBJS-$(CONFIG_H261_PARSER) += h261_parser.o OBJS-$(CONFIG_H263_PARSER) += h263_parser.o OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264_sei.o h264data.o OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o hevc_data.o +OBJS-$(CONFIG_IPU_PARSER) += ipu_parser.o OBJS-$(CONFIG_JPEG2000_PARSER) += jpeg2000_parser.o OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o OBJS-$(CONFIG_MLP_PARSER) += mlp_parse.o mlp_parser.o mlp.o @@ -1098,6 +1132,7 @@ OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o OBJS-$(CONFIG_VP8_PARSER) += vp8_parser.o OBJS-$(CONFIG_VP9_PARSER) += vp9_parser.o OBJS-$(CONFIG_WEBP_PARSER) += webp_parser.o +OBJS-$(CONFIG_XBM_PARSER) += xbm_parser.o OBJS-$(CONFIG_XMA_PARSER) += xma_parser.o # bitstream filters @@ -1132,6 +1167,7 @@ OBJS-$(CONFIG_OPUS_METADATA_BSF) += opus_metadata_bsf.o OBJS-$(CONFIG_PCM_RECHUNK_BSF) += pcm_rechunk_bsf.o OBJS-$(CONFIG_PRORES_METADATA_BSF) += prores_metadata_bsf.o OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o +OBJS-$(CONFIG_SETTS_BSF) += setts_bsf.o OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o OBJS-$(CONFIG_TRACE_HEADERS_BSF) += trace_headers_bsf.o OBJS-$(CONFIG_TRUEHD_CORE_BSF) += truehd_core_bsf.o mlp_parse.o mlp.o @@ -1171,10 +1207,9 @@ SKIPHEADERS-$(CONFIG_MEDIAFOUNDATION) += mf_utils.h SKIPHEADERS-$(CONFIG_NVDEC) += nvdec.h SKIPHEADERS-$(CONFIG_NVENC) += nvenc.h SKIPHEADERS-$(CONFIG_QSV) += qsv.h qsv_internal.h -SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h -SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_encode.h +SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_hevc.h vaapi_encode.h SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vt_internal.h SKIPHEADERS-$(CONFIG_V4L2_M2M) += v4l2_buffers.h v4l2_context.h v4l2_m2m.h @@ -1186,16 +1221,15 @@ TESTPROGS = avpacket \ imgconvert \ jpeg2000dwt \ mathops \ - options \ - mjpegenc_huffman \ utils \ TESTPROGS-$(CONFIG_CABAC) += cabac TESTPROGS-$(CONFIG_DCT) += avfft -TESTPROGS-$(CONFIG_FFT) += fft fft-fixed fft-fixed32 +TESTPROGS-$(CONFIG_FFT) += fft fft-fixed32 TESTPROGS-$(CONFIG_GOLOMB) += golomb TESTPROGS-$(CONFIG_IDCTDSP) += dct TESTPROGS-$(CONFIG_IIRFILTER) += iirfilter +TESTPROGS-$(CONFIG_MJPEG_ENCODER) += mjpegenc_huffman TESTPROGS-$(HAVE_MMX) += motion TESTPROGS-$(CONFIG_MPEGVIDEO) += mpeg12framerate TESTPROGS-$(CONFIG_H264_METADATA_BSF) += h264_levels @@ -1215,6 +1249,7 @@ HOSTPROGS = aacps_tablegen \ dv_tablegen \ motionpixels_tablegen \ mpegaudio_tablegen \ + mpegaudiodec_common_tablegen \ pcm_tablegen \ qdm2_tablegen \ sinewin_tablegen \ @@ -1239,7 +1274,8 @@ endif GEN_HEADERS = cbrt_tables.h cbrt_fixed_tables.h aacps_tables.h aacps_fixed_tables.h \ dv_tables.h \ - sinewin_tables.h sinewin_fixed_tables.h mpegaudio_tables.h motionpixels_tables.h \ + sinewin_tables.h sinewin_fixed_tables.h mpegaudio_tables.h \ + mpegaudiodec_common_tables.h motionpixels_tables.h \ pcm_tables.h qdm2_tables.h GEN_HEADERS := $(addprefix $(SUBDIR), $(GEN_HEADERS)) @@ -1249,15 +1285,15 @@ $(GEN_HEADERS): $(SUBDIR)%_tables.h: $(SUBDIR)%_tablegen$(HOSTEXESUF) ifdef CONFIG_HARDCODED_TABLES $(SUBDIR)cbrt_data.o: $(SUBDIR)cbrt_tables.h $(SUBDIR)cbrt_data_fixed.o: $(SUBDIR)cbrt_fixed_tables.h +$(SUBDIR)aacdec_fixed.o: $(SUBDIR)sinewin_fixed_tables.h $(SUBDIR)aacps_float.o: $(SUBDIR)aacps_tables.h $(SUBDIR)aacps_fixed.o: $(SUBDIR)aacps_fixed_tables.h -$(SUBDIR)aactab_fixed.o: $(SUBDIR)aac_fixed_tables.h $(SUBDIR)dvenc.o: $(SUBDIR)dv_tables.h $(SUBDIR)motionpixels.o: $(SUBDIR)motionpixels_tables.h +$(SUBDIR)mpegaudiodec_common.o: $(SUBDIR)mpegaudiodec_common_tables.h $(SUBDIR)mpegaudiodec_fixed.o: $(SUBDIR)mpegaudio_tables.h $(SUBDIR)mpegaudiodec_float.o: $(SUBDIR)mpegaudio_tables.h $(SUBDIR)pcm.o: $(SUBDIR)pcm_tables.h $(SUBDIR)qdm2.o: $(SUBDIR)qdm2_tables.h $(SUBDIR)sinewin.o: $(SUBDIR)sinewin_tables.h -$(SUBDIR)sinewin_fixed.o: $(SUBDIR)sinewin_fixed_tables.h endif diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index 38f25020f..91c89c87e 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -107,13 +107,16 @@ static void render_charset(AVCodecContext *avctx, uint8_t *charset, uint8_t pix; int lowdiff, highdiff; int *best_cb = c->mc_best_cb; - static uint8_t index1[256]; - static uint8_t index2[256]; - static uint8_t dither[256]; + uint8_t index1[256]; + uint8_t index2[256]; + uint8_t dither[256]; int i; int distance; - /* generate lookup-tables for dither and index before looping */ + /* Generate lookup-tables for dither and index before looping. + * This code relies on c->mc_luma_vals[c->mc_pal_size - 1] being + * the maximum of all the mc_luma_vals values and on the minimum + * being zero; this ensures that dither is properly initialized. */ i = 0; for (a=0; a < 256; a++) { if(i < c->mc_pal_size -1 && a == c->mc_luma_vals[i + 1]) { @@ -407,6 +410,7 @@ AVCodec ff_a64multi_encoder = { .close = a64multi_close_encoder, .pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE}, .capabilities = AV_CODEC_CAP_DELAY, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_A64MULTI5_ENCODER @@ -421,5 +425,6 @@ AVCodec ff_a64multi5_encoder = { .close = a64multi_close_encoder, .pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE}, .capabilities = AV_CODEC_CAP_DELAY, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; #endif diff --git a/libavcodec/aac.h b/libavcodec/aac.h index d422ea5b1..1e82f56ca 100644 --- a/libavcodec/aac.h +++ b/libavcodec/aac.h @@ -34,6 +34,7 @@ #include "aac_defines.h" #include "libavutil/float_dsp.h" #include "libavutil/fixed_dsp.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #if !USE_FIXED #include "mdct15.h" diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c index 54e459844..e84d30aea 100644 --- a/libavcodec/aac_ac3_parser.c +++ b/libavcodec/aac_ac3_parser.c @@ -89,7 +89,7 @@ get_next: the frame). */ if (avctx->codec_id != AV_CODEC_ID_AAC) { avctx->sample_rate = s->sample_rate; - if (avctx->codec_id != AV_CODEC_ID_EAC3) { + if (!CONFIG_EAC3_DECODER || avctx->codec_id != AV_CODEC_ID_EAC3) { avctx->channels = s->channels; avctx->channel_layout = s->channel_layout; } @@ -97,8 +97,12 @@ get_next: avctx->audio_service_type = s->service_type; } - if (avctx->codec_id != AV_CODEC_ID_EAC3) - avctx->bit_rate = s->bit_rate; + /* Calculate the average bit rate */ + s->frame_number++; + if (!CONFIG_EAC3_DECODER || avctx->codec_id != AV_CODEC_ID_EAC3) { + avctx->bit_rate += + (s->bit_rate - avctx->bit_rate) / s->frame_number; + } } return i; diff --git a/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h index c2506a5bf..8b93cbf84 100644 --- a/libavcodec/aac_ac3_parser.h +++ b/libavcodec/aac_ac3_parser.h @@ -55,6 +55,7 @@ typedef struct AACAC3ParseContext { uint64_t state; int need_next_header; + int frame_number; enum AVCodecID codec_id; } AACAC3ParseContext; diff --git a/libavcodec/aac_defines.h b/libavcodec/aac_defines.h index 438d78a7a..e94475ac5 100644 --- a/libavcodec/aac_defines.h +++ b/libavcodec/aac_defines.h @@ -34,6 +34,7 @@ #define AAC_RENAME(x) x ## _fixed #define AAC_RENAME_32(x) x ## _fixed_32 +#define AAC_RENAME2(x) x ## _fixed typedef int INTFLOAT; typedef unsigned UINTFLOAT; ///< Equivalent to INTFLOAT, Used as temporal cast to avoid undefined sign overflow operations. typedef int64_t INT64FLOAT; @@ -83,6 +84,7 @@ typedef int AAC_SIGNE; #define AAC_RENAME(x) x #define AAC_RENAME_32(x) x +#define AAC_RENAME2(x) ff_ ## x typedef float INTFLOAT; typedef float UINTFLOAT; typedef float INT64FLOAT; diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index d17852d8b..0174bf8d5 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -69,6 +69,11 @@ # include "mips/aacdec_mips.h" #endif +DECLARE_ALIGNED(32, static INTFLOAT, AAC_RENAME(sine_120))[120]; +DECLARE_ALIGNED(32, static INTFLOAT, AAC_RENAME(sine_960))[960]; +DECLARE_ALIGNED(32, static INTFLOAT, AAC_RENAME(aac_kbd_long_960))[960]; +DECLARE_ALIGNED(32, static INTFLOAT, AAC_RENAME(aac_kbd_short_120))[120]; + static av_always_inline void reset_predict_state(PredictorState *ps) { ps->r0 = 0.0f; diff --git a/libavcodec/aacdec_fixed.c b/libavcodec/aacdec_fixed.c index daaf765e0..c5d923a8b 100644 --- a/libavcodec/aacdec_fixed.c +++ b/libavcodec/aacdec_fixed.c @@ -70,7 +70,7 @@ #include "fft.h" #include "lpc.h" #include "kbdwin.h" -#include "sinewin.h" +#include "sinewin_fixed_tablegen.h" #include "aac.h" #include "aactab.h" @@ -86,6 +86,9 @@ #include #include +DECLARE_ALIGNED(32, static int, AAC_RENAME2(aac_kbd_long_1024))[1024]; +DECLARE_ALIGNED(32, static int, AAC_RENAME2(aac_kbd_short_128))[128]; + static av_always_inline void reset_predict_state(PredictorState *ps) { ps->r0.mant = 0; diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index a473e1bad..98f77a3ad 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -198,7 +198,7 @@ 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, uint64_t *layout) { if (layout_map[offset][0] == TYPE_CPE) { e2c_vec[offset] = (struct elem_to_channel) { @@ -207,6 +207,9 @@ static int assign_pair(struct elem_to_channel e2c_vec[MAX_ELEM_ID], .elem_id = layout_map[offset][1], .aac_position = pos }; + if (e2c_vec[offset].av_position != UINT64_MAX) + *layout |= e2c_vec[offset].av_position; + return 1; } else { e2c_vec[offset] = (struct elem_to_channel) { @@ -221,6 +224,12 @@ static int assign_pair(struct elem_to_channel e2c_vec[MAX_ELEM_ID], .elem_id = layout_map[offset + 1][1], .aac_position = pos }; + if (left != UINT64_MAX) + *layout |= left; + + if (right != UINT64_MAX) + *layout |= right; + return 2; } } @@ -257,12 +266,13 @@ static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, return num_pos_channels; } +#define PREFIX_FOR_22POINT2 (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_LOW_FREQUENCY_2) 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 } }; int num_front_channels, num_side_channels, num_back_channels; - uint64_t layout; + uint64_t layout = 0; if (FF_ARRAY_ELEMS(e2c_vec) < tags) return 0; @@ -294,6 +304,7 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_FRONT }; + layout |= e2c_vec[i].av_position; i++; num_front_channels--; } @@ -301,21 +312,21 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) i += assign_pair(e2c_vec, layout_map, i, AV_CH_FRONT_LEFT_OF_CENTER, AV_CH_FRONT_RIGHT_OF_CENTER, - AAC_CHANNEL_FRONT); + AAC_CHANNEL_FRONT, &layout); num_front_channels -= 2; } if (num_front_channels >= 2) { i += assign_pair(e2c_vec, layout_map, i, AV_CH_FRONT_LEFT, AV_CH_FRONT_RIGHT, - AAC_CHANNEL_FRONT); + AAC_CHANNEL_FRONT, &layout); num_front_channels -= 2; } while (num_front_channels >= 2) { i += assign_pair(e2c_vec, layout_map, i, UINT64_MAX, UINT64_MAX, - AAC_CHANNEL_FRONT); + AAC_CHANNEL_FRONT, &layout); num_front_channels -= 2; } @@ -323,14 +334,14 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) i += assign_pair(e2c_vec, layout_map, i, AV_CH_SIDE_LEFT, AV_CH_SIDE_RIGHT, - AAC_CHANNEL_FRONT); + AAC_CHANNEL_FRONT, &layout); num_side_channels -= 2; } while (num_side_channels >= 2) { i += assign_pair(e2c_vec, layout_map, i, UINT64_MAX, UINT64_MAX, - AAC_CHANNEL_SIDE); + AAC_CHANNEL_SIDE, &layout); num_side_channels -= 2; } @@ -338,14 +349,14 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) i += assign_pair(e2c_vec, layout_map, i, UINT64_MAX, UINT64_MAX, - AAC_CHANNEL_BACK); + AAC_CHANNEL_BACK, &layout); num_back_channels -= 2; } if (num_back_channels >= 2) { i += assign_pair(e2c_vec, layout_map, i, AV_CH_BACK_LEFT, AV_CH_BACK_RIGHT, - AAC_CHANNEL_BACK); + AAC_CHANNEL_BACK, &layout); num_back_channels -= 2; } if (num_back_channels) { @@ -355,6 +366,7 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_BACK }; + layout |= e2c_vec[i].av_position; i++; num_back_channels--; } @@ -366,6 +378,17 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_LFE }; + layout |= e2c_vec[i].av_position; + i++; + } + if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_LOW_FREQUENCY_2, + .syn_ele = TYPE_LFE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_LFE + }; + layout |= e2c_vec[i].av_position; i++; } while (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { @@ -378,26 +401,95 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) i++; } - // Must choose a stable sort + // The previous checks would end up at 8 at this point for 22.2 + if (layout == PREFIX_FOR_22POINT2 && tags == 16 && i == 8) { + const uint8_t (*reference_layout_map)[3] = aac_channel_layout_map[12]; + for (int j = 0; j < tags; j++) { + if (layout_map[j][0] != reference_layout_map[j][0] || + layout_map[j][2] != reference_layout_map[j][2]) + goto end_of_layout_definition; + } + + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_TOP_FRONT_CENTER, + .syn_ele = layout_map[i][0], + .elem_id = layout_map[i][1], + .aac_position = layout_map[i][2] + }; layout |= e2c_vec[i].av_position; i++; + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_TOP_FRONT_LEFT, + AV_CH_TOP_FRONT_RIGHT, + AAC_CHANNEL_FRONT, + &layout); + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_TOP_SIDE_LEFT, + AV_CH_TOP_SIDE_RIGHT, + AAC_CHANNEL_SIDE, + &layout); + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_TOP_CENTER, + .syn_ele = layout_map[i][0], + .elem_id = layout_map[i][1], + .aac_position = layout_map[i][2] + }; layout |= e2c_vec[i].av_position; i++; + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_TOP_BACK_LEFT, + AV_CH_TOP_BACK_RIGHT, + AAC_CHANNEL_BACK, + &layout); + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_TOP_BACK_CENTER, + .syn_ele = layout_map[i][0], + .elem_id = layout_map[i][1], + .aac_position = layout_map[i][2] + }; layout |= e2c_vec[i].av_position; i++; + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_BOTTOM_FRONT_CENTER, + .syn_ele = layout_map[i][0], + .elem_id = layout_map[i][1], + .aac_position = layout_map[i][2] + }; layout |= e2c_vec[i].av_position; i++; + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_BOTTOM_FRONT_LEFT, + AV_CH_BOTTOM_FRONT_RIGHT, + AAC_CHANNEL_FRONT, + &layout); + } + +end_of_layout_definition: + 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]); - next_n = i; - } - n = next_n; - } while (n > 0); + + if (layout == AV_CH_LAYOUT_22POINT2) { + // For 22.2 reorder the result as needed + FFSWAP(struct elem_to_channel, e2c_vec[2], e2c_vec[0]); // FL & FR first (final), FC third + FFSWAP(struct elem_to_channel, e2c_vec[2], e2c_vec[1]); // FC second (final), FLc & FRc third + FFSWAP(struct elem_to_channel, e2c_vec[6], e2c_vec[2]); // LFE1 third (final), FLc & FRc seventh + FFSWAP(struct elem_to_channel, e2c_vec[4], e2c_vec[3]); // BL & BR fourth (final), SiL & SiR fifth + FFSWAP(struct elem_to_channel, e2c_vec[6], e2c_vec[4]); // FLc & FRc fifth (final), SiL & SiR seventh + FFSWAP(struct elem_to_channel, e2c_vec[7], e2c_vec[6]); // LFE2 seventh (final), SiL & SiR eight (final) + FFSWAP(struct elem_to_channel, e2c_vec[9], e2c_vec[8]); // TpFL & TpFR ninth (final), TFC tenth (final) + FFSWAP(struct elem_to_channel, e2c_vec[11], e2c_vec[10]); // TC eleventh (final), TpSiL & TpSiR twelth + FFSWAP(struct elem_to_channel, e2c_vec[12], e2c_vec[11]); // TpBL & TpBR twelth (final), TpSiL & TpSiR thirteenth (final) + } else { + // For everything else, utilize the AV channel position define as a + // stable sort. + 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]); + next_n = i; + } + n = next_n; + } while (n > 0); + + } - layout = 0; for (i = 0; i < total_non_cc_elements; i++) { layout_map[i][0] = e2c_vec[i].syn_ele; layout_map[i][1] = e2c_vec[i].elem_id; layout_map[i][2] = e2c_vec[i].aac_position; - if (e2c_vec[i].av_position != UINT64_MAX) { - layout |= e2c_vec[i].av_position; - } } return layout; @@ -526,7 +618,7 @@ static int set_default_channel_config(AACContext *ac, AVCodecContext *avctx, int channel_config) { if (channel_config < 1 || (channel_config > 7 && channel_config < 11) || - channel_config > 12) { + channel_config > 13) { av_log(avctx, AV_LOG_ERROR, "invalid default channel configuration (%d)\n", channel_config); @@ -547,11 +639,14 @@ static int set_default_channel_config(AACContext *ac, AVCodecContext *avctx, * 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 && (!ac || !ac->warned_71_wide++)) { - 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); + if (channel_config == 7 && avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) { layout_map[2][2] = AAC_CHANNEL_SIDE; + + if (!ac || !ac->warned_71_wide++) { + 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); + } } return 0; @@ -606,6 +701,13 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) /* For indexed channel configurations map the channels solely based * on position. */ switch (ac->oc[1].m4ac.chan_config) { + case 13: + if (ac->tags_mapped > 3 && ((type == TYPE_CPE && elem_id < 8) || + (type == TYPE_SCE && elem_id < 6) || + (type == TYPE_LFE && elem_id < 2))) { + ac->tags_mapped++; + return ac->tag_che_map[type][elem_id] = ac->che[type][elem_id]; + } case 12: case 7: if (ac->tags_mapped == 3 && type == TYPE_CPE) { @@ -1096,29 +1198,25 @@ 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]), \ - size); - static void aacdec_init(AACContext *ac); static av_cold void aac_static_table_init(void) { - AAC_INIT_VLC_STATIC( 0, 304); - AAC_INIT_VLC_STATIC( 1, 270); - AAC_INIT_VLC_STATIC( 2, 550); - AAC_INIT_VLC_STATIC( 3, 300); - AAC_INIT_VLC_STATIC( 4, 328); - AAC_INIT_VLC_STATIC( 5, 294); - AAC_INIT_VLC_STATIC( 6, 306); - AAC_INIT_VLC_STATIC( 7, 268); - AAC_INIT_VLC_STATIC( 8, 510); - AAC_INIT_VLC_STATIC( 9, 366); - AAC_INIT_VLC_STATIC(10, 462); + static VLC_TYPE vlc_buf[304 + 270 + 550 + 300 + 328 + + 294 + 306 + 268 + 510 + 366 + 462][2]; + for (unsigned i = 0, offset = 0; i < 11; i++) { + vlc_spectral[i].table = &vlc_buf[offset]; + vlc_spectral[i].table_allocated = FF_ARRAY_ELEMS(vlc_buf) - offset; + ff_init_vlc_sparse(&vlc_spectral[i], 8, ff_aac_spectral_sizes[i], + ff_aac_spectral_bits[i], sizeof(ff_aac_spectral_bits[i][0]), + sizeof(ff_aac_spectral_bits[i][0]), + ff_aac_spectral_codes[i], sizeof(ff_aac_spectral_codes[i][0]), + sizeof(ff_aac_spectral_codes[i][0]), + ff_aac_codebook_vector_idx[i], sizeof(ff_aac_codebook_vector_idx[i][0]), + sizeof(ff_aac_codebook_vector_idx[i][0]), + INIT_VLC_STATIC_OVERLONG); + offset += vlc_spectral[i].table_size; + } AAC_RENAME(ff_aac_sbr_init)(); @@ -1135,17 +1233,18 @@ static av_cold void aac_static_table_init(void) 352); // window initialization - AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_long_1024), 4.0, 1024); - AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_short_128), 6.0, 128); #if !USE_FIXED - AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_long_960), 4.0, 960); - AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_short_120), 6.0, 120); - AAC_RENAME(ff_sine_window_init)(AAC_RENAME(ff_sine_960), 960); - AAC_RENAME(ff_sine_window_init)(AAC_RENAME(ff_sine_120), 120); + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(aac_kbd_long_960), 4.0, 960); + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(aac_kbd_short_120), 6.0, 120); + AAC_RENAME(ff_sine_window_init)(AAC_RENAME(sine_960), 960); + AAC_RENAME(ff_sine_window_init)(AAC_RENAME(sine_120), 120); + AAC_RENAME(ff_init_ff_sine_windows)(9); + ff_aac_float_common_init(); +#else + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME2(aac_kbd_long_1024), 4.0, 1024); + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME2(aac_kbd_short_128), 6.0, 128); + init_sine_windows_fixed(); #endif - AAC_RENAME(ff_init_ff_sine_windows)(10); - AAC_RENAME(ff_init_ff_sine_windows)( 9); - AAC_RENAME(ff_init_ff_sine_windows)( 7); AAC_RENAME(ff_cbrt_tableinit)(); } @@ -1703,7 +1802,6 @@ static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024], #if !USE_FIXED const float *vq = ff_aac_codebook_vector_vals[cbt_m1]; #endif /* !USE_FIXED */ - const uint16_t *cb_vector_idx = ff_aac_codebook_vector_idx[cbt_m1]; VLC_TYPE (*vlc_tab)[2] = vlc_spectral[cbt_m1].table; OPEN_READER(re, gb); @@ -1719,7 +1817,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024], UPDATE_CACHE(re, gb); GET_VLC(code, re, gb, vlc_tab, 8, 2); - cb_idx = cb_vector_idx[code]; + cb_idx = code; #if USE_FIXED cf = DEC_SQUAD(cf, cb_idx); #else @@ -1742,7 +1840,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024], UPDATE_CACHE(re, gb); GET_VLC(code, re, gb, vlc_tab, 8, 2); - cb_idx = cb_vector_idx[code]; + cb_idx = code; nnz = cb_idx >> 8 & 15; bits = nnz ? GET_CACHE(re, gb) : 0; LAST_SKIP_BITS(re, gb, nnz); @@ -1766,7 +1864,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024], UPDATE_CACHE(re, gb); GET_VLC(code, re, gb, vlc_tab, 8, 2); - cb_idx = cb_vector_idx[code]; + cb_idx = code; #if USE_FIXED cf = DEC_SPAIR(cf, cb_idx); #else @@ -1790,7 +1888,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024], UPDATE_CACHE(re, gb); GET_VLC(code, re, gb, vlc_tab, 8, 2); - cb_idx = cb_vector_idx[code]; + cb_idx = code; nnz = cb_idx >> 8 & 15; sign = nnz ? SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12) : 0; LAST_SKIP_BITS(re, gb, nnz); @@ -1823,14 +1921,14 @@ static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024], UPDATE_CACHE(re, gb); GET_VLC(code, re, gb, vlc_tab, 8, 2); + cb_idx = code; - if (!code) { + if (cb_idx == 0x0000) { *icf++ = 0; *icf++ = 0; continue; } - cb_idx = cb_vector_idx[code]; nnz = cb_idx >> 12; nzt = cb_idx >> 8; bits = SHOW_UBITS(re, gb, nnz) << (32-nnz); @@ -2548,10 +2646,10 @@ static void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns, static void windowing_and_mdct_ltp(AACContext *ac, INTFLOAT *out, INTFLOAT *in, IndividualChannelStream *ics) { - const INTFLOAT *lwindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_long_1024) : AAC_RENAME(ff_sine_1024); - const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); - const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_long_1024) : AAC_RENAME(ff_sine_1024); - const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); + const INTFLOAT *lwindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024); + const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128); + const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024); + const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128); if (ics->window_sequence[0] != LONG_STOP_SEQUENCE) { ac->fdsp->vector_fmul(in, in, lwindow_prev, 1024); @@ -2608,8 +2706,8 @@ static void update_ltp(AACContext *ac, SingleChannelElement *sce) IndividualChannelStream *ics = &sce->ics; INTFLOAT *saved = sce->saved; INTFLOAT *saved_ltp = sce->coeffs; - const INTFLOAT *lwindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_long_1024) : AAC_RENAME(ff_sine_1024); - const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); + const INTFLOAT *lwindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024); + const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128); int i; if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { @@ -2647,9 +2745,9 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce) INTFLOAT *in = sce->coeffs; INTFLOAT *out = sce->ret; INTFLOAT *saved = sce->saved; - const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); - const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_long_1024) : AAC_RENAME(ff_sine_1024); - const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); + const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128); + const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024); + const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128); INTFLOAT *buf = ac->buf_mdct; INTFLOAT *temp = ac->temp; int i; @@ -2716,9 +2814,9 @@ static void imdct_and_windowing_960(AACContext *ac, SingleChannelElement *sce) INTFLOAT *in = sce->coeffs; INTFLOAT *out = sce->ret; INTFLOAT *saved = sce->saved; - const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_120) : AAC_RENAME(ff_sine_120); - const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_long_960) : AAC_RENAME(ff_sine_960); - const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_short_120) : AAC_RENAME(ff_sine_120); + const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(aac_kbd_short_120) : AAC_RENAME(sine_120); + const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_long_960) : AAC_RENAME(sine_960); + const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_short_120) : AAC_RENAME(sine_120); INTFLOAT *buf = ac->buf_mdct; INTFLOAT *temp = ac->temp; int i; @@ -2795,10 +2893,10 @@ static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce) if (ics->use_kb_window[1]) { // AAC LD uses a low overlap sine window instead of a KBD window memcpy(out, saved, 192 * sizeof(*out)); - ac->fdsp->vector_fmul_window(out + 192, saved + 192, buf, AAC_RENAME(ff_sine_128), 64); + ac->fdsp->vector_fmul_window(out + 192, saved + 192, buf, AAC_RENAME2(sine_128), 64); memcpy( out + 320, buf + 64, 192 * sizeof(*out)); } else { - ac->fdsp->vector_fmul_window(out, saved, buf, AAC_RENAME(ff_sine_512), 256); + ac->fdsp->vector_fmul_window(out, saved, buf, AAC_RENAME2(sine_512), 256); } // buffer update @@ -2807,7 +2905,7 @@ static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce) static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce) { - INTFLOAT *in = sce->coeffs; + UINTFLOAT *in = sce->coeffs; INTFLOAT *out = sce->ret; INTFLOAT *saved = sce->saved; INTFLOAT *buf = ac->buf_mdct; @@ -3118,7 +3216,8 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data, } static int aac_decode_frame_int(AVCodecContext *avctx, void *data, - int *got_frame_ptr, GetBitContext *gb, AVPacket *avpkt) + int *got_frame_ptr, GetBitContext *gb, + const AVPacket *avpkt) { AACContext *ac = avctx->priv_data; ChannelElement *che = NULL, *che_prev = NULL; @@ -3213,7 +3312,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, break; case TYPE_PCE: { - uint8_t layout_map[MAX_ELEM_ID*4][3]; + uint8_t layout_map[MAX_ELEM_ID*4][3] = {{0}}; int tags; int pushed = push_output_configuration(ac); @@ -3338,11 +3437,11 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, int buf_consumed; int buf_offset; int err; - int new_extradata_size; + buffer_size_t new_extradata_size; const uint8_t *new_extradata = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &new_extradata_size); - int jp_dualmono_size; + buffer_size_t jp_dualmono_size; const uint8_t *jp_dualmono = av_packet_get_side_data(avpkt, AV_PKT_DATA_JP_DUALMONO, &jp_dualmono_size); diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h index baf51a74b..c54a3eb94 100644 --- a/libavcodec/aacdectab.h +++ b/libavcodec/aacdectab.h @@ -35,9 +35,9 @@ #include -static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 4, 5, 0, 5, 0 }; +static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 4, 5, 16, 5, 0 }; -static const uint8_t aac_channel_layout_map[16][5][3] = { +static const uint8_t aac_channel_layout_map[16][16][3] = { { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, }, { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, }, { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, }, @@ -50,6 +50,24 @@ static const uint8_t aac_channel_layout_map[16][5][3] = { { { 0, } }, { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, }, { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, }, + { + { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, // SCE1 = FC, + { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, // CPE1 = FLc and FRc, + { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, // CPE2 = FL and FR, + { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, // CPE3 = SiL and SiR, + { TYPE_CPE, 3, AAC_CHANNEL_BACK }, // CPE4 = BL and BR, + { TYPE_SCE, 1, AAC_CHANNEL_BACK }, // SCE2 = BC, + { TYPE_LFE, 0, AAC_CHANNEL_LFE }, // LFE1 = LFE1, + { TYPE_LFE, 1, AAC_CHANNEL_LFE }, // LFE2 = LFE2, + { TYPE_SCE, 2, AAC_CHANNEL_FRONT }, // SCE3 = TpFC, + { TYPE_CPE, 4, AAC_CHANNEL_FRONT }, // CPE5 = TpFL and TpFR, + { TYPE_CPE, 5, AAC_CHANNEL_SIDE }, // CPE6 = TpSiL and TpSiR, + { TYPE_SCE, 3, AAC_CHANNEL_FRONT }, // SCE4 = TpC, + { TYPE_CPE, 6, AAC_CHANNEL_BACK }, // CPE7 = TpBL and TpBR, + { TYPE_SCE, 4, AAC_CHANNEL_BACK }, // SCE5 = TpBC, + { TYPE_SCE, 5, AAC_CHANNEL_FRONT }, // SCE6 = BtFC, + { TYPE_CPE, 7, AAC_CHANNEL_FRONT }, // CPE8 = BtFL and BtFR + }, { { 0, } }, /* TODO: Add 7+1 TOP configuration */ }; @@ -67,6 +85,7 @@ static const uint64_t aac_channel_layout[16] = { 0, AV_CH_LAYOUT_6POINT1, AV_CH_LAYOUT_7POINT1, + AV_CH_LAYOUT_22POINT2, 0, /* AV_CH_LAYOUT_7POINT1_TOP, */ }; diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index db11e0ca2..070a2e706 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -30,14 +30,12 @@ ***********************************/ #include "libavutil/libm.h" -#include "libavutil/thread.h" #include "libavutil/float_dsp.h" #include "libavutil/opt.h" #include "avcodec.h" #include "put_bits.h" #include "internal.h" #include "mpeg4audio.h" -#include "kbdwin.h" #include "sinewin.h" #include "profiles.h" @@ -49,8 +47,6 @@ #include "psymodel.h" -static AVOnce aac_table_init = AV_ONCE_INIT; - static void put_pce(PutBitContext *pb, AVCodecContext *avctx) { int i, j; @@ -83,9 +79,9 @@ static void put_pce(PutBitContext *pb, AVCodecContext *avctx) } } - avpriv_align_put_bits(pb); + align_put_bits(pb); put_bits(pb, 8, strlen(aux_data)); - avpriv_put_string(pb, aux_data, 0); + ff_put_string(pb, aux_data, 0); } /** @@ -522,7 +518,7 @@ static void put_bitstream_info(AACEncContext *s, const char *name) put_bits(&s->pb, 8, namelen - 14); put_bits(&s->pb, 4, 0); //extension type - filler padbits = -put_bits_count(&s->pb) & 7; - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); for (i = 0; i < namelen - 2; i++) put_bits(&s->pb, 8, name[i]); put_bits(&s->pb, 12 - padbits, 0); @@ -925,10 +921,7 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) return AVERROR(ENOMEM); // window init - ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); - ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); - ff_init_ff_sine_windows(10); - ff_init_ff_sine_windows(7); + ff_aac_float_common_init(); if ((ret = ff_mdct_init(&s->mdct1024, 11, 0, 32768.0)) < 0) return ret; @@ -941,20 +934,14 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) static av_cold int alloc_buffers(AVCodecContext *avctx, AACEncContext *s) { int ch; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->buffer.samples, s->channels, 3 * 1024 * sizeof(s->buffer.samples[0]), alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->cpe, s->chan_map[0], sizeof(ChannelElement), alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->buffer.samples, s->channels * 3 * 1024) || + !FF_ALLOCZ_TYPED_ARRAY(s->cpe, s->chan_map[0])) + return AVERROR(ENOMEM); for(ch = 0; ch < s->channels; ch++) s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch; return 0; -alloc_fail: - return AVERROR(ENOMEM); -} - -static av_cold void aac_encode_init_tables(void) -{ - ff_aac_tableinit(); } static av_cold int aac_encode_init(AVCodecContext *avctx) @@ -1078,13 +1065,13 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) s->options.mid_side = 0; if ((ret = dsp_init(avctx, s)) < 0) - goto fail; + return ret; if ((ret = alloc_buffers(avctx, s)) < 0) - goto fail; + return ret; if ((ret = put_audio_specific_config(avctx))) - goto fail; + return ret; sizes[0] = ff_aac_swb_size_1024[s->samplerate_index]; sizes[1] = ff_aac_swb_size_128[s->samplerate_index]; @@ -1094,7 +1081,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) grouping[i] = s->chan_map[i + 1] == TYPE_CPE; if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping)) < 0) - goto fail; + return ret; s->psypp = ff_psy_preprocess_init(avctx); ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON); s->random_state = 0x1f2e3d4c; @@ -1108,15 +1095,10 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) if (HAVE_MIPSDSP) ff_aac_coder_init_mips(s); - if ((ret = ff_thread_once(&aac_table_init, &aac_encode_init_tables)) != 0) - return AVERROR_UNKNOWN; - ff_af_queue_init(avctx, &s->afq); + ff_aac_tableinit(); return 0; -fail: - aac_encode_end(avctx); - return ret; } #define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM @@ -1159,7 +1141,7 @@ AVCodec ff_aac_encoder = { .close = aac_encode_end, .defaults = aac_encode_defaults, .supported_samplerates = mpeg4audio_sample_rates, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h index 5a015ca92..8ffc94f99 100644 --- a/libavcodec/aacenc.h +++ b/libavcodec/aacenc.h @@ -23,6 +23,8 @@ #define AVCODEC_AACENC_H #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "put_bits.h" diff --git a/libavcodec/aacenctab.c b/libavcodec/aacenctab.c index f3d70fbe3..874365a59 100644 --- a/libavcodec/aacenctab.c +++ b/libavcodec/aacenctab.c @@ -88,7 +88,7 @@ static const uint8_t swb_size_1024_8[] = { 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80 }; -const uint8_t *ff_aac_swb_size_128[] = { +const uint8_t *const ff_aac_swb_size_128[] = { swb_size_128_96, swb_size_128_96, swb_size_128_64, swb_size_128_48, swb_size_128_48, swb_size_128_48, swb_size_128_24, swb_size_128_24, swb_size_128_16, @@ -96,7 +96,7 @@ const uint8_t *ff_aac_swb_size_128[] = { swb_size_128_8 }; -const uint8_t *ff_aac_swb_size_1024[] = { +const uint8_t *const ff_aac_swb_size_1024[] = { swb_size_1024_96, swb_size_1024_96, swb_size_1024_64, swb_size_1024_48, swb_size_1024_48, swb_size_1024_32, swb_size_1024_24, swb_size_1024_24, swb_size_1024_16, diff --git a/libavcodec/aacenctab.h b/libavcodec/aacenctab.h index 64932d709..dbbdf61df 100644 --- a/libavcodec/aacenctab.h +++ b/libavcodec/aacenctab.h @@ -38,9 +38,9 @@ #define AAC_MAX_CHANNELS 16 -extern const uint8_t *ff_aac_swb_size_1024[]; +extern const uint8_t *const ff_aac_swb_size_1024[]; extern const int ff_aac_swb_size_1024_len; -extern const uint8_t *ff_aac_swb_size_128[]; +extern const uint8_t *const ff_aac_swb_size_128[]; extern const int ff_aac_swb_size_128_len; /* Supported layouts without using a PCE */ diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c index 22df160fe..6c7a33fea 100644 --- a/libavcodec/aacps.c +++ b/libavcodec/aacps.c @@ -25,8 +25,8 @@ #include #include "libavutil/common.h" #include "libavutil/mathematics.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" -#include "get_bits.h" #include "aacps.h" #if USE_FIXED #include "aacps_fixed_tablegen.h" @@ -34,118 +34,12 @@ #include "libavutil/internal.h" #include "aacps_tablegen.h" #endif /* USE_FIXED */ -#include "aacpsdata.c" -#define PS_BASELINE 0 ///< Operate in Baseline PS mode - ///< Baseline implies 10 or 20 stereo bands, - ///< mixing mode A, and no ipd/opd - -#define numQMFSlots 32 //numTimeSlots * RATE - -static const int8_t num_env_tab[2][4] = { - { 0, 1, 2, 4, }, - { 1, 2, 3, 4, }, +static const INTFLOAT g1_Q2[] = { + Q31(0.0f), Q31(0.01899487526049f), Q31(0.0f), Q31(-0.07293139167538f), + Q31(0.0f), Q31(0.30596630545168f), Q31(0.5f) }; -static const int8_t nr_iidicc_par_tab[] = { - 10, 20, 34, 10, 20, 34, -}; - -static const int8_t nr_iidopd_par_tab[] = { - 5, 11, 17, 5, 11, 17, -}; - -enum { - huff_iid_df1, - huff_iid_dt1, - huff_iid_df0, - huff_iid_dt0, - huff_icc_df, - huff_icc_dt, - huff_ipd_df, - huff_ipd_dt, - huff_opd_df, - huff_opd_dt, -}; - -static const int huff_iid[] = { - huff_iid_df0, - huff_iid_df1, - huff_iid_dt0, - huff_iid_dt1, -}; - -static VLC vlc_ps[10]; - -#define READ_PAR_DATA(PAR, OFFSET, MASK, ERR_CONDITION) \ -/** \ - * Read Inter-channel Intensity Difference/Inter-Channel Coherence/ \ - * Inter-channel Phase Difference/Overall Phase Difference parameters from the \ - * bitstream. \ - * \ - * @param avctx contains the current codec context \ - * @param gb pointer to the input bitstream \ - * @param ps pointer to the Parametric Stereo context \ - * @param PAR pointer to the parameter to be read \ - * @param e envelope to decode \ - * @param dt 1: time delta-coded, 0: frequency delta-coded \ - */ \ -static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, \ - int8_t (*PAR)[PS_MAX_NR_IIDICC], int table_idx, int e, int dt) \ -{ \ - int b, num = ps->nr_ ## PAR ## _par; \ - VLC_TYPE (*vlc_table)[2] = vlc_ps[table_idx].table; \ - if (dt) { \ - int e_prev = e ? e - 1 : ps->num_env_old - 1; \ - e_prev = FFMAX(e_prev, 0); \ - for (b = 0; b < num; b++) { \ - int val = PAR[e_prev][b] + get_vlc2(gb, vlc_table, 9, 3) - OFFSET; \ - if (MASK) val &= MASK; \ - PAR[e][b] = val; \ - if (ERR_CONDITION) \ - goto err; \ - } \ - } else { \ - int val = 0; \ - for (b = 0; b < num; b++) { \ - val += get_vlc2(gb, vlc_table, 9, 3) - OFFSET; \ - if (MASK) val &= MASK; \ - PAR[e][b] = val; \ - if (ERR_CONDITION) \ - goto err; \ - } \ - } \ - return 0; \ -err: \ - av_log(avctx, AV_LOG_ERROR, "illegal "#PAR"\n"); \ - return AVERROR_INVALIDDATA; \ -} - -READ_PAR_DATA(iid, huff_offset[table_idx], 0, FFABS(ps->iid_par[e][b]) > 7 + 8 * ps->iid_quant) -READ_PAR_DATA(icc, huff_offset[table_idx], 0, ps->icc_par[e][b] > 7U) -READ_PAR_DATA(ipdopd, 0, 0x07, 0) - -static int ps_read_extension_data(GetBitContext *gb, PSContext *ps, int ps_extension_id) -{ - int e; - int count = get_bits_count(gb); - - if (ps_extension_id) - return 0; - - ps->enable_ipdopd = get_bits1(gb); - if (ps->enable_ipdopd) { - for (e = 0; e < ps->num_env; e++) { - int dt = get_bits1(gb); - read_ipdopd_data(NULL, gb, ps, ps->ipd_par, dt ? huff_ipd_dt : huff_ipd_df, e, dt); - dt = get_bits1(gb); - read_ipdopd_data(NULL, gb, ps, ps->opd_par, dt ? huff_opd_dt : huff_opd_df, e, dt); - } - } - skip_bits1(gb); //reserved_ps - return get_bits_count(gb) - count; -} - static void ipdopd_reset(int8_t *ipd_hist, int8_t *opd_hist) { int i; @@ -155,163 +49,6 @@ static void ipdopd_reset(int8_t *ipd_hist, int8_t *opd_hist) } } -int AAC_RENAME(ff_ps_read_data)(AVCodecContext *avctx, GetBitContext *gb_host, PSContext *ps, int bits_left) -{ - int e; - int bit_count_start = get_bits_count(gb_host); - int header; - int bits_consumed; - GetBitContext gbc = *gb_host, *gb = &gbc; - - header = get_bits1(gb); - if (header) { //enable_ps_header - ps->enable_iid = get_bits1(gb); - if (ps->enable_iid) { - int iid_mode = get_bits(gb, 3); - if (iid_mode > 5) { - av_log(avctx, AV_LOG_ERROR, "iid_mode %d is reserved.\n", - iid_mode); - goto err; - } - ps->nr_iid_par = nr_iidicc_par_tab[iid_mode]; - ps->iid_quant = iid_mode > 2; - ps->nr_ipdopd_par = nr_iidopd_par_tab[iid_mode]; - } - ps->enable_icc = get_bits1(gb); - if (ps->enable_icc) { - ps->icc_mode = get_bits(gb, 3); - if (ps->icc_mode > 5) { - av_log(avctx, AV_LOG_ERROR, "icc_mode %d is reserved.\n", - ps->icc_mode); - goto err; - } - ps->nr_icc_par = nr_iidicc_par_tab[ps->icc_mode]; - } - ps->enable_ext = get_bits1(gb); - } - - ps->frame_class = get_bits1(gb); - ps->num_env_old = ps->num_env; - ps->num_env = num_env_tab[ps->frame_class][get_bits(gb, 2)]; - - ps->border_position[0] = -1; - if (ps->frame_class) { - for (e = 1; e <= ps->num_env; e++) { - ps->border_position[e] = get_bits(gb, 5); - if (ps->border_position[e] < ps->border_position[e-1]) { - av_log(avctx, AV_LOG_ERROR, "border_position non monotone.\n"); - goto err; - } - } - } else - for (e = 1; e <= ps->num_env; e++) - ps->border_position[e] = (e * numQMFSlots >> ff_log2_tab[ps->num_env]) - 1; - - if (ps->enable_iid) { - for (e = 0; e < ps->num_env; e++) { - int dt = get_bits1(gb); - if (read_iid_data(avctx, gb, ps, ps->iid_par, huff_iid[2*dt+ps->iid_quant], e, dt)) - goto err; - } - } else - memset(ps->iid_par, 0, sizeof(ps->iid_par)); - - if (ps->enable_icc) - for (e = 0; e < ps->num_env; e++) { - int dt = get_bits1(gb); - if (read_icc_data(avctx, gb, ps, ps->icc_par, dt ? huff_icc_dt : huff_icc_df, e, dt)) - goto err; - } - else - memset(ps->icc_par, 0, sizeof(ps->icc_par)); - - if (ps->enable_ext) { - int cnt = get_bits(gb, 4); - if (cnt == 15) { - cnt += get_bits(gb, 8); - } - cnt *= 8; - while (cnt > 7) { - int ps_extension_id = get_bits(gb, 2); - cnt -= 2 + ps_read_extension_data(gb, ps, ps_extension_id); - } - if (cnt < 0) { - av_log(avctx, AV_LOG_ERROR, "ps extension overflow %d\n", cnt); - goto err; - } - skip_bits(gb, cnt); - } - - ps->enable_ipdopd &= !PS_BASELINE; - - //Fix up envelopes - if (!ps->num_env || ps->border_position[ps->num_env] < numQMFSlots - 1) { - //Create a fake envelope - int source = ps->num_env ? ps->num_env - 1 : ps->num_env_old - 1; - int b; - if (source >= 0 && source != ps->num_env) { - if (ps->enable_iid) { - memcpy(ps->iid_par+ps->num_env, ps->iid_par+source, sizeof(ps->iid_par[0])); - } - if (ps->enable_icc) { - memcpy(ps->icc_par+ps->num_env, ps->icc_par+source, sizeof(ps->icc_par[0])); - } - if (ps->enable_ipdopd) { - memcpy(ps->ipd_par+ps->num_env, ps->ipd_par+source, sizeof(ps->ipd_par[0])); - memcpy(ps->opd_par+ps->num_env, ps->opd_par+source, sizeof(ps->opd_par[0])); - } - } - if (ps->enable_iid){ - for (b = 0; b < ps->nr_iid_par; b++) { - if (FFABS(ps->iid_par[ps->num_env][b]) > 7 + 8 * ps->iid_quant) { - av_log(avctx, AV_LOG_ERROR, "iid_par invalid\n"); - goto err; - } - } - } - if (ps->enable_icc){ - for (b = 0; b < ps->nr_iid_par; b++) { - if (ps->icc_par[ps->num_env][b] > 7U) { - av_log(avctx, AV_LOG_ERROR, "icc_par invalid\n"); - goto err; - } - } - } - ps->num_env++; - ps->border_position[ps->num_env] = numQMFSlots - 1; - } - - - ps->is34bands_old = ps->is34bands; - if (!PS_BASELINE && (ps->enable_iid || ps->enable_icc)) - ps->is34bands = (ps->enable_iid && ps->nr_iid_par == 34) || - (ps->enable_icc && ps->nr_icc_par == 34); - - //Baseline - if (!ps->enable_ipdopd) { - memset(ps->ipd_par, 0, sizeof(ps->ipd_par)); - memset(ps->opd_par, 0, sizeof(ps->opd_par)); - } - - if (header) - ps->start = 1; - - bits_consumed = get_bits_count(gb) - bit_count_start; - if (bits_consumed <= bits_left) { - skip_bits_long(gb_host, bits_consumed); - return bits_consumed; - } - av_log(avctx, AV_LOG_ERROR, "Expected to read %d PS bits actually read %d.\n", bits_left, bits_consumed); -err: - ps->start = 0; - skip_bits_long(gb_host, bits_left); - memset(ps->iid_par, 0, sizeof(ps->iid_par)); - memset(ps->icc_par, 0, sizeof(ps->icc_par)); - memset(ps->ipd_par, 0, sizeof(ps->ipd_par)); - memset(ps->opd_par, 0, sizeof(ps->opd_par)); - return bits_left; -} - /** Split one subband into 2 subsubbands with a symmetric real filter. * The filter must have its non-center even coefficients equal to zero. */ static void hybrid2_re(INTFLOAT (*in)[2], INTFLOAT (*out)[32][2], const INTFLOAT filter[8], int len, int reverse) @@ -672,14 +409,14 @@ static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT const float transient_impact = 1.5f; const float a_smooth = 0.25f; ///< Smoothing coefficient #endif /* USE_FIXED */ - const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20; + const int8_t *const k_to_i = is34 ? ff_k_to_i_34 : ff_k_to_i_20; int i, k, m, n; int n0 = 0, nL = 32; const INTFLOAT peak_decay_factor = Q31(0.76592833836465f); memset(power, 0, 34 * sizeof(*power)); - if (is34 != ps->is34bands_old) { + if (is34 != ps->common.is34bands_old) { memset(ps->peak_decay_nrg, 0, sizeof(ps->peak_decay_nrg)); memset(ps->power_smooth, 0, sizeof(ps->power_smooth)); memset(ps->peak_decay_diff_smooth, 0, sizeof(ps->peak_decay_diff_smooth)); @@ -821,6 +558,7 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r) { int e, b, k; + PSCommonContext *const ps2 = &ps->common; INTFLOAT (*H11)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H11; INTFLOAT (*H12)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H12; INTFLOAT (*H21)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H21; @@ -835,29 +573,29 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r) int8_t (*icc_mapped)[PS_MAX_NR_IIDICC] = icc_mapped_buf; 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; - TABLE_CONST INTFLOAT (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB; + const int8_t *const k_to_i = is34 ? ff_k_to_i_34 : ff_k_to_i_20; + TABLE_CONST INTFLOAT (*H_LUT)[8][4] = (PS_BASELINE || ps2->icc_mode < 3) ? HA : HB; //Remapping - if (ps->num_env_old) { - memcpy(H11[0][0], H11[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[0][0][0])); - memcpy(H11[1][0], H11[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[1][0][0])); - memcpy(H12[0][0], H12[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[0][0][0])); - memcpy(H12[1][0], H12[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[1][0][0])); - memcpy(H21[0][0], H21[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[0][0][0])); - memcpy(H21[1][0], H21[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[1][0][0])); - memcpy(H22[0][0], H22[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[0][0][0])); - memcpy(H22[1][0], H22[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[1][0][0])); + if (ps2->num_env_old) { + memcpy(H11[0][0], H11[0][ps2->num_env_old], sizeof(H11[0][0])); + memcpy(H11[1][0], H11[1][ps2->num_env_old], sizeof(H11[1][0])); + memcpy(H12[0][0], H12[0][ps2->num_env_old], sizeof(H12[0][0])); + memcpy(H12[1][0], H12[1][ps2->num_env_old], sizeof(H12[1][0])); + memcpy(H21[0][0], H21[0][ps2->num_env_old], sizeof(H21[0][0])); + memcpy(H21[1][0], H21[1][ps2->num_env_old], sizeof(H21[1][0])); + memcpy(H22[0][0], H22[0][ps2->num_env_old], sizeof(H22[0][0])); + memcpy(H22[1][0], H22[1][ps2->num_env_old], sizeof(H22[1][0])); } if (is34) { - remap34(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1); - remap34(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1); - if (ps->enable_ipdopd) { - remap34(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0); - remap34(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0); + remap34(&iid_mapped, ps2->iid_par, ps2->nr_iid_par, ps2->num_env, 1); + remap34(&icc_mapped, ps2->icc_par, ps2->nr_icc_par, ps2->num_env, 1); + if (ps2->enable_ipdopd) { + remap34(&ipd_mapped, ps2->ipd_par, ps2->nr_ipdopd_par, ps2->num_env, 0); + remap34(&opd_mapped, ps2->opd_par, ps2->nr_ipdopd_par, ps2->num_env, 0); } - if (!ps->is34bands_old) { + if (!ps2->is34bands_old) { map_val_20_to_34(H11[0][0]); map_val_20_to_34(H11[1][0]); map_val_20_to_34(H12[0][0]); @@ -869,13 +607,13 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r) ipdopd_reset(ipd_hist, opd_hist); } } else { - remap20(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1); - remap20(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1); - if (ps->enable_ipdopd) { - remap20(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0); - remap20(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0); + remap20(&iid_mapped, ps2->iid_par, ps2->nr_iid_par, ps2->num_env, 1); + remap20(&icc_mapped, ps2->icc_par, ps2->nr_icc_par, ps2->num_env, 1); + if (ps2->enable_ipdopd) { + remap20(&ipd_mapped, ps2->ipd_par, ps2->nr_ipdopd_par, ps2->num_env, 0); + remap20(&opd_mapped, ps2->opd_par, ps2->nr_ipdopd_par, ps2->num_env, 0); } - if (ps->is34bands_old) { + if (ps2->is34bands_old) { map_val_34_to_20(H11[0][0]); map_val_34_to_20(H11[1][0]); map_val_34_to_20(H12[0][0]); @@ -889,15 +627,15 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r) } //Mixing - for (e = 0; e < ps->num_env; e++) { + for (e = 0; e < ps2->num_env; e++) { for (b = 0; b < NR_PAR_BANDS[is34]; b++) { INTFLOAT h11, h12, h21, h22; - h11 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][0]; - 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]; + h11 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps2->iid_quant][icc_mapped[e][b]][0]; + h12 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps2->iid_quant][icc_mapped[e][b]][1]; + h21 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps2->iid_quant][icc_mapped[e][b]][2]; + h22 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps2->iid_quant][icc_mapped[e][b]][3]; - if (!PS_BASELINE && ps->enable_ipdopd && b < NR_IPDOPD_BANDS[is34]) { + if (!PS_BASELINE && ps2->enable_ipdopd && b < NR_IPDOPD_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 INTFLOAT h11i, h12i, h21i, h22i; @@ -934,8 +672,8 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r) for (k = 0; k < NR_BANDS[is34]; k++) { LOCAL_ALIGNED_16(INTFLOAT, h, [2], [4]); LOCAL_ALIGNED_16(INTFLOAT, h_step, [2], [4]); - int start = ps->border_position[e]; - int stop = ps->border_position[e+1]; + int start = ps2->border_position[e]; + int stop = ps2->border_position[e+1]; INTFLOAT width = Q30(1.f) / ((stop - start) ? (stop - start) : 1); #if USE_FIXED width = FFMIN(2U*width, INT_MAX); @@ -945,7 +683,7 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r) h[0][1] = H12[0][e][b]; h[0][2] = H21[0][e][b]; h[0][3] = H22[0][e][b]; - if (!PS_BASELINE && ps->enable_ipdopd) { + if (!PS_BASELINE && ps2->enable_ipdopd) { //Is this necessary? ps_04_new seems unchanged if ((is34 && k <= 13 && k >= 9) || (!is34 && k <= 1)) { h[1][0] = -H11[1][e][b]; @@ -964,14 +702,14 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r) h_step[0][1] = AAC_MSUB31_V3(H12[0][e+1][b], h[0][1], width); h_step[0][2] = AAC_MSUB31_V3(H21[0][e+1][b], h[0][2], width); h_step[0][3] = AAC_MSUB31_V3(H22[0][e+1][b], h[0][3], width); - if (!PS_BASELINE && ps->enable_ipdopd) { + if (!PS_BASELINE && ps2->enable_ipdopd) { h_step[1][0] = AAC_MSUB31_V3(H11[1][e+1][b], h[1][0], width); h_step[1][1] = AAC_MSUB31_V3(H12[1][e+1][b], h[1][1], width); h_step[1][2] = AAC_MSUB31_V3(H21[1][e+1][b], h[1][2], width); h_step[1][3] = AAC_MSUB31_V3(H22[1][e+1][b], h[1][3], width); } if (stop - start) - ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd]( + ps->dsp.stereo_interpolate[!PS_BASELINE && ps2->enable_ipdopd]( l[k] + 1 + start, r[k] + 1 + start, h, h_step, stop - start); } @@ -983,7 +721,7 @@ int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][ INTFLOAT (*Lbuf)[32][2] = ps->Lbuf; INTFLOAT (*Rbuf)[32][2] = ps->Rbuf; const int len = 32; - int is34 = ps->is34bands; + int is34 = ps->common.is34bands; top += NR_BANDS[is34] - 64; memset(ps->delay+top, 0, (NR_BANDS[is34] - top)*sizeof(ps->delay[0])); @@ -999,45 +737,9 @@ int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][ return 0; } -#define PS_INIT_VLC_STATIC(num, size) \ - INIT_VLC_STATIC(&vlc_ps[num], 9, ps_tmp[num].table_size / ps_tmp[num].elem_size, \ - ps_tmp[num].ps_bits, 1, 1, \ - ps_tmp[num].ps_codes, ps_tmp[num].elem_size, ps_tmp[num].elem_size, \ - size); - -#define PS_VLC_ROW(name) \ - { name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) } - av_cold void AAC_RENAME(ff_ps_init)(void) { - // Syntax initialization - static const struct { - const void *ps_codes, *ps_bits; - const unsigned int table_size, elem_size; - } ps_tmp[] = { - PS_VLC_ROW(huff_iid_df1), - PS_VLC_ROW(huff_iid_dt1), - PS_VLC_ROW(huff_iid_df0), - PS_VLC_ROW(huff_iid_dt0), - PS_VLC_ROW(huff_icc_df), - PS_VLC_ROW(huff_icc_dt), - PS_VLC_ROW(huff_ipd_df), - PS_VLC_ROW(huff_ipd_dt), - PS_VLC_ROW(huff_opd_df), - PS_VLC_ROW(huff_opd_dt), - }; - - PS_INIT_VLC_STATIC(0, 1544); - PS_INIT_VLC_STATIC(1, 832); - PS_INIT_VLC_STATIC(2, 1024); - PS_INIT_VLC_STATIC(3, 1036); - PS_INIT_VLC_STATIC(4, 544); - PS_INIT_VLC_STATIC(5, 544); - PS_INIT_VLC_STATIC(6, 512); - PS_INIT_VLC_STATIC(7, 512); - PS_INIT_VLC_STATIC(8, 512); - PS_INIT_VLC_STATIC(9, 512); - ps_tableinit(); + ff_ps_init_common(); } av_cold void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps) diff --git a/libavcodec/aacps.h b/libavcodec/aacps.h index 61edce354..3efa38ad8 100644 --- a/libavcodec/aacps.h +++ b/libavcodec/aacps.h @@ -24,6 +24,8 @@ #include +#include "libavutil/mem_internal.h" + #include "aacpsdsp.h" #include "avcodec.h" #include "get_bits.h" @@ -37,8 +39,13 @@ #define PS_MAX_DELAY 14 #define PS_AP_LINKS 3 #define PS_MAX_AP_DELAY 5 +#define PS_BASELINE 0 ///< Operate in Baseline PS mode + ///< Baseline implies 10 or 20 stereo bands, + ///< mixing mode A, and no ipd/opd -typedef struct PSContext { +#define numQMFSlots 32 //numTimeSlots * RATE + +typedef struct PSCommonContext { int start; int enable_iid; int iid_quant; @@ -60,6 +67,10 @@ typedef struct PSContext { int8_t opd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Overall Phase Difference Parameters int is34bands; int is34bands_old; +} PSCommonContext; + +typedef struct PSContext { + PSCommonContext common; DECLARE_ALIGNED(16, INTFLOAT, in_buf)[5][44][2]; DECLARE_ALIGNED(16, INTFLOAT, delay)[PS_MAX_SSB][PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2]; @@ -78,9 +89,14 @@ typedef struct PSContext { PSDSPContext dsp; } PSContext; +extern const int8_t ff_k_to_i_20[]; +extern const int8_t ff_k_to_i_34[]; + +void ff_ps_init_common(void); void AAC_RENAME(ff_ps_init)(void); void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps); -int AAC_RENAME(ff_ps_read_data)(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, int bits_left); +int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb, + PSCommonContext *ps, int bits_left); int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top); #endif /* AVCODEC_AACPS_H */ diff --git a/libavcodec/aacps_common.c b/libavcodec/aacps_common.c new file mode 100644 index 000000000..8653b871c --- /dev/null +++ b/libavcodec/aacps_common.c @@ -0,0 +1,336 @@ +/* + * Functions common to fixed/float MPEG-4 Parametric Stereo decoding + * Copyright (c) 2010 Alex Converse + * + * 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/common.h" +#include "libavutil/thread.h" +#include "aacps.h" +#include "get_bits.h" +#include "aacpsdata.c" + +static const int8_t num_env_tab[2][4] = { + { 0, 1, 2, 4, }, + { 1, 2, 3, 4, }, +}; + +static const int8_t nr_iidicc_par_tab[] = { + 10, 20, 34, 10, 20, 34, +}; + +static const int8_t nr_iidopd_par_tab[] = { + 5, 11, 17, 5, 11, 17, +}; + +enum { + huff_iid_df1, + huff_iid_dt1, + huff_iid_df0, + huff_iid_dt0, + huff_icc_df, + huff_icc_dt, + huff_ipd_df, + huff_ipd_dt, + huff_opd_df, + huff_opd_dt, +}; + +static const int huff_iid[] = { + huff_iid_df0, + huff_iid_df1, + huff_iid_dt0, + huff_iid_dt1, +}; + +static VLC vlc_ps[10]; + +#define READ_PAR_DATA(PAR, OFFSET, MASK, ERR_CONDITION, NB_BITS, MAX_DEPTH) \ +/** \ + * Read Inter-channel Intensity Difference/Inter-Channel Coherence/ \ + * Inter-channel Phase Difference/Overall Phase Difference parameters from the \ + * bitstream. \ + * \ + * @param avctx contains the current codec context \ + * @param gb pointer to the input bitstream \ + * @param ps pointer to the Parametric Stereo context \ + * @param PAR pointer to the parameter to be read \ + * @param e envelope to decode \ + * @param dt 1: time delta-coded, 0: frequency delta-coded \ + */ \ +static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSCommonContext *ps, \ + int8_t (*PAR)[PS_MAX_NR_IIDICC], int table_idx, int e, int dt) \ +{ \ + int b, num = ps->nr_ ## PAR ## _par; \ + VLC_TYPE (*vlc_table)[2] = vlc_ps[table_idx].table; \ + if (dt) { \ + int e_prev = e ? e - 1 : ps->num_env_old - 1; \ + e_prev = FFMAX(e_prev, 0); \ + for (b = 0; b < num; b++) { \ + int val = PAR[e_prev][b] + get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH) - OFFSET; \ + if (MASK) val &= MASK; \ + PAR[e][b] = val; \ + if (ERR_CONDITION) \ + goto err; \ + } \ + } else { \ + int val = 0; \ + for (b = 0; b < num; b++) { \ + val += get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH) - OFFSET; \ + if (MASK) val &= MASK; \ + PAR[e][b] = val; \ + if (ERR_CONDITION) \ + goto err; \ + } \ + } \ + return 0; \ +err: \ + av_log(avctx, AV_LOG_ERROR, "illegal "#PAR"\n"); \ + return AVERROR_INVALIDDATA; \ +} + +READ_PAR_DATA(iid, huff_offset[table_idx], 0, FFABS(ps->iid_par[e][b]) > 7 + 8 * ps->iid_quant, 9, 3) +READ_PAR_DATA(icc, huff_offset[table_idx], 0, ps->icc_par[e][b] > 7U, 9, 2) +READ_PAR_DATA(ipdopd, 0, 0x07, 0, 5, 1) + +static int ps_read_extension_data(GetBitContext *gb, PSCommonContext *ps, + int ps_extension_id) +{ + int e; + int count = get_bits_count(gb); + + if (ps_extension_id) + return 0; + + ps->enable_ipdopd = get_bits1(gb); + if (ps->enable_ipdopd) { + for (e = 0; e < ps->num_env; e++) { + int dt = get_bits1(gb); + read_ipdopd_data(NULL, gb, ps, ps->ipd_par, dt ? huff_ipd_dt : huff_ipd_df, e, dt); + dt = get_bits1(gb); + read_ipdopd_data(NULL, gb, ps, ps->opd_par, dt ? huff_opd_dt : huff_opd_df, e, dt); + } + } + skip_bits1(gb); //reserved_ps + return get_bits_count(gb) - count; +} + +int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host, + PSCommonContext *ps, int bits_left) +{ + int e; + int bit_count_start = get_bits_count(gb_host); + int header; + int bits_consumed; + GetBitContext gbc = *gb_host, *gb = &gbc; + + header = get_bits1(gb); + if (header) { //enable_ps_header + ps->enable_iid = get_bits1(gb); + if (ps->enable_iid) { + int iid_mode = get_bits(gb, 3); + if (iid_mode > 5) { + av_log(avctx, AV_LOG_ERROR, "iid_mode %d is reserved.\n", + iid_mode); + goto err; + } + ps->nr_iid_par = nr_iidicc_par_tab[iid_mode]; + ps->iid_quant = iid_mode > 2; + ps->nr_ipdopd_par = nr_iidopd_par_tab[iid_mode]; + } + ps->enable_icc = get_bits1(gb); + if (ps->enable_icc) { + ps->icc_mode = get_bits(gb, 3); + if (ps->icc_mode > 5) { + av_log(avctx, AV_LOG_ERROR, "icc_mode %d is reserved.\n", + ps->icc_mode); + goto err; + } + ps->nr_icc_par = nr_iidicc_par_tab[ps->icc_mode]; + } + ps->enable_ext = get_bits1(gb); + } + + ps->frame_class = get_bits1(gb); + ps->num_env_old = ps->num_env; + ps->num_env = num_env_tab[ps->frame_class][get_bits(gb, 2)]; + + ps->border_position[0] = -1; + if (ps->frame_class) { + for (e = 1; e <= ps->num_env; e++) { + ps->border_position[e] = get_bits(gb, 5); + if (ps->border_position[e] < ps->border_position[e-1]) { + av_log(avctx, AV_LOG_ERROR, "border_position non monotone.\n"); + goto err; + } + } + } else + for (e = 1; e <= ps->num_env; e++) + ps->border_position[e] = (e * numQMFSlots >> ff_log2_tab[ps->num_env]) - 1; + + if (ps->enable_iid) { + for (e = 0; e < ps->num_env; e++) { + int dt = get_bits1(gb); + if (read_iid_data(avctx, gb, ps, ps->iid_par, huff_iid[2*dt+ps->iid_quant], e, dt)) + goto err; + } + } else + memset(ps->iid_par, 0, sizeof(ps->iid_par)); + + if (ps->enable_icc) + for (e = 0; e < ps->num_env; e++) { + int dt = get_bits1(gb); + if (read_icc_data(avctx, gb, ps, ps->icc_par, dt ? huff_icc_dt : huff_icc_df, e, dt)) + goto err; + } + else + memset(ps->icc_par, 0, sizeof(ps->icc_par)); + + if (ps->enable_ext) { + int cnt = get_bits(gb, 4); + if (cnt == 15) { + cnt += get_bits(gb, 8); + } + cnt *= 8; + while (cnt > 7) { + int ps_extension_id = get_bits(gb, 2); + cnt -= 2 + ps_read_extension_data(gb, ps, ps_extension_id); + } + if (cnt < 0) { + av_log(avctx, AV_LOG_ERROR, "ps extension overflow %d\n", cnt); + goto err; + } + skip_bits(gb, cnt); + } + + ps->enable_ipdopd &= !PS_BASELINE; + + //Fix up envelopes + if (!ps->num_env || ps->border_position[ps->num_env] < numQMFSlots - 1) { + //Create a fake envelope + int source = ps->num_env ? ps->num_env - 1 : ps->num_env_old - 1; + int b; + if (source >= 0 && source != ps->num_env) { + if (ps->enable_iid) { + memcpy(ps->iid_par+ps->num_env, ps->iid_par+source, sizeof(ps->iid_par[0])); + } + if (ps->enable_icc) { + memcpy(ps->icc_par+ps->num_env, ps->icc_par+source, sizeof(ps->icc_par[0])); + } + if (ps->enable_ipdopd) { + memcpy(ps->ipd_par+ps->num_env, ps->ipd_par+source, sizeof(ps->ipd_par[0])); + memcpy(ps->opd_par+ps->num_env, ps->opd_par+source, sizeof(ps->opd_par[0])); + } + } + if (ps->enable_iid){ + for (b = 0; b < ps->nr_iid_par; b++) { + if (FFABS(ps->iid_par[ps->num_env][b]) > 7 + 8 * ps->iid_quant) { + av_log(avctx, AV_LOG_ERROR, "iid_par invalid\n"); + goto err; + } + } + } + if (ps->enable_icc){ + for (b = 0; b < ps->nr_iid_par; b++) { + if (ps->icc_par[ps->num_env][b] > 7U) { + av_log(avctx, AV_LOG_ERROR, "icc_par invalid\n"); + goto err; + } + } + } + ps->num_env++; + ps->border_position[ps->num_env] = numQMFSlots - 1; + } + + + ps->is34bands_old = ps->is34bands; + if (!PS_BASELINE && (ps->enable_iid || ps->enable_icc)) + ps->is34bands = (ps->enable_iid && ps->nr_iid_par == 34) || + (ps->enable_icc && ps->nr_icc_par == 34); + + //Baseline + if (!ps->enable_ipdopd) { + memset(ps->ipd_par, 0, sizeof(ps->ipd_par)); + memset(ps->opd_par, 0, sizeof(ps->opd_par)); + } + + if (header) + ps->start = 1; + + bits_consumed = get_bits_count(gb) - bit_count_start; + if (bits_consumed <= bits_left) { + skip_bits_long(gb_host, bits_consumed); + return bits_consumed; + } + av_log(avctx, AV_LOG_ERROR, "Expected to read %d PS bits actually read %d.\n", bits_left, bits_consumed); +err: + ps->start = 0; + skip_bits_long(gb_host, bits_left); + memset(ps->iid_par, 0, sizeof(ps->iid_par)); + memset(ps->icc_par, 0, sizeof(ps->icc_par)); + memset(ps->ipd_par, 0, sizeof(ps->ipd_par)); + memset(ps->opd_par, 0, sizeof(ps->opd_par)); + return bits_left; +} + +#define PS_INIT_VLC_STATIC(num, nb_bits, size) \ + INIT_VLC_STATIC(&vlc_ps[num], nb_bits, ps_tmp[num].table_size / ps_tmp[num].elem_size, \ + ps_tmp[num].ps_bits, 1, 1, \ + ps_tmp[num].ps_codes, ps_tmp[num].elem_size, ps_tmp[num].elem_size, \ + size); + +#define PS_VLC_ROW(name) \ + { name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) } + +static av_cold void ps_init_common(void) +{ + // Syntax initialization + static const struct { + const void *ps_codes, *ps_bits; + const unsigned int table_size, elem_size; + } ps_tmp[] = { + PS_VLC_ROW(huff_iid_df1), + PS_VLC_ROW(huff_iid_dt1), + PS_VLC_ROW(huff_iid_df0), + PS_VLC_ROW(huff_iid_dt0), + PS_VLC_ROW(huff_icc_df), + PS_VLC_ROW(huff_icc_dt), + PS_VLC_ROW(huff_ipd_df), + PS_VLC_ROW(huff_ipd_dt), + PS_VLC_ROW(huff_opd_df), + PS_VLC_ROW(huff_opd_dt), + }; + + PS_INIT_VLC_STATIC(0, 9, 1544); + PS_INIT_VLC_STATIC(1, 9, 832); + PS_INIT_VLC_STATIC(2, 9, 1024); + PS_INIT_VLC_STATIC(3, 9, 1036); + PS_INIT_VLC_STATIC(4, 9, 544); + PS_INIT_VLC_STATIC(5, 9, 544); + PS_INIT_VLC_STATIC(6, 5, 32); + PS_INIT_VLC_STATIC(7, 5, 32); + PS_INIT_VLC_STATIC(8, 5, 32); + PS_INIT_VLC_STATIC(9, 5, 32); +} + +av_cold void ff_ps_init_common(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, ps_init_common); +} diff --git a/libavcodec/aacps_fixed_tablegen.h b/libavcodec/aacps_fixed_tablegen.h index 8b82deb59..8fb1da507 100644 --- a/libavcodec/aacps_fixed_tablegen.h +++ b/libavcodec/aacps_fixed_tablegen.h @@ -36,7 +36,12 @@ #else #include "libavutil/common.h" #include "libavutil/mathematics.h" -#include "libavutil/mem.h" +#ifdef BUILD_TABLES +#undef DECLARE_ALIGNED +#define DECLARE_ALIGNED(align, type, variable) type variable +#else +#include "libavutil/mem_internal.h" +#endif #include "aac_defines.h" #include "libavutil/softfloat.h" diff --git a/libavcodec/aacps_tablegen_template.c b/libavcodec/aacps_tablegen_template.c index 341bd4440..e70edf884 100644 --- a/libavcodec/aacps_tablegen_template.c +++ b/libavcodec/aacps_tablegen_template.c @@ -21,6 +21,7 @@ */ #include +#define BUILD_TABLES #define CONFIG_HARDCODED_TABLES 0 #include "aac_defines.h" diff --git a/libavcodec/aacpsdata.c b/libavcodec/aacpsdata.c index 5c1a1b0f8..7a1f49006 100644 --- a/libavcodec/aacpsdata.c +++ b/libavcodec/aacpsdata.c @@ -142,22 +142,17 @@ static const int8_t huff_offset[] = { }; ///Table 8.48 -static const int8_t k_to_i_20[] = { +const int8_t ff_k_to_i_20[] = { 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19 }; ///Table 8.49 -static const int8_t k_to_i_34[] = { +const int8_t ff_k_to_i_34[] = { 0, 1, 2, 3, 4, 5, 6, 6, 7, 2, 1, 0, 10, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 14, 11, 12, 13, 14, 15, 16, 13, 16, 17, 18, 19, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }; - -static const INTFLOAT g1_Q2[] = { - Q31(0.0f), Q31(0.01899487526049f), Q31(0.0f), Q31(-0.07293139167538f), - Q31(0.0f), Q31(0.30596630545168f), Q31(0.5f) -}; diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index 1d2a8d472..b74cd82ac 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -31,7 +31,6 @@ #include "sbr.h" #include "aacsbr.h" #include "aacsbrdata.h" -#include "aacsbr_tablegen.h" #include "fft.h" #include "internal.h" #include "aacps.h" @@ -39,6 +38,7 @@ #include "libavutil/internal.h" #include "libavutil/libm.h" #include "libavutil/avassert.h" +#include "libavutil/mem_internal.h" #include #include diff --git a/libavcodec/aacsbr_fixed.c b/libavcodec/aacsbr_fixed.c index 59cbba10f..ffa63f264 100644 --- a/libavcodec/aacsbr_fixed.c +++ b/libavcodec/aacsbr_fixed.c @@ -60,7 +60,6 @@ #include "sbr.h" #include "aacsbr.h" #include "aacsbrdata.h" -#include "aacsbr_fixed_tablegen.h" #include "fft.h" #include "aacps.h" #include "sbrdsp.h" diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c index 821615f2a..774f12e77 100644 --- a/libavcodec/aacsbr_template.c +++ b/libavcodec/aacsbr_template.c @@ -37,10 +37,6 @@ static av_cold void aacsbr_tableinit(void) { int n; - for (n = 1; n < 320; n++) - sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n]; - sbr_qmf_window_us[384] = -sbr_qmf_window_us[384]; - sbr_qmf_window_us[512] = -sbr_qmf_window_us[512]; for (n = 0; n < 320; n++) sbr_qmf_window_ds[n] = sbr_qmf_window_us[2*n]; @@ -957,7 +953,7 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, skip_bits_long(gb, *num_bits_left); // bs_fill_bits *num_bits_left = 0; } else { - *num_bits_left -= AAC_RENAME(ff_ps_read_data)(ac->avctx, gb, &sbr->ps, *num_bits_left); + *num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps.common, *num_bits_left); ac->avctx->profile = FF_PROFILE_AAC_HE_V2; } break; @@ -1548,7 +1544,7 @@ void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int } if (ac->oc[1].m4ac.ps == 1) { - if (sbr->ps.start) { + if (sbr->ps.common.start) { AAC_RENAME(ff_ps_apply)(ac->avctx, &sbr->ps, sbr->X[0], sbr->X[1], sbr->kx[1] + sbr->m[1]); } else { memcpy(sbr->X[1], sbr->X[0], sizeof(sbr->X[0])); diff --git a/libavcodec/aacsbrdata.h b/libavcodec/aacsbrdata.h index 4ff8fae91..7a11594c9 100644 --- a/libavcodec/aacsbrdata.h +++ b/libavcodec/aacsbrdata.h @@ -29,7 +29,7 @@ #define AVCODEC_AACSBRDATA_H #include -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "aac_defines.h" ///< Huffman tables for SBR @@ -532,4 +532,171 @@ const DECLARE_ALIGNED(16, INTFLOAT, AAC_RENAME(ff_sbr_noise_table))[][2] = { {Q31(-0.01053049862020f), Q31(-0.66959058036166f)}, {Q31(-0.91266367957293f), Q31(-0.11522938140034f)}, }; +///< window coefficients for analysis/synthesis QMF banks +static DECLARE_ALIGNED(32, INTFLOAT, sbr_qmf_window_ds)[320]; +/* This table contains redundancy: It is symmetric about the entry #320 + * with the exception of entries 384 and 512 which are negated. */ +static const DECLARE_ALIGNED(32, INTFLOAT, sbr_qmf_window_us)[640] = { + Q31( 0.0000000000f), Q31(-0.0005525286f), Q31(-0.0005617692f), Q31(-0.0004947518f), + Q31(-0.0004875227f), Q31(-0.0004893791f), Q31(-0.0005040714f), Q31(-0.0005226564f), + Q31(-0.0005466565f), Q31(-0.0005677802f), Q31(-0.0005870930f), Q31(-0.0006132747f), + Q31(-0.0006312493f), Q31(-0.0006540333f), Q31(-0.0006777690f), Q31(-0.0006941614f), + Q31(-0.0007157736f), Q31(-0.0007255043f), Q31(-0.0007440941f), Q31(-0.0007490598f), + Q31(-0.0007681371f), Q31(-0.0007724848f), Q31(-0.0007834332f), Q31(-0.0007779869f), + Q31(-0.0007803664f), Q31(-0.0007801449f), Q31(-0.0007757977f), Q31(-0.0007630793f), + Q31(-0.0007530001f), Q31(-0.0007319357f), Q31(-0.0007215391f), Q31(-0.0006917937f), + Q31(-0.0006650415f), Q31(-0.0006341594f), Q31(-0.0005946118f), Q31(-0.0005564576f), + Q31(-0.0005145572f), Q31(-0.0004606325f), Q31(-0.0004095121f), Q31(-0.0003501175f), + Q31(-0.0002896981f), Q31(-0.0002098337f), Q31(-0.0001446380f), Q31(-0.0000617334f), + Q31( 0.0000134949f), Q31( 0.0001094383f), Q31( 0.0002043017f), Q31( 0.0002949531f), + Q31( 0.0004026540f), Q31( 0.0005107388f), Q31( 0.0006239376f), Q31( 0.0007458025f), + Q31( 0.0008608443f), Q31( 0.0009885988f), Q31( 0.0011250155f), Q31( 0.0012577884f), + Q31( 0.0013902494f), Q31( 0.0015443219f), Q31( 0.0016868083f), Q31( 0.0018348265f), + Q31( 0.0019841140f), Q31( 0.0021461583f), Q31( 0.0023017254f), Q31( 0.0024625616f), + Q31( 0.0026201758f), Q31( 0.0027870464f), Q31( 0.0029469447f), Q31( 0.0031125420f), + Q31( 0.0032739613f), Q31( 0.0034418874f), Q31( 0.0036008268f), Q31( 0.0037603922f), + Q31( 0.0039207432f), Q31( 0.0040819753f), Q31( 0.0042264269f), Q31( 0.0043730719f), + Q31( 0.0045209852f), Q31( 0.0046606460f), Q31( 0.0047932560f), Q31( 0.0049137603f), + Q31( 0.0050393022f), Q31( 0.0051407353f), Q31( 0.0052461166f), Q31( 0.0053471681f), + Q31( 0.0054196775f), Q31( 0.0054876040f), Q31( 0.0055475714f), Q31( 0.0055938023f), + Q31( 0.0056220643f), Q31( 0.0056455196f), Q31( 0.0056389199f), Q31( 0.0056266114f), + Q31( 0.0055917128f), Q31( 0.0055404363f), Q31( 0.0054753783f), Q31( 0.0053838975f), + Q31( 0.0052715758f), Q31( 0.0051382275f), Q31( 0.0049839687f), Q31( 0.0048109469f), + Q31( 0.0046039530f), Q31( 0.0043801861f), Q31( 0.0041251642f), Q31( 0.0038456408f), + Q31( 0.0035401246f), Q31( 0.0032091885f), Q31( 0.0028446757f), Q31( 0.0024508540f), + Q31( 0.0020274176f), Q31( 0.0015784682f), Q31( 0.0010902329f), Q31( 0.0005832264f), + Q31( 0.0000276045f), Q31(-0.0005464280f), Q31(-0.0011568135f), Q31(-0.0018039472f), + Q31(-0.0024826723f), Q31(-0.0031933778f), Q31(-0.0039401124f), Q31(-0.0047222596f), + Q31(-0.0055337211f), Q31(-0.0063792293f), Q31(-0.0072615816f), Q31(-0.0081798233f), + Q31(-0.0091325329f), Q31(-0.0101150215f), Q31(-0.0111315548f), Q31(-0.0121849995f), + Q31( 0.0132718220f), Q31( 0.0143904666f), Q31( 0.0155405553f), Q31( 0.0167324712f), + Q31( 0.0179433381f), Q31( 0.0191872431f), Q31( 0.0204531793f), Q31( 0.0217467550f), + Q31( 0.0230680169f), Q31( 0.0244160992f), Q31( 0.0257875847f), Q31( 0.0271859429f), + Q31( 0.0286072173f), Q31( 0.0300502657f), Q31( 0.0315017608f), Q31( 0.0329754081f), + Q31( 0.0344620948f), Q31( 0.0359697560f), Q31( 0.0374812850f), Q31( 0.0390053679f), + Q31( 0.0405349170f), Q31( 0.0420649094f), Q31( 0.0436097542f), Q31( 0.0451488405f), + Q31( 0.0466843027f), Q31( 0.0482165720f), Q31( 0.0497385755f), Q31( 0.0512556155f), + Q31( 0.0527630746f), Q31( 0.0542452768f), Q31( 0.0557173648f), Q31( 0.0571616450f), + Q31( 0.0585915683f), Q31( 0.0599837480f), Q31( 0.0613455171f), Q31( 0.0626857808f), + Q31( 0.0639715898f), Q31( 0.0652247106f), Q31( 0.0664367512f), Q31( 0.0676075985f), + Q31( 0.0687043828f), Q31( 0.0697630244f), Q31( 0.0707628710f), Q31( 0.0717002673f), + Q31( 0.0725682583f), Q31( 0.0733620255f), Q31( 0.0741003642f), Q31( 0.0747452558f), + Q31( 0.0753137336f), Q31( 0.0758008358f), Q31( 0.0761992479f), Q31( 0.0764992170f), + Q31( 0.0767093490f), Q31( 0.0768173975f), Q31( 0.0768230011f), Q31( 0.0767204924f), + Q31( 0.0765050718f), Q31( 0.0761748321f), Q31( 0.0757305756f), Q31( 0.0751576255f), + Q31( 0.0744664394f), Q31( 0.0736406005f), Q31( 0.0726774642f), Q31( 0.0715826364f), + Q31( 0.0703533073f), Q31( 0.0689664013f), Q31( 0.0674525021f), Q31( 0.0657690668f), + Q31( 0.0639444805f), Q31( 0.0619602779f), Q31( 0.0598166570f), Q31( 0.0575152691f), + Q31( 0.0550460034f), Q31( 0.0524093821f), Q31( 0.0495978676f), Q31( 0.0466303305f), + Q31( 0.0434768782f), Q31( 0.0401458278f), Q31( 0.0366418116f), Q31( 0.0329583930f), + Q31( 0.0290824006f), Q31( 0.0250307561f), Q31( 0.0207997072f), Q31( 0.0163701258f), + Q31( 0.0117623832f), Q31( 0.0069636862f), Q31( 0.0019765601f), Q31(-0.0032086896f), + Q31(-0.0085711749f), Q31(-0.0141288827f), Q31(-0.0198834129f), Q31(-0.0258227288f), + Q31(-0.0319531274f), Q31(-0.0382776572f), Q31(-0.0447806821f), Q31(-0.0514804176f), + Q31(-0.0583705326f), Q31(-0.0654409853f), Q31(-0.0726943300f), Q31(-0.0801372934f), + Q31(-0.0877547536f), Q31(-0.0955533352f), Q31(-0.1035329531f), Q31(-0.1116826931f), + Q31(-0.1200077984f), Q31(-0.1285002850f), Q31(-0.1371551761f), Q31(-0.1459766491f), + Q31(-0.1549607071f), Q31(-0.1640958855f), Q31(-0.1733808172f), Q31(-0.1828172548f), + Q31(-0.1923966745f), Q31(-0.2021250176f), Q31(-0.2119735853f), Q31(-0.2219652696f), + Q31(-0.2320690870f), Q31(-0.2423016884f), Q31(-0.2526480309f), Q31(-0.2631053299f), + Q31(-0.2736634040f), Q31(-0.2843214189f), Q31(-0.2950716717f), Q31(-0.3059098575f), + Q31(-0.3168278913f), Q31(-0.3278113727f), Q31(-0.3388722693f), Q31(-0.3499914122f), + Q31( 0.3611589903f), Q31( 0.3723795546f), Q31( 0.3836350013f), Q31( 0.3949211761f), + Q31( 0.4062317676f), Q31( 0.4175696896f), Q31( 0.4289119920f), Q31( 0.4402553754f), + Q31( 0.4515996535f), Q31( 0.4629308085f), Q31( 0.4742453214f), Q31( 0.4855253091f), + Q31( 0.4967708254f), Q31( 0.5079817500f), Q31( 0.5191234970f), Q31( 0.5302240895f), + Q31( 0.5412553448f), Q31( 0.5522051258f), Q31( 0.5630789140f), Q31( 0.5738524131f), + Q31( 0.5845403235f), Q31( 0.5951123086f), Q31( 0.6055783538f), Q31( 0.6159109932f), + Q31( 0.6261242695f), Q31( 0.6361980107f), Q31( 0.6461269695f), Q31( 0.6559016302f), + Q31( 0.6655139880f), Q31( 0.6749663190f), Q31( 0.6842353293f), Q31( 0.6933282376f), + Q31( 0.7022388719f), Q31( 0.7109410426f), Q31( 0.7194462634f), Q31( 0.7277448900f), + Q31( 0.7358211758f), Q31( 0.7436827863f), Q31( 0.7513137456f), Q31( 0.7587080760f), + Q31( 0.7658674865f), Q31( 0.7727780881f), Q31( 0.7794287519f), Q31( 0.7858353120f), + Q31( 0.7919735841f), Q31( 0.7978466413f), Q31( 0.8034485751f), Q31( 0.8087695004f), + Q31( 0.8138191270f), Q31( 0.8185776004f), Q31( 0.8230419890f), Q31( 0.8272275347f), + Q31( 0.8311038457f), Q31( 0.8346937361f), Q31( 0.8379717337f), Q31( 0.8409541392f), + Q31( 0.8436238281f), Q31( 0.8459818469f), Q31( 0.8480315777f), Q31( 0.8497805198f), + Q31( 0.8511971524f), Q31( 0.8523047035f), Q31( 0.8531020949f), Q31( 0.8535720573f), + Q31( 0.8537385600f), Q31( 0.8535720573f), Q31( 0.8531020949f), Q31( 0.8523047035f), + Q31( 0.8511971524f), Q31( 0.8497805198f), Q31( 0.8480315777f), Q31( 0.8459818469f), + Q31( 0.8436238281f), Q31( 0.8409541392f), Q31( 0.8379717337f), Q31( 0.8346937361f), + Q31( 0.8311038457f), Q31( 0.8272275347f), Q31( 0.8230419890f), Q31( 0.8185776004f), + Q31( 0.8138191270f), Q31( 0.8087695004f), Q31( 0.8034485751f), Q31( 0.7978466413f), + Q31( 0.7919735841f), Q31( 0.7858353120f), Q31( 0.7794287519f), Q31( 0.7727780881f), + Q31( 0.7658674865f), Q31( 0.7587080760f), Q31( 0.7513137456f), Q31( 0.7436827863f), + Q31( 0.7358211758f), Q31( 0.7277448900f), Q31( 0.7194462634f), Q31( 0.7109410426f), + Q31( 0.7022388719f), Q31( 0.6933282376f), Q31( 0.6842353293f), Q31( 0.6749663190f), + Q31( 0.6655139880f), Q31( 0.6559016302f), Q31( 0.6461269695f), Q31( 0.6361980107f), + Q31( 0.6261242695f), Q31( 0.6159109932f), Q31( 0.6055783538f), Q31( 0.5951123086f), + Q31( 0.5845403235f), Q31( 0.5738524131f), Q31( 0.5630789140f), Q31( 0.5522051258f), + Q31( 0.5412553448f), Q31( 0.5302240895f), Q31( 0.5191234970f), Q31( 0.5079817500f), + Q31( 0.4967708254f), Q31( 0.4855253091f), Q31( 0.4742453214f), Q31( 0.4629308085f), + Q31( 0.4515996535f), Q31( 0.4402553754f), Q31( 0.4289119920f), Q31( 0.4175696896f), + Q31( 0.4062317676f), Q31( 0.3949211761f), Q31( 0.3836350013f), Q31( 0.3723795546f), + -Q31( 0.3611589903f), Q31(-0.3499914122f), Q31(-0.3388722693f), Q31(-0.3278113727f), + Q31(-0.3168278913f), Q31(-0.3059098575f), Q31(-0.2950716717f), Q31(-0.2843214189f), + Q31(-0.2736634040f), Q31(-0.2631053299f), Q31(-0.2526480309f), Q31(-0.2423016884f), + Q31(-0.2320690870f), Q31(-0.2219652696f), Q31(-0.2119735853f), Q31(-0.2021250176f), + Q31(-0.1923966745f), Q31(-0.1828172548f), Q31(-0.1733808172f), Q31(-0.1640958855f), + Q31(-0.1549607071f), Q31(-0.1459766491f), Q31(-0.1371551761f), Q31(-0.1285002850f), + Q31(-0.1200077984f), Q31(-0.1116826931f), Q31(-0.1035329531f), Q31(-0.0955533352f), + Q31(-0.0877547536f), Q31(-0.0801372934f), Q31(-0.0726943300f), Q31(-0.0654409853f), + Q31(-0.0583705326f), Q31(-0.0514804176f), Q31(-0.0447806821f), Q31(-0.0382776572f), + Q31(-0.0319531274f), Q31(-0.0258227288f), Q31(-0.0198834129f), Q31(-0.0141288827f), + Q31(-0.0085711749f), Q31(-0.0032086896f), Q31( 0.0019765601f), Q31( 0.0069636862f), + Q31( 0.0117623832f), Q31( 0.0163701258f), Q31( 0.0207997072f), Q31( 0.0250307561f), + Q31( 0.0290824006f), Q31( 0.0329583930f), Q31( 0.0366418116f), Q31( 0.0401458278f), + Q31( 0.0434768782f), Q31( 0.0466303305f), Q31( 0.0495978676f), Q31( 0.0524093821f), + Q31( 0.0550460034f), Q31( 0.0575152691f), Q31( 0.0598166570f), Q31( 0.0619602779f), + Q31( 0.0639444805f), Q31( 0.0657690668f), Q31( 0.0674525021f), Q31( 0.0689664013f), + Q31( 0.0703533073f), Q31( 0.0715826364f), Q31( 0.0726774642f), Q31( 0.0736406005f), + Q31( 0.0744664394f), Q31( 0.0751576255f), Q31( 0.0757305756f), Q31( 0.0761748321f), + Q31( 0.0765050718f), Q31( 0.0767204924f), Q31( 0.0768230011f), Q31( 0.0768173975f), + Q31( 0.0767093490f), Q31( 0.0764992170f), Q31( 0.0761992479f), Q31( 0.0758008358f), + Q31( 0.0753137336f), Q31( 0.0747452558f), Q31( 0.0741003642f), Q31( 0.0733620255f), + Q31( 0.0725682583f), Q31( 0.0717002673f), Q31( 0.0707628710f), Q31( 0.0697630244f), + Q31( 0.0687043828f), Q31( 0.0676075985f), Q31( 0.0664367512f), Q31( 0.0652247106f), + Q31( 0.0639715898f), Q31( 0.0626857808f), Q31( 0.0613455171f), Q31( 0.0599837480f), + Q31( 0.0585915683f), Q31( 0.0571616450f), Q31( 0.0557173648f), Q31( 0.0542452768f), + Q31( 0.0527630746f), Q31( 0.0512556155f), Q31( 0.0497385755f), Q31( 0.0482165720f), + Q31( 0.0466843027f), Q31( 0.0451488405f), Q31( 0.0436097542f), Q31( 0.0420649094f), + Q31( 0.0405349170f), Q31( 0.0390053679f), Q31( 0.0374812850f), Q31( 0.0359697560f), + Q31( 0.0344620948f), Q31( 0.0329754081f), Q31( 0.0315017608f), Q31( 0.0300502657f), + Q31( 0.0286072173f), Q31( 0.0271859429f), Q31( 0.0257875847f), Q31( 0.0244160992f), + Q31( 0.0230680169f), Q31( 0.0217467550f), Q31( 0.0204531793f), Q31( 0.0191872431f), + Q31( 0.0179433381f), Q31( 0.0167324712f), Q31( 0.0155405553f), Q31( 0.0143904666f), + -Q31( 0.0132718220f), Q31(-0.0121849995f), Q31(-0.0111315548f), Q31(-0.0101150215f), + Q31(-0.0091325329f), Q31(-0.0081798233f), Q31(-0.0072615816f), Q31(-0.0063792293f), + Q31(-0.0055337211f), Q31(-0.0047222596f), Q31(-0.0039401124f), Q31(-0.0031933778f), + Q31(-0.0024826723f), Q31(-0.0018039472f), Q31(-0.0011568135f), Q31(-0.0005464280f), + Q31( 0.0000276045f), Q31( 0.0005832264f), Q31( 0.0010902329f), Q31( 0.0015784682f), + Q31( 0.0020274176f), Q31( 0.0024508540f), Q31( 0.0028446757f), Q31( 0.0032091885f), + Q31( 0.0035401246f), Q31( 0.0038456408f), Q31( 0.0041251642f), Q31( 0.0043801861f), + Q31( 0.0046039530f), Q31( 0.0048109469f), Q31( 0.0049839687f), Q31( 0.0051382275f), + Q31( 0.0052715758f), Q31( 0.0053838975f), Q31( 0.0054753783f), Q31( 0.0055404363f), + Q31( 0.0055917128f), Q31( 0.0056266114f), Q31( 0.0056389199f), Q31( 0.0056455196f), + Q31( 0.0056220643f), Q31( 0.0055938023f), Q31( 0.0055475714f), Q31( 0.0054876040f), + Q31( 0.0054196775f), Q31( 0.0053471681f), Q31( 0.0052461166f), Q31( 0.0051407353f), + Q31( 0.0050393022f), Q31( 0.0049137603f), Q31( 0.0047932560f), Q31( 0.0046606460f), + Q31( 0.0045209852f), Q31( 0.0043730719f), Q31( 0.0042264269f), Q31( 0.0040819753f), + Q31( 0.0039207432f), Q31( 0.0037603922f), Q31( 0.0036008268f), Q31( 0.0034418874f), + Q31( 0.0032739613f), Q31( 0.0031125420f), Q31( 0.0029469447f), Q31( 0.0027870464f), + Q31( 0.0026201758f), Q31( 0.0024625616f), Q31( 0.0023017254f), Q31( 0.0021461583f), + Q31( 0.0019841140f), Q31( 0.0018348265f), Q31( 0.0016868083f), Q31( 0.0015443219f), + Q31( 0.0013902494f), Q31( 0.0012577884f), Q31( 0.0011250155f), Q31( 0.0009885988f), + Q31( 0.0008608443f), Q31( 0.0007458025f), Q31( 0.0006239376f), Q31( 0.0005107388f), + Q31( 0.0004026540f), Q31( 0.0002949531f), Q31( 0.0002043017f), Q31( 0.0001094383f), + Q31( 0.0000134949f), Q31(-0.0000617334f), Q31(-0.0001446380f), Q31(-0.0002098337f), + Q31(-0.0002896981f), Q31(-0.0003501175f), Q31(-0.0004095121f), Q31(-0.0004606325f), + Q31(-0.0005145572f), Q31(-0.0005564576f), Q31(-0.0005946118f), Q31(-0.0006341594f), + Q31(-0.0006650415f), Q31(-0.0006917937f), Q31(-0.0007215391f), Q31(-0.0007319357f), + Q31(-0.0007530001f), Q31(-0.0007630793f), Q31(-0.0007757977f), Q31(-0.0007801449f), + Q31(-0.0007803664f), Q31(-0.0007779869f), Q31(-0.0007834332f), Q31(-0.0007724848f), + Q31(-0.0007681371f), Q31(-0.0007490598f), Q31(-0.0007440941f), Q31(-0.0007255043f), + Q31(-0.0007157736f), Q31(-0.0006941614f), Q31(-0.0006777690f), Q31(-0.0006540333f), + Q31(-0.0006312493f), Q31(-0.0006132747f), Q31(-0.0005870930f), Q31(-0.0005677802f), + Q31(-0.0005466565f), Q31(-0.0005226564f), Q31(-0.0005040714f), Q31(-0.0004893791f), + Q31(-0.0004875227f), Q31(-0.0004947518f), Q31(-0.0005617692f), Q31(-0.0005525286f), +}; + #endif /* AVCODEC_AACSBRDATA_H */ diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c index df551b058..fa5420fec 100644 --- a/libavcodec/aactab.c +++ b/libavcodec/aactab.c @@ -27,20 +27,39 @@ * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) */ +#include "config.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" #include "aac.h" +#include "aactab.h" #include float ff_aac_pow2sf_tab[428]; float ff_aac_pow34sf_tab[428]; +#if CONFIG_AAC_ENCODER || CONFIG_AAC_DECODER +#include "kbdwin.h" +#include "sinewin.h" + DECLARE_ALIGNED(32, float, ff_aac_kbd_long_1024)[1024]; DECLARE_ALIGNED(32, float, ff_aac_kbd_short_128)[128]; -DECLARE_ALIGNED(32, float, ff_aac_kbd_long_960)[960]; -DECLARE_ALIGNED(32, float, ff_aac_kbd_short_120)[120]; -DECLARE_ALIGNED(32, int, ff_aac_kbd_long_1024_fixed)[1024]; -DECLARE_ALIGNED(32, int, ff_aac_kbd_short_128_fixed)[128]; + +static av_cold void aac_float_common_init(void) +{ + ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); + ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); + ff_init_ff_sine_windows(10); + ff_init_ff_sine_windows(7); +} + +av_cold void ff_aac_float_common_init(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, aac_float_common_init); +} +#endif const uint8_t ff_aac_num_swb_1024[] = { 41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40, 40 @@ -3280,3 +3299,53 @@ const DECLARE_ALIGNED(32, int, ff_aac_eld_window_480_fixed)[1800] = { 0xffecff1c, 0xffed391e, 0xffed740c, 0xffedafb1, 0xffedebe1, 0xffee287d, 0xffee654e, 0xffeea23f, }; + +static void aac_tableinit(void) +{ + /* 2^(i/16) for 0 <= i <= 15 */ + static const float exp2_lut[] = { + 1.00000000000000000000, + 1.04427378242741384032, + 1.09050773266525765921, + 1.13878863475669165370, + 1.18920711500272106672, + 1.24185781207348404859, + 1.29683955465100966593, + 1.35425554693689272830, + 1.41421356237309504880, + 1.47682614593949931139, + 1.54221082540794082361, + 1.61049033194925430818, + 1.68179283050742908606, + 1.75625216037329948311, + 1.83400808640934246349, + 1.91520656139714729387, + }; + float t1 = 8.8817841970012523233890533447265625e-16; // 2^(-50) + float t2 = 3.63797880709171295166015625e-12; // 2^(-38) + int t1_inc_cur, t2_inc_cur; + int t1_inc_prev = 0; + int t2_inc_prev = 8; + + for (int i = 0; i < 428; i++) { + t1_inc_cur = 4 * (i % 4); + t2_inc_cur = (8 + 3*i) % 16; + if (t1_inc_cur < t1_inc_prev) + t1 *= 2; + if (t2_inc_cur < t2_inc_prev) + t2 *= 2; + // A much more efficient and accurate way of doing: + // ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0); + // ff_aac_pow34sf_tab[i] = pow(ff_aac_pow2sf_tab[i], 3.0/4.0); + ff_aac_pow2sf_tab[i] = t1 * exp2_lut[t1_inc_cur]; + ff_aac_pow34sf_tab[i] = t2 * exp2_lut[t2_inc_cur]; + t1_inc_prev = t1_inc_cur; + t2_inc_prev = t2_inc_cur; + } +} + +void ff_aac_tableinit(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, aac_tableinit); +} diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h index 7cd812823..9b1450c2e 100644 --- a/libavcodec/aactab.h +++ b/libavcodec/aactab.h @@ -30,7 +30,7 @@ #ifndef AVCODEC_AACTAB_H #define AVCODEC_AACTAB_H -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "aac.h" #include @@ -42,51 +42,7 @@ extern float ff_aac_pow2sf_tab[428]; extern float ff_aac_pow34sf_tab[428]; -static inline void ff_aac_tableinit(void) -{ - int i; - - /* 2^(i/16) for 0 <= i <= 15 */ - static const float exp2_lut[] = { - 1.00000000000000000000, - 1.04427378242741384032, - 1.09050773266525765921, - 1.13878863475669165370, - 1.18920711500272106672, - 1.24185781207348404859, - 1.29683955465100966593, - 1.35425554693689272830, - 1.41421356237309504880, - 1.47682614593949931139, - 1.54221082540794082361, - 1.61049033194925430818, - 1.68179283050742908606, - 1.75625216037329948311, - 1.83400808640934246349, - 1.91520656139714729387, - }; - float t1 = 8.8817841970012523233890533447265625e-16; // 2^(-50) - float t2 = 3.63797880709171295166015625e-12; // 2^(-38) - int t1_inc_cur, t2_inc_cur; - int t1_inc_prev = 0; - int t2_inc_prev = 8; - - for (i = 0; i < 428; i++) { - t1_inc_cur = 4 * (i % 4); - t2_inc_cur = (8 + 3*i) % 16; - if (t1_inc_cur < t1_inc_prev) - t1 *= 2; - if (t2_inc_cur < t2_inc_prev) - t2 *= 2; - // A much more efficient and accurate way of doing: - // ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0); - // ff_aac_pow34sf_tab[i] = pow(ff_aac_pow2sf_tab[i], 3.0/4.0); - ff_aac_pow2sf_tab[i] = t1 * exp2_lut[t1_inc_cur]; - ff_aac_pow34sf_tab[i] = t2 * exp2_lut[t2_inc_cur]; - t1_inc_prev = t1_inc_cur; - t2_inc_prev = t2_inc_cur; - } -} +void ff_aac_tableinit(void); /* @name ltp_coef * Table of the LTP coefficients @@ -136,17 +92,15 @@ static const INTFLOAT * const tns_tmp2_map[4] = { */ DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024]; DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128]; -DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_960)[960]; -DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_120)[120]; -DECLARE_ALIGNED(32, extern int, ff_aac_kbd_long_1024_fixed)[1024]; -DECLARE_ALIGNED(32, extern int, ff_aac_kbd_long_512_fixed)[512]; -DECLARE_ALIGNED(32, extern int, ff_aac_kbd_short_128_fixed)[128]; DECLARE_ALIGNED(32, extern const float, ff_aac_eld_window_512)[1920]; DECLARE_ALIGNED(32, extern const int, ff_aac_eld_window_512_fixed)[1920]; DECLARE_ALIGNED(32, extern const float, ff_aac_eld_window_480)[1800]; DECLARE_ALIGNED(32, extern const int, ff_aac_eld_window_480_fixed)[1800]; // @} +/* Initializes data shared between float decoder and encoder. */ +void ff_aac_float_common_init(void); + /* @name number of scalefactor window bands for long and short transform windows respectively * @{ */ @@ -167,9 +121,9 @@ extern const uint16_t * const ff_aac_spectral_codes[11]; extern const uint8_t * const ff_aac_spectral_bits [11]; extern const uint16_t ff_aac_spectral_sizes[11]; -extern const float *ff_aac_codebook_vectors[]; -extern const float *ff_aac_codebook_vector_vals[]; -extern const uint16_t *ff_aac_codebook_vector_idx[]; +extern const float *const ff_aac_codebook_vectors[]; +extern const float *const ff_aac_codebook_vector_vals[]; +extern const uint16_t *const ff_aac_codebook_vector_idx[]; extern const uint16_t * const ff_swb_offset_1024[13]; extern const uint16_t * const ff_swb_offset_960 [13]; diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile index f6434e40d..954461f81 100644 --- a/libavcodec/aarch64/Makefile +++ b/libavcodec/aarch64/Makefile @@ -61,3 +61,6 @@ NEON-OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9itxfm_16bpp_neon.o \ aarch64/vp9lpf_neon.o \ aarch64/vp9mc_16bpp_neon.o \ aarch64/vp9mc_neon.o +NEON-OBJS-$(CONFIG_HEVC_DECODER) += aarch64/hevcdsp_idct_neon.o \ + aarch64/hevcdsp_init_aarch64.o \ + aarch64/hevcdsp_sao_neon.o diff --git a/libavcodec/aarch64/hevcdsp_idct_neon.S b/libavcodec/aarch64/hevcdsp_idct_neon.S new file mode 100644 index 000000000..28c11e632 --- /dev/null +++ b/libavcodec/aarch64/hevcdsp_idct_neon.S @@ -0,0 +1,621 @@ +/* + * ARM NEON optimised IDCT functions for HEVC decoding + * Copyright (c) 2014 Seppo Tomperi + * Copyright (c) 2017 Alexandra Hájková + * + * Ported from arm/hevcdsp_idct_neon.S by + * Copyright (c) 2020 Reimar Döffinger + * Copyright (c) 2020 Josh Dekker + * + * 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/aarch64/asm.S" + +const trans, align=4 + .short 64, 83, 64, 36 + .short 89, 75, 50, 18 + .short 90, 87, 80, 70 + .short 57, 43, 25, 9 + .short 90, 90, 88, 85 + .short 82, 78, 73, 67 + .short 61, 54, 46, 38 + .short 31, 22, 13, 4 +endconst + +.macro clip10 in1, in2, c1, c2 + smax \in1, \in1, \c1 + smax \in2, \in2, \c1 + smin \in1, \in1, \c2 + smin \in2, \in2, \c2 +.endm + +function ff_hevc_add_residual_4x4_8_neon, export=1 + ld1 {v0.8h-v1.8h}, [x1] + ld1 {v2.s}[0], [x0], x2 + ld1 {v2.s}[1], [x0], x2 + ld1 {v2.s}[2], [x0], x2 + ld1 {v2.s}[3], [x0], x2 + sub x0, x0, x2, lsl #2 + uxtl v6.8h, v2.8b + uxtl2 v7.8h, v2.16b + sqadd v0.8h, v0.8h, v6.8h + sqadd v1.8h, v1.8h, v7.8h + sqxtun v0.8b, v0.8h + sqxtun2 v0.16b, v1.8h + st1 {v0.s}[0], [x0], x2 + st1 {v0.s}[1], [x0], x2 + st1 {v0.s}[2], [x0], x2 + st1 {v0.s}[3], [x0], x2 + ret +endfunc + +function ff_hevc_add_residual_4x4_10_neon, export=1 + mov x12, x0 + ld1 {v0.8h-v1.8h}, [x1] + ld1 {v2.d}[0], [x12], x2 + ld1 {v2.d}[1], [x12], x2 + ld1 {v3.d}[0], [x12], x2 + sqadd v0.8h, v0.8h, v2.8h + ld1 {v3.d}[1], [x12], x2 + movi v4.8h, #0 + sqadd v1.8h, v1.8h, v3.8h + mvni v5.8h, #0xFC, lsl #8 // movi #0x3FF + clip10 v0.8h, v1.8h, v4.8h, v5.8h + st1 {v0.d}[0], [x0], x2 + st1 {v0.d}[1], [x0], x2 + st1 {v1.d}[0], [x0], x2 + st1 {v1.d}[1], [x0], x2 + ret +endfunc + +function ff_hevc_add_residual_8x8_8_neon, export=1 + add x12, x0, x2 + add x2, x2, x2 + mov x3, #8 +1: subs x3, x3, #2 + ld1 {v2.d}[0], [x0] + ld1 {v2.d}[1], [x12] + uxtl v3.8h, v2.8b + ld1 {v0.8h-v1.8h}, [x1], #32 + uxtl2 v2.8h, v2.16b + sqadd v0.8h, v0.8h, v3.8h + sqadd v1.8h, v1.8h, v2.8h + sqxtun v0.8b, v0.8h + sqxtun2 v0.16b, v1.8h + st1 {v0.d}[0], [x0], x2 + st1 {v0.d}[1], [x12], x2 + bne 1b + ret +endfunc + +function ff_hevc_add_residual_8x8_10_neon, export=1 + add x12, x0, x2 + add x2, x2, x2 + mov x3, #8 + movi v4.8h, #0 + mvni v5.8h, #0xFC, lsl #8 // movi #0x3FF +1: subs x3, x3, #2 + ld1 {v0.8h-v1.8h}, [x1], #32 + ld1 {v2.8h}, [x0] + sqadd v0.8h, v0.8h, v2.8h + ld1 {v3.8h}, [x12] + sqadd v1.8h, v1.8h, v3.8h + clip10 v0.8h, v1.8h, v4.8h, v5.8h + st1 {v0.8h}, [x0], x2 + st1 {v1.8h}, [x12], x2 + bne 1b + ret +endfunc + +function ff_hevc_add_residual_16x16_8_neon, export=1 + mov x3, #16 + add x12, x0, x2 + add x2, x2, x2 +1: subs x3, x3, #2 + ld1 {v16.16b}, [x0] + ld1 {v0.8h-v3.8h}, [x1], #64 + ld1 {v19.16b}, [x12] + uxtl v17.8h, v16.8b + uxtl2 v18.8h, v16.16b + uxtl v20.8h, v19.8b + uxtl2 v21.8h, v19.16b + sqadd v0.8h, v0.8h, v17.8h + sqadd v1.8h, v1.8h, v18.8h + sqadd v2.8h, v2.8h, v20.8h + sqadd v3.8h, v3.8h, v21.8h + sqxtun v0.8b, v0.8h + sqxtun2 v0.16b, v1.8h + sqxtun v1.8b, v2.8h + sqxtun2 v1.16b, v3.8h + st1 {v0.16b}, [x0], x2 + st1 {v1.16b}, [x12], x2 + bne 1b + ret +endfunc + +function ff_hevc_add_residual_16x16_10_neon, export=1 + mov x3, #16 + movi v20.8h, #0 + mvni v21.8h, #0xFC, lsl #8 // movi #0x3FF + add x12, x0, x2 + add x2, x2, x2 +1: subs x3, x3, #2 + ld1 {v16.8h-v17.8h}, [x0] + ld1 {v0.8h-v3.8h}, [x1], #64 + sqadd v0.8h, v0.8h, v16.8h + ld1 {v18.8h-v19.8h}, [x12] + sqadd v1.8h, v1.8h, v17.8h + sqadd v2.8h, v2.8h, v18.8h + sqadd v3.8h, v3.8h, v19.8h + clip10 v0.8h, v1.8h, v20.8h, v21.8h + clip10 v2.8h, v3.8h, v20.8h, v21.8h + st1 {v0.8h-v1.8h}, [x0], x2 + st1 {v2.8h-v3.8h}, [x12], x2 + bne 1b + ret +endfunc + +function ff_hevc_add_residual_32x32_8_neon, export=1 + add x12, x0, x2 + add x2, x2, x2 + mov x3, #32 +1: subs x3, x3, #2 + ld1 {v20.16b, v21.16b}, [x0] + uxtl v16.8h, v20.8b + uxtl2 v17.8h, v20.16b + ld1 {v22.16b, v23.16b}, [x12] + uxtl v18.8h, v21.8b + uxtl2 v19.8h, v21.16b + uxtl v20.8h, v22.8b + ld1 {v0.8h-v3.8h}, [x1], #64 + ld1 {v4.8h-v7.8h}, [x1], #64 + uxtl2 v21.8h, v22.16b + uxtl v22.8h, v23.8b + uxtl2 v23.8h, v23.16b + sqadd v0.8h, v0.8h, v16.8h + sqadd v1.8h, v1.8h, v17.8h + sqadd v2.8h, v2.8h, v18.8h + sqadd v3.8h, v3.8h, v19.8h + sqadd v4.8h, v4.8h, v20.8h + sqadd v5.8h, v5.8h, v21.8h + sqadd v6.8h, v6.8h, v22.8h + sqadd v7.8h, v7.8h, v23.8h + sqxtun v0.8b, v0.8h + sqxtun2 v0.16b, v1.8h + sqxtun v1.8b, v2.8h + sqxtun2 v1.16b, v3.8h + sqxtun v2.8b, v4.8h + sqxtun2 v2.16b, v5.8h + st1 {v0.16b, v1.16b}, [x0], x2 + sqxtun v3.8b, v6.8h + sqxtun2 v3.16b, v7.8h + st1 {v2.16b, v3.16b}, [x12], x2 + bne 1b + ret +endfunc + +function ff_hevc_add_residual_32x32_10_neon, export=1 + mov x3, #32 + movi v20.8h, #0 + mvni v21.8h, #0xFC, lsl #8 // movi #0x3FF +1: subs x3, x3, #1 + ld1 {v0.8h-v3.8h}, [x1], #64 + ld1 {v16.8h-v19.8h}, [x0] + sqadd v0.8h, v0.8h, v16.8h + sqadd v1.8h, v1.8h, v17.8h + sqadd v2.8h, v2.8h, v18.8h + sqadd v3.8h, v3.8h, v19.8h + clip10 v0.8h, v1.8h, v20.8h, v21.8h + clip10 v2.8h, v3.8h, v20.8h, v21.8h + st1 {v0.8h-v3.8h}, [x0], x2 + bne 1b + ret +endfunc + +.macro sum_sub out, in, c, op, p + .ifc \op, + + smlal\p \out, \in, \c + .else + smlsl\p \out, \in, \c + .endif +.endm + +.macro fixsqrshrn d, dt, n, m + .ifc \dt, .8h + sqrshrn2 \d\dt, \n\().4s, \m + .else + sqrshrn \n\().4h, \n\().4s, \m + mov \d\().d[0], \n\().d[0] + .endif +.endm + +// uses and clobbers v28-v31 as temp registers +.macro tr_4x4_8 in0, in1, in2, in3, out0, out1, out2, out3, p1, p2 + sshll\p1 v28.4s, \in0, #6 + mov v29.16b, v28.16b + smull\p1 v30.4s, \in1, v0.h[1] + smull\p1 v31.4s, \in1, v0.h[3] + smlal\p2 v28.4s, \in2, v0.h[0] //e0 + smlsl\p2 v29.4s, \in2, v0.h[0] //e1 + smlal\p2 v30.4s, \in3, v0.h[3] //o0 + smlsl\p2 v31.4s, \in3, v0.h[1] //o1 + + add \out0, v28.4s, v30.4s + add \out1, v29.4s, v31.4s + sub \out2, v29.4s, v31.4s + sub \out3, v28.4s, v30.4s +.endm + +.macro transpose8_4x4 r0, r1, r2, r3 + trn1 v2.8h, \r0\().8h, \r1\().8h + trn2 v3.8h, \r0\().8h, \r1\().8h + trn1 v4.8h, \r2\().8h, \r3\().8h + trn2 v5.8h, \r2\().8h, \r3\().8h + trn1 \r0\().4s, v2.4s, v4.4s + trn2 \r2\().4s, v2.4s, v4.4s + trn1 \r1\().4s, v3.4s, v5.4s + trn2 \r3\().4s, v3.4s, v5.4s +.endm + +.macro transpose_8x8 r0, r1, r2, r3, r4, r5, r6, r7 + transpose8_4x4 \r0, \r1, \r2, \r3 + transpose8_4x4 \r4, \r5, \r6, \r7 +.endm + +.macro tr_8x4 shift, in0,in0t, in1,in1t, in2,in2t, in3,in3t, in4,in4t, in5,in5t, in6,in6t, in7,in7t, p1, p2 + tr_4x4_8 \in0\in0t, \in2\in2t, \in4\in4t, \in6\in6t, v24.4s, v25.4s, v26.4s, v27.4s, \p1, \p2 + + smull\p1 v30.4s, \in1\in1t, v0.h[6] + smull\p1 v28.4s, \in1\in1t, v0.h[4] + smull\p1 v29.4s, \in1\in1t, v0.h[5] + sum_sub v30.4s, \in3\in3t, v0.h[4], -, \p1 + sum_sub v28.4s, \in3\in3t, v0.h[5], +, \p1 + sum_sub v29.4s, \in3\in3t, v0.h[7], -, \p1 + + sum_sub v30.4s, \in5\in5t, v0.h[7], +, \p2 + sum_sub v28.4s, \in5\in5t, v0.h[6], +, \p2 + sum_sub v29.4s, \in5\in5t, v0.h[4], -, \p2 + + sum_sub v30.4s, \in7\in7t, v0.h[5], +, \p2 + sum_sub v28.4s, \in7\in7t, v0.h[7], +, \p2 + sum_sub v29.4s, \in7\in7t, v0.h[6], -, \p2 + + add v31.4s, v26.4s, v30.4s + sub v26.4s, v26.4s, v30.4s + fixsqrshrn \in2,\in2t, v31, \shift + + + smull\p1 v31.4s, \in1\in1t, v0.h[7] + sum_sub v31.4s, \in3\in3t, v0.h[6], -, \p1 + sum_sub v31.4s, \in5\in5t, v0.h[5], +, \p2 + sum_sub v31.4s, \in7\in7t, v0.h[4], -, \p2 + fixsqrshrn \in5,\in5t, v26, \shift + + + add v26.4s, v24.4s, v28.4s + sub v24.4s, v24.4s, v28.4s + add v28.4s, v25.4s, v29.4s + sub v25.4s, v25.4s, v29.4s + add v30.4s, v27.4s, v31.4s + sub v27.4s, v27.4s, v31.4s + + fixsqrshrn \in0,\in0t, v26, \shift + fixsqrshrn \in7,\in7t, v24, \shift + fixsqrshrn \in1,\in1t, v28, \shift + fixsqrshrn \in6,\in6t, v25, \shift + fixsqrshrn \in3,\in3t, v30, \shift + fixsqrshrn \in4,\in4t, v27, \shift +.endm + +.macro idct_8x8 bitdepth +function ff_hevc_idct_8x8_\bitdepth\()_neon, export=1 +//x0 - coeffs + mov x1, x0 + ld1 {v16.8h-v19.8h}, [x1], #64 + ld1 {v20.8h-v23.8h}, [x1] + + movrel x1, trans + ld1 {v0.8h}, [x1] + + tr_8x4 7, v16,.4h, v17,.4h, v18,.4h, v19,.4h, v20,.4h, v21,.4h, v22,.4h, v23,.4h + tr_8x4 7, v16,.8h, v17,.8h, v18,.8h, v19,.8h, v20,.8h, v21,.8h, v22,.8h, v23,.8h, 2, 2 + + transpose_8x8 v16, v17, v18, v19, v20, v21, v22, v23 + + tr_8x4 20 - \bitdepth, v16,.4h, v17,.4h, v18,.4h, v19,.4h, v16,.8h, v17,.8h, v18,.8h, v19,.8h, , 2 + tr_8x4 20 - \bitdepth, v20,.4h, v21,.4h, v22,.4h, v23,.4h, v20,.8h, v21,.8h, v22,.8h, v23,.8h, , 2 + + transpose_8x8 v16, v17, v18, v19, v20, v21, v22, v23 + + mov x1, x0 + st1 {v16.8h-v19.8h}, [x1], #64 + st1 {v20.8h-v23.8h}, [x1] + + ret +endfunc +.endm + +.macro butterfly e, o, tmp_p, tmp_m + add \tmp_p, \e, \o + sub \tmp_m, \e, \o +.endm + +.macro tr16_8x4 in0, in1, in2, in3, offset + tr_4x4_8 \in0\().4h, \in1\().4h, \in2\().4h, \in3\().4h, v24.4s, v25.4s, v26.4s, v27.4s + + smull2 v28.4s, \in0\().8h, v0.h[4] + smull2 v29.4s, \in0\().8h, v0.h[5] + smull2 v30.4s, \in0\().8h, v0.h[6] + smull2 v31.4s, \in0\().8h, v0.h[7] + sum_sub v28.4s, \in1\().8h, v0.h[5], +, 2 + sum_sub v29.4s, \in1\().8h, v0.h[7], -, 2 + sum_sub v30.4s, \in1\().8h, v0.h[4], -, 2 + sum_sub v31.4s, \in1\().8h, v0.h[6], -, 2 + + sum_sub v28.4s, \in2\().8h, v0.h[6], +, 2 + sum_sub v29.4s, \in2\().8h, v0.h[4], -, 2 + sum_sub v30.4s, \in2\().8h, v0.h[7], +, 2 + sum_sub v31.4s, \in2\().8h, v0.h[5], +, 2 + + sum_sub v28.4s, \in3\().8h, v0.h[7], +, 2 + sum_sub v29.4s, \in3\().8h, v0.h[6], -, 2 + sum_sub v30.4s, \in3\().8h, v0.h[5], +, 2 + sum_sub v31.4s, \in3\().8h, v0.h[4], -, 2 + + butterfly v24.4s, v28.4s, v16.4s, v23.4s + butterfly v25.4s, v29.4s, v17.4s, v22.4s + butterfly v26.4s, v30.4s, v18.4s, v21.4s + butterfly v27.4s, v31.4s, v19.4s, v20.4s + add x4, sp, #\offset + st1 {v16.4s-v19.4s}, [x4], #64 + st1 {v20.4s-v23.4s}, [x4] +.endm + +.macro load16 in0, in1, in2, in3 + ld1 {\in0}[0], [x1], x2 + ld1 {\in0}[1], [x3], x2 + ld1 {\in1}[0], [x1], x2 + ld1 {\in1}[1], [x3], x2 + ld1 {\in2}[0], [x1], x2 + ld1 {\in2}[1], [x3], x2 + ld1 {\in3}[0], [x1], x2 + ld1 {\in3}[1], [x3], x2 +.endm + +.macro add_member in, t0, t1, t2, t3, t4, t5, t6, t7, op0, op1, op2, op3, op4, op5, op6, op7, p + sum_sub v21.4s, \in, \t0, \op0, \p + sum_sub v22.4s, \in, \t1, \op1, \p + sum_sub v23.4s, \in, \t2, \op2, \p + sum_sub v24.4s, \in, \t3, \op3, \p + sum_sub v25.4s, \in, \t4, \op4, \p + sum_sub v26.4s, \in, \t5, \op5, \p + sum_sub v27.4s, \in, \t6, \op6, \p + sum_sub v28.4s, \in, \t7, \op7, \p +.endm + +.macro butterfly16 in0, in1, in2, in3, in4, in5, in6, in7 + add v20.4s, \in0, \in1 + sub \in0, \in0, \in1 + add \in1, \in2, \in3 + sub \in2, \in2, \in3 + add \in3, \in4, \in5 + sub \in4, \in4, \in5 + add \in5, \in6, \in7 + sub \in6, \in6, \in7 +.endm + +.macro store16 in0, in1, in2, in3, rx + st1 {\in0}[0], [x1], x2 + st1 {\in0}[1], [x3], \rx + st1 {\in1}[0], [x1], x2 + st1 {\in1}[1], [x3], \rx + st1 {\in2}[0], [x1], x2 + st1 {\in2}[1], [x3], \rx + st1 {\in3}[0], [x1], x2 + st1 {\in3}[1], [x3], \rx +.endm + +.macro scale out0, out1, out2, out3, in0, in1, in2, in3, in4, in5, in6, in7, shift + sqrshrn \out0\().4h, \in0, \shift + sqrshrn2 \out0\().8h, \in1, \shift + sqrshrn \out1\().4h, \in2, \shift + sqrshrn2 \out1\().8h, \in3, \shift + sqrshrn \out2\().4h, \in4, \shift + sqrshrn2 \out2\().8h, \in5, \shift + sqrshrn \out3\().4h, \in6, \shift + sqrshrn2 \out3\().8h, \in7, \shift +.endm + +.macro transpose16_4x4_2 r0, r1, r2, r3 + // lower halves + trn1 v2.4h, \r0\().4h, \r1\().4h + trn2 v3.4h, \r0\().4h, \r1\().4h + trn1 v4.4h, \r2\().4h, \r3\().4h + trn2 v5.4h, \r2\().4h, \r3\().4h + trn1 v6.2s, v2.2s, v4.2s + trn2 v7.2s, v2.2s, v4.2s + trn1 v2.2s, v3.2s, v5.2s + trn2 v4.2s, v3.2s, v5.2s + mov \r0\().d[0], v6.d[0] + mov \r2\().d[0], v7.d[0] + mov \r1\().d[0], v2.d[0] + mov \r3\().d[0], v4.d[0] + + // upper halves in reverse order + trn1 v2.8h, \r3\().8h, \r2\().8h + trn2 v3.8h, \r3\().8h, \r2\().8h + trn1 v4.8h, \r1\().8h, \r0\().8h + trn2 v5.8h, \r1\().8h, \r0\().8h + trn1 v6.4s, v2.4s, v4.4s + trn2 v7.4s, v2.4s, v4.4s + trn1 v2.4s, v3.4s, v5.4s + trn2 v4.4s, v3.4s, v5.4s + mov \r3\().d[1], v6.d[1] + mov \r1\().d[1], v7.d[1] + mov \r2\().d[1], v2.d[1] + mov \r0\().d[1], v4.d[1] +.endm + +.macro tr_16x4 name, shift, offset, step +function func_tr_16x4_\name + mov x1, x5 + add x3, x5, #(\step * 64) + mov x2, #(\step * 128) + load16 v16.d, v17.d, v18.d, v19.d + movrel x1, trans + ld1 {v0.8h}, [x1] + + tr16_8x4 v16, v17, v18, v19, \offset + + add x1, x5, #(\step * 32) + add x3, x5, #(\step * 3 *32) + mov x2, #(\step * 128) + load16 v20.d, v17.d, v18.d, v19.d + movrel x1, trans, 16 + ld1 {v1.8h}, [x1] + smull v21.4s, v20.4h, v1.h[0] + smull v22.4s, v20.4h, v1.h[1] + smull v23.4s, v20.4h, v1.h[2] + smull v24.4s, v20.4h, v1.h[3] + smull v25.4s, v20.4h, v1.h[4] + smull v26.4s, v20.4h, v1.h[5] + smull v27.4s, v20.4h, v1.h[6] + smull v28.4s, v20.4h, v1.h[7] + + add_member v20.8h, v1.h[1], v1.h[4], v1.h[7], v1.h[5], v1.h[2], v1.h[0], v1.h[3], v1.h[6], +, +, +, -, -, -, -, -, 2 + add_member v17.4h, v1.h[2], v1.h[7], v1.h[3], v1.h[1], v1.h[6], v1.h[4], v1.h[0], v1.h[5], +, +, -, -, -, +, +, + + add_member v17.8h, v1.h[3], v1.h[5], v1.h[1], v1.h[7], v1.h[0], v1.h[6], v1.h[2], v1.h[4], +, -, -, +, +, +, -, -, 2 + add_member v18.4h, v1.h[4], v1.h[2], v1.h[6], v1.h[0], v1.h[7], v1.h[1], v1.h[5], v1.h[3], +, -, -, +, -, -, +, + + add_member v18.8h, v1.h[5], v1.h[0], v1.h[4], v1.h[6], v1.h[1], v1.h[3], v1.h[7], v1.h[2], +, -, +, +, -, +, +, -, 2 + add_member v19.4h, v1.h[6], v1.h[3], v1.h[0], v1.h[2], v1.h[5], v1.h[7], v1.h[4], v1.h[1], +, -, +, -, +, +, -, + + add_member v19.8h, v1.h[7], v1.h[6], v1.h[5], v1.h[4], v1.h[3], v1.h[2], v1.h[1], v1.h[0], +, -, +, -, +, -, +, -, 2 + + add x4, sp, #\offset + ld1 {v16.4s-v19.4s}, [x4], #64 + + butterfly16 v16.4s, v21.4s, v17.4s, v22.4s, v18.4s, v23.4s, v19.4s, v24.4s + scale v29, v30, v31, v24, v20.4s, v16.4s, v21.4s, v17.4s, v22.4s, v18.4s, v23.4s, v19.4s, \shift + transpose16_4x4_2 v29, v30, v31, v24 + mov x1, x6 + add x3, x6, #(24 +3*32) + mov x2, #32 + mov x4, #-32 + store16 v29.d, v30.d, v31.d, v24.d, x4 + + add x4, sp, #(\offset + 64) + ld1 {v16.4s-v19.4s}, [x4] + butterfly16 v16.4s, v25.4s, v17.4s, v26.4s, v18.4s, v27.4s, v19.4s, v28.4s + scale v29, v30, v31, v20, v20.4s, v16.4s, v25.4s, v17.4s, v26.4s, v18.4s, v27.4s, v19.4s, \shift + transpose16_4x4_2 v29, v30, v31, v20 + + add x1, x6, #8 + add x3, x6, #(16 + 3 * 32) + mov x2, #32 + mov x4, #-32 + store16 v29.d, v30.d, v31.d, v20.d, x4 + + ret +endfunc +.endm + +.macro idct_16x16 bitdepth +function ff_hevc_idct_16x16_\bitdepth\()_neon, export=1 +//r0 - coeffs + mov x15, x30 + + // allocate a temp buffer + sub sp, sp, #640 + +.irp i, 0, 1, 2, 3 + add x5, x0, #(8 * \i) + add x6, sp, #(8 * \i * 16) + bl func_tr_16x4_firstpass +.endr + +.irp i, 0, 1, 2, 3 + add x5, sp, #(8 * \i) + add x6, x0, #(8 * \i * 16) + bl func_tr_16x4_secondpass_\bitdepth +.endr + + add sp, sp, #640 + + mov x30, x15 + ret +endfunc +.endm + +idct_8x8 8 +idct_8x8 10 + +tr_16x4 firstpass, 7, 512, 1 +tr_16x4 secondpass_8, 20 - 8, 512, 1 +tr_16x4 secondpass_10, 20 - 10, 512, 1 + +idct_16x16 8 +idct_16x16 10 + +// void ff_hevc_idct_NxN_dc_DEPTH_neon(int16_t *coeffs) +.macro idct_dc size, bitdepth +function ff_hevc_idct_\size\()x\size\()_dc_\bitdepth\()_neon, export=1 + movi v1.8h, #((1 << (14 - \bitdepth))+1) + ld1r {v4.8h}, [x0] + add v4.8h, v4.8h, v1.8h + sshr v0.8h, v4.8h, #(15 - \bitdepth) + sshr v1.8h, v4.8h, #(15 - \bitdepth) +.if \size > 4 + sshr v2.8h, v4.8h, #(15 - \bitdepth) + sshr v3.8h, v4.8h, #(15 - \bitdepth) +.if \size > 16 /* dc 32x32 */ + mov x2, #4 +1: + subs x2, x2, #1 +.endif + add x12, x0, #64 + mov x13, #128 +.if \size > 8 /* dc 16x16 */ + st1 {v0.8h-v3.8h}, [x0], x13 + st1 {v0.8h-v3.8h}, [x12], x13 + st1 {v0.8h-v3.8h}, [x0], x13 + st1 {v0.8h-v3.8h}, [x12], x13 + st1 {v0.8h-v3.8h}, [x0], x13 + st1 {v0.8h-v3.8h}, [x12], x13 +.endif /* dc 8x8 */ + st1 {v0.8h-v3.8h}, [x0], x13 + st1 {v0.8h-v3.8h}, [x12], x13 +.if \size > 16 /* dc 32x32 */ + bne 1b +.endif +.else /* dc 4x4 */ + st1 {v0.8h-v1.8h}, [x0] +.endif + ret +endfunc +.endm + +idct_dc 4, 8 +idct_dc 4, 10 + +idct_dc 8, 8 +idct_dc 8, 10 + +idct_dc 16, 8 +idct_dc 16, 10 + +idct_dc 32, 8 +idct_dc 32, 10 diff --git a/libavcodec/aarch64/hevcdsp_init_aarch64.c b/libavcodec/aarch64/hevcdsp_init_aarch64.c new file mode 100644 index 000000000..c785e46f7 --- /dev/null +++ b/libavcodec/aarch64/hevcdsp_init_aarch64.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020 Reimar Döffinger + * + * 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/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/hevcdsp.h" + +void ff_hevc_add_residual_4x4_8_neon(uint8_t *_dst, int16_t *coeffs, + ptrdiff_t stride); +void ff_hevc_add_residual_4x4_10_neon(uint8_t *_dst, int16_t *coeffs, + ptrdiff_t stride); +void ff_hevc_add_residual_8x8_8_neon(uint8_t *_dst, int16_t *coeffs, + ptrdiff_t stride); +void ff_hevc_add_residual_8x8_10_neon(uint8_t *_dst, int16_t *coeffs, + ptrdiff_t stride); +void ff_hevc_add_residual_16x16_8_neon(uint8_t *_dst, int16_t *coeffs, + ptrdiff_t stride); +void ff_hevc_add_residual_16x16_10_neon(uint8_t *_dst, int16_t *coeffs, + ptrdiff_t stride); +void ff_hevc_add_residual_32x32_8_neon(uint8_t *_dst, int16_t *coeffs, + ptrdiff_t stride); +void ff_hevc_add_residual_32x32_10_neon(uint8_t *_dst, int16_t *coeffs, + ptrdiff_t stride); +void ff_hevc_idct_8x8_8_neon(int16_t *coeffs, int col_limit); +void ff_hevc_idct_8x8_10_neon(int16_t *coeffs, int col_limit); +void ff_hevc_idct_16x16_8_neon(int16_t *coeffs, int col_limit); +void ff_hevc_idct_16x16_10_neon(int16_t *coeffs, int col_limit); +void ff_hevc_idct_4x4_dc_8_neon(int16_t *coeffs); +void ff_hevc_idct_8x8_dc_8_neon(int16_t *coeffs); +void ff_hevc_idct_16x16_dc_8_neon(int16_t *coeffs); +void ff_hevc_idct_32x32_dc_8_neon(int16_t *coeffs); +void ff_hevc_idct_4x4_dc_10_neon(int16_t *coeffs); +void ff_hevc_idct_8x8_dc_10_neon(int16_t *coeffs); +void ff_hevc_idct_16x16_dc_10_neon(int16_t *coeffs); +void ff_hevc_idct_32x32_dc_10_neon(int16_t *coeffs); +void ff_hevc_sao_band_filter_8x8_8_neon(uint8_t *_dst, uint8_t *_src, + ptrdiff_t stride_dst, ptrdiff_t stride_src, + int16_t *sao_offset_val, int sao_left_class, + int width, int height); + + + +av_cold void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth) +{ + if (!have_neon(av_get_cpu_flags())) return; + + if (bit_depth == 8) { + c->add_residual[0] = ff_hevc_add_residual_4x4_8_neon; + c->add_residual[1] = ff_hevc_add_residual_8x8_8_neon; + c->add_residual[2] = ff_hevc_add_residual_16x16_8_neon; + c->add_residual[3] = ff_hevc_add_residual_32x32_8_neon; + c->idct[1] = ff_hevc_idct_8x8_8_neon; + c->idct[2] = ff_hevc_idct_16x16_8_neon; + c->idct_dc[0] = ff_hevc_idct_4x4_dc_8_neon; + c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_neon; + c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_neon; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_neon; + c->sao_band_filter[0] = ff_hevc_sao_band_filter_8x8_8_neon; + } + if (bit_depth == 10) { + c->add_residual[0] = ff_hevc_add_residual_4x4_10_neon; + c->add_residual[1] = ff_hevc_add_residual_8x8_10_neon; + c->add_residual[2] = ff_hevc_add_residual_16x16_10_neon; + c->add_residual[3] = ff_hevc_add_residual_32x32_10_neon; + c->idct[1] = ff_hevc_idct_8x8_10_neon; + c->idct[2] = ff_hevc_idct_16x16_10_neon; + c->idct_dc[0] = ff_hevc_idct_4x4_dc_10_neon; + c->idct_dc[1] = ff_hevc_idct_8x8_dc_10_neon; + c->idct_dc[2] = ff_hevc_idct_16x16_dc_10_neon; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_10_neon; + } +} diff --git a/libavcodec/aarch64/hevcdsp_sao_neon.S b/libavcodec/aarch64/hevcdsp_sao_neon.S new file mode 100644 index 000000000..f9fed8345 --- /dev/null +++ b/libavcodec/aarch64/hevcdsp_sao_neon.S @@ -0,0 +1,87 @@ +/* -*-arm64-*- + * vim: syntax=arm64asm + * + * AArch64 NEON optimised SAO functions for HEVC decoding + * + * Copyright (c) 2020 Josh Dekker + * + * 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/aarch64/asm.S" + +// void sao_band_filter(uint8_t *_dst, uint8_t *_src, +// ptrdiff_t stride_dst, ptrdiff_t stride_src, +// int16_t *sao_offset_val, int sao_left_class, +// int width, int height) +function ff_hevc_sao_band_filter_8x8_8_neon, export=1 + sub sp, sp, #64 + stp xzr, xzr, [sp] + stp xzr, xzr, [sp, #16] + stp xzr, xzr, [sp, #32] + stp xzr, xzr, [sp, #48] + mov w8, #4 +0: + ldrsh x9, [x4, x8, lsl #1] // x9 = sao_offset_val[k+1] + subs w8, w8, #1 + add w10, w8, w5 // x10 = k + sao_left_class + and w10, w10, #0x1F + strh w9, [sp, x10, lsl #1] + bne 0b + ld1 {v16.16b-v19.16b}, [sp], #64 + movi v20.8h, #1 +1: // beginning of line + mov w8, w6 +2: + // Simple layout for accessing 16bit values + // with 8bit LUT. + // + // 00 01 02 03 04 05 06 07 + // +-----------------------------------> + // |xDE#xAD|xCA#xFE|xBE#xEF|xFE#xED|.... + // +-----------------------------------> + // i-0 i-1 i-2 i-3 + // dst[x] = av_clip_pixel(src[x] + offset_table[src[x] >> shift]); + ld1 {v2.8b}, [x1] + // load src[x] + uxtl v0.8h, v2.8b + // >> shift + ushr v2.8h, v0.8h, #3 // BIT_DEPTH - 3 + // x2 (access lower short) + shl v1.8h, v2.8h, #1 // low (x2, accessing short) + // +1 access upper short + add v3.8h, v1.8h, v20.8h + // shift insert index to upper byte + sli v1.8h, v3.8h, #8 + // table + tbx v2.16b, {v16.16b-v19.16b}, v1.16b + // src[x] + table + add v1.8h, v0.8h, v2.8h + // clip + narrow + sqxtun v4.8b, v1.8h + // store + st1 {v4.8b}, [x0] + // done 8 pixels + subs w8, w8, #8 + bne 2b + // finished line + subs w7, w7, #1 + add x0, x0, x2 // dst += stride_dst + add x1, x1, x3 // src += stride_src + bne 1b + ret +endfunc diff --git a/libavcodec/aarch64/neontest.c b/libavcodec/aarch64/neontest.c index a24c22dd3..a4fc5a0e2 100644 --- a/libavcodec/aarch64/neontest.c +++ b/libavcodec/aarch64/neontest.c @@ -29,6 +29,7 @@ wrap(avcodec_open2(AVCodecContext *avctx, testneonclobbers(avcodec_open2, avctx, codec, options); } +#if FF_API_OLD_ENCDEC wrap(avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, @@ -47,15 +48,6 @@ wrap(avcodec_decode_video2(AVCodecContext *avctx, got_picture_ptr, avpkt); } -wrap(avcodec_decode_subtitle2(AVCodecContext *avctx, - AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt)) -{ - testneonclobbers(avcodec_decode_subtitle2, avctx, sub, - got_sub_ptr, avpkt); -} - wrap(avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, @@ -65,6 +57,22 @@ wrap(avcodec_encode_audio2(AVCodecContext *avctx, got_packet_ptr); } +wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr)) +{ + testneonclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr); +} +#endif + +wrap(avcodec_decode_subtitle2(AVCodecContext *avctx, + AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt)) +{ + testneonclobbers(avcodec_decode_subtitle2, avctx, sub, + got_sub_ptr, avpkt); +} + wrap(avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub)) @@ -72,12 +80,6 @@ wrap(avcodec_encode_subtitle(AVCodecContext *avctx, testneonclobbers(avcodec_encode_subtitle, avctx, buf, buf_size, sub); } -wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, - const AVFrame *frame, int *got_packet_ptr)) -{ - testneonclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr); -} - wrap(avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)) { testneonclobbers(avcodec_send_packet, avctx, avpkt); diff --git a/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c b/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c index 8dcfdeaaf..d2a4e90b3 100644 --- a/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c +++ b/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c @@ -22,6 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/aarch64/cpu.h" #include "vp9dsp_init.h" diff --git a/libavcodec/aarch64/vp9dsp_init_aarch64.c b/libavcodec/aarch64/vp9dsp_init_aarch64.c index 4c699759f..4d1fee62d 100644 --- a/libavcodec/aarch64/vp9dsp_init_aarch64.c +++ b/libavcodec/aarch64/vp9dsp_init_aarch64.c @@ -22,6 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/aarch64/cpu.h" #include "libavcodec/vp9dsp.h" #include "vp9dsp_init.h" diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h index f8f6a81f4..e358f8d9e 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -27,7 +27,6 @@ #ifndef AVCODEC_AC3_H #define AVCODEC_AC3_H -#define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ #define EAC3_MAX_CHANNELS 16 /**< maximum number of channels in EAC3 */ #define AC3_MAX_CHANNELS 7 /**< maximum number of channels, including coupling channel */ #define CPL_CH 0 /**< coupling channel index */ diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index eaa327a3e..c7deb56e1 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -33,6 +33,7 @@ #include "libavutil/crc.h" #include "libavutil/downmix_info.h" #include "libavutil/opt.h" +#include "libavutil/thread.h" #include "bswapdsp.h" #include "internal.h" #include "aac_ac3_parser.h" @@ -183,23 +184,26 @@ static av_cold void ac3_tables_init(void) */ static av_cold int ac3_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; AC3DecodeContext *s = avctx->priv_data; - int i; + int i, ret; s->avctx = avctx; - ac3_tables_init(); - ff_mdct_init(&s->imdct_256, 8, 1, 1.0); - ff_mdct_init(&s->imdct_512, 9, 1, 1.0); + if ((ret = ff_mdct_init(&s->imdct_256, 8, 1, 1.0)) < 0 || + (ret = ff_mdct_init(&s->imdct_512, 9, 1, 1.0)) < 0) + return ret; AC3_RENAME(ff_kbd_window_init)(s->window, 5.0, 256); ff_bswapdsp_init(&s->bdsp); #if (USE_FIXED) s->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & AV_CODEC_FLAG_BITEXACT); #else - s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); ff_fmt_convert_init(&s->fmt_conv, avctx); + s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); #endif + if (!s->fdsp) + return AVERROR(ENOMEM); ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT); av_lfg_init(&s->dith_state, 0); @@ -223,6 +227,8 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) s->dlyptr[i] = s->delay[i]; } + ff_thread_once(&init_static_once, ac3_tables_init); + return 0; } diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index ce1434b55..85653990c 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -53,6 +53,8 @@ #include "libavutil/float_dsp.h" #include "libavutil/fixed_dsp.h" #include "libavutil/lfg.h" +#include "libavutil/mem_internal.h" + #include "ac3.h" #include "ac3dsp.h" #include "bswapdsp.h" diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c index 336a538ca..daab43329 100644 --- a/libavcodec/ac3dec_fixed.c +++ b/libavcodec/ac3dec_fixed.c @@ -176,9 +176,11 @@ AVCodec ff_ac3_fixed_decoder = { .init = ac3_decode_init, .close = ac3_decode_end, .decode = ac3_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, .priv_class = &ac3_decoder_class, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/ac3dec_float.c b/libavcodec/ac3dec_float.c index b85a4ce33..b18317f8b 100644 --- a/libavcodec/ac3dec_float.c +++ b/libavcodec/ac3dec_float.c @@ -61,11 +61,13 @@ AVCodec ff_ac3_decoder = { .init = ac3_decode_init, .close = ac3_decode_end, .decode = ac3_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_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, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; #if CONFIG_EAC3_DECODER @@ -84,10 +86,12 @@ AVCodec ff_eac3_decoder = { .init = ac3_decode_init, .close = ac3_decode_end, .decode = ac3_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_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, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index 43438da13..85c721dd3 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "ac3.h" #include "ac3dsp.h" @@ -44,49 +46,6 @@ static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs) } } -static int ac3_max_msb_abs_int16_c(const int16_t *src, int len) -{ - int i, v = 0; - for (i = 0; i < len; i++) - v |= abs(src[i]); - return v; -} - -static void ac3_lshift_int16_c(int16_t *src, unsigned int len, - unsigned int shift) -{ - uint32_t *src32 = (uint32_t *)src; - const uint32_t mask = ~(((1 << shift) - 1) << 16); - int i; - len >>= 1; - for (i = 0; i < len; i += 8) { - src32[i ] = (src32[i ] << shift) & mask; - src32[i+1] = (src32[i+1] << shift) & mask; - src32[i+2] = (src32[i+2] << shift) & mask; - src32[i+3] = (src32[i+3] << shift) & mask; - src32[i+4] = (src32[i+4] << shift) & mask; - src32[i+5] = (src32[i+5] << shift) & mask; - src32[i+6] = (src32[i+6] << shift) & mask; - src32[i+7] = (src32[i+7] << shift) & mask; - } -} - -static void ac3_rshift_int32_c(int32_t *src, unsigned int len, - unsigned int shift) -{ - do { - *src++ >>= shift; - *src++ >>= shift; - *src++ >>= shift; - *src++ >>= shift; - *src++ >>= shift; - *src++ >>= shift; - *src++ >>= shift; - *src++ >>= shift; - len -= 8; - } while (len > 0); -} - static void float_to_fixed24_c(int32_t *dst, const float *src, unsigned int len) { const float scale = 1 << 24; @@ -374,19 +333,6 @@ void ff_ac3dsp_downmix_fixed(AC3DSPContext *c, int32_t **samples, int16_t **matr ac3_downmix_c_fixed(samples, matrix, out_ch, in_ch, len); } -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; - } -} - void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix, int out_ch, int in_ch, int len) { @@ -422,9 +368,6 @@ void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix, av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) { c->ac3_exponent_min = ac3_exponent_min_c; - c->ac3_max_msb_abs_int16 = ac3_max_msb_abs_int16_c; - c->ac3_lshift_int16 = ac3_lshift_int16_c; - c->ac3_rshift_int32 = ac3_rshift_int32_c; c->float_to_fixed24 = float_to_fixed24_c; c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_c; c->update_bap_counts = ac3_update_bap_counts_c; @@ -436,7 +379,6 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) c->out_channels = 0; c->downmix = NULL; c->downmix_fixed = NULL; - c->apply_window_int16 = apply_window_int16_c; if (ARCH_ARM) ff_ac3dsp_init_arm(c, bit_exact); diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h index 161de4cb8..a23b11526 100644 --- a/libavcodec/ac3dsp.h +++ b/libavcodec/ac3dsp.h @@ -42,39 +42,6 @@ typedef struct AC3DSPContext { */ void (*ac3_exponent_min)(uint8_t *exp, int num_reuse_blocks, int nb_coefs); - /** - * Calculate the maximum MSB of the absolute value of each element in an - * array of int16_t. - * @param src input array - * constraints: align 16. values must be in range [-32767,32767] - * @param len number of values in the array - * constraints: multiple of 16 greater than 0 - * @return a value with the same MSB as max(abs(src[])) - */ - int (*ac3_max_msb_abs_int16)(const int16_t *src, int len); - - /** - * Left-shift each value in an array of int16_t by a specified amount. - * @param src input array - * constraints: align 16 - * @param len number of values in the array - * constraints: multiple of 32 greater than 0 - * @param shift left shift amount - * constraints: range [0,15] - */ - void (*ac3_lshift_int16)(int16_t *src, unsigned int len, unsigned int shift); - - /** - * Right-shift each value in an array of int32_t by a specified amount. - * @param src input array - * constraints: align 16 - * @param len number of values in the array - * constraints: multiple of 16 greater than 0 - * @param shift right shift amount - * constraints: range [0,31] - */ - void (*ac3_rshift_int32)(int32_t *src, unsigned int len, unsigned int shift); - /** * Convert an array of float in range [-1.0,1.0] to int32_t with range * [-(1<<24),(1<<24)] @@ -136,20 +103,6 @@ typedef struct AC3DSPContext { int in_channels; void (*downmix)(float **samples, float **matrix, int len); void (*downmix_fixed)(int32_t **samples, int16_t **matrix, 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/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index ddbc7b247..4cfd0afe1 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -34,7 +34,9 @@ #include "libavutil/channel_layout.h" #include "libavutil/crc.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "internal.h" #include "me_cmp.h" @@ -67,6 +69,65 @@ static const float extmixlev_options[EXTMIXLEV_NUM_OPTIONS] = { LEVEL_MINUS_3DB, LEVEL_MINUS_4POINT5DB, LEVEL_MINUS_6DB, LEVEL_ZERO }; +/* The first two options apply only to the AC-3 encoders; + * the rest is also valid for EAC-3. When modifying it, + * it might be necessary to adapt said offset in eac3enc.c. */ +#define OFFSET(param) offsetof(AC3EncodeContext, options.param) +#define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) +const AVOption ff_ac3_enc_options[] = { +/* AC-3 downmix levels */ +{"center_mixlev", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_4POINT5DB }, 0.0, 1.0, AC3ENC_PARAM}, +{"surround_mixlev", "Surround Mix Level", OFFSET(surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_6DB }, 0.0, 1.0, AC3ENC_PARAM}, +/* audio production information */ +{"mixing_level", "Mixing Level", OFFSET(mixing_level), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 111, AC3ENC_PARAM}, +{"room_type", "Room Type", OFFSET(room_type), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_SMALL_ROOM, AC3ENC_PARAM, "room_type"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"}, + {"large", "Large Room", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_LARGE_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"}, + {"small", "Small Room", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_SMALL_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"}, +/* Metadata Options */ +{"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, AC3ENC_PARAM}, +{"copyright", "Copyright Bit", OFFSET(copyright), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM}, +{"dialnorm", "Dialogue Level (dB)", OFFSET(dialogue_level), AV_OPT_TYPE_INT, {.i64 = -31 }, -31, -1, AC3ENC_PARAM}, +{"dsur_mode", "Dolby Surround Mode", OFFSET(dolby_surround_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dsur_mode"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"}, + {"on", "Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"}, + {"off", "Not Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"}, +{"original", "Original Bit Stream", OFFSET(original), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM}, +/* extended bitstream information */ +{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DOWNMIX_DPLII, AC3ENC_PARAM, "dmix_mode"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"}, + {"ltrt", "Lt/Rt Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LTRT }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"}, + {"loro", "Lo/Ro Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LORO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"}, + {"dplii", "Dolby Pro Logic II Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_DPLII }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"}, +{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM}, +{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM}, +{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM}, +{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM}, +{"dsurex_mode", "Dolby Surround EX Mode", OFFSET(dolby_surround_ex_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DSUREX_DPLIIZ, AC3ENC_PARAM, "dsurex_mode"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"}, + {"on", "Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"}, + {"off", "Not Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"}, + {"dpliiz", "Dolby Pro Logic IIz-encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DSUREX_DPLIIZ }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"}, +{"dheadphone_mode", "Dolby Headphone Mode", OFFSET(dolby_headphone_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dheadphone_mode"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"}, + {"on", "Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"}, + {"off", "Not Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"}, +{"ad_conv_type", "A/D Converter Type", OFFSET(ad_converter_type), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_ADCONV_HDCD, AC3ENC_PARAM, "ad_conv_type"}, + {"standard", "Standard (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_ADCONV_STANDARD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, + {"hdcd", "HDCD", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_ADCONV_HDCD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, +/* Other Encoding Options */ +{"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, AC3ENC_PARAM}, +{"channel_coupling", "Channel Coupling", OFFSET(channel_coupling), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, AC3ENC_OPT_ON, AC3ENC_PARAM, "channel_coupling"}, + {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "channel_coupling"}, +{"cpl_start_band", "Coupling Start Band", OFFSET(cpl_start), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, 15, AC3ENC_PARAM, "cpl_start_band"}, + {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "cpl_start_band"}, +{NULL} +}; + +const AVCodecDefault ff_ac3_enc_defaults[] = { + { "b", "0" }, + { NULL } +}; /** * LUT for number of exponent groups. @@ -100,6 +161,15 @@ const uint64_t ff_ac3_channel_layouts[19] = { 0 }; +/** + * Table to remap channels from SMPTE order to AC-3 order. + * [channel_mode][lfe][ch] + */ +static const uint8_t ac3_enc_channel_map[8][2][6] = { + COMMON_CHANNEL_MAP + { { 0, 1, 2, 3, }, { 0, 1, 3, 4, 2, } }, + { { 0, 2, 1, 3, 4, }, { 0, 2, 1, 4, 5, 3 } }, +}; /** * LUT to select the bandwidth code based on the bit rate, sample rate, and @@ -269,7 +339,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s) * * @param s AC-3 encoder private context */ -void ff_ac3_apply_rematrixing(AC3EncodeContext *s) +static void ac3_apply_rematrixing(AC3EncodeContext *s) { int nb_coefs; int blk, bnd, i; @@ -303,7 +373,7 @@ void ff_ac3_apply_rematrixing(AC3EncodeContext *s) /* * Initialize exponent tables. */ -static av_cold void exponent_init(AC3EncodeContext *s) +static av_cold void exponent_init(void) { int expstr, i, grpsize; @@ -316,9 +386,6 @@ static av_cold void exponent_init(AC3EncodeContext *s) } /* LFE */ exponent_group_tab[0][0][7] = 2; - - if (CONFIG_EAC3_ENCODER && s->eac3) - ff_eac3_exponent_init(); } @@ -576,7 +643,7 @@ static int count_exponent_bits(AC3EncodeContext *s) * * @param s AC-3 encoder private context */ -void ff_ac3_group_exponents(AC3EncodeContext *s) +static void ac3_group_exponents(AC3EncodeContext *s) { int blk, ch, i, cpl; int group_size, nb_groups; @@ -634,7 +701,7 @@ void ff_ac3_group_exponents(AC3EncodeContext *s) * * @param s AC-3 encoder private context */ -void ff_ac3_process_exponents(AC3EncodeContext *s) +static void ac3_process_exponents(AC3EncodeContext *s) { extract_exponents(s); @@ -1143,7 +1210,7 @@ static int cbr_bit_allocation(AC3EncodeContext *s) * frame size. Output is the SNR offset and a set of bit allocation pointers * used to quantize the mantissas. */ -int ff_ac3_compute_bit_allocation(AC3EncodeContext *s) +static int ac3_compute_bit_allocation(AC3EncodeContext *s) { count_frame_bits(s); @@ -1297,7 +1364,7 @@ static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, * * @param s AC-3 encoder private context */ -void ff_ac3_quantize_mantissas(AC3EncodeContext *s) +static void ac3_quantize_mantissas(AC3EncodeContext *s) { int blk, ch, ch0=0, got_cpl; @@ -1658,11 +1725,11 @@ static void output_frame_end(AC3EncodeContext *s) * @param s AC-3 encoder private context * @param frame output data buffer */ -void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame) +static void ac3_output_frame(AC3EncodeContext *s, unsigned char *frame) { int blk; - init_put_bits(&s->pb, frame, AC3_MAX_CODED_FRAME_SIZE); + init_put_bits(&s->pb, frame, s->frame_size); s->output_frame_header(s); @@ -1672,6 +1739,36 @@ void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame) output_frame_end(s); } +int ff_ac3_encode_frame_common_end(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + AC3EncodeContext *const s = avctx->priv_data; + int ret; + + ac3_apply_rematrixing(s); + + ac3_process_exponents(s); + + ret = ac3_compute_bit_allocation(s); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n"); + return ret; + } + + ac3_group_exponents(s); + + ac3_quantize_mantissas(s); + + if ((ret = ff_alloc_packet2(avctx, avpkt, s->frame_size, 0)) < 0) + return ret; + ac3_output_frame(s, avpkt->data); + + if (frame->pts != AV_NOPTS_VALUE) + avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding); + + *got_packet_ptr = 1; + return 0; +} static void dprint_options(AC3EncodeContext *s) { @@ -2018,6 +2115,7 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx) int blk, ch; AC3EncodeContext *s = avctx->priv_data; + av_freep(&s->mdct_window); av_freep(&s->windowed_samples); if (s->planar_samples) for (ch = 0; ch < s->channels; ch++) @@ -2050,8 +2148,7 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx) av_freep(&block->cpl_coord_mant); } - if (s->mdct_end) - s->mdct_end(s); + s->mdct_end(s); return 0; } @@ -2096,7 +2193,7 @@ static av_cold int set_channel_info(AC3EncodeContext *s, int channels, s->has_center = (s->channel_mode & 0x01) && s->channel_mode != AC3_CHMODE_MONO; s->has_surround = s->channel_mode & 0x04; - s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe_on]; + s->channel_map = ac3_enc_channel_map[s->channel_mode][s->lfe_on]; *channel_layout = ch_layout; if (s->lfe_on) *channel_layout |= AV_CH_LOW_FREQUENCY; @@ -2322,60 +2419,46 @@ static av_cold void set_bandwidth(AC3EncodeContext *s) static av_cold int allocate_buffers(AC3EncodeContext *s) { - AVCodecContext *avctx = s->avctx; int blk, ch; int channels = s->channels + 1; /* includes coupling channel */ int channel_blocks = channels * s->num_blocks; int total_coefs = AC3_MAX_COEFS * channel_blocks; if (s->allocate_sample_buffers(s)) - goto alloc_fail; + return AVERROR(ENOMEM); + + if (!FF_ALLOC_TYPED_ARRAY(s->bap_buffer, total_coefs) || + !FF_ALLOC_TYPED_ARRAY(s->bap1_buffer, total_coefs) || + !FF_ALLOCZ_TYPED_ARRAY(s->mdct_coef_buffer, total_coefs) || + !FF_ALLOC_TYPED_ARRAY(s->exp_buffer, total_coefs) || + !FF_ALLOC_TYPED_ARRAY(s->grouped_exp_buffer, channel_blocks * 128) || + !FF_ALLOC_TYPED_ARRAY(s->psd_buffer, total_coefs) || + !FF_ALLOC_TYPED_ARRAY(s->band_psd_buffer, channel_blocks * 64) || + !FF_ALLOC_TYPED_ARRAY(s->mask_buffer, channel_blocks * 64) || + !FF_ALLOC_TYPED_ARRAY(s->qmant_buffer, total_coefs)) + return AVERROR(ENOMEM); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->bap_buffer, total_coefs, - sizeof(*s->bap_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->bap1_buffer, total_coefs, - sizeof(*s->bap1_buffer), alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->mdct_coef_buffer, total_coefs, - sizeof(*s->mdct_coef_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->exp_buffer, total_coefs, - sizeof(*s->exp_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->grouped_exp_buffer, channel_blocks, 128 * - sizeof(*s->grouped_exp_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->psd_buffer, total_coefs, - sizeof(*s->psd_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->band_psd_buffer, channel_blocks, 64 * - sizeof(*s->band_psd_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->mask_buffer, channel_blocks, 64 * - sizeof(*s->mask_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->qmant_buffer, total_coefs, - sizeof(*s->qmant_buffer), alloc_fail); if (s->cpl_enabled) { - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->cpl_coord_exp_buffer, channel_blocks, 16 * - sizeof(*s->cpl_coord_exp_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->cpl_coord_mant_buffer, channel_blocks, 16 * - sizeof(*s->cpl_coord_mant_buffer), alloc_fail); + if (!FF_ALLOC_TYPED_ARRAY(s->cpl_coord_exp_buffer, channel_blocks * 16) || + !FF_ALLOC_TYPED_ARRAY(s->cpl_coord_mant_buffer, channel_blocks * 16)) + return AVERROR(ENOMEM); } for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->mdct_coef, channels, sizeof(*block->mdct_coef), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->exp, channels, sizeof(*block->exp), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->grouped_exp, channels, sizeof(*block->grouped_exp), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->psd, channels, sizeof(*block->psd), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->band_psd, channels, sizeof(*block->band_psd), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->mask, channels, sizeof(*block->mask), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->qmant, channels, sizeof(*block->qmant), - alloc_fail); + + if (!FF_ALLOCZ_TYPED_ARRAY(block->mdct_coef, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->exp, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->grouped_exp, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->psd, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->band_psd, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->mask, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->qmant, channels)) + return AVERROR(ENOMEM); + if (s->cpl_enabled) { - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->cpl_coord_exp, channels, sizeof(*block->cpl_coord_exp), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->cpl_coord_mant, channels, sizeof(*block->cpl_coord_mant), - alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(block->cpl_coord_exp, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->cpl_coord_mant, channels)) + return AVERROR(ENOMEM); } for (ch = 0; ch < channels; ch++) { @@ -2397,33 +2480,32 @@ static av_cold int allocate_buffers(AC3EncodeContext *s) } if (!s->fixed_point) { - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->fixed_coef_buffer, total_coefs, - sizeof(*s->fixed_coef_buffer), alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->fixed_coef_buffer, total_coefs)) + return AVERROR(ENOMEM); for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->fixed_coef, channels, - sizeof(*block->fixed_coef), alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(block->fixed_coef, channels)) + return AVERROR(ENOMEM); for (ch = 0; ch < channels; ch++) block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (s->num_blocks * ch + blk)]; } } else { for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->fixed_coef, channels, - sizeof(*block->fixed_coef), alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(block->fixed_coef, channels)) + return AVERROR(ENOMEM); for (ch = 0; ch < channels; ch++) block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch]; } } return 0; -alloc_fail: - return AVERROR(ENOMEM); } av_cold int ff_ac3_encode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; AC3EncodeContext *s = avctx->priv_data; int ret, frame_size_58; @@ -2433,7 +2515,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) ret = validate_options(s); if (ret) - goto init_fail; + return ret; avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks; avctx->initial_padding = AC3_BLOCK_SIZE; @@ -2453,34 +2535,24 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) s->crc_inv[1] = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY); } - /* set function pointers */ - if (CONFIG_AC3_FIXED_ENCODER && s->fixed_point) { - s->mdct_end = ff_ac3_fixed_mdct_end; - s->mdct_init = ff_ac3_fixed_mdct_init; - s->allocate_sample_buffers = ff_ac3_fixed_allocate_sample_buffers; - } else if (CONFIG_AC3_ENCODER || CONFIG_EAC3_ENCODER) { - s->mdct_end = ff_ac3_float_mdct_end; - s->mdct_init = ff_ac3_float_mdct_init; - s->allocate_sample_buffers = ff_ac3_float_allocate_sample_buffers; - } - if (CONFIG_EAC3_ENCODER && s->eac3) + if (CONFIG_EAC3_ENCODER && s->eac3) { + static AVOnce init_static_once_eac3 = AV_ONCE_INIT; + ff_thread_once(&init_static_once_eac3, ff_eac3_exponent_init); s->output_frame_header = ff_eac3_output_frame_header; - else + } else s->output_frame_header = ac3_output_frame_header; set_bandwidth(s); - exponent_init(s); - bit_alloc_init(s); ret = s->mdct_init(s); if (ret) - goto init_fail; + return ret; ret = allocate_buffers(s); if (ret) - goto init_fail; + return ret; ff_audiodsp_init(&s->adsp); ff_me_cmp_init(&s->mecc, avctx); @@ -2488,8 +2560,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) dprint_options(s); + ff_thread_once(&init_static_once, exponent_init); + return 0; -init_fail: - ff_ac3_encode_close(avctx); - return ret; } diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h index 1e4a7405b..c064ba4d6 100644 --- a/libavcodec/ac3enc.h +++ b/libavcodec/ac3enc.h @@ -30,8 +30,6 @@ #include -#include "libavutil/float_dsp.h" - #include "ac3.h" #include "ac3dsp.h" #include "avcodec.h" @@ -41,18 +39,12 @@ #include "put_bits.h" #include "audiodsp.h" -#ifndef CONFIG_AC3ENC_FLOAT -#define CONFIG_AC3ENC_FLOAT 0 +#ifndef AC3ENC_FLOAT +#define AC3ENC_FLOAT 0 #endif -#define OFFSET(param) offsetof(AC3EncodeContext, options.param) -#define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) - -#define AC3ENC_TYPE_AC3_FIXED 0 -#define AC3ENC_TYPE_AC3 1 -#define AC3ENC_TYPE_EAC3 2 - -#if CONFIG_AC3ENC_FLOAT +#if AC3ENC_FLOAT +#include "libavutil/float_dsp.h" #define AC3_NAME(x) ff_ac3_float_ ## x #define MAC_COEF(d,a,b) ((d)+=(a)*(b)) #define COEF_MIN (-16777215.0/16777216.0) @@ -62,12 +54,13 @@ typedef float SampleType; typedef float CoefType; typedef float CoefSumType; #else +#include "libavutil/fixed_dsp.h" #define AC3_NAME(x) ff_ac3_fixed_ ## x #define MAC_COEF(d,a,b) MAC64(d,a,b) #define COEF_MIN -16777215 #define COEF_MAX 16777215 #define NEW_CPL_COORD_THRESHOLD 503317 -typedef int16_t SampleType; +typedef int32_t SampleType; typedef int32_t CoefType; typedef int64_t CoefSumType; #endif @@ -141,7 +134,6 @@ typedef struct AC3Block { uint16_t **qmant; ///< quantized mantissas uint8_t **cpl_coord_exp; ///< coupling coord exponents (cplcoexp) uint8_t **cpl_coord_mant; ///< coupling coord mantissas (cplcomant) - uint8_t coeff_shift[AC3_MAX_CHANNELS]; ///< fixed-point coefficient shift values uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block int num_rematrixing_bands; ///< number of rematrixing bands uint8_t rematrixing_flags[4]; ///< rematrixing flags @@ -165,7 +157,11 @@ typedef struct AC3EncodeContext { AVCodecContext *avctx; ///< parent AVCodecContext PutBitContext pb; ///< bitstream writer context AudioDSPContext adsp; +#if AC3ENC_FLOAT AVFloatDSPContext *fdsp; +#else + AVFixedDSPContext *fdsp; +#endif MECmpContext mecc; AC3DSPContext ac3dsp; ///< AC-3 optimized functions FFTContext mdct; ///< FFT context for MDCT calculation @@ -270,6 +266,8 @@ typedef struct AC3EncodeContext { extern const uint64_t ff_ac3_channel_layouts[19]; +extern const AVOption ff_ac3_enc_options[]; +extern const AVCodecDefault ff_ac3_enc_defaults[]; int ff_ac3_encode_init(AVCodecContext *avctx); int ff_ac3_float_encode_init(AVCodecContext *avctx); @@ -282,33 +280,11 @@ void ff_ac3_adjust_frame_size(AC3EncodeContext *s); void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s); -void ff_ac3_apply_rematrixing(AC3EncodeContext *s); - -void ff_ac3_process_exponents(AC3EncodeContext *s); - -int ff_ac3_compute_bit_allocation(AC3EncodeContext *s); - -void ff_ac3_group_exponents(AC3EncodeContext *s); - -void ff_ac3_quantize_mantissas(AC3EncodeContext *s); - -void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame); - - -/* prototypes for functions in ac3enc_fixed.c and ac3enc_float.c */ - -void ff_ac3_fixed_mdct_end(AC3EncodeContext *s); -void ff_ac3_float_mdct_end(AC3EncodeContext *s); - -int ff_ac3_fixed_mdct_init(AC3EncodeContext *s); -int ff_ac3_float_mdct_init(AC3EncodeContext *s); - +int ff_ac3_encode_frame_common_end(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr); /* prototypes for functions in ac3enc_template.c */ -int ff_ac3_fixed_allocate_sample_buffers(AC3EncodeContext *s); -int ff_ac3_float_allocate_sample_buffers(AC3EncodeContext *s); - int ff_ac3_fixed_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr); int ff_ac3_float_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index e57d03529..8b1a062c6 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -26,54 +26,22 @@ * fixed-point AC-3 encoder. */ +#define AC3ENC_FLOAT 0 #define FFT_FLOAT 0 -#undef CONFIG_AC3ENC_FLOAT +#define FFT_FIXED_32 1 #include "internal.h" #include "audiodsp.h" #include "ac3enc.h" #include "eac3enc.h" - -#define AC3ENC_TYPE AC3ENC_TYPE_AC3_FIXED -#include "ac3enc_opts_template.c" +#include "kbdwin.h" static const AVClass ac3enc_class = { .class_name = "Fixed-Point AC-3 Encoder", .item_name = av_default_item_name, - .option = ac3_options, + .option = ff_ac3_enc_options, .version = LIBAVUTIL_VERSION_INT, }; -/* - * Normalize the input samples to use the maximum available precision. - * This assumes signed 16-bit input samples. - */ -static int normalize_samples(AC3EncodeContext *s) -{ - int v = s->ac3dsp.ac3_max_msb_abs_int16(s->windowed_samples, AC3_WINDOW_SIZE); - v = 14 - av_log2(v); - if (v > 0) - s->ac3dsp.ac3_lshift_int16(s->windowed_samples, AC3_WINDOW_SIZE, v); - /* +6 to right-shift from 31-bit to 25-bit */ - return v + 6; -} - - -/* - * Scale MDCT coefficients to 25-bit signed fixed-point. - */ -static void scale_coefficients(AC3EncodeContext *s) -{ - int blk, ch; - - for (blk = 0; blk < s->num_blocks; blk++) { - AC3Block *block = &s->blocks[blk]; - for (ch = 1; ch <= s->channels; ch++) { - s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS, - block->coeff_shift[ch]); - } - } -} - static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4], const int32_t *coef0, const int32_t *coef1, int len) @@ -115,23 +83,36 @@ static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) * * @param s AC-3 encoder private context */ -av_cold void ff_ac3_fixed_mdct_end(AC3EncodeContext *s) +static av_cold void ac3_fixed_mdct_end(AC3EncodeContext *s) { ff_mdct_end(&s->mdct); } - /** * Initialize MDCT tables. * * @param s AC-3 encoder private context * @return 0 on success, negative error code on failure */ -av_cold int ff_ac3_fixed_mdct_init(AC3EncodeContext *s) +static av_cold int ac3_fixed_mdct_init(AC3EncodeContext *s) { - int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0); - s->mdct_window = ff_ac3_window; - return ret; + float fwin[AC3_BLOCK_SIZE]; + + int32_t *iwin = av_malloc_array(AC3_BLOCK_SIZE, sizeof(*iwin)); + if (!iwin) + return AVERROR(ENOMEM); + + ff_kbd_window_init(fwin, 5.0, AC3_BLOCK_SIZE); + for (int i = 0; i < AC3_BLOCK_SIZE; i++) + iwin[i] = lrintf(fwin[i] * (1 << 22)); + + s->mdct_window = iwin; + + s->fdsp = avpriv_alloc_fixed_dsp(s->avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!s->fdsp) + return AVERROR(ENOMEM); + + return ff_mdct_init(&s->mdct, 9, 0, -1.0); } @@ -139,6 +120,9 @@ static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx) { AC3EncodeContext *s = avctx->priv_data; s->fixed_point = 1; + s->mdct_end = ac3_fixed_mdct_end; + s->mdct_init = ac3_fixed_mdct_init; + s->allocate_sample_buffers = allocate_sample_buffers; return ff_ac3_encode_init(avctx); } @@ -152,10 +136,11 @@ AVCodec ff_ac3_fixed_encoder = { .init = ac3_fixed_encode_init, .encode2 = ff_ac3_fixed_encode_frame, .close = ff_ac3_encode_close, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE }, .priv_class = &ac3enc_class, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .supported_samplerates = ff_ac3_sample_rate_tab, .channel_layouts = ff_ac3_channel_layouts, - .defaults = ac3_defaults, + .defaults = ff_ac3_enc_defaults, }; diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index 1f3111af0..223874907 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -26,7 +26,7 @@ * floating-point AC-3 encoder. */ -#define CONFIG_AC3ENC_FLOAT 1 +#define AC3ENC_FLOAT 1 #include "internal.h" #include "audiodsp.h" #include "ac3enc.h" @@ -34,12 +34,10 @@ #include "kbdwin.h" -#define AC3ENC_TYPE AC3ENC_TYPE_AC3 -#include "ac3enc_opts_template.c" static const AVClass ac3enc_class = { .class_name = "AC-3 Encoder", .item_name = av_default_item_name, - .option = ac3_options, + .option = ff_ac3_enc_options, .version = LIBAVUTIL_VERSION_INT, }; @@ -94,10 +92,9 @@ static void sum_square_butterfly(AC3EncodeContext *s, float sum[4], * * @param s AC-3 encoder private context */ -av_cold void ff_ac3_float_mdct_end(AC3EncodeContext *s) +static av_cold void ac3_float_mdct_end(AC3EncodeContext *s) { ff_mdct_end(&s->mdct); - av_freep(&s->mdct_window); } @@ -107,31 +104,27 @@ av_cold void ff_ac3_float_mdct_end(AC3EncodeContext *s) * @param s AC-3 encoder private context * @return 0 on success, negative error code on failure */ -av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s) +static av_cold int ac3_float_mdct_init(AC3EncodeContext *s) { - float *window; - int i, n, n2; - - n = 1 << 9; - n2 = n >> 1; - - window = av_malloc_array(n, sizeof(*window)); + float *window = av_malloc_array(AC3_BLOCK_SIZE, sizeof(*window)); if (!window) { av_log(s->avctx, AV_LOG_ERROR, "Cannot allocate memory.\n"); return AVERROR(ENOMEM); } - ff_kbd_window_init(window, 5.0, n2); - for (i = 0; i < n2; i++) - window[n-1-i] = window[i]; + + ff_kbd_window_init(window, 5.0, AC3_BLOCK_SIZE); s->mdct_window = window; - return ff_mdct_init(&s->mdct, 9, 0, -2.0 / n); + return ff_mdct_init(&s->mdct, 9, 0, -2.0 / AC3_WINDOW_SIZE); } av_cold int ff_ac3_float_encode_init(AVCodecContext *avctx) { AC3EncodeContext *s = avctx->priv_data; + s->mdct_end = ac3_float_mdct_end; + s->mdct_init = ac3_float_mdct_init; + s->allocate_sample_buffers = allocate_sample_buffers; s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); if (!s->fdsp) return AVERROR(ENOMEM); @@ -152,5 +145,6 @@ AVCodec ff_ac3_encoder = { .priv_class = &ac3enc_class, .supported_samplerates = ff_ac3_sample_rate_tab, .channel_layouts = ff_ac3_channel_layouts, - .defaults = ac3_defaults, + .defaults = ff_ac3_enc_defaults, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index be659872f..5ecef3b17 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -30,6 +30,7 @@ #include "libavutil/attributes.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "audiodsp.h" #include "internal.h" @@ -37,23 +38,20 @@ #include "eac3enc.h" -int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s) +static int allocate_sample_buffers(AC3EncodeContext *s) { int ch; - FF_ALLOC_OR_GOTO(s->avctx, s->windowed_samples, AC3_WINDOW_SIZE * - sizeof(*s->windowed_samples), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(s->avctx, s->planar_samples, s->channels, sizeof(*s->planar_samples), - alloc_fail); - for (ch = 0; ch < s->channels; ch++) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->planar_samples[ch], - (AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples), - alloc_fail); - } + if (!FF_ALLOC_TYPED_ARRAY(s->windowed_samples, AC3_WINDOW_SIZE) || + !FF_ALLOCZ_TYPED_ARRAY(s->planar_samples, s->channels)) + return AVERROR(ENOMEM); + for (ch = 0; ch < s->channels; ch++) { + if (!(s->planar_samples[ch] = av_mallocz((AC3_FRAME_SIZE + AC3_BLOCK_SIZE) * + sizeof(**s->planar_samples)))) + return AVERROR(ENOMEM); + } return 0; -alloc_fail: - return AVERROR(ENOMEM); } @@ -93,19 +91,14 @@ static void apply_mdct(AC3EncodeContext *s) AC3Block *block = &s->blocks[blk]; const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE]; -#if CONFIG_AC3ENC_FLOAT s->fdsp->vector_fmul(s->windowed_samples, input_samples, - s->mdct_window, AC3_WINDOW_SIZE); -#else - s->ac3dsp.apply_window_int16(s->windowed_samples, input_samples, - s->mdct_window, AC3_WINDOW_SIZE); + s->mdct_window, AC3_BLOCK_SIZE); + s->fdsp->vector_fmul_reverse(s->windowed_samples + AC3_BLOCK_SIZE, + &input_samples[AC3_BLOCK_SIZE], + s->mdct_window, AC3_BLOCK_SIZE); - if (s->fixed_point) - block->coeff_shift[ch+1] = normalize_samples(s); -#endif - - s->mdct.mdct_calcw(&s->mdct, block->mdct_coef[ch+1], - s->windowed_samples); + s->mdct.mdct_calc(&s->mdct, block->mdct_coef[ch+1], + s->windowed_samples); } } } @@ -117,7 +110,7 @@ static void apply_mdct(AC3EncodeContext *s) static void apply_channel_coupling(AC3EncodeContext *s) { LOCAL_ALIGNED_16(CoefType, cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); -#if CONFIG_AC3ENC_FLOAT +#if AC3ENC_FLOAT LOCAL_ALIGNED_16(int32_t, fixed_cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); #else int32_t (*fixed_cpl_coords)[AC3_MAX_CHANNELS][16] = cpl_coords; @@ -127,7 +120,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) int cpl_start, num_cpl_coefs; memset(cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords)); -#if CONFIG_AC3ENC_FLOAT +#if AC3ENC_FLOAT memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords)); #endif @@ -268,7 +261,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) if (!block->cpl_in_use) continue; -#if CONFIG_AC3ENC_FLOAT +#if AC3ENC_FLOAT s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1], cpl_coords[blk][1], s->fbw_channels * 16); @@ -314,7 +307,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) } } - if (CONFIG_EAC3_ENCODER && s->eac3) + if (AC3ENC_FLOAT && CONFIG_EAC3_ENCODER && s->eac3) ff_eac3_set_cpl_states(s); } @@ -386,19 +379,13 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt, return ret; } - if (s->bit_alloc.sr_code == 1 || s->eac3) + if (s->bit_alloc.sr_code == 1 || (AC3ENC_FLOAT && s->eac3)) ff_ac3_adjust_frame_size(s); copy_input_samples(s, (SampleType **)frame->extended_data); apply_mdct(s); - if (s->fixed_point) - scale_coefficients(s); - - clip_coefficients(&s->adsp, s->blocks[0].mdct_coef[1], - AC3_MAX_COEFS * s->num_blocks * s->channels); - s->cpl_on = s->cpl_enabled; ff_ac3_compute_coupling_strategy(s); @@ -407,30 +394,9 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt, compute_rematrixing_strategy(s); - if (!s->fixed_point) - scale_coefficients(s); +#if AC3ENC_FLOAT + scale_coefficients(s); +#endif - ff_ac3_apply_rematrixing(s); - - ff_ac3_process_exponents(s); - - ret = ff_ac3_compute_bit_allocation(s); - if (ret) { - av_log(avctx, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n"); - return ret; - } - - ff_ac3_group_exponents(s); - - ff_ac3_quantize_mantissas(s); - - if ((ret = ff_alloc_packet2(avctx, avpkt, s->frame_size, 0)) < 0) - return ret; - ff_ac3_output_frame(s, avpkt->data); - - if (frame->pts != AV_NOPTS_VALUE) - avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding); - - *got_packet_ptr = 1; - return 0; + return ff_ac3_encode_frame_common_end(avctx, avpkt, frame, got_packet_ptr); } diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c index ef2a41bc5..e53086a75 100644 --- a/libavcodec/ac3tab.c +++ b/libavcodec/ac3tab.c @@ -25,7 +25,7 @@ */ #include "libavutil/channel_layout.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "ac3tab.h" @@ -97,24 +97,6 @@ const uint16_t avpriv_ac3_channel_layout_tab[8] = { AV_CH_LAYOUT_5POINT0 }; -#define COMMON_CHANNEL_MAP \ - { { 0, 1, }, { 0, 1, 2, } },\ - { { 0, }, { 0, 1, } },\ - { { 0, 1, }, { 0, 1, 2, } },\ - { { 0, 2, 1, }, { 0, 2, 1, 3, } },\ - { { 0, 1, 2, }, { 0, 1, 3, 2, } },\ - { { 0, 2, 1, 3, }, { 0, 2, 1, 4, 3, } }, - -/** - * Table to remap channels from SMPTE order to AC-3 order. - * [channel_mode][lfe][ch] - */ -const uint8_t ff_ac3_enc_channel_map[8][2][6] = { - COMMON_CHANNEL_MAP - { { 0, 1, 2, 3, }, { 0, 1, 3, 4, 2, } }, - { { 0, 2, 1, 3, 4, }, { 0, 2, 1, 4, 5, 3 } }, -}; - /** * Table to remap channels from AC-3 order to SMPTE order. * [channel_mode][lfe][ch] @@ -147,44 +129,6 @@ const uint8_t ff_eac3_default_cpl_band_struct[18] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 }; -/* AC-3 MDCT window */ - -/* MDCT window */ -DECLARE_ALIGNED(16, const int16_t, ff_ac3_window)[AC3_WINDOW_SIZE/2] = { - 4, 7, 12, 16, 21, 28, 34, 42, - 51, 61, 72, 84, 97, 111, 127, 145, - 164, 184, 207, 231, 257, 285, 315, 347, - 382, 419, 458, 500, 544, 591, 641, 694, - 750, 810, 872, 937, 1007, 1079, 1155, 1235, - 1318, 1406, 1497, 1593, 1692, 1796, 1903, 2016, - 2132, 2253, 2379, 2509, 2644, 2783, 2927, 3076, - 3230, 3389, 3552, 3721, 3894, 4072, 4255, 4444, - 4637, 4835, 5038, 5246, 5459, 5677, 5899, 6127, - 6359, 6596, 6837, 7083, 7334, 7589, 7848, 8112, - 8380, 8652, 8927, 9207, 9491, 9778,10069,10363, -10660,10960,11264,11570,11879,12190,12504,12820, -13138,13458,13780,14103,14427,14753,15079,15407, -15735,16063,16392,16720,17049,17377,17705,18032, -18358,18683,19007,19330,19651,19970,20287,20602, -20914,21225,21532,21837,22139,22438,22733,23025, -23314,23599,23880,24157,24430,24699,24964,25225, -25481,25732,25979,26221,26459,26691,26919,27142, -27359,27572,27780,27983,28180,28373,28560,28742, -28919,29091,29258,29420,29577,29729,29876,30018, -30155,30288,30415,30538,30657,30771,30880,30985, -31086,31182,31274,31363,31447,31528,31605,31678, -31747,31814,31877,31936,31993,32046,32097,32145, -32190,32232,32272,32310,32345,32378,32409,32438, -32465,32490,32513,32535,32556,32574,32592,32608, -32623,32636,32649,32661,32671,32681,32690,32698, -32705,32712,32718,32724,32729,32733,32737,32741, -32744,32747,32750,32752,32754,32756,32757,32759, -32760,32761,32762,32763,32764,32764,32765,32765, -32766,32766,32766,32766,32767,32767,32767,32767, -32767,32767,32767,32767,32767,32767,32767,32767, -32767,32767,32767,32767,32767,32767,32767,32767, -}; - const uint8_t ff_ac3_log_add_tab[260]= { 0x40,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37, 0x36,0x35,0x34,0x34,0x33,0x32,0x31,0x30,0x2f,0x2f, @@ -301,19 +245,6 @@ const uint16_t ff_ac3_fast_gain_tab[8]= { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400, }; -/** - * Default channel map for a dependent substream defined by acmod - */ -const uint16_t ff_eac3_default_chmap[8] = { - AC3_CHMAP_L | AC3_CHMAP_R, // FIXME Ch1+Ch2 - AC3_CHMAP_C, - AC3_CHMAP_L | AC3_CHMAP_R, - AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R, - AC3_CHMAP_L | AC3_CHMAP_R | AC3_CHMAP_C_SUR, - AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R | AC3_CHMAP_C_SUR, - AC3_CHMAP_L | AC3_CHMAP_R | AC3_CHMAP_L_SUR | AC3_CHMAP_R_SUR, - AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R | AC3_CHMAP_L_SUR | AC3_CHMAP_R_SUR -}; const uint64_t ff_eac3_custom_channel_map_locations[16][2] = { { 1, AV_CH_FRONT_LEFT }, { 1, AV_CH_FRONT_CENTER }, diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h index 1d1264e3f..ea8e3340c 100644 --- a/libavcodec/ac3tab.h +++ b/libavcodec/ac3tab.h @@ -31,13 +31,11 @@ extern const uint16_t ff_ac3_frame_size_tab[38][3]; extern const uint8_t ff_ac3_channels_tab[8]; extern av_export_avcodec const uint16_t avpriv_ac3_channel_layout_tab[8]; -extern const uint8_t ff_ac3_enc_channel_map[8][2][6]; extern const uint8_t ff_ac3_dec_channel_map[8][2][6]; extern const int ff_ac3_sample_rate_tab[]; extern const uint16_t ff_ac3_bitrate_tab[19]; extern const uint8_t ff_ac3_rematrix_band_tab[5]; extern const uint8_t ff_eac3_default_cpl_band_struct[18]; -extern const int16_t ff_ac3_window[AC3_WINDOW_SIZE/2]; extern const uint8_t ff_ac3_log_add_tab[260]; extern const uint16_t ff_ac3_hearing_threshold_tab[AC3_CRITICAL_BANDS][3]; extern const uint8_t ff_ac3_bap_tab[64]; @@ -47,7 +45,6 @@ extern const uint16_t ff_ac3_slow_gain_tab[4]; extern const uint16_t ff_ac3_db_per_bit_tab[4]; extern const int16_t ff_ac3_floor_tab[8]; extern const uint16_t ff_ac3_fast_gain_tab[8]; -extern const uint16_t ff_eac3_default_chmap[8]; extern const uint8_t ff_ac3_band_start_tab[AC3_CRITICAL_BANDS+1]; extern const uint8_t ff_ac3_bin_to_band_tab[253]; extern const uint64_t ff_eac3_custom_channel_map_locations[16][2]; @@ -68,4 +65,12 @@ enum CustomChannelMapLocation{ AC3_CHMAP_LFE = 1<<(15-15) }; +#define COMMON_CHANNEL_MAP \ + { { 0, 1, }, { 0, 1, 2, } },\ + { { 0, }, { 0, 1, } },\ + { { 0, 1, }, { 0, 1, 2, } },\ + { { 0, 2, 1, }, { 0, 2, 1, 3, } },\ + { { 0, 1, 2, }, { 0, 1, 3, 2, } },\ + { { 0, 2, 1, 3, }, { 0, 2, 1, 4, 3, } }, + #endif /* AVCODEC_AC3TAB_H */ diff --git a/libavcodec/acelp_pitch_delay.c b/libavcodec/acelp_pitch_delay.c index a070d1b25..1eca97ec6 100644 --- a/libavcodec/acelp_pitch_delay.c +++ b/libavcodec/acelp_pitch_delay.c @@ -29,47 +29,6 @@ #include "celp_math.h" #include "audiodsp.h" -int ff_acelp_decode_8bit_to_1st_delay3(int ac_index) -{ - ac_index += 58; - if(ac_index > 254) - ac_index = 3 * ac_index - 510; - return ac_index; -} - -int ff_acelp_decode_4bit_to_2nd_delay3( - int ac_index, - int pitch_delay_min) -{ - if(ac_index < 4) - return 3 * (ac_index + pitch_delay_min); - else if(ac_index < 12) - return 3 * pitch_delay_min + ac_index + 6; - else - return 3 * (ac_index + pitch_delay_min) - 18; -} - -int ff_acelp_decode_5_6_bit_to_2nd_delay3( - int ac_index, - int pitch_delay_min) -{ - return 3 * pitch_delay_min + ac_index - 2; -} - -int ff_acelp_decode_9bit_to_1st_delay6(int ac_index) -{ - if(ac_index < 463) - return ac_index + 105; - else - return 6 * (ac_index - 368); -} -int ff_acelp_decode_6bit_to_2nd_delay6( - int ac_index, - int pitch_delay_min) -{ - return 6 * pitch_delay_min + ac_index - 3; -} - void ff_acelp_update_past_gain( int16_t* quant_energy, int gain_corr_factor, diff --git a/libavcodec/acelp_pitch_delay.h b/libavcodec/acelp_pitch_delay.h index 2aade2f22..73fa3c331 100644 --- a/libavcodec/acelp_pitch_delay.h +++ b/libavcodec/acelp_pitch_delay.h @@ -41,7 +41,13 @@ * with 1/3 resolution, 19 < pitch_delay < 85 * integers only, 85 <= pitch_delay <= 143 */ -int ff_acelp_decode_8bit_to_1st_delay3(int ac_index); +static inline int ff_acelp_decode_8bit_to_1st_delay3(int ac_index) +{ + ac_index += 58; + if (ac_index > 254) + ac_index = 3 * ac_index - 510; + return ac_index; +} /** * @brief Decode pitch delay of the second subframe encoded by 5 or 6 bits @@ -58,9 +64,11 @@ int ff_acelp_decode_8bit_to_1st_delay3(int ac_index); * @remark The routine is used in G.729 @@8k, AMR @@10.2k, AMR @@7.95k, * AMR @@7.4k for the second subframe. */ -int ff_acelp_decode_5_6_bit_to_2nd_delay3( - int ac_index, - int pitch_delay_min); +static inline int ff_acelp_decode_5_6_bit_to_2nd_delay3(int ac_index, + int pitch_delay_min) +{ + return 3 * pitch_delay_min + ac_index - 2; +} /** * @brief Decode pitch delay with 1/3 precision. @@ -78,9 +86,16 @@ int ff_acelp_decode_5_6_bit_to_2nd_delay3( * @remark The routine is used in G.729 @@6.4k, AMR @@6.7k, AMR @@5.9k, * AMR @@5.15k, AMR @@4.75k for the second subframe. */ -int ff_acelp_decode_4bit_to_2nd_delay3( - int ac_index, - int pitch_delay_min); +static inline int ff_acelp_decode_4bit_to_2nd_delay3(int ac_index, + int pitch_delay_min) +{ + if (ac_index < 4) + return 3 * (ac_index + pitch_delay_min); + else if (ac_index < 12) + return 3 * pitch_delay_min + ac_index + 6; + else + return 3 * (ac_index + pitch_delay_min) - 18; +} /** * @brief Decode pitch delay of the first subframe encoded by 9 bits @@ -95,7 +110,13 @@ int ff_acelp_decode_4bit_to_2nd_delay3( * * @remark The routine is used in AMR @@12.2k for the first and third subframes. */ -int ff_acelp_decode_9bit_to_1st_delay6(int ac_index); +static inline int ff_acelp_decode_9bit_to_1st_delay6(int ac_index) +{ + if (ac_index < 463) + return ac_index + 105; + else + return 6 * (ac_index - 368); +} /** * @brief Decode pitch delay of the second subframe encoded by 6 bits @@ -111,9 +132,11 @@ int ff_acelp_decode_9bit_to_1st_delay6(int ac_index); * * @remark The routine is used in AMR @@12.2k for the second and fourth subframes. */ -int ff_acelp_decode_6bit_to_2nd_delay6( - int ac_index, - int pitch_delay_min); +static inline int ff_acelp_decode_6bit_to_2nd_delay6(int ac_index, + int pitch_delay_min) +{ + return 6 * pitch_delay_min + ac_index - 3; +} /** * @brief Update past quantized energies diff --git a/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c index 798217d73..0d4de0e4c 100644 --- a/libavcodec/acelp_vectors.c +++ b/libavcodec/acelp_vectors.c @@ -28,17 +28,6 @@ #include "avcodec.h" #include "acelp_vectors.h" -const uint8_t ff_fc_2pulses_9bits_track1[16] = -{ - 1, 3, - 6, 8, - 11, 13, - 16, 18, - 21, 23, - 26, 28, - 31, 33, - 36, 38 -}; const uint8_t ff_fc_2pulses_9bits_track1_gray[16] = { 1, 3, diff --git a/libavcodec/acelp_vectors.h b/libavcodec/acelp_vectors.h index fae834dac..c2587c5f6 100644 --- a/libavcodec/acelp_vectors.h +++ b/libavcodec/acelp_vectors.h @@ -102,7 +102,6 @@ extern const uint8_t ff_fc_4pulses_8bits_track_4[32]; * * Used in G.729 @@6.4k (with gray coding), AMR @@5.9k (without gray coding) */ -extern const uint8_t ff_fc_2pulses_9bits_track1[16]; extern const uint8_t ff_fc_2pulses_9bits_track1_gray[16]; /** diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 79c5d625d..8aab07e33 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -100,7 +100,7 @@ static const int8_t mtf_index_table[16] = { typedef struct ADPCMDecodeContext { ADPCMChannelStatus status[14]; int vqa_version; /**< VQA version. Used for ADPCM_IMA_WS */ - int has_status; + int has_status; /**< Status flag. Reset to 0 after a flush. */ } ADPCMDecodeContext; static av_cold int adpcm_decode_init(AVCodecContext * avctx) @@ -110,7 +110,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) unsigned int max_channels = 2; switch(avctx->codec->id) { - case AV_CODEC_ID_ADPCM_IMA_CUNNING: + case AV_CODEC_ID_ADPCM_IMA_AMV: max_channels = 1; break; case AV_CODEC_ID_ADPCM_DTK: @@ -129,12 +129,14 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) min_channels = 2; max_channels = 8; if (avctx->channels & 1) { - avpriv_request_sample(avctx, "channel count %d\n", avctx->channels); + avpriv_request_sample(avctx, "channel count %d", avctx->channels); return AVERROR_PATCHWELCOME; } break; case AV_CODEC_ID_ADPCM_PSX: max_channels = 8; + if (avctx->channels <= 0 || avctx->block_align % (16 * avctx->channels)) + return AVERROR_INVALIDDATA; break; case AV_CODEC_ID_ADPCM_IMA_DAT4: case AV_CODEC_ID_ADPCM_THP: @@ -162,11 +164,18 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) } break; case AV_CODEC_ID_ADPCM_IMA_APM: - if (avctx->extradata && avctx->extradata_size >= 16) { - c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 0), 18); - c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 4), 0, 88); - c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 8), 18); - c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 12), 0, 88); + if (avctx->extradata) { + if (avctx->extradata_size >= 28) { + c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 16), 18); + c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 20), 0, 88); + c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 4), 18); + c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 8), 0, 88); + } else if (avctx->extradata_size >= 16) { + c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 0), 18); + c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 4), 0, 88); + c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 8), 18); + c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 12), 0, 88); + } } break; case AV_CODEC_ID_ADPCM_IMA_WS: @@ -174,7 +183,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) c->vqa_version = AV_RL16(avctx->extradata); break; case AV_CODEC_ID_ADPCM_ARGO: - if (avctx->bits_per_coded_sample != 4) + if (avctx->bits_per_coded_sample != 4 || avctx->block_align != 17 * avctx->channels) return AVERROR_INVALIDDATA; break; case AV_CODEC_ID_ADPCM_ZORK: @@ -187,6 +196,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) switch (avctx->codec->id) { case AV_CODEC_ID_ADPCM_AICA: + case AV_CODEC_ID_ADPCM_IMA_CUNNING: case AV_CODEC_ID_ADPCM_IMA_DAT4: case AV_CODEC_ID_ADPCM_IMA_QT: case AV_CODEC_ID_ADPCM_IMA_WAV: @@ -203,6 +213,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_PSX: case AV_CODEC_ID_ADPCM_MTAF: case AV_CODEC_ID_ADPCM_ARGO: + case AV_CODEC_ID_ADPCM_IMA_MOFLEX: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; case AV_CODEC_ID_ADPCM_IMA_WS: @@ -682,11 +693,11 @@ static void adpcm_swf_decode(AVCodecContext *avctx, const uint8_t *buf, int buf_ } } -static inline int16_t adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int control, int shift) +int16_t ff_adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int shift, int flag) { - int sample = nibble * (1 << shift); + int sample = sign_extend(nibble, 4) * (1 << shift); - if (control & 0x04) + if (flag) sample += (8 * cs->sample1) - (4 * cs->sample2); else sample += 4 * cs->sample1; @@ -737,11 +748,6 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, return 0; nb_samples = 64; break; - case AV_CODEC_ID_ADPCM_ARGO: - if (buf_size < 17 * ch) - return 0; - nb_samples = 32; - break; /* simple 4-bit adpcm */ case AV_CODEC_ID_ADPCM_CT: case AV_CODEC_ID_ADPCM_IMA_APC: @@ -767,8 +773,8 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_4XM: case AV_CODEC_ID_ADPCM_AGM: case AV_CODEC_ID_ADPCM_IMA_DAT4: + case AV_CODEC_ID_ADPCM_IMA_MOFLEX: case AV_CODEC_ID_ADPCM_IMA_ISS: header_size = 4 * ch; break; - case AV_CODEC_ID_ADPCM_IMA_AMV: header_size = 8; break; case AV_CODEC_ID_ADPCM_IMA_SMJPEG: header_size = 4 * ch; break; } if (header_size > 0) @@ -776,6 +782,13 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, /* more complex formats */ switch (avctx->codec->id) { + case AV_CODEC_ID_ADPCM_IMA_AMV: + bytestream2_skip(gb, 4); + has_coded_samples = 1; + *coded_samples = bytestream2_get_le32u(gb); + nb_samples = FFMIN((buf_size - 8) * 2, *coded_samples); + bytestream2_seek(gb, -8, SEEK_CUR); + break; case AV_CODEC_ID_ADPCM_EA: has_coded_samples = 1; *coded_samples = bytestream2_get_le32(gb); @@ -913,6 +926,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_PSX: nb_samples = buf_size / (16 * ch) * 28; break; + case AV_CODEC_ID_ADPCM_ARGO: + nb_samples = buf_size / avctx->block_align * 32; + break; case AV_CODEC_ID_ADPCM_ZORK: nb_samples = buf_size / ch; break; @@ -1291,6 +1307,29 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, *samples++ = adpcm_ima_expand_nibble(&c->status[st], v2, 3); } break; + case AV_CODEC_ID_ADPCM_IMA_MOFLEX: + 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 (int subframe = 0; subframe < nb_samples / 256; subframe++) { + for (channel = 0; channel < avctx->channels; channel++) { + samples = samples_p[channel] + 256 * subframe; + for (n = 0; n < 256; n += 2) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); + } + } + } + break; case AV_CODEC_ID_ADPCM_IMA_DAT4: for (channel = 0; channel < avctx->channels; channel++) { cs = &c->status[channel]; @@ -1338,10 +1377,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_CODEC_ID_ADPCM_IMA_CUNNING: - for (n = 0; n < nb_samples / 2; n++) { - int v = bytestream2_get_byteu(&gb); - *samples++ = adpcm_ima_cunning_expand_nibble(&c->status[0], v & 0x0F); - *samples++ = adpcm_ima_cunning_expand_nibble(&c->status[0], v >> 4); + for (channel = 0; channel < avctx->channels; channel++) { + int16_t *smp = samples_p[channel]; + for (n = 0; n < nb_samples / 2; n++) { + int v = bytestream2_get_byteu(&gb); + *smp++ = adpcm_ima_cunning_expand_nibble(&c->status[channel], v & 0x0F); + *smp++ = adpcm_ima_cunning_expand_nibble(&c->status[channel], v >> 4); + } } break; case AV_CODEC_ID_ADPCM_IMA_OKI: @@ -1649,6 +1691,18 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_CODEC_ID_ADPCM_IMA_AMV: + av_assert0(avctx->channels == 1); + + /* + * Header format: + * int16_t predictor; + * uint8_t step_index; + * uint8_t reserved; + * uint32_t frame_size; + * + * Some implementations have step_index as 16-bits, but others + * only use the lower 8 and store garbage in the upper 8. + */ c->status[0].predictor = sign_extend(bytestream2_get_le16u(&gb), 16); c->status[0].step_index = bytestream2_get_byteu(&gb); bytestream2_skipu(&gb, 5); @@ -1658,12 +1712,23 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - for (n = nb_samples >> (1 - st); n > 0; n--) { + for (n = nb_samples >> 1; n > 0; n--) { int v = bytestream2_get_byteu(&gb); *samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4, 3); *samples++ = adpcm_ima_expand_nibble(&c->status[0], v & 0xf, 3); } + + if (nb_samples & 1) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4, 3); + + if (v & 0x0F) { + /* Holds true on all the http://samples.mplayerhq.hu/amv samples. */ + av_log(avctx, AV_LOG_WARNING, "Last nibble set on packet with odd sample count.\n"); + av_log(avctx, AV_LOG_WARNING, "Sample will be skipped.\n"); + } + } break; case AV_CODEC_ID_ADPCM_IMA_SMJPEG: for (i = 0; i < avctx->channels; i++) { @@ -1746,11 +1811,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_CODEC_ID_ADPCM_AICA: - if (!c->has_status) { - for (channel = 0; channel < avctx->channels; channel++) - c->status[channel].step = 0; - c->has_status = 1; - } for (channel = 0; channel < avctx->channels; channel++) { samples = samples_p[channel]; for (n = nb_samples >> 1; n > 0; n--) { @@ -1934,38 +1994,42 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_CODEC_ID_ADPCM_PSX: - for (channel = 0; channel < avctx->channels; channel++) { - samples = samples_p[channel]; + for (int block = 0; block < avpkt->size / FFMAX(avctx->block_align, 16 * avctx->channels); block++) { + int nb_samples_per_block = 28 * FFMAX(avctx->block_align, 16 * avctx->channels) / (16 * avctx->channels); + for (channel = 0; channel < avctx->channels; channel++) { + samples = samples_p[channel] + block * nb_samples_per_block; + av_assert0((block + 1) * nb_samples_per_block <= nb_samples); - /* Read in every sample for this channel. */ - for (i = 0; i < nb_samples / 28; i++) { - int filter, shift, flag, byte; + /* Read in every sample for this channel. */ + for (i = 0; i < nb_samples_per_block / 28; i++) { + int filter, shift, flag, byte; - filter = bytestream2_get_byteu(&gb); - shift = filter & 0xf; - filter = filter >> 4; - if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) - return AVERROR_INVALIDDATA; - flag = bytestream2_get_byteu(&gb); + filter = bytestream2_get_byteu(&gb); + shift = filter & 0xf; + filter = filter >> 4; + if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) + return AVERROR_INVALIDDATA; + flag = bytestream2_get_byteu(&gb); - /* Decode 28 samples. */ - for (n = 0; n < 28; n++) { - int sample = 0, scale; + /* Decode 28 samples. */ + for (n = 0; n < 28; n++) { + int sample = 0, scale; - if (flag < 0x07) { - if (n & 1) { - scale = sign_extend(byte >> 4, 4); - } else { - byte = bytestream2_get_byteu(&gb); - scale = sign_extend(byte, 4); + if (flag < 0x07) { + if (n & 1) { + scale = sign_extend(byte >> 4, 4); + } else { + byte = bytestream2_get_byteu(&gb); + scale = sign_extend(byte, 4); + } + + scale = scale * (1 << 12); + sample = (int)((scale >> shift) + (c->status[channel].sample1 * xa_adpcm_table[filter][0] + c->status[channel].sample2 * xa_adpcm_table[filter][1]) / 64); } - - scale = scale * (1 << 12); - sample = (int)((scale >> shift) + (c->status[channel].sample1 * xa_adpcm_table[filter][0] + c->status[channel].sample2 * xa_adpcm_table[filter][1]) / 64); + *samples++ = av_clip_int16(sample); + c->status[channel].sample2 = c->status[channel].sample1; + c->status[channel].sample1 = sample; } - *samples++ = av_clip_int16(sample); - c->status[channel].sample2 = c->status[channel].sample1; - c->status[channel].sample1 = sample; } } } @@ -1980,7 +2044,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, * uint4_t right_samples[nb_samples]; * * Format of the control byte: - * MSB [SSSSDRRR] LSB + * MSB [SSSSRDRR] LSB * S = (Shift Amount - 2) * D = Decoder flag. * R = Reserved @@ -1988,31 +2052,26 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, * Each block relies on the previous two samples of each channel. * They should be 0 initially. */ - for (channel = 0; channel < avctx->channels; channel++) { - int control, shift; + for (int block = 0; block < avpkt->size / avctx->block_align; block++) { + for (channel = 0; channel < avctx->channels; channel++) { + int control, shift; - samples = samples_p[channel]; - cs = c->status + channel; + samples = samples_p[channel] + block * 32; + cs = c->status + channel; - /* Get the control byte and decode the samples, 2 at a time. */ - control = bytestream2_get_byteu(&gb); - shift = (control >> 4) + 2; + /* Get the control byte and decode the samples, 2 at a time. */ + control = bytestream2_get_byteu(&gb); + shift = (control >> 4) + 2; - for (n = 0; n < nb_samples / 2; n++) { - int sample = bytestream2_get_byteu(&gb); - *samples++ = adpcm_argo_expand_nibble(cs, sign_extend(sample >> 4, 4), control, shift); - *samples++ = adpcm_argo_expand_nibble(cs, sign_extend(sample >> 0, 4), control, shift); + for (n = 0; n < 16; n++) { + int sample = bytestream2_get_byteu(&gb); + *samples++ = ff_adpcm_argo_expand_nibble(cs, sample >> 4, shift, control & 0x04); + *samples++ = ff_adpcm_argo_expand_nibble(cs, sample >> 0, shift, control & 0x04); + } } } break; case AV_CODEC_ID_ADPCM_ZORK: - if (!c->has_status) { - for (channel = 0; channel < avctx->channels; channel++) { - c->status[channel].predictor = 0; - c->status[channel].step_index = 0; - } - c->has_status = 1; - } for (n = 0; n < nb_samples * avctx->channels; n++) { int v = bytestream2_get_byteu(&gb); *samples++ = adpcm_zork_expand_nibble(&c->status[n % avctx->channels], v); @@ -2050,7 +2109,37 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, static void adpcm_flush(AVCodecContext *avctx) { ADPCMDecodeContext *c = avctx->priv_data; - c->has_status = 0; + + switch(avctx->codec_id) { + case AV_CODEC_ID_ADPCM_AICA: + for (int channel = 0; channel < avctx->channels; channel++) + c->status[channel].step = 0; + break; + + case AV_CODEC_ID_ADPCM_ARGO: + for (int channel = 0; channel < avctx->channels; channel++) { + c->status[channel].sample1 = 0; + c->status[channel].sample2 = 0; + } + break; + + case AV_CODEC_ID_ADPCM_IMA_ALP: + case AV_CODEC_ID_ADPCM_IMA_CUNNING: + case AV_CODEC_ID_ADPCM_IMA_SSI: + case AV_CODEC_ID_ADPCM_ZORK: + for (int channel = 0; channel < avctx->channels; channel++) { + c->status[channel].predictor = 0; + c->status[channel].step_index = 0; + } + break; + + default: + /* Other codecs may want to handle this during decoding. */ + c->has_status = 0; + return; + } + + c->has_status = 1; } @@ -2074,6 +2163,7 @@ AVCodec ff_ ## name_ ## _decoder = { \ .flush = adpcm_flush, \ .capabilities = AV_CODEC_CAP_DR1, \ .sample_fmts = sample_fmts_, \ + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \ } /* Note: Do not forget to add new entries to the Makefile as well. */ @@ -2093,13 +2183,14 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_XAS, sample_fmts_s16p, adpcm_ea_xas, ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_AMV, sample_fmts_s16, adpcm_ima_amv, "ADPCM IMA AMV"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_APC, sample_fmts_s16, adpcm_ima_apc, "ADPCM IMA CRYO APC"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_APM, sample_fmts_s16, adpcm_ima_apm, "ADPCM IMA Ubisoft APM"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_CUNNING, sample_fmts_s16, adpcm_ima_cunning, "ADPCM IMA Cunning Developments"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_CUNNING, sample_fmts_s16p, adpcm_ima_cunning, "ADPCM IMA Cunning Developments"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DAT4, sample_fmts_s16, adpcm_ima_dat4, "ADPCM IMA Eurocom DAT4"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DK3, sample_fmts_s16, adpcm_ima_dk3, "ADPCM IMA Duck DK3"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DK4, sample_fmts_s16, adpcm_ima_dk4, "ADPCM IMA Duck DK4"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_EACS, sample_fmts_s16, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_SEAD, sample_fmts_s16, adpcm_ima_ea_sead, "ADPCM IMA Electronic Arts 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_MOFLEX, sample_fmts_s16p, adpcm_ima_moflex, "ADPCM IMA MobiClip MOFLEX"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_MTF, sample_fmts_s16, adpcm_ima_mtf, "ADPCM IMA Capcom's MT Framework"); 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"); diff --git a/libavcodec/adpcm.h b/libavcodec/adpcm.h index 580db7df8..0ffc3da1d 100644 --- a/libavcodec/adpcm.h +++ b/libavcodec/adpcm.h @@ -28,8 +28,6 @@ #include -#define BLKSIZE 1024 - typedef struct ADPCMChannelStatus { int predictor; int16_t step_index; @@ -45,4 +43,6 @@ typedef struct ADPCMChannelStatus { int idelta; } ADPCMChannelStatus; +int16_t ff_adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int shift, int flag); + #endif /* AVCODEC_ADPCM_H */ diff --git a/libavcodec/adpcm_data.c b/libavcodec/adpcm_data.c index e34e04d5e..768a18a37 100644 --- a/libavcodec/adpcm_data.c +++ b/libavcodec/adpcm_data.c @@ -178,10 +178,22 @@ const int16_t ff_adpcm_mtaf_stepsize[32][16] = { -424, -1273, -2121, -2970, -3819, -4668, -5516, -6365, }, }; +/* + * Dumped from the binaries: + * - FantasticJourney.exe - 0x794D2, DGROUP:0x47A4D2 + * - BigRaceUSA.exe - 0x9B8AA, DGROUP:0x49C4AA + * - Timeshock!.exe - 0x8506A, DGROUP:0x485C6A + */ const int8_t ff_adpcm_ima_cunning_index_table[9] = { -1, -1, -1, -1, 1, 2, 3, 4, -1 }; +/* + * Dumped from the binaries: + * - FantasticJourney.exe - 0x79458, DGROUP:0x47A458 + * - BigRaceUSA.exe - 0x9B830, DGROUP:0x49C430 + * - Timeshock!.exe - 0x84FF0, DGROUP:0x485BF0 + */ const int16_t ff_adpcm_ima_cunning_step_table[61] = { 1, 1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index d5fbc0b9a..58308dae4 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -22,6 +22,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/opt.h" + #include "avcodec.h" #include "put_bits.h" #include "bytestream.h" @@ -49,6 +51,9 @@ typedef struct TrellisNode { } TrellisNode; typedef struct ADPCMEncodeContext { + AVClass *class; + int block_size; + ADPCMChannelStatus status[6]; TrellisPath *paths; TrellisNode *node_buf; @@ -58,45 +63,53 @@ typedef struct ADPCMEncodeContext { #define FREEZE_INTERVAL 128 -static av_cold int adpcm_encode_close(AVCodecContext *avctx); - static av_cold int adpcm_encode_init(AVCodecContext *avctx) { ADPCMEncodeContext *s = avctx->priv_data; uint8_t *extradata; int i; - int ret = AVERROR(ENOMEM); if (avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "only stereo or mono is supported\n"); return AVERROR(EINVAL); } - if (avctx->trellis && (unsigned)avctx->trellis > 16U) { - av_log(avctx, AV_LOG_ERROR, "invalid trellis size\n"); + /* + * AMV's block size has to match that of the corresponding video + * stream. Relax the POT requirement. + */ + if (avctx->codec->id != AV_CODEC_ID_ADPCM_IMA_AMV && + (s->block_size & (s->block_size - 1))) { + av_log(avctx, AV_LOG_ERROR, "block size must be power of 2\n"); return AVERROR(EINVAL); } - if (avctx->trellis && avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_SSI) { - /* - * The current trellis implementation doesn't work for extended - * runs of samples without periodic resets. Disallow it. - */ - av_log(avctx, AV_LOG_ERROR, "trellis not supported\n"); - return AVERROR_PATCHWELCOME; - } - if (avctx->trellis) { - int frontier = 1 << avctx->trellis; - int max_paths = frontier * FREEZE_INTERVAL; - FF_ALLOC_OR_GOTO(avctx, s->paths, - max_paths * sizeof(*s->paths), error); - FF_ALLOC_OR_GOTO(avctx, s->node_buf, - 2 * frontier * sizeof(*s->node_buf), error); - FF_ALLOC_OR_GOTO(avctx, s->nodep_buf, - 2 * frontier * sizeof(*s->nodep_buf), error); - FF_ALLOC_OR_GOTO(avctx, s->trellis_hash, - 65536 * sizeof(*s->trellis_hash), error); + int frontier, max_paths; + + if ((unsigned)avctx->trellis > 16U) { + av_log(avctx, AV_LOG_ERROR, "invalid trellis size\n"); + return AVERROR(EINVAL); + } + + if (avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_SSI || + avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_APM || + avctx->codec->id == AV_CODEC_ID_ADPCM_ARGO) { + /* + * The current trellis implementation doesn't work for extended + * runs of samples without periodic resets. Disallow it. + */ + av_log(avctx, AV_LOG_ERROR, "trellis not supported\n"); + return AVERROR_PATCHWELCOME; + } + + frontier = 1 << avctx->trellis; + max_paths = frontier * FREEZE_INTERVAL; + if (!FF_ALLOC_TYPED_ARRAY(s->paths, max_paths) || + !FF_ALLOC_TYPED_ARRAY(s->node_buf, 2 * frontier) || + !FF_ALLOC_TYPED_ARRAY(s->nodep_buf, 2 * frontier) || + !FF_ALLOC_TYPED_ARRAY(s->trellis_hash, 65536)) + return AVERROR(ENOMEM); } avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); @@ -105,11 +118,11 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) case AV_CODEC_ID_ADPCM_IMA_WAV: /* each 16 bits sample gives one nibble and we have 4 bytes per channel overhead */ - avctx->frame_size = (BLKSIZE - 4 * avctx->channels) * 8 / + avctx->frame_size = (s->block_size - 4 * avctx->channels) * 8 / (4 * avctx->channels) + 1; /* seems frame_size isn't taken into account... have to buffer the samples :-( */ - avctx->block_align = BLKSIZE; + avctx->block_align = s->block_size; avctx->bits_per_coded_sample = 4; break; case AV_CODEC_ID_ADPCM_IMA_QT: @@ -119,11 +132,11 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) case AV_CODEC_ID_ADPCM_MS: /* each 16 bits sample gives one nibble and we have 7 bytes per channel overhead */ - avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 / avctx->channels + 2; + avctx->frame_size = (s->block_size - 7 * avctx->channels) * 2 / avctx->channels + 2; avctx->bits_per_coded_sample = 4; - avctx->block_align = BLKSIZE; + avctx->block_align = s->block_size; if (!(avctx->extradata = av_malloc(32 + AV_INPUT_BUFFER_PADDING_SIZE))) - goto error; + return AVERROR(ENOMEM); avctx->extradata_size = 32; extradata = avctx->extradata; bytestream_put_le16(&extradata, avctx->frame_size); @@ -134,8 +147,8 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) } break; case AV_CODEC_ID_ADPCM_YAMAHA: - avctx->frame_size = BLKSIZE * 2 / avctx->channels; - avctx->block_align = BLKSIZE; + avctx->frame_size = s->block_size * 2 / avctx->channels; + avctx->block_align = s->block_size; break; case AV_CODEC_ID_ADPCM_SWF: if (avctx->sample_rate != 11025 && @@ -143,23 +156,47 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) avctx->sample_rate != 44100) { av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, " "22050 or 44100\n"); - ret = AVERROR(EINVAL); - goto error; + return AVERROR(EINVAL); } - avctx->frame_size = 512 * (avctx->sample_rate / 11025); + avctx->frame_size = 4096; /* Hardcoded according to the SWF spec. */ + avctx->block_align = (2 + avctx->channels * (22 + 4 * (avctx->frame_size - 1)) + 7) / 8; break; case AV_CODEC_ID_ADPCM_IMA_SSI: - avctx->frame_size = BLKSIZE * 2 / avctx->channels; - avctx->block_align = BLKSIZE; + case AV_CODEC_ID_ADPCM_IMA_ALP: + avctx->frame_size = s->block_size * 2 / avctx->channels; + avctx->block_align = s->block_size; + break; + case AV_CODEC_ID_ADPCM_IMA_AMV: + if (avctx->sample_rate != 22050) { + av_log(avctx, AV_LOG_ERROR, "Sample rate must be 22050\n"); + return AVERROR(EINVAL); + } + + if (avctx->channels != 1) { + av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n"); + return AVERROR(EINVAL); + } + + avctx->frame_size = s->block_size; + avctx->block_align = 8 + (FFALIGN(avctx->frame_size, 2) / 2); + break; + case AV_CODEC_ID_ADPCM_IMA_APM: + avctx->frame_size = s->block_size * 2 / avctx->channels; + avctx->block_align = s->block_size; + + if (!(avctx->extradata = av_mallocz(28 + AV_INPUT_BUFFER_PADDING_SIZE))) + return AVERROR(ENOMEM); + avctx->extradata_size = 28; + break; + case AV_CODEC_ID_ADPCM_ARGO: + avctx->frame_size = 32; + avctx->block_align = 17 * avctx->channels; break; default: - ret = AVERROR(EINVAL); - goto error; + return AVERROR(EINVAL); } return 0; -error: - return ret; } static av_cold int adpcm_encode_close(AVCodecContext *avctx) @@ -187,6 +224,25 @@ static inline uint8_t adpcm_ima_compress_sample(ADPCMChannelStatus *c, return nibble; } +static inline uint8_t adpcm_ima_alp_compress_sample(ADPCMChannelStatus *c, int16_t sample) +{ + const int delta = sample - c->prev_sample; + const int step = ff_adpcm_step_table[c->step_index]; + const int sign = (delta < 0) * 8; + + int nibble = FFMIN(abs(delta) * 4 / step, 7); + int diff = (step * nibble) >> 2; + if (sign) + diff = -diff; + + nibble = sign | nibble; + + c->prev_sample += diff; + c->prev_sample = av_clip_int16(c->prev_sample); + c->step_index = av_clip(c->step_index + ff_adpcm_index_table[nibble], 0, 88); + return nibble; +} + static inline uint8_t adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c, int16_t sample) { @@ -301,6 +357,7 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, nodes[0]->sample2 = c->sample2; if (version == AV_CODEC_ID_ADPCM_IMA_WAV || version == AV_CODEC_ID_ADPCM_IMA_QT || + version == AV_CODEC_ID_ADPCM_IMA_AMV || version == AV_CODEC_ID_ADPCM_SWF) nodes[0]->sample1 = c->prev_sample; if (version == AV_CODEC_ID_ADPCM_MS) @@ -405,6 +462,7 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, } } else if (version == AV_CODEC_ID_ADPCM_IMA_WAV || version == AV_CODEC_ID_ADPCM_IMA_QT || + version == AV_CODEC_ID_ADPCM_IMA_AMV || version == AV_CODEC_ID_ADPCM_SWF) { #define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\ const int predictor = nodes[j]->sample1;\ @@ -480,6 +538,46 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, c->idelta = nodes[0]->step; } +static inline int adpcm_argo_compress_nibble(const ADPCMChannelStatus *cs, int16_t s, + int shift, int flag) +{ + int nibble; + + if (flag) + nibble = 4 * s - 8 * cs->sample1 + 4 * cs->sample2; + else + nibble = 4 * s - 4 * cs->sample1; + + return (nibble >> shift) & 0x0F; +} + +static int64_t adpcm_argo_compress_block(ADPCMChannelStatus *cs, PutBitContext *pb, + const int16_t *samples, int nsamples, + int shift, int flag) +{ + int64_t error = 0; + + if (pb) { + put_bits(pb, 4, shift - 2); + put_bits(pb, 1, 0); + put_bits(pb, 1, !!flag); + put_bits(pb, 2, 0); + } + + for (int n = 0; n < nsamples; n++) { + /* Compress the nibble, then expand it to see how much precision we've lost. */ + int nibble = adpcm_argo_compress_nibble(cs, samples[n], shift, flag); + int16_t sample = ff_adpcm_argo_expand_nibble(cs, nibble, shift, flag); + + error += abs(samples[n] - sample); + + if (pb) + put_bits(pb, 4, nibble); + } + + return error; +} + static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { @@ -494,9 +592,9 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, samples_p = (int16_t **)frame->extended_data; st = avctx->channels == 2; - if (avctx->codec_id == AV_CODEC_ID_ADPCM_SWF) - pkt_size = (2 + avctx->channels * (22 + 4 * (frame->nb_samples - 1)) + 7) / 8; - else if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_SSI) + if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_SSI || + avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_ALP || + avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_APM) pkt_size = (frame->nb_samples * avctx->channels) / 2; else pkt_size = avctx->block_align; @@ -523,7 +621,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, /* stereo: 4 bytes (8 samples) for left, 4 bytes for right */ if (avctx->trellis > 0) { - FF_ALLOC_ARRAY_OR_GOTO(avctx, buf, avctx->channels, blocks * 8, error); + if (!FF_ALLOC_TYPED_ARRAY(buf, avctx->channels * blocks * 8)) + return AVERROR(ENOMEM); for (ch = 0; ch < avctx->channels; ch++) { adpcm_compress_trellis(avctx, &samples_p[ch][1], buf + ch * blocks * 8, &c->status[ch], @@ -598,6 +697,24 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, flush_put_bits(&pb); break; } + case AV_CODEC_ID_ADPCM_IMA_ALP: + { + PutBitContext pb; + init_put_bits(&pb, dst, pkt_size); + + av_assert0(avctx->trellis == 0); + + for (n = frame->nb_samples / 2; n > 0; n--) { + for (ch = 0; ch < avctx->channels; ch++) { + put_bits(&pb, 4, adpcm_ima_alp_compress_sample(c->status + ch, *samples++)); + put_bits(&pb, 4, adpcm_ima_alp_compress_sample(c->status + ch, samples[st])); + } + samples += avctx->channels; + } + + flush_put_bits(&pb); + break; + } case AV_CODEC_ID_ADPCM_SWF: { PutBitContext pb; @@ -618,7 +735,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } if (avctx->trellis > 0) { - FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error); + if (!(buf = av_malloc(2 * n))) + return AVERROR(ENOMEM); adpcm_compress_trellis(avctx, samples + avctx->channels, buf, &c->status[0], n, avctx->channels); if (avctx->channels == 2) @@ -666,7 +784,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (avctx->trellis > 0) { n = avctx->block_align - 7 * avctx->channels; - FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error); + if (!(buf = av_malloc(2 * n))) + return AVERROR(ENOMEM); if (avctx->channels == 1) { adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n, avctx->channels); @@ -693,7 +812,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, case AV_CODEC_ID_ADPCM_YAMAHA: n = frame->nb_samples / 2; if (avctx->trellis > 0) { - FF_ALLOC_OR_GOTO(avctx, buf, 2 * n * 2, error); + if (!(buf = av_malloc(2 * n * 2))) + return AVERROR(ENOMEM); n *= 2; if (avctx->channels == 1) { adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n, @@ -717,6 +837,97 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, *dst++ = nibble; } break; + case AV_CODEC_ID_ADPCM_IMA_APM: + { + PutBitContext pb; + init_put_bits(&pb, dst, pkt_size); + + av_assert0(avctx->trellis == 0); + + for (n = frame->nb_samples / 2; n > 0; n--) { + for (ch = 0; ch < avctx->channels; ch++) { + put_bits(&pb, 4, adpcm_ima_qt_compress_sample(c->status + ch, *samples++)); + put_bits(&pb, 4, adpcm_ima_qt_compress_sample(c->status + ch, samples[st])); + } + samples += avctx->channels; + } + + flush_put_bits(&pb); + break; + } + case AV_CODEC_ID_ADPCM_IMA_AMV: + { + av_assert0(avctx->channels == 1); + + c->status[0].prev_sample = *samples; + bytestream_put_le16(&dst, c->status[0].prev_sample); + bytestream_put_byte(&dst, c->status[0].step_index); + bytestream_put_byte(&dst, 0); + bytestream_put_le32(&dst, avctx->frame_size); + + if (avctx->trellis > 0) { + n = frame->nb_samples >> 1; + + if (!(buf = av_malloc(2 * n))) + return AVERROR(ENOMEM); + + adpcm_compress_trellis(avctx, samples, buf, &c->status[0], 2 * n, avctx->channels); + for (i = 0; i < n; i++) + bytestream_put_byte(&dst, (buf[2 * i] << 4) | buf[2 * i + 1]); + + samples += 2 * n; + av_free(buf); + } else for (n = frame->nb_samples >> 1; n > 0; n--) { + int nibble; + nibble = adpcm_ima_compress_sample(&c->status[0], *samples++) << 4; + nibble |= adpcm_ima_compress_sample(&c->status[0], *samples++) & 0x0F; + bytestream_put_byte(&dst, nibble); + } + + if (avctx->frame_size & 1) { + int nibble = adpcm_ima_compress_sample(&c->status[0], *samples++) << 4; + bytestream_put_byte(&dst, nibble); + } + break; + } + case AV_CODEC_ID_ADPCM_ARGO: + { + PutBitContext pb; + init_put_bits(&pb, dst, pkt_size); + + av_assert0(frame->nb_samples == 32); + + for (ch = 0; ch < avctx->channels; ch++) { + int64_t error = INT64_MAX, tmperr = INT64_MAX; + int shift = 2, flag = 0; + int saved1 = c->status[ch].sample1; + int saved2 = c->status[ch].sample2; + + /* Find the optimal coefficients, bail early if we find a perfect result. */ + for (int s = 2; s < 18 && tmperr != 0; s++) { + for (int f = 0; f < 2 && tmperr != 0; f++) { + c->status[ch].sample1 = saved1; + c->status[ch].sample2 = saved2; + tmperr = adpcm_argo_compress_block(c->status + ch, NULL, samples_p[ch], + frame->nb_samples, s, f); + if (tmperr < error) { + shift = s; + flag = f; + error = tmperr; + } + } + } + + /* Now actually do the encode. */ + c->status[ch].sample1 = saved1; + c->status[ch].sample2 = saved2; + adpcm_argo_compress_block(c->status + ch, &pb, samples_p[ch], + frame->nb_samples, shift, flag); + } + + flush_put_bits(&pb); + break; + } default: return AVERROR(EINVAL); } @@ -724,8 +935,6 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, avpkt->size = pkt_size; *got_packet_ptr = 1; return 0; -error: - return AVERROR(ENOMEM); } static const enum AVSampleFormat sample_fmts[] = { @@ -736,7 +945,28 @@ static const enum AVSampleFormat sample_fmts_p[] = { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }; +static const AVOption options[] = { + { + .name = "block_size", + .help = "set the block size", + .offset = offsetof(ADPCMEncodeContext, block_size), + .type = AV_OPT_TYPE_INT, + .default_val = {.i64 = 1024}, + .min = 32, + .max = 8192, /* Is this a reasonable upper limit? */ + .flags = AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM + }, + { NULL } +}; + #define ADPCM_ENCODER(id_, name_, sample_fmts_, capabilities_, long_name_) \ +static const AVClass name_ ## _encoder_class = { \ + .class_name = #name_, \ + .item_name = av_default_item_name, \ + .option = options, \ + .version = LIBAVUTIL_VERSION_INT, \ +}; \ + \ AVCodec ff_ ## name_ ## _encoder = { \ .name = #name_, \ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ @@ -748,9 +978,14 @@ AVCodec ff_ ## name_ ## _encoder = { \ .close = adpcm_encode_close, \ .sample_fmts = sample_fmts_, \ .capabilities = capabilities_, \ - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \ + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, \ + .priv_class = &name_ ## _encoder_class, \ } +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_ARGO, adpcm_argo, sample_fmts_p, 0, "ADPCM Argonaut Games"); +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_AMV, adpcm_ima_amv, sample_fmts, 0, "ADPCM IMA AMV"); +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_APM, adpcm_ima_apm, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Ubisoft APM"); +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_ALP, adpcm_ima_alp, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA High Voltage Software ALP"); ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, "ADPCM IMA QuickTime"); ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_SSI, adpcm_ima_ssi, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Simon & Schuster Interactive"); ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, sample_fmts_p, 0, "ADPCM IMA WAV"); diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 40ed8e5ba..94de3eee1 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -103,6 +103,22 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; const uint8_t *buf_end = buf + avpkt->size; int num_blocks, ch, ret; + buffer_size_t new_extradata_size; + uint8_t *new_extradata; + + new_extradata = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, + &new_extradata_size); + if (new_extradata && new_extradata_size > 0) { + int header_size; + if ((ret = ff_adx_decode_header(avctx, new_extradata, + new_extradata_size, &header_size, + c->coeff)) < 0) { + av_log(avctx, AV_LOG_ERROR, "error parsing new ADX extradata\n"); + return AVERROR_INVALIDDATA; + } + + c->eof = 0; + } if (c->eof) { *got_frame_ptr = 0; @@ -183,7 +199,8 @@ AVCodec ff_adpcm_adx_decoder = { .init = adx_decode_init, .decode = adx_decode_frame, .flush = adx_decode_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, }; diff --git a/libavcodec/agm.c b/libavcodec/agm.c index 5b7282b81..f39383140 100644 --- a/libavcodec/agm.c +++ b/libavcodec/agm.c @@ -26,6 +26,8 @@ #define BITSTREAM_READER_LE +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "bytestream.h" #include "copy_block.h" @@ -591,7 +593,7 @@ static int decode_raw_intra_rgb(AVCodecContext *avctx, GetByteContext *gbyte, AV return 0; } -static int fill_pixels(uint8_t **y0, uint8_t **y1, +av_always_inline static int fill_pixels(uint8_t **y0, uint8_t **y1, uint8_t **u, uint8_t **v, int ylinesize, int ulinesize, int vlinesize, uint8_t *fill, diff --git a/libavcodec/aic.c b/libavcodec/aic.c index f027fa99e..cf5b0782b 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -22,6 +22,8 @@ #include +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "bytestream.h" #include "internal.h" diff --git a/libavcodec/alac.c b/libavcodec/alac.c index c8b25dfea..7edbb06a3 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -492,6 +492,7 @@ static int allocate_buffers(ALACContext *alac) { int ch; unsigned buf_size = alac->max_samples_per_frame * sizeof(int32_t); + unsigned extra_buf_size = buf_size + AV_INPUT_BUFFER_PADDING_SIZE; for (ch = 0; ch < 2; ch++) { alac->predict_error_buffer[ch] = NULL; @@ -500,22 +501,19 @@ static int allocate_buffers(ALACContext *alac) } for (ch = 0; ch < FFMIN(alac->channels, 2); ch++) { - FF_ALLOC_OR_GOTO(alac->avctx, alac->predict_error_buffer[ch], - buf_size, buf_alloc_fail); + if (!(alac->predict_error_buffer[ch] = av_malloc(buf_size))) + return AVERROR(ENOMEM); alac->direct_output = alac->sample_size > 16; if (!alac->direct_output) { - FF_ALLOC_OR_GOTO(alac->avctx, alac->output_samples_buffer[ch], - buf_size + AV_INPUT_BUFFER_PADDING_SIZE, buf_alloc_fail); + if (!(alac->output_samples_buffer[ch] = av_malloc(extra_buf_size))) + return AVERROR(ENOMEM); } - FF_ALLOC_OR_GOTO(alac->avctx, alac->extra_bits_buffer[ch], - buf_size + AV_INPUT_BUFFER_PADDING_SIZE, buf_alloc_fail); + if (!(alac->extra_bits_buffer[ch] = av_malloc(extra_buf_size))) + return AVERROR(ENOMEM); } return 0; -buf_alloc_fail: - alac_decode_close(alac->avctx); - return AVERROR(ENOMEM); } static int alac_set_info(ALACContext *alac) @@ -627,6 +625,7 @@ AVCodec ff_alac_decoder = { .init = alac_decode_init, .close = alac_decode_close, .decode = alac_decode_frame, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .priv_class = &alac_class }; diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c index 804cc7b17..9d135d135 100644 --- a/libavcodec/alacenc.c +++ b/libavcodec/alacenc.c @@ -498,8 +498,6 @@ static av_cold int alac_encode_close(AVCodecContext *avctx) { AlacEncodeContext *s = avctx->priv_data; ff_lpc_end(&s->lpc_ctx); - av_freep(&avctx->extradata); - avctx->extradata_size = 0; return 0; } @@ -537,10 +535,8 @@ static av_cold int alac_encode_init(AVCodecContext *avctx) avctx->bits_per_raw_sample); avctx->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE); - if (!avctx->extradata) { - ret = AVERROR(ENOMEM); - goto error; - } + if (!avctx->extradata) + return AVERROR(ENOMEM); avctx->extradata_size = ALAC_EXTRADATA_SIZE; alac_extradata = avctx->extradata; @@ -568,8 +564,7 @@ FF_DISABLE_DEPRECATION_WARNINGS avctx->min_prediction_order > ALAC_MAX_LPC_ORDER) { av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n", avctx->min_prediction_order); - ret = AVERROR(EINVAL); - goto error; + return AVERROR(EINVAL); } s->min_prediction_order = avctx->min_prediction_order; @@ -580,8 +575,7 @@ FF_DISABLE_DEPRECATION_WARNINGS avctx->max_prediction_order > ALAC_MAX_LPC_ORDER) { av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n", avctx->max_prediction_order); - ret = AVERROR(EINVAL); - goto error; + return AVERROR(EINVAL); } s->max_prediction_order = avctx->max_prediction_order; @@ -593,8 +587,7 @@ FF_ENABLE_DEPRECATION_WARNINGS av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n", s->min_prediction_order, s->max_prediction_order); - ret = AVERROR(EINVAL); - goto error; + return AVERROR(EINVAL); } s->avctx = avctx; @@ -602,13 +595,10 @@ FF_ENABLE_DEPRECATION_WARNINGS if ((ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size, s->max_prediction_order, FF_LPC_TYPE_LEVINSON)) < 0) { - goto error; + return ret; } return 0; -error: - alac_encode_close(avctx); - return ret; } static int alac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index fa0c08d42..2e9a3581d 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -43,6 +43,7 @@ extern AVCodec ff_ansi_decoder; extern AVCodec ff_apng_encoder; extern AVCodec ff_apng_decoder; extern AVCodec ff_arbc_decoder; +extern AVCodec ff_argo_decoder; extern AVCodec ff_asv1_encoder; extern AVCodec ff_asv1_decoder; extern AVCodec ff_asv2_encoder; @@ -70,6 +71,7 @@ extern AVCodec ff_cavs_decoder; extern AVCodec ff_cdgraphics_decoder; extern AVCodec ff_cdtoons_decoder; extern AVCodec ff_cdxl_decoder; +extern AVCodec ff_cfhd_encoder; extern AVCodec ff_cfhd_decoder; extern AVCodec ff_cinepak_encoder; extern AVCodec ff_cinepak_decoder; @@ -80,6 +82,7 @@ extern AVCodec ff_cllc_decoder; extern AVCodec ff_comfortnoise_encoder; extern AVCodec ff_comfortnoise_decoder; extern AVCodec ff_cpia_decoder; +extern AVCodec ff_cri_decoder; extern AVCodec ff_cscd_decoder; extern AVCodec ff_cyuv_decoder; extern AVCodec ff_dds_decoder; @@ -106,6 +109,7 @@ extern AVCodec ff_eightsvx_exp_decoder; extern AVCodec ff_eightsvx_fib_decoder; extern AVCodec ff_escape124_decoder; extern AVCodec ff_escape130_decoder; +extern AVCodec ff_exr_encoder; extern AVCodec ff_exr_decoder; extern AVCodec ff_ffv1_encoder; extern AVCodec ff_ffv1_decoder; @@ -165,6 +169,7 @@ extern AVCodec ff_indeo3_decoder; extern AVCodec ff_indeo4_decoder; extern AVCodec ff_indeo5_decoder; extern AVCodec ff_interplay_video_decoder; +extern AVCodec ff_ipu_decoder; extern AVCodec ff_jpeg2000_encoder; extern AVCodec ff_jpeg2000_decoder; extern AVCodec ff_jpegls_encoder; @@ -185,6 +190,7 @@ extern AVCodec ff_mjpeg_encoder; extern AVCodec ff_mjpeg_decoder; extern AVCodec ff_mjpegb_decoder; extern AVCodec ff_mmvideo_decoder; +extern AVCodec ff_mobiclip_decoder; extern AVCodec ff_motionpixels_decoder; extern AVCodec ff_mpeg1video_encoder; extern AVCodec ff_mpeg1video_decoder; @@ -210,6 +216,7 @@ extern AVCodec ff_msmpeg4v2_decoder; extern AVCodec ff_msmpeg4v3_encoder; extern AVCodec ff_msmpeg4v3_decoder; extern AVCodec ff_msmpeg4_crystalhd_decoder; +extern AVCodec ff_msp2_decoder; extern AVCodec ff_msrle_decoder; extern AVCodec ff_mss1_decoder; extern AVCodec ff_mss2_decoder; @@ -233,11 +240,14 @@ extern AVCodec ff_pbm_encoder; extern AVCodec ff_pbm_decoder; extern AVCodec ff_pcx_encoder; extern AVCodec ff_pcx_decoder; +extern AVCodec ff_pfm_encoder; extern AVCodec ff_pfm_decoder; extern AVCodec ff_pgm_encoder; extern AVCodec ff_pgm_decoder; extern AVCodec ff_pgmyuv_encoder; extern AVCodec ff_pgmyuv_decoder; +extern AVCodec ff_pgx_decoder; +extern AVCodec ff_photocd_decoder; extern AVCodec ff_pictor_decoder; extern AVCodec ff_pixlet_decoder; extern AVCodec ff_png_encoder; @@ -265,6 +275,7 @@ extern AVCodec ff_rawvideo_decoder; extern AVCodec ff_rl2_decoder; extern AVCodec ff_roq_encoder; extern AVCodec ff_roq_decoder; +extern AVCodec ff_rpza_encoder; extern AVCodec ff_rpza_decoder; extern AVCodec ff_rscc_decoder; extern AVCodec ff_rv10_encoder; @@ -278,10 +289,12 @@ extern AVCodec ff_s302m_decoder; extern AVCodec ff_sanm_decoder; extern AVCodec ff_scpr_decoder; extern AVCodec ff_screenpresso_decoder; +extern AVCodec ff_sga_decoder; extern AVCodec ff_sgi_encoder; extern AVCodec ff_sgi_decoder; extern AVCodec ff_sgirle_decoder; extern AVCodec ff_sheervideo_decoder; +extern AVCodec ff_simbiosis_imx_decoder; extern AVCodec ff_smacker_decoder; extern AVCodec ff_smc_decoder; extern AVCodec ff_smvjpeg_decoder; @@ -289,6 +302,7 @@ extern AVCodec ff_snow_encoder; extern AVCodec ff_snow_decoder; extern AVCodec ff_sp5x_decoder; extern AVCodec ff_speedhq_decoder; +extern AVCodec ff_speedhq_encoder; extern AVCodec ff_srgc_decoder; extern AVCodec ff_sunrast_encoder; extern AVCodec ff_sunrast_decoder; @@ -427,6 +441,7 @@ extern AVCodec ff_dst_decoder; extern AVCodec ff_eac3_encoder; extern AVCodec ff_eac3_decoder; extern AVCodec ff_evrc_decoder; +extern AVCodec ff_fastaudio_decoder; extern AVCodec ff_ffwavesynth_decoder; extern AVCodec ff_flac_encoder; extern AVCodec ff_flac_decoder; @@ -554,6 +569,7 @@ extern AVCodec ff_pcm_s64be_encoder; extern AVCodec ff_pcm_s64be_decoder; extern AVCodec ff_pcm_s64le_encoder; extern AVCodec ff_pcm_s64le_decoder; +extern AVCodec ff_pcm_sga_decoder; extern AVCodec ff_pcm_u8_encoder; extern AVCodec ff_pcm_u8_decoder; extern AVCodec ff_pcm_u16be_encoder; @@ -589,6 +605,7 @@ extern AVCodec ff_adpcm_afc_decoder; extern AVCodec ff_adpcm_agm_decoder; extern AVCodec ff_adpcm_aica_decoder; extern AVCodec ff_adpcm_argo_decoder; +extern AVCodec ff_adpcm_argo_encoder; extern AVCodec ff_adpcm_ct_decoder; extern AVCodec ff_adpcm_dtk_decoder; extern AVCodec ff_adpcm_ea_decoder; @@ -604,9 +621,12 @@ extern AVCodec ff_adpcm_g726_decoder; extern AVCodec ff_adpcm_g726le_encoder; extern AVCodec ff_adpcm_g726le_decoder; extern AVCodec ff_adpcm_ima_amv_decoder; +extern AVCodec ff_adpcm_ima_amv_encoder; extern AVCodec ff_adpcm_ima_alp_decoder; +extern AVCodec ff_adpcm_ima_alp_encoder; extern AVCodec ff_adpcm_ima_apc_decoder; extern AVCodec ff_adpcm_ima_apm_decoder; +extern AVCodec ff_adpcm_ima_apm_encoder; extern AVCodec ff_adpcm_ima_cunning_decoder; extern AVCodec ff_adpcm_ima_dat4_decoder; extern AVCodec ff_adpcm_ima_dk3_decoder; @@ -614,6 +634,7 @@ extern AVCodec ff_adpcm_ima_dk4_decoder; extern AVCodec ff_adpcm_ima_ea_eacs_decoder; extern AVCodec ff_adpcm_ima_ea_sead_decoder; extern AVCodec ff_adpcm_ima_iss_decoder; +extern AVCodec ff_adpcm_ima_moflex_decoder; extern AVCodec ff_adpcm_ima_mtf_decoder; extern AVCodec ff_adpcm_ima_oki_decoder; extern AVCodec ff_adpcm_ima_qt_encoder; @@ -670,6 +691,7 @@ extern AVCodec ff_subviewer_decoder; extern AVCodec ff_subviewer1_decoder; extern AVCodec ff_text_encoder; extern AVCodec ff_text_decoder; +extern AVCodec ff_ttml_encoder; extern AVCodec ff_vplayer_decoder; extern AVCodec ff_webvtt_encoder; extern AVCodec ff_webvtt_decoder; @@ -725,8 +747,10 @@ extern AVCodec ff_librsvg_decoder; extern AVCodec ff_libshine_encoder; extern AVCodec ff_libspeex_encoder; extern AVCodec ff_libspeex_decoder; +extern AVCodec ff_libsvtav1_encoder; extern AVCodec ff_libtheora_encoder; extern AVCodec ff_libtwolame_encoder; +extern AVCodec ff_libuavs3d_decoder; extern AVCodec ff_libvo_amrwbenc_encoder; extern AVCodec ff_libvorbis_encoder; extern AVCodec ff_libvorbis_decoder; @@ -734,7 +758,6 @@ extern AVCodec ff_libvpx_vp8_encoder; extern AVCodec ff_libvpx_vp8_decoder; extern AVCodec ff_libvpx_vp9_encoder; extern AVCodec ff_libvpx_vp9_decoder; -extern AVCodec ff_libwavpack_encoder; /* preferred over libwebp */ extern AVCodec ff_libwebp_anim_encoder; extern AVCodec ff_libwebp_encoder; @@ -758,6 +781,10 @@ extern AVCodec ff_aac_mf_encoder; extern AVCodec ff_ac3_mf_encoder; extern AVCodec ff_h263_v4l2m2m_encoder; extern AVCodec ff_libaom_av1_decoder; +/* hwaccel hooks only, so prefer external decoders */ +extern AVCodec ff_av1_decoder; +extern AVCodec ff_av1_cuvid_decoder; +extern AVCodec ff_av1_qsv_decoder; extern AVCodec ff_libopenh264_encoder; extern AVCodec ff_libopenh264_decoder; extern AVCodec ff_h264_amf_encoder; diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 7eb14db8f..a8c3433fa 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -350,7 +350,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) return AVERROR_INVALIDDATA; if (avctx->channels > FF_SANE_NB_CHANNELS) { - avpriv_request_sample(avctx, "Huge number of channels\n"); + avpriv_request_sample(avctx, "Huge number of channels"); return AVERROR_PATCHWELCOME; } @@ -1016,6 +1016,10 @@ static int read_block(ALSDecContext *ctx, ALSBlockData *bd) ALSSpecificConfig *sconf = &ctx->sconf; *bd->shift_lsbs = 0; + + if (get_bits_left(gb) < 1) + return AVERROR_INVALIDDATA; + // read block type flag and read the samples accordingly if (get_bits1(gb)) { ret = read_var_block_data(ctx, bd); @@ -2179,6 +2183,6 @@ AVCodec ff_als_decoder = { .close = decode_end, .decode = decode_frame, .flush = flush, - .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c index 876fddd2b..fb23ed738 100644 --- a/libavcodec/amfenc.c +++ b/libavcodec/amfenc.c @@ -33,6 +33,7 @@ #include "libavutil/time.h" #include "amfenc.h" +#include "encode.h" #include "internal.h" #if CONFIG_D3D11VA @@ -451,7 +452,7 @@ static int amf_copy_buffer(AVCodecContext *avctx, AVPacket *pkt, AMFBuffer *buff int64_t timestamp = AV_NOPTS_VALUE; int64_t size = buffer->pVtbl->GetSize(buffer); - if ((ret = av_new_packet(pkt, size)) < 0) { + if ((ret = ff_get_encode_buffer(avctx, pkt, size, 0)) < 0) { return ret; } memcpy(pkt->data, buffer->pVtbl->GetNative(buffer), size); @@ -588,17 +589,27 @@ static void amf_release_buffer_with_frame_ref(AMFBuffer *frame_ref_storage_buffe frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer); } -int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame) +int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) { AmfContext *ctx = avctx->priv_data; AMFSurface *surface; AMF_RESULT res; int ret; + AMF_RESULT res_query; + AMFData *data = NULL; + AVFrame *frame = ctx->delayed_frame; + int block_and_wait; if (!ctx->encoder) return AVERROR(EINVAL); - if (!frame) { // submit drain + if (!frame->buf[0]) { + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + if (!frame->buf[0]) { // submit drain if (!ctx->eof) { // submit drain one time only if (ctx->delayed_surface != NULL) { ctx->delayed_drain = 1; // input queue is full: resubmit Drain() in ff_amf_receive_packet @@ -613,15 +624,10 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame) AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "Drain() failed with error %d\n", res); } } - } else{ - return AVERROR_EOF; } - } else { // submit frame + } else if (!ctx->delayed_surface) { // submit frame int hw_surface = 0; - if (ctx->delayed_surface != NULL) { - return AVERROR(EAGAIN); // should not happen when called from ffmpeg, other clients may resubmit - } // prepare surface from frame switch (frame->format) { #if CONFIG_D3D11VA @@ -693,38 +699,23 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame) break; } - // submit surface res = ctx->encoder->pVtbl->SubmitInput(ctx->encoder, (AMFData*)surface); if (res == AMF_INPUT_FULL) { // handle full queue //store surface for later submission ctx->delayed_surface = surface; - if (surface->pVtbl->GetMemoryType(surface) == AMF_MEMORY_DX11) { - av_frame_ref(ctx->delayed_frame, frame); - } } else { + int64_t pts = frame->pts; surface->pVtbl->Release(surface); AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "SubmitInput() failed with error %d\n", res); - if ((ret = timestamp_queue_enqueue(avctx, frame->pts)) < 0) { + av_frame_unref(frame); + if ((ret = timestamp_queue_enqueue(avctx, pts)) < 0) { return ret; } - } } - return 0; -} -int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) -{ - int ret; - AMF_RESULT res; - AMF_RESULT res_query; - AmfContext *ctx = avctx->priv_data; - AMFData *data = NULL; - int block_and_wait; - if (!ctx->encoder) - return AVERROR(EINVAL); do { block_and_wait = 0; @@ -791,3 +782,15 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) } return ret; } + +const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[] = { +#if CONFIG_D3D11VA + HW_CONFIG_ENCODER_FRAMES(D3D11, D3D11VA), + HW_CONFIG_ENCODER_DEVICE(NONE, D3D11VA), +#endif +#if CONFIG_DXVA2 + HW_CONFIG_ENCODER_FRAMES(DXVA2_VLD, DXVA2), + HW_CONFIG_ENCODER_DEVICE(NONE, DXVA2), +#endif + NULL, +}; diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h index b1361842b..358b2ef77 100644 --- a/libavcodec/amfenc.h +++ b/libavcodec/amfenc.h @@ -27,6 +27,7 @@ #include "libavutil/fifo.h" #include "avcodec.h" +#include "hwconfig.h" /** @@ -117,6 +118,8 @@ typedef struct AmfContext { int tier; } AmfContext; +extern const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[]; + /** * Common encoder initization function */ @@ -129,8 +132,6 @@ int ff_amf_encode_close(AVCodecContext *avctx); /** * Ecoding one frame - common function for all AMF encoders */ - -int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame); int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt); /** diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c index 7f2817f11..fe30d7f11 100644 --- a/libavcodec/amfenc_h264.c +++ b/libavcodec/amfenc_h264.c @@ -383,14 +383,15 @@ AVCodec ff_h264_amf_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = amf_encode_init_h264, - .send_frame = ff_amf_send_frame, .receive_packet = ff_amf_receive_packet, .close = ff_amf_encode_close, .priv_data_size = sizeof(AmfContext), .priv_class = &h264_amf_class, .defaults = defaults, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | + AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = ff_amf_pix_fmts, .wrapper_name = "amf", + .hw_configs = ff_amfenc_hw_configs, }; diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c index 77e57d246..b5c840e5f 100644 --- a/libavcodec/amfenc_hevc.c +++ b/libavcodec/amfenc_hevc.c @@ -69,7 +69,7 @@ static const AVOption options[] = { { "gop", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_GOP_ALIGNED }, 0, 0, VE, "hdrmode" }, { "idr", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_IDR_ALIGNED }, 0, 0, VE, "hdrmode" }, - { "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 60 }, 0, INT_MAX, VE }, + { "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, VE }, { "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, { "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, { "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, @@ -298,6 +298,8 @@ static const AVCodecDefault defaults[] = { { "b", "2M" }, { "g", "250" }, { "slices", "1" }, + { "qmin", "-1" }, + { "qmax", "-1" }, { NULL }, }; static const AVClass hevc_amf_class = { @@ -313,14 +315,15 @@ AVCodec ff_hevc_amf_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = amf_encode_init_hevc, - .send_frame = ff_amf_send_frame, .receive_packet = ff_amf_receive_packet, .close = ff_amf_encode_close, .priv_data_size = sizeof(AmfContext), .priv_class = &hevc_amf_class, .defaults = defaults, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | + AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = ff_amf_pix_fmts, .wrapper_name = "amf", + .hw_configs = ff_amfenc_hw_configs, }; diff --git a/libavcodec/amrnbdata.h b/libavcodec/amrnbdata.h index 435fd9924..20b7a6452 100644 --- a/libavcodec/amrnbdata.h +++ b/libavcodec/amrnbdata.h @@ -1424,11 +1424,6 @@ static const float pred_fac[LP_FILTER_ORDER] = { // fixed tables -/** - * number of pulses per mode - */ -static const uint8_t pulses_nb_per_mode[] = {2, 2, 2, 3, 4, 4, 8, 10}; - /** track start positions for algebraic code book routines */ static const uint8_t track_position[16] = { 0, 2, 0, 3, 0, 2, 0, 3, 1, 3, 2, 4, 1, 4, 1, 4 diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index ea299acd4..8e02d4cb2 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -1088,7 +1088,7 @@ AVCodec ff_amrnb_decoder = { .priv_data_size = sizeof(AMRContext), .init = amrnb_decode_init, .decode = amrnb_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, }; diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 555c4bc45..070f27690 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -1283,7 +1283,7 @@ AVCodec ff_amrwb_decoder = { .priv_data_size = sizeof(AMRWBContext), .init = amrwb_decode_init, .decode = amrwb_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, }; diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 4cbbfa40a..e0c6b6bb8 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -133,6 +133,21 @@ typedef struct APEPredictor { unsigned int sample_pos; } APEPredictor; +typedef struct APEPredictor64 { + int64_t *buf; + + int64_t lastA[2]; + + int64_t filterA[2]; + int64_t filterB[2]; + + uint64_t coeffsA[2][4]; ///< adaption coefficients + uint64_t coeffsB[2][5]; ///< adaption coefficients + int64_t historybuffer[HISTORY_SIZE + PREDICTOR_SIZE]; + + unsigned int sample_pos; +} APEPredictor64; + /** Decoder context */ typedef struct APEContext { AVClass *class; ///< class for AVOptions @@ -152,6 +167,7 @@ typedef struct APEContext { uint32_t CRC_state; ///< accumulated CRC int frameflags; ///< frame flags APEPredictor predictor; ///< predictor used for final reconstruction + APEPredictor64 predictor64; ///< 64bit predictor used for final reconstruction int32_t *decoded_buffer; int decoded_size; @@ -227,6 +243,7 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n"); return AVERROR(EINVAL); } + avctx->bits_per_raw_sample = s->bps = avctx->bits_per_coded_sample; switch (s->bps) { case 8: @@ -262,9 +279,8 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) for (i = 0; i < APE_FILTER_LEVELS; i++) { if (!ape_filter_orders[s->fset][i]) break; - FF_ALLOC_OR_GOTO(avctx, s->filterbuf[i], - (ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4, - filter_alloc_fail); + if (!(s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4))) + return AVERROR(ENOMEM); } if (s->fileversion < 3860) { @@ -300,9 +316,6 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; return 0; -filter_alloc_fail: - ape_decode_close(avctx); - return AVERROR(ENOMEM); } /** @@ -547,12 +560,10 @@ static inline int ape_decode_value_3900(APEContext *ctx, APERice *rice) static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice) { - unsigned int x, overflow; - int base, pivot; + unsigned int x, overflow, pivot; + int base; - pivot = rice->ksum >> 5; - if (pivot == 0) - pivot = 1; + pivot = FFMAX(rice->ksum >> 5, 1); overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980); @@ -793,13 +804,20 @@ static const int32_t initial_coeffs_3930[4] = { 360, 317, -109, 98 }; +static const int64_t initial_coeffs_3930_64bit[4] = { + 360, 317, -109, 98 +}; + static void init_predictor_decoder(APEContext *ctx) { APEPredictor *p = &ctx->predictor; + APEPredictor64 *p64 = &ctx->predictor64; /* Zero the history buffers */ memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(*p->historybuffer)); + memset(p64->historybuffer, 0, PREDICTOR_SIZE * sizeof(*p64->historybuffer)); p->buf = p->historybuffer; + p64->buf = p64->historybuffer; /* Initialize and zero the coefficients */ if (ctx->fileversion < 3930) { @@ -817,8 +835,11 @@ static void init_predictor_decoder(APEContext *ctx) } else { memcpy(p->coeffsA[0], initial_coeffs_3930, sizeof(initial_coeffs_3930)); memcpy(p->coeffsA[1], initial_coeffs_3930, sizeof(initial_coeffs_3930)); + memcpy(p64->coeffsA[0], initial_coeffs_3930_64bit, sizeof(initial_coeffs_3930_64bit)); + memcpy(p64->coeffsA[1], initial_coeffs_3930_64bit, sizeof(initial_coeffs_3930_64bit)); } memset(p->coeffsB, 0, sizeof(p->coeffsB)); + memset(p64->coeffsB, 0, sizeof(p64->coeffsB)); if (ctx->fileversion < 3930) { memcpy(p->coeffsB[0], initial_coeffs_b_3800, sizeof(initial_coeffs_b_3800)); @@ -830,7 +851,13 @@ static void init_predictor_decoder(APEContext *ctx) p->filterB[0] = p->filterB[1] = 0; p->lastA[0] = p->lastA[1] = 0; + p64->filterA[0] = p64->filterA[1] = 0; + p64->filterB[0] = p64->filterB[1] = 0; + p64->lastA[0] = p64->lastA[1] = 0; + p->sample_pos = 0; + + p64->sample_pos = 0; } /** Get inverse sign of integer (-1 for positive, 1 for negative and 0 for zero) */ @@ -1136,16 +1163,17 @@ static void predictor_decode_mono_3930(APEContext *ctx, int count) } } -static av_always_inline int predictor_update_filter(APEPredictor *p, +static av_always_inline int predictor_update_filter(APEPredictor64 *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB) { - int32_t predictionA, predictionB, sign; + int64_t predictionA, predictionB; + int32_t sign; p->buf[delayA] = p->lastA[filter]; p->buf[adaptA] = APESIGN(p->buf[delayA]); - p->buf[delayA - 1] = p->buf[delayA] - (unsigned)p->buf[delayA - 1]; + p->buf[delayA - 1] = p->buf[delayA] - (uint64_t)p->buf[delayA - 1]; p->buf[adaptA - 1] = APESIGN(p->buf[delayA - 1]); predictionA = p->buf[delayA ] * p->coeffsA[filter][0] + @@ -1154,9 +1182,9 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, p->buf[delayA - 3] * p->coeffsA[filter][3]; /* Apply a scaled first-order filter compression */ - p->buf[delayB] = p->filterA[filter ^ 1] - ((int)(p->filterB[filter] * 31U) >> 5); + p->buf[delayB] = p->filterA[filter ^ 1] - ((int64_t)(p->filterB[filter] * 31ULL) >> 5); p->buf[adaptB] = APESIGN(p->buf[delayB]); - p->buf[delayB - 1] = p->buf[delayB] - (unsigned)p->buf[delayB - 1]; + p->buf[delayB - 1] = p->buf[delayB] - (uint64_t)p->buf[delayB - 1]; p->buf[adaptB - 1] = APESIGN(p->buf[delayB - 1]); p->filterB[filter] = p->filterA[filter ^ 1]; @@ -1166,8 +1194,8 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, p->buf[delayB - 3] * p->coeffsB[filter][3] + p->buf[delayB - 4] * p->coeffsB[filter][4]; - p->lastA[filter] = decoded + ((int)((unsigned)predictionA + (predictionB >> 1)) >> 10); - p->filterA[filter] = p->lastA[filter] + ((int)(p->filterA[filter] * 31U) >> 5); + p->lastA[filter] = decoded + ((int64_t)((uint64_t)predictionA + (predictionB >> 1)) >> 10); + p->filterA[filter] = p->lastA[filter] + ((int64_t)(p->filterA[filter] * 31ULL) >> 5); sign = APESIGN(decoded); p->coeffsA[filter][0] += p->buf[adaptA ] * sign; @@ -1185,7 +1213,7 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, static void predictor_decode_stereo_3950(APEContext *ctx, int count) { - APEPredictor *p = &ctx->predictor; + APEPredictor64 *p = &ctx->predictor64; int32_t *decoded0 = ctx->decoded[0]; int32_t *decoded1 = ctx->decoded[1]; @@ -1214,7 +1242,7 @@ static void predictor_decode_stereo_3950(APEContext *ctx, int count) static void predictor_decode_mono_3950(APEContext *ctx, int count) { - APEPredictor *p = &ctx->predictor; + APEPredictor64 *p = &ctx->predictor64; int32_t *decoded0 = ctx->decoded[0]; int32_t predictionA, currentA, A, sign; @@ -1226,14 +1254,14 @@ static void predictor_decode_mono_3950(APEContext *ctx, int count) A = *decoded0; p->buf[YDELAYA] = currentA; - p->buf[YDELAYA - 1] = p->buf[YDELAYA] - (unsigned)p->buf[YDELAYA - 1]; + p->buf[YDELAYA - 1] = p->buf[YDELAYA] - (uint64_t)p->buf[YDELAYA - 1]; predictionA = p->buf[YDELAYA ] * p->coeffsA[0][0] + p->buf[YDELAYA - 1] * p->coeffsA[0][1] + p->buf[YDELAYA - 2] * p->coeffsA[0][2] + p->buf[YDELAYA - 3] * p->coeffsA[0][3]; - currentA = A + (unsigned)(predictionA >> 10); + currentA = A + (uint64_t)(predictionA >> 10); p->buf[YADAPTCOEFFSA] = APESIGN(p->buf[YDELAYA ]); p->buf[YADAPTCOEFFSA - 1] = APESIGN(p->buf[YDELAYA - 1]); @@ -1253,7 +1281,7 @@ static void predictor_decode_mono_3950(APEContext *ctx, int count) p->buf = p->historybuffer; } - p->filterA[0] = currentA + (unsigned)((int)(p->filterA[0] * 31U) >> 5); + p->filterA[0] = currentA + (uint64_t)((int64_t)(p->filterA[0] * 31U) >> 5); *(decoded0++) = p->filterA[0]; } @@ -1282,7 +1310,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f, int32_t *data, int count, int order, int fracbits) { int res; - int absres; + unsigned absres; while (count--) { /* round fixedpoint scalar product */ @@ -1290,7 +1318,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f, f->delay - order, f->adaptcoeffs - order, order, APESIGN(*data)); - res = (int)(res + (1U << (fracbits - 1))) >> fracbits; + res = (int64_t)(res + (1LL << (fracbits - 1))) >> fracbits; res += (unsigned)*data; *data++ = res; @@ -1306,7 +1334,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f, /* Version 3.98 and later files */ /* Update the adaption coefficients */ - absres = res < 0 ? -(unsigned)res : res; + absres = FFABSU(res); if (absres) *f->adaptcoeffs = APESIGN(res) * (8 << ((absres > f->avg * 3) + (absres > f->avg * 4 / 3))); @@ -1638,6 +1666,7 @@ AVCodec ff_ape_decoder = { .decode = ape_decode_frame, .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .flush = ape_flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P, diff --git a/libavcodec/argo.c b/libavcodec/argo.c new file mode 100644 index 000000000..7358d102e --- /dev/null +++ b/libavcodec/argo.c @@ -0,0 +1,740 @@ +/* + * Argonaut Games Video decoder + * Copyright (c) 2020 Paul B Mahol + * + * 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 + +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" + +typedef struct ArgoContext { + GetByteContext gb; + + int bpp; + int key; + int mv0[128][2]; + int mv1[16][2]; + uint32_t pal[256]; + AVFrame *frame; +} ArgoContext; + +static int decode_pal8(AVCodecContext *avctx, uint32_t *pal) +{ + ArgoContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + int start, count; + + start = bytestream2_get_le16(gb); + count = bytestream2_get_le16(gb); + + if (start + count > 256) + return AVERROR_INVALIDDATA; + + if (bytestream2_get_bytes_left(gb) < 3 * count) + return AVERROR_INVALIDDATA; + + for (int i = 0; i < count; i++) + pal[start + i] = (0xFF << 24U) | bytestream2_get_be24u(gb); + + return 0; +} + +static int decode_avcf(AVCodecContext *avctx, AVFrame *frame) +{ + ArgoContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + const int l = frame->linesize[0]; + const uint8_t *map = gb->buffer; + uint8_t *dst = frame->data[0]; + + if (bytestream2_get_bytes_left(gb) < 1024 + (frame->width / 2) * (frame->height / 2)) + return AVERROR_INVALIDDATA; + + bytestream2_skipu(gb, 1024); + for (int y = 0; y < frame->height; y += 2) { + for (int x = 0; x < frame->width; x += 2) { + int index = bytestream2_get_byteu(gb); + const uint8_t *block = map + index * 4; + + dst[x+0] = block[0]; + dst[x+1] = block[1]; + dst[x+l] = block[2]; + dst[x+l+1] = block[3]; + } + + dst += frame->linesize[0] * 2; + } + + return 0; +} + +static int decode_alcd(AVCodecContext *avctx, AVFrame *frame) +{ + ArgoContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + GetByteContext sb; + const int l = frame->linesize[0]; + const uint8_t *map = gb->buffer; + uint8_t *dst = frame->data[0]; + uint8_t codes = 0; + int count = 0; + + if (bytestream2_get_bytes_left(gb) < 1024 + (((frame->width / 2) * (frame->height / 2) + 7) >> 3)) + return AVERROR_INVALIDDATA; + + bytestream2_skipu(gb, 1024); + sb = *gb; + bytestream2_skipu(gb, ((frame->width / 2) * (frame->height / 2) + 7) >> 3); + + for (int y = 0; y < frame->height; y += 2) { + for (int x = 0; x < frame->width; x += 2) { + const uint8_t *block; + int index; + + if (count == 0) { + codes = bytestream2_get_byteu(&sb); + count = 8; + } + + if (codes & 0x80) { + index = bytestream2_get_byte(gb); + block = map + index * 4; + + dst[x+0] = block[0]; + dst[x+1] = block[1]; + dst[x+l] = block[2]; + dst[x+l+1] = block[3]; + } + + codes <<= 1; + count--; + } + + dst += frame->linesize[0] * 2; + } + + return 0; +} + +static int decode_mad1(AVCodecContext *avctx, AVFrame *frame) +{ + ArgoContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + const int w = frame->width; + const int h = frame->height; + const int l = frame->linesize[0]; + + while (bytestream2_get_bytes_left(gb) > 0) { + int size, type, pos, dy; + uint8_t *dst; + + type = bytestream2_get_byte(gb); + if (type == 0xFF) + break; + + switch (type) { + case 8: + dst = frame->data[0]; + for (int y = 0; y < h; y += 8) { + for (int x = 0; x < w; x += 8) { + int fill = bytestream2_get_byte(gb); + uint8_t *ddst = dst + x; + + for (int by = 0; by < 8; by++) { + memset(ddst, fill, 8); + ddst += l; + } + } + + dst += 8 * l; + } + break; + case 7: + while (bytestream2_get_bytes_left(gb) > 0) { + int bsize = bytestream2_get_byte(gb); + uint8_t *src; + int count; + + if (!bsize) + break; + + count = bytestream2_get_be16(gb); + while (count > 0) { + int mvx, mvy, a, b, c, mx, my; + int bsize_w, bsize_h; + + bsize_w = bsize_h = bsize; + if (bytestream2_get_bytes_left(gb) < 4) + return AVERROR_INVALIDDATA; + mvx = bytestream2_get_byte(gb) * bsize; + mvy = bytestream2_get_byte(gb) * bsize; + a = bytestream2_get_byte(gb); + b = bytestream2_get_byte(gb); + c = ((a & 0x3F) << 8) + b; + mx = mvx + (c & 0x7F) - 64; + my = mvy + (c >> 7) - 64; + + if (mvy < 0 || mvy >= h) + return AVERROR_INVALIDDATA; + + if (mvx < 0 || mvx >= w) + return AVERROR_INVALIDDATA; + + if (my < 0 || my >= h) + return AVERROR_INVALIDDATA; + + if (mx < 0 || mx >= w) + return AVERROR_INVALIDDATA; + + dst = frame->data[0] + mvx + l * mvy; + src = frame->data[0] + mx + l * my; + + bsize_w = FFMIN3(bsize_w, w - mvx, w - mx); + bsize_h = FFMIN3(bsize_h, h - mvy, h - my); + + if (mvy >= my && (mvy != my || mvx >= mx)) { + src += (bsize_h - 1) * l; + dst += (bsize_h - 1) * l; + for (int by = 0; by < bsize_h; by++) { + memmove(dst, src, bsize_w); + src -= l; + dst -= l; + } + } else { + for (int by = 0; by < bsize_h; by++) { + memmove(dst, src, bsize_w); + src += l; + dst += l; + } + } + + count--; + } + } + break; + case 6: + dst = frame->data[0]; + if (bytestream2_get_bytes_left(gb) < w * h) + return AVERROR_INVALIDDATA; + for (int y = 0; y < h; y++) { + bytestream2_get_bufferu(gb, dst, w); + dst += l; + } + break; + case 5: + dst = frame->data[0]; + for (int y = 0; y < h; y += 2) { + for (int x = 0; x < w; x += 2) { + int fill = bytestream2_get_byte(gb); + uint8_t *ddst = dst + x; + + fill = (fill << 8) | fill; + for (int by = 0; by < 2; by++) { + AV_WN16(ddst, fill); + + ddst += l; + } + } + + dst += 2 * l; + } + break; + case 3: + size = bytestream2_get_le16(gb); + if (size > 0) { + int x = bytestream2_get_byte(gb) * 4; + int y = bytestream2_get_byte(gb) * 4; + int count = bytestream2_get_byte(gb); + int fill = bytestream2_get_byte(gb); + + av_log(avctx, AV_LOG_DEBUG, "%d %d %d %d\n", x, y, count, fill); + for (int i = 0; i < count; i++) + ; + return AVERROR_PATCHWELCOME; + } + break; + case 2: + dst = frame->data[0]; + pos = 0; + dy = 0; + while (bytestream2_get_bytes_left(gb) > 0) { + int count = bytestream2_get_byteu(gb); + int skip = count & 0x3F; + + count = count >> 6; + if (skip == 0x3F) { + pos += 0x3E; + while (pos >= w) { + pos -= w; + dst += l; + dy++; + if (dy >= h) + return 0; + } + } else { + pos += skip; + while (pos >= w) { + pos -= w; + dst += l; + dy++; + if (dy >= h) + return 0; + } + while (count >= 0) { + int bits = bytestream2_get_byte(gb); + + for (int i = 0; i < 4; i++) { + switch (bits & 3) { + case 0: + break; + case 1: + if (dy < 1 && !pos) + return AVERROR_INVALIDDATA; + else + dst[pos] = pos ? dst[pos - 1] : dst[-l + w - 1]; + break; + case 2: + if (dy < 1) + return AVERROR_INVALIDDATA; + dst[pos] = dst[pos - l]; + break; + case 3: + dst[pos] = bytestream2_get_byte(gb); + break; + } + + pos++; + if (pos >= w) { + pos -= w; + dst += l; + dy++; + if (dy >= h) + return 0; + } + bits >>= 2; + } + count--; + } + } + } + break; + default: + return AVERROR_INVALIDDATA; + } + } + + return 0; +} + +static int decode_mad1_24(AVCodecContext *avctx, AVFrame *frame) +{ + ArgoContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + const int w = frame->width; + const int h = frame->height; + const int l = frame->linesize[0] / 4; + + while (bytestream2_get_bytes_left(gb) > 0) { + int osize, type, pos, dy, di, bcode, value, v14; + const uint8_t *bits; + uint32_t *dst; + + type = bytestream2_get_byte(gb); + if (type == 0xFF) + return 0; + + switch (type) { + case 8: + dst = (uint32_t *)frame->data[0]; + for (int y = 0; y + 12 <= h; y += 12) { + for (int x = 0; x + 12 <= w; x += 12) { + int fill = bytestream2_get_be24(gb); + uint32_t *dstp = dst + x; + + for (int by = 0; by < 12; by++) { + for (int bx = 0; bx < 12; bx++) + dstp[bx] = fill; + + dstp += l; + } + } + + dst += 12 * l; + } + break; + case 7: + while (bytestream2_get_bytes_left(gb) > 0) { + int bsize = bytestream2_get_byte(gb); + uint32_t *src; + int count; + + if (!bsize) + break; + + count = bytestream2_get_be16(gb); + while (count > 0) { + int mvx, mvy, a, b, c, mx, my; + int bsize_w, bsize_h; + + bsize_w = bsize_h = bsize; + if (bytestream2_get_bytes_left(gb) < 4) + return AVERROR_INVALIDDATA; + mvx = bytestream2_get_byte(gb) * bsize; + mvy = bytestream2_get_byte(gb) * bsize; + a = bytestream2_get_byte(gb); + b = bytestream2_get_byte(gb); + c = ((a & 0x3F) << 8) + b; + mx = mvx + (c & 0x7F) - 64; + my = mvy + (c >> 7) - 64; + + if (mvy < 0 || mvy >= h) + return AVERROR_INVALIDDATA; + + if (mvx < 0 || mvx >= w) + return AVERROR_INVALIDDATA; + + if (my < 0 || my >= h) + return AVERROR_INVALIDDATA; + + if (mx < 0 || mx >= w) + return AVERROR_INVALIDDATA; + + dst = (uint32_t *)frame->data[0] + mvx + l * mvy; + src = (uint32_t *)frame->data[0] + mx + l * my; + + bsize_w = FFMIN3(bsize_w, w - mvx, w - mx); + bsize_h = FFMIN3(bsize_h, h - mvy, h - my); + + if (mvy >= my && (mvy != my || mvx >= mx)) { + src += (bsize_h - 1) * l; + dst += (bsize_h - 1) * l; + for (int by = 0; by < bsize_h; by++) { + memmove(dst, src, bsize_w * 4); + src -= l; + dst -= l; + } + } else { + for (int by = 0; by < bsize_h; by++) { + memmove(dst, src, bsize_w * 4); + src += l; + dst += l; + } + } + + count--; + } + } + break; + case 12: + osize = ((h + 3) / 4) * ((w + 3) / 4) + 7; + bits = gb->buffer; + di = 0; + bcode = v14 = 0; + if (bytestream2_get_bytes_left(gb) < osize >> 3) + return AVERROR_INVALIDDATA; + bytestream2_skip(gb, osize >> 3); + for (int x = 0; x < w; x += 4) { + for (int y = 0; y < h; y += 4) { + int astate = 0; + + if (bits[di >> 3] & (1 << (di & 7))) { + int codes = bytestream2_get_byte(gb); + + for (int count = 0; count < 4; count++) { + uint32_t *src = (uint32_t *)frame->data[0]; + size_t src_size = l * (h - 1) + (w - 1); + int nv, v, code = codes & 3; + + pos = x; + dy = y + count; + dst = (uint32_t *)frame->data[0] + pos + dy * l; + if (code & 1) + bcode = bytestream2_get_byte(gb); + if (code == 3) { + for (int j = 0; j < 4; j++) { + switch (bcode & 3) { + case 0: + break; + case 1: + if (dy < 1 && !pos) + return AVERROR_INVALIDDATA; + dst[0] = dst[-1]; + break; + case 2: + if (dy < 1) + return AVERROR_INVALIDDATA; + dst[0] = dst[-l]; + break; + case 3: + if (astate) { + nv = value >> 4; + } else { + value = bytestream2_get_byte(gb); + nv = value & 0xF; + } + astate ^= 1; + dst[0] = src[av_clip(l * (dy + s->mv1[nv][1]) + pos + + s->mv1[nv][0], 0, src_size)]; + break; + } + + bcode >>= 2; + dst++; + pos++; + } + } else if (code) { + if (code == 1) + v14 = bcode; + else + bcode = v14; + for (int j = 0; j < 4; j++) { + switch (bcode & 3) { + case 0: + break; + case 1: + if (dy < 1 && !pos) + return AVERROR_INVALIDDATA; + dst[0] = dst[-1]; + break; + case 2: + if (dy < 1) + return AVERROR_INVALIDDATA; + dst[0] = dst[-l]; + break; + case 3: + v = bytestream2_get_byte(gb); + if (v < 128) { + dst[0] = src[av_clip(l * (dy + s->mv0[v][1]) + pos + + s->mv0[v][0], 0, src_size)]; + } else { + dst[0] = ((v & 0x7F) << 17) | bytestream2_get_be16(gb); + } + break; + } + + bcode >>= 2; + dst++; + pos++; + } + } + + codes >>= 2; + } + } + + di++; + } + } + break; + default: + return AVERROR_INVALIDDATA; + } + } + + return AVERROR_INVALIDDATA; +} + +static int decode_rle(AVCodecContext *avctx, AVFrame *frame) +{ + ArgoContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + const int w = frame->width; + const int h = frame->height; + const int l = frame->linesize[0]; + uint8_t *dst = frame->data[0]; + int pos = 0, y = 0; + + while (bytestream2_get_bytes_left(gb) > 0) { + int count = bytestream2_get_byte(gb); + int pixel = bytestream2_get_byte(gb); + + if (!count) { + pos += pixel; + while (pos >= w) { + pos -= w; + y++; + if (y >= h) + return 0; + } + } else { + while (count > 0) { + dst[pos + y * l] = pixel; + count--; + pos++; + if (pos >= w) { + pos = 0; + y++; + if (y >= h) + return 0; + } + } + } + } + + return 0; +} + +static int decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + ArgoContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + AVFrame *frame = s->frame; + uint32_t chunk; + int ret; + + bytestream2_init(gb, avpkt->data, avpkt->size); + + if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0) + return ret; + + chunk = bytestream2_get_be32(gb); + switch (chunk) { + case MKBETAG('P', 'A', 'L', '8'): + for (int y = 0; y < frame->height; y++) + memset(frame->data[0] + y * frame->linesize[0], 0, frame->width * s->bpp); + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) + memset(frame->data[1], 0, AVPALETTE_SIZE); + return decode_pal8(avctx, s->pal); + case MKBETAG('M', 'A', 'D', '1'): + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) + ret = decode_mad1(avctx, frame); + else + ret = decode_mad1_24(avctx, frame); + break; + case MKBETAG('A', 'V', 'C', 'F'): + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { + s->key = 1; + ret = decode_avcf(avctx, frame); + break; + } + case MKBETAG('A', 'L', 'C', 'D'): + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { + s->key = 0; + ret = decode_alcd(avctx, frame); + break; + } + case MKBETAG('R', 'L', 'E', 'F'): + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { + s->key = 1; + ret = decode_rle(avctx, frame); + break; + } + case MKBETAG('R', 'L', 'E', 'D'): + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { + s->key = 0; + ret = decode_rle(avctx, frame); + break; + } + default: + av_log(avctx, AV_LOG_DEBUG, "unknown chunk 0x%X\n", chunk); + break; + } + + if (ret < 0) + return ret; + + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) + memcpy(frame->data[1], s->pal, AVPALETTE_SIZE); + + if ((ret = av_frame_ref(data, s->frame)) < 0) + return ret; + + frame->pict_type = s->key ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + frame->key_frame = s->key; + *got_frame = 1; + + return avpkt->size; +} + +static av_cold int decode_init(AVCodecContext *avctx) +{ + ArgoContext *s = avctx->priv_data; + + switch (avctx->bits_per_raw_sample) { + case 8: s->bpp = 1; + avctx->pix_fmt = AV_PIX_FMT_PAL8; break; + case 24: s->bpp = 4; + avctx->pix_fmt = AV_PIX_FMT_BGR0; break; + default: avpriv_request_sample(s, "depth == %u", avctx->bits_per_raw_sample); + return AVERROR_PATCHWELCOME; + } + + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + + for (int n = 0, i = -4; i < 4; i++) { + for (int j = -14; j < 2; j++) { + s->mv0[n][0] = j; + s->mv0[n++][1] = i; + } + } + + for (int n = 0, i = -5; i <= 1; i += 2) { + int j = -5; + + while (j <= 1) { + s->mv1[n][0] = j; + s->mv1[n++][1] = i; + j += 2; + } + } + + return 0; +} + +static void decode_flush(AVCodecContext *avctx) +{ + ArgoContext *s = avctx->priv_data; + + av_frame_unref(s->frame); +} + +static av_cold int decode_close(AVCodecContext *avctx) +{ + ArgoContext *s = avctx->priv_data; + + av_frame_free(&s->frame); + + return 0; +} + +AVCodec ff_argo_decoder = { + .name = "argo", + .long_name = NULL_IF_CONFIG_SMALL("Argonaut Games Video"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_ARGO, + .priv_data_size = sizeof(ArgoContext), + .init = decode_init, + .decode = decode_frame, + .flush = decode_flush, + .close = decode_close, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, +}; diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index c6be81415..c4ab93aee 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -5,8 +5,7 @@ OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_init_arm.o \ arm/ac3dsp_arm.o OBJS-$(CONFIG_AUDIODSP) += arm/audiodsp_init_arm.o OBJS-$(CONFIG_BLOCKDSP) += arm/blockdsp_init_arm.o -OBJS-$(CONFIG_FFT) += arm/fft_init_arm.o \ - arm/fft_fixed_init_arm.o +OBJS-$(CONFIG_FFT) += arm/fft_init_arm.o OBJS-$(CONFIG_FLACDSP) += arm/flacdsp_init_arm.o \ arm/flacdsp_arm.o OBJS-$(CONFIG_FMTCONVERT) += arm/fmtconvert_init_arm.o @@ -108,8 +107,7 @@ NEON-OBJS-$(CONFIG_AUDIODSP) += arm/audiodsp_init_neon.o \ arm/int_neon.o NEON-OBJS-$(CONFIG_BLOCKDSP) += arm/blockdsp_init_neon.o \ arm/blockdsp_neon.o -NEON-OBJS-$(CONFIG_FFT) += arm/fft_neon.o \ - arm/fft_fixed_neon.o +NEON-OBJS-$(CONFIG_FFT) += arm/fft_neon.o NEON-OBJS-$(CONFIG_FMTCONVERT) += arm/fmtconvert_neon.o NEON-OBJS-$(CONFIG_G722DSP) += arm/g722dsp_neon.o NEON-OBJS-$(CONFIG_H264CHROMA) += arm/h264cmc_neon.o @@ -123,8 +121,7 @@ NEON-OBJS-$(CONFIG_HPELDSP) += arm/hpeldsp_init_neon.o \ NEON-OBJS-$(CONFIG_IDCTDSP) += arm/idctdsp_init_neon.o \ arm/idctdsp_neon.o \ arm/simple_idct_neon.o -NEON-OBJS-$(CONFIG_MDCT) += arm/mdct_neon.o \ - arm/mdct_fixed_neon.o +NEON-OBJS-$(CONFIG_MDCT) += arm/mdct_neon.o NEON-OBJS-$(CONFIG_MPEGVIDEO) += arm/mpegvideo_neon.o NEON-OBJS-$(CONFIG_PIXBLOCKDSP) += arm/pixblockdsp_neon.o NEON-OBJS-$(CONFIG_RDFT) += arm/rdft_neon.o diff --git a/libavcodec/arm/ac3dsp_init_arm.c b/libavcodec/arm/ac3dsp_init_arm.c index a3c32ff40..9217a7d0c 100644 --- a/libavcodec/arm/ac3dsp_init_arm.c +++ b/libavcodec/arm/ac3dsp_init_arm.c @@ -26,13 +26,8 @@ #include "config.h" void ff_ac3_exponent_min_neon(uint8_t *exp, int num_reuse_blocks, int nb_coefs); -int ff_ac3_max_msb_abs_int16_neon(const int16_t *src, int len); -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, @@ -61,12 +56,8 @@ av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact) if (have_neon(cpu_flags)) { c->ac3_exponent_min = ff_ac3_exponent_min_neon; - c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_neon; - c->ac3_lshift_int16 = ff_ac3_lshift_int16_neon; - 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/libavcodec/arm/neontest.c b/libavcodec/arm/neontest.c index f9c0dbf12..d1ede4955 100644 --- a/libavcodec/arm/neontest.c +++ b/libavcodec/arm/neontest.c @@ -29,6 +29,7 @@ wrap(avcodec_open2(AVCodecContext *avctx, testneonclobbers(avcodec_open2, avctx, codec, options); } +#if FF_API_OLD_ENCDEC wrap(avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, @@ -47,15 +48,6 @@ wrap(avcodec_decode_video2(AVCodecContext *avctx, got_picture_ptr, avpkt); } -wrap(avcodec_decode_subtitle2(AVCodecContext *avctx, - AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt)) -{ - testneonclobbers(avcodec_decode_subtitle2, avctx, sub, - got_sub_ptr, avpkt); -} - wrap(avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, @@ -65,6 +57,22 @@ wrap(avcodec_encode_audio2(AVCodecContext *avctx, got_packet_ptr); } +wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr)) +{ + testneonclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr); +} +#endif + +wrap(avcodec_decode_subtitle2(AVCodecContext *avctx, + AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt)) +{ + testneonclobbers(avcodec_decode_subtitle2, avctx, sub, + got_sub_ptr, avpkt); +} + wrap(avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub)) @@ -72,12 +80,6 @@ wrap(avcodec_encode_subtitle(AVCodecContext *avctx, testneonclobbers(avcodec_encode_subtitle, avctx, buf, buf_size, sub); } -wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, - const AVFrame *frame, int *got_packet_ptr)) -{ - testneonclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr); -} - wrap(avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)) { testneonclobbers(avcodec_send_packet, avctx, avpkt); diff --git a/libavcodec/arm/sbcdsp_init_arm.c b/libavcodec/arm/sbcdsp_init_arm.c index 6bf7e729e..b8fa5a35a 100644 --- a/libavcodec/arm/sbcdsp_init_arm.c +++ b/libavcodec/arm/sbcdsp_init_arm.c @@ -30,6 +30,7 @@ */ #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/arm/cpu.h" #include "libavcodec/sbcdsp.h" diff --git a/libavcodec/arm/vp9dsp_init_16bpp_arm_template.c b/libavcodec/arm/vp9dsp_init_16bpp_arm_template.c index 1b0007859..b0907094c 100644 --- a/libavcodec/arm/vp9dsp_init_16bpp_arm_template.c +++ b/libavcodec/arm/vp9dsp_init_16bpp_arm_template.c @@ -22,6 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/arm/cpu.h" #include "vp9dsp_init.h" diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c index cb7f48d5c..b3911f7e4 100644 --- a/libavcodec/arm/vp9dsp_init_arm.c +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -22,6 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/arm/cpu.h" #include "libavcodec/vp9dsp.h" #include "vp9dsp_init.h" diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c index c2c388d9f..189272bbd 100644 --- a/libavcodec/ass_split.c +++ b/libavcodec/ass_split.c @@ -376,7 +376,7 @@ ASSSplitContext *ff_ass_split(const char *buf) ASSSplitContext *ctx = av_mallocz(sizeof(*ctx)); if (!ctx) return NULL; - if (buf && !memcmp(buf, "\xef\xbb\xbf", 3)) // Skip UTF-8 BOM header + if (buf && !strncmp(buf, "\xef\xbb\xbf", 3)) // Skip UTF-8 BOM header buf += 3; ctx->current_section = -1; if (ass_split(ctx, buf) < 0) { diff --git a/libavcodec/asv.c b/libavcodec/asv.c index 14fdf7333..dcae90982 100644 --- a/libavcodec/asv.c +++ b/libavcodec/asv.c @@ -53,31 +53,37 @@ const uint8_t ff_asv_level_tab[7][2] = { }; const uint8_t ff_asv_dc_ccp_tab[8][2] = { - { 0x1, 2 }, { 0xD, 4 }, { 0xF, 4 }, { 0xC, 4 }, - { 0x5, 3 }, { 0xE, 4 }, { 0x4, 3 }, { 0x0, 2 }, + { 0x2, 2 }, { 0xB, 4 }, { 0xF, 4 }, { 0x3, 4 }, + { 0x5, 3 }, { 0x7, 4 }, { 0x1, 3 }, { 0x0, 2 }, }; const uint8_t ff_asv_ac_ccp_tab[16][2] = { - { 0x00, 2 }, { 0x3B, 6 }, { 0x0A, 4 }, { 0x3A, 6 }, - { 0x02, 3 }, { 0x39, 6 }, { 0x3C, 6 }, { 0x38, 6 }, - { 0x03, 3 }, { 0x3D, 6 }, { 0x08, 4 }, { 0x1F, 5 }, - { 0x09, 4 }, { 0x0B, 4 }, { 0x0D, 4 }, { 0x0C, 4 }, + { 0x00, 2 }, { 0x37, 6 }, { 0x05, 4 }, { 0x17, 6 }, + { 0x02, 3 }, { 0x27, 6 }, { 0x0F, 6 }, { 0x07, 6 }, + { 0x06, 3 }, { 0x2F, 6 }, { 0x01, 4 }, { 0x1F, 5 }, + { 0x09, 4 }, { 0x0D, 4 }, { 0x0B, 4 }, { 0x03, 4 }, }; -const uint8_t ff_asv2_level_tab[63][2] = { - { 0x3F, 10 }, { 0x2F, 10 }, { 0x37, 10 }, { 0x27, 10 }, { 0x3B, 10 }, { 0x2B, 10 }, { 0x33, 10 }, { 0x23, 10 }, - { 0x3D, 10 }, { 0x2D, 10 }, { 0x35, 10 }, { 0x25, 10 }, { 0x39, 10 }, { 0x29, 10 }, { 0x31, 10 }, { 0x21, 10 }, - { 0x1F, 8 }, { 0x17, 8 }, { 0x1B, 8 }, { 0x13, 8 }, { 0x1D, 8 }, { 0x15, 8 }, { 0x19, 8 }, { 0x11, 8 }, - { 0x0F, 6 }, { 0x0B, 6 }, { 0x0D, 6 }, { 0x09, 6 }, - { 0x07, 4 }, { 0x05, 4 }, - { 0x03, 2 }, - { 0x00, 5 }, - { 0x02, 2 }, - { 0x04, 4 }, { 0x06, 4 }, - { 0x08, 6 }, { 0x0C, 6 }, { 0x0A, 6 }, { 0x0E, 6 }, - { 0x10, 8 }, { 0x18, 8 }, { 0x14, 8 }, { 0x1C, 8 }, { 0x12, 8 }, { 0x1A, 8 }, { 0x16, 8 }, { 0x1E, 8 }, - { 0x20, 10 }, { 0x30, 10 }, { 0x28, 10 }, { 0x38, 10 }, { 0x24, 10 }, { 0x34, 10 }, { 0x2C, 10 }, { 0x3C, 10 }, - { 0x22, 10 }, { 0x32, 10 }, { 0x2A, 10 }, { 0x3A, 10 }, { 0x26, 10 }, { 0x36, 10 }, { 0x2E, 10 }, { 0x3E, 10 }, +const uint16_t ff_asv2_level_tab[63][2] = { + { 0x3F0, 10 }, { 0x3D0, 10 }, { 0x3B0, 10 }, { 0x390, 10 }, { 0x370, 10 }, + { 0x350, 10 }, { 0x330, 10 }, { 0x310, 10 }, { 0x2F0, 10 }, { 0x2D0, 10 }, + { 0x2B0, 10 }, { 0x290, 10 }, { 0x270, 10 }, { 0x250, 10 }, { 0x230, 10 }, + { 0x210, 10 }, + { 0x0F8, 8 }, { 0x0E8, 8 }, { 0x0D8, 8 }, { 0x0C8, 8 }, { 0x0B8, 8 }, + { 0x0A8, 8 }, { 0x098, 8 }, { 0x088, 8 }, + { 0x03C, 6 }, { 0x034, 6 }, { 0x02C, 6 }, { 0x024, 6 }, + { 0x00E, 4 }, { 0x00A, 4 }, + { 0x003, 2 }, + { 0x000, 5 }, + { 0x001, 2 }, + { 0x002, 4 }, { 0x006, 4 }, + { 0x004, 6 }, { 0x00C, 6 }, { 0x014, 6 }, { 0x01C, 6 }, + { 0x008, 8 }, { 0x018, 8 }, { 0x028, 8 }, { 0x038, 8 }, { 0x048, 8 }, + { 0x058, 8 }, { 0x068, 8 }, { 0x078, 8 }, + { 0x010, 10 }, { 0x030, 10 }, { 0x050, 10 }, { 0x070, 10 }, { 0x090, 10 }, + { 0x0B0, 10 }, { 0x0D0, 10 }, { 0x0F0, 10 }, { 0x110, 10 }, { 0x130, 10 }, + { 0x150, 10 }, { 0x170, 10 }, { 0x190, 10 }, { 0x1B0, 10 }, { 0x1D0, 10 }, + { 0x1F0, 10 } }; av_cold void ff_asv_common_init(AVCodecContext *avctx) diff --git a/libavcodec/asv.h b/libavcodec/asv.h index a1366b6fe..269bbe7c1 100644 --- a/libavcodec/asv.h +++ b/libavcodec/asv.h @@ -28,7 +28,7 @@ #include -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "blockdsp.h" @@ -66,7 +66,7 @@ extern const uint8_t ff_asv_ccp_tab[17][2]; extern const uint8_t ff_asv_level_tab[7][2]; extern const uint8_t ff_asv_dc_ccp_tab[8][2]; extern const uint8_t ff_asv_ac_ccp_tab[16][2]; -extern const uint8_t ff_asv2_level_tab[63][2]; +extern const uint16_t ff_asv2_level_tab[63][2]; void ff_asv_common_init(AVCodecContext *avctx); diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c index 9a11446f5..a72e11b84 100644 --- a/libavcodec/asvdec.c +++ b/libavcodec/asvdec.c @@ -25,16 +25,19 @@ #include "libavutil/attributes.h" #include "libavutil/mem.h" +#include "libavutil/thread.h" #include "asv.h" #include "avcodec.h" #include "blockdsp.h" #include "idctdsp.h" #include "internal.h" -#include "mathops.h" #include "mpeg12data.h" -#define VLC_BITS 6 +#define CCP_VLC_BITS 5 +#define DC_CCP_VLC_BITS 4 +#define AC_CCP_VLC_BITS 6 +#define ASV1_LEVEL_VLC_BITS 4 #define ASV2_LEVEL_VLC_BITS 10 static VLC ccp_vlc; @@ -43,40 +46,28 @@ static VLC dc_ccp_vlc; static VLC ac_ccp_vlc; static VLC asv2_level_vlc; -static av_cold void init_vlcs(ASV1Context *a) +static av_cold void init_vlcs(void) { - static int done = 0; - - if (!done) { - done = 1; - - INIT_VLC_STATIC(&ccp_vlc, VLC_BITS, 17, - &ff_asv_ccp_tab[0][1], 2, 1, - &ff_asv_ccp_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&dc_ccp_vlc, VLC_BITS, 8, - &ff_asv_dc_ccp_tab[0][1], 2, 1, - &ff_asv_dc_ccp_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&ac_ccp_vlc, VLC_BITS, 16, - &ff_asv_ac_ccp_tab[0][1], 2, 1, - &ff_asv_ac_ccp_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&level_vlc, VLC_BITS, 7, - &ff_asv_level_tab[0][1], 2, 1, - &ff_asv_level_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63, - &ff_asv2_level_tab[0][1], 2, 1, - &ff_asv2_level_tab[0][0], 2, 1, 1024); - } -} - -// FIXME write a reversed bitstream reader to avoid the double reverse -static inline int asv2_get_bits(GetBitContext *gb, int n) -{ - return ff_reverse[get_bits(gb, n) << (8 - n)]; + INIT_VLC_STATIC(&ccp_vlc, CCP_VLC_BITS, 17, + &ff_asv_ccp_tab[0][1], 2, 1, + &ff_asv_ccp_tab[0][0], 2, 1, 32); + INIT_LE_VLC_STATIC(&dc_ccp_vlc, DC_CCP_VLC_BITS, 8, + &ff_asv_dc_ccp_tab[0][1], 2, 1, + &ff_asv_dc_ccp_tab[0][0], 2, 1, 16); + INIT_LE_VLC_STATIC(&ac_ccp_vlc, AC_CCP_VLC_BITS, 16, + &ff_asv_ac_ccp_tab[0][1], 2, 1, + &ff_asv_ac_ccp_tab[0][0], 2, 1, 64); + INIT_VLC_STATIC(&level_vlc, ASV1_LEVEL_VLC_BITS, 7, + &ff_asv_level_tab[0][1], 2, 1, + &ff_asv_level_tab[0][0], 2, 1, 16); + INIT_LE_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63, + &ff_asv2_level_tab[0][1], 4, 2, + &ff_asv2_level_tab[0][0], 4, 2, 1024); } static inline int asv1_get_level(GetBitContext *gb) { - int code = get_vlc2(gb, level_vlc.table, VLC_BITS, 1); + int code = get_vlc2(gb, level_vlc.table, ASV1_LEVEL_VLC_BITS, 1); if (code == 3) return get_sbits(gb, 8); @@ -84,12 +75,31 @@ static inline int asv1_get_level(GetBitContext *gb) return code - 3; } +// get_vlc2() is big-endian in this file +static inline int asv2_get_vlc2(GetBitContext *gb, VLC_TYPE (*table)[2], int bits) +{ + unsigned int index; + int code, n; + + OPEN_READER(re, gb); + UPDATE_CACHE_LE(re, gb); + + index = SHOW_UBITS_LE(re, gb, bits); + code = table[index][0]; + n = table[index][1]; + LAST_SKIP_BITS(re, gb, n); + + CLOSE_READER(re, gb); + + return code; +} + static inline int asv2_get_level(GetBitContext *gb) { - int code = get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1); + int code = asv2_get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS); if (code == 31) - return (int8_t) asv2_get_bits(gb, 8); + return (int8_t) get_bits_le(gb, 8); else return code - 31; } @@ -101,7 +111,7 @@ static inline int asv1_decode_block(ASV1Context *a, int16_t block[64]) block[0] = 8 * get_bits(&a->gb, 8); for (i = 0; i < 11; i++) { - const int ccp = get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1); + const int ccp = get_vlc2(&a->gb, ccp_vlc.table, CCP_VLC_BITS, 1); if (ccp) { if (ccp == 16) @@ -129,11 +139,11 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64]) { int i, count, ccp; - count = asv2_get_bits(&a->gb, 4); + count = get_bits_le(&a->gb, 4); - block[0] = 8 * asv2_get_bits(&a->gb, 8); + block[0] = 8 * get_bits_le(&a->gb, 8); - ccp = get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1); + ccp = asv2_get_vlc2(&a->gb, dc_ccp_vlc.table, DC_CCP_VLC_BITS); if (ccp) { if (ccp & 4) block[a->scantable.permutated[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4; @@ -144,7 +154,7 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64]) } for (i = 1; i < count + 1; i++) { - const int ccp = get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1); + const int ccp = asv2_get_vlc2(&a->gb, ac_ccp_vlc.table, AC_CCP_VLC_BITS); if (ccp) { if (ccp & 8) @@ -218,21 +228,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; - av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, - buf_size); - if (!a->bitstream_buffer) - return AVERROR(ENOMEM); - if (avctx->codec_id == AV_CODEC_ID_ASV1) { + av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, + buf_size); + if (!a->bitstream_buffer) + return AVERROR(ENOMEM); + a->bbdsp.bswap_buf((uint32_t *) a->bitstream_buffer, (const uint32_t *) buf, buf_size / 4); + ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size); } else { - int i; - for (i = 0; i < buf_size; i++) - a->bitstream_buffer[i] = ff_reverse[buf[i]]; + ret = init_get_bits8_le(&a->gb, buf, buf_size); } - - init_get_bits(&a->gb, a->bitstream_buffer, buf_size * 8); + if (ret < 0) + return ret; for (mb_y = 0; mb_y < a->mb_height2; mb_y++) { for (mb_x = 0; mb_x < a->mb_width2; mb_x++) { @@ -272,6 +281,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, static av_cold int decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; ASV1Context *const a = avctx->priv_data; const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2; int i; @@ -283,7 +293,6 @@ static av_cold int decode_init(AVCodecContext *avctx) ff_asv_common_init(avctx); ff_blockdsp_init(&a->bdsp, avctx); ff_idctdsp_init(&a->idsp, avctx); - init_vlcs(a); ff_init_scantable(a->idsp.idct_permutation, &a->scantable, ff_asv_scantab); avctx->pix_fmt = AV_PIX_FMT_YUV420P; @@ -302,6 +311,8 @@ static av_cold int decode_init(AVCodecContext *avctx) a->inv_qscale; } + ff_thread_once(&init_static_once, init_vlcs); + return 0; } @@ -326,6 +337,7 @@ AVCodec ff_asv1_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif @@ -337,8 +349,8 @@ AVCodec ff_asv2_decoder = { .id = AV_CODEC_ID_ASV2, .priv_data_size = sizeof(ASV1Context), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif diff --git a/libavcodec/asvenc.c b/libavcodec/asvenc.c index c2c940f36..718ffa183 100644 --- a/libavcodec/asvenc.c +++ b/libavcodec/asvenc.c @@ -32,14 +32,8 @@ #include "dct.h" #include "fdctdsp.h" #include "internal.h" -#include "mathops.h" #include "mpeg12data.h" -static inline void asv2_put_bits(PutBitContext *pb, int n, int v) -{ - put_bits(pb, n, ff_reverse[v << (8 - n)]); -} - static inline void asv1_put_level(PutBitContext *pb, int level) { unsigned int index = level + 3; @@ -47,7 +41,7 @@ static inline void asv1_put_level(PutBitContext *pb, int level) if (index <= 6) { put_bits(pb, ff_asv_level_tab[index][1], ff_asv_level_tab[index][0]); } else { - put_bits(pb, ff_asv_level_tab[3][1], ff_asv_level_tab[3][0]); + put_bits(pb, 3, 0); /* Escape code */ put_sbits(pb, 8, level); } } @@ -57,14 +51,14 @@ static inline void asv2_put_level(ASV1Context *a, PutBitContext *pb, int level) unsigned int index = level + 31; if (index <= 62) { - put_bits(pb, ff_asv2_level_tab[index][1], ff_asv2_level_tab[index][0]); + put_bits_le(pb, ff_asv2_level_tab[index][1], ff_asv2_level_tab[index][0]); } else { - put_bits(pb, ff_asv2_level_tab[31][1], ff_asv2_level_tab[31][0]); + put_bits_le(pb, 5, 0); /* Escape code */ if (level < -128 || level > 127) { av_log(a->avctx, AV_LOG_WARNING, "Clipping level %d, increase qscale\n", level); level = av_clip_int8(level); } - asv2_put_bits(pb, 8, level & 0xFF); + put_bits_le(pb, 8, level & 0xFF); } } @@ -95,7 +89,7 @@ static inline void asv1_encode_block(ASV1Context *a, int16_t block[64]) if (ccp) { for (; nc_count; nc_count--) - put_bits(&a->pb, ff_asv_ccp_tab[0][1], ff_asv_ccp_tab[0][0]); + put_bits(&a->pb, 2, 2); /* Skip */ put_bits(&a->pb, ff_asv_ccp_tab[ccp][1], ff_asv_ccp_tab[ccp][0]); @@ -111,7 +105,7 @@ static inline void asv1_encode_block(ASV1Context *a, int16_t block[64]) nc_count++; } } - put_bits(&a->pb, ff_asv_ccp_tab[16][1], ff_asv_ccp_tab[16][0]); + put_bits(&a->pb, 5, 0xF); /* End of block */ } static inline void asv2_encode_block(ASV1Context *a, int16_t block[64]) @@ -127,8 +121,8 @@ static inline void asv2_encode_block(ASV1Context *a, int16_t block[64]) count >>= 2; - asv2_put_bits(&a->pb, 4, count); - asv2_put_bits(&a->pb, 8, (block[0] + 32) >> 6); + put_bits_le(&a->pb, 4, count); + put_bits_le(&a->pb, 8, (block[0] + 32) >> 6); block[0] = 0; for (i = 0; i <= count; i++) { @@ -150,9 +144,9 @@ static inline void asv2_encode_block(ASV1Context *a, int16_t block[64]) av_assert2(i || ccp < 8); if (i) - put_bits(&a->pb, ff_asv_ac_ccp_tab[ccp][1], ff_asv_ac_ccp_tab[ccp][0]); + put_bits_le(&a->pb, ff_asv_ac_ccp_tab[ccp][1], ff_asv_ac_ccp_tab[ccp][0]); else - put_bits(&a->pb, ff_asv_dc_ccp_tab[ccp][1], ff_asv_dc_ccp_tab[ccp][0]); + put_bits_le(&a->pb, ff_asv_dc_ccp_tab[ccp][1], ff_asv_dc_ccp_tab[ccp][0]); if (ccp) { if (ccp & 8) @@ -291,19 +285,16 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } emms_c(); - avpriv_align_put_bits(&a->pb); - while (put_bits_count(&a->pb) & 31) - put_bits(&a->pb, 8, 0); - - size = put_bits_count(&a->pb) / 32; + if (avctx->codec_id == AV_CODEC_ID_ASV1) + flush_put_bits(&a->pb); + else + flush_put_bits_le(&a->pb); + AV_WN32(put_bits_ptr(&a->pb), 0); + size = (put_bits_count(&a->pb) + 31) / 32; if (avctx->codec_id == AV_CODEC_ID_ASV1) { a->bbdsp.bswap_buf((uint32_t *) pkt->data, (uint32_t *) pkt->data, size); - } else { - int i; - for (i = 0; i < 4 * size; i++) - pkt->data[i] = ff_reverse[pkt->data[i]]; } pkt->size = size * 4; diff --git a/libavcodec/atrac.c b/libavcodec/atrac.c index 12e8997db..bf9878be4 100644 --- a/libavcodec/atrac.c +++ b/libavcodec/atrac.c @@ -30,6 +30,8 @@ #include #include +#include "libavutil/thread.h" + #include "avcodec.h" #include "atrac.h" @@ -45,22 +47,23 @@ static const float qmf_48tap_half[24] = { -0.043596379, -0.099384367, 0.13207909, 0.46424159 }; -av_cold void ff_atrac_generate_tables(void) +static av_cold void atrac_generate_tables(void) { - int i; - float s; - /* Generate scale factors */ - if (!ff_atrac_sf_table[63]) - for (i=0 ; i<64 ; i++) - ff_atrac_sf_table[i] = pow(2.0, (i - 15) / 3.0); + for (int i = 0; i < 64; i++) + ff_atrac_sf_table[i] = pow(2.0, (i - 15) / 3.0); /* Generate the QMF window. */ - if (!qmf_window[47]) - for (i=0 ; i<24; i++) { - s = qmf_48tap_half[i] * 2.0; - qmf_window[i] = qmf_window[47 - i] = s; - } + for (int i = 0; i < 24; i++) { + float s = qmf_48tap_half[i] * 2.0; + qmf_window[i] = qmf_window[47 - i] = s; + } +} + +av_cold void ff_atrac_generate_tables(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, atrac_generate_tables); } av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index a8c8c91bc..54f9b1c2d 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -33,6 +33,8 @@ #include #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "get_bits.h" #include "fft.h" @@ -80,7 +82,8 @@ typedef struct AT1Ctx { DECLARE_ALIGNED(32, float, high)[512]; float* bands[3]; FFTContext mdct_ctx[3]; - AVFloatDSPContext *fdsp; + void (*vector_fmul_window)(float *dst, const float *src0, + const float *src1, const float *win, int len); } AT1Ctx; /** size of the transform in samples in the long mode for each QMF band */ @@ -140,8 +143,8 @@ static int at1_imdct_block(AT1SUCtx* su, AT1Ctx *q) at1_imdct(q, &q->spec[pos], &su->spectrum[0][ref_pos + start_pos], nbits, band_num); /* overlap and window */ - q->fdsp->vector_fmul_window(&q->bands[band_num][start_pos], prev_buf, - &su->spectrum[0][ref_pos + start_pos], ff_sine_32, 16); + q->vector_fmul_window(&q->bands[band_num][start_pos], prev_buf, + &su->spectrum[0][ref_pos + start_pos], ff_sine_32, 16); prev_buf = &su->spectrum[0][ref_pos+start_pos + 16]; start_pos += block_size; @@ -324,8 +327,6 @@ static av_cold int atrac1_decode_end(AVCodecContext * avctx) ff_mdct_end(&q->mdct_ctx[1]); ff_mdct_end(&q->mdct_ctx[2]); - av_freep(&q->fdsp); - return 0; } @@ -333,6 +334,7 @@ static av_cold int atrac1_decode_end(AVCodecContext * avctx) static av_cold int atrac1_decode_init(AVCodecContext *avctx) { AT1Ctx *q = avctx->priv_data; + AVFloatDSPContext *fdsp; int ret; avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; @@ -353,7 +355,6 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) (ret = ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15))) || (ret = ff_mdct_init(&q->mdct_ctx[2], 9, 1, -1.0/ (1 << 15)))) { av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); - atrac1_decode_end(avctx); return ret; } @@ -361,7 +362,11 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) ff_atrac_generate_tables(); - q->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!fdsp) + return AVERROR(ENOMEM); + q->vector_fmul_window = fdsp->vector_fmul_window; + av_free(fdsp); q->bands[0] = q->low; q->bands[1] = q->mid; @@ -389,4 +394,5 @@ AVCodec ff_atrac1_decoder = { .capabilities = AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 067aa23f1..37ccbcc94 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -39,6 +39,9 @@ #include "libavutil/attributes.h" #include "libavutil/float_dsp.h" #include "libavutil/libm.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" + #include "avcodec.h" #include "bytestream.h" #include "fft.h" @@ -58,6 +61,8 @@ #define SAMPLES_PER_FRAME 1024 #define MDCT_SIZE 512 +#define ATRAC3_VLC_BITS 8 + typedef struct GainBlock { AtracGainInfo g_block[4]; } GainBlock; @@ -111,11 +116,12 @@ typedef struct ATRAC3Context { AtracGCContext gainc_ctx; FFTContext mdct_ctx; - AVFloatDSPContext *fdsp; + void (*vector_fmul)(float *dst, const float *src0, const float *src1, + int len); } ATRAC3Context; static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE]; -static VLC_TYPE atrac3_vlc_table[4096][2]; +static VLC_TYPE atrac3_vlc_table[7 * 1 << ATRAC3_VLC_BITS][2]; static VLC spectral_coeff_tab[7]; /** @@ -144,7 +150,7 @@ static void imlt(ATRAC3Context *q, float *input, float *output, int odd_band) q->mdct_ctx.imdct_calc(&q->mdct_ctx, output, input); /* Perform windowing on the output. */ - q->fdsp->vector_fmul(output, output, mdct_window, MDCT_SIZE); + q->vector_fmul(output, output, mdct_window, MDCT_SIZE); } /* @@ -194,7 +200,6 @@ static av_cold int atrac3_decode_close(AVCodecContext *avctx) av_freep(&q->units); av_freep(&q->decoded_bytes_buffer); - av_freep(&q->fdsp); ff_mdct_end(&q->mdct_ctx); @@ -244,18 +249,13 @@ static void read_quant_spectral_coeffs(GetBitContext *gb, int selector, /* variable length coding (VLC) */ if (selector != 1) { for (i = 0; i < num_codes; i++) { - huff_symb = get_vlc2(gb, spectral_coeff_tab[selector-1].table, - spectral_coeff_tab[selector-1].bits, 3); - huff_symb += 1; - code = huff_symb >> 1; - if (huff_symb & 1) - code = -code; - mantissas[i] = code; + mantissas[i] = get_vlc2(gb, spectral_coeff_tab[selector-1].table, + ATRAC3_VLC_BITS, 1); } } else { for (i = 0; i < num_codes; i++) { huff_symb = get_vlc2(gb, spectral_coeff_tab[selector - 1].table, - spectral_coeff_tab[selector - 1].bits, 3); + ATRAC3_VLC_BITS, 1); mantissas[i * 2 ] = mantissa_vlc_tab[huff_symb * 2 ]; mantissas[i * 2 + 1] = mantissa_vlc_tab[huff_symb * 2 + 1]; } @@ -851,6 +851,8 @@ static int atrac3al_decode_frame(AVCodecContext *avctx, void *data, static av_cold void atrac3_init_static_data(void) { + VLC_TYPE (*table)[2] = atrac3_vlc_table; + const uint8_t (*hufftabs)[2] = atrac3_hufftabs; int i; init_imdct_window(); @@ -858,32 +860,31 @@ static av_cold void atrac3_init_static_data(void) /* Initialize the VLC tables. */ for (i = 0; i < 7; i++) { - spectral_coeff_tab[i].table = &atrac3_vlc_table[atrac3_vlc_offs[i]]; - spectral_coeff_tab[i].table_allocated = atrac3_vlc_offs[i + 1] - - atrac3_vlc_offs[i ]; - init_vlc(&spectral_coeff_tab[i], 9, huff_tab_sizes[i], - huff_bits[i], 1, 1, - huff_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + spectral_coeff_tab[i].table = table; + spectral_coeff_tab[i].table_allocated = 256; + ff_init_vlc_from_lengths(&spectral_coeff_tab[i], ATRAC3_VLC_BITS, huff_tab_sizes[i], + &hufftabs[0][1], 2, + &hufftabs[0][0], 2, 1, + -31, INIT_VLC_USE_NEW_STATIC, NULL); + hufftabs += huff_tab_sizes[i]; + table += 256; } } static av_cold int atrac3_decode_init(AVCodecContext *avctx) { - static int static_init_done; + static AVOnce init_static_once = AV_ONCE_INIT; int i, js_pair, ret; int version, delay, samples_per_frame, frame_factor; const uint8_t *edata_ptr = avctx->extradata; ATRAC3Context *q = avctx->priv_data; + AVFloatDSPContext *fdsp; if (avctx->channels < MIN_CHANNELS || avctx->channels > MAX_CHANNELS) { av_log(avctx, AV_LOG_ERROR, "Channel configuration error!\n"); return AVERROR(EINVAL); } - if (!static_init_done) - atrac3_init_static_data(); - static_init_done = 1; - /* Take care of the codec-specific extradata. */ if (avctx->codec_id == AV_CODEC_ID_ATRAC3AL) { version = 4; @@ -964,7 +965,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - if (avctx->block_align > 1024 || avctx->block_align <= 0) + if (avctx->block_align > 4096 || avctx->block_align <= 0) return AVERROR(EINVAL); q->decoded_bytes_buffer = av_mallocz(FFALIGN(avctx->block_align, 4) + @@ -977,7 +978,6 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) /* initialize the MDCT transform */ if ((ret = ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768)) < 0) { av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); - av_freep(&q->decoded_bytes_buffer); return ret; } @@ -998,13 +998,17 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) } ff_atrac_init_gain_compensation(&q->gainc_ctx, 4, 3); - q->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!fdsp) + return AVERROR(ENOMEM); + q->vector_fmul = fdsp->vector_fmul; + av_free(fdsp); q->units = av_mallocz_array(avctx->channels, sizeof(*q->units)); - if (!q->units || !q->fdsp) { - atrac3_decode_close(avctx); + if (!q->units) return AVERROR(ENOMEM); - } + + ff_thread_once(&init_static_once, atrac3_init_static_data); return 0; } @@ -1021,6 +1025,7 @@ AVCodec ff_atrac3_decoder = { .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; AVCodec ff_atrac3al_decoder = { @@ -1035,4 +1040,5 @@ AVCodec ff_atrac3al_decoder = { .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/atrac3data.h b/libavcodec/atrac3data.h index 5d91274f4..d050c0f38 100644 --- a/libavcodec/atrac3data.h +++ b/libavcodec/atrac3data.h @@ -32,81 +32,47 @@ /* VLC tables */ -static const uint8_t huffcode1[9] = { - 0x0, 0x4, 0x5, 0xC, 0xD, 0x1C, 0x1D, 0x1E, 0x1F -}; - -static const uint8_t huffbits1[9] = { 1, 3, 3, 4, 4, 5, 5, 5, 5 }; - -static const uint8_t huffcode2[5] = { 0x0, 0x4, 0x5, 0x6, 0x7 }; - -static const uint8_t huffbits2[5] = { 1, 3, 3, 3, 3 }; - -static const uint8_t huffcode3[7] = { 0x0, 0x4, 0x5, 0xC, 0xD, 0xE, 0xF }; - -static const uint8_t huffbits3[7] = { 1, 3, 3, 4, 4, 4, 4 }; - -static const uint8_t huffcode4[9] = { - 0x0, 0x4, 0x5, 0xC, 0xD, 0x1C, 0x1D, 0x1E, 0x1F -}; - -static const uint8_t huffbits4[9] = { 1, 3, 3, 4, 4, 5, 5, 5, 5 }; - -static const uint8_t huffcode5[15] = { - 0x00, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x1C, - 0x1D, 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x0D -}; - -static const uint8_t huffbits5[15] = { - 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 4, 4 -}; - -static const uint8_t huffcode6[31] = { - 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x14, - 0x15, 0x16, 0x17, 0x18, 0x19, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x78, 0x79, 0x7A, - 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x08, 0x09 -}; - -static const uint8_t huffbits6[31] = { - 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4 -}; - -static const uint8_t huffcode7[63] = { - 0x00, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x24, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, - 0x31, 0x32, 0x33, 0x68, 0x69, 0x6A, 0x6B, 0x6C, - 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, - 0x75, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, - 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, - 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x02, 0x03 -}; - -static const uint8_t huffbits7[63] = { - 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4 +static const uint8_t atrac3_hufftabs[][2] = { + /* Spectral coefficient 1 - 9 entries */ + { 31, 1 }, { 32, 3 }, { 33, 3 }, { 34, 4 }, { 35, 4 }, + { 36, 5 }, { 37, 5 }, { 38, 5 }, { 39, 5 }, + /* Spectral coefficient 2 - 5 entries */ + { 31, 1 }, { 32, 3 }, { 30, 3 }, { 33, 3 }, { 29, 3 }, + /* Spectral coefficient 3 - 7 entries */ + { 31, 1 }, { 32, 3 }, { 30, 3 }, { 33, 4 }, + { 29, 4 }, { 34, 4 }, { 28, 4 }, + /* Spectral coefficient 4 - 9 entries */ + { 31, 1 }, { 32, 3 }, { 30, 3 }, { 33, 4 }, { 29, 4 }, + { 34, 5 }, { 28, 5 }, { 35, 5 }, { 27, 5 }, + /* Spectral coefficient 5 - 15 entries */ + { 31, 2 }, { 32, 3 }, { 30, 3 }, { 33, 4 }, { 29, 4 }, + { 34, 4 }, { 28, 4 }, { 38, 4 }, { 24, 4 }, { 35, 5 }, + { 27, 5 }, { 36, 6 }, { 26, 6 }, { 37, 6 }, { 25, 6 }, + /* Spectral coefficient 6 - 31 entries */ + { 31, 3 }, { 32, 4 }, { 30, 4 }, { 33, 4 }, { 29, 4 }, { 34, 4 }, + { 28, 4 }, { 46, 4 }, { 16, 4 }, { 35, 5 }, { 27, 5 }, { 36, 5 }, + { 26, 5 }, { 37, 5 }, { 25, 5 }, { 38, 6 }, { 24, 6 }, { 39, 6 }, + { 23, 6 }, { 40, 6 }, { 22, 6 }, { 41, 6 }, { 21, 6 }, { 42, 7 }, + { 20, 7 }, { 43, 7 }, { 19, 7 }, { 44, 7 }, { 18, 7 }, { 45, 7 }, + { 17, 7 }, + /* Spectral coefficient 7 - 63 entries */ + { 31, 3 }, { 62, 4 }, { 0, 4 }, { 32, 5 }, { 30, 5 }, { 33, 5 }, + { 29, 5 }, { 34, 5 }, { 28, 5 }, { 35, 5 }, { 27, 5 }, { 36, 5 }, + { 26, 5 }, { 37, 6 }, { 25, 6 }, { 38, 6 }, { 24, 6 }, { 39, 6 }, + { 23, 6 }, { 40, 6 }, { 22, 6 }, { 41, 6 }, { 21, 6 }, { 42, 6 }, + { 20, 6 }, { 43, 6 }, { 19, 6 }, { 44, 6 }, { 18, 6 }, { 45, 7 }, + { 17, 7 }, { 46, 7 }, { 16, 7 }, { 47, 7 }, { 15, 7 }, { 48, 7 }, + { 14, 7 }, { 49, 7 }, { 13, 7 }, { 50, 7 }, { 12, 7 }, { 51, 7 }, + { 11, 7 }, { 52, 8 }, { 10, 8 }, { 53, 8 }, { 9, 8 }, { 54, 8 }, + { 8, 8 }, { 55, 8 }, { 7, 8 }, { 56, 8 }, { 6, 8 }, { 57, 8 }, + { 5, 8 }, { 58, 8 }, { 4, 8 }, { 59, 8 }, { 3, 8 }, { 60, 8 }, + { 2, 8 }, { 61, 8 }, { 1, 8 }, }; static const uint8_t huff_tab_sizes[7] = { 9, 5, 7, 9, 15, 31, 63, }; -static const uint8_t* const huff_codes[7] = { - huffcode1, huffcode2, huffcode3, huffcode4, huffcode5, huffcode6, huffcode7 -}; - -static const uint8_t* const huff_bits[7] = { - huffbits1, huffbits2, huffbits3, huffbits4, huffbits5, huffbits6, huffbits7, -}; - -static const uint16_t atrac3_vlc_offs[9] = { - 0, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096 -}; - /* selector tables */ static const uint8_t clc_length_tab[8] = { 0, 4, 3, 3, 4, 4, 5, 6 }; diff --git a/libavcodec/atrac3plus.c b/libavcodec/atrac3plus.c index 8d1788958..3a0a0d5f3 100644 --- a/libavcodec/atrac3plus.c +++ b/libavcodec/atrac3plus.c @@ -43,170 +43,75 @@ static VLC tone_vlc_tabs[7]; * Generate canonical VLC table from given descriptor. * * @param[in] cb ptr to codebook descriptor - * @param[in] xlat ptr to translation table or NULL + * @param[in,out] xlat ptr to ptr to translation table * @param[in,out] tab_offset starting offset to the generated vlc table * @param[out] out_vlc ptr to vlc table to be generated */ -static av_cold void build_canonical_huff(const uint8_t *cb, const uint8_t *xlat, +static av_cold void build_canonical_huff(const uint8_t *cb, const uint8_t **xlat, int *tab_offset, VLC *out_vlc) { - int i, b; - uint16_t codes[256]; + int i, max_len; uint8_t bits[256]; - unsigned code = 0; int index = 0; - int min_len = *cb++; // get shortest codeword length - int max_len = *cb++; // get longest codeword length - for (b = min_len; b <= max_len; b++) { + for (int b = 1; b <= 12; b++) { for (i = *cb++; i > 0; i--) { av_assert0(index < 256); bits[index] = b; - codes[index] = code++; index++; } - code <<= 1; } + max_len = bits[index - 1]; out_vlc->table = &tables_data[*tab_offset]; out_vlc->table_allocated = 1 << max_len; - ff_init_vlc_sparse(out_vlc, max_len, index, bits, 1, 1, codes, 2, 2, - xlat, 1, 1, INIT_VLC_USE_NEW_STATIC); + ff_init_vlc_from_lengths(out_vlc, max_len, index, bits, 1, + *xlat, 1, 1, 0, INIT_VLC_USE_NEW_STATIC, NULL); *tab_offset += 1 << max_len; + *xlat += index; } av_cold void ff_atrac3p_init_vlcs(void) { - int i, wl_vlc_offs, ct_vlc_offs, sf_vlc_offs, tab_offset; + int i, tab_offset = 0; + const uint8_t *xlats; - static const uint8_t wl_nb_bits[4] = { 2, 3, 5, 5 }; - static const uint8_t wl_nb_codes[4] = { 3, 5, 8, 8 }; - static const uint8_t * const wl_bits[4] = { - atrac3p_wl_huff_bits1, atrac3p_wl_huff_bits2, - atrac3p_wl_huff_bits3, atrac3p_wl_huff_bits4 - }; - static const uint8_t * const wl_codes[4] = { - atrac3p_wl_huff_code1, atrac3p_wl_huff_code2, - atrac3p_wl_huff_code3, atrac3p_wl_huff_code4 - }; - static const uint8_t * const wl_xlats[4] = { - atrac3p_wl_huff_xlat1, atrac3p_wl_huff_xlat2, NULL, NULL - }; - - static const uint8_t ct_nb_bits[4] = { 3, 4, 4, 4 }; - static const uint8_t ct_nb_codes[4] = { 4, 8, 8, 8 }; - static const uint8_t * const ct_bits[4] = { - atrac3p_ct_huff_bits1, atrac3p_ct_huff_bits2, - atrac3p_ct_huff_bits2, atrac3p_ct_huff_bits3 - }; - static const uint8_t * const ct_codes[4] = { - atrac3p_ct_huff_code1, atrac3p_ct_huff_code2, - atrac3p_ct_huff_code2, atrac3p_ct_huff_code3 - }; - static const uint8_t * const ct_xlats[4] = { - NULL, NULL, atrac3p_ct_huff_xlat1, NULL - }; - - static const uint8_t sf_nb_bits[8] = { 9, 9, 9, 9, 6, 6, 7, 7 }; - static const uint8_t sf_nb_codes[8] = { 64, 64, 64, 64, 16, 16, 16, 16 }; - static const uint8_t * const sf_bits[8] = { - atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits2, - atrac3p_sf_huff_bits3, atrac3p_sf_huff_bits4, atrac3p_sf_huff_bits4, - atrac3p_sf_huff_bits5, atrac3p_sf_huff_bits6 - }; - static const uint16_t * const sf_codes[8] = { - atrac3p_sf_huff_code1, atrac3p_sf_huff_code1, atrac3p_sf_huff_code2, - atrac3p_sf_huff_code3, atrac3p_sf_huff_code4, atrac3p_sf_huff_code4, - atrac3p_sf_huff_code5, atrac3p_sf_huff_code6 - }; - static const uint8_t * const sf_xlats[8] = { - atrac3p_sf_huff_xlat1, atrac3p_sf_huff_xlat2, NULL, NULL, - atrac3p_sf_huff_xlat4, atrac3p_sf_huff_xlat5, NULL, NULL - }; - - static const uint8_t * const gain_cbs[11] = { - atrac3p_huff_gain_npoints1_cb, atrac3p_huff_gain_npoints1_cb, - atrac3p_huff_gain_lev1_cb, atrac3p_huff_gain_lev2_cb, - atrac3p_huff_gain_lev3_cb, atrac3p_huff_gain_lev4_cb, - atrac3p_huff_gain_loc3_cb, atrac3p_huff_gain_loc1_cb, - atrac3p_huff_gain_loc4_cb, atrac3p_huff_gain_loc2_cb, - atrac3p_huff_gain_loc5_cb - }; - static const uint8_t * const gain_xlats[11] = { - NULL, atrac3p_huff_gain_npoints2_xlat, atrac3p_huff_gain_lev1_xlat, - atrac3p_huff_gain_lev2_xlat, atrac3p_huff_gain_lev3_xlat, - atrac3p_huff_gain_lev4_xlat, atrac3p_huff_gain_loc3_xlat, - atrac3p_huff_gain_loc1_xlat, atrac3p_huff_gain_loc4_xlat, - atrac3p_huff_gain_loc2_xlat, atrac3p_huff_gain_loc5_xlat - }; - - static const uint8_t * const tone_cbs[7] = { - atrac3p_huff_tonebands_cb, atrac3p_huff_numwavs1_cb, - atrac3p_huff_numwavs2_cb, atrac3p_huff_wav_ampsf1_cb, - atrac3p_huff_wav_ampsf2_cb, atrac3p_huff_wav_ampsf3_cb, - atrac3p_huff_freq_cb - }; - static const uint8_t * const tone_xlats[7] = { - NULL, NULL, atrac3p_huff_numwavs2_xlat, atrac3p_huff_wav_ampsf1_xlat, - atrac3p_huff_wav_ampsf2_xlat, atrac3p_huff_wav_ampsf3_xlat, - atrac3p_huff_freq_xlat - }; - - for (i = 0, wl_vlc_offs = 0, ct_vlc_offs = 2508; i < 4; i++) { - wl_vlc_tabs[i].table = &tables_data[wl_vlc_offs]; - wl_vlc_tabs[i].table_allocated = 1 << wl_nb_bits[i]; - ct_vlc_tabs[i].table = &tables_data[ct_vlc_offs]; - ct_vlc_tabs[i].table_allocated = 1 << ct_nb_bits[i]; - - ff_init_vlc_sparse(&wl_vlc_tabs[i], wl_nb_bits[i], wl_nb_codes[i], - wl_bits[i], 1, 1, - wl_codes[i], 1, 1, - wl_xlats[i], 1, 1, - INIT_VLC_USE_NEW_STATIC); - - ff_init_vlc_sparse(&ct_vlc_tabs[i], ct_nb_bits[i], ct_nb_codes[i], - ct_bits[i], 1, 1, - ct_codes[i], 1, 1, - ct_xlats[i], 1, 1, - INIT_VLC_USE_NEW_STATIC); - - wl_vlc_offs += wl_vlc_tabs[i].table_allocated; - ct_vlc_offs += ct_vlc_tabs[i].table_allocated; + xlats = atrac3p_wl_ct_xlats; + for (int i = 0; i < 4; i++) { + build_canonical_huff(atrac3p_wl_cbs[i], &xlats, + &tab_offset, &wl_vlc_tabs[i]); + build_canonical_huff(atrac3p_ct_cbs[i], &xlats, + &tab_offset, &ct_vlc_tabs[i]); } - for (i = 0, sf_vlc_offs = 76; i < 8; i++) { - sf_vlc_tabs[i].table = &tables_data[sf_vlc_offs]; - sf_vlc_tabs[i].table_allocated = 1 << sf_nb_bits[i]; - - ff_init_vlc_sparse(&sf_vlc_tabs[i], sf_nb_bits[i], sf_nb_codes[i], - sf_bits[i], 1, 1, - sf_codes[i], 2, 2, - sf_xlats[i], 1, 1, - INIT_VLC_USE_NEW_STATIC); - sf_vlc_offs += sf_vlc_tabs[i].table_allocated; - } - - tab_offset = 2564; + xlats = atrac3p_sf_xlats; + for (int i = 0; i < 8; i++) + build_canonical_huff(atrac3p_sf_cbs[i], &xlats, + &tab_offset, &sf_vlc_tabs[i]); /* build huffman tables for spectrum decoding */ + xlats = atrac3p_spectra_xlats; for (i = 0; i < 112; i++) { - if (atrac3p_spectra_tabs[i].cb) - build_canonical_huff(atrac3p_spectra_tabs[i].cb, - atrac3p_spectra_tabs[i].xlat, - &tab_offset, &spec_vlc_tabs[i]); - else - spec_vlc_tabs[i].table = 0; + if (atrac3p_spectra_cbs[i][0] >= 0) + build_canonical_huff(atrac3p_spectra_cbs[i], + &xlats, &tab_offset, &spec_vlc_tabs[i]); + else /* Reuse already initialized VLC table */ + spec_vlc_tabs[i] = spec_vlc_tabs[-atrac3p_spectra_cbs[i][0]]; } /* build huffman tables for gain data decoding */ + xlats = atrac3p_gain_xlats; for (i = 0; i < 11; i++) - build_canonical_huff(gain_cbs[i], gain_xlats[i], &tab_offset, &gain_vlc_tabs[i]); + build_canonical_huff(atrac3p_gain_cbs[i], &xlats, + &tab_offset, &gain_vlc_tabs[i]); /* build huffman tables for tone decoding */ + xlats = atrac3p_tone_xlats; for (i = 0; i < 7; i++) - build_canonical_huff(tone_cbs[i], tone_xlats[i], &tab_offset, &tone_vlc_tabs[i]); + build_canonical_huff(atrac3p_tone_cbs[i], &xlats, + &tab_offset, &tone_vlc_tabs[i]); } /** @@ -880,10 +785,6 @@ static void decode_spectrum(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, tab_index = (chan->table_type * 8 + codetab) * 7 + wordlen - 1; tab = &atrac3p_spectra_tabs[tab_index]; - /* this allows reusing VLC tables */ - if (tab->redirect >= 0) - tab_index = tab->redirect; - decode_qu_spectra(gb, tab, &spec_vlc_tabs[tab_index], &chan->spectrum[ff_atrac3p_qu_to_spec_pos[qu]], num_specs); diff --git a/libavcodec/atrac3plus.h b/libavcodec/atrac3plus.h index 3c39e293c..a588436e2 100644 --- a/libavcodec/atrac3plus.h +++ b/libavcodec/atrac3plus.h @@ -31,6 +31,8 @@ #include #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" + #include "atrac.h" #include "avcodec.h" #include "fft.h" @@ -179,9 +181,9 @@ int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, void ff_atrac3p_init_imdct(AVCodecContext *avctx, FFTContext *mdct_ctx); /** - * Initialize sine waves synthesizer. + * Initialize sine waves synthesizer and ff_sine_* tables. */ -void ff_atrac3p_init_wave_synth(void); +void ff_atrac3p_init_dsp_static(void); /** * Synthesize sine waves for a particular subband. diff --git a/libavcodec/atrac3plus_data.h b/libavcodec/atrac3plus_data.h index 2a107eef1..05ae2b78a 100644 --- a/libavcodec/atrac3plus_data.h +++ b/libavcodec/atrac3plus_data.h @@ -27,148 +27,82 @@ #include /** VLC tables for wordlen */ -static const uint8_t atrac3p_wl_huff_code1[3] = { 0, 2, 3 }; - -static const uint8_t atrac3p_wl_huff_bits1[3] = { 1, 2, 2 }; - -static const uint8_t atrac3p_wl_huff_xlat1[3] = { 0, 1, 7 }; - -static const uint8_t atrac3p_wl_huff_code2[5] = { 0, 4, 5, 6, 7 }; - -static const uint8_t atrac3p_wl_huff_bits2[5] = { 1, 3, 3, 3, 3 }; - -static const uint8_t atrac3p_wl_huff_xlat2[5] = { 0, 1, 2, 6, 7 }; - -static const uint8_t atrac3p_wl_huff_code3[8] = { - 0, 4, 0xC, 0x1E, 0x1F, 0xD, 0xE, 5 -}; - -static const uint8_t atrac3p_wl_huff_bits3[8] = { 1, 3, 4, 5, 5, 4, 4, 3 }; - -static const uint8_t atrac3p_wl_huff_code4[8] = { - 0, 4, 0xC, 0xD, 0x1E, 0x1F, 0xE, 5 -}; - -static const uint8_t atrac3p_wl_huff_bits4[8] = { 1, 3, 4, 4, 5, 5, 4, 3 }; - -/** VLC tables for scale factor indexes */ -static const uint16_t atrac3p_sf_huff_code1[64] = { - 0, 2, 3, 4, 5, 0xC, 0xD, 0xE0, - 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0x1CE, 0x1CF, - 0x1D0, 0x1D1, 0x1D2, 0x1D3, 0x1D4, 0x1D5, 0x1D6, 0x1D7, - 0x1D8, 0x1D9, 0x1DA, 0x1DB, 0x1DC, 0x1DD, 0x1DE, 0x1DF, - 0x1E0, 0x1E1, 0x1E2, 0x1E3, 0x1E4, 0x1E5, 0x1E6, 0x1E7, - 0x1E8, 0x1E9, 0x1EA, 0x1EB, 0x1EC, 0x1ED, 0x1EE, 0x1EF, - 0x1F0, 0x1F1, 0x1F2, 0x1F3, 0x1F4, 0x1F5, 0x1F6, 0x1F7, - 0x1F8, 0x1F9, 0x1FA, 0x1FB, 0x1FC, 0x1FD, 0x1FE, 0x1FF -}; - -static const uint8_t atrac3p_sf_huff_bits1[64] = { - 2, 3, 3, 3, 3, 4, 4, 8, 8, 8, 8, 8, 8, 8, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 -}; - -static const uint8_t atrac3p_sf_huff_xlat1[64] = { - 0, 1, 61, 62, 63, 2, 60, 3, 4, 5, 6, 57, 58, 59, 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 -}; - -static const uint8_t atrac3p_sf_huff_xlat2[64] = { - 0, 1, 2, 62, 63, 3, 61, 4, 5, 6, 57, 58, 59, 60, 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 -}; - -static const uint16_t atrac3p_sf_huff_code2[64] = { - 0, 4, 0x18, 0x19, 0x70, 0x1CA, 0x1CB, 0x1CC, - 0x1CD, 0x1CE, 0x1CF, 0x1D0, 0x1D1, 0x1D2, 0x1D3, 0x1D4, - 0x1D5, 0x1D6, 0x1D7, 0x1D8, 0x1D9, 0x1DA, 0x1DB, 0x1DC, - 0x1DD, 0x1DE, 0x1DF, 0x1E0, 0x1E1, 0x1E2, 0x1E3, 0x1E4, - 0x1E5, 0x1E6, 0x1E7, 0x1E8, 0x1E9, 0x1EA, 0x1EB, 0x1EC, - 0x1ED, 0x1EE, 0x1EF, 0x1F0, 0x1F1, 0x1F2, 0x1F3, 0x1F4, - 0x1F5, 0x1F6, 0x1F7, 0x1F8, 0x1F9, 0x1FA, 0x1FB, 0x1FC, - 0x1FD, 0x1FE, 0x1FF, 0xE4, 0x71, 0x1A, 0x1B, 5 -}; - -static const uint8_t atrac3p_sf_huff_bits2[64] = { - 1, 3, 5, 5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 5, 5, 3 -}; - -static const uint16_t atrac3p_sf_huff_code3[64] = { - 0, 2, 3, 0x18, 0x19, 0x70, 0x1CC, 0x1CD, - 0x1CE, 0x1CF, 0x1D0, 0x1D1, 0x1D2, 0x1D3, 0x1D4, 0x1D5, - 0x1D6, 0x1D7, 0x1D8, 0x1D9, 0x1DA, 0x1DB, 0x1DC, 0x1DD, - 0x1DE, 0x1DF, 0x1E0, 0x1E1, 0x1E2, 0x1E3, 0x1E4, 0x1E5, - 0x1E6, 0x1E7, 0x1E8, 0x1E9, 0x1EA, 0x1EB, 0x1EC, 0x1ED, - 0x1EE, 0x1EF, 0x1F0, 0x1F1, 0x1F2, 0x1F3, 0x1F4, 0x1F5, - 0x1F6, 0x1F7, 0x1F8, 0x1F9, 0x1FA, 0x1FB, 0x1FC, 0x1FD, - 0x1FE, 0x1FF, 0x71, 0x72, 0x1A, 0x1B, 4, 5 -}; - -static const uint8_t atrac3p_sf_huff_bits3[64] = { - 2, 3, 3, 5, 5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 5, 5, 3, 3 -}; - -static const uint16_t atrac3p_sf_huff_code4[16] = { - 0, 2, 3, 4, 5, 0xC, 0xD, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0, 0x3D, 0x3E, 0x3F -}; - -static const uint8_t atrac3p_sf_huff_bits4[16] = { - 2, 3, 3, 3, 3, 4, 4, 6, 6, 6, 6, 6, 0, 6, 6, 6 -}; - -static const uint8_t atrac3p_sf_huff_xlat4[16] = { - 0, 1, 13, 14, 15, 2, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11 -}; - -static const uint8_t atrac3p_sf_huff_xlat5[16] = { - 0, 1, 2, 14, 15, 3, 13, 4, 5, 6, 7, 9, 8, 10, 11, 12 -}; - -static const uint16_t atrac3p_sf_huff_code5[16] = { - 0, 4, 0xC, 0x1C, 0x78, 0x79, 0x7A, 0x7B, - 0, 0x7C, 0x7D, 0x7E, 0x7F, 0x1D, 0xD, 5 -}; - -static const uint8_t atrac3p_sf_huff_bits5[16] = { - 1, 3, 4, 5, 7, 7, 7, 7, 0, 7, 7, 7, 7, 5, 4, 3 -}; - -static const uint16_t atrac3p_sf_huff_code6[16] = { - 0, 2, 3, 0xC, 0x1C, 0x3C, 0x7C, 0x7D, 0, 0x7E, 0x7F, 0x3D, 0x1D, 0xD, 4, 5 -}; - -static const uint8_t atrac3p_sf_huff_bits6[16] = { - 2, 3, 3, 4, 5, 6, 7, 7, 0, 7, 7, 6, 5, 4, 3, 3 +static const uint8_t atrac3p_wl_cbs[][12] = { + { 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0 }, }; /** VLC tables for code table indexes */ -static const uint8_t atrac3p_ct_huff_code1[4] = { 0, 2, 6, 7 }; - -static const uint8_t atrac3p_ct_huff_bits1[4] = { 1, 2, 3, 3 }; - -static const uint8_t atrac3p_ct_huff_code2[8] = { 0, 2, 3, 4, 5, 6, 0xE, 0xF }; - -static const uint8_t atrac3p_ct_huff_bits2[8] = { 2, 3, 3, 3, 3, 3, 4, 4 }; - -static const uint8_t atrac3p_ct_huff_xlat1[8] = { 0, 1, 2, 3, 6, 7, 4, 5 }; - -static const uint8_t atrac3p_ct_huff_code3[8] = { - 0, 4, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF +static const uint8_t atrac3p_ct_cbs[][12] = { + { 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, +}; +/* Symbols for wordlen interleaved with symbols for code table */ +static const uint8_t atrac3p_wl_ct_xlats[] = { + /* wordlen table 1 - 3 entries */ + 0, 1, 7, + /* code table 1 - 4 entries */ + 0, 1, 2, 3, + /* wordlen table 2 - 5 entries */ + 0, 1, 2, 6, 7, + /* code table 2 - 8 entries */ + 0, 1, 2, 3, 4, 5, 6, 7, + /* wordlen table 3 - 8 entries */ + 0, 1, 7, 2, 5, 6, 3, 4, + /* code table 3 - 8 entries */ + 0, 1, 2, 3, 6, 7, 4, 5, + /* wordlen table 4 - 8 entries */ + 0, 1, 7, 2, 3, 6, 4, 5, + /* code table 4 - 8 entries */ + 0, 1, 2, 3, 4, 5, 6, 7, }; -static const uint8_t atrac3p_ct_huff_bits3[8] = { 1, 3, 4, 4, 4, 4, 4, 4 }; +/** VLC tables for scale factor indexes */ +static const uint8_t atrac3p_sf_cbs[][12] = { + { 0, 1, 4, 2, 0, 0, 0, 7, 50, 0, 0, 0 }, + { 0, 1, 4, 2, 0, 0, 0, 7, 50, 0, 0, 0 }, + { 1, 0, 2, 0, 4, 0, 2, 1, 54, 0, 0, 0 }, + { 0, 1, 4, 0, 4, 0, 3, 0, 52, 0, 0, 0 }, + { 0, 1, 4, 2, 0, 8, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 4, 2, 0, 8, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 2, 2, 2, 0, 8, 0, 0, 0, 0, 0 }, + { 0, 1, 4, 2, 2, 2, 4, 0, 0, 0, 0, 0 }, +}; + +static const uint8_t atrac3p_sf_xlats[] = { + /* Scale factor index 1 - 64 entries */ + 0, 1, 61, 62, 63, 2, 60, 3, 4, 5, 6, 57, 58, 59, 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, + /* Scale factor index 2 - 64 entries */ + 0, 1, 2, 62, 63, 3, 61, 4, 5, 6, 57, 58, 59, 60, 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, + /* Scale factor index 3 - 64 entries */ + 0, 1, 63, 2, 3, 61, 62, 4, 60, 59, 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, + /* Scale factor index 4 - 64 entries */ + 0, 1, 2, 62, 63, 3, 4, 60, 61, 5, 58, 59, 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, + /* Scale factor index 5 - 15 entries */ + 0, 1, 13, 14, 15, 2, 12, 3, 4, 5, 6, 7, 9, 10, 11, + /* Scale factor index 6 - 15 entries */ + 0, 1, 2, 14, 15, 3, 13, 4, 5, 6, 7, 9, 10, 11, 12, + /* Scale factor index 7 - 15 entries */ + 0, 1, 15, 2, 14, 3, 13, 4, 5, 6, 7, 9, 10, 11, 12, + /* Scale factor index 8 - 15 entries */ + 0, 1, 2, 14, 15, 3, 13, 4, 12, 5, 11, 6, 7, 9, 10, +}; /* weights for quantized word lengths */ static const int8_t atrac3p_wl_weights[6][32] = { @@ -437,52 +371,150 @@ static const uint8_t atrac3p_ct_restricted_to_full[2][7][4] = { }; /** Tables for spectrum coding */ -static const uint8_t huff_a01_cb[14] = { - 1, 12, 1, 0, 0, 1, 7, 0, 19, 5, 13, 21, 6, 8 + +/* If the first entry of a subtable is negative, it means + * that another VLC is to be reused. */ +static const int8_t atrac3p_spectra_cbs[][12] = { + { 1, 0, 0, 1, 7, 0, 19, 5, 13, 21, 6, 8 }, + { 0, 1, 0, 4, 11, 0, 1, 29, 6, 20, 7, 2 }, + { 0, 0, 1, 8, 0, 13, 18, 7, 2, 0, 0, 0 }, + { 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 1, 3, 5, 8, 12, 23, 72, 68, 31, 2 }, + { 0, 1, 3, 2, 6, 4, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 2, 2, 2, 6, 14, 21, 13, 2, 0, 0 }, + { 1, 0, 0, 0, 8, 1, 18, 9, 22, 10, 12, 0 }, + { 0, 0, 0, 0, 16, 11, 32, 19, 1, 2, 0, 0 }, + { 1, 0, 0, 4, 2, 2, 9, 15, 12, 4, 0, 0 }, + { 0, 1, 0, 4, 3, 5, 16, 28, 34, 26, 4, 0 }, + { 0, 0, 0, 0, 9, 12, 16, 44, 98, 42, 4, 0 }, + { 0, 1, 1, 2, 2, 5, 7, 21, 54, 85, 62, 16 }, + { 0, 0, 3, 2, 5, 7, 17, 23, 6, 0, 0, 0 }, + { 1, 0, 0, 2, 6, 0, 7, 21, 15, 17, 8, 4 }, + { 0, 1, 4, 0, 4, 3, 8, 3, 2, 0, 0, 0 }, + { 0, 0, 5, 0, 4, 6, 10, 16, 8, 0, 0, 0 }, + { 0, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 3, 4, 12, 15, 34, 83, 75, 30, 0 }, + { 0, 0, 0, 3, 14, 10, 20, 16, 0, 0, 0, 0 }, + { 1, 0, 3, 1, 0, 4, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 2, 2, 6, 12, 18, 19, 15, 6, 0 }, + { 0, 0, 1, 1, 13, 1, 14, 28, 33, 81, 32, 52 }, + { 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 0, 2, 3, 6, 19, 9, 75, 110, 0, 0 }, + { 0, 0, 1, 3, 5, 5, 13, 27, 69, 96, 35, 2 }, + { 0, 0, 0, 7, 6, 8, 22, 20, 0, 0, 0, 0 }, + { 1, 0, 0, 6, 2, 0, 0, 0, 19, 9, 24, 20 }, + { 0, 0, 1, 2, 13, 1, 31, 13, 16, 4, 0, 0 }, + { 0, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 5, 4, 12, 17, 47, 24, 12, 0, 0 }, + { 0, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 16, 31, 36, 172, 0, 0, 0 }, + { 0, 0, 0, 5, 12, 9, 12, 15, 10, 0, 0, 0 }, + { 0, 1, 0, 6, 2, 6, 18, 4, 26, 6, 12, 0 }, + { 1, 0, 2, 2, 0, 4, 3, 8, 3, 2, 0, 0 }, + { 0, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 4, 7, 12, 19, 21, 58, 0, 0, 0 }, + { 1, 1, 1, 0, 3, 2, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 1, 8, 6, 8, 8, 0, 0, 0, 0, 0 }, + { 0, 0, 1, 5, 7, 8, 16, 22, 4, 0, 0, 0 }, + { 0, 1, 0, 8, 0, 1, 16, 10, 29, 12, 4, 0 }, + { 0, 0, 5, 2, 2, 9, 5, 2, 0, 0, 0, 0 }, + { 0, 0, 1, 1, 10, 4, 16, 29, 46, 75, 74, 0 }, + { 0, 0, 0, 1, 7, 12, 36, 63, 2, 0, 0, 0 }, + { 0, 3, 0, 1, 3, 4, 4, 0, 0, 0, 0, 0 }, + { 0, 1, 2, 2, 6, 8, 6, 3, 1, 2, 0, 0 }, + { 0, 1, 1, 3, 4, 6, 13, 25, 10, 0, 0, 0 }, + { 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 0, 4, 8, 3, 8, 24, 17, 12, 4, 0 }, + { 0, 1, 1, 5, 2, 8, 7, 13, 8, 4, 0, 0 }, + { 1, 0, 0, 4, 0, 4, 5, 9, 30, 45, 21, 2 }, + { 0, 1, 3, 3, 4, 4, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 1, 3, 4, 8, 10, 36, 60, 78, 48, 8 }, + { -6 }, + { 1, 0, 0, 2, 6, 0, 11, 13, 12, 24, 4, 8 }, + { 1, 0, 0, 4, 0, 8, 4, 9, 19, 13, 13, 10 }, + { 1, 0, 0, 4, 0, 5, 12, 13, 14, 0, 0, 0 }, + { 0, 1, 0, 4, 4, 5, 9, 30, 45, 21, 2, 0 }, + { 0, 0, 1, 4, 4, 4, 12, 30, 73, 75, 22, 0 }, + { -5 }, + { 0, 0, 3, 2, 4, 8, 23, 13, 10, 0, 0, 0 }, + { -14 }, + { 0, 0, 1, 3, 12, 0, 30, 9, 18, 8, 0, 0 }, + { -9 }, + { 1, 0, 0, 4, 0, 3, 5, 16, 28, 34, 26, 4 }, + { -11 }, + { 0, 0, 0, 4, 4, 9, 13, 37, 76, 72, 39, 2 }, + { -6 }, + { -28 }, + { -22 }, + { -2 }, + { -31 }, + { -60 }, + { 0, 0, 2, 2, 4, 5, 11, 26, 67, 78, 51, 10 }, + { -6 }, + { -35 }, + { 0, 1, 0, 4, 6, 7, 10, 22, 11, 16, 4, 0 }, + { 0, 1, 0, 0, 4, 11, 8, 28, 92, 97, 13, 2 }, + { -59 }, + { 1, 0, 0, 0, 4, 6, 6, 14, 42, 63, 59, 30 }, + { -75 }, + { 1, 0, 2, 0, 2, 2, 6, 17, 14, 13, 6, 0 }, + { 1, 0, 0, 1, 7, 0, 20, 4, 10, 24, 2, 12 }, + { 1, 0, 1, 3, 2, 3, 7, 4, 4, 0, 0, 0 }, + { 0, 1, 1, 3, 4, 9, 15, 12, 4, 0, 0, 0 }, + { -66 }, + { -32 }, + { -12 }, + { 0, 1, 1, 3, 4, 6, 14, 22, 12, 0, 0, 0 }, + { -42 }, + { 1, 0, 1, 3, 2, 3, 7, 4, 4, 0, 0, 0 }, + { 1, 1, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0 }, + { -17 }, + { -39 }, + { 1, 0, 2, 0, 2, 4, 11, 9, 2, 0, 0, 0 }, + { -62 }, + { -28 }, + { 1, 0, 0, 2, 3, 5, 12, 14, 18, 15, 9, 2 }, + { 1, 1, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 2, 2, 2, 6, 12, 34, 92, 54, 20 }, + { 1, 0, 0, 3, 0, 3, 3, 10, 40, 85, 61, 50 }, + { 0, 1, 2, 1, 4, 7, 10, 26, 12, 0, 0, 0 }, + { 1, 0, 0, 1, 7, 0, 19, 5, 13, 23, 0, 12 }, + { -78 }, + { 1, 0, 0, 0, 1, 4, 9, 4, 103, 110, 24, 0 }, + { 1, 0, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 4, 0, 0, 0, 8, 11, 24, 53, 64, 60 }, + { -47 }, + { 0, 1, 0, 4, 6, 10, 12, 7, 15, 4, 4, 0 }, }; -static const uint8_t huff_a01_xlat[81] = { +static const uint8_t atrac3p_spectra_xlats[] = { + /* Table set A, code table 0, wordlen 1 - 81 entries */ 0x00, 0x03, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x50, 0xD0, 0x70, 0xF0, 0xC4, 0x14, 0x34, 0x4C, 0x1C, 0x3C, 0x41, 0xC1, 0x31, 0x05, 0x0D, 0xC3, 0x13, 0x07, 0x0F, 0x44, 0xCC, 0x11, 0x43, 0x33, 0x54, 0x74, 0xDC, 0xFC, 0x71, 0x15, 0x4D, 0xCD, 0x1D, 0xD3, 0xC7, 0x37, 0x3F, 0xD4, 0xF4, 0x5C, 0x7C, 0x51, 0xD1, 0xF1, 0x45, 0xC5, 0x35, 0xDD, 0x3D, 0x53, 0x73, 0xF3, 0x47, 0x17, 0x77, 0x4F, 0xCF, 0x1F, 0x55, 0xF5, 0x7D, 0xD7, 0x5F, - 0xFF, 0xD5, 0x75, 0x5D, 0xFD, 0x57, 0xF7, 0xDF, 0x7F -}; - -static const uint8_t huff_a02_cb[13] = { - 2, 12, 1, 0, 4, 11, 0, 1, 29, 6, 20, 7, 2 -}; - -static const uint8_t huff_a02_xlat[81] = { + 0xFF, 0xD5, 0x75, 0x5D, 0xFD, 0x57, 0xF7, 0xDF, 0x7F, + /* Table set A, code table 0, wordlen 2 - 81 entries */ 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55, 0x90, 0x80, 0x20, 0x60, 0x84, 0x94, 0x24, 0x64, 0x08, 0x48, 0x18, 0x58, 0x81, 0x91, 0x21, 0x85, 0x95, 0x65, 0x09, 0x49, 0x19, 0x59, 0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56, 0x88, 0x61, 0x25, 0x29, 0x69, 0x5A, 0xA0, 0xA4, 0x98, 0x28, 0x68, 0xA1, 0xA5, 0x89, 0x99, 0xA9, 0x82, 0x92, 0x22, 0x62, 0x96, 0x26, 0x66, 0x0A, 0x4A, 0x1A, - 0xA8, 0x86, 0xA6, 0x8A, 0x9A, 0x2A, 0x6A, 0xA2, 0xAA -}; - -static const uint8_t huff_a03_cb[9] = { 3, 9, 1, 8, 0, 13, 18, 7, 2 }; - -static const uint8_t huff_a03_xlat[49] = { + 0xA8, 0x86, 0xA6, 0x8A, 0x9A, 0x2A, 0x6A, 0xA2, 0xAA, + /* Table set A, code table 0, wordlen 3 - 49 entries */ 0x00, 0x08, 0x38, 0x01, 0x09, 0x39, 0x07, 0x0F, 0x3F, 0x10, 0x30, 0x11, 0x31, 0x02, 0x0A, 0x3A, 0x05, 0x06, 0x0E, 0x3E, 0x17, 0x37, 0x18, 0x28, 0x19, 0x29, 0x2A, 0x32, 0x03, 0x0B, 0x33, 0x3B, 0x0D, 0x15, 0x3D, 0x16, 0x1E, 0x36, 0x1F, 0x2F, 0x12, 0x1A, 0x13, 0x2B, 0x1D, 0x35, 0x2E, 0x1B, - 0x2D -}; - -static const uint8_t huff_a04_cb[4] = { 2, 3, 2, 4 }; -static const uint8_t huff_a04_xlat[6] = { 1, 2, 0, 3, 4, 5 }; - -static const uint8_t huff_a05_cb[12] = { - 3, 12, 1, 3, 5, 8, 12, 23, 72, 68, 31, 2 -}; - -static const uint8_t huff_a05_xlat[225] = { + 0x2D, + /* Table set A, code table 0, wordlen 4 - 6 entries */ + 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, + /* Table set A, code table 0, wordlen 5 - 225 entries */ 0x00, 0x10, 0xF0, 0x01, 0x11, 0xF1, 0x0F, 0x1F, 0xFF, 0x20, 0xE0, 0xE1, 0x02, 0xF2, 0x0E, 0x1E, 0x2F, 0x30, 0xD0, 0x21, 0x12, 0x22, 0xE2, 0x03, 0x0D, 0x2E, 0xEE, 0xFE, 0xEF, 0x40, 0xC0, 0x31, 0xC1, 0xD1, 0x32, 0xD2, @@ -501,71 +533,40 @@ static const uint8_t huff_a05_xlat[225] = { 0x9C, 0xAC, 0xCC, 0x5D, 0x6D, 0x7D, 0x9D, 0xAD, 0xBD, 0x5E, 0x9E, 0xBE, 0x54, 0x45, 0x55, 0x65, 0x75, 0x95, 0xB5, 0x56, 0x66, 0x76, 0x96, 0xA6, 0x57, 0x67, 0x97, 0xA7, 0x69, 0x79, 0xA9, 0xB9, 0x6A, 0x7A, 0x9A, 0xAA, - 0xBA, 0x5B, 0x9B, 0xAB, 0xBB, 0xCB, 0xBC, 0x77, 0x99 -}; - -static const uint8_t huff_a06_cb[7] = { - 2, 6, 1, 3, 2, 6, 4 -}; - -static const uint8_t huff_a06_xlat[16] = { - 1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14, 10, 11, 12, 15 -}; - -static const uint8_t huff_a07_cb[11] = { - 2, 10, 1, 2, 2, 2, 6, 14, 21, 13, 2 -}; - -static const uint8_t huff_a07_xlat[63] = { - 0, 1, 63, 2, 62, 3, 61, 4, 5, 6, 58, 59, 60, 7, 8, 9, - 10, 26, 27, 28, 36, 37, 38, 54, 55, 56, 57, 11, 12, 13, 14, 15, - 16, 25, 29, 30, 31, 33, 34, 35, 39, 47, 48, 49, 50, 51, 52, 53, - 17, 18, 19, 20, 21, 22, 23, 41, 42, 43, 44, 45, 46, 24, 40 -}; - -static const uint8_t huff_a11_cb[13] = { - 1, 11, 1, 0, 0, 0, 8, 1, 18, 9, 22, 10, 12 -}; - -static const uint8_t huff_a11_xlat[81] = { + 0xBA, 0x5B, 0x9B, 0xAB, 0xBB, 0xCB, 0xBC, 0x77, 0x99, + /* Table set A, code table 0, wordlen 6 - 16 entries */ + 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0D, 0x0E, + 0x0A, 0x0B, 0x0C, 0x0F, + /* Table set A, code table 0, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x3F, 0x02, 0x3E, 0x03, 0x3D, 0x04, 0x05, 0x06, 0x3A, 0x3B, + 0x3C, 0x07, 0x08, 0x09, 0x0A, 0x1A, 0x1B, 0x1C, 0x24, 0x25, 0x26, 0x36, + 0x37, 0x38, 0x39, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x19, 0x1D, 0x1E, + 0x1F, 0x21, 0x22, 0x23, 0x27, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, + 0x2E, 0x18, 0x28, + /* Table set A, code table 1, wordlen 1 - 81 entries */ 0x00, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x03, 0xD0, 0x50, 0x70, 0xF0, 0xC4, 0x34, 0x4C, 0xCC, 0x1C, 0x41, 0xC1, 0x31, 0x05, 0x0D, 0x43, 0xC3, 0x13, 0x07, 0x0F, 0x44, 0x14, 0x74, 0xDC, 0x3C, 0x11, 0x1D, 0x33, 0x37, 0x54, 0xD4, 0xF4, 0x5C, 0x7C, 0xFC, 0xD1, 0x71, 0xF1, 0x15, 0x35, 0x4D, 0xCD, 0xDD, 0x3D, 0xD3, 0x73, 0x47, 0xC7, 0x17, 0x77, 0x3F, 0x51, 0x45, 0xC5, 0x55, 0x53, 0xF3, 0x4F, 0xCF, 0x1F, 0xFF, 0xD5, 0x75, 0xF5, - 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F -}; - -static const uint8_t huff_a12_cb[8] = { 5, 10, 16, 11, 32, 19, 1, 2 }; - -static const uint8_t huff_a12_xlat[81] = { + 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F, + /* Table set A, code table 1, wordlen 2 - 81 entries */ 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54, 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55, 0x90, 0x94, 0x58, 0x91, 0x95, 0x19, 0x59, 0x06, 0x46, 0x16, 0x56, 0x80, 0x60, 0x84, 0x24, 0x64, 0xA4, 0x08, 0x48, 0x18, 0x68, 0x81, 0x21, 0x61, 0xA1, 0x85, 0x25, 0x65, 0xA5, 0x09, 0x49, 0x99, 0x69, 0xA9, 0x02, 0x42, 0x12, 0x52, 0x96, 0x26, 0x66, 0x1A, 0x5A, 0x20, 0xA0, 0x88, 0x98, 0x28, 0xA8, 0x89, 0x29, 0x82, 0x92, 0x22, 0x62, 0x86, - 0xA6, 0x0A, 0x4A, 0x9A, 0x6A, 0xAA, 0xA2, 0x8A, 0x2A -}; - -static const uint8_t huff_a13_cb[12] = { - 1, 10, 1, 0, 0, 4, 2, 2, 9, 15, 12, 4 -}; - -static const uint8_t huff_a13_xlat[49] = { + 0xA6, 0x0A, 0x4A, 0x9A, 0x6A, 0xAA, 0xA2, 0x8A, 0x2A, + /* Table set A, code table 1, wordlen 3 - 49 entries */ 0x00, 0x08, 0x38, 0x01, 0x07, 0x39, 0x0F, 0x09, 0x3F, 0x10, 0x30, 0x31, 0x02, 0x3A, 0x06, 0x0E, 0x3E, 0x17, 0x18, 0x28, 0x11, 0x29, 0x0A, 0x32, 0x03, 0x0B, 0x3B, 0x05, 0x0D, 0x3D, 0x16, 0x1F, 0x37, 0x19, 0x12, 0x1A, 0x2A, 0x13, 0x33, 0x15, 0x35, 0x1E, 0x2E, 0x36, 0x2F, 0x1B, 0x2B, 0x1D, - 0x2D -}; - -static const uint8_t huff_a14_cb[12] = { - 2, 11, 1, 0, 4, 3, 5, 16, 28, 34, 26, 4 -}; - -static const uint8_t huff_a14_xlat[121] = { + 0x2D, + /* Table set A, code table 1, wordlen 4 - 121 entries */ 0x00, 0x10, 0xF0, 0x01, 0x0F, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x11, 0x02, 0x0E, 0x30, 0x50, 0xB0, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x03, 0x05, 0x0B, 0x0D, 0x1E, 0xFE, 0x2F, 0xEF, 0x40, 0xC0, 0x31, 0x51, 0xB1, 0xC1, 0xD1, @@ -576,12 +577,8 @@ static const uint8_t huff_a14_xlat[121] = { 0xED, 0x3E, 0x4E, 0xBE, 0xDE, 0x4F, 0xCF, 0xC2, 0x33, 0x43, 0xC3, 0xD3, 0x34, 0x44, 0x54, 0xB4, 0xD4, 0x45, 0x55, 0xC5, 0x4B, 0xCB, 0x3C, 0x4C, 0x5C, 0xCC, 0xDC, 0x3D, 0x4D, 0x5D, 0xCD, 0xDD, 0xCE, 0xC4, 0xB5, 0x5B, - 0xBB -}; - -static const uint8_t huff_a15_cb[9] = { 5, 11, 9, 12, 16, 44, 98, 42, 4 }; - -static const uint8_t huff_a15_xlat[225] = { + 0xBB, + /* Table set A, code table 1, wordlen 5 - 225 entries */ 0x00, 0x10, 0xF0, 0x01, 0x11, 0xF1, 0x0F, 0x1F, 0xFF, 0x20, 0xE0, 0x21, 0xE1, 0x02, 0x12, 0xF2, 0x0E, 0x1E, 0xFE, 0x2F, 0xEF, 0x30, 0xD0, 0x31, 0xD1, 0x22, 0xE2, 0x03, 0x13, 0xF3, 0x0D, 0x1D, 0xFD, 0x2E, 0xEE, 0x3F, @@ -600,14 +597,8 @@ static const uint8_t huff_a15_xlat[225] = { 0x54, 0x74, 0x94, 0xB4, 0x45, 0x55, 0x65, 0x75, 0x95, 0xA5, 0xB5, 0xC5, 0x56, 0x66, 0x76, 0x96, 0xA6, 0xB6, 0x47, 0x57, 0x67, 0xA7, 0xB7, 0x49, 0x59, 0x69, 0xA9, 0xB9, 0x6A, 0x7A, 0x9A, 0xAA, 0xBA, 0x4B, 0x5B, 0x6B, - 0x7B, 0x9B, 0xAB, 0xBB, 0x5C, 0x77, 0x97, 0x79, 0x99 -}; - -static const uint8_t huff_a16_cb[13] = { - 2, 12, 1, 1, 2, 2, 5, 7, 21, 54, 85, 62, 16 -}; - -static const uint8_t huff_a16_xlat[256] = { + 0x7B, 0x9B, 0xAB, 0xBB, 0x5C, 0x77, 0x97, 0x79, 0x99, + /* Table set A, code table 1, wordlen 6 - 256 entries */ 0x00, 0x01, 0x10, 0x11, 0x21, 0x12, 0x20, 0x31, 0x02, 0x22, 0x13, 0x30, 0x41, 0x32, 0x03, 0x23, 0x14, 0x24, 0x40, 0x51, 0x61, 0xD1, 0xE1, 0x42, 0x52, 0xD2, 0x33, 0x43, 0xD3, 0x04, 0x34, 0x05, 0x15, 0x25, 0x16, 0x1D, @@ -629,59 +620,37 @@ static const uint8_t huff_a16_xlat[256] = { 0x6B, 0xCB, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xFC, 0xDD, 0xED, 0xFD, 0xDE, 0xEE, 0xFE, 0x9F, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF, 0xB0, 0xA7, 0xB7, 0xA8, 0xB8, 0xA9, 0xB9, 0x8A, 0x9A, 0xAA, 0xBA, 0x7B, - 0x8B, 0x9B, 0xAB, 0xBB -}; - -static const uint8_t huff_a17_cb[9] = { 3, 9, 3, 2, 5, 7, 17, 23, 6 }; - -static const uint8_t huff_a17_xlat[63] = { - 0, 1, 63, 2, 62, 3, 4, 59, 60, 61, 5, 6, 7, 8, 56, 57, - 58, 9, 10, 11, 12, 13, 14, 26, 27, 36, 37, 38, 50, 51, 52, 53, - 54, 55, 15, 16, 17, 18, 19, 20, 21, 25, 28, 29, 30, 31, 33, 34, - 35, 39, 43, 44, 45, 46, 47, 48, 49, 22, 23, 24, 40, 41, 42 -}; - -static const uint8_t huff_a21_cb[14] = { - 1, 12, 1, 0, 0, 2, 6, 0, 7, 21, 15, 17, 8, 4 -}; - -static const uint8_t huff_a21_xlat[81] = { + 0x8B, 0x9B, 0xAB, 0xBB, + /* Table set A, code table 1, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x3F, 0x02, 0x3E, 0x03, 0x04, 0x3B, 0x3C, 0x3D, 0x05, 0x06, + 0x07, 0x08, 0x38, 0x39, 0x3A, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x1A, + 0x1B, 0x24, 0x25, 0x26, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x0F, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x19, 0x1C, 0x1D, 0x1E, 0x1F, 0x21, 0x22, + 0x23, 0x27, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x16, 0x17, 0x18, + 0x28, 0x29, 0x2A, + /* Table set A, code table 2, wordlen 1 - 81 entries */ 0x00, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x03, 0xD0, 0x70, 0x34, 0x1C, 0x0D, 0x13, 0x07, 0x50, 0xF0, 0x44, 0xC4, 0x14, 0x74, 0x4C, 0xCC, 0xDC, 0x3C, 0x41, 0xC1, 0x11, 0x31, 0x05, 0x1D, 0x43, 0xC3, 0x33, 0x37, 0x0F, 0x54, 0xF4, 0xFC, 0xD1, 0x71, 0x15, 0x4D, 0xCD, 0xDD, 0xD3, 0x73, 0x47, 0xC7, 0x77, 0x3F, 0xD4, 0x5C, 0x7C, 0x51, 0xF1, 0x45, 0xC5, 0x55, 0x35, 0x3D, 0x53, 0xF3, 0x17, 0x4F, 0xCF, 0x1F, 0xFF, 0x75, 0xF5, 0x5D, - 0x7D, 0xD7, 0xF7, 0x5F, 0xDF, 0xD5, 0xFD, 0x57, 0x7F -}; - -static const uint8_t huff_a22_cb[10] = { 2, 9, 1, 4, 0, 4, 3, 8, 3, 2 }; - -static const uint8_t huff_a22_xlat[25] = { + 0x7D, 0xD7, 0xF7, 0x5F, 0xDF, 0xD5, 0xFD, 0x57, 0x7F, + /* Table set A, code table 2, wordlen 2 - 25 entries */ 0x00, 0x08, 0x38, 0x01, 0x07, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x02, 0x06, 0x30, 0x11, 0x31, 0x0A, 0x3A, 0x0E, 0x17, 0x37, 0x32, 0x16, 0x3E, 0x12, - 0x36 -}; - -static const uint8_t huff_a23_cb[9] = { 3, 9, 5, 0, 4, 6, 10, 16, 8 }; - -static const uint8_t huff_a23_xlat[49] = { + 0x36, + /* Table set A, code table 2, wordlen 3 - 49 entries */ 0x00, 0x08, 0x38, 0x01, 0x07, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x30, 0x02, 0x3A, 0x06, 0x0E, 0x18, 0x28, 0x11, 0x31, 0x0A, 0x03, 0x05, 0x3E, 0x17, 0x37, 0x19, 0x29, 0x12, 0x2A, 0x32, 0x0B, 0x33, 0x3B, 0x0D, 0x15, 0x3D, 0x16, 0x1E, 0x36, 0x1F, 0x2F, 0x1A, 0x13, 0x1B, 0x2B, 0x1D, 0x2D, 0x35, - 0x2E -}; - -static const uint8_t huff_a24_cb[5] = { 2, 4, 3, 1, 2 }; - -static const uint8_t huff_a25_cb[5] = { 2, 4, 1, 5, 2 }; - -static const uint8_t huff_a25_xlat[8] = { 1, 0, 2, 3, 4, 5, 6, 7 }; - -static const uint8_t huff_a26_cb[10] = { 4, 11, 3, 4, 12, 15, 34, 83, 75, 30 }; - -static const uint8_t huff_a26_xlat[256] = { + 0x2E, + /* Table set A, code table 2, wordlen 4 - 6 entries */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + /* Table set A, code table 2, wordlen 5 - 8 entries */ + 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + /* Table set A, code table 2, wordlen 6 - 256 entries */ 0x00, 0x01, 0x11, 0x10, 0x21, 0x12, 0x22, 0x20, 0x30, 0x31, 0x41, 0x02, 0x32, 0x03, 0x13, 0x23, 0x33, 0x14, 0x24, 0x40, 0x51, 0x61, 0x42, 0x52, 0x43, 0x53, 0x04, 0x34, 0x44, 0x15, 0x25, 0x35, 0x16, 0x26, 0x50, 0x60, @@ -703,43 +672,25 @@ static const uint8_t huff_a26_xlat[256] = { 0x8E, 0x9E, 0xAE, 0xBE, 0x0F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xB8, 0xA9, 0xB9, 0x9A, 0xAA, 0xBA, 0xCA, 0x9B, 0xAB, 0xBB, 0xCB, 0xEB, 0xFB, 0xAC, 0xBC, 0xCC, 0xEC, 0xFC, 0xDD, 0xED, 0xFD, 0xCE, 0xDE, 0xEE, 0xFE, 0xBF, - 0xCF, 0xDF, 0xEF, 0xFF -}; - -static const uint8_t huff_a27_cb[7] = { 4, 8, 3, 14, 10, 20, 16 }; - -static const uint8_t huff_a27_xlat[63] = { - 0, 2, 3, 1, 5, 6, 7, 9, 54, 55, 56, 58, 59, 60, 61, 62, - 63, 4, 8, 10, 11, 12, 14, 49, 52, 53, 57, 13, 15, 16, 17, 18, - 19, 22, 23, 25, 26, 30, 39, 43, 44, 45, 46, 47, 48, 50, 51, 20, - 21, 24, 27, 28, 29, 31, 33, 34, 35, 36, 37, 38, 40, 41, 42 -}; - -static const uint8_t huff_a31_cb[8] = { 1, 6, 1, 0, 3, 1, 0, 4 }; - -static const uint8_t huff_a31_xlat[9] = { - 0x00, 0x04, 0x0C, 0x01, 0x03, 0x05, 0x0D, 0x07, 0x0F -}; - -static const uint8_t huff_a32_cb[13] = { - 1, 11, 1, 0, 0, 2, 2, 6, 12, 18, 19, 15, 6 -}; - -static const uint8_t huff_a32_xlat[81] = { + 0xCF, 0xDF, 0xEF, 0xFF, + /* Table set A, code table 2, wordlen 7 - 63 entries */ + 0x00, 0x02, 0x03, 0x01, 0x05, 0x06, 0x07, 0x09, 0x36, 0x37, 0x38, 0x3A, + 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x04, 0x08, 0x0A, 0x0B, 0x0C, 0x0E, 0x31, + 0x34, 0x35, 0x39, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x19, + 0x1A, 0x1E, 0x27, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x32, 0x33, 0x14, + 0x15, 0x18, 0x1B, 0x1C, 0x1D, 0x1F, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x28, 0x29, 0x2A, + /* Table set A, code table 3, wordlen 1 - 9 entries */ + 0x00, 0x04, 0x0C, 0x01, 0x03, 0x05, 0x0D, 0x07, 0x0F, + /* Table set A, code table 3, wordlen 2 - 81 entries */ 0x00, 0x40, 0x01, 0x10, 0x04, 0x80, 0x50, 0x20, 0x14, 0x05, 0x02, 0x90, 0x60, 0x44, 0x54, 0x24, 0x08, 0x18, 0x41, 0x11, 0x15, 0x09, 0x06, 0xA0, 0x84, 0x94, 0x64, 0xA4, 0x48, 0x58, 0x28, 0x51, 0x21, 0x45, 0x55, 0x25, 0x19, 0x12, 0x16, 0x0A, 0x1A, 0x68, 0xA8, 0x81, 0x91, 0x61, 0xA1, 0x85, 0x95, 0x65, 0xA5, 0x49, 0x59, 0x29, 0x69, 0x42, 0x52, 0x46, 0x56, 0x2A, 0x88, 0x98, 0x89, 0x99, 0xA9, 0x82, 0x92, 0x22, 0x62, 0x86, 0x26, 0x66, - 0x4A, 0x5A, 0x6A, 0xA2, 0x96, 0xA6, 0x8A, 0x9A, 0xAA -}; - -static const uint8_t huff_a33_cb[12] = { - 3, 12, 1, 1, 13, 1, 14, 28, 33, 81, 32, 52 -}; - -static const uint8_t huff_a33_xlat[256] = { + 0x4A, 0x5A, 0x6A, 0xA2, 0x96, 0xA6, 0x8A, 0x9A, 0xAA, + /* Table set A, code table 3, wordlen 3 - 256 entries */ 0x00, 0x10, 0x40, 0x50, 0x04, 0x44, 0x14, 0x54, 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55, 0x90, 0x20, 0x94, 0x64, 0x18, 0x21, 0x95, 0x19, 0x69, 0x02, 0x52, 0x06, 0x46, 0x16, 0x80, 0x60, 0x84, 0xD4, 0x24, 0x08, @@ -761,16 +712,10 @@ static const uint8_t huff_a33_xlat[256] = { 0xF6, 0xCA, 0x3A, 0x7A, 0xCE, 0xDE, 0xAE, 0x3E, 0x7E, 0xBE, 0xFE, 0xD3, 0xA3, 0xE3, 0x33, 0x73, 0xF3, 0x87, 0xC7, 0xD7, 0x27, 0x67, 0xE7, 0x77, 0xF7, 0xCB, 0xDB, 0x2B, 0xAB, 0x3B, 0xBB, 0xFB, 0x8F, 0xCF, 0xDF, 0x6F, - 0xAF, 0xEF, 0x7F, 0xFF -}; - -static const uint8_t huff_a34_cb[7] = { 1, 5, 1, 1, 1, 1, 2 }; - -static const uint8_t huff_a34_xlat[6] = { 1, 0, 2, 3, 4, 5 }; - -static const uint8_t huff_a35_cb[11] = { 2, 10, 1, 0, 2, 3, 6, 19, 9, 75, 110 }; - -static const uint8_t huff_a35_xlat[225] = { + 0xAF, 0xEF, 0x7F, 0xFF, + /* Table set A, code table 3, wordlen 4 - 6 entries */ + 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, + /* Table set A, code table 3, wordlen 5 - 225 entries */ 0x00, 0xF0, 0x0F, 0x10, 0x01, 0xFF, 0x20, 0xE0, 0x11, 0xF1, 0x0E, 0x1F, 0x30, 0x40, 0xD0, 0x21, 0xE1, 0x02, 0x12, 0x22, 0xE2, 0xF2, 0x03, 0x13, 0x1E, 0x2E, 0x3E, 0xEE, 0xFE, 0x2F, 0xEF, 0xD2, 0x43, 0xF3, 0x04, 0x0D, @@ -789,14 +734,8 @@ static const uint8_t huff_a35_xlat[225] = { 0xB9, 0xC9, 0xD9, 0xE9, 0x1A, 0x5A, 0x6A, 0x7A, 0x9A, 0xAA, 0xBA, 0xCA, 0x1B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x9B, 0xBB, 0xCB, 0xDB, 0x6C, 0x7C, 0x9C, 0xAC, 0xBC, 0xEC, 0x5D, 0x7D, 0x9D, 0xAD, 0xDD, 0x5E, 0x7E, 0x9E, - 0xAE, 0xBE, 0x4F, 0x5F, 0x6F, 0x9F, 0xAF, 0xBF, 0xCF -}; - -static const uint8_t huff_a36_cb[12] = { - 3, 12, 1, 3, 5, 5, 13, 27, 69, 96, 35, 2 -}; - -static const uint8_t huff_a36_xlat[256] = { + 0xAE, 0xBE, 0x4F, 0x5F, 0x6F, 0x9F, 0xAF, 0xBF, 0xCF, + /* Table set A, code table 3, wordlen 6 - 256 entries */ 0x00, 0x10, 0x01, 0x11, 0x20, 0x21, 0x02, 0x12, 0x22, 0x31, 0x41, 0x32, 0x13, 0x23, 0x30, 0x40, 0x51, 0x42, 0x03, 0x33, 0x43, 0x04, 0x14, 0x24, 0x34, 0x15, 0x25, 0x50, 0x61, 0x71, 0xD1, 0x52, 0x62, 0x72, 0xD2, 0x53, @@ -818,51 +757,33 @@ static const uint8_t huff_a36_xlat[256] = { 0x8F, 0x9F, 0xAF, 0xB0, 0xB6, 0xB7, 0xA8, 0xB8, 0x99, 0xA9, 0xB9, 0xC9, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0x0B, 0x6B, 0x7B, 0x8B, 0x9B, 0xCB, 0xAC, 0xBC, 0xCC, 0xFC, 0xFD, 0xCE, 0xDE, 0xEE, 0xFE, 0xBF, 0xCF, 0xDF, - 0xEF, 0xFF, 0xAB, 0xBB -}; - -static const uint8_t huff_a37_cb[7] = { 4, 8, 7, 6, 8, 22, 20 }; - -static const uint8_t huff_a37_xlat[63] = { - 0, 1, 2, 3, 61, 62, 63, 4, 5, 6, 58, 59, 60, 7, 8, 9, - 10, 54, 55, 56, 57, 11, 12, 13, 14, 15, 16, 25, 26, 27, 28, 29, - 30, 35, 36, 37, 38, 48, 49, 50, 51, 52, 53, 17, 18, 19, 20, 21, - 22, 23, 24, 31, 33, 34, 39, 40, 41, 42, 43, 44, 45, 46, 47 -}; - -static const uint8_t huff_a41_cb[14] = { - 1, 12, 1, 0, 0, 6, 2, 0, 0, 0, 19, 9, 24, 20 -}; - -static const uint8_t huff_a41_xlat[81] = { + 0xEF, 0xFF, 0xAB, 0xBB, + /* Table set A, code table 3, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x02, 0x03, 0x3D, 0x3E, 0x3F, 0x04, 0x05, 0x06, 0x3A, 0x3B, + 0x3C, 0x07, 0x08, 0x09, 0x0A, 0x36, 0x37, 0x38, 0x39, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x23, 0x24, 0x25, + 0x26, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x1F, 0x21, 0x22, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, + 0x2D, 0x2E, 0x2F, + /* Table set A, code table 4, wordlen 1 - 81 entries */ 0x00, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x03, 0x50, 0xD0, 0x70, 0xF0, 0xC4, 0x34, 0x4C, 0xCC, 0x1C, 0x41, 0xC1, 0x31, 0x05, 0x0D, 0x43, 0xC3, 0x13, 0x07, 0x0F, 0x44, 0x14, 0x74, 0xDC, 0x3C, 0x11, 0x1D, 0x33, 0x37, 0x54, 0xD4, 0xF4, 0x5C, 0x7C, 0xFC, 0xD1, 0x71, 0xF1, 0xC5, 0x15, 0x35, 0x4D, 0xCD, 0xDD, 0x3D, 0xD3, 0x73, 0x47, 0xC7, 0x17, 0x77, 0x1F, 0x3F, 0x51, 0x45, 0x55, 0xD5, 0x75, 0xF5, 0x5D, 0x7D, 0xFD, 0x53, 0xF3, - 0x57, 0xD7, 0xF7, 0x4F, 0xCF, 0x5F, 0xDF, 0x7F, 0xFF -}; - -static const uint8_t huff_a42_cb[10] = { 3, 10, 1, 2, 13, 1, 31, 13, 16, 4 }; - -static const uint8_t huff_a42_xlat[81] = { + 0x57, 0xD7, 0xF7, 0x4F, 0xCF, 0x5F, 0xDF, 0x7F, 0xFF, + /* Table set A, code table 4, wordlen 2 - 81 entries */ 0x00, 0x40, 0x01, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55, 0x59, 0x80, 0x90, 0x20, 0x60, 0x84, 0x94, 0x24, 0x64, 0x08, 0x48, 0x18, 0x58, 0x81, 0x91, 0x21, 0x61, 0x85, 0x95, 0x25, 0x65, 0x09, 0x49, 0x19, 0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56, 0xA0, 0xA4, 0x68, 0xA1, 0xA5, 0x99, 0x29, 0x69, 0x96, 0x66, 0x4A, 0x1A, 0x5A, 0x88, 0x98, 0x28, 0x89, 0xA9, 0x82, 0x92, 0x22, 0x62, 0x86, 0x26, - 0xA6, 0x0A, 0x9A, 0x2A, 0x6A, 0xA8, 0xA2, 0x8A, 0xAA -}; - -static const uint8_t huff_a43_cb[5] = { 2, 4, 2, 3, 2 }; - -static const uint8_t huff_a43_xlat[7] = { 0, 7, 1, 2, 6, 3, 5 }; - -static const uint8_t huff_a44_cb[9] = { 4, 10, 5, 4, 12, 17, 47, 24, 12 }; - -static const uint8_t huff_a44_xlat[121] = { + 0xA6, 0x0A, 0x9A, 0x2A, 0x6A, 0xA8, 0xA2, 0x8A, 0xAA, + /* Table set A, code table 4, wordlen 3 - 7 entries */ + 0x00, 0x07, 0x01, 0x02, 0x06, 0x03, 0x05, + /* Table set A, code table 4, wordlen 4 - 121 entries */ 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x21, 0xE1, 0x02, 0x12, 0xF2, 0x0E, 0x1E, 0xFE, 0x2F, 0xEF, 0x30, 0x50, 0xD0, 0xD1, 0x22, 0xE2, 0x03, 0x13, 0xF3, 0x0D, 0x1D, 0x2D, 0xFD, 0x2E, 0xEE, @@ -873,16 +794,10 @@ static const uint8_t huff_a44_xlat[121] = { 0xCF, 0x42, 0x52, 0x33, 0x53, 0xC3, 0x24, 0xB4, 0xD4, 0x25, 0x35, 0xC5, 0x4B, 0xCB, 0xDB, 0x3C, 0x4C, 0x5C, 0xDC, 0xEC, 0x4D, 0xBD, 0xCD, 0xDD, 0xCE, 0x43, 0x34, 0x44, 0x54, 0xC4, 0x45, 0x55, 0xB5, 0x5B, 0xBB, 0xBC, - 0xCC -}; - -static const uint8_t huff_a45_cb[5] = { 2, 4, 2, 2, 4 }; - -static const uint8_t huff_a45_xlat[8] = { 1, 2, 0, 3, 4, 5, 6, 7 }; - -static const uint8_t huff_a46_cb[7] = { 5, 9, 1, 16, 31, 36, 172 }; - -static const uint8_t huff_a46_xlat[256] = { + 0xCC, + /* Table set A, code table 4, wordlen 5 - 8 entries */ + 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, + /* Table set A, code table 4, wordlen 6 - 256 entries */ 0x02, 0x00, 0x30, 0x21, 0x31, 0x41, 0x61, 0x12, 0x22, 0x42, 0x62, 0x43, 0x53, 0x24, 0x45, 0x26, 0x27, 0x10, 0x40, 0xB0, 0x01, 0x11, 0x81, 0x32, 0x52, 0x72, 0x92, 0x03, 0x13, 0x33, 0x63, 0x14, 0x34, 0x54, 0x64, 0x74, @@ -904,45 +819,29 @@ static const uint8_t huff_a46_xlat[256] = { 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, - 0xCF, 0xDF, 0xEF, 0xFF -}; - -static const uint8_t huff_a47_cb[8] = { 4, 9, 5, 12, 9, 12, 15, 10 }; - -static const uint8_t huff_a47_xlat[63] = { - 0, 1, 2, 62, 63, 3, 4, 5, 6, 8, 54, 56, 57, 58, 59, 60, - 61, 7, 9, 10, 11, 12, 13, 14, 53, 55, 15, 16, 17, 18, 19, 20, - 21, 36, 37, 39, 42, 52, 22, 25, 28, 35, 38, 40, 41, 43, 45, 46, - 47, 48, 49, 50, 51, 23, 24, 26, 27, 29, 30, 31, 33, 34, 44 -}; - -static const uint8_t huff_a51_cb[12] = { - 2, 11, 1, 0, 6, 2, 6, 18, 4, 26, 6, 12 -}; - -static const uint8_t huff_a51_xlat[81] = { + 0xCF, 0xDF, 0xEF, 0xFF, + /* Table set A, code table 4, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x02, 0x3E, 0x3F, 0x03, 0x04, 0x05, 0x06, 0x08, 0x36, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x07, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x35, 0x37, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x24, 0x25, 0x27, + 0x2A, 0x34, 0x16, 0x19, 0x1C, 0x23, 0x26, 0x28, 0x29, 0x2B, 0x2D, 0x2E, + 0x2F, 0x30, 0x31, 0x32, 0x33, 0x17, 0x18, 0x1A, 0x1B, 0x1D, 0x1E, 0x1F, + 0x21, 0x22, 0x2C, + /* Table set A, code table 5, wordlen 1 - 81 entries */ 0x00, 0x40, 0xC0, 0x30, 0x04, 0x01, 0x03, 0x10, 0x0C, 0xD0, 0x70, 0x34, 0x1C, 0x0D, 0x07, 0x50, 0xF0, 0x44, 0xC4, 0x14, 0x4C, 0xCC, 0x3C, 0x41, 0xC1, 0x11, 0x31, 0x05, 0x43, 0xC3, 0x13, 0x33, 0x0F, 0x74, 0xDC, 0x1D, 0x37, 0x54, 0xD4, 0xF4, 0x5C, 0x7C, 0xFC, 0xD1, 0x71, 0xF1, 0xC5, 0x15, 0x35, 0x4D, 0xCD, 0xDD, 0x3D, 0x53, 0xD3, 0x73, 0x47, 0xC7, 0x17, 0x77, 0x4F, 0x1F, 0x3F, 0x51, 0x45, 0x55, 0xF3, 0xCF, 0xFF, 0xD5, 0x75, 0xF5, - 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F -}; - -static const uint8_t huff_a52_cb[12] = { 1, 10, 1, 0, 2, 2, 0, 4, 3, 8, 3, 2 }; - -static const uint8_t huff_a52_xlat[25] = { + 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F, + /* Table set A, code table 5, wordlen 2 - 25 entries */ 0x00, 0x08, 0x38, 0x01, 0x07, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x02, 0x06, 0x30, 0x11, 0x31, 0x0A, 0x3A, 0x0E, 0x17, 0x37, 0x32, 0x16, 0x3E, 0x12, - 0x36 -}; - -static const uint8_t huff_a53_xlat[7] = { 0, 1, 2, 6, 7, 3, 5 }; - -static const uint8_t huff_a54_cb[8] = { 4, 9, 4, 7, 12, 19, 21, 58 }; - -static const uint8_t huff_a54_xlat[121] = { + 0x36, + /* Table set A, code table 5, wordlen 3 - 7 entries */ + 0x00, 0x01, 0x02, 0x06, 0x07, 0x03, 0x05, + /* Table set A, code table 5, wordlen 4 - 121 entries */ 0x00, 0x01, 0x0F, 0x1F, 0x10, 0xE0, 0xF0, 0x11, 0xF1, 0x2F, 0xFF, 0x20, 0x21, 0xE1, 0x02, 0x12, 0xF2, 0x03, 0xF3, 0x0E, 0x2E, 0xFE, 0x3F, 0x30, 0x40, 0xD0, 0xC1, 0xD1, 0x22, 0xC2, 0x33, 0xE3, 0x0C, 0xCC, 0x0D, 0x1D, @@ -953,58 +852,33 @@ static const uint8_t huff_a54_xlat[121] = { 0xE4, 0xF4, 0x05, 0x15, 0x25, 0x35, 0x55, 0xB5, 0xC5, 0xD5, 0xE5, 0x0B, 0x1B, 0x2B, 0x3B, 0xBB, 0xCB, 0xDB, 0xEB, 0x2C, 0x3C, 0x4C, 0x5C, 0xBC, 0xDC, 0xEC, 0xFC, 0x4D, 0x5D, 0xCD, 0xED, 0x4E, 0xBE, 0xCE, 0xDE, 0x4F, - 0x5F -}; - -static const uint8_t huff_a55_cb[8] = { 1, 6, 1, 1, 1, 0, 3, 2 }; - -static const uint8_t huff_a55_xlat[8] = { 0, 1, 2, 3, 6, 7, 4, 5 }; - -static const uint8_t huff_a56_cb[7] = { 3, 7, 1, 8, 6, 8, 8 }; - -static const uint8_t huff_a56_xlat[31] = { - 4, 0, 1, 2, 3, 28, 29, 30, 31, 5, 6, 7, 24, 25, 27, 8, - 9, 14, 19, 21, 22, 23, 26, 10, 11, 12, 13, 15, 17, 18, 20 -}; - -static const uint8_t huff_a57_cb[9] = { 3, 9, 1, 5, 7, 8, 16, 22, 4 }; - -static const uint8_t huff_a57_xlat[63] = { - 0, 1, 2, 61, 62, 63, 3, 4, 5, 6, 58, 59, - 60, 7, 8, 9, 10, 54, 55, 56, 57, 11, 12, 13, - 14, 15, 26, 27, 28, 36, 37, 38, 49, 50, 51, 52, - 53, 16, 17, 18, 19, 20, 21, 23, 24, 25, 29, 30, - 31, 33, 34, 35, 39, 43, 44, 45, 46, 47, 48, 22, - 40, 41, 42 -}; - -static const uint8_t huff_a61_cb[12] = { - 2, 11, 1, 0, 8, 0, 1, 16, 10, 29, 12, 4 -}; - -static const uint8_t huff_a61_xlat[81] = { + 0x5F, + /* Table set A, code table 5, wordlen 5 - 8 entries */ + 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05, + /* Table set A, code table 5, wordlen 6 - 31 entries */ + 0x04, 0x00, 0x01, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F, 0x05, 0x06, 0x07, + 0x18, 0x19, 0x1B, 0x08, 0x09, 0x0E, 0x13, 0x15, 0x16, 0x17, 0x1A, 0x0A, + 0x0B, 0x0C, 0x0D, 0x0F, 0x11, 0x12, 0x14, + /* Table set A, code table 5, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x02, 0x3D, 0x3E, 0x3F, 0x03, 0x04, 0x05, 0x06, 0x3A, 0x3B, + 0x3C, 0x07, 0x08, 0x09, 0x0A, 0x36, 0x37, 0x38, 0x39, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x1A, 0x1B, 0x1C, 0x24, 0x25, 0x26, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x17, 0x18, 0x19, 0x1D, 0x1E, + 0x1F, 0x21, 0x22, 0x23, 0x27, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x16, + 0x28, 0x29, 0x2A, + /* Table set A, code table 6, wordlen 1 - 81 entries */ 0x00, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x03, 0x70, 0x50, 0xD0, 0xF0, 0x44, 0xC4, 0x14, 0x34, 0x4C, 0x1C, 0x3C, 0x31, 0x05, 0x0D, 0x13, 0x07, 0x0F, 0x74, 0xCC, 0xDC, 0xFC, 0x41, 0xC1, 0x11, 0x43, 0xC3, 0x33, 0x54, 0xD4, 0xF4, 0x5C, 0x7C, 0x51, 0xD1, 0x71, 0xF1, 0x45, 0xC5, 0x15, 0x35, 0x4D, 0xCD, 0x1D, 0x3D, 0x53, 0xD3, 0x73, 0xF3, 0x47, 0xC7, 0x17, 0x37, 0x4F, 0xCF, 0x1F, 0x3F, 0x55, 0xD5, 0x75, 0xF5, 0x5D, 0xDD, 0xFD, - 0x57, 0xD7, 0x77, 0xF7, 0xFF, 0x7D, 0x5F, 0xDF, 0x7F -}; - -static const uint8_t huff_a62_cb[8] = { 3, 8, 5, 2, 2, 9, 5, 2 }; - -static const uint8_t huff_a62_xlat[25] = { + 0x57, 0xD7, 0x77, 0xF7, 0xFF, 0x7D, 0x5F, 0xDF, 0x7F, + /* Table set A, code table 6, wordlen 2 - 25 entries */ 0x00, 0x08, 0x38, 0x01, 0x07, 0x39, 0x0F, 0x09, 0x3F, 0x10, 0x30, 0x31, 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x37, 0x11, 0x0A, 0x32, 0x16, 0x3E, 0x12, - 0x36 -}; - -static const uint8_t huff_a63_cb[11] = { - 3, 11, 1, 1, 10, 4, 16, 29, 46, 75, 74 -}; - -static const uint8_t huff_a63_xlat[256] = { + 0x36, + /* Table set A, code table 6, wordlen 3 - 256 entries */ 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x01, 0x41, 0x05, 0x45, 0x55, 0x54, 0x11, 0x51, 0x15, 0x80, 0x90, 0x60, 0x24, 0x64, 0xA4, 0x48, 0x61, 0x95, 0x25, 0xA5, 0x02, 0x42, 0x52, 0x16, 0x56, 0x20, 0x84, 0x94, 0x18, @@ -1026,12 +900,8 @@ static const uint8_t huff_a63_xlat[256] = { 0xBA, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xAE, 0xEE, 0x3E, 0xC3, 0x93, 0xD3, 0xE3, 0x33, 0x73, 0xF3, 0xC7, 0x67, 0xA7, 0xE7, 0x37, 0xB7, 0xF7, 0xCB, 0xDB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, 0x0F, 0x4F, 0x8F, 0x5F, 0xDF, 0x6F, - 0xAF, 0xEF, 0x3F, 0xFF -}; - -static const uint8_t huff_a64_cb[8] = { 4, 9, 1, 7, 12, 36, 63, 2 }; - -static const uint8_t huff_a64_xlat[121] = { + 0xAF, 0xEF, 0x3F, 0xFF, + /* Table set A, code table 6, wordlen 4 - 121 entries */ 0x00, 0x10, 0x20, 0xE0, 0xF0, 0x02, 0x0E, 0xEF, 0x30, 0x01, 0x11, 0x21, 0x31, 0xF1, 0x12, 0xF2, 0x1E, 0xEE, 0xDF, 0xFF, 0x40, 0xC0, 0xD0, 0xD1, 0xE1, 0x22, 0x32, 0x42, 0xD2, 0xE2, 0x03, 0x13, 0x23, 0xB3, 0xC3, 0xE3, @@ -1042,62 +912,38 @@ static const uint8_t huff_a64_xlat[121] = { 0xB5, 0xC5, 0xD5, 0xE5, 0x0B, 0x1B, 0x3B, 0x4B, 0x5B, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0xBC, 0xCC, 0xDC, 0xEC, 0x0D, 0x3D, 0x4D, 0x5D, 0xCD, 0xED, 0x3E, 0x5E, 0xBE, 0xCE, 0x4F, 0xCF, 0x5F, - 0xBF -}; - -static const uint8_t huff_a65_cb[8] = { 2, 7, 3, 0, 1, 3, 4, 4 }; - -static const uint8_t huff_a65_xlat[15] = { - 0, 1, 15, 14, 2, 3, 13, 4, 6, 10, 12, 5, 7, 9, 11 -}; - -static const uint8_t huff_a66_cb[11] = { 2, 10, 1, 2, 2, 6, 8, 6, 3, 1, 2 }; - -static const uint8_t huff_a66_xlat[31] = { - 0, 1, 31, 2, 30, 3, 4, 15, 17, 28, 29, 5, 6, 7, 8, 24, - 25, 26, 27, 9, 10, 11, 21, 22, 23, 12, 19, 20, 13, 14, 18 -}; - -static const uint8_t huff_a67_cb[10] = { 2, 9, 1, 1, 3, 4, 6, 13, 25, 10 }; - -static const uint8_t huff_a67_xlat[63] = { - 0, 1, 2, 62, 63, 3, 4, 60, 61, 5, 6, 7, 57, 58, 59, 8, - 9, 10, 11, 12, 13, 26, 38, 52, 53, 54, 55, 56, 14, 15, 16, 17, - 18, 19, 25, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 39, 45, 46, - 47, 48, 49, 50, 51, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44 -}; - -static const uint8_t huff_a71_cb[5] = { 1, 3, 1, 1, 2 }; - -static const uint8_t huff_a72_cb[12] = { - 2, 11, 1, 0, 4, 8, 3, 8, 24, 17, 12, 4 -}; - -static const uint8_t huff_a72_xlat[81] = { + 0xBF, + /* Table set A, code table 6, wordlen 5 - 15 entries */ + 0x00, 0x01, 0x0F, 0x0E, 0x02, 0x03, 0x0D, 0x04, 0x06, 0x0A, 0x0C, 0x05, + 0x07, 0x09, 0x0B, + /* Table set A, code table 6, wordlen 6 - 31 entries */ + 0x00, 0x01, 0x1F, 0x02, 0x1E, 0x03, 0x04, 0x0F, 0x11, 0x1C, 0x1D, 0x05, + 0x06, 0x07, 0x08, 0x18, 0x19, 0x1A, 0x1B, 0x09, 0x0A, 0x0B, 0x15, 0x16, + 0x17, 0x0C, 0x13, 0x14, 0x0D, 0x0E, 0x12, + /* Table set A, code table 6, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x02, 0x3E, 0x3F, 0x03, 0x04, 0x3C, 0x3D, 0x05, 0x06, 0x07, + 0x39, 0x3A, 0x3B, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x1A, 0x26, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x19, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x2D, 0x2E, + 0x2F, 0x30, 0x31, 0x32, 0x33, 0x14, 0x15, 0x16, 0x17, 0x18, 0x28, 0x29, + 0x2A, 0x2B, 0x2C, + /* Table set A, code table 7, wordlen 1 - 4 entries */ + 0x00, 0x01, 0x02, 0x03, + /* Table set A, code table 7, wordlen 2 - 81 entries */ 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x05, 0x15, 0x51, 0x45, 0x55, 0x80, 0x90, 0x20, 0x64, 0x08, 0x19, 0x02, 0x06, 0x60, 0x84, 0x94, 0x24, 0x48, 0x18, 0x58, 0x81, 0x91, 0x21, 0x61, 0x85, 0x95, 0x25, 0x65, 0x09, 0x49, 0x59, 0x42, 0x12, 0x52, 0x46, 0x16, 0x56, 0xA0, 0xA4, 0x98, 0x28, 0x68, 0xA1, 0xA5, 0x99, 0x29, 0x69, 0x96, 0x26, 0x66, 0x0A, 0x4A, 0x1A, 0x5A, 0x88, 0xA8, 0x89, 0xA9, 0x82, 0x92, 0x22, - 0x62, 0x86, 0xA6, 0x2A, 0x6A, 0xA2, 0x8A, 0x9A, 0xAA -}; - -static const uint8_t huff_a73_cb[11] = { 2, 10, 1, 1, 5, 2, 8, 7, 13, 8, 4 }; - -static const uint8_t huff_a73_xlat[49] = { + 0x62, 0x86, 0xA6, 0x2A, 0x6A, 0xA2, 0x8A, 0x9A, 0xAA, + /* Table set A, code table 7, wordlen 3 - 49 entries */ 0x00, 0x08, 0x38, 0x01, 0x39, 0x07, 0x0F, 0x09, 0x3F, 0x10, 0x30, 0x31, 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x11, 0x0A, 0x32, 0x0D, 0x16, 0x3E, 0x37, 0x18, 0x28, 0x19, 0x29, 0x12, 0x2A, 0x03, 0x3B, 0x05, 0x15, 0x1E, 0x1F, 0x2F, 0x1A, 0x0B, 0x2B, 0x33, 0x35, 0x3D, 0x2E, 0x36, 0x13, 0x1B, 0x1D, - 0x2D -}; - -static const uint8_t huff_a74_cb[14] = { - 1, 12, 1, 0, 0, 4, 0, 4, 5, 9, 30, 45, 21, 2 -}; - -static const uint8_t huff_a74_xlat[121] = { + 0x2D, + /* Table set A, code table 7, wordlen 4 - 121 entries */ 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x02, 0xF2, 0x0E, 0x21, 0xE1, 0x12, 0xE2, 0x1E, 0x2E, 0xFE, 0x2F, 0xEF, 0x30, 0x50, 0xB0, 0xC0, 0xD0, 0x31, 0xB1, 0xD1, 0x22, 0xD2, 0x03, 0x13, 0xE3, @@ -1108,20 +954,11 @@ static const uint8_t huff_a74_xlat[121] = { 0xEC, 0xFC, 0x3D, 0x5D, 0xDD, 0xED, 0x4E, 0x5E, 0xBE, 0xCE, 0xDE, 0x4F, 0xBF, 0xCF, 0x43, 0x53, 0x34, 0x54, 0xB4, 0xC4, 0x35, 0x45, 0x55, 0xB5, 0x4B, 0x5B, 0xCB, 0xDB, 0x4C, 0xBC, 0xCC, 0xDC, 0x4D, 0xBD, 0xCD, 0x44, - 0xBB -}; - -static const uint8_t huff_a75_cb[7] = { 2, 6, 1, 3, 3, 4, 4 }; - -static const uint8_t huff_a75_xlat[15] = { - 0, 1, 14, 15, 2, 3, 13, 4, 6, 10, 12, 5, 7, 9, 11 -}; - -static const uint8_t huff_a76_cb[12] = { - 3, 12, 1, 3, 4, 8, 10, 36, 60, 78, 48, 8 -}; - -static const uint8_t huff_a76_xlat[256] = { + 0xBB, + /* Table set A, code table 7, wordlen 5 - 15 entries */ + 0x00, 0x01, 0x0E, 0x0F, 0x02, 0x03, 0x0D, 0x04, 0x06, 0x0A, 0x0C, 0x05, + 0x07, 0x09, 0x0B, + /* Table set A, code table 7, wordlen 6 - 256 entries */ 0x00, 0x10, 0x01, 0x11, 0x20, 0x21, 0x02, 0x12, 0x30, 0x31, 0x41, 0x22, 0x03, 0x13, 0x23, 0x14, 0x40, 0x51, 0x61, 0x32, 0x42, 0x33, 0x04, 0x24, 0x15, 0x16, 0x50, 0x60, 0xD0, 0x71, 0x81, 0xD1, 0xE1, 0xF1, 0x52, 0x62, @@ -1143,52 +980,30 @@ static const uint8_t huff_a76_xlat[256] = { 0xC9, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xCA, 0xFA, 0x5B, 0x6B, 0x7B, 0x8B, 0xCB, 0xEB, 0xFB, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xEC, 0xFC, 0xDD, 0xED, 0xFD, 0xCE, 0xDE, 0xEE, 0xFE, 0xBF, 0xCF, 0xDF, 0xB7, 0xBA, 0x9B, 0xAB, - 0xBB, 0xCC, 0xEF, 0xFF -}; - -static const uint8_t huff_b01_cb[14] = { - 1, 12, 1, 0, 0, 2, 6, 0, 11, 13, 12, 24, 4, 8 -}; - -static const uint8_t huff_b01_xlat[81] = { + 0xBB, 0xCC, 0xEF, 0xFF, + /* Table set B, code table 0, wordlen 1 - 81 entries */ 0x00, 0x01, 0x03, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x50, 0xD0, 0x70, 0xF0, 0x34, 0x1C, 0x05, 0x0D, 0x13, 0x07, 0x0F, 0x44, 0xC4, 0x14, 0x4C, 0xCC, 0x3C, 0x41, 0xC1, 0x11, 0x31, 0x43, 0xC3, 0x33, 0x54, 0x74, 0xDC, 0xFC, 0x71, 0x15, 0x4D, 0x1D, 0xD3, 0xC7, 0x37, 0x3F, 0xD4, 0xF4, 0x5C, 0x7C, 0x51, 0xD1, 0xF1, 0x45, 0xC5, 0x55, 0x35, 0xCD, 0xDD, 0x3D, 0x53, 0x73, 0xF3, 0x47, 0x17, 0x77, 0x4F, 0xCF, 0x1F, 0xFF, 0xF5, 0x7D, 0xD7, - 0x5F, 0xD5, 0x75, 0x5D, 0xFD, 0x57, 0xF7, 0xDF, 0x7F -}; - -static const uint8_t huff_b02_cb[14] = { - 1, 12, 1, 0, 0, 4, 0, 8, 4, 9, 19, 13, 13, 10 -}; - -static const uint8_t huff_b02_xlat[81] = { + 0x5F, 0xD5, 0x75, 0x5D, 0xFD, 0x57, 0xF7, 0xDF, 0x7F, + /* Table set B, code table 0, wordlen 2 - 81 entries */ 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x05, 0x15, 0x80, 0x51, 0x45, 0x55, 0x90, 0x20, 0x60, 0x24, 0x08, 0x18, 0x09, 0x02, 0x06, 0x84, 0x94, 0x64, 0x48, 0x58, 0x81, 0x91, 0x21, 0x61, 0x95, 0x25, 0x65, 0x19, 0x59, 0x42, 0x12, 0x46, 0x16, 0x56, 0xA0, 0xA4, 0x28, 0x68, 0x85, 0xA5, 0x49, 0x29, 0x69, 0x52, 0x0A, 0x1A, 0x5A, 0x88, 0x98, 0xA1, 0x89, 0x99, 0xA9, 0x22, 0x62, 0x96, 0x26, 0x66, 0x4A, 0x6A, 0xA8, - 0x82, 0x92, 0xA2, 0x86, 0xA6, 0x8A, 0x9A, 0x2A, 0xAA -}; - -static const uint8_t huff_b03_cb[11] = { 1, 9, 1, 0, 0, 4, 0, 5, 12, 13, 14 }; - -static const uint8_t huff_b03_xlat[49] = { + 0x82, 0x92, 0xA2, 0x86, 0xA6, 0x8A, 0x9A, 0x2A, 0xAA, + /* Table set B, code table 0, wordlen 3 - 49 entries */ 0x00, 0x08, 0x38, 0x01, 0x07, 0x30, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x18, 0x28, 0x31, 0x02, 0x3A, 0x03, 0x05, 0x06, 0x0E, 0x17, 0x37, 0x11, 0x19, 0x29, 0x0A, 0x32, 0x0B, 0x3B, 0x0D, 0x15, 0x3D, 0x3E, 0x1F, 0x2F, 0x12, 0x1A, 0x2A, 0x13, 0x1B, 0x2B, 0x33, 0x1D, 0x2D, 0x35, 0x16, 0x1E, 0x2E, - 0x36 -}; - -static const uint8_t huff_b04_cb[12] = { - 2, 11, 1, 0, 4, 4, 5, 9, 30, 45, 21, 2 -}; - -static const uint8_t huff_b04_xlat[121] = { + 0x36, + /* Table set B, code table 0, wordlen 4 - 121 entries */ 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x02, 0xF2, 0x0E, 0x21, 0xE1, 0x12, 0xE2, 0x1E, 0x2E, 0xFE, 0x2F, 0xEF, 0x30, 0x50, 0xB0, 0xC0, 0xD0, 0x31, 0xB1, 0xD1, 0x22, 0xD2, 0x03, 0x13, 0xE3, @@ -1199,14 +1014,8 @@ static const uint8_t huff_b04_xlat[121] = { 0xEC, 0xFC, 0x3D, 0x5D, 0xDD, 0xED, 0x4E, 0x5E, 0xBE, 0xCE, 0xDE, 0x4F, 0xBF, 0xCF, 0x43, 0x53, 0x34, 0x54, 0xB4, 0xC4, 0x35, 0x45, 0x55, 0xB5, 0x4B, 0x5B, 0xCB, 0xDB, 0x4C, 0xBC, 0xCC, 0xDC, 0x4D, 0xBD, 0xCD, 0x44, - 0xBB -}; - -static const uint8_t huff_b05_cb[11] = { - 3, 11, 1, 4, 4, 4, 12, 30, 73, 75, 22 -}; - -static const uint8_t huff_b05_xlat[225] = { + 0xBB, + /* Table set B, code table 0, wordlen 5 - 225 entries */ 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x02, 0x0E, 0x30, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x03, 0x0D, 0x1E, 0xFE, 0x2F, 0xEF, 0x40, 0x60, 0x70, 0x90, 0xA0, 0xC0, 0x31, 0xD1, 0x22, 0x32, 0xD2, @@ -1225,35 +1034,23 @@ static const uint8_t huff_b05_xlat[225] = { 0x3B, 0x6B, 0x7B, 0x9B, 0xAB, 0xDB, 0xEB, 0x3C, 0x4C, 0x6C, 0x7C, 0x9C, 0xAC, 0xCC, 0xDC, 0x4D, 0x5D, 0x6D, 0xAD, 0xBD, 0xCD, 0x5E, 0xBE, 0x54, 0x45, 0x55, 0xB5, 0xC5, 0x76, 0x96, 0x67, 0x77, 0x97, 0xA7, 0x79, 0x99, - 0xA9, 0x7A, 0x9A, 0x4B, 0x5B, 0xBB, 0xCB, 0x5C, 0xBC -}; - -static const uint8_t huff_b07_cb[9] = { 3, 9, 3, 2, 4, 8, 23, 13, 10 }; - -static const uint8_t huff_b07_xlat[63] = { - 0, 1, 63, 2, 62, 3, 4, 60, 61, 5, 6, 7, 8, 56, 57, 58, - 59, 9, 10, 11, 12, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, - 37, 38, 39, 51, 52, 53, 54, 55, 13, 14, 15, 16, 17, 18, 19, 45, - 46, 47, 48, 49, 50, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44 -}; - -static const uint8_t huff_b12_cb[10] = { 3, 10, 1, 3, 12, 0, 30, 9, 18, 8 }; - -static const uint8_t huff_b12_xlat[81] = { + 0xA9, 0x7A, 0x9A, 0x4B, 0x5B, 0xBB, 0xCB, 0x5C, 0xBC, + /* Table set B, code table 0, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x3F, 0x02, 0x3E, 0x03, 0x04, 0x3C, 0x3D, 0x05, 0x06, 0x07, + 0x08, 0x38, 0x39, 0x3A, 0x3B, 0x09, 0x0A, 0x0B, 0x0C, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x2D, + 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x14, 0x15, 0x16, 0x17, 0x18, 0x28, 0x29, + 0x2A, 0x2B, 0x2C, + /* Table set B, code table 1, wordlen 2 - 81 entries */ 0x00, 0x40, 0x04, 0x01, 0x10, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55, 0x80, 0x90, 0x20, 0x60, 0x84, 0x94, 0x24, 0x64, 0x08, 0x48, 0x18, 0x81, 0x91, 0x61, 0x85, 0x95, 0x25, 0x65, 0x09, 0x49, 0x19, 0x59, 0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56, 0xA4, 0x58, 0x68, 0x21, 0xA5, 0x29, 0x69, 0x1A, 0x5A, 0xA0, 0x88, 0x98, 0x28, 0xA1, 0x89, 0x99, 0xA9, 0x92, 0x22, 0x62, 0x86, 0x96, 0x26, 0x66, 0x0A, 0x4A, - 0x6A, 0xA8, 0x82, 0xA2, 0xA6, 0x8A, 0x9A, 0x2A, 0xAA -}; - -static const uint8_t huff_b14_cb[14] = { - 1, 12, 1, 0, 0, 4, 0, 3, 5, 16, 28, 34, 26, 4 -}; - -static const uint8_t huff_b14_xlat[121] = { + 0x6A, 0xA8, 0x82, 0xA2, 0xA6, 0x8A, 0x9A, 0x2A, 0xAA, + /* Table set B, code table 1, wordlen 4 - 121 entries */ 0x00, 0x10, 0xF0, 0x01, 0x0F, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x11, 0x02, 0x0E, 0x30, 0x50, 0xB0, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x03, 0x05, 0x0B, 0x0D, 0x1E, 0xFE, 0x2F, 0xEF, 0x40, 0xC0, 0x31, 0x51, 0xB1, 0xC1, 0xD1, @@ -1264,14 +1061,8 @@ static const uint8_t huff_b14_xlat[121] = { 0xED, 0x3E, 0x4E, 0xBE, 0xDE, 0x4F, 0xCF, 0xC2, 0x33, 0x43, 0xC3, 0xD3, 0x34, 0x44, 0x54, 0xB4, 0xD4, 0x45, 0x55, 0xC5, 0x4B, 0xCB, 0x3C, 0x4C, 0x5C, 0xCC, 0xDC, 0x3D, 0x4D, 0x5D, 0xCD, 0xDD, 0xCE, 0xC4, 0xB5, 0x5B, - 0xBB -}; - -static const uint8_t huff_b16_cb[11] = { - 4, 12, 4, 4, 9, 13, 37, 76, 72, 39, 2 -}; - -static const uint8_t huff_b16_xlat[256] = { + 0xBB, + /* Table set B, code table 1, wordlen 6 - 256 entries */ 0x00, 0x10, 0x01, 0x11, 0x20, 0x21, 0x02, 0x12, 0x30, 0x31, 0x41, 0x22, 0x32, 0x03, 0x13, 0x23, 0x14, 0x40, 0x51, 0x61, 0x42, 0x52, 0x33, 0x43, 0x04, 0x24, 0x34, 0x15, 0x25, 0x16, 0x50, 0x60, 0x70, 0x71, 0x81, 0xD1, @@ -1293,14 +1084,8 @@ static const uint8_t huff_b16_xlat[256] = { 0xA8, 0xB8, 0xC8, 0x99, 0xA9, 0xB9, 0xC9, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xFA, 0x6B, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xFB, 0x9C, 0xAC, 0xBC, 0xCC, 0xEC, 0xFC, 0xDD, 0xED, 0xFD, 0xCE, 0xDE, 0xEE, 0xFE, 0xAF, 0xBF, - 0xCF, 0xDF, 0xEF, 0xFF -}; - -static const uint8_t huff_b26_cb[12] = { - 3, 12, 2, 2, 4, 5, 11, 26, 67, 78, 51, 10 -}; - -static const uint8_t huff_b26_xlat[256] = { + 0xCF, 0xDF, 0xEF, 0xFF, + /* Table set B, code table 2, wordlen 6 - 256 entries */ 0x00, 0x01, 0x10, 0x11, 0x20, 0x21, 0x02, 0x12, 0x30, 0x31, 0x22, 0x03, 0x13, 0x40, 0x41, 0x51, 0x32, 0x42, 0x23, 0x33, 0x04, 0x14, 0x24, 0x15, 0x50, 0x61, 0x71, 0xD1, 0xE1, 0x52, 0x62, 0xD2, 0x43, 0x53, 0xD3, 0x34, @@ -1322,28 +1107,16 @@ static const uint8_t huff_b26_xlat[256] = { 0x5A, 0x6A, 0x7A, 0x9A, 0xCA, 0xFA, 0x4B, 0x5B, 0x6B, 0x7B, 0xCB, 0xFB, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xEC, 0xFC, 0xDD, 0xED, 0xFD, 0xDE, 0xEE, 0xFE, 0xBF, 0xCF, 0xDF, 0xEF, 0xB8, 0xB9, 0x8A, 0xAA, 0xBA, 0x8B, - 0x9B, 0xAB, 0xBB, 0xFF -}; - -static const uint8_t huff_b32_cb[12] = { - 2, 11, 1, 0, 4, 6, 7, 10, 22, 11, 16, 4 -}; - -static const uint8_t huff_b32_xlat[81] = { + 0x9B, 0xAB, 0xBB, 0xFF, + /* Table set B, code table 3, wordlen 2 - 81 entries */ 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x41, 0x11, 0x05, 0x80, 0x54, 0x51, 0x45, 0x15, 0x55, 0x02, 0x90, 0x20, 0x60, 0x84, 0x24, 0x08, 0x18, 0x09, 0x12, 0x06, 0xA0, 0x94, 0x64, 0x48, 0x58, 0x81, 0x91, 0x21, 0x61, 0x85, 0x95, 0x25, 0x65, 0x49, 0x19, 0x59, 0x42, 0x52, 0x46, 0x16, 0x56, 0x0A, 0xA4, 0x28, 0x68, 0xA1, 0xA5, 0x29, 0x69, 0x26, 0x4A, 0x1A, 0x5A, 0x88, 0x98, 0xA8, 0x89, 0x99, 0xA9, 0x82, 0x92, 0x22, 0x62, 0x86, - 0x96, 0x66, 0x9A, 0x2A, 0x6A, 0xA2, 0xA6, 0x8A, 0xAA -}; - -static const uint8_t huff_b33_cb[13] = { - 2, 12, 1, 0, 0, 4, 11, 8, 28, 92, 97, 13, 2 -}; - -static const uint8_t huff_b33_xlat[256] = { + 0x96, 0x66, 0x9A, 0x2A, 0x6A, 0xA2, 0xA6, 0x8A, 0xAA, + /* Table set B, code table 3, wordlen 3 - 256 entries */ 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55, 0x20, 0x95, 0x65, 0x49, 0x59, 0x52, 0x46, 0x16, 0x80, 0x90, 0x60, 0x84, 0x94, 0x24, 0x64, 0xA4, 0x08, 0x48, 0x18, 0x58, @@ -1365,14 +1138,8 @@ static const uint8_t huff_b33_xlat[256] = { 0x93, 0xD3, 0x23, 0x63, 0xA3, 0xE3, 0x73, 0xB3, 0xF3, 0x07, 0x47, 0x87, 0xC7, 0x27, 0x37, 0x4B, 0x8B, 0xCB, 0x1B, 0x2B, 0x3B, 0x4F, 0x8F, 0xCF, 0x1F, 0x70, 0xB0, 0xF0, 0x8C, 0xCC, 0x2C, 0x3C, 0xC2, 0x32, 0xC3, 0x0F, - 0x2F, 0x3F, 0x33, 0x0B -}; - -static const uint8_t huff_b35_cb[14] = { - 1, 12, 1, 0, 0, 0, 4, 6, 6, 14, 42, 63, 59, 30 -}; - -static const uint8_t huff_b35_xlat[225] = { + 0x2F, 0x3F, 0x33, 0x0B, + /* Table set B, code table 3, wordlen 5 - 225 entries */ 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x02, 0x0E, 0x1F, 0xFF, 0x20, 0xE0, 0x21, 0xF2, 0xFE, 0xEF, 0x30, 0xD0, 0xE1, 0x12, 0x22, 0xE2, 0x03, 0x0D, 0x1D, 0x1E, 0x2E, 0xEE, 0x2F, 0xDF, 0x40, 0x60, 0x70, 0x90, 0xA0, @@ -1391,107 +1158,62 @@ static const uint8_t huff_b35_xlat[225] = { 0xDB, 0xEB, 0x3C, 0x6C, 0x9C, 0xAC, 0xCC, 0xDC, 0x5D, 0x9D, 0xAD, 0xBD, 0xCD, 0xBE, 0xBF, 0x53, 0x54, 0xB4, 0xC4, 0x45, 0x55, 0xB5, 0xC5, 0xD5, 0x56, 0x67, 0x77, 0x97, 0x49, 0x69, 0x79, 0x99, 0x5A, 0x7A, 0x9A, 0xAA, - 0xBA, 0x4B, 0x5B, 0x7B, 0xBB, 0xCB, 0x4C, 0x5C, 0xBC -}; - -static const uint8_t huff_b37_cb[13] = { - 1, 11, 1, 0, 2, 0, 2, 2, 6, 17, 14, 13, 6 -}; - -static const uint8_t huff_b37_xlat[63] = { - 0, 1, 63, 2, 62, 3, 61, 4, 5, 6, 58, 59, 60, 7, 8, 9, - 10, 25, 26, 27, 28, 29, 34, 35, 37, 38, 39, 55, 56, 57, 11, 13, - 14, 15, 30, 31, 33, 36, 49, 50, 51, 52, 53, 54, 12, 16, 17, 18, - 19, 21, 41, 43, 44, 45, 46, 47, 48, 20, 22, 23, 24, 40, 42 -}; - -static const uint8_t huff_b41_cb[14] = { - 1, 12, 1, 0, 0, 1, 7, 0, 20, 4, 10, 24, 2, 12 -}; - -static const uint8_t huff_b41_xlat[81] = { + 0xBA, 0x4B, 0x5B, 0x7B, 0xBB, 0xCB, 0x4C, 0x5C, 0xBC, + /* Table set B, code table 3, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x3F, 0x02, 0x3E, 0x03, 0x3D, 0x04, 0x05, 0x06, 0x3A, 0x3B, + 0x3C, 0x07, 0x08, 0x09, 0x0A, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x22, 0x23, + 0x25, 0x26, 0x27, 0x37, 0x38, 0x39, 0x0B, 0x0D, 0x0E, 0x0F, 0x1E, 0x1F, + 0x21, 0x24, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x0C, 0x10, 0x11, 0x12, + 0x13, 0x15, 0x29, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x14, 0x16, 0x17, + 0x18, 0x28, 0x2A, + /* Table set B, code table 4, wordlen 1 - 81 entries */ 0x00, 0x01, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x03, 0x50, 0xD0, 0x70, 0xF0, 0xC4, 0x14, 0x34, 0x4C, 0x1C, 0x3C, 0xC1, 0x11, 0x31, 0x05, 0x0D, 0xC3, 0x13, 0x33, 0x07, 0x0F, 0x44, 0xCC, 0x41, 0x43, 0x54, 0x74, 0xDC, 0xFC, 0x71, 0x15, 0x4D, 0x1D, 0x37, 0x3F, 0xD4, 0xF4, 0x5C, 0x7C, 0x51, 0xD1, 0xF1, 0x45, 0xC5, 0x35, 0xCD, 0xDD, 0x3D, 0x53, 0xD3, 0x73, 0xF3, 0x47, 0xC7, 0x17, 0x77, 0x4F, 0xCF, 0x1F, 0x55, 0xFF, 0xD5, 0x75, 0xF5, - 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F -}; - -static const uint8_t huff_b42_cb[11] = { 1, 9, 1, 0, 1, 3, 2, 3, 7, 4, 4 }; - -static const uint8_t huff_b42_xlat[25] = { + 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F, + /* Table set B, code table 4, wordlen 2 - 25 entries */ 0x00, 0x07, 0x08, 0x38, 0x01, 0x39, 0x0F, 0x10, 0x09, 0x3F, 0x30, 0x31, 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x11, 0x0A, 0x3E, 0x37, 0x12, 0x32, 0x16, - 0x36 -}; - -static const uint8_t huff_b43_cb[10] = { 2, 9, 1, 1, 3, 4, 9, 15, 12, 4 }; - -static const uint8_t huff_b43_xlat[49] = { + 0x36, + /* Table set B, code table 4, wordlen 3 - 49 entries */ 0x00, 0x07, 0x08, 0x38, 0x01, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x30, 0x31, 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x37, 0x18, 0x28, 0x11, 0x19, 0x29, 0x0A, 0x03, 0x0B, 0x3B, 0x05, 0x0D, 0x3D, 0x3E, 0x1F, 0x2F, 0x12, 0x1A, 0x2A, 0x32, 0x13, 0x33, 0x15, 0x35, 0x16, 0x1E, 0x2E, 0x36, 0x1B, 0x2B, 0x1D, - 0x2D -}; - -static const uint8_t huff_b47_cb[10] = { 2, 9, 1, 1, 3, 4, 6, 14, 22, 12 }; - -static const uint8_t huff_b47_xlat[63] = { - 0, 1, 2, 62, 63, 3, 4, 60, 61, 5, 6, 7, 57, 58, 59, 8, - 9, 10, 11, 12, 26, 27, 37, 38, 52, 53, 54, 55, 56, 13, 14, 15, - 16, 17, 18, 25, 28, 29, 30, 31, 33, 34, 35, 36, 39, 46, 47, 48, - 49, 50, 51, 19, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44, 45 -}; - -static const uint8_t huff_b52_cb[11] = { 1, 9, 1, 0, 1, 3, 2, 3, 7, 4, 4 }; - -static const uint8_t huff_b52_xlat[25] = { + 0x2D, + /* Table set B, code table 4, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x02, 0x3E, 0x3F, 0x03, 0x04, 0x3C, 0x3D, 0x05, 0x06, 0x07, + 0x39, 0x3A, 0x3B, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x1A, 0x1B, 0x25, 0x26, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x19, + 0x1C, 0x1D, 0x1E, 0x1F, 0x21, 0x22, 0x23, 0x24, 0x27, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x28, 0x29, 0x2A, + 0x2B, 0x2C, 0x2D, + /* Table set B, code table 5, wordlen 2 - 25 entries */ 0x00, 0x01, 0x08, 0x38, 0x07, 0x39, 0x0F, 0x30, 0x09, 0x3F, 0x10, 0x31, 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x11, 0x0A, 0x3E, 0x37, 0x12, 0x32, 0x16, - 0x36 -}; - -static const uint8_t huff_b53_cb[7] = { 1, 5, 1, 1, 1, 0, 4 }; // same as b63!!! - -static const uint8_t huff_b53_xlat[7] = { 0, 7, 1, 2, 3, 5, 6 }; - -static const uint8_t huff_b56_cb[11] = { 1, 9, 1, 0, 2, 0, 2, 4, 11, 9, 2 }; - -static const uint8_t huff_b56_xlat[31] = { - 0, 1, 31, 2, 30, 3, 4, 13, 29, 5, 6, 7, 14, 15, 17, 18, - 19, 26, 27, 28, 8, 9, 12, 20, 21, 22, 23, 24, 25, 10, 11 -}; - -static const uint8_t huff_b62_cb[14] = { - 1, 12, 1, 0, 0, 2, 3, 5, 12, 14, 18, 15, 9, 2 -}; - -static const uint8_t huff_b62_xlat[81] = { + 0x36, + /* Table set B, code table 5, wordlen 3 - 7 entries */ + 0x00, 0x07, 0x01, 0x02, 0x03, 0x05, 0x06, + /* Table set B, code table 5, wordlen 6 - 31 entries */ + 0x00, 0x01, 0x1F, 0x02, 0x1E, 0x03, 0x04, 0x0D, 0x1D, 0x05, 0x06, 0x07, + 0x0E, 0x0F, 0x11, 0x12, 0x13, 0x1A, 0x1B, 0x1C, 0x08, 0x09, 0x0C, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x0A, 0x0B, + /* Table set B, code table 6, wordlen 2 - 81 entries */ 0x00, 0x40, 0x01, 0x10, 0x04, 0x02, 0x80, 0x50, 0x90, 0x05, 0x06, 0x20, 0x60, 0x44, 0x14, 0x54, 0x24, 0x08, 0x18, 0x41, 0x11, 0x15, 0x09, 0xA0, 0x84, 0x94, 0x64, 0xA4, 0x28, 0x51, 0x45, 0x55, 0x19, 0x12, 0x16, 0x0A, 0x1A, 0x48, 0x58, 0x68, 0x81, 0x91, 0x21, 0x61, 0x85, 0x95, 0x25, 0x65, 0x49, 0x59, 0x29, 0x69, 0x42, 0x46, 0x56, 0x88, 0x98, 0xA8, 0xA1, 0xA5, 0x99, 0xA9, 0x52, 0x22, 0x26, 0x66, 0x4A, 0x5A, 0x2A, 0x6A, 0x89, 0x82, - 0x92, 0x62, 0x86, 0x96, 0xA6, 0x8A, 0xAA, 0xA2, 0x9A -}; - -static const uint8_t huff_b63_cb[7] = { 1, 5, 1, 1, 1, 0, 4 }; - -static const uint8_t huff_b63_xlat[7] = { 0, 1, 7, 2, 3, 5, 6 }; - -static const uint8_t huff_b64_cb[7] = { 1, 5, 1, 1, 1, 1, 2 }; - -static const uint8_t huff_b64_xlat[6] = { 1, 0, 2, 5, 3, 4 }; - -static const uint8_t huff_b65_cb[14] = { - 1, 12, 1, 0, 0, 2, 2, 2, 6, 12, 34, 92, 54, 20 -}; - -static const uint8_t huff_b65_xlat[225] = { + 0x92, 0x62, 0x86, 0x96, 0xA6, 0x8A, 0xAA, 0xA2, 0x9A, + /* Table set B, code table 6, wordlen 3 - 7 entries */ + 0x00, 0x01, 0x07, 0x02, 0x03, 0x05, 0x06, + /* Table set B, code table 6, wordlen 4 - 6 entries */ + 0x01, 0x00, 0x02, 0x05, 0x03, 0x04, + /* Table set B, code table 6, wordlen 5 - 225 entries */ 0x00, 0xF0, 0x01, 0x10, 0x0F, 0x11, 0xF1, 0x20, 0xE0, 0x02, 0x0E, 0x1F, 0xFF, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x07, 0x0A, 0x0D, 0x1E, 0xFE, 0x2F, 0xEF, 0x30, 0x70, 0x90, 0xA0, 0xC0, 0x71, 0x91, 0xC1, 0xD1, 0x32, 0x92, @@ -1510,14 +1232,8 @@ static const uint8_t huff_b65_xlat[225] = { 0xAA, 0xBA, 0x2B, 0x4B, 0x7B, 0x9B, 0xAB, 0xDB, 0x3C, 0x4C, 0x7C, 0x9C, 0xAC, 0xBC, 0xCC, 0x3D, 0x5D, 0x7D, 0xBD, 0xCD, 0x5E, 0xBE, 0xDE, 0xBF, 0xCF, 0x53, 0x64, 0xB4, 0xC4, 0x35, 0x55, 0xC5, 0xD5, 0x97, 0xB7, 0xC7, - 0x79, 0x99, 0x5B, 0xBB, 0xCB, 0x5C, 0xDC, 0x7F, 0xAF -}; - -static const uint8_t huff_b66_cb[14] = { - 1, 12, 1, 0, 0, 3, 0, 3, 3, 10, 40, 85, 61, 50 -}; - -static const uint8_t huff_b66_xlat[256] = { + 0x79, 0x99, 0x5B, 0xBB, 0xCB, 0x5C, 0xDC, 0x7F, 0xAF, + /* Table set B, code table 6, wordlen 6 - 256 entries */ 0x00, 0x10, 0x01, 0x11, 0x21, 0x02, 0x12, 0x20, 0x22, 0x13, 0x30, 0x31, 0x41, 0xD1, 0xE1, 0x32, 0x52, 0x03, 0x23, 0x2D, 0x40, 0x50, 0x60, 0x80, 0xD0, 0xE0, 0x51, 0x61, 0xF1, 0x42, 0x62, 0xD2, 0xE2, 0xF2, 0x33, 0x43, @@ -1539,37 +1255,23 @@ static const uint8_t huff_b66_xlat[256] = { 0x47, 0x87, 0xB7, 0xC7, 0x58, 0x68, 0x78, 0xA8, 0xB8, 0xC8, 0x39, 0x69, 0x89, 0xA9, 0xB9, 0xC9, 0xD9, 0x2A, 0x5A, 0x6A, 0x7A, 0x9A, 0xAA, 0x3B, 0x4B, 0x5B, 0x6B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0x6C, 0x9C, 0xDC, 0xFC, - 0xCD, 0xED, 0xAE, 0xDE -}; - -static const uint8_t huff_b67_cb[10] = { 2, 9, 1, 2, 1, 4, 7, 10, 26, 12 }; - -static const uint8_t huff_b67_xlat[63] = { - 0, 1, 63, 62, 2, 3, 60, 61, 4, 5, 6, 7, 57, 58, 59, 8, - 9, 10, 11, 12, 52, 53, 54, 55, 56, 13, 14, 15, 16, 17, 18, 25, - 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 46, 47, 48, - 49, 50, 51, 19, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44, 45 -}; - -static const uint8_t huff_b71_cb[14] = { - 1, 12, 1, 0, 0, 1, 7, 0, 19, 5, 13, 23, 0, 12 -}; - -static const uint8_t huff_b71_xlat[81] = { + 0xCD, 0xED, 0xAE, 0xDE, + /* Table set B, code table 6, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x3F, 0x3E, 0x02, 0x03, 0x3C, 0x3D, 0x04, 0x05, 0x06, 0x07, + 0x39, 0x3A, 0x3B, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, + 0x1E, 0x1F, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x28, 0x29, 0x2A, + 0x2B, 0x2C, 0x2D, + /* Table set B, code table 7, wordlen 1 - 81 entries */ 0x00, 0x03, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x50, 0xD0, 0x70, 0xF0, 0xC4, 0x14, 0x34, 0x4C, 0x1C, 0x3C, 0xC1, 0x11, 0x31, 0x05, 0x0D, 0x13, 0x33, 0x07, 0x0F, 0x44, 0xCC, 0x41, 0x43, 0xC3, 0x54, 0x74, 0xDC, 0xFC, 0xF1, 0xC5, 0x15, 0x1D, 0x53, 0xC7, 0x37, 0x4F, 0x3F, 0xD4, 0xF4, 0x5C, 0x7C, 0x51, 0xD1, 0x71, 0x45, 0x55, 0x35, 0x4D, 0xCD, 0xDD, 0x3D, 0xD3, 0x73, 0xF3, 0x47, 0x17, 0x77, 0xCF, 0x1F, 0xFF, 0xD5, 0x75, 0xF5, - 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F -}; - -static const uint8_t huff_b73_cb[13] = { - 1, 11, 1, 0, 0, 0, 1, 4, 9, 4, 103, 110, 24 -}; - -static const uint8_t huff_b73_xlat[256] = { + 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F, + /* Table set B, code table 7, wordlen 3 - 256 entries */ 0x00, 0x40, 0x10, 0x04, 0x01, 0x05, 0x50, 0x14, 0x54, 0x41, 0x11, 0x51, 0x45, 0x15, 0x55, 0x44, 0x95, 0x6A, 0x03, 0x80, 0xC0, 0x90, 0xD0, 0x94, 0xD4, 0x24, 0x64, 0x58, 0x91, 0xA1, 0x85, 0xD5, 0x25, 0x65, 0xA5, 0xE5, @@ -1591,20 +1293,10 @@ static const uint8_t huff_b73_xlat[256] = { 0x27, 0x37, 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x2B, 0x3B, 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x2F, 0x3F, 0xA0, 0xE0, 0x30, 0x34, 0x48, 0xC8, 0x28, 0x38, 0x0C, 0x4C, 0x8C, 0xCC, 0x2C, 0xC1, 0x31, 0x82, 0xC2, 0x12, 0x32, 0x43, - 0x83, 0xC3, 0x23, 0x33 -}; - -static const uint8_t huff_b74_cb[8] = { 1, 6, 1, 0, 2, 2, 2, 4 }; - -static const uint8_t huff_b74_xlat[11] = { - 0, 1, 15, 2, 14, 5, 13, 3, 4, 11, 12 -}; - -static const uint8_t huff_b75_cb[13] = { - 2, 12, 1, 4, 0, 0, 0, 8, 11, 24, 53, 64, 60 -}; - -static const uint8_t huff_b75_xlat[225] = { + 0x83, 0xC3, 0x23, 0x33, + /* Table set B, code table 7, wordlen 4 - 11 entries */ + 0x00, 0x01, 0x0F, 0x02, 0x0E, 0x05, 0x0D, 0x03, 0x04, 0x0B, 0x0C, + /* Table set B, code table 7, wordlen 5 - 225 entries */ 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x20, 0xE0, 0x11, 0xF1, 0x02, 0x0E, 0x1F, 0xFF, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x03, 0x0D, 0x1E, 0xFE, 0x2F, 0xEF, 0x30, 0x40, 0x60, 0x70, 0x90, 0xA0, 0xC0, 0x31, 0xD1, 0x22, 0xE2, 0x13, @@ -1623,18 +1315,92 @@ static const uint8_t huff_b75_xlat[225] = { 0xD5, 0x46, 0x56, 0x66, 0x76, 0x96, 0xA6, 0xB6, 0xC6, 0x57, 0x67, 0x77, 0x97, 0xA7, 0xB7, 0x49, 0x69, 0x79, 0x99, 0xA9, 0x4A, 0x5A, 0x7A, 0x9A, 0xAA, 0xBA, 0xCA, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0xBB, 0xCB, 0xDB, 0x3C, - 0x4C, 0x5C, 0xBC, 0xCC, 0xDC, 0x5D, 0xCD, 0xBE, 0xBF -}; - -static const uint8_t huff_b77_cb[12] = { - 2, 11, 1, 0, 4, 6, 10, 12, 7, 15, 4, 4 -}; - -static const uint8_t huff_b77_xlat[63] = { - 0, 1, 2, 62, 63, 3, 4, 5, 59, 60, 61, 6, 7, 8, 9, 10, - 54, 55, 56, 57, 58, 11, 12, 13, 14, 15, 16, 47, 49, 50, 51, 52, - 53, 17, 18, 19, 20, 45, 46, 48, 21, 22, 23, 24, 25, 26, 27, 37, - 38, 39, 40, 41, 42, 43, 44, 28, 29, 30, 35, 31, 33, 34, 36 + 0x4C, 0x5C, 0xBC, 0xCC, 0xDC, 0x5D, 0xCD, 0xBE, 0xBF, + /* Table set B, code table 7, wordlen 7 - 63 entries */ + 0x00, 0x01, 0x02, 0x3E, 0x3F, 0x03, 0x04, 0x05, 0x3B, 0x3C, 0x3D, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x2F, 0x31, 0x32, 0x33, 0x34, 0x35, 0x11, 0x12, 0x13, + 0x14, 0x2D, 0x2E, 0x30, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x1C, 0x1D, 0x1E, 0x23, 0x1F, + 0x21, 0x22, 0x24, + /* Table set B, code table 7, wordlen 7 - 8 entries */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + /* Table set B, code table 7, wordlen 7 - 8 entries */ + 0x00, 0x01, 0x07, 0x02, 0x06, 0x03, 0x04, 0x05, + /* Table set B, code table 7, wordlen 7 - 16 entries */ + 0x07, 0x05, 0x08, 0x06, 0x09, 0x04, 0x0A, 0x0B, 0x00, 0x01, 0x02, 0x03, + 0x0C, 0x0D, 0x0E, 0x0F, + /* Table set B, code table 7, wordlen 7 - 15 entries */ + 0x0F, 0x0E, 0x01, 0x0D, 0x02, 0x03, 0x0C, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, + /* Table set B, code table 7, wordlen 7 - 16 entries */ + 0x00, 0x01, 0x0E, 0x0F, 0x02, 0x0D, 0x03, 0x0C, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, + /* Table set B, code table 7, wordlen 7 - 16 entries */ + 0x00, 0x01, 0x0F, 0x0E, 0x02, 0x0D, 0x03, 0x0C, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, + /* Table set B, code table 7, wordlen 7 - 32 entries */ + 0x00, 0x01, 0x1F, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x1A, 0x1B, 0x1C, + 0x1D, 0x1E, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + /* Table set B, code table 7, wordlen 7 - 31 entries */ + 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, + /* Table set B, code table 7, wordlen 7 - 32 entries */ + 0x00, 0x1C, 0x1D, 0x01, 0x02, 0x03, 0x04, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1E, 0x1F, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + /* Table set B, code table 7, wordlen 7 - 31 entries */ + 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 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, + /* Table set B, code table 7, wordlen 7 - 32 entries */ + 0x00, 0x01, 0x02, 0x1F, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x1D, 0x1E, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, + /* Table set B, code table 7, wordlen 7 - 16 entries */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + /* Table set B, code table 7, wordlen 7 - 8 entries */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + /* Table set B, code table 7, wordlen 7 - 8 entries */ + 0x00, 0x01, 0x07, 0x02, 0x03, 0x04, 0x05, 0x06, + /* Table set B, code table 7, wordlen 7 - 32 entries */ + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x05, 0x06, + 0x07, 0x12, 0x13, 0x14, 0x15, 0x16, 0x04, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x00, 0x01, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F, + /* Table set B, code table 7, wordlen 7 - 32 entries */ + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x0E, + 0x0F, 0x10, 0x11, 0x1D, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x1E, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x1F, 0x00, 0x01, 0x02, 0x03, + /* Table set B, code table 7, wordlen 7 - 32 entries */ + 0x00, 0x01, 0x02, 0x1F, 0x03, 0x1D, 0x1E, 0x04, 0x05, 0x06, 0x1B, 0x1C, + 0x07, 0x18, 0x19, 0x1A, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + /* Table set B, code table 7, wordlen 7 - 256 entries */ + 0x00, 0x01, 0xFF, 0x02, 0xFE, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xFB, + 0xFC, 0xFD, 0x09, 0x0A, 0x0B, 0x0C, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 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, 0xF3, 0xF4, 0xF5, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, + 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, + 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0xC2, + 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, + 0xCF, 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, + 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, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, + 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, + 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, + 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, + 0xBE, 0xBF, 0xC0, 0xC1, }; /** Tables for spectrum coding. */ @@ -1643,272 +1409,251 @@ typedef struct Atrac3pSpecCodeTab { uint8_t num_coeffs; ///< 1 - map index to a single value, > 1 - map index to a vector of values uint8_t bits; ///< number of bits a single coefficient occupy uint8_t is_signed; ///< 1 - values in that table are signed ones, otherwise - absolute ones - - int redirect; ///< if >= 0: tells which huffman table must be reused - const uint8_t *cb; ///< pointer to the codebook descriptor - const uint8_t *xlat; ///< pointer to the translation table or NULL if none } Atrac3pSpecCodeTab; static const Atrac3pSpecCodeTab atrac3p_spectra_tabs[112] = { /* table set = A */ /* code table = 0 */ - { 1, 4, 2, 1, -1, huff_a01_cb, huff_a01_xlat }, // wordlen = 1 - { 1, 4, 2, 0, -1, huff_a02_cb, huff_a02_xlat }, // wordlen = 2 - { 1, 2, 3, 1, -1, huff_a03_cb, huff_a03_xlat }, // wordlen = 3 - { 1, 1, 3, 0, -1, huff_a04_cb, huff_a04_xlat }, // wordlen = 4 - { 1, 2, 4, 1, -1, huff_a05_cb, huff_a05_xlat }, // wordlen = 5 - { 1, 1, 4, 0, -1, huff_a06_cb, huff_a06_xlat }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_a07_cb, huff_a07_xlat }, // wordlen = 7 + { 1, 4, 2, 1 }, // wordlen = 1 + { 1, 4, 2, 0 }, // wordlen = 2 + { 1, 2, 3, 1 }, // wordlen = 3 + { 1, 1, 3, 0 }, // wordlen = 4 + { 1, 2, 4, 1 }, // wordlen = 5 + { 1, 1, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 1 */ - { 4, 4, 2, 1, -1, huff_a11_cb, huff_a11_xlat }, // wordlen = 1 - { 1, 4, 2, 0, -1, huff_a12_cb, huff_a12_xlat }, // wordlen = 2 - { 1, 2, 3, 1, -1, huff_a13_cb, huff_a13_xlat }, // wordlen = 3 - { 1, 2, 4, 1, -1, huff_a14_cb, huff_a14_xlat }, // wordlen = 4 - { 1, 2, 4, 1, -1, huff_a15_cb, huff_a15_xlat }, // wordlen = 5 - { 1, 2, 4, 0, -1, huff_a16_cb, huff_a16_xlat }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_a17_cb, huff_a17_xlat }, // wordlen = 7 + { 4, 4, 2, 1 }, // wordlen = 1 + { 1, 4, 2, 0 }, // wordlen = 2 + { 1, 2, 3, 1 }, // wordlen = 3 + { 1, 2, 4, 1 }, // wordlen = 4 + { 1, 2, 4, 1 }, // wordlen = 5 + { 1, 2, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 2 */ - { 1, 4, 2, 1, -1, huff_a21_cb, huff_a21_xlat }, // wordlen = 1 - { 1, 2, 3, 1, -1, huff_a22_cb, huff_a22_xlat }, // wordlen = 2 - { 1, 2, 3, 1, -1, huff_a23_cb, huff_a23_xlat }, // wordlen = 3 - { 1, 1, 3, 0, -1, huff_a24_cb, NULL }, // wordlen = 4 - { 1, 1, 3, 0, -1, huff_a25_cb, huff_a25_xlat }, // wordlen = 5 - { 1, 2, 4, 0, -1, huff_a26_cb, huff_a26_xlat }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_a27_cb, huff_a27_xlat }, // wordlen = 7 + { 1, 4, 2, 1 }, // wordlen = 1 + { 1, 2, 3, 1 }, // wordlen = 2 + { 1, 2, 3, 1 }, // wordlen = 3 + { 1, 1, 3, 0 }, // wordlen = 4 + { 1, 1, 3, 0 }, // wordlen = 5 + { 1, 2, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 3 */ - { 1, 2, 2, 1, -1, huff_a31_cb, huff_a31_xlat }, // wordlen = 1 - { 1, 4, 2, 0, -1, huff_a32_cb, huff_a32_xlat }, // wordlen = 2 - { 1, 4, 2, 0, -1, huff_a33_cb, huff_a33_xlat }, // wordlen = 3 - { 1, 1, 3, 0, -1, huff_a34_cb, huff_a34_xlat }, // wordlen = 4 - { 1, 2, 4, 1, -1, huff_a35_cb, huff_a35_xlat }, // wordlen = 5 - { 1, 2, 4, 0, -1, huff_a36_cb, huff_a36_xlat }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_a37_cb, huff_a37_xlat }, // wordlen = 7 + { 1, 2, 2, 1 }, // wordlen = 1 + { 1, 4, 2, 0 }, // wordlen = 2 + { 1, 4, 2, 0 }, // wordlen = 3 + { 1, 1, 3, 0 }, // wordlen = 4 + { 1, 2, 4, 1 }, // wordlen = 5 + { 1, 2, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 4 */ - { 1, 4, 2, 1, -1, huff_a41_cb, huff_a41_xlat }, // wordlen = 1 - { 1, 4, 2, 0, -1, huff_a42_cb, huff_a42_xlat }, // wordlen = 2 - { 1, 1, 3, 1, -1, huff_a43_cb, huff_a43_xlat }, // wordlen = 3 - { 1, 2, 4, 1, -1, huff_a44_cb, huff_a44_xlat }, // wordlen = 4 - { 1, 1, 3, 0, -1, huff_a45_cb, huff_a45_xlat }, // wordlen = 5 - { 1, 2, 4, 0, -1, huff_a46_cb, huff_a46_xlat }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_a47_cb, huff_a47_xlat }, // wordlen = 7 + { 1, 4, 2, 1 }, // wordlen = 1 + { 1, 4, 2, 0 }, // wordlen = 2 + { 1, 1, 3, 1 }, // wordlen = 3 + { 1, 2, 4, 1 }, // wordlen = 4 + { 1, 1, 3, 0 }, // wordlen = 5 + { 1, 2, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 5 */ - { 1, 4, 2, 1, -1, huff_a51_cb, huff_a51_xlat }, // wordlen = 1 - { 1, 2, 3, 1, -1, huff_a52_cb, huff_a52_xlat }, // wordlen = 2 - { 1, 1, 3, 1, -1, huff_a43_cb, huff_a53_xlat }, // wordlen = 3 - { 1, 2, 4, 1, -1, huff_a54_cb, huff_a54_xlat }, // wordlen = 4 - { 1, 1, 3, 0, -1, huff_a55_cb, huff_a55_xlat }, // wordlen = 5 - { 1, 1, 5, 1, -1, huff_a56_cb, huff_a56_xlat }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_a57_cb, huff_a57_xlat }, // wordlen = 7 + { 1, 4, 2, 1 }, // wordlen = 1 + { 1, 2, 3, 1 }, // wordlen = 2 + { 1, 1, 3, 1 }, // wordlen = 3 + { 1, 2, 4, 1 }, // wordlen = 4 + { 1, 1, 3, 0 }, // wordlen = 5 + { 1, 1, 5, 1 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 6 */ - { 2, 4, 2, 1, -1, huff_a61_cb, huff_a61_xlat }, // wordlen = 1 - { 1, 2, 3, 1, -1, huff_a62_cb, huff_a62_xlat }, // wordlen = 2 - { 1, 4, 2, 0, -1, huff_a63_cb, huff_a63_xlat }, // wordlen = 3 - { 1, 2, 4, 1, -1, huff_a64_cb, huff_a64_xlat }, // wordlen = 4 - { 1, 1, 4, 1, -1, huff_a65_cb, huff_a65_xlat }, // wordlen = 5 - { 1, 1, 5, 1, -1, huff_a66_cb, huff_a66_xlat }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_a67_cb, huff_a67_xlat }, // wordlen = 7 + { 2, 4, 2, 1 }, // wordlen = 1 + { 1, 2, 3, 1 }, // wordlen = 2 + { 1, 4, 2, 0 }, // wordlen = 3 + { 1, 2, 4, 1 }, // wordlen = 4 + { 1, 1, 4, 1 }, // wordlen = 5 + { 1, 1, 5, 1 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 7 */ - { 1, 2, 1, 0, -1, huff_a71_cb, NULL }, // wordlen = 1 - { 2, 4, 2, 0, -1, huff_a72_cb, huff_a72_xlat }, // wordlen = 2 - { 1, 2, 3, 1, -1, huff_a73_cb, huff_a73_xlat }, // wordlen = 3 - { 1, 2, 4, 1, -1, huff_a74_cb, huff_a74_xlat }, // wordlen = 4 - { 1, 1, 4, 1, -1, huff_a75_cb, huff_a75_xlat }, // wordlen = 5 - { 2, 2, 4, 0, -1, huff_a76_cb, huff_a76_xlat }, // wordlen = 6 - { 4, 1, 6, 1, 6, NULL, NULL }, // wordlen = 7 + { 1, 2, 1, 0 }, // wordlen = 1 + { 2, 4, 2, 0 }, // wordlen = 2 + { 1, 2, 3, 1 }, // wordlen = 3 + { 1, 2, 4, 1 }, // wordlen = 4 + { 1, 1, 4, 1 }, // wordlen = 5 + { 2, 2, 4, 0 }, // wordlen = 6 + { 4, 1, 6, 1 }, // wordlen = 7 /* table set = B */ /* code table = 0 */ - { 4, 4, 2, 1, -1, huff_b01_cb, huff_b01_xlat }, // wordlen = 1 - { 1, 4, 2, 0, -1, huff_b02_cb, huff_b02_xlat }, // wordlen = 2 - { 4, 2, 3, 1, -1, huff_b03_cb, huff_b03_xlat }, // wordlen = 3 - { 1, 2, 4, 1, -1, huff_b04_cb, huff_b04_xlat }, // wordlen = 4 - { 1, 2, 4, 1, -1, huff_b05_cb, huff_b05_xlat }, // wordlen = 5 - { 1, 1, 4, 0, 5, NULL, NULL }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_b07_cb, huff_b07_xlat }, // wordlen = 7 + { 4, 4, 2, 1 }, // wordlen = 1 + { 1, 4, 2, 0 }, // wordlen = 2 + { 4, 2, 3, 1 }, // wordlen = 3 + { 1, 2, 4, 1 }, // wordlen = 4 + { 1, 2, 4, 1 }, // wordlen = 5 + { 1, 1, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 1 */ - { 1, 4, 2, 1, 14, NULL, NULL }, // wordlen = 1 - { 1, 4, 2, 0, -1, huff_b12_cb, huff_b12_xlat }, // wordlen = 2 - { 1, 2, 3, 1, 9, NULL, NULL }, // wordlen = 3 - { 1, 2, 4, 1, -1, huff_b14_cb, huff_b14_xlat }, // wordlen = 4 - { 1, 2, 4, 1, 11, NULL, NULL }, // wordlen = 5 - { 1, 2, 4, 0, -1, huff_b16_cb, huff_b16_xlat }, // wordlen = 6 - { 1, 1, 6, 1, 6, NULL, NULL }, // wordlen = 7 + { 1, 4, 2, 1 }, // wordlen = 1 + { 1, 4, 2, 0 }, // wordlen = 2 + { 1, 2, 3, 1 }, // wordlen = 3 + { 1, 2, 4, 1 }, // wordlen = 4 + { 1, 2, 4, 1 }, // wordlen = 5 + { 1, 2, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 2 */ - { 4, 4, 2, 1, 28, NULL, NULL }, // wordlen = 1 - { 4, 4, 2, 0, 22, NULL, NULL }, // wordlen = 2 - { 1, 2, 3, 1, 2, NULL, NULL }, // wordlen = 3 - { 1, 2, 4, 1, 31, NULL, NULL }, // wordlen = 4 - { 2, 2, 4, 1, 60, NULL, NULL }, // wordlen = 5 - { 2, 2, 4, 0, -1, huff_b26_cb, huff_b26_xlat }, // wordlen = 6 - { 4, 1, 6, 1, 6, NULL, NULL }, // wordlen = 7 + { 4, 4, 2, 1 }, // wordlen = 1 + { 4, 4, 2, 0 }, // wordlen = 2 + { 1, 2, 3, 1 }, // wordlen = 3 + { 1, 2, 4, 1 }, // wordlen = 4 + { 2, 2, 4, 1 }, // wordlen = 5 + { 2, 2, 4, 0 }, // wordlen = 6 + { 4, 1, 6, 1 }, // wordlen = 7 /* code table = 3 */ - { 1, 4, 2, 1, 35, NULL, NULL }, // wordlen = 1 - { 1, 4, 2, 0, -1, huff_b32_cb, huff_b32_xlat }, // wordlen = 2 - { 1, 4, 2, 0, -1, huff_b33_cb, huff_b33_xlat }, // wordlen = 3 - { 2, 2, 4, 1, 59, NULL, NULL }, // wordlen = 4 - { 1, 2, 4, 1, -1, huff_b35_cb, huff_b35_xlat }, // wordlen = 5 - { 1, 2, 4, 0, 75, NULL, NULL }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_b37_cb, huff_b37_xlat }, // wordlen = 7 + { 1, 4, 2, 1 }, // wordlen = 1 + { 1, 4, 2, 0 }, // wordlen = 2 + { 1, 4, 2, 0 }, // wordlen = 3 + { 2, 2, 4, 1 }, // wordlen = 4 + { 1, 2, 4, 1 }, // wordlen = 5 + { 1, 2, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 4 */ - { 1, 4, 2, 1, -1, huff_b41_cb, huff_b41_xlat }, // wordlen = 1 - { 4, 2, 3, 1, -1, huff_b42_cb, huff_b42_xlat }, // wordlen = 2 - { 1, 2, 3, 1, -1, huff_b43_cb, huff_b43_xlat }, // wordlen = 3 - { 4, 2, 4, 1, 66, NULL, NULL }, // wordlen = 4 - { 1, 1, 3, 0, 32, NULL, NULL }, // wordlen = 5 - { 1, 2, 4, 0, 12, NULL, NULL }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_b47_cb, huff_b47_xlat }, // wordlen = 7 + { 1, 4, 2, 1 }, // wordlen = 1 + { 4, 2, 3, 1 }, // wordlen = 2 + { 1, 2, 3, 1 }, // wordlen = 3 + { 4, 2, 4, 1 }, // wordlen = 4 + { 1, 1, 3, 0 }, // wordlen = 5 + { 1, 2, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 5 */ - { 2, 4, 2, 1, 42, NULL, NULL }, // wordlen = 1 - { 1, 2, 3, 1, -1, huff_b52_cb, huff_b52_xlat }, // wordlen = 2 - { 4, 1, 3, 1, -1, huff_b53_cb, huff_b53_xlat }, // wordlen = 3 - { 1, 1, 3, 0, 17, NULL, NULL }, // wordlen = 4 - { 1, 1, 3, 0, 39, NULL, NULL }, // wordlen = 5 - { 1, 1, 5, 1, -1, huff_b56_cb, huff_b56_xlat }, // wordlen = 6 - { 2, 1, 6, 1, 62, NULL, NULL }, // wordlen = 7 + { 2, 4, 2, 1 }, // wordlen = 1 + { 1, 2, 3, 1 }, // wordlen = 2 + { 4, 1, 3, 1 }, // wordlen = 3 + { 1, 1, 3, 0 }, // wordlen = 4 + { 1, 1, 3, 0 }, // wordlen = 5 + { 1, 1, 5, 1 }, // wordlen = 6 + { 2, 1, 6, 1 }, // wordlen = 7 /* code table = 6 */ - { 1, 4, 2, 1, 28, NULL, NULL }, // wordlen = 1 - { 1, 4, 2, 0, -1, huff_b62_cb, huff_b62_xlat }, // wordlen = 2 - { 1, 1, 3, 1, -1, huff_b63_cb, huff_b63_xlat }, // wordlen = 3 - { 1, 1, 3, 0, -1, huff_b64_cb, huff_b64_xlat }, // wordlen = 4 - { 4, 2, 4, 1, -1, huff_b65_cb, huff_b65_xlat }, // wordlen = 5 - { 1, 2, 4, 0, -1, huff_b66_cb, huff_b66_xlat }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_b67_cb, huff_b67_xlat }, // wordlen = 7 + { 1, 4, 2, 1 }, // wordlen = 1 + { 1, 4, 2, 0 }, // wordlen = 2 + { 1, 1, 3, 1 }, // wordlen = 3 + { 1, 1, 3, 0 }, // wordlen = 4 + { 4, 2, 4, 1 }, // wordlen = 5 + { 1, 2, 4, 0 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 /* code table = 7 */ - { 1, 4, 2, 1, -1, huff_b71_cb, huff_b71_xlat }, // wordlen = 1 - { 4, 4, 2, 0, 78, NULL, NULL }, // wordlen = 2 - { 4, 4, 2, 0, -1, huff_b73_cb, huff_b73_xlat }, // wordlen = 3 - { 1, 1, 4, 1, -1, huff_b74_cb, huff_b74_xlat }, // wordlen = 4 - { 1, 2, 4, 1, -1, huff_b75_cb, huff_b75_xlat }, // wordlen = 5 - { 1, 1, 5, 1, 47, NULL, NULL }, // wordlen = 6 - { 1, 1, 6, 1, -1, huff_b77_cb, huff_b77_xlat }, // wordlen = 7 + { 1, 4, 2, 1 }, // wordlen = 1 + { 4, 4, 2, 0 }, // wordlen = 2 + { 4, 4, 2, 0 }, // wordlen = 3 + { 1, 1, 4, 1 }, // wordlen = 4 + { 1, 2, 4, 1 }, // wordlen = 5 + { 1, 1, 5, 1 }, // wordlen = 6 + { 1, 1, 6, 1 }, // wordlen = 7 }; /* Huffman tables for gain control data. */ -static const uint8_t atrac3p_huff_gain_npoints1_cb[9] = { - 1, 7, 1, 1, 1, 1, 1, 1, 2 +static const uint8_t atrac3p_gain_cbs[][12] = { + { 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0 }, + { 1, 0, 2, 2, 1, 2, 8, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 0, 2, 0, 8, 0, 0, 0 }, + { 1, 0, 3, 1, 1, 0, 2, 0, 8, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 0, 1, 2, 8, 0, 0, 0 }, + { 0, 1, 0, 2, 11, 18, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 2, 4, 4, 4, 0, 16, 0, 0, 0, 0 }, + { 0, 0, 0, 3, 23, 6, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 5, 3, 2, 3, 2, 16, 0, 0, 0, 0 }, + { 1, 0, 0, 3, 2, 6, 20, 0, 0, 0, 0, 0 }, }; -static const uint8_t atrac3p_huff_gain_npoints2_xlat[8] = { - 0, 1, 7, 2, 6, 3, 4, 5 -}; - -static const uint8_t atrac3p_huff_gain_lev1_cb[9] = { 1, 7, 1, 0, 2, 2, 1, 2, 8 }; -static const uint8_t atrac3p_huff_gain_lev1_xlat[16] = { - 7, 5, 8, 6, 9, 4, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15 -}; - -static const uint8_t atrac3p_huff_gain_lev2_cb[11] = { - 1, 9, 1, 1, 1, 1, 1, 0, 2, 0, 8 -}; - -static const uint8_t atrac3p_huff_gain_lev2_xlat[15] = { - 15, 14, 1, 13, 2, 3, 12, 4, 5, 6, 7, 8, 9, 10, 11 -}; - -static const uint8_t atrac3p_huff_gain_lev3_cb[11] = { - 1, 9, 1, 0, 3, 1, 1, 0, 2, 0, 8 -}; - -static const uint8_t atrac3p_huff_gain_lev3_xlat[16] = { - 0, 1, 14, 15, 2, 13, 3, 12, 4, 5, 6, 7, 8, 9, 10, 11 -}; - -static const uint8_t atrac3p_huff_gain_lev4_cb[11] = { - 1, 9, 1, 1, 1, 1, 1, 0, 1, 2, 8 -}; - -static const uint8_t atrac3p_huff_gain_lev4_xlat[16] = { - 0, 1, 15, 14, 2, 13, 3, 12, 4, 5, 6, 7, 8, 9, 10, 11 -}; - -static const uint8_t atrac3p_huff_gain_loc1_cb[9] = { 2, 8, 1, 2, 4, 4, 4, 0, 16 }; -static const uint8_t atrac3p_huff_gain_loc1_xlat[31] = { - 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 -}; - -static const uint8_t atrac3p_huff_gain_loc2_cb[8] = { 3, 8, 5, 3, 2, 3, 2, 16 }; -static const uint8_t atrac3p_huff_gain_loc2_xlat[31] = { - 2, 3, 4, 5, 6, 1, 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 -}; - -static const uint8_t atrac3p_huff_gain_loc3_cb[7] = { 2, 6, 1, 0, 2, 11, 18 }; -static const uint8_t atrac3p_huff_gain_loc3_xlat[32] = { - 0, 1, 31, 2, 3, 4, 5, 6, 7, 26, 27, 28, 29, 30, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 -}; - -static const uint8_t atrac3p_huff_gain_loc4_cb[5] = { 4, 6, 3, 23, 6 }; -static const uint8_t atrac3p_huff_gain_loc4_xlat[32] = { - 0, 28, 29, 1, 2, 3, 4, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 30, 31, 5, 6, 7, 8, 9, 10 -}; - -static const uint8_t atrac3p_huff_gain_loc5_cb[9] = { 1, 7, 1, 0, 0, 3, 2, 6, 20 }; -static const uint8_t atrac3p_huff_gain_loc5_xlat[32] = { - 0, 1, 2, 31, 3, 4, 5, 6, 7, 8, 29, 30, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 +static const uint8_t atrac3p_gain_xlats[] = { + /* Number of gain control points 1 - 8 entries */ + 0, 1, 2, 3, 4, 5, 6, 7, + /* Number of gain control points 2 - 8 entries */ + 0, 1, 7, 2, 6, 3, 4, 5, + /* Gain compensation level 1 - 16 entries */ + 7, 5, 8, 6, 9, 4, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15, + /* Gain compensation level 2 - 15 entries */ + 15, 14, 1, 13, 2, 3, 12, 4, 5, 6, 7, 8, 9, 10, 11, + /* Gain compensation level 3 - 16 entries */ + 0, 1, 14, 15, 2, 13, 3, 12, 4, 5, 6, 7, 8, 9, 10, 11, + /* Gain compensation level 4 - 16 entries */ + 0, 1, 15, 14, 2, 13, 3, 12, 4, 5, 6, 7, 8, 9, 10, 11, + /* Gain compensation location 3 - 32 entries */ + 0, 1, 31, 2, 3, 4, 5, 6, 7, 26, 27, 28, 29, 30, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + /* Gain compensation location 1 - 31 entries */ + 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, + /* Gain compensation location 4 - 32 entries */ + 0, 28, 29, 1, 2, 3, 4, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 30, 31, 5, 6, 7, 8, 9, 10, + /* Gain compensation location 2 - 31 entries */ + 2, 3, 4, 5, 6, 1, 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, + /* Gain compensation location 5 - 32 entries */ + 0, 1, 2, 31, 3, 4, 5, 6, 7, 8, 29, 30, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, }; /* Huffman tables for GHA waves data. */ -static const uint8_t atrac3p_huff_tonebands_cb[8] = { 1, 6, 1, 0, 1, 2, 4, 8 }; -static const uint8_t atrac3p_huff_numwavs1_cb[9] = { 1, 7, 1, 1, 1, 1, 1, 1, 2 }; -static const uint8_t atrac3p_huff_numwavs2_cb[8] = { 1, 6, 1, 1, 1, 1, 0, 4 }; -static const uint8_t atrac3p_huff_numwavs2_xlat[8] = { 0, 1, 7, 2, 3, 4, 5, 6 }; -static const uint8_t atrac3p_huff_wav_ampsf1_cb[7] = { 4, 8, 10, 8, 6, 0, 8 }; -static const uint8_t atrac3p_huff_wav_ampsf1_xlat[32] = { - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 5, 6, 7, 18, 19, 20, - 21, 22, 4, 23, 24, 25, 26, 27, 0, 1, 2, 3, 28, 29, 30, 31 +static const uint8_t atrac3p_tone_cbs[][12] = { + { 1, 0, 1, 2, 4, 8, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 0, 4, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 10, 8, 6, 0, 8, 0, 0, 0, 0 }, + { 0, 0, 0, 11, 5, 6, 6, 4, 0, 0, 0, 0 }, + { 0, 1, 3, 3, 1, 4, 4, 16, 0, 0, 0, 0 }, + { 1, 0, 0, 2, 2, 0, 9, 9, 29,104, 100, 0 }, }; -static const uint8_t atrac3p_huff_wav_ampsf2_cb[7] = { 4, 8, 11, 5, 6, 6, 4 }; -static const uint8_t atrac3p_huff_wav_ampsf2_xlat[32] = { - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 14, 15, 16, 17, 29, - 9, 10, 11, 12, 13, 30, 4, 5, 6, 7, 8, 31, 0, 1, 2, 3 -}; - -static const uint8_t atrac3p_huff_wav_ampsf3_cb[9] = { 2, 8, 1, 3, 3, 1, 4, 4, 16 }; -static const uint8_t atrac3p_huff_wav_ampsf3_xlat[32] = { - 0, 1, 2, 31, 3, 29, 30, 4, 5, 6, 27, 28, 7, 24, 25, 26, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 -}; - -static const uint8_t atrac3p_huff_freq_cb[13] = { - 1, 11, 1, 0, 0, 2, 2, 0, 9, 9, 29, 104, 100 -}; - -static const uint8_t atrac3p_huff_freq_xlat[256] = { - 0, 1, 255, 2, 254, 3, 4, 5, 6, 7, 8, 251, 252, 253, 9, 10, - 11, 12, 246, 247, 248, 249, 250, 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, 243, 244, 245, 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, 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, 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 +static const uint8_t atrac3p_tone_xlats[] = { + /* Number of tone bands - 16 entries */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, + /* Number of tones 1 - 8 entries */ + 0, 1, 2, 3, 4, 5, 6, 7, + /* Number of tones 2 - 8 entries */ + 0, 1, 7, 2, 3, 4, 5, 6, + /* Amplitude information 1 - 32 entries */ + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 5, 6, 7, 18, 19, + 20, 21, 22, 4, 23, 24, 25, 26, 27, 0, 1, 2, 3, 28, 29, + 30, 31, + /* Amplitude information 2 - 32 entries */ + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 14, 15, 16, 17, + 29, 9, 10, 11, 12, 13, 30, 4, 5, 6, 7, 8, 31, 0, 1, + 2, 3, + /* Amplitude information 3 - 32 entries */ + 0, 1, 2, 31, 3, 29, 30, 4, 5, 6, 27, 28, 7, 24, 25, + 26, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, + /* Frequencies - 256 entries */ + 0, 1, 255, 2, 254, 3, 4, 5, 6, 7, 8, 251, 252, 253, 9, + 10, 11, 12, 246, 247, 248, 249, 250, 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, 243, 244, 245, 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, 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, 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, }; #endif /* AVCODEC_ATRAC3PLUS_DATA_H */ diff --git a/libavcodec/atrac3plusdec.c b/libavcodec/atrac3plusdec.c index 4b008ba0e..c024ab6bd 100644 --- a/libavcodec/atrac3plusdec.c +++ b/libavcodec/atrac3plusdec.c @@ -39,6 +39,8 @@ #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "get_bits.h" #include "internal.h" @@ -144,8 +146,15 @@ static av_cold int set_channel_params(ATRAC3PContext *ctx, return 0; } +static av_cold void atrac3p_init_static(void) +{ + ff_atrac3p_init_vlcs(); + ff_atrac3p_init_dsp_static(); +} + static av_cold int atrac3p_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; ATRAC3PContext *ctx = avctx->priv_data; int i, ch, ret; @@ -154,8 +163,6 @@ static av_cold int atrac3p_decode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - ff_atrac3p_init_vlcs(); - /* initialize IPQF */ ff_mdct_init(&ctx->ipqf_dct_ctx, 5, 1, 32.0 / 32768.0); @@ -163,8 +170,6 @@ static av_cold int atrac3p_decode_init(AVCodecContext *avctx) ff_atrac_init_gain_compensation(&ctx->gainc_ctx, 6, 2); - ff_atrac3p_init_wave_synth(); - if ((ret = set_channel_params(ctx, avctx)) < 0) return ret; @@ -194,6 +199,8 @@ static av_cold int atrac3p_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + ff_thread_once(&init_static_once, atrac3p_init_static); + return 0; } @@ -392,7 +399,7 @@ AVCodec ff_atrac3p_decoder = { .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ATRAC3P, .capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .priv_data_size = sizeof(ATRAC3PContext), .init = atrac3p_decode_init, .close = atrac3p_decode_close, @@ -405,7 +412,7 @@ AVCodec ff_atrac3pal_decoder = { .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ATRAC3PAL, .capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .priv_data_size = sizeof(ATRAC3PContext), .init = atrac3p_decode_init, .close = atrac3p_decode_close, diff --git a/libavcodec/atrac3plusdsp.c b/libavcodec/atrac3plusdsp.c index ca3154e13..e32c5c817 100644 --- a/libavcodec/atrac3plusdsp.c +++ b/libavcodec/atrac3plusdsp.c @@ -29,6 +29,8 @@ #include "libavutil/float_dsp.h" #include "libavutil/libm.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "sinewin.h" #include "fft.h" @@ -79,9 +81,6 @@ const float ff_atrac3p_mant_tab[8] = { av_cold void ff_atrac3p_init_imdct(AVCodecContext *avctx, FFTContext *mdct_ctx) { - ff_init_ff_sine_windows(7); - ff_init_ff_sine_windows(6); - /* Initialize the MDCT transform. */ ff_mdct_init(mdct_ctx, 8, 1, -1.0); } @@ -94,7 +93,7 @@ static DECLARE_ALIGNED(32, float, sine_table)[2048]; ///< wave table static DECLARE_ALIGNED(32, float, hann_window)[256]; ///< Hann windowing function static float amp_sf_tab[64]; ///< scalefactors for quantized amplitudes -av_cold void ff_atrac3p_init_wave_synth(void) +av_cold void ff_atrac3p_init_dsp_static(void) { int i; @@ -109,6 +108,9 @@ av_cold void ff_atrac3p_init_wave_synth(void) /* generate amplitude scalefactors table */ for (i = 0; i < 64; i++) amp_sf_tab[i] = exp2f((i - 3) / 4.0f); + + ff_init_ff_sine_windows(7); + ff_init_ff_sine_windows(6); } /** diff --git a/libavcodec/atrac9dec.c b/libavcodec/atrac9dec.c index 075d610e7..f88b25da4 100644 --- a/libavcodec/atrac9dec.c +++ b/libavcodec/atrac9dec.c @@ -19,12 +19,18 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/thread.h" + #include "internal.h" #include "get_bits.h" #include "fft.h" #include "atrac9tab.h" #include "libavutil/lfg.h" #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" + +#define ATRAC9_SF_VLC_BITS 8 +#define ATRAC9_COEFF_VLC_BITS 9 typedef struct ATRAC9ChannelData { int band_ext; @@ -90,14 +96,15 @@ typedef struct ATRAC9Context { const ATRAC9BlockConfig *block_config; /* Generated on init */ - VLC sf_vlc[2][8]; /* Signed/unsigned, length */ - VLC coeff_vlc[2][8][4]; /* Cookbook, precision, cookbook index */ uint8_t alloc_curve[48][48]; DECLARE_ALIGNED(32, float, imdct_win)[256]; DECLARE_ALIGNED(32, float, temp)[256]; } ATRAC9Context; +static VLC sf_vlc[2][8]; /* Signed/unsigned, length */ +static VLC coeff_vlc[2][8][4]; /* Cookbook, precision, cookbook index */ + static inline int parse_gradient(ATRAC9Context *s, ATRAC9BlockData *b, GetBitContext *gb) { @@ -267,12 +274,13 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b, const uint8_t *sf_weights = at9_tab_sf_weights[get_bits(gb, 3)]; const int base = get_bits(gb, 5); const int len = get_bits(gb, 2) + 3; - const VLC *tab = &s->sf_vlc[0][len]; + const VLC *tab = &sf_vlc[0][len]; c->scalefactors[0] = get_bits(gb, len); for (int i = 1; i < b->band_ext_q_unit; i++) { - int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, 9, 2); + int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, + ATRAC9_SF_VLC_BITS, 1); c->scalefactors[i] = val & ((1 << len) - 1); } @@ -299,10 +307,10 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b, const int len = get_bits(gb, 2) + 2; const int unit_cnt = FFMIN(b->band_ext_q_unit, baseline_len); - const VLC *tab = &s->sf_vlc[1][len]; + const VLC *tab = &sf_vlc[1][len]; for (int i = 0; i < unit_cnt; i++) { - int dist = get_vlc2(gb, tab->table, 9, 2); + int dist = get_vlc2(gb, tab->table, ATRAC9_SF_VLC_BITS, 1); c->scalefactors[i] = baseline[i] + dist; } @@ -320,12 +328,13 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b, const int base = get_bits(gb, 5) - (1 << (5 - 1)); const int len = get_bits(gb, 2) + 1; const int unit_cnt = FFMIN(b->band_ext_q_unit, baseline_len); - const VLC *tab = &s->sf_vlc[0][len]; + const VLC *tab = &sf_vlc[0][len]; c->scalefactors[0] = get_bits(gb, len); for (int i = 1; i < unit_cnt; i++) { - int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, 9, 2); + int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, + ATRAC9_SF_VLC_BITS, 1); c->scalefactors[i] = val & ((1 << len) - 1); } @@ -406,12 +415,12 @@ static inline void read_coeffs_coarse(ATRAC9Context *s, ATRAC9BlockData *b, if (prec <= max_prec) { const int cb = c->codebookset[i]; const int cbi = at9_q_unit_to_codebookidx[i]; - const VLC *tab = &s->coeff_vlc[cb][prec][cbi]; + const VLC *tab = &coeff_vlc[cb][prec][cbi]; const HuffmanCodebook *huff = &at9_huffman_coeffs[cb][prec][cbi]; const int groups = bands >> huff->value_cnt_pow; for (int j = 0; j < groups; j++) { - uint16_t val = get_vlc2(gb, tab->table, 9, huff->max_bit_size); + uint16_t val = get_vlc2(gb, tab->table, ATRAC9_COEFF_VLC_BITS, 2); for (int k = 0; k < huff->value_cnt; k++) { coeffs[k] = sign_extend(val, huff->value_bits); @@ -824,23 +833,69 @@ static av_cold int atrac9_decode_close(AVCodecContext *avctx) { ATRAC9Context *s = avctx->priv_data; - for (int i = 1; i < 7; i++) - ff_free_vlc(&s->sf_vlc[0][i]); - for (int i = 2; i < 6; i++) - ff_free_vlc(&s->sf_vlc[1][i]); - for (int i = 0; i < 2; i++) - for (int j = 0; j < 8; j++) - for (int k = 0; k < 4; k++) - ff_free_vlc(&s->coeff_vlc[i][j][k]); - ff_mdct_end(&s->imdct); - av_free(s->fdsp); + av_freep(&s->fdsp); return 0; } +static av_cold void atrac9_init_vlc(VLC *vlc, int nb_bits, int nb_codes, + const uint8_t (**tab)[2], + unsigned *buf_offset, int offset) +{ + static VLC_TYPE vlc_buf[24812][2]; + + vlc->table = &vlc_buf[*buf_offset]; + vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *buf_offset; + ff_init_vlc_from_lengths(vlc, nb_bits, nb_codes, + &(*tab)[0][1], 2, &(*tab)[0][0], 2, 1, + offset, INIT_VLC_STATIC_OVERLONG, NULL); + *buf_offset += vlc->table_size; + *tab += nb_codes; +} + +static av_cold void atrac9_init_static(void) +{ + const uint8_t (*tab)[2]; + unsigned offset = 0; + + /* Unsigned scalefactor VLCs */ + tab = at9_sfb_a_tab; + for (int i = 1; i < 7; i++) { + const HuffmanCodebook *hf = &at9_huffman_sf_unsigned[i]; + + atrac9_init_vlc(&sf_vlc[0][i], ATRAC9_SF_VLC_BITS, + hf->size, &tab, &offset, 0); + } + + /* Signed scalefactor VLCs */ + tab = at9_sfb_b_tab; + for (int i = 2; i < 6; i++) { + const HuffmanCodebook *hf = &at9_huffman_sf_signed[i]; + + /* The symbols are signed integers in the range -16..15; + * the values in the source table are offset by 16 to make + * them fit into an uint8_t; the -16 reverses this shift. */ + atrac9_init_vlc(&sf_vlc[1][i], ATRAC9_SF_VLC_BITS, + hf->size, &tab, &offset, -16); + } + + /* Coefficient VLCs */ + tab = at9_coeffs_tab; + for (int i = 0; i < 2; i++) { + for (int j = 2; j < 8; j++) { + for (int k = i; k < 4; k++) { + const HuffmanCodebook *hf = &at9_huffman_coeffs[i][j][k]; + atrac9_init_vlc(&coeff_vlc[i][j][k], ATRAC9_COEFF_VLC_BITS, + hf->size, &tab, &offset, 0); + } + } + } +} + static av_cold int atrac9_decode_init(AVCodecContext *avctx) { + static AVOnce static_table_init = AV_ONCE_INIT; GetBitContext gb; ATRAC9Context *s = avctx->priv_data; int version, block_config_idx, superframe_idx, alloc_c_len; @@ -926,37 +981,7 @@ static av_cold int atrac9_decode_init(AVCodecContext *avctx) for (int j = 0; j < i; j++) s->alloc_curve[i - 1][j] = at9_tab_b_dist[(j * alloc_c_len) / i]; - /* Unsigned scalefactor VLCs */ - for (int i = 1; i < 7; i++) { - const HuffmanCodebook *hf = &at9_huffman_sf_unsigned[i]; - - init_vlc(&s->sf_vlc[0][i], 9, hf->size, hf->bits, 1, 1, hf->codes, - 2, 2, 0); - } - - /* Signed scalefactor VLCs */ - for (int i = 2; i < 6; i++) { - const HuffmanCodebook *hf = &at9_huffman_sf_signed[i]; - - int nums = hf->size; - int16_t sym[32]; - for (int j = 0; j < nums; j++) - sym[j] = sign_extend(j, hf->value_bits); - - ff_init_vlc_sparse(&s->sf_vlc[1][i], 9, hf->size, hf->bits, 1, 1, - hf->codes, 2, 2, sym, sizeof(*sym), sizeof(*sym), 0); - } - - /* Coefficient VLCs */ - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 8; j++) { - for (int k = 0; k < 4; k++) { - const HuffmanCodebook *hf = &at9_huffman_coeffs[i][j][k]; - init_vlc(&s->coeff_vlc[i][j][k], 9, hf->size, hf->bits, 1, 1, - hf->codes, 2, 2, 0); - } - } - } + ff_thread_once(&static_table_init, atrac9_init_static); return 0; } @@ -972,5 +997,5 @@ AVCodec ff_atrac9_decoder = { .decode = atrac9_decode_frame, .flush = atrac9_decode_flush, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, - .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; diff --git a/libavcodec/atrac9tab.h b/libavcodec/atrac9tab.h index 8f290f158..b169035aa 100644 --- a/libavcodec/atrac9tab.h +++ b/libavcodec/atrac9tab.h @@ -104,7 +104,7 @@ static const int at9_q_unit_to_coeff_idx[] = { 72, 80, 88, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256 }; -const uint8_t at9_q_unit_to_codebookidx[] = { +static const uint8_t at9_q_unit_to_codebookidx[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }; @@ -373,1165 +373,921 @@ static const uint8_t at9_tab_b_dist[] = { 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, }; -static const uint8_t huff_sfb_a1_bits[] = { - 1, 1, +static const uint8_t at9_sfb_a_tab[][2] = { + /* Unsigned scalefactor table 1 - 2 entries */ + { 0, 1 }, { 1, 1 }, + /* Unsigned scalefactor table 2 - 4 entries */ + { 0, 1 }, { 3, 2 }, { 1, 3 }, { 2, 3 }, + /* Unsigned scalefactor table 3 - 8 entries */ + { 0, 2 }, { 1, 2 }, { 7, 2 }, { 6, 3 }, { 2, 4 }, { 5, 5 }, { 3, 6 }, + { 4, 6 }, + /* Unsigned scalefactor table 4 - 16 entries */ + { 2, 4 }, { 14, 4 }, { 11, 8 }, { 10, 8 }, { 9, 8 }, { 6, 8 }, { 7, 8 }, + { 8, 8 }, { 5, 7 }, { 13, 5 }, { 3, 5 }, { 12, 6 }, { 4, 6 }, { 0, 2 }, + { 1, 2 }, { 15, 2 }, + /* Unsigned scalefactor table 5 - 32 entries */ + { 31, 3 }, { 1, 3 }, { 26, 7 }, { 7, 7 }, { 20, 8 }, { 21, 8 }, { 23, 8 }, + { 22, 8 }, { 29, 5 }, { 30, 4 }, { 4, 5 }, { 11, 8 }, { 24, 8 }, { 9, 8 }, + { 10, 8 }, { 6, 6 }, { 25, 7 }, { 19, 8 }, { 12, 8 }, { 27, 6 }, { 18, 8 }, + { 13, 8 }, { 16, 8 }, { 17, 8 }, { 14, 8 }, { 15, 8 }, { 8, 7 }, { 0, 2 }, + { 5, 5 }, { 28, 5 }, { 3, 4 }, { 2, 3 }, + /* Unsigned scalefactor table 6 - 64 entries */ + { 0, 3 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 61, 4 }, { 62, 4 }, { 63, 4 }, + { 4, 5 }, { 5, 5 }, { 58, 5 }, { 59, 5 }, { 60, 5 }, { 6, 6 }, { 7, 6 }, + { 8, 6 }, { 56, 6 }, { 57, 6 }, { 9, 7 }, { 10, 7 }, { 53, 7 }, { 54, 7 }, + { 55, 7 }, { 11, 8 }, { 12, 8 }, { 13, 8 }, { 14, 8 }, { 15, 8 }, { 16, 8 }, + { 17, 8 }, { 18, 8 }, { 19, 8 }, { 20, 8 }, { 21, 8 }, { 22, 8 }, { 23, 8 }, + { 24, 8 }, { 25, 8 }, { 26, 8 }, { 27, 8 }, { 28, 8 }, { 29, 8 }, { 30, 8 }, + { 31, 8 }, { 32, 8 }, { 33, 8 }, { 34, 8 }, { 35, 8 }, { 36, 8 }, { 37, 8 }, + { 38, 8 }, { 39, 8 }, { 40, 8 }, { 41, 8 }, { 42, 8 }, { 43, 8 }, { 44, 8 }, + { 45, 8 }, { 46, 8 }, { 47, 8 }, { 48, 8 }, { 49, 8 }, { 50, 8 }, { 51, 8 }, + { 52, 8 }, }; -static const uint16_t huff_sfb_a1_codes[] = { - 0x00, 0x01, -}; - -static const uint8_t huff_sfb_a2_bits[] = { - 1, 3, 3, 2, -}; - -static const uint16_t huff_sfb_a2_codes[] = { - 0x00, 0x06, 0x07, 0x02, -}; - -static const uint8_t huff_sfb_a3_bits[] = { - 2, 2, 4, 6, 6, 5, 3, 2, -}; - -static const uint16_t huff_sfb_a3_codes[] = { - 0x00, 0x01, 0x0E, 0x3E, 0x3F, 0x1E, 0x06, 0x02, -}; - -static const uint8_t huff_sfb_a4_bits[] = { - 2, 2, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 6, 5, 4, 2, -}; - -static const uint16_t huff_sfb_a4_codes[] = { - 0x01, 0x02, 0x00, 0x06, 0x0F, 0x13, 0x23, 0x24, - 0x25, 0x22, 0x21, 0x20, 0x0E, 0x05, 0x01, 0x03, -}; - -static const uint8_t huff_sfb_a5_bits[] = { - 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 5, 5, 4, 3, -}; - -static const uint16_t huff_sfb_a5_codes[] = { - 0x02, 0x01, 0x07, 0x0D, 0x0C, 0x18, 0x1B, 0x21, 0x3F, 0x6A, 0x6B, 0x68, - 0x73, 0x79, 0x7C, 0x7D, 0x7A, 0x7B, 0x78, 0x72, 0x44, 0x45, 0x47, 0x46, - 0x69, 0x38, 0x20, 0x1D, 0x19, 0x09, 0x05, 0x00, -}; - -static const uint8_t huff_sfb_a6_bits[] = { - 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 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, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, -}; - -static const uint16_t huff_sfb_a6_codes[] = { - 0x00, 0x01, 0x04, 0x05, 0x12, 0x13, 0x2E, 0x2F, 0x30, 0x66, 0x67, 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, 0x68, 0x69, 0x6A, 0x31, 0x32, 0x14, 0x15, - 0x16, 0x06, 0x07, 0x08, -}; - -static const uint8_t huff_sfb_b2_bits[] = { - 1, 2, 0, 2, -}; - -static const uint16_t huff_sfb_b2_codes[] = { - 0x00, 0x03, 0x00, 0x02, -}; - -static const uint8_t huff_sfb_b3_bits[] = { - 1, 3, 5, 6, 0, 6, 4, 2, -}; - -static const uint16_t huff_sfb_b3_codes[] = { - 0x01, 0x00, 0x04, 0x0B, 0x00, 0x0A, 0x03, 0x01, -}; - -static const uint8_t huff_sfb_b4_bits[] = { - 1, 3, 4, 5, 5, 7, 8, 8, 0, 8, 8, 7, 6, 6, 4, 3, -}; - -static const uint16_t huff_sfb_b4_codes[] = { - 0x01, 0x01, 0x04, 0x0E, 0x0F, 0x2C, 0x5A, 0x5D, 0x00, 0x5C, 0x5B, 0x2F, - 0x15, 0x14, 0x06, 0x00, -}; - -static const uint8_t huff_sfb_b5_bits[] = { - 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 6, 7, 7, 7, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 3, -}; - -static const uint16_t huff_sfb_b5_codes[] = { - 0x00, 0x05, 0x07, 0x0C, 0x04, 0x02, 0x03, 0x05, 0x09, 0x10, 0x23, 0x33, - 0x36, 0x6E, 0x60, 0x65, 0x62, 0x61, 0x63, 0x64, 0x6F, 0x6D, 0x6C, 0x6B, - 0x6A, 0x68, 0x69, 0x45, 0x44, 0x37, 0x1A, 0x07, +static const uint8_t at9_sfb_b_tab[][2] = { + /* Signed scalefactor table 2 - 3 entries */ + { 16, 1 }, { 15, 2 }, { 17, 2 }, + /* Signed scalefactor table 3 - 7 entries */ + { 17, 3 }, { 18, 5 }, { 13, 6 }, { 19, 6 }, { 14, 4 }, { 15, 2 }, { 16, 1 }, + /* Signed scalefactor table 4 - 15 entries */ + { 15, 3 }, { 17, 3 }, { 18, 4 }, { 13, 6 }, { 12, 6 }, { 21, 7 }, { 22, 8 }, + { 10, 8 }, { 9, 8 }, { 23, 8 }, { 11, 7 }, { 14, 4 }, { 19, 5 }, { 20, 5 }, + { 16, 1 }, + /* Signed scalefactor table 5 - 32 entries */ + { 16, 3 }, { 21, 4 }, { 22, 4 }, { 20, 4 }, { 23, 4 }, { 30, 8 }, { 1, 8 }, + { 0, 8 }, { 2, 8 }, { 3, 8 }, { 31, 8 }, { 27, 7 }, { 14, 6 }, { 28, 7 }, + { 13, 7 }, { 18, 4 }, { 25, 5 }, { 12, 7 }, { 11, 7 }, { 26, 6 }, { 24, 4 }, + { 17, 3 }, { 19, 4 }, { 9, 7 }, { 10, 7 }, { 8, 7 }, { 7, 7 }, { 6, 7 }, + { 5, 7 }, { 29, 7 }, { 4, 7 }, { 15, 3 }, }; typedef struct HuffmanCodebook { - const uint8_t *bits; - const uint16_t *codes; const int size; const int value_cnt; const int value_cnt_pow; const int value_bits; - const int max_bit_size; } HuffmanCodebook; static const HuffmanCodebook at9_huffman_sf_unsigned[] = { { 0 }, - { huff_sfb_a1_bits, huff_sfb_a1_codes, 2, 1, 0, 1, 1, }, - { huff_sfb_a2_bits, huff_sfb_a2_codes, 4, 1, 0, 2, 3, }, - { huff_sfb_a3_bits, huff_sfb_a3_codes, 8, 1, 0, 3, 6, }, - { huff_sfb_a4_bits, huff_sfb_a4_codes, 16, 1, 0, 4, 8, }, - { huff_sfb_a5_bits, huff_sfb_a5_codes, 32, 1, 0, 5, 8, }, - { huff_sfb_a6_bits, huff_sfb_a6_codes, 64, 1, 0, 6, 8, }, + { 2, 1, 0, 1 }, + { 4, 1, 0, 2 }, + { 8, 1, 0, 3 }, + { 16, 1, 0, 4 }, + { 32, 1, 0, 5 }, + { 64, 1, 0, 6 }, }; static const HuffmanCodebook at9_huffman_sf_signed[] = { { 0 }, { 0 }, - { huff_sfb_b2_bits, huff_sfb_b2_codes, 4, 1, 0, 2, 2, }, - { huff_sfb_b3_bits, huff_sfb_b3_codes, 8, 1, 0, 3, 6, }, - { huff_sfb_b4_bits, huff_sfb_b4_codes, 16, 1, 0, 4, 8, }, - { huff_sfb_b5_bits, huff_sfb_b5_codes, 32, 1, 0, 5, 8, }, -}; - -static const uint8_t huff_spec_a21_bits[] = { - 0, 3, 0, 3, 3, 3, 0, 3, 0, 0, 0, 0, 3, 3, 0, 3, -}; - -static const uint16_t huff_spec_a21_codes[] = { - 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x06, -}; - -static const uint8_t huff_spec_a22_bits[] = { - 0, 4, 0, 4, 5, 6, 0, 6, 0, 0, 0, 0, 5, 6, 0, 6, - 5, 6, 0, 6, 6, 7, 0, 7, 0, 0, 0, 0, 6, 7, 0, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 6, 0, 6, 6, 7, 0, 7, 0, 0, 0, 0, 6, 7, 0, 7, - 5, 6, 0, 6, 7, 7, 0, 7, 0, 0, 0, 0, 6, 7, 0, 7, - 6, 7, 0, 7, 7, 8, 0, 8, 0, 0, 0, 0, 7, 8, 0, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 7, 0, 7, 7, 8, 0, 8, 0, 0, 0, 0, 7, 7, 0, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 6, 0, 6, 6, 7, 0, 7, 0, 0, 0, 0, 7, 7, 0, 7, - 6, 7, 0, 7, 7, 8, 0, 7, 0, 0, 0, 0, 7, 8, 0, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 7, 0, 7, 7, 7, 0, 8, 0, 0, 0, 0, 7, 8, 0, 8, -}; - -static const uint16_t huff_spec_a22_codes[] = { - 0x00, 0x02, 0x00, 0x03, 0x10, 0x3C, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x11, 0x3E, 0x00, 0x3D, - 0x0E, 0x00, 0x00, 0x39, 0x18, 0x26, 0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x24, 0x00, 0x6D, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0F, 0x38, 0x00, 0x01, 0x1A, 0x6C, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x19, 0x74, 0x00, 0x27, - 0x16, 0x14, 0x00, 0x17, 0x76, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x35, 0x64, 0x00, 0x6F, - 0x26, 0x04, 0x00, 0x63, 0x22, 0xA2, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x67, 0xA0, 0x00, 0x0D, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2B, 0x52, 0x00, 0x0B, 0x20, 0x92, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x61, 0x0E, 0x00, 0x95, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x17, 0x16, 0x00, 0x15, 0x34, 0x6E, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x77, 0x08, 0x00, 0x07, - 0x2A, 0x0A, 0x00, 0x53, 0x60, 0x94, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x00, 0x93, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x27, 0x62, 0x00, 0x05, 0x66, 0x0C, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x23, 0x96, 0x00, 0xA3, -}; - -static const uint8_t huff_spec_a23_bits[] = { - 3, 4, 0, 4, 5, 6, 0, 6, 0, 0, 0, 0, 5, 6, 0, 6, - 5, 7, 0, 6, 6, 8, 0, 7, 0, 0, 0, 0, 6, 8, 0, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 6, 0, 7, 6, 7, 0, 8, 0, 0, 0, 0, 6, 7, 0, 8, - 5, 6, 0, 6, 7, 8, 0, 8, 0, 0, 0, 0, 6, 7, 0, 7, - 6, 8, 0, 7, 8, 9, 0, 9, 0, 0, 0, 0, 7, 9, 0, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 8, 0, 8, 8, 9, 0, 9, 0, 0, 0, 0, 7, 8, 0, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 6, 0, 6, 6, 7, 0, 7, 0, 0, 0, 0, 7, 8, 0, 8, - 6, 8, 0, 8, 7, 9, 0, 8, 0, 0, 0, 0, 8, 9, 0, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 7, 0, 8, 7, 8, 0, 9, 0, 0, 0, 0, 8, 9, 0, 9, -}; - -static const uint16_t huff_spec_a23_codes[] = { - 0x006, 0x002, 0x000, 0x003, 0x016, 0x01E, 0x000, 0x021, 0x000, 0x000, 0x000, 0x000, - 0x017, 0x020, 0x000, 0x01F, 0x01C, 0x054, 0x000, 0x027, 0x010, 0x0A6, 0x000, 0x027, - 0x000, 0x000, 0x000, 0x000, 0x015, 0x0A4, 0x000, 0x02D, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x01D, 0x026, 0x000, 0x055, 0x014, 0x02C, 0x000, 0x0A5, 0x000, 0x000, 0x000, 0x000, - 0x011, 0x026, 0x000, 0x0A7, 0x01E, 0x000, 0x000, 0x003, 0x04A, 0x074, 0x000, 0x071, - 0x000, 0x000, 0x000, 0x000, 0x023, 0x00A, 0x000, 0x009, 0x018, 0x072, 0x000, 0x00D, - 0x0A2, 0x15A, 0x000, 0x123, 0x000, 0x000, 0x000, 0x000, 0x00F, 0x158, 0x000, 0x05D, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x01B, 0x0AE, 0x000, 0x077, 0x092, 0x140, 0x000, 0x121, - 0x000, 0x000, 0x000, 0x000, 0x025, 0x05E, 0x000, 0x143, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x01F, 0x002, 0x000, 0x001, 0x022, 0x008, 0x000, 0x00B, 0x000, 0x000, 0x000, 0x000, - 0x04B, 0x070, 0x000, 0x075, 0x01A, 0x076, 0x000, 0x0AF, 0x024, 0x142, 0x000, 0x05F, - 0x000, 0x000, 0x000, 0x000, 0x093, 0x120, 0x000, 0x141, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x019, 0x00C, 0x000, 0x073, 0x00E, 0x05C, 0x000, 0x159, 0x000, 0x000, 0x000, 0x000, - 0x0A3, 0x122, 0x000, 0x15B, -}; - -static const uint8_t huff_spec_a24_bits[] = { - 2, 4, 0, 4, 5, 6, 0, 6, 0, 0, 0, 0, 5, 6, 0, 6, - 5, 7, 0, 6, 6, 8, 0, 8, 0, 0, 0, 0, 6, 8, 0, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 6, 0, 7, 6, 8, 0, 8, 0, 0, 0, 0, 6, 8, 0, 8, - 5, 7, 0, 7, 7, 9, 0, 9, 0, 0, 0, 0, 6, 8, 0, 8, - 6, 9, 0, 8, 8, 10, 0, 10, 0, 0, 0, 0, 8, 10, 0, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 8, 0, 9, 9, 10, 0, 10, 0, 0, 0, 0, 8, 9, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 7, 0, 7, 6, 8, 0, 8, 0, 0, 0, 0, 7, 9, 0, 9, - 6, 9, 0, 8, 8, 10, 0, 9, 0, 0, 0, 0, 9, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 8, 0, 9, 8, 9, 0, 10, 0, 0, 0, 0, 8, 10, 0, 10, -}; - -static const uint16_t huff_spec_a24_codes[] = { - 0x002, 0x002, 0x000, 0x003, 0x01E, 0x010, 0x000, 0x013, 0x000, 0x000, 0x000, 0x000, - 0x01F, 0x012, 0x000, 0x011, 0x01A, 0x030, 0x000, 0x01B, 0x000, 0x064, 0x000, 0x0C1, - 0x000, 0x000, 0x000, 0x000, 0x003, 0x052, 0x000, 0x07D, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x01B, 0x01A, 0x000, 0x031, 0x002, 0x07C, 0x000, 0x053, 0x000, 0x000, 0x000, 0x000, - 0x001, 0x0C0, 0x000, 0x065, 0x01C, 0x062, 0x000, 0x065, 0x02A, 0x198, 0x000, 0x19B, - 0x000, 0x000, 0x000, 0x000, 0x017, 0x078, 0x000, 0x07B, 0x004, 0x0FE, 0x000, 0x077, - 0x050, 0x33A, 0x000, 0x1F9, 0x000, 0x000, 0x000, 0x000, 0x073, 0x338, 0x000, 0x0E1, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x007, 0x066, 0x000, 0x187, 0x19E, 0x308, 0x000, 0x30B, - 0x000, 0x000, 0x000, 0x000, 0x075, 0x0E2, 0x000, 0x1FB, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x01D, 0x064, 0x000, 0x063, 0x016, 0x07A, 0x000, 0x079, 0x000, 0x000, 0x000, 0x000, - 0x02B, 0x19A, 0x000, 0x199, 0x006, 0x186, 0x000, 0x067, 0x074, 0x1FA, 0x000, 0x0E3, - 0x000, 0x000, 0x000, 0x000, 0x19F, 0x30A, 0x000, 0x309, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x005, 0x076, 0x000, 0x0FF, 0x072, 0x0E0, 0x000, 0x339, 0x000, 0x000, 0x000, 0x000, - 0x051, 0x1F8, 0x000, 0x33B, -}; - -static const uint8_t huff_spec_a31_bits[] = { - 0, 0, 4, 5, 0, 5, 4, 0, 0, 0, 5, 5, 0, 5, 5, 0, - 5, 5, 6, 6, 0, 6, 5, 5, 5, 6, 6, 7, 0, 7, 6, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 7, 0, 7, 6, 6, - 5, 5, 5, 6, 0, 6, 6, 5, 0, 0, 5, 5, 0, 5, 5, 0, -}; - -static const uint16_t huff_spec_a31_codes[] = { - 0x00, 0x00, 0x02, 0x18, 0x00, 0x19, 0x03, 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x09, 0x15, 0x00, - 0x1A, 0x0A, 0x3E, 0x2C, 0x00, 0x2F, 0x01, 0x0D, 0x0E, 0x38, 0x20, 0x78, 0x00, 0x7B, 0x23, 0x3B, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x3A, 0x22, 0x7A, 0x00, 0x79, 0x21, 0x39, - 0x1B, 0x0C, 0x00, 0x2E, 0x00, 0x2D, 0x3F, 0x0B, 0x00, 0x00, 0x14, 0x08, 0x00, 0x03, 0x13, 0x00, -}; - -static const uint8_t huff_spec_a32_bits[] = { - 4, 5, 5, 6, 0, 6, 5, 5, 5, 6, 5, 6, 0, 6, 5, 5, - 5, 5, 6, 7, 0, 7, 6, 5, 6, 6, 7, 7, 0, 7, 7, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 7, 7, 0, 7, 7, 6, - 5, 5, 6, 7, 0, 7, 6, 5, 5, 5, 5, 6, 0, 6, 5, 6, -}; - -static const uint16_t huff_spec_a32_codes[] = { - 0x0D, 0x18, 0x16, 0x3A, 0x00, 0x3B, 0x17, 0x19, 0x12, 0x3E, 0x08, 0x1C, 0x00, 0x1B, 0x07, 0x01, - 0x10, 0x02, 0x28, 0x78, 0x00, 0x7B, 0x1F, 0x05, 0x2A, 0x16, 0x72, 0x2A, 0x00, 0x29, 0x71, 0x19, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x18, 0x70, 0x28, 0x00, 0x2B, 0x73, 0x17, - 0x11, 0x04, 0x1E, 0x7A, 0x00, 0x79, 0x29, 0x03, 0x13, 0x00, 0x06, 0x1A, 0x00, 0x1D, 0x09, 0x3F, -}; - -static const uint8_t huff_spec_a33_bits[] = { - 3, 4, 5, 6, 0, 6, 5, 4, 4, 5, 6, 7, 0, 7, 6, 5, - 5, 6, 6, 7, 0, 7, 6, 6, 6, 7, 8, 8, 0, 8, 8, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 8, 0, 8, 8, 7, - 5, 6, 6, 7, 0, 7, 6, 6, 4, 5, 6, 7, 0, 7, 6, 5, -}; - -static const uint16_t huff_spec_a33_codes[] = { - 0x05, 0x06, 0x10, 0x08, 0x00, 0x09, 0x11, 0x07, 0x04, 0x12, 0x3E, 0x6A, 0x00, 0x6D, 0x3D, 0x19, - 0x06, 0x3A, 0x06, 0x02, 0x00, 0x01, 0x05, 0x39, 0x02, 0x16, 0xDC, 0x2A, 0x00, 0x29, 0xDF, 0x69, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x68, 0xDE, 0x28, 0x00, 0x2B, 0xDD, 0x17, - 0x07, 0x38, 0x04, 0x00, 0x00, 0x03, 0x07, 0x3B, 0x05, 0x18, 0x3C, 0x6C, 0x00, 0x6B, 0x3F, 0x13, -}; - -static const uint8_t huff_spec_a34_bits[] = { - 2, 4, 5, 7, 0, 7, 5, 4, 4, 5, 6, 8, 0, 8, 6, 5, - 5, 6, 7, 8, 0, 8, 7, 6, 7, 8, 8, 10, 0, 10, 9, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 0, 10, 8, 8, - 5, 6, 7, 8, 0, 8, 7, 6, 4, 5, 6, 8, 0, 8, 6, 5, -}; - -static const uint16_t huff_spec_a34_codes[] = { - 0x000, 0x00A, 0x00A, 0x034, 0x000, 0x035, 0x00B, 0x00B, 0x008, 0x01C, 0x032, 0x0DA, - 0x000, 0x0DD, 0x035, 0x01F, 0x008, 0x01E, 0x03A, 0x06C, 0x000, 0x063, 0x039, 0x031, - 0x032, 0x06E, 0x060, 0x37A, 0x000, 0x379, 0x1BF, 0x0D9, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x033, 0x0D8, 0x1BE, 0x378, 0x000, 0x37B, 0x061, 0x06F, - 0x009, 0x030, 0x038, 0x062, 0x000, 0x06D, 0x03B, 0x01F, 0x009, 0x01E, 0x034, 0x0DC, - 0x000, 0x0DB, 0x033, 0x01D, -}; - -static const uint8_t huff_spec_a41_bits[] = { - 0, 0, 0, 0, 6, 6, 7, 7, 0, 7, 7, 6, 6, 0, 0, 0, - 0, 0, 0, 0, 7, 7, 7, 7, 0, 7, 7, 7, 6, 0, 0, 0, - 0, 0, 0, 0, 7, 7, 7, 8, 0, 8, 7, 7, 7, 0, 0, 0, - 0, 0, 0, 0, 7, 7, 8, 8, 0, 8, 8, 7, 7, 0, 0, 0, - 7, 7, 7, 8, 7, 8, 8, 8, 0, 8, 8, 8, 7, 8, 7, 7, - 7, 7, 7, 7, 8, 8, 8, 9, 0, 8, 8, 8, 8, 7, 7, 7, - 7, 7, 8, 8, 8, 8, 9, 9, 0, 9, 8, 8, 8, 8, 8, 7, - 8, 8, 8, 8, 8, 9, 9, 9, 0, 9, 9, 9, 8, 8, 8, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 8, 8, 8, 8, 9, 9, 9, 0, 9, 9, 9, 8, 8, 8, 8, - 7, 7, 8, 8, 8, 8, 8, 9, 0, 9, 9, 8, 8, 8, 8, 7, - 7, 7, 7, 7, 8, 8, 8, 8, 0, 9, 8, 8, 8, 7, 7, 7, - 7, 7, 7, 8, 7, 8, 8, 8, 0, 8, 8, 8, 7, 8, 7, 7, - 0, 0, 0, 0, 7, 7, 8, 8, 0, 8, 8, 7, 7, 0, 0, 0, - 0, 0, 0, 0, 7, 7, 7, 8, 0, 8, 7, 7, 7, 0, 0, 0, - 0, 0, 0, 0, 6, 7, 7, 7, 0, 7, 7, 7, 7, 0, 0, 0, -}; - -static const uint16_t huff_spec_a41_codes[] = { - 0x000, 0x000, 0x000, 0x000, 0x018, 0x00E, 0x05E, 0x028, 0x000, 0x029, 0x05F, 0x00F, - 0x019, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x076, 0x06E, 0x03E, 0x004, - 0x000, 0x017, 0x045, 0x07B, 0x013, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x04A, 0x048, 0x010, 0x0CE, 0x000, 0x0E1, 0x023, 0x055, 0x053, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x008, 0x018, 0x0D6, 0x09E, 0x000, 0x09D, 0x0E5, 0x02B, - 0x01B, 0x000, 0x000, 0x000, 0x07C, 0x05C, 0x038, 0x0FC, 0x002, 0x0D2, 0x09A, 0x05C, - 0x000, 0x06B, 0x0A3, 0x0D9, 0x00F, 0x0FF, 0x03D, 0x061, 0x074, 0x056, 0x036, 0x000, - 0x0CC, 0x08C, 0x058, 0x1E2, 0x000, 0x00F, 0x05F, 0x0A1, 0x0D5, 0x00D, 0x03B, 0x059, - 0x040, 0x014, 0x0DA, 0x0B6, 0x084, 0x040, 0x1E0, 0x196, 0x000, 0x1A1, 0x00D, 0x043, - 0x087, 0x0C7, 0x0E3, 0x00B, 0x0F2, 0x0C4, 0x08E, 0x05A, 0x024, 0x1CC, 0x194, 0x168, - 0x000, 0x16B, 0x1A3, 0x1CF, 0x027, 0x069, 0x099, 0x0C9, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x0F3, 0x0C8, 0x098, 0x068, 0x026, 0x1CE, 0x1A2, 0x16A, 0x000, 0x169, 0x195, 0x1CD, - 0x025, 0x05B, 0x08F, 0x0C5, 0x041, 0x00A, 0x0E2, 0x0C6, 0x086, 0x042, 0x00C, 0x1A0, - 0x000, 0x197, 0x1E1, 0x041, 0x085, 0x0B7, 0x0DB, 0x015, 0x075, 0x058, 0x03A, 0x00C, - 0x0D4, 0x0A0, 0x05E, 0x00E, 0x000, 0x1E3, 0x059, 0x08D, 0x0CD, 0x001, 0x037, 0x057, - 0x07D, 0x060, 0x03C, 0x0FE, 0x00E, 0x0D8, 0x0A2, 0x06A, 0x000, 0x05D, 0x09B, 0x0D3, - 0x003, 0x0FD, 0x039, 0x05D, 0x000, 0x000, 0x000, 0x000, 0x01A, 0x02A, 0x0E4, 0x09C, - 0x000, 0x09F, 0x0D7, 0x019, 0x009, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x052, 0x054, 0x022, 0x0E0, 0x000, 0x0CF, 0x011, 0x049, 0x04B, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x012, 0x07A, 0x044, 0x016, 0x000, 0x005, 0x03F, 0x06F, - 0x077, 0x000, 0x000, 0x000, -}; - -static const uint8_t huff_spec_a42_bits[] = { - 5, 6, 7, 7, 7, 7, 8, 8, 0, 8, 8, 7, 7, 7, 7, 6, - 6, 7, 7, 8, 7, 7, 8, 8, 0, 8, 8, 7, 7, 8, 7, 7, - 7, 7, 8, 8, 7, 8, 8, 9, 0, 9, 8, 8, 7, 8, 8, 7, - 8, 8, 8, 8, 8, 8, 8, 9, 0, 9, 8, 8, 8, 8, 8, 8, - 7, 7, 7, 8, 8, 8, 9, 9, 0, 9, 9, 8, 8, 8, 7, 7, - 7, 7, 8, 8, 8, 9, 9, 9, 0, 9, 9, 9, 8, 8, 8, 7, - 8, 8, 8, 8, 9, 9, 9, 10, 0, 10, 9, 9, 9, 8, 8, 8, - 8, 8, 9, 9, 9, 9, 10, 10, 0, 10, 10, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 9, 9, 9, 9, 9, 10, 10, 0, 10, 10, 9, 9, 9, 9, 8, - 8, 8, 8, 8, 9, 9, 9, 10, 0, 10, 9, 9, 9, 8, 8, 8, - 7, 7, 8, 8, 8, 9, 9, 9, 0, 9, 9, 9, 8, 8, 8, 7, - 7, 7, 7, 8, 8, 8, 9, 9, 0, 9, 9, 8, 8, 8, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 9, 0, 9, 8, 8, 8, 8, 8, 8, - 7, 7, 8, 8, 7, 8, 8, 9, 0, 9, 8, 8, 7, 8, 8, 7, - 6, 7, 7, 8, 7, 7, 8, 8, 0, 8, 8, 7, 7, 8, 7, 7, -}; - -static const uint16_t huff_spec_a42_codes[] = { - 0x003, 0x018, 0x058, 0x000, 0x066, 0x03C, 0x0D6, 0x07C, 0x000, 0x07D, 0x0D7, 0x03D, - 0x067, 0x001, 0x059, 0x019, 0x002, 0x064, 0x036, 0x0DA, 0x04C, 0x01C, 0x0BE, 0x02C, - 0x000, 0x037, 0x0C5, 0x029, 0x04B, 0x0E7, 0x03B, 0x069, 0x044, 0x02E, 0x0FA, 0x092, - 0x020, 0x0F8, 0x086, 0x1FC, 0x000, 0x1E7, 0x07F, 0x0F5, 0x023, 0x0AD, 0x0FD, 0x02D, - 0x0F6, 0x0DC, 0x09C, 0x03E, 0x0F0, 0x0B6, 0x026, 0x186, 0x000, 0x18D, 0x02F, 0x0B5, - 0x0E1, 0x03D, 0x0AF, 0x0D9, 0x054, 0x040, 0x014, 0x0EC, 0x0BC, 0x054, 0x1C6, 0x108, - 0x000, 0x10B, 0x1C5, 0x069, 0x0B9, 0x0DF, 0x019, 0x047, 0x026, 0x008, 0x0E4, 0x0A2, - 0x056, 0x1DC, 0x142, 0x06A, 0x000, 0x091, 0x123, 0x1DF, 0x04B, 0x0A7, 0x0EB, 0x00B, - 0x0C0, 0x09E, 0x06A, 0x022, 0x1AA, 0x140, 0x092, 0x3CA, 0x000, 0x3A7, 0x04B, 0x121, - 0x18F, 0x007, 0x071, 0x0A5, 0x020, 0x004, 0x1A8, 0x174, 0x0E4, 0x068, 0x3A4, 0x2EE, - 0x000, 0x2ED, 0x3C9, 0x049, 0x0E7, 0x185, 0x1D1, 0x1FF, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x021, 0x1FE, 0x1D0, 0x184, 0x0E6, 0x048, 0x3C8, 0x2EC, 0x000, 0x2EF, 0x3A5, 0x069, - 0x0E5, 0x175, 0x1A9, 0x005, 0x0C1, 0x0A4, 0x070, 0x006, 0x18E, 0x120, 0x04A, 0x3A6, - 0x000, 0x3CB, 0x093, 0x141, 0x1AB, 0x023, 0x06B, 0x09F, 0x027, 0x00A, 0x0EA, 0x0A6, - 0x04A, 0x1DE, 0x122, 0x090, 0x000, 0x06B, 0x143, 0x1DD, 0x057, 0x0A3, 0x0E5, 0x009, - 0x055, 0x046, 0x018, 0x0DE, 0x0B8, 0x068, 0x1C4, 0x10A, 0x000, 0x109, 0x1C7, 0x055, - 0x0BD, 0x0ED, 0x015, 0x041, 0x0F7, 0x0D8, 0x0AE, 0x03C, 0x0E0, 0x0B4, 0x02E, 0x18C, - 0x000, 0x187, 0x027, 0x0B7, 0x0F1, 0x03F, 0x09D, 0x0DD, 0x045, 0x02C, 0x0FC, 0x0AC, - 0x022, 0x0F4, 0x07E, 0x1E6, 0x000, 0x1FD, 0x087, 0x0F9, 0x021, 0x093, 0x0FB, 0x02F, - 0x003, 0x068, 0x03A, 0x0E6, 0x04A, 0x028, 0x0C4, 0x036, 0x000, 0x02D, 0x0BF, 0x01D, - 0x04D, 0x0DB, 0x037, 0x065, -}; - -static const uint8_t huff_spec_a43_bits[] = { - 4, 6, 6, 7, 7, 8, 8, 9, 0, 9, 8, 8, 7, 7, 6, 6, - 5, 6, 7, 7, 7, 8, 8, 9, 0, 9, 8, 8, 7, 7, 7, 6, - 6, 7, 7, 7, 8, 8, 9, 9, 0, 9, 9, 8, 8, 7, 7, 7, - 7, 7, 7, 8, 8, 8, 9, 10, 0, 10, 9, 9, 8, 8, 7, 7, - 7, 7, 8, 8, 8, 9, 10, 10, 0, 10, 10, 9, 8, 8, 8, 7, - 8, 8, 8, 9, 9, 9, 10, 10, 0, 10, 10, 9, 9, 9, 8, 8, - 8, 9, 9, 9, 10, 10, 10, 10, 0, 10, 10, 10, 10, 9, 9, 9, - 9, 9, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 9, - 8, 9, 9, 9, 10, 10, 10, 10, 0, 10, 10, 10, 10, 9, 9, 9, - 8, 8, 8, 9, 9, 9, 10, 10, 0, 10, 10, 9, 9, 9, 8, 8, - 7, 7, 8, 8, 8, 9, 10, 10, 0, 10, 10, 9, 8, 8, 8, 7, - 7, 7, 7, 8, 8, 9, 9, 10, 0, 10, 9, 8, 8, 8, 7, 7, - 6, 7, 7, 7, 8, 8, 9, 9, 0, 9, 9, 8, 8, 7, 7, 7, - 5, 6, 7, 7, 7, 8, 8, 9, 0, 9, 8, 8, 7, 7, 7, 6, -}; - -static const uint16_t huff_spec_a43_codes[] = { - 0x002, 0x03E, 0x016, 0x060, 0x04E, 0x0DC, 0x04A, 0x130, 0x000, 0x131, 0x04B, 0x0DD, - 0x04F, 0x061, 0x017, 0x03F, 0x002, 0x02C, 0x076, 0x042, 0x034, 0x0CE, 0x002, 0x0E8, - 0x000, 0x0CF, 0x001, 0x0D1, 0x037, 0x045, 0x07B, 0x02F, 0x014, 0x072, 0x052, 0x01A, - 0x0E0, 0x080, 0x198, 0x01E, 0x000, 0x01D, 0x19B, 0x083, 0x0DF, 0x019, 0x055, 0x079, - 0x050, 0x03C, 0x004, 0x0C4, 0x096, 0x00C, 0x0EA, 0x34A, 0x000, 0x34F, 0x0ED, 0x1D7, - 0x095, 0x0AF, 0x003, 0x03F, 0x046, 0x026, 0x0D6, 0x092, 0x046, 0x15A, 0x3A8, 0x108, - 0x000, 0x10F, 0x3A3, 0x135, 0x039, 0x091, 0x0D9, 0x031, 0x0D4, 0x0CA, 0x072, 0x1C6, - 0x136, 0x090, 0x2B2, 0x104, 0x000, 0x103, 0x111, 0x08B, 0x133, 0x1D3, 0x071, 0x0C9, - 0x03E, 0x1B4, 0x18C, 0x0CC, 0x38A, 0x2B0, 0x106, 0x0F2, 0x000, 0x0EF, 0x101, 0x113, - 0x3A1, 0x0CB, 0x18F, 0x1B7, 0x0EE, 0x092, 0x388, 0x348, 0x10A, 0x0F4, 0x0F0, 0x0EA, - 0x000, 0x0E9, 0x0ED, 0x0F7, 0x10D, 0x34D, 0x3AB, 0x0C9, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x0EF, 0x0C8, 0x3AA, 0x34C, 0x10C, 0x0F6, 0x0EC, 0x0E8, 0x000, 0x0EB, 0x0F1, 0x0F5, - 0x10B, 0x349, 0x389, 0x093, 0x03F, 0x1B6, 0x18E, 0x0CA, 0x3A0, 0x112, 0x100, 0x0EE, - 0x000, 0x0F3, 0x107, 0x2B1, 0x38B, 0x0CD, 0x18D, 0x1B5, 0x0D5, 0x0C8, 0x070, 0x1D2, - 0x132, 0x08A, 0x110, 0x102, 0x000, 0x105, 0x2B3, 0x091, 0x137, 0x1C7, 0x073, 0x0CB, - 0x047, 0x030, 0x0D8, 0x090, 0x038, 0x134, 0x3A2, 0x10E, 0x000, 0x109, 0x3A9, 0x15B, - 0x047, 0x093, 0x0D7, 0x027, 0x051, 0x03E, 0x002, 0x0AE, 0x094, 0x1D6, 0x0EC, 0x34E, - 0x000, 0x34B, 0x0EB, 0x00D, 0x097, 0x0C5, 0x005, 0x03D, 0x015, 0x078, 0x054, 0x018, - 0x0DE, 0x082, 0x19A, 0x01C, 0x000, 0x01F, 0x199, 0x081, 0x0E1, 0x01B, 0x053, 0x073, - 0x003, 0x02E, 0x07A, 0x044, 0x036, 0x0D0, 0x000, 0x0CE, 0x000, 0x0E9, 0x003, 0x0CF, - 0x035, 0x043, 0x077, 0x02D, -}; - -static const uint8_t huff_spec_a44_bits[] = { - 4, 5, 6, 7, 7, 8, 9, 10, 0, 10, 9, 8, 7, 7, 6, 5, - 5, 6, 6, 7, 7, 8, 9, 10, 0, 10, 9, 8, 7, 7, 6, 6, - 6, 6, 7, 7, 8, 9, 10, 10, 0, 10, 10, 9, 8, 7, 7, 6, - 7, 7, 7, 8, 8, 9, 10, 10, 0, 10, 10, 9, 8, 8, 7, 7, - 7, 8, 8, 8, 9, 10, 10, 10, 0, 10, 10, 10, 9, 8, 8, 7, - 8, 8, 9, 9, 10, 10, 10, 10, 0, 10, 10, 10, 10, 9, 9, 8, - 9, 9, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 9, 9, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 9, - 8, 8, 9, 9, 10, 10, 10, 10, 0, 10, 10, 10, 10, 9, 9, 8, - 7, 7, 8, 8, 9, 10, 10, 10, 0, 10, 10, 10, 9, 8, 8, 8, - 7, 7, 7, 8, 8, 9, 10, 10, 0, 10, 10, 9, 8, 8, 7, 7, - 6, 6, 7, 7, 8, 9, 10, 10, 0, 10, 10, 9, 8, 7, 7, 6, - 5, 6, 6, 7, 7, 8, 9, 10, 0, 10, 9, 8, 7, 7, 6, 6, -}; - -static const uint16_t huff_spec_a44_codes[] = { - 0x00A, 0x012, 0x030, 0x06E, 0x024, 0x074, 0x0EC, 0x07E, 0x000, 0x07F, 0x0ED, 0x075, - 0x025, 0x06F, 0x031, 0x013, 0x010, 0x03C, 0x018, 0x05A, 0x002, 0x046, 0x09E, 0x07C, - 0x000, 0x079, 0x0E5, 0x04D, 0x007, 0x065, 0x01B, 0x03F, 0x02E, 0x016, 0x072, 0x01A, - 0x0D6, 0x1C6, 0x3B4, 0x066, 0x000, 0x06B, 0x3B7, 0x1D9, 0x0D5, 0x021, 0x075, 0x015, - 0x06C, 0x03E, 0x01E, 0x0CC, 0x044, 0x0F2, 0x082, 0x05C, 0x000, 0x05F, 0x087, 0x0F5, - 0x031, 0x0CF, 0x017, 0x059, 0x01C, 0x0EE, 0x0D0, 0x024, 0x1C0, 0x08E, 0x06E, 0x048, - 0x000, 0x04D, 0x06D, 0x089, 0x0F7, 0x033, 0x0D3, 0x001, 0x070, 0x028, 0x1C2, 0x0F0, - 0x08A, 0x074, 0x054, 0x040, 0x000, 0x043, 0x053, 0x073, 0x099, 0x0EF, 0x1C5, 0x02B, - 0x0E6, 0x04E, 0x08C, 0x080, 0x068, 0x058, 0x046, 0x02A, 0x000, 0x029, 0x045, 0x051, - 0x065, 0x085, 0x09B, 0x09D, 0x07A, 0x076, 0x060, 0x056, 0x04E, 0x02C, 0x024, 0x022, - 0x000, 0x021, 0x027, 0x02F, 0x04B, 0x05B, 0x063, 0x071, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x07B, 0x070, 0x062, 0x05A, 0x04A, 0x02E, 0x026, 0x020, 0x000, 0x023, 0x025, 0x02D, - 0x04F, 0x057, 0x061, 0x077, 0x0E7, 0x09C, 0x09A, 0x084, 0x064, 0x050, 0x044, 0x028, - 0x000, 0x02B, 0x047, 0x059, 0x069, 0x081, 0x08D, 0x04F, 0x071, 0x02A, 0x1C4, 0x0EE, - 0x098, 0x072, 0x052, 0x042, 0x000, 0x041, 0x055, 0x075, 0x08B, 0x0F1, 0x1C3, 0x029, - 0x01D, 0x000, 0x0D2, 0x032, 0x0F6, 0x088, 0x06C, 0x04C, 0x000, 0x049, 0x06F, 0x08F, - 0x1C1, 0x025, 0x0D1, 0x0EF, 0x06D, 0x058, 0x016, 0x0CE, 0x030, 0x0F4, 0x086, 0x05E, - 0x000, 0x05D, 0x083, 0x0F3, 0x045, 0x0CD, 0x01F, 0x03F, 0x02F, 0x014, 0x074, 0x020, - 0x0D4, 0x1D8, 0x3B6, 0x06A, 0x000, 0x067, 0x3B5, 0x1C7, 0x0D7, 0x01B, 0x073, 0x017, - 0x011, 0x03E, 0x01A, 0x064, 0x006, 0x04C, 0x0E4, 0x078, 0x000, 0x07D, 0x09F, 0x047, - 0x003, 0x05B, 0x019, 0x03D, -}; - -static const uint8_t huff_spec_a51_bits[] = { - 5, 5, 5, 5, 5, 6, 6, 6, 4, 4, 5, 5, 5, 5, 5, 5, - 0, 5, 5, 5, 5, 5, 5, 4, 4, 6, 6, 6, 5, 5, 5, 5, -}; - -static const uint16_t huff_spec_a51_codes[] = { - 0x19, 0x16, 0x12, 0x0E, 0x06, 0x3A, 0x38, 0x30, 0x00, 0x04, 0x1E, 0x1A, - 0x14, 0x10, 0x0C, 0x04, 0x00, 0x05, 0x0D, 0x11, 0x15, 0x1B, 0x1F, 0x05, - 0x01, 0x31, 0x39, 0x3B, 0x07, 0x0F, 0x13, 0x17, -}; - -static const uint8_t huff_spec_a52_bits[] = { - 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, - 0, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, -}; - -static const uint16_t huff_spec_a52_codes[] = { - 0x09, 0x04, 0x00, 0x1E, 0x1A, 0x14, 0x0C, 0x06, 0x18, 0x16, 0x0E, 0x04, - 0x3A, 0x38, 0x22, 0x20, 0x00, 0x21, 0x23, 0x39, 0x3B, 0x05, 0x0F, 0x17, - 0x19, 0x07, 0x0D, 0x15, 0x1B, 0x1F, 0x01, 0x05, -}; - -static const uint8_t huff_spec_a53_bits[] = { - 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 7, 7, 7, 7, - 0, 7, 7, 7, 7, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, -}; - -static const uint16_t huff_spec_a53_codes[] = { - 0x00, 0x0C, 0x08, 0x04, 0x1E, 0x16, 0x14, 0x06, 0x0C, 0x04, 0x38, 0x1E, - 0x76, 0x74, 0x3A, 0x38, 0x00, 0x39, 0x3B, 0x75, 0x77, 0x1F, 0x39, 0x05, - 0x0D, 0x07, 0x15, 0x17, 0x1F, 0x05, 0x09, 0x0D, -}; - -static const uint8_t huff_spec_a54_bits[] = { - 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, - 0, 8, 8, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, -}; - -static const uint16_t huff_spec_a54_codes[] = { - 0x02, 0x0E, 0x0A, 0x08, 0x02, 0x1A, 0x0E, 0x02, 0x00, 0x30, 0x18, 0x66, - 0x36, 0x34, 0xCA, 0xC8, 0x00, 0xC9, 0xCB, 0x35, 0x37, 0x67, 0x19, 0x31, - 0x01, 0x03, 0x0F, 0x1B, 0x03, 0x09, 0x0B, 0x0F, -}; - -static const uint8_t huff_spec_a61_bits[] = { - 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, - 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, - 5, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, -}; - -static const uint16_t huff_spec_a61_codes[] = { - 0x35, 0x30, 0x2A, 0x28, 0x24, 0x20, 0x18, 0x0E, 0x0C, 0x7E, 0x7C, 0x72, - 0x70, 0x68, 0x5E, 0x5C, 0x04, 0x0E, 0x08, 0x00, 0x3C, 0x3A, 0x36, 0x32, - 0x2C, 0x26, 0x22, 0x1A, 0x16, 0x14, 0x06, 0x04, 0x00, 0x05, 0x07, 0x15, - 0x17, 0x1B, 0x23, 0x27, 0x2D, 0x33, 0x37, 0x3B, 0x3D, 0x01, 0x09, 0x0F, - 0x05, 0x5D, 0x5F, 0x69, 0x71, 0x73, 0x7D, 0x7F, 0x0D, 0x0F, 0x19, 0x21, - 0x25, 0x29, 0x2B, 0x31, -}; - -static const uint8_t huff_spec_a62_bits[] = { - 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, - 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, -}; - -static const uint16_t huff_spec_a62_codes[] = { - 0x14, 0x0E, 0x08, 0x04, 0x02, 0x3E, 0x3C, 0x38, 0x34, 0x30, 0x2A, 0x24, - 0x1A, 0x18, 0x0E, 0x02, 0x32, 0x36, 0x2C, 0x26, 0x20, 0x16, 0x0C, 0x00, - 0x76, 0x74, 0x5E, 0x5C, 0x46, 0x44, 0x2A, 0x28, 0x00, 0x29, 0x2B, 0x45, - 0x47, 0x5D, 0x5F, 0x75, 0x77, 0x01, 0x0D, 0x17, 0x21, 0x27, 0x2D, 0x37, - 0x33, 0x03, 0x0F, 0x19, 0x1B, 0x25, 0x2B, 0x31, 0x35, 0x39, 0x3D, 0x3F, - 0x03, 0x05, 0x09, 0x0F, -}; - -static const uint8_t huff_spec_a63_bits[] = { - 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, - 0, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, -}; - -static const uint16_t huff_spec_a63_codes[] = { - 0x00, 0x1C, 0x18, 0x14, 0x10, 0x0A, 0x08, 0x02, 0x3E, 0x36, 0x2E, 0x2C, - 0x24, 0x1C, 0x0E, 0x08, 0x1E, 0x1A, 0x0C, 0x7A, 0x6A, 0x68, 0x4C, 0x32, - 0x16, 0x14, 0xF2, 0xF0, 0x9E, 0x9C, 0x62, 0x60, 0x00, 0x61, 0x63, 0x9D, - 0x9F, 0xF1, 0xF3, 0x15, 0x17, 0x33, 0x4D, 0x69, 0x6B, 0x7B, 0x0D, 0x1B, - 0x1F, 0x09, 0x0F, 0x1D, 0x25, 0x2D, 0x2F, 0x37, 0x3F, 0x03, 0x09, 0x0B, - 0x11, 0x15, 0x19, 0x1D, -}; - -static const uint8_t huff_spec_a64_bits[] = { - 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, - 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, - 6, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, -}; - -static const uint16_t huff_spec_a64_codes[] = { - 0x006, 0x002, 0x01C, 0x01A, 0x016, 0x012, 0x00E, 0x00A, 0x002, 0x03E, - 0x032, 0x02A, 0x022, 0x020, 0x010, 0x07A, 0x000, 0x078, 0x060, 0x050, - 0x024, 0x006, 0x0C6, 0x0C4, 0x0A4, 0x04E, 0x00A, 0x008, 0x14E, 0x14C, - 0x09A, 0x098, 0x000, 0x099, 0x09B, 0x14D, 0x14F, 0x009, 0x00B, 0x04F, - 0x0A5, 0x0C5, 0x0C7, 0x007, 0x025, 0x051, 0x061, 0x079, 0x001, 0x07B, - 0x011, 0x021, 0x023, 0x02B, 0x033, 0x03F, 0x003, 0x00B, 0x00F, 0x013, - 0x017, 0x01B, 0x01D, 0x003, -}; - -static const uint8_t huff_spec_a71_bits[] = { - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, - 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -}; - -static const uint16_t huff_spec_a71_codes[] = { - 0x6C, 0x66, 0x62, 0x5C, 0x56, 0x50, 0x52, 0x4E, 0x48, 0x3E, 0x36, 0x34, 0x2A, 0x26, 0x1E, 0x16, - 0x0E, 0x08, 0x00, 0xF6, 0xF4, 0xEE, 0xEC, 0xE2, 0xE0, 0xDA, 0xD2, 0xD0, 0xBE, 0xBC, 0xB2, 0xB0, - 0x0C, 0x20, 0x1C, 0x16, 0x10, 0x08, 0x02, 0x7E, 0x7C, 0x78, 0x74, 0x72, 0x6E, 0x6A, 0x64, 0x60, - 0x5A, 0x54, 0x4C, 0x4A, 0x46, 0x44, 0x3C, 0x32, 0x30, 0x28, 0x24, 0x1C, 0x14, 0x0C, 0x0A, 0x02, - 0x00, 0x03, 0x0B, 0x0D, 0x15, 0x1D, 0x25, 0x29, 0x31, 0x33, 0x3D, 0x45, 0x47, 0x4B, 0x4D, 0x55, - 0x5B, 0x61, 0x65, 0x6B, 0x6F, 0x73, 0x75, 0x79, 0x7D, 0x7F, 0x03, 0x09, 0x11, 0x17, 0x1D, 0x21, - 0x0D, 0xB1, 0xB3, 0xBD, 0xBF, 0xD1, 0xD3, 0xDB, 0xE1, 0xE3, 0xED, 0xEF, 0xF5, 0xF7, 0x01, 0x09, - 0x0F, 0x17, 0x1F, 0x27, 0x2B, 0x35, 0x37, 0x3F, 0x49, 0x4F, 0x53, 0x51, 0x57, 0x5D, 0x63, 0x67, -}; - -static const uint8_t huff_spec_a72_bits[] = { - 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, -}; - -static const uint16_t huff_spec_a72_codes[] = { - 0x2A, 0x24, 0x1C, 0x18, 0x12, 0x0E, 0x0A, 0x06, 0x02, 0x7E, 0x7C, 0x7A, 0x76, 0x72, 0x70, 0x6A, - 0x68, 0x62, 0x5C, 0x5A, 0x52, 0x4E, 0x46, 0x42, 0x3C, 0x34, 0x2A, 0x28, 0x20, 0x12, 0x10, 0x08, - 0x66, 0x74, 0x6C, 0x64, 0x5E, 0x58, 0x50, 0x44, 0x40, 0x36, 0x2C, 0x22, 0x1A, 0x0A, 0x02, 0x00, - 0xF2, 0xF0, 0xDE, 0xDC, 0xC2, 0xC0, 0xAE, 0xAC, 0x9A, 0x98, 0x7E, 0x7C, 0x5E, 0x5C, 0x32, 0x30, - 0x00, 0x31, 0x33, 0x5D, 0x5F, 0x7D, 0x7F, 0x99, 0x9B, 0xAD, 0xAF, 0xC1, 0xC3, 0xDD, 0xDF, 0xF1, - 0xF3, 0x01, 0x03, 0x0B, 0x1B, 0x23, 0x2D, 0x37, 0x41, 0x45, 0x51, 0x59, 0x5F, 0x65, 0x6D, 0x75, - 0x67, 0x09, 0x11, 0x13, 0x21, 0x29, 0x2B, 0x35, 0x3D, 0x43, 0x47, 0x4F, 0x53, 0x5B, 0x5D, 0x63, - 0x69, 0x6B, 0x71, 0x73, 0x77, 0x7B, 0x7D, 0x7F, 0x03, 0x07, 0x0B, 0x0F, 0x13, 0x19, 0x1D, 0x25, -}; - -static const uint8_t huff_spec_a73_bits[] = { - 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 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, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -}; - -static const uint16_t huff_spec_a73_codes[] = { - 0x003, 0x03E, 0x038, 0x034, 0x030, 0x02C, 0x028, 0x024, 0x020, 0x01C, 0x016, 0x014, - 0x00E, 0x00A, 0x004, 0x000, 0x07A, 0x076, 0x06E, 0x06C, 0x064, 0x05E, 0x056, 0x04E, - 0x04C, 0x044, 0x036, 0x030, 0x022, 0x018, 0x012, 0x004, 0x03C, 0x03E, 0x032, 0x024, - 0x020, 0x010, 0x0F2, 0x0F0, 0x0E8, 0x0CE, 0x0BA, 0x0B8, 0x0A8, 0x08C, 0x06A, 0x04E, - 0x04C, 0x034, 0x00E, 0x00C, 0x1D6, 0x1D4, 0x19A, 0x198, 0x156, 0x154, 0x11E, 0x11C, - 0x0D2, 0x0D0, 0x06E, 0x06C, 0x000, 0x06D, 0x06F, 0x0D1, 0x0D3, 0x11D, 0x11F, 0x155, - 0x157, 0x199, 0x19B, 0x1D5, 0x1D7, 0x00D, 0x00F, 0x035, 0x04D, 0x04F, 0x06B, 0x08D, - 0x0A9, 0x0B9, 0x0BB, 0x0CF, 0x0E9, 0x0F1, 0x0F3, 0x011, 0x021, 0x025, 0x033, 0x03F, - 0x03D, 0x005, 0x013, 0x019, 0x023, 0x031, 0x037, 0x045, 0x04D, 0x04F, 0x057, 0x05F, - 0x065, 0x06D, 0x06F, 0x077, 0x07B, 0x001, 0x005, 0x00B, 0x00F, 0x015, 0x017, 0x01D, - 0x021, 0x025, 0x029, 0x02D, 0x031, 0x035, 0x039, 0x03F, -}; - -static const uint8_t huff_spec_a74_bits[] = { - 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 7, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, -}; - -static const uint16_t huff_spec_a74_codes[] = { - 0x00D, 0x00A, 0x004, 0x000, 0x03A, 0x036, 0x032, 0x030, 0x02C, 0x028, 0x026, 0x022, - 0x01E, 0x018, 0x012, 0x00E, 0x006, 0x07E, 0x07A, 0x070, 0x06A, 0x05E, 0x056, 0x054, - 0x048, 0x040, 0x038, 0x022, 0x01A, 0x00A, 0x0F8, 0x0E6, 0x008, 0x0FA, 0x0F0, 0x0D2, - 0x0BA, 0x0B8, 0x094, 0x084, 0x074, 0x042, 0x032, 0x1E6, 0x1CA, 0x1C8, 0x1A2, 0x12E, - 0x10E, 0x10C, 0x0EC, 0x082, 0x062, 0x060, 0x3CA, 0x3C8, 0x342, 0x340, 0x25A, 0x258, - 0x1DE, 0x1DC, 0x102, 0x100, 0x000, 0x101, 0x103, 0x1DD, 0x1DF, 0x259, 0x25B, 0x341, - 0x343, 0x3C9, 0x3CB, 0x061, 0x063, 0x083, 0x0ED, 0x10D, 0x10F, 0x12F, 0x1A3, 0x1C9, - 0x1CB, 0x1E7, 0x033, 0x043, 0x075, 0x085, 0x095, 0x0B9, 0x0BB, 0x0D3, 0x0F1, 0x0FB, - 0x009, 0x0E7, 0x0F9, 0x00B, 0x01B, 0x023, 0x039, 0x041, 0x049, 0x055, 0x057, 0x05F, - 0x06B, 0x071, 0x07B, 0x07F, 0x007, 0x00F, 0x013, 0x019, 0x01F, 0x023, 0x027, 0x029, - 0x02D, 0x031, 0x033, 0x037, 0x03B, 0x001, 0x005, 0x00B, -}; - -static const uint8_t huff_spec_b22_bits[] = { - 0, 4, 0, 4, 4, 5, 0, 5, 0, 0, 0, 0, 4, 5, 0, 5, - 4, 7, 0, 6, 6, 9, 0, 7, 0, 0, 0, 0, 6, 9, 0, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 6, 0, 7, 6, 7, 0, 9, 0, 0, 0, 0, 6, 7, 0, 9, - 4, 8, 0, 8, 8, 10, 0, 10, 0, 0, 0, 0, 6, 9, 0, 9, - 5, 10, 0, 9, 9, 10, 0, 10, 0, 0, 0, 0, 7, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 9, 0, 10, 9, 10, 0, 10, 0, 0, 0, 0, 7, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 8, 0, 8, 6, 9, 0, 9, 0, 0, 0, 0, 8, 10, 0, 10, - 6, 10, 0, 9, 7, 10, 0, 10, 0, 0, 0, 0, 9, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 9, 0, 10, 7, 10, 0, 10, 0, 0, 0, 0, 9, 10, 0, 10, -}; - -static const uint16_t huff_spec_b22_codes[] = { - 0x000, 0x00E, 0x000, 0x00F, 0x008, 0x006, 0x000, 0x00B, 0x000, 0x000, 0x000, 0x000, - 0x009, 0x00A, 0x000, 0x007, 0x006, 0x00A, 0x000, 0x029, 0x006, 0x158, 0x000, 0x023, - 0x000, 0x000, 0x000, 0x000, 0x013, 0x174, 0x000, 0x021, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x007, 0x028, 0x000, 0x00B, 0x012, 0x020, 0x000, 0x175, 0x000, 0x000, 0x000, 0x000, - 0x007, 0x022, 0x000, 0x159, 0x00C, 0x0BC, 0x000, 0x0BF, 0x022, 0x2B8, 0x000, 0x2BB, - 0x000, 0x000, 0x000, 0x000, 0x00B, 0x170, 0x000, 0x15B, 0x000, 0x04E, 0x000, 0x15F, - 0x042, 0x04A, 0x000, 0x041, 0x000, 0x000, 0x000, 0x000, 0x055, 0x044, 0x000, 0x04D, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x02D, 0x172, 0x000, 0x2ED, 0x040, 0x042, 0x000, 0x047, - 0x000, 0x000, 0x000, 0x000, 0x013, 0x2EE, 0x000, 0x049, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x00D, 0x0BE, 0x000, 0x0BD, 0x00A, 0x15A, 0x000, 0x171, 0x000, 0x000, 0x000, 0x000, - 0x023, 0x2BA, 0x000, 0x2B9, 0x02C, 0x2EC, 0x000, 0x173, 0x012, 0x048, 0x000, 0x2EF, - 0x000, 0x000, 0x000, 0x000, 0x041, 0x046, 0x000, 0x043, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x001, 0x15E, 0x000, 0x04F, 0x054, 0x04C, 0x000, 0x045, 0x000, 0x000, 0x000, 0x000, - 0x043, 0x040, 0x000, 0x04B, -}; - -static const uint8_t huff_spec_b23_bits[] = { - 2, 4, 0, 4, 4, 6, 0, 6, 0, 0, 0, 0, 4, 6, 0, 6, - 4, 9, 0, 7, 7, 9, 0, 8, 0, 0, 0, 0, 7, 9, 0, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 7, 0, 9, 7, 8, 0, 9, 0, 0, 0, 0, 7, 8, 0, 9, - 4, 8, 0, 8, 9, 10, 0, 10, 0, 0, 0, 0, 7, 10, 0, 10, - 7, 10, 0, 10, 10, 10, 0, 10, 0, 0, 0, 0, 9, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 10, 0, 10, 10, 10, 0, 10, 0, 0, 0, 0, 8, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 8, 0, 8, 7, 10, 0, 10, 0, 0, 0, 0, 9, 10, 0, 10, - 7, 10, 0, 10, 8, 10, 0, 10, 0, 0, 0, 0, 10, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 10, 0, 10, 9, 10, 0, 10, 0, 0, 0, 0, 10, 10, 0, 10, -}; - -static const uint16_t huff_spec_b23_codes[] = { - 0x003, 0x008, 0x000, 0x009, 0x002, 0x018, 0x000, 0x01B, 0x000, 0x000, 0x000, 0x000, - 0x003, 0x01A, 0x000, 0x019, 0x000, 0x17C, 0x000, 0x055, 0x056, 0x0E8, 0x000, 0x07D, - 0x000, 0x000, 0x000, 0x000, 0x059, 0x0F6, 0x000, 0x07F, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x001, 0x054, 0x000, 0x17D, 0x058, 0x07E, 0x000, 0x0F7, 0x000, 0x000, 0x000, 0x000, - 0x057, 0x07C, 0x000, 0x0E9, 0x004, 0x0A2, 0x000, 0x0A1, 0x17A, 0x1DA, 0x000, 0x1D9, - 0x000, 0x000, 0x000, 0x000, 0x053, 0x1E8, 0x000, 0x2F3, 0x05C, 0x1D6, 0x000, 0x1E7, - 0x1EA, 0x1E2, 0x000, 0x1CF, 0x000, 0x000, 0x000, 0x000, 0x17F, 0x1CA, 0x000, 0x1DD, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x05B, 0x2F0, 0x000, 0x1DF, 0x1E4, 0x1CC, 0x000, 0x1D5, - 0x000, 0x000, 0x000, 0x000, 0x071, 0x1E0, 0x000, 0x1C9, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x005, 0x0A0, 0x000, 0x0A3, 0x052, 0x2F2, 0x000, 0x1E9, 0x000, 0x000, 0x000, 0x000, - 0x17B, 0x1D8, 0x000, 0x1DB, 0x05A, 0x1DE, 0x000, 0x2F1, 0x070, 0x1C8, 0x000, 0x1E1, - 0x000, 0x000, 0x000, 0x000, 0x1E5, 0x1D4, 0x000, 0x1CD, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x05D, 0x1E6, 0x000, 0x1D7, 0x17E, 0x1DC, 0x000, 0x1CB, 0x000, 0x000, 0x000, 0x000, - 0x1EB, 0x1CE, 0x000, 0x1E3, -}; - -static const uint8_t huff_spec_b24_bits[] = { - 1, 4, 0, 4, 5, 7, 0, 7, 0, 0, 0, 0, 5, 7, 0, 7, - 5, 9, 0, 7, 8, 10, 0, 9, 0, 0, 0, 0, 7, 10, 0, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 7, 0, 9, 7, 9, 0, 10, 0, 0, 0, 0, 8, 9, 0, 10, - 5, 9, 0, 8, 9, 10, 0, 10, 0, 0, 0, 0, 7, 10, 0, 10, - 7, 10, 0, 10, 10, 10, 0, 10, 0, 0, 0, 0, 10, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 10, 0, 10, 10, 10, 0, 10, 0, 0, 0, 0, 10, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 8, 0, 9, 7, 10, 0, 10, 0, 0, 0, 0, 9, 10, 0, 10, - 7, 10, 0, 10, 10, 10, 0, 10, 0, 0, 0, 0, 10, 10, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 10, 0, 10, 10, 10, 0, 10, 0, 0, 0, 0, 10, 10, 0, 10, -}; - -static const uint16_t huff_spec_b24_codes[] = { - 0x001, 0x000, 0x000, 0x001, 0x00A, 0x01C, 0x000, 0x033, 0x000, 0x000, 0x000, 0x000, - 0x00B, 0x032, 0x000, 0x01D, 0x008, 0x0D8, 0x000, 0x031, 0x06E, 0x0FA, 0x000, 0x0D7, - 0x000, 0x000, 0x000, 0x000, 0x011, 0x0F4, 0x000, 0x0D5, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x009, 0x030, 0x000, 0x0D9, 0x010, 0x0D4, 0x000, 0x0F5, 0x000, 0x000, 0x000, 0x000, - 0x06F, 0x0D6, 0x000, 0x0FB, 0x00E, 0x0DA, 0x000, 0x025, 0x0D2, 0x0D4, 0x000, 0x0DB, - 0x000, 0x000, 0x000, 0x000, 0x017, 0x0FE, 0x000, 0x0FD, 0x014, 0x0DC, 0x000, 0x0F9, - 0x0F2, 0x0D6, 0x000, 0x09B, 0x000, 0x000, 0x000, 0x000, 0x1A3, 0x09C, 0x000, 0x0D3, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x019, 0x0F6, 0x000, 0x0D9, 0x0F0, 0x09E, 0x000, 0x0D1, - 0x000, 0x000, 0x000, 0x000, 0x1A1, 0x0DE, 0x000, 0x099, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x00F, 0x024, 0x000, 0x0DB, 0x016, 0x0FC, 0x000, 0x0FF, 0x000, 0x000, 0x000, 0x000, - 0x0D3, 0x0DA, 0x000, 0x0D5, 0x018, 0x0D8, 0x000, 0x0F7, 0x1A0, 0x098, 0x000, 0x0DF, - 0x000, 0x000, 0x000, 0x000, 0x0F1, 0x0D0, 0x000, 0x09F, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x015, 0x0F8, 0x000, 0x0DD, 0x1A2, 0x0D2, 0x000, 0x09D, 0x000, 0x000, 0x000, 0x000, - 0x0F3, 0x09A, 0x000, 0x0D7 -}; - -static const uint8_t huff_spec_b32_bits[] = { - 2, 4, 5, 6, 0, 6, 5, 4, 5, 6, 6, 7, 0, 6, 5, 6, - 5, 6, 7, 7, 0, 8, 7, 6, 6, 7, 8, 9, 0, 9, 8, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 0, 9, 8, 7, - 5, 6, 7, 8, 0, 7, 7, 6, 5, 6, 5, 6, 0, 7, 6, 6, -}; - -static const uint16_t huff_spec_b32_codes[] = { - 0x001, 0x002, 0x01E, 0x02A, 0x000, 0x02B, 0x01F, 0x003, 0x016, 0x020, 0x03A, 0x064, - 0x000, 0x005, 0x001, 0x023, 0x01A, 0x026, 0x070, 0x00C, 0x000, 0x0CF, 0x073, 0x031, - 0x024, 0x00E, 0x0CC, 0x146, 0x000, 0x145, 0x0A1, 0x053, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x025, 0x052, 0x0A0, 0x144, 0x000, 0x147, 0x0CD, 0x00F, - 0x01B, 0x030, 0x072, 0x0CE, 0x000, 0x00D, 0x071, 0x027, 0x017, 0x022, 0x000, 0x004, - 0x000, 0x065, 0x03B, 0x021, -}; - -static const uint8_t huff_spec_b33_bits[] = { - 2, 4, 5, 7, 0, 7, 5, 4, 4, 5, 6, 8, 0, 7, 6, 5, - 5, 6, 7, 9, 0, 8, 7, 6, 7, 8, 9, 10, 0, 10, 9, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 0, 10, 9, 8, - 5, 6, 7, 8, 0, 9, 7, 6, 4, 5, 6, 7, 0, 8, 6, 5, -}; - -static const uint16_t huff_spec_b33_codes[] = { - 0x003, 0x008, 0x014, 0x05E, 0x000, 0x05F, 0x015, 0x009, 0x004, 0x002, 0x01C, 0x0BA, - 0x000, 0x011, 0x01F, 0x001, 0x00C, 0x00C, 0x014, 0x166, 0x000, 0x02D, 0x013, 0x00F, - 0x05A, 0x0B0, 0x05E, 0x0B8, 0x000, 0x0BB, 0x165, 0x0B9, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x05B, 0x0B8, 0x164, 0x0BA, 0x000, 0x0B9, 0x05F, 0x0B1, - 0x00D, 0x00E, 0x012, 0x02C, 0x000, 0x167, 0x015, 0x00D, 0x005, 0x000, 0x01E, 0x010, - 0x000, 0x0BB, 0x01D, 0x003 -}; - -static const uint8_t huff_spec_b34_bits[] = { - 1, 4, 6, 8, 0, 8, 6, 4, 4, 6, 7, 9, 0, 8, 7, 6, - 6, 7, 8, 10, 0, 10, 8, 7, 8, 9, 10, 10, 0, 10, 10, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10, 10, 0, 10, 10, 9, - 6, 7, 8, 10, 0, 10, 8, 7, 4, 6, 7, 8, 0, 9, 7, 6, -}; - -static const uint16_t huff_spec_b34_codes[] = { - 0x000, 0x00A, 0x038, 0x0EE, 0x000, 0x0EF, 0x039, 0x00B, 0x008, 0x03C, 0x06E, 0x1D8, - 0x000, 0x0C1, 0x075, 0x03F, 0x032, 0x068, 0x0C4, 0x358, 0x000, 0x30F, 0x0C7, 0x06D, - 0x0D4, 0x1AE, 0x30C, 0x308, 0x000, 0x30B, 0x35B, 0x1DB, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x0D5, 0x1DA, 0x35A, 0x30A, 0x000, 0x309, 0x30D, 0x1AF, - 0x033, 0x06C, 0x0C6, 0x30E, 0x000, 0x359, 0x0C5, 0x069, 0x009, 0x03E, 0x074, 0x0C0, - 0x000, 0x1D9, 0x06F, 0x03D, -}; - -static const uint8_t huff_spec_b42_bits[] = { - 4, 5, 6, 8, 6, 7, 8, 8, 0, 8, 8, 7, 6, 8, 6, 5, - 5, 6, 7, 8, 7, 7, 8, 9, 0, 8, 8, 7, 7, 8, 7, 6, - 7, 7, 8, 9, 7, 8, 9, 9, 0, 9, 9, 8, 7, 9, 8, 7, - 8, 9, 9, 10, 8, 8, 9, 10, 0, 10, 9, 8, 8, 10, 9, 8, - 6, 7, 8, 8, 9, 9, 10, 10, 0, 10, 10, 9, 9, 8, 8, 7, - 7, 7, 8, 9, 9, 10, 10, 10, 0, 10, 10, 10, 9, 9, 8, 7, - 8, 8, 9, 9, 10, 10, 10, 10, 0, 10, 10, 10, 10, 9, 9, 8, - 8, 9, 9, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 9, 9, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 9, 9, - 8, 8, 9, 9, 10, 10, 10, 10, 0, 10, 10, 10, 10, 9, 9, 8, - 7, 7, 8, 9, 9, 10, 10, 10, 0, 10, 10, 10, 9, 9, 8, 7, - 6, 7, 8, 8, 9, 9, 10, 10, 0, 10, 10, 9, 9, 8, 8, 7, - 8, 8, 9, 10, 8, 8, 9, 10, 0, 10, 9, 8, 8, 10, 9, 9, - 7, 7, 8, 9, 7, 8, 9, 9, 0, 9, 9, 8, 7, 9, 8, 7, - 5, 6, 7, 8, 7, 7, 8, 8, 0, 9, 8, 7, 7, 8, 7, 6, -}; - -static const uint16_t huff_spec_b42_codes[] = { - 0x00E, 0x018, 0x010, 0x0F0, 0x024, 0x05A, 0x0F6, 0x078, 0x000, 0x079, 0x0F7, 0x05B, - 0x025, 0x0F1, 0x011, 0x019, 0x00C, 0x014, 0x01C, 0x036, 0x05C, 0x012, 0x09E, 0x1E4, - 0x000, 0x00B, 0x0A9, 0x03B, 0x05F, 0x071, 0x019, 0x017, 0x06E, 0x000, 0x03E, 0x114, - 0x002, 0x0B0, 0x1AA, 0x07A, 0x000, 0x099, 0x1E7, 0x0B3, 0x00B, 0x131, 0x07F, 0x00D, - 0x0D8, 0x1FE, 0x112, 0x22E, 0x086, 0x010, 0x134, 0x35C, 0x000, 0x35F, 0x133, 0x013, - 0x081, 0x22D, 0x119, 0x07B, 0x00A, 0x050, 0x0F8, 0x04E, 0x1B4, 0x154, 0x3EC, 0x0D2, - 0x000, 0x0D7, 0x3D7, 0x137, 0x1FD, 0x073, 0x0FD, 0x057, 0x052, 0x010, 0x08E, 0x1E8, - 0x11A, 0x3EE, 0x0F2, 0x03C, 0x000, 0x03F, 0x0F1, 0x3D5, 0x111, 0x1F5, 0x09D, 0x025, - 0x0D2, 0x082, 0x1A0, 0x0F8, 0x36E, 0x0D4, 0x072, 0x03A, 0x000, 0x027, 0x071, 0x07D, - 0x36D, 0x0FB, 0x1AD, 0x085, 0x00C, 0x1A8, 0x03C, 0x346, 0x0D0, 0x076, 0x024, 0x020, - 0x000, 0x023, 0x039, 0x075, 0x07F, 0x345, 0x09B, 0x157, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x00D, 0x156, 0x09A, 0x344, 0x07E, 0x074, 0x038, 0x022, 0x000, 0x021, 0x025, 0x077, - 0x0D1, 0x347, 0x03D, 0x1A9, 0x0D3, 0x084, 0x1AC, 0x0FA, 0x36C, 0x07C, 0x070, 0x026, - 0x000, 0x03B, 0x073, 0x0D5, 0x36F, 0x0F9, 0x1A1, 0x083, 0x053, 0x024, 0x09C, 0x1F4, - 0x110, 0x3D4, 0x0F0, 0x03E, 0x000, 0x03D, 0x0F3, 0x3EF, 0x11B, 0x1E9, 0x08F, 0x011, - 0x00B, 0x056, 0x0FC, 0x072, 0x1FC, 0x136, 0x3D6, 0x0D6, 0x000, 0x0D3, 0x3ED, 0x155, - 0x1B5, 0x04F, 0x0F9, 0x051, 0x0D9, 0x07A, 0x118, 0x22C, 0x080, 0x012, 0x132, 0x35E, - 0x000, 0x35D, 0x135, 0x011, 0x087, 0x22F, 0x113, 0x1FF, 0x06F, 0x00C, 0x07E, 0x130, - 0x00A, 0x0B2, 0x1E6, 0x098, 0x000, 0x07B, 0x1AB, 0x0B1, 0x003, 0x115, 0x03F, 0x001, - 0x00D, 0x016, 0x018, 0x070, 0x05E, 0x03A, 0x0A8, 0x00A, 0x000, 0x1E5, 0x09F, 0x013, - 0x05D, 0x037, 0x01D, 0x015, -}; - -static const uint8_t huff_spec_b43_bits[] = { - 2, 5, 6, 7, 7, 8, 8, 9, 0, 9, 8, 8, 7, 7, 6, 5, - 5, 6, 7, 8, 7, 8, 9, 10, 0, 10, 9, 8, 7, 8, 7, 6, - 6, 7, 8, 9, 8, 9, 10, 10, 0, 10, 10, 9, 8, 9, 8, 7, - 7, 8, 9, 10, 9, 9, 10, 10, 0, 10, 10, 10, 9, 10, 9, 8, - 7, 8, 8, 9, 10, 10, 10, 10, 0, 10, 10, 10, 10, 9, 8, 7, - 8, 8, 9, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 9, 8, - 9, 9, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 9, 9, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 9, - 8, 8, 9, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 9, 8, - 7, 7, 8, 9, 10, 10, 10, 10, 0, 10, 10, 10, 10, 9, 8, 8, - 7, 8, 9, 10, 9, 10, 10, 10, 0, 10, 10, 9, 9, 10, 9, 8, - 6, 7, 8, 9, 8, 9, 10, 10, 0, 10, 10, 9, 8, 9, 8, 7, - 5, 6, 7, 8, 7, 8, 9, 10, 0, 10, 9, 8, 7, 8, 7, 6, -}; - -static const uint16_t huff_spec_b43_codes[] = { - 0x001, 0x01E, 0x022, 0x018, 0x064, 0x0EC, 0x008, 0x100, 0x000, 0x101, 0x009, 0x0ED, - 0x065, 0x019, 0x023, 0x01F, 0x01A, 0x030, 0x056, 0x09A, 0x00A, 0x090, 0x12C, 0x0A6, - 0x000, 0x0A9, 0x12F, 0x093, 0x00F, 0x09F, 0x059, 0x039, 0x00E, 0x054, 0x0BC, 0x19E, - 0x082, 0x176, 0x0AC, 0x088, 0x000, 0x08B, 0x0AF, 0x19D, 0x095, 0x1D1, 0x0BF, 0x051, - 0x002, 0x098, 0x1D4, 0x0B8, 0x170, 0x046, 0x090, 0x060, 0x000, 0x067, 0x095, 0x0BD, - 0x173, 0x0B5, 0x1D3, 0x09D, 0x052, 0x0EE, 0x034, 0x174, 0x0BA, 0x09C, 0x080, 0x044, - 0x000, 0x047, 0x06D, 0x099, 0x0BF, 0x16F, 0x085, 0x001, 0x0CC, 0x036, 0x16C, 0x0B0, - 0x09A, 0x084, 0x04E, 0x03E, 0x000, 0x037, 0x04B, 0x06B, 0x0A1, 0x0B3, 0x16B, 0x087, - 0x1D6, 0x102, 0x0A4, 0x092, 0x068, 0x04C, 0x034, 0x030, 0x000, 0x02D, 0x03D, 0x049, - 0x083, 0x097, 0x0AB, 0x169, 0x0B6, 0x09E, 0x06E, 0x064, 0x040, 0x038, 0x02E, 0x02A, - 0x000, 0x029, 0x033, 0x03B, 0x043, 0x063, 0x087, 0x0A3, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x0B7, 0x0A2, 0x086, 0x062, 0x042, 0x03A, 0x032, 0x028, 0x000, 0x02B, 0x02F, 0x039, - 0x041, 0x065, 0x06F, 0x09F, 0x1D7, 0x168, 0x0AA, 0x096, 0x082, 0x048, 0x03C, 0x02C, - 0x000, 0x031, 0x035, 0x04D, 0x069, 0x093, 0x0A5, 0x103, 0x0CD, 0x086, 0x16A, 0x0B2, - 0x0A0, 0x06A, 0x04A, 0x036, 0x000, 0x03F, 0x04F, 0x085, 0x09B, 0x0B1, 0x16D, 0x037, - 0x053, 0x000, 0x084, 0x16E, 0x0BE, 0x098, 0x06C, 0x046, 0x000, 0x045, 0x081, 0x09D, - 0x0BB, 0x175, 0x035, 0x0EF, 0x003, 0x09C, 0x1D2, 0x0B4, 0x172, 0x0BC, 0x094, 0x066, - 0x000, 0x061, 0x091, 0x047, 0x171, 0x0B9, 0x1D5, 0x099, 0x00F, 0x050, 0x0BE, 0x1D0, - 0x094, 0x19C, 0x0AE, 0x08A, 0x000, 0x089, 0x0AD, 0x177, 0x083, 0x19F, 0x0BD, 0x055, - 0x01B, 0x038, 0x058, 0x09E, 0x00E, 0x092, 0x12E, 0x0A8, 0x000, 0x0A7, 0x12D, 0x091, - 0x00B, 0x09B, 0x057, 0x031, -}; - -static const uint8_t huff_spec_b44_bits[] = { - 2, 4, 6, 7, 7, 8, 10, 10, 0, 10, 10, 8, 7, 7, 6, 4, - 5, 5, 7, 8, 8, 10, 10, 10, 0, 10, 10, 10, 8, 8, 7, 5, - 6, 7, 8, 9, 9, 10, 10, 10, 0, 10, 10, 10, 10, 9, 8, 7, - 8, 8, 9, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 8, - 8, 8, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 8, - 9, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 9, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, - 8, 8, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 8, - 8, 8, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 9, 8, - 6, 7, 8, 9, 10, 10, 10, 10, 0, 10, 10, 10, 9, 9, 8, 7, - 5, 5, 7, 8, 8, 10, 10, 10, 0, 10, 10, 10, 8, 8, 7, 5, -}; - -static const uint16_t huff_spec_b44_codes[] = { - 0x002, 0x002, 0x030, 0x000, 0x002, 0x00C, 0x1D2, 0x1AE, 0x000, 0x1AF, 0x1D3, 0x00D, - 0x003, 0x001, 0x031, 0x003, 0x01E, 0x002, 0x070, 0x0C8, 0x07E, 0x1E8, 0x1C0, 0x176, - 0x000, 0x17F, 0x1C3, 0x1EB, 0x0CF, 0x0D3, 0x073, 0x009, 0x018, 0x06A, 0x0EC, 0x1DE, - 0x1A2, 0x1CA, 0x1AA, 0x164, 0x000, 0x16D, 0x1AD, 0x1D1, 0x1EF, 0x1DD, 0x0EB, 0x06D, - 0x0E8, 0x0CA, 0x1BE, 0x1CE, 0x1DA, 0x1B6, 0x170, 0x154, 0x000, 0x153, 0x173, 0x1B1, - 0x1D7, 0x1D5, 0x343, 0x0CD, 0x0DC, 0x078, 0x340, 0x1CC, 0x1BA, 0x1A8, 0x156, 0x148, - 0x000, 0x145, 0x15F, 0x1A1, 0x1BD, 0x1D9, 0x1ED, 0x07D, 0x1BC, 0x1DC, 0x1C4, 0x1B2, - 0x17C, 0x15A, 0x14A, 0x03A, 0x000, 0x039, 0x147, 0x16B, 0x17B, 0x1B5, 0x1C9, 0x1DF, - 0x1C6, 0x1B8, 0x1A2, 0x168, 0x160, 0x14C, 0x02E, 0x024, 0x000, 0x027, 0x03D, 0x151, - 0x15D, 0x16F, 0x1A7, 0x1BF, 0x1A4, 0x174, 0x162, 0x14E, 0x140, 0x02C, 0x02A, 0x022, - 0x000, 0x021, 0x029, 0x03F, 0x143, 0x159, 0x167, 0x179, 0x000, 0x000, 0x000, 0x000, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, - 0x1A5, 0x178, 0x166, 0x158, 0x142, 0x03E, 0x028, 0x020, 0x000, 0x023, 0x02B, 0x02D, - 0x141, 0x14F, 0x163, 0x175, 0x1C7, 0x1BE, 0x1A6, 0x16E, 0x15C, 0x150, 0x03C, 0x026, - 0x000, 0x025, 0x02F, 0x14D, 0x161, 0x169, 0x1A3, 0x1B9, 0x1BD, 0x1DE, 0x1C8, 0x1B4, - 0x17A, 0x16A, 0x146, 0x038, 0x000, 0x03B, 0x14B, 0x15B, 0x17D, 0x1B3, 0x1C5, 0x1DD, - 0x0DD, 0x07C, 0x1EC, 0x1D8, 0x1BC, 0x1A0, 0x15E, 0x144, 0x000, 0x149, 0x157, 0x1A9, - 0x1BB, 0x1CD, 0x341, 0x079, 0x0E9, 0x0CC, 0x342, 0x1D4, 0x1D6, 0x1B0, 0x172, 0x152, - 0x000, 0x155, 0x171, 0x1B7, 0x1DB, 0x1CF, 0x1BF, 0x0CB, 0x019, 0x06C, 0x0EA, 0x1DC, - 0x1EE, 0x1D0, 0x1AC, 0x16C, 0x000, 0x165, 0x1AB, 0x1CB, 0x1A3, 0x1DF, 0x0ED, 0x06B, - 0x01F, 0x008, 0x072, 0x0D2, 0x0CE, 0x1EA, 0x1C2, 0x17E, 0x000, 0x177, 0x1C1, 0x1E9, - 0x07F, 0x0C9, 0x071, 0x003, -}; - -static const uint8_t huff_spec_b52_bits[] = { - 3, 4, 4, 4, 5, 5, 6, 6, 5, 5, 5, 6, 6, 6, 7, 7, - 0, 7, 7, 6, 6, 6, 5, 5, 5, 6, 6, 5, 5, 4, 4, 4, -}; - -static const uint16_t huff_spec_b52_codes[] = { - 0x06, 0x0E, 0x06, 0x00, 0x0A, 0x04, 0x2C, 0x12, 0x14, 0x10, 0x06, 0x2E, 0x24, 0x10, 0x4E, 0x4C, - 0x00, 0x4D, 0x4F, 0x11, 0x25, 0x2F, 0x07, 0x11, 0x15, 0x13, 0x2D, 0x05, 0x0B, 0x01, 0x07, 0x0F, -}; - -static const uint8_t huff_spec_b53_bits[] = { - 2, 3, 4, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 8, 8, - 0, 8, 8, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 4, 3, -}; - -static const uint16_t huff_spec_b53_codes[] = { - 0x02, 0x00, 0x06, 0x1C, 0x18, 0x3E, 0x16, 0x10, 0x3C, 0x36, 0x14, 0x6A, 0x26, 0x24, 0xD2, 0xD0, - 0x00, 0xD1, 0xD3, 0x25, 0x27, 0x6B, 0x15, 0x37, 0x3D, 0x11, 0x17, 0x3F, 0x19, 0x1D, 0x07, 0x01, -}; - -static const uint8_t huff_spec_b54_bits[] = { - 2, 3, 4, 4, 5, 6, 6, 7, 6, 6, 7, 8, 8, 8, 9, 9, - 0, 9, 9, 8, 8, 8, 7, 6, 6, 7, 6, 6, 5, 4, 4, 3, -}; - -static const uint16_t huff_spec_b54_codes[] = { - 0x003, 0x002, 0x008, 0x000, 0x014, 0x02E, 0x00E, 0x05A, 0x00A, 0x008, 0x01A, 0x0B2, - 0x032, 0x030, 0x162, 0x160, 0x000, 0x161, 0x163, 0x031, 0x033, 0x0B3, 0x01B, 0x009, - 0x00B, 0x05B, 0x00F, 0x02F, 0x015, 0x001, 0x009, 0x003, -}; - -static const uint8_t huff_spec_b62_bits[] = { - 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, - 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 0, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, - 6, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, -}; - -static const uint16_t huff_spec_b62_codes[] = { - 0x0D, 0x06, 0x1C, 0x14, 0x0A, 0x04, 0x3E, 0x2E, 0x22, 0x0E, 0x06, 0x00, 0x5A, 0x4E, 0x40, 0x20, - 0x30, 0x32, 0x24, 0x12, 0x0C, 0x02, 0x78, 0x58, 0x42, 0x22, 0x0A, 0x08, 0xF6, 0xF4, 0x9A, 0x98, - 0x00, 0x99, 0x9B, 0xF5, 0xF7, 0x09, 0x0B, 0x23, 0x43, 0x59, 0x79, 0x03, 0x0D, 0x13, 0x25, 0x33, - 0x31, 0x21, 0x41, 0x4F, 0x5B, 0x01, 0x07, 0x0F, 0x23, 0x2F, 0x3F, 0x05, 0x0B, 0x15, 0x1D, 0x07, -}; - -static const uint8_t huff_spec_b63_bits[] = { - 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, - 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, - 6, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, -}; - -static const uint16_t huff_spec_b63_codes[] = { - 0x006, 0x00E, 0x004, 0x014, 0x010, 0x006, 0x000, 0x026, 0x01C, 0x018, 0x004, 0x05C, - 0x04A, 0x03C, 0x016, 0x0BC, 0x006, 0x008, 0x058, 0x03E, 0x036, 0x014, 0x0B6, 0x0B4, - 0x090, 0x068, 0x17E, 0x17C, 0x126, 0x124, 0x0D6, 0x0D4, 0x000, 0x0D5, 0x0D7, 0x125, - 0x127, 0x17D, 0x17F, 0x069, 0x091, 0x0B5, 0x0B7, 0x015, 0x037, 0x03F, 0x059, 0x009, - 0x007, 0x0BD, 0x017, 0x03D, 0x04B, 0x05D, 0x005, 0x019, 0x01D, 0x027, 0x001, 0x007, - 0x011, 0x015, 0x005, 0x00F, -}; - -static const uint8_t huff_spec_b64_bits[] = { - 3, 3, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, - 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, - 0, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 7, 7, - 7, 8, 7, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 3, -}; - -static const uint16_t huff_spec_b64_codes[] = { - 0x007, 0x000, 0x008, 0x01A, 0x014, 0x00C, 0x032, 0x02E, 0x01E, 0x014, 0x062, 0x05A, - 0x03A, 0x026, 0x020, 0x0B2, 0x038, 0x02C, 0x022, 0x0C0, 0x05E, 0x04A, 0x186, 0x184, - 0x160, 0x0BA, 0x092, 0x090, 0x2C6, 0x2C4, 0x172, 0x170, 0x000, 0x171, 0x173, 0x2C5, - 0x2C7, 0x091, 0x093, 0x0BB, 0x161, 0x185, 0x187, 0x04B, 0x05F, 0x0C1, 0x023, 0x02D, - 0x039, 0x0B3, 0x021, 0x027, 0x03B, 0x05B, 0x063, 0x015, 0x01F, 0x02F, 0x033, 0x00D, - 0x015, 0x01B, 0x009, 0x001, -}; - -static const uint8_t huff_spec_b72_bits[] = { - 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, -}; - -static const uint16_t huff_spec_b72_codes[] = { - 0x01E, 0x016, 0x00C, 0x000, 0x038, 0x032, 0x028, 0x022, 0x01C, 0x012, 0x00E, 0x006, - 0x076, 0x06C, 0x060, 0x04E, 0x03E, 0x02A, 0x022, 0x01A, 0x012, 0x00A, 0x0FC, 0x0DC, - 0x0C6, 0x0A8, 0x094, 0x086, 0x058, 0x042, 0x040, 0x02A, 0x068, 0x07C, 0x06A, 0x056, - 0x048, 0x040, 0x02E, 0x028, 0x016, 0x010, 0x008, 0x0EA, 0x0DE, 0x0AA, 0x09A, 0x096, - 0x07A, 0x078, 0x05A, 0x032, 0x030, 0x028, 0x1FE, 0x1FC, 0x1D2, 0x1D0, 0x18A, 0x188, - 0x132, 0x130, 0x10A, 0x108, 0x000, 0x109, 0x10B, 0x131, 0x133, 0x189, 0x18B, 0x1D1, - 0x1D3, 0x1FD, 0x1FF, 0x029, 0x031, 0x033, 0x05B, 0x079, 0x07B, 0x097, 0x09B, 0x0AB, - 0x0DF, 0x0EB, 0x009, 0x011, 0x017, 0x029, 0x02F, 0x041, 0x049, 0x057, 0x06B, 0x07D, - 0x069, 0x02B, 0x041, 0x043, 0x059, 0x087, 0x095, 0x0A9, 0x0C7, 0x0DD, 0x0FD, 0x00B, - 0x013, 0x01B, 0x023, 0x02B, 0x03F, 0x04F, 0x061, 0x06D, 0x077, 0x007, 0x00F, 0x013, - 0x01D, 0x023, 0x029, 0x033, 0x039, 0x001, 0x00D, 0x017, -}; - -static const uint8_t huff_spec_b73_bits[] = { - 3, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, - 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, - 8, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 4, -}; - -static const uint16_t huff_spec_b73_codes[] = { - 0x000, 0x006, 0x018, 0x010, 0x004, 0x03A, 0x034, 0x02A, 0x026, 0x014, 0x010, 0x07E, - 0x072, 0x06E, 0x05C, 0x052, 0x04A, 0x02C, 0x024, 0x018, 0x0F4, 0x0E0, 0x0DA, 0x0B6, - 0x0B2, 0x0A0, 0x05E, 0x04E, 0x038, 0x034, 0x1E6, 0x1B2, 0x0FA, 0x01E, 0x0F8, 0x0F0, - 0x0BE, 0x0B4, 0x0A2, 0x090, 0x04C, 0x03A, 0x1EE, 0x1E4, 0x1C6, 0x1B0, 0x178, 0x162, - 0x126, 0x124, 0x0B8, 0x06C, 0x3DA, 0x3D8, 0x38A, 0x388, 0x2F6, 0x2F4, 0x2C2, 0x2C0, - 0x176, 0x174, 0x0DC, 0x0DE, 0x000, 0x0DF, 0x0DD, 0x175, 0x177, 0x2C1, 0x2C3, 0x2F5, - 0x2F7, 0x389, 0x38B, 0x3D9, 0x3DB, 0x06D, 0x0B9, 0x125, 0x127, 0x163, 0x179, 0x1B1, - 0x1C7, 0x1E5, 0x1EF, 0x03B, 0x04D, 0x091, 0x0A3, 0x0B5, 0x0BF, 0x0F1, 0x0F9, 0x01F, - 0x0FB, 0x1B3, 0x1E7, 0x035, 0x039, 0x04F, 0x05F, 0x0A1, 0x0B3, 0x0B7, 0x0DB, 0x0E1, - 0x0F5, 0x019, 0x025, 0x02D, 0x04B, 0x053, 0x05D, 0x06F, 0x073, 0x07F, 0x011, 0x015, - 0x027, 0x02B, 0x035, 0x03B, 0x005, 0x011, 0x019, 0x007, -}; - -static const uint8_t huff_spec_b74_bits[] = { - 3, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, - 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, - 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, - 8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, - 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, -}; - -static const uint16_t huff_spec_b74_codes[] = { - 0x001, 0x008, 0x01E, 0x018, 0x00C, 0x002, 0x03A, 0x034, 0x02C, 0x01E, 0x016, 0x012, - 0x072, 0x06E, 0x05E, 0x056, 0x050, 0x038, 0x022, 0x004, 0x0E2, 0x0DA, 0x0BA, 0x0A8, - 0x076, 0x054, 0x050, 0x002, 0x000, 0x1C0, 0x1B0, 0x156, 0x0A4, 0x0A6, 0x074, 0x052, - 0x004, 0x1C2, 0x1B2, 0x170, 0x154, 0x0AE, 0x0AC, 0x086, 0x2E6, 0x2E4, 0x10A, 0x108, - 0x106, 0x104, 0x102, 0x100, 0x03E, 0x03A, 0x03C, 0x038, 0x036, 0x034, 0x032, 0x030, - 0x01E, 0x01A, 0x01C, 0x018, 0x000, 0x019, 0x01D, 0x01B, 0x01F, 0x031, 0x033, 0x035, - 0x037, 0x039, 0x03D, 0x03B, 0x03F, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x2E5, - 0x2E7, 0x087, 0x0AD, 0x0AF, 0x155, 0x171, 0x1B3, 0x1C3, 0x005, 0x053, 0x075, 0x0A7, - 0x0A5, 0x157, 0x1B1, 0x1C1, 0x001, 0x003, 0x051, 0x055, 0x077, 0x0A9, 0x0BB, 0x0DB, - 0x0E3, 0x005, 0x023, 0x039, 0x051, 0x057, 0x05F, 0x06F, 0x073, 0x013, 0x017, 0x01F, - 0x02D, 0x035, 0x03B, 0x003, 0x00D, 0x019, 0x01F, 0x009, + { 3, 1, 0, 2 }, + { 7, 1, 0, 3 }, + { 15, 1, 0, 4 }, + { 32, 1, 0, 5 }, +}; + +static const uint8_t at9_coeffs_tab[][2] = { + /* Coefficient table A.2.1 - 8 entries */ + { 1, 3 }, { 3, 3 }, { 12, 3 }, { 4, 3 }, { 7, 3 }, + { 13, 3 }, { 15, 3 }, { 5, 3 }, + /* Coefficient table A.2.2 - 80 entries */ + { 17, 6 }, { 51, 6 }, { 81, 7 }, { 243, 7 }, { 69, 7 }, + { 207, 7 }, { 205, 7 }, { 71, 7 }, { 209, 7 }, { 115, 7 }, + { 245, 7 }, { 95, 7 }, { 125, 7 }, { 215, 7 }, { 1, 4 }, + { 3, 4 }, { 116, 7 }, { 220, 7 }, { 84, 7 }, { 252, 7 }, + { 29, 7 }, { 55, 7 }, { 21, 7 }, { 63, 7 }, { 65, 6 }, + { 195, 6 }, { 193, 6 }, { 67, 6 }, { 20, 6 }, { 60, 6 }, + { 52, 6 }, { 28, 6 }, { 16, 5 }, { 48, 5 }, { 4, 5 }, + { 12, 5 }, { 221, 8 }, { 119, 8 }, { 117, 8 }, { 223, 8 }, + { 213, 8 }, { 127, 8 }, { 253, 8 }, { 87, 8 }, { 80, 6 }, + { 240, 6 }, { 93, 8 }, { 247, 8 }, { 85, 8 }, { 255, 8 }, + { 113, 7 }, { 211, 7 }, { 208, 6 }, { 112, 6 }, { 64, 5 }, + { 192, 5 }, { 212, 7 }, { 124, 7 }, { 241, 7 }, { 83, 7 }, + { 77, 7 }, { 199, 7 }, { 244, 7 }, { 92, 7 }, { 196, 6 }, + { 76, 6 }, { 53, 7 }, { 31, 7 }, { 197, 7 }, { 79, 7 }, + { 49, 6 }, { 19, 6 }, { 61, 7 }, { 23, 7 }, { 68, 7 }, + { 204, 7 }, { 5, 6 }, { 15, 6 }, { 13, 6 }, { 7, 6 }, + /* Coefficient table A.2.3 - 81 entries */ + { 65, 6 }, { 195, 6 }, { 193, 6 }, { 67, 6 }, { 197, 7 }, + { 79, 7 }, { 77, 7 }, { 199, 7 }, { 241, 7 }, { 83, 7 }, + { 244, 7 }, { 92, 7 }, { 1, 4 }, { 3, 4 }, { 20, 6 }, + { 60, 6 }, { 212, 7 }, { 124, 7 }, { 61, 7 }, { 23, 7 }, + { 52, 6 }, { 28, 6 }, { 53, 7 }, { 31, 7 }, { 245, 8 }, + { 95, 8 }, { 125, 8 }, { 215, 8 }, { 80, 6 }, { 240, 6 }, + { 208, 6 }, { 112, 6 }, { 205, 8 }, { 71, 8 }, { 81, 8 }, + { 243, 8 }, { 69, 8 }, { 207, 8 }, { 209, 8 }, { 115, 8 }, + { 5, 6 }, { 15, 6 }, { 13, 6 }, { 7, 6 }, { 196, 6 }, + { 76, 6 }, { 221, 9 }, { 119, 9 }, { 253, 9 }, { 87, 9 }, + { 116, 8 }, { 220, 8 }, { 68, 7 }, { 204, 7 }, { 49, 6 }, + { 19, 6 }, { 117, 9 }, { 223, 9 }, { 213, 9 }, { 127, 9 }, + { 84, 8 }, { 252, 8 }, { 29, 8 }, { 55, 8 }, { 21, 8 }, + { 63, 8 }, { 17, 7 }, { 51, 7 }, { 93, 9 }, { 247, 9 }, + { 85, 9 }, { 255, 9 }, { 113, 8 }, { 211, 8 }, { 4, 5 }, + { 12, 5 }, { 0, 3 }, { 16, 5 }, { 48, 5 }, { 64, 5 }, + { 192, 5 }, + /* Coefficient table A.2.4 - 81 entries */ + { 20, 6 }, { 60, 6 }, { 52, 6 }, { 28, 6 }, { 80, 6 }, + { 240, 6 }, { 208, 6 }, { 112, 6 }, { 1, 4 }, { 3, 4 }, + { 5, 6 }, { 15, 6 }, { 13, 6 }, { 7, 6 }, { 84, 8 }, + { 252, 8 }, { 29, 8 }, { 55, 8 }, { 68, 7 }, { 204, 7 }, + { 196, 6 }, { 76, 6 }, { 17, 7 }, { 51, 7 }, { 21, 8 }, + { 63, 8 }, { 113, 8 }, { 211, 8 }, { 49, 6 }, { 19, 6 }, + { 245, 9 }, { 95, 9 }, { 125, 9 }, { 215, 9 }, { 244, 8 }, + { 92, 8 }, { 212, 8 }, { 124, 8 }, { 241, 8 }, { 83, 8 }, + { 77, 8 }, { 199, 8 }, { 197, 8 }, { 79, 8 }, { 53, 8 }, + { 31, 8 }, { 253, 10 }, { 87, 10 }, { 213, 10 }, { 127, 10 }, + { 81, 9 }, { 243, 9 }, { 0, 2 }, { 61, 8 }, { 23, 8 }, + { 117, 10 }, { 223, 10 }, { 221, 10 }, { 119, 10 }, { 209, 9 }, + { 115, 9 }, { 65, 7 }, { 195, 7 }, { 193, 7 }, { 67, 7 }, + { 69, 9 }, { 207, 9 }, { 205, 9 }, { 71, 9 }, { 93, 10 }, + { 247, 10 }, { 85, 10 }, { 255, 10 }, { 116, 9 }, { 220, 9 }, + { 16, 5 }, { 48, 5 }, { 64, 5 }, { 192, 5 }, { 4, 5 }, + { 12, 5 }, + /* Coefficient table A.3.1 - 40 entries */ + { 50, 5 }, { 22, 5 }, { 11, 5 }, { 61, 5 }, { 2, 4 }, + { 6, 4 }, { 59, 5 }, { 13, 5 }, { 17, 5 }, { 55, 5 }, + { 49, 5 }, { 23, 5 }, { 24, 5 }, { 40, 5 }, { 26, 6 }, + { 46, 6 }, { 42, 6 }, { 30, 6 }, { 10, 5 }, { 62, 5 }, + { 58, 5 }, { 14, 5 }, { 19, 6 }, { 53, 6 }, { 51, 6 }, + { 21, 6 }, { 3, 5 }, { 5, 5 }, { 16, 5 }, { 48, 5 }, + { 25, 6 }, { 47, 6 }, { 41, 6 }, { 31, 6 }, { 27, 7 }, + { 45, 7 }, { 43, 7 }, { 29, 7 }, { 18, 6 }, { 54, 6 }, + /* Coefficient table A.3.2 - 49 entries */ + { 57, 5 }, { 15, 5 }, { 17, 5 }, { 55, 5 }, { 49, 5 }, + { 23, 5 }, { 58, 5 }, { 14, 5 }, { 10, 5 }, { 62, 5 }, + { 43, 7 }, { 29, 7 }, { 27, 7 }, { 45, 7 }, { 25, 6 }, + { 47, 6 }, { 41, 6 }, { 31, 6 }, { 59, 6 }, { 13, 6 }, + { 11, 6 }, { 61, 6 }, { 50, 6 }, { 22, 6 }, { 16, 5 }, + { 48, 5 }, { 8, 5 }, { 56, 5 }, { 18, 6 }, { 54, 6 }, + { 24, 6 }, { 40, 6 }, { 2, 5 }, { 6, 5 }, { 1, 5 }, + { 7, 5 }, { 0, 4 }, { 42, 7 }, { 30, 7 }, { 26, 7 }, + { 46, 7 }, { 3, 6 }, { 5, 6 }, { 19, 7 }, { 53, 7 }, + { 51, 7 }, { 21, 7 }, { 9, 6 }, { 63, 6 }, + /* Coefficient table A.3.3 - 49 entries */ + { 51, 7 }, { 21, 7 }, { 19, 7 }, { 53, 7 }, { 24, 6 }, + { 40, 6 }, { 50, 6 }, { 22, 6 }, { 18, 6 }, { 54, 6 }, + { 3, 6 }, { 5, 6 }, { 43, 8 }, { 29, 8 }, { 27, 8 }, + { 45, 8 }, { 25, 7 }, { 47, 7 }, { 16, 5 }, { 48, 5 }, + { 8, 4 }, { 56, 4 }, { 1, 4 }, { 7, 4 }, { 2, 5 }, + { 6, 5 }, { 9, 5 }, { 63, 5 }, { 0, 3 }, { 57, 5 }, + { 15, 5 }, { 41, 7 }, { 31, 7 }, { 11, 7 }, { 61, 7 }, + { 59, 7 }, { 13, 7 }, { 26, 8 }, { 46, 8 }, { 42, 8 }, + { 30, 8 }, { 49, 6 }, { 23, 6 }, { 17, 6 }, { 55, 6 }, + { 58, 6 }, { 14, 6 }, { 10, 6 }, { 62, 6 }, + /* Coefficient table A.3.4 - 49 entries */ + { 0, 2 }, { 16, 5 }, { 48, 5 }, { 2, 5 }, { 6, 5 }, + { 26, 8 }, { 46, 8 }, { 51, 8 }, { 21, 8 }, { 24, 7 }, + { 40, 7 }, { 3, 7 }, { 5, 7 }, { 19, 8 }, { 53, 8 }, + { 25, 8 }, { 47, 8 }, { 50, 7 }, { 22, 7 }, { 18, 7 }, + { 54, 7 }, { 17, 6 }, { 55, 6 }, { 8, 4 }, { 56, 4 }, + { 1, 4 }, { 7, 4 }, { 49, 6 }, { 23, 6 }, { 10, 6 }, + { 62, 6 }, { 58, 6 }, { 14, 6 }, { 41, 8 }, { 31, 8 }, + { 11, 8 }, { 61, 8 }, { 59, 8 }, { 13, 8 }, { 43, 10 }, + { 29, 10 }, { 27, 10 }, { 45, 10 }, { 42, 9 }, { 30, 9 }, + { 9, 5 }, { 63, 5 }, { 57, 5 }, { 15, 5 }, + /* Coefficient table A.4.1 - 176 entries */ + { 83, 7 }, { 189, 7 }, { 68, 7 }, { 204, 7 }, { 23, 7 }, + { 249, 7 }, { 166, 8 }, { 106, 8 }, { 183, 8 }, { 89, 8 }, + { 52, 7 }, { 220, 7 }, { 161, 7 }, { 111, 7 }, { 179, 7 }, + { 93, 7 }, { 196, 7 }, { 76, 7 }, { 38, 7 }, { 234, 7 }, + { 116, 8 }, { 156, 8 }, { 148, 8 }, { 124, 8 }, { 97, 7 }, + { 175, 7 }, { 247, 7 }, { 25, 7 }, { 53, 7 }, { 219, 7 }, + { 212, 7 }, { 60, 7 }, { 5, 6 }, { 11, 6 }, { 101, 8 }, + { 171, 8 }, { 165, 8 }, { 107, 8 }, { 230, 7 }, { 42, 7 }, + { 244, 6 }, { 28, 6 }, { 7, 7 }, { 9, 7 }, { 213, 7 }, + { 59, 7 }, { 86, 8 }, { 186, 8 }, { 115, 8 }, { 157, 8 }, + { 71, 8 }, { 201, 8 }, { 182, 8 }, { 90, 8 }, { 4, 6 }, + { 12, 6 }, { 147, 8 }, { 125, 8 }, { 199, 8 }, { 73, 8 }, + { 82, 7 }, { 190, 7 }, { 66, 7 }, { 206, 7 }, { 178, 7 }, + { 94, 7 }, { 194, 7 }, { 78, 7 }, { 22, 7 }, { 250, 7 }, + { 96, 7 }, { 160, 7 }, { 100, 8 }, { 172, 8 }, { 164, 8 }, + { 108, 8 }, { 246, 7 }, { 26, 7 }, { 85, 8 }, { 187, 8 }, + { 114, 8 }, { 158, 8 }, { 37, 7 }, { 235, 7 }, { 36, 7 }, + { 236, 7 }, { 146, 8 }, { 126, 8 }, { 70, 8 }, { 202, 8 }, + { 215, 8 }, { 57, 8 }, { 55, 8 }, { 217, 8 }, { 181, 8 }, + { 91, 8 }, { 198, 8 }, { 74, 8 }, { 228, 7 }, { 44, 7 }, + { 229, 7 }, { 43, 7 }, { 81, 7 }, { 191, 7 }, { 177, 7 }, + { 95, 7 }, { 119, 9 }, { 153, 9 }, { 151, 9 }, { 121, 9 }, + { 99, 8 }, { 173, 8 }, { 65, 7 }, { 207, 7 }, { 6, 7 }, + { 10, 7 }, { 193, 7 }, { 79, 7 }, { 113, 8 }, { 159, 8 }, + { 163, 8 }, { 109, 8 }, { 145, 8 }, { 127, 8 }, { 118, 9 }, + { 154, 9 }, { 103, 9 }, { 169, 9 }, { 84, 8 }, { 188, 8 }, + { 39, 8 }, { 233, 8 }, { 167, 9 }, { 105, 9 }, { 150, 9 }, + { 122, 9 }, { 69, 8 }, { 203, 8 }, { 180, 8 }, { 92, 8 }, + { 54, 8 }, { 218, 8 }, { 197, 8 }, { 75, 8 }, { 98, 8 }, + { 174, 8 }, { 21, 7 }, { 251, 7 }, { 231, 8 }, { 41, 8 }, + { 162, 8 }, { 110, 8 }, { 214, 8 }, { 58, 8 }, { 117, 9 }, + { 155, 9 }, { 149, 9 }, { 123, 9 }, { 80, 7 }, { 176, 7 }, + { 20, 7 }, { 252, 7 }, { 102, 9 }, { 170, 9 }, { 87, 9 }, + { 185, 9 }, { 112, 8 }, { 144, 8 }, { 245, 7 }, { 27, 7 }, + { 64, 7 }, { 192, 7 }, { 67, 8 }, { 205, 8 }, { 195, 8 }, + { 77, 8 }, + /* Coefficient table A.4.2 - 225 entries */ + { 3, 7 }, { 13, 7 }, { 113, 8 }, { 159, 8 }, { 163, 8 }, + { 109, 8 }, { 16, 6 }, { 240, 6 }, { 81, 7 }, { 191, 7 }, + { 177, 7 }, { 95, 7 }, { 0, 5 }, { 112, 8 }, { 144, 8 }, + { 99, 8 }, { 173, 8 }, { 149, 9 }, { 123, 9 }, { 166, 9 }, + { 106, 9 }, { 54, 8 }, { 218, 8 }, { 66, 7 }, { 206, 7 }, + { 23, 8 }, { 249, 8 }, { 214, 8 }, { 58, 8 }, { 194, 7 }, + { 78, 7 }, { 117, 9 }, { 155, 9 }, { 87, 9 }, { 185, 9 }, + { 247, 8 }, { 25, 8 }, { 21, 7 }, { 251, 7 }, { 211, 8 }, + { 61, 8 }, { 51, 8 }, { 221, 8 }, { 36, 7 }, { 236, 7 }, + { 228, 7 }, { 44, 7 }, { 183, 9 }, { 89, 9 }, { 102, 9 }, + { 170, 9 }, { 180, 8 }, { 92, 8 }, { 80, 7 }, { 176, 7 }, + { 245, 7 }, { 27, 7 }, { 69, 8 }, { 203, 8 }, { 84, 8 }, + { 188, 8 }, { 225, 7 }, { 47, 7 }, { 33, 7 }, { 239, 7 }, + { 1, 6 }, { 15, 6 }, { 197, 8 }, { 75, 8 }, { 98, 8 }, + { 174, 8 }, { 18, 7 }, { 254, 7 }, { 162, 8 }, { 110, 8 }, + { 116, 9 }, { 156, 9 }, { 148, 9 }, { 124, 9 }, { 242, 7 }, + { 30, 7 }, { 5, 7 }, { 11, 7 }, { 7, 8 }, { 9, 8 }, + { 230, 8 }, { 42, 8 }, { 65, 7 }, { 207, 7 }, { 71, 9 }, + { 201, 9 }, { 199, 9 }, { 73, 9 }, { 38, 8 }, { 234, 8 }, + { 32, 7 }, { 224, 7 }, { 193, 7 }, { 79, 7 }, { 165, 9 }, + { 107, 9 }, { 182, 9 }, { 90, 9 }, { 35, 8 }, { 237, 8 }, + { 244, 7 }, { 28, 7 }, { 20, 7 }, { 252, 7 }, { 50, 8 }, + { 222, 8 }, { 97, 8 }, { 175, 8 }, { 101, 9 }, { 171, 9 }, + { 86, 9 }, { 186, 9 }, { 83, 8 }, { 189, 8 }, { 161, 8 }, + { 111, 8 }, { 179, 8 }, { 93, 8 }, { 64, 7 }, { 192, 7 }, + { 227, 8 }, { 45, 8 }, { 210, 8 }, { 62, 8 }, { 2, 7 }, + { 14, 7 }, { 213, 8 }, { 59, 8 }, { 53, 8 }, { 219, 8 }, + { 196, 8 }, { 76, 8 }, { 115, 9 }, { 157, 9 }, { 151, 10 }, + { 121, 10 }, { 119, 10 }, { 153, 10 }, { 68, 8 }, { 204, 8 }, + { 22, 8 }, { 250, 8 }, { 96, 8 }, { 160, 8 }, { 147, 9 }, + { 125, 9 }, { 55, 9 }, { 217, 9 }, { 246, 8 }, { 26, 8 }, + { 215, 9 }, { 57, 9 }, { 164, 9 }, { 108, 9 }, { 17, 7 }, + { 255, 7 }, { 4, 7 }, { 12, 7 }, { 241, 7 }, { 31, 7 }, + { 114, 9 }, { 158, 9 }, { 100, 9 }, { 172, 9 }, { 6, 8 }, + { 10, 8 }, { 209, 8 }, { 63, 8 }, { 19, 8 }, { 253, 8 }, + { 49, 8 }, { 223, 8 }, { 195, 8 }, { 77, 8 }, { 212, 8 }, + { 60, 8 }, { 198, 9 }, { 74, 9 }, { 70, 9 }, { 202, 9 }, + { 82, 8 }, { 190, 8 }, { 243, 8 }, { 29, 8 }, { 146, 9 }, + { 126, 9 }, { 118, 10 }, { 154, 10 }, { 167, 10 }, { 105, 10 }, + { 178, 8 }, { 94, 8 }, { 67, 8 }, { 205, 8 }, { 85, 9 }, + { 187, 9 }, { 181, 9 }, { 91, 9 }, { 52, 8 }, { 220, 8 }, + { 150, 10 }, { 122, 10 }, { 103, 10 }, { 169, 10 }, { 231, 9 }, + { 41, 9 }, { 229, 8 }, { 43, 8 }, { 48, 8 }, { 208, 8 }, + { 37, 8 }, { 235, 8 }, { 34, 8 }, { 238, 8 }, { 226, 8 }, + { 46, 8 }, { 39, 9 }, { 233, 9 }, { 145, 9 }, { 127, 9 }, + /* Coefficient table A.4.3 - 225 entries */ + { 246, 8 }, { 26, 8 }, { 22, 8 }, { 250, 8 }, { 210, 7 }, + { 62, 7 }, { 50, 7 }, { 222, 7 }, { 53, 8 }, { 219, 8 }, + { 231, 9 }, { 41, 9 }, { 39, 9 }, { 233, 9 }, { 16, 5 }, + { 240, 5 }, { 0, 4 }, { 227, 7 }, { 45, 7 }, { 35, 7 }, + { 237, 7 }, { 196, 8 }, { 76, 8 }, { 151, 10 }, { 121, 10 }, + { 119, 10 }, { 153, 10 }, { 150, 10 }, { 122, 10 }, { 167, 10 }, + { 105, 10 }, { 118, 10 }, { 154, 10 }, { 103, 10 }, { 169, 10 }, + { 117, 10 }, { 155, 10 }, { 149, 10 }, { 123, 10 }, { 96, 8 }, + { 160, 8 }, { 166, 10 }, { 106, 10 }, { 183, 10 }, { 89, 10 }, + { 87, 10 }, { 185, 10 }, { 102, 10 }, { 170, 10 }, { 71, 10 }, + { 201, 10 }, { 116, 10 }, { 156, 10 }, { 148, 10 }, { 124, 10 }, + { 199, 10 }, { 73, 10 }, { 182, 10 }, { 90, 10 }, { 165, 10 }, + { 107, 10 }, { 181, 9 }, { 91, 9 }, { 68, 8 }, { 204, 8 }, + { 85, 9 }, { 187, 9 }, { 113, 9 }, { 159, 9 }, { 6, 8 }, + { 10, 8 }, { 65, 7 }, { 207, 7 }, { 32, 6 }, { 224, 6 }, + { 2, 6 }, { 14, 6 }, { 193, 7 }, { 79, 7 }, { 145, 9 }, + { 127, 9 }, { 163, 9 }, { 109, 9 }, { 99, 9 }, { 173, 9 }, + { 247, 9 }, { 25, 9 }, { 20, 7 }, { 252, 7 }, { 244, 7 }, + { 28, 7 }, { 178, 8 }, { 94, 8 }, { 82, 8 }, { 190, 8 }, + { 23, 9 }, { 249, 9 }, { 54, 9 }, { 218, 9 }, { 214, 9 }, + { 58, 9 }, { 112, 9 }, { 144, 9 }, { 49, 7 }, { 223, 7 }, + { 209, 7 }, { 63, 7 }, { 37, 8 }, { 235, 8 }, { 229, 8 }, + { 43, 8 }, { 19, 7 }, { 253, 7 }, { 243, 7 }, { 29, 7 }, + { 64, 7 }, { 192, 7 }, { 195, 8 }, { 77, 8 }, { 67, 8 }, + { 205, 8 }, { 212, 8 }, { 60, 8 }, { 52, 8 }, { 220, 8 }, + { 7, 9 }, { 9, 9 }, { 180, 9 }, { 92, 9 }, { 197, 9 }, + { 75, 9 }, { 84, 9 }, { 188, 9 }, { 4, 7 }, { 12, 7 }, + { 48, 7 }, { 208, 7 }, { 34, 7 }, { 238, 7 }, { 226, 7 }, + { 46, 7 }, { 101, 10 }, { 171, 10 }, { 86, 10 }, { 186, 10 }, + { 69, 9 }, { 203, 9 }, { 211, 8 }, { 61, 8 }, { 17, 6 }, + { 255, 6 }, { 241, 6 }, { 31, 6 }, { 3, 7 }, { 13, 7 }, + { 51, 8 }, { 221, 8 }, { 98, 9 }, { 174, 9 }, { 162, 9 }, + { 110, 9 }, { 177, 8 }, { 95, 8 }, { 81, 8 }, { 191, 8 }, + { 38, 9 }, { 234, 9 }, { 230, 9 }, { 42, 9 }, { 21, 8 }, + { 251, 8 }, { 245, 8 }, { 27, 8 }, { 115, 10 }, { 157, 10 }, + { 55, 10 }, { 217, 10 }, { 147, 10 }, { 125, 10 }, { 215, 10 }, + { 57, 10 }, { 80, 8 }, { 176, 8 }, { 66, 8 }, { 206, 8 }, + { 194, 8 }, { 78, 8 }, { 97, 9 }, { 175, 9 }, { 161, 9 }, + { 111, 9 }, { 5, 8 }, { 11, 8 }, { 228, 8 }, { 44, 8 }, + { 36, 8 }, { 236, 8 }, { 114, 10 }, { 158, 10 }, { 100, 10 }, + { 172, 10 }, { 83, 9 }, { 189, 9 }, { 33, 7 }, { 239, 7 }, + { 164, 10 }, { 108, 10 }, { 198, 10 }, { 74, 10 }, { 179, 9 }, + { 93, 9 }, { 70, 10 }, { 202, 10 }, { 146, 10 }, { 126, 10 }, + { 213, 9 }, { 59, 9 }, { 18, 7 }, { 254, 7 }, { 225, 7 }, + { 47, 7 }, { 242, 7 }, { 30, 7 }, { 1, 6 }, { 15, 6 }, + /* Coefficient table A.4.4 - 225 entries */ + { 193, 7 }, { 79, 7 }, { 20, 7 }, { 252, 7 }, { 151, 10 }, + { 121, 10 }, { 119, 10 }, { 153, 10 }, { 118, 10 }, { 154, 10 }, + { 150, 10 }, { 122, 10 }, { 167, 10 }, { 105, 10 }, { 103, 10 }, + { 169, 10 }, { 117, 10 }, { 155, 10 }, { 149, 10 }, { 123, 10 }, + { 244, 7 }, { 28, 7 }, { 87, 10 }, { 185, 10 }, { 183, 10 }, + { 89, 10 }, { 166, 10 }, { 106, 10 }, { 102, 10 }, { 170, 10 }, + { 71, 10 }, { 201, 10 }, { 148, 10 }, { 124, 10 }, { 199, 10 }, + { 73, 10 }, { 116, 10 }, { 156, 10 }, { 165, 10 }, { 107, 10 }, + { 182, 10 }, { 90, 10 }, { 86, 10 }, { 186, 10 }, { 115, 10 }, + { 157, 10 }, { 101, 10 }, { 171, 10 }, { 147, 10 }, { 125, 10 }, + { 55, 10 }, { 217, 10 }, { 215, 10 }, { 57, 10 }, { 114, 10 }, + { 158, 10 }, { 146, 10 }, { 126, 10 }, { 164, 10 }, { 108, 10 }, + { 39, 10 }, { 233, 10 }, { 100, 10 }, { 172, 10 }, { 231, 10 }, + { 41, 10 }, { 198, 10 }, { 74, 10 }, { 70, 10 }, { 202, 10 }, + { 145, 10 }, { 127, 10 }, { 181, 10 }, { 91, 10 }, { 85, 10 }, + { 187, 10 }, { 113, 10 }, { 159, 10 }, { 247, 10 }, { 25, 10 }, + { 112, 10 }, { 144, 10 }, { 23, 10 }, { 249, 10 }, { 7, 10 }, + { 9, 10 }, { 99, 10 }, { 173, 10 }, { 54, 10 }, { 218, 10 }, + { 163, 10 }, { 109, 10 }, { 214, 10 }, { 58, 10 }, { 197, 10 }, + { 75, 10 }, { 84, 10 }, { 188, 10 }, { 98, 10 }, { 174, 10 }, + { 69, 10 }, { 203, 10 }, { 67, 8 }, { 205, 8 }, { 180, 10 }, + { 92, 10 }, { 162, 10 }, { 110, 10 }, { 97, 9 }, { 175, 9 }, + { 81, 8 }, { 191, 8 }, { 177, 8 }, { 95, 8 }, { 210, 7 }, + { 62, 7 }, { 212, 8 }, { 60, 8 }, { 195, 8 }, { 77, 8 }, + { 35, 7 }, { 237, 7 }, { 64, 7 }, { 192, 7 }, { 50, 7 }, + { 222, 7 }, { 227, 7 }, { 45, 7 }, { 52, 8 }, { 220, 8 }, + { 21, 8 }, { 251, 8 }, { 4, 7 }, { 12, 7 }, { 245, 8 }, + { 27, 8 }, { 161, 9 }, { 111, 9 }, { 22, 9 }, { 250, 9 }, + { 225, 6 }, { 47, 6 }, { 33, 6 }, { 239, 6 }, { 18, 6 }, + { 254, 6 }, { 242, 6 }, { 30, 6 }, { 80, 8 }, { 176, 8 }, + { 246, 9 }, { 26, 9 }, { 96, 9 }, { 160, 9 }, { 5, 8 }, + { 11, 8 }, { 6, 9 }, { 10, 9 }, { 179, 9 }, { 93, 9 }, + { 83, 9 }, { 189, 9 }, { 53, 9 }, { 219, 9 }, { 213, 9 }, + { 59, 9 }, { 196, 9 }, { 76, 9 }, { 49, 7 }, { 223, 7 }, + { 16, 5 }, { 240, 5 }, { 1, 5 }, { 15, 5 }, { 0, 4 }, + { 209, 7 }, { 63, 7 }, { 19, 7 }, { 253, 7 }, { 32, 6 }, + { 224, 6 }, { 2, 6 }, { 14, 6 }, { 243, 7 }, { 29, 7 }, + { 51, 8 }, { 221, 8 }, { 211, 8 }, { 61, 8 }, { 66, 8 }, + { 206, 8 }, { 194, 8 }, { 78, 8 }, { 228, 8 }, { 44, 8 }, + { 36, 8 }, { 236, 8 }, { 48, 7 }, { 208, 7 }, { 3, 7 }, + { 13, 7 }, { 68, 9 }, { 204, 9 }, { 82, 9 }, { 190, 9 }, + { 178, 9 }, { 94, 9 }, { 37, 9 }, { 235, 9 }, { 34, 7 }, + { 238, 7 }, { 226, 7 }, { 46, 7 }, { 229, 9 }, { 43, 9 }, + { 38, 10 }, { 234, 10 }, { 230, 10 }, { 42, 10 }, { 65, 8 }, + { 207, 8 }, { 17, 6 }, { 255, 6 }, { 241, 6 }, { 31, 6 }, + /* Coefficient table A.5.1 - 31 entries */ + { 8, 4 }, { 24, 4 }, { 15, 5 }, { 17, 5 }, { 4, 5 }, + { 28, 5 }, { 9, 4 }, { 23, 4 }, { 14, 5 }, { 18, 5 }, + { 3, 5 }, { 29, 5 }, { 13, 5 }, { 19, 5 }, { 2, 5 }, + { 30, 5 }, { 12, 5 }, { 20, 5 }, { 1, 5 }, { 31, 5 }, + { 7, 6 }, { 25, 6 }, { 0, 5 }, { 11, 5 }, { 21, 5 }, + { 6, 6 }, { 26, 6 }, { 5, 6 }, { 27, 6 }, { 10, 5 }, + { 22, 5 }, + /* Coefficient table A.5.2 - 31 entries */ + { 2, 4 }, { 30, 4 }, { 11, 5 }, { 21, 5 }, { 7, 5 }, + { 25, 5 }, { 1, 4 }, { 31, 4 }, { 6, 5 }, { 26, 5 }, + { 10, 5 }, { 22, 5 }, { 15, 6 }, { 17, 6 }, { 14, 6 }, + { 18, 6 }, { 0, 4 }, { 5, 5 }, { 27, 5 }, { 9, 5 }, + { 23, 5 }, { 8, 5 }, { 24, 5 }, { 4, 5 }, { 28, 5 }, + { 13, 6 }, { 19, 6 }, { 12, 6 }, { 20, 6 }, { 3, 5 }, + { 29, 5 }, + /* Coefficient table A.5.3 - 31 entries */ + { 0, 3 }, { 9, 5 }, { 23, 5 }, { 7, 5 }, { 25, 5 }, + { 3, 4 }, { 29, 4 }, { 8, 5 }, { 24, 5 }, { 15, 7 }, + { 17, 7 }, { 14, 7 }, { 18, 7 }, { 11, 6 }, { 21, 6 }, + { 2, 4 }, { 30, 4 }, { 6, 5 }, { 26, 5 }, { 5, 5 }, + { 27, 5 }, { 1, 4 }, { 31, 4 }, { 10, 6 }, { 22, 6 }, + { 13, 7 }, { 19, 7 }, { 12, 7 }, { 20, 7 }, { 4, 5 }, + { 28, 5 }, + /* Coefficient table A.5.4 - 31 entries */ + { 8, 5 }, { 24, 5 }, { 7, 5 }, { 25, 5 }, { 4, 4 }, + { 28, 4 }, { 0, 3 }, { 10, 6 }, { 22, 6 }, { 13, 7 }, + { 19, 7 }, { 12, 7 }, { 20, 7 }, { 6, 5 }, { 26, 5 }, + { 3, 4 }, { 29, 4 }, { 2, 4 }, { 30, 4 }, { 9, 6 }, + { 23, 6 }, { 15, 8 }, { 17, 8 }, { 14, 8 }, { 18, 8 }, + { 11, 7 }, { 21, 7 }, { 5, 5 }, { 27, 5 }, { 1, 4 }, + { 31, 4 }, + /* Coefficient table A.6.1 - 63 entries */ + { 19, 5 }, { 45, 5 }, { 31, 6 }, { 33, 6 }, { 30, 6 }, + { 34, 6 }, { 16, 5 }, { 48, 5 }, { 8, 6 }, { 56, 6 }, + { 7, 6 }, { 57, 6 }, { 18, 5 }, { 46, 5 }, { 29, 6 }, + { 35, 6 }, { 28, 6 }, { 36, 6 }, { 6, 6 }, { 58, 6 }, + { 27, 6 }, { 37, 6 }, { 17, 5 }, { 47, 5 }, { 5, 6 }, + { 59, 6 }, { 26, 6 }, { 38, 6 }, { 4, 6 }, { 60, 6 }, + { 25, 6 }, { 39, 6 }, { 3, 6 }, { 61, 6 }, { 2, 6 }, + { 62, 6 }, { 24, 6 }, { 40, 6 }, { 15, 7 }, { 49, 7 }, + { 14, 7 }, { 50, 7 }, { 1, 6 }, { 63, 6 }, { 23, 6 }, + { 41, 6 }, { 13, 7 }, { 51, 7 }, { 0, 6 }, { 22, 6 }, + { 42, 6 }, { 12, 7 }, { 52, 7 }, { 11, 7 }, { 53, 7 }, + { 21, 6 }, { 43, 6 }, { 20, 6 }, { 44, 6 }, { 10, 7 }, + { 54, 7 }, { 9, 7 }, { 55, 7 }, + /* Coefficient table A.6.2 - 63 entries */ + { 23, 6 }, { 41, 6 }, { 15, 6 }, { 49, 6 }, { 4, 5 }, + { 60, 5 }, { 3, 5 }, { 61, 5 }, { 22, 6 }, { 42, 6 }, + { 14, 6 }, { 50, 6 }, { 2, 5 }, { 62, 5 }, { 31, 7 }, + { 33, 7 }, { 30, 7 }, { 34, 7 }, { 21, 6 }, { 43, 6 }, + { 13, 6 }, { 51, 6 }, { 12, 6 }, { 52, 6 }, { 1, 5 }, + { 63, 5 }, { 20, 6 }, { 44, 6 }, { 29, 7 }, { 35, 7 }, + { 28, 7 }, { 36, 7 }, { 11, 6 }, { 53, 6 }, { 19, 6 }, + { 45, 6 }, { 0, 5 }, { 10, 6 }, { 54, 6 }, { 18, 6 }, + { 46, 6 }, { 27, 7 }, { 37, 7 }, { 26, 7 }, { 38, 7 }, + { 9, 6 }, { 55, 6 }, { 16, 6 }, { 48, 6 }, { 8, 6 }, + { 56, 6 }, { 17, 6 }, { 47, 6 }, { 7, 6 }, { 57, 6 }, + { 25, 7 }, { 39, 7 }, { 24, 7 }, { 40, 7 }, { 6, 6 }, + { 58, 6 }, { 5, 6 }, { 59, 6 }, + /* Coefficient table A.6.3 - 63 entries */ + { 0, 4 }, { 7, 5 }, { 57, 5 }, { 15, 6 }, { 49, 6 }, + { 25, 7 }, { 39, 7 }, { 24, 7 }, { 40, 7 }, { 18, 6 }, + { 46, 6 }, { 14, 6 }, { 50, 6 }, { 6, 5 }, { 58, 5 }, + { 5, 5 }, { 59, 5 }, { 31, 8 }, { 33, 8 }, { 30, 8 }, + { 34, 8 }, { 23, 7 }, { 41, 7 }, { 17, 6 }, { 47, 6 }, + { 13, 6 }, { 51, 6 }, { 16, 6 }, { 48, 6 }, { 4, 5 }, + { 60, 5 }, { 12, 6 }, { 52, 6 }, { 22, 7 }, { 42, 7 }, + { 29, 8 }, { 35, 8 }, { 28, 8 }, { 36, 8 }, { 3, 5 }, + { 61, 5 }, { 11, 6 }, { 53, 6 }, { 10, 6 }, { 54, 6 }, + { 2, 5 }, { 62, 5 }, { 21, 7 }, { 43, 7 }, { 20, 7 }, + { 44, 7 }, { 9, 6 }, { 55, 6 }, { 1, 5 }, { 63, 5 }, + { 27, 8 }, { 37, 8 }, { 26, 8 }, { 38, 8 }, { 19, 7 }, + { 45, 7 }, { 8, 6 }, { 56, 6 }, + /* Coefficient table A.6.4 - 63 entries */ + { 16, 6 }, { 48, 6 }, { 27, 8 }, { 37, 8 }, { 26, 8 }, + { 38, 8 }, { 21, 7 }, { 43, 7 }, { 8, 5 }, { 56, 5 }, + { 1, 4 }, { 63, 4 }, { 14, 6 }, { 50, 6 }, { 20, 7 }, + { 44, 7 }, { 31, 9 }, { 33, 9 }, { 30, 9 }, { 34, 9 }, + { 25, 8 }, { 39, 8 }, { 7, 5 }, { 57, 5 }, { 0, 4 }, + { 6, 5 }, { 58, 5 }, { 13, 6 }, { 51, 6 }, { 12, 6 }, + { 52, 6 }, { 5, 5 }, { 59, 5 }, { 19, 7 }, { 45, 7 }, + { 24, 8 }, { 40, 8 }, { 29, 9 }, { 35, 9 }, { 28, 9 }, + { 36, 9 }, { 11, 6 }, { 53, 6 }, { 4, 5 }, { 60, 5 }, + { 18, 7 }, { 46, 7 }, { 23, 8 }, { 41, 8 }, { 22, 8 }, + { 42, 8 }, { 10, 6 }, { 54, 6 }, { 3, 5 }, { 61, 5 }, + { 2, 5 }, { 62, 5 }, { 17, 7 }, { 47, 7 }, { 15, 7 }, + { 49, 7 }, { 9, 6 }, { 55, 6 }, + /* Coefficient table A.7.1 - 127 entries */ + { 18, 7 }, { 110, 7 }, { 63, 7 }, { 65, 7 }, { 38, 6 }, + { 90, 6 }, { 17, 7 }, { 111, 7 }, { 62, 7 }, { 66, 7 }, + { 61, 7 }, { 67, 7 }, { 16, 7 }, { 112, 7 }, { 37, 6 }, + { 91, 6 }, { 60, 7 }, { 68, 7 }, { 15, 7 }, { 113, 7 }, + { 32, 6 }, { 96, 6 }, { 59, 7 }, { 69, 7 }, { 14, 7 }, + { 114, 7 }, { 36, 6 }, { 92, 6 }, { 58, 7 }, { 70, 7 }, + { 13, 7 }, { 115, 7 }, { 57, 7 }, { 71, 7 }, { 12, 7 }, + { 116, 7 }, { 35, 6 }, { 93, 6 }, { 56, 7 }, { 72, 7 }, + { 55, 7 }, { 73, 7 }, { 11, 7 }, { 117, 7 }, { 10, 7 }, + { 118, 7 }, { 34, 6 }, { 94, 6 }, { 54, 7 }, { 74, 7 }, + { 9, 7 }, { 119, 7 }, { 33, 6 }, { 95, 6 }, { 53, 7 }, + { 75, 7 }, { 52, 7 }, { 76, 7 }, { 8, 7 }, { 120, 7 }, + { 51, 7 }, { 77, 7 }, { 50, 7 }, { 78, 7 }, { 7, 7 }, + { 121, 7 }, { 5, 7 }, { 123, 7 }, { 6, 7 }, { 122, 7 }, + { 49, 7 }, { 79, 7 }, { 4, 7 }, { 124, 7 }, { 31, 8 }, + { 97, 8 }, { 30, 8 }, { 98, 8 }, { 48, 7 }, { 80, 7 }, + { 3, 7 }, { 125, 7 }, { 29, 8 }, { 99, 8 }, { 28, 8 }, + { 100, 8 }, { 47, 7 }, { 81, 7 }, { 2, 7 }, { 126, 7 }, + { 46, 7 }, { 82, 7 }, { 1, 7 }, { 127, 7 }, { 27, 8 }, + { 101, 8 }, { 26, 8 }, { 102, 8 }, { 45, 7 }, { 83, 7 }, + { 0, 7 }, { 25, 8 }, { 103, 8 }, { 44, 7 }, { 84, 7 }, + { 24, 8 }, { 104, 8 }, { 23, 8 }, { 105, 8 }, { 43, 7 }, + { 85, 7 }, { 42, 7 }, { 86, 7 }, { 22, 8 }, { 106, 8 }, + { 21, 8 }, { 107, 8 }, { 41, 7 }, { 87, 7 }, { 20, 8 }, + { 108, 8 }, { 19, 8 }, { 109, 8 }, { 40, 7 }, { 88, 7 }, + { 39, 7 }, { 89, 7 }, + /* Coefficient table A.7.2 - 127 entries */ + { 47, 7 }, { 81, 7 }, { 46, 7 }, { 82, 7 }, { 8, 6 }, + { 120, 6 }, { 31, 7 }, { 97, 7 }, { 45, 7 }, { 83, 7 }, + { 7, 6 }, { 121, 6 }, { 30, 7 }, { 98, 7 }, { 29, 7 }, + { 99, 7 }, { 6, 6 }, { 122, 6 }, { 63, 8 }, { 65, 8 }, + { 62, 8 }, { 66, 8 }, { 44, 7 }, { 84, 7 }, { 5, 6 }, + { 123, 6 }, { 28, 7 }, { 100, 7 }, { 43, 7 }, { 85, 7 }, + { 4, 6 }, { 124, 6 }, { 27, 7 }, { 101, 7 }, { 26, 7 }, + { 102, 7 }, { 42, 7 }, { 86, 7 }, { 61, 8 }, { 67, 8 }, + { 60, 8 }, { 68, 8 }, { 3, 6 }, { 125, 6 }, { 25, 7 }, + { 103, 7 }, { 41, 7 }, { 87, 7 }, { 2, 6 }, { 126, 6 }, + { 24, 7 }, { 104, 7 }, { 59, 8 }, { 69, 8 }, { 58, 8 }, + { 70, 8 }, { 40, 7 }, { 88, 7 }, { 23, 7 }, { 105, 7 }, + { 39, 7 }, { 89, 7 }, { 22, 7 }, { 106, 7 }, { 1, 6 }, + { 127, 6 }, { 57, 8 }, { 71, 8 }, { 56, 8 }, { 72, 8 }, + { 21, 7 }, { 107, 7 }, { 38, 7 }, { 90, 7 }, { 20, 7 }, + { 108, 7 }, { 0, 6 }, { 55, 8 }, { 73, 8 }, { 54, 8 }, + { 74, 8 }, { 37, 7 }, { 91, 7 }, { 19, 7 }, { 109, 7 }, + { 18, 7 }, { 110, 7 }, { 36, 7 }, { 92, 7 }, { 53, 8 }, + { 75, 8 }, { 52, 8 }, { 76, 8 }, { 17, 7 }, { 111, 7 }, + { 35, 7 }, { 93, 7 }, { 32, 7 }, { 96, 7 }, { 16, 7 }, + { 112, 7 }, { 15, 7 }, { 113, 7 }, { 34, 7 }, { 94, 7 }, + { 51, 8 }, { 77, 8 }, { 50, 8 }, { 78, 8 }, { 14, 7 }, + { 114, 7 }, { 13, 7 }, { 115, 7 }, { 33, 7 }, { 95, 7 }, + { 12, 7 }, { 116, 7 }, { 49, 8 }, { 79, 8 }, { 48, 8 }, + { 80, 8 }, { 11, 7 }, { 117, 7 }, { 10, 7 }, { 118, 7 }, + { 9, 7 }, { 119, 7 }, + /* Coefficient table A.7.3 - 127 entries */ + { 15, 6 }, { 113, 6 }, { 31, 7 }, { 97, 7 }, { 51, 8 }, + { 77, 8 }, { 50, 8 }, { 78, 8 }, { 14, 6 }, { 114, 6 }, + { 0, 5 }, { 37, 7 }, { 91, 7 }, { 30, 7 }, { 98, 7 }, + { 13, 6 }, { 115, 6 }, { 29, 7 }, { 99, 7 }, { 49, 8 }, + { 79, 8 }, { 63, 9 }, { 65, 9 }, { 62, 9 }, { 66, 9 }, + { 12, 6 }, { 116, 6 }, { 36, 7 }, { 92, 7 }, { 28, 7 }, + { 100, 7 }, { 35, 7 }, { 93, 7 }, { 48, 8 }, { 80, 8 }, + { 47, 8 }, { 81, 8 }, { 11, 6 }, { 117, 6 }, { 10, 6 }, + { 118, 6 }, { 27, 7 }, { 101, 7 }, { 34, 7 }, { 94, 7 }, + { 61, 9 }, { 67, 9 }, { 60, 9 }, { 68, 9 }, { 46, 8 }, + { 82, 8 }, { 26, 7 }, { 102, 7 }, { 9, 6 }, { 119, 6 }, + { 32, 7 }, { 96, 7 }, { 33, 7 }, { 95, 7 }, { 8, 6 }, + { 120, 6 }, { 25, 7 }, { 103, 7 }, { 45, 8 }, { 83, 8 }, + { 59, 9 }, { 69, 9 }, { 58, 9 }, { 70, 9 }, { 7, 6 }, + { 121, 6 }, { 24, 7 }, { 104, 7 }, { 23, 7 }, { 105, 7 }, + { 6, 6 }, { 122, 6 }, { 44, 8 }, { 84, 8 }, { 57, 9 }, + { 71, 9 }, { 56, 9 }, { 72, 9 }, { 22, 7 }, { 106, 7 }, + { 5, 6 }, { 123, 6 }, { 43, 8 }, { 85, 8 }, { 42, 8 }, + { 86, 8 }, { 21, 7 }, { 107, 7 }, { 4, 6 }, { 124, 6 }, + { 20, 7 }, { 108, 7 }, { 55, 9 }, { 73, 9 }, { 54, 9 }, + { 74, 9 }, { 41, 8 }, { 87, 8 }, { 3, 6 }, { 125, 6 }, + { 19, 7 }, { 109, 7 }, { 18, 7 }, { 110, 7 }, { 2, 6 }, + { 126, 6 }, { 40, 8 }, { 88, 8 }, { 53, 9 }, { 75, 9 }, + { 52, 9 }, { 76, 9 }, { 17, 7 }, { 111, 7 }, { 39, 8 }, + { 89, 8 }, { 38, 8 }, { 90, 8 }, { 16, 7 }, { 112, 7 }, + { 1, 6 }, { 127, 6 }, + /* Coefficient table A.7.4 - 127 entries */ + { 3, 5 }, { 125, 5 }, { 32, 7 }, { 96, 7 }, { 29, 7 }, + { 99, 7 }, { 16, 6 }, { 112, 6 }, { 2, 5 }, { 126, 5 }, + { 53, 9 }, { 75, 9 }, { 52, 9 }, { 76, 9 }, { 42, 8 }, + { 86, 8 }, { 28, 7 }, { 100, 7 }, { 15, 6 }, { 113, 6 }, + { 63, 10 }, { 65, 10 }, { 62, 10 }, { 66, 10 }, { 51, 9 }, + { 77, 9 }, { 41, 8 }, { 87, 8 }, { 27, 7 }, { 101, 7 }, + { 14, 6 }, { 114, 6 }, { 1, 5 }, { 127, 5 }, { 13, 6 }, + { 115, 6 }, { 0, 5 }, { 26, 7 }, { 102, 7 }, { 40, 8 }, + { 88, 8 }, { 50, 9 }, { 78, 9 }, { 61, 10 }, { 67, 10 }, + { 60, 10 }, { 68, 10 }, { 12, 6 }, { 116, 6 }, { 25, 7 }, + { 103, 7 }, { 39, 8 }, { 89, 8 }, { 49, 9 }, { 79, 9 }, + { 48, 9 }, { 80, 9 }, { 11, 6 }, { 117, 6 }, { 24, 7 }, + { 104, 7 }, { 38, 8 }, { 90, 8 }, { 59, 10 }, { 69, 10 }, + { 58, 10 }, { 70, 10 }, { 47, 9 }, { 81, 9 }, { 10, 6 }, + { 118, 6 }, { 9, 6 }, { 119, 6 }, { 23, 7 }, { 105, 7 }, + { 22, 7 }, { 106, 7 }, { 8, 6 }, { 120, 6 }, { 37, 8 }, + { 91, 8 }, { 36, 8 }, { 92, 8 }, { 21, 7 }, { 107, 7 }, + { 7, 6 }, { 121, 6 }, { 6, 6 }, { 122, 6 }, { 57, 10 }, + { 71, 10 }, { 56, 10 }, { 72, 10 }, { 46, 9 }, { 82, 9 }, + { 35, 8 }, { 93, 8 }, { 20, 7 }, { 108, 7 }, { 5, 6 }, + { 123, 6 }, { 19, 7 }, { 109, 7 }, { 45, 9 }, { 83, 9 }, + { 44, 9 }, { 84, 9 }, { 31, 8 }, { 97, 8 }, { 4, 6 }, + { 124, 6 }, { 34, 8 }, { 94, 8 }, { 55, 10 }, { 73, 10 }, + { 54, 10 }, { 74, 10 }, { 43, 9 }, { 85, 9 }, { 18, 7 }, + { 110, 7 }, { 30, 8 }, { 98, 8 }, { 33, 8 }, { 95, 8 }, + { 17, 7 }, { 111, 7 }, + /* Coefficient table B.2.2 - 80 entries */ + { 80, 5 }, { 240, 5 }, { 253, 10 }, { 87, 10 }, { 117, 10 }, + { 223, 10 }, { 93, 10 }, { 247, 10 }, { 221, 10 }, { 119, 10 }, + { 213, 10 }, { 127, 10 }, { 85, 10 }, { 255, 10 }, { 245, 10 }, + { 95, 10 }, { 81, 10 }, { 243, 10 }, { 17, 7 }, { 51, 7 }, + { 20, 6 }, { 60, 6 }, { 116, 9 }, { 220, 9 }, { 84, 9 }, + { 252, 9 }, { 68, 8 }, { 204, 8 }, { 212, 7 }, { 124, 7 }, + { 196, 6 }, { 76, 6 }, { 5, 5 }, { 15, 5 }, { 53, 7 }, + { 31, 7 }, { 61, 7 }, { 23, 7 }, { 52, 6 }, { 28, 6 }, + { 13, 5 }, { 7, 5 }, { 16, 4 }, { 48, 4 }, { 4, 4 }, + { 12, 4 }, { 49, 6 }, { 19, 6 }, { 244, 7 }, { 92, 7 }, + { 21, 9 }, { 63, 9 }, { 197, 9 }, { 79, 9 }, { 69, 10 }, + { 207, 10 }, { 205, 10 }, { 71, 10 }, { 241, 9 }, { 83, 9 }, + { 208, 6 }, { 112, 6 }, { 77, 9 }, { 199, 9 }, { 113, 9 }, + { 211, 9 }, { 29, 9 }, { 55, 9 }, { 209, 10 }, { 115, 10 }, + { 125, 10 }, { 215, 10 }, { 65, 8 }, { 195, 8 }, { 193, 8 }, + { 67, 8 }, { 64, 4 }, { 192, 4 }, { 1, 4 }, { 3, 4 }, + /* Coefficient table B.2.3 - 81 entries */ + { 16, 4 }, { 48, 4 }, { 4, 4 }, { 12, 4 }, { 64, 4 }, + { 192, 4 }, { 5, 6 }, { 15, 6 }, { 13, 6 }, { 7, 6 }, + { 212, 8 }, { 124, 8 }, { 213, 10 }, { 127, 10 }, { 93, 10 }, + { 247, 10 }, { 117, 10 }, { 223, 10 }, { 253, 10 }, { 87, 10 }, + { 21, 9 }, { 63, 9 }, { 221, 10 }, { 119, 10 }, { 81, 10 }, + { 243, 10 }, { 205, 10 }, { 71, 10 }, { 69, 10 }, { 207, 10 }, + { 245, 10 }, { 95, 10 }, { 209, 10 }, { 115, 10 }, { 125, 10 }, + { 215, 10 }, { 85, 10 }, { 255, 10 }, { 116, 10 }, { 220, 10 }, + { 241, 10 }, { 83, 10 }, { 77, 10 }, { 199, 10 }, { 84, 10 }, + { 252, 10 }, { 29, 9 }, { 55, 9 }, { 61, 8 }, { 23, 8 }, + { 53, 8 }, { 31, 8 }, { 1, 4 }, { 3, 4 }, { 193, 8 }, + { 67, 8 }, { 65, 8 }, { 195, 8 }, { 196, 7 }, { 76, 7 }, + { 49, 7 }, { 19, 7 }, { 20, 7 }, { 60, 7 }, { 52, 7 }, + { 28, 7 }, { 208, 7 }, { 112, 7 }, { 80, 7 }, { 240, 7 }, + { 113, 10 }, { 211, 10 }, { 197, 10 }, { 79, 10 }, { 68, 9 }, + { 204, 9 }, { 17, 9 }, { 51, 9 }, { 244, 9 }, { 92, 9 }, + { 0, 2 }, + /* Coefficient table B.2.4 - 81 entries */ + { 1, 4 }, { 3, 4 }, { 52, 7 }, { 28, 7 }, { 193, 8 }, + { 67, 8 }, { 213, 10 }, { 127, 10 }, { 253, 10 }, { 87, 10 }, + { 93, 10 }, { 247, 10 }, { 117, 10 }, { 223, 10 }, { 80, 7 }, + { 240, 7 }, { 196, 7 }, { 76, 7 }, { 208, 7 }, { 112, 7 }, + { 221, 10 }, { 119, 10 }, { 245, 10 }, { 95, 10 }, { 69, 10 }, + { 207, 10 }, { 85, 10 }, { 255, 10 }, { 209, 10 }, { 115, 10 }, + { 205, 10 }, { 71, 10 }, { 81, 10 }, { 243, 10 }, { 125, 10 }, + { 215, 10 }, { 5, 7 }, { 15, 7 }, { 116, 10 }, { 220, 10 }, + { 84, 10 }, { 252, 10 }, { 29, 10 }, { 55, 10 }, { 113, 10 }, + { 211, 10 }, { 241, 10 }, { 83, 10 }, { 21, 10 }, { 63, 10 }, + { 197, 10 }, { 79, 10 }, { 77, 10 }, { 199, 10 }, { 16, 5 }, + { 48, 5 }, { 4, 5 }, { 12, 5 }, { 49, 7 }, { 19, 7 }, + { 13, 7 }, { 7, 7 }, { 212, 10 }, { 124, 10 }, { 244, 10 }, + { 92, 10 }, { 68, 9 }, { 204, 9 }, { 53, 9 }, { 31, 9 }, + { 61, 9 }, { 23, 9 }, { 17, 9 }, { 51, 9 }, { 65, 9 }, + { 195, 9 }, { 20, 8 }, { 60, 8 }, { 64, 5 }, { 192, 5 }, + { 0, 1 }, + /* Coefficient table B.3.2 - 49 entries */ + { 58, 5 }, { 14, 5 }, { 59, 6 }, { 13, 6 }, { 19, 7 }, + { 53, 7 }, { 25, 7 }, { 47, 7 }, { 1, 4 }, { 7, 4 }, + { 0, 2 }, { 9, 6 }, { 63, 6 }, { 57, 6 }, { 15, 6 }, + { 24, 6 }, { 40, 6 }, { 17, 6 }, { 55, 6 }, { 42, 8 }, + { 30, 8 }, { 43, 9 }, { 29, 9 }, { 27, 9 }, { 45, 9 }, + { 41, 7 }, { 31, 7 }, { 3, 6 }, { 5, 6 }, { 8, 5 }, + { 56, 5 }, { 49, 6 }, { 23, 6 }, { 11, 7 }, { 61, 7 }, + { 26, 8 }, { 46, 8 }, { 51, 8 }, { 21, 8 }, { 16, 5 }, + { 48, 5 }, { 18, 7 }, { 54, 7 }, { 50, 7 }, { 22, 7 }, + { 10, 6 }, { 62, 6 }, { 2, 5 }, { 6, 5 }, + /* Coefficient table B.3.3 - 49 entries */ + { 57, 5 }, { 15, 5 }, { 9, 5 }, { 63, 5 }, { 59, 7 }, + { 13, 7 }, { 50, 7 }, { 22, 7 }, { 18, 7 }, { 54, 7 }, + { 51, 8 }, { 21, 8 }, { 27, 10 }, { 45, 10 }, { 43, 10 }, + { 29, 10 }, { 26, 9 }, { 46, 9 }, { 17, 6 }, { 55, 6 }, + { 49, 6 }, { 23, 6 }, { 8, 4 }, { 56, 4 }, { 16, 5 }, + { 48, 5 }, { 10, 6 }, { 62, 6 }, { 58, 6 }, { 14, 6 }, + { 1, 4 }, { 7, 4 }, { 2, 5 }, { 6, 5 }, { 25, 8 }, + { 47, 8 }, { 42, 9 }, { 30, 9 }, { 19, 9 }, { 53, 9 }, + { 24, 7 }, { 40, 7 }, { 41, 8 }, { 31, 8 }, { 11, 8 }, + { 61, 8 }, { 3, 7 }, { 5, 7 }, { 0, 2 }, + /* Coefficient table B.3.4 - 49 entries */ + { 0, 1 }, { 8, 4 }, { 56, 4 }, { 1, 4 }, { 7, 4 }, + { 59, 8 }, { 13, 8 }, { 27, 10 }, { 45, 10 }, { 43, 10 }, + { 29, 10 }, { 26, 10 }, { 46, 10 }, { 51, 10 }, { 21, 10 }, + { 18, 8 }, { 54, 8 }, { 50, 8 }, { 22, 8 }, { 16, 6 }, + { 48, 6 }, { 17, 7 }, { 55, 7 }, { 24, 8 }, { 40, 8 }, + { 19, 10 }, { 53, 10 }, { 42, 10 }, { 30, 10 }, { 25, 9 }, + { 47, 9 }, { 49, 7 }, { 23, 7 }, { 10, 7 }, { 62, 7 }, + { 2, 6 }, { 6, 6 }, { 58, 7 }, { 14, 7 }, { 11, 9 }, + { 61, 9 }, { 41, 9 }, { 31, 9 }, { 3, 8 }, { 5, 8 }, + { 9, 6 }, { 63, 6 }, { 57, 6 }, { 15, 6 }, + /* Coefficient table B.4.2 - 225 entries */ + { 33, 7 }, { 239, 7 }, { 36, 7 }, { 236, 7 }, { 119, 10 }, + { 153, 10 }, { 151, 10 }, { 121, 10 }, { 118, 10 }, { 154, 10 }, + { 167, 10 }, { 105, 10 }, { 247, 8 }, { 25, 8 }, { 112, 8 }, + { 144, 8 }, { 150, 10 }, { 122, 10 }, { 103, 10 }, { 169, 10 }, + { 87, 10 }, { 185, 10 }, { 183, 10 }, { 89, 10 }, { 53, 8 }, + { 219, 8 }, { 213, 8 }, { 59, 8 }, { 228, 7 }, { 44, 7 }, + { 225, 7 }, { 47, 7 }, { 166, 10 }, { 106, 10 }, { 102, 10 }, + { 170, 10 }, { 149, 10 }, { 123, 10 }, { 117, 10 }, { 155, 10 }, + { 114, 9 }, { 158, 9 }, { 165, 10 }, { 107, 10 }, { 148, 10 }, + { 124, 10 }, { 81, 7 }, { 191, 7 }, { 21, 7 }, { 251, 7 }, + { 64, 6 }, { 192, 6 }, { 242, 7 }, { 30, 7 }, { 116, 10 }, + { 156, 10 }, { 71, 10 }, { 201, 10 }, { 101, 10 }, { 171, 10 }, + { 199, 10 }, { 73, 10 }, { 19, 8 }, { 253, 8 }, { 18, 7 }, + { 254, 7 }, { 182, 10 }, { 90, 10 }, { 86, 10 }, { 186, 10 }, + { 39, 9 }, { 233, 9 }, { 34, 8 }, { 238, 8 }, { 2, 6 }, + { 14, 6 }, { 177, 7 }, { 95, 7 }, { 231, 9 }, { 41, 9 }, + { 146, 9 }, { 126, 9 }, { 67, 8 }, { 205, 8 }, { 17, 6 }, + { 255, 6 }, { 241, 6 }, { 31, 6 }, { 16, 5 }, { 240, 5 }, + { 243, 8 }, { 29, 8 }, { 195, 8 }, { 77, 8 }, { 245, 7 }, + { 27, 7 }, { 7, 8 }, { 9, 8 }, { 209, 8 }, { 63, 8 }, + { 99, 9 }, { 173, 9 }, { 163, 9 }, { 109, 9 }, { 226, 8 }, + { 46, 8 }, { 212, 8 }, { 60, 8 }, { 97, 8 }, { 175, 8 }, + { 161, 8 }, { 111, 8 }, { 52, 8 }, { 220, 8 }, { 180, 9 }, + { 92, 9 }, { 50, 9 }, { 222, 9 }, { 35, 9 }, { 237, 9 }, + { 211, 10 }, { 61, 10 }, { 51, 10 }, { 221, 10 }, { 210, 9 }, + { 62, 9 }, { 84, 9 }, { 188, 9 }, { 82, 8 }, { 190, 8 }, + { 4, 6 }, { 12, 6 }, { 227, 9 }, { 45, 9 }, { 214, 9 }, + { 58, 9 }, { 54, 9 }, { 218, 9 }, { 197, 9 }, { 75, 9 }, + { 178, 8 }, { 94, 8 }, { 22, 8 }, { 250, 8 }, { 65, 7 }, + { 207, 7 }, { 80, 7 }, { 176, 7 }, { 246, 8 }, { 26, 8 }, + { 69, 9 }, { 203, 9 }, { 145, 9 }, { 127, 9 }, { 193, 7 }, + { 79, 7 }, { 37, 8 }, { 235, 8 }, { 229, 8 }, { 43, 8 }, + { 5, 7 }, { 11, 7 }, { 20, 7 }, { 252, 7 }, { 244, 7 }, + { 28, 7 }, { 1, 5 }, { 15, 5 }, { 98, 9 }, { 174, 9 }, + { 147, 10 }, { 125, 10 }, { 115, 10 }, { 157, 10 }, { 96, 8 }, + { 160, 8 }, { 113, 9 }, { 159, 9 }, { 38, 9 }, { 234, 9 }, + { 162, 9 }, { 110, 9 }, { 55, 10 }, { 217, 10 }, { 215, 10 }, + { 57, 10 }, { 48, 8 }, { 208, 8 }, { 68, 9 }, { 204, 9 }, + { 164, 10 }, { 108, 10 }, { 100, 10 }, { 172, 10 }, { 32, 7 }, + { 224, 7 }, { 0, 4 }, { 3, 8 }, { 13, 8 }, { 23, 9 }, + { 249, 9 }, { 230, 9 }, { 42, 9 }, { 83, 9 }, { 189, 9 }, + { 181, 10 }, { 91, 10 }, { 198, 10 }, { 74, 10 }, { 6, 8 }, + { 10, 8 }, { 66, 8 }, { 206, 8 }, { 179, 9 }, { 93, 9 }, + { 70, 10 }, { 202, 10 }, { 85, 10 }, { 187, 10 }, { 194, 8 }, + { 78, 8 }, { 196, 9 }, { 76, 9 }, { 49, 9 }, { 223, 9 }, + /* Coefficient table B.4.3 - 225 entries */ + { 193, 7 }, { 79, 7 }, { 48, 7 }, { 208, 7 }, { 6, 8 }, + { 10, 8 }, { 151, 10 }, { 121, 10 }, { 119, 10 }, { 153, 10 }, + { 167, 10 }, { 105, 10 }, { 118, 10 }, { 154, 10 }, { 103, 10 }, + { 169, 10 }, { 150, 10 }, { 122, 10 }, { 102, 10 }, { 170, 10 }, + { 183, 10 }, { 89, 10 }, { 117, 10 }, { 155, 10 }, { 149, 10 }, + { 123, 10 }, { 166, 10 }, { 106, 10 }, { 87, 10 }, { 185, 10 }, + { 116, 10 }, { 156, 10 }, { 148, 10 }, { 124, 10 }, { 71, 10 }, + { 201, 10 }, { 199, 10 }, { 73, 10 }, { 165, 10 }, { 107, 10 }, + { 182, 10 }, { 90, 10 }, { 101, 10 }, { 171, 10 }, { 86, 10 }, + { 186, 10 }, { 20, 7 }, { 252, 7 }, { 55, 10 }, { 217, 10 }, + { 147, 10 }, { 125, 10 }, { 115, 10 }, { 157, 10 }, { 215, 10 }, + { 57, 10 }, { 100, 10 }, { 172, 10 }, { 181, 10 }, { 91, 10 }, + { 198, 10 }, { 74, 10 }, { 114, 10 }, { 158, 10 }, { 244, 7 }, + { 28, 7 }, { 70, 10 }, { 202, 10 }, { 164, 10 }, { 108, 10 }, + { 85, 10 }, { 187, 10 }, { 146, 10 }, { 126, 10 }, { 39, 10 }, + { 233, 10 }, { 231, 10 }, { 41, 10 }, { 53, 9 }, { 219, 9 }, + { 54, 10 }, { 218, 10 }, { 99, 10 }, { 173, 10 }, { 214, 10 }, + { 58, 10 }, { 163, 10 }, { 109, 10 }, { 197, 10 }, { 75, 10 }, + { 84, 10 }, { 188, 10 }, { 69, 10 }, { 203, 10 }, { 113, 10 }, + { 159, 10 }, { 180, 10 }, { 92, 10 }, { 145, 10 }, { 127, 10 }, + { 98, 10 }, { 174, 10 }, { 23, 10 }, { 249, 10 }, { 247, 10 }, + { 25, 10 }, { 162, 10 }, { 110, 10 }, { 38, 10 }, { 234, 10 }, + { 230, 10 }, { 42, 10 }, { 83, 10 }, { 189, 10 }, { 179, 10 }, + { 93, 10 }, { 211, 10 }, { 61, 10 }, { 112, 10 }, { 144, 10 }, + { 51, 10 }, { 221, 10 }, { 68, 10 }, { 204, 10 }, { 213, 10 }, + { 59, 10 }, { 196, 10 }, { 76, 10 }, { 3, 7 }, { 13, 7 }, + { 66, 8 }, { 206, 8 }, { 81, 8 }, { 191, 8 }, { 32, 6 }, + { 224, 6 }, { 0, 2 }, { 7, 9 }, { 9, 9 }, { 97, 9 }, + { 175, 9 }, { 36, 8 }, { 236, 8 }, { 194, 8 }, { 78, 8 }, + { 177, 8 }, { 95, 8 }, { 2, 6 }, { 14, 6 }, { 21, 8 }, + { 251, 8 }, { 245, 8 }, { 27, 8 }, { 228, 8 }, { 44, 8 }, + { 22, 9 }, { 250, 9 }, { 246, 9 }, { 26, 9 }, { 49, 8 }, + { 223, 8 }, { 19, 8 }, { 253, 8 }, { 209, 8 }, { 63, 8 }, + { 243, 8 }, { 29, 8 }, { 225, 7 }, { 47, 7 }, { 64, 7 }, + { 192, 7 }, { 33, 7 }, { 239, 7 }, { 18, 7 }, { 254, 7 }, + { 242, 7 }, { 30, 7 }, { 161, 9 }, { 111, 9 }, { 178, 9 }, + { 94, 9 }, { 82, 9 }, { 190, 9 }, { 195, 9 }, { 77, 9 }, + { 52, 9 }, { 220, 9 }, { 212, 9 }, { 60, 9 }, { 67, 9 }, + { 205, 9 }, { 37, 9 }, { 235, 9 }, { 34, 8 }, { 238, 8 }, + { 226, 8 }, { 46, 8 }, { 17, 6 }, { 255, 6 }, { 4, 7 }, + { 12, 7 }, { 80, 8 }, { 176, 8 }, { 229, 9 }, { 43, 9 }, + { 35, 9 }, { 237, 9 }, { 16, 5 }, { 240, 5 }, { 241, 6 }, + { 31, 6 }, { 227, 9 }, { 45, 9 }, { 210, 9 }, { 62, 9 }, + { 50, 9 }, { 222, 9 }, { 96, 9 }, { 160, 9 }, { 5, 8 }, + { 11, 8 }, { 65, 8 }, { 207, 8 }, { 1, 5 }, { 15, 5 }, + /* Coefficient table B.4.4 - 225 entries */ + { 3, 7 }, { 13, 7 }, { 4, 7 }, { 12, 7 }, { 151, 10 }, + { 121, 10 }, { 119, 10 }, { 153, 10 }, { 103, 10 }, { 169, 10 }, + { 167, 10 }, { 105, 10 }, { 150, 10 }, { 122, 10 }, { 118, 10 }, + { 154, 10 }, { 117, 10 }, { 155, 10 }, { 102, 10 }, { 170, 10 }, + { 5, 8 }, { 11, 8 }, { 183, 10 }, { 89, 10 }, { 87, 10 }, + { 185, 10 }, { 166, 10 }, { 106, 10 }, { 149, 10 }, { 123, 10 }, + { 17, 5 }, { 255, 5 }, { 1, 4 }, { 15, 4 }, { 241, 5 }, + { 31, 5 }, { 116, 10 }, { 156, 10 }, { 148, 10 }, { 124, 10 }, + { 199, 10 }, { 73, 10 }, { 182, 10 }, { 90, 10 }, { 71, 10 }, + { 201, 10 }, { 86, 10 }, { 186, 10 }, { 101, 10 }, { 171, 10 }, + { 115, 10 }, { 157, 10 }, { 165, 10 }, { 107, 10 }, { 215, 10 }, + { 57, 10 }, { 55, 10 }, { 217, 10 }, { 70, 10 }, { 202, 10 }, + { 147, 10 }, { 125, 10 }, { 85, 10 }, { 187, 10 }, { 164, 10 }, + { 108, 10 }, { 198, 10 }, { 74, 10 }, { 100, 10 }, { 172, 10 }, + { 114, 10 }, { 158, 10 }, { 39, 10 }, { 233, 10 }, { 146, 10 }, + { 126, 10 }, { 99, 10 }, { 173, 10 }, { 181, 10 }, { 91, 10 }, + { 231, 10 }, { 41, 10 }, { 163, 10 }, { 109, 10 }, { 54, 10 }, + { 218, 10 }, { 214, 10 }, { 58, 10 }, { 113, 10 }, { 159, 10 }, + { 23, 10 }, { 249, 10 }, { 145, 10 }, { 127, 10 }, { 180, 10 }, + { 92, 10 }, { 84, 10 }, { 188, 10 }, { 247, 10 }, { 25, 10 }, + { 32, 6 }, { 224, 6 }, { 197, 10 }, { 75, 10 }, { 98, 10 }, + { 174, 10 }, { 112, 10 }, { 144, 10 }, { 162, 10 }, { 110, 10 }, + { 69, 10 }, { 203, 10 }, { 38, 10 }, { 234, 10 }, { 230, 10 }, + { 42, 10 }, { 7, 10 }, { 9, 10 }, { 213, 10 }, { 59, 10 }, + { 83, 10 }, { 189, 10 }, { 179, 10 }, { 93, 10 }, { 53, 10 }, + { 219, 10 }, { 97, 10 }, { 175, 10 }, { 68, 10 }, { 204, 10 }, + { 196, 10 }, { 76, 10 }, { 161, 10 }, { 111, 10 }, { 22, 10 }, + { 250, 10 }, { 246, 10 }, { 26, 10 }, { 82, 10 }, { 190, 10 }, + { 96, 10 }, { 160, 10 }, { 178, 10 }, { 94, 10 }, { 37, 10 }, + { 235, 10 }, { 67, 10 }, { 205, 10 }, { 51, 10 }, { 221, 10 }, + { 229, 10 }, { 43, 10 }, { 6, 10 }, { 10, 10 }, { 211, 10 }, + { 61, 10 }, { 212, 10 }, { 60, 10 }, { 195, 10 }, { 77, 10 }, + { 52, 10 }, { 220, 10 }, { 81, 10 }, { 191, 10 }, { 177, 10 }, + { 95, 10 }, { 65, 8 }, { 207, 8 }, { 21, 10 }, { 251, 10 }, + { 245, 10 }, { 27, 10 }, { 194, 10 }, { 78, 10 }, { 228, 10 }, + { 44, 10 }, { 193, 8 }, { 79, 8 }, { 20, 8 }, { 252, 8 }, + { 0, 2 }, { 2, 6 }, { 14, 6 }, { 19, 8 }, { 253, 8 }, + { 49, 8 }, { 223, 8 }, { 209, 8 }, { 63, 8 }, { 244, 8 }, + { 28, 8 }, { 66, 10 }, { 206, 10 }, { 210, 10 }, { 62, 10 }, + { 36, 9 }, { 236, 9 }, { 243, 8 }, { 29, 8 }, { 33, 7 }, + { 239, 7 }, { 225, 7 }, { 47, 7 }, { 64, 8 }, { 192, 8 }, + { 80, 9 }, { 176, 9 }, { 50, 9 }, { 222, 9 }, { 18, 7 }, + { 254, 7 }, { 242, 7 }, { 30, 7 }, { 48, 8 }, { 208, 8 }, + { 226, 8 }, { 46, 8 }, { 34, 8 }, { 238, 8 }, { 227, 9 }, + { 45, 9 }, { 35, 9 }, { 237, 9 }, { 16, 5 }, { 240, 5 }, + /* Coefficient table B.5.2 - 31 entries */ + { 3, 4 }, { 29, 4 }, { 5, 5 }, { 27, 5 }, { 10, 5 }, + { 22, 5 }, { 13, 6 }, { 19, 6 }, { 7, 6 }, { 25, 6 }, + { 4, 5 }, { 28, 5 }, { 2, 4 }, { 30, 4 }, { 9, 5 }, + { 23, 5 }, { 12, 6 }, { 20, 6 }, { 15, 7 }, { 17, 7 }, + { 14, 7 }, { 18, 7 }, { 8, 5 }, { 24, 5 }, { 6, 6 }, + { 26, 6 }, { 11, 6 }, { 21, 6 }, { 0, 3 }, { 1, 4 }, + { 31, 4 }, + /* Coefficient table B.5.3 - 31 entries */ + { 1, 3 }, { 31, 3 }, { 7, 6 }, { 25, 6 }, { 13, 7 }, + { 19, 7 }, { 12, 7 }, { 20, 7 }, { 10, 6 }, { 22, 6 }, + { 6, 6 }, { 26, 6 }, { 2, 4 }, { 30, 4 }, { 0, 2 }, + { 4, 5 }, { 28, 5 }, { 15, 8 }, { 17, 8 }, { 14, 8 }, + { 18, 8 }, { 11, 7 }, { 21, 7 }, { 9, 6 }, { 23, 6 }, + { 3, 5 }, { 29, 5 }, { 8, 6 }, { 24, 6 }, { 5, 6 }, + { 27, 6 }, + /* Coefficient table B.5.4 - 31 entries */ + { 3, 4 }, { 29, 4 }, { 9, 6 }, { 23, 6 }, { 8, 6 }, + { 24, 6 }, { 13, 8 }, { 19, 8 }, { 12, 8 }, { 20, 8 }, + { 10, 7 }, { 22, 7 }, { 6, 6 }, { 26, 6 }, { 1, 3 }, + { 31, 3 }, { 2, 4 }, { 30, 4 }, { 4, 5 }, { 28, 5 }, + { 15, 9 }, { 17, 9 }, { 14, 9 }, { 18, 9 }, { 11, 8 }, + { 21, 8 }, { 7, 7 }, { 25, 7 }, { 5, 6 }, { 27, 6 }, + { 0, 2 }, + /* Coefficient table B.6.2 - 63 entries */ + { 11, 6 }, { 53, 6 }, { 21, 6 }, { 43, 6 }, { 27, 7 }, + { 37, 7 }, { 26, 7 }, { 38, 7 }, { 10, 6 }, { 54, 6 }, + { 5, 5 }, { 59, 5 }, { 20, 6 }, { 44, 6 }, { 9, 6 }, + { 55, 6 }, { 15, 7 }, { 49, 7 }, { 25, 7 }, { 39, 7 }, + { 19, 6 }, { 45, 6 }, { 4, 5 }, { 60, 5 }, { 1, 4 }, + { 63, 4 }, { 14, 7 }, { 50, 7 }, { 24, 7 }, { 40, 7 }, + { 8, 6 }, { 56, 6 }, { 18, 6 }, { 46, 6 }, { 31, 8 }, + { 33, 8 }, { 30, 8 }, { 34, 8 }, { 13, 7 }, { 51, 7 }, + { 3, 5 }, { 61, 5 }, { 23, 7 }, { 41, 7 }, { 12, 7 }, + { 52, 7 }, { 7, 6 }, { 57, 6 }, { 16, 6 }, { 48, 6 }, + { 17, 6 }, { 47, 6 }, { 0, 4 }, { 2, 5 }, { 62, 5 }, + { 22, 7 }, { 42, 7 }, { 29, 8 }, { 35, 8 }, { 28, 8 }, + { 36, 8 }, { 6, 6 }, { 58, 6 }, + /* Coefficient table B.6.3 - 63 entries */ + { 6, 5 }, { 58, 5 }, { 10, 6 }, { 54, 6 }, { 16, 6 }, + { 48, 6 }, { 17, 6 }, { 47, 6 }, { 21, 7 }, { 43, 7 }, + { 14, 7 }, { 50, 7 }, { 5, 5 }, { 59, 5 }, { 2, 4 }, + { 62, 4 }, { 9, 6 }, { 55, 6 }, { 25, 8 }, { 39, 8 }, + { 31, 9 }, { 33, 9 }, { 30, 9 }, { 34, 9 }, { 20, 7 }, + { 44, 7 }, { 8, 6 }, { 56, 6 }, { 13, 7 }, { 51, 7 }, + { 19, 7 }, { 45, 7 }, { 4, 5 }, { 60, 5 }, { 24, 8 }, + { 40, 8 }, { 29, 9 }, { 35, 9 }, { 28, 9 }, { 36, 9 }, + { 12, 7 }, { 52, 7 }, { 7, 6 }, { 57, 6 }, { 3, 5 }, + { 61, 5 }, { 18, 7 }, { 46, 7 }, { 23, 8 }, { 41, 8 }, + { 22, 8 }, { 42, 8 }, { 11, 7 }, { 53, 7 }, { 15, 8 }, + { 49, 8 }, { 27, 9 }, { 37, 9 }, { 26, 9 }, { 38, 9 }, + { 0, 3 }, { 1, 4 }, { 63, 4 }, + /* Coefficient table B.6.4 - 63 entries */ + { 1, 3 }, { 63, 3 }, { 14, 7 }, { 50, 7 }, { 18, 7 }, + { 46, 7 }, { 27, 9 }, { 37, 9 }, { 26, 9 }, { 38, 9 }, + { 21, 8 }, { 43, 8 }, { 13, 7 }, { 51, 7 }, { 9, 6 }, + { 55, 6 }, { 17, 7 }, { 47, 7 }, { 31, 10 }, { 33, 10 }, + { 30, 10 }, { 34, 10 }, { 25, 9 }, { 39, 9 }, { 20, 8 }, + { 44, 8 }, { 5, 5 }, { 59, 5 }, { 16, 7 }, { 48, 7 }, + { 12, 7 }, { 52, 7 }, { 8, 6 }, { 56, 6 }, { 2, 4 }, + { 62, 4 }, { 4, 5 }, { 60, 5 }, { 24, 9 }, { 40, 9 }, + { 29, 10 }, { 35, 10 }, { 28, 10 }, { 36, 10 }, { 15, 8 }, + { 49, 8 }, { 11, 7 }, { 53, 7 }, { 7, 6 }, { 57, 6 }, + { 19, 8 }, { 45, 8 }, { 23, 9 }, { 41, 9 }, { 22, 9 }, + { 42, 9 }, { 10, 7 }, { 54, 7 }, { 6, 6 }, { 58, 6 }, + { 3, 5 }, { 61, 5 }, { 0, 3 }, + /* Coefficient table B.7.2 - 127 entries */ + { 3, 5 }, { 125, 5 }, { 42, 7 }, { 86, 7 }, { 21, 7 }, + { 107, 7 }, { 11, 6 }, { 117, 6 }, { 41, 7 }, { 87, 7 }, + { 20, 7 }, { 108, 7 }, { 53, 8 }, { 75, 8 }, { 31, 8 }, + { 97, 8 }, { 40, 7 }, { 88, 7 }, { 52, 8 }, { 76, 8 }, + { 51, 8 }, { 77, 8 }, { 19, 7 }, { 109, 7 }, { 10, 6 }, + { 118, 6 }, { 30, 8 }, { 98, 8 }, { 29, 8 }, { 99, 8 }, + { 18, 7 }, { 110, 7 }, { 9, 6 }, { 119, 6 }, { 39, 7 }, + { 89, 7 }, { 17, 7 }, { 111, 7 }, { 28, 8 }, { 100, 8 }, + { 50, 8 }, { 78, 8 }, { 38, 7 }, { 90, 7 }, { 2, 5 }, + { 126, 5 }, { 8, 6 }, { 120, 6 }, { 49, 8 }, { 79, 8 }, + { 48, 8 }, { 80, 8 }, { 16, 7 }, { 112, 7 }, { 37, 7 }, + { 91, 7 }, { 63, 9 }, { 65, 9 }, { 62, 9 }, { 66, 9 }, + { 27, 8 }, { 101, 8 }, { 7, 6 }, { 121, 6 }, { 36, 7 }, + { 92, 7 }, { 26, 8 }, { 102, 8 }, { 47, 8 }, { 81, 8 }, + { 61, 9 }, { 67, 9 }, { 60, 9 }, { 68, 9 }, { 46, 8 }, + { 82, 8 }, { 15, 7 }, { 113, 7 }, { 6, 6 }, { 122, 6 }, + { 25, 8 }, { 103, 8 }, { 45, 8 }, { 83, 8 }, { 35, 7 }, + { 93, 7 }, { 1, 5 }, { 127, 5 }, { 14, 7 }, { 114, 7 }, + { 59, 9 }, { 69, 9 }, { 58, 9 }, { 70, 9 }, { 24, 8 }, + { 104, 8 }, { 5, 6 }, { 123, 6 }, { 32, 7 }, { 96, 7 }, + { 34, 7 }, { 94, 7 }, { 13, 7 }, { 115, 7 }, { 23, 8 }, + { 105, 8 }, { 44, 8 }, { 84, 8 }, { 4, 6 }, { 124, 6 }, + { 57, 9 }, { 71, 9 }, { 56, 9 }, { 72, 9 }, { 43, 8 }, + { 85, 8 }, { 12, 7 }, { 116, 7 }, { 0, 5 }, { 33, 7 }, + { 95, 7 }, { 22, 8 }, { 106, 8 }, { 55, 9 }, { 73, 9 }, + { 54, 9 }, { 74, 9 }, + /* Coefficient table B.7.3 - 127 entries */ + { 0, 3 }, { 4, 5 }, { 124, 5 }, { 19, 7 }, { 109, 7 }, + { 29, 8 }, { 99, 8 }, { 51, 9 }, { 77, 9 }, { 62, 10 }, + { 66, 10 }, { 63, 10 }, { 65, 10 }, { 28, 8 }, { 100, 8 }, + { 41, 8 }, { 87, 8 }, { 33, 7 }, { 95, 7 }, { 10, 6 }, + { 118, 6 }, { 18, 7 }, { 110, 7 }, { 40, 8 }, { 88, 8 }, + { 27, 8 }, { 101, 8 }, { 9, 6 }, { 119, 6 }, { 17, 7 }, + { 111, 7 }, { 50, 9 }, { 78, 9 }, { 61, 10 }, { 67, 10 }, + { 60, 10 }, { 68, 10 }, { 26, 8 }, { 102, 8 }, { 1, 4 }, + { 127, 4 }, { 3, 5 }, { 125, 5 }, { 39, 8 }, { 89, 8 }, + { 49, 9 }, { 79, 9 }, { 48, 9 }, { 80, 9 }, { 16, 7 }, + { 112, 7 }, { 8, 6 }, { 120, 6 }, { 25, 8 }, { 103, 8 }, + { 38, 8 }, { 90, 8 }, { 15, 7 }, { 113, 7 }, { 7, 6 }, + { 121, 6 }, { 59, 10 }, { 69, 10 }, { 58, 10 }, { 70, 10 }, + { 47, 9 }, { 81, 9 }, { 24, 8 }, { 104, 8 }, { 37, 8 }, + { 91, 8 }, { 23, 8 }, { 105, 8 }, { 14, 7 }, { 114, 7 }, + { 46, 9 }, { 82, 9 }, { 57, 10 }, { 71, 10 }, { 56, 10 }, + { 72, 10 }, { 36, 8 }, { 92, 8 }, { 2, 5 }, { 126, 5 }, + { 6, 6 }, { 122, 6 }, { 45, 9 }, { 83, 9 }, { 31, 9 }, + { 97, 9 }, { 22, 8 }, { 106, 8 }, { 13, 7 }, { 115, 7 }, + { 21, 8 }, { 107, 8 }, { 55, 10 }, { 73, 10 }, { 54, 10 }, + { 74, 10 }, { 44, 9 }, { 84, 9 }, { 12, 7 }, { 116, 7 }, + { 5, 6 }, { 123, 6 }, { 35, 8 }, { 93, 8 }, { 43, 9 }, + { 85, 9 }, { 30, 9 }, { 98, 9 }, { 20, 8 }, { 108, 8 }, + { 53, 10 }, { 75, 10 }, { 52, 10 }, { 76, 10 }, { 42, 9 }, + { 86, 9 }, { 34, 8 }, { 94, 8 }, { 32, 8 }, { 96, 8 }, + { 11, 7 }, { 117, 7 }, + /* Coefficient table B.7.4 - 127 entries */ + { 28, 8 }, { 100, 8 }, { 27, 8 }, { 101, 8 }, { 36, 8 }, + { 92, 8 }, { 63, 10 }, { 65, 10 }, { 61, 10 }, { 67, 10 }, + { 62, 10 }, { 66, 10 }, { 60, 10 }, { 68, 10 }, { 19, 7 }, + { 109, 7 }, { 59, 10 }, { 69, 10 }, { 58, 10 }, { 70, 10 }, + { 57, 10 }, { 71, 10 }, { 56, 10 }, { 72, 10 }, { 55, 10 }, + { 73, 10 }, { 53, 10 }, { 75, 10 }, { 54, 10 }, { 74, 10 }, + { 52, 10 }, { 76, 10 }, { 5, 5 }, { 123, 5 }, { 0, 3 }, + { 51, 10 }, { 77, 10 }, { 50, 10 }, { 78, 10 }, { 49, 10 }, + { 79, 10 }, { 48, 10 }, { 80, 10 }, { 47, 10 }, { 81, 10 }, + { 46, 10 }, { 82, 10 }, { 43, 9 }, { 85, 9 }, { 18, 7 }, + { 110, 7 }, { 11, 6 }, { 117, 6 }, { 26, 8 }, { 102, 8 }, + { 35, 8 }, { 93, 8 }, { 25, 8 }, { 103, 8 }, { 42, 9 }, + { 86, 9 }, { 41, 9 }, { 87, 9 }, { 10, 6 }, { 118, 6 }, + { 4, 5 }, { 124, 5 }, { 17, 7 }, { 111, 7 }, { 34, 8 }, + { 94, 8 }, { 24, 8 }, { 104, 8 }, { 9, 6 }, { 119, 6 }, + { 1, 4 }, { 127, 4 }, { 16, 7 }, { 112, 7 }, { 32, 8 }, + { 96, 8 }, { 33, 8 }, { 95, 8 }, { 23, 8 }, { 105, 8 }, + { 40, 9 }, { 88, 9 }, { 31, 9 }, { 97, 9 }, { 15, 7 }, + { 113, 7 }, { 8, 6 }, { 120, 6 }, { 39, 9 }, { 89, 9 }, + { 45, 10 }, { 83, 10 }, { 44, 10 }, { 84, 10 }, { 22, 8 }, + { 106, 8 }, { 14, 7 }, { 114, 7 }, { 3, 5 }, { 125, 5 }, + { 7, 6 }, { 121, 6 }, { 30, 9 }, { 98, 9 }, { 38, 9 }, + { 90, 9 }, { 21, 8 }, { 107, 8 }, { 13, 7 }, { 115, 7 }, + { 29, 9 }, { 99, 9 }, { 37, 9 }, { 91, 9 }, { 20, 8 }, + { 108, 8 }, { 12, 7 }, { 116, 7 }, { 6, 6 }, { 122, 6 }, + { 2, 5 }, { 126, 5 }, }; static const HuffmanCodebook at9_huffman_coeffs[][8][4] = { @@ -1539,40 +1295,40 @@ static const HuffmanCodebook at9_huffman_coeffs[][8][4] = { { { 0 } }, { { 0 } }, { - { huff_spec_a21_bits, huff_spec_a21_codes, 16, 2, 1, 2, 3, }, - { huff_spec_a22_bits, huff_spec_a22_codes, 256, 4, 2, 2, 8, }, - { huff_spec_a23_bits, huff_spec_a23_codes, 256, 4, 2, 2, 9, }, - { huff_spec_a24_bits, huff_spec_a24_codes, 256, 4, 2, 2, 10, }, + { 8, 2, 1, 2 }, + { 80, 4, 2, 2 }, + { 81, 4, 2, 2 }, + { 81, 4, 2, 2 }, }, { - { huff_spec_a31_bits, huff_spec_a31_codes, 64, 2, 1, 3, 7, }, - { huff_spec_a32_bits, huff_spec_a32_codes, 64, 2, 1, 3, 7, }, - { huff_spec_a33_bits, huff_spec_a33_codes, 64, 2, 1, 3, 8, }, - { huff_spec_a34_bits, huff_spec_a34_codes, 64, 2, 1, 3, 10, }, + { 40, 2, 1, 3 }, + { 49, 2, 1, 3 }, + { 49, 2, 1, 3 }, + { 49, 2, 1, 3 }, }, { - { huff_spec_a41_bits, huff_spec_a41_codes, 256, 2, 1, 4, 9, }, - { huff_spec_a42_bits, huff_spec_a42_codes, 256, 2, 1, 4, 10, }, - { huff_spec_a43_bits, huff_spec_a43_codes, 256, 2, 1, 4, 10, }, - { huff_spec_a44_bits, huff_spec_a44_codes, 256, 2, 1, 4, 10, }, + { 176, 2, 1, 4 }, + { 225, 2, 1, 4 }, + { 225, 2, 1, 4 }, + { 225, 2, 1, 4 }, }, { - { huff_spec_a51_bits, huff_spec_a51_codes, 32, 1, 0, 5, 6, }, - { huff_spec_a52_bits, huff_spec_a52_codes, 32, 1, 0, 5, 6, }, - { huff_spec_a53_bits, huff_spec_a53_codes, 32, 1, 0, 5, 7, }, - { huff_spec_a54_bits, huff_spec_a54_codes, 32, 1, 0, 5, 8, }, + { 31, 1, 0, 5 }, + { 31, 1, 0, 5 }, + { 31, 1, 0, 5 }, + { 31, 1, 0, 5 }, }, { - { huff_spec_a61_bits, huff_spec_a61_codes, 64, 1, 0, 6, 7, }, - { huff_spec_a62_bits, huff_spec_a62_codes, 64, 1, 0, 6, 7, }, - { huff_spec_a63_bits, huff_spec_a63_codes, 64, 1, 0, 6, 8, }, - { huff_spec_a64_bits, huff_spec_a64_codes, 64, 1, 0, 6, 9, }, + { 63, 1, 0, 6 }, + { 63, 1, 0, 6 }, + { 63, 1, 0, 6 }, + { 63, 1, 0, 6 }, }, { - { huff_spec_a71_bits, huff_spec_a71_codes, 128, 1, 0, 7, 8, }, - { huff_spec_a72_bits, huff_spec_a72_codes, 128, 1, 0, 7, 8, }, - { huff_spec_a73_bits, huff_spec_a73_codes, 128, 1, 0, 7, 9, }, - { huff_spec_a74_bits, huff_spec_a74_codes, 128, 1, 0, 7, 10, }, + { 127, 1, 0, 7 }, + { 127, 1, 0, 7 }, + { 127, 1, 0, 7 }, + { 127, 1, 0, 7 }, }, }, { @@ -1580,39 +1336,39 @@ static const HuffmanCodebook at9_huffman_coeffs[][8][4] = { { { 0 } }, { { 0 }, - { huff_spec_b22_bits, huff_spec_b22_codes, 256, 4, 2, 2, 10, }, - { huff_spec_b23_bits, huff_spec_b23_codes, 256, 4, 2, 2, 10, }, - { huff_spec_b24_bits, huff_spec_b24_codes, 256, 4, 2, 2, 10, }, + { 80, 4, 2, 2 }, + { 81, 4, 2, 2 }, + { 81, 4, 2, 2 }, }, { { 0 }, - { huff_spec_b32_bits, huff_spec_b32_codes, 64, 2, 1, 3, 9, }, - { huff_spec_b33_bits, huff_spec_b33_codes, 64, 2, 1, 3, 10, }, - { huff_spec_b34_bits, huff_spec_b34_codes, 64, 2, 1, 3, 10, }, + { 49, 2, 1, 3 }, + { 49, 2, 1, 3 }, + { 49, 2, 1, 3 }, }, { { 0 }, - { huff_spec_b42_bits, huff_spec_b42_codes, 256, 2, 1, 4, 10, }, - { huff_spec_b43_bits, huff_spec_b43_codes, 256, 2, 1, 4, 10, }, - { huff_spec_b44_bits, huff_spec_b44_codes, 256, 2, 1, 4, 10, }, + { 225, 2, 1, 4 }, + { 225, 2, 1, 4 }, + { 225, 2, 1, 4 }, }, { { 0 }, - { huff_spec_b52_bits, huff_spec_b52_codes, 32, 1, 0, 5, 7, }, - { huff_spec_b53_bits, huff_spec_b53_codes, 32, 1, 0, 5, 8, }, - { huff_spec_b54_bits, huff_spec_b54_codes, 32, 1, 0, 5, 9, }, + { 31, 1, 0, 5 }, + { 31, 1, 0, 5 }, + { 31, 1, 0, 5 }, }, { { 0 }, - { huff_spec_b62_bits, huff_spec_b62_codes, 64, 1, 0, 6, 8, }, - { huff_spec_b63_bits, huff_spec_b63_codes, 64, 1, 0, 6, 9, }, - { huff_spec_b64_bits, huff_spec_b64_codes, 64, 1, 0, 6, 10, }, + { 63, 1, 0, 6 }, + { 63, 1, 0, 6 }, + { 63, 1, 0, 6 }, }, { { 0 }, - { huff_spec_b72_bits, huff_spec_b72_codes, 128, 1, 0, 7, 9, }, - { huff_spec_b73_bits, huff_spec_b73_codes, 128, 1, 0, 7, 10, }, - { huff_spec_b74_bits, huff_spec_b74_codes, 128, 1, 0, 7, 10, }, + { 127, 1, 0, 7 }, + { 127, 1, 0, 7 }, + { 127, 1, 0, 7 }, }, }, }; diff --git a/libavcodec/atsc_a53.c b/libavcodec/atsc_a53.c new file mode 100644 index 000000000..2d89ef50b --- /dev/null +++ b/libavcodec/atsc_a53.c @@ -0,0 +1,119 @@ +/* + * 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 "atsc_a53.h" +#include "get_bits.h" + +int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, + void **data, size_t *sei_size) +{ + AVFrameSideData *side_data = NULL; + uint8_t *sei_data; + + if (frame) + side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC); + + if (!side_data) { + *data = NULL; + return 0; + } + + *sei_size = side_data->size + 11; + *data = av_mallocz(*sei_size + prefix_len); + if (!*data) + return AVERROR(ENOMEM); + sei_data = (uint8_t*)*data + prefix_len; + + // country code + sei_data[0] = 181; + sei_data[1] = 0; + sei_data[2] = 49; + + /** + * 'GA94' is standard in North America for ATSC, but hard coding + * this style may not be the right thing to do -- other formats + * do exist. This information is not available in the side_data + * so we are going with this right now. + */ + AV_WL32(sei_data + 3, MKTAG('G', 'A', '9', '4')); + sei_data[7] = 3; + sei_data[8] = ((side_data->size/3) & 0x1f) | 0x40; + sei_data[9] = 0; + + memcpy(sei_data + 10, side_data->data, side_data->size); + + sei_data[side_data->size+10] = 255; + + return 0; +} + +int ff_parse_a53_cc(AVBufferRef **pbuf, const uint8_t *data, int size) +{ + AVBufferRef *buf = *pbuf; + GetBitContext gb; + size_t new_size, old_size = buf ? buf->size : 0; + int ret, cc_count; + + if (size < 3) + return AVERROR(EINVAL); + + ret = init_get_bits8(&gb, data, size); + if (ret < 0) + return ret; + + if (get_bits(&gb, 8) != 0x3) // user_data_type_code + return 0; + + skip_bits(&gb, 1); // reserved + if (!get_bits(&gb, 1)) // process_cc_data_flag + return 0; + + skip_bits(&gb, 1); // zero bit + cc_count = get_bits(&gb, 5); + if (!cc_count) + return 0; + + skip_bits(&gb, 8); // reserved + + /* 3 bytes per CC plus one byte marker_bits at the end */ + if (cc_count * 3 >= (get_bits_left(&gb) >> 3)) + return AVERROR(EINVAL); + + new_size = (old_size + cc_count * 3); + + if (new_size > INT_MAX) + return AVERROR(EINVAL); + + /* Allow merging of the cc data from two fields. */ + ret = av_buffer_realloc(pbuf, new_size); + if (ret < 0) + return ret; + + buf = *pbuf; + /* Use of av_buffer_realloc assumes buffer is writeable */ + for (int i = 0; i < cc_count; i++) { + buf->data[old_size++] = get_bits(&gb, 8); + buf->data[old_size++] = get_bits(&gb, 8); + buf->data[old_size++] = get_bits(&gb, 8); + } + + return cc_count; +} diff --git a/libavcodec/atsc_a53.h b/libavcodec/atsc_a53.h new file mode 100644 index 000000000..0622a5554 --- /dev/null +++ b/libavcodec/atsc_a53.h @@ -0,0 +1,56 @@ +/* + * 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_ATSC_A53_H +#define AVCODEC_ATSC_A53_H + +#include +#include + +#include "libavutil/buffer.h" +#include "libavutil/frame.h" + +/** + * Check AVFrame for A53 side data and allocate and fill SEI message with A53 info + * + * @param frame Raw frame to get A53 side data from + * @param prefix_len Number of bytes to allocate before SEI message + * @param data Pointer to a variable to store allocated memory + * Upon return the variable will hold NULL on error or if frame has no A53 info. + * Otherwise it will point to prefix_len uninitialized bytes followed by + * *sei_size SEI message + * @param sei_size Pointer to a variable to store generated SEI message length + * @return Zero on success, negative error code on failure + */ +int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, + void **data, size_t *sei_size); + +/** + * Parse a data array for ATSC A53 Part 4 Closed Captions and store them in an AVBufferRef. + * + * @param pbuf Pointer to an AVBufferRef to append the closed captions. *pbuf may be NULL, in + * which case a new buffer will be allocated and put in it. + * @param data The data array containing the raw A53 data. + * @param size Size of the data array in bytes. + * + * @return Number of closed captions parsed on success, negative error code on failure. + * If no Closed Captions are parsed, *pbuf is untouched. + */ +int ff_parse_a53_cc(AVBufferRef **pbuf, const uint8_t *data, int size); + +#endif /* AVCODEC_ATSC_A53_H */ diff --git a/libavcodec/audiotoolboxdec.c b/libavcodec/audiotoolboxdec.c index 5c0a9de8f..bf3e00959 100644 --- a/libavcodec/audiotoolboxdec.c +++ b/libavcodec/audiotoolboxdec.c @@ -1,7 +1,7 @@ /* * Audio Toolbox system codecs * - * copyright (c) 2016 Rodger Combs + * copyright (c) 2016 rcombs * * This file is part of FFmpeg. * @@ -296,7 +296,8 @@ static int ffat_set_extradata(AVCodecContext *avctx) return 0; } -static av_cold int ffat_create_decoder(AVCodecContext *avctx, AVPacket *pkt) +static av_cold int ffat_create_decoder(AVCodecContext *avctx, + const AVPacket *pkt) { ATDecodeContext *at = avctx->priv_data; OSStatus status; @@ -483,7 +484,7 @@ static int ffat_decode(AVCodecContext *avctx, void *data, if (avctx->codec_id == AV_CODEC_ID_AAC) { if (!at->extradata_size) { uint8_t *side_data; - int side_data_size = 0; + buffer_size_t side_data_size; side_data = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size); @@ -595,7 +596,7 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx) .flush = ffat_decode_flush, \ .priv_class = &ffat_##NAME##_dec_class, \ .bsfs = bsf_name, \ - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, \ + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_CHANNEL_CONF, \ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, \ .wrapper_name = "at", \ }; diff --git a/libavcodec/audiotoolboxenc.c b/libavcodec/audiotoolboxenc.c index e8748b3c6..b0a4340ae 100644 --- a/libavcodec/audiotoolboxenc.c +++ b/libavcodec/audiotoolboxenc.c @@ -1,7 +1,7 @@ /* * Audio Toolbox system codecs * - * copyright (c) 2016 Rodger Combs + * copyright (c) 2016 rcombs * * This file is part of FFmpeg. * diff --git a/libavcodec/av1.h b/libavcodec/av1.h index 6c0e32485..0f99ae482 100644 --- a/libavcodec/av1.h +++ b/libavcodec/av1.h @@ -160,4 +160,12 @@ enum { AV1_SCALABILITY_L4T7_KEY_SHIFT = 28, }; +// Frame Restoration types (section 6.10.15) +enum { + AV1_RESTORE_NONE = 0, + AV1_RESTORE_WIENER = 1, + AV1_RESTORE_SGRPROJ = 2, + AV1_RESTORE_SWITCHABLE = 3, +}; + #endif /* AVCODEC_AV1_H */ diff --git a/libavcodec/av1_frame_merge_bsf.c b/libavcodec/av1_frame_merge_bsf.c index b5aa57e0f..fce5bdb67 100644 --- a/libavcodec/av1_frame_merge_bsf.c +++ b/libavcodec/av1_frame_merge_bsf.c @@ -24,7 +24,8 @@ #include "cbs_av1.h" typedef struct AV1FMergeContext { - CodedBitstreamContext *cbc; + CodedBitstreamContext *input; + CodedBitstreamContext *output; CodedBitstreamFragment frag[2]; AVPacket *pkt, *in; int idx; @@ -34,8 +35,8 @@ static void av1_frame_merge_flush(AVBSFContext *bsf) { AV1FMergeContext *ctx = bsf->priv_data; - ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[0]); - ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[1]); + ff_cbs_fragment_reset(&ctx->frag[0]); + ff_cbs_fragment_reset(&ctx->frag[1]); av_packet_unref(ctx->in); av_packet_unref(ctx->pkt); } @@ -54,7 +55,7 @@ static int av1_frame_merge_filter(AVBSFContext *bsf, AVPacket *out) return err; } - err = ff_cbs_read_packet(ctx->cbc, frag, in); + err = ff_cbs_read_packet(ctx->input, frag, in); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); goto fail; @@ -82,7 +83,7 @@ static int av1_frame_merge_filter(AVBSFContext *bsf, AVPacket *out) if (tu->nb_units > 0 && frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) { eof: - err = ff_cbs_write_packet(ctx->cbc, buffer_pkt, tu); + err = ff_cbs_write_packet(ctx->output, buffer_pkt, tu); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); goto fail; @@ -93,7 +94,7 @@ eof: ctx->idx = !ctx->idx; } else { for (i = 0; i < frag->nb_units; i++) { - err = ff_cbs_insert_unit_content(ctx->cbc, tu, -1, frag->units[i].type, + err = ff_cbs_insert_unit_content(tu, -1, frag->units[i].type, frag->units[i].content, frag->units[i].content_ref); if (err < 0) goto fail; @@ -108,7 +109,7 @@ eof: else av_packet_unref(in); - ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[ctx->idx]); + ff_cbs_fragment_reset(&ctx->frag[ctx->idx]); fail: if (err < 0 && err != AVERROR(EAGAIN)) @@ -120,24 +121,30 @@ fail: static int av1_frame_merge_init(AVBSFContext *bsf) { AV1FMergeContext *ctx = bsf->priv_data; + int err; ctx->in = av_packet_alloc(); ctx->pkt = av_packet_alloc(); if (!ctx->in || !ctx->pkt) return AVERROR(ENOMEM); - return ff_cbs_init(&ctx->cbc, AV_CODEC_ID_AV1, bsf); + err = ff_cbs_init(&ctx->input, AV_CODEC_ID_AV1, bsf); + if (err < 0) + return err; + + return ff_cbs_init(&ctx->output, AV_CODEC_ID_AV1, bsf); } static void av1_frame_merge_close(AVBSFContext *bsf) { AV1FMergeContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->cbc, &ctx->frag[0]); - ff_cbs_fragment_free(ctx->cbc, &ctx->frag[1]); + ff_cbs_fragment_free(&ctx->frag[0]); + ff_cbs_fragment_free(&ctx->frag[1]); av_packet_free(&ctx->in); av_packet_free(&ctx->pkt); - ff_cbs_close(&ctx->cbc); + ff_cbs_close(&ctx->input); + ff_cbs_close(&ctx->output); } static const enum AVCodecID av1_frame_merge_codec_ids[] = { diff --git a/libavcodec/av1_frame_split_bsf.c b/libavcodec/av1_frame_split_bsf.c index 87dfc8310..fa8b887b6 100644 --- a/libavcodec/av1_frame_split_bsf.c +++ b/libavcodec/av1_frame_split_bsf.c @@ -172,7 +172,7 @@ static int av1_frame_split_filter(AVBSFContext *ctx, AVPacket *out) if (s->cur_frame == s->nb_frames) { av_packet_unref(s->buffer_pkt); - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); } return 0; @@ -187,7 +187,7 @@ fail: av_packet_unref(out); av_packet_unref(s->buffer_pkt); } - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); return ret; } @@ -214,7 +214,7 @@ static int av1_frame_split_init(AVBSFContext *ctx) if (ret < 0) return ret; - s->cbc->decompose_unit_types = (CodedBitstreamUnitType*)decompose_unit_types; + s->cbc->decompose_unit_types = decompose_unit_types; s->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(decompose_unit_types); if (!ctx->par_in->extradata_size) @@ -224,7 +224,7 @@ static int av1_frame_split_init(AVBSFContext *ctx) if (ret < 0) av_log(ctx, AV_LOG_WARNING, "Failed to parse extradata.\n"); - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); return 0; } @@ -234,7 +234,7 @@ static void av1_frame_split_flush(AVBSFContext *ctx) AV1FSplitContext *s = ctx->priv_data; av_packet_unref(s->buffer_pkt); - ff_cbs_fragment_reset(s->cbc, &s->temporal_unit); + ff_cbs_fragment_reset(&s->temporal_unit); } static void av1_frame_split_close(AVBSFContext *ctx) @@ -242,7 +242,7 @@ static void av1_frame_split_close(AVBSFContext *ctx) AV1FSplitContext *s = ctx->priv_data; av_packet_free(&s->buffer_pkt); - ff_cbs_fragment_free(s->cbc, &s->temporal_unit); + ff_cbs_fragment_free(&s->temporal_unit); ff_cbs_close(&s->cbc); } diff --git a/libavcodec/av1_metadata_bsf.c b/libavcodec/av1_metadata_bsf.c index ee1a63c1e..328db5c0d 100644 --- a/libavcodec/av1_metadata_bsf.c +++ b/libavcodec/av1_metadata_bsf.c @@ -20,21 +20,12 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_av1.h" -enum { - PASS, - INSERT, - REMOVE, -}; - typedef struct AV1MetadataContext { - const AVClass *class; - - CodedBitstreamContext *cbc; - CodedBitstreamFragment access_unit; + CBSBSFContext common; int td; @@ -112,186 +103,66 @@ static int av1_metadata_update_sequence_header(AVBSFContext *bsf, return 0; } -static int av1_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) +static int av1_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *frag) { AV1MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->access_unit; - uint8_t *side_data; - int side_data_size; - int err, i; - - side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, - &side_data_size); - if (!side_data_size) - return 0; - - err = ff_cbs_read(ctx->cbc, frag, side_data, side_data_size); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n"); - return err; - } - - for (i = 0; i < frag->nb_units; i++) { - if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) { - AV1RawOBU *obu = frag->units[i].content; - err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header); - if (err < 0) - return err; - } - } - - err = ff_cbs_write_fragment_data(ctx->cbc, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n"); - return err; - } - - side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, frag->data_size); - if (!side_data) - return AVERROR(ENOMEM); - memcpy(side_data, frag->data, frag->data_size); - - ff_cbs_fragment_reset(ctx->cbc, frag); - - return 0; -} - -static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) -{ - AV1MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->access_unit; AV1RawOBU td, *obu; int err, i; - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = av1_metadata_update_side_data(bsf, pkt); - if (err < 0) - goto fail; - - err = ff_cbs_read_packet(ctx->cbc, frag, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } - - if (frag->nb_units == 0) { - av_log(bsf, AV_LOG_ERROR, "No OBU in packet.\n"); - err = AVERROR_INVALIDDATA; - goto fail; - } - for (i = 0; i < frag->nb_units; i++) { if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) { obu = frag->units[i].content; err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header); if (err < 0) - goto fail; + return err; } } // If a Temporal Delimiter is present, it must be the first OBU. - if (frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) { - if (ctx->td == REMOVE) - ff_cbs_delete_unit(ctx->cbc, frag, 0); - } else if (ctx->td == INSERT) { + if (frag->nb_units && frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) { + if (ctx->td == BSF_ELEMENT_REMOVE) + ff_cbs_delete_unit(frag, 0); + } else if (pkt && ctx->td == BSF_ELEMENT_INSERT) { td = (AV1RawOBU) { .header.obu_type = AV1_OBU_TEMPORAL_DELIMITER, }; - err = ff_cbs_insert_unit_content(ctx->cbc, frag, 0, AV1_OBU_TEMPORAL_DELIMITER, + err = ff_cbs_insert_unit_content(frag, 0, AV1_OBU_TEMPORAL_DELIMITER, &td, NULL); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to insert Temporal Delimiter.\n"); - goto fail; + return err; } } if (ctx->delete_padding) { for (i = frag->nb_units - 1; i >= 0; i--) { if (frag->units[i].type == AV1_OBU_PADDING) - ff_cbs_delete_unit(ctx->cbc, frag, i); + ff_cbs_delete_unit(frag, i); } } - err = ff_cbs_write_packet(ctx->cbc, pkt, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; - } - - err = 0; -fail: - ff_cbs_fragment_reset(ctx->cbc, frag); - - if (err < 0) - av_packet_unref(pkt); - - return err; + return 0; } +static const CBSBSFType av1_metadata_type = { + .codec_id = AV_CODEC_ID_AV1, + .fragment_name = "temporal unit", + .unit_name = "OBU", + .update_fragment = &av1_metadata_update_fragment, +}; + static int av1_metadata_init(AVBSFContext *bsf) { - AV1MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->access_unit; - AV1RawOBU *obu; - int err, i; - - err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_AV1, bsf); - if (err < 0) - return err; - - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - for (i = 0; i < frag->nb_units; i++) { - if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) { - obu = frag->units[i].content; - err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header); - if (err < 0) - goto fail; - } - } - - err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; - } - } - - err = 0; -fail: - ff_cbs_fragment_reset(ctx->cbc, frag); - return err; -} - -static void av1_metadata_close(AVBSFContext *bsf) -{ - AV1MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit); - ff_cbs_close(&ctx->cbc); + return ff_cbs_bsf_generic_init(bsf, &av1_metadata_type); } #define OFFSET(x) offsetof(AV1MetadataContext, x) #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM) static const AVOption av1_metadata_options[] = { - { "td", "Temporal Delimiter OBU", - OFFSET(td), AV_OPT_TYPE_INT, - { .i64 = PASS }, PASS, REMOVE, FLAGS, "td" }, - { "pass", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = PASS }, .flags = FLAGS, .unit = "td" }, - { "insert", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = INSERT }, .flags = FLAGS, .unit = "td" }, - { "remove", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = REMOVE }, .flags = FLAGS, .unit = "td" }, + BSF_ELEMENT_OPTIONS_PIR("td", "Temporal Delimiter OBU", + td, FLAGS), { "color_primaries", "Set color primaries (section 6.4.2)", OFFSET(color_primaries), AV_OPT_TYPE_INT, @@ -351,7 +222,7 @@ const AVBitStreamFilter ff_av1_metadata_bsf = { .priv_data_size = sizeof(AV1MetadataContext), .priv_class = &av1_metadata_class, .init = &av1_metadata_init, - .close = &av1_metadata_close, - .filter = &av1_metadata_filter, + .close = &ff_cbs_bsf_generic_close, + .filter = &ff_cbs_bsf_generic_filter, .codec_ids = av1_metadata_codec_ids, }; diff --git a/libavcodec/av1_parse.h b/libavcodec/av1_parse.h index 01bcd646c..ae0ebb5a1 100644 --- a/libavcodec/av1_parse.h +++ b/libavcodec/av1_parse.h @@ -27,6 +27,9 @@ #include "avcodec.h" #include "get_bits.h" +// OBU header fields + max leb128 length +#define MAX_OBU_HEADER_SIZE (2 + 8) + typedef struct AV1OBU { /** Size of payload */ int size; @@ -105,7 +108,7 @@ static inline int parse_obu_header(const uint8_t *buf, int buf_size, int ret, extension_flag, has_size_flag; int64_t size; - ret = init_get_bits8(&gb, buf, FFMIN(buf_size, 2 + 8)); // OBU header fields + max leb128 length + ret = init_get_bits8(&gb, buf, FFMIN(buf_size, MAX_OBU_HEADER_SIZE)); if (ret < 0) return ret; diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c index 036ab5e14..6a76ffb7b 100644 --- a/libavcodec/av1_parser.c +++ b/libavcodec/av1_parser.c @@ -73,12 +73,12 @@ static int av1_parser_parse(AVCodecParserContext *ctx, if (avctx->extradata_size && !s->parsed_extradata) { s->parsed_extradata = 1; - ret = ff_cbs_read(s->cbc, td, avctx->extradata, avctx->extradata_size); + ret = ff_cbs_read_extradata_from_codec(s->cbc, td, avctx); if (ret < 0) { av_log(avctx, AV_LOG_WARNING, "Failed to parse extradata.\n"); } - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); } ret = ff_cbs_read(s->cbc, td, data, size); @@ -99,7 +99,6 @@ static int av1_parser_parse(AVCodecParserContext *ctx, CodedBitstreamUnit *unit = &td->units[i]; AV1RawOBU *obu = unit->content; AV1RawFrameHeader *frame; - int frame_type; if (unit->type == AV1_OBU_FRAME) frame = &obu->obu.frame.header; @@ -111,30 +110,15 @@ static int av1_parser_parse(AVCodecParserContext *ctx, if (obu->header.spatial_id > 0) continue; - if (frame->show_existing_frame) { - AV1ReferenceFrameState *ref = &av1->ref[frame->frame_to_show_map_idx]; - - if (!ref->valid) { - av_log(avctx, AV_LOG_ERROR, "Invalid reference frame\n"); - goto end; - } - - ctx->width = ref->frame_width; - ctx->height = ref->frame_height; - frame_type = ref->frame_type; - - ctx->key_frame = 0; - } else if (!frame->show_frame) { + if (!frame->show_frame && !frame->show_existing_frame) continue; - } else { - ctx->width = av1->frame_width; - ctx->height = av1->frame_height; - frame_type = frame->frame_type; - ctx->key_frame = frame_type == AV1_FRAME_KEY; - } + ctx->width = frame->frame_width_minus_1 + 1; + ctx->height = frame->frame_height_minus_1 + 1; - switch (frame_type) { + ctx->key_frame = frame->frame_type == AV1_FRAME_KEY && !frame->show_existing_frame; + + switch (frame->frame_type) { case AV1_FRAME_KEY: case AV1_FRAME_INTRA_ONLY: ctx->pict_type = AV_PICTURE_TYPE_I; @@ -171,8 +155,6 @@ static int av1_parser_parse(AVCodecParserContext *ctx, color->transfer_characteristics == AVCOL_TRC_IEC61966_2_1) ctx->format = pix_fmts_rgb[color->high_bitdepth + color->twelve_bit]; - avctx->pix_fmt = ctx->format; - avctx->profile = seq->seq_profile; avctx->level = seq->seq_level_idx[0]; @@ -181,17 +163,11 @@ static int av1_parser_parse(AVCodecParserContext *ctx, avctx->color_trc = (enum AVColorTransferCharacteristic) color->transfer_characteristics; avctx->color_range = color->color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; - if (ctx->width != avctx->width || ctx->height != avctx->height) { - ret = ff_set_dimensions(avctx, ctx->width, ctx->height); - if (ret < 0) - goto end; - } - if (avctx->framerate.num) avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); end: - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); s->cbc->log_ctx = NULL; @@ -215,7 +191,7 @@ static av_cold int av1_parser_init(AVCodecParserContext *ctx) if (ret < 0) return ret; - s->cbc->decompose_unit_types = (CodedBitstreamUnitType *)decompose_unit_types; + s->cbc->decompose_unit_types = decompose_unit_types; s->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(decompose_unit_types); return 0; @@ -225,7 +201,7 @@ static void av1_parser_close(AVCodecParserContext *ctx) { AV1ParseContext *s = ctx->priv_data; - ff_cbs_fragment_free(s->cbc, &s->temporal_unit); + ff_cbs_fragment_free(&s->temporal_unit); ff_cbs_close(&s->cbc); } diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c new file mode 100644 index 000000000..a75d6744d --- /dev/null +++ b/libavcodec/av1dec.c @@ -0,0 +1,1158 @@ +/* + * AV1 video decoder + * + * 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/film_grain_params.h" +#include "libavutil/pixdesc.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "av1dec.h" +#include "bytestream.h" +#include "hwconfig.h" +#include "internal.h" +#include "profiles.h" + +static uint32_t inverse_recenter(int r, uint32_t v) +{ + if (v > 2 * r) + return v; + else if (v & 1) + return r - ((v + 1) >> 1); + else + return r + (v >> 1); +} + +static uint32_t decode_unsigned_subexp_with_ref(uint32_t sub_exp, + int mx, int r) +{ + if ((r << 1) <= mx) { + return inverse_recenter(r, sub_exp); + } else { + return mx - 1 - inverse_recenter(mx - 1 - r, sub_exp); + } +} + +static int32_t decode_signed_subexp_with_ref(uint32_t sub_exp, int low, + int high, int r) +{ + int32_t x = decode_unsigned_subexp_with_ref(sub_exp, high - low, r - low); + return x + low; +} + +static void read_global_param(AV1DecContext *s, int type, int ref, int idx) +{ + uint8_t primary_frame, prev_frame; + uint32_t abs_bits, prec_bits, round, prec_diff, sub, mx; + int32_t r, prev_gm_param; + + primary_frame = s->raw_frame_header->primary_ref_frame; + prev_frame = s->raw_frame_header->ref_frame_idx[primary_frame]; + abs_bits = AV1_GM_ABS_ALPHA_BITS; + prec_bits = AV1_GM_ALPHA_PREC_BITS; + + /* setup_past_independence() sets PrevGmParams to default values. We can + * simply point to the current's frame gm_params as they will be initialized + * with defaults at this point. + */ + if (s->raw_frame_header->primary_ref_frame == AV1_PRIMARY_REF_NONE) + prev_gm_param = s->cur_frame.gm_params[ref][idx]; + else + prev_gm_param = s->ref[prev_frame].gm_params[ref][idx]; + + if (idx < 2) { + if (type == AV1_WARP_MODEL_TRANSLATION) { + abs_bits = AV1_GM_ABS_TRANS_ONLY_BITS - + !s->raw_frame_header->allow_high_precision_mv; + prec_bits = AV1_GM_TRANS_ONLY_PREC_BITS - + !s->raw_frame_header->allow_high_precision_mv; + } else { + abs_bits = AV1_GM_ABS_TRANS_BITS; + prec_bits = AV1_GM_TRANS_PREC_BITS; + } + } + round = (idx % 3) == 2 ? (1 << AV1_WARPEDMODEL_PREC_BITS) : 0; + prec_diff = AV1_WARPEDMODEL_PREC_BITS - prec_bits; + sub = (idx % 3) == 2 ? (1 << prec_bits) : 0; + mx = 1 << abs_bits; + r = (prev_gm_param >> prec_diff) - sub; + + s->cur_frame.gm_params[ref][idx] = + (decode_signed_subexp_with_ref(s->raw_frame_header->gm_params[ref][idx], + -mx, mx + 1, r) << prec_diff) + round; +} + +/** +* update gm type/params, since cbs already implemented part of this funcation, +* so we don't need to full implement spec. +*/ +static void global_motion_params(AV1DecContext *s) +{ + const AV1RawFrameHeader *header = s->raw_frame_header; + int type, ref; + + for (ref = AV1_REF_FRAME_LAST; ref <= AV1_REF_FRAME_ALTREF; ref++) { + s->cur_frame.gm_type[ref] = AV1_WARP_MODEL_IDENTITY; + for (int i = 0; i < 6; i++) + s->cur_frame.gm_params[ref][i] = (i % 3 == 2) ? + 1 << AV1_WARPEDMODEL_PREC_BITS : 0; + } + if (header->frame_type == AV1_FRAME_KEY || + header->frame_type == AV1_FRAME_INTRA_ONLY) + return; + + for (ref = AV1_REF_FRAME_LAST; ref <= AV1_REF_FRAME_ALTREF; ref++) { + if (header->is_global[ref]) { + if (header->is_rot_zoom[ref]) { + type = AV1_WARP_MODEL_ROTZOOM; + } else { + type = header->is_translation[ref] ? AV1_WARP_MODEL_TRANSLATION + : AV1_WARP_MODEL_AFFINE; + } + } else { + type = AV1_WARP_MODEL_IDENTITY; + } + s->cur_frame.gm_type[ref] = type; + + if (type >= AV1_WARP_MODEL_ROTZOOM) { + read_global_param(s, type, ref, 2); + read_global_param(s, type, ref, 3); + if (type == AV1_WARP_MODEL_AFFINE) { + read_global_param(s, type, ref, 4); + read_global_param(s, type, ref, 5); + } else { + s->cur_frame.gm_params[ref][4] = -s->cur_frame.gm_params[ref][3]; + s->cur_frame.gm_params[ref][5] = s->cur_frame.gm_params[ref][2]; + } + } + if (type >= AV1_WARP_MODEL_TRANSLATION) { + read_global_param(s, type, ref, 0); + read_global_param(s, type, ref, 1); + } + } +} + +static int get_relative_dist(const AV1RawSequenceHeader *seq, + unsigned int a, unsigned int b) +{ + unsigned int diff = a - b; + unsigned int m = 1 << seq->order_hint_bits_minus_1; + return (diff & (m - 1)) - (diff & m); +} + +static void skip_mode_params(AV1DecContext *s) +{ + const AV1RawFrameHeader *header = s->raw_frame_header; + const AV1RawSequenceHeader *seq = s->raw_seq; + + int forward_idx, backward_idx; + int forward_hint, backward_hint; + int second_forward_idx, second_forward_hint; + int ref_hint, dist, i; + + if (!header->skip_mode_present) + return; + + forward_idx = -1; + backward_idx = -1; + for (i = 0; i < AV1_REFS_PER_FRAME; i++) { + ref_hint = s->ref[header->ref_frame_idx[i]].raw_frame_header->order_hint; + dist = get_relative_dist(seq, ref_hint, header->order_hint); + if (dist < 0) { + if (forward_idx < 0 || + get_relative_dist(seq, ref_hint, forward_hint) > 0) { + forward_idx = i; + forward_hint = ref_hint; + } + } else if (dist > 0) { + if (backward_idx < 0 || + get_relative_dist(seq, ref_hint, backward_hint) < 0) { + backward_idx = i; + backward_hint = ref_hint; + } + } + } + + if (forward_idx < 0) { + return; + } else if (backward_idx >= 0) { + s->cur_frame.skip_mode_frame_idx[0] = + AV1_REF_FRAME_LAST + FFMIN(forward_idx, backward_idx); + s->cur_frame.skip_mode_frame_idx[1] = + AV1_REF_FRAME_LAST + FFMAX(forward_idx, backward_idx); + return; + } + + second_forward_idx = -1; + for (i = 0; i < AV1_REFS_PER_FRAME; i++) { + ref_hint = s->ref[header->ref_frame_idx[i]].raw_frame_header->order_hint; + if (get_relative_dist(seq, ref_hint, forward_hint) < 0) { + if (second_forward_idx < 0 || + get_relative_dist(seq, ref_hint, second_forward_hint) > 0) { + second_forward_idx = i; + second_forward_hint = ref_hint; + } + } + } + + if (second_forward_idx < 0) + return; + + s->cur_frame.skip_mode_frame_idx[0] = + AV1_REF_FRAME_LAST + FFMIN(forward_idx, second_forward_idx); + s->cur_frame.skip_mode_frame_idx[1] = + AV1_REF_FRAME_LAST + FFMAX(forward_idx, second_forward_idx); +} + +static void coded_lossless_param(AV1DecContext *s) +{ + const AV1RawFrameHeader *header = s->raw_frame_header; + int i; + + if (header->delta_q_y_dc || header->delta_q_u_ac || + header->delta_q_u_dc || header->delta_q_v_ac || + header->delta_q_v_dc) { + s->cur_frame.coded_lossless = 0; + return; + } + + s->cur_frame.coded_lossless = 1; + for (i = 0; i < AV1_MAX_SEGMENTS; i++) { + int qindex; + if (header->feature_enabled[i][AV1_SEG_LVL_ALT_Q]) { + qindex = (header->base_q_idx + + header->feature_value[i][AV1_SEG_LVL_ALT_Q]); + } else { + qindex = header->base_q_idx; + } + qindex = av_clip_uintp2(qindex, 8); + + if (qindex) { + s->cur_frame.coded_lossless = 0; + return; + } + } +} + +static void load_grain_params(AV1DecContext *s) +{ + const AV1RawFrameHeader *header = s->raw_frame_header; + const AV1RawFilmGrainParams *film_grain = &header->film_grain, *src; + AV1RawFilmGrainParams *dst = &s->cur_frame.film_grain; + + if (!film_grain->apply_grain) + return; + + if (film_grain->update_grain) { + memcpy(dst, film_grain, sizeof(*dst)); + return; + } + + src = &s->ref[film_grain->film_grain_params_ref_idx].film_grain; + + memcpy(dst, src, sizeof(*dst)); + dst->grain_seed = film_grain->grain_seed; +} + +static int init_tile_data(AV1DecContext *s) + +{ + int cur_tile_num = + s->raw_frame_header->tile_cols * s->raw_frame_header->tile_rows; + if (s->tile_num < cur_tile_num) { + int ret = av_reallocp_array(&s->tile_group_info, cur_tile_num, + sizeof(TileGroupInfo)); + if (ret < 0) { + s->tile_num = 0; + return ret; + } + } + s->tile_num = cur_tile_num; + + return 0; +} + +static int get_tiles_info(AVCodecContext *avctx, const AV1RawTileGroup *tile_group) +{ + AV1DecContext *s = avctx->priv_data; + GetByteContext gb; + uint16_t tile_num, tile_row, tile_col; + uint32_t size = 0, size_bytes = 0; + + bytestream2_init(&gb, tile_group->tile_data.data, + tile_group->tile_data.data_size); + s->tg_start = tile_group->tg_start; + s->tg_end = tile_group->tg_end; + + for (tile_num = tile_group->tg_start; tile_num <= tile_group->tg_end; tile_num++) { + tile_row = tile_num / s->raw_frame_header->tile_cols; + tile_col = tile_num % s->raw_frame_header->tile_cols; + + if (tile_num == tile_group->tg_end) { + s->tile_group_info[tile_num].tile_size = bytestream2_get_bytes_left(&gb); + s->tile_group_info[tile_num].tile_offset = bytestream2_tell(&gb); + s->tile_group_info[tile_num].tile_row = tile_row; + s->tile_group_info[tile_num].tile_column = tile_col; + return 0; + } + size_bytes = s->raw_frame_header->tile_size_bytes_minus1 + 1; + if (bytestream2_get_bytes_left(&gb) < size_bytes) + return AVERROR_INVALIDDATA; + size = 0; + for (int i = 0; i < size_bytes; i++) + size |= bytestream2_get_byteu(&gb) << 8 * i; + if (bytestream2_get_bytes_left(&gb) <= size) + return AVERROR_INVALIDDATA; + size++; + + s->tile_group_info[tile_num].tile_size = size; + s->tile_group_info[tile_num].tile_offset = bytestream2_tell(&gb); + s->tile_group_info[tile_num].tile_row = tile_row; + s->tile_group_info[tile_num].tile_column = tile_col; + + bytestream2_skipu(&gb, size); + } + + return 0; + +} + +static int get_pixel_format(AVCodecContext *avctx) +{ + AV1DecContext *s = avctx->priv_data; + const AV1RawSequenceHeader *seq = s->raw_seq; + uint8_t bit_depth; + int ret; + enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; +#define HWACCEL_MAX (CONFIG_AV1_DXVA2_HWACCEL + \ + CONFIG_AV1_D3D11VA_HWACCEL * 2 + \ + CONFIG_AV1_NVDEC_HWACCEL + \ + CONFIG_AV1_VAAPI_HWACCEL) + enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts; + + if (seq->seq_profile == 2 && seq->color_config.high_bitdepth) + bit_depth = seq->color_config.twelve_bit ? 12 : 10; + else if (seq->seq_profile <= 2) + bit_depth = seq->color_config.high_bitdepth ? 10 : 8; + else { + av_log(avctx, AV_LOG_ERROR, + "Unknown AV1 profile %d.\n", seq->seq_profile); + return -1; + } + + if (!seq->color_config.mono_chrome) { + // 4:4:4 x:0 y:0, 4:2:2 x:1 y:0, 4:2:0 x:1 y:1 + if (seq->color_config.subsampling_x == 0 && + seq->color_config.subsampling_y == 0) { + if (bit_depth == 8) + pix_fmt = AV_PIX_FMT_YUV444P; + else if (bit_depth == 10) + pix_fmt = AV_PIX_FMT_YUV444P10; + else if (bit_depth == 12) + pix_fmt = AV_PIX_FMT_YUV444P12; + else + av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n"); + } else if (seq->color_config.subsampling_x == 1 && + seq->color_config.subsampling_y == 0) { + if (bit_depth == 8) + pix_fmt = AV_PIX_FMT_YUV422P; + else if (bit_depth == 10) + pix_fmt = AV_PIX_FMT_YUV422P10; + else if (bit_depth == 12) + pix_fmt = AV_PIX_FMT_YUV422P12; + else + av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n"); + } else if (seq->color_config.subsampling_x == 1 && + seq->color_config.subsampling_y == 1) { + if (bit_depth == 8) + pix_fmt = AV_PIX_FMT_YUV420P; + else if (bit_depth == 10) + pix_fmt = AV_PIX_FMT_YUV420P10; + else if (bit_depth == 12) + pix_fmt = AV_PIX_FMT_YUV420P12; + else + av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n"); + } + } else { + if (bit_depth == 8) + pix_fmt = AV_PIX_FMT_GRAY8; + else if (bit_depth == 10) + pix_fmt = AV_PIX_FMT_GRAY10; + else if (bit_depth == 12) + pix_fmt = AV_PIX_FMT_GRAY12; + else + av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n"); + } + + av_log(avctx, AV_LOG_DEBUG, "AV1 decode get format: %s.\n", + av_get_pix_fmt_name(pix_fmt)); + + if (pix_fmt == AV_PIX_FMT_NONE) + return -1; + s->pix_fmt = pix_fmt; + + switch (s->pix_fmt) { + case AV_PIX_FMT_YUV420P: +#if CONFIG_AV1_DXVA2_HWACCEL + *fmtp++ = AV_PIX_FMT_DXVA2_VLD; +#endif +#if CONFIG_AV1_D3D11VA_HWACCEL + *fmtp++ = AV_PIX_FMT_D3D11VA_VLD; + *fmtp++ = AV_PIX_FMT_D3D11; +#endif +#if CONFIG_AV1_NVDEC_HWACCEL + *fmtp++ = AV_PIX_FMT_CUDA; +#endif +#if CONFIG_AV1_VAAPI_HWACCEL + *fmtp++ = AV_PIX_FMT_VAAPI; +#endif + break; + case AV_PIX_FMT_YUV420P10: +#if CONFIG_AV1_DXVA2_HWACCEL + *fmtp++ = AV_PIX_FMT_DXVA2_VLD; +#endif +#if CONFIG_AV1_D3D11VA_HWACCEL + *fmtp++ = AV_PIX_FMT_D3D11VA_VLD; + *fmtp++ = AV_PIX_FMT_D3D11; +#endif +#if CONFIG_AV1_NVDEC_HWACCEL + *fmtp++ = AV_PIX_FMT_CUDA; +#endif +#if CONFIG_AV1_VAAPI_HWACCEL + *fmtp++ = AV_PIX_FMT_VAAPI; +#endif + break; + case AV_PIX_FMT_GRAY8: +#if CONFIG_AV1_NVDEC_HWACCEL + *fmtp++ = AV_PIX_FMT_CUDA; +#endif + break; + case AV_PIX_FMT_GRAY10: +#if CONFIG_AV1_NVDEC_HWACCEL + *fmtp++ = AV_PIX_FMT_CUDA; +#endif + break; + } + + *fmtp++ = s->pix_fmt; + *fmtp = AV_PIX_FMT_NONE; + + ret = ff_thread_get_format(avctx, pix_fmts); + if (ret < 0) + return ret; + + /** + * check if the HW accel is inited correctly. If not, return un-implemented. + * Since now the av1 decoder doesn't support native decode, if it will be + * implemented in the future, need remove this check. + */ + if (!avctx->hwaccel) { + av_log(avctx, AV_LOG_ERROR, "Your platform doesn't suppport" + " hardware accelerated AV1 decoding.\n"); + return AVERROR(ENOSYS); + } + + avctx->pix_fmt = ret; + + return 0; +} + +static void av1_frame_unref(AVCodecContext *avctx, AV1Frame *f) +{ + ff_thread_release_buffer(avctx, &f->tf); + av_buffer_unref(&f->hwaccel_priv_buf); + f->hwaccel_picture_private = NULL; + av_buffer_unref(&f->header_ref); + f->raw_frame_header = NULL; + f->spatial_id = f->temporal_id = 0; + memset(f->skip_mode_frame_idx, 0, + 2 * sizeof(uint8_t)); + memset(&f->film_grain, 0, sizeof(f->film_grain)); + f->coded_lossless = 0; +} + +static int av1_frame_ref(AVCodecContext *avctx, AV1Frame *dst, const AV1Frame *src) +{ + int ret; + + ret = ff_thread_ref_frame(&dst->tf, &src->tf); + if (ret < 0) + return ret; + + dst->header_ref = av_buffer_ref(src->header_ref); + if (!dst->header_ref) + goto fail; + + dst->raw_frame_header = src->raw_frame_header; + + if (src->hwaccel_picture_private) { + dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf); + if (!dst->hwaccel_priv_buf) + goto fail; + dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data; + } + + dst->spatial_id = src->spatial_id; + dst->temporal_id = src->temporal_id; + memcpy(dst->gm_type, + src->gm_type, + AV1_NUM_REF_FRAMES * sizeof(uint8_t)); + memcpy(dst->gm_params, + src->gm_params, + AV1_NUM_REF_FRAMES * 6 * sizeof(int32_t)); + memcpy(dst->skip_mode_frame_idx, + src->skip_mode_frame_idx, + 2 * sizeof(uint8_t)); + memcpy(&dst->film_grain, + &src->film_grain, + sizeof(dst->film_grain)); + dst->coded_lossless = src->coded_lossless; + + return 0; + +fail: + av1_frame_unref(avctx, dst); + return AVERROR(ENOMEM); +} + +static av_cold int av1_decode_free(AVCodecContext *avctx) +{ + AV1DecContext *s = avctx->priv_data; + + for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) { + av1_frame_unref(avctx, &s->ref[i]); + av_frame_free(&s->ref[i].tf.f); + } + av1_frame_unref(avctx, &s->cur_frame); + av_frame_free(&s->cur_frame.tf.f); + + av_buffer_unref(&s->seq_ref); + av_buffer_unref(&s->header_ref); + av_freep(&s->tile_group_info); + + ff_cbs_fragment_free(&s->current_obu); + ff_cbs_close(&s->cbc); + + return 0; +} + +static int set_context_with_sequence(AVCodecContext *avctx, + const AV1RawSequenceHeader *seq) +{ + int width = seq->max_frame_width_minus_1 + 1; + int height = seq->max_frame_height_minus_1 + 1; + + avctx->profile = seq->seq_profile; + avctx->level = seq->seq_level_idx[0]; + + avctx->color_range = + seq->color_config.color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; + avctx->color_primaries = seq->color_config.color_primaries; + avctx->colorspace = seq->color_config.color_primaries; + avctx->color_trc = seq->color_config.transfer_characteristics; + + switch (seq->color_config.chroma_sample_position) { + case AV1_CSP_VERTICAL: + avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; + break; + case AV1_CSP_COLOCATED: + avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; + break; + } + + if (avctx->width != width || avctx->height != height) { + int ret = ff_set_dimensions(avctx, width, height); + if (ret < 0) + return ret; + } + avctx->sample_aspect_ratio = (AVRational) { 1, 1 }; + + if (seq->timing_info.num_units_in_display_tick && + seq->timing_info.time_scale) { + av_reduce(&avctx->framerate.den, &avctx->framerate.num, + seq->timing_info.num_units_in_display_tick, + seq->timing_info.time_scale, + INT_MAX); + if (seq->timing_info.equal_picture_interval) + avctx->ticks_per_frame = seq->timing_info.num_ticks_per_picture_minus_1 + 1; + } + + return 0; +} + +static int update_context_with_frame_header(AVCodecContext *avctx, + const AV1RawFrameHeader *header) +{ + AVRational aspect_ratio; + int width = header->frame_width_minus_1 + 1; + int height = header->frame_height_minus_1 + 1; + int r_width = header->render_width_minus_1 + 1; + int r_height = header->render_height_minus_1 + 1; + int ret; + + if (avctx->width != width || avctx->height != height) { + ret = ff_set_dimensions(avctx, width, height); + if (ret < 0) + return ret; + } + + av_reduce(&aspect_ratio.num, &aspect_ratio.den, + (int64_t)height * r_width, + (int64_t)width * r_height, + INT_MAX); + + if (av_cmp_q(avctx->sample_aspect_ratio, aspect_ratio)) { + ret = ff_set_sar(avctx, aspect_ratio); + if (ret < 0) + return ret; + } + + return 0; +} + +static av_cold int av1_decode_init(AVCodecContext *avctx) +{ + AV1DecContext *s = avctx->priv_data; + AV1RawSequenceHeader *seq; + int ret; + + s->avctx = avctx; + s->pix_fmt = AV_PIX_FMT_NONE; + + for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) { + s->ref[i].tf.f = av_frame_alloc(); + if (!s->ref[i].tf.f) { + av_log(avctx, AV_LOG_ERROR, + "Failed to allocate reference frame buffer %d.\n", i); + return AVERROR(ENOMEM); + } + } + + s->cur_frame.tf.f = av_frame_alloc(); + if (!s->cur_frame.tf.f) { + av_log(avctx, AV_LOG_ERROR, + "Failed to allocate current frame buffer.\n"); + return AVERROR(ENOMEM); + } + + ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_AV1, avctx); + if (ret < 0) + return ret; + + av_opt_set_int(s->cbc->priv_data, "operating_point", s->operating_point, 0); + + if (avctx->extradata && avctx->extradata_size) { + ret = ff_cbs_read_extradata_from_codec(s->cbc, + &s->current_obu, + avctx); + if (ret < 0) { + av_log(avctx, AV_LOG_WARNING, "Failed to read extradata.\n"); + return ret; + } + + seq = ((CodedBitstreamAV1Context *)(s->cbc->priv_data))->sequence_header; + if (!seq) { + av_log(avctx, AV_LOG_WARNING, "No sequence header available.\n"); + goto end; + } + + ret = set_context_with_sequence(avctx, seq); + if (ret < 0) { + av_log(avctx, AV_LOG_WARNING, "Failed to set decoder context.\n"); + goto end; + } + + end: + ff_cbs_fragment_reset(&s->current_obu); + } + + return ret; +} + +static int av1_frame_alloc(AVCodecContext *avctx, AV1Frame *f) +{ + AV1DecContext *s = avctx->priv_data; + AV1RawFrameHeader *header= s->raw_frame_header; + AVFrame *frame; + int ret; + + ret = update_context_with_frame_header(avctx, header); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to update context with frame header\n"); + return ret; + } + + f->header_ref = av_buffer_ref(s->header_ref); + if (!f->header_ref) + return AVERROR(ENOMEM); + + f->raw_frame_header = s->raw_frame_header; + + if ((ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0) + goto fail; + + frame = f->tf.f; + frame->key_frame = header->frame_type == AV1_FRAME_KEY; + + switch (header->frame_type) { + case AV1_FRAME_KEY: + case AV1_FRAME_INTRA_ONLY: + frame->pict_type = AV_PICTURE_TYPE_I; + break; + case AV1_FRAME_INTER: + frame->pict_type = AV_PICTURE_TYPE_P; + break; + case AV1_FRAME_SWITCH: + frame->pict_type = AV_PICTURE_TYPE_SP; + break; + } + + if (avctx->hwaccel) { + const AVHWAccel *hwaccel = avctx->hwaccel; + if (hwaccel->frame_priv_data_size) { + f->hwaccel_priv_buf = + av_buffer_allocz(hwaccel->frame_priv_data_size); + if (!f->hwaccel_priv_buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + f->hwaccel_picture_private = f->hwaccel_priv_buf->data; + } + } + return 0; + +fail: + av1_frame_unref(avctx, f); + return ret; +} + +static int export_film_grain(AVCodecContext *avctx, AVFrame *frame) +{ + AV1DecContext *s = avctx->priv_data; + const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain; + AVFilmGrainParams *fgp; + AVFilmGrainAOMParams *aom; + + if (!film_grain->apply_grain) + return 0; + + fgp = av_film_grain_params_create_side_data(frame); + if (!fgp) + return AVERROR(ENOMEM); + + fgp->type = AV_FILM_GRAIN_PARAMS_AV1; + fgp->seed = film_grain->grain_seed; + + aom = &fgp->codec.aom; + aom->chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma; + aom->scaling_shift = film_grain->grain_scaling_minus_8 + 8; + aom->ar_coeff_lag = film_grain->ar_coeff_lag; + aom->ar_coeff_shift = film_grain->ar_coeff_shift_minus_6 + 6; + aom->grain_scale_shift = film_grain->grain_scale_shift; + aom->overlap_flag = film_grain->overlap_flag; + aom->limit_output_range = film_grain->clip_to_restricted_range; + + aom->num_y_points = film_grain->num_y_points; + for (int i = 0; i < film_grain->num_y_points; i++) { + aom->y_points[i][0] = film_grain->point_y_value[i]; + aom->y_points[i][1] = film_grain->point_y_scaling[i]; + } + aom->num_uv_points[0] = film_grain->num_cb_points; + for (int i = 0; i < film_grain->num_cb_points; i++) { + aom->uv_points[0][i][0] = film_grain->point_cb_value[i]; + aom->uv_points[0][i][1] = film_grain->point_cb_scaling[i]; + } + aom->num_uv_points[1] = film_grain->num_cr_points; + for (int i = 0; i < film_grain->num_cr_points; i++) { + aom->uv_points[1][i][0] = film_grain->point_cr_value[i]; + aom->uv_points[1][i][1] = film_grain->point_cr_scaling[i]; + } + + for (int i = 0; i < 24; i++) { + aom->ar_coeffs_y[i] = film_grain->ar_coeffs_y_plus_128[i] - 128; + } + for (int i = 0; i < 25; i++) { + aom->ar_coeffs_uv[0][i] = film_grain->ar_coeffs_cb_plus_128[i] - 128; + aom->ar_coeffs_uv[1][i] = film_grain->ar_coeffs_cr_plus_128[i] - 128; + } + + aom->uv_mult[0] = film_grain->cb_mult; + aom->uv_mult[1] = film_grain->cr_mult; + aom->uv_mult_luma[0] = film_grain->cb_luma_mult; + aom->uv_mult_luma[1] = film_grain->cr_luma_mult; + aom->uv_offset[0] = film_grain->cb_offset; + aom->uv_offset[1] = film_grain->cr_offset; + + return 0; +} + +static int set_output_frame(AVCodecContext *avctx, AVFrame *frame, + const AVPacket *pkt, int *got_frame) +{ + AV1DecContext *s = avctx->priv_data; + const AVFrame *srcframe = s->cur_frame.tf.f; + int ret; + + // TODO: all layers + if (s->operating_point_idc && + av_log2(s->operating_point_idc >> 8) > s->cur_frame.spatial_id) + return 0; + + ret = av_frame_ref(frame, srcframe); + if (ret < 0) + return ret; + + if (avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) { + ret = export_film_grain(avctx, frame); + if (ret < 0) { + av_frame_unref(frame); + return ret; + } + } + + frame->pts = pkt->pts; + frame->pkt_dts = pkt->dts; + frame->pkt_size = pkt->size; + + *got_frame = 1; + + return 0; +} + +static int update_reference_list(AVCodecContext *avctx) +{ + AV1DecContext *s = avctx->priv_data; + const AV1RawFrameHeader *header = s->raw_frame_header; + int ret; + + for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) { + if (header->refresh_frame_flags & (1 << i)) { + if (s->ref[i].tf.f->buf[0]) + av1_frame_unref(avctx, &s->ref[i]); + if ((ret = av1_frame_ref(avctx, &s->ref[i], &s->cur_frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, + "Failed to update frame %d in reference list\n", i); + return ret; + } + } + } + return 0; +} + +static int get_current_frame(AVCodecContext *avctx) +{ + AV1DecContext *s = avctx->priv_data; + int ret; + + if (s->cur_frame.tf.f->buf[0]) + av1_frame_unref(avctx, &s->cur_frame); + + ret = av1_frame_alloc(avctx, &s->cur_frame); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Failed to allocate space for current frame.\n"); + return ret; + } + + ret = init_tile_data(s); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to init tile data.\n"); + return ret; + } + + global_motion_params(s); + skip_mode_params(s); + coded_lossless_param(s); + load_grain_params(s); + + return ret; +} + +static int av1_decode_frame(AVCodecContext *avctx, void *frame, + int *got_frame, AVPacket *pkt) +{ + AV1DecContext *s = avctx->priv_data; + AV1RawTileGroup *raw_tile_group = NULL; + int ret; + + ret = ff_cbs_read_packet(s->cbc, &s->current_obu, pkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to read packet.\n"); + goto end; + } + av_log(avctx, AV_LOG_DEBUG, "Total obu for this frame:%d.\n", + s->current_obu.nb_units); + + for (int i = 0; i < s->current_obu.nb_units; i++) { + CodedBitstreamUnit *unit = &s->current_obu.units[i]; + AV1RawOBU *obu = unit->content; + const AV1RawOBUHeader *header; + + if (!obu) + continue; + + header = &obu->header; + av_log(avctx, AV_LOG_DEBUG, "Obu idx:%d, obu type:%d.\n", i, unit->type); + + switch (unit->type) { + case AV1_OBU_SEQUENCE_HEADER: + av_buffer_unref(&s->seq_ref); + s->seq_ref = av_buffer_ref(unit->content_ref); + if (!s->seq_ref) { + ret = AVERROR(ENOMEM); + goto end; + } + + s->raw_seq = &obu->obu.sequence_header; + + ret = set_context_with_sequence(avctx, s->raw_seq); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to set context.\n"); + s->raw_seq = NULL; + goto end; + } + + s->operating_point_idc = s->raw_seq->operating_point_idc[s->operating_point]; + + if (s->pix_fmt == AV_PIX_FMT_NONE) { + ret = get_pixel_format(avctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Failed to get pixel format.\n"); + s->raw_seq = NULL; + goto end; + } + } + + if (avctx->hwaccel && avctx->hwaccel->decode_params) { + ret = avctx->hwaccel->decode_params(avctx, unit->type, unit->data, + unit->data_size); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "HW accel decode params fail.\n"); + s->raw_seq = NULL; + goto end; + } + } + break; + case AV1_OBU_REDUNDANT_FRAME_HEADER: + if (s->raw_frame_header) + break; + // fall-through + case AV1_OBU_FRAME: + case AV1_OBU_FRAME_HEADER: + if (!s->raw_seq) { + av_log(avctx, AV_LOG_ERROR, "Missing Sequence Header.\n"); + ret = AVERROR_INVALIDDATA; + goto end; + } + + av_buffer_unref(&s->header_ref); + s->header_ref = av_buffer_ref(unit->content_ref); + if (!s->header_ref) { + ret = AVERROR(ENOMEM); + goto end; + } + + if (unit->type == AV1_OBU_FRAME) + s->raw_frame_header = &obu->obu.frame.header; + else + s->raw_frame_header = &obu->obu.frame_header; + + if (s->raw_frame_header->show_existing_frame) { + if (s->cur_frame.tf.f->buf[0]) + av1_frame_unref(avctx, &s->cur_frame); + + ret = av1_frame_ref(avctx, &s->cur_frame, + &s->ref[s->raw_frame_header->frame_to_show_map_idx]); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to get reference frame.\n"); + goto end; + } + + ret = update_reference_list(avctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to update reference list.\n"); + goto end; + } + + ret = set_output_frame(avctx, frame, pkt, got_frame); + if (ret < 0) + av_log(avctx, AV_LOG_ERROR, "Set output frame error.\n"); + + s->raw_frame_header = NULL; + + goto end; + } + + ret = get_current_frame(avctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Get current frame error\n"); + goto end; + } + + s->cur_frame.spatial_id = header->spatial_id; + s->cur_frame.temporal_id = header->temporal_id; + + if (avctx->hwaccel) { + ret = avctx->hwaccel->start_frame(avctx, unit->data, + unit->data_size); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "HW accel start frame fail.\n"); + goto end; + } + } + if (unit->type != AV1_OBU_FRAME) + break; + // fall-through + case AV1_OBU_TILE_GROUP: + if (!s->raw_frame_header) { + av_log(avctx, AV_LOG_ERROR, "Missing Frame Header.\n"); + ret = AVERROR_INVALIDDATA; + goto end; + } + + if (unit->type == AV1_OBU_FRAME) + raw_tile_group = &obu->obu.frame.tile_group; + else + raw_tile_group = &obu->obu.tile_group; + + ret = get_tiles_info(avctx, raw_tile_group); + if (ret < 0) + goto end; + + if (avctx->hwaccel) { + ret = avctx->hwaccel->decode_slice(avctx, + raw_tile_group->tile_data.data, + raw_tile_group->tile_data.data_size); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "HW accel decode slice fail.\n"); + goto end; + } + } + break; + case AV1_OBU_TILE_LIST: + case AV1_OBU_TEMPORAL_DELIMITER: + case AV1_OBU_PADDING: + case AV1_OBU_METADATA: + break; + default: + av_log(avctx, AV_LOG_DEBUG, + "Unknown obu type: %d (%"SIZE_SPECIFIER" bits).\n", + unit->type, unit->data_size); + } + + if (raw_tile_group && (s->tile_num == raw_tile_group->tg_end + 1)) { + if (avctx->hwaccel) { + ret = avctx->hwaccel->end_frame(avctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "HW accel end frame fail.\n"); + goto end; + } + } + + ret = update_reference_list(avctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to update reference list.\n"); + goto end; + } + + if (s->raw_frame_header->show_frame) { + ret = set_output_frame(avctx, frame, pkt, got_frame); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Set output frame error\n"); + goto end; + } + } + raw_tile_group = NULL; + s->raw_frame_header = NULL; + } + } + +end: + ff_cbs_fragment_reset(&s->current_obu); + if (ret < 0) + s->raw_frame_header = NULL; + return ret; +} + +static void av1_decode_flush(AVCodecContext *avctx) +{ + AV1DecContext *s = avctx->priv_data; + + for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) + av1_frame_unref(avctx, &s->ref[i]); + + av1_frame_unref(avctx, &s->cur_frame); + s->operating_point_idc = 0; + s->raw_frame_header = NULL; + s->raw_seq = NULL; + + ff_cbs_flush(s->cbc); +} + +#define OFFSET(x) offsetof(AV1DecContext, x) +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM +static const AVOption av1_options[] = { + { "operating_point", "Select an operating point of the scalable bitstream", + OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, AV1_MAX_OPERATING_POINTS - 1, VD }, + { NULL } +}; + +static const AVClass av1_class = { + .class_name = "AV1 decoder", + .item_name = av_default_item_name, + .option = av1_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_av1_decoder = { + .name = "av1", + .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_AV1, + .priv_data_size = sizeof(AV1DecContext), + .init = av1_decode_init, + .close = av1_decode_free, + .decode = av1_decode_frame, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_SETS_PKT_DTS, + .flush = av1_decode_flush, + .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), + .priv_class = &av1_class, + .hw_configs = (const AVCodecHWConfigInternal *const []) { +#if CONFIG_AV1_DXVA2_HWACCEL + HWACCEL_DXVA2(av1), +#endif +#if CONFIG_AV1_D3D11VA_HWACCEL + HWACCEL_D3D11VA(av1), +#endif +#if CONFIG_AV1_D3D11VA2_HWACCEL + HWACCEL_D3D11VA2(av1), +#endif +#if CONFIG_AV1_NVDEC_HWACCEL + HWACCEL_NVDEC(av1), +#endif +#if CONFIG_AV1_VAAPI_HWACCEL + HWACCEL_VAAPI(av1), +#endif + NULL + }, +}; diff --git a/libavcodec/av1dec.h b/libavcodec/av1dec.h new file mode 100644 index 000000000..248a68750 --- /dev/null +++ b/libavcodec/av1dec.h @@ -0,0 +1,88 @@ +/* + * AV1 video decoder + * * + * 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_AV1DEC_H +#define AVCODEC_AV1DEC_H + +#include + +#include "libavutil/buffer.h" +#include "libavutil/pixfmt.h" +#include "avcodec.h" +#include "cbs.h" +#include "cbs_av1.h" +#include "thread.h" + +typedef struct AV1Frame { + ThreadFrame tf; + + AVBufferRef *hwaccel_priv_buf; + void *hwaccel_picture_private; + + AVBufferRef *header_ref; + AV1RawFrameHeader *raw_frame_header; + + int temporal_id; + int spatial_id; + + uint8_t gm_type[AV1_NUM_REF_FRAMES]; + int32_t gm_params[AV1_NUM_REF_FRAMES][6]; + + uint8_t skip_mode_frame_idx[2]; + + AV1RawFilmGrainParams film_grain; + + uint8_t coded_lossless; +} AV1Frame; + +typedef struct TileGroupInfo { + uint32_t tile_offset; + uint32_t tile_size; + uint16_t tile_row; + uint16_t tile_column; +} TileGroupInfo; + +typedef struct AV1DecContext { + const AVClass *class; + AVCodecContext *avctx; + + enum AVPixelFormat pix_fmt; + CodedBitstreamContext *cbc; + CodedBitstreamFragment current_obu; + + AVBufferRef *seq_ref; + AV1RawSequenceHeader *raw_seq; + AVBufferRef *header_ref; + AV1RawFrameHeader *raw_frame_header; + TileGroupInfo *tile_group_info; + uint16_t tile_num; + uint16_t tg_start; + uint16_t tg_end; + + int operating_point_idc; + + AV1Frame ref[AV1_NUM_REF_FRAMES]; + AV1Frame cur_frame; + + // AVOptions + int operating_point; +} AV1DecContext; + +#endif /* AVCODEC_AV1DEC_H */ diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c new file mode 100644 index 000000000..e572e9533 --- /dev/null +++ b/libavcodec/avcodec.c @@ -0,0 +1,851 @@ +/* + * AVCodecContext functions for libavcodec + * + * 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 + * AVCodecContext functions for libavcodec + */ + +#include "config.h" +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/imgutils.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include "libavutil/thread.h" +#include "avcodec.h" +#include "decode.h" +#include "encode.h" +#include "frame_thread_encoder.h" +#include "internal.h" +#include "thread.h" +#if CONFIG_ICONV +# include +#endif + +#include "libavutil/ffversion.h" +const char av_codec_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + +unsigned avcodec_version(void) +{ + av_assert0(AV_CODEC_ID_PCM_S8_PLANAR==65563); + av_assert0(AV_CODEC_ID_ADPCM_G722==69660); + av_assert0(AV_CODEC_ID_SRT==94216); + av_assert0(LIBAVCODEC_VERSION_MICRO >= 100); + + return LIBAVCODEC_VERSION_INT; +} + +const char *avcodec_configuration(void) +{ + return FFMPEG_CONFIGURATION; +} + +const char *avcodec_license(void) +{ +#define LICENSE_PREFIX "libavcodec license: " + return &LICENSE_PREFIX FFMPEG_LICENSE[sizeof(LICENSE_PREFIX) - 1]; +} + +int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) +{ + int i; + + for (i = 0; i < count; i++) { + int r = func(c, (char *)arg + i * size); + if (ret) + ret[i] = r; + } + emms_c(); + return 0; +} + +int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int jobnr, int threadnr), void *arg, int *ret, int count) +{ + int i; + + for (i = 0; i < count; i++) { + int r = func(c, arg, i, 0); + if (ret) + ret[i] = r; + } + emms_c(); + return 0; +} + +static AVMutex codec_mutex = AV_MUTEX_INITIALIZER; + +static void lock_avcodec(const AVCodec *codec) +{ + if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init) + ff_mutex_lock(&codec_mutex); +} + +static void unlock_avcodec(const AVCodec *codec) +{ + if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init) + ff_mutex_unlock(&codec_mutex); +} + +#if FF_API_LOCKMGR +int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) +{ + return 0; +} +#endif + +static int64_t get_bit_rate(AVCodecContext *ctx) +{ + int64_t bit_rate; + int bits_per_sample; + + switch (ctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + case AVMEDIA_TYPE_DATA: + case AVMEDIA_TYPE_SUBTITLE: + case AVMEDIA_TYPE_ATTACHMENT: + bit_rate = ctx->bit_rate; + break; + case AVMEDIA_TYPE_AUDIO: + bits_per_sample = av_get_bits_per_sample(ctx->codec_id); + if (bits_per_sample) { + bit_rate = ctx->sample_rate * (int64_t)ctx->channels; + if (bit_rate > INT64_MAX / bits_per_sample) { + bit_rate = 0; + } else + bit_rate *= bits_per_sample; + } else + bit_rate = ctx->bit_rate; + break; + default: + bit_rate = 0; + break; + } + return bit_rate; +} + +int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) +{ + int ret = 0; + int codec_init_ok = 0; + AVDictionary *tmp = NULL; + AVCodecInternal *avci; + + if (avcodec_is_open(avctx)) + return 0; + + if (!codec && !avctx->codec) { + av_log(avctx, AV_LOG_ERROR, "No codec provided to avcodec_open2()\n"); + return AVERROR(EINVAL); + } + if (codec && avctx->codec && codec != avctx->codec) { + av_log(avctx, AV_LOG_ERROR, "This AVCodecContext was allocated for %s, " + "but %s passed to avcodec_open2()\n", avctx->codec->name, codec->name); + return AVERROR(EINVAL); + } + if (!codec) + codec = avctx->codec; + + if (avctx->extradata_size < 0 || avctx->extradata_size >= FF_MAX_EXTRADATA_SIZE) + return AVERROR(EINVAL); + + if (options) + av_dict_copy(&tmp, *options, 0); + + lock_avcodec(codec); + + avci = av_mallocz(sizeof(*avci)); + if (!avci) { + ret = AVERROR(ENOMEM); + goto end; + } + avctx->internal = avci; + +#if FF_API_OLD_ENCDEC + avci->to_free = av_frame_alloc(); + avci->compat_decode_frame = av_frame_alloc(); + avci->compat_encode_packet = av_packet_alloc(); + if (!avci->to_free || !avci->compat_decode_frame || !avci->compat_encode_packet) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } +#endif + avci->buffer_frame = av_frame_alloc(); + avci->buffer_pkt = av_packet_alloc(); + avci->es.in_frame = av_frame_alloc(); + avci->ds.in_pkt = av_packet_alloc(); + avci->last_pkt_props = av_packet_alloc(); + avci->pkt_props = av_fifo_alloc(sizeof(*avci->last_pkt_props)); + if (!avci->buffer_frame || !avci->buffer_pkt || + !avci->es.in_frame || !avci->ds.in_pkt || + !avci->last_pkt_props || !avci->pkt_props) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avci->skip_samples_multiplier = 1; + + if (codec->priv_data_size > 0) { + if (!avctx->priv_data) { + avctx->priv_data = av_mallocz(codec->priv_data_size); + if (!avctx->priv_data) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + if (codec->priv_class) { + *(const AVClass **)avctx->priv_data = codec->priv_class; + av_opt_set_defaults(avctx->priv_data); + } + } + if (codec->priv_class && (ret = av_opt_set_dict(avctx->priv_data, &tmp)) < 0) + goto free_and_end; + } else { + avctx->priv_data = NULL; + } + if ((ret = av_opt_set_dict(avctx, &tmp)) < 0) + goto free_and_end; + + if (avctx->codec_whitelist && av_match_list(codec->name, avctx->codec_whitelist, ',') <= 0) { + av_log(avctx, AV_LOG_ERROR, "Codec (%s) not on whitelist \'%s\'\n", codec->name, avctx->codec_whitelist); + ret = AVERROR(EINVAL); + goto free_and_end; + } + + // only call ff_set_dimensions() for non H.264/VP6F/DXV 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 || avctx->codec_id == AV_CODEC_ID_DXV))) { + if (avctx->coded_width && avctx->coded_height) + ret = ff_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); + else if (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_size2(avctx->coded_width, avctx->coded_height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0 + || av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0)) { + av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n"); + ff_set_dimensions(avctx, 0, 0); + } + + if (avctx->width > 0 && avctx->height > 0) { + if (av_image_check_sar(avctx->width, avctx->height, + avctx->sample_aspect_ratio) < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + avctx->sample_aspect_ratio.num, + avctx->sample_aspect_ratio.den); + avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; + } + } + + if (avctx->channels > FF_SANE_NB_CHANNELS || avctx->channels < 0) { + av_log(avctx, AV_LOG_ERROR, "Too many or invalid channels: %d\n", avctx->channels); + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (av_codec_is_decoder(codec) && + codec->type == AVMEDIA_TYPE_AUDIO && + !(codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF) && + avctx->channels == 0) { + av_log(avctx, AV_LOG_ERROR, "Decoder requires channel count but channels not set\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } + + if (avctx->sample_rate < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid sample rate: %d\n", avctx->sample_rate); + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->block_align < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid block align: %d\n", avctx->block_align); + ret = AVERROR(EINVAL); + goto free_and_end; + } + + avctx->codec = codec; + if ((avctx->codec_type == AVMEDIA_TYPE_UNKNOWN || avctx->codec_type == codec->type) && + avctx->codec_id == AV_CODEC_ID_NONE) { + avctx->codec_type = codec->type; + avctx->codec_id = codec->id; + } + if (avctx->codec_id != codec->id || (avctx->codec_type != codec->type + && avctx->codec_type != AVMEDIA_TYPE_ATTACHMENT)) { + av_log(avctx, AV_LOG_ERROR, "Codec type or id mismatches\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } + avctx->frame_number = 0; + avctx->codec_descriptor = avcodec_descriptor_get(avctx->codec_id); + + if ((avctx->codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) && + avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + const char *codec_string = av_codec_is_encoder(codec) ? "encoder" : "decoder"; + const AVCodec *codec2; + 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 & AV_CODEC_CAP_EXPERIMENTAL)) + 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; + } + + if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && + (!avctx->time_base.num || !avctx->time_base.den)) { + avctx->time_base.num = 1; + avctx->time_base.den = avctx->sample_rate; + } + + if (av_codec_is_encoder(avctx->codec)) + ret = ff_encode_preinit(avctx); + else + ret = ff_decode_preinit(avctx); + if (ret < 0) + goto free_and_end; + + if (!HAVE_THREADS) + av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n"); + + if (CONFIG_FRAME_THREAD_ENCODER && av_codec_is_encoder(avctx->codec)) { + unlock_avcodec(codec); //we will instantiate a few encoders thus kick the counter to prevent false detection of a problem + ret = ff_frame_thread_encoder_init(avctx, options ? *options : NULL); + lock_avcodec(codec); + if (ret < 0) + goto free_and_end; + } + + if (HAVE_THREADS + && !(avci->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) { + ret = ff_thread_init(avctx); + if (ret < 0) { + goto free_and_end; + } + } + if (!HAVE_THREADS && !(codec->caps_internal & FF_CODEC_CAP_AUTO_THREADS)) + avctx->thread_count = 1; + + if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME) + || avci->frame_thread_encoder)) { + ret = avctx->codec->init(avctx); + if (ret < 0) { + codec_init_ok = -1; + goto free_and_end; + } + codec_init_ok = 1; + } + + ret=0; + + if (av_codec_is_decoder(avctx->codec)) { + if (!avctx->bit_rate) + avctx->bit_rate = get_bit_rate(avctx); + /* validate channel layout from the decoder */ + if (avctx->channel_layout) { + int channels = av_get_channel_layout_nb_channels(avctx->channel_layout); + if (!avctx->channels) + avctx->channels = channels; + else if (channels != avctx->channels) { + char buf[512]; + av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); + av_log(avctx, AV_LOG_WARNING, + "Channel layout '%s' with %d channels does not match specified number of channels %d: " + "ignoring specified channel layout\n", + buf, channels, avctx->channels); + avctx->channel_layout = 0; + } + } + if (avctx->channels && avctx->channels < 0 || + avctx->channels > FF_SANE_NB_CHANNELS) { + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->bits_per_coded_sample < 0) { + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->sub_charenc) { + if (avctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { + av_log(avctx, AV_LOG_ERROR, "Character encoding is only " + "supported with subtitles codecs\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } else if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) { + av_log(avctx, AV_LOG_WARNING, "Codec '%s' is bitmap-based, " + "subtitles character encoding will be ignored\n", + avctx->codec_descriptor->name); + avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_DO_NOTHING; + } else { + /* input character encoding is set for a text based subtitle + * codec at this point */ + if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_AUTOMATIC) + avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_PRE_DECODER; + + if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_PRE_DECODER) { +#if CONFIG_ICONV + iconv_t cd = iconv_open("UTF-8", avctx->sub_charenc); + if (cd == (iconv_t)-1) { + ret = AVERROR(errno); + av_log(avctx, AV_LOG_ERROR, "Unable to open iconv context " + "with input character encoding \"%s\"\n", avctx->sub_charenc); + goto free_and_end; + } + iconv_close(cd); +#else + av_log(avctx, AV_LOG_ERROR, "Character encoding subtitles " + "conversion needs a libavcodec built with iconv support " + "for this codec\n"); + ret = AVERROR(ENOSYS); + goto free_and_end; +#endif + } + } + } + +#if FF_API_AVCTX_TIMEBASE + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); +#endif + } + if (codec->priv_data_size > 0 && avctx->priv_data && codec->priv_class) { + av_assert0(*(const AVClass **)avctx->priv_data == codec->priv_class); + } + +end: + unlock_avcodec(codec); + if (options) { + av_dict_free(options); + *options = tmp; + } + + return ret; +free_and_end: + if (avctx->codec && avctx->codec->close && + (codec_init_ok > 0 || (codec_init_ok < 0 && + avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP))) + avctx->codec->close(avctx); + + if (HAVE_THREADS && avci->thread_ctx) + ff_thread_free(avctx); + + if (codec->priv_class && avctx->priv_data) + av_opt_free(avctx->priv_data); + av_opt_free(avctx); + + if (av_codec_is_encoder(avctx->codec)) { +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + av_frame_free(&avctx->coded_frame); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + av_freep(&avctx->extradata); + avctx->extradata_size = 0; + } + + av_dict_free(&tmp); + av_freep(&avctx->priv_data); + av_freep(&avctx->subtitle_header); + +#if FF_API_OLD_ENCDEC + av_frame_free(&avci->to_free); + av_frame_free(&avci->compat_decode_frame); + av_packet_free(&avci->compat_encode_packet); +#endif + av_frame_free(&avci->buffer_frame); + av_packet_free(&avci->buffer_pkt); + av_packet_free(&avci->last_pkt_props); + av_fifo_freep(&avci->pkt_props); + + av_packet_free(&avci->ds.in_pkt); + av_frame_free(&avci->es.in_frame); + av_bsf_free(&avci->bsf); + + av_buffer_unref(&avci->pool); + av_freep(&avci); + avctx->internal = NULL; + avctx->codec = NULL; + goto end; +} + +void avcodec_flush_buffers(AVCodecContext *avctx) +{ + AVCodecInternal *avci = avctx->internal; + + if (av_codec_is_encoder(avctx->codec)) { + int caps = avctx->codec->capabilities; + + if (!(caps & AV_CODEC_CAP_ENCODER_FLUSH)) { + // Only encoders that explicitly declare support for it can be + // flushed. Otherwise, this is a no-op. + av_log(avctx, AV_LOG_WARNING, "Ignoring attempt to flush encoder " + "that doesn't support it\n"); + return; + } + + // We haven't implemented flushing for frame-threaded encoders. + av_assert0(!(caps & AV_CODEC_CAP_FRAME_THREADS)); + } + + avci->draining = 0; + avci->draining_done = 0; + avci->nb_draining_errors = 0; + av_frame_unref(avci->buffer_frame); +#if FF_API_OLD_ENCDEC + av_frame_unref(avci->compat_decode_frame); + av_packet_unref(avci->compat_encode_packet); +#endif + av_packet_unref(avci->buffer_pkt); + + av_packet_unref(avci->last_pkt_props); + while (av_fifo_size(avci->pkt_props) >= sizeof(*avci->last_pkt_props)) { + av_fifo_generic_read(avci->pkt_props, + avci->last_pkt_props, sizeof(*avci->last_pkt_props), + NULL); + av_packet_unref(avci->last_pkt_props); + } + av_fifo_reset(avci->pkt_props); + + av_frame_unref(avci->es.in_frame); + av_packet_unref(avci->ds.in_pkt); + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) + ff_thread_flush(avctx); + else if (avctx->codec->flush) + avctx->codec->flush(avctx); + + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; + + if (av_codec_is_decoder(avctx->codec)) + av_bsf_flush(avci->bsf); + +#if FF_API_OLD_ENCDEC +FF_DISABLE_DEPRECATION_WARNINGS + if (!avctx->refcounted_frames) + av_frame_unref(avci->to_free); +FF_ENABLE_DEPRECATION_WARNINGS +#endif +} + +void avsubtitle_free(AVSubtitle *sub) +{ + int i; + + for (i = 0; i < sub->num_rects; i++) { + av_freep(&sub->rects[i]->data[0]); + av_freep(&sub->rects[i]->data[1]); + av_freep(&sub->rects[i]->data[2]); + av_freep(&sub->rects[i]->data[3]); + av_freep(&sub->rects[i]->text); + av_freep(&sub->rects[i]->ass); + av_freep(&sub->rects[i]); + } + + av_freep(&sub->rects); + + memset(sub, 0, sizeof(*sub)); +} + +av_cold int avcodec_close(AVCodecContext *avctx) +{ + int i; + + if (!avctx) + return 0; + + if (avcodec_is_open(avctx)) { + if (CONFIG_FRAME_THREAD_ENCODER && + avctx->internal->frame_thread_encoder && avctx->thread_count > 1) { + ff_frame_thread_encoder_free(avctx); + } + if (HAVE_THREADS && avctx->internal->thread_ctx) + ff_thread_free(avctx); + if (avctx->codec && avctx->codec->close) + avctx->codec->close(avctx); + avctx->internal->byte_buffer_size = 0; + av_freep(&avctx->internal->byte_buffer); +#if FF_API_OLD_ENCDEC + av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->compat_decode_frame); + av_packet_free(&avctx->internal->compat_encode_packet); +#endif + av_frame_free(&avctx->internal->buffer_frame); + av_packet_free(&avctx->internal->buffer_pkt); + av_packet_unref(avctx->internal->last_pkt_props); + while (av_fifo_size(avctx->internal->pkt_props) >= + sizeof(*avctx->internal->last_pkt_props)) { + av_fifo_generic_read(avctx->internal->pkt_props, + avctx->internal->last_pkt_props, + sizeof(*avctx->internal->last_pkt_props), + NULL); + av_packet_unref(avctx->internal->last_pkt_props); + } + av_packet_free(&avctx->internal->last_pkt_props); + av_fifo_freep(&avctx->internal->pkt_props); + + av_packet_free(&avctx->internal->ds.in_pkt); + av_frame_free(&avctx->internal->es.in_frame); + + av_buffer_unref(&avctx->internal->pool); + + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + av_freep(&avctx->internal->hwaccel_priv_data); + + av_bsf_free(&avctx->internal->bsf); + + av_freep(&avctx->internal); + } + + for (i = 0; i < avctx->nb_coded_side_data; i++) + av_freep(&avctx->coded_side_data[i].data); + av_freep(&avctx->coded_side_data); + avctx->nb_coded_side_data = 0; + + av_buffer_unref(&avctx->hw_frames_ctx); + av_buffer_unref(&avctx->hw_device_ctx); + + if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) + av_opt_free(avctx->priv_data); + av_opt_free(avctx); + av_freep(&avctx->priv_data); + if (av_codec_is_encoder(avctx->codec)) { + av_freep(&avctx->extradata); +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + av_frame_free(&avctx->coded_frame); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + } + avctx->codec = NULL; + avctx->active_thread_type = 0; + + return 0; +} + +static const char *unknown_if_null(const char *str) +{ + return str ? str : "unknown"; +} + +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) +{ + const char *codec_type; + const char *codec_name; + const char *profile = NULL; + int64_t bitrate; + int new_line = 0; + AVRational display_aspect_ratio; + const char *separator = enc->dump_separator ? (const char *)enc->dump_separator : ", "; + const char *str; + + if (!buf || buf_size <= 0) + return; + codec_type = av_get_media_type_string(enc->codec_type); + codec_name = avcodec_get_name(enc->codec_id); + profile = avcodec_profile_name(enc->codec_id, enc->profile); + + 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_type == AVMEDIA_TYPE_VIDEO + && av_log_get_level() >= AV_LOG_VERBOSE + && enc->refs) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %d reference frame%s", + enc->refs, enc->refs > 1 ? "s" : ""); + + if (enc->codec_tag) + snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s / 0x%04X)", + av_fourcc2str(enc->codec_tag), enc->codec_tag); + + switch (enc->codec_type) { + case AVMEDIA_TYPE_VIDEO: + { + char detail[256] = "("; + + av_strlcat(buf, separator, buf_size); + + snprintf(buf + strlen(buf), buf_size - strlen(buf), + "%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" : + unknown_if_null(av_get_pix_fmt_name(enc->pix_fmt))); + if (enc->bits_per_raw_sample && enc->pix_fmt != AV_PIX_FMT_NONE && + enc->bits_per_raw_sample < av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth) + av_strlcatf(detail, sizeof(detail), "%d bpc, ", enc->bits_per_raw_sample); + if (enc->color_range != AVCOL_RANGE_UNSPECIFIED && + (str = av_color_range_name(enc->color_range))) + av_strlcatf(detail, sizeof(detail), "%s, ", str); + + if (enc->colorspace != AVCOL_SPC_UNSPECIFIED || + enc->color_primaries != AVCOL_PRI_UNSPECIFIED || + enc->color_trc != AVCOL_TRC_UNSPECIFIED) { + const char *col = unknown_if_null(av_color_space_name(enc->colorspace)); + const char *pri = unknown_if_null(av_color_primaries_name(enc->color_primaries)); + const char *trc = unknown_if_null(av_color_transfer_name(enc->color_trc)); + if (strcmp(col, pri) || strcmp(col, trc)) { + new_line = 1; + av_strlcatf(detail, sizeof(detail), "%s/%s/%s, ", + col, pri, trc); + } else + av_strlcatf(detail, sizeof(detail), "%s, ", col); + } + + if (enc->field_order != AV_FIELD_UNKNOWN) { + const char *field_order = "progressive"; + if (enc->field_order == AV_FIELD_TT) + field_order = "top first"; + else if (enc->field_order == AV_FIELD_BB) + field_order = "bottom first"; + else if (enc->field_order == AV_FIELD_TB) + field_order = "top coded first (swapped)"; + else if (enc->field_order == AV_FIELD_BT) + field_order = "bottom coded first (swapped)"; + + av_strlcatf(detail, sizeof(detail), "%s, ", field_order); + } + + if (av_log_get_level() >= AV_LOG_VERBOSE && + enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED && + (str = av_chroma_location_name(enc->chroma_sample_location))) + av_strlcatf(detail, sizeof(detail), "%s, ", str); + + if (strlen(detail) > 1) { + detail[strlen(detail) - 2] = 0; + av_strlcatf(buf, buf_size, "%s)", detail); + } + } + + if (enc->width) { + av_strlcat(buf, new_line ? separator : ", ", buf_size); + + snprintf(buf + strlen(buf), buf_size - strlen(buf), + "%dx%d", + enc->width, enc->height); + + if (av_log_get_level() >= AV_LOG_VERBOSE && + (enc->width != enc->coded_width || + enc->height != enc->coded_height)) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " (%dx%d)", enc->coded_width, enc->coded_height); + + if (enc->sample_aspect_ratio.num) { + av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, + enc->width * (int64_t)enc->sample_aspect_ratio.num, + enc->height * (int64_t)enc->sample_aspect_ratio.den, + 1024 * 1024); + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " [SAR %d:%d DAR %d:%d]", + enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den, + display_aspect_ratio.num, display_aspect_ratio.den); + } + if (av_log_get_level() >= AV_LOG_DEBUG) { + int g = av_gcd(enc->time_base.num, enc->time_base.den); + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %d/%d", + enc->time_base.num / g, enc->time_base.den / g); + } + } + if (encode) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", q=%d-%d", enc->qmin, enc->qmax); + } else { + if (enc->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", Closed Captions"); + if (enc->properties & FF_CODEC_PROPERTY_LOSSLESS) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", lossless"); + } + break; + case AVMEDIA_TYPE_AUDIO: + av_strlcat(buf, separator, buf_size); + + if (enc->sample_rate) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + "%d Hz, ", enc->sample_rate); + } + av_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout); + if (enc->sample_fmt != AV_SAMPLE_FMT_NONE && + (str = av_get_sample_fmt_name(enc->sample_fmt))) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %s", str); + } + if ( enc->bits_per_raw_sample > 0 + && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " (%d bit)", enc->bits_per_raw_sample); + if (av_log_get_level() >= AV_LOG_VERBOSE) { + if (enc->initial_padding) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", delay %d", enc->initial_padding); + if (enc->trailing_padding) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", padding %d", enc->trailing_padding); + } + break; + case AVMEDIA_TYPE_DATA: + if (av_log_get_level() >= AV_LOG_DEBUG) { + int g = av_gcd(enc->time_base.num, enc->time_base.den); + if (g) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %d/%d", + 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; + } + if (encode) { + if (enc->flags & AV_CODEC_FLAG_PASS1) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", pass 1"); + if (enc->flags & AV_CODEC_FLAG_PASS2) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", pass 2"); + } + bitrate = get_bit_rate(enc); + if (bitrate != 0) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %"PRId64" kb/s", bitrate / 1000); + } else if (enc->rc_max_rate > 0) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", max. %"PRId64" kb/s", enc->rc_max_rate / 1000); + } +} + +int avcodec_is_open(AVCodecContext *s) +{ + return !!s->internal; +} diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index c91b2fd16..8a71c0423 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -410,6 +410,11 @@ typedef struct RcOverride{ * Export the AVVideoEncParams structure through frame side data. */ #define AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS (1 << 2) +/** + * Decoding only. + * Do not apply film grain, export it instead. + */ +#define AV_CODEC_EXPORT_DATA_FILM_GRAIN (1 << 3) /** * Pan Scan area. @@ -508,6 +513,11 @@ typedef struct AVProducerReferenceTime { */ #define AV_GET_BUFFER_FLAG_REF (1 << 0) +/** + * The encoder will keep a reference to the packet and may reuse it later. + */ +#define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0) + struct AVCodecInternal; /** @@ -1314,9 +1324,9 @@ typedef struct AVCodecContext { * * Some decoders do not support linesizes changing between frames. * - * If frame multithreading is used and thread_safe_callbacks is set, - * this callback may be called from a different thread, but not from more - * than one at once. Does not need to be reentrant. + * If frame multithreading is used, this callback may be called from a + * different thread, but not from more than one at once. Does not need to be + * reentrant. * * @see avcodec_align_dimensions2() * @@ -1340,6 +1350,7 @@ typedef struct AVCodecContext { */ int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); +#if FF_API_OLD_ENCDEC /** * If non-zero, the decoded audio and video frames returned from * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted @@ -1355,6 +1366,7 @@ typedef struct AVCodecContext { */ attribute_deprecated int refcounted_frames; +#endif /* - encoding parameters */ float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) @@ -1614,42 +1626,20 @@ 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 #define FF_DEBUG_ER 0x00000400 #define FF_DEBUG_MMCO 0x00000800 #define FF_DEBUG_BUGS 0x00001000 -#if FF_API_DEBUG_MV -#define FF_DEBUG_VIS_QP 0x00002000 -#define FF_DEBUG_VIS_MB_TYPE 0x00004000 -#endif #define FF_DEBUG_BUFFERS 0x00008000 #define FF_DEBUG_THREADS 0x00010000 #define FF_DEBUG_GREEN_MD 0x00800000 #define FF_DEBUG_NOMC 0x01000000 -#if FF_API_DEBUG_MV - /** - * debug - * - 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 - /** * Error recognition; may misdetect some more or less valid parts as errors. - * - encoding: unused + * - encoding: Set by user. * - decoding: Set by user. */ int err_recognition; @@ -1756,14 +1746,12 @@ 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. */ int lowres; -#endif #if FF_API_CODED_FRAME /** @@ -1803,6 +1791,7 @@ typedef struct AVCodecContext { */ int active_thread_type; +#if FF_API_THREAD_SAFE_CALLBACKS /** * Set by the client if its custom get_buffer() callback can be called * synchronously from another thread, which allows faster multithreaded decoding. @@ -1810,8 +1799,18 @@ typedef struct AVCodecContext { * Ignored if the default get_buffer() is used. * - encoding: Set by user. * - decoding: Set by user. + * + * @deprecated the custom get_buffer2() callback should always be + * thread-safe. Thread-unsafe get_buffer2() implementations will be + * invalid starting with LIBAVCODEC_VERSION_MAJOR=60; in other words, + * libavcodec will behave as if this field was always set to 1. + * Callers that want to be forward compatible with future libavcodec + * versions should wrap access to this field in + * #if LIBAVCODEC_VERSION_MAJOR < 60 */ + attribute_deprecated int thread_safe_callbacks; +#endif /** * The codec may call this to execute several independent things. @@ -1949,6 +1948,9 @@ typedef struct AVCodecContext { #define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 #define FF_PROFILE_HEVC_REXT 4 +#define FF_PROFILE_VVC_MAIN_10 1 +#define FF_PROFILE_VVC_MAIN_10_444 33 + #define FF_PROFILE_AV1_MAIN 0 #define FF_PROFILE_AV1_HIGH 1 #define FF_PROFILE_AV1_PROFESSIONAL 2 @@ -2089,15 +2091,6 @@ 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. - */ - int lowres; -#endif - /** * Current statistics for PTS correction. * - decoding: maintained and used by libavcodec, not intended to be used by user apps @@ -2148,12 +2141,11 @@ typedef struct AVCodecContext { */ int seek_preroll; -#if !FF_API_DEBUG_MV +#if FF_API_DEBUG_MV /** - * debug motion vectors - * - encoding: Set by user. - * - decoding: Set by user. + * @deprecated unused */ + attribute_deprecated 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 @@ -2352,6 +2344,44 @@ typedef struct AVCodecContext { * - encoding: set by user */ int export_side_data; + + /** + * This callback is called at the beginning of each packet to get a data + * buffer for it. + * + * The following field will be set in the packet before this callback is + * called: + * - size + * This callback must use the above value to calculate the required buffer size, + * which must padded by at least AV_INPUT_BUFFER_PADDING_SIZE bytes. + * + * This callback must fill the following fields in the packet: + * - data: alignment requirements for AVPacket apply, if any. Some architectures and + * encoders may benefit from having aligned data. + * - buf: must contain a pointer to an AVBufferRef structure. The packet's + * data pointer must be contained in it. See: av_buffer_create(), av_buffer_alloc(), + * and av_buffer_ref(). + * + * If AV_CODEC_CAP_DR1 is not set then get_encode_buffer() must call + * avcodec_default_get_encode_buffer() instead of providing a buffer allocated by + * some other means. + * + * The flags field may contain a combination of AV_GET_ENCODE_BUFFER_FLAG_ flags. + * They may be used for example to hint what use the buffer may get after being + * created. + * Implementations of this callback may ignore flags they don't understand. + * If AV_GET_ENCODE_BUFFER_FLAG_REF is set in flags then the packet may be reused + * (read and/or written to if it is writable) later by libavcodec. + * + * This callback must be thread-safe, as when frame threading is used, it may + * be called from multiple threads simultaneously. + * + * @see avcodec_default_get_encode_buffer() + * + * - encoding: Set by libavcodec, user can override. + * - decoding: unused + */ + int (*get_encode_buffer)(struct AVCodecContext *s, AVPacket *pkt, int flags); } AVCodecContext; #if FF_API_CODEC_GET_SET @@ -2372,12 +2402,10 @@ void av_codec_set_codec_descriptor(AVCodecContext *avctx, co attribute_deprecated unsigned av_codec_get_codec_properties(const AVCodecContext *avctx); -#if FF_API_LOWRES attribute_deprecated int av_codec_get_lowres(const AVCodecContext *avctx); attribute_deprecated void av_codec_set_lowres(AVCodecContext *avctx, int val); -#endif attribute_deprecated int av_codec_get_seek_preroll(const AVCodecContext *avctx); @@ -2727,25 +2755,13 @@ const char *avcodec_license(void); #if FF_API_NEXT /** - * Register the codec codec and initialize libavcodec. - * - * @warning either this function or avcodec_register_all() must be called - * before any other libavcodec functions. - * - * @see avcodec_register_all() + * @deprecated Calling this function is unnecessary. */ attribute_deprecated void avcodec_register(AVCodec *codec); /** - * Register all the codecs, parsers and bitstream filters which were enabled at - * configuration time. If you do not call this function you can select exactly - * which formats you want to support, by using the individual registration - * functions. - * - * @see avcodec_register - * @see av_register_codec_parser - * @see av_register_bitstream_filter + * @deprecated Calling this function is unnecessary. */ attribute_deprecated void avcodec_register_all(void); @@ -2789,14 +2805,13 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec); */ const AVClass *avcodec_get_class(void); -#if FF_API_COPY_CONTEXT +#if FF_API_GET_FRAME_CLASS /** - * Get the AVClass for AVFrame. It can be used in combination with - * AV_OPT_SEARCH_FAKE_OBJ for examining options. - * - * @see av_opt_find(). + * @deprecated This function should not be used. */ +attribute_deprecated const AVClass *avcodec_get_frame_class(void); +#endif /** * Get the AVClass for AVSubtitleRect. It can be used in combination with @@ -2806,6 +2821,7 @@ const AVClass *avcodec_get_frame_class(void); */ const AVClass *avcodec_get_subtitle_rect_class(void); +#if FF_API_COPY_CONTEXT /** * Copy the settings of the source AVCodecContext into the destination * AVCodecContext. The resulting destination codec context will be @@ -2862,7 +2878,6 @@ int avcodec_parameters_to_context(AVCodecContext *codec, * @ref avcodec_receive_frame()). * * @code - * avcodec_register_all(); * av_dict_set(&opts, "b", "2.5M", 0); * codec = avcodec_find_decoder(AV_CODEC_ID_H264); * if (!codec) @@ -2926,6 +2941,13 @@ void avsubtitle_free(AVSubtitle *sub); */ int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags); +/** + * The default callback for AVCodecContext.get_encode_buffer(). It is made public so + * it can be called by custom get_encode_buffer() implementations for encoders without + * AV_CODEC_CAP_DR1 set. + */ +int avcodec_default_get_encode_buffer(AVCodecContext *s, AVPacket *pkt, int flags); + /** * Modify width and height values so that they will result in a memory * buffer that is acceptable for the codec if you do not use any horizontal @@ -2967,6 +2989,7 @@ int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos); */ enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos); +#if FF_API_OLD_ENCDEC /** * Decode the audio frame of size avpkt->size from avpkt->data into frame. * @@ -3073,6 +3096,7 @@ attribute_deprecated int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt); +#endif /** * Decode a subtitle message. @@ -3529,7 +3553,10 @@ typedef struct AVCodecParser { const uint8_t *buf, int buf_size); void (*parser_close)(AVCodecParserContext *s); int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); +#if FF_API_NEXT + attribute_deprecated struct AVCodecParser *next; +#endif } AVCodecParser; /** @@ -3543,11 +3570,13 @@ typedef struct AVCodecParser { */ const AVCodecParser *av_parser_iterate(void **opaque); +#if FF_API_NEXT attribute_deprecated AVCodecParser *av_parser_next(const AVCodecParser *c); attribute_deprecated void av_register_codec_parser(AVCodecParser *parser); +#endif AVCodecParserContext *av_parser_init(int codec_id); /** @@ -3588,14 +3617,18 @@ int av_parser_parse2(AVCodecParserContext *s, int64_t pts, int64_t dts, int64_t pos); +#if FF_API_PARSER_CHANGE /** * @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 dump_extradata, remove_extra or extract_extradata + * bitstream filters instead. */ +attribute_deprecated int av_parser_change(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe); +#endif void av_parser_close(AVCodecParserContext *s); /** @@ -3608,6 +3641,7 @@ void av_parser_close(AVCodecParserContext *s); * @{ */ +#if FF_API_OLD_ENCDEC /** * Encode a frame of audio. * @@ -3646,7 +3680,9 @@ void av_parser_close(AVCodecParserContext *s); * not be used. * @return 0 on success, negative error code on failure * - * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead + * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead. + * If allowed and required, set AVCodecContext.get_encode_buffer to + * a custom function to pass user supplied output buffers. */ attribute_deprecated int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, @@ -3685,11 +3721,14 @@ int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, * not be used. * @return 0 on success, negative error code on failure * - * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead + * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead. + * If allowed and required, set AVCodecContext.get_encode_buffer to + * a custom function to pass user supplied output buffers. */ attribute_deprecated int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr); +#endif int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub); @@ -3796,12 +3835,6 @@ void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int */ unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat pix_fmt); -/** - * @deprecated see av_get_pix_fmt_loss() - */ -int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, - int has_alpha); - /** * Find the best pixel format to convert to given a certain source pixel * format. When converting from one pixel format to another, information loss @@ -3823,15 +3856,24 @@ enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *p enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); +#if FF_API_AVCODEC_PIX_FMT +/** + * @deprecated see av_get_pix_fmt_loss() + */ +attribute_deprecated +int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, + int has_alpha); /** * @deprecated see av_find_best_pix_fmt_of_2() */ +attribute_deprecated enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); attribute_deprecated enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); +#endif enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat * fmt); diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index dce26cb31..b5bac5c5f 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -32,6 +32,7 @@ #include "packet.h" #include "packet_internal.h" +#if FF_API_INIT_PACKET void av_init_packet(AVPacket *pkt) { pkt->pts = AV_NOPTS_VALUE; @@ -49,6 +50,16 @@ FF_ENABLE_DEPRECATION_WARNINGS pkt->side_data = NULL; pkt->side_data_elems = 0; } +#endif + +static void get_packet_defaults(AVPacket *pkt) +{ + memset(pkt, 0, sizeof(*pkt)); + + pkt->pts = AV_NOPTS_VALUE; + pkt->dts = AV_NOPTS_VALUE; + pkt->pos = -1; +} AVPacket *av_packet_alloc(void) { @@ -56,7 +67,7 @@ AVPacket *av_packet_alloc(void) if (!pkt) return pkt; - av_init_packet(pkt); + get_packet_defaults(pkt); return pkt; } @@ -92,7 +103,7 @@ int av_new_packet(AVPacket *pkt, int size) if (ret < 0) return ret; - av_init_packet(pkt); + get_packet_defaults(pkt); pkt->buf = buf; pkt->data = buf->data; pkt->size = size; @@ -330,12 +341,16 @@ int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, - int size) + buffer_size_t size) { int ret; uint8_t *data; +#if FF_API_BUFFER_SIZE_T if ((unsigned)size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) +#else + if (size > SIZE_MAX - AV_INPUT_BUFFER_PADDING_SIZE) +#endif return NULL; data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); if (!data) @@ -351,7 +366,7 @@ uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, } uint8_t *av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, - int *size) + buffer_size_t *size) { int i; @@ -400,6 +415,7 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_PRFT: return "Producer Reference Time"; case AV_PKT_DATA_ICC_PROFILE: return "ICC Profile"; case AV_PKT_DATA_DOVI_CONF: return "DOVI configuration record"; + case AV_PKT_DATA_S12M_TIMECODE: return "SMPTE ST 12-1:2014 timecode"; } return NULL; } @@ -491,42 +507,55 @@ int av_packet_split_side_data(AVPacket *pkt){ } #endif +#if FF_API_BUFFER_SIZE_T uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size) +#else +uint8_t *av_packet_pack_dictionary(AVDictionary *dict, size_t *size) +#endif { - 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); + for (int pass = 0; pass < 2; pass++) { + const AVDictionaryEntry *t = NULL; + size_t total_length = 0; - if (!new_data) - goto fail; - data = new_data; - if (new_size > INT_MAX) - goto fail; + while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) { + for (int i = 0; i < 2; i++) { + const char *str = i ? t->value : t->key; + const size_t len = strlen(str) + 1; - memcpy(data + *size, t->key, keylen + 1); - memcpy(data + *size + keylen + 1, t->value, valuelen + 1); - - *size = new_size; + if (pass) + memcpy(data + total_length, str, len); +#if FF_API_BUFFER_SIZE_T + else if (len > INT_MAX - total_length) +#else + else if (len > SIZE_MAX - total_length) +#endif + return NULL; + total_length += len; + } + } + if (pass) + break; + data = av_malloc(total_length); + if (!data) + return NULL; + *size = total_length; } return data; - -fail: - av_freep(&data); - *size = 0; - return NULL; } +#if FF_API_BUFFER_SIZE_T int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict) +#else +int av_packet_unpack_dictionary(const uint8_t *data, size_t size, + AVDictionary **dict) +#endif { const uint8_t *end; int ret; @@ -553,7 +582,7 @@ int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **di } int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, - int size) + buffer_size_t size) { int i; @@ -588,7 +617,7 @@ FF_ENABLE_DEPRECATION_WARNINGS dst->side_data_elems = 0; for (i = 0; i < src->side_data_elems; i++) { enum AVPacketSideDataType type = src->side_data[i].type; - int size = src->side_data[i].size; + buffer_size_t 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); @@ -606,9 +635,7 @@ 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; + get_packet_defaults(pkt); } int av_packet_ref(AVPacket *dst, const AVPacket *src) @@ -663,9 +690,7 @@ AVPacket *av_packet_clone(const AVPacket *src) void av_packet_move_ref(AVPacket *dst, AVPacket *src) { *dst = *src; - av_init_packet(src); - src->data = NULL; - src->size = 0; + get_packet_defaults(src); } int av_packet_make_refcounted(AVPacket *pkt) @@ -725,10 +750,77 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif } +int avpriv_packet_list_put(PacketList **packet_buffer, + PacketList **plast_pktl, + AVPacket *pkt, + int (*copy)(AVPacket *dst, const AVPacket *src), + int flags) +{ + PacketList *pktl = av_mallocz(sizeof(PacketList)); + int ret; + + if (!pktl) + return AVERROR(ENOMEM); + + if (copy) { + ret = copy(&pktl->pkt, pkt); + if (ret < 0) { + av_free(pktl); + return ret; + } + } else { + ret = av_packet_make_refcounted(pkt); + if (ret < 0) { + av_free(pktl); + return ret; + } + av_packet_move_ref(&pktl->pkt, pkt); + } + + if (*packet_buffer) + (*plast_pktl)->next = pktl; + else + *packet_buffer = pktl; + + /* Add the packet in the buffered packet list. */ + *plast_pktl = pktl; + return 0; +} + +int avpriv_packet_list_get(PacketList **pkt_buffer, + PacketList **pkt_buffer_end, + AVPacket *pkt) +{ + PacketList *pktl; + if (!*pkt_buffer) + return AVERROR(EAGAIN); + pktl = *pkt_buffer; + *pkt = pktl->pkt; + *pkt_buffer = pktl->next; + if (!pktl->next) + *pkt_buffer_end = NULL; + av_freep(&pktl); + return 0; +} + +void avpriv_packet_list_free(PacketList **pkt_buf, PacketList **pkt_buf_end) +{ + PacketList *tmp = *pkt_buf; + + while (tmp) { + PacketList *pktl = tmp; + tmp = pktl->next; + av_packet_unref(&pktl->pkt); + av_freep(&pktl); + } + *pkt_buf = NULL; + *pkt_buf_end = NULL; +} + int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type) { uint8_t *side_data; - int side_data_size; + buffer_size_t side_data_size; int i; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, &side_data_size); @@ -754,7 +846,7 @@ int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp) { AVProducerReferenceTime *prft; uint8_t *side_data; - int side_data_size; + buffer_size_t side_data_size; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &side_data_size); if (!side_data) { diff --git a/libavcodec/avrndec.c b/libavcodec/avrndec.c index 104ff2d90..477afd8bf 100644 --- a/libavcodec/avrndec.c +++ b/libavcodec/avrndec.c @@ -21,13 +21,9 @@ #include "avcodec.h" #include "internal.h" -#include "mjpeg.h" -#include "mjpegdec.h" #include "libavutil/imgutils.h" typedef struct { - AVCodecContext *mjpeg_avctx; - int is_mjpeg; int interlace; int tff; } AVRnContext; @@ -37,40 +33,6 @@ static av_cold int init(AVCodecContext *avctx) AVRnContext *a = avctx->priv_data; int ret; - // Support "Resolution 1:1" for Avid AVI Codec - a->is_mjpeg = avctx->extradata_size < 31 || memcmp(&avctx->extradata[28], "1:1", 3); - - if(!a->is_mjpeg && avctx->lowres) { - av_log(avctx, AV_LOG_ERROR, "lowres is not possible with rawvideo\n"); - return AVERROR(EINVAL); - } - - if(a->is_mjpeg) { - AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG); - AVDictionary *thread_opt = NULL; - if (!codec) { - av_log(avctx, AV_LOG_ERROR, "MJPEG codec not found\n"); - return AVERROR_DECODER_NOT_FOUND; - } - - a->mjpeg_avctx = avcodec_alloc_context3(codec); - - av_dict_set(&thread_opt, "threads", "1", 0); // Is this needed ? - a->mjpeg_avctx->refcounted_frames = 1; - a->mjpeg_avctx->flags = avctx->flags; - a->mjpeg_avctx->idct_algo = avctx->idct_algo; - a->mjpeg_avctx->lowres = avctx->lowres; - a->mjpeg_avctx->width = avctx->width; - a->mjpeg_avctx->height = avctx->height; - - if ((ret = ff_codec_open2_recursive(a->mjpeg_avctx, codec, &thread_opt)) < 0) { - av_log(avctx, AV_LOG_ERROR, "MJPEG codec failed to open\n"); - } - av_dict_free(&thread_opt); - - return ret; - } - if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) return ret; @@ -87,16 +49,6 @@ static av_cold int init(AVCodecContext *avctx) return 0; } -static av_cold int end(AVCodecContext *avctx) -{ - AVRnContext *a = avctx->priv_data; - - avcodec_close(a->mjpeg_avctx); - av_freep(&a->mjpeg_avctx); - - return 0; -} - static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -106,28 +58,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; int y, ret, true_height; - if(a->is_mjpeg) { - ret = avcodec_decode_video2(a->mjpeg_avctx, data, got_frame, avpkt); - - if (ret >= 0 && *got_frame && avctx->width <= p->width && avctx->height <= p->height) { - int shift = p->height - avctx->height; - int subsample_h, subsample_v; - - av_pix_fmt_get_chroma_sub_sample(p->format, &subsample_h, &subsample_v); - - p->data[0] += p->linesize[0] * shift; - if (p->data[2]) { - p->data[1] += p->linesize[1] * (shift>>subsample_v); - p->data[2] += p->linesize[2] * (shift>>subsample_v); - } - - p->width = avctx->width; - p->height = avctx->height; - } - avctx->pix_fmt = a->mjpeg_avctx->pix_fmt; - return ret; - } - true_height = buf_size / (2*avctx->width); if(buf_size < 2*avctx->width * avctx->height) { @@ -166,8 +96,7 @@ AVCodec ff_avrn_decoder = { .id = AV_CODEC_ID_AVRN, .priv_data_size = sizeof(AVRnContext), .init = init, - .close = end, .decode = decode_frame, - .max_lowres = 3, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/avs2_parser.c b/libavcodec/avs2_parser.c index 1c9b3423f..54f687142 100644 --- a/libavcodec/avs2_parser.c +++ b/libavcodec/avs2_parser.c @@ -21,10 +21,10 @@ #include "parser.h" -#define SLICE_MAX_START_CODE 0x000001af +#define AVS2_SLICE_MAX_START_CODE 0x000001AF -#define ISPIC(x) ((x) == 0xB3 || (x) == 0xB6) -#define ISUNIT(x) ((x) == 0xB0 || (x) == 0xB1 || (x) == 0xB2 || ISPIC(x)) +#define AVS2_ISPIC(x) ((x) == 0xB3 || (x) == 0xB6) +#define AVS2_ISUNIT(x) ((x) == 0xB0 || (x) == 0xB1 || (x) == 0xB2 || AVS2_ISPIC(x)) static int avs2_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) { @@ -34,9 +34,9 @@ static int avs2_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_siz if (!pic_found) { for (; cur < buf_size; ++cur) { - state = (state<<8) | buf[cur]; - if (ISUNIT(buf[cur])){ - ++cur; + state = (state << 8) | buf[cur]; + if (AVS2_ISUNIT(buf[cur])){ + cur++; pic_found = 1; break; } @@ -46,9 +46,9 @@ static int avs2_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_siz if (pic_found) { if (!buf_size) return END_NOT_FOUND; - for (; cur < buf_size; ++cur) { + for (; cur < buf_size; cur++) { state = (state << 8) | buf[cur]; - if ((state & 0xFFFFFF00) == 0x100 && state > SLICE_MAX_START_CODE) { + if ((state & 0xFFFFFF00) == 0x100 && state > AVS2_SLICE_MAX_START_CODE) { pc->frame_start_found = 0; pc->state = -1; return cur - 3; diff --git a/libavcodec/avs3.h b/libavcodec/avs3.h new file mode 100644 index 000000000..4189d9b58 --- /dev/null +++ b/libavcodec/avs3.h @@ -0,0 +1,118 @@ +/* + * AVS3 related definitions + * + * Copyright (C) 2020 Huiwen Ren, + * + * 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_AVS3_H +#define AVCODEC_AVS3_H + +#define AVS3_NAL_START_CODE 0x010000 +#define AVS3_SEQ_START_CODE 0xB0 +#define AVS3_SEQ_END_CODE 0xB1 +#define AVS3_USER_DATA_START_CODE 0xB2 +#define AVS3_INTRA_PIC_START_CODE 0xB3 +#define AVS3_UNDEF_START_CODE 0xB4 +#define AVS3_EXTENSION_START_CODE 0xB5 +#define AVS3_INTER_PIC_START_CODE 0xB6 +#define AVS3_VIDEO_EDIT_CODE 0xB7 +#define AVS3_FIRST_SLICE_START_CODE 0x00 +#define AVS3_PROFILE_BASELINE_MAIN 0x20 +#define AVS3_PROFILE_BASELINE_MAIN10 0x22 + +#define AVS3_ISPIC(x) ((x) == AVS3_INTRA_PIC_START_CODE || (x) == AVS3_INTER_PIC_START_CODE) +#define AVS3_ISUNIT(x) ((x) == AVS3_SEQ_START_CODE || AVS3_ISPIC(x)) + +#include "libavutil/avutil.h" +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" + +static const AVRational ff_avs3_frame_rate_tab[16] = { + { 0 , 0 }, // forbid + { 24000, 1001}, + { 24 , 1 }, + { 25 , 1 }, + { 30000, 1001}, + { 30 , 1 }, + { 50 , 1 }, + { 60000, 1001}, + { 60 , 1 }, + { 100 , 1 }, + { 120 , 1 }, + { 200 , 1 }, + { 240 , 1 }, + { 300 , 1 }, + { 0 , 0 }, // reserved + { 0 , 0 } // reserved +}; + +static const int ff_avs3_color_primaries_tab[10] = { + AVCOL_PRI_RESERVED0 , // 0 + AVCOL_PRI_BT709 , // 1 + AVCOL_PRI_UNSPECIFIED , // 2 + AVCOL_PRI_RESERVED , // 3 + AVCOL_PRI_BT470M , // 4 + AVCOL_PRI_BT470BG , // 5 + AVCOL_PRI_SMPTE170M , // 6 + AVCOL_PRI_SMPTE240M , // 7 + AVCOL_PRI_FILM , // 8 + AVCOL_PRI_BT2020 // 9 +}; + +static const int ff_avs3_color_transfer_tab[15] = { + AVCOL_TRC_RESERVED0 , // 0 + AVCOL_TRC_BT709 , // 1 + AVCOL_TRC_UNSPECIFIED , // 2 + AVCOL_TRC_RESERVED , // 3 + AVCOL_TRC_GAMMA22 , // 4 + AVCOL_TRC_GAMMA28 , // 5 + AVCOL_TRC_SMPTE170M , // 6 + AVCOL_TRC_SMPTE240M , // 7 + AVCOL_TRC_LINEAR , // 8 + AVCOL_TRC_LOG , // 9 + AVCOL_TRC_LOG_SQRT , // 10 + AVCOL_TRC_BT2020_12 , // 11 + AVCOL_TRC_SMPTE2084 , // 12 + AVCOL_TRC_UNSPECIFIED , // 13 + AVCOL_TRC_ARIB_STD_B67 // 14 +}; + +static const int ff_avs3_color_matrix_tab[12] = { + AVCOL_SPC_RESERVED , // 0 + AVCOL_SPC_BT709 , // 1 + AVCOL_SPC_UNSPECIFIED , // 2 + AVCOL_SPC_RESERVED , // 3 + AVCOL_SPC_FCC , // 4 + AVCOL_SPC_BT470BG , // 5 + AVCOL_SPC_SMPTE170M , // 6 + AVCOL_SPC_SMPTE240M , // 7 + AVCOL_SPC_BT2020_NCL , // 8 + AVCOL_SPC_BT2020_CL , // 9 + AVCOL_SPC_UNSPECIFIED , // 10 + AVCOL_SPC_UNSPECIFIED // 11 +}; + +static const enum AVPictureType ff_avs3_image_type[4] = { + AV_PICTURE_TYPE_NONE, + AV_PICTURE_TYPE_I, + AV_PICTURE_TYPE_P, + AV_PICTURE_TYPE_B +}; + +#endif /* AVCODEC_AVS3_H */ diff --git a/libavcodec/avs3_parser.c b/libavcodec/avs3_parser.c new file mode 100644 index 000000000..bf97f75db --- /dev/null +++ b/libavcodec/avs3_parser.c @@ -0,0 +1,179 @@ +/* + * AVS3-P2/IEEE1857.10 video parser. + * Copyright (c) 2020 Zhenyu Wang + * Bingjie Han + * Huiwen Ren + * + * 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 "avs3.h" +#include "get_bits.h" +#include "parser.h" + +static int avs3_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) +{ + int pic_found = pc->frame_start_found; + uint32_t state = pc->state; + int cur = 0; + + if (!pic_found) { + for (; cur < buf_size; ++cur) { + state = (state << 8) | buf[cur]; + if (AVS3_ISPIC(buf[cur])){ + cur++; + pic_found = 1; + break; + } + } + } + + if (pic_found) { + if (!buf_size) + return END_NOT_FOUND; + for (; cur < buf_size; ++cur) { + state = (state << 8) | buf[cur]; + if ((state & 0xFFFFFF00) == 0x100 && AVS3_ISUNIT(state & 0xFF)) { + pc->frame_start_found = 0; + pc->state = -1; + return cur - 3; + } + } + } + + pc->frame_start_found = pic_found; + pc->state = state; + + return END_NOT_FOUND; +} + +static void parse_avs3_nal_units(AVCodecParserContext *s, const uint8_t *buf, + int buf_size, AVCodecContext *avctx) +{ + if (buf_size < 5) { + return; + } + + if (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x1) { + if (buf[3] == AVS3_SEQ_START_CODE) { + GetBitContext gb; + int profile, ratecode; + + init_get_bits(&gb, buf + 4, buf_size - 4); + + s->key_frame = 1; + s->pict_type = AV_PICTURE_TYPE_I; + + profile = get_bits(&gb, 8); + // Skip bits: level(8) + // progressive(1) + // field(1) + // library(2) + // resv(1) + // width(14) + // resv(1) + // height(14) + // chroma(2) + // sampe_precision(3) + skip_bits(&gb, 47); + + if (profile == AVS3_PROFILE_BASELINE_MAIN10) { + int sample_precision = get_bits(&gb, 3); + if (sample_precision == 1) { + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + } else if (sample_precision == 2) { + avctx->pix_fmt = AV_PIX_FMT_YUV420P10LE; + } else { + avctx->pix_fmt = AV_PIX_FMT_NONE; + } + } + + // Skip bits: resv(1) + // aspect(4) + skip_bits(&gb, 5); + + ratecode = get_bits(&gb, 4); + + // Skip bits: resv(1) + // bitrate_low(18) + // resv(1) + // bitrate_high(12) + skip_bits(&gb, 32); + + avctx->has_b_frames = !get_bits(&gb, 1); + + avctx->framerate.num = avctx->time_base.den = ff_avs3_frame_rate_tab[ratecode].num; + avctx->framerate.den = avctx->time_base.num = ff_avs3_frame_rate_tab[ratecode].den; + + s->width = s->coded_width = avctx->width; + s->height = s->coded_height = avctx->height; + + av_log(avctx, AV_LOG_DEBUG, + "AVS3 parse seq HDR: profile %d; coded size: %dx%d; frame rate code: %d\n", + profile, avctx->width, avctx->height, ratecode); + + } else if (buf[3] == AVS3_INTRA_PIC_START_CODE) { + s->key_frame = 1; + s->pict_type = AV_PICTURE_TYPE_I; + } else if (buf[3] == AVS3_INTER_PIC_START_CODE){ + s->key_frame = 0; + if (buf_size > 9) { + int pic_code_type = buf[8] & 0x3; + if (pic_code_type == 1 || pic_code_type == 3) { + s->pict_type = AV_PICTURE_TYPE_P; + } else { + s->pict_type = AV_PICTURE_TYPE_B; + } + } + } + } +} + + +static int avs3_parse(AVCodecParserContext *s, 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 = avs3_find_frame_end(pc, buf, buf_size); + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + + parse_avs3_nal_units(s, buf, buf_size, avctx); + + *poutbuf = buf; + *poutbuf_size = buf_size; + + return next; +} + +AVCodecParser ff_avs3_parser = { + .codec_ids = { AV_CODEC_ID_AVS3 }, + .priv_data_size = sizeof(ParseContext), + .parser_parse = avs3_parse, + .parser_close = ff_parse_close, + .split = ff_mpeg4video_split, +}; diff --git a/libavcodec/bink.c b/libavcodec/bink.c index f251ab401..5efd24e9c 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -23,6 +23,7 @@ #include "libavutil/attributes.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #define BITSTREAM_READER_LE #include "avcodec.h" @@ -114,7 +115,7 @@ typedef struct Bundle { typedef struct BinkContext { AVCodecContext *avctx; BlockDSPContext bdsp; - HpelDSPContext hdsp; + op_pixels_func put_pixels_tab; BinkDSPContext binkdsp; AVFrame *last; int version; ///< internal Bink file version @@ -178,17 +179,20 @@ static void init_lengths(BinkContext *c, int width, int bw) static av_cold int init_bundles(BinkContext *c) { int bw, bh, blocks; + uint8_t *tmp; int i; bw = (c->avctx->width + 7) >> 3; bh = (c->avctx->height + 7) >> 3; blocks = bw * bh; + tmp = av_calloc(blocks, 64 * BINKB_NB_SRC); + if (!tmp) + return AVERROR(ENOMEM); for (i = 0; i < BINKB_NB_SRC; i++) { - 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; + c->bundle[i].data = tmp; + tmp += blocks * 64; + c->bundle[i].data_end = tmp; } return 0; @@ -201,9 +205,7 @@ static av_cold int init_bundles(BinkContext *c) */ static av_cold void free_bundles(BinkContext *c) { - int i; - for (i = 0; i < BINKB_NB_SRC; i++) - av_freep(&c->bundle[i].data); + av_freep(&c->bundle[0].data); } /** @@ -926,7 +928,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, if (ref < ref_start || ref + 8*stride > ref_end) { av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { - c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8); + c->put_pixels_tab(dst, ref, stride, 8); } else { put_pixels8x8_overlapped(dst, ref, stride); } @@ -942,7 +944,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, if (ref < ref_start || ref + 8 * stride > ref_end) { av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { - c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8); + c->put_pixels_tab(dst, ref, stride, 8); } else { put_pixels8x8_overlapped(dst, ref, stride); } @@ -974,7 +976,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, if (ref < ref_start || ref + 8 * stride > ref_end) { av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { - c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8); + c->put_pixels_tab(dst, ref, stride, 8); } else { put_pixels8x8_overlapped(dst, ref, stride); } @@ -1009,7 +1011,7 @@ static int bink_put_pixels(BinkContext *c, xoff, yoff); return AVERROR_INVALIDDATA; } - c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8); + c->put_pixels_tab(dst, ref, stride, 8); return 0; } @@ -1092,7 +1094,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, } switch (blk) { case SKIP_BLOCK: - c->hdsp.put_pixels_tab[1][0](dst, prev, stride, 8); + c->put_pixels_tab(dst, prev, stride, 8); break; case SCALED_BLOCK: blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); @@ -1344,6 +1346,7 @@ static av_cold int decode_init(AVCodecContext *avctx) BinkContext * const c = avctx->priv_data; static VLC_TYPE table[16 * 128][2]; static int binkb_initialised = 0; + HpelDSPContext hdsp; int i, ret; int flags; @@ -1378,13 +1381,12 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->color_range = c->version == 'k' ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; ff_blockdsp_init(&c->bdsp, avctx); - ff_hpeldsp_init(&c->hdsp, avctx->flags); + ff_hpeldsp_init(&hdsp, avctx->flags); + c->put_pixels_tab = hdsp.put_pixels_tab[1][0]; ff_binkdsp_init(&c->binkdsp); - if ((ret = init_bundles(c)) < 0) { - free_bundles(c); + if ((ret = init_bundles(c)) < 0) return ret; - } if (c->version == 'b') { if (!binkb_initialised) { @@ -1424,4 +1426,5 @@ AVCodec ff_bink_decoder = { .decode = decode_frame, .flush = flush, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index 012190a95..df15a0fd5 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -30,6 +30,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/intfloat.h" +#include "libavutil/mem_internal.h" #define BITSTREAM_READER_LE #include "avcodec.h" @@ -40,8 +41,6 @@ #include "rdft.h" #include "wma_freqs.h" -static float quant_table[96]; - #define MAX_CHANNELS 2 #define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11) @@ -54,10 +53,10 @@ typedef struct BinkAudioContext { int overlap_len; ///< overlap size (samples) int block_size; int num_bands; - unsigned int *bands; float root; - DECLARE_ALIGNED(32, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE]; + unsigned int bands[26]; float previous[MAX_CHANNELS][BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block + float quant_table[96]; AVPacket *pkt; union { RDFTContext rdft; @@ -71,7 +70,7 @@ static av_cold int decode_init(AVCodecContext *avctx) BinkAudioContext *s = avctx->priv_data; int sample_rate = avctx->sample_rate; int sample_rate_half; - int i; + int i, ret; int frame_len_bits; /* determine frame length */ @@ -116,7 +115,7 @@ static av_cold int decode_init(AVCodecContext *avctx) s->root = s->frame_len / (sqrt(s->frame_len) * 32768.0); for (i = 0; i < 96; i++) { /* constant is result of 0.066399999/log10(M_E) */ - quant_table[i] = expf(i * 0.15289164787221953823f) * s->root; + s->quant_table[i] = expf(i * 0.15289164787221953823f) * s->root; } /* calculate number of bands */ @@ -124,10 +123,6 @@ static av_cold int decode_init(AVCodecContext *avctx) if (sample_rate_half <= ff_wma_critical_freqs[s->num_bands - 1]) break; - s->bands = av_malloc((s->num_bands + 1) * sizeof(*s->bands)); - if (!s->bands) - return AVERROR(ENOMEM); - /* populate bands data */ s->bands[0] = 2; for (i = 1; i < s->num_bands; i++) @@ -137,11 +132,13 @@ static av_cold int decode_init(AVCodecContext *avctx) s->first = 1; if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) - ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R); + ret = ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R); else if (CONFIG_BINKAUDIO_DCT_DECODER) - ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III); + ret = ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III); else av_assert0(0); + if (ret < 0) + return ret; s->pkt = av_packet_alloc(); if (!s->pkt) @@ -197,7 +194,7 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct) return AVERROR_INVALIDDATA; for (i = 0; i < s->num_bands; i++) { int value = get_bits(gb, 8); - quant[i] = quant_table[FFMIN(value, 95)]; + quant[i] = s->quant_table[FFMIN(value, 95)]; } k = 0; @@ -275,7 +272,6 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct) static av_cold int decode_end(AVCodecContext *avctx) { BinkAudioContext * s = avctx->priv_data; - av_freep(&s->bands); if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) ff_rdft_end(&s->trans.rdft); else if (CONFIG_BINKAUDIO_DCT_DECODER) @@ -351,6 +347,7 @@ AVCodec ff_binkaudio_rdft_decoder = { .close = decode_end, .receive_frame = binkaudio_receive_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; AVCodec ff_binkaudio_dct_decoder = { @@ -363,4 +360,5 @@ AVCodec ff_binkaudio_dct_decoder = { .close = decode_end, .receive_frame = binkaudio_receive_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/bitpacked.c b/libavcodec/bitpacked.c index 952ba73a3..23e82c69b 100644 --- a/libavcodec/bitpacked.c +++ b/libavcodec/bitpacked.c @@ -33,12 +33,12 @@ struct BitpackedContext { int (*decode)(AVCodecContext *avctx, AVFrame *frame, - AVPacket *pkt); + const AVPacket *pkt); }; /* For this format, it's a simple passthrough */ static int bitpacked_decode_uyvy422(AVCodecContext *avctx, AVFrame *frame, - AVPacket *avpkt) + const AVPacket *avpkt) { int ret; @@ -56,7 +56,7 @@ static int bitpacked_decode_uyvy422(AVCodecContext *avctx, AVFrame *frame, } static int bitpacked_decode_yuv422p10(AVCodecContext *avctx, AVFrame *frame, - AVPacket *avpkt) + const AVPacket *avpkt) { uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 20; uint64_t packet_size = (uint64_t)avpkt->size * 8; diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index 53a2db745..e425ffdc9 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -45,13 +45,18 @@ const uint8_t ff_log2_run[41]={ 24, }; +#if FF_API_AVPRIV_PUT_BITS void avpriv_align_put_bits(PutBitContext *s) { - put_bits(s, s->bit_left & 7, 0); + align_put_bits(s); } +void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) +{ + ff_copy_bits(pb, src, length); +} +#endif -void avpriv_put_string(PutBitContext *pb, const char *string, - int terminate_string) +void ff_put_string(PutBitContext *pb, const char *string, int terminate_string) { while (*string) { put_bits(pb, 8, *string); @@ -61,7 +66,7 @@ void avpriv_put_string(PutBitContext *pb, const char *string, put_bits(pb, 8, 0); } -void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) +void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length) { int words = length >> 4; int bits = length & 15; @@ -99,10 +104,10 @@ void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) v = *(const uint16_t *)ptr; \ break; \ case 4: \ + default: \ + av_assert1(size == 4); \ v = *(const uint32_t *)ptr; \ break; \ - default: \ - av_assert1(0); \ } \ } @@ -127,14 +132,41 @@ static int alloc_table(VLC *vlc, int size, int use_static) return index; } +#define LOCALBUF_ELEMS 1500 // the maximum currently needed is 1296 by rv34 + typedef struct VLCcode { uint8_t bits; - uint16_t symbol; + VLC_TYPE symbol; /** codeword, with the first bit-to-be-read in the msb * (even if intended for a little-endian bitstream reader) */ uint32_t code; } VLCcode; +static int vlc_common_init(VLC *vlc_arg, int nb_bits, int nb_codes, + VLC **vlc, VLC *localvlc, VLCcode **buf, + int flags) +{ + *vlc = vlc_arg; + (*vlc)->bits = nb_bits; + if (flags & INIT_VLC_USE_NEW_STATIC) { + av_assert0(nb_codes <= LOCALBUF_ELEMS); + *localvlc = *vlc_arg; + *vlc = localvlc; + (*vlc)->table_size = 0; + } else { + (*vlc)->table = NULL; + (*vlc)->table_allocated = 0; + (*vlc)->table_size = 0; + } + if (nb_codes > LOCALBUF_ELEMS) { + *buf = av_malloc_array(nb_codes, sizeof(VLCcode)); + if (!*buf) + return AVERROR(ENOMEM); + } + + return 0; +} + static int compare_vlcspec(const void *a, const void *b) { const VLCcode *sa = a, *sb = b; @@ -182,7 +214,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, j = code >> (32 - table_nb_bits); nb = 1 << (table_nb_bits - n); inc = 1; - if (flags & INIT_VLC_LE) { + if (flags & INIT_VLC_OUTPUT_LE) { j = bitswap_32(code); inc = 1 << n; } @@ -217,7 +249,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, subtable_bits = FFMAX(subtable_bits, n); } subtable_bits = FFMIN(subtable_bits, table_nb_bits); - j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix; + j = (flags & INIT_VLC_OUTPUT_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix; table[j][1] = -subtable_bits; ff_dlog(NULL, "%4x: n=%d (subtable)\n", j, codes[i].bits + table_nb_bits); @@ -243,6 +275,27 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, return table_index; } +static int vlc_common_end(VLC *vlc, int nb_bits, int nb_codes, VLCcode *codes, + int flags, VLC *vlc_arg, VLCcode localbuf[LOCALBUF_ELEMS]) +{ + int ret = build_table(vlc, nb_bits, nb_codes, codes, flags); + + if (flags & INIT_VLC_USE_NEW_STATIC) { + if (vlc->table_size != vlc->table_allocated && + !(flags & (INIT_VLC_STATIC_OVERLONG & ~INIT_VLC_USE_NEW_STATIC))) + av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated); + av_assert0(ret >= 0); + *vlc_arg = *vlc; + } else { + if (codes != localbuf) + av_free(codes); + if (ret < 0) { + av_freep(&vlc->table); + return ret; + } + } + return 0; +} /* Build VLC decoding tables suitable for use with get_vlc(). @@ -266,9 +319,6 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, 'wrap' and 'size' make it possible to use any memory configuration and types (byte/word/long) to store the 'bits', 'codes', and 'symbols' tables. - - 'use_static' should be set to 1 for tables, which should be freed - with av_free_static(), 0 if ff_free_vlc() will be used. */ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, @@ -276,52 +326,39 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, const void *symbols, int symbols_wrap, int symbols_size, int flags) { - VLCcode *buf; + VLCcode localbuf[LOCALBUF_ELEMS], *buf = localbuf; int i, j, ret; - VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34 VLC localvlc, *vlc; - vlc = vlc_arg; - vlc->bits = nb_bits; - if (flags & INIT_VLC_USE_NEW_STATIC) { - av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf)); - buf = localbuf; - localvlc = *vlc_arg; - vlc = &localvlc; - vlc->table_size = 0; - } else { - vlc->table = NULL; - vlc->table_allocated = 0; - vlc->table_size = 0; - - buf = av_malloc_array((nb_codes + 1), sizeof(VLCcode)); - if (!buf) - return AVERROR(ENOMEM); - } - + ret = vlc_common_init(vlc_arg, nb_bits, nb_codes, &vlc, &localvlc, + &buf, flags); + if (ret < 0) + return ret; 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); \ + unsigned len; \ + GET_DATA(len, 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)) \ + if (len > 3*nb_bits || len > 32) { \ + av_log(NULL, AV_LOG_ERROR, "Too long VLC (%u) in init_vlc\n", len);\ + if (buf != localbuf) \ av_free(buf); \ return AVERROR(EINVAL); \ } \ + buf[j].bits = len; \ GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \ if (buf[j].code >= (1LL< nb_bits); + COPY(len > nb_bits); // qsort is the slowest part of init_vlc, and could probably be improved or avoided AV_QSORT(buf, j, struct VLCcode, compare_vlcspec); - COPY(buf[j].bits && buf[j].bits <= nb_bits); + COPY(len && len <= nb_bits); nb_codes = j; - ret = build_table(vlc, nb_bits, nb_codes, buf, flags); - - 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); - - av_assert0(ret >= 0); - *vlc_arg = *vlc; - } else { - av_free(buf); - if (ret < 0) { - av_freep(&vlc->table); - return ret; - } - } - return 0; + return vlc_common_end(vlc, nb_bits, nb_codes, buf, + flags, vlc_arg, localbuf); } +int ff_init_vlc_from_lengths(VLC *vlc_arg, int nb_bits, int nb_codes, + const int8_t *lens, int lens_wrap, + const void *symbols, int symbols_wrap, int symbols_size, + int offset, int flags, void *logctx) +{ + VLCcode localbuf[LOCALBUF_ELEMS], *buf = localbuf; + VLC localvlc, *vlc; + uint64_t code; + int ret, j, len_max = FFMIN(32, 3 * nb_bits); + + ret = vlc_common_init(vlc_arg, nb_bits, nb_codes, &vlc, &localvlc, + &buf, flags); + if (ret < 0) + return ret; + + j = code = 0; + for (int i = 0; i < nb_codes; i++, lens += lens_wrap) { + int len = *lens; + if (len > 0) { + unsigned sym; + + buf[j].bits = len; + if (symbols) + GET_DATA(sym, symbols, i, symbols_wrap, symbols_size) + else + sym = i; + buf[j].symbol = sym + offset; + buf[j++].code = code; + } else if (len < 0) { + len = -len; + } else + continue; + if (len > len_max || code & ((1U << (32 - len)) - 1)) { + av_log(logctx, AV_LOG_ERROR, "Invalid VLC (length %u)\n", len); + goto fail; + } + code += 1U << (32 - len); + if (code > UINT32_MAX + 1ULL) { + av_log(logctx, AV_LOG_ERROR, "Overdetermined VLC tree\n"); + goto fail; + } + } + return vlc_common_end(vlc, nb_bits, j, buf, + flags, vlc_arg, localbuf); +fail: + if (buf != localbuf) + av_free(buf); + return AVERROR_INVALIDDATA; +} void ff_free_vlc(VLC *vlc) { diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c index a7aa5dca6..02d33abb1 100644 --- a/libavcodec/bitstream_filters.c +++ b/libavcodec/bitstream_filters.c @@ -53,6 +53,7 @@ extern const AVBitStreamFilter ff_opus_metadata_bsf; extern const AVBitStreamFilter ff_pcm_rechunk_bsf; extern const AVBitStreamFilter ff_prores_metadata_bsf; extern const AVBitStreamFilter ff_remove_extradata_bsf; +extern const AVBitStreamFilter ff_setts_bsf; extern const AVBitStreamFilter ff_text2movsub_bsf; extern const AVBitStreamFilter ff_trace_headers_bsf; extern const AVBitStreamFilter ff_truehd_core_bsf; @@ -96,6 +97,7 @@ const AVBitStreamFilter *av_bsf_get_by_name(const char *name) return NULL; } +#if FF_API_CHILD_CLASS_NEXT const AVClass *ff_bsf_child_class_next(const AVClass *prev) { const AVBitStreamFilter *f = NULL; @@ -115,3 +117,16 @@ const AVClass *ff_bsf_child_class_next(const AVClass *prev) } return NULL; } +#endif + +const AVClass *ff_bsf_child_class_iterate(void **opaque) +{ + const AVBitStreamFilter *f; + + /* find next filter with priv options */ + while ((f = av_bsf_iterate(opaque))) { + if (f->priv_class) + return f->priv_class; + } + return NULL; +} diff --git a/libavcodec/bmvaudio.c b/libavcodec/bmvaudio.c index b1587ab36..7c4dad7f8 100644 --- a/libavcodec/bmvaudio.c +++ b/libavcodec/bmvaudio.c @@ -85,5 +85,5 @@ AVCodec ff_bmv_audio_decoder = { .id = AV_CODEC_ID_BMV_AUDIO, .init = bmv_aud_decode_init, .decode = bmv_aud_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c index 5e1c794a7..157984bd9 100644 --- a/libavcodec/bsf.c +++ b/libavcodec/bsf.c @@ -45,14 +45,15 @@ void av_bsf_free(AVBSFContext **pctx) return; ctx = *pctx; - if (ctx->filter->close) - ctx->filter->close(ctx); + if (ctx->internal) { + if (ctx->filter->close) + ctx->filter->close(ctx); + av_packet_free(&ctx->internal->buffer_pkt); + av_freep(&ctx->internal); + } if (ctx->filter->priv_class && ctx->priv_data) av_opt_free(ctx->priv_data); - if (ctx->internal) - av_packet_free(&ctx->internal->buffer_pkt); - av_freep(&ctx->internal); av_freep(&ctx->priv_data); avcodec_parameters_free(&ctx->par_in); @@ -79,7 +80,10 @@ static const AVClass bsf_class = { .item_name = bsf_to_name, .version = LIBAVUTIL_VERSION_INT, .child_next = bsf_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = ff_bsf_child_class_next, +#endif + .child_class_iterate = ff_bsf_child_class_iterate, .category = AV_CLASS_CATEGORY_BITSTREAM_FILTER, }; @@ -107,20 +111,6 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx) ret = AVERROR(ENOMEM); goto fail; } - - bsfi = av_mallocz(sizeof(*bsfi)); - if (!bsfi) { - ret = AVERROR(ENOMEM); - goto fail; - } - ctx->internal = bsfi; - - bsfi->buffer_pkt = av_packet_alloc(); - if (!bsfi->buffer_pkt) { - ret = AVERROR(ENOMEM); - goto fail; - } - /* allocate priv data and init private options */ if (filter->priv_data_size) { ctx->priv_data = av_mallocz(filter->priv_data_size); @@ -133,6 +123,20 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx) av_opt_set_defaults(ctx->priv_data); } } + /* Allocate AVBSFInternal; must happen after priv_data has been allocated + * so that a filter->close needing priv_data is never called without. */ + bsfi = av_mallocz(sizeof(*bsfi)); + if (!bsfi) { + ret = AVERROR(ENOMEM); + goto fail; + } + ctx->internal = bsfi; + + bsfi->buffer_pkt = av_packet_alloc(); + if (!bsfi->buffer_pkt) { + ret = AVERROR(ENOMEM); + goto fail; + } *pctx = ctx; return 0; diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h index 7ed51677e..3b5faa85c 100644 --- a/libavcodec/bsf.h +++ b/libavcodec/bsf.h @@ -215,7 +215,7 @@ int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt); int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt); /** - * Reset the internal bitstream filter state / flush internal buffers. + * Reset the internal bitstream filter state. Should be called e.g. when seeking. */ void av_bsf_flush(AVBSFContext *ctx); diff --git a/libavcodec/bsf_internal.h b/libavcodec/bsf_internal.h index fefd5b890..b78c134bd 100644 --- a/libavcodec/bsf_internal.h +++ b/libavcodec/bsf_internal.h @@ -42,6 +42,10 @@ int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt); */ int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt); +#if FF_API_CHILD_CLASS_NEXT const AVClass *ff_bsf_child_class_next(const AVClass *prev); +#endif + +const AVClass *ff_bsf_child_class_iterate(void **opaque); #endif /* AVCODEC_BSF_INTERNAL_H */ diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h index 0516a6e3d..d0033f14f 100644 --- a/libavcodec/bytestream.h +++ b/libavcodec/bytestream.h @@ -77,11 +77,15 @@ static av_always_inline type bytestream2_get_ ## name(GetByteContext *g) \ } \ return bytestream2_get_ ## name ## u(g); \ } \ +static av_always_inline type bytestream2_peek_ ## name ## u(GetByteContext *g) \ +{ \ + return read(g->buffer); \ +} \ static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g) \ { \ if (g->buffer_end - g->buffer < bytes) \ return 0; \ - return read(g->buffer); \ + return bytestream2_peek_ ## name ## u(g); \ } DEF(uint64_t, le64, 8, AV_RL64, AV_WL64) diff --git a/libavcodec/c93.c b/libavcodec/c93.c index e1808150b..7e3bfdbc7 100644 --- a/libavcodec/c93.c +++ b/libavcodec/c93.c @@ -63,10 +63,8 @@ static av_cold int decode_init(AVCodecContext *avctx) s->pictures[0] = av_frame_alloc(); s->pictures[1] = av_frame_alloc(); - if (!s->pictures[0] || !s->pictures[1]) { - decode_end(avctx); + if (!s->pictures[0] || !s->pictures[1]) return AVERROR(ENOMEM); - } return 0; } @@ -269,5 +267,5 @@ AVCodec ff_c93_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 54e9bb4d8..6649feebe 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -27,6 +27,7 @@ #include #include "libavutil/common.h" +#include "libavutil/mem_internal.h" #include "cabac.h" #include "cabac_functions.h" @@ -157,18 +158,6 @@ DECLARE_ASM_ALIGNED(1, const uint8_t, ff_h264_cabac_tables)[512 + 4*2*64 + 4*64 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8 }; -/** - * @param buf_size size of buf in bits - */ -void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){ - init_put_bits(&c->pb, buf, buf_size); - - c->low= 0; - c->range= 0x1FE; - c->outstanding_count= 0; - c->pb.bit_left++; //avoids firstBitFlag -} - /** * * @param buf_size size of buf in bits diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 1bf1c620d..38d06b284 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -29,8 +29,6 @@ #include -#include "put_bits.h" - extern const uint8_t ff_h264_cabac_tables[512 + 4*2*64 + 4*64 + 63]; #define H264_NORM_SHIFT_OFFSET 0 #define H264_LPS_RANGE_OFFSET 512 @@ -43,14 +41,11 @@ extern const uint8_t ff_h264_cabac_tables[512 + 4*2*64 + 4*64 + 63]; typedef struct CABACContext{ int low; int range; - int outstanding_count; const uint8_t *bytestream_start; const uint8_t *bytestream; const uint8_t *bytestream_end; - PutBitContext pb; }CABACContext; -void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); int ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); #endif /* AVCODEC_CABAC_H */ diff --git a/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h index bb2b4210b..46af92182 100644 --- a/libavcodec/cabac_functions.h +++ b/libavcodec/cabac_functions.h @@ -27,6 +27,7 @@ #ifndef AVCODEC_CABAC_FUNCTIONS_H #define AVCODEC_CABAC_FUNCTIONS_H +#include #include #include "cabac.h" diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c index ba2b6ef23..74b837150 100644 --- a/libavcodec/cavs.c +++ b/libavcodec/cavs.c @@ -25,6 +25,8 @@ * @author Stefan Gehrer */ +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "get_bits.h" #include "golomb.h" diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h index 6bfb22ce4..cbc163fb4 100644 --- a/libavcodec/cavs.h +++ b/libavcodec/cavs.h @@ -22,6 +22,8 @@ #ifndef AVCODEC_CAVS_H #define AVCODEC_CAVS_H +#include "libavutil/mem_internal.h" + #include "cavsdsp.h" #include "blockdsp.h" #include "h264chroma.h" diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index aaed80719..9c3825df3 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -676,7 +676,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) } h->pred_mode_Y[pos] = predpred; } - pred_mode_uv = get_ue_golomb(gb); + pred_mode_uv = get_ue_golomb_31(gb); if (pred_mode_uv > 6) { av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n"); return AVERROR_INVALIDDATA; diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index 42cb9711f..c7f69845f 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -23,12 +23,13 @@ #include "libavutil/avassert.h" #include "libavutil/buffer.h" #include "libavutil/common.h" +#include "libavutil/opt.h" #include "cbs.h" #include "cbs_internal.h" -static const CodedBitstreamType *cbs_type_table[] = { +static const CodedBitstreamType *const cbs_type_table[] = { #if CONFIG_CBS_AV1 &ff_cbs_type_av1, #endif @@ -93,7 +94,7 @@ int ff_cbs_init(CodedBitstreamContext **ctx_ptr, return AVERROR(ENOMEM); ctx->log_ctx = log_ctx; - ctx->codec = type; + ctx->codec = type; /* Must be before any error */ if (type->priv_data_size) { ctx->priv_data = av_mallocz(ctx->codec->priv_data_size); @@ -101,6 +102,10 @@ int ff_cbs_init(CodedBitstreamContext **ctx_ptr, av_freep(&ctx); return AVERROR(ENOMEM); } + if (type->priv_class) { + *(const AVClass **)ctx->priv_data = type->priv_class; + av_opt_set_defaults(ctx->priv_data); + } } ctx->decompose_unit_types = NULL; @@ -112,6 +117,12 @@ int ff_cbs_init(CodedBitstreamContext **ctx_ptr, return 0; } +void ff_cbs_flush(CodedBitstreamContext *ctx) +{ + if (ctx->codec->flush) + ctx->codec->flush(ctx); +} + void ff_cbs_close(CodedBitstreamContext **ctx_ptr) { CodedBitstreamContext *ctx = *ctx_ptr; @@ -119,16 +130,19 @@ void ff_cbs_close(CodedBitstreamContext **ctx_ptr) if (!ctx) return; - if (ctx->codec && ctx->codec->close) + if (ctx->codec->close) ctx->codec->close(ctx); av_freep(&ctx->write_buffer); + + if (ctx->codec->priv_class && ctx->priv_data) + av_opt_free(ctx->priv_data); + av_freep(&ctx->priv_data); av_freep(ctx_ptr); } -static void cbs_unit_uninit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) +static void cbs_unit_uninit(CodedBitstreamUnit *unit) { av_buffer_unref(&unit->content_ref); unit->content = NULL; @@ -139,13 +153,12 @@ static void cbs_unit_uninit(CodedBitstreamContext *ctx, unit->data_bit_padding = 0; } -void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) +void ff_cbs_fragment_reset(CodedBitstreamFragment *frag) { int i; for (i = 0; i < frag->nb_units; i++) - cbs_unit_uninit(ctx, &frag->units[i]); + cbs_unit_uninit(&frag->units[i]); frag->nb_units = 0; av_buffer_unref(&frag->data_ref); @@ -154,10 +167,9 @@ void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, frag->data_bit_padding = 0; } -void ff_cbs_fragment_free(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) +void ff_cbs_fragment_free(CodedBitstreamFragment *frag) { - ff_cbs_fragment_reset(ctx, frag); + ff_cbs_fragment_reset(frag); av_freep(&frag->units); frag->nb_units_allocated = 0; @@ -190,6 +202,12 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx, av_log(ctx->log_ctx, AV_LOG_VERBOSE, "Decomposition unimplemented for unit %d " "(type %"PRIu32").\n", i, unit->type); + } else if (err == AVERROR(EAGAIN)) { + av_log(ctx->log_ctx, AV_LOG_VERBOSE, + "Skipping decomposition of unit %d " + "(type %"PRIu32").\n", i, unit->type); + av_buffer_unref(&unit->content_ref); + unit->content = NULL; } else if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d " "(type %"PRIu32").\n", i, unit->type); @@ -200,8 +218,7 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx, return 0; } -static int cbs_fill_fragment_data(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +static int cbs_fill_fragment_data(CodedBitstreamFragment *frag, const uint8_t *data, size_t size) { av_assert0(!frag->data && !frag->data_ref); @@ -221,66 +238,67 @@ static int cbs_fill_fragment_data(CodedBitstreamContext *ctx, return 0; } -int ff_cbs_read_extradata(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - const AVCodecParameters *par) +static int cbs_read_data(CodedBitstreamContext *ctx, + CodedBitstreamFragment *frag, + AVBufferRef *buf, + const uint8_t *data, size_t size, + int header) { int err; - err = cbs_fill_fragment_data(ctx, frag, par->extradata, - par->extradata_size); - if (err < 0) - return err; + if (buf) { + frag->data_ref = av_buffer_ref(buf); + if (!frag->data_ref) + return AVERROR(ENOMEM); - err = ctx->codec->split_fragment(ctx, frag, 1); + frag->data = (uint8_t *)data; + frag->data_size = size; + + } else { + err = cbs_fill_fragment_data(frag, data, size); + if (err < 0) + return err; + } + + err = ctx->codec->split_fragment(ctx, frag, header); if (err < 0) return err; return cbs_read_fragment_content(ctx, frag); } +int ff_cbs_read_extradata(CodedBitstreamContext *ctx, + CodedBitstreamFragment *frag, + const AVCodecParameters *par) +{ + return cbs_read_data(ctx, frag, NULL, + par->extradata, + par->extradata_size, 1); +} + +int ff_cbs_read_extradata_from_codec(CodedBitstreamContext *ctx, + CodedBitstreamFragment *frag, + const AVCodecContext *avctx) +{ + return cbs_read_data(ctx, frag, NULL, + avctx->extradata, + avctx->extradata_size, 1); +} + int ff_cbs_read_packet(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVPacket *pkt) { - int err; - - if (pkt->buf) { - frag->data_ref = av_buffer_ref(pkt->buf); - if (!frag->data_ref) - return AVERROR(ENOMEM); - - frag->data = pkt->data; - frag->data_size = pkt->size; - - } else { - err = cbs_fill_fragment_data(ctx, frag, pkt->data, pkt->size); - if (err < 0) - return err; - } - - err = ctx->codec->split_fragment(ctx, frag, 0); - if (err < 0) - return err; - - return cbs_read_fragment_content(ctx, frag); + return cbs_read_data(ctx, frag, pkt->buf, + pkt->data, pkt->size, 0); } int ff_cbs_read(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const uint8_t *data, size_t size) { - int err; - - err = cbs_fill_fragment_data(ctx, frag, data, size); - if (err < 0) - return err; - - err = ctx->codec->split_fragment(ctx, frag, 0); - if (err < 0) - return err; - - return cbs_read_fragment_content(ctx, frag); + return cbs_read_data(ctx, frag, NULL, + data, size, 0); } static int cbs_write_unit_data(CodedBitstreamContext *ctx, @@ -328,7 +346,7 @@ static int cbs_write_unit_data(CodedBitstreamContext *ctx, flush_put_bits(&pbc); - ret = ff_cbs_alloc_unit_data(ctx, unit, put_bits_count(&pbc) / 8); + ret = ff_cbs_alloc_unit_data(unit, put_bits_count(&pbc) / 8); if (ret < 0) return ret; @@ -641,8 +659,7 @@ int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc, } -int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, +int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit, size_t size, void (*free)(void *opaque, uint8_t *data)) { @@ -662,8 +679,7 @@ int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, return 0; } -int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, +int ff_cbs_alloc_unit_data(CodedBitstreamUnit *unit, size_t size) { av_assert0(!unit->data && !unit->data_ref); @@ -680,8 +696,7 @@ int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx, return 0; } -static int cbs_insert_unit(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +static int cbs_insert_unit(CodedBitstreamFragment *frag, int position) { CodedBitstreamUnit *units; @@ -719,8 +734,7 @@ static int cbs_insert_unit(CodedBitstreamContext *ctx, return 0; } -int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, @@ -742,7 +756,7 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, content_ref = NULL; } - err = cbs_insert_unit(ctx, frag, position); + err = cbs_insert_unit(frag, position); if (err < 0) { av_buffer_unref(&content_ref); return err; @@ -756,8 +770,7 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, return 0; } -int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +int ff_cbs_insert_unit_data(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, uint8_t *data, size_t data_size, @@ -781,7 +794,7 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, return AVERROR(ENOMEM); } - err = cbs_insert_unit(ctx, frag, position); + err = cbs_insert_unit(frag, position); if (err < 0) { av_buffer_unref(&data_ref); return err; @@ -796,14 +809,13 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, return 0; } -void ff_cbs_delete_unit(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +void ff_cbs_delete_unit(CodedBitstreamFragment *frag, int position) { av_assert0(0 <= position && position < frag->nb_units && "Unit to be deleted not in fragment."); - cbs_unit_uninit(ctx, &frag->units[position]); + cbs_unit_uninit(&frag->units[position]); --frag->nb_units; @@ -812,3 +824,235 @@ void ff_cbs_delete_unit(CodedBitstreamContext *ctx, frag->units + position + 1, (frag->nb_units - position) * sizeof(*frag->units)); } + +static void cbs_default_free_unit_content(void *opaque, uint8_t *data) +{ + const CodedBitstreamUnitTypeDescriptor *desc = opaque; + if (desc->content_type == CBS_CONTENT_TYPE_INTERNAL_REFS) { + int i; + for (i = 0; i < desc->nb_ref_offsets; i++) { + void **ptr = (void**)(data + desc->ref_offsets[i]); + av_buffer_unref((AVBufferRef**)(ptr + 1)); + } + } + av_free(data); +} + +static const CodedBitstreamUnitTypeDescriptor + *cbs_find_unit_type_desc(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit) +{ + const CodedBitstreamUnitTypeDescriptor *desc; + int i, j; + + if (!ctx->codec->unit_types) + return NULL; + + for (i = 0;; i++) { + desc = &ctx->codec->unit_types[i]; + if (desc->nb_unit_types == 0) + break; + if (desc->nb_unit_types == CBS_UNIT_TYPE_RANGE) { + if (unit->type >= desc->unit_type_range_start && + unit->type <= desc->unit_type_range_end) + return desc; + } else { + for (j = 0; j < desc->nb_unit_types; j++) { + if (desc->unit_types[j] == unit->type) + return desc; + } + } + } + return NULL; +} + +int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit) +{ + const CodedBitstreamUnitTypeDescriptor *desc; + + av_assert0(!unit->content && !unit->content_ref); + + desc = cbs_find_unit_type_desc(ctx, unit); + if (!desc) + return AVERROR(ENOSYS); + + unit->content = av_mallocz(desc->content_size); + if (!unit->content) + return AVERROR(ENOMEM); + + unit->content_ref = + av_buffer_create(unit->content, desc->content_size, + desc->content_free ? desc->content_free + : cbs_default_free_unit_content, + (void*)desc, 0); + if (!unit->content_ref) { + av_freep(&unit->content); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int cbs_clone_unit_content(AVBufferRef **clone_ref, + CodedBitstreamUnit *unit, + const CodedBitstreamUnitTypeDescriptor *desc) +{ + uint8_t *src, *copy; + uint8_t **src_ptr, **copy_ptr; + AVBufferRef **src_buf, **copy_buf; + int err, i; + + av_assert0(unit->content); + src = unit->content; + + copy = av_memdup(src, desc->content_size); + if (!copy) + return AVERROR(ENOMEM); + + for (i = 0; i < desc->nb_ref_offsets; i++) { + src_ptr = (uint8_t**)(src + desc->ref_offsets[i]); + src_buf = (AVBufferRef**)(src_ptr + 1); + copy_ptr = (uint8_t**)(copy + desc->ref_offsets[i]); + copy_buf = (AVBufferRef**)(copy_ptr + 1); + + if (!*src_ptr) { + av_assert0(!*src_buf); + continue; + } + if (!*src_buf) { + // We can't handle a non-refcounted pointer here - we don't + // have enough information to handle whatever structure lies + // at the other end of it. + err = AVERROR(EINVAL); + goto fail; + } + + // src_ptr is required to point somewhere inside src_buf. If it + // doesn't, there is a bug somewhere. + av_assert0(*src_ptr >= (*src_buf)->data && + *src_ptr < (*src_buf)->data + (*src_buf)->size); + + *copy_buf = av_buffer_ref(*src_buf); + if (!*copy_buf) { + err = AVERROR(ENOMEM); + goto fail; + } + *copy_ptr = (*copy_buf)->data + (*src_ptr - (*src_buf)->data); + } + + *clone_ref = av_buffer_create(copy, desc->content_size, + desc->content_free ? desc->content_free : + cbs_default_free_unit_content, + (void*)desc, 0); + if (!*clone_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + + return 0; + +fail: + for (--i; i >= 0; i--) + av_buffer_unref((AVBufferRef**)(copy + desc->ref_offsets[i])); + av_freep(©); + *clone_ref = NULL; + return err; +} + +int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit) +{ + const CodedBitstreamUnitTypeDescriptor *desc; + AVBufferRef *ref; + int err; + + av_assert0(unit->content); + if (unit->content_ref) { + // Already refcounted, nothing to do. + return 0; + } + + desc = cbs_find_unit_type_desc(ctx, unit); + if (!desc) + return AVERROR(ENOSYS); + + switch (desc->content_type) { + case CBS_CONTENT_TYPE_POD: + ref = av_buffer_alloc(desc->content_size); + if (!ref) + return AVERROR(ENOMEM); + memcpy(ref->data, unit->content, desc->content_size); + err = 0; + break; + + case CBS_CONTENT_TYPE_INTERNAL_REFS: + err = cbs_clone_unit_content(&ref, unit, desc); + break; + + case CBS_CONTENT_TYPE_COMPLEX: + if (!desc->content_clone) + return AVERROR_PATCHWELCOME; + err = desc->content_clone(&ref, unit); + break; + + default: + av_assert0(0 && "Invalid content type."); + } + + if (err < 0) + return err; + + unit->content_ref = ref; + unit->content = ref->data; + return 0; +} + +int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit) +{ + const CodedBitstreamUnitTypeDescriptor *desc; + AVBufferRef *ref; + int err; + + // This can only be applied to refcounted units. + err = ff_cbs_make_unit_refcounted(ctx, unit); + if (err < 0) + return err; + av_assert0(unit->content && unit->content_ref); + + if (av_buffer_is_writable(unit->content_ref)) + return 0; + + desc = cbs_find_unit_type_desc(ctx, unit); + if (!desc) + return AVERROR(ENOSYS); + + switch (desc->content_type) { + case CBS_CONTENT_TYPE_POD: + err = av_buffer_make_writable(&unit->content_ref); + break; + + case CBS_CONTENT_TYPE_INTERNAL_REFS: + err = cbs_clone_unit_content(&ref, unit, desc); + break; + + case CBS_CONTENT_TYPE_COMPLEX: + if (!desc->content_clone) + return AVERROR_PATCHWELCOME; + err = desc->content_clone(&ref, unit); + break; + + default: + av_assert0(0 && "Invalid content type."); + } + if (err < 0) + return err; + + if (desc->content_type != CBS_CONTENT_TYPE_POD) { + av_buffer_unref(&unit->content_ref); + unit->content_ref = ref; + } + unit->content = unit->content_ref->data; + return 0; +} diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h index 9ca1fbd60..f022282b7 100644 --- a/libavcodec/cbs.h +++ b/libavcodec/cbs.h @@ -45,8 +45,10 @@ struct CodedBitstreamType; /** * The codec-specific type of a bitstream unit. * + * AV1: obu_type * H.264 / AVC: nal_unit_type * H.265 / HEVC: nal_unit_type + * JPEG: marker value (without 0xff prefix) * MPEG-2: start code value (without prefix) * VP9: unused, set to zero (every unit is a frame) */ @@ -194,7 +196,7 @@ typedef struct CodedBitstreamContext { * Types not in this list will be available in bitstream form only. * If NULL, all supported types will be decomposed. */ - CodedBitstreamUnitType *decompose_unit_types; + const CodedBitstreamUnitType *decompose_unit_types; /** * Length of the decompose_unit_types array. */ @@ -234,6 +236,11 @@ extern const enum AVCodecID ff_cbs_all_codec_ids[]; int ff_cbs_init(CodedBitstreamContext **ctx, enum AVCodecID codec_id, void *log_ctx); +/** + * Reset all internal state in a context. + */ +void ff_cbs_flush(CodedBitstreamContext *ctx); + /** * Close a context and free all internal state. */ @@ -255,6 +262,17 @@ int ff_cbs_read_extradata(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVCodecParameters *par); +/** + * Read the extradata bitstream found in a codec context into a + * fragment, then split into units and decompose. + * + * This acts identical to ff_cbs_read_extradata() for the case where + * you already have a codec context. + */ +int ff_cbs_read_extradata_from_codec(CodedBitstreamContext *ctx, + CodedBitstreamFragment *frag, + const AVCodecContext *avctx); + /** * Read the data bitstream from a packet into a fragment, then * split into units and decompose. @@ -330,33 +348,38 @@ int ff_cbs_write_packet(CodedBitstreamContext *ctx, * Free the units contained in a fragment as well as the fragment's * own data buffer, but not the units array itself. */ -void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag); +void ff_cbs_fragment_reset(CodedBitstreamFragment *frag); /** * Free the units array of a fragment in addition to what * ff_cbs_fragment_reset does. */ -void ff_cbs_fragment_free(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag); +void ff_cbs_fragment_free(CodedBitstreamFragment *frag); /** * Allocate a new internal content buffer of the given size in the unit. * * The content will be zeroed. */ -int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, +int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit, size_t size, void (*free)(void *opaque, uint8_t *content)); +/** + * Allocate a new internal content buffer matching the type of the unit. + * + * The content will be zeroed. + */ +int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit); + + /** * Allocate a new internal data buffer of the given size in the unit. * * The data buffer will have input padding. */ -int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, +int ff_cbs_alloc_unit_data(CodedBitstreamUnit *unit, size_t size); /** @@ -365,8 +388,7 @@ int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx, * The content structure continues to be owned by the caller if * content_buf is not supplied. */ -int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, @@ -379,8 +401,7 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, * av_malloc() and will on success become owned by the unit after this * call or freed on error. */ -int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +int ff_cbs_insert_unit_data(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, uint8_t *data, size_t data_size, @@ -391,9 +412,37 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, * * Requires position to be >= 0 and < frag->nb_units. */ -void ff_cbs_delete_unit(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +void ff_cbs_delete_unit(CodedBitstreamFragment *frag, int position); +/** + * Make the content of a unit refcounted. + * + * If the unit is not refcounted, this will do a deep copy of the unit + * content to new refcounted buffers. + * + * It is not valid to call this function on a unit which does not have + * decomposed content. + */ +int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit); + +/** + * Make the content of a unit writable so that internal fields can be + * modified. + * + * If it is known that there are no other references to the content of + * the unit, does nothing and returns success. Otherwise (including the + * case where the unit content is not refcounted), it does a full clone + * of the content (including any internal buffers) to make a new copy, + * and replaces the existing references inside the unit with that. + * + * It is not valid to call this function on a unit which does not have + * decomposed content. + */ +int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit); + + #endif /* AVCODEC_CBS_H */ diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c index 0abcba9c6..302e1f38f 100644 --- a/libavcodec/cbs_av1.c +++ b/libavcodec/cbs_av1.c @@ -17,6 +17,7 @@ */ #include "libavutil/avassert.h" +#include "libavutil/opt.h" #include "libavutil/pixfmt.h" #include "cbs.h" @@ -120,16 +121,11 @@ static int cbs_av1_write_uvlc(CodedBitstreamContext *ctx, PutBitContext *pbc, if (ctx->trace_enable) position = put_bits_count(pbc); - if (value == 0) { - zeroes = 0; - put_bits(pbc, 1, 1); - } else { - zeroes = av_log2(value + 1); - v = value - (1U << zeroes) + 1; - put_bits(pbc, zeroes, 0); - put_bits(pbc, 1, 1); - put_bits(pbc, zeroes, v); - } + zeroes = av_log2(value + 1); + v = value - (1U << zeroes) + 1; + put_bits(pbc, zeroes, 0); + put_bits(pbc, 1, 1); + put_bits(pbc, zeroes, v); if (ctx->trace_enable) { char bits[65]; @@ -763,6 +759,39 @@ static int cbs_av1_split_fragment(CodedBitstreamContext *ctx, goto fail; } + if (header && size && data[0] & 0x80) { + // first bit is nonzero, the extradata does not consist purely of + // OBUs. Expect MP4/Matroska AV1CodecConfigurationRecord + int config_record_version = data[0] & 0x7f; + + if (config_record_version != 1) { + av_log(ctx->log_ctx, AV_LOG_ERROR, + "Unknown version %d of AV1CodecConfigurationRecord " + "found!\n", + config_record_version); + err = AVERROR_INVALIDDATA; + goto fail; + } + + if (size <= 4) { + if (size < 4) { + av_log(ctx->log_ctx, AV_LOG_WARNING, + "Undersized AV1CodecConfigurationRecord v%d found!\n", + config_record_version); + err = AVERROR_INVALIDDATA; + goto fail; + } + + goto success; + } + + // In AV1CodecConfigurationRecord v1, actual OBUs start after + // four bytes. Thus set the offset as required for properly + // parsing them. + data += 4; + size -= 4; + } + while (size > 0) { AV1RawOBUHeader header; uint64_t obu_size; @@ -799,7 +828,7 @@ static int cbs_av1_split_fragment(CodedBitstreamContext *ctx, goto fail; } - err = ff_cbs_insert_unit_data(ctx, frag, -1, header.obu_type, + err = ff_cbs_insert_unit_data(frag, -1, header.obu_type, data, obu_length, frag->data_ref); if (err < 0) goto fail; @@ -808,56 +837,13 @@ static int cbs_av1_split_fragment(CodedBitstreamContext *ctx, size -= obu_length; } +success: err = 0; fail: ctx->trace_enable = trace; return err; } -static void cbs_av1_free_tile_data(AV1RawTileData *td) -{ - av_buffer_unref(&td->data_ref); -} - -static void cbs_av1_free_padding(AV1RawPadding *pd) -{ - av_buffer_unref(&pd->payload_ref); -} - -static void cbs_av1_free_metadata(AV1RawMetadata *md) -{ - switch (md->metadata_type) { - case AV1_METADATA_TYPE_ITUT_T35: - av_buffer_unref(&md->metadata.itut_t35.payload_ref); - break; - } -} - -static void cbs_av1_free_obu(void *opaque, uint8_t *content) -{ - AV1RawOBU *obu = (AV1RawOBU*)content; - - switch (obu->header.obu_type) { - case AV1_OBU_TILE_GROUP: - cbs_av1_free_tile_data(&obu->obu.tile_group.tile_data); - break; - case AV1_OBU_FRAME: - cbs_av1_free_tile_data(&obu->obu.frame.tile_group.tile_data); - break; - case AV1_OBU_TILE_LIST: - cbs_av1_free_tile_data(&obu->obu.tile_list.tile_data); - break; - case AV1_OBU_METADATA: - cbs_av1_free_metadata(&obu->obu.metadata); - break; - case AV1_OBU_PADDING: - cbs_av1_free_padding(&obu->obu.padding); - break; - } - - av_freep(&obu); -} - static int cbs_av1_ref_tile_data(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, GetBitContext *gbc, @@ -892,8 +878,7 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx, GetBitContext gbc; int err, start_pos, end_pos; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*obu), - &cbs_av1_free_obu); + err = ff_cbs_alloc_unit_content2(ctx, unit); if (err < 0) return err; obu = unit->content; @@ -925,9 +910,6 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx, start_pos = get_bits_count(&gbc); if (obu->header.obu_extension_flag) { - priv->temporal_id = obu->header.temporal_id; - priv->spatial_id = obu->header.spatial_id; - if (obu->header.obu_type != AV1_OBU_SEQUENCE_HEADER && obu->header.obu_type != AV1_OBU_TEMPORAL_DELIMITER && priv->operating_point_idc) { @@ -936,16 +918,11 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx, int in_spatial_layer = (priv->operating_point_idc >> (priv->spatial_id + 8)) & 1; if (!in_temporal_layer || !in_spatial_layer) { - // Decoding will drop this OBU at this operating point. + return AVERROR(EAGAIN); // drop_obu() } } - } else { - priv->temporal_id = 0; - priv->spatial_id = 0; } - priv->ref = (AV1ReferenceFrameState *)&priv->read_ref; - switch (obu->header.obu_type) { case AV1_OBU_SEQUENCE_HEADER: { @@ -954,6 +931,18 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx, if (err < 0) return err; + if (priv->operating_point >= 0) { + AV1RawSequenceHeader *sequence_header = &obu->obu.sequence_header; + + if (priv->operating_point > sequence_header->operating_points_cnt_minus_1) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid Operating Point %d requested. " + "Must not be higher than %u.\n", + priv->operating_point, sequence_header->operating_points_cnt_minus_1); + return AVERROR(EINVAL); + } + priv->operating_point_idc = sequence_header->operating_point_idc[priv->operating_point]; + } + av_buffer_unref(&priv->sequence_header_ref); priv->sequence_header = NULL; @@ -1089,8 +1078,6 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx, td = NULL; start_pos = put_bits_count(pbc); - priv->ref = (AV1ReferenceFrameState *)&priv->write_ref; - switch (obu->header.obu_type) { case AV1_OBU_SEQUENCE_HEADER: { @@ -1102,6 +1089,10 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx, av_buffer_unref(&priv->sequence_header_ref); priv->sequence_header = NULL; + err = ff_cbs_make_unit_refcounted(ctx, unit); + if (err < 0) + return err; + priv->sequence_header_ref = av_buffer_ref(unit->content_ref); if (!priv->sequence_header_ref) return AVERROR(ENOMEM); @@ -1254,6 +1245,20 @@ static int cbs_av1_assemble_fragment(CodedBitstreamContext *ctx, return 0; } +static void cbs_av1_flush(CodedBitstreamContext *ctx) +{ + CodedBitstreamAV1Context *priv = ctx->priv_data; + + av_buffer_unref(&priv->frame_header_ref); + priv->sequence_header = NULL; + priv->frame_header = NULL; + + memset(priv->ref, 0, sizeof(priv->ref)); + priv->operating_point_idc = 0; + priv->seen_frame_header = 0; + priv->tile_num = 0; +} + static void cbs_av1_close(CodedBitstreamContext *ctx) { CodedBitstreamAV1Context *priv = ctx->priv_data; @@ -1262,15 +1267,70 @@ static void cbs_av1_close(CodedBitstreamContext *ctx) av_buffer_unref(&priv->frame_header_ref); } +static void cbs_av1_free_metadata(void *unit, uint8_t *content) +{ + AV1RawOBU *obu = (AV1RawOBU*)content; + AV1RawMetadata *md; + + av_assert0(obu->header.obu_type == AV1_OBU_METADATA); + md = &obu->obu.metadata; + + switch (md->metadata_type) { + case AV1_METADATA_TYPE_ITUT_T35: + av_buffer_unref(&md->metadata.itut_t35.payload_ref); + break; + } + av_free(content); +} + +static const CodedBitstreamUnitTypeDescriptor cbs_av1_unit_types[] = { + CBS_UNIT_TYPE_POD(AV1_OBU_SEQUENCE_HEADER, AV1RawOBU), + CBS_UNIT_TYPE_POD(AV1_OBU_TEMPORAL_DELIMITER, AV1RawOBU), + CBS_UNIT_TYPE_POD(AV1_OBU_FRAME_HEADER, AV1RawOBU), + CBS_UNIT_TYPE_POD(AV1_OBU_REDUNDANT_FRAME_HEADER, AV1RawOBU), + + CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_TILE_GROUP, AV1RawOBU, + obu.tile_group.tile_data.data), + CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_FRAME, AV1RawOBU, + obu.frame.tile_group.tile_data.data), + CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_TILE_LIST, AV1RawOBU, + obu.tile_list.tile_data.data), + CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_PADDING, AV1RawOBU, + obu.padding.payload), + + CBS_UNIT_TYPE_COMPLEX(AV1_OBU_METADATA, AV1RawOBU, + &cbs_av1_free_metadata), + + CBS_UNIT_TYPE_END_OF_LIST +}; + +#define OFFSET(x) offsetof(CodedBitstreamAV1Context, x) +static const AVOption cbs_av1_options[] = { + { "operating_point", "Set operating point to select layers to parse from a scalable bitstream", + OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AV1_MAX_OPERATING_POINTS - 1, 0 }, + { NULL } +}; + +static const AVClass cbs_av1_class = { + .class_name = "cbs_av1", + .item_name = av_default_item_name, + .option = cbs_av1_options, + .version = LIBAVUTIL_VERSION_INT, +}; + const CodedBitstreamType ff_cbs_type_av1 = { .codec_id = AV_CODEC_ID_AV1, + .priv_class = &cbs_av1_class, .priv_data_size = sizeof(CodedBitstreamAV1Context), + .unit_types = cbs_av1_unit_types, + .split_fragment = &cbs_av1_split_fragment, .read_unit = &cbs_av1_read_unit, .write_unit = &cbs_av1_write_obu, .assemble_fragment = &cbs_av1_assemble_fragment, + .flush = &cbs_av1_flush, .close = &cbs_av1_close, }; diff --git a/libavcodec/cbs_av1.h b/libavcodec/cbs_av1.h index 1adb5ae07..1fc80dcfa 100644 --- a/libavcodec/cbs_av1.h +++ b/libavcodec/cbs_av1.h @@ -130,6 +130,38 @@ typedef struct AV1RawSequenceHeader { uint8_t film_grain_params_present; } AV1RawSequenceHeader; +typedef struct AV1RawFilmGrainParams { + uint8_t apply_grain; + uint16_t grain_seed; + uint8_t update_grain; + uint8_t film_grain_params_ref_idx; + uint8_t num_y_points; + uint8_t point_y_value[14]; + uint8_t point_y_scaling[14]; + uint8_t chroma_scaling_from_luma; + uint8_t num_cb_points; + uint8_t point_cb_value[10]; + uint8_t point_cb_scaling[10]; + uint8_t num_cr_points; + uint8_t point_cr_value[10]; + uint8_t point_cr_scaling[10]; + uint8_t grain_scaling_minus_8; + uint8_t ar_coeff_lag; + uint8_t ar_coeffs_y_plus_128[24]; + uint8_t ar_coeffs_cb_plus_128[25]; + uint8_t ar_coeffs_cr_plus_128[25]; + uint8_t ar_coeff_shift_minus_6; + uint8_t grain_scale_shift; + uint8_t cb_mult; + uint8_t cb_luma_mult; + uint16_t cb_offset; + uint8_t cr_mult; + uint8_t cr_luma_mult; + uint16_t cr_offset; + uint8_t overlap_flag; + uint8_t clip_to_restricted_range; +} AV1RawFilmGrainParams; + typedef struct AV1RawFrameHeader { uint8_t show_existing_frame; uint8_t frame_to_show_map_idx; @@ -251,41 +283,13 @@ typedef struct AV1RawFrameHeader { //AV1RawSubexp gm_params[AV1_TOTAL_REFS_PER_FRAME][6]; uint32_t gm_params[AV1_TOTAL_REFS_PER_FRAME][6]; - uint8_t apply_grain; - uint16_t grain_seed; - uint8_t update_grain; - uint8_t film_grain_params_ref_idx; - uint8_t num_y_points; - uint8_t point_y_value[14]; - uint8_t point_y_scaling[14]; - uint8_t chroma_scaling_from_luma; - uint8_t num_cb_points; - uint8_t point_cb_value[10]; - uint8_t point_cb_scaling[10]; - uint8_t num_cr_points; - uint8_t point_cr_value[10]; - uint8_t point_cr_scaling[10]; - uint8_t grain_scaling_minus_8; - uint8_t ar_coeff_lag; - uint8_t ar_coeffs_y_plus_128[24]; - uint8_t ar_coeffs_cb_plus_128[25]; - uint8_t ar_coeffs_cr_plus_128[25]; - uint8_t ar_coeff_shift_minus_6; - uint8_t grain_scale_shift; - uint8_t cb_mult; - uint8_t cb_luma_mult; - uint16_t cb_offset; - uint8_t cr_mult; - uint8_t cr_luma_mult; - uint16_t cr_offset; - uint8_t overlap_flag; - uint8_t clip_to_restricted_range; + AV1RawFilmGrainParams film_grain; } AV1RawFrameHeader; typedef struct AV1RawTileData { uint8_t *data; - size_t data_size; AVBufferRef *data_ref; + size_t data_size; } AV1RawTileData; typedef struct AV1RawTileGroup { @@ -346,8 +350,8 @@ typedef struct AV1RawMetadataITUTT35 { uint8_t itu_t_t35_country_code_extension_byte; uint8_t *payload; - size_t payload_size; AVBufferRef *payload_ref; + size_t payload_size; } AV1RawMetadataITUTT35; typedef struct AV1RawMetadataTimecode { @@ -379,8 +383,8 @@ typedef struct AV1RawMetadata { typedef struct AV1RawPadding { uint8_t *payload; - size_t payload_size; AVBufferRef *payload_ref; + size_t payload_size; } AV1RawPadding; @@ -413,9 +417,16 @@ typedef struct AV1ReferenceFrameState { int subsampling_y; // RefSubsamplingY int bit_depth; // RefBitDepth int order_hint; // RefOrderHint + + int8_t loop_filter_ref_deltas[AV1_TOTAL_REFS_PER_FRAME]; + int8_t loop_filter_mode_deltas[2]; + uint8_t feature_enabled[AV1_MAX_SEGMENTS][AV1_SEG_LVL_MAX]; + int16_t feature_value[AV1_MAX_SEGMENTS][AV1_SEG_LVL_MAX]; } AV1ReferenceFrameState; typedef struct CodedBitstreamAV1Context { + const AVClass *class; + AV1RawSequenceHeader *sequence_header; AVBufferRef *sequence_header_ref; @@ -441,10 +452,12 @@ typedef struct CodedBitstreamAV1Context { int all_lossless; int tile_cols; int tile_rows; + int tile_num; - AV1ReferenceFrameState *ref; - AV1ReferenceFrameState read_ref[AV1_NUM_REF_FRAMES]; - AV1ReferenceFrameState write_ref[AV1_NUM_REF_FRAMES]; + AV1ReferenceFrameState ref[AV1_NUM_REF_FRAMES]; + + // AVOptions + int operating_point; } CodedBitstreamAV1Context; diff --git a/libavcodec/cbs_av1_syntax_template.c b/libavcodec/cbs_av1_syntax_template.c index beab57300..6fe6e9a4f 100644 --- a/libavcodec/cbs_av1_syntax_template.c +++ b/libavcodec/cbs_av1_syntax_template.c @@ -19,6 +19,7 @@ static int FUNC(obu_header)(CodedBitstreamContext *ctx, RWContext *rw, AV1RawOBUHeader *current) { + CodedBitstreamAV1Context *priv = ctx->priv_data; int err; HEADER("OBU header"); @@ -35,8 +36,14 @@ static int FUNC(obu_header)(CodedBitstreamContext *ctx, RWContext *rw, fb(3, temporal_id); fb(2, spatial_id); fc(3, extension_header_reserved_3bits, 0, 0); + } else { + infer(temporal_id, 0); + infer(spatial_id, 0); } + priv->temporal_id = current->temporal_id; + priv->spatial_id = current->spatial_id; + return 0; } @@ -485,14 +492,14 @@ static int FUNC(frame_size)(CodedBitstreamContext *ctx, RWContext *rw, if (current->frame_size_override_flag) { fb(seq->frame_width_bits_minus_1 + 1, frame_width_minus_1); fb(seq->frame_height_bits_minus_1 + 1, frame_height_minus_1); - - priv->frame_width = current->frame_width_minus_1 + 1; - priv->frame_height = current->frame_height_minus_1 + 1; } else { - priv->frame_width = seq->max_frame_width_minus_1 + 1; - priv->frame_height = seq->max_frame_height_minus_1 + 1; + infer(frame_width_minus_1, seq->max_frame_width_minus_1); + infer(frame_height_minus_1, seq->max_frame_height_minus_1); } + priv->frame_width = current->frame_width_minus_1 + 1; + priv->frame_height = current->frame_height_minus_1 + 1; + CHECK(FUNC(superres_params)(ctx, rw, current)); return 0; @@ -509,14 +516,14 @@ static int FUNC(render_size)(CodedBitstreamContext *ctx, RWContext *rw, if (current->render_and_frame_size_different) { fb(16, render_width_minus_1); fb(16, render_height_minus_1); - - priv->render_width = current->render_width_minus_1 + 1; - priv->render_height = current->render_height_minus_1 + 1; } else { - priv->render_width = priv->upscaled_width; - priv->render_height = priv->frame_height; + infer(render_width_minus_1, current->frame_width_minus_1); + infer(render_height_minus_1, current->frame_height_minus_1); } + priv->render_width = current->render_width_minus_1 + 1; + priv->render_height = current->render_height_minus_1 + 1; + return 0; } @@ -540,6 +547,11 @@ static int FUNC(frame_size_with_refs)(CodedBitstreamContext *ctx, RWContext *rw, return AVERROR_INVALIDDATA; } + infer(frame_width_minus_1, ref->upscaled_width - 1); + infer(frame_height_minus_1, ref->frame_height - 1); + infer(render_width_minus_1, ref->render_width - 1); + infer(render_height_minus_1, ref->render_height - 1); + priv->upscaled_width = ref->upscaled_width; priv->frame_width = priv->upscaled_width; priv->frame_height = ref->frame_height; @@ -624,6 +636,15 @@ static int FUNC(tile_info)(CodedBitstreamContext *ctx, RWContext *rw, current->tile_rows_log2; current->tile_rows = (sb_rows + tile_height_sb - 1) / tile_height_sb; + for (i = 0; i < current->tile_cols - 1; i++) + infer(width_in_sbs_minus_1[i], tile_width_sb - 1); + infer(width_in_sbs_minus_1[i], + sb_cols - (current->tile_cols - 1) * tile_width_sb - 1); + for (i = 0; i < current->tile_rows - 1; i++) + infer(height_in_sbs_minus_1[i], tile_height_sb - 1); + infer(height_in_sbs_minus_1[i], + sb_rows - (current->tile_rows - 1) * tile_height_sb - 1); + } else { int widest_tile_sb, start_sb, size_sb, max_width, max_height; @@ -722,8 +743,11 @@ static int FUNC(quantization_params)(CodedBitstreamContext *ctx, RWContext *rw, static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, AV1RawFrameHeader *current) { + CodedBitstreamAV1Context *priv = ctx->priv_data; static const uint8_t bits[AV1_SEG_LVL_MAX] = { 8, 6, 6, 6, 6, 3, 0, 0 }; static const uint8_t sign[AV1_SEG_LVL_MAX] = { 1, 1, 1, 1, 1, 0, 0, 0 }; + static const uint8_t default_feature_enabled[AV1_SEG_LVL_MAX] = { 0 }; + static const int16_t default_feature_value[AV1_SEG_LVL_MAX] = { 0 }; int i, j, err; flag(segmentation_enabled); @@ -742,9 +766,22 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, flag(segmentation_update_data); } - if (current->segmentation_update_data) { - for (i = 0; i < AV1_MAX_SEGMENTS; i++) { - for (j = 0; j < AV1_SEG_LVL_MAX; j++) { + for (i = 0; i < AV1_MAX_SEGMENTS; i++) { + const uint8_t *ref_feature_enabled; + const int16_t *ref_feature_value; + + if (current->primary_ref_frame == AV1_PRIMARY_REF_NONE) { + ref_feature_enabled = default_feature_enabled; + ref_feature_value = default_feature_value; + } else { + ref_feature_enabled = + priv->ref[current->ref_frame_idx[current->primary_ref_frame]].feature_enabled[i]; + ref_feature_value = + priv->ref[current->ref_frame_idx[current->primary_ref_frame]].feature_value[i]; + } + + for (j = 0; j < AV1_SEG_LVL_MAX; j++) { + if (current->segmentation_update_data) { flags(feature_enabled[i][j], 2, i, j); if (current->feature_enabled[i][j] && bits[j] > 0) { @@ -755,6 +792,9 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, } else { infer(feature_value[i][j], 0); } + } else { + infer(feature_enabled[i][j], ref_feature_enabled[j]); + infer(feature_value[i][j], ref_feature_value[j]); } } } @@ -816,6 +856,9 @@ static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw, AV1RawFrameHeader *current) { CodedBitstreamAV1Context *priv = ctx->priv_data; + static const int8_t default_loop_filter_ref_deltas[AV1_TOTAL_REFS_PER_FRAME] = + { 1, 0, 0, 0, -1, 0, -1, -1 }; + static const int8_t default_loop_filter_mode_deltas[2] = { 0, 0 }; int i, err; if (priv->coded_lossless || current->allow_intrabc) { @@ -849,19 +892,44 @@ static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw, flag(loop_filter_delta_enabled); if (current->loop_filter_delta_enabled) { - flag(loop_filter_delta_update); - if (current->loop_filter_delta_update) { - for (i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) { - flags(update_ref_delta[i], 1, i); - if (current->update_ref_delta[i]) - sus(1 + 6, loop_filter_ref_deltas[i], 1, i); - } - for (i = 0; i < 2; i++) { - flags(update_mode_delta[i], 1, i); - if (current->update_mode_delta[i]) - sus(1 + 6, loop_filter_mode_deltas[i], 1, i); - } + const int8_t *ref_loop_filter_ref_deltas, *ref_loop_filter_mode_deltas; + + if (current->primary_ref_frame == AV1_PRIMARY_REF_NONE) { + ref_loop_filter_ref_deltas = default_loop_filter_ref_deltas; + ref_loop_filter_mode_deltas = default_loop_filter_mode_deltas; + } else { + ref_loop_filter_ref_deltas = + priv->ref[current->ref_frame_idx[current->primary_ref_frame]].loop_filter_ref_deltas; + ref_loop_filter_mode_deltas = + priv->ref[current->ref_frame_idx[current->primary_ref_frame]].loop_filter_mode_deltas; } + + flag(loop_filter_delta_update); + for (i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) { + if (current->loop_filter_delta_update) + flags(update_ref_delta[i], 1, i); + else + infer(update_ref_delta[i], 0); + if (current->update_ref_delta[i]) + sus(1 + 6, loop_filter_ref_deltas[i], 1, i); + else + infer(loop_filter_ref_deltas[i], ref_loop_filter_ref_deltas[i]); + } + for (i = 0; i < 2; i++) { + if (current->loop_filter_delta_update) + flags(update_mode_delta[i], 1, i); + else + infer(update_mode_delta[i], 0); + if (current->update_mode_delta[i]) + sus(1 + 6, loop_filter_mode_deltas[i], 1, i); + else + infer(loop_filter_mode_deltas[i], ref_loop_filter_mode_deltas[i]); + } + } else { + for (i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) + infer(loop_filter_ref_deltas[i], default_loop_filter_ref_deltas[i]); + for (i = 0; i < 2; i++) + infer(loop_filter_mode_deltas[i], default_loop_filter_mode_deltas[i]); } return 0; @@ -919,7 +987,7 @@ static int FUNC(lr_params)(CodedBitstreamContext *ctx, RWContext *rw, for (i = 0; i < priv->num_planes; i++) { fbs(2, lr_type[i], 1, i); - if (current->lr_type[i] != 0) { + if (current->lr_type[i] != AV1_RESTORE_NONE) { uses_lr = 1; if (i > 0) uses_chroma_lr = 1; @@ -1126,7 +1194,8 @@ static int FUNC(global_motion_params)(CodedBitstreamContext *ctx, RWContext *rw, } static int FUNC(film_grain_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) + AV1RawFilmGrainParams *current, + AV1RawFrameHeader *frame_header) { CodedBitstreamAV1Context *priv = ctx->priv_data; const AV1RawSequenceHeader *seq = priv->sequence_header; @@ -1134,7 +1203,7 @@ static int FUNC(film_grain_params)(CodedBitstreamContext *ctx, RWContext *rw, int i, err; if (!seq->film_grain_params_present || - (!current->show_frame && !current->showable_frame)) + (!frame_header->show_frame && !frame_header->showable_frame)) return 0; flag(apply_grain); @@ -1144,7 +1213,7 @@ static int FUNC(film_grain_params)(CodedBitstreamContext *ctx, RWContext *rw, fb(16, grain_seed); - if (current->frame_type == AV1_FRAME_INTER) + if (frame_header->frame_type == AV1_FRAME_INTER) flag(update_grain); else infer(update_grain, 1); @@ -1266,6 +1335,13 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, fb(3, frame_to_show_map_idx); ref = &priv->ref[current->frame_to_show_map_idx]; + if (!ref->valid) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "Missing reference frame needed for " + "show_existing_frame (frame_to_show_map_idx = %d).\n", + current->frame_to_show_map_idx); + return AVERROR_INVALIDDATA; + } + if (seq->decoder_model_info_present_flag && !seq->timing_info.equal_picture_interval) { fb(seq->decoder_model_info.frame_presentation_time_length_minus_1 + 1, @@ -1291,6 +1367,11 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, } else infer(refresh_frame_flags, 0); + infer(frame_width_minus_1, ref->upscaled_width - 1); + infer(frame_height_minus_1, ref->frame_height - 1); + infer(render_width_minus_1, ref->render_width - 1); + infer(render_height_minus_1, ref->render_height - 1); + // Section 7.20 goto update_refs; } @@ -1410,9 +1491,12 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, fb(8, refresh_frame_flags); if (!frame_is_intra || current->refresh_frame_flags != all_frames) { - if (current->error_resilient_mode && seq->enable_order_hint) { + if (seq->enable_order_hint) { for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - fbs(order_hint_bits, ref_order_hint[i], 1, i); + if (current->error_resilient_mode) + fbs(order_hint_bits, ref_order_hint[i], 1, i); + else + infer(ref_order_hint[i], priv->ref[i].order_hint); if (current->ref_order_hint[i] != priv->ref[i].order_hint) priv->ref[i].valid = 0; } @@ -1552,7 +1636,7 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, CHECK(FUNC(global_motion_params)(ctx, rw, current)); - CHECK(FUNC(film_grain_params)(ctx, rw, current)); + CHECK(FUNC(film_grain_params)(ctx, rw, ¤t->film_grain, current)); av_log(ctx->log_ctx, AV_LOG_DEBUG, "Frame %d: size %dx%d " "upscaled %d render %dx%d subsample %dx%d " @@ -1580,6 +1664,14 @@ update_refs: .bit_depth = priv->bit_depth, .order_hint = priv->order_hint, }; + memcpy(priv->ref[i].loop_filter_ref_deltas, current->loop_filter_ref_deltas, + sizeof(current->loop_filter_ref_deltas)); + memcpy(priv->ref[i].loop_filter_mode_deltas, current->loop_filter_mode_deltas, + sizeof(current->loop_filter_mode_deltas)); + memcpy(priv->ref[i].feature_enabled, current->feature_enabled, + sizeof(current->feature_enabled)); + memcpy(priv->ref[i].feature_value, current->feature_value, + sizeof(current->feature_value)); } } @@ -1631,6 +1723,8 @@ static int FUNC(frame_header_obu)(CodedBitstreamContext *ctx, RWContext *rw, CHECK(FUNC(uncompressed_header)(ctx, rw, current)); + priv->tile_num = 0; + if (current->show_existing_frame) { priv->seen_frame_header = 0; } else { @@ -1696,10 +1790,12 @@ static int FUNC(tile_group_obu)(CodedBitstreamContext *ctx, RWContext *rw, } else { tile_bits = cbs_av1_tile_log2(1, priv->tile_cols) + cbs_av1_tile_log2(1, priv->tile_rows); - fb(tile_bits, tg_start); - fb(tile_bits, tg_end); + fc(tile_bits, tg_start, priv->tile_num, num_tiles - 1); + fc(tile_bits, tg_end, current->tg_start, num_tiles - 1); } + priv->tile_num = current->tg_end + 1; + CHECK(FUNC(byte_alignment)(ctx, rw)); // Reset header for next frame. diff --git a/libavcodec/cbs_bsf.c b/libavcodec/cbs_bsf.c new file mode 100644 index 000000000..f0f7dd79b --- /dev/null +++ b/libavcodec/cbs_bsf.c @@ -0,0 +1,159 @@ +/* + * 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 "bsf_internal.h" +#include "cbs_bsf.h" + +static int cbs_bsf_update_side_data(AVBSFContext *bsf, AVPacket *pkt) +{ + CBSBSFContext *ctx = bsf->priv_data; + CodedBitstreamFragment *frag = &ctx->fragment; + uint8_t *side_data; + buffer_size_t side_data_size; + int err; + + side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, + &side_data_size); + if (!side_data_size) + return 0; + + err = ff_cbs_read(ctx->input, frag, side_data, side_data_size); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, + "Failed to read extradata from packet side data.\n"); + return err; + } + + err = ctx->type->update_fragment(bsf, NULL, frag); + if (err < 0) + return err; + + err = ff_cbs_write_fragment_data(ctx->output, frag); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, + "Failed to write extradata into packet side data.\n"); + return err; + } + + side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, + frag->data_size); + if (!side_data) + return AVERROR(ENOMEM); + memcpy(side_data, frag->data, frag->data_size); + + ff_cbs_fragment_reset(frag); + return 0; +} + +int ff_cbs_bsf_generic_filter(AVBSFContext *bsf, AVPacket *pkt) +{ + CBSBSFContext *ctx = bsf->priv_data; + CodedBitstreamFragment *frag = &ctx->fragment; + int err; + + err = ff_bsf_get_packet_ref(bsf, pkt); + if (err < 0) + return err; + + err = cbs_bsf_update_side_data(bsf, pkt); + if (err < 0) + goto fail; + + err = ff_cbs_read_packet(ctx->input, frag, pkt); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to read %s from packet.\n", + ctx->type->fragment_name); + goto fail; + } + + if (frag->nb_units == 0) { + av_log(bsf, AV_LOG_ERROR, "No %s found in packet.\n", + ctx->type->unit_name); + err = AVERROR_INVALIDDATA; + goto fail; + } + + err = ctx->type->update_fragment(bsf, pkt, frag); + if (err < 0) + goto fail; + + err = ff_cbs_write_packet(ctx->output, pkt, frag); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to write %s into packet.\n", + ctx->type->fragment_name); + goto fail; + } + + err = 0; +fail: + ff_cbs_fragment_reset(frag); + + if (err < 0) + av_packet_unref(pkt); + + return err; +} + +int ff_cbs_bsf_generic_init(AVBSFContext *bsf, const CBSBSFType *type) +{ + CBSBSFContext *ctx = bsf->priv_data; + CodedBitstreamFragment *frag = &ctx->fragment; + int err; + + ctx->type = type; + + err = ff_cbs_init(&ctx->input, type->codec_id, bsf); + if (err < 0) + return err; + + err = ff_cbs_init(&ctx->output, type->codec_id, bsf); + if (err < 0) + return err; + + if (bsf->par_in->extradata) { + err = ff_cbs_read_extradata(ctx->input, frag, bsf->par_in); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); + goto fail; + } + + err = type->update_fragment(bsf, NULL, frag); + if (err < 0) + goto fail; + + err = ff_cbs_write_extradata(ctx->output, bsf->par_out, frag); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); + goto fail; + } + } + + err = 0; +fail: + ff_cbs_fragment_reset(frag); + return err; +} + +void ff_cbs_bsf_generic_close(AVBSFContext *bsf) +{ + CBSBSFContext *ctx = bsf->priv_data; + + ff_cbs_fragment_free(&ctx->fragment); + ff_cbs_close(&ctx->input); + ff_cbs_close(&ctx->output); +} diff --git a/libavcodec/cbs_bsf.h b/libavcodec/cbs_bsf.h new file mode 100644 index 000000000..6be95abc3 --- /dev/null +++ b/libavcodec/cbs_bsf.h @@ -0,0 +1,131 @@ +/* + * 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_CBS_BSF_H +#define AVCODEC_CBS_BSF_H + +#include "cbs.h" + + +typedef struct CBSBSFType { + enum AVCodecID codec_id; + + // Name of a frame fragment in this codec (e.g. "access unit", + // "temporal unit"). + const char *fragment_name; + + // Name of a unit for this BSF, for use in error messages (e.g. + // "NAL unit", "OBU"). + const char *unit_name; + + // Update the content of a fragment with whatever metadata changes + // are desired. The associated AVPacket is provided so that any side + // data associated with the fragment can be inspected or edited. If + // pkt is NULL, then an extradata header fragment is being updated. + int (*update_fragment)(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *frag); +} CBSBSFType; + +// Common structure for all generic CBS BSF users. An instance of this +// structure must be the first member of the BSF private context (to be +// pointed to by AVBSFContext.priv_data). +typedef struct CBSBSFContext { + const AVClass *class; + const CBSBSFType *type; + + CodedBitstreamContext *input; + CodedBitstreamContext *output; + CodedBitstreamFragment fragment; +} CBSBSFContext; + +/** + * Initialise generic CBS BSF setup. + * + * Creates the input and output CBS instances, and applies the filter to + * the extradata on the input codecpar if any is present. + * + * Since it calls the update_fragment() function immediately to deal with + * extradata, this should be called after any codec-specific setup is done + * (probably at the end of the AVBitStreamFilter.init function). + */ +int ff_cbs_bsf_generic_init(AVBSFContext *bsf, const CBSBSFType *type); + +/** + * Close a generic CBS BSF instance. + * + * If no other deinitialisation is required then this function can be used + * directly as AVBitStreamFilter.close. + */ +void ff_cbs_bsf_generic_close(AVBSFContext *bsf); + +/** + * Filter operation for CBS BSF. + * + * Reads the input packet into a CBS fragment, calls update_fragment() on + * it, then writes the result to an output packet. If the input packet + * has AV_PKT_DATA_NEW_EXTRADATA side-data associated with it then it does + * the same thing to that new extradata to form the output side-data first. + * + * If the BSF does not do anything else then this function can be used + * directly as AVBitStreamFilter.filter. + */ +int ff_cbs_bsf_generic_filter(AVBSFContext *bsf, AVPacket *pkt); + + +// Options for element manipulation. +enum { + // Pass this element through unchanged. + BSF_ELEMENT_PASS, + // Insert this element, replacing any existing instances of it. + // Associated values may be provided explicitly (as addtional options) + // or implicitly (either as side data or deduced from other parts of + // the stream). + BSF_ELEMENT_INSERT, + // Remove this element if it appears in the stream. + BSF_ELEMENT_REMOVE, + // Extract this element to side data, so that further manipulation + // can happen elsewhere. + BSF_ELEMENT_EXTRACT, +}; + +#define BSF_ELEMENT_OPTIONS_PIR(name, help, field, opt_flags) \ + { name, help, OFFSET(field), AV_OPT_TYPE_INT, \ + { .i64 = BSF_ELEMENT_PASS }, \ + BSF_ELEMENT_PASS, BSF_ELEMENT_REMOVE, opt_flags, name }, \ + { "pass", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_PASS }, .flags = opt_flags, .unit = name }, \ + { "insert", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_INSERT }, .flags = opt_flags, .unit = name }, \ + { "remove", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_REMOVE }, .flags = opt_flags, .unit = name } + +#define BSF_ELEMENT_OPTIONS_PIRE(name, help, field, opt_flags) \ + { name, help, OFFSET(field), AV_OPT_TYPE_INT, \ + { .i64 = BSF_ELEMENT_PASS }, \ + BSF_ELEMENT_PASS, BSF_ELEMENT_EXTRACT, opt_flags, name }, \ + { "pass", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_PASS }, .flags = opt_flags, .unit = name }, \ + { "insert", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_INSERT }, .flags = opt_flags, .unit = name }, \ + { "remove", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_REMOVE }, .flags = opt_flags, .unit = name }, \ + { "extract", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_EXTRACT }, .flags = opt_flags, .unit = name } \ + + +#endif /* AVCODEC_CBS_BSF_H */ diff --git a/libavcodec/cbs_h264.h b/libavcodec/cbs_h264.h index 9f7c2a0d3..5a8641a33 100644 --- a/libavcodec/cbs_h264.h +++ b/libavcodec/cbs_h264.h @@ -24,19 +24,10 @@ #include "cbs.h" #include "cbs_h2645.h" +#include "cbs_sei.h" #include "h264.h" -enum { - // This limit is arbitrary - it is sufficient for one message of each - // type plus some repeats, and will therefore easily cover all sane - // streams. However, it is possible to make technically-valid streams - // for which it will fail (for example, by including a large number of - // user-data-unregistered messages). - H264_MAX_SEI_PAYLOADS = 64, -}; - - typedef struct H264RawNALUnitHeader { uint8_t nal_ref_idc; uint8_t nal_unit_type; @@ -274,21 +265,6 @@ typedef struct H264RawSEIPanScanRect { uint16_t pan_scan_rect_repetition_period; } H264RawSEIPanScanRect; -typedef struct H264RawSEIUserDataRegistered { - uint8_t itu_t_t35_country_code; - uint8_t itu_t_t35_country_code_extension_byte; - uint8_t *data; - size_t data_length; - AVBufferRef *data_ref; -} H264RawSEIUserDataRegistered; - -typedef struct H264RawSEIUserDataUnregistered { - uint8_t uuid_iso_iec_11578[16]; - uint8_t *data; - size_t data_length; - AVBufferRef *data_ref; -} H264RawSEIUserDataUnregistered; - typedef struct H264RawSEIRecoveryPoint { uint16_t recovery_frame_cnt; uint8_t exact_match_flag; @@ -305,47 +281,9 @@ typedef struct H264RawSEIDisplayOrientation { uint8_t display_orientation_extension_flag; } H264RawSEIDisplayOrientation; -typedef struct H264RawSEIMasteringDisplayColourVolume { - uint16_t display_primaries_x[3]; - uint16_t display_primaries_y[3]; - uint16_t white_point_x; - uint16_t white_point_y; - uint32_t max_display_mastering_luminance; - uint32_t min_display_mastering_luminance; -} H264RawSEIMasteringDisplayColourVolume; - -typedef struct H264RawSEIAlternativeTransferCharacteristics { - uint8_t preferred_transfer_characteristics; -} H264RawSEIAlternativeTransferCharacteristics; - -typedef struct H264RawSEIPayload { - uint32_t payload_type; - uint32_t payload_size; - union { - H264RawSEIBufferingPeriod buffering_period; - H264RawSEIPicTiming pic_timing; - H264RawSEIPanScanRect pan_scan_rect; - // H264RawSEIFiller filler -> no fields. - H264RawSEIUserDataRegistered user_data_registered; - H264RawSEIUserDataUnregistered user_data_unregistered; - H264RawSEIRecoveryPoint recovery_point; - H264RawSEIDisplayOrientation display_orientation; - H264RawSEIMasteringDisplayColourVolume mastering_display_colour_volume; - H264RawSEIAlternativeTransferCharacteristics - alternative_transfer_characteristics; - struct { - uint8_t *data; - size_t data_length; - AVBufferRef *data_ref; - } other; - } payload; -} H264RawSEIPayload; - typedef struct H264RawSEI { H264RawNALUnitHeader nal_unit_header; - - H264RawSEIPayload payload[H264_MAX_SEI_PAYLOADS]; - uint8_t payload_count; + SEIRawMessageList message_list; } H264RawSEI; typedef struct H264RawSliceHeader { @@ -429,10 +367,10 @@ typedef struct H264RawSliceHeader { typedef struct H264RawSlice { H264RawSliceHeader header; - uint8_t *data; - size_t data_size; - int data_bit_start; + uint8_t *data; AVBufferRef *data_ref; + size_t data_size; + int data_bit_start; } H264RawSlice; typedef struct H264RawFiller { @@ -465,29 +403,4 @@ typedef struct CodedBitstreamH264Context { uint8_t last_slice_nal_unit_type; } CodedBitstreamH264Context; - -/** - * Add an SEI message to an access unit. - * - * On success, the payload will be owned by a unit in access_unit; - * on failure, the content of the payload will be freed. - */ -int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *access_unit, - H264RawSEIPayload *payload); - -/** - * Delete an SEI message from an access unit. - * - * Deletes from nal_unit, which must be an SEI NAL unit. If this is the - * last message in nal_unit, also deletes it from access_unit. - * - * Requires nal_unit to be a unit in access_unit and position to be >= 0 - * and < the payload count of the SEI nal_unit. - */ -void ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *access_unit, - CodedBitstreamUnit *nal_unit, - int position); - #endif /* AVCODEC_CBS_H264_H */ diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 64fe2c1b9..6005d46e0 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -253,9 +253,11 @@ static int cbs_h265_payload_extension_present(GetBitContext *gbc, uint32_t paylo return err; \ } while (0) -#define FUNC_NAME(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name -#define FUNC_H264(rw, name) FUNC_NAME(rw, h264, name) -#define FUNC_H265(rw, name) FUNC_NAME(rw, h265, name) +#define FUNC_NAME2(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name +#define FUNC_NAME1(rw, codec, name) FUNC_NAME2(rw, codec, name) +#define FUNC_H264(name) FUNC_NAME1(READWRITE, h264, name) +#define FUNC_H265(name) FUNC_NAME1(READWRITE, h265, name) +#define FUNC_SEI(name) FUNC_NAME1(READWRITE, sei, name) #define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL) @@ -346,6 +348,7 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) #define more_rbsp_data(var) ((var) = cbs_h2645_read_more_rbsp_data(rw)) +#define bit_position(rw) (get_bits_count(rw)) #define byte_alignment(rw) (get_bits_count(rw) % 8) #define allocate(name, size) do { \ @@ -356,11 +359,15 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) name = name ## _ref->data; \ } while (0) -#define FUNC(name) FUNC_H264(READWRITE, name) +#define FUNC(name) FUNC_SEI(name) +#include "cbs_sei_syntax_template.c" +#undef FUNC + +#define FUNC(name) FUNC_H264(name) #include "cbs_h264_syntax_template.c" #undef FUNC -#define FUNC(name) FUNC_H265(READWRITE, name) +#define FUNC(name) FUNC_H265(name) #include "cbs_h265_syntax_template.c" #undef FUNC @@ -373,6 +380,7 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) #undef xse #undef infer #undef more_rbsp_data +#undef bit_position #undef byte_alignment #undef allocate @@ -418,6 +426,7 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) #define more_rbsp_data(var) (var) +#define bit_position(rw) (put_bits_count(rw)) #define byte_alignment(rw) (put_bits_count(rw) % 8) #define allocate(name, size) do { \ @@ -428,11 +437,15 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) } \ } while (0) -#define FUNC(name) FUNC_H264(READWRITE, name) +#define FUNC(name) FUNC_SEI(name) +#include "cbs_sei_syntax_template.c" +#undef FUNC + +#define FUNC(name) FUNC_H264(name) #include "cbs_h264_syntax_template.c" #undef FUNC -#define FUNC(name) FUNC_H265(READWRITE, name) +#define FUNC(name) FUNC_H265(name) #include "cbs_h265_syntax_template.c" #undef FUNC @@ -450,122 +463,11 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) #undef se #undef infer #undef more_rbsp_data +#undef bit_position #undef byte_alignment #undef allocate -static void cbs_h264_free_pps(void *opaque, uint8_t *content) -{ - H264RawPPS *pps = (H264RawPPS*)content; - av_buffer_unref(&pps->slice_group_id_ref); - av_freep(&content); -} - -static void cbs_h264_free_sei_payload(H264RawSEIPayload *payload) -{ - switch (payload->payload_type) { - case H264_SEI_TYPE_BUFFERING_PERIOD: - case H264_SEI_TYPE_PIC_TIMING: - case H264_SEI_TYPE_PAN_SCAN_RECT: - case H264_SEI_TYPE_RECOVERY_POINT: - case H264_SEI_TYPE_DISPLAY_ORIENTATION: - case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: - case H264_SEI_TYPE_ALTERNATIVE_TRANSFER: - break; - case H264_SEI_TYPE_USER_DATA_REGISTERED: - av_buffer_unref(&payload->payload.user_data_registered.data_ref); - break; - case H264_SEI_TYPE_USER_DATA_UNREGISTERED: - av_buffer_unref(&payload->payload.user_data_unregistered.data_ref); - break; - default: - av_buffer_unref(&payload->payload.other.data_ref); - break; - } -} - -static void cbs_h264_free_sei(void *opaque, uint8_t *content) -{ - H264RawSEI *sei = (H264RawSEI*)content; - int i; - for (i = 0; i < sei->payload_count; i++) - cbs_h264_free_sei_payload(&sei->payload[i]); - av_freep(&content); -} - -static void cbs_h264_free_slice(void *opaque, uint8_t *content) -{ - H264RawSlice *slice = (H264RawSlice*)content; - av_buffer_unref(&slice->data_ref); - av_freep(&content); -} - -static void cbs_h265_free_vps(void *opaque, uint8_t *content) -{ - H265RawVPS *vps = (H265RawVPS*)content; - av_buffer_unref(&vps->extension_data.data_ref); - av_freep(&content); -} - -static void cbs_h265_free_sps(void *opaque, uint8_t *content) -{ - H265RawSPS *sps = (H265RawSPS*)content; - av_buffer_unref(&sps->extension_data.data_ref); - av_freep(&content); -} - -static void cbs_h265_free_pps(void *opaque, uint8_t *content) -{ - H265RawPPS *pps = (H265RawPPS*)content; - av_buffer_unref(&pps->extension_data.data_ref); - av_freep(&content); -} - -static void cbs_h265_free_slice(void *opaque, uint8_t *content) -{ - H265RawSlice *slice = (H265RawSlice*)content; - av_buffer_unref(&slice->data_ref); - av_freep(&content); -} - -static void cbs_h265_free_sei_payload(H265RawSEIPayload *payload) -{ - switch (payload->payload_type) { - case HEVC_SEI_TYPE_BUFFERING_PERIOD: - case HEVC_SEI_TYPE_PICTURE_TIMING: - case HEVC_SEI_TYPE_PAN_SCAN_RECT: - case HEVC_SEI_TYPE_RECOVERY_POINT: - case HEVC_SEI_TYPE_DISPLAY_ORIENTATION: - case HEVC_SEI_TYPE_ACTIVE_PARAMETER_SETS: - case HEVC_SEI_TYPE_DECODED_PICTURE_HASH: - case HEVC_SEI_TYPE_TIME_CODE: - case HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO: - case HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO: - case HEVC_SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: - case HEVC_SEI_TYPE_ALPHA_CHANNEL_INFO: - break; - case HEVC_SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: - av_buffer_unref(&payload->payload.user_data_registered.data_ref); - break; - case HEVC_SEI_TYPE_USER_DATA_UNREGISTERED: - av_buffer_unref(&payload->payload.user_data_unregistered.data_ref); - break; - default: - av_buffer_unref(&payload->payload.other.data_ref); - break; - } - av_buffer_unref(&payload->extension_data.data_ref); -} - -static void cbs_h265_free_sei(void *opaque, uint8_t *content) -{ - H265RawSEI *sei = (H265RawSEI*)content; - int i; - for (i = 0; i < sei->payload_count; i++) - cbs_h265_free_sei_payload(&sei->payload[i]); - av_freep(&content); -} - static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const H2645Packet *packet) @@ -591,7 +493,7 @@ static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, ref = (nal->data == nal->raw_data) ? frag->data_ref : packet->rbsp.rbsp_buffer_ref; - err = ff_cbs_insert_unit_data(ctx, frag, -1, nal->type, + err = ff_cbs_insert_unit_data(frag, -1, nal->type, (uint8_t*)nal->data, size, ref); if (err < 0) return err; @@ -766,23 +668,23 @@ static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \ CodedBitstreamH26 ## h26n ## Context *priv = ctx->priv_data; \ H26 ## h26n ## Raw ## ps_name *ps_var = unit->content; \ unsigned int id = ps_var->id_element; \ + int err; \ if (id >= FF_ARRAY_ELEMS(priv->ps_var)) { \ av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid " #ps_name \ " id : %d.\n", id); \ return AVERROR_INVALIDDATA; \ } \ + err = ff_cbs_make_unit_refcounted(ctx, unit); \ + if (err < 0) \ + return err; \ if (priv->ps_var[id] == priv->active_ ## ps_var) \ priv->active_ ## ps_var = NULL ; \ av_buffer_unref(&priv->ps_var ## _ref[id]); \ - if (unit->content_ref) \ - priv->ps_var ## _ref[id] = av_buffer_ref(unit->content_ref); \ - else \ - priv->ps_var ## _ref[id] = av_buffer_alloc(sizeof(*ps_var)); \ + av_assert0(unit->content_ref); \ + priv->ps_var ## _ref[id] = av_buffer_ref(unit->content_ref); \ if (!priv->ps_var ## _ref[id]) \ return AVERROR(ENOMEM); \ priv->ps_var[id] = (H26 ## h26n ## Raw ## ps_name *)priv->ps_var ## _ref[id]->data; \ - if (!unit->content_ref) \ - memcpy(priv->ps_var[id], ps_var, sizeof(*ps_var)); \ return 0; \ } @@ -802,15 +704,14 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; + err = ff_cbs_alloc_unit_content2(ctx, unit); + if (err < 0) + return err; + switch (unit->type) { case H264_NAL_SPS: { - H264RawSPS *sps; - - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*sps), NULL); - if (err < 0) - return err; - sps = unit->content; + H264RawSPS *sps = unit->content; err = cbs_h264_read_sps(ctx, &gbc, sps); if (err < 0) @@ -824,12 +725,6 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_SPS_EXT: { - err = ff_cbs_alloc_unit_content(ctx, unit, - sizeof(H264RawSPSExtension), - NULL); - if (err < 0) - return err; - err = cbs_h264_read_sps_extension(ctx, &gbc, unit->content); if (err < 0) return err; @@ -838,13 +733,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_PPS: { - H264RawPPS *pps; - - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*pps), - &cbs_h264_free_pps); - if (err < 0) - return err; - pps = unit->content; + H264RawPPS *pps = unit->content; err = cbs_h264_read_pps(ctx, &gbc, pps); if (err < 0) @@ -860,15 +749,9 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_IDR_SLICE: case H264_NAL_AUXILIARY_SLICE: { - H264RawSlice *slice; + H264RawSlice *slice = unit->content; int pos, len; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice), - &cbs_h264_free_slice); - if (err < 0) - return err; - slice = unit->content; - err = cbs_h264_read_slice_header(ctx, &gbc, &slice->header); if (err < 0) return err; @@ -890,11 +773,6 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_AUD: { - err = ff_cbs_alloc_unit_content(ctx, unit, - sizeof(H264RawAUD), NULL); - if (err < 0) - return err; - err = cbs_h264_read_aud(ctx, &gbc, unit->content); if (err < 0) return err; @@ -903,11 +781,6 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_SEI: { - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(H264RawSEI), - &cbs_h264_free_sei); - if (err < 0) - return err; - err = cbs_h264_read_sei(ctx, &gbc, unit->content); if (err < 0) return err; @@ -916,11 +789,6 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_FILLER_DATA: { - err = ff_cbs_alloc_unit_content(ctx, unit, - sizeof(H264RawFiller), NULL); - if (err < 0) - return err; - err = cbs_h264_read_filler(ctx, &gbc, unit->content); if (err < 0) return err; @@ -930,12 +798,6 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_END_SEQUENCE: case H264_NAL_END_STREAM: { - err = ff_cbs_alloc_unit_content(ctx, unit, - sizeof(H264RawNALUnitHeader), - NULL); - if (err < 0) - return err; - err = (unit->type == H264_NAL_END_SEQUENCE ? cbs_h264_read_end_of_sequence : cbs_h264_read_end_of_stream)(ctx, &gbc, unit->content); @@ -961,16 +823,14 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; + err = ff_cbs_alloc_unit_content2(ctx, unit); + if (err < 0) + return err; + switch (unit->type) { case HEVC_NAL_VPS: { - H265RawVPS *vps; - - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*vps), - &cbs_h265_free_vps); - if (err < 0) - return err; - vps = unit->content; + H265RawVPS *vps = unit->content; err = cbs_h265_read_vps(ctx, &gbc, vps); if (err < 0) @@ -983,13 +843,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, break; case HEVC_NAL_SPS: { - H265RawSPS *sps; - - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*sps), - &cbs_h265_free_sps); - if (err < 0) - return err; - sps = unit->content; + H265RawSPS *sps = unit->content; err = cbs_h265_read_sps(ctx, &gbc, sps); if (err < 0) @@ -1003,13 +857,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, case HEVC_NAL_PPS: { - H265RawPPS *pps; - - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*pps), - &cbs_h265_free_pps); - if (err < 0) - return err; - pps = unit->content; + H265RawPPS *pps = unit->content; err = cbs_h265_read_pps(ctx, &gbc, pps); if (err < 0) @@ -1038,15 +886,9 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, case HEVC_NAL_IDR_N_LP: case HEVC_NAL_CRA_NUT: { - H265RawSlice *slice; + H265RawSlice *slice = unit->content; int pos, len; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice), - &cbs_h265_free_slice); - if (err < 0) - return err; - slice = unit->content; - err = cbs_h265_read_slice_segment_header(ctx, &gbc, &slice->header); if (err < 0) return err; @@ -1068,11 +910,6 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, case HEVC_NAL_AUD: { - err = ff_cbs_alloc_unit_content(ctx, unit, - sizeof(H265RawAUD), NULL); - if (err < 0) - return err; - err = cbs_h265_read_aud(ctx, &gbc, unit->content); if (err < 0) return err; @@ -1082,12 +919,6 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, case HEVC_NAL_SEI_PREFIX: case HEVC_NAL_SEI_SUFFIX: { - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(H265RawSEI), - &cbs_h265_free_sei); - - if (err < 0) - return err; - err = cbs_h265_read_sei(ctx, &gbc, unit->content, unit->type == HEVC_NAL_SEI_PREFIX); @@ -1390,6 +1221,22 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, return 0; } +static int cbs_h2645_unit_requires_zero_byte(enum AVCodecID codec_id, + CodedBitstreamUnitType type, + int nal_unit_index) +{ + // Section B.1.2 in H.264, section B.2.2 in H.265. + if (nal_unit_index == 0) { + // Assume that this is the first NAL unit in an access unit. + return 1; + } + if (codec_id == AV_CODEC_ID_H264) + return type == H264_NAL_SPS || type == H264_NAL_PPS; + if (codec_id == AV_CODEC_ID_HEVC) + return type == HEVC_NAL_VPS || type == HEVC_NAL_SPS || type == HEVC_NAL_PPS; + return 0; +} + static int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag) { @@ -1424,14 +1271,7 @@ static int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, frag->data_bit_padding = unit->data_bit_padding; } - if ((ctx->codec->codec_id == AV_CODEC_ID_H264 && - (unit->type == H264_NAL_SPS || - unit->type == H264_NAL_PPS)) || - (ctx->codec->codec_id == AV_CODEC_ID_HEVC && - (unit->type == HEVC_NAL_VPS || - unit->type == HEVC_NAL_SPS || - unit->type == HEVC_NAL_PPS)) || - i == 0 /* (Assume this is the start of an access unit.) */) { + if (cbs_h2645_unit_requires_zero_byte(ctx->codec->codec_id, unit->type, i)) { // zero_byte data[dp++] = 0; } @@ -1477,6 +1317,24 @@ static int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, return 0; } +static void cbs_h264_flush(CodedBitstreamContext *ctx) +{ + CodedBitstreamH264Context *h264 = ctx->priv_data; + + for (int i = 0; i < FF_ARRAY_ELEMS(h264->sps); i++) { + av_buffer_unref(&h264->sps_ref[i]); + h264->sps[i] = NULL; + } + for (int i = 0; i < FF_ARRAY_ELEMS(h264->pps); i++) { + av_buffer_unref(&h264->pps_ref[i]); + h264->pps[i] = NULL; + } + + h264->active_sps = NULL; + h264->active_pps = NULL; + h264->last_slice_nal_unit_type = 0; +} + static void cbs_h264_close(CodedBitstreamContext *ctx) { CodedBitstreamH264Context *h264 = ctx->priv_data; @@ -1490,6 +1348,28 @@ static void cbs_h264_close(CodedBitstreamContext *ctx) av_buffer_unref(&h264->pps_ref[i]); } +static void cbs_h265_flush(CodedBitstreamContext *ctx) +{ + CodedBitstreamH265Context *h265 = ctx->priv_data; + + for (int i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++) { + av_buffer_unref(&h265->vps_ref[i]); + h265->vps[i] = NULL; + } + for (int i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++) { + av_buffer_unref(&h265->sps_ref[i]); + h265->sps[i] = NULL; + } + for (int i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++) { + av_buffer_unref(&h265->pps_ref[i]); + h265->pps[i] = NULL; + } + + h265->active_vps = NULL; + h265->active_sps = NULL; + h265->active_pps = NULL; +} + static void cbs_h265_close(CodedBitstreamContext *ctx) { CodedBitstreamH265Context *h265 = ctx->priv_data; @@ -1505,16 +1385,107 @@ static void cbs_h265_close(CodedBitstreamContext *ctx) av_buffer_unref(&h265->pps_ref[i]); } +static void cbs_h264_free_sei(void *opaque, uint8_t *content) +{ + H264RawSEI *sei = (H264RawSEI*)content; + ff_cbs_sei_free_message_list(&sei->message_list); + av_free(content); +} + +static const CodedBitstreamUnitTypeDescriptor cbs_h264_unit_types[] = { + CBS_UNIT_TYPE_POD(H264_NAL_SPS, H264RawSPS), + CBS_UNIT_TYPE_POD(H264_NAL_SPS_EXT, H264RawSPSExtension), + + CBS_UNIT_TYPE_INTERNAL_REF(H264_NAL_PPS, H264RawPPS, slice_group_id), + + { + .nb_unit_types = 3, + .unit_types = { + H264_NAL_IDR_SLICE, + H264_NAL_SLICE, + H264_NAL_AUXILIARY_SLICE, + }, + .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, + .content_size = sizeof(H264RawSlice), + .nb_ref_offsets = 1, + .ref_offsets = { offsetof(H264RawSlice, data) }, + }, + + CBS_UNIT_TYPE_POD(H264_NAL_AUD, H264RawAUD), + CBS_UNIT_TYPE_POD(H264_NAL_FILLER_DATA, H264RawFiller), + CBS_UNIT_TYPE_POD(H264_NAL_END_SEQUENCE, H264RawNALUnitHeader), + CBS_UNIT_TYPE_POD(H264_NAL_END_STREAM, H264RawNALUnitHeader), + + CBS_UNIT_TYPE_COMPLEX(H264_NAL_SEI, H264RawSEI, &cbs_h264_free_sei), + + CBS_UNIT_TYPE_END_OF_LIST +}; + +static void cbs_h265_free_sei(void *opaque, uint8_t *content) +{ + H265RawSEI *sei = (H265RawSEI*)content; + ff_cbs_sei_free_message_list(&sei->message_list); + av_free(content); +} + +static const CodedBitstreamUnitTypeDescriptor cbs_h265_unit_types[] = { + CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_VPS, H265RawVPS, extension_data.data), + CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_SPS, H265RawSPS, extension_data.data), + CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_PPS, H265RawPPS, extension_data.data), + + CBS_UNIT_TYPE_POD(HEVC_NAL_AUD, H265RawAUD), + + { + // Slices of non-IRAP pictures. + .nb_unit_types = CBS_UNIT_TYPE_RANGE, + .unit_type_range_start = HEVC_NAL_TRAIL_N, + .unit_type_range_end = HEVC_NAL_RASL_R, + + .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, + .content_size = sizeof(H265RawSlice), + .nb_ref_offsets = 1, + .ref_offsets = { offsetof(H265RawSlice, data) }, + }, + + { + // Slices of IRAP pictures. + .nb_unit_types = CBS_UNIT_TYPE_RANGE, + .unit_type_range_start = HEVC_NAL_BLA_W_LP, + .unit_type_range_end = HEVC_NAL_CRA_NUT, + + .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, + .content_size = sizeof(H265RawSlice), + .nb_ref_offsets = 1, + .ref_offsets = { offsetof(H265RawSlice, data) }, + }, + + { + .nb_unit_types = 2, + .unit_types = { + HEVC_NAL_SEI_PREFIX, + HEVC_NAL_SEI_SUFFIX + }, + .content_type = CBS_CONTENT_TYPE_COMPLEX, + .content_size = sizeof(H265RawSEI), + .content_free = &cbs_h265_free_sei, + }, + + CBS_UNIT_TYPE_END_OF_LIST +}; + const CodedBitstreamType ff_cbs_type_h264 = { .codec_id = AV_CODEC_ID_H264, .priv_data_size = sizeof(CodedBitstreamH264Context), + .unit_types = cbs_h264_unit_types, + .split_fragment = &cbs_h2645_split_fragment, .read_unit = &cbs_h264_read_nal_unit, .write_unit = &cbs_h264_write_nal_unit, .assemble_fragment = &cbs_h2645_assemble_fragment, + .flush = &cbs_h264_flush, .close = &cbs_h264_close, }; @@ -1523,102 +1494,175 @@ const CodedBitstreamType ff_cbs_type_h265 = { .priv_data_size = sizeof(CodedBitstreamH265Context), + .unit_types = cbs_h265_unit_types, + .split_fragment = &cbs_h2645_split_fragment, .read_unit = &cbs_h265_read_nal_unit, .write_unit = &cbs_h265_write_nal_unit, .assemble_fragment = &cbs_h2645_assemble_fragment, + .flush = &cbs_h265_flush, .close = &cbs_h265_close, }; -int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *au, - H264RawSEIPayload *payload) +static const SEIMessageTypeDescriptor cbs_sei_common_types[] = { + { + SEI_TYPE_FILLER_PAYLOAD, + 1, 1, + sizeof(SEIRawFillerPayload), + SEI_MESSAGE_RW(sei, filler_payload), + }, + { + SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35, + 1, 1, + sizeof(SEIRawUserDataRegistered), + SEI_MESSAGE_RW(sei, user_data_registered), + }, + { + SEI_TYPE_USER_DATA_UNREGISTERED, + 1, 1, + sizeof(SEIRawUserDataUnregistered), + SEI_MESSAGE_RW(sei, user_data_unregistered), + }, + { + SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME, + 1, 0, + sizeof(SEIRawMasteringDisplayColourVolume), + SEI_MESSAGE_RW(sei, mastering_display_colour_volume), + }, + { + SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO, + 1, 0, + sizeof(SEIRawContentLightLevelInfo), + SEI_MESSAGE_RW(sei, content_light_level_info), + }, + { + SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS, + 1, 0, + sizeof(SEIRawAlternativeTransferCharacteristics), + SEI_MESSAGE_RW(sei, alternative_transfer_characteristics), + }, + SEI_MESSAGE_TYPE_END, +}; + +static const SEIMessageTypeDescriptor cbs_sei_h264_types[] = { + { + SEI_TYPE_BUFFERING_PERIOD, + 1, 0, + sizeof(H264RawSEIBufferingPeriod), + SEI_MESSAGE_RW(h264, sei_buffering_period), + }, + { + SEI_TYPE_PIC_TIMING, + 1, 0, + sizeof(H264RawSEIPicTiming), + SEI_MESSAGE_RW(h264, sei_pic_timing), + }, + { + SEI_TYPE_PAN_SCAN_RECT, + 1, 0, + sizeof(H264RawSEIPanScanRect), + SEI_MESSAGE_RW(h264, sei_pan_scan_rect), + }, + { + SEI_TYPE_RECOVERY_POINT, + 1, 0, + sizeof(H264RawSEIRecoveryPoint), + SEI_MESSAGE_RW(h264, sei_recovery_point), + }, + { + SEI_TYPE_DISPLAY_ORIENTATION, + 1, 0, + sizeof(H264RawSEIDisplayOrientation), + SEI_MESSAGE_RW(h264, sei_display_orientation), + }, + SEI_MESSAGE_TYPE_END +}; + +static const SEIMessageTypeDescriptor cbs_sei_h265_types[] = { + { + SEI_TYPE_BUFFERING_PERIOD, + 1, 0, + sizeof(H265RawSEIBufferingPeriod), + SEI_MESSAGE_RW(h265, sei_buffering_period), + }, + { + SEI_TYPE_PIC_TIMING, + 1, 0, + sizeof(H265RawSEIPicTiming), + SEI_MESSAGE_RW(h265, sei_pic_timing), + }, + { + SEI_TYPE_PAN_SCAN_RECT, + 1, 0, + sizeof(H265RawSEIPanScanRect), + SEI_MESSAGE_RW(h265, sei_pan_scan_rect), + }, + { + SEI_TYPE_RECOVERY_POINT, + 1, 0, + sizeof(H265RawSEIRecoveryPoint), + SEI_MESSAGE_RW(h265, sei_recovery_point), + }, + { + SEI_TYPE_DISPLAY_ORIENTATION, + 1, 0, + sizeof(H265RawSEIDisplayOrientation), + SEI_MESSAGE_RW(h265, sei_display_orientation), + }, + { + SEI_TYPE_ACTIVE_PARAMETER_SETS, + 1, 0, + sizeof(H265RawSEIActiveParameterSets), + SEI_MESSAGE_RW(h265, sei_active_parameter_sets), + }, + { + SEI_TYPE_DECODED_PICTURE_HASH, + 0, 1, + sizeof(H265RawSEIDecodedPictureHash), + SEI_MESSAGE_RW(h265, sei_decoded_picture_hash), + }, + { + SEI_TYPE_TIME_CODE, + 1, 0, + sizeof(H265RawSEITimeCode), + SEI_MESSAGE_RW(h265, sei_time_code), + }, + { + SEI_TYPE_ALPHA_CHANNEL_INFO, + 1, 0, + sizeof(H265RawSEIAlphaChannelInfo), + SEI_MESSAGE_RW(h265, sei_alpha_channel_info), + }, + SEI_MESSAGE_TYPE_END +}; + +const SEIMessageTypeDescriptor *ff_cbs_sei_find_type(CodedBitstreamContext *ctx, + int payload_type) { - H264RawSEI *sei = NULL; - int err, i; + const SEIMessageTypeDescriptor *codec_list; + int i; - // Find an existing SEI NAL unit to add to. - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_SEI) { - sei = au->units[i].content; - if (sei->payload_count < H264_MAX_SEI_PAYLOADS) - break; - - sei = NULL; - } + for (i = 0; cbs_sei_common_types[i].type >= 0; i++) { + if (cbs_sei_common_types[i].type == payload_type) + return &cbs_sei_common_types[i]; } - if (!sei) { - // Need to make a new SEI NAL unit. Insert it before the first - // slice data NAL unit; if no slice data, add at the end. - AVBufferRef *sei_ref; - - sei = av_mallocz(sizeof(*sei)); - if (!sei) { - err = AVERROR(ENOMEM); - goto fail; - } - - sei->nal_unit_header.nal_unit_type = H264_NAL_SEI; - sei->nal_unit_header.nal_ref_idc = 0; - - sei_ref = av_buffer_create((uint8_t*)sei, sizeof(*sei), - &cbs_h264_free_sei, NULL, 0); - if (!sei_ref) { - av_freep(&sei); - err = AVERROR(ENOMEM); - goto fail; - } - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_SLICE || - au->units[i].type == H264_NAL_IDR_SLICE) - break; - } - - err = ff_cbs_insert_unit_content(ctx, au, i, H264_NAL_SEI, - sei, sei_ref); - av_buffer_unref(&sei_ref); - if (err < 0) - goto fail; + switch (ctx->codec->codec_id) { + case AV_CODEC_ID_H264: + codec_list = cbs_sei_h264_types; + break; + case AV_CODEC_ID_H265: + codec_list = cbs_sei_h265_types; + break; + default: + return NULL; } - memcpy(&sei->payload[sei->payload_count], payload, sizeof(*payload)); - ++sei->payload_count; + for (i = 0; codec_list[i].type >= 0; i++) { + if (codec_list[i].type == payload_type) + return &codec_list[i]; + } - return 0; -fail: - cbs_h264_free_sei_payload(payload); - return err; -} - -void ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *au, - CodedBitstreamUnit *nal, - int position) -{ - H264RawSEI *sei = nal->content; - - av_assert0(nal->type == H264_NAL_SEI); - av_assert0(position >= 0 && position < sei->payload_count); - - if (position == 0 && sei->payload_count == 1) { - // Deleting NAL unit entirely. - int i; - - for (i = 0; i < au->nb_units; i++) { - if (&au->units[i] == nal) - break; - } - - ff_cbs_delete_unit(ctx, au, i); - } else { - cbs_h264_free_sei_payload(&sei->payload[position]); - - --sei->payload_count; - memmove(sei->payload + position, - sei->payload + position + 1, - (sei->payload_count - position) * sizeof(*sei->payload)); - } + return NULL; } diff --git a/libavcodec/cbs_h264_syntax_template.c b/libavcodec/cbs_h264_syntax_template.c index b65460996..9587f3398 100644 --- a/libavcodec/cbs_h264_syntax_template.c +++ b/libavcodec/cbs_h264_syntax_template.c @@ -511,7 +511,8 @@ static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw, } static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIBufferingPeriod *current) + H264RawSEIBufferingPeriod *current, + SEIMessageState *sei) { CodedBitstreamH264Context *h264 = ctx->priv_data; const H264RawSPS *sps; @@ -604,7 +605,8 @@ static int FUNC(sei_pic_timestamp)(CodedBitstreamContext *ctx, RWContext *rw, } static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIPicTiming *current) + H264RawSEIPicTiming *current, + SEIMessageState *sei) { CodedBitstreamH264Context *h264 = ctx->priv_data; const H264RawSPS *sps; @@ -675,7 +677,8 @@ static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, } static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIPanScanRect *current) + H264RawSEIPanScanRect *current, + SEIMessageState *sei) { int err, i; @@ -700,72 +703,9 @@ static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_user_data_registered)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIUserDataRegistered *current, - uint32_t *payload_size) -{ - int err, i, j; - - HEADER("User Data Registered ITU-T T.35"); - - u(8, itu_t_t35_country_code, 0x00, 0xff); - if (current->itu_t_t35_country_code != 0xff) - i = 1; - else { - u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); - i = 2; - } - -#ifdef READ - if (*payload_size < i) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data registered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - i; -#else - *payload_size = i + current->data_length; -#endif - - allocate(current->data, current->data_length); - for (j = 0; j < current->data_length; j++) - xu(8, itu_t_t35_payload_byte[i], current->data[j], 0x00, 0xff, 1, i + j); - - return 0; -} - -static int FUNC(sei_user_data_unregistered)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIUserDataUnregistered *current, - uint32_t *payload_size) -{ - int err, i; - - HEADER("User Data Unregistered"); - -#ifdef READ - if (*payload_size < 16) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data unregistered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - 16; -#else - *payload_size = 16 + current->data_length; -#endif - - for (i = 0; i < 16; i++) - us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); - - allocate(current->data, current->data_length); - - for (i = 0; i < current->data_length; i++) - xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); - - return 0; -} - static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIRecoveryPoint *current) + H264RawSEIRecoveryPoint *current, + SEIMessageState *sei) { int err; @@ -780,7 +720,8 @@ static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, } static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIDisplayOrientation *current) + H264RawSEIDisplayOrientation *current, + SEIMessageState *sei) { int err; @@ -798,205 +739,17 @@ static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext * return 0; } -static int FUNC(sei_mastering_display_colour_volume)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIMasteringDisplayColourVolume *current) -{ - int err, c; - - HEADER("Mastering Display Colour Volume"); - - for (c = 0; c < 3; c++) { - us(16, display_primaries_x[c], 0, 50000, 1, c); - us(16, display_primaries_y[c], 0, 50000, 1, c); - } - - u(16, white_point_x, 0, 50000); - u(16, white_point_y, 0, 50000); - - u(32, max_display_mastering_luminance, 1, MAX_UINT_BITS(32)); - u(32, min_display_mastering_luminance, 0, current->max_display_mastering_luminance - 1); - - return 0; -} - -static int FUNC(sei_alternative_transfer_characteristics)(CodedBitstreamContext *ctx, - RWContext *rw, - H264RawSEIAlternativeTransferCharacteristics *current) -{ - int err; - - HEADER("Alternative Transfer Characteristics"); - - ub(8, preferred_transfer_characteristics); - - return 0; -} - -static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIPayload *current) -{ - int err, i; - int start_position, end_position; - -#ifdef READ - start_position = get_bits_count(rw); -#else - start_position = put_bits_count(rw); -#endif - - switch (current->payload_type) { - case H264_SEI_TYPE_BUFFERING_PERIOD: - CHECK(FUNC(sei_buffering_period) - (ctx, rw, ¤t->payload.buffering_period)); - break; - case H264_SEI_TYPE_PIC_TIMING: - CHECK(FUNC(sei_pic_timing) - (ctx, rw, ¤t->payload.pic_timing)); - break; - case H264_SEI_TYPE_PAN_SCAN_RECT: - CHECK(FUNC(sei_pan_scan_rect) - (ctx, rw, ¤t->payload.pan_scan_rect)); - break; - case H264_SEI_TYPE_FILLER_PAYLOAD: - { - for (i = 0; i < current->payload_size; i++) - fixed(8, ff_byte, 0xff); - } - break; - case H264_SEI_TYPE_USER_DATA_REGISTERED: - CHECK(FUNC(sei_user_data_registered) - (ctx, rw, ¤t->payload.user_data_registered, ¤t->payload_size)); - break; - case H264_SEI_TYPE_USER_DATA_UNREGISTERED: - CHECK(FUNC(sei_user_data_unregistered) - (ctx, rw, ¤t->payload.user_data_unregistered, ¤t->payload_size)); - break; - case H264_SEI_TYPE_RECOVERY_POINT: - CHECK(FUNC(sei_recovery_point) - (ctx, rw, ¤t->payload.recovery_point)); - break; - case H264_SEI_TYPE_DISPLAY_ORIENTATION: - CHECK(FUNC(sei_display_orientation) - (ctx, rw, ¤t->payload.display_orientation)); - break; - case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: - CHECK(FUNC(sei_mastering_display_colour_volume) - (ctx, rw, ¤t->payload.mastering_display_colour_volume)); - break; - case H264_SEI_TYPE_ALTERNATIVE_TRANSFER: - CHECK(FUNC(sei_alternative_transfer_characteristics) - (ctx, rw, ¤t->payload.alternative_transfer_characteristics)); - break; - default: - { -#ifdef READ - current->payload.other.data_length = current->payload_size; -#endif - allocate(current->payload.other.data, current->payload.other.data_length); - for (i = 0; i < current->payload.other.data_length; i++) - xu(8, payload_byte[i], current->payload.other.data[i], 0, 255, 1, i); - } - } - - if (byte_alignment(rw)) { - fixed(1, bit_equal_to_one, 1); - while (byte_alignment(rw)) - fixed(1, bit_equal_to_zero, 0); - } - -#ifdef READ - end_position = get_bits_count(rw); - if (end_position < start_position + 8 * current->payload_size) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Incorrect SEI payload length: " - "header %"PRIu32" bits, actually %d bits.\n", - 8 * current->payload_size, - end_position - start_position); - return AVERROR_INVALIDDATA; - } -#else - end_position = put_bits_count(rw); - current->payload_size = (end_position - start_position) / 8; -#endif - - return 0; -} - static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEI *current) { - int err, k; + int err; HEADER("Supplemental Enhancement Information"); CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, 1 << H264_NAL_SEI)); -#ifdef READ - for (k = 0; k < H264_MAX_SEI_PAYLOADS; k++) { - uint32_t payload_type = 0; - uint32_t payload_size = 0; - uint32_t tmp; - - while (show_bits(rw, 8) == 0xff) { - fixed(8, ff_byte, 0xff); - payload_type += 255; - } - xu(8, last_payload_type_byte, tmp, 0, 254, 0); - payload_type += tmp; - - while (show_bits(rw, 8) == 0xff) { - fixed(8, ff_byte, 0xff); - payload_size += 255; - } - xu(8, last_payload_size_byte, tmp, 0, 254, 0); - payload_size += tmp; - - current->payload[k].payload_type = payload_type; - current->payload[k].payload_size = payload_size; - - current->payload_count++; - CHECK(FUNC(sei_payload)(ctx, rw, ¤t->payload[k])); - - if (!cbs_h2645_read_more_rbsp_data(rw)) - break; - } - if (k >= H264_MAX_SEI_PAYLOADS) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many payloads in " - "SEI message: found %d.\n", k); - return AVERROR_INVALIDDATA; - } -#else - for (k = 0; k < current->payload_count; k++) { - PutBitContext start_state; - uint32_t tmp; - int need_size, i; - - // Somewhat clumsy: we write the payload twice when - // we don't know the size in advance. This will mess - // with trace output, but is otherwise harmless. - start_state = *rw; - need_size = !current->payload[k].payload_size; - for (i = 0; i < 1 + need_size; i++) { - *rw = start_state; - - tmp = current->payload[k].payload_type; - while (tmp >= 255) { - fixed(8, ff_byte, 0xff); - tmp -= 255; - } - xu(8, last_payload_type_byte, tmp, 0, 254, 0); - - tmp = current->payload[k].payload_size; - while (tmp >= 255) { - fixed(8, ff_byte, 0xff); - tmp -= 255; - } - xu(8, last_payload_size_byte, tmp, 0, 254, 0); - - CHECK(FUNC(sei_payload)(ctx, rw, ¤t->payload[k])); - } - } -#endif + CHECK(FUNC_SEI(message_list)(ctx, rw, ¤t->message_list, 1)); CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); diff --git a/libavcodec/cbs_h265.h b/libavcodec/cbs_h265.h index 73897f77a..f7753f120 100644 --- a/libavcodec/cbs_h265.h +++ b/libavcodec/cbs_h265.h @@ -23,17 +23,9 @@ #include #include "cbs_h2645.h" +#include "cbs_sei.h" #include "hevc.h" -enum { - // This limit is arbitrary - it is sufficient for one message of each - // type plus some repeats, and will therefore easily cover all sane - // streams. However, it is possible to make technically-valid streams - // for which it will fail (for example, by including a large number of - // user-data-unregistered messages). - H265_MAX_SEI_PAYLOADS = 64, -}; - typedef struct H265RawNALUnitHeader { uint8_t nal_unit_type; uint8_t nuh_layer_id; @@ -183,9 +175,9 @@ typedef struct H265RawVUI { } H265RawVUI; typedef struct H265RawExtensionData { - uint8_t *data; - size_t bit_length; + uint8_t *data; AVBufferRef *data_ref; + size_t bit_length; } H265RawExtensionData; typedef struct H265RawVPS { @@ -541,10 +533,10 @@ typedef struct H265RawSliceHeader { typedef struct H265RawSlice { H265RawSliceHeader header; - uint8_t *data; - size_t data_size; - int data_bit_start; + uint8_t *data; AVBufferRef *data_ref; + size_t data_size; + int data_bit_start; } H265RawSlice; @@ -596,21 +588,6 @@ typedef struct H265RawSEIPanScanRect { uint16_t pan_scan_rect_persistence_flag; } H265RawSEIPanScanRect; -typedef struct H265RawSEIUserDataRegistered { - uint8_t itu_t_t35_country_code; - uint8_t itu_t_t35_country_code_extension_byte; - uint8_t *data; - size_t data_length; - AVBufferRef *data_ref; -} H265RawSEIUserDataRegistered; - -typedef struct H265RawSEIUserDataUnregistered { - uint8_t uuid_iso_iec_11578[16]; - uint8_t *data; - size_t data_length; - AVBufferRef *data_ref; -} H265RawSEIUserDataUnregistered; - typedef struct H265RawSEIRecoveryPoint { int16_t recovery_poc_cnt; uint8_t exact_match_flag; @@ -661,24 +638,6 @@ typedef struct H265RawSEITimeCode { int32_t time_offset_value[3]; } H265RawSEITimeCode; -typedef struct H265RawSEIMasteringDisplayColourVolume { - uint16_t display_primaries_x[3]; - uint16_t display_primaries_y[3]; - uint16_t white_point_x; - uint16_t white_point_y; - uint32_t max_display_mastering_luminance; - uint32_t min_display_mastering_luminance; -} H265RawSEIMasteringDisplayColourVolume; - -typedef struct H265RawSEIContentLightLevelInfo { - uint16_t max_content_light_level; - uint16_t max_pic_average_light_level; -} H265RawSEIContentLightLevelInfo; - -typedef struct H265RawSEIAlternativeTransferCharacteristics { - uint8_t preferred_transfer_characteristics; -} H265RawSEIAlternativeTransferCharacteristics; - typedef struct H265RawSEIAlphaChannelInfo { uint8_t alpha_channel_cancel_flag; uint8_t alpha_channel_use_idc; @@ -690,39 +649,9 @@ typedef struct H265RawSEIAlphaChannelInfo { uint8_t alpha_channel_clip_type_flag; } H265RawSEIAlphaChannelInfo; -typedef struct H265RawSEIPayload { - uint32_t payload_type; - uint32_t payload_size; - union { - H265RawSEIBufferingPeriod buffering_period; - H265RawSEIPicTiming pic_timing; - H265RawSEIPanScanRect pan_scan_rect; - H265RawSEIUserDataRegistered user_data_registered; - H265RawSEIUserDataUnregistered user_data_unregistered; - H265RawSEIRecoveryPoint recovery_point; - H265RawSEIDisplayOrientation display_orientation; - H265RawSEIActiveParameterSets active_parameter_sets; - H265RawSEIDecodedPictureHash decoded_picture_hash; - H265RawSEITimeCode time_code; - H265RawSEIMasteringDisplayColourVolume mastering_display; - H265RawSEIContentLightLevelInfo content_light_level; - H265RawSEIAlternativeTransferCharacteristics - alternative_transfer_characteristics; - H265RawSEIAlphaChannelInfo alpha_channel_info; - struct { - uint8_t *data; - size_t data_length; - AVBufferRef *data_ref; - } other; - } payload; - H265RawExtensionData extension_data; -} H265RawSEIPayload; - typedef struct H265RawSEI { H265RawNALUnitHeader nal_unit_header; - - H265RawSEIPayload payload[H265_MAX_SEI_PAYLOADS]; - uint8_t payload_count; + SEIRawMessageList message_list; } H265RawSEI; typedef struct CodedBitstreamH265Context { diff --git a/libavcodec/cbs_h265_syntax_template.c b/libavcodec/cbs_h265_syntax_template.c index 48fae82d0..5d216aad3 100644 --- a/libavcodec/cbs_h265_syntax_template.c +++ b/libavcodec/cbs_h265_syntax_template.c @@ -1369,6 +1369,7 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, if (current->nal_unit_header.nal_unit_type != HEVC_NAL_IDR_W_RADL && current->nal_unit_header.nal_unit_type != HEVC_NAL_IDR_N_LP) { const H265RawSTRefPicSet *rps; + int dpb_slots_remaining; ub(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, slice_pic_order_cnt_lsb); @@ -1387,6 +1388,22 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, rps = &sps->st_ref_pic_set[0]; } + dpb_slots_remaining = HEVC_MAX_DPB_SIZE - 1 - + rps->num_negative_pics - rps->num_positive_pics; + if (pps->pps_curr_pic_ref_enabled_flag && + (sps->sample_adaptive_offset_enabled_flag || + !pps->pps_deblocking_filter_disabled_flag || + pps->deblocking_filter_override_enabled_flag)) { + // This picture will occupy two DPB slots. + if (dpb_slots_remaining == 0) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid stream: " + "short-term ref pic set contains too many pictures " + "to use with current picture reference enabled.\n"); + return AVERROR_INVALIDDATA; + } + --dpb_slots_remaining; + } + num_pic_total_curr = 0; for (i = 0; i < rps->num_negative_pics; i++) if (rps->used_by_curr_pic_s0_flag[i]) @@ -1399,13 +1416,15 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, unsigned int idx_size; if (sps->num_long_term_ref_pics_sps > 0) { - ue(num_long_term_sps, 0, sps->num_long_term_ref_pics_sps); + ue(num_long_term_sps, 0, FFMIN(sps->num_long_term_ref_pics_sps, + dpb_slots_remaining)); idx_size = av_log2(sps->num_long_term_ref_pics_sps - 1) + 1; + dpb_slots_remaining -= current->num_long_term_sps; } else { infer(num_long_term_sps, 0); idx_size = 0; } - ue(num_long_term_pics, 0, HEVC_MAX_REFS - current->num_long_term_sps); + ue(num_long_term_pics, 0, dpb_slots_remaining); for (i = 0; i < current->num_long_term_sps + current->num_long_term_pics; i++) { @@ -1596,10 +1615,9 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIBufferingPeriod *current, - uint32_t *payload_size, - int *more_data) +static int FUNC(sei_buffering_period) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIBufferingPeriod *current, SEIMessageState *sei) { CodedBitstreamH265Context *h265 = ctx->priv_data; const H265RawSPS *sps; @@ -1687,7 +1705,7 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, #ifdef READ end_pos = get_bits_count(rw); - if (cbs_h265_payload_extension_present(rw, *payload_size, + if (cbs_h265_payload_extension_present(rw, sei->payload_size, end_pos - start_pos)) flag(use_alt_cpb_params_flag); else @@ -1695,20 +1713,21 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, #else // If unknown extension data exists, then use_alt_cpb_params_flag is // coded in the bitstream and must be written even if it's 0. - if (current->use_alt_cpb_params_flag || *more_data) { + if (current->use_alt_cpb_params_flag || sei->extension_present) { flag(use_alt_cpb_params_flag); // Ensure this bit is not the last in the payload by making the // more_data_in_payload() check evaluate to true, so it may not // be mistaken as something else by decoders. - *more_data = 1; + sei->extension_present = 1; } #endif return 0; } -static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIPicTiming *current) +static int FUNC(sei_pic_timing) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIPicTiming *current, SEIMessageState *sei) { CodedBitstreamH265Context *h265 = ctx->priv_data; const H265RawSPS *sps; @@ -1782,8 +1801,9 @@ static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIPanScanRect *current) +static int FUNC(sei_pan_scan_rect) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIPanScanRect *current, SEIMessageState *sei) { int err, i; @@ -1808,72 +1828,9 @@ static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_user_data_registered)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIUserDataRegistered *current, - uint32_t *payload_size) -{ - int err, i, j; - - HEADER("User Data Registered ITU-T T.35"); - - u(8, itu_t_t35_country_code, 0x00, 0xff); - if (current->itu_t_t35_country_code != 0xff) - i = 1; - else { - u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); - i = 2; - } - -#ifdef READ - if (*payload_size < i) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data registered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - i; -#else - *payload_size = i + current->data_length; -#endif - - allocate(current->data, current->data_length); - for (j = 0; j < current->data_length; j++) - xu(8, itu_t_t35_payload_byte[i], current->data[j], 0x00, 0xff, 1, i + j); - - return 0; -} - -static int FUNC(sei_user_data_unregistered)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIUserDataUnregistered *current, - uint32_t *payload_size) -{ - int err, i; - - HEADER("User Data Unregistered"); - -#ifdef READ - if (*payload_size < 16) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data unregistered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - 16; -#else - *payload_size = 16 + current->data_length; -#endif - - for (i = 0; i < 16; i++) - us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); - - allocate(current->data, current->data_length); - - for (i = 0; i < current->data_length; i++) - xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); - - return 0; -} - -static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIRecoveryPoint *current) +static int FUNC(sei_recovery_point) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIRecoveryPoint *current, SEIMessageState *sei) { int err; @@ -1887,8 +1844,9 @@ static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIDisplayOrientation *current) +static int FUNC(sei_display_orientation) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIDisplayOrientation *current, SEIMessageState *sei) { int err; @@ -1905,8 +1863,9 @@ static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext * return 0; } -static int FUNC(sei_active_parameter_sets)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIActiveParameterSets *current) +static int FUNC(sei_active_parameter_sets) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIActiveParameterSets *current, SEIMessageState *sei) { CodedBitstreamH265Context *h265 = ctx->priv_data; const H265RawVPS *vps; @@ -1941,8 +1900,9 @@ static int FUNC(sei_active_parameter_sets)(CodedBitstreamContext *ctx, RWContext return 0; } -static int FUNC(sei_decoded_picture_hash)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIDecodedPictureHash *current) +static int FUNC(sei_decoded_picture_hash) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIDecodedPictureHash *current, SEIMessageState *sei) { CodedBitstreamH265Context *h265 = ctx->priv_data; const H265RawSPS *sps = h265->active_sps; @@ -1972,8 +1932,9 @@ static int FUNC(sei_decoded_picture_hash)(CodedBitstreamContext *ctx, RWContext return 0; } -static int FUNC(sei_time_code)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEITimeCode *current) +static int FUNC(sei_time_code) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEITimeCode *current, SEIMessageState *sei) { int err, i; @@ -2022,58 +1983,9 @@ static int FUNC(sei_time_code)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_mastering_display)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIMasteringDisplayColourVolume *current) -{ - int err, c; - - HEADER("Mastering Display Colour Volume"); - - for (c = 0; c < 3; c++) { - us(16, display_primaries_x[c], 0, 50000, 1, c); - us(16, display_primaries_y[c], 0, 50000, 1, c); - } - - u(16, white_point_x, 0, 50000); - u(16, white_point_y, 0, 50000); - - u(32, max_display_mastering_luminance, - 1, MAX_UINT_BITS(32)); - u(32, min_display_mastering_luminance, - 0, current->max_display_mastering_luminance - 1); - - return 0; -} - -static int FUNC(sei_content_light_level)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIContentLightLevelInfo *current) -{ - int err; - - HEADER("Content Light Level"); - - ub(16, max_content_light_level); - ub(16, max_pic_average_light_level); - - return 0; -} - -static int FUNC(sei_alternative_transfer_characteristics)(CodedBitstreamContext *ctx, - RWContext *rw, - H265RawSEIAlternativeTransferCharacteristics *current) -{ - int err; - - HEADER("Alternative Transfer Characteristics"); - - ub(8, preferred_transfer_characteristics); - - return 0; -} - -static int FUNC(sei_alpha_channel_info)(CodedBitstreamContext *ctx, - RWContext *rw, - H265RawSEIAlphaChannelInfo *current) +static int FUNC(sei_alpha_channel_info) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIAlphaChannelInfo *current, SEIMessageState *sei) { int err, length; @@ -2099,144 +2011,10 @@ static int FUNC(sei_alpha_channel_info)(CodedBitstreamContext *ctx, return 0; } -static int FUNC(payload_extension)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawExtensionData *current, uint32_t payload_size, - int cur_pos) -{ - int err; - size_t byte_length, k; - -#ifdef READ - GetBitContext tmp; - int bits_left, payload_zero_bits; - - if (!cbs_h265_payload_extension_present(rw, payload_size, cur_pos)) - return 0; - - bits_left = 8 * payload_size - cur_pos; - tmp = *rw; - if (bits_left > 8) - skip_bits_long(&tmp, bits_left - 8); - payload_zero_bits = get_bits(&tmp, FFMIN(bits_left, 8)); - if (!payload_zero_bits) - return AVERROR_INVALIDDATA; - payload_zero_bits = ff_ctz(payload_zero_bits); - current->bit_length = bits_left - payload_zero_bits - 1; - allocate(current->data, (current->bit_length + 7) / 8); -#endif - - byte_length = (current->bit_length + 7) / 8; - for (k = 0; k < byte_length; k++) { - int length = FFMIN(current->bit_length - k * 8, 8); - xu(length, reserved_payload_extension_data, current->data[k], - 0, MAX_UINT_BITS(length), 0); - } - - return 0; -} - -static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIPayload *current, int prefix) -{ - int err, i; - int start_position, current_position; - int more_data = !!current->extension_data.bit_length; - -#ifdef READ - start_position = get_bits_count(rw); -#else - start_position = put_bits_count(rw); -#endif - - switch (current->payload_type) { -#define SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid) do { \ - if (prefix && !prefix_valid) { \ - av_log(ctx->log_ctx, AV_LOG_ERROR, "SEI type %s invalid " \ - "as prefix SEI!\n", #name); \ - return AVERROR_INVALIDDATA; \ - } \ - if (!prefix && !suffix_valid) { \ - av_log(ctx->log_ctx, AV_LOG_ERROR, "SEI type %s invalid " \ - "as suffix SEI!\n", #name); \ - return AVERROR_INVALIDDATA; \ - } \ - } while (0) -#define SEI_TYPE_N(type, prefix_valid, suffix_valid, name) \ - case HEVC_SEI_TYPE_ ## type: \ - SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid); \ - CHECK(FUNC(sei_ ## name)(ctx, rw, ¤t->payload.name)); \ - break -#define SEI_TYPE_S(type, prefix_valid, suffix_valid, name) \ - case HEVC_SEI_TYPE_ ## type: \ - SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid); \ - CHECK(FUNC(sei_ ## name)(ctx, rw, ¤t->payload.name, \ - ¤t->payload_size)); \ - break -#define SEI_TYPE_E(type, prefix_valid, suffix_valid, name) \ - case HEVC_SEI_TYPE_ ## type: \ - SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid); \ - CHECK(FUNC(sei_ ## name)(ctx, rw, ¤t->payload.name, \ - ¤t->payload_size, \ - &more_data)); \ - break - - SEI_TYPE_E(BUFFERING_PERIOD, 1, 0, buffering_period); - SEI_TYPE_N(PICTURE_TIMING, 1, 0, pic_timing); - SEI_TYPE_N(PAN_SCAN_RECT, 1, 0, pan_scan_rect); - SEI_TYPE_S(USER_DATA_REGISTERED_ITU_T_T35, - 1, 1, user_data_registered); - SEI_TYPE_S(USER_DATA_UNREGISTERED, 1, 1, user_data_unregistered); - SEI_TYPE_N(RECOVERY_POINT, 1, 0, recovery_point); - SEI_TYPE_N(DISPLAY_ORIENTATION, 1, 0, display_orientation); - SEI_TYPE_N(ACTIVE_PARAMETER_SETS, 1, 0, active_parameter_sets); - SEI_TYPE_N(DECODED_PICTURE_HASH, 0, 1, decoded_picture_hash); - SEI_TYPE_N(TIME_CODE, 1, 0, time_code); - SEI_TYPE_N(MASTERING_DISPLAY_INFO, 1, 0, mastering_display); - SEI_TYPE_N(CONTENT_LIGHT_LEVEL_INFO, 1, 0, content_light_level); - SEI_TYPE_N(ALTERNATIVE_TRANSFER_CHARACTERISTICS, - 1, 0, alternative_transfer_characteristics); - SEI_TYPE_N(ALPHA_CHANNEL_INFO, 1, 0, alpha_channel_info); - -#undef SEI_TYPE - default: - { -#ifdef READ - current->payload.other.data_length = current->payload_size; -#endif - allocate(current->payload.other.data, current->payload.other.data_length); - - for (i = 0; i < current->payload_size; i++) - xu(8, payload_byte[i], current->payload.other.data[i], 0, 255, - 1, i); - } - } - - // more_data_in_payload() -#ifdef READ - current_position = get_bits_count(rw) - start_position; - if (current_position < 8 * current->payload_size) { -#else - current_position = put_bits_count(rw) - start_position; - if (byte_alignment(rw) || more_data) { -#endif - CHECK(FUNC(payload_extension)(ctx, rw, ¤t->extension_data, - current->payload_size, current_position)); - fixed(1, bit_equal_to_one, 1); - while (byte_alignment(rw)) - fixed(1, bit_equal_to_zero, 0); - } - -#ifdef WRITE - current->payload_size = (put_bits_count(rw) - start_position) >> 3; -#endif - - return 0; -} - static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw, H265RawSEI *current, int prefix) { - int err, k; + int err; if (prefix) HEADER("Prefix Supplemental Enhancement Information"); @@ -2247,72 +2025,7 @@ static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw, prefix ? HEVC_NAL_SEI_PREFIX : HEVC_NAL_SEI_SUFFIX)); -#ifdef READ - for (k = 0; k < H265_MAX_SEI_PAYLOADS; k++) { - uint32_t payload_type = 0; - uint32_t payload_size = 0; - uint32_t tmp; - - while (show_bits(rw, 8) == 0xff) { - fixed(8, ff_byte, 0xff); - payload_type += 255; - } - xu(8, last_payload_type_byte, tmp, 0, 254, 0); - payload_type += tmp; - - while (show_bits(rw, 8) == 0xff) { - fixed(8, ff_byte, 0xff); - payload_size += 255; - } - xu(8, last_payload_size_byte, tmp, 0, 254, 0); - payload_size += tmp; - - current->payload[k].payload_type = payload_type; - current->payload[k].payload_size = payload_size; - - current->payload_count++; - CHECK(FUNC(sei_payload)(ctx, rw, ¤t->payload[k], prefix)); - - if (!cbs_h2645_read_more_rbsp_data(rw)) - break; - } - if (k >= H265_MAX_SEI_PAYLOADS) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many payloads in " - "SEI message: found %d.\n", k); - return AVERROR_INVALIDDATA; - } -#else - for (k = 0; k < current->payload_count; k++) { - PutBitContext start_state; - uint32_t tmp; - int need_size, i; - - // Somewhat clumsy: we write the payload twice when - // we don't know the size in advance. This will mess - // with trace output, but is otherwise harmless. - start_state = *rw; - need_size = !current->payload[k].payload_size; - for (i = 0; i < 1 + need_size; i++) { - *rw = start_state; - - tmp = current->payload[k].payload_type; - while (tmp >= 255) { - fixed(8, ff_byte, 0xff); - tmp -= 255; - } - xu(8, last_payload_type_byte, tmp, 0, 254, 0); - - tmp = current->payload[k].payload_size; - while (tmp >= 255) { - fixed(8, ff_byte, 0xff); - tmp -= 255; - } - xu(8, last_payload_size_byte, tmp, 0, 254, 0); - - CHECK(FUNC(sei_payload)(ctx, rw, ¤t->payload[k], prefix)); - } - } -#endif + CHECK(FUNC_SEI(message_list)(ctx, rw, ¤t->message_list, prefix)); CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h index 4c5a535ca..a39288003 100644 --- a/libavcodec/cbs_internal.h +++ b/libavcodec/cbs_internal.h @@ -25,11 +25,79 @@ #include "put_bits.h" +enum CBSContentType { + // Unit content is a simple structure. + CBS_CONTENT_TYPE_POD, + // Unit content contains some references to other structures, but all + // managed via buffer reference counting. The descriptor defines the + // structure offsets of every buffer reference. + CBS_CONTENT_TYPE_INTERNAL_REFS, + // Unit content is something more complex. The descriptor defines + // special functions to manage the content. + CBS_CONTENT_TYPE_COMPLEX, +}; + +enum { + // Maximum number of unit types described by the same unit type + // descriptor. + CBS_MAX_UNIT_TYPES = 3, + // Maximum number of reference buffer offsets in any one unit. + CBS_MAX_REF_OFFSETS = 2, + // Special value used in a unit type descriptor to indicate that it + // applies to a large range of types rather than a set of discrete + // values. + CBS_UNIT_TYPE_RANGE = -1, +}; + +typedef const struct CodedBitstreamUnitTypeDescriptor { + // Number of entries in the unit_types array, or the special value + // CBS_UNIT_TYPE_RANGE to indicate that the range fields should be + // used instead. + int nb_unit_types; + + // Array of unit types that this entry describes. + const CodedBitstreamUnitType unit_types[CBS_MAX_UNIT_TYPES]; + + // Start and end of unit type range, used if nb_unit_types is + // CBS_UNIT_TYPE_RANGE. + const CodedBitstreamUnitType unit_type_range_start; + const CodedBitstreamUnitType unit_type_range_end; + + // The type of content described. + enum CBSContentType content_type; + // The size of the structure which should be allocated to contain + // the decomposed content of this type of unit. + size_t content_size; + + // Number of entries in the ref_offsets array. Only used if the + // content_type is CBS_CONTENT_TYPE_INTERNAL_REFS. + int nb_ref_offsets; + // The structure must contain two adjacent elements: + // type *field; + // AVBufferRef *field_ref; + // where field points to something in the buffer referred to by + // field_ref. This offset is then set to offsetof(struct, field). + size_t ref_offsets[CBS_MAX_REF_OFFSETS]; + + void (*content_free)(void *opaque, uint8_t *data); + int (*content_clone)(AVBufferRef **ref, CodedBitstreamUnit *unit); +} CodedBitstreamUnitTypeDescriptor; + typedef struct CodedBitstreamType { enum AVCodecID codec_id; + // A class for the private data, used to declare private AVOptions. + // This field is NULL for types that do not declare any options. + // If this field is non-NULL, the first member of the filter private data + // must be a pointer to AVClass. + const AVClass *priv_class; + size_t priv_data_size; + // List of unit type descriptors for this codec. + // Terminated by a descriptor with nb_unit_types equal to zero. + const CodedBitstreamUnitTypeDescriptor *unit_types; + // Split frag->data into coded bitstream units, creating the // frag->units array. Fill data but not content on each unit. // The header argument should be set if the fragment came from @@ -55,6 +123,9 @@ typedef struct CodedBitstreamType { int (*assemble_fragment)(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag); + // Reset the codec internal state. + void (*flush)(CodedBitstreamContext *ctx); + // Free the codec internal state. void (*close)(CodedBitstreamContext *ctx); } CodedBitstreamType; @@ -106,6 +177,30 @@ int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc, #define MIN_INT_BITS(length) (-(INT64_C(1) << ((length) - 1))) +#define CBS_UNIT_TYPE_POD(type, structure) { \ + .nb_unit_types = 1, \ + .unit_types = { type }, \ + .content_type = CBS_CONTENT_TYPE_POD, \ + .content_size = sizeof(structure), \ + } +#define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field) { \ + .nb_unit_types = 1, \ + .unit_types = { type }, \ + .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, \ + .content_size = sizeof(structure), \ + .nb_ref_offsets = 1, \ + .ref_offsets = { offsetof(structure, ref_field) }, \ + } +#define CBS_UNIT_TYPE_COMPLEX(type, structure, free_func) { \ + .nb_unit_types = 1, \ + .unit_types = { type }, \ + .content_type = CBS_CONTENT_TYPE_COMPLEX, \ + .content_size = sizeof(structure), \ + .content_free = free_func, \ + } +#define CBS_UNIT_TYPE_END_OF_LIST { .nb_unit_types = 0 } + + extern const CodedBitstreamType ff_cbs_type_av1; extern const CodedBitstreamType ff_cbs_type_h264; extern const CodedBitstreamType ff_cbs_type_h265; diff --git a/libavcodec/cbs_jpeg.c b/libavcodec/cbs_jpeg.c index 471d77074..7d3e10fcc 100644 --- a/libavcodec/cbs_jpeg.c +++ b/libavcodec/cbs_jpeg.c @@ -226,7 +226,7 @@ static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx, data_ref = frag->data_ref; } - err = ff_cbs_insert_unit_data(ctx, frag, unit, marker, + err = ff_cbs_insert_unit_data(frag, unit, marker, data, data_size, data_ref); if (err < 0) return err; @@ -252,7 +252,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, if (unit->type >= JPEG_MARKER_SOF0 && unit->type <= JPEG_MARKER_SOF3) { - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(JPEGRawFrameHeader), NULL); if (err < 0) @@ -264,7 +264,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, } else if (unit->type >= JPEG_MARKER_APPN && unit->type <= JPEG_MARKER_APPN + 15) { - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(JPEGRawApplicationData), &cbs_jpeg_free_application_data); if (err < 0) @@ -278,7 +278,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, JPEGRawScan *scan; int pos; - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(JPEGRawScan), &cbs_jpeg_free_scan); if (err < 0) @@ -304,7 +304,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, #define SEGMENT(marker, type, func, free) \ case JPEG_MARKER_ ## marker: \ { \ - err = ff_cbs_alloc_unit_content(ctx, unit, \ + err = ff_cbs_alloc_unit_content(unit, \ sizeof(type), free); \ if (err < 0) \ return err; \ diff --git a/libavcodec/cbs_jpeg.h b/libavcodec/cbs_jpeg.h index ff1961106..6305f0ee8 100644 --- a/libavcodec/cbs_jpeg.h +++ b/libavcodec/cbs_jpeg.h @@ -80,8 +80,8 @@ typedef struct JPEGRawScanHeader { typedef struct JPEGRawScan { JPEGRawScanHeader header; uint8_t *data; - size_t data_size; AVBufferRef *data_ref; + size_t data_size; } JPEGRawScan; typedef struct JPEGRawQuantisationTable { diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c index 97f7889cb..26400f279 100644 --- a/libavcodec/cbs_mpeg2.c +++ b/libavcodec/cbs_mpeg2.c @@ -140,28 +140,6 @@ #undef infer -static void cbs_mpeg2_free_picture_header(void *opaque, uint8_t *content) -{ - MPEG2RawPictureHeader *picture = (MPEG2RawPictureHeader*)content; - av_buffer_unref(&picture->extra_information_picture.extra_information_ref); - av_freep(&content); -} - -static void cbs_mpeg2_free_user_data(void *opaque, uint8_t *content) -{ - MPEG2RawUserData *user = (MPEG2RawUserData*)content; - av_buffer_unref(&user->user_data_ref); - av_freep(&content); -} - -static void cbs_mpeg2_free_slice(void *opaque, uint8_t *content) -{ - MPEG2RawSlice *slice = (MPEG2RawSlice*)content; - av_buffer_unref(&slice->header.extra_information_slice.extra_information_ref); - av_buffer_unref(&slice->data_ref); - av_freep(&content); -} - static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int header) @@ -207,7 +185,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx, final = 1; } - err = ff_cbs_insert_unit_data(ctx, frag, i, unit_type, (uint8_t*)start, + err = ff_cbs_insert_unit_data(frag, i, unit_type, (uint8_t*)start, unit_size, frag->data_ref); if (err < 0) return err; @@ -231,15 +209,13 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - if (MPEG2_START_IS_SLICE(unit->type)) { - MPEG2RawSlice *slice; - int pos, len; + err = ff_cbs_alloc_unit_content2(ctx, unit); + if (err < 0) + return err; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice), - &cbs_mpeg2_free_slice); - if (err < 0) - return err; - slice = unit->content; + if (MPEG2_START_IS_SLICE(unit->type)) { + MPEG2RawSlice *slice = unit->content; + int pos, len; err = cbs_mpeg2_read_slice_header(ctx, &gbc, &slice->header); if (err < 0) @@ -264,12 +240,7 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx, #define START(start_code, type, read_func, free_func) \ case start_code: \ { \ - type *header; \ - err = ff_cbs_alloc_unit_content(ctx, unit, \ - sizeof(*header), free_func); \ - if (err < 0) \ - return err; \ - header = unit->content; \ + type *header = unit->content; \ err = cbs_mpeg2_read_ ## read_func(ctx, &gbc, header); \ if (err < 0) \ return err; \ @@ -420,11 +391,40 @@ static int cbs_mpeg2_assemble_fragment(CodedBitstreamContext *ctx, return 0; } +static const CodedBitstreamUnitTypeDescriptor cbs_mpeg2_unit_types[] = { + CBS_UNIT_TYPE_INTERNAL_REF(MPEG2_START_PICTURE, MPEG2RawPictureHeader, + extra_information_picture.extra_information), + + { + .nb_unit_types = CBS_UNIT_TYPE_RANGE, + .unit_type_range_start = 0x01, + .unit_type_range_end = 0xaf, + + .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, + .content_size = sizeof(MPEG2RawSlice), + .nb_ref_offsets = 2, + .ref_offsets = { offsetof(MPEG2RawSlice, header.extra_information_slice.extra_information), + offsetof(MPEG2RawSlice, data) }, + }, + + CBS_UNIT_TYPE_INTERNAL_REF(MPEG2_START_USER_DATA, MPEG2RawUserData, + user_data), + + CBS_UNIT_TYPE_POD(MPEG2_START_SEQUENCE_HEADER, MPEG2RawSequenceHeader), + CBS_UNIT_TYPE_POD(MPEG2_START_EXTENSION, MPEG2RawExtensionData), + CBS_UNIT_TYPE_POD(MPEG2_START_SEQUENCE_END, MPEG2RawSequenceEnd), + CBS_UNIT_TYPE_POD(MPEG2_START_GROUP, MPEG2RawGroupOfPicturesHeader), + + CBS_UNIT_TYPE_END_OF_LIST +}; + const CodedBitstreamType ff_cbs_type_mpeg2 = { .codec_id = AV_CODEC_ID_MPEG2VIDEO, .priv_data_size = sizeof(CodedBitstreamMPEG2Context), + .unit_types = cbs_mpeg2_unit_types, + .split_fragment = &cbs_mpeg2_split_fragment, .read_unit = &cbs_mpeg2_read_unit, .write_unit = &cbs_mpeg2_write_unit, diff --git a/libavcodec/cbs_mpeg2.h b/libavcodec/cbs_mpeg2.h index 5bcafd09f..f7075a460 100644 --- a/libavcodec/cbs_mpeg2.h +++ b/libavcodec/cbs_mpeg2.h @@ -76,9 +76,9 @@ typedef struct MPEG2RawSequenceHeader { typedef struct MPEG2RawUserData { uint8_t user_data_start_code; - uint8_t *user_data; - size_t user_data_length; + uint8_t *user_data; AVBufferRef *user_data_ref; + size_t user_data_length; } MPEG2RawUserData; typedef struct MPEG2RawSequenceExtension { @@ -206,10 +206,10 @@ typedef struct MPEG2RawSliceHeader { typedef struct MPEG2RawSlice { MPEG2RawSliceHeader header; - uint8_t *data; - size_t data_size; - int data_bit_start; + uint8_t *data; AVBufferRef *data_ref; + size_t data_size; + int data_bit_start; } MPEG2RawSlice; typedef struct MPEG2RawSequenceEnd { diff --git a/libavcodec/cbs_sei.c b/libavcodec/cbs_sei.c new file mode 100644 index 000000000..141e97ec5 --- /dev/null +++ b/libavcodec/cbs_sei.c @@ -0,0 +1,369 @@ +/* + * 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 "cbs.h" +#include "cbs_internal.h" +#include "cbs_h264.h" +#include "cbs_h265.h" +#include "cbs_sei.h" + +static void cbs_free_user_data_registered(void *opaque, uint8_t *data) +{ + SEIRawUserDataRegistered *udr = (SEIRawUserDataRegistered*)data; + av_buffer_unref(&udr->data_ref); + av_free(udr); +} + +static void cbs_free_user_data_unregistered(void *opaque, uint8_t *data) +{ + SEIRawUserDataUnregistered *udu = (SEIRawUserDataUnregistered*)data; + av_buffer_unref(&udu->data_ref); + av_free(udu); +} + +int ff_cbs_sei_alloc_message_payload(SEIRawMessage *message, + const SEIMessageTypeDescriptor *desc) +{ + void (*free_func)(void*, uint8_t*); + + av_assert0(message->payload == NULL && + message->payload_ref == NULL); + message->payload_type = desc->type; + + if (desc->type == SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35) + free_func = &cbs_free_user_data_registered; + else if (desc->type == SEI_TYPE_USER_DATA_UNREGISTERED) + free_func = &cbs_free_user_data_unregistered; + else + free_func = NULL; + + if (free_func) { + message->payload = av_mallocz(desc->size); + if (!message->payload) + return AVERROR(ENOMEM); + message->payload_ref = + av_buffer_create(message->payload, desc->size, + free_func, NULL, 0); + } else { + message->payload_ref = av_buffer_alloc(desc->size); + } + if (!message->payload_ref) { + av_freep(&message->payload); + return AVERROR(ENOMEM); + } + message->payload = message->payload_ref->data; + + return 0; +} + +int ff_cbs_sei_list_add(SEIRawMessageList *list) +{ + void *ptr; + int old_count = list->nb_messages_allocated; + + av_assert0(list->nb_messages <= old_count); + if (list->nb_messages + 1 > old_count) { + int new_count = 2 * old_count + 1; + + ptr = av_realloc_array(list->messages, + new_count, sizeof(*list->messages)); + if (!ptr) + return AVERROR(ENOMEM); + + list->messages = ptr; + list->nb_messages_allocated = new_count; + + // Zero the newly-added entries. + memset(list->messages + old_count, 0, + (new_count - old_count) * sizeof(*list->messages)); + } + ++list->nb_messages; + return 0; +} + +void ff_cbs_sei_free_message_list(SEIRawMessageList *list) +{ + for (int i = 0; i < list->nb_messages; i++) { + SEIRawMessage *message = &list->messages[i]; + av_buffer_unref(&message->payload_ref); + av_buffer_unref(&message->extension_data_ref); + } + av_free(list->messages); +} + +static int cbs_sei_get_unit(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + int prefix, + CodedBitstreamUnit **sei_unit) +{ + CodedBitstreamUnit *unit; + int sei_type, highest_vcl_type, err, i, position; + + switch (ctx->codec->codec_id) { + case AV_CODEC_ID_H264: + // (We can ignore auxiliary slices because we only have prefix + // SEI in H.264 and an auxiliary picture must always follow a + // primary picture.) + highest_vcl_type = H264_NAL_IDR_SLICE; + if (prefix) + sei_type = H264_NAL_SEI; + else + return AVERROR(EINVAL); + break; + case AV_CODEC_ID_H265: + highest_vcl_type = HEVC_NAL_RSV_VCL31; + if (prefix) + sei_type = HEVC_NAL_SEI_PREFIX; + else + sei_type = HEVC_NAL_SEI_SUFFIX; + break; + default: + return AVERROR(EINVAL); + } + + // Find an existing SEI NAL unit of the right type. + unit = NULL; + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type == sei_type) { + unit = &au->units[i]; + break; + } + } + + if (unit) { + *sei_unit = unit; + return 0; + } + + // Need to add a new SEI NAL unit ... + if (prefix) { + // ... before the first VCL NAL unit. + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type < highest_vcl_type) + break; + } + position = i; + } else { + // ... after the last VCL NAL unit. + for (i = au->nb_units - 1; i >= 0; i--) { + if (au->units[i].type < highest_vcl_type) + break; + } + if (i < 0) { + // No VCL units; just put it at the end. + position = au->nb_units; + } else { + position = i + 1; + } + } + + err = ff_cbs_insert_unit_content(au, position, sei_type, + NULL, NULL); + if (err < 0) + return err; + unit = &au->units[position]; + unit->type = sei_type; + + err = ff_cbs_alloc_unit_content2(ctx, unit); + if (err < 0) + return err; + + switch (ctx->codec->codec_id) { + case AV_CODEC_ID_H264: + { + H264RawSEI sei = { + .nal_unit_header = { + .nal_ref_idc = 0, + .nal_unit_type = sei_type, + }, + }; + memcpy(unit->content, &sei, sizeof(sei)); + } + break; + case AV_CODEC_ID_H265: + { + H265RawSEI sei = { + .nal_unit_header = { + .nal_unit_type = sei_type, + .nuh_layer_id = 0, + .nuh_temporal_id_plus1 = 1, + }, + }; + memcpy(unit->content, &sei, sizeof(sei)); + } + break; + default: + av_assert0(0); + } + + *sei_unit = unit; + return 0; +} + +static int cbs_sei_get_message_list(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit, + SEIRawMessageList **list) +{ + switch (ctx->codec->codec_id) { + case AV_CODEC_ID_H264: + { + H264RawSEI *sei = unit->content; + if (unit->type != H264_NAL_SEI) + return AVERROR(EINVAL); + *list = &sei->message_list; + } + break; + case AV_CODEC_ID_H265: + { + H265RawSEI *sei = unit->content; + if (unit->type != HEVC_NAL_SEI_PREFIX && + unit->type != HEVC_NAL_SEI_SUFFIX) + return AVERROR(EINVAL); + *list = &sei->message_list; + } + break; + default: + return AVERROR(EINVAL); + } + + return 0; +} + +int ff_cbs_sei_add_message(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + int prefix, + uint32_t payload_type, + void *payload_data, + AVBufferRef *payload_buf) +{ + const SEIMessageTypeDescriptor *desc; + CodedBitstreamUnit *unit; + SEIRawMessageList *list; + SEIRawMessage *message; + AVBufferRef *payload_ref; + int err; + + desc = ff_cbs_sei_find_type(ctx, payload_type); + if (!desc) + return AVERROR(EINVAL); + + // Find an existing SEI unit or make a new one to add to. + err = cbs_sei_get_unit(ctx, au, prefix, &unit); + if (err < 0) + return err; + + // Find the message list inside the codec-dependent unit. + err = cbs_sei_get_message_list(ctx, unit, &list); + if (err < 0) + return err; + + // Add a new message to the message list. + err = ff_cbs_sei_list_add(list); + if (err < 0) + return err; + + if (payload_buf) { + payload_ref = av_buffer_ref(payload_buf); + if (!payload_ref) + return AVERROR(ENOMEM); + } else { + payload_ref = NULL; + } + + message = &list->messages[list->nb_messages - 1]; + + message->payload_type = payload_type; + message->payload = payload_data; + message->payload_ref = payload_ref; + + return 0; +} + +int ff_cbs_sei_find_message(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + uint32_t payload_type, + SEIRawMessage **iter) +{ + int err, i, j, found; + + found = 0; + for (i = 0; i < au->nb_units; i++) { + CodedBitstreamUnit *unit = &au->units[i]; + SEIRawMessageList *list; + + err = cbs_sei_get_message_list(ctx, unit, &list); + if (err < 0) + continue; + + for (j = 0; j < list->nb_messages; j++) { + SEIRawMessage *message = &list->messages[j]; + + if (message->payload_type == payload_type) { + if (!*iter || found) { + *iter = message; + return 0; + } + if (message == *iter) + found = 1; + } + } + } + + return AVERROR(ENOENT); +} + +static void cbs_sei_delete_message(SEIRawMessageList *list, + int position) +{ + SEIRawMessage *message; + + av_assert0(0 <= position && position < list->nb_messages); + + message = &list->messages[position]; + av_buffer_unref(&message->payload_ref); + av_buffer_unref(&message->extension_data_ref); + + --list->nb_messages; + + if (list->nb_messages > 0) { + memmove(list->messages + position, + list->messages + position + 1, + (list->nb_messages - position) * sizeof(*list->messages)); + } +} + +void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + uint32_t payload_type) +{ + int err, i, j; + + for (i = 0; i < au->nb_units; i++) { + CodedBitstreamUnit *unit = &au->units[i]; + SEIRawMessageList *list; + + err = cbs_sei_get_message_list(ctx, unit, &list); + if (err < 0) + continue; + + for (j = list->nb_messages - 1; j >= 0; j--) { + if (list->messages[j].payload_type == payload_type) + cbs_sei_delete_message(list, j); + } + } +} diff --git a/libavcodec/cbs_sei.h b/libavcodec/cbs_sei.h new file mode 100644 index 000000000..c7a7a95be --- /dev/null +++ b/libavcodec/cbs_sei.h @@ -0,0 +1,199 @@ +/* + * 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_CBS_SEI_H +#define AVCODEC_CBS_SEI_H + +#include +#include + +#include "libavutil/buffer.h" + +#include "cbs.h" +#include "sei.h" + + +typedef struct SEIRawFillerPayload { + uint32_t payload_size; +} SEIRawFillerPayload; + +typedef struct SEIRawUserDataRegistered { + uint8_t itu_t_t35_country_code; + uint8_t itu_t_t35_country_code_extension_byte; + uint8_t *data; + AVBufferRef *data_ref; + size_t data_length; +} SEIRawUserDataRegistered; + +typedef struct SEIRawUserDataUnregistered { + uint8_t uuid_iso_iec_11578[16]; + uint8_t *data; + AVBufferRef *data_ref; + size_t data_length; +} SEIRawUserDataUnregistered; + +typedef struct SEIRawMasteringDisplayColourVolume { + uint16_t display_primaries_x[3]; + uint16_t display_primaries_y[3]; + uint16_t white_point_x; + uint16_t white_point_y; + uint32_t max_display_mastering_luminance; + uint32_t min_display_mastering_luminance; +} SEIRawMasteringDisplayColourVolume; + +typedef struct SEIRawContentLightLevelInfo { + uint16_t max_content_light_level; + uint16_t max_pic_average_light_level; +} SEIRawContentLightLevelInfo; + +typedef struct SEIRawAlternativeTransferCharacteristics { + uint8_t preferred_transfer_characteristics; +} SEIRawAlternativeTransferCharacteristics; + +typedef struct SEIRawMessage { + uint32_t payload_type; + uint32_t payload_size; + void *payload; + AVBufferRef *payload_ref; + uint8_t *extension_data; + AVBufferRef *extension_data_ref; + size_t extension_bit_length; +} SEIRawMessage; + +typedef struct SEIRawMessageList { + SEIRawMessage *messages; + int nb_messages; + int nb_messages_allocated; +} SEIRawMessageList; + + +typedef struct SEIMessageState { + // The type of the payload being written. + uint32_t payload_type; + // When reading, contains the size of the payload to allow finding the + // end of variable-length fields (such as user_data_payload_byte[]). + // (When writing, the size will be derived from the total number of + // bytes actually written.) + uint32_t payload_size; + // When writing, indicates that payload extension data is present so + // all extended fields must be written. May be updated by the writer + // to indicate that extended fields have been written, so the extension + // end bits must be written too. + uint8_t extension_present; +} SEIMessageState; + +struct GetBitContext; +struct PutBitContext; + +typedef int (*SEIMessageReadFunction)(CodedBitstreamContext *ctx, + struct GetBitContext *rw, + void *current, + SEIMessageState *sei); + +typedef int (*SEIMessageWriteFunction)(CodedBitstreamContext *ctx, + struct PutBitContext *rw, + void *current, + SEIMessageState *sei); + +typedef struct SEIMessageTypeDescriptor { + // Payload type for the message. (-1 in this field ends a list.) + int type; + // Valid in a prefix SEI NAL unit (always for H.264). + uint8_t prefix; + // Valid in a suffix SEI NAL unit (never for H.264). + uint8_t suffix; + // Size of the decomposed structure. + size_t size; + // Read bitstream into SEI message. + SEIMessageReadFunction read; + // Write bitstream from SEI message. + SEIMessageWriteFunction write; +} SEIMessageTypeDescriptor; + +// Macro for the read/write pair. The clumsy cast is needed because the +// current pointer is typed in all of the read/write functions but has to +// be void here to fit all cases. +#define SEI_MESSAGE_RW(codec, name) \ + .read = (SEIMessageReadFunction) cbs_ ## codec ## _read_ ## name, \ + .write = (SEIMessageWriteFunction)cbs_ ## codec ## _write_ ## name + +// End-of-list sentinel element. +#define SEI_MESSAGE_TYPE_END { .type = -1 } + + +/** + * Find the type descriptor for the given payload type. + * + * Returns NULL if the payload type is not known. + */ +const SEIMessageTypeDescriptor *ff_cbs_sei_find_type(CodedBitstreamContext *ctx, + int payload_type); + +/** + * Allocate a new payload for the given SEI message. + */ +int ff_cbs_sei_alloc_message_payload(SEIRawMessage *message, + const SEIMessageTypeDescriptor *desc); + +/** + * Allocate a new empty SEI message in a message list. + * + * The new message is in place nb_messages - 1. + */ +int ff_cbs_sei_list_add(SEIRawMessageList *list); + +/** + * Free all SEI messages in a message list. + */ +void ff_cbs_sei_free_message_list(SEIRawMessageList *list); + +/** + * Add an SEI message to an access unit. + * + * Will add to an existing SEI NAL unit, or create a new one for the + * message if there is no suitable existing one. + * + * Takes a new reference to payload_buf, if set. If payload_buf is + * NULL then the new message will not be reference counted. + */ +int ff_cbs_sei_add_message(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + int prefix, + uint32_t payload_type, + void *payload_data, + AVBufferRef *payload_buf); + +/** + * Iterate over messages with the given payload type in an access unit. + * + * Set message to NULL in the first call. Returns 0 while more messages + * are available, AVERROR(ENOENT) when all messages have been found. + */ +int ff_cbs_sei_find_message(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + uint32_t payload_type, + SEIRawMessage **message); + +/** + * Delete all messages with the given payload type from an access unit. + */ +void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + uint32_t payload_type); + +#endif /* AVCODEC_CBS_SEI_H */ diff --git a/libavcodec/cbs_sei_syntax_template.c b/libavcodec/cbs_sei_syntax_template.c new file mode 100644 index 000000000..0ef7b42ed --- /dev/null +++ b/libavcodec/cbs_sei_syntax_template.c @@ -0,0 +1,322 @@ +/* + * 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 + */ + +static int FUNC(filler_payload) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawFillerPayload *current, SEIMessageState *state) +{ + int err, i; + + HEADER("Filler Payload"); + +#ifdef READ + current->payload_size = state->payload_size; +#endif + + for (i = 0; i < current->payload_size; i++) + fixed(8, ff_byte, 0xff); + + return 0; +} + +static int FUNC(user_data_registered) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawUserDataRegistered *current, SEIMessageState *state) +{ + int err, i, j; + + HEADER("User Data Registered ITU-T T.35"); + + u(8, itu_t_t35_country_code, 0x00, 0xff); + if (current->itu_t_t35_country_code != 0xff) + i = 1; + else { + u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); + i = 2; + } + +#ifdef READ + if (state->payload_size < i) { + av_log(ctx->log_ctx, AV_LOG_ERROR, + "Invalid SEI user data registered payload.\n"); + return AVERROR_INVALIDDATA; + } + current->data_length = state->payload_size - i; +#endif + + allocate(current->data, current->data_length); + for (j = 0; j < current->data_length; j++) + xu(8, itu_t_t35_payload_byte[], current->data[j], 0x00, 0xff, 1, i + j); + + return 0; +} + +static int FUNC(user_data_unregistered) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawUserDataUnregistered *current, SEIMessageState *state) +{ + int err, i; + + HEADER("User Data Unregistered"); + +#ifdef READ + if (state->payload_size < 16) { + av_log(ctx->log_ctx, AV_LOG_ERROR, + "Invalid SEI user data unregistered payload.\n"); + return AVERROR_INVALIDDATA; + } + current->data_length = state->payload_size - 16; +#endif + + for (i = 0; i < 16; i++) + us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); + + allocate(current->data, current->data_length); + + for (i = 0; i < current->data_length; i++) + xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); + + return 0; +} + +static int FUNC(mastering_display_colour_volume) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawMasteringDisplayColourVolume *current, SEIMessageState *state) +{ + int err, c; + + HEADER("Mastering Display Colour Volume"); + + for (c = 0; c < 3; c++) { + ubs(16, display_primaries_x[c], 1, c); + ubs(16, display_primaries_y[c], 1, c); + } + + ub(16, white_point_x); + ub(16, white_point_y); + + ub(32, max_display_mastering_luminance); + ub(32, min_display_mastering_luminance); + + return 0; +} + +static int FUNC(content_light_level_info) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawContentLightLevelInfo *current, SEIMessageState *state) +{ + int err; + + HEADER("Content Light Level Information"); + + ub(16, max_content_light_level); + ub(16, max_pic_average_light_level); + + return 0; +} + +static int FUNC(alternative_transfer_characteristics) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawAlternativeTransferCharacteristics *current, + SEIMessageState *state) +{ + int err; + + HEADER("Alternative Transfer Characteristics"); + + ub(8, preferred_transfer_characteristics); + + return 0; +} + +static int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw, + SEIRawMessage *current) +{ + const SEIMessageTypeDescriptor *desc; + int err, i; + + desc = ff_cbs_sei_find_type(ctx, current->payload_type); + if (desc) { + SEIMessageState state = { + .payload_type = current->payload_type, + .payload_size = current->payload_size, + .extension_present = current->extension_bit_length > 0, + }; + int start_position, current_position, bits_written; + +#ifdef READ + CHECK(ff_cbs_sei_alloc_message_payload(current, desc)); +#endif + + start_position = bit_position(rw); + + CHECK(desc->READWRITE(ctx, rw, current->payload, &state)); + + current_position = bit_position(rw); + bits_written = current_position - start_position; + + if (byte_alignment(rw) || state.extension_present || + bits_written < 8 * current->payload_size) { + size_t bits_left; + +#ifdef READ + GetBitContext tmp = *rw; + int trailing_bits, trailing_zero_bits; + + bits_left = 8 * current->payload_size - bits_written; + if (bits_left > 8) + skip_bits_long(&tmp, bits_left - 8); + trailing_bits = get_bits(&tmp, FFMIN(bits_left, 8)); + if (trailing_bits == 0) { + // The trailing bits must contain a bit_equal_to_one, so + // they can't all be zero. + return AVERROR_INVALIDDATA; + } + trailing_zero_bits = ff_ctz(trailing_bits); + current->extension_bit_length = + bits_left - 1 - trailing_zero_bits; +#endif + + if (current->extension_bit_length > 0) { + allocate(current->extension_data, + (current->extension_bit_length + 7) / 8); + + bits_left = current->extension_bit_length; + for (i = 0; bits_left > 0; i++) { + int length = FFMIN(bits_left, 8); + xu(length, reserved_payload_extension_data, + current->extension_data[i], + 0, MAX_UINT_BITS(length), 0); + bits_left -= length; + } + } + + fixed(1, bit_equal_to_one, 1); + while (byte_alignment(rw)) + fixed(1, bit_equal_to_zero, 0); + } + +#ifdef WRITE + current->payload_size = (put_bits_count(rw) - start_position) / 8; +#endif + } else { + uint8_t *data; + + allocate(current->payload, current->payload_size); + data = current->payload; + + for (i = 0; i < current->payload_size; i++) + xu(8, payload_byte[i], data[i], 0, 255, 1, i); + } + + return 0; +} + +static int FUNC(message_list)(CodedBitstreamContext *ctx, RWContext *rw, + SEIRawMessageList *current, int prefix) +{ + SEIRawMessage *message; + int err, k; + +#ifdef READ + for (k = 0;; k++) { + uint32_t payload_type = 0; + uint32_t payload_size = 0; + uint32_t tmp; + GetBitContext payload_gbc; + + while (show_bits(rw, 8) == 0xff) { + fixed(8, ff_byte, 0xff); + payload_type += 255; + } + xu(8, last_payload_type_byte, tmp, 0, 254, 0); + payload_type += tmp; + + while (show_bits(rw, 8) == 0xff) { + fixed(8, ff_byte, 0xff); + payload_size += 255; + } + xu(8, last_payload_size_byte, tmp, 0, 254, 0); + payload_size += tmp; + + // There must be space remaining for both the payload and + // the trailing bits on the SEI NAL unit. + if (payload_size + 1 > get_bits_left(rw) / 8) { + av_log(ctx->log_ctx, AV_LOG_ERROR, + "Invalid SEI message: payload_size too large " + "(%"PRIu32" bytes).\n", payload_size); + return AVERROR_INVALIDDATA; + } + CHECK(init_get_bits(&payload_gbc, rw->buffer, + get_bits_count(rw) + 8 * payload_size)); + skip_bits_long(&payload_gbc, get_bits_count(rw)); + + CHECK(ff_cbs_sei_list_add(current)); + message = ¤t->messages[k]; + + message->payload_type = payload_type; + message->payload_size = payload_size; + + CHECK(FUNC(message)(ctx, &payload_gbc, message)); + + skip_bits_long(rw, 8 * payload_size); + + if (!cbs_h2645_read_more_rbsp_data(rw)) + break; + } +#else + for (k = 0; k < current->nb_messages; k++) { + PutBitContext start_state; + uint32_t tmp; + int trace, i; + + message = ¤t->messages[k]; + + // We write the payload twice in order to find the size. Trace + // output is switched off for the first write. + trace = ctx->trace_enable; + ctx->trace_enable = 0; + + start_state = *rw; + for (i = 0; i < 2; i++) { + *rw = start_state; + + tmp = message->payload_type; + while (tmp >= 255) { + fixed(8, ff_byte, 0xff); + tmp -= 255; + } + xu(8, last_payload_type_byte, tmp, 0, 254, 0); + + tmp = message->payload_size; + while (tmp >= 255) { + fixed(8, ff_byte, 0xff); + tmp -= 255; + } + xu(8, last_payload_size_byte, tmp, 0, 254, 0); + + err = FUNC(message)(ctx, rw, message); + ctx->trace_enable = trace; + if (err < 0) + return err; + } + } +#endif + + return 0; +} diff --git a/libavcodec/cbs_vp9.c b/libavcodec/cbs_vp9.c index eef603bfb..e0b8c02ac 100644 --- a/libavcodec/cbs_vp9.c +++ b/libavcodec/cbs_vp9.c @@ -451,7 +451,7 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, return AVERROR_INVALIDDATA; } - err = ff_cbs_insert_unit_data(ctx, frag, -1, 0, + err = ff_cbs_insert_unit_data(frag, -1, 0, frag->data + pos, sfi.frame_sizes[i], frag->data_ref); @@ -469,7 +469,7 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, return 0; } else { - err = ff_cbs_insert_unit_data(ctx, frag, -1, 0, + err = ff_cbs_insert_unit_data(frag, -1, 0, frag->data, frag->data_size, frag->data_ref); if (err < 0) @@ -479,13 +479,6 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, return 0; } -static void cbs_vp9_free_frame(void *opaque, uint8_t *content) -{ - VP9RawFrame *frame = (VP9RawFrame*)content; - av_buffer_unref(&frame->data_ref); - av_freep(&frame); -} - static int cbs_vp9_read_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit) { @@ -497,8 +490,7 @@ static int cbs_vp9_read_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*frame), - &cbs_vp9_free_frame); + err = ff_cbs_alloc_unit_content2(ctx, unit); if (err < 0) return err; frame = unit->content; @@ -642,13 +634,30 @@ static int cbs_vp9_assemble_fragment(CodedBitstreamContext *ctx, return 0; } +static void cbs_vp9_flush(CodedBitstreamContext *ctx) +{ + CodedBitstreamVP9Context *vp9 = ctx->priv_data; + + memset(vp9->ref, 0, sizeof(vp9->ref)); +} + +static const CodedBitstreamUnitTypeDescriptor cbs_vp9_unit_types[] = { + CBS_UNIT_TYPE_INTERNAL_REF(0, VP9RawFrame, data), + CBS_UNIT_TYPE_END_OF_LIST +}; + const CodedBitstreamType ff_cbs_type_vp9 = { .codec_id = AV_CODEC_ID_VP9, .priv_data_size = sizeof(CodedBitstreamVP9Context), + .unit_types = cbs_vp9_unit_types, + .split_fragment = &cbs_vp9_split_fragment, .read_unit = &cbs_vp9_read_unit, .write_unit = &cbs_vp9_write_unit, + + .flush = &cbs_vp9_flush, + .assemble_fragment = &cbs_vp9_assemble_fragment, }; diff --git a/libavcodec/cbs_vp9.h b/libavcodec/cbs_vp9.h index 40e62476e..af15eb4ba 100644 --- a/libavcodec/cbs_vp9.h +++ b/libavcodec/cbs_vp9.h @@ -165,8 +165,8 @@ typedef struct VP9RawFrame { VP9RawFrameHeader header; uint8_t *data; - size_t data_size; AVBufferRef *data_ref; + size_t data_size; } VP9RawFrame; typedef struct VP9RawSuperframeIndex { diff --git a/libavcodec/ccaption_dec.c b/libavcodec/ccaption_dec.c index bf3563a0b..a208e19b9 100644 --- a/libavcodec/ccaption_dec.c +++ b/libavcodec/ccaption_dec.c @@ -32,10 +32,6 @@ static const AVRational ms_tb = {1, 1000}; -/* - * TODO list - * 1) handle font and color completely - */ enum cc_mode { CCMODE_POPON, CCMODE_PAINTON, @@ -173,6 +169,18 @@ static const char *charset_overrides[4][128] = }, }; +static const unsigned char bg_attribs[8] = // Color +{ + CCCOL_WHITE, + CCCOL_GREEN, + CCCOL_BLUE, + CCCOL_CYAN, + CCCOL_RED, + CCCOL_YELLOW, + CCCOL_MAGENTA, + CCCOL_BLACK, +}; + static const unsigned char pac2_attribs[32][3] = // Color, font, ident { { CCCOL_WHITE, CCFONT_REGULAR, 0 }, // 0x40 || 0x60 @@ -215,6 +223,7 @@ struct Screen { uint8_t characters[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; uint8_t charsets[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; uint8_t colors[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; + uint8_t bgs[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; uint8_t fonts[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; /* * Bitmask of used rows; if a bit is not set, the @@ -228,39 +237,37 @@ struct Screen { typedef struct CCaptionSubContext { AVClass *class; int real_time; + int data_field; struct Screen screen[2]; int active_screen; uint8_t cursor_row; uint8_t cursor_column; uint8_t cursor_color; + uint8_t bg_color; uint8_t cursor_font; uint8_t cursor_charset; - AVBPrint buffer; + AVBPrint buffer[2]; + int buffer_index; int buffer_changed; int rollup; enum cc_mode mode; - int64_t start_time; - /* visible screen time */ - int64_t startv_time; - int64_t end_time; + int64_t buffer_time[2]; int screen_touched; int64_t last_real_time; - char prev_cmd[2]; - /* buffer to store pkt data */ - uint8_t *pktbuf; - int pktbuf_size; + uint8_t prev_cmd[2]; int readorder; } CCaptionSubContext; - static av_cold int init_decoder(AVCodecContext *avctx) { int ret; CCaptionSubContext *ctx = avctx->priv_data; - av_bprint_init(&ctx->buffer, 0, AV_BPRINT_SIZE_UNLIMITED); + av_bprint_init(&ctx->buffer[0], 0, AV_BPRINT_SIZE_UNLIMITED); + av_bprint_init(&ctx->buffer[1], 0, AV_BPRINT_SIZE_UNLIMITED); /* taking by default roll up to 2 */ ctx->mode = CCMODE_ROLLUP; + ctx->bg_color = CCCOL_BLACK; ctx->rollup = 2; ctx->cursor_row = 10; ret = ff_ass_subtitle_header(avctx, "Monospace", @@ -282,9 +289,8 @@ static av_cold int init_decoder(AVCodecContext *avctx) static av_cold int close_decoder(AVCodecContext *avctx) { CCaptionSubContext *ctx = avctx->priv_data; - av_bprint_finalize(&ctx->buffer, NULL); - av_freep(&ctx->pktbuf); - ctx->pktbuf_size = 0; + av_bprint_finalize(&ctx->buffer[0], NULL); + av_bprint_finalize(&ctx->buffer[1], NULL); return 0; } @@ -301,6 +307,7 @@ static void flush_decoder(AVCodecContext *avctx) ctx->cursor_column = 0; ctx->cursor_font = 0; ctx->cursor_color = 0; + ctx->bg_color = CCCOL_BLACK; ctx->cursor_charset = 0; ctx->active_screen = 0; ctx->last_real_time = 0; @@ -308,7 +315,8 @@ static void flush_decoder(AVCodecContext *avctx) ctx->buffer_changed = 0; if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP)) ctx->readorder = 0; - av_bprint_clear(&ctx->buffer); + av_bprint_clear(&ctx->buffer[0]); + av_bprint_clear(&ctx->buffer[1]); } /** @@ -319,11 +327,15 @@ static void write_char(CCaptionSubContext *ctx, struct Screen *screen, char ch) uint8_t col = ctx->cursor_column; char *row = screen->characters[ctx->cursor_row]; char *font = screen->fonts[ctx->cursor_row]; + char *color = screen->colors[ctx->cursor_row]; + char *bg = screen->bgs[ctx->cursor_row]; char *charset = screen->charsets[ctx->cursor_row]; if (col < SCREEN_COLUMNS) { row[col] = ch; font[col] = ctx->cursor_font; + color[col] = ctx->cursor_color; + bg[col] = ctx->bg_color; charset[col] = ctx->cursor_charset; ctx->cursor_charset = CCSET_BASIC_AMERICAN; if (ch) ctx->cursor_column++; @@ -347,11 +359,13 @@ static void write_char(CCaptionSubContext *ctx, struct Screen *screen, char ch) * If the second byte doesn't pass parity, it returns INVALIDDATA * user can ignore the whole pair and pass the other pair. */ -static int validate_cc_data_pair(uint8_t *cc_data_pair) +static int validate_cc_data_pair(const uint8_t *cc_data_pair, uint8_t *hi) { uint8_t cc_valid = (*cc_data_pair & 4) >>2; uint8_t cc_type = *cc_data_pair & 3; + *hi = cc_data_pair[1]; + if (!cc_valid) return AVERROR_INVALIDDATA; @@ -361,7 +375,7 @@ static int validate_cc_data_pair(uint8_t *cc_data_pair) return AVERROR_INVALIDDATA; } if (!av_parity(cc_data_pair[1])) { - cc_data_pair[1]=0x7F; + *hi = 0x7F; } } @@ -374,10 +388,6 @@ static int validate_cc_data_pair(uint8_t *cc_data_pair) if (cc_type == 3 || cc_type == 2) return AVERROR_PATCHWELCOME; - /* remove parity bit */ - cc_data_pair[1] &= 0x7F; - cc_data_pair[2] &= 0x7F; - return 0; } @@ -423,6 +433,7 @@ static void roll_up(CCaptionSubContext *ctx) memcpy(screen->characters[i_row], screen->characters[i_row+1], SCREEN_COLUMNS); memcpy(screen->colors[i_row], screen->colors[i_row+1], SCREEN_COLUMNS); + memcpy(screen->bgs[i_row], screen->bgs[i_row+1], SCREEN_COLUMNS); memcpy(screen->fonts[i_row], screen->fonts[i_row+1], SCREEN_COLUMNS); memcpy(screen->charsets[i_row], screen->charsets[i_row+1], SCREEN_COLUMNS); if (CHECK_FLAG(screen->row_used, i_row + 1)) @@ -437,7 +448,11 @@ static int capture_screen(CCaptionSubContext *ctx) int i, j, tab = 0; struct Screen *screen = ctx->screen + ctx->active_screen; enum cc_font prev_font = CCFONT_REGULAR; - av_bprint_clear(&ctx->buffer); + enum cc_color_code prev_color = CCCOL_WHITE; + enum cc_color_code prev_bg_color = CCCOL_BLACK; + const int bidx = ctx->buffer_index; + + av_bprint_clear(&ctx->buffer[bidx]); for (i = 0; screen->row_used && i < SCREEN_ROWS; i++) { @@ -457,6 +472,8 @@ static int capture_screen(CCaptionSubContext *ctx) if (CHECK_FLAG(screen->row_used, i)) { const char *row = screen->characters[i]; const char *font = screen->fonts[i]; + const char *bg = screen->bgs[i]; + const char *color = screen->colors[i]; const char *charset = screen->charsets[i]; const char *override; int x, y, seen_char = 0; @@ -468,10 +485,10 @@ static int capture_screen(CCaptionSubContext *ctx) x = ASS_DEFAULT_PLAYRESX * (0.1 + 0.0250 * j); y = ASS_DEFAULT_PLAYRESY * (0.1 + 0.0533 * i); - av_bprintf(&ctx->buffer, "{\\an7}{\\pos(%d,%d)}", x, y); + av_bprintf(&ctx->buffer[bidx], "{\\an7}{\\pos(%d,%d)}", x, y); for (; j < SCREEN_COLUMNS; j++) { - const char *e_tag = "", *s_tag = ""; + const char *e_tag = "", *s_tag = "", *c_tag = "", *b_tag = ""; if (row[j] == 0) break; @@ -500,38 +517,99 @@ static int capture_screen(CCaptionSubContext *ctx) break; } } + if (prev_color != color[j]) { + switch (color[j]) { + case CCCOL_WHITE: + c_tag = "{\\c&HFFFFFF&}"; + break; + case CCCOL_GREEN: + c_tag = "{\\c&H00FF00&}"; + break; + case CCCOL_BLUE: + c_tag = "{\\c&HFF0000&}"; + break; + case CCCOL_CYAN: + c_tag = "{\\c&HFFFF00&}"; + break; + case CCCOL_RED: + c_tag = "{\\c&H0000FF&}"; + break; + case CCCOL_YELLOW: + c_tag = "{\\c&H00FFFF&}"; + break; + case CCCOL_MAGENTA: + c_tag = "{\\c&HFF00FF&}"; + break; + } + } + if (prev_bg_color != bg[j]) { + switch (bg[j]) { + case CCCOL_WHITE: + b_tag = "{\\3c&HFFFFFF&}"; + break; + case CCCOL_GREEN: + b_tag = "{\\3c&H00FF00&}"; + break; + case CCCOL_BLUE: + b_tag = "{\\3c&HFF0000&}"; + break; + case CCCOL_CYAN: + b_tag = "{\\3c&HFFFF00&}"; + break; + case CCCOL_RED: + b_tag = "{\\3c&H0000FF&}"; + break; + case CCCOL_YELLOW: + b_tag = "{\\3c&H00FFFF&}"; + break; + case CCCOL_MAGENTA: + b_tag = "{\\3c&HFF00FF&}"; + break; + case CCCOL_BLACK: + b_tag = "{\\3c&H000000&}"; + break; + } + } + prev_font = font[j]; + prev_color = color[j]; + prev_bg_color = bg[j]; override = charset_overrides[(int)charset[j]][(int)row[j]]; if (override) { - av_bprintf(&ctx->buffer, "%s%s%s", e_tag, s_tag, override); + av_bprintf(&ctx->buffer[bidx], "%s%s%s%s%s", e_tag, s_tag, c_tag, b_tag, override); seen_char = 1; } else if (row[j] == ' ' && !seen_char) { - av_bprintf(&ctx->buffer, "%s%s\\h", e_tag, s_tag); + av_bprintf(&ctx->buffer[bidx], "%s%s%s%s\\h", e_tag, s_tag, c_tag, b_tag); } else { - av_bprintf(&ctx->buffer, "%s%s%c", e_tag, s_tag, row[j]); + av_bprintf(&ctx->buffer[bidx], "%s%s%s%s%c", e_tag, s_tag, c_tag, b_tag, row[j]); seen_char = 1; } } - av_bprintf(&ctx->buffer, "\\N"); + av_bprintf(&ctx->buffer[bidx], "\\N"); } } - if (!av_bprint_is_complete(&ctx->buffer)) + if (!av_bprint_is_complete(&ctx->buffer[bidx])) return AVERROR(ENOMEM); - if (screen->row_used && ctx->buffer.len >= 2) { - ctx->buffer.len -= 2; - ctx->buffer.str[ctx->buffer.len] = 0; + if (screen->row_used && ctx->buffer[bidx].len >= 2) { + ctx->buffer[bidx].len -= 2; + ctx->buffer[bidx].str[ctx->buffer[bidx].len] = 0; } ctx->buffer_changed = 1; return 0; } -static int reap_screen(CCaptionSubContext *ctx, int64_t pts) +static void update_time(CCaptionSubContext *ctx, int64_t pts) { - ctx->start_time = ctx->startv_time; - ctx->startv_time = pts; - ctx->end_time = pts; - return capture_screen(ctx); + ctx->buffer_time[0] = ctx->buffer_time[1]; + ctx->buffer_time[1] = pts; +} + +static void handle_bgattr(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) +{ + const int i = (lo & 0xf) >> 1; + + ctx->bg_color = bg_attribs[i]; } static void handle_textattr(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) @@ -576,49 +654,55 @@ static void handle_pac(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) } } -/** - * @param pts it is required to set end time - */ -static void handle_edm(CCaptionSubContext *ctx, int64_t pts) +static int handle_edm(CCaptionSubContext *ctx) { struct Screen *screen = ctx->screen + ctx->active_screen; + int ret; // In buffered mode, keep writing to screen until it is wiped. // Before wiping the display, capture contents to emit subtitle. if (!ctx->real_time) - reap_screen(ctx, pts); + ret = capture_screen(ctx); screen->row_used = 0; + ctx->bg_color = CCCOL_BLACK; // In realtime mode, emit an empty caption so the last one doesn't // stay on the screen. if (ctx->real_time) - reap_screen(ctx, pts); + ret = capture_screen(ctx); + + return ret; } -static void handle_eoc(CCaptionSubContext *ctx, int64_t pts) +static int handle_eoc(CCaptionSubContext *ctx) { - // In buffered mode, we wait til the *next* EOC and - // reap what was already on the screen since the last EOC. - if (!ctx->real_time) - handle_edm(ctx,pts); + int ret; ctx->active_screen = !ctx->active_screen; + + // In buffered mode, we wait til the *next* EOC and + // capture what was already on the screen since the last EOC. + if (!ctx->real_time) + ret = handle_edm(ctx); + ctx->cursor_column = 0; // In realtime mode, we display the buffered contents (after // flipping the buffer to active above) as soon as EOC arrives. if (ctx->real_time) - reap_screen(ctx, pts); + ret = capture_screen(ctx); + + return ret; } -static void handle_delete_end_of_row(CCaptionSubContext *ctx, char hi, char lo) +static void handle_delete_end_of_row(CCaptionSubContext *ctx) { struct Screen *screen = get_writing_screen(ctx); write_char(ctx, screen, 0); } -static void handle_char(CCaptionSubContext *ctx, char hi, char lo, int64_t pts) +static void handle_char(CCaptionSubContext *ctx, char hi, char lo) { struct Screen *screen = get_writing_screen(ctx); @@ -658,11 +742,12 @@ static void handle_char(CCaptionSubContext *ctx, char hi, char lo, int64_t pts) ff_dlog(ctx, "(%c)\n", hi); } -static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint8_t lo) +static int process_cc608(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) { + int ret = 0; + if (hi == ctx->prev_cmd[0] && lo == ctx->prev_cmd[1]) { - /* ignore redundant command */ - return; + return 0; } /* set prev command */ @@ -675,6 +760,8 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint } else if ( ( hi == 0x11 && lo >= 0x20 && lo <= 0x2f ) || ( hi == 0x17 && lo >= 0x2e && lo <= 0x2f) ) { handle_textattr(ctx, hi, lo); + } else if ((hi == 0x10 && lo >= 0x20 && lo <= 0x2f)) { + handle_bgattr(ctx, hi, lo); } else if (hi == 0x14 || hi == 0x15 || hi == 0x1c) { switch (lo) { case 0x20: @@ -682,7 +769,7 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint ctx->mode = CCMODE_POPON; break; case 0x24: - handle_delete_end_of_row(ctx, hi, lo); + handle_delete_end_of_row(ctx); break; case 0x25: case 0x26: @@ -700,13 +787,13 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint break; case 0x2c: /* erase display memory */ - handle_edm(ctx, pts); + handle_edm(ctx); break; case 0x2d: /* carriage return */ ff_dlog(ctx, "carriage return\n"); if (!ctx->real_time) - reap_screen(ctx, pts); + ret = capture_screen(ctx); roll_up(ctx); ctx->cursor_column = 0; break; @@ -722,7 +809,7 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint case 0x2f: /* end of caption */ ff_dlog(ctx, "handle_eoc\n"); - handle_eoc(ctx, pts); + ret = handle_eoc(ctx); break; default: ff_dlog(ctx, "Unknown command 0x%hhx 0x%hhx\n", hi, lo); @@ -730,73 +817,93 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint } } else if (hi >= 0x11 && hi <= 0x13) { /* Special characters */ - handle_char(ctx, hi, lo, pts); + handle_char(ctx, hi, lo); } else if (hi >= 0x20) { /* Standard characters (always in pairs) */ - handle_char(ctx, hi, lo, pts); + handle_char(ctx, hi, lo); ctx->prev_cmd[0] = ctx->prev_cmd[1] = 0; } else if (hi == 0x17 && lo >= 0x21 && lo <= 0x23) { int i; /* Tab offsets (spacing) */ for (i = 0; i < lo - 0x20; i++) { - handle_char(ctx, ' ', 0, pts); + handle_char(ctx, ' ', 0); } } else { /* Ignoring all other non data code */ ff_dlog(ctx, "Unknown command 0x%hhx 0x%hhx\n", hi, lo); } + + return ret; } static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt) { CCaptionSubContext *ctx = avctx->priv_data; AVSubtitle *sub = data; - const int64_t start_time = sub->pts; - uint8_t *bptr = NULL; + int64_t in_time = sub->pts; + int64_t start_time; + int64_t end_time; + int bidx = ctx->buffer_index; + const uint8_t *bptr = avpkt->data; int len = avpkt->size; int ret = 0; int i; - av_fast_padded_malloc(&ctx->pktbuf, &ctx->pktbuf_size, len); - if (!ctx->pktbuf) { - av_log(ctx, AV_LOG_WARNING, "Insufficient Memory of %d truncated to %d\n", len, ctx->pktbuf_size); - return AVERROR(ENOMEM); - } - memcpy(ctx->pktbuf, avpkt->data, len); - bptr = ctx->pktbuf; + for (i = 0; i < len; i += 3) { + uint8_t hi, cc_type = bptr[i] & 1; - for (i = 0; i < len; i += 3) { - uint8_t cc_type = *(bptr + i) & 3; - if (validate_cc_data_pair(bptr + i)) + if (ctx->data_field < 0) + ctx->data_field = cc_type; + + if (validate_cc_data_pair(bptr + i, &hi)) continue; - /* ignoring data field 1 */ - if(cc_type == 1) + + if (cc_type != ctx->data_field) continue; - else - process_cc608(ctx, start_time, *(bptr + i + 1) & 0x7f, *(bptr + i + 2) & 0x7f); + + ret = process_cc608(ctx, hi & 0x7f, bptr[i + 2] & 0x7f); + if (ret < 0) + return ret; if (!ctx->buffer_changed) continue; ctx->buffer_changed = 0; - if (*ctx->buffer.str || ctx->real_time) - { - ff_dlog(ctx, "cdp writing data (%s)\n",ctx->buffer.str); - ret = ff_ass_add_rect(sub, ctx->buffer.str, ctx->readorder++, 0, NULL, NULL); - if (ret < 0) - return ret; - sub->pts = ctx->start_time; + if (!ctx->real_time && ctx->mode == CCMODE_POPON) + ctx->buffer_index = bidx = !ctx->buffer_index; + + update_time(ctx, in_time); + + if (ctx->buffer[bidx].str[0] || ctx->real_time) { + ff_dlog(ctx, "cdp writing data (%s)\n", ctx->buffer[bidx].str); + start_time = ctx->buffer_time[0]; + sub->pts = start_time; + end_time = ctx->buffer_time[1]; if (!ctx->real_time) - sub->end_display_time = av_rescale_q(ctx->end_time - ctx->start_time, + sub->end_display_time = av_rescale_q(end_time - start_time, AV_TIME_BASE_Q, ms_tb); else sub->end_display_time = -1; - ctx->buffer_changed = 0; + ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL); + if (ret < 0) + return ret; ctx->last_real_time = sub->pts; ctx->screen_touched = 0; } } + if (!bptr && !ctx->real_time && ctx->buffer[!ctx->buffer_index].str[0]) { + bidx = !ctx->buffer_index; + ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL); + if (ret < 0) + return ret; + sub->pts = ctx->buffer_time[1]; + sub->end_display_time = av_rescale_q(ctx->buffer_time[1] - ctx->buffer_time[0], + AV_TIME_BASE_Q, ms_tb); + if (sub->end_display_time == 0) + sub->end_display_time = ctx->buffer[bidx].len * 20; + } + if (ctx->real_time && ctx->screen_touched && sub->pts > ctx->last_real_time + av_rescale_q(200, ms_tb, AV_TIME_BASE_Q)) { ctx->last_real_time = sub->pts; @@ -805,7 +912,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp capture_screen(ctx); ctx->buffer_changed = 0; - ret = ff_ass_add_rect(sub, ctx->buffer.str, ctx->readorder++, 0, NULL, NULL); + ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL); if (ret < 0) return ret; sub->end_display_time = -1; @@ -819,6 +926,10 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { { "real_time", "emit subtitle events as they are decoded for real-time display", OFFSET(real_time), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, SD }, + { "data_field", "select data field", OFFSET(data_field), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, SD, "data_field" }, + { "auto", "pick first one that appears", 0, AV_OPT_TYPE_CONST, { .i64 =-1 }, 0, 0, SD, "data_field" }, + { "first", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, SD, "data_field" }, + { "second", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, SD, "data_field" }, {NULL} }; @@ -840,4 +951,5 @@ AVCodec ff_ccaption_decoder = { .flush = flush_decoder, .decode = decode, .priv_class = &ccaption_dec_class, + .capabilities = AV_CODEC_CAP_DELAY, }; diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index 469128964..263459d0f 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -365,6 +365,18 @@ static int cdg_decode_frame(AVCodecContext *avctx, return avpkt->size; } +static void cdg_decode_flush(AVCodecContext *avctx) +{ + CDGraphicsContext *cc = avctx->priv_data; + + if (!cc->frame->data[0]) + return; + + memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height); + if (!avctx->frame_number) + memset(cc->frame->data[1], 0, AVPALETTE_SIZE); +} + static av_cold int cdg_decode_end(AVCodecContext *avctx) { CDGraphicsContext *cc = avctx->priv_data; @@ -383,5 +395,6 @@ AVCodec ff_cdgraphics_decoder = { .init = cdg_decode_init, .close = cdg_decode_end, .decode = cdg_decode_frame, + .flush = cdg_decode_flush, .capabilities = AV_CODEC_CAP_DR1, }; diff --git a/libavcodec/cdtoons.c b/libavcodec/cdtoons.c index a8609815c..3530f8145 100644 --- a/libavcodec/cdtoons.c +++ b/libavcodec/cdtoons.c @@ -453,4 +453,5 @@ AVCodec ff_cdtoons_decoder = { .decode = cdtoons_decode_frame, .capabilities = AV_CODEC_CAP_DR1, .flush = cdtoons_flush, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c index 78f5d5010..056c3577a 100644 --- a/libavcodec/cdxl.c +++ b/libavcodec/cdxl.c @@ -43,6 +43,7 @@ typedef struct CDXLVideoContext { AVCodecContext *avctx; int bpp; + int type; int format; int padded_bits; const uint8_t *palette; @@ -65,14 +66,19 @@ static av_cold int cdxl_decode_init(AVCodecContext *avctx) static void import_palette(CDXLVideoContext *c, uint32_t *new_palette) { - int i; - - for (i = 0; i < c->palette_size / 2; i++) { - unsigned rgb = AV_RB16(&c->palette[i * 2]); - unsigned r = ((rgb >> 8) & 0xF) * 0x11; - unsigned g = ((rgb >> 4) & 0xF) * 0x11; - unsigned b = (rgb & 0xF) * 0x11; - AV_WN32(&new_palette[i], (0xFFU << 24) | (r << 16) | (g << 8) | b); + if (c->type == 1) { + for (int i = 0; i < c->palette_size / 2; i++) { + unsigned rgb = AV_RB16(&c->palette[i * 2]); + unsigned r = ((rgb >> 8) & 0xF) * 0x11; + unsigned g = ((rgb >> 4) & 0xF) * 0x11; + unsigned b = (rgb & 0xF) * 0x11; + AV_WN32(&new_palette[i], (0xFFU << 24) | (r << 16) | (g << 8) | b); + } + } else { + for (int i = 0; i < c->palette_size / 3; i++) { + unsigned rgb = AV_RB24(&c->palette[i * 3]); + AV_WN32(&new_palette[i], (0xFFU << 24) | rgb); + } } } @@ -246,6 +252,7 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data, if (buf_size < 32) return AVERROR_INVALIDDATA; + c->type = buf[0]; encoding = buf[1] & 7; c->format = buf[1] & 0xE0; w = AV_RB16(&buf[14]); @@ -256,7 +263,11 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data, c->video = c->palette + c->palette_size; c->video_size = buf_size - c->palette_size - 32; - if (c->palette_size > 512) + if (c->type > 1) + return AVERROR_INVALIDDATA; + if (c->type == 1 && c->palette_size > 512) + return AVERROR_INVALIDDATA; + if (c->type == 0 && c->palette_size > 768) return AVERROR_INVALIDDATA; if (buf_size < c->palette_size + 32) return AVERROR_INVALIDDATA; @@ -295,6 +306,7 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; p->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; if (encoding) { av_fast_padded_malloc(&c->new_video, &c->new_video_size, @@ -334,4 +346,5 @@ AVCodec ff_cdxl_decoder = { .close = cdxl_decode_end, .decode = cdxl_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/celp_math.c b/libavcodec/celp_math.c index a96b1aed9..920995a87 100644 --- a/libavcodec/celp_math.c +++ b/libavcodec/celp_math.c @@ -29,6 +29,7 @@ #include "celp_math.h" #include "libavutil/common.h" +#ifdef G729_BITEXACT static const uint16_t exp2a[]= { 0, 1435, 2901, 4400, 5931, 7496, 9096, 10730, @@ -54,6 +55,7 @@ int ff_exp2(uint16_t power) result= (result<<3) + ((result*exp2b[(power>>5)&31])>>17); return result + ((result*(power&31)*89)>>22); } +#endif /** * Table used to compute log2(x) diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index fac1892ce..6f13207cc 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -40,31 +40,33 @@ #define ALPHA_COMPAND_DC_OFFSET 256 #define ALPHA_COMPAND_GAIN 9400 -enum CFHDParam { - ChannelCount = 12, - SubbandCount = 14, - ImageWidth = 20, - ImageHeight = 21, - LowpassPrecision = 35, - SubbandNumber = 48, - Quantization = 53, - ChannelNumber = 62, - SampleFlags = 68, - BitsPerComponent = 101, - ChannelWidth = 104, - ChannelHeight = 105, - PrescaleShift = 109, -}; - - - static av_cold int cfhd_init(AVCodecContext *avctx) { CFHDContext *s = avctx->priv_data; - avctx->bits_per_raw_sample = 10; s->avctx = avctx; + for (int i = 0; i < 64; i++) { + int val = i; + + if (val >= 40) { + if (val >= 54) { + val -= 54; + val <<= 2; + val += 54; + } + + val -= 40; + val <<= 2; + val += 40; + } + + s->lut[0][i] = val; + } + + for (int i = 0; i < 256; i++) + s->lut[1][i] = i + ((768LL * i * i * i) / (256 * 256 * 256)); + return ff_cfhd_init_vlcs(s); } @@ -86,32 +88,28 @@ static void init_frame_defaults(CFHDContext *s) { s->coded_width = 0; s->coded_height = 0; + s->coded_format = AV_PIX_FMT_YUV422P10; s->cropped_height = 0; s->bpc = 10; - s->channel_cnt = 4; + s->channel_cnt = 3; s->subband_cnt = SUBBAND_COUNT; s->channel_num = 0; s->lowpass_precision = 16; s->quantisation = 1; - s->wavelet_depth = 3; - s->pshift = 1; s->codebook = 0; s->difference_coding = 0; - s->progressive = 0; + s->frame_type = 0; + s->sample_type = 0; + if (s->transform_type != 2) + s->transform_type = -1; init_plane_defaults(s); init_peak_table_defaults(s); } -/* TODO: merge with VLC tables or use LUT */ -static inline int dequant_and_decompand(int level, int quantisation, int codebook) +static inline int dequant_and_decompand(CFHDContext *s, int level, int quantisation, int codebook) { if (codebook == 0 || codebook == 1) { - int64_t abslevel = abs(level); - if (level < 264) - return (abslevel + ((768 * abslevel * abslevel * abslevel) / (255 * 255 * 255))) * - FFSIGN(level) * quantisation; - else - return level * quantisation; + return s->lut[codebook][abs(level)] * FFSIGN(level) * quantisation; } else return level * quantisation; } @@ -150,14 +148,15 @@ static inline void process_alpha(int16_t *alpha, int width) } } -static inline void process_bayer(AVFrame *frame) +static inline void process_bayer(AVFrame *frame, int bpc) { const int linesize = frame->linesize[0]; uint16_t *r = (uint16_t *)frame->data[0]; uint16_t *g1 = (uint16_t *)(frame->data[0] + 2); uint16_t *g2 = (uint16_t *)(frame->data[0] + frame->linesize[0]); uint16_t *b = (uint16_t *)(frame->data[0] + frame->linesize[0] + 2); - const int mid = 2048; + const int mid = 1 << (bpc - 1); + const int factor = 1 << (16 - bpc); for (int y = 0; y < frame->height >> 1; y++) { for (int x = 0; x < frame->width; x += 2) { @@ -175,10 +174,10 @@ static inline void process_bayer(AVFrame *frame) G2 = g - gd; B = (bg - mid) * 2 + g; - R = av_clip_uintp2(R * 16, 16); - G1 = av_clip_uintp2(G1 * 16, 16); - G2 = av_clip_uintp2(G2 * 16, 16); - B = av_clip_uintp2(B * 16, 16); + R = av_clip_uintp2(R * factor, 16); + G1 = av_clip_uintp2(G1 * factor, 16); + G2 = av_clip_uintp2(G2 * factor, 16); + B = av_clip_uintp2(B * factor, 16); r[x] = R; g1[x] = G1; @@ -193,49 +192,6 @@ static inline void process_bayer(AVFrame *frame) } } -static inline void filter(int16_t *output, ptrdiff_t out_stride, - int16_t *low, ptrdiff_t low_stride, - int16_t *high, ptrdiff_t high_stride, - int len, int clip) -{ - int16_t tmp; - int i; - - for (i = 0; i < len; i++) { - if (i == 0) { - tmp = (11*low[0*low_stride] - 4*low[1*low_stride] + low[2*low_stride] + 4) >> 3; - output[(2*i+0)*out_stride] = (tmp + high[0*high_stride]) >> 1; - if (clip) - output[(2*i+0)*out_stride] = av_clip_uintp2_c(output[(2*i+0)*out_stride], clip); - - tmp = ( 5*low[0*low_stride] + 4*low[1*low_stride] - low[2*low_stride] + 4) >> 3; - output[(2*i+1)*out_stride] = (tmp - high[0*high_stride]) >> 1; - if (clip) - output[(2*i+1)*out_stride] = av_clip_uintp2_c(output[(2*i+1)*out_stride], clip); - } else if (i == len-1) { - tmp = ( 5*low[i*low_stride] + 4*low[(i-1)*low_stride] - low[(i-2)*low_stride] + 4) >> 3; - output[(2*i+0)*out_stride] = (tmp + high[i*high_stride]) >> 1; - if (clip) - output[(2*i+0)*out_stride] = av_clip_uintp2_c(output[(2*i+0)*out_stride], clip); - - tmp = (11*low[i*low_stride] - 4*low[(i-1)*low_stride] + low[(i-2)*low_stride] + 4) >> 3; - output[(2*i+1)*out_stride] = (tmp - high[i*high_stride]) >> 1; - if (clip) - output[(2*i+1)*out_stride] = av_clip_uintp2_c(output[(2*i+1)*out_stride], clip); - } else { - tmp = (low[(i-1)*low_stride] - low[(i+1)*low_stride] + 4) >> 3; - output[(2*i+0)*out_stride] = (tmp + low[i*low_stride] + high[i*high_stride]) >> 1; - if (clip) - output[(2*i+0)*out_stride] = av_clip_uintp2_c(output[(2*i+0)*out_stride], clip); - - tmp = (low[(i+1)*low_stride] - low[(i-1)*low_stride] + 4) >> 3; - output[(2*i+1)*out_stride] = (tmp + low[i*low_stride] - high[i*high_stride]) >> 1; - if (clip) - output[(2*i+1)*out_stride] = av_clip_uintp2_c(output[(2*i+1)*out_stride], clip); - } - } -} - static inline void interlaced_vertical_filter(int16_t *output, int16_t *low, int16_t *high, int width, int linesize, int plane) { @@ -248,29 +204,16 @@ static inline void interlaced_vertical_filter(int16_t *output, int16_t *low, int output[i + linesize] = av_clip_uintp2(odd, 10); } } -static void horiz_filter(int16_t *output, int16_t *low, int16_t *high, - int width) -{ - filter(output, 1, low, 1, high, 1, width, 0); -} -static void horiz_filter_clip(int16_t *output, int16_t *low, int16_t *high, - int width, int clip) +static inline void inverse_temporal_filter(int16_t *low, int16_t *high, int width) { - filter(output, 1, low, 1, high, 1, width, clip); -} + for (int i = 0; i < width; i++) { + int even = (low[i] - high[i]) / 2; + int odd = (low[i] + high[i]) / 2; -static void horiz_filter_clip_bayer(int16_t *output, int16_t *low, int16_t *high, - int width, int clip) -{ - filter(output, 2, low, 1, high, 1, width, clip); -} - -static void vert_filter(int16_t *output, ptrdiff_t out_stride, - int16_t *low, ptrdiff_t low_stride, - int16_t *high, ptrdiff_t high_stride, int len) -{ - filter(output, out_stride, low, low_stride, high, high_stride, len, 0); + low[i] = even; + high[i] = odd; + } } static void free_buffers(CFHDContext *s) @@ -278,35 +221,41 @@ static void free_buffers(CFHDContext *s) int i, j; for (i = 0; i < FF_ARRAY_ELEMS(s->plane); i++) { + Plane *p = &s->plane[i]; av_freep(&s->plane[i].idwt_buf); av_freep(&s->plane[i].idwt_tmp); + s->plane[i].idwt_size = 0; - for (j = 0; j < 9; j++) + for (j = 0; j < SUBBAND_COUNT_3D; j++) s->plane[i].subband[j] = NULL; - for (j = 0; j < 8; j++) + for (j = 0; j < 10; j++) s->plane[i].l_h[j] = NULL; + + for (j = 0; j < DWT_LEVELS_3D; j++) + p->band[j][0].read_ok = + p->band[j][1].read_ok = + p->band[j][2].read_ok = + p->band[j][3].read_ok = 0; } s->a_height = 0; s->a_width = 0; + s->a_transform_type = INT_MIN; } static int alloc_buffers(AVCodecContext *avctx) { CFHDContext *s = avctx->priv_data; - int i, j, ret, planes; + int i, j, ret, planes, bayer = 0; int chroma_x_shift, chroma_y_shift; unsigned k; - if (s->coded_format == AV_PIX_FMT_BAYER_RGGB16) { - s->coded_width *= 2; - s->coded_height *= 2; - } - if ((ret = ff_set_dimensions(avctx, s->coded_width, s->coded_height)) < 0) return ret; avctx->pix_fmt = s->coded_format; + ff_cfhddsp_init(&s->dsp, s->bpc, avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16); + if ((ret = av_pix_fmt_get_chroma_sub_sample(s->coded_format, &chroma_x_shift, &chroma_y_shift)) < 0) @@ -316,30 +265,42 @@ static int alloc_buffers(AVCodecContext *avctx) planes = 4; chroma_x_shift = 1; chroma_y_shift = 1; + bayer = 1; } for (i = 0; i < planes; i++) { int w8, h8, w4, h4, w2, h2; - int width = i ? avctx->width >> chroma_x_shift : avctx->width; - int height = i ? avctx->height >> chroma_y_shift : avctx->height; - ptrdiff_t stride = FFALIGN(width / 8, 8) * 8; - if (chroma_y_shift) + int width = (i || bayer) ? s->coded_width >> chroma_x_shift : s->coded_width; + int height = (i || bayer) ? s->coded_height >> chroma_y_shift : s->coded_height; + ptrdiff_t stride = (FFALIGN(width / 8, 8) + 64) * 8; + + if (chroma_y_shift && !bayer) height = FFALIGN(height / 8, 2) * 8; s->plane[i].width = width; s->plane[i].height = height; s->plane[i].stride = stride; - w8 = FFALIGN(s->plane[i].width / 8, 8); - h8 = height / 8; + w8 = FFALIGN(s->plane[i].width / 8, 8) + 64; + h8 = FFALIGN(height, 8) / 8; w4 = w8 * 2; h4 = h8 * 2; w2 = w4 * 2; h2 = h4 * 2; - s->plane[i].idwt_buf = - av_mallocz_array(height * stride, sizeof(*s->plane[i].idwt_buf)); - s->plane[i].idwt_tmp = - av_malloc_array(height * stride, sizeof(*s->plane[i].idwt_tmp)); + if (s->transform_type == 0) { + s->plane[i].idwt_size = FFALIGN(height, 8) * stride; + s->plane[i].idwt_buf = + av_mallocz_array(s->plane[i].idwt_size, sizeof(*s->plane[i].idwt_buf)); + s->plane[i].idwt_tmp = + av_malloc_array(s->plane[i].idwt_size, sizeof(*s->plane[i].idwt_tmp)); + } else { + s->plane[i].idwt_size = FFALIGN(height, 8) * stride * 2; + s->plane[i].idwt_buf = + av_mallocz_array(s->plane[i].idwt_size, sizeof(*s->plane[i].idwt_buf)); + s->plane[i].idwt_tmp = + av_malloc_array(s->plane[i].idwt_size, sizeof(*s->plane[i].idwt_tmp)); + } + if (!s->plane[i].idwt_buf || !s->plane[i].idwt_tmp) return AVERROR(ENOMEM); @@ -350,14 +311,39 @@ static int alloc_buffers(AVCodecContext *avctx) s->plane[i].subband[4] = s->plane[i].idwt_buf + 2 * w4 * h4; s->plane[i].subband[5] = s->plane[i].idwt_buf + 1 * w4 * h4; s->plane[i].subband[6] = s->plane[i].idwt_buf + 3 * w4 * h4; - s->plane[i].subband[7] = s->plane[i].idwt_buf + 2 * w2 * h2; - s->plane[i].subband[8] = s->plane[i].idwt_buf + 1 * w2 * h2; - s->plane[i].subband[9] = s->plane[i].idwt_buf + 3 * w2 * h2; + if (s->transform_type == 0) { + s->plane[i].subband[7] = s->plane[i].idwt_buf + 2 * w2 * h2; + s->plane[i].subband[8] = s->plane[i].idwt_buf + 1 * w2 * h2; + s->plane[i].subband[9] = s->plane[i].idwt_buf + 3 * w2 * h2; + } else { + int16_t *frame2 = + s->plane[i].subband[7] = s->plane[i].idwt_buf + 4 * w2 * h2; + s->plane[i].subband[8] = frame2 + 2 * w4 * h4; + s->plane[i].subband[9] = frame2 + 1 * w4 * h4; + s->plane[i].subband[10] = frame2 + 3 * w4 * h4; + s->plane[i].subband[11] = frame2 + 2 * w2 * h2; + s->plane[i].subband[12] = frame2 + 1 * w2 * h2; + s->plane[i].subband[13] = frame2 + 3 * w2 * h2; + s->plane[i].subband[14] = s->plane[i].idwt_buf + 2 * w2 * h2; + s->plane[i].subband[15] = s->plane[i].idwt_buf + 1 * w2 * h2; + s->plane[i].subband[16] = s->plane[i].idwt_buf + 3 * w2 * h2; + } - for (j = 0; j < DWT_LEVELS; j++) { - for (k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { - s->plane[i].band[j][k].a_width = w8 << j; - s->plane[i].band[j][k].a_height = h8 << j; + if (s->transform_type == 0) { + for (j = 0; j < DWT_LEVELS; j++) { + for (k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { + s->plane[i].band[j][k].a_width = w8 << j; + s->plane[i].band[j][k].a_height = h8 << j; + } + } + } else { + for (j = 0; j < DWT_LEVELS_3D; j++) { + int t = j < 1 ? 0 : (j < 3 ? 1 : 2); + + for (k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { + s->plane[i].band[j][k].a_width = w8 << t; + s->plane[i].band[j][k].a_height = h8 << t; + } } } @@ -370,8 +356,15 @@ static int alloc_buffers(AVCodecContext *avctx) // s->plane[i].l_h[5] = ll1; s->plane[i].l_h[6] = s->plane[i].idwt_tmp; s->plane[i].l_h[7] = s->plane[i].idwt_tmp + 2 * w2 * h2; + if (s->transform_type != 0) { + int16_t *frame2 = s->plane[i].idwt_tmp + 4 * w2 * h2; + + s->plane[i].l_h[8] = frame2; + s->plane[i].l_h[9] = frame2 + 2 * w2 * h2; + } } + s->a_transform_type = s->transform_type; s->a_height = s->coded_height; s->a_width = s->coded_width; s->a_format = s->coded_format; @@ -383,19 +376,19 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { CFHDContext *s = avctx->priv_data; + CFHDDSPContext *dsp = &s->dsp; GetByteContext gb; ThreadFrame frame = { .f = data }; AVFrame *pic = data; - int ret = 0, i, j, planes, plane, got_buffer = 0; + int ret = 0, i, j, plane, got_buffer = 0; int16_t *coeff_data; - s->coded_format = AV_PIX_FMT_YUV422P10; init_frame_defaults(s); - planes = av_pix_fmt_count_planes(s->coded_format); + s->planes = av_pix_fmt_count_planes(s->coded_format); bytestream2_init(&gb, avpkt->data, avpkt->size); - while (bytestream2_get_bytes_left(&gb) > 4) { + while (bytestream2_get_bytes_left(&gb) >= 4) { /* Bit weird but implement the tag parsing as the spec says */ uint16_t tagu = bytestream2_get_be16(&gb); int16_t tag = (int16_t)tagu; @@ -406,181 +399,203 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, if (abs_tag8 >= 0x60 && abs_tag8 <= 0x6f) { av_log(avctx, AV_LOG_DEBUG, "large len %x\n", ((tagu & 0xff) << 16) | data); } else if (tag == SampleFlags) { - av_log(avctx, AV_LOG_DEBUG, "Progressive?%"PRIu16"\n", data); + av_log(avctx, AV_LOG_DEBUG, "Progressive? %"PRIu16"\n", data); s->progressive = data & 0x0001; + } else if (tag == FrameType) { + s->frame_type = data; + av_log(avctx, AV_LOG_DEBUG, "Frame type %"PRIu16"\n", data); + } else if (abstag == VersionMajor) { + av_log(avctx, AV_LOG_DEBUG, "Version major %"PRIu16"\n", data); + } else if (abstag == VersionMinor) { + av_log(avctx, AV_LOG_DEBUG, "Version minor %"PRIu16"\n", data); + } else if (abstag == VersionRevision) { + av_log(avctx, AV_LOG_DEBUG, "Version revision %"PRIu16"\n", data); + } else if (abstag == VersionEdit) { + av_log(avctx, AV_LOG_DEBUG, "Version edit %"PRIu16"\n", data); + } else if (abstag == Version) { + av_log(avctx, AV_LOG_DEBUG, "Version %"PRIu16"\n", data); } else if (tag == ImageWidth) { av_log(avctx, AV_LOG_DEBUG, "Width %"PRIu16"\n", data); s->coded_width = data; } else if (tag == ImageHeight) { av_log(avctx, AV_LOG_DEBUG, "Height %"PRIu16"\n", data); s->coded_height = data; - } else if (tag == 101) { - av_log(avctx, AV_LOG_DEBUG, "Bits per component: %"PRIu16"\n", data); - if (data < 1 || data > 31) { - av_log(avctx, AV_LOG_ERROR, "Bits per component %d is invalid\n", data); - ret = AVERROR(EINVAL); - break; - } - s->bpc = data; } else if (tag == ChannelCount) { av_log(avctx, AV_LOG_DEBUG, "Channel Count: %"PRIu16"\n", data); s->channel_cnt = data; if (data > 4) { av_log(avctx, AV_LOG_ERROR, "Channel Count of %"PRIu16" is unsupported\n", data); ret = AVERROR_PATCHWELCOME; - break; + goto end; } } else if (tag == SubbandCount) { av_log(avctx, AV_LOG_DEBUG, "Subband Count: %"PRIu16"\n", data); - if (data != SUBBAND_COUNT) { + if (data != SUBBAND_COUNT && data != SUBBAND_COUNT_3D) { av_log(avctx, AV_LOG_ERROR, "Subband Count of %"PRIu16" is unsupported\n", data); ret = AVERROR_PATCHWELCOME; - break; + goto end; } } else if (tag == ChannelNumber) { s->channel_num = data; av_log(avctx, AV_LOG_DEBUG, "Channel number %"PRIu16"\n", data); - if (s->channel_num >= planes) { + if (s->channel_num >= s->planes) { av_log(avctx, AV_LOG_ERROR, "Invalid channel number\n"); ret = AVERROR(EINVAL); - break; + goto end; } init_plane_defaults(s); } else if (tag == SubbandNumber) { - if (s->subband_num != 0 && data == 1) // hack + if (s->subband_num != 0 && data == 1 && (s->transform_type == 0 || s->transform_type == 2)) // hack s->level++; av_log(avctx, AV_LOG_DEBUG, "Subband number %"PRIu16"\n", data); s->subband_num = data; - if (s->level >= DWT_LEVELS) { + if ((s->transform_type == 0 && s->level >= DWT_LEVELS) || + (s->transform_type == 2 && s->level >= DWT_LEVELS_3D)) { av_log(avctx, AV_LOG_ERROR, "Invalid level\n"); ret = AVERROR(EINVAL); - break; + goto end; } if (s->subband_num > 3) { av_log(avctx, AV_LOG_ERROR, "Invalid subband number\n"); ret = AVERROR(EINVAL); - break; + goto end; } - } else if (tag == 51) { + } else if (tag == SubbandBand) { av_log(avctx, AV_LOG_DEBUG, "Subband number actual %"PRIu16"\n", data); - s->subband_num_actual = data; - if (s->subband_num_actual >= 10) { + if ((s->transform_type == 0 && data >= SUBBAND_COUNT) || + (s->transform_type == 2 && data >= SUBBAND_COUNT_3D && data != 255)) { av_log(avctx, AV_LOG_ERROR, "Invalid subband number actual\n"); ret = AVERROR(EINVAL); - break; + goto end; } + if (s->transform_type == 0 || s->transform_type == 2) + s->subband_num_actual = data; + else + av_log(avctx, AV_LOG_WARNING, "Ignoring subband num actual %"PRIu16"\n", data); } else if (tag == LowpassPrecision) av_log(avctx, AV_LOG_DEBUG, "Lowpass precision bits: %"PRIu16"\n", data); else if (tag == Quantization) { s->quantisation = data; av_log(avctx, AV_LOG_DEBUG, "Quantisation: %"PRIu16"\n", data); - } else if (tag == PrescaleShift) { - s->prescale_shift[0] = (data >> 0) & 0x7; - s->prescale_shift[1] = (data >> 3) & 0x7; - s->prescale_shift[2] = (data >> 6) & 0x7; - av_log(avctx, AV_LOG_DEBUG, "Prescale shift (VC-5): %x\n", data); - } else if (tag == 27) { - av_log(avctx, AV_LOG_DEBUG, "Lowpass width %"PRIu16"\n", data); - if (data < 3 || data > s->plane[s->channel_num].band[0][0].a_width) { - av_log(avctx, AV_LOG_ERROR, "Invalid lowpass width\n"); + } else if (tag == PrescaleTable) { + for (i = 0; i < 8; i++) + s->prescale_table[i] = (data >> (14 - i * 2)) & 0x3; + av_log(avctx, AV_LOG_DEBUG, "Prescale table: %x\n", data); + } else if (tag == BandEncoding) { + if (!data || data > 5) { + av_log(avctx, AV_LOG_ERROR, "Invalid band encoding\n"); ret = AVERROR(EINVAL); - break; + goto end; } + s->band_encoding = data; + av_log(avctx, AV_LOG_DEBUG, "Encode Method for Subband %d : %x\n", s->subband_num_actual, data); + } else if (tag == LowpassWidth) { + av_log(avctx, AV_LOG_DEBUG, "Lowpass width %"PRIu16"\n", data); s->plane[s->channel_num].band[0][0].width = data; s->plane[s->channel_num].band[0][0].stride = data; - } else if (tag == 28) { + } else if (tag == LowpassHeight) { av_log(avctx, AV_LOG_DEBUG, "Lowpass height %"PRIu16"\n", data); - if (data < 3 || data > s->plane[s->channel_num].band[0][0].a_height) { - av_log(avctx, AV_LOG_ERROR, "Invalid lowpass height\n"); - ret = AVERROR(EINVAL); - break; - } s->plane[s->channel_num].band[0][0].height = data; - } else if (tag == 1) + } else if (tag == SampleType) { + s->sample_type = data; av_log(avctx, AV_LOG_DEBUG, "Sample type? %"PRIu16"\n", data); - else if (tag == 10) { - if (data != 0) { - avpriv_report_missing_feature(avctx, "Transform type of %"PRIu16, data); - ret = AVERROR_PATCHWELCOME; - break; + } else if (tag == TransformType) { + if (data > 2) { + av_log(avctx, AV_LOG_ERROR, "Invalid transform type\n"); + ret = AVERROR(EINVAL); + goto end; } else if (data == 1) { av_log(avctx, AV_LOG_ERROR, "unsupported transform type\n"); ret = AVERROR_PATCHWELCOME; - break; + goto end; + } + if (s->transform_type == -1) { + s->transform_type = data; + av_log(avctx, AV_LOG_DEBUG, "Transform type %"PRIu16"\n", data); + } else { + av_log(avctx, AV_LOG_DEBUG, "Ignoring additional transform type %"PRIu16"\n", data); } - av_log(avctx, AV_LOG_DEBUG, "Transform-type? %"PRIu16"\n", data); } else if (abstag >= 0x4000 && abstag <= 0x40ff) { if (abstag == 0x4001) s->peak.level = 0; av_log(avctx, AV_LOG_DEBUG, "Small chunk length %d %s\n", data * 4, tag < 0 ? "optional" : "required"); bytestream2_skipu(&gb, data * 4); - } else if (tag == 23) { - av_log(avctx, AV_LOG_DEBUG, "Skip frame\n"); - avpriv_report_missing_feature(avctx, "Skip frame"); - ret = AVERROR_PATCHWELCOME; - break; - } else if (tag == 2) { - av_log(avctx, AV_LOG_DEBUG, "tag=2 header - skipping %i tag/value pairs\n", data); + } else if (tag == FrameIndex) { + av_log(avctx, AV_LOG_DEBUG, "Frame index %"PRIu16"\n", data); + s->frame_index = data; + } else if (tag == SampleIndexTable) { + av_log(avctx, AV_LOG_DEBUG, "Sample index table - skipping %i values\n", data); if (data > bytestream2_get_bytes_left(&gb) / 4) { - av_log(avctx, AV_LOG_ERROR, "too many tag/value pairs (%d)\n", data); + av_log(avctx, AV_LOG_ERROR, "too many values (%d)\n", data); ret = AVERROR_INVALIDDATA; - break; + goto end; } for (i = 0; i < data; i++) { - uint16_t tag2 = bytestream2_get_be16(&gb); - uint16_t val2 = bytestream2_get_be16(&gb); - av_log(avctx, AV_LOG_DEBUG, "Tag/Value = %x %x\n", tag2, val2); + uint32_t offset = bytestream2_get_be32(&gb); + av_log(avctx, AV_LOG_DEBUG, "Offset = %"PRIu32"\n", offset); } - } else if (tag == 41) { + } else if (tag == HighpassWidth) { av_log(avctx, AV_LOG_DEBUG, "Highpass width %i channel %i level %i subband %i\n", data, s->channel_num, s->level, s->subband_num); if (data < 3) { av_log(avctx, AV_LOG_ERROR, "Invalid highpass width\n"); ret = AVERROR(EINVAL); - break; + goto end; } s->plane[s->channel_num].band[s->level][s->subband_num].width = data; s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8); - } else if (tag == 42) { + } else if (tag == HighpassHeight) { av_log(avctx, AV_LOG_DEBUG, "Highpass height %i\n", data); if (data < 3) { av_log(avctx, AV_LOG_ERROR, "Invalid highpass height\n"); ret = AVERROR(EINVAL); - break; + goto end; } s->plane[s->channel_num].band[s->level][s->subband_num].height = data; - } else if (tag == 49) { + } else if (tag == BandWidth) { av_log(avctx, AV_LOG_DEBUG, "Highpass width2 %i\n", data); if (data < 3) { av_log(avctx, AV_LOG_ERROR, "Invalid highpass width2\n"); ret = AVERROR(EINVAL); - break; + goto end; } s->plane[s->channel_num].band[s->level][s->subband_num].width = data; s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8); - } else if (tag == 50) { + } else if (tag == BandHeight) { av_log(avctx, AV_LOG_DEBUG, "Highpass height2 %i\n", data); if (data < 3) { av_log(avctx, AV_LOG_ERROR, "Invalid highpass height2\n"); ret = AVERROR(EINVAL); - break; + goto end; } s->plane[s->channel_num].band[s->level][s->subband_num].height = data; - } else if (tag == 71) { - s->codebook = data; - av_log(avctx, AV_LOG_DEBUG, "Codebook %i\n", s->codebook); - } else if (tag == 72) { + } else if (tag == InputFormat) { + av_log(avctx, AV_LOG_DEBUG, "Input format %i\n", data); + if (s->coded_format == AV_PIX_FMT_NONE || + s->coded_format == AV_PIX_FMT_YUV422P10) { + if (data >= 100 && data <= 105) { + s->coded_format = AV_PIX_FMT_BAYER_RGGB16; + } else if (data >= 122 && data <= 128) { + s->coded_format = AV_PIX_FMT_GBRP12; + } else if (data == 30) { + s->coded_format = AV_PIX_FMT_GBRAP12; + } else { + s->coded_format = AV_PIX_FMT_YUV422P10; + } + s->planes = s->coded_format == AV_PIX_FMT_BAYER_RGGB16 ? 4 : av_pix_fmt_count_planes(s->coded_format); + } + } else if (tag == BandCodingFlags) { s->codebook = data & 0xf; s->difference_coding = (data >> 4) & 1; av_log(avctx, AV_LOG_DEBUG, "Other codebook? %i\n", s->codebook); - } else if (tag == 70) { - av_log(avctx, AV_LOG_DEBUG, "Subsampling or bit-depth flag? %i\n", data); + } else if (tag == Precision) { + av_log(avctx, AV_LOG_DEBUG, "Precision %i\n", data); if (!(data == 10 || data == 12)) { av_log(avctx, AV_LOG_ERROR, "Invalid bits per channel\n"); ret = AVERROR(EINVAL); - break; + goto end; } - s->bpc = data; - } else if (tag == 84) { + avctx->bits_per_raw_sample = s->bpc = data; + } else if (tag == EncodedFormat) { av_log(avctx, AV_LOG_DEBUG, "Sample format? %i\n", data); if (data == 1) { s->coded_format = AV_PIX_FMT_YUV422P10; @@ -593,23 +608,23 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, } else { avpriv_report_missing_feature(avctx, "Sample format of %"PRIu16, data); ret = AVERROR_PATCHWELCOME; - break; + goto end; } - planes = data == 2 ? 4 : av_pix_fmt_count_planes(s->coded_format); - } else if (tag == -85) { + s->planes = data == 2 ? 4 : av_pix_fmt_count_planes(s->coded_format); + } else if (tag == -DisplayHeight) { av_log(avctx, AV_LOG_DEBUG, "Cropped height %"PRIu16"\n", data); s->cropped_height = data; - } else if (tag == -75) { + } else if (tag == -PeakOffsetLow) { s->peak.offset &= ~0xffff; s->peak.offset |= (data & 0xffff); s->peak.base = gb; s->peak.level = 0; - } else if (tag == -76) { + } else if (tag == -PeakOffsetHigh) { s->peak.offset &= 0xffff; s->peak.offset |= (data & 0xffffU)<<16; s->peak.base = gb; s->peak.level = 0; - } else if (tag == -74 && s->peak.offset) { + } else if (tag == -PeakLevel && s->peak.offset) { s->peak.level = data; if (s->peak.offset < 4 - bytestream2_tell(&s->peak.base) || s->peak.offset > 4 + bytestream2_get_bytes_left(&s->peak.base) @@ -621,11 +636,36 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, } else av_log(avctx, AV_LOG_DEBUG, "Unknown tag %i data %x\n", tag, data); - /* Some kind of end of header tag */ - if (tag == 4 && data == 0x1a4a && s->coded_width && s->coded_height && + if (tag == BitstreamMarker && data == 0xf0f && s->coded_format != AV_PIX_FMT_NONE) { + int lowpass_height = s->plane[s->channel_num].band[0][0].height; + int lowpass_width = s->plane[s->channel_num].band[0][0].width; + int factor = s->coded_format == AV_PIX_FMT_BAYER_RGGB16 ? 2 : 1; + + if (s->coded_width) { + s->coded_width *= factor; + } + + if (s->coded_height) { + s->coded_height *= factor; + } + + if (!s->a_width && !s->coded_width) { + s->coded_width = lowpass_width * factor * 8; + } + + if (!s->a_height && !s->coded_height) { + s->coded_height = lowpass_height * factor * 8; + } + + if (s->a_width && !s->coded_width) + s->coded_width = s->a_width; + if (s->a_height && !s->coded_height) + s->coded_height = s->a_height; + if (s->a_width != s->coded_width || s->a_height != s->coded_height || - s->a_format != s->coded_format) { + s->a_format != s->coded_format || + s->transform_type != s->a_transform_type) { free_buffers(s); if ((ret = alloc_buffers(avctx)) < 0) { free_buffers(s); @@ -651,15 +691,49 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, s->coded_height = 0; s->coded_format = AV_PIX_FMT_NONE; got_buffer = 1; + } else if (tag == FrameIndex && data == 1 && s->sample_type == 1 && s->frame_type == 2) { + frame.f->width = + frame.f->height = 0; + + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) + return ret; + s->coded_width = 0; + s->coded_height = 0; + s->coded_format = AV_PIX_FMT_NONE; + got_buffer = 1; } + + if (s->subband_num_actual == 255) + goto finish; coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual]; /* Lowpass coefficients */ - if (tag == 4 && data == 0xf0f && s->a_width && s->a_height) { - int lowpass_height = s->plane[s->channel_num].band[0][0].height; - int lowpass_width = s->plane[s->channel_num].band[0][0].width; - int lowpass_a_height = s->plane[s->channel_num].band[0][0].a_height; - int lowpass_a_width = s->plane[s->channel_num].band[0][0].a_width; + if (tag == BitstreamMarker && data == 0xf0f) { + int lowpass_height, lowpass_width, lowpass_a_height, lowpass_a_width; + + if (!s->a_width || !s->a_height) { + ret = AVERROR_INVALIDDATA; + goto end; + } + + lowpass_height = s->plane[s->channel_num].band[0][0].height; + lowpass_width = s->plane[s->channel_num].band[0][0].width; + lowpass_a_height = s->plane[s->channel_num].band[0][0].a_height; + lowpass_a_width = s->plane[s->channel_num].band[0][0].a_width; + + if (lowpass_width < 3 || + lowpass_width > lowpass_a_width) { + av_log(avctx, AV_LOG_ERROR, "Invalid lowpass width\n"); + ret = AVERROR(EINVAL); + goto end; + } + + if (lowpass_height < 3 || + lowpass_height > lowpass_a_height) { + av_log(avctx, AV_LOG_ERROR, "Invalid lowpass height\n"); + ret = AVERROR(EINVAL); + goto end; + } if (!got_buffer) { av_log(avctx, AV_LOG_ERROR, "No end of header tag found\n"); @@ -668,7 +742,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, } if (lowpass_height > lowpass_a_height || lowpass_width > lowpass_a_width || - lowpass_a_width * lowpass_a_height * sizeof(int16_t) > bytestream2_get_bytes_left(&gb)) { + lowpass_width * lowpass_height * sizeof(int16_t) > bytestream2_get_bytes_left(&gb)) { av_log(avctx, AV_LOG_ERROR, "Too many lowpass coefficients\n"); ret = AVERROR(EINVAL); goto end; @@ -692,20 +766,30 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, lowpass_width * sizeof(*coeff_data)); } + s->plane[s->channel_num].band[0][0].read_ok = 1; + av_log(avctx, AV_LOG_DEBUG, "Lowpass coefficients %d\n", lowpass_width * lowpass_height); } - if (tag == 55 && s->subband_num_actual != 255 && s->a_width && s->a_height) { - int highpass_height = s->plane[s->channel_num].band[s->level][s->subband_num].height; - int highpass_width = s->plane[s->channel_num].band[s->level][s->subband_num].width; - int highpass_a_width = s->plane[s->channel_num].band[s->level][s->subband_num].a_width; - int highpass_a_height = s->plane[s->channel_num].band[s->level][s->subband_num].a_height; - int highpass_stride = s->plane[s->channel_num].band[s->level][s->subband_num].stride; + av_assert0(s->subband_num_actual != 255); + if (tag == BandHeader || tag == BandSecondPass) { + int highpass_height, highpass_width, highpass_a_width, highpass_a_height, highpass_stride, a_expected; int expected; - int a_expected = highpass_a_height * highpass_a_width; int level, run, coeff; int count = 0, bytes; + if (!s->a_width || !s->a_height) { + ret = AVERROR_INVALIDDATA; + goto end; + } + + highpass_height = s->plane[s->channel_num].band[s->level][s->subband_num].height; + highpass_width = s->plane[s->channel_num].band[s->level][s->subband_num].width; + highpass_a_width = s->plane[s->channel_num].band[s->level][s->subband_num].a_width; + highpass_a_height = s->plane[s->channel_num].band[s->level][s->subband_num].a_height; + highpass_stride = s->plane[s->channel_num].band[s->level][s->subband_num].stride; + a_expected = highpass_a_height * highpass_a_width; + if (!got_buffer) { av_log(avctx, AV_LOG_ERROR, "No end of header tag found\n"); ret = AVERROR(EINVAL); @@ -721,9 +805,16 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_DEBUG, "Start subband coeffs plane %i level %i codebook %i expected %i\n", s->channel_num, s->level, s->codebook, expected); - init_get_bits(&s->gb, gb.buffer, bytestream2_get_bytes_left(&gb) * 8); + ret = init_get_bits8(&s->gb, gb.buffer, bytestream2_get_bytes_left(&gb)); + if (ret < 0) + goto end; { OPEN_READER(re, &s->gb); + + const int lossless = s->band_encoding == 5; + + if (s->codebook == 0 && s->transform_type == 2 && s->subband_num_actual == 7) + s->codebook = 1; if (!s->codebook) { while (1) { UPDATE_CACHE(re, &s->gb); @@ -739,9 +830,21 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, if (count > expected) break; - coeff = dequant_and_decompand(level, s->quantisation, 0); - for (i = 0; i < run; i++) - *coeff_data++ = coeff; + if (!lossless) + coeff = dequant_and_decompand(s, level, s->quantisation, 0); + else + coeff = level; + if (tag == BandSecondPass) { + const uint16_t q = s->quantisation; + + for (i = 0; i < run; i++) { + *coeff_data |= coeff * 256; + *coeff_data++ *= q; + } + } else { + for (i = 0; i < run; i++) + *coeff_data++ = coeff; + } } } else { while (1) { @@ -758,9 +861,21 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, if (count > expected) break; - coeff = dequant_and_decompand(level, s->quantisation, s->codebook); - for (i = 0; i < run; i++) - *coeff_data++ = coeff; + if (!lossless) + coeff = dequant_and_decompand(s, level, s->quantisation, s->codebook); + else + coeff = level; + if (tag == BandSecondPass) { + const uint16_t q = s->quantisation; + + for (i = 0; i < run; i++) { + *coeff_data |= coeff * 256; + *coeff_data++ *= q; + } + } else { + for (i = 0; i < run; i++) + *coeff_data++ = coeff; + } } } CLOSE_READER(re, &s->gb); @@ -785,18 +900,23 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, bytestream2_seek(&gb, bytes, SEEK_CUR); av_log(avctx, AV_LOG_DEBUG, "End subband coeffs %i extra %i\n", count, count - expected); - s->codebook = 0; - - /* Copy last line of coefficients if odd height */ - if (highpass_height & 1) { - memcpy(&coeff_data[highpass_height * highpass_stride], - &coeff_data[(highpass_height - 1) * highpass_stride], - highpass_stride * sizeof(*coeff_data)); - } + s->plane[s->channel_num].band[s->level][s->subband_num].read_ok = 1; +finish: + if (s->subband_num_actual != 255) + s->codebook = 0; } } + s->planes = av_pix_fmt_count_planes(avctx->pix_fmt); + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { + s->progressive = 1; + s->planes = 4; + } + + ff_thread_finish_setup(avctx); + if (!s->a_width || !s->a_height || s->a_format == AV_PIX_FMT_NONE || + s->a_transform_type == INT_MIN || s->coded_width || s->coded_height || s->coded_format != AV_PIX_FMT_NONE) { av_log(avctx, AV_LOG_ERROR, "Invalid dimensions\n"); ret = AVERROR(EINVAL); @@ -809,232 +929,470 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, goto end; } - planes = av_pix_fmt_count_planes(avctx->pix_fmt); - if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { - if (!s->progressive) - return AVERROR_INVALIDDATA; - planes = 4; + for (plane = 0; plane < s->planes; plane++) { + int o, level; + + for (level = 0; level < (s->transform_type == 0 ? DWT_LEVELS : DWT_LEVELS_3D) ; level++) { + if (s->transform_type == 2) + if (level == 2 || level == 5) + continue; + for (o = !!level; o < 4 ; o++) { + if (!s->plane[plane].band[level][o].read_ok) { + ret = AVERROR_INVALIDDATA; + goto end; + } + } + } } - for (plane = 0; plane < planes && !ret; plane++) { - /* level 1 */ - int lowpass_height = s->plane[plane].band[0][0].height; - int lowpass_width = s->plane[plane].band[0][0].width; - int highpass_stride = s->plane[plane].band[0][1].stride; - int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane; - ptrdiff_t dst_linesize; - int16_t *low, *high, *output, *dst; + if (s->transform_type == 0 && s->sample_type != 1) { + for (plane = 0; plane < s->planes && !ret; plane++) { + /* level 1 */ + int lowpass_height = s->plane[plane].band[0][0].height; + int output_stride = s->plane[plane].band[0][0].a_width; + int lowpass_width = s->plane[plane].band[0][0].width; + int highpass_stride = s->plane[plane].band[0][1].stride; + int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane; + ptrdiff_t dst_linesize; + int16_t *low, *high, *output, *dst; - if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { - act_plane = 0; - dst_linesize = pic->linesize[act_plane]; - } else { - dst_linesize = pic->linesize[act_plane] / 2; - } + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { + act_plane = 0; + dst_linesize = pic->linesize[act_plane]; + } else { + dst_linesize = pic->linesize[act_plane] / 2; + } - if (lowpass_height > s->plane[plane].band[0][0].a_height || lowpass_width > s->plane[plane].band[0][0].a_width || - !highpass_stride || s->plane[plane].band[0][1].width > s->plane[plane].band[0][1].a_width) { - av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); - ret = AVERROR(EINVAL); - goto end; - } + if (lowpass_height > s->plane[plane].band[0][0].a_height || lowpass_width > s->plane[plane].band[0][0].a_width || + !highpass_stride || s->plane[plane].band[0][1].width > s->plane[plane].band[0][1].a_width || + lowpass_width < 3 || lowpass_height < 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); + ret = AVERROR(EINVAL); + goto end; + } - av_log(avctx, AV_LOG_DEBUG, "Decoding level 1 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); + av_log(avctx, AV_LOG_DEBUG, "Decoding level 1 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); - low = s->plane[plane].subband[0]; - high = s->plane[plane].subband[2]; - output = s->plane[plane].l_h[0]; - for (i = 0; i < lowpass_width; i++) { - vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height); - low++; - high++; - output++; - } + low = s->plane[plane].subband[0]; + high = s->plane[plane].subband[2]; + output = s->plane[plane].l_h[0]; + dsp->vert_filter(output, output_stride, low, lowpass_width, high, highpass_stride, lowpass_width, lowpass_height); - low = s->plane[plane].subband[1]; - high = s->plane[plane].subband[3]; - output = s->plane[plane].l_h[1]; + low = s->plane[plane].subband[1]; + high = s->plane[plane].subband[3]; + output = s->plane[plane].l_h[1]; - for (i = 0; i < lowpass_width; i++) { - // note the stride of "low" is highpass_stride - vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height); - low++; - high++; - output++; - } + dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].l_h[0]; + high = s->plane[plane].l_h[1]; + output = s->plane[plane].subband[0]; + dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); + if (s->bpc == 12) { + output = s->plane[plane].subband[0]; + for (i = 0; i < lowpass_height * 2; i++) { + for (j = 0; j < lowpass_width * 2; j++) + output[j] *= 4; + + output += output_stride * 2; + } + } + + /* level 2 */ + lowpass_height = s->plane[plane].band[1][1].height; + output_stride = s->plane[plane].band[1][1].a_width; + lowpass_width = s->plane[plane].band[1][1].width; + highpass_stride = s->plane[plane].band[1][1].stride; + + if (lowpass_height > s->plane[plane].band[1][1].a_height || lowpass_width > s->plane[plane].band[1][1].a_width || + !highpass_stride || s->plane[plane].band[1][1].width > s->plane[plane].band[1][1].a_width || + lowpass_width < 3 || lowpass_height < 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); + ret = AVERROR(EINVAL); + goto end; + } + + av_log(avctx, AV_LOG_DEBUG, "Level 2 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); + + low = s->plane[plane].subband[0]; + high = s->plane[plane].subband[5]; + output = s->plane[plane].l_h[3]; + dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].subband[4]; + high = s->plane[plane].subband[6]; + output = s->plane[plane].l_h[4]; + dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].l_h[3]; + high = s->plane[plane].l_h[4]; + output = s->plane[plane].subband[0]; + dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); - low = s->plane[plane].l_h[0]; - high = s->plane[plane].l_h[1]; - output = s->plane[plane].subband[0]; - for (i = 0; i < lowpass_height * 2; i++) { - horiz_filter(output, low, high, lowpass_width); - low += lowpass_width; - high += lowpass_width; - output += lowpass_width * 2; - } - if (s->bpc == 12) { output = s->plane[plane].subband[0]; for (i = 0; i < lowpass_height * 2; i++) { for (j = 0; j < lowpass_width * 2; j++) output[j] *= 4; - output += lowpass_width * 2; + output += output_stride * 2; + } + + /* level 3 */ + lowpass_height = s->plane[plane].band[2][1].height; + output_stride = s->plane[plane].band[2][1].a_width; + lowpass_width = s->plane[plane].band[2][1].width; + highpass_stride = s->plane[plane].band[2][1].stride; + + if (lowpass_height > s->plane[plane].band[2][1].a_height || lowpass_width > s->plane[plane].band[2][1].a_width || + !highpass_stride || s->plane[plane].band[2][1].width > s->plane[plane].band[2][1].a_width || + lowpass_height < 3 || lowpass_width < 3 || lowpass_width * 2 > s->plane[plane].width) { + av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); + ret = AVERROR(EINVAL); + goto end; + } + + av_log(avctx, AV_LOG_DEBUG, "Level 3 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); + if (s->progressive) { + low = s->plane[plane].subband[0]; + high = s->plane[plane].subband[8]; + output = s->plane[plane].l_h[6]; + dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].subband[7]; + high = s->plane[plane].subband[9]; + output = s->plane[plane].l_h[7]; + dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + dst = (int16_t *)pic->data[act_plane]; + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { + if (plane & 1) + dst++; + if (plane > 1) + dst += pic->linesize[act_plane] >> 1; + } + low = s->plane[plane].l_h[6]; + high = s->plane[plane].l_h[7]; + + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16 && + (lowpass_height * 2 > avctx->coded_height / 2 || + lowpass_width * 2 > avctx->coded_width / 2 ) + ) { + ret = AVERROR_INVALIDDATA; + goto end; + } + + for (i = 0; i < s->plane[act_plane].height; i++) { + dsp->horiz_filter_clip(dst, low, high, lowpass_width, s->bpc); + if (avctx->pix_fmt == AV_PIX_FMT_GBRAP12 && act_plane == 3) + process_alpha(dst, lowpass_width * 2); + low += output_stride; + high += output_stride; + dst += dst_linesize; + } + } else { + av_log(avctx, AV_LOG_DEBUG, "interlaced frame ? %d", pic->interlaced_frame); + pic->interlaced_frame = 1; + low = s->plane[plane].subband[0]; + high = s->plane[plane].subband[7]; + output = s->plane[plane].l_h[6]; + dsp->horiz_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].subband[8]; + high = s->plane[plane].subband[9]; + output = s->plane[plane].l_h[7]; + dsp->horiz_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + dst = (int16_t *)pic->data[act_plane]; + low = s->plane[plane].l_h[6]; + high = s->plane[plane].l_h[7]; + for (i = 0; i < s->plane[act_plane].height / 2; i++) { + interlaced_vertical_filter(dst, low, high, lowpass_width * 2, pic->linesize[act_plane]/2, act_plane); + low += output_stride * 2; + high += output_stride * 2; + dst += pic->linesize[act_plane]; + } } } + } else if (s->transform_type == 2 && (avctx->internal->is_copy || s->frame_index == 1 || s->sample_type != 1)) { + for (plane = 0; plane < s->planes && !ret; plane++) { + int lowpass_height = s->plane[plane].band[0][0].height; + int output_stride = s->plane[plane].band[0][0].a_width; + int lowpass_width = s->plane[plane].band[0][0].width; + int highpass_stride = s->plane[plane].band[0][1].stride; + int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane; + int16_t *low, *high, *output, *dst; + ptrdiff_t dst_linesize; - /* level 2 */ - lowpass_height = s->plane[plane].band[1][1].height; - lowpass_width = s->plane[plane].band[1][1].width; - highpass_stride = s->plane[plane].band[1][1].stride; + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { + act_plane = 0; + dst_linesize = pic->linesize[act_plane]; + } else { + dst_linesize = pic->linesize[act_plane] / 2; + } - if (lowpass_height > s->plane[plane].band[1][1].a_height || lowpass_width > s->plane[plane].band[1][1].a_width || - !highpass_stride || s->plane[plane].band[1][1].width > s->plane[plane].band[1][1].a_width) { - av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); - ret = AVERROR(EINVAL); - goto end; - } + if (lowpass_height > s->plane[plane].band[0][0].a_height || lowpass_width > s->plane[plane].band[0][0].a_width || + !highpass_stride || s->plane[plane].band[0][1].width > s->plane[plane].band[0][1].a_width || + lowpass_width < 3 || lowpass_height < 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); + ret = AVERROR(EINVAL); + goto end; + } - av_log(avctx, AV_LOG_DEBUG, "Level 2 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); + av_log(avctx, AV_LOG_DEBUG, "Decoding level 1 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); - low = s->plane[plane].subband[0]; - high = s->plane[plane].subband[5]; - output = s->plane[plane].l_h[3]; - for (i = 0; i < lowpass_width; i++) { - vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height); - low++; - high++; - output++; - } - - low = s->plane[plane].subband[4]; - high = s->plane[plane].subband[6]; - output = s->plane[plane].l_h[4]; - for (i = 0; i < lowpass_width; i++) { - vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height); - low++; - high++; - output++; - } - - low = s->plane[plane].l_h[3]; - high = s->plane[plane].l_h[4]; - output = s->plane[plane].subband[0]; - for (i = 0; i < lowpass_height * 2; i++) { - horiz_filter(output, low, high, lowpass_width); - low += lowpass_width; - high += lowpass_width; - output += lowpass_width * 2; - } - - output = s->plane[plane].subband[0]; - for (i = 0; i < lowpass_height * 2; i++) { - for (j = 0; j < lowpass_width * 2; j++) - output[j] *= 4; - - output += lowpass_width * 2; - } - - /* level 3 */ - lowpass_height = s->plane[plane].band[2][1].height; - lowpass_width = s->plane[plane].band[2][1].width; - highpass_stride = s->plane[plane].band[2][1].stride; - - if (lowpass_height > s->plane[plane].band[2][1].a_height || lowpass_width > s->plane[plane].band[2][1].a_width || - !highpass_stride || s->plane[plane].band[2][1].width > s->plane[plane].band[2][1].a_width) { - av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); - ret = AVERROR(EINVAL); - goto end; - } - - av_log(avctx, AV_LOG_DEBUG, "Level 3 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); - if (s->progressive) { low = s->plane[plane].subband[0]; - high = s->plane[plane].subband[8]; - output = s->plane[plane].l_h[6]; - for (i = 0; i < lowpass_width; i++) { - vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height); - low++; - high++; - output++; + high = s->plane[plane].subband[2]; + output = s->plane[plane].l_h[0]; + dsp->vert_filter(output, output_stride, low, lowpass_width, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].subband[1]; + high = s->plane[plane].subband[3]; + output = s->plane[plane].l_h[1]; + dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].l_h[0]; + high = s->plane[plane].l_h[1]; + output = s->plane[plane].l_h[7]; + dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); + if (s->bpc == 12) { + output = s->plane[plane].l_h[7]; + for (i = 0; i < lowpass_height * 2; i++) { + for (j = 0; j < lowpass_width * 2; j++) + output[j] *= 4; + + output += output_stride * 2; + } + } + + lowpass_height = s->plane[plane].band[1][1].height; + output_stride = s->plane[plane].band[1][1].a_width; + lowpass_width = s->plane[plane].band[1][1].width; + highpass_stride = s->plane[plane].band[1][1].stride; + + if (lowpass_height > s->plane[plane].band[1][1].a_height || lowpass_width > s->plane[plane].band[1][1].a_width || + !highpass_stride || s->plane[plane].band[1][1].width > s->plane[plane].band[1][1].a_width || + lowpass_width < 3 || lowpass_height < 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); + ret = AVERROR(EINVAL); + goto end; + } + + av_log(avctx, AV_LOG_DEBUG, "Level 2 lowpass plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); + + low = s->plane[plane].l_h[7]; + high = s->plane[plane].subband[5]; + output = s->plane[plane].l_h[3]; + dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].subband[4]; + high = s->plane[plane].subband[6]; + output = s->plane[plane].l_h[4]; + dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].l_h[3]; + high = s->plane[plane].l_h[4]; + output = s->plane[plane].l_h[7]; + dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); + + output = s->plane[plane].l_h[7]; + for (i = 0; i < lowpass_height * 2; i++) { + for (j = 0; j < lowpass_width * 2; j++) + output[j] *= 4; + output += output_stride * 2; } low = s->plane[plane].subband[7]; high = s->plane[plane].subband[9]; - output = s->plane[plane].l_h[7]; - for (i = 0; i < lowpass_width; i++) { - vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height); - low++; - high++; - output++; - } + output = s->plane[plane].l_h[3]; + dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); - dst = (int16_t *)pic->data[act_plane]; - if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { - if (plane & 1) - dst++; - if (plane > 1) - dst += pic->linesize[act_plane] >> 1; - } - low = s->plane[plane].l_h[6]; - high = s->plane[plane].l_h[7]; + low = s->plane[plane].subband[8]; + high = s->plane[plane].subband[10]; + output = s->plane[plane].l_h[4]; + dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); - if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16 && - (lowpass_height * 2 > avctx->coded_height / 2 || - lowpass_width * 2 > avctx->coded_width / 2 ) - ) { - ret = AVERROR_INVALIDDATA; + low = s->plane[plane].l_h[3]; + high = s->plane[plane].l_h[4]; + output = s->plane[plane].l_h[9]; + dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); + + lowpass_height = s->plane[plane].band[4][1].height; + output_stride = s->plane[plane].band[4][1].a_width; + lowpass_width = s->plane[plane].band[4][1].width; + highpass_stride = s->plane[plane].band[4][1].stride; + av_log(avctx, AV_LOG_DEBUG, "temporal level %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); + + if (lowpass_height > s->plane[plane].band[4][1].a_height || lowpass_width > s->plane[plane].band[4][1].a_width || + !highpass_stride || s->plane[plane].band[4][1].width > s->plane[plane].band[4][1].a_width || + lowpass_width < 3 || lowpass_height < 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); + ret = AVERROR(EINVAL); goto end; } - for (i = 0; i < lowpass_height * 2; i++) { - if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) - horiz_filter_clip_bayer(dst, low, high, lowpass_width, s->bpc); - else - horiz_filter_clip(dst, low, high, lowpass_width, s->bpc); - if (avctx->pix_fmt == AV_PIX_FMT_GBRAP12 && act_plane == 3) - process_alpha(dst, lowpass_width * 2); - low += lowpass_width; - high += lowpass_width; - dst += dst_linesize; - } - } else { - av_log(avctx, AV_LOG_DEBUG, "interlaced frame ? %d", pic->interlaced_frame); - pic->interlaced_frame = 1; - low = s->plane[plane].subband[0]; - high = s->plane[plane].subband[7]; - output = s->plane[plane].l_h[6]; - for (i = 0; i < lowpass_height; i++) { - horiz_filter(output, low, high, lowpass_width); - low += lowpass_width; - high += lowpass_width; - output += lowpass_width * 2; - } - - low = s->plane[plane].subband[8]; - high = s->plane[plane].subband[9]; + low = s->plane[plane].l_h[7]; + high = s->plane[plane].l_h[9]; output = s->plane[plane].l_h[7]; for (i = 0; i < lowpass_height; i++) { - horiz_filter(output, low, high, lowpass_width); - low += lowpass_width; - high += lowpass_width; - output += lowpass_width * 2; + inverse_temporal_filter(low, high, lowpass_width); + low += output_stride; + high += output_stride; } + if (s->progressive) { + low = s->plane[plane].l_h[7]; + high = s->plane[plane].subband[15]; + output = s->plane[plane].l_h[6]; + dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); - dst = (int16_t *)pic->data[act_plane]; - low = s->plane[plane].l_h[6]; - high = s->plane[plane].l_h[7]; - for (i = 0; i < lowpass_height; i++) { - interlaced_vertical_filter(dst, low, high, lowpass_width * 2, pic->linesize[act_plane]/2, act_plane); - low += lowpass_width * 2; - high += lowpass_width * 2; - dst += pic->linesize[act_plane]; + low = s->plane[plane].subband[14]; + high = s->plane[plane].subband[16]; + output = s->plane[plane].l_h[7]; + dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].l_h[9]; + high = s->plane[plane].subband[12]; + output = s->plane[plane].l_h[8]; + dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].subband[11]; + high = s->plane[plane].subband[13]; + output = s->plane[plane].l_h[9]; + dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + if (s->sample_type == 1) + continue; + + dst = (int16_t *)pic->data[act_plane]; + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { + if (plane & 1) + dst++; + if (plane > 1) + dst += pic->linesize[act_plane] >> 1; + } + + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16 && + (lowpass_height * 2 > avctx->coded_height / 2 || + lowpass_width * 2 > avctx->coded_width / 2 ) + ) { + ret = AVERROR_INVALIDDATA; + goto end; + } + + low = s->plane[plane].l_h[6]; + high = s->plane[plane].l_h[7]; + for (i = 0; i < s->plane[act_plane].height; i++) { + dsp->horiz_filter_clip(dst, low, high, lowpass_width, s->bpc); + low += output_stride; + high += output_stride; + dst += dst_linesize; + } + } else { + pic->interlaced_frame = 1; + low = s->plane[plane].l_h[7]; + high = s->plane[plane].subband[14]; + output = s->plane[plane].l_h[6]; + dsp->horiz_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].subband[15]; + high = s->plane[plane].subband[16]; + output = s->plane[plane].l_h[7]; + dsp->horiz_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].l_h[9]; + high = s->plane[plane].subband[11]; + output = s->plane[plane].l_h[8]; + dsp->horiz_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); + + low = s->plane[plane].subband[12]; + high = s->plane[plane].subband[13]; + output = s->plane[plane].l_h[9]; + dsp->horiz_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); + + if (s->sample_type == 1) + continue; + + dst = (int16_t *)pic->data[act_plane]; + low = s->plane[plane].l_h[6]; + high = s->plane[plane].l_h[7]; + for (i = 0; i < s->plane[act_plane].height / 2; i++) { + interlaced_vertical_filter(dst, low, high, lowpass_width * 2, pic->linesize[act_plane]/2, act_plane); + low += output_stride * 2; + high += output_stride * 2; + dst += pic->linesize[act_plane]; + } } } } + if (s->transform_type == 2 && s->sample_type == 1) { + int16_t *low, *high, *dst; + int output_stride, lowpass_height, lowpass_width; + ptrdiff_t dst_linesize; + + for (plane = 0; plane < s->planes; plane++) { + int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane; + + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { + act_plane = 0; + dst_linesize = pic->linesize[act_plane]; + } else { + dst_linesize = pic->linesize[act_plane] / 2; + } + + lowpass_height = s->plane[plane].band[4][1].height; + output_stride = s->plane[plane].band[4][1].a_width; + lowpass_width = s->plane[plane].band[4][1].width; + + if (lowpass_height > s->plane[plane].band[4][1].a_height || lowpass_width > s->plane[plane].band[4][1].a_width || + s->plane[plane].band[4][1].width > s->plane[plane].band[4][1].a_width || + lowpass_width < 3 || lowpass_height < 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); + ret = AVERROR(EINVAL); + goto end; + } + + if (s->progressive) { + dst = (int16_t *)pic->data[act_plane]; + low = s->plane[plane].l_h[8]; + high = s->plane[plane].l_h[9]; + + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { + if (plane & 1) + dst++; + if (plane > 1) + dst += pic->linesize[act_plane] >> 1; + } + + if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16 && + (lowpass_height * 2 > avctx->coded_height / 2 || + lowpass_width * 2 > avctx->coded_width / 2 ) + ) { + ret = AVERROR_INVALIDDATA; + goto end; + } + + for (i = 0; i < s->plane[act_plane].height; i++) { + dsp->horiz_filter_clip(dst, low, high, lowpass_width, s->bpc); + low += output_stride; + high += output_stride; + dst += dst_linesize; + } + } else { + dst = (int16_t *)pic->data[act_plane]; + low = s->plane[plane].l_h[8]; + high = s->plane[plane].l_h[9]; + for (i = 0; i < s->plane[act_plane].height / 2; i++) { + interlaced_vertical_filter(dst, low, high, lowpass_width * 2, pic->linesize[act_plane]/2, act_plane); + low += output_stride * 2; + high += output_stride * 2; + dst += pic->linesize[act_plane]; + } + } + } + } if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) - process_bayer(pic); + process_bayer(pic, s->bpc); end: if (ret < 0) return ret; @@ -1055,15 +1413,61 @@ static av_cold int cfhd_close(AVCodecContext *avctx) return 0; } +#if HAVE_THREADS +static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) +{ + CFHDContext *psrc = src->priv_data; + CFHDContext *pdst = dst->priv_data; + int ret; + + if (dst == src || psrc->transform_type == 0) + return 0; + + if (pdst->plane[0].idwt_size != psrc->plane[0].idwt_size || + pdst->a_format != psrc->a_format || + pdst->a_width != psrc->a_width || + pdst->a_height != psrc->a_height || + pdst->a_transform_type != psrc->a_transform_type) + free_buffers(pdst); + + pdst->a_format = psrc->a_format; + pdst->a_width = psrc->a_width; + pdst->a_height = psrc->a_height; + pdst->a_transform_type = psrc->a_transform_type; + pdst->transform_type = psrc->transform_type; + pdst->progressive = psrc->progressive; + pdst->planes = psrc->planes; + + if (!pdst->plane[0].idwt_buf) { + pdst->coded_width = pdst->a_width; + pdst->coded_height = pdst->a_height; + pdst->coded_format = pdst->a_format; + pdst->transform_type = pdst->a_transform_type; + ret = alloc_buffers(dst); + if (ret < 0) + return ret; + } + + for (int plane = 0; plane < pdst->planes; plane++) { + memcpy(pdst->plane[plane].band, psrc->plane[plane].band, sizeof(pdst->plane[plane].band)); + memcpy(pdst->plane[plane].idwt_buf, psrc->plane[plane].idwt_buf, + pdst->plane[plane].idwt_size * sizeof(int16_t)); + } + + return 0; +} +#endif + AVCodec ff_cfhd_decoder = { .name = "cfhd", - .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"), + .long_name = NULL_IF_CONFIG_SMALL("GoPro CineForm HD"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CFHD, .priv_data_size = sizeof(CFHDContext), .init = cfhd_init, .close = cfhd_close, .decode = cfhd_decode, + .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h index 4f2c82d8b..19e5c7cf0 100644 --- a/libavcodec/cfhd.h +++ b/libavcodec/cfhd.h @@ -29,9 +29,75 @@ #include "bytestream.h" #include "get_bits.h" #include "vlc.h" +#include "cfhddsp.h" + +enum CFHDParam { + SampleType = 1, + SampleIndexTable = 2, + BitstreamMarker = 4, + VersionMajor = 5, + VersionMinor = 6, + VersionRevision = 7, + VersionEdit = 8, + TransformType = 10, + NumFrames = 11, + ChannelCount = 12, + WaveletCount = 13, + SubbandCount = 14, + NumSpatial = 15, + FirstWavelet = 16, + GroupTrailer = 18, + FrameType = 19, + ImageWidth = 20, + ImageHeight = 21, + FrameIndex = 23, + LowpassSubband = 25, + NumLevels = 26, + LowpassWidth = 27, + LowpassHeight = 28, + PixelOffset = 33, + LowpassQuantization=34, + LowpassPrecision = 35, + WaveletType = 37, + WaveletNumber = 38, + WaveletLevel = 39, + NumBands = 40, + HighpassWidth = 41, + HighpassHeight = 42, + LowpassBorder = 43, + HighpassBorder = 44, + LowpassScale = 45, + LowpassDivisor = 46, + SubbandNumber = 48, + BandWidth = 49, + BandHeight = 50, + SubbandBand = 51, + BandEncoding = 52, + Quantization = 53, + BandScale = 54, + BandHeader = 55, + BandTrailer = 56, + ChannelNumber = 62, + SampleFlags = 68, + FrameNumber = 69, + Precision = 70, + InputFormat = 71, + BandCodingFlags = 72, + PeakLevel = 74, + PeakOffsetLow = 75, + PeakOffsetHigh = 76, + Version = 79, + BandSecondPass = 82, + PrescaleTable = 83, + EncodedFormat = 84, + DisplayHeight = 85, + ChannelWidth = 104, + ChannelHeight = 105, +}; #define VLC_BITS 9 #define SUBBAND_COUNT 10 +#define SUBBAND_COUNT_3D 17 typedef struct CFHD_RL_VLC_ELEM { int16_t level; @@ -40,18 +106,15 @@ typedef struct CFHD_RL_VLC_ELEM { } CFHD_RL_VLC_ELEM; #define DWT_LEVELS 3 +#define DWT_LEVELS_3D 6 typedef struct SubBand { - int level; - int orientation; ptrdiff_t stride; int a_width; int width; int a_height; int height; - int pshift; - int quant; - uint8_t *ibuf; + int8_t read_ok; } SubBand; typedef struct Plane { @@ -61,12 +124,13 @@ typedef struct Plane { int16_t *idwt_buf; int16_t *idwt_tmp; + int idwt_size; /* TODO: merge this into SubBand structure */ - int16_t *subband[SUBBAND_COUNT]; - int16_t *l_h[8]; + int16_t *subband[SUBBAND_COUNT_3D]; + int16_t *l_h[10]; - SubBand band[DWT_LEVELS][4]; + SubBand band[DWT_LEVELS_3D][4]; } Plane; typedef struct Peak { @@ -84,8 +148,15 @@ typedef struct CFHDContext { CFHD_RL_VLC_ELEM table_18_rl_vlc[4572]; VLC vlc_18; + int lut[2][256]; + GetBitContext gb; + int planes; + int frame_type; + int frame_index; + int sample_type; + int transform_type; int coded_width; int coded_height; int cropped_height; @@ -95,15 +166,15 @@ typedef struct CFHDContext { int a_width; int a_height; int a_format; + int a_transform_type; int bpc; // bits per channel/component int channel_cnt; int subband_cnt; + int band_encoding; int channel_num; uint8_t lowpass_precision; uint16_t quantisation; - int wavelet_depth; - int pshift; int codebook; int difference_coding; @@ -111,9 +182,11 @@ typedef struct CFHDContext { int level; int subband_num_actual; - uint8_t prescale_shift[3]; + uint8_t prescale_table[8]; Plane plane[4]; Peak peak; + + CFHDDSPContext dsp; } CFHDContext; int ff_cfhd_init_vlcs(CFHDContext *s); diff --git a/libavcodec/cfhddsp.c b/libavcodec/cfhddsp.c new file mode 100644 index 000000000..4028263f7 --- /dev/null +++ b/libavcodec/cfhddsp.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015-2016 Kieran Kunhya + * + * 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/common.h" +#include "libavutil/avassert.h" + +#include "cfhddsp.h" + +static av_always_inline void filter(int16_t *output, ptrdiff_t out_stride, + const int16_t *low, ptrdiff_t low_stride, + const int16_t *high, ptrdiff_t high_stride, + int len, int clip) +{ + int16_t tmp; + int i; + + tmp = (11*low[0*low_stride] - 4*low[1*low_stride] + low[2*low_stride] + 4) >> 3; + output[(2*0+0)*out_stride] = (tmp + high[0*high_stride]) >> 1; + if (clip) + output[(2*0+0)*out_stride] = av_clip_uintp2_c(output[(2*0+0)*out_stride], clip); + + tmp = ( 5*low[0*low_stride] + 4*low[1*low_stride] - low[2*low_stride] + 4) >> 3; + output[(2*0+1)*out_stride] = (tmp - high[0*high_stride]) >> 1; + if (clip) + output[(2*0+1)*out_stride] = av_clip_uintp2_c(output[(2*0+1)*out_stride], clip); + + for (i = 1; i < len - 1; i++) { + tmp = (low[(i-1)*low_stride] - low[(i+1)*low_stride] + 4) >> 3; + output[(2*i+0)*out_stride] = (tmp + low[i*low_stride] + high[i*high_stride]) >> 1; + if (clip) + output[(2*i+0)*out_stride] = av_clip_uintp2_c(output[(2*i+0)*out_stride], clip); + + tmp = (low[(i+1)*low_stride] - low[(i-1)*low_stride] + 4) >> 3; + output[(2*i+1)*out_stride] = (tmp + low[i*low_stride] - high[i*high_stride]) >> 1; + if (clip) + output[(2*i+1)*out_stride] = av_clip_uintp2_c(output[(2*i+1)*out_stride], clip); + } + + tmp = ( 5*low[i*low_stride] + 4*low[(i-1)*low_stride] - low[(i-2)*low_stride] + 4) >> 3; + output[(2*i+0)*out_stride] = (tmp + high[i*high_stride]) >> 1; + if (clip) + output[(2*i+0)*out_stride] = av_clip_uintp2_c(output[(2*i+0)*out_stride], clip); + + tmp = (11*low[i*low_stride] - 4*low[(i-1)*low_stride] + low[(i-2)*low_stride] + 4) >> 3; + output[(2*i+1)*out_stride] = (tmp - high[i*high_stride]) >> 1; + if (clip) + output[(2*i+1)*out_stride] = av_clip_uintp2_c(output[(2*i+1)*out_stride], clip); +} + +static void vert_filter(int16_t *output, ptrdiff_t out_stride, + const int16_t *low, ptrdiff_t low_stride, + const int16_t *high, ptrdiff_t high_stride, + int width, int height) +{ + for (int i = 0; i < width; i++) { + filter(output, out_stride, low, low_stride, high, high_stride, height, 0); + low++; + high++; + output++; + } +} + +static void horiz_filter(int16_t *output, ptrdiff_t ostride, + const int16_t *low, ptrdiff_t lstride, + const int16_t *high, ptrdiff_t hstride, + int width, int height) +{ + for (int i = 0; i < height; i++) { + filter(output, 1, low, 1, high, 1, width, 0); + low += lstride; + high += hstride; + output += ostride * 2; + } +} + +static void horiz_filter_clip(int16_t *output, const int16_t *low, const int16_t *high, + int width, int clip) +{ + filter(output, 1, low, 1, high, 1, width, clip); +} + +static void horiz_filter_clip_bayer(int16_t *output, const int16_t *low, const int16_t *high, + int width, int clip) +{ + filter(output, 2, low, 1, high, 1, width, clip); +} + +av_cold void ff_cfhddsp_init(CFHDDSPContext *c, int depth, int bayer) +{ + c->horiz_filter = horiz_filter; + c->vert_filter = vert_filter; + + if (bayer) + c->horiz_filter_clip = horiz_filter_clip_bayer; + else + c->horiz_filter_clip = horiz_filter_clip; + + if (ARCH_X86) + ff_cfhddsp_init_x86(c, depth, bayer); +} diff --git a/libavcodec/cfhddsp.h b/libavcodec/cfhddsp.h new file mode 100644 index 000000000..8737eb324 --- /dev/null +++ b/libavcodec/cfhddsp.h @@ -0,0 +1,44 @@ +/* + * 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_CFHDDSP_H +#define AVCODEC_CFHDDSP_H + +#include +#include + +typedef struct CFHDDSPContext { + void (*horiz_filter)(int16_t *output, ptrdiff_t out_stride, + const int16_t *low, ptrdiff_t low_stride, + const int16_t *high, ptrdiff_t high_stride, + int width, int height); + + void (*vert_filter)(int16_t *output, ptrdiff_t out_stride, + const int16_t *low, ptrdiff_t low_stride, + const int16_t *high, ptrdiff_t high_stride, + int width, int height); + + void (*horiz_filter_clip)(int16_t *output, const int16_t *low, const int16_t *high, + int width, int bpc); +} CFHDDSPContext; + +void ff_cfhddsp_init(CFHDDSPContext *c, int format, int bayer); + +void ff_cfhddsp_init_x86(CFHDDSPContext *c, int format, int bayer); + +#endif /* AVCODEC_CFHDDSP_H */ diff --git a/libavcodec/cfhdenc.c b/libavcodec/cfhdenc.c new file mode 100644 index 000000000..42bbf99c9 --- /dev/null +++ b/libavcodec/cfhdenc.c @@ -0,0 +1,866 @@ +/* + * Copyright (c) 2020 Paul B Mahol + * + * 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 + * Cineform HD video encoder + */ + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/imgutils.h" +#include "libavutil/opt.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "cfhd.h" +#include "cfhdencdsp.h" +#include "put_bits.h" +#include "internal.h" +#include "thread.h" + +/* Derived from existing tables from decoder */ +static const unsigned codebook[256][2] = { + { 1, 0x00000000 }, { 2, 0x00000002 }, { 3, 0x00000007 }, { 5, 0x00000019 }, { 6, 0x00000030 }, + { 6, 0x00000036 }, { 7, 0x00000063 }, { 7, 0x0000006B }, { 7, 0x0000006F }, { 8, 0x000000D4 }, + { 8, 0x000000DC }, { 9, 0x00000189 }, { 9, 0x000001A0 }, { 9, 0x000001AB }, {10, 0x00000310 }, + {10, 0x00000316 }, {10, 0x00000354 }, {10, 0x00000375 }, {10, 0x00000377 }, {11, 0x00000623 }, + {11, 0x00000684 }, {11, 0x000006AB }, {11, 0x000006EC }, {12, 0x00000C44 }, {12, 0x00000C5C }, + {12, 0x00000C5E }, {12, 0x00000D55 }, {12, 0x00000DD1 }, {12, 0x00000DD3 }, {12, 0x00000DDB }, + {13, 0x0000188B }, {13, 0x000018BB }, {13, 0x00001AA8 }, {13, 0x00001BA0 }, {13, 0x00001BA4 }, + {13, 0x00001BB5 }, {14, 0x00003115 }, {14, 0x00003175 }, {14, 0x0000317D }, {14, 0x00003553 }, + {14, 0x00003768 }, {15, 0x00006228 }, {15, 0x000062E8 }, {15, 0x000062F8 }, {15, 0x00006AA4 }, + {15, 0x00006E85 }, {15, 0x00006E87 }, {15, 0x00006ED3 }, {16, 0x0000C453 }, {16, 0x0000C5D3 }, + {16, 0x0000C5F3 }, {16, 0x0000DD08 }, {16, 0x0000DD0C }, {16, 0x0000DDA4 }, {17, 0x000188A4 }, + {17, 0x00018BA5 }, {17, 0x00018BE5 }, {17, 0x0001AA95 }, {17, 0x0001AA97 }, {17, 0x0001BA13 }, + {17, 0x0001BB4A }, {17, 0x0001BB4B }, {18, 0x00031748 }, {18, 0x000317C8 }, {18, 0x00035528 }, + {18, 0x0003552C }, {18, 0x00037424 }, {18, 0x00037434 }, {18, 0x00037436 }, {19, 0x00062294 }, + {19, 0x00062E92 }, {19, 0x00062F92 }, {19, 0x0006AA52 }, {19, 0x0006AA5A }, {19, 0x0006E84A }, + {19, 0x0006E86A }, {19, 0x0006E86E }, {20, 0x000C452A }, {20, 0x000C5D27 }, {20, 0x000C5F26 }, + {20, 0x000D54A6 }, {20, 0x000D54B6 }, {20, 0x000DD096 }, {20, 0x000DD0D6 }, {20, 0x000DD0DE }, + {21, 0x00188A56 }, {21, 0x0018BA4D }, {21, 0x0018BE4E }, {21, 0x0018BE4F }, {21, 0x001AA96E }, + {21, 0x001BA12E }, {21, 0x001BA12F }, {21, 0x001BA1AF }, {21, 0x001BA1BF }, {22, 0x00317498 }, + {22, 0x0035529C }, {22, 0x0035529D }, {22, 0x003552DE }, {22, 0x003552DF }, {22, 0x0037435D }, + {22, 0x0037437D }, {23, 0x0062295D }, {23, 0x0062E933 }, {23, 0x006AA53D }, {23, 0x006AA53E }, + {23, 0x006AA53F }, {23, 0x006E86B9 }, {23, 0x006E86F8 }, {24, 0x00C452B8 }, {24, 0x00C5D265 }, + {24, 0x00D54A78 }, {24, 0x00D54A79 }, {24, 0x00DD0D70 }, {24, 0x00DD0D71 }, {24, 0x00DD0DF2 }, + {24, 0x00DD0DF3 }, {26, 0x03114BA2 }, {25, 0x0188A5B1 }, {25, 0x0188A58B }, {25, 0x0188A595 }, + {25, 0x0188A5D6 }, {25, 0x0188A5D7 }, {25, 0x0188A5A8 }, {25, 0x0188A5AE }, {25, 0x0188A5AF }, + {25, 0x0188A5C4 }, {25, 0x0188A5C5 }, {25, 0x0188A587 }, {25, 0x0188A584 }, {25, 0x0188A585 }, + {25, 0x0188A5C6 }, {25, 0x0188A5C7 }, {25, 0x0188A5CC }, {25, 0x0188A5CD }, {25, 0x0188A581 }, + {25, 0x0188A582 }, {25, 0x0188A583 }, {25, 0x0188A5CE }, {25, 0x0188A5CF }, {25, 0x0188A5C2 }, + {25, 0x0188A5C3 }, {25, 0x0188A5C1 }, {25, 0x0188A5B4 }, {25, 0x0188A5B5 }, {25, 0x0188A5E6 }, + {25, 0x0188A5E7 }, {25, 0x0188A5E4 }, {25, 0x0188A5E5 }, {25, 0x0188A5AB }, {25, 0x0188A5E0 }, + {25, 0x0188A5E1 }, {25, 0x0188A5E2 }, {25, 0x0188A5E3 }, {25, 0x0188A5B6 }, {25, 0x0188A5B7 }, + {25, 0x0188A5FD }, {25, 0x0188A57E }, {25, 0x0188A57F }, {25, 0x0188A5EC }, {25, 0x0188A5ED }, + {25, 0x0188A5FE }, {25, 0x0188A5FF }, {25, 0x0188A57D }, {25, 0x0188A59C }, {25, 0x0188A59D }, + {25, 0x0188A5E8 }, {25, 0x0188A5E9 }, {25, 0x0188A5EA }, {25, 0x0188A5EB }, {25, 0x0188A5EF }, + {25, 0x0188A57A }, {25, 0x0188A57B }, {25, 0x0188A578 }, {25, 0x0188A579 }, {25, 0x0188A5BA }, + {25, 0x0188A5BB }, {25, 0x0188A5B8 }, {25, 0x0188A5B9 }, {25, 0x0188A588 }, {25, 0x0188A589 }, + {25, 0x018BA4C8 }, {25, 0x018BA4C9 }, {25, 0x0188A5FA }, {25, 0x0188A5FB }, {25, 0x0188A5BC }, + {25, 0x0188A5BD }, {25, 0x0188A598 }, {25, 0x0188A599 }, {25, 0x0188A5F4 }, {25, 0x0188A5F5 }, + {25, 0x0188A59B }, {25, 0x0188A5DE }, {25, 0x0188A5DF }, {25, 0x0188A596 }, {25, 0x0188A597 }, + {25, 0x0188A5F8 }, {25, 0x0188A5F9 }, {25, 0x0188A5F1 }, {25, 0x0188A58E }, {25, 0x0188A58F }, + {25, 0x0188A5DC }, {25, 0x0188A5DD }, {25, 0x0188A5F2 }, {25, 0x0188A5F3 }, {25, 0x0188A58C }, + {25, 0x0188A58D }, {25, 0x0188A5A4 }, {25, 0x0188A5F0 }, {25, 0x0188A5A5 }, {25, 0x0188A5A6 }, + {25, 0x0188A5A7 }, {25, 0x0188A59A }, {25, 0x0188A5A2 }, {25, 0x0188A5A3 }, {25, 0x0188A58A }, + {25, 0x0188A5B0 }, {25, 0x0188A5A0 }, {25, 0x0188A5A1 }, {25, 0x0188A5DA }, {25, 0x0188A5DB }, + {25, 0x0188A59E }, {25, 0x0188A59F }, {25, 0x0188A5D8 }, {25, 0x0188A5EE }, {25, 0x0188A5D9 }, + {25, 0x0188A5F6 }, {25, 0x0188A5F7 }, {25, 0x0188A57C }, {25, 0x0188A5C8 }, {25, 0x0188A5C9 }, + {25, 0x0188A594 }, {25, 0x0188A5FC }, {25, 0x0188A5CA }, {25, 0x0188A5CB }, {25, 0x0188A5B2 }, + {25, 0x0188A5AA }, {25, 0x0188A5B3 }, {25, 0x0188A572 }, {25, 0x0188A573 }, {25, 0x0188A5C0 }, + {25, 0x0188A5BE }, {25, 0x0188A5BF }, {25, 0x0188A592 }, {25, 0x0188A580 }, {25, 0x0188A593 }, + {25, 0x0188A590 }, {25, 0x0188A591 }, {25, 0x0188A586 }, {25, 0x0188A5A9 }, {25, 0x0188A5D2 }, + {25, 0x0188A5D3 }, {25, 0x0188A5D4 }, {25, 0x0188A5D5 }, {25, 0x0188A5AC }, {25, 0x0188A5AD }, + {25, 0x0188A5D0 }, +}; + +/* Derived by extracting runcodes from existing tables from decoder */ +static const uint16_t runbook[18][3] = { + {1, 0x0000, 1}, {2, 0x0000, 2}, {3, 0x0000, 3}, {4, 0x0000, 4}, + {5, 0x0000, 5}, {6, 0x0000, 6}, {7, 0x0000, 7}, {8, 0x0000, 8}, + {9, 0x0000, 9}, {10, 0x0000, 10}, {11, 0x0000, 11}, + {7, 0x0069, 12}, {8, 0x00D1, 20}, {9, 0x018A, 32}, + {10, 0x0343, 60}, {11, 0x0685, 100}, {13, 0x18BF, 180}, {13, 0x1BA5, 320}, +}; + +/* + * Derived by inspecting various quality encodes + * and adding some more from scratch. + */ +static const uint16_t quantization_per_subband[2][3][13][9] = { + {{ + { 16, 16, 8, 4, 4, 2, 6, 6, 9, }, // film3+ + { 16, 16, 8, 4, 4, 2, 6, 6, 9, }, // film3 + { 16, 16, 8, 4, 4, 2, 7, 7, 10, }, // film2+ + { 16, 16, 8, 4, 4, 2, 8, 8, 12, }, // film2 + { 16, 16, 8, 4, 4, 2, 16, 16, 26, }, // film1++ + { 24, 24, 12, 6, 6, 3, 24, 24, 36, }, // film1+ + { 24, 24, 12, 6, 6, 3, 24, 24, 36, }, // film1 + { 32, 32, 24, 8, 8, 6, 32, 32, 48, }, // high+ + { 32, 32, 24, 8, 8, 6, 32, 32, 48, }, // high + { 48, 48, 32, 12, 12, 8, 64, 64, 96, }, // medium+ + { 48, 48, 32, 12, 12, 8, 64, 64, 96, }, // medium + { 64, 64, 48, 16, 16, 12, 96, 96, 144, }, // low+ + { 64, 64, 48, 16, 16, 12, 128, 128, 192, }, // low + }, + { + { 16, 16, 8, 4, 4, 2, 6, 6, 9, }, // film3+ + { 16, 16, 8, 4, 4, 2, 6, 6, 12, }, // film3 + { 16, 16, 8, 4, 4, 2, 7, 7, 14, }, // film2+ + { 16, 16, 8, 4, 4, 2, 8, 8, 16, }, // film2 + { 16, 16, 8, 4, 4, 2, 16, 16, 26, }, // film1++ + { 24, 24, 12, 6, 6, 3, 24, 24, 36, }, // film1+ + { 24, 24, 12, 6, 6, 3, 24, 24, 48, }, // film1 + { 32, 32, 24, 8, 8, 6, 32, 32, 48, }, // high+ + { 48, 48, 32, 12, 12, 8, 32, 32, 64, }, // high + { 48, 48, 32, 12, 12, 8, 64, 64, 96, }, // medium+ + { 48, 48, 32, 12, 12, 8, 64, 64, 128, }, // medium + { 64, 64, 48, 16, 16, 12, 96, 96, 160, }, // low+ + { 64, 64, 48, 16, 16, 12, 128, 128, 192, }, // low + }, + { + { 16, 16, 8, 4, 4, 2, 6, 6, 9, }, // film3+ + { 16, 16, 8, 4, 4, 2, 6, 6, 12, }, // film3 + { 16, 16, 8, 4, 4, 2, 7, 7, 14, }, // film2+ + { 16, 16, 8, 4, 4, 2, 8, 8, 16, }, // film2 + { 16, 16, 8, 4, 4, 2, 16, 16, 26, }, // film1++ + { 24, 24, 12, 6, 6, 3, 24, 24, 36, }, // film1+ + { 24, 24, 12, 6, 6, 3, 24, 24, 48, }, // film1 + { 32, 32, 24, 8, 8, 6, 32, 32, 48, }, // high+ + { 48, 48, 32, 12, 12, 8, 32, 32, 64, }, // high + { 48, 48, 32, 12, 12, 8, 64, 64, 96, }, // medium+ + { 48, 48, 32, 12, 12, 8, 64, 64, 128, }, // medium + { 64, 64, 48, 16, 16, 12, 96, 96, 160, }, // low+ + { 64, 64, 48, 16, 16, 12, 128, 128, 192, }, // low + }}, + {{ + { 16, 16, 8, 16, 16, 8, 24, 24, 36, }, // film3+ + { 16, 16, 8, 16, 16, 8, 24, 24, 36, }, // film3 + { 16, 16, 8, 16, 16, 8, 32, 32, 48, }, // film2+ + { 16, 16, 8, 16, 16, 8, 32, 32, 48, }, // film2 + { 16, 16, 8, 20, 20, 10, 80, 80, 128, }, // film1++ + { 24, 24, 12, 24, 24, 12, 96, 96, 144, }, // film1+ + { 24, 24, 12, 24, 24, 12, 96, 96, 144, }, // film1 + { 32, 32, 24, 32, 32, 24, 128, 128, 192, }, // high+ + { 32, 32, 24, 32, 32, 24, 128, 128, 192, }, // high + { 48, 48, 32, 48, 48, 32, 256, 256, 384, }, // medium+ + { 48, 48, 32, 48, 48, 32, 256, 256, 384, }, // medium + { 56, 56, 40, 56, 56, 40, 512, 512, 768, }, // low+ + { 64, 64, 48, 64, 64, 48, 512, 512, 768, }, // low + }, + { + { 16, 16, 8, 16, 16, 8, 24, 24, 36, }, // film3+ + { 16, 16, 8, 16, 16, 8, 48, 48, 72, }, // film3 + { 16, 16, 8, 16, 16, 8, 48, 48, 72, }, // film2+ + { 16, 16, 8, 16, 16, 8, 64, 64, 96, }, // film2 + { 16, 16, 8, 20, 20, 10, 80, 80, 128, }, // film1++ + { 24, 24, 12, 24, 24, 12, 96, 96, 144, }, // film1+ + { 24, 24, 12, 24, 24, 12, 192, 192, 288, }, // film1 + { 32, 32, 24, 32, 32, 24, 128, 128, 192, }, // high+ + { 32, 32, 24, 32, 32, 24, 256, 256, 384, }, // high + { 48, 48, 32, 48, 48, 32, 256, 256, 384, }, // medium+ + { 48, 48, 32, 48, 48, 32, 512, 512, 768, }, // medium + { 56, 56, 40, 56, 56, 40, 512, 512, 768, }, // low+ + { 64, 64, 48, 64, 64, 48,1024,1024,1536, }, // low + }, + { + { 16, 16, 8, 16, 16, 8, 24, 24, 36, }, // film3+ + { 16, 16, 8, 16, 16, 8, 48, 48, 72, }, // film3 + { 16, 16, 8, 16, 16, 8, 48, 48, 72, }, // film2+ + { 16, 16, 8, 16, 16, 8, 64, 64, 96, }, // film2 + { 16, 16, 10, 20, 20, 10, 80, 80, 128, }, // film1++ + { 24, 24, 12, 24, 24, 12, 96, 96, 144, }, // film1+ + { 24, 24, 12, 24, 24, 12, 192, 192, 288, }, // film1 + { 32, 32, 24, 32, 32, 24, 128, 128, 192, }, // high+ + { 32, 32, 24, 32, 32, 24, 256, 256, 384, }, // high + { 48, 48, 32, 48, 48, 32, 256, 256, 384, }, // medium+ + { 48, 48, 32, 48, 48, 32, 512, 512, 768, }, // medium + { 56, 56, 40, 56, 56, 40, 512, 512, 768, }, // low+ + { 64, 64, 48, 64, 64, 48,1024,1024,1536, }, // low + }}, +}; + +typedef struct Codebook { + unsigned bits; + unsigned size; +} Codebook; + +typedef struct Runbook { + unsigned size; + unsigned bits; + unsigned run; +} Runbook; + +typedef struct PlaneEnc { + unsigned size; + + int16_t *dwt_buf; + int16_t *dwt_tmp; + + unsigned quantization[SUBBAND_COUNT]; + int16_t *subband[SUBBAND_COUNT]; + int16_t *l_h[8]; + + SubBand band[DWT_LEVELS][4]; +} PlaneEnc; + +typedef struct CFHDEncContext { + const AVClass *class; + + PutBitContext pb; + PutByteContext pby; + + int quality; + int planes; + int chroma_h_shift; + int chroma_v_shift; + PlaneEnc plane[4]; + + uint16_t lut[1024]; + Runbook rb[321]; + Codebook cb[513]; + int16_t *alpha; + + CFHDEncDSPContext dsp; +} CFHDEncContext; + +static av_cold int cfhd_encode_init(AVCodecContext *avctx) +{ + CFHDEncContext *s = avctx->priv_data; + const int sign_mask = 256; + const int twos_complement = -sign_mask; + const int mag_mask = sign_mask - 1; + int ret, last = 0; + + ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, + &s->chroma_h_shift, + &s->chroma_v_shift); + if (ret < 0) + return ret; + + if (avctx->width & 15) { + av_log(avctx, AV_LOG_ERROR, "Width must be multiple of 16.\n"); + return AVERROR_INVALIDDATA; + } + + s->planes = av_pix_fmt_count_planes(avctx->pix_fmt); + + for (int i = 0; i < s->planes; i++) { + int w8, h8, w4, h4, w2, h2; + int width = i ? avctx->width >> s->chroma_h_shift : avctx->width; + int height = i ? FFALIGN(avctx->height >> s->chroma_v_shift, 8) : + FFALIGN(avctx->height >> s->chroma_v_shift, 8); + ptrdiff_t stride = (FFALIGN(width / 8, 8) + 64) * 8; + + w8 = FFALIGN(width / 8, 8) + 64; + h8 = FFALIGN(height, 8) / 8; + w4 = w8 * 2; + h4 = h8 * 2; + w2 = w4 * 2; + h2 = h4 * 2; + + s->plane[i].dwt_buf = + av_mallocz_array(height * stride, sizeof(*s->plane[i].dwt_buf)); + s->plane[i].dwt_tmp = + av_malloc_array(height * stride, sizeof(*s->plane[i].dwt_tmp)); + if (!s->plane[i].dwt_buf || !s->plane[i].dwt_tmp) + return AVERROR(ENOMEM); + + s->plane[i].subband[0] = s->plane[i].dwt_buf; + s->plane[i].subband[1] = s->plane[i].dwt_buf + 2 * w8 * h8; + s->plane[i].subband[2] = s->plane[i].dwt_buf + 1 * w8 * h8; + s->plane[i].subband[3] = s->plane[i].dwt_buf + 3 * w8 * h8; + s->plane[i].subband[4] = s->plane[i].dwt_buf + 2 * w4 * h4; + s->plane[i].subband[5] = s->plane[i].dwt_buf + 1 * w4 * h4; + s->plane[i].subband[6] = s->plane[i].dwt_buf + 3 * w4 * h4; + s->plane[i].subband[7] = s->plane[i].dwt_buf + 2 * w2 * h2; + s->plane[i].subband[8] = s->plane[i].dwt_buf + 1 * w2 * h2; + s->plane[i].subband[9] = s->plane[i].dwt_buf + 3 * w2 * h2; + + for (int j = 0; j < DWT_LEVELS; j++) { + for (int k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { + s->plane[i].band[j][k].width = (width / 8) << j; + s->plane[i].band[j][k].height = (height / 8) << j; + s->plane[i].band[j][k].a_width = w8 << j; + s->plane[i].band[j][k].a_height = h8 << j; + } + } + + /* ll2 and ll1 commented out because they are done in-place */ + s->plane[i].l_h[0] = s->plane[i].dwt_tmp; + s->plane[i].l_h[1] = s->plane[i].dwt_tmp + 2 * w8 * h8; + // s->plane[i].l_h[2] = ll2; + s->plane[i].l_h[3] = s->plane[i].dwt_tmp; + s->plane[i].l_h[4] = s->plane[i].dwt_tmp + 2 * w4 * h4; + // s->plane[i].l_h[5] = ll1; + s->plane[i].l_h[6] = s->plane[i].dwt_tmp; + s->plane[i].l_h[7] = s->plane[i].dwt_tmp + 2 * w2 * h2; + } + + for (int i = 0; i < 512; i++) { + int value = (i & sign_mask) ? twos_complement + (i & mag_mask): i; + int mag = FFMIN(FFABS(value), 255); + + if (mag) { + s->cb[i].bits = (codebook[mag][1] << 1) | (value > 0 ? 0 : 1); + s->cb[i].size = codebook[mag][0] + 1; + } else { + s->cb[i].bits = codebook[mag][1]; + s->cb[i].size = codebook[mag][0]; + } + } + + s->cb[512].bits = 0x3114ba3; + s->cb[512].size = 26; + + s->rb[0].run = 0; + + for (int i = 1, j = 0; i < 320 && j < 17; j++) { + int run = runbook[j][2]; + int end = runbook[j+1][2]; + + while (i < end) { + s->rb[i].run = run; + s->rb[i].bits = runbook[j][1]; + s->rb[i++].size = runbook[j][0]; + } + } + + s->rb[320].bits = runbook[17][1]; + s->rb[320].size = runbook[17][0]; + s->rb[320].run = 320; + + for (int i = 0; i < 256; i++) { + int idx = i + ((768LL * i * i * i) / (256 * 256 * 256)); + + s->lut[idx] = i; + } + for (int i = 0; i < 1024; i++) { + if (s->lut[i]) + last = s->lut[i]; + else + s->lut[i] = last; + } + + ff_cfhdencdsp_init(&s->dsp); + + if (s->planes != 4) + return 0; + + s->alpha = av_calloc(avctx->width * avctx->height, sizeof(*s->alpha)); + if (!s->alpha) + return AVERROR(ENOMEM); + + return 0; +} + +static void quantize_band(int16_t *input, int width, int a_width, + int height, unsigned quantization) +{ + const int16_t factor = (uint32_t)(1U << 15) / quantization; + + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) + input[j] = av_clip_intp2(((input[j] * factor + 16384 * FFSIGN(input[j])) / 32768), 10); + input += a_width; + } +} + +static int put_runcode(PutBitContext *pb, int count, const Runbook *const rb) +{ + while (count > 0) { + const int index = FFMIN(320, count); + + put_bits(pb, rb[index].size, rb[index].bits); + count -= rb[index].run; + } + + return 0; +} + +static void process_alpha(const int16_t *src, int width, int height, ptrdiff_t stride, int16_t *dst) +{ + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + int alpha = src[j]; + + if (alpha > 0 && alpha < 4080) { + alpha *= 223; + alpha += 128; + alpha >>= 8; + alpha += 256; + } + + dst[j] = av_clip_uintp2(alpha, 12); + } + + src += stride; + dst += width; + } +} + +static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *frame, int *got_packet) +{ + CFHDEncContext *s = avctx->priv_data; + CFHDEncDSPContext *dsp = &s->dsp; + PutByteContext *pby = &s->pby; + PutBitContext *pb = &s->pb; + const Codebook *const cb = s->cb; + const Runbook *const rb = s->rb; + const uint16_t *lut = s->lut; + unsigned pos; + int ret; + + for (int plane = 0; plane < s->planes; plane++) { + int width = s->plane[plane].band[2][0].width; + int a_width = s->plane[plane].band[2][0].a_width; + int height = s->plane[plane].band[2][0].height; + int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane; + int16_t *input = (int16_t *)frame->data[act_plane]; + int16_t *low = s->plane[plane].l_h[6]; + int16_t *high = s->plane[plane].l_h[7]; + ptrdiff_t in_stride = frame->linesize[act_plane] / 2; + int low_stride, high_stride; + + if (plane == 3) { + process_alpha(input, avctx->width, avctx->height, + in_stride, s->alpha); + input = s->alpha; + in_stride = avctx->width; + } + + dsp->horiz_filter(input, low, high, + in_stride, a_width, a_width, + width * 2, height * 2); + + input = s->plane[plane].l_h[7]; + low = s->plane[plane].subband[7]; + low_stride = s->plane[plane].band[2][0].a_width; + high = s->plane[plane].subband[9]; + high_stride = s->plane[plane].band[2][0].a_width; + + dsp->vert_filter(input, low, high, + a_width, low_stride, high_stride, + width, height * 2); + + input = s->plane[plane].l_h[6]; + low = s->plane[plane].l_h[7]; + high = s->plane[plane].subband[8]; + + dsp->vert_filter(input, low, high, + a_width, low_stride, high_stride, + width, height * 2); + + a_width = s->plane[plane].band[1][0].a_width; + width = s->plane[plane].band[1][0].width; + height = s->plane[plane].band[1][0].height; + input = s->plane[plane].l_h[7]; + low = s->plane[plane].l_h[3]; + low_stride = s->plane[plane].band[1][0].a_width; + high = s->plane[plane].l_h[4]; + high_stride = s->plane[plane].band[1][0].a_width; + + for (int i = 0; i < height * 2; i++) { + for (int j = 0; j < width * 2; j++) + input[j] /= 4; + input += a_width * 2; + } + + input = s->plane[plane].l_h[7]; + dsp->horiz_filter(input, low, high, + a_width * 2, low_stride, high_stride, + width * 2, height * 2); + + input = s->plane[plane].l_h[4]; + low = s->plane[plane].subband[4]; + high = s->plane[plane].subband[6]; + + dsp->vert_filter(input, low, high, + a_width, low_stride, high_stride, + width, height * 2); + + input = s->plane[plane].l_h[3]; + low = s->plane[plane].l_h[4]; + high = s->plane[plane].subband[5]; + + dsp->vert_filter(input, low, high, + a_width, low_stride, high_stride, + width, height * 2); + + a_width = s->plane[plane].band[0][0].a_width; + width = s->plane[plane].band[0][0].width; + height = s->plane[plane].band[0][0].height; + input = s->plane[plane].l_h[4]; + low = s->plane[plane].l_h[0]; + low_stride = s->plane[plane].band[0][0].a_width; + high = s->plane[plane].l_h[1]; + high_stride = s->plane[plane].band[0][0].a_width; + + if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) { + for (int i = 0; i < height * 2; i++) { + for (int j = 0; j < width * 2; j++) + input[j] /= 4; + input += a_width * 2; + } + } + + input = s->plane[plane].l_h[4]; + dsp->horiz_filter(input, low, high, + a_width * 2, low_stride, high_stride, + width * 2, height * 2); + + low = s->plane[plane].subband[1]; + high = s->plane[plane].subband[3]; + input = s->plane[plane].l_h[1]; + + dsp->vert_filter(input, low, high, + a_width, low_stride, high_stride, + width, height * 2); + + low = s->plane[plane].subband[0]; + high = s->plane[plane].subband[2]; + input = s->plane[plane].l_h[0]; + + dsp->vert_filter(input, low, high, + a_width, low_stride, high_stride, + width, height * 2); + } + + ret = ff_alloc_packet2(avctx, pkt, 64LL + s->planes * (2LL * avctx->width * avctx->height + 1000LL), 0); + if (ret < 0) + return ret; + + bytestream2_init_writer(pby, pkt->data, pkt->size); + + bytestream2_put_be16(pby, SampleType); + bytestream2_put_be16(pby, 9); + + bytestream2_put_be16(pby, SampleIndexTable); + bytestream2_put_be16(pby, s->planes); + + for (int i = 0; i < s->planes; i++) + bytestream2_put_be32(pby, 0); + + bytestream2_put_be16(pby, TransformType); + bytestream2_put_be16(pby, 0); + + bytestream2_put_be16(pby, NumFrames); + bytestream2_put_be16(pby, 1); + + bytestream2_put_be16(pby, ChannelCount); + bytestream2_put_be16(pby, s->planes); + + bytestream2_put_be16(pby, EncodedFormat); + bytestream2_put_be16(pby, avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 1 : 3 + (s->planes == 4)); + + bytestream2_put_be16(pby, WaveletCount); + bytestream2_put_be16(pby, 3); + + bytestream2_put_be16(pby, SubbandCount); + bytestream2_put_be16(pby, SUBBAND_COUNT); + + bytestream2_put_be16(pby, NumSpatial); + bytestream2_put_be16(pby, 2); + + bytestream2_put_be16(pby, FirstWavelet); + bytestream2_put_be16(pby, 3); + + bytestream2_put_be16(pby, ImageWidth); + bytestream2_put_be16(pby, avctx->width); + + bytestream2_put_be16(pby, ImageHeight); + bytestream2_put_be16(pby, avctx->height); + + bytestream2_put_be16(pby, -FrameNumber); + bytestream2_put_be16(pby, frame->pts & 0xFFFF); + + bytestream2_put_be16(pby, Precision); + bytestream2_put_be16(pby, avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 10 : 12); + + bytestream2_put_be16(pby, PrescaleTable); + bytestream2_put_be16(pby, avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 0x2000 : 0x2800); + + bytestream2_put_be16(pby, SampleFlags); + bytestream2_put_be16(pby, 1); + + for (int p = 0; p < s->planes; p++) { + int width = s->plane[p].band[0][0].width; + int a_width = s->plane[p].band[0][0].a_width; + int height = s->plane[p].band[0][0].height; + int16_t *data = s->plane[p].subband[0]; + + if (p) { + bytestream2_put_be16(pby, SampleType); + bytestream2_put_be16(pby, 3); + + bytestream2_put_be16(pby, ChannelNumber); + bytestream2_put_be16(pby, p); + } + + bytestream2_put_be16(pby, BitstreamMarker); + bytestream2_put_be16(pby, 0x1a4a); + + pos = bytestream2_tell_p(pby); + + bytestream2_put_be16(pby, LowpassSubband); + bytestream2_put_be16(pby, 0); + + bytestream2_put_be16(pby, NumLevels); + bytestream2_put_be16(pby, 3); + + bytestream2_put_be16(pby, LowpassWidth); + bytestream2_put_be16(pby, width); + + bytestream2_put_be16(pby, LowpassHeight); + bytestream2_put_be16(pby, height); + + bytestream2_put_be16(pby, PixelOffset); + bytestream2_put_be16(pby, 0); + + bytestream2_put_be16(pby, LowpassQuantization); + bytestream2_put_be16(pby, 1); + + bytestream2_put_be16(pby, LowpassPrecision); + bytestream2_put_be16(pby, 16); + + bytestream2_put_be16(pby, BitstreamMarker); + bytestream2_put_be16(pby, 0x0f0f); + + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) + bytestream2_put_be16(pby, data[j]); + data += a_width; + } + + bytestream2_put_be16(pby, BitstreamMarker); + bytestream2_put_be16(pby, 0x1b4b); + + for (int l = 0; l < 3; l++) { + for (int i = 0; i < 3; i++) { + s->plane[p].quantization[1 + l * 3 + i] = quantization_per_subband[avctx->pix_fmt != AV_PIX_FMT_YUV422P10][p >= 3 ? 0 : p][s->quality][l * 3 + i]; + } + } + + for (int l = 0; l < 3; l++) { + int a_width = s->plane[p].band[l][0].a_width; + int width = s->plane[p].band[l][0].width; + int stride = FFALIGN(width, 8); + int height = s->plane[p].band[l][0].height; + + bytestream2_put_be16(pby, BitstreamMarker); + bytestream2_put_be16(pby, 0x0d0d); + + bytestream2_put_be16(pby, WaveletType); + bytestream2_put_be16(pby, 3 + 2 * (l == 2)); + + bytestream2_put_be16(pby, WaveletNumber); + bytestream2_put_be16(pby, 3 - l); + + bytestream2_put_be16(pby, WaveletLevel); + bytestream2_put_be16(pby, 3 - l); + + bytestream2_put_be16(pby, NumBands); + bytestream2_put_be16(pby, 4); + + bytestream2_put_be16(pby, HighpassWidth); + bytestream2_put_be16(pby, width); + + bytestream2_put_be16(pby, HighpassHeight); + bytestream2_put_be16(pby, height); + + bytestream2_put_be16(pby, LowpassBorder); + bytestream2_put_be16(pby, 0); + + bytestream2_put_be16(pby, HighpassBorder); + bytestream2_put_be16(pby, 0); + + bytestream2_put_be16(pby, LowpassScale); + bytestream2_put_be16(pby, 1); + + bytestream2_put_be16(pby, LowpassDivisor); + bytestream2_put_be16(pby, 1); + + for (int i = 0; i < 3; i++) { + int16_t *data = s->plane[p].subband[1 + l * 3 + i]; + int count = 0, padd = 0; + + bytestream2_put_be16(pby, BitstreamMarker); + bytestream2_put_be16(pby, 0x0e0e); + + bytestream2_put_be16(pby, SubbandNumber); + bytestream2_put_be16(pby, i + 1); + + bytestream2_put_be16(pby, BandCodingFlags); + bytestream2_put_be16(pby, 1); + + bytestream2_put_be16(pby, BandWidth); + bytestream2_put_be16(pby, width); + + bytestream2_put_be16(pby, BandHeight); + bytestream2_put_be16(pby, height); + + bytestream2_put_be16(pby, SubbandBand); + bytestream2_put_be16(pby, 1 + l * 3 + i); + + bytestream2_put_be16(pby, BandEncoding); + bytestream2_put_be16(pby, 3); + + bytestream2_put_be16(pby, Quantization); + bytestream2_put_be16(pby, s->plane[p].quantization[1 + l * 3 + i]); + + bytestream2_put_be16(pby, BandScale); + bytestream2_put_be16(pby, 1); + + bytestream2_put_be16(pby, BandHeader); + bytestream2_put_be16(pby, 0); + + quantize_band(data, width, a_width, height, + s->plane[p].quantization[1 + l * 3 + i]); + + init_put_bits(pb, pkt->data + bytestream2_tell_p(pby), bytestream2_get_bytes_left_p(pby)); + + for (int m = 0; m < height; m++) { + for (int j = 0; j < stride; j++) { + int16_t index = j >= width ? 0 : FFSIGN(data[j]) * lut[FFABS(data[j])]; + + if (index < 0) + index += 512; + if (index == 0) { + count++; + continue; + } else if (count > 0) { + count = put_runcode(pb, count, rb); + } + + put_bits(pb, cb[index].size, cb[index].bits); + } + + data += a_width; + } + + if (count > 0) { + count = put_runcode(pb, count, rb); + } + + put_bits(pb, cb[512].size, cb[512].bits); + + flush_put_bits(pb); + bytestream2_skip_p(pby, put_bits_count(pb) >> 3); + padd = (4 - (bytestream2_tell_p(pby) & 3)) & 3; + while (padd--) + bytestream2_put_byte(pby, 0); + + bytestream2_put_be16(pby, BandTrailer); + bytestream2_put_be16(pby, 0); + } + + bytestream2_put_be16(pby, BitstreamMarker); + bytestream2_put_be16(pby, 0x0c0c); + } + + s->plane[p].size = bytestream2_tell_p(pby) - pos; + } + + bytestream2_put_be16(pby, GroupTrailer); + bytestream2_put_be16(pby, 0); + + av_shrink_packet(pkt, bytestream2_tell_p(pby)); + + pkt->flags |= AV_PKT_FLAG_KEY; + + bytestream2_seek_p(pby, 8, SEEK_SET); + for (int i = 0; i < s->planes; i++) + bytestream2_put_be32(pby, s->plane[i].size); + + *got_packet = 1; + + return 0; +} + +static av_cold int cfhd_encode_close(AVCodecContext *avctx) +{ + CFHDEncContext *s = avctx->priv_data; + + for (int i = 0; i < s->planes; i++) { + av_freep(&s->plane[i].dwt_buf); + av_freep(&s->plane[i].dwt_tmp); + + for (int j = 0; j < SUBBAND_COUNT; j++) + s->plane[i].subband[j] = NULL; + + for (int j = 0; j < 8; j++) + s->plane[i].l_h[j] = NULL; + } + + av_freep(&s->alpha); + + return 0; +} + +#define OFFSET(x) offsetof(CFHDEncContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "quality", "set quality", OFFSET(quality), AV_OPT_TYPE_INT, {.i64= 0}, 0, 12, VE, "q" }, + { "film3+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 0}, 0, 0, VE, "q" }, + { "film3", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 1}, 0, 0, VE, "q" }, + { "film2+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 2}, 0, 0, VE, "q" }, + { "film2", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 3}, 0, 0, VE, "q" }, + { "film1.5", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 4}, 0, 0, VE, "q" }, + { "film1+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 5}, 0, 0, VE, "q" }, + { "film1", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 6}, 0, 0, VE, "q" }, + { "high+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 7}, 0, 0, VE, "q" }, + { "high", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 8}, 0, 0, VE, "q" }, + { "medium+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 9}, 0, 0, VE, "q" }, + { "medium", NULL, 0, AV_OPT_TYPE_CONST, {.i64=10}, 0, 0, VE, "q" }, + { "low+", NULL, 0, AV_OPT_TYPE_CONST, {.i64=11}, 0, 0, VE, "q" }, + { "low", NULL, 0, AV_OPT_TYPE_CONST, {.i64=12}, 0, 0, VE, "q" }, + { NULL}, +}; + +static const AVClass cfhd_class = { + .class_name = "cfhd", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_cfhd_encoder = { + .name = "cfhd", + .long_name = NULL_IF_CONFIG_SMALL("GoPro CineForm HD"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_CFHD, + .priv_data_size = sizeof(CFHDEncContext), + .priv_class = &cfhd_class, + .init = cfhd_encode_init, + .close = cfhd_encode_close, + .encode2 = cfhd_encode_frame, + .capabilities = AV_CODEC_CAP_FRAME_THREADS, + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_YUV422P10, + AV_PIX_FMT_GBRP12, + AV_PIX_FMT_GBRAP12, + AV_PIX_FMT_NONE + }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, +}; diff --git a/libavcodec/cfhdencdsp.c b/libavcodec/cfhdencdsp.c new file mode 100644 index 000000000..b979e9e09 --- /dev/null +++ b/libavcodec/cfhdencdsp.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015-2016 Kieran Kunhya + * + * 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/common.h" +#include "libavutil/avassert.h" + +#include "cfhdencdsp.h" + +static av_always_inline void filter(int16_t *input, ptrdiff_t in_stride, + int16_t *low, ptrdiff_t low_stride, + int16_t *high, ptrdiff_t high_stride, + int len) +{ + low[(0>>1) * low_stride] = av_clip_int16(input[0*in_stride] + input[1*in_stride]); + high[(0>>1) * high_stride] = av_clip_int16((5 * input[0*in_stride] - 11 * input[1*in_stride] + + 4 * input[2*in_stride] + 4 * input[3*in_stride] - + 1 * input[4*in_stride] - 1 * input[5*in_stride] + 4) >> 3); + + for (int i = 2; i < len - 2; i += 2) { + low[(i>>1) * low_stride] = av_clip_int16(input[i*in_stride] + input[(i+1)*in_stride]); + high[(i>>1) * high_stride] = av_clip_int16(((-input[(i-2)*in_stride] - input[(i-1)*in_stride] + + input[(i+2)*in_stride] + input[(i+3)*in_stride] + 4) >> 3) + + input[(i+0)*in_stride] - input[(i+1)*in_stride]); + } + + low[((len-2)>>1) * low_stride] = av_clip_int16(input[((len-2)+0)*in_stride] + input[((len-2)+1)*in_stride]); + high[((len-2)>>1) * high_stride] = av_clip_int16((11* input[((len-2)+0)*in_stride] - 5 * input[((len-2)+1)*in_stride] - + 4 * input[((len-2)-1)*in_stride] - 4 * input[((len-2)-2)*in_stride] + + 1 * input[((len-2)-3)*in_stride] + 1 * input[((len-2)-4)*in_stride] + 4) >> 3); +} + +static void horiz_filter(int16_t *input, int16_t *low, int16_t *high, + ptrdiff_t in_stride, ptrdiff_t low_stride, + ptrdiff_t high_stride, + int width, int height) +{ + for (int i = 0; i < height; i++) { + filter(input, 1, low, 1, high, 1, width); + input += in_stride; + low += low_stride; + high += high_stride; + } +} + +static void vert_filter(int16_t *input, int16_t *low, int16_t *high, + ptrdiff_t in_stride, ptrdiff_t low_stride, + ptrdiff_t high_stride, + int width, int height) +{ + for (int i = 0; i < width; i++) + filter(&input[i], in_stride, &low[i], low_stride, &high[i], high_stride, height); +} + +av_cold void ff_cfhdencdsp_init(CFHDEncDSPContext *c) +{ + c->horiz_filter = horiz_filter; + c->vert_filter = vert_filter; + + if (ARCH_X86) + ff_cfhdencdsp_init_x86(c); +} diff --git a/libavcodec/cfhdencdsp.h b/libavcodec/cfhdencdsp.h new file mode 100644 index 000000000..b3aac8d0a --- /dev/null +++ b/libavcodec/cfhdencdsp.h @@ -0,0 +1,41 @@ +/* + * 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_CFHDENCDSP_H +#define AVCODEC_CFHDENCDSP_H + +#include +#include + +typedef struct CFHDEncDSPContext { + void (*horiz_filter)(int16_t *input, int16_t *low, int16_t *high, + ptrdiff_t in_stride, ptrdiff_t low_stride, + ptrdiff_t high_stride, + int width, int height); + + void (*vert_filter)(int16_t *input, int16_t *low, int16_t *high, + ptrdiff_t in_stride, ptrdiff_t low_stride, + ptrdiff_t high_stride, + int width, int height); +} CFHDEncDSPContext; + +void ff_cfhdencdsp_init(CFHDEncDSPContext *c); + +void ff_cfhdencdsp_init_x86(CFHDEncDSPContext *c); + +#endif /* AVCODEC_CFHDENCDSP_H */ diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index 9c5b25423..d70cb4b69 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -477,7 +477,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx, return ret; if (s->palette_video) { - int size; + buffer_size_t size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); if (pal && size == AVPALETTE_SIZE) { s->frame->palette_has_changed = 1; @@ -522,4 +522,5 @@ AVCodec ff_cinepak_decoder = { .close = cinepak_decode_end, .decode = cinepak_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/cinepakenc.c b/libavcodec/cinepakenc.c index 6024df0fb..4c9b96166 100644 --- a/libavcodec/cinepakenc.c +++ b/libavcodec/cinepakenc.c @@ -171,22 +171,22 @@ static av_cold int cinepak_encode_init(AVCodecContext *avctx) if (!(s->last_frame = av_frame_alloc())) return AVERROR(ENOMEM); if (!(s->best_frame = av_frame_alloc())) - goto enomem; + return AVERROR(ENOMEM); if (!(s->scratch_frame = av_frame_alloc())) - goto enomem; + return AVERROR(ENOMEM); if (avctx->pix_fmt == AV_PIX_FMT_RGB24) if (!(s->input_frame = av_frame_alloc())) - goto enomem; + return AVERROR(ENOMEM); if (!(s->codebook_input = av_malloc_array((avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4) * (avctx->width * avctx->height) >> 2, sizeof(*s->codebook_input)))) - goto enomem; + return AVERROR(ENOMEM); if (!(s->codebook_closest = av_malloc_array((avctx->width * avctx->height) >> 2, sizeof(*s->codebook_closest)))) - goto enomem; + return AVERROR(ENOMEM); for (x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++) if (!(s->pict_bufs[x] = av_malloc((avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4) * (avctx->width * avctx->height) >> 2))) - goto enomem; + return AVERROR(ENOMEM); mb_count = avctx->width * avctx->height / MB_AREA; @@ -199,13 +199,13 @@ static av_cold int cinepak_encode_init(AVCodecContext *avctx) frame_buf_size = CVID_HEADER_SIZE + s->max_max_strips * strip_buf_size; if (!(s->strip_buf = av_malloc(strip_buf_size))) - goto enomem; + return AVERROR(ENOMEM); if (!(s->frame_buf = av_malloc(frame_buf_size))) - goto enomem; + return AVERROR(ENOMEM); if (!(s->mb = av_malloc_array(mb_count, sizeof(mb_info)))) - goto enomem; + return AVERROR(ENOMEM); av_lfg_init(&s->randctx, 1); s->avctx = avctx; @@ -252,23 +252,6 @@ static av_cold int cinepak_encode_init(AVCodecContext *avctx) s->max_strips = s->max_max_strips; return 0; - -enomem: - av_frame_free(&s->last_frame); - av_frame_free(&s->best_frame); - av_frame_free(&s->scratch_frame); - if (avctx->pix_fmt == AV_PIX_FMT_RGB24) - av_frame_free(&s->input_frame); - av_freep(&s->codebook_input); - av_freep(&s->codebook_closest); - av_freep(&s->strip_buf); - av_freep(&s->frame_buf); - av_freep(&s->mb); - - for (x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++) - av_freep(&s->pict_bufs[x]); - - return AVERROR(ENOMEM); } static int64_t calculate_mode_score(CinepakEncContext *s, int h, @@ -1206,4 +1189,5 @@ AVCodec ff_cinepak_encoder = { .close = cinepak_encode_end, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }, .priv_class = &cinepak_class, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c index 65bf14040..79ba88857 100644 --- a/libavcodec/clearvideo.c +++ b/libavcodec/clearvideo.c @@ -24,6 +24,9 @@ * ClearVideo decoder */ +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" + #include "avcodec.h" #include "bytestream.h" #include "get_bits.h" @@ -32,9 +35,9 @@ #include "mathops.h" #include "clearvideodata.h" +#define CLV_VLC_BITS 9 + typedef struct LevelCodes { - uint16_t mv_esc; - uint16_t bias_esc; VLC flags_cb; VLC mv_cb; VLC bias_cb; @@ -73,13 +76,15 @@ typedef struct CLVContext { MVInfo mvi; int tile_size; int tile_shift; - VLC dc_vlc, ac_vlc; - LevelCodes ylev[4], ulev[3], vlev[3]; int luma_dc_quant, chroma_dc_quant, ac_quant; DECLARE_ALIGNED(16, int16_t, block)[64]; int top_dc[3], left_dc[4]; } CLVContext; +static VLC dc_vlc, ac_vlc; +static LevelCodes lev[4 + 3 + 3]; // 0..3: Y, 4..6: U, 7..9: V +static VLC_TYPE vlc_buf[16716][2]; + static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac, int ac_quant) { @@ -87,16 +92,13 @@ static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac, int idx = 1, last = 0, val, skip; memset(blk, 0, sizeof(*blk) * 64); - blk[0] = get_vlc2(gb, ctx->dc_vlc.table, 9, 3); - if (blk[0] < 0) - return AVERROR_INVALIDDATA; - blk[0] -= 63; + blk[0] = get_vlc2(gb, dc_vlc.table, CLV_VLC_BITS, 3); if (!has_ac) return 0; while (idx < 64 && !last) { - val = get_vlc2(gb, ctx->ac_vlc.table, 9, 2); + val = get_vlc2(gb, ac_vlc.table, CLV_VLC_BITS, 2); if (val < 0) return AVERROR_INVALIDDATA; if (val != 0x1BFF) { @@ -359,7 +361,7 @@ static void mvi_update_row(MVInfo *mvi) } } -static TileInfo* decode_tile_info(GetBitContext *gb, LevelCodes *lc, int level) +static TileInfo *decode_tile_info(GetBitContext *gb, const LevelCodes *lc, int level) { TileInfo *ti; int i, flags = 0; @@ -367,13 +369,13 @@ static TileInfo* decode_tile_info(GetBitContext *gb, LevelCodes *lc, int level) MV mv = { 0 }; if (lc[level].flags_cb.table) { - flags = get_vlc2(gb, lc[level].flags_cb.table, lc[level].flags_cb.bits, 2); + flags = get_vlc2(gb, lc[level].flags_cb.table, CLV_VLC_BITS, 2); } if (lc[level].mv_cb.table) { - uint16_t mv_code = get_vlc2(gb, lc[level].mv_cb.table, lc[level].mv_cb.bits, 3); + uint16_t mv_code = get_vlc2(gb, lc[level].mv_cb.table, CLV_VLC_BITS, 2); - if (mv_code != lc[level].mv_esc) { + if (mv_code != MV_ESC) { mv.x = (int8_t)(mv_code & 0xff); mv.y = (int8_t)(mv_code >> 8); } else { @@ -383,9 +385,9 @@ static TileInfo* decode_tile_info(GetBitContext *gb, LevelCodes *lc, int level) } if (lc[level].bias_cb.table) { - uint16_t bias_val = get_vlc2(gb, lc[level].bias_cb.table, lc[level].bias_cb.bits, 2); + uint16_t bias_val = get_vlc2(gb, lc[level].bias_cb.table, CLV_VLC_BITS, 2); - if (bias_val != lc[level].bias_esc) { + if (bias_val != BIAS_ESC) { bias = (int16_t)(bias_val); } else { bias = get_sbits(gb, 16); @@ -596,7 +598,7 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, TileInfo *tile; MV mv, cmv; - tile = decode_tile_info(&c->gb, c->ylev, 0); + tile = decode_tile_info(&c->gb, &lev[0], 0); // Y if (!tile) return AVERROR(ENOMEM); mv = mvi_predict(&c->mvi, i, j, tile->mv); @@ -611,14 +613,14 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, cmv.x /= 2; cmv.y /= 2; av_freep(&tile); - tile = decode_tile_info(&c->gb, c->ulev, 0); + tile = decode_tile_info(&c->gb, &lev[4], 0); // U if (!tile) return AVERROR(ENOMEM); ret = restore_tree(avctx, c->pic, c->prev, 1, x, y, size, tile, cmv); if (ret < 0) mb_ret = ret; av_freep(&tile); - tile = decode_tile_info(&c->gb, c->vlev, 0); + tile = decode_tile_info(&c->gb, &lev[7], 0); // V if (!tile) return AVERROR(ENOMEM); ret = restore_tree(avctx, c->pic, c->prev, 2, x, y, size, tile, cmv); @@ -648,8 +650,63 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, return mb_ret < 0 ? mb_ret : buf_size; } +static av_cold void build_vlc(VLC *vlc, const uint8_t counts[16], + const uint16_t **syms, unsigned *offset) +{ + uint8_t lens[MAX_VLC_ENTRIES]; + unsigned num = 0; + + for (int i = 0; i < 16; i++) { + unsigned count = counts[i]; + if (count == 255) /* Special case for Y_3 table */ + count = 303; + for (count += num; num < count; num++) + lens[num] = i + 1; + } + vlc->table = &vlc_buf[*offset]; + vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *offset; + ff_init_vlc_from_lengths(vlc, CLV_VLC_BITS, num, lens, 1, + *syms, 2, 2, 0, INIT_VLC_STATIC_OVERLONG, NULL); + *syms += num; + *offset += vlc->table_size; +} + +static av_cold void clv_init_static(void) +{ + const uint16_t *mv_syms = clv_mv_syms, *bias_syms = clv_bias_syms; + + INIT_VLC_STATIC_FROM_LENGTHS(&dc_vlc, CLV_VLC_BITS, NUM_DC_CODES, + clv_dc_lens, 1, + clv_dc_syms, 1, 1, -63, 0, 1104); + INIT_VLC_STATIC_FROM_LENGTHS(&ac_vlc, CLV_VLC_BITS, NUM_AC_CODES, + clv_ac_bits, 1, + clv_ac_syms, 2, 2, 0, 0, 554); + for (unsigned i = 0, j = 0, k = 0, offset = 0;; i++) { + if (0x36F & (1 << i)) { + build_vlc(&lev[i].mv_cb, clv_mv_len_counts[k], &mv_syms, &offset); + k++; + } + if (i == FF_ARRAY_ELEMS(lev) - 1) + break; + if (0x1B7 & (1 << i)) { + lev[i].flags_cb.table = &vlc_buf[offset]; + lev[i].flags_cb.table_allocated = FF_ARRAY_ELEMS(vlc_buf) - offset; + ff_init_vlc_from_lengths(&lev[i].flags_cb, CLV_VLC_BITS, 16, + clv_flags_bits[j], 1, + clv_flags_syms[j], 1, 1, + 0, INIT_VLC_STATIC_OVERLONG, NULL); + offset += lev[i].flags_cb.table_size; + + build_vlc(&lev[i + 1].bias_cb, clv_bias_len_counts[j], + &bias_syms, &offset); + j++; + } + } +} + static av_cold int clv_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; CLVContext *const c = avctx->priv_data; int ret, w, h; @@ -691,185 +748,8 @@ static av_cold int clv_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); ff_idctdsp_init(&c->idsp, avctx); - ret = init_vlc(&c->dc_vlc, 9, NUM_DC_CODES, - clv_dc_bits, 1, 1, - clv_dc_codes, 1, 1, 0); - if (ret) { - av_log(avctx, AV_LOG_ERROR, "Error initialising DC VLC\n"); - return ret; - } - ret = ff_init_vlc_sparse(&c->ac_vlc, 9, NUM_AC_CODES, - clv_ac_bits, 1, 1, - clv_ac_codes, 1, 1, - clv_ac_syms, 2, 2, 0); - if (ret) { - av_log(avctx, AV_LOG_ERROR, "Error initialising AC VLC\n"); - return ret; - } - ret = init_vlc(&c->ylev[0].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsy_0_bits), - clv_flagsy_0_bits, 1, 1, - clv_flagsy_0_codes, 2, 2, 0); - if (ret) - return ret; - - ret = init_vlc(&c->ylev[1].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsy_1_bits), - clv_flagsy_1_bits, 1, 1, - clv_flagsy_1_codes, 2, 2, 0); - if (ret) - return ret; - - ret = init_vlc(&c->ylev[2].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsy_2_bits), - clv_flagsy_2_bits, 1, 1, - clv_flagsy_2_codes, 2, 2, 0); - if (ret) - return ret; - - ret = init_vlc(&c->ulev[0].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsu_0_bits), - clv_flagsu_0_bits, 1, 1, - clv_flagsu_0_codes, 2, 2, 0); - if (ret) - return ret; - - ret = init_vlc(&c->ulev[1].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsu_1_bits), - clv_flagsu_1_bits, 1, 1, - clv_flagsu_1_codes, 2, 2, 0); - if (ret) - return ret; - - ret = init_vlc(&c->vlev[0].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsv_0_bits), - clv_flagsv_0_bits, 1, 1, - clv_flagsv_0_codes, 2, 2, 0); - if (ret) - return ret; - - ret = init_vlc(&c->vlev[1].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsv_1_bits), - clv_flagsv_1_bits, 1, 1, - clv_flagsv_1_codes, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ylev[0].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvy_0_bits), - clv_mvy_0_bits, 1, 1, - clv_mvy_0_codes, 2, 2, - clv_mvy_0_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ylev[1].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvy_1_bits), - clv_mvy_1_bits, 1, 1, - clv_mvy_1_codes, 2, 2, - clv_mvy_1_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ylev[2].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvy_2_bits), - clv_mvy_2_bits, 1, 1, - clv_mvy_2_codes, 2, 2, - clv_mvy_2_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ylev[3].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvy_3_bits), - clv_mvy_3_bits, 1, 1, - clv_mvy_3_codes, 2, 2, - clv_mvy_3_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ulev[1].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvu_1_bits), - clv_mvu_1_bits, 1, 1, - clv_mvu_1_codes, 2, 2, - clv_mvu_1_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ulev[2].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvu_2_bits), - clv_mvu_2_bits, 1, 1, - clv_mvu_2_codes, 2, 2, - clv_mvu_2_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->vlev[1].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvv_1_bits), - clv_mvv_1_bits, 1, 1, - clv_mvv_1_codes, 2, 2, - clv_mvv_1_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->vlev[2].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvv_2_bits), - clv_mvv_2_bits, 1, 1, - clv_mvv_2_codes, 2, 2, - clv_mvv_2_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ylev[1].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasy_1_bits), - clv_biasy_1_bits, 1, 1, - clv_biasy_1_codes, 2, 2, - clv_biasy_1_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ylev[2].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasy_2_bits), - clv_biasy_2_bits, 1, 1, - clv_biasy_2_codes, 2, 2, - clv_biasy_2_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ylev[3].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasy_3_bits), - clv_biasy_3_bits, 1, 1, - clv_biasy_3_codes, 2, 2, - clv_biasy_3_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ulev[1].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasu_1_bits), - clv_biasu_1_bits, 1, 1, - clv_biasu_1_codes, 2, 2, - clv_biasu_1_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->ulev[2].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasu_2_bits), - clv_biasu_2_bits, 1, 1, - clv_biasu_2_codes, 2, 2, - clv_biasu_2_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->vlev[1].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasv_1_bits), - clv_biasv_1_bits, 1, 1, - clv_biasv_1_codes, 2, 2, - clv_biasv_1_syms, 2, 2, 0); - if (ret) - return ret; - - ret = ff_init_vlc_sparse(&c->vlev[2].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasv_2_bits), - clv_biasv_2_bits, 1, 1, - clv_biasv_2_codes, 2, 2, - clv_biasv_2_syms, 2, 2, 0); - if (ret) - return ret; - - c->ylev[0].mv_esc = 0x0909; - c->ylev[1].mv_esc = 0x0A0A; - c->ylev[2].mv_esc = 0x1010; - c->ylev[3].mv_esc = 0x1313; - c->ulev[1].mv_esc = 0x0808; - c->ulev[2].mv_esc = 0x0B0B; - c->vlev[1].mv_esc = 0x0808; - c->vlev[2].mv_esc = 0x0B0B; - - c->ylev[1].bias_esc = 0x100; - c->ylev[2].bias_esc = 0x100; - c->ylev[3].bias_esc = 0x100; - c->ulev[1].bias_esc = 0x100; - c->ulev[2].bias_esc = 0x100; - c->vlev[1].bias_esc = 0x100; - c->vlev[2].bias_esc = 0x100; + ff_thread_once(&init_static_once, clv_init_static); return 0; } @@ -877,29 +757,12 @@ static av_cold int clv_decode_init(AVCodecContext *avctx) static av_cold int clv_decode_end(AVCodecContext *avctx) { CLVContext *const c = avctx->priv_data; - int i; av_frame_free(&c->prev); av_frame_free(&c->pic); av_freep(&c->mvi.mv); - ff_free_vlc(&c->dc_vlc); - ff_free_vlc(&c->ac_vlc); - for (i = 0; i < 4; i++) { - ff_free_vlc(&c->ylev[i].mv_cb); - ff_free_vlc(&c->ylev[i].flags_cb); - ff_free_vlc(&c->ylev[i].bias_cb); - } - for (i = 0; i < 3; i++) { - ff_free_vlc(&c->ulev[i].mv_cb); - ff_free_vlc(&c->ulev[i].flags_cb); - ff_free_vlc(&c->ulev[i].bias_cb); - ff_free_vlc(&c->vlev[i].mv_cb); - ff_free_vlc(&c->vlev[i].flags_cb); - ff_free_vlc(&c->vlev[i].bias_cb); - } - return 0; } diff --git a/libavcodec/clearvideodata.h b/libavcodec/clearvideodata.h index 43d12dee4..37d5eb3bb 100644 --- a/libavcodec/clearvideodata.h +++ b/libavcodec/clearvideodata.h @@ -24,1809 +24,659 @@ #include "libavutil/common.h" +#define MAX_VLC_ENTRIES 1370 #define NUM_DC_CODES 127 -#define NUM_AC_CODES 103 +#define NUM_AC_CODES 104 -static const uint8_t clv_dc_codes[NUM_DC_CODES] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x07, 0x0B, - 0x0C, 0x08, 0x08, 0x09, 0x04, 0x06, 0x07, 0x05, - 0x04, 0x05, 0x04, 0x06, 0x05, 0x06, 0x07, 0x05, - 0x06, 0x07, 0x06, 0x07, 0x08, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x07, 0x08, 0x09, 0x07, 0x08, - 0x06, 0x07, 0x08, 0x06, 0x04, 0x05, 0x02, 0x01, - 0x03, 0x06, 0x07, 0x07, 0x09, 0x0A, 0x0B, 0x09, - 0x0A, 0x0B, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x09, - 0x0D, 0x0A, 0x0B, 0x08, 0x09, 0x0A, 0x0B, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x06, 0x07, 0x06, 0x08, - 0x07, 0x09, 0x0A, 0x0B, 0x09, 0x0A, 0x0B, 0x0C, - 0x14, 0x0D, 0x0D, 0x0E, 0x0F, 0x15, 0x15, 0x16, - 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, - 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, +static const uint8_t clv_dc_lens[NUM_DC_CODES] = { + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 21, 21, 21, 20, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 19, 18, 18, 18, 18, + 17, 17, 17, 17, 16, 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, + 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 10, 10, 10, + 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, + 7, 7, 7, 7, 6, 6, 5, 5, 5, 5, 3, 3, 1, }; -static const uint8_t clv_dc_bits[NUM_DC_CODES] = { - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 21, 22, 22, 19, 20, - 20, 19, 18, 18, 15, 17, 17, 16, - 14, 15, 12, 13, 14, 14, 14, 12, - 12, 12, 11, 11, 11, 10, 10, 10, - 10, 10, 10, 9, 9, 9, 8, 8, - 7, 7, 7, 6, 5, 5, 3, 1, - 3, 5, 5, 6, 7, 7, 7, 8, - 8, 8, 9, 9, 9, 9, 10, 11, - 10, 11, 11, 12, 12, 12, 12, 13, - 14, 14, 14, 14, 15, 15, 16, 17, - 16, 17, 18, 18, 19, 19, 19, 19, - 21, 19, 20, 19, 19, 21, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, +static const uint8_t clv_dc_syms[NUM_DC_CODES] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x15, 0x6E, 0x6F, 0x70, + 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, + 0x7D, 0x7E, 0x13, 0x68, 0x6D, 0x17, 0x18, 0x6A, 0x16, 0x19, 0x64, 0x65, + 0x66, 0x67, 0x69, 0x6B, 0x6C, 0x1A, 0x1B, 0x62, 0x63, 0x1D, 0x1E, 0x5F, + 0x61, 0x1F, 0x5E, 0x60, 0x1C, 0x21, 0x5C, 0x5D, 0x20, 0x24, 0x25, 0x26, + 0x58, 0x59, 0x5A, 0x5B, 0x23, 0x57, 0x22, 0x27, 0x28, 0x29, 0x53, 0x54, + 0x55, 0x56, 0x2A, 0x2B, 0x2C, 0x4F, 0x51, 0x52, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x4E, 0x50, 0x33, 0x34, 0x35, 0x4A, 0x4B, 0x4C, 0x4D, 0x36, + 0x37, 0x47, 0x48, 0x49, 0x38, 0x39, 0x3A, 0x44, 0x45, 0x46, 0x3B, 0x43, + 0x3C, 0x3D, 0x41, 0x42, 0x3E, 0x40, 0x3F, }; static const uint16_t clv_ac_syms[NUM_AC_CODES] = { - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, - 0x0009, 0x000A, 0x000B, 0x000C, 0x0011, 0x0012, 0x0013, 0x0014, - 0x0015, 0x0016, 0x0021, 0x0022, 0x0023, 0x0024, 0x0031, 0x0032, - 0x0033, 0x0041, 0x0042, 0x0043, 0x0051, 0x0052, 0x0053, 0x0061, - 0x0062, 0x0063, 0x0071, 0x0072, 0x0081, 0x0082, 0x0091, 0x0092, - 0x00A1, 0x00A2, 0x00B1, 0x00C1, 0x00D1, 0x00E1, 0x00F1, 0x0101, - 0x0111, 0x0121, 0x0131, 0x0141, 0x0151, 0x0161, 0x0171, 0x0181, - 0x0191, 0x01A1, 0x1001, 0x1002, 0x1003, 0x1011, 0x1012, 0x1021, - 0x1031, 0x1041, 0x1051, 0x1061, 0x1071, 0x1081, 0x1091, 0x10A1, - 0x10B1, 0x10C1, 0x10D1, 0x10E1, 0x10F1, 0x1101, 0x1111, 0x1121, - 0x1131, 0x1141, 0x1151, 0x1161, 0x1171, 0x1181, 0x1191, 0x11A1, - 0x11B1, 0x11C1, 0x11D1, 0x11E1, 0x11F1, 0x1201, 0x1211, 0x1221, - 0x1231, 0x1241, 0x1251, 0x1261, 0x1271, 0x1281, 0x1BFF, -}; - -static const uint8_t clv_ac_codes[NUM_AC_CODES] = { - 0x02, 0x0F, 0x15, 0x17, 0x1F, 0x25, 0x24, 0x21, - 0x20, 0x07, 0x06, 0x20, 0x06, 0x14, 0x1E, 0x0F, - 0x21, 0x50, 0x0E, 0x1D, 0x0E, 0x51, 0x0D, 0x23, - 0x0D, 0x0C, 0x22, 0x52, 0x0B, 0x0C, 0x53, 0x13, - 0x0B, 0x54, 0x12, 0x0A, 0x11, 0x09, 0x10, 0x08, - 0x16, 0x55, 0x15, 0x14, 0x1C, 0x1B, 0x21, 0x20, - 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x22, 0x23, - 0x56, 0x57, 0x07, 0x19, 0x05, 0x0F, 0x04, 0x0E, - 0x0D, 0x0C, 0x13, 0x12, 0x11, 0x10, 0x1A, 0x19, - 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x18, 0x17, - 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x07, 0x06, - 0x05, 0x04, 0x24, 0x25, 0x26, 0x27, 0x58, 0x59, - 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x03, + 0x0000, 0x1012, 0x1003, 0x000B, 0x000A, 0x11C1, 0x11B1, 0x11A1, 0x1191, + 0x0092, 0x0082, 0x0072, 0x0062, 0x0052, 0x0033, 0x0023, 0x0014, 0x000C, + 0x0015, 0x0171, 0x0181, 0x11D1, 0x11E1, 0x11F1, 0x1201, 0x0016, 0x0024, + 0x0043, 0x0053, 0x0063, 0x00A2, 0x0191, 0x01A1, 0x1211, 0x1221, 0x1231, + 0x1241, 0x1251, 0x1261, 0x1271, 0x1281, 0x1BFF, 0x0009, 0x0008, 0x1181, + 0x1171, 0x1161, 0x1151, 0x1141, 0x1131, 0x1121, 0x1111, 0x1002, 0x0161, + 0x0151, 0x0141, 0x0131, 0x0121, 0x0111, 0x0101, 0x00F1, 0x0042, 0x0032, + 0x0007, 0x0006, 0x1101, 0x10F1, 0x10E1, 0x10D1, 0x10C1, 0x10B1, 0x10A1, + 0x1091, 0x00E1, 0x00D1, 0x0022, 0x0013, 0x0005, 0x1081, 0x1071, 0x1061, + 0x1051, 0x00C1, 0x00B1, 0x00A1, 0x0004, 0x1041, 0x1031, 0x1021, 0x1011, + 0x0091, 0x0081, 0x0071, 0x0061, 0x0012, 0x0003, 0x0051, 0x0041, 0x0031, + 0x1001, 0x0001, 0x0011, 0x0021, 0x0002 }; +/* The -9 refers to an open end in the tree. */ static const uint8_t clv_ac_bits[NUM_AC_CODES] = { - 2, 4, 6, 7, 8, 9, 9, 10, - 10, 11, 11, 11, 3, 6, 8, 10, - 11, 12, 4, 8, 10, 12, 5, 9, - 10, 5, 9, 12, 5, 10, 12, 6, - 10, 12, 6, 10, 6, 10, 6, 10, - 7, 12, 7, 7, 8, 8, 9, 9, - 9, 9, 9, 9, 9, 9, 11, 11, - 12, 12, 4, 9, 11, 6, 11, 6, - 6, 6, 7, 7, 7, 7, 8, 8, - 8, 8, 8, 8, 8, 8, 9, 9, - 9, 9, 9, 9, 9, 9, 10, 10, - 10, 10, 11, 11, 11, 11, 12, 12, - 12, 12, 12, 12, 12, 12, 7, + -9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 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, 7, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 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, 6, 6, 6, 6, 6, + 6, 5, 5, 5, 4, 2, 3, 4, 4 }; -static const uint8_t clv_flagsy_0_bits[] = { - 3, 4, 4, 4, 4, 4, 6, 5, 4, 7, 4, 5, 4, 7, 5, 2, +static const uint8_t clv_flags_bits[][16] = { + { 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 7, 7 }, // Y_0 + { 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 7, 8, 8 }, // Y_1 + { 1, 4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 7, 8, 9, 10, 10 }, // Y_2 + { 1, 4, 4, 4, 4, 4, 4, 5, 5, 5, 7, 7, 7, 8, 9, 9 }, // U_0 + { 1, 4, 4, 4, 4, 4, 4, 4, 5, 6, 8, 8, 8, 9, 10, 10 }, // U_1 + { 1, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 10 }, // V_0 + { 1, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 8, 9, 10, 11, 11 } // V_1 }; -static const uint16_t clv_flagsy_0_codes[] = { - 0x0002, 0x0009, 0x000B, 0x0006, 0x000C, 0x0007, 0x003E, 0x001C, - 0x000D, 0x007E, 0x000A, 0x001D, 0x0008, 0x007F, 0x001E, 0x0000, +static const uint8_t clv_flags_syms[][16] = { + { 15, 0, 3, 5, 12, 1, 10, 2, 4, 8, 7, 11, 14, 6, 9, 13 }, // Y_0 + { 0, 15, 3, 12, 5, 1, 4, 2, 8, 10, 11, 7, 9, 6, 13, 14 }, // Y_1 + { 0, 3, 12, 4, 2, 1, 8, 5, 7, 10, 9, 6, 11, 13, 14, 15 }, // Y_2 + { 0, 15, 3, 12, 1, 10, 2, 5, 4, 8, 11, 7, 14, 13, 9, 6 }, // U_0 + { 0, 2, 12, 3, 4, 1, 8, 5, 10, 7, 9, 6, 11, 14, 13, 15 }, // U_1 + { 0, 15, 1, 12, 3, 10, 2, 5, 8, 4, 11, 14, 6, 9, 7, 13 }, // V_0 + { 0, 8, 3, 4, 2, 1, 12, 5, 10, 7, 9, 6, 14, 11, 13, 15 } // V_1 }; -static const uint8_t clv_flagsy_1_bits[] = { - 2, 4, 4, 3, 4, 4, 7, 6, 4, 6, 4, 6, 4, 8, 8, 3, +static const uint8_t clv_mv_len_counts[][16] = { + { 1, 0, 0, 2, 2, 6, 13, 6, 14, 28, 38, 38, 58, 56, 20, 8 }, + { 1, 0, 0, 2, 3, 4, 8, 10, 20, 30, 37, 63, 84, 68, 32, 0 }, + { 0, 1, 0, 4, 0, 6, 9, 24, 32, 48, 112, 142, 232, 166, 142, 44 }, + { 0, 1, 0, 2, 2, 6, 9, 16, 40, 82, 146, 228, 191, 255, 244, 100 }, + { 0, 0, 2, 5, 2, 12, 6, 15, 14, 24, 37, 33, 24, 28, 8, 16 }, + { 1, 0, 0, 2, 2, 5, 10, 12, 19, 19, 37, 74, 69, 120, 48, 24 }, + { 0, 0, 2, 3, 8, 7, 8, 8, 23, 37, 30, 36, 28, 16, 12, 8 }, + { 1, 0, 0, 0, 4, 5, 14, 18, 20, 39, 6, 80, 75, 112, 36, 32 }, }; -static const uint16_t clv_flagsy_1_codes[] = { - 0x0000, 0x000A, 0x000C, 0x0003, 0x000B, 0x0009, 0x007E, 0x003D, - 0x000D, 0x003E, 0x000E, 0x003C, 0x0008, 0x00FE, 0x00FF, 0x0002, +#define MV_ESC 0x13 +static const uint16_t clv_mv_syms[] = { + /* Y_0 motion vectors - 290 entries */ + 0x0000, 0x00FF, 0x0001, 0xFF00, 0x0100, 0x0002, 0x00FE, MV_ESC, 0x00FD, + 0x0004, 0x00FC, 0x0003, 0x01FF, 0xFF01, 0x0101, 0xFFFF, 0xFE00, 0x0200, + 0x0005, 0x00FB, 0x00FA, 0x0006, 0x0007, 0x00F9, 0xFF02, 0x0102, 0xFFFE, + 0x01FE, 0xFD00, 0x0300, 0xFC00, 0x0400, 0x02FF, 0xFE01, 0x0201, 0xFEFF, + 0x0008, 0x00F8, 0xFB00, 0x0500, 0xFFFD, 0x01FD, 0xFF03, 0x0103, 0xFFFA, + 0x01FA, 0xFF06, 0x0106, 0xFA00, 0x0600, 0xFE02, 0x0202, 0xFEFE, 0x02FE, + 0xFFFC, 0x01FC, 0xFF04, 0x0104, 0xF900, 0x0700, 0xFF05, 0x0105, 0xFFFB, + 0x01FB, 0xFEFD, 0x02FD, 0xFE03, 0x0203, 0xFF07, 0x0107, 0xFFF9, 0x01F9, + 0xFEFC, 0x02FC, 0xFE04, 0x0204, 0xFD02, 0x0302, 0xFDFE, 0x03FE, 0x03FF, + 0xFD01, 0x0301, 0xFDFF, 0xFDFD, 0xFD03, 0x03FD, 0x0303, 0xFEFA, 0x02FA, + 0xFE06, 0x0206, 0xFFF8, 0x0108, 0x01F8, 0xFF08, 0x04FF, 0xFC01, 0x0401, + 0xFCFF, 0x0208, 0xFE08, 0x02F8, 0xFEF8, 0x02FB, 0xFE05, 0xFEFB, 0x0205, + 0xF800, 0x0800, 0xFD05, 0xFDFB, 0x0305, 0x03FB, 0xFDFC, 0x03FC, 0xFD04, + 0x0304, 0x0207, 0xFE07, 0xFEF9, 0x02F9, 0xFCFD, 0xFC03, 0x04FD, 0x0403, + 0xFC02, 0x0402, 0xFCFE, 0x04FE, 0xFB02, 0x05FE, 0x0502, 0xFBFE, 0xFCFC, + 0x04FC, 0xFC04, 0x0404, 0x0308, 0xFD08, 0x03F8, 0xFDF8, 0xFBFC, 0x05FC, + 0xFB04, 0x0504, 0x05FF, 0xFB01, 0x0501, 0xFBFF, 0x04FB, 0xFCFB, 0xFC05, + 0x0405, 0x06FF, 0xFA01, 0x0601, 0xFAFF, 0xFDFA, 0x03FA, 0xFD06, 0x0306, + 0xFBFD, 0xFB03, 0x05FD, 0x0503, 0xFCFA, 0x04FA, 0x0406, 0xFC06, 0xFC08, + 0x0408, 0xFCF8, 0x04F8, 0xFD07, 0x0307, 0xFDF9, 0x03F9, 0x05F8, 0x0508, + 0xFBF8, 0xFB08, 0x05FB, 0x0505, 0xFB05, 0xFBFB, 0x0407, 0xFC07, 0xFCF9, + 0x04F9, 0xFA03, 0xFAFD, 0x06FD, 0x0603, 0x06FE, 0xFAFE, 0xFA08, 0xFA02, + 0x0608, 0x0602, 0xFAF8, 0x06F8, 0x07FF, 0xF9FF, 0xF901, 0x0701, 0x08FF, + 0x0801, 0xF801, 0xF8FF, 0xF902, 0xF9FE, 0x0702, 0x07FE, 0x06FB, 0x0605, + 0xFA05, 0xFAFB, 0xFB07, 0xFBF9, 0x0507, 0x05F9, 0xF903, 0x07FD, 0xF9FD, + 0x0703, 0x06F9, 0x05FA, 0xFAF9, 0x0506, 0xFBFA, 0x0607, 0xFA07, 0xFB06, + 0x0606, 0xFAFA, 0xFA06, 0x06FA, 0xF9FA, 0x0706, 0xF906, 0x07FA, 0xF802, + 0xF8FE, 0x08FE, 0x0802, 0x07F8, 0xF9F8, 0xFAFC, 0x0708, 0xF908, 0x0604, + 0x06FC, 0xFA04, 0x0707, 0x07F9, 0xF907, 0xF9F9, 0xF9FB, 0x07FB, 0x0705, + 0xF905, 0x0803, 0xF8FD, 0xF803, 0x08FD, 0x0805, 0x08FB, 0xF8FB, 0xF807, + 0xF8F9, 0x0807, 0x08F9, 0xF805, 0xF904, 0x0704, 0xF9FC, 0x07FC, 0x0806, + 0x08FA, 0xF806, 0xF8FA, 0x0804, 0x08FC, 0xF804, 0xF8FC, 0x0808, 0xF8F8, + 0x08F8, 0xF808, + /* Y_1 motion vectors - 362 entries */ + 0x0000, 0x00FF, 0x0001, 0xFF00, 0x0100, MV_ESC, 0xFFFF, 0x01FF, 0xFF01, + 0x0101, 0x00FE, 0x0002, 0x0003, 0x00FD, 0x0004, 0x00FC, 0xFE00, 0x0200, + 0x0005, 0x00FB, 0x00FA, 0x0006, 0x0007, 0x00F9, 0xFFFE, 0x01FE, 0xFF02, + 0x0102, 0xFF03, 0x0103, 0xFFFD, 0x01FD, 0xFEFF, 0x02FF, 0xFE01, 0x0201, + 0x0008, 0x00F8, 0x00F7, 0x0009, 0xFD00, 0x0300, 0xFF04, 0x0104, 0xFFFC, + 0x01FC, 0xFC00, 0x0400, 0xFB00, 0x0500, 0xFA00, 0x0600, 0xFEFE, 0x02FE, + 0xFE02, 0x0202, 0xFFFA, 0x01FA, 0xFF06, 0x0106, 0xFF05, 0x0105, 0xFFFB, + 0x01FB, 0xFDFF, 0x03FF, 0xFD01, 0x0301, 0xFE03, 0x0203, 0xFEFD, 0x02FD, + 0xF900, 0x0700, 0xFF08, 0x0108, 0xFFF8, 0x01F8, 0xFCFF, 0x04FF, 0xFC01, + 0x0401, 0xFF07, 0x0107, 0xFFF9, 0x01F9, 0x0204, 0xFEFC, 0x02FC, 0xFE04, + 0xFE05, 0x0205, 0xFEFB, 0x02FB, 0x0109, 0xFFF7, 0xFF09, 0x01F7, 0xFDFE, + 0x03FE, 0xFD02, 0x0302, 0xFCFE, 0x04FE, 0xF800, 0x0800, 0xFC02, 0x0402, + 0xFD03, 0x0303, 0xFDFD, 0x03FD, 0xFBFF, 0xFB01, 0x0501, 0x05FF, 0xFE07, + 0x0207, 0xFEF9, 0x02F9, 0x04FD, 0xFC03, 0xFCFD, 0x0403, 0xFBFE, 0x05FE, + 0xFB02, 0x0502, 0xFEFA, 0x02FA, 0xFE06, 0x0206, 0x0304, 0xFDFC, 0x03FC, + 0xFD04, 0xFDFA, 0x03FA, 0x0306, 0x06FF, 0xFAFF, 0xFA01, 0x0601, 0xFD06, + 0xF700, 0x0900, 0x0404, 0xFCFC, 0x04FC, 0xFC04, 0xFD05, 0x0305, 0x03FB, + 0xFDFB, 0xFE08, 0xFEF8, 0x02F8, 0x0208, 0x03F8, 0xFD08, 0xFDF8, 0x0308, + 0x04F8, 0xFC08, 0x0408, 0xFCF8, 0xFAFE, 0x06FE, 0xFA02, 0x0602, 0x04FA, + 0xFC06, 0x0406, 0xFCFA, 0xFC05, 0x0405, 0x04FB, 0xFCFB, 0x05FD, 0xFB03, + 0xFBFD, 0x0503, 0x0504, 0xFBFC, 0xFB04, 0x05FC, 0x06FD, 0xFAFC, 0x0604, + 0x06FC, 0xFA03, 0xFAFD, 0x0603, 0xFA04, 0xFB05, 0x0505, 0xFD07, 0x0307, + 0xFBFB, 0xFDF9, 0x05FB, 0x03F9, 0x0508, 0xFBF8, 0x05F8, 0xFB08, 0x0209, + 0xFE09, 0x02F7, 0xFEF7, 0x0608, 0x06F8, 0xFA08, 0xFAF8, 0xFC07, 0xF9FF, + 0x0407, 0x07FF, 0xFCF9, 0xF901, 0x0701, 0x04F9, 0xF9FE, 0x07FE, 0xF902, + 0x0702, 0x05F9, 0xFB07, 0xFBF9, 0x0507, 0x07FD, 0xF903, 0xF9FD, 0x0703, + 0xFD09, 0x03F7, 0x0309, 0xFDF7, 0x0704, 0xF9FC, 0x07FC, 0xF904, 0x0605, + 0xFAFB, 0xFA05, 0x06FB, 0x05FA, 0xFB06, 0x0506, 0xFBFA, 0x08FF, 0xF801, + 0xF8FF, 0x0801, 0xF8FE, 0x0802, 0xF802, 0x08FE, 0x0901, 0xF7FF, 0x09FF, + 0xF701, 0x06F9, 0x0607, 0xFAF9, 0xFA07, 0x04F7, 0xFC09, 0x0409, 0xFCF7, + 0x0707, 0xF9F9, 0xF907, 0x07F9, 0x0606, 0xFA06, 0x06FA, 0xFAFA, 0xF908, + 0xF9F8, 0x07F8, 0x0708, 0x07FA, 0xF906, 0x0706, 0xF9FA, 0x0804, 0xF7FE, + 0x08FC, 0xF804, 0xF702, 0x0902, 0xF8FC, 0x09FE, 0x05F7, 0xFB09, 0x0509, + 0xFBF7, 0x0803, 0x08FD, 0xF803, 0xF8FD, 0xF905, 0x0705, 0x07FB, 0xF9FB, + 0xF8FA, 0x08FA, 0x0806, 0xF806, 0xF7FC, 0xF704, 0x09FC, 0x0904, 0xF7FD, + 0xF703, 0x09FD, 0x0903, 0x0808, 0xF808, 0x08F8, 0xF8F8, 0xF706, 0x0906, + 0xF7FA, 0x09FA, 0xF805, 0x0805, 0xF8FB, 0x08FB, 0xFA09, 0x0609, 0x06F7, + 0xFAF7, 0x08F9, 0xF8F9, 0x0807, 0xF807, 0x0709, 0x07F7, 0xF909, 0xF9F7, + 0x0905, 0xF705, 0x09FB, 0xF7FB, 0x09F8, 0xF7F8, 0x0908, 0xF708, 0x08F7, + 0xF809, 0xF8F7, 0x0809, 0xF709, 0xF7F7, 0x0909, 0x09F7, 0xF7F9, 0x09F9, + 0x0907, 0xF707, + /* Y_2 motion vectors - 962 entries */ + 0x0000, 0x0001, 0x00FF, 0xFF00, 0x0100, 0x0002, 0x00FE, 0x0101, 0xFFFF, + 0x01FF, 0xFF01, 0x0003, 0x00FD, 0x0004, 0x00FC, MV_ESC, 0x0005, 0x00FB, + 0xFE00, 0x0200, 0xFF02, 0x0102, 0xFFFE, 0x01FE, 0x00FA, 0x0006, 0x00F9, + 0x0007, 0x0201, 0xFEFF, 0x02FF, 0xFE01, 0xFD00, 0x0300, 0xFF03, 0x0103, + 0xFFFD, 0x01FD, 0xFC00, 0x0400, 0x0008, 0x00F8, 0xFB00, 0x0500, 0x0009, + 0x00F7, 0x00F5, 0x000B, 0xFE02, 0x0202, 0xFEFE, 0x02FE, 0x00F6, 0x000A, + 0xFF04, 0x0104, 0xFFFC, 0x01FC, 0xFA00, 0x0600, 0x0301, 0xFDFF, 0x03FF, + 0xFD01, 0xF900, 0x0700, 0x0401, 0xFCFF, 0x04FF, 0xFC01, 0x000C, 0x00F4, + 0xFFFA, 0x01FA, 0xFF06, 0x0106, 0xFF05, 0x0105, 0xFFFB, 0x01FB, 0xF800, + 0x0800, 0xFE03, 0x0203, 0xFEFD, 0x02FD, 0xFE04, 0x0204, 0xFEFC, 0x02FC, + 0xFFF9, 0x01F9, 0xFF07, 0x0107, 0x00F3, 0x000D, 0xFD02, 0x0302, 0xFDFE, + 0x03FE, 0x00F2, 0x000E, 0x0501, 0xFBFF, 0x05FF, 0xFB01, 0xFE05, 0x0205, + 0xFEFB, 0x02FB, 0xFF08, 0x0108, 0xFFF8, 0x01F8, 0xFC02, 0x0402, 0xFCFE, + 0x04FE, 0xF700, 0x0900, 0xFEFA, 0x02FA, 0xFE06, 0x0206, 0x00F1, 0x000F, + 0xFF09, 0x0109, 0xFFF7, 0x01F7, 0xFFF6, 0x01F6, 0xFF0A, 0x010A, 0xFD03, + 0x0303, 0xFDFD, 0x03FD, 0xFC03, 0x0403, 0xFCFD, 0x04FD, 0xFD04, 0x0304, + 0xFDFC, 0x03FC, 0xF600, 0x0A00, 0x0601, 0xFAFF, 0x06FF, 0xFA01, 0xFB02, + 0x0502, 0xFBFE, 0x05FE, 0xFF0C, 0x010C, 0xFFF4, 0x01F4, 0xFFF5, 0x01F5, + 0xFF0B, 0x010B, 0x0701, 0xF9FF, 0x07FF, 0xF901, 0xFDFA, 0x03FA, 0xFD06, + 0x0306, 0xFE08, 0x0208, 0xFEF8, 0x02F8, 0xFA02, 0x0602, 0xFAFE, 0x06FE, + 0xFEF9, 0x02F9, 0xFE07, 0x0207, 0xFE09, 0x0209, 0xFEF7, 0x02F7, 0xFC04, + 0x0404, 0xFCFC, 0x04FC, 0xFB03, 0x0503, 0xFBFD, 0x05FD, 0x0801, 0xF8FF, + 0x08FF, 0xF801, 0xFD05, 0x0305, 0xFDFB, 0x03FB, 0xFFF3, 0x01F3, 0x010D, + 0xFF0D, 0xF902, 0x0702, 0xF9FE, 0x07FE, 0xF500, 0x0B00, 0xFA03, 0x0603, + 0xFAFD, 0x06FD, 0xFC05, 0x0405, 0xFCFB, 0x04FB, 0xFEF6, 0x02F6, 0xFE0A, + 0x020A, 0xFDF9, 0x03F9, 0xFD07, 0x0307, 0xFEF5, 0x02F5, 0xFE0B, 0x020B, + 0xFFF2, 0x01F2, 0xFF0E, 0x010E, 0xF400, 0x0C00, 0xF802, 0x0802, 0xF8FE, + 0x08FE, 0xF903, 0x0703, 0xF9FD, 0x07FD, 0x03F8, 0xFB04, 0x0504, 0xFBFC, + 0x05FC, 0xFD08, 0x0308, 0xFDF8, 0xFB05, 0x0505, 0xFBFB, 0x05FB, 0xFA04, + 0x0604, 0xFAFC, 0x06FC, 0xF300, 0x0D00, 0xFC08, 0x0408, 0xFCF8, 0x04F8, + 0xFCFA, 0x04FA, 0xFC06, 0x0406, 0xF200, 0x0E00, 0x0901, 0xF7FF, 0x09FF, + 0xF701, 0xFD09, 0x0309, 0xFDF7, 0x03F7, 0xFDF6, 0x03F6, 0xFD0A, 0x030A, + 0xFC09, 0x0409, 0xFCF7, 0x04F7, 0x0A01, 0xF6FF, 0x0AFF, 0xF601, 0xFBF8, + 0xFB08, 0x0508, 0x05F8, 0x020C, 0xFE0C, 0xFEF4, 0x02F4, 0xFA05, 0xFAFB, + 0x0605, 0x06FB, 0x01F1, 0x010F, 0xFF0F, 0xFFF1, 0xF100, 0x0F00, 0xF904, + 0x0704, 0xF9FC, 0x07FC, 0xF803, 0x0803, 0xF8FD, 0x08FD, 0xF804, 0x0804, + 0xF8FC, 0x08FC, 0xFCF9, 0x04F9, 0xFC07, 0x0407, 0xF702, 0x0902, 0xF7FE, + 0x09FE, 0xF602, 0x0A02, 0xF6FE, 0x0AFE, 0xFB09, 0xFBF7, 0x05F7, 0x0509, + 0x0B01, 0xF5FF, 0x0BFF, 0xF501, 0xFBFA, 0x05FA, 0xFB06, 0x0506, 0xFBF9, + 0x05F9, 0xFB07, 0x0507, 0xF703, 0x0903, 0xF7FD, 0x09FD, 0xFAFA, 0xF704, + 0x06FA, 0x0904, 0xFA06, 0x0606, 0xF7FC, 0x09FC, 0xFDF5, 0x03F5, 0x030B, + 0xFD0B, 0xFAF9, 0x06F9, 0xFA07, 0x0607, 0xFA08, 0x0608, 0xFAF8, 0x06F8, + 0xF502, 0x0B02, 0xF5FE, 0x0BFE, 0xF9F9, 0x07F9, 0xF907, 0x0707, 0xF905, + 0xF9FB, 0x0705, 0x07FB, 0xF9FA, 0x07FA, 0xF906, 0x0706, 0x0C01, 0xF4FF, + 0x0CFF, 0xF401, 0xF908, 0x0708, 0xF9F8, 0x07F8, 0xF8F9, 0x08F9, 0xF807, + 0x0807, 0x0AFC, 0xF604, 0x0A04, 0xF6FC, 0xF8FA, 0x08FA, 0xF806, 0x0806, + 0xF603, 0x0A03, 0xF6FD, 0x0AFD, 0xF805, 0xF8FB, 0x0805, 0x08FB, 0xFA09, + 0x0609, 0xFAF7, 0x06F7, 0x040A, 0xFCF6, 0x04F6, 0xFC0A, 0xFDF4, 0x030C, + 0xFD0C, 0x03F4, 0xFB0A, 0xFBF6, 0x05F6, 0x050A, 0xFCF5, 0xFC0B, 0x04F5, + 0x040B, 0xF705, 0xF7FB, 0x0905, 0x09FB, 0xF808, 0x0808, 0xF8F8, 0x08F8, + 0xFAF6, 0x06F6, 0xFA0A, 0x060A, 0xF7FA, 0x09FA, 0xF706, 0x0906, 0xF9F6, + 0x07F6, 0xF90A, 0x070A, 0x02F1, 0xFEF3, 0x02F3, 0xFE0D, 0xFE0F, 0xFEF1, + 0x020F, 0x020D, 0x050B, 0xFBF5, 0x05F5, 0xFB0B, 0x040C, 0xFCF4, 0xFC0C, + 0x04F4, 0xFAF5, 0x06F5, 0xFA0B, 0x060B, 0x020E, 0xFEF2, 0xFE0E, 0x02F2, + 0xFB0C, 0x05F4, 0xFBF4, 0x050C, 0xF9F5, 0x070B, 0x07F5, 0xF90B, 0x030E, + 0xFDF2, 0x03F2, 0xFD0E, 0xF8F5, 0x08F5, 0x080B, 0xF80B, 0xF5FD, 0xF503, + 0x0B03, 0x0BFD, 0x030D, 0xFD0D, 0xFDF3, 0x03F3, 0x09F9, 0x0907, 0xF707, + 0xF7F9, 0xF6FA, 0x0AFA, 0x0A06, 0xF606, 0xF403, 0x0C03, 0x0709, 0xF4FD, + 0xF9F7, 0xF909, 0x0CFD, 0x07F7, 0x0AF9, 0x0A07, 0xF607, 0xF6F9, 0xF5FA, + 0xF506, 0x0BFA, 0x0B06, 0xF303, 0xF3FD, 0x0DFD, 0x0D03, 0x0D01, 0xF3FF, + 0x0DFF, 0xF301, 0xFCF2, 0xFC0E, 0x040E, 0x04F2, 0x0809, 0xF8F7, 0x08F7, + 0xF809, 0xF5FC, 0xF504, 0x0B04, 0x0BFC, 0xF7F5, 0x09F5, 0x090B, 0xF70B, + 0x0E03, 0xF2FD, 0xF203, 0x0EFD, 0xFBF2, 0x050E, 0x05F2, 0xFB0E, 0xFCF3, + 0xFC0D, 0x04F3, 0x040D, 0xF402, 0x0C02, 0xF4FE, 0x0CFE, 0xF6F5, 0xF6FB, + 0x0AF5, 0xF605, 0x0A05, 0x0AFB, 0x0A0B, 0xF60B, 0x080A, 0xF8F6, 0x08F6, + 0xF80A, 0xF7F6, 0xF70A, 0x09F6, 0x090A, 0x0BFB, 0xF505, 0xF5FB, 0x0B05, + 0x030F, 0x03F1, 0xFDF1, 0xFD0F, 0xF2FF, 0x0EFF, 0xF201, 0x0E01, 0xF6F6, + 0x0AF6, 0x0908, 0xF60A, 0x0A0A, 0xF708, 0xF7F8, 0x09F8, 0x0BF9, 0x0B07, + 0xF5F9, 0xF507, 0xF709, 0x0909, 0xF7F7, 0x09F7, 0x0CF9, 0xF407, 0x0C07, + 0xF4F9, 0xF608, 0x0A08, 0xF6F8, 0x0AF8, 0xFBF3, 0x05F3, 0xFB0D, 0x050D, + 0xF5F8, 0xF508, 0x0B08, 0x0BF8, 0x060D, 0xFAF3, 0x06F3, 0xFA0D, 0x0CFA, + 0xF4FA, 0xF406, 0x0C06, 0x0DF9, 0xF307, 0x0D07, 0xF3F9, 0x0D02, 0x0DFE, + 0xF3FE, 0xF302, 0xFA0E, 0xFAF2, 0x060E, 0x06F2, 0xF4FB, 0x0C05, 0x0CFB, + 0xF405, 0x070D, 0xF9F3, 0xF90D, 0x07F3, 0xF5F5, 0x0BF5, 0x0B0B, 0xF50B, + 0x0AF7, 0x0A09, 0xF6F7, 0xF609, 0xF202, 0x0E02, 0xFAF4, 0xF2FE, 0x0EFE, + 0xFA0C, 0x06F4, 0x060C, 0xF404, 0x0C04, 0xF4FC, 0x0CFC, 0xFC0F, 0x0D04, + 0xFCF1, 0x04F1, 0xF304, 0x0DFC, 0x040F, 0x070C, 0xF3FC, 0xF9F4, 0x07F4, + 0xF90C, 0xF8F3, 0xF3FA, 0x08F3, 0xF306, 0x080D, 0x0DFA, 0x0D06, 0xF80D, + 0xF204, 0x0EFC, 0xF2FC, 0x0E04, 0x07F2, 0xF90E, 0xF9F2, 0x070E, 0xF3FB, + 0x0D05, 0xF305, 0x0DFB, 0xF4F8, 0x080C, 0xF8F4, 0xF408, 0x0C08, 0x0CF8, + 0x08F4, 0xF80C, 0xF70C, 0x090C, 0xF7F4, 0x09F4, 0xF4F5, 0x0CF5, 0x0C0B, + 0xF40B, 0xF8F2, 0xF80E, 0x080E, 0x08F2, 0x0A0C, 0xF60C, 0xF6F4, 0x0AF4, + 0x0F02, 0xF102, 0xF1FE, 0x0FFE, 0x090D, 0xF7F3, 0x09F3, 0xF70D, 0xF1FC, + 0xF104, 0x0FFC, 0x0F04, 0x0B0C, 0xF50C, 0xF5F4, 0x0BF4, 0xFB0F, 0x050F, + 0x05F1, 0xFBF1, 0xF5F6, 0x0B0A, 0xF50A, 0x0BF6, 0xF60D, 0xF6F3, 0x0A0D, + 0x0AF3, 0xF70E, 0xF7F2, 0x09F2, 0x090E, 0x06F1, 0x060F, 0xFAF1, 0xFA0F, + 0x0DF5, 0x0D0B, 0xF3F5, 0xF30B, 0x0B09, 0x0BF7, 0xF509, 0xF5F7, 0x0D08, + 0xF3F8, 0xF308, 0x0DF8, 0x0CF6, 0x0C0A, 0xF4F6, 0xF40A, 0xF50D, 0x0BF3, + 0x0B0D, 0xF208, 0xF40C, 0xF5F3, 0x0EF8, 0xF4F4, 0xF2F8, 0x0CF4, 0x0C0C, + 0x0E08, 0xF2F9, 0x0EF9, 0xF207, 0x0E07, 0xF205, 0x0E05, 0x0EFB, 0xF2FB, + 0x0A0E, 0x0AF2, 0xF6F2, 0xF103, 0x0FFD, 0xF60E, 0x0F03, 0xF1FD, 0x0EF5, + 0x0E0B, 0xF2F5, 0xF20B, 0x0DF6, 0xF30A, 0xF3F6, 0x0D0A, 0x0F05, 0x0FFB, + 0xF105, 0xF1FB, 0x070F, 0xF9F1, 0x07F1, 0xF90F, 0xF80F, 0x080F, 0x08F1, + 0xF8F1, 0x0BF2, 0xF50E, 0xF5F2, 0x0B0E, 0x09F1, 0x090F, 0xF7F1, 0xF70F, + 0x0CF3, 0xF20A, 0xF40D, 0x0EF6, 0xF4F3, 0xF2F6, 0x0E0A, 0x0C0D, 0xF60F, + 0xF50F, 0xF4F7, 0x0A0F, 0x0AF1, 0x0BF1, 0xF6F1, 0x0C09, 0x0B0F, 0xF409, + 0x0CF7, 0xF5F1, 0xF40F, 0x0CF1, 0x0C0F, 0xF4F1, 0xF30C, 0x0DF4, 0xF3F4, + 0x0D0C, 0xF309, 0x0EF4, 0xF3F7, 0x0D09, 0x0DF7, 0xF2F4, 0xF20C, 0x0E0C, + 0xF4F2, 0xF40E, 0x0C0E, 0x0CF2, 0x0DF2, 0xF30E, 0xF3F2, 0x0D0E, 0x0EFA, + 0x0E06, 0xF206, 0xF2FA, 0x0FFA, 0x0F06, 0xF106, 0xF1FA, 0xF20E, 0x0E09, + 0x0E0E, 0xF2F2, 0xF2F7, 0x0EF2, 0x0EF7, 0xF209, 0xF2F3, 0xF30D, 0xF20D, + 0x0EF3, 0xF3F3, 0x0DF3, 0x0E0D, 0x0D0D, 0xF3F1, 0x0D0F, 0xF30F, 0x0DF1, + 0xF107, 0x0FF9, 0x0F07, 0xF1F9, 0xF2F1, 0xF20F, 0x0FF7, 0x0EF1, 0xF1F7, + 0x0E0F, 0xF109, 0x0F09, 0xF1F8, 0xF108, 0x0FF8, 0x0F08, 0x0F0B, 0xF10B, + 0x0FF6, 0xF1F6, 0x0FF5, 0x0F0A, 0xF10A, 0xF1F5, 0xF1F3, 0xF10D, 0x0FF3, + 0x0F0D, 0x0FFF, 0xF1FF, 0xF101, 0x0F01, 0x0F0F, 0xF1F1, 0x0FF1, 0xF10F, + 0x0FF2, 0xF10C, 0x0F0E, 0x0FF4, 0xF1F4, 0xF1F2, 0x0F0C, 0xF10E, + /* Y_3 motion vectors - 1370 elements */ + 0x0000, 0x00FF, 0x0001, 0xFF00, 0x0100, 0x00FE, 0x0002, 0xFFFF, 0x01FF, + 0xFF01, 0x0101, 0x00FD, 0x0003, 0x00FC, 0x0004, 0xFE00, 0x0200, 0x0005, + 0x00FB, MV_ESC, 0xFFFE, 0x01FE, 0xFF02, 0x0102, 0x0006, 0x00FA, 0xFEFF, + 0x02FF, 0xFE01, 0x0201, 0xFD00, 0x0300, 0xFC00, 0x0400, 0x00F9, 0x0007, + 0xFFFD, 0x01FD, 0xFF03, 0x0103, 0x00F8, 0x0008, 0x00F7, 0x0009, 0x000A, + 0x00F6, 0xFEFE, 0x02FE, 0xFE02, 0x0202, 0xFFFC, 0x01FC, 0xFF04, 0x0104, + 0xFB00, 0x0500, 0xFDFF, 0x03FF, 0xFD01, 0x0301, 0xFEFD, 0x02FD, 0xFE03, + 0x0203, 0xFCFF, 0x04FF, 0xFC01, 0x0401, 0xFF05, 0x0105, 0xFFFB, 0x01FB, + 0x000B, 0x00F5, 0xFA00, 0x0600, 0xF900, 0x0700, 0xFFF9, 0x01F9, 0xFF07, + 0x0107, 0xFDFE, 0x03FE, 0xFD02, 0x0302, 0xFBFF, 0x05FF, 0xFB01, 0x0501, + 0xF800, 0x0800, 0xFF06, 0x0106, 0xFFFA, 0x01FA, 0xFAFF, 0x06FF, 0xFA01, + 0x0601, 0xFEFC, 0x02FC, 0xFE04, 0x0204, 0xFFF8, 0x01F8, 0xFF08, 0x0108, + 0xFCFE, 0x04FE, 0xFC02, 0x0402, 0xF700, 0x0900, 0xF600, 0x0A00, 0xFDFD, + 0x03FD, 0xFD03, 0x0303, 0xFF0A, 0x010A, 0xFFF6, 0x01F6, 0xFE05, 0x0205, + 0xFEFB, 0x02FB, 0x000C, 0x00F4, 0xFDFC, 0x03FC, 0xFD04, 0x0304, 0x000D, + 0x00F3, 0xFE06, 0x0206, 0xFEFA, 0x02FA, 0xFFF7, 0x01F7, 0xFF09, 0x0109, + 0xFF0B, 0x010B, 0xFFF5, 0x01F5, 0xFBFE, 0x05FE, 0xFB02, 0x0502, 0xFD05, + 0x0305, 0xFDFB, 0x03FB, 0x000E, 0x00F2, 0xFCFD, 0x04FD, 0xFC03, 0x0403, + 0xF9FF, 0x07FF, 0xF901, 0x0701, 0xFBFD, 0x05FD, 0xFB03, 0x0503, 0xFEF9, + 0x02F9, 0xFE07, 0x0207, 0xF8FF, 0x08FF, 0xF801, 0x0801, 0x00F1, 0x000F, + 0xFAFE, 0x06FE, 0xFA02, 0x0602, 0xFD06, 0x0306, 0xFDFA, 0x03FA, 0x0010, + 0x00F0, 0xFEF8, 0x02F8, 0xFE08, 0x0208, 0xFE0A, 0x020A, 0xFEF6, 0x02F6, + 0xFEF7, 0x02F7, 0xFE09, 0x0209, 0xFDF9, 0x03F9, 0xFD07, 0x0307, 0xF500, + 0x0B00, 0xFCFC, 0x04FC, 0xFC04, 0x0404, 0xF7FF, 0x09FF, 0xF701, 0x0901, + 0xF9FE, 0x07FE, 0xF902, 0x0702, 0x0011, 0x00EF, 0xFBFC, 0x05FC, 0xFB04, + 0x0504, 0xFC05, 0x0405, 0xFCFB, 0x04FB, 0xFAFD, 0x06FD, 0xF8FE, 0x08FE, + 0xF802, 0x0802, 0xFA03, 0x0603, 0xFDF7, 0x03F7, 0xFD09, 0x0309, 0xFB05, + 0x0505, 0xFBFB, 0x05FB, 0xF9FD, 0x07FD, 0xF903, 0x0703, 0x00EE, 0x0012, + 0xFC06, 0x0406, 0xFCFA, 0x04FA, 0xF7FE, 0x09FE, 0xF702, 0x0902, 0xFDF8, + 0x03F8, 0xFD08, 0x0308, 0xF6FF, 0x0AFF, 0xF601, 0x0A01, 0xFAFC, 0x06FC, + 0xFA04, 0x0604, 0xFA05, 0x0605, 0xFAFB, 0x06FB, 0xFF0C, 0x010C, 0xFFF4, + 0x01F4, 0xFCF8, 0x04F8, 0xFC08, 0x0408, 0xFB06, 0x0506, 0xFBFA, 0x05FA, + 0xFE0B, 0x020B, 0xFEF5, 0x02F5, 0xFCF7, 0x04F7, 0xFC09, 0x0409, 0xFD0A, + 0x030A, 0xFDF6, 0x03F6, 0xFCF9, 0x04F9, 0xFC07, 0x0407, 0xF8FD, 0x08FD, + 0xF803, 0x0803, 0xF9FC, 0x07FC, 0xF904, 0x0704, 0xF400, 0x0C00, 0xF7FD, + 0x09FD, 0xF703, 0x0903, 0xF8FC, 0x08FC, 0xF804, 0x0804, 0xFBF9, 0x05F9, + 0xFB07, 0x0507, 0xF905, 0x0705, 0xF9FB, 0x07FB, 0xFAF9, 0x06F9, 0xFA07, + 0x0607, 0xFBF8, 0x05F8, 0xFB08, 0x0508, 0xFD0B, 0x030B, 0xFDF5, 0x03F5, + 0xFA06, 0x0606, 0xFAFA, 0x06FA, 0xFC0A, 0x040A, 0xFCF6, 0x04F6, 0xFAF8, + 0x06F8, 0xFA08, 0x0608, 0xF9F9, 0x07F9, 0xF907, 0x0707, 0xFF0E, 0x010E, + 0xFFF2, 0x01F2, 0xFBF7, 0x05F7, 0xFB09, 0x0509, 0xFF0D, 0x010D, 0xFFF3, + 0x01F3, 0xF906, 0xF9FA, 0x0706, 0x07FA, 0x0609, 0xFAF7, 0x06F7, 0xFA09, + 0x0709, 0xF9F7, 0x07F7, 0xF909, 0xF8F9, 0x08F9, 0xF807, 0x0807, 0xF300, + 0x0D00, 0xFB0A, 0x050A, 0xFBF6, 0x05F6, 0xF6FE, 0x0AFE, 0xF602, 0x0A02, + 0xFC0B, 0xFCF5, 0x040B, 0x04F5, 0xF7FC, 0x09FC, 0xF704, 0x0904, 0xF805, + 0x0805, 0xF8FB, 0x08FB, 0xF6FC, 0x0AFC, 0xF604, 0x0A04, 0xFE0D, 0x020D, + 0xFEF3, 0x02F3, 0x0809, 0xF8F7, 0x08F7, 0xF809, 0xF806, 0xF8FA, 0x0806, + 0x08FA, 0x0AFD, 0xF603, 0x0A03, 0xF6FD, 0xFA0A, 0x060A, 0xFAF6, 0x06F6, + 0xF5FF, 0x0BFF, 0xF501, 0x0B01, 0xF705, 0x0905, 0xF7FB, 0x09FB, 0xFFF1, + 0x01F1, 0xFF0F, 0x010F, 0xF605, 0x0A05, 0xF6FB, 0x0AFB, 0xFF11, 0x0111, + 0xFFEF, 0x01EF, 0xF9F8, 0x07F8, 0xF908, 0x0708, 0xF90A, 0x070A, 0xF9F6, + 0x07F6, 0xFB0B, 0x05F5, 0xFBF5, 0x050B, 0x080A, 0xF80A, 0xF8F6, 0x08F6, + 0xF7F9, 0x09F9, 0xF706, 0xF7FA, 0x0906, 0xF707, 0x09FA, 0x0907, 0xF606, + 0xF6FA, 0x0A06, 0x0AFA, 0xF6F9, 0x0AF9, 0xF607, 0x0A07, 0xF200, 0x0E00, + 0xF70A, 0x090A, 0xF5FD, 0x0BFD, 0xF7F6, 0x09F6, 0xF503, 0x0B03, 0xF60A, + 0x0A0A, 0xF6F6, 0x0AF6, 0x0110, 0xFFF0, 0x01F0, 0xFF10, 0xF8F8, 0x08F8, + 0xF808, 0x0808, 0xF7F8, 0x09F8, 0xF708, 0x0908, 0xF100, 0x0F00, 0xFA0B, + 0xFAF5, 0x060B, 0x06F5, 0xF9F5, 0xF90B, 0x07F5, 0x070B, 0xF4FF, 0x0CFF, + 0xF401, 0x0C01, 0xFFEE, 0x0112, 0x01EE, 0xFF12, 0x0909, 0xF7F7, 0x09F7, + 0xF709, 0xF505, 0x0B05, 0xF5FB, 0x0BFB, 0xF4FD, 0x0CFD, 0xF403, 0x0C03, + 0xFE0C, 0x020C, 0xFEF4, 0x02F4, 0x0CFB, 0x0A09, 0xF6F7, 0x0AF7, 0xF405, + 0x0C05, 0xF4FB, 0xF609, 0xF8F5, 0x080B, 0x08F5, 0xF80B, 0xF5FE, 0x0BFE, + 0xF502, 0x0B02, 0xFD0D, 0x030D, 0xFDF3, 0x03F3, 0x020E, 0xFEF2, 0x02F2, + 0xFE0E, 0x0B0A, 0xF5F6, 0x0BF6, 0xF50A, 0x0A08, 0xF6F8, 0x0AF8, 0xF608, + 0xF5FC, 0xF504, 0x0B04, 0x0BFC, 0x030C, 0xFD0C, 0xFDF4, 0x03F4, 0xFEEE, + 0xFE12, 0x02EE, 0x0212, 0xF7F5, 0xF70B, 0x090B, 0x09F5, 0xF4FE, 0x0CFE, + 0xF402, 0x0C02, 0xF40A, 0xF4FC, 0x0C0A, 0xF4F6, 0x0CF6, 0xF404, 0x0C04, + 0x0CFC, 0x02F1, 0xFEF1, 0x020F, 0xFE0F, 0x040D, 0xFC0D, 0xFCF3, 0x04F3, + 0x0B09, 0xFE11, 0x0211, 0xF5F7, 0x0BF7, 0xFEEF, 0x02EF, 0xF509, 0xF506, + 0xF5FA, 0x0B06, 0x0BFA, 0xFC0C, 0x040C, 0xFCF4, 0x04F4, 0xF406, 0xF4FA, + 0x0C06, 0x0CFA, 0xF3FD, 0x0DFD, 0xF303, 0x0D03, 0xF000, 0x1000, 0xFB0D, + 0xFBF3, 0x05F3, 0x050D, 0xF5F9, 0x0BF9, 0xF507, 0x0B07, 0xF60B, 0xF6F5, + 0x0A0B, 0x0AF5, 0xF4F9, 0x0CF9, 0xF407, 0x0C07, 0xF5F5, 0xF50B, 0x0B0B, + 0x0BF5, 0xEF00, 0x1100, 0x060D, 0xFAF3, 0x06F3, 0xFA0D, 0x050C, 0xF3FE, + 0xFB0C, 0x0DFE, 0x05F4, 0xF302, 0x0D02, 0xFBF4, 0x03F1, 0x030F, 0xFD0F, + 0xFDF1, 0xEE00, 0x1200, 0xFA0C, 0x06F4, 0x060C, 0xFAF4, 0xF2FE, 0x0EFE, + 0xF3FF, 0x0DFF, 0xF301, 0x0D01, 0xF202, 0x0E02, 0xF5F8, 0x0BF8, 0xF508, + 0x0B08, 0xF90D, 0x070D, 0xF9F3, 0x07F3, 0x030E, 0x03F2, 0xFDF2, 0xFD0E, + 0xF304, 0x0D04, 0x0DFC, 0xF3FC, 0x0DFB, 0xF3FB, 0xF305, 0x0D05, 0x070C, + 0xF90C, 0xF9F4, 0x07F4, 0xFDEE, 0xF2FF, 0x0EFF, 0x0312, 0xFD12, 0xF201, + 0x03EE, 0x0E01, 0xF80C, 0x080C, 0x08F4, 0xF8F4, 0x0DFA, 0xFC0E, 0xFCF2, + 0x040E, 0x04F2, 0xF306, 0xF3FA, 0x0D06, 0xF4F8, 0x0CF8, 0xF408, 0x0C08, + 0x0C09, 0xF4F7, 0x0CF7, 0xF409, 0x04F1, 0xFC0F, 0x040F, 0xFCF1, 0x0EFD, + 0xF2FD, 0xF203, 0x0E03, 0x090C, 0xF70C, 0xF7F4, 0x09F4, 0xF3F8, 0x0DF8, + 0xF308, 0x0D08, 0x0A0C, 0xF60C, 0xF6F4, 0x0AF4, 0xF4F5, 0x0C0B, 0xF40B, + 0x0CF5, 0x05F1, 0xFB0F, 0xF1FF, 0x0FFF, 0xF101, 0x0F01, 0xFBF1, 0x050F, + 0xFB0E, 0x050E, 0xFBF2, 0x05F2, 0x06F1, 0xFA0F, 0x060F, 0xFAF1, 0x0DF9, + 0xF3F9, 0x0D07, 0xF307, 0x080D, 0xF80D, 0xF8F3, 0x08F3, 0x090D, 0xF70D, + 0xF7F3, 0x09F3, 0xF3F7, 0xFE10, 0xFEF0, 0x0DF7, 0x02F0, 0x0210, 0x0D09, + 0xF309, 0xF0FF, 0x10FF, 0xF001, 0x1001, 0x0A0D, 0xFA0E, 0xF60D, 0x060E, + 0xFAF2, 0x06F2, 0xF6F3, 0x0AF3, 0xF2FC, 0x0EFC, 0x0E04, 0xF204, 0xF205, + 0x0EFB, 0x0E05, 0xF2FB, 0xF90F, 0x070F, 0x07F1, 0xF9F1, 0x0310, 0xFDF0, + 0xFD10, 0x03F0, 0x0E08, 0xF2F8, 0x0EF8, 0xF208, 0xF30A, 0xF3F6, 0x0DF6, + 0x0D0A, 0x0F08, 0xF1F8, 0x0FF8, 0xF108, 0xF50C, 0x0B0C, 0x0FFD, 0x0F03, + 0x0BF4, 0xF103, 0xF5F4, 0xF1FD, 0xF20A, 0xF2F6, 0x0EF6, 0x0410, 0xFCF0, + 0xFC10, 0x04F0, 0x0E0A, 0xF207, 0x0311, 0xFC11, 0x0411, 0xF2F9, 0xFCEF, + 0xFD11, 0xFDEF, 0x0EF9, 0x03EF, 0x0E07, 0x04EF, 0x0510, 0xFBF0, 0xFB10, + 0x0511, 0x05F0, 0xFBEF, 0xFB11, 0x05EF, 0x0F07, 0xF1F9, 0x0FF9, 0xF107, + 0xFA10, 0x0610, 0xFAF0, 0x06F0, 0xF0FD, 0xF003, 0x10FD, 0x1003, 0xF1FE, + 0x0FFE, 0xF102, 0x0F02, 0xF9F2, 0x07F2, 0xF90E, 0x070E, 0xF30B, 0x0D0B, + 0xF80E, 0xF3F5, 0x08F2, 0x080E, 0x0DF5, 0xF8F2, 0xF50D, 0xF5F3, 0x0B0D, + 0x0EFA, 0x0BF3, 0xF206, 0xF2FA, 0x0E06, 0xF70E, 0x090E, 0xF7F2, 0x09F2, + 0x0FFB, 0x0FFC, 0xF1FB, 0xF104, 0x0F04, 0xF105, 0xF1FC, 0x0F05, 0x0F0A, + 0x0FF6, 0x0F06, 0xF1F6, 0xF106, 0xF1FA, 0xF10A, 0x0FFA, 0xEFFD, 0xEF01, + 0x11FD, 0xEFFF, 0x11FF, 0xEF03, 0x1101, 0x1103, 0x0C0C, 0xF40C, 0xF4F4, + 0x0CF4, 0x10FB, 0xF005, 0xF0FB, 0x1005, 0x1002, 0xF0FE, 0x10FE, 0xF002, + 0xF910, 0x08F0, 0xF8F0, 0xF9F0, 0x0810, 0xF810, 0x07F0, 0x0710, 0x10FC, + 0xF0FC, 0xF60E, 0xF6F2, 0x1004, 0x0AF2, 0xF004, 0x0A0E, 0x11FC, 0xEFFC, + 0xF30C, 0xEF04, 0x1104, 0xF3F4, 0x0D0C, 0x0DF4, 0x11FB, 0x1105, 0xEFFB, + 0xEF05, 0x080F, 0xF80F, 0x08F1, 0xF8F1, 0xFC12, 0x04EE, 0x0412, 0xFCEE, + 0xEFFE, 0xF5F2, 0x11FE, 0x0B0E, 0x10FA, 0xF50E, 0x0BF2, 0xEF02, 0x1006, + 0x1102, 0xF006, 0xF0FA, 0xFB12, 0xFBEE, 0x0512, 0x05EE, 0x10F8, 0xF4F2, + 0x1008, 0x0CF2, 0xF0F8, 0xF40E, 0x0C0E, 0xF008, 0xF20C, 0x0EF4, 0xF2F4, + 0x0E0C, 0xF20B, 0xF2F5, 0x09F0, 0xF7F0, 0x0910, 0xF710, 0x0E0B, 0x0EF5, + 0x0AF0, 0x0A10, 0xF6F0, 0xF610, 0xEEFC, 0xFAEF, 0x12FC, 0x1204, 0xEE04, + 0x0611, 0xFA11, 0x06EF, 0xEF06, 0x1106, 0xEFFA, 0x11FA, 0xEF08, 0xEFF8, + 0x11F8, 0x1108, 0xF7F1, 0x090F, 0xF70F, 0x09F1, 0x0E09, 0xF209, 0x0EF7, + 0xF2F7, 0xF0F6, 0x100A, 0x10F6, 0xF5F0, 0xF00A, 0x0BF0, 0xF510, 0x0B10, + 0x0D0E, 0xF30E, 0x0A0F, 0x0DF2, 0xF3F2, 0xF60F, 0x0AF1, 0xF6F1, 0x0CF3, + 0x0FF7, 0x0F09, 0xF40D, 0xF4F3, 0xF1F7, 0x0C0D, 0xF109, 0x07EE, 0xF912, + 0xFA12, 0xFAEE, 0x0712, 0xF9EE, 0x0612, 0x06EE, 0xF9EF, 0xF911, 0x0711, + 0x07EF, 0x0D0D, 0x0DF3, 0x0F0C, 0x110A, 0x11F6, 0xF10C, 0xF30D, 0xEFF6, + 0x0FF4, 0xEF0A, 0xF3F3, 0xF1F4, 0x10F9, 0xF007, 0xF0F9, 0x1007, 0xF8EF, + 0x0811, 0xF20D, 0x0EF3, 0x0E0D, 0xF2F3, 0xF811, 0x08EF, 0xF1F5, 0x0FF5, + 0xF10B, 0x0F0B, 0xF0F4, 0xF00C, 0xF2F2, 0x10F4, 0x0E0E, 0x0EF2, 0xF20E, + 0x100C, 0x09EF, 0x0911, 0xF7EF, 0xF711, 0xF611, 0x0A11, 0xF6EF, 0x0AEF, + 0x12FF, 0xEE01, 0x1201, 0xEEFF, 0xF5F1, 0x0BF1, 0xF50F, 0x0B0F, 0x10F5, + 0xEE06, 0xF00B, 0x1206, 0x12FA, 0xF0F5, 0xEEFA, 0x100B, 0x0CF0, 0xF410, + 0xF4F0, 0x0C10, 0x11F9, 0x0BEF, 0xF5EF, 0x0CF1, 0xEFF9, 0xF511, 0x0C0F, + 0xEF07, 0xF4F1, 0xF40F, 0x0B11, 0x1107, 0xEEFD, 0x12FD, 0xEE03, 0x1203, + 0x0DF0, 0xF3F0, 0xF310, 0x0D10, 0x0C11, 0x0CEF, 0xF4EF, 0xF411, 0x0EF0, + 0xF210, 0x0E10, 0xF2F0, 0x08EE, 0xF8EE, 0x0812, 0xF812, 0x110B, 0xF7EE, + 0xF712, 0x11F5, 0x0912, 0xEFF5, 0x09EE, 0xEF0B, 0xEEF9, 0x12F9, 0xEE07, + 0x1207, 0x0F0E, 0xF30F, 0x0D0F, 0x0DF1, 0xF10E, 0xF3F1, 0xF1F2, 0x0FF2, + 0xF6EE, 0xF612, 0x0AEE, 0x0A12, 0xF20F, 0x0E0F, 0xF2F1, 0x0EF1, 0xF0F7, + 0x1009, 0xF009, 0x10F7, 0xEEFB, 0x12FB, 0xEE05, 0x1205, 0x1202, 0x0FF3, + 0xEE08, 0xF1F3, 0x12F8, 0x12FE, 0xF10D, 0x1208, 0x0F0D, 0xEEFE, 0xEEF8, + 0xEE02, 0x0FF1, 0xF10F, 0xF1F1, 0x0F0F, 0x12F4, 0x11F4, 0x1109, 0xEFF4, + 0xEE0A, 0xEFF7, 0x110C, 0xEEF4, 0xEE0C, 0x11F7, 0xEF0C, 0x120C, 0xF110, + 0xF1F0, 0x120A, 0xEEF6, 0xEF09, 0x12F6, 0x0F10, 0x0FF0, 0x10F2, 0xF0F2, + 0x100E, 0xF00E, 0xEEF5, 0x0B12, 0x0BEE, 0xF512, 0x120B, 0x12F5, 0xF5EE, + 0xEE0B, 0x1209, 0x12F7, 0xEE09, 0xEEF7, 0xF4EE, 0x0C12, 0x0CEE, 0xF412, + 0x100D, 0x0D12, 0xF0F3, 0x0DEE, 0xF3EF, 0x0DEF, 0xF3EE, 0x0D11, 0xF312, + 0xF00D, 0xF311, 0x10F3, 0x11F3, 0xEFF3, 0x0E12, 0xF212, 0xF2EE, 0x0EEE, + 0xEF0D, 0x110D, 0x100F, 0xF0F1, 0xF00F, 0x10F1, 0x10F0, 0xF211, 0xF0F0, + 0xF010, 0x0EEF, 0xF2EF, 0x0E11, 0x1010, 0x120D, 0xEE0D, 0x12F3, 0xEEF3, + 0x11F1, 0xF111, 0xEFF2, 0x110F, 0xEF0E, 0xEF0F, 0x0FEF, 0x11F2, 0x0F11, + 0xF1EF, 0x110E, 0xEFF1, 0xEE0E, 0x120E, 0x12F2, 0xF1EE, 0x0FEE, 0xEEF2, + 0xF112, 0x0F12, 0xF0EE, 0x10EE, 0xF012, 0x1012, 0x11F0, 0xEF10, 0xEFF0, + 0x1110, 0xF0EF, 0x10EF, 0x1011, 0xF011, 0x11EF, 0xEF11, 0xEFEF, 0xEF12, + 0x11EE, 0x1112, 0xEFEE, 0x1111, 0xEE11, 0xEEEF, 0x12EF, 0x1211, 0x1212, + 0x12EE, 0xEEEE, 0xEE12, 0xEEF1, 0x12F1, 0xEE0F, 0x120F, 0xEE10, 0x1210, + 0xEEF0, 0x12F0, + /* U_1 motion vectors - 226 entries */ + 0x0001, 0x00FF, 0x0000, 0x0002, 0x00FE, 0x00FD, 0x0003, 0xFF00, 0x0100, + 0xFE00, 0x0200, 0x0101, 0xFFFF, 0x01FF, 0xFF01, 0x00FB, 0x0005, 0xFD00, + 0x0300, 0xFC00, 0x0400, 0x0004, 0x00FC, MV_ESC, 0x00FA, 0x0006, 0x0201, + 0xFEFF, 0x02FF, 0xFE01, 0xFFFD, 0x01FD, 0xFF03, 0x0103, 0xFEFD, 0x02FD, + 0xFE03, 0x0203, 0xFF02, 0x0102, 0xFFFE, 0x01FE, 0xFB00, 0x0500, 0xFDFD, + 0x03FD, 0xFD03, 0x0303, 0xFF04, 0x0104, 0xFFFC, 0x01FC, 0xFE02, 0x0202, + 0xFEFE, 0x02FE, 0xFA00, 0x0600, 0xFFFB, 0x01FB, 0xFF05, 0x0105, 0x00F9, + 0x0007, 0xFD02, 0x0302, 0xFDFE, 0x03FE, 0x0301, 0xFDFF, 0x03FF, 0xFD01, + 0xFEFB, 0x02FB, 0xFE05, 0x0205, 0x0401, 0xFCFF, 0x04FF, 0xFC01, 0xFE04, + 0x0204, 0xFEFC, 0x02FC, 0xFC02, 0x0402, 0xFCFE, 0x04FE, 0xFD04, 0x0304, + 0xFDFC, 0x03FC, 0xFFFA, 0x01FA, 0x0106, 0xFF06, 0xFC04, 0x0404, 0xFCFC, + 0x04FC, 0x0501, 0xFBFF, 0x05FF, 0xFB01, 0x0504, 0xFB04, 0xFBFC, 0x05FC, + 0xFE06, 0xFEFA, 0x02FA, 0x0206, 0xF900, 0x0700, 0xFB02, 0x0502, 0xFBFE, + 0x05FE, 0x0306, 0xFDFA, 0xFD06, 0x03FA, 0xFCFA, 0x0406, 0xFC06, 0x04FA, + 0x01F9, 0x0107, 0xFF07, 0xFFF9, 0xFE07, 0x02F9, 0xFEF9, 0x0207, 0xFDFB, + 0x03FB, 0xFD05, 0x0305, 0xFCFD, 0x04FD, 0xFC03, 0x0403, 0x0601, 0x06FF, + 0xFAFF, 0xFA01, 0x0701, 0xF9FF, 0x07FF, 0xF901, 0x03F9, 0xFD07, 0x0307, + 0xFDF9, 0xFBFA, 0x0506, 0xFB06, 0x05FA, 0xFCFB, 0x04FB, 0x0405, 0xFC05, + 0x0503, 0x05FD, 0xFB03, 0xFBFD, 0xFA03, 0xFAFA, 0x0606, 0x06FD, 0xFA06, + 0x0603, 0x06FA, 0xFAFD, 0xFA04, 0xFAFC, 0x0604, 0x06FC, 0x04F9, 0xFC07, + 0x0407, 0xFCF9, 0xFA02, 0xFBF9, 0x0507, 0xFAFE, 0x05F9, 0x06FE, 0x0602, + 0xFB07, 0x06F9, 0xFAF9, 0xFA07, 0x0607, 0x07FE, 0xF902, 0x0704, 0xF9FC, + 0xF904, 0xF9FE, 0x07FC, 0x0702, 0x07FA, 0x0706, 0xF906, 0xF9FA, 0x07FD, + 0x0703, 0xF903, 0xF9FD, 0xFB05, 0x0505, 0xFBFB, 0x05FB, 0xFA05, 0x07FB, + 0xF9FB, 0x0605, 0x0705, 0x06FB, 0xFAFB, 0xF905, 0xF9F9, 0xF907, 0x07F9, + 0x0707, + /* U_2 motion vectors - 442 entries */ + 0x0000, 0xFF00, 0x0100, 0x00FF, 0x0001, 0xFFFF, 0x01FF, 0xFF01, 0x0101, + MV_ESC, 0x0002, 0x00FE, 0xFE00, 0x0200, 0x0003, 0x00FD, 0xFEFF, 0x02FF, + 0xFE01, 0x0201, 0xFF02, 0x0102, 0xFFFE, 0x01FE, 0xFD00, 0x0300, 0x00FC, + 0x0005, 0xFDFF, 0x03FF, 0xFD01, 0x0301, 0xFF03, 0x0103, 0xFFFD, 0x01FD, + 0xFE02, 0x0202, 0xFEFE, 0x02FE, 0xFCFF, 0x04FF, 0xFC01, 0x0401, 0xFBFF, + 0x05FF, 0xFB01, 0x0501, 0x0004, 0x00FB, 0xFD02, 0x0302, 0xFDFE, 0x03FE, + 0xFF05, 0x0105, 0xFFFB, 0x01FB, 0x0006, 0x00FA, 0xFFFC, 0x01FC, 0xFF04, + 0x0104, 0xFE03, 0x0203, 0xFEFD, 0x02FD, 0xFC00, 0x0400, 0xFF06, 0x0106, + 0xFFFA, 0x01FA, 0xFEFC, 0x02FC, 0xFE04, 0x0204, 0xFD03, 0x0303, 0xFDFD, + 0x03FD, 0xFC02, 0x0402, 0xFCFE, 0x04FE, 0xFAFF, 0x06FF, 0xFA01, 0x0601, + 0xFC03, 0x0403, 0xFCFD, 0x04FD, 0xFB02, 0x0502, 0xFBFE, 0x05FE, 0xFB00, + 0x0500, 0xFA00, 0x0600, 0xFE05, 0x0205, 0xFEFB, 0x02FB, 0xFA02, 0x0602, + 0xFAFE, 0x06FE, 0xFD05, 0x0305, 0xFDFB, 0x03FB, 0xFB03, 0x0503, 0xFBFD, + 0x05FD, 0xFC05, 0x0405, 0xFCFB, 0x04FB, 0xFDFC, 0x03FC, 0x00F9, 0xFD04, + 0x0304, 0x0007, 0xF902, 0x0702, 0xFA03, 0x0603, 0xFAFD, 0xFA05, 0xFB05, + 0x06FD, 0x0505, 0x0605, 0xF9FE, 0xFE06, 0x0206, 0xFEFA, 0x07FE, 0x02FA, + 0xFAFB, 0xFBFB, 0x05FB, 0x06FB, 0xFD06, 0x0306, 0xFDFA, 0x03FA, 0x0406, + 0xFC06, 0xFCFA, 0x04FA, 0xFCFC, 0x04FC, 0xFC04, 0x0404, 0xF9FF, 0x07FF, + 0xF901, 0x0701, 0xFFF9, 0x01F9, 0x0107, 0xFF07, 0xFAFC, 0xFBFC, 0x05FC, + 0x06FC, 0xFA04, 0xFB04, 0x0504, 0x0604, 0xFB06, 0x0506, 0xFBFA, 0x05FA, + 0x0008, 0x00F8, 0xF9FC, 0x07FC, 0xF904, 0x0704, 0xFA06, 0x0606, 0xFAFA, + 0x06FA, 0x00F7, 0x0009, 0xF700, 0xF800, 0xF900, 0x0700, 0x0800, 0x0900, + 0xFEF9, 0x02F9, 0xFE07, 0x0207, 0xF8FF, 0xFF08, 0x0108, 0xFFF8, 0x08FF, + 0x01F8, 0xF801, 0x0801, 0x0307, 0xFDF9, 0x03F9, 0xFD07, 0xF7FF, 0x09FF, + 0xF701, 0x0901, 0xF8FC, 0xF903, 0x08FC, 0xF804, 0xF9FD, 0x0804, 0xF905, + 0x0705, 0x0703, 0xF9FB, 0x07FD, 0x07FB, 0xFC07, 0x01F7, 0xFCF9, 0x04F9, + 0x0407, 0xFF09, 0x0109, 0xFFF7, 0x0802, 0xFAF9, 0xFBF9, 0x05F9, 0x06F9, + 0xFB07, 0xF8FE, 0xFA07, 0x0507, 0x08FE, 0x0607, 0xF802, 0x0902, 0xF803, + 0x0803, 0xF8FD, 0x08FD, 0xF805, 0xF7FE, 0x0805, 0x00F6, 0x09FE, 0x000A, + 0xF8FB, 0x08FB, 0xF702, 0x07FA, 0xF906, 0xFEF8, 0x0208, 0xF9FA, 0xF6FF, + 0xFD08, 0x0308, 0xFDF8, 0x0AFF, 0x0706, 0x02F8, 0x03F8, 0xF601, 0xFE08, + 0x0A01, 0xFE09, 0x02F7, 0x0905, 0xF705, 0xF7FB, 0x0209, 0xFEF7, 0x09FB, + 0xF603, 0xFC09, 0xF703, 0x03F7, 0xF605, 0x04F7, 0x0903, 0x0A03, 0x09FD, + 0xFBF7, 0x0AFD, 0x0A05, 0x05F7, 0xFD09, 0x0A00, 0xFC08, 0xF7FD, 0x0408, + 0xFCF8, 0xFB09, 0x0509, 0x0AFB, 0xF600, 0xF6FB, 0xFCF7, 0xF6FD, 0x04F8, + 0x0309, 0xFDF7, 0x0409, 0x01F6, 0xFA09, 0xF9F9, 0xFF0A, 0x08FA, 0xFBF8, + 0xFFF6, 0x07F9, 0x0609, 0xFB08, 0x06F7, 0xF8FA, 0x0906, 0xF907, 0x0508, + 0xF706, 0xF7FA, 0x09FA, 0xFAF7, 0x010A, 0x0707, 0x0806, 0x05F8, 0xF806, + 0x0A06, 0xF7FC, 0xF606, 0xFEF6, 0xF6FE, 0x0608, 0xF908, 0x0A02, 0xF602, + 0x020A, 0xFD0A, 0x09FC, 0x0AFA, 0xFDF6, 0x0708, 0xF9F8, 0x0AFE, 0xFAF8, + 0xF704, 0xFA08, 0x06F8, 0x030A, 0x02F6, 0xF6FA, 0xFE0A, 0x07F8, 0x0904, + 0x03F6, 0x04F6, 0xFBF6, 0x08F9, 0xF8F9, 0x05F6, 0xFB0A, 0x0807, 0xFC0A, + 0xF807, 0x040A, 0x050A, 0xFCF6, 0x0709, 0x060A, 0x07F7, 0xF9F7, 0xF909, + 0xFAF6, 0xFA0A, 0x06F6, 0x0AFC, 0xF808, 0x09F7, 0x08F8, 0xF708, 0x09F9, + 0xF8F7, 0xF707, 0x0809, 0xF7F9, 0xF8F8, 0x09F8, 0xF709, 0xF6FC, 0x08F7, + 0xF809, 0x0907, 0xF604, 0xF90A, 0x0909, 0xF9F6, 0xF7F8, 0x0A04, 0x070A, + 0x07F6, 0x0808, 0x0908, 0xF7F7, 0x080A, 0x08F6, 0xF8F6, 0xF70A, 0x09F6, + 0xF80A, 0x090A, 0xF7F6, 0x0A09, 0x0AF8, 0xF6F6, 0x0AF9, 0xF6F7, 0x0A07, + 0x0A0A, 0x0AF7, 0x0AF6, 0xF60A, 0x0A08, 0xF6F9, 0xF609, 0xF607, 0xF6F8, + 0xF608, + /* V_1 motion vectors - 226 entries */ + 0x0001, 0x00FF, 0x0000, 0xFF00, 0x0100, 0x0002, 0x00FE, 0x00FD, 0x0003, + 0x0004, 0x00FC, 0x00FB, 0x0005, 0x0101, 0xFFFF, 0x01FF, 0xFF01, 0xFE00, + 0x0200, 0xFD00, 0x0300, MV_ESC, 0xFF02, 0x0102, 0xFFFE, 0x01FE, 0xFC00, + 0x0400, 0x0201, 0xFEFF, 0x02FF, 0xFE01, 0xFFFD, 0x01FD, 0xFF03, 0x0103, + 0x00FA, 0x0006, 0xFE02, 0x0202, 0xFEFE, 0x02FE, 0xFD02, 0x0302, 0xFDFE, + 0x03FE, 0xFEFD, 0xFC02, 0x02FD, 0x0402, 0xFE03, 0xFCFE, 0x0203, 0x04FE, + 0xFF04, 0x0104, 0xFFFC, 0x01FC, 0xFB00, 0x0500, 0x00F9, 0x0007, 0xFE04, + 0x0204, 0xFEFC, 0x02FC, 0xFA00, 0x0600, 0xFD04, 0x0304, 0xFDFC, 0x03FC, + 0xFFFB, 0x01FB, 0xFF05, 0x0105, 0x0301, 0xFDFF, 0x03FF, 0xFD01, 0x01F9, + 0x0107, 0xFF07, 0xFFF9, 0x0401, 0xFCFF, 0x04FF, 0xFC01, 0xFEFB, 0x02FB, + 0xFE05, 0x0205, 0xFF06, 0x0106, 0xFFFA, 0x01FA, 0x0501, 0xFBFF, 0x05FF, + 0xFB01, 0x0206, 0xFEFA, 0x02FA, 0xFE06, 0xF900, 0x0700, 0xFB02, 0x0502, + 0xFBFE, 0x05FE, 0xFDFB, 0x0305, 0x03FB, 0xFD05, 0xFDFD, 0x03FD, 0xFD03, + 0x0303, 0x0404, 0xFC04, 0xFCFC, 0x04FC, 0xFA02, 0x0602, 0xFAFE, 0x06FE, + 0xFCFD, 0x04FD, 0x0403, 0xFC03, 0x05FD, 0xFB03, 0x0503, 0xFBFD, 0x02F9, + 0xFE07, 0xFEF9, 0x0207, 0x0601, 0xFAFF, 0xFDFA, 0xFD06, 0x06FF, 0x03FA, + 0xFA01, 0x0306, 0x0504, 0xFB04, 0xFBFC, 0x05FC, 0xFAFC, 0xFA04, 0x0604, + 0x06FC, 0xFA03, 0x0603, 0x06FD, 0xFAFD, 0xF904, 0x0704, 0xF9FC, 0x07FC, + 0x0307, 0xFD07, 0x03F9, 0xFDF9, 0xFCF9, 0xFC07, 0x04F9, 0x0407, 0xFCFB, + 0xFC05, 0x0405, 0x04FB, 0xFBFB, 0xFB05, 0x0505, 0x05FB, 0x04FA, 0xFCFA, + 0x0406, 0xFC06, 0xF901, 0x0701, 0xF9FF, 0x07FF, 0x05F9, 0x0507, 0xFBF9, + 0xFB07, 0x0702, 0xF902, 0xF9FE, 0x07FE, 0x06FB, 0x0605, 0xFAFB, 0xFA05, + 0x0506, 0xF9FD, 0xFB06, 0xFBFA, 0xF903, 0x07FD, 0x05FA, 0x0703, 0xF905, + 0xF9FB, 0x0705, 0x07FB, 0xFA06, 0x0606, 0xFA07, 0x0607, 0xFAF9, 0x06F9, + 0x06FA, 0xFAFA, 0xF906, 0x07FA, 0xF9FA, 0x0706, 0xF907, 0xF9F9, 0x07F9, + 0x0707, + /* V_2 motion vectors - 442 elements */ + 0x0000, 0x00FF, 0x0001, 0xFF00, 0x0100, 0xFFFF, 0x01FF, 0xFF01, 0x0101, + MV_ESC, 0xFE00, 0x0200, 0xFEFF, 0x02FF, 0xFE01, 0x0201, 0x0002, 0x00FE, + 0x00FC, 0x0003, 0x0004, 0x00FD, 0x0005, 0x00FB, 0xFDFF, 0x03FF, 0xFD01, + 0x0301, 0xFFFC, 0x01FC, 0xFF03, 0x0103, 0xFF04, 0x0104, 0xFFFD, 0x01FD, + 0xFD00, 0x0300, 0xFF02, 0x0102, 0xFFFE, 0x01FE, 0xFC00, 0x0400, 0xFEFC, + 0x02FC, 0xFE03, 0x0203, 0xFE04, 0x0204, 0xFEFD, 0x02FD, 0xFCFF, 0x04FF, + 0xFC01, 0x0401, 0xFE02, 0x0202, 0xFEFE, 0x02FE, 0xFD02, 0x0302, 0xFDFE, + 0x03FE, 0xFDFC, 0x03FC, 0xFD03, 0x0303, 0xFD04, 0x0304, 0xFDFD, 0x03FD, + 0xFF05, 0x0105, 0xFFFB, 0x01FB, 0x0006, 0x00FA, 0xFBFF, 0x05FF, 0xFB01, + 0x0501, 0xFAFF, 0x06FF, 0xFA01, 0x0601, 0x000A, 0xFF06, 0x0106, 0xFFFA, + 0x01FA, 0xFE05, 0x0205, 0xFB00, 0x0500, 0xFEFB, 0x02FB, 0xFE06, 0x0206, + 0xFEFA, 0x02FA, 0xFC02, 0x0402, 0xFCFE, 0x04FE, 0xFA00, 0x0600, 0xFCFC, + 0xFC03, 0x04FC, 0x0403, 0xFC04, 0xFCFD, 0x0404, 0x04FD, 0xFB02, 0x0502, + 0xFBFE, 0x05FE, 0xFD05, 0x0305, 0xFDFB, 0x03FB, 0x00F7, 0x00F9, 0x00F6, + 0x0007, 0x0009, 0xFA02, 0xFBFC, 0x0602, 0xFB03, 0x05FC, 0x0503, 0xFB04, + 0xFBFD, 0x0504, 0x05FD, 0xFAFE, 0x06FE, 0xF9FF, 0x07FF, 0xF901, 0x0701, + 0xFC05, 0x0405, 0xFCFB, 0x04FB, 0xFAFC, 0xFA03, 0x06FC, 0x0603, 0xFFF9, + 0xFA04, 0x01F9, 0xFAFD, 0x0604, 0xFB05, 0x06FD, 0x0505, 0xFF07, 0x0107, + 0xFBFB, 0x05FB, 0xFC06, 0xFD06, 0x0306, 0x0406, 0xFCFA, 0xFDFA, 0x03FA, + 0x04FA, 0xF9FC, 0x01F7, 0xF903, 0x07FC, 0x0703, 0xF904, 0xF9FD, 0x0704, + 0x07FD, 0xFB06, 0x0506, 0xFBFA, 0x05FA, 0xFF09, 0x0109, 0xFFF7, 0xF900, + 0x0700, 0xF8FF, 0x08FF, 0xF801, 0x0801, 0xFEF9, 0x02F9, 0xFA06, 0x0606, + 0xFAFA, 0xFE07, 0x06FA, 0xF800, 0x0800, 0x0207, 0xF8FC, 0xF803, 0x08FC, + 0x0803, 0xF804, 0xF8FD, 0x0804, 0x08FD, 0xFF08, 0x0108, 0xFFF8, 0xF700, + 0x00F8, 0x01F8, 0x0900, 0x0008, 0xF902, 0x0702, 0xF9FE, 0x07FE, 0xFDF9, + 0x03F9, 0x0307, 0xFD07, 0xF7FF, 0x09FF, 0xF701, 0x0901, 0xFA05, 0x0605, + 0xFAFB, 0x06FB, 0xFBF9, 0xFCF9, 0x04F9, 0x05F9, 0x0507, 0xFB07, 0x0407, + 0xFC07, 0xFE09, 0x02F7, 0x0209, 0xF600, 0x0A00, 0xFEF7, 0x0802, 0x0705, + 0xF905, 0xFFF6, 0xF8FE, 0x08FE, 0x01F6, 0x010A, 0xF9FB, 0xFF0A, 0x07FB, + 0xF802, 0x03F7, 0x0309, 0xFD09, 0xFDF7, 0x0607, 0x0902, 0xFAF9, 0x0409, + 0x04F7, 0x06F9, 0xF7FE, 0x09FE, 0xFA07, 0xFC09, 0xFCF7, 0xF702, 0xF705, + 0x07FA, 0xF9F9, 0x0707, 0xF7FB, 0x07F9, 0x0805, 0x0A05, 0xF805, 0xF906, + 0x0706, 0xF9FA, 0xF907, 0xF605, 0x0905, 0xF6FB, 0xF8FB, 0x08FB, 0x09FB, + 0x0AFB, 0xFE08, 0x0509, 0xFEF6, 0x020A, 0xF6FF, 0xFD08, 0x0308, 0xFDF8, + 0xFB09, 0x0208, 0x0AFF, 0xFE0A, 0x02F8, 0xFBF7, 0x02F6, 0x03F8, 0xFEF8, + 0xF601, 0x05F7, 0x0A01, 0xFB08, 0xF7FC, 0x0904, 0xF703, 0x0A04, 0x09FC, + 0x0AFC, 0x0903, 0xF604, 0x0608, 0x09FD, 0xFCF8, 0xFAF8, 0xF7FD, 0x05F8, + 0xFA08, 0x0508, 0xF704, 0xF603, 0xFC08, 0x0A03, 0xF6FC, 0x04F8, 0xFBF8, + 0x06F8, 0xF6FD, 0x0408, 0x0AFD, 0xF706, 0x08F9, 0xF908, 0xF8F9, 0x040A, + 0xF602, 0x0A02, 0x0708, 0x08FA, 0xFDF6, 0x0AFE, 0xF806, 0xFCF6, 0xF7FA, + 0x0906, 0xFC0A, 0x0807, 0x07F8, 0xF6FE, 0x03F6, 0x030A, 0x09FA, 0xF8FA, + 0xF9F8, 0xFD0A, 0x0806, 0xF807, 0x04F6, 0xF7F9, 0xF707, 0xFBF6, 0x09F9, + 0x05F6, 0xFB0A, 0x0907, 0x050A, 0xF6F9, 0x0AF9, 0x0A07, 0xF607, 0xF909, + 0xF8F6, 0xF70A, 0x09F6, 0xFA09, 0x07F7, 0x0609, 0x070A, 0xFAF7, 0x06F7, + 0xF90A, 0xFA0A, 0x090A, 0xFAF6, 0xF9F6, 0xF7F6, 0x080A, 0xF80A, 0x06F6, + 0xF9F7, 0x07F6, 0x0709, 0x060A, 0x08F6, 0x0909, 0x09F8, 0xF7F7, 0x08F8, + 0xF8F8, 0xF709, 0x0809, 0x0808, 0xF808, 0x0908, 0xF7F8, 0xF8F7, 0x08F7, + 0xF708, 0x09F7, 0xF809, 0x0AFA, 0xF60A, 0x0A06, 0x0AF6, 0xF609, 0xF6F7, + 0xF6FA, 0x0A09, 0x0AF7, 0xF6F8, 0x0A0A, 0x0AF8, 0xF606, 0x0A08, 0xF608, + 0xF6F6, }; -static const uint8_t clv_flagsy_2_bits[] = { - 1, 4, 4, 4, 4, 5, 7, 5, 4, 6, 5, 8, 4, 9, 10, 10, +static const uint8_t clv_bias_len_counts[][16] = { + { 1, 1, 1, 0, 2, 0, 4, 3, 3, 6, 5, 10, 16, 7, 17, 2 }, + { 1, 0, 2, 2, 0, 4, 2, 6, 4, 8, 6, 10, 9, 7, 23, 14 }, + { 0, 2, 1, 3, 2, 3, 4, 4, 8, 8, 8, 7, 7, 10, 21, 6 }, + { 1, 1, 1, 0, 2, 1, 3, 2, 4, 4, 2, 8, 6, 2, 3, 2 }, + { 1, 0, 2, 2, 1, 3, 2, 4, 4, 4, 4, 4, 2, 7, 6, 8 }, + { 1, 1, 1, 0, 2, 2, 1, 3, 2, 4, 3, 5, 6, 6, 3, 2 }, + { 1, 0, 2, 2, 2, 1, 3, 2, 4, 5, 1, 4, 10, 2, 3, 2 }, }; -static const uint16_t clv_flagsy_2_codes[] = { - 0x0000, 0x000C, 0x000B, 0x0008, 0x000A, 0x001C, 0x007E, 0x001D, - 0x000D, 0x003E, 0x001E, 0x00FE, 0x0009, 0x01FE, 0x03FE, 0x03FF, -}; - -static const uint8_t clv_flagsu_0_bits[] = { - 1, 4, 4, 4, 5, 5, 9, 7, 5, 9, 4, 7, 4, 8, 7, 4, -}; - -static const uint16_t clv_flagsu_0_codes[] = { - 0x0000, 0x000B, 0x000D, 0x0009, 0x001D, 0x001C, 0x01FF, 0x007D, - 0x001E, 0x01FE, 0x000C, 0x007C, 0x000A, 0x00FE, 0x007E, 0x0008, -}; - -static const uint8_t clv_flagsu_1_bits[] = { - 1, 4, 4, 4, 4, 4, 8, 6, 4, 8, 5, 8, 4, 10, 9, 10, -}; - -static const uint16_t clv_flagsu_1_codes[] = { - 0x0000, 0x000C, 0x0008, 0x000A, 0x000B, 0x000E, 0x00FD, 0x003E, - 0x000D, 0x00FC, 0x001E, 0x00FE, 0x0009, 0x03FE, 0x01FE, 0x03FF, -}; - -static const uint8_t clv_flagsv_0_bits[] = { - 1, 4, 5, 4, 5, 5, 8, 10, 5, 9, 5, 6, 4, 10, 7, 3, -}; - -static const uint16_t clv_flagsv_0_codes[] = { - 0x0000, 0x000A, 0x001B, 0x000C, 0x001E, 0x001C, 0x00FE, 0x03FE, - 0x001D, 0x01FE, 0x001A, 0x003E, 0x000B, 0x03FF, 0x007E, 0x0004, -}; - -static const uint8_t clv_flagsv_1_bits[] = { - 1, 4, 4, 4, 4, 5, 8, 6, 3, 7, 5, 10, 5, 11, 9, 11, -}; - -static const uint16_t clv_flagsv_1_codes[] = { - 0x0000, 0x000D, 0x000C, 0x000A, 0x000B, 0x001D, 0x00FE, 0x003E, - 0x0004, 0x007E, 0x001E, 0x03FE, 0x001C, 0x07FE, 0x01FE, 0x07FF, -}; - -static const uint8_t clv_mvy_0_bits[] = { - 16, 14, 13, 13, 13, 12, 11, 11, 9, 11, 11, 12, 13, 13, 13, 14, - 16, 15, 14, 14, 14, 13, 13, 12, 10, 7, 10, 12, 13, 13, 14, 14, - 14, 15, 15, 14, 14, 14, 13, 13, 11, 10, 7, 10, 11, 13, 13, 14, - 14, 14, 15, 15, 14, 14, 13, 13, 12, 11, 10, 7, 10, 11, 12, 13, - 13, 14, 14, 15, 16, 15, 14, 12, 12, 12, 11, 10, 6, 10, 11, 12, - 12, 12, 14, 15, 16, 15, 14, 13, 13, 12, 11, 10, 9, 6, 9, 10, - 11, 12, 13, 13, 14, 15, 14, 14, 13, 12, 12, 11, 10, 8, 6, 8, - 10, 11, 12, 12, 13, 14, 14, 14, 13, 13, 13, 11, 11, 9, 7, 4, - 7, 9, 11, 11, 12, 13, 13, 14, 11, 10, 10, 9, 9, 8, 7, 5, - 1, 5, 7, 8, 9, 9, 10, 10, 11, 14, 13, 13, 12, 11, 11, 9, - 7, 4, 7, 9, 11, 11, 13, 13, 13, 14, 14, 14, 13, 12, 12, 11, - 10, 8, 6, 8, 10, 11, 12, 12, 13, 14, 14, 15, 14, 13, 13, 12, - 11, 10, 9, 7, 9, 10, 11, 12, 13, 13, 14, 15, 16, 15, 14, 12, - 12, 12, 11, 10, 6, 10, 11, 12, 12, 12, 14, 15, 16, 15, 14, 14, - 13, 13, 12, 11, 10, 7, 10, 11, 12, 13, 13, 14, 14, 15, 15, 14, - 14, 14, 13, 13, 11, 10, 7, 10, 11, 13, 13, 14, 14, 14, 15, 15, - 14, 14, 14, 13, 13, 12, 10, 7, 10, 12, 13, 13, 14, 14, 14, 15, - 16, 14, 13, 13, 13, 12, 11, 11, 9, 11, 11, 12, 13, 13, 13, 14, - 16, 6, -}; - -static const uint16_t clv_mvy_0_codes[] = { - 0xFFFD, 0x3FE5, 0x1FD8, 0x1FC4, 0x1FBC, 0x0FCB, 0x07CF, 0x07C4, - 0x01D7, 0x07C6, 0x07CE, 0x0FCA, 0x1FBD, 0x1FC2, 0x1FD9, 0x3FE4, - 0xFFFE, 0x7FF0, 0x3FEF, 0x3FD2, 0x3FC9, 0x1FCC, 0x1FC0, 0x0FB6, - 0x03D6, 0x0070, 0x03D7, 0x0FB7, 0x1FC1, 0x1FCD, 0x3FCB, 0x3FD0, - 0x3FED, 0x7FF2, 0x7FFB, 0x3FDC, 0x3FD9, 0x3FD4, 0x1FB6, 0x1FAE, - 0x07C0, 0x03BC, 0x006D, 0x03BD, 0x07C1, 0x1FAF, 0x1FB7, 0x3FD1, - 0x3FDB, 0x3FDF, 0x7FF9, 0x7FEE, 0x3FF0, 0x3FC7, 0x1FC9, 0x1FA7, - 0x0FAD, 0x07D2, 0x03CE, 0x006C, 0x03CF, 0x07D0, 0x0FAF, 0x1FA6, - 0x1FC6, 0x3FC4, 0x3FF1, 0x7FED, 0xFFFB, 0x7FF6, 0x3FE6, 0x0FCC, - 0x0FC4, 0x0FB0, 0x07B0, 0x03C6, 0x0031, 0x03C7, 0x07B1, 0x0FB1, - 0x0FC5, 0x0FCD, 0x3FEA, 0x7FF7, 0xFFF9, 0x7FE9, 0x3FCE, 0x1FCF, - 0x1FB2, 0x0FB8, 0x07BC, 0x03D0, 0x01DA, 0x002F, 0x01DB, 0x03D1, - 0x07BE, 0x0FBA, 0x1FB4, 0x1FD0, 0x3FCD, 0x7FEB, 0x3FE1, 0x3FC1, - 0x1FD3, 0x0FC3, 0x0FBE, 0x07B6, 0x03C4, 0x00E4, 0x002D, 0x00E5, - 0x03C5, 0x07B7, 0x0FBF, 0x0FC1, 0x1FD2, 0x3FC3, 0x3FE2, 0x3FBF, - 0x1FDB, 0x1FAD, 0x1FA5, 0x07CB, 0x07BB, 0x01D5, 0x0068, 0x0008, - 0x0065, 0x01D2, 0x07B8, 0x07C8, 0x0FD0, 0x1FAA, 0x1FDA, 0x3FBC, - 0x07D4, 0x03CA, 0x03C0, 0x01D8, 0x01D0, 0x00E6, 0x0069, 0x0014, - 0x0000, 0x0015, 0x006A, 0x00E7, 0x01D1, 0x01D9, 0x03C1, 0x03CB, - 0x07D5, 0x3FBE, 0x1FDC, 0x1FAB, 0x0FD1, 0x07C9, 0x07B9, 0x01D3, - 0x0066, 0x0009, 0x0067, 0x01D4, 0x07BA, 0x07CA, 0x1FA4, 0x1FAC, - 0x1FDD, 0x3FBD, 0x3FE0, 0x3FC0, 0x1FD5, 0x0FC0, 0x0FBC, 0x07B4, - 0x03C2, 0x00E2, 0x002C, 0x00E3, 0x03C3, 0x07B5, 0x0FBD, 0x0FC2, - 0x1FD7, 0x3FC2, 0x3FE3, 0x7FEA, 0x3FCC, 0x1FCE, 0x1FB3, 0x0FB9, - 0x07BD, 0x03D2, 0x01DC, 0x0064, 0x01DD, 0x03D3, 0x07BF, 0x0FBB, - 0x1FB5, 0x1FD1, 0x3FCF, 0x7FE8, 0xFFFA, 0x7FF4, 0x3FEB, 0x0FCE, - 0x0FC6, 0x0FB2, 0x07B2, 0x03C8, 0x0030, 0x03C9, 0x07B3, 0x0FB3, - 0x0FC7, 0x0FCF, 0x3FE9, 0x7FF5, 0xFFF8, 0x7FF3, 0x3FF3, 0x3FC6, - 0x1FC8, 0x1FA8, 0x0FAC, 0x07D1, 0x03CC, 0x006B, 0x03CD, 0x07D3, - 0x0FAE, 0x1FA9, 0x1FC7, 0x3FC5, 0x3FF2, 0x7FEC, 0x7FFA, 0x3FDE, - 0x3FDA, 0x3FD7, 0x1FB9, 0x1FB0, 0x07C2, 0x03BE, 0x006E, 0x03BF, - 0x07C3, 0x1FB1, 0x1FB8, 0x3FD3, 0x3FD8, 0x3FDD, 0x7FF8, 0x7FEF, - 0x3FEE, 0x3FD6, 0x3FC8, 0x1FCB, 0x1FBE, 0x0FB5, 0x03D4, 0x006F, - 0x03D5, 0x0FB4, 0x1FBF, 0x1FCA, 0x3FCA, 0x3FD5, 0x3FEC, 0x7FF1, - 0xFFFF, 0x3FE8, 0x1FD4, 0x1FC5, 0x1FBA, 0x0FC9, 0x07CD, 0x07C7, - 0x01D6, 0x07C5, 0x07CC, 0x0FC8, 0x1FBB, 0x1FC3, 0x1FD6, 0x3FE7, - 0xFFFC, 0x002E, -}; - -static const uint16_t clv_mvy_0_syms[] = { - 0xF8F8, 0xF9F8, 0xFAF8, 0xFBF8, 0xFCF8, 0xFDF8, 0xFEF8, 0xFFF8, - 0x00F8, 0x01F8, 0x02F8, 0x03F8, 0x04F8, 0x05F8, 0x06F8, 0x07F8, - 0x08F8, 0xF8F9, 0xF9F9, 0xFAF9, 0xFBF9, 0xFCF9, 0xFDF9, 0xFEF9, - 0xFFF9, 0x00F9, 0x01F9, 0x02F9, 0x03F9, 0x04F9, 0x05F9, 0x06F9, - 0x07F9, 0x08F9, 0xF8FA, 0xF9FA, 0xFAFA, 0xFBFA, 0xFCFA, 0xFDFA, - 0xFEFA, 0xFFFA, 0x00FA, 0x01FA, 0x02FA, 0x03FA, 0x04FA, 0x05FA, - 0x06FA, 0x07FA, 0x08FA, 0xF8FB, 0xF9FB, 0xFAFB, 0xFBFB, 0xFCFB, - 0xFDFB, 0xFEFB, 0xFFFB, 0x00FB, 0x01FB, 0x02FB, 0x03FB, 0x04FB, - 0x05FB, 0x06FB, 0x07FB, 0x08FB, 0xF8FC, 0xF9FC, 0xFAFC, 0xFBFC, - 0xFCFC, 0xFDFC, 0xFEFC, 0xFFFC, 0x00FC, 0x01FC, 0x02FC, 0x03FC, - 0x04FC, 0x05FC, 0x06FC, 0x07FC, 0x08FC, 0xF8FD, 0xF9FD, 0xFAFD, - 0xFBFD, 0xFCFD, 0xFDFD, 0xFEFD, 0xFFFD, 0x00FD, 0x01FD, 0x02FD, - 0x03FD, 0x04FD, 0x05FD, 0x06FD, 0x07FD, 0x08FD, 0xF8FE, 0xF9FE, - 0xFAFE, 0xFBFE, 0xFCFE, 0xFDFE, 0xFEFE, 0xFFFE, 0x00FE, 0x01FE, - 0x02FE, 0x03FE, 0x04FE, 0x05FE, 0x06FE, 0x07FE, 0x08FE, 0xF8FF, - 0xF9FF, 0xFAFF, 0xFBFF, 0xFCFF, 0xFDFF, 0xFEFF, 0xFFFF, 0x00FF, - 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, 0x07FF, 0x08FF, - 0xF800, 0xF900, 0xFA00, 0xFB00, 0xFC00, 0xFD00, 0xFE00, 0xFF00, - 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, - 0x0800, 0xF801, 0xF901, 0xFA01, 0xFB01, 0xFC01, 0xFD01, 0xFE01, - 0xFF01, 0x0001, 0x0101, 0x0201, 0x0301, 0x0401, 0x0501, 0x0601, - 0x0701, 0x0801, 0xF802, 0xF902, 0xFA02, 0xFB02, 0xFC02, 0xFD02, - 0xFE02, 0xFF02, 0x0002, 0x0102, 0x0202, 0x0302, 0x0402, 0x0502, - 0x0602, 0x0702, 0x0802, 0xF803, 0xF903, 0xFA03, 0xFB03, 0xFC03, - 0xFD03, 0xFE03, 0xFF03, 0x0003, 0x0103, 0x0203, 0x0303, 0x0403, - 0x0503, 0x0603, 0x0703, 0x0803, 0xF804, 0xF904, 0xFA04, 0xFB04, - 0xFC04, 0xFD04, 0xFE04, 0xFF04, 0x0004, 0x0104, 0x0204, 0x0304, - 0x0404, 0x0504, 0x0604, 0x0704, 0x0804, 0xF805, 0xF905, 0xFA05, - 0xFB05, 0xFC05, 0xFD05, 0xFE05, 0xFF05, 0x0005, 0x0105, 0x0205, - 0x0305, 0x0405, 0x0505, 0x0605, 0x0705, 0x0805, 0xF806, 0xF906, - 0xFA06, 0xFB06, 0xFC06, 0xFD06, 0xFE06, 0xFF06, 0x0006, 0x0106, - 0x0206, 0x0306, 0x0406, 0x0506, 0x0606, 0x0706, 0x0806, 0xF807, - 0xF907, 0xFA07, 0xFB07, 0xFC07, 0xFD07, 0xFE07, 0xFF07, 0x0007, - 0x0107, 0x0207, 0x0307, 0x0407, 0x0507, 0x0607, 0x0707, 0x0807, - 0xF808, 0xF908, 0xFA08, 0xFB08, 0xFC08, 0xFD08, 0xFE08, 0xFF08, - 0x0008, 0x0108, 0x0208, 0x0308, 0x0408, 0x0508, 0x0608, 0x0708, - 0x0808, 0x0909, -}; - -static const uint8_t clv_mvy_1_bits[] = { - 15, 15, 15, 15, 14, 14, 13, 13, 11, 9, 11, 13, 13, 14, 14, 15, - 15, 15, 15, 15, 14, 14, 13, 13, 12, 12, 12, 10, 9, 10, 12, 12, - 12, 13, 13, 14, 14, 15, 15, 15, 14, 14, 13, 13, 13, 12, 11, 8, - 11, 12, 13, 13, 13, 14, 14, 15, 15, 14, 14, 14, 14, 13, 12, 12, - 12, 10, 8, 10, 12, 12, 12, 13, 14, 14, 14, 14, 15, 14, 14, 13, - 13, 12, 12, 11, 10, 8, 10, 11, 12, 12, 13, 13, 14, 14, 15, 14, - 14, 13, 13, 13, 12, 12, 11, 9, 7, 9, 11, 12, 12, 13, 13, 13, - 14, 14, 14, 14, 13, 13, 13, 12, 11, 10, 9, 7, 9, 10, 11, 12, - 13, 13, 13, 14, 14, 14, 13, 13, 12, 12, 11, 11, 10, 8, 7, 8, - 10, 11, 11, 12, 12, 13, 13, 14, 13, 13, 13, 12, 11, 11, 10, 9, - 6, 4, 6, 9, 10, 11, 12, 12, 13, 13, 13, 12, 11, 10, 10, 10, - 9, 9, 7, 5, 1, 5, 7, 9, 9, 10, 10, 10, 11, 12, 13, 13, - 13, 12, 11, 11, 10, 9, 6, 4, 6, 9, 10, 11, 11, 12, 13, 13, - 13, 14, 13, 13, 12, 12, 11, 11, 10, 8, 7, 8, 10, 11, 11, 12, - 12, 13, 13, 14, 14, 14, 13, 13, 13, 12, 11, 10, 9, 7, 9, 10, - 11, 12, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 12, 12, 11, 9, - 7, 9, 11, 12, 12, 13, 13, 13, 14, 14, 15, 14, 14, 13, 13, 12, - 12, 11, 10, 8, 10, 11, 12, 12, 13, 13, 14, 14, 15, 14, 14, 14, - 14, 13, 12, 12, 12, 10, 8, 10, 12, 12, 12, 13, 14, 14, 14, 14, - 15, 15, 14, 14, 13, 13, 13, 12, 11, 8, 11, 12, 13, 13, 13, 14, - 14, 15, 15, 15, 14, 14, 13, 13, 12, 12, 12, 10, 9, 10, 12, 12, - 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 14, 14, 13, 13, 11, 9, - 11, 13, 13, 14, 14, 15, 15, 15, 15, 5, -}; - -static const uint16_t clv_mvy_1_codes[] = { - 0x7FF9, 0x7FF6, 0x7FEB, 0x7FE3, 0x3FCF, 0x3FB3, 0x1FBD, 0x1FA1, - 0x07AD, 0x01CE, 0x07AF, 0x1FA0, 0x1FBB, 0x3FB0, 0x3FCC, 0x7FE2, - 0x7FE9, 0x7FF4, 0x7FFB, 0x7FF1, 0x3FE7, 0x3FBD, 0x1FA5, 0x1F9B, - 0x0FB4, 0x0FAF, 0x0FAA, 0x03CC, 0x01CD, 0x03CD, 0x0FAB, 0x0FAD, - 0x0FB1, 0x1F9C, 0x1FA3, 0x3FBE, 0x3FE6, 0x7FF0, 0x7FFC, 0x7FE5, - 0x3FB5, 0x3FAE, 0x1FB4, 0x1FAA, 0x1F97, 0x0F85, 0x07A2, 0x00DD, - 0x07A3, 0x0F86, 0x1F99, 0x1FAD, 0x1FB2, 0x3FAC, 0x3FB7, 0x7FE4, - 0x7FFD, 0x3FEA, 0x3FD8, 0x3FC3, 0x3FBB, 0x1FC9, 0x0FBC, 0x0F97, - 0x0F8F, 0x03B8, 0x00DA, 0x03B9, 0x0F90, 0x0F98, 0x0FB9, 0x1FC6, - 0x3FBA, 0x3FC0, 0x3FD9, 0x3FEB, 0x7FEF, 0x3FEE, 0x3FD7, 0x1FC3, - 0x1F96, 0x0FC0, 0x0FA8, 0x07AA, 0x03BE, 0x00D9, 0x03BF, 0x07AB, - 0x0FA7, 0x0FBF, 0x1F98, 0x1FC5, 0x3FD6, 0x3FEF, 0x7FEE, 0x3FDC, - 0x3FCA, 0x1FBF, 0x1F8B, 0x1F87, 0x0FA2, 0x0F94, 0x07A5, 0x01D4, - 0x0069, 0x01D5, 0x07A6, 0x0F95, 0x0FA3, 0x1F89, 0x1F8D, 0x1FC0, - 0x3FC6, 0x3FDE, 0x3FE0, 0x3FD3, 0x1FB8, 0x1F8F, 0x1F84, 0x0F89, - 0x07BC, 0x03C6, 0x01C6, 0x0067, 0x01C7, 0x03C7, 0x07BD, 0x0F87, - 0x1F82, 0x1F8A, 0x1FB6, 0x3FD1, 0x3FE2, 0x3FC5, 0x1FCE, 0x1FAE, - 0x0FB5, 0x0F8B, 0x07B4, 0x07B0, 0x03B4, 0x00DE, 0x0064, 0x00DF, - 0x03B5, 0x07B1, 0x07B5, 0x0F8C, 0x0FB6, 0x1FAF, 0x1FD1, 0x3FCB, - 0x1FD3, 0x1FCC, 0x1FA7, 0x0F9B, 0x07BE, 0x079C, 0x03C0, 0x01C8, - 0x002E, 0x0008, 0x002F, 0x01C9, 0x03C1, 0x079D, 0x0F82, 0x0F9A, - 0x1FA9, 0x1FCA, 0x1FD4, 0x0F9F, 0x07B6, 0x03C8, 0x03B2, 0x03B0, - 0x01D6, 0x01D0, 0x006A, 0x0014, 0x0000, 0x0015, 0x006B, 0x01D1, - 0x01D7, 0x03B1, 0x03B3, 0x03C9, 0x07B7, 0x0FA0, 0x1FD5, 0x1FCB, - 0x1FAB, 0x0F9C, 0x07BF, 0x079E, 0x03C2, 0x01CA, 0x0030, 0x0009, - 0x0031, 0x01CB, 0x03C3, 0x079F, 0x07C0, 0x0F9D, 0x1FAC, 0x1FCD, - 0x1FD2, 0x3FC8, 0x1FD0, 0x1FB0, 0x0FB7, 0x0F8D, 0x07B8, 0x07B2, - 0x03B6, 0x00E0, 0x0065, 0x00E1, 0x03B7, 0x07B3, 0x07B9, 0x0F8E, - 0x0FB8, 0x1FB1, 0x1FCF, 0x3FC9, 0x3FE1, 0x3FD2, 0x1FB7, 0x1F8E, - 0x1F83, 0x0F88, 0x07BA, 0x03C4, 0x01C4, 0x0066, 0x01C5, 0x03C5, - 0x07BB, 0x0F8A, 0x1F85, 0x1F90, 0x1FB9, 0x3FD0, 0x3FE3, 0x3FDD, - 0x3FC7, 0x1FC1, 0x1F91, 0x1F88, 0x0FA4, 0x0F96, 0x07A7, 0x01D2, - 0x0068, 0x01D3, 0x07A4, 0x0F93, 0x0FA1, 0x1F86, 0x1F8C, 0x1FBE, - 0x3FC4, 0x3FDF, 0x7FED, 0x3FEC, 0x3FD4, 0x1FC4, 0x1F92, 0x0FBD, - 0x0FA5, 0x07A8, 0x03BC, 0x00D8, 0x03BD, 0x07A9, 0x0FA6, 0x0FBE, - 0x1F93, 0x1FC2, 0x3FD5, 0x3FED, 0x7FEC, 0x3FE8, 0x3FDB, 0x3FC1, - 0x3FB9, 0x1FC7, 0x0FBA, 0x0F9E, 0x0F91, 0x03BA, 0x00DB, 0x03BB, - 0x0F92, 0x0F99, 0x0FBB, 0x1FC8, 0x3FB8, 0x3FC2, 0x3FDA, 0x3FE9, - 0x7FFF, 0x7FE7, 0x3FB6, 0x3FAF, 0x1FB3, 0x1FA6, 0x1F94, 0x0F83, - 0x07A0, 0x00DC, 0x07A1, 0x0F84, 0x1F95, 0x1FA8, 0x1FB5, 0x3FAD, - 0x3FB4, 0x7FE6, 0x7FFE, 0x7FF3, 0x3FE5, 0x3FBC, 0x1FA4, 0x1F9D, - 0x0FB2, 0x0FAE, 0x0FA9, 0x03CA, 0x01CC, 0x03CB, 0x0FAC, 0x0FB0, - 0x0FB3, 0x1F9A, 0x1FA2, 0x3FBF, 0x3FE4, 0x7FF2, 0x7FF8, 0x7FF5, - 0x7FEA, 0x7FE0, 0x3FCD, 0x3FB1, 0x1FBA, 0x1F9F, 0x07AE, 0x01CF, - 0x07AC, 0x1F9E, 0x1FBC, 0x3FB2, 0x3FCE, 0x7FE1, 0x7FE8, 0x7FF7, - 0x7FFA, 0x0016, -}; - -static const uint16_t clv_mvy_1_syms[] = { - 0xF7F7, 0xF8F7, 0xF9F7, 0xFAF7, 0xFBF7, 0xFCF7, 0xFDF7, 0xFEF7, - 0xFFF7, 0x00F7, 0x01F7, 0x02F7, 0x03F7, 0x04F7, 0x05F7, 0x06F7, - 0x07F7, 0x08F7, 0x09F7, 0xF7F8, 0xF8F8, 0xF9F8, 0xFAF8, 0xFBF8, - 0xFCF8, 0xFDF8, 0xFEF8, 0xFFF8, 0x00F8, 0x01F8, 0x02F8, 0x03F8, - 0x04F8, 0x05F8, 0x06F8, 0x07F8, 0x08F8, 0x09F8, 0xF7F9, 0xF8F9, - 0xF9F9, 0xFAF9, 0xFBF9, 0xFCF9, 0xFDF9, 0xFEF9, 0xFFF9, 0x00F9, - 0x01F9, 0x02F9, 0x03F9, 0x04F9, 0x05F9, 0x06F9, 0x07F9, 0x08F9, - 0x09F9, 0xF7FA, 0xF8FA, 0xF9FA, 0xFAFA, 0xFBFA, 0xFCFA, 0xFDFA, - 0xFEFA, 0xFFFA, 0x00FA, 0x01FA, 0x02FA, 0x03FA, 0x04FA, 0x05FA, - 0x06FA, 0x07FA, 0x08FA, 0x09FA, 0xF7FB, 0xF8FB, 0xF9FB, 0xFAFB, - 0xFBFB, 0xFCFB, 0xFDFB, 0xFEFB, 0xFFFB, 0x00FB, 0x01FB, 0x02FB, - 0x03FB, 0x04FB, 0x05FB, 0x06FB, 0x07FB, 0x08FB, 0x09FB, 0xF7FC, - 0xF8FC, 0xF9FC, 0xFAFC, 0xFBFC, 0xFCFC, 0xFDFC, 0xFEFC, 0xFFFC, - 0x00FC, 0x01FC, 0x02FC, 0x03FC, 0x04FC, 0x05FC, 0x06FC, 0x07FC, - 0x08FC, 0x09FC, 0xF7FD, 0xF8FD, 0xF9FD, 0xFAFD, 0xFBFD, 0xFCFD, - 0xFDFD, 0xFEFD, 0xFFFD, 0x00FD, 0x01FD, 0x02FD, 0x03FD, 0x04FD, - 0x05FD, 0x06FD, 0x07FD, 0x08FD, 0x09FD, 0xF7FE, 0xF8FE, 0xF9FE, - 0xFAFE, 0xFBFE, 0xFCFE, 0xFDFE, 0xFEFE, 0xFFFE, 0x00FE, 0x01FE, - 0x02FE, 0x03FE, 0x04FE, 0x05FE, 0x06FE, 0x07FE, 0x08FE, 0x09FE, - 0xF7FF, 0xF8FF, 0xF9FF, 0xFAFF, 0xFBFF, 0xFCFF, 0xFDFF, 0xFEFF, - 0xFFFF, 0x00FF, 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, - 0x07FF, 0x08FF, 0x09FF, 0xF700, 0xF800, 0xF900, 0xFA00, 0xFB00, - 0xFC00, 0xFD00, 0xFE00, 0xFF00, 0x0000, 0x0100, 0x0200, 0x0300, - 0x0400, 0x0500, 0x0600, 0x0700, 0x0800, 0x0900, 0xF701, 0xF801, - 0xF901, 0xFA01, 0xFB01, 0xFC01, 0xFD01, 0xFE01, 0xFF01, 0x0001, - 0x0101, 0x0201, 0x0301, 0x0401, 0x0501, 0x0601, 0x0701, 0x0801, - 0x0901, 0xF702, 0xF802, 0xF902, 0xFA02, 0xFB02, 0xFC02, 0xFD02, - 0xFE02, 0xFF02, 0x0002, 0x0102, 0x0202, 0x0302, 0x0402, 0x0502, - 0x0602, 0x0702, 0x0802, 0x0902, 0xF703, 0xF803, 0xF903, 0xFA03, - 0xFB03, 0xFC03, 0xFD03, 0xFE03, 0xFF03, 0x0003, 0x0103, 0x0203, - 0x0303, 0x0403, 0x0503, 0x0603, 0x0703, 0x0803, 0x0903, 0xF704, - 0xF804, 0xF904, 0xFA04, 0xFB04, 0xFC04, 0xFD04, 0xFE04, 0xFF04, - 0x0004, 0x0104, 0x0204, 0x0304, 0x0404, 0x0504, 0x0604, 0x0704, - 0x0804, 0x0904, 0xF705, 0xF805, 0xF905, 0xFA05, 0xFB05, 0xFC05, - 0xFD05, 0xFE05, 0xFF05, 0x0005, 0x0105, 0x0205, 0x0305, 0x0405, - 0x0505, 0x0605, 0x0705, 0x0805, 0x0905, 0xF706, 0xF806, 0xF906, - 0xFA06, 0xFB06, 0xFC06, 0xFD06, 0xFE06, 0xFF06, 0x0006, 0x0106, - 0x0206, 0x0306, 0x0406, 0x0506, 0x0606, 0x0706, 0x0806, 0x0906, - 0xF707, 0xF807, 0xF907, 0xFA07, 0xFB07, 0xFC07, 0xFD07, 0xFE07, - 0xFF07, 0x0007, 0x0107, 0x0207, 0x0307, 0x0407, 0x0507, 0x0607, - 0x0707, 0x0807, 0x0907, 0xF708, 0xF808, 0xF908, 0xFA08, 0xFB08, - 0xFC08, 0xFD08, 0xFE08, 0xFF08, 0x0008, 0x0108, 0x0208, 0x0308, - 0x0408, 0x0508, 0x0608, 0x0708, 0x0808, 0x0908, 0xF709, 0xF809, - 0xF909, 0xFA09, 0xFB09, 0xFC09, 0xFD09, 0xFE09, 0xFF09, 0x0009, - 0x0109, 0x0209, 0x0309, 0x0409, 0x0509, 0x0609, 0x0709, 0x0809, - 0x0909, 0x0A0A, -}; - -static const uint8_t clv_mvy_2_bits[] = { - 16, 16, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 13, 12, 11, - 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, - 15, 15, 15, 15, 15, 14, 14, 14, 14, 13, 13, 13, 13, 11, 10, 11, - 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 15, - 15, 15, 15, 14, 14, 14, 14, 14, 14, 13, 13, 13, 11, 10, 11, 13, - 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 15, 15, - 15, 14, 14, 14, 14, 14, 14, 13, 13, 13, 12, 11, 9, 11, 12, 13, - 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 16, 16, 15, 15, 14, - 14, 13, 13, 13, 13, 13, 13, 13, 12, 11, 11, 9, 11, 11, 12, 13, - 13, 13, 13, 13, 13, 13, 14, 14, 14, 15, 16, 16, 15, 15, 15, 14, - 13, 13, 13, 13, 13, 13, 13, 12, 11, 11, 9, 11, 11, 12, 13, 13, - 13, 13, 13, 13, 13, 14, 15, 15, 15, 16, 16, 15, 15, 15, 15, 14, - 14, 13, 13, 13, 12, 12, 12, 11, 11, 9, 11, 11, 12, 12, 12, 13, - 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 15, 15, 14, 14, 14, 13, - 13, 13, 12, 12, 12, 12, 11, 10, 8, 10, 11, 12, 12, 12, 12, 13, - 13, 13, 14, 14, 14, 15, 15, 16, 16, 15, 14, 14, 14, 13, 13, 13, - 13, 12, 12, 12, 11, 11, 10, 8, 10, 11, 11, 12, 12, 12, 13, 13, - 13, 13, 14, 14, 14, 15, 16, 15, 15, 14, 14, 13, 13, 13, 13, 13, - 12, 12, 12, 11, 10, 9, 8, 9, 10, 11, 12, 12, 12, 13, 13, 13, - 13, 13, 14, 14, 15, 15, 15, 15, 14, 14, 13, 13, 13, 13, 13, 12, - 12, 11, 11, 10, 10, 7, 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, - 13, 14, 14, 15, 15, 14, 14, 14, 14, 13, 13, 12, 12, 12, 12, 12, - 11, 11, 10, 9, 7, 9, 10, 11, 11, 12, 12, 12, 12, 12, 13, 13, - 14, 14, 14, 14, 15, 13, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, - 11, 10, 8, 7, 8, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, - 13, 13, 15, 14, 14, 14, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, - 9, 8, 6, 8, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 14, - 14, 14, 16, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 9, 9, 8, - 6, 4, 6, 8, 9, 9, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, - 16, 12, 12, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 8, 7, 4, - 2, 4, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, - 16, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 9, 9, 8, 6, 4, - 6, 8, 9, 9, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 16, 14, - 14, 14, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 9, 8, 6, 8, - 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 13, - 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 8, 7, 8, 10, - 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 15, 14, 14, 14, - 14, 13, 13, 12, 12, 12, 12, 12, 11, 11, 10, 9, 7, 9, 10, 11, - 11, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 14, 14, - 13, 13, 13, 13, 13, 12, 12, 11, 11, 10, 10, 7, 10, 10, 11, 11, - 12, 12, 13, 13, 13, 13, 13, 14, 14, 15, 15, 15, 15, 14, 14, 13, - 13, 13, 13, 13, 12, 12, 12, 11, 10, 9, 8, 9, 10, 11, 12, 12, - 12, 13, 13, 13, 13, 13, 14, 14, 15, 15, 16, 15, 14, 14, 14, 13, - 13, 13, 13, 12, 12, 12, 11, 11, 10, 8, 10, 11, 11, 12, 12, 12, - 13, 13, 13, 13, 14, 14, 14, 15, 16, 16, 15, 15, 14, 14, 14, 13, - 13, 13, 12, 12, 12, 12, 11, 10, 8, 10, 11, 12, 12, 12, 12, 13, - 13, 13, 14, 14, 14, 15, 15, 16, 16, 15, 15, 15, 15, 14, 14, 13, - 13, 13, 12, 12, 12, 11, 11, 9, 11, 11, 12, 12, 12, 13, 13, 13, - 14, 14, 15, 15, 15, 15, 16, 16, 15, 15, 15, 14, 13, 13, 13, 13, - 13, 13, 13, 12, 11, 11, 9, 11, 11, 12, 13, 13, 13, 13, 13, 13, - 13, 14, 15, 15, 15, 16, 16, 15, 15, 14, 14, 13, 13, 13, 13, 13, - 13, 13, 12, 11, 11, 9, 11, 11, 12, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 15, 16, 16, 15, 15, 15, 14, 14, 14, 14, 14, 14, 13, - 13, 13, 12, 11, 9, 11, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 13, - 13, 13, 11, 10, 11, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, - 15, 15, 16, 16, 15, 15, 15, 15, 15, 14, 14, 14, 14, 13, 13, 13, - 13, 12, 10, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, - 15, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 13, - 12, 11, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 16, - 16, 7, -}; - -static const uint16_t clv_mvy_2_codes[] = { - 0xFFF5, 0xFFD8, 0x7FE6, 0x7FB9, 0x7FB5, 0x7FB0, 0x7FA0, 0x7F99, - 0x7F93, 0x3FAA, 0x3F9B, 0x3F52, 0x1F76, 0x1EF5, 0x0F0B, 0x06F0, - 0x0F08, 0x1EF0, 0x1F75, 0x3F53, 0x3F9A, 0x3FA8, 0x7F94, 0x7F98, - 0x7F9E, 0x7FAE, 0x7FAF, 0x7FB7, 0x7FE9, 0xFFDB, 0xFFF6, 0xFFFD, - 0x7FD9, 0x7FCC, 0x7FC6, 0x7F9C, 0x7F80, 0x3FA5, 0x3F80, 0x3F6A, - 0x3F31, 0x1F54, 0x1F40, 0x1F11, 0x1F05, 0x075E, 0x0360, 0x075F, - 0x1F07, 0x1F12, 0x1F43, 0x1F56, 0x3F33, 0x3F68, 0x3F83, 0x3FA6, - 0x7F7F, 0x7F9A, 0x7FC9, 0x7FCA, 0x7FDB, 0xFFF8, 0xFFEC, 0x7FDE, - 0x7FE2, 0x7FA6, 0x7F6F, 0x3FA1, 0x3F8D, 0x3F5C, 0x3F39, 0x3F21, - 0x3F18, 0x1F58, 0x1F1E, 0x1EF1, 0x0740, 0x035A, 0x0741, 0x1EF2, - 0x1F1F, 0x1F5A, 0x3F19, 0x3F22, 0x3F3B, 0x3F5E, 0x3F8E, 0x3FA3, - 0x7F6B, 0x7FA2, 0x7FE3, 0x7FE1, 0xFFEE, 0xFFFC, 0x7FC3, 0x7FBC, - 0x7F71, 0x3F96, 0x3F86, 0x3F7A, 0x3F72, 0x3F59, 0x3F46, 0x1F0A, - 0x1EFD, 0x1ED0, 0x0F02, 0x0712, 0x019F, 0x0713, 0x0F03, 0x1ED3, - 0x1EFF, 0x1F09, 0x3F4A, 0x3F5A, 0x3F76, 0x3F7B, 0x3F87, 0x3F97, - 0x7F73, 0x7FBB, 0x7FBF, 0xFFFB, 0xFFEB, 0x7F88, 0x7F5C, 0x3F7C, - 0x3F3C, 0x1F60, 0x1F4C, 0x1F14, 0x1F0C, 0x1F00, 0x1EF9, 0x1ED8, - 0x0F42, 0x075A, 0x0714, 0x0186, 0x0715, 0x075B, 0x0F43, 0x1EDA, - 0x1EFA, 0x1F01, 0x1F0E, 0x1F15, 0x1F4D, 0x1F62, 0x3F3D, 0x3F7D, - 0x3FAC, 0x7F86, 0xFFE8, 0xFFE7, 0x7FA7, 0x7F8C, 0x7F68, 0x3F9C, - 0x1F7C, 0x1F6C, 0x1F69, 0x1EEC, 0x1EE4, 0x1ED5, 0x1ECD, 0x0EF0, - 0x0752, 0x06F6, 0x018C, 0x06F7, 0x0753, 0x0EF1, 0x1ECE, 0x1ED6, - 0x1EE5, 0x1EED, 0x1F6A, 0x1F6E, 0x1F7D, 0x3F9F, 0x7F66, 0x7F8A, - 0x7FA5, 0xFFE6, 0xFFDC, 0x7FDA, 0x7FC0, 0x7FAC, 0x7F61, 0x3F42, - 0x3F0E, 0x1F45, 0x1F2C, 0x1ECA, 0x0F27, 0x0EF6, 0x0EEE, 0x072E, - 0x06F4, 0x0185, 0x06F5, 0x072F, 0x0EEF, 0x0EF7, 0x0F28, 0x1ECB, - 0x1F2F, 0x1F46, 0x3F0F, 0x3F40, 0x7F5F, 0x7FB4, 0x7FC2, 0x7FDC, - 0xFFDA, 0xFFE0, 0x7F72, 0x7F63, 0x3F70, 0x3F1C, 0x3F16, 0x1F82, - 0x1EE2, 0x1EB2, 0x0F4C, 0x0EFC, 0x0EE0, 0x0ED3, 0x0722, 0x036C, - 0x00BF, 0x036D, 0x0723, 0x0ECC, 0x0EE1, 0x0EFF, 0x0F4D, 0x1EB3, - 0x1EE3, 0x1F83, 0x3F17, 0x3F1F, 0x3F75, 0x7F65, 0x7F70, 0xFFE2, - 0xFFD7, 0x7F76, 0x3F2B, 0x3F13, 0x3F0A, 0x1F33, 0x1F23, 0x1EB4, - 0x1EA0, 0x0F46, 0x0F32, 0x0F1A, 0x0756, 0x0728, 0x0356, 0x00B0, - 0x0357, 0x0729, 0x0757, 0x0F1B, 0x0F33, 0x0F47, 0x1EA1, 0x1EB5, - 0x1F20, 0x1F30, 0x3F08, 0x3F10, 0x3F28, 0x7F77, 0xFFD5, 0x7FD5, - 0x7FD1, 0x3F5D, 0x3F25, 0x1F34, 0x1F24, 0x1EE8, 0x1EBC, 0x1EA8, - 0x0F3A, 0x0F2E, 0x0EE2, 0x071C, 0x0374, 0x01A0, 0x00AE, 0x01A1, - 0x0375, 0x071D, 0x0EE3, 0x0F2F, 0x0F3C, 0x1EA9, 0x1EBD, 0x1EE9, - 0x1F25, 0x1F36, 0x3F24, 0x3F61, 0x7FCE, 0x7FD2, 0x7F91, 0x7F7D, - 0x3F6C, 0x3F34, 0x1F72, 0x1F61, 0x1EDD, 0x1EC5, 0x1EA5, 0x0F05, - 0x0ED6, 0x0750, 0x073E, 0x0368, 0x034A, 0x0052, 0x034B, 0x0369, - 0x073F, 0x0751, 0x0ED7, 0x0F07, 0x1EA7, 0x1EC7, 0x1EDF, 0x1F65, - 0x1F70, 0x3F36, 0x3F6F, 0x7F7C, 0x7F8F, 0x3F90, 0x3F66, 0x3F58, - 0x3F4E, 0x1F48, 0x1EBB, 0x0F40, 0x0F18, 0x0F10, 0x0EDA, 0x0ECF, - 0x0732, 0x0704, 0x0354, 0x0190, 0x004F, 0x0191, 0x0355, 0x0705, - 0x0733, 0x0ED0, 0x0EDB, 0x0F11, 0x0F19, 0x0F41, 0x1EB8, 0x1F4B, - 0x3F4F, 0x3F55, 0x3F65, 0x3F92, 0x7F85, 0x1F51, 0x1F39, 0x1F2B, - 0x1F18, 0x1EC2, 0x0F38, 0x0F14, 0x0ECA, 0x074C, 0x0736, 0x0700, - 0x06FC, 0x0350, 0x00BA, 0x004D, 0x00BB, 0x0351, 0x06FD, 0x0701, - 0x0737, 0x074D, 0x0ECB, 0x0F15, 0x0F39, 0x1EC3, 0x1F1B, 0x1F2E, - 0x1F3A, 0x1F53, 0x7F82, 0x3F8A, 0x3F47, 0x3F2E, 0x1F5E, 0x1E9E, - 0x0F24, 0x0F20, 0x0EC6, 0x0746, 0x0726, 0x070E, 0x0370, 0x035E, - 0x018A, 0x00AC, 0x0021, 0x00AD, 0x018B, 0x035F, 0x0371, 0x070F, - 0x0727, 0x0747, 0x0EC7, 0x0F21, 0x0F25, 0x1E9F, 0x1F5F, 0x3F2D, - 0x3F48, 0x3F8B, 0xFFF1, 0x1F78, 0x1F3D, 0x1EAD, 0x0F2B, 0x0EF9, - 0x0EE9, 0x0739, 0x0719, 0x0709, 0x0363, 0x019B, 0x0195, 0x00B3, - 0x0023, 0x0005, 0x0024, 0x00B4, 0x0196, 0x019C, 0x0364, 0x070A, - 0x071A, 0x073A, 0x0EEA, 0x0EFA, 0x0F2C, 0x1EAE, 0x1F3E, 0x1F79, - 0xFFF0, 0x0F0C, 0x0EE6, 0x0EDC, 0x0EC2, 0x0748, 0x0706, 0x0372, - 0x034C, 0x0198, 0x0192, 0x00C0, 0x00BC, 0x00B6, 0x0053, 0x0006, - 0x0000, 0x0007, 0x0054, 0x00B7, 0x00BD, 0x00C1, 0x0193, 0x0199, - 0x034D, 0x0373, 0x0707, 0x0749, 0x0EC3, 0x0EDD, 0x0EE7, 0x0F0D, - 0xFFF2, 0x1F7A, 0x1F3F, 0x1EAF, 0x0F2D, 0x0EFB, 0x0EEB, 0x073B, - 0x071B, 0x070B, 0x0365, 0x019D, 0x0197, 0x00B5, 0x0025, 0x0004, - 0x0022, 0x00B2, 0x0194, 0x019A, 0x0362, 0x0708, 0x0718, 0x0738, - 0x0EE8, 0x0EF8, 0x0F2A, 0x1EAC, 0x1F3C, 0x1F7B, 0xFFF3, 0x3F89, - 0x3F44, 0x3F2F, 0x1F5C, 0x1E9C, 0x0F22, 0x0F1E, 0x0EC4, 0x0744, - 0x0724, 0x070C, 0x036E, 0x035C, 0x0188, 0x00AA, 0x0020, 0x00AB, - 0x0189, 0x035D, 0x036F, 0x070D, 0x0725, 0x0745, 0x0EC5, 0x0F1F, - 0x0F23, 0x1E9D, 0x1F5D, 0x3F2C, 0x3F45, 0x3F88, 0x7F81, 0x1F52, - 0x1F38, 0x1F28, 0x1F19, 0x1EC0, 0x0F36, 0x0F12, 0x0EC8, 0x074A, - 0x0734, 0x06FE, 0x06FA, 0x034E, 0x00B8, 0x004C, 0x00B9, 0x034F, - 0x06FB, 0x06FF, 0x0735, 0x074B, 0x0EC9, 0x0F13, 0x0F37, 0x1EC1, - 0x1F1A, 0x1F29, 0x1F3B, 0x1F50, 0x7F84, 0x3F91, 0x3F64, 0x3F54, - 0x3F4C, 0x1F49, 0x1EB9, 0x0F3B, 0x0F16, 0x0F0E, 0x0ED8, 0x0ECD, - 0x0730, 0x0702, 0x0352, 0x018E, 0x004E, 0x018F, 0x0353, 0x0703, - 0x0731, 0x0ECE, 0x0ED9, 0x0F0F, 0x0F17, 0x0F3D, 0x1EBA, 0x1F4A, - 0x3F4D, 0x3F51, 0x3F67, 0x3F93, 0x7F90, 0x7F7A, 0x3F6E, 0x3F37, - 0x1F71, 0x1F63, 0x1EDC, 0x1EC4, 0x1EA4, 0x0F04, 0x0ED4, 0x074E, - 0x073C, 0x0366, 0x0348, 0x0051, 0x0349, 0x0367, 0x073D, 0x074F, - 0x0ED5, 0x0F06, 0x1EA6, 0x1EC6, 0x1EDE, 0x1F64, 0x1F73, 0x3F35, - 0x3F6D, 0x7F7B, 0x7F8E, 0x7FD4, 0x7FD0, 0x3F5F, 0x3F26, 0x1F35, - 0x1F27, 0x1EEA, 0x1EBE, 0x1EAA, 0x0F3E, 0x0F30, 0x0EE4, 0x071E, - 0x0376, 0x01A2, 0x00AF, 0x01A3, 0x0377, 0x071F, 0x0EE5, 0x0F31, - 0x0F3F, 0x1EAB, 0x1EBF, 0x1EEB, 0x1F26, 0x1F37, 0x3F27, 0x3F62, - 0x7FCF, 0x7FD3, 0xFFD4, 0x7F78, 0x3F29, 0x3F11, 0x3F0B, 0x1F32, - 0x1F22, 0x1EB6, 0x1EA2, 0x0F48, 0x0F34, 0x0F1C, 0x0758, 0x072A, - 0x0358, 0x00B1, 0x0359, 0x072B, 0x0759, 0x0F1D, 0x0F35, 0x0F49, - 0x1EA3, 0x1EB7, 0x1F21, 0x1F31, 0x3F09, 0x3F12, 0x3F2A, 0x7F79, - 0xFFD6, 0xFFE1, 0x7F6D, 0x7F64, 0x3F73, 0x3F1D, 0x3F14, 0x1F81, - 0x1EE0, 0x1EB0, 0x0F4A, 0x0EFD, 0x0EDE, 0x0ED1, 0x0720, 0x036A, - 0x00BE, 0x036B, 0x0721, 0x0ED2, 0x0EDF, 0x0EFE, 0x0F4B, 0x1EB1, - 0x1EE1, 0x1F7E, 0x3F15, 0x3F1E, 0x3F74, 0x7F62, 0x7F75, 0xFFE3, - 0xFFDE, 0x7FDD, 0x7FBE, 0x7FB3, 0x7F60, 0x3F43, 0x3F0C, 0x1F47, - 0x1F2D, 0x1EC8, 0x0F26, 0x0EF4, 0x0EEC, 0x072C, 0x06F2, 0x0184, - 0x06F3, 0x072D, 0x0EED, 0x0EF5, 0x0F29, 0x1EC9, 0x1F2A, 0x1F44, - 0x3F0D, 0x3F41, 0x7F5E, 0x7FB1, 0x7FC1, 0x7FD7, 0xFFDF, 0xFFEA, - 0x7FA3, 0x7F8B, 0x7F69, 0x3F9E, 0x1F7F, 0x1F6D, 0x1F6B, 0x1EEE, - 0x1EE6, 0x1ED4, 0x1ECF, 0x0EF2, 0x0754, 0x06F8, 0x018D, 0x06F9, - 0x0755, 0x0EF3, 0x1ECC, 0x1ED7, 0x1EE7, 0x1EEF, 0x1F68, 0x1F6F, - 0x1F80, 0x3F9D, 0x7F67, 0x7F8D, 0x7FA8, 0xFFE9, 0xFFE5, 0x7F89, - 0x7F5D, 0x3F7F, 0x3F3F, 0x1F67, 0x1F4F, 0x1F17, 0x1F0F, 0x1F02, - 0x1EFB, 0x1ED9, 0x0F45, 0x075C, 0x0716, 0x0187, 0x0717, 0x075D, - 0x0F44, 0x1EDB, 0x1EF8, 0x1F03, 0x1F0D, 0x1F16, 0x1F4E, 0x1F66, - 0x3F3E, 0x3F7E, 0x3FAD, 0x7F87, 0xFFE4, 0xFFF9, 0x7FC4, 0x7FBA, - 0x7F6E, 0x3F95, 0x3F85, 0x3F78, 0x3F77, 0x3F5B, 0x3F49, 0x1F08, - 0x1EFE, 0x1ED2, 0x0F01, 0x0710, 0x019E, 0x0711, 0x0F00, 0x1ED1, - 0x1EFC, 0x1F0B, 0x3F4B, 0x3F57, 0x3F71, 0x3F79, 0x3F84, 0x3F94, - 0x7F74, 0x7FBD, 0x7FC5, 0xFFFE, 0xFFED, 0x7FE0, 0x7FDF, 0x7FA4, - 0x7F6A, 0x3FA0, 0x3F8F, 0x3F63, 0x3F3A, 0x3F23, 0x3F1A, 0x1F59, - 0x1F1D, 0x1EF3, 0x0743, 0x035B, 0x0742, 0x1EF7, 0x1F1C, 0x1F5B, - 0x3F1B, 0x3F20, 0x3F38, 0x3F60, 0x3F8C, 0x3FA2, 0x7F6C, 0x7FA9, - 0x7FE5, 0x7FE4, 0xFFEF, 0xFFFF, 0x7FD6, 0x7FCB, 0x7FC7, 0x7F9B, - 0x7F83, 0x3FA4, 0x3F81, 0x3F69, 0x3F30, 0x1F57, 0x1F41, 0x1F13, - 0x1F06, 0x0EC0, 0x0361, 0x0EC1, 0x1F04, 0x1F10, 0x1F42, 0x1F55, - 0x3F32, 0x3F6B, 0x3F82, 0x3FA7, 0x7F7E, 0x7F9D, 0x7FC8, 0x7FCD, - 0x7FD8, 0xFFFA, 0xFFF7, 0xFFD9, 0x7FE8, 0x7FB6, 0x7FAB, 0x7FAA, - 0x7FA1, 0x7F96, 0x7F95, 0x3FAB, 0x3F98, 0x3F50, 0x1F77, 0x1EF4, - 0x0F0A, 0x06F1, 0x0F09, 0x1EF6, 0x1F74, 0x3F56, 0x3F99, 0x3FA9, - 0x7F92, 0x7F97, 0x7F9F, 0x7FAD, 0x7FB2, 0x7FB8, 0x7FE7, 0xFFDD, - 0xFFF4, 0x0050, -}; - -static const uint16_t clv_mvy_2_syms[] = { - 0xF1F1, 0xF2F1, 0xF3F1, 0xF4F1, 0xF5F1, 0xF6F1, 0xF7F1, 0xF8F1, - 0xF9F1, 0xFAF1, 0xFBF1, 0xFCF1, 0xFDF1, 0xFEF1, 0xFFF1, 0x00F1, - 0x01F1, 0x02F1, 0x03F1, 0x04F1, 0x05F1, 0x06F1, 0x07F1, 0x08F1, - 0x09F1, 0x0AF1, 0x0BF1, 0x0CF1, 0x0DF1, 0x0EF1, 0x0FF1, 0xF1F2, - 0xF2F2, 0xF3F2, 0xF4F2, 0xF5F2, 0xF6F2, 0xF7F2, 0xF8F2, 0xF9F2, - 0xFAF2, 0xFBF2, 0xFCF2, 0xFDF2, 0xFEF2, 0xFFF2, 0x00F2, 0x01F2, - 0x02F2, 0x03F2, 0x04F2, 0x05F2, 0x06F2, 0x07F2, 0x08F2, 0x09F2, - 0x0AF2, 0x0BF2, 0x0CF2, 0x0DF2, 0x0EF2, 0x0FF2, 0xF1F3, 0xF2F3, - 0xF3F3, 0xF4F3, 0xF5F3, 0xF6F3, 0xF7F3, 0xF8F3, 0xF9F3, 0xFAF3, - 0xFBF3, 0xFCF3, 0xFDF3, 0xFEF3, 0xFFF3, 0x00F3, 0x01F3, 0x02F3, - 0x03F3, 0x04F3, 0x05F3, 0x06F3, 0x07F3, 0x08F3, 0x09F3, 0x0AF3, - 0x0BF3, 0x0CF3, 0x0DF3, 0x0EF3, 0x0FF3, 0xF1F4, 0xF2F4, 0xF3F4, - 0xF4F4, 0xF5F4, 0xF6F4, 0xF7F4, 0xF8F4, 0xF9F4, 0xFAF4, 0xFBF4, - 0xFCF4, 0xFDF4, 0xFEF4, 0xFFF4, 0x00F4, 0x01F4, 0x02F4, 0x03F4, - 0x04F4, 0x05F4, 0x06F4, 0x07F4, 0x08F4, 0x09F4, 0x0AF4, 0x0BF4, - 0x0CF4, 0x0DF4, 0x0EF4, 0x0FF4, 0xF1F5, 0xF2F5, 0xF3F5, 0xF4F5, - 0xF5F5, 0xF6F5, 0xF7F5, 0xF8F5, 0xF9F5, 0xFAF5, 0xFBF5, 0xFCF5, - 0xFDF5, 0xFEF5, 0xFFF5, 0x00F5, 0x01F5, 0x02F5, 0x03F5, 0x04F5, - 0x05F5, 0x06F5, 0x07F5, 0x08F5, 0x09F5, 0x0AF5, 0x0BF5, 0x0CF5, - 0x0DF5, 0x0EF5, 0x0FF5, 0xF1F6, 0xF2F6, 0xF3F6, 0xF4F6, 0xF5F6, - 0xF6F6, 0xF7F6, 0xF8F6, 0xF9F6, 0xFAF6, 0xFBF6, 0xFCF6, 0xFDF6, - 0xFEF6, 0xFFF6, 0x00F6, 0x01F6, 0x02F6, 0x03F6, 0x04F6, 0x05F6, - 0x06F6, 0x07F6, 0x08F6, 0x09F6, 0x0AF6, 0x0BF6, 0x0CF6, 0x0DF6, - 0x0EF6, 0x0FF6, 0xF1F7, 0xF2F7, 0xF3F7, 0xF4F7, 0xF5F7, 0xF6F7, - 0xF7F7, 0xF8F7, 0xF9F7, 0xFAF7, 0xFBF7, 0xFCF7, 0xFDF7, 0xFEF7, - 0xFFF7, 0x00F7, 0x01F7, 0x02F7, 0x03F7, 0x04F7, 0x05F7, 0x06F7, - 0x07F7, 0x08F7, 0x09F7, 0x0AF7, 0x0BF7, 0x0CF7, 0x0DF7, 0x0EF7, - 0x0FF7, 0xF1F8, 0xF2F8, 0xF3F8, 0xF4F8, 0xF5F8, 0xF6F8, 0xF7F8, - 0xF8F8, 0xF9F8, 0xFAF8, 0xFBF8, 0xFCF8, 0xFDF8, 0xFEF8, 0xFFF8, - 0x00F8, 0x01F8, 0x02F8, 0x03F8, 0x04F8, 0x05F8, 0x06F8, 0x07F8, - 0x08F8, 0x09F8, 0x0AF8, 0x0BF8, 0x0CF8, 0x0DF8, 0x0EF8, 0x0FF8, - 0xF1F9, 0xF2F9, 0xF3F9, 0xF4F9, 0xF5F9, 0xF6F9, 0xF7F9, 0xF8F9, - 0xF9F9, 0xFAF9, 0xFBF9, 0xFCF9, 0xFDF9, 0xFEF9, 0xFFF9, 0x00F9, - 0x01F9, 0x02F9, 0x03F9, 0x04F9, 0x05F9, 0x06F9, 0x07F9, 0x08F9, - 0x09F9, 0x0AF9, 0x0BF9, 0x0CF9, 0x0DF9, 0x0EF9, 0x0FF9, 0xF1FA, - 0xF2FA, 0xF3FA, 0xF4FA, 0xF5FA, 0xF6FA, 0xF7FA, 0xF8FA, 0xF9FA, - 0xFAFA, 0xFBFA, 0xFCFA, 0xFDFA, 0xFEFA, 0xFFFA, 0x00FA, 0x01FA, - 0x02FA, 0x03FA, 0x04FA, 0x05FA, 0x06FA, 0x07FA, 0x08FA, 0x09FA, - 0x0AFA, 0x0BFA, 0x0CFA, 0x0DFA, 0x0EFA, 0x0FFA, 0xF1FB, 0xF2FB, - 0xF3FB, 0xF4FB, 0xF5FB, 0xF6FB, 0xF7FB, 0xF8FB, 0xF9FB, 0xFAFB, - 0xFBFB, 0xFCFB, 0xFDFB, 0xFEFB, 0xFFFB, 0x00FB, 0x01FB, 0x02FB, - 0x03FB, 0x04FB, 0x05FB, 0x06FB, 0x07FB, 0x08FB, 0x09FB, 0x0AFB, - 0x0BFB, 0x0CFB, 0x0DFB, 0x0EFB, 0x0FFB, 0xF1FC, 0xF2FC, 0xF3FC, - 0xF4FC, 0xF5FC, 0xF6FC, 0xF7FC, 0xF8FC, 0xF9FC, 0xFAFC, 0xFBFC, - 0xFCFC, 0xFDFC, 0xFEFC, 0xFFFC, 0x00FC, 0x01FC, 0x02FC, 0x03FC, - 0x04FC, 0x05FC, 0x06FC, 0x07FC, 0x08FC, 0x09FC, 0x0AFC, 0x0BFC, - 0x0CFC, 0x0DFC, 0x0EFC, 0x0FFC, 0xF1FD, 0xF2FD, 0xF3FD, 0xF4FD, - 0xF5FD, 0xF6FD, 0xF7FD, 0xF8FD, 0xF9FD, 0xFAFD, 0xFBFD, 0xFCFD, - 0xFDFD, 0xFEFD, 0xFFFD, 0x00FD, 0x01FD, 0x02FD, 0x03FD, 0x04FD, - 0x05FD, 0x06FD, 0x07FD, 0x08FD, 0x09FD, 0x0AFD, 0x0BFD, 0x0CFD, - 0x0DFD, 0x0EFD, 0x0FFD, 0xF1FE, 0xF2FE, 0xF3FE, 0xF4FE, 0xF5FE, - 0xF6FE, 0xF7FE, 0xF8FE, 0xF9FE, 0xFAFE, 0xFBFE, 0xFCFE, 0xFDFE, - 0xFEFE, 0xFFFE, 0x00FE, 0x01FE, 0x02FE, 0x03FE, 0x04FE, 0x05FE, - 0x06FE, 0x07FE, 0x08FE, 0x09FE, 0x0AFE, 0x0BFE, 0x0CFE, 0x0DFE, - 0x0EFE, 0x0FFE, 0xF1FF, 0xF2FF, 0xF3FF, 0xF4FF, 0xF5FF, 0xF6FF, - 0xF7FF, 0xF8FF, 0xF9FF, 0xFAFF, 0xFBFF, 0xFCFF, 0xFDFF, 0xFEFF, - 0xFFFF, 0x00FF, 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, - 0x07FF, 0x08FF, 0x09FF, 0x0AFF, 0x0BFF, 0x0CFF, 0x0DFF, 0x0EFF, - 0x0FFF, 0xF100, 0xF200, 0xF300, 0xF400, 0xF500, 0xF600, 0xF700, - 0xF800, 0xF900, 0xFA00, 0xFB00, 0xFC00, 0xFD00, 0xFE00, 0xFF00, - 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, - 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, - 0xF101, 0xF201, 0xF301, 0xF401, 0xF501, 0xF601, 0xF701, 0xF801, - 0xF901, 0xFA01, 0xFB01, 0xFC01, 0xFD01, 0xFE01, 0xFF01, 0x0001, - 0x0101, 0x0201, 0x0301, 0x0401, 0x0501, 0x0601, 0x0701, 0x0801, - 0x0901, 0x0A01, 0x0B01, 0x0C01, 0x0D01, 0x0E01, 0x0F01, 0xF102, - 0xF202, 0xF302, 0xF402, 0xF502, 0xF602, 0xF702, 0xF802, 0xF902, - 0xFA02, 0xFB02, 0xFC02, 0xFD02, 0xFE02, 0xFF02, 0x0002, 0x0102, - 0x0202, 0x0302, 0x0402, 0x0502, 0x0602, 0x0702, 0x0802, 0x0902, - 0x0A02, 0x0B02, 0x0C02, 0x0D02, 0x0E02, 0x0F02, 0xF103, 0xF203, - 0xF303, 0xF403, 0xF503, 0xF603, 0xF703, 0xF803, 0xF903, 0xFA03, - 0xFB03, 0xFC03, 0xFD03, 0xFE03, 0xFF03, 0x0003, 0x0103, 0x0203, - 0x0303, 0x0403, 0x0503, 0x0603, 0x0703, 0x0803, 0x0903, 0x0A03, - 0x0B03, 0x0C03, 0x0D03, 0x0E03, 0x0F03, 0xF104, 0xF204, 0xF304, - 0xF404, 0xF504, 0xF604, 0xF704, 0xF804, 0xF904, 0xFA04, 0xFB04, - 0xFC04, 0xFD04, 0xFE04, 0xFF04, 0x0004, 0x0104, 0x0204, 0x0304, - 0x0404, 0x0504, 0x0604, 0x0704, 0x0804, 0x0904, 0x0A04, 0x0B04, - 0x0C04, 0x0D04, 0x0E04, 0x0F04, 0xF105, 0xF205, 0xF305, 0xF405, - 0xF505, 0xF605, 0xF705, 0xF805, 0xF905, 0xFA05, 0xFB05, 0xFC05, - 0xFD05, 0xFE05, 0xFF05, 0x0005, 0x0105, 0x0205, 0x0305, 0x0405, - 0x0505, 0x0605, 0x0705, 0x0805, 0x0905, 0x0A05, 0x0B05, 0x0C05, - 0x0D05, 0x0E05, 0x0F05, 0xF106, 0xF206, 0xF306, 0xF406, 0xF506, - 0xF606, 0xF706, 0xF806, 0xF906, 0xFA06, 0xFB06, 0xFC06, 0xFD06, - 0xFE06, 0xFF06, 0x0006, 0x0106, 0x0206, 0x0306, 0x0406, 0x0506, - 0x0606, 0x0706, 0x0806, 0x0906, 0x0A06, 0x0B06, 0x0C06, 0x0D06, - 0x0E06, 0x0F06, 0xF107, 0xF207, 0xF307, 0xF407, 0xF507, 0xF607, - 0xF707, 0xF807, 0xF907, 0xFA07, 0xFB07, 0xFC07, 0xFD07, 0xFE07, - 0xFF07, 0x0007, 0x0107, 0x0207, 0x0307, 0x0407, 0x0507, 0x0607, - 0x0707, 0x0807, 0x0907, 0x0A07, 0x0B07, 0x0C07, 0x0D07, 0x0E07, - 0x0F07, 0xF108, 0xF208, 0xF308, 0xF408, 0xF508, 0xF608, 0xF708, - 0xF808, 0xF908, 0xFA08, 0xFB08, 0xFC08, 0xFD08, 0xFE08, 0xFF08, - 0x0008, 0x0108, 0x0208, 0x0308, 0x0408, 0x0508, 0x0608, 0x0708, - 0x0808, 0x0908, 0x0A08, 0x0B08, 0x0C08, 0x0D08, 0x0E08, 0x0F08, - 0xF109, 0xF209, 0xF309, 0xF409, 0xF509, 0xF609, 0xF709, 0xF809, - 0xF909, 0xFA09, 0xFB09, 0xFC09, 0xFD09, 0xFE09, 0xFF09, 0x0009, - 0x0109, 0x0209, 0x0309, 0x0409, 0x0509, 0x0609, 0x0709, 0x0809, - 0x0909, 0x0A09, 0x0B09, 0x0C09, 0x0D09, 0x0E09, 0x0F09, 0xF10A, - 0xF20A, 0xF30A, 0xF40A, 0xF50A, 0xF60A, 0xF70A, 0xF80A, 0xF90A, - 0xFA0A, 0xFB0A, 0xFC0A, 0xFD0A, 0xFE0A, 0xFF0A, 0x000A, 0x010A, - 0x020A, 0x030A, 0x040A, 0x050A, 0x060A, 0x070A, 0x080A, 0x090A, - 0x0A0A, 0x0B0A, 0x0C0A, 0x0D0A, 0x0E0A, 0x0F0A, 0xF10B, 0xF20B, - 0xF30B, 0xF40B, 0xF50B, 0xF60B, 0xF70B, 0xF80B, 0xF90B, 0xFA0B, - 0xFB0B, 0xFC0B, 0xFD0B, 0xFE0B, 0xFF0B, 0x000B, 0x010B, 0x020B, - 0x030B, 0x040B, 0x050B, 0x060B, 0x070B, 0x080B, 0x090B, 0x0A0B, - 0x0B0B, 0x0C0B, 0x0D0B, 0x0E0B, 0x0F0B, 0xF10C, 0xF20C, 0xF30C, - 0xF40C, 0xF50C, 0xF60C, 0xF70C, 0xF80C, 0xF90C, 0xFA0C, 0xFB0C, - 0xFC0C, 0xFD0C, 0xFE0C, 0xFF0C, 0x000C, 0x010C, 0x020C, 0x030C, - 0x040C, 0x050C, 0x060C, 0x070C, 0x080C, 0x090C, 0x0A0C, 0x0B0C, - 0x0C0C, 0x0D0C, 0x0E0C, 0x0F0C, 0xF10D, 0xF20D, 0xF30D, 0xF40D, - 0xF50D, 0xF60D, 0xF70D, 0xF80D, 0xF90D, 0xFA0D, 0xFB0D, 0xFC0D, - 0xFD0D, 0xFE0D, 0xFF0D, 0x000D, 0x010D, 0x020D, 0x030D, 0x040D, - 0x050D, 0x060D, 0x070D, 0x080D, 0x090D, 0x0A0D, 0x0B0D, 0x0C0D, - 0x0D0D, 0x0E0D, 0x0F0D, 0xF10E, 0xF20E, 0xF30E, 0xF40E, 0xF50E, - 0xF60E, 0xF70E, 0xF80E, 0xF90E, 0xFA0E, 0xFB0E, 0xFC0E, 0xFD0E, - 0xFE0E, 0xFF0E, 0x000E, 0x010E, 0x020E, 0x030E, 0x040E, 0x050E, - 0x060E, 0x070E, 0x080E, 0x090E, 0x0A0E, 0x0B0E, 0x0C0E, 0x0D0E, - 0x0E0E, 0x0F0E, 0xF10F, 0xF20F, 0xF30F, 0xF40F, 0xF50F, 0xF60F, - 0xF70F, 0xF80F, 0xF90F, 0xFA0F, 0xFB0F, 0xFC0F, 0xFD0F, 0xFE0F, - 0xFF0F, 0x000F, 0x010F, 0x020F, 0x030F, 0x040F, 0x050F, 0x060F, - 0x070F, 0x080F, 0x090F, 0x0A0F, 0x0B0F, 0x0C0F, 0x0D0F, 0x0E0F, - 0x0F0F, 0x1010, -}; - -static const uint8_t clv_mvy_3_bits[] = { - 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 13, - 13, 12, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, - 15, 15, 14, 14, 14, 13, 12, 11, 12, 13, 14, 14, 14, 15, 15, 15, - 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, - 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 12, 11, 12, 14, 14, - 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, - 16, 16, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, - 12, 11, 12, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, - 15, 16, 16, 16, 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 13, 13, 12, 10, 12, 13, 13, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 15, 15, 15, 15, - 14, 14, 14, 14, 13, 13, 13, 13, 13, 12, 12, 10, 12, 12, 13, 13, - 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 15, 15, - 15, 15, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 11, - 10, 11, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, - 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, - 12, 12, 12, 11, 10, 9, 10, 11, 12, 12, 12, 12, 12, 13, 13, 13, - 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 13, - 12, 12, 12, 12, 12, 12, 12, 11, 11, 10, 9, 10, 11, 11, 12, 12, - 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 16, 15, 15, - 15, 15, 14, 14, 13, 13, 12, 12, 12, 12, 12, 11, 11, 11, 10, 9, - 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, - 15, 16, 15, 15, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 12, 12, - 11, 11, 11, 10, 9, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, - 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 14, 14, 14, 13, 13, 12, - 12, 12, 12, 12, 12, 11, 11, 11, 10, 8, 10, 11, 11, 11, 12, 12, - 12, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 14, 14, - 14, 14, 13, 13, 12, 12, 12, 12, 12, 11, 11, 11, 10, 10, 8, 10, - 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 15, - 15, 15, 14, 14, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, - 10, 10, 9, 7, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, - 13, 14, 14, 14, 14, 15, 15, 14, 14, 14, 14, 13, 13, 13, 12, 12, - 12, 12, 11, 11, 11, 10, 10, 9, 7, 9, 10, 10, 11, 11, 11, 12, - 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 14, 14, 14, 14, - 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, 10, 9, 9, 7, 9, 9, - 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 15, - 15, 14, 14, 14, 13, 13, 13, 13, 12, 11, 11, 11, 11, 10, 10, 10, - 9, 8, 6, 8, 9, 10, 10, 10, 11, 11, 11, 11, 12, 13, 13, 13, - 13, 14, 14, 14, 15, 15, 14, 14, 14, 13, 13, 12, 12, 11, 11, 11, - 11, 10, 10, 9, 9, 8, 6, 4, 6, 8, 9, 9, 10, 10, 11, 11, - 11, 11, 12, 12, 13, 13, 14, 14, 14, 15, 13, 13, 13, 12, 12, 12, - 12, 11, 10, 10, 10, 10, 9, 9, 8, 8, 7, 5, 2, 5, 7, 8, - 8, 9, 9, 10, 10, 10, 10, 11, 12, 12, 12, 12, 13, 13, 13, 15, - 14, 14, 14, 13, 13, 12, 12, 11, 11, 11, 11, 10, 10, 9, 9, 8, - 6, 4, 6, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, - 14, 14, 14, 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 11, 11, 11, - 11, 10, 10, 10, 9, 8, 6, 8, 9, 10, 10, 10, 11, 11, 11, 11, - 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 14, 14, 14, 14, 13, 13, - 12, 12, 12, 12, 11, 11, 11, 11, 10, 9, 9, 7, 9, 9, 10, 11, - 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 14, - 14, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 9, - 7, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, - 14, 14, 15, 15, 14, 14, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, - 11, 11, 10, 10, 9, 7, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, - 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 14, 14, 14, 14, 13, 13, - 12, 12, 12, 12, 12, 11, 11, 11, 10, 10, 8, 10, 10, 11, 11, 11, - 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, - 14, 14, 14, 13, 13, 12, 12, 12, 12, 12, 12, 11, 11, 11, 10, 8, - 10, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 15, - 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 12, 12, - 11, 11, 11, 10, 9, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, - 14, 14, 14, 14, 14, 15, 15, 16, 15, 15, 15, 15, 14, 14, 13, 13, - 12, 12, 12, 12, 12, 11, 11, 11, 10, 9, 10, 11, 11, 11, 12, 12, - 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 15, 15, 14, - 14, 14, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 10, 9, 10, - 11, 11, 12, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, - 15, 15, 15, 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 12, - 12, 11, 10, 9, 10, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, - 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, - 13, 13, 13, 13, 13, 13, 13, 11, 10, 11, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 15, 15, - 15, 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 12, 12, 10, 12, 12, - 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, - 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, - 13, 12, 10, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, - 15, 15, 15, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 14, - 14, 14, 14, 14, 13, 13, 12, 11, 12, 13, 13, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 15, 15, 15, - 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 12, 11, 12, 14, 14, - 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, - 12, 11, 12, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, - 15, 14, 14, 13, 13, 12, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, - 15, 15, 16, 16, 16, 16, 16, 16, 16, 7, -}; - -static const uint16_t clv_mvy_3_codes[] = { - 0xFFF6, 0xFFEE, 0xFFDC, 0xFFD7, 0xFFB4, 0xFFAA, 0xFFA0, 0x7FCC, - 0x7F8E, 0x7F7B, 0x7F77, 0x7F13, 0x7F11, 0x3F56, 0x3F48, 0x1F16, - 0x1E94, 0x0F28, 0x06F0, 0x0F2A, 0x1E96, 0x1F1C, 0x3F46, 0x3F58, - 0x7F15, 0x7F0E, 0x7F76, 0x7F80, 0x7F90, 0x7FC8, 0xFFA2, 0xFFA7, - 0xFFB5, 0xFFD8, 0xFFDD, 0xFFEC, 0xFFF5, 0xFFF1, 0xFFEA, 0xFFE4, - 0xFFD1, 0xFFC1, 0xFFA8, 0x7F70, 0x7F5C, 0x7F44, 0x7F40, 0x7F2A, - 0x7F16, 0x7EDF, 0x3ED6, 0x3ECA, 0x3ECC, 0x1EB5, 0x0EDE, 0x06D3, - 0x0EDF, 0x1EB6, 0x3ECE, 0x3ED0, 0x3ED8, 0x7EE5, 0x7F19, 0x7F31, - 0x7F3E, 0x7F45, 0x7F5B, 0x7F6F, 0xFFA9, 0xFFC0, 0xFFCE, 0xFFE5, - 0xFFE8, 0xFFF2, 0xFFFE, 0xFFE2, 0xFFBE, 0x7FBB, 0x7F75, 0x7F6B, - 0x7F58, 0x7EF9, 0x7EDC, 0x3F68, 0x3F27, 0x3F28, 0x3EDF, 0x3ED2, - 0x3EC1, 0x3EA6, 0x3E87, 0x0F0F, 0x06B3, 0x0F10, 0x3E89, 0x3EA8, - 0x3EC3, 0x3ED5, 0x3EE0, 0x3F2B, 0x3F26, 0x3F67, 0x7EDA, 0x7EFB, - 0x7F56, 0x7F6A, 0x7F72, 0x7FC1, 0xFFBC, 0xFFE0, 0xFFFF, 0xFFF8, - 0xFFD3, 0xFFB9, 0x7FAC, 0x7F94, 0x7F8B, 0x7F62, 0x7F4A, 0x7F05, - 0x7EEE, 0x3F44, 0x3EA4, 0x3E78, 0x3E6F, 0x3E54, 0x1EEF, 0x1EA9, - 0x0ED4, 0x06A8, 0x0ED5, 0x1EA8, 0x1EEC, 0x3E51, 0x3E69, 0x3E75, - 0x3EA3, 0x3F43, 0x7EF1, 0x7F04, 0x7F4B, 0x7F5D, 0x7F89, 0x7F95, - 0x7FAA, 0xFFBB, 0xFFC8, 0xFFF9, 0xFFD9, 0xFFCA, 0x7FC3, 0x7F8C, - 0x7F38, 0x7F02, 0x3F5A, 0x3F4A, 0x3F30, 0x3EFF, 0x3EF4, 0x3EE9, - 0x3E95, 0x3E73, 0x3E43, 0x1F08, 0x1E81, 0x0E84, 0x0349, 0x0E85, - 0x1E82, 0x1F07, 0x3E45, 0x3E74, 0x3E96, 0x3EEA, 0x3EF1, 0x3F00, - 0x3F32, 0x3F4F, 0x3F5C, 0x7F01, 0x7F3B, 0x7F8D, 0x7FC2, 0xFFCF, - 0xFFD6, 0xFFC7, 0xFFB1, 0xFFA6, 0x7FA1, 0x7F2F, 0x7F24, 0x7F0A, - 0x3EF6, 0x3E97, 0x3E83, 0x3E7F, 0x1F04, 0x1EE1, 0x1ECB, 0x1EAE, - 0x1E7E, 0x0EBA, 0x0E8C, 0x0333, 0x0E8D, 0x0EBB, 0x1E7F, 0x1EAF, - 0x1ECC, 0x1EE2, 0x1F05, 0x3E80, 0x3E84, 0x3E98, 0x3EF9, 0x7F06, - 0x7F1B, 0x7F2D, 0x7F9F, 0xFFAF, 0xFFB0, 0xFFC6, 0x7FB5, 0x7FB1, - 0x7F36, 0x7F25, 0x3F63, 0x3F3A, 0x3F1B, 0x3EBB, 0x3E63, 0x3E5B, - 0x3E40, 0x1F14, 0x1EF5, 0x1EEB, 0x1EBE, 0x1E92, 0x1E6A, 0x070C, - 0x032D, 0x070D, 0x1E6B, 0x1E93, 0x1EBF, 0x1EE8, 0x1EF3, 0x1F15, - 0x3E3F, 0x3E5C, 0x3E64, 0x3EB9, 0x3F1C, 0x3F3C, 0x3F62, 0x7F22, - 0x7F39, 0x7FAF, 0x7FAE, 0x7FC6, 0x7F7F, 0x7F53, 0x7F32, 0x3F66, - 0x3EF0, 0x3E65, 0x1EDA, 0x1ED3, 0x1E98, 0x1E74, 0x0F20, 0x0F1D, - 0x0EEA, 0x0EA9, 0x0E70, 0x0718, 0x033E, 0x0179, 0x033F, 0x0719, - 0x0E71, 0x0EAB, 0x0EE9, 0x0F1F, 0x0F22, 0x1E76, 0x1E9B, 0x1ED5, - 0x1EDD, 0x3E68, 0x3EF3, 0x3F6C, 0x7F33, 0x7F4E, 0x7F7D, 0x7FCB, - 0x7FBD, 0x7F21, 0x7EF6, 0x3F0C, 0x3EBE, 0x3EAE, 0x1EA3, 0x1E85, - 0x0F0C, 0x0F06, 0x0EEE, 0x0EE6, 0x0ECA, 0x0EA2, 0x0E78, 0x0720, - 0x06BA, 0x0326, 0x015D, 0x0327, 0x06BB, 0x0721, 0x0E79, 0x0EA3, - 0x0ECB, 0x0EE7, 0x0EEF, 0x0F07, 0x0F0D, 0x1E86, 0x1EA4, 0x3EAF, - 0x3EBF, 0x3F0A, 0x7EF8, 0x7F1E, 0x7FBF, 0xFF9F, 0x7FB3, 0x7F96, - 0x7F0B, 0x7EF5, 0x3E85, 0x3E4E, 0x1EB3, 0x1E6E, 0x0F2D, 0x0EBD, - 0x0E97, 0x0E93, 0x0E86, 0x071A, 0x06E4, 0x06BC, 0x0338, 0x015A, - 0x0339, 0x06BD, 0x06E5, 0x071B, 0x0E87, 0x0E94, 0x0E98, 0x0EBE, - 0x0F2E, 0x1E6F, 0x1EB4, 0x3E4F, 0x3E88, 0x7EF4, 0x7F07, 0x7F99, - 0x7FB7, 0xFF9D, 0x7FA8, 0x7EEB, 0x3F5D, 0x3EB2, 0x3EAA, 0x3E5D, - 0x3E49, 0x1EFE, 0x1E89, 0x0F16, 0x0F12, 0x0EE0, 0x0E7A, 0x0E6A, - 0x070E, 0x06FA, 0x06B4, 0x0314, 0x0158, 0x0315, 0x06B5, 0x06FB, - 0x070F, 0x0E6B, 0x0E7B, 0x0EE1, 0x0F13, 0x0F17, 0x1E8A, 0x1EFF, - 0x3E4A, 0x3E5E, 0x3EAB, 0x3EB3, 0x3F59, 0x7EEC, 0x7FA2, 0x7F82, - 0x7F5E, 0x7F28, 0x3EDA, 0x3EC9, 0x3E7A, 0x1ED6, 0x1ECE, 0x0EFC, - 0x0EF0, 0x0E9A, 0x0E7E, 0x0E66, 0x0E5E, 0x0722, 0x06C0, 0x06A0, - 0x02FA, 0x00A8, 0x02FB, 0x06A1, 0x06C1, 0x0723, 0x0E5F, 0x0E67, - 0x0E7F, 0x0E9B, 0x0EF1, 0x0EFD, 0x1ECF, 0x1ED7, 0x3E79, 0x3ECD, - 0x3EDB, 0x7F26, 0x7F5A, 0x7F83, 0x7F54, 0x7EE8, 0x3F54, 0x3F0E, - 0x3EFB, 0x3E47, 0x1EC1, 0x1EB9, 0x0EF9, 0x0EF3, 0x0EC1, 0x0E8F, - 0x0E74, 0x0714, 0x06F4, 0x06B0, 0x0336, 0x030A, 0x009F, 0x030B, - 0x0337, 0x06B1, 0x06F5, 0x0715, 0x0E75, 0x0E91, 0x0EC3, 0x0EF6, - 0x0EFB, 0x1EBB, 0x1EC3, 0x3E41, 0x3EF8, 0x3F10, 0x3F4D, 0x7EE9, - 0x7F52, 0x7F9A, 0x3F3F, 0x3F1F, 0x3F03, 0x3EA0, 0x1F0F, 0x1E72, - 0x1E62, 0x0EDA, 0x0ED2, 0x0EB2, 0x0E64, 0x0708, 0x06EA, 0x06DA, - 0x0346, 0x032A, 0x0176, 0x004B, 0x0177, 0x032B, 0x0347, 0x06DB, - 0x06EB, 0x0709, 0x0E65, 0x0EB3, 0x0ED3, 0x0EDB, 0x1E63, 0x1E6C, - 0x1F0E, 0x3E9E, 0x3F01, 0x3F1D, 0x3F3D, 0x7F9B, 0x7EDE, 0x3F36, - 0x3F2E, 0x3F07, 0x3E99, 0x1F0D, 0x1EA1, 0x1E8C, 0x0EB4, 0x0EAC, - 0x0E5A, 0x0E50, 0x0702, 0x06D4, 0x06C6, 0x032E, 0x0310, 0x0162, - 0x0046, 0x0163, 0x0311, 0x032F, 0x06C7, 0x06D5, 0x0703, 0x0E51, - 0x0E5B, 0x0EAD, 0x0EB5, 0x1E8F, 0x1EA7, 0x1F0C, 0x3E9A, 0x3F02, - 0x3F2D, 0x3F35, 0x7EE0, 0x7F66, 0x3F11, 0x3EE1, 0x3EBC, 0x3E56, - 0x1EC4, 0x1E64, 0x0F04, 0x0EC7, 0x0E56, 0x0E4C, 0x06EC, 0x06DC, - 0x069C, 0x0694, 0x0320, 0x016C, 0x0154, 0x0044, 0x0155, 0x016D, - 0x0321, 0x0695, 0x069D, 0x06DD, 0x06ED, 0x0E4D, 0x0E57, 0x0EC4, - 0x0F05, 0x1E65, 0x1EC5, 0x3E55, 0x3EB7, 0x3EE3, 0x3F13, 0x7F67, - 0x7FA7, 0x3F49, 0x3F22, 0x3EE5, 0x1EF6, 0x1EE5, 0x1E9C, 0x1E78, - 0x0EA4, 0x06F6, 0x06DE, 0x06CE, 0x06AA, 0x0340, 0x0318, 0x02FE, - 0x015E, 0x009A, 0x001C, 0x009B, 0x015F, 0x02FF, 0x0319, 0x0341, - 0x06AB, 0x06CF, 0x06DF, 0x06F7, 0x0EA5, 0x1E79, 0x1E9D, 0x1EE7, - 0x1EF7, 0x3EE6, 0x3F23, 0x3F4B, 0x7FA3, 0x7F49, 0x3F14, 0x3E8D, - 0x3E6B, 0x1F17, 0x1EF8, 0x0F24, 0x0ECC, 0x06FE, 0x06CA, 0x06A4, - 0x0698, 0x030C, 0x0302, 0x0170, 0x0168, 0x00A0, 0x001E, 0x0004, - 0x001F, 0x00A1, 0x0169, 0x0171, 0x0303, 0x030D, 0x0699, 0x06A5, - 0x06CB, 0x06FF, 0x0ECD, 0x0F25, 0x1EF9, 0x1F18, 0x3E6C, 0x3E8E, - 0x3F15, 0x7F46, 0x1EF0, 0x1EDE, 0x1EC8, 0x0F1A, 0x0F00, 0x0E9E, - 0x0E54, 0x06C4, 0x031E, 0x031C, 0x0306, 0x02F8, 0x017A, 0x0166, - 0x00A6, 0x00A4, 0x0048, 0x000C, 0x0000, 0x000D, 0x0049, 0x00A5, - 0x00A7, 0x0167, 0x017B, 0x02F9, 0x0307, 0x031D, 0x031F, 0x06C5, - 0x0E55, 0x0E9F, 0x0F01, 0x0F1B, 0x1EC9, 0x1EDF, 0x1EF1, 0x7F47, - 0x3F12, 0x3E8F, 0x3E6D, 0x1F1B, 0x1EFA, 0x0F26, 0x0ECE, 0x0700, - 0x06CC, 0x06A6, 0x069A, 0x030E, 0x0304, 0x0172, 0x016A, 0x00A2, - 0x0020, 0x0005, 0x0021, 0x00A3, 0x016B, 0x0173, 0x0305, 0x030F, - 0x069B, 0x06A7, 0x06CD, 0x0701, 0x0ECF, 0x0F27, 0x1EFB, 0x1F1D, - 0x3E6E, 0x3E90, 0x3F17, 0x7F48, 0x7FA9, 0x3F50, 0x3F24, 0x3EE7, - 0x1EFC, 0x1EE9, 0x1E9E, 0x1E7A, 0x0EA6, 0x06F8, 0x06E0, 0x06D0, - 0x06AC, 0x0342, 0x031A, 0x0300, 0x0160, 0x009C, 0x001D, 0x009D, - 0x0161, 0x0301, 0x031B, 0x0343, 0x06AD, 0x06D1, 0x06E1, 0x06F9, - 0x0EA7, 0x1E7B, 0x1E9F, 0x1EEA, 0x1EFD, 0x3EE8, 0x3F21, 0x3F52, - 0x7F9E, 0x7F68, 0x3F16, 0x3EE2, 0x3EBA, 0x3E57, 0x1EC6, 0x1E66, - 0x0F08, 0x0EC5, 0x0E58, 0x0E4E, 0x06EE, 0x06E2, 0x069E, 0x0696, - 0x0322, 0x016E, 0x0156, 0x0045, 0x0157, 0x016F, 0x0323, 0x0697, - 0x069F, 0x06E3, 0x06EF, 0x0E4F, 0x0E59, 0x0EC6, 0x0F09, 0x1E67, - 0x1EC7, 0x3E58, 0x3EB8, 0x3EE4, 0x3F18, 0x7F69, 0x7EE2, 0x3F38, - 0x3F33, 0x3F04, 0x3E9C, 0x1F0A, 0x1EA5, 0x1E8D, 0x0EB6, 0x0EAE, - 0x0E5C, 0x0E52, 0x0704, 0x06D6, 0x06C8, 0x0330, 0x0312, 0x0164, - 0x0047, 0x0165, 0x0313, 0x0331, 0x06C9, 0x06D7, 0x0705, 0x0E53, - 0x0E5D, 0x0EAF, 0x0EB7, 0x1E8E, 0x1EA6, 0x1F0B, 0x3E9B, 0x3F05, - 0x3F31, 0x3F39, 0x7EE1, 0x7F9C, 0x3F40, 0x3F1E, 0x3F06, 0x3E9D, - 0x1F10, 0x1E70, 0x1E60, 0x0ED8, 0x0ED0, 0x0EB0, 0x0E62, 0x0706, - 0x06E8, 0x06D8, 0x0344, 0x0328, 0x0174, 0x004A, 0x0175, 0x0329, - 0x0345, 0x06D9, 0x06E9, 0x0707, 0x0E63, 0x0EB1, 0x0ED1, 0x0ED9, - 0x1E61, 0x1E71, 0x1F11, 0x3E9F, 0x3F08, 0x3F20, 0x3F3E, 0x7F9D, - 0x7F4F, 0x7EE6, 0x3F53, 0x3F0D, 0x3EFA, 0x3E46, 0x1EC0, 0x1EB8, - 0x0EF8, 0x0EF2, 0x0EC0, 0x0E8E, 0x0E72, 0x0712, 0x06F2, 0x06AE, - 0x0334, 0x0308, 0x009E, 0x0309, 0x0335, 0x06AF, 0x06F3, 0x0713, - 0x0E73, 0x0E90, 0x0EC2, 0x0EF4, 0x0EFA, 0x1EBA, 0x1EC2, 0x3E48, - 0x3EFC, 0x3F0B, 0x3F51, 0x7EE7, 0x7F51, 0x7F84, 0x7F61, 0x7F27, - 0x3EDC, 0x3EC5, 0x3E7C, 0x1ED8, 0x1ED0, 0x0EFE, 0x0EF5, 0x0E9C, - 0x0E80, 0x0E68, 0x0E60, 0x0724, 0x06C2, 0x06A2, 0x02FC, 0x00A9, - 0x02FD, 0x06A3, 0x06C3, 0x0725, 0x0E61, 0x0E69, 0x0E81, 0x0E9D, - 0x0EF7, 0x0EFF, 0x1ED1, 0x1ED9, 0x3E7B, 0x3ECF, 0x3ED9, 0x7F29, - 0x7F65, 0x7F85, 0x7FA0, 0x7EEA, 0x3F60, 0x3EB4, 0x3EAC, 0x3E5F, - 0x3E4B, 0x1F00, 0x1E8B, 0x0F18, 0x0F14, 0x0EE2, 0x0E7C, 0x0E6C, - 0x0710, 0x06FC, 0x06B6, 0x0316, 0x0159, 0x0317, 0x06B7, 0x06FD, - 0x0711, 0x0E6D, 0x0E7D, 0x0EE3, 0x0F15, 0x0F19, 0x1E88, 0x1F01, - 0x3E4C, 0x3E60, 0x3EA9, 0x3EB1, 0x3F5B, 0x7EED, 0x7FA5, 0xFF9E, - 0x7FBE, 0x7F98, 0x7F0D, 0x7EF3, 0x3E8C, 0x3E50, 0x1EB7, 0x1E73, - 0x0F2F, 0x0EBF, 0x0E99, 0x0E95, 0x0E88, 0x071C, 0x06E6, 0x06BE, - 0x033A, 0x015B, 0x033B, 0x06BF, 0x06E7, 0x071D, 0x0E89, 0x0E92, - 0x0E96, 0x0EBC, 0x0F2C, 0x1E6D, 0x1EB0, 0x3E4D, 0x3E8B, 0x7EF2, - 0x7F08, 0x7F97, 0x7FB0, 0xFF9C, 0x7FB2, 0x7F23, 0x7EFA, 0x3F0F, - 0x3EBD, 0x3EAD, 0x1EA0, 0x1E87, 0x0F0A, 0x0F02, 0x0EED, 0x0EE4, - 0x0EC8, 0x0EA0, 0x0E76, 0x071E, 0x06B8, 0x0324, 0x015C, 0x0325, - 0x06B9, 0x071F, 0x0E77, 0x0EA1, 0x0EC9, 0x0EE5, 0x0EEC, 0x0F03, - 0x0F0B, 0x1E84, 0x1EA2, 0x3EB0, 0x3EC4, 0x3F09, 0x7EF7, 0x7F1D, - 0x7FBC, 0x7FCD, 0x7F81, 0x7F50, 0x7F34, 0x3F65, 0x3EED, 0x3E67, - 0x1EDB, 0x1ED2, 0x1E99, 0x1E77, 0x0F21, 0x0F1C, 0x0EE8, 0x0EA8, - 0x0E6E, 0x0716, 0x033C, 0x0178, 0x033D, 0x0717, 0x0E6F, 0x0EAA, - 0x0EEB, 0x0F1E, 0x0F23, 0x1E75, 0x1E9A, 0x1ED4, 0x1EDC, 0x3E66, - 0x3EEE, 0x3F6B, 0x7F35, 0x7F55, 0x7F7A, 0x7FCA, 0x7FB6, 0x7FB8, - 0x7F37, 0x7F1F, 0x3F61, 0x3F37, 0x3F1A, 0x3EB5, 0x3E62, 0x3E5A, - 0x1F1E, 0x1F13, 0x1EF2, 0x1EE6, 0x1EBC, 0x1E91, 0x1E68, 0x070A, - 0x032C, 0x070B, 0x1E69, 0x1E90, 0x1EBD, 0x1EE4, 0x1EF4, 0x1F12, - 0x3E3E, 0x3E59, 0x3E61, 0x3EB6, 0x3F19, 0x3F3B, 0x3F64, 0x7F1C, - 0x7F3D, 0x7FB4, 0x7FB9, 0xFFC5, 0xFFB6, 0xFFAD, 0x7FA4, 0x7F2C, - 0x7F20, 0x7F09, 0x3EF5, 0x3E93, 0x3E82, 0x3E7E, 0x1F02, 0x1EE3, - 0x1ECA, 0x1EAD, 0x1E7C, 0x0EB8, 0x0E8A, 0x0332, 0x0E8B, 0x0EB9, - 0x1E7D, 0x1EAC, 0x1ECD, 0x1EE0, 0x1F03, 0x3E7D, 0x3E81, 0x3E91, - 0x3EF7, 0x7F0C, 0x7F1A, 0x7F2E, 0x7FA6, 0xFFA4, 0xFFB7, 0xFFC4, - 0xFFD4, 0xFFCC, 0x7FC5, 0x7F8A, 0x7F3C, 0x7EFF, 0x3F5E, 0x3F4E, - 0x3F2F, 0x3EFD, 0x3EEF, 0x3EEB, 0x3E92, 0x3E71, 0x3E42, 0x1F09, - 0x1E83, 0x0E82, 0x0348, 0x0E83, 0x1E80, 0x1F06, 0x3E44, 0x3E72, - 0x3E94, 0x3EEC, 0x3EF2, 0x3EFE, 0x3F34, 0x3F4C, 0x3F5F, 0x7EFE, - 0x7F3A, 0x7F86, 0x7FC4, 0xFFD2, 0xFFD5, 0xFFFA, 0xFFCD, 0xFFBA, - 0x7FAB, 0x7F92, 0x7F87, 0x7F63, 0x7F4C, 0x7F03, 0x7EF0, 0x3F42, - 0x3EA1, 0x3E76, 0x3E6A, 0x3E52, 0x1EEE, 0x1EAB, 0x0ED6, 0x06A9, - 0x0ED7, 0x1EAA, 0x1EED, 0x3E53, 0x3E70, 0x3E77, 0x3EA2, 0x3F41, - 0x7EEF, 0x7F00, 0x7F4D, 0x7F60, 0x7F88, 0x7F93, 0x7FAD, 0xFFB8, - 0xFFCB, 0xFFFB, 0xFFFC, 0xFFE1, 0xFFBF, 0x7FBA, 0x7F73, 0x7F6C, - 0x7F57, 0x7EFC, 0x7EDD, 0x3F6A, 0x3F2A, 0x3F25, 0x3EDD, 0x3ED3, - 0x3EC2, 0x3EA7, 0x3E86, 0x0F11, 0x06B2, 0x0F0E, 0x3E8A, 0x3EA5, - 0x3EC0, 0x3ED1, 0x3EDE, 0x3F2C, 0x3F29, 0x3F69, 0x7EDB, 0x7EFD, - 0x7F59, 0x7F6D, 0x7F74, 0x7FC0, 0xFFC3, 0xFFE3, 0xFFFD, 0xFFF0, - 0xFFE9, 0xFFE7, 0xFFC9, 0xFFBD, 0xFFAE, 0x7F71, 0x7F5F, 0x7F42, - 0x7F41, 0x7F30, 0x7F17, 0x7EE4, 0x3ED7, 0x3EC7, 0x3ECB, 0x1EB1, - 0x0EDC, 0x06D2, 0x0EDD, 0x1EB2, 0x3EC6, 0x3EC8, 0x3ED4, 0x7EE3, - 0x7F18, 0x7F2B, 0x7F3F, 0x7F43, 0x7F64, 0x7F6E, 0xFFAB, 0xFFC2, - 0xFFD0, 0xFFE6, 0xFFEF, 0xFFF3, 0xFFF7, 0xFFEB, 0xFFDE, 0xFFDA, - 0xFFB3, 0xFFAC, 0xFFA3, 0x7FC9, 0x7F8F, 0x7F7C, 0x7F79, 0x7F0F, - 0x7F10, 0x3F55, 0x3F45, 0x1F1A, 0x1E95, 0x0F2B, 0x06F1, 0x0F29, - 0x1E97, 0x1F19, 0x3F47, 0x3F57, 0x7F14, 0x7F12, 0x7F78, 0x7F7E, - 0x7F91, 0x7FC7, 0xFFA1, 0xFFA5, 0xFFB2, 0xFFDB, 0xFFDF, 0xFFED, - 0xFFF4, 0x004C, -}; - -static const uint16_t clv_mvy_3_syms[] = { - 0xEEEE, 0xEFEE, 0xF0EE, 0xF1EE, 0xF2EE, 0xF3EE, 0xF4EE, 0xF5EE, - 0xF6EE, 0xF7EE, 0xF8EE, 0xF9EE, 0xFAEE, 0xFBEE, 0xFCEE, 0xFDEE, - 0xFEEE, 0xFFEE, 0x00EE, 0x01EE, 0x02EE, 0x03EE, 0x04EE, 0x05EE, - 0x06EE, 0x07EE, 0x08EE, 0x09EE, 0x0AEE, 0x0BEE, 0x0CEE, 0x0DEE, - 0x0EEE, 0x0FEE, 0x10EE, 0x11EE, 0x12EE, 0xEEEF, 0xEFEF, 0xF0EF, - 0xF1EF, 0xF2EF, 0xF3EF, 0xF4EF, 0xF5EF, 0xF6EF, 0xF7EF, 0xF8EF, - 0xF9EF, 0xFAEF, 0xFBEF, 0xFCEF, 0xFDEF, 0xFEEF, 0xFFEF, 0x00EF, - 0x01EF, 0x02EF, 0x03EF, 0x04EF, 0x05EF, 0x06EF, 0x07EF, 0x08EF, - 0x09EF, 0x0AEF, 0x0BEF, 0x0CEF, 0x0DEF, 0x0EEF, 0x0FEF, 0x10EF, - 0x11EF, 0x12EF, 0xEEF0, 0xEFF0, 0xF0F0, 0xF1F0, 0xF2F0, 0xF3F0, - 0xF4F0, 0xF5F0, 0xF6F0, 0xF7F0, 0xF8F0, 0xF9F0, 0xFAF0, 0xFBF0, - 0xFCF0, 0xFDF0, 0xFEF0, 0xFFF0, 0x00F0, 0x01F0, 0x02F0, 0x03F0, - 0x04F0, 0x05F0, 0x06F0, 0x07F0, 0x08F0, 0x09F0, 0x0AF0, 0x0BF0, - 0x0CF0, 0x0DF0, 0x0EF0, 0x0FF0, 0x10F0, 0x11F0, 0x12F0, 0xEEF1, - 0xEFF1, 0xF0F1, 0xF1F1, 0xF2F1, 0xF3F1, 0xF4F1, 0xF5F1, 0xF6F1, - 0xF7F1, 0xF8F1, 0xF9F1, 0xFAF1, 0xFBF1, 0xFCF1, 0xFDF1, 0xFEF1, - 0xFFF1, 0x00F1, 0x01F1, 0x02F1, 0x03F1, 0x04F1, 0x05F1, 0x06F1, - 0x07F1, 0x08F1, 0x09F1, 0x0AF1, 0x0BF1, 0x0CF1, 0x0DF1, 0x0EF1, - 0x0FF1, 0x10F1, 0x11F1, 0x12F1, 0xEEF2, 0xEFF2, 0xF0F2, 0xF1F2, - 0xF2F2, 0xF3F2, 0xF4F2, 0xF5F2, 0xF6F2, 0xF7F2, 0xF8F2, 0xF9F2, - 0xFAF2, 0xFBF2, 0xFCF2, 0xFDF2, 0xFEF2, 0xFFF2, 0x00F2, 0x01F2, - 0x02F2, 0x03F2, 0x04F2, 0x05F2, 0x06F2, 0x07F2, 0x08F2, 0x09F2, - 0x0AF2, 0x0BF2, 0x0CF2, 0x0DF2, 0x0EF2, 0x0FF2, 0x10F2, 0x11F2, - 0x12F2, 0xEEF3, 0xEFF3, 0xF0F3, 0xF1F3, 0xF2F3, 0xF3F3, 0xF4F3, - 0xF5F3, 0xF6F3, 0xF7F3, 0xF8F3, 0xF9F3, 0xFAF3, 0xFBF3, 0xFCF3, - 0xFDF3, 0xFEF3, 0xFFF3, 0x00F3, 0x01F3, 0x02F3, 0x03F3, 0x04F3, - 0x05F3, 0x06F3, 0x07F3, 0x08F3, 0x09F3, 0x0AF3, 0x0BF3, 0x0CF3, - 0x0DF3, 0x0EF3, 0x0FF3, 0x10F3, 0x11F3, 0x12F3, 0xEEF4, 0xEFF4, - 0xF0F4, 0xF1F4, 0xF2F4, 0xF3F4, 0xF4F4, 0xF5F4, 0xF6F4, 0xF7F4, - 0xF8F4, 0xF9F4, 0xFAF4, 0xFBF4, 0xFCF4, 0xFDF4, 0xFEF4, 0xFFF4, - 0x00F4, 0x01F4, 0x02F4, 0x03F4, 0x04F4, 0x05F4, 0x06F4, 0x07F4, - 0x08F4, 0x09F4, 0x0AF4, 0x0BF4, 0x0CF4, 0x0DF4, 0x0EF4, 0x0FF4, - 0x10F4, 0x11F4, 0x12F4, 0xEEF5, 0xEFF5, 0xF0F5, 0xF1F5, 0xF2F5, - 0xF3F5, 0xF4F5, 0xF5F5, 0xF6F5, 0xF7F5, 0xF8F5, 0xF9F5, 0xFAF5, - 0xFBF5, 0xFCF5, 0xFDF5, 0xFEF5, 0xFFF5, 0x00F5, 0x01F5, 0x02F5, - 0x03F5, 0x04F5, 0x05F5, 0x06F5, 0x07F5, 0x08F5, 0x09F5, 0x0AF5, - 0x0BF5, 0x0CF5, 0x0DF5, 0x0EF5, 0x0FF5, 0x10F5, 0x11F5, 0x12F5, - 0xEEF6, 0xEFF6, 0xF0F6, 0xF1F6, 0xF2F6, 0xF3F6, 0xF4F6, 0xF5F6, - 0xF6F6, 0xF7F6, 0xF8F6, 0xF9F6, 0xFAF6, 0xFBF6, 0xFCF6, 0xFDF6, - 0xFEF6, 0xFFF6, 0x00F6, 0x01F6, 0x02F6, 0x03F6, 0x04F6, 0x05F6, - 0x06F6, 0x07F6, 0x08F6, 0x09F6, 0x0AF6, 0x0BF6, 0x0CF6, 0x0DF6, - 0x0EF6, 0x0FF6, 0x10F6, 0x11F6, 0x12F6, 0xEEF7, 0xEFF7, 0xF0F7, - 0xF1F7, 0xF2F7, 0xF3F7, 0xF4F7, 0xF5F7, 0xF6F7, 0xF7F7, 0xF8F7, - 0xF9F7, 0xFAF7, 0xFBF7, 0xFCF7, 0xFDF7, 0xFEF7, 0xFFF7, 0x00F7, - 0x01F7, 0x02F7, 0x03F7, 0x04F7, 0x05F7, 0x06F7, 0x07F7, 0x08F7, - 0x09F7, 0x0AF7, 0x0BF7, 0x0CF7, 0x0DF7, 0x0EF7, 0x0FF7, 0x10F7, - 0x11F7, 0x12F7, 0xEEF8, 0xEFF8, 0xF0F8, 0xF1F8, 0xF2F8, 0xF3F8, - 0xF4F8, 0xF5F8, 0xF6F8, 0xF7F8, 0xF8F8, 0xF9F8, 0xFAF8, 0xFBF8, - 0xFCF8, 0xFDF8, 0xFEF8, 0xFFF8, 0x00F8, 0x01F8, 0x02F8, 0x03F8, - 0x04F8, 0x05F8, 0x06F8, 0x07F8, 0x08F8, 0x09F8, 0x0AF8, 0x0BF8, - 0x0CF8, 0x0DF8, 0x0EF8, 0x0FF8, 0x10F8, 0x11F8, 0x12F8, 0xEEF9, - 0xEFF9, 0xF0F9, 0xF1F9, 0xF2F9, 0xF3F9, 0xF4F9, 0xF5F9, 0xF6F9, - 0xF7F9, 0xF8F9, 0xF9F9, 0xFAF9, 0xFBF9, 0xFCF9, 0xFDF9, 0xFEF9, - 0xFFF9, 0x00F9, 0x01F9, 0x02F9, 0x03F9, 0x04F9, 0x05F9, 0x06F9, - 0x07F9, 0x08F9, 0x09F9, 0x0AF9, 0x0BF9, 0x0CF9, 0x0DF9, 0x0EF9, - 0x0FF9, 0x10F9, 0x11F9, 0x12F9, 0xEEFA, 0xEFFA, 0xF0FA, 0xF1FA, - 0xF2FA, 0xF3FA, 0xF4FA, 0xF5FA, 0xF6FA, 0xF7FA, 0xF8FA, 0xF9FA, - 0xFAFA, 0xFBFA, 0xFCFA, 0xFDFA, 0xFEFA, 0xFFFA, 0x00FA, 0x01FA, - 0x02FA, 0x03FA, 0x04FA, 0x05FA, 0x06FA, 0x07FA, 0x08FA, 0x09FA, - 0x0AFA, 0x0BFA, 0x0CFA, 0x0DFA, 0x0EFA, 0x0FFA, 0x10FA, 0x11FA, - 0x12FA, 0xEEFB, 0xEFFB, 0xF0FB, 0xF1FB, 0xF2FB, 0xF3FB, 0xF4FB, - 0xF5FB, 0xF6FB, 0xF7FB, 0xF8FB, 0xF9FB, 0xFAFB, 0xFBFB, 0xFCFB, - 0xFDFB, 0xFEFB, 0xFFFB, 0x00FB, 0x01FB, 0x02FB, 0x03FB, 0x04FB, - 0x05FB, 0x06FB, 0x07FB, 0x08FB, 0x09FB, 0x0AFB, 0x0BFB, 0x0CFB, - 0x0DFB, 0x0EFB, 0x0FFB, 0x10FB, 0x11FB, 0x12FB, 0xEEFC, 0xEFFC, - 0xF0FC, 0xF1FC, 0xF2FC, 0xF3FC, 0xF4FC, 0xF5FC, 0xF6FC, 0xF7FC, - 0xF8FC, 0xF9FC, 0xFAFC, 0xFBFC, 0xFCFC, 0xFDFC, 0xFEFC, 0xFFFC, - 0x00FC, 0x01FC, 0x02FC, 0x03FC, 0x04FC, 0x05FC, 0x06FC, 0x07FC, - 0x08FC, 0x09FC, 0x0AFC, 0x0BFC, 0x0CFC, 0x0DFC, 0x0EFC, 0x0FFC, - 0x10FC, 0x11FC, 0x12FC, 0xEEFD, 0xEFFD, 0xF0FD, 0xF1FD, 0xF2FD, - 0xF3FD, 0xF4FD, 0xF5FD, 0xF6FD, 0xF7FD, 0xF8FD, 0xF9FD, 0xFAFD, - 0xFBFD, 0xFCFD, 0xFDFD, 0xFEFD, 0xFFFD, 0x00FD, 0x01FD, 0x02FD, - 0x03FD, 0x04FD, 0x05FD, 0x06FD, 0x07FD, 0x08FD, 0x09FD, 0x0AFD, - 0x0BFD, 0x0CFD, 0x0DFD, 0x0EFD, 0x0FFD, 0x10FD, 0x11FD, 0x12FD, - 0xEEFE, 0xEFFE, 0xF0FE, 0xF1FE, 0xF2FE, 0xF3FE, 0xF4FE, 0xF5FE, - 0xF6FE, 0xF7FE, 0xF8FE, 0xF9FE, 0xFAFE, 0xFBFE, 0xFCFE, 0xFDFE, - 0xFEFE, 0xFFFE, 0x00FE, 0x01FE, 0x02FE, 0x03FE, 0x04FE, 0x05FE, - 0x06FE, 0x07FE, 0x08FE, 0x09FE, 0x0AFE, 0x0BFE, 0x0CFE, 0x0DFE, - 0x0EFE, 0x0FFE, 0x10FE, 0x11FE, 0x12FE, 0xEEFF, 0xEFFF, 0xF0FF, - 0xF1FF, 0xF2FF, 0xF3FF, 0xF4FF, 0xF5FF, 0xF6FF, 0xF7FF, 0xF8FF, - 0xF9FF, 0xFAFF, 0xFBFF, 0xFCFF, 0xFDFF, 0xFEFF, 0xFFFF, 0x00FF, - 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, 0x07FF, 0x08FF, - 0x09FF, 0x0AFF, 0x0BFF, 0x0CFF, 0x0DFF, 0x0EFF, 0x0FFF, 0x10FF, - 0x11FF, 0x12FF, 0xEE00, 0xEF00, 0xF000, 0xF100, 0xF200, 0xF300, - 0xF400, 0xF500, 0xF600, 0xF700, 0xF800, 0xF900, 0xFA00, 0xFB00, - 0xFC00, 0xFD00, 0xFE00, 0xFF00, 0x0000, 0x0100, 0x0200, 0x0300, - 0x0400, 0x0500, 0x0600, 0x0700, 0x0800, 0x0900, 0x0A00, 0x0B00, - 0x0C00, 0x0D00, 0x0E00, 0x0F00, 0x1000, 0x1100, 0x1200, 0xEE01, - 0xEF01, 0xF001, 0xF101, 0xF201, 0xF301, 0xF401, 0xF501, 0xF601, - 0xF701, 0xF801, 0xF901, 0xFA01, 0xFB01, 0xFC01, 0xFD01, 0xFE01, - 0xFF01, 0x0001, 0x0101, 0x0201, 0x0301, 0x0401, 0x0501, 0x0601, - 0x0701, 0x0801, 0x0901, 0x0A01, 0x0B01, 0x0C01, 0x0D01, 0x0E01, - 0x0F01, 0x1001, 0x1101, 0x1201, 0xEE02, 0xEF02, 0xF002, 0xF102, - 0xF202, 0xF302, 0xF402, 0xF502, 0xF602, 0xF702, 0xF802, 0xF902, - 0xFA02, 0xFB02, 0xFC02, 0xFD02, 0xFE02, 0xFF02, 0x0002, 0x0102, - 0x0202, 0x0302, 0x0402, 0x0502, 0x0602, 0x0702, 0x0802, 0x0902, - 0x0A02, 0x0B02, 0x0C02, 0x0D02, 0x0E02, 0x0F02, 0x1002, 0x1102, - 0x1202, 0xEE03, 0xEF03, 0xF003, 0xF103, 0xF203, 0xF303, 0xF403, - 0xF503, 0xF603, 0xF703, 0xF803, 0xF903, 0xFA03, 0xFB03, 0xFC03, - 0xFD03, 0xFE03, 0xFF03, 0x0003, 0x0103, 0x0203, 0x0303, 0x0403, - 0x0503, 0x0603, 0x0703, 0x0803, 0x0903, 0x0A03, 0x0B03, 0x0C03, - 0x0D03, 0x0E03, 0x0F03, 0x1003, 0x1103, 0x1203, 0xEE04, 0xEF04, - 0xF004, 0xF104, 0xF204, 0xF304, 0xF404, 0xF504, 0xF604, 0xF704, - 0xF804, 0xF904, 0xFA04, 0xFB04, 0xFC04, 0xFD04, 0xFE04, 0xFF04, - 0x0004, 0x0104, 0x0204, 0x0304, 0x0404, 0x0504, 0x0604, 0x0704, - 0x0804, 0x0904, 0x0A04, 0x0B04, 0x0C04, 0x0D04, 0x0E04, 0x0F04, - 0x1004, 0x1104, 0x1204, 0xEE05, 0xEF05, 0xF005, 0xF105, 0xF205, - 0xF305, 0xF405, 0xF505, 0xF605, 0xF705, 0xF805, 0xF905, 0xFA05, - 0xFB05, 0xFC05, 0xFD05, 0xFE05, 0xFF05, 0x0005, 0x0105, 0x0205, - 0x0305, 0x0405, 0x0505, 0x0605, 0x0705, 0x0805, 0x0905, 0x0A05, - 0x0B05, 0x0C05, 0x0D05, 0x0E05, 0x0F05, 0x1005, 0x1105, 0x1205, - 0xEE06, 0xEF06, 0xF006, 0xF106, 0xF206, 0xF306, 0xF406, 0xF506, - 0xF606, 0xF706, 0xF806, 0xF906, 0xFA06, 0xFB06, 0xFC06, 0xFD06, - 0xFE06, 0xFF06, 0x0006, 0x0106, 0x0206, 0x0306, 0x0406, 0x0506, - 0x0606, 0x0706, 0x0806, 0x0906, 0x0A06, 0x0B06, 0x0C06, 0x0D06, - 0x0E06, 0x0F06, 0x1006, 0x1106, 0x1206, 0xEE07, 0xEF07, 0xF007, - 0xF107, 0xF207, 0xF307, 0xF407, 0xF507, 0xF607, 0xF707, 0xF807, - 0xF907, 0xFA07, 0xFB07, 0xFC07, 0xFD07, 0xFE07, 0xFF07, 0x0007, - 0x0107, 0x0207, 0x0307, 0x0407, 0x0507, 0x0607, 0x0707, 0x0807, - 0x0907, 0x0A07, 0x0B07, 0x0C07, 0x0D07, 0x0E07, 0x0F07, 0x1007, - 0x1107, 0x1207, 0xEE08, 0xEF08, 0xF008, 0xF108, 0xF208, 0xF308, - 0xF408, 0xF508, 0xF608, 0xF708, 0xF808, 0xF908, 0xFA08, 0xFB08, - 0xFC08, 0xFD08, 0xFE08, 0xFF08, 0x0008, 0x0108, 0x0208, 0x0308, - 0x0408, 0x0508, 0x0608, 0x0708, 0x0808, 0x0908, 0x0A08, 0x0B08, - 0x0C08, 0x0D08, 0x0E08, 0x0F08, 0x1008, 0x1108, 0x1208, 0xEE09, - 0xEF09, 0xF009, 0xF109, 0xF209, 0xF309, 0xF409, 0xF509, 0xF609, - 0xF709, 0xF809, 0xF909, 0xFA09, 0xFB09, 0xFC09, 0xFD09, 0xFE09, - 0xFF09, 0x0009, 0x0109, 0x0209, 0x0309, 0x0409, 0x0509, 0x0609, - 0x0709, 0x0809, 0x0909, 0x0A09, 0x0B09, 0x0C09, 0x0D09, 0x0E09, - 0x0F09, 0x1009, 0x1109, 0x1209, 0xEE0A, 0xEF0A, 0xF00A, 0xF10A, - 0xF20A, 0xF30A, 0xF40A, 0xF50A, 0xF60A, 0xF70A, 0xF80A, 0xF90A, - 0xFA0A, 0xFB0A, 0xFC0A, 0xFD0A, 0xFE0A, 0xFF0A, 0x000A, 0x010A, - 0x020A, 0x030A, 0x040A, 0x050A, 0x060A, 0x070A, 0x080A, 0x090A, - 0x0A0A, 0x0B0A, 0x0C0A, 0x0D0A, 0x0E0A, 0x0F0A, 0x100A, 0x110A, - 0x120A, 0xEE0B, 0xEF0B, 0xF00B, 0xF10B, 0xF20B, 0xF30B, 0xF40B, - 0xF50B, 0xF60B, 0xF70B, 0xF80B, 0xF90B, 0xFA0B, 0xFB0B, 0xFC0B, - 0xFD0B, 0xFE0B, 0xFF0B, 0x000B, 0x010B, 0x020B, 0x030B, 0x040B, - 0x050B, 0x060B, 0x070B, 0x080B, 0x090B, 0x0A0B, 0x0B0B, 0x0C0B, - 0x0D0B, 0x0E0B, 0x0F0B, 0x100B, 0x110B, 0x120B, 0xEE0C, 0xEF0C, - 0xF00C, 0xF10C, 0xF20C, 0xF30C, 0xF40C, 0xF50C, 0xF60C, 0xF70C, - 0xF80C, 0xF90C, 0xFA0C, 0xFB0C, 0xFC0C, 0xFD0C, 0xFE0C, 0xFF0C, - 0x000C, 0x010C, 0x020C, 0x030C, 0x040C, 0x050C, 0x060C, 0x070C, - 0x080C, 0x090C, 0x0A0C, 0x0B0C, 0x0C0C, 0x0D0C, 0x0E0C, 0x0F0C, - 0x100C, 0x110C, 0x120C, 0xEE0D, 0xEF0D, 0xF00D, 0xF10D, 0xF20D, - 0xF30D, 0xF40D, 0xF50D, 0xF60D, 0xF70D, 0xF80D, 0xF90D, 0xFA0D, - 0xFB0D, 0xFC0D, 0xFD0D, 0xFE0D, 0xFF0D, 0x000D, 0x010D, 0x020D, - 0x030D, 0x040D, 0x050D, 0x060D, 0x070D, 0x080D, 0x090D, 0x0A0D, - 0x0B0D, 0x0C0D, 0x0D0D, 0x0E0D, 0x0F0D, 0x100D, 0x110D, 0x120D, - 0xEE0E, 0xEF0E, 0xF00E, 0xF10E, 0xF20E, 0xF30E, 0xF40E, 0xF50E, - 0xF60E, 0xF70E, 0xF80E, 0xF90E, 0xFA0E, 0xFB0E, 0xFC0E, 0xFD0E, - 0xFE0E, 0xFF0E, 0x000E, 0x010E, 0x020E, 0x030E, 0x040E, 0x050E, - 0x060E, 0x070E, 0x080E, 0x090E, 0x0A0E, 0x0B0E, 0x0C0E, 0x0D0E, - 0x0E0E, 0x0F0E, 0x100E, 0x110E, 0x120E, 0xEE0F, 0xEF0F, 0xF00F, - 0xF10F, 0xF20F, 0xF30F, 0xF40F, 0xF50F, 0xF60F, 0xF70F, 0xF80F, - 0xF90F, 0xFA0F, 0xFB0F, 0xFC0F, 0xFD0F, 0xFE0F, 0xFF0F, 0x000F, - 0x010F, 0x020F, 0x030F, 0x040F, 0x050F, 0x060F, 0x070F, 0x080F, - 0x090F, 0x0A0F, 0x0B0F, 0x0C0F, 0x0D0F, 0x0E0F, 0x0F0F, 0x100F, - 0x110F, 0x120F, 0xEE10, 0xEF10, 0xF010, 0xF110, 0xF210, 0xF310, - 0xF410, 0xF510, 0xF610, 0xF710, 0xF810, 0xF910, 0xFA10, 0xFB10, - 0xFC10, 0xFD10, 0xFE10, 0xFF10, 0x0010, 0x0110, 0x0210, 0x0310, - 0x0410, 0x0510, 0x0610, 0x0710, 0x0810, 0x0910, 0x0A10, 0x0B10, - 0x0C10, 0x0D10, 0x0E10, 0x0F10, 0x1010, 0x1110, 0x1210, 0xEE11, - 0xEF11, 0xF011, 0xF111, 0xF211, 0xF311, 0xF411, 0xF511, 0xF611, - 0xF711, 0xF811, 0xF911, 0xFA11, 0xFB11, 0xFC11, 0xFD11, 0xFE11, - 0xFF11, 0x0011, 0x0111, 0x0211, 0x0311, 0x0411, 0x0511, 0x0611, - 0x0711, 0x0811, 0x0911, 0x0A11, 0x0B11, 0x0C11, 0x0D11, 0x0E11, - 0x0F11, 0x1011, 0x1111, 0x1211, 0xEE12, 0xEF12, 0xF012, 0xF112, - 0xF212, 0xF312, 0xF412, 0xF512, 0xF612, 0xF712, 0xF812, 0xF912, - 0xFA12, 0xFB12, 0xFC12, 0xFD12, 0xFE12, 0xFF12, 0x0012, 0x0112, - 0x0212, 0x0312, 0x0412, 0x0512, 0x0612, 0x0712, 0x0812, 0x0912, - 0x0A12, 0x0B12, 0x0C12, 0x0D12, 0x0E12, 0x0F12, 0x1012, 0x1112, - 0x1212, 0x1313, -}; - -static const uint8_t clv_mvu_1_bits[] = { - 16, 14, 14, 14, 13, 12, 12, 10, 12, 12, 13, 14, 14, 14, 16, 15, - 13, 13, 12, 12, 11, 11, 7, 11, 11, 12, 12, 13, 13, 15, 16, 16, - 16, 13, 12, 10, 10, 6, 10, 10, 12, 13, 16, 16, 16, 14, 14, 11, - 11, 11, 11, 9, 7, 9, 11, 11, 11, 11, 14, 14, 15, 13, 13, 12, - 9, 8, 8, 4, 8, 8, 9, 12, 13, 13, 15, 14, 14, 11, 11, 10, - 9, 8, 4, 8, 9, 10, 11, 12, 14, 14, 12, 12, 11, 10, 10, 8, - 6, 3, 6, 8, 10, 10, 11, 12, 12, 11, 10, 9, 6, 6, 6, 5, - 4, 5, 6, 6, 6, 9, 10, 11, 12, 12, 11, 10, 10, 8, 6, 3, - 6, 7, 10, 10, 11, 12, 12, 14, 14, 11, 11, 10, 9, 8, 4, 8, - 9, 10, 11, 11, 14, 14, 15, 13, 13, 12, 9, 8, 8, 4, 8, 8, - 9, 12, 13, 13, 15, 14, 14, 11, 11, 11, 11, 9, 7, 9, 11, 11, - 11, 11, 14, 14, 16, 16, 16, 13, 12, 10, 10, 6, 10, 10, 12, 13, - 16, 16, 16, 15, 13, 13, 12, 12, 11, 11, 7, 11, 11, 12, 12, 13, - 13, 15, 16, 14, 14, 14, 13, 12, 12, 10, 12, 12, 13, 14, 14, 14, - 16, 7, -}; - -static const uint16_t clv_mvu_1_codes[] = { - 0xFFFC, 0x3FED, 0x3FE5, 0x3FE3, 0x1FD9, 0x0FD9, 0x0FD6, 0x03CE, - 0x0FD3, 0x0FD8, 0x1FD6, 0x3FE0, 0x3FE8, 0x3FEC, 0xFFFE, 0x7FF3, - 0x1FE7, 0x1FDA, 0x0FCF, 0x0FCC, 0x07DD, 0x07CC, 0x006B, 0x07CD, - 0x07DE, 0x0FCE, 0x0FD2, 0x1FDD, 0x1FEC, 0x7FF0, 0xFFF6, 0xFFFA, - 0xFFF2, 0x1FDE, 0x0FDB, 0x03D8, 0x03CA, 0x002E, 0x03CB, 0x03D9, - 0x0FDC, 0x1FDF, 0xFFF3, 0xFFF9, 0xFFF5, 0x3FF3, 0x3FDD, 0x07DA, - 0x07D2, 0x07CA, 0x07C2, 0x01DE, 0x0069, 0x01DF, 0x07C3, 0x07CB, - 0x07D3, 0x07DB, 0x3FDF, 0x3FF6, 0x7FF7, 0x1FED, 0x1FE5, 0x0FDF, - 0x01D8, 0x00E3, 0x00DF, 0x0007, 0x00E0, 0x00E4, 0x01D9, 0x0FE0, - 0x1FE3, 0x1FE9, 0x7FF4, 0x3FF5, 0x3FE7, 0x07E4, 0x07C6, 0x03D2, - 0x01E2, 0x00E9, 0x0006, 0x00EA, 0x01E3, 0x03D3, 0x07C7, 0x0FCA, - 0x3FE9, 0x3FF0, 0x0FE8, 0x0FE5, 0x07D5, 0x03DD, 0x03D5, 0x00DC, - 0x002B, 0x0001, 0x002C, 0x00DD, 0x03D6, 0x03DE, 0x07D6, 0x0FE4, - 0x0FE9, 0x07E0, 0x03C8, 0x01D6, 0x0032, 0x0030, 0x0028, 0x0012, - 0x0004, 0x0013, 0x0029, 0x0031, 0x0033, 0x01D7, 0x03C9, 0x07E1, - 0x0FEA, 0x0FE6, 0x07D7, 0x03DF, 0x03D7, 0x00DE, 0x002D, 0x0000, - 0x002A, 0x006D, 0x03D4, 0x03DC, 0x07D4, 0x0FE3, 0x0FE7, 0x3FF1, - 0x3FE4, 0x07E2, 0x07C4, 0x03D0, 0x01E0, 0x00E7, 0x0005, 0x00E8, - 0x01E1, 0x03D1, 0x07C5, 0x07E3, 0x3FEA, 0x3FF7, 0x7FF6, 0x1FE6, - 0x1FE4, 0x0FE1, 0x01DA, 0x00E5, 0x00E1, 0x0008, 0x00E2, 0x00E6, - 0x01DB, 0x0FE2, 0x1FE2, 0x1FEB, 0x7FF5, 0x3FF4, 0x3FDC, 0x07D9, - 0x07D0, 0x07C8, 0x07C0, 0x01DC, 0x0068, 0x01DD, 0x07C1, 0x07C9, - 0x07D1, 0x07D8, 0x3FDE, 0x3FF2, 0xFFFB, 0xFFF4, 0xFFF0, 0x1FE1, - 0x0FDD, 0x03DA, 0x03CC, 0x002F, 0x03CD, 0x03DB, 0x0FDE, 0x1FE0, - 0xFFF1, 0xFFF7, 0xFFF8, 0x7FF2, 0x1FEA, 0x1FDC, 0x0FD1, 0x0FCD, - 0x07DC, 0x07CF, 0x006C, 0x07CE, 0x07DF, 0x0FCB, 0x0FD0, 0x1FDB, - 0x1FE8, 0x7FF1, 0xFFFD, 0x3FEE, 0x3FEB, 0x3FE1, 0x1FD7, 0x0FD7, - 0x0FD5, 0x03CF, 0x0FD4, 0x0FDA, 0x1FD8, 0x3FE2, 0x3FE6, 0x3FEF, - 0xFFFF, 0x006A, -}; - -static const uint16_t clv_mvu_1_syms[] = { - 0xF9F9, 0xFAF9, 0xFBF9, 0xFCF9, 0xFDF9, 0xFEF9, 0xFFF9, 0x00F9, - 0x01F9, 0x02F9, 0x03F9, 0x04F9, 0x05F9, 0x06F9, 0x07F9, 0xF9FA, - 0xFAFA, 0xFBFA, 0xFCFA, 0xFDFA, 0xFEFA, 0xFFFA, 0x00FA, 0x01FA, - 0x02FA, 0x03FA, 0x04FA, 0x05FA, 0x06FA, 0x07FA, 0xF9FB, 0xFAFB, - 0xFBFB, 0xFCFB, 0xFDFB, 0xFEFB, 0xFFFB, 0x00FB, 0x01FB, 0x02FB, - 0x03FB, 0x04FB, 0x05FB, 0x06FB, 0x07FB, 0xF9FC, 0xFAFC, 0xFBFC, - 0xFCFC, 0xFDFC, 0xFEFC, 0xFFFC, 0x00FC, 0x01FC, 0x02FC, 0x03FC, - 0x04FC, 0x05FC, 0x06FC, 0x07FC, 0xF9FD, 0xFAFD, 0xFBFD, 0xFCFD, - 0xFDFD, 0xFEFD, 0xFFFD, 0x00FD, 0x01FD, 0x02FD, 0x03FD, 0x04FD, - 0x05FD, 0x06FD, 0x07FD, 0xF9FE, 0xFAFE, 0xFBFE, 0xFCFE, 0xFDFE, - 0xFEFE, 0xFFFE, 0x00FE, 0x01FE, 0x02FE, 0x03FE, 0x04FE, 0x05FE, - 0x06FE, 0x07FE, 0xF9FF, 0xFAFF, 0xFBFF, 0xFCFF, 0xFDFF, 0xFEFF, - 0xFFFF, 0x00FF, 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, - 0x07FF, 0xF900, 0xFA00, 0xFB00, 0xFC00, 0xFD00, 0xFE00, 0xFF00, - 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, - 0xF901, 0xFA01, 0xFB01, 0xFC01, 0xFD01, 0xFE01, 0xFF01, 0x0001, - 0x0101, 0x0201, 0x0301, 0x0401, 0x0501, 0x0601, 0x0701, 0xF902, - 0xFA02, 0xFB02, 0xFC02, 0xFD02, 0xFE02, 0xFF02, 0x0002, 0x0102, - 0x0202, 0x0302, 0x0402, 0x0502, 0x0602, 0x0702, 0xF903, 0xFA03, - 0xFB03, 0xFC03, 0xFD03, 0xFE03, 0xFF03, 0x0003, 0x0103, 0x0203, - 0x0303, 0x0403, 0x0503, 0x0603, 0x0703, 0xF904, 0xFA04, 0xFB04, - 0xFC04, 0xFD04, 0xFE04, 0xFF04, 0x0004, 0x0104, 0x0204, 0x0304, - 0x0404, 0x0504, 0x0604, 0x0704, 0xF905, 0xFA05, 0xFB05, 0xFC05, - 0xFD05, 0xFE05, 0xFF05, 0x0005, 0x0105, 0x0205, 0x0305, 0x0405, - 0x0505, 0x0605, 0x0705, 0xF906, 0xFA06, 0xFB06, 0xFC06, 0xFD06, - 0xFE06, 0xFF06, 0x0006, 0x0106, 0x0206, 0x0306, 0x0406, 0x0506, - 0x0606, 0x0706, 0xF907, 0xFA07, 0xFB07, 0xFC07, 0xFD07, 0xFE07, - 0xFF07, 0x0007, 0x0107, 0x0207, 0x0307, 0x0407, 0x0507, 0x0607, - 0x0707, 0x0808, -}; - -static const uint8_t clv_mvu_2_bits[] = { - 16, 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 15, 15, - 15, 15, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, - 13, 14, 14, 14, 14, 14, 15, 15, 15, 16, 16, 15, 15, 14, 14, 14, - 14, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 16, 16, - 15, 15, 14, 13, 13, 13, 13, 13, 12, 12, 12, 13, 13, 13, 13, 13, - 14, 15, 15, 16, 14, 14, 14, 14, 13, 12, 12, 12, 12, 11, 10, 11, - 12, 12, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14, 13, 12, 12, 12, - 12, 11, 10, 9, 10, 11, 12, 12, 12, 12, 13, 14, 14, 14, 15, 14, - 13, 13, 12, 12, 12, 12, 11, 10, 8, 10, 11, 12, 12, 12, 12, 13, - 13, 14, 15, 14, 14, 14, 13, 12, 12, 11, 11, 10, 9, 7, 9, 10, - 11, 11, 12, 12, 13, 14, 14, 14, 14, 14, 13, 12, 12, 11, 11, 10, - 9, 8, 7, 8, 9, 10, 11, 11, 12, 12, 13, 14, 14, 14, 13, 13, - 12, 11, 9, 9, 8, 7, 6, 5, 6, 7, 8, 9, 9, 11, 12, 13, - 13, 14, 14, 13, 13, 13, 11, 11, 10, 8, 7, 4, 1, 4, 7, 8, - 10, 11, 11, 13, 13, 13, 14, 14, 13, 13, 12, 11, 9, 9, 8, 7, - 6, 5, 6, 7, 8, 9, 9, 11, 12, 13, 13, 14, 14, 14, 13, 12, - 11, 11, 11, 9, 9, 8, 7, 8, 9, 10, 11, 11, 12, 12, 13, 14, - 14, 14, 14, 14, 13, 12, 12, 11, 11, 10, 9, 7, 9, 10, 11, 11, - 12, 12, 13, 14, 14, 14, 15, 14, 13, 13, 12, 12, 12, 12, 11, 10, - 9, 10, 11, 12, 12, 12, 12, 13, 13, 14, 15, 14, 14, 14, 13, 12, - 12, 12, 12, 11, 10, 8, 10, 11, 12, 12, 12, 12, 13, 14, 14, 14, - 14, 14, 14, 14, 13, 12, 12, 12, 12, 11, 10, 11, 12, 12, 12, 12, - 13, 14, 14, 14, 14, 16, 15, 15, 14, 13, 13, 13, 13, 13, 12, 12, - 12, 13, 13, 13, 13, 13, 14, 15, 15, 16, 16, 15, 15, 14, 14, 14, - 14, 14, 14, 13, 12, 13, 14, 14, 14, 14, 14, 14, 15, 15, 16, 16, - 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, - 15, 15, 15, 16, 16, 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 14, - 14, 14, 15, 15, 15, 15, 16, 16, 16, 6, -}; - -static const uint16_t clv_mvu_2_codes[] = { - 0xFFF2, 0xFFEF, 0xFFEA, 0x7FEC, 0x7FD5, 0x7FC5, 0x7FCF, 0x3FD3, - 0x3FC9, 0x3FB4, 0x3F72, 0x3FAE, 0x3FDC, 0x3FE1, 0x7FC4, 0x7FC8, - 0x7FD7, 0x7FF0, 0xFFE9, 0xFFEC, 0xFFF8, 0xFFF4, 0x7FF3, 0x7FDE, - 0x7FD3, 0x3FC0, 0x3F99, 0x3FA8, 0x3FAC, 0x3F8E, 0x1FA8, 0x1F79, - 0x1FA2, 0x3F89, 0x3F93, 0x3F95, 0x3F9C, 0x3FB8, 0x7FD2, 0x7FE6, - 0x7FDA, 0xFFF7, 0xFFFE, 0x7FED, 0x7FE2, 0x3FD5, 0x3FD7, 0x3FB3, - 0x3FA2, 0x3F80, 0x3F7A, 0x1F88, 0x1F70, 0x1F8A, 0x3F83, 0x3F84, - 0x3FAA, 0x3FC4, 0x3FDA, 0x3FDF, 0x7FDB, 0x7FE3, 0xFFF1, 0xFFFB, - 0x7FE1, 0x7FC7, 0x3FB0, 0x1FAA, 0x1FAB, 0x1FA3, 0x1F8E, 0x1F81, - 0x0FA7, 0x0F7F, 0x0FA8, 0x1F82, 0x1F8F, 0x1FA4, 0x1FAC, 0x1FAD, - 0x3FB5, 0x7FC6, 0x7FDD, 0xFFF3, 0x3FDD, 0x3FBE, 0x3FB9, 0x3F7C, - 0x1F77, 0x0FB5, 0x0F9D, 0x0F99, 0x0F90, 0x0794, 0x03BE, 0x0795, - 0x0F92, 0x0F9A, 0x0F9E, 0x0FB6, 0x1F78, 0x3F78, 0x3FB2, 0x3FBF, - 0x3FD2, 0x3FA7, 0x3F8C, 0x3F75, 0x1F9E, 0x0F93, 0x0F94, 0x0F7B, - 0x0F73, 0x07B4, 0x03BB, 0x01D9, 0x03BC, 0x07B5, 0x0F74, 0x0F7C, - 0x0F95, 0x0F96, 0x1FA0, 0x3F76, 0x3F8F, 0x3FA5, 0x7FE5, 0x3FC7, - 0x1F95, 0x1F71, 0x0FAB, 0x0FAC, 0x0F9F, 0x0F7D, 0x0796, 0x03BF, - 0x00DE, 0x03C0, 0x0797, 0x0F7E, 0x0FA0, 0x0FAD, 0x0FAE, 0x1F72, - 0x1F97, 0x3FD1, 0x7FD8, 0x3FA9, 0x3FA0, 0x3F6D, 0x1F99, 0x0F87, - 0x0F77, 0x07A8, 0x079C, 0x03C5, 0x01CA, 0x0067, 0x01CB, 0x03C6, - 0x079D, 0x07A9, 0x0F78, 0x0F8A, 0x1F9F, 0x3F6E, 0x3F98, 0x3F9A, - 0x3FCA, 0x3F70, 0x1FAF, 0x0F8D, 0x0F6F, 0x07AC, 0x07A0, 0x03B7, - 0x01CE, 0x00DA, 0x0063, 0x00DB, 0x01CF, 0x03B8, 0x07A1, 0x07AD, - 0x0F70, 0x0F91, 0x1FB2, 0x3F73, 0x3FD6, 0x3F7D, 0x1F91, 0x1F85, - 0x0FA3, 0x07A2, 0x01D4, 0x01D0, 0x00E0, 0x0068, 0x002C, 0x0014, - 0x002D, 0x0069, 0x00E1, 0x01D1, 0x01D5, 0x07A3, 0x0FA4, 0x1F89, - 0x1F92, 0x3F81, 0x3FA6, 0x1F7B, 0x1F7C, 0x1F7D, 0x07B0, 0x07AE, - 0x03C7, 0x00DC, 0x0064, 0x0008, 0x0000, 0x0009, 0x0065, 0x00DD, - 0x03C8, 0x07AF, 0x07B1, 0x1F7E, 0x1F7F, 0x1F80, 0x3F9E, 0x3F85, - 0x1F93, 0x1F8B, 0x0FA5, 0x07A4, 0x01D6, 0x01D2, 0x00E2, 0x006A, - 0x002E, 0x0015, 0x002F, 0x006B, 0x00E3, 0x01D3, 0x01D7, 0x07A5, - 0x0FA6, 0x1F8C, 0x1F94, 0x3F87, 0x3FCE, 0x3F77, 0x1FB4, 0x0F83, - 0x07B6, 0x07AA, 0x079E, 0x01DA, 0x01CC, 0x00D8, 0x0062, 0x00D9, - 0x01CD, 0x03B6, 0x079F, 0x07AB, 0x0F6E, 0x0F84, 0x1FA9, 0x3F6A, - 0x3FCD, 0x3F90, 0x3F92, 0x3F6B, 0x1F96, 0x0F85, 0x0F75, 0x07A6, - 0x079A, 0x03C3, 0x01C8, 0x0066, 0x01C9, 0x03C4, 0x079B, 0x07A7, - 0x0F76, 0x0F86, 0x1F9D, 0x3F6C, 0x3F96, 0x3F97, 0x7FE9, 0x3FD8, - 0x1F98, 0x1F73, 0x0FAF, 0x0FB0, 0x0FA1, 0x0F80, 0x0798, 0x03C1, - 0x01D8, 0x03C2, 0x0799, 0x0F81, 0x0FA2, 0x0FB1, 0x0FB2, 0x1F74, - 0x1F9A, 0x3FE0, 0x7FEE, 0x3F94, 0x3F8B, 0x3F6F, 0x1F9B, 0x0F88, - 0x0F89, 0x0F79, 0x0F71, 0x07B2, 0x03B9, 0x00DF, 0x03BA, 0x07B3, - 0x0F72, 0x0F7A, 0x0F8B, 0x0F8C, 0x1F9C, 0x3F71, 0x3F8A, 0x3F9B, - 0x3FC8, 0x3FBD, 0x3FC5, 0x3F79, 0x1F75, 0x0FB3, 0x0F9C, 0x0F97, - 0x0F8E, 0x0792, 0x03BD, 0x0793, 0x0F8F, 0x0F98, 0x0F9B, 0x0FB4, - 0x1F76, 0x3F82, 0x3FC3, 0x3FBA, 0x3FC6, 0xFFFD, 0x7FDF, 0x7FCC, - 0x3FBB, 0x1FB0, 0x1FAE, 0x1FA1, 0x1F90, 0x1F83, 0x0FAA, 0x0F82, - 0x0FA9, 0x1F84, 0x1F8D, 0x1FA5, 0x1FB1, 0x1FB3, 0x3FC2, 0x7FCA, - 0x7FE8, 0xFFF5, 0xFFFF, 0x7FDC, 0x7FD9, 0x3FCC, 0x3FD9, 0x3FB7, - 0x3F9F, 0x3F7E, 0x3F86, 0x1F86, 0x0FB7, 0x1F87, 0x3F7B, 0x3F7F, - 0x3FA1, 0x3FBC, 0x3FCB, 0x3FD4, 0x7FF1, 0x7FF2, 0xFFFA, 0xFFFC, - 0x7FE4, 0x7FE7, 0x7FD4, 0x3FAF, 0x3FA3, 0x3F91, 0x3F9D, 0x3F88, - 0x1FA6, 0x1F7A, 0x1FA7, 0x3F8D, 0x3FAB, 0x3FAD, 0x3FA4, 0x3FB6, - 0x7FD0, 0x7FE0, 0x7FEB, 0xFFF0, 0xFFF9, 0xFFEB, 0xFFED, 0x7FEA, - 0x7FD6, 0x7FC9, 0x7FCB, 0x3FD0, 0x3FDE, 0x3FB1, 0x3F74, 0x3FC1, - 0x3FCF, 0x3FDB, 0x7FCD, 0x7FCE, 0x7FD1, 0x7FEF, 0xFFE8, 0xFFEE, - 0xFFF6, 0x0030, -}; - -static const uint16_t clv_mvu_2_syms[] = { - 0xF6F6, 0xF7F6, 0xF8F6, 0xF9F6, 0xFAF6, 0xFBF6, 0xFCF6, 0xFDF6, - 0xFEF6, 0xFFF6, 0x00F6, 0x01F6, 0x02F6, 0x03F6, 0x04F6, 0x05F6, - 0x06F6, 0x07F6, 0x08F6, 0x09F6, 0x0AF6, 0xF6F7, 0xF7F7, 0xF8F7, - 0xF9F7, 0xFAF7, 0xFBF7, 0xFCF7, 0xFDF7, 0xFEF7, 0xFFF7, 0x00F7, - 0x01F7, 0x02F7, 0x03F7, 0x04F7, 0x05F7, 0x06F7, 0x07F7, 0x08F7, - 0x09F7, 0x0AF7, 0xF6F8, 0xF7F8, 0xF8F8, 0xF9F8, 0xFAF8, 0xFBF8, - 0xFCF8, 0xFDF8, 0xFEF8, 0xFFF8, 0x00F8, 0x01F8, 0x02F8, 0x03F8, - 0x04F8, 0x05F8, 0x06F8, 0x07F8, 0x08F8, 0x09F8, 0x0AF8, 0xF6F9, - 0xF7F9, 0xF8F9, 0xF9F9, 0xFAF9, 0xFBF9, 0xFCF9, 0xFDF9, 0xFEF9, - 0xFFF9, 0x00F9, 0x01F9, 0x02F9, 0x03F9, 0x04F9, 0x05F9, 0x06F9, - 0x07F9, 0x08F9, 0x09F9, 0x0AF9, 0xF6FA, 0xF7FA, 0xF8FA, 0xF9FA, - 0xFAFA, 0xFBFA, 0xFCFA, 0xFDFA, 0xFEFA, 0xFFFA, 0x00FA, 0x01FA, - 0x02FA, 0x03FA, 0x04FA, 0x05FA, 0x06FA, 0x07FA, 0x08FA, 0x09FA, - 0x0AFA, 0xF6FB, 0xF7FB, 0xF8FB, 0xF9FB, 0xFAFB, 0xFBFB, 0xFCFB, - 0xFDFB, 0xFEFB, 0xFFFB, 0x00FB, 0x01FB, 0x02FB, 0x03FB, 0x04FB, - 0x05FB, 0x06FB, 0x07FB, 0x08FB, 0x09FB, 0x0AFB, 0xF6FC, 0xF7FC, - 0xF8FC, 0xF9FC, 0xFAFC, 0xFBFC, 0xFCFC, 0xFDFC, 0xFEFC, 0xFFFC, - 0x00FC, 0x01FC, 0x02FC, 0x03FC, 0x04FC, 0x05FC, 0x06FC, 0x07FC, - 0x08FC, 0x09FC, 0x0AFC, 0xF6FD, 0xF7FD, 0xF8FD, 0xF9FD, 0xFAFD, - 0xFBFD, 0xFCFD, 0xFDFD, 0xFEFD, 0xFFFD, 0x00FD, 0x01FD, 0x02FD, - 0x03FD, 0x04FD, 0x05FD, 0x06FD, 0x07FD, 0x08FD, 0x09FD, 0x0AFD, - 0xF6FE, 0xF7FE, 0xF8FE, 0xF9FE, 0xFAFE, 0xFBFE, 0xFCFE, 0xFDFE, - 0xFEFE, 0xFFFE, 0x00FE, 0x01FE, 0x02FE, 0x03FE, 0x04FE, 0x05FE, - 0x06FE, 0x07FE, 0x08FE, 0x09FE, 0x0AFE, 0xF6FF, 0xF7FF, 0xF8FF, - 0xF9FF, 0xFAFF, 0xFBFF, 0xFCFF, 0xFDFF, 0xFEFF, 0xFFFF, 0x00FF, - 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, 0x07FF, 0x08FF, - 0x09FF, 0x0AFF, 0xF600, 0xF700, 0xF800, 0xF900, 0xFA00, 0xFB00, - 0xFC00, 0xFD00, 0xFE00, 0xFF00, 0x0000, 0x0100, 0x0200, 0x0300, - 0x0400, 0x0500, 0x0600, 0x0700, 0x0800, 0x0900, 0x0A00, 0xF601, - 0xF701, 0xF801, 0xF901, 0xFA01, 0xFB01, 0xFC01, 0xFD01, 0xFE01, - 0xFF01, 0x0001, 0x0101, 0x0201, 0x0301, 0x0401, 0x0501, 0x0601, - 0x0701, 0x0801, 0x0901, 0x0A01, 0xF602, 0xF702, 0xF802, 0xF902, - 0xFA02, 0xFB02, 0xFC02, 0xFD02, 0xFE02, 0xFF02, 0x0002, 0x0102, - 0x0202, 0x0302, 0x0402, 0x0502, 0x0602, 0x0702, 0x0802, 0x0902, - 0x0A02, 0xF603, 0xF703, 0xF803, 0xF903, 0xFA03, 0xFB03, 0xFC03, - 0xFD03, 0xFE03, 0xFF03, 0x0003, 0x0103, 0x0203, 0x0303, 0x0403, - 0x0503, 0x0603, 0x0703, 0x0803, 0x0903, 0x0A03, 0xF604, 0xF704, - 0xF804, 0xF904, 0xFA04, 0xFB04, 0xFC04, 0xFD04, 0xFE04, 0xFF04, - 0x0004, 0x0104, 0x0204, 0x0304, 0x0404, 0x0504, 0x0604, 0x0704, - 0x0804, 0x0904, 0x0A04, 0xF605, 0xF705, 0xF805, 0xF905, 0xFA05, - 0xFB05, 0xFC05, 0xFD05, 0xFE05, 0xFF05, 0x0005, 0x0105, 0x0205, - 0x0305, 0x0405, 0x0505, 0x0605, 0x0705, 0x0805, 0x0905, 0x0A05, - 0xF606, 0xF706, 0xF806, 0xF906, 0xFA06, 0xFB06, 0xFC06, 0xFD06, - 0xFE06, 0xFF06, 0x0006, 0x0106, 0x0206, 0x0306, 0x0406, 0x0506, - 0x0606, 0x0706, 0x0806, 0x0906, 0x0A06, 0xF607, 0xF707, 0xF807, - 0xF907, 0xFA07, 0xFB07, 0xFC07, 0xFD07, 0xFE07, 0xFF07, 0x0007, - 0x0107, 0x0207, 0x0307, 0x0407, 0x0507, 0x0607, 0x0707, 0x0807, - 0x0907, 0x0A07, 0xF608, 0xF708, 0xF808, 0xF908, 0xFA08, 0xFB08, - 0xFC08, 0xFD08, 0xFE08, 0xFF08, 0x0008, 0x0108, 0x0208, 0x0308, - 0x0408, 0x0508, 0x0608, 0x0708, 0x0808, 0x0908, 0x0A08, 0xF609, - 0xF709, 0xF809, 0xF909, 0xFA09, 0xFB09, 0xFC09, 0xFD09, 0xFE09, - 0xFF09, 0x0009, 0x0109, 0x0209, 0x0309, 0x0409, 0x0509, 0x0609, - 0x0709, 0x0809, 0x0909, 0x0A09, 0xF60A, 0xF70A, 0xF80A, 0xF90A, - 0xFA0A, 0xFB0A, 0xFC0A, 0xFD0A, 0xFE0A, 0xFF0A, 0x000A, 0x010A, - 0x020A, 0x030A, 0x040A, 0x050A, 0x060A, 0x070A, 0x080A, 0x090A, - 0x0A0A, 0x0B0B, -}; - -static const uint8_t clv_mvv_1_bits[] = { - 16, 15, 13, 13, 13, 12, 10, 10, 10, 12, 13, 13, 13, 15, 16, 16, - 15, 14, 13, 12, 11, 10, 9, 10, 11, 12, 13, 14, 15, 16, 15, 14, - 13, 13, 11, 10, 10, 5, 10, 10, 11, 13, 13, 14, 15, 12, 12, 12, - 11, 10, 10, 9, 5, 9, 10, 10, 11, 12, 12, 12, 14, 12, 12, 12, - 11, 9, 8, 5, 8, 9, 11, 12, 12, 12, 14, 14, 11, 11, 9, 9, - 9, 7, 5, 7, 9, 9, 9, 11, 11, 14, 13, 12, 11, 10, 10, 8, - 6, 3, 6, 8, 10, 10, 11, 12, 13, 11, 10, 9, 7, 6, 6, 4, - 4, 4, 6, 7, 7, 10, 10, 11, 13, 12, 11, 10, 10, 8, 6, 3, - 6, 8, 10, 10, 11, 12, 13, 14, 11, 11, 9, 9, 9, 7, 5, 7, - 9, 9, 9, 11, 11, 14, 14, 12, 12, 12, 11, 9, 8, 5, 8, 9, - 11, 12, 12, 12, 14, 12, 12, 12, 11, 10, 10, 9, 5, 9, 10, 10, - 11, 12, 12, 12, 15, 14, 13, 13, 11, 10, 10, 5, 10, 10, 11, 13, - 13, 14, 15, 16, 15, 14, 13, 12, 11, 10, 9, 10, 11, 12, 13, 14, - 15, 16, 16, 15, 13, 13, 13, 12, 10, 10, 10, 12, 13, 13, 13, 15, - 16, 7, -}; - -static const uint16_t clv_mvv_1_codes[] = { - 0xFFFD, 0x7FF8, 0x1FF2, 0x1FDC, 0x1FDB, 0x0FD2, 0x03D6, 0x03BF, - 0x03D3, 0x0FD0, 0x1FDA, 0x1FDE, 0x1FF0, 0x7FF9, 0xFFFE, 0xFFFA, - 0x7FFB, 0x3FF3, 0x1FE9, 0x0FD6, 0x07CB, 0x03E1, 0x01C8, 0x03E2, - 0x07CC, 0x0FD9, 0x1FE8, 0x3FF6, 0x7FFA, 0xFFF9, 0x7FF1, 0x3FEE, - 0x1FE4, 0x1FE0, 0x07D4, 0x03DB, 0x03CB, 0x0014, 0x03CC, 0x03DC, - 0x07D6, 0x1FE3, 0x1FE7, 0x3FEC, 0x7FF3, 0x0FEA, 0x0FE0, 0x0FDE, - 0x07DE, 0x03C9, 0x03C3, 0x01DC, 0x0013, 0x01DD, 0x03C4, 0x03CA, - 0x07DF, 0x0FDF, 0x0FE3, 0x0FEB, 0x3FF1, 0x0FE7, 0x0FCF, 0x0FC8, - 0x07D8, 0x01D2, 0x00E0, 0x0010, 0x00E1, 0x01D4, 0x07D9, 0x0FC9, - 0x0FCC, 0x0FE6, 0x3FF5, 0x3FEA, 0x07E2, 0x07D2, 0x01D7, 0x01D0, - 0x01CC, 0x006A, 0x000F, 0x006B, 0x01CD, 0x01D1, 0x01D9, 0x07D3, - 0x07E3, 0x3FEB, 0x1FEE, 0x0FD5, 0x07C7, 0x03D8, 0x03D0, 0x00DD, - 0x002D, 0x0001, 0x002E, 0x00DE, 0x03D1, 0x03D9, 0x07C8, 0x0FD8, - 0x1FEF, 0x07CE, 0x03C5, 0x01DE, 0x006C, 0x0032, 0x0030, 0x0005, - 0x0004, 0x0006, 0x0031, 0x0066, 0x006D, 0x03BE, 0x03C6, 0x07CF, - 0x1FEC, 0x0FDA, 0x07C9, 0x03DA, 0x03D2, 0x00DF, 0x002F, 0x0000, - 0x002C, 0x00DC, 0x03CF, 0x03D7, 0x07C6, 0x0FD4, 0x1FED, 0x3FE9, - 0x07E0, 0x07D0, 0x01D3, 0x01CE, 0x01CA, 0x0068, 0x000E, 0x0069, - 0x01CB, 0x01CF, 0x01D5, 0x07D1, 0x07E1, 0x3FE8, 0x3FF4, 0x0FE4, - 0x0FCD, 0x0FCB, 0x07DA, 0x01D6, 0x00E2, 0x0011, 0x00E3, 0x01D8, - 0x07DB, 0x0FCA, 0x0FCE, 0x0FE5, 0x3FF7, 0x0FE8, 0x0FE1, 0x0FDD, - 0x07DD, 0x03C7, 0x03C1, 0x01DA, 0x0012, 0x01DB, 0x03C2, 0x03C8, - 0x07DC, 0x0FDC, 0x0FE2, 0x0FE9, 0x7FF0, 0x3FEF, 0x1FE5, 0x1FE1, - 0x07D7, 0x03DD, 0x03CD, 0x0015, 0x03CE, 0x03DE, 0x07D5, 0x1FE2, - 0x1FE6, 0x3FED, 0x7FF2, 0xFFF8, 0x7FF4, 0x3FF2, 0x1FEB, 0x0FD7, - 0x07CD, 0x03DF, 0x01C9, 0x03E0, 0x07CA, 0x0FDB, 0x1FEA, 0x3FF0, - 0x7FF5, 0xFFFB, 0xFFFC, 0x7FF6, 0x1FF3, 0x1FDD, 0x1FD9, 0x0FD1, - 0x03D5, 0x03C0, 0x03D4, 0x0FD3, 0x1FD8, 0x1FDF, 0x1FF1, 0x7FF7, - 0xFFFF, 0x0067, -}; - -static const uint16_t clv_mvv_1_syms[] = { - 0xF9F9, 0xFAF9, 0xFBF9, 0xFCF9, 0xFDF9, 0xFEF9, 0xFFF9, 0x00F9, - 0x01F9, 0x02F9, 0x03F9, 0x04F9, 0x05F9, 0x06F9, 0x07F9, 0xF9FA, - 0xFAFA, 0xFBFA, 0xFCFA, 0xFDFA, 0xFEFA, 0xFFFA, 0x00FA, 0x01FA, - 0x02FA, 0x03FA, 0x04FA, 0x05FA, 0x06FA, 0x07FA, 0xF9FB, 0xFAFB, - 0xFBFB, 0xFCFB, 0xFDFB, 0xFEFB, 0xFFFB, 0x00FB, 0x01FB, 0x02FB, - 0x03FB, 0x04FB, 0x05FB, 0x06FB, 0x07FB, 0xF9FC, 0xFAFC, 0xFBFC, - 0xFCFC, 0xFDFC, 0xFEFC, 0xFFFC, 0x00FC, 0x01FC, 0x02FC, 0x03FC, - 0x04FC, 0x05FC, 0x06FC, 0x07FC, 0xF9FD, 0xFAFD, 0xFBFD, 0xFCFD, - 0xFDFD, 0xFEFD, 0xFFFD, 0x00FD, 0x01FD, 0x02FD, 0x03FD, 0x04FD, - 0x05FD, 0x06FD, 0x07FD, 0xF9FE, 0xFAFE, 0xFBFE, 0xFCFE, 0xFDFE, - 0xFEFE, 0xFFFE, 0x00FE, 0x01FE, 0x02FE, 0x03FE, 0x04FE, 0x05FE, - 0x06FE, 0x07FE, 0xF9FF, 0xFAFF, 0xFBFF, 0xFCFF, 0xFDFF, 0xFEFF, - 0xFFFF, 0x00FF, 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, - 0x07FF, 0xF900, 0xFA00, 0xFB00, 0xFC00, 0xFD00, 0xFE00, 0xFF00, - 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, - 0xF901, 0xFA01, 0xFB01, 0xFC01, 0xFD01, 0xFE01, 0xFF01, 0x0001, - 0x0101, 0x0201, 0x0301, 0x0401, 0x0501, 0x0601, 0x0701, 0xF902, - 0xFA02, 0xFB02, 0xFC02, 0xFD02, 0xFE02, 0xFF02, 0x0002, 0x0102, - 0x0202, 0x0302, 0x0402, 0x0502, 0x0602, 0x0702, 0xF903, 0xFA03, - 0xFB03, 0xFC03, 0xFD03, 0xFE03, 0xFF03, 0x0003, 0x0103, 0x0203, - 0x0303, 0x0403, 0x0503, 0x0603, 0x0703, 0xF904, 0xFA04, 0xFB04, - 0xFC04, 0xFD04, 0xFE04, 0xFF04, 0x0004, 0x0104, 0x0204, 0x0304, - 0x0404, 0x0504, 0x0604, 0x0704, 0xF905, 0xFA05, 0xFB05, 0xFC05, - 0xFD05, 0xFE05, 0xFF05, 0x0005, 0x0105, 0x0205, 0x0305, 0x0405, - 0x0505, 0x0605, 0x0705, 0xF906, 0xFA06, 0xFB06, 0xFC06, 0xFD06, - 0xFE06, 0xFF06, 0x0006, 0x0106, 0x0206, 0x0306, 0x0406, 0x0506, - 0x0606, 0x0706, 0xF907, 0xFA07, 0xFB07, 0xFC07, 0xFD07, 0xFE07, - 0xFF07, 0x0007, 0x0107, 0x0207, 0x0307, 0x0407, 0x0507, 0x0607, - 0x0707, 0x0808, -}; - -static const uint8_t clv_mvv_2_bits[] = { - 16, 15, 15, 15, 15, 15, 14, 14, 14, 13, 12, 13, 14, 14, 14, 15, - 15, 15, 15, 15, 16, 16, 16, 16, 15, 15, 14, 14, 14, 13, 13, 12, - 12, 13, 14, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 14, 14, 14, - 14, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, 14, 16, 16, 16, 15, - 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 13, 13, 13, 13, 14, - 14, 14, 15, 15, 16, 14, 14, 14, 13, 12, 12, 12, 10, 10, 10, 10, - 10, 12, 12, 12, 13, 14, 14, 14, 16, 14, 14, 14, 13, 13, 12, 12, - 12, 10, 10, 7, 10, 10, 12, 12, 12, 13, 13, 14, 14, 14, 14, 14, - 13, 12, 12, 12, 12, 10, 9, 8, 7, 8, 9, 10, 12, 12, 12, 12, - 13, 14, 14, 14, 14, 13, 12, 12, 12, 12, 10, 9, 8, 7, 8, 9, - 10, 12, 12, 12, 12, 13, 14, 14, 14, 14, 13, 13, 12, 12, 11, 10, - 9, 8, 7, 8, 9, 10, 11, 12, 12, 13, 13, 14, 14, 14, 13, 13, - 12, 10, 10, 9, 8, 7, 6, 5, 6, 7, 8, 9, 10, 10, 12, 13, - 13, 14, 13, 13, 13, 13, 11, 10, 9, 8, 7, 5, 1, 5, 7, 8, - 9, 10, 11, 13, 13, 13, 13, 14, 13, 13, 12, 10, 10, 9, 8, 7, - 6, 5, 6, 7, 8, 9, 10, 10, 12, 13, 13, 14, 14, 14, 13, 13, - 12, 12, 11, 9, 9, 8, 7, 8, 9, 9, 11, 12, 12, 13, 13, 14, - 14, 14, 14, 13, 12, 12, 12, 12, 10, 9, 8, 7, 8, 9, 10, 12, - 12, 12, 12, 13, 14, 14, 14, 14, 13, 12, 12, 12, 12, 10, 9, 8, - 7, 8, 9, 10, 12, 12, 12, 12, 13, 14, 14, 14, 14, 14, 13, 13, - 12, 12, 12, 10, 10, 7, 10, 10, 12, 12, 12, 13, 13, 14, 14, 14, - 16, 14, 14, 14, 13, 12, 12, 12, 10, 10, 10, 10, 10, 12, 12, 12, - 13, 14, 14, 14, 16, 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, - 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 14, 14, 14, - 14, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, 14, 16, 16, 16, 16, - 16, 16, 15, 15, 14, 14, 14, 13, 12, 12, 12, 13, 14, 14, 14, 15, - 15, 16, 16, 16, 16, 15, 15, 15, 15, 15, 14, 14, 14, 13, 10, 13, - 14, 14, 14, 15, 15, 15, 15, 15, 16, 6, -}; - -static const uint16_t clv_mvv_2_codes[] = { - 0xFFFF, 0x7FE7, 0x7FD9, 0x7FE6, 0x7FE5, 0x7FCE, 0x3FD6, 0x3FD3, - 0x3F9C, 0x1FB2, 0x0F7A, 0x1FB5, 0x3FA8, 0x3FDD, 0x3FE5, 0x7FD0, - 0x7FEA, 0x7FEC, 0x7FEF, 0x7FDB, 0xFFF3, 0xFFF5, 0xFFE2, 0xFFEB, - 0x7FEB, 0x7FE0, 0x3FA7, 0x3F84, 0x3F79, 0x1FAE, 0x1F70, 0x0F78, - 0x0FAA, 0x1FAA, 0x3F76, 0x3F7E, 0x3FAC, 0x7FE1, 0x7FDD, 0xFFEC, - 0xFFEE, 0xFFF8, 0xFFF9, 0xFFEA, 0xFFE4, 0x3FE1, 0x3FBA, 0x3FC5, - 0x3FB9, 0x3FA1, 0x3FAA, 0x1F8B, 0x1F8D, 0x1F8E, 0x3FA6, 0x3FA9, - 0x3FC4, 0x3FBC, 0x3FC6, 0x3FDB, 0xFFE3, 0xFFE1, 0xFFFB, 0x7FD4, - 0x7FCC, 0x3FCD, 0x3F88, 0x3F7C, 0x1FA1, 0x1FA2, 0x1F95, 0x1F77, - 0x0F95, 0x0F79, 0x0F97, 0x1F78, 0x1F96, 0x1FA3, 0x1FA4, 0x3F7F, - 0x3F8B, 0x3FCB, 0x7FCF, 0x7FD5, 0xFFF6, 0x3FD7, 0x3FE0, 0x3F91, - 0x1F7B, 0x0FB4, 0x0FA5, 0x0FA6, 0x03D5, 0x03CB, 0x03BF, 0x03CC, - 0x03D6, 0x0FA7, 0x0FA8, 0x0FB5, 0x1F7D, 0x3F87, 0x3FD2, 0x3FDF, - 0xFFF0, 0x3F95, 0x3F8A, 0x3F96, 0x1FB7, 0x1F9F, 0x0F9F, 0x0F8F, - 0x0F76, 0x03D1, 0x03BC, 0x0067, 0x03BD, 0x03D2, 0x0F77, 0x0F90, - 0x0FA0, 0x1FA0, 0x1FB9, 0x3F97, 0x3F98, 0x3F99, 0x3FC3, 0x3FAF, - 0x1F81, 0x0FA9, 0x0F91, 0x0F7E, 0x0F68, 0x03B2, 0x01C6, 0x00D4, - 0x0062, 0x00D5, 0x01C7, 0x03B3, 0x0F6A, 0x0F81, 0x0F93, 0x0FAC, - 0x1F83, 0x3FB3, 0x3FB4, 0x3FC7, 0x3FBB, 0x1F86, 0x0FAF, 0x0F98, - 0x0F84, 0x0F6D, 0x03B8, 0x01CC, 0x00DA, 0x0065, 0x00DB, 0x01CD, - 0x03B9, 0x0F6F, 0x0F86, 0x0F9B, 0x0FB1, 0x1F88, 0x3FB8, 0x3FC9, - 0x3FDC, 0x3F80, 0x1FB3, 0x1F93, 0x0F87, 0x0F72, 0x07B0, 0x03B0, - 0x01D4, 0x00E0, 0x0061, 0x00E1, 0x01D5, 0x03B1, 0x07B1, 0x0F73, - 0x0F88, 0x1F94, 0x1FB4, 0x3F81, 0x3FD4, 0x3F9E, 0x1F99, 0x1F73, - 0x0F89, 0x03C4, 0x03C0, 0x01CE, 0x00D0, 0x005C, 0x0028, 0x0010, - 0x0029, 0x005D, 0x00D1, 0x01CF, 0x03C1, 0x03C5, 0x0F8A, 0x1F74, - 0x1F9A, 0x3FA4, 0x1FAC, 0x1F8C, 0x1F7E, 0x1F71, 0x07B2, 0x03CF, - 0x01C4, 0x00DC, 0x005A, 0x0012, 0x0000, 0x0013, 0x005B, 0x00DD, - 0x01C5, 0x03D0, 0x07B3, 0x1F72, 0x1F7F, 0x1F8F, 0x1FAD, 0x3FAB, - 0x1F9B, 0x1F75, 0x0F8B, 0x03C6, 0x03C2, 0x01D0, 0x00D2, 0x005E, - 0x002A, 0x0011, 0x002B, 0x005F, 0x00D3, 0x01D1, 0x03C3, 0x03C7, - 0x0F8C, 0x1F76, 0x1F9C, 0x3FAD, 0x3FCF, 0x3F85, 0x1FBA, 0x1F91, - 0x0F7D, 0x0F70, 0x07AE, 0x01D6, 0x01D2, 0x00DE, 0x0060, 0x00DF, - 0x01D3, 0x01D7, 0x07AF, 0x0F71, 0x0F7F, 0x1F92, 0x1FAF, 0x3F7B, - 0x3FD0, 0x3FC0, 0x3FB1, 0x1F82, 0x0FAB, 0x0F92, 0x0F80, 0x0F69, - 0x03B4, 0x01C8, 0x00D6, 0x0063, 0x00D7, 0x01C9, 0x03B5, 0x0F6B, - 0x0F82, 0x0F94, 0x0FAD, 0x1F84, 0x3FB5, 0x3FC2, 0x3FB6, 0x3FBF, - 0x1F85, 0x0FAE, 0x0F96, 0x0F83, 0x0F6C, 0x03B6, 0x01CA, 0x00D8, - 0x0064, 0x00D9, 0x01CB, 0x03B7, 0x0F6E, 0x0F85, 0x0F99, 0x0FB0, - 0x1F87, 0x3FB0, 0x3FB2, 0x3F93, 0x3F86, 0x3F8E, 0x1FB1, 0x1F9D, - 0x0F9A, 0x0F8D, 0x0F74, 0x03CD, 0x03BA, 0x0066, 0x03BB, 0x03CE, - 0x0F75, 0x0F8E, 0x0F9C, 0x1F9E, 0x1FB0, 0x3F8C, 0x3F94, 0x3F8D, - 0xFFFC, 0x3FCA, 0x3FD5, 0x3F8F, 0x1F79, 0x0FB2, 0x0FA1, 0x0FA2, - 0x03D3, 0x03C9, 0x03BE, 0x03CA, 0x03D4, 0x0FA3, 0x0FA4, 0x0FB3, - 0x1F7A, 0x3F90, 0x3FE3, 0x3FD8, 0xFFF2, 0x7FD7, 0x7FCD, 0x3FE4, - 0x3F92, 0x3F82, 0x1FA6, 0x1FA8, 0x1F98, 0x1F7C, 0x0F9D, 0x0F7B, - 0x0F9E, 0x1F80, 0x1F97, 0x1FA7, 0x1FA5, 0x3F7A, 0x3F89, 0x3FDA, - 0x7FD2, 0x7FD6, 0xFFFE, 0xFFED, 0xFFE8, 0x3FCC, 0x3FBD, 0x3FAE, - 0x3FC1, 0x3F9F, 0x3F9A, 0x1F89, 0x1F90, 0x1F8A, 0x3FA3, 0x3FA0, - 0x3FC8, 0x3FBE, 0x3FB7, 0x3FD1, 0xFFE7, 0xFFE9, 0xFFFD, 0xFFF4, - 0xFFE5, 0xFFEF, 0x7FD8, 0x7FDC, 0x3FA2, 0x3F83, 0x3F78, 0x1FA9, - 0x0FB6, 0x0F7C, 0x0FB7, 0x1FAB, 0x3F77, 0x3F7D, 0x3F9B, 0x7FDE, - 0x7FED, 0xFFE6, 0xFFE0, 0xFFF7, 0xFFF1, 0x7FDA, 0x7FE9, 0x7FE2, - 0x7FE3, 0x7FD1, 0x3FD9, 0x3FE2, 0x3FA5, 0x1FB8, 0x03C8, 0x1FB6, - 0x3F9D, 0x3FDE, 0x3FCE, 0x7FD3, 0x7FEE, 0x7FDF, 0x7FE8, 0x7FE4, - 0xFFFA, 0x002C, -}; - -static const uint16_t clv_mvv_2_syms[] = { - 0xF6F6, 0xF7F6, 0xF8F6, 0xF9F6, 0xFAF6, 0xFBF6, 0xFCF6, 0xFDF6, - 0xFEF6, 0xFFF6, 0x00F6, 0x01F6, 0x02F6, 0x03F6, 0x04F6, 0x05F6, - 0x06F6, 0x07F6, 0x08F6, 0x09F6, 0x0AF6, 0xF6F7, 0xF7F7, 0xF8F7, - 0xF9F7, 0xFAF7, 0xFBF7, 0xFCF7, 0xFDF7, 0xFEF7, 0xFFF7, 0x00F7, - 0x01F7, 0x02F7, 0x03F7, 0x04F7, 0x05F7, 0x06F7, 0x07F7, 0x08F7, - 0x09F7, 0x0AF7, 0xF6F8, 0xF7F8, 0xF8F8, 0xF9F8, 0xFAF8, 0xFBF8, - 0xFCF8, 0xFDF8, 0xFEF8, 0xFFF8, 0x00F8, 0x01F8, 0x02F8, 0x03F8, - 0x04F8, 0x05F8, 0x06F8, 0x07F8, 0x08F8, 0x09F8, 0x0AF8, 0xF6F9, - 0xF7F9, 0xF8F9, 0xF9F9, 0xFAF9, 0xFBF9, 0xFCF9, 0xFDF9, 0xFEF9, - 0xFFF9, 0x00F9, 0x01F9, 0x02F9, 0x03F9, 0x04F9, 0x05F9, 0x06F9, - 0x07F9, 0x08F9, 0x09F9, 0x0AF9, 0xF6FA, 0xF7FA, 0xF8FA, 0xF9FA, - 0xFAFA, 0xFBFA, 0xFCFA, 0xFDFA, 0xFEFA, 0xFFFA, 0x00FA, 0x01FA, - 0x02FA, 0x03FA, 0x04FA, 0x05FA, 0x06FA, 0x07FA, 0x08FA, 0x09FA, - 0x0AFA, 0xF6FB, 0xF7FB, 0xF8FB, 0xF9FB, 0xFAFB, 0xFBFB, 0xFCFB, - 0xFDFB, 0xFEFB, 0xFFFB, 0x00FB, 0x01FB, 0x02FB, 0x03FB, 0x04FB, - 0x05FB, 0x06FB, 0x07FB, 0x08FB, 0x09FB, 0x0AFB, 0xF6FC, 0xF7FC, - 0xF8FC, 0xF9FC, 0xFAFC, 0xFBFC, 0xFCFC, 0xFDFC, 0xFEFC, 0xFFFC, - 0x00FC, 0x01FC, 0x02FC, 0x03FC, 0x04FC, 0x05FC, 0x06FC, 0x07FC, - 0x08FC, 0x09FC, 0x0AFC, 0xF6FD, 0xF7FD, 0xF8FD, 0xF9FD, 0xFAFD, - 0xFBFD, 0xFCFD, 0xFDFD, 0xFEFD, 0xFFFD, 0x00FD, 0x01FD, 0x02FD, - 0x03FD, 0x04FD, 0x05FD, 0x06FD, 0x07FD, 0x08FD, 0x09FD, 0x0AFD, - 0xF6FE, 0xF7FE, 0xF8FE, 0xF9FE, 0xFAFE, 0xFBFE, 0xFCFE, 0xFDFE, - 0xFEFE, 0xFFFE, 0x00FE, 0x01FE, 0x02FE, 0x03FE, 0x04FE, 0x05FE, - 0x06FE, 0x07FE, 0x08FE, 0x09FE, 0x0AFE, 0xF6FF, 0xF7FF, 0xF8FF, - 0xF9FF, 0xFAFF, 0xFBFF, 0xFCFF, 0xFDFF, 0xFEFF, 0xFFFF, 0x00FF, - 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, 0x07FF, 0x08FF, - 0x09FF, 0x0AFF, 0xF600, 0xF700, 0xF800, 0xF900, 0xFA00, 0xFB00, - 0xFC00, 0xFD00, 0xFE00, 0xFF00, 0x0000, 0x0100, 0x0200, 0x0300, - 0x0400, 0x0500, 0x0600, 0x0700, 0x0800, 0x0900, 0x0A00, 0xF601, - 0xF701, 0xF801, 0xF901, 0xFA01, 0xFB01, 0xFC01, 0xFD01, 0xFE01, - 0xFF01, 0x0001, 0x0101, 0x0201, 0x0301, 0x0401, 0x0501, 0x0601, - 0x0701, 0x0801, 0x0901, 0x0A01, 0xF602, 0xF702, 0xF802, 0xF902, - 0xFA02, 0xFB02, 0xFC02, 0xFD02, 0xFE02, 0xFF02, 0x0002, 0x0102, - 0x0202, 0x0302, 0x0402, 0x0502, 0x0602, 0x0702, 0x0802, 0x0902, - 0x0A02, 0xF603, 0xF703, 0xF803, 0xF903, 0xFA03, 0xFB03, 0xFC03, - 0xFD03, 0xFE03, 0xFF03, 0x0003, 0x0103, 0x0203, 0x0303, 0x0403, - 0x0503, 0x0603, 0x0703, 0x0803, 0x0903, 0x0A03, 0xF604, 0xF704, - 0xF804, 0xF904, 0xFA04, 0xFB04, 0xFC04, 0xFD04, 0xFE04, 0xFF04, - 0x0004, 0x0104, 0x0204, 0x0304, 0x0404, 0x0504, 0x0604, 0x0704, - 0x0804, 0x0904, 0x0A04, 0xF605, 0xF705, 0xF805, 0xF905, 0xFA05, - 0xFB05, 0xFC05, 0xFD05, 0xFE05, 0xFF05, 0x0005, 0x0105, 0x0205, - 0x0305, 0x0405, 0x0505, 0x0605, 0x0705, 0x0805, 0x0905, 0x0A05, - 0xF606, 0xF706, 0xF806, 0xF906, 0xFA06, 0xFB06, 0xFC06, 0xFD06, - 0xFE06, 0xFF06, 0x0006, 0x0106, 0x0206, 0x0306, 0x0406, 0x0506, - 0x0606, 0x0706, 0x0806, 0x0906, 0x0A06, 0xF607, 0xF707, 0xF807, - 0xF907, 0xFA07, 0xFB07, 0xFC07, 0xFD07, 0xFE07, 0xFF07, 0x0007, - 0x0107, 0x0207, 0x0307, 0x0407, 0x0507, 0x0607, 0x0707, 0x0807, - 0x0907, 0x0A07, 0xF608, 0xF708, 0xF808, 0xF908, 0xFA08, 0xFB08, - 0xFC08, 0xFD08, 0xFE08, 0xFF08, 0x0008, 0x0108, 0x0208, 0x0308, - 0x0408, 0x0508, 0x0608, 0x0708, 0x0808, 0x0908, 0x0A08, 0xF609, - 0xF709, 0xF809, 0xF909, 0xFA09, 0xFB09, 0xFC09, 0xFD09, 0xFE09, - 0xFF09, 0x0009, 0x0109, 0x0209, 0x0309, 0x0409, 0x0509, 0x0609, - 0x0709, 0x0809, 0x0909, 0x0A09, 0xF60A, 0xF70A, 0xF80A, 0xF90A, - 0xFA0A, 0xFB0A, 0xFC0A, 0xFD0A, 0xFE0A, 0xFF0A, 0x000A, 0x010A, - 0x020A, 0x030A, 0x040A, 0x050A, 0x060A, 0x070A, 0x080A, 0x090A, - 0x0A0A, 0x0B0B, -}; - -static const uint8_t clv_biasy_1_bits[] = { - 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 13, 13, - 13, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, - 8, 8, 7, 7, 5, 2, 1, 3, 5, 7, 7, 8, 9, 9, 10, 10, - 10, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 16, 12, -}; - -static const uint16_t clv_biasy_1_codes[] = { - 0xFFFE, 0x7FFE, 0x7FFC, 0x7FFA, 0x7FF6, 0x7FF7, 0x7FF3, 0x7FF2, - 0x7FEF, 0x7FEE, 0x3FF5, 0x3FF3, 0x3FF1, 0x1FF7, 0x1FF5, 0x1FF2, - 0x1FF0, 0x1FEE, 0x1FEC, 0x1FEA, 0x1FE8, 0x0FF2, 0x0FF0, 0x0FEE, - 0x0FEB, 0x07F4, 0x07F3, 0x07F1, 0x03F7, 0x03F5, 0x03F3, 0x01F7, - 0x00FA, 0x00F8, 0x007A, 0x0078, 0x001C, 0x0002, 0x0000, 0x0006, - 0x001D, 0x0079, 0x007B, 0x00F9, 0x01F6, 0x01F8, 0x03F2, 0x03F4, - 0x03F6, 0x07F0, 0x07F2, 0x0FEA, 0x0FEC, 0x0FEF, 0x0FF1, 0x0FF3, - 0x1FE9, 0x1FEB, 0x1FED, 0x1FEF, 0x1FF1, 0x1FF3, 0x1FF4, 0x1FF6, - 0x3FF0, 0x3FF2, 0x3FF4, 0x3FF6, 0x7FF0, 0x7FF1, 0x7FF4, 0x7FF8, - 0x7FF5, 0x7FF9, 0x7FFB, 0x7FFD, 0xFFFF, 0x0FED, -}; - -static const uint16_t clv_biasy_1_syms[] = { - 0xFF68, 0xFF6C, 0xFF70, 0xFF74, 0xFF78, 0xFF7C, 0xFF80, 0xFF84, - 0xFF88, 0xFF8C, 0xFF90, 0xFF94, 0xFF98, 0xFF9C, 0xFFA0, 0xFFA4, - 0xFFA8, 0xFFAC, 0xFFB0, 0xFFB4, 0xFFB8, 0xFFBC, 0xFFC0, 0xFFC4, - 0xFFC8, 0xFFCC, 0xFFD0, 0xFFD4, 0xFFD8, 0xFFDC, 0xFFE0, 0xFFE4, - 0xFFE8, 0xFFEC, 0xFFF0, 0xFFF4, 0xFFF8, 0xFFFC, 0x0000, 0x0004, - 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, 0x0020, 0x0024, - 0x0028, 0x002C, 0x0030, 0x0034, 0x0038, 0x003C, 0x0040, 0x0044, - 0x0048, 0x004C, 0x0050, 0x0054, 0x0058, 0x005C, 0x0060, 0x0064, - 0x0068, 0x006C, 0x0070, 0x0074, 0x0078, 0x007C, 0x0080, 0x0084, - 0x0088, 0x008C, 0x0090, 0x0094, 0x0098, 0x0100, -}; - -static const uint8_t clv_biasy_2_bits[] = { - 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 14, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 12, 12, 11, - 11, 11, 10, 10, 10, 10, 9, 9, 8, 8, 8, 7, 6, 6, 4, 3, - 1, 3, 4, 6, 6, 7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 11, - 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, - 16, 15, -}; - -static const uint16_t clv_biasy_2_codes[] = { - 0xFFFE, 0xFFFC, 0xFFFA, 0xFFF9, 0xFFF6, 0xFFF5, 0xFFF3, 0x7FF7, - 0x7FF5, 0x7FF1, 0x7FF3, 0x7FF0, 0x7FEE, 0x7FEC, 0x7FE9, 0x7FE6, - 0x7FE4, 0x7FE2, 0x3FEF, 0x3FEE, 0x3FEC, 0x3FEA, 0x1FF2, 0x1FF1, - 0x1FEF, 0x1FED, 0x0FF4, 0x0FF3, 0x0FF1, 0x0FEF, 0x0FED, 0x07F4, - 0x07F3, 0x07F1, 0x03F6, 0x03F4, 0x03F2, 0x03F0, 0x01F6, 0x01F4, - 0x00F8, 0x00F6, 0x00F4, 0x0078, 0x003A, 0x0038, 0x000C, 0x0004, - 0x0000, 0x0005, 0x000D, 0x0039, 0x003B, 0x0079, 0x00F5, 0x00F7, - 0x00F9, 0x01F5, 0x01F7, 0x03F1, 0x03F3, 0x03F5, 0x03F7, 0x07F0, - 0x07F2, 0x07F5, 0x0FEC, 0x0FEE, 0x0FF0, 0x0FF2, 0x0FF5, 0x1FEC, - 0x1FEE, 0x1FF0, 0x1FF3, 0x1FF4, 0x3FEB, 0x3FED, 0x3FF0, 0x7FE3, - 0x7FE5, 0x7FE7, 0x7FEA, 0x7FEB, 0x7FED, 0x7FEF, 0x7FF4, 0x7FF2, - 0x7FF6, 0x7FF8, 0xFFF2, 0xFFF4, 0xFFF7, 0xFFF8, 0xFFFB, 0xFFFD, - 0xFFFF, 0x7FE8, -}; - -static const uint16_t clv_biasy_2_syms[] = { - 0xFF40, 0xFF44, 0xFF48, 0xFF4C, 0xFF50, 0xFF54, 0xFF58, 0xFF5C, - 0xFF60, 0xFF64, 0xFF68, 0xFF6C, 0xFF70, 0xFF74, 0xFF78, 0xFF7C, - 0xFF80, 0xFF84, 0xFF88, 0xFF8C, 0xFF90, 0xFF94, 0xFF98, 0xFF9C, - 0xFFA0, 0xFFA4, 0xFFA8, 0xFFAC, 0xFFB0, 0xFFB4, 0xFFB8, 0xFFBC, - 0xFFC0, 0xFFC4, 0xFFC8, 0xFFCC, 0xFFD0, 0xFFD4, 0xFFD8, 0xFFDC, - 0xFFE0, 0xFFE4, 0xFFE8, 0xFFEC, 0xFFF0, 0xFFF4, 0xFFF8, 0xFFFC, - 0x0000, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, - 0x0020, 0x0024, 0x0028, 0x002C, 0x0030, 0x0034, 0x0038, 0x003C, - 0x0040, 0x0044, 0x0048, 0x004C, 0x0050, 0x0054, 0x0058, 0x005C, - 0x0060, 0x0064, 0x0068, 0x006C, 0x0070, 0x0074, 0x0078, 0x007C, - 0x0080, 0x0084, 0x0088, 0x008C, 0x0090, 0x0094, 0x0098, 0x009C, - 0x00A0, 0x00A4, 0x00A8, 0x00AC, 0x00B0, 0x00B4, 0x00B8, 0x00BC, - 0x00C0, 0x0100, -}; - -static const uint8_t clv_biasy_3_bits[] = { - 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, - 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, - 10, 9, 9, 9, 9, 8, 8, 7, 7, 6, 5, 4, 4, 2, 2, 3, - 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, - 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 15, -}; - -static const uint16_t clv_biasy_3_codes[] = { - 0xFFFF, 0xFFFC, 0xFFFA, 0x7FFC, 0x7FF9, 0x7FF6, 0x7FF4, 0x7FF2, - 0x7FF1, 0x7FEF, 0x7FEC, 0x7FEB, 0x7FE9, 0x3FF3, 0x3FF0, 0x3FEE, - 0x3FED, 0x3FEA, 0x1FF3, 0x1FF2, 0x1FF0, 0x1FEE, 0x0FF4, 0x0FF3, - 0x0FF1, 0x07F7, 0x07F5, 0x07F3, 0x07F1, 0x03F7, 0x03F4, 0x03F2, - 0x03F0, 0x01F6, 0x01F4, 0x01F2, 0x01F0, 0x00F6, 0x00F4, 0x0078, - 0x0076, 0x0039, 0x001B, 0x000C, 0x000A, 0x0001, 0x0000, 0x0004, - 0x000B, 0x001A, 0x0038, 0x003A, 0x0077, 0x0079, 0x00F5, 0x00F7, - 0x01F1, 0x01F3, 0x01F5, 0x01F7, 0x03F1, 0x03F3, 0x03F5, 0x03F6, - 0x07F0, 0x07F2, 0x07F4, 0x07F6, 0x0FF0, 0x0FF2, 0x0FF5, 0x0FF6, - 0x1FEF, 0x1FF1, 0x1FF4, 0x3FEB, 0x3FEC, 0x3FEF, 0x3FF1, 0x3FF2, - 0x7FE8, 0x7FEA, 0x7FED, 0x7FEE, 0x7FF0, 0x7FF3, 0x7FF5, 0x7FF7, - 0x7FFA, 0x7FFB, 0xFFFB, 0xFFFD, 0xFFFE, 0x7FF8, -}; - -static const uint16_t clv_biasy_3_syms[] = { - 0xFF48, 0xFF4C, 0xFF50, 0xFF54, 0xFF58, 0xFF5C, 0xFF60, 0xFF64, - 0xFF68, 0xFF6C, 0xFF70, 0xFF74, 0xFF78, 0xFF7C, 0xFF80, 0xFF84, - 0xFF88, 0xFF8C, 0xFF90, 0xFF94, 0xFF98, 0xFF9C, 0xFFA0, 0xFFA4, - 0xFFA8, 0xFFAC, 0xFFB0, 0xFFB4, 0xFFB8, 0xFFBC, 0xFFC0, 0xFFC4, - 0xFFC8, 0xFFCC, 0xFFD0, 0xFFD4, 0xFFD8, 0xFFDC, 0xFFE0, 0xFFE4, - 0xFFE8, 0xFFEC, 0xFFF0, 0xFFF4, 0xFFF8, 0xFFFC, 0x0000, 0x0004, - 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, 0x0020, 0x0024, - 0x0028, 0x002C, 0x0030, 0x0034, 0x0038, 0x003C, 0x0040, 0x0044, - 0x0048, 0x004C, 0x0050, 0x0054, 0x0058, 0x005C, 0x0060, 0x0064, - 0x0068, 0x006C, 0x0070, 0x0074, 0x0078, 0x007C, 0x0080, 0x0084, - 0x0088, 0x008C, 0x0090, 0x0094, 0x0098, 0x009C, 0x00A0, 0x00A4, - 0x00A8, 0x00AC, 0x00B0, 0x00B4, 0x00B8, 0x0100, -}; - -static const uint8_t clv_biasu_1_bits[] = { - 16, 15, 14, 13, 13, 13, 12, 12, 12, 12, 11, 10, 10, 9, 9, 8, - 7, 6, 5, 2, 1, 3, 5, 7, 7, 8, 9, 9, 10, 10, 11, 12, - 12, 12, 12, 13, 13, 13, 14, 15, 15, 16, -}; - -static const uint16_t clv_biasu_1_codes[] = { - 0xFFFE, 0x7FFC, 0x3FFC, 0x1FFC, 0x1FFA, 0x1FF9, 0x0FFA, 0x0FF7, - 0x0FF8, 0x0FF5, 0x07F8, 0x03FA, 0x03F8, 0x01FA, 0x01F9, 0x00FA, - 0x007B, 0x003C, 0x001C, 0x0002, 0x0000, 0x0006, 0x001D, 0x007A, - 0x007C, 0x00FB, 0x01F8, 0x01FB, 0x03F9, 0x03FB, 0x07F9, 0x0FF4, - 0x0FF6, 0x0FF9, 0x0FFB, 0x1FF8, 0x1FFB, 0x1FFD, 0x3FFD, 0x7FFD, - 0x7FFE, 0xFFFF, -}; - -static const uint16_t clv_biasu_1_syms[] = { - 0xFFB0, 0xFFB4, 0xFFB8, 0xFFBC, 0xFFC0, 0xFFC4, 0xFFC8, 0xFFCC, - 0xFFD0, 0xFFD4, 0xFFD8, 0xFFDC, 0xFFE0, 0xFFE4, 0xFFE8, 0xFFEC, - 0xFFF0, 0xFFF4, 0xFFF8, 0xFFFC, 0x0000, 0x0004, 0x0008, 0x000C, - 0x0010, 0x0014, 0x0018, 0x001C, 0x0020, 0x0024, 0x0028, 0x002C, - 0x0030, 0x0034, 0x0038, 0x003C, 0x0040, 0x0044, 0x0048, 0x004C, - 0x0050, 0x0100, -}; - -static const uint8_t clv_biasu_2_bits[] = { - 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 12, 12, 11, 11, 10, - 10, 9, 9, 8, 8, 7, 6, 5, 4, 3, 1, 3, 4, 6, 6, 7, - 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 14, 14, 15, 15, - 15, 16, 16, 16, 16, 14, -}; - -static const uint16_t clv_biasu_2_codes[] = { - 0xFFFC, 0xFFF8, 0xFFFA, 0xFFFD, 0x7FF8, 0x7FFA, 0x7FF7, 0x3FF6, - 0x3FF7, 0x3FF4, 0x1FF9, 0x0FFB, 0x0FF9, 0x07FB, 0x07F9, 0x03FA, - 0x03F8, 0x01FA, 0x01F9, 0x00FB, 0x00F9, 0x007B, 0x003B, 0x001C, - 0x000C, 0x0004, 0x0000, 0x0005, 0x000D, 0x003A, 0x003C, 0x007A, - 0x00F8, 0x00FA, 0x01F8, 0x01FB, 0x03F9, 0x03FB, 0x07F8, 0x07FA, - 0x0FF8, 0x0FFA, 0x1FF8, 0x3FF5, 0x3FF8, 0x3FF9, 0x7FFB, 0x7FF9, - 0x7FF6, 0xFFF9, 0xFFFF, 0xFFFE, 0xFFFB, 0x3FFA, -}; - -static const uint16_t clv_biasu_2_syms[] = { - 0xFF98, 0xFF9C, 0xFFA0, 0xFFA4, 0xFFA8, 0xFFAC, 0xFFB0, 0xFFB4, - 0xFFB8, 0xFFBC, 0xFFC0, 0xFFC4, 0xFFC8, 0xFFCC, 0xFFD0, 0xFFD4, - 0xFFD8, 0xFFDC, 0xFFE0, 0xFFE4, 0xFFE8, 0xFFEC, 0xFFF0, 0xFFF4, - 0xFFF8, 0xFFFC, 0x0000, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, - 0x0018, 0x001C, 0x0020, 0x0024, 0x0028, 0x002C, 0x0030, 0x0034, - 0x0038, 0x003C, 0x0040, 0x0044, 0x0048, 0x004C, 0x0050, 0x0054, - 0x0058, 0x005C, 0x0060, 0x0064, 0x0068, 0x0100, -}; - -static const uint8_t clv_biasv_1_bits[] = { - 16, 15, 14, 14, 14, 13, 13, 13, 12, 12, 11, 11, 10, 10, 9, 8, - 7, 6, 5, 2, 1, 3, 5, 6, 8, 8, 9, 10, 10, 11, 12, 12, - 12, 13, 13, 13, 14, 14, 15, 15, 16, 14, -}; - -static const uint16_t clv_biasv_1_codes[] = { - 0xFFFF, 0x7FFD, 0x3FFD, 0x3FFB, 0x3FF9, 0x1FFB, 0x1FF8, 0x1FF6, - 0x0FFA, 0x0FF8, 0x07FA, 0x07F8, 0x03FA, 0x03F8, 0x01FB, 0x00FB, - 0x007C, 0x003C, 0x001C, 0x0002, 0x0000, 0x0006, 0x001D, 0x003D, - 0x00FA, 0x00FC, 0x01FA, 0x03F9, 0x03FB, 0x07F9, 0x0FF6, 0x0FF7, - 0x0FF9, 0x1FF7, 0x1FF9, 0x1FFA, 0x3FFA, 0x3FFC, 0x7FFC, 0x7FFE, - 0xFFFE, 0x3FF8, -}; - -static const uint16_t clv_biasv_1_syms[] = { - 0xFFB0, 0xFFB4, 0xFFB8, 0xFFBC, 0xFFC0, 0xFFC4, 0xFFC8, 0xFFCC, - 0xFFD0, 0xFFD4, 0xFFD8, 0xFFDC, 0xFFE0, 0xFFE4, 0xFFE8, 0xFFEC, - 0xFFF0, 0xFFF4, 0xFFF8, 0xFFFC, 0x0000, 0x0004, 0x0008, 0x000C, - 0x0010, 0x0014, 0x0018, 0x001C, 0x0020, 0x0024, 0x0028, 0x002C, - 0x0030, 0x0034, 0x0038, 0x003C, 0x0040, 0x0044, 0x0048, 0x004C, - 0x0050, 0x0100, -}; - -static const uint8_t clv_biasv_2_bits[] = { - 16, 15, 14, 13, 13, 13, 13, 13, 12, 12, 11, 10, 10, 9, 9, 8, - 7, 6, 5, 4, 3, 1, 3, 4, 5, 7, 7, 8, 9, 9, 10, 10, - 10, 12, 12, 13, 13, 13, 13, 13, 14, 16, 15, 15, -}; - -static const uint16_t clv_biasv_2_codes[] = { - 0xFFFE, 0x7FFD, 0x3FFC, 0x1FFC, 0x1FFB, 0x1FF8, 0x1FF7, 0x1FF4, - 0x0FF8, 0x0FF7, 0x07FA, 0x03FB, 0x03F8, 0x01FA, 0x01F9, 0x00FA, - 0x007B, 0x003C, 0x001C, 0x000C, 0x0004, 0x0000, 0x0005, 0x000D, - 0x001D, 0x007A, 0x007C, 0x00FB, 0x01F8, 0x01FB, 0x03F9, 0x03FA, - 0x03FC, 0x0FF6, 0x0FF9, 0x1FF5, 0x1FF9, 0x1FF6, 0x1FFA, 0x1FFD, - 0x3FFD, 0xFFFF, 0x7FFE, 0x7FFC, -}; - -static const uint16_t clv_biasv_2_syms[] = { - 0xFFAC, 0xFFB0, 0xFFB4, 0xFFB8, 0xFFBC, 0xFFC0, 0xFFC4, 0xFFC8, - 0xFFCC, 0xFFD0, 0xFFD4, 0xFFD8, 0xFFDC, 0xFFE0, 0xFFE4, 0xFFE8, - 0xFFEC, 0xFFF0, 0xFFF4, 0xFFF8, 0xFFFC, 0x0000, 0x0004, 0x0008, - 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, 0x0020, 0x0024, 0x0028, - 0x002C, 0x0030, 0x0034, 0x0038, 0x003C, 0x0040, 0x0044, 0x0048, - 0x004C, 0x0050, 0x0054, 0x0100, +#define BIAS_ESC 1 +static const uint16_t clv_bias_syms[] = { + /* Y_1 bias values - 78 entries */ + 0x0000, 0xFFFC, 0x0004, 0xFFF8, 0x0008, 0xFFF4, 0x000C, 0xFFF0, 0x0010, + 0xFFEC, 0x0014, 0xFFE8, 0x0018, 0xFFE4, 0x001C, 0x0020, 0xFFE0, 0x0024, + 0xFFDC, 0x0028, 0xFFD8, 0x002C, 0xFFD4, 0x0030, 0xFFD0, 0xFFCC, 0x0034, + 0xFFC8, 0x0038, BIAS_ESC, 0xFFC4, 0x003C, 0xFFC0, 0x0040, 0xFFBC, 0x0044, + 0xFFB8, 0x0048, 0xFFB4, 0x004C, 0xFFB0, 0x0050, 0xFFAC, 0x0054, 0xFFA8, + 0x0058, 0xFFA4, 0x005C, 0x0060, 0xFFA0, 0x0064, 0xFF9C, 0x0068, 0xFF98, + 0x006C, 0xFF94, 0x0070, 0xFF90, 0x0074, 0xFF8C, 0xFF88, 0x0078, 0x007C, + 0xFF84, 0xFF80, 0x0080, 0x0088, 0xFF78, 0xFF7C, 0x0084, 0x008C, 0xFF74, + 0x0090, 0xFF70, 0x0094, 0xFF6C, 0xFF68, 0x0098, + /* Y_2 bias values - 98 entries */ + 0x0000, 0xFFFC, 0x0004, 0xFFF8, 0x0008, 0xFFF4, 0x000C, 0xFFF0, 0x0010, + 0xFFEC, 0x0014, 0xFFE8, 0x0018, 0xFFE4, 0x001C, 0xFFE0, 0x0020, 0xFFDC, + 0x0024, 0xFFD8, 0x0028, 0xFFD4, 0x002C, 0xFFD0, 0x0030, 0xFFCC, 0x0034, + 0xFFC8, 0x0038, 0x003C, 0xFFC4, 0x0040, 0xFFC0, 0xFFBC, 0x0044, 0x0048, + 0xFFB8, 0x004C, 0xFFB4, 0x0050, 0xFFB0, 0x0054, 0xFFAC, 0xFFA8, 0x0058, + 0x005C, 0xFFA4, 0x0060, 0xFFA0, 0x0064, 0xFF9C, 0xFF98, 0x0068, 0x006C, + 0xFF94, 0x0070, 0xFF90, 0x0074, 0xFF8C, 0xFF88, 0x0078, 0xFF84, 0x007C, + 0xFF80, 0x0080, 0xFF7C, 0x0084, BIAS_ESC, 0xFF78, 0x0088, 0x008C, 0xFF74, + 0x0090, 0xFF70, 0x0094, 0xFF6C, 0xFF64, 0x009C, 0xFF68, 0x0098, 0xFF60, + 0x00A0, 0xFF5C, 0x00A4, 0x00A8, 0xFF58, 0x00AC, 0xFF54, 0xFF50, 0x00B0, + 0x00B4, 0xFF4C, 0xFF48, 0x00B8, 0xFF44, 0x00BC, 0xFF40, 0x00C0, + /* Y_3 bias values - 94 entries */ + 0x0000, 0xFFFC, 0x0004, 0xFFF8, 0x0008, 0xFFF4, 0x000C, 0xFFF0, 0x0010, + 0xFFEC, 0x0014, 0xFFE8, 0x0018, 0xFFE4, 0x001C, 0xFFE0, 0x0020, 0xFFDC, + 0x0024, 0xFFD8, 0x0028, 0xFFD4, 0x002C, 0xFFD0, 0x0030, 0xFFCC, 0x0034, + 0xFFC8, 0x0038, 0xFFC4, 0x003C, 0xFFC0, 0x0040, 0x0044, 0xFFBC, 0x0048, + 0xFFB8, 0x004C, 0xFFB4, 0x0050, 0xFFB0, 0x0054, 0xFFAC, 0x0058, 0xFFA8, + 0x005C, 0xFFA4, 0xFFA0, 0x0060, 0x0064, 0xFF9C, 0x0068, 0xFF98, 0x006C, + 0xFF94, 0xFF90, 0x0070, 0xFF8C, 0x0074, 0x0078, 0xFF88, 0xFF84, 0x007C, + 0xFF80, 0x0080, 0x0084, 0xFF7C, 0x0088, 0xFF78, 0x008C, 0xFF74, 0xFF70, + 0x0090, 0x0094, 0xFF6C, 0x0098, 0xFF68, 0xFF64, 0x009C, 0xFF60, 0x00A0, + 0xFF5C, 0x00A4, BIAS_ESC, 0xFF58, 0x00A8, 0x00AC, 0xFF54, 0xFF50, 0x00B0, + 0xFF4C, 0x00B4, 0x00B8, 0xFF48, + /* U_1 bias values - 42 entries */ + 0x0000, 0xFFFC, 0x0004, 0xFFF8, 0x0008, 0xFFF4, 0x000C, 0xFFF0, 0x0010, + 0xFFEC, 0x0014, 0x0018, 0xFFE8, 0xFFE4, 0x001C, 0xFFE0, 0x0020, 0xFFDC, + 0x0024, 0xFFD8, 0x0028, 0x002C, 0xFFD4, 0x0030, 0xFFCC, 0xFFD0, 0x0034, + 0xFFC8, 0x0038, 0x003C, 0xFFC4, 0xFFC0, 0x0040, 0xFFBC, 0x0044, 0xFFB8, + 0x0048, 0xFFB4, 0x004C, 0x0050, 0xFFB0, BIAS_ESC, + /* U_2 bias values - 54 entries */ + 0x0000, 0xFFFC, 0x0004, 0xFFF8, 0x0008, 0xFFF4, 0x000C, 0xFFF0, 0x0010, + 0x0014, 0xFFEC, 0x0018, 0xFFE8, 0x001C, 0xFFE4, 0x0020, 0xFFE0, 0xFFDC, + 0x0024, 0xFFD8, 0x0028, 0xFFD4, 0x002C, 0x0030, 0xFFD0, 0x0034, 0xFFCC, + 0x0038, 0xFFC8, 0x003C, 0xFFC4, 0x0040, 0xFFC0, 0xFFBC, 0x0044, 0xFFB4, + 0xFFB8, 0x0048, 0x004C, BIAS_ESC, 0x0058, 0xFFB0, 0xFFA8, 0x0054, 0xFFAC, + 0x0050, 0xFF9C, 0x005C, 0xFFA0, 0x0068, 0xFF98, 0xFFA4, 0x0064, 0x0060, + /* V_1 bias values - 42 entries */ + 0x0000, 0xFFFC, 0x0004, 0xFFF8, 0x0008, 0xFFF4, 0x000C, 0xFFF0, 0x0010, + 0xFFEC, 0x0014, 0x0018, 0xFFE8, 0xFFE4, 0x001C, 0xFFE0, 0x0020, 0xFFDC, + 0x0024, 0xFFD8, 0x0028, 0x002C, 0xFFD4, 0x0030, 0xFFD0, 0xFFCC, 0x0034, + 0xFFC8, 0x0038, 0x003C, 0xFFC4, BIAS_ESC, 0xFFC0, 0x0040, 0xFFBC, 0x0044, + 0xFFB8, 0x0048, 0xFFB4, 0x004C, 0x0050, 0xFFB0, + /* V_2 bias values - 44 entries */ + 0x0000, 0xFFFC, 0x0004, 0xFFF8, 0x0008, 0xFFF4, 0x000C, 0xFFF0, 0x0010, + 0xFFEC, 0x0014, 0xFFE8, 0x0018, 0x001C, 0xFFE4, 0xFFE0, 0x0020, 0xFFDC, + 0x0024, 0x0028, 0xFFD8, 0x002C, 0xFFD4, 0x0030, 0xFFD0, 0xFFCC, 0x0034, + 0xFFC8, 0x0038, 0x0040, 0xFFC4, 0xFFC0, 0x003C, 0x0044, 0xFFBC, 0xFFB8, + 0x0048, 0xFFB4, 0x004C, BIAS_ESC, 0xFFB0, 0x0054, 0xFFAC, 0x0050 }; #endif /* AVCODEC_CLEARVIDEODATA_H */ diff --git a/libavcodec/cljrdec.c b/libavcodec/cljrdec.c index 4b187f8cf..c41df12d5 100644 --- a/libavcodec/cljrdec.c +++ b/libavcodec/cljrdec.c @@ -90,5 +90,6 @@ AVCodec ff_cljr_decoder = { .init = decode_init, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c index 1f2c98ef7..837e04f17 100644 --- a/libavcodec/cllc.c +++ b/libavcodec/cllc.c @@ -46,19 +46,15 @@ static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) { uint8_t symbols[256]; uint8_t bits[256]; - uint16_t codes[256]; - int num_lens, num_codes, num_codes_sum, prefix; + int num_lens, num_codes, num_codes_sum; int i, j, count; - prefix = 0; count = 0; num_codes_sum = 0; num_lens = get_bits(gb, 5); if (num_lens > VLC_BITS * VLC_DEPTH) { - vlc->table = NULL; - av_log(ctx->avctx, AV_LOG_ERROR, "To long VLCs %d\n", num_lens); return AVERROR_INVALIDDATA; } @@ -68,8 +64,6 @@ static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) num_codes_sum += num_codes; if (num_codes_sum > 256) { - vlc->table = NULL; - av_log(ctx->avctx, AV_LOG_ERROR, "Too many VLCs (%d) to be read.\n", num_codes_sum); return AVERROR_INVALIDDATA; @@ -78,20 +72,13 @@ static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) for (j = 0; j < num_codes; j++) { symbols[count] = get_bits(gb, 8); bits[count] = i + 1; - codes[count] = prefix++; count++; } - if (prefix > (65535 - 256)/2) { - vlc->table = NULL; - return AVERROR_INVALIDDATA; - } - - prefix <<= 1; } - return ff_init_vlc_sparse(vlc, VLC_BITS, count, bits, 1, 1, - codes, 2, 2, symbols, 1, 1, 0); + return ff_init_vlc_from_lengths(vlc, VLC_BITS, count, bits, 1, + symbols, 1, 1, 0, 0, ctx->avctx); } /* @@ -247,7 +234,7 @@ static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) for (i = 0; i < 4; i++) { ret = read_code_table(ctx, gb, &vlc[i]); if (ret < 0) { - for (j = 0; j <= i; j++) + for (j = 0; j < i; j++) ff_free_vlc(&vlc[j]); av_log(ctx->avctx, AV_LOG_ERROR, @@ -290,7 +277,7 @@ static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) for (i = 0; i < 3; i++) { ret = read_code_table(ctx, gb, &vlc[i]); if (ret < 0) { - for (j = 0; j <= i; j++) + for (j = 0; j < i; j++) ff_free_vlc(&vlc[j]); av_log(ctx->avctx, AV_LOG_ERROR, @@ -343,7 +330,7 @@ static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) for (i = 0; i < 2; i++) { ret = read_code_table(ctx, gb, &vlc[i]); if (ret < 0) { - for (j = 0; j <= i; j++) + for (j = 0; j < i; j++) ff_free_vlc(&vlc[j]); av_log(ctx->avctx, AV_LOG_ERROR, diff --git a/libavcodec/cngdec.c b/libavcodec/cngdec.c index 747ab49cd..ceee087c5 100644 --- a/libavcodec/cngdec.c +++ b/libavcodec/cngdec.c @@ -173,7 +173,7 @@ AVCodec ff_comfortnoise_decoder = { .close = cng_decode_close, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/cngenc.c b/libavcodec/cngenc.c index e185c4a40..b622d7bbd 100644 --- a/libavcodec/cngenc.c +++ b/libavcodec/cngenc.c @@ -37,8 +37,8 @@ static av_cold int cng_encode_close(AVCodecContext *avctx) { CNGContext *p = avctx->priv_data; ff_lpc_end(&p->lpc); - av_free(p->samples32); - av_free(p->ref_coef); + av_freep(&p->samples32); + av_freep(&p->ref_coef); return 0; } @@ -58,10 +58,8 @@ static av_cold int cng_encode_init(AVCodecContext *avctx) return ret; p->samples32 = av_malloc_array(avctx->frame_size, sizeof(*p->samples32)); p->ref_coef = av_malloc_array(p->order, sizeof(*p->ref_coef)); - if (!p->samples32 || !p->ref_coef) { - cng_encode_close(avctx); + if (!p->samples32 || !p->ref_coef) return AVERROR(ENOMEM); - } return 0; } @@ -113,4 +111,5 @@ AVCodec ff_comfortnoise_encoder = { .close = cng_encode_close, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/codec.h b/libavcodec/codec.h index 1fda619ee..50a22f6e3 100644 --- a/libavcodec/codec.h +++ b/libavcodec/codec.h @@ -43,9 +43,11 @@ */ #define AV_CODEC_CAP_DRAW_HORIZ_BAND (1 << 0) /** - * Codec uses get_buffer() for allocating buffers and supports custom allocators. - * If not set, it might not use get_buffer() at all or use operations that - * assume the buffer was allocated by avcodec_default_get_buffer. + * Codec uses get_buffer() or get_encode_buffer() for allocating buffers and + * supports custom allocators. + * If not set, it might not use get_buffer() or get_encode_buffer() at all, or + * use operations that assume the buffer was allocated by + * avcodec_default_get_buffer2 or avcodec_default_get_encode_buffer. */ #define AV_CODEC_CAP_DR1 (1 << 1) #define AV_CODEC_CAP_TRUNCATED (1 << 3) @@ -113,9 +115,14 @@ */ #define AV_CODEC_CAP_PARAM_CHANGE (1 << 14) /** - * Codec supports avctx->thread_count == 0 (auto). + * Codec supports multithreading through a method other than slice- or + * frame-level multithreading. Typically this marks wrappers around + * multithreading-capable external libraries. */ -#define AV_CODEC_CAP_AUTO_THREADS (1 << 15) +#define AV_CODEC_CAP_OTHER_THREADS (1 << 15) +#if FF_API_AUTO_THREADS +#define AV_CODEC_CAP_AUTO_THREADS AV_CODEC_CAP_OTHER_THREADS +#endif /** * Audio encoder supports receiving a different number of samples in each call. */ @@ -236,7 +243,9 @@ typedef struct AVCodec { ***************************************************************** */ int priv_data_size; +#if FF_API_NEXT struct AVCodec *next; +#endif /** * @name Frame-level threading support functions * @{ @@ -257,7 +266,7 @@ typedef struct AVCodec { const AVCodecDefault *defaults; /** - * Initialize codec static data, called from avcodec_register(). + * Initialize codec static data, called from av_codec_iterate(). * * This is not intended for time consuming operations as it is * run for every codec regardless of that codec being used. @@ -271,7 +280,7 @@ typedef struct AVCodec { * Encode data to an AVPacket. * * @param avctx codec context - * @param avpkt output AVPacket (may contain a user-provided buffer) + * @param avpkt output AVPacket * @param[in] frame AVFrame containing the raw data to be encoded * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a * non-empty packet was returned in avpkt. @@ -279,17 +288,26 @@ typedef struct AVCodec { */ int (*encode2)(struct AVCodecContext *avctx, struct AVPacket *avpkt, const struct AVFrame *frame, int *got_packet_ptr); - int (*decode)(struct AVCodecContext *, void *outdata, int *outdata_size, struct AVPacket *avpkt); + /** + * Decode picture or subtitle data. + * + * @param avctx codec context + * @param outdata codec type dependent output struct + * @param[out] got_frame_ptr decoder sets to 0 or 1 to indicate that a + * non-empty frame or subtitle was returned in + * outdata. + * @param[in] avpkt AVPacket containing the data to be decoded + * @return amount of bytes read from the packet on success, negative error + * code on failure + */ + int (*decode)(struct AVCodecContext *avctx, void *outdata, + int *got_frame_ptr, struct AVPacket *avpkt); int (*close)(struct AVCodecContext *); /** - * Encode API with decoupled packet/frame dataflow. The API is the - * same as the avcodec_ prefixed APIs (avcodec_send_frame() etc.), except - * that: - * - never called if the codec is closed or the wrong type, - * - if AV_CODEC_CAP_DELAY is not set, drain frames are never sent, - * - only one drain frame is ever passed down, + * Encode API with decoupled frame/packet dataflow. This function is called + * to get one output packet. It should call ff_encode_get_frame() to obtain + * input data. */ - int (*send_frame)(struct AVCodecContext *avctx, const struct AVFrame *frame); int (*receive_packet)(struct AVCodecContext *avctx, struct AVPacket *avpkt); /** @@ -322,7 +340,7 @@ typedef struct AVCodec { * * The user can only access this field via avcodec_get_hw_config(). */ - const struct AVCodecHWConfigInternal **hw_configs; + const struct AVCodecHWConfigInternal *const *hw_configs; /** * List of supported codec_tags, terminated by FF_CODEC_TAGS_END. diff --git a/libavcodec/codec2utils.c b/libavcodec/codec2utils.c index 931478f22..a94266240 100644 --- a/libavcodec/codec2utils.c +++ b/libavcodec/codec2utils.c @@ -23,6 +23,7 @@ #include "internal.h" #include "libavcodec/codec2utils.h" +#if LIBAVCODEC_VERSION_MAJOR < 59 int avpriv_codec2_mode_bit_rate(void *logctx, int mode) { int frame_size = avpriv_codec2_mode_frame_size(logctx, mode); @@ -37,7 +38,7 @@ int avpriv_codec2_mode_bit_rate(void *logctx, int mode) int avpriv_codec2_mode_frame_size(void *logctx, int mode) { - int frame_size_table[AVPRIV_CODEC2_MODE_MAX+1] = { + int frame_size_table[CODEC2_MODE_MAX+1] = { 160, // 3200 160, // 2400 320, // 1600 @@ -49,7 +50,7 @@ int avpriv_codec2_mode_frame_size(void *logctx, int mode) 320, // 700C }; - if (mode < 0 || mode > AVPRIV_CODEC2_MODE_MAX) { + if (mode < 0 || mode > CODEC2_MODE_MAX) { av_log(logctx, AV_LOG_ERROR, "unknown codec2 mode %i, can't find frame_size\n", mode); return 0; } else { @@ -59,7 +60,7 @@ int avpriv_codec2_mode_frame_size(void *logctx, int mode) int avpriv_codec2_mode_block_align(void *logctx, int mode) { - int block_align_table[AVPRIV_CODEC2_MODE_MAX+1] = { + int block_align_table[CODEC2_MODE_MAX+1] = { 8, // 3200 6, // 2400 8, // 1600 @@ -71,10 +72,11 @@ int avpriv_codec2_mode_block_align(void *logctx, int mode) 4, // 700C }; - if (mode < 0 || mode > AVPRIV_CODEC2_MODE_MAX) { + if (mode < 0 || mode > CODEC2_MODE_MAX) { av_log(logctx, AV_LOG_ERROR, "unknown codec2 mode %i, can't find block_align\n", mode); return 0; } else { return block_align_table[mode]; } } +#endif diff --git a/libavcodec/codec2utils.h b/libavcodec/codec2utils.h index 6def4d4aa..37f0693dc 100644 --- a/libavcodec/codec2utils.h +++ b/libavcodec/codec2utils.h @@ -24,17 +24,19 @@ #include +#include "version.h" + //Highest mode we're willing to use. //Don't want to let users accidentally produce files that can't be decoded in the future. //CODEC2_MODE_WB (9) is experimental/unstable as of 2017-11-23. -#define AVPRIV_CODEC2_MODE_MAX 8 //CODEC2_MODE_700C +#define CODEC2_MODE_MAX 8 //CODEC2_MODE_700C //Used by both codec2raw demuxer and libcodec2 encoder. //The integers match the values in codec2.h, so "3200" -> CODEC2_MODE_3000 = 0 and so on. //It is possible that we're linked to a version of libcodec2 that lacks some of these modes. //For example Debian stretch ships with libcodec2.so.0.4 which lacks CODEC2_MODE_700C. -#define AVPRIV_CODEC2_AVOPTIONS(desc, classname, min_val, default_val, option_flags) \ - { "mode", desc, offsetof(classname, mode), AV_OPT_TYPE_INT, {.i64 = default_val}, min_val, AVPRIV_CODEC2_MODE_MAX, .flags=option_flags, .unit="codec2_mode"},\ +#define CODEC2_AVOPTIONS(desc, classname, min_val, default_val, option_flags) \ + { "mode", desc, offsetof(classname, mode), AV_OPT_TYPE_INT, {.i64 = default_val}, min_val, CODEC2_MODE_MAX, .flags=option_flags, .unit="codec2_mode"},\ { "3200", "3200", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, .flags=option_flags, .unit="codec2_mode"},\ { "2400", "2400", 0, AV_OPT_TYPE_CONST, {.i64 = 1}, .flags=option_flags, .unit="codec2_mode"},\ { "1600", "1600", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, .flags=option_flags, .unit="codec2_mode"},\ @@ -45,6 +47,7 @@ { "700B", "700B", 0, AV_OPT_TYPE_CONST, {.i64 = 7}, .flags=option_flags, .unit="codec2_mode"},\ { "700C", "700C", 0, AV_OPT_TYPE_CONST, {.i64 = 8}, .flags=option_flags, .unit="codec2_mode"} +#if LIBAVCODEC_VERSION_MAJOR < 59 //The three following functions are here to avoid needing libavformat/codec2.c to depend on libcodec2 //Computes bitrate from mode, with frames rounded up to the nearest octet. @@ -58,11 +61,12 @@ int avpriv_codec2_mode_frame_size(void *logctx, int mode); //Mimics (codec2_bits_per_frame()+7)/8 int avpriv_codec2_mode_block_align(void *logctx, int mode); +#endif -#define AVPRIV_CODEC2_EXTRADATA_SIZE 4 +#define CODEC2_EXTRADATA_SIZE 4 //Used in codec2raw demuxer and libcodec2 encoder -static inline void avpriv_codec2_make_extradata(uint8_t *ptr, int mode) { +static inline void codec2_make_extradata(uint8_t *ptr, int mode) { //version 0.8 as of 2017-12-23 (r3386) ptr[0] = 0; //major ptr[1] = 8; //minor @@ -70,12 +74,7 @@ static inline void avpriv_codec2_make_extradata(uint8_t *ptr, int mode) { ptr[3] = 0; //flags } -//Returns version as a 16-bit value. 0.8 -> 0x0008 -static inline uint16_t avpriv_codec2_version_from_extradata(uint8_t *ptr) { - return (ptr[0] << 8) + ptr[1]; -} - -static inline uint8_t avpriv_codec2_mode_from_extradata(uint8_t *ptr) { +static inline uint8_t codec2_mode_from_extradata(uint8_t *ptr) { return ptr[2]; } diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 9f8847544..17f8a1404 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1405,6 +1405,35 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("AVS2-P2/IEEE1857.4"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_PGX, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pgx", + .long_name = NULL_IF_CONFIG_SMALL("PGX (JPEG2000 Test Format)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_AVS3, + .type = AVMEDIA_TYPE_VIDEO, + .name = "avs3", + .long_name = NULL_IF_CONFIG_SMALL("AVS3-P2/IEEE1857.10"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MSP2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "msp2", + .long_name = NULL_IF_CONFIG_SMALL("Microsoft Paint (MSP) version 2"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_VVC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vvc", + .long_name = NULL_IF_CONFIG_SMALL("H.266 / VVC (Versatile Video Coding)"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + .profiles = NULL_IF_CONFIG_SMALL(ff_vvc_profiles), + }, { .id = AV_CODEC_ID_Y41P, .type = AVMEDIA_TYPE_VIDEO, @@ -1498,6 +1527,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_SMVJPEG, .type = AVMEDIA_TYPE_VIDEO, .name = "smvjpeg", + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, .long_name = NULL_IF_CONFIG_SMALL("Sigmatel Motion Video"), }, { @@ -1519,7 +1549,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_CFHD, .type = AVMEDIA_TYPE_VIDEO, .name = "cfhd", - .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"), + .long_name = NULL_IF_CONFIG_SMALL("GoPro CineForm HD"), .props = AV_CODEC_PROP_LOSSY, }, { @@ -1777,6 +1807,55 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("PFM (Portable FloatMap) image"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_MOBICLIP, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mobiclip", + .long_name = NULL_IF_CONFIG_SMALL("MobiClip Video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PHOTOCD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "photocd", + .long_name = NULL_IF_CONFIG_SMALL("Kodak Photo CD"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_IPU, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ipu", + .long_name = NULL_IF_CONFIG_SMALL("IPU Video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ARGO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "argo", + .long_name = NULL_IF_CONFIG_SMALL("Argonaut Games Video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CRI, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cri", + .long_name = NULL_IF_CONFIG_SMALL("Cintel RAW"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SIMBIOSIS_IMX, + .type = AVMEDIA_TYPE_VIDEO, + .name = "simbiosis_imx", + .long_name = NULL_IF_CONFIG_SMALL("Simbiosis Interactive IMX Video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SGA_VIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "sga", + .long_name = NULL_IF_CONFIG_SMALL("Digital Pictures SGA Video"), + .props = AV_CODEC_PROP_LOSSY, + }, /* various PCM "codecs" */ { @@ -2024,6 +2103,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("PCM Archimedes VIDC"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_PCM_SGA, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_sga", + .long_name = NULL_IF_CONFIG_SMALL("PCM SGA"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, /* various ADPCM codecs */ { @@ -2369,6 +2455,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Cunning Developments"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_ADPCM_IMA_MOFLEX, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_moflex", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA MobiClip MOFLEX"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, /* AMR */ { @@ -2897,7 +2990,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "tak", .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), - .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_METASOUND, @@ -3116,6 +3209,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("CRI HCA"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_FASTAUDIO, + .type = AVMEDIA_TYPE_AUDIO, + .name = "fastaudio", + .long_name = NULL_IF_CONFIG_SMALL("MobiClip FastAudio"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, /* subtitle codecs */ { @@ -3374,6 +3474,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, + { + .id = AV_CODEC_ID_MPEG2TS, + .type = AVMEDIA_TYPE_DATA, + .name = "mpegts", + .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-TS stream"), + .mime_types= MT("application/MP2T"), + }, { .id = AV_CODEC_ID_WRAPPED_AVFRAME, .type = AVMEDIA_TYPE_VIDEO, diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h index d885962c9..ab7bc68ee 100644 --- a/libavcodec/codec_id.h +++ b/libavcodec/codec_id.h @@ -241,6 +241,11 @@ enum AVCodecID { AV_CODEC_ID_SCREENPRESSO, AV_CODEC_ID_RSCC, AV_CODEC_ID_AVS2, + AV_CODEC_ID_PGX, + AV_CODEC_ID_AVS3, + AV_CODEC_ID_MSP2, + AV_CODEC_ID_VVC, +#define AV_CODEC_ID_H266 AV_CODEC_ID_VVC AV_CODEC_ID_Y41P = 0x8000, AV_CODEC_ID_AVRP, @@ -295,6 +300,13 @@ enum AVCodecID { AV_CODEC_ID_MV30, AV_CODEC_ID_NOTCHLC, AV_CODEC_ID_PFM, + AV_CODEC_ID_MOBICLIP, + AV_CODEC_ID_PHOTOCD, + AV_CODEC_ID_IPU, + AV_CODEC_ID_ARGO, + AV_CODEC_ID_CRI, + AV_CODEC_ID_SIMBIOSIS_IMX, + AV_CODEC_ID_SGA_VIDEO, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs @@ -335,6 +347,7 @@ enum AVCodecID { AV_CODEC_ID_PCM_F16LE, AV_CODEC_ID_PCM_F24LE, AV_CODEC_ID_PCM_VIDC, + AV_CODEC_ID_PCM_SGA, /* various ADPCM codecs */ AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, @@ -387,6 +400,7 @@ enum AVCodecID { AV_CODEC_ID_ADPCM_IMA_ALP, AV_CODEC_ID_ADPCM_IMA_MTF, AV_CODEC_ID_ADPCM_IMA_CUNNING, + AV_CODEC_ID_ADPCM_IMA_MOFLEX, /* AMR */ AV_CODEC_ID_AMR_NB = 0x12000, @@ -502,6 +516,7 @@ enum AVCodecID { AV_CODEC_ID_MPEGH_3D_AUDIO, AV_CODEC_ID_SIREN, AV_CODEC_ID_HCA, + AV_CODEC_ID_FASTAUDIO, /* subtitle codecs */ AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. diff --git a/libavcodec/codec_par.c b/libavcodec/codec_par.c new file mode 100644 index 000000000..1a5168a04 --- /dev/null +++ b/libavcodec/codec_par.c @@ -0,0 +1,202 @@ +/* + * AVCodecParameters functions for libavcodec + * + * 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 + * AVCodecParameters functions for libavcodec. + */ + +#include +#include "libavutil/mem.h" +#include "avcodec.h" +#include "codec_par.h" + +static void codec_parameters_reset(AVCodecParameters *par) +{ + av_freep(&par->extradata); + + memset(par, 0, sizeof(*par)); + + par->codec_type = AVMEDIA_TYPE_UNKNOWN; + par->codec_id = AV_CODEC_ID_NONE; + par->format = -1; + par->field_order = AV_FIELD_UNKNOWN; + par->color_range = AVCOL_RANGE_UNSPECIFIED; + par->color_primaries = AVCOL_PRI_UNSPECIFIED; + par->color_trc = AVCOL_TRC_UNSPECIFIED; + par->color_space = AVCOL_SPC_UNSPECIFIED; + par->chroma_location = AVCHROMA_LOC_UNSPECIFIED; + par->sample_aspect_ratio = (AVRational){ 0, 1 }; + par->profile = FF_PROFILE_UNKNOWN; + par->level = FF_LEVEL_UNKNOWN; +} + +AVCodecParameters *avcodec_parameters_alloc(void) +{ + AVCodecParameters *par = av_mallocz(sizeof(*par)); + + if (!par) + return NULL; + codec_parameters_reset(par); + return par; +} + +void avcodec_parameters_free(AVCodecParameters **ppar) +{ + AVCodecParameters *par = *ppar; + + if (!par) + return; + codec_parameters_reset(par); + + av_freep(ppar); +} + +int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src) +{ + codec_parameters_reset(dst); + memcpy(dst, src, sizeof(*dst)); + + dst->extradata = NULL; + dst->extradata_size = 0; + if (src->extradata) { + dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!dst->extradata) + return AVERROR(ENOMEM); + memcpy(dst->extradata, src->extradata, src->extradata_size); + dst->extradata_size = src->extradata_size; + } + + return 0; +} + +int avcodec_parameters_from_context(AVCodecParameters *par, + const AVCodecContext *codec) +{ + codec_parameters_reset(par); + + par->codec_type = codec->codec_type; + par->codec_id = codec->codec_id; + par->codec_tag = codec->codec_tag; + + par->bit_rate = codec->bit_rate; + par->bits_per_coded_sample = codec->bits_per_coded_sample; + par->bits_per_raw_sample = codec->bits_per_raw_sample; + par->profile = codec->profile; + par->level = codec->level; + + switch (par->codec_type) { + case AVMEDIA_TYPE_VIDEO: + par->format = codec->pix_fmt; + par->width = codec->width; + par->height = codec->height; + par->field_order = codec->field_order; + par->color_range = codec->color_range; + par->color_primaries = codec->color_primaries; + par->color_trc = codec->color_trc; + par->color_space = codec->colorspace; + par->chroma_location = codec->chroma_sample_location; + par->sample_aspect_ratio = codec->sample_aspect_ratio; + par->video_delay = codec->has_b_frames; + break; + case AVMEDIA_TYPE_AUDIO: + par->format = codec->sample_fmt; + par->channel_layout = codec->channel_layout; + par->channels = codec->channels; + par->sample_rate = codec->sample_rate; + par->block_align = codec->block_align; + par->frame_size = codec->frame_size; + par->initial_padding = codec->initial_padding; + par->trailing_padding = codec->trailing_padding; + par->seek_preroll = codec->seek_preroll; + break; + case AVMEDIA_TYPE_SUBTITLE: + par->width = codec->width; + par->height = codec->height; + break; + } + + if (codec->extradata) { + par->extradata = av_mallocz(codec->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!par->extradata) + return AVERROR(ENOMEM); + memcpy(par->extradata, codec->extradata, codec->extradata_size); + par->extradata_size = codec->extradata_size; + } + + return 0; +} + +int avcodec_parameters_to_context(AVCodecContext *codec, + const AVCodecParameters *par) +{ + codec->codec_type = par->codec_type; + codec->codec_id = par->codec_id; + codec->codec_tag = par->codec_tag; + + codec->bit_rate = par->bit_rate; + codec->bits_per_coded_sample = par->bits_per_coded_sample; + codec->bits_per_raw_sample = par->bits_per_raw_sample; + codec->profile = par->profile; + codec->level = par->level; + + switch (par->codec_type) { + case AVMEDIA_TYPE_VIDEO: + codec->pix_fmt = par->format; + codec->width = par->width; + codec->height = par->height; + codec->field_order = par->field_order; + codec->color_range = par->color_range; + codec->color_primaries = par->color_primaries; + codec->color_trc = par->color_trc; + codec->colorspace = par->color_space; + codec->chroma_sample_location = par->chroma_location; + codec->sample_aspect_ratio = par->sample_aspect_ratio; + codec->has_b_frames = par->video_delay; + break; + case AVMEDIA_TYPE_AUDIO: + codec->sample_fmt = par->format; + codec->channel_layout = par->channel_layout; + codec->channels = par->channels; + codec->sample_rate = par->sample_rate; + codec->block_align = par->block_align; + codec->frame_size = par->frame_size; + codec->delay = + codec->initial_padding = par->initial_padding; + codec->trailing_padding = par->trailing_padding; + codec->seek_preroll = par->seek_preroll; + break; + case AVMEDIA_TYPE_SUBTITLE: + codec->width = par->width; + codec->height = par->height; + break; + } + + if (par->extradata) { + av_freep(&codec->extradata); + codec->extradata = av_mallocz(par->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!codec->extradata) + return AVERROR(ENOMEM); + memcpy(codec->extradata, par->extradata, par->extradata_size); + codec->extradata_size = par->extradata_size; + } + + return 0; +} diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 958249544..a9de3c8b1 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -44,6 +44,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/lfg.h" +#include "libavutil/mem_internal.h" #include "audiodsp.h" #include "avcodec.h" @@ -65,6 +66,9 @@ #define SUBBAND_SIZE 20 #define MAX_SUBPACKETS 5 +#define QUANT_VLC_BITS 9 +#define COUPLING_VLC_BITS 6 + typedef struct cook_gains { int *now; int *previous; @@ -190,6 +194,21 @@ static av_cold void init_gain_table(COOKContext *q) (1.0 / (double) q->gain_size_factor)); } +static av_cold int build_vlc(VLC *vlc, int nb_bits, const uint8_t counts[16], + const void *syms, int symbol_size, int offset, + void *logctx) +{ + uint8_t lens[MAX_COOK_VLC_ENTRIES]; + unsigned num = 0; + + for (int i = 0; i < 16; i++) + for (unsigned count = num + counts[i]; num < count; num++) + lens[num] = i + 1; + + return ff_init_vlc_from_lengths(vlc, nb_bits, num, lens, 1, + syms, symbol_size, symbol_size, + offset, 0, logctx); +} static av_cold int init_cook_vlc_tables(COOKContext *q) { @@ -197,23 +216,24 @@ static av_cold int init_cook_vlc_tables(COOKContext *q) result = 0; for (i = 0; i < 13; i++) { - result |= init_vlc(&q->envelope_quant_index[i], 9, 24, - envelope_quant_index_huffbits[i], 1, 1, - envelope_quant_index_huffcodes[i], 2, 2, 0); + result |= build_vlc(&q->envelope_quant_index[i], QUANT_VLC_BITS, + envelope_quant_index_huffcounts[i], + envelope_quant_index_huffsyms[i], 1, -12, q->avctx); } av_log(q->avctx, AV_LOG_DEBUG, "sqvh VLC init\n"); for (i = 0; i < 7; i++) { - result |= init_vlc(&q->sqvh[i], vhvlcsize_tab[i], vhsize_tab[i], - cvh_huffbits[i], 1, 1, - cvh_huffcodes[i], 2, 2, 0); + int sym_size = 1 + (i == 3); + result |= build_vlc(&q->sqvh[i], vhvlcsize_tab[i], + cvh_huffcounts[i], + cvh_huffsyms[i], sym_size, 0, q->avctx); } for (i = 0; i < q->num_subpackets; i++) { if (q->subpacket[i].joint_stereo == 1) { - result |= init_vlc(&q->subpacket[i].channel_coupling, 6, - (1 << q->subpacket[i].js_vlc_bits) - 1, - ccpl_huffbits[q->subpacket[i].js_vlc_bits - 2], 1, 1, - ccpl_huffcodes[q->subpacket[i].js_vlc_bits - 2], 2, 2, 0); + result |= build_vlc(&q->subpacket[i].channel_coupling, COUPLING_VLC_BITS, + ccpl_huffcounts[q->subpacket[i].js_vlc_bits - 2], + ccpl_huffsyms[q->subpacket[i].js_vlc_bits - 2], 1, + 0, q->avctx); av_log(q->avctx, AV_LOG_DEBUG, "subpacket %i Joint-stereo VLC used.\n", i); } } @@ -380,8 +400,8 @@ static int decode_envelope(COOKContext *q, COOKSubpacket *p, vlc_index = 13; // the VLC tables >13 are identical to No. 13 j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index - 1].table, - q->envelope_quant_index[vlc_index - 1].bits, 2); - quant_index_table[i] = quant_index_table[i - 1] + j - 12; // differential encoding + QUANT_VLC_BITS, 2); + quant_index_table[i] = quant_index_table[i - 1] + j; // differential encoding if (quant_index_table[i] > 63 || quant_index_table[i] < -63) { av_log(q->avctx, AV_LOG_ERROR, "Invalid quantizer %d at position %d, outside [-63, 63] range\n", @@ -759,7 +779,7 @@ static int decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab) for (i = 0; i < length; i++) decouple_tab[start + i] = get_vlc2(&q->gb, p->channel_coupling.table, - p->channel_coupling.bits, 3); + COUPLING_VLC_BITS, 3); else for (i = 0; i < length; i++) { int v = get_bits(&q->gb, p->js_vlc_bits); diff --git a/libavcodec/cookdata.h b/libavcodec/cookdata.h index efb8a5394..a4ca1201b 100644 --- a/libavcodec/cookdata.h +++ b/libavcodec/cookdata.h @@ -70,436 +70,216 @@ static const int vpr_tab[7] = { /* VLC data */ -static const int vhsize_tab[7] = { - 191, 97, 48, 607, 246, 230, 32, -}; +#define MAX_COOK_VLC_ENTRIES 520 static const int vhvlcsize_tab[7] = { 8, 7, 7, 10, 9, 9, 6, }; -static const uint8_t envelope_quant_index_huffbits[13][24] = { - { 4, 6, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 5, 7, 8, 9, 11, 11, 12, 12, 12, 12 }, - { 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 7, 9, 11, 12, 13, 15, 15, 15, 16, 16 }, - { 12, 10, 8, 6, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 4, 5, 5, 7, 9, 11, 13, 14, 14 }, - { 13, 10, 9, 9, 7, 7, 5, 5, 4, 3, 3, 3, 3, 3, 4, 4, 4, 5, 7, 9, 11, 13, 13, 13 }, - { 12, 13, 10, 8, 6, 6, 5, 5, 4, 4, 3, 3, 3, 3, 3, 4, 5, 5, 6, 7, 9, 11, 14, 14 }, - { 12, 11, 9, 8, 8, 7, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 5, 7, 8, 10, 13, 14, 14 }, - { 15, 16, 15, 12, 10, 8, 6, 5, 4, 3, 3, 3, 2, 3, 4, 5, 5, 7, 9, 11, 13, 16, 16, 16 }, - { 14, 14, 11, 10, 9, 7, 7, 5, 5, 4, 3, 3, 2, 3, 3, 4, 5, 7, 9, 9, 12, 14, 15, 15 }, - { 9, 9, 9, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 13 }, - { 14, 12, 10, 8, 6, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 8, 8, 9, 11, 14, 14, 14 }, - { 13, 10, 9, 8, 6, 6, 5, 4, 4, 4, 3, 3, 2, 3, 4, 5, 6, 8, 9, 9, 11, 12, 14, 14 }, - { 16, 13, 12, 11, 9, 6, 5, 5, 4, 4, 4, 3, 2, 3, 3, 4, 5, 7, 8, 10, 14, 16, 16, 16 }, - { 13, 14, 14, 14, 10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9, 11, 14, 14, 14 }, +static const uint8_t envelope_quant_index_huffcounts[13][16] = { + { 0, 0, 3, 8, 3, 1, 1, 1, 1, 0, 2, 4, 0, 0, 0, 0 }, + { 0, 0, 6, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 2 }, + { 0, 0, 3, 8, 3, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0 }, + { 0, 0, 5, 4, 3, 0, 3, 0, 3, 1, 1, 0, 4, 0, 0, 0 }, + { 0, 0, 5, 3, 4, 3, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0 }, + { 0, 0, 5, 4, 3, 0, 2, 3, 1, 1, 1, 1, 1, 2, 0, 0 }, + { 0, 1, 4, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 4 }, + { 0, 1, 4, 2, 3, 0, 3, 0, 3, 1, 1, 1, 0, 3, 2, 0 }, + { 0, 0, 6, 2, 2, 2, 2, 2, 3, 1, 1, 1, 2, 0, 0, 0 }, + { 0, 0, 6, 2, 2, 3, 0, 3, 1, 1, 1, 1, 0, 4, 0, 0 }, + { 0, 1, 3, 4, 2, 3, 0, 2, 3, 1, 1, 1, 1, 2, 0, 0 }, + { 0, 1, 3, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4 }, + { 0, 1, 4, 2, 3, 0, 3, 1, 1, 1, 1, 0, 1, 6, 0, 0 }, }; -static const uint16_t envelope_quant_index_huffcodes[13][24] = { - {0x0006, 0x003e, 0x001c, 0x001d, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x0000, 0x0001, - 0x0002, 0x000d, 0x001e, 0x007e, 0x00fe, 0x01fe, 0x07fc, 0x07fd, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff}, - {0x03fe, 0x00fe, 0x003e, 0x001c, 0x001d, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x000d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x0ffe, 0x1ffe, 0x7ffc, 0x7ffd, 0x7ffe, 0xfffe, 0xffff}, - {0x0ffe, 0x03fe, 0x00fe, 0x003e, 0x001c, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x0000, - 0x0001, 0x0002, 0x000c, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffe, 0x3ffe, 0x3fff}, - {0x1ffc, 0x03fe, 0x01fc, 0x01fd, 0x007c, 0x007d, 0x001c, 0x001d, 0x000a, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x000b, 0x000c, 0x000d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffd, 0x1ffe, 0x1fff}, - {0x0ffe, 0x1ffe, 0x03fe, 0x00fe, 0x003c, 0x003d, 0x001a, 0x001b, 0x000a, 0x000b, 0x0000, 0x0001, - 0x0002, 0x0003, 0x0004, 0x000c, 0x001c, 0x001d, 0x003e, 0x007e, 0x01fe, 0x07fe, 0x3ffe, 0x3fff}, - {0x0ffe, 0x07fe, 0x01fe, 0x00fc, 0x00fd, 0x007c, 0x001c, 0x000a, 0x000b, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x000c, 0x000d, 0x001d, 0x001e, 0x007d, 0x00fe, 0x03fe, 0x1ffe, 0x3ffe, 0x3fff}, - {0x7ffc, 0xfffc, 0x7ffd, 0x0ffe, 0x03fe, 0x00fe, 0x003e, 0x001c, 0x000c, 0x0002, 0x0003, 0x0004, - 0x0000, 0x0005, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffe, 0xfffd, 0xfffe, 0xffff}, - {0x3ffc, 0x3ffd, 0x07fe, 0x03fe, 0x01fc, 0x007c, 0x007d, 0x001c, 0x001d, 0x000c, 0x0002, 0x0003, - 0x0000, 0x0004, 0x0005, 0x000d, 0x001e, 0x007e, 0x01fd, 0x01fe, 0x0ffe, 0x3ffe, 0x7ffe, 0x7fff}, - {0x01fc, 0x01fd, 0x01fe, 0x00fc, 0x007c, 0x003c, 0x001c, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, - 0x0004, 0x0005, 0x000d, 0x001d, 0x003d, 0x007d, 0x00fd, 0x03fe, 0x07fe, 0x0ffe, 0x1ffe, 0x1fff}, - {0x3ffc, 0x0ffe, 0x03fe, 0x00fc, 0x003c, 0x003d, 0x001c, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, - 0x0004, 0x0005, 0x000d, 0x001d, 0x003e, 0x00fd, 0x00fe, 0x01fe, 0x07fe, 0x3ffd, 0x3ffe, 0x3fff}, - {0x1ffe, 0x03fe, 0x01fc, 0x00fc, 0x003c, 0x003d, 0x001c, 0x000a, 0x000b, 0x000c, 0x0002, 0x0003, - 0x0000, 0x0004, 0x000d, 0x001d, 0x003e, 0x00fd, 0x01fd, 0x01fe, 0x07fe, 0x0ffe, 0x3ffe, 0x3fff}, - {0xfffc, 0x1ffe, 0x0ffe, 0x07fe, 0x01fe, 0x003e, 0x001c, 0x001d, 0x000a, 0x000b, 0x000c, 0x0002, - 0x0000, 0x0003, 0x0004, 0x000d, 0x001e, 0x007e, 0x00fe, 0x03fe, 0x3ffe, 0xfffd, 0xfffe, 0xffff}, - {0x1ffc, 0x3ffa, 0x3ffb, 0x3ffc, 0x03fe, 0x00fe, 0x007c, 0x007d, 0x001c, 0x000c, 0x0002, 0x0003, - 0x0000, 0x0004, 0x0005, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x3ffd, 0x3ffe, 0x3fff}, +static const uint8_t envelope_quant_index_huffsyms[13][24] = { + { 10, 11, 12, 0, 4, 5, 6, 7, 8, 9, 13, 2, + 3, 14, 1, 15, 16, 17, 18, 19, 20, 21, 22, 23 }, + { 6, 7, 8, 9, 10, 11, 5, 12, 3, 4, 13, 2, + 14, 1, 15, 0, 16, 17, 18, 19, 20, 21, 22, 23 }, + { 11, 12, 13, 5, 6, 7, 8, 9, 10, 14, 15, 4, + 16, 17, 3, 18, 2, 19, 1, 20, 0, 21, 22, 23 }, + { 9, 10, 11, 12, 13, 8, 14, 15, 16, 6, 7, 17, + 4, 5, 18, 2, 3, 19, 1, 20, 0, 21, 22, 23 }, + { 10, 11, 12, 13, 14, 8, 9, 15, 6, 7, 16, 17, + 4, 5, 18, 19, 3, 20, 2, 21, 0, 1, 22, 23 }, + { 9, 10, 11, 12, 13, 7, 8, 14, 15, 6, 16, 17, + 5, 18, 3, 4, 19, 2, 20, 1, 0, 21, 22, 23 }, + { 12, 9, 10, 11, 13, 8, 14, 7, 15, 16, 6, 17, + 5, 18, 4, 19, 3, 20, 0, 2, 1, 21, 22, 23 }, + { 12, 10, 11, 13, 14, 9, 15, 7, 8, 16, 5, 6, + 17, 4, 18, 19, 3, 2, 20, 0, 1, 21, 22, 23 }, + { 8, 9, 10, 11, 12, 13, 7, 14, 6, 15, 5, 16, + 4, 17, 3, 18, 0, 1, 2, 19, 20, 21, 22, 23 }, + { 8, 9, 10, 11, 12, 13, 7, 14, 6, 15, 4, 5, + 16, 3, 17, 18, 19, 2, 20, 1, 0, 21, 22, 23 }, + { 12, 10, 11, 13, 7, 8, 9, 14, 6, 15, 4, 5, + 16, 3, 17, 2, 18, 19, 1, 20, 21, 0, 22, 23 }, + { 12, 11, 13, 14, 8, 9, 10, 15, 6, 7, 16, 5, + 17, 18, 4, 19, 3, 2, 1, 20, 0, 21, 22, 23 }, + { 12, 10, 11, 13, 14, 9, 15, 8, 16, 17, 6, 7, + 18, 5, 19, 4, 20, 0, 1, 2, 3, 21, 22, 23 }, }; -static const uint8_t cvh_huffbits0[191] = { - 1, 4, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, - 11, 11, 4, 5, 6, 7, 7, 8, 8, 9, 9, 9, - 9, 10, 11, 11, 5, 6, 7, 8, 8, 9, 9, 9, - 9, 10, 10, 10, 11, 12, 6, 7, 8, 9, 9, 9, - 9, 10, 10, 10, 10, 11, 12, 13, 7, 7, 8, 9, - 9, 9, 10, 10, 10, 10, 11, 11, 12, 13, 8, 8, - 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 13, 14, - 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, - 13, 15, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, - 12, 13, 14, 15, 9, 9, 9, 10, 10, 10, 11, 11, - 12, 13, 12, 14, 15, 16, 9, 9, 10, 10, 10, 10, - 11, 12, 12, 14, 14, 16, 16, 0, 9, 9, 10, 10, - 11, 11, 12, 13, 13, 14, 14, 15, 0, 0, 10, 10, - 10, 11, 11, 12, 12, 13, 15, 15, 16, 0, 0, 0, - 11, 11, 11, 12, 13, 13, 13, 15, 16, 16, 0, 0, - 0, 0, 11, 11, 12, 13, 13, 14, 15, 16, 16, +static const uint8_t cvh_huffcounts[7][16] = { + { 1, 0, 0, 2, 2, 5, 8, 15, 31, 33, 28, 17, 15, 8, 8, 8 }, + { 1, 0, 0, 2, 4, 5, 7, 16, 18, 12, 11, 7, 3, 5, 1, 2 }, + { 1, 0, 1, 2, 4, 2, 5, 8, 7, 8, 2, 3, 1, 1, 1, 2 }, + { 0, 1, 0, 2, 5, 12, 7, 27, 22, 41, 32, 41, 55, 23, 32, 220 }, + { 0, 1, 0, 5, 7, 4, 8, 9, 17, 10, 13, 17, 12, 14, 92, 0 }, + { 0, 1, 0, 5, 6, 8, 8, 8, 4, 7, 11, 23, 21, 10, 80, 0 }, + { 1, 0, 0, 5, 0, 9, 1, 7, 4, 3, 2, 0, 0, 0, 0, 0 }, }; -static const uint16_t cvh_huffcodes0[191] = { - 0x0000,0x0008,0x002c,0x002d,0x0062,0x0063,0x00d4,0x00d5,0x00d6,0x01c6,0x01c7,0x03ca, - 0x07d6,0x07d7,0x0009,0x0014,0x002e,0x0064,0x0065,0x00d7,0x00d8,0x01c8,0x01c9,0x01ca, - 0x01cb,0x03cb,0x07d8,0x07d9,0x0015,0x002f,0x0066,0x00d9,0x00da,0x01cc,0x01cd,0x01ce, - 0x01cf,0x03cc,0x03cd,0x03ce,0x07da,0x0fe4,0x0030,0x0067,0x00db,0x01d0,0x01d1,0x01d2, - 0x01d3,0x03cf,0x03d0,0x03d1,0x03d2,0x07db,0x0fe5,0x1fea,0x0068,0x0069,0x00dc,0x01d4, - 0x01d5,0x01d6,0x03d3,0x03d4,0x03d5,0x03d6,0x07dc,0x07dd,0x0fe6,0x1feb,0x00dd,0x00de, - 0x01d7,0x01d8,0x01d9,0x03d7,0x03d8,0x03d9,0x03da,0x07de,0x07df,0x0fe7,0x1fec,0x3ff2, - 0x00df,0x00e0,0x01da,0x01db,0x03db,0x03dc,0x07e0,0x07e1,0x07e2,0x0fe8,0x0fe9,0x1fed, - 0x1fee,0x7ff4,0x00e1,0x00e2,0x01dc,0x01dd,0x03dd,0x03de,0x07e3,0x07e4,0x07e5,0x0fea, - 0x0feb,0x1fef,0x3ff3,0x7ff5,0x01de,0x01df,0x01e0,0x03df,0x03e0,0x03e1,0x07e6,0x07e7, - 0x0fec,0x1ff0,0x0fed,0x3ff4,0x7ff6,0xfff8,0x01e1,0x01e2,0x03e2,0x03e3,0x03e4,0x03e5, - 0x07e8,0x0fee,0x0fef,0x3ff5,0x3ff6,0xfff9,0xfffa,0xfffa,0x01e3,0x01e4,0x03e6,0x03e7, - 0x07e9,0x07ea,0x0ff0,0x1ff1,0x1ff2,0x3ff7,0x3ff8,0x7ff7,0x7ff7,0xfffa,0x03e8,0x03e9, - 0x03ea,0x07eb,0x07ec,0x0ff1,0x0ff2,0x1ff3,0x7ff8,0x7ff9,0xfffb,0x3ff8,0x7ff7,0x7ff7, - 0x07ed,0x07ee,0x07ef,0x0ff3,0x1ff4,0x1ff5,0x1ff6,0x7ffa,0xfffc,0xfffd,0xfffb,0xfffb, - 0x3ff8,0x7ff7,0x07f0,0x07f1,0x0ff4,0x1ff7,0x1ff8,0x3ff9,0x7ffb,0xfffe,0xffff, +static const uint8_t cvh_huffsyms0[181] = { + 0, 1, 14, 15, 28, 2, 3, 16, 29, 42, 4, 5, 17, 18, 30, + 43, 56, 57, 6, 7, 8, 19, 20, 31, 32, 44, 58, 70, 71, 84, + 85, 98, 99, 9, 10, 21, 22, 23, 24, 33, 34, 35, 36, 45, 46, + 47, 48, 59, 60, 61, 72, 73, 74, 86, 87, 100, 101, 112, 113, 114, + 126, 127, 140, 141, 11, 25, 37, 38, 39, 49, 50, 51, 52, 62, 63, + 64, 65, 75, 76, 77, 78, 88, 89, 102, 103, 115, 116, 117, 128, 129, + 130, 131, 142, 143, 154, 155, 156, 12, 13, 26, 27, 40, 53, 66, 67, + 79, 80, 90, 91, 92, 104, 105, 106, 118, 119, 132, 144, 145, 157, 158, + 168, 169, 170, 182, 183, 41, 54, 68, 81, 93, 94, 107, 108, 120, 122, + 133, 134, 146, 159, 160, 171, 184, 55, 69, 82, 95, 96, 109, 121, 147, + 148, 161, 172, 173, 174, 185, 186, 83, 110, 123, 135, 136, 149, 150, 187, + 97, 111, 124, 151, 162, 163, 175, 188, 125, 137, 138, 164, 176, 177, 189, + 190, }; - -static const uint8_t cvh_huffbits1[97] = { - 1, 4, 5, 6, 7, 8, 8, 9, 10, 10, 4, 5, - 6, 7, 7, 8, 8, 9, 9, 11, 5, 5, 6, 7, - 8, 8, 9, 9, 10, 11, 6, 6, 7, 8, 8, 9, - 9, 10, 11, 12, 7, 7, 8, 8, 9, 9, 10, 11, - 11, 13, 8, 8, 8, 9, 9, 10, 10, 11, 12, 14, - 8, 8, 8, 9, 10, 11, 11, 12, 13, 15, 9, 9, - 9, 10, 11, 12, 12, 14, 14, 0, 9, 9, 9, 10, - 11, 12, 14, 16, 0, 0, 10, 10, 11, 12, 13, 14, - 16, +static const uint8_t cvh_huffsyms1[94] = { + 0, 1, 10, 2, 11, 20, 21, 3, 12, 22, 30, 31, 4, 13, 14, 23, 32, 40, 41, + 5, 6, 15, 16, 24, 25, 33, 34, 42, 43, 50, 51, 52, 60, 61, 62, 7, 17, 18, + 26, 27, 35, 36, 44, 45, 53, 54, 63, 70, 71, 72, 80, 81, 82, 8, 9, 28, 37, + 46, 55, 56, 64, 73, 83, 90, 91, 19, 29, 38, 47, 48, 57, 65, 66, 74, 84, 92, + 39, 58, 67, 75, 76, 85, 93, 49, 68, 94, 59, 77, 78, 86, 95, 69, 87, 96, }; - -static const uint16_t cvh_huffcodes1[97] = { - 0x0000,0x0008,0x0014,0x0030,0x006a,0x00e2,0x00e3,0x01e4,0x03ec,0x03ed,0x0009,0x0015, - 0x0031,0x006b,0x006c,0x00e4,0x00e5,0x01e5,0x01e6,0x07f0,0x0016,0x0017,0x0032,0x006d, - 0x00e6,0x00e7,0x01e7,0x01e8,0x03ee,0x07f1,0x0033,0x0034,0x006e,0x00e8,0x00e9,0x01e9, - 0x01ea,0x03ef,0x07f2,0x0ff6,0x006f,0x0070,0x00ea,0x00eb,0x01eb,0x01ec,0x03f0,0x07f3, - 0x07f4,0x1ffa,0x00ec,0x00ed,0x00ee,0x01ed,0x01ee,0x03f1,0x03f2,0x07f5,0x0ff7,0x3ffa, - 0x00ef,0x00f0,0x00f1,0x01ef,0x03f3,0x07f6,0x07f7,0x0ff8,0x1ffb,0x7ffe,0x01f0,0x01f1, - 0x01f2,0x03f4,0x07f8,0x0ff9,0x0ffa,0x3ffb,0x3ffc,0x0000,0x01f3,0x01f4,0x01f5,0x03f5, - 0x07f9,0x0ffb,0x3ffd,0xfffe,0x0000,0x0000,0x03f6,0x03f7,0x07fa,0x0ffc,0x1ffc,0x3ffe, - 0xffff, +static const uint8_t cvh_huffsyms2[48] = { + 0, 7, 1, 8, 2, 9, 14, 15, 16, 22, 3, 10, 17, 21, 23, 4, 11, 18, 24, + 28, 29, 30, 35, 5, 12, 25, 31, 36, 37, 42, 6, 13, 19, 20, 26, 32, 38, 43, + 39, 44, 27, 33, 45, 46, 34, 40, 41, 47, }; -static const uint8_t cvh_huffbits2[48] = { - 1, 4, 5, 7, 8, 9, 10, 3, 4, 5, 7, 8, - 9, 10, 5, 5, 6, 7, 8, 10, 10, 7, 6, 7, - 8, 9, 10, 12, 8, 8, 8, 9, 10, 12, 14, 8, - 9, 9, 10, 11, 15, 16, 9, 10, 11, 12, 13, 16, +static const uint16_t cvh_huffsyms3[520] = { + 0, 1, 125, 5, 6, 25, 30, 150, 2, 7, 26, 31, 126, 130, 131, + 151, 155, 156, 250, 275, 10, 35, 36, 50, 55, 175, 180, 3, 8, 11, + 12, 27, 32, 37, 56, 127, 132, 136, 152, 157, 160, 161, 176, 181, 251, + 255, 256, 276, 280, 281, 300, 305, 375, 400, 15, 16, 40, 41, 51, 60, + 61, 75, 80, 135, 162, 177, 185, 186, 200, 205, 301, 306, 405, 425, 500, + 525, 4, 9, 13, 17, 20, 28, 33, 38, 42, 52, 57, 81, 85, 128, + 133, 137, 140, 141, 158, 165, 166, 182, 187, 191, 206, 210, 257, 261, 277, + 282, 285, 286, 310, 311, 325, 330, 376, 380, 401, 406, 430, 21, 29, 46, + 62, 65, 66, 76, 86, 100, 105, 142, 153, 163, 190, 201, 211, 225, 230, + 252, 260, 262, 287, 302, 307, 381, 402, 426, 431, 450, 455, 505, 550, 14, + 18, 34, 43, 45, 53, 58, 67, 70, 71, 77, 87, 138, 146, 167, 168, + 171, 178, 183, 192, 207, 216, 235, 258, 265, 283, 291, 312, 315, 316, 326, + 331, 332, 335, 336, 350, 407, 410, 411, 530, 555, 22, 39, 47, 59, 63, + 82, 90, 91, 101, 106, 110, 111, 129, 134, 145, 154, 159, 170, 172, 188, + 195, 196, 202, 212, 215, 226, 231, 236, 253, 263, 266, 267, 278, 288, 290, + 292, 303, 317, 337, 355, 356, 377, 382, 385, 386, 432, 436, 451, 456, 460, + 501, 506, 526, 531, 551, 68, 72, 115, 147, 164, 184, 272, 295, 296, 297, + 309, 333, 340, 360, 387, 416, 427, 435, 437, 480, 510, 532, 556, 19, 44, + 54, 83, 97, 104, 107, 143, 173, 193, 208, 237, 268, 313, 320, 327, 341, + 351, 352, 378, 403, 412, 441, 442, 457, 475, 511, 515, 527, 528, 536, 552, + 23, 24, 48, 49, 64, 69, 73, 78, 79, 84, 88, 89, 92, 93, 94, + 95, 96, 98, 102, 103, 108, 109, 112, 113, 116, 117, 118, 120, 121, 139, + 144, 148, 149, 169, 174, 179, 189, 194, 197, 198, 203, 204, 209, 213, 214, + 217, 218, 219, 220, 221, 222, 223, 227, 228, 229, 232, 233, 234, 238, 240, + 241, 242, 243, 245, 246, 254, 259, 264, 269, 270, 271, 273, 279, 284, 289, + 293, 294, 298, 304, 308, 314, 318, 319, 321, 322, 323, 328, 329, 334, 338, + 339, 342, 343, 345, 346, 347, 353, 357, 358, 361, 362, 363, 365, 366, 367, + 379, 383, 384, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 404, + 408, 409, 413, 414, 415, 417, 418, 419, 420, 421, 422, 423, 428, 429, 433, + 434, 438, 439, 440, 443, 445, 446, 447, 452, 453, 454, 458, 459, 461, 462, + 463, 465, 466, 467, 468, 470, 471, 476, 477, 478, 481, 482, 483, 485, 486, + 487, 490, 491, 502, 503, 504, 507, 508, 509, 512, 513, 516, 517, 518, 520, + 521, 529, 533, 534, 535, 537, 538, 540, 541, 542, 543, 545, 546, 553, 557, + 558, 560, 561, 562, 563, 565, 566, 567, 575, 576, 577, 578, 580, 581, 582, + 583, 585, 586, 587, 590, 591, 600, 601, 605, 606, }; -static const uint16_t cvh_huffcodes2[48] = { - 0x0000,0x000a,0x0018,0x0074,0x00f2,0x01f4,0x03f6,0x0004,0x000b,0x0019,0x0075,0x00f3, - 0x01f5,0x03f7,0x001a,0x001b,0x0038,0x0076,0x00f4,0x03f8,0x03f9,0x0077,0x0039,0x0078, - 0x00f5,0x01f6,0x03fa,0x0ffc,0x00f6,0x00f7,0x00f8,0x01f7,0x03fb,0x0ffd,0x3ffe,0x00f9, - 0x01f8,0x01f9,0x03fc,0x07fc,0x7ffe,0xfffe,0x01fa,0x03fd,0x07fd,0x0ffe,0x1ffe,0xffff, +static const uint8_t cvh_huffsyms4[209] = { + 0, 1, 4, 16, 64, 80, 5, 17, 20, 21, 65, 68, 84, 69, 81, + 85, 128, 2, 6, 8, 25, 32, 96, 100, 144, 9, 22, 24, 36, 37, + 89, 101, 132, 148, 18, 33, 66, 70, 72, 73, 82, 86, 88, 97, 129, + 133, 145, 149, 160, 164, 192, 3, 7, 10, 26, 40, 41, 104, 105, 112, + 208, 12, 13, 28, 29, 48, 52, 74, 90, 102, 116, 152, 161, 165, 19, + 23, 34, 38, 83, 93, 98, 113, 134, 136, 137, 150, 153, 193, 196, 209, + 212, 42, 49, 53, 67, 71, 77, 87, 92, 117, 130, 146, 197, 11, 44, + 45, 56, 76, 106, 108, 131, 168, 169, 176, 180, 213, 224, 14, 15, 27, + 30, 31, 35, 39, 43, 46, 50, 51, 54, 55, 57, 58, 60, 61, 75, + 78, 79, 91, 94, 95, 99, 103, 107, 109, 110, 114, 115, 118, 119, 120, + 121, 122, 124, 125, 135, 138, 139, 140, 141, 142, 147, 151, 154, 155, 156, + 157, 158, 162, 163, 166, 167, 170, 172, 173, 177, 178, 181, 182, 184, 185, + 194, 195, 198, 199, 200, 201, 202, 204, 205, 210, 211, 214, 215, 216, 217, + 218, 220, 221, 225, 226, 228, 229, 230, 232, 233, 240, 241, 244, 245, }; -static const uint8_t cvh_huffbits3[607] = { - 2, 4, 6, 8, 10, 5, 5, 6, 8, 10, 7, 8, - 8, 10, 12, 9, 9, 10, 12, 15, 10, 11, 13, 16, - 16, 5, 6, 8, 10, 11, 5, 6, 8, 10, 12, 7, - 7, 8, 10, 13, 9, 9, 10, 12, 15, 12, 11, 13, - 16, 16, 7, 9, 10, 12, 15, 7, 8, 10, 12, 13, - 9, 9, 11, 13, 16, 11, 11, 12, 14, 16, 12, 12, - 14, 16, 0, 9, 11, 12, 16, 16, 9, 10, 13, 15, - 16, 10, 11, 12, 16, 16, 13, 13, 16, 16, 16, 16, - 16, 15, 16, 0, 11, 13, 16, 16, 15, 11, 13, 15, - 16, 16, 13, 13, 16, 16, 0, 14, 16, 16, 16, 0, - 16, 16, 0, 0, 0, 4, 6, 8, 10, 13, 6, 6, - 8, 10, 13, 9, 8, 10, 12, 16, 10, 10, 11, 15, - 16, 13, 12, 14, 16, 16, 5, 6, 8, 11, 13, 6, - 6, 8, 10, 13, 8, 8, 9, 11, 14, 10, 10, 12, - 12, 16, 13, 12, 13, 15, 16, 7, 8, 9, 12, 16, - 7, 8, 10, 12, 14, 9, 9, 10, 13, 16, 11, 10, - 12, 15, 16, 13, 13, 16, 16, 0, 9, 11, 13, 16, - 16, 9, 10, 12, 15, 16, 10, 11, 13, 16, 16, 13, - 12, 16, 16, 16, 16, 16, 16, 16, 0, 11, 13, 16, - 16, 16, 11, 13, 16, 16, 16, 12, 13, 15, 16, 0, - 16, 16, 16, 16, 0, 16, 16, 0, 0, 0, 6, 8, - 11, 13, 16, 8, 8, 10, 12, 16, 11, 10, 11, 13, - 16, 12, 13, 13, 15, 16, 16, 16, 14, 16, 0, 6, - 8, 10, 13, 16, 8, 8, 10, 12, 16, 10, 10, 11, - 13, 16, 13, 12, 13, 16, 16, 14, 14, 14, 16, 0, - 8, 9, 11, 13, 16, 8, 9, 11, 16, 14, 10, 10, - 12, 15, 16, 12, 12, 13, 16, 16, 15, 16, 16, 16, - 0, 10, 12, 15, 16, 16, 10, 12, 12, 14, 16, 12, - 12, 13, 16, 16, 14, 15, 16, 16, 0, 16, 16, 16, - 0, 0, 12, 15, 15, 16, 0, 13, 13, 16, 16, 0, - 14, 16, 16, 16, 0, 16, 16, 16, 0, 0, 0, 0, - 0, 0, 0, 8, 10, 13, 15, 16, 10, 11, 13, 16, - 16, 13, 13, 14, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 0, 8, 10, 11, 15, 16, 9, 10, 12, - 16, 16, 12, 12, 15, 16, 16, 16, 14, 16, 16, 16, - 16, 16, 16, 16, 0, 9, 11, 14, 16, 16, 10, 11, - 13, 16, 16, 14, 13, 14, 16, 16, 16, 15, 15, 16, - 0, 16, 16, 16, 0, 0, 11, 13, 16, 16, 16, 11, - 13, 15, 16, 16, 13, 16, 16, 16, 0, 16, 16, 16, - 16, 0, 16, 16, 0, 0, 0, 15, 16, 16, 16, 0, - 14, 16, 16, 16, 0, 16, 16, 16, 0, 0, 16, 16, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 13, 16, 16, - 16, 11, 13, 16, 16, 16, 14, 15, 16, 16, 0, 15, - 16, 16, 16, 0, 16, 16, 0, 0, 0, 9, 13, 15, - 15, 16, 12, 13, 14, 16, 16, 16, 15, 16, 16, 0, - 16, 16, 16, 16, 0, 16, 16, 0, 0, 0, 11, 13, - 15, 16, 0, 12, 14, 16, 16, 0, 16, 16, 16, 16, - 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16, - 16, 16, 16, 0, 16, 16, 16, 16, 0, 16, 16, 16, - 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, - 16, 16, 0, 0, 0, 16, 16, +static const uint8_t cvh_huffsyms5[192] = { + 0, 1, 3, 9, 27, 81, 4, 12, 36, 82, 84, 108, 10, 13, 28, + 30, 39, 90, 109, 117, 31, 37, 40, 85, 91, 93, 111, 120, 2, 54, + 94, 112, 118, 121, 162, 189, 5, 6, 18, 135, 7, 15, 21, 45, 63, + 163, 171, 11, 16, 19, 48, 57, 83, 87, 99, 144, 165, 198, 14, 29, + 32, 33, 34, 42, 46, 58, 66, 86, 88, 96, 102, 114, 126, 127, 129, + 138, 166, 172, 174, 190, 192, 22, 38, 41, 43, 49, 55, 64, 92, 100, + 103, 110, 130, 136, 139, 145, 147, 148, 175, 193, 199, 201, 8, 24, 95, + 97, 115, 119, 123, 153, 180, 216, 17, 20, 23, 25, 35, 44, 47, 50, + 51, 52, 56, 59, 60, 61, 65, 67, 68, 69, 70, 72, 73, 75, 76, + 89, 98, 101, 104, 105, 106, 113, 116, 122, 124, 125, 128, 131, 132, 133, + 137, 140, 141, 142, 146, 149, 150, 151, 154, 156, 157, 164, 167, 168, 169, + 173, 176, 177, 178, 181, 183, 184, 191, 194, 195, 196, 200, 202, 203, 204, + 205, 207, 208, 210, 211, 217, 219, 220, 225, 226, 228, 229, }; - -static const uint16_t cvh_huffcodes3[607] = { - 0x0000,0x0004,0x0022,0x00c6,0x03b0,0x000c,0x000d,0x0023,0x00c7,0x03b1,0x005c,0x00c8, - 0x00c9,0x03b2,0x0fa4,0x01c2,0x01c3,0x03b3,0x0fa5,0x7f72,0x03b4,0x07b2,0x1f9a,0xff24, - 0xff25,0x000e,0x0024,0x00ca,0x03b5,0x07b3,0x000f,0x0025,0x00cb,0x03b6,0x0fa6,0x005d, - 0x005e,0x00cc,0x03b7,0x1f9b,0x01c4,0x01c5,0x03b8,0x0fa7,0x7f73,0x0fa8,0x07b4,0x1f9c, - 0xff26,0xff27,0x005f,0x01c6,0x03b9,0x0fa9,0x7f74,0x0060,0x00cd,0x03ba,0x0faa,0x1f9d, - 0x01c7,0x01c8,0x07b5,0x1f9e,0xff28,0x07b6,0x07b7,0x0fab,0x3fa2,0xff29,0x0fac,0x0fad, - 0x3fa3,0xff2a,0x3fa2,0x01c9,0x07b8,0x0fae,0xff2b,0xff2c,0x01ca,0x03bb,0x1f9f,0x7f75, - 0xff2d,0x03bc,0x07b9,0x0faf,0xff2e,0xff2f,0x1fa0,0x1fa1,0xff30,0xff31,0xff32,0xff33, - 0xff34,0x7f76,0xff35,0xff31,0x07ba,0x1fa2,0xff36,0xff37,0x7f77,0x07bb,0x1fa3,0x7f78, - 0xff38,0xff39,0x1fa4,0x1fa5,0xff3a,0xff3b,0xff2e,0x3fa4,0xff3c,0xff3d,0xff3e,0xff31, - 0xff3f,0xff40,0xff30,0xff31,0xff31,0x0005,0x0026,0x00ce,0x03bd,0x1fa6,0x0027,0x0028, - 0x00cf,0x03be,0x1fa7,0x01cb,0x00d0,0x03bf,0x0fb0,0xff41,0x03c0,0x03c1,0x07bc,0x7f79, - 0xff42,0x1fa8,0x0fb1,0x3fa5,0xff43,0xff44,0x0010,0x0029,0x00d1,0x07bd,0x1fa9,0x002a, - 0x002b,0x00d2,0x03c2,0x1faa,0x00d3,0x00d4,0x01cc,0x07be,0x3fa6,0x03c3,0x03c4,0x0fb2, - 0x0fb3,0xff45,0x1fab,0x0fb4,0x1fac,0x7f7a,0xff46,0x0061,0x00d5,0x01cd,0x0fb5,0xff47, - 0x0062,0x00d6,0x03c5,0x0fb6,0x3fa7,0x01ce,0x01cf,0x03c6,0x1fad,0xff48,0x07bf,0x03c7, - 0x0fb7,0x7f7b,0xff49,0x1fae,0x1faf,0xff4a,0xff4b,0x7f7b,0x01d0,0x07c0,0x1fb0,0xff4c, - 0xff4d,0x01d1,0x03c8,0x0fb8,0x7f7c,0xff4e,0x03c9,0x07c1,0x1fb1,0xff4f,0xff50,0x1fb2, - 0x0fb9,0xff51,0xff52,0xff53,0xff54,0xff55,0xff56,0xff57,0xff52,0x07c2,0x1fb3,0xff58, - 0xff59,0xff5a,0x07c3,0x1fb4,0xff5b,0xff5c,0xff5d,0x0fba,0x1fb5,0x7f7d,0xff5e,0xff4f, - 0xff5f,0xff60,0xff61,0xff62,0xff52,0xff63,0xff64,0xff51,0xff52,0xff52,0x002c,0x00d7, - 0x07c4,0x1fb6,0xff65,0x00d8,0x00d9,0x03ca,0x0fbb,0xff66,0x07c5,0x03cb,0x07c6,0x1fb7, - 0xff67,0x0fbc,0x1fb8,0x1fb9,0x7f7e,0xff68,0xff69,0xff6a,0x3fa8,0xff6b,0x7f7e,0x002d, - 0x00da,0x03cc,0x1fba,0xff6c,0x00db,0x00dc,0x03cd,0x0fbd,0xff6d,0x03ce,0x03cf,0x07c7, - 0x1fbb,0xff6e,0x1fbc,0x0fbe,0x1fbd,0xff6f,0xff70,0x3fa9,0x3faa,0x3fab,0xff71,0xff6f, - 0x00dd,0x01d2,0x07c8,0x1fbe,0xff72,0x00de,0x01d3,0x07c9,0xff73,0x3fac,0x03d0,0x03d1, - 0x0fbf,0x7f7f,0xff74,0x0fc0,0x0fc1,0x1fbf,0xff75,0xff76,0x7f80,0xff77,0xff78,0xff79, - 0xff75,0x03d2,0x0fc2,0x7f81,0xff7a,0xff7b,0x03d3,0x0fc3,0x0fc4,0x3fad,0xff7c,0x0fc5, - 0x0fc6,0x1fc0,0xff7d,0xff7e,0x3fae,0x7f82,0xff7f,0xff80,0xff80,0xff81,0xff82,0xff83, - 0xff80,0xff80,0x0fc7,0x7f83,0x7f84,0xff84,0xff7a,0x1fc1,0x1fc2,0xff85,0xff86,0x3fad, - 0x3faf,0xff87,0xff88,0xff89,0xff7d,0xff8a,0xff8b,0xff8c,0xff80,0xff80,0x3fae,0x7f82, - 0xff7f,0xff80,0xff80,0x00df,0x03d4,0x1fc3,0x7f85,0xff8d,0x03d5,0x07ca,0x1fc4,0xff8e, - 0xff8f,0x1fc5,0x1fc6,0x3fb0,0xff90,0xff91,0xff92,0xff93,0xff94,0xff95,0xff96,0xff97, - 0xff98,0xff99,0xff9a,0xff95,0x00e0,0x03d6,0x07cb,0x7f86,0xff9b,0x01d4,0x03d7,0x0fc8, - 0xff9c,0xff9d,0x0fc9,0x0fca,0x7f87,0xff9e,0xff9f,0xffa0,0x3fb1,0xffa1,0xffa2,0xffa3, - 0xffa4,0xffa5,0xffa6,0xffa7,0xffa2,0x01d5,0x07cc,0x3fb2,0xffa8,0xffa9,0x03d8,0x07cd, - 0x1fc7,0xffaa,0xffab,0x3fb3,0x1fc8,0x3fb4,0xffac,0xffad,0xffae,0x7f88,0x7f89,0xffaf, - 0xffaf,0xffb0,0xffb1,0xffb2,0xffaf,0xffaf,0x07ce,0x1fc9,0xffb3,0xffb4,0xffb5,0x07cf, - 0x1fca,0x7f8a,0xffb6,0xffb7,0x1fcb,0xffb8,0xffb9,0xffba,0xffba,0xffbb,0xffbc,0xffbd, - 0xffbe,0xffbe,0xffbf,0xffc0,0xffbd,0xffbe,0xffbe,0x7f8b,0xffc1,0xffc2,0xffc3,0xffb4, - 0x3fb5,0xffc4,0xffc5,0xffc6,0xffb6,0xffc7,0xffc8,0xffc9,0xffba,0xffba,0xffca,0xffcb, - 0xffbd,0xffbe,0xffbe,0xffbb,0xffbc,0xffbd,0xffbe,0xffbe,0x01d6,0x1fcc,0xffcc,0xffcd, - 0xffce,0x07d0,0x1fcd,0xffcf,0xffd0,0xffd1,0x3fb6,0x7f8c,0xffd2,0xffd3,0xff90,0x7f8d, - 0xffd4,0xffd5,0xffd6,0xff95,0xffd7,0xffd8,0xff94,0xff95,0xff95,0x01d7,0x1fce,0x7f8e, - 0x7f8f,0xffd9,0x0fcb,0x1fcf,0x3fb7,0xffda,0xffdb,0xffdc,0x7f90,0xffdd,0xffde,0xff9e, - 0xffdf,0xffe0,0xffe1,0xffe2,0xffa2,0xffe3,0xffe4,0xffa1,0xffa2,0xffa2,0x07d1,0x1fd0, - 0x7f91,0xffe5,0xffa8,0x0fcc,0x3fb8,0xffe6,0xffe7,0xffaa,0xffe8,0xffe9,0xffea,0xffeb, - 0xffac,0xffec,0xffed,0xffee,0xffaf,0xffaf,0xffae,0x7f88,0x7f89,0xffaf,0xffaf,0xffef, - 0xfff0,0xfff1,0xfff2,0xffb4,0xfff3,0xfff4,0xfff5,0xfff6,0xffb6,0xfff7,0xfff8,0xfff9, - 0xffba,0xffba,0xfffa,0xfffb,0xffbd,0xffbe,0xffbe,0xffbb,0xffbc,0xffbd,0xffbe,0xffbe, - 0xfffc,0xfffd,0xffb3,0xffb4,0xffb4,0xfffe,0xffff, +static const uint8_t cvh_huffsyms6[32] = { + 0, 1, 2, 4, 8, 16, 3, 5, 6, 9, 10, 12, 17, 20, 24, 18, 7, 11, 14, + 19, 22, 26, 28, 13, 21, 25, 30, 15, 27, 29, 23, 31, }; -static const uint8_t cvh_huffbits4[246] = { - 2, 4, 7, 10, 4, 5, 7, 10, 7, 8, 10, 14, - 11, 11, 15, 15, 4, 5, 9, 12, 5, 5, 8, 12, - 8, 7, 10, 15, 11, 11, 15, 15, 7, 9, 12, 15, - 8, 8, 12, 15, 10, 10, 13, 15, 14, 14, 15, 0, - 11, 13, 15, 15, 11, 13, 15, 15, 14, 15, 15, 0, - 15, 15, 0, 0, 4, 5, 9, 13, 5, 6, 9, 13, - 9, 9, 11, 15, 14, 13, 15, 15, 4, 6, 9, 12, - 5, 6, 9, 13, 9, 8, 11, 15, 13, 12, 15, 15, - 7, 9, 12, 15, 7, 8, 11, 15, 10, 10, 14, 15, - 14, 15, 15, 0, 10, 12, 15, 15, 11, 13, 15, 15, - 15, 15, 15, 0, 15, 15, 0, 0, 6, 9, 13, 14, - 8, 9, 12, 15, 12, 12, 15, 15, 15, 15, 15, 0, - 7, 9, 13, 15, 8, 9, 12, 15, 11, 12, 15, 15, - 15, 15, 15, 0, 9, 11, 15, 15, 9, 11, 15, 15, - 14, 14, 15, 0, 15, 15, 0, 0, 14, 15, 15, 0, - 14, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 0, - 9, 12, 15, 15, 12, 13, 15, 15, 15, 15, 15, 0, - 15, 15, 0, 0, 10, 12, 15, 15, 12, 14, 15, 15, - 15, 15, 15, 0, 15, 15, 0, 0, 14, 15, 15, 0, - 15, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 0, - 15, 15, 0, 0, 15, 15, +static const void* const cvh_huffsyms[7] = { + cvh_huffsyms0, cvh_huffsyms1, cvh_huffsyms2, cvh_huffsyms3, + cvh_huffsyms4, cvh_huffsyms5, cvh_huffsyms6, }; - -static const uint16_t cvh_huffcodes4[246] = { - 0x0000,0x0004,0x006c,0x03e6,0x0005,0x0012,0x006d,0x03e7,0x006e,0x00e8,0x03e8,0x3fc4, - 0x07e0,0x07e1,0x7fa4,0x7fa5,0x0006,0x0013,0x01e2,0x0fda,0x0014,0x0015,0x00e9,0x0fdb, - 0x00ea,0x006f,0x03e9,0x7fa6,0x07e2,0x07e3,0x7fa7,0x7fa8,0x0070,0x01e3,0x0fdc,0x7fa9, - 0x00eb,0x00ec,0x0fdd,0x7faa,0x03ea,0x03eb,0x1fd6,0x7fab,0x3fc5,0x3fc6,0x7fac,0x1fd6, - 0x07e4,0x1fd7,0x7fad,0x7fae,0x07e5,0x1fd8,0x7faf,0x7fb0,0x3fc7,0x7fb1,0x7fb2,0x1fd6, - 0x7fb3,0x7fb4,0x1fd6,0x1fd6,0x0007,0x0016,0x01e4,0x1fd9,0x0017,0x0032,0x01e5,0x1fda, - 0x01e6,0x01e7,0x07e6,0x7fb5,0x3fc8,0x1fdb,0x7fb6,0x7fb7,0x0008,0x0033,0x01e8,0x0fde, - 0x0018,0x0034,0x01e9,0x1fdc,0x01ea,0x00ed,0x07e7,0x7fb8,0x1fdd,0x0fdf,0x7fb9,0x7fba, - 0x0071,0x01eb,0x0fe0,0x7fbb,0x0072,0x00ee,0x07e8,0x7fbc,0x03ec,0x03ed,0x3fc9,0x7fbd, - 0x3fca,0x7fbe,0x7fbf,0x3fc9,0x03ee,0x0fe1,0x7fc0,0x7fc1,0x07e9,0x1fde,0x7fc2,0x7fc3, - 0x7fc4,0x7fc5,0x7fc6,0x3fc9,0x7fc7,0x7fc8,0x3fc9,0x3fc9,0x0035,0x01ec,0x1fdf,0x3fcb, - 0x00ef,0x01ed,0x0fe2,0x7fc9,0x0fe3,0x0fe4,0x7fca,0x7fcb,0x7fcc,0x7fcd,0x7fce,0x7fca, - 0x0073,0x01ee,0x1fe0,0x7fcf,0x00f0,0x01ef,0x0fe5,0x7fd0,0x07ea,0x0fe6,0x7fd1,0x7fd2, - 0x7fd3,0x7fd4,0x7fd5,0x7fd1,0x01f0,0x07eb,0x7fd6,0x7fd7,0x01f1,0x07ec,0x7fd8,0x7fd9, - 0x3fcc,0x3fcd,0x7fda,0x7fda,0x7fdb,0x7fdc,0x7fda,0x7fda,0x3fce,0x7fdd,0x7fde,0x7fd6, - 0x3fcf,0x7fdf,0x7fe0,0x7fd8,0x7fe1,0x7fe2,0x7fda,0x7fda,0x3fcc,0x3fcd,0x7fda,0x7fda, - 0x01f2,0x0fe7,0x7fe3,0x7fe4,0x0fe8,0x1fe1,0x7fe5,0x7fe6,0x7fe7,0x7fe8,0x7fe9,0x7fca, - 0x7fea,0x7feb,0x7fca,0x7fca,0x03ef,0x0fe9,0x7fec,0x7fed,0x0fea,0x3fd0,0x7fee,0x7fef, - 0x7ff0,0x7ff1,0x7ff2,0x7fd1,0x7ff3,0x7ff4,0x7fd1,0x7fd1,0x3fd1,0x7ff5,0x7ff6,0x7fd6, - 0x7ff7,0x7ff8,0x7ff9,0x7fd8,0x7ffa,0x7ffb,0x7fda,0x7fda,0x3fcc,0x3fcd,0x7fda,0x7fda, - 0x7ffc,0x7ffd,0x7fd6,0x7fd6,0x7ffe,0x7fff, +static const uint8_t ccpl_huffsyms2[3] = { + 1, 0, 2, }; - -static const uint8_t cvh_huffbits5[230] = { - 2, 4, 8, 4, 5, 9, 9, 10, 14, 4, 6, 11, - 5, 6, 12, 10, 11, 15, 9, 11, 15, 10, 13, 15, - 14, 15, 0, 4, 6, 12, 6, 7, 12, 12, 12, 15, - 5, 7, 13, 6, 7, 13, 12, 13, 15, 10, 12, 15, - 11, 13, 15, 15, 15, 0, 8, 13, 15, 11, 12, 15, - 15, 15, 0, 10, 13, 15, 12, 15, 15, 15, 15, 0, - 15, 15, 0, 15, 15, 0, 0, 0, 0, 4, 5, 11, - 5, 7, 12, 11, 12, 15, 6, 7, 13, 7, 8, 14, - 12, 14, 15, 11, 13, 15, 12, 13, 15, 15, 15, 0, - 5, 6, 13, 7, 8, 15, 12, 14, 15, 6, 8, 14, - 7, 8, 15, 14, 15, 15, 12, 12, 15, 12, 13, 15, - 15, 15, 0, 9, 13, 15, 12, 13, 15, 15, 15, 0, - 11, 13, 15, 13, 13, 15, 15, 15, 0, 14, 15, 0, - 15, 15, 0, 0, 0, 0, 8, 10, 15, 11, 12, 15, - 15, 15, 0, 10, 12, 15, 12, 13, 15, 15, 15, 0, - 14, 15, 0, 15, 15, 0, 0, 0, 0, 8, 12, 15, - 12, 13, 15, 15, 15, 0, 11, 13, 15, 13, 15, 15, - 15, 15, 0, 15, 15, 0, 15, 15, 0, 0, 0, 0, - 14, 15, 0, 15, 15, 0, 0, 0, 0, 15, 15, 0, - 15, 15, +static const uint8_t ccpl_huffsyms3[7] = { + 3, 2, 4, 5, 1, 0, 6, }; - - -static const uint16_t cvh_huffcodes5[230] = { - 0x0000,0x0004,0x00f0,0x0005,0x0012,0x01f0,0x01f1,0x03e8,0x3fce,0x0006,0x0030,0x07de, - 0x0013,0x0031,0x0fd2,0x03e9,0x07df,0x7fb0,0x01f2,0x07e0,0x7fb1,0x03ea,0x1fd2,0x7fb2, - 0x3fcf,0x7fb3,0x0031,0x0007,0x0032,0x0fd3,0x0033,0x0070,0x0fd4,0x0fd5,0x0fd6,0x7fb4, - 0x0014,0x0071,0x1fd3,0x0034,0x0072,0x1fd4,0x0fd7,0x1fd5,0x7fb5,0x03eb,0x0fd8,0x7fb6, - 0x07e1,0x1fd6,0x7fb7,0x7fb8,0x7fb9,0x0072,0x00f1,0x1fd7,0x7fba,0x07e2,0x0fd9,0x7fbb, - 0x7fbc,0x7fbd,0x0070,0x03ec,0x1fd8,0x7fbe,0x0fda,0x7fbf,0x7fc0,0x7fc1,0x7fc2,0x0072, - 0x7fc3,0x7fc4,0x0071,0x7fc5,0x7fc6,0x0072,0x0034,0x0072,0x0072,0x0008,0x0015,0x07e3, - 0x0016,0x0073,0x0fdb,0x07e4,0x0fdc,0x7fc7,0x0035,0x0074,0x1fd9,0x0075,0x00f2,0x3fd0, - 0x0fdd,0x3fd1,0x7fc8,0x07e5,0x1fda,0x7fc9,0x0fde,0x1fdb,0x7fca,0x7fcb,0x7fcc,0x00f2, - 0x0017,0x0036,0x1fdc,0x0076,0x00f3,0x7fcd,0x0fdf,0x3fd2,0x7fce,0x0037,0x00f4,0x3fd3, - 0x0077,0x00f5,0x7fcf,0x3fd4,0x7fd0,0x7fd1,0x0fe0,0x0fe1,0x7fd2,0x0fe2,0x1fdd,0x7fd3, - 0x7fd4,0x7fd5,0x00f5,0x01f3,0x1fde,0x7fd6,0x0fe3,0x1fdf,0x7fd7,0x7fd8,0x7fd9,0x00f3, - 0x07e6,0x1fe0,0x7fda,0x1fe1,0x1fe2,0x7fdb,0x7fdc,0x7fdd,0x00f5,0x3fd5,0x7fde,0x00f4, - 0x7fdf,0x7fe0,0x00f5,0x0077,0x00f5,0x00f5,0x00f6,0x03ed,0x7fe1,0x07e7,0x0fe4,0x7fe2, - 0x7fe3,0x7fe4,0x0073,0x03ee,0x0fe5,0x7fe5,0x0fe6,0x1fe3,0x7fe6,0x7fe7,0x7fe8,0x00f2, - 0x3fd6,0x7fe9,0x0074,0x7fea,0x7feb,0x00f2,0x0075,0x00f2,0x00f2,0x00f7,0x0fe7,0x7fec, - 0x0fe8,0x1fe4,0x7fed,0x7fee,0x7fef,0x00f3,0x07e8,0x1fe5,0x7ff0,0x1fe6,0x7ff1,0x7ff2, - 0x7ff3,0x7ff4,0x00f5,0x7ff5,0x7ff6,0x00f4,0x7ff7,0x7ff8,0x00f5,0x0077,0x00f5,0x00f5, - 0x3fd7,0x7ff9,0x0036,0x7ffa,0x7ffb,0x00f3,0x0076,0x00f3,0x00f3,0x7ffc,0x7ffd,0x0000, - 0x7ffe,0x7fff, +static const uint8_t ccpl_huffsyms4[15] = { + 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 0, 1, 13, 14, }; - -static const uint8_t cvh_huffbits6[32] = { - 1, 4, 4, 6, 4, 6, 6, 8, 4, 6, 6, 8, - 6, 9, 8, 10, 4, 6, 7, 8, 6, 9, 8, 11, - 6, 9, 8, 10, 8, 10, 9, 11, +static const uint8_t ccpl_huffsyms5[31] = { + 15, 14, 16, 12, 13, 17, 18, 10, 11, 19, 20, 8, 9, 21, 22, 6, 7, 23, 24, + 4, 5, 25, 26, 0, 1, 2, 3, 27, 28, 29, 30, }; -static const uint16_t cvh_huffcodes6[32] = { - 0x0000,0x0008,0x0009,0x0034,0x000a,0x0035,0x0036,0x00f6,0x000b,0x0037,0x0038,0x00f7, - 0x0039,0x01fa,0x00f8,0x03fc,0x000c,0x003a,0x007a,0x00f9,0x003b,0x01fb,0x00fa,0x07fe, - 0x003c,0x01fc,0x00fb,0x03fd,0x00fc,0x03fe,0x01fd,0x07ff, +static const uint8_t ccpl_huffsyms6[63] = { + 31, 30, 32, 28, 29, 33, 34, 26, 27, 35, 36, 22, 23, 24, 25, 37, 38, 39, 40, + 18, 19, 20, 21, 41, 42, 43, 44, 13, 14, 15, 16, 17, 45, 46, 47, 48, 9, 10, + 11, 12, 49, 50, 51, 52, 53, 5, 6, 7, 8, 54, 55, 56, 57, 4, 58, 3, 59, + 2, 60, 61, 1, 0, 62, }; -static const uint16_t* const cvh_huffcodes[7] = { - cvh_huffcodes0, cvh_huffcodes1, cvh_huffcodes2, cvh_huffcodes3, - cvh_huffcodes4, cvh_huffcodes5, cvh_huffcodes6, +static const uint8_t ccpl_huffcounts[5][16] = { + { 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 2, 2, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 2, 0, 4, 4, 4, 4, 4, 8, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 1, 1, 4, 4, 8, 8, 9, 9, 8, 2, 2, 3, 1, 2 }, }; -static const uint8_t* const cvh_huffbits[7] = { - cvh_huffbits0, cvh_huffbits1, cvh_huffbits2, cvh_huffbits3, - cvh_huffbits4, cvh_huffbits5, cvh_huffbits6, +static const uint8_t *const ccpl_huffsyms[5] = { + ccpl_huffsyms2, ccpl_huffsyms3, + ccpl_huffsyms4, ccpl_huffsyms5, ccpl_huffsyms6 }; - -static const uint16_t ccpl_huffcodes2[3] = { - 0x02,0x00,0x03, -}; - -static const uint16_t ccpl_huffcodes3[7] = { - 0x3e,0x1e,0x02,0x00,0x06,0x0e,0x3f, -}; - -static const uint16_t ccpl_huffcodes4[15] = { - 0xfc,0xfd,0x7c,0x3c,0x1c,0x0c,0x04,0x00,0x05,0x0d,0x1d,0x3d, - 0x7d,0xfe,0xff, -}; - -static const uint16_t ccpl_huffcodes5[31] = { - 0x03f8,0x03f9,0x03fa,0x03fb,0x01f8,0x01f9,0x00f8,0x00f9,0x0078,0x0079,0x0038,0x0039, - 0x0018,0x0019,0x0004,0x0000,0x0005,0x001a,0x001b,0x003a,0x003b,0x007a,0x007b,0x00fa, - 0x00fb,0x01fa,0x01fb,0x03fc,0x03fd,0x03fe,0x03ff, -}; - -static const uint16_t ccpl_huffcodes6[63] = { - 0xfffe, 0x7ffe, 0x3ffc, 0x1ffc, 0x0ffc, 0x07f6, 0x07f7, 0x07f8, 0x07f9, - 0x03f2, 0x03f3, 0x03f4, 0x03f5, 0x01f0, 0x01f1, 0x01f2, 0x01f3, 0x01f4, - 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x0070, 0x0071, 0x0072, 0x0073, 0x0034, - 0x0035, 0x0016, 0x0017, 0x0004, 0x0000, 0x000a, 0x0018, 0x0019, 0x0036, - 0x0037, 0x0074, 0x0075, 0x0076, 0x0077, 0x00f4, 0x00f5, 0x00f6, 0x00f7, - 0x01f5, 0x01f6, 0x01f7, 0x01f8, 0x03f6, 0x03f7, 0x03f8, 0x03f9, 0x03fa, - 0x07fa, 0x07fb, 0x07fc, 0x07fd, 0x0ffd, 0x1ffd, 0x3ffd, 0x3ffe, 0xffff -}; - -static const uint8_t ccpl_huffbits2[3] = { - 2,1,2, -}; - -static const uint8_t ccpl_huffbits3[7] = { - 6,5,2,1,3,4,6, -}; - -static const uint8_t ccpl_huffbits4[15] = { - 8,8,7,6,5,4,3,1,3,4,5,6,7,8,8, -}; - -static const uint8_t ccpl_huffbits5[31] = { - 10,10,10,10,9,9,8,8,7,7,6,6, - 5,5,3,1,3,5,5,6,6,7,7,8, - 8,9,9,10,10,10,10, -}; - -static const uint8_t ccpl_huffbits6[63] = { - 16,15,14,13,12,11,11,11,11,10,10,10, - 10,9,9,9,9,9,8,8,8,8,7,7, - 7,7,6,6,5,5,3,1,4,5,5,6, - 6,7,7,7,7,8,8,8,8,9,9,9, - 9,10,10,10,10,10,11,11,11,11,12,13, - 14,14,16, -}; - -static const uint16_t* const ccpl_huffcodes[5] = { - ccpl_huffcodes2,ccpl_huffcodes3, - ccpl_huffcodes4,ccpl_huffcodes5,ccpl_huffcodes6 -}; - -static const uint8_t* const ccpl_huffbits[5] = { - ccpl_huffbits2,ccpl_huffbits3, - ccpl_huffbits4,ccpl_huffbits5,ccpl_huffbits6 -}; - - //Coupling tables static const int cplband[51] = { diff --git a/libavcodec/cpia.c b/libavcodec/cpia.c index bf09e1a5d..5f12a99a8 100644 --- a/libavcodec/cpia.c +++ b/libavcodec/cpia.c @@ -230,4 +230,5 @@ AVCodec ff_cpia_decoder = { .close = cpia_decode_end, .decode = cpia_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/cri.c b/libavcodec/cri.c new file mode 100644 index 000000000..0558d0c8d --- /dev/null +++ b/libavcodec/cri.c @@ -0,0 +1,438 @@ +/* + * CRI image decoder + * + * Copyright (c) 2020 Paul B Mahol + * + * 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 + * Cintel RAW image decoder + */ + +#define BITSTREAM_READER_LE + +#include "libavutil/intfloat.h" +#include "libavutil/display.h" +#include "avcodec.h" +#include "bytestream.h" +#include "get_bits.h" +#include "internal.h" +#include "thread.h" + +typedef struct CRIContext { + AVCodecContext *jpeg_avctx; // wrapper context for MJPEG + AVPacket *jpkt; // encoded JPEG tile + AVFrame *jpgframe; // decoded JPEG tile + + GetByteContext gb; + int color_model; + const uint8_t *data; + unsigned data_size; + uint64_t tile_size[4]; +} CRIContext; + +static av_cold int cri_decode_init(AVCodecContext *avctx) +{ + CRIContext *s = avctx->priv_data; + const AVCodec *codec; + int ret; + + s->jpgframe = av_frame_alloc(); + if (!s->jpgframe) + return AVERROR(ENOMEM); + + s->jpkt = av_packet_alloc(); + if (!s->jpkt) + return AVERROR(ENOMEM); + + codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG); + if (!codec) + return AVERROR_BUG; + s->jpeg_avctx = avcodec_alloc_context3(codec); + if (!s->jpeg_avctx) + return AVERROR(ENOMEM); + s->jpeg_avctx->flags = avctx->flags; + s->jpeg_avctx->flags2 = avctx->flags2; + s->jpeg_avctx->dct_algo = avctx->dct_algo; + s->jpeg_avctx->idct_algo = avctx->idct_algo; + ret = avcodec_open2(s->jpeg_avctx, codec, NULL); + if (ret < 0) + return ret; + + return 0; +} + +static void unpack_10bit(GetByteContext *gb, uint16_t *dst, int shift, + int w, int h, ptrdiff_t stride) +{ + int count = w * h; + int pos = 0; + + while (count > 0) { + uint32_t a0, a1, a2, a3; + if (bytestream2_get_bytes_left(gb) < 4) + break; + a0 = bytestream2_get_le32(gb); + a1 = bytestream2_get_le32(gb); + a2 = bytestream2_get_le32(gb); + a3 = bytestream2_get_le32(gb); + dst[pos] = (((a0 >> 1) & 0xE00) | (a0 & 0x1FF)) << shift; + pos++; + if (pos >= w) { + if (count == 1) + break; + dst += stride; + pos = 0; + } + dst[pos] = (((a0 >> 13) & 0x3F) | ((a0 >> 14) & 0xFC0)) << shift; + pos++; + if (pos >= w) { + if (count == 2) + break; + dst += stride; + pos = 0; + } + dst[pos] = (((a0 >> 26) & 7) | ((a1 & 0x1FF) << 3)) << shift; + pos++; + if (pos >= w) { + if (count == 3) + break; + dst += stride; + pos = 0; + } + dst[pos] = (((a1 >> 10) & 0x1FF) | ((a1 >> 11) & 0xE00)) << shift; + pos++; + if (pos >= w) { + if (count == 4) + break; + dst += stride; + pos = 0; + } + dst[pos] = (((a1 >> 23) & 0x3F) | ((a2 & 0x3F) << 6)) << shift; + pos++; + if (pos >= w) { + if (count == 5) + break; + dst += stride; + pos = 0; + } + dst[pos] = (((a2 >> 7) & 0xFF8) | ((a2 >> 6) & 7)) << shift; + pos++; + if (pos >= w) { + if (count == 6) + break; + dst += stride; + pos = 0; + } + dst[pos] = (((a3 & 7) << 9) | ((a2 >> 20) & 0x1FF)) << shift; + pos++; + if (pos >= w) { + if (count == 7) + break; + dst += stride; + pos = 0; + } + dst[pos] = (((a3 >> 4) & 0xFC0) | ((a3 >> 3) & 0x3F)) << shift; + pos++; + if (pos >= w) { + if (count == 8) + break; + dst += stride; + pos = 0; + } + dst[pos] = (((a3 >> 16) & 7) | ((a3 >> 17) & 0xFF8)) << shift; + pos++; + if (pos >= w) { + if (count == 9) + break; + dst += stride; + pos = 0; + } + + count -= 9; + } +} + +static int cri_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + CRIContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + ThreadFrame frame = { .f = data }; + int ret, bps, hflip = 0, vflip = 0; + AVFrameSideData *rotation; + int compressed = 0; + AVFrame *p = data; + + s->data = NULL; + s->data_size = 0; + + bytestream2_init(gb, avpkt->data, avpkt->size); + + while (bytestream2_get_bytes_left(gb) > 8) { + char codec_name[1024]; + uint32_t key, length; + float framerate; + int width, height; + + key = bytestream2_get_le32(gb); + length = bytestream2_get_le32(gb); + + switch (key) { + case 1: + if (length != 4) + return AVERROR_INVALIDDATA; + + if (bytestream2_get_le32(gb) != MKTAG('D', 'V', 'C', 'C')) + return AVERROR_INVALIDDATA; + break; + case 100: + if (length < 16) + return AVERROR_INVALIDDATA; + width = bytestream2_get_le32(gb); + height = bytestream2_get_le32(gb); + s->color_model = bytestream2_get_le32(gb); + if (bytestream2_get_le32(gb) != 1) + return AVERROR_INVALIDDATA; + ret = ff_set_dimensions(avctx, width, height); + if (ret < 0) + return ret; + length -= 16; + goto skip; + case 101: + if (length != 4) + return AVERROR_INVALIDDATA; + + if (bytestream2_get_le32(gb) != 0) + return AVERROR_INVALIDDATA; + break; + case 102: + bytestream2_get_buffer(gb, codec_name, FFMIN(length, sizeof(codec_name) - 1)); + length -= FFMIN(length, sizeof(codec_name) - 1); + if (strncmp(codec_name, "cintel_craw", FFMIN(length, sizeof(codec_name) - 1))) + return AVERROR_INVALIDDATA; + compressed = 1; + goto skip; + case 103: + if (bytestream2_get_bytes_left(gb) < length) + return AVERROR_INVALIDDATA; + s->data = gb->buffer; + s->data_size = length; + goto skip; + case 105: + hflip = bytestream2_get_byte(gb) != 0; + length--; + goto skip; + case 106: + vflip = bytestream2_get_byte(gb) != 0; + length--; + goto skip; + case 107: + if (length != 4) + return AVERROR_INVALIDDATA; + framerate = av_int2float(bytestream2_get_le32(gb)); + avctx->framerate.num = framerate * 1000; + avctx->framerate.den = 1000; + break; + case 119: + if (length != 32) + return AVERROR_INVALIDDATA; + + for (int i = 0; i < 4; i++) + s->tile_size[i] = bytestream2_get_le64(gb); + break; + default: + av_log(avctx, AV_LOG_DEBUG, "skipping unknown key %u of length %u\n", key, length); +skip: + bytestream2_skip(gb, length); + } + } + + switch (s->color_model) { + case 76: + case 88: + avctx->pix_fmt = AV_PIX_FMT_BAYER_BGGR16; + break; + case 77: + case 89: + avctx->pix_fmt = AV_PIX_FMT_BAYER_GBRG16; + break; + case 78: + case 90: + avctx->pix_fmt = AV_PIX_FMT_BAYER_RGGB16; + break; + case 45: + case 79: + case 91: + avctx->pix_fmt = AV_PIX_FMT_BAYER_GRBG16; + break; + } + + switch (s->color_model) { + case 45: + bps = 10; + break; + case 76: + case 77: + case 78: + case 79: + bps = 12; + break; + case 88: + case 89: + case 90: + case 91: + bps = 16; + break; + default: + return AVERROR_INVALIDDATA; + } + + if (compressed) { + for (int i = 0; i < 4; i++) { + if (s->tile_size[i] >= s->data_size) + return AVERROR_INVALIDDATA; + } + + if (s->tile_size[0] + s->tile_size[1] + s->tile_size[2] + s->tile_size[3] != + s->data_size) + return AVERROR_INVALIDDATA; + } + + if (!s->data || !s->data_size) + return AVERROR_INVALIDDATA; + + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) + return ret; + + avctx->bits_per_raw_sample = bps; + + if (!compressed && s->color_model == 45) { + uint16_t *dst = (uint16_t *)p->data[0]; + GetByteContext gb; + + bytestream2_init(&gb, s->data, s->data_size); + unpack_10bit(&gb, dst, 4, avctx->width, avctx->height, p->linesize[0] / 2); + } else if (!compressed) { + GetBitContext gbit; + const int shift = 16 - bps; + + ret = init_get_bits8(&gbit, s->data, s->data_size); + if (ret < 0) + return ret; + + for (int y = 0; y < avctx->height; y++) { + uint16_t *dst = (uint16_t *)(p->data[0] + y * p->linesize[0]); + + if (get_bits_left(&gbit) < avctx->width * bps) + break; + + for (int x = 0; x < avctx->width; x++) + dst[x] = get_bits(&gbit, bps) << shift; + } + } else { + unsigned offset = 0; + + for (int tile = 0; tile < 4; tile++) { + av_packet_unref(s->jpkt); + s->jpkt->data = (uint8_t *)s->data + offset; + s->jpkt->size = s->tile_size[tile]; + + ret = avcodec_send_packet(s->jpeg_avctx, s->jpkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); + return ret; + } + + ret = avcodec_receive_frame(s->jpeg_avctx, s->jpgframe); + if (ret < 0 || s->jpgframe->format != AV_PIX_FMT_GRAY16 || + s->jpeg_avctx->width * 2 != avctx->width || + s->jpeg_avctx->height * 2 != avctx->height) { + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "JPEG decoding error (%d).\n", ret); + } else { + av_log(avctx, AV_LOG_ERROR, + "JPEG invalid format.\n"); + ret = AVERROR_INVALIDDATA; + } + + /* Normally skip, if error explode */ + if (avctx->err_recognition & AV_EF_EXPLODE) + return ret; + else + return 0; + } + + for (int y = 0; y < s->jpeg_avctx->height; y++) { + const int hw = s->jpgframe->width / 2; + uint16_t *dst = (uint16_t *)(p->data[0] + (y * 2) * p->linesize[0] + tile * hw * 2); + const uint16_t *src = (const uint16_t *)(s->jpgframe->data[0] + y * s->jpgframe->linesize[0]); + + memcpy(dst, src, hw * 2); + src += hw; + dst += p->linesize[0] / 2; + memcpy(dst, src, hw * 2); + } + + av_frame_unref(s->jpgframe); + offset += s->tile_size[tile]; + } + } + + if (hflip || vflip) { + rotation = av_frame_new_side_data(p, AV_FRAME_DATA_DISPLAYMATRIX, + sizeof(int32_t) * 9); + if (rotation) { + av_display_rotation_set((int32_t *)rotation->data, 0.f); + av_display_matrix_flip((int32_t *)rotation->data, hflip, vflip); + } + } + + p->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; + + *got_frame = 1; + + return 0; +} + +static av_cold int cri_decode_close(AVCodecContext *avctx) +{ + CRIContext *s = avctx->priv_data; + + av_frame_free(&s->jpgframe); + av_packet_free(&s->jpkt); + avcodec_free_context(&s->jpeg_avctx); + + return 0; +} + +AVCodec ff_cri_decoder = { + .name = "cri", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_CRI, + .priv_data_size = sizeof(CRIContext), + .init = cri_decode_init, + .decode = cri_decode_frame, + .close = cri_decode_close, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, + .long_name = NULL_IF_CONFIG_SMALL("Cintel RAW"), +}; diff --git a/libavcodec/cri_parser.c b/libavcodec/cri_parser.c new file mode 100644 index 000000000..9790747a9 --- /dev/null +++ b/libavcodec/cri_parser.c @@ -0,0 +1,105 @@ +/* + * CRI parser + * Copyright (c) 2021 Paul B Mahol + * + * 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 + * CRI parser + */ + +#include "libavutil/bswap.h" +#include "libavutil/common.h" + +#include "parser.h" + +typedef struct CRIParser { + ParseContext pc; + int count; + int chunk; + int read_bytes; + int skip_bytes; +} CRIParser; + +#define KEY (((uint64_t)'\1' << 56) | ((uint64_t)'\0' << 48) | \ + ((uint64_t)'\0' << 40) | ((uint64_t)'\0' << 32) | \ + ((uint64_t)'\4' << 24) | ((uint64_t)'\0' << 16) | \ + ((uint64_t)'\0' << 8) | ((uint64_t)'\0' << 0)) + +static int cri_parse(AVCodecParserContext *s, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + CRIParser *bpc = s->priv_data; + uint64_t state = bpc->pc.state64; + int next = END_NOT_FOUND, i = 0; + + s->pict_type = AV_PICTURE_TYPE_I; + s->key_frame = 1; + s->duration = 1; + + *poutbuf_size = 0; + *poutbuf = NULL; + + for (; i < buf_size; i++) { + state = (state << 8) | buf[i]; + bpc->read_bytes++; + + if (bpc->skip_bytes > 0) { + bpc->skip_bytes--; + if (bpc->skip_bytes == 0) + bpc->read_bytes = 0; + } else { + if (state != KEY) + continue; + } + + if (bpc->skip_bytes == 0 && bpc->read_bytes >= 8) { + bpc->skip_bytes = av_bswap32(state & 0xFFFFFFFF); + bpc->chunk = state >> 32; + bpc->read_bytes = 0; + bpc->count++; + } + + if (bpc->chunk == 0x01000000 && bpc->skip_bytes == 4 && + bpc->read_bytes == 0 && bpc->count > 1) { + next = i - 7; + break; + } + } + + bpc->pc.state64 = state; + if (ff_combine_frame(&bpc->pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + + return next; +} + +AVCodecParser ff_cri_parser = { + .codec_ids = { AV_CODEC_ID_CRI }, + .priv_data_size = sizeof(CRIParser), + .parser_parse = cri_parse, + .parser_close = ff_parse_close, +}; diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c index e3c595596..228803183 100644 --- a/libavcodec/crystalhd.c +++ b/libavcodec/crystalhd.c @@ -657,7 +657,6 @@ static int crystalhd_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt) BC_STATUS bc_ret; CHDContext *priv = avctx->priv_data; HANDLE dev = priv->dev; - AVPacket filtered_packet = { 0 }; int ret = 0; av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_packet\n"); @@ -700,7 +699,6 @@ static int crystalhd_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt) goto exit; } exit: - av_packet_unref(&filtered_packet); return ret; } diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index 2d6377bc8..ec57afdef 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -42,6 +42,10 @@ #define cudaVideoSurfaceFormat_YUV444_16Bit 3 #endif +#if NVDECAPI_CHECK_VERSION(11, 0) +#define CUVID_HAS_AV1_SUPPORT +#endif + typedef struct CuvidContext { AVClass *avclass; @@ -549,6 +553,12 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) tmp_frame->format = AV_PIX_FMT_CUDA; tmp_frame->hw_frames_ctx = av_buffer_ref(ctx->hwframe); + if (!tmp_frame->hw_frames_ctx) { + ret = AVERROR(ENOMEM); + av_frame_free(&tmp_frame); + goto error; + } + tmp_frame->width = avctx->width; tmp_frame->height = avctx->height; @@ -624,6 +634,9 @@ FF_ENABLE_DEPRECATION_WARNINGS } error: + if (ret < 0) + av_frame_unref(frame); + if (mapped_frame) eret = CHECK_CU(ctx->cvdl->cuvidUnmapVideoFrame(ctx->cudecoder, mapped_frame)); @@ -669,15 +682,22 @@ static int cuvid_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, static av_cold int cuvid_decode_end(AVCodecContext *avctx) { CuvidContext *ctx = avctx->priv_data; + AVHWDeviceContext *device_ctx = (AVHWDeviceContext *)ctx->hwdevice->data; + AVCUDADeviceContext *device_hwctx = device_ctx->hwctx; + CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx; av_fifo_freep(&ctx->frame_queue); + ctx->cudl->cuCtxPushCurrent(cuda_ctx); + if (ctx->cuparser) ctx->cvdl->cuvidDestroyVideoParser(ctx->cuparser); if (ctx->cudecoder) ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder); + ctx->cudl->cuCtxPopCurrent(&dummy); + ctx->cudl = NULL; av_buffer_unref(&ctx->hwframe); @@ -939,6 +959,11 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) case AV_CODEC_ID_VC1: ctx->cuparseinfo.CodecType = cudaVideoCodec_VC1; break; +#endif +#if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT) + case AV_CODEC_ID_AV1: + ctx->cuparseinfo.CodecType = cudaVideoCodec_AV1; + break; #endif default: av_log(avctx, AV_LOG_ERROR, "Invalid CUVID codec!\n"); @@ -974,7 +999,7 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) } ctx->cuparseinfo.ulMaxNumDecodeSurfaces = ctx->nb_surfaces; - ctx->cuparseinfo.ulMaxDisplayDelay = 4; + ctx->cuparseinfo.ulMaxDisplayDelay = (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) ? 0 : 4; ctx->cuparseinfo.pUserData = avctx; ctx->cuparseinfo.pfnSequenceCallback = cuvid_handle_video_sequence; ctx->cuparseinfo.pfnDecodePicture = cuvid_handle_picture_decode; @@ -1091,7 +1116,7 @@ static const AVOption options[] = { { NULL } }; -static const AVCodecHWConfigInternal *cuvid_hw_configs[] = { +static const AVCodecHWConfigInternal *const cuvid_hw_configs[] = { &(const AVCodecHWConfigInternal) { .public = { .pix_fmt = AV_PIX_FMT_CUDA, @@ -1134,6 +1159,10 @@ static const AVCodecHWConfigInternal *cuvid_hw_configs[] = { .wrapper_name = "cuvid", \ }; +#if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT) +DEFINE_CUVID_CODEC(av1, AV1, NULL) +#endif + #if CONFIG_HEVC_CUVID_DECODER DEFINE_CUVID_CODEC(hevc, HEVC, "hevc_mp4toannexb") #endif diff --git a/libavcodec/dca_core.h b/libavcodec/dca_core.h index 10128d1e3..86bfa6220 100644 --- a/libavcodec/dca_core.h +++ b/libavcodec/dca_core.h @@ -24,7 +24,7 @@ #include "libavutil/common.h" #include "libavutil/float_dsp.h" #include "libavutil/fixed_dsp.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "internal.h" diff --git a/libavcodec/dca_lbr.c b/libavcodec/dca_lbr.c index 747fdafd3..2f8060df8 100644 --- a/libavcodec/dca_lbr.c +++ b/libavcodec/dca_lbr.c @@ -21,6 +21,7 @@ #define BITSTREAM_READER_LE #include "libavutil/channel_layout.h" +#include "libavutil/mem_internal.h" #include "dcadec.h" #include "dcadata.h" diff --git a/libavcodec/dca_lbr.h b/libavcodec/dca_lbr.h index 6d4c0a8a6..e6856a2cf 100644 --- a/libavcodec/dca_lbr.h +++ b/libavcodec/dca_lbr.h @@ -23,7 +23,7 @@ #include "libavutil/common.h" #include "libavutil/float_dsp.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "internal.h" diff --git a/libavcodec/dca_xll.h b/libavcodec/dca_xll.h index bc0aa65b1..3aaad6d37 100644 --- a/libavcodec/dca_xll.h +++ b/libavcodec/dca_xll.h @@ -22,7 +22,7 @@ #define AVCODEC_DCA_XLL_H #include "libavutil/common.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "internal.h" diff --git a/libavcodec/dcadata.c b/libavcodec/dcadata.c index 1b646a7aa..643b0cc02 100644 --- a/libavcodec/dcadata.c +++ b/libavcodec/dcadata.c @@ -22,7 +22,7 @@ #include -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "dca.h" #include "dcadata.h" diff --git a/libavcodec/dcadsp.c b/libavcodec/dcadsp.c index fade1a6c0..9d00ebd28 100644 --- a/libavcodec/dcadsp.c +++ b/libavcodec/dcadsp.c @@ -19,6 +19,7 @@ */ #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "dcadsp.h" #include "dcamath.h" @@ -328,7 +329,7 @@ static void dmix_add_c(int32_t *dst, const int32_t *src, int coeff, ptrdiff_t le int i; for (i = 0; i < len; i++) - dst[i] += mul15(src[i], coeff); + dst[i] += (unsigned)mul15(src[i], coeff); } static void dmix_scale_c(int32_t *dst, int scale, ptrdiff_t len) diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c index 34b3e9416..87fb5f545 100644 --- a/libavcodec/dcaenc.c +++ b/libavcodec/dcaenc.c @@ -28,6 +28,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/ffmath.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "avcodec.h" #include "dca.h" @@ -924,10 +925,10 @@ static void fill_in_adpcm_bufer(DCAEncContext *c) * But there are no proper value in decoder history, so likely result will be no good. * Bitstream has "Predictor history flag switch", but this flag disables history for all subbands */ - samples[0] = c->adpcm_history[ch][band][0] << 7; - samples[1] = c->adpcm_history[ch][band][1] << 7; - samples[2] = c->adpcm_history[ch][band][2] << 7; - samples[3] = c->adpcm_history[ch][band][3] << 7; + samples[0] = c->adpcm_history[ch][band][0] * (1 << 7); + samples[1] = c->adpcm_history[ch][band][1] * (1 << 7); + samples[2] = c->adpcm_history[ch][band][2] * (1 << 7); + samples[3] = c->adpcm_history[ch][band][3] * (1 << 7); } } } diff --git a/libavcodec/decode.c b/libavcodec/decode.c index a190c3901..5a00aeeda 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -66,7 +66,8 @@ typedef struct FramePool { static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt) { - int size = 0, ret; + int ret; + buffer_size_t size; const uint8_t *data; uint32_t flags; int64_t val; @@ -142,66 +143,49 @@ fail2: return 0; } -static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) +#define IS_EMPTY(pkt) (!(pkt)->data) + +static int copy_packet_props(AVPacket *dst, const AVPacket *src) { - int ret = 0; - - av_packet_unref(avci->last_pkt_props); - if (pkt) { - ret = av_packet_copy_props(avci->last_pkt_props, pkt); - if (!ret) - avci->last_pkt_props->size = pkt->size; // HACK: Needed for ff_decode_frame_props(). - } - return ret; -} - -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); + int ret = av_packet_copy_props(dst, src); 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 = avci->to_free->channels; - 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; - frame->channels = avci->to_free->channels; + dst->size = src->size; // HACK: Needed for ff_decode_frame_props(). + dst->data = (void*)1; // HACK: Needed for IS_EMPTY(). return 0; } -int ff_decode_bsfs_init(AVCodecContext *avctx) +static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) +{ + AVPacket tmp = { 0 }; + int ret = 0; + + if (IS_EMPTY(avci->last_pkt_props)) { + if (av_fifo_size(avci->pkt_props) >= sizeof(*pkt)) { + av_fifo_generic_read(avci->pkt_props, avci->last_pkt_props, + sizeof(*avci->last_pkt_props), NULL); + } else + return copy_packet_props(avci->last_pkt_props, pkt); + } + + if (av_fifo_space(avci->pkt_props) < sizeof(*pkt)) { + ret = av_fifo_grow(avci->pkt_props, sizeof(*pkt)); + if (ret < 0) + return ret; + } + + ret = copy_packet_props(&tmp, pkt); + if (ret < 0) + return ret; + + av_fifo_generic_write(avci->pkt_props, &tmp, sizeof(tmp), NULL); + + return 0; +} + +static int decode_bsfs_init(AVCodecContext *avctx) { AVCodecInternal *avci = avctx->internal; int ret; @@ -257,8 +241,10 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) if (ret < 0) goto finish; +#if FF_API_OLD_ENCDEC if (avctx->codec->receive_frame) avci->compat_decode_consumed += pkt->size; +#endif return 0; finish: @@ -308,12 +294,11 @@ static int64_t guess_correct_pts(AVCodecContext *ctx, * returning any output, so this function needs to be called in a loop until it * returns EAGAIN. **/ -static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame) +static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame, int64_t *discarded_samples) { AVCodecInternal *avci = avctx->internal; DecodeSimpleContext *ds = &avci->ds; AVPacket *pkt = ds->in_pkt; - // copy to ensure we do not change pkt int got_frame, actual_got_frame; int ret; @@ -362,21 +347,14 @@ static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame) if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { if (frame->flags & AV_FRAME_FLAG_DISCARD) got_frame = 0; - if (got_frame) - frame->best_effort_timestamp = guess_correct_pts(avctx, - frame->pts, - frame->pkt_dts); } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { uint8_t *side; - int side_size; + buffer_size_t side_size; uint32_t discard_padding = 0; uint8_t skip_reason = 0; uint8_t discard_reason = 0; if (ret >= 0 && got_frame) { - frame->best_effort_timestamp = guess_correct_pts(avctx, - frame->pts, - frame->pkt_dts); if (frame->format == AV_SAMPLE_FMT_NONE) frame->format = avctx->sample_fmt; if (!frame->channel_layout) @@ -401,12 +379,14 @@ static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame) !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { avci->skip_samples = FFMAX(0, avci->skip_samples - frame->nb_samples); got_frame = 0; + *discarded_samples += frame->nb_samples; } if (avci->skip_samples > 0 && got_frame && !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { if(frame->nb_samples <= avci->skip_samples){ got_frame = 0; + *discarded_samples += frame->nb_samples; avci->skip_samples -= frame->nb_samples; av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n", avci->skip_samples); @@ -434,6 +414,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n", avci->skip_samples, frame->nb_samples); + *discarded_samples += avci->skip_samples; frame->nb_samples -= avci->skip_samples; avci->skip_samples = 0; } @@ -442,6 +423,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (discard_padding > 0 && discard_padding <= frame->nb_samples && got_frame && !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { if (discard_padding == frame->nb_samples) { + *discarded_samples += frame->nb_samples; got_frame = 0; } else { if(avctx->pkt_timebase.num && avctx->sample_rate) { @@ -508,10 +490,13 @@ FF_ENABLE_DEPRECATION_WARNINGS } } +#if FF_API_OLD_ENCDEC avci->compat_decode_consumed += ret; +#endif if (ret >= pkt->size || ret < 0) { av_packet_unref(pkt); + av_packet_unref(avci->last_pkt_props); } else { int consumed = ret; @@ -533,9 +518,12 @@ FF_ENABLE_DEPRECATION_WARNINGS static int decode_simple_receive_frame(AVCodecContext *avctx, AVFrame *frame) { int ret; + int64_t discarded_samples = 0; while (!frame->buf[0]) { - ret = decode_simple_internal(avctx, frame); + if (discarded_samples > avctx->max_samples) + return AVERROR(EAGAIN); + ret = decode_simple_internal(avctx, frame, &discarded_samples); if (ret < 0) return ret; } @@ -550,15 +538,21 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) av_assert0(!frame->buf[0]); - if (avctx->codec->receive_frame) + if (avctx->codec->receive_frame) { ret = avctx->codec->receive_frame(avctx, frame); - else + if (ret != AVERROR(EAGAIN)) + av_packet_unref(avci->last_pkt_props); + } else ret = decode_simple_receive_frame(avctx, frame); if (ret == AVERROR_EOF) avci->draining_done = 1; if (!ret) { + frame->best_effort_timestamp = guess_correct_pts(avctx, + frame->pts, + frame->pkt_dts); + /* the only case where decode data is not set should be decoders * that do not call ff_get_buffer() */ av_assert0((frame->private_ref && frame->private_ref->size == sizeof(FrameDecodeData)) || @@ -722,6 +716,54 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr return 0; } +#if FF_API_OLD_ENCDEC +FF_DISABLE_DEPRECATION_WARNINGS +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 = avci->to_free->channels; + 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; + frame->channels = avci->to_free->channels; + + return 0; +} + static int compat_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, const AVPacket *pkt) { @@ -817,6 +859,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, { return compat_decode(avctx, frame, got_frame_ptr, avpkt); } +FF_ENABLE_DEPRECATION_WARNINGS +#endif static void get_subtitle_defaults(AVSubtitle *sub) { @@ -825,55 +869,58 @@ static void get_subtitle_defaults(AVSubtitle *sub) } #define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */ -static int recode_subtitle(AVCodecContext *avctx, - AVPacket *outpkt, const AVPacket *inpkt) +static int recode_subtitle(AVCodecContext *avctx, AVPacket **outpkt, + AVPacket *inpkt, AVPacket *buf_pkt) { #if CONFIG_ICONV iconv_t cd = (iconv_t)-1; int ret = 0; char *inb, *outb; size_t inl, outl; - AVPacket tmp; #endif - if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0) + if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0) { + *outpkt = inpkt; return 0; + } #if CONFIG_ICONV - cd = iconv_open("UTF-8", avctx->sub_charenc); - av_assert0(cd != (iconv_t)-1); - inb = inpkt->data; inl = inpkt->size; if (inl >= INT_MAX / UTF8_MAX_BYTES - AV_INPUT_BUFFER_PADDING_SIZE) { av_log(avctx, AV_LOG_ERROR, "Subtitles packet is too big for recoding\n"); - ret = AVERROR(ENOMEM); - goto end; + return AVERROR(ERANGE); } - ret = av_new_packet(&tmp, inl * UTF8_MAX_BYTES); + cd = iconv_open("UTF-8", avctx->sub_charenc); + av_assert0(cd != (iconv_t)-1); + + ret = av_new_packet(buf_pkt, inl * UTF8_MAX_BYTES); if (ret < 0) goto end; - outpkt->buf = tmp.buf; - outpkt->data = tmp.data; - outpkt->size = tmp.size; - outb = outpkt->data; - outl = outpkt->size; + ret = av_packet_copy_props(buf_pkt, inpkt); + if (ret < 0) + goto end; + outb = buf_pkt->data; + outl = buf_pkt->size; if (iconv(cd, &inb, &inl, &outb, &outl) == (size_t)-1 || iconv(cd, NULL, NULL, &outb, &outl) == (size_t)-1 || - outl >= outpkt->size || inl != 0) { + outl >= buf_pkt->size || inl != 0) { ret = FFMIN(AVERROR(errno), -1); av_log(avctx, AV_LOG_ERROR, "Unable to recode subtitle event \"%s\" " "from %s to UTF-8\n", inpkt->data, avctx->sub_charenc); - av_packet_unref(&tmp); goto end; } - outpkt->size -= outl; - memset(outpkt->data + outpkt->size, 0, outl); + buf_pkt->size -= outl; + memset(buf_pkt->data + buf_pkt->size, 0, outl); + *outpkt = buf_pkt; + ret = 0; end: + if (ret < 0) + av_packet_unref(buf_pkt); if (cd != (iconv_t)-1) iconv_close(cd); return ret; @@ -979,7 +1026,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt) { - int i, ret = 0; + int ret = 0; if (!avpkt->data && avpkt->size) { av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); @@ -996,69 +1043,60 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, get_subtitle_defaults(sub); if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { - AVPacket pkt_recoded = *avpkt; + AVCodecInternal *avci = avctx->internal; + AVPacket *pkt; - ret = recode_subtitle(avctx, &pkt_recoded, avpkt); - if (ret < 0) { - *got_sub_ptr = 0; - } else { - ret = extract_packet_props(avctx->internal, &pkt_recoded); - if (ret < 0) - return ret; + ret = recode_subtitle(avctx, &pkt, avpkt, avci->buffer_pkt); + if (ret < 0) + return ret; - if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE) - sub->pts = av_rescale_q(avpkt->pts, - avctx->pkt_timebase, AV_TIME_BASE_Q); - 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 (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE) + sub->pts = av_rescale_q(avpkt->pts, + avctx->pkt_timebase, AV_TIME_BASE_Q); + ret = avctx->codec->decode(avctx, sub, got_sub_ptr, pkt); + av_assert1((ret >= 0) >= !!*got_sub_ptr && + !!*got_sub_ptr >= !!sub->num_rects); #if FF_API_ASS_TIMING - if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS - && *got_sub_ptr && sub->num_rects) { - const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase - : avctx->time_base; - int err = convert_sub_to_old_ass_form(sub, avpkt, tb); - if (err < 0) - ret = err; - } + if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS + && *got_sub_ptr && sub->num_rects) { + const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase + : avctx->time_base; + int err = convert_sub_to_old_ass_form(sub, avpkt, tb); + if (err < 0) + ret = err; + } #endif - 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); - } + 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); + } - 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; + 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; - for (i = 0; i < sub->num_rects; i++) { - if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_IGNORE && - 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); - ret = AVERROR_INVALIDDATA; - break; - } - } - - if (avpkt->data != pkt_recoded.data) { // did we recode? - /* prevent from destroying side data from original packet */ - pkt_recoded.side_data = NULL; - pkt_recoded.side_data_elems = 0; - - av_packet_unref(&pkt_recoded); + for (unsigned i = 0; i < sub->num_rects; i++) { + if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_IGNORE && + 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); + ret = AVERROR_INVALIDDATA; + break; } } if (*got_sub_ptr) avctx->frame_number++; + + if (pkt == avci->buffer_pkt) // did we recode? + av_packet_unref(avci->buffer_pkt); } return ret; @@ -1471,12 +1509,12 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) switch (avctx->codec_type) { case AVMEDIA_TYPE_VIDEO: { - uint8_t *data[4]; int linesize[4]; - int size[4] = { 0 }; int w = frame->width; int h = frame->height; - int tmpsize, unaligned; + int unaligned; + ptrdiff_t linesize1[4]; + size_t size[4]; avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); @@ -1494,20 +1532,19 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) unaligned |= linesize[i] % pool->stride_align[i]; } while (unaligned); - tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, - NULL, linesize); - if (tmpsize < 0) { - ret = tmpsize; + for (i = 0; i < 4; i++) + linesize1[i] = linesize[i]; + ret = av_image_fill_plane_sizes(size, avctx->pix_fmt, h, linesize1); + if (ret < 0) goto fail; - } - - for (i = 0; i < 3 && data[i + 1]; i++) - size[i] = data[i + 1] - data[i]; - size[i] = tmpsize - (data[i] - data[0]); for (i = 0; i < 4; i++) { pool->linesize[i] = linesize[i]; if (size[i]) { + if (size[i] > INT_MAX - (16 + STRIDE_ALIGN - 1)) { + ret = AVERROR(EINVAL); + goto fail; + } pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, CONFIG_MEMORY_POISONING ? NULL : @@ -1672,7 +1709,7 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame) { - int size; + buffer_size_t size; const uint8_t *side_metadata; AVDictionary **frame_md = &frame->metadata; @@ -1684,8 +1721,7 @@ static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame) int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { - const AVPacket *pkt = avctx->internal->last_pkt_props; - int i; + AVPacket *pkt = avctx->internal->last_pkt_props; static const struct { enum AVPacketSideDataType packet; enum AVFrameSideDataType frame; @@ -1699,39 +1735,42 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { AV_PKT_DATA_CONTENT_LIGHT_LEVEL, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL }, { AV_PKT_DATA_A53_CC, AV_FRAME_DATA_A53_CC }, { AV_PKT_DATA_ICC_PROFILE, AV_FRAME_DATA_ICC_PROFILE }, + { AV_PKT_DATA_S12M_TIMECODE, AV_FRAME_DATA_S12M_TIMECODE }, }; - if (pkt) { - frame->pts = pkt->pts; + if (IS_EMPTY(pkt) && av_fifo_size(avctx->internal->pkt_props) >= sizeof(*pkt)) + av_fifo_generic_read(avctx->internal->pkt_props, + pkt, sizeof(*pkt), NULL); + + frame->pts = pkt->pts; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = pkt->pts; + frame->pkt_pts = pkt->pts; FF_ENABLE_DEPRECATION_WARNINGS #endif - frame->pkt_pos = pkt->pos; - frame->pkt_duration = pkt->duration; - frame->pkt_size = pkt->size; + frame->pkt_pos = pkt->pos; + frame->pkt_duration = pkt->duration; + frame->pkt_size = pkt->size; - for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) { - int size; - uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); - if (packet_sd) { - AVFrameSideData *frame_sd = av_frame_new_side_data(frame, - sd[i].frame, - size); - if (!frame_sd) - return AVERROR(ENOMEM); + for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) { + buffer_size_t size; + uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); + if (packet_sd) { + AVFrameSideData *frame_sd = av_frame_new_side_data(frame, + sd[i].frame, + size); + if (!frame_sd) + return AVERROR(ENOMEM); - memcpy(frame_sd->data, packet_sd, size); - } + memcpy(frame_sd->data, packet_sd, size); } - add_metadata_from_side_data(pkt, frame); + } + add_metadata_from_side_data(pkt, frame); - if (pkt->flags & AV_PKT_FLAG_DISCARD) { - frame->flags |= AV_FRAME_FLAG_DISCARD; - } else { - frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); - } + if (pkt->flags & AV_PKT_FLAG_DISCARD) { + frame->flags |= AV_FRAME_FLAG_DISCARD; + } else { + frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); } frame->reordered_opaque = avctx->reordered_opaque; @@ -1965,3 +2004,50 @@ int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } + +int ff_decode_preinit(AVCodecContext *avctx) +{ + int ret = 0; + + /* if the decoder init function was already called previously, + * free the already allocated subtitle_header before overwriting it */ + av_freep(&avctx->subtitle_header); + +#if FF_API_THREAD_SAFE_CALLBACKS +FF_DISABLE_DEPRECATION_WARNINGS + if ((avctx->thread_type & FF_THREAD_FRAME) && + avctx->get_buffer2 != avcodec_default_get_buffer2 && + !avctx->thread_safe_callbacks) { + av_log(avctx, AV_LOG_WARNING, "Requested frame threading with a " + "custom get_buffer2() implementation which is not marked as " + "thread safe. This is not supported anymore, make your " + "callback thread-safe.\n"); + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) { + av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n", + avctx->codec->max_lowres); + avctx->lowres = avctx->codec->max_lowres; + } + + avctx->pts_correction_num_faulty_pts = + avctx->pts_correction_num_faulty_dts = 0; + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; + + if ( !CONFIG_GRAY && avctx->flags & AV_CODEC_FLAG_GRAY + && avctx->codec_descriptor->type == AVMEDIA_TYPE_VIDEO) + av_log(avctx, AV_LOG_WARNING, + "gray decoding requested but not enabled at configuration time\n"); + if (avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS) { + avctx->export_side_data |= AV_CODEC_EXPORT_DATA_MVS; + } + + ret = decode_bsfs_init(avctx); + if (ret < 0) + return ret; + + return 0; +} diff --git a/libavcodec/decode.h b/libavcodec/decode.h index 5565346f9..1467b1eb3 100644 --- a/libavcodec/decode.h +++ b/libavcodec/decode.h @@ -65,10 +65,9 @@ typedef struct FrameDecodeData { int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); /** - * Called during avcodec_open2() to initialize avctx->internal->bsf. - * The bsf should be freed with av_bsf_free(). + * Set various frame properties from the codec context / packet data. */ -int ff_decode_bsfs_init(AVCodecContext *avctx); +int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame); /** * Make sure avctx.hw_frames_ctx is set. If it's not set, the function will @@ -80,4 +79,10 @@ int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, int ff_attach_decode_data(AVFrame *frame); +/** + * Perform decoder initialization and validation. + * Called when opening the decoder, before the AVCodec.init() call. + */ +int ff_decode_preinit(AVCodecContext *avctx); + #endif /* AVCODEC_DECODE_H */ diff --git a/libavcodec/dirac_arith.c b/libavcodec/dirac_arith.c index 36142fe19..69b628023 100644 --- a/libavcodec/dirac_arith.c +++ b/libavcodec/dirac_arith.c @@ -28,7 +28,7 @@ #include "dirac_arith.h" -const uint16_t ff_dirac_prob[256] = { +static const uint16_t dirac_prob[256] = { 0, 2, 5, 8, 11, 15, 20, 24, 29, 35, 41, 47, 53, 60, 67, 74, 82, 89, 97, 106, 114, 123, 132, 141, @@ -88,8 +88,8 @@ av_cold void ff_dirac_init_arith_tables(void) int i; for (i = 0; i < 256; i++) { - ff_dirac_prob_branchless[i][0] = ff_dirac_prob[255-i]; - ff_dirac_prob_branchless[i][1] = -ff_dirac_prob[i]; + ff_dirac_prob_branchless[i][0] = dirac_prob[255-i]; + ff_dirac_prob_branchless[i][1] = -dirac_prob[i]; } } diff --git a/libavcodec/dirac_arith.h b/libavcodec/dirac_arith.h index 79526a7ca..350a58fca 100644 --- a/libavcodec/dirac_arith.h +++ b/libavcodec/dirac_arith.h @@ -86,7 +86,6 @@ typedef struct { } DiracArith; extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT]; -extern const uint16_t ff_dirac_prob[256]; extern int16_t ff_dirac_prob_branchless[256][2]; static inline void renorm(DiracArith *c) diff --git a/libavcodec/dirac_vlc.c b/libavcodec/dirac_vlc.c index 2e2fa7ea6..c5a0371da 100644 --- a/libavcodec/dirac_vlc.c +++ b/libavcodec/dirac_vlc.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mem_internal.h" + #include "dirac_vlc.h" enum { @@ -43,7 +45,7 @@ typedef struct LUTState { uint16_t state; /* Expected state for the next byte */ } LUTState; -const DECLARE_ALIGNED(32, LUTState, ff_dirac_golomb_lut)[1024] = { +static const DECLARE_ALIGNED(32, LUTState, dirac_golomb_lut)[1024] = { { +16, 0, 0, 0, 0, 5, +1, 0, 0, STATE_FOLLOW }, { +17, 0, 0, 0, 0, 5, +1, 0, 0, STATE_FOLLOW }, { +8, 0, 0, 0, 0, 4, +1, 1, 0, STATE_START }, @@ -1087,13 +1089,13 @@ const DECLARE_ALIGNED(32, LUTState, ff_dirac_golomb_lut)[1024] = { dst += lut.num; \ if (dst >= last) \ return coeffs; \ - lut = ff_dirac_golomb_lut[lut.state + *buf++]; \ + lut = dirac_golomb_lut[lut.state + *buf++]; \ } while (0) int ff_dirac_golomb_read_16bit(const uint8_t *buf, int bytes, uint8_t *_dst, int coeffs) { - LUTState lut = ff_dirac_golomb_lut[*buf++]; + LUTState lut = dirac_golomb_lut[*buf++]; int16_t *dst = (int16_t *)_dst, *last = dst + coeffs; uint16_t val = 0; @@ -1113,7 +1115,7 @@ int ff_dirac_golomb_read_16bit(const uint8_t *buf, int bytes, int ff_dirac_golomb_read_32bit(const uint8_t *buf, int bytes, uint8_t *_dst, int coeffs) { - LUTState lut = ff_dirac_golomb_lut[*buf++]; + LUTState lut = dirac_golomb_lut[*buf++]; int32_t *dst = (int32_t *)_dst, *last = dst + coeffs; uint32_t val = 0; diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index ed42bc366..b9999cde0 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -26,6 +26,7 @@ * @author Marco Gerards , David Conrad, Jordi Ortiz */ +#include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "libavutil/thread.h" #include "avcodec.h" diff --git a/libavcodec/diracdsp.c b/libavcodec/diracdsp.c index 4e08d3817..80dfafd78 100644 --- a/libavcodec/diracdsp.c +++ b/libavcodec/diracdsp.c @@ -195,7 +195,7 @@ static void dequant_subband_ ## PX ## _c(uint8_t *src, uint8_t *dst, ptrdiff_t s { \ int i, y; \ for (y = 0; y < tot_v; y++) { \ - PX c, sign, *src_r = (PX *)src, *dst_r = (PX *)dst; \ + PX c, *src_r = (PX *)src, *dst_r = (PX *)dst; \ for (i = 0; i < tot_h; i++) { \ c = *src_r++; \ if (c < 0) c = -((-(unsigned)c*qf + qs) >> 2); \ diff --git a/libavcodec/dnxhddata.c b/libavcodec/dnxhddata.c index 154be8986..3a69a0f50 100644 --- a/libavcodec/dnxhddata.c +++ b/libavcodec/dnxhddata.c @@ -932,7 +932,7 @@ static const uint8_t dnxhd_1250_run[62] = { 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, }; -const CIDEntry ff_dnxhd_cid_table[] = { +static const CIDEntry dnxhd_cid_table[] = { { 1235, 1920, 1080, 917504, 917504, 0, 6, 10, 4, dnxhd_1235_luma_weight, dnxhd_1235_chroma_weight, @@ -1075,31 +1075,31 @@ const CIDEntry ff_dnxhd_cid_table[] = { { 0 }, { 5888, 255} }, }; -int ff_dnxhd_get_cid_table(int cid) +const CIDEntry *ff_dnxhd_get_cid_table(int cid) { - int i; - for (i = 0; i < FF_ARRAY_ELEMS(ff_dnxhd_cid_table); i++) - if (ff_dnxhd_cid_table[i].cid == cid) - return i; - return -1; + for (int i = 0; i < FF_ARRAY_ELEMS(dnxhd_cid_table); i++) + if (dnxhd_cid_table[i].cid == cid) + return &dnxhd_cid_table[i]; + return NULL; } int avpriv_dnxhd_get_frame_size(int cid) { - int i = ff_dnxhd_get_cid_table(cid); - if (i<0) - return i; - return ff_dnxhd_cid_table[i].frame_size; + const CIDEntry *entry = ff_dnxhd_get_cid_table(cid); + if (!entry) + return -1; + return entry->frame_size; } int avpriv_dnxhd_get_hr_frame_size(int cid, int w, int h) { - int result, i = ff_dnxhd_get_cid_table(cid); + const CIDEntry *entry = ff_dnxhd_get_cid_table(cid); + int result; - if (i < 0) - return i; + if (!entry) + return -1; - result = ((h + 15) / 16) * ((w + 15) / 16) * (int64_t)ff_dnxhd_cid_table[i].packet_scale.num / ff_dnxhd_cid_table[i].packet_scale.den; + result = ((h + 15) / 16) * ((w + 15) / 16) * (int64_t)entry->packet_scale.num / entry->packet_scale.den; result = (result + 2048) / 4096 * 4096; return FFMAX(result, 8192); @@ -1107,10 +1107,10 @@ int avpriv_dnxhd_get_hr_frame_size(int cid, int w, int h) int avpriv_dnxhd_get_interlaced(int cid) { - int i = ff_dnxhd_get_cid_table(cid); - if (i < 0) - return i; - return ff_dnxhd_cid_table[i].flags & DNXHD_INTERLACED ? 1 : 0; + const CIDEntry *entry = ff_dnxhd_get_cid_table(cid); + if (!entry) + return -1; + return entry->flags & DNXHD_INTERLACED ? 1 : 0; } static int dnxhd_find_hr_cid(AVCodecContext *avctx) @@ -1140,8 +1140,8 @@ int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth) if (!mbs) return 0; - for (i = 0; i < FF_ARRAY_ELEMS(ff_dnxhd_cid_table); i++) { - const CIDEntry *cid = &ff_dnxhd_cid_table[i]; + for (i = 0; i < FF_ARRAY_ELEMS(dnxhd_cid_table); i++) { + const CIDEntry *cid = &dnxhd_cid_table[i]; int interlaced = cid->flags & DNXHD_INTERLACED ? 1 : 0; if (cid->width == avctx->width && cid->height == avctx->height && interlaced == !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) && @@ -1163,8 +1163,8 @@ int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth) void ff_dnxhd_print_profiles(AVCodecContext *avctx, int loglevel) { int i, j; - for (i = 0; i < FF_ARRAY_ELEMS(ff_dnxhd_cid_table); i++) { - const CIDEntry *cid = &ff_dnxhd_cid_table[i]; + for (i = 0; i < FF_ARRAY_ELEMS(dnxhd_cid_table); i++) { + const CIDEntry *cid = &dnxhd_cid_table[i]; for (j = 0; j < FF_ARRAY_ELEMS(cid->bit_rates); j++) { if (!cid->bit_rates[j]) break; diff --git a/libavcodec/dnxhddata.h b/libavcodec/dnxhddata.h index cfa6b0c99..898079cff 100644 --- a/libavcodec/dnxhddata.h +++ b/libavcodec/dnxhddata.h @@ -58,9 +58,7 @@ typedef struct CIDEntry { AVRational packet_scale; } CIDEntry; -extern const CIDEntry ff_dnxhd_cid_table[]; - -int ff_dnxhd_get_cid_table(int cid); +const CIDEntry *ff_dnxhd_get_cid_table(int cid); int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth); void ff_dnxhd_print_profiles(AVCodecContext *avctx, int loglevel); diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index e5d01e2e7..c78d55aee 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -25,6 +25,8 @@ */ #include "libavutil/imgutils.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "blockdsp.h" #define UNCHECKED_BITSTREAM_READER 1 @@ -111,18 +113,19 @@ static av_cold int dnxhd_decode_init(AVCodecContext *avctx) static int dnxhd_init_vlc(DNXHDContext *ctx, uint32_t cid, int bitdepth) { if (cid != ctx->cid) { - int index; + const CIDEntry *cid_table = ff_dnxhd_get_cid_table(cid); - if ((index = ff_dnxhd_get_cid_table(cid)) < 0) { + if (!cid_table) { av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %"PRIu32"\n", cid); return AVERROR(ENOSYS); } - if (ff_dnxhd_cid_table[index].bit_depth != bitdepth && - ff_dnxhd_cid_table[index].bit_depth != DNXHD_VARIABLE) { - av_log(ctx->avctx, AV_LOG_ERROR, "bit depth mismatches %d %d\n", ff_dnxhd_cid_table[index].bit_depth, bitdepth); + if (cid_table->bit_depth != bitdepth && + cid_table->bit_depth != DNXHD_VARIABLE) { + av_log(ctx->avctx, AV_LOG_ERROR, "bit depth mismatches %d %d\n", + cid_table->bit_depth, bitdepth); return AVERROR_INVALIDDATA; } - ctx->cid_table = &ff_dnxhd_cid_table[index]; + ctx->cid_table = cid_table; av_log(ctx->avctx, AV_LOG_VERBOSE, "Profile cid %"PRIu32".\n", cid); ff_free_vlc(&ctx->ac_vlc); diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 5d5f1ffc0..2461c5172 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -25,6 +25,7 @@ #include "libavutil/attributes.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "avcodec.h" @@ -207,15 +208,11 @@ static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx) int i, j, level, run; int max_level = 1 << (ctx->bit_depth + 2); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->orig_vlc_codes, - max_level, 4 * sizeof(*ctx->orig_vlc_codes), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->orig_vlc_bits, - max_level, 4 * sizeof(*ctx->orig_vlc_bits), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_codes, - 63 * 2, fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_bits, - 63, fail); - + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->orig_vlc_codes, max_level * 4) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->orig_vlc_bits, max_level * 4) || + !(ctx->run_codes = av_mallocz(63 * 2)) || + !(ctx->run_bits = av_mallocz(63))) + return AVERROR(ENOMEM); ctx->vlc_codes = ctx->orig_vlc_codes + max_level * 2; ctx->vlc_bits = ctx->orig_vlc_bits + max_level * 2; for (level = -max_level; level < max_level; level++) { @@ -259,8 +256,6 @@ static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx) ctx->run_bits[run] = ctx->cid_table->run_bits[i]; } return 0; -fail: - return AVERROR(ENOMEM); } static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) @@ -271,16 +266,11 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) const uint8_t *luma_weight_table = ctx->cid_table->luma_weight; const uint8_t *chroma_weight_table = ctx->cid_table->chroma_weight; - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l, - (ctx->m.avctx->qmax + 1), 64 * sizeof(int), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c, - (ctx->m.avctx->qmax + 1), 64 * sizeof(int), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l16, - (ctx->m.avctx->qmax + 1), 64 * 2 * sizeof(uint16_t), - fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c16, - (ctx->m.avctx->qmax + 1), 64 * 2 * sizeof(uint16_t), - fail); + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l, ctx->m.avctx->qmax + 1) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c, ctx->m.avctx->qmax + 1) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l16, ctx->m.avctx->qmax + 1) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c16, ctx->m.avctx->qmax + 1)) + return AVERROR(ENOMEM); if (ctx->bit_depth == 8) { for (i = 1; i < 64; i++) { @@ -339,33 +329,29 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) ctx->m.q_intra_matrix = ctx->qmatrix_l; return 0; -fail: - return AVERROR(ENOMEM); } static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx) { - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_rc, (ctx->m.avctx->qmax + 1), - ctx->m.mb_num * sizeof(RCEntry), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_rc, (ctx->m.avctx->qmax + 1) * ctx->m.mb_num)) + return AVERROR(ENOMEM); + if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) { - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_cmp, - ctx->m.mb_num, sizeof(RCCMPEntry), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_cmp_tmp, - ctx->m.mb_num, sizeof(RCCMPEntry), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp, ctx->m.mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp_tmp, ctx->m.mb_num)) + return AVERROR(ENOMEM); } ctx->frame_bits = (ctx->coding_unit_size - ctx->data_offset - 4 - ctx->min_padding) * 8; ctx->qscale = 1; ctx->lambda = 2 << LAMBDA_FRAC_BITS; // qscale 2 return 0; -fail: - return AVERROR(ENOMEM); } static av_cold int dnxhd_encode_init(AVCodecContext *avctx) { DNXHDEncContext *ctx = avctx->priv_data; - int i, index, ret; + int i, ret; switch (avctx->pix_fmt) { case AV_PIX_FMT_YUV422P: @@ -425,10 +411,8 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - index = ff_dnxhd_get_cid_table(ctx->cid); - av_assert0(index >= 0); - - ctx->cid_table = &ff_dnxhd_cid_table[index]; + ctx->cid_table = ff_dnxhd_get_cid_table(ctx->cid); + av_assert0(ctx->cid_table); ctx->m.avctx = avctx; ctx->m.mb_intra = 1; @@ -510,15 +494,11 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) if ((ret = dnxhd_init_rc(ctx)) < 0) return ret; - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_size, - ctx->m.mb_height * sizeof(uint32_t), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_offs, - ctx->m.mb_height * sizeof(uint32_t), fail); - 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); - + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->slice_size, ctx->m.mb_height) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->slice_offs, ctx->m.mb_height) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_bits, ctx->m.mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_qscale, ctx->m.mb_num)) + return AVERROR(ENOMEM); #if FF_API_CODED_FRAME FF_DISABLE_DEPRECATION_WARNINGS avctx->coded_frame->key_frame = 1; @@ -543,14 +523,12 @@ FF_ENABLE_DEPRECATION_WARNINGS for (i = 1; i < avctx->thread_count; i++) { ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext)); if (!ctx->thread[i]) - goto fail; + return AVERROR(ENOMEM); memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext)); } } return 0; -fail: // for FF_ALLOCZ_OR_GOTO - return AVERROR(ENOMEM); } static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h index 7b0d862e2..9e4c869bc 100644 --- a/libavcodec/dnxhdenc.h +++ b/libavcodec/dnxhdenc.h @@ -28,6 +28,8 @@ #include "config.h" +#include "libavutil/mem_internal.h" + #include "mpegvideo.h" #include "dnxhddata.h" diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c index 429612ec0..ecb2f4802 100644 --- a/libavcodec/dolby_e.c +++ b/libavcodec/dolby_e.c @@ -21,13 +21,586 @@ #include "libavutil/float_dsp.h" #include "libavutil/thread.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "internal.h" #include "get_bits.h" -#include "put_bits.h" #include "dolby_e.h" +#include "kbdwin.h" #include "fft.h" +#define MAX_SEGMENTS 2 + +#define MAX_GROUPS 8 +#define MAX_EXPONENTS 304 +#define MAX_MANTISSAS 1024 + +#define MAX_MSTR_EXP 2 +#define MAX_BIAS_EXP 50 + +typedef struct DBEGroup { + uint8_t nb_exponent; + uint8_t nb_bias_exp[MAX_MSTR_EXP]; + uint16_t exp_ofs; + uint16_t mnt_ofs; + const uint8_t *nb_mantissa; + uint8_t imdct_idx; + uint8_t imdct_phs; + uint16_t win_len; + uint16_t dst_ofs; + uint16_t win_ofs; + uint16_t src_ofs; +} DBEGroup; + +typedef struct DBEChannel { + int gr_code; + int bw_code; + + int nb_groups; + int nb_mstr_exp; + DBEGroup groups[MAX_GROUPS]; + + int exp_strategy[MAX_GROUPS]; + int exponents[MAX_EXPONENTS]; + int bap[MAX_EXPONENTS]; + int idx[MAX_EXPONENTS]; + + DECLARE_ALIGNED(32, float, mantissas)[MAX_MANTISSAS]; +} DBEChannel; + +typedef struct DBEDecodeContext { + AVCodecContext *avctx; + DBEContext dectx; + + DBEChannel channels[MAX_SEGMENTS][MAX_CHANNELS]; + + DECLARE_ALIGNED(32, float, history)[MAX_CHANNELS][256]; + + FFTContext imdct[3]; + AVFloatDSPContext *fdsp; +} DBEDecodeContext; + +static const int8_t lfe_channel_tab[MAX_PROG_CONF + 1] = { + 5, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5 +}; + +static const uint8_t ch_reorder_4[4] = { 0, 2, 1, 3 }; +static const uint8_t ch_reorder_6[6] = { 0, 2, 4, 1, 3, 5 }; +static const uint8_t ch_reorder_8[8] = { 0, 2, 6, 4, 1, 3, 7, 5 }; +static const uint8_t ch_reorder_n[8] = { 0, 2, 4, 6, 1, 3, 5, 7 }; + + +static const uint8_t nb_groups_tab[4] = { 1, 8, 7, 1 }; + +static const uint8_t nb_mstr_exp_tab[4] = { 2, 2, 2, 1 }; + +static const uint8_t nb_mantissa_38[38] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, + 7, 8, 9, 10, 11, 12, +}; + +static const uint8_t nb_mantissa_44[44] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, + 8, 9, 10, 11, 12, 13, 15, 16, 18, 20, 22, 25, +}; + +static const uint8_t nb_mantissa_50[50] = { + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, + 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 12, 13, 14, 16, + 18, 19, 22, 24, 27, 29, 32, 36, 40, 44, 49, 54, 60, 66, 74, 82, + 90, 100, +}; + +static const uint8_t imdct_bits_tab[3] = { 8, 9, 11 }; + +static const DBEGroup grp_tab_0[1] = { + { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 }, +}; + +static const DBEGroup grp_tab_1[8] = { + { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 }, + { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 }, + { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 }, + { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, + { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, + { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, + { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 704, 0, 0 }, + { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 1, 256, 832, 0, 0 }, +}; + +static const DBEGroup grp_tab_2[7] = { + { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 }, + { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 }, + { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 }, + { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, + { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, + { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, + { 44, { 19, 25 }, 228, 768, nb_mantissa_44, 1, 1, 448, 704, 960, 64 }, +}; + +static const DBEGroup grp_tab_3[1] = { + { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 }, +}; + +static const DBEGroup grp_tab_4[1] = { + { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 }, +}; + +static const DBEGroup grp_tab_5[8] = { + { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 1, 256, 64, 0, 0 }, + { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 192, 0, 0 }, + { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, + { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, + { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, + { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 }, + { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 }, + { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 }, +}; + +static const DBEGroup grp_tab_6[7] = { + { 44, { 19, 25 }, 0, 0, nb_mantissa_44, 1, 1, 448, 0, 3264, 0 }, + { 38, { 12, 26 }, 44, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, + { 38, { 12, 26 }, 82, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, + { 38, { 12, 26 }, 120, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, + { 38, { 12, 26 }, 158, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 }, + { 38, { 12, 26 }, 196, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 }, + { 38, { 12, 26 }, 234, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 }, +}; + +static const DBEGroup grp_tab_7[1] = { + { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 }, +}; + +static const DBEGroup *const frm_ofs_tab[2][4] = { + { grp_tab_0, grp_tab_1, grp_tab_2, grp_tab_3 }, + { grp_tab_4, grp_tab_5, grp_tab_6, grp_tab_7 } +}; + +static const uint8_t mantissa_size1[16][4] = { + { 0, 0, 0, 0 }, { 2, 1, 1, 1 }, { 3, 2, 1, 1 }, { 4, 3, 2, 1 }, + { 5, 4, 3, 2 }, { 6, 5, 4, 3 }, { 7, 6, 5, 4 }, { 8, 7, 6, 5 }, + { 9, 8, 7, 6 }, { 10, 9, 8, 7 }, { 11, 10, 9, 8 }, { 12, 11, 10, 9 }, + { 13, 12, 11, 10 }, { 14, 13, 12, 11 }, { 15, 14, 13, 12 }, { 16, 15, 14, 13 }, +}; + +static const uint8_t mantissa_size2[16][4] = { + { 0, 0, 0, 0 }, { 2, 1, 2, 2 }, { 3, 2, 3, 3 }, { 4, 3, 4, 4 }, + { 5, 4, 5, 5 }, { 6, 5, 6, 6 }, { 7, 6, 7, 7 }, { 8, 7, 8, 8 }, + { 9, 8, 9, 9 }, { 10, 9, 10, 10 }, { 11, 10, 11, 11 }, { 12, 11, 12, 12 }, + { 13, 12, 13, 13 }, { 14, 13, 14, 14 }, { 15, 14, 15, 15 }, { 16, 15, 16, 16 }, +}; + +static const float start_window[192] = { + 0.00161569379826, 0.00185748233347, 0.00198562758548, 0.00207834078104, + 0.00215717748523, 0.00223067096393, 0.00230299213147, 0.00237651215396, + 0.00245275561606, 0.00253281402069, 0.00261754673613, 0.00270768786168, + 0.00280390761895, 0.00290684998656, 0.00301715751161, 0.00313548872798, + 0.00326253122934, 0.00339901215995, 0.00354570716636, 0.00370344845023, + 0.00387313232586, 0.00405572653911, 0.00425227750970, 0.00446391759265, + 0.00469187240551, 0.00493746822816, 0.00520213944619, 0.00548743597507, + 0.00579503056737, 0.00612672586953, 0.00648446105606, 0.00687031782873, + 0.00728652552677, 0.00773546505205, 0.00821967127415, 0.00874183354619, + 0.00930479393832, 0.00991154278653, 0.01056521116692, 0.01126905994567, + 0.01202646513050, 0.01284089936559, 0.01371590957417, 0.01465509096066, + 0.01566205783408, 0.01674041199523, 0.01789370972358, 0.01912542867865, + 0.02043893626265, 0.02183746113793, 0.02332406961796, 0.02490164852364, + 0.02657289580178, 0.02834031974193, 0.03020624702903, 0.03217283918354, + 0.03424211623810, 0.03641598586180, 0.03869627565015, 0.04108476601498, + 0.04358322107390, 0.04619341515939, 0.04891715301882, 0.05175628239149, + + 0.05471237327267, 0.05778734733755, 0.06098291402413, 0.06430101352084, + 0.06774345212186, 0.07131188644726, 0.07500780649199, 0.07883251748595, + 0.08278712056651, 0.08687249228061, 0.09108926295730, 0.09543779401074, + 0.09991815425851, 0.10453009536427, 0.10927302653894, 0.11414598865987, + 0.11914762799220, 0.12427616972097, 0.12952939152560, 0.13490459744934, + 0.14039859233595, 0.14600765712201, 0.15172752528722, 0.15755336077528, + 0.16347973770491, 0.16950062219342, 0.17560935661442, 0.18179864660619, + 0.18806055113821, 0.19438647593012, 0.20076717050010, 0.20719272909882, + 0.21365259576030, 0.22013557367283, 0.22662983904194, 0.23312295958328, + 0.23960191774666, 0.24605313873388, 0.25246252333253, 0.25881548554631, + 0.26509699495987, 0.27129162373316, 0.27738359807707, 0.28335685401987, + 0.28919509723179, 0.29488186663467, 0.30040060148455, 0.30573471157819, + 0.31086765019993, 0.31578298939317, 0.32046449711227, 0.32489621578468, + 0.32906254179156, 0.33294830535654, 0.33653885031840, 0.33982011325336, + 0.34277870140679, 0.34540196889300, 0.34767809062480, 0.34959613344194, + 0.35114612391958, 0.35231911235422, 0.35310723244504, 0.35350375621308, + + 0.35350314372945, 0.35310108725579, 0.35229454943591, 0.35108179521634, + 0.34946241721522, 0.34743735430290, 0.34500890320420, 0.34218072298001, + 0.33895783229541, 0.33534659943168, 0.33135472505060, 0.32699121776996, + 0.32226636266000, 0.31719168282019, 0.31177989424432, 0.30604485422875, + 0.30000150362379, 0.29366580327088, 0.28705466500775, 0.28018587766131, + 0.27307802848095, 0.26575042049535, 0.25822298630189, 0.25051619882000, + 0.24265097955783, 0.23464860495522, 0.22653061137548, 0.21831869932335, + 0.21003463746705, 0.20170016703857, 0.19333690717811, 0.18496626177620, + 0.17660932835062, 0.16828680947474, 0.16001892724986, 0.15182534128597, + 0.14372507062477, 0.13573642000364, 0.12787691082233, 0.12016321713317, + 0.11261110693234, 0.10523538898282, 0.09804986534955, 0.09106728977263, + 0.08429933194438, 0.07775654768810, 0.07144835495683, 0.06538301547324, + 0.05956762170687, 0.05400808871425, 0.04870915012107, 0.04367435714993, + 0.03890607899172, 0.03440550179663, 0.03017262174627, 0.02620622428513, + 0.02250383492507, 0.01906161305732, 0.01587412848221, 0.01293388032354, + 0.01023019677288, 0.00774641320626, 0.00545109736891, 0.00325868651263, +}; + +static const float short_window2[192] = { + 0.00018861094606, 0.00033433010202, 0.00050309624485, 0.00070306161748, + 0.00093995174533, 0.00121913067128, 0.00154606505568, 0.00192647806126, + 0.00236641248692, 0.00287225985240, 0.00345077377440, 0.00410907465023, + 0.00485464855241, 0.00569534163219, 0.00663935063508, 0.00769520981249, + 0.00887177436246, 0.01017820046395, 0.01162392194150, 0.01321862359335, + 0.01497221122468, 0.01689477844427, 0.01899657030441, 0.02128794388846, + 0.02377932597692, 0.02648116795039, 0.02940389811590, 0.03255787167130, + 0.03595331854986, 0.03960028941437, 0.04350860009563, 0.04768777479454, + 0.05214698838949, 0.05689500821121, 0.06194013566525, 0.06729014809766, + 0.07295224131210, 0.07893297315602, 0.08523820859989, 0.09187306673620, + 0.09884187012422, 0.10614809690222, 0.11379433608064, 0.12178224641797, + 0.13011251926531, 0.13878484574660, 0.14779788861830, 0.15714925912610, + 0.16683549914631, 0.17685206886673, 0.18719334022589, 0.19785259629099, + 0.20882203671372, 0.22009278936030, 0.23165492816694, 0.24349749722585, + 0.25560854105961, 0.26797514099368, 0.28058345748882, 0.29341877824732, + 0.30646557185942, 0.31970754671026, 0.33312771482295, 0.34670846027024, + + 0.36043161174692, 0.37427851885723, 0.38823013163645, 0.40226708279486, + 0.41636977214436, 0.43051845264462, 0.44469331748632, 0.45887458761470, + 0.47304259908636, 0.48717788964798, 0.50126128392546, 0.51527397661778, + 0.52919761310050, 0.54301436685998, 0.55670701320069, 0.57025899869448, + 0.58365450587230, 0.59687851269542, 0.60991684638414, 0.62275623122793, + 0.63538433005035, 0.64778977905593, 0.65996221584264, 0.67189230042379, + 0.68357172916486, 0.69499324160511, 0.70615062019861, 0.71703868307548, + 0.72765326998919, 0.73799122168099, 0.74805035295521, 0.75782941981995, + 0.76732808110520, 0.77654685502339, 0.78548707118622, 0.79415081863423, + 0.80254089047207, 0.81066072573188, 0.81851434910893, 0.82610630922734, + 0.83344161609862, 0.84052567843230, 0.84736424144524, 0.85396332579459, + 0.86032916822973, 0.86646816451999, 0.87238681516918, 0.87809167437532, + 0.88358930263537, 0.88888622333073, 0.89398888356256, 0.89890361943564, + 0.90363662591861, 0.90819393133744, 0.91258137648979, 0.91680459830070, + 0.92086901787718, 0.92477983276087, 0.92854201312583, 0.93216030163834, + 0.93563921662343, 0.93898305819384, 0.94219591693690, 0.94528168477979, + + 0.94823843319821, 0.95106834367330, 0.95377776558539, 0.95636718335775, + 0.95883679961479, 0.96118650212341, 0.96341583179195, 0.96552395212906, + 0.96750962060547, 0.96937116231768, 0.97110644638309, 0.97271286544154, + 0.97418731862798, 0.97552619834964, 0.97672538116257, 0.97778022299974, + 0.97868555895586, 0.97943570778357, 0.98002448120255, 0.98044519806866, + 0.98069070339493, 0.98075339216123, 0.98062523779637, 0.98029782516478, + 0.97976238784222, 0.97900984942031, 0.97803086854002, 0.97681588731895, + 0.97535518280755, 0.97363892108474, 0.97165721358452, 0.96940017523145, + 0.96685798395452, 0.96402094114589, 0.96087953263194, 0.95742448973047, + 0.95364684997699, 0.94953801711660, 0.94508981997396, 0.94029456983253, + 0.93514511597504, 0.92963489905951, 0.92375800202883, 0.91750919827624, + 0.91088399681406, 0.90387868421832, 0.89649036314692, 0.88871698725397, + 0.88055739234735, 0.87201132366062, 0.86307945913336, 0.85376342861693, + 0.84406582894455, 0.83399023482637, 0.82354120554757, 0.81272428745995, + 0.80154601230457, 0.79001389138101, 0.77813640562199, 0.76592299164227, + 0.75338402384395, 0.74053079267526, 0.72737547915460, 0.71393112578527, +}; + +static const float short_window3[64] = { + 0.00326887936450, 0.00550242900936, 0.00786846643791, 0.01045683453520, + 0.01330402120132, 0.01643221072863, 0.01985798040609, 0.02359509464766, + 0.02765559221954, 0.03205025893128, 0.03678884369614, 0.04188015679495, + 0.04733210987781, 0.05315172583924, 0.05934513287609, 0.06591755045290, + 0.07287327156378, 0.08021564389822, 0.08794705152307, 0.09606889811179, + 0.10458159240070, 0.11348453632940, 0.12277611617809, 0.13245369691511, + 0.14251361989876, 0.15295120402567, 0.16376075037904, 0.17493555039885, + 0.18646789757072, 0.19834910260891, 0.21056951208995, 0.22311853047787, + 0.23598464546683, 0.24915545655419, 0.26261770674500, 0.27635731727778, + 0.29035942525136, 0.30460842402318, 0.31908800624032, 0.33378120935681, + 0.34867046348260, 0.36373764140285, 0.37896411059909, 0.39433078709788, + 0.40981819096657, 0.42540650327031, 0.44107562429959, 0.45680523287270, + 0.47257484651351, 0.48836388230077, 0.50415171818214, 0.51991775454258, + 0.53564147581496, 0.55130251191887, 0.56688069931047, 0.58235614142007, + 0.59770926827271, 0.61292089506118, 0.62797227945823, 0.64284517745255, + 0.65752189749349, 0.67198535273209, 0.68621911114984, 0.70020744337099, +}; + +static const uint8_t dc_code_tab[5] = { 0, 0, 0, 1, 1 }; + +static const uint8_t ht_code_tab[5] = { 0, 0, 1, 2, 2 }; + +static const uint8_t band_ofs_tab[3][4] = { + { 12, 8, 4, 0 }, { 14, 10, 6, 0 }, { 12, 8, 4, 0 } +}; + +static const uint8_t band_low_tab[3] = { 9, 17, 24 }; + +static const uint16_t fast_gain_tab[8] = { + 128, 256, 384, 512, 640, 768, 896, 1024 +}; + +static const uint16_t slow_decay_tab[2][2] = { { 27, -1 }, { 32, 21 } }; + +static const uint16_t misc_decay_tab[3][2][2] = { + { { 354, -1 }, { 425, 425 } }, + { { 266, -1 }, { 320, -1 } }, + { { 213, -1 }, { 256, -1 } } +}; + +static const uint16_t fast_decay_tab[3][2][2][50] = { + {{{ + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + }}, {{ + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, + }, { + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + }}}, {{{ + 266, 266, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, + }}, {{ + 319, 319, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, + }}}, {{{ + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }}, {{ + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }}} +}; + +static const uint16_t fast_gain_adj_tab[3][2][62] = { + {{ + 0, 0, 0, 0, 0, 0, 0, 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, 4, 7, 11, 16, 29, 44, 59, + 76, 94, 116, 142, 179, 221, 252, 285, 312, 334, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 5, 8, 10, 15, 28, 42, 57, 75, 93, + 115, 140, 177, 219, 247, 280, 308, 330, 427, 533, + }}, {{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 5, 8, 12, 21, 35, 51, 69, 89, + 111, 138, 176, 220, 251, 284, 312, 334, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 5, 8, 11, 18, 33, 49, 65, 84, 106, 132, + 168, 214, 245, 279, 308, 329, 427, 533, + }}, {{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 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, 4, 7, 10, 17, + 31, 47, 65, 84, 107, 134, 171, 215, 250, 283, + 312, 334, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 6, 9, 13, 27, 43, + 60, 79, 100, 126, 160, 207, 242, 276, 307, 329, + 427, 533, + }} +}; + +static const uint16_t slow_gain_tab[3][2][50] = { + {{ + 3072, 3072, 3072, 3072, 3072, 3072, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, + }, { + 3072, 3072, 3072, 3072, 3072, 3072, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, + }}, {{ + 3072, 1212, 1212, 1212, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, + }}, {{ + 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }} +}; + +static const uint16_t hearing_thresh_tab[3][3][50] = { + {{ + 1403, 1141, 1000, 959, 948, 957, 946, 925, 899, 871, + 843, 815, 789, 766, 745, 727, 705, 687, 681, 686, + 701, 725, 768, 854, 940, 1018, 1075, 1103, 1111, 1106, + 1098, 1105, 1142, 1237, 1419, 1721, 2169, 2805, + }, { + 1401, 1130, 995, 957, 947, 955, 941, 918, 890, 861, + 831, 803, 777, 754, 734, 717, 698, 684, 682, 692, + 712, 743, 798, 894, 976, 1045, 1091, 1109, 1110, 1102, + 1098, 1116, 1174, 1300, 1526, 1884, 2401, 3072, + }, { + 1393, 1086, 974, 949, 957, 941, 913, 878, 843, 808, + 777, 750, 727, 708, 695, 686, 681, 689, 714, 752, + 811, 888, 971, 1044, 1087, 1108, 1110, 1102, 1098, 1115, + 1172, 1290, 1489, 1812, 2293, 2964, 3072, 3072, + }}, {{ + 1412, 1343, 1141, 1047, 1000, 974, 959, 951, 948, 947, + 957, 953, 946, 936, 925, 906, 878, 850, 822, 795, + 771, 745, 719, 700, 687, 681, 685, 701, 733, 784, + 885, 977, 1047, 1092, 1110, 1108, 1099, 1102, 1138, 1233, + 1413, 1711, 2157, 2797, + }, { + 1412, 1336, 1130, 1040, 995, 970, 957, 950, 947, 947, + 955, 950, 941, 930, 918, 897, 868, 838, 810, 783, + 759, 734, 710, 693, 684, 681, 690, 712, 752, 823, + 924, 1009, 1069, 1102, 1111, 1104, 1098, 1111, 1168, 1295, + 1518, 1873, 2388, 3072, + }, { + 1411, 1293, 1086, 1009, 974, 957, 949, 947, 957, 951, + 941, 928, 913, 896, 878, 852, 817, 785, 756, 732, + 713, 695, 683, 682, 689, 710, 746, 811, 906, 992, + 1061, 1099, 1111, 1106, 1098, 1107, 1155, 1266, 1471, 1799, + 2277, 2945, 3072, 3072, + }}, {{ + 1431, 1412, 1403, 1379, 1343, 1293, 1229, 1180, 1125, 1075, + 1040, 1014, 996, 979, 965, 957, 951, 948, 947, 957, + 951, 940, 924, 903, 877, 846, 815, 785, 753, 725, + 702, 686, 681, 689, 714, 760, 847, 947, 1028, 1083, + 1108, 1109, 1101, 1100, 1132, 1222, 1402, 1705, 2160, 2803, + }, { + 1431, 1412, 1401, 1375, 1336, 1278, 1215, 1168, 1115, 1066, + 1032, 1008, 991, 975, 962, 954, 950, 947, 947, 955, + 948, 935, 916, 894, 866, 835, 803, 772, 742, 715, + 695, 683, 683, 697, 729, 784, 887, 982, 1054, 1096, + 1111, 1106, 1098, 1107, 1159, 1281, 1505, 1865, 2391, 3072, + }, { + 1427, 1411, 1393, 1353, 1293, 1215, 1160, 1118, 1072, 1031, + 1003, 984, 971, 960, 952, 948, 947, 957, 952, 941, + 924, 902, 876, 847, 815, 781, 750, 723, 700, 685, + 681, 691, 719, 766, 858, 958, 1039, 1089, 1109, 1108, + 1099, 1102, 1141, 1245, 1442, 1766, 2250, 2930, 3072, 3072, + }} +}; + +static const int16_t lwc_gain_tab[11][7] = { + { -21, -197, -271, -466, 32767, 32767, 32767 }, + { -197, -29, -244, -271, -540, 32767, 32767 }, + { -271, -244, -29, -249, -271, -593, 32767 }, + { -466, -271, -249, -29, -251, -271, -632 }, + { -540, -271, -251, -29, -251, -271, -664 }, + { -593, -271, -251, -29, -252, -271, -690 }, + { -632, -271, -252, -29, -252, -271, -711 }, + { -664, -271, -252, -29, -252, -271, -730 }, + { -690, -271, -252, -29, -252, -271, -745 }, + { -711, -271, -252, -29, -253, -271, -759 }, + { -730, -271, -253, -29, -253, -271, -771 }, +}; + +static const int16_t lwc_adj_tab[7] = { + -192, -320, -448, -512, -448, -320, -192, +}; + +static const uint8_t log_add_tab[212] = { + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 52, 51, 50, + 49, 48, 47, 47, 46, 45, 44, 44, 43, 42, 41, 41, 40, 39, 38, 38, + 37, 36, 36, 35, 35, 34, 33, 33, 32, 32, 31, 30, 30, 29, 29, 28, + 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 21, + 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, + 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, + 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, +}; + +static const uint8_t bap_tab[64] = { + 0, 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, 6, 7, 7, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, + 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, +}; + +static float mantissa_tab1[17][4]; +static float mantissa_tab2[17][4]; +static float mantissa_tab3[17][4]; +static float exponent_tab[50]; +static float gain_tab[1024]; + +DECLARE_ALIGNED(32, static float, window)[3712]; + static int skip_input(DBEContext *s, int nb_words) { if (nb_words > s->input_size) { @@ -43,7 +616,7 @@ static int skip_input(DBEContext *s, int nb_words) static int parse_key(DBEContext *s) { if (s->key_present) { - uint8_t *key = s->input; + const uint8_t *key = s->input; int ret = skip_input(s, 1); if (ret < 0) return ret; @@ -52,105 +625,11 @@ static int parse_key(DBEContext *s) return 0; } -static int convert_input(DBEContext *s, int nb_words, int key) +static int parse_metadata_ext(DBEDecodeContext *s1) { - uint8_t *src = s->input; - uint8_t *dst = s->buffer; - PutBitContext pb; - int i; - - av_assert0(nb_words <= 1024u); - - if (nb_words > s->input_size) { - av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); - return AVERROR_INVALIDDATA; - } - - switch (s->word_bits) { - case 16: - for (i = 0; i < nb_words; i++, src += 2, dst += 2) - AV_WB16(dst, AV_RB16(src) ^ key); - break; - case 20: - init_put_bits(&pb, s->buffer, sizeof(s->buffer)); - for (i = 0; i < nb_words; i++, src += 3) - put_bits(&pb, 20, AV_RB24(src) >> 4 ^ key); - flush_put_bits(&pb); - break; - case 24: - for (i = 0; i < nb_words; i++, src += 3, dst += 3) - AV_WB24(dst, AV_RB24(src) ^ key); - break; - default: - av_assert0(0); - } - - return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits); -} - -static int parse_metadata(DBEContext *s) -{ - int i, ret, key, mtd_size; - - if ((key = parse_key(s)) < 0) - return key; - if ((ret = convert_input(s, 1, key)) < 0) - return ret; - - skip_bits(&s->gb, 4); - mtd_size = get_bits(&s->gb, 10); - if (!mtd_size) { - av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n"); - return AVERROR_INVALIDDATA; - } - - if ((ret = convert_input(s, mtd_size, key)) < 0) - return ret; - - skip_bits(&s->gb, 14); - s->prog_conf = get_bits(&s->gb, 6); - if (s->prog_conf > MAX_PROG_CONF) { - av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n"); - return AVERROR_INVALIDDATA; - } - - s->nb_channels = nb_channels_tab[s->prog_conf]; - s->nb_programs = nb_programs_tab[s->prog_conf]; - - s->fr_code = get_bits(&s->gb, 4); - s->fr_code_orig = get_bits(&s->gb, 4); - if (!sample_rate_tab[s->fr_code] || - !sample_rate_tab[s->fr_code_orig]) { - av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n"); - return AVERROR_INVALIDDATA; - } - - skip_bits_long(&s->gb, 88); - for (i = 0; i < s->nb_channels; i++) - s->ch_size[i] = get_bits(&s->gb, 10); - s->mtd_ext_size = get_bits(&s->gb, 8); - s->meter_size = get_bits(&s->gb, 8); - - skip_bits_long(&s->gb, 10 * s->nb_programs); - for (i = 0; i < s->nb_channels; i++) { - s->rev_id[i] = get_bits(&s->gb, 4); - skip_bits1(&s->gb); - s->begin_gain[i] = get_bits(&s->gb, 10); - s->end_gain[i] = get_bits(&s->gb, 10); - } - - if (get_bits_left(&s->gb) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n"); - return AVERROR_INVALIDDATA; - } - - return skip_input(s, mtd_size + 1); -} - -static int parse_metadata_ext(DBEContext *s) -{ - if (s->mtd_ext_size) - return skip_input(s, s->key_present + s->mtd_ext_size + 1); + DBEContext *s = &s1->dectx; + if (s->metadata.mtd_ext_size) + return skip_input(s, s->key_present + s->metadata.mtd_ext_size + 1); return 0; } @@ -278,8 +757,9 @@ static void bit_allocate(int nb_exponent, int nb_code, int fr_code, } } -static int parse_bit_alloc(DBEContext *s, DBEChannel *c) +static int parse_bit_alloc(DBEDecodeContext *s1, DBEChannel *c) { + DBEContext *s = &s1->dectx; DBEGroup *p, *g; int bap_strategy[MAX_GROUPS], fg_spc[MAX_GROUPS]; int fg_ofs[MAX_GROUPS], msk_mod[MAX_GROUPS]; @@ -311,7 +791,7 @@ static int parse_bit_alloc(DBEContext *s, DBEChannel *c) for (i = 0, p = NULL, g = c->groups; i < c->nb_groups; i++, p = g, g++) { if (c->exp_strategy[i] || bap_strategy[i]) { - bit_allocate(g->nb_exponent, g->imdct_idx, s->fr_code, + bit_allocate(g->nb_exponent, g->imdct_idx, s->metadata.fr_code, c->exponents + g->exp_ofs, c->bap + g->exp_ofs, fg_spc[i], fg_ofs[i], msk_mod[i], snr_ofs); } else { @@ -411,17 +891,18 @@ static int parse_mantissas(DBEContext *s, DBEChannel *c) return 0; } -static int parse_channel(DBEContext *s, int ch, int seg_id) +static int parse_channel(DBEDecodeContext *s1, int ch, int seg_id) { - DBEChannel *c = &s->channels[seg_id][ch]; + DBEContext *s = &s1->dectx; + DBEChannel *c = &s1->channels[seg_id][ch]; int i, ret; - if (s->rev_id[ch] > 1) { - avpriv_report_missing_feature(s->avctx, "Encoder revision %d", s->rev_id[ch]); + if (s->metadata.rev_id[ch] > 1) { + avpriv_report_missing_feature(s->avctx, "Encoder revision %d", s->metadata.rev_id[ch]); return AVERROR_PATCHWELCOME; } - if (ch == lfe_channel_tab[s->prog_conf]) { + if (ch == lfe_channel_tab[s->metadata.prog_conf]) { c->gr_code = 3; c->bw_code = 29; } else { @@ -446,7 +927,7 @@ static int parse_channel(DBEContext *s, int ch, int seg_id) if ((ret = parse_exponents(s, c)) < 0) return ret; - if ((ret = parse_bit_alloc(s, c)) < 0) + if ((ret = parse_bit_alloc(s1, c)) < 0) return ret; if ((ret = parse_indices(s, c)) < 0) return ret; @@ -461,42 +942,45 @@ static int parse_channel(DBEContext *s, int ch, int seg_id) return 0; } -static int parse_audio(DBEContext *s, int start, int end, int seg_id) +static int parse_audio(DBEDecodeContext *s1, int start, int end, int seg_id) { + DBEContext *s = &s1->dectx; int ch, ret, key; if ((key = parse_key(s)) < 0) return key; for (ch = start; ch < end; ch++) { - if (!s->ch_size[ch]) { - s->channels[seg_id][ch].nb_groups = 0; + if (!s->metadata.ch_size[ch]) { + s1->channels[seg_id][ch].nb_groups = 0; continue; } - if ((ret = convert_input(s, s->ch_size[ch], key)) < 0) + ret = ff_dolby_e_convert_input(s, s->metadata.ch_size[ch], key); + if (ret < 0) return ret; - if ((ret = parse_channel(s, ch, seg_id)) < 0) { - if (s->avctx->err_recognition & AV_EF_EXPLODE) + if ((ret = parse_channel(s1, ch, seg_id)) < 0) { + if (s1->avctx->err_recognition & AV_EF_EXPLODE) return ret; - s->channels[seg_id][ch].nb_groups = 0; + s1->channels[seg_id][ch].nb_groups = 0; } - if ((ret = skip_input(s, s->ch_size[ch])) < 0) + if ((ret = skip_input(s, s->metadata.ch_size[ch])) < 0) return ret; } return skip_input(s, 1); } -static int parse_meter(DBEContext *s) +static int parse_meter(DBEDecodeContext *s1) { - if (s->meter_size) - return skip_input(s, s->key_present + s->meter_size + 1); + DBEContext *s = &s1->dectx; + if (s->metadata.meter_size) + return skip_input(s, s->key_present + s->metadata.meter_size + 1); return 0; } -static void imdct_calc(DBEContext *s, DBEGroup *g, float *result, float *values) +static void imdct_calc(DBEDecodeContext *s1, DBEGroup *g, float *result, float *values) { - FFTContext *imdct = &s->imdct[g->imdct_idx]; + FFTContext *imdct = &s1->imdct[g->imdct_idx]; int n = 1 << imdct_bits_tab[g->imdct_idx]; int n2 = n >> 1; int i; @@ -520,7 +1004,7 @@ static void imdct_calc(DBEContext *s, DBEGroup *g, float *result, float *values) } } -static void transform(DBEContext *s, DBEChannel *c, float *history, float *output) +static void transform(DBEDecodeContext *s1, DBEChannel *c, float *history, float *output) { LOCAL_ALIGNED_32(float, buffer, [2048]); LOCAL_ALIGNED_32(float, result, [1152]); @@ -533,8 +1017,8 @@ static void transform(DBEContext *s, DBEChannel *c, float *history, float *outpu float *dst = result + g->dst_ofs; float *win = window + g->win_ofs; - imdct_calc(s, g, buffer, c->mantissas + g->mnt_ofs); - s->fdsp->vector_fmul_add(dst, src, win, dst, g->win_len); + imdct_calc(s1, g, buffer, c->mantissas + g->mnt_ofs); + s1->fdsp->vector_fmul_add(dst, src, win, dst, g->win_len); } for (i = 0; i < 256; i++) @@ -545,7 +1029,7 @@ static void transform(DBEContext *s, DBEChannel *c, float *history, float *outpu history[i] = result[896 + i]; } -static void apply_gain(DBEContext *s, int begin, int end, float *output) +static void apply_gain(DBEDecodeContext *s, int begin, int end, float *output) { if (begin == 960 && end == 960) return; @@ -562,16 +1046,17 @@ static void apply_gain(DBEContext *s, int begin, int end, float *output) } } -static int filter_frame(DBEContext *s, AVFrame *frame) +static int filter_frame(DBEDecodeContext *s, AVFrame *frame) { + const DolbyEHeaderInfo *const metadata = &s->dectx.metadata; const uint8_t *reorder; int ch, ret; - if (s->nb_channels == 4) + if (metadata->nb_channels == 4) reorder = ch_reorder_4; - else if (s->nb_channels == 6) + else if (metadata->nb_channels == 6) reorder = ch_reorder_6; - else if (s->nb_programs == 1 && !(s->avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) + else if (metadata->nb_programs == 1 && !(s->avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) reorder = ch_reorder_8; else reorder = ch_reorder_n; @@ -580,11 +1065,11 @@ static int filter_frame(DBEContext *s, AVFrame *frame) if ((ret = ff_get_buffer(s->avctx, frame, 0)) < 0) return ret; - for (ch = 0; ch < s->nb_channels; ch++) { + for (ch = 0; ch < metadata->nb_channels; ch++) { float *output = (float *)frame->extended_data[reorder[ch]]; transform(s, &s->channels[0][ch], s->history[ch], output); transform(s, &s->channels[1][ch], s->history[ch], output + FRAME_SAMPLES / 2); - apply_gain(s, s->begin_gain[ch], s->end_gain[ch], output); + apply_gain(s, metadata->begin_gain[ch], metadata->end_gain[ch], output); } return 0; @@ -593,39 +1078,21 @@ static int filter_frame(DBEContext *s, AVFrame *frame) static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { - DBEContext *s = avctx->priv_data; - int i, j, hdr, ret; + DBEDecodeContext *s1 = avctx->priv_data; + DBEContext *s = &s1->dectx; + int i, j, ret; - if (avpkt->size < 3) - return AVERROR_INVALIDDATA; - - hdr = AV_RB24(avpkt->data); - if ((hdr & 0xfffffe) == 0x7888e) { - s->word_bits = 24; - } else if ((hdr & 0xffffe0) == 0x788e0) { - s->word_bits = 20; - } else if ((hdr & 0xfffe00) == 0x78e00) { - s->word_bits = 16; - } else { - av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n"); - return AVERROR_INVALIDDATA; - } - - s->word_bytes = s->word_bits + 7 >> 3; - s->input = avpkt->data + s->word_bytes; - s->input_size = avpkt->size / s->word_bytes - 1; - s->key_present = hdr >> 24 - s->word_bits & 1; - - if ((ret = parse_metadata(s)) < 0) + if ((ret = ff_dolby_e_parse_header(s, avpkt->data, avpkt->size)) < 0) return ret; - if (s->nb_programs > 1 && !s->multi_prog_warned) { + if (s->metadata.nb_programs > 1 && !s->metadata.multi_prog_warned) { av_log(avctx, AV_LOG_WARNING, "Stream has %d programs (configuration %d), " - "channels will be output in native order.\n", s->nb_programs, s->prog_conf); - s->multi_prog_warned = 1; + "channels will be output in native order.\n", + s->metadata.nb_programs, s->metadata.prog_conf); + s->metadata.multi_prog_warned = 1; } - switch (s->nb_channels) { + switch (s->metadata.nb_channels) { case 4: avctx->channel_layout = AV_CH_LAYOUT_4POINT0; break; @@ -637,25 +1104,25 @@ static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, break; } - avctx->channels = s->nb_channels; - avctx->sample_rate = sample_rate_tab[s->fr_code]; + avctx->channels = s->metadata.nb_channels; + avctx->sample_rate = s->metadata.sample_rate; avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; - i = s->nb_channels / 2; - j = s->nb_channels; - if ((ret = parse_audio(s, 0, i, 0)) < 0) + i = s->metadata.nb_channels / 2; + j = s->metadata.nb_channels; + if ((ret = parse_audio(s1, 0, i, 0)) < 0) return ret; - if ((ret = parse_audio(s, i, j, 0)) < 0) + if ((ret = parse_audio(s1, i, j, 0)) < 0) return ret; - if ((ret = parse_metadata_ext(s)) < 0) + if ((ret = parse_metadata_ext(s1)) < 0) return ret; - if ((ret = parse_audio(s, 0, i, 1)) < 0) + if ((ret = parse_audio(s1, 0, i, 1)) < 0) return ret; - if ((ret = parse_audio(s, i, j, 1)) < 0) + if ((ret = parse_audio(s1, i, j, 1)) < 0) return ret; - if ((ret = parse_meter(s)) < 0) + if ((ret = parse_meter(s1)) < 0) return ret; - if ((ret = filter_frame(s, data)) < 0) + if ((ret = filter_frame(s1, data)) < 0) return ret; *got_frame_ptr = 1; @@ -664,14 +1131,14 @@ static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, static av_cold void dolby_e_flush(AVCodecContext *avctx) { - DBEContext *s = avctx->priv_data; + DBEDecodeContext *s = avctx->priv_data; memset(s->history, 0, sizeof(s->history)); } static av_cold int dolby_e_close(AVCodecContext *avctx) { - DBEContext *s = avctx->priv_data; + DBEDecodeContext *s = avctx->priv_data; int i; for (i = 0; i < 3; i++) @@ -771,7 +1238,7 @@ static av_cold void init_tables(void) static av_cold int dolby_e_init(AVCodecContext *avctx) { static AVOnce init_once = AV_ONCE_INIT; - DBEContext *s = avctx->priv_data; + DBEDecodeContext *s = avctx->priv_data; int i; if (ff_thread_once(&init_once, init_tables)) @@ -784,8 +1251,8 @@ static av_cold int dolby_e_init(AVCodecContext *avctx) if (!(s->fdsp = avpriv_float_dsp_alloc(0))) return AVERROR(ENOMEM); - s->multi_prog_warned = !!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE); - s->avctx = avctx; + s->dectx.metadata.multi_prog_warned = !!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE); + s->dectx.avctx = s->avctx = avctx; return 0; } @@ -794,7 +1261,7 @@ AVCodec ff_dolby_e_decoder = { .long_name = NULL_IF_CONFIG_SMALL("Dolby E"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_DOLBY_E, - .priv_data_size = sizeof(DBEContext), + .priv_data_size = sizeof(DBEDecodeContext), .init = dolby_e_init, .decode = dolby_e_decode_frame, .close = dolby_e_close, diff --git a/libavcodec/dolby_e.h b/libavcodec/dolby_e.h index ae04bf699..9f0c06572 100644 --- a/libavcodec/dolby_e.h +++ b/libavcodec/dolby_e.h @@ -21,70 +21,23 @@ #ifndef AVCODEC_DOLBY_E_H #define AVCODEC_DOLBY_E_H -#include "libavutil/float_dsp.h" -#include "libavutil/libm.h" -#include "libavutil/mem.h" - -#include "internal.h" +#include #include "get_bits.h" -#include "kbdwin.h" -#include "fft.h" #define FRAME_SAMPLES 1792 #define MAX_PROG_CONF 23 #define MAX_PROGRAMS 8 #define MAX_CHANNELS 8 -#define MAX_SEGMENTS 2 - -#define MAX_GROUPS 8 -#define MAX_EXPONENTS 304 -#define MAX_MANTISSAS 1024 - -#define MAX_MSTR_EXP 2 -#define MAX_BIAS_EXP 50 - -typedef struct DBEGroup { - uint8_t nb_exponent; - uint8_t nb_bias_exp[MAX_MSTR_EXP]; - uint16_t exp_ofs; - uint16_t mnt_ofs; - const uint8_t *nb_mantissa; - uint8_t imdct_idx; - uint8_t imdct_phs; - uint16_t win_len; - uint16_t dst_ofs; - uint16_t win_ofs; - uint16_t src_ofs; -} DBEGroup; - -typedef struct DBEChannel { - int gr_code; - int bw_code; - - int nb_groups; - int nb_mstr_exp; - DBEGroup groups[MAX_GROUPS]; - - int exp_strategy[MAX_GROUPS]; - int exponents[MAX_EXPONENTS]; - int bap[MAX_EXPONENTS]; - int idx[MAX_EXPONENTS]; - - DECLARE_ALIGNED(32, float, mantissas)[MAX_MANTISSAS]; -} DBEChannel; - -typedef struct DBEContext { - AVCodecContext *avctx; - GetBitContext gb; - - uint8_t *input; - int input_size; - - int word_bits; - int word_bytes; - int key_present; +/** + * @struct DolbyEHeaderInfo + * Coded Dolby E header values up to end_gain element, plus derived values. + */ +typedef struct DolbyEHeaderInfo { + /** @name Coded elements + * @{ + */ int prog_conf; int nb_channels; int nb_programs; @@ -99,549 +52,52 @@ typedef struct DBEContext { int rev_id[MAX_CHANNELS]; int begin_gain[MAX_CHANNELS]; int end_gain[MAX_CHANNELS]; + /** @} */ + /** @name Derived values + * @{ + */ int multi_prog_warned; - DBEChannel channels[MAX_SEGMENTS][MAX_CHANNELS]; + int sample_rate; + /** @} */ +} DolbyEHeaderInfo; - DECLARE_ALIGNED(32, float, history)[MAX_CHANNELS][256]; +/** + * @struct DBEContext + * Dolby E reading context used by decoder and parser. + */ +typedef struct DBEContext { + void *avctx; + GetBitContext gb; - FFTContext imdct[3]; - AVFloatDSPContext *fdsp; + const uint8_t *input; + int input_size; + + int word_bits; + int word_bytes; + int key_present; + + DolbyEHeaderInfo metadata; uint8_t buffer[1024 * 3 + AV_INPUT_BUFFER_PADDING_SIZE]; } DBEContext; -static const uint8_t nb_programs_tab[MAX_PROG_CONF + 1] = { - 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1, 2, 3, 3, 4, 5, 6, 1, 2, 3, 4, 1, 1 -}; +/** + * Use the provided key to transform the input into data (put into s->buffer) + * suitable for further processing and initialize s->gb to read said data. + */ +int ff_dolby_e_convert_input(DBEContext *s, int nb_words, int key); -static const uint8_t nb_channels_tab[MAX_PROG_CONF + 1] = { - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8 -}; - -static const int8_t lfe_channel_tab[MAX_PROG_CONF + 1] = { - 5, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5 -}; - -static const uint8_t ch_reorder_4[4] = { 0, 2, 1, 3 }; -static const uint8_t ch_reorder_6[6] = { 0, 2, 4, 1, 3, 5 }; -static const uint8_t ch_reorder_8[8] = { 0, 2, 6, 4, 1, 3, 7, 5 }; -static const uint8_t ch_reorder_n[8] = { 0, 2, 4, 6, 1, 3, 5, 7 }; - -static const uint16_t sample_rate_tab[16] = { - 0, 42965, 43008, 44800, 53706, 53760 -}; - -static const uint8_t nb_groups_tab[4] = { 1, 8, 7, 1 }; - -static const uint8_t nb_mstr_exp_tab[4] = { 2, 2, 2, 1 }; - -static const uint8_t nb_mantissa_38[38] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, - 7, 8, 9, 10, 11, 12, -}; - -static const uint8_t nb_mantissa_44[44] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, - 8, 9, 10, 11, 12, 13, 15, 16, 18, 20, 22, 25, -}; - -static const uint8_t nb_mantissa_50[50] = { - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, - 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 12, 13, 14, 16, - 18, 19, 22, 24, 27, 29, 32, 36, 40, 44, 49, 54, 60, 66, 74, 82, - 90, 100, -}; - -static const uint8_t imdct_bits_tab[3] = { 8, 9, 11 }; - -static const DBEGroup grp_tab_0[1] = { - { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 }, -}; - -static const DBEGroup grp_tab_1[8] = { - { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 }, - { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 }, - { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 }, - { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, - { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, - { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, - { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 704, 0, 0 }, - { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 1, 256, 832, 0, 0 }, -}; - -static const DBEGroup grp_tab_2[7] = { - { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 }, - { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 }, - { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 }, - { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, - { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, - { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, - { 44, { 19, 25 }, 228, 768, nb_mantissa_44, 1, 1, 448, 704, 960, 64 }, -}; - -static const DBEGroup grp_tab_3[1] = { - { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 }, -}; - -static const DBEGroup grp_tab_4[1] = { - { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 }, -}; - -static const DBEGroup grp_tab_5[8] = { - { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 1, 256, 64, 0, 0 }, - { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 192, 0, 0 }, - { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, - { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, - { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, - { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 }, - { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 }, - { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 }, -}; - -static const DBEGroup grp_tab_6[7] = { - { 44, { 19, 25 }, 0, 0, nb_mantissa_44, 1, 1, 448, 0, 3264, 0 }, - { 38, { 12, 26 }, 44, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, - { 38, { 12, 26 }, 82, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, - { 38, { 12, 26 }, 120, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, - { 38, { 12, 26 }, 158, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 }, - { 38, { 12, 26 }, 196, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 }, - { 38, { 12, 26 }, 234, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 }, -}; - -static const DBEGroup grp_tab_7[1] = { - { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 }, -}; - -static const DBEGroup *const frm_ofs_tab[2][4] = { - { grp_tab_0, grp_tab_1, grp_tab_2, grp_tab_3 }, - { grp_tab_4, grp_tab_5, grp_tab_6, grp_tab_7 } -}; - -static const uint8_t mantissa_size1[16][4] = { - { 0, 0, 0, 0 }, { 2, 1, 1, 1 }, { 3, 2, 1, 1 }, { 4, 3, 2, 1 }, - { 5, 4, 3, 2 }, { 6, 5, 4, 3 }, { 7, 6, 5, 4 }, { 8, 7, 6, 5 }, - { 9, 8, 7, 6 }, { 10, 9, 8, 7 }, { 11, 10, 9, 8 }, { 12, 11, 10, 9 }, - { 13, 12, 11, 10 }, { 14, 13, 12, 11 }, { 15, 14, 13, 12 }, { 16, 15, 14, 13 }, -}; - -static const uint8_t mantissa_size2[16][4] = { - { 0, 0, 0, 0 }, { 2, 1, 2, 2 }, { 3, 2, 3, 3 }, { 4, 3, 4, 4 }, - { 5, 4, 5, 5 }, { 6, 5, 6, 6 }, { 7, 6, 7, 7 }, { 8, 7, 8, 8 }, - { 9, 8, 9, 9 }, { 10, 9, 10, 10 }, { 11, 10, 11, 11 }, { 12, 11, 12, 12 }, - { 13, 12, 13, 13 }, { 14, 13, 14, 14 }, { 15, 14, 15, 15 }, { 16, 15, 16, 16 }, -}; - -static const float start_window[192] = { - 0.00161569379826, 0.00185748233347, 0.00198562758548, 0.00207834078104, - 0.00215717748523, 0.00223067096393, 0.00230299213147, 0.00237651215396, - 0.00245275561606, 0.00253281402069, 0.00261754673613, 0.00270768786168, - 0.00280390761895, 0.00290684998656, 0.00301715751161, 0.00313548872798, - 0.00326253122934, 0.00339901215995, 0.00354570716636, 0.00370344845023, - 0.00387313232586, 0.00405572653911, 0.00425227750970, 0.00446391759265, - 0.00469187240551, 0.00493746822816, 0.00520213944619, 0.00548743597507, - 0.00579503056737, 0.00612672586953, 0.00648446105606, 0.00687031782873, - 0.00728652552677, 0.00773546505205, 0.00821967127415, 0.00874183354619, - 0.00930479393832, 0.00991154278653, 0.01056521116692, 0.01126905994567, - 0.01202646513050, 0.01284089936559, 0.01371590957417, 0.01465509096066, - 0.01566205783408, 0.01674041199523, 0.01789370972358, 0.01912542867865, - 0.02043893626265, 0.02183746113793, 0.02332406961796, 0.02490164852364, - 0.02657289580178, 0.02834031974193, 0.03020624702903, 0.03217283918354, - 0.03424211623810, 0.03641598586180, 0.03869627565015, 0.04108476601498, - 0.04358322107390, 0.04619341515939, 0.04891715301882, 0.05175628239149, - - 0.05471237327267, 0.05778734733755, 0.06098291402413, 0.06430101352084, - 0.06774345212186, 0.07131188644726, 0.07500780649199, 0.07883251748595, - 0.08278712056651, 0.08687249228061, 0.09108926295730, 0.09543779401074, - 0.09991815425851, 0.10453009536427, 0.10927302653894, 0.11414598865987, - 0.11914762799220, 0.12427616972097, 0.12952939152560, 0.13490459744934, - 0.14039859233595, 0.14600765712201, 0.15172752528722, 0.15755336077528, - 0.16347973770491, 0.16950062219342, 0.17560935661442, 0.18179864660619, - 0.18806055113821, 0.19438647593012, 0.20076717050010, 0.20719272909882, - 0.21365259576030, 0.22013557367283, 0.22662983904194, 0.23312295958328, - 0.23960191774666, 0.24605313873388, 0.25246252333253, 0.25881548554631, - 0.26509699495987, 0.27129162373316, 0.27738359807707, 0.28335685401987, - 0.28919509723179, 0.29488186663467, 0.30040060148455, 0.30573471157819, - 0.31086765019993, 0.31578298939317, 0.32046449711227, 0.32489621578468, - 0.32906254179156, 0.33294830535654, 0.33653885031840, 0.33982011325336, - 0.34277870140679, 0.34540196889300, 0.34767809062480, 0.34959613344194, - 0.35114612391958, 0.35231911235422, 0.35310723244504, 0.35350375621308, - - 0.35350314372945, 0.35310108725579, 0.35229454943591, 0.35108179521634, - 0.34946241721522, 0.34743735430290, 0.34500890320420, 0.34218072298001, - 0.33895783229541, 0.33534659943168, 0.33135472505060, 0.32699121776996, - 0.32226636266000, 0.31719168282019, 0.31177989424432, 0.30604485422875, - 0.30000150362379, 0.29366580327088, 0.28705466500775, 0.28018587766131, - 0.27307802848095, 0.26575042049535, 0.25822298630189, 0.25051619882000, - 0.24265097955783, 0.23464860495522, 0.22653061137548, 0.21831869932335, - 0.21003463746705, 0.20170016703857, 0.19333690717811, 0.18496626177620, - 0.17660932835062, 0.16828680947474, 0.16001892724986, 0.15182534128597, - 0.14372507062477, 0.13573642000364, 0.12787691082233, 0.12016321713317, - 0.11261110693234, 0.10523538898282, 0.09804986534955, 0.09106728977263, - 0.08429933194438, 0.07775654768810, 0.07144835495683, 0.06538301547324, - 0.05956762170687, 0.05400808871425, 0.04870915012107, 0.04367435714993, - 0.03890607899172, 0.03440550179663, 0.03017262174627, 0.02620622428513, - 0.02250383492507, 0.01906161305732, 0.01587412848221, 0.01293388032354, - 0.01023019677288, 0.00774641320626, 0.00545109736891, 0.00325868651263, -}; - -static const float short_window2[192] = { - 0.00018861094606, 0.00033433010202, 0.00050309624485, 0.00070306161748, - 0.00093995174533, 0.00121913067128, 0.00154606505568, 0.00192647806126, - 0.00236641248692, 0.00287225985240, 0.00345077377440, 0.00410907465023, - 0.00485464855241, 0.00569534163219, 0.00663935063508, 0.00769520981249, - 0.00887177436246, 0.01017820046395, 0.01162392194150, 0.01321862359335, - 0.01497221122468, 0.01689477844427, 0.01899657030441, 0.02128794388846, - 0.02377932597692, 0.02648116795039, 0.02940389811590, 0.03255787167130, - 0.03595331854986, 0.03960028941437, 0.04350860009563, 0.04768777479454, - 0.05214698838949, 0.05689500821121, 0.06194013566525, 0.06729014809766, - 0.07295224131210, 0.07893297315602, 0.08523820859989, 0.09187306673620, - 0.09884187012422, 0.10614809690222, 0.11379433608064, 0.12178224641797, - 0.13011251926531, 0.13878484574660, 0.14779788861830, 0.15714925912610, - 0.16683549914631, 0.17685206886673, 0.18719334022589, 0.19785259629099, - 0.20882203671372, 0.22009278936030, 0.23165492816694, 0.24349749722585, - 0.25560854105961, 0.26797514099368, 0.28058345748882, 0.29341877824732, - 0.30646557185942, 0.31970754671026, 0.33312771482295, 0.34670846027024, - - 0.36043161174692, 0.37427851885723, 0.38823013163645, 0.40226708279486, - 0.41636977214436, 0.43051845264462, 0.44469331748632, 0.45887458761470, - 0.47304259908636, 0.48717788964798, 0.50126128392546, 0.51527397661778, - 0.52919761310050, 0.54301436685998, 0.55670701320069, 0.57025899869448, - 0.58365450587230, 0.59687851269542, 0.60991684638414, 0.62275623122793, - 0.63538433005035, 0.64778977905593, 0.65996221584264, 0.67189230042379, - 0.68357172916486, 0.69499324160511, 0.70615062019861, 0.71703868307548, - 0.72765326998919, 0.73799122168099, 0.74805035295521, 0.75782941981995, - 0.76732808110520, 0.77654685502339, 0.78548707118622, 0.79415081863423, - 0.80254089047207, 0.81066072573188, 0.81851434910893, 0.82610630922734, - 0.83344161609862, 0.84052567843230, 0.84736424144524, 0.85396332579459, - 0.86032916822973, 0.86646816451999, 0.87238681516918, 0.87809167437532, - 0.88358930263537, 0.88888622333073, 0.89398888356256, 0.89890361943564, - 0.90363662591861, 0.90819393133744, 0.91258137648979, 0.91680459830070, - 0.92086901787718, 0.92477983276087, 0.92854201312583, 0.93216030163834, - 0.93563921662343, 0.93898305819384, 0.94219591693690, 0.94528168477979, - - 0.94823843319821, 0.95106834367330, 0.95377776558539, 0.95636718335775, - 0.95883679961479, 0.96118650212341, 0.96341583179195, 0.96552395212906, - 0.96750962060547, 0.96937116231768, 0.97110644638309, 0.97271286544154, - 0.97418731862798, 0.97552619834964, 0.97672538116257, 0.97778022299974, - 0.97868555895586, 0.97943570778357, 0.98002448120255, 0.98044519806866, - 0.98069070339493, 0.98075339216123, 0.98062523779637, 0.98029782516478, - 0.97976238784222, 0.97900984942031, 0.97803086854002, 0.97681588731895, - 0.97535518280755, 0.97363892108474, 0.97165721358452, 0.96940017523145, - 0.96685798395452, 0.96402094114589, 0.96087953263194, 0.95742448973047, - 0.95364684997699, 0.94953801711660, 0.94508981997396, 0.94029456983253, - 0.93514511597504, 0.92963489905951, 0.92375800202883, 0.91750919827624, - 0.91088399681406, 0.90387868421832, 0.89649036314692, 0.88871698725397, - 0.88055739234735, 0.87201132366062, 0.86307945913336, 0.85376342861693, - 0.84406582894455, 0.83399023482637, 0.82354120554757, 0.81272428745995, - 0.80154601230457, 0.79001389138101, 0.77813640562199, 0.76592299164227, - 0.75338402384395, 0.74053079267526, 0.72737547915460, 0.71393112578527, -}; - -static const float short_window3[64] = { - 0.00326887936450, 0.00550242900936, 0.00786846643791, 0.01045683453520, - 0.01330402120132, 0.01643221072863, 0.01985798040609, 0.02359509464766, - 0.02765559221954, 0.03205025893128, 0.03678884369614, 0.04188015679495, - 0.04733210987781, 0.05315172583924, 0.05934513287609, 0.06591755045290, - 0.07287327156378, 0.08021564389822, 0.08794705152307, 0.09606889811179, - 0.10458159240070, 0.11348453632940, 0.12277611617809, 0.13245369691511, - 0.14251361989876, 0.15295120402567, 0.16376075037904, 0.17493555039885, - 0.18646789757072, 0.19834910260891, 0.21056951208995, 0.22311853047787, - 0.23598464546683, 0.24915545655419, 0.26261770674500, 0.27635731727778, - 0.29035942525136, 0.30460842402318, 0.31908800624032, 0.33378120935681, - 0.34867046348260, 0.36373764140285, 0.37896411059909, 0.39433078709788, - 0.40981819096657, 0.42540650327031, 0.44107562429959, 0.45680523287270, - 0.47257484651351, 0.48836388230077, 0.50415171818214, 0.51991775454258, - 0.53564147581496, 0.55130251191887, 0.56688069931047, 0.58235614142007, - 0.59770926827271, 0.61292089506118, 0.62797227945823, 0.64284517745255, - 0.65752189749349, 0.67198535273209, 0.68621911114984, 0.70020744337099, -}; - -static const uint8_t dc_code_tab[5] = { 0, 0, 0, 1, 1 }; - -static const uint8_t ht_code_tab[5] = { 0, 0, 1, 2, 2 }; - -static const uint8_t band_ofs_tab[3][4] = { - { 12, 8, 4, 0 }, { 14, 10, 6, 0 }, { 12, 8, 4, 0 } -}; - -static const uint8_t band_low_tab[3] = { 9, 17, 24 }; - -static const uint16_t fast_gain_tab[8] = { - 128, 256, 384, 512, 640, 768, 896, 1024 -}; - -static const uint16_t slow_decay_tab[2][2] = { { 27, -1 }, { 32, 21 } }; - -static const uint16_t misc_decay_tab[3][2][2] = { - { { 354, -1 }, { 425, 425 } }, - { { 266, -1 }, { 320, -1 } }, - { { 213, -1 }, { 256, -1 } } -}; - -static const uint16_t fast_decay_tab[3][2][2][50] = { - {{{ - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - }}, {{ - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - }, { - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - }}}, {{{ - 266, 266, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, - }}, {{ - 319, 319, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, - }}}, {{{ - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }}, {{ - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }}} -}; - -static const uint16_t fast_gain_adj_tab[3][2][62] = { - {{ - 0, 0, 0, 0, 0, 0, 0, 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, 4, 7, 11, 16, 29, 44, 59, - 76, 94, 116, 142, 179, 221, 252, 285, 312, 334, - }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 5, 8, 10, 15, 28, 42, 57, 75, 93, - 115, 140, 177, 219, 247, 280, 308, 330, 427, 533, - }}, {{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 5, 8, 12, 21, 35, 51, 69, 89, - 111, 138, 176, 220, 251, 284, 312, 334, - }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 5, 8, 11, 18, 33, 49, 65, 84, 106, 132, - 168, 214, 245, 279, 308, 329, 427, 533, - }}, {{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 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, 4, 7, 10, 17, - 31, 47, 65, 84, 107, 134, 171, 215, 250, 283, - 312, 334, - }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 6, 9, 13, 27, 43, - 60, 79, 100, 126, 160, 207, 242, 276, 307, 329, - 427, 533, - }} -}; - -static const uint16_t slow_gain_tab[3][2][50] = { - {{ - 3072, 3072, 3072, 3072, 3072, 3072, 1063, 1063, 1063, 1063, - 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, - 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, - 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, - }, { - 3072, 3072, 3072, 3072, 3072, 3072, 850, 850, 850, 850, - 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, - 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, - 850, 850, 850, 850, 850, 850, 850, 850, - }}, {{ - 3072, 1212, 1212, 1212, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, - }}, {{ - 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }} -}; - -static const uint16_t hearing_thresh_tab[3][3][50] = { - {{ - 1403, 1141, 1000, 959, 948, 957, 946, 925, 899, 871, - 843, 815, 789, 766, 745, 727, 705, 687, 681, 686, - 701, 725, 768, 854, 940, 1018, 1075, 1103, 1111, 1106, - 1098, 1105, 1142, 1237, 1419, 1721, 2169, 2805, - }, { - 1401, 1130, 995, 957, 947, 955, 941, 918, 890, 861, - 831, 803, 777, 754, 734, 717, 698, 684, 682, 692, - 712, 743, 798, 894, 976, 1045, 1091, 1109, 1110, 1102, - 1098, 1116, 1174, 1300, 1526, 1884, 2401, 3072, - }, { - 1393, 1086, 974, 949, 957, 941, 913, 878, 843, 808, - 777, 750, 727, 708, 695, 686, 681, 689, 714, 752, - 811, 888, 971, 1044, 1087, 1108, 1110, 1102, 1098, 1115, - 1172, 1290, 1489, 1812, 2293, 2964, 3072, 3072, - }}, {{ - 1412, 1343, 1141, 1047, 1000, 974, 959, 951, 948, 947, - 957, 953, 946, 936, 925, 906, 878, 850, 822, 795, - 771, 745, 719, 700, 687, 681, 685, 701, 733, 784, - 885, 977, 1047, 1092, 1110, 1108, 1099, 1102, 1138, 1233, - 1413, 1711, 2157, 2797, - }, { - 1412, 1336, 1130, 1040, 995, 970, 957, 950, 947, 947, - 955, 950, 941, 930, 918, 897, 868, 838, 810, 783, - 759, 734, 710, 693, 684, 681, 690, 712, 752, 823, - 924, 1009, 1069, 1102, 1111, 1104, 1098, 1111, 1168, 1295, - 1518, 1873, 2388, 3072, - }, { - 1411, 1293, 1086, 1009, 974, 957, 949, 947, 957, 951, - 941, 928, 913, 896, 878, 852, 817, 785, 756, 732, - 713, 695, 683, 682, 689, 710, 746, 811, 906, 992, - 1061, 1099, 1111, 1106, 1098, 1107, 1155, 1266, 1471, 1799, - 2277, 2945, 3072, 3072, - }}, {{ - 1431, 1412, 1403, 1379, 1343, 1293, 1229, 1180, 1125, 1075, - 1040, 1014, 996, 979, 965, 957, 951, 948, 947, 957, - 951, 940, 924, 903, 877, 846, 815, 785, 753, 725, - 702, 686, 681, 689, 714, 760, 847, 947, 1028, 1083, - 1108, 1109, 1101, 1100, 1132, 1222, 1402, 1705, 2160, 2803, - }, { - 1431, 1412, 1401, 1375, 1336, 1278, 1215, 1168, 1115, 1066, - 1032, 1008, 991, 975, 962, 954, 950, 947, 947, 955, - 948, 935, 916, 894, 866, 835, 803, 772, 742, 715, - 695, 683, 683, 697, 729, 784, 887, 982, 1054, 1096, - 1111, 1106, 1098, 1107, 1159, 1281, 1505, 1865, 2391, 3072, - }, { - 1427, 1411, 1393, 1353, 1293, 1215, 1160, 1118, 1072, 1031, - 1003, 984, 971, 960, 952, 948, 947, 957, 952, 941, - 924, 902, 876, 847, 815, 781, 750, 723, 700, 685, - 681, 691, 719, 766, 858, 958, 1039, 1089, 1109, 1108, - 1099, 1102, 1141, 1245, 1442, 1766, 2250, 2930, 3072, 3072, - }} -}; - -static const int16_t lwc_gain_tab[11][7] = { - { -21, -197, -271, -466, 32767, 32767, 32767 }, - { -197, -29, -244, -271, -540, 32767, 32767 }, - { -271, -244, -29, -249, -271, -593, 32767 }, - { -466, -271, -249, -29, -251, -271, -632 }, - { -540, -271, -251, -29, -251, -271, -664 }, - { -593, -271, -251, -29, -252, -271, -690 }, - { -632, -271, -252, -29, -252, -271, -711 }, - { -664, -271, -252, -29, -252, -271, -730 }, - { -690, -271, -252, -29, -252, -271, -745 }, - { -711, -271, -252, -29, -253, -271, -759 }, - { -730, -271, -253, -29, -253, -271, -771 }, -}; - -static const int16_t lwc_adj_tab[7] = { - -192, -320, -448, -512, -448, -320, -192, -}; - -static const uint8_t log_add_tab[212] = { - 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 52, 51, 50, - 49, 48, 47, 47, 46, 45, 44, 44, 43, 42, 41, 41, 40, 39, 38, 38, - 37, 36, 36, 35, 35, 34, 33, 33, 32, 32, 31, 30, 30, 29, 29, 28, - 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 21, - 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, - 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, - 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, - 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, - 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 0, -}; - -static const uint8_t bap_tab[64] = { - 0, 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, 6, 7, 7, 7, 7, 8, - 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, - 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, -}; - -static float mantissa_tab1[17][4]; -static float mantissa_tab2[17][4]; -static float mantissa_tab3[17][4]; -static float exponent_tab[50]; -static float gain_tab[1024]; - -DECLARE_ALIGNED(32, static float, window)[3712]; +/** + * Initialize DBEContext and parse Dolby E metadata. + * Set word_bits/word_bytes, input, input_size, key_present + * and parse the header up to the end_gain element. + * @param[out] s DBEContext. + * @param[in] buf raw input buffer. + * @param[in] buf_size must be 3 bytes at least. + * @return Returns 0 on success, AVERROR_INVALIDDATA on error + */ +int ff_dolby_e_parse_header(DBEContext *s, const uint8_t *buf, int buf_size); #endif diff --git a/libavcodec/dolby_e_parse.c b/libavcodec/dolby_e_parse.c new file mode 100644 index 000000000..ffedcd99a --- /dev/null +++ b/libavcodec/dolby_e_parse.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2017 foo86 + * + * 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 "get_bits.h" +#include "put_bits.h" +#include "dolby_e.h" + +static const uint8_t nb_programs_tab[MAX_PROG_CONF + 1] = { + 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1, 2, 3, 3, 4, 5, 6, 1, 2, 3, 4, 1, 1 +}; + +static const uint8_t nb_channels_tab[MAX_PROG_CONF + 1] = { + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8 +}; + +static const uint16_t sample_rate_tab[16] = { + 0, 42965, 43008, 44800, 53706, 53760 +}; + +static int skip_input(DBEContext *s, int nb_words) +{ + if (nb_words > s->input_size) { + return AVERROR_INVALIDDATA; + } + + s->input += nb_words * s->word_bytes; + s->input_size -= nb_words; + return 0; +} + +static int parse_key(DBEContext *s) +{ + if (s->key_present) { + const uint8_t *key = s->input; + int ret = skip_input(s, 1); + if (ret < 0) + return ret; + return AV_RB24(key) >> 24 - s->word_bits; + } + return 0; +} + +int ff_dolby_e_convert_input(DBEContext *s, int nb_words, int key) +{ + const uint8_t *src = s->input; + uint8_t *dst = s->buffer; + PutBitContext pb; + int i; + + av_assert0(nb_words <= 1024u); + + if (nb_words > s->input_size) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); + return AVERROR_INVALIDDATA; + } + + switch (s->word_bits) { + case 16: + for (i = 0; i < nb_words; i++, src += 2, dst += 2) + AV_WB16(dst, AV_RB16(src) ^ key); + break; + case 20: + init_put_bits(&pb, s->buffer, sizeof(s->buffer)); + for (i = 0; i < nb_words; i++, src += 3) + put_bits(&pb, 20, AV_RB24(src) >> 4 ^ key); + flush_put_bits(&pb); + break; + case 24: + for (i = 0; i < nb_words; i++, src += 3, dst += 3) + AV_WB24(dst, AV_RB24(src) ^ key); + break; + default: + av_assert0(0); + } + + return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits); +} + +int ff_dolby_e_parse_header(DBEContext *s, const uint8_t *buf, int buf_size) +{ + DolbyEHeaderInfo *const header = &s->metadata; + int hdr, ret, key, mtd_size; + + if (buf_size < 3) + return AVERROR_INVALIDDATA; + + hdr = AV_RB24(buf); + if ((hdr & 0xfffffe) == 0x7888e) { + s->word_bits = 24; + } else if ((hdr & 0xffffe0) == 0x788e0) { + s->word_bits = 20; + } else if ((hdr & 0xfffe00) == 0x78e00) { + s->word_bits = 16; + } else { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid frame header\n"); + return AVERROR_INVALIDDATA; + } + + s->word_bytes = s->word_bits + 7 >> 3; + s->input = buf + s->word_bytes; + s->input_size = buf_size / s->word_bytes - 1; + s->key_present = hdr >> 24 - s->word_bits & 1; + + if ((key = parse_key(s)) < 0) + return key; + if ((ret = ff_dolby_e_convert_input(s, 1, key)) < 0) + return ret; + + skip_bits(&s->gb, 4); + mtd_size = get_bits(&s->gb, 10); + if (!mtd_size) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n"); + return AVERROR_INVALIDDATA; + } + + if ((ret = ff_dolby_e_convert_input(s, mtd_size, key)) < 0) + return ret; + + skip_bits(&s->gb, 14); + header->prog_conf = get_bits(&s->gb, 6); + if (header->prog_conf > MAX_PROG_CONF) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n"); + return AVERROR_INVALIDDATA; + } + + header->nb_channels = nb_channels_tab[header->prog_conf]; + header->nb_programs = nb_programs_tab[header->prog_conf]; + + header->fr_code = get_bits(&s->gb, 4); + header->fr_code_orig = get_bits(&s->gb, 4); + if (!(header->sample_rate = sample_rate_tab[header->fr_code]) || + !sample_rate_tab[header->fr_code_orig]) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n"); + return AVERROR_INVALIDDATA; + } + + skip_bits_long(&s->gb, 88); + for (int i = 0; i < header->nb_channels; i++) + header->ch_size[i] = get_bits(&s->gb, 10); + header->mtd_ext_size = get_bits(&s->gb, 8); + header->meter_size = get_bits(&s->gb, 8); + + skip_bits_long(&s->gb, 10 * header->nb_programs); + for (int i = 0; i < header->nb_channels; i++) { + header->rev_id[i] = get_bits(&s->gb, 4); + skip_bits1(&s->gb); + header->begin_gain[i] = get_bits(&s->gb, 10); + header->end_gain[i] = get_bits(&s->gb, 10); + } + + if (get_bits_left(&s->gb) < 0) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n"); + return AVERROR_INVALIDDATA; + } + + return skip_input(s, mtd_size + 1); +} diff --git a/libavcodec/dolby_e_parser.c b/libavcodec/dolby_e_parser.c new file mode 100644 index 000000000..3ae973bdd --- /dev/null +++ b/libavcodec/dolby_e_parser.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017 foo86 + * + * 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 "dolby_e.h" +#include "get_bits.h" +#include "put_bits.h" + +typedef struct DBEParseContext { + DBEContext dectx; +} DBEParseContext; + +static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + DBEParseContext *s1 = s2->priv_data; + DBEContext *s = &s1->dectx; + int ret; + + if ((ret = ff_dolby_e_parse_header(s, buf, buf_size)) < 0) + goto end; + + s2->duration = FRAME_SAMPLES; + switch (s->metadata.nb_channels) { + case 4: + avctx->channel_layout = AV_CH_LAYOUT_4POINT0; + break; + case 6: + avctx->channel_layout = AV_CH_LAYOUT_5POINT1; + break; + case 8: + avctx->channel_layout = AV_CH_LAYOUT_7POINT1; + break; + } + + avctx->channels = s->metadata.nb_channels; + avctx->sample_rate = s->metadata.sample_rate; + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + +end: + /* always return the full packet. this parser isn't doing any splitting or + combining, only packet analysis */ + *poutbuf = buf; + *poutbuf_size = buf_size; + return buf_size; +} + +AVCodecParser ff_dolby_e_parser = { + .codec_ids = { AV_CODEC_ID_DOLBY_E }, + .priv_data_size = sizeof(DBEParseContext), + .parser_parse = dolby_e_parse, +}; diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c index b1833ed9e..5372e3d58 100644 --- a/libavcodec/dpx.c +++ b/libavcodec/dpx.c @@ -23,10 +23,43 @@ #include "libavutil/intreadwrite.h" #include "libavutil/intfloat.h" #include "libavutil/imgutils.h" +#include "libavutil/timecode.h" #include "bytestream.h" #include "avcodec.h" #include "internal.h" +enum DPX_TRC { + DPX_TRC_USER_DEFINED = 0, + DPX_TRC_PRINTING_DENSITY = 1, + DPX_TRC_LINEAR = 2, + DPX_TRC_LOGARITHMIC = 3, + DPX_TRC_UNSPECIFIED_VIDEO = 4, + DPX_TRC_SMPTE_274 = 5, + DPX_TRC_ITU_R_709_4 = 6, + DPX_TRC_ITU_R_601_625 = 7, + DPX_TRC_ITU_R_601_525 = 8, + DPX_TRC_SMPTE_170 = 9, + DPX_TRC_ITU_R_624_4_PAL = 10, + DPX_TRC_Z_LINEAR = 11, + DPX_TRC_Z_HOMOGENEOUS = 12, +}; + +enum DPX_COL_SPEC { + DPX_COL_SPEC_USER_DEFINED = 0, + DPX_COL_SPEC_PRINTING_DENSITY = 1, + /* 2 = N/A */ + /* 3 = N/A */ + DPX_COL_SPEC_UNSPECIFIED_VIDEO = 4, + DPX_COL_SPEC_SMPTE_274 = 5, + DPX_COL_SPEC_ITU_R_709_4 = 6, + DPX_COL_SPEC_ITU_R_601_625 = 7, + DPX_COL_SPEC_ITU_R_601_525 = 8, + DPX_COL_SPEC_SMPTE_170 = 9, + DPX_COL_SPEC_ITU_R_624_4_PAL = 10, + /* 11 = N/A */ + /* 12 = N/A */ +}; + static unsigned int read16(const uint8_t **ptr, int is_big) { unsigned int temp; @@ -126,14 +159,15 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *const p = data; uint8_t *ptr[AV_NUM_DATA_POINTERS]; uint32_t header_version, version = 0; - char creator[101]; - char input_device[33]; + char creator[101] = { 0 }; + char input_device[33] = { 0 }; unsigned int offset; int magic_num, endian; - int x, y, stride, i, ret; + int x, y, stride, i, j, ret; int w, h, bits_per_color, descriptor, elements, packing; - int encoding, need_align = 0; + int yuv, color_trc, color_spec; + int encoding, need_align = 0, unpadded_10bit = 0; unsigned int rgbBuffer = 0; int n_datum = 0; @@ -192,6 +226,8 @@ static int decode_frame(AVCodecContext *avctx, // Need to end in 0x320 to read the descriptor buf += 20; descriptor = buf[0]; + color_trc = buf[1]; + color_spec = buf[2]; // Need to end in 0x323 to read the bits per color buf += 3; @@ -216,31 +252,109 @@ static int decode_frame(AVCodecContext *avctx, else avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; + /* preferred frame rate from Motion-picture film header */ if (offset >= 1724 + 4) { buf = avpkt->data + 1724; i = read32(&buf, endian); - if(i) { + if(i && i != 0xFFFFFFFF) { AVRational q = av_d2q(av_int2float(i), 4096); if (q.num > 0 && q.den > 0) avctx->framerate = q; } } + /* alternative frame rate from television header */ + if (offset >= 1940 + 4 && + !(avctx->framerate.num && avctx->framerate.den)) { + buf = avpkt->data + 1940; + i = read32(&buf, endian); + if(i && i != 0xFFFFFFFF) { + AVRational q = av_d2q(av_int2float(i), 4096); + if (q.num > 0 && q.den > 0) + avctx->framerate = q; + } + } + + /* SMPTE TC from television header */ + if (offset >= 1920 + 4) { + uint32_t tc; + uint32_t *tc_sd; + char tcbuf[AV_TIMECODE_STR_SIZE]; + + buf = avpkt->data + 1920; + // read32 to native endian, av_bswap32 to opposite of native for + // compatibility with av_timecode_make_smpte_tc_string2 etc + tc = av_bswap32(read32(&buf, endian)); + + if (i != 0xFFFFFFFF) { + AVFrameSideData *tcside = + av_frame_new_side_data(p, AV_FRAME_DATA_S12M_TIMECODE, + sizeof(uint32_t) * 4); + if (!tcside) + return AVERROR(ENOMEM); + + tc_sd = (uint32_t*)tcside->data; + tc_sd[0] = 1; + tc_sd[1] = tc; + + av_timecode_make_smpte_tc_string2(tcbuf, avctx->framerate, + tc_sd[1], 0, 0); + av_dict_set(&p->metadata, "timecode", tcbuf, 0); + } + } + + /* color range from television header */ + if (offset >= 1964 + 4) { + buf = avpkt->data + 1952; + i = read32(&buf, endian); + + buf = avpkt->data + 1964; + j = read32(&buf, endian); + + if (i != 0xFFFFFFFF && j != 0xFFFFFFFF) { + float minCV, maxCV; + minCV = av_int2float(i); + maxCV = av_int2float(j); + if (bits_per_color >= 1 && + minCV == 0.0f && maxCV == ((1<color_range = AVCOL_RANGE_JPEG; + } else if (bits_per_color >= 8 && + minCV == (1 <<(bits_per_color - 4)) && + maxCV == (235<<(bits_per_color - 8))) { + avctx->color_range = AVCOL_RANGE_MPEG; + } + } + } + switch (descriptor) { + case 1: // R + case 2: // G + case 3: // B + case 4: // A case 6: // Y elements = 1; + yuv = 1; + break; + case 50: // RGB + elements = 3; + yuv = 0; break; case 52: // ABGR case 51: // RGBA - case 103: // UYVA4444 elements = 4; - break; - case 50: // RGB - case 102: // UYV444 - elements = 3; + yuv = 0; break; case 100: // UYVY422 elements = 2; + yuv = 1; + break; + case 102: // UYV444 + elements = 3; + yuv = 1; + break; + case 103: // UYVA4444 + elements = 4; + yuv = 1; break; default: avpriv_report_missing_feature(avctx, "Descriptor %d", descriptor); @@ -275,8 +389,10 @@ static int decode_frame(AVCodecContext *avctx, case 16: stride = 2 * avctx->width * elements; break; - case 1: case 32: + stride = 4 * avctx->width * elements; + break; + case 1: case 64: avpriv_report_missing_feature(avctx, "Depth %d", bits_per_color); return AVERROR_PATCHWELCOME; @@ -284,6 +400,82 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } + switch (color_trc) { + case DPX_TRC_LINEAR: + avctx->color_trc = AVCOL_TRC_LINEAR; + break; + case DPX_TRC_SMPTE_274: + case DPX_TRC_ITU_R_709_4: + avctx->color_trc = AVCOL_TRC_BT709; + break; + case DPX_TRC_ITU_R_601_625: + case DPX_TRC_ITU_R_601_525: + case DPX_TRC_SMPTE_170: + avctx->color_trc = AVCOL_TRC_SMPTE170M; + break; + case DPX_TRC_ITU_R_624_4_PAL: + avctx->color_trc = AVCOL_TRC_GAMMA28; + break; + case DPX_TRC_USER_DEFINED: + case DPX_TRC_UNSPECIFIED_VIDEO: + /* Nothing to do */ + break; + default: + av_log(avctx, AV_LOG_VERBOSE, "Cannot map DPX transfer characteristic " + "%d to color_trc.\n", color_trc); + break; + } + + switch (color_spec) { + case DPX_COL_SPEC_SMPTE_274: + case DPX_COL_SPEC_ITU_R_709_4: + avctx->color_primaries = AVCOL_PRI_BT709; + break; + case DPX_COL_SPEC_ITU_R_601_625: + case DPX_COL_SPEC_ITU_R_624_4_PAL: + avctx->color_primaries = AVCOL_PRI_BT470BG; + break; + case DPX_COL_SPEC_ITU_R_601_525: + case DPX_COL_SPEC_SMPTE_170: + avctx->color_primaries = AVCOL_PRI_SMPTE170M; + break; + case DPX_COL_SPEC_USER_DEFINED: + case DPX_COL_SPEC_UNSPECIFIED_VIDEO: + /* Nothing to do */ + break; + default: + av_log(avctx, AV_LOG_VERBOSE, "Cannot map DPX color specification " + "%d to color_primaries.\n", color_spec); + break; + } + + if (yuv) { + switch (color_spec) { + case DPX_COL_SPEC_SMPTE_274: + case DPX_COL_SPEC_ITU_R_709_4: + avctx->colorspace = AVCOL_SPC_BT709; + break; + case DPX_COL_SPEC_ITU_R_601_625: + case DPX_COL_SPEC_ITU_R_624_4_PAL: + avctx->colorspace = AVCOL_SPC_BT470BG; + break; + case DPX_COL_SPEC_ITU_R_601_525: + case DPX_COL_SPEC_SMPTE_170: + avctx->colorspace = AVCOL_SPC_SMPTE170M; + break; + case DPX_COL_SPEC_USER_DEFINED: + case DPX_COL_SPEC_UNSPECIFIED_VIDEO: + /* Nothing to do */ + break; + default: + av_log(avctx, AV_LOG_INFO, "Cannot map DPX color specification " + "%d to colorspace.\n", color_spec); + break; + } + } else { + avctx->colorspace = AVCOL_SPC_RGB; + } + // Table 3c: Runs will always break at scan line boundaries. Packing // will always break to the next 32-bit word at scan-line boundaries. // Unfortunately, the encoder produced invalid files, so attempt @@ -305,6 +497,14 @@ static int decode_frame(AVCodecContext *avctx, } switch (1000 * descriptor + 10 * bits_per_color + endian) { + case 1081: + case 1080: + case 2081: + case 2080: + case 3081: + case 3080: + case 4081: + case 4080: case 6081: case 6080: avctx->pix_fmt = AV_PIX_FMT_GRAY8; @@ -313,6 +513,20 @@ static int decode_frame(AVCodecContext *avctx, case 6120: avctx->pix_fmt = AV_PIX_FMT_GRAY12; break; + case 1320: + case 2320: + case 3320: + case 4320: + case 6320: + avctx->pix_fmt = AV_PIX_FMT_GRAYF32LE; + break; + case 1321: + case 2321: + case 3321: + case 4321: + case 6321: + avctx->pix_fmt = AV_PIX_FMT_GRAYF32BE; + break; case 50081: case 50080: avctx->pix_fmt = AV_PIX_FMT_RGB24; @@ -363,6 +577,18 @@ static int decode_frame(AVCodecContext *avctx, case 51160: avctx->pix_fmt = AV_PIX_FMT_RGBA64LE; break; + case 50320: + avctx->pix_fmt = AV_PIX_FMT_GBRPF32LE; + break; + case 50321: + avctx->pix_fmt = AV_PIX_FMT_GBRPF32BE; + break; + case 51320: + avctx->pix_fmt = AV_PIX_FMT_GBRAPF32LE; + break; + case 51321: + avctx->pix_fmt = AV_PIX_FMT_GBRAPF32BE; + break; case 100081: avctx->pix_fmt = AV_PIX_FMT_UYVY422; break; @@ -373,7 +599,8 @@ static int decode_frame(AVCodecContext *avctx, avctx->pix_fmt = AV_PIX_FMT_YUVA444P; break; default: - av_log(avctx, AV_LOG_ERROR, "Unsupported format\n"); + av_log(avctx, AV_LOG_ERROR, "Unsupported format %d\n", + 1000 * descriptor + 10 * bits_per_color + endian); return AVERROR_PATCHWELCOME; } @@ -390,6 +617,12 @@ static int decode_frame(AVCodecContext *avctx, input_device[32] = '\0'; av_dict_set(&p->metadata, "Input Device", input_device, 0); + // Some devices do not pad 10bit samples to whole 32bit words per row + if (!memcmp(input_device, "Scanity", 7) || + !memcmp(creator, "Lasergraphics Inc.", 18)) { + unpadded_10bit = 1; + } + // Move pointer to offset from start of file buf = avpkt->data + offset; @@ -422,7 +655,7 @@ static int decode_frame(AVCodecContext *avctx, read10in32(&buf, &rgbBuffer, &n_datum, endian, shift); } - if (memcmp(input_device, "Scanity", 7)) + if (!unpadded_10bit) n_datum = 0; for (i = 0; i < elements; i++) ptr[i] += p->linesize[i]; @@ -465,6 +698,36 @@ static int decode_frame(AVCodecContext *avctx, buf += need_align; } break; + case 32: + if (elements == 1) { + av_image_copy_plane(ptr[0], p->linesize[0], + buf, stride, + elements * avctx->width * 4, avctx->height); + } else { + for (y = 0; y < avctx->height; y++) { + ptr[0] = p->data[0] + y * p->linesize[0]; + ptr[1] = p->data[1] + y * p->linesize[1]; + ptr[2] = p->data[2] + y * p->linesize[2]; + ptr[3] = p->data[3] + y * p->linesize[3]; + for (x = 0; x < avctx->width; x++) { + AV_WN32(ptr[2], AV_RN32(buf)); + AV_WN32(ptr[0], AV_RN32(buf + 4)); + AV_WN32(ptr[1], AV_RN32(buf + 8)); + if (avctx->pix_fmt == AV_PIX_FMT_GBRAPF32BE || + avctx->pix_fmt == AV_PIX_FMT_GBRAPF32LE) { + AV_WN32(ptr[3], AV_RN32(buf + 12)); + buf += 4; + ptr[3] += 4; + } + + buf += 12; + ptr[2] += 4; + ptr[0] += 4; + ptr[1] += 4; + } + } + } + break; case 16: elements *= 2; case 8: diff --git a/libavcodec/dsd.c b/libavcodec/dsd.c index d48f87fa0..95aab61ea 100644 --- a/libavcodec/dsd.c +++ b/libavcodec/dsd.c @@ -21,6 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/thread.h" #include "libavcodec/internal.h" #include "libavcodec/mathops.h" #include "avcodec.h" @@ -45,11 +46,8 @@ static av_cold void dsd_ctables_tableinit(void) av_cold void ff_init_dsd_data(void) { - static int done = 0; - if (done) - return; - dsd_ctables_tableinit(); - done = 1; + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, dsd_ctables_tableinit); } void ff_dsd2pcm_translate(DSDContext* s, size_t samples, int lsbf, diff --git a/libavcodec/dsddec.c b/libavcodec/dsddec.c index 39837a5ad..21d1d9f5d 100644 --- a/libavcodec/dsddec.c +++ b/libavcodec/dsddec.c @@ -27,11 +27,11 @@ */ #include "libavcodec/internal.h" -#include "libavcodec/mathops.h" #include "avcodec.h" #include "dsd.h" #define DSD_SILENCE 0x69 +#define DSD_SILENCE_REVERSED 0x96 /* 0x69 = 01101001 * This pattern "on repeat" makes a low energy 352.8 kHz tone * and a high energy 1.0584 MHz tone which should be filtered @@ -53,7 +53,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if (!s) return AVERROR(ENOMEM); - silence = avctx->codec_id == AV_CODEC_ID_DSD_LSBF || avctx->codec_id == AV_CODEC_ID_DSD_LSBF_PLANAR ? ff_reverse[DSD_SILENCE] : DSD_SILENCE; + silence = avctx->codec_id == AV_CODEC_ID_DSD_LSBF || avctx->codec_id == AV_CODEC_ID_DSD_LSBF_PLANAR ? DSD_SILENCE_REVERSED : DSD_SILENCE; for (i = 0; i < avctx->channels; i++) { s[i].pos = 0; memset(s[i].buf, silence, sizeof(s[i].buf)); @@ -66,7 +66,7 @@ static av_cold int decode_init(AVCodecContext *avctx) typedef struct ThreadData { AVFrame *frame; - AVPacket *avpkt; + const AVPacket *avpkt; } ThreadData; static int dsd_channel(AVCodecContext *avctx, void *tdata, int j, int threadnr) @@ -75,7 +75,7 @@ static int dsd_channel(AVCodecContext *avctx, void *tdata, int j, int threadnr) DSDContext *s = avctx->priv_data; ThreadData *td = tdata; AVFrame *frame = td->frame; - AVPacket *avpkt = td->avpkt; + const AVPacket *avpkt = td->avpkt; int src_next, src_stride; float *dst = ((float **)frame->extended_data)[j]; @@ -125,6 +125,7 @@ AVCodec ff_##name_##_decoder = { \ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS, \ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, \ AV_SAMPLE_FMT_NONE }, \ + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \ }; DSD_DECODER(DSD_LSBF, dsd_lsbf, "DSD (Direct Stream Digital), least significant bit first") diff --git a/libavcodec/dsicinaudio.c b/libavcodec/dsicinaudio.c index 290dab41a..3ee6c196d 100644 --- a/libavcodec/dsicinaudio.c +++ b/libavcodec/dsicinaudio.c @@ -129,5 +129,5 @@ AVCodec ff_dsicinaudio_decoder = { .priv_data_size = sizeof(CinAudioContext), .init = cinaudio_decode_init, .decode = cinaudio_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; diff --git a/libavcodec/dsicinvideo.c b/libavcodec/dsicinvideo.c index 7f74808e6..52f660fb5 100644 --- a/libavcodec/dsicinvideo.c +++ b/libavcodec/dsicinvideo.c @@ -58,7 +58,6 @@ static av_cold int allocate_buffers(CinVideoContext *cin) cin->bitmap_table[i] = av_mallocz(cin->bitmap_size); if (!cin->bitmap_table[i]) { av_log(cin->avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n"); - destroy_buffers(cin); return AVERROR(ENOMEM); } } diff --git a/libavcodec/dss_sp.c b/libavcodec/dss_sp.c index 14025fcdd..568757d21 100644 --- a/libavcodec/dss_sp.c +++ b/libavcodec/dss_sp.c @@ -22,6 +22,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "avcodec.h" @@ -781,5 +782,5 @@ AVCodec ff_dss_sp_decoder = { .priv_data_size = sizeof(DssSpContext), .init = dss_sp_decode_init, .decode = dss_sp_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c index 41e761d7e..84d19b91a 100644 --- a/libavcodec/dstdec.c +++ b/libavcodec/dstdec.c @@ -27,6 +27,7 @@ #include "libavutil/avassert.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "internal.h" #include "get_bits.h" #include "avcodec.h" @@ -389,4 +390,5 @@ AVCodec ff_dst_decoder = { .capabilities = AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/dv_profile.c b/libavcodec/dv_profile.c index 66505c886..0fc227dd0 100644 --- a/libavcodec/dv_profile.c +++ b/libavcodec/dv_profile.c @@ -261,24 +261,22 @@ const AVDVProfile* ff_dv_frame_profile(AVCodecContext* codec, const AVDVProfile const uint8_t *frame, unsigned buf_size) { #if CONFIG_DVPROFILE - int i, dsf, stype; + int i, dsf, stype, pal; if(buf_size < DV_PROFILE_BYTES) return NULL; dsf = (frame[3] & 0x80) >> 7; stype = frame[80 * 5 + 48 + 3] & 0x1f; + pal = !!(frame[80 * 5 + 48 + 3] & 0x20); /* 576i50 25Mbps 4:1:1 is a special case */ if ((dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) || (stype == 31 && codec && codec->codec_tag==AV_RL32("SL25") && codec->coded_width==720 && codec->coded_height==576)) return &dv_profiles[2]; - if( stype == 0 - && codec - && (codec->codec_tag==AV_RL32("dvsd") || codec->codec_tag==AV_RL32("CDVC")) - && codec->coded_width ==720 - && codec->coded_height==576) + /* hack for trac issues #8333 and #2177, PAL DV files with dsf flag 0 - detect via pal flag and buf_size */ + if (dsf == 0 && pal == 1 && stype == dv_profiles[1].video_stype && buf_size == dv_profiles[1].frame_size) return &dv_profiles[1]; for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++) diff --git a/libavcodec/dvbsub_parser.c b/libavcodec/dvbsub_parser.c index 8ced3c4c3..b7a3d6154 100644 --- a/libavcodec/dvbsub_parser.c +++ b/libavcodec/dvbsub_parser.c @@ -35,20 +35,12 @@ /* parser definition */ typedef struct DVBSubParseContext { - uint8_t *packet_buf; int packet_start; int packet_index; int in_packet; + uint8_t packet_buf[PARSE_BUF_SIZE]; } DVBSubParseContext; -static av_cold int dvbsub_parse_init(AVCodecParserContext *s) -{ - DVBSubParseContext *pc = s->priv_data; - pc->packet_buf = av_malloc(PARSE_BUF_SIZE); - - return 0; -} - static int dvbsub_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, @@ -173,16 +165,8 @@ static int dvbsub_parse(AVCodecParserContext *s, return buf_size; } -static av_cold void dvbsub_parse_close(AVCodecParserContext *s) -{ - DVBSubParseContext *pc = s->priv_data; - av_freep(&pc->packet_buf); -} - AVCodecParser ff_dvbsub_parser = { .codec_ids = { AV_CODEC_ID_DVB_SUBTITLE }, .priv_data_size = sizeof(DVBSubParseContext), - .parser_init = dvbsub_parse_init, .parser_parse = dvbsub_parse, - .parser_close = dvbsub_parse_close, }; diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index f63a1f3bf..9bee33e4a 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -710,8 +710,8 @@ static void compute_default_clut(DVBSubContext *ctx, uint8_t *clut, AVSubtitleRe } count = FFMAX(i - 1, 1); - for (i--; i>=0; i--) { - int v = i*255/count; + for (i--; i >= 0; i--) { + int v = i * 255 / count; AV_WN32(clut + 4*list_inv[i], RGBA(v/2,v,v/2,v)); } } @@ -737,7 +737,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou } /* Not touching AVSubtitles again*/ - if(sub->num_rects) { + if (sub->num_rects) { avpriv_request_sample(ctx, "Different Version of Segment asked Twice"); return AVERROR_PATCHWELCOME; } @@ -747,7 +747,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou sub->num_rects++; } - if(ctx->compute_edt == 0) { + if (ctx->compute_edt == 0) { sub->end_display_time = ctx->time_out * 1000; *got_output = 1; } else if (ctx->prev_start != AV_NOPTS_VALUE) { @@ -813,7 +813,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou ret = AVERROR(ENOMEM); goto fail; } - memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(uint32_t)); + memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(*clut_table)); rect->data[0] = av_malloc(region->buf_size); if (!rect->data[0]) { @@ -851,7 +851,7 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; fail: if (sub->rects) { - for(i=0; inum_rects; i++) { + for (i=0; i < sub->num_rects; i++) { rect = sub->rects[i]; if (rect) { av_freep(&rect->data[0]); @@ -1032,11 +1032,15 @@ static int dvbsub_parse_object_segment(AVCodecContext *avctx, dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1, non_modifying_color); } - -/* } else if (coding_method == 1) {*/ - + } else if (coding_method == 1) { + avpriv_report_missing_feature(avctx, "coded as a string of characters"); + return AVERROR_PATCHWELCOME; + } else if (coding_method == 2) { + avpriv_report_missing_feature(avctx, "progressive coding of pixels"); + return AVERROR_PATCHWELCOME; } else { av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method); + return AVERROR_INVALIDDATA; } return 0; @@ -1073,11 +1077,11 @@ static int dvbsub_parse_clut_segment(AVCodecContext *avctx, clut = get_clut(ctx, clut_id); if (!clut) { - clut = av_malloc(sizeof(DVBSubCLUT)); + clut = av_malloc(sizeof(*clut)); if (!clut) return AVERROR(ENOMEM); - memcpy(clut, &default_clut, sizeof(DVBSubCLUT)); + memcpy(clut, &default_clut, sizeof(*clut)); clut->id = clut_id; clut->version = -1; @@ -1088,53 +1092,53 @@ static int dvbsub_parse_clut_segment(AVCodecContext *avctx, if (clut->version != version) { - clut->version = version; + clut->version = version; - while (buf + 4 < buf_end) { - entry_id = *buf++; + while (buf + 4 < buf_end) { + entry_id = *buf++; - depth = (*buf) & 0xe0; + depth = (*buf) & 0xe0; - if (depth == 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf); + if (depth == 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf); + } + + full_range = (*buf++) & 1; + + if (full_range) { + y = *buf++; + cr = *buf++; + cb = *buf++; + alpha = *buf++; + } else { + y = buf[0] & 0xfc; + cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4; + cb = (buf[1] << 2) & 0xf0; + alpha = (buf[1] << 6) & 0xc0; + + buf += 2; + } + + if (y == 0) + alpha = 0xff; + + YUV_TO_RGB1_CCIR(cb, cr); + YUV_TO_RGB2_CCIR(r, g, b, y); + + ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha); + if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) { + ff_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 && entry_id < 4) + clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha); + else if (depth & 0x40 && entry_id < 16) + clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha); + else if (depth & 0x20) + clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha); } - - full_range = (*buf++) & 1; - - if (full_range) { - y = *buf++; - cr = *buf++; - cb = *buf++; - alpha = *buf++; - } else { - y = buf[0] & 0xfc; - cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4; - cb = (buf[1] << 2) & 0xf0; - alpha = (buf[1] << 6) & 0xc0; - - buf += 2; - } - - if (y == 0) - alpha = 0xff; - - YUV_TO_RGB1_CCIR(cb, cr); - YUV_TO_RGB2_CCIR(r, g, b, y); - - ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha); - if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) { - ff_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 && entry_id < 4) - clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha); - else if (depth & 0x40 && entry_id < 16) - clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha); - else if (depth & 0x20) - clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha); - } } return 0; @@ -1163,7 +1167,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, region = get_region(ctx, region_id); if (!region) { - region = av_mallocz(sizeof(DVBSubRegion)); + region = av_mallocz(sizeof(*region)); if (!region) return AVERROR(ENOMEM); @@ -1210,7 +1214,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, } region->depth = 1 << (((*buf++) >> 2) & 7); - if(region->depth<2 || region->depth>8){ + if (region->depth < 2 || region->depth > 8) { av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth); region->depth= 4; } @@ -1244,7 +1248,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, object = get_object(ctx, object_id); if (!object) { - object = av_mallocz(sizeof(DVBSubObject)); + object = av_mallocz(sizeof(*object)); if (!object) return AVERROR(ENOMEM); @@ -1255,7 +1259,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, object->type = (*buf) >> 6; - display = av_mallocz(sizeof(DVBSubObjectDisplay)); + display = av_mallocz(sizeof(*display)); if (!display) return AVERROR(ENOMEM); @@ -1318,7 +1322,7 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx, ff_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state); - if(ctx->compute_edt == 1) + if (ctx->compute_edt == 1) save_subtitle_set(avctx, sub, got_output); if (page_state == 1 || page_state == 2) { @@ -1352,7 +1356,7 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx, } if (!display) { - display = av_mallocz(sizeof(DVBSubRegionDisplay)); + display = av_mallocz(sizeof(*display)); if (!display) return AVERROR(ENOMEM); } @@ -1601,7 +1605,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, { DVBSubContext *ctx = avctx->priv_data; - if(ctx->compute_edt == 0) + if (ctx->compute_edt == 0) save_subtitle_set(avctx, sub, got_output); #ifdef DEBUG save_display_set(ctx); @@ -1717,12 +1721,12 @@ static int dvbsub_decode(AVCodecContext *avctx, } end: - if(ret < 0) { + if (ret < 0) { *got_sub_ptr = 0; avsubtitle_free(sub); return ret; } else { - if(ctx->compute_edt == 1 ) + if (ctx->compute_edt == 1) FFSWAP(int64_t, ctx->prev_start, sub->pts); } @@ -1730,10 +1734,11 @@ end: } #define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM +#define OFFSET(x) offsetof(DVBSubContext, x) static const AVOption options[] = { - {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS}, - {"compute_clut", "compute clut when not available(-1) or always(1) or never(0)", offsetof(DVBSubContext, compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, DS}, - {"dvb_substream", "", offsetof(DVBSubContext, substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS}, + {"compute_edt", "compute end of time using pts or timeout", OFFSET(compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS}, + {"compute_clut", "compute clut when not available(-1) or always(1) or never(0)", OFFSET(compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, DS}, + {"dvb_substream", "", OFFSET(substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS}, {NULL} }; static const AVClass dvbsubdec_class = { diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c new file mode 100644 index 000000000..d1620e0c5 --- /dev/null +++ b/libavcodec/dvbsubenc.c @@ -0,0 +1,515 @@ +/* + * DVB subtitle encoding + * Copyright (c) 2005 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 "avcodec.h" +#include "bytestream.h" +#include "libavutil/colorspace.h" + +typedef struct DVBSubtitleContext { + int object_version; +} DVBSubtitleContext; + +#define PUTBITS2(val)\ +{\ + bitbuf |= (val) << bitcnt;\ + bitcnt -= 2;\ + if (bitcnt < 0) {\ + bitcnt = 6;\ + *q++ = bitbuf;\ + bitbuf = 0;\ + }\ +} + +static int dvb_encode_rle2(uint8_t **pq, int buf_size, + const uint8_t *bitmap, int linesize, + int w, int h) +{ + uint8_t *q, *line_begin; + unsigned int bitbuf; + int bitcnt; + int x, y, len, x1, v, color; + + q = *pq; + + for(y = 0; y < h; y++) { + // Worst case line is 3 bits per value + 4 bytes overhead + if (buf_size * 8 < w * 3 + 32) + return AVERROR_BUFFER_TOO_SMALL; + line_begin = q; + *q++ = 0x10; + bitbuf = 0; + bitcnt = 6; + + x = 0; + while (x < w) { + x1 = x; + color = bitmap[x1++]; + while (x1 < w && bitmap[x1] == color) + x1++; + len = x1 - x; + if (color == 0 && len == 2) { + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(1); + } else if (len >= 3 && len <= 10) { + v = len - 3; + PUTBITS2(0); + PUTBITS2((v >> 2) | 2); + PUTBITS2(v & 3); + PUTBITS2(color); + } else if (len >= 12 && len <= 27) { + v = len - 12; + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(2); + PUTBITS2(v >> 2); + PUTBITS2(v & 3); + PUTBITS2(color); + } else if (len >= 29) { + /* length = 29 ... 284 */ + if (len > 284) + len = 284; + v = len - 29; + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(3); + PUTBITS2((v >> 6)); + PUTBITS2((v >> 4) & 3); + PUTBITS2((v >> 2) & 3); + PUTBITS2(v & 3); + PUTBITS2(color); + } else { + PUTBITS2(color); + if (color == 0) { + PUTBITS2(1); + } + len = 1; + } + x += len; + } + /* end of line */ + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(0); + if (bitcnt != 6) { + *q++ = bitbuf; + } + *q++ = 0xf0; + bitmap += linesize; + buf_size -= q - line_begin; + } + len = q - *pq; + *pq = q; + return len; +} + +#define PUTBITS4(val)\ +{\ + bitbuf |= (val) << bitcnt;\ + bitcnt -= 4;\ + if (bitcnt < 0) {\ + bitcnt = 4;\ + *q++ = bitbuf;\ + bitbuf = 0;\ + }\ +} + +/* some DVB decoders only implement 4 bits/pixel */ +static int dvb_encode_rle4(uint8_t **pq, int buf_size, + const uint8_t *bitmap, int linesize, + int w, int h) +{ + uint8_t *q, *line_begin; + unsigned int bitbuf; + int bitcnt; + int x, y, len, x1, v, color; + + q = *pq; + + for(y = 0; y < h; y++) { + // Worst case line is 6 bits per value, + 4 bytes overhead + if (buf_size * 8 < w * 6 + 32) + return AVERROR_BUFFER_TOO_SMALL; + line_begin = q; + *q++ = 0x11; + bitbuf = 0; + bitcnt = 4; + + x = 0; + while (x < w) { + x1 = x; + color = bitmap[x1++]; + while (x1 < w && bitmap[x1] == color) + x1++; + len = x1 - x; + if (color == 0 && len == 2) { + PUTBITS4(0); + PUTBITS4(0xd); + } else if (color == 0 && (len >= 3 && len <= 9)) { + PUTBITS4(0); + PUTBITS4(len - 2); + } else if (len >= 4 && len <= 7) { + PUTBITS4(0); + PUTBITS4(8 + len - 4); + PUTBITS4(color); + } else if (len >= 9 && len <= 24) { + PUTBITS4(0); + PUTBITS4(0xe); + PUTBITS4(len - 9); + PUTBITS4(color); + } else if (len >= 25) { + if (len > 280) + len = 280; + v = len - 25; + PUTBITS4(0); + PUTBITS4(0xf); + PUTBITS4(v >> 4); + PUTBITS4(v & 0xf); + PUTBITS4(color); + } else { + PUTBITS4(color); + if (color == 0) { + PUTBITS4(0xc); + } + len = 1; + } + x += len; + } + /* end of line */ + PUTBITS4(0); + PUTBITS4(0); + if (bitcnt != 4) { + *q++ = bitbuf; + } + *q++ = 0xf0; + bitmap += linesize; + buf_size -= q - line_begin; + } + len = q - *pq; + *pq = q; + return len; +} + +static int dvb_encode_rle8(uint8_t **pq, int buf_size, + const uint8_t *bitmap, int linesize, + int w, int h) +{ + uint8_t *q, *line_begin; + int x, y, len, x1, color; + + q = *pq; + + for (y = 0; y < h; y++) { + // Worst case line is 12 bits per value, + 3 bytes overhead + if (buf_size * 8 < w * 12 + 24) + return AVERROR_BUFFER_TOO_SMALL; + line_begin = q; + *q++ = 0x12; + + x = 0; + while (x < w) { + x1 = x; + color = bitmap[x1++]; + while (x1 < w && bitmap[x1] == color) + x1++; + len = x1 - x; + if (len == 1 && color) { + // 00000001 to 11111111 1 pixel in colour x + *q++ = color; + } else { + if (color == 0x00) { + // 00000000 0LLLLLLL L pixels (1-127) in colour 0 (L > 0) + len = FFMIN(len, 127); + *q++ = 0x00; + *q++ = len; + } else if (len > 2) { + // 00000000 1LLLLLLL CCCCCCCC L pixels (3-127) in colour C (L > 2) + len = FFMIN(len, 127); + *q++ = 0x00; + *q++ = 0x80+len; + *q++ = color; + } + else if (len == 2) { + *q++ = color; + *q++ = color; + } else { + *q++ = color; + len = 1; + } + } + x += len; + } + /* end of line */ + // 00000000 end of 8-bit/pixel_code_string + *q++ = 0x00; + *q++ = 0xf0; + bitmap += linesize; + buf_size -= q - line_begin; + } + len = q - *pq; + *pq = q; + return len; +} + +static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, + const AVSubtitle *h) +{ + DVBSubtitleContext *s = avctx->priv_data; + uint8_t *q, *pseg_len; + int page_id, region_id, clut_id, object_id, i, bpp_index, page_state; + + + q = outbuf; + + page_id = 1; + + if (h->num_rects && !h->rects) + return AVERROR(EINVAL); + + if (avctx->width > 0 && avctx->height > 0) { + if (buf_size < 11) + return AVERROR_BUFFER_TOO_SMALL; + /* display definition segment */ + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x14; /* segment_type */ + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = 0x00; /* dds version number & display window flag */ + bytestream_put_be16(&q, avctx->width - 1); /* display width */ + bytestream_put_be16(&q, avctx->height - 1); /* display height */ + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + buf_size -= 11; + } + + /* page composition segment */ + + if (buf_size < 8 + h->num_rects * 6) + return AVERROR_BUFFER_TOO_SMALL; + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x10; /* segment_type */ + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = 30; /* page_timeout (seconds) */ + page_state = 2; /* mode change */ + /* page_version = 0 + page_state */ + *q++ = (s->object_version << 4) | (page_state << 2) | 3; + + for (region_id = 0; region_id < h->num_rects; region_id++) { + *q++ = region_id; + *q++ = 0xff; /* reserved */ + bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */ + bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */ + } + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + buf_size -= 8 + h->num_rects * 6; + + if (h->num_rects) { + for (clut_id = 0; clut_id < h->num_rects; clut_id++) { + if (buf_size < 6 + h->rects[clut_id]->nb_colors * 6) + return AVERROR_BUFFER_TOO_SMALL; + + /* CLUT segment */ + + if (h->rects[clut_id]->nb_colors <= 4) { + /* 2 bpp, some decoders do not support it correctly */ + bpp_index = 0; + } else if (h->rects[clut_id]->nb_colors <= 16) { + /* 4 bpp, standard encoding */ + bpp_index = 1; + } else if (h->rects[clut_id]->nb_colors <= 256) { + /* 8 bpp, standard encoding */ + bpp_index = 2; + } else { + return AVERROR(EINVAL); + } + + + /* CLUT segment */ + *q++ = 0x0f; /* sync byte */ + *q++ = 0x12; /* CLUT definition segment */ + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = clut_id; + *q++ = (0 << 4) | 0xf; /* version = 0 */ + + for(i = 0; i < h->rects[clut_id]->nb_colors; i++) { + *q++ = i; /* clut_entry_id */ + *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */ + { + int a, r, g, b; + uint32_t x= ((uint32_t*)h->rects[clut_id]->data[1])[i]; + a = (x >> 24) & 0xff; + r = (x >> 16) & 0xff; + g = (x >> 8) & 0xff; + b = (x >> 0) & 0xff; + + *q++ = RGB_TO_Y_CCIR(r, g, b); + *q++ = RGB_TO_V_CCIR(r, g, b, 0); + *q++ = RGB_TO_U_CCIR(r, g, b, 0); + *q++ = 255 - a; + } + } + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + buf_size -= 6 + h->rects[clut_id]->nb_colors * 6; + } + + if (buf_size < h->num_rects * 22) + return AVERROR_BUFFER_TOO_SMALL; + for (region_id = 0; region_id < h->num_rects; region_id++) { + + /* region composition segment */ + + if (h->rects[region_id]->nb_colors <= 4) { + /* 2 bpp, some decoders do not support it correctly */ + bpp_index = 0; + } else if (h->rects[region_id]->nb_colors <= 16) { + /* 4 bpp, standard encoding */ + bpp_index = 1; + } else if (h->rects[region_id]->nb_colors <= 256) { + /* 8 bpp, standard encoding */ + bpp_index = 2; + } else { + return AVERROR(EINVAL); + } + + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x11; /* segment_type */ + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = region_id; + *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ + bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */ + bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */ + *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03; + *q++ = region_id; /* clut_id == region_id */ + *q++ = 0; /* 8 bit fill colors */ + *q++ = 0x03; /* 4 bit and 2 bit fill colors */ + + bytestream_put_be16(&q, region_id); /* object_id == region_id */ + *q++ = (0 << 6) | (0 << 4); + *q++ = 0; + *q++ = 0xf0; + *q++ = 0; + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + } + buf_size -= h->num_rects * 22; + + for (object_id = 0; object_id < h->num_rects; object_id++) { + int (*dvb_encode_rle)(uint8_t **pq, int buf_size, + const uint8_t *bitmap, int linesize, + int w, int h); + + if (buf_size < 13) + return AVERROR_BUFFER_TOO_SMALL; + + /* bpp_index maths */ + if (h->rects[object_id]->nb_colors <= 4) { + /* 2 bpp, some decoders do not support it correctly */ + dvb_encode_rle = dvb_encode_rle2; + } else if (h->rects[object_id]->nb_colors <= 16) { + /* 4 bpp, standard encoding */ + dvb_encode_rle = dvb_encode_rle4; + } else if (h->rects[object_id]->nb_colors <= 256) { + /* 8 bpp, standard encoding */ + dvb_encode_rle = dvb_encode_rle8; + } else { + return AVERROR(EINVAL); + } + + /* Object Data segment */ + *q++ = 0x0f; /* sync byte */ + *q++ = 0x13; + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + + bytestream_put_be16(&q, object_id); + *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0, + object_coding_method, + non_modifying_color_flag */ + { + uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr; + int ret; + + ptop_field_len = q; + q += 2; + pbottom_field_len = q; + q += 2; + buf_size -= 13; + + top_ptr = q; + ret = dvb_encode_rle(&q, buf_size, + h->rects[object_id]->data[0], + h->rects[object_id]->w * 2, + h->rects[object_id]->w, + h->rects[object_id]->h >> 1); + if (ret < 0) + return ret; + buf_size -= ret; + bottom_ptr = q; + ret = dvb_encode_rle(&q, buf_size, + h->rects[object_id]->data[0] + h->rects[object_id]->w, + h->rects[object_id]->w * 2, + h->rects[object_id]->w, + h->rects[object_id]->h >> 1); + if (ret < 0) + return ret; + buf_size -= ret; + + bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr); + bytestream_put_be16(&pbottom_field_len, q - bottom_ptr); + } + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + } + } + + /* end of display set segment */ + + if (buf_size < 6) + return AVERROR_BUFFER_TOO_SMALL; + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x80; /* segment_type */ + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + buf_size -= 6; + + s->object_version = (s->object_version + 1) & 0xf; + return q - outbuf; +} + +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, +}; diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index c526091eb..a0647e58b 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -38,6 +38,7 @@ #include "libavutil/avassert.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "avcodec.h" diff --git a/libavcodec/dvdsub_parser.c b/libavcodec/dvdsub_parser.c index 698ccb698..054af69db 100644 --- a/libavcodec/dvdsub_parser.c +++ b/libavcodec/dvdsub_parser.c @@ -32,11 +32,6 @@ typedef struct DVDSubParseContext { int packet_index; } DVDSubParseContext; -static av_cold int dvdsub_parse_init(AVCodecParserContext *s) -{ - return 0; -} - static int dvdsub_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, @@ -92,7 +87,6 @@ static av_cold void dvdsub_parse_close(AVCodecParserContext *s) AVCodecParser ff_dvdsub_parser = { .codec_ids = { AV_CODEC_ID_DVD_SUBTITLE }, .priv_data_size = sizeof(DVDSubParseContext), - .parser_init = dvdsub_parse_init, .parser_parse = dvdsub_parse, .parser_close = dvdsub_parse_close, }; diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c index e54b5f0d7..9fa9d5b6d 100644 --- a/libavcodec/dvdsubenc.c +++ b/libavcodec/dvdsubenc.c @@ -424,6 +424,29 @@ fail: return ret; } +static int bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf) +{ + int ret; + char *str; + + ret = av_bprint_finalize(buf, &str); + if (ret < 0) + return ret; + if (!av_bprint_is_complete(buf)) { + av_free(str); + return AVERROR(ENOMEM); + } + + avctx->extradata = str; + /* Note: the string is NUL terminated (so extradata can be read as a + * string), but the ending character is not accounted in the size (in + * binary formats you are likely not supposed to mux that character). When + * extradata is copied, it is also padded with AV_INPUT_BUFFER_PADDING_SIZE + * zeros. */ + avctx->extradata_size = buf->len; + return 0; +} + static int dvdsub_init(AVCodecContext *avctx) { DVDSubtitleContext *dvdc = avctx->priv_data; @@ -451,7 +474,7 @@ static int dvdsub_init(AVCodecContext *avctx) av_bprintf(&extradata, " %06"PRIx32"%c", dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n'); - ret = avpriv_bprint_to_extradata(avctx, &extradata); + ret = bprint_to_extradata(avctx, &extradata); if (ret < 0) return ret; diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c index 3e98d1b38..233e2b68c 100644 --- a/libavcodec/dvenc.c +++ b/libavcodec/dvenc.c @@ -30,6 +30,7 @@ #include "libavutil/attributes.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" @@ -215,8 +216,8 @@ static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, if (s->avctx->flags & AV_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); + int is = s->ildct_cmp(NULL, data, NULL, linesize * 2, 4) + + s->ildct_cmp(NULL, data + linesize, NULL, linesize * 2, 4); return ps > is; } } @@ -317,9 +318,8 @@ static const int dv100_qstep_inv[16] = { 65536, 65536, 32768, 21845, 16384, 13107, 10923, 9362, 8192, 4096, 3641, 3277, 2979, 2731, 2341, 1260, }; -/* DV100 weights are pre-zigzagged, inverted and multiplied by 2^(dv100_weight_shift) +/* DV100 weights are pre-zigzagged, inverted and multiplied by 2^16 (in DV100 the AC components are divided by the spec weights) */ -static const int dv100_weight_shift = 16; static const int dv_weight_1080[2][64] = { { 8192, 65536, 65536, 61681, 61681, 61681, 58254, 58254, 58254, 58254, 58254, 58254, 55188, 58254, 58254, 55188, @@ -511,7 +511,7 @@ static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, i if (data) { if (DV_PROFILE_IS_HD(s->sys)) { - s->get_pixels(blk, data, linesize << bi->dct_mode); + s->get_pixels(blk, data, linesize * (1 << bi->dct_mode)); s->fdct[0](blk); } else { bi->dct_mode = dv_guess_dct_mode(s, data, linesize); @@ -860,7 +860,7 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg) qnos[mb_index] = DV_PROFILE_IS_HD(s->sys) ? 1 : 15; - y_ptr = s->frame->data[0] + ((mb_y * s->frame->linesize[0] + mb_x) << 3); + y_ptr = s->frame->data[0] + (mb_y * s->frame->linesize[0] + mb_x) * 8; linesize = s->frame->linesize[0]; if (s->sys->height == 1080 && mb_y < 134) @@ -874,12 +874,12 @@ static int dv_encode_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->frame->linesize[0] << (3*!enc_blk->dct_mode); + y_stride = s->frame->linesize[0] * (1 << (3*!enc_blk->dct_mode)); } else { y_stride = 16; } y_ptr = s->frame->data[0] + - ((mb_y * s->frame->linesize[0] + mb_x) << 3); + (mb_y * s->frame->linesize[0] + mb_x) * 8; linesize = s->frame->linesize[0]; if (s->sys->video_stype == 4) { /* SD 422 */ @@ -898,17 +898,17 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg) enc_blk += 4; /* initializing chrominance blocks */ - 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))) << 3); + 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))) * 8; for (j = 2; j; j--) { uint8_t *c_ptr = s->frame->data[j] + c_offset; linesize = s->frame->linesize[j]; - y_stride = (mb_y == 134) ? 8 : (s->frame->linesize[j] << (3*!enc_blk->dct_mode)); + y_stride = (mb_y == 134) ? 8 : (s->frame->linesize[j] * (1 << (3*!enc_blk->dct_mode))); 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); + d = c_ptr + linesize * 8; b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c index f6edc03e1..3f62eac25 100644 --- a/libavcodec/dxa.c +++ b/libavcodec/dxa.c @@ -343,7 +343,6 @@ static av_cold int decode_init(AVCodecContext *avctx) c->dsize = avctx->width * avctx->height * 2; 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); } @@ -371,4 +370,5 @@ AVCodec ff_dxa_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c index e5d710069..f314bcec7 100644 --- a/libavcodec/dxtory.c +++ b/libavcodec/dxtory.c @@ -31,24 +31,84 @@ #include "get_bits.h" #include "internal.h" #include "unary.h" +#include "thread.h" + +static int64_t get_raw_size(enum AVPixelFormat fmt, int width, int height) +{ + switch (fmt) { + case AV_PIX_FMT_RGB555LE: + case AV_PIX_FMT_RGB565LE: + return width * height * 2LL; + case AV_PIX_FMT_RGB24: + case AV_PIX_FMT_BGR24: + case AV_PIX_FMT_YUV444P: + return width * height * 3LL; + case AV_PIX_FMT_YUV420P: + return (int64_t)(width * height) + 2 * AV_CEIL_RSHIFT(width, 1) * AV_CEIL_RSHIFT(height, 1); + case AV_PIX_FMT_YUV410P: + return (int64_t)(width * height) + 2 * AV_CEIL_RSHIFT(width, 2) * AV_CEIL_RSHIFT(height, 2); + } + + return 0; +} + +static void do_vflip(AVCodecContext *avctx, AVFrame *pic, int vflip) +{ + if (!vflip) + return; + + switch (pic->format) { + case AV_PIX_FMT_YUV444P: + pic->data[1] += (avctx->height - 1) * pic->linesize[1]; + pic->linesize[1] = -pic->linesize[1]; + pic->data[2] += (avctx->height - 1) * pic->linesize[2]; + pic->linesize[2] = -pic->linesize[2]; + case AV_PIX_FMT_RGB555LE: + case AV_PIX_FMT_RGB565LE: + case AV_PIX_FMT_BGR24: + case AV_PIX_FMT_RGB24: + pic->data[0] += (avctx->height - 1) * pic->linesize[0]; + pic->linesize[0] = -pic->linesize[0]; + break; + case AV_PIX_FMT_YUV410P: + pic->data[0] += (avctx->height - 1) * pic->linesize[0]; + pic->linesize[0] = -pic->linesize[0]; + pic->data[1] += (AV_CEIL_RSHIFT(avctx->height, 2) - 1) * pic->linesize[1]; + pic->linesize[1] = -pic->linesize[1]; + pic->data[2] += (AV_CEIL_RSHIFT(avctx->height, 2) - 1) * pic->linesize[2]; + pic->linesize[2] = -pic->linesize[2]; + break; + case AV_PIX_FMT_YUV420P: + pic->data[0] += (avctx->height - 1) * pic->linesize[0]; + pic->linesize[0] = -pic->linesize[0]; + pic->data[1] += (AV_CEIL_RSHIFT(avctx->height, 1) - 1) * pic->linesize[1]; + pic->linesize[1] = -pic->linesize[1]; + pic->data[2] += (AV_CEIL_RSHIFT(avctx->height, 1) - 1) * pic->linesize[2]; + pic->linesize[2] = -pic->linesize[2]; + break; + } +} static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, - int id, int bpp) + int id, int bpp, uint32_t vflipped) { + ThreadFrame frame = { .f = pic }; int h; uint8_t *dst; int ret; - if (src_size < avctx->width * avctx->height * (int64_t)bpp) { + if (src_size < get_raw_size(id, avctx->width, avctx->height)) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } avctx->pix_fmt = id; - if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + dst = pic->data[0]; for (h = 0; h < avctx->height; h++) { memcpy(dst, src, avctx->width * bpp); @@ -56,33 +116,47 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, dst += pic->linesize[0]; } + do_vflip(avctx, pic, vflipped); + return 0; } static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { + ThreadFrame frame = { .f = pic }; int h, w; uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V; + int height, width, hmargin, vmargin; + int huvborder; int ret; - if (src_size < FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) * 9LL / 8) { + if (src_size < get_raw_size(AV_PIX_FMT_YUV410P, avctx->width, avctx->height)) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } avctx->pix_fmt = AV_PIX_FMT_YUV410P; - if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + + height = avctx->height & ~3; + width = avctx->width & ~3; + hmargin = avctx->width - width; + vmargin = avctx->height - height; + huvborder = AV_CEIL_RSHIFT(avctx->width, 2) - 1; + Y1 = pic->data[0]; Y2 = pic->data[0] + pic->linesize[0]; Y3 = pic->data[0] + pic->linesize[0] * 2; Y4 = pic->data[0] + pic->linesize[0] * 3; U = pic->data[1]; V = pic->data[2]; - for (h = 0; h < avctx->height; h += 4) { - for (w = 0; w < avctx->width; w += 4) { + for (h = 0; h < height; h += 4) { + for (w = 0; w < width; w += 4) { AV_COPY32U(Y1 + w, src); AV_COPY32U(Y2 + w, src + 4); AV_COPY32U(Y3 + w, src + 8); @@ -91,70 +165,151 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, V[w >> 2] = src[17] + 0x80; src += 18; } - Y1 += pic->linesize[0] << 2; - Y2 += pic->linesize[0] << 2; - Y3 += pic->linesize[0] << 2; - Y4 += pic->linesize[0] << 2; + if (hmargin) { + for (w = 0; w < hmargin; w++) { + Y1[width + w] = src[w]; + Y2[width + w] = src[w + hmargin * 1]; + Y3[width + w] = src[w + hmargin * 2]; + Y4[width + w] = src[w + hmargin * 3]; + } + src += 4 * hmargin; + U[huvborder] = src[0] + 0x80; + V[huvborder] = src[1] + 0x80; + src += 2; + } + Y1 += pic->linesize[0] * 4; + Y2 += pic->linesize[0] * 4; + Y3 += pic->linesize[0] * 4; + Y4 += pic->linesize[0] * 4; U += pic->linesize[1]; V += pic->linesize[2]; } + if (vmargin) { + for (w = 0; w < width; w += 4) { + AV_COPY32U(Y1 + w, src); + if (vmargin > 1) + AV_COPY32U(Y2 + w, src + 4); + if (vmargin > 2) + AV_COPY32U(Y3 + w, src + 8); + src += 4 * vmargin; + U[w >> 2] = src[0] + 0x80; + V[w >> 2] = src[1] + 0x80; + src += 2; + } + if (hmargin) { + for (w = 0; w < hmargin; w++) { + AV_COPY32U(Y1 + w, src); + if (vmargin > 1) + AV_COPY32U(Y2 + w, src + 4); + if (vmargin > 2) + AV_COPY32U(Y3 + w, src + 8); + src += 4 * vmargin; + } + U[huvborder] = src[0] + 0x80; + V[huvborder] = src[1] + 0x80; + src += 2; + } + } + + do_vflip(avctx, pic, vflipped); + return 0; } static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { + ThreadFrame frame = { .f = pic }; int h, w; uint8_t *Y1, *Y2, *U, *V; + int height, width, hmargin, vmargin; + int huvborder; int ret; - if (src_size < FFALIGN(avctx->width, 2) * FFALIGN(avctx->height, 2) * 3LL / 2) { + if (src_size < get_raw_size(AV_PIX_FMT_YUV420P, avctx->width, avctx->height)) { 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) + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + + height = avctx->height & ~1; + width = avctx->width & ~1; + hmargin = avctx->width - width; + vmargin = avctx->height - height; + huvborder = AV_CEIL_RSHIFT(avctx->width, 1) - 1; + Y1 = pic->data[0]; Y2 = pic->data[0] + pic->linesize[0]; U = pic->data[1]; V = pic->data[2]; - for (h = 0; h < avctx->height; h += 2) { - for (w = 0; w < avctx->width; w += 2) { + for (h = 0; h < height; h += 2) { + for (w = 0; w < width; w += 2) { AV_COPY16(Y1 + w, src); AV_COPY16(Y2 + w, src + 2); U[w >> 1] = src[4] + 0x80; V[w >> 1] = src[5] + 0x80; src += 6; } - Y1 += pic->linesize[0] << 1; - Y2 += pic->linesize[0] << 1; + if (hmargin) { + Y1[width + 1] = src[0]; + Y2[width + 1] = src[1]; + U[huvborder] = src[2] + 0x80; + V[huvborder] = src[3] + 0x80; + src += 4; + } + Y1 += pic->linesize[0] * 2; + Y2 += pic->linesize[0] * 2; U += pic->linesize[1]; V += pic->linesize[2]; } + if (vmargin) { + for (w = 0; w < width; w += 2) { + AV_COPY16U(Y1 + w, src); + U[w >> 1] = src[0] + 0x80; + V[w >> 1] = src[1] + 0x80; + src += 4; + } + if (hmargin) { + Y1[w] = src[0]; + U[huvborder] = src[1] + 0x80; + V[huvborder] = src[2] + 0x80; + src += 3; + } + } + + do_vflip(avctx, pic, vflipped); + return 0; } static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { + ThreadFrame frame = { .f = pic }; int h, w; uint8_t *Y, *U, *V; int ret; - if (src_size < avctx->width * avctx->height * 3LL) { + if (src_size < get_raw_size(AV_PIX_FMT_YUV444P, avctx->width, avctx->height)) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } avctx->pix_fmt = AV_PIX_FMT_YUV444P; - if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + Y = pic->data[0]; U = pic->data[1]; V = pic->data[2]; @@ -169,6 +324,8 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, V += pic->linesize[2]; } + do_vflip(avctx, pic, vflipped); + return 0; } @@ -270,8 +427,10 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, decode_slice_func decode_slice, setup_lru_func setup_lru, - enum AVPixelFormat fmt) + enum AVPixelFormat fmt, + uint32_t vflipped) { + ThreadFrame frame = { .f = pic }; GetByteContext gb, gb_check; GetBitContext gb2; int nslices, slice, line = 0; @@ -298,9 +457,11 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, return AVERROR_INVALIDDATA; avctx->pix_fmt = fmt; - if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + for (slice = 0; slice < nslices; slice++) { slice_size = bytestream2_get_le32(&gb); @@ -322,6 +483,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, avpriv_request_sample(avctx, "Not enough slice data available"); } + do_vflip(avctx, pic, vflipped); + return 0; } @@ -336,7 +499,7 @@ static int dx2_decode_slice_5x5(GetBitContext *gb, AVFrame *frame, int stride = frame->linesize[0]; uint8_t *dst = frame->data[0] + stride * line; - for (y = 0; y < left && get_bits_left(gb) > 6 * width; y++) { + for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) { for (x = 0; x < width; x++) { b = decode_sym_565(gb, lru[0], 5); g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5); @@ -379,19 +542,20 @@ static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame, } static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size, int is_565) + const uint8_t *src, int src_size, int is_565, + uint32_t vflipped) { enum AVPixelFormat fmt = AV_PIX_FMT_RGB24; if (is_565) return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_565, setup_lru_565, - fmt); + fmt, vflipped); else return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_555, setup_lru_555, - fmt); + fmt, vflipped); } static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame, @@ -402,7 +566,7 @@ static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame, int stride = frame->linesize[0]; uint8_t *dst = frame->data[0] + stride * line; - for (y = 0; y < left && get_bits_left(gb) > 6 * width; y++) { + for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) { for (x = 0; x < width; x++) { dst[x * 3 + 0] = decode_sym(gb, lru[0]); dst[x * 3 + 1] = decode_sym(gb, lru[1]); @@ -424,12 +588,13 @@ static void default_setup_lru(uint8_t lru[3][8]) } static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_rgb, default_setup_lru, - AV_PIX_FMT_BGR24); + AV_PIX_FMT_BGR24, vflipped); } static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, @@ -447,31 +612,68 @@ static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, uint8_t *U = frame->data[1] + (ustride >> 2) * line; uint8_t *V = frame->data[2] + (vstride >> 2) * line; - for (y = 0; y < left - 3 && get_bits_left(gb) > 9 * width; y += 4) { - for (x = 0; x < width; x += 4) { + int h, w, hmargin, vmargin; + int huvborder; + + h = frame->height & ~3; + w = frame->width & ~3; + hmargin = frame->width - w; + vmargin = frame->height - h; + huvborder = AV_CEIL_RSHIFT(frame->width, 2) - 1; + + for (y = 0; y < left - 3 && get_bits_left(gb) >= 18 * w / 4 + hmargin * 4 + (!!hmargin * 2); y += 4) { + for (x = 0; x < w; x += 4) { for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) Y[x + i + j * ystride] = decode_sym(gb, lru[0]); U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80; V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80; } + if (hmargin) { + for (j = 0; j < 4; j++) + for (i = 0; i < hmargin; i++) + Y[x + i + j * ystride] = decode_sym(gb, lru[0]); + U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80; + V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80; + } Y += ystride * 4; U += ustride; V += vstride; } + if (vmargin && y + vmargin == left) { + for (x = 0; x < width; x += 4) { + for (j = 0; j < vmargin; j++) + for (i = 0; i < 4; i++) + Y[x + i + j * ystride] = decode_sym(gb, lru[0]); + U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80; + V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80; + } + if (hmargin) { + for (j = 0; j < vmargin; j++) { + for (i = 0; i < hmargin; i++) + Y[x + i + j * ystride] = decode_sym(gb, lru[0]); + } + U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80; + V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80; + } + + y += vmargin; + } + return y; } static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_410, default_setup_lru, - AV_PIX_FMT_YUV410P); + AV_PIX_FMT_YUV410P, vflipped); } static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, @@ -490,9 +692,17 @@ static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, uint8_t *U = frame->data[1] + (ustride >> 1) * line; uint8_t *V = frame->data[2] + (vstride >> 1) * line; + int h, w, hmargin, vmargin; + int huvborder; - for (y = 0; y < left - 1 && get_bits_left(gb) > 6 * width; y += 2) { - for (x = 0; x < width; x += 2) { + h = frame->height & ~1; + w = frame->width & ~1; + hmargin = frame->width - w; + vmargin = frame->height - h; + huvborder = AV_CEIL_RSHIFT(frame->width, 1) - 1; + + for (y = 0; y < left - 1 && get_bits_left(gb) >= 3 * w + hmargin * 4; y += 2) { + for (x = 0; x < w; 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]); @@ -500,22 +710,42 @@ static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80; V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80; } + if (hmargin) { + Y[x + 0 * ystride] = decode_sym(gb, lru[0]); + Y[x + 1 * ystride] = decode_sym(gb, lru[0]); + U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80; + V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80; + } Y += ystride * 2; U += ustride; V += vstride; } + if (vmargin) { + for (x = 0; x < width; x += 2) { + Y[x + 0] = decode_sym(gb, lru[0]); + U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80; + V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80; + } + if (hmargin) { + Y[x] = decode_sym(gb, lru[0]); + U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80; + V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80; + } + } + return y; } static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_420, default_setup_lru, - AV_PIX_FMT_YUV420P); + AV_PIX_FMT_YUV420P, vflipped); } static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, @@ -534,7 +764,7 @@ static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, uint8_t *U = frame->data[1] + ustride * line; uint8_t *V = frame->data[2] + vstride * line; - for (y = 0; y < left && get_bits_left(gb) > 6 * width; y++) { + for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) { for (x = 0; x < width; x++) { Y[x] = decode_sym(gb, lru[0]); U[x] = decode_sym(gb, lru[1]) ^ 0x80; @@ -550,12 +780,13 @@ static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, } static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_444, default_setup_lru, - AV_PIX_FMT_YUV444P); + AV_PIX_FMT_YUV444P, vflipped); } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, @@ -563,57 +794,75 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, { AVFrame *pic = data; const uint8_t *src = avpkt->data; - int ret; + uint32_t type; + int vflipped, ret; if (avpkt->size < 16) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } - switch (AV_RB32(src)) { + type = AV_RB32(src); + vflipped = !!(type & 0x20); + + switch (type) { + case 0x01000021: case 0x01000001: ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, - AV_PIX_FMT_BGR24, 3); + AV_PIX_FMT_BGR24, 3, vflipped); break; + case 0x01000029: case 0x01000009: - ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x02000021: case 0x02000001: - ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x02000029: case 0x02000009: - ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x03000021: case 0x03000001: - ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x03000029: case 0x03000009: - ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x04000021: case 0x04000001: - ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x04000029: case 0x04000009: - ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x17000021: case 0x17000001: ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, - AV_PIX_FMT_RGB565LE, 2); + AV_PIX_FMT_RGB565LE, 2, vflipped); break; + case 0x17000029: case 0x17000009: - ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1); + ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1, vflipped); break; + case 0x18000021: + case 0x19000021: case 0x18000001: case 0x19000001: ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, - AV_PIX_FMT_RGB555LE, 2); + AV_PIX_FMT_RGB555LE, 2, vflipped); break; + case 0x18000029: + case 0x19000029: case 0x18000009: case 0x19000009: - ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0); + ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0, vflipped); break; default: - avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src)); + avpriv_request_sample(avctx, "Frame header %"PRIX32, type); return AVERROR_PATCHWELCOME; } @@ -633,5 +882,5 @@ AVCodec ff_dxtory_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DXTORY, .decode = decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, }; diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index 32416112b..b57ea2194 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -45,6 +45,7 @@ DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main, 0x5b11d51b, 0x2f4c,0x4452,0xbc,0xc3,0x0 DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main10,0x107af0e0, 0xef1a,0x4d19,0xab,0xa8,0x67,0xa1,0x63,0x07,0x3d,0x13); DEFINE_GUID(ff_DXVA2_ModeVP9_VLD_Profile0,0x463707f8,0xa1d0,0x4585,0x87,0x6d,0x83,0xaa,0x6d,0x60,0xb8,0x9e); DEFINE_GUID(ff_DXVA2_ModeVP9_VLD_10bit_Profile2,0xa4c749ef,0x6ecf,0x48aa,0x84,0x48,0x50,0xa7,0xa1,0x16,0x5f,0xf7); +DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_Profile0,0xb8be4ccb,0xcf53,0x46ba,0x8d,0x59,0xd6,0xb8,0xa6,0xda,0x5d,0x2a); DEFINE_GUID(ff_DXVA2_NoEncrypt, 0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5); DEFINE_GUID(ff_GUID_NULL, 0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); DEFINE_GUID(ff_IID_IDirectXVideoDecoderService, 0xfc51a551,0xd5e7,0x11d9,0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02); @@ -72,6 +73,8 @@ static const int prof_vp9_profile0[] = {FF_PROFILE_VP9_0, FF_PROFILE_UNKNOWN}; static const int prof_vp9_profile2[] = {FF_PROFILE_VP9_2, FF_PROFILE_UNKNOWN}; +static const int prof_av1_profile0[] = {FF_PROFILE_AV1_MAIN, + FF_PROFILE_UNKNOWN}; static const dxva_mode dxva_modes[] = { /* MPEG-2 */ @@ -98,6 +101,9 @@ static const dxva_mode dxva_modes[] = { { &ff_DXVA2_ModeVP9_VLD_Profile0, AV_CODEC_ID_VP9, prof_vp9_profile0 }, { &ff_DXVA2_ModeVP9_VLD_10bit_Profile2, AV_CODEC_ID_VP9, prof_vp9_profile2 }, + /* AV1 */ + { &ff_DXVA2_ModeAV1_VLD_Profile0, AV_CODEC_ID_AV1, prof_av1_profile0 }, + { NULL, 0 }, }; @@ -604,7 +610,7 @@ int ff_dxva2_common_frame_params(AVCodecContext *avctx, surface_alignment = 32; /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure all coding features have enough room to work with */ - else if (avctx->codec_id == AV_CODEC_ID_HEVC) + else if (avctx->codec_id == AV_CODEC_ID_HEVC || avctx->codec_id == AV_CODEC_ID_AV1) surface_alignment = 128; else surface_alignment = 16; @@ -615,7 +621,7 @@ int ff_dxva2_common_frame_params(AVCodecContext *avctx, /* add surfaces based on number of possible refs */ if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC) num_surfaces += 16; - else if (avctx->codec_id == AV_CODEC_ID_VP9) + else if (avctx->codec_id == AV_CODEC_ID_VP9 || avctx->codec_id == AV_CODEC_ID_AV1) num_surfaces += 8; else num_surfaces += 2; diff --git a/libavcodec/dxva2_av1.c b/libavcodec/dxva2_av1.c new file mode 100644 index 000000000..aa14e473d --- /dev/null +++ b/libavcodec/dxva2_av1.c @@ -0,0 +1,506 @@ +/* + * DXVA2 AV1 HW acceleration. + * + * copyright (c) 2020 Hendrik Leppkes + * + * 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/avassert.h" +#include "libavutil/pixdesc.h" + +#include "dxva2_internal.h" +#include "av1dec.h" + +#define MAX_TILES 256 + +struct AV1DXVAContext { + FFDXVASharedContext shared; + + unsigned int bitstream_allocated; + uint8_t *bitstream_cache; +}; + +struct av1_dxva2_picture_context { + DXVA_PicParams_AV1 pp; + unsigned tile_count; + DXVA_Tile_AV1 tiles[MAX_TILES]; + uint8_t *bitstream; + unsigned bitstream_size; +}; + +static int get_bit_depth_from_seq(const AV1RawSequenceHeader *seq) +{ + if (seq->seq_profile == 2 && seq->color_config.high_bitdepth) + return seq->color_config.twelve_bit ? 12 : 10; + else if (seq->seq_profile <= 2 && seq->color_config.high_bitdepth) + return 10; + else + return 8; +} + +static int fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const AV1DecContext *h, + DXVA_PicParams_AV1 *pp) +{ + int i,j, uses_lr; + const AV1RawSequenceHeader *seq = h->raw_seq; + const AV1RawFrameHeader *frame_header = h->raw_frame_header; + const AV1RawFilmGrainParams *film_grain = &h->cur_frame.film_grain; + + unsigned char remap_lr_type[4] = { AV1_RESTORE_NONE, AV1_RESTORE_SWITCHABLE, AV1_RESTORE_WIENER, AV1_RESTORE_SGRPROJ }; + int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && film_grain->apply_grain; + + memset(pp, 0, sizeof(*pp)); + + pp->width = avctx->width; + pp->height = avctx->height; + + pp->max_width = seq->max_frame_width_minus_1 + 1; + pp->max_height = seq->max_frame_height_minus_1 + 1; + + pp->CurrPicTextureIndex = ff_dxva2_get_surface_index(avctx, ctx, h->cur_frame.tf.f); + pp->superres_denom = frame_header->use_superres ? frame_header->coded_denom : AV1_SUPERRES_NUM; + pp->bitdepth = get_bit_depth_from_seq(seq); + pp->seq_profile = seq->seq_profile; + + /* Tiling info */ + pp->tiles.cols = frame_header->tile_cols; + pp->tiles.rows = frame_header->tile_rows; + pp->tiles.context_update_id = frame_header->context_update_tile_id; + + for (i = 0; i < pp->tiles.cols; i++) + pp->tiles.widths[i] = frame_header->width_in_sbs_minus_1[i] + 1; + + for (i = 0; i < pp->tiles.rows; i++) + pp->tiles.heights[i] = frame_header->height_in_sbs_minus_1[i] + 1; + + /* Coding tools */ + pp->coding.use_128x128_superblock = seq->use_128x128_superblock; + pp->coding.intra_edge_filter = seq->enable_intra_edge_filter; + pp->coding.interintra_compound = seq->enable_interintra_compound; + pp->coding.masked_compound = seq->enable_masked_compound; + pp->coding.warped_motion = frame_header->allow_warped_motion; + pp->coding.dual_filter = seq->enable_dual_filter; + pp->coding.jnt_comp = seq->enable_jnt_comp; + pp->coding.screen_content_tools = frame_header->allow_screen_content_tools; + pp->coding.integer_mv = frame_header->force_integer_mv || !(frame_header->frame_type & 1); + pp->coding.cdef = seq->enable_cdef; + pp->coding.restoration = seq->enable_restoration; + pp->coding.film_grain = seq->film_grain_params_present && !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN); + pp->coding.intrabc = frame_header->allow_intrabc; + pp->coding.high_precision_mv = frame_header->allow_high_precision_mv; + pp->coding.switchable_motion_mode = frame_header->is_motion_mode_switchable; + pp->coding.filter_intra = seq->enable_filter_intra; + pp->coding.disable_frame_end_update_cdf = frame_header->disable_frame_end_update_cdf; + pp->coding.disable_cdf_update = frame_header->disable_cdf_update; + pp->coding.reference_mode = frame_header->reference_select; + pp->coding.skip_mode = frame_header->skip_mode_present; + pp->coding.reduced_tx_set = frame_header->reduced_tx_set; + pp->coding.superres = frame_header->use_superres; + pp->coding.tx_mode = frame_header->tx_mode; + pp->coding.use_ref_frame_mvs = frame_header->use_ref_frame_mvs; + pp->coding.enable_ref_frame_mvs = seq->enable_ref_frame_mvs; + pp->coding.reference_frame_update = 1; // 0 for show_existing_frame with key frames, but those are not passed to the hwaccel + + /* Format & Picture Info flags */ + pp->format.frame_type = frame_header->frame_type; + pp->format.show_frame = frame_header->show_frame; + pp->format.showable_frame = frame_header->showable_frame; + pp->format.subsampling_x = seq->color_config.subsampling_x; + pp->format.subsampling_y = seq->color_config.subsampling_y; + pp->format.mono_chrome = seq->color_config.mono_chrome; + + /* References */ + pp->primary_ref_frame = frame_header->primary_ref_frame; + pp->order_hint = frame_header->order_hint; + pp->order_hint_bits = seq->enable_order_hint ? seq->order_hint_bits_minus_1 + 1 : 0; + + memset(pp->RefFrameMapTextureIndex, 0xFF, sizeof(pp->RefFrameMapTextureIndex)); + for (i = 0; i < AV1_REFS_PER_FRAME; i++) { + int8_t ref_idx = frame_header->ref_frame_idx[i]; + AVFrame *ref_frame = h->ref[ref_idx].tf.f; + + pp->frame_refs[i].width = ref_frame->width; + pp->frame_refs[i].height = ref_frame->height; + pp->frame_refs[i].Index = ref_frame->buf[0] ? ref_idx : 0xFF; + + /* Global Motion */ + pp->frame_refs[i].wminvalid = (h->cur_frame.gm_type[AV1_REF_FRAME_LAST + i] == AV1_WARP_MODEL_IDENTITY); + pp->frame_refs[i].wmtype = h->cur_frame.gm_type[AV1_REF_FRAME_LAST + i]; + for (j = 0; j < 6; ++j) { + pp->frame_refs[i].wmmat[j] = h->cur_frame.gm_params[AV1_REF_FRAME_LAST + i][j]; + } + } + for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { + AVFrame *ref_frame = h->ref[i].tf.f; + if (ref_frame->buf[0]) + pp->RefFrameMapTextureIndex[i] = ff_dxva2_get_surface_index(avctx, ctx, ref_frame); + } + + /* Loop filter parameters */ + pp->loop_filter.filter_level[0] = frame_header->loop_filter_level[0]; + pp->loop_filter.filter_level[1] = frame_header->loop_filter_level[1]; + pp->loop_filter.filter_level_u = frame_header->loop_filter_level[2]; + pp->loop_filter.filter_level_v = frame_header->loop_filter_level[3]; + pp->loop_filter.sharpness_level = frame_header->loop_filter_sharpness; + pp->loop_filter.mode_ref_delta_enabled = frame_header->loop_filter_delta_enabled; + pp->loop_filter.mode_ref_delta_update = frame_header->loop_filter_delta_update; + pp->loop_filter.delta_lf_multi = frame_header->delta_lf_multi; + pp->loop_filter.delta_lf_present = frame_header->delta_lf_present; + pp->loop_filter.delta_lf_res = frame_header->delta_lf_res; + + for (i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) { + pp->loop_filter.ref_deltas[i] = frame_header->loop_filter_ref_deltas[i]; + } + + pp->loop_filter.mode_deltas[0] = frame_header->loop_filter_mode_deltas[0]; + pp->loop_filter.mode_deltas[1] = frame_header->loop_filter_mode_deltas[1]; + pp->loop_filter.frame_restoration_type[0] = remap_lr_type[frame_header->lr_type[0]]; + pp->loop_filter.frame_restoration_type[1] = remap_lr_type[frame_header->lr_type[1]]; + pp->loop_filter.frame_restoration_type[2] = remap_lr_type[frame_header->lr_type[2]]; + uses_lr = frame_header->lr_type[0] || frame_header->lr_type[1] || frame_header->lr_type[2]; + pp->loop_filter.log2_restoration_unit_size[0] = uses_lr ? (6 + frame_header->lr_unit_shift) : 8; + pp->loop_filter.log2_restoration_unit_size[1] = uses_lr ? (6 + frame_header->lr_unit_shift - frame_header->lr_uv_shift) : 8; + pp->loop_filter.log2_restoration_unit_size[2] = uses_lr ? (6 + frame_header->lr_unit_shift - frame_header->lr_uv_shift) : 8; + + /* Quantization */ + pp->quantization.delta_q_present = frame_header->delta_q_present; + pp->quantization.delta_q_res = frame_header->delta_q_res; + pp->quantization.base_qindex = frame_header->base_q_idx; + pp->quantization.y_dc_delta_q = frame_header->delta_q_y_dc; + pp->quantization.u_dc_delta_q = frame_header->delta_q_u_dc; + pp->quantization.v_dc_delta_q = frame_header->delta_q_v_dc; + pp->quantization.u_ac_delta_q = frame_header->delta_q_u_ac; + pp->quantization.v_ac_delta_q = frame_header->delta_q_v_ac; + pp->quantization.qm_y = frame_header->using_qmatrix ? frame_header->qm_y : 0xFF; + pp->quantization.qm_u = frame_header->using_qmatrix ? frame_header->qm_u : 0xFF; + pp->quantization.qm_v = frame_header->using_qmatrix ? frame_header->qm_v : 0xFF; + + /* Cdef parameters */ + pp->cdef.damping = frame_header->cdef_damping_minus_3; + pp->cdef.bits = frame_header->cdef_bits; + for (i = 0; i < 8; i++) { + pp->cdef.y_strengths[i].primary = frame_header->cdef_y_pri_strength[i]; + pp->cdef.y_strengths[i].secondary = frame_header->cdef_y_sec_strength[i]; + pp->cdef.uv_strengths[i].primary = frame_header->cdef_uv_pri_strength[i]; + pp->cdef.uv_strengths[i].secondary = frame_header->cdef_uv_sec_strength[i]; + } + + /* Misc flags */ + pp->interp_filter = frame_header->interpolation_filter; + + /* Segmentation */ + pp->segmentation.enabled = frame_header->segmentation_enabled; + pp->segmentation.update_map = frame_header->segmentation_update_map; + pp->segmentation.update_data = frame_header->segmentation_update_data; + pp->segmentation.temporal_update = frame_header->segmentation_temporal_update; + for (i = 0; i < AV1_MAX_SEGMENTS; i++) { + for (j = 0; j < AV1_SEG_LVL_MAX; j++) { + pp->segmentation.feature_mask[i].mask |= frame_header->feature_enabled[i][j] << j; + pp->segmentation.feature_data[i][j] = frame_header->feature_value[i][j]; + } + } + + /* Film grain */ + if (apply_grain) { + pp->film_grain.apply_grain = 1; + pp->film_grain.scaling_shift_minus8 = film_grain->grain_scaling_minus_8; + pp->film_grain.chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma; + pp->film_grain.ar_coeff_lag = film_grain->ar_coeff_lag; + pp->film_grain.ar_coeff_shift_minus6 = film_grain->ar_coeff_shift_minus_6; + pp->film_grain.grain_scale_shift = film_grain->grain_scale_shift; + pp->film_grain.overlap_flag = film_grain->overlap_flag; + pp->film_grain.clip_to_restricted_range = film_grain->clip_to_restricted_range; + pp->film_grain.matrix_coeff_is_identity = (seq->color_config.matrix_coefficients == AVCOL_SPC_RGB); + + pp->film_grain.grain_seed = film_grain->grain_seed; + pp->film_grain.num_y_points = film_grain->num_y_points; + for (i = 0; i < film_grain->num_y_points; i++) { + pp->film_grain.scaling_points_y[i][0] = film_grain->point_y_value[i]; + pp->film_grain.scaling_points_y[i][1] = film_grain->point_y_scaling[i]; + } + pp->film_grain.num_cb_points = film_grain->num_cb_points; + for (i = 0; i < film_grain->num_cb_points; i++) { + pp->film_grain.scaling_points_cb[i][0] = film_grain->point_cb_value[i]; + pp->film_grain.scaling_points_cb[i][1] = film_grain->point_cb_scaling[i]; + } + pp->film_grain.num_cr_points = film_grain->num_cr_points; + for (i = 0; i < film_grain->num_cr_points; i++) { + pp->film_grain.scaling_points_cr[i][0] = film_grain->point_cr_value[i]; + pp->film_grain.scaling_points_cr[i][1] = film_grain->point_cr_scaling[i]; + } + for (i = 0; i < 24; i++) { + pp->film_grain.ar_coeffs_y[i] = film_grain->ar_coeffs_y_plus_128[i]; + } + for (i = 0; i < 25; i++) { + pp->film_grain.ar_coeffs_cb[i] = film_grain->ar_coeffs_cb_plus_128[i]; + pp->film_grain.ar_coeffs_cr[i] = film_grain->ar_coeffs_cr_plus_128[i]; + } + pp->film_grain.cb_mult = film_grain->cb_mult; + pp->film_grain.cb_luma_mult = film_grain->cb_luma_mult; + pp->film_grain.cr_mult = film_grain->cr_mult; + pp->film_grain.cr_luma_mult = film_grain->cr_luma_mult; + pp->film_grain.cb_offset = film_grain->cb_offset; + pp->film_grain.cr_offset = film_grain->cr_offset; + pp->film_grain.cr_offset = film_grain->cr_offset; + } + + // XXX: Setting the StatusReportFeedbackNumber breaks decoding on some drivers (tested on NVIDIA 457.09) + // Status Reporting is not used by FFmpeg, hence not providing a number does not cause any issues + //pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++; + return 0; +} + +static int dxva2_av1_start_frame(AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + const AV1DecContext *h = avctx->priv_data; + AVDXVAContext *ctx = DXVA_CONTEXT(avctx); + struct av1_dxva2_picture_context *ctx_pic = h->cur_frame.hwaccel_picture_private; + + if (!DXVA_CONTEXT_VALID(avctx, ctx)) + return -1; + av_assert0(ctx_pic); + + /* Fill up DXVA_PicParams_AV1 */ + if (fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp) < 0) + return -1; + + ctx_pic->bitstream_size = 0; + ctx_pic->bitstream = NULL; + return 0; +} + +static int dxva2_av1_decode_slice(AVCodecContext *avctx, + const uint8_t *buffer, + uint32_t size) +{ + const AV1DecContext *h = avctx->priv_data; + const AV1RawFrameHeader *frame_header = h->raw_frame_header; + struct av1_dxva2_picture_context *ctx_pic = h->cur_frame.hwaccel_picture_private; + struct AV1DXVAContext *ctx = avctx->internal->hwaccel_priv_data; + void *tmp; + + ctx_pic->tile_count = frame_header->tile_cols * frame_header->tile_rows; + + /* too many tiles, exceeding all defined levels in the AV1 spec */ + if (ctx_pic->tile_count > MAX_TILES) + return AVERROR(ENOSYS); + + /* Shortcut if all tiles are in the same buffer */ + if (ctx_pic->tile_count == h->tg_end - h->tg_start + 1) { + ctx_pic->bitstream = (uint8_t *)buffer; + ctx_pic->bitstream_size = size; + + for (uint32_t tile_num = 0; tile_num < ctx_pic->tile_count; tile_num++) { + ctx_pic->tiles[tile_num].DataOffset = h->tile_group_info[tile_num].tile_offset; + ctx_pic->tiles[tile_num].DataSize = h->tile_group_info[tile_num].tile_size; + ctx_pic->tiles[tile_num].row = h->tile_group_info[tile_num].tile_row; + ctx_pic->tiles[tile_num].column = h->tile_group_info[tile_num].tile_column; + ctx_pic->tiles[tile_num].anchor_frame = 0xFF; + } + + return 0; + } + + /* allocate an internal buffer */ + tmp = av_fast_realloc(ctx->bitstream_cache, &ctx->bitstream_allocated, + ctx_pic->bitstream_size + size); + if (!tmp) { + return AVERROR(ENOMEM); + } + ctx_pic->bitstream = ctx->bitstream_cache = tmp; + + memcpy(ctx_pic->bitstream + ctx_pic->bitstream_size, buffer, size); + + for (uint32_t tile_num = h->tg_start; tile_num <= h->tg_end; tile_num++) { + ctx_pic->tiles[tile_num].DataOffset = ctx_pic->bitstream_size + h->tile_group_info[tile_num].tile_offset; + ctx_pic->tiles[tile_num].DataSize = h->tile_group_info[tile_num].tile_size; + ctx_pic->tiles[tile_num].row = h->tile_group_info[tile_num].tile_row; + ctx_pic->tiles[tile_num].column = h->tile_group_info[tile_num].tile_column; + ctx_pic->tiles[tile_num].anchor_frame = 0xFF; + } + + ctx_pic->bitstream_size += size; + + return 0; +} + +static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, + DECODER_BUFFER_DESC *bs, + DECODER_BUFFER_DESC *sc) +{ + const AV1DecContext *h = avctx->priv_data; + AVDXVAContext *ctx = DXVA_CONTEXT(avctx); + struct av1_dxva2_picture_context *ctx_pic = h->cur_frame.hwaccel_picture_private; + void *dxva_data_ptr; + uint8_t *dxva_data; + unsigned dxva_size; + unsigned padding; + unsigned type; + +#if CONFIG_D3D11VA + if (ff_dxva2_is_d3d11(avctx)) { + type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM; + if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, + D3D11VA_CONTEXT(ctx)->decoder, + type, + &dxva_size, &dxva_data_ptr))) + return -1; + } +#endif +#if CONFIG_DXVA2 + if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { + type = DXVA2_BitStreamDateBufferType; + if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, + type, + &dxva_data_ptr, &dxva_size))) + return -1; + } +#endif + + dxva_data = dxva_data_ptr; + + if (ctx_pic->bitstream_size > dxva_size) { + av_log(avctx, AV_LOG_ERROR, "Bitstream size exceeds hardware buffer"); + return -1; + } + + memcpy(dxva_data, ctx_pic->bitstream, ctx_pic->bitstream_size); + + padding = FFMIN(128 - ((ctx_pic->bitstream_size) & 127), dxva_size - ctx_pic->bitstream_size); + if (padding > 0) { + memset(dxva_data + ctx_pic->bitstream_size, 0, padding); + ctx_pic->bitstream_size += padding; + } + +#if CONFIG_D3D11VA + if (ff_dxva2_is_d3d11(avctx)) + if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type))) + return -1; +#endif +#if CONFIG_DXVA2 + if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) + if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type))) + return -1; +#endif + +#if CONFIG_D3D11VA + if (ff_dxva2_is_d3d11(avctx)) { + D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs; + memset(dsc11, 0, sizeof(*dsc11)); + dsc11->BufferType = type; + dsc11->DataSize = ctx_pic->bitstream_size; + dsc11->NumMBsInBuffer = 0; + + type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL; + } +#endif +#if CONFIG_DXVA2 + if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { + DXVA2_DecodeBufferDesc *dsc2 = bs; + memset(dsc2, 0, sizeof(*dsc2)); + dsc2->CompressedBufferType = type; + dsc2->DataSize = ctx_pic->bitstream_size; + dsc2->NumMBsInBuffer = 0; + + type = DXVA2_SliceControlBufferType; + } +#endif + + return ff_dxva2_commit_buffer(avctx, ctx, sc, type, + ctx_pic->tiles, sizeof(*ctx_pic->tiles) * ctx_pic->tile_count, 0); +} + +static int dxva2_av1_end_frame(AVCodecContext *avctx) +{ + const AV1DecContext *h = avctx->priv_data; + struct av1_dxva2_picture_context *ctx_pic = h->cur_frame.hwaccel_picture_private; + int ret; + + if (ctx_pic->bitstream_size <= 0) + return -1; + + ret = ff_dxva2_common_end_frame(avctx, h->cur_frame.tf.f, + &ctx_pic->pp, sizeof(ctx_pic->pp), + NULL, 0, + commit_bitstream_and_slice_buffer); + + return ret; +} + +static int dxva2_av1_uninit(AVCodecContext *avctx) +{ + struct AV1DXVAContext *ctx = avctx->internal->hwaccel_priv_data; + + av_freep(&ctx->bitstream_cache); + ctx->bitstream_allocated = 0; + + return ff_dxva2_decode_uninit(avctx); +} + +#if CONFIG_AV1_DXVA2_HWACCEL +const AVHWAccel ff_av1_dxva2_hwaccel = { + .name = "av1_dxva2", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_AV1, + .pix_fmt = AV_PIX_FMT_DXVA2_VLD, + .init = ff_dxva2_decode_init, + .uninit = dxva2_av1_uninit, + .start_frame = dxva2_av1_start_frame, + .decode_slice = dxva2_av1_decode_slice, + .end_frame = dxva2_av1_end_frame, + .frame_params = ff_dxva2_common_frame_params, + .frame_priv_data_size = sizeof(struct av1_dxva2_picture_context), + .priv_data_size = sizeof(struct AV1DXVAContext), +}; +#endif + +#if CONFIG_AV1_D3D11VA_HWACCEL +const AVHWAccel ff_av1_d3d11va_hwaccel = { + .name = "av1_d3d11va", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_AV1, + .pix_fmt = AV_PIX_FMT_D3D11VA_VLD, + .init = ff_dxva2_decode_init, + .uninit = dxva2_av1_uninit, + .start_frame = dxva2_av1_start_frame, + .decode_slice = dxva2_av1_decode_slice, + .end_frame = dxva2_av1_end_frame, + .frame_params = ff_dxva2_common_frame_params, + .frame_priv_data_size = sizeof(struct av1_dxva2_picture_context), + .priv_data_size = sizeof(struct AV1DXVAContext), +}; +#endif + +#if CONFIG_AV1_D3D11VA2_HWACCEL +const AVHWAccel ff_av1_d3d11va2_hwaccel = { + .name = "av1_d3d11va2", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_AV1, + .pix_fmt = AV_PIX_FMT_D3D11, + .init = ff_dxva2_decode_init, + .uninit = dxva2_av1_uninit, + .start_frame = dxva2_av1_start_frame, + .decode_slice = dxva2_av1_decode_slice, + .end_frame = dxva2_av1_end_frame, + .frame_params = ff_dxva2_common_frame_params, + .frame_priv_data_size = sizeof(struct av1_dxva2_picture_context), + .priv_data_size = sizeof(struct AV1DXVAContext), +}; +#endif diff --git a/libavcodec/dynamic_hdr10_plus.c b/libavcodec/dynamic_hdr10_plus.c new file mode 100644 index 000000000..a602e606e --- /dev/null +++ b/libavcodec/dynamic_hdr10_plus.c @@ -0,0 +1,198 @@ +/* + * 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 "dynamic_hdr10_plus.h" +#include "get_bits.h" + +static const int64_t luminance_den = 1; +static const int32_t peak_luminance_den = 15; +static const int64_t rgb_den = 100000; +static const int32_t fraction_pixel_den = 1000; +static const int32_t knee_point_den = 4095; +static const int32_t bezier_anchor_den = 1023; +static const int32_t saturation_weight_den = 8; + +int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *s, const uint8_t *data, + int size) +{ + GetBitContext gbc, *gb = &gbc; + int ret; + + if (!s) + return AVERROR(ENOMEM); + + ret = init_get_bits8(gb, data, size); + if (ret < 0) + return ret; + + s->application_version = get_bits(gb, 8); + + if (get_bits_left(gb) < 2) + return AVERROR_INVALIDDATA; + s->num_windows = get_bits(gb, 2); + + if (s->num_windows < 1 || s->num_windows > 3) { + return AVERROR_INVALIDDATA; + } + + if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1))) + return AVERROR_INVALIDDATA; + + for (int w = 1; w < s->num_windows; w++) { + // The corners are set to absolute coordinates here. They should be + // converted to the relative coordinates (in [0, 1]) in the decoder. + AVHDRPlusColorTransformParams *params = &s->params[w]; + params->window_upper_left_corner_x = + (AVRational){get_bits(gb, 16), 1}; + params->window_upper_left_corner_y = + (AVRational){get_bits(gb, 16), 1}; + params->window_lower_right_corner_x = + (AVRational){get_bits(gb, 16), 1}; + params->window_lower_right_corner_y = + (AVRational){get_bits(gb, 16), 1}; + + params->center_of_ellipse_x = get_bits(gb, 16); + params->center_of_ellipse_y = get_bits(gb, 16); + params->rotation_angle = get_bits(gb, 8); + params->semimajor_axis_internal_ellipse = get_bits(gb, 16); + params->semimajor_axis_external_ellipse = get_bits(gb, 16); + params->semiminor_axis_external_ellipse = get_bits(gb, 16); + params->overlap_process_option = get_bits1(gb); + } + + if (get_bits_left(gb) < 28) + return AVERROR(EINVAL); + + s->targeted_system_display_maximum_luminance = + (AVRational){get_bits_long(gb, 27), luminance_den}; + s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb); + + if (s->targeted_system_display_actual_peak_luminance_flag) { + int rows, cols; + if (get_bits_left(gb) < 10) + return AVERROR(EINVAL); + rows = get_bits(gb, 5); + cols = get_bits(gb, 5); + if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) { + return AVERROR_INVALIDDATA; + } + s->num_rows_targeted_system_display_actual_peak_luminance = rows; + s->num_cols_targeted_system_display_actual_peak_luminance = cols; + + if (get_bits_left(gb) < (rows * cols * 4)) + return AVERROR(EINVAL); + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + s->targeted_system_display_actual_peak_luminance[i][j] = + (AVRational){get_bits(gb, 4), peak_luminance_den}; + } + } + } + for (int w = 0; w < s->num_windows; w++) { + AVHDRPlusColorTransformParams *params = &s->params[w]; + if (get_bits_left(gb) < (3 * 17 + 17 + 4)) + return AVERROR(EINVAL); + + for (int i = 0; i < 3; i++) { + params->maxscl[i] = + (AVRational){get_bits(gb, 17), rgb_den}; + } + params->average_maxrgb = + (AVRational){get_bits(gb, 17), rgb_den}; + params->num_distribution_maxrgb_percentiles = get_bits(gb, 4); + + if (get_bits_left(gb) < + (params->num_distribution_maxrgb_percentiles * 24)) + return AVERROR(EINVAL); + + for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) { + params->distribution_maxrgb[i].percentage = get_bits(gb, 7); + params->distribution_maxrgb[i].percentile = + (AVRational){get_bits(gb, 17), rgb_den}; + } + + if (get_bits_left(gb) < 10) + return AVERROR(EINVAL); + + params->fraction_bright_pixels = (AVRational){get_bits(gb, 10), fraction_pixel_den}; + } + if (get_bits_left(gb) < 1) + return AVERROR(EINVAL); + s->mastering_display_actual_peak_luminance_flag = get_bits1(gb); + if (s->mastering_display_actual_peak_luminance_flag) { + int rows, cols; + if (get_bits_left(gb) < 10) + return AVERROR(EINVAL); + rows = get_bits(gb, 5); + cols = get_bits(gb, 5); + if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) { + return AVERROR_INVALIDDATA; + } + s->num_rows_mastering_display_actual_peak_luminance = rows; + s->num_cols_mastering_display_actual_peak_luminance = cols; + + if (get_bits_left(gb) < (rows * cols * 4)) + return AVERROR(EINVAL); + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + s->mastering_display_actual_peak_luminance[i][j] = + (AVRational){get_bits(gb, 4), peak_luminance_den}; + } + } + } + + for (int w = 0; w < s->num_windows; w++) { + AVHDRPlusColorTransformParams *params = &s->params[w]; + if (get_bits_left(gb) < 1) + return AVERROR(EINVAL); + + params->tone_mapping_flag = get_bits1(gb); + if (params->tone_mapping_flag) { + if (get_bits_left(gb) < 28) + return AVERROR(EINVAL); + + params->knee_point_x = + (AVRational){get_bits(gb, 12), knee_point_den}; + params->knee_point_y = + (AVRational){get_bits(gb, 12), knee_point_den}; + params->num_bezier_curve_anchors = get_bits(gb, 4); + + if (get_bits_left(gb) < (params->num_bezier_curve_anchors * 10)) + return AVERROR(EINVAL); + + for (int i = 0; i < params->num_bezier_curve_anchors; i++) { + params->bezier_curve_anchors[i] = + (AVRational){get_bits(gb, 10), bezier_anchor_den}; + } + } + + if (get_bits_left(gb) < 1) + return AVERROR(EINVAL); + params->color_saturation_mapping_flag = get_bits1(gb); + if (params->color_saturation_mapping_flag) { + if (get_bits_left(gb) < 6) + return AVERROR(EINVAL); + params->color_saturation_weight = + (AVRational){get_bits(gb, 6), saturation_weight_den}; + } + } + + return 0; +} diff --git a/libavcodec/dynamic_hdr10_plus.h b/libavcodec/dynamic_hdr10_plus.h new file mode 100644 index 000000000..cd7acf043 --- /dev/null +++ b/libavcodec/dynamic_hdr10_plus.h @@ -0,0 +1,35 @@ +/* + * 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_DYNAMIC_HDR10_PLUS_H +#define AVCODEC_DYNAMIC_HDR10_PLUS_H + +#include "libavutil/hdr_dynamic_metadata.h" + +/** + * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRPlus). + * @param s A pointer containing the decoded AVDynamicHDRPlus structure. + * @param data The byte array containing the raw ITU-T T.35 data. + * @param size Size of the data array in bytes. + * + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR. + */ +int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *s, const uint8_t *data, + int size); + +#endif /* AVCODEC_DYNAMIC_HDR10_PLUS_H */ diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c index 6a90571e5..356bb677c 100644 --- a/libavcodec/eac3enc.c +++ b/libavcodec/eac3enc.c @@ -24,7 +24,7 @@ * E-AC-3 encoder */ -#define CONFIG_AC3ENC_FLOAT 1 +#define AC3ENC_FLOAT 1 #include "libavutil/attributes.h" #include "ac3enc.h" @@ -32,13 +32,10 @@ #include "eac3_data.h" -#define AC3ENC_TYPE AC3ENC_TYPE_EAC3 -#include "ac3enc_opts_template.c" - static const AVClass eac3enc_class = { .class_name = "E-AC-3 Encoder", .item_name = av_default_item_name, - .option = ac3_options, + .option = &ff_ac3_enc_options[2], /* First two options are AC-3 only. */ .version = LIBAVUTIL_VERSION_INT, }; @@ -265,5 +262,6 @@ AVCodec ff_eac3_encoder = { .priv_class = &eac3enc_class, .supported_samplerates = ff_ac3_sample_rate_tab, .channel_layouts = ff_ac3_channel_layouts, - .defaults = ac3_defaults, + .defaults = ff_ac3_enc_defaults, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 6f39d72b8..b239acffd 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -50,11 +50,8 @@ static av_cold int cmv_decode_init(AVCodecContext *avctx){ s->last_frame = av_frame_alloc(); s->last2_frame = av_frame_alloc(); - if (!s->last_frame || !s->last2_frame) { - av_frame_free(&s->last_frame); - av_frame_free(&s->last2_frame); + if (!s->last_frame || !s->last2_frame) return AVERROR(ENOMEM); - } return 0; } @@ -243,4 +240,5 @@ AVCodec ff_eacmv_decoder = { .close = cmv_decode_end, .decode = cmv_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index 7f28abbaf..2c03aa5a1 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -28,6 +28,8 @@ * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_MAD */ +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "blockdsp.h" #include "bytestream.h" @@ -349,4 +351,5 @@ AVCodec ff_eamad_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c index 1308c07cf..197ba6fc6 100644 --- a/libavcodec/eatgq.c +++ b/libavcodec/eatgq.c @@ -29,6 +29,9 @@ */ #define BITSTREAM_READER_LE + +#include "libavutil/mem_internal.h" + #include "aandcttab.h" #include "avcodec.h" #include "bytestream.h" diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index 96536b1a0..2be2737fd 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -26,6 +26,8 @@ * @see http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TQI */ +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "blockdsp.h" #include "bswapdsp.h" @@ -189,4 +191,5 @@ AVCodec ff_eatqi_decoder = { .close = tqi_decode_end, .decode = tqi_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/encode.c b/libavcodec/encode.c index b1784ed05..89df5235d 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -26,61 +26,96 @@ #include "libavutil/samplefmt.h" #include "avcodec.h" +#include "encode.h" #include "frame_thread_encoder.h" #include "internal.h" int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_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 - AV_INPUT_BUFFER_PADDING_SIZE) { av_log(avctx, AV_LOG_ERROR, "Invalid minimum required packet size %"PRId64" (max allowed is %d)\n", size, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE); return AVERROR(EINVAL); } + av_assert0(!avpkt->data); + if (avctx && 2*min_size < size) { // FIXME The factor needs to be finetuned - av_assert0(!avpkt->data || avpkt->data != avctx->internal->byte_buffer); - if (!avpkt->data || avpkt->size < size) { - av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size); - avpkt->data = avctx->internal->byte_buffer; - avpkt->size = avctx->internal->byte_buffer_size; - } + av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size); + avpkt->data = avctx->internal->byte_buffer; + avpkt->size = size; } - if (avpkt->data) { - AVBufferRef *buf = avpkt->buf; - - if (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); - avpkt->buf = buf; - avpkt->size = size; - return 0; - } else { + if (!avpkt->data) { int ret = av_new_packet(avpkt, size); if (ret < 0) av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %"PRId64"\n", size); return ret; } + + return 0; +} + +int avcodec_default_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int flags) +{ + int ret; + + if (avpkt->size < 0 || avpkt->size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + return AVERROR(EINVAL); + + if (avpkt->data || avpkt->buf) { + av_log(avctx, AV_LOG_ERROR, "avpkt->{data,buf} != NULL in avcodec_default_get_encode_buffer()\n"); + return AVERROR(EINVAL); + } + + ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %d\n", avpkt->size); + return ret; + } + avpkt->data = avpkt->buf->data; + memset(avpkt->data + avpkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + + return 0; +} + +int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags) +{ + int ret; + + if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + return AVERROR(EINVAL); + + av_assert0(!avpkt->data && !avpkt->buf); + + avpkt->size = size; + ret = avctx->get_encode_buffer(avctx, avpkt, flags); + if (ret < 0) + goto fail; + + if (!avpkt->data || !avpkt->buf) { + av_log(avctx, AV_LOG_ERROR, "No buffer returned by get_encode_buffer()\n"); + ret = AVERROR(EINVAL); + goto fail; + } + + ret = 0; +fail: + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "get_encode_buffer() failed\n"); + av_packet_unref(avpkt); + } + + return ret; } /** * Pad last frame with silence. */ -static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) +static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src) { - AVFrame *frame = NULL; int ret; - if (!(frame = av_frame_alloc())) - return AVERROR(ENOMEM); - frame->format = src->format; frame->channel_layout = src->channel_layout; frame->channels = src->channels; @@ -101,246 +136,10 @@ static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) s->channels, s->sample_fmt)) < 0) goto fail; - *dst = frame; - return 0; fail: - av_frame_free(&frame); - return ret; -} - -int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - AVFrame *extended_frame = NULL; - AVFrame *padded_frame = NULL; - int ret; - AVPacket user_pkt = *avpkt; - int needs_realloc = !user_pkt.data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { - av_packet_unref(avpkt); - return 0; - } - - /* ensure that extended_data is properly set */ - if (frame && !frame->extended_data) { - if (av_sample_fmt_is_planar(avctx->sample_fmt) && - avctx->channels > AV_NUM_DATA_POINTERS) { - av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, " - "with more than %d channels, but extended_data is not set.\n", - AV_NUM_DATA_POINTERS); - return AVERROR(EINVAL); - } - av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n"); - - extended_frame = av_frame_alloc(); - if (!extended_frame) - return AVERROR(ENOMEM); - - memcpy(extended_frame, frame, sizeof(AVFrame)); - extended_frame->extended_data = extended_frame->data; - frame = extended_frame; - } - - /* extract audio service type metadata */ - if (frame) { - AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); - if (sd && sd->size >= sizeof(enum AVAudioServiceType)) - avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; - } - - /* check for valid frame size */ - if (frame) { - if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { - if (frame->nb_samples > avctx->frame_size) { - av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n"); - ret = AVERROR(EINVAL); - goto end; - } - } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { - /* if we already got an undersized frame, that must have been the last */ - if (avctx->internal->last_audio_frame) { - av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame (avcodec_encode_audio2)\n", avctx->frame_size); - ret = AVERROR(EINVAL); - goto end; - } - - if (frame->nb_samples < avctx->frame_size) { - ret = pad_last_frame(avctx, &padded_frame, frame); - if (ret < 0) - goto end; - - frame = padded_frame; - avctx->internal->last_audio_frame = 1; - } - - if (frame->nb_samples != avctx->frame_size) { - av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d) (avcodec_encode_audio2)\n", frame->nb_samples, avctx->frame_size); - ret = AVERROR(EINVAL); - goto end; - } - } - } - - av_assert0(avctx->codec->encode2); - - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - if (!ret) { - if (*got_packet_ptr) { - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { - if (avpkt->pts == AV_NOPTS_VALUE) - avpkt->pts = frame->pts; - if (!avpkt->duration) - avpkt->duration = ff_samples_to_time_base(avctx, - frame->nb_samples); - } - avpkt->dts = avpkt->pts; - } else { - avpkt->size = 0; - } - } - if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { - needs_realloc = 0; - if (user_pkt.data) { - if (user_pkt.size >= avpkt->size) { - memcpy(user_pkt.data, avpkt->data, avpkt->size); - } else { - av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); - avpkt->size = user_pkt.size; - ret = -1; - } - avpkt->buf = user_pkt.buf; - avpkt->data = user_pkt.data; - } else if (!avpkt->buf) { - ret = av_packet_make_refcounted(avpkt); - if (ret < 0) - goto end; - } - } - - if (!ret) { - if (needs_realloc && avpkt->data) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - if (frame) - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) { - av_packet_unref(avpkt); - goto end; - } - - /* NOTE: if we add any audio encoders which output non-keyframe packets, - * this needs to be moved to the encoders, but for now we can do it - * here to simplify things */ - avpkt->flags |= AV_PKT_FLAG_KEY; - -end: - av_frame_free(&padded_frame); - av_free(extended_frame); - - return ret; -} - -int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - int ret; - AVPacket user_pkt = *avpkt; - int needs_realloc = !user_pkt.data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if ((avctx->flags&AV_CODEC_FLAG_PASS1) && avctx->stats_out) - avctx->stats_out[0] = '\0'; - - if (!frame && - !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || - (avctx->internal->frame_thread_encoder && avctx->active_thread_type & FF_THREAD_FRAME))) { - av_packet_unref(avpkt); - return 0; - } - - if (av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) - return AVERROR(EINVAL); - - if (frame && frame->format == AV_PIX_FMT_NONE) - av_log(avctx, AV_LOG_WARNING, "AVFrame.format is not set\n"); - if (frame && (frame->width == 0 || frame->height == 0)) - av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n"); - - av_assert0(avctx->codec->encode2); - - - if (CONFIG_FRAME_THREAD_ENCODER && - avctx->internal->frame_thread_encoder && (avctx->active_thread_type & FF_THREAD_FRAME)) - ret = ff_thread_video_encode_frame(avctx, avpkt, frame, got_packet_ptr); - else { - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - if (*got_packet_ptr && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - avpkt->pts = avpkt->dts = frame->pts; - } - av_assert0(ret <= 0); - - emms_c(); - - if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { - needs_realloc = 0; - if (user_pkt.data) { - if (user_pkt.size >= avpkt->size) { - memcpy(user_pkt.data, avpkt->data, avpkt->size); - } else { - av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); - avpkt->size = user_pkt.size; - ret = -1; - } - avpkt->buf = user_pkt.buf; - avpkt->data = user_pkt.data; - } else if (!avpkt->buf) { - ret = av_packet_make_refcounted(avpkt); - if (ret < 0) - return ret; - } - } - - if (!ret) { - if (!*got_packet_ptr) - avpkt->size = 0; - - if (needs_realloc && avpkt->data) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - - if (frame) - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) - av_packet_unref(avpkt); - + av_frame_unref(frame); return ret; } @@ -358,101 +157,526 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, return ret; } -static int do_encode(AVCodecContext *avctx, const AVFrame *frame, int *got_packet) +int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame) { + AVCodecInternal *avci = avctx->internal; + + if (avci->draining) + return AVERROR_EOF; + + if (!avci->buffer_frame->buf[0]) + return AVERROR(EAGAIN); + + av_frame_move_ref(frame, avci->buffer_frame); + + return 0; +} + +static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + EncodeSimpleContext *es = &avci->es; + AVFrame *frame = es->in_frame; + int got_packet; int ret; - *got_packet = 0; - av_packet_unref(avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; + if (avci->draining_done) + return AVERROR_EOF; - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avcodec_encode_video2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = avcodec_encode_audio2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else { - ret = AVERROR(EINVAL); + if (!frame->buf[0] && !avci->draining) { + av_frame_unref(frame); + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; } - if (ret >= 0 && *got_packet) { + if (!frame->buf[0]) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || + (avci->frame_thread_encoder && avctx->active_thread_type & FF_THREAD_FRAME))) + return AVERROR_EOF; + + // Flushing is signaled with a NULL frame + frame = NULL; + } + + got_packet = 0; + + av_assert0(avctx->codec->encode2); + + if (CONFIG_FRAME_THREAD_ENCODER && + avci->frame_thread_encoder && (avctx->active_thread_type & FF_THREAD_FRAME)) + /* This might modify frame, but it doesn't matter, because + * the frame properties used below are not used for video + * (due to the delay inherent in frame threaded encoding, it makes + * no sense to use the properties of the current frame anyway). */ + ret = ff_thread_video_encode_frame(avctx, avpkt, frame, &got_packet); + else { + ret = avctx->codec->encode2(avctx, avpkt, frame, &got_packet); + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO && !ret && got_packet && + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + avpkt->pts = avpkt->dts = frame->pts; + } + + av_assert0(ret <= 0); + + emms_c(); + + if (!ret && got_packet) { + if (avpkt->data) { + ret = av_packet_make_refcounted(avpkt); + if (ret < 0) + goto end; + } + + if (frame && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + if (avpkt->pts == AV_NOPTS_VALUE) + avpkt->pts = frame->pts; + if (!avpkt->duration) + avpkt->duration = ff_samples_to_time_base(avctx, + frame->nb_samples); + } + } + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + /* NOTE: if we add any audio encoders which output non-keyframe packets, + * this needs to be moved to the encoders, but for now we can do it + * here to simplify things */ + avpkt->flags |= AV_PKT_FLAG_KEY; + avpkt->dts = avpkt->pts; + } + } + + if (avci->draining && !got_packet) + avci->draining_done = 1; + +end: + if (ret < 0 || !got_packet) + av_packet_unref(avpkt); + + if (frame) { + if (!ret) + avctx->frame_number++; + av_frame_unref(frame); + } + + if (got_packet) // Encoders must always return ref-counted buffers. // Side-data only packets have no data and can be not ref-counted. - av_assert0(!avctx->internal->buffer_pkt->data || avctx->internal->buffer_pkt->buf); - avctx->internal->buffer_pkt_valid = 1; - ret = 0; - } else { - av_packet_unref(avctx->internal->buffer_pkt); - } + av_assert0(!avpkt->data || avpkt->buf); return ret; } +static int encode_simple_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) +{ + int ret; + + while (!avpkt->data && !avpkt->side_data) { + ret = encode_simple_internal(avctx, avpkt); + if (ret < 0) + return ret; + } + + return 0; +} + +static int encode_receive_packet_internal(AVCodecContext *avctx, AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + if (avci->draining_done) + return AVERROR_EOF; + + av_assert0(!avpkt->data && !avpkt->side_data); + + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if ((avctx->flags & AV_CODEC_FLAG_PASS1) && avctx->stats_out) + avctx->stats_out[0] = '\0'; + if (av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) + return AVERROR(EINVAL); + } + + if (avctx->codec->receive_packet) { + ret = avctx->codec->receive_packet(avctx, avpkt); + if (ret < 0) + av_packet_unref(avpkt); + else + // Encoders must always return ref-counted buffers. + // Side-data only packets have no data and can be not ref-counted. + av_assert0(!avpkt->data || avpkt->buf); + } else + ret = encode_simple_receive_packet(avctx, avpkt); + + if (ret == AVERROR_EOF) + avci->draining_done = 1; + + return ret; +} + +static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src) +{ + AVCodecInternal *avci = avctx->internal; + AVFrame *dst = avci->buffer_frame; + int ret; + + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + /* extract audio service type metadata */ + AVFrameSideData *sd = av_frame_get_side_data(src, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); + if (sd && sd->size >= sizeof(enum AVAudioServiceType)) + avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; + + /* check for valid frame size */ + if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { + if (src->nb_samples > avctx->frame_size) { + av_log(avctx, AV_LOG_ERROR, "more samples than frame size\n"); + return AVERROR(EINVAL); + } + } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { + /* if we already got an undersized frame, that must have been the last */ + if (avctx->internal->last_audio_frame) { + av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame\n", avctx->frame_size); + return AVERROR(EINVAL); + } + + if (src->nb_samples < avctx->frame_size) { + ret = pad_last_frame(avctx, dst, src); + if (ret < 0) + return ret; + + avctx->internal->last_audio_frame = 1; + } else if (src->nb_samples > avctx->frame_size) { + av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d)\n", src->nb_samples, avctx->frame_size); + return AVERROR(EINVAL); + } + } + } + + if (!dst->data[0]) { + ret = av_frame_ref(dst, src); + if (ret < 0) + return ret; + } + + return 0; +} + int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame) { + AVCodecInternal *avci = avctx->internal; + int ret; + if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) return AVERROR(EINVAL); - if (avctx->internal->draining) + if (avci->draining) return AVERROR_EOF; - if (!frame) { - avctx->internal->draining = 1; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return 0; - } - - if (avctx->codec->send_frame) - return avctx->codec->send_frame(avctx, frame); - - // Emulation via old API. Do it here instead of avcodec_receive_packet, because: - // 1. if the AVFrame is not refcounted, the copying will be much more - // expensive than copying the packet data - // 2. assume few users use non-refcounted AVPackets, so usually no copy is - // needed - - if (avctx->internal->buffer_pkt_valid) + if (avci->buffer_frame->data[0]) return AVERROR(EAGAIN); - return do_encode(avctx, frame, &(int){0}); + if (!frame) { + avci->draining = 1; + } else { + ret = encode_send_frame_internal(avctx, frame); + if (ret < 0) + return ret; + } + + if (!avci->buffer_pkt->data && !avci->buffer_pkt->side_data) { + ret = encode_receive_packet_internal(avctx, avci->buffer_pkt); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + } + + return 0; } int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) { + AVCodecInternal *avci = avctx->internal; + int ret; + av_packet_unref(avpkt); if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) return AVERROR(EINVAL); - if (avctx->codec->receive_packet) { - int ret; - if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return AVERROR_EOF; - ret = avctx->codec->receive_packet(avctx, avpkt); - if (!ret) - // Encoders must always return ref-counted buffers. - // Side-data only packets have no data and can be not ref-counted. - av_assert0(!avpkt->data || avpkt->buf); - return ret; - } - - // Emulation via old API. - - if (!avctx->internal->buffer_pkt_valid) { - int got_packet; - int ret; - if (!avctx->internal->draining) - return AVERROR(EAGAIN); - ret = do_encode(avctx, NULL, &got_packet); + if (avci->buffer_pkt->data || avci->buffer_pkt->side_data) { + av_packet_move_ref(avpkt, avci->buffer_pkt); + } else { + ret = encode_receive_packet_internal(avctx, avpkt); if (ret < 0) return ret; - if (ret >= 0 && !got_packet) - return AVERROR_EOF; } - av_packet_move_ref(avpkt, avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; + return 0; +} + +#if FF_API_OLD_ENCDEC +static int compat_encode(AVCodecContext *avctx, AVPacket *avpkt, + int *got_packet, const AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + AVPacket user_pkt; + int ret; + + *got_packet = 0; + + if (frame && avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if (frame->format == AV_PIX_FMT_NONE) + av_log(avctx, AV_LOG_WARNING, "AVFrame.format is not set\n"); + if (frame->width == 0 || frame->height == 0) + av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n"); + } + + if (avctx->codec->capabilities & AV_CODEC_CAP_DR1) { + av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_encode_* API does not support " + "AV_CODEC_CAP_DR1 encoders\n"); + return AVERROR(ENOSYS); + } + + ret = avcodec_send_frame(avctx, frame); + if (ret == AVERROR_EOF) + ret = 0; + else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each encode call, so this should not + * ever happen */ + return AVERROR_BUG; + } else if (ret < 0) + return ret; + + av_packet_move_ref(&user_pkt, avpkt); + while (ret >= 0) { + ret = avcodec_receive_packet(avctx, avpkt); + if (ret < 0) { + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + ret = 0; + goto finish; + } + + if (avpkt != avci->compat_encode_packet) { + if (avpkt->data && user_pkt.data) { + if (user_pkt.size >= avpkt->size) { + memcpy(user_pkt.data, avpkt->data, avpkt->size); + av_buffer_unref(&avpkt->buf); + avpkt->buf = user_pkt.buf; + avpkt->data = user_pkt.data; +FF_DISABLE_DEPRECATION_WARNINGS + av_init_packet(&user_pkt); +FF_ENABLE_DEPRECATION_WARNINGS + } else { + av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); + av_packet_unref(avpkt); + ret = AVERROR(EINVAL); + goto finish; + } + } + + *got_packet = 1; + avpkt = avci->compat_encode_packet; + } else { + if (!avci->compat_decode_warned) { + av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_encode_* " + "API cannot return all the packets for this encoder. " + "Some packets will be dropped. Update your code to the " + "new encoding API to fix this.\n"); + avci->compat_decode_warned = 1; + av_packet_unref(avpkt); + } + } + + if (avci->draining) + break; + } + +finish: + if (ret < 0) + av_packet_unref(&user_pkt); + + return ret; +} + +int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + int ret = compat_encode(avctx, avpkt, got_packet_ptr, frame); + + if (ret < 0) + av_packet_unref(avpkt); + + return ret; +} + +int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + int ret = compat_encode(avctx, avpkt, got_packet_ptr, frame); + + if (ret < 0) + av_packet_unref(avpkt); + + return ret; +} +#endif + +int ff_encode_preinit(AVCodecContext *avctx) +{ + int i; +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + return AVERROR(ENOMEM); + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + if (avctx->time_base.num <= 0 || avctx->time_base.den <= 0) { + av_log(avctx, AV_LOG_ERROR, "The encoder timebase is not set.\n"); + return AVERROR(EINVAL); + } + + if (avctx->codec->sample_fmts) { + for (i = 0; avctx->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) { + if (avctx->sample_fmt == avctx->codec->sample_fmts[i]) + break; + if (avctx->channels == 1 && + av_get_planar_sample_fmt(avctx->sample_fmt) == + av_get_planar_sample_fmt(avctx->codec->sample_fmts[i])) { + avctx->sample_fmt = avctx->codec->sample_fmts[i]; + break; + } + } + if (avctx->codec->sample_fmts[i] == AV_SAMPLE_FMT_NONE) { + char buf[128]; + snprintf(buf, sizeof(buf), "%d", avctx->sample_fmt); + av_log(avctx, AV_LOG_ERROR, "Specified sample format %s is invalid or not supported\n", + (char *)av_x_if_null(av_get_sample_fmt_name(avctx->sample_fmt), buf)); + return AVERROR(EINVAL); + } + } + if (avctx->codec->pix_fmts) { + for (i = 0; avctx->codec->pix_fmts[i] != AV_PIX_FMT_NONE; i++) + if (avctx->pix_fmt == avctx->codec->pix_fmts[i]) + break; + if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE + && !(avctx->codec_id == AV_CODEC_ID_MJPEG + && avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL)) { + char buf[128]; + snprintf(buf, sizeof(buf), "%d", avctx->pix_fmt); + av_log(avctx, AV_LOG_ERROR, "Specified pixel format %s is invalid or not supported\n", + (char *)av_x_if_null(av_get_pix_fmt_name(avctx->pix_fmt), buf)); + return AVERROR(EINVAL); + } + if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ420P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ411P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ422P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ440P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ444P) + avctx->color_range = AVCOL_RANGE_JPEG; + } + if (avctx->codec->supported_samplerates) { + for (i = 0; avctx->codec->supported_samplerates[i] != 0; i++) + if (avctx->sample_rate == avctx->codec->supported_samplerates[i]) + break; + if (avctx->codec->supported_samplerates[i] == 0) { + av_log(avctx, AV_LOG_ERROR, "Specified sample rate %d is not supported\n", + avctx->sample_rate); + return AVERROR(EINVAL); + } + } + if (avctx->sample_rate < 0) { + av_log(avctx, AV_LOG_ERROR, "Specified sample rate %d is not supported\n", + avctx->sample_rate); + return AVERROR(EINVAL); + } + if (avctx->codec->channel_layouts) { + if (!avctx->channel_layout) { + av_log(avctx, AV_LOG_WARNING, "Channel layout not specified\n"); + } else { + for (i = 0; avctx->codec->channel_layouts[i] != 0; i++) + if (avctx->channel_layout == avctx->codec->channel_layouts[i]) + break; + if (avctx->codec->channel_layouts[i] == 0) { + char buf[512]; + av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); + av_log(avctx, AV_LOG_ERROR, "Specified channel layout '%s' is not supported\n", buf); + return AVERROR(EINVAL); + } + } + } + if (avctx->channel_layout && avctx->channels) { + int channels = av_get_channel_layout_nb_channels(avctx->channel_layout); + if (channels != avctx->channels) { + char buf[512]; + av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); + av_log(avctx, AV_LOG_ERROR, + "Channel layout '%s' with %d channels does not match number of specified channels %d\n", + buf, channels, avctx->channels); + return AVERROR(EINVAL); + } + } else if (avctx->channel_layout) { + avctx->channels = av_get_channel_layout_nb_channels(avctx->channel_layout); + } + if (avctx->channels < 0) { + av_log(avctx, AV_LOG_ERROR, "Specified number of channels %d is not supported\n", + avctx->channels); + return AVERROR(EINVAL); + } + if(avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(avctx->pix_fmt); + if ( avctx->bits_per_raw_sample < 0 + || (avctx->bits_per_raw_sample > 8 && pixdesc->comp[0].depth <= 8)) { + av_log(avctx, AV_LOG_WARNING, "Specified bit depth %d not possible with the specified pixel formats depth %d\n", + avctx->bits_per_raw_sample, pixdesc->comp[0].depth); + avctx->bits_per_raw_sample = pixdesc->comp[0].depth; + } + if (avctx->width <= 0 || avctx->height <= 0) { + av_log(avctx, AV_LOG_ERROR, "dimensions not set\n"); + return AVERROR(EINVAL); + } + } + if ( (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO) + && avctx->bit_rate>0 && avctx->bit_rate<1000) { + av_log(avctx, AV_LOG_WARNING, "Bitrate %"PRId64" is extremely low, maybe you mean %"PRId64"k\n", avctx->bit_rate, avctx->bit_rate); + } + + if (!avctx->rc_initial_buffer_occupancy) + avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3LL / 4; + + if (avctx->ticks_per_frame && avctx->time_base.num && + avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { + av_log(avctx, AV_LOG_ERROR, + "ticks_per_frame %d too large for the timebase %d/%d.", + avctx->ticks_per_frame, + avctx->time_base.num, + avctx->time_base.den); + return AVERROR(EINVAL); + } + + if (avctx->hw_frames_ctx) { + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (frames_ctx->format != avctx->pix_fmt) { + av_log(avctx, AV_LOG_ERROR, + "Mismatching AVCodecContext.pix_fmt and AVHWFramesContext.format\n"); + return AVERROR(EINVAL); + } + if (avctx->sw_pix_fmt != AV_PIX_FMT_NONE && + avctx->sw_pix_fmt != frames_ctx->sw_format) { + av_log(avctx, AV_LOG_ERROR, + "Mismatching AVCodecContext.sw_pix_fmt (%s) " + "and AVHWFramesContext.sw_format (%s)\n", + av_get_pix_fmt_name(avctx->sw_pix_fmt), + av_get_pix_fmt_name(frames_ctx->sw_format)); + return AVERROR(EINVAL); + } + avctx->sw_pix_fmt = frames_ctx->sw_format; + } + return 0; } diff --git a/libavcodec/encode.h b/libavcodec/encode.h new file mode 100644 index 000000000..9af2f4248 --- /dev/null +++ b/libavcodec/encode.h @@ -0,0 +1,53 @@ +/* + * generic encoding-related code + * + * 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_ENCODE_H +#define AVCODEC_ENCODE_H + +#include "libavutil/frame.h" + +#include "avcodec.h" +#include "packet.h" + +/** + * Called by encoders to get the next frame for encoding. + * + * @param frame An empty frame to be filled with data. + * @return 0 if a new reference has been successfully written to frame + * AVERROR(EAGAIN) if no data is currently available + * AVERROR_EOF if end of stream has been reached, so no more data + * will be available + */ +int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame); + +/** + * Get a buffer for a packet. This is a wrapper around + * AVCodecContext.get_encode_buffer() and should be used instead calling get_encode_buffer() + * directly. + */ +int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags); + +/* + * Perform encoder initialization and validation. + * Called when opening the encoder, before the AVCodec.init() call. + */ +int ff_encode_preinit(AVCodecContext *avctx); + +#endif /* AVCODEC_ENCODE_H */ diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c index 1dd7eedd7..a6fda901d 100644 --- a/libavcodec/escape130.c +++ b/libavcodec/escape130.c @@ -128,9 +128,6 @@ static av_cold int escape130_decode_init(AVCodecContext *avctx) 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); } @@ -358,4 +355,5 @@ AVCodec ff_escape130_decoder = { .close = escape130_decode_close, .decode = escape130_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/evrcdec.c b/libavcodec/evrcdec.c index 8728c02a3..00e342a1f 100644 --- a/libavcodec/evrcdec.c +++ b/libavcodec/evrcdec.c @@ -935,7 +935,7 @@ AVCodec ff_evrc_decoder = { .id = AV_CODEC_ID_EVRC, .init = evrc_decode_init, .decode = evrc_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .priv_data_size = sizeof(EVRCContext), .priv_class = &evrcdec_class, }; diff --git a/libavcodec/exif.c b/libavcodec/exif.c index 2874772db..0b656fd09 100644 --- a/libavcodec/exif.c +++ b/libavcodec/exif.c @@ -95,22 +95,15 @@ static int exif_decode_tag(void *logctx, GetByteContext *gbytes, int le, ret = ff_exif_decode_ifd(logctx, gbytes, le, depth + 1, metadata); } else { const char *name = exif_get_tag_name(id); - char *use_name = (char*) name; - - if (!use_name) { - use_name = av_malloc(7); - if (!use_name) { - return AVERROR(ENOMEM); - } - snprintf(use_name, 7, "0x%04X", id); - } - - ret = exif_add_metadata(logctx, count, type, use_name, NULL, - gbytes, le, metadata); + char buf[7]; if (!name) { - av_freep(&use_name); + name = buf; + snprintf(buf, sizeof(buf), "0x%04X", id); } + + ret = exif_add_metadata(logctx, count, type, name, NULL, + gbytes, le, metadata); } bytestream2_seek(gbytes, cur_pos, SEEK_SET); diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 2e008c8f6..65e5203c3 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -29,8 +29,6 @@ * * For more information on the OpenEXR format, visit: * http://openexr.com/ - * - * exr_half2float() is credited to Aaftab Munshi, Dan Ginsburg, Dave Shreiner. */ #include @@ -54,6 +52,7 @@ #include "exrdsp.h" #include "get_bits.h" #include "internal.h" +#include "half2float.h" #include "mathops.h" #include "thread.h" @@ -66,8 +65,8 @@ enum ExrCompr { EXR_PXR24, EXR_B44, EXR_B44A, - EXR_DWA, - EXR_DWB, + EXR_DWAA, + EXR_DWAB, EXR_UNKN, }; @@ -91,6 +90,12 @@ enum ExrTileLevelRound { EXR_TILE_ROUND_UNKNOWN, }; +typedef struct HuffEntry { + uint8_t len; + uint16_t sym; + uint32_t code; +} HuffEntry; + typedef struct EXRChannel { int xsub, ysub; enum ExrPixelType pixel_type; @@ -113,9 +118,28 @@ typedef struct EXRThreadData { uint8_t *bitmap; uint16_t *lut; + uint8_t *ac_data; + unsigned ac_size; + + uint8_t *dc_data; + unsigned dc_size; + + uint8_t *rle_data; + unsigned rle_size; + + uint8_t *rle_raw_data; + unsigned rle_raw_size; + + float block[3][64]; + int ysize, xsize; int channel_line_size; + + int run_sym; + HuffEntry *he; + uint64_t *freq; + VLC vlc; } EXRThreadData; typedef struct EXRContext { @@ -134,14 +158,17 @@ typedef struct EXRContext { const AVPixFmtDescriptor *desc; int w, h; - uint32_t xmax, xmin; - uint32_t ymax, ymin; + uint32_t sar; + int32_t xmax, xmin; + int32_t ymax, ymin; uint32_t xdelta, ydelta; int scan_lines_per_block; EXRTileAttribute tile_attr; /* header data attribute of tile */ int is_tile; /* 0 if scanline, 1 if tile */ + int is_multipart; + int current_part; int is_luma;/* 1 if there is an Y plane */ @@ -152,78 +179,22 @@ typedef struct EXRContext { EXRChannel *channels; int nb_channels; int current_channel_offset; + uint32_t chunk_count; EXRThreadData *thread_data; const char *layer; + int selected_part; enum AVColorTransferCharacteristic apply_trc_type; float gamma; union av_intfloat32 gamma_table[65536]; + + uint32_t mantissatable[2048]; + uint32_t exponenttable[64]; + uint16_t offsettable[64]; } EXRContext; -/* -15 stored using a single precision bias of 127 */ -#define HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP 0x38000000 - -/* max exponent value in single precision that will be converted - * to Inf or Nan when stored as a half-float */ -#define HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP 0x47800000 - -/* 255 is the max exponent biased value */ -#define FLOAT_MAX_BIASED_EXP (0xFF << 23) - -#define HALF_FLOAT_MAX_BIASED_EXP (0x1F << 10) - -/** - * Convert a half float as a uint16_t into a full float. - * - * @param hf half float as uint16_t - * - * @return float value - */ -static union av_intfloat32 exr_half2float(uint16_t hf) -{ - unsigned int sign = (unsigned int) (hf >> 15); - unsigned int mantissa = (unsigned int) (hf & ((1 << 10) - 1)); - unsigned int exp = (unsigned int) (hf & HALF_FLOAT_MAX_BIASED_EXP); - union av_intfloat32 f; - - if (exp == HALF_FLOAT_MAX_BIASED_EXP) { - // we have a half-float NaN or Inf - // half-float NaNs will be converted to a single precision NaN - // half-float Infs will be converted to a single precision Inf - exp = FLOAT_MAX_BIASED_EXP; - if (mantissa) - mantissa = (1 << 23) - 1; // set all bits to indicate a NaN - } else if (exp == 0x0) { - // convert half-float zero/denorm to single precision value - if (mantissa) { - mantissa <<= 1; - exp = HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP; - // check for leading 1 in denorm mantissa - while ((mantissa & (1 << 10))) { - // for every leading 0, decrement single precision exponent by 1 - // and shift half-float mantissa value to the left - mantissa <<= 1; - exp -= (1 << 23); - } - // clamp the mantissa to 10 bits - mantissa &= ((1 << 10) - 1); - // shift left to generate single-precision mantissa of 23 bits - mantissa <<= 13; - } - } else { - // shift left to generate single-precision mantissa of 23 bits - mantissa <<= 13; - // generate single precision biased exponent value - exp = (exp << 13) + HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP; - } - - f.i = (sign << 31) | exp | mantissa; - - return f; -} - static int zip_uncompress(EXRContext *s, const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td) { @@ -241,10 +212,10 @@ static int zip_uncompress(EXRContext *s, const uint8_t *src, int compressed_size return 0; } -static int rle_uncompress(EXRContext *ctx, const uint8_t *src, int compressed_size, - int uncompressed_size, EXRThreadData *td) +static int rle(uint8_t *dst, const uint8_t *src, + int compressed_size, int uncompressed_size) { - uint8_t *d = td->tmp; + uint8_t *d = dst; const int8_t *s = src; int ssize = compressed_size; int dsize = uncompressed_size; @@ -280,6 +251,14 @@ static int rle_uncompress(EXRContext *ctx, const uint8_t *src, int compressed_si if (dend != d) return AVERROR_INVALIDDATA; + return 0; +} + +static int rle_uncompress(EXRContext *ctx, const uint8_t *src, int compressed_size, + int uncompressed_size, EXRThreadData *td) +{ + rle(td->tmp, src, compressed_size, uncompressed_size); + av_assert1(uncompressed_size % 2 == 0); ctx->dsp.predictor(td->tmp, uncompressed_size); @@ -315,25 +294,15 @@ static void apply_lut(const uint16_t *lut, uint16_t *dst, int dsize) } #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) +static void huf_canonical_code_table(uint64_t *freq) { uint64_t c, n[59] = { 0 }; int i; - for (i = 0; i < HUF_ENCSIZE; ++i) - n[hcode[i]] += 1; + for (i = 0; i < HUF_ENCSIZE; i++) + n[freq[i]] += 1; c = 0; for (i = 58; i > 0; --i) { @@ -343,10 +312,10 @@ static void huf_canonical_code_table(uint64_t *hcode) } for (i = 0; i < HUF_ENCSIZE; ++i) { - int l = hcode[i]; + int l = freq[i]; if (l > 0) - hcode[i] = l | (n[l]++ << 6); + freq[i] = l | (n[l]++ << 6); } } @@ -356,7 +325,7 @@ static void huf_canonical_code_table(uint64_t *hcode) #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) + int32_t im, int32_t iM, uint64_t *freq) { GetBitContext gbit; int ret = init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb)); @@ -364,7 +333,7 @@ static int huf_unpack_enc_table(GetByteContext *gb, return ret; for (; im <= iM; im++) { - uint64_t l = hcode[im] = get_bits(&gbit, 6); + uint64_t l = freq[im] = get_bits(&gbit, 6); if (l == LONG_ZEROCODE_RUN) { int zerun = get_bits(&gbit, 8) + SHORTEST_LONG_RUN; @@ -373,7 +342,7 @@ static int huf_unpack_enc_table(GetByteContext *gb, return AVERROR_INVALIDDATA; while (zerun--) - hcode[im++] = 0; + freq[im++] = 0; im--; } else if (l >= SHORT_ZEROCODE_RUN) { @@ -383,202 +352,133 @@ static int huf_unpack_enc_table(GetByteContext *gb, return AVERROR_INVALIDDATA; while (zerun--) - hcode[im++] = 0; + freq[im++] = 0; im--; } } bytestream2_skip(gb, (get_bits_count(&gbit) + 7) / 8); - huf_canonical_code_table(hcode); + huf_canonical_code_table(freq); return 0; } -static int huf_build_dec_table(const uint64_t *hcode, int im, - int iM, HufDec *hdecod) +static int huf_build_dec_table(EXRContext *s, + EXRThreadData *td, int im, int iM) { - for (; im <= iM; im++) { - uint64_t c = hcode[im] >> 6; - int i, l = hcode[im] & 63; + int j = 0; - if (c >> l) - return AVERROR_INVALIDDATA; + td->run_sym = -1; + for (int i = im; i < iM; i++) { + td->he[j].sym = i; + td->he[j].len = td->freq[i] & 63; + td->he[j].code = td->freq[i] >> 6; + if (td->he[j].len > 32) { + avpriv_request_sample(s->avctx, "Too big code length"); + return AVERROR_PATCHWELCOME; + } + if (td->he[j].len > 0) + j++; + else + td->run_sym = i; + } - if (l > HUF_DECBITS) { - HufDec *pl = hdecod + (c >> (l - HUF_DECBITS)); - if (pl->len) + if (im > 0) + td->run_sym = 0; + else if (iM < 65535) + td->run_sym = 65535; + + if (td->run_sym == -1) { + avpriv_request_sample(s->avctx, "No place for run symbol"); + return AVERROR_PATCHWELCOME; + } + + td->he[j].sym = td->run_sym; + td->he[j].len = td->freq[iM] & 63; + if (td->he[j].len > 32) { + avpriv_request_sample(s->avctx, "Too big code length"); + return AVERROR_PATCHWELCOME; + } + td->he[j].code = td->freq[iM] >> 6; + j++; + + ff_free_vlc(&td->vlc); + return ff_init_vlc_sparse(&td->vlc, 12, j, + &td->he[0].len, sizeof(td->he[0]), sizeof(td->he[0].len), + &td->he[0].code, sizeof(td->he[0]), sizeof(td->he[0].code), + &td->he[0].sym, sizeof(td->he[0]), sizeof(td->he[0].sym), 0); +} + +static int huf_decode(VLC *vlc, GetByteContext *gb, int nbits, int run_sym, + int no, uint16_t *out) +{ + GetBitContext gbit; + int oe = 0; + + init_get_bits(&gbit, gb->buffer, nbits); + while (get_bits_left(&gbit) > 0 && oe < no) { + uint16_t x = get_vlc2(&gbit, vlc->table, 12, 2); + + if (x == run_sym) { + int run = get_bits(&gbit, 8); + uint16_t fill; + + if (oe == 0 || oe + run > no) return AVERROR_INVALIDDATA; - pl->lit++; + fill = out[oe - 1]; - pl->p = av_realloc(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, outb) \ -{ \ - if (po == rlc) { \ - if (lc < 8) \ - get_char(c, lc, gb); \ - lc -= 8; \ - \ - cs = c >> lc; \ - \ - if (out + cs > oe || out == outb) \ - 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; - uint16_t 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, outb); - } 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, outb); - 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) { - lc -= pl.len; - get_code(pl.lit, rlc, c, lc, gb, out, oe, outb); + while (run-- > 0) + out[oe++] = fill; } else { - return AVERROR_INVALIDDATA; + out[oe++] = x; } } - if (out - outb != no) - return AVERROR_INVALIDDATA; return 0; } -static int huf_uncompress(GetByteContext *gb, +static int huf_uncompress(EXRContext *s, + EXRThreadData *td, + GetByteContext *gb, uint16_t *dst, int dst_size) { - int32_t src_size, im, iM; + int32_t im, iM; uint32_t nBits; - uint64_t *freq; - HufDec *hdec; - int ret, i; + int ret; - 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) + iM < 0 || iM >= HUF_ENCSIZE) return AVERROR_INVALIDDATA; bytestream2_skip(gb, 4); - freq = av_mallocz_array(HUF_ENCSIZE, sizeof(*freq)); - hdec = av_mallocz_array(HUF_DECSIZE, sizeof(*hdec)); - if (!freq || !hdec) { + if (!td->freq) + td->freq = av_malloc_array(HUF_ENCSIZE, sizeof(*td->freq)); + if (!td->he) + td->he = av_calloc(HUF_ENCSIZE, sizeof(*td->he)); + if (!td->freq || !td->he) { ret = AVERROR(ENOMEM); - goto fail; + return ret; } - if ((ret = huf_unpack_enc_table(gb, im, iM, freq)) < 0) - goto fail; + memset(td->freq, 0, sizeof(*td->freq) * HUF_ENCSIZE); + if ((ret = huf_unpack_enc_table(gb, im, iM, td->freq)) < 0) + return ret; if (nBits > 8 * bytestream2_get_bytes_left(gb)) { ret = AVERROR_INVALIDDATA; - goto fail; + return ret; } - 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; + if ((ret = huf_build_dec_table(s, td, im, iM)) < 0) + return ret; + return huf_decode(&td->vlc, gb, nBits, td->run_sym, dst_size, dst); } static inline void wdec14(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b) @@ -726,7 +626,8 @@ static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize, maxval = reverse_lut(td->bitmap, td->lut); - ret = huf_uncompress(&gb, tmp, dsize / sizeof(uint16_t)); + bytestream2_skip(&gb, 4); + ret = huf_uncompress(s, td, &gb, tmp, dsize / sizeof(uint16_t)); if (ret) return ret; @@ -984,6 +885,292 @@ static int b44_uncompress(EXRContext *s, const uint8_t *src, int compressed_size return 0; } +static int ac_uncompress(EXRContext *s, GetByteContext *gb, float *block) +{ + int ret = 0, n = 1; + + while (n < 64) { + uint16_t val = bytestream2_get_ne16(gb); + + if (val == 0xff00) { + n = 64; + } else if ((val >> 8) == 0xff) { + n += val & 0xff; + } else { + ret = n; + block[ff_zigzag_direct[n]] = av_int2float(half2float(val, + s->mantissatable, + s->exponenttable, + s->offsettable)); + n++; + } + } + + return ret; +} + +static void idct_1d(float *blk, int step) +{ + const float a = .5f * cosf( M_PI / 4.f); + const float b = .5f * cosf( M_PI / 16.f); + const float c = .5f * cosf( M_PI / 8.f); + const float d = .5f * cosf(3.f*M_PI / 16.f); + const float e = .5f * cosf(5.f*M_PI / 16.f); + const float f = .5f * cosf(3.f*M_PI / 8.f); + const float g = .5f * cosf(7.f*M_PI / 16.f); + + float alpha[4], beta[4], theta[4], gamma[4]; + + alpha[0] = c * blk[2 * step]; + alpha[1] = f * blk[2 * step]; + alpha[2] = c * blk[6 * step]; + alpha[3] = f * blk[6 * step]; + + beta[0] = b * blk[1 * step] + d * blk[3 * step] + e * blk[5 * step] + g * blk[7 * step]; + beta[1] = d * blk[1 * step] - g * blk[3 * step] - b * blk[5 * step] - e * blk[7 * step]; + beta[2] = e * blk[1 * step] - b * blk[3 * step] + g * blk[5 * step] + d * blk[7 * step]; + beta[3] = g * blk[1 * step] - e * blk[3 * step] + d * blk[5 * step] - b * blk[7 * step]; + + theta[0] = a * (blk[0 * step] + blk[4 * step]); + theta[3] = a * (blk[0 * step] - blk[4 * step]); + + theta[1] = alpha[0] + alpha[3]; + theta[2] = alpha[1] - alpha[2]; + + gamma[0] = theta[0] + theta[1]; + gamma[1] = theta[3] + theta[2]; + gamma[2] = theta[3] - theta[2]; + gamma[3] = theta[0] - theta[1]; + + blk[0 * step] = gamma[0] + beta[0]; + blk[1 * step] = gamma[1] + beta[1]; + blk[2 * step] = gamma[2] + beta[2]; + blk[3 * step] = gamma[3] + beta[3]; + + blk[4 * step] = gamma[3] - beta[3]; + blk[5 * step] = gamma[2] - beta[2]; + blk[6 * step] = gamma[1] - beta[1]; + blk[7 * step] = gamma[0] - beta[0]; +} + +static void dct_inverse(float *block) +{ + for (int i = 0; i < 8; i++) + idct_1d(block + i, 8); + + for (int i = 0; i < 8; i++) { + idct_1d(block, 1); + block += 8; + } +} + +static void convert(float y, float u, float v, + float *b, float *g, float *r) +{ + *r = y + 1.5747f * v; + *g = y - 0.1873f * u - 0.4682f * v; + *b = y + 1.8556f * u; +} + +static float to_linear(float x, float scale) +{ + float ax = fabsf(x); + + if (ax <= 1.f) { + return FFSIGN(x) * powf(ax, 2.2f * scale); + } else { + const float log_base = expf(2.2f * scale); + + return FFSIGN(x) * powf(log_base, ax - 1.f); + } +} + +static int dwa_uncompress(EXRContext *s, const uint8_t *src, int compressed_size, + int uncompressed_size, EXRThreadData *td) +{ + int64_t version, lo_usize, lo_size; + int64_t ac_size, dc_size, rle_usize, rle_csize, rle_raw_size; + int64_t ac_count, dc_count, ac_compression; + const int dc_w = td->xsize >> 3; + const int dc_h = td->ysize >> 3; + GetByteContext gb, agb; + int skip, ret; + + if (compressed_size <= 88) + return AVERROR_INVALIDDATA; + + version = AV_RL64(src + 0); + if (version != 2) + return AVERROR_INVALIDDATA; + + lo_usize = AV_RL64(src + 8); + lo_size = AV_RL64(src + 16); + ac_size = AV_RL64(src + 24); + dc_size = AV_RL64(src + 32); + rle_csize = AV_RL64(src + 40); + rle_usize = AV_RL64(src + 48); + rle_raw_size = AV_RL64(src + 56); + ac_count = AV_RL64(src + 64); + dc_count = AV_RL64(src + 72); + ac_compression = AV_RL64(src + 80); + + if (compressed_size < 88LL + lo_size + ac_size + dc_size + rle_csize) + return AVERROR_INVALIDDATA; + + bytestream2_init(&gb, src + 88, compressed_size - 88); + skip = bytestream2_get_le16(&gb); + if (skip < 2) + return AVERROR_INVALIDDATA; + + bytestream2_skip(&gb, skip - 2); + + if (lo_size > 0) { + if (lo_usize > uncompressed_size) + return AVERROR_INVALIDDATA; + bytestream2_skip(&gb, lo_size); + } + + if (ac_size > 0) { + unsigned long dest_len = ac_count * 2LL; + GetByteContext agb = gb; + + if (ac_count > 3LL * td->xsize * s->scan_lines_per_block) + return AVERROR_INVALIDDATA; + + av_fast_padded_malloc(&td->ac_data, &td->ac_size, dest_len); + if (!td->ac_data) + return AVERROR(ENOMEM); + + switch (ac_compression) { + case 0: + ret = huf_uncompress(s, td, &agb, (int16_t *)td->ac_data, ac_count); + if (ret < 0) + return ret; + break; + case 1: + if (uncompress(td->ac_data, &dest_len, agb.buffer, ac_size) != Z_OK || + dest_len != ac_count * 2LL) + return AVERROR_INVALIDDATA; + break; + default: + return AVERROR_INVALIDDATA; + } + + bytestream2_skip(&gb, ac_size); + } + + if (dc_size > 0) { + unsigned long dest_len = dc_count * 2LL; + GetByteContext agb = gb; + + if (dc_count > (6LL * td->xsize * td->ysize + 63) / 64) + return AVERROR_INVALIDDATA; + + av_fast_padded_malloc(&td->dc_data, &td->dc_size, FFALIGN(dest_len, 64) * 2); + if (!td->dc_data) + return AVERROR(ENOMEM); + + if (uncompress(td->dc_data + FFALIGN(dest_len, 64), &dest_len, agb.buffer, dc_size) != Z_OK || + (dest_len != dc_count * 2LL)) + return AVERROR_INVALIDDATA; + + s->dsp.predictor(td->dc_data + FFALIGN(dest_len, 64), dest_len); + s->dsp.reorder_pixels(td->dc_data, td->dc_data + FFALIGN(dest_len, 64), dest_len); + + bytestream2_skip(&gb, dc_size); + } + + if (rle_raw_size > 0 && rle_csize > 0 && rle_usize > 0) { + unsigned long dest_len = rle_usize; + + av_fast_padded_malloc(&td->rle_data, &td->rle_size, rle_usize); + if (!td->rle_data) + return AVERROR(ENOMEM); + + av_fast_padded_malloc(&td->rle_raw_data, &td->rle_raw_size, rle_raw_size); + if (!td->rle_raw_data) + return AVERROR(ENOMEM); + + if (uncompress(td->rle_data, &dest_len, gb.buffer, rle_csize) != Z_OK || + (dest_len != rle_usize)) + return AVERROR_INVALIDDATA; + + ret = rle(td->rle_raw_data, td->rle_data, rle_usize, rle_raw_size); + if (ret < 0) + return ret; + bytestream2_skip(&gb, rle_csize); + } + + bytestream2_init(&agb, td->ac_data, ac_count * 2); + + for (int y = 0; y < td->ysize; y += 8) { + for (int x = 0; x < td->xsize; x += 8) { + memset(td->block, 0, sizeof(td->block)); + + for (int j = 0; j < 3; j++) { + float *block = td->block[j]; + const int idx = (x >> 3) + (y >> 3) * dc_w + dc_w * dc_h * j; + uint16_t *dc = (uint16_t *)td->dc_data; + union av_intfloat32 dc_val; + + dc_val.i = half2float(dc[idx], s->mantissatable, + s->exponenttable, s->offsettable); + + block[0] = dc_val.f; + ac_uncompress(s, &agb, block); + dct_inverse(block); + } + + { + const float scale = s->pixel_type == EXR_FLOAT ? 2.f : 1.f; + const int o = s->nb_channels == 4; + float *bo = ((float *)td->uncompressed_data) + + y * td->xsize * s->nb_channels + td->xsize * (o + 0) + x; + float *go = ((float *)td->uncompressed_data) + + y * td->xsize * s->nb_channels + td->xsize * (o + 1) + x; + float *ro = ((float *)td->uncompressed_data) + + y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x; + float *yb = td->block[0]; + float *ub = td->block[1]; + float *vb = td->block[2]; + + for (int yy = 0; yy < 8; yy++) { + for (int xx = 0; xx < 8; xx++) { + const int idx = xx + yy * 8; + + convert(yb[idx], ub[idx], vb[idx], &bo[xx], &go[xx], &ro[xx]); + + bo[xx] = to_linear(bo[xx], scale); + go[xx] = to_linear(go[xx], scale); + ro[xx] = to_linear(ro[xx], scale); + } + + bo += td->xsize * s->nb_channels; + go += td->xsize * s->nb_channels; + ro += td->xsize * s->nb_channels; + } + } + } + } + + if (s->nb_channels < 4) + return 0; + + for (int y = 0; y < td->ysize && td->rle_raw_data; y++) { + uint32_t *ao = ((uint32_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels; + uint8_t *ai0 = td->rle_raw_data + y * td->xsize; + uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2; + + for (int x = 0; x < td->xsize; x++) { + uint16_t ha = ai0[x] | (ai1[x] << 8); + + ao[x] = half2float(ha, s->mantissatable, s->exponenttable, s->offsettable); + } + } + + return 0; +} + static int decode_block(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr) { @@ -995,12 +1182,13 @@ static int decode_block(AVCodecContext *avctx, void *tdata, uint64_t line_offset, uncompressed_size; uint8_t *ptr; uint32_t data_size; - uint64_t line, col = 0; + int line, col = 0; uint64_t tile_x, tile_y, tile_level_x, tile_level_y; const uint8_t *src; int step = s->desc->flags & AV_PIX_FMT_FLAG_FLOAT ? 4 : 2 * s->desc->nb_components; - int axmax = (avctx->width - (s->xmax + 1)) * step; /* nb pixel to add at the right of the datawindow */ - int bxmin = s->xmin * step; /* nb pixel to add at the left of the datawindow */ + int bxmin = 0, axmax = 0, window_xoffset = 0; + int window_xmin, window_xmax, window_ymin, window_ymax; + int data_xoffset, data_yoffset, data_window_offset, xsize, ysize; int i, x, buf_size = s->buf_size; int c, rgb_channel_count; float one_gamma = 1.0f / s->gamma; @@ -1014,6 +1202,8 @@ static int decode_block(AVCodecContext *avctx, void *tdata, return AVERROR_INVALIDDATA; src = buf + line_offset + 20; + if (s->is_multipart) + src += 4; tile_x = AV_RL32(src - 20); tile_y = AV_RL32(src - 16); @@ -1029,28 +1219,21 @@ static int decode_block(AVCodecContext *avctx, void *tdata, return AVERROR_PATCHWELCOME; } - if (s->xmin || s->ymin) { - avpriv_report_missing_feature(s->avctx, "Tiles with xmin/ymin"); - return AVERROR_PATCHWELCOME; - } + if (tile_x && s->tile_attr.xSize + (int64_t)FFMAX(s->xmin, 0) >= INT_MAX / tile_x ) + return AVERROR_INVALIDDATA; + if (tile_y && s->tile_attr.ySize + (int64_t)FFMAX(s->ymin, 0) >= INT_MAX / tile_y ) + return AVERROR_INVALIDDATA; - line = s->tile_attr.ySize * tile_y; + line = s->ymin + s->tile_attr.ySize * tile_y; col = s->tile_attr.xSize * tile_x; if (line < s->ymin || line > s->ymax || - col < s->xmin || col > s->xmax) + s->xmin + col < s->xmin || s->xmin + col > s->xmax) return AVERROR_INVALIDDATA; td->ysize = FFMIN(s->tile_attr.ySize, s->ydelta - tile_y * s->tile_attr.ySize); td->xsize = FFMIN(s->tile_attr.xSize, s->xdelta - tile_x * s->tile_attr.xSize); - if (col) { /* not the first tile of the line */ - bxmin = 0; /* doesn't add pixel at the left of the datawindow */ - } - - if ((col + td->xsize) != s->xdelta)/* not the last tile of the line */ - axmax = 0; /* doesn't add pixel at the right of the datawindow */ - if (td->xsize * (uint64_t)s->current_channel_offset > INT_MAX) return AVERROR_INVALIDDATA; @@ -1061,6 +1244,8 @@ static int decode_block(AVCodecContext *avctx, void *tdata, return AVERROR_INVALIDDATA; src = buf + line_offset + 8; + if (s->is_multipart) + src += 4; line = AV_RL32(src - 8); if (line < s->ymin || line > s->ymax) @@ -1087,6 +1272,33 @@ static int decode_block(AVCodecContext *avctx, void *tdata, } } + window_xmin = FFMIN(avctx->width, FFMAX(0, s->xmin + col)); + window_xmax = FFMIN(avctx->width, FFMAX(0, s->xmin + col + td->xsize)); + window_ymin = FFMIN(avctx->height, FFMAX(0, line )); + window_ymax = FFMIN(avctx->height, FFMAX(0, line + td->ysize)); + xsize = window_xmax - window_xmin; + ysize = window_ymax - window_ymin; + + /* tile or scanline not visible skip decoding */ + if (xsize <= 0 || ysize <= 0) + return 0; + + /* is the first tile or is a scanline */ + if(col == 0) { + window_xmin = 0; + /* pixels to add at the left of the display window */ + window_xoffset = FFMAX(0, s->xmin); + /* bytes to add at the left of the display window */ + bxmin = window_xoffset * step; + } + + /* is the last tile or is a scanline */ + if(col + td->xsize == s->xdelta) { + window_xmax = avctx->width; + /* bytes to add at the right of the display window */ + axmax = FFMAX(0, (avctx->width - (s->xmax + 1))) * step; + } + if (data_size < uncompressed_size || s->is_tile) { /* td->tmp is use for tile reorganization */ av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size); if (!td->tmp) @@ -1119,6 +1331,10 @@ static int decode_block(AVCodecContext *avctx, void *tdata, case EXR_B44A: ret = b44_uncompress(s, src, data_size, uncompressed_size, td); break; + case EXR_DWAA: + case EXR_DWAB: + ret = dwa_uncompress(s, src, data_size, uncompressed_size, td); + break; } if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "decode_block() failed.\n"); @@ -1127,20 +1343,24 @@ static int decode_block(AVCodecContext *avctx, void *tdata, src = td->uncompressed_data; } + /* offsets to crop data outside display window */ + data_xoffset = FFABS(FFMIN(0, s->xmin + col)) * (s->pixel_type == EXR_HALF ? 2 : 4); + data_yoffset = FFABS(FFMIN(0, line)); + data_window_offset = (data_yoffset * td->channel_line_size) + data_xoffset; + if (!s->is_luma) { - channel_buffer[0] = src + td->xsize * s->channel_offsets[0]; - channel_buffer[1] = src + td->xsize * s->channel_offsets[1]; - channel_buffer[2] = src + td->xsize * s->channel_offsets[2]; + channel_buffer[0] = src + (td->xsize * s->channel_offsets[0]) + data_window_offset; + channel_buffer[1] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset; + channel_buffer[2] = src + (td->xsize * s->channel_offsets[2]) + data_window_offset; rgb_channel_count = 3; } else { /* put y data in the first channel_buffer */ - channel_buffer[0] = src + td->xsize * s->channel_offsets[1]; + channel_buffer[0] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset; rgb_channel_count = 1; } - if (s->channel_offsets[3] >= 0) - channel_buffer[3] = src + td->xsize * s->channel_offsets[3]; + if (s->channel_offsets[3] >= 0) + channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset; if (s->desc->flags & AV_PIX_FMT_FLAG_FLOAT) { - /* todo: change this when a floating point pixel format with luma with alpha is implemented */ int channel_count = s->channel_offsets[3] >= 0 ? 4 : rgb_channel_count; if (s->is_luma) { @@ -1150,9 +1370,9 @@ static int decode_block(AVCodecContext *avctx, void *tdata, for (c = 0; c < channel_count; c++) { int plane = s->desc->comp[c].plane; - ptr = p->data[plane] + line * p->linesize[plane] + (col * 4); + ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * 4); - for (i = 0; i < td->ysize; i++, ptr += p->linesize[plane]) { + for (i = 0; i < ysize; i++, ptr += p->linesize[plane]) { const uint8_t *src; union av_intfloat32 *ptr_x; @@ -1161,34 +1381,45 @@ static int decode_block(AVCodecContext *avctx, void *tdata, // Zero out the start if xmin is not 0 memset(ptr_x, 0, bxmin); - ptr_x += s->xmin; + ptr_x += window_xoffset; - if (s->pixel_type == EXR_FLOAT) { + if (s->pixel_type == EXR_FLOAT || + s->compression == EXR_DWAA || + s->compression == EXR_DWAB) { // 32-bit union av_intfloat32 t; if (trc_func && c < 3) { - for (x = 0; x < td->xsize; x++) { + for (x = 0; x < xsize; x++) { t.i = bytestream_get_le32(&src); t.f = trc_func(t.f); *ptr_x++ = t; } - } else { - for (x = 0; x < td->xsize; x++) { + } else if (one_gamma != 1.f) { + for (x = 0; x < xsize; x++) { t.i = bytestream_get_le32(&src); if (t.f > 0.0f && c < 3) /* avoid negative values */ t.f = powf(t.f, one_gamma); *ptr_x++ = t; } + } else { + for (x = 0; x < xsize; x++) { + t.i = bytestream_get_le32(&src); + *ptr_x++ = t; + } } } else if (s->pixel_type == EXR_HALF) { // 16-bit - if (c < 3) { - for (x = 0; x < td->xsize; x++) { + if (c < 3 || !trc_func) { + for (x = 0; x < xsize; x++) { *ptr_x++ = s->gamma_table[bytestream_get_le16(&src)]; } } else { - for (x = 0; x < td->xsize; x++) { - *ptr_x++ = exr_half2float(bytestream_get_le16(&src));; + for (x = 0; x < xsize; x++) { + ptr_x[0].i = half2float(bytestream_get_le16(&src), + s->mantissatable, + s->exponenttable, + s->offsettable); + ptr_x++; } } } @@ -1201,9 +1432,9 @@ static int decode_block(AVCodecContext *avctx, void *tdata, } else { av_assert1(s->pixel_type == EXR_UINT); - ptr = p->data[0] + line * p->linesize[0] + (col * s->desc->nb_components * 2); + ptr = p->data[0] + window_ymin * p->linesize[0] + (window_xmin * s->desc->nb_components * 2); - for (i = 0; i < td->ysize; i++, ptr += p->linesize[0]) { + for (i = 0; i < ysize; i++, ptr += p->linesize[0]) { const uint8_t * a; const uint8_t *rgb[3]; @@ -1220,9 +1451,9 @@ static int decode_block(AVCodecContext *avctx, void *tdata, // Zero out the start if xmin is not 0 memset(ptr_x, 0, bxmin); - ptr_x += s->xmin * s->desc->nb_components; + ptr_x += window_xoffset * s->desc->nb_components; - for (x = 0; x < td->xsize; x++) { + for (x = 0; x < xsize; x++) { for (c = 0; c < rgb_channel_count; c++) { *ptr_x++ = bytestream_get_le32(&rgb[c]) >> 16; } @@ -1245,6 +1476,23 @@ static int decode_block(AVCodecContext *avctx, void *tdata, return 0; } +static void skip_header_chunk(EXRContext *s) +{ + GetByteContext *gb = &s->gb; + + while (bytestream2_get_bytes_left(gb) > 0) { + if (!bytestream2_peek_byte(gb)) + break; + + // Process unknown variables + for (int i = 0; i < 2; i++) // value_name and value_type + while (bytestream2_get_byte(gb) != 0); + + // Skip variable length + bytestream2_skip(gb, bytestream2_get_le32(gb)); + } +} + /** * Check if the variable name corresponds to its data type. * @@ -1262,21 +1510,22 @@ static int check_header_variable(EXRContext *s, const char *value_type, unsigned int minimum_length) { + GetByteContext *gb = &s->gb; int var_size = -1; - if (bytestream2_get_bytes_left(&s->gb) >= minimum_length && - !strcmp(s->gb.buffer, value_name)) { + if (bytestream2_get_bytes_left(gb) >= minimum_length && + !strcmp(gb->buffer, value_name)) { // found value_name, jump to value_type (null terminated strings) - s->gb.buffer += strlen(value_name) + 1; - if (!strcmp(s->gb.buffer, value_type)) { - s->gb.buffer += strlen(value_type) + 1; - var_size = bytestream2_get_le32(&s->gb); + gb->buffer += strlen(value_name) + 1; + if (!strcmp(gb->buffer, value_type)) { + gb->buffer += strlen(value_type) + 1; + var_size = bytestream2_get_le32(gb); // don't go read past boundaries - if (var_size > bytestream2_get_bytes_left(&s->gb)) + if (var_size > bytestream2_get_bytes_left(gb)) var_size = 0; } else { // value_type not found, reset the buffer - s->gb.buffer -= strlen(value_name) + 1; + gb->buffer -= strlen(value_name) + 1; av_log(s->avctx, AV_LOG_WARNING, "Unknown data type %s for header variable %s.\n", value_type, value_name); @@ -1289,7 +1538,8 @@ static int check_header_variable(EXRContext *s, static int decode_header(EXRContext *s, AVFrame *frame) { AVDictionary *metadata = NULL; - int magic_number, version, i, flags, sar = 0; + GetByteContext *gb = &s->gb; + int magic_number, version, flags; int layer_match = 0; int ret; int dup_channels = 0; @@ -1313,14 +1563,16 @@ static int decode_header(EXRContext *s, AVFrame *frame) s->tile_attr.xSize = -1; s->tile_attr.ySize = -1; s->is_tile = 0; + s->is_multipart = 0; s->is_luma = 0; + s->current_part = 0; - if (bytestream2_get_bytes_left(&s->gb) < 10) { + if (bytestream2_get_bytes_left(gb) < 10) { av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n"); return AVERROR_INVALIDDATA; } - magic_number = bytestream2_get_le32(&s->gb); + magic_number = bytestream2_get_le32(gb); if (magic_number != 20000630) { /* As per documentation of OpenEXR, it is supposed to be * int 20000630 little-endian */ @@ -1328,28 +1580,60 @@ static int decode_header(EXRContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } - version = bytestream2_get_byte(&s->gb); + version = bytestream2_get_byte(gb); if (version != 2) { avpriv_report_missing_feature(s->avctx, "Version %d", version); return AVERROR_PATCHWELCOME; } - flags = bytestream2_get_le24(&s->gb); + flags = bytestream2_get_le24(gb); if (flags & 0x02) s->is_tile = 1; + if (flags & 0x10) + s->is_multipart = 1; if (flags & 0x08) { avpriv_report_missing_feature(s->avctx, "deep data"); return AVERROR_PATCHWELCOME; } - if (flags & 0x10) { - avpriv_report_missing_feature(s->avctx, "multipart"); - return AVERROR_PATCHWELCOME; - } // Parse the header - while (bytestream2_get_bytes_left(&s->gb) > 0 && *s->gb.buffer) { + while (bytestream2_get_bytes_left(gb) > 0) { int var_size; + + while (s->is_multipart && s->current_part < s->selected_part && + bytestream2_get_bytes_left(gb) > 0) { + if (bytestream2_peek_byte(gb)) { + skip_header_chunk(s); + } else { + bytestream2_skip(gb, 1); + if (!bytestream2_peek_byte(gb)) + break; + } + bytestream2_skip(gb, 1); + s->current_part++; + } + + if (!bytestream2_peek_byte(gb)) { + if (!s->is_multipart) + break; + bytestream2_skip(gb, 1); + if (s->current_part == s->selected_part) { + while (bytestream2_get_bytes_left(gb) > 0) { + if (bytestream2_peek_byte(gb)) { + skip_header_chunk(s); + } else { + bytestream2_skip(gb, 1); + if (!bytestream2_peek_byte(gb)) + break; + } + } + } + if (!bytestream2_peek_byte(gb)) + break; + s->current_part++; + } + if ((var_size = check_header_variable(s, "channels", "chlist", 38)) >= 0) { GetByteContext ch_gb; @@ -1358,7 +1642,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) goto fail; } - bytestream2_init(&ch_gb, s->gb.buffer, var_size); + bytestream2_init(&ch_gb, gb->buffer, var_size); while (bytestream2_get_bytes_left(&ch_gb) >= 19) { EXRChannel *channel; @@ -1495,7 +1779,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) } // skip one last byte and update main gb - s->gb.buffer = ch_gb.buffer + 1; + gb->buffer = ch_gb.buffer + 1; continue; } else if ((var_size = check_header_variable(s, "dataWindow", "box2i", 31)) >= 0) { @@ -1505,10 +1789,10 @@ static int decode_header(EXRContext *s, AVFrame *frame) goto fail; } - xmin = bytestream2_get_le32(&s->gb); - ymin = bytestream2_get_le32(&s->gb); - xmax = bytestream2_get_le32(&s->gb); - ymax = bytestream2_get_le32(&s->gb); + xmin = bytestream2_get_le32(gb); + ymin = bytestream2_get_le32(gb); + xmax = bytestream2_get_le32(gb); + ymax = bytestream2_get_le32(gb); if (xmin > xmax || ymin > ymax || (unsigned)xmax - xmin >= INT_MAX || @@ -1526,14 +1810,20 @@ static int decode_header(EXRContext *s, AVFrame *frame) continue; } else if ((var_size = check_header_variable(s, "displayWindow", "box2i", 34)) >= 0) { + int32_t sx, sy, dx, dy; + if (!var_size) { ret = AVERROR_INVALIDDATA; goto fail; } - bytestream2_skip(&s->gb, 8); - s->w = bytestream2_get_le32(&s->gb) + 1; - s->h = bytestream2_get_le32(&s->gb) + 1; + sx = bytestream2_get_le32(gb); + sy = bytestream2_get_le32(gb); + dx = bytestream2_get_le32(gb); + dy = bytestream2_get_le32(gb); + + s->w = dx - sx + 1; + s->h = dy - sy + 1; continue; } else if ((var_size = check_header_variable(s, "lineOrder", @@ -1544,7 +1834,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) goto fail; } - line_order = bytestream2_get_byte(&s->gb); + line_order = bytestream2_get_byte(gb); av_log(s->avctx, AV_LOG_DEBUG, "line order: %d.\n", line_order); if (line_order > 2) { av_log(s->avctx, AV_LOG_ERROR, "Unknown line order.\n"); @@ -1560,7 +1850,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) goto fail; } - sar = bytestream2_get_le32(&s->gb); + s->sar = bytestream2_get_le32(gb); continue; } else if ((var_size = check_header_variable(s, "compression", @@ -1571,10 +1861,12 @@ static int decode_header(EXRContext *s, AVFrame *frame) } if (s->compression == EXR_UNKN) - s->compression = bytestream2_get_byte(&s->gb); - else + s->compression = bytestream2_get_byte(gb); + else { + bytestream2_skip(gb, 1); av_log(s->avctx, AV_LOG_WARNING, "Found more than one compression attribute.\n"); + } continue; } else if ((var_size = check_header_variable(s, "tiles", @@ -1585,10 +1877,10 @@ static int decode_header(EXRContext *s, AVFrame *frame) av_log(s->avctx, AV_LOG_WARNING, "Found tile attribute and scanline flags. Exr will be interpreted as scanline.\n"); - s->tile_attr.xSize = bytestream2_get_le32(&s->gb); - s->tile_attr.ySize = bytestream2_get_le32(&s->gb); + s->tile_attr.xSize = bytestream2_get_le32(gb); + s->tile_attr.ySize = bytestream2_get_le32(gb); - tileLevel = bytestream2_get_byte(&s->gb); + tileLevel = bytestream2_get_byte(gb); s->tile_attr.level_mode = tileLevel & 0x0f; s->tile_attr.level_round = (tileLevel >> 4) & 0x0f; @@ -1611,29 +1903,85 @@ static int decode_header(EXRContext *s, AVFrame *frame) "string", 1)) >= 0) { uint8_t key[256] = { 0 }; - bytestream2_get_buffer(&s->gb, key, FFMIN(sizeof(key) - 1, var_size)); + bytestream2_get_buffer(gb, key, FFMIN(sizeof(key) - 1, var_size)); av_dict_set(&metadata, "writer", key, 0); + continue; + } else if ((var_size = check_header_variable(s, "framesPerSecond", + "rational", 33)) >= 0) { + if (!var_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + s->avctx->framerate.num = bytestream2_get_le32(gb); + s->avctx->framerate.den = bytestream2_get_le32(gb); + + continue; + } else if ((var_size = check_header_variable(s, "chunkCount", + "int", 23)) >= 0) { + + s->chunk_count = bytestream2_get_le32(gb); + + continue; + } else if ((var_size = check_header_variable(s, "type", + "string", 16)) >= 0) { + uint8_t key[256] = { 0 }; + + bytestream2_get_buffer(gb, key, FFMIN(sizeof(key) - 1, var_size)); + if (strncmp("scanlineimage", key, var_size) && + strncmp("tiledimage", key, var_size)) + return AVERROR_PATCHWELCOME; + + continue; + } else if ((var_size = check_header_variable(s, "preview", + "preview", 16)) >= 0) { + uint32_t pw = bytestream2_get_le32(gb); + uint32_t ph = bytestream2_get_le32(gb); + int64_t psize = 4LL * pw * ph; + + if (psize >= bytestream2_get_bytes_left(gb)) + return AVERROR_INVALIDDATA; + + bytestream2_skip(gb, psize); + continue; } // Check if there are enough bytes for a header - if (bytestream2_get_bytes_left(&s->gb) <= 9) { + if (bytestream2_get_bytes_left(gb) <= 9) { av_log(s->avctx, AV_LOG_ERROR, "Incomplete header\n"); ret = AVERROR_INVALIDDATA; goto fail; } // Process unknown variables - for (i = 0; i < 2; i++) // value_name and value_type - while (bytestream2_get_byte(&s->gb) != 0); + { + uint8_t name[256] = { 0 }; + uint8_t type[256] = { 0 }; + uint8_t value[256] = { 0 }; + int i = 0, size; - // Skip variable length - bytestream2_skip(&s->gb, bytestream2_get_le32(&s->gb)); + while (bytestream2_get_bytes_left(gb) > 0 && + bytestream2_peek_byte(gb) && i < 255) { + name[i++] = bytestream2_get_byte(gb); + } + + bytestream2_skip(gb, 1); + i = 0; + while (bytestream2_get_bytes_left(gb) > 0 && + bytestream2_peek_byte(gb) && i < 255) { + type[i++] = bytestream2_get_byte(gb); + } + bytestream2_skip(gb, 1); + size = bytestream2_get_le32(gb); + + bytestream2_get_buffer(gb, value, FFMIN(sizeof(value) - 1, size)); + if (!strcmp(type, "string")) + av_dict_set(&metadata, name, value, 0); + } } - ff_set_sar(s->avctx, av_d2q(av_int2float(sar), 255)); - if (s->compression == EXR_UNKN) { av_log(s->avctx, AV_LOG_ERROR, "Missing compression attribute.\n"); ret = AVERROR_INVALIDDATA; @@ -1648,7 +1996,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) } } - if (bytestream2_get_bytes_left(&s->gb) <= 0) { + if (bytestream2_get_bytes_left(gb) <= 0) { av_log(s->avctx, AV_LOG_ERROR, "Incomplete frame.\n"); ret = AVERROR_INVALIDDATA; goto fail; @@ -1657,7 +2005,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) frame->metadata = metadata; // aaand we are done - bytestream2_skip(&s->gb, 1); + bytestream2_skip(gb, 1); return 0; fail: av_dict_free(&metadata); @@ -1668,11 +2016,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { EXRContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; ThreadFrame frame = { .f = data }; AVFrame *picture = data; uint8_t *ptr; - int i, y, ret; + int i, y, ret, ymax; int planes; int out_line_size; int nb_blocks; /* nb scanline or nb tile */ @@ -1680,11 +2029,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, uint64_t start_next_scanline; PutByteContext offset_table_writer; - bytestream2_init(&s->gb, avpkt->data, avpkt->size); + bytestream2_init(gb, avpkt->data, avpkt->size); if ((ret = decode_header(s, picture)) < 0) return ret; + if ((s->compression == EXR_DWAA || s->compression == EXR_DWAB) && + s->pixel_type == EXR_HALF) { + s->current_channel_offset *= 2; + for (int i = 0; i < 4; i++) + s->channel_offsets[i] *= 2; + } + switch (s->pixel_type) { case EXR_FLOAT: case EXR_HALF: @@ -1739,22 +2095,21 @@ static int decode_frame(AVCodecContext *avctx, void *data, case EXR_PIZ: case EXR_B44: case EXR_B44A: + case EXR_DWAA: s->scan_lines_per_block = 32; break; + case EXR_DWAB: + s->scan_lines_per_block = 256; + break; default: avpriv_report_missing_feature(avctx, "Compression %d", s->compression); return AVERROR_PATCHWELCOME; } - /* Verify the xmin, xmax, ymin, ymax and xdelta before setting - * the actual image size. */ - if (s->xmin > s->xmax || - s->ymin > s->ymax || - s->xdelta != s->xmax - s->xmin + 1 || - s->xmax >= s->w || - s->ymax >= s->h || - s->ydelta == 0xFFFFFFFF || s->xdelta == 0xFFFFFFFF - ) { + /* Verify the xmin, xmax, ymin and ymax before setting the actual image size. + * It's possible for the data window can larger or outside the display window */ + if (s->xmin > s->xmax || s->ymin > s->ymax || + s->ydelta == 0xFFFFFFFF || s->xdelta == 0xFFFFFFFF) { av_log(avctx, AV_LOG_ERROR, "Wrong or missing size information.\n"); return AVERROR_INVALIDDATA; } @@ -1762,6 +2117,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_set_dimensions(avctx, s->w, s->h)) < 0) return ret; + ff_set_sar(s->avctx, av_d2q(av_int2float(s->sar), 255)); + s->desc = av_pix_fmt_desc_get(avctx->pix_fmt); if (!s->desc) return AVERROR_INVALIDDATA; @@ -1785,14 +2142,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; - if (bytestream2_get_bytes_left(&s->gb)/8 < nb_blocks) + if (bytestream2_get_bytes_left(gb)/8 < nb_blocks) return AVERROR_INVALIDDATA; // check offset table and recreate it if need - if (!s->is_tile && bytestream2_peek_le64(&s->gb) == 0) { + if (!s->is_tile && bytestream2_peek_le64(gb) == 0) { av_log(s->avctx, AV_LOG_DEBUG, "recreating invalid scanline offset table\n"); - start_offset_table = bytestream2_tell(&s->gb); + start_offset_table = bytestream2_tell(gb); start_next_scanline = start_offset_table + nb_blocks * 8; bytestream2_init_writer(&offset_table_writer, &avpkt->data[start_offset_table], nb_blocks * 8); @@ -1801,10 +2158,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, bytestream2_put_le64(&offset_table_writer, start_next_scanline); /* get len of next scanline */ - bytestream2_seek(&s->gb, start_next_scanline + 4, SEEK_SET);/* skip line number */ - start_next_scanline += (bytestream2_get_le32(&s->gb) + 8); + bytestream2_seek(gb, start_next_scanline + 4, SEEK_SET);/* skip line number */ + start_next_scanline += (bytestream2_get_le32(gb) + 8); } - bytestream2_seek(&s->gb, start_offset_table, SEEK_SET); + bytestream2_seek(gb, start_offset_table, SEEK_SET); } // save pointer we are going to use in decode_block @@ -1824,14 +2181,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, avctx->execute2(avctx, decode_block, s->thread_data, NULL, nb_blocks); + ymax = FFMAX(0, s->ymax + 1); // Zero out the end if ymax+1 is not h - for (i = 0; i < planes; i++) { - ptr = picture->data[i] + ((s->ymax+1) * picture->linesize[i]); - for (y = s->ymax + 1; y < avctx->height; y++) { - memset(ptr, 0, out_line_size); - ptr += picture->linesize[i]; + if (ymax < avctx->height) + for (i = 0; i < planes; i++) { + ptr = picture->data[i] + (ymax * picture->linesize[i]); + for (y = ymax; y < avctx->height; y++) { + memset(ptr, 0, out_line_size); + ptr += picture->linesize[i]; + } } - } picture->pict_type = AV_PICTURE_TYPE_I; *got_frame = 1; @@ -1847,6 +2206,8 @@ static av_cold int decode_init(AVCodecContext *avctx) float one_gamma = 1.0f / s->gamma; avpriv_trc_function trc_func = NULL; + half2float_table(s->mantissatable, s->exponenttable, s->offsettable); + s->avctx = avctx; ff_exrdsp_init(&s->dsp); @@ -1858,18 +2219,18 @@ static av_cold int decode_init(AVCodecContext *avctx) trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type); if (trc_func) { for (i = 0; i < 65536; ++i) { - t = exr_half2float(i); + t.i = half2float(i, s->mantissatable, s->exponenttable, s->offsettable); t.f = trc_func(t.f); s->gamma_table[i] = t; } } else { if (one_gamma > 0.9999f && one_gamma < 1.0001f) { for (i = 0; i < 65536; ++i) { - s->gamma_table[i] = exr_half2float(i); + s->gamma_table[i].i = half2float(i, s->mantissatable, s->exponenttable, s->offsettable); } } else { for (i = 0; i < 65536; ++i) { - t = exr_half2float(i); + t.i = half2float(i, s->mantissatable, s->exponenttable, s->offsettable); /* If negative value we reuse half value */ if (t.f <= 0.0f) { s->gamma_table[i] = t; @@ -1899,6 +2260,13 @@ static av_cold int decode_end(AVCodecContext *avctx) av_freep(&td->tmp); av_freep(&td->bitmap); av_freep(&td->lut); + av_freep(&td->he); + av_freep(&td->freq); + av_freep(&td->ac_data); + av_freep(&td->dc_data); + av_freep(&td->rle_data); + av_freep(&td->rle_raw_data); + ff_free_vlc(&td->vlc); } av_freep(&s->thread_data); @@ -1912,6 +2280,8 @@ static av_cold int decode_end(AVCodecContext *avctx) static const AVOption options[] = { { "layer", "Set the decoding layer", OFFSET(layer), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD }, + { "part", "Set the decoding part", OFFSET(selected_part), + AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD }, { "gamma", "Set the float gamma value when decoding", OFFSET(gamma), AV_OPT_TYPE_FLOAT, { .dbl = 1.0f }, 0.001, FLT_MAX, VD }, diff --git a/libavcodec/exrenc.c b/libavcodec/exrenc.c new file mode 100644 index 000000000..db9000a85 --- /dev/null +++ b/libavcodec/exrenc.c @@ -0,0 +1,552 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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 + * OpenEXR encoder + */ + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/opt.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/imgutils.h" +#include "libavutil/pixdesc.h" +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" +#include "float2half.h" + +enum ExrCompr { + EXR_RAW, + EXR_RLE, + EXR_ZIP1, + EXR_ZIP16, + EXR_NBCOMPR, +}; + +enum ExrPixelType { + EXR_UINT, + EXR_HALF, + EXR_FLOAT, + EXR_UNKNOWN, +}; + +static const char abgr_chlist[4] = { 'A', 'B', 'G', 'R' }; +static const char bgr_chlist[4] = { 'B', 'G', 'R', 'A' }; +static const uint8_t gbra_order[4] = { 3, 1, 0, 2 }; +static const uint8_t gbr_order[4] = { 1, 0, 2, 0 }; + +typedef struct EXRScanlineData { + uint8_t *compressed_data; + unsigned int compressed_size; + + uint8_t *uncompressed_data; + unsigned int uncompressed_size; + + uint8_t *tmp; + unsigned int tmp_size; + + int64_t actual_size; +} EXRScanlineData; + +typedef struct EXRContext { + const AVClass *class; + + int compression; + int pixel_type; + int planes; + int nb_scanlines; + int scanline_height; + float gamma; + const char *ch_names; + const uint8_t *ch_order; + PutByteContext pb; + + EXRScanlineData *scanline; + + uint16_t basetable[512]; + uint8_t shifttable[512]; +} EXRContext; + +static int encode_init(AVCodecContext *avctx) +{ + EXRContext *s = avctx->priv_data; + + float2half_tables(s->basetable, s->shifttable); + + switch (avctx->pix_fmt) { + case AV_PIX_FMT_GBRPF32: + s->planes = 3; + s->ch_names = bgr_chlist; + s->ch_order = gbr_order; + break; + case AV_PIX_FMT_GBRAPF32: + s->planes = 4; + s->ch_names = abgr_chlist; + s->ch_order = gbra_order; + break; + default: + av_assert0(0); + } + + switch (s->compression) { + case EXR_RAW: + case EXR_RLE: + case EXR_ZIP1: + s->scanline_height = 1; + s->nb_scanlines = avctx->height; + break; + case EXR_ZIP16: + s->scanline_height = 16; + s->nb_scanlines = (avctx->height + s->scanline_height - 1) / s->scanline_height; + break; + default: + av_assert0(0); + } + + s->scanline = av_calloc(s->nb_scanlines, sizeof(*s->scanline)); + if (!s->scanline) + return AVERROR(ENOMEM); + + return 0; +} + +static int encode_close(AVCodecContext *avctx) +{ + EXRContext *s = avctx->priv_data; + + for (int y = 0; y < s->nb_scanlines && s->scanline; y++) { + EXRScanlineData *scanline = &s->scanline[y]; + + av_freep(&scanline->tmp); + av_freep(&scanline->compressed_data); + av_freep(&scanline->uncompressed_data); + } + + av_freep(&s->scanline); + + return 0; +} + +static void reorder_pixels(uint8_t *dst, const uint8_t *src, ptrdiff_t size) +{ + const ptrdiff_t half_size = (size + 1) / 2; + uint8_t *t1 = dst; + uint8_t *t2 = dst + half_size; + + for (ptrdiff_t i = 0; i < half_size; i++) { + t1[i] = *(src++); + t2[i] = *(src++); + } +} + +static void predictor(uint8_t *src, ptrdiff_t size) +{ + int p = src[0]; + + for (ptrdiff_t i = 1; i < size; i++) { + int d = src[i] - p + 384; + + p = src[i]; + src[i] = d; + } +} + +static int64_t rle_compress(uint8_t *out, int64_t out_size, + const uint8_t *in, int64_t in_size) +{ + int64_t i = 0, o = 0, run = 1, copy = 0; + + while (i < in_size) { + while (i + run < in_size && in[i] == in[i + run] && run < 128) + run++; + + if (run >= 3) { + if (o + 2 >= out_size) + return -1; + out[o++] = run - 1; + out[o++] = in[i]; + i += run; + } else { + if (i + run < in_size) + copy += run; + while (i + copy < in_size && copy < 127 && in[i + copy] != in[i + copy - 1]) + copy++; + + if (o + 1 + copy >= out_size) + return -1; + out[o++] = -copy; + + for (int x = 0; x < copy; x++) + out[o + x] = in[i + x]; + + o += copy; + i += copy; + copy = 0; + } + + run = 1; + } + + return o; +} + +static int encode_scanline_rle(EXRContext *s, const AVFrame *frame) +{ + const int64_t element_size = s->pixel_type == EXR_HALF ? 2LL : 4LL; + + for (int y = 0; y < frame->height; y++) { + EXRScanlineData *scanline = &s->scanline[y]; + int64_t tmp_size = element_size * s->planes * frame->width; + int64_t max_compressed_size = tmp_size * 3 / 2; + + av_fast_padded_malloc(&scanline->uncompressed_data, &scanline->uncompressed_size, tmp_size); + if (!scanline->uncompressed_data) + return AVERROR(ENOMEM); + + av_fast_padded_malloc(&scanline->tmp, &scanline->tmp_size, tmp_size); + if (!scanline->tmp) + return AVERROR(ENOMEM); + + av_fast_padded_malloc(&scanline->compressed_data, &scanline->compressed_size, max_compressed_size); + if (!scanline->compressed_data) + return AVERROR(ENOMEM); + + switch (s->pixel_type) { + case EXR_FLOAT: + for (int p = 0; p < s->planes; p++) { + int ch = s->ch_order[p]; + + memcpy(scanline->uncompressed_data + frame->width * 4 * p, + frame->data[ch] + y * frame->linesize[ch], frame->width * 4); + } + break; + case EXR_HALF: + for (int p = 0; p < s->planes; p++) { + int ch = s->ch_order[p]; + uint16_t *dst = (uint16_t *)(scanline->uncompressed_data + frame->width * 2 * p); + uint32_t *src = (uint32_t *)(frame->data[ch] + y * frame->linesize[ch]); + + for (int x = 0; x < frame->width; x++) + dst[x] = float2half(src[x], s->basetable, s->shifttable); + } + break; + } + + reorder_pixels(scanline->tmp, scanline->uncompressed_data, tmp_size); + predictor(scanline->tmp, tmp_size); + scanline->actual_size = rle_compress(scanline->compressed_data, + max_compressed_size, + scanline->tmp, tmp_size); + + if (scanline->actual_size <= 0 || scanline->actual_size >= tmp_size) { + FFSWAP(uint8_t *, scanline->uncompressed_data, scanline->compressed_data); + FFSWAP(int, scanline->uncompressed_size, scanline->compressed_size); + scanline->actual_size = tmp_size; + } + } + + return 0; +} + +static int encode_scanline_zip(EXRContext *s, const AVFrame *frame) +{ + const int64_t element_size = s->pixel_type == EXR_HALF ? 2LL : 4LL; + + for (int y = 0; y < s->nb_scanlines; y++) { + EXRScanlineData *scanline = &s->scanline[y]; + const int scanline_height = FFMIN(s->scanline_height, frame->height - y * s->scanline_height); + int64_t tmp_size = element_size * s->planes * frame->width * scanline_height; + int64_t max_compressed_size = tmp_size * 3 / 2; + unsigned long actual_size, source_size; + + av_fast_padded_malloc(&scanline->uncompressed_data, &scanline->uncompressed_size, tmp_size); + if (!scanline->uncompressed_data) + return AVERROR(ENOMEM); + + av_fast_padded_malloc(&scanline->tmp, &scanline->tmp_size, tmp_size); + if (!scanline->tmp) + return AVERROR(ENOMEM); + + av_fast_padded_malloc(&scanline->compressed_data, &scanline->compressed_size, max_compressed_size); + if (!scanline->compressed_data) + return AVERROR(ENOMEM); + + switch (s->pixel_type) { + case EXR_FLOAT: + for (int l = 0; l < scanline_height; l++) { + const int scanline_size = frame->width * 4 * s->planes; + + for (int p = 0; p < s->planes; p++) { + int ch = s->ch_order[p]; + + memcpy(scanline->uncompressed_data + scanline_size * l + p * frame->width * 4, + frame->data[ch] + (y * s->scanline_height + l) * frame->linesize[ch], + frame->width * 4); + } + } + break; + case EXR_HALF: + for (int l = 0; l < scanline_height; l++) { + const int scanline_size = frame->width * 2 * s->planes; + + for (int p = 0; p < s->planes; p++) { + int ch = s->ch_order[p]; + uint16_t *dst = (uint16_t *)(scanline->uncompressed_data + scanline_size * l + p * frame->width * 2); + uint32_t *src = (uint32_t *)(frame->data[ch] + (y * s->scanline_height + l) * frame->linesize[ch]); + + for (int x = 0; x < frame->width; x++) + dst[x] = float2half(src[x], s->basetable, s->shifttable); + } + } + break; + } + + reorder_pixels(scanline->tmp, scanline->uncompressed_data, tmp_size); + predictor(scanline->tmp, tmp_size); + source_size = tmp_size; + actual_size = max_compressed_size; + compress(scanline->compressed_data, &actual_size, + scanline->tmp, source_size); + + scanline->actual_size = actual_size; + if (scanline->actual_size >= tmp_size) { + FFSWAP(uint8_t *, scanline->uncompressed_data, scanline->compressed_data); + FFSWAP(int, scanline->uncompressed_size, scanline->compressed_size); + scanline->actual_size = tmp_size; + } + } + + return 0; +} + +static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *frame, int *got_packet) +{ + EXRContext *s = avctx->priv_data; + PutByteContext *pb = &s->pb; + int64_t offset; + int ret; + int64_t out_size = 2048LL + avctx->height * 16LL + + av_image_get_buffer_size(avctx->pix_fmt, + avctx->width, + avctx->height, 64) * 3LL / 2; + + if ((ret = ff_alloc_packet2(avctx, pkt, out_size, out_size)) < 0) + return ret; + + bytestream2_init_writer(pb, pkt->data, pkt->size); + + bytestream2_put_le32(pb, 20000630); + bytestream2_put_byte(pb, 2); + bytestream2_put_le24(pb, 0); + bytestream2_put_buffer(pb, "channels\0chlist\0", 16); + bytestream2_put_le32(pb, s->planes * 18 + 1); + + for (int p = 0; p < s->planes; p++) { + bytestream2_put_byte(pb, s->ch_names[p]); + bytestream2_put_byte(pb, 0); + bytestream2_put_le32(pb, s->pixel_type); + bytestream2_put_le32(pb, 0); + bytestream2_put_le32(pb, 1); + bytestream2_put_le32(pb, 1); + } + bytestream2_put_byte(pb, 0); + + bytestream2_put_buffer(pb, "compression\0compression\0", 24); + bytestream2_put_le32(pb, 1); + bytestream2_put_byte(pb, s->compression); + + bytestream2_put_buffer(pb, "dataWindow\0box2i\0", 17); + bytestream2_put_le32(pb, 16); + bytestream2_put_le32(pb, 0); + bytestream2_put_le32(pb, 0); + bytestream2_put_le32(pb, avctx->width - 1); + bytestream2_put_le32(pb, avctx->height - 1); + + bytestream2_put_buffer(pb, "displayWindow\0box2i\0", 20); + bytestream2_put_le32(pb, 16); + bytestream2_put_le32(pb, 0); + bytestream2_put_le32(pb, 0); + bytestream2_put_le32(pb, avctx->width - 1); + bytestream2_put_le32(pb, avctx->height - 1); + + bytestream2_put_buffer(pb, "lineOrder\0lineOrder\0", 20); + bytestream2_put_le32(pb, 1); + bytestream2_put_byte(pb, 0); + + bytestream2_put_buffer(pb, "screenWindowCenter\0v2f\0", 23); + bytestream2_put_le32(pb, 8); + bytestream2_put_le64(pb, 0); + + bytestream2_put_buffer(pb, "screenWindowWidth\0float\0", 24); + bytestream2_put_le32(pb, 4); + bytestream2_put_le32(pb, av_float2int(1.f)); + + if (avctx->sample_aspect_ratio.num && avctx->sample_aspect_ratio.den) { + bytestream2_put_buffer(pb, "pixelAspectRatio\0float\0", 23); + bytestream2_put_le32(pb, 4); + bytestream2_put_le32(pb, av_float2int(av_q2d(avctx->sample_aspect_ratio))); + } + + if (avctx->framerate.num && avctx->framerate.den) { + bytestream2_put_buffer(pb, "framesPerSecond\0rational\0", 25); + bytestream2_put_le32(pb, 8); + bytestream2_put_le32(pb, avctx->framerate.num); + bytestream2_put_le32(pb, avctx->framerate.den); + } + + bytestream2_put_buffer(pb, "gamma\0float\0", 12); + bytestream2_put_le32(pb, 4); + bytestream2_put_le32(pb, av_float2int(s->gamma)); + + bytestream2_put_buffer(pb, "writer\0string\0", 14); + bytestream2_put_le32(pb, 4); + bytestream2_put_buffer(pb, "lavc", 4); + bytestream2_put_byte(pb, 0); + + switch (s->compression) { + case EXR_RAW: + /* nothing to do */ + break; + case EXR_RLE: + encode_scanline_rle(s, frame); + break; + case EXR_ZIP16: + case EXR_ZIP1: + encode_scanline_zip(s, frame); + break; + default: + av_assert0(0); + } + + switch (s->compression) { + case EXR_RAW: + offset = bytestream2_tell_p(pb) + avctx->height * 8LL; + + if (s->pixel_type == EXR_FLOAT) { + + for (int y = 0; y < avctx->height; y++) { + bytestream2_put_le64(pb, offset); + offset += avctx->width * s->planes * 4 + 8; + } + + for (int y = 0; y < avctx->height; y++) { + bytestream2_put_le32(pb, y); + bytestream2_put_le32(pb, s->planes * avctx->width * 4); + for (int p = 0; p < s->planes; p++) { + int ch = s->ch_order[p]; + bytestream2_put_buffer(pb, frame->data[ch] + y * frame->linesize[ch], + avctx->width * 4); + } + } + } else { + for (int y = 0; y < avctx->height; y++) { + bytestream2_put_le64(pb, offset); + offset += avctx->width * s->planes * 2 + 8; + } + + for (int y = 0; y < avctx->height; y++) { + bytestream2_put_le32(pb, y); + bytestream2_put_le32(pb, s->planes * avctx->width * 2); + for (int p = 0; p < s->planes; p++) { + int ch = s->ch_order[p]; + uint32_t *src = (uint32_t *)(frame->data[ch] + y * frame->linesize[ch]); + + for (int x = 0; x < frame->width; x++) + bytestream2_put_le16(pb, float2half(src[x], s->basetable, s->shifttable)); + } + } + } + break; + case EXR_ZIP16: + case EXR_ZIP1: + case EXR_RLE: + offset = bytestream2_tell_p(pb) + s->nb_scanlines * 8LL; + + for (int y = 0; y < s->nb_scanlines; y++) { + EXRScanlineData *scanline = &s->scanline[y]; + + bytestream2_put_le64(pb, offset); + offset += scanline->actual_size + 8; + } + + for (int y = 0; y < s->nb_scanlines; y++) { + EXRScanlineData *scanline = &s->scanline[y]; + + bytestream2_put_le32(pb, y * s->scanline_height); + bytestream2_put_le32(pb, scanline->actual_size); + bytestream2_put_buffer(pb, scanline->compressed_data, + scanline->actual_size); + } + break; + default: + av_assert0(0); + } + + av_shrink_packet(pkt, bytestream2_tell_p(pb)); + + pkt->flags |= AV_PKT_FLAG_KEY; + *got_packet = 1; + + return 0; +} + +#define OFFSET(x) offsetof(EXRContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "compression", "set compression type", OFFSET(compression), AV_OPT_TYPE_INT, {.i64=0}, 0, EXR_NBCOMPR-1, VE, "compr" }, + { "none", "none", 0, AV_OPT_TYPE_CONST, {.i64=EXR_RAW}, 0, 0, VE, "compr" }, + { "rle" , "RLE", 0, AV_OPT_TYPE_CONST, {.i64=EXR_RLE}, 0, 0, VE, "compr" }, + { "zip1", "ZIP1", 0, AV_OPT_TYPE_CONST, {.i64=EXR_ZIP1}, 0, 0, VE, "compr" }, + { "zip16", "ZIP16", 0, AV_OPT_TYPE_CONST, {.i64=EXR_ZIP16}, 0, 0, VE, "compr" }, + { "format", "set pixel type", OFFSET(pixel_type), AV_OPT_TYPE_INT, {.i64=EXR_FLOAT}, EXR_HALF, EXR_UNKNOWN-1, VE, "pixel" }, + { "half" , NULL, 0, AV_OPT_TYPE_CONST, {.i64=EXR_HALF}, 0, 0, VE, "pixel" }, + { "float", NULL, 0, AV_OPT_TYPE_CONST, {.i64=EXR_FLOAT}, 0, 0, VE, "pixel" }, + { "gamma", "set gamma", OFFSET(gamma), AV_OPT_TYPE_FLOAT, {.dbl=1.f}, 0.001, FLT_MAX, VE }, + { NULL}, +}; + +static const AVClass exr_class = { + .class_name = "exr", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_exr_encoder = { + .name = "exr", + .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"), + .priv_data_size = sizeof(EXRContext), + .priv_class = &exr_class, + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_EXR, + .init = encode_init, + .encode2 = encode_frame, + .close = encode_close, + .capabilities = AV_CODEC_CAP_FRAME_THREADS, + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_GBRPF32, + AV_PIX_FMT_GBRAPF32, + AV_PIX_FMT_NONE }, +}; diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 1fead74b5..32c732f52 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -103,7 +103,6 @@ static int extract_extradata_av1(AVBSFContext *ctx, AVPacket *pkt, av_buffer_unref(&filtered_buf); return AVERROR(ENOMEM); } - memset(extradata + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); *data = extradata; *size = extradata_size; @@ -198,7 +197,6 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, av_buffer_unref(&filtered_buf); return AVERROR(ENOMEM); } - memset(extradata + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); *data = extradata; *size = extradata_size; @@ -254,7 +252,6 @@ static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, return AVERROR(ENOMEM); memcpy(*data, pkt->data, extradata_size); - memset(*data + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); *size = extradata_size; if (s->remove) { @@ -278,19 +275,16 @@ static int extract_extradata_mpeg12(AVBSFContext *ctx, AVPacket *pkt, if (state == 0x1B3) found = 1; else if (found && state != 0x1B5 && state < 0x200 && state >= 0x100) { - if (i > 3) { - *size = i - 3; - *data = av_malloc(*size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!*data) - return AVERROR(ENOMEM); + *size = i - 3; + *data = av_malloc(*size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!*data) + return AVERROR(ENOMEM); - memcpy(*data, pkt->data, *size); - memset(*data + *size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + memcpy(*data, pkt->data, *size); - if (s->remove) { - pkt->data += *size; - pkt->size -= *size; - } + if (s->remove) { + pkt->data += *size; + pkt->size -= *size; } break; } @@ -315,7 +309,6 @@ static int extract_extradata_mpeg4(AVBSFContext *ctx, AVPacket *pkt, return AVERROR(ENOMEM); memcpy(*data, pkt->data, *size); - memset(*data + *size, 0, AV_INPUT_BUFFER_PADDING_SIZE); if (s->remove) { pkt->data += *size; @@ -377,6 +370,7 @@ static int extract_extradata_filter(AVBSFContext *ctx, AVPacket *pkt) goto fail; if (extradata) { + memset(extradata + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, extradata, extradata_size); if (ret < 0) { diff --git a/libavcodec/fastaudio.c b/libavcodec/fastaudio.c new file mode 100644 index 000000000..9de42d213 --- /dev/null +++ b/libavcodec/fastaudio.c @@ -0,0 +1,202 @@ +/* + * MOFLEX Fast Audio decoder + * Copyright (c) 2015-2016 Florian Nouwt + * Copyright (c) 2017 Adib Surani + * Copyright (c) 2020 Paul B Mahol + * + * 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/intreadwrite.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" +#include "mathops.h" + +typedef struct ChannelItems { + float f[8]; + float last; +} ChannelItems; + +typedef struct FastAudioContext { + float table[8][64]; + + ChannelItems *ch; +} FastAudioContext; + +static av_cold int fastaudio_init(AVCodecContext *avctx) +{ + FastAudioContext *s = avctx->priv_data; + + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + + for (int i = 0; i < 8; i++) + s->table[0][i] = (i - 159.5f) / 160.f; + for (int i = 0; i < 11; i++) + s->table[0][i + 8] = (i - 37.5f) / 40.f; + for (int i = 0; i < 27; i++) + s->table[0][i + 8 + 11] = (i - 13.f) / 20.f; + for (int i = 0; i < 11; i++) + s->table[0][i + 8 + 11 + 27] = (i + 27.5f) / 40.f; + for (int i = 0; i < 7; i++) + s->table[0][i + 8 + 11 + 27 + 11] = (i + 152.5f) / 160.f; + + memcpy(s->table[1], s->table[0], sizeof(s->table[0])); + + for (int i = 0; i < 7; i++) + s->table[2][i] = (i - 33.5f) / 40.f; + for (int i = 0; i < 25; i++) + s->table[2][i + 7] = (i - 13.f) / 20.f; + + for (int i = 0; i < 32; i++) + s->table[3][i] = -s->table[2][31 - i]; + + for (int i = 0; i < 16; i++) + s->table[4][i] = i * 0.22f / 3.f - 0.6f; + + for (int i = 0; i < 16; i++) + s->table[5][i] = i * 0.20f / 3.f - 0.3f; + + for (int i = 0; i < 8; i++) + s->table[6][i] = i * 0.36f / 3.f - 0.4f; + + for (int i = 0; i < 8; i++) + s->table[7][i] = i * 0.34f / 3.f - 0.2f; + + s->ch = av_calloc(avctx->channels, sizeof(*s->ch)); + if (!s->ch) + return AVERROR(ENOMEM); + + return 0; +} + +static int read_bits(int bits, int *ppos, unsigned *src) +{ + int r, pos; + + pos = *ppos; + pos += bits; + r = src[(pos - 1) / 32] >> ((-pos) & 31); + *ppos = pos; + + return r & ((1 << bits) - 1); +} + +static const uint8_t bits[8] = { 6, 6, 5, 5, 4, 0, 3, 3, }; + +static void set_sample(int i, int j, int v, float *result, int *pads, float value) +{ + result[i * 64 + pads[i] + j * 3] = value * (2 * v - 7); +} + +static int fastaudio_decode(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *pkt) +{ + FastAudioContext *s = avctx->priv_data; + GetByteContext gb; + AVFrame *frame = data; + int subframes; + int ret; + + subframes = pkt->size / (40 * avctx->channels); + frame->nb_samples = subframes * 256; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + bytestream2_init(&gb, pkt->data, pkt->size); + + for (int subframe = 0; subframe < subframes; subframe++) { + for (int channel = 0; channel < avctx->channels; channel++) { + ChannelItems *ch = &s->ch[channel]; + float result[256] = { 0 }; + unsigned src[10]; + int inds[4], pads[4]; + float m[8]; + int pos = 0; + + for (int i = 0; i < 10; i++) + src[i] = bytestream2_get_le32(&gb); + + for (int i = 0; i < 8; i++) + m[7 - i] = s->table[i][read_bits(bits[i], &pos, src)]; + + for (int i = 0; i < 4; i++) + inds[3 - i] = read_bits(6, &pos, src); + + for (int i = 0; i < 4; i++) + pads[3 - i] = read_bits(2, &pos, src); + + for (int i = 0, index5 = 0; i < 4; i++) { + float value = av_int2float((inds[i] + 1) << 20) * powf(2.f, 116.f); + + for (int j = 0, tmp = 0; j < 21; j++) { + set_sample(i, j, j == 20 ? tmp / 2 : read_bits(3, &pos, src), result, pads, value); + if (j % 10 == 9) + tmp = 4 * tmp + read_bits(2, &pos, src); + if (j == 20) + index5 = FFMIN(2 * index5 + tmp % 2, 63); + } + + m[2] = s->table[5][index5]; + } + + for (int i = 0; i < 256; i++) { + float x = result[i]; + + for (int j = 0; j < 8; j++) { + x -= m[j] * ch->f[j]; + ch->f[j] += m[j] * x; + } + + memmove(&ch->f[0], &ch->f[1], sizeof(float) * 7); + ch->f[7] = x; + ch->last = x + ch->last * 0.86f; + result[i] = ch->last * 2.f; + } + + memcpy(frame->extended_data[channel] + 1024 * subframe, result, 256 * sizeof(float)); + } + } + + *got_frame = 1; + + return pkt->size; +} + +static av_cold int fastaudio_close(AVCodecContext *avctx) +{ + FastAudioContext *s = avctx->priv_data; + + av_freep(&s->ch); + + return 0; +} + +AVCodec ff_fastaudio_decoder = { + .name = "fastaudio", + .long_name = NULL_IF_CONFIG_SMALL("MobiClip FastAudio"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_FASTAUDIO, + .priv_data_size = sizeof(FastAudioContext), + .init = fastaudio_init, + .decode = fastaudio_decode, + .close = fastaudio_close, + .capabilities = AV_CODEC_CAP_DR1, + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, +}; diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index 2a1d2bc3f..3dd64cf73 100644 --- a/libavcodec/faxcompr.c +++ b/libavcodec/faxcompr.c @@ -24,6 +24,7 @@ * CCITT Fax Group 3 and 4 decompression * @author Konstantin Shishkov */ +#include "libavutil/thread.h" #include "avcodec.h" #include "get_bits.h" #include "put_bits.h" @@ -96,15 +97,12 @@ static const uint8_t ccitt_group3_2d_lens[11] = { static VLC ccitt_vlc[2], ccitt_group3_2d_vlc; -av_cold void ff_ccitt_unpack_init(void) +static av_cold void ccitt_unpack_init(void) { static VLC_TYPE code_table1[528][2]; static VLC_TYPE code_table2[648][2]; int i; - static int initialized = 0; - if (initialized) - return; ccitt_vlc[0].table = code_table1; ccitt_vlc[0].table_allocated = 528; ccitt_vlc[1].table = code_table2; @@ -119,7 +117,12 @@ av_cold void ff_ccitt_unpack_init(void) INIT_VLC_STATIC(&ccitt_group3_2d_vlc, 9, 11, ccitt_group3_2d_lens, 1, 1, ccitt_group3_2d_bits, 1, 1, 512); - initialized = 1; +} + +av_cold void ff_ccitt_unpack_init(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, ccitt_unpack_init); } static int decode_uncompressed(AVCodecContext *avctx, GetBitContext *gb, diff --git a/libavcodec/fft-internal.h b/libavcodec/fft-internal.h index 0a8f7d05c..3bd5a1123 100644 --- a/libavcodec/fft-internal.h +++ b/libavcodec/fft-internal.h @@ -34,7 +34,7 @@ (dim) = (are) * (bim) + (aim) * (bre); \ } while (0) -#else +#else /* FFT_FLOAT */ #define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits))) @@ -52,33 +52,6 @@ #define FIX15(a) av_clip(SCALE_FLOAT(a, 31), -2147483647, 2147483647) -#else /* FFT_FIXED_32 */ - -#include "fft.h" -#include "mathops.h" - -void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input); - -#define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767) - -#define sqrthalf ((int16_t)((1<<15)*M_SQRT1_2)) - -#define BF(x, y, a, b) do { \ - x = (a - b) >> 1; \ - y = (a + b) >> 1; \ - } while (0) - -#define CMULS(dre, dim, are, aim, bre, bim, sh) do { \ - (dre) = (MUL16(are, bre) - MUL16(aim, bim)) >> sh; \ - (dim) = (MUL16(are, bim) + MUL16(aim, bre)) >> sh; \ - } while (0) - -#define CMUL(dre, dim, are, aim, bre, bim) \ - CMULS(dre, dim, are, aim, bre, bim, 15) - -#define CMULL(dre, dim, are, aim, bre, bim) \ - CMULS(dre, dim, are, aim, bre, bim, 0) - #endif /* FFT_FIXED_32 */ #endif /* FFT_FLOAT */ diff --git a/libavcodec/fft.h b/libavcodec/fft.h index c858570a2..e03ca01ab 100644 --- a/libavcodec/fft.h +++ b/libavcodec/fft.h @@ -32,7 +32,8 @@ #include #include "config.h" -#include "libavutil/mem.h" + +#include "libavutil/mem_internal.h" #if FFT_FLOAT @@ -51,12 +52,6 @@ typedef float FFTDouble; typedef int32_t FFTSample; -#else /* FFT_FIXED_32 */ - -#define FFT_NAME(x) x ## _fixed - -typedef int16_t FFTSample; - #endif /* FFT_FIXED_32 */ typedef struct FFTComplex { @@ -107,7 +102,6 @@ struct FFTContext { void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input); void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); - void (*mdct_calcw)(struct FFTContext *s, FFTDouble *output, const FFTSample *input); enum fft_permutation_type fft_permutation; enum mdct_permutation_type mdct_permutation; uint32_t *revtab32; @@ -115,8 +109,16 @@ struct FFTContext { #if CONFIG_HARDCODED_TABLES #define COSTABLE_CONST const +#define ff_init_ff_cos_tabs(index) #else #define COSTABLE_CONST +#define ff_init_ff_cos_tabs FFT_NAME(ff_init_ff_cos_tabs) + +/** + * Initialize the cosine table in ff_cos_tabs[index] + * @param index index in ff_cos_tabs array of the table to initialize + */ +void ff_init_ff_cos_tabs(int index); #endif #define COSTABLE(size) \ @@ -138,14 +140,6 @@ extern COSTABLE(65536); extern COSTABLE(131072); extern COSTABLE_CONST FFTSample* const FFT_NAME(ff_cos_tabs)[18]; -#define ff_init_ff_cos_tabs FFT_NAME(ff_init_ff_cos_tabs) - -/** - * Initialize the cosine table in ff_cos_tabs[index] - * @param index index in ff_cos_tabs array of the table to initialize - */ -void ff_init_ff_cos_tabs(int index); - #define ff_fft_init FFT_NAME(ff_fft_init) #define ff_fft_end FFT_NAME(ff_fft_end) @@ -162,8 +156,6 @@ void ff_fft_init_arm(FFTContext *s); void ff_fft_init_mips(FFTContext *s); void ff_fft_init_ppc(FFTContext *s); -void ff_fft_fixed_init_arm(FFTContext *s); - void ff_fft_end(FFTContext *s); #define ff_mdct_init FFT_NAME(ff_mdct_init) diff --git a/libavcodec/fft_init_table.c b/libavcodec/fft_init_table.c index c488018f6..83e35ffb7 100644 --- a/libavcodec/fft_init_table.c +++ b/libavcodec/fft_init_table.c @@ -51,6 +51,8 @@ * @file * definitions and initialization of LUT table for FFT */ +#include "libavutil/thread.h" + #include "libavcodec/fft_table.h" const int32_t ff_w_tab_sr[MAX_FFT_SIZE/(4*16)] = { @@ -314,15 +316,29 @@ const int32_t ff_w_tab_sr[MAX_FFT_SIZE/(4*16)] = { uint16_t ff_fft_offsets_lut[21845]; -void ff_fft_lut_init(uint16_t *table, int off, int size, int *index) +static void 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); + fft_lut_init(table, off, size >> 1, index); + fft_lut_init(table, off + (size >> 1), size >> 2, index); + fft_lut_init(table, off + 3 * (size >> 2), size >> 2, index); } } + +static void fft_lut_init_start(void) +{ + int n = 0; + + fft_lut_init(ff_fft_offsets_lut, 0, 1 << 17, &n); +} + +void ff_fft_lut_init(void) +{ + static AVOnce init_once = AV_ONCE_INIT; + + ff_thread_once(&init_once, fft_lut_init_start); +} diff --git a/libavcodec/fft_table.h b/libavcodec/fft_table.h index ed0a6588b..09df49f2b 100644 --- a/libavcodec/fft_table.h +++ b/libavcodec/fft_table.h @@ -61,6 +61,6 @@ extern const int32_t ff_w_tab_sr[]; extern uint16_t ff_fft_offsets_lut[]; -void ff_fft_lut_init(uint16_t *table, int off, int size, int *index); +void ff_fft_lut_init(void); #endif /* AVCODEC_FFT_TABLE_H */ diff --git a/libavcodec/fft_template.c b/libavcodec/fft_template.c index 20a62e429..3012372a7 100644 --- a/libavcodec/fft_template.c +++ b/libavcodec/fft_template.c @@ -35,13 +35,6 @@ #if FFT_FIXED_32 #include "fft_table.h" - -static void av_cold fft_lut_init(void) -{ - int n = 0; - ff_fft_lut_init(ff_fft_offsets_lut, 0, 1 << 17, &n); -} - #else /* FFT_FIXED_32 */ /* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */ @@ -120,6 +113,10 @@ static CosTabsInitOnce cos_tabs_init_once[] = { { init_ff_cos_tabs_131072, AV_ONCE_INIT }, }; +av_cold void ff_init_ff_cos_tabs(int index) +{ + ff_thread_once(&cos_tabs_init_once[index].control, cos_tabs_init_once[index].func); +} #endif COSTABLE_CONST FFTSample * const FFT_NAME(ff_cos_tabs)[] = { NULL, NULL, NULL, NULL, @@ -155,12 +152,6 @@ static int split_radix_permutation(int i, int n, int inverse) else return split_radix_permutation(i, m, inverse)*4 - 1; } -av_cold void ff_init_ff_cos_tabs(int index) -{ -#if (!CONFIG_HARDCODED_TABLES) && (!FFT_FIXED_32) - ff_thread_once(&cos_tabs_init_once[index].control, cos_tabs_init_once[index].func); -#endif -} static const int avx_tab[] = { 0, 4, 1, 5, 8, 12, 9, 13, 2, 6, 3, 7, 10, 14, 11, 15 @@ -236,21 +227,14 @@ av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) #endif #if FFT_FIXED_32 - { - static AVOnce control = AV_ONCE_INIT; - ff_thread_once(&control, fft_lut_init); - } + ff_fft_lut_init(); #else /* FFT_FIXED_32 */ #if FFT_FLOAT if (ARCH_AARCH64) ff_fft_init_aarch64(s); if (ARCH_ARM) ff_fft_init_arm(s); if (ARCH_PPC) ff_fft_init_ppc(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); @@ -258,7 +242,7 @@ av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) #endif /* FFT_FIXED_32 */ - if (s->fft_permutation == FF_FFT_PERM_AVX) { + if (ARCH_X86 && FFT_FLOAT && s->fft_permutation == FF_FFT_PERM_AVX) { fft_perm_avx(s); } else { #define PROCESS_FFT_PERM_SWAP_LSBS(num) do {\ diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index 93cec1424..1c580c3b4 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -115,12 +115,11 @@ av_cold int ff_ffv1_init_slices_state(FFV1Context *f) av_cold int ff_ffv1_init_slice_contexts(FFV1Context *f) { - int i; + int i, max_slice_count = f->num_h_slices * f->num_v_slices; - f->max_slice_count = f->num_h_slices * f->num_v_slices; - av_assert0(f->max_slice_count > 0); + av_assert0(max_slice_count > 0); - for (i = 0; i < f->max_slice_count; i++) { + for (i = 0; i < max_slice_count;) { int sx = i % f->num_h_slices; int sy = i / f->num_h_slices; int sxs = f->avctx->width * sx / f->num_h_slices; @@ -132,7 +131,7 @@ av_cold int ff_ffv1_init_slice_contexts(FFV1Context *f) if (!fs) goto memfail; - f->slice_context[i] = fs; + f->slice_context[i++] = fs; memcpy(fs, f, sizeof(*fs)); memset(fs->rc_stat2, 0, sizeof(fs->rc_stat2)); @@ -145,21 +144,14 @@ av_cold int ff_ffv1_init_slice_contexts(FFV1Context *f) sizeof(*fs->sample_buffer)); fs->sample_buffer32 = av_malloc_array((fs->width + 6), 3 * MAX_PLANES * sizeof(*fs->sample_buffer32)); - if (!fs->sample_buffer || !fs->sample_buffer32) { - av_freep(&fs->sample_buffer); - av_freep(&fs->sample_buffer32); - av_freep(&f->slice_context[i]); + if (!fs->sample_buffer || !fs->sample_buffer32) goto memfail; - } } + f->max_slice_count = max_slice_count; return 0; memfail: - while(--i >= 0) { - av_freep(&f->slice_context[i]->sample_buffer); - av_freep(&f->slice_context[i]->sample_buffer32); - av_freep(&f->slice_context[i]); - } + f->max_slice_count = i; return AVERROR(ENOMEM); } diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 0a3f42549..8516fef5d 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -888,8 +888,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac int trailer = 3 + 5*!!f->ec; int v; - if (i || f->version > 2) v = AV_RB24(buf_p-trailer) + trailer; - else v = buf_p - c->bytestream_start; + if (i || f->version > 2) { + if (trailer > buf_p - buf) v = INT_MAX; + else v = AV_RB24(buf_p-trailer) + trailer; + } else v = buf_p - c->bytestream_start; if (buf_p - c->bytestream_start < v) { av_log(avctx, AV_LOG_ERROR, "Slice pointer chain broken\n"); ff_thread_report_progress(&f->picture, INT_MAX, 0); diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 97dc15eac..611b250e9 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -1354,4 +1354,5 @@ AVCodec ff_ffv1_encoder = { .defaults = ffv1_defaults, #endif .priv_class = &ffv1_class, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c index d92bb38c4..3f982d07c 100644 --- a/libavcodec/ffwavesynth.c +++ b/libavcodec/ffwavesynth.c @@ -188,7 +188,7 @@ static uint64_t frac64(uint64_t a, uint64_t b) static uint64_t phi_at(struct ws_interval *in, int64_t ts) { - uint64_t dt = ts - in->ts_start; + uint64_t dt = ts - (uint64_t)in->ts_start; uint64_t dt2 = dt & 1 ? /* dt * (dt - 1) / 2 without overflow */ dt * ((dt - 1) >> 1) : (dt >> 1) * (dt - 1); return in->phi0 + dt * in->dphi0 + dt2 * in->ddphi; @@ -323,13 +323,11 @@ static av_cold int wavesynth_init(AVCodecContext *avc) r = wavesynth_parse_extradata(avc); if (r < 0) { av_log(avc, AV_LOG_ERROR, "Invalid intervals definitions.\n"); - goto fail; + return r; } ws->sin = av_malloc(sizeof(*ws->sin) << SIN_BITS); - if (!ws->sin) { - r = AVERROR(ENOMEM); - goto fail; - } + if (!ws->sin) + return AVERROR(ENOMEM); for (i = 0; i < 1 << SIN_BITS; i++) ws->sin[i] = floor(32767 * sin(2 * M_PI * i / (1 << SIN_BITS))); ws->dither_state = MKTAG('D','I','T','H'); @@ -340,11 +338,6 @@ static av_cold int wavesynth_init(AVCodecContext *avc) wavesynth_seek(ws, 0); avc->sample_fmt = AV_SAMPLE_FMT_S16; return 0; - -fail: - av_freep(&ws->inter); - av_freep(&ws->sin); - return r; } static void wavesynth_synth_sample(struct wavesynth_context *ws, int64_t ts, @@ -476,4 +469,5 @@ AVCodec ff_ffwavesynth_decoder = { .close = wavesynth_close, .decode = wavesynth_decode, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/fic.c b/libavcodec/fic.c index 95baaedaa..ef5f3f44d 100644 --- a/libavcodec/fic.c +++ b/libavcodec/fic.c @@ -22,6 +22,7 @@ */ #include "libavutil/common.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "avcodec.h" #include "internal.h" diff --git a/libavcodec/filter_units_bsf.c b/libavcodec/filter_units_bsf.c index 700dc06ef..354594ac5 100644 --- a/libavcodec/filter_units_bsf.c +++ b/libavcodec/filter_units_bsf.c @@ -125,7 +125,7 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt) } if (ctx->mode == REMOVE ? j < ctx->nb_types : j >= ctx->nb_types) - ff_cbs_delete_unit(ctx->cbc, frag, i); + ff_cbs_delete_unit(frag, i); } if (frag->nb_units == 0) { @@ -143,7 +143,7 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt) fail: if (err < 0) av_packet_unref(pkt); - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); return err; } @@ -199,7 +199,7 @@ static int filter_units_init(AVBSFContext *bsf) av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); } - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); } return err; @@ -211,7 +211,7 @@ static void filter_units_close(AVBSFContext *bsf) av_freep(&ctx->type_list); - ff_cbs_fragment_free(ctx->cbc, &ctx->fragment); + ff_cbs_fragment_free(&ctx->fragment); ff_cbs_close(&ctx->cbc); } diff --git a/libavcodec/fitsdec.c b/libavcodec/fitsdec.c index 32a79cdd0..802aa5b50 100644 --- a/libavcodec/fitsdec.c +++ b/libavcodec/fitsdec.c @@ -63,7 +63,7 @@ static int fill_data_min_max(const uint8_t *ptr8, FITSHeader *header, const uint int i, j; header->data_min = DBL_MAX; - header->data_max = DBL_MIN; + header->data_max = -DBL_MAX; switch (header->bitpix) { #define CASE_N(a, t, rd) \ case a: \ diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index fb27e8e6d..9e55bc136 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -262,7 +262,7 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order) } else { int real_limit = tmp ? (INT_MAX >> tmp) + 2 : INT_MAX; for (; i < samples; i++) { - int v = get_sr_golomb_flac(&gb, tmp, real_limit, 0); + int v = get_sr_golomb_flac(&gb, tmp, real_limit, 1); if (v == 0x80000000){ av_log(s->avctx, AV_LOG_ERROR, "invalid residual\n"); return AVERROR_INVALIDDATA; @@ -654,10 +654,10 @@ static const AVOption options[] = { }; static const AVClass flac_decoder_class = { - "FLAC decoder", - av_default_item_name, - options, - LIBAVUTIL_VERSION_INT, + .class_name = "FLAC decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, }; AVCodec ff_flac_decoder = { @@ -669,7 +669,9 @@ AVCodec ff_flac_decoder = { .init = flac_decode_init, .close = flac_decode_close, .decode = flac_decode_frame, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1 | + AV_CODEC_CAP_FRAME_THREADS, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32, diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index 8e7dbc52b..a2aa4bdf1 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -1513,4 +1513,5 @@ AVCodec ff_flac_encoder = { AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, .priv_class = &flac_encoder_class, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c index f55cb0fee..9481f80f0 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -179,7 +179,7 @@ static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size) return 0; } -static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, +static int flashsv_decode_block(AVCodecContext *avctx, const AVPacket *avpkt, GetBitContext *gb, int block_size, int width, int height, int x_pos, int y_pos, int blk_idx) diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c index 65db11269..00aedf079 100644 --- a/libavcodec/flashsv2enc.c +++ b/libavcodec/flashsv2enc.c @@ -142,6 +142,7 @@ static void init_blocks(FlashSV2Context * s, Block * blocks, { int row, col; Block *b; + memset(blocks, 0, s->cols * s->rows * sizeof(*blocks)); for (col = 0; col < s->cols; col++) { for (row = 0; row < s->rows; row++) { b = blocks + (col + row * s->cols); @@ -158,7 +159,7 @@ static void init_blocks(FlashSV2Context * s, Block * blocks, b->enc = encbuf; b->data = databuf; encbuf += b->width * b->height * 3; - databuf += !databuf ? 0 : b->width * b->height * 6; + databuf = databuf ? databuf + b->width * b->height * 6 : NULL; } } } @@ -174,9 +175,37 @@ static void reset_stats(FlashSV2Context * s) #endif } +static int update_block_dimensions(FlashSV2Context *s, int block_width, int block_height) +{ + s->block_width = block_width; + s->block_height = block_height; + s->rows = (s->image_height + s->block_height - 1) / s->block_height; + s->cols = (s->image_width + s->block_width - 1) / s->block_width; + if (s->rows * s->cols > s->blocks_size / sizeof(Block)) { + s->frame_blocks = av_realloc_array(s->frame_blocks, s->rows, s->cols * sizeof(Block)); + s->key_blocks = av_realloc_array(s->key_blocks, s->cols, s->rows * sizeof(Block)); + if (!s->frame_blocks || !s->key_blocks) { + av_log(s->avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); + return AVERROR(ENOMEM); + } + s->blocks_size = s->rows * s->cols * sizeof(Block); + } + init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer); + init_blocks(s, s->key_blocks, s->keybuffer, 0); + + av_fast_malloc(&s->blockbuffer, &s->blockbuffer_size, block_width * block_height * 6); + if (!s->blockbuffer) { + av_log(s->avctx, AV_LOG_ERROR, "Could not allocate block buffer.\n"); + return AVERROR(ENOMEM); + } + return 0; +} + + static av_cold int flashsv2_encode_init(AVCodecContext * avctx) { FlashSV2Context *s = avctx->priv_data; + int ret; s->avctx = avctx; @@ -186,23 +215,23 @@ static av_cold int flashsv2_encode_init(AVCodecContext * avctx) if (s->comp < 0 || s->comp > 9) { av_log(avctx, AV_LOG_ERROR, "Compression level should be 0-9, not %d\n", s->comp); - return -1; + return AVERROR(EINVAL); } if ((avctx->width > 4095) || (avctx->height > 4095)) { av_log(avctx, AV_LOG_ERROR, "Input dimensions too large, input must be max 4095x4095 !\n"); - return -1; + return AVERROR(EINVAL); } if ((avctx->width < 16) || (avctx->height < 16)) { av_log(avctx, AV_LOG_ERROR, "Input dimensions too small, input must be at least 16x16 !\n"); - return -1; + return AVERROR(EINVAL); } - if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) - return -1; + if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) + return ret; s->last_key_frame = 0; @@ -210,33 +239,19 @@ static av_cold int flashsv2_encode_init(AVCodecContext * avctx) s->image_width = avctx->width; s->image_height = avctx->height; - s->block_width = (s->image_width / 12) & ~15; - s->block_height = (s->image_height / 12) & ~15; - - if(!s->block_width) - s->block_width = 1; - if(!s->block_height) - s->block_height = 1; - - s->rows = (s->image_height + s->block_height - 1) / s->block_height; - s->cols = (s->image_width + s->block_width - 1) / s->block_width; - s->frame_size = s->image_width * s->image_height * 3; - s->blocks_size = s->rows * s->cols * sizeof(Block); s->encbuffer = av_mallocz(s->frame_size); s->keybuffer = av_mallocz(s->frame_size); s->databuffer = av_mallocz(s->frame_size * 6); s->current_frame = av_mallocz(s->frame_size); s->key_frame = av_mallocz(s->frame_size); - s->frame_blocks = av_mallocz(s->blocks_size); - s->key_blocks = av_mallocz(s->blocks_size); + if (!s->encbuffer || !s->keybuffer || !s->databuffer + || !s->current_frame || !s->key_frame) { + av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); + return AVERROR(ENOMEM); + } - s->blockbuffer = NULL; - s->blockbuffer_size = 0; - - init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer); - init_blocks(s, s->key_blocks, s->keybuffer, 0); reset_stats(s); #ifndef FLASHSV2_DUMB s->total_bits = 1; @@ -245,15 +260,7 @@ static av_cold int flashsv2_encode_init(AVCodecContext * avctx) s->use_custom_palette = 0; s->palette_type = -1; // so that the palette will be generated in reconfigure_at_keyframe - if (!s->encbuffer || !s->keybuffer || !s->databuffer - || !s->current_frame || !s->key_frame || !s->key_blocks - || !s->frame_blocks) { - av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); - cleanup(s); - return -1; - } - - return 0; + return update_block_dimensions(s, 64, 64); } static int new_key_frame(FlashSV2Context * s) @@ -801,29 +808,10 @@ static int reconfigure_at_keyframe(FlashSV2Context * s, const uint8_t * image, int block_width = optimum_block_width (s); int block_height = optimum_block_height(s); - s->rows = (s->image_height + block_height - 1) / block_height; - s->cols = (s->image_width + block_width - 1) / block_width; - if (block_width != s->block_width || block_height != s->block_height) { - s->block_width = block_width; - s->block_height = block_height; - if (s->rows * s->cols > s->blocks_size / sizeof(Block)) { - s->frame_blocks = av_realloc_array(s->frame_blocks, s->rows, s->cols * sizeof(Block)); - s->key_blocks = av_realloc_array(s->key_blocks, s->cols, s->rows * sizeof(Block)); - if (!s->frame_blocks || !s->key_blocks) { - av_log(s->avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); - return -1; - } - s->blocks_size = s->rows * s->cols * sizeof(Block); - } - init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer); - init_blocks(s, s->key_blocks, s->keybuffer, 0); - - av_fast_malloc(&s->blockbuffer, &s->blockbuffer_size, block_width * block_height * 6); - if (!s->blockbuffer) { - av_log(s->avctx, AV_LOG_ERROR, "Could not allocate block buffer.\n"); - return AVERROR(ENOMEM); - } + res = update_block_dimensions(s, block_width, block_height); + if (res < 0) + return res; } s->use15_7 = optimum_use15_7(s); @@ -919,4 +907,5 @@ 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 }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c index f7f98efde..95ae98844 100644 --- a/libavcodec/flashsvenc.c +++ b/libavcodec/flashsvenc.c @@ -59,11 +59,10 @@ typedef struct FlashSVContext { uint8_t *previous_frame; int image_width, image_height; int block_width, block_height; - uint8_t *tmpblock; uint8_t *encbuffer; int block_size; - z_stream zstream; int last_key_frame; + uint8_t tmpblock[3 * 256 * 256]; } FlashSVContext; static int copy_region_enc(uint8_t *sptr, uint8_t *dptr, int dx, int dy, @@ -92,11 +91,8 @@ static av_cold int flashsv_encode_end(AVCodecContext *avctx) { FlashSVContext *s = avctx->priv_data; - deflateEnd(&s->zstream); - av_freep(&s->encbuffer); av_freep(&s->previous_frame); - av_freep(&s->tmpblock); return 0; } @@ -113,18 +109,14 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - // Needed if zlib unused or init aborted before deflateInit - memset(&s->zstream, 0, sizeof(z_stream)); - s->last_key_frame = 0; s->image_width = avctx->width; s->image_height = avctx->height; - s->tmpblock = av_mallocz(3 * 256 * 256); s->encbuffer = av_mallocz(s->image_width * s->image_height * 3); - if (!s->tmpblock || !s->encbuffer) { + if (!s->encbuffer) { av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); return AVERROR(ENOMEM); } @@ -182,7 +174,6 @@ static int encode_bitstream(FlashSVContext *s, const AVFrame *p, uint8_t *buf, ret = compress2(ptr + 2, &zsize, s->tmpblock, 3 * cur_blk_width * cur_blk_height, 9); - //ret = deflateReset(&s->zstream); if (ret != Z_OK) av_log(s->avctx, AV_LOG_ERROR, "error while compressing block %dx%d\n", i, j); diff --git a/libavcodec/float2half.h b/libavcodec/float2half.h new file mode 100644 index 000000000..e05125088 --- /dev/null +++ b/libavcodec/float2half.h @@ -0,0 +1,67 @@ +/* + * 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_FLOAT2HALF_H +#define AVCODEC_FLOAT2HALF_H + +#include + +static void float2half_tables(uint16_t *basetable, uint8_t *shifttable) +{ + for (int i = 0; i < 256; i++) { + int e = i - 127; + + if (e < -24) { // Very small numbers map to zero + basetable[i|0x000] = 0x0000; + basetable[i|0x100] = 0x8000; + shifttable[i|0x000] = 24; + shifttable[i|0x100] = 24; + } else if (e < -14) { // Small numbers map to denorms + basetable[i|0x000] = (0x0400>>(-e-14)); + basetable[i|0x100] = (0x0400>>(-e-14)) | 0x8000; + shifttable[i|0x000] = -e-1; + shifttable[i|0x100] = -e-1; + } else if (e <= 15) { // Normal numbers just lose precision + basetable[i|0x000] = ((e + 15) << 10); + basetable[i|0x100] = ((e + 15) << 10) | 0x8000; + shifttable[i|0x000] = 13; + shifttable[i|0x100] = 13; + } else if (e < 128) { // Large numbers map to Infinity + basetable[i|0x000] = 0x7C00; + basetable[i|0x100] = 0xFC00; + shifttable[i|0x000] = 24; + shifttable[i|0x100] = 24; + } else { // Infinity and NaN's stay Infinity and NaN's + basetable[i|0x000] = 0x7C00; + basetable[i|0x100] = 0xFC00; + shifttable[i|0x000] = 13; + shifttable[i|0x100] = 13; + } + } +} + +static uint16_t float2half(uint32_t f, uint16_t *basetable, uint8_t *shifttable) +{ + uint16_t h; + + h = basetable[(f >> 23) & 0x1ff] + ((f & 0x007fffff) >> shifttable[(f >> 23) & 0x1ff]); + + return h; +} + +#endif /* AVCODEC_FLOAT2HALF_H */ diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c index c1227277b..b85e4667c 100644 --- a/libavcodec/flvenc.c +++ b/libavcodec/flvenc.c @@ -28,7 +28,7 @@ void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number) { int format; - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); put_bits(&s->pb, 17, 1); /* 0: H.263 escape codes 1: 11-bit escape codes */ diff --git a/libavcodec/fmvc.c b/libavcodec/fmvc.c index 5bee96a18..3701b0849 100644 --- a/libavcodec/fmvc.c +++ b/libavcodec/fmvc.c @@ -440,6 +440,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, memcpy(dst, src, avctx->width * s->bpp); dst -= frame->linesize[0]; src += s->stride * 4; + if (bytestream2_tell_p(pb) < y*s->stride * 4) + break; } } else { unsigned block, nb_blocks; diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index 83229f620..778317d60 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -22,7 +22,6 @@ #include "frame_thread_encoder.h" -#include "libavutil/fifo.h" #include "libavutil/avassert.h" #include "libavutil/imgutils.h" #include "libavutil/opt.h" @@ -32,27 +31,32 @@ #include "thread.h" #define MAX_THREADS 64 -#define BUFFER_SIZE (2*MAX_THREADS) +/* There can be as many as MAX_THREADS + 1 outstanding tasks. + * An additional + 1 is needed so that one can distinguish + * the case of zero and MAX_THREADS + 1 outstanding tasks modulo + * the number of buffers. */ +#define BUFFER_SIZE (MAX_THREADS + 2) typedef struct{ - void *indata; - void *outdata; - int64_t return_code; - unsigned index; + AVFrame *indata; + AVPacket *outdata; + int return_code; + int finished; } Task; typedef struct{ AVCodecContext *parent_avctx; pthread_mutex_t buffer_mutex; - AVFifoBuffer *task_fifo; - pthread_mutex_t task_fifo_mutex; + pthread_mutex_t task_fifo_mutex; /* Used to guard (next_)task_index */ pthread_cond_t task_fifo_cond; - Task finished_tasks[BUFFER_SIZE]; - pthread_mutex_t finished_task_mutex; + unsigned max_tasks; + Task tasks[BUFFER_SIZE]; + pthread_mutex_t finished_task_mutex; /* Guards tasks[i].finished */ pthread_cond_t finished_task_cond; + unsigned next_task_index; unsigned task_index; unsigned finished_task_index; @@ -63,28 +67,32 @@ typedef struct{ static void * attribute_align_arg worker(void *v){ AVCodecContext *avctx = v; ThreadContext *c = avctx->internal->frame_thread_encoder; - AVPacket *pkt = NULL; while (!atomic_load(&c->exit)) { int got_packet = 0, ret; + AVPacket *pkt; AVFrame *frame; - Task task; - - if(!pkt) pkt = av_packet_alloc(); - if(!pkt) continue; - av_init_packet(pkt); + Task *task; + unsigned task_index; pthread_mutex_lock(&c->task_fifo_mutex); - while (av_fifo_size(c->task_fifo) <= 0 || atomic_load(&c->exit)) { + while (c->next_task_index == c->task_index || atomic_load(&c->exit)) { if (atomic_load(&c->exit)) { pthread_mutex_unlock(&c->task_fifo_mutex); goto end; } pthread_cond_wait(&c->task_fifo_cond, &c->task_fifo_mutex); } - av_fifo_generic_read(c->task_fifo, &task, sizeof(task), NULL); + task_index = c->next_task_index; + c->next_task_index = (c->next_task_index + 1) % c->max_tasks; pthread_mutex_unlock(&c->task_fifo_mutex); - frame = task.indata; + /* The main thread ensures that any two outstanding tasks have + * different indices, ergo each worker thread owns its element + * of c->tasks with the exception of finished, which is shared + * with the main thread and guarded by finished_task_mutex. */ + task = &c->tasks[task_index]; + frame = task->indata; + pkt = task->outdata; ret = avctx->codec->encode2(avctx, pkt, frame, &got_packet); if(got_packet) { @@ -99,15 +107,13 @@ static void * attribute_align_arg worker(void *v){ pthread_mutex_lock(&c->buffer_mutex); av_frame_unref(frame); pthread_mutex_unlock(&c->buffer_mutex); - av_frame_free(&frame); pthread_mutex_lock(&c->finished_task_mutex); - c->finished_tasks[task.index].outdata = pkt; pkt = NULL; - c->finished_tasks[task.index].return_code = ret; + task->return_code = ret; + task->finished = 1; pthread_cond_signal(&c->finished_task_cond); pthread_mutex_unlock(&c->finished_task_mutex); } end: - av_free(pkt); pthread_mutex_lock(&c->buffer_mutex); avcodec_close(avctx); pthread_mutex_unlock(&c->buffer_mutex); @@ -181,10 +187,6 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ c->parent_avctx = avctx; - c->task_fifo = av_fifo_alloc_array(BUFFER_SIZE, sizeof(Task)); - if(!c->task_fifo) - goto fail; - pthread_mutex_init(&c->task_fifo_mutex, NULL); pthread_mutex_init(&c->finished_task_mutex, NULL); pthread_mutex_init(&c->buffer_mutex, NULL); @@ -192,6 +194,13 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ pthread_cond_init(&c->finished_task_cond, NULL); atomic_init(&c->exit, 0); + c->max_tasks = avctx->thread_count + 2; + for (unsigned i = 0; i < c->max_tasks; i++) { + if (!(c->tasks[i].indata = av_frame_alloc()) || + !(c->tasks[i].outdata = av_packet_alloc())) + goto fail; + } + for(i=0; ithread_count ; i++){ AVDictionary *tmp = NULL; int ret; @@ -253,21 +262,9 @@ void ff_frame_thread_encoder_free(AVCodecContext *avctx){ pthread_join(c->worker[i], NULL); } - while (av_fifo_size(c->task_fifo) > 0) { - Task task; - AVFrame *frame; - av_fifo_generic_read(c->task_fifo, &task, sizeof(task), NULL); - frame = task.indata; - av_frame_free(&frame); - task.indata = NULL; - } - - for (i=0; ifinished_tasks[i].outdata != NULL) { - AVPacket *pkt = c->finished_tasks[i].outdata; - av_packet_free(&pkt); - c->finished_tasks[i].outdata = NULL; - } + for (unsigned i = 0; i < c->max_tasks; i++) { + av_frame_free(&c->tasks[i].indata); + av_packet_free(&c->tasks[i].outdata); } pthread_mutex_destroy(&c->task_fifo_mutex); @@ -275,55 +272,47 @@ void ff_frame_thread_encoder_free(AVCodecContext *avctx){ pthread_mutex_destroy(&c->buffer_mutex); pthread_cond_destroy(&c->task_fifo_cond); pthread_cond_destroy(&c->finished_task_cond); - av_fifo_freep(&c->task_fifo); av_freep(&avctx->internal->frame_thread_encoder); } -int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr){ +int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + AVFrame *frame, int *got_packet_ptr) +{ ThreadContext *c = avctx->internal->frame_thread_encoder; - Task task; - int ret; + Task *outtask; av_assert1(!*got_packet_ptr); if(frame){ - AVFrame *new = av_frame_alloc(); - if(!new) - return AVERROR(ENOMEM); - ret = av_frame_ref(new, frame); - if(ret < 0) { - av_frame_free(&new); - return ret; - } + av_frame_move_ref(c->tasks[c->task_index].indata, frame); - task.index = c->task_index; - task.indata = (void*)new; pthread_mutex_lock(&c->task_fifo_mutex); - av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL); + c->task_index = (c->task_index + 1) % c->max_tasks; pthread_cond_signal(&c->task_fifo_cond); pthread_mutex_unlock(&c->task_fifo_mutex); - - c->task_index = (c->task_index+1) % BUFFER_SIZE; } + outtask = &c->tasks[c->finished_task_index]; pthread_mutex_lock(&c->finished_task_mutex); + /* The access to task_index in the following code is ok, + * because it is only ever changed by the main thread. */ if (c->task_index == c->finished_task_index || - (frame && !c->finished_tasks[c->finished_task_index].outdata && - (c->task_index - c->finished_task_index) % BUFFER_SIZE <= avctx->thread_count)) { + (frame && !outtask->finished && + (c->task_index - c->finished_task_index + c->max_tasks) % c->max_tasks <= avctx->thread_count)) { pthread_mutex_unlock(&c->finished_task_mutex); return 0; } - - while (!c->finished_tasks[c->finished_task_index].outdata) { + while (!outtask->finished) { pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex); } - task = c->finished_tasks[c->finished_task_index]; - *pkt = *(AVPacket*)(task.outdata); + pthread_mutex_unlock(&c->finished_task_mutex); + /* We now own outtask completely: No worker thread touches it any more, + * because there is no outstanding task with this index. */ + outtask->finished = 0; + av_packet_move_ref(pkt, outtask->outdata); if(pkt->data) *got_packet_ptr = 1; - av_freep(&c->finished_tasks[c->finished_task_index].outdata); - c->finished_task_index = (c->finished_task_index+1) % BUFFER_SIZE; - pthread_mutex_unlock(&c->finished_task_mutex); + c->finished_task_index = (c->finished_task_index + 1) % c->max_tasks; - return task.return_code; + return outtask->return_code; } diff --git a/libavcodec/frame_thread_encoder.h b/libavcodec/frame_thread_encoder.h index 1f79553f2..c400d6b32 100644 --- a/libavcodec/frame_thread_encoder.h +++ b/libavcodec/frame_thread_encoder.h @@ -25,6 +25,7 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options); void ff_frame_thread_encoder_free(AVCodecContext *avctx); -int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr); +int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + AVFrame *frame, int *got_packet_ptr); #endif /* AVCODEC_FRAME_THREAD_ENCODER_H */ diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 7a7673f73..8d01b44f1 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -31,6 +31,10 @@ * Version 2 files support by Konstantin Shishkov */ +#include "config.h" + +#define CACHED_BITSTREAM_READER HAVE_FAST_64BIT +#define UNCHECKED_BITSTREAM_READER 1 #include "avcodec.h" #include "get_bits.h" #include "huffman.h" diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 7ef275c9f..da910c1e5 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -30,6 +30,7 @@ #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "blockdsp.h" @@ -40,6 +41,7 @@ #include "internal.h" #include "jpegtables.h" #include "mjpeg.h" +#include "mjpegdec.h" #define EPIC_PIX_STACK_SIZE 1024 #define EPIC_PIX_STACK_MAX (EPIC_PIX_STACK_SIZE - 1) @@ -158,45 +160,24 @@ typedef struct G2MContext { int cursor_hot_x, cursor_hot_y; } G2MContext; -static av_cold int build_vlc(VLC *vlc, const uint8_t *bits_table, - const uint8_t *val_table, int nb_codes, - int is_ac) -{ - uint8_t huff_size[256] = { 0 }; - uint16_t huff_code[256]; - uint16_t huff_sym[256]; - int i; - - ff_mjpeg_build_huffman_codes(huff_size, huff_code, bits_table, val_table); - - for (i = 0; i < 256; i++) - huff_sym[i] = i + 16 * is_ac; - - if (is_ac) - huff_sym[0] = 16 * 256; - - return ff_init_vlc_sparse(vlc, 9, nb_codes, huff_size, 1, 1, - huff_code, 2, 2, huff_sym, 2, 2, 0); -} - static av_cold int jpg_init(AVCodecContext *avctx, JPGContext *c) { int ret; - ret = build_vlc(&c->dc_vlc[0], avpriv_mjpeg_bits_dc_luminance, - avpriv_mjpeg_val_dc, 12, 0); + ret = ff_mjpeg_build_vlc(&c->dc_vlc[0], avpriv_mjpeg_bits_dc_luminance, + avpriv_mjpeg_val_dc, 0, avctx); if (ret) return ret; - ret = build_vlc(&c->dc_vlc[1], avpriv_mjpeg_bits_dc_chrominance, - avpriv_mjpeg_val_dc, 12, 0); + ret = ff_mjpeg_build_vlc(&c->dc_vlc[1], avpriv_mjpeg_bits_dc_chrominance, + avpriv_mjpeg_val_dc, 0, avctx); if (ret) return ret; - ret = build_vlc(&c->ac_vlc[0], avpriv_mjpeg_bits_ac_luminance, - avpriv_mjpeg_val_ac_luminance, 251, 1); + ret = ff_mjpeg_build_vlc(&c->ac_vlc[0], avpriv_mjpeg_bits_ac_luminance, + avpriv_mjpeg_val_ac_luminance, 1, avctx); if (ret) return ret; - ret = build_vlc(&c->ac_vlc[1], avpriv_mjpeg_bits_ac_chrominance, - avpriv_mjpeg_val_ac_chrominance, 251, 1); + ret = ff_mjpeg_build_vlc(&c->ac_vlc[1], avpriv_mjpeg_bits_ac_chrominance, + avpriv_mjpeg_val_ac_chrominance, 1, avctx); if (ret) return ret; @@ -248,7 +229,7 @@ static int jpg_decode_block(JPGContext *c, GetBitContext *gb, return AVERROR_INVALIDDATA; c->bdsp.clear_block(block); - dc = get_vlc2(gb, c->dc_vlc[is_chroma].table, 9, 3); + dc = get_vlc2(gb, c->dc_vlc[is_chroma].table, 9, 2); if (dc < 0) return AVERROR_INVALIDDATA; if (dc) @@ -259,7 +240,7 @@ static int jpg_decode_block(JPGContext *c, GetBitContext *gb, pos = 0; while (pos < 63) { - val = get_vlc2(gb, c->ac_vlc[is_chroma].table, 9, 3); + val = get_vlc2(gb, c->ac_vlc[is_chroma].table, 9, 2); if (val < 0) return AVERROR_INVALIDDATA; pos += val >> 4; @@ -560,7 +541,7 @@ static uint32_t epic_decode_pixel_pred(ePICContext *dc, int x, int y, } if (R<0 || G<0 || B<0 || R > 255 || G > 255 || B > 255) { - avpriv_request_sample(NULL, "RGB %d %d %d is out of range\n", R, G, B); + avpriv_request_sample(NULL, "RGB %d %d %d (out of range)", R, G, B); return 0; } @@ -1048,7 +1029,7 @@ static int kempf_restore_buf(const uint8_t *src, int len, else if (npal <= 16) nb = 4; else nb = 8; - for (j = 0; j < height; j++, dst += stride, jpeg_tile += tile_stride) { + for (j = 0; j < height; j++, dst += stride, jpeg_tile = FF_PTR_ADD(jpeg_tile, tile_stride)) { if (get_bits(&gb, 8)) continue; for (i = 0; i < width; i++) { diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c index 7c270bc33..8444d9a4b 100644 --- a/libavcodec/g722dec.c +++ b/libavcodec/g722dec.c @@ -147,6 +147,6 @@ AVCodec ff_adpcm_g722_decoder = { .priv_data_size = sizeof(G722Context), .init = g722_decode_init, .decode = g722_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .priv_class = &g722_decoder_class, }; diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c index 25b61df19..9e2ebf67c 100644 --- a/libavcodec/g722enc.c +++ b/libavcodec/g722enc.c @@ -59,27 +59,11 @@ static av_cold int g722_encode_close(AVCodecContext *avctx) static av_cold int g722_encode_init(AVCodecContext * avctx) { G722Context *c = avctx->priv_data; - int ret; c->band[0].scale_factor = 8; c->band[1].scale_factor = 2; c->prev_samples_pos = 22; - if (avctx->trellis) { - int frontier = 1 << avctx->trellis; - int max_paths = frontier * FREEZE_INTERVAL; - int i; - for (i = 0; i < 2; i++) { - c->paths[i] = av_mallocz_array(max_paths, sizeof(**c->paths)); - c->node_buf[i] = av_mallocz_array(frontier, 2 * sizeof(**c->node_buf)); - c->nodep_buf[i] = av_mallocz_array(frontier, 2 * sizeof(**c->nodep_buf)); - if (!c->paths[i] || !c->node_buf[i] || !c->nodep_buf[i]) { - ret = AVERROR(ENOMEM); - goto error; - } - } - } - if (avctx->frame_size) { /* validate frame size */ if (avctx->frame_size & 1 || avctx->frame_size > MAX_FRAME_SIZE) { @@ -113,14 +97,23 @@ static av_cold int g722_encode_init(AVCodecContext * avctx) avctx->trellis); avctx->trellis = new_trellis; } + if (avctx->trellis) { + int frontier = 1 << avctx->trellis; + int max_paths = frontier * FREEZE_INTERVAL; + + for (int i = 0; i < 2; i++) { + c->paths[i] = av_calloc(max_paths, sizeof(**c->paths)); + c->node_buf[i] = av_calloc(frontier, 2 * sizeof(**c->node_buf)); + c->nodep_buf[i] = av_calloc(frontier, 2 * sizeof(**c->nodep_buf)); + if (!c->paths[i] || !c->node_buf[i] || !c->nodep_buf[i]) + return AVERROR(ENOMEM); + } + } } ff_g722dsp_init(&c->dsp); return 0; -error: - g722_encode_close(avctx); - return ret; } static const int16_t low_quant[33] = { @@ -387,4 +380,5 @@ AVCodec ff_adpcm_g722_encoder = { .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO, 0 }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c index 1deff495d..0c47458c2 100644 --- a/libavcodec/g723_1.c +++ b/libavcodec/g723_1.c @@ -29,6 +29,1077 @@ #include "celp_math.h" #include "g723_1.h" +const int16_t ff_g723_1_cos_tab[COS_TBL_SIZE + 1] = { + 16384, 16383, 16379, 16373, 16364, 16353, 16340, 16324, + 16305, 16284, 16261, 16235, 16207, 16176, 16143, 16107, + 16069, 16029, 15986, 15941, 15893, 15843, 15791, 15736, + 15679, 15619, 15557, 15493, 15426, 15357, 15286, 15213, + 15137, 15059, 14978, 14896, 14811, 14724, 14635, 14543, + 14449, 14354, 14256, 14155, 14053, 13949, 13842, 13733, + 13623, 13510, 13395, 13279, 13160, 13039, 12916, 12792, + 12665, 12537, 12406, 12274, 12140, 12004, 11866, 11727, + 11585, 11442, 11297, 11151, 11003, 10853, 10702, 10549, + 10394, 10238, 10080, 9921, 9760, 9598, 9434, 9269, + 9102, 8935, 8765, 8595, 8423, 8250, 8076, 7900, + 7723, 7545, 7366, 7186, 7005, 6823, 6639, 6455, + 6270, 6084, 5897, 5708, 5520, 5330, 5139, 4948, + 4756, 4563, 4370, 4176, 3981, 3786, 3590, 3393, + 3196, 2999, 2801, 2603, 2404, 2205, 2006, 1806, + 1606, 1406, 1205, 1005, 804, 603, 402, 201, + 0, -201, -402, -603, -804, -1005, -1205, -1406, + -1606, -1806, -2006, -2205, -2404, -2603, -2801, -2999, + -3196, -3393, -3590, -3786, -3981, -4176, -4370, -4563, + -4756, -4948, -5139, -5330, -5520, -5708, -5897, -6084, + -6270, -6455, -6639, -6823, -7005, -7186, -7366, -7545, + -7723, -7900, -8076, -8250, -8423, -8595, -8765, -8935, + -9102, -9269, -9434, -9598, -9760, -9921, -10080, -10238, + -10394, -10549, -10702, -10853, -11003, -11151, -11297, -11442, + -11585, -11727, -11866, -12004, -12140, -12274, -12406, -12537, + -12665, -12792, -12916, -13039, -13160, -13279, -13395, -13510, + -13623, -13733, -13842, -13949, -14053, -14155, -14256, -14354, + -14449, -14543, -14635, -14724, -14811, -14896, -14978, -15059, + -15137, -15213, -15286, -15357, -15426, -15493, -15557, -15619, + -15679, -15736, -15791, -15843, -15893, -15941, -15986, -16029, + -16069, -16107, -16143, -16176, -16207, -16235, -16261, -16284, + -16305, -16324, -16340, -16353, -16364, -16373, -16379, -16383, + -16384, -16383, -16379, -16373, -16364, -16353, -16340, -16324, + -16305, -16284, -16261, -16235, -16207, -16176, -16143, -16107, + -16069, -16029, -15986, -15941, -15893, -15843, -15791, -15736, + -15679, -15619, -15557, -15493, -15426, -15357, -15286, -15213, + -15137, -15059, -14978, -14896, -14811, -14724, -14635, -14543, + -14449, -14354, -14256, -14155, -14053, -13949, -13842, -13733, + -13623, -13510, -13395, -13279, -13160, -13039, -12916, -12792, + -12665, -12537, -12406, -12274, -12140, -12004, -11866, -11727, + -11585, -11442, -11297, -11151, -11003, -10853, -10702, -10549, + -10394, -10238, -10080, -9921, -9760, -9598, -9434, -9269, + -9102, -8935, -8765, -8595, -8423, -8250, -8076, -7900, + -7723, -7545, -7366, -7186, -7005, -6823, -6639, -6455, + -6270, -6084, -5897, -5708, -5520, -5330, -5139, -4948, + -4756, -4563, -4370, -4176, -3981, -3786, -3590, -3393, + -3196, -2999, -2801, -2603, -2404, -2205, -2006, -1806, + -1606, -1406, -1205, -1005, -804, -603, -402, -201, + 0, 201, 402, 603, 804, 1005, 1205, 1406, + 1606, 1806, 2006, 2205, 2404, 2603, 2801, 2999, + 3196, 3393, 3590, 3786, 3981, 4176, 4370, 4563, + 4756, 4948, 5139, 5330, 5520, 5708, 5897, 6084, + 6270, 6455, 6639, 6823, 7005, 7186, 7366, 7545, + 7723, 7900, 8076, 8250, 8423, 8595, 8765, 8935, + 9102, 9269, 9434, 9598, 9760, 9921, 10080, 10238, + 10394, 10549, 10702, 10853, 11003, 11151, 11297, 11442, + 11585, 11727, 11866, 12004, 12140, 12274, 12406, 12537, + 12665, 12792, 12916, 13039, 13160, 13279, 13395, 13510, + 13623, 13733, 13842, 13949, 14053, 14155, 14256, 14354, + 14449, 14543, 14635, 14724, 14811, 14896, 14978, 15059, + 15137, 15213, 15286, 15357, 15426, 15493, 15557, 15619, + 15679, 15736, 15791, 15843, 15893, 15941, 15986, 16029, + 16069, 16107, 16143, 16176, 16207, 16235, 16261, 16284, + 16305, 16324, 16340, 16353, 16364, 16373, 16379, 16383, + 16384 +}; + +const int16_t ff_g723_1_lsp_band0[LSP_CB_SIZE][3] = { + { 0, 0, 0}, { -270, -1372, -1032}, { -541, -1650, -1382}, + { -723, -2011, -2213}, { -941, -1122, -1942}, { -780, -1145, -2454}, + { -884, -1309, -1373}, {-1051, -1523, -1766}, {-1083, -1622, -2300}, + { -777, -1377, -2147}, { -935, -1467, -2763}, { -802, -1327, -3471}, + { -935, -1959, -3999}, { -240, -89, 222}, { -661, -257, -160}, + { -994, -466, -419}, { -188, -164, -278}, { -342, -512, -415}, + { -607, -511, -797}, { 16, 19, -716}, { 374, 425, -972}, + { -346, 245, -282}, { -265, 506, -754}, { -620, -147, 1955}, + { -742, -860, 2597}, { -150, -352, 2704}, { 305, 880, 1954}, + { 123, 731, 2766}, { -348, 765, 3327}, { 618, 221, 3258}, + { -178, -47, 4219}, { 393, 1304, 3842}, { 698, 1702, 4801}, + { 63, -584, 1229}, { -215, -732, 1704}, { 172, -335, 1909}, + { -2, 216, 1797}, { 353, 127, 2205}, {-1208, 188, 11}, + { -513, -75, -683}, { -973, 222, -646}, { -616, -843, -388}, + { -950, -1113, -359}, {-1431, -623, -705}, {-1398, -1063, -178}, + { -45, -461, 35}, { -9, -657, -216}, { 127, -1078, 95}, + { -950, -1156, 584}, {-1480, -1494, 449}, { -120, -705, 516}, + { -368, -961, 727}, { -378, -526, 973}, { -793, -614, 676}, + { -801, -755, 1287}, {-1476, -340, 1636}, { -505, -1254, 1543}, + {-1243, -1622, 1532}, { -776, -1477, -655}, {-1151, -1296, -823}, + {-1153, -1672, -1124}, {-1291, -2003, -1702}, { -622, -1283, 57}, + { -471, -1611, 509}, {-1060, -1570, -139}, { -873, -2156, -536}, + {-1716, -2021, -364}, {-2150, -3218, -1291}, {-1248, -1945, -2904}, + {-1215, -2633, -2855}, { 167, -244, 84}, { 349, -412, -217}, + { -40, -352, 632}, { 227, -529, 405}, { 68, -383, -443}, + { 167, -558, -706}, { -275, -854, -14}, { -351, -1089, -449}, + { 341, -72, -289}, { 603, -106, -474}, { 322, -219, -649}, + { 179, -317, -998}, { 450, -291, -996}, { 555, 195, -525}, + { 784, 272, -831}, { -148, -384, -849}, { 82, -536, -1357}, + { 238, -172, -1354}, { 422, -268, -1841}, { 297, -737, -2079}, + { -111, -801, -598}, { 1, -668, -984}, { -131, -818, -1299}, + { -329, -521, -1310}, { -151, -778, -1834}, { -93, -352, -1746}, + { -568, -640, -1821}, { -509, -941, -2183}, { 464, -815, -1250}, + { 79, -1133, -1597}, { -184, -1353, -2123}, { -196, -410, -2427}, + { -192, -833, -2810}, { -259, -1382, -3045}, { -217, 4, -1166}, + { -800, -325, -1219}, { -363, -830, -898}, { -661, -1134, -960}, + { -386, -980, -1501}, { -627, -1159, -1722}, { -903, -829, -855}, + { -685, -829, -1313}, {-1065, -959, -1405}, { 441, 25, -847}, + { 655, -27, -1181}, { 1159, -110, -705}, { 856, 253, -1671}, + { 415, 404, -1}, { 322, 903, -398}, { 670, 499, -292}, + { 803, 591, -610}, { 1144, 591, -814}, { 717, 183, 393}, + { 857, 381, 106}, { 609, 62, -27}, { 792, 198, -325}, + { 735, 805, 88}, { 1142, 812, 78}, { 1028, 366, -292}, + { 1309, 743, -237}, { 1615, 589, -79}, { 1010, 639, -243}, + { 999, 964, -311}, { 1500, 1137, -615}, { 988, 357, 646}, + { 1227, 667, 683}, { 1164, 1565, 894}, { 1392, 2015, 477}, + { 1138, 533, 250}, { 1437, 896, 391}, { 1765, 1118, 99}, + { 1112, 1090, 802}, { 1596, 846, 1134}, { 937, 1161, 279}, + { 1719, 1254, 683}, { 1338, 1086, 35}, { 1419, 1324, 428}, + { 1428, 1524, 40}, { 2108, 1594, 89}, { 1015, 544, 1222}, + { 1121, 925, 1263}, { 1030, 1318, 1485}, { 1295, 789, 1817}, + { 1323, 1272, 1909}, { 1724, 1237, 1803}, { 1797, 1689, 858}, + { 2149, 1367, 1301}, { 2302, 1867, 761}, { 2863, 2351, 1053}, + { 52, 163, -76}, { 230, 309, -492}, { -71, 619, 39}, + { -218, 856, 499}, { -654, 736, -207}, { -535, 1259, 155}, + { -480, 1476, 643}, { 262, 1081, 102}, { 309, 1592, -182}, + { 627, 1629, 534}, { 337, 643, 456}, { 758, 670, 713}, + { 202, 1126, 658}, { 612, 1131, 666}, { 686, 1223, 1136}, + { -131, 377, 525}, { 42, 708, 907}, { 87, 1488, 1035}, + { 432, 2117, 904}, { 137, 981, 1332}, { -447, 1014, 1136}, + { -839, 1793, 1246}, { -559, 297, 198}, { -850, 685, 446}, + {-1273, 632, 826}, { -401, -544, 173}, { -753, -793, 144}, + { -436, -9, 772}, { -115, -243, 1310}, { -670, -269, 374}, + {-1027, -13, 639}, { -887, -81, 1137}, {-1277, -455, 158}, + {-1411, -720, 736}, { 172, 88, 403}, { 386, 255, 756}, + { -500, 522, 910}, { -958, 659, 1388}, { -395, 301, 1344}, + { -356, 768, 1813}, { -613, 841, 2419}, { 445, -122, 252}, + { 629, -87, 723}, { 283, -253, 870}, { 456, -116, 1381}, + { 757, 180, 1059}, { 532, 408, 1509}, { 947, 288, 1806}, + { 1325, 994, 2524}, { 892, 1219, 3023}, { 1397, 1596, 3406}, + { 1143, 1552, 2546}, { 1850, 1433, 2710}, { -10, 134, 1002}, + { 154, 499, 1323}, { 508, 792, 1117}, { 509, 1340, 1616}, + { 762, 862, 1608}, { 787, 740, 2320}, { 794, 1727, 1283}, + { 465, 2108, 1660}, { -120, 1451, 1613}, { -386, 2016, 2169}, + { 891, 1225, 2050}, { 456, 1480, 2185}, { 1493, 1283, 1209}, + { 1397, 1636, 1518}, { 1776, 1738, 1552}, { 1572, 1698, 2141}, + { 1389, 2126, 1271}, { 1959, 2413, 1119}, { 1365, 2892, 1505}, + { 2206, 1971, 1623}, { 2076, 1950, 2280}, { 1717, 2291, 1867}, + { 2366, 2515, 1953}, { 2865, 2838, 2522}, { 2535, 3465, 2011}, + { 3381, 4127, 2638}, { 836, 2667, 2289}, { 1761, 2773, 2337}, + { 1415, 3325, 2911}, { 2354, 3138, 3126}, { 2659, 4192, 4010}, + { 1048, 1786, 1818}, { 1242, 2111, 2240}, { 1512, 2079, 2780}, + { 1573, 2491, 3138}, { 2230, 2377, 2782}, { 416, 1773, 2704}, + { 725, 2336, 3297}, { 1252, 2373, 3978}, { 2094, 2268, 3568}, + { 2011, 2712, 4528}, { 1341, 3507, 3876}, { 1216, 3919, 4922}, + { 1693, 4793, 6012} +}; + +const int16_t ff_g723_1_lsp_band1[LSP_CB_SIZE][3] = { + { 0, 0, 0}, {-2114, -1302, 76}, {-2652, -1278, -1368}, + {-2847, -828, -349}, {-3812, -2190, -349}, {-3946, -364, -449}, + {-2725, -4492, -3607}, {-3495, -4764, -1744}, { -51, -756, 84}, + { -153, -1191, 504}, { 108, -1418, 1167}, { -835, -896, 390}, + { -569, -1702, 87}, {-1151, -1818, 933}, {-1826, -2547, 411}, + {-1842, -1818, 1451}, {-2438, -1611, 781}, {-2747, -2477, 1311}, + { -940, 1252, 477}, {-1629, 1688, 602}, {-1202, 617, 280}, + {-1737, 393, 580}, {-1528, 1077, 1199}, {-2165, -161, 1408}, + {-2504, -1087, 2371}, {-3458, -175, 1395}, {-1397, -98, -843}, + {-2252, -177, -1149}, {-1489, -726, -1283}, {-1558, -265, -1744}, + {-1867, -821, -1897}, {-2062, -1516, -2340}, {-2595, -1142, -2861}, + { 170, 46, -819}, { -193, -204, -1151}, { 326, -196, -1532}, + { 780, 329, -816}, { 201, 369, -1243}, { 650, -209, -1060}, + { 1144, -15, -1216}, { 1203, -259, -1867}, { -890, -564, -1430}, + { -638, -852, -1921}, { 177, -739, -1358}, { -261, -526, -1666}, + { 206, -407, -2255}, { 338, -526, -822}, { 421, -1095, -1009}, + { 765, -607, -1408}, { 825, -1295, -2004}, { 357, -905, -1815}, + { -58, -1248, -1588}, { -596, -1436, -2046}, { -73, -1159, -2116}, + { -115, -1382, -2581}, { -160, -1723, -1952}, { -6, -2196, -2954}, + { -649, -1705, -2603}, { -617, -1453, -3282}, { -949, -2019, -3102}, + { -812, 1544, 1937}, {-1854, 574, 2000}, {-1463, 1140, 2649}, + {-2683, 1748, 1452}, {-2486, 2241, 2523}, { 783, 1910, 1435}, + { 581, 2682, 1376}, { 236, 2197, 1885}, { -453, 2943, 2057}, + { -682, 2178, 2565}, {-1342, 3201, 3328}, { -288, -184, 262}, + { 121, -149, -183}, { 758, -412, 206}, { 1038, -204, 853}, + { 1577, -457, 700}, { 937, -640, -567}, { 1508, -528, -1024}, + { -225, -527, -427}, { -564, -1095, -332}, { -742, -353, -186}, + {-1288, -459, 84}, {-1853, -484, -274}, {-1554, -731, 825}, + {-2425, -234, 382}, {-1722, 293, -271}, {-2515, 425, -564}, + {-2599, 818, 464}, { -358, 118, -375}, { -613, 198, -874}, + { -690, 683, -324}, {-1352, 1155, -168}, {-1093, 129, -324}, + {-1184, 611, -858}, { 433, 386, -372}, { -120, 486, -634}, + { 234, 851, -631}, { 602, 128, 46}, { 1099, 410, 159}, + { 715, -145, -424}, { 1198, -85, -593}, { 1390, 367, -358}, + { 1683, 362, -964}, { 1711, 622, 45}, { 2033, 833, -383}, + { 2890, 549, -506}, { 7, 401, 52}, { 72, 811, 415}, + { 566, 668, 41}, { 467, 1218, 130}, { 68, 957, -187}, + { -25, 1649, -103}, { -661, 260, 214}, { -925, -94, 612}, + { -321, -422, 965}, { -788, -672, 1783}, { 400, -673, 779}, + { 741, -595, 1635}, { -161, 307, 657}, { -382, 836, 871}, + { -814, 400, 1223}, { 364, 606, 1247}, { 57, 75, 1571}, + { 151, 471, 2287}, { -81, 1021, 1502}, { 227, 1470, 1097}, + { 658, 1275, 1653}, { 664, 1478, 2377}, { 263, -127, 444}, + { 264, 89, 969}, { 794, 171, 576}, { 821, 186, 1226}, + { 404, 462, 517}, { 339, 918, 794}, { 1280, 1423, 196}, + { 1453, 2019, 365}, { 1615, 1481, 672}, { 2394, 1708, 508}, + { 806, 1238, 573}, { 713, 1158, 1078}, { 1285, 1436, 1232}, + { 1790, 1188, 1141}, { 765, 643, 864}, { 1032, 797, 1279}, + { 900, 563, 1827}, { 1514, 673, 2312}, { 1544, 1129, 3240}, + { 1469, 1050, 1594}, { 1945, 1318, 1988}, { 2397, 2026, 2060}, + { 3538, 2057, 2620}, { 1249, -118, 74}, { 1727, 194, 421}, + { 2078, -50, -463}, { 970, 688, -432}, { 1149, 952, -110}, + { 1254, 1275, -651}, { 1386, 929, 401}, { 1960, 1167, 232}, + { 407, -752, -243}, { 859, -1118, 172}, { -227, -860, -992}, + { -796, -1175, -1380}, { 8, -1282, -388}, { 353, -1781, -1037}, + { -732, -397, -807}, { -853, -28, -1342}, {-1229, -1207, -1959}, + {-1015, -1125, -2543}, {-1452, -1791, -2725}, {-1891, -2416, -3269}, + { -918, -1629, -783}, { -580, -2155, -698}, {-1097, -2364, -96}, + {-1387, -1513, 7}, {-1588, -2076, -664}, {-1473, -2740, -784}, + {-2378, -3149, -56}, {-2856, -2092, -169}, {-3391, -3708, 316}, + {-1176, -890, -614}, {-1944, -1061, -800}, { -299, -1517, -1000}, + { -640, -1850, -1526}, {-1454, -1536, -1233}, {-1890, -1955, -1756}, + {-1086, -1921, -2122}, { -750, -2325, -2260}, {-1325, -2413, -2673}, + {-1114, -2542, -3459}, {-1341, -2901, -3963}, {-1160, -2226, -1393}, + {-1001, -2772, -1573}, {-1594, -2641, -1978}, {-1534, -3046, -2624}, + {-2224, -2196, -675}, {-2807, -3054, -1102}, {-2008, -2840, -1186}, + {-1980, -3332, -1695}, {-1715, -3562, -505}, {-2527, -4000, -1887}, + {-2333, -2734, -2296}, {-3440, -2401, -3211}, {-2008, -3528, -3337}, + {-2247, -3291, -4510}, { -475, 949, 155}, { -149, 1365, 545}, + { -757, 1644, 1083}, { -217, 2053, 1353}, {-1433, 2301, 1462}, + { 495, 1661, 529}, { 10, 2037, 740}, { 2082, 1898, 978}, + { 2831, 2294, 911}, { 842, 793, 420}, { 1223, 1023, 863}, + { 1237, 451, 780}, { 1744, 708, 822}, { 1533, 284, 1384}, + { 2135, 609, 1538}, { 2305, 626, 540}, { 2368, 1187, 955}, + { 2586, 1255, -7}, { 3116, 1131, 726}, { 3431, 1730, 428}, + { 2734, 1648, 1307}, { 2988, 1231, 2010}, { 3523, 2024, 1488}, + { 1034, 1657, 871}, { 1206, 2163, 1036}, { 1807, 2372, 1233}, + { 1808, 1769, 1493}, { 1573, 2332, 1779}, { 1216, 1609, 1866}, + { 1480, 1898, 2513}, { 465, 2708, 2776}, { 771, 3638, 3338}, + { 1869, 2599, 2623}, { 2825, 2745, 2468}, { 2638, 2439, 1585}, + { 2094, 2970, 1308}, { 2022, 3057, 1999}, { 3428, 2912, 1816}, + { 4536, 2974, 2129}, { 1046, 2563, 2086}, { 1363, 3562, 2318}, + { 2511, 1891, 2984}, { 1866, 2306, 3986}, { 3272, 2924, 3682}, + { 3146, 3564, 2272}, { 3592, 3968, 2822}, { 2431, 3369, 3069}, + { 1931, 4709, 3090}, { 2629, 4220, 3986}, { 4639, 4056, 3664}, + { 4035, 5334, 4912} +}; + +const int16_t ff_g723_1_lsp_band2[LSP_CB_SIZE][4] = { + { 0, 0, 0, 0}, { 601, 512, -542, 334}, + { 428, 1087, -484, -132}, { 652, 622, -391, -572}, + { 378, 799, 141, -860}, { 1040, 409, 112, -554}, + { 1123, 670, -75, -847}, { 1421, 494, -315, -1095}, + { 787, 1001, 114, -460}, { 988, 1672, 216, -681}, + { 1007, 1241, -132, -1247}, { 1073, 399, 186, -5}, + { 1262, 193, -694, -129}, { 325, 196, 51, -641}, + { 861, -59, 350, -458}, { 1261, 567, 586, -346}, + { 1532, 885, 210, -517}, { 2027, 937, 113, -792}, + { 1383, 1064, 334, 38}, { 1964, 1468, 459, 133}, + { 2062, 1186, -98, -121}, { 2577, 1445, 506, -373}, + { 2310, 1682, -2, -960}, { 2876, 1939, 765, 138}, + { 3581, 2360, 649, -414}, { 219, 176, -398, -309}, + { 434, -78, -435, -880}, { -344, 301, 265, -552}, + { -915, 470, 657, -380}, { 419, -432, -163, -453}, + { 351, -953, 8, -562}, { 789, -43, 20, -958}, + { 302, -594, -352, -1159}, { 1040, 108, -668, -924}, + { 1333, 210, -1217, -1663}, { 483, 589, -350, -1140}, + { 1003, 824, -802, -1184}, { 745, 58, -589, -1443}, + { 346, 247, -915, -1683}, { 270, 796, -720, -2043}, + { 1208, 722, -222, -193}, { 1486, 1180, -412, -672}, + { 1722, 179, -69, -521}, { 2047, 860, -666, -1410}, + { -146, 222, -281, -805}, { -189, 90, -114, -1307}, + { -152, 1086, -241, -764}, { -439, 733, -601, -1302}, + { -833, -167, -351, -601}, { -856, -422, -411, -1059}, + { -747, -355, -582, -1644}, { -837, 210, -916, -1144}, + {-1800, 32, -878, -1687}, { -48, -23, -1146, 52}, + { -350, -409, -1656, -364}, { 265, -728, -858, -577}, + { 458, -247, -1141, -997}, { 691, -407, -1988, -1161}, + { -66, -104, -705, -1249}, { -431, -93, -1191, -1844}, + { 203, -732, -1000, -1693}, { 10, -832, -1846, -1819}, + { 493, -128, -1436, -1768}, { 488, -311, -1730, -2540}, + { -653, -532, -1150, -1172}, {-1086, -289, -1706, -1533}, + { -699, -1205, -1216, -1766}, {-1032, -1481, -2074, -1523}, + { -721, -1220, -2277, -2600}, { 12, -539, -1484, -1131}, + { -40, -911, -2106, -441}, { -471, -484, -2267, -1549}, + { -141, -988, -3006, -1721}, {-1545, -2102, -583, 342}, + {-1383, -2772, -386, -13}, {-2118, -2589, -1205, 72}, + {-2147, -3231, -965, 390}, {-2949, -3300, -621, 637}, + {-3907, -4138, -865, 803}, {-1287, -845, -375, -548}, + {-1416, -1169, -487, -1277}, {-1400, -1690, -1027, -418}, + {-2018, -1909, -1188, -1260}, {-1418, -2222, -2029, -128}, + {-2067, -2998, -2693, -310}, { -950, -1028, -1538, 185}, + {-1616, -915, -2205, -549}, { 19, -821, -1145, 352}, + { 184, -1175, -1356, -627}, { -547, -1088, -1661, -911}, + { -216, -1502, -2197, -948}, { -795, -1306, -2374, -451}, + { -924, -1889, -2796, -680}, { -600, -1614, -3609, -885}, + {-2392, -2528, 319, 303}, {-2908, -2095, -310, 573}, + {-3460, -2141, 49, -113}, {-2231, -448, 675, -146}, + {-2805, -532, 1231, 479}, {-2684, -486, -200, 611}, + {-3525, -971, -198, 704}, {-3707, 173, 349, 254}, + {-4734, -1447, -34, 880}, { 777, -512, 114, -10}, + { 1250, -66, 442, -5}, { 604, 613, 452, -352}, + { 1224, 777, 675, -1014}, {-1372, -79, -1208, -238}, + {-2389, -17, -1157, -818}, {-1504, -673, -1133, -1060}, + {-1984, -799, -2005, -1973}, {-2037, -798, -1068, -105}, + {-3190, -899, -1817, -194}, { -156, -886, 394, -318}, + { -258, -1283, 551, 202}, { -536, -1729, 910, 331}, + { -847, -1109, 795, -163}, {-1171, -1128, 715, 519}, + {-1080, -1319, 1685, 668}, {-1000, -1921, 96, 211}, + {-1487, -2148, 831, 174}, {-1139, -374, 414, -4}, + {-1517, -1383, 396, -352}, {-1012, 439, -59, -967}, + {-1812, 706, -440, -1030}, {-1971, -329, -34, -827}, + {-2472, -1588, -151, -606}, {-2161, 374, -281, 76}, + {-3012, 231, -15, -690}, { 1104, 566, 721, 209}, + { 1685, 564, 383, 98}, { 1898, 750, 792, -97}, + { 556, -64, 561, -93}, { 876, 162, 913, -22}, + { 961, 675, 1296, 140}, { 756, -396, 851, 544}, + { 360, -303, 1341, 396}, { 878, -22, 1464, 863}, + { -309, -273, 642, -129}, { -686, -82, 842, 454}, + { -5, -47, 1069, 998}, { -94, 967, 1277, 298}, + { -489, 385, 1473, 746}, { -369, -717, 1333, 242}, + { 281, -993, 1726, 924}, { 464, 601, 1575, 1376}, + { -250, 206, 2339, 1175}, { -438, 377, -597, -285}, + {-1020, 787, -790, -287}, { -458, -410, 215, 295}, + { -589, -860, -121, 797}, {-1175, 122, -437, 466}, + {-1480, -121, 367, 924}, { 234, 323, 770, -555}, + { 145, 30, 996, 26}, { 66, 849, 93, -145}, + { -117, 1261, 474, -399}, {-1495, 1051, 218, -506}, + {-1390, 694, 994, 88}, { 616, 7, 78, 304}, + { 1060, 52, -62, 835}, { 833, 454, 649, 1359}, + { -770, 464, 47, 93}, { -574, 1199, -39, 379}, + { 114, -98, 488, 485}, { 727, 244, 606, 696}, + { -76, 455, 671, 546}, { -565, -13, 145, 819}, + { -376, 569, 448, 1128}, { 218, 122, 265, 1167}, + { 230, 738, 932, 1003}, { 138, 477, 36, 450}, + { 404, 787, -73, 1000}, { 497, 1259, 387, 1231}, + { 17, 207, 195, -79}, { 562, 358, 53, -158}, + { 493, 387, 478, 189}, { 678, 831, 640, 558}, + { -197, 523, 613, 57}, { 429, 894, 769, 111}, + { 67, 1174, 568, 511}, { 1242, 824, 251, 840}, + { 1419, 1074, 864, 481}, { 924, 1474, 669, 724}, + { 1539, 1879, 654, 1590}, { 445, 337, 1111, 541}, + { 472, 1421, 1264, 1094}, { 794, 735, 1103, 668}, + { 1055, 863, 1192, 1020}, { 778, 1105, 806, 1798}, + { 1052, 1527, 1587, 2151}, { 881, 1552, 1265, 391}, + { 726, 872, 1812, 601}, { 1469, 280, 1008, 616}, + { 1403, 577, 1803, 1244}, { 1650, 1314, 1148, 1072}, + { 1297, 1669, 1911, 1026}, { 2093, 1044, 2115, 1189}, + { 1644, 1961, 2587, 1512}, { 25, -315, -9, -106}, + { 290, -339, 428, -444}, { -68, -783, 735, 772}, + { 245, -555, 468, 47}, { 334, -895, 814, 146}, + { 235, 368, -964, -959}, { -203, 315, -1566, -1217}, + { 801, 17, -276, -354}, { 894, -495, -789, -635}, + { 716, 291, -1189, -357}, { 560, -260, -733, -2}, + { 679, -508, -1429, 211}, { -51, -62, -428, 557}, + { 322, -638, -211, 614}, { -878, -1057, -84, -71}, + { -388, -1415, -167, -318}, { -754, -1574, 214, -539}, + {-1419, -2004, -92, -787}, { -47, -856, -347, -255}, + { 23, -1211, -173, 320}, { -658, -487, -893, 353}, + { -783, -1587, -584, 507}, {-1420, -859, -378, 441}, + {-2095, -1491, -137, 439}, { -321, -1450, -1288, -12}, + { -359, -2113, -553, -8}, { -831, -1918, -1561, 32}, + {-1014, -2487, -1359, -939}, { -475, -311, -169, -236}, + { -907, -426, 276, -611}, { -96, -400, 50, -710}, + { -426, -1022, -10, -985}, { -197, -258, -744, -575}, + { -611, -930, -771, -394}, { -267, -776, -612, -939}, + { -256, -1346, -802, -1122}, { -796, -1570, -825, -754}, + { 712, 876, 141, 227}, { 981, 1509, 85, 124}, + { 1462, 1228, 979, -39}, { 1734, 999, 1481, 440}, + { 2293, 1116, 769, 440}, { 2504, 1480, 1241, 356}, + { 2474, 1909, 1558, 810}, { 917, 1134, 607, -134}, + { 509, 1809, 781, -123}, { 1712, 1506, 559, -423}, + { 2037, 2317, 726, -155}, { 3031, 2676, 1203, 331}, + { 3664, 3274, 1768, 531}, { 1610, 1839, 867, 183}, + { 1774, 1972, 1538, 97}, { 1822, 2158, 1282, 659}, + { 2222, 2758, 1818, 900}, { 3251, 2124, 1723, 996}, + { 3633, 2336, 2408, 1453}, { 2923, 3517, 2567, 1318}, +}; + +const int32_t ff_g723_1_combinatorial_table[PULSE_MAX][SUBFRAME_LEN/GRID_SIZE] = { + {118755, 98280, 80730, 65780, 53130, + 42504, 33649, 26334, 20349, 15504, + 11628, 8568, 6188, 4368, 3003, + 2002, 1287, 792, 462, 252, + 126, 56, 21, 6, 1, + 0, 0, 0, 0, 0}, + + { 23751, 20475, 17550, 14950, 12650, + 10626, 8855, 7315, 5985, 4845, + 3876, 3060, 2380, 1820, 1365, + 1001, 715, 495, 330, 210, + 126, 70, 35, 15, 5, + 1, 0, 0, 0, 0}, + + { 3654, 3276, 2925, 2600, 2300, + 2024, 1771, 1540, 1330, 1140, + 969, 816, 680, 560, 455, + 364, 286, 220, 165, 120, + 84, 56, 35, 20, 10, + 4, 1, 0, 0, 0}, + + { 406, 378, 351, 325, 300, + 276, 253, 231, 210, 190, + 171, 153, 136, 120, 105, + 91, 78, 66, 55, 45, + 36, 28, 21, 15, 10, + 6, 3, 1, 0, 0}, + + { 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, 0}, + + { 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1}, +}; + +const int16_t ff_g723_1_fixed_cb_gain[GAIN_LEVELS] = { + 1, 2, 3, 4, 6, 9, 13, 18, + 26, 38, 55, 80, 115, 166, 240, 348, + 502, 726, 1050, 1517, 2193, 3170, 4582, 6623, +}; + +const int16_t ff_g723_1_adaptive_cb_gain85[85 * 20] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 800, 1496, 167, -256, + -338, -39, -136, -1, -4, -6, -73, -8, + -15, 12, 23, 2, 16, 30, 3, -5, + -462, -686, 493, 2575, 311, -13, -28, -14, + -404, -5, -19, 13, 20, 72, 107, -77, + 8, 13, -9, -48, 1483, 144, 784, 928, + 1243, -134, -1, -37, -52, -94, -13, -71, + -6, -84, -8, -44, -112, -10, -59, -70, + -77, 275, 3522, 1056, -1254, 0, -4, -757, + -68, -95, 1, 16, -59, 4, -17, -227, + -5, 21, 269, 80, -125, -40, -264, 381, + 5027, 0, 0, -4, -8, -1542, 0, -2, + 0, 2, 0, 6, 38, 12, 81, -117, + 138, 332, 2215, 2574, 1339, -1, -6, -299, + -404, -109, -2, -18, -44, -21, -52, -348, + -11, -27, -181, -210, 3685, 2883, -887, 866, + -1639, -828, -507, -48, -45, -164, -648, 199, + 156, -194, -152, 46, 368, 288, -88, 86, + 1396, 2146, 2235, 345, 942, -118, -281, -305, + -7, -54, -182, -190, -292, -29, -45, -47, + -80, -123, -128, -19, 13, 4475, 3549, -804, + -655, 0, -1222, -768, -39, -26, -3, -2, + -969, 0, 219, 174, 0, 179, 141, -32, + -724, 254, 242, 6049, 2462, -32, -3, -3, + -2233, -370, 11, 10, -3, 267, -94, -89, + 108, -38, -36, -909, 626, -1713, 6121, 4561, + -1061, -23, -179, -2287, -1270, -68, 65, -233, + 640, -174, 477, -1704, 40, -111, 396, 295, + -350, 1391, 7985, 511, -405, -7, -118, -3892, + -15, -10, 29, 170, -678, 10, -43, -249, + -8, 34, 197, 12, 3144, -529, 608, 2530, + 3878, -603, -17, -22, -390, -918, 101, -116, + 19, -485, 81, -93, -744, 125, -144, -599, + 2589, -689, 3045, 5603, -404, -409, -29, -566, + -1916, -10, 108, -481, 128, -885, 235, -1041, + 63, -17, 75, 138, 3107, 513, 1374, -3594, + -4922, -589, -16, -115, -788, -1478, -97, -260, + -43, 681, 112, 301, 933, 154, 413, -1079, + 2468, 6010, 1107, -390, 1961, -372, -2204, -74, + -9, -234, -905, -166, -406, 58, 143, 26, + -295, -719, -132, 46, 4773, 2766, 2368, 4862, + -4044, -1390, -467, -342, -1443, -998, -806, -690, + -399, -1416, -821, -702, 1178, 682, 584, 1200, + 1665, -1879, 1443, 1701, 8562, -169, -215, -127, + -176, -4475, 190, -146, 165, -172, 195, -149, + -870, 982, -754, -889, 2716, 9011, -1007, 755, + -1785, -450, -4956, -61, -34, -194, -1493, 167, + 554, -125, -415, 46, 296, 982, -109, 82, + -2727, 7548, 1285, 938, 3420, -453, -3478, -100, + -53, -714, 1256, 213, -592, 156, -432, -73, + 569, -1576, -268, -196, 3677, 882, 4050, 1202, + 2323, -825, -47, -1001, -88, -329, -198, -909, + -218, -269, -64, -297, -521, -125, -574, -170, + 2046, -753, 122, 10102, 603, -255, -34, 0, + -6229, -22, 94, -15, 5, -1261, 464, -75, + -75, 27, -4, -372, 449, -1815, 10690, 3870, + -527, -12, -201, -6976, -914, -16, 49, -293, + 1184, -106, 428, -2525, 14, -58, 344, 124, + -941, 2352, 5049, 3650, 2637, -54, -337, -1556, + -813, -424, 135, 290, -725, 209, -524, -1125, + 151, -378, -812, -587, -1879, 796, 3117, 9569, + -404, -215, -38, -593, -5589, -9, 91, 357, + -151, 1097, -464, -1821, -46, 19, 76, 236, + -1715, 2043, -2096, 9946, 4001, -179, -254, -268, + -6038, -977, 213, -219, 261, 1041, -1240, 1272, + 418, -498, 511, -2429, -5772, -618, -3921, 284, + -3155, -2033, -23, -938, -4, -607, -218, -1381, + -148, 100, 10, 68, -1111, -119, -755, 54, + 382, 4748, 8003, -2064, 2198, -8, -1376, -3909, + -260, -294, -110, -186, -2319, 48, 598, 1008, + -51, -637, -1073, 277, -867, 3015, 11926, -1675, + 947, -45, -555, -8681, -171, -54, 159, 631, + -2195, -88, 308, 1219, 50, -174, -690, 96, + -4933, -432, 6757, 3771, 1352, -1485, -11, -2786, + -867, -111, -130, 2034, 178, 1135, 99, -1555, + 407, 35, -557, -311, 152, 9726, 4231, -1928, + 1490, -1, -5774, -1092, -226, -135, -90, -39, + -2511, 17, 1144, 498, -13, -884, -384, 175, + 2512, 193, 9033, 5361, -3148, -385, -2, -4980, + -1754, -605, -29, -1385, -106, -822, -63, -2956, + 482, 37, 1735, 1030, 8464, 2844, 12, 549, + 2132, -4373, -493, 0, -18, -277, -1469, -6, + -2, -284, -95, 0, -1101, -370, -1, -71, + 2141, -2602, 7166, 9046, -1350, -279, -413, -3134, + -4994, -111, 340, -936, 1138, -1182, 1436, -3957, + 176, -214, 590, 745, -244, 278, 13307, 1227, + -161, -3, -4, -10808, -91, -1, 4, 198, + -226, 18, -20, -997, -2, 2, 131, 12, + -1947, 8217, 6269, 917, -2559, -231, -4121, -2399, + -51, -399, 976, 745, -3144, 108, -460, -350, + -304, 1283, 979, 143, -1810, 2061, -2781, 6056, + 10058, -200, -259, -472, -2238, -6174, 227, -307, + 349, 669, -761, 1028, 1111, -1265, 1707, -3717, + 7827, 9161, -3409, 2473, -1510, -3739, -5122, -709, + -373, -139, -4376, 1628, 1906, -1181, -1382, 514, + 721, 844, -314, 228, -1430, 8313, 9541, -2955, + 1626, -124, -4218, -5556, -533, -161, 725, 832, + -4841, -257, 1499, 1721, 142, -825, -947, 293, + 2819, -4247, 5391, 8673, 2756, -485, -1101, -1774, + -4591, -463, 730, -927, 1397, -1492, 2248, -2854, + -474, 714, -907, -1459, 141, 14552, 690, 257, + -112, -1, -12926, -29, -4, 0, -125, -5, + -613, -2, -228, -10, 0, 99, 4, 1, + 11938, -1859, 1806, -962, -884, -8699, -211, -199, + -56, -47, 1355, -1316, 205, 701, -109, 106, + 644, -100, 97, -51, 3728, 1982, 2264, 4584, + 3131, -848, -239, -312, -1282, -598, -451, -515, + -273, -1043, -554, -633, -712, -378, -432, -876, + -1181, 766, 720, 14303, -216, -85, -35, -31, + -12486, -2, 55, 51, -33, 1031, -668, -628, + -15, 10, 9, 189, -4385, 4826, 10112, 1569, + 3388, -1173, -1421, -6242, -150, -700, 1291, 2706, + -2979, 420, -462, -969, 906, -998, -2091, -324, + -448, 1932, 15591, -1842, 657, -12, -227, -14837, + -207, -26, 52, 427, -1838, -50, 217, 1753, + 18, -77, -626, 74, -4141, 1844, 3962, 5517, + 6220, -1046, -207, -958, -1858, -2361, 466, 1001, + -446, 1394, -621, -1334, 1572, -700, -1504, -2094, + 729, -2299, 14755, 3657, -952, -32, -322, -13288, + -816, -55, 102, -656, 2071, -162, 513, -3294, + 42, -133, 857, 212, -1385, 5801, 13339, -3137, + 1344, -117, -2054, -10861, -600, -110, 490, 1127, + -4723, -265, 1111, 2554, 113, -476, -1094, 257, + 4710, 9661, 1073, -2467, 3274, -1354, -5697, -70, + -371, -654, -2777, -308, -633, 709, 1455, 161, + -941, -1930, -214, 493, 1843, -3624, 12422, 6898, + -1559, -207, -802, -9419, -2904, -148, 407, -1397, + 2748, -775, 1526, -5230, 175, -344, 1182, 656, + 1433, 2394, 2507, 1380, 8780, -125, -349, -383, + -116, -4705, -209, -219, -366, -120, -201, -211, + -768, -1283, -1343, -740, -1712, 12915, 5883, -2197, + 991, -179, -10181, -2112, -294, -60, 1350, 615, + -4638, -229, 1732, 789, 103, -781, -356, 133, + 15072, 2158, -1245, 910, -496, -13865, -284, -94, + -50, -15, -1986, 1145, 164, -837, -119, 69, + 456, 65, -37, 27, 4655, 7319, 4916, 586, + -3381, -1322, -3270, -1475, -20, -697, -2079, -1396, + -2196, -166, -261, -175, 960, 1510, 1014, 120, + 1191, -2140, 5120, 13498, -1418, -86, -279, -1600, + -11121, -122, 155, -372, 669, -981, 1763, -4218, + 103, -185, 443, 1168, -1530, -817, 8191, 9632, + -1452, -143, -40, -4095, -5663, -128, -76, 765, + 408, 900, 480, -4815, -135, -72, 726, 854, + -3236, 607, 1696, -2106, 11485, -639, -22, -175, + -270, -8051, 119, 335, -62, -416, 78, 218, + 2268, -425, -1189, 1476, 3203, -1903, -837, 9679, + 7057, -626, -221, -42, -5718, -3039, 372, 163, + -97, -1892, 1124, 494, -1380, 819, 360, -4169, + 213, -655, 17015, 620, -384, -2, -26, -17671, + -23, -9, 8, -221, 681, -8, 24, -644, + 5, -15, 399, 14, 5088, 35, -3339, 3726, + 8488, -1580, 0, -680, -847, -4397, -10, 1037, + 7, -1157, -8, 759, -2636, -18, 1730, -1930, + -988, 1454, -2688, 15039, 2682, -59, -129, -441, + -13805, -439, 87, -162, 238, 907, -1335, 2467, + 161, -238, 440, -2462, -4865, -2842, -53, 5495, + 6523, -1445, -493, 0, -1843, -2597, -844, -16, + -9, 1632, 953, 18, 1937, 1131, 21, -2188, + 3076, 15069, -2914, 1810, -971, -577, -13860, -518, + -200, -57, -2829, 547, 2680, -339, -1665, 322, + 182, 893, -172, 107, 1311, 5355, 11054, 2299, + -3654, -105, -1750, -7458, -322, -814, -428, -885, + -3613, -184, -751, -1551, 292, 1194, 2465, 512, + 4035, 5619, 4618, 1815, 1912, -994, -1927, -1301, + -201, -223, -1384, -1137, -1583, -447, -622, -511, + -471, -656, -539, -211, -2131, 2754, -4501, 12879, + 7432, -277, -463, -1236, -10124, -3371, 358, -585, + 756, 1675, -2165, 3538, 967, -1249, 2042, -5842, + 5618, -515, 3219, -4149, 4857, -1926, -16, -632, + -1050, -1440, 176, -1104, 101, 1422, -130, 815, + -1666, 152, -954, 1230, 1838, -1709, 1139, 16867, + 716, -206, -178, -79, -17366, -31, 191, -127, + 118, -1892, 1759, -1173, -80, 74, -49, -737, + 1978, -3845, 10050, 11854, -2492, -238, -902, -6164, + -8576, -379, 464, -1213, 2358, -1431, 2782, -7271, + 301, -585, 1529, 1803, -2600, 11246, 11289, -3647, + 1463, -412, -7720, -7778, -812, -130, 1784, 1791, + -7749, -578, 2504, 2513, 232, -1004, -1008, 325, + 3442, 907, 2725, 8970, 3638, -723, -50, -453, + -4911, -808, -190, -572, -150, -1884, -496, -1492, + -764, -201, -605, -1992, -126, 17498, 3481, -2003, + 1090, 0, -18689, -739, -244, -72, 135, 26, + -3717, -15, 2139, 425, 8, -1165, -231, 133, + -1814, 1048, -2164, 4070, 16272, -200, -67, -285, + -1011, -16160, 116, -239, 138, 450, -260, 537, + 1801, -1041, 2149, -4042, 9354, 12580, -1883, 962, + -617, -5341, -9660, -216, -56, -23, -7183, 1075, + 1446, -549, -738, 110, 352, 474, -71, 36, + 1708, 4199, 7387, 6335, 1003, -178, -1076, -3330, + -2449, -61, -437, -770, -1893, -660, -1623, -2856, + -104, -257, -452, -388, -2624, 5623, 17310, -2353, + 592, -420, -1930, -18288, -338, -21, 900, 2772, + -5941, -376, 807, 2486, 94, -203, -625, 85, + 1211, -850, 1193, -1926, 15992, -89, -44, -86, + -226, -15609, 62, -88, 61, 142, -100, 140, + -1182, 830, -1165, 1880, 3983, -2054, 11506, -19, + 3622, -968, -257, -8080, 0, -801, 499, -2797, + 1442, 4, -2, 13, -880, 454, -2544, 4, + -786, -1354, 16092, 7246, -1665, -37, -111, -15805, + -3205, -169, -65, 772, 1330, 348, 599, -7117, + -80, -137, 1636, 736, -4316, -511, 6674, 11665, + 4633, -1137, -15, -2719, -8305, -1310, -134, 1758, + 208, 3073, 364, -4752, 1220, 144, -1887, -3299, + 7912, 4557, 1937, 1885, 7037, -3821, -1267, -229, + -216, -3022, -2200, -935, -538, -910, -524, -222, + -3398, -1957, -832, -809, 3434, 2967, 5867, 8196, + 8766, -720, -537, -2101, -4100, -4690, -622, -1230, + -1062, -1718, -1484, -2935, -1837, -1588, -3139, -4385, + 5881, 9176, 8119, 3934, 3355, -2111, -5139, -4023, + -944, -687, -3294, -2914, -4547, -1412, -2203, -1949, + -1204, -1879, -1662, -805 +}; + +const int16_t ff_g723_1_adaptive_cb_gain170[170 * 20] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 776, 212, 715, 670, + 809, -36, -2, -31, -27, -39, -10, -33, + -9, -31, -8, -29, -38, -10, -35, -33, + 1296, 1316, -168, -320, -815, -102, -105, -1, + -6, -40, -104, 13, 13, 25, 25, -3, + 64, 65, -8, -15, -589, 680, 2478, 308, + -596, -21, -28, -375, -5, -21, 24, 89, + -102, 11, -12, -46, -21, 24, 90, 11, + -735, -487, -5, 2948, 468, -33, -14, 0, + -530, -13, -21, 0, 0, 132, 87, 0, + 21, 13, 0, -84, 1042, 1730, 1068, 333, + 626, -66, -182, -69, -6, -23, -110, -67, + -112, -21, -35, -21, -39, -66, -40, -12, + 486, -769, 4074, 2825, -1107, -14, -36, -1013, + -487, -74, 22, -120, 191, -83, 132, -702, + 32, -52, 275, 191, 1521, -767, -124, 4320, + 1026, -141, -35, 0, -1139, -64, 71, 11, + -5, -401, 202, 32, -95, 48, 7, -270, + 2425, 1267, 3439, -91, -1166, -359, -98, -722, + 0, -83, -187, -509, -266, 13, 7, 19, + 172, 90, 244, -6, -1251, 975, 173, 4039, + 2005, -95, -58, -1, -996, -245, 74, 13, + -10, 308, -240, -42, 153, -119, -21, -494, + 1820, 632, 1322, 2062, 1031, -202, -24, -106, + -259, -64, -70, -146, -51, -229, -79, -166, + -114, -39, -83, -129, -447, 4904, 244, -315, + -2038, -12, -1467, -3, -6, -253, 134, 6, + -73, -8, 94, 4, -55, 610, 30, -39, + -208, -1102, 463, -448, 5653, -2, -74, -13, + -12, -1950, -14, 5, 31, -5, -30, 12, + 71, 380, -159, 154, 4739, 2600, -1864, 856, + -1554, -1371, -412, -212, -44, -147, -752, 539, + 295, -247, -135, 97, 449, 246, -176, 81, + 1894, 3533, 35, -26, 2145, -219, -762, 0, + 0, -280, -408, -4, -7, 3, 5, 0, + -248, -462, -4, 3, -2699, 1841, 4072, 2443, + 1582, -444, -207, -1012, -364, -152, 303, 670, + -457, 402, -274, -607, 260, -177, -393, -236, + -844, 3358, 6106, -1059, -537, -43, -688, -2275, + -68, -17, 173, 314, -1251, -54, 217, 395, + -27, 110, 200, -34, 1251, 1016, 3020, 2210, + 1445, -95, -63, -556, -298, -127, -77, -230, + -187, -168, -137, -407, -110, -89, -266, -194, + 2099, 2277, 4038, 3533, -2870, -269, -316, -995, + -762, -503, -291, -517, -561, -452, -491, -871, + 367, 399, 707, 619, 400, -1114, 8516, 2422, + -1117, -9, -75, -4426, -358, -76, 27, -208, + 579, -59, 164, -1259, 27, -75, 580, 165, + -4398, -2011, 3912, -2407, 2258, -1180, -247, -934, + -353, -311, -540, 1050, 480, -646, -295, 575, + 606, 277, -539, 331, 1767, -1447, 4240, 6160, + -757, -190, -127, -1097, -2316, -35, 156, -457, + 374, -664, 544, -1594, 81, -66, 195, 284, + 1594, -1463, 1035, 6938, 1920, -155, -130, -65, + -2938, -225, 142, -100, 92, -675, 619, -438, + -186, 171, -121, -813, -562, 4716, 4085, -591, + 2421, -19, -1357, -1018, -21, -357, 162, 140, + -1175, -20, 170, 147, 83, -696, -603, 87, + 1552, 8778, -935, 354, -1424, -147, -4703, -53, + -7, -123, -831, 88, 501, -33, -189, 20, + 134, 763, -81, 30, 4831, -4431, 41, -1479, + -2976, -1424, -1198, 0, -133, -540, 1306, -12, + 11, 436, -400, 3, 877, -804, 7, -268, + 2090, 1192, 1006, 1645, 4853, -266, -86, -61, + -165, -1437, -152, -128, -73, -210, -119, -101, + -619, -353, -298, -487, 2386, 5712, 1426, -94, + 1350, -347, -1991, -124, 0, -111, -832, -207, + -497, 13, 32, 8, -196, -470, -117, 7, + -1349, 1091, 1659, 8891, 313, -111, -72, -168, + -4825, -5, 89, 136, -110, 732, -592, -900, + 25, -20, -31, -170, 9980, 916, -381, -808, + 88, -6080, -51, -8, -39, 0, -558, 232, + 21, 492, 45, -18, -53, -4, 2, 4, + 2338, -1031, -248, 3928, 6484, -333, -64, -3, + -942, -2566, 147, 35, -15, -560, 247, 59, + -925, 408, 98, -1555, 6166, -1240, -337, 3672, + -1277, -2320, -93, -6, -823, -99, 466, 126, + -25, -1382, 278, 75, 480, -96, -26, 286, + 4377, -132, -2588, 1701, 4865, -1169, -1, -409, + -176, -1444, 35, 691, -20, -454, 13, 268, + -1299, 39, 768, -505, 2594, 3295, 3944, 1481, + 682, -410, -662, -949, -133, -28, -521, -624, + -793, -234, -297, -356, -108, -137, -164, -61, + 4151, 624, 815, 4485, 2229, -1052, -23, -40, + -1228, -303, -158, -206, -31, -1136, -170, -223, + -565, -84, -111, -610, -3575, -361, 4924, 2791, + 4698, -780, -7, -1480, -475, -1347, -78, 1074, + 108, 609, 61, -839, 1025, 103, -1412, -800, + -2518, 3791, 8623, 315, 2465, -387, -877, -4538, + -6, -370, 582, 1325, -1995, 48, -73, -166, + 378, -570, -1297, -47, -691, 2989, 9957, -421, + -1142, -29, -545, -6051, -10, -79, 126, 420, + -1817, -17, 76, 256, -48, 208, 694, -29, + -1918, 104, -3190, -3410, -4440, -224, 0, -621, + -709, -1203, 12, -373, 20, -399, 21, -664, + -519, 28, -864, -924, -3359, -1668, 1854, 6939, + 1430, -688, -169, -209, -2939, -124, -341, 380, + 188, 1422, 706, -785, 293, 145, -161, -606, + 42, 9706, 3164, -952, 907, 0, -5750, -611, + -55, -50, -25, -8, -1874, 2, 564, 183, + -2, -537, -175, 52, 1607, 785, 2862, 4327, + 3307, -157, -37, -500, -1143, -667, -77, -280, + -137, -424, -207, -756, -324, -158, -577, -873, + 6801, 3416, 2227, 1682, -3217, -2823, -712, -302, + -172, -631, -1418, -924, -464, -698, -350, -228, + 1335, 670, 437, 330, 3459, 3898, 364, 7841, + -2640, -730, -927, -8, -3753, -425, -823, -76, + -86, -1655, -1865, -174, 557, 628, 58, 1263, + -5902, -3458, -2465, -1886, 4334, -2126, -730, -371, + -217, -1146, -1245, -888, -520, -679, -398, -283, + 1561, 915, 652, 499, -3710, 1133, 7849, 3443, + -215, -840, -78, -3760, -723, -2, 256, 1777, + -543, 779, -238, -1649, -48, 14, 103, 45, + 4132, 2828, 2, -4212, -4116, -1042, -488, 0, + -1083, -1034, -713, 0, 0, 1062, 727, 0, + 1038, 710, 0, -1058, 5875, 8496, -1796, 1376, + -1786, -2107, -4406, -197, -115, -194, -3047, 644, + 931, -493, -713, 150, 640, 926, -195, 150, + 3143, 3483, 3546, -793, 4489, -603, -740, -767, + -38, -1230, -668, -680, -754, 152, 168, 171, + -861, -954, -971, 217, 2845, 7965, 3695, -5432, + 3978, -494, -3873, -833, -1801, -966, -1383, -641, + -1796, 943, 2641, 1225, -691, -1934, -897, 1319, + 1538, 150, 7139, 2049, 3097, -144, -1, -3110, + -256, -585, -14, -670, -65, -192, -18, -892, + -290, -28, -1349, -387, 618, 7520, 4729, -238, + -3373, -23, -3452, -1365, -3, -694, -283, -178, + -2170, 8, 109, 68, 127, 1548, 973, -49, + 2965, -3013, 7912, 7076, -1997, -536, -554, -3821, + -3056, -243, 545, -1431, 1455, -1280, 1301, -3417, + 361, -367, 964, 862, 2443, -929, -1113, 9677, + 4138, -364, -52, -75, -5716, -1045, 138, 166, + -63, -1443, 549, 657, -617, 234, 281, -2444, + 1966, 3309, 10085, -3399, 2105, -236, -668, -6207, + -705, -270, -397, -1210, -2037, 408, 686, 2092, + -252, -425, -1295, 436, -112, -1368, 8868, 4822, + 2048, 0, -114, -4800, -1419, -256, -9, 61, + 740, 33, 402, -2610, 14, 171, -1108, -602, + -2597, 438, -1839, 6229, 7266, -411, -11, -206, + -2368, -3223, 69, -291, 49, 987, -166, 699, + 1152, -194, 816, -2763, 3454, 553, 9127, 4946, + -5596, -728, -18, -5084, -1493, -1911, -116, -1924, + -308, -1042, -166, -2755, 1179, 188, 3117, 1689, + -532, -663, 12262, 2495, -1004, -17, -26, -9177, + -380, -61, -21, 398, 496, 81, 101, -1867, + -32, -40, 751, 152, -2100, 1317, -1509, 11425, + 2997, -269, -105, -139, -7967, -548, 168, -193, + 121, 1464, -918, 1052, 384, -240, 276, -2090, + 1193, -2697, 11259, 5373, -763, -86, -444, -7737, + -1762, -35, 196, -819, 1853, -391, 884, -3692, + 55, -125, 525, 250, 2405, -471, 11079, 203, + 782, -353, -13, -7491, -2, -37, 69, -1626, + 318, -29, 5, -137, -114, 22, -529, -9, + -1871, 5685, 11290, -2662, 1353, -213, -1972, -7780, + -432, -111, 649, 1289, -3917, -304, 923, 1834, + 154, -469, -932, 220, -3768, 5927, -3093, 5041, + 5212, -866, -2144, -584, -1551, -1658, 1363, -711, + 1119, 1159, -1824, 951, 1198, -1885, 984, -1603, + -2546, 9502, 5969, -2440, 1928, -395, -5511, -2175, + -363, -226, 1477, 927, -3462, -379, 1415, 889, + 299, -1118, -702, 287, -4963, 3568, 4592, 5508, + 3451, -1503, -777, -1287, -1851, -727, 1080, 1391, + -1000, 1668, -1199, -1543, 1045, -751, -967, -1160, + 1745, -2586, 3983, 10899, -1551, -186, -408, -968, + -7250, -146, 275, -424, 628, -1161, 1720, -2649, + 165, -244, 377, 1032, 867, -456, -727, 3369, + 11822, -45, -12, -32, -692, -8531, 24, 38, + -20, -178, 93, 149, -625, 329, 525, -2431, + 7535, 2422, 1926, 1405, 1599, -3466, -358, -226, + -120, -156, -1114, -886, -284, -646, -207, -165, + -735, -236, -188, -137, 1041, -735, -142, 13209, + 1515, -66, -33, -1, -10649, -140, 46, 9, + -6, -839, 593, 114, -96, 68, 13, -1222, + 7950, 6745, -1444, -1008, 2721, -3857, -2777, -127, + -62, -452, -3273, 700, 594, 489, 415, -88, + -1320, -1120, 239, 167, -4754, -1379, 4522, -578, + -5733, -1379, -116, -1248, -20, -2006, -400, 1312, + 380, -167, -48, 159, -1663, -482, 1582, -202, + 3220, 5978, 5923, 2430, -2689, -633, -2181, -2141, + -360, -441, -1175, -1164, -2161, -477, -886, -878, + 528, 981, 972, 398, 377, 1312, 13978, -1470, + 677, -8, -105, -11925, -132, -28, -30, -321, + -1119, 33, 117, 1254, -15, -54, -577, 60, + -3435, 6770, 314, -885, 5686, -720, -2797, -6, + -47, -1973, 1419, 65, -129, -185, 366, 16, + 1192, -2349, -109, 307, 3171, 8774, -2260, 2679, + 3069, -613, -4699, -312, -438, -575, -1698, 437, + 1210, -518, -1435, 369, -594, -1643, 423, -501, + 5557, 1509, 5407, -125, -7386, -1884, -139, -1784, + 0, -3330, -511, -1834, -498, 42, 11, 41, + 2505, 680, 2438, -56, -2838, 2595, 13228, 271, + 1793, -491, -411, -10680, -4, -196, 449, 2291, + -2095, 47, -42, -219, 310, -284, -1447, -29, + 664, -278, 14966, 951, -711, -26, -4, -13672, + -55, -30, 11, -606, 253, -38, 16, -869, + 28, -12, 650, 41, 808, 1770, 8658, 5863, + -1486, -39, -191, -4576, -2098, -134, -87, -427, + -935, -289, -633, -3098, 73, 160, 785, 531, + 3063, 1539, 2000, -542, 9576, -572, -144, -244, + -17, -5597, -287, -374, -188, 101, 51, 66, + -1790, -900, -1169, 317, 514, 14083, -323, 896, + -891, -16, -12106, -6, -49, -48, -442, 10, + 277, -28, -770, 17, 27, 766, -17, 48, + 892, 158, 5237, 11057, -1603, -48, -1, -1674, + -7462, -156, -8, -285, -50, -602, -106, -3534, + 87, 15, 512, 1082, -1612, 2564, -4296, 12526, + 5710, -158, -401, -1126, -9576, -1990, 252, -422, + 672, 1232, -1960, 3284, 561, -893, 1497, -4365, + 4889, -6878, 612, 6109, 4753, -1459, -2887, -22, + -2277, -1379, 2052, -182, 257, -1823, 2564, -228, + -1418, 1995, -177, -1772, 3053, -506, 2403, 9625, + 1322, -569, -15, -352, -5655, -106, 94, -448, + 74, -1794, 297, -1412, -246, 40, -194, -777, + -754, 12904, 4480, -2113, 1471, -34, -10163, -1225, + -272, -132, 594, 206, -3529, -97, 1664, 577, + 67, -1159, -402, 189, 4255, 1476, 5055, 2393, + 2912, -1105, -132, -1559, -349, -517, -383, -1313, + -455, -621, -215, -738, -756, -262, -898, -425, + -1371, 535, 1417, 14604, -997, -114, -17, -122, + -13017, -60, 44, 118, -46, 1222, -477, -1263, + -83, 32, 86, 888, 5368, -1744, 4083, -1236, + 3753, -1758, -185, -1017, -93, -860, 571, -1338, + 434, 405, -131, 308, -1229, 399, -935, 283, + 1588, -3097, 14415, 3699, -1171, -154, -585, -12683, + -835, -83, 300, -1397, 2725, -358, 699, -3255, + 113, -221, 1030, 264, 212, 7989, 9471, -3344, + 2009, -2, -3895, -5475, -682, -246, -103, -123, + -4618, 43, 1630, 1933, -26, -979, -1161, 410, + 856, 2294, -627, 6930, 6929, -44, -321, -24, + -2931, -2930, -119, 32, 87, -362, -970, 265, + -362, -970, 265, -2931, 2357, -4187, 7162, 7683, + 3371, -339, -1070, -3131, -3603, -693, 602, -1030, + 1830, -1105, 1963, -3359, -485, 861, -1474, -1581, + 350, 4585, 14053, -3819, 1218, -7, -1283, -12054, + -890, -90, -97, -300, -3933, 81, 1068, 3275, + -26, -341, -1045, 284, -3248, 3531, 475, 2137, + 11711, -644, -761, -13, -278, -8372, 700, 94, + -102, 423, -460, -62, 2322, -2524, -340, -1528, + -3017, 3852, 1725, 8440, 5257, -555, -905, -181, + -4348, -1686, 709, 317, -405, 1554, -1984, -889, + 968, -1236, -553, -2708, -909, 3196, 15512, -2528, + 1066, -50, -623, -14686, -390, -69, 177, 861, + -3026, -140, 493, 2393, 59, -208, -1009, 164, + 959, -3370, 9617, 9545, -1761, -56, -693, -5645, + -5561, -189, 197, -563, 1978, -558, 1963, -5603, + 103, -362, 1034, 1026, 7575, 11796, -4845, 3252, + -1703, -3502, -8493, -1433, -645, -177, -5454, 2240, + 3488, -1503, -2341, 961, 787, 1226, -503, 338, + 6409, 1722, 1764, -4191, 6015, -2507, -181, -189, + -1072, -2208, -673, -690, -185, 1639, 440, 451, + -2353, -632, -647, 1538, -2420, 12161, 5038, 1286, + -2098, -357, -9027, -1549, -100, -268, 1796, 744, + -3740, 190, -954, -395, -310, 1557, 645, 164, + -2232, -1341, 7246, 9470, -1977, -304, -109, -3204, + -5474, -238, -182, 987, 593, 1290, 775, -4188, + -269, -161, 874, 1143, 1030, 7034, 4231, 1551, + 3077, -64, -3019, -1093, -146, -577, -442, -266, + -1816, -97, -666, -400, -193, -1321, -794, -291, + 5121, 11835, -477, -1749, 2298, -1601, -8549, -13, + -186, -322, -3699, 149, 344, 546, 1264, -50, + -718, -1660, 66, 245, -3328, 3827, 5921, 9976, + -1045, -676, -894, -2140, -6075, -66, 777, 1203, + -1383, 2027, -2330, -3605, -212, 244, 377, 636, + 3813, 5718, -4666, -3412, 5674, -887, -1995, -1329, + -710, -1965, -1331, 1086, 1628, 794, 1191, -972, + -1320, -1980, 1616, 1181, 1348, -3672, 13154, 6938, + -1690, -110, -823, -10561, -2938, -174, 302, -1082, + 2948, -570, 1555, -5570, 139, -379, 1357, 716, + 2151, -3586, 6949, 12131, -1224, -282, -785, -2947, + -8982, -91, 470, -912, 1521, -1592, 2655, -5145, + 160, -268, 519, 906, -2889, 9647, 10276, -2728, + 995, -509, -5680, -6445, -454, -60, 1701, 1812, + -6051, -481, 1606, 1711, 175, -586, -624, 165, + 6177, 2184, 555, 1985, 6589, -2329, -291, -18, + -240, -2650, -823, -209, -74, -748, -264, -67, + -2484, -878, -223, -798, -492, 391, 17166, -681, + 240, -14, -9, -17987, -28, -3, 11, 515, + -410, -20, 16, 713, 7, -5, -252, 10, + 12628, 5448, -2630, 3011, -2695, -9733, -1811, -422, + -553, -443, -4199, 2027, 874, -2321, -1001, 483, + 2077, 896, -432, 495, -3628, -534, 3447, 7002, + 6751, -803, -17, -725, -2992, -2782, -118, 763, + 112, 1550, 228, -1473, 1495, 220, -1420, -2885, + -5239, 5901, 8107, 3650, 4846, -1675, -2125, -4012, + -813, -1433, 1887, 2592, -2920, 1167, -1315, -1806, + 1550, -1745, -2398, -1080, 6157, 6678, 4099, -1074, + 2348, -2314, -2722, -1025, -70, -336, -2509, -1540, + -1670, 403, 437, 268, -882, -957, -587, 153, + 1079, 16099, 242, -881, 1690, -71, -15820, -3, + -47, -174, -1060, -16, -238, 58, 865, 13, + -111, -1661, -25, 90, -278, 227, -1039, 1636, + 16945, -4, -3, -65, -163, -17526, 3, -17, + 14, 27, -22, 103, 287, -234, 1074, -1693, + 15778, -1454, 574, -603, -107, -15195, -129, -20, + -22, 0, 1400, -553, 51, 581, -53, 21, + 103, -9, 3, -3, 2406, -836, 13224, 7993, + -4266, -353, -42, -10673, -3899, -1111, 122, -1942, + 674, -1174, 407, -6451, 626, -217, 3443, 2081, + 3184, 14368, -3336, 2255, -1801, -619, -12600, -679, + -310, -198, -2793, 648, 2926, -438, -1977, 459, + 350, 1580, -366, 247, -1698, 17076, 2504, -539, + -646, -176, -17798, -382, -17, -25, 1770, 259, + -2610, -55, 561, 82, -67, 673, 98, -21, + 2375, -797, -2696, 14483, 5383, -344, -38, -443, + -12803, -1769, 115, 391, -131, -2100, 705, 2384, + -780, 262, 886, -4759, -2691, 2554, -4520, 9573, + 10655, -442, -398, -1247, -5594, -6930, 419, -742, + 704, 1572, -1492, 2641, 1750, -1661, 2939, -6226, + -4332, -4399, -1657, 4880, 7375, -1145, -1181, -167, + -1453, -3319, -1163, -438, -444, 1290, 1310, 493, + 1950, 1980, 745, -2196, -3498, 7405, 9955, 2693, + -2971, -746, -3347, -6049, -442, -538, 1581, 2125, + -4499, 575, -1217, -1636, -634, 1342, 1805, 488, + 6717, -3792, 7739, 2798, 3489, -2754, -877, -3655, + -477, -743, 1554, -3173, 1791, -1147, 647, -1321, + -1430, 807, -1648, -595, 5263, 9770, 3463, 1069, + -3971, -1690, -5826, -732, -69, -962, -3138, -1112, + -2065, -343, -637, -226, 1275, 2368, 839, 259, + 1243, -2634, 16772, 1871, 332, -94, -423, -17169, + -213, -6, 199, -1273, 2696, -142, 300, -1915, + -25, 53, -339, -37, 2691, 2836, 3105, 5711, + 4817, -442, -491, -588, -1991, -1416, -465, -510, + -537, -938, -988, -1082, -791, -834, -913, -1679, + 4366, 2944, 7210, 3627, 1161, -1163, -529, -3172, + -803, -82, -784, -1921, -1295, -966, -651, -1596, + -309, -208, -511, -257, 13888, 3951, -671, -2305, + 3354, -11773, -953, -27, -324, -686, -3349, 569, + 161, 1954, 556, -94, -2843, -809, 137, 472, + 7053, 5847, 2929, 8378, -4794, -3036, -2086, -523, + -4284, -1403, -2517, -1261, -1045, -3607, -2990, -1498, + 2064, 1711, 857, 2451, -2191, 12838, 9182, -3915, + 1617, -293, -10059, -5146, -935, -159, 1717, 1228, + -7195, -523, 3068, 2194, 216, -1267, -906, 386, + -4881, 13114, 5767, -435, 4155, -1454, -10498, -2030, + -11, -1054, 3907, 1718, -4616, -129, 348, 153, + 1238, -3326, -1462, 110, 7843, -1250, 210, 7106, + -5203, -3754, -95, -2, -3082, -1652, 598, -100, + 16, -3402, 542, -91, 2491, -397, 66, 2257, + -2463, 8168, 14551, -3908, 1828, -370, -4072, -12923, + -932, -204, 1228, 2188, -7254, -587, 1948, 3471, + 274, -911, -1623, 436, -1579, 347, -272, -2735, + 16031, -152, -7, -4, -456, -15686, 33, -26, + 5, -263, 58, -45, 1545, -340, 266, 2676, + -6327, 1328, 5093, -5079, 7617, -2443, -107, -1583, + -1574, -3541, 513, 1967, -413, -1961, 411, 1578, + 2941, -617, -2367, 2361, 3286, -4509, 11306, 11025, + -2623, -659, -1241, -7802, -7419, -420, 904, -2267, + 3112, -2211, 3034, -7608, 526, -722, 1810, 1765, + 5567, 17853, -3754, 1166, -519, -1892, -19455, -860, + -83, -16, -6067, 1275, 4090, -396, -1271, 267, + 176, 566, -119, 37, -2136, -424, 15292, 5108, + -1648, -278, -10, -14273, -1593, -165, -55, 1993, + 396, 666, 132, -4768, -214, -42, 1538, 514, + 2267, -3297, 2549, 16563, -791, -313, -663, -396, + -16745, -38, 456, -352, 513, -2291, 3333, -2576, + 109, -159, 123, 799, 3655, 1899, -3364, 6279, + 12510, -815, -220, -690, -2406, -9552, -423, 750, + 390, -1400, -728, 1289, -2791, -1450, 2568, -4794, + 8052, 2285, -6193, 5138, 6003, -3957, -318, -2341, + -1611, -2199, -1123, 3044, 864, -2525, -716, 1942, + -2950, -837, 2269, -1882, -386, -2291, 7679, 15387, + -2723, -9, -320, -3599, -14452, -452, -54, 181, + 1074, 362, 2152, -7212, -64, -380, 1276, 2557, + 2777, -1173, 3984, 13079, 2508, -470, -84, -969, + -10440, -384, 198, -675, 285, -2217, 936, -3180, + -425, 179, -610, -2002, -1879, 1771, -2684, 16705, + 1833, -215, -191, -439, -17032, -205, 203, -308, + 290, 1916, -1805, 2736, 210, -198, 300, -1869, + 1052, 4495, 15519, 1467, -4032, -67, -1233, -14700, + -131, -992, -288, -997, -4257, -94, -402, -1389, + 259, 1106, 3819, 361, 3010, 2544, 6969, 7559, + 1996, -553, -395, -2964, -3487, -243, -467, -1280, + -1082, -1388, -1174, -3215, -366, -310, -849, -921, + -5209, -1867, 8713, 10351, 1549, -1656, -212, -4634, + -6540, -146, -593, 2770, 993, 3291, 1180, -5505, + 492, 176, -824, -979, -4314, 8513, 913, 7547, + -2723, -1135, -4423, -50, -3476, -452, 2241, 240, + -474, 1987, -3921, -420, -717, 1415, 151, 1254, + 12929, -1219, 2448, 1757, 6303, -10204, -90, -365, + -188, -2425, 962, -1932, 182, -1386, 130, -262, + -4974, 469, -941, -676, 6465, 4132, 3167, 3160, + 5697, -2551, -1042, -612, -609, -1981, -1630, -1249, + -798, -1247, -797, -611, -2248, -1437, -1101, -1099, + -3636, 4859, 18914, -1335, 810, -807, -1441, -21836, + -108, -40, 1078, 4198, -5609, -296, 396, 1541, + 179, -240, -936, 66, 8844, 7864, 654, -4063, + -5680, -4774, -3774, -26, -1007, -1969, -4245, -353, + -314, 2193, 1950, 162, 3066, 2726, 226, -1408, + 1859, 2634, 9228, 996, 9464, -211, -423, -5197, + -60, -5467, -299, -1047, -1483, -113, -160, -561, + -1074, -1521, -5330, -575, 2949, 12260, 10290, -497, + -3943, -530, -9174, -6463, -15, -949, -2206, -1852, + -7700, 89, 372, 312, 709, 2950, 2476, -119, + -2903, 1552, 14867, 9970, -496, -514, -147, -13491, + -6068, -15, 275, 2634, -1408, 1766, -944, -9047, + -87, 47, 450, 302, 3243, 8234, 7586, 3373, + 2151, -642, -4138, -3512, -694, -282, -1630, -1501, + -3812, -667, -1695, -1561, -425, -1081, -996, -442, + -9631, 60, 3501, 5359, 10150, -5662, 0, -748, + -1752, -6288, 35, 2058, -12, 3150, -19, -1145, + 5967, -37, -2169, -3320, -6874, -2553, -5446, -2195, + -7841, -2884, -397, -1810, -294, -3753, -1071, -2285, + -848, -921, -342, -729, -3290, -1221, -2606, -1050, + -3413, -1141, 4630, 13612, 7897, -711, -79, -1308, + -11310, -3806, -237, 964, 322, 2836, 948, -3847, + 1645, 550, -2231, -6561, 4410, -5678, 8006, -3992, + 3811, -1187, -1968, -3912, -973, -886, 1528, -2155, + 2775, 1074, -1383, 1951, -1025, 1321, -1862, 928, + 5659, 11535, 2203, -452, 7169, -1954, -8121, -296, + -12, -3137, -3984, -761, -1551, 156, 318, 60, + -2476, -5048, -964, 197, 2914, -2914, 3485, -3965, + 13675, -518, -518, -741, -959, -11414, 518, -620, + 620, 705, -705, 843, -2433, 2432, -2909, 3310, + 7843, 1907, 1022, 8882, 7972, -3755, -222, -63, + -4815, -3879, -913, -489, -119, -4252, -1034, -554, + -3816, -928, -497, -4322, 13807, 9531, 1436, 1612, + 1779, -11636, -5544, -125, -158, -193, -8032, -1210, + -835, -1358, -938, -141, -1499, -1035, -156, -175, + 13620, -5337, 5450, -2263, 1723, -11322, -1738, -1813, + -312, -181, 4436, -4531, 1775, 1881, -737, 752, + -1432, 561, -573, 238, 5297, 8374, 8872, 7694, + 6538, -1712, -4280, -4804, -3613, -2609, -2707, -2868, + -4534, -2487, -3932, -4166, -2113, -3341, -3540, -3070 +}; + int ff_g723_1_scale_vector(int16_t *dst, const int16_t *vector, int length) { int bits, max = 0; @@ -98,9 +1169,9 @@ void ff_g723_1_gen_acb_excitation(int16_t *vector, int16_t *prev_excitation, /* Select quantization table */ if (cur_rate == RATE_6300 && pitch_lag < SUBFRAME_LEN - 2) { - cb_ptr = adaptive_cb_gain85; + cb_ptr = ff_g723_1_adaptive_cb_gain85; } else - cb_ptr = adaptive_cb_gain170; + cb_ptr = ff_g723_1_adaptive_cb_gain170; /* Calculate adaptive vector */ cb_ptr += subfrm->ad_cb_gain * 20; @@ -125,8 +1196,8 @@ static void lsp2lpc(int16_t *lpc) for (j = 0; j < LPC_ORDER; j++) { int index = (lpc[j] >> 7) & 0x1FF; int offset = lpc[j] & 0x7f; - int temp1 = cos_tab[index] * (1 << 16); - int temp2 = (cos_tab[index + 1] - cos_tab[index]) * + int temp1 = ff_g723_1_cos_tab[index] * (1 << 16); + int temp2 = (ff_g723_1_cos_tab[index + 1] - ff_g723_1_cos_tab[index]) * (((offset << 8) + 0x80) << 1); lpc[j] = -(av_sat_dadd32(1 << 15, temp1 + temp2) >> 16); @@ -215,16 +1286,16 @@ void ff_g723_1_inverse_quant(int16_t *cur_lsp, int16_t *prev_lsp, } /* Get the VQ table entry corresponding to the transmitted index */ - cur_lsp[0] = lsp_band0[lsp_index[0]][0]; - cur_lsp[1] = lsp_band0[lsp_index[0]][1]; - cur_lsp[2] = lsp_band0[lsp_index[0]][2]; - cur_lsp[3] = lsp_band1[lsp_index[1]][0]; - cur_lsp[4] = lsp_band1[lsp_index[1]][1]; - cur_lsp[5] = lsp_band1[lsp_index[1]][2]; - cur_lsp[6] = lsp_band2[lsp_index[2]][0]; - cur_lsp[7] = lsp_band2[lsp_index[2]][1]; - cur_lsp[8] = lsp_band2[lsp_index[2]][2]; - cur_lsp[9] = lsp_band2[lsp_index[2]][3]; + cur_lsp[0] = ff_g723_1_lsp_band0[lsp_index[0]][0]; + cur_lsp[1] = ff_g723_1_lsp_band0[lsp_index[0]][1]; + cur_lsp[2] = ff_g723_1_lsp_band0[lsp_index[0]][2]; + cur_lsp[3] = ff_g723_1_lsp_band1[lsp_index[1]][0]; + cur_lsp[4] = ff_g723_1_lsp_band1[lsp_index[1]][1]; + cur_lsp[5] = ff_g723_1_lsp_band1[lsp_index[1]][2]; + cur_lsp[6] = ff_g723_1_lsp_band2[lsp_index[2]][0]; + cur_lsp[7] = ff_g723_1_lsp_band2[lsp_index[2]][1]; + cur_lsp[8] = ff_g723_1_lsp_band2[lsp_index[2]][2]; + cur_lsp[9] = ff_g723_1_lsp_band2[lsp_index[2]][3]; /* Add predicted vector & DC component to the previously quantized vector */ for (i = 0; i < LPC_ORDER; i++) { diff --git a/libavcodec/g723_1.h b/libavcodec/g723_1.h index d60d481e6..521f220b2 100644 --- a/libavcodec/g723_1.h +++ b/libavcodec/g723_1.h @@ -221,11 +221,6 @@ void ff_g723_1_inverse_quant(int16_t *cur_lsp, int16_t *prev_lsp, static const uint8_t frame_size[4] = { 24, 20, 4, 1 }; -/** - * Postfilter gain weighting factors scaled by 2^15 - */ -static const int16_t ppf_gain_weight[2] = {0x1800, 0x2000}; - /** * LSP DC component */ @@ -243,1202 +238,30 @@ static const int16_t dc_lsp[LPC_ORDER] = { }; /* Cosine table scaled by 2^14 */ -static const int16_t cos_tab[COS_TBL_SIZE + 1] = { - 16384, 16383, 16379, 16373, 16364, 16353, 16340, 16324, - 16305, 16284, 16261, 16235, 16207, 16176, 16143, 16107, - 16069, 16029, 15986, 15941, 15893, 15843, 15791, 15736, - 15679, 15619, 15557, 15493, 15426, 15357, 15286, 15213, - 15137, 15059, 14978, 14896, 14811, 14724, 14635, 14543, - 14449, 14354, 14256, 14155, 14053, 13949, 13842, 13733, - 13623, 13510, 13395, 13279, 13160, 13039, 12916, 12792, - 12665, 12537, 12406, 12274, 12140, 12004, 11866, 11727, - 11585, 11442, 11297, 11151, 11003, 10853, 10702, 10549, - 10394, 10238, 10080, 9921, 9760, 9598, 9434, 9269, - 9102, 8935, 8765, 8595, 8423, 8250, 8076, 7900, - 7723, 7545, 7366, 7186, 7005, 6823, 6639, 6455, - 6270, 6084, 5897, 5708, 5520, 5330, 5139, 4948, - 4756, 4563, 4370, 4176, 3981, 3786, 3590, 3393, - 3196, 2999, 2801, 2603, 2404, 2205, 2006, 1806, - 1606, 1406, 1205, 1005, 804, 603, 402, 201, - 0, -201, -402, -603, -804, -1005, -1205, -1406, - -1606, -1806, -2006, -2205, -2404, -2603, -2801, -2999, - -3196, -3393, -3590, -3786, -3981, -4176, -4370, -4563, - -4756, -4948, -5139, -5330, -5520, -5708, -5897, -6084, - -6270, -6455, -6639, -6823, -7005, -7186, -7366, -7545, - -7723, -7900, -8076, -8250, -8423, -8595, -8765, -8935, - -9102, -9269, -9434, -9598, -9760, -9921, -10080, -10238, - -10394, -10549, -10702, -10853, -11003, -11151, -11297, -11442, - -11585, -11727, -11866, -12004, -12140, -12274, -12406, -12537, - -12665, -12792, -12916, -13039, -13160, -13279, -13395, -13510, - -13623, -13733, -13842, -13949, -14053, -14155, -14256, -14354, - -14449, -14543, -14635, -14724, -14811, -14896, -14978, -15059, - -15137, -15213, -15286, -15357, -15426, -15493, -15557, -15619, - -15679, -15736, -15791, -15843, -15893, -15941, -15986, -16029, - -16069, -16107, -16143, -16176, -16207, -16235, -16261, -16284, - -16305, -16324, -16340, -16353, -16364, -16373, -16379, -16383, - -16384, -16383, -16379, -16373, -16364, -16353, -16340, -16324, - -16305, -16284, -16261, -16235, -16207, -16176, -16143, -16107, - -16069, -16029, -15986, -15941, -15893, -15843, -15791, -15736, - -15679, -15619, -15557, -15493, -15426, -15357, -15286, -15213, - -15137, -15059, -14978, -14896, -14811, -14724, -14635, -14543, - -14449, -14354, -14256, -14155, -14053, -13949, -13842, -13733, - -13623, -13510, -13395, -13279, -13160, -13039, -12916, -12792, - -12665, -12537, -12406, -12274, -12140, -12004, -11866, -11727, - -11585, -11442, -11297, -11151, -11003, -10853, -10702, -10549, - -10394, -10238, -10080, -9921, -9760, -9598, -9434, -9269, - -9102, -8935, -8765, -8595, -8423, -8250, -8076, -7900, - -7723, -7545, -7366, -7186, -7005, -6823, -6639, -6455, - -6270, -6084, -5897, -5708, -5520, -5330, -5139, -4948, - -4756, -4563, -4370, -4176, -3981, -3786, -3590, -3393, - -3196, -2999, -2801, -2603, -2404, -2205, -2006, -1806, - -1606, -1406, -1205, -1005, -804, -603, -402, -201, - 0, 201, 402, 603, 804, 1005, 1205, 1406, - 1606, 1806, 2006, 2205, 2404, 2603, 2801, 2999, - 3196, 3393, 3590, 3786, 3981, 4176, 4370, 4563, - 4756, 4948, 5139, 5330, 5520, 5708, 5897, 6084, - 6270, 6455, 6639, 6823, 7005, 7186, 7366, 7545, - 7723, 7900, 8076, 8250, 8423, 8595, 8765, 8935, - 9102, 9269, 9434, 9598, 9760, 9921, 10080, 10238, - 10394, 10549, 10702, 10853, 11003, 11151, 11297, 11442, - 11585, 11727, 11866, 12004, 12140, 12274, 12406, 12537, - 12665, 12792, 12916, 13039, 13160, 13279, 13395, 13510, - 13623, 13733, 13842, 13949, 14053, 14155, 14256, 14354, - 14449, 14543, 14635, 14724, 14811, 14896, 14978, 15059, - 15137, 15213, 15286, 15357, 15426, 15493, 15557, 15619, - 15679, 15736, 15791, 15843, 15893, 15941, 15986, 16029, - 16069, 16107, 16143, 16176, 16207, 16235, 16261, 16284, - 16305, 16324, 16340, 16353, 16364, 16373, 16379, 16383, - 16384 -}; +extern const int16_t ff_g723_1_cos_tab[COS_TBL_SIZE + 1]; +#define G723_1_COS_TAB_FIRST_ELEMENT 16384 /** * LSP VQ tables */ -static const int16_t lsp_band0[LSP_CB_SIZE][3] = { - { 0, 0, 0}, { -270, -1372, -1032}, { -541, -1650, -1382}, - { -723, -2011, -2213}, { -941, -1122, -1942}, { -780, -1145, -2454}, - { -884, -1309, -1373}, {-1051, -1523, -1766}, {-1083, -1622, -2300}, - { -777, -1377, -2147}, { -935, -1467, -2763}, { -802, -1327, -3471}, - { -935, -1959, -3999}, { -240, -89, 222}, { -661, -257, -160}, - { -994, -466, -419}, { -188, -164, -278}, { -342, -512, -415}, - { -607, -511, -797}, { 16, 19, -716}, { 374, 425, -972}, - { -346, 245, -282}, { -265, 506, -754}, { -620, -147, 1955}, - { -742, -860, 2597}, { -150, -352, 2704}, { 305, 880, 1954}, - { 123, 731, 2766}, { -348, 765, 3327}, { 618, 221, 3258}, - { -178, -47, 4219}, { 393, 1304, 3842}, { 698, 1702, 4801}, - { 63, -584, 1229}, { -215, -732, 1704}, { 172, -335, 1909}, - { -2, 216, 1797}, { 353, 127, 2205}, {-1208, 188, 11}, - { -513, -75, -683}, { -973, 222, -646}, { -616, -843, -388}, - { -950, -1113, -359}, {-1431, -623, -705}, {-1398, -1063, -178}, - { -45, -461, 35}, { -9, -657, -216}, { 127, -1078, 95}, - { -950, -1156, 584}, {-1480, -1494, 449}, { -120, -705, 516}, - { -368, -961, 727}, { -378, -526, 973}, { -793, -614, 676}, - { -801, -755, 1287}, {-1476, -340, 1636}, { -505, -1254, 1543}, - {-1243, -1622, 1532}, { -776, -1477, -655}, {-1151, -1296, -823}, - {-1153, -1672, -1124}, {-1291, -2003, -1702}, { -622, -1283, 57}, - { -471, -1611, 509}, {-1060, -1570, -139}, { -873, -2156, -536}, - {-1716, -2021, -364}, {-2150, -3218, -1291}, {-1248, -1945, -2904}, - {-1215, -2633, -2855}, { 167, -244, 84}, { 349, -412, -217}, - { -40, -352, 632}, { 227, -529, 405}, { 68, -383, -443}, - { 167, -558, -706}, { -275, -854, -14}, { -351, -1089, -449}, - { 341, -72, -289}, { 603, -106, -474}, { 322, -219, -649}, - { 179, -317, -998}, { 450, -291, -996}, { 555, 195, -525}, - { 784, 272, -831}, { -148, -384, -849}, { 82, -536, -1357}, - { 238, -172, -1354}, { 422, -268, -1841}, { 297, -737, -2079}, - { -111, -801, -598}, { 1, -668, -984}, { -131, -818, -1299}, - { -329, -521, -1310}, { -151, -778, -1834}, { -93, -352, -1746}, - { -568, -640, -1821}, { -509, -941, -2183}, { 464, -815, -1250}, - { 79, -1133, -1597}, { -184, -1353, -2123}, { -196, -410, -2427}, - { -192, -833, -2810}, { -259, -1382, -3045}, { -217, 4, -1166}, - { -800, -325, -1219}, { -363, -830, -898}, { -661, -1134, -960}, - { -386, -980, -1501}, { -627, -1159, -1722}, { -903, -829, -855}, - { -685, -829, -1313}, {-1065, -959, -1405}, { 441, 25, -847}, - { 655, -27, -1181}, { 1159, -110, -705}, { 856, 253, -1671}, - { 415, 404, -1}, { 322, 903, -398}, { 670, 499, -292}, - { 803, 591, -610}, { 1144, 591, -814}, { 717, 183, 393}, - { 857, 381, 106}, { 609, 62, -27}, { 792, 198, -325}, - { 735, 805, 88}, { 1142, 812, 78}, { 1028, 366, -292}, - { 1309, 743, -237}, { 1615, 589, -79}, { 1010, 639, -243}, - { 999, 964, -311}, { 1500, 1137, -615}, { 988, 357, 646}, - { 1227, 667, 683}, { 1164, 1565, 894}, { 1392, 2015, 477}, - { 1138, 533, 250}, { 1437, 896, 391}, { 1765, 1118, 99}, - { 1112, 1090, 802}, { 1596, 846, 1134}, { 937, 1161, 279}, - { 1719, 1254, 683}, { 1338, 1086, 35}, { 1419, 1324, 428}, - { 1428, 1524, 40}, { 2108, 1594, 89}, { 1015, 544, 1222}, - { 1121, 925, 1263}, { 1030, 1318, 1485}, { 1295, 789, 1817}, - { 1323, 1272, 1909}, { 1724, 1237, 1803}, { 1797, 1689, 858}, - { 2149, 1367, 1301}, { 2302, 1867, 761}, { 2863, 2351, 1053}, - { 52, 163, -76}, { 230, 309, -492}, { -71, 619, 39}, - { -218, 856, 499}, { -654, 736, -207}, { -535, 1259, 155}, - { -480, 1476, 643}, { 262, 1081, 102}, { 309, 1592, -182}, - { 627, 1629, 534}, { 337, 643, 456}, { 758, 670, 713}, - { 202, 1126, 658}, { 612, 1131, 666}, { 686, 1223, 1136}, - { -131, 377, 525}, { 42, 708, 907}, { 87, 1488, 1035}, - { 432, 2117, 904}, { 137, 981, 1332}, { -447, 1014, 1136}, - { -839, 1793, 1246}, { -559, 297, 198}, { -850, 685, 446}, - {-1273, 632, 826}, { -401, -544, 173}, { -753, -793, 144}, - { -436, -9, 772}, { -115, -243, 1310}, { -670, -269, 374}, - {-1027, -13, 639}, { -887, -81, 1137}, {-1277, -455, 158}, - {-1411, -720, 736}, { 172, 88, 403}, { 386, 255, 756}, - { -500, 522, 910}, { -958, 659, 1388}, { -395, 301, 1344}, - { -356, 768, 1813}, { -613, 841, 2419}, { 445, -122, 252}, - { 629, -87, 723}, { 283, -253, 870}, { 456, -116, 1381}, - { 757, 180, 1059}, { 532, 408, 1509}, { 947, 288, 1806}, - { 1325, 994, 2524}, { 892, 1219, 3023}, { 1397, 1596, 3406}, - { 1143, 1552, 2546}, { 1850, 1433, 2710}, { -10, 134, 1002}, - { 154, 499, 1323}, { 508, 792, 1117}, { 509, 1340, 1616}, - { 762, 862, 1608}, { 787, 740, 2320}, { 794, 1727, 1283}, - { 465, 2108, 1660}, { -120, 1451, 1613}, { -386, 2016, 2169}, - { 891, 1225, 2050}, { 456, 1480, 2185}, { 1493, 1283, 1209}, - { 1397, 1636, 1518}, { 1776, 1738, 1552}, { 1572, 1698, 2141}, - { 1389, 2126, 1271}, { 1959, 2413, 1119}, { 1365, 2892, 1505}, - { 2206, 1971, 1623}, { 2076, 1950, 2280}, { 1717, 2291, 1867}, - { 2366, 2515, 1953}, { 2865, 2838, 2522}, { 2535, 3465, 2011}, - { 3381, 4127, 2638}, { 836, 2667, 2289}, { 1761, 2773, 2337}, - { 1415, 3325, 2911}, { 2354, 3138, 3126}, { 2659, 4192, 4010}, - { 1048, 1786, 1818}, { 1242, 2111, 2240}, { 1512, 2079, 2780}, - { 1573, 2491, 3138}, { 2230, 2377, 2782}, { 416, 1773, 2704}, - { 725, 2336, 3297}, { 1252, 2373, 3978}, { 2094, 2268, 3568}, - { 2011, 2712, 4528}, { 1341, 3507, 3876}, { 1216, 3919, 4922}, - { 1693, 4793, 6012} -}; - -static const int16_t lsp_band1[LSP_CB_SIZE][3] = { - { 0, 0, 0}, {-2114, -1302, 76}, {-2652, -1278, -1368}, - {-2847, -828, -349}, {-3812, -2190, -349}, {-3946, -364, -449}, - {-2725, -4492, -3607}, {-3495, -4764, -1744}, { -51, -756, 84}, - { -153, -1191, 504}, { 108, -1418, 1167}, { -835, -896, 390}, - { -569, -1702, 87}, {-1151, -1818, 933}, {-1826, -2547, 411}, - {-1842, -1818, 1451}, {-2438, -1611, 781}, {-2747, -2477, 1311}, - { -940, 1252, 477}, {-1629, 1688, 602}, {-1202, 617, 280}, - {-1737, 393, 580}, {-1528, 1077, 1199}, {-2165, -161, 1408}, - {-2504, -1087, 2371}, {-3458, -175, 1395}, {-1397, -98, -843}, - {-2252, -177, -1149}, {-1489, -726, -1283}, {-1558, -265, -1744}, - {-1867, -821, -1897}, {-2062, -1516, -2340}, {-2595, -1142, -2861}, - { 170, 46, -819}, { -193, -204, -1151}, { 326, -196, -1532}, - { 780, 329, -816}, { 201, 369, -1243}, { 650, -209, -1060}, - { 1144, -15, -1216}, { 1203, -259, -1867}, { -890, -564, -1430}, - { -638, -852, -1921}, { 177, -739, -1358}, { -261, -526, -1666}, - { 206, -407, -2255}, { 338, -526, -822}, { 421, -1095, -1009}, - { 765, -607, -1408}, { 825, -1295, -2004}, { 357, -905, -1815}, - { -58, -1248, -1588}, { -596, -1436, -2046}, { -73, -1159, -2116}, - { -115, -1382, -2581}, { -160, -1723, -1952}, { -6, -2196, -2954}, - { -649, -1705, -2603}, { -617, -1453, -3282}, { -949, -2019, -3102}, - { -812, 1544, 1937}, {-1854, 574, 2000}, {-1463, 1140, 2649}, - {-2683, 1748, 1452}, {-2486, 2241, 2523}, { 783, 1910, 1435}, - { 581, 2682, 1376}, { 236, 2197, 1885}, { -453, 2943, 2057}, - { -682, 2178, 2565}, {-1342, 3201, 3328}, { -288, -184, 262}, - { 121, -149, -183}, { 758, -412, 206}, { 1038, -204, 853}, - { 1577, -457, 700}, { 937, -640, -567}, { 1508, -528, -1024}, - { -225, -527, -427}, { -564, -1095, -332}, { -742, -353, -186}, - {-1288, -459, 84}, {-1853, -484, -274}, {-1554, -731, 825}, - {-2425, -234, 382}, {-1722, 293, -271}, {-2515, 425, -564}, - {-2599, 818, 464}, { -358, 118, -375}, { -613, 198, -874}, - { -690, 683, -324}, {-1352, 1155, -168}, {-1093, 129, -324}, - {-1184, 611, -858}, { 433, 386, -372}, { -120, 486, -634}, - { 234, 851, -631}, { 602, 128, 46}, { 1099, 410, 159}, - { 715, -145, -424}, { 1198, -85, -593}, { 1390, 367, -358}, - { 1683, 362, -964}, { 1711, 622, 45}, { 2033, 833, -383}, - { 2890, 549, -506}, { 7, 401, 52}, { 72, 811, 415}, - { 566, 668, 41}, { 467, 1218, 130}, { 68, 957, -187}, - { -25, 1649, -103}, { -661, 260, 214}, { -925, -94, 612}, - { -321, -422, 965}, { -788, -672, 1783}, { 400, -673, 779}, - { 741, -595, 1635}, { -161, 307, 657}, { -382, 836, 871}, - { -814, 400, 1223}, { 364, 606, 1247}, { 57, 75, 1571}, - { 151, 471, 2287}, { -81, 1021, 1502}, { 227, 1470, 1097}, - { 658, 1275, 1653}, { 664, 1478, 2377}, { 263, -127, 444}, - { 264, 89, 969}, { 794, 171, 576}, { 821, 186, 1226}, - { 404, 462, 517}, { 339, 918, 794}, { 1280, 1423, 196}, - { 1453, 2019, 365}, { 1615, 1481, 672}, { 2394, 1708, 508}, - { 806, 1238, 573}, { 713, 1158, 1078}, { 1285, 1436, 1232}, - { 1790, 1188, 1141}, { 765, 643, 864}, { 1032, 797, 1279}, - { 900, 563, 1827}, { 1514, 673, 2312}, { 1544, 1129, 3240}, - { 1469, 1050, 1594}, { 1945, 1318, 1988}, { 2397, 2026, 2060}, - { 3538, 2057, 2620}, { 1249, -118, 74}, { 1727, 194, 421}, - { 2078, -50, -463}, { 970, 688, -432}, { 1149, 952, -110}, - { 1254, 1275, -651}, { 1386, 929, 401}, { 1960, 1167, 232}, - { 407, -752, -243}, { 859, -1118, 172}, { -227, -860, -992}, - { -796, -1175, -1380}, { 8, -1282, -388}, { 353, -1781, -1037}, - { -732, -397, -807}, { -853, -28, -1342}, {-1229, -1207, -1959}, - {-1015, -1125, -2543}, {-1452, -1791, -2725}, {-1891, -2416, -3269}, - { -918, -1629, -783}, { -580, -2155, -698}, {-1097, -2364, -96}, - {-1387, -1513, 7}, {-1588, -2076, -664}, {-1473, -2740, -784}, - {-2378, -3149, -56}, {-2856, -2092, -169}, {-3391, -3708, 316}, - {-1176, -890, -614}, {-1944, -1061, -800}, { -299, -1517, -1000}, - { -640, -1850, -1526}, {-1454, -1536, -1233}, {-1890, -1955, -1756}, - {-1086, -1921, -2122}, { -750, -2325, -2260}, {-1325, -2413, -2673}, - {-1114, -2542, -3459}, {-1341, -2901, -3963}, {-1160, -2226, -1393}, - {-1001, -2772, -1573}, {-1594, -2641, -1978}, {-1534, -3046, -2624}, - {-2224, -2196, -675}, {-2807, -3054, -1102}, {-2008, -2840, -1186}, - {-1980, -3332, -1695}, {-1715, -3562, -505}, {-2527, -4000, -1887}, - {-2333, -2734, -2296}, {-3440, -2401, -3211}, {-2008, -3528, -3337}, - {-2247, -3291, -4510}, { -475, 949, 155}, { -149, 1365, 545}, - { -757, 1644, 1083}, { -217, 2053, 1353}, {-1433, 2301, 1462}, - { 495, 1661, 529}, { 10, 2037, 740}, { 2082, 1898, 978}, - { 2831, 2294, 911}, { 842, 793, 420}, { 1223, 1023, 863}, - { 1237, 451, 780}, { 1744, 708, 822}, { 1533, 284, 1384}, - { 2135, 609, 1538}, { 2305, 626, 540}, { 2368, 1187, 955}, - { 2586, 1255, -7}, { 3116, 1131, 726}, { 3431, 1730, 428}, - { 2734, 1648, 1307}, { 2988, 1231, 2010}, { 3523, 2024, 1488}, - { 1034, 1657, 871}, { 1206, 2163, 1036}, { 1807, 2372, 1233}, - { 1808, 1769, 1493}, { 1573, 2332, 1779}, { 1216, 1609, 1866}, - { 1480, 1898, 2513}, { 465, 2708, 2776}, { 771, 3638, 3338}, - { 1869, 2599, 2623}, { 2825, 2745, 2468}, { 2638, 2439, 1585}, - { 2094, 2970, 1308}, { 2022, 3057, 1999}, { 3428, 2912, 1816}, - { 4536, 2974, 2129}, { 1046, 2563, 2086}, { 1363, 3562, 2318}, - { 2511, 1891, 2984}, { 1866, 2306, 3986}, { 3272, 2924, 3682}, - { 3146, 3564, 2272}, { 3592, 3968, 2822}, { 2431, 3369, 3069}, - { 1931, 4709, 3090}, { 2629, 4220, 3986}, { 4639, 4056, 3664}, - { 4035, 5334, 4912} -}; - -static const int16_t lsp_band2[LSP_CB_SIZE][4] = { - { 0, 0, 0, 0}, { 601, 512, -542, 334}, - { 428, 1087, -484, -132}, { 652, 622, -391, -572}, - { 378, 799, 141, -860}, { 1040, 409, 112, -554}, - { 1123, 670, -75, -847}, { 1421, 494, -315, -1095}, - { 787, 1001, 114, -460}, { 988, 1672, 216, -681}, - { 1007, 1241, -132, -1247}, { 1073, 399, 186, -5}, - { 1262, 193, -694, -129}, { 325, 196, 51, -641}, - { 861, -59, 350, -458}, { 1261, 567, 586, -346}, - { 1532, 885, 210, -517}, { 2027, 937, 113, -792}, - { 1383, 1064, 334, 38}, { 1964, 1468, 459, 133}, - { 2062, 1186, -98, -121}, { 2577, 1445, 506, -373}, - { 2310, 1682, -2, -960}, { 2876, 1939, 765, 138}, - { 3581, 2360, 649, -414}, { 219, 176, -398, -309}, - { 434, -78, -435, -880}, { -344, 301, 265, -552}, - { -915, 470, 657, -380}, { 419, -432, -163, -453}, - { 351, -953, 8, -562}, { 789, -43, 20, -958}, - { 302, -594, -352, -1159}, { 1040, 108, -668, -924}, - { 1333, 210, -1217, -1663}, { 483, 589, -350, -1140}, - { 1003, 824, -802, -1184}, { 745, 58, -589, -1443}, - { 346, 247, -915, -1683}, { 270, 796, -720, -2043}, - { 1208, 722, -222, -193}, { 1486, 1180, -412, -672}, - { 1722, 179, -69, -521}, { 2047, 860, -666, -1410}, - { -146, 222, -281, -805}, { -189, 90, -114, -1307}, - { -152, 1086, -241, -764}, { -439, 733, -601, -1302}, - { -833, -167, -351, -601}, { -856, -422, -411, -1059}, - { -747, -355, -582, -1644}, { -837, 210, -916, -1144}, - {-1800, 32, -878, -1687}, { -48, -23, -1146, 52}, - { -350, -409, -1656, -364}, { 265, -728, -858, -577}, - { 458, -247, -1141, -997}, { 691, -407, -1988, -1161}, - { -66, -104, -705, -1249}, { -431, -93, -1191, -1844}, - { 203, -732, -1000, -1693}, { 10, -832, -1846, -1819}, - { 493, -128, -1436, -1768}, { 488, -311, -1730, -2540}, - { -653, -532, -1150, -1172}, {-1086, -289, -1706, -1533}, - { -699, -1205, -1216, -1766}, {-1032, -1481, -2074, -1523}, - { -721, -1220, -2277, -2600}, { 12, -539, -1484, -1131}, - { -40, -911, -2106, -441}, { -471, -484, -2267, -1549}, - { -141, -988, -3006, -1721}, {-1545, -2102, -583, 342}, - {-1383, -2772, -386, -13}, {-2118, -2589, -1205, 72}, - {-2147, -3231, -965, 390}, {-2949, -3300, -621, 637}, - {-3907, -4138, -865, 803}, {-1287, -845, -375, -548}, - {-1416, -1169, -487, -1277}, {-1400, -1690, -1027, -418}, - {-2018, -1909, -1188, -1260}, {-1418, -2222, -2029, -128}, - {-2067, -2998, -2693, -310}, { -950, -1028, -1538, 185}, - {-1616, -915, -2205, -549}, { 19, -821, -1145, 352}, - { 184, -1175, -1356, -627}, { -547, -1088, -1661, -911}, - { -216, -1502, -2197, -948}, { -795, -1306, -2374, -451}, - { -924, -1889, -2796, -680}, { -600, -1614, -3609, -885}, - {-2392, -2528, 319, 303}, {-2908, -2095, -310, 573}, - {-3460, -2141, 49, -113}, {-2231, -448, 675, -146}, - {-2805, -532, 1231, 479}, {-2684, -486, -200, 611}, - {-3525, -971, -198, 704}, {-3707, 173, 349, 254}, - {-4734, -1447, -34, 880}, { 777, -512, 114, -10}, - { 1250, -66, 442, -5}, { 604, 613, 452, -352}, - { 1224, 777, 675, -1014}, {-1372, -79, -1208, -238}, - {-2389, -17, -1157, -818}, {-1504, -673, -1133, -1060}, - {-1984, -799, -2005, -1973}, {-2037, -798, -1068, -105}, - {-3190, -899, -1817, -194}, { -156, -886, 394, -318}, - { -258, -1283, 551, 202}, { -536, -1729, 910, 331}, - { -847, -1109, 795, -163}, {-1171, -1128, 715, 519}, - {-1080, -1319, 1685, 668}, {-1000, -1921, 96, 211}, - {-1487, -2148, 831, 174}, {-1139, -374, 414, -4}, - {-1517, -1383, 396, -352}, {-1012, 439, -59, -967}, - {-1812, 706, -440, -1030}, {-1971, -329, -34, -827}, - {-2472, -1588, -151, -606}, {-2161, 374, -281, 76}, - {-3012, 231, -15, -690}, { 1104, 566, 721, 209}, - { 1685, 564, 383, 98}, { 1898, 750, 792, -97}, - { 556, -64, 561, -93}, { 876, 162, 913, -22}, - { 961, 675, 1296, 140}, { 756, -396, 851, 544}, - { 360, -303, 1341, 396}, { 878, -22, 1464, 863}, - { -309, -273, 642, -129}, { -686, -82, 842, 454}, - { -5, -47, 1069, 998}, { -94, 967, 1277, 298}, - { -489, 385, 1473, 746}, { -369, -717, 1333, 242}, - { 281, -993, 1726, 924}, { 464, 601, 1575, 1376}, - { -250, 206, 2339, 1175}, { -438, 377, -597, -285}, - {-1020, 787, -790, -287}, { -458, -410, 215, 295}, - { -589, -860, -121, 797}, {-1175, 122, -437, 466}, - {-1480, -121, 367, 924}, { 234, 323, 770, -555}, - { 145, 30, 996, 26}, { 66, 849, 93, -145}, - { -117, 1261, 474, -399}, {-1495, 1051, 218, -506}, - {-1390, 694, 994, 88}, { 616, 7, 78, 304}, - { 1060, 52, -62, 835}, { 833, 454, 649, 1359}, - { -770, 464, 47, 93}, { -574, 1199, -39, 379}, - { 114, -98, 488, 485}, { 727, 244, 606, 696}, - { -76, 455, 671, 546}, { -565, -13, 145, 819}, - { -376, 569, 448, 1128}, { 218, 122, 265, 1167}, - { 230, 738, 932, 1003}, { 138, 477, 36, 450}, - { 404, 787, -73, 1000}, { 497, 1259, 387, 1231}, - { 17, 207, 195, -79}, { 562, 358, 53, -158}, - { 493, 387, 478, 189}, { 678, 831, 640, 558}, - { -197, 523, 613, 57}, { 429, 894, 769, 111}, - { 67, 1174, 568, 511}, { 1242, 824, 251, 840}, - { 1419, 1074, 864, 481}, { 924, 1474, 669, 724}, - { 1539, 1879, 654, 1590}, { 445, 337, 1111, 541}, - { 472, 1421, 1264, 1094}, { 794, 735, 1103, 668}, - { 1055, 863, 1192, 1020}, { 778, 1105, 806, 1798}, - { 1052, 1527, 1587, 2151}, { 881, 1552, 1265, 391}, - { 726, 872, 1812, 601}, { 1469, 280, 1008, 616}, - { 1403, 577, 1803, 1244}, { 1650, 1314, 1148, 1072}, - { 1297, 1669, 1911, 1026}, { 2093, 1044, 2115, 1189}, - { 1644, 1961, 2587, 1512}, { 25, -315, -9, -106}, - { 290, -339, 428, -444}, { -68, -783, 735, 772}, - { 245, -555, 468, 47}, { 334, -895, 814, 146}, - { 235, 368, -964, -959}, { -203, 315, -1566, -1217}, - { 801, 17, -276, -354}, { 894, -495, -789, -635}, - { 716, 291, -1189, -357}, { 560, -260, -733, -2}, - { 679, -508, -1429, 211}, { -51, -62, -428, 557}, - { 322, -638, -211, 614}, { -878, -1057, -84, -71}, - { -388, -1415, -167, -318}, { -754, -1574, 214, -539}, - {-1419, -2004, -92, -787}, { -47, -856, -347, -255}, - { 23, -1211, -173, 320}, { -658, -487, -893, 353}, - { -783, -1587, -584, 507}, {-1420, -859, -378, 441}, - {-2095, -1491, -137, 439}, { -321, -1450, -1288, -12}, - { -359, -2113, -553, -8}, { -831, -1918, -1561, 32}, - {-1014, -2487, -1359, -939}, { -475, -311, -169, -236}, - { -907, -426, 276, -611}, { -96, -400, 50, -710}, - { -426, -1022, -10, -985}, { -197, -258, -744, -575}, - { -611, -930, -771, -394}, { -267, -776, -612, -939}, - { -256, -1346, -802, -1122}, { -796, -1570, -825, -754}, - { 712, 876, 141, 227}, { 981, 1509, 85, 124}, - { 1462, 1228, 979, -39}, { 1734, 999, 1481, 440}, - { 2293, 1116, 769, 440}, { 2504, 1480, 1241, 356}, - { 2474, 1909, 1558, 810}, { 917, 1134, 607, -134}, - { 509, 1809, 781, -123}, { 1712, 1506, 559, -423}, - { 2037, 2317, 726, -155}, { 3031, 2676, 1203, 331}, - { 3664, 3274, 1768, 531}, { 1610, 1839, 867, 183}, - { 1774, 1972, 1538, 97}, { 1822, 2158, 1282, 659}, - { 2222, 2758, 1818, 900}, { 3251, 2124, 1723, 996}, - { 3633, 2336, 2408, 1453}, { 2923, 3517, 2567, 1318}, -}; +extern const int16_t ff_g723_1_lsp_band0[LSP_CB_SIZE][3]; +extern const int16_t ff_g723_1_lsp_band1[LSP_CB_SIZE][3]; +extern const int16_t ff_g723_1_lsp_band2[LSP_CB_SIZE][4]; /** * Used for the coding/decoding of the pulses positions * for the MP-MLQ codebook */ -static const int32_t combinatorial_table[PULSE_MAX][SUBFRAME_LEN/GRID_SIZE] = { - {118755, 98280, 80730, 65780, 53130, - 42504, 33649, 26334, 20349, 15504, - 11628, 8568, 6188, 4368, 3003, - 2002, 1287, 792, 462, 252, - 126, 56, 21, 6, 1, - 0, 0, 0, 0, 0}, - - { 23751, 20475, 17550, 14950, 12650, - 10626, 8855, 7315, 5985, 4845, - 3876, 3060, 2380, 1820, 1365, - 1001, 715, 495, 330, 210, - 126, 70, 35, 15, 5, - 1, 0, 0, 0, 0}, - - { 3654, 3276, 2925, 2600, 2300, - 2024, 1771, 1540, 1330, 1140, - 969, 816, 680, 560, 455, - 364, 286, 220, 165, 120, - 84, 56, 35, 20, 10, - 4, 1, 0, 0, 0}, - - { 406, 378, 351, 325, 300, - 276, 253, 231, 210, 190, - 171, 153, 136, 120, 105, - 91, 78, 66, 55, 45, - 36, 28, 21, 15, 10, - 6, 3, 1, 0, 0}, - - { 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, 0}, - - { 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1}, -}; - -static const int16_t pitch_contrib[340] = { - 60, 0, 0, 2489, 60, 0, 0, 5217, - 1, 6171, 0, 3953, 0, 10364, 1, 9357, - -1, 8843, 1, 9396, 0, 5794, -1, 10816, - 2, 11606, -2, 12072, 0, 8616, 1, 12170, - 0, 14440, 0, 7787, -1, 13721, 0, 18205, - 0, 14471, 0, 15807, 1, 15275, 0, 13480, - -1, 18375, -1, 0, 1, 11194, -1, 13010, - 1, 18836, -2, 20354, 1, 16233, -1, 0, - 60, 0, 0, 12130, 0, 13385, 1, 17834, - 1, 20875, 0, 21996, 1, 0, 1, 18277, - -1, 21321, 1, 13738, -1, 19094, -1, 20387, - -1, 0, 0, 21008, 60, 0, -2, 22807, - 0, 15900, 1, 0, 0, 17989, -1, 22259, - 1, 24395, 1, 23138, 0, 23948, 1, 22997, - 2, 22604, -1, 25942, 0, 26246, 1, 25321, - 0, 26423, 0, 24061, 0, 27247, 60, 0, - -1, 25572, 1, 23918, 1, 25930, 2, 26408, - -1, 19049, 1, 27357, -1, 24538, 60, 0, - -1, 25093, 0, 28549, 1, 0, 0, 22793, - -1, 25659, 0, 29377, 0, 30276, 0, 26198, - 1, 22521, -1, 28919, 0, 27384, 1, 30162, - -1, 0, 0, 24237, -1, 30062, 0, 21763, - 1, 30917, 60, 0, 0, 31284, 0, 29433, - 1, 26821, 1, 28655, 0, 31327, 2, 30799, - 1, 31389, 0, 32322, 1, 31760, -2, 31830, - 0, 26936, -1, 31180, 1, 30875, 0, 27873, - -1, 30429, 1, 31050, 0, 0, 0, 31912, - 1, 31611, 0, 31565, 0, 25557, 0, 31357, - 60, 0, 1, 29536, 1, 28985, -1, 26984, - -1, 31587, 2, 30836, -2, 31133, 0, 30243, - -1, 30742, -1, 32090, 60, 0, 2, 30902, - 60, 0, 0, 30027, 0, 29042, 60, 0, - 0, 31756, 0, 24553, 0, 25636, -2, 30501, - 60, 0, -1, 29617, 0, 30649, 60, 0, - 0, 29274, 2, 30415, 0, 27480, 0, 31213, - -1, 28147, 0, 30600, 1, 31652, 2, 29068, - 60, 0, 1, 28571, 1, 28730, 1, 31422, - 0, 28257, 0, 24797, 60, 0, 0, 0, - 60, 0, 0, 22105, 0, 27852, 60, 0, - 60, 0, -1, 24214, 0, 24642, 0, 23305, - 60, 0, 60, 0, 1, 22883, 0, 21601, - 60, 0, 2, 25650, 60, 0, -2, 31253, - -2, 25144, 0, 17998 -}; +extern const int32_t ff_g723_1_combinatorial_table[PULSE_MAX][SUBFRAME_LEN/GRID_SIZE]; /** * Number of non-zero pulses in the MP-MLQ excitation */ static const int8_t pulses[4] = {6, 5, 6, 5}; -/** - * Size of the MP-MLQ fixed excitation codebooks - */ -static const int32_t max_pos[4] = {593775, 142506, 593775, 142506}; +extern const int16_t ff_g723_1_fixed_cb_gain[GAIN_LEVELS]; -static const int16_t fixed_cb_gain[GAIN_LEVELS] = { - 1, 2, 3, 4, 6, 9, 13, 18, - 26, 38, 55, 80, 115, 166, 240, 348, - 502, 726, 1050, 1517, 2193, 3170, 4582, 6623, -}; - -static const int16_t adaptive_cb_gain85[85 * 20] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 800, 1496, 167, -256, - -338, -39, -136, -1, -4, -6, -73, -8, - -15, 12, 23, 2, 16, 30, 3, -5, - -462, -686, 493, 2575, 311, -13, -28, -14, - -404, -5, -19, 13, 20, 72, 107, -77, - 8, 13, -9, -48, 1483, 144, 784, 928, - 1243, -134, -1, -37, -52, -94, -13, -71, - -6, -84, -8, -44, -112, -10, -59, -70, - -77, 275, 3522, 1056, -1254, 0, -4, -757, - -68, -95, 1, 16, -59, 4, -17, -227, - -5, 21, 269, 80, -125, -40, -264, 381, - 5027, 0, 0, -4, -8, -1542, 0, -2, - 0, 2, 0, 6, 38, 12, 81, -117, - 138, 332, 2215, 2574, 1339, -1, -6, -299, - -404, -109, -2, -18, -44, -21, -52, -348, - -11, -27, -181, -210, 3685, 2883, -887, 866, - -1639, -828, -507, -48, -45, -164, -648, 199, - 156, -194, -152, 46, 368, 288, -88, 86, - 1396, 2146, 2235, 345, 942, -118, -281, -305, - -7, -54, -182, -190, -292, -29, -45, -47, - -80, -123, -128, -19, 13, 4475, 3549, -804, - -655, 0, -1222, -768, -39, -26, -3, -2, - -969, 0, 219, 174, 0, 179, 141, -32, - -724, 254, 242, 6049, 2462, -32, -3, -3, - -2233, -370, 11, 10, -3, 267, -94, -89, - 108, -38, -36, -909, 626, -1713, 6121, 4561, - -1061, -23, -179, -2287, -1270, -68, 65, -233, - 640, -174, 477, -1704, 40, -111, 396, 295, - -350, 1391, 7985, 511, -405, -7, -118, -3892, - -15, -10, 29, 170, -678, 10, -43, -249, - -8, 34, 197, 12, 3144, -529, 608, 2530, - 3878, -603, -17, -22, -390, -918, 101, -116, - 19, -485, 81, -93, -744, 125, -144, -599, - 2589, -689, 3045, 5603, -404, -409, -29, -566, - -1916, -10, 108, -481, 128, -885, 235, -1041, - 63, -17, 75, 138, 3107, 513, 1374, -3594, - -4922, -589, -16, -115, -788, -1478, -97, -260, - -43, 681, 112, 301, 933, 154, 413, -1079, - 2468, 6010, 1107, -390, 1961, -372, -2204, -74, - -9, -234, -905, -166, -406, 58, 143, 26, - -295, -719, -132, 46, 4773, 2766, 2368, 4862, - -4044, -1390, -467, -342, -1443, -998, -806, -690, - -399, -1416, -821, -702, 1178, 682, 584, 1200, - 1665, -1879, 1443, 1701, 8562, -169, -215, -127, - -176, -4475, 190, -146, 165, -172, 195, -149, - -870, 982, -754, -889, 2716, 9011, -1007, 755, - -1785, -450, -4956, -61, -34, -194, -1493, 167, - 554, -125, -415, 46, 296, 982, -109, 82, - -2727, 7548, 1285, 938, 3420, -453, -3478, -100, - -53, -714, 1256, 213, -592, 156, -432, -73, - 569, -1576, -268, -196, 3677, 882, 4050, 1202, - 2323, -825, -47, -1001, -88, -329, -198, -909, - -218, -269, -64, -297, -521, -125, -574, -170, - 2046, -753, 122, 10102, 603, -255, -34, 0, - -6229, -22, 94, -15, 5, -1261, 464, -75, - -75, 27, -4, -372, 449, -1815, 10690, 3870, - -527, -12, -201, -6976, -914, -16, 49, -293, - 1184, -106, 428, -2525, 14, -58, 344, 124, - -941, 2352, 5049, 3650, 2637, -54, -337, -1556, - -813, -424, 135, 290, -725, 209, -524, -1125, - 151, -378, -812, -587, -1879, 796, 3117, 9569, - -404, -215, -38, -593, -5589, -9, 91, 357, - -151, 1097, -464, -1821, -46, 19, 76, 236, - -1715, 2043, -2096, 9946, 4001, -179, -254, -268, - -6038, -977, 213, -219, 261, 1041, -1240, 1272, - 418, -498, 511, -2429, -5772, -618, -3921, 284, - -3155, -2033, -23, -938, -4, -607, -218, -1381, - -148, 100, 10, 68, -1111, -119, -755, 54, - 382, 4748, 8003, -2064, 2198, -8, -1376, -3909, - -260, -294, -110, -186, -2319, 48, 598, 1008, - -51, -637, -1073, 277, -867, 3015, 11926, -1675, - 947, -45, -555, -8681, -171, -54, 159, 631, - -2195, -88, 308, 1219, 50, -174, -690, 96, - -4933, -432, 6757, 3771, 1352, -1485, -11, -2786, - -867, -111, -130, 2034, 178, 1135, 99, -1555, - 407, 35, -557, -311, 152, 9726, 4231, -1928, - 1490, -1, -5774, -1092, -226, -135, -90, -39, - -2511, 17, 1144, 498, -13, -884, -384, 175, - 2512, 193, 9033, 5361, -3148, -385, -2, -4980, - -1754, -605, -29, -1385, -106, -822, -63, -2956, - 482, 37, 1735, 1030, 8464, 2844, 12, 549, - 2132, -4373, -493, 0, -18, -277, -1469, -6, - -2, -284, -95, 0, -1101, -370, -1, -71, - 2141, -2602, 7166, 9046, -1350, -279, -413, -3134, - -4994, -111, 340, -936, 1138, -1182, 1436, -3957, - 176, -214, 590, 745, -244, 278, 13307, 1227, - -161, -3, -4, -10808, -91, -1, 4, 198, - -226, 18, -20, -997, -2, 2, 131, 12, - -1947, 8217, 6269, 917, -2559, -231, -4121, -2399, - -51, -399, 976, 745, -3144, 108, -460, -350, - -304, 1283, 979, 143, -1810, 2061, -2781, 6056, - 10058, -200, -259, -472, -2238, -6174, 227, -307, - 349, 669, -761, 1028, 1111, -1265, 1707, -3717, - 7827, 9161, -3409, 2473, -1510, -3739, -5122, -709, - -373, -139, -4376, 1628, 1906, -1181, -1382, 514, - 721, 844, -314, 228, -1430, 8313, 9541, -2955, - 1626, -124, -4218, -5556, -533, -161, 725, 832, - -4841, -257, 1499, 1721, 142, -825, -947, 293, - 2819, -4247, 5391, 8673, 2756, -485, -1101, -1774, - -4591, -463, 730, -927, 1397, -1492, 2248, -2854, - -474, 714, -907, -1459, 141, 14552, 690, 257, - -112, -1, -12926, -29, -4, 0, -125, -5, - -613, -2, -228, -10, 0, 99, 4, 1, - 11938, -1859, 1806, -962, -884, -8699, -211, -199, - -56, -47, 1355, -1316, 205, 701, -109, 106, - 644, -100, 97, -51, 3728, 1982, 2264, 4584, - 3131, -848, -239, -312, -1282, -598, -451, -515, - -273, -1043, -554, -633, -712, -378, -432, -876, - -1181, 766, 720, 14303, -216, -85, -35, -31, - -12486, -2, 55, 51, -33, 1031, -668, -628, - -15, 10, 9, 189, -4385, 4826, 10112, 1569, - 3388, -1173, -1421, -6242, -150, -700, 1291, 2706, - -2979, 420, -462, -969, 906, -998, -2091, -324, - -448, 1932, 15591, -1842, 657, -12, -227, -14837, - -207, -26, 52, 427, -1838, -50, 217, 1753, - 18, -77, -626, 74, -4141, 1844, 3962, 5517, - 6220, -1046, -207, -958, -1858, -2361, 466, 1001, - -446, 1394, -621, -1334, 1572, -700, -1504, -2094, - 729, -2299, 14755, 3657, -952, -32, -322, -13288, - -816, -55, 102, -656, 2071, -162, 513, -3294, - 42, -133, 857, 212, -1385, 5801, 13339, -3137, - 1344, -117, -2054, -10861, -600, -110, 490, 1127, - -4723, -265, 1111, 2554, 113, -476, -1094, 257, - 4710, 9661, 1073, -2467, 3274, -1354, -5697, -70, - -371, -654, -2777, -308, -633, 709, 1455, 161, - -941, -1930, -214, 493, 1843, -3624, 12422, 6898, - -1559, -207, -802, -9419, -2904, -148, 407, -1397, - 2748, -775, 1526, -5230, 175, -344, 1182, 656, - 1433, 2394, 2507, 1380, 8780, -125, -349, -383, - -116, -4705, -209, -219, -366, -120, -201, -211, - -768, -1283, -1343, -740, -1712, 12915, 5883, -2197, - 991, -179, -10181, -2112, -294, -60, 1350, 615, - -4638, -229, 1732, 789, 103, -781, -356, 133, - 15072, 2158, -1245, 910, -496, -13865, -284, -94, - -50, -15, -1986, 1145, 164, -837, -119, 69, - 456, 65, -37, 27, 4655, 7319, 4916, 586, - -3381, -1322, -3270, -1475, -20, -697, -2079, -1396, - -2196, -166, -261, -175, 960, 1510, 1014, 120, - 1191, -2140, 5120, 13498, -1418, -86, -279, -1600, - -11121, -122, 155, -372, 669, -981, 1763, -4218, - 103, -185, 443, 1168, -1530, -817, 8191, 9632, - -1452, -143, -40, -4095, -5663, -128, -76, 765, - 408, 900, 480, -4815, -135, -72, 726, 854, - -3236, 607, 1696, -2106, 11485, -639, -22, -175, - -270, -8051, 119, 335, -62, -416, 78, 218, - 2268, -425, -1189, 1476, 3203, -1903, -837, 9679, - 7057, -626, -221, -42, -5718, -3039, 372, 163, - -97, -1892, 1124, 494, -1380, 819, 360, -4169, - 213, -655, 17015, 620, -384, -2, -26, -17671, - -23, -9, 8, -221, 681, -8, 24, -644, - 5, -15, 399, 14, 5088, 35, -3339, 3726, - 8488, -1580, 0, -680, -847, -4397, -10, 1037, - 7, -1157, -8, 759, -2636, -18, 1730, -1930, - -988, 1454, -2688, 15039, 2682, -59, -129, -441, - -13805, -439, 87, -162, 238, 907, -1335, 2467, - 161, -238, 440, -2462, -4865, -2842, -53, 5495, - 6523, -1445, -493, 0, -1843, -2597, -844, -16, - -9, 1632, 953, 18, 1937, 1131, 21, -2188, - 3076, 15069, -2914, 1810, -971, -577, -13860, -518, - -200, -57, -2829, 547, 2680, -339, -1665, 322, - 182, 893, -172, 107, 1311, 5355, 11054, 2299, - -3654, -105, -1750, -7458, -322, -814, -428, -885, - -3613, -184, -751, -1551, 292, 1194, 2465, 512, - 4035, 5619, 4618, 1815, 1912, -994, -1927, -1301, - -201, -223, -1384, -1137, -1583, -447, -622, -511, - -471, -656, -539, -211, -2131, 2754, -4501, 12879, - 7432, -277, -463, -1236, -10124, -3371, 358, -585, - 756, 1675, -2165, 3538, 967, -1249, 2042, -5842, - 5618, -515, 3219, -4149, 4857, -1926, -16, -632, - -1050, -1440, 176, -1104, 101, 1422, -130, 815, - -1666, 152, -954, 1230, 1838, -1709, 1139, 16867, - 716, -206, -178, -79, -17366, -31, 191, -127, - 118, -1892, 1759, -1173, -80, 74, -49, -737, - 1978, -3845, 10050, 11854, -2492, -238, -902, -6164, - -8576, -379, 464, -1213, 2358, -1431, 2782, -7271, - 301, -585, 1529, 1803, -2600, 11246, 11289, -3647, - 1463, -412, -7720, -7778, -812, -130, 1784, 1791, - -7749, -578, 2504, 2513, 232, -1004, -1008, 325, - 3442, 907, 2725, 8970, 3638, -723, -50, -453, - -4911, -808, -190, -572, -150, -1884, -496, -1492, - -764, -201, -605, -1992, -126, 17498, 3481, -2003, - 1090, 0, -18689, -739, -244, -72, 135, 26, - -3717, -15, 2139, 425, 8, -1165, -231, 133, - -1814, 1048, -2164, 4070, 16272, -200, -67, -285, - -1011, -16160, 116, -239, 138, 450, -260, 537, - 1801, -1041, 2149, -4042, 9354, 12580, -1883, 962, - -617, -5341, -9660, -216, -56, -23, -7183, 1075, - 1446, -549, -738, 110, 352, 474, -71, 36, - 1708, 4199, 7387, 6335, 1003, -178, -1076, -3330, - -2449, -61, -437, -770, -1893, -660, -1623, -2856, - -104, -257, -452, -388, -2624, 5623, 17310, -2353, - 592, -420, -1930, -18288, -338, -21, 900, 2772, - -5941, -376, 807, 2486, 94, -203, -625, 85, - 1211, -850, 1193, -1926, 15992, -89, -44, -86, - -226, -15609, 62, -88, 61, 142, -100, 140, - -1182, 830, -1165, 1880, 3983, -2054, 11506, -19, - 3622, -968, -257, -8080, 0, -801, 499, -2797, - 1442, 4, -2, 13, -880, 454, -2544, 4, - -786, -1354, 16092, 7246, -1665, -37, -111, -15805, - -3205, -169, -65, 772, 1330, 348, 599, -7117, - -80, -137, 1636, 736, -4316, -511, 6674, 11665, - 4633, -1137, -15, -2719, -8305, -1310, -134, 1758, - 208, 3073, 364, -4752, 1220, 144, -1887, -3299, - 7912, 4557, 1937, 1885, 7037, -3821, -1267, -229, - -216, -3022, -2200, -935, -538, -910, -524, -222, - -3398, -1957, -832, -809, 3434, 2967, 5867, 8196, - 8766, -720, -537, -2101, -4100, -4690, -622, -1230, - -1062, -1718, -1484, -2935, -1837, -1588, -3139, -4385, - 5881, 9176, 8119, 3934, 3355, -2111, -5139, -4023, - -944, -687, -3294, -2914, -4547, -1412, -2203, -1949, - -1204, -1879, -1662, -805 -}; - -static const int16_t adaptive_cb_gain170[170 * 20] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 776, 212, 715, 670, - 809, -36, -2, -31, -27, -39, -10, -33, - -9, -31, -8, -29, -38, -10, -35, -33, - 1296, 1316, -168, -320, -815, -102, -105, -1, - -6, -40, -104, 13, 13, 25, 25, -3, - 64, 65, -8, -15, -589, 680, 2478, 308, - -596, -21, -28, -375, -5, -21, 24, 89, - -102, 11, -12, -46, -21, 24, 90, 11, - -735, -487, -5, 2948, 468, -33, -14, 0, - -530, -13, -21, 0, 0, 132, 87, 0, - 21, 13, 0, -84, 1042, 1730, 1068, 333, - 626, -66, -182, -69, -6, -23, -110, -67, - -112, -21, -35, -21, -39, -66, -40, -12, - 486, -769, 4074, 2825, -1107, -14, -36, -1013, - -487, -74, 22, -120, 191, -83, 132, -702, - 32, -52, 275, 191, 1521, -767, -124, 4320, - 1026, -141, -35, 0, -1139, -64, 71, 11, - -5, -401, 202, 32, -95, 48, 7, -270, - 2425, 1267, 3439, -91, -1166, -359, -98, -722, - 0, -83, -187, -509, -266, 13, 7, 19, - 172, 90, 244, -6, -1251, 975, 173, 4039, - 2005, -95, -58, -1, -996, -245, 74, 13, - -10, 308, -240, -42, 153, -119, -21, -494, - 1820, 632, 1322, 2062, 1031, -202, -24, -106, - -259, -64, -70, -146, -51, -229, -79, -166, - -114, -39, -83, -129, -447, 4904, 244, -315, - -2038, -12, -1467, -3, -6, -253, 134, 6, - -73, -8, 94, 4, -55, 610, 30, -39, - -208, -1102, 463, -448, 5653, -2, -74, -13, - -12, -1950, -14, 5, 31, -5, -30, 12, - 71, 380, -159, 154, 4739, 2600, -1864, 856, - -1554, -1371, -412, -212, -44, -147, -752, 539, - 295, -247, -135, 97, 449, 246, -176, 81, - 1894, 3533, 35, -26, 2145, -219, -762, 0, - 0, -280, -408, -4, -7, 3, 5, 0, - -248, -462, -4, 3, -2699, 1841, 4072, 2443, - 1582, -444, -207, -1012, -364, -152, 303, 670, - -457, 402, -274, -607, 260, -177, -393, -236, - -844, 3358, 6106, -1059, -537, -43, -688, -2275, - -68, -17, 173, 314, -1251, -54, 217, 395, - -27, 110, 200, -34, 1251, 1016, 3020, 2210, - 1445, -95, -63, -556, -298, -127, -77, -230, - -187, -168, -137, -407, -110, -89, -266, -194, - 2099, 2277, 4038, 3533, -2870, -269, -316, -995, - -762, -503, -291, -517, -561, -452, -491, -871, - 367, 399, 707, 619, 400, -1114, 8516, 2422, - -1117, -9, -75, -4426, -358, -76, 27, -208, - 579, -59, 164, -1259, 27, -75, 580, 165, - -4398, -2011, 3912, -2407, 2258, -1180, -247, -934, - -353, -311, -540, 1050, 480, -646, -295, 575, - 606, 277, -539, 331, 1767, -1447, 4240, 6160, - -757, -190, -127, -1097, -2316, -35, 156, -457, - 374, -664, 544, -1594, 81, -66, 195, 284, - 1594, -1463, 1035, 6938, 1920, -155, -130, -65, - -2938, -225, 142, -100, 92, -675, 619, -438, - -186, 171, -121, -813, -562, 4716, 4085, -591, - 2421, -19, -1357, -1018, -21, -357, 162, 140, - -1175, -20, 170, 147, 83, -696, -603, 87, - 1552, 8778, -935, 354, -1424, -147, -4703, -53, - -7, -123, -831, 88, 501, -33, -189, 20, - 134, 763, -81, 30, 4831, -4431, 41, -1479, - -2976, -1424, -1198, 0, -133, -540, 1306, -12, - 11, 436, -400, 3, 877, -804, 7, -268, - 2090, 1192, 1006, 1645, 4853, -266, -86, -61, - -165, -1437, -152, -128, -73, -210, -119, -101, - -619, -353, -298, -487, 2386, 5712, 1426, -94, - 1350, -347, -1991, -124, 0, -111, -832, -207, - -497, 13, 32, 8, -196, -470, -117, 7, - -1349, 1091, 1659, 8891, 313, -111, -72, -168, - -4825, -5, 89, 136, -110, 732, -592, -900, - 25, -20, -31, -170, 9980, 916, -381, -808, - 88, -6080, -51, -8, -39, 0, -558, 232, - 21, 492, 45, -18, -53, -4, 2, 4, - 2338, -1031, -248, 3928, 6484, -333, -64, -3, - -942, -2566, 147, 35, -15, -560, 247, 59, - -925, 408, 98, -1555, 6166, -1240, -337, 3672, - -1277, -2320, -93, -6, -823, -99, 466, 126, - -25, -1382, 278, 75, 480, -96, -26, 286, - 4377, -132, -2588, 1701, 4865, -1169, -1, -409, - -176, -1444, 35, 691, -20, -454, 13, 268, - -1299, 39, 768, -505, 2594, 3295, 3944, 1481, - 682, -410, -662, -949, -133, -28, -521, -624, - -793, -234, -297, -356, -108, -137, -164, -61, - 4151, 624, 815, 4485, 2229, -1052, -23, -40, - -1228, -303, -158, -206, -31, -1136, -170, -223, - -565, -84, -111, -610, -3575, -361, 4924, 2791, - 4698, -780, -7, -1480, -475, -1347, -78, 1074, - 108, 609, 61, -839, 1025, 103, -1412, -800, - -2518, 3791, 8623, 315, 2465, -387, -877, -4538, - -6, -370, 582, 1325, -1995, 48, -73, -166, - 378, -570, -1297, -47, -691, 2989, 9957, -421, - -1142, -29, -545, -6051, -10, -79, 126, 420, - -1817, -17, 76, 256, -48, 208, 694, -29, - -1918, 104, -3190, -3410, -4440, -224, 0, -621, - -709, -1203, 12, -373, 20, -399, 21, -664, - -519, 28, -864, -924, -3359, -1668, 1854, 6939, - 1430, -688, -169, -209, -2939, -124, -341, 380, - 188, 1422, 706, -785, 293, 145, -161, -606, - 42, 9706, 3164, -952, 907, 0, -5750, -611, - -55, -50, -25, -8, -1874, 2, 564, 183, - -2, -537, -175, 52, 1607, 785, 2862, 4327, - 3307, -157, -37, -500, -1143, -667, -77, -280, - -137, -424, -207, -756, -324, -158, -577, -873, - 6801, 3416, 2227, 1682, -3217, -2823, -712, -302, - -172, -631, -1418, -924, -464, -698, -350, -228, - 1335, 670, 437, 330, 3459, 3898, 364, 7841, - -2640, -730, -927, -8, -3753, -425, -823, -76, - -86, -1655, -1865, -174, 557, 628, 58, 1263, - -5902, -3458, -2465, -1886, 4334, -2126, -730, -371, - -217, -1146, -1245, -888, -520, -679, -398, -283, - 1561, 915, 652, 499, -3710, 1133, 7849, 3443, - -215, -840, -78, -3760, -723, -2, 256, 1777, - -543, 779, -238, -1649, -48, 14, 103, 45, - 4132, 2828, 2, -4212, -4116, -1042, -488, 0, - -1083, -1034, -713, 0, 0, 1062, 727, 0, - 1038, 710, 0, -1058, 5875, 8496, -1796, 1376, - -1786, -2107, -4406, -197, -115, -194, -3047, 644, - 931, -493, -713, 150, 640, 926, -195, 150, - 3143, 3483, 3546, -793, 4489, -603, -740, -767, - -38, -1230, -668, -680, -754, 152, 168, 171, - -861, -954, -971, 217, 2845, 7965, 3695, -5432, - 3978, -494, -3873, -833, -1801, -966, -1383, -641, - -1796, 943, 2641, 1225, -691, -1934, -897, 1319, - 1538, 150, 7139, 2049, 3097, -144, -1, -3110, - -256, -585, -14, -670, -65, -192, -18, -892, - -290, -28, -1349, -387, 618, 7520, 4729, -238, - -3373, -23, -3452, -1365, -3, -694, -283, -178, - -2170, 8, 109, 68, 127, 1548, 973, -49, - 2965, -3013, 7912, 7076, -1997, -536, -554, -3821, - -3056, -243, 545, -1431, 1455, -1280, 1301, -3417, - 361, -367, 964, 862, 2443, -929, -1113, 9677, - 4138, -364, -52, -75, -5716, -1045, 138, 166, - -63, -1443, 549, 657, -617, 234, 281, -2444, - 1966, 3309, 10085, -3399, 2105, -236, -668, -6207, - -705, -270, -397, -1210, -2037, 408, 686, 2092, - -252, -425, -1295, 436, -112, -1368, 8868, 4822, - 2048, 0, -114, -4800, -1419, -256, -9, 61, - 740, 33, 402, -2610, 14, 171, -1108, -602, - -2597, 438, -1839, 6229, 7266, -411, -11, -206, - -2368, -3223, 69, -291, 49, 987, -166, 699, - 1152, -194, 816, -2763, 3454, 553, 9127, 4946, - -5596, -728, -18, -5084, -1493, -1911, -116, -1924, - -308, -1042, -166, -2755, 1179, 188, 3117, 1689, - -532, -663, 12262, 2495, -1004, -17, -26, -9177, - -380, -61, -21, 398, 496, 81, 101, -1867, - -32, -40, 751, 152, -2100, 1317, -1509, 11425, - 2997, -269, -105, -139, -7967, -548, 168, -193, - 121, 1464, -918, 1052, 384, -240, 276, -2090, - 1193, -2697, 11259, 5373, -763, -86, -444, -7737, - -1762, -35, 196, -819, 1853, -391, 884, -3692, - 55, -125, 525, 250, 2405, -471, 11079, 203, - 782, -353, -13, -7491, -2, -37, 69, -1626, - 318, -29, 5, -137, -114, 22, -529, -9, - -1871, 5685, 11290, -2662, 1353, -213, -1972, -7780, - -432, -111, 649, 1289, -3917, -304, 923, 1834, - 154, -469, -932, 220, -3768, 5927, -3093, 5041, - 5212, -866, -2144, -584, -1551, -1658, 1363, -711, - 1119, 1159, -1824, 951, 1198, -1885, 984, -1603, - -2546, 9502, 5969, -2440, 1928, -395, -5511, -2175, - -363, -226, 1477, 927, -3462, -379, 1415, 889, - 299, -1118, -702, 287, -4963, 3568, 4592, 5508, - 3451, -1503, -777, -1287, -1851, -727, 1080, 1391, - -1000, 1668, -1199, -1543, 1045, -751, -967, -1160, - 1745, -2586, 3983, 10899, -1551, -186, -408, -968, - -7250, -146, 275, -424, 628, -1161, 1720, -2649, - 165, -244, 377, 1032, 867, -456, -727, 3369, - 11822, -45, -12, -32, -692, -8531, 24, 38, - -20, -178, 93, 149, -625, 329, 525, -2431, - 7535, 2422, 1926, 1405, 1599, -3466, -358, -226, - -120, -156, -1114, -886, -284, -646, -207, -165, - -735, -236, -188, -137, 1041, -735, -142, 13209, - 1515, -66, -33, -1, -10649, -140, 46, 9, - -6, -839, 593, 114, -96, 68, 13, -1222, - 7950, 6745, -1444, -1008, 2721, -3857, -2777, -127, - -62, -452, -3273, 700, 594, 489, 415, -88, - -1320, -1120, 239, 167, -4754, -1379, 4522, -578, - -5733, -1379, -116, -1248, -20, -2006, -400, 1312, - 380, -167, -48, 159, -1663, -482, 1582, -202, - 3220, 5978, 5923, 2430, -2689, -633, -2181, -2141, - -360, -441, -1175, -1164, -2161, -477, -886, -878, - 528, 981, 972, 398, 377, 1312, 13978, -1470, - 677, -8, -105, -11925, -132, -28, -30, -321, - -1119, 33, 117, 1254, -15, -54, -577, 60, - -3435, 6770, 314, -885, 5686, -720, -2797, -6, - -47, -1973, 1419, 65, -129, -185, 366, 16, - 1192, -2349, -109, 307, 3171, 8774, -2260, 2679, - 3069, -613, -4699, -312, -438, -575, -1698, 437, - 1210, -518, -1435, 369, -594, -1643, 423, -501, - 5557, 1509, 5407, -125, -7386, -1884, -139, -1784, - 0, -3330, -511, -1834, -498, 42, 11, 41, - 2505, 680, 2438, -56, -2838, 2595, 13228, 271, - 1793, -491, -411, -10680, -4, -196, 449, 2291, - -2095, 47, -42, -219, 310, -284, -1447, -29, - 664, -278, 14966, 951, -711, -26, -4, -13672, - -55, -30, 11, -606, 253, -38, 16, -869, - 28, -12, 650, 41, 808, 1770, 8658, 5863, - -1486, -39, -191, -4576, -2098, -134, -87, -427, - -935, -289, -633, -3098, 73, 160, 785, 531, - 3063, 1539, 2000, -542, 9576, -572, -144, -244, - -17, -5597, -287, -374, -188, 101, 51, 66, - -1790, -900, -1169, 317, 514, 14083, -323, 896, - -891, -16, -12106, -6, -49, -48, -442, 10, - 277, -28, -770, 17, 27, 766, -17, 48, - 892, 158, 5237, 11057, -1603, -48, -1, -1674, - -7462, -156, -8, -285, -50, -602, -106, -3534, - 87, 15, 512, 1082, -1612, 2564, -4296, 12526, - 5710, -158, -401, -1126, -9576, -1990, 252, -422, - 672, 1232, -1960, 3284, 561, -893, 1497, -4365, - 4889, -6878, 612, 6109, 4753, -1459, -2887, -22, - -2277, -1379, 2052, -182, 257, -1823, 2564, -228, - -1418, 1995, -177, -1772, 3053, -506, 2403, 9625, - 1322, -569, -15, -352, -5655, -106, 94, -448, - 74, -1794, 297, -1412, -246, 40, -194, -777, - -754, 12904, 4480, -2113, 1471, -34, -10163, -1225, - -272, -132, 594, 206, -3529, -97, 1664, 577, - 67, -1159, -402, 189, 4255, 1476, 5055, 2393, - 2912, -1105, -132, -1559, -349, -517, -383, -1313, - -455, -621, -215, -738, -756, -262, -898, -425, - -1371, 535, 1417, 14604, -997, -114, -17, -122, - -13017, -60, 44, 118, -46, 1222, -477, -1263, - -83, 32, 86, 888, 5368, -1744, 4083, -1236, - 3753, -1758, -185, -1017, -93, -860, 571, -1338, - 434, 405, -131, 308, -1229, 399, -935, 283, - 1588, -3097, 14415, 3699, -1171, -154, -585, -12683, - -835, -83, 300, -1397, 2725, -358, 699, -3255, - 113, -221, 1030, 264, 212, 7989, 9471, -3344, - 2009, -2, -3895, -5475, -682, -246, -103, -123, - -4618, 43, 1630, 1933, -26, -979, -1161, 410, - 856, 2294, -627, 6930, 6929, -44, -321, -24, - -2931, -2930, -119, 32, 87, -362, -970, 265, - -362, -970, 265, -2931, 2357, -4187, 7162, 7683, - 3371, -339, -1070, -3131, -3603, -693, 602, -1030, - 1830, -1105, 1963, -3359, -485, 861, -1474, -1581, - 350, 4585, 14053, -3819, 1218, -7, -1283, -12054, - -890, -90, -97, -300, -3933, 81, 1068, 3275, - -26, -341, -1045, 284, -3248, 3531, 475, 2137, - 11711, -644, -761, -13, -278, -8372, 700, 94, - -102, 423, -460, -62, 2322, -2524, -340, -1528, - -3017, 3852, 1725, 8440, 5257, -555, -905, -181, - -4348, -1686, 709, 317, -405, 1554, -1984, -889, - 968, -1236, -553, -2708, -909, 3196, 15512, -2528, - 1066, -50, -623, -14686, -390, -69, 177, 861, - -3026, -140, 493, 2393, 59, -208, -1009, 164, - 959, -3370, 9617, 9545, -1761, -56, -693, -5645, - -5561, -189, 197, -563, 1978, -558, 1963, -5603, - 103, -362, 1034, 1026, 7575, 11796, -4845, 3252, - -1703, -3502, -8493, -1433, -645, -177, -5454, 2240, - 3488, -1503, -2341, 961, 787, 1226, -503, 338, - 6409, 1722, 1764, -4191, 6015, -2507, -181, -189, - -1072, -2208, -673, -690, -185, 1639, 440, 451, - -2353, -632, -647, 1538, -2420, 12161, 5038, 1286, - -2098, -357, -9027, -1549, -100, -268, 1796, 744, - -3740, 190, -954, -395, -310, 1557, 645, 164, - -2232, -1341, 7246, 9470, -1977, -304, -109, -3204, - -5474, -238, -182, 987, 593, 1290, 775, -4188, - -269, -161, 874, 1143, 1030, 7034, 4231, 1551, - 3077, -64, -3019, -1093, -146, -577, -442, -266, - -1816, -97, -666, -400, -193, -1321, -794, -291, - 5121, 11835, -477, -1749, 2298, -1601, -8549, -13, - -186, -322, -3699, 149, 344, 546, 1264, -50, - -718, -1660, 66, 245, -3328, 3827, 5921, 9976, - -1045, -676, -894, -2140, -6075, -66, 777, 1203, - -1383, 2027, -2330, -3605, -212, 244, 377, 636, - 3813, 5718, -4666, -3412, 5674, -887, -1995, -1329, - -710, -1965, -1331, 1086, 1628, 794, 1191, -972, - -1320, -1980, 1616, 1181, 1348, -3672, 13154, 6938, - -1690, -110, -823, -10561, -2938, -174, 302, -1082, - 2948, -570, 1555, -5570, 139, -379, 1357, 716, - 2151, -3586, 6949, 12131, -1224, -282, -785, -2947, - -8982, -91, 470, -912, 1521, -1592, 2655, -5145, - 160, -268, 519, 906, -2889, 9647, 10276, -2728, - 995, -509, -5680, -6445, -454, -60, 1701, 1812, - -6051, -481, 1606, 1711, 175, -586, -624, 165, - 6177, 2184, 555, 1985, 6589, -2329, -291, -18, - -240, -2650, -823, -209, -74, -748, -264, -67, - -2484, -878, -223, -798, -492, 391, 17166, -681, - 240, -14, -9, -17987, -28, -3, 11, 515, - -410, -20, 16, 713, 7, -5, -252, 10, - 12628, 5448, -2630, 3011, -2695, -9733, -1811, -422, - -553, -443, -4199, 2027, 874, -2321, -1001, 483, - 2077, 896, -432, 495, -3628, -534, 3447, 7002, - 6751, -803, -17, -725, -2992, -2782, -118, 763, - 112, 1550, 228, -1473, 1495, 220, -1420, -2885, - -5239, 5901, 8107, 3650, 4846, -1675, -2125, -4012, - -813, -1433, 1887, 2592, -2920, 1167, -1315, -1806, - 1550, -1745, -2398, -1080, 6157, 6678, 4099, -1074, - 2348, -2314, -2722, -1025, -70, -336, -2509, -1540, - -1670, 403, 437, 268, -882, -957, -587, 153, - 1079, 16099, 242, -881, 1690, -71, -15820, -3, - -47, -174, -1060, -16, -238, 58, 865, 13, - -111, -1661, -25, 90, -278, 227, -1039, 1636, - 16945, -4, -3, -65, -163, -17526, 3, -17, - 14, 27, -22, 103, 287, -234, 1074, -1693, - 15778, -1454, 574, -603, -107, -15195, -129, -20, - -22, 0, 1400, -553, 51, 581, -53, 21, - 103, -9, 3, -3, 2406, -836, 13224, 7993, - -4266, -353, -42, -10673, -3899, -1111, 122, -1942, - 674, -1174, 407, -6451, 626, -217, 3443, 2081, - 3184, 14368, -3336, 2255, -1801, -619, -12600, -679, - -310, -198, -2793, 648, 2926, -438, -1977, 459, - 350, 1580, -366, 247, -1698, 17076, 2504, -539, - -646, -176, -17798, -382, -17, -25, 1770, 259, - -2610, -55, 561, 82, -67, 673, 98, -21, - 2375, -797, -2696, 14483, 5383, -344, -38, -443, - -12803, -1769, 115, 391, -131, -2100, 705, 2384, - -780, 262, 886, -4759, -2691, 2554, -4520, 9573, - 10655, -442, -398, -1247, -5594, -6930, 419, -742, - 704, 1572, -1492, 2641, 1750, -1661, 2939, -6226, - -4332, -4399, -1657, 4880, 7375, -1145, -1181, -167, - -1453, -3319, -1163, -438, -444, 1290, 1310, 493, - 1950, 1980, 745, -2196, -3498, 7405, 9955, 2693, - -2971, -746, -3347, -6049, -442, -538, 1581, 2125, - -4499, 575, -1217, -1636, -634, 1342, 1805, 488, - 6717, -3792, 7739, 2798, 3489, -2754, -877, -3655, - -477, -743, 1554, -3173, 1791, -1147, 647, -1321, - -1430, 807, -1648, -595, 5263, 9770, 3463, 1069, - -3971, -1690, -5826, -732, -69, -962, -3138, -1112, - -2065, -343, -637, -226, 1275, 2368, 839, 259, - 1243, -2634, 16772, 1871, 332, -94, -423, -17169, - -213, -6, 199, -1273, 2696, -142, 300, -1915, - -25, 53, -339, -37, 2691, 2836, 3105, 5711, - 4817, -442, -491, -588, -1991, -1416, -465, -510, - -537, -938, -988, -1082, -791, -834, -913, -1679, - 4366, 2944, 7210, 3627, 1161, -1163, -529, -3172, - -803, -82, -784, -1921, -1295, -966, -651, -1596, - -309, -208, -511, -257, 13888, 3951, -671, -2305, - 3354, -11773, -953, -27, -324, -686, -3349, 569, - 161, 1954, 556, -94, -2843, -809, 137, 472, - 7053, 5847, 2929, 8378, -4794, -3036, -2086, -523, - -4284, -1403, -2517, -1261, -1045, -3607, -2990, -1498, - 2064, 1711, 857, 2451, -2191, 12838, 9182, -3915, - 1617, -293, -10059, -5146, -935, -159, 1717, 1228, - -7195, -523, 3068, 2194, 216, -1267, -906, 386, - -4881, 13114, 5767, -435, 4155, -1454, -10498, -2030, - -11, -1054, 3907, 1718, -4616, -129, 348, 153, - 1238, -3326, -1462, 110, 7843, -1250, 210, 7106, - -5203, -3754, -95, -2, -3082, -1652, 598, -100, - 16, -3402, 542, -91, 2491, -397, 66, 2257, - -2463, 8168, 14551, -3908, 1828, -370, -4072, -12923, - -932, -204, 1228, 2188, -7254, -587, 1948, 3471, - 274, -911, -1623, 436, -1579, 347, -272, -2735, - 16031, -152, -7, -4, -456, -15686, 33, -26, - 5, -263, 58, -45, 1545, -340, 266, 2676, - -6327, 1328, 5093, -5079, 7617, -2443, -107, -1583, - -1574, -3541, 513, 1967, -413, -1961, 411, 1578, - 2941, -617, -2367, 2361, 3286, -4509, 11306, 11025, - -2623, -659, -1241, -7802, -7419, -420, 904, -2267, - 3112, -2211, 3034, -7608, 526, -722, 1810, 1765, - 5567, 17853, -3754, 1166, -519, -1892, -19455, -860, - -83, -16, -6067, 1275, 4090, -396, -1271, 267, - 176, 566, -119, 37, -2136, -424, 15292, 5108, - -1648, -278, -10, -14273, -1593, -165, -55, 1993, - 396, 666, 132, -4768, -214, -42, 1538, 514, - 2267, -3297, 2549, 16563, -791, -313, -663, -396, - -16745, -38, 456, -352, 513, -2291, 3333, -2576, - 109, -159, 123, 799, 3655, 1899, -3364, 6279, - 12510, -815, -220, -690, -2406, -9552, -423, 750, - 390, -1400, -728, 1289, -2791, -1450, 2568, -4794, - 8052, 2285, -6193, 5138, 6003, -3957, -318, -2341, - -1611, -2199, -1123, 3044, 864, -2525, -716, 1942, - -2950, -837, 2269, -1882, -386, -2291, 7679, 15387, - -2723, -9, -320, -3599, -14452, -452, -54, 181, - 1074, 362, 2152, -7212, -64, -380, 1276, 2557, - 2777, -1173, 3984, 13079, 2508, -470, -84, -969, - -10440, -384, 198, -675, 285, -2217, 936, -3180, - -425, 179, -610, -2002, -1879, 1771, -2684, 16705, - 1833, -215, -191, -439, -17032, -205, 203, -308, - 290, 1916, -1805, 2736, 210, -198, 300, -1869, - 1052, 4495, 15519, 1467, -4032, -67, -1233, -14700, - -131, -992, -288, -997, -4257, -94, -402, -1389, - 259, 1106, 3819, 361, 3010, 2544, 6969, 7559, - 1996, -553, -395, -2964, -3487, -243, -467, -1280, - -1082, -1388, -1174, -3215, -366, -310, -849, -921, - -5209, -1867, 8713, 10351, 1549, -1656, -212, -4634, - -6540, -146, -593, 2770, 993, 3291, 1180, -5505, - 492, 176, -824, -979, -4314, 8513, 913, 7547, - -2723, -1135, -4423, -50, -3476, -452, 2241, 240, - -474, 1987, -3921, -420, -717, 1415, 151, 1254, - 12929, -1219, 2448, 1757, 6303, -10204, -90, -365, - -188, -2425, 962, -1932, 182, -1386, 130, -262, - -4974, 469, -941, -676, 6465, 4132, 3167, 3160, - 5697, -2551, -1042, -612, -609, -1981, -1630, -1249, - -798, -1247, -797, -611, -2248, -1437, -1101, -1099, - -3636, 4859, 18914, -1335, 810, -807, -1441, -21836, - -108, -40, 1078, 4198, -5609, -296, 396, 1541, - 179, -240, -936, 66, 8844, 7864, 654, -4063, - -5680, -4774, -3774, -26, -1007, -1969, -4245, -353, - -314, 2193, 1950, 162, 3066, 2726, 226, -1408, - 1859, 2634, 9228, 996, 9464, -211, -423, -5197, - -60, -5467, -299, -1047, -1483, -113, -160, -561, - -1074, -1521, -5330, -575, 2949, 12260, 10290, -497, - -3943, -530, -9174, -6463, -15, -949, -2206, -1852, - -7700, 89, 372, 312, 709, 2950, 2476, -119, - -2903, 1552, 14867, 9970, -496, -514, -147, -13491, - -6068, -15, 275, 2634, -1408, 1766, -944, -9047, - -87, 47, 450, 302, 3243, 8234, 7586, 3373, - 2151, -642, -4138, -3512, -694, -282, -1630, -1501, - -3812, -667, -1695, -1561, -425, -1081, -996, -442, - -9631, 60, 3501, 5359, 10150, -5662, 0, -748, - -1752, -6288, 35, 2058, -12, 3150, -19, -1145, - 5967, -37, -2169, -3320, -6874, -2553, -5446, -2195, - -7841, -2884, -397, -1810, -294, -3753, -1071, -2285, - -848, -921, -342, -729, -3290, -1221, -2606, -1050, - -3413, -1141, 4630, 13612, 7897, -711, -79, -1308, - -11310, -3806, -237, 964, 322, 2836, 948, -3847, - 1645, 550, -2231, -6561, 4410, -5678, 8006, -3992, - 3811, -1187, -1968, -3912, -973, -886, 1528, -2155, - 2775, 1074, -1383, 1951, -1025, 1321, -1862, 928, - 5659, 11535, 2203, -452, 7169, -1954, -8121, -296, - -12, -3137, -3984, -761, -1551, 156, 318, 60, - -2476, -5048, -964, 197, 2914, -2914, 3485, -3965, - 13675, -518, -518, -741, -959, -11414, 518, -620, - 620, 705, -705, 843, -2433, 2432, -2909, 3310, - 7843, 1907, 1022, 8882, 7972, -3755, -222, -63, - -4815, -3879, -913, -489, -119, -4252, -1034, -554, - -3816, -928, -497, -4322, 13807, 9531, 1436, 1612, - 1779, -11636, -5544, -125, -158, -193, -8032, -1210, - -835, -1358, -938, -141, -1499, -1035, -156, -175, - 13620, -5337, 5450, -2263, 1723, -11322, -1738, -1813, - -312, -181, 4436, -4531, 1775, 1881, -737, 752, - -1432, 561, -573, 238, 5297, 8374, 8872, 7694, - 6538, -1712, -4280, -4804, -3613, -2609, -2707, -2868, - -4534, -2487, -3932, -4166, -2113, -3341, -3540, -3070 -}; - -/** - * 0.65^i (Zero part) and 0.75^i (Pole part) scaled by 2^15 - */ -static const int16_t postfilter_tbl[2][LPC_ORDER] = { - /* Zero */ - {21299, 13844, 8999, 5849, 3802, 2471, 1606, 1044, 679, 441}, - /* Pole */ - {24576, 18432, 13824, 10368, 7776, 5832, 4374, 3281, 2460, 1845} -}; - -/** - * Hamming window coefficients scaled by 2^15 - */ -static const int16_t hamming_window[LPC_FRAME] = { - 2621, 2631, 2659, 2705, 2770, 2853, 2955, 3074, 3212, 3367, - 3541, 3731, 3939, 4164, 4405, 4663, 4937, 5226, 5531, 5851, - 6186, 6534, 6897, 7273, 7661, 8062, 8475, 8899, 9334, 9780, - 10235, 10699, 11172, 11653, 12141, 12636, 13138, 13645, 14157, 14673, - 15193, 15716, 16242, 16769, 17298, 17827, 18356, 18884, 19411, 19935, - 20457, 20975, 21489, 21999, 22503, 23002, 23494, 23978, 24455, 24924, - 25384, 25834, 26274, 26704, 27122, 27529, 27924, 28306, 28675, 29031, - 29373, 29700, 30012, 30310, 30592, 30857, 31107, 31340, 31557, 31756, - 31938, 32102, 32249, 32377, 32488, 32580, 32654, 32710, 32747, 32766, - 32766, 32747, 32710, 32654, 32580, 32488, 32377, 32249, 32102, 31938, - 31756, 31557, 31340, 31107, 30857, 30592, 30310, 30012, 29700, 29373, - 29031, 28675, 28306, 27924, 27529, 27122, 26704, 26274, 25834, 25384, - 24924, 24455, 23978, 23494, 23002, 22503, 21999, 21489, 20975, 20457, - 19935, 19411, 18884, 18356, 17827, 17298, 16769, 16242, 15716, 15193, - 14673, 14157, 13645, 13138, 12636, 12141, 11653, 11172, 10699, 10235, - 9780, 9334, 8899, 8475, 8062, 7661, 7273, 6897, 6534, 6186, - 5851, 5531, 5226, 4937, 4663, 4405, 4164, 3939, 3731, 3541, - 3367, 3212, 3074, 2955, 2853, 2770, 2705, 2659, 2631, 2621 -}; - -/** - * Binomial window coefficients scaled by 2^15 - */ -static const int16_t binomial_window[LPC_ORDER] = { - 32749, 32695, 32604, 32477, 32315, 32118, 31887, 31622, 31324, 30995 -}; - -/** - * 0.994^i scaled by 2^15 - */ -static const int16_t bandwidth_expand[LPC_ORDER] = { - 32571, 32376, 32182, 31989, 31797, 31606, 31416, 31228, 31040, 30854 -}; - -/** - * 0.5^i scaled by 2^15 - */ -static const int16_t percept_flt_tbl[2][LPC_ORDER] = { - /* Zero part */ - {29491, 26542, 23888, 21499, 19349, 17414, 15673, 14106, 12695, 11425}, - /* Pole part */ - {16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32} -}; - -static const int cng_adaptive_cb_lag[4] = { 1, 0, 1, 3 }; - -static const int cng_filt[4] = { 273, 998, 499, 333 }; - -static const int cng_bseg[3] = { 2048, 18432, 231233 }; +extern const int16_t ff_g723_1_adaptive_cb_gain85 [ 85 * 20]; +extern const int16_t ff_g723_1_adaptive_cb_gain170[170 * 20]; #endif /* AVCODEC_G723_1_H */ diff --git a/libavcodec/g723_1dec.c b/libavcodec/g723_1dec.c index f601d31d0..fddd4b03c 100644 --- a/libavcodec/g723_1dec.c +++ b/libavcodec/g723_1dec.c @@ -40,6 +40,78 @@ #define CNG_RANDOM_SEED 12345 +/** + * Postfilter gain weighting factors scaled by 2^15 + */ +static const int16_t ppf_gain_weight[2] = {0x1800, 0x2000}; + +static const int16_t pitch_contrib[340] = { + 60, 0, 0, 2489, 60, 0, 0, 5217, + 1, 6171, 0, 3953, 0, 10364, 1, 9357, + -1, 8843, 1, 9396, 0, 5794, -1, 10816, + 2, 11606, -2, 12072, 0, 8616, 1, 12170, + 0, 14440, 0, 7787, -1, 13721, 0, 18205, + 0, 14471, 0, 15807, 1, 15275, 0, 13480, + -1, 18375, -1, 0, 1, 11194, -1, 13010, + 1, 18836, -2, 20354, 1, 16233, -1, 0, + 60, 0, 0, 12130, 0, 13385, 1, 17834, + 1, 20875, 0, 21996, 1, 0, 1, 18277, + -1, 21321, 1, 13738, -1, 19094, -1, 20387, + -1, 0, 0, 21008, 60, 0, -2, 22807, + 0, 15900, 1, 0, 0, 17989, -1, 22259, + 1, 24395, 1, 23138, 0, 23948, 1, 22997, + 2, 22604, -1, 25942, 0, 26246, 1, 25321, + 0, 26423, 0, 24061, 0, 27247, 60, 0, + -1, 25572, 1, 23918, 1, 25930, 2, 26408, + -1, 19049, 1, 27357, -1, 24538, 60, 0, + -1, 25093, 0, 28549, 1, 0, 0, 22793, + -1, 25659, 0, 29377, 0, 30276, 0, 26198, + 1, 22521, -1, 28919, 0, 27384, 1, 30162, + -1, 0, 0, 24237, -1, 30062, 0, 21763, + 1, 30917, 60, 0, 0, 31284, 0, 29433, + 1, 26821, 1, 28655, 0, 31327, 2, 30799, + 1, 31389, 0, 32322, 1, 31760, -2, 31830, + 0, 26936, -1, 31180, 1, 30875, 0, 27873, + -1, 30429, 1, 31050, 0, 0, 0, 31912, + 1, 31611, 0, 31565, 0, 25557, 0, 31357, + 60, 0, 1, 29536, 1, 28985, -1, 26984, + -1, 31587, 2, 30836, -2, 31133, 0, 30243, + -1, 30742, -1, 32090, 60, 0, 2, 30902, + 60, 0, 0, 30027, 0, 29042, 60, 0, + 0, 31756, 0, 24553, 0, 25636, -2, 30501, + 60, 0, -1, 29617, 0, 30649, 60, 0, + 0, 29274, 2, 30415, 0, 27480, 0, 31213, + -1, 28147, 0, 30600, 1, 31652, 2, 29068, + 60, 0, 1, 28571, 1, 28730, 1, 31422, + 0, 28257, 0, 24797, 60, 0, 0, 0, + 60, 0, 0, 22105, 0, 27852, 60, 0, + 60, 0, -1, 24214, 0, 24642, 0, 23305, + 60, 0, 60, 0, 1, 22883, 0, 21601, + 60, 0, 2, 25650, 60, 0, -2, 31253, + -2, 25144, 0, 17998 +}; + +/** + * Size of the MP-MLQ fixed excitation codebooks + */ +static const int32_t max_pos[4] = {593775, 142506, 593775, 142506}; + +/** + * 0.65^i (Zero part) and 0.75^i (Pole part) scaled by 2^15 + */ +static const int16_t postfilter_tbl[2][LPC_ORDER] = { + /* Zero */ + {21299, 13844, 8999, 5849, 3802, 2471, 1606, 1044, 679, 441}, + /* Pole */ + {24576, 18432, 13824, 10368, 7776, 5832, 4374, 3281, 2460, 1845} +}; + +static const int cng_adaptive_cb_lag[4] = { 1, 0, 1, 3 }; + +static const int cng_filt[4] = { 273, 998, 499, 333 }; + +static const int cng_bseg[3] = { 2048, 18432, 231233 }; + static av_cold int g723_1_decode_init(AVCodecContext *avctx) { G723_1_Context *s = avctx->priv_data; @@ -221,16 +293,16 @@ static void gen_fcb_excitation(int16_t *vector, G723_1_Subframe *subfrm, j = PULSE_MAX - pulses[index]; temp = subfrm->pulse_pos; for (i = 0; i < SUBFRAME_LEN / GRID_SIZE; i++) { - temp -= combinatorial_table[j][i]; + temp -= ff_g723_1_combinatorial_table[j][i]; if (temp >= 0) continue; - temp += combinatorial_table[j++][i]; + temp += ff_g723_1_combinatorial_table[j++][i]; if (subfrm->pulse_sign & (1 << (PULSE_MAX - j))) { vector[subfrm->grid_index + GRID_SIZE * i] = - -fixed_cb_gain[subfrm->amp_index]; + -ff_g723_1_fixed_cb_gain[subfrm->amp_index]; } else { vector[subfrm->grid_index + GRID_SIZE * i] = - fixed_cb_gain[subfrm->amp_index]; + ff_g723_1_fixed_cb_gain[subfrm->amp_index]; } if (j == PULSE_MAX) break; @@ -238,7 +310,7 @@ static void gen_fcb_excitation(int16_t *vector, G723_1_Subframe *subfrm, if (subfrm->dirac_train == 1) ff_g723_1_gen_dirac_train(vector, pitch_lag); } else { /* 5300 bps */ - int cb_gain = fixed_cb_gain[subfrm->amp_index]; + int cb_gain = ff_g723_1_fixed_cb_gain[subfrm->amp_index]; int cb_shift = subfrm->grid_index; int cb_sign = subfrm->pulse_sign; int cb_pos = subfrm->pulse_pos; @@ -915,7 +987,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data, int16_t *vector_ptr = p->excitation + PITCH_MAX; /* Update interpolation gain memory */ - p->interp_gain = fixed_cb_gain[(p->subframe[2].amp_index + + p->interp_gain = ff_g723_1_fixed_cb_gain[(p->subframe[2].amp_index + p->subframe[3].amp_index) >> 1]; for (i = 0; i < SUBFRAMES; i++) { gen_fcb_excitation(vector_ptr, &p->subframe[i], p->cur_rate, diff --git a/libavcodec/g723_1enc.c b/libavcodec/g723_1enc.c index 592840566..11b0c7f71 100644 --- a/libavcodec/g723_1enc.c +++ b/libavcodec/g723_1enc.c @@ -40,6 +40,54 @@ #define BITSTREAM_WRITER_LE #include "put_bits.h" +/** + * Hamming window coefficients scaled by 2^15 + */ +static const int16_t hamming_window[LPC_FRAME] = { + 2621, 2631, 2659, 2705, 2770, 2853, 2955, 3074, 3212, 3367, + 3541, 3731, 3939, 4164, 4405, 4663, 4937, 5226, 5531, 5851, + 6186, 6534, 6897, 7273, 7661, 8062, 8475, 8899, 9334, 9780, + 10235, 10699, 11172, 11653, 12141, 12636, 13138, 13645, 14157, 14673, + 15193, 15716, 16242, 16769, 17298, 17827, 18356, 18884, 19411, 19935, + 20457, 20975, 21489, 21999, 22503, 23002, 23494, 23978, 24455, 24924, + 25384, 25834, 26274, 26704, 27122, 27529, 27924, 28306, 28675, 29031, + 29373, 29700, 30012, 30310, 30592, 30857, 31107, 31340, 31557, 31756, + 31938, 32102, 32249, 32377, 32488, 32580, 32654, 32710, 32747, 32766, + 32766, 32747, 32710, 32654, 32580, 32488, 32377, 32249, 32102, 31938, + 31756, 31557, 31340, 31107, 30857, 30592, 30310, 30012, 29700, 29373, + 29031, 28675, 28306, 27924, 27529, 27122, 26704, 26274, 25834, 25384, + 24924, 24455, 23978, 23494, 23002, 22503, 21999, 21489, 20975, 20457, + 19935, 19411, 18884, 18356, 17827, 17298, 16769, 16242, 15716, 15193, + 14673, 14157, 13645, 13138, 12636, 12141, 11653, 11172, 10699, 10235, + 9780, 9334, 8899, 8475, 8062, 7661, 7273, 6897, 6534, 6186, + 5851, 5531, 5226, 4937, 4663, 4405, 4164, 3939, 3731, 3541, + 3367, 3212, 3074, 2955, 2853, 2770, 2705, 2659, 2631, 2621 +}; + +/** + * Binomial window coefficients scaled by 2^15 + */ +static const int16_t binomial_window[LPC_ORDER] = { + 32749, 32695, 32604, 32477, 32315, 32118, 31887, 31622, 31324, 30995 +}; + +/** + * 0.994^i scaled by 2^15 + */ +static const int16_t bandwidth_expand[LPC_ORDER] = { + 32571, 32376, 32182, 31989, 31797, 31606, 31416, 31228, 31040, 30854 +}; + +/** + * 0.5^i scaled by 2^15 + */ +static const int16_t percept_flt_tbl[2][LPC_ORDER] = { + /* Zero part */ + {29491, 26542, 23888, 21499, 19349, 17414, 15673, 14106, 12695, 11425}, + /* Pole part */ + {16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32} +}; + static av_cold int g723_1_encode_init(AVCodecContext *avctx) { G723_1_Context *s = avctx->priv_data; @@ -242,14 +290,14 @@ static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp) p = 0; temp = 0; for (i = 0; i <= LPC_ORDER / 2; i++) - temp += f[2 * i] * cos_tab[0]; + temp += f[2 * i] * G723_1_COS_TAB_FIRST_ELEMENT; prev_val = av_clipl_int32(temp << 1); count = 0; for (i = 1; i < COS_TBL_SIZE / 2; i++) { /* Evaluate */ temp = 0; for (j = 0; j <= LPC_ORDER / 2; j++) - temp += f[LPC_ORDER - 2 * j + p] * cos_tab[i * j % COS_TBL_SIZE]; + temp += f[LPC_ORDER - 2 * j + p] * ff_g723_1_cos_tab[i * j % COS_TBL_SIZE]; cur_val = av_clipl_int32(temp << 1); /* Check for sign change, indicating a zero crossing */ @@ -273,7 +321,7 @@ static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp) temp = 0; for (j = 0; j <= LPC_ORDER / 2; j++) temp += f[LPC_ORDER - 2 * j + p] * - cos_tab[i * j % COS_TBL_SIZE]; + ff_g723_1_cos_tab[i * j % COS_TBL_SIZE]; cur_val = av_clipl_int32(temp << 1); } prev_val = cur_val; @@ -298,11 +346,11 @@ static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp) \ for (i = 0; i < LSP_CB_SIZE; i++) { \ for (j = 0; j < size; j++){ \ - temp[j] = (weight[j + (offset)] * lsp_band##num[i][j] + \ + temp[j] = (weight[j + (offset)] * ff_g723_1_lsp_band##num[i][j] + \ (1 << 14)) >> 15; \ } \ error = ff_g723_1_dot_product(lsp + (offset), temp, size) << 1; \ - error -= ff_g723_1_dot_product(lsp_band##num[i], temp, size); \ + error -= ff_g723_1_dot_product(ff_g723_1_lsp_band##num[i], temp, size); \ if (error > max) { \ max = error; \ lsp_index[num] = i; \ @@ -642,7 +690,7 @@ static void acb_search(G723_1_ChannelContext *p, int16_t *residual, { int16_t flt_buf[PITCH_ORDER][SUBFRAME_LEN]; - const int16_t *cb_tbl = adaptive_cb_gain85; + const int16_t *cb_tbl = ff_g723_1_adaptive_cb_gain85; int ccr_buf[PITCH_ORDER * SUBFRAMES << 2]; @@ -720,7 +768,7 @@ static void acb_search(G723_1_ChannelContext *p, int16_t *residual, /* Select quantization table */ if (!odd_frame && pitch_lag + i - 1 >= SUBFRAME_LEN - 2 || odd_frame && pitch_lag >= SUBFRAME_LEN - 2) { - cb_tbl = adaptive_cb_gain170; + cb_tbl = ff_g723_1_adaptive_cb_gain170; tbl_size = 170; } @@ -838,7 +886,7 @@ static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp, min = 1 << 30; max_amp_index = GAIN_LEVELS - 2; for (j = max_amp_index; j >= 2; j--) { - temp = av_clipl_int32((int64_t) fixed_cb_gain[j] * + temp = av_clipl_int32((int64_t) ff_g723_1_fixed_cb_gain[j] * impulse_corr[0] << 1); temp = FFABS(temp - amp); if (temp < min) { @@ -855,7 +903,7 @@ static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp, ccr2[k] = ccr1[k]; } param.amp_index = max_amp_index + j - 2; - amp = fixed_cb_gain[param.amp_index]; + amp = ff_g723_1_fixed_cb_gain[param.amp_index]; param.pulse_sign[0] = (ccr2[param.pulse_pos[0]] < 0) ? -amp : amp; temp_corr[param.pulse_pos[0]] = 1; @@ -942,7 +990,7 @@ static void pack_fcb_param(G723_1_Subframe *subfrm, FCBParam *optim, for (i = 0; i < SUBFRAME_LEN >> 1; i++) { int val = buf[optim->grid_index + (i << 1)]; if (!val) { - subfrm->pulse_pos += combinatorial_table[j][i]; + subfrm->pulse_pos += ff_g723_1_combinatorial_table[j][i]; } else { subfrm->pulse_sign <<= 1; if (val < 0) @@ -1030,7 +1078,7 @@ static int pack_bitstream(G723_1_ChannelContext *p, AVPacket *avpkt) put_bits(&pb, 1, p->subframe[3].grid_index); if (p->cur_rate == RATE_6300) { - skip_put_bits(&pb, 1); /* reserved bit */ + put_bits(&pb, 1, 0); /* reserved bit */ /* Write 13 bit combined position index */ temp = (p->subframe[0].pulse_pos >> 16) * 810 + diff --git a/libavcodec/g726.c b/libavcodec/g726.c index 80cb06491..71f579141 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -513,7 +513,7 @@ AVCodec ff_adpcm_g726_decoder = { .init = g726_decode_init, .decode = g726_decode_frame, .flush = g726_decode_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; #endif @@ -526,7 +526,7 @@ AVCodec ff_adpcm_g726le_decoder = { .init = g726_decode_init, .decode = g726_decode_frame, .flush = g726_decode_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"), }; #endif diff --git a/libavcodec/gdv.c b/libavcodec/gdv.c index f00f3ac14..860634c9e 100644 --- a/libavcodec/gdv.c +++ b/libavcodec/gdv.c @@ -461,7 +461,8 @@ static int gdv_decode_frame(AVCodecContext *avctx, void *data, GetByteContext *gb = &gdv->gb; PutByteContext *pb = &gdv->pb; AVFrame *frame = data; - int ret, i, pal_size; + int ret, i; + buffer_size_t pal_size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &pal_size); int compression; unsigned flags; @@ -551,7 +552,7 @@ static int gdv_decode_frame(AVCodecContext *avctx, void *data, *got_frame = 1; - return ret < 0 ? ret : avpkt->size; + return avpkt->size; } static av_cold int gdv_decode_close(AVCodecContext *avctx) diff --git a/libavcodec/gif.c b/libavcodec/gif.c index e2242d043..cafd93e19 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -47,10 +47,12 @@ typedef struct GIFContext { const AVClass *class; LZWState *lzw; uint8_t *buf; + uint8_t *shrunk_buf; int buf_size; AVFrame *last_frame; int flags; int image; + int use_global_palette; uint32_t palette[AVPALETTE_COUNT]; ///< local reference palette for !pal8 int palette_loaded; int transparent_index; @@ -62,6 +64,38 @@ enum { GF_TRANSDIFF = 1<<1, }; +static void shrink_palette(const uint32_t *src, uint8_t *map, + uint32_t *dst, size_t *palette_count) +{ + size_t colors_seen = 0; + + for (size_t i = 0; i < AVPALETTE_COUNT; i++) { + int seen = 0; + for (size_t c = 0; c < colors_seen; c++) { + if (src[i] == dst[c]) { + seen = 1; + break; + } + } + if (!seen) { + dst[colors_seen] = src[i]; + map[i] = colors_seen; + colors_seen++; + } + } + + *palette_count = colors_seen; +} + +static void remap_frame_to_palette(const uint8_t *src, int src_linesize, + uint8_t *dst, int dst_linesize, + int w, int h, uint8_t *map) +{ + for (int i = 0; i < h; i++) + for (int j = 0; j < w; j++) + dst[i * dst_linesize + j] = map[src[i * src_linesize + j]]; +} + static int is_image_translucent(AVCodecContext *avctx, const uint8_t *buf, const int linesize) { @@ -266,8 +300,19 @@ static int gif_image_write_image(AVCodecContext *avctx, int x_start = 0, y_start = 0, trans = s->transparent_index; int bcid = -1, honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && !palette; const uint8_t *ptr; + uint32_t shrunk_palette[AVPALETTE_COUNT]; + uint8_t map[AVPALETTE_COUNT] = { 0 }; + size_t shrunk_palette_count = 0; - if (!s->image && avctx->frame_number && is_image_translucent(avctx, buf, linesize)) { + /* + * We memset to 0xff instead of 0x00 so that the transparency detection + * doesn't pick anything after the palette entries as the transparency + * index, and because GIF89a requires us to always write a power-of-2 + * number of palette entries. + */ + memset(shrunk_palette, 0xff, AVPALETTE_SIZE); + + if (!s->image && is_image_translucent(avctx, buf, linesize)) { gif_crop_translucent(avctx, buf, linesize, &width, &height, &x_start, &y_start); honor_transparency = 0; disposal = GCE_DISPOSAL_BACKGROUND; @@ -293,12 +338,14 @@ static int gif_image_write_image(AVCodecContext *avctx, bcid = get_palette_transparency_index(global_palette); - bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */ + bytestream_put_byte(bytestream, ((uint8_t) s->use_global_palette << 7) | 0x70 | (s->use_global_palette ? 7 : 0)); /* flags: global clut, 256 entries */ bytestream_put_byte(bytestream, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : bcid); /* background color index */ bytestream_put_byte(bytestream, aspect); - for (int i = 0; i < 256; i++) { - const uint32_t v = global_palette[i] & 0xffffff; - bytestream_put_be24(bytestream, v); + if (s->use_global_palette) { + for (int i = 0; i < 256; i++) { + const uint32_t v = global_palette[i] & 0xffffff; + bytestream_put_be24(bytestream, v); + } } } @@ -312,6 +359,11 @@ static int gif_image_write_image(AVCodecContext *avctx, if (trans < 0) honor_transparency = 0; + if (palette || !s->use_global_palette) { + const uint32_t *pal = palette ? palette : s->palette; + shrink_palette(pal, map, shrunk_palette, &shrunk_palette_count); + } + bcid = honor_transparency || disposal == GCE_DISPOSAL_BACKGROUND ? trans : get_palette_transparency_index(palette); /* graphic control extension */ @@ -320,7 +372,7 @@ static int gif_image_write_image(AVCodecContext *avctx, bytestream_put_byte(bytestream, 0x04); /* block size */ bytestream_put_byte(bytestream, disposal<<2 | (bcid >= 0)); bytestream_put_le16(bytestream, 5); // default delay - bytestream_put_byte(bytestream, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : bcid); + bytestream_put_byte(bytestream, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : (shrunk_palette_count ? map[bcid] : bcid)); bytestream_put_byte(bytestream, 0x00); /* image block */ @@ -330,23 +382,37 @@ static int gif_image_write_image(AVCodecContext *avctx, bytestream_put_le16(bytestream, width); bytestream_put_le16(bytestream, height); - if (!palette) { - bytestream_put_byte(bytestream, 0x00); /* flags */ - } else { + if (palette || !s->use_global_palette) { + unsigned pow2_count = av_log2(shrunk_palette_count - 1); 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_byte(bytestream, 1<<7 | pow2_count); /* flags */ + for (i = 0; i < 1 << (pow2_count + 1); i++) { + const uint32_t v = shrunk_palette[i]; bytestream_put_be24(bytestream, v); } + } else { + bytestream_put_byte(bytestream, 0x00); /* flags */ } bytestream_put_byte(bytestream, 0x08); ff_lzw_encode_init(s->lzw, s->buf, s->buf_size, - 12, FF_LZW_GIF, put_bits); + 12, FF_LZW_GIF, 1); - ptr = buf + y_start*linesize + x_start; + if (shrunk_palette_count) { + if (!s->shrunk_buf) { + s->shrunk_buf = av_malloc(avctx->height * linesize); + if (!s->shrunk_buf) { + av_log(avctx, AV_LOG_ERROR, "Could not allocated remapped frame buffer.\n"); + return AVERROR(ENOMEM); + } + } + remap_frame_to_palette(buf, linesize, s->shrunk_buf, linesize, avctx->width, avctx->height, map); + ptr = s->shrunk_buf + y_start*linesize + x_start; + } else { + ptr = buf + y_start*linesize + x_start; + } if (honor_transparency) { const int ref_linesize = s->last_frame->linesize[0]; const uint8_t *ref = s->last_frame->data[0] + y_start*ref_linesize + x_start; @@ -366,7 +432,7 @@ static int gif_image_write_image(AVCodecContext *avctx, ptr += linesize; } } - len += ff_lzw_encode_flush(s->lzw, flush_put_bits); + len += ff_lzw_encode_flush(s->lzw); ptr = s->buf; while (len > 0) { @@ -460,6 +526,7 @@ static int gif_encode_close(AVCodecContext *avctx) av_freep(&s->lzw); av_freep(&s->buf); + av_freep(&s->shrunk_buf); s->buf_size = 0; av_frame_free(&s->last_frame); av_freep(&s->tmpl); @@ -473,6 +540,7 @@ static const AVOption gif_options[] = { { "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" }, { "gifimage", "enable encoding only images per frame", OFFSET(image), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { "global_palette", "write a palette to the global gif header where feasible", OFFSET(use_global_palette), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { NULL } }; @@ -497,4 +565,5 @@ AVCodec ff_gif_encoder = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE }, .priv_class = &gif_class, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 7fd46a91b..4d531cf80 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -66,9 +66,12 @@ static inline int get_ue_golomb(GetBitContext *gb) return ff_ue_golomb_vlc_code[buf]; } else { int log = 2 * av_log2(buf) - 31; + + skip_bits_long(gb, 32 - log); + if (log < 7) + return AVERROR_INVALIDDATA; buf >>= log; buf--; - skip_bits_long(gb, 32 - log); return buf; } @@ -87,10 +90,8 @@ static inline int get_ue_golomb(GetBitContext *gb) int log = 2 * av_log2(buf) - 31; LAST_SKIP_BITS(re, gb, 32 - log); CLOSE_READER(re, gb); - if (log < 7) { - av_log(NULL, AV_LOG_ERROR, "Invalid UE golomb code\n"); + if (log < 7) return AVERROR_INVALIDDATA; - } buf >>= log; buf--; @@ -115,7 +116,8 @@ static inline unsigned get_ue_golomb_long(GetBitContext *gb) /** * read unsigned exp golomb code, constraint to a max of 31. - * the return value is undefined if the stored value exceeds 31. + * If the value encountered is not in 0..31, the return value + * is outside the range 0..30. */ static inline int get_ue_golomb_31(GetBitContext *gb) { diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c index cd5699518..bf3740aa5 100644 --- a/libavcodec/gsmdec.c +++ b/libavcodec/gsmdec.c @@ -120,7 +120,7 @@ AVCodec ff_gsm_decoder = { .init = gsm_init, .decode = gsm_decode_frame, .flush = gsm_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; #endif #if CONFIG_GSM_MS_DECODER @@ -133,6 +133,6 @@ AVCodec ff_gsm_ms_decoder = { .init = gsm_init, .decode = gsm_decode_frame, .flush = gsm_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; #endif diff --git a/libavcodec/h261.c b/libavcodec/h261.c index 47bad4e57..01abfadcd 100644 --- a/libavcodec/h261.c +++ b/libavcodec/h261.c @@ -30,8 +30,6 @@ #define IS_FIL(a) ((a) & MB_TYPE_H261_FIL) -uint8_t ff_h261_rl_table_store[2][2 * MAX_RUN + MAX_LEVEL + 3]; - static void h261_loop_filter(uint8_t *src, int stride) { int x, y, xy, yz; @@ -79,14 +77,3 @@ void ff_h261_loop_filter(MpegEncContext *s) 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; - - ff_rl_init(&ff_h261_rl_tcoeff, ff_h261_rl_table_store); - done = 1; -} diff --git a/libavcodec/h261.h b/libavcodec/h261.h index 399a404b2..25728a295 100644 --- a/libavcodec/h261.h +++ b/libavcodec/h261.h @@ -48,8 +48,6 @@ typedef struct 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]; @@ -60,7 +58,6 @@ 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); diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index 14a874c45..eb544e604 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -26,6 +26,7 @@ */ #include "libavutil/avassert.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "mpeg_er.h" #include "mpegutils.h" @@ -34,7 +35,7 @@ #include "h261.h" #include "internal.h" -#define H261_MBA_VLC_BITS 9 +#define H261_MBA_VLC_BITS 8 #define H261_MTYPE_VLC_BITS 6 #define H261_MV_VLC_BITS 7 #define H261_CBP_VLC_BITS 9 @@ -47,46 +48,40 @@ static VLC h261_mtype_vlc; static VLC h261_mv_vlc; static VLC h261_cbp_vlc; -static av_cold void h261_decode_init_vlc(H261Context *h) +static av_cold void h261_decode_init_static(void) { - static int done = 0; - - 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); - INIT_VLC_STATIC(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10, - 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); - 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); - INIT_VLC_RL(ff_h261_rl_tcoeff, 552); - } + INIT_VLC_STATIC(&h261_mba_vlc, H261_MBA_VLC_BITS, 35, + ff_h261_mba_bits, 1, 1, + ff_h261_mba_code, 1, 1, 540); + INIT_VLC_STATIC(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10, + 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); + 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); + INIT_FIRST_VLC_RL(ff_h261_rl_tcoeff, 552); } static av_cold int h261_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; H261Context *h = avctx->priv_data; MpegEncContext *const s = &h->s; // set defaults - ff_mpv_decode_defaults(s); ff_mpv_decode_init(s, avctx); s->out_format = FMT_H261; s->low_delay = 1; avctx->pix_fmt = AV_PIX_FMT_YUV420P; - ff_h261_common_init(); - h261_decode_init_vlc(h); - h->gob_start_code_skipped = 0; + ff_thread_once(&init_static_once, h261_decode_init_static); + return 0; } @@ -431,7 +426,7 @@ static int h261_decode_mb(H261Context *h) // Read cbp if (HAS_CBP(h->mtype)) - cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1; + cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 1) + 1; if (s->mb_intra) { s->current_picture.mb_type[xy] = MB_TYPE_INTRA; @@ -613,10 +608,7 @@ retry: } 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; } if (!s->context_initialized) { @@ -686,5 +678,6 @@ AVCodec ff_h261_decoder = { .close = h261_decode_end, .decode = h261_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .max_lowres = 3, }; diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c index 196c37b54..eec526c50 100644 --- a/libavcodec/h261enc.c +++ b/libavcodec/h261enc.c @@ -27,6 +27,7 @@ #include "libavutil/attributes.h" #include "libavutil/avassert.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "mpegutils.h" #include "mpegvideo.h" @@ -55,7 +56,7 @@ 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); + align_put_bits(&s->pb); /* Update the pointer to last GOB */ s->ptr_lastgob = put_bits_ptr(&s->pb); @@ -322,8 +323,7 @@ void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], } } -static av_cold void init_uni_h261_rl_tab(RLTable *rl, uint32_t *bits_tab, - uint8_t *len_tab) +static av_cold void init_uni_h261_rl_tab(const RLTable *rl, uint8_t *len_tab) { int slevel, run, last; @@ -362,9 +362,17 @@ static av_cold void init_uni_h261_rl_tab(RLTable *rl, uint32_t *bits_tab, } } +static av_cold void h261_encode_init_static(void) +{ + static uint8_t h261_rl_table_store[2][2 * MAX_RUN + MAX_LEVEL + 3]; + + ff_rl_init(&ff_h261_rl_tcoeff, h261_rl_table_store); + init_uni_h261_rl_tab(&ff_h261_rl_tcoeff, uni_h261_rl_len); +} + av_cold void ff_h261_encode_init(MpegEncContext *s) { - ff_h261_common_init(); + static AVOnce init_static_once = AV_ONCE_INIT; s->min_qcoeff = -127; s->max_qcoeff = 127; @@ -372,10 +380,9 @@ av_cold void ff_h261_encode_init(MpegEncContext *s) 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_thread_once(&init_static_once, h261_encode_init_static); } static const AVClass h261_class = { @@ -394,7 +401,7 @@ AVCodec ff_h261_encoder = { .init = ff_mpv_encode_init, .encode2 = ff_mpv_encode_picture, .close = ff_mpv_encode_end, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .priv_class = &h261_class, diff --git a/libavcodec/h263.h b/libavcodec/h263.h index f891f7237..998f7d0d5 100644 --- a/libavcodec/h263.h +++ b/libavcodec/h263.h @@ -34,6 +34,7 @@ // 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 H263_MV_VLC_BITS 9 #define INTRA_MCBPC_VLC_BITS 6 #define INTER_MCBPC_VLC_BITS 7 #define CBPY_VLC_BITS 6 @@ -44,6 +45,7 @@ extern VLC ff_h263_intra_MCBPC_vlc; extern VLC ff_h263_inter_MCBPC_vlc; extern VLC ff_h263_cbpy_vlc; +extern VLC ff_h263_mv_vlc; extern const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[]; diff --git a/libavcodec/h263data.c b/libavcodec/h263data.c index f649d58f4..604a0425e 100644 --- a/libavcodec/h263data.c +++ b/libavcodec/h263data.c @@ -25,11 +25,11 @@ #include +#include "libavutil/thread.h" + #include "h263data.h" #include "mpegvideo.h" -uint8_t ff_h263_static_rl_table_store[2][2][2 * MAX_RUN + MAX_LEVEL + 3]; - /* intra MCBPC, mb_type = (intra), then (intraq) */ const uint8_t ff_h263_intra_MCBPC_code[9] = { 1, 1, 2, 3, 1, 1, 2, 3, 1 }; const uint8_t ff_h263_intra_MCBPC_bits[9] = { 1, 3, 3, 3, 4, 6, 6, 6, 9 }; @@ -290,3 +290,15 @@ const AVRational ff_h263_pixel_aspect[16] = { { 0, 1 }, { 0, 1 }, }; + +static av_cold void h263_init_rl_inter(void) +{ + static uint8_t h263_rl_inter_table[2][2 * MAX_RUN + MAX_LEVEL + 3]; + ff_rl_init(&ff_h263_rl_inter, h263_rl_inter_table); +} + +av_cold void ff_h263_init_rl_inter(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, h263_init_rl_inter); +} diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h index 3da0e3771..144704d12 100644 --- a/libavcodec/h263data.h +++ b/libavcodec/h263data.h @@ -61,7 +61,7 @@ extern const int8_t ff_inter_run[102]; extern RLTable ff_h263_rl_inter; extern RLTable ff_rl_intra_aic; -extern uint8_t ff_h263_static_rl_table_store[2][2][2 * MAX_RUN + MAX_LEVEL + 3]; +void ff_h263_init_rl_inter(void); extern const uint16_t ff_h263_format[8][2]; diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 31ac563f4..e8b4d83e6 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -28,6 +28,8 @@ #define UNCHECKED_BITSTREAM_READER 1 #include "libavutil/cpu.h" +#include "libavutil/video_enc_params.h" + #include "avcodec.h" #include "error_resilience.h" #include "flv.h" @@ -73,7 +75,6 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) s->out_format = FMT_H263; // set defaults - ff_mpv_decode_defaults(s); ff_mpv_decode_init(s, avctx); s->quant_precision = 5; @@ -743,7 +744,7 @@ const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[] = { AV_PIX_FMT_NONE }; -const AVCodecHWConfigInternal *ff_h263_hw_config_list[] = { +const AVCodecHWConfigInternal *const ff_h263_hw_config_list[] = { #if CONFIG_H263_VAAPI_HWACCEL HWACCEL_VAAPI(h263), #endif diff --git a/libavcodec/h2645_parse.c b/libavcodec/h2645_parse.c index 2e0387164..6fbe97ad4 100644 --- a/libavcodec/h2645_parse.c +++ b/libavcodec/h2645_parse.c @@ -146,7 +146,7 @@ nsc: return si; } -static const char *hevc_nal_type_name[64] = { +static const char *const hevc_nal_type_name[64] = { "TRAIL_N", // HEVC_NAL_TRAIL_N "TRAIL_R", // HEVC_NAL_TRAIL_R "TSA_N", // HEVC_NAL_TSA_N @@ -219,7 +219,7 @@ static const char *hevc_nal_unit_name(int nal_type) return hevc_nal_type_name[nal_type]; } -static const char *h264_nal_type_name[32] = { +static const char *const h264_nal_type_name[32] = { "Unspecified 0", //H264_NAL_UNSPECIFIED "Coded slice of a non-IDR picture", // H264_NAL_SLICE "Coded slice data partition A", // H264_NAL_DPA @@ -287,7 +287,7 @@ static int get_bit_length(H2645NAL *nal, int skip_trailing_zeros) /** * @return AVERROR_INVALIDDATA if the packet is not a valid NAL unit, - * 0 if the unit should be skipped, 1 otherwise + * 0 otherwise */ static int hevc_parse_nal_header(H2645NAL *nal, void *logctx) { @@ -307,7 +307,7 @@ static int hevc_parse_nal_header(H2645NAL *nal, void *logctx) "nal_unit_type: %d(%s), nuh_layer_id: %d, temporal_id: %d\n", nal->type, hevc_nal_unit_name(nal->type), nal->nuh_layer_id, nal->temporal_id); - return 1; + return 0; } static int h264_parse_nal_header(H2645NAL *nal, void *logctx) @@ -324,7 +324,7 @@ static int h264_parse_nal_header(H2645NAL *nal, void *logctx) "nal_unit_type: %d(%s), nal_ref_idc: %d\n", nal->type, h264_nal_unit_name(nal->type), nal->ref_idc); - return 1; + return 0; } static int find_next_start_code(const uint8_t *buf, const uint8_t *next_avc) @@ -467,7 +467,7 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, memset(pkt->nals + pkt->nals_allocated, 0, sizeof(*pkt->nals)); nal = &pkt->nals[pkt->nb_nals]; - nal->skipped_bytes_pos_size = 1024; // initial buffer size + nal->skipped_bytes_pos_size = FFMIN(1024, extract_length/3+1); // initial buffer size nal->skipped_bytes_pos = av_malloc_array(nal->skipped_bytes_pos_size, sizeof(*nal->skipped_bytes_pos)); if (!nal->skipped_bytes_pos) return AVERROR(ENOMEM); @@ -485,8 +485,6 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, "NALFF: Consumed only %d bytes instead of %d\n", consumed, extract_length); - pkt->nb_nals++; - bytestream2_skip(&bc, consumed); /* see commit 3566042a0 */ @@ -496,21 +494,27 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, nal->size_bits = get_bit_length(nal, skip_trailing_zeros); + if (nal->size <= 0 || nal->size_bits <= 0) + continue; + ret = init_get_bits(&nal->gb, nal->data, nal->size_bits); if (ret < 0) return ret; + /* Reset type in case it contains a stale value from a previously parsed NAL */ + nal->type = 0; + if (codec_id == AV_CODEC_ID_HEVC) ret = hevc_parse_nal_header(nal, logctx); else ret = h264_parse_nal_header(nal, logctx); - if (ret <= 0 || nal->size <= 0 || nal->size_bits <= 0) { - if (ret < 0) { - av_log(logctx, AV_LOG_WARNING, "Invalid NAL unit %d, skipping.\n", - nal->type); - } - pkt->nb_nals--; + if (ret < 0) { + av_log(logctx, AV_LOG_WARNING, "Invalid NAL unit %d, skipping.\n", + nal->type); + continue; } + + pkt->nb_nals++; } return 0; diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index 6481992e5..9f5f69233 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -324,93 +324,88 @@ static av_cold void init_cavlc_level_tab(void){ } } -av_cold void ff_h264_decode_init_vlc(void){ - static int done = 0; +av_cold void ff_h264_decode_init_vlc(void) +{ + int offset; - if (!done) { - int i; - int offset; - done = 1; + chroma_dc_coeff_token_vlc.table = chroma_dc_coeff_token_vlc_table; + chroma_dc_coeff_token_vlc.table_allocated = chroma_dc_coeff_token_vlc_table_size; + init_vlc(&chroma_dc_coeff_token_vlc, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 4*5, + &chroma_dc_coeff_token_len [0], 1, 1, + &chroma_dc_coeff_token_bits[0], 1, 1, + INIT_VLC_USE_NEW_STATIC); - chroma_dc_coeff_token_vlc.table = chroma_dc_coeff_token_vlc_table; - chroma_dc_coeff_token_vlc.table_allocated = chroma_dc_coeff_token_vlc_table_size; - init_vlc(&chroma_dc_coeff_token_vlc, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 4*5, - &chroma_dc_coeff_token_len [0], 1, 1, - &chroma_dc_coeff_token_bits[0], 1, 1, + chroma422_dc_coeff_token_vlc.table = chroma422_dc_coeff_token_vlc_table; + chroma422_dc_coeff_token_vlc.table_allocated = chroma422_dc_coeff_token_vlc_table_size; + init_vlc(&chroma422_dc_coeff_token_vlc, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 4*9, + &chroma422_dc_coeff_token_len [0], 1, 1, + &chroma422_dc_coeff_token_bits[0], 1, 1, + INIT_VLC_USE_NEW_STATIC); + + offset = 0; + for (int i = 0; i < 4; i++) { + coeff_token_vlc[i].table = coeff_token_vlc_tables + offset; + coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i]; + init_vlc(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4*17, + &coeff_token_len [i][0], 1, 1, + &coeff_token_bits[i][0], 1, 1, INIT_VLC_USE_NEW_STATIC); - - chroma422_dc_coeff_token_vlc.table = chroma422_dc_coeff_token_vlc_table; - chroma422_dc_coeff_token_vlc.table_allocated = chroma422_dc_coeff_token_vlc_table_size; - init_vlc(&chroma422_dc_coeff_token_vlc, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 4*9, - &chroma422_dc_coeff_token_len [0], 1, 1, - &chroma422_dc_coeff_token_bits[0], 1, 1, - INIT_VLC_USE_NEW_STATIC); - - offset = 0; - for(i=0; i<4; i++){ - coeff_token_vlc[i].table = coeff_token_vlc_tables+offset; - coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i]; - init_vlc(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4*17, - &coeff_token_len [i][0], 1, 1, - &coeff_token_bits[i][0], 1, 1, - INIT_VLC_USE_NEW_STATIC); - offset += coeff_token_vlc_tables_size[i]; - } - /* - * This is a one time safety check to make sure that - * the packed static coeff_token_vlc table sizes - * were initialized correctly. - */ - av_assert0(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables)); - - for(i=0; i<3; i++){ - chroma_dc_total_zeros_vlc[i+1].table = chroma_dc_total_zeros_vlc_tables[i]; - chroma_dc_total_zeros_vlc[i+1].table_allocated = chroma_dc_total_zeros_vlc_tables_size; - init_vlc(&chroma_dc_total_zeros_vlc[i+1], - CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 4, - &chroma_dc_total_zeros_len [i][0], 1, 1, - &chroma_dc_total_zeros_bits[i][0], 1, 1, - INIT_VLC_USE_NEW_STATIC); - } - - for(i=0; i<7; i++){ - chroma422_dc_total_zeros_vlc[i+1].table = chroma422_dc_total_zeros_vlc_tables[i]; - chroma422_dc_total_zeros_vlc[i+1].table_allocated = chroma422_dc_total_zeros_vlc_tables_size; - init_vlc(&chroma422_dc_total_zeros_vlc[i+1], - CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 8, - &chroma422_dc_total_zeros_len [i][0], 1, 1, - &chroma422_dc_total_zeros_bits[i][0], 1, 1, - INIT_VLC_USE_NEW_STATIC); - } - - for(i=0; i<15; i++){ - total_zeros_vlc[i+1].table = total_zeros_vlc_tables[i]; - total_zeros_vlc[i+1].table_allocated = total_zeros_vlc_tables_size; - init_vlc(&total_zeros_vlc[i+1], - TOTAL_ZEROS_VLC_BITS, 16, - &total_zeros_len [i][0], 1, 1, - &total_zeros_bits[i][0], 1, 1, - INIT_VLC_USE_NEW_STATIC); - } - - for(i=0; i<6; i++){ - run_vlc[i+1].table = run_vlc_tables[i]; - run_vlc[i+1].table_allocated = run_vlc_tables_size; - init_vlc(&run_vlc[i+1], - RUN_VLC_BITS, 7, - &run_len [i][0], 1, 1, - &run_bits[i][0], 1, 1, - INIT_VLC_USE_NEW_STATIC); - } - run7_vlc.table = run7_vlc_table, - run7_vlc.table_allocated = run7_vlc_table_size; - init_vlc(&run7_vlc, RUN7_VLC_BITS, 16, - &run_len [6][0], 1, 1, - &run_bits[6][0], 1, 1, - INIT_VLC_USE_NEW_STATIC); - - init_cavlc_level_tab(); + offset += coeff_token_vlc_tables_size[i]; } + /* + * This is a one time safety check to make sure that + * the packed static coeff_token_vlc table sizes + * were initialized correctly. + */ + av_assert0(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables)); + + for (int i = 0; i < 3; i++) { + chroma_dc_total_zeros_vlc[i + 1].table = chroma_dc_total_zeros_vlc_tables[i]; + chroma_dc_total_zeros_vlc[i + 1].table_allocated = chroma_dc_total_zeros_vlc_tables_size; + init_vlc(&chroma_dc_total_zeros_vlc[i + 1], + CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 4, + &chroma_dc_total_zeros_len [i][0], 1, 1, + &chroma_dc_total_zeros_bits[i][0], 1, 1, + INIT_VLC_USE_NEW_STATIC); + } + + for (int i = 0; i < 7; i++) { + chroma422_dc_total_zeros_vlc[i + 1].table = chroma422_dc_total_zeros_vlc_tables[i]; + chroma422_dc_total_zeros_vlc[i + 1].table_allocated = chroma422_dc_total_zeros_vlc_tables_size; + init_vlc(&chroma422_dc_total_zeros_vlc[i + 1], + CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 8, + &chroma422_dc_total_zeros_len [i][0], 1, 1, + &chroma422_dc_total_zeros_bits[i][0], 1, 1, + INIT_VLC_USE_NEW_STATIC); + } + + for (int i = 0; i < 15; i++) { + total_zeros_vlc[i + 1].table = total_zeros_vlc_tables[i]; + total_zeros_vlc[i + 1].table_allocated = total_zeros_vlc_tables_size; + init_vlc(&total_zeros_vlc[i + 1], + TOTAL_ZEROS_VLC_BITS, 16, + &total_zeros_len [i][0], 1, 1, + &total_zeros_bits[i][0], 1, 1, + INIT_VLC_USE_NEW_STATIC); + } + + for (int i = 0; i < 6; i++) { + run_vlc[i + 1].table = run_vlc_tables[i]; + run_vlc[i + 1].table_allocated = run_vlc_tables_size; + init_vlc(&run_vlc[i + 1], + RUN_VLC_BITS, 7, + &run_len [i][0], 1, 1, + &run_bits[i][0], 1, 1, + INIT_VLC_USE_NEW_STATIC); + } + run7_vlc.table = run7_vlc_table; + run7_vlc.table_allocated = run7_vlc_table_size; + init_vlc(&run7_vlc, RUN7_VLC_BITS, 16, + &run_len [6][0], 1, 1, + &run_bits[6][0], 1, 1, + INIT_VLC_USE_NEW_STATIC); + + init_cavlc_level_tab(); } static inline int get_level_prefix(GetBitContext *gb){ diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index a01d823e7..8f0798113 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -43,7 +43,7 @@ static int get_scale_factor(H264SliceContext *sl, int td = av_clip_int8(pocdiff); if (pocdiff != (int)pocdiff) - avpriv_request_sample(sl->h264->avctx, "pocdiff overflow\n"); + avpriv_request_sample(sl->h264->avctx, "pocdiff overflow"); if (td == 0 || sl->ref_list[0][i].parent->long_ref) { return 256; diff --git a/libavcodec/h264_levels.c b/libavcodec/h264_levels.c index dd517f100..801b27fdd 100644 --- a/libavcodec/h264_levels.c +++ b/libavcodec/h264_levels.c @@ -75,18 +75,6 @@ static int h264_get_br_factor(int profile_idc) return 1200; } -const H264LevelDescriptor *ff_h264_get_level(int level_idc, - int constraint_set3_flag) -{ - int i; - for (i = 0; i < FF_ARRAY_ELEMS(h264_levels); i++) { - if (h264_levels[i].level_idc == level_idc && - h264_levels[i].constraint_set3_flag == constraint_set3_flag) - return &h264_levels[i]; - } - return NULL; -} - const H264LevelDescriptor *ff_h264_guess_level(int profile_idc, int64_t bitrate, int framerate, diff --git a/libavcodec/h264_levels.h b/libavcodec/h264_levels.h index 0a0f41032..6bba2e862 100644 --- a/libavcodec/h264_levels.h +++ b/libavcodec/h264_levels.h @@ -36,9 +36,6 @@ typedef struct H264LevelDescriptor { uint8_t max_mvs_per_2mb; } H264LevelDescriptor; -const H264LevelDescriptor *ff_h264_get_level(int level_idc, - int constraint_set3_flag); - /** * Guess the level of a stream from some parameters. * diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c index 0924f3261..558ec6c02 100644 --- a/libavcodec/h264_loopfilter.c +++ b/libavcodec/h264_loopfilter.c @@ -27,6 +27,7 @@ #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "internal.h" #include "avcodec.h" #include "h264dec.h" diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c index cef054bd6..06d23e314 100644 --- a/libavcodec/h264_metadata_bsf.c +++ b/libavcodec/h264_metadata_bsf.c @@ -22,20 +22,13 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_h264.h" #include "h264.h" #include "h264_levels.h" #include "h264_sei.h" -enum { - PASS, - INSERT, - REMOVE, - EXTRACT, -}; - enum { FLIP_HORIZONTAL = 1, FLIP_VERTICAL = 2, @@ -47,14 +40,12 @@ enum { }; typedef struct H264MetadataContext { - const AVClass *class; - - CodedBitstreamContext *cbc; - CodedBitstreamFragment access_unit; + CBSBSFContext common; int done_first_au; int aud; + H264RawAUD aud_nal; AVRational sample_aspect_ratio; @@ -77,17 +68,72 @@ typedef struct H264MetadataContext { int crop_bottom; const char *sei_user_data; + SEIRawUserDataUnregistered sei_user_data_payload; int delete_filler; int display_orientation; double rotate; int flip; + H264RawSEIDisplayOrientation display_orientation_payload; int level; } H264MetadataContext; +static int h264_metadata_insert_aud(AVBSFContext *bsf, + CodedBitstreamFragment *au) +{ + H264MetadataContext *ctx = bsf->priv_data; + int primary_pic_type_mask = 0xff; + int err, i, j; + + static const int primary_pic_type_table[] = { + 0x084, // 2, 7 + 0x0a5, // 0, 2, 5, 7 + 0x0e7, // 0, 1, 2, 5, 6, 7 + 0x210, // 4, 9 + 0x318, // 3, 4, 8, 9 + 0x294, // 2, 4, 7, 9 + 0x3bd, // 0, 2, 3, 4, 5, 7, 8, 9 + 0x3ff, // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; + + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type == H264_NAL_SLICE || + au->units[i].type == H264_NAL_IDR_SLICE) { + H264RawSlice *slice = au->units[i].content; + for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++) { + if (!(primary_pic_type_table[j] & + (1 << slice->header.slice_type))) + primary_pic_type_mask &= ~(1 << j); + } + } + } + for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++) + if (primary_pic_type_mask & (1 << j)) + break; + if (j >= FF_ARRAY_ELEMS(primary_pic_type_table)) { + av_log(bsf, AV_LOG_ERROR, "No usable primary_pic_type: " + "invalid slice types?\n"); + return AVERROR_INVALIDDATA; + } + + ctx->aud_nal = (H264RawAUD) { + .nal_unit_header.nal_unit_type = H264_NAL_AUD, + .primary_pic_type = j, + }; + + err = ff_cbs_insert_unit_content(au, 0, H264_NAL_AUD, + &ctx->aud_nal, NULL); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n"); + return err; + } + + return 0; +} + static int h264_metadata_update_sps(AVBSFContext *bsf, H264RawSPS *sps) { @@ -276,294 +322,94 @@ static int h264_metadata_update_sps(AVBSFContext *bsf, return 0; } -static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) +static int h264_metadata_handle_display_orientation(AVBSFContext *bsf, + AVPacket *pkt, + CodedBitstreamFragment *au, + int seek_point) { H264MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - uint8_t *side_data; - int side_data_size; - int err, i; + SEIRawMessage *message; + int err; - side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, - &side_data_size); - if (!side_data_size) - return 0; + message = NULL; + while (ff_cbs_sei_find_message(ctx->common.output, au, + SEI_TYPE_DISPLAY_ORIENTATION, + &message) == 0) { + H264RawSEIDisplayOrientation *disp = message->payload; + int32_t *matrix; - err = ff_cbs_read(ctx->cbc, au, side_data, side_data_size); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n"); - return err; - } + matrix = av_malloc(9 * sizeof(int32_t)); + if (!matrix) + return AVERROR(ENOMEM); - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_SPS) { - err = h264_metadata_update_sps(bsf, au->units[i].content); - if (err < 0) - return err; + av_display_rotation_set(matrix, + disp->anticlockwise_rotation * + 180.0 / 65536.0); + av_display_matrix_flip(matrix, disp->hor_flip, disp->ver_flip); + + // If there are multiple display orientation messages in an + // access unit, then the last one added to the packet (i.e. + // the first one in the access unit) will prevail. + err = av_packet_add_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX, + (uint8_t*)matrix, + 9 * sizeof(int32_t)); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to attach extracted " + "displaymatrix side data to packet.\n"); + av_free(matrix); + return AVERROR(ENOMEM); } } - err = ff_cbs_write_fragment_data(ctx->cbc, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n"); - return err; + if (ctx->display_orientation == BSF_ELEMENT_REMOVE || + ctx->display_orientation == BSF_ELEMENT_INSERT) { + ff_cbs_sei_delete_message_type(ctx->common.output, au, + SEI_TYPE_DISPLAY_ORIENTATION); } - side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, au->data_size); - if (!side_data) - return AVERROR(ENOMEM); - memcpy(side_data, au->data, au->data_size); - - ff_cbs_fragment_reset(ctx->cbc, au); - - return 0; -} - -static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) -{ - H264MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - int err, i, j, has_sps; - H264RawAUD aud; - - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = h264_metadata_update_side_data(bsf, pkt); - if (err < 0) - goto fail; - - err = ff_cbs_read_packet(ctx->cbc, au, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } - - if (au->nb_units == 0) { - av_log(bsf, AV_LOG_ERROR, "No NAL units in packet.\n"); - err = AVERROR_INVALIDDATA; - goto fail; - } - - // If an AUD is present, it must be the first NAL unit. - if (au->units[0].type == H264_NAL_AUD) { - if (ctx->aud == REMOVE) - ff_cbs_delete_unit(ctx->cbc, au, 0); - } else { - if (ctx->aud == INSERT) { - static const int primary_pic_type_table[] = { - 0x084, // 2, 7 - 0x0a5, // 0, 2, 5, 7 - 0x0e7, // 0, 1, 2, 5, 6, 7 - 0x210, // 4, 9 - 0x318, // 3, 4, 8, 9 - 0x294, // 2, 4, 7, 9 - 0x3bd, // 0, 2, 3, 4, 5, 7, 8, 9 - 0x3ff, // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 - }; - int primary_pic_type_mask = 0xff; - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_SLICE || - au->units[i].type == H264_NAL_IDR_SLICE) { - H264RawSlice *slice = au->units[i].content; - for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++) { - if (!(primary_pic_type_table[j] & - (1 << slice->header.slice_type))) - primary_pic_type_mask &= ~(1 << j); - } - } - } - for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++) - if (primary_pic_type_mask & (1 << j)) - break; - if (j >= FF_ARRAY_ELEMS(primary_pic_type_table)) { - av_log(bsf, AV_LOG_ERROR, "No usable primary_pic_type: " - "invalid slice types?\n"); - err = AVERROR_INVALIDDATA; - goto fail; - } - - aud = (H264RawAUD) { - .nal_unit_header.nal_unit_type = H264_NAL_AUD, - .primary_pic_type = j, - }; - - err = ff_cbs_insert_unit_content(ctx->cbc, au, - 0, H264_NAL_AUD, &aud, NULL); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n"); - goto fail; - } - } - } - - has_sps = 0; - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_SPS) { - err = h264_metadata_update_sps(bsf, au->units[i].content); - if (err < 0) - goto fail; - has_sps = 1; - } - } - - // Only insert the SEI in access units containing SPSs, and also - // unconditionally in the first access unit we ever see. - if (ctx->sei_user_data && (has_sps || !ctx->done_first_au)) { - H264RawSEIPayload payload = { - .payload_type = H264_SEI_TYPE_USER_DATA_UNREGISTERED, - }; - H264RawSEIUserDataUnregistered *udu = - &payload.payload.user_data_unregistered; - - for (i = j = 0; j < 32 && ctx->sei_user_data[i]; i++) { - int c, v; - c = ctx->sei_user_data[i]; - if (c == '-') { - continue; - } else if (av_isxdigit(c)) { - c = av_tolower(c); - v = (c <= '9' ? c - '0' : c - 'a' + 10); - } else { - goto invalid_user_data; - } - if (j & 1) - udu->uuid_iso_iec_11578[j / 2] |= v; - else - udu->uuid_iso_iec_11578[j / 2] = v << 4; - ++j; - } - if (j == 32 && ctx->sei_user_data[i] == '+') { - size_t len = strlen(ctx->sei_user_data + i + 1); - - udu->data_ref = av_buffer_alloc(len + 1); - if (!udu->data_ref) { - err = AVERROR(ENOMEM); - goto fail; - } - - udu->data = udu->data_ref->data; - udu->data_length = len + 1; - memcpy(udu->data, ctx->sei_user_data + i + 1, len + 1); - - err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI " - "message to access unit.\n"); - goto fail; - } - - } else { - invalid_user_data: - av_log(bsf, AV_LOG_ERROR, "Invalid user data: " - "must be \"UUID+string\".\n"); - err = AVERROR(EINVAL); - goto fail; - } - } - - if (ctx->delete_filler) { - for (i = au->nb_units - 1; i >= 0; i--) { - if (au->units[i].type == H264_NAL_FILLER_DATA) { - ff_cbs_delete_unit(ctx->cbc, au, i); - continue; - } - - if (au->units[i].type == H264_NAL_SEI) { - // Filler SEI messages. - H264RawSEI *sei = au->units[i].content; - - for (j = sei->payload_count - 1; j >= 0; j--) { - if (sei->payload[j].payload_type == - H264_SEI_TYPE_FILLER_PAYLOAD) - ff_cbs_h264_delete_sei_message(ctx->cbc, au, - &au->units[i], j); - } - } - } - } - - if (ctx->display_orientation != PASS) { - for (i = au->nb_units - 1; i >= 0; i--) { - H264RawSEI *sei; - if (au->units[i].type != H264_NAL_SEI) - continue; - sei = au->units[i].content; - - for (j = sei->payload_count - 1; j >= 0; j--) { - H264RawSEIDisplayOrientation *disp; - int32_t *matrix; - - if (sei->payload[j].payload_type != - H264_SEI_TYPE_DISPLAY_ORIENTATION) - continue; - disp = &sei->payload[j].payload.display_orientation; - - if (ctx->display_orientation == REMOVE || - ctx->display_orientation == INSERT) { - ff_cbs_h264_delete_sei_message(ctx->cbc, au, - &au->units[i], j); - continue; - } - - matrix = av_malloc(9 * sizeof(int32_t)); - if (!matrix) { - err = AVERROR(ENOMEM); - goto fail; - } - - av_display_rotation_set(matrix, - disp->anticlockwise_rotation * - 180.0 / 65536.0); - av_display_matrix_flip(matrix, disp->hor_flip, disp->ver_flip); - - // If there are multiple display orientation messages in an - // access unit, then the last one added to the packet (i.e. - // the first one in the access unit) will prevail. - err = av_packet_add_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX, - (uint8_t*)matrix, - 9 * sizeof(int32_t)); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to attach extracted " - "displaymatrix side data to packet.\n"); - av_free(matrix); - goto fail; - } - } - } - } - if (ctx->display_orientation == INSERT) { - H264RawSEIPayload payload = { - .payload_type = H264_SEI_TYPE_DISPLAY_ORIENTATION, - }; + if (ctx->display_orientation == BSF_ELEMENT_INSERT) { H264RawSEIDisplayOrientation *disp = - &payload.payload.display_orientation; + &ctx->display_orientation_payload; uint8_t *data; - int size; + buffer_size_t size; int write = 0; data = av_packet_get_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX, &size); if (data && size >= 9 * sizeof(int32_t)) { int32_t matrix[9]; - int hflip, vflip; - double angle; + double dmatrix[9]; + int hflip, vflip, i; + double scale_x, scale_y, angle; memcpy(matrix, data, sizeof(matrix)); - hflip = vflip = 0; - if (matrix[0] < 0 && matrix[4] > 0) - hflip = 1; - else if (matrix[0] > 0 && matrix[4] < 0) - vflip = 1; - av_display_matrix_flip(matrix, hflip, vflip); + for (i = 0; i < 9; i++) + dmatrix[i] = matrix[i] / 65536.0; - angle = av_display_rotation_get(matrix); + // Extract scale factors. + scale_x = hypot(dmatrix[0], dmatrix[3]); + scale_y = hypot(dmatrix[1], dmatrix[4]); - if (!(angle >= -180.0 && angle <= 180.0 /* also excludes NaN */) || - matrix[2] != 0 || matrix[5] != 0 || - matrix[6] != 0 || matrix[7] != 0) { + // Select flips to make the main diagonal positive. + hflip = dmatrix[0] < 0.0; + vflip = dmatrix[4] < 0.0; + if (hflip) + scale_x = -scale_x; + if (vflip) + scale_y = -scale_y; + + // Rescale. + for (i = 0; i < 9; i += 3) { + dmatrix[i] /= scale_x; + dmatrix[i + 1] /= scale_y; + } + + // Extract rotation. + angle = atan2(dmatrix[3], dmatrix[0]); + + if (!(angle >= -M_PI && angle <= M_PI) || + matrix[2] != 0.0 || matrix[5] != 0.0 || + matrix[6] != 0.0 || matrix[7] != 0.0) { av_log(bsf, AV_LOG_WARNING, "Input display matrix is not " "representable in H.264 parameters.\n"); } else { @@ -571,13 +417,13 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) disp->ver_flip = vflip; disp->anticlockwise_rotation = (uint16_t)rint((angle >= 0.0 ? angle - : angle + 360.0) * - 65536.0 / 360.0); + : angle + 2 * M_PI) * + 32768.0 / M_PI); write = 1; } } - if (has_sps || !ctx->done_first_au) { + if (seek_point) { if (!isnan(ctx->rotate)) { disp->anticlockwise_rotation = (uint16_t)rint((ctx->rotate >= 0.0 ? ctx->rotate @@ -595,91 +441,148 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (write) { disp->display_orientation_repetition_period = 1; - err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload); + err = ff_cbs_sei_add_message(ctx->common.output, au, 1, + SEI_TYPE_DISPLAY_ORIENTATION, + disp, NULL); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to add display orientation " "SEI message to access unit.\n"); - goto fail; + return err; } } } - err = ff_cbs_write_packet(ctx->cbc, pkt, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; + return 0; +} + +static int h264_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *au) +{ + H264MetadataContext *ctx = bsf->priv_data; + int err, i, has_sps, seek_point; + + // If an AUD is present, it must be the first NAL unit. + if (au->nb_units && au->units[0].type == H264_NAL_AUD) { + if (ctx->aud == BSF_ELEMENT_REMOVE) + ff_cbs_delete_unit(au, 0); + } else { + if (pkt && ctx->aud == BSF_ELEMENT_INSERT) { + err = h264_metadata_insert_aud(bsf, au); + if (err < 0) + return err; + } } - ctx->done_first_au = 1; + has_sps = 0; + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type == H264_NAL_SPS) { + err = h264_metadata_update_sps(bsf, au->units[i].content); + if (err < 0) + return err; + has_sps = 1; + } + } - err = 0; -fail: - ff_cbs_fragment_reset(ctx->cbc, au); + if (pkt) { + // The current packet should be treated as a seek point for metadata + // insertion if any of: + // - It is the first packet in the stream. + // - It contains an SPS, indicating that a sequence might start here. + // - It is marked as containing a key frame. + seek_point = !ctx->done_first_au || has_sps || + (pkt->flags & AV_PKT_FLAG_KEY); + } else { + seek_point = 0; + } - if (err < 0) - av_packet_unref(pkt); + if (ctx->sei_user_data && seek_point) { + err = ff_cbs_sei_add_message(ctx->common.output, au, 1, + SEI_TYPE_USER_DATA_UNREGISTERED, + &ctx->sei_user_data_payload, NULL); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI " + "message to access unit.\n"); + return err; + } + } - return err; + if (ctx->delete_filler) { + for (i = au->nb_units - 1; i >= 0; i--) { + if (au->units[i].type == H264_NAL_FILLER_DATA) { + ff_cbs_delete_unit(au, i); + continue; + } + } + + ff_cbs_sei_delete_message_type(ctx->common.output, au, + SEI_TYPE_FILLER_PAYLOAD); + } + + if (pkt && ctx->display_orientation != BSF_ELEMENT_PASS) { + err = h264_metadata_handle_display_orientation(bsf, pkt, au, + seek_point); + if (err < 0) + return err; + } + + if (pkt) + ctx->done_first_au = 1; + + return 0; } +static const CBSBSFType h264_metadata_type = { + .codec_id = AV_CODEC_ID_H264, + .fragment_name = "access unit", + .unit_name = "NAL unit", + .update_fragment = &h264_metadata_update_fragment, +}; + static int h264_metadata_init(AVBSFContext *bsf) { H264MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - int err, i; - err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_H264, bsf); - if (err < 0) - return err; + if (ctx->sei_user_data) { + SEIRawUserDataUnregistered *udu = &ctx->sei_user_data_payload; + int i, j; - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->cbc, au, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_SPS) { - err = h264_metadata_update_sps(bsf, au->units[i].content); - if (err < 0) - goto fail; + // Parse UUID. It must be a hex string of length 32, possibly + // containing '-'s between hex digits (which we ignore). + for (i = j = 0; j < 32 && i < 64 && ctx->sei_user_data[i]; i++) { + int c, v; + c = ctx->sei_user_data[i]; + if (c == '-') { + continue; + } else if (av_isxdigit(c)) { + c = av_tolower(c); + v = (c <= '9' ? c - '0' : c - 'a' + 10); + } else { + break; } + if (j & 1) + udu->uuid_iso_iec_11578[j / 2] |= v; + else + udu->uuid_iso_iec_11578[j / 2] = v << 4; + ++j; } - - err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; + if (j == 32 && ctx->sei_user_data[i] == '+') { + udu->data = (uint8_t*)ctx->sei_user_data + i + 1; + udu->data_length = strlen(udu->data) + 1; + } else { + av_log(bsf, AV_LOG_ERROR, "Invalid user data: " + "must be \"UUID+string\".\n"); + return AVERROR(EINVAL); } } - err = 0; -fail: - ff_cbs_fragment_reset(ctx->cbc, au); - return err; -} - -static void h264_metadata_close(AVBSFContext *bsf) -{ - H264MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit); - ff_cbs_close(&ctx->cbc); + return ff_cbs_bsf_generic_init(bsf, &h264_metadata_type); } #define OFFSET(x) offsetof(H264MetadataContext, x) #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM) static const AVOption h264_metadata_options[] = { - { "aud", "Access Unit Delimiter NAL units", - OFFSET(aud), AV_OPT_TYPE_INT, - { .i64 = PASS }, PASS, REMOVE, FLAGS, "aud" }, - { "pass", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = PASS }, .flags = FLAGS, .unit = "aud" }, - { "insert", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = INSERT }, .flags = FLAGS, .unit = "aud" }, - { "remove", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = REMOVE }, .flags = FLAGS, .unit = "aud" }, + BSF_ELEMENT_OPTIONS_PIR("aud", "Access Unit Delimiter NAL units", + aud, FLAGS), { "sample_aspect_ratio", "Set sample aspect ratio (table E-1)", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, @@ -735,17 +638,9 @@ static const AVOption h264_metadata_options[] = { { "delete_filler", "Delete all filler (both NAL and SEI)", OFFSET(delete_filler), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS}, - { "display_orientation", "Display orientation SEI", - OFFSET(display_orientation), AV_OPT_TYPE_INT, - { .i64 = PASS }, PASS, EXTRACT, FLAGS, "disp_or" }, - { "pass", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = PASS }, .flags = FLAGS, .unit = "disp_or" }, - { "insert", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = INSERT }, .flags = FLAGS, .unit = "disp_or" }, - { "remove", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = REMOVE }, .flags = FLAGS, .unit = "disp_or" }, - { "extract", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = EXTRACT }, .flags = FLAGS, .unit = "disp_or" }, + BSF_ELEMENT_OPTIONS_PIRE("display_orientation", + "Display orientation SEI", + display_orientation, FLAGS), { "rotate", "Set rotation in display orientation SEI (anticlockwise angle in degrees)", OFFSET(rotate), AV_OPT_TYPE_DOUBLE, @@ -809,7 +704,7 @@ const AVBitStreamFilter ff_h264_metadata_bsf = { .priv_data_size = sizeof(H264MetadataContext), .priv_class = &h264_metadata_class, .init = &h264_metadata_init, - .close = &h264_metadata_close, - .filter = &h264_metadata_filter, + .close = &ff_cbs_bsf_generic_close, + .filter = &ff_cbs_bsf_generic_filter, .codec_ids = h264_metadata_codec_ids, }; diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h index bf395e3fe..19d9ee462 100644 --- a/libavcodec/h264_mvpred.h +++ b/libavcodec/h264_mvpred.h @@ -33,6 +33,7 @@ #include "h264dec.h" #include "mpegutils.h" #include "libavutil/avassert.h" +#include "libavutil/mem_internal.h" static av_always_inline int fetch_diagonal_mv(const H264Context *h, H264SliceContext *sl, diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index 352ffea94..1c1d1c04b 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -35,7 +35,7 @@ int ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps, pwt->use_weight = 0; pwt->use_weight_chroma = 0; - pwt->luma_log2_weight_denom = get_ue_golomb(gb); + pwt->luma_log2_weight_denom = get_ue_golomb_31(gb); if (pwt->luma_log2_weight_denom > 7U) { av_log(logctx, AV_LOG_ERROR, "luma_log2_weight_denom %d is out of range\n", pwt->luma_log2_weight_denom); pwt->luma_log2_weight_denom = 0; @@ -43,7 +43,7 @@ int ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps, luma_def = 1 << pwt->luma_log2_weight_denom; if (sps->chroma_format_idc) { - pwt->chroma_log2_weight_denom = get_ue_golomb(gb); + pwt->chroma_log2_weight_denom = get_ue_golomb_31(gb); if (pwt->chroma_log2_weight_denom > 7U) { av_log(logctx, AV_LOG_ERROR, "chroma_log2_weight_denom %d is out of range\n", pwt->chroma_log2_weight_denom); pwt->chroma_log2_weight_denom = 0; diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index e774929e2..e21c2b56a 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -181,8 +181,8 @@ static inline int decode_vui_parameters(GetBitContext *gb, void *logctx, /* chroma_location_info_present_flag */ if (get_bits1(gb)) { /* chroma_sample_location_type_top_field */ - sps->chroma_location = get_ue_golomb(gb) + 1; - get_ue_golomb(gb); /* chroma_sample_location_type_bottom_field */ + sps->chroma_location = get_ue_golomb_31(gb) + 1; + get_ue_golomb_31(gb); /* chroma_sample_location_type_bottom_field */ } else sps->chroma_location = AVCHROMA_LOC_LEFT; @@ -224,12 +224,12 @@ static inline int decode_vui_parameters(GetBitContext *gb, void *logctx, sps->bitstream_restriction_flag = get_bits1(gb); if (sps->bitstream_restriction_flag) { get_bits1(gb); /* motion_vectors_over_pic_boundaries_flag */ - get_ue_golomb(gb); /* max_bytes_per_pic_denom */ - get_ue_golomb(gb); /* max_bits_per_mb_denom */ - get_ue_golomb(gb); /* log2_max_mv_length_horizontal */ - get_ue_golomb(gb); /* log2_max_mv_length_vertical */ - sps->num_reorder_frames = get_ue_golomb(gb); - get_ue_golomb(gb); /*max_dec_frame_buffering*/ + get_ue_golomb_31(gb); /* max_bytes_per_pic_denom */ + get_ue_golomb_31(gb); /* max_bits_per_mb_denom */ + get_ue_golomb_31(gb); /* log2_max_mv_length_horizontal */ + get_ue_golomb_31(gb); /* log2_max_mv_length_vertical */ + sps->num_reorder_frames = get_ue_golomb_31(gb); + get_ue_golomb_31(gb); /*max_dec_frame_buffering*/ if (get_bits_left(gb) < 0) { sps->num_reorder_frames = 0; @@ -403,8 +403,8 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, goto fail; } } - sps->bit_depth_luma = get_ue_golomb(gb) + 8; - sps->bit_depth_chroma = get_ue_golomb(gb) + 8; + sps->bit_depth_luma = get_ue_golomb_31(gb) + 8; + sps->bit_depth_chroma = get_ue_golomb_31(gb) + 8; if (sps->bit_depth_chroma != sps->bit_depth_luma) { avpriv_request_sample(avctx, "Different chroma and luma bit depth"); @@ -428,7 +428,7 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, sps->bit_depth_chroma = 8; } - log2_max_frame_num_minus4 = get_ue_golomb(gb); + log2_max_frame_num_minus4 = get_ue_golomb_31(gb); if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 || log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) { av_log(avctx, AV_LOG_ERROR, @@ -441,7 +441,7 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, sps->poc_type = get_ue_golomb_31(gb); if (sps->poc_type == 0) { // FIXME #define - unsigned t = get_ue_golomb(gb); + unsigned t = get_ue_golomb_31(gb); if (t>12) { av_log(avctx, AV_LOG_ERROR, "log2_max_poc_lsb (%d) is out of range\n", t); goto fail; diff --git a/libavcodec/h264_redundant_pps_bsf.c b/libavcodec/h264_redundant_pps_bsf.c index 8f6978095..6ba40291d 100644 --- a/libavcodec/h264_redundant_pps_bsf.c +++ b/libavcodec/h264_redundant_pps_bsf.c @@ -24,15 +24,13 @@ #include "bsf.h" #include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_h264.h" #include "h264.h" typedef struct H264RedundantPPSContext { - CodedBitstreamContext *input; - CodedBitstreamContext *output; - - CodedBitstreamFragment access_unit; + CBSBSFContext common; int global_pic_init_qp; int current_pic_init_qp; @@ -41,8 +39,19 @@ typedef struct H264RedundantPPSContext { static int h264_redundant_pps_fixup_pps(H264RedundantPPSContext *ctx, - H264RawPPS *pps) + CodedBitstreamUnit *unit) { + H264RawPPS *pps; + int err; + + // The changes we are about to perform affect the parsing process, + // so we must make sure that the PPS is writable, otherwise the + // parsing of future slices will be incorrect and even raise errors. + err = ff_cbs_make_unit_writable(ctx->common.input, unit); + if (err < 0) + return err; + pps = unit->content; + // Record the current value of pic_init_qp in order to fix up // following slices, then overwrite with the global value. ctx->current_pic_init_qp = pps->pic_init_qp_minus26 + 26; @@ -67,21 +76,14 @@ static int h264_redundant_pps_fixup_slice(H264RedundantPPSContext *ctx, return 0; } -static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt) +static int h264_redundant_pps_update_fragment(AVBSFContext *bsf, + AVPacket *pkt, + CodedBitstreamFragment *au) { H264RedundantPPSContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; int au_has_sps; int err, i; - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = ff_cbs_read_packet(ctx->input, au, pkt); - if (err < 0) - goto fail; - au_has_sps = 0; for (i = 0; i < au->nb_units; i++) { CodedBitstreamUnit *nal = &au->units[i]; @@ -89,13 +91,13 @@ static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt) if (nal->type == H264_NAL_SPS) au_has_sps = 1; if (nal->type == H264_NAL_PPS) { - err = h264_redundant_pps_fixup_pps(ctx, nal->content); + err = h264_redundant_pps_fixup_pps(ctx, nal); if (err < 0) - goto fail; + return err; if (!au_has_sps) { av_log(bsf, AV_LOG_VERBOSE, "Deleting redundant PPS " "at %"PRId64".\n", pkt->pts); - ff_cbs_delete_unit(ctx->input, au, i); + ff_cbs_delete_unit(au, i); i--; continue; } @@ -107,62 +109,7 @@ static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt) } } - err = ff_cbs_write_packet(ctx->output, pkt, au); - if (err < 0) - goto fail; - - err = 0; -fail: - ff_cbs_fragment_reset(ctx->output, au); - if (err < 0) - av_packet_unref(pkt); - - return err; -} - -static int h264_redundant_pps_init(AVBSFContext *bsf) -{ - H264RedundantPPSContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - int err, i; - - err = ff_cbs_init(&ctx->input, AV_CODEC_ID_H264, bsf); - if (err < 0) - return err; - - err = ff_cbs_init(&ctx->output, AV_CODEC_ID_H264, bsf); - if (err < 0) - return err; - - ctx->global_pic_init_qp = 26; - - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->input, au, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_PPS) { - err = h264_redundant_pps_fixup_pps(ctx, au->units[i].content); - if (err < 0) - goto fail; - } - } - - ctx->extradata_pic_init_qp = ctx->current_pic_init_qp; - err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; - } - } - - err = 0; -fail: - ff_cbs_fragment_reset(ctx->output, au); - return err; + return 0; } static void h264_redundant_pps_flush(AVBSFContext *bsf) @@ -171,13 +118,20 @@ static void h264_redundant_pps_flush(AVBSFContext *bsf) ctx->current_pic_init_qp = ctx->extradata_pic_init_qp; } -static void h264_redundant_pps_close(AVBSFContext *bsf) +static const CBSBSFType h264_redundant_pps_type = { + .codec_id = AV_CODEC_ID_H264, + .fragment_name = "access unit", + .unit_name = "NAL unit", + .update_fragment = &h264_redundant_pps_update_fragment, +}; + +static int h264_redundant_pps_init(AVBSFContext *bsf) { H264RedundantPPSContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->input, &ctx->access_unit); - ff_cbs_close(&ctx->input); - ff_cbs_close(&ctx->output); + ctx->global_pic_init_qp = 26; + + return ff_cbs_bsf_generic_init(bsf, &h264_redundant_pps_type); } static const enum AVCodecID h264_redundant_pps_codec_ids[] = { @@ -189,7 +143,7 @@ const AVBitStreamFilter ff_h264_redundant_pps_bsf = { .priv_data_size = sizeof(H264RedundantPPSContext), .init = &h264_redundant_pps_init, .flush = &h264_redundant_pps_flush, - .close = &h264_redundant_pps_close, - .filter = &h264_redundant_pps_filter, + .close = &ff_cbs_bsf_generic_close, + .filter = &ff_cbs_bsf_generic_filter, .codec_ids = h264_redundant_pps_codec_ids, }; diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 870dd9071..ca2ca59e1 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -25,6 +25,7 @@ * @author Michael Niedermayer */ +#include "atsc_a53.h" #include "avcodec.h" #include "get_bits.h" #include "golomb.h" @@ -52,6 +53,10 @@ void ff_h264_sei_uninit(H264SEIContext *h) h->afd.present = 0; av_buffer_unref(&h->a53_caption.buf_ref); + for (int i = 0; i < h->unregistered.nb_buf_ref; i++) + av_buffer_unref(&h->unregistered.buf_ref[i]); + h->unregistered.nb_buf_ref = 0; + av_freep(&h->unregistered.buf_ref); } int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, @@ -169,87 +174,68 @@ static int decode_registered_user_data_closed_caption(H264SEIA53Caption *h, GetBitContext *gb, void *logctx, int size) { - int flag; - int user_data_type_code; - int cc_count; - if (size < 3) return AVERROR(EINVAL); - user_data_type_code = get_bits(gb, 8); - if (user_data_type_code == 0x3) { - skip_bits(gb, 1); // reserved - - flag = get_bits(gb, 1); // process_cc_data_flag - if (flag) { - skip_bits(gb, 1); // zero bit - cc_count = get_bits(gb, 5); - skip_bits(gb, 8); // reserved - size -= 2; - - if (cc_count && size >= cc_count * 3) { - int old_size = h->buf_ref ? h->buf_ref->size : 0; - const uint64_t new_size = (old_size + cc_count - * UINT64_C(3)); - int i, ret; - - if (new_size > INT_MAX) - return AVERROR(EINVAL); - - /* Allow merging of the cc data from two fields. */ - ret = av_buffer_realloc(&h->buf_ref, new_size); - if (ret < 0) - return ret; - - /* Use of av_buffer_realloc assumes buffer is writeable */ - for (i = 0; i < cc_count; i++) { - h->buf_ref->data[old_size++] = get_bits(gb, 8); - h->buf_ref->data[old_size++] = get_bits(gb, 8); - h->buf_ref->data[old_size++] = get_bits(gb, 8); - } - - skip_bits(gb, 8); // marker_bits - } - } - } else { - int i; - for (i = 0; i < size - 1; i++) - skip_bits(gb, 8); - } - - return 0; + return ff_parse_a53_cc(&h->buf_ref, gb->buffer + get_bits_count(gb) / 8, size); } static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb, void *logctx, int size) { - uint32_t country_code; - uint32_t user_identifier; + int country_code, provider_code; - if (size < 7) + if (size < 3) return AVERROR_INVALIDDATA; - size -= 7; + size -= 3; country_code = get_bits(gb, 8); // itu_t_t35_country_code if (country_code == 0xFF) { + if (size < 1) + return AVERROR_INVALIDDATA; + skip_bits(gb, 8); // itu_t_t35_country_code_extension_byte size--; } - /* itu_t_t35_payload_byte follows */ - skip_bits(gb, 8); // terminal provider code - skip_bits(gb, 8); // terminal provider oriented code - user_identifier = get_bits_long(gb, 32); + if (country_code != 0xB5) { // usa_country_code + av_log(logctx, AV_LOG_VERBOSE, + "Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n", + country_code); + return 0; + } - switch (user_identifier) { + /* itu_t_t35_payload_byte follows */ + provider_code = get_bits(gb, 16); + + switch (provider_code) { + case 0x31: { // atsc_provider_code + uint32_t user_identifier; + + if (size < 4) + return AVERROR_INVALIDDATA; + size -= 4; + + user_identifier = get_bits_long(gb, 32); + switch (user_identifier) { case MKBETAG('D', 'T', 'G', '1'): // afd_data return decode_registered_user_data_afd(&h->afd, gb, size); case MKBETAG('G', 'A', '9', '4'): // closed captions return decode_registered_user_data_closed_caption(&h->a53_caption, gb, logctx, size); default: - skip_bits(gb, size * 8); + av_log(logctx, AV_LOG_VERBOSE, + "Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n", + user_identifier); break; + } + break; + } + default: + av_log(logctx, AV_LOG_VERBOSE, + "Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n", + provider_code); + break; } return 0; @@ -260,25 +246,34 @@ static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext * { uint8_t *user_data; int e, build, i; + AVBufferRef *buf_ref, **tmp; if (size < 16 || size >= INT_MAX - 1) return AVERROR_INVALIDDATA; - user_data = av_malloc(size + 1); - if (!user_data) + tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref)); + if (!tmp) return AVERROR(ENOMEM); + h->buf_ref = tmp; + + buf_ref = av_buffer_alloc(size + 1); + if (!buf_ref) + return AVERROR(ENOMEM); + user_data = buf_ref->data; for (i = 0; i < size; i++) user_data[i] = get_bits(gb, 8); user_data[i] = 0; + buf_ref->size = size; + h->buf_ref[h->nb_buf_ref++] = buf_ref; + 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; - av_free(user_data); return 0; } @@ -449,31 +444,31 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, return ret; switch (type) { - case H264_SEI_TYPE_PIC_TIMING: // Picture timing SEI + case SEI_TYPE_PIC_TIMING: // Picture timing SEI ret = decode_picture_timing(&h->picture_timing, &gb_payload, logctx); break; - case H264_SEI_TYPE_USER_DATA_REGISTERED: + case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: ret = decode_registered_user_data(h, &gb_payload, logctx, size); break; - case H264_SEI_TYPE_USER_DATA_UNREGISTERED: + case SEI_TYPE_USER_DATA_UNREGISTERED: ret = decode_unregistered_user_data(&h->unregistered, &gb_payload, logctx, size); break; - case H264_SEI_TYPE_RECOVERY_POINT: + case SEI_TYPE_RECOVERY_POINT: ret = decode_recovery_point(&h->recovery_point, &gb_payload, logctx); break; - case H264_SEI_TYPE_BUFFERING_PERIOD: + case SEI_TYPE_BUFFERING_PERIOD: ret = decode_buffering_period(&h->buffering_period, &gb_payload, ps, logctx); break; - case H264_SEI_TYPE_FRAME_PACKING: + case SEI_TYPE_FRAME_PACKING_ARRANGEMENT: ret = decode_frame_packing_arrangement(&h->frame_packing, &gb_payload); break; - case H264_SEI_TYPE_DISPLAY_ORIENTATION: + case SEI_TYPE_DISPLAY_ORIENTATION: ret = decode_display_orientation(&h->display_orientation, &gb_payload); break; - case H264_SEI_TYPE_GREEN_METADATA: + case SEI_TYPE_GREEN_METADATA: ret = decode_green_metadata(&h->green_metadata, &gb_payload); break; - case H264_SEI_TYPE_ALTERNATIVE_TRANSFER: + case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: ret = decode_alternative_transfer(&h->alternative_transfer, &gb_payload); break; default: diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h index f07a5055c..14cc55936 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -21,24 +21,8 @@ #include "get_bits.h" #include "h264_ps.h" +#include "sei.h" -/** - * SEI message types - */ -typedef enum { - H264_SEI_TYPE_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1) - H264_SEI_TYPE_PIC_TIMING = 1, ///< picture timing - H264_SEI_TYPE_PAN_SCAN_RECT = 2, ///< pan-scan rectangle - H264_SEI_TYPE_FILLER_PAYLOAD = 3, ///< filler data - H264_SEI_TYPE_USER_DATA_REGISTERED = 4, ///< registered user data as specified by Rec. ITU-T T.35 - H264_SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data - H264_SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) - H264_SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement - H264_SEI_TYPE_DISPLAY_ORIENTATION = 47, ///< display orientation - H264_SEI_TYPE_GREEN_METADATA = 56, ///< GreenMPEG information - H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME = 137, ///< mastering display properties - H264_SEI_TYPE_ALTERNATIVE_TRANSFER = 147, ///< alternative transfer -} H264_SEI_Type; /** * pic_struct in picture timing SEI message @@ -126,6 +110,8 @@ typedef struct H264SEIA53Caption { typedef struct H264SEIUnregistered { int x264_build; + AVBufferRef **buf_ref; + int nb_buf_ref; } H264SEIUnregistered; typedef struct H264SEIRecoveryPoint { diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 4e3abf859..62f7a61ae 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -304,9 +304,8 @@ int ff_h264_update_thread_context(AVCodecContext *dst, if (dst == src) return 0; - // We can't fail if SPS isn't set at it breaks current skip_frame code - //if (!h1->ps.sps) - // return AVERROR_INVALIDDATA; + if (inited && !h1->ps.sps) + return AVERROR_INVALIDDATA; if (inited && (h->width != h1->width || @@ -325,29 +324,22 @@ int ff_h264_update_thread_context(AVCodecContext *dst, // SPS/PPS for (i = 0; i < FF_ARRAY_ELEMS(h->ps.sps_list); i++) { - av_buffer_unref(&h->ps.sps_list[i]); - if (h1->ps.sps_list[i]) { - h->ps.sps_list[i] = av_buffer_ref(h1->ps.sps_list[i]); - if (!h->ps.sps_list[i]) - return AVERROR(ENOMEM); - } + ret = av_buffer_replace(&h->ps.sps_list[i], h1->ps.sps_list[i]); + if (ret < 0) + return ret; } for (i = 0; i < FF_ARRAY_ELEMS(h->ps.pps_list); i++) { - av_buffer_unref(&h->ps.pps_list[i]); - if (h1->ps.pps_list[i]) { - h->ps.pps_list[i] = av_buffer_ref(h1->ps.pps_list[i]); - if (!h->ps.pps_list[i]) - return AVERROR(ENOMEM); - } + ret = av_buffer_replace(&h->ps.pps_list[i], h1->ps.pps_list[i]); + if (ret < 0) + return ret; } - av_buffer_unref(&h->ps.pps_ref); + ret = av_buffer_replace(&h->ps.pps_ref, h1->ps.pps_ref); + if (ret < 0) + return ret; h->ps.pps = NULL; h->ps.sps = NULL; if (h1->ps.pps_ref) { - h->ps.pps_ref = av_buffer_ref(h1->ps.pps_ref); - if (!h->ps.pps_ref) - return AVERROR(ENOMEM); h->ps.pps = (const PPS*)h->ps.pps_ref->data; h->ps.sps = h->ps.pps->sps; } @@ -432,12 +424,29 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->frame_recovered = h1->frame_recovered; - av_buffer_unref(&h->sei.a53_caption.buf_ref); - if (h1->sei.a53_caption.buf_ref) { - h->sei.a53_caption.buf_ref = av_buffer_ref(h1->sei.a53_caption.buf_ref); - if (!h->sei.a53_caption.buf_ref) - return AVERROR(ENOMEM); + ret = av_buffer_replace(&h->sei.a53_caption.buf_ref, h1->sei.a53_caption.buf_ref); + if (ret < 0) + return ret; + + for (i = 0; i < h->sei.unregistered.nb_buf_ref; i++) + av_buffer_unref(&h->sei.unregistered.buf_ref[i]); + h->sei.unregistered.nb_buf_ref = 0; + + if (h1->sei.unregistered.nb_buf_ref) { + ret = av_reallocp_array(&h->sei.unregistered.buf_ref, + h1->sei.unregistered.nb_buf_ref, + sizeof(*h->sei.unregistered.buf_ref)); + if (ret < 0) + return ret; + + for (i = 0; i < h1->sei.unregistered.nb_buf_ref; i++) { + h->sei.unregistered.buf_ref[i] = av_buffer_ref(h1->sei.unregistered.buf_ref[i]); + if (!h->sei.unregistered.buf_ref[i]) + return AVERROR(ENOMEM); + h->sei.unregistered.nb_buf_ref++; + } } + h->sei.unregistered.x264_build = h1->sei.unregistered.x264_build; if (!h->cur_pic_ptr) return 0; @@ -912,6 +921,11 @@ static int h264_slice_header_init(H264Context *h) const SPS *sps = h->ps.sps; int i, ret; + if (!sps) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + ff_set_sar(h->avctx, sps->sar); av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt, &h->chroma_x_shift, &h->chroma_y_shift); @@ -1125,9 +1139,10 @@ static int h264_export_frame_props(H264Context *h) { const SPS *sps = h->ps.sps; H264Picture *cur = h->cur_pic_ptr; + AVFrame *out = cur->f; - cur->f->interlaced_frame = 0; - cur->f->repeat_pict = 0; + out->interlaced_frame = 0; + out->repeat_pict = 0; /* Signal interlacing information externally. */ /* Prioritize picture timing SEI information over used @@ -1150,59 +1165,59 @@ static int h264_export_frame_props(H264Context *h) break; case H264_SEI_PIC_STRUCT_TOP_FIELD: case H264_SEI_PIC_STRUCT_BOTTOM_FIELD: - cur->f->interlaced_frame = 1; + out->interlaced_frame = 1; break; case H264_SEI_PIC_STRUCT_TOP_BOTTOM: case H264_SEI_PIC_STRUCT_BOTTOM_TOP: if (FIELD_OR_MBAFF_PICTURE(h)) - cur->f->interlaced_frame = 1; + out->interlaced_frame = 1; else // try to flag soft telecine progressive - cur->f->interlaced_frame = h->prev_interlaced_frame; + out->interlaced_frame = h->prev_interlaced_frame; break; case H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: case H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: /* Signal the possibility of telecined film externally * (pic_struct 5,6). From these hints, let the applications * decide if they apply deinterlacing. */ - cur->f->repeat_pict = 1; + out->repeat_pict = 1; break; case H264_SEI_PIC_STRUCT_FRAME_DOUBLING: - cur->f->repeat_pict = 2; + out->repeat_pict = 2; break; case H264_SEI_PIC_STRUCT_FRAME_TRIPLING: - cur->f->repeat_pict = 4; + out->repeat_pict = 4; break; } if ((pt->ct_type & 3) && pt->pic_struct <= H264_SEI_PIC_STRUCT_BOTTOM_TOP) - cur->f->interlaced_frame = (pt->ct_type & (1 << 1)) != 0; + out->interlaced_frame = (pt->ct_type & (1 << 1)) != 0; } else { /* Derive interlacing flag from used decoding process. */ - cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h); + out->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h); } - h->prev_interlaced_frame = cur->f->interlaced_frame; + h->prev_interlaced_frame = out->interlaced_frame; if (cur->field_poc[0] != cur->field_poc[1]) { /* Derive top_field_first from field pocs. */ - cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1]; + out->top_field_first = cur->field_poc[0] < cur->field_poc[1]; } else { if (sps->pic_struct_present_flag && h->sei.picture_timing.present) { /* Use picture timing SEI information. Even if it is a * information of a past frame, better than nothing. */ if (h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM || h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP) - cur->f->top_field_first = 1; + out->top_field_first = 1; else - cur->f->top_field_first = 0; - } else if (cur->f->interlaced_frame) { + out->top_field_first = 0; + } else if (out->interlaced_frame) { /* Default to top field first when pic_struct_present_flag * is not set but interlaced frame detected */ - cur->f->top_field_first = 1; + out->top_field_first = 1; } else { /* Most likely progressive */ - cur->f->top_field_first = 0; + out->top_field_first = 0; } } @@ -1211,7 +1226,7 @@ static int h264_export_frame_props(H264Context *h) h->sei.frame_packing.content_interpretation_type > 0 && h->sei.frame_packing.content_interpretation_type < 3) { H264SEIFramePacking *fp = &h->sei.frame_packing; - AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f); + AVStereo3D *stereo = av_stereo3d_create_side_data(out); if (stereo) { switch (fp->arrangement_type) { case H264_SEI_FPA_TYPE_CHECKERBOARD: @@ -1258,7 +1273,7 @@ static int h264_export_frame_props(H264Context *h) h->sei.display_orientation.vflip)) { H264SEIDisplayOrientation *o = &h->sei.display_orientation; double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16); - AVFrameSideData *rotation = av_frame_new_side_data(cur->f, + AVFrameSideData *rotation = av_frame_new_side_data(out, AV_FRAME_DATA_DISPLAYMATRIX, sizeof(int32_t) * 9); if (rotation) { @@ -1269,7 +1284,7 @@ static int h264_export_frame_props(H264Context *h) } if (h->sei.afd.present) { - AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_AFD, + AVFrameSideData *sd = av_frame_new_side_data(out, AV_FRAME_DATA_AFD, sizeof(uint8_t)); if (sd) { @@ -1281,7 +1296,7 @@ static int h264_export_frame_props(H264Context *h) if (h->sei.a53_caption.buf_ref) { H264SEIA53Caption *a53 = &h->sei.a53_caption; - AVFrameSideData *sd = av_frame_new_side_data_from_buf(cur->f, AV_FRAME_DATA_A53_CC, a53->buf_ref); + AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, AV_FRAME_DATA_A53_CC, a53->buf_ref); if (!sd) av_buffer_unref(&a53->buf_ref); a53->buf_ref = NULL; @@ -1289,11 +1304,25 @@ static int h264_export_frame_props(H264Context *h) h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } - if (h->sei.picture_timing.timecode_cnt > 0) { - uint32_t tc = 0; - uint32_t *tc_sd; + for (int i = 0; i < h->sei.unregistered.nb_buf_ref; i++) { + H264SEIUnregistered *unreg = &h->sei.unregistered; - AVFrameSideData *tcside = av_frame_new_side_data(cur->f, + if (unreg->buf_ref[i]) { + AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, + AV_FRAME_DATA_SEI_UNREGISTERED, + unreg->buf_ref[i]); + if (!sd) + av_buffer_unref(&unreg->buf_ref[i]); + unreg->buf_ref[i] = NULL; + } + } + h->sei.unregistered.nb_buf_ref = 0; + + if (h->sei.picture_timing.timecode_cnt > 0) { + uint32_t *tc_sd; + char tcbuf[AV_TIMECODE_STR_SIZE]; + + AVFrameSideData *tcside = av_frame_new_side_data(out, AV_FRAME_DATA_S12M_TIMECODE, sizeof(uint32_t)*4); if (!tcside) @@ -1303,33 +1332,15 @@ static int h264_export_frame_props(H264Context *h) tc_sd[0] = h->sei.picture_timing.timecode_cnt; for (int i = 0; i < tc_sd[0]; i++) { - uint32_t frames; + int drop = h->sei.picture_timing.timecode[i].dropframe; + int hh = h->sei.picture_timing.timecode[i].hours; + int mm = h->sei.picture_timing.timecode[i].minutes; + int ss = h->sei.picture_timing.timecode[i].seconds; + int ff = h->sei.picture_timing.timecode[i].frame; - /* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS. - See SMPTE ST 12-1:2014 Sec 12.1 for more info. */ - if (av_cmp_q(h->avctx->framerate, (AVRational) {30, 1}) == 1) { - frames = h->sei.picture_timing.timecode[i].frame / 2; - if (h->sei.picture_timing.timecode[i].frame % 2 == 1) { - if (av_cmp_q(h->avctx->framerate, (AVRational) {50, 1}) == 0) - tc |= (1 << 7); - else - tc |= (1 << 23); - } - } else { - frames = h->sei.picture_timing.timecode[i].frame; - } - - tc |= h->sei.picture_timing.timecode[i].dropframe << 30; - tc |= (frames / 10) << 28; - tc |= (frames % 10) << 24; - tc |= (h->sei.picture_timing.timecode[i].seconds / 10) << 20; - tc |= (h->sei.picture_timing.timecode[i].seconds % 10) << 16; - tc |= (h->sei.picture_timing.timecode[i].minutes / 10) << 12; - tc |= (h->sei.picture_timing.timecode[i].minutes % 10) << 8; - tc |= (h->sei.picture_timing.timecode[i].hours / 10) << 4; - tc |= (h->sei.picture_timing.timecode[i].hours % 10); - - tc_sd[i + 1] = tc; + tc_sd[i + 1] = av_timecode_get_smpte(h->avctx->framerate, drop, hh, mm, ss, ff); + av_timecode_make_smpte_tc_string2(tcbuf, h->avctx->framerate, tc_sd[i + 1], 0, 0); + av_dict_set(&out->metadata, "timecode", tcbuf, 0); } h->sei.picture_timing.timecode_cnt = 0; } @@ -1592,14 +1603,15 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl, ff_thread_await_progress(&prev->tf, INT_MAX, 0); if (prev->field_picture) ff_thread_await_progress(&prev->tf, INT_MAX, 1); - av_image_copy(h->short_ref[0]->f->data, - h->short_ref[0]->f->linesize, - (const uint8_t **)prev->f->data, - prev->f->linesize, - prev->f->format, - prev->f->width, - prev->f->height); + ff_thread_release_buffer(h->avctx, &h->short_ref[0]->tf); + h->short_ref[0]->tf.f = h->short_ref[0]->f; + ret = ff_thread_ref_frame(&h->short_ref[0]->tf, &prev->tf); + if (ret < 0) + return ret; h->short_ref[0]->poc = prev->poc + 2U; + ff_thread_report_progress(&h->short_ref[0]->tf, INT_MAX, 0); + if (h->short_ref[0]->field_picture) + ff_thread_report_progress(&h->short_ref[0]->tf, INT_MAX, 1); } else if (!h->frame_recovered && !h->avctx->hwaccel) ff_color_frame(h->short_ref[0]->f, c); h->short_ref[0]->frame_num = h->poc.prev_frame_num; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 6270ea80d..47b9abbc5 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -182,40 +182,27 @@ 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->nb_slice_ctx, 1); + const int st_size = big_mb_num + h->mb_stride; int x, y; - FF_ALLOCZ_ARRAY_OR_GOTO(h->avctx, h->intra4x4_pred_mode, - row_mb_num, 8 * sizeof(uint8_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(h->intra4x4_pred_mode, row_mb_num * 8) || + !FF_ALLOCZ_TYPED_ARRAY(h->non_zero_count, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->slice_table_base, st_size) || + !FF_ALLOCZ_TYPED_ARRAY(h->cbp_table, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->chroma_pred_mode_table, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->mvd_table[0], row_mb_num * 8) || + !FF_ALLOCZ_TYPED_ARRAY(h->mvd_table[1], row_mb_num * 8) || + !FF_ALLOCZ_TYPED_ARRAY(h->direct_table, big_mb_num * 4) || + !FF_ALLOCZ_TYPED_ARRAY(h->list_counts, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->mb2b_xy, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->mb2br_xy, big_mb_num)) + return AVERROR(ENOMEM); h->slice_ctx[0].intra4x4_pred_mode = h->intra4x4_pred_mode; - - FF_ALLOCZ_OR_GOTO(h->avctx, h->non_zero_count, - big_mb_num * 48 * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(h->avctx, h->slice_table_base, - (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base), fail) - FF_ALLOCZ_OR_GOTO(h->avctx, h->cbp_table, - big_mb_num * sizeof(uint16_t), fail) - FF_ALLOCZ_OR_GOTO(h->avctx, h->chroma_pred_mode_table, - big_mb_num * sizeof(uint8_t), fail) - FF_ALLOCZ_ARRAY_OR_GOTO(h->avctx, h->mvd_table[0], - row_mb_num, 16 * sizeof(uint8_t), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(h->avctx, h->mvd_table[1], - row_mb_num, 16 * sizeof(uint8_t), fail); h->slice_ctx[0].mvd_table[0] = h->mvd_table[0]; h->slice_ctx[0].mvd_table[1] = h->mvd_table[1]; - - FF_ALLOCZ_OR_GOTO(h->avctx, h->direct_table, - 4 * big_mb_num * sizeof(uint8_t), fail); - FF_ALLOCZ_OR_GOTO(h->avctx, h->list_counts, - big_mb_num * sizeof(uint8_t), fail) - memset(h->slice_table_base, -1, - (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base)); + st_size * sizeof(*h->slice_table_base)); h->slice_table = h->slice_table_base + h->mb_stride * 2 + 1; - - FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2b_xy, - big_mb_num * sizeof(uint32_t), fail); - FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2br_xy, - big_mb_num * sizeof(uint32_t), fail); for (y = 0; y < h->mb_height; y++) for (x = 0; x < h->mb_width; x++) { const int mb_xy = x + y * h->mb_stride; @@ -226,9 +213,6 @@ int ff_h264_alloc_tables(H264Context *h) } return 0; - -fail: - return AVERROR(ENOMEM); } /** @@ -253,8 +237,8 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) if (sl != h->slice_ctx) { memset(er, 0, sizeof(*er)); - } else - if (CONFIG_ERROR_RESILIENCE) { + } else if (CONFIG_ERROR_RESILIENCE) { + const int er_size = h->mb_height * h->mb_stride * (4*sizeof(int) + 1); /* init ER */ er->avctx = h->avctx; @@ -269,8 +253,11 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) er->b8_stride = h->mb_width * 2 + 1; // error resilience code looks cleaner with this - FF_ALLOCZ_OR_GOTO(h->avctx, er->mb_index2xy, - (h->mb_num + 1) * sizeof(int), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(er->mb_index2xy, h->mb_num + 1) || + !FF_ALLOCZ_TYPED_ARRAY(er->error_status_table, mb_array_size) || + !FF_ALLOCZ_TYPED_ARRAY(er->er_temp_buffer, er_size) || + !FF_ALLOCZ_TYPED_ARRAY(sl->dc_val_base, yc_size)) + return AVERROR(ENOMEM); // ff_h264_free_tables will clean up for us for (y = 0; y < h->mb_height; y++) for (x = 0; x < h->mb_width; x++) @@ -278,15 +265,6 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) 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->error_status_table, - mb_array_size * sizeof(uint8_t), fail); - - FF_ALLOC_OR_GOTO(h->avctx, er->er_temp_buffer, - h->mb_height * h->mb_stride * (4*sizeof(int) + 1), fail); - - FF_ALLOCZ_OR_GOTO(h->avctx, sl->dc_val_base, - yc_size * sizeof(int16_t), fail); er->dc_val[0] = sl->dc_val_base + h->mb_width * 2 + 2; er->dc_val[1] = sl->dc_val_base + y_size + h->mb_stride + 1; er->dc_val[2] = er->dc_val[1] + c_size; @@ -295,9 +273,6 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) } return 0; - -fail: - return AVERROR(ENOMEM); // ff_h264_free_tables will clean up for us } static int h264_init_context(AVCodecContext *avctx, H264Context *h) @@ -872,7 +847,7 @@ fail: return ret; } -static int is_extra(const uint8_t *buf, int buf_size) +static int is_avcc_extradata(const uint8_t *buf, int buf_size) { int cnt= buf[5]&0x1f; const uint8_t *p= buf+6; @@ -999,16 +974,15 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, if (buf_size == 0) return send_next_delayed_frame(h, pict, got_frame, 0); - if (h->is_avc && av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) { - int side_size; + if (av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) { + buffer_size_t side_size; uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); - if (is_extra(side, side_size)) - ff_h264_decode_extradata(side, side_size, - &h->ps, &h->is_avc, &h->nal_length_size, - avctx->err_recognition, avctx); + ff_h264_decode_extradata(side, side_size, + &h->ps, &h->is_avc, &h->nal_length_size, + avctx->err_recognition, avctx); } if (h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC) { - if (is_extra(buf, buf_size)) + if (is_avcc_extradata(buf, buf_size)) return ff_h264_decode_extradata(buf, buf_size, &h->ps, &h->is_avc, &h->nal_length_size, avctx->err_recognition, avctx); @@ -1080,7 +1054,7 @@ AVCodec ff_h264_decoder = { .capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_H264_DXVA2_HWACCEL HWACCEL_DXVA2(h264), #endif diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index 29c4d4e42..b3677cdbb 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -30,6 +30,7 @@ #include "libavutil/buffer.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "libavutil/thread.h" #include "cabac.h" diff --git a/libavcodec/h265_metadata_bsf.c b/libavcodec/h265_metadata_bsf.c index 749456157..d84183976 100644 --- a/libavcodec/h265_metadata_bsf.c +++ b/libavcodec/h265_metadata_bsf.c @@ -20,28 +20,19 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_h265.h" #include "hevc.h" #include "h265_profile_level.h" -enum { - PASS, - INSERT, - REMOVE, -}; - enum { LEVEL_UNSET = -2, LEVEL_AUTO = -1, }; typedef struct H265MetadataContext { - const AVClass *class; - - CodedBitstreamContext *cbc; - CodedBitstreamFragment access_unit; + CBSBSFContext common; H265RawAUD aud_nal; @@ -337,89 +328,18 @@ static int h265_metadata_update_sps(AVBSFContext *bsf, return 0; } -static int h265_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) +static int h265_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *au) { H265MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - uint8_t *side_data; - int side_data_size; int err, i; - side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, - &side_data_size); - if (!side_data_size) - return 0; - - err = ff_cbs_read(ctx->cbc, au, side_data, side_data_size); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n"); - return err; - } - - if (ctx->level == LEVEL_AUTO && !ctx->level_guess) - h265_metadata_guess_level(bsf, au); - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == HEVC_NAL_VPS) { - err = h265_metadata_update_vps(bsf, au->units[i].content); - if (err < 0) - return err; - } - if (au->units[i].type == HEVC_NAL_SPS) { - err = h265_metadata_update_sps(bsf, au->units[i].content); - if (err < 0) - return err; - } - } - - err = ff_cbs_write_fragment_data(ctx->cbc, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n"); - return err; - } - - side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, au->data_size); - if (!side_data) - return AVERROR(ENOMEM); - memcpy(side_data, au->data, au->data_size); - - ff_cbs_fragment_reset(ctx->cbc, au); - - return 0; -} - -static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) -{ - H265MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - int err, i; - - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = h265_metadata_update_side_data(bsf, pkt); - if (err < 0) - goto fail; - - err = ff_cbs_read_packet(ctx->cbc, au, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } - - if (au->nb_units == 0) { - av_log(bsf, AV_LOG_ERROR, "No NAL units in packet.\n"); - err = AVERROR_INVALIDDATA; - goto fail; - } - // If an AUD is present, it must be the first NAL unit. - if (au->units[0].type == HEVC_NAL_AUD) { - if (ctx->aud == REMOVE) - ff_cbs_delete_unit(ctx->cbc, au, 0); + if (au->nb_units && au->units[0].type == HEVC_NAL_AUD) { + if (ctx->aud == BSF_ELEMENT_REMOVE) + ff_cbs_delete_unit(au, 0); } else { - if (ctx->aud == INSERT) { + if (pkt && ctx->aud == BSF_ELEMENT_INSERT) { H265RawAUD *aud = &ctx->aud_nal; int pic_type = 0, temporal_id = 8, layer_id = 0; @@ -449,11 +369,10 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) }; aud->pic_type = pic_type; - err = ff_cbs_insert_unit_content(ctx->cbc, au, - 0, HEVC_NAL_AUD, aud, NULL); + err = ff_cbs_insert_unit_content(au, 0, HEVC_NAL_AUD, aud, NULL); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n"); - goto fail; + return err; } } } @@ -465,97 +384,35 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (au->units[i].type == HEVC_NAL_VPS) { err = h265_metadata_update_vps(bsf, au->units[i].content); if (err < 0) - goto fail; + return err; } if (au->units[i].type == HEVC_NAL_SPS) { err = h265_metadata_update_sps(bsf, au->units[i].content); if (err < 0) - goto fail; + return err; } } - err = ff_cbs_write_packet(ctx->cbc, pkt, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; - } - - err = 0; -fail: - ff_cbs_fragment_reset(ctx->cbc, au); - - if (err < 0) - av_packet_unref(pkt); - - return err; + return 0; } +static const CBSBSFType h265_metadata_type = { + .codec_id = AV_CODEC_ID_HEVC, + .fragment_name = "access unit", + .unit_name = "NAL unit", + .update_fragment = &h265_metadata_update_fragment, +}; + static int h265_metadata_init(AVBSFContext *bsf) { - H265MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - int err, i; - - err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_HEVC, bsf); - if (err < 0) - return err; - - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->cbc, au, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - if (ctx->level == LEVEL_AUTO) - h265_metadata_guess_level(bsf, au); - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == HEVC_NAL_VPS) { - err = h265_metadata_update_vps(bsf, au->units[i].content); - if (err < 0) - goto fail; - } - if (au->units[i].type == HEVC_NAL_SPS) { - err = h265_metadata_update_sps(bsf, au->units[i].content); - if (err < 0) - goto fail; - } - } - - err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; - } - } - - err = 0; -fail: - ff_cbs_fragment_reset(ctx->cbc, au); - return err; -} - -static void h265_metadata_close(AVBSFContext *bsf) -{ - H265MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit); - ff_cbs_close(&ctx->cbc); + return ff_cbs_bsf_generic_init(bsf, &h265_metadata_type); } #define OFFSET(x) offsetof(H265MetadataContext, x) #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM) static const AVOption h265_metadata_options[] = { - { "aud", "Access Unit Delimiter NAL units", - OFFSET(aud), AV_OPT_TYPE_INT, - { .i64 = PASS }, PASS, REMOVE, FLAGS, "aud" }, - { "pass", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = PASS }, .flags = FLAGS, .unit = "aud" }, - { "insert", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = INSERT }, .flags = FLAGS, .unit = "aud" }, - { "remove", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = REMOVE }, .flags = FLAGS, .unit = "aud" }, + BSF_ELEMENT_OPTIONS_PIR("aud", "Access Unit Delimiter NAL units", + aud, FLAGS), { "sample_aspect_ratio", "Set sample aspect ratio (table E-1)", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, @@ -646,7 +503,7 @@ const AVBitStreamFilter ff_hevc_metadata_bsf = { .priv_data_size = sizeof(H265MetadataContext), .priv_class = &h265_metadata_class, .init = &h265_metadata_init, - .close = &h265_metadata_close, - .filter = &h265_metadata_filter, + .close = &ff_cbs_bsf_generic_close, + .filter = &ff_cbs_bsf_generic_filter, .codec_ids = h265_metadata_codec_ids, }; diff --git a/libavcodec/h265_profile_level.c b/libavcodec/h265_profile_level.c index d79c1ab20..7ff9681f6 100644 --- a/libavcodec/h265_profile_level.c +++ b/libavcodec/h265_profile_level.c @@ -120,18 +120,6 @@ static const H265ProfileDescriptor h265_profiles[] = { }; -const H265LevelDescriptor *ff_h265_get_level(int level_idc) -{ - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(h265_levels); i++) { - if (h265_levels[i].level_idc == level_idc) - return &h265_levels[i]; - } - - return NULL; -} - const H265ProfileDescriptor *ff_h265_get_profile(const H265RawProfileTierLevel *ptl) { int i; diff --git a/libavcodec/h265_profile_level.h b/libavcodec/h265_profile_level.h index 2d5bebaec..f1a11f51d 100644 --- a/libavcodec/h265_profile_level.h +++ b/libavcodec/h265_profile_level.h @@ -70,8 +70,6 @@ typedef struct H265ProfileDescriptor { } H265ProfileDescriptor; -const H265LevelDescriptor *ff_h265_get_level(int level_idc); - const H265ProfileDescriptor *ff_h265_get_profile(const H265RawProfileTierLevel *ptl); diff --git a/libavcodec/half2float.h b/libavcodec/half2float.h new file mode 100644 index 000000000..fd11caffd --- /dev/null +++ b/libavcodec/half2float.h @@ -0,0 +1,74 @@ +/* + * 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_HALF2FLOAT_H +#define AVCODEC_HALF2FLOAT_H + +#include + +static uint32_t convertmantissa(uint32_t i) +{ + int32_t m = i << 13; // Zero pad mantissa bits + int32_t e = 0; // Zero exponent + + while (!(m & 0x00800000)) { // While not normalized + e -= 0x00800000; // Decrement exponent (1<<23) + m <<= 1; // Shift mantissa + } + + m &= ~0x00800000; // Clear leading 1 bit + e += 0x38800000; // Adjust bias ((127-14)<<23) + + return m | e; // Return combined number +} + +static void half2float_table(uint32_t *mantissatable, uint32_t *exponenttable, + uint16_t *offsettable) +{ + mantissatable[0] = 0; + for (int i = 1; i < 1024; i++) + mantissatable[i] = convertmantissa(i); + for (int i = 1024; i < 2048; i++) + mantissatable[i] = 0x38000000UL + ((i - 1024) << 13UL); + + exponenttable[0] = 0; + for (int i = 1; i < 31; i++) + exponenttable[i] = i << 23; + for (int i = 33; i < 63; i++) + exponenttable[i] = 0x80000000UL + ((i - 32) << 23UL); + exponenttable[31]= 0x47800000UL; + exponenttable[32]= 0x80000000UL; + exponenttable[63]= 0xC7800000UL; + + offsettable[0] = 0; + for (int i = 1; i < 64; i++) + offsettable[i] = 1024; + offsettable[32] = 0; +} + +static uint32_t half2float(uint16_t h, uint32_t *mantissatable, uint32_t *exponenttable, + uint16_t *offsettable) +{ + uint32_t f; + + f = mantissatable[offsettable[h >> 10] + (h & 0x3ff)] + exponenttable[h >> 10]; + + return f; +} + +#endif /* AVCODEC_HALF2FLOAT_H */ diff --git a/libavcodec/hca_data.h b/libavcodec/hca_data.h index 80b4a794d..7093221c2 100644 --- a/libavcodec/hca_data.h +++ b/libavcodec/hca_data.h @@ -86,18 +86,18 @@ static const float intensity_ratio_table[] = { 2.0, 1.85714, 1.71429, 1.57143, 1.42857, 1.28571, 1.14286, 1.0, 0.857143, 0.714286, 0.571429, 0.428571, 0.285714, 0.142857, 0.0, 0.0, - 0, 1.87066e-08, 2.49253e-08, 3.32113e-08, 4.42518e-08, 5.89626e-08, 7.85637e-08, 1.04681e-07, +}; + +static const float scale_conversion_table[] = +{ + 0, 0, 1.87066e-08, 2.49253e-08, 3.32113e-08, 4.42518e-08, 5.89626e-08, 7.85637e-08, 1.04681e-07, 1.3948e-07, 1.85848e-07, 2.4763e-07, 3.2995e-07, 4.39636e-07, 5.85785e-07, 7.80519e-07, 1.03999e-06, 1.38572e-06, 1.84637e-06, 2.46017e-06, 3.27801e-06, 4.36772e-06, 5.8197e-06, 7.75435e-06, 1.03321e-05, 1.37669e-05, 1.83435e-05, 2.44414e-05, 3.25665e-05, 4.33927e-05, 5.78179e-05, 7.70384e-05, 0.000102648, 0.000136772, 0.00018224, 0.000242822, 0.000323544, 0.000431101, 0.000574413, 0.000765366, 0.0010198, 0.00135881, 0.00181053, 0.0024124, 0.00321437, 0.00428293, 0.00570671, 0.00760381, 0.0101316, 0.0134996, 0.0179873, 0.0239669, 0.0319343, 0.0425503, 0.0566954, 0.0755428, 0.100656, - 0.134117, 0.178702, 0.238108, 0.317263, 0.422731, 0.563261, 0.750507, 0.0, -}; - -static const float scale_conversion_table[] = -{ + 0.134117, 0.178702, 0.238108, 0.317263, 0.422731, 0.563261, 0.750507, 1.0, 1.33243, 1.77538, 2.36557, 3.15196, 4.19978, 5.59592, 7.45618, 9.93486, 13.2375, 17.6381, 23.5016, 31.3143, 41.7242, 55.5947, 74.0762, 98.7015, 131.513, 175.232, 233.485, 311.103, 414.524, 552.326, 735.937, @@ -108,6 +108,8 @@ static const float scale_conversion_table[] = 9.55285e+06, 1.27285e+07, 1.69599e+07, 2.25979e+07, 3.01102e+07, 4.01198e+07, 5.3457e+07, 0, }; +static const int scale_conv_bias = 64; + static const float dequantizer_scaling_table[] = { 1.58838e-07, 2.11641e-07, 2.81998e-07, 3.75743e-07, 5.00652e-07, 6.67085e-07, 8.88846e-07, 1.18433e-06, diff --git a/libavcodec/hcadec.c b/libavcodec/hcadec.c index f46ed699d..9c3eda21a 100644 --- a/libavcodec/hcadec.c +++ b/libavcodec/hcadec.c @@ -19,6 +19,7 @@ #include "libavutil/crc.h" #include "libavutil/float_dsp.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "libavutil/tx.h" #include "avcodec.h" @@ -267,7 +268,7 @@ static void apply_intensity_stereo(HCAContext *s, ChannelContext *ch1, ChannelCo int index, unsigned band_count, unsigned base_band_count, unsigned stereo_band_count) { - float ratio_l = intensity_ratio_table[ch1->intensity[index]]; + float ratio_l = intensity_ratio_table[ch2->intensity[index]]; float ratio_r = ratio_l - 2.0f; float *c1 = &ch1->imdct_in[base_band_count]; float *c2 = &ch2->imdct_in[base_band_count]; @@ -291,7 +292,8 @@ static void reconstruct_hfr(HCAContext *s, ChannelContext *ch, for (int i = 0, k = start_band, l = start_band - 1; i < hfr_group_count; i++){ for (int j = 0; j < bands_per_hfr_group && k < total_band_count && l >= 0; j++, k++, l--){ - ch->imdct_in[k] = scale_conversion_table[ (ch->hfr_scale[i] - ch->scale_factors[l]) & 63 ] * ch->imdct_in[l]; + ch->imdct_in[k] = scale_conversion_table[ scale_conv_bias + + av_clip_intp2(ch->hfr_scale[i] - ch->scale_factors[l], 6) ] * ch->imdct_in[l]; } } diff --git a/libavcodec/hcom.c b/libavcodec/hcom.c index 8300676f9..06fa25fcd 100644 --- a/libavcodec/hcom.c +++ b/libavcodec/hcom.c @@ -67,15 +67,11 @@ static av_cold int hcom_init(AVCodecContext *avctx) if (s->dict[i].l >= 0 && (s->dict[i].l >= s->dict_entries || s->dict[i].r >= s->dict_entries || - s->dict[i].r < 0 )) { - av_freep(&s->dict); + s->dict[i].r < 0 )) return AVERROR_INVALIDDATA; - } } - if (s->dict[0].l < 0) { - av_freep(&s->dict); + if (s->dict[0].l < 0) return AVERROR_INVALIDDATA; - } avctx->sample_fmt = AV_SAMPLE_FMT_U8; s->dict_entry = 0; @@ -148,4 +144,5 @@ AVCodec ff_hcom_decoder = { .close = hcom_close, .decode = hcom_decode, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index 3635b16ca..9b8c8e342 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -454,12 +454,19 @@ void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts) (s->ps.sps->ctb_width == 2 && ctb_addr_ts % s->ps.sps->ctb_width == 0))) { memcpy(s->cabac_state, s->HEVClc->cabac_state, HEVC_CONTEXTS); + if (s->ps.sps->persistent_rice_adaptation_enabled_flag) { + memcpy(s->stat_coeff, s->HEVClc->stat_coeff, HEVC_STAT_COEFFS); + } } } -static void load_states(HEVCContext *s) +static void load_states(HEVCContext *s, int thread) { memcpy(s->HEVClc->cabac_state, s->cabac_state, HEVC_CONTEXTS); + if (s->ps.sps->persistent_rice_adaptation_enabled_flag) { + const HEVCContext *prev = s->sList[(thread + s->threads_number - 1) % s->threads_number]; + memcpy(s->HEVClc->stat_coeff, prev->stat_coeff, HEVC_STAT_COEFFS); + } } static int cabac_reinit(HEVCLocalContext *lc) @@ -501,7 +508,7 @@ static void cabac_init_state(HEVCContext *s) s->HEVClc->stat_coeff[i] = 0; } -int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) +int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts, int thread) { if (ctb_addr_ts == s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]) { int ret = cabac_init_decoder(s); @@ -518,7 +525,7 @@ int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) if (s->ps.sps->ctb_width == 1) cabac_init_state(s); else if (s->sh.dependent_slice_segment_flag == 1) - load_states(s); + load_states(s, thread); } } } else { @@ -549,7 +556,7 @@ int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) if (s->ps.sps->ctb_width == 1) cabac_init_state(s); else - load_states(s); + load_states(s, thread); } } } diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c index fd0dbd9a5..1f6ca5a31 100644 --- a/libavcodec/hevc_mvs.c +++ b/libavcodec/hevc_mvs.c @@ -48,9 +48,9 @@ void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, lc->na.cand_up = (lc->ctb_up_flag || y0b); lc->na.cand_left = (lc->ctb_left_flag || x0b); - lc->na.cand_up_left = (!x0b && !y0b) ? lc->ctb_up_left_flag : lc->na.cand_left && lc->na.cand_up; + lc->na.cand_up_left = (x0b || y0b) ? lc->na.cand_left && lc->na.cand_up : lc->ctb_up_left_flag; lc->na.cand_up_right_sap = - ((x0b + nPbW) == (1 << s->ps.sps->log2_ctb_size)) ? + (x0b + nPbW == 1 << s->ps.sps->log2_ctb_size) ? lc->ctb_up_right_flag && !y0b : lc->na.cand_up; lc->na.cand_up_right = lc->na.cand_up_right_sap diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 5af4b788d..463d35205 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -136,7 +136,7 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal, for (i = 0; i < ps->pps->num_extra_slice_header_bits; i++) skip_bits(gb, 1); // slice_reserved_undetermined_flag[] - slice_type = get_ue_golomb(gb); + slice_type = get_ue_golomb_31(gb); if (!(slice_type == HEVC_SLICE_I || slice_type == HEVC_SLICE_P || slice_type == HEVC_SLICE_B)) { av_log(avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n", diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 139f3deed..764c4849e 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -783,7 +783,7 @@ static void set_default_scaling_list_data(ScalingList *sl) static int scaling_list_data(GetBitContext *gb, AVCodecContext *avctx, ScalingList *sl, HEVCSPS *sps) { uint8_t scaling_list_pred_mode_flag; - int32_t scaling_list_dc_coef[2][6]; + uint8_t scaling_list_dc_coef[2][6]; int size_id, matrix_id, pos; int i; diff --git a/libavcodec/hevc_ps_enc.c b/libavcodec/hevc_ps_enc.c index 78a73a5c0..5449f81c8 100644 --- a/libavcodec/hevc_ps_enc.c +++ b/libavcodec/hevc_ps_enc.c @@ -113,10 +113,9 @@ int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id, put_bits(&pb, 1, 0); // extension flag put_bits(&pb, 1, 1); // stop bit - avpriv_align_put_bits(&pb); + flush_put_bits(&pb); data_size = put_bits_count(&pb) / 8; - flush_put_bits(&pb); return data_size; } diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index b4b90b570..c881c4338 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -22,6 +22,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "atsc_a53.h" +#include "dynamic_hdr10_plus.h" #include "golomb.h" #include "hevc_ps.h" #include "hevc_sei.h" @@ -164,83 +166,150 @@ static int decode_nal_sei_pic_timing(HEVCSEI *s, GetBitContext *gb, const HEVCPa static int decode_registered_user_data_closed_caption(HEVCSEIA53Caption *s, GetBitContext *gb, int size) { - int flag; - int user_data_type_code; - int cc_count; + int ret; if (size < 3) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; - user_data_type_code = get_bits(gb, 8); - if (user_data_type_code == 0x3) { - skip_bits(gb, 1); // reserved + ret = ff_parse_a53_cc(&s->buf_ref, gb->buffer + get_bits_count(gb) / 8, size); - flag = get_bits(gb, 1); // process_cc_data_flag - if (flag) { - skip_bits(gb, 1); - cc_count = get_bits(gb, 5); - skip_bits(gb, 8); // reserved - size -= 2; + if (ret < 0) + return ret; - if (cc_count && size >= cc_count * 3) { - int old_size = s->buf_ref ? s->buf_ref->size : 0; - const uint64_t new_size = (old_size + cc_count - * UINT64_C(3)); - int i, ret; + skip_bits_long(gb, size * 8); - if (new_size > INT_MAX) - return AVERROR(EINVAL); + return 0; +} - /* Allow merging of the cc data from two fields. */ - ret = av_buffer_realloc(&s->buf_ref, new_size); - if (ret < 0) - return ret; +static int decode_nal_sei_user_data_unregistered(HEVCSEIUnregistered *s, GetBitContext *gb, + int size) +{ + AVBufferRef *buf_ref, **tmp; - for (i = 0; i < cc_count; i++) { - s->buf_ref->data[old_size++] = get_bits(gb, 8); - s->buf_ref->data[old_size++] = get_bits(gb, 8); - s->buf_ref->data[old_size++] = get_bits(gb, 8); - } - skip_bits(gb, 8); // marker_bits - } - } - } else { - int i; - for (i = 0; i < size - 1; i++) - skip_bits(gb, 8); + if (size < 16 || size >= INT_MAX - 1) + return AVERROR_INVALIDDATA; + + tmp = av_realloc_array(s->buf_ref, s->nb_buf_ref + 1, sizeof(*s->buf_ref)); + if (!tmp) + return AVERROR(ENOMEM); + s->buf_ref = tmp; + + buf_ref = av_buffer_alloc(size + 1); + if (!buf_ref) + return AVERROR(ENOMEM); + + for (int i = 0; i < size; i++) + buf_ref->data[i] = get_bits(gb, 8); + buf_ref->data[size] = 0; + buf_ref->size = size; + s->buf_ref[s->nb_buf_ref++] = buf_ref; + + return 0; +} + +static int decode_registered_user_data_dynamic_hdr_plus(HEVCSEIDynamicHDRPlus *s, + GetBitContext *gb, int size) +{ + size_t meta_size; + int err; + AVDynamicHDRPlus *metadata = av_dynamic_hdr_plus_alloc(&meta_size); + if (!metadata) + return AVERROR(ENOMEM); + + err = ff_parse_itu_t_t35_to_dynamic_hdr10_plus(metadata, + gb->buffer + get_bits_count(gb) / 8, size); + if (err < 0) { + av_free(metadata); + return err; } + av_buffer_unref(&s->info); + s->info = av_buffer_create((uint8_t *)metadata, meta_size, NULL, NULL, 0); + if (!s->info) { + av_free(metadata); + return AVERROR(ENOMEM); + } + + skip_bits_long(gb, size * 8); + return 0; } static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEI *s, GetBitContext *gb, - int size) + void *logctx, int size) { - uint32_t country_code; - uint32_t user_identifier; + int country_code, provider_code; - if (size < 7) - return AVERROR(EINVAL); - size -= 7; + if (size < 3) + return AVERROR_INVALIDDATA; + size -= 3; country_code = get_bits(gb, 8); if (country_code == 0xFF) { + if (size < 1) + return AVERROR_INVALIDDATA; + skip_bits(gb, 8); size--; } - skip_bits(gb, 8); - skip_bits(gb, 8); + if (country_code != 0xB5) { // usa_country_code + av_log(logctx, AV_LOG_VERBOSE, + "Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n", + country_code); + goto end; + } - user_identifier = get_bits_long(gb, 32); + provider_code = get_bits(gb, 16); - switch (user_identifier) { + switch (provider_code) { + case 0x3C: { // smpte_provider_code + // A/341 Amendment - 2094-40 + const uint16_t smpte2094_40_provider_oriented_code = 0x0001; + const uint8_t smpte2094_40_application_identifier = 0x04; + uint16_t provider_oriented_code; + uint8_t application_identifier; + + if (size < 3) + return AVERROR_INVALIDDATA; + size -= 3; + + provider_oriented_code = get_bits(gb, 16); + application_identifier = get_bits(gb, 8); + if (provider_oriented_code == smpte2094_40_provider_oriented_code && + application_identifier == smpte2094_40_application_identifier) { + return decode_registered_user_data_dynamic_hdr_plus(&s->dynamic_hdr_plus, gb, size); + } + break; + } + case 0x31: { // atsc_provider_code + uint32_t user_identifier; + + if (size < 4) + return AVERROR_INVALIDDATA; + size -= 4; + + user_identifier = get_bits_long(gb, 32); + switch (user_identifier) { case MKBETAG('G', 'A', '9', '4'): return decode_registered_user_data_closed_caption(&s->a53_caption, gb, size); default: - skip_bits_long(gb, size * 8); + av_log(logctx, AV_LOG_VERBOSE, + "Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n", + user_identifier); break; + } + break; } + default: + av_log(logctx, AV_LOG_VERBOSE, + "Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n", + provider_code); + break; + } + +end: + skip_bits_long(gb, size * 8); return 0; } @@ -280,28 +349,79 @@ static int decode_nal_sei_alternative_transfer(HEVCSEIAlternativeTransfer *s, Ge return 0; } +static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb) +{ + s->num_clock_ts = get_bits(gb, 2); + + for (int i = 0; i < s->num_clock_ts; i++) { + s->clock_timestamp_flag[i] = get_bits(gb, 1); + + if (s->clock_timestamp_flag[i]) { + s->units_field_based_flag[i] = get_bits(gb, 1); + s->counting_type[i] = get_bits(gb, 5); + s->full_timestamp_flag[i] = get_bits(gb, 1); + s->discontinuity_flag[i] = get_bits(gb, 1); + s->cnt_dropped_flag[i] = get_bits(gb, 1); + + s->n_frames[i] = get_bits(gb, 9); + + if (s->full_timestamp_flag[i]) { + s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59); + s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59); + s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23); + } else { + s->seconds_flag[i] = get_bits(gb, 1); + if (s->seconds_flag[i]) { + s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59); + s->minutes_flag[i] = get_bits(gb, 1); + if (s->minutes_flag[i]) { + s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59); + s->hours_flag[i] = get_bits(gb, 1); + if (s->hours_flag[i]) { + s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23); + } + } + } + } + + s->time_offset_length[i] = get_bits(gb, 5); + if (s->time_offset_length[i] > 0) { + s->time_offset_value[i] = get_bits(gb, s->time_offset_length[i]); + } + } + } + + s->present = 1; + return 0; +} + + static int decode_nal_sei_prefix(GetBitContext *gb, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, int type, int size) { switch (type) { case 256: // Mismatched value from HM 8.1 return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gb); - case HEVC_SEI_TYPE_FRAME_PACKING: + case SEI_TYPE_FRAME_PACKING_ARRANGEMENT: return decode_nal_sei_frame_packing_arrangement(&s->frame_packing, gb); - case HEVC_SEI_TYPE_DISPLAY_ORIENTATION: + case SEI_TYPE_DISPLAY_ORIENTATION: return decode_nal_sei_display_orientation(&s->display_orientation, gb); - case HEVC_SEI_TYPE_PICTURE_TIMING: + case SEI_TYPE_PIC_TIMING: return decode_nal_sei_pic_timing(s, gb, ps, logctx, size); - case HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO: + case SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: return decode_nal_sei_mastering_display_info(&s->mastering_display, gb); - case HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO: + case SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO: return decode_nal_sei_content_light_info(&s->content_light, gb); - case HEVC_SEI_TYPE_ACTIVE_PARAMETER_SETS: + case SEI_TYPE_ACTIVE_PARAMETER_SETS: return decode_nal_sei_active_parameter_sets(s, gb, logctx); - case HEVC_SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: - return decode_nal_sei_user_data_registered_itu_t_t35(s, gb, size); - case HEVC_SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: + case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: + return decode_nal_sei_user_data_registered_itu_t_t35(s, gb, logctx, size); + case SEI_TYPE_USER_DATA_UNREGISTERED: + return decode_nal_sei_user_data_unregistered(&s->unregistered, gb, size); + case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: return decode_nal_sei_alternative_transfer(&s->alternative_transfer, gb); + case SEI_TYPE_TIME_CODE: + return decode_nal_sei_timecode(&s->timecode, gb); default: av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); skip_bits_long(gb, 8 * size); @@ -313,7 +433,7 @@ static int decode_nal_sei_suffix(GetBitContext *gb, void *logctx, HEVCSEI *s, int type, int size) { switch (type) { - case HEVC_SEI_TYPE_DECODED_PICTURE_HASH: + case SEI_TYPE_DECODED_PICTURE_HASH: return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gb); default: av_log(logctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type); @@ -373,4 +493,10 @@ int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s, void ff_hevc_reset_sei(HEVCSEI *s) { av_buffer_unref(&s->a53_caption.buf_ref); + + for (int i = 0; i < s->unregistered.nb_buf_ref; i++) + av_buffer_unref(&s->unregistered.buf_ref[i]); + s->unregistered.nb_buf_ref = 0; + av_freep(&s->unregistered.buf_ref); + av_buffer_unref(&s->dynamic_hdr_plus.info); } diff --git a/libavcodec/hevc_sei.h b/libavcodec/hevc_sei.h index a44ccca7f..c67dbceb6 100644 --- a/libavcodec/hevc_sei.h +++ b/libavcodec/hevc_sei.h @@ -24,40 +24,8 @@ #include #include "get_bits.h" +#include "sei.h" -/** - * SEI message types - */ -typedef enum { - HEVC_SEI_TYPE_BUFFERING_PERIOD = 0, - HEVC_SEI_TYPE_PICTURE_TIMING = 1, - HEVC_SEI_TYPE_PAN_SCAN_RECT = 2, - HEVC_SEI_TYPE_FILLER_PAYLOAD = 3, - HEVC_SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35 = 4, - HEVC_SEI_TYPE_USER_DATA_UNREGISTERED = 5, - HEVC_SEI_TYPE_RECOVERY_POINT = 6, - HEVC_SEI_TYPE_SCENE_INFO = 9, - HEVC_SEI_TYPE_FULL_FRAME_SNAPSHOT = 15, - HEVC_SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_START = 16, - HEVC_SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_END = 17, - HEVC_SEI_TYPE_FILM_GRAIN_CHARACTERISTICS = 19, - HEVC_SEI_TYPE_POST_FILTER_HINT = 22, - HEVC_SEI_TYPE_TONE_MAPPING_INFO = 23, - HEVC_SEI_TYPE_FRAME_PACKING = 45, - HEVC_SEI_TYPE_DISPLAY_ORIENTATION = 47, - HEVC_SEI_TYPE_SOP_DESCRIPTION = 128, - HEVC_SEI_TYPE_ACTIVE_PARAMETER_SETS = 129, - HEVC_SEI_TYPE_DECODING_UNIT_INFO = 130, - HEVC_SEI_TYPE_TEMPORAL_LEVEL0_INDEX = 131, - HEVC_SEI_TYPE_DECODED_PICTURE_HASH = 132, - HEVC_SEI_TYPE_SCALABLE_NESTING = 133, - HEVC_SEI_TYPE_REGION_REFRESH_INFO = 134, - HEVC_SEI_TYPE_TIME_CODE = 136, - HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO = 137, - HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO = 144, - HEVC_SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS = 147, - HEVC_SEI_TYPE_ALPHA_CHANNEL_INFO = 165, -} HEVC_SEI_Type; typedef enum { HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING = 7, @@ -91,6 +59,11 @@ typedef struct HEVCSEIA53Caption { AVBufferRef *buf_ref; } HEVCSEIA53Caption; +typedef struct HEVCSEIUnregistered { + AVBufferRef **buf_ref; + int nb_buf_ref; +} HEVCSEIUnregistered; + typedef struct HEVCSEIMasteringDisplay { int present; uint16_t display_primaries[3][2]; @@ -99,6 +72,10 @@ typedef struct HEVCSEIMasteringDisplay { uint32_t min_luminance; } HEVCSEIMasteringDisplay; +typedef struct HEVCSEIDynamicHDRPlus { + AVBufferRef *info; +} HEVCSEIDynamicHDRPlus; + typedef struct HEVCSEIContentLight { int present; uint16_t max_content_light_level; @@ -110,16 +87,39 @@ typedef struct HEVCSEIAlternativeTransfer { int preferred_transfer_characteristics; } HEVCSEIAlternativeTransfer; +typedef struct HEVCSEITimeCode { + int present; + uint8_t num_clock_ts; + uint8_t clock_timestamp_flag[3]; + uint8_t units_field_based_flag[3]; + uint8_t counting_type[3]; + uint8_t full_timestamp_flag[3]; + uint8_t discontinuity_flag[3]; + uint8_t cnt_dropped_flag[3]; + uint16_t n_frames[3]; + uint8_t seconds_value[3]; + uint8_t minutes_value[3]; + uint8_t hours_value[3]; + uint8_t seconds_flag[3]; + uint8_t minutes_flag[3]; + uint8_t hours_flag[3]; + uint8_t time_offset_length[3]; + int32_t time_offset_value[3]; +} HEVCSEITimeCode; + typedef struct HEVCSEI { HEVCSEIPictureHash picture_hash; HEVCSEIFramePacking frame_packing; HEVCSEIDisplayOrientation display_orientation; HEVCSEIPictureTiming picture_timing; HEVCSEIA53Caption a53_caption; + HEVCSEIUnregistered unregistered; HEVCSEIMasteringDisplay mastering_display; + HEVCSEIDynamicHDRPlus dynamic_hdr_plus; HEVCSEIContentLight content_light; int active_seq_parameter_set_id; HEVCSEIAlternativeTransfer alternative_transfer; + HEVCSEITimeCode timecode; } HEVCSEI; struct HEVCParamSets; diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 1eaeaf72f..2231aed25 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -32,6 +32,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/stereo3d.h" +#include "libavutil/timecode.h" #include "bswapdsp.h" #include "bytestream.h" @@ -348,6 +349,15 @@ static void export_stream_params(HEVCContext *s, const HEVCSPS *sps) avctx->colorspace = AVCOL_SPC_UNSPECIFIED; } + avctx->chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED; + if (sps->chroma_format_idc == 1) { + if (sps->vui.chroma_loc_info_present_flag) { + if (sps->vui.chroma_sample_loc_type_top_field <= 5) + avctx->chroma_sample_location = sps->vui.chroma_sample_loc_type_top_field + 1; + } else + avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; + } + if (vps->vps_timing_info_present_flag) { num = vps->vps_num_units_in_tick; den = vps->vps_time_scale; @@ -359,12 +369,22 @@ static void export_stream_params(HEVCContext *s, const HEVCSPS *sps) if (num != 0 && den != 0) av_reduce(&avctx->framerate.den, &avctx->framerate.num, num, den, 1 << 30); +} + +static int export_stream_params_from_sei(HEVCContext *s) +{ + AVCodecContext *avctx = s->avctx; + + if (s->sei.a53_caption.buf_ref) + s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; if (s->sei.alternative_transfer.present && av_color_transfer_name(s->sei.alternative_transfer.preferred_transfer_characteristics) && s->sei.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) { avctx->color_trc = s->sei.alternative_transfer.preferred_transfer_characteristics; } + + return 0; } static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) @@ -414,6 +434,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL *fmt++ = AV_PIX_FMT_VIDEOTOOLBOX; #endif +#if CONFIG_HEVC_VDPAU_HWACCEL + *fmt++ = AV_PIX_FMT_VDPAU; +#endif #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif @@ -435,6 +458,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) case AV_PIX_FMT_YUV420P12: case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUV444P12: +#if CONFIG_HEVC_VDPAU_HWACCEL + *fmt++ = AV_PIX_FMT_VDPAU; +#endif #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif @@ -489,6 +515,9 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps, s->sao_pixel_buffer_v[c_idx] = av_malloc((h * 2 * sps->ctb_width) << sps->pixel_shift); + if (!s->sao_pixel_buffer_h[c_idx] || + !s->sao_pixel_buffer_v[c_idx]) + goto fail; } } @@ -499,6 +528,10 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps, fail: pic_arrays_free(s); + for (i = 0; i < 3; i++) { + av_freep(&s->sao_pixel_buffer_h[i]); + av_freep(&s->sao_pixel_buffer_v[i]); + } s->ps.sps = NULL; return ret; } @@ -566,6 +599,10 @@ static int hls_slice_header(HEVCContext *s) s->max_ra = INT_MAX; } + ret = export_stream_params_from_sei(s); + if (ret < 0) + return ret; + sh->dependent_slice_segment_flag = 0; if (!sh->first_slice_in_pic_flag) { int slice_address_length; @@ -2443,7 +2480,7 @@ static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread) y_ctb = (ctb_addr_rs / ((s->ps.sps->width + ctb_size - 1) >> s->ps.sps->log2_ctb_size)) << s->ps.sps->log2_ctb_size; hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts); - ret = ff_hevc_cabac_init(s, ctb_addr_ts); + ret = ff_hevc_cabac_init(s, ctb_addr_ts, 0); if (ret < 0) { s->tab_slice_address[ctb_addr_rs] = -1; return ret; @@ -2521,7 +2558,7 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int return 0; } - ret = ff_hevc_cabac_init(s, ctb_addr_ts); + ret = ff_hevc_cabac_init(s, ctb_addr_ts, thread); if (ret < 0) goto error; hls_sao_param(s, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> s->ps.sps->log2_ctb_size); @@ -2594,13 +2631,19 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1); - if (!s->sList[1]) { - for (i = 1; i < s->threads_number; i++) { - s->sList[i] = av_malloc(sizeof(HEVCContext)); - memcpy(s->sList[i], s, sizeof(HEVCContext)); - s->HEVClcList[i] = av_mallocz(sizeof(HEVCLocalContext)); - s->sList[i]->HEVClc = s->HEVClcList[i]; + for (i = 1; i < s->threads_number; i++) { + if (s->sList[i] && s->HEVClcList[i]) + continue; + av_freep(&s->sList[i]); + av_freep(&s->HEVClcList[i]); + s->sList[i] = av_malloc(sizeof(HEVCContext)); + s->HEVClcList[i] = av_mallocz(sizeof(HEVCLocalContext)); + if (!s->sList[i] || !s->HEVClcList[i]) { + res = AVERROR(ENOMEM); + goto error; } + memcpy(s->sList[i], s, sizeof(HEVCContext)); + s->sList[i]->HEVClc = s->HEVClcList[i]; } offset = (lc->gb.index >> 3); @@ -2795,8 +2838,57 @@ static int set_side_data(HEVCContext *s) if (!sd) av_buffer_unref(&a53->buf_ref); a53->buf_ref = NULL; + } - s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; + for (int i = 0; i < s->sei.unregistered.nb_buf_ref; i++) { + HEVCSEIUnregistered *unreg = &s->sei.unregistered; + + if (unreg->buf_ref[i]) { + AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, + AV_FRAME_DATA_SEI_UNREGISTERED, + unreg->buf_ref[i]); + if (!sd) + av_buffer_unref(&unreg->buf_ref[i]); + unreg->buf_ref[i] = NULL; + } + } + s->sei.unregistered.nb_buf_ref = 0; + + if (s->sei.timecode.present) { + uint32_t *tc_sd; + char tcbuf[AV_TIMECODE_STR_SIZE]; + AVFrameSideData *tcside = av_frame_new_side_data(out, AV_FRAME_DATA_S12M_TIMECODE, + sizeof(uint32_t) * 4); + if (!tcside) + return AVERROR(ENOMEM); + + tc_sd = (uint32_t*)tcside->data; + tc_sd[0] = s->sei.timecode.num_clock_ts; + + for (int i = 0; i < tc_sd[0]; i++) { + int drop = s->sei.timecode.cnt_dropped_flag[i]; + int hh = s->sei.timecode.hours_value[i]; + int mm = s->sei.timecode.minutes_value[i]; + int ss = s->sei.timecode.seconds_value[i]; + int ff = s->sei.timecode.n_frames[i]; + + tc_sd[i + 1] = av_timecode_get_smpte(s->avctx->framerate, drop, hh, mm, ss, ff); + av_timecode_make_smpte_tc_string2(tcbuf, s->avctx->framerate, tc_sd[i + 1], 0, 0); + av_dict_set(&out->metadata, "timecode", tcbuf, 0); + } + + s->sei.timecode.num_clock_ts = 0; + } + + if (s->sei.dynamic_hdr_plus.info) { + AVBufferRef *info_ref = av_buffer_ref(s->sei.dynamic_hdr_plus.info); + if (!info_ref) + return AVERROR(ENOMEM); + + if (!av_frame_new_side_data_from_buf(out, AV_FRAME_DATA_DYNAMIC_HDR_PLUS, info_ref)) { + av_buffer_unref(&info_ref); + return AVERROR(ENOMEM); + } } return 0; @@ -3199,6 +3291,11 @@ static int hevc_decode_extradata(HEVCContext *s, uint8_t *buf, int length, int f } } + /* export stream parameters from SEI */ + ret = export_stream_params_from_sei(s); + if (ret < 0) + return ret; + return 0; } @@ -3206,7 +3303,7 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, AVPacket *avpkt) { int ret; - int new_extradata_size; + buffer_size_t new_extradata_size; uint8_t *new_extradata; HEVCContext *s = avctx->priv_data; @@ -3333,16 +3430,15 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) av_freep(&s->sh.offset); av_freep(&s->sh.size); - for (i = 1; i < s->threads_number; i++) { - HEVCLocalContext *lc = s->HEVClcList[i]; - if (lc) { + if (s->HEVClcList && s->sList) { + for (i = 1; i < s->threads_number; i++) { av_freep(&s->HEVClcList[i]); av_freep(&s->sList[i]); } } - if (s->HEVClc == s->HEVClcList[0]) - s->HEVClc = NULL; - av_freep(&s->HEVClcList[0]); + av_freep(&s->HEVClc); + av_freep(&s->HEVClcList); + av_freep(&s->sList); ff_h2645_packet_uninit(&s->pkt); @@ -3359,7 +3455,9 @@ static av_cold int hevc_init_context(AVCodecContext *avctx) s->avctx = avctx; s->HEVClc = av_mallocz(sizeof(HEVCLocalContext)); - if (!s->HEVClc) + s->HEVClcList = av_mallocz(sizeof(HEVCLocalContext*) * s->threads_number); + s->sList = av_mallocz(sizeof(HEVCContext*) * s->threads_number); + if (!s->HEVClc || !s->HEVClcList || !s->sList) goto fail; s->HEVClcList[0] = s->HEVClc; s->sList[0] = s; @@ -3425,30 +3523,21 @@ static int hevc_update_thread_context(AVCodecContext *dst, if (s->ps.sps != s0->ps.sps) s->ps.sps = NULL; for (i = 0; i < FF_ARRAY_ELEMS(s->ps.vps_list); i++) { - av_buffer_unref(&s->ps.vps_list[i]); - if (s0->ps.vps_list[i]) { - s->ps.vps_list[i] = av_buffer_ref(s0->ps.vps_list[i]); - if (!s->ps.vps_list[i]) - return AVERROR(ENOMEM); - } + ret = av_buffer_replace(&s->ps.vps_list[i], s0->ps.vps_list[i]); + if (ret < 0) + return ret; } for (i = 0; i < FF_ARRAY_ELEMS(s->ps.sps_list); i++) { - av_buffer_unref(&s->ps.sps_list[i]); - if (s0->ps.sps_list[i]) { - s->ps.sps_list[i] = av_buffer_ref(s0->ps.sps_list[i]); - if (!s->ps.sps_list[i]) - return AVERROR(ENOMEM); - } + ret = av_buffer_replace(&s->ps.sps_list[i], s0->ps.sps_list[i]); + if (ret < 0) + return ret; } for (i = 0; i < FF_ARRAY_ELEMS(s->ps.pps_list); i++) { - av_buffer_unref(&s->ps.pps_list[i]); - if (s0->ps.pps_list[i]) { - s->ps.pps_list[i] = av_buffer_ref(s0->ps.pps_list[i]); - if (!s->ps.pps_list[i]) - return AVERROR(ENOMEM); - } + ret = av_buffer_replace(&s->ps.pps_list[i], s0->ps.pps_list[i]); + if (ret < 0) + return ret; } if (s->ps.sps != s0->ps.sps) @@ -3473,19 +3562,43 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->max_ra = INT_MAX; } - av_buffer_unref(&s->sei.a53_caption.buf_ref); - if (s0->sei.a53_caption.buf_ref) { - s->sei.a53_caption.buf_ref = av_buffer_ref(s0->sei.a53_caption.buf_ref); - if (!s->sei.a53_caption.buf_ref) - return AVERROR(ENOMEM); + ret = av_buffer_replace(&s->sei.a53_caption.buf_ref, s0->sei.a53_caption.buf_ref); + if (ret < 0) + return ret; + + for (i = 0; i < s->sei.unregistered.nb_buf_ref; i++) + av_buffer_unref(&s->sei.unregistered.buf_ref[i]); + s->sei.unregistered.nb_buf_ref = 0; + + if (s0->sei.unregistered.nb_buf_ref) { + ret = av_reallocp_array(&s->sei.unregistered.buf_ref, + s0->sei.unregistered.nb_buf_ref, + sizeof(*s->sei.unregistered.buf_ref)); + if (ret < 0) + return ret; + + for (i = 0; i < s0->sei.unregistered.nb_buf_ref; i++) { + s->sei.unregistered.buf_ref[i] = av_buffer_ref(s0->sei.unregistered.buf_ref[i]); + if (!s->sei.unregistered.buf_ref[i]) + return AVERROR(ENOMEM); + s->sei.unregistered.nb_buf_ref++; + } } + ret = av_buffer_replace(&s->sei.dynamic_hdr_plus.info, s0->sei.dynamic_hdr_plus.info); + if (ret < 0) + return ret; + s->sei.frame_packing = s0->sei.frame_packing; s->sei.display_orientation = s0->sei.display_orientation; s->sei.mastering_display = s0->sei.mastering_display; s->sei.content_light = s0->sei.content_light; s->sei.alternative_transfer = s0->sei.alternative_transfer; + ret = export_stream_params_from_sei(s); + if (ret < 0) + return ret; + return 0; } #endif @@ -3495,6 +3608,16 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) HEVCContext *s = avctx->priv_data; int ret; + if(avctx->active_thread_type & FF_THREAD_SLICE) + s->threads_number = avctx->thread_count; + else + s->threads_number = 1; + + if((avctx->active_thread_type & FF_THREAD_FRAME) && avctx->thread_count > 1) + s->threads_type = FF_THREAD_FRAME; + else + s->threads_type = FF_THREAD_SLICE; + ret = hevc_init_context(avctx); if (ret < 0) return ret; @@ -3505,26 +3628,15 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) atomic_init(&s->wpp_err, 0); - if(avctx->active_thread_type & FF_THREAD_SLICE) - s->threads_number = avctx->thread_count; - else - s->threads_number = 1; - if (!avctx->internal->is_copy) { if (avctx->extradata_size > 0 && avctx->extradata) { ret = hevc_decode_extradata(s, avctx->extradata, avctx->extradata_size, 1); if (ret < 0) { - hevc_decode_free(avctx); return ret; } } } - if((avctx->active_thread_type & FF_THREAD_FRAME) && avctx->thread_count > 1) - s->threads_type = FF_THREAD_FRAME; - else - s->threads_type = FF_THREAD_SLICE; - return 0; } @@ -3570,9 +3682,9 @@ AVCodec ff_hevc_decoder = { .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING | - FF_CODEC_CAP_ALLOCATE_PROGRESS, + FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP, .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles), - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_HEVC_DXVA2_HWACCEL HWACCEL_DXVA2(hevc), #endif diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index 39c5c7f89..482638a8e 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -27,6 +27,7 @@ #include "libavutil/buffer.h" #include "libavutil/md5.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "bswapdsp.h" @@ -42,7 +43,6 @@ #include "thread.h" #include "videodsp.h" -#define MAX_NB_THREADS 16 #define SHIFT_CTB_WPP 2 //TODO: check if this is really the maximum @@ -53,6 +53,7 @@ #define DEFAULT_INTRA_TC_OFFSET 2 #define HEVC_CONTEXTS 199 +#define HEVC_STAT_COEFFS 4 #define MRG_MAX_NUM_CANDS 5 @@ -424,7 +425,7 @@ typedef struct HEVCFrame { typedef struct HEVCLocalContext { uint8_t cabac_state[HEVC_CONTEXTS]; - uint8_t stat_coeff[4]; + uint8_t stat_coeff[HEVC_STAT_COEFFS]; uint8_t first_qp_group; @@ -468,9 +469,9 @@ typedef struct HEVCContext { const AVClass *c; // needed by private avoptions AVCodecContext *avctx; - struct HEVCContext *sList[MAX_NB_THREADS]; + struct HEVCContext **sList; - HEVCLocalContext *HEVClcList[MAX_NB_THREADS]; + HEVCLocalContext **HEVClcList; HEVCLocalContext *HEVClc; uint8_t threads_type; @@ -480,6 +481,7 @@ typedef struct HEVCContext { int height; uint8_t *cabac_state; + uint8_t stat_coeff[HEVC_STAT_COEFFS]; /** 1 if the independent slice segment header was successfully parsed */ uint8_t slice_initialized; @@ -594,7 +596,7 @@ int ff_hevc_frame_rps(HEVCContext *s); int ff_hevc_slice_rpl(HEVCContext *s); void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts); -int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts); +int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts, int thread); int ff_hevc_sao_merge_flag_decode(HEVCContext *s); int ff_hevc_sao_type_idx_decode(HEVCContext *s); int ff_hevc_sao_band_position_decode(HEVCContext *s); diff --git a/libavcodec/hevcdsp.c b/libavcodec/hevcdsp.c index 957e40d5f..fe272ac1c 100644 --- a/libavcodec/hevcdsp.c +++ b/libavcodec/hevcdsp.c @@ -257,6 +257,8 @@ int i = 0; break; } + if (ARCH_AARCH64) + ff_hevc_dsp_init_aarch64(hevcdsp, bit_depth); if (ARCH_ARM) ff_hevc_dsp_init_arm(hevcdsp, bit_depth); if (ARCH_PPC) diff --git a/libavcodec/hevcdsp.h b/libavcodec/hevcdsp.h index 0ae67cba8..0e013a832 100644 --- a/libavcodec/hevcdsp.h +++ b/libavcodec/hevcdsp.h @@ -25,6 +25,8 @@ #ifndef AVCODEC_HEVCDSP_H #define AVCODEC_HEVCDSP_H +#include "libavutil/mem_internal.h" + #include "get_bits.h" #define MAX_PB_SIZE 64 @@ -127,6 +129,7 @@ void ff_hevc_dsp_init(HEVCDSPContext *hpc, int bit_depth); extern const int8_t ff_hevc_epel_filters[7][4]; extern const int8_t ff_hevc_qpel_filters[3][16]; +void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth); void ff_hevc_dsp_init_arm(HEVCDSPContext *c, const int bit_depth); void ff_hevc_dsp_init_ppc(HEVCDSPContext *c, const int bit_depth); void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth); diff --git a/libavcodec/hevcpred_template.c b/libavcodec/hevcpred_template.c index f1a1f4c1f..ca75ec112 100644 --- a/libavcodec/hevcpred_template.c +++ b/libavcodec/hevcpred_template.c @@ -214,7 +214,7 @@ do { \ while (j < size_max_x && !IS_INTRA(j, -1)) j++; if (j > 0) - if (x0 > 0) { + if (cand_up_left) { EXTEND_LEFT_CIP(top, j, j + 1); } else { EXTEND_LEFT_CIP(top, j, j); diff --git a/libavcodec/hnm4video.c b/libavcodec/hnm4video.c index 177ce1d47..43baa9c57 100644 --- a/libavcodec/hnm4video.c +++ b/libavcodec/hnm4video.c @@ -387,15 +387,6 @@ static void hnm_update_palette(AVCodecContext *avctx, uint8_t *src, } } -static void hnm_flip_buffers(Hnm4VideoContext *hnm) -{ - uint8_t *temp; - - temp = hnm->current; - hnm->current = hnm->previous; - hnm->previous = temp; -} - static int hnm_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -450,7 +441,7 @@ static int hnm_decode_frame(AVCodecContext *avctx, void *data, frame->key_frame = 0; memcpy(frame->data[1], hnm->palette, 256 * 4); *got_frame = 1; - hnm_flip_buffers(hnm); + FFSWAP(uint8_t *, hnm->current, hnm->previous); } else { av_log(avctx, AV_LOG_ERROR, "invalid chunk id: %d\n", chunk_id); return AVERROR_INVALIDDATA; @@ -473,6 +464,8 @@ static av_cold int hnm_decode_init(AVCodecContext *avctx) ret = av_image_check_size(avctx->width, avctx->height, 0, avctx); if (ret < 0) return ret; + if (avctx->height & 1) + return AVERROR(EINVAL); hnm->version = avctx->extradata[0]; avctx->pix_fmt = AV_PIX_FMT_PAL8; @@ -482,13 +475,8 @@ static av_cold int hnm_decode_init(AVCodecContext *avctx) hnm->buffer2 = av_mallocz(avctx->width * avctx->height); hnm->processed = av_mallocz(avctx->width * avctx->height); - if ( !hnm->buffer1 || !hnm->buffer2 || !hnm->processed - || avctx->width * avctx->height == 0 - || avctx->height % 2) { + if (!hnm->buffer1 || !hnm->buffer2 || !hnm->processed) { av_log(avctx, AV_LOG_ERROR, "av_mallocz() failed\n"); - av_freep(&hnm->buffer1); - av_freep(&hnm->buffer2); - av_freep(&hnm->processed); return AVERROR(ENOMEM); } @@ -519,4 +507,5 @@ AVCodec ff_hnm4_video_decoder = { .close = hnm_decode_end, .decode = hnm_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/hq_hqa.h b/libavcodec/hq_hqa.h index 608e2ca1a..08d79e745 100644 --- a/libavcodec/hq_hqa.h +++ b/libavcodec/hq_hqa.h @@ -23,6 +23,8 @@ #include +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "bytestream.h" #include "hq_hqadsp.h" diff --git a/libavcodec/hq_hqadata.c b/libavcodec/hq_hqadata.c index ae9231aa0..56470eadc 100644 --- a/libavcodec/hq_hqadata.c +++ b/libavcodec/hq_hqadata.c @@ -1142,7 +1142,7 @@ const int32_t *const ff_hq_quants[NUM_HQ_QUANTS][2][4] = { { { qmat3A, qmat48, qmat4C, qmat4C }, { qmat3B, qmat49, qmat4D, qmat4D } }, }; -const uint8_t ff_hq_ac_bits[NUM_HQ_AC_ENTRIES] = { +static const uint8_t hq_ac_bits[NUM_HQ_AC_ENTRIES] = { 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 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, @@ -1192,7 +1192,7 @@ const uint8_t ff_hq_ac_bits[NUM_HQ_AC_ENTRIES] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, }; -const uint16_t ff_hq_ac_codes[NUM_HQ_AC_ENTRIES] = { +static const uint16_t hq_ac_codes[NUM_HQ_AC_ENTRIES] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0006, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, @@ -8373,5 +8373,5 @@ av_cold int ff_hq_init_vlcs(HQContext *c) return ret; return init_vlc(&c->hq_ac_vlc, 9, NUM_HQ_AC_ENTRIES, - ff_hq_ac_bits, 1, 1, ff_hq_ac_codes, 2, 2, 0); + hq_ac_bits, 1, 1, hq_ac_codes, 2, 2, 0); } diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c index e2b895ac4..aa4ff22a8 100644 --- a/libavcodec/hqx.c +++ b/libavcodec/hqx.c @@ -122,8 +122,6 @@ static int decode_block(GetBitContext *gb, VLC *vlc, memset(block, 0, 64 * sizeof(*block)); dc = get_vlc2(gb, vlc->table, HQX_DC_VLC_BITS, 2); - if (dc < 0) - return AVERROR_INVALIDDATA; *last_dc += dc; block[0] = sign_extend(*last_dc << (12 - dcb), 12); @@ -197,7 +195,7 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y) int i, ret; int cbp; - cbp = get_vlc2(gb, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1); + cbp = get_vlc2(gb, ctx->cbp_vlc.table, HQX_CBP_VLC_BITS, 1); for (i = 0; i < 12; i++) memset(slice->block[i], 0, sizeof(**slice->block) * 64); @@ -283,7 +281,7 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y) int i, ret; int cbp; - cbp = get_vlc2(gb, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1); + cbp = get_vlc2(gb, ctx->cbp_vlc.table, HQX_CBP_VLC_BITS, 1); for (i = 0; i < 16; i++) memset(slice->block[i], 0, sizeof(**slice->block) * 64); diff --git a/libavcodec/hqx.h b/libavcodec/hqx.h index 42d382de1..3eddaafb2 100644 --- a/libavcodec/hqx.h +++ b/libavcodec/hqx.h @@ -24,7 +24,8 @@ #include #include "libavutil/frame.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" + #include "get_bits.h" #include "hqxdsp.h" @@ -77,6 +78,7 @@ typedef struct HQXContext { VLC dc_vlc[3]; } HQXContext; +#define HQX_CBP_VLC_BITS 5 #define HQX_DC_VLC_BITS 9 extern const HQXAC ff_hqx_ac[NUM_HQX_AC]; diff --git a/libavcodec/hqxvlc.c b/libavcodec/hqxvlc.c index 06a807366..7ab242766 100644 --- a/libavcodec/hqxvlc.c +++ b/libavcodec/hqxvlc.c @@ -2150,7 +2150,7 @@ const HQXAC ff_hqx_ac[NUM_HQX_AC] = { av_cold int ff_hqx_init_vlcs(HQXContext *ctx) { - int ret = init_vlc(&ctx->cbp_vlc, 5, FF_ARRAY_ELEMS(cbp_vlc_lens), + int ret = init_vlc(&ctx->cbp_vlc, HQX_CBP_VLC_BITS, FF_ARRAY_ELEMS(cbp_vlc_lens), cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0); if (ret < 0) return ret; diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h index 6109c89bd..8e54cf73f 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -21,6 +21,11 @@ #include "avcodec.h" +extern const AVHWAccel ff_av1_d3d11va_hwaccel; +extern const AVHWAccel ff_av1_d3d11va2_hwaccel; +extern const AVHWAccel ff_av1_dxva2_hwaccel; +extern const AVHWAccel ff_av1_nvdec_hwaccel; +extern const AVHWAccel ff_av1_vaapi_hwaccel; extern const AVHWAccel ff_h263_vaapi_hwaccel; extern const AVHWAccel ff_h263_videotoolbox_hwaccel; extern const AVHWAccel ff_h264_d3d11va_hwaccel; diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c index 6b2d8087a..569191511 100644 --- a/libavcodec/idcinvideo.c +++ b/libavcodec/idcinvideo.c @@ -214,7 +214,7 @@ static int idcin_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; IdcinContext *s = avctx->priv_data; - int pal_size; + buffer_size_t pal_size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &pal_size); AVFrame *frame = data; int ret; @@ -258,4 +258,5 @@ AVCodec ff_idcin_decoder = { .decode = idcin_decode_frame, .capabilities = AV_CODEC_CAP_DR1, .defaults = idcin_defaults, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/iirfilter.c b/libavcodec/iirfilter.c index b20251582..cd5bbc943 100644 --- a/libavcodec/iirfilter.c +++ b/libavcodec/iirfilter.c @@ -171,12 +171,10 @@ av_cold struct FFIIRFilterCoeffs *ff_iir_filter_init_coeffs(void *avc, if (order <= 0 || order > MAXORDER || cutoff_ratio >= 1.0) return NULL; - FF_ALLOCZ_OR_GOTO(avc, c, sizeof(FFIIRFilterCoeffs), - init_fail); - FF_ALLOC_OR_GOTO(avc, c->cx, sizeof(c->cx[0]) * ((order >> 1) + 1), - init_fail); - FF_ALLOC_OR_GOTO(avc, c->cy, sizeof(c->cy[0]) * order, - init_fail); + if (!(c = av_mallocz(sizeof(*c))) || + !(c->cx = av_malloc (sizeof(c->cx[0]) * ((order >> 1) + 1))) || + !(c->cy = av_malloc (sizeof(c->cy[0]) * order))) + goto free; c->order = order; switch (filt_type) { @@ -190,13 +188,12 @@ av_cold struct FFIIRFilterCoeffs *ff_iir_filter_init_coeffs(void *avc, break; default: av_log(avc, AV_LOG_ERROR, "filter type is not currently implemented\n"); - goto init_fail; + goto free; } if (!ret) return c; - -init_fail: +free: ff_iir_filter_free_coeffsp(&c); return NULL; } diff --git a/libavcodec/ilbcdata.h b/libavcodec/ilbcdata.h index 8d145bc18..b17e24df5 100644 --- a/libavcodec/ilbcdata.h +++ b/libavcodec/ilbcdata.h @@ -60,10 +60,6 @@ static const int16_t kLpcChirpSyntDenum[] = { 32767, 29573, 26690, 24087, 21739, 19619, 17707, 15980, 14422, 13016, 11747 }; -static const int16_t LpcChirpWeightDenum[] = { - 32767, 13835, 5841, 2466, 1041, 440, 186, 78, 33, 14, 6 -}; - static const int16_t cos_tbl[64] = { 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, diff --git a/libavcodec/ilbcdec.c b/libavcodec/ilbcdec.c index a82a27525..33f4e2c1e 100644 --- a/libavcodec/ilbcdec.c +++ b/libavcodec/ilbcdec.c @@ -1484,6 +1484,6 @@ AVCodec ff_ilbc_decoder = { .id = AV_CODEC_ID_ILBC, .init = ilbc_decode_init, .decode = ilbc_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .priv_data_size = sizeof(ILBCContext), }; diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 82a908160..51e7c1b2e 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -38,6 +38,9 @@ #include "libavutil/ffmath.h" #include "libavutil/float_dsp.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" + #include "avcodec.h" #include "bswapdsp.h" #include "get_bits.h" @@ -95,7 +98,7 @@ typedef struct IMCContext { GetBitContext gb; BswapDSPContext bdsp; - AVFloatDSPContext *fdsp; + void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len); FFTContext fft; DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2]; float *out_samples; @@ -110,13 +113,9 @@ typedef struct IMCContext { static VLC huffman_vlc[4][4]; +#define IMC_VLC_BITS 9 #define VLC_TABLES_SIZE 9512 -static const int vlc_offsets[17] = { - 0, 640, 1156, 1732, 2308, 2852, 3396, 3924, - 4452, 5220, 5860, 6628, 7268, 7908, 8424, 8936, VLC_TABLES_SIZE -}; - static VLC_TYPE vlc_tables[VLC_TABLES_SIZE][2]; static inline double freq2bark(double freq) @@ -175,10 +174,28 @@ static av_cold void iac_generate_tabs(IMCContext *q, int sampling_rate) } } +static av_cold void imc_init_static(void) +{ + /* initialize the VLC tables */ + for (int i = 0, offset = 0; i < 4 ; i++) { + for (int j = 0; j < 4; j++) { + huffman_vlc[i][j].table = &vlc_tables[offset]; + huffman_vlc[i][j].table_allocated = VLC_TABLES_SIZE - offset; + ff_init_vlc_from_lengths(&huffman_vlc[i][j], IMC_VLC_BITS, imc_huffman_sizes[i], + imc_huffman_lens[i][j], 1, + imc_huffman_syms[i][j], 1, 1, + 0, INIT_VLC_STATIC_OVERLONG, NULL); + offset += huffman_vlc[i][j].table_size; + } + } +} + static av_cold int imc_decode_init(AVCodecContext *avctx) { int i, j, ret; IMCContext *q = avctx->priv_data; + static AVOnce init_static_once = AV_ONCE_INIT; + AVFloatDSPContext *fdsp; double r1, r2; if (avctx->codec_id == AV_CODEC_ID_IAC && avctx->sample_rate > 96000) { @@ -232,17 +249,6 @@ static av_cold int imc_decode_init(AVCodecContext *avctx) for (i = 0; i < 30; i++) q->sqrt_tab[i] = sqrt(i); - /* initialize the VLC tables */ - for (i = 0; i < 4 ; i++) { - for (j = 0; j < 4; j++) { - huffman_vlc[i][j].table = &vlc_tables[vlc_offsets[i * 4 + j]]; - huffman_vlc[i][j].table_allocated = vlc_offsets[i * 4 + j + 1] - vlc_offsets[i * 4 + j]; - init_vlc(&huffman_vlc[i][j], 9, imc_huffman_sizes[i], - imc_huffman_lens[i][j], 1, 1, - imc_huffman_bits[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC); - } - } - if (avctx->codec_id == AV_CODEC_ID_IAC) { iac_generate_tabs(q, avctx->sample_rate); } else { @@ -252,22 +258,23 @@ static av_cold int imc_decode_init(AVCodecContext *avctx) memcpy(q->weights2, imc_weights2, sizeof(imc_weights2)); } + fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!fdsp) + return AVERROR(ENOMEM); + q->butterflies_float = fdsp->butterflies_float; + av_free(fdsp); if ((ret = ff_fft_init(&q->fft, 7, 1))) { av_log(avctx, AV_LOG_INFO, "FFT init failed\n"); return ret; } ff_bswapdsp_init(&q->bdsp); - q->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); - if (!q->fdsp) { - ff_fft_end(&q->fft); - - return AVERROR(ENOMEM); - } avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; + ff_thread_once(&init_static_once, imc_init_static); + return 0; } @@ -348,7 +355,7 @@ static void imc_read_level_coeffs(IMCContext *q, int stream_format_code, levlCoeffs[0] = get_bits(&q->gb, 7); for (i = start; i < BANDS; i++) { levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table, - hufftab[cb_sel[i]]->bits, 2); + IMC_VLC_BITS, 2); if (levlCoeffs[i] == 17) levlCoeffs[i] += get_bits(&q->gb, 4); } @@ -1050,8 +1057,8 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, } if (avctx->channels == 2) { - q->fdsp->butterflies_float((float *)frame->extended_data[0], - (float *)frame->extended_data[1], COEFFS); + q->butterflies_float((float *)frame->extended_data[0], + (float *)frame->extended_data[1], COEFFS); } *got_frame_ptr = 1; @@ -1064,7 +1071,6 @@ static av_cold int imc_decode_close(AVCodecContext * avctx) IMCContext *q = avctx->priv_data; ff_fft_end(&q->fft); - av_freep(&q->fdsp); return 0; } @@ -1088,9 +1094,10 @@ AVCodec ff_imc_decoder = { .close = imc_decode_close, .decode = imc_decode_frame, .flush = flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_IAC_DECODER @@ -1107,5 +1114,6 @@ AVCodec ff_iac_decoder = { .capabilities = AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif diff --git a/libavcodec/imcdata.h b/libavcodec/imcdata.h index 64e7c7185..46037bd55 100644 --- a/libavcodec/imcdata.h +++ b/libavcodec/imcdata.h @@ -114,55 +114,55 @@ static const uint8_t imc_huffman_sizes[4] = { static const uint8_t imc_huffman_lens[4][4][18] = { { - { 16, 15, 13, 11, 8, 5, 3, 1, 2, 4, 6, 9, 10, 12, 14, 16, 7, 0 }, - { 10, 8, 7, 6, 4, 4, 3, 2, 2, 3, 4, 6, 7, 9, 11, 11, 7, 0 }, - { 15, 15, 14, 11, 8, 6, 4, 2, 1, 4, 5, 7, 9, 10, 12, 13, 4, 0 }, - { 13, 11, 10, 8, 6, 4, 2, 2, 2, 3, 5, 7, 9, 12, 15, 15, 14, 0 }, + { 1, 2, 5, 6, 11, 12, 15, 16, 16, 14, 13, 10, 9, 8, 7, 4, 3 }, + { 2, 3, 3, 4, 4, 4, 6, 6, 7, 7, 7, 8, 9, 10, 11, 11, 2 }, + { 1, 4, 4, 7, 9, 10, 12, 15, 15, 14, 13, 11, 8, 6, 5, 4, 2 }, + { 2, 2, 4, 8, 9, 14, 15, 15, 13, 12, 11, 10, 7, 6, 5, 3, 2 }, }, { - { 14, 12, 10, 8, 7, 4, 2, 2, 2, 3, 5, 7, 9, 11, 13, 14, 7, 0 }, - { 14, 13, 11, 8, 6, 4, 3, 2, 2, 3, 5, 7, 9, 10, 12, 14, 3, 0 }, - { 13, 12, 10, 7, 5, 4, 3, 2, 2, 3, 4, 6, 8, 9, 11, 13, 4, 0 }, - { 13, 12, 10, 7, 5, 4, 3, 2, 2, 3, 4, 6, 8, 9, 11, 13, 4, 0 }, + { 2, 2, 3, 4, 7, 7, 10, 11, 12, 14, 14, 13, 9, 8, 7, 5, 2 }, + { 2, 3, 14, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2 }, + { 2, 3, 3, 4, 4, 5, 7, 9, 11, 12, 13, 13, 10, 8, 6, 4, 2 }, + { 2, 3, 3, 4, 4, 5, 7, 9, 11, 12, 13, 13, 10, 8, 6, 4, 2 }, }, { - { 16, 14, 12, 10, 8, 5, 3, 1, 2, 4, 7, 9, 11, 13, 15, 17, 6, 17 }, - { 15, 13, 11, 8, 6, 4, 2, 2, 2, 3, 5, 7, 10, 12, 14, 16, 9, 16 }, - { 14, 12, 11, 9, 8, 6, 3, 1, 2, 5, 7, 10, 13, 15, 16, 17, 4, 17 }, - { 16, 14, 12, 9, 7, 5, 2, 2, 2, 3, 4, 6, 8, 11, 13, 15, 10, 16 }, + { 3, 5, 8, 9, 12, 15, 17, 17, 16, 14, 13, 11, 10, 7, 6, 4, 2, 1 }, + { 4, 7, 8, 10, 11, 12, 15, 16, 16, 14, 13, 9, 6, 5, 3, 2, 2, 2 }, + { 4, 5, 6, 7, 12, 13, 17, 17, 16, 15, 14, 11, 10, 9, 8, 3, 2, 1 }, + { 2, 5, 7, 8, 14, 15, 16, 16, 13, 12, 11, 10, 9, 6, 4, 3, 2, 2 }, }, { - { 13, 11, 10, 8, 7, 5, 2, 2, 2, 4, 6, 9, 12, 14, 15, 16, 3, 16 }, - { 11, 11, 10, 9, 8, 7, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 5 }, - { 9, 9, 7, 6, 5, 4, 3, 3, 2, 3, 4, 5, 4, 5, 5, 6, 8, 6 }, - { 13, 12, 10, 8, 5, 3, 3, 2, 2, 3, 4, 7, 9, 11, 14, 15, 6, 15 }, + { 2, 4, 7, 9, 10, 12, 13, 15, 16, 16, 14, 11, 8, 6, 5, 3, 2, 2 }, + { 3, 5, 5, 7, 10, 11, 11, 9, 8, 6, 5, 4, 4, 3, 3, 3, 3, 3 }, + { 5, 8, 9, 9, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2 }, + { 2, 3, 5, 7, 8, 11, 12, 13, 15, 15, 14, 10, 9, 6, 4, 3, 3, 2 }, } }; -static const uint16_t imc_huffman_bits[4][4][18] = { +static const uint8_t imc_huffman_syms[4][4][18] = { { - { 0xCC32, 0x6618, 0x1987, 0x0660, 0x00CD, 0x0018, 0x0007, 0x0000, 0x0002, 0x000D, 0x0032, 0x0199, 0x0331, 0x0CC2, 0x330D, 0xCC33, 0x0067, 0x0000 }, - { 0x02FE, 0x00BE, 0x005E, 0x002D, 0x000A, 0x0009, 0x0003, 0x0003, 0x0000, 0x0002, 0x0008, 0x002C, 0x005D, 0x017E, 0x05FE, 0x05FF, 0x005C, 0x0000 }, - { 0x5169, 0x5168, 0x28B5, 0x0517, 0x00A3, 0x0029, 0x0008, 0x0003, 0x0000, 0x0009, 0x0015, 0x0050, 0x0144, 0x028A, 0x0A2C, 0x145B, 0x000B, 0x0000 }, - { 0x1231, 0x048D, 0x0247, 0x0090, 0x0025, 0x0008, 0x0001, 0x0003, 0x0000, 0x0005, 0x0013, 0x0049, 0x0122, 0x0919, 0x48C3, 0x48C2, 0x2460, 0x0000 }, + { 7, 8, 5, 10, 3, 13, 1, 0, 15, 14, 2, 12, 11, 4, 16, 9, 6 }, + { 8, 9, 6, 10, 5, 4, 11, 3, 16, 12, 2, 1, 13, 0, 14, 15, 7 }, + { 8, 6, 9, 11, 12, 13, 14, 1, 0, 2, 15, 3, 4, 5, 10, 16, 7 }, + { 8, 6, 5, 3, 12, 16, 15, 14, 0, 13, 1, 2, 11, 4, 10, 9, 7 }, }, { - { 0x2D1D, 0x0B46, 0x02D0, 0x00B5, 0x0059, 0x000A, 0x0003, 0x0001, 0x0000, 0x0004, 0x0017, 0x005B, 0x0169, 0x05A2, 0x168F, 0x2D1C, 0x0058, 0x0000 }, - { 0x1800, 0x0C01, 0x0301, 0x0061, 0x0019, 0x0007, 0x0004, 0x0003, 0x0000, 0x0005, 0x000D, 0x0031, 0x00C1, 0x0181, 0x0601, 0x1801, 0x0002, 0x0000 }, - { 0x1556, 0x0AAA, 0x02AB, 0x0054, 0x0014, 0x000B, 0x0002, 0x0003, 0x0000, 0x0003, 0x0008, 0x002B, 0x00AB, 0x0154, 0x0554, 0x1557, 0x0009, 0x0000 }, - { 0x1556, 0x0AAA, 0x02AB, 0x0054, 0x0014, 0x000B, 0x0002, 0x0003, 0x0000, 0x0003, 0x0008, 0x002B, 0x00AB, 0x0154, 0x0554, 0x1557, 0x0009, 0x0000 }, + { 8, 7, 9, 5, 16, 4, 2, 13, 1, 15, 0, 14, 12, 3, 11, 10, 6 }, + { 8, 16, 0, 15, 1, 14, 2, 13, 12, 3, 11, 4, 10, 5, 6, 9, 7 }, + { 8, 6, 9, 10, 16, 4, 3, 13, 14, 1, 0, 15, 2, 12, 11, 5, 7 }, + { 8, 6, 9, 10, 16, 4, 3, 13, 14, 1, 0, 15, 2, 12, 11, 5, 7 }, }, { - { 0x2993, 0x0A65, 0x0298, 0x00A7, 0x0028, 0x0004, 0x0000, 0x0001, 0x0001, 0x0003, 0x0015, 0x0052, 0x014D, 0x0533, 0x14C8, 0x5324, 0x000B, 0x5325 }, - { 0x09B8, 0x026F, 0x009A, 0x0012, 0x0005, 0x0000, 0x0001, 0x0002, 0x0003, 0x0001, 0x0003, 0x0008, 0x004C, 0x0136, 0x04DD, 0x1373, 0x0027, 0x1372 }, - { 0x0787, 0x01E0, 0x00F1, 0x003D, 0x001F, 0x0006, 0x0001, 0x0001, 0x0001, 0x0002, 0x000E, 0x0079, 0x03C2, 0x0F0D, 0x1E19, 0x3C30, 0x0000, 0x3C31 }, - { 0x4B06, 0x12C0, 0x04B1, 0x0097, 0x0024, 0x0008, 0x0002, 0x0003, 0x0000, 0x0003, 0x0005, 0x0013, 0x004A, 0x0259, 0x0961, 0x2582, 0x012D, 0x4B07 }, + { 6, 5, 4, 11, 2, 14, 15, 17, 0, 1, 13, 12, 3, 10, 16, 9, 8, 7 }, + { 5, 11, 3, 12, 2, 13, 0, 17, 15, 14, 1, 16, 4, 10, 9, 6, 7, 8 }, + { 16, 9, 5, 10, 1, 12, 15, 17, 14, 13, 0, 2, 11, 3, 4, 6, 8, 7 }, + { 8, 5, 4, 12, 1, 15, 0, 17, 14, 2, 13, 16, 3, 11, 10, 9, 6, 7 }, }, { - { 0x0A5A, 0x0297, 0x014A, 0x0053, 0x0028, 0x000B, 0x0003, 0x0000, 0x0002, 0x0004, 0x0015, 0x00A4, 0x052C, 0x14B7, 0x296C, 0x52DB, 0x0003, 0x52DA }, - { 0x0193, 0x0192, 0x00C8, 0x0065, 0x0033, 0x0018, 0x0007, 0x0004, 0x0000, 0x0004, 0x0005, 0x0007, 0x0006, 0x0003, 0x0005, 0x0005, 0x000D, 0x0004 }, - { 0x0012, 0x0013, 0x0005, 0x0003, 0x0000, 0x0003, 0x0005, 0x0004, 0x0003, 0x0003, 0x0005, 0x0005, 0x0004, 0x0004, 0x0003, 0x0005, 0x0008, 0x0004 }, - { 0x0D66, 0x06B2, 0x01AD, 0x006A, 0x000C, 0x0005, 0x0004, 0x0000, 0x0003, 0x0002, 0x0007, 0x0034, 0x00D7, 0x0358, 0x1ACF, 0x359C, 0x001B, 0x359D }, + { 7, 9, 4, 11, 2, 12, 0, 14, 17, 15, 13, 1, 3, 10, 5, 16, 8, 6 }, + { 8, 17, 15, 5, 2, 1, 0, 3, 4, 16, 6, 7, 14, 13, 9, 10, 12, 11 }, + { 4, 16, 0, 1, 2, 3, 17, 15, 14, 13, 11, 5, 12, 10, 9, 7, 6, 8 }, + { 7, 9, 4, 11, 3, 13, 1, 0, 15, 17, 14, 2, 12, 16, 10, 6, 5, 8 }, } }; diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c index 1fd636c83..8de156340 100644 --- a/libavcodec/imgconvert.c +++ b/libavcodec/imgconvert.c @@ -44,6 +44,7 @@ void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int } #endif +#if FF_API_AVCODEC_PIX_FMT int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, int has_alpha) @@ -60,9 +61,10 @@ enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) { - return avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr); + return av_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr); } +#endif 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){ @@ -73,7 +75,7 @@ enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *p for (i=0; pix_fmt_list[i] != AV_PIX_FMT_NONE; i++) { loss = loss_ptr ? *loss_ptr : 0; - best = avcodec_find_best_pix_fmt_of_2(best, pix_fmt_list[i], src_pix_fmt, has_alpha, &loss); + best = av_find_best_pix_fmt_of_2(best, pix_fmt_list[i], src_pix_fmt, has_alpha, &loss); } if (loss_ptr) diff --git a/libavcodec/imm4.c b/libavcodec/imm4.c index d92bc30dd..636130dd5 100644 --- a/libavcodec/imm4.c +++ b/libavcodec/imm4.c @@ -24,6 +24,7 @@ #include #include +#include "libavutil/mem_internal.h" #include "libavutil/thread.h" #include "avcodec.h" @@ -33,6 +34,11 @@ #include "idctdsp.h" #include "internal.h" +#define CBPLO_VLC_BITS 6 +#define CBPHI_VLC_BITS 6 +#define BLKTYPE_VLC_BITS 9 +#define BLOCK_VLC_BITS 12 + typedef struct IMM4Context { BswapDSPContext bdsp; GetBitContext gb; @@ -58,16 +64,9 @@ static const uint8_t inter_cb[] = { 30, 20, 15 }; -static const uint8_t cbplo_symbols[] = { - 3, 4, 19, 20, 35, 36, 51, 52 -}; - -static const uint8_t cbplo_bits[] = { - 1, 4, 3, 6, 3, 6, 3, 6 -}; - -static const uint8_t cbplo_codes[] = { - 1, 1, 1, 1, 2, 2, 3, 3 +static const uint8_t cbplo[][2] = { + { 0,-6 }, { 0x01, 6 }, { 0x02, 6 }, { 0x03, 6 }, { 0x00, 4 }, + { 0x01, 3 }, { 0x02, 3 }, { 0x03, 3 }, { 0x00, 1 }, }; static const uint8_t cbphi_bits[] = { @@ -78,47 +77,36 @@ static const uint8_t cbphi_codes[] = { 3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3 }; -static const uint8_t blktype_symbols[] = { - 0, 1, 2, 3, 4, 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 50, 51, 52 -}; - -static const uint8_t blktype_bits[] = { - 1, 3, 3, 5, 6, 4, 7, 7, 8, 9, 4, 7, 7, 8, 6, 8, 7, 9 -}; - -static const uint8_t blktype_codes[] = { - 1, 3, 2, 3, 4, 3, 7, 5, 4, 4, 2, 6, 4, 3, 5, 5, 3, 2 +static const uint8_t blktype[][2] = { + { 0,-8 }, { 0x34, 9 }, { 0,-9 }, { 0x14, 9 }, { 0,-9 }, + { 0x23, 8 }, { 0x13, 8 }, { 0x32, 8 }, { 0x33, 7 }, { 0x22, 7 }, + { 0x12, 7 }, { 0x21, 7 }, { 0x11, 7 }, { 0x04, 6 }, { 0x30, 6 }, + { 0x03, 5 }, { 0x20, 4 }, { 0x10, 4 }, { 0x02, 3 }, { 0x01, 3 }, + { 0x00, 1 }, }; static const uint16_t block_symbols[] = { - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x101, 0x102, 0x103, 0x104, 0x181, 0x182, 0x183, 0x201, 0x202, - 0x203, 0x281, 0x282, 0x283, 0x301, 0x302, 0x303, 0x381, 0x382, 0x401, 0x402, - 0x481, 0x482, 0x501, 0x502, 0x581, 0x601, 0x681, 0x701, 0x781, 0x801, 0x881, - 0x901, 0x981, 0xA01, 0xA81, 0xB01, 0xB81, 0xC01, 0xC81, 0xD01, 0x4001, 0x4002, - 0x4003, 0x4081, 0x4082, 0x4101, 0x4181, 0x4201, 0x4281, 0x4301, 0x4381, 0x4401, - 0x4481, 0x4501, 0x4581, 0x4601, 0x4681, 0x4701, 0x4781, 0x4801, 0x4881, 0x4901, - 0x4981, 0x4A01, 0x4A81, 0x4B01, 0x4B81, 0x4C01, 0x4C81, 0x4D01, 0x4D81, 0x4E01, - 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x5081, 0x5101, 0x5181, 0x5201, 0x5281, 0x5301, - 0x5381, 0x5401 + 0, 0x4082, 0x4003, 0x000B, 0x000A, 0x4E01, 0x4D81, 0x4D01, 0x4C81, + 0x0482, 0x0402, 0x0382, 0x0302, 0x0282, 0x0183, 0x0103, 0x0084, 0x000C, + 0x0085, 0x0B81, 0x0C01, 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x0086, 0x0104, + 0x0203, 0x0283, 0x0303, 0x0502, 0x0C81, 0x0D01, 0x5081, 0x5101, 0x5181, + 0x5201, 0x5281, 0x5301, 0x5381, 0x5401, 0x0000, 0x0009, 0x0008, 0x4C01, + 0x4B81, 0x4B01, 0x4A81, 0x4A01, 0x4981, 0x4901, 0x4881, 0x4002, 0x0B01, + 0x0A81, 0x0A01, 0x0981, 0x0901, 0x0881, 0x0801, 0x0781, 0x0202, 0x0182, + 0x0007, 0x0006, 0x4801, 0x4781, 0x4701, 0x4681, 0x4601, 0x4581, 0x4501, + 0x4481, 0x0701, 0x0681, 0x0102, 0x0083, 0x0005, 0x4401, 0x4381, 0x4301, + 0x4281, 0x0601, 0x0581, 0x0501, 0x0004, 0x4201, 0x4181, 0x4101, 0x4081, + 0x0481, 0x0401, 0x0381, 0x0301, 0x0082, 0x0003, 0x0281, 0x0201, 0x0181, + 0x4001, 0x0001, 0x0081, 0x0101, 0x0002, }; static const uint8_t block_bits[] = { - 7, 2, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 3, 6, 8, 10, 11, 12, 4, 8, - 10, 12, 5, 9, 10, 5, 9, 12, 5, 10, 12, 6, 10, 12, 6, 10, 6, 10, 6, - 10, 7, 12, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 12, 12, 4, 9, - 11, 6, 11, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, - 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, - 12, 12 -}; - -static const uint8_t block_codes[] = { - 3, 2, 15, 21, 23, 31, 37, 36, 33, 32, 7, 6, 32, 6, 20, 30, 15, 33, 80, - 14, 29, 14, 81, 13, 35, 13, 12, 34, 82, 11, 12, 83, 19, 11, 84, 18, - 10, 17, 9, 16, 8, 22, 85, 21, 20, 28, 27, 33, 32, 31, 30, 29, 28, - 27, 26, 34, 35, 86, 87, 7, 25, 5, 15, 4, 14, 13, 12, 19, 18, 17, 16, - 26, 25, 24, 23, 22, 21, 20, 19, 24, 23, 22, 21, 20, 19, 18, 17, 7, - 6, 5, 4, 36, 37, 38, 39, 88, 89, 90, 91, 92, 93, 94, 95 + -9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 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, 7, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 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, 6, 6, 6, 6, 6, + 6, 5, 5, 5, 4, 2, 3, 4, 4, }; static VLC cbplo_tab; @@ -130,7 +118,7 @@ static int get_cbphi(GetBitContext *gb, int x) { int value; - value = get_vlc2(gb, cbphi_tab.table, cbphi_tab.bits, 1); + value = get_vlc2(gb, cbphi_tab.table, CBPHI_VLC_BITS, 1); if (value < 0) return AVERROR_INVALIDDATA; @@ -147,7 +135,7 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb, for (i = !flag; i < 64; i++) { int value; - value = get_vlc2(gb, block_tab.table, block_tab.bits, 1); + value = get_vlc2(gb, block_tab.table, BLOCK_VLC_BITS, 1); if (value < 0) return AVERROR_INVALIDDATA; if (value == 0) { @@ -234,7 +222,7 @@ static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame for (x = 0; x < avctx->width; x += 16) { unsigned flag, cbphi, cbplo; - cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4; + cbplo = get_vlc2(gb, cbplo_tab.table, CBPLO_VLC_BITS, 1); flag = get_bits1(gb); cbphi = get_cbphi(gb, 1); @@ -300,7 +288,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, continue; } - value = get_vlc2(gb, blktype_tab.table, blktype_tab.bits, 1); + value = get_vlc2(gb, blktype_tab.table, BLKTYPE_VLC_BITS, 1); if (value < 0) return AVERROR_INVALIDDATA; @@ -488,17 +476,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, static av_cold void imm4_init_static_data(void) { - INIT_VLC_SPARSE_STATIC(&cbplo_tab, 9, FF_ARRAY_ELEMS(cbplo_bits), - cbplo_bits, 1, 1, cbplo_codes, 1, 1, cbplo_symbols, 1, 1, 512); + INIT_VLC_STATIC_FROM_LENGTHS(&cbplo_tab, CBPLO_VLC_BITS, FF_ARRAY_ELEMS(cbplo), + &cbplo[0][1], 2, &cbplo[0][0], 2, 1, + 0, 0, 1 << CBPLO_VLC_BITS); - INIT_VLC_SPARSE_STATIC(&cbphi_tab, 6, FF_ARRAY_ELEMS(cbphi_bits), + INIT_VLC_SPARSE_STATIC(&cbphi_tab, CBPHI_VLC_BITS, FF_ARRAY_ELEMS(cbphi_bits), cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64); - INIT_VLC_SPARSE_STATIC(&blktype_tab, 9, FF_ARRAY_ELEMS(blktype_bits), - blktype_bits, 1, 1, blktype_codes, 1, 1, blktype_symbols, 1, 1, 512); + INIT_VLC_STATIC_FROM_LENGTHS(&blktype_tab, BLKTYPE_VLC_BITS, FF_ARRAY_ELEMS(blktype), + &blktype[0][1], 2, &blktype[0][0], 2, 1, + 0, 0, 1 << BLKTYPE_VLC_BITS); - INIT_VLC_SPARSE_STATIC(&block_tab, 12, FF_ARRAY_ELEMS(block_bits), - block_bits, 1, 1, block_codes, 1, 1, block_symbols, 2, 2, 4096); + INIT_VLC_STATIC_FROM_LENGTHS(&block_tab, BLOCK_VLC_BITS, FF_ARRAY_ELEMS(block_bits), + block_bits, 1, block_symbols, 2, 2, + 0, 0, 1 << BLOCK_VLC_BITS); } static av_cold int decode_init(AVCodecContext *avctx) diff --git a/libavcodec/imm5.c b/libavcodec/imm5.c index 917b414e6..5f8faa4dd 100644 --- a/libavcodec/imm5.c +++ b/libavcodec/imm5.c @@ -63,7 +63,7 @@ static av_cold int imm5_init(AVCodecContext *avctx) ctx->h264_avctx->thread_count = 1; ctx->h264_avctx->flags = avctx->flags; ctx->h264_avctx->flags2 = avctx->flags2; - ret = ff_codec_open2_recursive(ctx->h264_avctx, codec, NULL); + ret = avcodec_open2(ctx->h264_avctx, codec, NULL); if (ret < 0) return ret; @@ -76,7 +76,7 @@ static av_cold int imm5_init(AVCodecContext *avctx) ctx->hevc_avctx->thread_count = 1; ctx->hevc_avctx->flags = avctx->flags; ctx->hevc_avctx->flags2 = avctx->flags2; - ret = ff_codec_open2_recursive(ctx->hevc_avctx, codec, NULL); + ret = avcodec_open2(ctx->hevc_avctx, codec, NULL); if (ret < 0) return ret; diff --git a/libavcodec/imx.c b/libavcodec/imx.c new file mode 100644 index 000000000..0d6c99e5b --- /dev/null +++ b/libavcodec/imx.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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 "avcodec.h" +#include "bytestream.h" +#include "internal.h" + +typedef struct SimbiosisIMXContext { + AVFrame *frame; + uint32_t pal[256]; + uint8_t history[32768]; + int pos; +} SimbiosisIMXContext; + +static av_cold int imx_decode_init(AVCodecContext *avctx) +{ + SimbiosisIMXContext *imx = avctx->priv_data; + + avctx->pix_fmt = AV_PIX_FMT_PAL8; + avctx->width = 320; + avctx->height = 160; + + imx->frame = av_frame_alloc(); + if (!imx->frame) + return AVERROR(ENOMEM); + + return 0; +} + +static int imx_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + SimbiosisIMXContext *imx = avctx->priv_data; + int ret, x, y; + buffer_size_t pal_size; + const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &pal_size); + AVFrame *frame = imx->frame; + GetByteContext gb; + + if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0) + return ret; + + if (pal && pal_size == AVPALETTE_SIZE) { + memcpy(imx->pal, pal, pal_size); + frame->palette_has_changed = 1; + frame->key_frame = 1; + } else { + frame->key_frame = 0; + frame->palette_has_changed = 0; + } + + bytestream2_init(&gb, avpkt->data, avpkt->size); + + memcpy(frame->data[1], imx->pal, AVPALETTE_SIZE); + + x = 0, y = 0; + while (bytestream2_get_bytes_left(&gb) > 0 && + x < 320 && y < 160) { + int b = bytestream2_get_byte(&gb); + int len = b & 0x3f; + int op = b >> 6; + int fill; + + switch (op) { + case 3: + len = len * 64 + bytestream2_get_byte(&gb); + case 0: + while (len > 0) { + x++; + len--; + if (x >= 320) { + x = 0; + y++; + } + if (y >= 160) + break; + } + + frame->key_frame = 0; + break; + case 1: + if (len == 0) { + int offset = bytestream2_get_le16(&gb); + + if (offset < 0 || offset >= 32768) + return AVERROR_INVALIDDATA; + + len = bytestream2_get_byte(&gb); + while (len > 0 && offset < 32768) { + frame->data[0][x + y * frame->linesize[0]] = imx->history[offset++]; + x++; + len--; + if (x >= 320) { + x = 0; + y++; + } + if (y >= 160) + break; + } + + frame->key_frame = 0; + } else { + while (len > 0) { + fill = bytestream2_get_byte(&gb); + frame->data[0][x + y * frame->linesize[0]] = fill; + if (imx->pos < 32768) + imx->history[imx->pos++] = fill; + x++; + len--; + if (x >= 320) { + x = 0; + y++; + } + if (y >= 160) + break; + } + } + break; + case 2: + fill = bytestream2_get_byte(&gb); + + while (len > 0) { + frame->data[0][x + y * frame->linesize[0]] = fill; + x++; + len--; + if (x >= 320) { + x = 0; + y++; + } + if (y >= 160) + break; + } + break; + } + } + + frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + + if ((ret = av_frame_ref(data, frame)) < 0) + return ret; + + *got_frame = 1; + + return avpkt->size; +} + +static void imx_decode_flush(AVCodecContext *avctx) +{ + SimbiosisIMXContext *imx = avctx->priv_data; + + av_frame_unref(imx->frame); + imx->pos = 0; + memset(imx->pal, 0, sizeof(imx->pal)); + memset(imx->history, 0, sizeof(imx->history)); +} + +static int imx_decode_close(AVCodecContext *avctx) +{ + SimbiosisIMXContext *imx = avctx->priv_data; + + av_frame_free(&imx->frame); + + return 0; +} + +AVCodec ff_simbiosis_imx_decoder = { + .name = "simbiosis_imx", + .long_name = NULL_IF_CONFIG_SMALL("Simbiosis Interactive IMX Video"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_SIMBIOSIS_IMX, + .priv_data_size = sizeof(SimbiosisIMXContext), + .init = imx_decode_init, + .decode = imx_decode_frame, + .close = imx_decode_close, + .flush = imx_decode_flush, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_INIT_CLEANUP, +}; diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c index ccf6cd84c..572130826 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -25,6 +25,7 @@ */ #include "libavutil/attributes.h" +#include "libavutil/thread.h" #define BITSTREAM_READER_LE #include "avcodec.h" @@ -46,7 +47,7 @@ static VLC ir2_vlc; /* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */ static inline int ir2_get_code(GetBitContext *gb) { - return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1; + return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1); } static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, @@ -174,10 +175,6 @@ static int ir2_decode_frame(AVCodecContext *avctx, s->decode_delta = buf[18]; /* decide whether frame uses deltas or not */ -#ifndef BITSTREAM_READER_LE - for (i = 0; i < buf_size; i++) - buf[i] = ff_reverse[buf[i]]; -#endif if ((ret = init_get_bits8(&s->gb, buf + start, buf_size - start)) < 0) return ret; @@ -229,10 +226,17 @@ static int ir2_decode_frame(AVCodecContext *avctx, return buf_size; } +static av_cold void ir2_init_static(void) +{ + INIT_VLC_STATIC_FROM_LENGTHS(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, + &ir2_tab[0][1], 2, &ir2_tab[0][0], 2, 1, + 0, INIT_VLC_OUTPUT_LE, 1 << CODE_VLC_BITS); +} + static av_cold int ir2_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; Ir2Context * const ic = avctx->priv_data; - static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2]; ic->avctx = avctx; @@ -242,17 +246,7 @@ static av_cold int ir2_decode_init(AVCodecContext *avctx) if (!ic->picture) return AVERROR(ENOMEM); - ir2_vlc.table = vlc_tables; - ir2_vlc.table_allocated = 1 << CODE_VLC_BITS; -#ifdef BITSTREAM_READER_LE - init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, - &ir2_codes[0][1], 4, 2, - &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); -#else - init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, - &ir2_codes[0][1], 4, 2, - &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC); -#endif + ff_thread_once(&init_static_once, ir2_init_static); return 0; } @@ -276,4 +270,5 @@ AVCodec ff_indeo2_decoder = { .close = ir2_decode_end, .decode = ir2_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/indeo2data.h b/libavcodec/indeo2data.h index bfdb0a68a..9981a3b2c 100644 --- a/libavcodec/indeo2data.h +++ b/libavcodec/indeo2data.h @@ -25,43 +25,36 @@ #include #define IR2_CODES 143 -static const uint16_t ir2_codes[IR2_CODES][2] = { - { 0x0000, 3 }, { 0x0004, 3 }, { 0x0006, 3 }, { 0x0001, 5 }, - { 0x0009, 5 }, { 0x0019, 5 }, { 0x000D, 5 }, { 0x001D, 5 }, - { 0x0023, 6 }, { 0x0013, 6 }, { 0x0033, 6 }, { 0x000B, 6 }, - { 0x002B, 6 }, { 0x001B, 6 }, { 0x0007, 8 }, { 0x0087, 8 }, - { 0x0027, 8 }, { 0x00A7, 8 }, { 0x0067, 8 }, { 0x00E7, 8 }, - { 0x0097, 8 }, { 0x0057, 8 }, { 0x0037, 8 }, { 0x00B7, 8 }, - { 0x00F7, 8 }, { 0x000F, 9 }, { 0x008F, 9 }, { 0x018F, 9 }, - { 0x014F, 9 }, { 0x00CF, 9 }, { 0x002F, 9 }, { 0x012F, 9 }, - { 0x01AF, 9 }, { 0x006F, 9 }, { 0x00EF, 9 }, { 0x01EF, 9 }, - { 0x001F, 10 }, { 0x021F, 10 }, { 0x011F, 10 }, { 0x031F, 10 }, - { 0x009F, 10 }, { 0x029F, 10 }, { 0x019F, 10 }, { 0x039F, 10 }, - { 0x005F, 10 }, { 0x025F, 10 }, { 0x015F, 10 }, { 0x035F, 10 }, - { 0x00DF, 10 }, { 0x02DF, 10 }, { 0x01DF, 10 }, { 0x03DF, 10 }, - { 0x003F, 13 }, { 0x103F, 13 }, { 0x083F, 13 }, { 0x183F, 13 }, - { 0x043F, 13 }, { 0x143F, 13 }, { 0x0C3F, 13 }, { 0x1C3F, 13 }, - { 0x023F, 13 }, { 0x123F, 13 }, { 0x0A3F, 13 }, { 0x1A3F, 13 }, - { 0x063F, 13 }, { 0x163F, 13 }, { 0x0E3F, 13 }, { 0x1E3F, 13 }, - { 0x013F, 13 }, { 0x113F, 13 }, { 0x093F, 13 }, { 0x193F, 13 }, - { 0x053F, 13 }, { 0x153F, 13 }, { 0x0D3F, 13 }, { 0x1D3F, 13 }, - { 0x033F, 13 }, { 0x133F, 13 }, { 0x0B3F, 13 }, { 0x1B3F, 13 }, - { 0x073F, 13 }, { 0x173F, 13 }, { 0x0F3F, 13 }, { 0x1F3F, 13 }, - { 0x00BF, 13 }, { 0x10BF, 13 }, { 0x08BF, 13 }, { 0x18BF, 13 }, - { 0x04BF, 13 }, { 0x14BF, 13 }, { 0x0CBF, 13 }, { 0x1CBF, 13 }, - { 0x02BF, 13 }, { 0x12BF, 13 }, { 0x0ABF, 13 }, { 0x1ABF, 13 }, - { 0x06BF, 13 }, { 0x16BF, 13 }, { 0x0EBF, 13 }, { 0x1EBF, 13 }, - { 0x01BF, 13 }, { 0x11BF, 13 }, { 0x09BF, 13 }, { 0x19BF, 13 }, - { 0x05BF, 13 }, { 0x15BF, 13 }, { 0x0DBF, 13 }, { 0x1DBF, 13 }, - { 0x03BF, 13 }, { 0x13BF, 13 }, { 0x0BBF, 13 }, { 0x1BBF, 13 }, - { 0x07BF, 13 }, { 0x17BF, 13 }, { 0x0FBF, 13 }, { 0x1FBF, 13 }, - { 0x007F, 14 }, { 0x207F, 14 }, { 0x107F, 14 }, { 0x307F, 14 }, - { 0x087F, 14 }, { 0x287F, 14 }, { 0x187F, 14 }, { 0x387F, 14 }, - { 0x047F, 14 }, { 0x247F, 14 }, { 0x147F, 14 }, { 0x0002, 3 }, - { 0x0011, 5 }, { 0x0005, 5 }, { 0x0015, 5 }, { 0x0003, 6 }, - { 0x003B, 6 }, { 0x0047, 8 }, { 0x00C7, 8 }, { 0x0017, 8 }, - { 0x00D7, 8 }, { 0x0077, 8 }, { 0x010F, 9 }, { 0x004F, 9 }, - { 0x01CF, 9 }, { 0x00AF, 9 }, { 0x016F, 9 }, +static const uint8_t ir2_tab[IR2_CODES][2] = { + { 0x01, 3 }, { 0x02, 3 }, { 0x80, 3 }, { 0x03, 3 }, { 0x04, 5 }, + { 0x81, 5 }, { 0x05, 5 }, { 0x06, 5 }, { 0x82, 5 }, { 0x83, 5 }, + { 0x07, 5 }, { 0x08, 5 }, { 0x84, 6 }, { 0x09, 6 }, { 0x0A, 6 }, + { 0x0B, 6 }, { 0x0C, 6 }, { 0x0D, 6 }, { 0x0E, 6 }, { 0x85, 6 }, + { 0x0F, 8 }, { 0x10, 8 }, { 0x86, 8 }, { 0x87, 8 }, { 0x11, 8 }, + { 0x12, 8 }, { 0x13, 8 }, { 0x14, 8 }, { 0x88, 8 }, { 0x15, 8 }, + { 0x16, 8 }, { 0x89, 8 }, { 0x17, 8 }, { 0x18, 8 }, { 0x8A, 8 }, + { 0x19, 8 }, { 0x1A, 9 }, { 0x8B, 9 }, { 0x1B, 9 }, { 0x1C, 9 }, + { 0x8C, 9 }, { 0x1D, 9 }, { 0x1E, 9 }, { 0x8D, 9 }, { 0x1F, 9 }, + { 0x20, 9 }, { 0x8E, 9 }, { 0x21, 9 }, { 0x22, 9 }, { 0x8F, 9 }, + { 0x23, 9 }, { 0x24, 9 }, { 0x25, 10 }, { 0x26, 10 }, { 0x27, 10 }, + { 0x28, 10 }, { 0x29, 10 }, { 0x2A, 10 }, { 0x2B, 10 }, { 0x2C, 10 }, + { 0x2D, 10 }, { 0x2E, 10 }, { 0x2F, 10 }, { 0x30, 10 }, { 0x31, 10 }, + { 0x32, 10 }, { 0x33, 10 }, { 0x34, 10 }, { 0x35, 13 }, { 0x36, 13 }, + { 0x37, 13 }, { 0x38, 13 }, { 0x39, 13 }, { 0x3A, 13 }, { 0x3B, 13 }, + { 0x3C, 13 }, { 0x3D, 13 }, { 0x3E, 13 }, { 0x3F, 13 }, { 0x40, 13 }, + { 0x41, 13 }, { 0x42, 13 }, { 0x43, 13 }, { 0x44, 13 }, { 0x45, 13 }, + { 0x46, 13 }, { 0x47, 13 }, { 0x48, 13 }, { 0x49, 13 }, { 0x4A, 13 }, + { 0x4B, 13 }, { 0x4C, 13 }, { 0x4D, 13 }, { 0x4E, 13 }, { 0x4F, 13 }, + { 0x50, 13 }, { 0x51, 13 }, { 0x52, 13 }, { 0x53, 13 }, { 0x54, 13 }, + { 0x55, 13 }, { 0x56, 13 }, { 0x57, 13 }, { 0x58, 13 }, { 0x59, 13 }, + { 0x5A, 13 }, { 0x5B, 13 }, { 0x5C, 13 }, { 0x5D, 13 }, { 0x5E, 13 }, + { 0x5F, 13 }, { 0x60, 13 }, { 0x61, 13 }, { 0x62, 13 }, { 0x63, 13 }, + { 0x64, 13 }, { 0x65, 13 }, { 0x66, 13 }, { 0x67, 13 }, { 0x68, 13 }, + { 0x69, 13 }, { 0x6A, 13 }, { 0x6B, 13 }, { 0x6C, 13 }, { 0x6D, 13 }, + { 0x6E, 13 }, { 0x6F, 13 }, { 0x70, 13 }, { 0x71, 13 }, { 0x72, 13 }, + { 0x73, 13 }, { 0x74, 13 }, { 0x75, 14 }, { 0x76, 14 }, { 0x77, 14 }, + { 0x78, 14 }, { 0x79, 14 }, { 0x7A, 14 }, { 0x7B, 14 }, { 0x7C, 14 }, + { 0x7D, 14 }, { 0x7E, 14 }, { 0x7F, 14 }, }; static const uint8_t ir2_delta_table[4][256] = { diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 71d478c9f..5257d983c 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -171,7 +171,7 @@ static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx, if (luma_width < 16 || luma_width > 640 || luma_height < 16 || luma_height > 480 || - luma_width & 3 || luma_height & 3) { + luma_width & 1 || luma_height & 1) { av_log(avctx, AV_LOG_ERROR, "Invalid picture dimensions: %d x %d!\n", luma_width, luma_height); return AVERROR_INVALIDDATA; @@ -203,10 +203,8 @@ 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); + if (!ctx->planes[p].buffers[0] || !ctx->planes[p].buffers[1]) 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); @@ -1143,4 +1141,5 @@ AVCodec ff_indeo3_decoder = { .close = decode_close, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c index 4bfc6cdd7..e2778af6c 100644 --- a/libavcodec/indeo4.c +++ b/libavcodec/indeo4.c @@ -713,4 +713,5 @@ AVCodec ff_indeo4_decoder = { .close = ff_ivi_decode_close, .decode = ff_ivi_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c index 4ccdbcaf0..3de4a30ee 100644 --- a/libavcodec/indeo5.c +++ b/libavcodec/indeo5.c @@ -30,6 +30,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" #include "get_bits.h" +#include "internal.h" #include "ivi.h" #include "ivi_dsp.h" #include "indeo5data.h" @@ -692,4 +693,5 @@ AVCodec ff_indeo5_decoder = { .close = ff_ivi_decode_close, .decode = ff_ivi_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 0a72a0e37..b57b99681 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -28,6 +28,7 @@ #include "libavutil/buffer.h" #include "libavutil/channel_layout.h" +#include "libavutil/fifo.h" #include "libavutil/mathematics.h" #include "libavutil/pixfmt.h" #include "avcodec.h" @@ -73,6 +74,10 @@ * uses ff_thread_report/await_progress(). */ #define FF_CODEC_CAP_ALLOCATE_PROGRESS (1 << 6) +/** + * Codec handles avctx->thread_count == 0 (auto) internally. + */ +#define FF_CODEC_CAP_AUTO_THREADS (1 << 7) /** * AVCodec.codec_tags termination value @@ -110,9 +115,12 @@ typedef struct DecodeSimpleContext { AVPacket *in_pkt; - AVFrame *out_frame; } DecodeSimpleContext; +typedef struct EncodeSimpleContext { + AVFrame *in_frame; +} EncodeSimpleContext; + typedef struct AVCodecInternal { /** * Whether the parent AVCodecContext is a copy of the context which had @@ -128,7 +136,9 @@ typedef struct AVCodecInternal { */ int last_audio_frame; +#if FF_API_OLD_ENCDEC AVFrame *to_free; +#endif AVBufferRef *pool; @@ -142,6 +152,7 @@ typedef struct AVCodecInternal { * for decoding. */ AVPacket *last_pkt_props; + AVFifoBuffer *pkt_props; /** * temporary buffer used for encoders to store their bitstream @@ -151,6 +162,8 @@ typedef struct AVCodecInternal { void *frame_thread_encoder; + EncodeSimpleContext es; + /** * Number of audio samples to skip at the start of the next decoded frame */ @@ -170,9 +183,10 @@ typedef struct AVCodecInternal { * buffers for using new encode/decode API through legacy API */ AVPacket *buffer_pkt; - int buffer_pkt_valid; // encoding: packet without data can be valid AVFrame *buffer_frame; int draining_done; + +#if FF_API_OLD_ENCDEC int compat_decode_warned; /* this variable is set by the decoder internals to signal to the old * API compat wrappers the amount of data consumed from the last packet */ @@ -181,6 +195,8 @@ typedef struct AVCodecInternal { * of the packet (that should be submitted in the next decode call */ size_t compat_decode_partial_size; AVFrame *compat_decode_frame; + AVPacket *compat_encode_packet; +#endif int showed_multi_packet_warning; @@ -299,18 +315,6 @@ int ff_thread_can_start_frame(AVCodecContext *avctx); int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx); -/** - * Call avcodec_open2 recursively by decrementing counter, unlocking mutex, - * calling the function and then restoring again. Assumes the mutex is - * already locked - */ -int ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); - -/** - * Finalize buf into extradata and set its size appropriately. - */ -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); @@ -348,29 +352,25 @@ int ff_side_data_update_matrix_encoding(AVFrame *frame, */ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt); -/** - * Set various frame properties from the codec context / packet data. - */ -int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame); - /** * Add a CPB properties side data to an encoding context. */ AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx); /** - * Check AVFrame for A53 side data and allocate and fill SEI message with A53 info + * Check AVFrame for S12M timecode side data and allocate and fill TC SEI message with timecode info * - * @param frame Raw frame to get A53 side data from + * @param frame Raw frame to get S12M timecode side data from + * @param rate The frame rate * @param prefix_len Number of bytes to allocate before SEI message * @param data Pointer to a variable to store allocated memory - * Upon return the variable will hold NULL on error or if frame has no A53 info. + * Upon return the variable will hold NULL on error or if frame has no S12M timecode info. * Otherwise it will point to prefix_len uninitialized bytes followed by * *sei_size SEI message * @param sei_size Pointer to a variable to store generated SEI message length * @return Zero on success, negative error code on failure */ -int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, +int ff_alloc_timecode_sei(const AVFrame *frame, AVRational rate, size_t prefix_len, void **data, size_t *sei_size); /** diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index 274641c3d..4d16fdf61 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -1160,7 +1160,6 @@ static void ipvideo_decode_format_11_opcodes(IpvideoContext *s, AVFrame *frame) static av_cold int ipvideo_decode_init(AVCodecContext *avctx) { IpvideoContext *s = avctx->priv_data; - int ret; s->avctx = avctx; @@ -1175,8 +1174,7 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx) s->prev_decode_frame = av_frame_alloc(); if (!s->last_frame || !s->second_last_frame || !s->cur_decode_frame || !s->prev_decode_frame) { - ret = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } s->cur_decode_frame->width = avctx->width; @@ -1187,12 +1185,6 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx) s->prev_decode_frame->format = avctx->pix_fmt; return 0; -error: - av_frame_free(&s->last_frame); - av_frame_free(&s->second_last_frame); - av_frame_free(&s->cur_decode_frame); - av_frame_free(&s->prev_decode_frame); - return ret; } static int ipvideo_decode_frame(AVCodecContext *avctx, @@ -1325,7 +1317,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, return ret; if (!s->is_16bpp) { - int size; + buffer_size_t size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); if (pal && size == AVPALETTE_SIZE) { frame->palette_has_changed = 1; @@ -1381,4 +1373,5 @@ AVCodec ff_interplay_video_decoder = { .close = ipvideo_decode_end, .decode = ipvideo_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c index f385423dc..0bd0db29c 100644 --- a/libavcodec/intrax8.c +++ b/libavcodec/intrax8.c @@ -22,6 +22,7 @@ */ #include "libavutil/avassert.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "get_bits.h" #include "idctdsp.h" @@ -31,6 +32,8 @@ #include "intrax8dsp.h" #include "mpegutils.h" +#define VLC_BUFFER_SIZE 28150 + #define MAX_TABLE_DEPTH(table_bits, max_bits) \ ((max_bits + table_bits - 1) / table_bits) @@ -46,82 +49,45 @@ static VLC j_ac_vlc[2][2][8]; // [quant < 13], [intra / inter], [select] static VLC j_dc_vlc[2][8]; // [quant], [select] static VLC j_orient_vlc[2][4]; // [quant], [select] -static av_cold int x8_vlc_init(void) +static av_cold void x8_init_vlc(VLC *vlc, int nb_bits, int nb_codes, + int *offset, const uint8_t table[][2]) +{ + static VLC_TYPE vlc_buf[VLC_BUFFER_SIZE][2]; + + vlc->table = &vlc_buf[*offset]; + vlc->table_allocated = VLC_BUFFER_SIZE - *offset; + ff_init_vlc_from_lengths(vlc, nb_bits, nb_codes, &table[0][1], 2, + &table[0][0], 2, 1, 0, INIT_VLC_STATIC_OVERLONG, NULL); + *offset += vlc->table_size; +} + +static av_cold void x8_vlc_init(void) { int i; int offset = 0; - int sizeidx = 0; - static const uint16_t sizes[8 * 4 + 8 * 2 + 2 + 4] = { - 576, 548, 582, 618, 546, 616, 560, 642, - 584, 582, 704, 664, 512, 544, 656, 640, - 512, 648, 582, 566, 532, 614, 596, 648, - 586, 552, 584, 590, 544, 578, 584, 624, - - 528, 528, 526, 528, 536, 528, 526, 544, - 544, 512, 512, 528, 528, 544, 512, 544, - - 128, 128, 128, 128, 128, 128, - }; - - static VLC_TYPE table[28150][2]; // set ac tables -#define init_ac_vlc(dst, src) \ - do { \ - dst.table = &table[offset]; \ - dst.table_allocated = sizes[sizeidx]; \ - offset += sizes[sizeidx++]; \ - init_vlc(&dst, AC_VLC_BITS, 77, &src[1], 4, 2, &src[0], 4, 2, \ - INIT_VLC_USE_NEW_STATIC); \ - } while(0) - - for (i = 0; i < 8; i++) { - init_ac_vlc(j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0]); - init_ac_vlc(j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0]); - init_ac_vlc(j_ac_vlc[1][0][i], x8_ac0_lowquant_table[i][0]); - init_ac_vlc(j_ac_vlc[1][1][i], x8_ac1_lowquant_table[i][0]); - } -#undef init_ac_vlc + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + for (int k = 0; k < 8; k++) + x8_init_vlc(&j_ac_vlc[i][j][k], AC_VLC_BITS, 77, + &offset, x8_ac_quant_table[i][j][k]); // set dc tables -#define init_dc_vlc(dst, src) \ - do { \ - dst.table = &table[offset]; \ - dst.table_allocated = sizes[sizeidx]; \ - offset += sizes[sizeidx++]; \ - init_vlc(&dst, DC_VLC_BITS, 34, &src[1], 4, 2, &src[0], 4, 2, \ - INIT_VLC_USE_NEW_STATIC); \ - } while(0) - - for (i = 0; i < 8; i++) { - init_dc_vlc(j_dc_vlc[0][i], x8_dc_highquant_table[i][0]); - init_dc_vlc(j_dc_vlc[1][i], x8_dc_lowquant_table[i][0]); - } -#undef init_dc_vlc + for (int i = 0; i < 2; i++) + for (int j = 0; j < 8; j++) + x8_init_vlc(&j_dc_vlc[i][j], DC_VLC_BITS, 34, &offset, + x8_dc_quant_table[i][j]); // set orient tables -#define init_or_vlc(dst, src) \ - do { \ - dst.table = &table[offset]; \ - dst.table_allocated = sizes[sizeidx]; \ - offset += sizes[sizeidx++]; \ - init_vlc(&dst, OR_VLC_BITS, 12, &src[1], 4, 2, &src[0], 4, 2, \ - INIT_VLC_USE_NEW_STATIC); \ - } while(0) - for (i = 0; i < 2; i++) - init_or_vlc(j_orient_vlc[0][i], x8_orient_highquant_table[i][0]); + x8_init_vlc(&j_orient_vlc[0][i], OR_VLC_BITS, 12, + &offset, x8_orient_highquant_table[i]); for (i = 0; i < 4; i++) - init_or_vlc(j_orient_vlc[1][i], x8_orient_lowquant_table[i][0]); -#undef init_or_vlc + x8_init_vlc(&j_orient_vlc[1][i], OR_VLC_BITS, 12, + &offset, x8_orient_lowquant_table[i]); - if (offset != sizeof(table) / sizeof(VLC_TYPE) / 2) { - av_log(NULL, AV_LOG_ERROR, "table size %"SIZE_SPECIFIER" does not match needed %i\n", - sizeof(table) / sizeof(VLC_TYPE) / 2, offset); - return AVERROR_INVALIDDATA; - } - - return 0; + av_assert2(offset == VLC_BUFFER_SIZE); } static void x8_reset_vlc_tables(IntraX8Context *w) @@ -731,9 +697,7 @@ av_cold int ff_intrax8_common_init(AVCodecContext *avctx, int block_last_index[12], int mb_width, int mb_height) { - int ret = x8_vlc_init(); - if (ret < 0) - return ret; + static AVOnce init_static_once = AV_ONCE_INIT; w->avctx = avctx; w->idsp = *idsp; @@ -762,6 +726,8 @@ av_cold int ff_intrax8_common_init(AVCodecContext *avctx, ff_intrax8dsp_init(&w->dsp); ff_blockdsp_init(&w->bdsp, avctx); + ff_thread_once(&init_static_once, x8_vlc_init); + return 0; } diff --git a/libavcodec/intrax8huf.h b/libavcodec/intrax8huf.h index 558d0e540..f91b6728c 100644 --- a/libavcodec/intrax8huf.h +++ b/libavcodec/intrax8huf.h @@ -21,939 +21,777 @@ #include -static const uint16_t x8_orient_lowquant_table[4][12][2] = { - { // 0 - { 0x0000, 1 }, { 0x0004, 3 }, { 0x0005, 3 }, { 0x000C, 4 }, - { 0x000D, 4 }, { 0x0038, 6 }, { 0x001D, 5 }, { 0x0039, 6 }, - { 0x003C, 6 }, { 0x003D, 6 }, { 0x003E, 6 }, { 0x003F, 6 }, +static const uint8_t x8_orient_lowquant_table[4][12][2] = { + { /* Orient lowquant table 0 */ + { 0, 1 }, { 1, 3 }, { 2, 3 }, { 3, 4 }, { 4, 4 }, { 5, 6 }, + { 7, 6 }, { 6, 5 }, { 8, 6 }, { 9, 6 }, { 10, 6 }, { 11, 6 }, }, - { // 1 - { 0x0000, 5 }, { 0x0001, 5 }, { 0x0002, 5 }, { 0x0001, 2 }, - { 0x0002, 2 }, { 0x0002, 4 }, { 0x0003, 5 }, { 0x0006, 3 }, - { 0x0003, 4 }, { 0x000E, 4 }, { 0x001E, 5 }, { 0x001F, 5 }, + { /* Orient lowquant table 1 */ + { 0, 5 }, { 1, 5 }, { 2, 5 }, { 6, 5 }, { 5, 4 }, { 8, 4 }, + { 3, 2 }, { 4, 2 }, { 7, 3 }, { 9, 4 }, { 10, 5 }, { 11, 5 }, }, - { // 2 - { 0x0000, 2 }, { 0x0001, 2 }, { 0x0004, 3 }, { 0x0005, 3 }, - { 0x0006, 3 }, { 0x0038, 6 }, { 0x0039, 6 }, { 0x001D, 5 }, - { 0x003C, 6 }, { 0x003D, 6 }, { 0x003E, 6 }, { 0x003F, 6 }, + { /* Orient lowquant table 2 */ + { 0, 2 }, { 1, 2 }, { 2, 3 }, { 3, 3 }, { 4, 3 }, { 5, 6 }, + { 6, 6 }, { 7, 5 }, { 8, 6 }, { 9, 6 }, { 10, 6 }, { 11, 6 }, }, - { // 3 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0003, 4 }, { 0x0001, 2 }, - { 0x0002, 2 }, { 0x0018, 5 }, { 0x0019, 5 }, { 0x000D, 4 }, - { 0x001C, 5 }, { 0x001D, 5 }, { 0x001E, 5 }, { 0x001F, 5 }, + { /* Orient lowquant table 3 */ + { 0, 3 }, { 1, 4 }, { 2, 4 }, { 3, 2 }, { 4, 2 }, { 5, 5 }, + { 6, 5 }, { 7, 4 }, { 8, 5 }, { 9, 5 }, { 10, 5 }, { 11, 5 }, }, }; -static const uint16_t x8_orient_highquant_table[2][12][2] = { - { // 0 - { 0x0000, 2 }, { 0x0001, 2 }, { 0x0004, 3 }, { 0x0005, 3 }, - { 0x0006, 3 }, { 0x0038, 6 }, { 0x001D, 5 }, { 0x0039, 6 }, - { 0x003C, 6 }, { 0x003D, 6 }, { 0x003E, 6 }, { 0x003F, 6 }, +static const uint8_t x8_orient_highquant_table[2][12][2] = { + { /* Orient highquant table 0 */ + { 0, 2 }, { 1, 2 }, { 2, 3 }, { 3, 3 }, { 4, 3 }, { 5, 6 }, + { 7, 6 }, { 6, 5 }, { 8, 6 }, { 9, 6 }, { 10, 6 }, { 11, 6 }, }, - { // 1 - { 0x0000, 1 }, { 0x0002, 2 }, { 0x0006, 3 }, { 0x001C, 5 }, - { 0x001D, 5 }, { 0x0078, 7 }, { 0x003D, 6 }, { 0x0079, 7 }, - { 0x007C, 7 }, { 0x007D, 7 }, { 0x007E, 7 }, { 0x007F, 7 }, + { /* Orient highquant table 1 */ + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 5 }, { 4, 5 }, { 5, 7 }, + { 7, 7 }, { 6, 6 }, { 8, 7 }, { 9, 7 }, { 10, 7 }, { 11, 7 }, }, }; #define MAX_OR_VLC_BITS 7 -static const uint16_t x8_dc_lowquant_table[8][34][2] = { - { // 0 - { 0x0000, 5 }, { 0x0001, 4 }, { 0x0001, 5 }, { 0x0004, 5 }, - { 0x0005, 5 }, { 0x0006, 5 }, { 0x000E, 6 }, { 0x000F, 6 }, - { 0x0040, 8 }, { 0x0041, 8 }, { 0x0840, 13 }, { 0x0841, 13 }, - { 0x0842, 13 }, { 0x0843, 13 }, { 0x0844, 13 }, { 0x0845, 13 }, - { 0x0846, 13 }, { 0x0002, 2 }, { 0x0003, 2 }, { 0x0003, 3 }, - { 0x0005, 4 }, { 0x0009, 5 }, { 0x0011, 6 }, { 0x0043, 8 }, - { 0x0085, 9 }, { 0x0847, 13 }, { 0x0848, 13 }, { 0x0849, 13 }, - { 0x084A, 13 }, { 0x084B, 13 }, { 0x084C, 13 }, { 0x084D, 13 }, - { 0x084E, 13 }, { 0x084F, 13 }, +static const uint8_t x8_dc_quant_table[2][8][34][2] = { + { + { /* DC highquant table 0 */ + { 0, 5 }, { 3, 5 }, { 1, 4 }, { 2, 4 }, { 4, 5 }, + { 6, 5 }, { 5, 4 }, { 7, 5 }, { 8, 7 }, { 9, 7 }, + { 10, 12 }, { 11, 12 }, { 12, 12 }, { 13, 12 }, { 14, 12 }, + { 15, 12 }, { 16, 12 }, { 25, 12 }, { 26, 12 }, { 27, 12 }, + { 28, 12 }, { 29, 12 }, { 30, 12 }, { 31, 12 }, { 32, 12 }, + { 33, 12 }, { 24, 8 }, { 23, 7 }, { 17, 3 }, { 18, 2 }, + { 19, 3 }, { 20, 4 }, { 21, 5 }, { 22, 5 }, + }, + { /* DC highquant table 1 */ + { 0, 3 }, { 1, 3 }, { 2, 3 }, { 3, 4 }, { 4, 4 }, + { 5, 3 }, { 6, 4 }, { 7, 4 }, { 8, 6 }, { 9, 7 }, + { 10, 7 }, { 11, 11 }, { 12, 11 }, { 13, 11 }, { 14, 11 }, + { 15, 11 }, { 16, 11 }, { 25, 11 }, { 27, 11 }, { 28, 11 }, + { 29, 11 }, { 30, 11 }, { 31, 11 }, { 32, 10 }, { 33, 10 }, + { 23, 7 }, { 17, 6 }, { 18, 4 }, { 19, 5 }, { 20, 5 }, + { 21, 6 }, { 24, 7 }, { 26, 7 }, { 22, 5 }, + }, + { /* DC highquant table 2 */ + { 0, 7 }, { 1, 7 }, { 2, 6 }, { 3, 7 }, { 5, 7 }, + { 4, 6 }, { 6, 8 }, { 7, 8 }, { 8, 13 }, { 9, 13 }, + { 10, 13 }, { 11, 13 }, { 12, 13 }, { 13, 13 }, { 14, 13 }, + { 15, 13 }, { 16, 12 }, { 23, 12 }, { 24, 12 }, { 25, 12 }, + { 26, 12 }, { 27, 12 }, { 28, 12 }, { 29, 12 }, { 30, 12 }, + { 31, 12 }, { 32, 12 }, { 33, 12 }, { 22, 8 }, { 21, 6 }, + { 20, 5 }, { 19, 3 }, { 18, 2 }, { 17, 1 }, + }, + { /* DC highquant table 3 */ + { 0, 4 }, { 3, 4 }, { 1, 3 }, { 2, 3 }, { 4, 4 }, + { 8, 5 }, { 9, 5 }, { 5, 3 }, { 6, 3 }, { 7, 3 }, + { 10, 7 }, { 11, 11 }, { 12, 11 }, { 13, 11 }, { 14, 11 }, + { 15, 11 }, { 16, 11 }, { 25, 11 }, { 26, 11 }, { 27, 11 }, + { 29, 11 }, { 30, 11 }, { 31, 11 }, { 32, 10 }, { 33, 10 }, + { 18, 7 }, { 21, 7 }, { 17, 5 }, { 19, 6 }, { 20, 6 }, + { 22, 7 }, { 23, 7 }, { 24, 7 }, { 28, 7 }, + }, + { /* DC highquant table 4 */ + { 0, 8 }, { 4, 9 }, { 6, 9 }, { 1, 7 }, { 2, 7 }, + { 3, 7 }, { 5, 8 }, { 7, 14 }, { 8, 14 }, { 9, 14 }, + { 10, 14 }, { 11, 14 }, { 12, 14 }, { 13, 14 }, { 14, 14 }, + { 15, 13 }, { 16, 13 }, { 24, 13 }, { 25, 13 }, { 26, 13 }, + { 27, 13 }, { 28, 13 }, { 29, 13 }, { 30, 13 }, { 31, 13 }, + { 32, 13 }, { 33, 13 }, { 23, 9 }, { 22, 7 }, { 21, 6 }, + { 20, 4 }, { 19, 3 }, { 17, 2 }, { 18, 1 }, + }, + { /* DC highquant table 5 */ + { 0, 7 }, { 1, 7 }, { 2, 6 }, { 3, 6 }, { 4, 6 }, + { 5, 6 }, { 6, 6 }, { 7, 6 }, { 8, 6 }, { 9, 6 }, + { 10, 6 }, { 11, 6 }, { 12, 6 }, { 13, 6 }, { 14, 6 }, + { 15, 6 }, { 16, 6 }, { 17, 6 }, { 18, 6 }, { 19, 6 }, + { 20, 6 }, { 21, 6 }, { 22, 6 }, { 23, 6 }, { 24, 6 }, + { 25, 6 }, { 26, 6 }, { 28, 6 }, { 29, 6 }, { 30, 6 }, + { 31, 6 }, { 32, 6 }, { 33, 6 }, { 27, 1 }, + }, + { /* DC highquant table 6 */ + { 0, 5 }, { 2, 5 }, { 1, 4 }, { 3, 5 }, { 4, 6 }, + { 6, 6 }, { 5, 5 }, { 7, 6 }, { 8, 8 }, { 9, 8 }, + { 10, 13 }, { 11, 13 }, { 12, 13 }, { 13, 13 }, { 14, 13 }, + { 15, 13 }, { 16, 13 }, { 25, 13 }, { 26, 13 }, { 27, 13 }, + { 28, 13 }, { 29, 13 }, { 30, 13 }, { 31, 13 }, { 32, 13 }, + { 33, 13 }, { 24, 9 }, { 23, 8 }, { 17, 2 }, { 18, 2 }, + { 19, 3 }, { 20, 4 }, { 21, 5 }, { 22, 5 }, + }, + { /* DC highquant table 7 */ + { 0, 7 }, { 1, 7 }, { 2, 7 }, { 3, 7 }, { 4, 7 }, + { 5, 7 }, { 6, 7 }, { 7, 7 }, { 8, 7 }, { 9, 7 }, + { 10, 7 }, { 11, 7 }, { 12, 7 }, { 13, 7 }, { 14, 7 }, + { 15, 7 }, { 16, 7 }, { 19, 7 }, { 20, 7 }, { 21, 7 }, + { 22, 7 }, { 23, 7 }, { 24, 7 }, { 25, 7 }, { 26, 7 }, + { 27, 7 }, { 28, 7 }, { 29, 7 }, { 30, 7 }, { 31, 7 }, + { 32, 7 }, { 33, 7 }, { 18, 2 }, { 17, 1 }, + }, }, - { // 1 - { 0x0000, 4 }, { 0x0001, 3 }, { 0x0002, 3 }, { 0x0001, 4 }, - { 0x0006, 4 }, { 0x0004, 3 }, { 0x0007, 4 }, { 0x0005, 3 }, - { 0x000C, 4 }, { 0x000D, 4 }, { 0x001C, 5 }, { 0x003A, 6 }, - { 0x01D8, 9 }, { 0x01D9, 9 }, { 0x1DA0, 13 }, { 0x1DA1, 13 }, - { 0x1DA2, 13 }, { 0x003C, 6 }, { 0x003D, 6 }, { 0x003E, 6 }, - { 0x0077, 7 }, { 0x01DB, 9 }, { 0x007E, 7 }, { 0x00FE, 8 }, - { 0x01FE, 9 }, { 0x1DA3, 13 }, { 0x1DA4, 13 }, { 0x1DA5, 13 }, - { 0x0ED3, 12 }, { 0x0ED4, 12 }, { 0x01FF, 9 }, { 0x0ED5, 12 }, - { 0x0ED6, 12 }, { 0x0ED7, 12 }, - }, - { // 2 - { 0x0000, 4 }, { 0x0001, 3 }, { 0x0002, 3 }, { 0x0001, 4 }, - { 0x0006, 4 }, { 0x0007, 4 }, { 0x0008, 4 }, { 0x0009, 4 }, - { 0x0028, 6 }, { 0x0029, 6 }, { 0x0054, 7 }, { 0x0055, 7 }, - { 0x0AC0, 12 }, { 0x0AC1, 12 }, { 0x0AC2, 12 }, { 0x0AC3, 12 }, - { 0x0AC4, 12 }, { 0x000B, 4 }, { 0x0006, 3 }, { 0x000E, 4 }, - { 0x001E, 5 }, { 0x003E, 6 }, { 0x003F, 6 }, { 0x0057, 7 }, - { 0x00AD, 8 }, { 0x0AC5, 12 }, { 0x0AC6, 12 }, { 0x0AC7, 12 }, - { 0x0AC8, 12 }, { 0x0AC9, 12 }, { 0x0ACA, 12 }, { 0x0ACB, 12 }, - { 0x0566, 11 }, { 0x0567, 11 }, - }, - { // 3 - { 0x0000, 4 }, { 0x0001, 2 }, { 0x0001, 3 }, { 0x0004, 3 }, - { 0x0005, 3 }, { 0x0006, 3 }, { 0x0001, 4 }, { 0x000E, 4 }, - { 0x003C, 6 }, { 0x003D, 6 }, { 0x007C, 7 }, { 0x00FA, 8 }, - { 0x3EC0, 14 }, { 0x3EC1, 14 }, { 0x3EC2, 14 }, { 0x3EC3, 14 }, - { 0x1F62, 13 }, { 0x01F7, 9 }, { 0x007E, 7 }, { 0x00FE, 8 }, - { 0x00FF, 8 }, { 0x1F63, 13 }, { 0x1F64, 13 }, { 0x1F65, 13 }, - { 0x1F66, 13 }, { 0x1F67, 13 }, { 0x1F68, 13 }, { 0x1F69, 13 }, - { 0x1F6A, 13 }, { 0x1F6B, 13 }, { 0x1F6C, 13 }, { 0x1F6D, 13 }, - { 0x1F6E, 13 }, { 0x1F6F, 13 }, - }, - { // 4 - { 0x0000, 7 }, { 0x0001, 7 }, { 0x0002, 7 }, { 0x0003, 7 }, - { 0x0004, 7 }, { 0x0005, 7 }, { 0x0006, 7 }, { 0x0007, 7 }, - { 0x0008, 7 }, { 0x0009, 7 }, { 0x000A, 7 }, { 0x000B, 7 }, - { 0x000C, 7 }, { 0x000D, 7 }, { 0x000E, 7 }, { 0x000F, 7 }, - { 0x0010, 7 }, { 0x0001, 1 }, { 0x0001, 2 }, { 0x0011, 7 }, - { 0x0012, 7 }, { 0x0013, 7 }, { 0x0014, 7 }, { 0x0015, 7 }, - { 0x0016, 7 }, { 0x0017, 7 }, { 0x0018, 7 }, { 0x0019, 7 }, - { 0x001A, 7 }, { 0x001B, 7 }, { 0x001C, 7 }, { 0x001D, 7 }, - { 0x001E, 7 }, { 0x001F, 7 }, - }, - { // 5 - { 0x0000, 5 }, { 0x0001, 4 }, { 0x0001, 5 }, { 0x0008, 6 }, - { 0x0009, 6 }, { 0x000A, 6 }, { 0x0016, 7 }, { 0x000C, 6 }, - { 0x0017, 7 }, { 0x000D, 6 }, { 0x0038, 8 }, { 0x001D, 7 }, - { 0x0039, 8 }, { 0x0780, 13 }, { 0x0781, 13 }, { 0x0782, 13 }, - { 0x0783, 13 }, { 0x0002, 3 }, { 0x0001, 1 }, { 0x0003, 3 }, - { 0x001F, 7 }, { 0x003D, 8 }, { 0x0079, 9 }, { 0x0784, 13 }, - { 0x0785, 13 }, { 0x0786, 13 }, { 0x0787, 13 }, { 0x0788, 13 }, - { 0x0789, 13 }, { 0x078A, 13 }, { 0x078B, 13 }, { 0x078C, 13 }, - { 0x078D, 13 }, { 0x03C7, 12 }, - }, - { // 6 - { 0x0000, 4 }, { 0x0001, 2 }, { 0x0001, 3 }, { 0x0004, 3 }, - { 0x0001, 4 }, { 0x000A, 4 }, { 0x0016, 5 }, { 0x002E, 6 }, - { 0x005E, 7 }, { 0x005F, 7 }, { 0x00C0, 8 }, { 0x3040, 14 }, - { 0x3041, 14 }, { 0x0305, 10 }, { 0x0183, 9 }, { 0x3042, 14 }, - { 0x3043, 14 }, { 0x000D, 4 }, { 0x0007, 3 }, { 0x0019, 5 }, - { 0x0031, 6 }, { 0x00C2, 8 }, { 0x00C3, 8 }, { 0x3044, 14 }, - { 0x3045, 14 }, { 0x3046, 14 }, { 0x3047, 14 }, { 0x3048, 14 }, - { 0x3049, 14 }, { 0x304A, 14 }, { 0x304B, 14 }, { 0x304C, 14 }, - { 0x304D, 14 }, { 0x1827, 13 }, - }, - { // 7 - { 0x0000, 6 }, { 0x0001, 6 }, { 0x0002, 6 }, { 0x0006, 7 }, - { 0x0007, 7 }, { 0x0004, 6 }, { 0x0005, 6 }, { 0x0006, 6 }, - { 0x000E, 7 }, { 0x001E, 8 }, { 0x001F, 8 }, { 0x0040, 9 }, - { 0x0082, 10 }, { 0x0830, 14 }, { 0x0831, 14 }, { 0x0832, 14 }, - { 0x0833, 14 }, { 0x0001, 1 }, { 0x0001, 2 }, { 0x0003, 4 }, - { 0x0005, 5 }, { 0x0009, 6 }, { 0x0011, 7 }, { 0x0021, 8 }, - { 0x0834, 14 }, { 0x0835, 14 }, { 0x0836, 14 }, { 0x0837, 14 }, - { 0x0838, 14 }, { 0x0839, 14 }, { 0x083A, 14 }, { 0x083B, 14 }, - { 0x041E, 13 }, { 0x041F, 13 }, - }, -}; - -static const uint16_t x8_dc_highquant_table[8][34][2] = { - { // 0 - { 0x0000, 5 }, { 0x0001, 4 }, { 0x0002, 4 }, { 0x0001, 5 }, - { 0x0006, 5 }, { 0x0004, 4 }, { 0x0007, 5 }, { 0x000A, 5 }, - { 0x002C, 7 }, { 0x002D, 7 }, { 0x05C0, 12 }, { 0x05C1, 12 }, - { 0x05C2, 12 }, { 0x05C3, 12 }, { 0x05C4, 12 }, { 0x05C5, 12 }, - { 0x05C6, 12 }, { 0x0003, 3 }, { 0x0002, 2 }, { 0x0006, 3 }, - { 0x000E, 4 }, { 0x001E, 5 }, { 0x001F, 5 }, { 0x002F, 7 }, - { 0x005D, 8 }, { 0x05C7, 12 }, { 0x05C8, 12 }, { 0x05C9, 12 }, - { 0x05CA, 12 }, { 0x05CB, 12 }, { 0x05CC, 12 }, { 0x05CD, 12 }, - { 0x05CE, 12 }, { 0x05CF, 12 }, - }, - { // 1 - { 0x0000, 3 }, { 0x0001, 3 }, { 0x0002, 3 }, { 0x0006, 4 }, - { 0x0007, 4 }, { 0x0004, 3 }, { 0x000A, 4 }, { 0x000B, 4 }, - { 0x0030, 6 }, { 0x0062, 7 }, { 0x0063, 7 }, { 0x0640, 11 }, - { 0x0641, 11 }, { 0x0642, 11 }, { 0x0643, 11 }, { 0x0644, 11 }, - { 0x0645, 11 }, { 0x0033, 6 }, { 0x000D, 4 }, { 0x001C, 5 }, - { 0x001D, 5 }, { 0x003C, 6 }, { 0x001F, 5 }, { 0x0065, 7 }, - { 0x007A, 7 }, { 0x0646, 11 }, { 0x007B, 7 }, { 0x0647, 11 }, - { 0x0648, 11 }, { 0x0649, 11 }, { 0x064A, 11 }, { 0x064B, 11 }, - { 0x0326, 10 }, { 0x0327, 10 }, - }, - { // 2 - { 0x0000, 7 }, { 0x0001, 7 }, { 0x0001, 6 }, { 0x0004, 7 }, - { 0x0003, 6 }, { 0x0005, 7 }, { 0x0010, 8 }, { 0x0011, 8 }, - { 0x0240, 13 }, { 0x0241, 13 }, { 0x0242, 13 }, { 0x0243, 13 }, - { 0x0244, 13 }, { 0x0245, 13 }, { 0x0246, 13 }, { 0x0247, 13 }, - { 0x0124, 12 }, { 0x0001, 1 }, { 0x0001, 2 }, { 0x0001, 3 }, - { 0x0003, 5 }, { 0x0005, 6 }, { 0x0013, 8 }, { 0x0125, 12 }, - { 0x0126, 12 }, { 0x0127, 12 }, { 0x0128, 12 }, { 0x0129, 12 }, - { 0x012A, 12 }, { 0x012B, 12 }, { 0x012C, 12 }, { 0x012D, 12 }, - { 0x012E, 12 }, { 0x012F, 12 }, - }, - { // 3 - { 0x0000, 4 }, { 0x0001, 3 }, { 0x0002, 3 }, { 0x0001, 4 }, - { 0x0006, 4 }, { 0x0004, 3 }, { 0x0005, 3 }, { 0x0006, 3 }, - { 0x000E, 5 }, { 0x000F, 5 }, { 0x0070, 7 }, { 0x0710, 11 }, - { 0x0711, 11 }, { 0x0712, 11 }, { 0x0713, 11 }, { 0x0714, 11 }, - { 0x0715, 11 }, { 0x001D, 5 }, { 0x0072, 7 }, { 0x003C, 6 }, - { 0x003D, 6 }, { 0x0073, 7 }, { 0x007C, 7 }, { 0x007D, 7 }, - { 0x007E, 7 }, { 0x0716, 11 }, { 0x0717, 11 }, { 0x0718, 11 }, - { 0x007F, 7 }, { 0x0719, 11 }, { 0x071A, 11 }, { 0x071B, 11 }, - { 0x038E, 10 }, { 0x038F, 10 }, - }, - { // 4 - { 0x0000, 8 }, { 0x0001, 7 }, { 0x0002, 7 }, { 0x0003, 7 }, - { 0x0002, 9 }, { 0x0008, 8 }, { 0x0003, 9 }, { 0x0240, 14 }, - { 0x0241, 14 }, { 0x0242, 14 }, { 0x0243, 14 }, { 0x0244, 14 }, - { 0x0245, 14 }, { 0x0246, 14 }, { 0x0247, 14 }, { 0x0124, 13 }, - { 0x0125, 13 }, { 0x0001, 2 }, { 0x0001, 1 }, { 0x0001, 3 }, - { 0x0001, 4 }, { 0x0003, 6 }, { 0x0005, 7 }, { 0x0013, 9 }, - { 0x0126, 13 }, { 0x0127, 13 }, { 0x0128, 13 }, { 0x0129, 13 }, - { 0x012A, 13 }, { 0x012B, 13 }, { 0x012C, 13 }, { 0x012D, 13 }, - { 0x012E, 13 }, { 0x012F, 13 }, - }, - { // 5 - { 0x0000, 7 }, { 0x0001, 7 }, { 0x0001, 6 }, { 0x0002, 6 }, - { 0x0003, 6 }, { 0x0004, 6 }, { 0x0005, 6 }, { 0x0006, 6 }, - { 0x0007, 6 }, { 0x0008, 6 }, { 0x0009, 6 }, { 0x000A, 6 }, - { 0x000B, 6 }, { 0x000C, 6 }, { 0x000D, 6 }, { 0x000E, 6 }, - { 0x000F, 6 }, { 0x0010, 6 }, { 0x0011, 6 }, { 0x0012, 6 }, - { 0x0013, 6 }, { 0x0014, 6 }, { 0x0015, 6 }, { 0x0016, 6 }, - { 0x0017, 6 }, { 0x0018, 6 }, { 0x0019, 6 }, { 0x0001, 1 }, - { 0x001A, 6 }, { 0x001B, 6 }, { 0x001C, 6 }, { 0x001D, 6 }, - { 0x001E, 6 }, { 0x001F, 6 }, - }, - { // 6 - { 0x0000, 5 }, { 0x0001, 4 }, { 0x0001, 5 }, { 0x0004, 5 }, - { 0x000A, 6 }, { 0x0006, 5 }, { 0x000B, 6 }, { 0x000E, 6 }, - { 0x003C, 8 }, { 0x003D, 8 }, { 0x07C0, 13 }, { 0x07C1, 13 }, - { 0x07C2, 13 }, { 0x07C3, 13 }, { 0x07C4, 13 }, { 0x07C5, 13 }, - { 0x07C6, 13 }, { 0x0001, 2 }, { 0x0002, 2 }, { 0x0006, 3 }, - { 0x000E, 4 }, { 0x001E, 5 }, { 0x001F, 5 }, { 0x003F, 8 }, - { 0x007D, 9 }, { 0x07C7, 13 }, { 0x07C8, 13 }, { 0x07C9, 13 }, - { 0x07CA, 13 }, { 0x07CB, 13 }, { 0x07CC, 13 }, { 0x07CD, 13 }, - { 0x07CE, 13 }, { 0x07CF, 13 }, - }, - { // 7 - { 0x0000, 7 }, { 0x0001, 7 }, { 0x0002, 7 }, { 0x0003, 7 }, - { 0x0004, 7 }, { 0x0005, 7 }, { 0x0006, 7 }, { 0x0007, 7 }, - { 0x0008, 7 }, { 0x0009, 7 }, { 0x000A, 7 }, { 0x000B, 7 }, - { 0x000C, 7 }, { 0x000D, 7 }, { 0x000E, 7 }, { 0x000F, 7 }, - { 0x0010, 7 }, { 0x0001, 1 }, { 0x0001, 2 }, { 0x0011, 7 }, - { 0x0012, 7 }, { 0x0013, 7 }, { 0x0014, 7 }, { 0x0015, 7 }, - { 0x0016, 7 }, { 0x0017, 7 }, { 0x0018, 7 }, { 0x0019, 7 }, - { 0x001A, 7 }, { 0x001B, 7 }, { 0x001C, 7 }, { 0x001D, 7 }, - { 0x001E, 7 }, { 0x001F, 7 }, + { + { /* DC lowquant table 0 */ + { 0, 5 }, { 2, 5 }, { 1, 4 }, { 3, 5 }, { 4, 5 }, + { 5, 5 }, { 6, 6 }, { 7, 6 }, { 8, 8 }, { 9, 8 }, + { 10, 13 }, { 11, 13 }, { 12, 13 }, { 13, 13 }, { 14, 13 }, + { 15, 13 }, { 16, 13 }, { 25, 13 }, { 26, 13 }, { 27, 13 }, + { 28, 13 }, { 29, 13 }, { 30, 13 }, { 31, 13 }, { 32, 13 }, + { 33, 13 }, { 24, 9 }, { 23, 8 }, { 22, 6 }, { 21, 5 }, + { 20, 4 }, { 19, 3 }, { 17, 2 }, { 18, 2 }, + }, + { /* DC lowquant table 1 */ + { 0, 4 }, { 3, 4 }, { 1, 3 }, { 2, 3 }, { 4, 4 }, + { 6, 4 }, { 5, 3 }, { 7, 3 }, { 8, 4 }, { 9, 4 }, + { 10, 5 }, { 11, 6 }, { 12, 9 }, { 13, 9 }, { 14, 13 }, + { 15, 13 }, { 16, 13 }, { 25, 13 }, { 26, 13 }, { 27, 13 }, + { 28, 12 }, { 29, 12 }, { 31, 12 }, { 32, 12 }, { 33, 12 }, + { 21, 9 }, { 20, 7 }, { 17, 6 }, { 18, 6 }, { 19, 6 }, + { 22, 7 }, { 23, 8 }, { 24, 9 }, { 30, 9 }, + }, + { /* DC lowquant table 2 */ + { 0, 4 }, { 3, 4 }, { 1, 3 }, { 2, 3 }, { 4, 4 }, + { 5, 4 }, { 6, 4 }, { 7, 4 }, { 8, 6 }, { 9, 6 }, + { 10, 7 }, { 11, 7 }, { 12, 12 }, { 13, 12 }, { 14, 12 }, + { 15, 12 }, { 16, 12 }, { 25, 12 }, { 26, 12 }, { 27, 12 }, + { 28, 12 }, { 29, 12 }, { 30, 12 }, { 31, 12 }, { 32, 11 }, + { 33, 11 }, { 24, 8 }, { 23, 7 }, { 17, 4 }, { 18, 3 }, + { 19, 4 }, { 20, 5 }, { 21, 6 }, { 22, 6 }, + }, + { /* DC lowquant table 3 */ + { 0, 4 }, { 6, 4 }, { 2, 3 }, { 1, 2 }, { 3, 3 }, + { 4, 3 }, { 5, 3 }, { 7, 4 }, { 8, 6 }, { 9, 6 }, + { 10, 7 }, { 11, 8 }, { 12, 14 }, { 13, 14 }, { 14, 14 }, + { 15, 14 }, { 16, 13 }, { 21, 13 }, { 22, 13 }, { 23, 13 }, + { 24, 13 }, { 25, 13 }, { 26, 13 }, { 27, 13 }, { 28, 13 }, + { 29, 13 }, { 30, 13 }, { 31, 13 }, { 32, 13 }, { 33, 13 }, + { 17, 9 }, { 18, 7 }, { 19, 8 }, { 20, 8 }, + }, + { /* DC lowquant table 4 */ + { 0, 7 }, { 1, 7 }, { 2, 7 }, { 3, 7 }, { 4, 7 }, + { 5, 7 }, { 6, 7 }, { 7, 7 }, { 8, 7 }, { 9, 7 }, + { 10, 7 }, { 11, 7 }, { 12, 7 }, { 13, 7 }, { 14, 7 }, + { 15, 7 }, { 16, 7 }, { 19, 7 }, { 20, 7 }, { 21, 7 }, + { 22, 7 }, { 23, 7 }, { 24, 7 }, { 25, 7 }, { 26, 7 }, + { 27, 7 }, { 28, 7 }, { 29, 7 }, { 30, 7 }, { 31, 7 }, + { 32, 7 }, { 33, 7 }, { 18, 2 }, { 17, 1 }, + }, + { /* DC lowquant table 5 */ + { 0, 5 }, { 2, 5 }, { 1, 4 }, { 3, 6 }, { 4, 6 }, + { 5, 6 }, { 6, 7 }, { 8, 7 }, { 7, 6 }, { 9, 6 }, + { 10, 8 }, { 12, 8 }, { 11, 7 }, { 13, 13 }, { 14, 13 }, + { 15, 13 }, { 16, 13 }, { 23, 13 }, { 24, 13 }, { 25, 13 }, + { 26, 13 }, { 27, 13 }, { 28, 13 }, { 29, 13 }, { 30, 13 }, + { 31, 13 }, { 32, 13 }, { 33, 12 }, { 22, 9 }, { 21, 8 }, + { 20, 7 }, { 17, 3 }, { 19, 3 }, { 18, 1 }, + }, + { /* DC lowquant table 6 */ + { 0, 4 }, { 4, 4 }, { 2, 3 }, { 1, 2 }, { 3, 3 }, + { 5, 4 }, { 6, 5 }, { 7, 6 }, { 8, 7 }, { 9, 7 }, + { 10, 8 }, { 11, 14 }, { 12, 14 }, { 15, 14 }, { 16, 14 }, + { 23, 14 }, { 24, 14 }, { 25, 14 }, { 26, 14 }, { 27, 14 }, + { 28, 14 }, { 29, 14 }, { 30, 14 }, { 31, 14 }, { 32, 14 }, + { 33, 13 }, { 13, 10 }, { 14, 9 }, { 21, 8 }, { 22, 8 }, + { 20, 6 }, { 19, 5 }, { 17, 4 }, { 18, 3 }, + }, + { /* DC lowquant table 7 */ + { 0, 6 }, { 1, 6 }, { 2, 6 }, { 3, 7 }, { 4, 7 }, + { 5, 6 }, { 6, 6 }, { 7, 6 }, { 8, 7 }, { 9, 8 }, + { 10, 8 }, { 11, 9 }, { 12, 10 }, { 13, 14 }, { 14, 14 }, + { 15, 14 }, { 16, 14 }, { 24, 14 }, { 25, 14 }, { 26, 14 }, + { 27, 14 }, { 28, 14 }, { 29, 14 }, { 30, 14 }, { 31, 14 }, + { 32, 13 }, { 33, 13 }, { 23, 8 }, { 22, 7 }, { 21, 6 }, + { 20, 5 }, { 19, 4 }, { 18, 2 }, { 17, 1 }, + }, }, }; #define MAX_DC_VLC_BITS 14 -static const uint16_t x8_ac0_lowquant_table[8][77][2] = { - { // 0 - { 0x0000, 2 }, { 0x0002, 3 }, { 0x0006, 4 }, { 0x000E, 5 }, - { 0x001E, 6 }, { 0x003E, 7 }, { 0x003F, 7 }, { 0x0040, 7 }, - { 0x0104, 9 }, { 0x0083, 8 }, { 0x0084, 8 }, { 0x0085, 8 }, - { 0x020A, 10 }, { 0x020B, 10 }, { 0x0218, 10 }, { 0x0219, 10 }, - { 0x0009, 4 }, { 0x0044, 7 }, { 0x010D, 9 }, { 0x021C, 10 }, - { 0x0023, 6 }, { 0x0045, 7 }, { 0x0050, 7 }, { 0x000B, 4 }, - { 0x000C, 4 }, { 0x0015, 5 }, { 0x001A, 5 }, { 0x001B, 5 }, - { 0x0029, 6 }, { 0x0038, 6 }, { 0x0039, 6 }, { 0x003A, 6 }, - { 0x0051, 7 }, { 0x0076, 7 }, { 0x0077, 7 }, { 0x0078, 7 }, - { 0x0079, 7 }, { 0x007A, 7 }, { 0x007B, 7 }, { 0x00F8, 8 }, - { 0x010F, 9 }, { 0x021D, 10 }, { 0x3E40, 14 }, { 0x3E41, 14 }, - { 0x3E42, 14 }, { 0x3E43, 14 }, { 0x03E5, 10 }, { 0x3E44, 14 }, - { 0x01F3, 9 }, { 0x3E45, 14 }, { 0x3E46, 14 }, { 0x3E47, 14 }, - { 0x00FA, 8 }, { 0x3E48, 14 }, { 0x3E49, 14 }, { 0x3E4A, 14 }, - { 0x3E4B, 14 }, { 0x03EC, 10 }, { 0x3E4C, 14 }, { 0x007E, 7 }, - { 0x00FE, 8 }, { 0x00FF, 8 }, { 0x01F7, 9 }, { 0x3E4D, 14 }, - { 0x3E4E, 14 }, { 0x3E4F, 14 }, { 0x3ED0, 14 }, { 0x3ED1, 14 }, - { 0x3ED2, 14 }, { 0x3ED3, 14 }, { 0x3ED4, 14 }, { 0x3ED5, 14 }, - { 0x1F6B, 13 }, { 0x1F6C, 13 }, { 0x1F6D, 13 }, { 0x1F6E, 13 }, - { 0x1F6F, 13 }, +static const uint8_t x8_ac_quant_table[2][2][8][77][2] = { + { + { + { /* AC highquant table group 0, table 0 */ + { 0, 3 }, { 1, 4 }, { 2, 6 }, { 3, 6 }, { 4, 7 }, + { 6, 15 }, { 8, 15 }, { 10, 15 }, { 12, 15 }, { 13, 15 }, + { 14, 15 }, { 15, 14 }, { 34, 14 }, { 45, 14 }, { 46, 14 }, + { 47, 14 }, { 49, 14 }, { 50, 14 }, { 51, 14 }, { 52, 14 }, + { 53, 14 }, { 54, 14 }, { 55, 14 }, { 56, 14 }, { 57, 14 }, + { 58, 14 }, { 60, 14 }, { 61, 14 }, { 62, 14 }, { 63, 14 }, + { 64, 14 }, { 65, 14 }, { 67, 14 }, { 69, 14 }, { 70, 14 }, + { 71, 14 }, { 72, 14 }, { 74, 14 }, { 75, 14 }, { 76, 14 }, + { 9, 9 }, { 7, 8 }, { 5, 6 }, { 11, 9 }, { 18, 9 }, + { 19, 9 }, { 22, 9 }, { 20, 7 }, { 17, 6 }, { 16, 5 }, + { 21, 7 }, { 29, 8 }, { 33, 8 }, { 28, 6 }, { 27, 5 }, + { 24, 3 }, { 23, 2 }, { 25, 4 }, { 26, 4 }, { 30, 7 }, + { 32, 7 }, { 31, 6 }, { 35, 7 }, { 36, 7 }, { 37, 7 }, + { 38, 9 }, { 41, 9 }, { 42, 8 }, { 39, 5 }, { 40, 6 }, + { 43, 9 }, { 44, 9 }, { 48, 8 }, { 59, 9 }, { 66, 9 }, + { 68, 9 }, { 73, 9 }, + }, + { /* AC highquant table group 0, table 1 */ + { 0, 3 }, { 1, 4 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, + { 5, 6 }, { 6, 6 }, { 7, 6 }, { 8, 7 }, { 9, 8 }, + { 10, 8 }, { 11, 8 }, { 12, 8 }, { 13, 14 }, { 44, 14 }, + { 47, 14 }, { 50, 14 }, { 51, 14 }, { 54, 14 }, { 55, 14 }, + { 56, 14 }, { 63, 14 }, { 64, 14 }, { 67, 14 }, { 68, 14 }, + { 69, 14 }, { 70, 14 }, { 72, 14 }, { 76, 14 }, { 14, 10 }, + { 15, 10 }, { 45, 10 }, { 32, 8 }, { 16, 4 }, { 17, 5 }, + { 18, 6 }, { 19, 7 }, { 31, 7 }, { 20, 5 }, { 21, 6 }, + { 26, 6 }, { 22, 5 }, { 24, 5 }, { 23, 4 }, { 25, 5 }, + { 27, 6 }, { 28, 6 }, { 29, 6 }, { 30, 6 }, { 33, 8 }, + { 38, 8 }, { 34, 7 }, { 35, 7 }, { 36, 7 }, { 37, 7 }, + { 39, 7 }, { 40, 7 }, { 41, 8 }, { 42, 8 }, { 43, 8 }, + { 46, 9 }, { 49, 9 }, { 53, 8 }, { 58, 8 }, { 57, 6 }, + { 48, 5 }, { 52, 5 }, { 59, 7 }, { 60, 8 }, { 61, 9 }, + { 66, 9 }, { 62, 8 }, { 65, 8 }, { 71, 9 }, { 75, 9 }, + { 74, 8 }, { 73, 5 }, + }, + { /* AC highquant table group 0, table 2 */ + { 0, 4 }, { 1, 5 }, { 2, 12 }, { 3, 12 }, { 4, 12 }, + { 5, 12 }, { 6, 12 }, { 7, 12 }, { 8, 12 }, { 9, 12 }, + { 10, 12 }, { 11, 12 }, { 12, 11 }, { 13, 11 }, { 14, 11 }, + { 15, 11 }, { 16, 11 }, { 17, 11 }, { 18, 11 }, { 19, 11 }, + { 20, 11 }, { 21, 11 }, { 22, 11 }, { 28, 11 }, { 29, 11 }, + { 30, 11 }, { 31, 11 }, { 32, 11 }, { 33, 11 }, { 34, 11 }, + { 35, 11 }, { 36, 11 }, { 37, 11 }, { 38, 11 }, { 40, 11 }, + { 41, 11 }, { 42, 11 }, { 43, 11 }, { 44, 11 }, { 45, 11 }, + { 46, 11 }, { 47, 11 }, { 48, 11 }, { 49, 11 }, { 50, 11 }, + { 51, 11 }, { 52, 11 }, { 53, 11 }, { 54, 11 }, { 55, 11 }, + { 56, 11 }, { 57, 11 }, { 58, 11 }, { 59, 11 }, { 60, 11 }, + { 61, 11 }, { 62, 11 }, { 63, 11 }, { 64, 11 }, { 65, 11 }, + { 66, 11 }, { 67, 11 }, { 68, 11 }, { 69, 11 }, { 70, 11 }, + { 71, 11 }, { 72, 11 }, { 73, 11 }, { 74, 11 }, { 75, 11 }, + { 76, 11 }, { 25, 5 }, { 26, 5 }, { 27, 5 }, { 39, 5 }, + { 24, 2 }, { 23, 1 }, + }, + { /* AC highquant table group 0, table 3 */ + { 0, 8 }, { 1, 8 }, { 2, 8 }, { 3, 8 }, { 4, 8 }, + { 5, 8 }, { 6, 8 }, { 7, 8 }, { 8, 8 }, { 9, 8 }, + { 10, 8 }, { 11, 8 }, { 12, 8 }, { 13, 8 }, { 14, 8 }, + { 15, 8 }, { 16, 8 }, { 17, 8 }, { 18, 8 }, { 19, 8 }, + { 20, 8 }, { 21, 8 }, { 22, 8 }, { 24, 8 }, { 25, 7 }, + { 26, 7 }, { 27, 7 }, { 28, 7 }, { 29, 7 }, { 30, 7 }, + { 31, 7 }, { 32, 7 }, { 33, 7 }, { 34, 7 }, { 35, 7 }, + { 36, 7 }, { 37, 7 }, { 38, 7 }, { 39, 7 }, { 40, 7 }, + { 41, 7 }, { 42, 7 }, { 43, 7 }, { 44, 7 }, { 45, 7 }, + { 46, 7 }, { 47, 7 }, { 48, 7 }, { 49, 7 }, { 50, 7 }, + { 51, 7 }, { 52, 7 }, { 53, 7 }, { 54, 7 }, { 55, 7 }, + { 56, 7 }, { 57, 7 }, { 58, 7 }, { 59, 7 }, { 60, 7 }, + { 61, 7 }, { 62, 7 }, { 63, 7 }, { 64, 7 }, { 65, 7 }, + { 66, 7 }, { 67, 7 }, { 68, 7 }, { 69, 7 }, { 70, 7 }, + { 71, 7 }, { 72, 7 }, { 73, 7 }, { 74, 7 }, { 75, 7 }, + { 76, 7 }, { 23, 1 }, + }, + { /* AC highquant table group 0, table 4 */ + { 0, 9 }, { 1, 9 }, { 2, 9 }, { 3, 9 }, { 4, 9 }, + { 5, 9 }, { 6, 9 }, { 7, 9 }, { 8, 9 }, { 9, 9 }, + { 10, 9 }, { 11, 9 }, { 12, 9 }, { 13, 9 }, { 14, 9 }, + { 15, 9 }, { 16, 9 }, { 17, 9 }, { 18, 9 }, { 19, 9 }, + { 20, 9 }, { 21, 9 }, { 22, 8 }, { 25, 8 }, { 26, 8 }, + { 27, 8 }, { 28, 8 }, { 29, 8 }, { 30, 8 }, { 31, 8 }, + { 32, 8 }, { 33, 8 }, { 34, 8 }, { 35, 8 }, { 36, 8 }, + { 37, 8 }, { 38, 8 }, { 39, 8 }, { 40, 8 }, { 41, 8 }, + { 42, 8 }, { 43, 8 }, { 44, 8 }, { 45, 8 }, { 46, 8 }, + { 47, 8 }, { 48, 8 }, { 49, 8 }, { 50, 8 }, { 51, 8 }, + { 52, 8 }, { 53, 8 }, { 54, 8 }, { 55, 8 }, { 56, 8 }, + { 57, 8 }, { 58, 8 }, { 59, 8 }, { 60, 8 }, { 61, 8 }, + { 62, 8 }, { 63, 8 }, { 64, 8 }, { 65, 8 }, { 66, 8 }, + { 67, 8 }, { 68, 8 }, { 69, 8 }, { 70, 8 }, { 71, 8 }, + { 72, 8 }, { 73, 8 }, { 74, 8 }, { 75, 8 }, { 76, 8 }, + { 23, 2 }, { 24, 1 }, + }, + { /* AC highquant table group 0, table 5 */ + { 0, 10 }, { 1, 10 }, { 2, 10 }, { 3, 10 }, { 4, 10 }, + { 5, 10 }, { 6, 10 }, { 7, 10 }, { 8, 10 }, { 9, 10 }, + { 10, 10 }, { 11, 10 }, { 12, 10 }, { 13, 10 }, { 14, 10 }, + { 15, 10 }, { 16, 10 }, { 17, 10 }, { 18, 10 }, { 19, 10 }, + { 20, 9 }, { 21, 9 }, { 22, 9 }, { 25, 9 }, { 26, 9 }, + { 28, 9 }, { 29, 9 }, { 30, 9 }, { 31, 9 }, { 32, 9 }, + { 33, 9 }, { 34, 9 }, { 35, 9 }, { 36, 9 }, { 37, 9 }, + { 38, 9 }, { 39, 9 }, { 40, 9 }, { 41, 9 }, { 42, 9 }, + { 43, 9 }, { 44, 9 }, { 45, 9 }, { 46, 9 }, { 47, 9 }, + { 48, 9 }, { 49, 9 }, { 50, 9 }, { 51, 9 }, { 52, 9 }, + { 53, 9 }, { 54, 9 }, { 55, 9 }, { 56, 9 }, { 57, 9 }, + { 58, 9 }, { 59, 9 }, { 60, 9 }, { 61, 9 }, { 62, 9 }, + { 63, 9 }, { 64, 9 }, { 65, 9 }, { 66, 9 }, { 67, 9 }, + { 68, 9 }, { 69, 9 }, { 70, 9 }, { 71, 9 }, { 72, 9 }, + { 73, 9 }, { 74, 9 }, { 75, 9 }, { 76, 9 }, { 24, 3 }, + { 27, 2 }, { 23, 1 }, + }, + { /* AC highquant table group 0, table 6 */ + { 0, 2 }, { 1, 4 }, { 2, 5 }, { 3, 5 }, { 4, 6 }, + { 5, 6 }, { 6, 7 }, { 7, 8 }, { 8, 8 }, { 9, 8 }, + { 10, 9 }, { 11, 9 }, { 12, 10 }, { 14, 10 }, { 13, 9 }, + { 15, 15 }, { 42, 15 }, { 46, 15 }, { 50, 15 }, { 51, 15 }, + { 55, 15 }, { 56, 14 }, { 59, 14 }, { 61, 14 }, { 62, 14 }, + { 63, 14 }, { 64, 14 }, { 68, 14 }, { 69, 14 }, { 70, 14 }, + { 71, 14 }, { 72, 14 }, { 75, 14 }, { 76, 14 }, { 43, 10 }, + { 37, 9 }, { 17, 5 }, { 18, 6 }, { 19, 6 }, { 16, 3 }, + { 20, 4 }, { 21, 7 }, { 24, 7 }, { 25, 7 }, { 26, 7 }, + { 22, 5 }, { 23, 5 }, { 27, 8 }, { 30, 8 }, { 28, 7 }, + { 29, 7 }, { 31, 8 }, { 32, 8 }, { 33, 8 }, { 34, 8 }, + { 35, 8 }, { 36, 8 }, { 38, 8 }, { 39, 8 }, { 40, 8 }, + { 41, 9 }, { 44, 10 }, { 45, 10 }, { 47, 10 }, { 54, 10 }, + { 49, 9 }, { 58, 8 }, { 60, 10 }, { 66, 10 }, { 67, 10 }, + { 74, 10 }, { 65, 8 }, { 48, 6 }, { 52, 4 }, { 53, 6 }, + { 57, 6 }, { 73, 5 }, + }, + { /* AC highquant table group 0, table 7 */ + { 0, 3 }, { 1, 4 }, { 2, 5 }, { 3, 5 }, { 4, 6 }, + { 5, 8 }, { 9, 13 }, { 12, 13 }, { 13, 13 }, { 14, 13 }, + { 42, 13 }, { 45, 13 }, { 46, 13 }, { 47, 13 }, { 50, 13 }, + { 51, 13 }, { 53, 13 }, { 54, 13 }, { 55, 13 }, { 56, 13 }, + { 58, 13 }, { 61, 13 }, { 62, 13 }, { 63, 13 }, { 64, 13 }, + { 66, 13 }, { 67, 13 }, { 68, 13 }, { 69, 13 }, { 70, 13 }, + { 72, 12 }, { 74, 12 }, { 75, 12 }, { 76, 12 }, { 6, 7 }, + { 7, 6 }, { 8, 7 }, { 10, 8 }, { 11, 8 }, { 15, 8 }, + { 31, 8 }, { 18, 7 }, { 19, 6 }, { 17, 5 }, { 16, 4 }, + { 20, 6 }, { 21, 7 }, { 36, 8 }, { 37, 8 }, { 22, 6 }, + { 27, 6 }, { 23, 3 }, { 24, 5 }, { 25, 5 }, { 26, 4 }, + { 28, 6 }, { 29, 6 }, { 30, 5 }, { 32, 6 }, { 33, 6 }, + { 34, 6 }, { 35, 6 }, { 38, 7 }, { 40, 7 }, { 41, 7 }, + { 43, 7 }, { 39, 5 }, { 44, 8 }, { 52, 8 }, { 48, 7 }, + { 49, 7 }, { 57, 8 }, { 60, 8 }, { 59, 7 }, { 65, 8 }, + { 71, 8 }, { 73, 6 }, + }, + }, + { + { /* AC highquant table group 1, table 0 */ + { 0, 3 }, { 1, 4 }, { 2, 5 }, { 3, 5 }, { 4, 5 }, + { 5, 5 }, { 6, 6 }, { 7, 7 }, { 9, 7 }, { 8, 6 }, + { 10, 8 }, { 13, 8 }, { 11, 7 }, { 12, 7 }, { 14, 8 }, + { 15, 9 }, { 41, 9 }, { 17, 6 }, { 18, 6 }, { 19, 7 }, + { 21, 8 }, { 42, 9 }, { 43, 9 }, { 16, 4 }, { 20, 5 }, + { 22, 6 }, { 26, 6 }, { 23, 4 }, { 24, 4 }, { 25, 5 }, + { 27, 6 }, { 28, 6 }, { 29, 6 }, { 30, 7 }, { 31, 7 }, + { 32, 7 }, { 33, 7 }, { 34, 7 }, { 35, 7 }, { 36, 7 }, + { 37, 7 }, { 38, 7 }, { 39, 7 }, { 40, 7 }, { 44, 11 }, + { 54, 14 }, { 55, 14 }, { 56, 14 }, { 64, 14 }, { 69, 14 }, + { 70, 14 }, { 72, 14 }, { 76, 14 }, { 53, 10 }, { 45, 9 }, + { 47, 8 }, { 46, 6 }, { 48, 5 }, { 49, 7 }, { 50, 9 }, + { 51, 9 }, { 58, 10 }, { 67, 10 }, { 61, 9 }, { 52, 7 }, + { 57, 7 }, { 59, 7 }, { 60, 8 }, { 62, 8 }, { 63, 7 }, + { 65, 7 }, { 66, 7 }, { 68, 10 }, { 71, 10 }, { 74, 9 }, + { 75, 8 }, { 73, 6 }, + }, + { /* AC highquant table group 1, table 1 */ + { 0, 2 }, { 1, 4 }, { 2, 5 }, { 3, 5 }, { 4, 6 }, + { 5, 7 }, { 6, 7 }, { 7, 7 }, { 8, 8 }, { 9, 9 }, + { 10, 9 }, { 11, 9 }, { 12, 9 }, { 13, 15 }, { 42, 15 }, + { 44, 15 }, { 45, 15 }, { 46, 15 }, { 47, 15 }, { 50, 15 }, + { 51, 15 }, { 56, 15 }, { 61, 15 }, { 62, 15 }, { 63, 15 }, + { 64, 15 }, { 66, 15 }, { 67, 14 }, { 15, 11 }, { 14, 10 }, + { 30, 9 }, { 19, 7 }, { 17, 5 }, { 18, 6 }, { 23, 6 }, + { 16, 3 }, { 20, 4 }, { 21, 5 }, { 24, 7 }, { 25, 7 }, + { 26, 8 }, { 27, 8 }, { 28, 7 }, { 22, 4 }, { 29, 8 }, + { 31, 8 }, { 32, 9 }, { 33, 9 }, { 34, 9 }, { 35, 9 }, + { 36, 10 }, { 37, 11 }, { 38, 11 }, { 39, 9 }, { 40, 9 }, + { 41, 11 }, { 55, 11 }, { 43, 10 }, { 49, 8 }, { 54, 8 }, + { 48, 6 }, { 53, 7 }, { 58, 8 }, { 59, 11 }, { 68, 14 }, + { 69, 14 }, { 70, 14 }, { 71, 14 }, { 72, 14 }, { 74, 14 }, + { 75, 14 }, { 76, 14 }, { 60, 10 }, { 65, 9 }, { 52, 4 }, + { 57, 5 }, { 73, 5 }, + }, + { /* AC highquant table group 1, table 2 */ + { 0, 3 }, { 1, 4 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, + { 5, 7 }, { 7, 7 }, { 6, 6 }, { 8, 9 }, { 9, 9 }, + { 10, 8 }, { 11, 15 }, { 13, 15 }, { 14, 15 }, { 15, 15 }, + { 46, 15 }, { 47, 15 }, { 50, 15 }, { 51, 15 }, { 54, 14 }, + { 55, 14 }, { 56, 14 }, { 62, 14 }, { 63, 14 }, { 64, 14 }, + { 66, 14 }, { 67, 14 }, { 69, 14 }, { 70, 14 }, { 72, 14 }, + { 76, 14 }, { 34, 10 }, { 12, 9 }, { 31, 8 }, { 17, 5 }, + { 16, 3 }, { 18, 7 }, { 19, 7 }, { 21, 6 }, { 22, 5 }, + { 20, 4 }, { 23, 4 }, { 24, 4 }, { 25, 5 }, { 26, 6 }, + { 27, 6 }, { 28, 6 }, { 29, 6 }, { 30, 7 }, { 32, 7 }, + { 33, 8 }, { 35, 8 }, { 36, 9 }, { 37, 10 }, { 38, 10 }, + { 41, 9 }, { 42, 9 }, { 39, 6 }, { 40, 7 }, { 43, 8 }, + { 44, 10 }, { 60, 10 }, { 45, 9 }, { 48, 7 }, { 49, 9 }, + { 58, 9 }, { 53, 8 }, { 57, 6 }, { 52, 5 }, { 59, 9 }, + { 61, 10 }, { 68, 10 }, { 65, 8 }, { 71, 9 }, { 75, 9 }, + { 74, 8 }, { 73, 6 }, + }, + { /* AC highquant table group 1, table 3 */ + { 0, 3 }, { 1, 4 }, { 2, 5 }, { 3, 5 }, { 4, 6 }, + { 5, 6 }, { 6, 7 }, { 7, 7 }, { 8, 6 }, { 9, 6 }, + { 10, 7 }, { 11, 7 }, { 12, 9 }, { 13, 9 }, { 15, 8 }, + { 14, 7 }, { 17, 6 }, { 16, 5 }, { 18, 9 }, { 42, 9 }, + { 32, 8 }, { 19, 7 }, { 20, 6 }, { 21, 7 }, { 22, 7 }, + { 27, 6 }, { 25, 5 }, { 23, 3 }, { 24, 3 }, { 26, 5 }, + { 28, 6 }, { 29, 6 }, { 30, 7 }, { 31, 7 }, { 33, 8 }, + { 34, 8 }, { 35, 8 }, { 41, 8 }, { 36, 7 }, { 38, 7 }, + { 37, 6 }, { 39, 7 }, { 43, 14 }, { 44, 14 }, { 45, 14 }, + { 50, 14 }, { 51, 14 }, { 53, 14 }, { 54, 13 }, { 55, 13 }, + { 56, 13 }, { 58, 13 }, { 64, 13 }, { 67, 13 }, { 68, 13 }, + { 69, 13 }, { 70, 13 }, { 71, 13 }, { 72, 13 }, { 74, 13 }, + { 76, 13 }, { 47, 9 }, { 49, 8 }, { 40, 6 }, { 46, 7 }, + { 48, 7 }, { 52, 8 }, { 57, 8 }, { 60, 7 }, { 59, 6 }, + { 61, 9 }, { 75, 9 }, { 73, 8 }, { 63, 7 }, { 62, 6 }, + { 65, 7 }, { 66, 7 }, + }, + { /* AC highquant table group 1, table 4 */ + { 0, 2 }, { 1, 4 }, { 2, 5 }, { 3, 5 }, { 4, 6 }, + { 5, 6 }, { 6, 7 }, { 7, 7 }, { 8, 7 }, { 9, 8 }, + { 10, 9 }, { 11, 9 }, { 12, 10 }, { 13, 10 }, { 14, 10 }, + { 15, 15 }, { 50, 15 }, { 51, 15 }, { 54, 15 }, { 55, 15 }, + { 56, 15 }, { 61, 15 }, { 64, 15 }, { 45, 12 }, { 47, 12 }, + { 58, 12 }, { 32, 8 }, { 19, 7 }, { 18, 6 }, { 17, 5 }, + { 16, 3 }, { 20, 4 }, { 21, 6 }, { 22, 6 }, { 24, 5 }, + { 23, 4 }, { 25, 6 }, { 26, 6 }, { 27, 6 }, { 28, 7 }, + { 29, 7 }, { 30, 7 }, { 31, 7 }, { 33, 8 }, { 34, 8 }, + { 35, 8 }, { 36, 8 }, { 37, 8 }, { 38, 10 }, { 43, 10 }, + { 41, 9 }, { 39, 7 }, { 40, 8 }, { 42, 9 }, { 44, 10 }, + { 46, 10 }, { 49, 8 }, { 53, 9 }, { 59, 10 }, { 60, 10 }, + { 48, 6 }, { 52, 6 }, { 57, 7 }, { 62, 12 }, { 67, 15 }, + { 69, 15 }, { 70, 15 }, { 71, 15 }, { 72, 14 }, { 76, 14 }, + { 63, 11 }, { 68, 12 }, { 74, 12 }, { 75, 11 }, { 66, 9 }, + { 65, 8 }, { 73, 6 }, + }, + { /* AC highquant table group 1, table 5 */ + { 0, 3 }, { 1, 4 }, { 2, 4 }, { 3, 5 }, { 4, 5 }, + { 5, 6 }, { 6, 7 }, { 7, 8 }, { 8, 11 }, { 10, 11 }, + { 11, 10 }, { 9, 9 }, { 12, 11 }, { 13, 15 }, { 14, 15 }, + { 15, 15 }, { 47, 15 }, { 49, 15 }, { 50, 15 }, { 51, 15 }, + { 54, 15 }, { 55, 14 }, { 56, 14 }, { 58, 14 }, { 63, 14 }, + { 38, 11 }, { 53, 11 }, { 37, 9 }, { 32, 8 }, { 19, 7 }, + { 18, 6 }, { 16, 4 }, { 17, 5 }, { 20, 5 }, { 21, 7 }, + { 31, 7 }, { 22, 6 }, { 25, 5 }, { 24, 4 }, { 23, 3 }, + { 26, 5 }, { 27, 5 }, { 28, 5 }, { 29, 6 }, { 30, 6 }, + { 33, 8 }, { 34, 8 }, { 35, 7 }, { 36, 8 }, { 41, 8 }, + { 40, 7 }, { 39, 5 }, { 42, 8 }, { 44, 10 }, { 60, 10 }, + { 45, 9 }, { 43, 7 }, { 46, 9 }, { 59, 9 }, { 61, 10 }, + { 64, 14 }, { 67, 14 }, { 68, 14 }, { 69, 14 }, { 70, 14 }, + { 72, 14 }, { 75, 14 }, { 76, 14 }, { 66, 11 }, { 62, 9 }, + { 48, 7 }, { 52, 7 }, { 57, 7 }, { 65, 8 }, { 71, 9 }, + { 74, 9 }, { 73, 7 }, + }, + { /* AC highquant table group 1, table 6 */ + { 0, 3 }, { 1, 4 }, { 2, 4 }, { 3, 5 }, { 4, 5 }, + { 5, 5 }, { 6, 5 }, { 7, 6 }, { 8, 7 }, { 10, 7 }, + { 9, 5 }, { 11, 13 }, { 13, 13 }, { 15, 13 }, { 29, 13 }, + { 32, 13 }, { 33, 13 }, { 34, 12 }, { 37, 12 }, { 38, 12 }, + { 40, 12 }, { 41, 12 }, { 42, 12 }, { 43, 12 }, { 44, 12 }, + { 45, 12 }, { 50, 12 }, { 53, 12 }, { 54, 12 }, { 55, 12 }, + { 56, 12 }, { 58, 12 }, { 60, 12 }, { 61, 12 }, { 62, 12 }, + { 63, 12 }, { 64, 12 }, { 66, 12 }, { 67, 12 }, { 68, 12 }, + { 69, 12 }, { 70, 12 }, { 71, 12 }, { 72, 12 }, { 74, 12 }, + { 76, 12 }, { 12, 7 }, { 14, 7 }, { 18, 7 }, { 17, 6 }, + { 19, 7 }, { 21, 7 }, { 16, 4 }, { 20, 5 }, { 22, 5 }, + { 23, 6 }, { 24, 6 }, { 25, 7 }, { 27, 7 }, { 26, 6 }, + { 28, 7 }, { 30, 7 }, { 31, 7 }, { 35, 7 }, { 36, 7 }, + { 39, 7 }, { 47, 6 }, { 46, 5 }, { 49, 5 }, { 48, 4 }, + { 51, 7 }, { 75, 7 }, { 57, 6 }, { 52, 5 }, { 59, 6 }, + { 65, 6 }, { 73, 5 }, + }, + { /* AC highquant table group 1, table 7 */ + { 0, 3 }, { 1, 4 }, { 2, 5 }, { 3, 6 }, { 4, 6 }, + { 5, 8 }, { 6, 8 }, { 7, 8 }, { 8, 11 }, { 9, 15 }, + { 10, 15 }, { 11, 15 }, { 12, 15 }, { 13, 15 }, { 14, 15 }, + { 15, 15 }, { 38, 15 }, { 46, 15 }, { 47, 15 }, { 50, 15 }, + { 51, 15 }, { 53, 15 }, { 54, 15 }, { 55, 15 }, { 56, 15 }, + { 37, 11 }, { 58, 15 }, { 61, 15 }, { 62, 15 }, { 63, 15 }, + { 64, 15 }, { 66, 15 }, { 67, 15 }, { 68, 15 }, { 69, 15 }, + { 70, 15 }, { 72, 14 }, { 75, 14 }, { 76, 14 }, { 19, 9 }, + { 17, 6 }, { 18, 7 }, { 21, 8 }, { 22, 8 }, { 28, 6 }, + { 16, 4 }, { 20, 5 }, { 25, 5 }, { 26, 5 }, { 27, 5 }, + { 23, 2 }, { 24, 3 }, { 29, 6 }, { 30, 8 }, { 31, 8 }, + { 32, 9 }, { 36, 9 }, { 33, 8 }, { 34, 7 }, { 35, 8 }, + { 41, 8 }, { 40, 7 }, { 42, 9 }, { 44, 9 }, { 43, 8 }, + { 39, 5 }, { 45, 9 }, { 49, 10 }, { 71, 10 }, { 48, 8 }, + { 52, 8 }, { 57, 9 }, { 60, 9 }, { 59, 8 }, { 65, 9 }, + { 74, 9 }, { 73, 7 }, + }, + }, }, - { // 1 - { 0x0000, 3 }, { 0x0004, 5 }, { 0x0014, 7 }, { 0x000B, 6 }, - { 0x000C, 6 }, { 0x002A, 8 }, { 0x002B, 8 }, { 0x0034, 8 }, - { 0x0D40, 14 }, { 0x0D41, 14 }, { 0x001B, 7 }, { 0x0D42, 14 }, - { 0x0D43, 14 }, { 0x0D44, 14 }, { 0x0D45, 14 }, { 0x0D46, 14 }, - { 0x000E, 6 }, { 0x003C, 8 }, { 0x0D47, 14 }, { 0x003D, 8 }, - { 0x0D48, 14 }, { 0x0D49, 14 }, { 0x0D4A, 14 }, { 0x0001, 2 }, - { 0x0004, 3 }, { 0x0014, 5 }, { 0x000B, 4 }, { 0x000C, 4 }, - { 0x000D, 4 }, { 0x002A, 6 }, { 0x001F, 7 }, { 0x0056, 7 }, - { 0x0057, 7 }, { 0x0070, 7 }, { 0x00E2, 8 }, { 0x0072, 7 }, - { 0x003A, 6 }, { 0x003B, 6 }, { 0x003C, 6 }, { 0x003D, 6 }, - { 0x00E3, 8 }, { 0x0D4B, 14 }, { 0x00E6, 8 }, { 0x00E7, 8 }, - { 0x00F8, 8 }, { 0x0D4C, 14 }, { 0x0D4D, 14 }, { 0x0D4E, 14 }, - { 0x00F9, 8 }, { 0x0D4F, 14 }, { 0x0D50, 14 }, { 0x0D51, 14 }, - { 0x06A9, 13 }, { 0x06AA, 13 }, { 0x06AB, 13 }, { 0x06AC, 13 }, - { 0x06AD, 13 }, { 0x06AE, 13 }, { 0x06AF, 13 }, { 0x003F, 6 }, - { 0x06B0, 13 }, { 0x06B1, 13 }, { 0x06B2, 13 }, { 0x06B3, 13 }, - { 0x06B4, 13 }, { 0x007D, 7 }, { 0x06B5, 13 }, { 0x06B6, 13 }, - { 0x06B7, 13 }, { 0x06B8, 13 }, { 0x06B9, 13 }, { 0x06BA, 13 }, - { 0x06BB, 13 }, { 0x06BC, 13 }, { 0x06BD, 13 }, { 0x06BE, 13 }, - { 0x06BF, 13 }, - }, - { // 2 - { 0x0000, 2 }, { 0x0002, 3 }, { 0x0003, 3 }, { 0x0008, 4 }, - { 0x0012, 5 }, { 0x0013, 5 }, { 0x0028, 6 }, { 0x0029, 6 }, - { 0x0054, 7 }, { 0x0055, 7 }, { 0x0056, 7 }, { 0x00AE, 8 }, - { 0x00AF, 8 }, { 0x00B0, 8 }, { 0x0162, 9 }, { 0x02C6, 10 }, - { 0x000C, 4 }, { 0x002D, 6 }, { 0x00B2, 8 }, { 0x0166, 9 }, - { 0x002E, 6 }, { 0x0167, 9 }, { 0x00BC, 8 }, { 0x001A, 5 }, - { 0x0036, 6 }, { 0x0037, 6 }, { 0x0038, 6 }, { 0x005F, 7 }, - { 0x0072, 7 }, { 0x0073, 7 }, { 0x0074, 7 }, { 0x0075, 7 }, - { 0x0076, 7 }, { 0x0077, 7 }, { 0x0078, 7 }, { 0x0079, 7 }, - { 0x007A, 7 }, { 0x007B, 7 }, { 0x00BD, 8 }, { 0xB1C0, 16 }, - { 0xB1C1, 16 }, { 0x58E1, 15 }, { 0x0B1D, 12 }, { 0x58E2, 15 }, - { 0x58E3, 15 }, { 0x58E4, 15 }, { 0x00F8, 8 }, { 0x03E4, 10 }, - { 0x01F3, 9 }, { 0x0B1E, 12 }, { 0x58E5, 15 }, { 0x58E6, 15 }, - { 0x00FA, 8 }, { 0x58E7, 15 }, { 0x58F8, 15 }, { 0x58F9, 15 }, - { 0x58FA, 15 }, { 0x01F6, 9 }, { 0x58FB, 15 }, { 0x007E, 7 }, - { 0x00FE, 8 }, { 0x00FF, 8 }, { 0x07CA, 11 }, { 0x0F96, 12 }, - { 0x58FC, 15 }, { 0x58FD, 15 }, { 0x58FE, 15 }, { 0x58FF, 15 }, - { 0x7CB8, 15 }, { 0x7CB9, 15 }, { 0x7CBA, 15 }, { 0x7CBB, 15 }, - { 0x7CBC, 15 }, { 0x01F7, 9 }, { 0x7CBD, 15 }, { 0x7CBE, 15 }, - { 0x7CBF, 15 }, - }, - { // 3 - { 0x0000, 2 }, { 0x0002, 3 }, { 0x0006, 4 }, { 0x000E, 5 }, - { 0x000F, 5 }, { 0x0020, 6 }, { 0x0021, 6 }, { 0x0044, 7 }, - { 0x0045, 7 }, { 0x008C, 8 }, { 0x008D, 8 }, { 0x011C, 9 }, - { 0x011D, 9 }, { 0x011E, 9 }, { 0x023E, 10 }, { 0x023F, 10 }, - { 0x0005, 3 }, { 0x0012, 5 }, { 0x004C, 7 }, { 0x004D, 7 }, - { 0x000C, 4 }, { 0x004E, 7 }, { 0x001A, 5 }, { 0x0036, 6 }, - { 0x004F, 7 }, { 0x006E, 7 }, { 0x006F, 7 }, { 0x00E0, 8 }, - { 0x00E1, 8 }, { 0x00E2, 8 }, { 0x00E3, 8 }, { 0x00E4, 8 }, - { 0x00E5, 8 }, { 0x01CC, 9 }, { 0x00E7, 8 }, { 0x00E8, 8 }, - { 0x00E9, 8 }, { 0x01CD, 9 }, { 0x0750, 11 }, { 0x03A9, 10 }, - { 0x0751, 11 }, { 0x7540, 15 }, { 0x03AB, 10 }, { 0x7541, 15 }, - { 0x7542, 15 }, { 0x7543, 15 }, { 0x01D6, 9 }, { 0x0755, 11 }, - { 0x0076, 7 }, { 0x0EA9, 12 }, { 0x7544, 15 }, { 0x7545, 15 }, - { 0x001E, 5 }, { 0x0077, 7 }, { 0x00F8, 8 }, { 0x03AE, 10 }, - { 0x075E, 11 }, { 0x007D, 7 }, { 0x03E4, 10 }, { 0x00FC, 8 }, - { 0x00FD, 8 }, { 0x03E5, 10 }, { 0x03E6, 10 }, { 0x0EBE, 12 }, - { 0x7546, 15 }, { 0x07CE, 11 }, { 0x7547, 15 }, { 0x75F8, 15 }, - { 0x75F9, 15 }, { 0x75FA, 15 }, { 0x75FB, 15 }, { 0x75FC, 15 }, - { 0x75FD, 15 }, { 0x007F, 7 }, { 0x3AFF, 14 }, { 0x0F9E, 12 }, - { 0x0F9F, 12 }, - }, - { // 4 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0003, 4 }, { 0x0008, 5 }, - { 0x0012, 6 }, { 0x0013, 6 }, { 0x0014, 6 }, { 0x002A, 7 }, - { 0x0016, 6 }, { 0x002B, 7 }, { 0x005C, 8 }, { 0x005D, 8 }, - { 0x005E, 8 }, { 0x00BE, 9 }, { 0x00BF, 9 }, { 0x0060, 8 }, - { 0x0007, 4 }, { 0x000D, 5 }, { 0x0019, 6 }, { 0x0020, 6 }, - { 0x0009, 4 }, { 0x0021, 6 }, { 0x0011, 5 }, { 0x0014, 5 }, - { 0x002A, 6 }, { 0x002B, 6 }, { 0x002C, 6 }, { 0x002D, 6 }, - { 0x002E, 6 }, { 0x002F, 6 }, { 0x0030, 6 }, { 0x0031, 7 }, - { 0x0062, 7 }, { 0x0063, 7 }, { 0x0064, 7 }, { 0x0065, 7 }, - { 0x0066, 7 }, { 0x0061, 8 }, { 0x0670, 11 }, { 0x0068, 7 }, - { 0x0069, 7 }, { 0x00CF, 8 }, { 0x019D, 9 }, { 0x01A8, 9 }, - { 0x01A9, 9 }, { 0x0339, 10 }, { 0x01AA, 9 }, { 0x0356, 10 }, - { 0x0036, 6 }, { 0x00D6, 8 }, { 0x6710, 15 }, { 0x6711, 15 }, - { 0x000E, 4 }, { 0x006E, 7 }, { 0x01AE, 9 }, { 0x6712, 15 }, - { 0x6713, 15 }, { 0x003C, 6 }, { 0x0357, 10 }, { 0x006F, 7 }, - { 0x00F4, 8 }, { 0x00F5, 8 }, { 0x035E, 10 }, { 0x01EC, 9 }, - { 0x6714, 15 }, { 0x01ED, 9 }, { 0x035F, 10 }, { 0x03DC, 10 }, - { 0x03DD, 10 }, { 0x6715, 15 }, { 0x338B, 14 }, { 0x338C, 14 }, - { 0x338D, 14 }, { 0x001F, 5 }, { 0x01EF, 9 }, { 0x338E, 14 }, - { 0x338F, 14 }, - }, - { // 5 - { 0x0000, 2 }, { 0x0004, 4 }, { 0x000A, 5 }, { 0x000B, 5 }, - { 0x0018, 6 }, { 0x0019, 6 }, { 0x0034, 7 }, { 0x006A, 8 }, - { 0x006B, 8 }, { 0x006C, 8 }, { 0x00DA, 9 }, { 0x036C, 11 }, - { 0x006E, 8 }, { 0x01B7, 10 }, { 0x036D, 11 }, { 0x3780, 15 }, - { 0x0004, 3 }, { 0x000E, 5 }, { 0x001E, 6 }, { 0x003E, 7 }, - { 0x000A, 4 }, { 0x002C, 6 }, { 0x0017, 5 }, { 0x002D, 6 }, - { 0x003F, 7 }, { 0x00C0, 8 }, { 0x0061, 7 }, { 0x00C1, 8 }, - { 0x0062, 7 }, { 0x00C6, 8 }, { 0x0064, 7 }, { 0x00C7, 8 }, - { 0x00CA, 8 }, { 0x00DF, 9 }, { 0x0196, 9 }, { 0x0197, 9 }, - { 0x0198, 9 }, { 0x0199, 9 }, { 0x0379, 11 }, { 0x019A, 9 }, - { 0x01BD, 10 }, { 0x066C, 11 }, { 0x3781, 15 }, { 0x0337, 10 }, - { 0x066D, 11 }, { 0x0670, 11 }, { 0x0339, 10 }, { 0x0671, 11 }, - { 0x0034, 6 }, { 0x00CF, 8 }, { 0x3782, 15 }, { 0x3783, 15 }, - { 0x000E, 4 }, { 0x001B, 5 }, { 0x006A, 7 }, { 0x006B, 7 }, - { 0x019D, 9 }, { 0x003C, 6 }, { 0x00F4, 8 }, { 0x00F5, 8 }, - { 0x03D8, 10 }, { 0x07B2, 11 }, { 0x3784, 15 }, { 0x03DA, 10 }, - { 0x3785, 15 }, { 0x03DB, 10 }, { 0x03DC, 10 }, { 0x3786, 15 }, - { 0x3787, 15 }, { 0x1BC4, 14 }, { 0x1BC5, 14 }, { 0x1BC6, 14 }, - { 0x1BC7, 14 }, { 0x001F, 5 }, { 0x03DD, 10 }, { 0x07B3, 11 }, - { 0x01EF, 9 }, - }, - { // 6 - { 0x0000, 2 }, { 0x0004, 4 }, { 0x000A, 5 }, { 0x0016, 6 }, - { 0x0017, 6 }, { 0x0060, 8 }, { 0x00C2, 9 }, { 0x0186, 10 }, - { 0x0187, 10 }, { 0x00C4, 9 }, { 0x3140, 15 }, { 0x3141, 15 }, - { 0x018B, 10 }, { 0x3142, 15 }, { 0x018C, 10 }, { 0x3143, 15 }, - { 0x0007, 4 }, { 0x000D, 5 }, { 0x0064, 8 }, { 0x0065, 8 }, - { 0x0010, 5 }, { 0x00C7, 9 }, { 0x0066, 8 }, { 0x0005, 3 }, - { 0x0006, 3 }, { 0x0009, 4 }, { 0x0011, 5 }, { 0x0038, 6 }, - { 0x0039, 6 }, { 0x0074, 7 }, { 0x0075, 7 }, { 0x0076, 7 }, - { 0x0067, 8 }, { 0x00EE, 8 }, { 0x01DE, 9 }, { 0x00F0, 8 }, - { 0x018D, 10 }, { 0x3144, 15 }, { 0x01DF, 9 }, { 0x003D, 6 }, - { 0x003E, 6 }, { 0x01E2, 9 }, { 0x03C6, 10 }, { 0x00F2, 8 }, - { 0x00F3, 8 }, { 0x03C7, 10 }, { 0x3145, 15 }, { 0x3146, 15 }, - { 0x01F8, 9 }, { 0x3147, 15 }, { 0x3148, 15 }, { 0x3149, 15 }, - { 0x00FD, 8 }, { 0x314A, 15 }, { 0x314B, 15 }, { 0x314C, 15 }, - { 0x314D, 15 }, { 0x01F9, 9 }, { 0x314E, 15 }, { 0x01FC, 9 }, - { 0x314F, 15 }, { 0x3150, 15 }, { 0x3151, 15 }, { 0x3152, 15 }, - { 0x3153, 15 }, { 0x03FA, 10 }, { 0x03FB, 10 }, { 0x3154, 15 }, - { 0x3155, 15 }, { 0x3156, 15 }, { 0x3157, 15 }, { 0x3158, 15 }, - { 0x3159, 15 }, { 0x00FF, 8 }, { 0x18AD, 14 }, { 0x18AE, 14 }, - { 0x18AF, 14 }, - }, - { // 7 - { 0x0000, 4 }, { 0x0080, 11 }, { 0x0081, 11 }, { 0x0082, 11 }, - { 0x0083, 11 }, { 0x0084, 11 }, { 0x0085, 11 }, { 0x0086, 11 }, - { 0x0087, 11 }, { 0x0088, 11 }, { 0x0089, 11 }, { 0x008A, 11 }, - { 0x008B, 11 }, { 0x008C, 11 }, { 0x008D, 11 }, { 0x008E, 11 }, - { 0x008F, 11 }, { 0x0048, 10 }, { 0x0049, 10 }, { 0x004A, 10 }, - { 0x004B, 10 }, { 0x004C, 10 }, { 0x004D, 10 }, { 0x0001, 1 }, - { 0x0001, 2 }, { 0x004E, 10 }, { 0x0002, 4 }, { 0x0003, 4 }, - { 0x004F, 10 }, { 0x0050, 10 }, { 0x0051, 10 }, { 0x0052, 10 }, - { 0x0053, 10 }, { 0x0054, 10 }, { 0x0055, 10 }, { 0x0056, 10 }, - { 0x0057, 10 }, { 0x0058, 10 }, { 0x0059, 10 }, { 0x005A, 10 }, - { 0x005B, 10 }, { 0x005C, 10 }, { 0x005D, 10 }, { 0x005E, 10 }, - { 0x005F, 10 }, { 0x0060, 10 }, { 0x0061, 10 }, { 0x0062, 10 }, - { 0x0063, 10 }, { 0x0064, 10 }, { 0x0065, 10 }, { 0x0066, 10 }, - { 0x0067, 10 }, { 0x0068, 10 }, { 0x0069, 10 }, { 0x006A, 10 }, - { 0x006B, 10 }, { 0x006C, 10 }, { 0x006D, 10 }, { 0x006E, 10 }, - { 0x006F, 10 }, { 0x0070, 10 }, { 0x0071, 10 }, { 0x0072, 10 }, - { 0x0073, 10 }, { 0x0074, 10 }, { 0x0075, 10 }, { 0x0076, 10 }, - { 0x0077, 10 }, { 0x0078, 10 }, { 0x0079, 10 }, { 0x007A, 10 }, - { 0x007B, 10 }, { 0x007C, 10 }, { 0x007D, 10 }, { 0x007E, 10 }, - { 0x007F, 10 }, - }, -}; - -static const uint16_t x8_ac0_highquant_table[8][77][2] = { - { // 0 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x000C, 6 }, { 0x000D, 6 }, - { 0x001C, 7 }, { 0x000F, 6 }, { 0x1D00, 15 }, { 0x003B, 8 }, - { 0x1D01, 15 }, { 0x0075, 9 }, { 0x1D02, 15 }, { 0x0080, 9 }, - { 0x1D03, 15 }, { 0x1D04, 15 }, { 0x1D05, 15 }, { 0x0E83, 14 }, - { 0x0009, 5 }, { 0x0011, 6 }, { 0x0081, 9 }, { 0x0082, 9 }, - { 0x0021, 7 }, { 0x0028, 7 }, { 0x0083, 9 }, { 0x0002, 2 }, - { 0x0003, 3 }, { 0x000C, 4 }, { 0x000D, 4 }, { 0x000B, 5 }, - { 0x0015, 6 }, { 0x0052, 8 }, { 0x0070, 7 }, { 0x0039, 6 }, - { 0x0071, 7 }, { 0x0053, 8 }, { 0x0E84, 14 }, { 0x0074, 7 }, - { 0x0075, 7 }, { 0x0076, 7 }, { 0x01DC, 9 }, { 0x001E, 5 }, - { 0x003E, 6 }, { 0x01DD, 9 }, { 0x00EF, 8 }, { 0x01F8, 9 }, - { 0x01F9, 9 }, { 0x0E85, 14 }, { 0x0E86, 14 }, { 0x0E87, 14 }, - { 0x00FD, 8 }, { 0x0E88, 14 }, { 0x0E89, 14 }, { 0x0E8A, 14 }, - { 0x0E8B, 14 }, { 0x0E8C, 14 }, { 0x0E8D, 14 }, { 0x0E8E, 14 }, - { 0x0E8F, 14 }, { 0x0E90, 14 }, { 0x0E91, 14 }, { 0x01FC, 9 }, - { 0x0E92, 14 }, { 0x0E93, 14 }, { 0x0E94, 14 }, { 0x0E95, 14 }, - { 0x0E96, 14 }, { 0x0E97, 14 }, { 0x01FD, 9 }, { 0x0E98, 14 }, - { 0x01FE, 9 }, { 0x0E99, 14 }, { 0x0E9A, 14 }, { 0x0E9B, 14 }, - { 0x0E9C, 14 }, { 0x01FF, 9 }, { 0x0E9D, 14 }, { 0x0E9E, 14 }, - { 0x0E9F, 14 }, - }, - { // 1 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0003, 4 }, { 0x0008, 5 }, - { 0x0012, 6 }, { 0x0013, 6 }, { 0x0014, 6 }, { 0x0015, 6 }, - { 0x002C, 7 }, { 0x005A, 8 }, { 0x005B, 8 }, { 0x005C, 8 }, - { 0x005D, 8 }, { 0x1780, 14 }, { 0x0179, 10 }, { 0x017A, 10 }, - { 0x0006, 4 }, { 0x000E, 5 }, { 0x001E, 6 }, { 0x003E, 7 }, - { 0x0010, 5 }, { 0x0022, 6 }, { 0x0012, 5 }, { 0x000A, 4 }, - { 0x0013, 5 }, { 0x0016, 5 }, { 0x0023, 6 }, { 0x002E, 6 }, - { 0x002F, 6 }, { 0x0030, 6 }, { 0x0031, 6 }, { 0x003F, 7 }, - { 0x005F, 8 }, { 0x00C8, 8 }, { 0x0065, 7 }, { 0x0066, 7 }, - { 0x0067, 7 }, { 0x0068, 7 }, { 0x00C9, 8 }, { 0x0069, 7 }, - { 0x006A, 7 }, { 0x00D6, 8 }, { 0x00D7, 8 }, { 0x00D8, 8 }, - { 0x1781, 14 }, { 0x017B, 10 }, { 0x01B2, 9 }, { 0x1782, 14 }, - { 0x001C, 5 }, { 0x01B3, 9 }, { 0x1783, 14 }, { 0x1784, 14 }, - { 0x001D, 5 }, { 0x00DA, 8 }, { 0x1785, 14 }, { 0x1786, 14 }, - { 0x1787, 14 }, { 0x0037, 6 }, { 0x00DB, 8 }, { 0x0078, 7 }, - { 0x00F2, 8 }, { 0x01E6, 9 }, { 0x00F4, 8 }, { 0x1788, 14 }, - { 0x1789, 14 }, { 0x00F5, 8 }, { 0x01E7, 9 }, { 0x178A, 14 }, - { 0x178B, 14 }, { 0x178C, 14 }, { 0x178D, 14 }, { 0x01EC, 9 }, - { 0x178E, 14 }, { 0x001F, 5 }, { 0x00F7, 8 }, { 0x01ED, 9 }, - { 0x178F, 14 }, - }, - { // 2 - { 0x0000, 4 }, { 0x0002, 5 }, { 0x0180, 12 }, { 0x0181, 12 }, - { 0x0182, 12 }, { 0x0183, 12 }, { 0x0184, 12 }, { 0x0185, 12 }, - { 0x0186, 12 }, { 0x0187, 12 }, { 0x0188, 12 }, { 0x0189, 12 }, - { 0x00C5, 11 }, { 0x00C6, 11 }, { 0x00C7, 11 }, { 0x00C8, 11 }, - { 0x00C9, 11 }, { 0x00CA, 11 }, { 0x00CB, 11 }, { 0x00CC, 11 }, - { 0x00CD, 11 }, { 0x00CE, 11 }, { 0x00CF, 11 }, { 0x0001, 1 }, - { 0x0001, 2 }, { 0x0004, 5 }, { 0x0005, 5 }, { 0x0006, 5 }, - { 0x00D0, 11 }, { 0x00D1, 11 }, { 0x00D2, 11 }, { 0x00D3, 11 }, - { 0x00D4, 11 }, { 0x00D5, 11 }, { 0x00D6, 11 }, { 0x00D7, 11 }, - { 0x00D8, 11 }, { 0x00D9, 11 }, { 0x00DA, 11 }, { 0x0007, 5 }, - { 0x00DB, 11 }, { 0x00DC, 11 }, { 0x00DD, 11 }, { 0x00DE, 11 }, - { 0x00DF, 11 }, { 0x00E0, 11 }, { 0x00E1, 11 }, { 0x00E2, 11 }, - { 0x00E3, 11 }, { 0x00E4, 11 }, { 0x00E5, 11 }, { 0x00E6, 11 }, - { 0x00E7, 11 }, { 0x00E8, 11 }, { 0x00E9, 11 }, { 0x00EA, 11 }, - { 0x00EB, 11 }, { 0x00EC, 11 }, { 0x00ED, 11 }, { 0x00EE, 11 }, - { 0x00EF, 11 }, { 0x00F0, 11 }, { 0x00F1, 11 }, { 0x00F2, 11 }, - { 0x00F3, 11 }, { 0x00F4, 11 }, { 0x00F5, 11 }, { 0x00F6, 11 }, - { 0x00F7, 11 }, { 0x00F8, 11 }, { 0x00F9, 11 }, { 0x00FA, 11 }, - { 0x00FB, 11 }, { 0x00FC, 11 }, { 0x00FD, 11 }, { 0x00FE, 11 }, - { 0x00FF, 11 }, - }, - { // 3 - { 0x0000, 8 }, { 0x0001, 8 }, { 0x0002, 8 }, { 0x0003, 8 }, - { 0x0004, 8 }, { 0x0005, 8 }, { 0x0006, 8 }, { 0x0007, 8 }, - { 0x0008, 8 }, { 0x0009, 8 }, { 0x000A, 8 }, { 0x000B, 8 }, - { 0x000C, 8 }, { 0x000D, 8 }, { 0x000E, 8 }, { 0x000F, 8 }, - { 0x0010, 8 }, { 0x0011, 8 }, { 0x0012, 8 }, { 0x0013, 8 }, - { 0x0014, 8 }, { 0x0015, 8 }, { 0x0016, 8 }, { 0x0001, 1 }, - { 0x0017, 8 }, { 0x000C, 7 }, { 0x000D, 7 }, { 0x000E, 7 }, - { 0x000F, 7 }, { 0x0010, 7 }, { 0x0011, 7 }, { 0x0012, 7 }, - { 0x0013, 7 }, { 0x0014, 7 }, { 0x0015, 7 }, { 0x0016, 7 }, - { 0x0017, 7 }, { 0x0018, 7 }, { 0x0019, 7 }, { 0x001A, 7 }, - { 0x001B, 7 }, { 0x001C, 7 }, { 0x001D, 7 }, { 0x001E, 7 }, - { 0x001F, 7 }, { 0x0020, 7 }, { 0x0021, 7 }, { 0x0022, 7 }, - { 0x0023, 7 }, { 0x0024, 7 }, { 0x0025, 7 }, { 0x0026, 7 }, - { 0x0027, 7 }, { 0x0028, 7 }, { 0x0029, 7 }, { 0x002A, 7 }, - { 0x002B, 7 }, { 0x002C, 7 }, { 0x002D, 7 }, { 0x002E, 7 }, - { 0x002F, 7 }, { 0x0030, 7 }, { 0x0031, 7 }, { 0x0032, 7 }, - { 0x0033, 7 }, { 0x0034, 7 }, { 0x0035, 7 }, { 0x0036, 7 }, - { 0x0037, 7 }, { 0x0038, 7 }, { 0x0039, 7 }, { 0x003A, 7 }, - { 0x003B, 7 }, { 0x003C, 7 }, { 0x003D, 7 }, { 0x003E, 7 }, - { 0x003F, 7 }, - }, - { // 4 - { 0x0000, 9 }, { 0x0001, 9 }, { 0x0002, 9 }, { 0x0003, 9 }, - { 0x0004, 9 }, { 0x0005, 9 }, { 0x0006, 9 }, { 0x0007, 9 }, - { 0x0008, 9 }, { 0x0009, 9 }, { 0x000A, 9 }, { 0x000B, 9 }, - { 0x000C, 9 }, { 0x000D, 9 }, { 0x000E, 9 }, { 0x000F, 9 }, - { 0x0010, 9 }, { 0x0011, 9 }, { 0x0012, 9 }, { 0x0013, 9 }, - { 0x0014, 9 }, { 0x0015, 9 }, { 0x000B, 8 }, { 0x0001, 2 }, - { 0x0001, 1 }, { 0x000C, 8 }, { 0x000D, 8 }, { 0x000E, 8 }, - { 0x000F, 8 }, { 0x0010, 8 }, { 0x0011, 8 }, { 0x0012, 8 }, - { 0x0013, 8 }, { 0x0014, 8 }, { 0x0015, 8 }, { 0x0016, 8 }, - { 0x0017, 8 }, { 0x0018, 8 }, { 0x0019, 8 }, { 0x001A, 8 }, - { 0x001B, 8 }, { 0x001C, 8 }, { 0x001D, 8 }, { 0x001E, 8 }, - { 0x001F, 8 }, { 0x0020, 8 }, { 0x0021, 8 }, { 0x0022, 8 }, - { 0x0023, 8 }, { 0x0024, 8 }, { 0x0025, 8 }, { 0x0026, 8 }, - { 0x0027, 8 }, { 0x0028, 8 }, { 0x0029, 8 }, { 0x002A, 8 }, - { 0x002B, 8 }, { 0x002C, 8 }, { 0x002D, 8 }, { 0x002E, 8 }, - { 0x002F, 8 }, { 0x0030, 8 }, { 0x0031, 8 }, { 0x0032, 8 }, - { 0x0033, 8 }, { 0x0034, 8 }, { 0x0035, 8 }, { 0x0036, 8 }, - { 0x0037, 8 }, { 0x0038, 8 }, { 0x0039, 8 }, { 0x003A, 8 }, - { 0x003B, 8 }, { 0x003C, 8 }, { 0x003D, 8 }, { 0x003E, 8 }, - { 0x003F, 8 }, - }, - { // 5 - { 0x0000, 10 }, { 0x0001, 10 }, { 0x0002, 10 }, { 0x0003, 10 }, - { 0x0004, 10 }, { 0x0005, 10 }, { 0x0006, 10 }, { 0x0007, 10 }, - { 0x0008, 10 }, { 0x0009, 10 }, { 0x000A, 10 }, { 0x000B, 10 }, - { 0x000C, 10 }, { 0x000D, 10 }, { 0x000E, 10 }, { 0x000F, 10 }, - { 0x0010, 10 }, { 0x0011, 10 }, { 0x0012, 10 }, { 0x0013, 10 }, - { 0x000A, 9 }, { 0x000B, 9 }, { 0x000C, 9 }, { 0x0001, 1 }, - { 0x0001, 3 }, { 0x000D, 9 }, { 0x000E, 9 }, { 0x0001, 2 }, - { 0x000F, 9 }, { 0x0010, 9 }, { 0x0011, 9 }, { 0x0012, 9 }, - { 0x0013, 9 }, { 0x0014, 9 }, { 0x0015, 9 }, { 0x0016, 9 }, - { 0x0017, 9 }, { 0x0018, 9 }, { 0x0019, 9 }, { 0x001A, 9 }, - { 0x001B, 9 }, { 0x001C, 9 }, { 0x001D, 9 }, { 0x001E, 9 }, - { 0x001F, 9 }, { 0x0020, 9 }, { 0x0021, 9 }, { 0x0022, 9 }, - { 0x0023, 9 }, { 0x0024, 9 }, { 0x0025, 9 }, { 0x0026, 9 }, - { 0x0027, 9 }, { 0x0028, 9 }, { 0x0029, 9 }, { 0x002A, 9 }, - { 0x002B, 9 }, { 0x002C, 9 }, { 0x002D, 9 }, { 0x002E, 9 }, - { 0x002F, 9 }, { 0x0030, 9 }, { 0x0031, 9 }, { 0x0032, 9 }, - { 0x0033, 9 }, { 0x0034, 9 }, { 0x0035, 9 }, { 0x0036, 9 }, - { 0x0037, 9 }, { 0x0038, 9 }, { 0x0039, 9 }, { 0x003A, 9 }, - { 0x003B, 9 }, { 0x003C, 9 }, { 0x003D, 9 }, { 0x003E, 9 }, - { 0x003F, 9 }, - }, - { // 6 - { 0x0000, 2 }, { 0x0004, 4 }, { 0x000A, 5 }, { 0x000B, 5 }, - { 0x0018, 6 }, { 0x0019, 6 }, { 0x0034, 7 }, { 0x006A, 8 }, - { 0x006B, 8 }, { 0x006C, 8 }, { 0x00DA, 9 }, { 0x00DB, 9 }, - { 0x01B8, 10 }, { 0x00DD, 9 }, { 0x01B9, 10 }, { 0x3780, 15 }, - { 0x0004, 3 }, { 0x000E, 5 }, { 0x001E, 6 }, { 0x001F, 6 }, - { 0x000A, 4 }, { 0x0058, 7 }, { 0x0017, 5 }, { 0x0018, 5 }, - { 0x0059, 7 }, { 0x005A, 7 }, { 0x005B, 7 }, { 0x00C8, 8 }, - { 0x0065, 7 }, { 0x0066, 7 }, { 0x00C9, 8 }, { 0x00CE, 8 }, - { 0x00CF, 8 }, { 0x00D0, 8 }, { 0x00D1, 8 }, { 0x00D2, 8 }, - { 0x00D3, 8 }, { 0x00DF, 9 }, { 0x00D4, 8 }, { 0x00D5, 8 }, - { 0x00D6, 8 }, { 0x01AE, 9 }, { 0x3781, 15 }, { 0x01BD, 10 }, - { 0x035E, 10 }, { 0x035F, 10 }, { 0x3782, 15 }, { 0x0360, 10 }, - { 0x0037, 6 }, { 0x01B1, 9 }, { 0x3783, 15 }, { 0x3784, 15 }, - { 0x000E, 4 }, { 0x003C, 6 }, { 0x0361, 10 }, { 0x3785, 15 }, - { 0x1BC3, 14 }, { 0x003D, 6 }, { 0x00D9, 8 }, { 0x1BC4, 14 }, - { 0x0368, 10 }, { 0x1BC5, 14 }, { 0x1BC6, 14 }, { 0x1BC7, 14 }, - { 0x1BC8, 14 }, { 0x00DB, 8 }, { 0x0369, 10 }, { 0x036A, 10 }, - { 0x1BC9, 14 }, { 0x1BCA, 14 }, { 0x1BCB, 14 }, { 0x1BCC, 14 }, - { 0x1BCD, 14 }, { 0x001F, 5 }, { 0x036B, 10 }, { 0x1BCE, 14 }, - { 0x1BCF, 14 }, - }, - { // 7 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0006, 5 }, { 0x0007, 5 }, - { 0x0010, 6 }, { 0x0044, 8 }, { 0x0023, 7 }, { 0x0012, 6 }, - { 0x0026, 7 }, { 0x08A0, 13 }, { 0x004E, 8 }, { 0x004F, 8 }, - { 0x08A1, 13 }, { 0x08A2, 13 }, { 0x08A3, 13 }, { 0x0050, 8 }, - { 0x0006, 4 }, { 0x000B, 5 }, { 0x0029, 7 }, { 0x0015, 6 }, - { 0x001C, 6 }, { 0x003A, 7 }, { 0x001E, 6 }, { 0x0004, 3 }, - { 0x0014, 5 }, { 0x0015, 5 }, { 0x000B, 4 }, { 0x001F, 6 }, - { 0x0030, 6 }, { 0x0031, 6 }, { 0x0019, 5 }, { 0x0051, 8 }, - { 0x0034, 6 }, { 0x0035, 6 }, { 0x0036, 6 }, { 0x0037, 6 }, - { 0x0076, 8 }, { 0x0077, 8 }, { 0x0070, 7 }, { 0x001D, 5 }, - { 0x0071, 7 }, { 0x0072, 7 }, { 0x08A4, 13 }, { 0x0073, 7 }, - { 0x00F0, 8 }, { 0x08A5, 13 }, { 0x08A6, 13 }, { 0x08A7, 13 }, - { 0x0079, 7 }, { 0x007A, 7 }, { 0x08A8, 13 }, { 0x08A9, 13 }, - { 0x00F1, 8 }, { 0x08AA, 13 }, { 0x08AB, 13 }, { 0x08AC, 13 }, - { 0x08AD, 13 }, { 0x00F6, 8 }, { 0x08AE, 13 }, { 0x007C, 7 }, - { 0x00F7, 8 }, { 0x08AF, 13 }, { 0x08B0, 13 }, { 0x08B1, 13 }, - { 0x08B2, 13 }, { 0x00FA, 8 }, { 0x08B3, 13 }, { 0x08B4, 13 }, - { 0x08B5, 13 }, { 0x08B6, 13 }, { 0x08B7, 13 }, { 0x00FB, 8 }, - { 0x045C, 12 }, { 0x003F, 6 }, { 0x045D, 12 }, { 0x045E, 12 }, - { 0x045F, 12 }, - }, -}; - -static const uint16_t x8_ac1_lowquant_table[8][77][2] = { - { // 0 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0003, 4 }, { 0x0008, 5 }, - { 0x0012, 6 }, { 0x0026, 7 }, { 0x0014, 6 }, { 0x004E, 8 }, - { 0x004F, 8 }, { 0x00A8, 9 }, { 0x0152, 10 }, { 0x00AA, 9 }, - { 0x00AB, 9 }, { 0x00AC, 9 }, { 0x2A60, 15 }, { 0x02A7, 11 }, - { 0x0006, 4 }, { 0x000B, 5 }, { 0x001C, 6 }, { 0x003A, 7 }, - { 0x000F, 5 }, { 0x003B, 7 }, { 0x0010, 5 }, { 0x0005, 3 }, - { 0x0009, 4 }, { 0x0011, 5 }, { 0x0018, 5 }, { 0x0019, 5 }, - { 0x001A, 5 }, { 0x0036, 6 }, { 0x0037, 6 }, { 0x0070, 7 }, - { 0x0057, 8 }, { 0x00E2, 8 }, { 0x00E3, 8 }, { 0x00E4, 8 }, - { 0x00E5, 8 }, { 0x00AD, 9 }, { 0x0398, 10 }, { 0x003A, 6 }, - { 0x0076, 7 }, { 0x00E7, 8 }, { 0x00EE, 8 }, { 0x00EF, 8 }, - { 0x0732, 11 }, { 0x039A, 10 }, { 0x0733, 11 }, { 0x2A61, 15 }, - { 0x0078, 7 }, { 0x1531, 14 }, { 0x1532, 14 }, { 0x1533, 14 }, - { 0x003D, 6 }, { 0x039B, 10 }, { 0x1534, 14 }, { 0x1535, 14 }, - { 0x1536, 14 }, { 0x0079, 7 }, { 0x1537, 14 }, { 0x00F8, 8 }, - { 0x01F2, 9 }, { 0x07CC, 11 }, { 0x03E7, 10 }, { 0x07CD, 11 }, - { 0x3E80, 14 }, { 0x00FB, 8 }, { 0x03E9, 10 }, { 0x3E81, 14 }, - { 0x3E82, 14 }, { 0x3E83, 14 }, { 0x3E84, 14 }, { 0x3E85, 14 }, - { 0x3E86, 14 }, { 0x003F, 6 }, { 0x01F5, 9 }, { 0x07D1, 11 }, - { 0x3E87, 14 }, - }, - { // 1 - { 0x0000, 2 }, { 0x0002, 3 }, { 0x0006, 4 }, { 0x000E, 5 }, - { 0x001E, 6 }, { 0x001F, 6 }, { 0x0040, 7 }, { 0x0082, 8 }, - { 0x0083, 8 }, { 0x0084, 8 }, { 0x010A, 9 }, { 0x010B, 9 }, - { 0x0430, 11 }, { 0x0431, 11 }, { 0x0432, 11 }, { 0x0433, 11 }, - { 0x0005, 3 }, { 0x0011, 5 }, { 0x0024, 6 }, { 0x004A, 7 }, - { 0x000C, 4 }, { 0x0026, 6 }, { 0x000D, 4 }, { 0x0087, 8 }, - { 0x010D, 9 }, { 0x0258, 10 }, { 0x012D, 9 }, { 0x0259, 10 }, - { 0x025C, 10 }, { 0x0974, 12 }, { 0x025E, 10 }, { 0x025F, 10 }, - { 0x0270, 10 }, { 0x0271, 10 }, { 0x04BB, 11 }, { 0x0975, 12 }, - { 0x0272, 10 }, { 0x09CC, 12 }, { 0x09CD, 12 }, { 0x4E70, 15 }, - { 0x4E71, 15 }, { 0x4E72, 15 }, { 0x4E73, 15 }, { 0x273A, 14 }, - { 0x273B, 14 }, { 0x273C, 14 }, { 0x04E8, 11 }, { 0x04E9, 11 }, - { 0x009E, 8 }, { 0x0275, 10 }, { 0x09D8, 12 }, { 0x273D, 14 }, - { 0x000E, 4 }, { 0x003C, 6 }, { 0x007A, 7 }, { 0x009F, 8 }, - { 0x0277, 10 }, { 0x003E, 6 }, { 0x00F6, 8 }, { 0x04ED, 11 }, - { 0x03DC, 10 }, { 0x273E, 14 }, { 0x07BA, 11 }, { 0x09D9, 12 }, - { 0x273F, 14 }, { 0x3DD8, 14 }, { 0x3DD9, 14 }, { 0x3DDA, 14 }, - { 0x3DDB, 14 }, { 0x3DDC, 14 }, { 0x3DDD, 14 }, { 0x3DDE, 14 }, - { 0x3DDF, 14 }, { 0x003F, 6 }, { 0x07BC, 11 }, { 0x07BD, 11 }, - { 0x03DF, 10 }, - }, - { // 2 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0006, 5 }, { 0x000E, 6 }, - { 0x001E, 7 }, { 0x003E, 8 }, { 0x003F, 8 }, { 0x0040, 8 }, - { 0x0104, 10 }, { 0x0083, 9 }, { 0x0105, 10 }, { 0x0108, 10 }, - { 0x4240, 16 }, { 0x010A, 10 }, { 0x010B, 10 }, { 0x4241, 16 }, - { 0x0003, 3 }, { 0x0009, 5 }, { 0x0011, 6 }, { 0x0043, 8 }, - { 0x0004, 3 }, { 0x000A, 5 }, { 0x000A, 4 }, { 0x002C, 7 }, - { 0x00B4, 9 }, { 0x00B5, 9 }, { 0x00B6, 9 }, { 0x00B7, 9 }, - { 0x00B8, 9 }, { 0x0172, 10 }, { 0x0173, 10 }, { 0x0174, 10 }, - { 0x0175, 10 }, { 0x0176, 10 }, { 0x0177, 10 }, { 0x00BC, 9 }, - { 0x017A, 10 }, { 0x0213, 11 }, { 0x4242, 16 }, { 0x017B, 10 }, - { 0x02F8, 11 }, { 0x017D, 10 }, { 0x02F9, 11 }, { 0x017E, 10 }, - { 0x4243, 16 }, { 0x02FE, 11 }, { 0x2122, 15 }, { 0x2123, 15 }, - { 0x0058, 7 }, { 0x0164, 9 }, { 0x2124, 15 }, { 0x2125, 15 }, - { 0x0006, 3 }, { 0x000E, 4 }, { 0x002D, 6 }, { 0x002E, 6 }, - { 0x00B3, 8 }, { 0x001E, 5 }, { 0x005E, 7 }, { 0x2126, 15 }, - { 0x2127, 15 }, { 0x2128, 15 }, { 0x2129, 15 }, { 0x02FF, 11 }, - { 0x212A, 15 }, { 0x0594, 11 }, { 0x0595, 11 }, { 0x0596, 11 }, - { 0x212B, 15 }, { 0x212C, 15 }, { 0x212D, 15 }, { 0x212E, 15 }, - { 0x212F, 15 }, { 0x001F, 5 }, { 0x0597, 11 }, { 0x00BE, 8 }, - { 0x00BF, 8 }, - }, - { // 3 - { 0x0000, 2 }, { 0x0002, 3 }, { 0x0006, 4 }, { 0x0007, 4 }, - { 0x0010, 5 }, { 0x0011, 5 }, { 0x0024, 6 }, { 0x0025, 6 }, - { 0x0026, 6 }, { 0x0027, 6 }, { 0x0050, 7 }, { 0x0051, 7 }, - { 0x00A4, 8 }, { 0x00A5, 8 }, { 0x00A6, 8 }, { 0x014E, 9 }, - { 0x000B, 4 }, { 0x002A, 6 }, { 0x0056, 7 }, { 0x014F, 9 }, - { 0x0030, 6 }, { 0x00AE, 8 }, { 0x0062, 7 }, { 0x0032, 6 }, - { 0x0033, 6 }, { 0x0034, 6 }, { 0x0035, 6 }, { 0x0036, 6 }, - { 0x0063, 7 }, { 0x006E, 7 }, { 0x006F, 7 }, { 0x0070, 7 }, - { 0x0071, 7 }, { 0x0072, 7 }, { 0x0073, 7 }, { 0x0074, 7 }, - { 0x00AF, 8 }, { 0x00EA, 8 }, { 0x01D6, 9 }, { 0x075C, 11 }, - { 0x03AF, 10 }, { 0x75D0, 15 }, { 0x75D1, 15 }, { 0x75D2, 15 }, - { 0x75D3, 15 }, { 0x75D4, 15 }, { 0x0076, 7 }, { 0x00EE, 8 }, - { 0x00EF, 8 }, { 0x0EBB, 12 }, { 0x01E0, 9 }, { 0x75D5, 15 }, - { 0x0079, 7 }, { 0x01E1, 9 }, { 0x75D6, 15 }, { 0x75D7, 15 }, - { 0x7880, 15 }, { 0x00F4, 8 }, { 0x0789, 11 }, { 0x003E, 6 }, - { 0x007B, 7 }, { 0x00F5, 8 }, { 0x00FC, 8 }, { 0x007F, 7 }, - { 0x01E3, 9 }, { 0x078A, 11 }, { 0x078B, 11 }, { 0x7881, 15 }, - { 0x7882, 15 }, { 0x7883, 15 }, { 0x3C42, 14 }, { 0x3C43, 14 }, - { 0x3C44, 14 }, { 0x00FD, 8 }, { 0x3C45, 14 }, { 0x3C46, 14 }, - { 0x3C47, 14 }, - }, - { // 4 - { 0x0000, 2 }, { 0x0004, 4 }, { 0x000A, 5 }, { 0x0016, 6 }, - { 0x0017, 6 }, { 0x0030, 7 }, { 0x0031, 7 }, { 0x0064, 8 }, - { 0x0065, 8 }, { 0x0066, 8 }, { 0x00CE, 9 }, { 0x00CF, 9 }, - { 0x01A0, 10 }, { 0x01A1, 10 }, { 0x1A20, 14 }, { 0x0689, 12 }, - { 0x0004, 3 }, { 0x000E, 5 }, { 0x001B, 6 }, { 0x0035, 7 }, - { 0x000A, 4 }, { 0x001E, 6 }, { 0x0016, 5 }, { 0x0017, 5 }, - { 0x001F, 6 }, { 0x0030, 6 }, { 0x0031, 6 }, { 0x0064, 7 }, - { 0x0065, 7 }, { 0x0069, 8 }, { 0x0066, 7 }, { 0x00CE, 8 }, - { 0x00CF, 8 }, { 0x00D0, 8 }, { 0x00D1, 8 }, { 0x00D2, 8 }, - { 0x01A6, 9 }, { 0x01A3, 10 }, { 0x034E, 10 }, { 0x006A, 7 }, - { 0x00D6, 8 }, { 0x01AE, 9 }, { 0x01AF, 9 }, { 0x034F, 10 }, - { 0x0345, 11 }, { 0x01B0, 9 }, { 0x01B1, 9 }, { 0x0364, 10 }, - { 0x006D, 7 }, { 0x00DC, 8 }, { 0x0D94, 12 }, { 0x0D95, 12 }, - { 0x000E, 4 }, { 0x003C, 6 }, { 0x00DD, 8 }, { 0x00DE, 8 }, - { 0x01B3, 9 }, { 0x003D, 6 }, { 0x00DF, 8 }, { 0x01F0, 9 }, - { 0x03E2, 10 }, { 0x03E3, 10 }, { 0x06CB, 11 }, { 0x03E4, 10 }, - { 0x07CA, 11 }, { 0x01F3, 9 }, { 0x01F4, 9 }, { 0x07CB, 11 }, - { 0x07D4, 11 }, { 0x1A21, 14 }, { 0x1A22, 14 }, { 0x07D5, 11 }, - { 0x1A23, 14 }, { 0x003F, 6 }, { 0x01F6, 9 }, { 0x01F7, 9 }, - { 0x03EB, 10 }, - }, - { // 5 - { 0x0000, 2 }, { 0x0002, 3 }, { 0x0006, 4 }, { 0x000E, 5 }, - { 0x000F, 5 }, { 0x0020, 6 }, { 0x0021, 6 }, { 0x0044, 7 }, - { 0x0045, 7 }, { 0x0046, 7 }, { 0x008E, 8 }, { 0x008F, 8 }, - { 0x0090, 8 }, { 0x0122, 9 }, { 0x0246, 10 }, { 0x0124, 9 }, - { 0x0005, 3 }, { 0x0013, 5 }, { 0x004A, 7 }, { 0x0093, 8 }, - { 0x0018, 5 }, { 0x004B, 7 }, { 0x0032, 6 }, { 0x001A, 5 }, - { 0x0033, 6 }, { 0x006C, 7 }, { 0x006D, 7 }, { 0x006E, 7 }, - { 0x00DE, 8 }, { 0x00DF, 8 }, { 0x0070, 7 }, { 0x00E2, 8 }, - { 0x00E3, 8 }, { 0x00E4, 8 }, { 0x00E5, 8 }, { 0x00E6, 8 }, - { 0x00E7, 8 }, { 0x0125, 9 }, { 0x01D0, 9 }, { 0x048E, 11 }, - { 0x091E, 12 }, { 0x091F, 12 }, { 0x7440, 15 }, { 0x1D11, 13 }, - { 0x7441, 15 }, { 0x7442, 15 }, { 0x00E9, 8 }, { 0x01D4, 9 }, - { 0x00EB, 8 }, { 0x03A3, 10 }, { 0x01D5, 9 }, { 0x1D12, 13 }, - { 0x001E, 5 }, { 0x0076, 7 }, { 0x01DC, 9 }, { 0x01DD, 9 }, - { 0x7443, 15 }, { 0x007C, 7 }, { 0x0745, 11 }, { 0x00EF, 8 }, - { 0x00FA, 8 }, { 0x00FB, 8 }, { 0x01F8, 9 }, { 0x00FD, 8 }, - { 0x07E4, 11 }, { 0x0FCA, 12 }, { 0x1D13, 13 }, { 0x7E58, 15 }, - { 0x7E59, 15 }, { 0x7E5A, 15 }, { 0x7E5B, 15 }, { 0x7E5C, 15 }, - { 0x7E5D, 15 }, { 0x007F, 7 }, { 0x3F2F, 14 }, { 0x07E6, 11 }, - { 0x07E7, 11 }, - }, - { // 6 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0003, 4 }, { 0x0008, 5 }, - { 0x0009, 5 }, { 0x0014, 6 }, { 0x0015, 6 }, { 0x002C, 7 }, - { 0x005A, 8 }, { 0x005B, 8 }, { 0x005C, 8 }, { 0x00BA, 9 }, - { 0x00BB, 9 }, { 0x00BC, 9 }, { 0x02F4, 11 }, { 0x05EA, 12 }, - { 0x0003, 3 }, { 0x0010, 5 }, { 0x0022, 6 }, { 0x0046, 7 }, - { 0x0009, 4 }, { 0x0028, 6 }, { 0x0015, 5 }, { 0x000B, 4 }, - { 0x0018, 5 }, { 0x0029, 6 }, { 0x0032, 6 }, { 0x0047, 7 }, - { 0x0066, 7 }, { 0x0067, 7 }, { 0x0068, 7 }, { 0x0069, 7 }, - { 0x006A, 7 }, { 0x005F, 8 }, { 0x00D6, 8 }, { 0x00D7, 8 }, - { 0x01B0, 9 }, { 0x00D9, 8 }, { 0x017B, 10 }, { 0x006D, 7 }, - { 0x00DC, 8 }, { 0x01B1, 9 }, { 0x06E8, 11 }, { 0x01BB, 9 }, - { 0x0375, 10 }, { 0x05EB, 12 }, { 0x01BC, 9 }, { 0x6E90, 15 }, - { 0x0038, 6 }, { 0x0072, 7 }, { 0x6E91, 15 }, { 0x6E92, 15 }, - { 0x001D, 5 }, { 0x0073, 7 }, { 0x01BD, 9 }, { 0x06F8, 11 }, - { 0x6E93, 15 }, { 0x003C, 6 }, { 0x01BF, 9 }, { 0x00F4, 8 }, - { 0x01EA, 9 }, { 0x037D, 10 }, { 0x03D6, 10 }, { 0x06F9, 11 }, - { 0x6E94, 15 }, { 0x00F6, 8 }, { 0x01EE, 9 }, { 0x6E95, 15 }, - { 0x6E96, 15 }, { 0x6E97, 15 }, { 0x374C, 14 }, { 0x374D, 14 }, - { 0x374E, 14 }, { 0x001F, 5 }, { 0x03D7, 10 }, { 0x01EF, 9 }, - { 0x374F, 14 }, - }, - { // 7 - { 0x0000, 2 }, { 0x0004, 4 }, { 0x000A, 5 }, { 0x0016, 6 }, - { 0x002E, 7 }, { 0x002F, 7 }, { 0x0060, 8 }, { 0x0061, 8 }, - { 0x00C4, 9 }, { 0x00C5, 9 }, { 0x00C6, 9 }, { 0x018E, 10 }, - { 0x31E0, 15 }, { 0x31E1, 15 }, { 0x31E2, 15 }, { 0x31E3, 15 }, - { 0x0004, 3 }, { 0x000D, 5 }, { 0x0019, 6 }, { 0x0038, 7 }, - { 0x000A, 4 }, { 0x001D, 6 }, { 0x000B, 4 }, { 0x0072, 8 }, - { 0x0073, 8 }, { 0x00F0, 9 }, { 0x01E2, 10 }, { 0x00F2, 9 }, - { 0x01E3, 10 }, { 0x00F3, 9 }, { 0x01E8, 10 }, { 0x01E9, 10 }, - { 0x31E4, 15 }, { 0x01EA, 10 }, { 0x031F, 11 }, { 0x03D6, 11 }, - { 0x31E5, 15 }, { 0x01EC, 10 }, { 0x31E6, 15 }, { 0x00F7, 9 }, - { 0x03D7, 11 }, { 0x31E7, 15 }, { 0x31E8, 15 }, { 0x03DA, 11 }, - { 0x03DB, 11 }, { 0x31E9, 15 }, { 0x03E0, 11 }, { 0x31EA, 15 }, - { 0x003F, 7 }, { 0x01F1, 10 }, { 0x31EB, 15 }, { 0x31EC, 15 }, - { 0x0006, 3 }, { 0x001C, 5 }, { 0x0074, 7 }, { 0x0075, 7 }, - { 0x00F9, 9 }, { 0x001E, 5 }, { 0x0076, 7 }, { 0x00FA, 9 }, - { 0x03E1, 11 }, { 0x31ED, 15 }, { 0x18F7, 14 }, { 0x1F60, 14 }, - { 0x1F61, 14 }, { 0x01DC, 9 }, { 0x01DD, 9 }, { 0x1F62, 14 }, - { 0x1F63, 14 }, { 0x1F64, 14 }, { 0x1F65, 14 }, { 0x1F66, 14 }, - { 0x1F67, 14 }, { 0x001F, 5 }, { 0x03ED, 11 }, { 0x00EF, 8 }, - { 0x01F7, 10 }, - }, -}; - -static const uint16_t x8_ac1_highquant_table[8][77][2] = { - { // 0 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0006, 5 }, { 0x0007, 5 }, - { 0x0008, 5 }, { 0x0009, 5 }, { 0x0014, 6 }, { 0x002A, 7 }, - { 0x0016, 6 }, { 0x002B, 7 }, { 0x005C, 8 }, { 0x002F, 7 }, - { 0x0030, 7 }, { 0x005D, 8 }, { 0x0062, 8 }, { 0x00C6, 9 }, - { 0x0007, 4 }, { 0x0019, 6 }, { 0x001A, 6 }, { 0x0036, 7 }, - { 0x0010, 5 }, { 0x006E, 8 }, { 0x0022, 6 }, { 0x0009, 4 }, - { 0x000A, 4 }, { 0x0016, 5 }, { 0x0023, 6 }, { 0x002E, 6 }, - { 0x002F, 6 }, { 0x0030, 6 }, { 0x0062, 7 }, { 0x0063, 7 }, - { 0x0064, 7 }, { 0x0065, 7 }, { 0x0066, 7 }, { 0x0067, 7 }, - { 0x0068, 7 }, { 0x0069, 7 }, { 0x006A, 7 }, { 0x006B, 7 }, - { 0x006C, 7 }, { 0x00C7, 9 }, { 0x00DE, 9 }, { 0x00DF, 9 }, - { 0x06D0, 11 }, { 0x01B5, 9 }, { 0x0037, 6 }, { 0x00DB, 8 }, - { 0x001C, 5 }, { 0x0074, 7 }, { 0x01D4, 9 }, { 0x01D5, 9 }, - { 0x0076, 7 }, { 0x0369, 10 }, { 0x3688, 14 }, { 0x3689, 14 }, - { 0x368A, 14 }, { 0x0077, 7 }, { 0x03AC, 10 }, { 0x0078, 7 }, - { 0x00F2, 8 }, { 0x01D7, 9 }, { 0x00F3, 8 }, { 0x007A, 7 }, - { 0x368B, 14 }, { 0x007B, 7 }, { 0x007C, 7 }, { 0x03AD, 10 }, - { 0x03E8, 10 }, { 0x368C, 14 }, { 0x368D, 14 }, { 0x03E9, 10 }, - { 0x368E, 14 }, { 0x003F, 6 }, { 0x01F5, 9 }, { 0x00FB, 8 }, - { 0x368F, 14 }, - }, - { // 1 - { 0x0000, 2 }, { 0x0004, 4 }, { 0x000A, 5 }, { 0x000B, 5 }, - { 0x0018, 6 }, { 0x0032, 7 }, { 0x0033, 7 }, { 0x0034, 7 }, - { 0x006A, 8 }, { 0x00D6, 9 }, { 0x00D7, 9 }, { 0x00D8, 9 }, - { 0x00D9, 9 }, { 0x3680, 15 }, { 0x01B5, 10 }, { 0x0369, 11 }, - { 0x0004, 3 }, { 0x000E, 5 }, { 0x001E, 6 }, { 0x0037, 7 }, - { 0x000A, 4 }, { 0x0016, 5 }, { 0x000C, 4 }, { 0x001F, 6 }, - { 0x005C, 7 }, { 0x005D, 7 }, { 0x00BC, 8 }, { 0x00BD, 8 }, - { 0x005F, 7 }, { 0x00D0, 8 }, { 0x00DB, 9 }, { 0x00D1, 8 }, - { 0x01A4, 9 }, { 0x01A5, 9 }, { 0x01A6, 9 }, { 0x01A7, 9 }, - { 0x0350, 10 }, { 0x06A2, 11 }, { 0x06A3, 11 }, { 0x01A9, 9 }, - { 0x01AA, 9 }, { 0x06AC, 11 }, { 0x3681, 15 }, { 0x0357, 10 }, - { 0x3682, 15 }, { 0x3683, 15 }, { 0x3684, 15 }, { 0x3685, 15 }, - { 0x0036, 6 }, { 0x00D6, 8 }, { 0x3686, 15 }, { 0x3687, 15 }, - { 0x000E, 4 }, { 0x006E, 7 }, { 0x00D7, 8 }, { 0x06AD, 11 }, - { 0x3688, 15 }, { 0x001E, 5 }, { 0x00DE, 8 }, { 0x06F8, 11 }, - { 0x037D, 10 }, { 0x3689, 15 }, { 0x368A, 15 }, { 0x368B, 15 }, - { 0x368C, 15 }, { 0x01BF, 9 }, { 0x368D, 15 }, { 0x1B47, 14 }, - { 0x37C8, 14 }, { 0x37C9, 14 }, { 0x37CA, 14 }, { 0x37CB, 14 }, - { 0x37CC, 14 }, { 0x001F, 5 }, { 0x37CD, 14 }, { 0x37CE, 14 }, - { 0x37CF, 14 }, - }, - { // 2 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0003, 4 }, { 0x0008, 5 }, - { 0x0012, 6 }, { 0x0026, 7 }, { 0x0014, 6 }, { 0x0027, 7 }, - { 0x00A8, 9 }, { 0x00A9, 9 }, { 0x0055, 8 }, { 0x2B00, 15 }, - { 0x00AD, 9 }, { 0x2B01, 15 }, { 0x2B02, 15 }, { 0x2B03, 15 }, - { 0x0003, 3 }, { 0x000B, 5 }, { 0x0040, 7 }, { 0x0041, 7 }, - { 0x0009, 4 }, { 0x0021, 6 }, { 0x0011, 5 }, { 0x000A, 4 }, - { 0x000B, 4 }, { 0x0018, 5 }, { 0x0032, 6 }, { 0x0033, 6 }, - { 0x0034, 6 }, { 0x0035, 6 }, { 0x006C, 7 }, { 0x0057, 8 }, - { 0x006D, 7 }, { 0x00DC, 8 }, { 0x0159, 10 }, { 0x00DD, 8 }, - { 0x01BC, 9 }, { 0x037A, 10 }, { 0x037B, 10 }, { 0x0038, 6 }, - { 0x0072, 7 }, { 0x01BE, 9 }, { 0x01BF, 9 }, { 0x00E6, 8 }, - { 0x039C, 10 }, { 0x01CF, 9 }, { 0x2B04, 15 }, { 0x2B05, 15 }, - { 0x0074, 7 }, { 0x01D4, 9 }, { 0x2B06, 15 }, { 0x2B07, 15 }, - { 0x001E, 5 }, { 0x00EB, 8 }, { 0x1584, 14 }, { 0x1585, 14 }, - { 0x1586, 14 }, { 0x003B, 6 }, { 0x01D5, 9 }, { 0x01F0, 9 }, - { 0x039D, 10 }, { 0x03E2, 10 }, { 0x1587, 14 }, { 0x1588, 14 }, - { 0x1589, 14 }, { 0x00F9, 8 }, { 0x158A, 14 }, { 0x158B, 14 }, - { 0x03E3, 10 }, { 0x158C, 14 }, { 0x158D, 14 }, { 0x01F4, 9 }, - { 0x158E, 14 }, { 0x003F, 6 }, { 0x00FB, 8 }, { 0x01F5, 9 }, - { 0x158F, 14 }, - }, - { // 3 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0006, 5 }, { 0x0007, 5 }, - { 0x0010, 6 }, { 0x0011, 6 }, { 0x0024, 7 }, { 0x0025, 7 }, - { 0x0013, 6 }, { 0x0014, 6 }, { 0x002A, 7 }, { 0x002B, 7 }, - { 0x00B0, 9 }, { 0x00B1, 9 }, { 0x002D, 7 }, { 0x0059, 8 }, - { 0x000C, 5 }, { 0x0017, 6 }, { 0x00D0, 9 }, { 0x0035, 7 }, - { 0x001B, 6 }, { 0x0038, 7 }, { 0x0039, 7 }, { 0x0004, 3 }, - { 0x0005, 3 }, { 0x000F, 5 }, { 0x0018, 5 }, { 0x001D, 6 }, - { 0x0032, 6 }, { 0x0033, 6 }, { 0x0068, 7 }, { 0x0069, 7 }, - { 0x0069, 8 }, { 0x00D4, 8 }, { 0x00D5, 8 }, { 0x00D6, 8 }, - { 0x006C, 7 }, { 0x0037, 6 }, { 0x006D, 7 }, { 0x0070, 7 }, - { 0x0039, 6 }, { 0x00D7, 8 }, { 0x00D1, 9 }, { 0x3880, 14 }, - { 0x3881, 14 }, { 0x3882, 14 }, { 0x0074, 7 }, { 0x01C5, 9 }, - { 0x0075, 7 }, { 0x00E3, 8 }, { 0x3883, 14 }, { 0x3884, 14 }, - { 0x00EC, 8 }, { 0x3885, 14 }, { 0x1C43, 13 }, { 0x1C44, 13 }, - { 0x1C45, 13 }, { 0x00ED, 8 }, { 0x1C46, 13 }, { 0x003C, 6 }, - { 0x0077, 7 }, { 0x01E8, 9 }, { 0x003E, 6 }, { 0x007B, 7 }, - { 0x1C47, 13 }, { 0x007E, 7 }, { 0x007F, 7 }, { 0x1C48, 13 }, - { 0x1C49, 13 }, { 0x1C4A, 13 }, { 0x1C4B, 13 }, { 0x1C4C, 13 }, - { 0x1C4D, 13 }, { 0x00F5, 8 }, { 0x1C4E, 13 }, { 0x01E9, 9 }, - { 0x1C4F, 13 }, - }, - { // 4 - { 0x0000, 2 }, { 0x0004, 4 }, { 0x000A, 5 }, { 0x000B, 5 }, - { 0x0018, 6 }, { 0x0019, 6 }, { 0x0034, 7 }, { 0x0035, 7 }, - { 0x0036, 7 }, { 0x006E, 8 }, { 0x00DE, 9 }, { 0x00DF, 9 }, - { 0x01C0, 10 }, { 0x01C1, 10 }, { 0x01C2, 10 }, { 0x3860, 15 }, - { 0x0004, 3 }, { 0x000F, 5 }, { 0x001D, 6 }, { 0x0039, 7 }, - { 0x000A, 4 }, { 0x002C, 6 }, { 0x002D, 6 }, { 0x000C, 4 }, - { 0x0017, 5 }, { 0x0034, 6 }, { 0x0035, 6 }, { 0x0036, 6 }, - { 0x006E, 7 }, { 0x006F, 7 }, { 0x0070, 7 }, { 0x0071, 7 }, - { 0x0071, 8 }, { 0x00E4, 8 }, { 0x00E5, 8 }, { 0x00E6, 8 }, - { 0x00E7, 8 }, { 0x00E8, 8 }, { 0x03A4, 10 }, { 0x0075, 7 }, - { 0x00EC, 8 }, { 0x01D3, 9 }, { 0x01DA, 9 }, { 0x03A5, 10 }, - { 0x03B6, 10 }, { 0x070D, 12 }, { 0x03B7, 10 }, { 0x070E, 12 }, - { 0x003C, 6 }, { 0x00EE, 8 }, { 0x3861, 15 }, { 0x3862, 15 }, - { 0x003D, 6 }, { 0x01DE, 9 }, { 0x3863, 15 }, { 0x3864, 15 }, - { 0x3865, 15 }, { 0x007C, 7 }, { 0x070F, 12 }, { 0x03BE, 10 }, - { 0x03BF, 10 }, { 0x3866, 15 }, { 0x0FA0, 12 }, { 0x07D1, 11 }, - { 0x3867, 15 }, { 0x00FB, 8 }, { 0x01F5, 9 }, { 0x7D08, 15 }, - { 0x0FA4, 12 }, { 0x7D09, 15 }, { 0x7D0A, 15 }, { 0x7D0B, 15 }, - { 0x3E86, 14 }, { 0x003F, 6 }, { 0x0FA5, 12 }, { 0x07D3, 11 }, - { 0x3E87, 14 }, - }, - { // 5 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0003, 4 }, { 0x0008, 5 }, - { 0x0009, 5 }, { 0x0014, 6 }, { 0x002A, 7 }, { 0x0056, 8 }, - { 0x02B8, 11 }, { 0x00AF, 9 }, { 0x02B9, 11 }, { 0x015D, 10 }, - { 0x02C0, 11 }, { 0x2C10, 15 }, { 0x2C11, 15 }, { 0x2C12, 15 }, - { 0x0006, 4 }, { 0x000E, 5 }, { 0x0017, 6 }, { 0x002D, 7 }, - { 0x000F, 5 }, { 0x0040, 7 }, { 0x0021, 6 }, { 0x0005, 3 }, - { 0x0009, 4 }, { 0x0011, 5 }, { 0x0018, 5 }, { 0x0019, 5 }, - { 0x001A, 5 }, { 0x0036, 6 }, { 0x0037, 6 }, { 0x0041, 7 }, - { 0x0059, 8 }, { 0x00E0, 8 }, { 0x00E1, 8 }, { 0x0071, 7 }, - { 0x00E4, 8 }, { 0x00B1, 9 }, { 0x02C2, 11 }, { 0x001D, 5 }, - { 0x0073, 7 }, { 0x00E5, 8 }, { 0x00F0, 8 }, { 0x0079, 7 }, - { 0x03C4, 10 }, { 0x01E3, 9 }, { 0x01E8, 9 }, { 0x2C13, 15 }, - { 0x007B, 7 }, { 0x2C14, 15 }, { 0x2C15, 15 }, { 0x2C16, 15 }, - { 0x007C, 7 }, { 0x02C3, 11 }, { 0x2C17, 15 }, { 0x160C, 14 }, - { 0x160D, 14 }, { 0x007D, 7 }, { 0x160E, 14 }, { 0x01E9, 9 }, - { 0x03C5, 10 }, { 0x03D4, 10 }, { 0x01EB, 9 }, { 0x160F, 14 }, - { 0x3D50, 14 }, { 0x00FC, 8 }, { 0x07AB, 11 }, { 0x3D51, 14 }, - { 0x3D52, 14 }, { 0x3D53, 14 }, { 0x3D54, 14 }, { 0x01FA, 9 }, - { 0x3D55, 14 }, { 0x007F, 7 }, { 0x01FB, 9 }, { 0x3D56, 14 }, - { 0x3D57, 14 }, - }, - { // 6 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0003, 4 }, { 0x0008, 5 }, - { 0x0009, 5 }, { 0x000A, 5 }, { 0x000B, 5 }, { 0x0018, 6 }, - { 0x0032, 7 }, { 0x000D, 5 }, { 0x0033, 7 }, { 0x0E00, 13 }, - { 0x0039, 7 }, { 0x0E01, 13 }, { 0x003A, 7 }, { 0x0E02, 13 }, - { 0x0008, 4 }, { 0x001E, 6 }, { 0x003B, 7 }, { 0x003E, 7 }, - { 0x0012, 5 }, { 0x003F, 7 }, { 0x0013, 5 }, { 0x0028, 6 }, - { 0x0029, 6 }, { 0x0054, 7 }, { 0x002B, 6 }, { 0x0055, 7 }, - { 0x0058, 7 }, { 0x0E03, 13 }, { 0x0059, 7 }, { 0x005A, 7 }, - { 0x0E04, 13 }, { 0x0E05, 13 }, { 0x0703, 12 }, { 0x005B, 7 }, - { 0x005C, 7 }, { 0x0704, 12 }, { 0x0705, 12 }, { 0x005D, 7 }, - { 0x0706, 12 }, { 0x0707, 12 }, { 0x0708, 12 }, { 0x0709, 12 }, - { 0x070A, 12 }, { 0x070B, 12 }, { 0x0018, 5 }, { 0x002F, 6 }, - { 0x000D, 4 }, { 0x0019, 5 }, { 0x070C, 12 }, { 0x0070, 7 }, - { 0x001D, 5 }, { 0x070D, 12 }, { 0x070E, 12 }, { 0x070F, 12 }, - { 0x0710, 12 }, { 0x0039, 6 }, { 0x0711, 12 }, { 0x003C, 6 }, - { 0x0712, 12 }, { 0x0713, 12 }, { 0x0714, 12 }, { 0x0715, 12 }, - { 0x0716, 12 }, { 0x003D, 6 }, { 0x0717, 12 }, { 0x0718, 12 }, - { 0x0719, 12 }, { 0x071A, 12 }, { 0x071B, 12 }, { 0x071C, 12 }, - { 0x071D, 12 }, { 0x001F, 5 }, { 0x071E, 12 }, { 0x0071, 7 }, - { 0x071F, 12 }, - }, - { // 7 - { 0x0000, 3 }, { 0x0002, 4 }, { 0x0006, 5 }, { 0x000E, 6 }, - { 0x000F, 6 }, { 0x0040, 8 }, { 0x0041, 8 }, { 0x0042, 8 }, - { 0x0218, 11 }, { 0x2190, 15 }, { 0x2191, 15 }, { 0x2192, 15 }, - { 0x2193, 15 }, { 0x2194, 15 }, { 0x2195, 15 }, { 0x2196, 15 }, - { 0x0005, 4 }, { 0x0011, 6 }, { 0x0024, 7 }, { 0x0087, 9 }, - { 0x000C, 5 }, { 0x004A, 8 }, { 0x004B, 8 }, { 0x0002, 2 }, - { 0x0006, 3 }, { 0x000D, 5 }, { 0x000E, 5 }, { 0x000F, 5 }, - { 0x0013, 6 }, { 0x0038, 6 }, { 0x00E4, 8 }, { 0x00E5, 8 }, - { 0x01CC, 9 }, { 0x00E7, 8 }, { 0x0074, 7 }, { 0x00EA, 8 }, - { 0x01CD, 9 }, { 0x021A, 11 }, { 0x2197, 15 }, { 0x001E, 5 }, - { 0x0076, 7 }, { 0x00EB, 8 }, { 0x01DC, 9 }, { 0x00EF, 8 }, - { 0x01DD, 9 }, { 0x01F0, 9 }, { 0x2198, 15 }, { 0x2199, 15 }, - { 0x00F9, 8 }, { 0x03E2, 10 }, { 0x219A, 15 }, { 0x219B, 15 }, - { 0x00FA, 8 }, { 0x219C, 15 }, { 0x219D, 15 }, { 0x219E, 15 }, - { 0x219F, 15 }, { 0x01F6, 9 }, { 0x21B0, 15 }, { 0x00FC, 8 }, - { 0x01F7, 9 }, { 0x21B1, 15 }, { 0x21B2, 15 }, { 0x21B3, 15 }, - { 0x21B4, 15 }, { 0x01FA, 9 }, { 0x21B5, 15 }, { 0x21B6, 15 }, - { 0x21B7, 15 }, { 0x21B8, 15 }, { 0x21B9, 15 }, { 0x03E3, 10 }, - { 0x10DD, 14 }, { 0x007F, 7 }, { 0x01FB, 9 }, { 0x10DE, 14 }, - { 0x10DF, 14 }, + { + { + { /* AC lowquant table group 0, table 0 */ + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, + { 5, 7 }, { 6, 7 }, { 7, 7 }, { 8, 9 }, { 12, 10 }, + { 13, 10 }, { 9, 8 }, { 10, 8 }, { 11, 8 }, { 14, 10 }, + { 15, 10 }, { 18, 9 }, { 19, 10 }, { 41, 10 }, { 40, 9 }, + { 17, 7 }, { 21, 7 }, { 20, 6 }, { 16, 4 }, { 22, 7 }, + { 32, 7 }, { 28, 6 }, { 25, 5 }, { 23, 4 }, { 24, 4 }, + { 26, 5 }, { 27, 5 }, { 29, 6 }, { 30, 6 }, { 31, 6 }, + { 33, 7 }, { 34, 7 }, { 35, 7 }, { 36, 7 }, { 37, 7 }, + { 38, 7 }, { 39, 8 }, { 42, 14 }, { 43, 14 }, { 44, 14 }, + { 45, 14 }, { 47, 14 }, { 49, 14 }, { 50, 14 }, { 51, 14 }, + { 53, 14 }, { 54, 14 }, { 55, 14 }, { 56, 14 }, { 58, 14 }, + { 63, 14 }, { 64, 14 }, { 65, 14 }, { 46, 10 }, { 48, 9 }, + { 52, 8 }, { 57, 10 }, { 66, 14 }, { 67, 14 }, { 68, 14 }, + { 69, 14 }, { 70, 14 }, { 71, 14 }, { 72, 13 }, { 73, 13 }, + { 74, 13 }, { 75, 13 }, { 76, 13 }, { 62, 9 }, { 59, 7 }, + { 60, 8 }, { 61, 8 }, + }, + { /* AC lowquant table group 0, table 1 */ + { 0, 3 }, { 1, 5 }, { 2, 7 }, { 5, 8 }, { 6, 8 }, + { 3, 6 }, { 4, 6 }, { 7, 8 }, { 8, 14 }, { 9, 14 }, + { 11, 14 }, { 12, 14 }, { 13, 14 }, { 14, 14 }, { 15, 14 }, + { 18, 14 }, { 20, 14 }, { 21, 14 }, { 22, 14 }, { 41, 14 }, + { 45, 14 }, { 46, 14 }, { 47, 14 }, { 49, 14 }, { 50, 14 }, + { 51, 14 }, { 52, 13 }, { 53, 13 }, { 54, 13 }, { 55, 13 }, + { 56, 13 }, { 57, 13 }, { 58, 13 }, { 60, 13 }, { 61, 13 }, + { 62, 13 }, { 63, 13 }, { 64, 13 }, { 66, 13 }, { 67, 13 }, + { 68, 13 }, { 69, 13 }, { 70, 13 }, { 71, 13 }, { 72, 13 }, + { 73, 13 }, { 74, 13 }, { 75, 13 }, { 76, 13 }, { 10, 7 }, + { 16, 6 }, { 17, 8 }, { 19, 8 }, { 30, 7 }, { 23, 2 }, + { 24, 3 }, { 25, 5 }, { 29, 6 }, { 31, 7 }, { 32, 7 }, + { 26, 4 }, { 27, 4 }, { 28, 4 }, { 33, 7 }, { 34, 8 }, + { 40, 8 }, { 35, 7 }, { 42, 8 }, { 43, 8 }, { 36, 6 }, + { 37, 6 }, { 38, 6 }, { 39, 6 }, { 44, 8 }, { 48, 8 }, + { 65, 7 }, { 59, 6 }, + }, + { /* AC lowquant table group 0, table 2 */ + { 0, 2 }, { 1, 3 }, { 2, 3 }, { 3, 4 }, { 4, 5 }, + { 5, 5 }, { 6, 6 }, { 7, 6 }, { 8, 7 }, { 9, 7 }, + { 10, 7 }, { 11, 8 }, { 12, 8 }, { 13, 8 }, { 14, 9 }, + { 15, 10 }, { 39, 16 }, { 40, 16 }, { 41, 15 }, { 43, 15 }, + { 44, 15 }, { 45, 15 }, { 50, 15 }, { 51, 15 }, { 53, 15 }, + { 42, 12 }, { 49, 12 }, { 54, 15 }, { 55, 15 }, { 56, 15 }, + { 58, 15 }, { 64, 15 }, { 65, 15 }, { 66, 15 }, { 67, 15 }, + { 18, 8 }, { 19, 9 }, { 21, 9 }, { 17, 6 }, { 20, 6 }, + { 22, 8 }, { 38, 8 }, { 27, 7 }, { 16, 4 }, { 23, 5 }, + { 24, 6 }, { 25, 6 }, { 26, 6 }, { 28, 7 }, { 29, 7 }, + { 30, 7 }, { 31, 7 }, { 32, 7 }, { 33, 7 }, { 34, 7 }, + { 35, 7 }, { 36, 7 }, { 37, 7 }, { 46, 8 }, { 47, 10 }, + { 62, 11 }, { 63, 12 }, { 68, 15 }, { 69, 15 }, { 70, 15 }, + { 71, 15 }, { 72, 15 }, { 74, 15 }, { 75, 15 }, { 76, 15 }, + { 48, 9 }, { 52, 8 }, { 57, 9 }, { 73, 9 }, { 59, 7 }, + { 60, 8 }, { 61, 8 }, + }, + { /* AC lowquant table group 0, table 3 */ + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 5 }, + { 5, 6 }, { 6, 6 }, { 7, 7 }, { 8, 7 }, { 9, 8 }, + { 10, 8 }, { 11, 9 }, { 12, 9 }, { 13, 9 }, { 14, 10 }, + { 15, 10 }, { 17, 5 }, { 18, 7 }, { 19, 7 }, { 21, 7 }, + { 24, 7 }, { 16, 3 }, { 20, 4 }, { 22, 5 }, { 23, 6 }, + { 25, 7 }, { 26, 7 }, { 27, 8 }, { 28, 8 }, { 29, 8 }, + { 30, 8 }, { 31, 8 }, { 32, 8 }, { 33, 9 }, { 37, 9 }, + { 34, 8 }, { 35, 8 }, { 36, 8 }, { 38, 11 }, { 40, 11 }, + { 39, 10 }, { 41, 15 }, { 43, 15 }, { 44, 15 }, { 45, 15 }, + { 50, 15 }, { 51, 15 }, { 64, 15 }, { 66, 15 }, { 49, 12 }, + { 47, 11 }, { 42, 10 }, { 46, 9 }, { 55, 10 }, { 56, 11 }, + { 63, 12 }, { 67, 15 }, { 68, 15 }, { 69, 15 }, { 70, 15 }, + { 71, 15 }, { 72, 15 }, { 74, 14 }, { 48, 7 }, { 53, 7 }, + { 52, 5 }, { 54, 8 }, { 58, 10 }, { 61, 10 }, { 62, 10 }, + { 65, 11 }, { 75, 12 }, { 76, 12 }, { 57, 7 }, { 59, 8 }, + { 60, 8 }, { 73, 7 }, + }, + { /* AC lowquant table group 0, table 4 */ + { 0, 3 }, { 1, 4 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, + { 5, 6 }, { 6, 6 }, { 7, 7 }, { 9, 7 }, { 8, 6 }, + { 10, 8 }, { 11, 8 }, { 12, 8 }, { 13, 9 }, { 14, 9 }, + { 15, 8 }, { 37, 8 }, { 31, 7 }, { 18, 6 }, { 17, 5 }, + { 16, 4 }, { 19, 6 }, { 21, 6 }, { 22, 5 }, { 20, 4 }, + { 23, 5 }, { 24, 6 }, { 25, 6 }, { 26, 6 }, { 27, 6 }, + { 28, 6 }, { 29, 6 }, { 30, 6 }, { 32, 7 }, { 33, 7 }, + { 34, 7 }, { 35, 7 }, { 36, 7 }, { 38, 11 }, { 50, 15 }, + { 51, 15 }, { 55, 15 }, { 56, 15 }, { 64, 15 }, { 69, 15 }, + { 70, 14 }, { 71, 14 }, { 72, 14 }, { 75, 14 }, { 76, 14 }, + { 45, 10 }, { 42, 9 }, { 41, 8 }, { 39, 7 }, { 40, 7 }, + { 43, 9 }, { 44, 9 }, { 46, 9 }, { 47, 10 }, { 58, 10 }, + { 49, 8 }, { 54, 9 }, { 62, 10 }, { 66, 10 }, { 48, 6 }, + { 53, 7 }, { 59, 7 }, { 52, 4 }, { 57, 6 }, { 60, 8 }, + { 61, 8 }, { 63, 9 }, { 65, 9 }, { 67, 10 }, { 68, 10 }, + { 74, 9 }, { 73, 5 }, + }, + { /* AC lowquant table group 0, table 5 */ + { 0, 2 }, { 1, 4 }, { 2, 5 }, { 3, 5 }, { 4, 6 }, + { 5, 6 }, { 6, 7 }, { 7, 8 }, { 8, 8 }, { 9, 8 }, + { 10, 9 }, { 11, 11 }, { 14, 11 }, { 13, 10 }, { 12, 8 }, + { 15, 15 }, { 42, 15 }, { 50, 15 }, { 51, 15 }, { 62, 15 }, + { 64, 15 }, { 67, 15 }, { 68, 15 }, { 69, 14 }, { 70, 14 }, + { 71, 14 }, { 72, 14 }, { 38, 11 }, { 40, 10 }, { 33, 9 }, + { 17, 5 }, { 18, 6 }, { 19, 7 }, { 24, 7 }, { 16, 3 }, + { 20, 4 }, { 21, 6 }, { 23, 6 }, { 22, 5 }, { 25, 8 }, + { 27, 8 }, { 26, 7 }, { 28, 7 }, { 29, 8 }, { 31, 8 }, + { 30, 7 }, { 32, 8 }, { 34, 9 }, { 35, 9 }, { 36, 9 }, + { 37, 9 }, { 39, 9 }, { 41, 11 }, { 44, 11 }, { 43, 10 }, + { 45, 11 }, { 47, 11 }, { 46, 10 }, { 56, 9 }, { 49, 8 }, + { 48, 6 }, { 54, 7 }, { 55, 7 }, { 53, 5 }, { 52, 4 }, + { 57, 6 }, { 58, 8 }, { 59, 8 }, { 60, 10 }, { 61, 11 }, + { 75, 11 }, { 63, 10 }, { 65, 10 }, { 66, 10 }, { 74, 10 }, + { 76, 9 }, { 73, 5 }, + }, + { /* AC lowquant table group 0, table 6 */ + { 0, 2 }, { 1, 4 }, { 2, 5 }, { 3, 6 }, { 4, 6 }, + { 5, 8 }, { 6, 9 }, { 7, 10 }, { 8, 10 }, { 9, 9 }, + { 10, 15 }, { 11, 15 }, { 13, 15 }, { 15, 15 }, { 37, 15 }, + { 46, 15 }, { 47, 15 }, { 49, 15 }, { 50, 15 }, { 51, 15 }, + { 53, 15 }, { 54, 15 }, { 55, 15 }, { 56, 15 }, { 58, 15 }, + { 60, 15 }, { 61, 15 }, { 62, 15 }, { 63, 15 }, { 64, 15 }, + { 67, 15 }, { 68, 15 }, { 69, 15 }, { 70, 15 }, { 71, 15 }, + { 72, 15 }, { 74, 14 }, { 75, 14 }, { 76, 14 }, { 12, 10 }, + { 14, 10 }, { 36, 10 }, { 21, 9 }, { 18, 8 }, { 19, 8 }, + { 22, 8 }, { 32, 8 }, { 17, 5 }, { 16, 4 }, { 20, 5 }, + { 26, 5 }, { 25, 4 }, { 23, 3 }, { 24, 3 }, { 27, 6 }, + { 28, 6 }, { 29, 7 }, { 30, 7 }, { 31, 7 }, { 33, 8 }, + { 34, 9 }, { 38, 9 }, { 35, 8 }, { 41, 9 }, { 42, 10 }, + { 45, 10 }, { 43, 8 }, { 44, 8 }, { 39, 6 }, { 40, 6 }, + { 48, 9 }, { 57, 9 }, { 52, 8 }, { 59, 9 }, { 65, 10 }, + { 66, 10 }, { 73, 8 }, + }, + { /* AC lowquant table group 0, table 7 */ + { 0, 4 }, { 1, 11 }, { 2, 11 }, { 3, 11 }, { 4, 11 }, + { 5, 11 }, { 6, 11 }, { 7, 11 }, { 8, 11 }, { 9, 11 }, + { 10, 11 }, { 11, 11 }, { 12, 11 }, { 13, 11 }, { 14, 11 }, + { 15, 11 }, { 16, 11 }, { 17, 10 }, { 18, 10 }, { 19, 10 }, + { 20, 10 }, { 21, 10 }, { 22, 10 }, { 25, 10 }, { 28, 10 }, + { 29, 10 }, { 30, 10 }, { 31, 10 }, { 32, 10 }, { 33, 10 }, + { 34, 10 }, { 35, 10 }, { 36, 10 }, { 37, 10 }, { 38, 10 }, + { 39, 10 }, { 40, 10 }, { 41, 10 }, { 42, 10 }, { 43, 10 }, + { 44, 10 }, { 45, 10 }, { 46, 10 }, { 47, 10 }, { 48, 10 }, + { 49, 10 }, { 50, 10 }, { 51, 10 }, { 52, 10 }, { 53, 10 }, + { 54, 10 }, { 55, 10 }, { 56, 10 }, { 57, 10 }, { 58, 10 }, + { 59, 10 }, { 60, 10 }, { 61, 10 }, { 62, 10 }, { 63, 10 }, + { 64, 10 }, { 65, 10 }, { 66, 10 }, { 67, 10 }, { 68, 10 }, + { 69, 10 }, { 70, 10 }, { 71, 10 }, { 72, 10 }, { 73, 10 }, + { 74, 10 }, { 75, 10 }, { 76, 10 }, { 26, 4 }, { 27, 4 }, + { 24, 2 }, { 23, 1 }, + }, + }, + { + { /* AC lowquant table group 1, table 0 */ + { 0, 3 }, { 1, 4 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, + { 5, 7 }, { 7, 8 }, { 8, 8 }, { 6, 6 }, { 9, 9 }, + { 10, 10 }, { 14, 15 }, { 47, 15 }, { 49, 14 }, { 50, 14 }, + { 51, 14 }, { 54, 14 }, { 55, 14 }, { 56, 14 }, { 58, 14 }, + { 15, 11 }, { 11, 9 }, { 12, 9 }, { 13, 9 }, { 37, 9 }, + { 32, 8 }, { 17, 5 }, { 16, 4 }, { 18, 6 }, { 19, 7 }, + { 21, 7 }, { 20, 5 }, { 22, 5 }, { 25, 5 }, { 24, 4 }, + { 23, 3 }, { 26, 5 }, { 27, 5 }, { 28, 5 }, { 29, 6 }, + { 30, 6 }, { 31, 7 }, { 33, 8 }, { 34, 8 }, { 35, 8 }, + { 36, 8 }, { 38, 10 }, { 44, 11 }, { 46, 11 }, { 45, 10 }, + { 53, 10 }, { 41, 8 }, { 39, 6 }, { 40, 7 }, { 42, 8 }, + { 43, 8 }, { 48, 7 }, { 57, 7 }, { 52, 6 }, { 59, 8 }, + { 60, 9 }, { 61, 11 }, { 63, 11 }, { 62, 10 }, { 64, 14 }, + { 67, 14 }, { 68, 14 }, { 69, 14 }, { 70, 14 }, { 71, 14 }, + { 72, 14 }, { 76, 14 }, { 75, 11 }, { 66, 10 }, { 74, 9 }, + { 65, 8 }, { 73, 6 }, + }, + { /* AC lowquant table group 1, table 1 */ + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, + { 5, 6 }, { 6, 7 }, { 7, 8 }, { 8, 8 }, { 9, 8 }, + { 10, 9 }, { 11, 9 }, { 12, 11 }, { 13, 11 }, { 14, 11 }, + { 15, 11 }, { 24, 9 }, { 23, 8 }, { 17, 5 }, { 18, 6 }, + { 19, 7 }, { 25, 10 }, { 27, 10 }, { 26, 9 }, { 28, 10 }, + { 29, 12 }, { 35, 12 }, { 34, 11 }, { 30, 10 }, { 31, 10 }, + { 21, 6 }, { 32, 10 }, { 33, 10 }, { 36, 10 }, { 37, 12 }, + { 38, 12 }, { 39, 15 }, { 40, 15 }, { 41, 15 }, { 42, 15 }, + { 43, 14 }, { 44, 14 }, { 45, 14 }, { 51, 14 }, { 61, 14 }, + { 64, 14 }, { 46, 11 }, { 47, 11 }, { 49, 10 }, { 50, 12 }, + { 63, 12 }, { 59, 11 }, { 56, 10 }, { 48, 8 }, { 55, 8 }, + { 16, 3 }, { 20, 4 }, { 22, 4 }, { 52, 4 }, { 53, 6 }, + { 54, 7 }, { 58, 8 }, { 60, 10 }, { 62, 11 }, { 65, 14 }, + { 66, 14 }, { 67, 14 }, { 68, 14 }, { 69, 14 }, { 70, 14 }, + { 71, 14 }, { 72, 14 }, { 74, 11 }, { 75, 11 }, { 76, 10 }, + { 57, 6 }, { 73, 6 }, + }, + { /* AC lowquant table group 1, table 2 */ + { 0, 3 }, { 1, 4 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, + { 5, 8 }, { 6, 8 }, { 7, 8 }, { 8, 10 }, { 10, 10 }, + { 9, 9 }, { 11, 10 }, { 12, 16 }, { 15, 16 }, { 38, 16 }, + { 44, 16 }, { 46, 15 }, { 47, 15 }, { 50, 15 }, { 51, 15 }, + { 59, 15 }, { 60, 15 }, { 61, 15 }, { 62, 15 }, { 64, 15 }, + { 68, 15 }, { 69, 15 }, { 70, 15 }, { 71, 15 }, { 72, 15 }, + { 37, 11 }, { 13, 10 }, { 14, 10 }, { 19, 8 }, { 18, 6 }, + { 17, 5 }, { 21, 5 }, { 23, 7 }, { 24, 9 }, { 25, 9 }, + { 26, 9 }, { 27, 9 }, { 28, 9 }, { 29, 10 }, { 30, 10 }, + { 31, 10 }, { 32, 10 }, { 33, 10 }, { 34, 10 }, { 35, 9 }, + { 36, 10 }, { 39, 10 }, { 40, 11 }, { 42, 11 }, { 41, 10 }, + { 43, 10 }, { 45, 11 }, { 63, 11 }, { 16, 3 }, { 20, 3 }, + { 22, 4 }, { 48, 7 }, { 49, 9 }, { 65, 11 }, { 66, 11 }, + { 67, 11 }, { 74, 11 }, { 56, 8 }, { 54, 6 }, { 55, 6 }, + { 58, 7 }, { 75, 8 }, { 76, 8 }, { 52, 3 }, { 53, 4 }, + { 57, 5 }, { 73, 5 }, + }, + { /* AC lowquant table group 1, table 3 */ + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, + { 5, 5 }, { 6, 6 }, { 7, 6 }, { 8, 6 }, { 9, 6 }, + { 10, 7 }, { 11, 7 }, { 12, 8 }, { 13, 8 }, { 14, 8 }, + { 15, 9 }, { 19, 9 }, { 17, 6 }, { 18, 7 }, { 21, 8 }, + { 36, 8 }, { 16, 4 }, { 20, 6 }, { 22, 7 }, { 28, 7 }, + { 23, 6 }, { 24, 6 }, { 25, 6 }, { 26, 6 }, { 27, 6 }, + { 29, 7 }, { 30, 7 }, { 31, 7 }, { 32, 7 }, { 33, 7 }, + { 34, 7 }, { 35, 7 }, { 37, 8 }, { 38, 9 }, { 39, 11 }, + { 41, 15 }, { 42, 15 }, { 43, 15 }, { 44, 15 }, { 45, 15 }, + { 51, 15 }, { 54, 15 }, { 55, 15 }, { 49, 12 }, { 40, 10 }, + { 46, 7 }, { 47, 8 }, { 48, 8 }, { 50, 9 }, { 53, 9 }, + { 56, 15 }, { 67, 15 }, { 68, 15 }, { 69, 15 }, { 70, 14 }, + { 71, 14 }, { 72, 14 }, { 74, 14 }, { 75, 14 }, { 76, 14 }, + { 58, 11 }, { 65, 11 }, { 66, 11 }, { 64, 9 }, { 52, 7 }, + { 57, 8 }, { 61, 8 }, { 60, 7 }, { 59, 6 }, { 62, 8 }, + { 73, 8 }, { 63, 7 }, + }, + { /* AC lowquant table group 1, table 4 */ + { 0, 2 }, { 1, 4 }, { 2, 5 }, { 3, 6 }, { 4, 6 }, + { 5, 7 }, { 6, 7 }, { 7, 8 }, { 8, 8 }, { 9, 8 }, + { 10, 9 }, { 11, 9 }, { 12, 10 }, { 13, 10 }, { 14, 14 }, + { 69, 14 }, { 70, 14 }, { 72, 14 }, { 15, 12 }, { 44, 11 }, + { 37, 10 }, { 29, 8 }, { 19, 7 }, { 18, 6 }, { 17, 5 }, + { 21, 6 }, { 24, 6 }, { 16, 3 }, { 20, 4 }, { 22, 5 }, + { 23, 5 }, { 25, 6 }, { 26, 6 }, { 27, 7 }, { 28, 7 }, + { 30, 7 }, { 31, 8 }, { 32, 8 }, { 33, 8 }, { 34, 8 }, + { 35, 8 }, { 36, 9 }, { 38, 10 }, { 43, 10 }, { 39, 7 }, + { 40, 8 }, { 41, 9 }, { 42, 9 }, { 45, 9 }, { 46, 9 }, + { 47, 10 }, { 50, 12 }, { 51, 12 }, { 62, 11 }, { 56, 9 }, + { 48, 7 }, { 49, 8 }, { 54, 8 }, { 55, 8 }, { 58, 8 }, + { 52, 4 }, { 53, 6 }, { 57, 6 }, { 59, 9 }, { 60, 10 }, + { 61, 10 }, { 63, 10 }, { 64, 11 }, { 67, 11 }, { 65, 9 }, + { 66, 9 }, { 68, 11 }, { 71, 11 }, { 76, 10 }, { 74, 9 }, + { 75, 9 }, { 73, 6 }, + }, + { /* AC lowquant table group 1, table 5 */ + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 5 }, + { 5, 6 }, { 6, 6 }, { 7, 7 }, { 8, 7 }, { 9, 7 }, + { 10, 8 }, { 11, 8 }, { 12, 8 }, { 13, 9 }, { 14, 10 }, + { 39, 11 }, { 40, 12 }, { 41, 12 }, { 15, 9 }, { 37, 9 }, + { 19, 8 }, { 18, 7 }, { 21, 7 }, { 17, 5 }, { 16, 3 }, + { 20, 5 }, { 22, 6 }, { 24, 6 }, { 23, 5 }, { 25, 7 }, + { 26, 7 }, { 27, 7 }, { 28, 8 }, { 29, 8 }, { 30, 7 }, + { 31, 8 }, { 32, 8 }, { 33, 8 }, { 34, 8 }, { 35, 8 }, + { 36, 8 }, { 38, 9 }, { 42, 15 }, { 44, 15 }, { 45, 15 }, + { 56, 15 }, { 43, 13 }, { 51, 13 }, { 66, 13 }, { 58, 11 }, + { 49, 10 }, { 46, 8 }, { 47, 9 }, { 50, 9 }, { 48, 8 }, + { 53, 7 }, { 54, 9 }, { 55, 9 }, { 59, 8 }, { 52, 5 }, + { 57, 7 }, { 60, 8 }, { 61, 8 }, { 62, 9 }, { 64, 11 }, + { 65, 12 }, { 67, 15 }, { 68, 15 }, { 69, 15 }, { 70, 15 }, + { 71, 15 }, { 72, 15 }, { 74, 14 }, { 75, 11 }, { 76, 11 }, + { 63, 8 }, { 73, 7 }, + }, + { /* AC lowquant table group 1, table 6 */ + { 0, 3 }, { 1, 4 }, { 2, 4 }, { 3, 5 }, { 4, 5 }, + { 5, 6 }, { 6, 6 }, { 7, 7 }, { 8, 8 }, { 9, 8 }, + { 10, 8 }, { 11, 9 }, { 12, 9 }, { 13, 9 }, { 14, 11 }, + { 15, 12 }, { 45, 12 }, { 38, 10 }, { 33, 8 }, { 16, 3 }, + { 17, 5 }, { 18, 6 }, { 19, 7 }, { 27, 7 }, { 20, 4 }, + { 21, 6 }, { 25, 6 }, { 22, 5 }, { 23, 4 }, { 24, 5 }, + { 26, 6 }, { 28, 7 }, { 29, 7 }, { 30, 7 }, { 31, 7 }, + { 32, 7 }, { 34, 8 }, { 35, 8 }, { 36, 9 }, { 41, 9 }, + { 37, 8 }, { 39, 7 }, { 40, 8 }, { 42, 11 }, { 47, 15 }, + { 50, 15 }, { 51, 15 }, { 56, 15 }, { 64, 15 }, { 67, 15 }, + { 68, 15 }, { 69, 15 }, { 70, 14 }, { 71, 14 }, { 72, 14 }, + { 76, 14 }, { 44, 10 }, { 43, 9 }, { 46, 9 }, { 54, 9 }, + { 55, 11 }, { 63, 11 }, { 61, 10 }, { 58, 9 }, { 48, 6 }, + { 49, 7 }, { 53, 7 }, { 52, 5 }, { 57, 6 }, { 59, 8 }, + { 60, 9 }, { 62, 10 }, { 74, 10 }, { 65, 8 }, { 66, 9 }, + { 75, 9 }, { 73, 5 }, + }, + { /* AC lowquant table group 1, table 7 */ + { 0, 2 }, { 1, 4 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, + { 5, 7 }, { 6, 8 }, { 7, 8 }, { 8, 9 }, { 9, 9 }, + { 10, 9 }, { 11, 10 }, { 12, 15 }, { 13, 15 }, { 14, 15 }, + { 15, 15 }, { 32, 15 }, { 36, 15 }, { 38, 15 }, { 41, 15 }, + { 42, 15 }, { 45, 15 }, { 47, 15 }, { 50, 15 }, { 51, 15 }, + { 61, 15 }, { 62, 14 }, { 34, 11 }, { 18, 6 }, { 17, 5 }, + { 19, 7 }, { 23, 8 }, { 24, 8 }, { 21, 6 }, { 25, 9 }, + { 26, 10 }, { 28, 10 }, { 27, 9 }, { 29, 9 }, { 30, 10 }, + { 31, 10 }, { 33, 10 }, { 35, 11 }, { 40, 11 }, { 37, 10 }, + { 43, 11 }, { 44, 11 }, { 39, 9 }, { 46, 11 }, { 60, 11 }, + { 49, 10 }, { 56, 9 }, { 59, 9 }, { 63, 14 }, { 64, 14 }, + { 67, 14 }, { 68, 14 }, { 69, 14 }, { 70, 14 }, { 71, 14 }, + { 72, 14 }, { 74, 11 }, { 76, 10 }, { 48, 7 }, { 16, 3 }, + { 20, 4 }, { 22, 4 }, { 52, 3 }, { 53, 5 }, { 54, 7 }, + { 55, 7 }, { 58, 7 }, { 65, 9 }, { 66, 9 }, { 75, 8 }, + { 57, 5 }, { 73, 5 }, + }, + }, }, }; #define MAX_AC_VLC_BITS 16 diff --git a/libavcodec/ipu_parser.c b/libavcodec/ipu_parser.c new file mode 100644 index 000000000..c22172f0b --- /dev/null +++ b/libavcodec/ipu_parser.c @@ -0,0 +1,77 @@ +/* + * IPU parser + * Copyright (c) 2020 Paul B Mahol + * + * 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 + * IPU parser + */ + +#include "parser.h" + +typedef struct IPUParseContext { + ParseContext pc; +} IPUParseContext; + +static int ipu_parse(AVCodecParserContext *s, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + IPUParseContext *ipc = s->priv_data; + uint32_t state = ipc->pc.state; + int next = END_NOT_FOUND, i = 0; + + s->pict_type = AV_PICTURE_TYPE_NONE; + s->duration = 1; + + *poutbuf_size = 0; + *poutbuf = NULL; + + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + for (; i < buf_size; i++) { + state = (state << 8) | buf[i]; + if (state == 0x1b0) { + next = i + 1; + break; + } + } + + ipc->pc.state = state; + if (ff_combine_frame(&ipc->pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + + return next; +} + +AVCodecParser ff_ipu_parser = { + .codec_ids = { AV_CODEC_ID_IPU }, + .priv_data_size = sizeof(IPUParseContext), + .parser_parse = ipu_parse, + .parser_close = ff_parse_close, +}; diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c index c1005b099..565a6a1ac 100644 --- a/libavcodec/ituh263dec.c +++ b/libavcodec/ituh263dec.c @@ -34,6 +34,7 @@ #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/mathematics.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "mpegvideo.h" #include "h263.h" @@ -51,7 +52,6 @@ // 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 MV_VLC_BITS 9 #define H263_MBTYPE_B_VLC_BITS 6 #define CBPC_B_VLC_BITS 3 @@ -98,7 +98,7 @@ void ff_h263_show_pict_info(MpegEncContext *s){ VLC ff_h263_intra_MCBPC_vlc; VLC ff_h263_inter_MCBPC_vlc; VLC ff_h263_cbpy_vlc; -static VLC mv_vlc; +VLC ff_h263_mv_vlc; static VLC h263_mbtype_b_vlc; static VLC cbpc_b_vlc; @@ -119,13 +119,12 @@ av_cold void ff_h263_decode_init_vlc(void) INIT_VLC_STATIC(&ff_h263_cbpy_vlc, CBPY_VLC_BITS, 16, &ff_h263_cbpy_tab[0][1], 2, 1, &ff_h263_cbpy_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 33, + INIT_VLC_STATIC(&ff_h263_mv_vlc, H263_MV_VLC_BITS, 33, &ff_mvtab[0][1], 2, 1, &ff_mvtab[0][0], 2, 1, 538); - ff_rl_init(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); - ff_rl_init(&ff_rl_intra_aic, ff_h263_static_rl_table_store[1]); + ff_h263_init_rl_inter(); INIT_VLC_RL(ff_h263_rl_inter, 554); - INIT_VLC_RL(ff_rl_intra_aic, 554); + INIT_FIRST_VLC_RL(ff_rl_intra_aic, 554); INIT_VLC_STATIC(&h263_mbtype_b_vlc, H263_MBTYPE_B_VLC_BITS, 15, &ff_h263_mbtype_b_tab[0][1], 2, 1, &ff_h263_mbtype_b_tab[0][0], 2, 1, 80); @@ -270,7 +269,7 @@ int ff_h263_resync(MpegEncContext *s){ int ff_h263_decode_motion(MpegEncContext * s, int pred, int f_code) { int code, val, sign, shift; - code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); + code = get_vlc2(&s->gb, ff_h263_mv_vlc.table, H263_MV_VLC_BITS, 2); if (code == 0) return pred; @@ -467,7 +466,7 @@ static int h263_decode_block(MpegEncContext * s, int16_t * block, level = s->last_dc[component]; if (s->rv10_first_dc_coded[component]) { diff = ff_rv_decode_dc(s, n); - if (diff == 0xffff) + if (diff < 0) return -1; level += diff; level = level & 0xff; /* handle wrap round */ diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c index ee09f2974..43260e698 100644 --- a/libavcodec/ituh263enc.c +++ b/libavcodec/ituh263enc.c @@ -124,7 +124,7 @@ void ff_h263_encode_picture_header(MpegEncContext * s, int picture_number) coded_frame_rate= 1800000; coded_frame_rate_base= (1000+best_clock_code)*best_divisor; - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); /* Update the pointer to last GOB */ s->ptr_lastgob = put_bits_ptr(&s->pb); @@ -713,8 +713,7 @@ static av_cold void init_mv_penalty_and_fcode(MpegEncContext *s) } } -static av_cold 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(const RLTable *rl, uint8_t *len_tab) { int slevel, run, last; @@ -738,10 +737,9 @@ static av_cold void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, len= rl->table_vlc[code][1]; bits=bits*2+sign; len++; - if(code!=rl->n && len < len_tab[index]){ - if(bits_tab) bits_tab[index]= bits; + if (code != rl->n && len < len_tab[index]) len_tab [index]= len; - } + /* ESC */ bits= rl->table_vlc[rl->n][0]; len = rl->table_vlc[rl->n][1]; @@ -749,10 +747,8 @@ static av_cold void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, bits=bits*64+run; len+=6; bits=bits*256+(level&0xff); len+=8; - if(len < len_tab[index]){ - if(bits_tab) bits_tab[index]= bits; + if (len < len_tab[index]) len_tab [index]= len; - } } } } @@ -763,13 +759,14 @@ av_cold void ff_h263_encode_init(MpegEncContext *s) static int done = 0; if (!done) { + static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3]; done = 1; - ff_rl_init(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); - ff_rl_init(&ff_rl_intra_aic, ff_h263_static_rl_table_store[1]); + ff_rl_init(&ff_rl_intra_aic, rl_intra_table); + ff_h263_init_rl_inter(); - init_uni_h263_rl_tab(&ff_rl_intra_aic, NULL, uni_h263_intra_aic_rl_len); - init_uni_h263_rl_tab(&ff_h263_rl_inter , NULL, uni_h263_inter_rl_len); + init_uni_h263_rl_tab(&ff_rl_intra_aic, uni_h263_intra_aic_rl_len); + init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len); init_mv_penalty_and_fcode(s); } diff --git a/libavcodec/ivi.c b/libavcodec/ivi.c index c5c50fb5c..a5074e998 100644 --- a/libavcodec/ivi.c +++ b/libavcodec/ivi.c @@ -30,12 +30,12 @@ #include "libavutil/attributes.h" #include "libavutil/imgutils.h" +#include "libavutil/thread.h" #define BITSTREAM_READER_LE #include "avcodec.h" #include "get_bits.h" #include "internal.h" -#include "mathops.h" #include "ivi.h" #include "ivi_dsp.h" @@ -115,23 +115,6 @@ static int ivi_mc(const IVIBandDesc *band, ivi_mc_func mc, ivi_mc_avg_func mc_av return 0; } -/** - * Reverse "nbits" bits of the value "val" and return the result - * in the least significant bits. - */ -static uint16_t inv_bits(uint16_t val, int nbits) -{ - uint16_t res; - - if (nbits <= 8) { - res = ff_reverse[val] >> (8 - nbits); - } else - res = ((ff_reverse[val & 0xFF] << 8) + - (ff_reverse[val >> 8])) >> (16 - nbits); - - return res; -} - /* * Generate a huffman codebook from the given descriptor * and convert it into the FFmpeg VLC table. @@ -162,7 +145,7 @@ static int ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag) if (bits[pos] > IVI_VLC_BITS) return AVERROR_INVALIDDATA; /* invalid descriptor */ - codewords[pos] = inv_bits((prefix | j), bits[pos]); + codewords[pos] = prefix | j; if (!bits[pos]) bits[pos] = 1; @@ -172,17 +155,14 @@ static int ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag) /* number of codewords = pos */ return init_vlc(vlc, IVI_VLC_BITS, pos, bits, 1, 1, codewords, 2, 2, - (flag ? INIT_VLC_USE_NEW_STATIC : 0) | INIT_VLC_LE); + (flag ? INIT_VLC_USE_NEW_STATIC : 0) | INIT_VLC_OUTPUT_LE); } -av_cold void ff_ivi_init_static_vlc(void) +static av_cold void ivi_init_static_vlc(void) { int i; static VLC_TYPE table_data[8192 * 16][2]; - static int initialized_vlcs = 0; - if (initialized_vlcs) - return; 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; @@ -193,7 +173,12 @@ av_cold void ff_ivi_init_static_vlc(void) ivi_create_huff_from_desc(&ivi_blk_huff_desc[i], &ivi_blk_vlc_tabs[i], 1); } - initialized_vlcs = 1; +} + +av_cold void ff_ivi_init_static_vlc(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, ivi_init_static_vlc); } /* @@ -442,8 +427,10 @@ av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, av_freep(&band->tiles); band->tiles = av_mallocz_array(band->num_tiles, sizeof(IVITile)); - if (!band->tiles) + if (!band->tiles) { + band->num_tiles = 0; return AVERROR(ENOMEM); + } /* use the first luma band as reference for motion vectors * and quant */ diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index 38643c9a2..e3c5a3218 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -32,6 +32,7 @@ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team * Copyright (c) 2007, Callum Lerwick + * Copyright (c) 2020, Gautam Ramakrishnan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -72,6 +73,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/opt.h" #include "libavutil/intreadwrite.h" +#include "libavutil/avstring.h" #define NMSEDEC_BITS 7 #define NMSEDEC_FRACBITS (NMSEDEC_BITS-1) @@ -100,6 +102,7 @@ static const int dwt_norms[2][4][10] = { // [dwt_type][band][rlevel] (multiplied typedef struct { Jpeg2000Component *comp; + double *layer_rates; } Jpeg2000Tile; typedef struct { @@ -126,9 +129,16 @@ typedef struct { Jpeg2000QuantStyle qntsty; Jpeg2000Tile *tile; + int layer_rates[100]; + uint8_t compression_rate_enc; ///< Is compression done using compression ratio? int format; int pred; + int sop; + int eph; + int prog; + int nlayers; + char *lr_str; } Jpeg2000EncoderContext; @@ -239,27 +249,36 @@ static void j2k_flush(Jpeg2000EncoderContext *s) static void tag_tree_code(Jpeg2000EncoderContext *s, Jpeg2000TgtNode *node, int threshold) { Jpeg2000TgtNode *stack[30]; - int sp = 1, curval = 0; - stack[0] = node; + int sp = -1, curval = 0; - node = node->parent; - while(node){ - if (node->vis){ - curval = node->val; - break; - } - node->vis++; - stack[sp++] = node; + while(node->parent){ + stack[++sp] = node; node = node->parent; } - while(--sp >= 0){ - if (stack[sp]->val >= threshold){ - put_bits(s, 0, threshold - curval); - break; + + while (1) { + if (curval > node->temp_val) + node->temp_val = curval; + else { + curval = node->temp_val; } - put_bits(s, 0, stack[sp]->val - curval); - put_bits(s, 1, 1); - curval = stack[sp]->val; + + if (node->val >= threshold) { + put_bits(s, 0, threshold - curval); + curval = threshold; + } else { + put_bits(s, 0, node->val - curval); + curval = node->val; + if (!node->vis) { + put_bits(s, 1, 1); + node->vis = 1; + } + } + + node->temp_val = curval; + if (sp < 0) + break; + node = stack[sp--]; } } @@ -298,7 +317,7 @@ static int put_siz(Jpeg2000EncoderContext *s) bytestream_put_be16(&s->buf, s->ncomponents); // CSiz for (i = 0; i < s->ncomponents; i++){ // Ssiz_i XRsiz_i, YRsiz_i - bytestream_put_byte(&s->buf, 7); + bytestream_put_byte(&s->buf, s->cbps[i] - 1); bytestream_put_byte(&s->buf, i?1<chroma_shift[0]:1); bytestream_put_byte(&s->buf, i?1<chroma_shift[1]:1); } @@ -308,16 +327,21 @@ static int put_siz(Jpeg2000EncoderContext *s) static int put_cod(Jpeg2000EncoderContext *s) { Jpeg2000CodingStyle *codsty = &s->codsty; + uint8_t scod = 0; if (s->buf_end - s->buf < 14) return -1; bytestream_put_be16(&s->buf, JPEG2000_COD); bytestream_put_be16(&s->buf, 12); // Lcod - bytestream_put_byte(&s->buf, 0); // Scod + if (s->sop) + scod |= JPEG2000_CSTY_SOP; + if (s->eph) + scod |= JPEG2000_CSTY_EPH; + bytestream_put_byte(&s->buf, scod); // Scod // SGcod - bytestream_put_byte(&s->buf, 0); // progression level - bytestream_put_be16(&s->buf, 1); // num of layers + bytestream_put_byte(&s->buf, s->prog); // progression level + bytestream_put_be16(&s->buf, s->nlayers); // num of layers if(s->avctx->pix_fmt == AV_PIX_FMT_YUV444P){ bytestream_put_byte(&s->buf, 0); // unspecified }else{ @@ -396,6 +420,31 @@ static uint8_t *put_sot(Jpeg2000EncoderContext *s, int tileno) return psotptr; } +static void compute_rates(Jpeg2000EncoderContext* s) +{ + int i, j; + int layno, compno; + for (i = 0; i < s->numYtiles; i++) { + for (j = 0; j < s->numXtiles; j++) { + Jpeg2000Tile *tile = &s->tile[s->numXtiles * i + j]; + for (compno = 0; compno < s->ncomponents; compno++) { + int tilew = tile->comp[compno].coord[0][1] - tile->comp[compno].coord[0][0]; + int tileh = tile->comp[compno].coord[1][1] - tile->comp[compno].coord[1][0]; + int scale = (compno?1 << s->chroma_shift[0]:1) * (compno?1 << s->chroma_shift[1]:1); + for (layno = 0; layno < s->nlayers; layno++) { + if (s->layer_rates[layno] > 0) { + tile->layer_rates[layno] += (double)(tilew * tileh) * s->ncomponents * s->cbps[compno] / + (double)(s->layer_rates[layno] * 8 * scale); + } else { + tile->layer_rates[layno] = 0.0; + } + } + } + } + } + +} + /** * compute the sizes of tiles, resolution levels, bands, etc. * allocate memory for them @@ -410,7 +459,7 @@ static int init_tiles(Jpeg2000EncoderContext *s) s->numXtiles = ff_jpeg2000_ceildiv(s->width, s->tile_width); s->numYtiles = ff_jpeg2000_ceildiv(s->height, s->tile_height); - s->tile = av_malloc_array(s->numXtiles, s->numYtiles * sizeof(Jpeg2000Tile)); + s->tile = av_calloc(s->numXtiles, s->numYtiles * sizeof(Jpeg2000Tile)); if (!s->tile) return AVERROR(ENOMEM); for (tileno = 0, tiley = 0; tiley < s->numYtiles; tiley++) @@ -420,6 +469,11 @@ static int init_tiles(Jpeg2000EncoderContext *s) tile->comp = av_mallocz_array(s->ncomponents, sizeof(Jpeg2000Component)); if (!tile->comp) return AVERROR(ENOMEM); + + tile->layer_rates = av_mallocz_array(s->nlayers, sizeof(*tile->layer_rates)); + if (!tile->layer_rates) + return AVERROR(ENOMEM); + for (compno = 0; compno < s->ncomponents; compno++){ Jpeg2000Component *comp = tile->comp + compno; int ret, i, j; @@ -444,46 +498,53 @@ static int init_tiles(Jpeg2000EncoderContext *s) return ret; } } + compute_rates(s); return 0; } -static void copy_frame(Jpeg2000EncoderContext *s) -{ - int tileno, compno, i, y, x; - uint8_t *line; - for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ - Jpeg2000Tile *tile = s->tile + tileno; - if (s->planar){ - for (compno = 0; compno < s->ncomponents; 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]; - } - } - } else{ - 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; - for (y = tile->comp[0].coord[1][0]; y < tile->comp[0].coord[1][1]; y++){ - 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].i_data[i] = *ptr++ - (1 << 7); - } - } - line += s->picture->linesize[0]; - } - } +#define COPY_FRAME(D, PIXEL) \ + static void copy_frame_ ##D(Jpeg2000EncoderContext *s) \ + { \ + int tileno, compno, i, y, x; \ + PIXEL *line; \ + for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ \ + Jpeg2000Tile *tile = s->tile + tileno; \ + if (s->planar){ \ + for (compno = 0; compno < s->ncomponents; compno++){ \ + Jpeg2000Component *comp = tile->comp + compno; \ + int *dst = comp->i_data; \ + int cbps = s->cbps[compno]; \ + line = (PIXEL*)s->picture->data[compno] \ + + comp->coord[1][0] * (s->picture->linesize[compno] / sizeof(PIXEL)) \ + + comp->coord[0][0]; \ + for (y = comp->coord[1][0]; y < comp->coord[1][1]; y++){ \ + PIXEL *ptr = line; \ + for (x = comp->coord[0][0]; x < comp->coord[0][1]; x++) \ + *dst++ = *ptr++ - (1 << (cbps - 1)); \ + line += s->picture->linesize[compno] / sizeof(PIXEL); \ + } \ + } \ + } else{ \ + line = (PIXEL*)s->picture->data[0] + tile->comp[0].coord[1][0] * (s->picture->linesize[0] / sizeof(PIXEL)) \ + + tile->comp[0].coord[0][0] * s->ncomponents; \ + \ + i = 0; \ + for (y = tile->comp[0].coord[1][0]; y < tile->comp[0].coord[1][1]; y++){ \ + PIXEL *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++){ \ + int cbps = s->cbps[compno]; \ + tile->comp[compno].i_data[i] = *ptr++ - (1 << (cbps - 1)); \ + } \ + } \ + line += s->picture->linesize[0] / sizeof(PIXEL); \ + } \ + } \ + } \ } -} + +COPY_FRAME(8, uint8_t) +COPY_FRAME(16, uint16_t) static void init_quantization(Jpeg2000EncoderContext *s) { @@ -680,6 +741,8 @@ static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg20 } cblk->passes[passno].rate = ff_mqc_flush_to(&t1->mqc, cblk->passes[passno].flushed, &cblk->passes[passno].flushed_len); + cblk->passes[passno].rate -= cblk->passes[passno].flushed_len; + wmsedec += (int64_t)nmsedec << (2*bpno); cblk->passes[passno].disto = wmsedec; @@ -691,8 +754,10 @@ static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg20 cblk->npasses = passno; cblk->ninclpasses = passno; - if (passno) + if (passno) { cblk->passes[passno-1].rate = ff_mqc_flush_to(&t1->mqc, cblk->passes[passno-1].flushed, &cblk->passes[passno-1].flushed_len); + cblk->passes[passno-1].rate -= cblk->passes[passno-1].flushed_len; + } } /* tier-2 routines: */ @@ -712,33 +777,82 @@ static void putnumpasses(Jpeg2000EncoderContext *s, int n) } -static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, int precno, - uint8_t *expn, int numgbits) +static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, int layno, + int precno, uint8_t *expn, int numgbits, int packetno, + int nlayers) { int bandno, empty = 1; - + int i; // init bitstream *s->buf = 0; s->bit_index = 0; + if (s->sop) { + bytestream_put_be16(&s->buf, JPEG2000_SOP); + bytestream_put_be16(&s->buf, 4); + bytestream_put_be16(&s->buf, packetno); + } // header + if (!layno) { + for (bandno = 0; bandno < rlevel->nbands; bandno++) { + Jpeg2000Band *band = rlevel->band + bandno; + if (band->coord[0][0] < band->coord[0][1] + && band->coord[1][0] < band->coord[1][1]) { + Jpeg2000Prec *prec = band->prec + precno; + int nb_cblks = prec->nb_codeblocks_height * prec->nb_codeblocks_width; + int pos; + ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 99); + ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 99); + for (pos = 0; pos < nb_cblks; pos++) { + Jpeg2000Cblk *cblk = &prec->cblk[pos]; + prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - cblk->nonzerobits; + cblk->incl = 0; + cblk->lblock = 3; + tag_tree_update(prec->zerobits + pos); + for (i = 0; i < nlayers; i++) { + if (cblk->layers[i].npasses > 0) { + prec->cblkincl[pos].val = i; + break; + } + } + if (i == nlayers) + prec->cblkincl[pos].val = i; + tag_tree_update(prec->cblkincl + pos); + } + } + } + } + // is the packet empty? for (bandno = 0; bandno < rlevel->nbands; bandno++){ - if (rlevel->band[bandno].coord[0][0] < rlevel->band[bandno].coord[0][1] - && rlevel->band[bandno].coord[1][0] < rlevel->band[bandno].coord[1][1]){ - empty = 0; - break; + Jpeg2000Band *band = rlevel->band + bandno; + if (band->coord[0][0] < band->coord[0][1] + && band->coord[1][0] < band->coord[1][1]) { + Jpeg2000Prec *prec = band->prec + precno; + int nb_cblks = prec->nb_codeblocks_height * prec->nb_codeblocks_width; + int pos; + for (pos = 0; pos < nb_cblks; pos++) { + Jpeg2000Cblk *cblk = &prec->cblk[pos]; + if (cblk->layers[layno].npasses) { + empty = 0; + break; + } + } + if (!empty) + break; } } put_bits(s, !empty, 1); if (empty){ j2k_flush(s); + if (s->eph) + bytestream_put_be16(&s->buf, JPEG2000_EPH); return 0; } - for (bandno = 0; bandno < rlevel->nbands; bandno++){ + for (bandno = 0; bandno < rlevel->nbands; bandno++) { Jpeg2000Band *band = rlevel->band + bandno; Jpeg2000Prec *prec = band->prec + precno; int yi, xi, pos; @@ -748,61 +862,70 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in || band->coord[1][0] == band->coord[1][1]) continue; - for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){ + 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 - prec->cblk[yi * cblknw + xi].nonzerobits; - tag_tree_update(prec->zerobits + pos); - } - } - - for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){ - for (xi = 0; xi < cblknw; xi++, pos++){ - int pad = 0, llen, length; + int llen = 0, length; Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi; if (s->buf_end - s->buf < 20) // approximately return -1; // inclusion information - tag_tree_code(s, prec->cblkincl + pos, 1); - if (!cblk->ninclpasses) - continue; - // zerobits information - tag_tree_code(s, prec->zerobits + pos, 100); - // number of passes - putnumpasses(s, cblk->ninclpasses); - - length = cblk->passes[cblk->ninclpasses-1].rate; - llen = av_log2(length) - av_log2(cblk->ninclpasses) - 2; - if (llen < 0){ - pad = -llen; - llen = 0; + if (!cblk->incl) + tag_tree_code(s, prec->cblkincl + pos, layno + 1); + else { + put_bits(s, cblk->layers[layno].npasses > 0, 1); } + + if (!cblk->layers[layno].npasses) + continue; + + // zerobits information + if (!cblk->incl) { + tag_tree_code(s, prec->zerobits + pos, 100); + cblk->incl = 1; + } + + // number of passes + putnumpasses(s, cblk->layers[layno].npasses); + + length = cblk->layers[layno].data_len; + if (layno == nlayers - 1 && cblk->layers[layno].cum_passes){ + length += cblk->passes[cblk->layers[layno].cum_passes-1].flushed_len; + } + if (cblk->lblock + av_log2(cblk->layers[layno].npasses) < av_log2(length) + 1) { + llen = av_log2(length) + 1 - cblk->lblock - av_log2(cblk->layers[layno].npasses); + } + // length of code block + cblk->lblock += llen; put_bits(s, 1, llen); put_bits(s, 0, 1); - put_num(s, length, av_log2(length)+1+pad); + put_num(s, length, cblk->lblock + av_log2(cblk->layers[layno].npasses)); } } } j2k_flush(s); - for (bandno = 0; bandno < rlevel->nbands; bandno++){ + if (s->eph) { + bytestream_put_be16(&s->buf, JPEG2000_EPH); + } + + for (bandno = 0; bandno < rlevel->nbands; bandno++) { 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++){ + for (yi =0; yi < prec->nb_codeblocks_height; yi++) { int 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) + if (cblk->layers[layno].npasses) { + if (s->buf_end - s->buf < cblk->layers[layno].data_len + 2) return -1; - bytestream_put_buffer(&s->buf, cblk->data + 1, cblk->passes[cblk->ninclpasses-1].rate - - cblk->passes[cblk->ninclpasses-1].flushed_len); - bytestream_put_buffer(&s->buf, cblk->passes[cblk->ninclpasses-1].flushed, - cblk->passes[cblk->ninclpasses-1].flushed_len); + bytestream_put_buffer(&s->buf, cblk->layers[layno].data_start + 1, cblk->layers[layno].data_len); + if (layno == nlayers - 1 && cblk->layers[layno].cum_passes) { + bytestream_put_buffer(&s->buf, cblk->passes[cblk->layers[layno].cum_passes-1].flushed, + cblk->passes[cblk->layers[layno].cum_passes-1].flushed_len); + } } } } @@ -810,29 +933,420 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in return 0; } -static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno) +static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno, int nlayers) { - int compno, reslevelno, ret; + int compno, reslevelno, layno, ret; Jpeg2000CodingStyle *codsty = &s->codsty; Jpeg2000QuantStyle *qntsty = &s->qntsty; + int packetno = 0; + int step_x, step_y; + int x, y; + int tile_coord[2][2]; + int col = tileno % s->numXtiles; + int row = tileno / s->numXtiles; + + tile_coord[0][0] = col * s->tile_width; + tile_coord[0][1] = FFMIN(tile_coord[0][0] + s->tile_width, s->width); + tile_coord[1][0] = row * s->tile_height; + tile_coord[1][1] = FFMIN(tile_coord[1][0] + s->tile_height, s->height); 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; - 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)) < 0) - return ret; + switch (s->prog) { + case JPEG2000_PGOD_LRCP: + for (layno = 0; layno < nlayers; layno++) { + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + for (compno = 0; compno < s->ncomponents; compno++){ + int precno; + 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, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } } } } + break; + case JPEG2000_PGOD_RLCP: + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + for (layno = 0; layno < nlayers; layno++) { + for (compno = 0; compno < s->ncomponents; compno++){ + int precno; + 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, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } + } + } + } + break; + case JPEG2000_PGOD_RPCL: + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { + int precno; + step_x = 30; + step_y = 30; + for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; + if (reslevelno < codsty->nreslevels) { + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno); + step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno); + } + } + + step_x = 1<ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; + int log_subsampling[2] = { compno?s->chroma_shift[0]:0, compno?s->chroma_shift[1]:0}; + unsigned prcx, prcy; + int trx0, try0; + + trx0 = ff_jpeg2000_ceildivpow2(tile_coord[0][0], log_subsampling[0] + reducedresno); + try0 = ff_jpeg2000_ceildivpow2(tile_coord[1][0], log_subsampling[1] + reducedresno); + + if (!(y % ((uint64_t)1 << (reslevel->log2_prec_height + reducedresno + log_subsampling[1])) == 0 || + (y == tile_coord[1][0] && (try0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_height))))) + continue; + + if (!(x % ((uint64_t)1 << (reslevel->log2_prec_width + reducedresno + log_subsampling[0])) == 0 || + (x == tile_coord[0][0] && (trx0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_width))))) + continue; + + // check if a precinct exists + prcx = ff_jpeg2000_ceildivpow2(x, log_subsampling[0] + reducedresno) >> reslevel->log2_prec_width; + prcy = ff_jpeg2000_ceildivpow2(y, log_subsampling[1] + reducedresno) >> reslevel->log2_prec_height; + prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> reslevel->log2_prec_width; + prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> reslevel->log2_prec_height; + precno = prcx + reslevel->num_precincts_x * prcy; + + if (prcx >= reslevel->num_precincts_x || prcy >= reslevel->num_precincts_y) { + av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n", + prcx, prcy, reslevel->num_precincts_x, reslevel->num_precincts_y); + continue; + } + for (layno = 0; layno < nlayers; layno++) { + if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } + } + } + } + } + break; + case JPEG2000_PGOD_PCRL: + step_x = 32; + step_y = 32; + for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; + + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno); + step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno); + } + } + if (step_x >= 31 || step_y >= 31){ + avpriv_request_sample(s->avctx, "PCRL with large step"); + return AVERROR_PATCHWELCOME; + } + step_x = 1<ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; + int log_subsampling[2] = { compno?s->chroma_shift[0]:0, compno?s->chroma_shift[1]:0}; + + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { + unsigned prcx, prcy; + int precno; + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; + int trx0, try0; + + trx0 = ff_jpeg2000_ceildivpow2(tile_coord[0][0], log_subsampling[0] + reducedresno); + try0 = ff_jpeg2000_ceildivpow2(tile_coord[1][0], log_subsampling[1] + reducedresno); + + if (!(y % ((uint64_t)1 << (reslevel->log2_prec_height + reducedresno + log_subsampling[1])) == 0 || + (y == tile_coord[1][0] && (try0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_height))))) + continue; + + if (!(x % ((uint64_t)1 << (reslevel->log2_prec_width + reducedresno + log_subsampling[0])) == 0 || + (x == tile_coord[0][0] && (trx0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_width))))) + continue; + + // check if a precinct exists + prcx = ff_jpeg2000_ceildivpow2(x, log_subsampling[0] + reducedresno) >> reslevel->log2_prec_width; + prcy = ff_jpeg2000_ceildivpow2(y, log_subsampling[1] + reducedresno) >> reslevel->log2_prec_height; + prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> reslevel->log2_prec_width; + prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> reslevel->log2_prec_height; + + precno = prcx + reslevel->num_precincts_x * prcy; + + if (prcx >= reslevel->num_precincts_x || prcy >= reslevel->num_precincts_y) { + av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n", + prcx, prcy, reslevel->num_precincts_x, reslevel->num_precincts_y); + continue; + } + for (layno = 0; layno < nlayers; layno++) { + if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } + } + } + } + } + break; + case JPEG2000_PGOD_CPRL: + for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; + int log_subsampling[2] = { compno?s->chroma_shift[0]:0, compno?s->chroma_shift[1]:0}; + step_x = 32; + step_y = 32; + + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno); + step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno); + } + if (step_x >= 31 || step_y >= 31){ + avpriv_request_sample(s->avctx, "CPRL with large step"); + return AVERROR_PATCHWELCOME; + } + step_x = 1<nreslevels; reslevelno++) { + unsigned prcx, prcy; + int precno; + int trx0, try0; + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; + + trx0 = ff_jpeg2000_ceildivpow2(tile_coord[0][0], log_subsampling[0] + reducedresno); + try0 = ff_jpeg2000_ceildivpow2(tile_coord[1][0], log_subsampling[1] + reducedresno); + + if (!(y % ((uint64_t)1 << (reslevel->log2_prec_height + reducedresno + log_subsampling[1])) == 0 || + (y == tile_coord[1][0] && (try0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_height))))) + continue; + + if (!(x % ((uint64_t)1 << (reslevel->log2_prec_width + reducedresno + log_subsampling[0])) == 0 || + (x == tile_coord[0][0] && (trx0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_width))))) + continue; + + // check if a precinct exists + prcx = ff_jpeg2000_ceildivpow2(x, log_subsampling[0] + reducedresno) >> reslevel->log2_prec_width; + prcy = ff_jpeg2000_ceildivpow2(y, log_subsampling[1] + reducedresno) >> reslevel->log2_prec_height; + prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> reslevel->log2_prec_width; + prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> reslevel->log2_prec_height; + + precno = prcx + reslevel->num_precincts_x * prcy; + + if (prcx >= reslevel->num_precincts_x || prcy >= reslevel->num_precincts_y) { + av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n", + prcx, prcy, reslevel->num_precincts_x, reslevel->num_precincts_y); + continue; + } + for (layno = 0; layno < nlayers; layno++) { + if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits, packetno++, nlayers)) < 0) + return ret; + } + } + } + } + } + + } + av_log(s->avctx, AV_LOG_DEBUG, "after tier2\n"); return 0; } +static void makelayer(Jpeg2000EncoderContext *s, int layno, double thresh, Jpeg2000Tile* tile, int final) +{ + int compno, resno, bandno, precno, cblkno; + int passno; + + for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = &tile->comp[compno]; + + for (resno = 0; resno < s->codsty.nreslevels; resno++) { + Jpeg2000ResLevel *reslevel = comp->reslevel + resno; + + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + for (bandno = 0; bandno < reslevel->nbands ; bandno++){ + Jpeg2000Band *band = reslevel->band + bandno; + Jpeg2000Prec *prec = band->prec + precno; + + for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ + Jpeg2000Cblk *cblk = prec->cblk + cblkno; + Jpeg2000Layer *layer = &cblk->layers[layno]; + int n; + + if (layno == 0) { + cblk->ninclpasses = 0; + } + + n = cblk->ninclpasses; + + if (thresh < 0) { + n = cblk->npasses; + } else { + for (passno = cblk->ninclpasses; passno < cblk->npasses; passno++) { + int32_t dr; + double dd; + Jpeg2000Pass *pass = &cblk->passes[passno]; + + if (n == 0) { + dr = pass->rate; + dd = pass->disto; + } else { + dr = pass->rate - cblk->passes[n - 1].rate; + dd = pass->disto - cblk->passes[n-1].disto; + } + + if (!dr) { + if (dd != 0.0) { + n = passno + 1; + } + continue; + } + + if (thresh - (dd / dr) < DBL_EPSILON) + n = passno + 1; + } + } + layer->npasses = n - cblk->ninclpasses; + layer->cum_passes = n; + + if (layer->npasses == 0) { + layer->disto = 0; + layer->data_len = 0; + continue; + } + + if (cblk->ninclpasses == 0) { + layer->data_len = cblk->passes[n - 1].rate; + layer->data_start = cblk->data; + layer->disto = cblk->passes[n - 1].disto; + } else { + layer->data_len = cblk->passes[n - 1].rate - cblk->passes[cblk->ninclpasses - 1].rate; + layer->data_start = cblk->data + cblk->passes[cblk->ninclpasses - 1].rate; + layer->disto = cblk->passes[n - 1].disto - + cblk->passes[cblk->ninclpasses - 1].disto; + } + if (final) { + cblk->ninclpasses = n; + } + } + } + } + } + } +} + +static void makelayers(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) +{ + int precno, compno, reslevelno, bandno, cblkno, lev, passno, layno; + int i; + double min = DBL_MAX; + double max = 0; + double thresh; + int tile_disto = 0; + + Jpeg2000CodingStyle *codsty = &s->codsty; + + for (compno = 0; compno < s->ncomponents; compno++){ + Jpeg2000Component *comp = tile->comp + compno; + + for (reslevelno = 0, lev = codsty->nreslevels-1; reslevelno < codsty->nreslevels; reslevelno++, lev--){ + Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; + + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + for (bandno = 0; bandno < reslevel->nbands ; bandno++){ + Jpeg2000Band *band = reslevel->band + bandno; + Jpeg2000Prec *prec = band->prec + precno; + + for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ + Jpeg2000Cblk *cblk = prec->cblk + cblkno; + for (passno = 0; passno < cblk->npasses; passno++) { + Jpeg2000Pass *pass = &cblk->passes[passno]; + int dr; + double dd, drslope; + + tile_disto += pass->disto; + if (passno == 0) { + dr = (int32_t)pass->rate; + dd = pass->disto; + } else { + dr = (int32_t)(pass->rate - cblk->passes[passno - 1].rate); + dd = pass->disto - cblk->passes[passno - 1].disto; + } + + if (dr <= 0) + continue; + + drslope = dd / dr; + if (drslope < min) + min = drslope; + + if (drslope > max) + max = drslope; + } + } + } + } + } + } + + for (layno = 0; layno < s->nlayers; layno++) { + double lo = min; + double hi = max; + double stable_thresh = 0.0; + double good_thresh = 0.0; + if (!s->layer_rates[layno]) { + good_thresh = -1.0; + } else { + for (i = 0; i < 128; i++) { + uint8_t *stream_pos = s->buf; + int ret; + thresh = (lo + hi) / 2; + makelayer(s, layno, thresh, tile, 0); + ret = encode_packets(s, tile, (int)(tile - s->tile), layno + 1); + memset(stream_pos, 0, s->buf - stream_pos); + if ((s->buf - stream_pos > ceil(tile->layer_rates[layno])) || ret < 0) { + lo = thresh; + s->buf = stream_pos; + continue; + } + hi = thresh; + stable_thresh = thresh; + s->buf = stream_pos; + } + } + if (good_thresh >= 0.0) + good_thresh = stable_thresh == 0.0 ? thresh : stable_thresh; + makelayer(s, layno, good_thresh, tile, 1); + } +} + static int getcut(Jpeg2000Cblk *cblk, int64_t lambda, int dwt_norm) { int passno, res = 0; @@ -841,9 +1355,9 @@ static int getcut(Jpeg2000Cblk *cblk, int64_t lambda, int dwt_norm) int64_t dd; dr = cblk->passes[passno].rate - - (res ? cblk->passes[res-1].rate:0); + - (res ? cblk->passes[res-1].rate : 0); dd = cblk->passes[passno].disto - - (res ? cblk->passes[res-1].disto:0); + - (res ? cblk->passes[res-1].disto : 0); if (((dd * dwt_norm) >> WMSEDEC_SHIFT) * dwt_norm >= dr * lambda) res = passno+1; @@ -873,6 +1387,11 @@ static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) cblk->ninclpasses = getcut(cblk, s->lambda, (int64_t)dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 15); + cblk->layers[0].data_start = cblk->data; + cblk->layers[0].cum_passes = cblk->ninclpasses; + cblk->layers[0].npasses = cblk->ninclpasses; + if (cblk->ninclpasses) + cblk->layers[0].data_len = cblk->passes[cblk->ninclpasses - 1].rate; } } } @@ -960,8 +1479,12 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno } av_log(s->avctx, AV_LOG_DEBUG, "rate control\n"); - truncpasses(s, tile); - if ((ret = encode_packets(s, tile, tileno)) < 0) + if (s->compression_rate_enc) + makelayers(s, tile); + else + truncpasses(s, tile); + + if ((ret = encode_packets(s, tile, tileno, s->nlayers)) < 0) return ret; av_log(s->avctx, AV_LOG_DEBUG, "after rate control\n"); return 0; @@ -972,12 +1495,17 @@ static void cleanup(Jpeg2000EncoderContext *s) int tileno, compno; Jpeg2000CodingStyle *codsty = &s->codsty; + if (!s->tile) + return; for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ - for (compno = 0; compno < s->ncomponents; compno++){ - Jpeg2000Component *comp = s->tile[tileno].comp + compno; - ff_jpeg2000_cleanup(comp, codsty); + if (s->tile[tileno].comp) { + for (compno = 0; compno < s->ncomponents; compno++){ + Jpeg2000Component *comp = s->tile[tileno].comp + compno; + ff_jpeg2000_cleanup(comp, codsty); + } + av_freep(&s->tile[tileno].comp); } - av_freep(&s->tile[tileno].comp); + av_freep(&s->tile[tileno].layer_rates); } av_freep(&s->tile); } @@ -1015,7 +1543,11 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, s->lambda = s->picture->quality * LAMBDA_SCALE; - copy_frame(s); + if (avctx->pix_fmt == AV_PIX_FMT_BGR48 || avctx->pix_fmt == AV_PIX_FMT_GRAY16) + copy_frame_16(s); + else + copy_frame_8(s); + reinit(s); if (s->format == CODEC_JP2) { @@ -1132,6 +1664,53 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static int parse_layer_rates(Jpeg2000EncoderContext *s) +{ + int i; + char *token; + char *saveptr = NULL; + int rate; + int nlayers = 0; + if (!s->lr_str) { + s->nlayers = 1; + s->layer_rates[0] = 0; + s->compression_rate_enc = 0; + return 0; + } + + token = av_strtok(s->lr_str, ",", &saveptr); + if (rate = strtol(token, NULL, 10)) { + s->layer_rates[0] = rate <= 1 ? 0:rate; + nlayers++; + } else { + return AVERROR_INVALIDDATA; + } + + while (1) { + token = av_strtok(NULL, ",", &saveptr); + if (!token) + break; + if (rate = strtol(token, NULL, 10)) { + if (nlayers >= 100) { + return AVERROR_INVALIDDATA; + } + s->layer_rates[nlayers] = rate <= 1 ? 0:rate; + nlayers++; + } else { + return AVERROR_INVALIDDATA; + } + } + + for (i = 1; i < nlayers; i++) { + if (s->layer_rates[i] >= s->layer_rates[i-1]) { + return AVERROR_INVALIDDATA; + } + } + s->nlayers = nlayers; + s->compression_rate_enc = 1; + return 0; +} + static av_cold int j2kenc_init(AVCodecContext *avctx) { int i, ret; @@ -1141,6 +1720,12 @@ static av_cold int j2kenc_init(AVCodecContext *avctx) s->avctx = avctx; av_log(s->avctx, AV_LOG_DEBUG, "init\n"); + if (parse_layer_rates(s)) { + av_log(s, AV_LOG_WARNING, "Layer rates invalid. Encoding with 1 layer based on quality metric.\n"); + s->nlayers = 1; + s->layer_rates[0] = 0; + s->compression_rate_enc = 0; + } #if FF_API_PRIVATE_OPT FF_DISABLE_DEPRECATION_WARNINGS @@ -1161,6 +1746,7 @@ FF_ENABLE_DEPRECATION_WARNINGS memset(codsty->log2_prec_heights, 15, sizeof(codsty->log2_prec_heights)); codsty->nreslevels2decode= codsty->nreslevels = 7; + codsty->nlayers = s->nlayers; codsty->log2_cblk_width = 4; codsty->log2_cblk_height = 4; codsty->transform = s->pred ? FF_DWT53 : FF_DWT97_INT; @@ -1180,12 +1766,16 @@ FF_ENABLE_DEPRECATION_WARNINGS s->width = avctx->width; s->height = avctx->height; - for (i = 0; i < 3; i++) - s->cbps[i] = 8; + for (i = 0; i < 3; i++) { + if (avctx->pix_fmt == AV_PIX_FMT_GRAY16 || avctx->pix_fmt == AV_PIX_FMT_RGB48) + s->cbps[i] = 16; + else + s->cbps[i] = 8; + } - if (avctx->pix_fmt == AV_PIX_FMT_RGB24){ + if (avctx->pix_fmt == AV_PIX_FMT_RGB24 || avctx->pix_fmt == AV_PIX_FMT_RGB48){ s->ncomponents = 3; - } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 || avctx->pix_fmt == AV_PIX_FMT_PAL8){ + } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 || avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY16){ s->ncomponents = 1; } else{ // planar YUV s->planar = 1; @@ -1230,7 +1820,15 @@ static const AVOption options[] = { { "pred", "DWT Type", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "pred" }, { "dwt97int", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, { "dwt53", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, - + { "sop", "SOP marker", OFFSET(sop), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, }, + { "eph", "EPH marker", OFFSET(eph), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, }, + { "prog", "Progression Order", OFFSET(prog), AV_OPT_TYPE_INT, { .i64 = 0 }, JPEG2000_PGOD_LRCP, JPEG2000_PGOD_CPRL, VE, "prog" }, + { "lrcp", NULL, OFFSET(prog), AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_LRCP }, 0, 0, VE, "prog" }, + { "rlcp", NULL, OFFSET(prog), AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_RLCP }, 0, 0, VE, "prog" }, + { "rpcl", NULL, OFFSET(prog), AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_RPCL }, 0, 0, VE, "prog" }, + { "pcrl", NULL, OFFSET(prog), AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_PCRL }, 0, 0, VE, "prog" }, + { "cprl", NULL, OFFSET(prog), AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_CPRL }, 0, 0, VE, "prog" }, + { "layer_rates", "Layer Rates", OFFSET(lr_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE }, { NULL } }; @@ -1255,7 +1853,9 @@ AVCodec ff_jpeg2000_encoder = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_PAL8, + AV_PIX_FMT_RGB48, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }, .priv_class = &j2k_class, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 73206d17f..56d98c8a8 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -39,7 +39,7 @@ /* tag tree routines */ /* allocate the memory for tag tree */ -static int32_t tag_tree_size(int w, int h) +int32_t ff_tag_tree_size(int w, int h) { int64_t res = 0; while (w > 1 || h > 1) { @@ -57,7 +57,7 @@ static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h) Jpeg2000TgtNode *res, *t, *t2; int32_t tt_size; - tt_size = tag_tree_size(w, h); + tt_size = ff_tag_tree_size(w, h); t = res = av_mallocz_array(tt_size, sizeof(*t)); if (!res) @@ -82,12 +82,13 @@ static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h) return res; } -static void tag_tree_zero(Jpeg2000TgtNode *t, int w, int h) +void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h, int val) { - int i, siz = tag_tree_size(w, h); + int i, siz = ff_tag_tree_size(w, h); for (i = 0; i < siz; i++) { - t[i].val = 0; + t[i].val = val; + t[i].temp_val = 0; t[i].vis = 0; } } @@ -260,9 +261,11 @@ static void init_band_stepsize(AVCodecContext *avctx, band->f_stepsize *= 0.5; } -static int init_prec(Jpeg2000Band *band, +static int init_prec(AVCodecContext *avctx, + Jpeg2000Band *band, Jpeg2000ResLevel *reslevel, Jpeg2000Component *comp, + Jpeg2000CodingStyle *codsty, int precno, int bandno, int reslevelno, int log2_band_prec_width, int log2_band_prec_height) @@ -365,6 +368,11 @@ static int init_prec(Jpeg2000Band *band, cblk->lblock = 3; cblk->length = 0; cblk->npasses = 0; + if (av_codec_is_encoder(avctx->codec)) { + cblk->layers = av_mallocz_array(codsty->nlayers, sizeof(*cblk->layers)); + if (!cblk->layers) + return AVERROR(ENOMEM); + } } return 0; @@ -438,7 +446,7 @@ static int init_band(AVCodecContext *avctx, return AVERROR(ENOMEM); for (precno = 0; precno < nb_precincts; precno++) { - ret = init_prec(band, reslevel, comp, + ret = init_prec(avctx, band, reslevel, comp, codsty, precno, bandno, reslevelno, log2_band_prec_width, log2_band_prec_height); if (ret < 0) @@ -509,9 +517,6 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp, // update precincts size: 2^n value reslevel->log2_prec_width = codsty->log2_prec_widths[reslevelno]; reslevel->log2_prec_height = codsty->log2_prec_heights[reslevelno]; - if (!reslevel->log2_prec_width || !reslevel->log2_prec_height) { - return AVERROR_INVALIDDATA; - } /* Number of bands for each resolution level */ if (reslevelno == 0) @@ -570,8 +575,8 @@ void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty) Jpeg2000Band *band = rlevel->band + bandno; for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++) { Jpeg2000Prec *prec = band->prec + precno; - tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height); - tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height); + ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 0); + ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 0); for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) { Jpeg2000Cblk *cblk = prec->cblk + cblkno; cblk->length = 0; @@ -616,6 +621,7 @@ void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty) av_freep(&cblk->passes); av_freep(&cblk->lengthinc); av_freep(&cblk->data_start); + av_freep(&cblk->layers); } av_freep(&prec->cblk); } diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index 0f8271698..612832c87 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -127,6 +127,7 @@ typedef struct Jpeg2000T1Context { typedef struct Jpeg2000TgtNode { uint8_t val; + uint8_t temp_val; uint8_t vis; struct Jpeg2000TgtNode *parent; } Jpeg2000TgtNode; @@ -144,6 +145,7 @@ typedef struct Jpeg2000CodingStyle { uint8_t prog_order; // progression order uint8_t log2_prec_widths[JPEG2000_MAX_RESLEVELS]; // precincts size according resolution levels uint8_t log2_prec_heights[JPEG2000_MAX_RESLEVELS]; // TODO: initialize prec_size array with 0? + uint8_t init; } Jpeg2000CodingStyle; typedef struct Jpeg2000QuantStyle { @@ -160,10 +162,19 @@ typedef struct Jpeg2000Pass { int flushed_len; } Jpeg2000Pass; +typedef struct Jpeg2000Layer { + uint8_t *data_start; + int data_len; + int npasses; + double disto; + int cum_passes; +} Jpeg2000Layer; + typedef struct Jpeg2000Cblk { uint8_t npasses; uint8_t ninclpasses; // number coding of passes included in codestream uint8_t nonzerobits; + uint8_t incl; uint16_t length; uint16_t *lengthinc; uint8_t nb_lengthinc; @@ -174,6 +185,7 @@ typedef struct Jpeg2000Cblk { int nb_terminationsinc; int *data_start; Jpeg2000Pass *passes; + Jpeg2000Layer *layers; int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} } Jpeg2000Cblk; // code block @@ -219,9 +231,9 @@ static inline int ff_jpeg2000_ceildivpow2(int a, int b) return -((-(int64_t)a) >> b); } -static inline int ff_jpeg2000_ceildiv(int a, int b) +static inline int ff_jpeg2000_ceildiv(int a, int64_t b) { - return (a + (int64_t)b - 1) / b; + return (a + b - 1) / b; } /* TIER-1 routines */ @@ -289,4 +301,7 @@ static inline int needs_termination(int style, int passno) { return 0; } +int32_t ff_tag_tree_size(int w, int h); +void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h, int val); + #endif /* AVCODEC_JPEG2000_H */ diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index fad614e03..63edbcda0 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -71,6 +71,7 @@ typedef struct Jpeg2000POC { typedef struct Jpeg2000TilePart { uint8_t tile_index; // Tile index who refers the tile-part const uint8_t *tp_end; + GetByteContext header_tpg; // bit stream of header if PPM header is used GetByteContext tpg; // bit stream in tile-part } Jpeg2000TilePart; @@ -102,6 +103,13 @@ typedef struct Jpeg2000DecoderContext { uint8_t cbps[4]; // bits per sample in particular components uint8_t sgnd[4]; // if a component is signed uint8_t properties[4]; + + uint8_t has_ppm; + uint8_t *packed_headers; // contains packed headers. Used only along with PPM marker + int packed_headers_size; + GetByteContext packed_headers_stream; + uint8_t in_tile_headers; + int cdx[4], cdy[4]; int precision; int ncomponents; @@ -269,6 +277,8 @@ static int get_siz(Jpeg2000DecoderContext *s) const enum AVPixelFormat *possible_fmts = NULL; int possible_fmts_nb = 0; int ret; + int o_dimx, o_dimy; //original image dimensions. + int dimx, dimy; if (bytestream2_get_bytes_left(&s->g) < 36) { av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n"); @@ -286,10 +296,6 @@ static int get_siz(Jpeg2000DecoderContext *s) s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz ncomponents = bytestream2_get_be16u(&s->g); // CSiz - if (s->image_offset_x || s->image_offset_y) { - avpriv_request_sample(s->avctx, "Support for image offsets"); - return AVERROR_PATCHWELCOME; - } if (av_image_check_size2(s->width, s->height, s->avctx->max_pixels, AV_PIX_FMT_NONE, 0, s->avctx)) { avpriv_request_sample(s->avctx, "Large Dimensions"); return AVERROR_PATCHWELCOME; @@ -371,11 +377,18 @@ static int get_siz(Jpeg2000DecoderContext *s) } /* compute image size with reduction factor */ - ret = ff_set_dimensions(s->avctx, - ff_jpeg2000_ceildivpow2(s->width - s->image_offset_x, - s->reduction_factor), - ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y, - s->reduction_factor)); + o_dimx = ff_jpeg2000_ceildivpow2(s->width - s->image_offset_x, + s->reduction_factor); + o_dimy = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y, + s->reduction_factor); + dimx = ff_jpeg2000_ceildiv(o_dimx, s->cdx[0]); + dimy = ff_jpeg2000_ceildiv(o_dimy, s->cdy[0]); + for (i = 1; i < s->ncomponents; i++) { + dimx = FFMAX(dimx, ff_jpeg2000_ceildiv(o_dimx, s->cdx[i])); + dimy = FFMAX(dimy, ff_jpeg2000_ceildiv(o_dimy, s->cdy[i])); + } + + ret = ff_set_dimensions(s->avctx, dimx, dimy); if (ret < 0) return ret; @@ -427,6 +440,18 @@ static int get_siz(Jpeg2000DecoderContext *s) s->cdef[3] = 3; i = 0; } + } else if (ncomponents == 3 && s->precision == 8 && + s->cdx[0] == s->cdx[1] && s->cdx[0] == s->cdx[2] && + s->cdy[0] == s->cdy[1] && s->cdy[0] == s->cdy[2]) { + s->avctx->pix_fmt = AV_PIX_FMT_RGB24; + i = 0; + } else if (ncomponents == 2 && s->precision == 8 && + s->cdx[0] == s->cdx[1] && s->cdy[0] == s->cdy[1]) { + s->avctx->pix_fmt = AV_PIX_FMT_YA8; + i = 0; + } else if (ncomponents == 1 && s->precision == 8) { + s->avctx->pix_fmt = AV_PIX_FMT_GRAY8; + i = 0; } } @@ -558,7 +583,7 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, if ((ret = get_cox(s, &tmp)) < 0) return ret; - + tmp.init = 1; for (compno = 0; compno < s->ncomponents; compno++) if (!(properties[compno] & HAD_COC)) memcpy(c + compno, &tmp, sizeof(tmp)); @@ -571,7 +596,7 @@ static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, uint8_t *properties) { int compno, ret; - uint8_t has_eph; + uint8_t has_eph, has_sop; if (bytestream2_get_bytes_left(&s->g) < 2) { av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COC\n"); @@ -589,13 +614,16 @@ static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, c += compno; has_eph = c->csty & JPEG2000_CSTY_EPH; + has_sop = c->csty & JPEG2000_CSTY_SOP; c->csty = bytestream2_get_byteu(&s->g); c->csty |= has_eph; //do not override eph present bits from COD + c->csty |= has_sop; //do not override sop present bits from COD if ((ret = get_cox(s, c)) < 0) return ret; properties[compno] |= HAD_COC; + c->init = 1; return 0; } @@ -908,6 +936,30 @@ static int get_plt(Jpeg2000DecoderContext *s, int n) return 0; } +static int get_ppm(Jpeg2000DecoderContext *s, int n) +{ + void *new; + + if (n < 3) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid length for PPM data.\n"); + return AVERROR_INVALIDDATA; + } + bytestream2_get_byte(&s->g); //Zppm is skipped and not used + new = av_realloc(s->packed_headers, + s->packed_headers_size + n - 3); + if (new) { + s->packed_headers = new; + } else + return AVERROR(ENOMEM); + s->has_ppm = 1; + memset(&s->packed_headers_stream, 0, sizeof(s->packed_headers_stream)); + bytestream_get_buffer(&s->g.buffer, s->packed_headers + s->packed_headers_size, + n - 3); + s->packed_headers_size += n - 3; + + return 0; +} + static int get_ppt(Jpeg2000DecoderContext *s, int n) { Jpeg2000Tile *tile; @@ -969,12 +1021,11 @@ static int init_tile(Jpeg2000DecoderContext *s, int tileno) comp->coord_o[0][1] = tile->coord[0][1]; comp->coord_o[1][0] = tile->coord[1][0]; comp->coord_o[1][1] = tile->coord[1][1]; - if (compno) { - comp->coord_o[0][0] /= s->cdx[compno]; - comp->coord_o[0][1] /= s->cdx[compno]; - comp->coord_o[1][0] /= s->cdy[compno]; - comp->coord_o[1][1] /= s->cdy[compno]; - } + + comp->coord_o[0][0] = ff_jpeg2000_ceildiv(comp->coord_o[0][0], s->cdx[compno]); + comp->coord_o[0][1] = ff_jpeg2000_ceildiv(comp->coord_o[0][1], s->cdx[compno]); + comp->coord_o[1][0] = ff_jpeg2000_ceildiv(comp->coord_o[1][0], s->cdy[compno]); + comp->coord_o[1][1] = ff_jpeg2000_ceildiv(comp->coord_o[1][1], s->cdy[compno]); comp->coord[0][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], s->reduction_factor); comp->coord[0][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][1], s->reduction_factor); @@ -983,7 +1034,8 @@ static int init_tile(Jpeg2000DecoderContext *s, int tileno) if (!comp->roi_shift) comp->roi_shift = s->roi_shift[compno]; - + if (!codsty->init) + return AVERROR_INVALIDDATA; if (ret = ff_jpeg2000_init_component(comp, codsty, qntsty, s->cbps[compno], s->cdx[compno], s->cdy[compno], s->avctx)) @@ -1019,8 +1071,19 @@ static int getlblockinc(Jpeg2000DecoderContext *s) return res; } -static inline void select_stream(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, +static inline void select_header(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index) +{ + s->g = tile->tile_part[*tp_index].header_tpg; + if (bytestream2_get_bytes_left(&s->g) == 0 && s->bit_index == 8) { + if (*tp_index < FF_ARRAY_ELEMS(tile->tile_part) - 1) { + s->g = tile->tile_part[++(*tp_index)].tpg; + } + } +} + +static inline void select_stream(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, + int *tp_index, Jpeg2000CodingStyle *codsty) { s->g = tile->tile_part[*tp_index].tpg; if (bytestream2_get_bytes_left(&s->g) == 0 && s->bit_index == 8) { @@ -1028,8 +1091,12 @@ static inline void select_stream(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, s->g = tile->tile_part[++(*tp_index)].tpg; } } - if (bytestream2_peek_be32(&s->g) == JPEG2000_SOP_FIXED_BYTES) - bytestream2_skip(&s->g, JPEG2000_SOP_BYTE_LENGTH); + if (codsty->csty & JPEG2000_CSTY_SOP) { + if (bytestream2_peek_be32(&s->g) == JPEG2000_SOP_FIXED_BYTES) + bytestream2_skip(&s->g, JPEG2000_SOP_BYTE_LENGTH); + else + av_log(s->avctx, AV_LOG_ERROR, "SOP marker not found. instead %X\n", bytestream2_peek_be32(&s->g)); + } } static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index, @@ -1044,10 +1111,12 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, return 0; rlevel->band[0].prec[precno].decoded_layers = layno + 1; // Select stream to read from - if (tile->has_ppt) + if (s->has_ppm) + select_header(s, tile, tp_index); + else if (tile->has_ppt) s->g = tile->packed_headers_stream; else - select_stream(s, tile, tp_index); + select_stream(s, tile, tp_index, codsty); if (!(ret = get_bits(s, 1))) { jpeg2000_flush(s); @@ -1158,9 +1227,12 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, } // Save state of stream - if (tile->has_ppt) { + if (s->has_ppm) { + tile->tile_part[*tp_index].header_tpg = s->g; + select_stream(s, tile, tp_index, codsty); + } else if (tile->has_ppt) { tile->packed_headers_stream = s->g; - select_stream(s, tile, tp_index); + select_stream(s, tile, tp_index, codsty); } for (bandno = 0; bandno < rlevel->nbands; bandno++) { Jpeg2000Band *band = rlevel->band + bandno; @@ -1208,10 +1280,20 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, return 0; skip_data: - if (tile->has_ppt) + if (codsty->csty & JPEG2000_CSTY_EPH) { + if (bytestream2_peek_be16(&s->g) == JPEG2000_EPH) + bytestream2_skip(&s->g, 2); + else + av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found. instead %X\n", bytestream2_peek_be32(&s->g)); + } + if (s->has_ppm) { + tile->tile_part[*tp_index].header_tpg = s->g; + select_stream(s, tile, tp_index, codsty); + } else if (tile->has_ppt) { tile->packed_headers_stream = s->g; - else - tile->tile_part[*tp_index].tpg = s->g; + select_stream(s, tile, tp_index, codsty); + } + tile->tile_part[*tp_index].tpg = s->g; return 0; } @@ -1375,22 +1457,28 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2 uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; unsigned prcx, prcy; + int trx0, try0; - int xc = x / s->cdx[compno]; - int yc = y / s->cdy[compno]; + if (!s->cdx[compno] || !s->cdy[compno]) + return AVERROR_INVALIDDATA; if (reslevelno >= codsty->nreslevels) continue; - if (yc % (1LL << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check + trx0 = ff_jpeg2000_ceildiv(tile->coord[0][0], (int64_t)s->cdx[compno] << reducedresno); + try0 = ff_jpeg2000_ceildiv(tile->coord[1][0], (int64_t)s->cdy[compno] << reducedresno); + + if (!(y % ((uint64_t)s->cdy[compno] << (rlevel->log2_prec_height + reducedresno)) == 0 || + (y == tile->coord[1][0] && ((int64_t)try0 << reducedresno) % (1ULL << (reducedresno + rlevel->log2_prec_height))))) continue; - if (xc % (1LL << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check + if (!(x % ((uint64_t)s->cdx[compno] << (rlevel->log2_prec_width + reducedresno)) == 0 || + (x == tile->coord[0][0] && ((int64_t)trx0 << reducedresno) % (1ULL << (reducedresno + rlevel->log2_prec_width))))) continue; // check if a precinct exists - prcx = ff_jpeg2000_ceildivpow2(xc, reducedresno) >> rlevel->log2_prec_width; - prcy = ff_jpeg2000_ceildivpow2(yc, reducedresno) >> rlevel->log2_prec_height; + prcx = ff_jpeg2000_ceildiv(x, (int64_t)s->cdx[compno] << reducedresno) >> rlevel->log2_prec_width; + prcy = ff_jpeg2000_ceildiv(y, (int64_t)s->cdy[compno] << reducedresno) >> rlevel->log2_prec_height; prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> rlevel->log2_prec_width; prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> rlevel->log2_prec_height; @@ -1445,23 +1533,30 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2 Jpeg2000Component *comp = tile->comp + compno; Jpeg2000CodingStyle *codsty = tile->codsty + compno; Jpeg2000QuantStyle *qntsty = tile->qntsty + compno; - int xc = x / s->cdx[compno]; - int yc = y / s->cdy[compno]; + + if (!s->cdx[compno] || !s->cdy[compno]) + return AVERROR_INVALIDDATA; for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); reslevelno++) { unsigned prcx, prcy; uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + int trx0, try0; - if (yc % (1LL << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check - continue; + trx0 = ff_jpeg2000_ceildiv(tile->coord[0][0], (int64_t)s->cdx[compno] << reducedresno); + try0 = ff_jpeg2000_ceildiv(tile->coord[1][0], (int64_t)s->cdy[compno] << reducedresno); - if (xc % (1LL << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check - continue; + if (!(y % ((uint64_t)s->cdy[compno] << (rlevel->log2_prec_height + reducedresno)) == 0 || + (y == tile->coord[1][0] && ((int64_t)try0 << reducedresno) % (1ULL << (reducedresno + rlevel->log2_prec_height))))) + continue; + + if (!(x % ((uint64_t)s->cdx[compno] << (rlevel->log2_prec_width + reducedresno)) == 0 || + (x == tile->coord[0][0] && ((int64_t)trx0 << reducedresno) % (1ULL << (reducedresno + rlevel->log2_prec_width))))) + continue; // check if a precinct exists - prcx = ff_jpeg2000_ceildivpow2(xc, reducedresno) >> rlevel->log2_prec_width; - prcy = ff_jpeg2000_ceildivpow2(yc, reducedresno) >> rlevel->log2_prec_height; + prcx = ff_jpeg2000_ceildiv(x, (int64_t)s->cdx[compno] << reducedresno) >> rlevel->log2_prec_width; + prcy = ff_jpeg2000_ceildiv(y, (int64_t)s->cdy[compno] << reducedresno) >> rlevel->log2_prec_height; prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> rlevel->log2_prec_width; prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> rlevel->log2_prec_height; @@ -1720,9 +1815,13 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, pass_cnt ++; } - if (cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) != t1->mqc.bp) { + if (cblk->data + cblk->length - 2 > t1->mqc.bp) { av_log(s->avctx, AV_LOG_WARNING, "End mismatch %"PTRDIFF_SPECIFIER"\n", - cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) - t1->mqc.bp); + cblk->data + cblk->length - 2 - t1->mqc.bp); + } + + if (cblk->data + cblk->length < t1->mqc.bp) { + av_log(s->avctx, AV_LOG_WARNING, "Synthetic End of Stream Marker Read.\n"); } return 1; @@ -1927,18 +2026,23 @@ static inline void tile_codeblocks(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile float *datap = comp->f_data; \ int32_t *i_datap = comp->i_data; \ int cbps = s->cbps[compno]; \ - int w = tile->comp[compno].coord[0][1] - s->image_offset_x; \ + int w = tile->comp[compno].coord[0][1] - \ + ff_jpeg2000_ceildiv(s->image_offset_x, s->cdx[compno]); \ + int h = tile->comp[compno].coord[1][1] - \ + ff_jpeg2000_ceildiv(s->image_offset_y, s->cdy[compno]); \ int plane = 0; \ \ if (planar) \ plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1); \ \ - y = tile->comp[compno].coord[1][0] - s->image_offset_y / s->cdy[compno]; \ + y = tile->comp[compno].coord[1][0] - \ + ff_jpeg2000_ceildiv(s->image_offset_y, s->cdy[compno]); \ line = (PIXEL *)picture->data[plane] + y * (picture->linesize[plane] / sizeof(PIXEL));\ - for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y++) { \ + for (; y < h; y++) { \ PIXEL *dst; \ \ - x = tile->comp[compno].coord[0][0] - s->image_offset_x / s->cdx[compno]; \ + x = tile->comp[compno].coord[0][0] - \ + ff_jpeg2000_ceildiv(s->image_offset_x, s->cdx[compno]); \ dst = line + x * pixelsize + compno*!planar; \ \ if (codsty->transform == FF_DWT97) { \ @@ -2026,6 +2130,9 @@ static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s) s->tile[tileno].packed_headers_size = 0; } } + av_freep(&s->packed_headers); + s->packed_headers_size = 0; + memset(&s->packed_headers_stream, 0, sizeof(s->packed_headers_stream)); av_freep(&s->tile); memset(s->codsty, 0, sizeof(s->codsty)); memset(s->qntsty, 0, sizeof(s->qntsty)); @@ -2054,7 +2161,8 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) marker = bytestream2_get_be16u(&s->g); oldpos = bytestream2_tell(&s->g); - + if (marker >= 0xFF30 && marker <= 0xFF3F) + continue; if (marker == JPEG2000_SOD) { Jpeg2000Tile *tile; Jpeg2000TilePart *tp; @@ -2075,6 +2183,13 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) return AVERROR_INVALIDDATA; } + if (s->has_ppm) { + uint32_t tp_header_size = bytestream2_get_be32(&s->packed_headers_stream); + if (bytestream2_get_bytes_left(&s->packed_headers_stream) < tp_header_size) + return AVERROR_INVALIDDATA; + bytestream2_init(&tp->header_tpg, s->packed_headers_stream.buffer, tp_header_size); + bytestream2_skip(&s->packed_headers_stream, tp_header_size); + } if (tile->has_ppt && tile->tp_idx == 0) { bytestream2_init(&tile->packed_headers_stream, tile->packed_headers, tile->packed_headers_size); } @@ -2126,6 +2241,12 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) ret = get_poc(s, len, poc); break; case JPEG2000_SOT: + if (!s->in_tile_headers) { + s->in_tile_headers = 1; + if (s->has_ppm) { + bytestream2_init(&s->packed_headers_stream, s->packed_headers, s->packed_headers_size); + } + } if (!(ret = get_sot(s, len))) { av_assert1(s->curtileno >= 0); codsty = s->tile[s->curtileno].codsty; @@ -2151,8 +2272,22 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) // Packet length, tile-part header ret = get_plt(s, len); break; + case JPEG2000_PPM: + // Packed headers, main header + if (s->in_tile_headers) { + av_log(s->avctx, AV_LOG_ERROR, "PPM Marker can only be in Main header\n"); + return AVERROR_INVALIDDATA; + } + ret = get_ppm(s, len); + break; case JPEG2000_PPT: // Packed headers, tile-part header + if (s->has_ppm) { + av_log(s->avctx, AV_LOG_ERROR, + "Cannot have both PPT and PPM marker.\n"); + return AVERROR_INVALIDDATA; + } + ret = get_ppt(s, len); break; default: diff --git a/libavcodec/jpegls.h b/libavcodec/jpegls.h index 6b89b2afa..aac67bbe3 100644 --- a/libavcodec/jpegls.h +++ b/libavcodec/jpegls.h @@ -34,10 +34,6 @@ #undef near /* This file uses struct member 'near' which in windows.h is defined as empty. */ -typedef struct JpeglsContext { - AVCodecContext *avctx; -} JpeglsContext; - typedef struct JLSState { int T1, T2, T3; int A[367], B[367], C[365], N[367]; @@ -99,7 +95,7 @@ static inline void ff_jpegls_downscale_state(JLSState *state, int Q) static inline int ff_jpegls_update_state_regular(JLSState *state, int Q, int err) { - if(FFABS(err) > 0xFFFF) + if(FFABS(err) > 0xFFFF || FFABS(err) > INT_MAX - state->A[Q]) return -0x10000; state->A[Q] += FFABS(err); err *= state->twonear; diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index fd4eb234b..69980eaa4 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -551,7 +551,8 @@ AVCodec ff_jpegls_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - .decode = ff_mjpeg_decode_frame, + .receive_frame = ff_mjpeg_receive_frame, .capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_SETS_PKT_DTS, }; diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c index 5ecd430db..2bb6b1407 100644 --- a/libavcodec/jpeglsenc.c +++ b/libavcodec/jpeglsenc.c @@ -26,6 +26,7 @@ */ #include "avcodec.h" +#include "bytestream.h" #include "get_bits.h" #include "put_bits.h" #include "golomb.h" @@ -41,6 +42,18 @@ typedef struct JPEGLSContext { int pred; } JPEGLSContext; +static inline void put_marker_byteu(PutByteContext *pb, enum JpegMarker code) +{ + bytestream2_put_byteu(pb, 0xff); + bytestream2_put_byteu(pb, code); +} + +static inline void put_marker_byte(PutByteContext *pb, enum JpegMarker code) +{ + bytestream2_put_byte(pb, 0xff); + bytestream2_put_byte(pb, code); +} + /** * Encode error from regular symbol */ @@ -128,21 +141,19 @@ static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, * Encode one line of image */ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, - void *last, void *cur, int last2, int w, + void *tmp, const void *in, int last2, int w, int stride, int comp, int bits) { int x = 0; - int Ra, Rb, Rc, Rd; + int Ra = R(tmp, 0), Rb, Rc = last2, Rd; int D0, D1, D2; while (x < w) { int err, pred, sign; /* compute gradients */ - Ra = x ? R(cur, x - stride) : R(last, x); - Rb = R(last, x); - Rc = x ? R(last, x - stride) : last2; - Rd = (x >= w - stride) ? R(last, x) : R(last, x + stride); + Rb = R(tmp, x); + Rd = (x >= w - stride) ? R(tmp, x) : R(tmp, x + stride); D0 = Rd - Rb; D1 = Rb - Rc; D2 = Rc - Ra; @@ -155,18 +166,18 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, run = 0; RUNval = Ra; - while (x < w && (FFABS(R(cur, x) - RUNval) <= state->near)) { + while (x < w && (FFABS(R(in, x) - RUNval) <= state->near)) { run++; - W(cur, x, Ra); + W(tmp, x, Ra); x += stride; } ls_encode_run(state, pb, run, comp, x < w); if (x >= w) return; - Rb = R(last, x); + Rb = R(tmp, x); RItype = FFABS(Ra - Rb) <= state->near; pred = RItype ? Ra : Rb; - err = R(cur, x) - pred; + err = R(in, x) - pred; if (!RItype && Ra > Rb) err = -err; @@ -181,8 +192,10 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, 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); - } + } else + Ra = R(in, x); + W(tmp, x, Ra); + if (err < 0) err += state->range; if (err >= state->range + 1 >> 1) @@ -205,11 +218,11 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, context = -context; sign = 1; pred = av_clip(pred - state->C[context], 0, state->maxval); - err = pred - R(cur, x); + err = pred - R(in, x); } else { sign = 0; pred = av_clip(pred + state->C[context], 0, state->maxval); - err = R(cur, x) - pred; + err = R(in, x) - pred; } if (state->near) { @@ -221,16 +234,18 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, 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); - } + } else + Ra = R(in, x); + W(tmp, x, Ra); ls_encode_regular(state, pb, context, err); } + Rc = Rb; x += stride; } } -static void ls_store_lse(JLSState *state, PutBitContext *pb) +static void ls_store_lse(JLSState *state, PutByteContext *pb) { /* Test if we have default params and don't need to store LSE */ JLSState state2 = { 0 }; @@ -243,14 +258,14 @@ static void ls_store_lse(JLSState *state, PutBitContext *pb) 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, 16, state->maxval); - put_bits(pb, 16, state->T1); - put_bits(pb, 16, state->T2); - put_bits(pb, 16, state->T3); - put_bits(pb, 16, state->reset); + put_marker_byteu(pb, LSE); + bytestream2_put_be16u(pb, 13); + bytestream2_put_byteu(pb, 1); + bytestream2_put_be16u(pb, state->maxval); + bytestream2_put_be16u(pb, state->T1); + bytestream2_put_be16u(pb, state->T2); + bytestream2_put_be16u(pb, state->T3); + bytestream2_put_be16u(pb, state->reset); } static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, @@ -258,13 +273,12 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, { JPEGLSContext *ctx = avctx->priv_data; const AVFrame *const p = pict; - PutBitContext pb, pb2; + PutByteContext pb; + PutBitContext pb2; GetBitContext gb; - uint8_t *buf2 = NULL; - uint8_t *zero = NULL; - uint8_t *cur = NULL; + const uint8_t *in; uint8_t *last = NULL; - JLSState *state = NULL; + JLSState state = { 0 }; int i, size, ret; int comps; @@ -285,72 +299,65 @@ FF_ENABLE_DEPRECATION_WARNINGS AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0) return ret; - buf2 = av_malloc(pkt->size); - if (!buf2) - goto memfail; + last = av_malloc((unsigned)pkt->size + FFABS(p->linesize[0])); + if (!last) + return AVERROR(ENOMEM); + memset(last, 0, FFABS(p->linesize[0])); - init_put_bits(&pb, pkt->data, pkt->size); - init_put_bits(&pb2, buf2, pkt->size); + bytestream2_init_writer(&pb, pkt->data, pkt->size); + init_put_bits(&pb2, last + FFABS(p->linesize[0]), pkt->size); /* write our own JPEG header, can't use mjpeg_picture_header */ - 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, 16, avctx->height); - put_bits(&pb, 16, avctx->width); - put_bits(&pb, 8, comps); // components + put_marker_byteu(&pb, SOI); + put_marker_byteu(&pb, SOF48); + bytestream2_put_be16u(&pb, 8 + comps * 3); // header size depends on components + bytestream2_put_byteu(&pb, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8); // bpp + bytestream2_put_be16u(&pb, avctx->height); + bytestream2_put_be16u(&pb, avctx->width); + bytestream2_put_byteu(&pb, 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 + bytestream2_put_byteu(&pb, i); // component ID + bytestream2_put_byteu(&pb, 0x11); // subsampling: none + bytestream2_put_byteu(&pb, 0); // Tiq, used by JPEG-LS ext } - put_marker(&pb, SOS); - put_bits(&pb, 16, 6 + comps * 2); - put_bits(&pb, 8, comps); + put_marker_byteu(&pb, SOS); + bytestream2_put_be16u(&pb, 6 + comps * 2); + bytestream2_put_byteu(&pb, comps); for (i = 1; i <= comps; i++) { - put_bits(&pb, 8, i); // component ID - put_bits(&pb, 8, 0); // mapping index: none + bytestream2_put_byteu(&pb, i); // component ID + bytestream2_put_byteu(&pb, 0); // mapping index: none } - put_bits(&pb, 8, ctx->pred); - 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)); - if (!state) - goto memfail; + bytestream2_put_byteu(&pb, ctx->pred); + bytestream2_put_byteu(&pb, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line + bytestream2_put_byteu(&pb, 0); // point transform: none /* initialize JPEG-LS state from JPEG parameters */ - state->near = ctx->pred; - state->bpp = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8; - ff_jpegls_reset_coding_parameters(state, 0); - ff_jpegls_init_state(state); + state.near = ctx->pred; + state.bpp = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8; + ff_jpegls_reset_coding_parameters(&state, 0); + ff_jpegls_init_state(&state); - ls_store_lse(state, &pb); + ls_store_lse(&state, &pb); - zero = last = av_mallocz(FFABS(p->linesize[0])); - if (!zero) - goto memfail; - - cur = p->data[0]; + in = 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]; - last = cur; - cur += p->linesize[0]; + int last0 = last[0]; + ls_encode_line(&state, &pb2, last, in, t, avctx->width, 1, 0, 8); + t = last0; + in += p->linesize[0]; } } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY16) { int t = 0; for (i = 0; i < avctx->height; i++) { - ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16); - t = *((uint16_t *)last); - last = cur; - cur += p->linesize[0]; + int last0 = *((uint16_t *)last); + ls_encode_line(&state, &pb2, last, in, t, avctx->width, 1, 0, 16); + t = last0; + in += p->linesize[0]; } } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) { int j, width; @@ -359,12 +366,12 @@ FF_ENABLE_DEPRECATION_WARNINGS 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], + int last0 = last[j]; + ls_encode_line(&state, &pb2, last + j, in + j, Rc[j], width, 3, j, 8); - Rc[j] = last[j]; + Rc[j] = last0; } - last = cur; - cur += p->linesize[0]; + in += p->linesize[0]; } } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) { int j, width; @@ -373,18 +380,15 @@ FF_ENABLE_DEPRECATION_WARNINGS 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], + int last0 = last[j]; + ls_encode_line(&state, &pb2, last + j, in + j, Rc[j], width, 3, j, 8); - Rc[j] = last[j]; + Rc[j] = last0; } - last = cur; - cur += p->linesize[0]; + in += 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. */ @@ -392,37 +396,28 @@ FF_ENABLE_DEPRECATION_WARNINGS size = put_bits_count(&pb2); flush_put_bits(&pb2); /* do escape coding */ - init_get_bits(&gb, buf2, size); + init_get_bits(&gb, pb2.buf, size); size -= 7; while (get_bits_count(&gb) < size) { int v; v = get_bits(&gb, 8); - put_bits(&pb, 8, v); + bytestream2_put_byte(&pb, v); if (v == 0xFF) { v = get_bits(&gb, 7); - put_bits(&pb, 8, v); + bytestream2_put_byte(&pb, v); } } - avpriv_align_put_bits(&pb); - av_freep(&buf2); + av_freep(&last); /* End of image */ - put_marker(&pb, EOI); - flush_put_bits(&pb); + put_marker_byte(&pb, EOI); emms_c(); - pkt->size = put_bits_count(&pb) >> 3; + pkt->size = bytestream2_tell_p(&pb); pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; - -memfail: - av_packet_unref(pkt); - av_freep(&buf2); - av_freep(&state); - av_freep(&zero); - return AVERROR(ENOMEM); } static av_cold int encode_init_ls(AVCodecContext *ctx) diff --git a/libavcodec/jpegtables.c b/libavcodec/jpegtables.c index fa5c6f9fc..ef3f8dee2 100644 --- a/libavcodec/jpegtables.c +++ b/libavcodec/jpegtables.c @@ -122,35 +122,3 @@ const uint8_t avpriv_mjpeg_val_ac_chrominance[] = 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa }; - -/* isn't this function nicer than the one in the libjpeg ? */ -void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, - const uint8_t *bits_table, - const uint8_t *val_table) -{ - int i, j, k,nb, code, sym; - - /* Some badly encoded files [1] map 2 different codes to symbol 0. - Only the first one is valid, so we zero-initialize this here and - make sure we only set it once (the first time) in the loop below. - - [1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here: - https://www.dji.com/gr/zenmuse-x7/info#downloads - */ - huff_size[0] = 0; - - k = 0; - code = 0; - for(i=1;i<=16;i++) { - nb = bits_table[i]; - for(j=0;jg, avpkt->data, avpkt->size); diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 2dcd249b6..d281733fd 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -173,7 +173,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac int uqvq, ret; unsigned int mthread_inlen, mthread_outlen; unsigned int len = buf_size; - int linesize; + int linesize, offset; if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; @@ -373,8 +373,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac /* Convert colorspace */ y_out = frame->data[0] + (height - 1) * frame->linesize[0]; - u_out = frame->data[1] + (height - 1) * frame->linesize[1]; - v_out = frame->data[2] + (height - 1) * frame->linesize[2]; + offset = (height - 1) * frame->linesize[1]; + u_out = FF_PTR_ADD(frame->data[1], offset); + offset = (height - 1) * frame->linesize[2]; + v_out = FF_PTR_ADD(frame->data[2], offset); switch (c->imgtype) { case IMGTYPE_YUV111: for (row = 0; row < height; row++) { diff --git a/libavcodec/libaomdec.c b/libavcodec/libaomdec.c index a72ac984e..1fc0a0001 100644 --- a/libavcodec/libaomdec.c +++ b/libavcodec/libaomdec.c @@ -197,6 +197,14 @@ static int aom_decode(AVCodecContext *avctx, void *data, int *got_frame, } if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) return ret; + + av_reduce(&picture->sample_aspect_ratio.num, + &picture->sample_aspect_ratio.den, + picture->height * img->r_w, + picture->width * img->r_h, + INT_MAX); + ff_set_sar(avctx, picture->sample_aspect_ratio); + if ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img->bit_depth == 8) image_copy_16_to_8(picture, img); else @@ -228,7 +236,8 @@ AVCodec ff_libaom_av1_decoder = { .init = av1_init, .close = aom_free, .decode = aom_decode, - .capabilities = AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), .wrapper_name = "libaom", }; diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c index 1c78da719..2c3c3eb18 100644 --- a/libavcodec/libaomenc.c +++ b/libavcodec/libaomenc.c @@ -96,6 +96,35 @@ typedef struct AOMEncoderContext { int enable_restoration; int usage; int tune; + int enable_rect_partitions; + int enable_1to4_partitions; + int enable_ab_partitions; + int enable_angle_delta; + int enable_cfl_intra; + int enable_paeth_intra; + int enable_smooth_intra; + int enable_intra_edge_filter; + int enable_palette; + int enable_filter_intra; + int enable_flip_idtx; + int enable_tx64; + int reduced_tx_type_set; + int use_intra_dct_only; + int use_inter_dct_only; + int use_intra_default_tx_only; + int enable_ref_frame_mvs; + int enable_interinter_wedge; + int enable_interintra_wedge; + int enable_interintra_comp; + int enable_masked_comp; + int enable_obmc; + int enable_onesided_comp; + int enable_reduced_reference_set; + int enable_smooth_interintra; + int enable_diff_wtd_comp; + int enable_dist_wtd_comp; + int enable_dual_filter; + AVDictionary *aom_params; } AOMContext; static const char *const ctlidstr[] = { @@ -135,6 +164,36 @@ static const char *const ctlidstr[] = { #endif [AV1E_SET_ENABLE_CDEF] = "AV1E_SET_ENABLE_CDEF", [AOME_SET_TUNING] = "AOME_SET_TUNING", +#if AOM_ENCODER_ABI_VERSION >= 22 + [AV1E_SET_ENABLE_1TO4_PARTITIONS] = "AV1E_SET_ENABLE_1TO4_PARTITIONS", + [AV1E_SET_ENABLE_AB_PARTITIONS] = "AV1E_SET_ENABLE_AB_PARTITIONS", + [AV1E_SET_ENABLE_RECT_PARTITIONS] = "AV1E_SET_ENABLE_RECT_PARTITIONS", + [AV1E_SET_ENABLE_ANGLE_DELTA] = "AV1E_SET_ENABLE_ANGLE_DELTA", + [AV1E_SET_ENABLE_CFL_INTRA] = "AV1E_SET_ENABLE_CFL_INTRA", + [AV1E_SET_ENABLE_FILTER_INTRA] = "AV1E_SET_ENABLE_FILTER_INTRA", + [AV1E_SET_ENABLE_INTRA_EDGE_FILTER] = "AV1E_SET_ENABLE_INTRA_EDGE_FILTER", + [AV1E_SET_ENABLE_PAETH_INTRA] = "AV1E_SET_ENABLE_PAETH_INTRA", + [AV1E_SET_ENABLE_SMOOTH_INTRA] = "AV1E_SET_ENABLE_SMOOTH_INTRA", + [AV1E_SET_ENABLE_PALETTE] = "AV1E_SET_ENABLE_PALETTE", + [AV1E_SET_ENABLE_FLIP_IDTX] = "AV1E_SET_ENABLE_FLIP_IDTX", + [AV1E_SET_ENABLE_TX64] = "AV1E_SET_ENABLE_TX64", + [AV1E_SET_INTRA_DCT_ONLY] = "AV1E_SET_INTRA_DCT_ONLY", + [AV1E_SET_INTER_DCT_ONLY] = "AV1E_SET_INTER_DCT_ONLY", + [AV1E_SET_INTRA_DEFAULT_TX_ONLY] = "AV1E_SET_INTRA_DEFAULT_TX_ONLY", + [AV1E_SET_REDUCED_TX_TYPE_SET] = "AV1E_SET_REDUCED_TX_TYPE_SET", + [AV1E_SET_ENABLE_DIFF_WTD_COMP] = "AV1E_SET_ENABLE_DIFF_WTD_COMP", + [AV1E_SET_ENABLE_DIST_WTD_COMP] = "AV1E_SET_ENABLE_DIST_WTD_COMP", + [AV1E_SET_ENABLE_DUAL_FILTER] = "AV1E_SET_ENABLE_DUAL_FILTER", + [AV1E_SET_ENABLE_INTERINTER_WEDGE] = "AV1E_SET_ENABLE_INTERINTER_WEDGE", + [AV1E_SET_ENABLE_INTERINTRA_WEDGE] = "AV1E_SET_ENABLE_INTERINTRA_WEDGE", + [AV1E_SET_ENABLE_MASKED_COMP] = "AV1E_SET_ENABLE_MASKED_COMP", + [AV1E_SET_ENABLE_INTERINTRA_COMP] = "AV1E_SET_ENABLE_INTERINTRA_COMP", + [AV1E_SET_ENABLE_OBMC] = "AV1E_SET_ENABLE_OBMC", + [AV1E_SET_ENABLE_ONESIDED_COMP] = "AV1E_SET_ENABLE_ONESIDED_COMP", + [AV1E_SET_REDUCED_REFERENCE_SET] = "AV1E_SET_REDUCED_REFERENCE_SET", + [AV1E_SET_ENABLE_SMOOTH_INTERINTRA] = "AV1E_SET_ENABLE_SMOOTH_INTERINTRA", + [AV1E_SET_ENABLE_REF_FRAME_MVS] = "AV1E_SET_ENABLE_REF_FRAME_MVS", +#endif }; static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc) @@ -277,8 +336,12 @@ static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps, aom_img_fmt_t *img_fmt) { AOMContext av_unused *ctx = avctx->priv_data; - enccfg->g_bit_depth = enccfg->g_input_bit_depth = 8; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + enccfg->g_bit_depth = enccfg->g_input_bit_depth = desc->comp[0].depth; switch (avctx->pix_fmt) { + case AV_PIX_FMT_GRAY8: + enccfg->monochrome = 1; + /* Fall-through */ case AV_PIX_FMT_YUV420P: enccfg->g_profile = FF_PROFILE_AV1_MAIN; *img_fmt = AOM_IMG_FMT_I420; @@ -288,14 +351,17 @@ static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps, *img_fmt = AOM_IMG_FMT_I422; return 0; case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_GBRP: enccfg->g_profile = FF_PROFILE_AV1_HIGH; *img_fmt = AOM_IMG_FMT_I444; return 0; + case AV_PIX_FMT_GRAY10: + case AV_PIX_FMT_GRAY12: + enccfg->monochrome = 1; + /* Fall-through */ case AV_PIX_FMT_YUV420P10: case AV_PIX_FMT_YUV420P12: if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) { - enccfg->g_bit_depth = enccfg->g_input_bit_depth = - avctx->pix_fmt == AV_PIX_FMT_YUV420P10 ? 10 : 12; enccfg->g_profile = enccfg->g_bit_depth == 10 ? FF_PROFILE_AV1_MAIN : FF_PROFILE_AV1_PROFESSIONAL; *img_fmt = AOM_IMG_FMT_I42016; @@ -306,8 +372,6 @@ static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps, case AV_PIX_FMT_YUV422P10: case AV_PIX_FMT_YUV422P12: if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) { - enccfg->g_bit_depth = enccfg->g_input_bit_depth = - avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 10 : 12; enccfg->g_profile = FF_PROFILE_AV1_PROFESSIONAL; *img_fmt = AOM_IMG_FMT_I42216; *flags |= AOM_CODEC_USE_HIGHBITDEPTH; @@ -316,9 +380,9 @@ static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps, break; case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUV444P12: + case AV_PIX_FMT_GBRP10: + case AV_PIX_FMT_GBRP12: if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) { - enccfg->g_bit_depth = enccfg->g_input_bit_depth = - avctx->pix_fmt == AV_PIX_FMT_YUV444P10 ? 10 : 12; enccfg->g_profile = enccfg->g_bit_depth == 10 ? FF_PROFILE_AV1_HIGH : FF_PROFILE_AV1_PROFESSIONAL; *img_fmt = AOM_IMG_FMT_I44416; @@ -516,6 +580,7 @@ static av_cold int aom_init(AVCodecContext *avctx, const struct aom_codec_iface *iface) { AOMContext *ctx = avctx->priv_data; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); struct aom_codec_enc_cfg enccfg = { 0 }; #ifdef AOM_FRAME_IS_INTRAONLY aom_codec_flags_t flags = @@ -698,6 +763,64 @@ static av_cold int aom_init(AVCodecContext *avctx, codecctl_int(avctx, AV1E_SET_ENABLE_CDEF, ctx->enable_cdef); if (ctx->enable_restoration >= 0) codecctl_int(avctx, AV1E_SET_ENABLE_RESTORATION, ctx->enable_restoration); +#if AOM_ENCODER_ABI_VERSION >= 22 + if (ctx->enable_rect_partitions >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_RECT_PARTITIONS, ctx->enable_rect_partitions); + if (ctx->enable_1to4_partitions >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_1TO4_PARTITIONS, ctx->enable_1to4_partitions); + if (ctx->enable_ab_partitions >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_AB_PARTITIONS, ctx->enable_ab_partitions); + if (ctx->enable_angle_delta >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_ANGLE_DELTA, ctx->enable_angle_delta); + if (ctx->enable_cfl_intra >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_CFL_INTRA, ctx->enable_cfl_intra); + if (ctx->enable_filter_intra >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_FILTER_INTRA, ctx->enable_filter_intra); + if (ctx->enable_intra_edge_filter >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_INTRA_EDGE_FILTER, ctx->enable_intra_edge_filter); + if (ctx->enable_paeth_intra >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_PAETH_INTRA, ctx->enable_paeth_intra); + if (ctx->enable_smooth_intra >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_SMOOTH_INTRA, ctx->enable_smooth_intra); + if (ctx->enable_palette >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_PALETTE, ctx->enable_palette); + if (ctx->enable_tx64 >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_TX64, ctx->enable_tx64); + if (ctx->enable_flip_idtx >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_FLIP_IDTX, ctx->enable_flip_idtx); + if (ctx->use_intra_dct_only >= 0) + codecctl_int(avctx, AV1E_SET_INTRA_DCT_ONLY, ctx->use_intra_dct_only); + if (ctx->use_inter_dct_only >= 0) + codecctl_int(avctx, AV1E_SET_INTER_DCT_ONLY, ctx->use_inter_dct_only); + if (ctx->use_intra_default_tx_only >= 0) + codecctl_int(avctx, AV1E_SET_INTRA_DEFAULT_TX_ONLY, ctx->use_intra_default_tx_only); + if (ctx->reduced_tx_type_set >= 0) + codecctl_int(avctx, AV1E_SET_REDUCED_TX_TYPE_SET, ctx->reduced_tx_type_set); + if (ctx->enable_ref_frame_mvs >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_REF_FRAME_MVS, ctx->enable_ref_frame_mvs); + if (ctx->enable_reduced_reference_set >= 0) + codecctl_int(avctx, AV1E_SET_REDUCED_REFERENCE_SET, ctx->enable_reduced_reference_set); + if (ctx->enable_diff_wtd_comp >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_DIFF_WTD_COMP, ctx->enable_diff_wtd_comp); + if (ctx->enable_dist_wtd_comp >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_DIST_WTD_COMP, ctx->enable_dist_wtd_comp); + if (ctx->enable_dual_filter >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_DUAL_FILTER, ctx->enable_dual_filter); + if (ctx->enable_interinter_wedge >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_INTERINTER_WEDGE, ctx->enable_interinter_wedge); + if (ctx->enable_masked_comp >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_MASKED_COMP, ctx->enable_masked_comp); + if (ctx->enable_interintra_comp >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_INTERINTRA_COMP, ctx->enable_interintra_comp); + if (ctx->enable_interintra_wedge >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_INTERINTRA_WEDGE, ctx->enable_interintra_wedge); + if (ctx->enable_obmc >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_OBMC, ctx->enable_obmc); + if (ctx->enable_onesided_comp >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_ONESIDED_COMP, ctx->enable_onesided_comp); + if (ctx->enable_smooth_interintra >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_SMOOTH_INTERINTRA, ctx->enable_smooth_interintra); +#endif codecctl_int(avctx, AOME_SET_STATIC_THRESHOLD, ctx->static_thresh); if (ctx->crf >= 0) @@ -705,9 +828,15 @@ static av_cold int aom_init(AVCodecContext *avctx, if (ctx->tune >= 0) codecctl_int(avctx, AOME_SET_TUNING, ctx->tune); - codecctl_int(avctx, AV1E_SET_COLOR_PRIMARIES, avctx->color_primaries); - codecctl_int(avctx, AV1E_SET_MATRIX_COEFFICIENTS, avctx->colorspace); - codecctl_int(avctx, AV1E_SET_TRANSFER_CHARACTERISTICS, avctx->color_trc); + if (desc->flags & AV_PIX_FMT_FLAG_RGB) { + codecctl_int(avctx, AV1E_SET_COLOR_PRIMARIES, AVCOL_PRI_BT709); + codecctl_int(avctx, AV1E_SET_MATRIX_COEFFICIENTS, AVCOL_SPC_RGB); + codecctl_int(avctx, AV1E_SET_TRANSFER_CHARACTERISTICS, AVCOL_TRC_IEC61966_2_1); + } else { + codecctl_int(avctx, AV1E_SET_COLOR_PRIMARIES, avctx->color_primaries); + codecctl_int(avctx, AV1E_SET_MATRIX_COEFFICIENTS, avctx->colorspace); + codecctl_int(avctx, AV1E_SET_TRANSFER_CHARACTERISTICS, avctx->color_trc); + } if (ctx->aq_mode >= 0) codecctl_int(avctx, AV1E_SET_AQ_MODE, ctx->aq_mode); if (ctx->frame_parallel >= 0) @@ -746,6 +875,20 @@ static av_cold int aom_init(AVCodecContext *avctx, codecctl_int(avctx, AV1E_SET_ENABLE_INTRABC, ctx->enable_intrabc); #endif +#if AOM_ENCODER_ABI_VERSION >= 23 + { + AVDictionaryEntry *en = NULL; + + while ((en = av_dict_get(ctx->aom_params, "", en, AV_DICT_IGNORE_SUFFIX))) { + int ret = aom_codec_set_option(&ctx->encoder, en->key, en->value); + if (ret != AOM_CODEC_OK) { + log_encoder_error(avctx, en->key); + return AVERROR_EXTERNAL; + } + } + } +#endif + // provide dummy value to initialize wrapper, values will be updated each _encode() aom_img_wrap(&ctx->rawimg, img_fmt, avctx->width, avctx->height, 1, (unsigned char*)1); @@ -1033,6 +1176,16 @@ static const enum AVPixelFormat av1_pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_GBRP, + AV_PIX_FMT_NONE +}; + +static const enum AVPixelFormat av1_pix_fmts_with_gray[] = { + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV444P, + AV_PIX_FMT_GBRP, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }; @@ -1040,22 +1193,47 @@ static const enum AVPixelFormat av1_pix_fmts_highbd[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_GBRP, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, + AV_PIX_FMT_NONE +}; + +static const enum AVPixelFormat av1_pix_fmts_highbd_with_gray[] = { + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV444P, + AV_PIX_FMT_GBRP, + AV_PIX_FMT_YUV420P10, + AV_PIX_FMT_YUV422P10, + AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV422P12, + AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, + AV_PIX_FMT_GRAY8, + AV_PIX_FMT_GRAY10, + AV_PIX_FMT_GRAY12, AV_PIX_FMT_NONE }; static av_cold void av1_init_static(AVCodec *codec) { + int supports_monochrome = aom_codec_version() >= 20001; aom_codec_caps_t codec_caps = aom_codec_get_caps(aom_codec_av1_cx()); if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) - codec->pix_fmts = av1_pix_fmts_highbd; + codec->pix_fmts = supports_monochrome ? av1_pix_fmts_highbd_with_gray : + av1_pix_fmts_highbd; else - codec->pix_fmts = av1_pix_fmts; + codec->pix_fmts = supports_monochrome ? av1_pix_fmts_with_gray : + av1_pix_fmts; if (aom_codec_version_major() < 2) codec->capabilities |= AV_CODEC_CAP_EXPERIMENTAL; @@ -1107,6 +1285,38 @@ static const AVOption options[] = { { "tune", "The metric that the encoder tunes for. Automatically chosen by the encoder by default", OFFSET(tune), AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM, VE, "tune"}, { "psnr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_PSNR}, 0, 0, VE, "tune"}, { "ssim", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_SSIM}, 0, 0, VE, "tune"}, + FF_AV1_PROFILE_OPTS + { "enable-rect-partitions", "Enable rectangular partitions", OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-1to4-partitions", "Enable 1:4/4:1 partitions", OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-ab-partitions", "Enable ab shape partitions", OFFSET(enable_ab_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-angle-delta", "Enable angle delta intra prediction", OFFSET(enable_angle_delta), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-cfl-intra", "Enable chroma predicted from luma intra prediction", OFFSET(enable_cfl_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-filter-intra", "Enable filter intra predictor", OFFSET(enable_filter_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-intra-edge-filter", "Enable intra edge filter", OFFSET(enable_intra_edge_filter), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-smooth-intra", "Enable smooth intra prediction mode", OFFSET(enable_smooth_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-paeth-intra", "Enable paeth predictor in intra prediction", OFFSET(enable_paeth_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-palette", "Enable palette prediction mode", OFFSET(enable_palette), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-flip-idtx", "Enable extended transform type", OFFSET(enable_flip_idtx), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-tx64", "Enable 64-pt transform", OFFSET(enable_tx64), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "reduced-tx-type-set", "Use reduced set of transform types", OFFSET(reduced_tx_type_set), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "use-intra-dct-only", "Use DCT only for INTRA modes", OFFSET(use_intra_dct_only), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "use-inter-dct-only", "Use DCT only for INTER modes", OFFSET(use_inter_dct_only), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "use-intra-default-tx-only", "Use default-transform only for INTRA modes", OFFSET(use_intra_default_tx_only), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-ref-frame-mvs", "Enable temporal mv prediction", OFFSET(enable_ref_frame_mvs), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-reduced-reference-set", "Use reduced set of single and compound references", OFFSET(enable_reduced_reference_set), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-obmc", "Enable obmc", OFFSET(enable_obmc), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-dual-filter", "Enable dual filter", OFFSET(enable_dual_filter), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-diff-wtd-comp", "Enable difference-weighted compound", OFFSET(enable_diff_wtd_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-dist-wtd-comp", "Enable distance-weighted compound", OFFSET(enable_dist_wtd_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-onesided-comp", "Enable one sided compound", OFFSET(enable_onesided_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-interinter-wedge", "Enable interinter wedge compound", OFFSET(enable_interinter_wedge), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-interintra-wedge", "Enable interintra wedge compound", OFFSET(enable_interintra_wedge), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-masked-comp", "Enable masked compound", OFFSET(enable_masked_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-interintra-comp", "Enable interintra compound", OFFSET(enable_interintra_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-smooth-interintra", "Enable smooth interintra mode", OFFSET(enable_smooth_interintra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, +#if AOM_ENCODER_ABI_VERSION >= 23 + { "aom-params", "Set libaom options using a :-separated list of key=value pairs", OFFSET(aom_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE }, +#endif { NULL }, }; @@ -1135,7 +1345,8 @@ AVCodec ff_libaom_av1_encoder = { .init = av1_init, .encode2 = aom_encode, .close = aom_free, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), .priv_class = &class_aom, .defaults = defaults, diff --git a/libavcodec/libcodec2.c b/libavcodec/libcodec2.c index 1d6bed038..2164f3605 100644 --- a/libavcodec/libcodec2.c +++ b/libavcodec/libcodec2.c @@ -34,7 +34,7 @@ typedef struct { static const AVOption options[] = { //not AV_OPT_FLAG_DECODING_PARAM since mode should come from the demuxer //1300 (aka FreeDV 1600) is the most common mode on-the-air, default to it here as well - AVPRIV_CODEC2_AVOPTIONS("codec2 mode", LibCodec2Context, 0, 4 /*CODEC2_MODE_1300*/, AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_ENCODING_PARAM), + CODEC2_AVOPTIONS("codec2 mode", LibCodec2Context, 0, 4 /*CODEC2_MODE_1300*/, AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_ENCODING_PARAM), { NULL }, }; @@ -55,7 +55,7 @@ static av_cold int libcodec2_init_common(AVCodecContext *avctx, int mode) { LibCodec2Context *c2 = avctx->priv_data; //Grab mode name from options, unless it's some weird number. - const char *modename = mode >= 0 && mode <= AVPRIV_CODEC2_MODE_MAX ? options[mode+1].name : "?"; + const char *modename = mode >= 0 && mode <= CODEC2_MODE_MAX ? options[mode+1].name : "?"; c2->codec = codec2_create(mode); if (!c2->codec) { @@ -93,13 +93,13 @@ static av_cold int libcodec2_init_decoder(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_S16; avctx->channel_layout = AV_CH_LAYOUT_MONO; - if (avctx->extradata_size != AVPRIV_CODEC2_EXTRADATA_SIZE) { + if (avctx->extradata_size != CODEC2_EXTRADATA_SIZE) { av_log(avctx, AV_LOG_ERROR, "must have exactly %i bytes of extradata (got %i)\n", - AVPRIV_CODEC2_EXTRADATA_SIZE, avctx->extradata_size); + CODEC2_EXTRADATA_SIZE, avctx->extradata_size); return AVERROR_INVALIDDATA; } - return libcodec2_init_common(avctx, avpriv_codec2_mode_from_extradata(avctx->extradata)); + return libcodec2_init_common(avctx, codec2_mode_from_extradata(avctx->extradata)); } static av_cold int libcodec2_init_encoder(AVCodecContext *avctx) @@ -114,13 +114,13 @@ static av_cold int libcodec2_init_encoder(AVCodecContext *avctx) return AVERROR(EINVAL); } - avctx->extradata = av_mallocz(AVPRIV_CODEC2_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE); + avctx->extradata = av_mallocz(CODEC2_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE); if (!avctx->extradata) { return AVERROR(ENOMEM); } - avctx->extradata_size = AVPRIV_CODEC2_EXTRADATA_SIZE; - avpriv_codec2_make_extradata(avctx->extradata, c2->mode); + avctx->extradata_size = CODEC2_EXTRADATA_SIZE; + codec2_make_extradata(avctx->extradata, c2->mode); return libcodec2_init_common(avctx, c2->mode); } @@ -189,7 +189,7 @@ AVCodec ff_libcodec2_decoder = { .init = libcodec2_init_decoder, .close = libcodec2_close, .decode = libcodec2_decode, - .capabilities = 0, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF, .supported_samplerates = (const int[]){ 8000, 0 }, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 }, diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c index bbb3ec1e6..3c2a68b7e 100644 --- a/libavcodec/libdav1d.c +++ b/libavcodec/libdav1d.c @@ -22,11 +22,14 @@ #include #include "libavutil/avassert.h" +#include "libavutil/film_grain_params.h" #include "libavutil/mastering_display_metadata.h" #include "libavutil/imgutils.h" #include "libavutil/opt.h" +#include "atsc_a53.h" #include "avcodec.h" +#include "bytestream.h" #include "decode.h" #include "internal.h" @@ -66,12 +69,11 @@ static int libdav1d_picture_allocator(Dav1dPicture *p, void *cookie) { Libdav1dContext *dav1d = cookie; enum AVPixelFormat format = pix_fmt[p->p.layout][p->seq_hdr->hbd]; - int ret, linesize[4], h = FFALIGN(p->p.h, 128); + int ret, linesize[4], h = FFALIGN(p->p.h, 128), w = FFALIGN(p->p.w, 128); uint8_t *aligned_ptr, *data[4]; AVBufferRef *buf; - ret = av_image_fill_arrays(data, linesize, NULL, format, FFALIGN(p->p.w, 128), - h, DAV1D_PICTURE_ALIGNMENT); + ret = av_image_get_buffer_size(format, w, h, DAV1D_PICTURE_ALIGNMENT); if (ret < 0) return ret; @@ -94,7 +96,8 @@ static int libdav1d_picture_allocator(Dav1dPicture *p, void *cookie) // Use the extra DAV1D_PICTURE_ALIGNMENT padding bytes in the buffer to align it // if required. aligned_ptr = (uint8_t *)FFALIGN((uintptr_t)buf->data, DAV1D_PICTURE_ALIGNMENT); - ret = av_image_fill_pointers(data, format, h, aligned_ptr, linesize); + ret = av_image_fill_arrays(data, linesize, aligned_ptr, format, w, h, + DAV1D_PICTURE_ALIGNMENT); if (ret < 0) { av_buffer_unref(&buf); return ret; @@ -135,6 +138,8 @@ static av_cold int libdav1d_init(AVCodecContext *c) s.frame_size_limit = c->max_pixels; if (dav1d->apply_grain >= 0) s.apply_grain = dav1d->apply_grain; + else if (c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) + s.apply_grain = 0; s.all_layers = dav1d->all_layers; if (dav1d->operating_point >= 0) @@ -272,6 +277,7 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) frame->height * (int64_t)p->frame_hdr->render_width, frame->width * (int64_t)p->frame_hdr->render_height, INT_MAX); + ff_set_sar(c, frame->sample_aspect_ratio); switch (p->seq_hdr->chr) { case DAV1D_CHR_VERTICAL: @@ -307,7 +313,7 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) } // match timestamps and packet size - frame->pts = frame->best_effort_timestamp = p->m.timestamp; + frame->pts = p->m.timestamp; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS frame->pkt_pts = p->m.timestamp; @@ -364,6 +370,72 @@ FF_ENABLE_DEPRECATION_WARNINGS light->MaxCLL = p->content_light->max_content_light_level; light->MaxFALL = p->content_light->max_frame_average_light_level; } + if (p->itut_t35) { + GetByteContext gb; + unsigned int user_identifier; + + bytestream2_init(&gb, p->itut_t35->payload, p->itut_t35->payload_size); + bytestream2_skip(&gb, 1); // terminal provider code + bytestream2_skip(&gb, 1); // terminal provider oriented code + user_identifier = bytestream2_get_be32(&gb); + switch (user_identifier) { + case MKBETAG('G', 'A', '9', '4'): { // closed captions + AVBufferRef *buf = NULL; + + res = ff_parse_a53_cc(&buf, gb.buffer, bytestream2_get_bytes_left(&gb)); + if (res < 0) + goto fail; + if (!res) + break; + + if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_A53_CC, buf)) + av_buffer_unref(&buf); + + c->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; + break; + } + default: // ignore unsupported identifiers + break; + } + } + if (p->frame_hdr->film_grain.present && (!dav1d->apply_grain || + (c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN))) { + AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame); + if (!fgp) { + res = AVERROR(ENOMEM); + goto fail; + } + + fgp->type = AV_FILM_GRAIN_PARAMS_AV1; + fgp->seed = p->frame_hdr->film_grain.data.seed; + fgp->codec.aom.num_y_points = p->frame_hdr->film_grain.data.num_y_points; + fgp->codec.aom.chroma_scaling_from_luma = p->frame_hdr->film_grain.data.chroma_scaling_from_luma; + fgp->codec.aom.scaling_shift = p->frame_hdr->film_grain.data.scaling_shift; + fgp->codec.aom.ar_coeff_lag = p->frame_hdr->film_grain.data.ar_coeff_lag; + fgp->codec.aom.ar_coeff_shift = p->frame_hdr->film_grain.data.ar_coeff_shift; + fgp->codec.aom.grain_scale_shift = p->frame_hdr->film_grain.data.grain_scale_shift; + fgp->codec.aom.overlap_flag = p->frame_hdr->film_grain.data.overlap_flag; + fgp->codec.aom.limit_output_range = p->frame_hdr->film_grain.data.clip_to_restricted_range; + + memcpy(&fgp->codec.aom.y_points, &p->frame_hdr->film_grain.data.y_points, + sizeof(fgp->codec.aom.y_points)); + memcpy(&fgp->codec.aom.num_uv_points, &p->frame_hdr->film_grain.data.num_uv_points, + sizeof(fgp->codec.aom.num_uv_points)); + memcpy(&fgp->codec.aom.uv_points, &p->frame_hdr->film_grain.data.uv_points, + sizeof(fgp->codec.aom.uv_points)); + memcpy(&fgp->codec.aom.ar_coeffs_y, &p->frame_hdr->film_grain.data.ar_coeffs_y, + sizeof(fgp->codec.aom.ar_coeffs_y)); + memcpy(&fgp->codec.aom.ar_coeffs_uv[0], &p->frame_hdr->film_grain.data.ar_coeffs_uv[0], + sizeof(fgp->codec.aom.ar_coeffs_uv[0])); + memcpy(&fgp->codec.aom.ar_coeffs_uv[1], &p->frame_hdr->film_grain.data.ar_coeffs_uv[1], + sizeof(fgp->codec.aom.ar_coeffs_uv[1])); + memcpy(&fgp->codec.aom.uv_mult, &p->frame_hdr->film_grain.data.uv_mult, + sizeof(fgp->codec.aom.uv_mult)); + memcpy(&fgp->codec.aom.uv_mult_luma, &p->frame_hdr->film_grain.data.uv_luma_mult, + sizeof(fgp->codec.aom.uv_mult_luma)); + memcpy(&fgp->codec.aom.uv_offset, &p->frame_hdr->film_grain.data.uv_offset, + sizeof(fgp->codec.aom.uv_offset)); + } res = 0; fail: @@ -389,7 +461,7 @@ static av_cold int libdav1d_close(AVCodecContext *c) static const AVOption libdav1d_options[] = { { "tilethreads", "Tile threads", OFFSET(tile_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_TILE_THREADS, VD }, { "framethreads", "Frame threads", OFFSET(frame_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_FRAME_THREADS, VD }, - { "filmgrain", "Apply Film Grain", OFFSET(apply_grain), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VD }, + { "filmgrain", "Apply Film Grain", OFFSET(apply_grain), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VD | AV_OPT_FLAG_DEPRECATED }, { "oppoint", "Select an operating point of the scalable bitstream", OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 31, VD }, { "alllayers", "Output all spatial layers", OFFSET(all_layers), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD }, { NULL } @@ -412,8 +484,9 @@ AVCodec ff_libdav1d_decoder = { .close = libdav1d_close, .flush = libdav1d_flush, .receive_frame = libdav1d_receive_frame, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SETS_PKT_DTS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SETS_PKT_DTS | + FF_CODEC_CAP_AUTO_THREADS, .priv_class = &libdav1d_class, .wrapper_name = "libdav1d", }; diff --git a/libavcodec/libdavs2.c b/libavcodec/libdavs2.c index 218f3ec23..0f18353c9 100644 --- a/libavcodec/libdavs2.c +++ b/libavcodec/libdavs2.c @@ -23,6 +23,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "davs2.h" typedef struct DAVS2Context { @@ -221,7 +222,8 @@ AVCodec ff_libdavs2_decoder = { .close = davs2_end, .decode = davs2_decode_frame, .flush = davs2_flush, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .wrapper_name = "libdavs2", diff --git a/libavcodec/libgsmdec.c b/libavcodec/libgsmdec.c index 89e1de0fe..1182afae6 100644 --- a/libavcodec/libgsmdec.c +++ b/libavcodec/libgsmdec.c @@ -134,7 +134,7 @@ AVCodec ff_libgsm_decoder = { .close = libgsm_decode_close, .decode = libgsm_decode_frame, .flush = libgsm_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .wrapper_name = "libgsm", }; #endif @@ -149,7 +149,7 @@ AVCodec ff_libgsm_ms_decoder = { .close = libgsm_decode_close, .decode = libgsm_decode_frame, .flush = libgsm_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .wrapper_name = "libgsm", }; #endif diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c index 9a56cc878..9c8258991 100644 --- a/libavcodec/libilbc.c +++ b/libavcodec/libilbc.c @@ -27,6 +27,10 @@ #include "avcodec.h" #include "internal.h" +#ifndef LIBILBC_VERSION_MAJOR +#define LIBILBC_VERSION_MAJOR 2 +#endif + static int get_mode(AVCodecContext *avctx) { if (avctx->block_align == 38) @@ -41,7 +45,11 @@ static int get_mode(AVCodecContext *avctx) typedef struct ILBCDecContext { const AVClass *class; +#if LIBILBC_VERSION_MAJOR < 3 iLBC_Dec_Inst_t decoder; +#else + IlbcDecoder decoder; +#endif int enhance; } ILBCDecContext; @@ -87,7 +95,12 @@ static int ilbc_decode_frame(AVCodecContext *avctx, void *data, int ret; if (s->decoder.no_of_bytes > buf_size) { +#if LIBILBC_VERSION_MAJOR < 3 av_log(avctx, AV_LOG_ERROR, "iLBC frame too short (%u, should be %u)\n", +#else + av_log(avctx, AV_LOG_ERROR, "iLBC frame too short (%u, should be " + "%"SIZE_SPECIFIER")\n", +#endif buf_size, s->decoder.no_of_bytes); return AVERROR_INVALIDDATA; } @@ -111,13 +124,17 @@ AVCodec ff_libilbc_decoder = { .priv_data_size = sizeof(ILBCDecContext), .init = ilbc_decode_init, .decode = ilbc_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .priv_class = &ilbc_dec_class, }; typedef struct ILBCEncContext { const AVClass *class; +#if LIBILBC_VERSION_MAJOR < 3 iLBC_Enc_Inst_t encoder; +#else + IlbcEncoder encoder; +#endif int mode; } ILBCEncContext; diff --git a/libavcodec/libkvazaar.c b/libavcodec/libkvazaar.c index 02bcae3d5..443264985 100644 --- a/libavcodec/libkvazaar.c +++ b/libavcodec/libkvazaar.c @@ -37,6 +37,7 @@ #include "avcodec.h" #include "internal.h" +#include "packet_internal.h" typedef struct LibkvazaarContext { const AVClass *class; @@ -80,13 +81,8 @@ static av_cold int libkvazaar_init(AVCodecContext *avctx) cfg->height = avctx->height; if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { - if (avctx->ticks_per_frame > INT_MAX / avctx->framerate.den) { - av_log(avctx, AV_LOG_ERROR, - "Could not set framerate for kvazaar: integer overflow\n"); - return AVERROR(EINVAL); - } cfg->framerate_num = avctx->framerate.num; - cfg->framerate_denom = avctx->time_base.den * avctx->ticks_per_frame; + cfg->framerate_denom = avctx->framerate.den; } else { if (avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { av_log(avctx, AV_LOG_ERROR, @@ -99,6 +95,9 @@ static av_cold int libkvazaar_init(AVCodecContext *avctx) cfg->target_bitrate = avctx->bit_rate; cfg->vui.sar_width = avctx->sample_aspect_ratio.num; cfg->vui.sar_height = avctx->sample_aspect_ratio.den; + if (avctx->bit_rate) { + cfg->rc_algorithm = KVZ_LAMBDA; + } if (ctx->kvz_params) { AVDictionary *dict = NULL; @@ -175,6 +174,7 @@ static int libkvazaar_encode(AVCodecContext *avctx, kvz_data_chunk *data_out = NULL; uint32_t len_out = 0; int retval = 0; + int pict_type; *got_packet_ptr = 0; @@ -262,6 +262,34 @@ static int libkvazaar_encode(AVCodecContext *avctx, avpkt->flags |= AV_PKT_FLAG_KEY; } + switch (frame_info.slice_type) { + case KVZ_SLICE_I: + pict_type = AV_PICTURE_TYPE_I; + break; + case KVZ_SLICE_P: + pict_type = AV_PICTURE_TYPE_P; + break; + case KVZ_SLICE_B: + pict_type = AV_PICTURE_TYPE_B; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered.\n"); + return AVERROR_EXTERNAL; + } +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame->pict_type = pict_type; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + ff_side_data_set_encoder_stats(avpkt, frame_info.qp * FF_QP2LAMBDA, NULL, 0, pict_type); + +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame->quality = frame_info.qp * FF_QP2LAMBDA; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + *got_packet_ptr = 1; } @@ -302,7 +330,7 @@ AVCodec ff_libkvazaar_encoder = { .long_name = NULL_IF_CONFIG_SMALL("libkvazaar H.265 / HEVC"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, .pix_fmts = pix_fmts, .priv_class = &class, @@ -313,7 +341,8 @@ AVCodec ff_libkvazaar_encoder = { .encode2 = libkvazaar_encode, .close = libkvazaar_close, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_AUTO_THREADS, .wrapper_name = "libkvazaar", }; diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c index 614b3a221..f23bb48d5 100644 --- a/libavcodec/libopencore-amr.c +++ b/libavcodec/libopencore-amr.c @@ -139,7 +139,7 @@ AVCodec ff_libopencore_amrnb_decoder = { .init = amr_nb_decode_init, .close = amr_nb_decode_close, .decode = amr_nb_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; #endif /* CONFIG_LIBOPENCORE_AMRNB_DECODER */ @@ -379,7 +379,7 @@ AVCodec ff_libopencore_amrwb_decoder = { .init = amr_wb_decode_init, .close = amr_wb_decode_close, .decode = amr_wb_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .wrapper_name = "libopencore_amrwb", }; diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c index f63aa5234..0eade7349 100644 --- a/libavcodec/libopenh264enc.c +++ b/libavcodec/libopenh264enc.c @@ -156,7 +156,16 @@ static av_cold int svc_encode_init(AVCodecContext *avctx) (*s->encoder)->GetDefaultParams(s->encoder, ¶m); - param.fMaxFrameRate = 1/av_q2d(avctx->time_base); + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { + param.fMaxFrameRate = av_q2d(avctx->framerate); + } else { + if (avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { + av_log(avctx, AV_LOG_ERROR, + "Could not set framerate for libopenh264enc: integer overflow\n"); + return AVERROR(EINVAL); + } + param.fMaxFrameRate = 1.0 / av_q2d(avctx->time_base) / FFMAX(avctx->ticks_per_frame, 1); + } param.iPicWidth = avctx->width; param.iPicHeight = avctx->height; param.iTargetBitrate = avctx->bit_rate > 0 ? avctx->bit_rate : TARGET_BITRATE_DEFAULT; @@ -438,8 +447,9 @@ AVCodec ff_libopenh264_encoder = { .init = svc_encode_init, .encode2 = svc_encode_frame, .close = svc_encode_close, - .capabilities = AV_CODEC_CAP_AUTO_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, + .capabilities = AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_AUTO_THREADS, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .defaults = svc_enc_defaults, diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c index 1724a4990..082a431c6 100644 --- a/libavcodec/libopusdec.c +++ b/libavcodec/libopusdec.c @@ -235,7 +235,7 @@ AVCodec ff_libopus_decoder = { .close = libopus_decode_close, .decode = libopus_decode, .flush = libopus_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index 13017ac32..70d17f802 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -34,6 +34,7 @@ typedef struct LibopusEncOpts { int vbr; int application; int packet_loss; + int fec; int complexity; float frame_duration; int packet_size; @@ -93,7 +94,7 @@ static void libopus_write_header(AVCodecContext *avctx, int stream_count, bytestream_put_buffer(&p, "OpusHead", 8); bytestream_put_byte(&p, 1); /* Version */ bytestream_put_byte(&p, channels); - bytestream_put_le16(&p, avctx->initial_padding); /* Lookahead samples at 48kHz */ + bytestream_put_le16(&p, avctx->initial_padding * 48000 / avctx->sample_rate); /* Lookahead samples at 48kHz */ bytestream_put_le32(&p, avctx->sample_rate); /* Original sample rate */ bytestream_put_le16(&p, 0); /* Gain of 0dB is recommended. */ @@ -149,6 +150,13 @@ static int libopus_configure_encoder(AVCodecContext *avctx, OpusMSEncoder *enc, "Unable to set expected packet loss percentage: %s\n", opus_strerror(ret)); + ret = opus_multistream_encoder_ctl(enc, + OPUS_SET_INBAND_FEC(opts->fec)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, + "Unable to set inband FEC: %s\n", + opus_strerror(ret)); + if (avctx->cutoff) { ret = opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(opts->max_bandwidth)); @@ -544,6 +552,7 @@ static const AVOption libopus_options[] = { { "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 = 20.0 }, 2.5, 120.0, FLAGS }, { "packet_loss", "Expected packet loss percentage", OFFSET(packet_loss), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, FLAGS }, + { "fec", "Enable inband FEC. Expected packet loss must be non-zero", OFFSET(fec), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 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" }, { "on", "Use variable bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "vbr" }, diff --git a/libavcodec/librav1e.c b/libavcodec/librav1e.c index 6f9b4cce4..37c3007d8 100644 --- a/libavcodec/librav1e.c +++ b/libavcodec/librav1e.c @@ -30,12 +30,15 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avcodec.h" +#include "encode.h" #include "internal.h" typedef struct librav1eContext { const AVClass *class; RaContext *ctx; + AVFrame *frame; + RaFrame *rframe; AVBSFContext *bsf; uint8_t *pass_data; @@ -165,7 +168,12 @@ static av_cold int librav1e_encode_close(AVCodecContext *avctx) rav1e_context_unref(ctx->ctx); ctx->ctx = NULL; } + if (ctx->rframe) { + rav1e_frame_unref(ctx->rframe); + ctx->rframe = NULL; + } + av_frame_free(&ctx->frame); av_bsf_free(&ctx->bsf); av_freep(&ctx->pass_data); @@ -180,6 +188,10 @@ static av_cold int librav1e_encode_init(AVCodecContext *avctx) int rret; int ret = 0; + ctx->frame = av_frame_alloc(); + if (!ctx->frame) + return AVERROR(ENOMEM); + cfg = rav1e_config_default(); if (!cfg) { av_log(avctx, AV_LOG_ERROR, "Could not allocate rav1e config.\n"); @@ -416,39 +428,63 @@ end: return ret; } -static int librav1e_send_frame(AVCodecContext *avctx, const AVFrame *frame) +static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt) { librav1eContext *ctx = avctx->priv_data; - RaFrame *rframe = NULL; + RaFrame *rframe = ctx->rframe; + RaPacket *rpkt = NULL; int ret; - if (frame) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + if (!rframe) { + AVFrame *frame = ctx->frame; - rframe = rav1e_frame_new(ctx->ctx); - if (!rframe) { - av_log(avctx, AV_LOG_ERROR, "Could not allocate new rav1e frame.\n"); - return AVERROR(ENOMEM); - } + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; - for (int i = 0; i < desc->nb_components; i++) { - int shift = i ? desc->log2_chroma_h : 0; - int bytes = desc->comp[0].depth == 8 ? 1 : 2; - rav1e_frame_fill_plane(rframe, i, frame->data[i], - (frame->height >> shift) * frame->linesize[i], - frame->linesize[i], bytes); + if (frame->buf[0]) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + + int64_t *pts = av_malloc(sizeof(int64_t)); + if (!pts) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate PTS buffer.\n"); + return AVERROR(ENOMEM); + } + *pts = frame->pts; + + rframe = rav1e_frame_new(ctx->ctx); + if (!rframe) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate new rav1e frame.\n"); + av_frame_unref(frame); + av_freep(&pts); + return AVERROR(ENOMEM); + } + + for (int i = 0; i < desc->nb_components; i++) { + int shift = i ? desc->log2_chroma_h : 0; + int bytes = desc->comp[0].depth == 8 ? 1 : 2; + rav1e_frame_fill_plane(rframe, i, frame->data[i], + (frame->height >> shift) * frame->linesize[i], + frame->linesize[i], bytes); + } + av_frame_unref(frame); + rav1e_frame_set_opaque(rframe, pts, av_free); } } ret = rav1e_send_frame(ctx->ctx, rframe); if (rframe) - rav1e_frame_unref(rframe); /* No need to unref if flushing. */ + if (ret == RA_ENCODER_STATUS_ENOUGH_DATA) { + ctx->rframe = rframe; /* Queue is full. Store the RaFrame to retry next call */ + } else { + rav1e_frame_unref(rframe); /* No need to unref if flushing. */ + ctx->rframe = NULL; + } switch (ret) { case RA_ENCODER_STATUS_SUCCESS: - break; case RA_ENCODER_STATUS_ENOUGH_DATA: - return AVERROR(EAGAIN); + break; case RA_ENCODER_STATUS_FAILURE: av_log(avctx, AV_LOG_ERROR, "Could not send frame: %s\n", rav1e_status_to_str(ret)); return AVERROR_EXTERNAL; @@ -457,15 +493,6 @@ static int librav1e_send_frame(AVCodecContext *avctx, const AVFrame *frame) return AVERROR_UNKNOWN; } - return 0; -} - -static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt) -{ - librav1eContext *ctx = avctx->priv_data; - RaPacket *rpkt = NULL; - int ret; - retry: if (avctx->flags & AV_CODEC_FLAG_PASS1) { @@ -490,9 +517,7 @@ retry: } return AVERROR_EOF; case RA_ENCODER_STATUS_ENCODED: - if (avctx->internal->draining) - goto retry; - return AVERROR(EAGAIN); + goto retry; case RA_ENCODER_STATUS_NEED_MORE_DATA: if (avctx->internal->draining) { av_log(avctx, AV_LOG_ERROR, "Unexpected error when receiving packet after EOF.\n"); @@ -507,7 +532,7 @@ retry: return AVERROR_UNKNOWN; } - ret = av_new_packet(pkt, rpkt->len); + ret = ff_get_encode_buffer(avctx, pkt, rpkt->len, 0); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate packet.\n"); rav1e_packet_unref(rpkt); @@ -519,7 +544,8 @@ retry: if (rpkt->frame_type == RA_FRAME_TYPE_KEY) pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pts = pkt->dts = rpkt->input_frameno * avctx->ticks_per_frame; + pkt->pts = pkt->dts = *((int64_t *) rpkt->opaque); + av_free(rpkt->opaque); rav1e_packet_unref(rpkt); if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { @@ -592,14 +618,14 @@ AVCodec ff_librav1e_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AV1, .init = librav1e_encode_init, - .send_frame = librav1e_send_frame, .receive_packet = librav1e_receive_packet, .close = librav1e_encode_close, .priv_data_size = sizeof(librav1eContext), .priv_class = &class, .defaults = librav1e_defaults, .pix_fmts = librav1e_pix_fmts, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | + AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS, .wrapper_name = "librav1e", }; diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c index d67c68c7f..b02582b38 100644 --- a/libavcodec/libspeexdec.c +++ b/libavcodec/libspeexdec.c @@ -199,6 +199,6 @@ AVCodec ff_libspeex_decoder = { .close = libspeex_decode_close, .decode = libspeex_decode_frame, .flush = libspeex_decode_flush, - .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .wrapper_name = "libspeex", }; diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c new file mode 100644 index 000000000..cfd93a248 --- /dev/null +++ b/libavcodec/libsvtav1.c @@ -0,0 +1,572 @@ +/* + * Scalable Video Technology for AV1 encoder library plugin + * + * Copyright (c) 2018 Intel Corporation + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/imgutils.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "libavutil/avassert.h" + +#include "internal.h" +#include "encode.h" +#include "packet_internal.h" +#include "avcodec.h" +#include "profiles.h" + +typedef enum eos_status { + EOS_NOT_REACHED = 0, + EOS_SENT, + EOS_RECEIVED +}EOS_STATUS; + +typedef struct SvtContext { + const AVClass *class; + + EbSvtAv1EncConfiguration enc_params; + EbComponentType *svt_handle; + + EbBufferHeaderType *in_buf; + int raw_size; + int max_tu_size; + + AVFrame *frame; + + AVBufferPool *pool; + + EOS_STATUS eos_flag; + + // User options. + int hierarchical_level; + int la_depth; + int enc_mode; + int rc_mode; + int scd; + int qp; + + int tier; + + int tile_columns; + int tile_rows; +} SvtContext; + +static const struct { + EbErrorType eb_err; + int av_err; + const char *desc; +} svt_errors[] = { + { EB_ErrorNone, 0, "success" }, + { EB_ErrorInsufficientResources, AVERROR(ENOMEM), "insufficient resources" }, + { EB_ErrorUndefined, AVERROR(EINVAL), "undefined error" }, + { EB_ErrorInvalidComponent, AVERROR(EINVAL), "invalid component" }, + { EB_ErrorBadParameter, AVERROR(EINVAL), "bad parameter" }, + { EB_ErrorDestroyThreadFailed, AVERROR_EXTERNAL, "failed to destroy thread" }, + { EB_ErrorSemaphoreUnresponsive, AVERROR_EXTERNAL, "semaphore unresponsive" }, + { EB_ErrorDestroySemaphoreFailed, AVERROR_EXTERNAL, "failed to destroy semaphore"}, + { EB_ErrorCreateMutexFailed, AVERROR_EXTERNAL, "failed to create mutex" }, + { EB_ErrorMutexUnresponsive, AVERROR_EXTERNAL, "mutex unresponsive" }, + { EB_ErrorDestroyMutexFailed, AVERROR_EXTERNAL, "failed to destroy mutex" }, + { EB_NoErrorEmptyQueue, AVERROR(EAGAIN), "empty queue" }, +}; + +static int svt_map_error(EbErrorType eb_err, const char **desc) +{ + int i; + + av_assert0(desc); + for (i = 0; i < FF_ARRAY_ELEMS(svt_errors); i++) { + if (svt_errors[i].eb_err == eb_err) { + *desc = svt_errors[i].desc; + return svt_errors[i].av_err; + } + } + *desc = "unknown error"; + return AVERROR_UNKNOWN; +} + +static int svt_print_error(void *log_ctx, EbErrorType err, + const char *error_string) +{ + const char *desc; + int ret = svt_map_error(err, &desc); + + av_log(log_ctx, AV_LOG_ERROR, "%s: %s (0x%x)\n", error_string, desc, err); + + return ret; +} + +static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc) +{ + const int pack_mode_10bit = + (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ? 1 : 0; + const size_t luma_size_8bit = + config->source_width * config->source_height * (1 << pack_mode_10bit); + const size_t luma_size_10bit = + (config->encoder_bit_depth > 8 && pack_mode_10bit == 0) ? luma_size_8bit : 0; + + EbSvtIOFormat *in_data; + + svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2; + + // allocate buffer for in and out + svt_enc->in_buf = av_mallocz(sizeof(*svt_enc->in_buf)); + if (!svt_enc->in_buf) + return AVERROR(ENOMEM); + + svt_enc->in_buf->p_buffer = av_mallocz(sizeof(*in_data)); + if (!svt_enc->in_buf->p_buffer) + return AVERROR(ENOMEM); + + svt_enc->in_buf->size = sizeof(*svt_enc->in_buf); + + return 0; + +} + +static int config_enc_params(EbSvtAv1EncConfiguration *param, + AVCodecContext *avctx) +{ + SvtContext *svt_enc = avctx->priv_data; + const AVPixFmtDescriptor *desc; + + param->source_width = avctx->width; + param->source_height = avctx->height; + + desc = av_pix_fmt_desc_get(avctx->pix_fmt); + param->encoder_bit_depth = desc->comp[0].depth; + + if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 1) + param->encoder_color_format = EB_YUV420; + else if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 0) + param->encoder_color_format = EB_YUV422; + else if (!desc->log2_chroma_w && !desc->log2_chroma_h) + param->encoder_color_format = EB_YUV444; + else { + av_log(avctx, AV_LOG_ERROR , "Unsupported pixel format\n"); + return AVERROR(EINVAL); + } + + if (avctx->profile != FF_PROFILE_UNKNOWN) + param->profile = avctx->profile; + + if (avctx->level != FF_LEVEL_UNKNOWN) + param->level = avctx->level; + + if ((param->encoder_color_format == EB_YUV422 || param->encoder_bit_depth > 10) + && param->profile != FF_PROFILE_AV1_PROFESSIONAL ) { + av_log(avctx, AV_LOG_WARNING, "Forcing Professional profile\n"); + param->profile = FF_PROFILE_AV1_PROFESSIONAL; + } else if (param->encoder_color_format == EB_YUV444 && param->profile != FF_PROFILE_AV1_HIGH) { + av_log(avctx, AV_LOG_WARNING, "Forcing High profile\n"); + param->profile = FF_PROFILE_AV1_HIGH; + } + + // Update param from options + param->hierarchical_levels = svt_enc->hierarchical_level; + param->enc_mode = svt_enc->enc_mode; + param->tier = svt_enc->tier; + param->rate_control_mode = svt_enc->rc_mode; + param->scene_change_detection = svt_enc->scd; + param->qp = svt_enc->qp; + + param->target_bit_rate = avctx->bit_rate; + + if (avctx->gop_size > 0) + param->intra_period_length = avctx->gop_size - 1; + + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { + param->frame_rate_numerator = avctx->framerate.num; + param->frame_rate_denominator = avctx->framerate.den; + } else { + param->frame_rate_numerator = avctx->time_base.den; + param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame; + } + + if (param->rate_control_mode) { + param->max_qp_allowed = avctx->qmax; + param->min_qp_allowed = avctx->qmin; + } + + param->intra_refresh_type = 2; /* Real keyframes only */ + + if (svt_enc->la_depth >= 0) + param->look_ahead_distance = svt_enc->la_depth; + + param->tile_columns = svt_enc->tile_columns; + param->tile_rows = svt_enc->tile_rows; + + return 0; +} + +static int read_in_data(EbSvtAv1EncConfiguration *param, const AVFrame *frame, + EbBufferHeaderType *header_ptr) +{ + EbSvtIOFormat *in_data = (EbSvtIOFormat *)header_ptr->p_buffer; + ptrdiff_t linesizes[4]; + size_t sizes[4]; + int bytes_shift = param->encoder_bit_depth > 8 ? 1 : 0; + int ret, frame_size; + + for (int i = 0; i < 4; i++) + linesizes[i] = frame->linesize[i]; + + ret = av_image_fill_plane_sizes(sizes, frame->format, frame->height, + linesizes); + if (ret < 0) + return ret; + + frame_size = 0; + for (int i = 0; i < 4; i++) { + if (sizes[i] > INT_MAX - frame_size) + return AVERROR(EINVAL); + frame_size += sizes[i]; + } + + in_data->luma = frame->data[0]; + in_data->cb = frame->data[1]; + in_data->cr = frame->data[2]; + + in_data->y_stride = AV_CEIL_RSHIFT(frame->linesize[0], bytes_shift); + in_data->cb_stride = AV_CEIL_RSHIFT(frame->linesize[1], bytes_shift); + in_data->cr_stride = AV_CEIL_RSHIFT(frame->linesize[2], bytes_shift); + + header_ptr->n_filled_len = frame_size; + + return 0; +} + +static av_cold int eb_enc_init(AVCodecContext *avctx) +{ + SvtContext *svt_enc = avctx->priv_data; + EbErrorType svt_ret; + int ret; + + svt_enc->eos_flag = EOS_NOT_REACHED; + + svt_ret = svt_av1_enc_init_handle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params); + if (svt_ret != EB_ErrorNone) { + return svt_print_error(avctx, svt_ret, "Error initializing encoder handle"); + } + + ret = config_enc_params(&svt_enc->enc_params, avctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error configuring encoder parameters\n"); + return ret; + } + + svt_ret = svt_av1_enc_set_parameter(svt_enc->svt_handle, &svt_enc->enc_params); + if (svt_ret != EB_ErrorNone) { + return svt_print_error(avctx, svt_ret, "Error setting encoder parameters"); + } + + svt_ret = svt_av1_enc_init(svt_enc->svt_handle); + if (svt_ret != EB_ErrorNone) { + return svt_print_error(avctx, svt_ret, "Error initializing encoder"); + } + + if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { + EbBufferHeaderType *headerPtr = NULL; + + svt_ret = svt_av1_enc_stream_header(svt_enc->svt_handle, &headerPtr); + if (svt_ret != EB_ErrorNone) { + return svt_print_error(avctx, svt_ret, "Error building stream header"); + } + + avctx->extradata_size = headerPtr->n_filled_len; + avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) { + av_log(avctx, AV_LOG_ERROR, + "Cannot allocate AV1 header of size %d.\n", avctx->extradata_size); + return AVERROR(ENOMEM); + } + + memcpy(avctx->extradata, headerPtr->p_buffer, avctx->extradata_size); + + svt_ret = svt_av1_enc_stream_header_release(headerPtr); + if (svt_ret != EB_ErrorNone) { + return svt_print_error(avctx, svt_ret, "Error freeing stream header"); + } + } + + svt_enc->frame = av_frame_alloc(); + if (!svt_enc->frame) + return AVERROR(ENOMEM); + + return alloc_buffer(&svt_enc->enc_params, svt_enc); +} + +static int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame) +{ + SvtContext *svt_enc = avctx->priv_data; + EbBufferHeaderType *headerPtr = svt_enc->in_buf; + int ret; + + if (!frame) { + EbBufferHeaderType headerPtrLast; + + if (svt_enc->eos_flag == EOS_SENT) + return 0; + + headerPtrLast.n_alloc_len = 0; + headerPtrLast.n_filled_len = 0; + headerPtrLast.n_tick_count = 0; + headerPtrLast.p_app_private = NULL; + headerPtrLast.p_buffer = NULL; + headerPtrLast.flags = EB_BUFFERFLAG_EOS; + + svt_av1_enc_send_picture(svt_enc->svt_handle, &headerPtrLast); + svt_enc->eos_flag = EOS_SENT; + return 0; + } + + ret = read_in_data(&svt_enc->enc_params, frame, headerPtr); + if (ret < 0) + return ret; + + headerPtr->flags = 0; + headerPtr->p_app_private = NULL; + headerPtr->pts = frame->pts; + + svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr); + + return 0; +} + +static AVBufferRef *get_output_ref(AVCodecContext *avctx, SvtContext *svt_enc, int filled_len) +{ + if (filled_len > svt_enc->max_tu_size) { + const int max_frames = 8; + int max_tu_size; + + if (filled_len > svt_enc->raw_size * max_frames) { + av_log(avctx, AV_LOG_ERROR, "TU size > %d raw frame size.\n", max_frames); + return NULL; + } + + max_tu_size = 1 << av_ceil_log2(filled_len); + av_buffer_pool_uninit(&svt_enc->pool); + svt_enc->pool = av_buffer_pool_init(max_tu_size + AV_INPUT_BUFFER_PADDING_SIZE, NULL); + if (!svt_enc->pool) + return NULL; + + svt_enc->max_tu_size = max_tu_size; + } + av_assert0(svt_enc->pool); + + return av_buffer_pool_get(svt_enc->pool); +} + +static int eb_receive_packet(AVCodecContext *avctx, AVPacket *pkt) +{ + SvtContext *svt_enc = avctx->priv_data; + EbBufferHeaderType *headerPtr; + AVFrame *frame = svt_enc->frame; + EbErrorType svt_ret; + AVBufferRef *ref; + int ret = 0, pict_type; + + if (svt_enc->eos_flag == EOS_RECEIVED) + return AVERROR_EOF; + + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + if (ret == AVERROR_EOF) + frame = NULL; + + ret = eb_send_frame(avctx, frame); + if (ret < 0) + return ret; + av_frame_unref(svt_enc->frame); + + svt_ret = svt_av1_enc_get_packet(svt_enc->svt_handle, &headerPtr, svt_enc->eos_flag); + if (svt_ret == EB_NoErrorEmptyQueue) + return AVERROR(EAGAIN); + + ref = get_output_ref(avctx, svt_enc, headerPtr->n_filled_len); + if (!ref) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate output packet.\n"); + svt_av1_enc_release_out_buffer(&headerPtr); + return AVERROR(ENOMEM); + } + pkt->buf = ref; + pkt->data = ref->data; + + memcpy(pkt->data, headerPtr->p_buffer, headerPtr->n_filled_len); + memset(pkt->data + headerPtr->n_filled_len, 0, AV_INPUT_BUFFER_PADDING_SIZE); + + pkt->size = headerPtr->n_filled_len; + pkt->pts = headerPtr->pts; + pkt->dts = headerPtr->dts; + + switch (headerPtr->pic_type) { + case EB_AV1_KEY_PICTURE: + pkt->flags |= AV_PKT_FLAG_KEY; + // fall-through + case EB_AV1_INTRA_ONLY_PICTURE: + pict_type = AV_PICTURE_TYPE_I; + break; + case EB_AV1_INVALID_PICTURE: + pict_type = AV_PICTURE_TYPE_NONE; + break; + default: + pict_type = AV_PICTURE_TYPE_P; + break; + } + + if (headerPtr->pic_type == EB_AV1_NON_REF_PICTURE) + pkt->flags |= AV_PKT_FLAG_DISPOSABLE; + + if (headerPtr->flags & EB_BUFFERFLAG_EOS) + svt_enc->eos_flag = EOS_RECEIVED; + + ff_side_data_set_encoder_stats(pkt, headerPtr->qp * FF_QP2LAMBDA, NULL, 0, pict_type); + + svt_av1_enc_release_out_buffer(&headerPtr); + + return 0; +} + +static av_cold int eb_enc_close(AVCodecContext *avctx) +{ + SvtContext *svt_enc = avctx->priv_data; + + if (svt_enc->svt_handle) { + svt_av1_enc_deinit(svt_enc->svt_handle); + svt_av1_enc_deinit_handle(svt_enc->svt_handle); + } + if (svt_enc->in_buf) { + av_free(svt_enc->in_buf->p_buffer); + av_freep(&svt_enc->in_buf); + } + + av_buffer_pool_uninit(&svt_enc->pool); + av_frame_free(&svt_enc->frame); + + return 0; +} + +#define OFFSET(x) offsetof(SvtContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "hielevel", "Hierarchical prediction levels setting", OFFSET(hierarchical_level), + AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE , "hielevel"}, + { "3level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "hielevel" }, + { "4level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, INT_MIN, INT_MAX, VE, "hielevel" }, + + { "la_depth", "Look ahead distance [0, 120]", OFFSET(la_depth), + AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 120, VE }, + + { "preset", "Encoding preset [0, 8]", + OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = MAX_ENC_PRESET }, 0, MAX_ENC_PRESET, VE }, + + { "tier", "Set operating point tier", OFFSET(tier), + AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "tier" }, + { "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, VE, "tier" }, + { "high", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "tier" }, + + FF_AV1_PROFILE_OPTS + +#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = value }, 0, 0, VE, "avctx.level" + { LEVEL("2.0", 20) }, + { LEVEL("2.1", 21) }, + { LEVEL("2.2", 22) }, + { LEVEL("2.3", 23) }, + { LEVEL("3.0", 30) }, + { LEVEL("3.1", 31) }, + { LEVEL("3.2", 32) }, + { LEVEL("3.3", 33) }, + { LEVEL("4.0", 40) }, + { LEVEL("4.1", 41) }, + { LEVEL("4.2", 42) }, + { LEVEL("4.3", 43) }, + { LEVEL("5.0", 50) }, + { LEVEL("5.1", 51) }, + { LEVEL("5.2", 52) }, + { LEVEL("5.3", 53) }, + { LEVEL("6.0", 60) }, + { LEVEL("6.1", 61) }, + { LEVEL("6.2", 62) }, + { LEVEL("6.3", 63) }, + { LEVEL("7.0", 70) }, + { LEVEL("7.1", 71) }, + { LEVEL("7.2", 72) }, + { LEVEL("7.3", 73) }, +#undef LEVEL + + { "rc", "Bit rate control mode", OFFSET(rc_mode), + AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, VE , "rc"}, + { "cqp", "Constant quantizer", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "rc" }, + { "vbr", "Variable Bit Rate, use a target bitrate for the entire stream", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "rc" }, + { "cvbr", "Constrained Variable Bit Rate, use a target bitrate for each GOP", 0, AV_OPT_TYPE_CONST,{ .i64 = 2 }, INT_MIN, INT_MAX, VE, "rc" }, + + { "qp", "Quantizer to use with cqp rate control mode", OFFSET(qp), + AV_OPT_TYPE_INT, { .i64 = 50 }, 0, 63, VE }, + + { "sc_detection", "Scene change detection", OFFSET(scd), + AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, + + { "tile_columns", "Log2 of number of tile columns to use", OFFSET(tile_columns), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, VE}, + { "tile_rows", "Log2 of number of tile rows to use", OFFSET(tile_rows), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 6, VE}, + + {NULL}, +}; + +static const AVClass class = { + .class_name = "libsvtav1", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVCodecDefault eb_enc_defaults[] = { + { "b", "7M" }, + { "g", "-1" }, + { "qmin", "0" }, + { "qmax", "63" }, + { NULL }, +}; + +AVCodec ff_libsvtav1_encoder = { + .name = "libsvtav1", + .long_name = NULL_IF_CONFIG_SMALL("SVT-AV1(Scalable Video Technology for AV1) encoder"), + .priv_data_size = sizeof(SvtContext), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_AV1, + .init = eb_enc_init, + .receive_packet = eb_receive_packet, + .close = eb_enc_close, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV420P10, + AV_PIX_FMT_NONE }, + .priv_class = &class, + .defaults = eb_enc_defaults, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .wrapper_name = "libsvtav1", +}; diff --git a/libavcodec/libuavs3d.c b/libavcodec/libuavs3d.c new file mode 100644 index 000000000..be03da39e --- /dev/null +++ b/libavcodec/libuavs3d.c @@ -0,0 +1,263 @@ +/* + * RAW AVS3-P2/IEEE1857.10 video demuxer + * Copyright (c) 2020 Zhenyu Wang + * Bingjie Han + * Huiwen Ren + * + * 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/avassert.h" +#include "libavutil/avutil.h" +#include "libavutil/common.h" +#include "libavutil/imgutils.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "avs3.h" +#include "internal.h" +#include "uavs3d.h" + +typedef struct uavs3d_context { + AVCodecContext *avctx; + void *dec_handle; + int frame_threads; + int got_seqhdr; + uavs3d_io_frm_t dec_frame; +} uavs3d_context; + +#define UAVS3D_CHECK_START_CODE(data_ptr, PIC_START_CODE) \ + (AV_RL32(data_ptr) != (PIC_START_CODE << 24) + AVS3_NAL_START_CODE) +static int uavs3d_find_next_start_code(const unsigned char *bs_data, int bs_len, int *left) +{ + const unsigned char *data_ptr = bs_data + 4; + int count = bs_len - 4; + + while (count >= 4 && + UAVS3D_CHECK_START_CODE(data_ptr, AVS3_INTER_PIC_START_CODE) && + UAVS3D_CHECK_START_CODE(data_ptr, AVS3_INTRA_PIC_START_CODE) && + UAVS3D_CHECK_START_CODE(data_ptr, AVS3_SEQ_START_CODE) && + UAVS3D_CHECK_START_CODE(data_ptr, AVS3_FIRST_SLICE_START_CODE) && + UAVS3D_CHECK_START_CODE(data_ptr, AVS3_SEQ_END_CODE)) { + data_ptr++; + count--; + } + + if (count >= 4) { + *left = count; + return 1; + } + + return 0; +} + +static void uavs3d_output_callback(uavs3d_io_frm_t *dec_frame) { + uavs3d_io_frm_t frm_out; + AVFrame *frm = (AVFrame *)dec_frame->priv; + int i; + + if (!frm || !frm->data[0]) { + dec_frame->got_pic = 0; + av_log(NULL, AV_LOG_ERROR, "Invalid AVFrame in uavs3d output.\n"); + return; + } + + frm->pts = dec_frame->pts; + frm->pkt_dts = dec_frame->dts; + frm->pkt_pos = dec_frame->pkt_pos; + frm->pkt_size = dec_frame->pkt_size; + frm->coded_picture_number = dec_frame->dtr; + frm->display_picture_number = dec_frame->ptr; + + if (dec_frame->type < 0 || dec_frame->type >= 4) { + av_log(NULL, AV_LOG_WARNING, "Error frame type in uavs3d: %d.\n", dec_frame->type); + } + + frm->pict_type = ff_avs3_image_type[dec_frame->type]; + frm->key_frame = (frm->pict_type == AV_PICTURE_TYPE_I); + + for (i = 0; i < 3; i++) { + frm_out.width [i] = dec_frame->width[i]; + frm_out.height[i] = dec_frame->height[i]; + frm_out.stride[i] = frm->linesize[i]; + frm_out.buffer[i] = frm->data[i]; + } + + uavs3d_img_cpy_cvt(&frm_out, dec_frame, dec_frame->bit_depth); +} + +static av_cold int libuavs3d_init(AVCodecContext *avctx) +{ + uavs3d_context *h = avctx->priv_data; + uavs3d_cfg_t cdsc; + + cdsc.frm_threads = avctx->thread_count > 0 ? avctx->thread_count : av_cpu_count(); + cdsc.check_md5 = 0; + h->dec_handle = uavs3d_create(&cdsc, uavs3d_output_callback, NULL); + h->got_seqhdr = 0; + + if (!h->dec_handle) { + return AVERROR(ENOMEM); + } + + return 0; +} + +static av_cold int libuavs3d_end(AVCodecContext *avctx) +{ + uavs3d_context *h = avctx->priv_data; + + if (h->dec_handle) { + uavs3d_flush(h->dec_handle, NULL); + uavs3d_delete(h->dec_handle); + h->dec_handle = NULL; + } + h->got_seqhdr = 0; + + return 0; +} + +static void libuavs3d_flush(AVCodecContext * avctx) +{ + uavs3d_context *h = avctx->priv_data; + + if (h->dec_handle) { + uavs3d_reset(h->dec_handle); + } +} + +#define UAVS3D_CHECK_INVALID_RANGE(v, l, r) ((v)<(l)||(v)>(r)) +static int libuavs3d_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) +{ + uavs3d_context *h = avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + const uint8_t *buf_end; + const uint8_t *buf_ptr; + AVFrame *frm = data; + int left_bytes; + int ret, finish = 0; + + *got_frame = 0; + frm->pts = -1; + frm->pict_type = AV_PICTURE_TYPE_NONE; + + if (!buf_size) { + if (h->got_seqhdr) { + if (!frm->data[0] && (ret = ff_get_buffer(avctx, frm, 0)) < 0) { + return ret; + } + h->dec_frame.priv = data; // AVFrame + } + do { + ret = uavs3d_flush(h->dec_handle, &h->dec_frame); + } while (ret > 0 && !h->dec_frame.got_pic); + } else { + uavs3d_io_frm_t *frm_dec = &h->dec_frame; + + buf_ptr = buf; + buf_end = buf + buf_size; + frm_dec->pkt_pos = avpkt->pos; + frm_dec->pkt_size = avpkt->size; + + while (!finish) { + int bs_len; + + if (h->got_seqhdr) { + if (!frm->data[0] && (ret = ff_get_buffer(avctx, frm, 0)) < 0) { + return ret; + } + h->dec_frame.priv = data; // AVFrame + } + + if (uavs3d_find_next_start_code(buf_ptr, buf_end - buf_ptr, &left_bytes)) { + bs_len = buf_end - buf_ptr - left_bytes; + } else { + bs_len = buf_end - buf_ptr; + finish = 1; + } + frm_dec->bs = (unsigned char *)buf_ptr; + frm_dec->bs_len = bs_len; + frm_dec->pts = avpkt->pts; + frm_dec->dts = avpkt->dts; + uavs3d_decode(h->dec_handle, frm_dec); + buf_ptr += bs_len; + + if (frm_dec->nal_type == NAL_SEQ_HEADER) { + struct uavs3d_com_seqh_t *seqh = frm_dec->seqhdr; + if (UAVS3D_CHECK_INVALID_RANGE(seqh->frame_rate_code, 0, 15)) { + av_log(avctx, AV_LOG_ERROR, "Invalid frame rate code: %d.\n", seqh->frame_rate_code); + seqh->frame_rate_code = 3; // default 25 fps + } else { + avctx->framerate.num = ff_avs3_frame_rate_tab[seqh->frame_rate_code].num; + avctx->framerate.den = ff_avs3_frame_rate_tab[seqh->frame_rate_code].den; + } + avctx->has_b_frames = !seqh->low_delay; + avctx->pix_fmt = seqh->bit_depth_internal == 8 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10LE; + ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size); + h->got_seqhdr = 1; + + if (seqh->colour_description) { + if (UAVS3D_CHECK_INVALID_RANGE(seqh->colour_primaries, 0, 9) || + UAVS3D_CHECK_INVALID_RANGE(seqh->transfer_characteristics, 0, 14) || + UAVS3D_CHECK_INVALID_RANGE(seqh->matrix_coefficients, 0, 11)) { + av_log(avctx, AV_LOG_ERROR, + "Invalid colour description: primaries: %d" + "transfer characteristics: %d" + "matrix coefficients: %d.\n", + seqh->colour_primaries, + seqh->transfer_characteristics, + seqh->matrix_coefficients); + } else { + avctx->color_primaries = ff_avs3_color_primaries_tab[seqh->colour_primaries]; + avctx->color_trc = ff_avs3_color_transfer_tab [seqh->transfer_characteristics]; + avctx->colorspace = ff_avs3_color_matrix_tab [seqh->matrix_coefficients]; + } + } + } + if (frm_dec->got_pic) { + break; + } + } + } + + *got_frame = h->dec_frame.got_pic; + + if (!(*got_frame)) { + av_frame_unref(frm); + } + + return buf_ptr - buf; +} + +AVCodec ff_libuavs3d_decoder = { + .name = "libuavs3d", + .long_name = NULL_IF_CONFIG_SMALL("libuavs3d AVS3-P2/IEEE1857.10"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_AVS3, + .priv_data_size = sizeof(uavs3d_context), + .init = libuavs3d_init, + .close = libuavs3d_end, + .decode = libuavs3d_decode_frame, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, + .flush = libuavs3d_flush, + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV420P10LE, + AV_PIX_FMT_NONE }, + .wrapper_name = "libuavs3d", +}; diff --git a/libavcodec/libvorbisdec.c b/libavcodec/libvorbisdec.c index 3c53b8fda..ebb0fcdd8 100644 --- a/libavcodec/libvorbisdec.c +++ b/libavcodec/libvorbisdec.c @@ -217,5 +217,5 @@ AVCodec ff_libvorbis_decoder = { .init = oggvorbis_decode_init, .decode = oggvorbis_decode_frame, .close = oggvorbis_decode_close, - .capabilities = AV_CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_CHANNEL_CONF, }; diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c index f78f872fe..bf9476495 100644 --- a/libavcodec/libvorbisenc.c +++ b/libavcodec/libvorbisenc.c @@ -70,6 +70,17 @@ static const AVClass vorbis_class = { .version = LIBAVUTIL_VERSION_INT, }; +static const uint8_t vorbis_encoding_channel_layout_offsets[8][8] = { + { 0 }, + { 0, 1 }, + { 0, 2, 1 }, + { 0, 1, 2, 3 }, + { 0, 2, 1, 3, 4 }, + { 0, 2, 1, 4, 5, 3 }, + { 0, 2, 1, 5, 6, 4, 3 }, + { 0, 2, 1, 6, 7, 4, 5, 3 }, +}; + static int vorbis_error_to_averror(int ov_err) { switch (ov_err) { @@ -287,7 +298,7 @@ static int libvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, buffer = vorbis_analysis_buffer(&s->vd, samples); for (c = 0; c < channels; c++) { int co = (channels > 8) ? c : - ff_vorbis_encoding_channel_layout_offsets[channels - 1][c]; + vorbis_encoding_channel_layout_offsets[channels - 1][c]; memcpy(buffer[c], frame->extended_data[co], samples * sizeof(*buffer[c])); } diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c index 1063c546b..9b5728fba 100644 --- a/libavcodec/libvpxdec.c +++ b/libavcodec/libvpxdec.c @@ -32,6 +32,7 @@ #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "decode.h" #include "internal.h" #include "libvpx.h" #include "profiles.h" @@ -220,7 +221,7 @@ static int vpx_decode(AVCodecContext *avctx, struct vpx_image *img, *img_alpha; int ret; uint8_t *side_data = NULL; - int side_data_size = 0; + buffer_size_t side_data_size; ret = decode_frame(avctx, &ctx->decoder, avpkt->data, avpkt->size); if (ret) @@ -360,7 +361,8 @@ AVCodec ff_libvpx_vp8_decoder = { .init = vp8_init, .close = vpx_free, .decode = vpx_decode, - .capabilities = AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .wrapper_name = "libvpx", }; #endif /* CONFIG_LIBVPX_VP8_DECODER */ @@ -381,7 +383,8 @@ AVCodec ff_libvpx_vp9_decoder = { .init = vp9_init, .close = vpx_free, .decode = vpx_decode, - .capabilities = AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .init_static_data = ff_vp9_init_static, .profiles = NULL_IF_CONFIG_SMALL(ff_vp9_profiles), .wrapper_name = "libvpx", diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 8e0ea4237..3f36943c1 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -41,6 +41,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" #include "libavutil/opt.h" +#include "libavutil/pixdesc.h" /** * Portion of struct vpx_codec_cx_pkt from vpx_encoder.h. @@ -124,6 +125,9 @@ typedef struct VPxEncoderContext { * encounter a frame with ROI side data. */ int roi_warned; +#if CONFIG_LIBVPX_VP9_ENCODER && defined(VPX_CTRL_VP9E_SET_MAX_INTER_BITRATE_PCT) + vpx_svc_ref_frame_config_t ref_frame_config; +#endif } VPxContext; /** String mappings for enum vp8e_enc_control_id */ @@ -151,6 +155,7 @@ static const char *const ctlidstr[] = { [VP9E_SET_SVC_LAYER_ID] = "VP9E_SET_SVC_LAYER_ID", #if VPX_ENCODER_ABI_VERSION >= 12 [VP9E_SET_SVC_PARAMETERS] = "VP9E_SET_SVC_PARAMETERS", + [VP9E_SET_SVC_REF_FRAME_CONFIG] = "VP9E_SET_SVC_REF_FRAME_CONFIG", #endif [VP9E_SET_SVC] = "VP9E_SET_SVC", #if VPX_ENCODER_ABI_VERSION >= 11 @@ -393,6 +398,20 @@ static void vp8_ts_parse_int_array(int *dest, char *value, size_t value_len, int } } +#if CONFIG_LIBVPX_VP9_ENCODER && defined(VPX_CTRL_VP9E_SET_MAX_INTER_BITRATE_PCT) +static void vp8_ts_parse_int64_array(int64_t *dest, char *value, size_t value_len, int max_entries) +{ + int dest_idx = 0; + char *saveptr = NULL; + char *token = av_strtok(value, ",", &saveptr); + + while (token && dest_idx < max_entries) { + dest[dest_idx++] = strtoull(token, NULL, 10); + token = av_strtok(NULL, ",", &saveptr); + } +} +#endif + static void set_temporal_layer_pattern(int layering_mode, vpx_codec_enc_cfg_t *cfg, int *layer_flags, int *flag_periodicity) { @@ -540,13 +559,94 @@ static int vpx_ts_param_parse(VPxContext *ctx, struct vpx_codec_enc_cfg *enccfg, return 0; } +#if CONFIG_LIBVPX_VP9_ENCODER && defined(VPX_CTRL_VP9E_SET_MAX_INTER_BITRATE_PCT) +static int vpx_ref_frame_config_set_value(vpx_svc_ref_frame_config_t *ref_frame_config, + int ss_number_layers, char *key, char *value) +{ + size_t value_len = strlen(value); + + if (!value_len) + return AVERROR(EINVAL); + + if (!strcmp(key, "rfc_update_buffer_slot")) { + vp8_ts_parse_int_array(ref_frame_config->update_buffer_slot, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_update_last")) { + vp8_ts_parse_int_array(ref_frame_config->update_last, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_update_golden")) { + vp8_ts_parse_int_array(ref_frame_config->update_golden, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_update_alt_ref")) { + vp8_ts_parse_int_array(ref_frame_config->update_alt_ref, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_lst_fb_idx")) { + vp8_ts_parse_int_array(ref_frame_config->lst_fb_idx, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_gld_fb_idx")) { + vp8_ts_parse_int_array(ref_frame_config->gld_fb_idx, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_alt_fb_idx")) { + vp8_ts_parse_int_array(ref_frame_config->alt_fb_idx, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_reference_last")) { + vp8_ts_parse_int_array(ref_frame_config->reference_last, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_reference_golden")) { + vp8_ts_parse_int_array(ref_frame_config->reference_golden, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_reference_alt_ref")) { + vp8_ts_parse_int_array(ref_frame_config->reference_alt_ref, value, value_len, ss_number_layers); + } else if (!strcmp(key, "rfc_reference_duration")) { + vp8_ts_parse_int64_array(ref_frame_config->duration, value, value_len, ss_number_layers); + } + + return 0; +} + +static int vpx_parse_ref_frame_config_element(vpx_svc_ref_frame_config_t *ref_frame_config, + int ss_number_layers, const char **buf) +{ + const char key_val_sep[] = "="; + const char pairs_sep[] = ":"; + char *key = av_get_token(buf, key_val_sep); + char *val = NULL; + int ret; + + if (key && *key && strspn(*buf, key_val_sep)) { + (*buf)++; + val = av_get_token(buf, pairs_sep); + } + + if (key && *key && val && *val) + ret = vpx_ref_frame_config_set_value(ref_frame_config, ss_number_layers, key, val); + else + ret = AVERROR(EINVAL); + + av_freep(&key); + av_freep(&val); + + return ret; +} + +static int vpx_parse_ref_frame_config(vpx_svc_ref_frame_config_t *ref_frame_config, + int ss_number_layers, const char *str) +{ + int ret = 0; + + while (*str) { + ret = + vpx_parse_ref_frame_config_element(ref_frame_config, ss_number_layers, &str); + if (ret < 0) + return ret; + + if (*str) + str++; + } + + return ret; +} +#endif + #if CONFIG_LIBVPX_VP9_ENCODER static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps, struct vpx_codec_enc_cfg *enccfg, vpx_codec_flags_t *flags, vpx_img_fmt_t *img_fmt) { VPxContext av_unused *ctx = avctx->priv_data; - enccfg->g_bit_depth = enccfg->g_input_bit_depth = 8; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + enccfg->g_bit_depth = enccfg->g_input_bit_depth = desc->comp[0].depth; switch (avctx->pix_fmt) { case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUVA420P: @@ -570,8 +670,6 @@ static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps, case AV_PIX_FMT_YUV420P10: case AV_PIX_FMT_YUV420P12: if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) { - enccfg->g_bit_depth = enccfg->g_input_bit_depth = - avctx->pix_fmt == AV_PIX_FMT_YUV420P10 ? 10 : 12; enccfg->g_profile = 2; *img_fmt = VPX_IMG_FMT_I42016; *flags |= VPX_CODEC_USE_HIGHBITDEPTH; @@ -581,8 +679,6 @@ static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps, case AV_PIX_FMT_YUV422P10: case AV_PIX_FMT_YUV422P12: if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) { - enccfg->g_bit_depth = enccfg->g_input_bit_depth = - avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 10 : 12; enccfg->g_profile = 3; *img_fmt = VPX_IMG_FMT_I42216; *flags |= VPX_CODEC_USE_HIGHBITDEPTH; @@ -592,8 +688,6 @@ static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps, case AV_PIX_FMT_YUV440P10: case AV_PIX_FMT_YUV440P12: if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) { - enccfg->g_bit_depth = enccfg->g_input_bit_depth = - avctx->pix_fmt == AV_PIX_FMT_YUV440P10 ? 10 : 12; enccfg->g_profile = 3; *img_fmt = VPX_IMG_FMT_I44016; *flags |= VPX_CODEC_USE_HIGHBITDEPTH; @@ -606,9 +700,6 @@ static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps, case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUV444P12: if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) { - enccfg->g_bit_depth = enccfg->g_input_bit_depth = - avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || - avctx->pix_fmt == AV_PIX_FMT_GBRP10 ? 10 : 12; enccfg->g_profile = 3; *img_fmt = VPX_IMG_FMT_I44416; *flags |= VPX_CODEC_USE_HIGHBITDEPTH; @@ -1130,7 +1221,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (cx_frame->have_sse) { int i; /* Beware of the Y/U/V/all order! */ -#if FF_API_CODED_FRAME +#if FF_API_CODED_FRAME && FF_API_ERROR_FRAME FF_DISABLE_DEPRECATION_WARNINGS avctx->coded_frame->error[0] = cx_frame->sse[1]; avctx->coded_frame->error[1] = cx_frame->sse[2]; @@ -1535,6 +1626,26 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket *pkt, #endif layer_id_valid = 1; } +#if CONFIG_LIBVPX_VP9_ENCODER && defined(VPX_CTRL_VP9E_SET_MAX_INTER_BITRATE_PCT) + en = av_dict_get(frame->metadata, "ref-frame-config", NULL, 0); + + if (en) { + if (avctx->codec_id == AV_CODEC_ID_VP9) { + int ret = vpx_parse_ref_frame_config(&ctx->ref_frame_config, + enccfg->ss_number_layers, en->value); + if (ret < 0) { + av_log(avctx, AV_LOG_WARNING, + "Error parsing ref_frame_config option %s.\n", en->value); + return ret; + } + + codecctl_intp(avctx, VP9E_SET_SVC_REF_FRAME_CONFIG, (int *)&ctx->ref_frame_config); + } else { + av_log(avctx, AV_LOG_WARNING, + "Ignoring ref-frame-config for a non-VP9 codec\n"); + } + } +#endif } if (sd) { @@ -1759,7 +1870,8 @@ AVCodec ff_libvpx_vp8_encoder = { .init = vp8_init, .encode2 = vpx_encode, .close = vpx_free, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE }, .priv_class = &class_vp8, .defaults = defaults, @@ -1789,7 +1901,8 @@ AVCodec ff_libvpx_vp9_encoder = { .init = vp9_init, .encode2 = vpx_encode, .close = vpx_free, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .profiles = NULL_IF_CONFIG_SMALL(ff_vp9_profiles), .priv_class = &class_vp9, .defaults = defaults, diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index d4b1fd0d5..4ddc4973a 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -30,6 +30,7 @@ #include "avcodec.h" #include "internal.h" #include "packet_internal.h" +#include "atsc_a53.h" #if defined(_MSC_VER) #define X264_API_IMPORTS 1 @@ -511,6 +512,10 @@ static av_cold int X264_close(AVCodecContext *avctx) av_freep(&x4->sei); av_freep(&x4->reordered_opaque); +#if X264_BUILD >= 161 + x264_param_cleanup(&x4->params); +#endif + if (x4->enc) { x264_encoder_close(x4->enc); x4->enc = NULL; @@ -519,19 +524,31 @@ static av_cold int X264_close(AVCodecContext *avctx) return 0; } -#define OPT_STR(opt, param) \ - do { \ - int ret; \ - if ((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); \ - else \ - av_log(avctx, AV_LOG_ERROR, \ - "bad value for '%s': '%s'\n", opt, param); \ - return -1; \ - } \ - } while (0) +static int parse_opts(AVCodecContext *avctx, const char *opt, const char *param) +{ + X264Context *x4 = avctx->priv_data; + int ret; + + if ((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); + ret = AVERROR(EINVAL); +#if X264_BUILD >= 161 + } else if (ret == X264_PARAM_ALLOC_FAILED) { + av_log(avctx, AV_LOG_ERROR, + "out of memory parsing option '%s': '%s'\n", opt, param); + ret = AVERROR(ENOMEM); +#endif + } else { + av_log(avctx, AV_LOG_ERROR, + "bad value for '%s': '%s'\n", opt, param); + ret = AVERROR(EINVAL); + } + } + + return ret; +} static int convert_pix_fmt(enum AVPixelFormat pix_fmt) { @@ -581,6 +598,7 @@ static av_cold int X264_init(AVCodecContext *avctx) X264Context *x4 = avctx->priv_data; AVCPBProperties *cpb_props; int sw,sh; + int ret; if (avctx->global_quality > 0) av_log(avctx, AV_LOG_WARNING, "-qscale is ignored, -crf is recommended.\n"); @@ -664,11 +682,11 @@ static av_cold int X264_init(AVCodecContext *avctx) #if FF_API_PRIVATE_OPT FF_DISABLE_DEPRECATION_WARNINGS - if (avctx->chromaoffset >= 0) + if (avctx->chromaoffset) x4->chroma_offset = avctx->chromaoffset; FF_ENABLE_DEPRECATION_WARNINGS #endif - if (x4->chroma_offset >= 0) + if (x4->chroma_offset) x4->params.analyse.i_chroma_qp_offset = x4->chroma_offset; if (avctx->gop_size >= 0) @@ -890,9 +908,14 @@ FF_ENABLE_DEPRECATION_WARNINGS while(p){ char param[4096]={0}, val[4096]={0}; if(sscanf(p, "%4095[^:=]=%4095[^:]", param, val) == 1){ - OPT_STR(param, "1"); - }else - OPT_STR(param, val); + ret = parse_opts(avctx, param, "1"); + if (ret < 0) + return ret; + } else { + ret = parse_opts(avctx, param, val); + if (ret < 0) + return ret; + } p= strchr(p, ':'); p+=!!p; } @@ -902,10 +925,15 @@ FF_ENABLE_DEPRECATION_WARNINGS { AVDictionaryEntry *en = NULL; while (en = av_dict_get(x4->x264_params, "", en, AV_DICT_IGNORE_SUFFIX)) { - if (x264_param_parse(&x4->params, en->key, en->value) < 0) + if ((ret = x264_param_parse(&x4->params, en->key, en->value)) < 0) { av_log(avctx, AV_LOG_WARNING, "Error parsing option '%s = %s'.\n", en->key, en->value); +#if X264_BUILD >= 161 + if (ret == X264_PARAM_ALLOC_FAILED) + return AVERROR(ENOMEM); +#endif + } } } @@ -1023,19 +1051,17 @@ static const enum AVPixelFormat pix_fmts_8bit_rgb[] = { }; #endif +#if X264_BUILD < 153 static av_cold void X264_init_static(AVCodec *codec) { -#if X264_BUILD < 153 if (x264_bit_depth == 8) codec->pix_fmts = pix_fmts_8bit; else if (x264_bit_depth == 9) codec->pix_fmts = pix_fmts_9bit; else if (x264_bit_depth == 10) codec->pix_fmts = pix_fmts_10bit; -#else - codec->pix_fmts = pix_fmts_all; -#endif } +#endif #define OFFSET(x) offsetof(X264Context, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM @@ -1113,7 +1139,7 @@ static const AVOption options[] = { { "vlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "coder" }, { "ac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "coder" }, { "b_strategy", "Strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 2, VE }, - { "chromaoffset", "QP difference between chroma and luma", OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE }, + { "chromaoffset", "QP difference between chroma and luma", OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, VE }, { "sc_threshold", "Scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE }, { "noise_reduction", "Noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE }, @@ -1176,16 +1202,21 @@ AVCodec ff_libx264_encoder = { .init = X264_init, .encode2 = X264_frame, .close = X264_close, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .priv_class = &x264_class, .defaults = x264_defaults, +#if X264_BUILD < 153 .init_static_data = X264_init_static, -#if X264_BUILD >= 158 - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, #else - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .pix_fmts = pix_fmts_all, #endif + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS +#if X264_BUILD >= 158 + | FF_CODEC_CAP_INIT_THREADSAFE +#endif + , .wrapper_name = "libx264", }; #endif @@ -1207,16 +1238,16 @@ AVCodec ff_libx264rgb_encoder = { .init = X264_init, .encode2 = X264_frame, .close = X264_close, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_class = &rgbclass, .defaults = x264_defaults, .pix_fmts = pix_fmts_8bit_rgb, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS #if X264_BUILD >= 158 - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, -#else - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + | FF_CODEC_CAP_INIT_THREADSAFE #endif + , .wrapper_name = "libx264", }; #endif @@ -1238,12 +1269,12 @@ AVCodec ff_libx262_encoder = { .init = X264_init, .encode2 = X264_frame, .close = X264_close, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_class = &X262_class, .defaults = x264_defaults, .pix_fmts = pix_fmts_8bit, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS, .wrapper_name = "libx264", }; #endif diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index f560d7f62..b2008e96f 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -310,8 +310,8 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) if (!cpb_props) return AVERROR(ENOMEM); cpb_props->buffer_size = ctx->params->rc.vbvBufferSize * 1000; - cpb_props->max_bitrate = ctx->params->rc.vbvMaxBitrate * 1000; - cpb_props->avg_bitrate = ctx->params->rc.bitrate * 1000; + cpb_props->max_bitrate = ctx->params->rc.vbvMaxBitrate * 1000LL; + cpb_props->avg_bitrate = ctx->params->rc.bitrate * 1000LL; if (!(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) ctx->params->bRepeatHeaders = 1; @@ -700,7 +700,8 @@ AVCodec ff_libx265_encoder = { .priv_data_size = sizeof(libx265Context), .priv_class = &class, .defaults = x265_defaults, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .wrapper_name = "libx265", }; diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c index 752ff66df..a83b93b83 100644 --- a/libavcodec/libxavs.c +++ b/libavcodec/libxavs.c @@ -475,7 +475,8 @@ AVCodec ff_libxavs_encoder = { .init = XAVS_init, .encode2 = XAVS_frame, .close = XAVS_close, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .priv_class = &xavs_class, .defaults = xavs_defaults, diff --git a/libavcodec/libxavs2.c b/libavcodec/libxavs2.c index 76b57e731..2a4a3e36b 100644 --- a/libavcodec/libxavs2.c +++ b/libavcodec/libxavs2.c @@ -223,6 +223,12 @@ static int xavs2_encode_frame(AVCodecContext *avctx, AVPacket *pkt, pkt->pts = cae->packet.pts; pkt->dts = cae->packet.dts; + if (cae->packet.type == XAVS2_TYPE_IDR || + cae->packet.type == XAVS2_TYPE_I || + cae->packet.type == XAVS2_TYPE_KEYFRAME) { + pkt->flags |= AV_PKT_FLAG_KEY; + } + memcpy(pkt->data, cae->packet.stream, cae->packet.len); pkt->size = cae->packet.len; @@ -288,7 +294,8 @@ AVCodec ff_libxavs2_encoder = { .init = xavs2_init, .encode2 = xavs2_encode_frame, .close = xavs2_close, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, + .caps_internal = FF_CODEC_CAP_AUTO_THREADS, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .priv_class = &libxavs2, diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c index 857077dc3..50601807a 100644 --- a/libavcodec/libxvid.c +++ b/libavcodec/libxvid.c @@ -40,7 +40,6 @@ #include "avcodec.h" #include "internal.h" -#include "libxvid.h" #include "mpegutils.h" #include "packet_internal.h" @@ -685,17 +684,22 @@ FF_ENABLE_DEPRECATION_WARNINGS /* Encode a dummy frame to get the extradata immediately */ if (x->quicktime_format) { AVFrame *picture; - AVPacket packet = {0}; - int size, got_packet, ret; + AVPacket *packet; + int size, got_packet; - av_init_packet(&packet); + packet = av_packet_alloc(); + if (!packet) + return AVERROR(ENOMEM); picture = av_frame_alloc(); - if (!picture) + if (!picture) { + av_packet_free(&packet); return AVERROR(ENOMEM); + } xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); if( xerr ) { + av_packet_free(&packet); av_frame_free(&picture); av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n"); return AVERROR_EXTERNAL; @@ -704,6 +708,7 @@ FF_ENABLE_DEPRECATION_WARNINGS size = ((avctx->width + 1) & ~1) * ((avctx->height + 1) & ~1); picture->data[0] = av_malloc(size + size / 2); if (!picture->data[0]) { + av_packet_free(&packet); av_frame_free(&picture); return AVERROR(ENOMEM); } @@ -711,9 +716,8 @@ FF_ENABLE_DEPRECATION_WARNINGS picture->data[2] = picture->data[1] + size / 4; memset(picture->data[0], 0, size); memset(picture->data[1], 128, size / 2); - ret = xvid_encode_frame(avctx, &packet, picture, &got_packet); - if (!ret && got_packet) - av_packet_unref(&packet); + xvid_encode_frame(avctx, packet, picture, &got_packet); + av_packet_free(&packet); av_free(picture->data[0]); av_frame_free(&picture); xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c index 70eff9e6f..3c68c08a3 100644 --- a/libavcodec/ljpegenc.c +++ b/libavcodec/ljpegenc.c @@ -32,12 +32,14 @@ #include "libavutil/frame.h" #include "libavutil/mem.h" +#include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avcodec.h" #include "idctdsp.h" #include "internal.h" #include "jpegtables.h" +#include "mathops.h" #include "mjpegenc_common.h" #include "mjpeg.h" @@ -309,7 +311,7 @@ FF_ENABLE_DEPRECATION_WARNINGS s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch)); if (!s->scratch) - goto fail; + return AVERROR(ENOMEM); ff_idctdsp_init(&s->idsp, avctx); ff_init_scantable(s->idsp.idct_permutation, &s->scantable, @@ -327,9 +329,6 @@ FF_ENABLE_DEPRECATION_WARNINGS avpriv_mjpeg_val_dc); return 0; -fail: - ljpeg_encode_close(avctx); - return AVERROR(ENOMEM); } #define OFFSET(x) offsetof(LJpegEncContext, x) diff --git a/libavcodec/loco.c b/libavcodec/loco.c index 25dd1575b..99e3a1d02 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -346,4 +346,5 @@ AVCodec ff_loco_decoder = { .init = decode_init, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c index f8da1e126..1d1d04fd8 100644 --- a/libavcodec/lpc.c +++ b/libavcodec/lpc.c @@ -21,6 +21,7 @@ #include "libavutil/common.h" #include "libavutil/lls.h" +#include "libavutil/mem_internal.h" #define LPC_USE_DOUBLE #include "lpc.h" diff --git a/libavcodec/lscrdec.c b/libavcodec/lscrdec.c new file mode 100644 index 000000000..042da84bf --- /dev/null +++ b/libavcodec/lscrdec.c @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2019 Paul B Mahol + * + * 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/frame.h" +#include "libavutil/error.h" +#include "libavutil/log.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "codec.h" +#include "internal.h" +#include "packet.h" +#include "png.h" +#include "pngdsp.h" + +typedef struct LSCRContext { + PNGDSPContext dsp; + AVCodecContext *avctx; + + AVFrame *last_picture; + uint8_t *buffer; + int buffer_size; + uint8_t *crow_buf; + int crow_size; + uint8_t *last_row; + unsigned int last_row_size; + + GetByteContext gb; + uint8_t *image_buf; + int image_linesize; + int row_size; + int cur_h; + int y; + + z_stream zstream; +} LSCRContext; + +static void handle_row(LSCRContext *s) +{ + uint8_t *ptr, *last_row; + + ptr = s->image_buf + s->image_linesize * s->y; + if (s->y == 0) + last_row = s->last_row; + else + last_row = ptr - s->image_linesize; + + ff_png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1, + last_row, s->row_size, 3); + + s->y++; +} + +static int decode_idat(LSCRContext *s, int length) +{ + int ret; + s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb)); + s->zstream.next_in = s->gb.buffer; + + if (length <= 0) + return AVERROR_INVALIDDATA; + + bytestream2_skip(&s->gb, length); + + /* decode one line if possible */ + 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 error %d\n", ret); + return AVERROR_EXTERNAL; + } + if (s->zstream.avail_out == 0) { + if (s->y < s->cur_h) { + handle_row(s); + } + 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(s->avctx, AV_LOG_WARNING, + "%d undecompressed bytes left in buffer\n", s->zstream.avail_in); + return 0; + } + } + return 0; +} + +static int decode_frame_lscr(AVCodecContext *avctx, + void *data, int *got_frame, + AVPacket *avpkt) +{ + LSCRContext *const s = avctx->priv_data; + GetByteContext *gb = &s->gb; + AVFrame *frame = s->last_picture; + int ret, nb_blocks, offset = 0; + + if (avpkt->size < 2) + return AVERROR_INVALIDDATA; + if (avpkt->size == 2) + return 0; + + bytestream2_init(gb, avpkt->data, avpkt->size); + + nb_blocks = bytestream2_get_le16(gb); + if (bytestream2_get_bytes_left(gb) < 2 + nb_blocks * (12 + 8)) + return AVERROR_INVALIDDATA; + + ret = ff_reget_buffer(avctx, frame, + nb_blocks ? 0 : FF_REGET_BUFFER_FLAG_READONLY); + if (ret < 0) + return ret; + + for (int b = 0; b < nb_blocks; b++) { + int x, y, x2, y2, w, h, left; + uint32_t csize, size; + + s->zstream.zalloc = ff_png_zalloc; + s->zstream.zfree = ff_png_zfree; + s->zstream.opaque = NULL; + + if ((ret = inflateInit(&s->zstream)) != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret); + ret = AVERROR_EXTERNAL; + goto end; + } + + bytestream2_seek(gb, 2 + b * 12, SEEK_SET); + + x = bytestream2_get_le16(gb); + y = bytestream2_get_le16(gb); + x2 = bytestream2_get_le16(gb); + y2 = bytestream2_get_le16(gb); + w = x2-x; + s->cur_h = h = y2-y; + + if (w <= 0 || x < 0 || x >= avctx->width || w + x > avctx->width || + h <= 0 || y < 0 || y >= avctx->height || h + y > avctx->height) { + ret = AVERROR_INVALIDDATA; + goto end; + } + + size = bytestream2_get_le32(gb); + + frame->key_frame = (nb_blocks == 1) && + (w == avctx->width) && + (h == avctx->height) && + (x == 0) && (y == 0); + + bytestream2_seek(gb, 2 + nb_blocks * 12 + offset, SEEK_SET); + csize = bytestream2_get_be32(gb); + if (bytestream2_get_le32(gb) != MKTAG('I', 'D', 'A', 'T')) { + ret = AVERROR_INVALIDDATA; + goto end; + } + + offset += size; + left = size; + + s->y = 0; + s->row_size = w * 3; + + av_fast_padded_malloc(&s->buffer, &s->buffer_size, s->row_size + 16); + if (!s->buffer) { + ret = AVERROR(ENOMEM); + goto end; + } + + av_fast_padded_malloc(&s->last_row, &s->last_row_size, s->row_size); + if (!s->last_row) { + ret = AVERROR(ENOMEM); + goto end; + } + + s->crow_size = w * 3 + 1; + s->crow_buf = s->buffer + 15; + s->zstream.avail_out = s->crow_size; + s->zstream.next_out = s->crow_buf; + s->image_buf = frame->data[0] + (avctx->height - y - 1) * frame->linesize[0] + x * 3; + s->image_linesize =-frame->linesize[0]; + + while (left > 16) { + ret = decode_idat(s, csize); + if (ret < 0) + goto end; + left -= csize + 16; + if (left > 16) { + bytestream2_skip(gb, 4); + csize = bytestream2_get_be32(gb); + if (bytestream2_get_le32(gb) != MKTAG('I', 'D', 'A', 'T')) { + ret = AVERROR_INVALIDDATA; + goto end; + } + } + } + + inflateEnd(&s->zstream); + } + + frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + + if ((ret = av_frame_ref(data, frame)) < 0) + return ret; + + *got_frame = 1; +end: + inflateEnd(&s->zstream); + + if (ret < 0) + return ret; + return avpkt->size; +} + +static int lscr_decode_close(AVCodecContext *avctx) +{ + LSCRContext *s = avctx->priv_data; + + av_frame_free(&s->last_picture); + av_freep(&s->buffer); + av_freep(&s->last_row); + + return 0; +} + +static int lscr_decode_init(AVCodecContext *avctx) +{ + LSCRContext *s = avctx->priv_data; + + avctx->color_range = AVCOL_RANGE_JPEG; + avctx->pix_fmt = AV_PIX_FMT_BGR24; + + s->avctx = avctx; + s->last_picture = av_frame_alloc(); + if (!s->last_picture) + return AVERROR(ENOMEM); + + ff_pngdsp_init(&s->dsp); + + return 0; +} + +static void lscr_decode_flush(AVCodecContext *avctx) +{ + LSCRContext *s = avctx->priv_data; + av_frame_unref(s->last_picture); +} + +AVCodec ff_lscr_decoder = { + .name = "lscr", + .long_name = NULL_IF_CONFIG_SMALL("LEAD Screen Capture"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_LSCR, + .priv_data_size = sizeof(LSCRContext), + .init = lscr_decode_init, + .close = lscr_decode_close, + .decode = decode_frame_lscr, + .flush = lscr_decode_flush, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, +}; diff --git a/libavcodec/lzw.h b/libavcodec/lzw.h index 6af8a6b83..dae4d0522 100644 --- a/libavcodec/lzw.h +++ b/libavcodec/lzw.h @@ -54,10 +54,8 @@ struct LZWEncodeState; extern const int ff_lzw_encode_state_size; void ff_lzw_encode_init(struct LZWEncodeState *s, uint8_t *outbuf, int outsize, - int maxbits, enum FF_LZW_MODES mode, - void (*lzw_put_bits)(struct PutBitContext *, int, unsigned int)); + int maxbits, enum FF_LZW_MODES mode, int little_endian); int ff_lzw_encode(struct LZWEncodeState * s, const uint8_t * inbuf, int insize); -int ff_lzw_encode_flush(struct LZWEncodeState *s, - void (*lzw_flush_put_bits)(struct PutBitContext *)); +int ff_lzw_encode_flush(struct LZWEncodeState *s); #endif /* AVCODEC_LZW_H */ diff --git a/libavcodec/lzwenc.c b/libavcodec/lzwenc.c index 03080ee58..e693d7427 100644 --- a/libavcodec/lzwenc.c +++ b/libavcodec/lzwenc.c @@ -60,7 +60,7 @@ typedef struct LZWEncodeState { int output_bytes; ///< Number of written bytes int last_code; ///< Value of last output code or LZW_PREFIX_EMPTY enum FF_LZW_MODES mode; ///< TIFF or GIF - void (*put_bits)(PutBitContext *, int, unsigned); ///< GIF is LE while TIFF is BE + int little_endian; ///< GIF is LE while TIFF is BE }LZWEncodeState; @@ -113,7 +113,10 @@ static inline int hashOffset(const int head) static inline void writeCode(LZWEncodeState * s, int c) { av_assert2(0 <= c && c < 1 << s->bits); - s->put_bits(&s->pb, s->bits, c); + if (s->little_endian) + put_bits_le(&s->pb, s->bits, c); + else + put_bits(&s->pb, s->bits, c); } @@ -200,8 +203,7 @@ static int writtenBytes(LZWEncodeState *s){ * @param maxbits Maximum length of code */ void ff_lzw_encode_init(LZWEncodeState *s, uint8_t *outbuf, int outsize, - int maxbits, enum FF_LZW_MODES mode, - void (*lzw_put_bits)(PutBitContext *, int, unsigned)) + int maxbits, enum FF_LZW_MODES mode, int little_endian) { s->clear_code = 256; s->end_code = 257; @@ -214,7 +216,7 @@ void ff_lzw_encode_init(LZWEncodeState *s, uint8_t *outbuf, int outsize, s->last_code = LZW_PREFIX_EMPTY; s->bits = 9; s->mode = mode; - s->put_bits = lzw_put_bits; + s->little_endian = little_endian; } /** @@ -257,16 +259,22 @@ int ff_lzw_encode(LZWEncodeState * s, const uint8_t * inbuf, int insize) * @param s LZW state * @return Number of bytes written or -1 on error */ -int ff_lzw_encode_flush(LZWEncodeState *s, - void (*lzw_flush_put_bits)(PutBitContext *)) +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); + if (s->little_endian) { + if (s->mode == FF_LZW_GIF) + put_bits_le(&s->pb, 1, 0); - lzw_flush_put_bits(&s->pb); + flush_put_bits_le(&s->pb); + } else { + if (s->mode == FF_LZW_GIF) + put_bits(&s->pb, 1, 0); + + flush_put_bits(&s->pb); + } s->last_code = -1; return writtenBytes(s); diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c index 731854959..13cb34611 100644 --- a/libavcodec/magicyuv.c +++ b/libavcodec/magicyuv.c @@ -22,8 +22,9 @@ #include #include +#define CACHED_BITSTREAM_READER !ARCH_X86_32 + #include "libavutil/pixdesc.h" -#include "libavutil/qsort.h" #include "avcodec.h" #include "bytestream.h" @@ -45,9 +46,8 @@ typedef enum Prediction { } Prediction; typedef struct HuffEntry { - uint16_t sym; uint8_t len; - uint32_t code; + uint16_t sym; } HuffEntry; typedef struct MagicYUVContext { @@ -61,131 +61,33 @@ typedef struct MagicYUVContext { int color_matrix; // video color matrix int flags; int interlaced; // video is interlaced - uint8_t *buf; // pointer to AVPacket->data + const uint8_t *buf; // pointer to AVPacket->data int hshift[4]; int vshift[4]; Slice *slices[4]; // slice bitstream positions for each plane unsigned int slices_size[4]; // slice sizes for each plane - uint8_t len[4][4096]; // table of code lengths for each plane VLC vlc[4]; // VLC for each plane - int (*huff_build)(VLC *vlc, uint8_t *len); int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata, int j, int threadnr); LLVidDSPContext llviddsp; } MagicYUVContext; -static int huff_cmp_len(const void *a, const void *b) -{ - const HuffEntry *aa = a, *bb = b; - return (aa->len - bb->len) * 256 + aa->sym - bb->sym; -} - -static int huff_cmp_len10(const void *a, const void *b) -{ - const HuffEntry *aa = a, *bb = b; - return (aa->len - bb->len) * 1024 + aa->sym - bb->sym; -} - -static int huff_cmp_len12(const void *a, const void *b) -{ - const HuffEntry *aa = a, *bb = b; - return (aa->len - bb->len) * 4096 + aa->sym - bb->sym; -} - -static int huff_build10(VLC *vlc, uint8_t *len) -{ - HuffEntry he[1024]; - uint32_t codes[1024]; - uint8_t bits[1024]; - uint16_t syms[1024]; - uint32_t code; - int i; - - for (i = 0; i < 1024; i++) { - he[i].sym = 1023 - i; - he[i].len = len[i]; - if (len[i] == 0 || len[i] > 32) - return AVERROR_INVALIDDATA; - } - AV_QSORT(he, 1024, HuffEntry, huff_cmp_len10); - - code = 1; - for (i = 1023; i >= 0; i--) { - codes[i] = code >> (32 - he[i].len); - bits[i] = he[i].len; - syms[i] = he[i].sym; - code += 0x80000000u >> (he[i].len - 1); - } - - ff_free_vlc(vlc); - return ff_init_vlc_sparse(vlc, FFMIN(he[1023].len, 12), 1024, - bits, sizeof(*bits), sizeof(*bits), - codes, sizeof(*codes), sizeof(*codes), - syms, sizeof(*syms), sizeof(*syms), 0); -} - -static int huff_build12(VLC *vlc, uint8_t *len) +static int huff_build(const uint8_t len[], uint16_t codes_pos[33], + VLC *vlc, int nb_elems, void *logctx) { HuffEntry he[4096]; - uint32_t codes[4096]; - uint8_t bits[4096]; - uint16_t syms[4096]; - uint32_t code; - int i; - for (i = 0; i < 4096; i++) { - he[i].sym = 4095 - i; - he[i].len = len[i]; - if (len[i] == 0 || len[i] > 32) - return AVERROR_INVALIDDATA; - } - AV_QSORT(he, 4096, HuffEntry, huff_cmp_len12); + for (int i = 31; i > 0; i--) + codes_pos[i] += codes_pos[i + 1]; - code = 1; - for (i = 4095; i >= 0; i--) { - codes[i] = code >> (32 - he[i].len); - bits[i] = he[i].len; - syms[i] = he[i].sym; - code += 0x80000000u >> (he[i].len - 1); - } + for (unsigned i = nb_elems; i-- > 0;) + he[--codes_pos[len[i]]] = (HuffEntry){ len[i], i }; ff_free_vlc(vlc); - return ff_init_vlc_sparse(vlc, FFMIN(he[4095].len, 14), 4096, - bits, sizeof(*bits), sizeof(*bits), - codes, sizeof(*codes), sizeof(*codes), - syms, sizeof(*syms), sizeof(*syms), 0); -} - -static int huff_build(VLC *vlc, uint8_t *len) -{ - HuffEntry he[256]; - uint32_t codes[256]; - uint8_t bits[256]; - uint8_t syms[256]; - uint32_t code; - int i; - - for (i = 0; i < 256; i++) { - he[i].sym = 255 - i; - he[i].len = len[i]; - if (len[i] == 0 || len[i] > 32) - return AVERROR_INVALIDDATA; - } - AV_QSORT(he, 256, HuffEntry, huff_cmp_len); - - code = 1; - for (i = 255; i >= 0; i--) { - codes[i] = code >> (32 - he[i].len); - bits[i] = he[i].len; - syms[i] = he[i].sym; - code += 0x80000000u >> (he[i].len - 1); - } - - ff_free_vlc(vlc); - return ff_init_vlc_sparse(vlc, FFMIN(he[255].len, 12), 256, - bits, sizeof(*bits), sizeof(*bits), - codes, sizeof(*codes), sizeof(*codes), - syms, sizeof(*syms), sizeof(*syms), 0); + return ff_init_vlc_from_lengths(vlc, FFMIN(he[0].len, 12), nb_elems, + &he[0].len, sizeof(he[0]), + &he[0].sym, sizeof(he[0]), sizeof(he[0].sym), + 0, 0, logctx); } static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1, @@ -259,7 +161,7 @@ static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, if (pix < 0) return AVERROR_INVALIDDATA; - dst[x] = max - pix; + dst[x] = pix; } dst += stride; } @@ -358,27 +260,26 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]); ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced); ptrdiff_t stride = p->linesize[i]; + const uint8_t *slice = s->buf + s->slices[i][j].start; int flags, pred; - int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start, - s->slices[i][j].size); - if (ret < 0) - return ret; - - flags = get_bits(&gb, 8); - pred = get_bits(&gb, 8); + flags = bytestream_get_byte(&slice); + pred = bytestream_get_byte(&slice); dst = p->data[i] + j * sheight * stride; if (flags & 1) { - if (get_bits_left(&gb) < 8* width * height) + if (s->slices[i][j].size - 2 < width * height) return AVERROR_INVALIDDATA; for (k = 0; k < height; k++) { - for (x = 0; x < width; x++) - dst[x] = get_bits(&gb, 8); - + bytestream_get_buffer(&slice, dst, width); dst += stride; } } else { + int ret = init_get_bits8(&gb, slice, s->slices[i][j].size - 2); + + if (ret < 0) + return ret; + for (k = 0; k < height; k++) { for (x = 0; x < width; x++) { int pix; @@ -389,7 +290,7 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, if (pix < 0) return AVERROR_INVALIDDATA; - dst[x] = 255 - pix; + dst[x] = pix; } dst += stride; } @@ -473,25 +374,40 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, return 0; } -static int build_huffman(AVCodecContext *avctx, GetBitContext *gbit, int max) +static int build_huffman(AVCodecContext *avctx, const uint8_t *table, + int table_size, int max) { MagicYUVContext *s = avctx->priv_data; + GetByteContext gb; + uint8_t len[4096]; + uint16_t length_count[33] = { 0 }; int i = 0, j = 0, k; - memset(s->len, 0, sizeof(s->len)); - while (get_bits_left(gbit) >= 8) { - int b = get_bits(gbit, 1); - int x = get_bits(gbit, 7); - int l = get_bitsz(gbit, b * 8) + 1; + bytestream2_init(&gb, table, table_size); - for (k = 0; k < l; k++) - if (j + k < max) - s->len[i][j + k] = x; + while (bytestream2_get_bytes_left(&gb) > 0) { + int b = bytestream2_peek_byteu(&gb) & 0x80; + int x = bytestream2_get_byteu(&gb) & ~0x80; + int l = 1; + + if (b) { + if (bytestream2_get_bytes_left(&gb) <= 0) + break; + l += bytestream2_get_byteu(&gb); + } + k = j + l; + if (k > max || x == 0 || x > 32) { + av_log(avctx, AV_LOG_ERROR, "Invalid Huffman codes\n"); + return AVERROR_INVALIDDATA; + } + + length_count[x] += l; + for (; j < k; j++) + len[j] = x; - j += l; if (j == max) { j = 0; - if (s->huff_build(&s->vlc[i], s->len[i])) { + if (huff_build(len, length_count, &s->vlc[i], max, avctx)) { av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); return AVERROR_INVALIDDATA; } @@ -499,9 +415,7 @@ static int build_huffman(AVCodecContext *avctx, GetBitContext *gbit, int max) if (i == s->planes) { break; } - } else if (j > max) { - av_log(avctx, AV_LOG_ERROR, "Invalid Huffman codes\n"); - return AVERROR_INVALIDDATA; + memset(length_count, 0, sizeof(length_count)); } } @@ -519,24 +433,26 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, MagicYUVContext *s = avctx->priv_data; ThreadFrame frame = { .f = data }; AVFrame *p = data; - GetByteContext gbyte; - GetBitContext gbit; + GetByteContext gb; uint32_t first_offset, offset, next_offset, header_size, slice_width; int width, height, format, version, table_size; int ret, i, j; - bytestream2_init(&gbyte, avpkt->data, avpkt->size); - if (bytestream2_get_le32(&gbyte) != MKTAG('M', 'A', 'G', 'Y')) + if (avpkt->size < 36) return AVERROR_INVALIDDATA; - header_size = bytestream2_get_le32(&gbyte); + bytestream2_init(&gb, avpkt->data, avpkt->size); + if (bytestream2_get_le32u(&gb) != MKTAG('M', 'A', 'G', 'Y')) + return AVERROR_INVALIDDATA; + + header_size = bytestream2_get_le32u(&gb); if (header_size < 32 || header_size >= avpkt->size) { av_log(avctx, AV_LOG_ERROR, "header or packet too small %"PRIu32"\n", header_size); return AVERROR_INVALIDDATA; } - version = bytestream2_get_byte(&gbyte); + version = bytestream2_get_byteu(&gb); if (version != 7) { avpriv_request_sample(avctx, "Version %d", version); return AVERROR_PATCHWELCOME; @@ -549,7 +465,7 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, s->decorrelate = 0; s->bps = 8; - format = bytestream2_get_byte(&gbyte); + format = bytestream2_get_byteu(&gb); switch (format) { case 0x65: avctx->pix_fmt = AV_PIX_FMT_GBRP; @@ -614,46 +530,50 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, avctx->pix_fmt = AV_PIX_FMT_GRAY10; s->bps = 10; break; + case 0x7b: + avctx->pix_fmt = AV_PIX_FMT_YUV420P10; + s->hshift[1] = + s->vshift[1] = + s->hshift[2] = + s->vshift[2] = 1; + s->bps = 10; + break; default: avpriv_request_sample(avctx, "Format 0x%X", format); return AVERROR_PATCHWELCOME; } s->max = 1 << s->bps; s->magy_decode_slice = s->bps == 8 ? magy_decode_slice : magy_decode_slice10; - if ( s->bps == 8) - s->huff_build = huff_build; - else - s->huff_build = s->bps == 10 ? huff_build10 : huff_build12; s->planes = av_pix_fmt_count_planes(avctx->pix_fmt); - bytestream2_skip(&gbyte, 1); - s->color_matrix = bytestream2_get_byte(&gbyte); - s->flags = bytestream2_get_byte(&gbyte); + bytestream2_skipu(&gb, 1); + s->color_matrix = bytestream2_get_byteu(&gb); + s->flags = bytestream2_get_byteu(&gb); s->interlaced = !!(s->flags & 2); - bytestream2_skip(&gbyte, 3); + bytestream2_skipu(&gb, 3); - width = bytestream2_get_le32(&gbyte); - height = bytestream2_get_le32(&gbyte); + width = bytestream2_get_le32u(&gb); + height = bytestream2_get_le32u(&gb); ret = ff_set_dimensions(avctx, width, height); if (ret < 0) return ret; - slice_width = bytestream2_get_le32(&gbyte); + slice_width = bytestream2_get_le32u(&gb); if (slice_width != avctx->coded_width) { avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width); return AVERROR_PATCHWELCOME; } - s->slice_height = bytestream2_get_le32(&gbyte); + s->slice_height = bytestream2_get_le32u(&gb); if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) { av_log(avctx, AV_LOG_ERROR, "invalid slice height: %d\n", s->slice_height); return AVERROR_INVALIDDATA; } - bytestream2_skip(&gbyte, 4); + bytestream2_skipu(&gb, 4); s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height; - if (s->nb_slices > INT_MAX / sizeof(Slice)) { + if (s->nb_slices > INT_MAX / FFMAX(sizeof(Slice), 4 * 5)) { av_log(avctx, AV_LOG_ERROR, "invalid number of slices: %d\n", s->nb_slices); return AVERROR_INVALIDDATA; @@ -670,12 +590,14 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, } } + if (bytestream2_get_bytes_left(&gb) <= s->nb_slices * s->planes * 5) + return AVERROR_INVALIDDATA; for (i = 0; i < s->planes; i++) { av_fast_malloc(&s->slices[i], &s->slices_size[i], s->nb_slices * sizeof(Slice)); if (!s->slices[i]) return AVERROR(ENOMEM); - offset = bytestream2_get_le32(&gbyte); + offset = bytestream2_get_le32u(&gb); if (offset >= avpkt->size - header_size) return AVERROR_INVALIDDATA; @@ -685,11 +607,13 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, for (j = 0; j < s->nb_slices - 1; j++) { s->slices[i][j].start = offset + header_size; - next_offset = bytestream2_get_le32(&gbyte); + next_offset = bytestream2_get_le32u(&gb); if (next_offset <= offset || next_offset >= avpkt->size - header_size) return AVERROR_INVALIDDATA; s->slices[i][j].size = next_offset - offset; + if (s->slices[i][j].size < 2) + return AVERROR_INVALIDDATA; offset = next_offset; } @@ -700,20 +624,17 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (bytestream2_get_byte(&gbyte) != s->planes) + if (bytestream2_get_byteu(&gb) != s->planes) return AVERROR_INVALIDDATA; - bytestream2_skip(&gbyte, s->nb_slices * s->planes); + bytestream2_skipu(&gb, s->nb_slices * s->planes); - table_size = header_size + first_offset - bytestream2_tell(&gbyte); + table_size = header_size + first_offset - bytestream2_tell(&gb); if (table_size < 2) return AVERROR_INVALIDDATA; - ret = init_get_bits8(&gbit, avpkt->data + bytestream2_tell(&gbyte), table_size); - if (ret < 0) - return ret; - - ret = build_huffman(avctx, &gbit, s->max); + ret = build_huffman(avctx, avpkt->data + bytestream2_tell(&gb), + table_size, s->max); if (ret < 0) return ret; diff --git a/libavcodec/magicyuvenc.c b/libavcodec/magicyuvenc.c index e9fe3bf51..d53fe6f32 100644 --- a/libavcodec/magicyuvenc.c +++ b/libavcodec/magicyuvenc.c @@ -40,7 +40,6 @@ typedef enum Prediction { } Prediction; typedef struct HuffEntry { - uint8_t sym; uint8_t len; uint32_t code; } HuffEntry; @@ -245,32 +244,18 @@ static av_cold int magy_encode_init(AVCodecContext *avctx) return 0; } -static int magy_huff_cmp_len(const void *a, const void *b) +static void calculate_codes(HuffEntry *he, uint16_t codes_count[33]) { - const HuffEntry *aa = a, *bb = b; - return (aa->len - bb->len) * 256 + aa->sym - bb->sym; -} - -static int huff_cmp_sym(const void *a, const void *b) -{ - const HuffEntry *aa = a, *bb = b; - return bb->sym - aa->sym; -} - -static void calculate_codes(HuffEntry *he) -{ - uint32_t code; - int i; - - AV_QSORT(he, 256, HuffEntry, magy_huff_cmp_len); - - code = 1; - for (i = 255; i >= 0; i--) { - he[i].code = code >> (32 - he[i].len); - code += 0x80000000u >> (he[i].len - 1); + for (unsigned i = 32, nb_codes = 0; i > 0; i--) { + uint16_t curr = codes_count[i]; // # of leafs of length i + codes_count[i] = nb_codes / 2; // # of non-leaf nodes on level i + nb_codes = codes_count[i] + curr; // # of nodes on level i } - AV_QSORT(he, 256, HuffEntry, huff_cmp_sym); + for (unsigned i = 0; i < 256; i++) { + he[i].code = codes_count[he[i].len]; + codes_count[he[i].len]++; + } } static void count_usage(uint8_t *src, int width, @@ -295,12 +280,13 @@ typedef struct PackageMergerList { static int compare_by_prob(const void *a, const void *b) { - PTable a_val = *(PTable *)a; - PTable b_val = *(PTable *)b; - return a_val.prob - b_val.prob; + const PTable *a2 = a; + const PTable *b2 = b; + return a2->prob - b2->prob; } static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts, + uint16_t codes_counts[33], int size, int max_length) { PackageMergerList list_a, list_b, *to = &list_a, *from = &list_b, *temp; @@ -356,8 +342,8 @@ static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts, } for (i = 0; i < size; i++) { - distincts[i].sym = i; distincts[i].len = nbits[i]; + codes_counts[nbits[i]]++; } } @@ -366,18 +352,19 @@ static int encode_table(AVCodecContext *avctx, uint8_t *dst, PutBitContext *pb, HuffEntry *he) { PTable counts[256] = { {0} }; + uint16_t codes_counts[33] = { 0 }; int i; count_usage(dst, width, height, counts); for (i = 0; i < 256; i++) { counts[i].prob++; - counts[i].value = 255 - i; + counts[i].value = i; } - magy_huffman_compute_bits(counts, he, 256, 12); + magy_huffman_compute_bits(counts, he, codes_counts, 256, 12); - calculate_codes(he); + calculate_codes(he, codes_counts); for (i = 0; i < 256; i++) { put_bits(pb, 1, 0); @@ -587,4 +574,5 @@ AVCodec ff_magicyuv_encoder = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/mdct15.h b/libavcodec/mdct15.h index 42e60f3e1..035246ff9 100644 --- a/libavcodec/mdct15.h +++ b/libavcodec/mdct15.h @@ -23,6 +23,8 @@ #include +#include "libavutil/mem_internal.h" + #include "fft.h" typedef struct MDCT15Context { diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index 7e34ec568..101e55833 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -27,6 +27,8 @@ * This is very similar to intra-only MPEG-1. */ +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "blockdsp.h" #include "bswapdsp.h" @@ -71,8 +73,6 @@ static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n) } else { component = (n <= 3 ? 0 : n - 4 + 1); diff = decode_dc(&a->gb, component); - if (diff >= 0xffff) - return AVERROR_INVALIDDATA; a->last_dc[component] += diff; block[0] = a->last_dc[component] * (1 << 3); } @@ -260,4 +260,5 @@ AVCodec ff_mdec_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/me_cmp.c b/libavcodec/me_cmp.c index ae248c52f..60545248b 100644 --- a/libavcodec/me_cmp.c +++ b/libavcodec/me_cmp.c @@ -22,6 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "copy_block.h" #include "simple_idct.h" @@ -1011,31 +1012,8 @@ WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c) WRAPPER8_16_SQ(rd8x8_c, rd16_c) WRAPPER8_16_SQ(bit8x8_c, bit16_c) -int ff_check_alignment(void) -{ - static int did_fail = 0; - LOCAL_ALIGNED_16(int, aligned, [4]); - - if ((intptr_t)aligned & 15) { - if (!did_fail) { -#if HAVE_MMX || HAVE_ALTIVEC - av_log(NULL, AV_LOG_ERROR, - "Compiler did not align stack variables. Libavcodec has been miscompiled\n" - "and may be very slow or crash. This is not a bug in libavcodec,\n" - "but in the compiler. You may try recompiling using gcc >= 4.2.\n" - "Do not report crashes to FFmpeg developers.\n"); -#endif - did_fail=1; - } - return -1; - } - return 0; -} - av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx) { - ff_check_alignment(); - c->sum_abs_dctelem = sum_abs_dctelem_c; /* TODO [0] 16 [1] 8 */ diff --git a/libavcodec/me_cmp.h b/libavcodec/me_cmp.h index 0a589e3c3..e9b5161c9 100644 --- a/libavcodec/me_cmp.h +++ b/libavcodec/me_cmp.h @@ -79,8 +79,6 @@ typedef struct MECmpContext { me_cmp_func median_sad[6]; } MECmpContext; -int ff_check_alignment(void); - void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx); void ff_me_cmp_init_alpha(MECmpContext *c, AVCodecContext *avctx); void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx); diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c index 79abc8b6a..c829941d6 100644 --- a/libavcodec/mediacodec_wrapper.c +++ b/libavcodec/mediacodec_wrapper.c @@ -45,6 +45,7 @@ struct JNIAMediaCodecListFields { jmethodID get_codec_capabilities_id; jmethodID get_supported_types_id; jmethodID is_encoder_id; + jmethodID is_software_only_id; jclass codec_capabilities_class; jfieldID color_formats_id; @@ -81,6 +82,7 @@ static const struct FFJniField jni_amediacodeclist_mapping[] = { { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_capabilities_id), 1 }, { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_supported_types_id), 1 }, { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_encoder_id), 1 }, + { "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_software_only_id), 0 }, { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_capabilities_class), 1 }, { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, color_formats_id), 1 }, @@ -441,6 +443,41 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e goto done_with_info; } + if (jfields.is_software_only_id) { + int is_software_only = (*env)->CallBooleanMethod(env, info, jfields.is_software_only_id); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done; + } + + if (is_software_only) { + goto done_with_info; + } + } + + codec_name = (*env)->CallObjectMethod(env, info, jfields.get_name_id); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done; + } + + name = ff_jni_jstring_to_utf_chars(env, codec_name, log_ctx); + if (!name) { + goto done; + } + + if (codec_name) { + (*env)->DeleteLocalRef(env, codec_name); + codec_name = NULL; + } + + /* Skip software decoders */ + if ( + strstr(name, "OMX.google") || + strstr(name, "OMX.ffmpeg") || + (strstr(name, "OMX.SEC") && strstr(name, ".sw.")) || + !strcmp(name, "OMX.qcom.video.decoder.hevcswvdec")) { + goto done_with_info; + } + type_count = (*env)->GetArrayLength(env, types); for (j = 0; j < type_count; j++) { int k; @@ -456,74 +493,51 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e goto done; } - if (!av_strcasecmp(supported_type, mime)) { - codec_name = (*env)->CallObjectMethod(env, info, jfields.get_name_id); - if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; - } + if (av_strcasecmp(supported_type, mime)) { + goto done_with_type; + } - name = ff_jni_jstring_to_utf_chars(env, codec_name, log_ctx); - if (!name) { - goto done; - } + capabilities = (*env)->CallObjectMethod(env, info, jfields.get_codec_capabilities_id, type); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done; + } - if (codec_name) { - (*env)->DeleteLocalRef(env, codec_name); - codec_name = NULL; - } + profile_levels = (*env)->GetObjectField(env, capabilities, jfields.profile_levels_id); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done; + } - /* Skip software decoders */ - if ( - strstr(name, "OMX.google") || - strstr(name, "OMX.ffmpeg") || - (strstr(name, "OMX.SEC") && strstr(name, ".sw.")) || - !strcmp(name, "OMX.qcom.video.decoder.hevcswvdec")) { - av_freep(&name); - goto done_with_type; - } + profile_count = (*env)->GetArrayLength(env, profile_levels); + if (!profile_count) { + found_codec = 1; + } + for (k = 0; k < profile_count; k++) { + int supported_profile = 0; - capabilities = (*env)->CallObjectMethod(env, info, jfields.get_codec_capabilities_id, type); - if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; - } - - profile_levels = (*env)->GetObjectField(env, capabilities, jfields.profile_levels_id); - if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; - } - - profile_count = (*env)->GetArrayLength(env, profile_levels); - if (!profile_count) { + if (profile < 0) { found_codec = 1; + break; } - for (k = 0; k < profile_count; k++) { - int supported_profile = 0; - if (profile < 0) { - found_codec = 1; - break; - } + profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done; + } - profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k); - if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; - } + supported_profile = (*env)->GetIntField(env, profile_level, jfields.profile_id); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done; + } - supported_profile = (*env)->GetIntField(env, profile_level, jfields.profile_id); - if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; - } + found_codec = profile == supported_profile; - found_codec = profile == supported_profile; + if (profile_level) { + (*env)->DeleteLocalRef(env, profile_level); + profile_level = NULL; + } - if (profile_level) { - (*env)->DeleteLocalRef(env, profile_level); - profile_level = NULL; - } - - if (found_codec) { - break; - } + if (found_codec) { + break; } } @@ -548,8 +562,6 @@ done_with_type: if (found_codec) { break; } - - av_freep(&name); } done_with_info: @@ -566,6 +578,8 @@ done_with_info: if (found_codec) { break; } + + av_freep(&name); } done: diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c index 25410021e..ad592d14a 100644 --- a/libavcodec/mediacodecdec.c +++ b/libavcodec/mediacodecdec.c @@ -167,8 +167,11 @@ static int h264_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format) ff_AMediaFormat_setBuffer(format, "csd-1", (void*)data, data_size); av_freep(&data); } else { - av_log(avctx, AV_LOG_ERROR, "Could not extract PPS/SPS from extradata"); - ret = AVERROR_INVALIDDATA; + const int warn = is_avc && (avctx->codec_tag == MKTAG('a','v','c','1') || + avctx->codec_tag == MKTAG('a','v','c','2')); + av_log(avctx, warn ? AV_LOG_WARNING : AV_LOG_DEBUG, + "Could not extract PPS/SPS from extradata\n"); + ret = 0; } done: @@ -254,8 +257,10 @@ static int hevc_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format) av_freep(&data); } else { - av_log(avctx, AV_LOG_ERROR, "Could not extract VPS/PPS/SPS from extradata"); - ret = AVERROR_INVALIDDATA; + const int warn = is_nalff && avctx->codec_tag == MKTAG('h','v','c','1'); + av_log(avctx, warn ? AV_LOG_WARNING : AV_LOG_DEBUG, + "Could not extract VPS/PPS/SPS from extradata\n"); + ret = 0; } done: @@ -486,7 +491,7 @@ static void mediacodec_decode_flush(AVCodecContext *avctx) ff_mediacodec_dec_flush(avctx, s->ctx); } -static const AVCodecHWConfigInternal *mediacodec_hw_configs[] = { +static const AVCodecHWConfigInternal *const mediacodec_hw_configs[] = { &(const AVCodecHWConfigInternal) { .public = { .pix_fmt = AV_PIX_FMT_MEDIACODEC, diff --git a/libavcodec/metasound.c b/libavcodec/metasound.c index 87cd7cb21..27cf1dd83 100644 --- a/libavcodec/metasound.c +++ b/libavcodec/metasound.c @@ -341,22 +341,16 @@ static av_cold int metasound_decode_init(AVCodecContext *avctx) tctx->mtab = &ff_metasound_mode2224s; break; case (1 << 16) + (44 << 8) + 32: + case (2 << 16) + (44 << 8) + 32: tctx->mtab = &ff_metasound_mode4432; break; - case (2 << 16) + (44 << 8) + 32: - tctx->mtab = &ff_metasound_mode4432s; - break; case (1 << 16) + (44 << 8) + 40: + case (2 << 16) + (44 << 8) + 40: tctx->mtab = &ff_metasound_mode4440; break; - case (2 << 16) + (44 << 8) + 40: - tctx->mtab = &ff_metasound_mode4440s; - break; case (1 << 16) + (44 << 8) + 48: - tctx->mtab = &ff_metasound_mode4448; - break; case (2 << 16) + (44 << 8) + 48: - tctx->mtab = &ff_metasound_mode4448s; + tctx->mtab = &ff_metasound_mode4448; break; default: av_log(avctx, AV_LOG_ERROR, @@ -385,7 +379,7 @@ AVCodec ff_metasound_decoder = { .init = metasound_decode_init, .close = ff_twinvq_decode_close, .decode = ff_twinvq_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/libavcodec/metasound_data.c b/libavcodec/metasound_data.c index da2548af9..22b2730dd 100644 --- a/libavcodec/metasound_data.c +++ b/libavcodec/metasound_data.c @@ -19,8 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include "metasound_data.h" +#if CONFIG_METASOUND_DECODER static const int16_t cb0806sl0[] = { -417, -225, -84, 16, -106, -34, -246, -164, 112, 48, -47, 36, -65, -68, -172, -1655, @@ -12101,8 +12103,9 @@ static const int16_t fcb44sm[] = { -623, -588, 38, -58, 975, 1529, -986, -891, -1121, -619, 1967, -463, -7, 632, 768, 953, }; +#endif /* CONFIG_METASOUND_DECODER */ -static const float lsp8[] = { +const float ff_metasound_lsp8[] = { 0.2702, 0.5096, 0.6437, 0.7672, 0.9639, 1.0696, 1.2625, 1.5789, 1.9285, 2.2383, 2.5129, 2.8470, 0.1740, 0.3677, 0.6082, 0.8387, 1.1084, 1.3721, 1.6362, 1.8733, 2.0640, 2.3442, 2.6087, 2.8548, @@ -12168,73 +12171,7 @@ static const float lsp8[] = { 0.2217, 0.2632, 0.2706, 0.2624, 0.2162, 0.2453, 0.2460, 0.2531, }; -static const float lsp8s[] = { - 0.2702, 0.5096, 0.6437, 0.7672, 0.9639, 1.0696, 1.2625, 1.5789, - 1.9285, 2.2383, 2.5129, 2.8470, 0.1740, 0.3677, 0.6082, 0.8387, - 1.1084, 1.3721, 1.6362, 1.8733, 2.0640, 2.3442, 2.6087, 2.8548, - 0.1536, 0.3279, 0.5143, 0.6859, 0.9763, 1.2744, 1.5605, 1.8566, - 2.1007, 2.3450, 2.6075, 2.8850, 0.2075, 0.4533, 0.7709, 1.0377, - 1.2953, 1.5132, 1.7826, 2.0351, 2.2590, 2.4996, 2.6795, 2.8748, - 0.1393, 0.2453, 0.3754, 0.5453, 0.8148, 1.1289, 1.4389, 1.7592, - 2.0353, 2.3215, 2.5934, 2.8588, 0.1250, 0.3627, 0.7613, 1.1380, - 1.4163, 1.5565, 1.6920, 1.8130, 1.8678, 2.0427, 2.4318, 2.8544, - 0.2256, 0.4223, 0.6452, 0.8599, 1.0673, 1.3118, 1.5486, 1.8366, - 2.0759, 2.3026, 2.5284, 2.8030, 0.2304, 0.4404, 0.6891, 0.8964, - 1.1510, 1.4202, 1.6483, 1.8580, 2.1181, 2.3686, 2.6078, 2.9128, - 0.2230, 0.3816, 0.5520, 0.6062, 0.7909, 1.0988, 1.4330, 1.7846, - 2.0713, 2.3457, 2.6048, 2.8708, 0.2447, 0.5800, 0.8249, 0.9905, - 1.1721, 1.3990, 1.6694, 1.9064, 2.1307, 2.4255, 2.6815, 2.9117, - 0.1974, 0.3812, 0.5802, 0.7759, 0.9280, 1.1547, 1.4170, 1.6369, - 1.8890, 2.2587, 2.5626, 2.8239, 0.1209, 0.2510, 0.4841, 0.8048, - 1.1197, 1.3563, 1.6073, 1.8926, 2.1350, 2.3669, 2.6291, 2.8985, - 0.2352, 0.4347, 0.6582, 0.8178, 0.9548, 1.1654, 1.4942, 1.8812, - 2.1703, 2.3779, 2.6412, 2.8871, 0.2091, 0.4084, 0.6730, 0.9151, - 1.1259, 1.3262, 1.5937, 1.8129, 2.0237, 2.3317, 2.5778, 2.8620, - 0.1167, 0.2406, 0.4520, 0.7298, 0.9848, 1.2448, 1.5137, 1.7874, - 2.0280, 2.3020, 2.5914, 2.8794, 0.3003, 0.4966, 0.6520, 0.8505, - 1.1600, 1.3981, 1.5805, 1.8346, 2.0757, 2.3102, 2.5760, 2.8499, - 0.2451, 0.4163, 0.5960, 0.7805, 0.9507, 1.2438, 1.5587, 1.8581, - 2.0735, 2.3198, 2.5704, 2.8220, 0.3112, 0.5517, 0.7032, 0.8528, - 1.1489, 1.4257, 1.6848, 1.9388, 2.1577, 2.4265, 2.6678, 2.9051, - 0.2249, 0.3897, 0.5559, 0.7473, 1.0158, 1.3581, 1.6914, 1.9930, - 2.1843, 2.3534, 2.5512, 2.8065, 0.2600, 0.4574, 0.7349, 0.9691, - 1.1696, 1.3848, 1.6335, 1.9021, 2.1174, 2.3481, 2.5902, 2.8390, - 0.2246, 0.3372, 0.4560, 0.5249, 0.7056, 1.0273, 1.3810, 1.7132, - 1.9819, 2.2574, 2.5410, 2.8491, 0.1419, 0.4834, 0.8835, 1.1453, - 1.2839, 1.4224, 1.5593, 1.7877, 2.1285, 2.4070, 2.6043, 2.8511, - 0.1886, 0.3677, 0.5617, 0.8099, 1.1277, 1.3841, 1.5804, 1.8136, - 2.0307, 2.2805, 2.5399, 2.8322, 0.2351, 0.4151, 0.6675, 0.8713, - 1.0464, 1.3292, 1.6586, 1.9281, 2.1355, 2.3495, 2.6222, 2.8782, - 0.2700, 0.4489, 0.6206, 0.7121, 0.7737, 0.9848, 1.3658, 1.7433, - 2.0139, 2.2243, 2.4806, 2.8175, 0.2479, 0.4425, 0.6490, 0.8745, - 1.1161, 1.3849, 1.6773, 1.9566, 2.1491, 2.3624, 2.5685, 2.8114, - 0.2035, 0.3701, 0.5567, 0.7953, 1.0082, 1.2758, 1.5373, 1.7822, - 2.0175, 2.2601, 2.4759, 2.7771, 0.1856, 0.3461, 0.5998, 0.9041, - 1.2383, 1.4612, 1.6667, 1.9305, 2.1617, 2.4107, 2.6477, 2.8656, - 0.2107, 0.3715, 0.5289, 0.6651, 0.8420, 1.1168, 1.4401, 1.7230, - 1.9901, 2.2687, 2.5452, 2.8655, 0.1218, 0.2999, 0.6348, 0.9482, - 1.2745, 1.5876, 1.9129, 2.2348, 2.4020, 2.4922, 2.6351, 2.8357, - 0.1617, 0.3483, 0.5869, 0.8163, 1.0366, 1.2344, 1.4609, 1.7029, - 1.9476, 2.2337, 2.5258, 2.8442, 0.2505, 0.4894, 0.7510, 0.9152, - 1.0845, 1.3657, 1.6528, 1.8346, 2.0160, 2.2811, 2.5338, 2.8136, - 0.0947, 0.1158, 0.0578, -0.0337, -0.0066, 0.0104, -0.0447, -0.0505, - -0.0778, -0.0293, 0.0251, -0.0143, 0.0349, -0.0227, -0.0909, 0.0523, - 0.0325, -0.0410, -0.1045, -0.0899, -0.0009, 0.0075, -0.0575, -0.0855, - -0.0129, 0.0575, 0.0597, 0.0391, 0.0371, -0.0184, -0.0083, 0.0287, - 0.0143, 0.0167, 0.0120, -0.0168, 0.0452, 0.0223, -0.0352, 0.0119, - -0.0496, -0.0965, -0.0661, -0.0072, 0.1099, 0.0843, -0.0087, -0.0478, - -0.0128, -0.0120, -0.0004, 0.0731, 0.1047, 0.0630, 0.0196, -0.0103, - -0.0399, -0.0986, -0.0912, -0.0390, -0.0247, -0.0694, -0.0749, -0.0066, - 0.0223, 0.0634, 0.0343, -0.0134, 0.0727, 0.0241, 0.0066, 0.0437, - 0.0610, 0.0364, 0.0248, -0.0358, -0.0686, -0.0104, 0.0426, 0.0088, - -0.0137, -0.0165, 0.0671, 0.0815, -0.0863, -0.0644, -0.0088, 0.0023, - 0.0482, 0.1174, 0.1270, 0.0594, 0.0165, 0.0949, 0.1098, 0.0137, - 0.4951, 0.4999, 0.4958, 0.4907, 0.4984, 0.4965, 0.4958, 0.4996, - 0.4987, 0.4958, 0.4986, 0.4977, 0.2841, 0.2186, 0.1474, 0.1687, - 0.2217, 0.2632, 0.2706, 0.2624, 0.2162, 0.2453, 0.2460, 0.2531, -}; - -static const float lsp11[] = { +const float ff_metasound_lsp11[] = { 0.1103, 0.3862, 0.6863, 0.8447, 0.9231, 1.0261, 1.1248, 1.4057, 1.6621, 1.8010, 1.8692, 2.0704, 2.3490, 2.6060, 2.7539, 2.8977, 0.1273, 0.2407, 0.3812, 0.6004, 0.7767, 0.9383, 1.1344, 1.3351, @@ -12401,174 +12338,7 @@ static const float lsp11[] = { 0.1486, 0.1342, 0.1215, 0.1423, 0.1634, 0.1588, 0.1539, 0.1857, }; -static const float lsp11s[] = { - 0.1103, 0.3862, 0.6863, 0.8447, 0.9231, 1.0261, 1.1248, 1.4057, - 1.6621, 1.8010, 1.8692, 2.0704, 2.3490, 2.6060, 2.7539, 2.8977, - 0.1273, 0.2407, 0.3812, 0.6004, 0.7767, 0.9383, 1.1344, 1.3351, - 1.5233, 1.7262, 1.9466, 2.1739, 2.3495, 2.5162, 2.7164, 2.9202, - 0.2010, 0.3330, 0.4488, 0.6465, 0.8046, 0.9889, 1.1479, 1.2964, - 1.4770, 1.6606, 1.8789, 2.1155, 2.3287, 2.5199, 2.7101, 2.9119, - 0.1168, 0.2197, 0.3279, 0.4691, 0.6268, 0.8251, 1.0533, 1.2714, - 1.4712, 1.6762, 1.8831, 2.1114, 2.3230, 2.5297, 2.7365, 2.9270, - 0.1405, 0.3109, 0.4986, 0.6891, 0.8634, 1.0583, 1.2594, 1.4349, - 1.6232, 1.8116, 1.9905, 2.1935, 2.3799, 2.5656, 2.7661, 2.9486, - 0.1703, 0.3057, 0.4403, 0.5225, 0.5969, 0.8110, 1.0729, 1.3215, - 1.5407, 1.7381, 1.9477, 2.1680, 2.3586, 2.5612, 2.7630, 2.9410, - 0.1128, 0.2628, 0.4523, 0.6495, 0.8176, 0.9816, 1.1746, 1.3710, - 1.5568, 1.7518, 1.9497, 2.1452, 2.3346, 2.5389, 2.7362, 2.9264, - 0.1809, 0.3287, 0.5205, 0.7264, 0.9298, 1.1217, 1.2970, 1.4894, - 1.6874, 1.8493, 2.0576, 2.2382, 2.4097, 2.6041, 2.7796, 2.9389, - 0.2502, 0.4709, 0.6892, 0.8346, 0.9209, 1.0455, 1.2399, 1.4616, - 1.6463, 1.8380, 2.0475, 2.2397, 2.4665, 2.6550, 2.7701, 2.8895, - 0.1040, 0.2340, 0.3964, 0.5740, 0.7764, 0.9941, 1.2000, 1.4014, - 1.6024, 1.7974, 1.9939, 2.1959, 2.3783, 2.5663, 2.7613, 2.9484, - 0.1912, 0.3393, 0.4743, 0.6313, 0.8014, 0.9879, 1.1855, 1.3922, - 1.5678, 1.7289, 1.9271, 2.1165, 2.3089, 2.5414, 2.7448, 2.9269, - 0.0965, 0.2025, 0.3398, 0.4990, 0.6934, 0.9386, 1.1730, 1.3766, - 1.5783, 1.7783, 1.9790, 2.1831, 2.3670, 2.5578, 2.7641, 2.9516, - 0.2126, 0.3652, 0.5545, 0.7170, 0.8674, 1.0640, 1.2558, 1.4061, - 1.5904, 1.8095, 1.9760, 2.1505, 2.3549, 2.5575, 2.7023, 2.8877, - 0.1827, 0.3426, 0.4894, 0.6488, 0.7960, 0.9535, 1.1217, 1.2798, - 1.4566, 1.6453, 1.8044, 2.0042, 2.2379, 2.4611, 2.6697, 2.8966, - 0.2034, 0.3822, 0.5231, 0.6960, 0.9200, 1.0394, 1.1616, 1.3772, - 1.5493, 1.7330, 1.9646, 2.1233, 2.3334, 2.5361, 2.7087, 2.9470, - 0.1050, 0.2060, 0.3705, 0.5998, 0.8337, 1.0577, 1.2559, 1.4327, - 1.6334, 1.8165, 1.9853, 2.2058, 2.4063, 2.5818, 2.7625, 2.9458, - 0.1419, 0.4053, 0.6660, 0.8911, 1.0405, 1.1547, 1.2506, 1.3926, - 1.5669, 1.7527, 1.9694, 2.2054, 2.3889, 2.5743, 2.7586, 2.9174, - 0.1514, 0.2825, 0.4309, 0.5772, 0.7470, 0.9703, 1.1462, 1.3316, - 1.5321, 1.7259, 1.9282, 2.1266, 2.3106, 2.5064, 2.7067, 2.9094, - 0.1693, 0.3156, 0.4878, 0.6635, 0.8206, 0.9569, 1.1154, 1.3064, - 1.5109, 1.7184, 1.9179, 2.1036, 2.2763, 2.4820, 2.6949, 2.9105, - 0.1432, 0.2718, 0.4241, 0.5564, 0.6939, 0.9011, 1.1582, 1.3948, - 1.6181, 1.8024, 1.9814, 2.1740, 2.3459, 2.5456, 2.7491, 2.9307, - 0.2294, 0.3857, 0.5590, 0.7434, 0.9189, 1.0941, 1.2740, 1.4456, - 1.6178, 1.7994, 1.9689, 2.1644, 2.3525, 2.5385, 2.7468, 2.9405, - 0.1667, 0.3109, 0.4612, 0.6032, 0.7375, 0.8866, 1.0840, 1.3053, - 1.4982, 1.7044, 1.9146, 2.1117, 2.2942, 2.4983, 2.7084, 2.9132, - 0.1810, 0.3205, 0.4696, 0.6231, 0.7641, 0.9959, 1.2427, 1.4361, - 1.5889, 1.7544, 1.9083, 2.0733, 2.2457, 2.4461, 2.6793, 2.9098, - 0.1164, 0.3753, 0.6068, 0.7503, 1.0100, 1.2131, 1.3793, 1.5302, - 1.6300, 1.7950, 1.9057, 2.1031, 2.3830, 2.5745, 2.6949, 2.8779, - 0.1571, 0.4378, 0.6735, 0.8312, 0.8944, 0.9818, 1.1622, 1.4094, - 1.6423, 1.8066, 1.9258, 2.1838, 2.4363, 2.6279, 2.7358, 2.8790, - 0.1398, 0.2686, 0.4248, 0.6156, 0.7870, 1.0035, 1.2012, 1.3689, - 1.5363, 1.7398, 1.9604, 2.1619, 2.3345, 2.5097, 2.7271, 2.9368, - 0.1913, 0.3338, 0.4987, 0.6446, 0.7852, 1.0163, 1.1886, 1.3610, - 1.5379, 1.7230, 1.8880, 2.0862, 2.2960, 2.4928, 2.7122, 2.9151, - 0.0908, 0.1752, 0.2899, 0.5365, 0.7761, 1.0100, 1.2124, 1.4060, - 1.6019, 1.8010, 1.9774, 2.1905, 2.3733, 2.5623, 2.7660, 2.9565, - 0.1773, 0.3179, 0.4925, 0.6864, 0.8452, 0.9897, 1.1860, 1.3722, - 1.5515, 1.7658, 1.9802, 2.1819, 2.3620, 2.5442, 2.7250, 2.9220, - 0.1286, 0.2341, 0.3689, 0.5364, 0.7176, 0.9350, 1.1083, 1.2943, - 1.4974, 1.7059, 1.9047, 2.1145, 2.3242, 2.5361, 2.7453, 2.9329, - 0.2273, 0.3834, 0.5565, 0.7192, 0.8431, 0.9962, 1.1763, 1.3571, - 1.5774, 1.7419, 1.9202, 2.1131, 2.2919, 2.4898, 2.6895, 2.9180, - 0.1775, 0.3058, 0.4274, 0.6023, 0.8151, 1.0734, 1.3211, 1.5178, - 1.6706, 1.8154, 1.9686, 2.1537, 2.3461, 2.5276, 2.7181, 2.9121, - 0.1653, 0.4304, 0.6361, 0.7824, 0.9183, 1.0452, 1.2071, 1.4077, - 1.6206, 1.8299, 2.0089, 2.1948, 2.3900, 2.5982, 2.7844, 2.9487, - 0.1492, 0.2609, 0.3820, 0.5485, 0.7243, 0.9319, 1.1538, 1.3579, - 1.5266, 1.7002, 1.8873, 2.1016, 2.3175, 2.5221, 2.7241, 2.9243, - 0.2074, 0.3781, 0.5209, 0.6869, 0.8577, 0.9875, 1.1849, 1.3568, - 1.4907, 1.7335, 1.8902, 2.1224, 2.3099, 2.4918, 2.7023, 2.8765, - 0.1359, 0.2254, 0.3286, 0.4432, 0.6586, 0.8964, 1.1125, 1.3523, - 1.5626, 1.7579, 1.9846, 2.1905, 2.3548, 2.5542, 2.7663, 2.9346, - 0.1430, 0.2966, 0.4685, 0.6493, 0.8315, 1.0304, 1.2220, 1.4082, - 1.5995, 1.7888, 1.9774, 2.1737, 2.3607, 2.5577, 2.7558, 2.9405, - 0.1477, 0.2694, 0.4056, 0.5626, 0.7051, 0.8647, 1.0491, 1.2488, - 1.4814, 1.7072, 1.9150, 2.1147, 2.3038, 2.5144, 2.7184, 2.9202, - 0.1690, 0.3033, 0.4580, 0.6686, 0.8536, 1.0293, 1.2124, 1.3998, - 1.5718, 1.7607, 1.9580, 2.1245, 2.2971, 2.4762, 2.6896, 2.9177, - 0.1092, 0.2779, 0.4853, 0.6880, 0.9011, 1.0953, 1.2752, 1.4618, - 1.6623, 1.8484, 2.0264, 2.2152, 2.4017, 2.5835, 2.7671, 2.9436, - 0.1497, 0.3637, 0.6014, 0.8032, 0.9963, 1.1835, 1.3741, 1.5698, - 1.7382, 1.9094, 2.0710, 2.2392, 2.4082, 2.5926, 2.7762, 2.9536, - 0.1434, 0.2492, 0.3966, 0.5934, 0.8033, 1.0657, 1.2796, 1.4276, - 1.5745, 1.7833, 1.9288, 2.1247, 2.3543, 2.5412, 2.7049, 2.8872, - 0.1612, 0.2926, 0.4574, 0.6387, 0.8265, 1.0180, 1.1808, 1.3526, - 1.5564, 1.7536, 1.9187, 2.1192, 2.3149, 2.5006, 2.7101, 2.9217, - 0.0828, 0.1863, 0.3235, 0.5050, 0.7250, 0.9867, 1.2093, 1.3941, - 1.5980, 1.7932, 1.9809, 2.1894, 2.3918, 2.5773, 2.7540, 2.9329, - 0.2001, 0.3655, 0.5290, 0.6761, 0.8027, 0.9972, 1.2090, 1.4255, - 1.6085, 1.7825, 1.9804, 2.1681, 2.3457, 2.5325, 2.7319, 2.9196, - 0.1505, 0.2767, 0.4254, 0.6054, 0.7821, 0.9567, 1.1294, 1.3080, - 1.4984, 1.6954, 1.8666, 2.0736, 2.2875, 2.4969, 2.7072, 2.9163, - 0.1589, 0.4151, 0.5749, 0.6651, 0.8061, 1.0470, 1.2616, 1.3690, - 1.4985, 1.7808, 1.9825, 2.1068, 2.2751, 2.5448, 2.7133, 2.8689, - 0.0916, 0.1846, 0.3788, 0.6329, 0.8774, 1.0687, 1.2653, 1.4561, - 1.6573, 1.8449, 2.0402, 2.2254, 2.3968, 2.5861, 2.7792, 2.9508, - 0.2282, 0.4159, 0.5834, 0.6899, 0.8108, 1.0321, 1.2795, 1.5262, - 1.6936, 1.8469, 2.0922, 2.2607, 2.3795, 2.5301, 2.7386, 2.9530, - 0.1651, 0.3004, 0.4555, 0.6179, 0.7891, 0.9584, 1.1372, 1.3707, - 1.5951, 1.7880, 1.9434, 2.1465, 2.3311, 2.5081, 2.6977, 2.8970, - 0.1279, 0.3828, 0.6330, 0.8323, 0.9652, 1.1175, 1.2319, 1.3511, - 1.5115, 1.6392, 1.7835, 1.9558, 2.2008, 2.4635, 2.6910, 2.9058, - 0.1193, 0.2185, 0.3521, 0.5311, 0.7378, 0.9239, 1.1105, 1.3217, - 1.5362, 1.7504, 1.9536, 2.1627, 2.3560, 2.5506, 2.7548, 2.9453, - 0.1806, 0.3432, 0.4981, 0.6948, 0.8928, 1.0527, 1.2467, 1.4140, - 1.6326, 1.7950, 1.9935, 2.1969, 2.3512, 2.5682, 2.7445, 2.9277, - 0.1846, 0.3112, 0.4568, 0.5891, 0.7317, 0.8493, 1.0204, 1.2022, - 1.3688, 1.6020, 1.8428, 2.0710, 2.2725, 2.4879, 2.7057, 2.9160, - 0.0880, 0.2514, 0.5332, 0.7272, 0.8906, 1.1354, 1.3199, 1.4941, - 1.6010, 1.7151, 1.8712, 2.0643, 2.2755, 2.5375, 2.7054, 2.8891, - 0.1382, 0.2833, 0.4658, 0.6897, 0.9071, 1.0716, 1.2469, 1.4143, - 1.5910, 1.7947, 1.9805, 2.1581, 2.3338, 2.5215, 2.7292, 2.9211, - 0.1061, 0.3494, 0.6327, 0.8570, 0.9748, 1.0560, 1.1529, 1.3250, - 1.6032, 1.8340, 1.9711, 2.1157, 2.3011, 2.5464, 2.8078, 2.9803, - 0.1603, 0.2839, 0.4307, 0.5980, 0.7980, 1.0399, 1.1971, 1.3524, - 1.5715, 1.7838, 1.9468, 2.1498, 2.3627, 2.5514, 2.7327, 2.9148, - 0.1691, 0.3117, 0.4796, 0.6895, 0.8732, 1.0164, 1.1916, 1.3707, - 1.5384, 1.7202, 1.8857, 2.0672, 2.2487, 2.4593, 2.6789, 2.8940, - 0.0965, 0.1702, 0.3191, 0.5721, 0.8100, 1.0241, 1.2272, 1.4196, - 1.6093, 1.8057, 1.9884, 2.2037, 2.3925, 2.5805, 2.7578, 2.9366, - 0.1950, 0.3519, 0.5272, 0.6973, 0.8732, 1.0656, 1.2112, 1.3959, - 1.6116, 1.7821, 1.9445, 2.1592, 2.3348, 2.5142, 2.7440, 2.9297, - 0.1388, 0.2557, 0.4120, 0.5727, 0.7354, 0.9196, 1.0985, 1.2805, - 1.4643, 1.6535, 1.8340, 2.0546, 2.2758, 2.4778, 2.6921, 2.9122, - 0.1823, 0.3336, 0.4957, 0.6771, 0.8563, 1.0137, 1.2299, 1.3849, - 1.5718, 1.7667, 1.9193, 2.1326, 2.3135, 2.5268, 2.7133, 2.8998, - 0.0790, 0.1901, 0.4083, 0.6456, 0.8463, 1.0285, 1.2297, 1.4181, - 1.6159, 1.8056, 1.9971, 2.1912, 2.3816, 2.5746, 2.7692, 2.9497, - 0.0049, 0.0116, 0.0045, 0.0039, -0.0010, -0.0122, -0.0205, -0.0034, - -0.0140, -0.0041, 0.0191, -0.0322, 0.0002, -0.0124, -0.0269, 0.0059, - 0.0586, 0.0339, -0.0389, -0.0319, -0.0079, -0.0205, -0.0363, -0.0211, - 0.0241, 0.0595, 0.0469, 0.0283, 0.0176, -0.0183, -0.0173, -0.0004, - 0.0024, 0.0145, 0.0534, 0.0197, -0.0065, -0.0067, 0.0133, 0.0358, - -0.0104, -0.0386, -0.0109, -0.0078, 0.0275, 0.0565, 0.0251, -0.0027, - -0.0053, 0.0171, 0.0088, 0.0495, 0.0141, 0.0039, -0.0445, -0.0426, - -0.0184, -0.0280, -0.0223, 0.0039, -0.0171, -0.0606, -0.0786, -0.0430, - 0.0544, 0.0595, 0.0320, -0.0012, 0.0108, 0.0185, 0.0066, 0.0408, - 0.0552, -0.0073, -0.0247, -0.0480, -0.0288, 0.0186, 0.0212, -0.0013, - 0.0403, 0.0598, 0.0690, 0.0516, -0.0298, -0.0177, 0.0278, 0.0168, - -0.0106, 0.0251, 0.0386, 0.0331, -0.0052, 0.0133, 0.0291, -0.0158, - -0.0329, -0.0367, 0.0287, 0.0462, -0.0176, 0.0049, 0.0242, -0.0034, - 0.0135, 0.0086, -0.0149, 0.0241, 0.0504, 0.0246, -0.0273, -0.0369, - -0.0108, -0.0449, -0.0625, -0.0414, -0.0292, -0.0571, -0.0440, -0.0088, - 0.0098, 0.0009, -0.0004, 0.0007, -0.0314, -0.0208, -0.0138, -0.0277, - -0.0044, 0.0522, 0.0315, -0.0270, -0.0277, -0.0256, -0.0103, -0.0201, - -0.0287, -0.0279, -0.0182, 0.0472, 0.0613, 0.0450, 0.0413, 0.0333, - 0.0444, 0.0223, 0.0061, 0.0316, 0.0321, 0.0501, 0.0460, 0.0250, - 0.0227, 0.0235, 0.0099, 0.0185, -0.0347, -0.0684, -0.0189, 0.0242, - -0.0190, -0.0273, -0.0012, -0.0253, 0.0293, -0.0231, -0.0219, -0.0010, - 0.0153, 0.0128, -0.0166, -0.0435, -0.0417, -0.0121, -0.0351, -0.0390, - 0.0077, -0.0278, -0.0355, 0.0092, -0.0063, 0.0005, 0.0216, 0.0461, - 0.0538, 0.0451, 0.0298, -0.0130, 0.0058, 0.0206, 0.0471, 0.0499, - 0.0280, 0.0086, -0.0007, -0.0317, 0.0259, 0.0176, 0.0043, 0.0212, - 0.0138, 0.0106, 0.0220, -0.0025, 0.0050, 0.0122, -0.0051, -0.0086, - -0.0472, -0.0005, 0.0193, 0.0032, 0.0246, 0.0222, 0.0090, -0.0320, - -0.0713, -0.0526, -0.0151, -0.0440, -0.0648, -0.0466, -0.0092, 0.0115, - -0.0129, 0.0053, -0.0344, -0.0385, 0.0392, 0.0599, 0.0414, 0.0165, - -0.0098, -0.0320, -0.0261, -0.0055, -0.0139, -0.0110, 0.0084, 0.0172, - -0.0492, -0.0537, -0.0320, -0.0036, 0.0265, 0.0385, 0.0064, -0.0280, - -0.0230, 0.0134, 0.0241, 0.0106, 0.0387, 0.0105, 0.0068, 0.0260, - 0.4940, 0.4911, 0.4849, 0.4820, 0.4837, 0.4839, 0.4824, 0.4799, - 0.4812, 0.4782, 0.4788, 0.4711, 0.4706, 0.4671, 0.4601, 0.4578, - 0.2954, 0.2121, 0.1859, 0.1958, 0.1474, 0.1086, 0.1351, 0.1362, - 0.1486, 0.1342, 0.1215, 0.1423, 0.1634, 0.1588, 0.1539, 0.1857, -}; - -static const float lsp16[] = { +const float ff_metasound_lsp16[] = { 0.1813, 0.3911, 0.6301, 0.8012, 1.0057, 1.2041, 1.4271, 1.6943, 1.9402, 2.1733, 2.3521, 2.4989, 2.5839, 2.6846, 2.7634, 2.8950, 0.1311, 0.3183, 0.4659, 0.5601, 0.6658, 0.7828, 1.0065, 1.2717, @@ -12747,7 +12517,7 @@ static const float lsp16[] = { -0.0429, -0.0615, -0.0893, -0.0618, -0.0384, -0.0134, -0.0232, -0.0238, }; -static const float lsp22[] = { +const float ff_metasound_lsp22[] = { 0.0664, 0.1875, 0.4300, 0.6730, 0.8793, 1.0640, 1.2563, 1.4433, 1.6394, 1.8176, 2.0029, 2.1921, 2.3796, 2.5671, 2.7595, 2.9536, 0.2128, 0.4052, 0.5311, 0.6404, 0.7875, 0.8775, 1.0974, 1.3261, @@ -12914,174 +12684,7 @@ static const float lsp22[] = { 0.4239, 0.4331, 0.4522, 0.4423, 0.4475, 0.4387, 0.4525, 0.4446, }; -static const float lsp22s[] = { - 0.0664, 0.1875, 0.4300, 0.6730, 0.8793, 1.0640, 1.2563, 1.4433, - 1.6394, 1.8176, 2.0029, 2.1921, 2.3796, 2.5671, 2.7595, 2.9536, - 0.2128, 0.4052, 0.5311, 0.6404, 0.7875, 0.8775, 1.0974, 1.3261, - 1.5563, 1.6790, 1.8339, 2.1195, 2.3226, 2.4609, 2.6440, 2.8947, - 0.2024, 0.3362, 0.4834, 0.6784, 0.9088, 1.0850, 1.2188, 1.4054, - 1.6102, 1.7767, 1.9679, 2.1436, 2.3445, 2.5467, 2.7429, 2.9320, - 0.1181, 0.2279, 0.4413, 0.6114, 0.7710, 0.9427, 1.1142, 1.2707, - 1.4892, 1.7416, 1.9526, 2.1466, 2.3629, 2.5445, 2.7293, 2.9205, - 0.1155, 0.2720, 0.4886, 0.6812, 0.8594, 1.0422, 1.2315, 1.4116, - 1.6137, 1.8020, 1.9758, 2.1743, 2.3602, 2.5568, 2.7472, 2.9374, - 0.1110, 0.3312, 0.4735, 0.5612, 0.7129, 0.8146, 1.0233, 1.3155, - 1.5765, 1.7746, 1.9574, 2.1416, 2.3220, 2.5384, 2.7334, 2.9318, - 0.1656, 0.3350, 0.4215, 0.5609, 0.6759, 0.8503, 1.1405, 1.4094, - 1.6057, 1.6860, 1.7639, 2.0031, 2.2680, 2.5076, 2.7263, 2.9368, - 0.1466, 0.3638, 0.4587, 0.5674, 0.7381, 0.8669, 0.9619, 1.1658, - 1.4667, 1.7440, 1.9335, 2.1018, 2.3022, 2.5281, 2.7359, 2.9261, - 0.1061, 0.2566, 0.4739, 0.6751, 0.8711, 1.0704, 1.2720, 1.4655, - 1.6605, 1.8494, 2.0290, 2.2197, 2.4008, 2.5912, 2.7772, 2.9513, - 0.1116, 0.2364, 0.3971, 0.6316, 0.8583, 1.0335, 1.1686, 1.3302, - 1.5612, 1.7877, 1.9829, 2.2052, 2.3596, 2.5460, 2.7341, 2.9290, - 0.2661, 0.4186, 0.5126, 0.6477, 0.8818, 1.1045, 1.2852, 1.4128, - 1.5851, 1.7593, 1.9399, 2.1757, 2.3684, 2.5136, 2.6927, 2.9064, - 0.1495, 0.2749, 0.4391, 0.6304, 0.8239, 1.0181, 1.1995, 1.3759, - 1.5669, 1.7722, 1.9671, 2.1635, 2.3586, 2.5528, 2.7445, 2.9311, - 0.0912, 0.1759, 0.3066, 0.5660, 0.8005, 0.9568, 1.1832, 1.4504, - 1.6259, 1.7948, 2.0113, 2.2002, 2.3654, 2.5583, 2.7929, 2.9735, - 0.1353, 0.2747, 0.4078, 0.5977, 0.7658, 0.9124, 1.1081, 1.3630, - 1.5875, 1.7847, 1.9323, 2.1181, 2.3321, 2.5046, 2.7183, 2.9225, - 0.1938, 0.4063, 0.4982, 0.6002, 0.7702, 0.9071, 1.1631, 1.3885, - 1.6043, 1.8118, 1.9306, 2.0893, 2.2724, 2.4609, 2.6283, 2.8802, - 0.1857, 0.3351, 0.4381, 0.6101, 0.7561, 0.8555, 1.0384, 1.3171, - 1.5667, 1.6904, 1.7552, 1.9689, 2.2597, 2.5260, 2.7272, 2.9337, - 0.1037, 0.2159, 0.4188, 0.6174, 0.8035, 1.0285, 1.2256, 1.4230, - 1.6400, 1.8322, 2.0144, 2.1988, 2.3810, 2.5682, 2.7613, 2.9438, - 0.1625, 0.2776, 0.4225, 0.6001, 0.7879, 0.9087, 1.0801, 1.2759, - 1.4899, 1.7448, 1.9911, 2.1770, 2.3723, 2.5777, 2.7971, 2.9444, - 0.2111, 0.3640, 0.5839, 0.7290, 0.8051, 1.0023, 1.2315, 1.4143, - 1.5878, 1.7755, 1.9804, 2.1498, 2.3312, 2.5350, 2.7613, 2.9472, - 0.1423, 0.2646, 0.4136, 0.6350, 0.8070, 0.9514, 1.1168, 1.3213, - 1.5776, 1.7721, 1.9404, 2.1545, 2.3385, 2.5137, 2.7396, 2.9553, - 0.1132, 0.2386, 0.4103, 0.5931, 0.7808, 0.9881, 1.1840, 1.3860, - 1.6021, 1.7990, 1.9922, 2.1885, 2.3852, 2.5717, 2.7640, 2.9510, - 0.1267, 0.2602, 0.3913, 0.5944, 0.7598, 0.9198, 1.0781, 1.2715, - 1.5299, 1.7573, 1.9308, 2.1346, 2.3267, 2.5419, 2.7466, 2.9320, - 0.2023, 0.3417, 0.4392, 0.6141, 0.7439, 0.8593, 1.1096, 1.3543, - 1.5185, 1.6553, 1.7862, 2.0341, 2.2718, 2.4834, 2.7103, 2.9466, - 0.1113, 0.2470, 0.3677, 0.5686, 0.7700, 0.9356, 1.0806, 1.2452, - 1.4830, 1.7344, 1.9268, 2.1404, 2.3371, 2.5169, 2.7329, 2.9012, - 0.1664, 0.3554, 0.5573, 0.7471, 0.9245, 1.0998, 1.2787, 1.4655, - 1.6654, 1.8346, 2.0179, 2.2159, 2.4096, 2.5946, 2.7790, 2.9530, - 0.1313, 0.2625, 0.4731, 0.6444, 0.8110, 0.9878, 1.1493, 1.3212, - 1.5719, 1.8138, 1.9861, 2.1943, 2.3714, 2.5578, 2.7346, 2.9296, - 0.1186, 0.3035, 0.5049, 0.6860, 0.8670, 0.9975, 1.1364, 1.3471, - 1.5695, 1.7412, 1.9346, 2.1506, 2.3413, 2.5531, 2.7794, 2.9627, - 0.1108, 0.2697, 0.4787, 0.6344, 0.7909, 0.9586, 1.1440, 1.3511, - 1.5686, 1.7601, 1.9246, 2.1241, 2.3293, 2.5390, 2.7315, 2.9333, - 0.0985, 0.2302, 0.3544, 0.5759, 0.7620, 0.9651, 1.1497, 1.3080, - 1.5500, 1.7845, 1.9518, 2.1734, 2.3565, 2.5665, 2.7605, 2.9102, - 0.1208, 0.2727, 0.4381, 0.5736, 0.7382, 0.8390, 1.0102, 1.2648, - 1.5100, 1.7440, 1.9619, 2.1430, 2.3307, 2.5159, 2.7264, 2.9211, - 0.1582, 0.2777, 0.4475, 0.6551, 0.8591, 1.0084, 1.1414, 1.3291, - 1.5902, 1.7826, 1.9543, 2.1659, 2.3233, 2.5044, 2.6935, 2.9199, - 0.1360, 0.2873, 0.4585, 0.6295, 0.7592, 0.9089, 1.0492, 1.2733, - 1.5391, 1.7768, 1.9372, 2.1329, 2.3168, 2.5015, 2.6857, 2.8837, - 0.0886, 0.1829, 0.3696, 0.6126, 0.8334, 1.0135, 1.2303, 1.4674, - 1.6743, 1.8564, 2.0530, 2.2370, 2.3960, 2.5787, 2.7756, 2.9377, - 0.2005, 0.3537, 0.4700, 0.6249, 0.7385, 0.9097, 1.1759, 1.3811, - 1.5314, 1.6705, 1.8546, 2.1229, 2.3292, 2.5251, 2.7951, 2.9646, - 0.1999, 0.3112, 0.4722, 0.7146, 0.8908, 1.0028, 1.1831, 1.3903, - 1.6125, 1.7514, 1.9083, 2.1248, 2.3271, 2.5339, 2.6945, 2.8918, - 0.1243, 0.2606, 0.4382, 0.5850, 0.7705, 0.9727, 1.1214, 1.3059, - 1.5218, 1.7406, 1.9137, 2.1353, 2.3354, 2.5299, 2.7287, 2.9068, - 0.1039, 0.2426, 0.4265, 0.6284, 0.8152, 0.9941, 1.2004, 1.4038, - 1.5912, 1.7763, 1.9650, 2.1598, 2.3474, 2.5488, 2.7419, 2.9322, - 0.1364, 0.2420, 0.3886, 0.5864, 0.7663, 0.8844, 1.0860, 1.3242, - 1.5518, 1.7893, 2.0004, 2.1562, 2.3619, 2.5516, 2.7687, 2.9181, - 0.1483, 0.2851, 0.4479, 0.6312, 0.7924, 0.9821, 1.1705, 1.3386, - 1.5375, 1.7226, 1.9053, 2.0991, 2.2898, 2.4953, 2.7000, 2.9146, - 0.2332, 0.4561, 0.5407, 0.6212, 0.7524, 0.8215, 0.9522, 1.1685, - 1.5216, 1.7132, 1.8291, 2.0647, 2.2811, 2.4857, 2.7071, 2.9281, - 0.1348, 0.3126, 0.5179, 0.7192, 0.9227, 1.1363, 1.3223, 1.4756, - 1.6509, 1.8191, 1.9991, 2.1976, 2.3877, 2.5768, 2.7590, 2.9386, - 0.1093, 0.2211, 0.4763, 0.6703, 0.8282, 0.9536, 1.1202, 1.3796, - 1.6043, 1.8031, 1.9832, 2.1604, 2.3578, 2.5856, 2.7650, 2.9291, - 0.1865, 0.3027, 0.4580, 0.6719, 0.8400, 1.0082, 1.1901, 1.3782, - 1.5448, 1.6885, 1.9477, 2.1381, 2.2797, 2.5113, 2.7465, 2.9414, - 0.1575, 0.3124, 0.4649, 0.6262, 0.8095, 0.9858, 1.1676, 1.3602, - 1.5646, 1.7582, 1.9550, 2.1671, 2.3628, 2.5734, 2.7670, 2.9519, - 0.1174, 0.2777, 0.4663, 0.6333, 0.8169, 1.0096, 1.1885, 1.3847, - 1.5803, 1.7571, 1.9380, 2.1398, 2.3414, 2.5407, 2.7360, 2.9375, - 0.1073, 0.2264, 0.4083, 0.5973, 0.7474, 0.9514, 1.1349, 1.3337, - 1.5433, 1.7348, 1.9380, 2.1436, 2.3441, 2.5438, 2.7457, 2.9383, - 0.1472, 0.2880, 0.4793, 0.6268, 0.8015, 1.0063, 1.1715, 1.3644, - 1.5525, 1.7410, 1.9258, 2.1227, 2.3214, 2.5149, 2.7148, 2.9196, - 0.1414, 0.2565, 0.4349, 0.6111, 0.7695, 0.9496, 1.1212, 1.3265, - 1.5218, 1.7209, 1.9015, 2.0887, 2.3158, 2.5077, 2.7233, 2.9421, - 0.1252, 0.2667, 0.4454, 0.6431, 0.8371, 1.0124, 1.2110, 1.4160, - 1.6240, 1.8242, 2.0047, 2.1974, 2.3902, 2.5778, 2.7637, 2.9481, - 0.1321, 0.2565, 0.3846, 0.5847, 0.7578, 0.9259, 1.0637, 1.2239, - 1.4690, 1.7346, 1.9750, 2.1882, 2.3712, 2.5509, 2.7280, 2.8885, - 0.1437, 0.2930, 0.4428, 0.6156, 0.8045, 0.9638, 1.1450, 1.3138, - 1.5144, 1.7355, 1.9469, 2.1534, 2.3414, 2.5452, 2.7353, 2.9334, - 0.1692, 0.2770, 0.3831, 0.6100, 0.7825, 0.9302, 1.0690, 1.2481, - 1.4615, 1.6799, 1.9165, 2.1739, 2.3435, 2.5349, 2.7520, 2.9163, - 0.1235, 0.2489, 0.4354, 0.6343, 0.8236, 1.0066, 1.1908, 1.3474, - 1.5656, 1.8275, 2.0620, 2.2548, 2.4135, 2.5913, 2.7639, 2.9334, - 0.1090, 0.1961, 0.3854, 0.5701, 0.7024, 0.8843, 1.1393, 1.3785, - 1.5940, 1.7797, 1.9442, 2.1740, 2.3853, 2.5773, 2.7727, 2.9406, - 0.1560, 0.3477, 0.5011, 0.6287, 0.7612, 0.9896, 1.1510, 1.3420, - 1.5435, 1.6816, 1.8731, 2.0651, 2.2613, 2.4999, 2.7027, 2.8971, - 0.1459, 0.2416, 0.3833, 0.5450, 0.7916, 0.9223, 1.0662, 1.1953, - 1.4029, 1.6616, 1.9320, 2.1459, 2.3386, 2.5081, 2.6799, 2.9195, - 0.1546, 0.3854, 0.6184, 0.8460, 1.0599, 1.2428, 1.3906, 1.5550, - 1.7388, 1.8945, 2.0757, 2.2386, 2.4014, 2.5705, 2.7574, 2.9400, - 0.1080, 0.2307, 0.4112, 0.6067, 0.7725, 0.9467, 1.1285, 1.3205, - 1.5348, 1.7609, 1.9937, 2.1878, 2.3583, 2.5515, 2.7199, 2.9049, - 0.1482, 0.3178, 0.4983, 0.6342, 0.7783, 0.9880, 1.2019, 1.3404, - 1.5223, 1.7296, 1.9211, 2.0943, 2.2928, 2.5008, 2.7136, 2.9224, - 0.1145, 0.2910, 0.4891, 0.6492, 0.8126, 0.9530, 1.1180, 1.3155, - 1.5054, 1.6893, 1.8899, 2.1188, 2.3389, 2.5512, 2.7313, 2.9224, - 0.0939, 0.1689, 0.3250, 0.5792, 0.7698, 0.9245, 1.1574, 1.3865, - 1.5959, 1.7977, 1.9821, 2.1528, 2.3326, 2.5540, 2.7553, 2.9179, - 0.1243, 0.2474, 0.3923, 0.6199, 0.7908, 0.9379, 1.1497, 1.3734, - 1.5582, 1.7420, 1.9539, 2.1385, 2.3240, 2.5277, 2.7311, 2.9178, - 0.1961, 0.3748, 0.5176, 0.6387, 0.8169, 1.0477, 1.2124, 1.3869, - 1.5604, 1.7225, 1.8770, 2.0837, 2.2960, 2.5103, 2.6945, 2.8862, - 0.1295, 0.2403, 0.4149, 0.6189, 0.7913, 0.9130, 1.0832, 1.2787, - 1.4860, 1.7112, 1.9502, 2.1348, 2.2776, 2.4982, 2.7431, 2.9522, - 0.0160, 0.0362, 0.0097, 0.0057, -0.0014, -0.0073, -0.0046, -0.0064, - -0.0121, 0.0019, 0.0149, -0.0440, -0.0479, -0.0382, -0.0480, -0.0182, - 0.0170, 0.0114, -0.0298, -0.0175, -0.0033, -0.0354, -0.0510, -0.0025, - 0.0307, 0.0351, 0.0338, 0.0420, 0.0138, -0.0175, -0.0102, 0.0053, - 0.0084, -0.0003, 0.0412, -0.0027, 0.0145, -0.0039, 0.0083, 0.0400, - 0.0001, -0.0262, 0.0055, -0.0082, 0.0348, 0.0433, 0.0137, -0.0024, - -0.0055, 0.0262, 0.0521, 0.0349, 0.0185, 0.0076, -0.0319, -0.0561, - -0.0460, -0.0253, -0.0097, 0.0163, 0.0184, -0.0037, -0.0480, -0.0371, - 0.0628, 0.0665, 0.0296, -0.0057, 0.0253, 0.0227, 0.0350, 0.0692, - 0.0545, 0.0218, 0.0094, -0.0449, -0.0372, 0.0005, 0.0258, 0.0118, - 0.0285, 0.0760, 0.0822, 0.0527, -0.0299, -0.0049, 0.0170, 0.0195, - 0.0136, 0.0286, 0.0289, 0.0139, 0.0054, 0.0152, 0.0244, 0.0028, - -0.0056, -0.0260, 0.0307, 0.0572, -0.0087, 0.0088, 0.0062, 0.0000, - 0.0125, 0.0000, -0.0292, 0.0820, 0.0872, 0.0646, 0.0346, 0.0076, - -0.0022, -0.0253, -0.0567, -0.0188, -0.0336, -0.0673, -0.0549, -0.0166, - -0.0259, -0.0140, 0.0040, -0.0029, -0.0430, -0.0531, -0.0253, -0.0019, - -0.0071, 0.0393, 0.0072, -0.0327, -0.0236, -0.0235, -0.0177, -0.0186, - -0.0280, -0.0201, -0.0077, 0.0383, 0.0418, 0.0321, 0.0294, 0.0169, - 0.0468, 0.0301, 0.0133, 0.0363, 0.0516, 0.0937, 0.1240, 0.1404, - 0.1325, 0.1178, 0.0999, 0.0251, -0.0037, -0.0495, -0.0703, -0.0219, - -0.0261, -0.0304, -0.0204, -0.0372, 0.0355, 0.0131, -0.0093, -0.0099, - -0.0069, -0.0034, -0.0065, -0.0208, -0.0231, -0.0117, -0.0211, -0.0243, - 0.0046, -0.0107, -0.0070, 0.0123, 0.0230, 0.0152, 0.0164, 0.0412, - 0.0619, 0.0858, 0.0862, -0.0056, 0.0125, 0.0182, 0.0347, 0.0388, - 0.0456, 0.0407, -0.0249, -0.0460, 0.0206, 0.0299, 0.0253, 0.0207, - 0.0177, 0.0238, 0.0253, 0.0030, 0.0042, 0.0020, -0.0081, -0.0136, - -0.0290, -0.0042, 0.0122, 0.0051, 0.0107, 0.0228, 0.0211, -0.0068, - -0.0436, -0.0299, -0.0078, -0.0779, -0.1157, -0.0679, 0.0172, 0.0150, - -0.0051, 0.0081, -0.0512, -0.0616, 0.0576, 0.0799, 0.0803, 0.0336, - 0.0001, -0.0298, -0.0747, -0.0115, -0.0101, -0.0170, -0.0050, 0.0174, - -0.0290, -0.0601, -0.0150, 0.0121, 0.0165, 0.0230, 0.0028, -0.0317, - -0.0165, 0.0356, 0.0451, 0.0120, 0.0321, 0.0084, -0.0058, 0.0122, - 0.1935, 0.1802, 0.2195, 0.2410, 0.2201, 0.1915, 0.1840, 0.1935, - 0.2213, 0.2079, 0.1858, 0.1974, 0.2239, 0.2173, 0.1840, 0.2120, - 0.4912, 0.4777, 0.4607, 0.4395, 0.4426, 0.4388, 0.4416, 0.4345, - 0.4239, 0.4331, 0.4522, 0.4423, 0.4475, 0.4387, 0.4525, 0.4446, -}; - -static const float lsp44s[] = { +const float ff_metasound_lsp44[] = { 0.0927, 0.2291, 0.4059, 0.5779, 0.7288, 0.8821, 1.0377, 1.1915, 1.3433, 1.4931, 1.6475, 1.7989, 1.9381, 2.0858, 2.2321, 2.3765, 2.5187, 2.6530, 2.7895, 2.9354, 0.0944, 0.1974, 0.3046, 0.4714, @@ -13289,6 +12892,7 @@ static const float lsp44s[] = { 0.1897, 0.1772, 0.1651, 0.1247, 0.1041, 0.1231, 0.1809, 0.2234, }; +#if CONFIG_METASOUND_DECODER static const int16_t shape8[] = { 2765, 1262, 6624, 867, 688, 1884, 3245, 1248, -2160, 593, 182, -1004, -1067, 687, 1021, -920, @@ -14971,17 +14575,6 @@ static const uint16_t bark_tab_l22_1024[] = { 29, 36, 45, 60, 80, 113, 173, 302, }; -static const uint16_t bark_tab_s22_128[] = { - 1, 2, 1, 2, 3, 4, 6, 10, - 23, 76, -}; - -static const uint16_t bark_tab_m22_512[] = { - 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_l22s_1024[] = { 6, 7, 6, 6, 7, 7, 7, 7, 7, 8, 9, 8, 10, 10, 11, 12, @@ -15006,11 +14599,13 @@ static const uint16_t bark_tab_l44_2048[] = { 64, 79, 98, 123, 161, 220, 320, 512, }; +#define bark_tab_m22_512 bark_tab_m44_512 /* Both tables are identical */ 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, }; +#define bark_tab_s22_128 bark_tab_s44_128 /* Both tables are identical */ static const uint16_t bark_tab_s44_128[] = { 1, 2, 1, 2, 3, 4, 6, 10, 23, 76 }; @@ -15021,7 +14616,7 @@ const TwinVQModeTab ff_metasound_mode0806 = { { 2, bark_tab_m8_256, 20, fcb8m, 2, 5, cb0806sm0, cb0806sm1, 22 }, { 1, bark_tab_l8_512, 30, fcb8l, 3, 6, cb0806sl0, cb0806sl1, 24 } }, - 512, 12, lsp8, 1, 5, 3, 3, shape8, 8, 28, 20, 6, 200 + 512, 12, ff_metasound_lsp8, 1, 5, 3, 3, shape8, 8, 28, 20, 6, 200 }; const TwinVQModeTab ff_metasound_mode0806s = { @@ -15030,7 +14625,7 @@ const TwinVQModeTab ff_metasound_mode0806s = { { 2, bark_tab_m8s_256, 20, fcb8sm, 2, 5, cb0806sm0, cb0806sm1, 22 }, { 1, bark_tab_l8s_512, 30, fcb8sl, 3, 6, cb0806sl0, cb0806sl1, 24 } }, - 512, 12, lsp8s, 1, 5, 3, 3, shape8s, 8, 28, 20, 6, 200 + 512, 12, ff_metasound_lsp8, 1, 5, 3, 3, shape8s, 8, 28, 20, 6, 200 }; const TwinVQModeTab ff_metasound_mode0808 = { @@ -15039,7 +14634,7 @@ const TwinVQModeTab ff_metasound_mode0808 = { { 2, bark_tab_m8_256, 20, fcb8m, 2, 5, cb0808m0, cb0808m1, 16 }, { 1, bark_tab_l8_512, 30, fcb8l, 3, 6, cb0808l0, cb0808l1, 17 } }, - 512, 12, lsp8, 1, 5, 3, 3, shape8, 8, 28, 20, 6, 200 + 512, 12, ff_metasound_lsp8, 1, 5, 3, 3, shape8, 8, 28, 20, 6, 200 }; const TwinVQModeTab ff_metasound_mode0808s = { @@ -15048,7 +14643,7 @@ const TwinVQModeTab ff_metasound_mode0808s = { { 2, bark_tab_m8s_256, 20, fcb8sm, 2, 5, cb0808sm0, cb0808sm1, 16 }, { 1, bark_tab_l8s_512, 30, fcb8sl, 3, 6, cb0808sl0, cb0808sl1, 17 } }, - 512, 12, lsp8s, 1, 5, 3, 3, shape8s, 8, 28, 20, 6, 200 + 512, 12, ff_metasound_lsp8, 1, 5, 3, 3, shape8s, 8, 28, 20, 6, 200 }; const TwinVQModeTab ff_metasound_mode1110 = { @@ -15057,7 +14652,7 @@ const TwinVQModeTab ff_metasound_mode1110 = { { 2, bark_tab_m11_256, 16, fcb11m, 2, 5, cb1110m0, cb1110m1, 18 }, { 1, bark_tab_l11_512, 24, fcb11l, 3, 6, cb1110l0, cb1110l1, 19 } }, - 512, 16, lsp11, 1, 6, 4, 3, shape11, 9, 28, 20, 7, 200 + 512, 16, ff_metasound_lsp11, 1, 6, 4, 3, shape11, 9, 28, 20, 7, 200 }; const TwinVQModeTab ff_metasound_mode1110s = { @@ -15066,7 +14661,7 @@ const TwinVQModeTab ff_metasound_mode1110s = { { 2, bark_tab_m11s_256, 20, fcb11sm, 2, 5, cb1110sm0, cb1110sm1, 18 }, { 1, bark_tab_l11s_512, 30, fcb11sl, 3, 6, cb1110sl0, cb1110sl1, 20 } }, - 512, 16, lsp11s, 1, 6, 4, 3, shape11s, 9, 36, 30, 7, 200 + 512, 16, ff_metasound_lsp11, 1, 6, 4, 3, shape11s, 9, 36, 30, 7, 200 }; const TwinVQModeTab ff_metasound_mode1616 = { @@ -15075,7 +14670,7 @@ const TwinVQModeTab ff_metasound_mode1616 = { { 2, bark_tab_m16_512, 24, fcb16m, 2, 5, cb1616m0, cb1616m1, 15 }, { 1, bark_tab_l16_1024, 30, fcb16l, 3, 6, cb1616l0, cb1616l1, 16 } }, - 1024, 16, lsp16, 1, 6, 4, 3, shape16, 9, 28, 30, 7, 200 + 1024, 16, ff_metasound_lsp16, 1, 6, 4, 3, shape16, 9, 28, 30, 7, 200 }; const TwinVQModeTab ff_metasound_mode1616s = { @@ -15084,7 +14679,7 @@ const TwinVQModeTab ff_metasound_mode1616s = { { 2, bark_tab_m16s_512, 20, fcb16sm, 2, 5, cb1616sm0, cb1616sm1, 15 }, { 1, bark_tab_l16s_1024, 30, fcb16sl, 3, 6, cb1616sl0, cb1616sl1, 16 } }, - 1024, 16, lsp16, 1, 6, 4, 3, shape16s, 9, 56, 60, 7, 200 + 1024, 16, ff_metasound_lsp16, 1, 6, 4, 3, shape16s, 9, 56, 60, 7, 200 }; const TwinVQModeTab ff_metasound_mode2224 = { @@ -15093,7 +14688,7 @@ const TwinVQModeTab ff_metasound_mode2224 = { { 2, bark_tab_m22_512, 20, fcb22m, 2, 6, cb2224m0, cb2224m1, 14 }, { 1, bark_tab_l22_1024, 32, fcb22l, 4, 6, cb2224l0, cb2224l1, 15 } }, - 1024, 16, lsp22, 1, 6, 4, 3, shape22, 9, 56, 36, 7, 200 + 1024, 16, ff_metasound_lsp22, 1, 6, 4, 3, shape22, 9, 56, 36, 7, 200 }; const TwinVQModeTab ff_metasound_mode2224s = { @@ -15102,7 +14697,7 @@ const TwinVQModeTab ff_metasound_mode2224s = { { 2, bark_tab_m22s_512, 20, fcb22sm, 2, 6, cb2224sm0, cb2224sm1, 14 }, { 1, bark_tab_l22s_1024, 32, fcb22sl, 4, 6, cb2224sl0, cb2224sl1, 15 } }, - 1024, 16, lsp22s, 1, 6, 4, 3, shape22s, 9, 56, 36, 7, 200 + 1024, 16, ff_metasound_lsp22, 1, 6, 4, 3, shape22s, 9, 56, 36, 7, 200 }; const TwinVQModeTab ff_metasound_mode4432 = { @@ -15111,16 +14706,7 @@ const TwinVQModeTab ff_metasound_mode4432 = { { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4432m0, cb4432m1, 21 }, { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4432l0, cb4432l1, 22 } }, - 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200, -}; - -const TwinVQModeTab ff_metasound_mode4432s = { - { - { 16, bark_tab_s44_128, 10, fcb44ss, 1, 6, cb4432s0, cb4432s1, 23 }, - { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4432m0, cb4432m1, 21 }, - { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4432l0, cb4432l1, 22 } - }, - 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200, + 2048, 20, ff_metasound_lsp44, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200, }; const TwinVQModeTab ff_metasound_mode4440 = { @@ -15129,16 +14715,7 @@ const TwinVQModeTab ff_metasound_mode4440 = { { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4440sm0, cb4440sm1, 17 }, { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4440sl0, cb4440sl1, 17 } }, - 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200 -}; - -const TwinVQModeTab ff_metasound_mode4440s = { - { - { 16, bark_tab_s44_128, 10, fcb44ss, 1, 6, cb4440ss0, cb4440ss1, 18 }, - { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4440sm0, cb4440sm1, 17 }, - { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4440sl0, cb4440sl1, 17 } - }, - 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200 + 2048, 20, ff_metasound_lsp44, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200 }; const TwinVQModeTab ff_metasound_mode4448 = { @@ -15147,14 +14724,6 @@ const TwinVQModeTab ff_metasound_mode4448 = { { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4448sm0, cb4448sm1, 14 }, { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4448sl0, cb4448sl1, 14 } }, - 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200 -}; - -const TwinVQModeTab ff_metasound_mode4448s = { - { - { 16, bark_tab_s44_128, 10, fcb44ss, 1, 6, cb4448ss0, cb4448ss1, 15 }, - { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4448sm0, cb4448sm1, 14 }, - { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4448sl0, cb4448sl1, 14 } - }, - 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200 + 2048, 20, ff_metasound_lsp44, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200 }; +#endif /* CONFIG_METASOUND_DECODER */ diff --git a/libavcodec/metasound_data.h b/libavcodec/metasound_data.h index 5c334113c..24c77c386 100644 --- a/libavcodec/metasound_data.h +++ b/libavcodec/metasound_data.h @@ -27,6 +27,12 @@ #include "twinvq.h" +extern const float ff_metasound_lsp8[]; +extern const float ff_metasound_lsp11[]; +extern const float ff_metasound_lsp16[]; +extern const float ff_metasound_lsp22[]; +extern const float ff_metasound_lsp44[]; + extern const TwinVQModeTab ff_metasound_mode0806; extern const TwinVQModeTab ff_metasound_mode0806s; extern const TwinVQModeTab ff_metasound_mode0808; @@ -40,10 +46,7 @@ extern const TwinVQModeTab ff_metasound_mode2224s; extern const TwinVQModeTab ff_metasound_mode2232; extern const TwinVQModeTab ff_metasound_mode2232s; extern const TwinVQModeTab ff_metasound_mode4432; -extern const TwinVQModeTab ff_metasound_mode4432s; extern const TwinVQModeTab ff_metasound_mode4440; -extern const TwinVQModeTab ff_metasound_mode4440s; extern const TwinVQModeTab ff_metasound_mode4448; -extern const TwinVQModeTab ff_metasound_mode4448s; #endif /* AVCODEC_METASOUND_DATA_H */ diff --git a/libavcodec/mfenc.c b/libavcodec/mfenc.c index ee3c164e6..d70e49351 100644 --- a/libavcodec/mfenc.c +++ b/libavcodec/mfenc.c @@ -22,6 +22,7 @@ #define _WIN32_WINNT 0x0602 #endif +#include "encode.h" #include "mf_utils.h" #include "libavutil/imgutils.h" #include "libavutil/opt.h" @@ -30,6 +31,7 @@ typedef struct MFContext { AVClass *av_class; + AVFrame *frame; int is_video, is_audio; GUID main_subtype; IMFTransform *mft; @@ -241,7 +243,7 @@ static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPac if (FAILED(hr)) return AVERROR_EXTERNAL; - if ((ret = av_new_packet(avpkt, len)) < 0) + if ((ret = ff_get_encode_buffer(avctx, avpkt, len, 0)) < 0) return ret; IMFSample_ConvertToContiguousBuffer(sample, &buffer); @@ -398,26 +400,6 @@ static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample) return 0; } -static int mf_send_frame(AVCodecContext *avctx, const AVFrame *frame) -{ - MFContext *c = avctx->priv_data; - int ret; - IMFSample *sample = NULL; - if (frame) { - sample = mf_avframe_to_sample(avctx, frame); - if (!sample) - return AVERROR(ENOMEM); - if (c->is_video && c->codec_api) { - if (frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent) - ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1)); - } - } - ret = mf_send_sample(avctx, sample); - if (sample) - IMFSample_Release(sample); - return ret; -} - static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample) { MFContext *c = avctx->priv_data; @@ -500,9 +482,36 @@ static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample) static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) { - IMFSample *sample; + MFContext *c = avctx->priv_data; + IMFSample *sample = NULL; int ret; + if (!c->frame->buf[0]) { + ret = ff_encode_get_frame(avctx, c->frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + if (c->frame->buf[0]) { + sample = mf_avframe_to_sample(avctx, c->frame); + if (!sample) { + av_frame_unref(c->frame); + return AVERROR(ENOMEM); + } + if (c->is_video && c->codec_api) { + if (c->frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent) + ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1)); + } + } + + ret = mf_send_sample(avctx, sample); + if (sample) + IMFSample_Release(sample); + if (ret != AVERROR(EAGAIN)) + av_frame_unref(c->frame); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + ret = mf_receive_sample(avctx, &sample); if (ret < 0) return ret; @@ -1034,6 +1043,10 @@ static int mf_init(AVCodecContext *avctx) const CLSID *subtype = ff_codec_to_mf_subtype(avctx->codec_id); int use_hw = 0; + c->frame = av_frame_alloc(); + if (!c->frame) + return AVERROR(ENOMEM); + c->is_audio = avctx->codec_type == AVMEDIA_TYPE_AUDIO; c->is_video = !c->is_audio; c->reorder_delay = AV_NOPTS_VALUE; @@ -1122,6 +1135,8 @@ static int mf_close(AVCodecContext *avctx) ff_free_mf(&c->mft); + av_frame_free(&c->frame); + av_freep(&avctx->extradata); avctx->extradata_size = 0; @@ -1146,10 +1161,10 @@ static int mf_close(AVCodecContext *avctx) .priv_data_size = sizeof(MFContext), \ .init = mf_init, \ .close = mf_close, \ - .send_frame = mf_send_frame, \ .receive_packet = mf_receive_packet, \ EXTRA \ - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, \ + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \ + AV_CODEC_CAP_DR1, \ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | \ FF_CODEC_CAP_INIT_CLEANUP, \ }; diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 2563a49d5..407faa02d 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -23,6 +23,9 @@ #include #include +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" + #include "avcodec.h" #include "blockdsp.h" #include "internal.h" @@ -34,6 +37,7 @@ #include "thread.h" #define MIMIC_HEADER_SIZE 20 +#define MIMIC_VLC_BITS 11 typedef struct MimicContext { AVCodecContext *avctx; @@ -57,50 +61,33 @@ typedef struct MimicContext { BswapDSPContext bbdsp; HpelDSPContext hdsp; IDCTDSPContext idsp; - VLC vlc; /* Kept in the context so multithreading can have a constant to read from */ int next_cur_index; int next_prev_index; } MimicContext; -static const uint32_t huffcodes[] = { - 0x0000000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000b, - 0x0000001b, 0x00000038, 0x00000078, 0x00000079, 0x0000007a, 0x000000f9, - 0x000000fa, 0x000003fb, 0x000007f8, 0x000007f9, 0x000007fa, 0x000007fb, - 0x00000ff8, 0x00000ff9, 0x00000001, 0x00000039, 0x0000007b, 0x000000fb, - 0x000001f8, 0x000001f9, 0x00000ffa, 0x00000ffb, 0x00001ff8, 0x00001ff9, - 0x00001ffa, 0x00001ffb, 0x00003ff8, 0x00003ff9, 0x00003ffa, 0x00000000, - 0x00000004, 0x0000003a, 0x000001fa, 0x00003ffb, 0x00007ff8, 0x00007ff9, - 0x00007ffa, 0x00007ffb, 0x0000fff8, 0x0000fff9, 0x0000fffa, 0x0000fffb, - 0x0001fff8, 0x0001fff9, 0x0001fffa, 0x00000000, 0x0000000c, 0x000000f8, - 0x000001fb, 0x0001fffb, 0x0003fff8, 0x0003fff9, 0x0003fffa, 0x0003fffb, - 0x0007fff8, 0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9, - 0x000ffffa, 0x00000000, 0x0000001a, 0x000003f8, 0x000ffffb, 0x001ffff8, - 0x001ffff9, 0x001ffffa, 0x001ffffb, 0x003ffff8, 0x003ffff9, 0x003ffffa, - 0x003ffffb, 0x007ffff8, 0x007ffff9, 0x007ffffa, 0x007ffffb, 0x00000000, - 0x0000003b, 0x000003f9, 0x00fffff8, 0x00fffff9, 0x00fffffa, 0x00fffffb, - 0x01fffff8, 0x01fffff9, 0x01fffffa, 0x01fffffb, 0x03fffff8, 0x03fffff9, - 0x03fffffa, 0x03fffffb, 0x07fffff8, 0x00000000, 0x000003fa, 0x07fffff9, - 0x07fffffa, 0x07fffffb, 0x0ffffff8, 0x0ffffff9, 0x0ffffffa, 0x0ffffffb, - 0x1ffffff8, 0x1ffffff9, 0x1ffffffa, 0x1ffffffb, 0x3ffffff8, 0x3ffffff9, - 0x3ffffffa, +static VLC block_vlc; + +static const uint8_t huffsyms[] = { + 0x10, 0x20, 0x30, 0x00, 0x11, 0x40, 0x50, 0x12, 0x13, 0x21, 0x31, 0x60, + 0x14, 0x15, 0x16, 0x22, 0x41, 0x17, 0x18, 0x23, 0x24, 0x25, 0x32, 0x42, + 0x51, 0x61, 0x70, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x52, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, }; static const uint8_t huffbits[] = { - 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 4, 5, 6, 7, 7, 7, 8, - 8, 10, 11, 11, 11, 11, 12, 12, 2, 6, 7, 8, - 9, 9, 12, 12, 13, 13, 13, 13, 14, 14, 14, 0, - 3, 6, 9, 14, 15, 15, 15, 15, 16, 16, 16, 16, - 17, 17, 17, 0, 4, 8, 9, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 0, 5, 10, 20, 21, - 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 0, - 6, 10, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, - 26, 26, 27, 0, 10, 27, 27, 27, 28, 28, 28, 28, - 29, 29, 29, 29, 30, 30, 30, + 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, + 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, + 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, + 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, + 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, }; static const uint8_t col_zag[64] = { @@ -128,24 +115,24 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx) av_frame_free(&ctx->frames[i].f); } - ff_free_vlc(&ctx->vlc); - return 0; } +static av_cold void mimic_init_static(void) +{ + INIT_VLC_STATIC_FROM_LENGTHS(&block_vlc, MIMIC_VLC_BITS, FF_ARRAY_ELEMS(huffbits), + huffbits, 1, huffsyms, 1, 1, 0, 0, 4368); +} + static av_cold int mimic_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; MimicContext *ctx = avctx->priv_data; - int ret, i; + int i; ctx->prev_index = 0; ctx->cur_index = 15; - if ((ret = init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits), - huffbits, 1, 1, huffcodes, 4, 4, 0)) < 0) { - av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n"); - return ret; - } ff_blockdsp_init(&ctx->bdsp, avctx); ff_bswapdsp_init(&ctx->bbdsp); ff_hpeldsp_init(&ctx->hdsp, avctx->flags); @@ -154,12 +141,12 @@ static av_cold int mimic_decode_init(AVCodecContext *avctx) for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) { ctx->frames[i].f = av_frame_alloc(); - if (!ctx->frames[i].f) { - mimic_decode_end(avctx); + if (!ctx->frames[i].f) return AVERROR(ENOMEM); - } } + ff_thread_once(&init_static_once, mimic_init_static); + return 0; } @@ -239,7 +226,7 @@ static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale) int value; int coeff; - vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3); + vlc = get_vlc2(&ctx->gb, block_vlc.table, MIMIC_VLC_BITS, 3); if (!vlc) /* end-of-block code */ return 0; if (vlc == -1) @@ -459,5 +446,6 @@ AVCodec ff_mimic_decoder = { .decode = mimic_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context), - .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS | + FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/mips/Makefile b/libavcodec/mips/Makefile index b4993f6e7..2be4d9b8a 100644 --- a/libavcodec/mips/Makefile +++ b/libavcodec/mips/Makefile @@ -71,6 +71,8 @@ MSA-OBJS-$(CONFIG_IDCTDSP) += mips/idctdsp_msa.o \ MSA-OBJS-$(CONFIG_MPEGVIDEO) += mips/mpegvideo_msa.o MSA-OBJS-$(CONFIG_MPEGVIDEOENC) += mips/mpegvideoencdsp_msa.o MSA-OBJS-$(CONFIG_ME_CMP) += mips/me_cmp_msa.o +MSA-OBJS-$(CONFIG_VC1_DECODER) += mips/vc1dsp_msa.o + MMI-OBJS += mips/constants.o MMI-OBJS-$(CONFIG_H264DSP) += mips/h264dsp_mmi.o MMI-OBJS-$(CONFIG_H264CHROMA) += mips/h264chroma_mmi.o @@ -89,4 +91,3 @@ MMI-OBJS-$(CONFIG_WMV2DSP) += mips/wmv2dsp_mmi.o MMI-OBJS-$(CONFIG_HEVC_DECODER) += mips/hevcdsp_mmi.o MMI-OBJS-$(CONFIG_VP3DSP) += mips/vp3dsp_idct_mmi.o MMI-OBJS-$(CONFIG_VP9_DECODER) += mips/vp9_mc_mmi.o -MSA-OBJS-$(CONFIG_VC1_DECODER) += mips/vc1dsp_msa.o diff --git a/libavcodec/mips/aacdec_mips.c b/libavcodec/mips/aacdec_mips.c index 8e3065293..7f2478957 100644 --- a/libavcodec/mips/aacdec_mips.c +++ b/libavcodec/mips/aacdec_mips.c @@ -340,7 +340,7 @@ static void update_ltp_mips(AACContext *ac, SingleChannelElement *sce) float *saved_ltp = sce->coeffs; const float *lwindow = ics->use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024; const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; - float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; + uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { float *p_saved_ltp = saved_ltp + 576; diff --git a/libavcodec/mips/aacpsdsp_mips.c b/libavcodec/mips/aacpsdsp_mips.c index ef47e31a9..f63541330 100644 --- a/libavcodec/mips/aacpsdsp_mips.c +++ b/libavcodec/mips/aacpsdsp_mips.c @@ -293,16 +293,17 @@ static void ps_decorrelate_mips(float (*out)[2], float (*delay)[2], float phi_fract0 = phi_fract[0]; float phi_fract1 = phi_fract[1]; float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9; + float f1, f2, f3; float *p_delay_end = (p_delay + (len << 1)); /* merged 2 loops */ + f1 = 0.65143905753106; + f2 = 0.56471812200776; + f3 = 0.48954165955695; __asm__ volatile( ".set push \n\t" ".set noreorder \n\t" - "li.s %[ag0], 0.65143905753106 \n\t" - "li.s %[ag1], 0.56471812200776 \n\t" - "li.s %[ag2], 0.48954165955695 \n\t" "mul.s %[ag0], %[ag0], %[g_decay_slope] \n\t" "mul.s %[ag1], %[ag1], %[g_decay_slope] \n\t" "mul.s %[ag2], %[ag2], %[g_decay_slope] \n\t" @@ -378,10 +379,10 @@ static void ps_decorrelate_mips(float (*out)[2], float (*delay)[2], [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5), [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8), [temp9]"=&f"(temp9), [p_delay]"+r"(p_delay), [p_ap_delay]"+r"(p_ap_delay), - [p_Q_fract]"+r"(p_Q_fract), [p_t_gain]"+r"(p_t_gain), [p_out]"+r"(p_out), - [ag0]"=&f"(ag0), [ag1]"=&f"(ag1), [ag2]"=&f"(ag2) + [p_Q_fract]"+r"(p_Q_fract), [p_t_gain]"+r"(p_t_gain), [p_out]"+r"(p_out) : [phi_fract0]"f"(phi_fract0), [phi_fract1]"f"(phi_fract1), - [p_delay_end]"r"(p_delay_end), [g_decay_slope]"f"(g_decay_slope) + [p_delay_end]"r"(p_delay_end), [g_decay_slope]"f"(g_decay_slope), + [ag0]"f"(f1), [ag1]"f"(f2), [ag2]"f"(f3) : "memory" ); } diff --git a/libavcodec/mips/aacpsy_mips.h b/libavcodec/mips/aacpsy_mips.h index a1fe5ccea..7d27d32f1 100644 --- a/libavcodec/mips/aacpsy_mips.h +++ b/libavcodec/mips/aacpsy_mips.h @@ -135,11 +135,11 @@ static void psy_hp_filter_mips(const float *firbuf, float *hpfsmpl, const float float coeff3 = psy_fir_coeffs[7]; float coeff4 = psy_fir_coeffs[9]; + float f1 = 32768.0; __asm__ volatile ( ".set push \n\t" ".set noreorder \n\t" - "li.s $f12, 32768 \n\t" "1: \n\t" "lwc1 $f0, 40(%[fb]) \n\t" "lwc1 $f1, 4(%[fb]) \n\t" @@ -203,14 +203,14 @@ static void psy_hp_filter_mips(const float *firbuf, float *hpfsmpl, const float "madd.s %[sum2], %[sum2], $f9, %[coeff4] \n\t" "madd.s %[sum4], %[sum4], $f6, %[coeff4] \n\t" "madd.s %[sum3], %[sum3], $f3, %[coeff4] \n\t" - "mul.s %[sum1], %[sum1], $f12 \n\t" - "mul.s %[sum2], %[sum2], $f12 \n\t" + "mul.s %[sum1], %[sum1], %[f1] \n\t" + "mul.s %[sum2], %[sum2], %[f1] \n\t" "madd.s %[sum4], %[sum4], $f11, %[coeff4] \n\t" "madd.s %[sum3], %[sum3], $f8, %[coeff4] \n\t" "swc1 %[sum1], 0(%[hp]) \n\t" "swc1 %[sum2], 4(%[hp]) \n\t" - "mul.s %[sum4], %[sum4], $f12 \n\t" - "mul.s %[sum3], %[sum3], $f12 \n\t" + "mul.s %[sum4], %[sum4], %[f1] \n\t" + "mul.s %[sum3], %[sum3], %[f1] \n\t" "swc1 %[sum4], 12(%[hp]) \n\t" "swc1 %[sum3], 8(%[hp]) \n\t" "bne %[fb], %[fb_end], 1b \n\t" @@ -223,9 +223,9 @@ static void psy_hp_filter_mips(const float *firbuf, float *hpfsmpl, const float [fb]"+r"(fb), [hp]"+r"(hp) : [coeff0]"f"(coeff0), [coeff1]"f"(coeff1), [coeff2]"f"(coeff2), [coeff3]"f"(coeff3), - [coeff4]"f"(coeff4), [fb_end]"r"(fb_end) + [coeff4]"f"(coeff4), [fb_end]"r"(fb_end), [f1]"f"(f1) : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", - "$f7", "$f8", "$f9", "$f10", "$f11", "$f12", + "$f7", "$f8", "$f9", "$f10", "$f11", "memory" ); } diff --git a/libavcodec/mips/aacsbr_mips.c b/libavcodec/mips/aacsbr_mips.c index 2e0cd723d..33fd9b229 100644 --- a/libavcodec/mips/aacsbr_mips.c +++ b/libavcodec/mips/aacsbr_mips.c @@ -53,6 +53,7 @@ #include "libavcodec/aac.h" #include "libavcodec/aacsbr.h" +#include "libavutil/mem_internal.h" #include "libavutil/mips/asmdefs.h" #define ENVELOPE_ADJUSTMENT_OFFSET 2 @@ -333,7 +334,7 @@ static void sbr_hf_assemble_mips(float Y1[38][64][2], int indexnoise = ch_data->f_indexnoise; int indexsine = ch_data->f_indexsine; float *g_temp1, *q_temp1, *pok, *pok1; - float temp1, temp2, temp3, temp4; + uint32_t temp1, temp2, temp3, temp4; int size = m_max; if (sbr->reset) { diff --git a/libavcodec/mips/blockdsp_init_mips.c b/libavcodec/mips/blockdsp_init_mips.c index 55ac1c3e9..c6964fa74 100644 --- a/libavcodec/mips/blockdsp_init_mips.c +++ b/libavcodec/mips/blockdsp_init_mips.c @@ -19,36 +19,26 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "blockdsp_mips.h" -#if HAVE_MSA -static av_cold void blockdsp_init_msa(BlockDSPContext *c) -{ - c->clear_block = ff_clear_block_msa; - c->clear_blocks = ff_clear_blocks_msa; - - c->fill_block_tab[0] = ff_fill_block16_msa; - c->fill_block_tab[1] = ff_fill_block8_msa; -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static av_cold void blockdsp_init_mmi(BlockDSPContext *c) -{ - c->clear_block = ff_clear_block_mmi; - c->clear_blocks = ff_clear_blocks_mmi; - - c->fill_block_tab[0] = ff_fill_block16_mmi; - c->fill_block_tab[1] = ff_fill_block8_mmi; -} -#endif /* HAVE_MMI */ - void ff_blockdsp_init_mips(BlockDSPContext *c) { -#if HAVE_MMI - blockdsp_init_mmi(c); -#endif /* HAVE_MMI */ -#if HAVE_MSA - blockdsp_init_msa(c); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + c->clear_block = ff_clear_block_mmi; + c->clear_blocks = ff_clear_blocks_mmi; + + c->fill_block_tab[0] = ff_fill_block16_mmi; + c->fill_block_tab[1] = ff_fill_block8_mmi; + } + + if (have_msa(cpu_flags)) { + c->clear_block = ff_clear_block_msa; + c->clear_blocks = ff_clear_blocks_msa; + + c->fill_block_tab[0] = ff_fill_block16_msa; + c->fill_block_tab[1] = ff_fill_block8_msa; + } } diff --git a/libavcodec/mips/cabac.h b/libavcodec/mips/cabac.h index 03b5010ed..3d09e9352 100644 --- a/libavcodec/mips/cabac.h +++ b/libavcodec/mips/cabac.h @@ -25,7 +25,7 @@ #define AVCODEC_MIPS_CABAC_H #include "libavcodec/cabac.h" -#include "libavutil/mips/mmiutils.h" +#include "libavutil/mips/asmdefs.h" #include "config.h" #define get_cabac_inline get_cabac_inline_mips @@ -109,7 +109,7 @@ static av_always_inline int get_cabac_inline_mips(CABACContext *c, [lps_off]"i"(H264_LPS_RANGE_OFFSET), [mlps_off]"i"(H264_MLPS_STATE_OFFSET + 128), [norm_off]"i"(H264_NORM_SHIFT_OFFSET), - [cabac_mask]"i"(CABAC_MASK) + [cabac_mask]"r"(CABAC_MASK) : "memory" ); diff --git a/libavcodec/mips/compute_antialias_fixed.h b/libavcodec/mips/compute_antialias_fixed.h index a967f67de..1f395d230 100644 --- a/libavcodec/mips/compute_antialias_fixed.h +++ b/libavcodec/mips/compute_antialias_fixed.h @@ -59,7 +59,8 @@ static void compute_antialias_mips_fixed(MPADecodeContext *s, GranuleDef *g) { - int32_t *ptr, *csa; + const int32_t *csa; + int32_t *ptr; int n, i; int MAX_lo = 0xffffffff; diff --git a/libavcodec/mips/compute_antialias_float.h b/libavcodec/mips/compute_antialias_float.h index e2b4f29f4..633eb9589 100644 --- a/libavcodec/mips/compute_antialias_float.h +++ b/libavcodec/mips/compute_antialias_float.h @@ -63,7 +63,7 @@ static void compute_antialias_mips_float(MPADecodeContext *s, GranuleDef *g) { float *ptr, *ptr_end; - float *csa = &csa_table[0][0]; + const float *csa = &csa_table[0][0]; /* temporary variables */ float in1, in2, in3, in4, in5, in6, in7, in8; float out1, out2, out3, out4; diff --git a/libavcodec/mips/constants.c b/libavcodec/mips/constants.c index a7c4a5ccf..8c990b611 100644 --- a/libavcodec/mips/constants.c +++ b/libavcodec/mips/constants.c @@ -20,7 +20,7 @@ */ #include "config.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "constants.h" DECLARE_ALIGNED(8, const uint64_t, ff_pw_1) = {0x0001000100010001ULL}; diff --git a/libavcodec/mips/fft_mips.c b/libavcodec/mips/fft_mips.c index 03dcbad4d..a6656d965 100644 --- a/libavcodec/mips/fft_mips.c +++ b/libavcodec/mips/fft_mips.c @@ -71,6 +71,7 @@ static void ff_fft_calc_mips(FFTContext *s, FFTComplex *z) float temp, temp1, temp3, temp4; FFTComplex * tmpz_n2, * tmpz_n34, * tmpz_n4; FFTComplex * tmpz_n2_i, * tmpz_n34_i, * tmpz_n4_i, * tmpz_i; + float f1 = 0.7071067812; num_transforms = (21845 >> (17 - s->nbits)) | 1; @@ -148,7 +149,6 @@ static void ff_fft_calc_mips(FFTContext *s, FFTComplex *z) "swc1 %[pom2], 4(%[tmpz]) \n\t" // tmpz[0].im = tmpz[0].im + tmp6; "lwc1 %[pom1], 16(%[tmpz]) \n\t" "lwc1 %[pom3], 20(%[tmpz]) \n\t" - "li.s %[pom], 0.7071067812 \n\t" // float pom = 0.7071067812f; "add.s %[temp1],%[tmp1], %[tmp2] \n\t" "sub.s %[temp], %[pom1], %[tmp8] \n\t" "add.s %[pom2], %[pom3], %[tmp7] \n\t" @@ -159,10 +159,10 @@ static void ff_fft_calc_mips(FFTContext *s, FFTComplex *z) "add.s %[pom1], %[pom1], %[tmp8] \n\t" "sub.s %[pom3], %[pom3], %[tmp7] \n\t" "add.s %[tmp3], %[tmp3], %[tmp4] \n\t" - "mul.s %[tmp5], %[pom], %[temp1] \n\t" // tmp5 = pom * (tmp1 + tmp2); - "mul.s %[tmp7], %[pom], %[temp3] \n\t" // tmp7 = pom * (tmp3 - tmp4); - "mul.s %[tmp6], %[pom], %[temp4] \n\t" // tmp6 = pom * (tmp2 - tmp1); - "mul.s %[tmp8], %[pom], %[tmp3] \n\t" // tmp8 = pom * (tmp3 + tmp4); + "mul.s %[tmp5], %[f1], %[temp1] \n\t" // tmp5 = pom * (tmp1 + tmp2); + "mul.s %[tmp7], %[f1], %[temp3] \n\t" // tmp7 = pom * (tmp3 - tmp4); + "mul.s %[tmp6], %[f1], %[temp4] \n\t" // tmp6 = pom * (tmp2 - tmp1); + "mul.s %[tmp8], %[f1], %[tmp3] \n\t" // tmp8 = pom * (tmp3 + tmp4); "swc1 %[pom1], 16(%[tmpz]) \n\t" // tmpz[2].re = tmpz[2].re + tmp8; "swc1 %[pom3], 20(%[tmpz]) \n\t" // tmpz[2].im = tmpz[2].im - tmp7; "add.s %[tmp1], %[tmp5], %[tmp7] \n\t" // tmp1 = tmp5 + tmp7; @@ -193,7 +193,7 @@ static void ff_fft_calc_mips(FFTContext *s, FFTComplex *z) [tmp3]"=&f"(tmp3), [tmp2]"=&f"(tmp2), [tmp4]"=&f"(tmp4), [tmp5]"=&f"(tmp5), [tmp7]"=&f"(tmp7), [tmp6]"=&f"(tmp6), [tmp8]"=&f"(tmp8), [pom3]"=&f"(pom3),[temp]"=&f"(temp), [temp1]"=&f"(temp1), [temp3]"=&f"(temp3), [temp4]"=&f"(temp4) - : [tmpz]"r"(tmpz) + : [tmpz]"r"(tmpz), [f1]"f"(f1) : "memory" ); } @@ -500,9 +500,7 @@ static void ff_imdct_calc_mips(FFTContext *s, FFTSample *output, const FFTSample av_cold void ff_fft_init_mips(FFTContext *s) { - int n=0; - - ff_fft_lut_init(ff_fft_offsets_lut, 0, 1 << 17, &n); + ff_fft_lut_init(); ff_init_ff_cos_tabs(17); #if HAVE_INLINE_ASM diff --git a/libavcodec/mips/h263dsp_init_mips.c b/libavcodec/mips/h263dsp_init_mips.c index 09bd93707..a73eb12d8 100644 --- a/libavcodec/mips/h263dsp_init_mips.c +++ b/libavcodec/mips/h263dsp_init_mips.c @@ -18,19 +18,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "h263dsp_mips.h" -#if HAVE_MSA -static av_cold void h263dsp_init_msa(H263DSPContext *c) -{ - c->h263_h_loop_filter = ff_h263_h_loop_filter_msa; - c->h263_v_loop_filter = ff_h263_v_loop_filter_msa; -} -#endif // #if HAVE_MSA - av_cold void ff_h263dsp_init_mips(H263DSPContext *c) { -#if HAVE_MSA - h263dsp_init_msa(c); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_msa(cpu_flags)){ + c->h263_h_loop_filter = ff_h263_h_loop_filter_msa; + c->h263_v_loop_filter = ff_h263_v_loop_filter_msa; + } } diff --git a/libavcodec/mips/h264chroma_init_mips.c b/libavcodec/mips/h264chroma_init_mips.c index ae817e47a..6bb19d3dd 100644 --- a/libavcodec/mips/h264chroma_init_mips.c +++ b/libavcodec/mips/h264chroma_init_mips.c @@ -19,45 +19,34 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "h264chroma_mips.h" -#if HAVE_MSA -static av_cold void h264chroma_init_msa(H264ChromaContext *c, int bit_depth) -{ - const int high_bit_depth = bit_depth > 8; - - if (!high_bit_depth) { - c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_msa; - c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_msa; - c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_msa; - - c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_msa; - c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_msa; - c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_msa; - } -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static av_cold void h264chroma_init_mmi(H264ChromaContext *c, int bit_depth) -{ - int high_bit_depth = bit_depth > 8; - - if (!high_bit_depth) { - c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_mmi; - c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_mmi; - c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_mmi; - c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_mmi; - } -} -#endif /* HAVE_MMI */ av_cold void ff_h264chroma_init_mips(H264ChromaContext *c, int bit_depth) { -#if HAVE_MMI - h264chroma_init_mmi(c, bit_depth); -#endif /* HAVE_MMI */ -#if HAVE_MSA - h264chroma_init_msa(c, bit_depth); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + int high_bit_depth = bit_depth > 8; + + /* MMI apears to be faster than MSA here */ + if (have_msa(cpu_flags)) { + if (!high_bit_depth) { + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_msa; + c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_msa; + c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_msa; + + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_msa; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_msa; + c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_msa; + } + } + + if (have_mmi(cpu_flags)) { + if (!high_bit_depth) { + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_mmi; + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_mmi; + c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_mmi; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_mmi; + } + } } diff --git a/libavcodec/mips/h264dsp_init_mips.c b/libavcodec/mips/h264dsp_init_mips.c index dc08a2580..9cd05e0f2 100644 --- a/libavcodec/mips/h264dsp_init_mips.c +++ b/libavcodec/mips/h264dsp_init_mips.c @@ -19,129 +19,116 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "h264dsp_mips.h" -#if HAVE_MSA -static av_cold void h264dsp_init_msa(H264DSPContext *c, - const int bit_depth, - const int chroma_format_idc) -{ - if (8 == bit_depth) { - c->h264_v_loop_filter_luma = ff_h264_v_lpf_luma_inter_msa; - c->h264_h_loop_filter_luma = ff_h264_h_lpf_luma_inter_msa; - c->h264_h_loop_filter_luma_mbaff = - ff_h264_h_loop_filter_luma_mbaff_msa; - c->h264_v_loop_filter_luma_intra = ff_h264_v_lpf_luma_intra_msa; - c->h264_h_loop_filter_luma_intra = ff_h264_h_lpf_luma_intra_msa; - c->h264_h_loop_filter_luma_mbaff_intra = - ff_h264_h_loop_filter_luma_mbaff_intra_msa; - c->h264_v_loop_filter_chroma = ff_h264_v_lpf_chroma_inter_msa; - - if (chroma_format_idc <= 1) - c->h264_h_loop_filter_chroma = ff_h264_h_lpf_chroma_inter_msa; - else - c->h264_h_loop_filter_chroma = - ff_h264_h_loop_filter_chroma422_msa; - - if (chroma_format_idc > 1) - c->h264_h_loop_filter_chroma_mbaff = - ff_h264_h_loop_filter_chroma422_mbaff_msa; - - c->h264_v_loop_filter_chroma_intra = - ff_h264_v_lpf_chroma_intra_msa; - - if (chroma_format_idc <= 1) - c->h264_h_loop_filter_chroma_intra = - ff_h264_h_lpf_chroma_intra_msa; - - /* Weighted MC */ - c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels16_8_msa; - c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels8_8_msa; - c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels4_8_msa; - - c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels16_8_msa; - c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels8_8_msa; - c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels4_8_msa; - - c->h264_idct_add = ff_h264_idct_add_msa; - c->h264_idct8_add = ff_h264_idct8_addblk_msa; - c->h264_idct_dc_add = ff_h264_idct4x4_addblk_dc_msa; - c->h264_idct8_dc_add = ff_h264_idct8_dc_addblk_msa; - c->h264_idct_add16 = ff_h264_idct_add16_msa; - c->h264_idct8_add4 = ff_h264_idct8_add4_msa; - - if (chroma_format_idc <= 1) - c->h264_idct_add8 = ff_h264_idct_add8_msa; - else - c->h264_idct_add8 = ff_h264_idct_add8_422_msa; - - c->h264_idct_add16intra = ff_h264_idct_add16_intra_msa; - c->h264_luma_dc_dequant_idct = ff_h264_deq_idct_luma_dc_msa; - } // if (8 == bit_depth) -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static av_cold void h264dsp_init_mmi(H264DSPContext * c, const int bit_depth, - const int chroma_format_idc) -{ - if (bit_depth == 8) { - c->h264_add_pixels4_clear = ff_h264_add_pixels4_8_mmi; - c->h264_idct_add = ff_h264_idct_add_8_mmi; - c->h264_idct8_add = ff_h264_idct8_add_8_mmi; - c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmi; - c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmi; - c->h264_idct_add16 = ff_h264_idct_add16_8_mmi; - c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmi; - c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmi; - - if (chroma_format_idc <= 1) - c->h264_idct_add8 = ff_h264_idct_add8_8_mmi; - else - c->h264_idct_add8 = ff_h264_idct_add8_422_8_mmi; - - c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_8_mmi; - - if (chroma_format_idc <= 1) - c->h264_chroma_dc_dequant_idct = - ff_h264_chroma_dc_dequant_idct_8_mmi; - else - c->h264_chroma_dc_dequant_idct = - ff_h264_chroma422_dc_dequant_idct_8_mmi; - - c->weight_h264_pixels_tab[0] = ff_h264_weight_pixels16_8_mmi; - c->weight_h264_pixels_tab[1] = ff_h264_weight_pixels8_8_mmi; - c->weight_h264_pixels_tab[2] = ff_h264_weight_pixels4_8_mmi; - - c->biweight_h264_pixels_tab[0] = ff_h264_biweight_pixels16_8_mmi; - c->biweight_h264_pixels_tab[1] = ff_h264_biweight_pixels8_8_mmi; - c->biweight_h264_pixels_tab[2] = ff_h264_biweight_pixels4_8_mmi; - - c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_mmi; - c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_mmi; - - if (chroma_format_idc <= 1) { - c->h264_h_loop_filter_chroma = - ff_deblock_h_chroma_8_mmi; - c->h264_h_loop_filter_chroma_intra = - ff_deblock_h_chroma_intra_8_mmi; - } - - c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_mmi; - c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_mmi; - c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_mmi; - c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmi; - } -} -#endif /* HAVE_MMI */ - av_cold void ff_h264dsp_init_mips(H264DSPContext *c, const int bit_depth, const int chroma_format_idc) { -#if HAVE_MMI - h264dsp_init_mmi(c, bit_depth, chroma_format_idc); -#endif /* HAVE_MMI */ -#if HAVE_MSA - h264dsp_init_msa(c, bit_depth, chroma_format_idc); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + if (bit_depth == 8) { + c->h264_add_pixels4_clear = ff_h264_add_pixels4_8_mmi; + c->h264_idct_add = ff_h264_idct_add_8_mmi; + c->h264_idct8_add = ff_h264_idct8_add_8_mmi; + c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmi; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmi; + c->h264_idct_add16 = ff_h264_idct_add16_8_mmi; + c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmi; + c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmi; + + if (chroma_format_idc <= 1) + c->h264_idct_add8 = ff_h264_idct_add8_8_mmi; + else + c->h264_idct_add8 = ff_h264_idct_add8_422_8_mmi; + + c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_8_mmi; + + if (chroma_format_idc <= 1) + c->h264_chroma_dc_dequant_idct = + ff_h264_chroma_dc_dequant_idct_8_mmi; + else + c->h264_chroma_dc_dequant_idct = + ff_h264_chroma422_dc_dequant_idct_8_mmi; + + c->weight_h264_pixels_tab[0] = ff_h264_weight_pixels16_8_mmi; + c->weight_h264_pixels_tab[1] = ff_h264_weight_pixels8_8_mmi; + c->weight_h264_pixels_tab[2] = ff_h264_weight_pixels4_8_mmi; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_pixels16_8_mmi; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_pixels8_8_mmi; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_pixels4_8_mmi; + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_mmi; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_mmi; + + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = + ff_deblock_h_chroma_8_mmi; + c->h264_h_loop_filter_chroma_intra = + ff_deblock_h_chroma_intra_8_mmi; + } + + c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_mmi; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_mmi; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_mmi; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmi; + } + } + + if (have_msa(cpu_flags)) { + if (bit_depth == 8) { + c->h264_v_loop_filter_luma = ff_h264_v_lpf_luma_inter_msa; + c->h264_h_loop_filter_luma = ff_h264_h_lpf_luma_inter_msa; + c->h264_h_loop_filter_luma_mbaff = + ff_h264_h_loop_filter_luma_mbaff_msa; + c->h264_v_loop_filter_luma_intra = ff_h264_v_lpf_luma_intra_msa; + c->h264_h_loop_filter_luma_intra = ff_h264_h_lpf_luma_intra_msa; + c->h264_h_loop_filter_luma_mbaff_intra = + ff_h264_h_loop_filter_luma_mbaff_intra_msa; + c->h264_v_loop_filter_chroma = ff_h264_v_lpf_chroma_inter_msa; + + if (chroma_format_idc <= 1) + c->h264_h_loop_filter_chroma = ff_h264_h_lpf_chroma_inter_msa; + else + c->h264_h_loop_filter_chroma = + ff_h264_h_loop_filter_chroma422_msa; + + if (chroma_format_idc > 1) + c->h264_h_loop_filter_chroma_mbaff = + ff_h264_h_loop_filter_chroma422_mbaff_msa; + + c->h264_v_loop_filter_chroma_intra = + ff_h264_v_lpf_chroma_intra_msa; + + if (chroma_format_idc <= 1) + c->h264_h_loop_filter_chroma_intra = + ff_h264_h_lpf_chroma_intra_msa; + + /* Weighted MC */ + c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels16_8_msa; + c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels8_8_msa; + c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels4_8_msa; + + c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels16_8_msa; + c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels8_8_msa; + c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels4_8_msa; + + c->h264_idct_add = ff_h264_idct_add_msa; + c->h264_idct8_add = ff_h264_idct8_addblk_msa; + c->h264_idct_dc_add = ff_h264_idct4x4_addblk_dc_msa; + c->h264_idct8_dc_add = ff_h264_idct8_dc_addblk_msa; + c->h264_idct_add16 = ff_h264_idct_add16_msa; + c->h264_idct8_add4 = ff_h264_idct8_add4_msa; + + if (chroma_format_idc <= 1) + c->h264_idct_add8 = ff_h264_idct_add8_msa; + else + c->h264_idct_add8 = ff_h264_idct_add8_422_msa; + + c->h264_idct_add16intra = ff_h264_idct_add16_intra_msa; + c->h264_luma_dc_dequant_idct = ff_h264_deq_idct_luma_dc_msa; + } + } } diff --git a/libavcodec/mips/h264dsp_mips.h b/libavcodec/mips/h264dsp_mips.h index 21b7de06f..35e16c41b 100644 --- a/libavcodec/mips/h264dsp_mips.h +++ b/libavcodec/mips/h264dsp_mips.h @@ -25,21 +25,21 @@ #include "libavcodec/h264dec.h" #include "constants.h" -void ff_h264_h_lpf_luma_inter_msa(uint8_t *src, int stride, +void ff_h264_h_lpf_luma_inter_msa(uint8_t *src, ptrdiff_t stride, int alpha, int beta, int8_t *tc0); -void ff_h264_v_lpf_luma_inter_msa(uint8_t *src, int stride, +void ff_h264_v_lpf_luma_inter_msa(uint8_t *src, ptrdiff_t stride, int alpha, int beta, int8_t *tc0); -void ff_h264_h_lpf_chroma_inter_msa(uint8_t *src, int stride, +void ff_h264_h_lpf_chroma_inter_msa(uint8_t *src, ptrdiff_t stride, int alpha, int beta, int8_t *tc0); -void ff_h264_v_lpf_chroma_inter_msa(uint8_t *src, int stride, +void ff_h264_v_lpf_chroma_inter_msa(uint8_t *src, ptrdiff_t stride, int alpha, int beta, int8_t *tc0); -void ff_h264_h_loop_filter_chroma422_msa(uint8_t *src, int32_t stride, +void ff_h264_h_loop_filter_chroma422_msa(uint8_t *src, ptrdiff_t stride, int32_t alpha, int32_t beta, int8_t *tc0); -void ff_h264_h_loop_filter_chroma422_mbaff_msa(uint8_t *src, int32_t stride, +void ff_h264_h_loop_filter_chroma422_mbaff_msa(uint8_t *src, ptrdiff_t stride, int32_t alpha, int32_t beta, int8_t *tc0); -void ff_h264_h_loop_filter_luma_mbaff_msa(uint8_t *src, int32_t stride, +void ff_h264_h_loop_filter_luma_mbaff_msa(uint8_t *src, ptrdiff_t stride, int32_t alpha, int32_t beta, int8_t *tc0); @@ -67,15 +67,15 @@ void ff_h264_idct8_add4_msa(uint8_t *dst, const int *blk_offset, int16_t *blk, int dst_stride, const uint8_t nnzc[15 * 8]); -void ff_h264_h_lpf_luma_intra_msa(uint8_t *src, int stride, +void ff_h264_h_lpf_luma_intra_msa(uint8_t *src, ptrdiff_t stride, int alpha, int beta); -void ff_h264_v_lpf_luma_intra_msa(uint8_t *src, int stride, +void ff_h264_v_lpf_luma_intra_msa(uint8_t *src, ptrdiff_t stride, int alpha, int beta); -void ff_h264_h_lpf_chroma_intra_msa(uint8_t *src, int stride, +void ff_h264_h_lpf_chroma_intra_msa(uint8_t *src, ptrdiff_t stride, int alpha, int beta); -void ff_h264_v_lpf_chroma_intra_msa(uint8_t *src, int stride, +void ff_h264_v_lpf_chroma_intra_msa(uint8_t *src, ptrdiff_t stride, int alpha, int beta); -void ff_h264_h_loop_filter_luma_mbaff_intra_msa(uint8_t *src, int stride, +void ff_h264_h_loop_filter_luma_mbaff_intra_msa(uint8_t *src, ptrdiff_t stride, int alpha, int beta); void ff_biweight_h264_pixels16_8_msa(uint8_t *dst, uint8_t *src, @@ -357,23 +357,23 @@ void ff_h264_biweight_pixels4_8_mmi(uint8_t *dst, uint8_t *src, void ff_deblock_v_chroma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int8_t *tc0); -void ff_deblock_v_chroma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +void ff_deblock_v_chroma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta); -void ff_deblock_h_chroma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, +void ff_deblock_h_chroma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int8_t *tc0); -void ff_deblock_h_chroma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +void ff_deblock_h_chroma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta); -void ff_deblock_v_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, +void ff_deblock_v_luma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int8_t *tc0); -void ff_deblock_v_luma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +void ff_deblock_v_luma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta); -void ff_deblock_h_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, +void ff_deblock_h_luma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int8_t *tc0); -void ff_deblock_h_luma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +void ff_deblock_h_luma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta); -void ff_deblock_v8_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, +void ff_deblock_v8_luma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int8_t *tc0); -void ff_deblock_v8_luma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +void ff_deblock_v8_luma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta); void ff_put_h264_qpel16_mc00_mmi(uint8_t *dst, const uint8_t *src, diff --git a/libavcodec/mips/h264dsp_mmi.c b/libavcodec/mips/h264dsp_mmi.c index 0459711b8..d4fcef0d6 100644 --- a/libavcodec/mips/h264dsp_mmi.c +++ b/libavcodec/mips/h264dsp_mmi.c @@ -26,6 +26,7 @@ #include "libavcodec/bit_depth_template.c" #include "h264dsp_mips.h" #include "libavutil/mips/mmiutils.h" +#include "libavutil/mem_internal.h" void ff_h264_add_pixels4_8_mmi(uint8_t *dst, int16_t *src, int stride) { @@ -177,7 +178,7 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) __asm__ volatile ( "lhu %[tmp0], 0x00(%[block]) \n\t" - PTR_ADDI "$29, $29, -0x20 \n\t" + PTR_ADDI "$sp, $sp, -0x20 \n\t" PTR_ADDIU "%[tmp0], %[tmp0], 0x20 \n\t" MMI_LDC1(%[ftmp1], %[block], 0x10) "sh %[tmp0], 0x00(%[block]) \n\t" @@ -254,8 +255,8 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) "punpckhwd %[ftmp3], %[ftmp6], %[ftmp0] \n\t" "punpcklwd %[ftmp6], %[ftmp6], %[ftmp0] \n\t" MMI_LDC1(%[ftmp0], %[block], 0x00) - MMI_SDC1(%[ftmp7], $29, 0x00) - MMI_SDC1(%[ftmp1], $29, 0x10) + MMI_SDC1(%[ftmp7], $sp, 0x00) + MMI_SDC1(%[ftmp1], $sp, 0x10) "dmfc1 %[tmp1], %[ftmp6] \n\t" "dmfc1 %[tmp3], %[ftmp3] \n\t" "punpckhhw %[ftmp3], %[ftmp5], %[ftmp2] \n\t" @@ -266,8 +267,8 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) "punpcklwd %[ftmp5], %[ftmp5], %[ftmp4] \n\t" "punpckhwd %[ftmp4], %[ftmp3], %[ftmp2] \n\t" "punpcklwd %[ftmp3], %[ftmp3], %[ftmp2] \n\t" - MMI_SDC1(%[ftmp5], $29, 0x08) - MMI_SDC1(%[ftmp0], $29, 0x18) + MMI_SDC1(%[ftmp5], $sp, 0x08) + MMI_SDC1(%[ftmp0], $sp, 0x18) "dmfc1 %[tmp2], %[ftmp3] \n\t" "dmfc1 %[tmp4], %[ftmp4] \n\t" MMI_LDC1(%[ftmp1], %[block], 0x18) @@ -359,7 +360,7 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) PTR_ADDIU "%[addr0], %[dst], 0x04 \n\t" "mov.d %[ftmp7], %[ftmp10] \n\t" "dmtc1 %[tmp3], %[ftmp6] \n\t" - MMI_LDC1(%[ftmp1], $29, 0x10) + MMI_LDC1(%[ftmp1], $sp, 0x10) "dmtc1 %[tmp1], %[ftmp3] \n\t" "mov.d %[ftmp4], %[ftmp1] \n\t" "psrah %[ftmp1], %[ftmp1], %[ftmp8] \n\t" @@ -392,7 +393,7 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) "psrah %[ftmp0], %[ftmp3], %[ftmp8] \n\t" "paddh %[ftmp2], %[ftmp2], %[ftmp3] \n\t" "psubh %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - MMI_LDC1(%[ftmp3], $29, 0x00) + MMI_LDC1(%[ftmp3], $sp, 0x00) "dmtc1 %[tmp5], %[ftmp7] \n\t" "paddh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" "paddh %[ftmp3], %[ftmp3], %[ftmp3] \n\t" @@ -414,9 +415,9 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) "paddh %[ftmp1], %[ftmp1], %[ftmp7] \n\t" "psubh %[ftmp3], %[ftmp3], %[ftmp6] \n\t" "paddh %[ftmp7], %[ftmp7], %[ftmp7] \n\t" - MMI_SDC1(%[ftmp3], $29, 0x00) + MMI_SDC1(%[ftmp3], $sp, 0x00) "psubh %[ftmp7], %[ftmp7], %[ftmp1] \n\t" - MMI_SDC1(%[ftmp0], $29, 0x10) + MMI_SDC1(%[ftmp0], $sp, 0x10) "dmfc1 %[tmp1], %[ftmp2] \n\t" "xor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" MMI_SDC1(%[ftmp2], %[block], 0x00) @@ -463,8 +464,8 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) "packushb %[ftmp0], %[ftmp0], %[ftmp2] \n\t" MMI_SWC1(%[ftmp3], %[dst], 0x00) MMI_SWXC1(%[ftmp0], %[dst], %[stride], 0x00) - MMI_LDC1(%[ftmp5], $29, 0x00) - MMI_LDC1(%[ftmp4], $29, 0x10) + MMI_LDC1(%[ftmp5], $sp, 0x00) + MMI_LDC1(%[ftmp4], $sp, 0x10) "dmtc1 %[tmp1], %[ftmp6] \n\t" PTR_ADDU "%[dst], %[dst], %[stride] \n\t" PTR_ADDU "%[dst], %[dst], %[stride] \n\t" @@ -496,7 +497,7 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) MMI_SWXC1(%[ftmp0], %[dst], %[stride], 0x00) "dmtc1 %[tmp4], %[ftmp1] \n\t" "dmtc1 %[tmp2], %[ftmp6] \n\t" - MMI_LDC1(%[ftmp4], $29, 0x18) + MMI_LDC1(%[ftmp4], $sp, 0x18) "mov.d %[ftmp5], %[ftmp4] \n\t" "psrah %[ftmp4], %[ftmp4], %[ftmp8] \n\t" "psrah %[ftmp7], %[ftmp11], %[ftmp8] \n\t" @@ -528,7 +529,7 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) "psrah %[ftmp7], %[ftmp6], %[ftmp8] \n\t" "paddh %[ftmp0], %[ftmp0], %[ftmp6] \n\t" "psubh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" - MMI_LDC1(%[ftmp6], $29, 0x08) + MMI_LDC1(%[ftmp6], $sp, 0x08) "dmtc1 %[tmp6], %[ftmp3] \n\t" "paddh %[ftmp3], %[ftmp3], %[ftmp6] \n\t" "paddh %[ftmp6], %[ftmp6], %[ftmp6] \n\t" @@ -550,9 +551,9 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) "paddh %[ftmp4], %[ftmp4], %[ftmp3] \n\t" "psubh %[ftmp6], %[ftmp6], %[ftmp1] \n\t" "paddh %[ftmp3], %[ftmp3], %[ftmp3] \n\t" - MMI_SDC1(%[ftmp6], $29, 0x08) + MMI_SDC1(%[ftmp6], $sp, 0x08) "psubh %[ftmp3], %[ftmp3], %[ftmp4] \n\t" - MMI_SDC1(%[ftmp7], $29, 0x18) + MMI_SDC1(%[ftmp7], $sp, 0x18) "dmfc1 %[tmp2], %[ftmp0] \n\t" "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" MMI_ULWC1(%[ftmp6], %[addr0], 0x00) @@ -581,8 +582,8 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) "packushb %[ftmp7], %[ftmp7], %[ftmp0] \n\t" MMI_SWC1(%[ftmp6], %[addr0], 0x00) MMI_SWXC1(%[ftmp7], %[addr0], %[stride], 0x00) - MMI_LDC1(%[ftmp2], $29, 0x08) - MMI_LDC1(%[ftmp5], $29, 0x18) + MMI_LDC1(%[ftmp2], $sp, 0x08) + MMI_LDC1(%[ftmp5], $sp, 0x18) PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t" "dmtc1 %[tmp2], %[ftmp1] \n\t" PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t" @@ -612,7 +613,7 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) "packushb %[ftmp7], %[ftmp7], %[ftmp0] \n\t" MMI_SWC1(%[ftmp6], %[addr0], 0x00) MMI_SWXC1(%[ftmp7], %[addr0], %[stride], 0x00) - PTR_ADDIU "$29, $29, 0x20 \n\t" + PTR_ADDIU "$sp, $sp, 0x20 \n\t" : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), @@ -630,7 +631,7 @@ void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride) [addr0]"=&r"(addr[0]) : [dst]"r"(dst), [block]"r"(block), [stride]"r"((mips_reg)stride) - : "$29","memory" + : "memory" ); } @@ -1433,7 +1434,7 @@ void ff_h264_biweight_pixels4_8_mmi(uint8_t *dst, uint8_t *src, } } -void ff_deblock_v8_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, +void ff_deblock_v8_luma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int8_t *tc0) { double ftmp[12]; @@ -1561,7 +1562,7 @@ void ff_deblock_v8_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, ); } -static void deblock_v8_luma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +static void deblock_v8_luma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta) { DECLARE_ALIGNED(8, const uint64_t, stack[0x0a]); @@ -1871,7 +1872,7 @@ void ff_deblock_v_chroma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, ); } -void ff_deblock_v_chroma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +void ff_deblock_v_chroma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta) { double ftmp[9]; @@ -1949,7 +1950,7 @@ void ff_deblock_v_chroma_intra_8_mmi(uint8_t *pix, int stride, int alpha, ); } -void ff_deblock_h_chroma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, +void ff_deblock_h_chroma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int8_t *tc0) { double ftmp[11]; @@ -2089,7 +2090,7 @@ void ff_deblock_h_chroma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, ); } -void ff_deblock_h_chroma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +void ff_deblock_h_chroma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta) { double ftmp[11]; @@ -2222,7 +2223,7 @@ void ff_deblock_h_chroma_intra_8_mmi(uint8_t *pix, int stride, int alpha, ); } -void ff_deblock_v_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, +void ff_deblock_v_luma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int8_t *tc0) { if ((tc0[0] & tc0[1]) >= 0) @@ -2231,14 +2232,14 @@ void ff_deblock_v_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, ff_deblock_v8_luma_8_mmi(pix + 8, stride, alpha, beta, tc0 + 2); } -void ff_deblock_v_luma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +void ff_deblock_v_luma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta) { deblock_v8_luma_intra_8_mmi(pix + 0, stride, alpha, beta); deblock_v8_luma_intra_8_mmi(pix + 8, stride, alpha, beta); } -void ff_deblock_h_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, +void ff_deblock_h_luma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int8_t *tc0) { DECLARE_ALIGNED(8, const uint64_t, stack[0x0d]); @@ -2457,7 +2458,7 @@ void ff_deblock_h_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta, ); } -void ff_deblock_h_luma_intra_8_mmi(uint8_t *pix, int stride, int alpha, +void ff_deblock_h_luma_intra_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta) { DECLARE_ALIGNED(8, const uint64_t, ptmp[0x11]); diff --git a/libavcodec/mips/h264dsp_msa.c b/libavcodec/mips/h264dsp_msa.c index dd0598291..a8c3f3ced 100644 --- a/libavcodec/mips/h264dsp_msa.c +++ b/libavcodec/mips/h264dsp_msa.c @@ -21,7 +21,7 @@ #include "libavutil/mips/generic_macros_msa.h" #include "h264dsp_mips.h" -static void avc_wgt_4x2_msa(uint8_t *data, int32_t stride, +static void avc_wgt_4x2_msa(uint8_t *data, ptrdiff_t stride, int32_t log2_denom, int32_t src_weight, int32_t offset_in) { @@ -48,8 +48,9 @@ static void avc_wgt_4x2_msa(uint8_t *data, int32_t stride, ST_W2(src0, 0, 1, data, stride); } -static void avc_wgt_4x4_msa(uint8_t *data, int32_t stride, int32_t log2_denom, - int32_t src_weight, int32_t offset_in) +static void avc_wgt_4x4_msa(uint8_t *data, ptrdiff_t stride, + int32_t log2_denom, int32_t src_weight, + int32_t offset_in) { uint32_t tp0, tp1, tp2, tp3, offset_val; v16u8 src0 = { 0 }; @@ -74,8 +75,9 @@ static void avc_wgt_4x4_msa(uint8_t *data, int32_t stride, int32_t log2_denom, ST_W4(src0, 0, 1, 2, 3, data, stride); } -static void avc_wgt_4x8_msa(uint8_t *data, int32_t stride, int32_t log2_denom, - int32_t src_weight, int32_t offset_in) +static void avc_wgt_4x8_msa(uint8_t *data, ptrdiff_t stride, + int32_t log2_denom, int32_t src_weight, + int32_t offset_in) { uint32_t tp0, tp1, tp2, tp3, offset_val; v16u8 src0 = { 0 }, src1 = { 0 }; @@ -105,8 +107,9 @@ static void avc_wgt_4x8_msa(uint8_t *data, int32_t stride, int32_t log2_denom, ST_W8(src0, src1, 0, 1, 2, 3, 0, 1, 2, 3, data, stride); } -static void avc_wgt_8x4_msa(uint8_t *data, int32_t stride, int32_t log2_denom, - int32_t src_weight, int32_t offset_in) +static void avc_wgt_8x4_msa(uint8_t *data, ptrdiff_t stride, + int32_t log2_denom, int32_t src_weight, + int32_t offset_in) { uint32_t offset_val; uint64_t tp0, tp1, tp2, tp3; @@ -136,7 +139,7 @@ static void avc_wgt_8x4_msa(uint8_t *data, int32_t stride, int32_t log2_denom, ST_D4(src0, src1, 0, 1, 0, 1, data, stride); } -static void avc_wgt_8x8_msa(uint8_t *data, int32_t stride, int32_t log2_denom, +static void avc_wgt_8x8_msa(uint8_t *data, ptrdiff_t stride, int32_t log2_denom, int32_t src_weight, int32_t offset_in) { uint32_t offset_val; @@ -178,8 +181,9 @@ static void avc_wgt_8x8_msa(uint8_t *data, int32_t stride, int32_t log2_denom, ST_D8(src0, src1, src2, src3, 0, 1, 0, 1, 0, 1, 0, 1, data, stride); } -static void avc_wgt_8x16_msa(uint8_t *data, int32_t stride, int32_t log2_denom, - int32_t src_weight, int32_t offset_in) +static void avc_wgt_8x16_msa(uint8_t *data, ptrdiff_t stride, + int32_t log2_denom, int32_t src_weight, + int32_t offset_in) { uint32_t offset_val, cnt; uint64_t tp0, tp1, tp2, tp3; @@ -223,7 +227,7 @@ static void avc_wgt_8x16_msa(uint8_t *data, int32_t stride, int32_t log2_denom, } } -static void avc_biwgt_4x2_msa(uint8_t *src, uint8_t *dst, int32_t stride, +static void avc_biwgt_4x2_msa(uint8_t *src, uint8_t *dst, ptrdiff_t stride, int32_t log2_denom, int32_t src_weight, int32_t dst_weight, int32_t offset_in) { @@ -256,7 +260,7 @@ static void avc_biwgt_4x2_msa(uint8_t *src, uint8_t *dst, int32_t stride, ST_W2(dst0, 0, 1, dst, stride); } -static void avc_biwgt_4x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, +static void avc_biwgt_4x4_msa(uint8_t *src, uint8_t *dst, ptrdiff_t stride, int32_t log2_denom, int32_t src_weight, int32_t dst_weight, int32_t offset_in) { @@ -290,7 +294,7 @@ static void avc_biwgt_4x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, ST_W4(dst0, 0, 1, 2, 3, dst, stride); } -static void avc_biwgt_4x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, +static void avc_biwgt_4x8_msa(uint8_t *src, uint8_t *dst, ptrdiff_t stride, int32_t log2_denom, int32_t src_weight, int32_t dst_weight, int32_t offset_in) { @@ -330,7 +334,7 @@ static void avc_biwgt_4x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, ST_W8(dst0, dst1, 0, 1, 2, 3, 0, 1, 2, 3, dst, stride); } -static void avc_biwgt_8x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, +static void avc_biwgt_8x4_msa(uint8_t *src, uint8_t *dst, ptrdiff_t stride, int32_t log2_denom, int32_t src_weight, int32_t dst_weight, int32_t offset_in) { @@ -368,7 +372,7 @@ static void avc_biwgt_8x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, ST_D4(dst0, dst1, 0, 1, 0, 1, dst, stride); } -static void avc_biwgt_8x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, +static void avc_biwgt_8x8_msa(uint8_t *src, uint8_t *dst, ptrdiff_t stride, int32_t log2_denom, int32_t src_weight, int32_t dst_weight, int32_t offset_in) { @@ -419,7 +423,7 @@ static void avc_biwgt_8x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, ST_D8(dst0, dst1, dst2, dst3, 0, 1, 0, 1, 0, 1, 0, 1, dst, stride); } -static void avc_biwgt_8x16_msa(uint8_t *src, uint8_t *dst, int32_t stride, +static void avc_biwgt_8x16_msa(uint8_t *src, uint8_t *dst, ptrdiff_t stride, int32_t log2_denom, int32_t src_weight, int32_t dst_weight, int32_t offset_in) { @@ -679,7 +683,7 @@ static void avc_biwgt_8x16_msa(uint8_t *src, uint8_t *dst, int32_t stride, static void avc_loopfilter_luma_intra_edge_hor_msa(uint8_t *data, uint8_t alpha_in, uint8_t beta_in, - uint32_t img_width) + ptrdiff_t img_width) { v16u8 p0_asub_q0, p1_asub_p0, q1_asub_q0; v16u8 is_less_than, is_less_than_beta, is_less_than_alpha; @@ -812,7 +816,7 @@ static void avc_loopfilter_luma_intra_edge_hor_msa(uint8_t *data, static void avc_loopfilter_luma_intra_edge_ver_msa(uint8_t *data, uint8_t alpha_in, uint8_t beta_in, - uint32_t img_width) + ptrdiff_t img_width) { uint8_t *src = data - 4; v16u8 alpha, beta, p0_asub_q0; @@ -969,7 +973,8 @@ static void avc_loopfilter_luma_intra_edge_ver_msa(uint8_t *data, } } -static void avc_h_loop_filter_luma_mbaff_intra_msa(uint8_t *src, int32_t stride, +static void avc_h_loop_filter_luma_mbaff_intra_msa(uint8_t *src, + ptrdiff_t stride, int32_t alpha_in, int32_t beta_in) { @@ -1171,7 +1176,7 @@ static void avc_h_loop_filter_luma_mbaff_intra_msa(uint8_t *src, int32_t stride, static void avc_loopfilter_cb_or_cr_intra_edge_hor_msa(uint8_t *data_cb_or_cr, uint8_t alpha_in, uint8_t beta_in, - uint32_t img_width) + ptrdiff_t img_width) { v16u8 alpha, beta; v16u8 is_less_than; @@ -1220,7 +1225,7 @@ static void avc_loopfilter_cb_or_cr_intra_edge_hor_msa(uint8_t *data_cb_or_cr, static void avc_loopfilter_cb_or_cr_intra_edge_ver_msa(uint8_t *data_cb_or_cr, uint8_t alpha_in, uint8_t beta_in, - uint32_t img_width) + ptrdiff_t img_width) { v8i16 tmp1; v16u8 alpha, beta, is_less_than; @@ -1286,7 +1291,7 @@ static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, uint8_t tc2, uint8_t tc3, uint8_t alpha_in, uint8_t beta_in, - uint32_t img_width) + ptrdiff_t img_width) { v16u8 tmp_vec, bs = { 0 }; @@ -1566,7 +1571,7 @@ static void avc_loopfilter_luma_inter_edge_hor_msa(uint8_t *data, uint8_t tc2, uint8_t tc3, uint8_t alpha_in, uint8_t beta_in, - uint32_t image_width) + ptrdiff_t image_width) { v16u8 tmp_vec; v16u8 bs = { 0 }; @@ -1715,7 +1720,7 @@ static void avc_loopfilter_luma_inter_edge_hor_msa(uint8_t *data, } } -static void avc_h_loop_filter_luma_mbaff_msa(uint8_t *in, int32_t stride, +static void avc_h_loop_filter_luma_mbaff_msa(uint8_t *in, ptrdiff_t stride, int32_t alpha_in, int32_t beta_in, int8_t *tc0) { @@ -1941,7 +1946,7 @@ static void avc_loopfilter_cb_or_cr_inter_edge_hor_msa(uint8_t *data, uint8_t tc2, uint8_t tc3, uint8_t alpha_in, uint8_t beta_in, - uint32_t img_width) + ptrdiff_t img_width) { v16u8 alpha, beta; v8i16 tmp_vec; @@ -2027,7 +2032,7 @@ static void avc_loopfilter_cb_or_cr_inter_edge_ver_msa(uint8_t *data, uint8_t tc2, uint8_t tc3, uint8_t alpha_in, uint8_t beta_in, - uint32_t img_width) + ptrdiff_t img_width) { uint8_t *src; v16u8 alpha, beta; @@ -2115,7 +2120,7 @@ static void avc_loopfilter_cb_or_cr_inter_edge_ver_msa(uint8_t *data, } } -static void avc_h_loop_filter_chroma422_msa(uint8_t *src, int32_t stride, +static void avc_h_loop_filter_chroma422_msa(uint8_t *src, ptrdiff_t stride, int32_t alpha_in, int32_t beta_in, int8_t *tc0) { @@ -2139,7 +2144,8 @@ static void avc_h_loop_filter_chroma422_msa(uint8_t *src, int32_t stride, } } -static void avc_h_loop_filter_chroma422_mbaff_msa(uint8_t *src, int32_t stride, +static void avc_h_loop_filter_chroma422_mbaff_msa(uint8_t *src, + ptrdiff_t stride, int32_t alpha_in, int32_t beta_in, int8_t *tc0) @@ -2171,7 +2177,7 @@ static void avc_h_loop_filter_chroma422_mbaff_msa(uint8_t *src, int32_t stride, } } -void ff_h264_h_lpf_luma_inter_msa(uint8_t *data, int img_width, +void ff_h264_h_lpf_luma_inter_msa(uint8_t *data, ptrdiff_t img_width, int alpha, int beta, int8_t *tc) { uint8_t bs0 = 1; @@ -2193,7 +2199,7 @@ void ff_h264_h_lpf_luma_inter_msa(uint8_t *data, int img_width, alpha, beta, img_width); } -void ff_h264_v_lpf_luma_inter_msa(uint8_t *data, int img_width, +void ff_h264_v_lpf_luma_inter_msa(uint8_t *data, ptrdiff_t img_width, int alpha, int beta, int8_t *tc) { @@ -2216,7 +2222,7 @@ void ff_h264_v_lpf_luma_inter_msa(uint8_t *data, int img_width, alpha, beta, img_width); } -void ff_h264_h_lpf_chroma_inter_msa(uint8_t *data, int img_width, +void ff_h264_h_lpf_chroma_inter_msa(uint8_t *data, ptrdiff_t img_width, int alpha, int beta, int8_t *tc) { uint8_t bs0 = 1; @@ -2238,7 +2244,7 @@ void ff_h264_h_lpf_chroma_inter_msa(uint8_t *data, int img_width, alpha, beta, img_width); } -void ff_h264_v_lpf_chroma_inter_msa(uint8_t *data, int img_width, +void ff_h264_v_lpf_chroma_inter_msa(uint8_t *data, ptrdiff_t img_width, int alpha, int beta, int8_t *tc) { uint8_t bs0 = 1; @@ -2260,40 +2266,40 @@ void ff_h264_v_lpf_chroma_inter_msa(uint8_t *data, int img_width, alpha, beta, img_width); } -void ff_h264_h_lpf_luma_intra_msa(uint8_t *data, int img_width, +void ff_h264_h_lpf_luma_intra_msa(uint8_t *data, ptrdiff_t img_width, int alpha, int beta) { avc_loopfilter_luma_intra_edge_ver_msa(data, (uint8_t) alpha, (uint8_t) beta, - (unsigned int) img_width); + img_width); } -void ff_h264_v_lpf_luma_intra_msa(uint8_t *data, int img_width, +void ff_h264_v_lpf_luma_intra_msa(uint8_t *data, ptrdiff_t img_width, int alpha, int beta) { avc_loopfilter_luma_intra_edge_hor_msa(data, (uint8_t) alpha, (uint8_t) beta, - (unsigned int) img_width); + img_width); } -void ff_h264_h_lpf_chroma_intra_msa(uint8_t *data, int img_width, +void ff_h264_h_lpf_chroma_intra_msa(uint8_t *data, ptrdiff_t img_width, int alpha, int beta) { avc_loopfilter_cb_or_cr_intra_edge_ver_msa(data, (uint8_t) alpha, (uint8_t) beta, - (unsigned int) img_width); + img_width); } -void ff_h264_v_lpf_chroma_intra_msa(uint8_t *data, int img_width, +void ff_h264_v_lpf_chroma_intra_msa(uint8_t *data, ptrdiff_t img_width, int alpha, int beta) { avc_loopfilter_cb_or_cr_intra_edge_hor_msa(data, (uint8_t) alpha, (uint8_t) beta, - (unsigned int) img_width); + img_width); } void ff_h264_h_loop_filter_chroma422_msa(uint8_t *src, - int32_t ystride, + ptrdiff_t ystride, int32_t alpha, int32_t beta, int8_t *tc0) { @@ -2301,7 +2307,7 @@ void ff_h264_h_loop_filter_chroma422_msa(uint8_t *src, } void ff_h264_h_loop_filter_chroma422_mbaff_msa(uint8_t *src, - int32_t ystride, + ptrdiff_t ystride, int32_t alpha, int32_t beta, int8_t *tc0) @@ -2310,7 +2316,7 @@ void ff_h264_h_loop_filter_chroma422_mbaff_msa(uint8_t *src, } void ff_h264_h_loop_filter_luma_mbaff_msa(uint8_t *src, - int32_t ystride, + ptrdiff_t ystride, int32_t alpha, int32_t beta, int8_t *tc0) @@ -2319,7 +2325,7 @@ void ff_h264_h_loop_filter_luma_mbaff_msa(uint8_t *src, } void ff_h264_h_loop_filter_luma_mbaff_intra_msa(uint8_t *src, - int32_t ystride, + ptrdiff_t ystride, int32_t alpha, int32_t beta) { diff --git a/libavcodec/mips/h264pred_init_mips.c b/libavcodec/mips/h264pred_init_mips.c index e537ad8bd..0fd9bb737 100644 --- a/libavcodec/mips/h264pred_init_mips.c +++ b/libavcodec/mips/h264pred_init_mips.c @@ -19,134 +19,121 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "config.h" #include "h264dsp_mips.h" #include "h264pred_mips.h" -#if HAVE_MSA -static av_cold void h264_pred_init_msa(H264PredContext *h, int codec_id, - const int bit_depth, - const int chroma_format_idc) -{ - if (8 == bit_depth) { - if (chroma_format_idc == 1) { - h->pred8x8[VERT_PRED8x8] = ff_h264_intra_pred_vert_8x8_msa; - h->pred8x8[HOR_PRED8x8] = ff_h264_intra_pred_horiz_8x8_msa; - } - - if (codec_id != AV_CODEC_ID_VP7 && codec_id != AV_CODEC_ID_VP8) { - if (chroma_format_idc == 1) { - h->pred8x8[PLANE_PRED8x8] = ff_h264_intra_predict_plane_8x8_msa; - } - } - if (codec_id != AV_CODEC_ID_RV40 && codec_id != AV_CODEC_ID_VP7 - && codec_id != AV_CODEC_ID_VP8) { - if (chroma_format_idc == 1) { - h->pred8x8[DC_PRED8x8] = ff_h264_intra_predict_dc_4blk_8x8_msa; - h->pred8x8[LEFT_DC_PRED8x8] = - ff_h264_intra_predict_hor_dc_8x8_msa; - h->pred8x8[TOP_DC_PRED8x8] = - ff_h264_intra_predict_vert_dc_8x8_msa; - h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8] = - ff_h264_intra_predict_mad_cow_dc_l0t_8x8_msa; - h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8] = - ff_h264_intra_predict_mad_cow_dc_0lt_8x8_msa; - h->pred8x8[ALZHEIMER_DC_L00_PRED8x8] = - ff_h264_intra_predict_mad_cow_dc_l00_8x8_msa; - h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8] = - ff_h264_intra_predict_mad_cow_dc_0l0_8x8_msa; - } - } else { - if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { - h->pred8x8[7] = ff_vp8_pred8x8_127_dc_8_msa; - h->pred8x8[8] = ff_vp8_pred8x8_129_dc_8_msa; - } - } - - if (chroma_format_idc == 1) { - h->pred8x8[DC_128_PRED8x8] = ff_h264_intra_pred_dc_128_8x8_msa; - } - - h->pred16x16[DC_PRED8x8] = ff_h264_intra_pred_dc_16x16_msa; - h->pred16x16[VERT_PRED8x8] = ff_h264_intra_pred_vert_16x16_msa; - h->pred16x16[HOR_PRED8x8] = ff_h264_intra_pred_horiz_16x16_msa; - - switch (codec_id) { - case AV_CODEC_ID_SVQ3: - case AV_CODEC_ID_RV40: - break; - case AV_CODEC_ID_VP7: - case AV_CODEC_ID_VP8: - h->pred16x16[7] = ff_vp8_pred16x16_127_dc_8_msa; - h->pred16x16[8] = ff_vp8_pred16x16_129_dc_8_msa; - break; - default: - h->pred16x16[PLANE_PRED8x8] = - ff_h264_intra_predict_plane_16x16_msa; - break; - } - - h->pred16x16[LEFT_DC_PRED8x8] = ff_h264_intra_pred_dc_left_16x16_msa; - h->pred16x16[TOP_DC_PRED8x8] = ff_h264_intra_pred_dc_top_16x16_msa; - h->pred16x16[DC_128_PRED8x8] = ff_h264_intra_pred_dc_128_16x16_msa; - } -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static av_cold void h264_pred_init_mmi(H264PredContext *h, int codec_id, - const int bit_depth, const int chroma_format_idc) -{ - if (bit_depth == 8) { - if (chroma_format_idc == 1) { - h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x8_vertical_8_mmi; - h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_mmi; - } else { - h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x16_vertical_8_mmi; - h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x16_horizontal_8_mmi; - } - - h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_mmi; - h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_8_mmi; - h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmi; - h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_8_mmi; - h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_8_mmi; - -#if ARCH_MIPS64 - switch (codec_id) { - case AV_CODEC_ID_SVQ3: - h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_svq3_8_mmi; - break; - case AV_CODEC_ID_RV40: - h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_rv40_8_mmi; - break; - case AV_CODEC_ID_VP7: - case AV_CODEC_ID_VP8: - break; - default: - h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_h264_8_mmi; - break; - } -#endif - - if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) { - if (chroma_format_idc == 1) { - h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_8_mmi; - h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_8_mmi; - } - } - } -} -#endif /* HAVE_MMI */ - av_cold void ff_h264_pred_init_mips(H264PredContext *h, int codec_id, int bit_depth, const int chroma_format_idc) { -#if HAVE_MMI - h264_pred_init_mmi(h, codec_id, bit_depth, chroma_format_idc); -#endif /* HAVE_MMI */ -#if HAVE_MSA - h264_pred_init_msa(h, codec_id, bit_depth, chroma_format_idc); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + if (bit_depth == 8) { + if (chroma_format_idc == 1) { + h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x8_vertical_8_mmi; + h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_mmi; + } else { + h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x16_vertical_8_mmi; + h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x16_horizontal_8_mmi; + } + + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_mmi; + h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_8_mmi; + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmi; + h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_8_mmi; + h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_8_mmi; + + #if ARCH_MIPS64 + switch (codec_id) { + case AV_CODEC_ID_SVQ3: + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_svq3_8_mmi; + break; + case AV_CODEC_ID_RV40: + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_rv40_8_mmi; + break; + case AV_CODEC_ID_VP7: + case AV_CODEC_ID_VP8: + break; + default: + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_h264_8_mmi; + break; + } + #endif + + if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) { + if (chroma_format_idc == 1) { + h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_8_mmi; + h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_8_mmi; + } + } + } + } + + if (have_msa(cpu_flags)) { + if (8 == bit_depth) { + if (chroma_format_idc == 1) { + h->pred8x8[VERT_PRED8x8] = ff_h264_intra_pred_vert_8x8_msa; + h->pred8x8[HOR_PRED8x8] = ff_h264_intra_pred_horiz_8x8_msa; + } + + if (codec_id != AV_CODEC_ID_VP7 && codec_id != AV_CODEC_ID_VP8) { + if (chroma_format_idc == 1) { + h->pred8x8[PLANE_PRED8x8] = ff_h264_intra_predict_plane_8x8_msa; + } + } + if (codec_id != AV_CODEC_ID_RV40 && codec_id != AV_CODEC_ID_VP7 + && codec_id != AV_CODEC_ID_VP8) { + if (chroma_format_idc == 1) { + h->pred8x8[DC_PRED8x8] = ff_h264_intra_predict_dc_4blk_8x8_msa; + h->pred8x8[LEFT_DC_PRED8x8] = + ff_h264_intra_predict_hor_dc_8x8_msa; + h->pred8x8[TOP_DC_PRED8x8] = + ff_h264_intra_predict_vert_dc_8x8_msa; + h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8] = + ff_h264_intra_predict_mad_cow_dc_l0t_8x8_msa; + h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8] = + ff_h264_intra_predict_mad_cow_dc_0lt_8x8_msa; + h->pred8x8[ALZHEIMER_DC_L00_PRED8x8] = + ff_h264_intra_predict_mad_cow_dc_l00_8x8_msa; + h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8] = + ff_h264_intra_predict_mad_cow_dc_0l0_8x8_msa; + } + } else { + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { + h->pred8x8[7] = ff_vp8_pred8x8_127_dc_8_msa; + h->pred8x8[8] = ff_vp8_pred8x8_129_dc_8_msa; + } + } + + if (chroma_format_idc == 1) { + h->pred8x8[DC_128_PRED8x8] = ff_h264_intra_pred_dc_128_8x8_msa; + } + + h->pred16x16[DC_PRED8x8] = ff_h264_intra_pred_dc_16x16_msa; + h->pred16x16[VERT_PRED8x8] = ff_h264_intra_pred_vert_16x16_msa; + h->pred16x16[HOR_PRED8x8] = ff_h264_intra_pred_horiz_16x16_msa; + + switch (codec_id) { + case AV_CODEC_ID_SVQ3: + case AV_CODEC_ID_RV40: + break; + case AV_CODEC_ID_VP7: + case AV_CODEC_ID_VP8: + h->pred16x16[7] = ff_vp8_pred16x16_127_dc_8_msa; + h->pred16x16[8] = ff_vp8_pred16x16_129_dc_8_msa; + break; + default: + h->pred16x16[PLANE_PRED8x8] = + ff_h264_intra_predict_plane_16x16_msa; + break; + } + + h->pred16x16[LEFT_DC_PRED8x8] = ff_h264_intra_pred_dc_left_16x16_msa; + h->pred16x16[TOP_DC_PRED8x8] = ff_h264_intra_pred_dc_top_16x16_msa; + h->pred16x16[DC_128_PRED8x8] = ff_h264_intra_pred_dc_128_16x16_msa; + } + } } diff --git a/libavcodec/mips/h264pred_mmi.c b/libavcodec/mips/h264pred_mmi.c index f4fe0911a..0209c2e43 100644 --- a/libavcodec/mips/h264pred_mmi.c +++ b/libavcodec/mips/h264pred_mmi.c @@ -178,7 +178,9 @@ void ff_pred8x8l_top_dc_8_mmi(uint8_t *src, int has_topleft, "1: \n\t" "bnez %[has_topright], 2f \n\t" - "pinsrh_3 %[ftmp2], %[ftmp2], %[ftmp4] \n\t" + "dli %[tmp0], 0xa4 \n\t" + "mtc1 %[tmp0], %[ftmp1] \n\t" + "pshufh %[ftmp2], %[ftmp2], %[ftmp1] \n\t" "2: \n\t" "dli %[tmp0], 0x02 \n\t" @@ -370,7 +372,9 @@ void ff_pred8x8l_vertical_8_mmi(uint8_t *src, int has_topleft, "1: \n\t" "bnez %[has_topright], 2f \n\t" - "pinsrh_3 %[ftmp11], %[ftmp11], %[ftmp9] \n\t" + "dli %[tmp0], 0xa4 \n\t" + "mtc1 %[tmp0], %[ftmp1] \n\t" + "pshufh %[ftmp11], %[ftmp11], %[ftmp1] \n\t" "2: \n\t" "dli %[tmp0], 0x02 \n\t" diff --git a/libavcodec/mips/h264qpel_init_mips.c b/libavcodec/mips/h264qpel_init_mips.c index 33bae3093..ea839f071 100644 --- a/libavcodec/mips/h264qpel_init_mips.c +++ b/libavcodec/mips/h264qpel_init_mips.c @@ -19,231 +19,221 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "h264dsp_mips.h" -#if HAVE_MSA -static av_cold void h264qpel_init_msa(H264QpelContext *c, int bit_depth) -{ - if (8 == bit_depth) { - c->put_h264_qpel_pixels_tab[0][0] = ff_put_h264_qpel16_mc00_msa; - c->put_h264_qpel_pixels_tab[0][1] = ff_put_h264_qpel16_mc10_msa; - c->put_h264_qpel_pixels_tab[0][2] = ff_put_h264_qpel16_mc20_msa; - c->put_h264_qpel_pixels_tab[0][3] = ff_put_h264_qpel16_mc30_msa; - c->put_h264_qpel_pixels_tab[0][4] = ff_put_h264_qpel16_mc01_msa; - c->put_h264_qpel_pixels_tab[0][5] = ff_put_h264_qpel16_mc11_msa; - c->put_h264_qpel_pixels_tab[0][6] = ff_put_h264_qpel16_mc21_msa; - c->put_h264_qpel_pixels_tab[0][7] = ff_put_h264_qpel16_mc31_msa; - c->put_h264_qpel_pixels_tab[0][8] = ff_put_h264_qpel16_mc02_msa; - c->put_h264_qpel_pixels_tab[0][9] = ff_put_h264_qpel16_mc12_msa; - c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_msa; - c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_msa; - c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_msa; - c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_msa; - c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_msa; - c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_msa; - - c->put_h264_qpel_pixels_tab[1][0] = ff_put_h264_qpel8_mc00_msa; - c->put_h264_qpel_pixels_tab[1][1] = ff_put_h264_qpel8_mc10_msa; - c->put_h264_qpel_pixels_tab[1][2] = ff_put_h264_qpel8_mc20_msa; - c->put_h264_qpel_pixels_tab[1][3] = ff_put_h264_qpel8_mc30_msa; - c->put_h264_qpel_pixels_tab[1][4] = ff_put_h264_qpel8_mc01_msa; - c->put_h264_qpel_pixels_tab[1][5] = ff_put_h264_qpel8_mc11_msa; - c->put_h264_qpel_pixels_tab[1][6] = ff_put_h264_qpel8_mc21_msa; - c->put_h264_qpel_pixels_tab[1][7] = ff_put_h264_qpel8_mc31_msa; - c->put_h264_qpel_pixels_tab[1][8] = ff_put_h264_qpel8_mc02_msa; - c->put_h264_qpel_pixels_tab[1][9] = ff_put_h264_qpel8_mc12_msa; - c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_msa; - c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_msa; - c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_msa; - c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_msa; - c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_msa; - c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_msa; - - c->put_h264_qpel_pixels_tab[2][1] = ff_put_h264_qpel4_mc10_msa; - c->put_h264_qpel_pixels_tab[2][2] = ff_put_h264_qpel4_mc20_msa; - c->put_h264_qpel_pixels_tab[2][3] = ff_put_h264_qpel4_mc30_msa; - c->put_h264_qpel_pixels_tab[2][4] = ff_put_h264_qpel4_mc01_msa; - c->put_h264_qpel_pixels_tab[2][5] = ff_put_h264_qpel4_mc11_msa; - c->put_h264_qpel_pixels_tab[2][6] = ff_put_h264_qpel4_mc21_msa; - c->put_h264_qpel_pixels_tab[2][7] = ff_put_h264_qpel4_mc31_msa; - c->put_h264_qpel_pixels_tab[2][8] = ff_put_h264_qpel4_mc02_msa; - c->put_h264_qpel_pixels_tab[2][9] = ff_put_h264_qpel4_mc12_msa; - c->put_h264_qpel_pixels_tab[2][10] = ff_put_h264_qpel4_mc22_msa; - c->put_h264_qpel_pixels_tab[2][11] = ff_put_h264_qpel4_mc32_msa; - c->put_h264_qpel_pixels_tab[2][12] = ff_put_h264_qpel4_mc03_msa; - c->put_h264_qpel_pixels_tab[2][13] = ff_put_h264_qpel4_mc13_msa; - c->put_h264_qpel_pixels_tab[2][14] = ff_put_h264_qpel4_mc23_msa; - c->put_h264_qpel_pixels_tab[2][15] = ff_put_h264_qpel4_mc33_msa; - - c->avg_h264_qpel_pixels_tab[0][0] = ff_avg_h264_qpel16_mc00_msa; - c->avg_h264_qpel_pixels_tab[0][1] = ff_avg_h264_qpel16_mc10_msa; - c->avg_h264_qpel_pixels_tab[0][2] = ff_avg_h264_qpel16_mc20_msa; - c->avg_h264_qpel_pixels_tab[0][3] = ff_avg_h264_qpel16_mc30_msa; - c->avg_h264_qpel_pixels_tab[0][4] = ff_avg_h264_qpel16_mc01_msa; - c->avg_h264_qpel_pixels_tab[0][5] = ff_avg_h264_qpel16_mc11_msa; - c->avg_h264_qpel_pixels_tab[0][6] = ff_avg_h264_qpel16_mc21_msa; - c->avg_h264_qpel_pixels_tab[0][7] = ff_avg_h264_qpel16_mc31_msa; - c->avg_h264_qpel_pixels_tab[0][8] = ff_avg_h264_qpel16_mc02_msa; - c->avg_h264_qpel_pixels_tab[0][9] = ff_avg_h264_qpel16_mc12_msa; - c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_msa; - c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_msa; - c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_msa; - c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_msa; - c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_msa; - c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_msa; - - c->avg_h264_qpel_pixels_tab[1][0] = ff_avg_h264_qpel8_mc00_msa; - c->avg_h264_qpel_pixels_tab[1][1] = ff_avg_h264_qpel8_mc10_msa; - c->avg_h264_qpel_pixels_tab[1][2] = ff_avg_h264_qpel8_mc20_msa; - c->avg_h264_qpel_pixels_tab[1][3] = ff_avg_h264_qpel8_mc30_msa; - c->avg_h264_qpel_pixels_tab[1][4] = ff_avg_h264_qpel8_mc01_msa; - c->avg_h264_qpel_pixels_tab[1][5] = ff_avg_h264_qpel8_mc11_msa; - c->avg_h264_qpel_pixels_tab[1][6] = ff_avg_h264_qpel8_mc21_msa; - c->avg_h264_qpel_pixels_tab[1][7] = ff_avg_h264_qpel8_mc31_msa; - c->avg_h264_qpel_pixels_tab[1][8] = ff_avg_h264_qpel8_mc02_msa; - c->avg_h264_qpel_pixels_tab[1][9] = ff_avg_h264_qpel8_mc12_msa; - c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_msa; - c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_msa; - c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_msa; - c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_msa; - c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_msa; - c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_msa; - - c->avg_h264_qpel_pixels_tab[2][0] = ff_avg_h264_qpel4_mc00_msa; - c->avg_h264_qpel_pixels_tab[2][1] = ff_avg_h264_qpel4_mc10_msa; - c->avg_h264_qpel_pixels_tab[2][2] = ff_avg_h264_qpel4_mc20_msa; - c->avg_h264_qpel_pixels_tab[2][3] = ff_avg_h264_qpel4_mc30_msa; - c->avg_h264_qpel_pixels_tab[2][4] = ff_avg_h264_qpel4_mc01_msa; - c->avg_h264_qpel_pixels_tab[2][5] = ff_avg_h264_qpel4_mc11_msa; - c->avg_h264_qpel_pixels_tab[2][6] = ff_avg_h264_qpel4_mc21_msa; - c->avg_h264_qpel_pixels_tab[2][7] = ff_avg_h264_qpel4_mc31_msa; - c->avg_h264_qpel_pixels_tab[2][8] = ff_avg_h264_qpel4_mc02_msa; - c->avg_h264_qpel_pixels_tab[2][9] = ff_avg_h264_qpel4_mc12_msa; - c->avg_h264_qpel_pixels_tab[2][10] = ff_avg_h264_qpel4_mc22_msa; - c->avg_h264_qpel_pixels_tab[2][11] = ff_avg_h264_qpel4_mc32_msa; - c->avg_h264_qpel_pixels_tab[2][12] = ff_avg_h264_qpel4_mc03_msa; - c->avg_h264_qpel_pixels_tab[2][13] = ff_avg_h264_qpel4_mc13_msa; - c->avg_h264_qpel_pixels_tab[2][14] = ff_avg_h264_qpel4_mc23_msa; - c->avg_h264_qpel_pixels_tab[2][15] = ff_avg_h264_qpel4_mc33_msa; - } -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static av_cold void h264qpel_init_mmi(H264QpelContext *c, int bit_depth) -{ - if (8 == bit_depth) { - c->put_h264_qpel_pixels_tab[0][0] = ff_put_h264_qpel16_mc00_mmi; - c->put_h264_qpel_pixels_tab[0][1] = ff_put_h264_qpel16_mc10_mmi; - c->put_h264_qpel_pixels_tab[0][2] = ff_put_h264_qpel16_mc20_mmi; - c->put_h264_qpel_pixels_tab[0][3] = ff_put_h264_qpel16_mc30_mmi; - c->put_h264_qpel_pixels_tab[0][4] = ff_put_h264_qpel16_mc01_mmi; - c->put_h264_qpel_pixels_tab[0][5] = ff_put_h264_qpel16_mc11_mmi; - c->put_h264_qpel_pixels_tab[0][6] = ff_put_h264_qpel16_mc21_mmi; - c->put_h264_qpel_pixels_tab[0][7] = ff_put_h264_qpel16_mc31_mmi; - c->put_h264_qpel_pixels_tab[0][8] = ff_put_h264_qpel16_mc02_mmi; - c->put_h264_qpel_pixels_tab[0][9] = ff_put_h264_qpel16_mc12_mmi; - c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_mmi; - c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_mmi; - c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_mmi; - c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_mmi; - c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_mmi; - c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_mmi; - - c->put_h264_qpel_pixels_tab[1][0] = ff_put_h264_qpel8_mc00_mmi; - c->put_h264_qpel_pixels_tab[1][1] = ff_put_h264_qpel8_mc10_mmi; - c->put_h264_qpel_pixels_tab[1][2] = ff_put_h264_qpel8_mc20_mmi; - c->put_h264_qpel_pixels_tab[1][3] = ff_put_h264_qpel8_mc30_mmi; - c->put_h264_qpel_pixels_tab[1][4] = ff_put_h264_qpel8_mc01_mmi; - c->put_h264_qpel_pixels_tab[1][5] = ff_put_h264_qpel8_mc11_mmi; - c->put_h264_qpel_pixels_tab[1][6] = ff_put_h264_qpel8_mc21_mmi; - c->put_h264_qpel_pixels_tab[1][7] = ff_put_h264_qpel8_mc31_mmi; - c->put_h264_qpel_pixels_tab[1][8] = ff_put_h264_qpel8_mc02_mmi; - c->put_h264_qpel_pixels_tab[1][9] = ff_put_h264_qpel8_mc12_mmi; - c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_mmi; - c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_mmi; - c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_mmi; - c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_mmi; - c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_mmi; - c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_mmi; - - c->put_h264_qpel_pixels_tab[2][0] = ff_put_h264_qpel4_mc00_mmi; - c->put_h264_qpel_pixels_tab[2][1] = ff_put_h264_qpel4_mc10_mmi; - c->put_h264_qpel_pixels_tab[2][2] = ff_put_h264_qpel4_mc20_mmi; - c->put_h264_qpel_pixels_tab[2][3] = ff_put_h264_qpel4_mc30_mmi; - c->put_h264_qpel_pixels_tab[2][4] = ff_put_h264_qpel4_mc01_mmi; - c->put_h264_qpel_pixels_tab[2][5] = ff_put_h264_qpel4_mc11_mmi; - c->put_h264_qpel_pixels_tab[2][6] = ff_put_h264_qpel4_mc21_mmi; - c->put_h264_qpel_pixels_tab[2][7] = ff_put_h264_qpel4_mc31_mmi; - c->put_h264_qpel_pixels_tab[2][8] = ff_put_h264_qpel4_mc02_mmi; - c->put_h264_qpel_pixels_tab[2][9] = ff_put_h264_qpel4_mc12_mmi; - c->put_h264_qpel_pixels_tab[2][10] = ff_put_h264_qpel4_mc22_mmi; - c->put_h264_qpel_pixels_tab[2][11] = ff_put_h264_qpel4_mc32_mmi; - c->put_h264_qpel_pixels_tab[2][12] = ff_put_h264_qpel4_mc03_mmi; - c->put_h264_qpel_pixels_tab[2][13] = ff_put_h264_qpel4_mc13_mmi; - c->put_h264_qpel_pixels_tab[2][14] = ff_put_h264_qpel4_mc23_mmi; - c->put_h264_qpel_pixels_tab[2][15] = ff_put_h264_qpel4_mc33_mmi; - - c->avg_h264_qpel_pixels_tab[0][0] = ff_avg_h264_qpel16_mc00_mmi; - c->avg_h264_qpel_pixels_tab[0][1] = ff_avg_h264_qpel16_mc10_mmi; - c->avg_h264_qpel_pixels_tab[0][2] = ff_avg_h264_qpel16_mc20_mmi; - c->avg_h264_qpel_pixels_tab[0][3] = ff_avg_h264_qpel16_mc30_mmi; - c->avg_h264_qpel_pixels_tab[0][4] = ff_avg_h264_qpel16_mc01_mmi; - c->avg_h264_qpel_pixels_tab[0][5] = ff_avg_h264_qpel16_mc11_mmi; - c->avg_h264_qpel_pixels_tab[0][6] = ff_avg_h264_qpel16_mc21_mmi; - c->avg_h264_qpel_pixels_tab[0][7] = ff_avg_h264_qpel16_mc31_mmi; - c->avg_h264_qpel_pixels_tab[0][8] = ff_avg_h264_qpel16_mc02_mmi; - c->avg_h264_qpel_pixels_tab[0][9] = ff_avg_h264_qpel16_mc12_mmi; - c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_mmi; - c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_mmi; - c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_mmi; - c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_mmi; - c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_mmi; - c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_mmi; - - c->avg_h264_qpel_pixels_tab[1][0] = ff_avg_h264_qpel8_mc00_mmi; - c->avg_h264_qpel_pixels_tab[1][1] = ff_avg_h264_qpel8_mc10_mmi; - c->avg_h264_qpel_pixels_tab[1][2] = ff_avg_h264_qpel8_mc20_mmi; - c->avg_h264_qpel_pixels_tab[1][3] = ff_avg_h264_qpel8_mc30_mmi; - c->avg_h264_qpel_pixels_tab[1][4] = ff_avg_h264_qpel8_mc01_mmi; - c->avg_h264_qpel_pixels_tab[1][5] = ff_avg_h264_qpel8_mc11_mmi; - c->avg_h264_qpel_pixels_tab[1][6] = ff_avg_h264_qpel8_mc21_mmi; - c->avg_h264_qpel_pixels_tab[1][7] = ff_avg_h264_qpel8_mc31_mmi; - c->avg_h264_qpel_pixels_tab[1][8] = ff_avg_h264_qpel8_mc02_mmi; - c->avg_h264_qpel_pixels_tab[1][9] = ff_avg_h264_qpel8_mc12_mmi; - c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_mmi; - c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_mmi; - c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_mmi; - c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_mmi; - c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_mmi; - c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_mmi; - - c->avg_h264_qpel_pixels_tab[2][0] = ff_avg_h264_qpel4_mc00_mmi; - c->avg_h264_qpel_pixels_tab[2][1] = ff_avg_h264_qpel4_mc10_mmi; - c->avg_h264_qpel_pixels_tab[2][2] = ff_avg_h264_qpel4_mc20_mmi; - c->avg_h264_qpel_pixels_tab[2][3] = ff_avg_h264_qpel4_mc30_mmi; - c->avg_h264_qpel_pixels_tab[2][4] = ff_avg_h264_qpel4_mc01_mmi; - c->avg_h264_qpel_pixels_tab[2][5] = ff_avg_h264_qpel4_mc11_mmi; - c->avg_h264_qpel_pixels_tab[2][6] = ff_avg_h264_qpel4_mc21_mmi; - c->avg_h264_qpel_pixels_tab[2][7] = ff_avg_h264_qpel4_mc31_mmi; - c->avg_h264_qpel_pixels_tab[2][8] = ff_avg_h264_qpel4_mc02_mmi; - c->avg_h264_qpel_pixels_tab[2][9] = ff_avg_h264_qpel4_mc12_mmi; - c->avg_h264_qpel_pixels_tab[2][10] = ff_avg_h264_qpel4_mc22_mmi; - c->avg_h264_qpel_pixels_tab[2][11] = ff_avg_h264_qpel4_mc32_mmi; - c->avg_h264_qpel_pixels_tab[2][12] = ff_avg_h264_qpel4_mc03_mmi; - c->avg_h264_qpel_pixels_tab[2][13] = ff_avg_h264_qpel4_mc13_mmi; - c->avg_h264_qpel_pixels_tab[2][14] = ff_avg_h264_qpel4_mc23_mmi; - c->avg_h264_qpel_pixels_tab[2][15] = ff_avg_h264_qpel4_mc33_mmi; - } -} -#endif /* HAVE_MMI */ - av_cold void ff_h264qpel_init_mips(H264QpelContext *c, int bit_depth) { -#if HAVE_MMI - h264qpel_init_mmi(c, bit_depth); -#endif /* HAVE_MMI */ -#if HAVE_MSA - h264qpel_init_msa(c, bit_depth); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + if (bit_depth == 8) { + c->put_h264_qpel_pixels_tab[0][0] = ff_put_h264_qpel16_mc00_mmi; + c->put_h264_qpel_pixels_tab[0][1] = ff_put_h264_qpel16_mc10_mmi; + c->put_h264_qpel_pixels_tab[0][2] = ff_put_h264_qpel16_mc20_mmi; + c->put_h264_qpel_pixels_tab[0][3] = ff_put_h264_qpel16_mc30_mmi; + c->put_h264_qpel_pixels_tab[0][4] = ff_put_h264_qpel16_mc01_mmi; + c->put_h264_qpel_pixels_tab[0][5] = ff_put_h264_qpel16_mc11_mmi; + c->put_h264_qpel_pixels_tab[0][6] = ff_put_h264_qpel16_mc21_mmi; + c->put_h264_qpel_pixels_tab[0][7] = ff_put_h264_qpel16_mc31_mmi; + c->put_h264_qpel_pixels_tab[0][8] = ff_put_h264_qpel16_mc02_mmi; + c->put_h264_qpel_pixels_tab[0][9] = ff_put_h264_qpel16_mc12_mmi; + c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_mmi; + c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_mmi; + c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_mmi; + c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_mmi; + c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_mmi; + c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_mmi; + + c->put_h264_qpel_pixels_tab[1][0] = ff_put_h264_qpel8_mc00_mmi; + c->put_h264_qpel_pixels_tab[1][1] = ff_put_h264_qpel8_mc10_mmi; + c->put_h264_qpel_pixels_tab[1][2] = ff_put_h264_qpel8_mc20_mmi; + c->put_h264_qpel_pixels_tab[1][3] = ff_put_h264_qpel8_mc30_mmi; + c->put_h264_qpel_pixels_tab[1][4] = ff_put_h264_qpel8_mc01_mmi; + c->put_h264_qpel_pixels_tab[1][5] = ff_put_h264_qpel8_mc11_mmi; + c->put_h264_qpel_pixels_tab[1][6] = ff_put_h264_qpel8_mc21_mmi; + c->put_h264_qpel_pixels_tab[1][7] = ff_put_h264_qpel8_mc31_mmi; + c->put_h264_qpel_pixels_tab[1][8] = ff_put_h264_qpel8_mc02_mmi; + c->put_h264_qpel_pixels_tab[1][9] = ff_put_h264_qpel8_mc12_mmi; + c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_mmi; + c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_mmi; + c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_mmi; + c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_mmi; + c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_mmi; + c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_mmi; + + c->put_h264_qpel_pixels_tab[2][0] = ff_put_h264_qpel4_mc00_mmi; + c->put_h264_qpel_pixels_tab[2][1] = ff_put_h264_qpel4_mc10_mmi; + c->put_h264_qpel_pixels_tab[2][2] = ff_put_h264_qpel4_mc20_mmi; + c->put_h264_qpel_pixels_tab[2][3] = ff_put_h264_qpel4_mc30_mmi; + c->put_h264_qpel_pixels_tab[2][4] = ff_put_h264_qpel4_mc01_mmi; + c->put_h264_qpel_pixels_tab[2][5] = ff_put_h264_qpel4_mc11_mmi; + c->put_h264_qpel_pixels_tab[2][6] = ff_put_h264_qpel4_mc21_mmi; + c->put_h264_qpel_pixels_tab[2][7] = ff_put_h264_qpel4_mc31_mmi; + c->put_h264_qpel_pixels_tab[2][8] = ff_put_h264_qpel4_mc02_mmi; + c->put_h264_qpel_pixels_tab[2][9] = ff_put_h264_qpel4_mc12_mmi; + c->put_h264_qpel_pixels_tab[2][10] = ff_put_h264_qpel4_mc22_mmi; + c->put_h264_qpel_pixels_tab[2][11] = ff_put_h264_qpel4_mc32_mmi; + c->put_h264_qpel_pixels_tab[2][12] = ff_put_h264_qpel4_mc03_mmi; + c->put_h264_qpel_pixels_tab[2][13] = ff_put_h264_qpel4_mc13_mmi; + c->put_h264_qpel_pixels_tab[2][14] = ff_put_h264_qpel4_mc23_mmi; + c->put_h264_qpel_pixels_tab[2][15] = ff_put_h264_qpel4_mc33_mmi; + + c->avg_h264_qpel_pixels_tab[0][0] = ff_avg_h264_qpel16_mc00_mmi; + c->avg_h264_qpel_pixels_tab[0][1] = ff_avg_h264_qpel16_mc10_mmi; + c->avg_h264_qpel_pixels_tab[0][2] = ff_avg_h264_qpel16_mc20_mmi; + c->avg_h264_qpel_pixels_tab[0][3] = ff_avg_h264_qpel16_mc30_mmi; + c->avg_h264_qpel_pixels_tab[0][4] = ff_avg_h264_qpel16_mc01_mmi; + c->avg_h264_qpel_pixels_tab[0][5] = ff_avg_h264_qpel16_mc11_mmi; + c->avg_h264_qpel_pixels_tab[0][6] = ff_avg_h264_qpel16_mc21_mmi; + c->avg_h264_qpel_pixels_tab[0][7] = ff_avg_h264_qpel16_mc31_mmi; + c->avg_h264_qpel_pixels_tab[0][8] = ff_avg_h264_qpel16_mc02_mmi; + c->avg_h264_qpel_pixels_tab[0][9] = ff_avg_h264_qpel16_mc12_mmi; + c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_mmi; + c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_mmi; + c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_mmi; + c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_mmi; + c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_mmi; + c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_mmi; + + c->avg_h264_qpel_pixels_tab[1][0] = ff_avg_h264_qpel8_mc00_mmi; + c->avg_h264_qpel_pixels_tab[1][1] = ff_avg_h264_qpel8_mc10_mmi; + c->avg_h264_qpel_pixels_tab[1][2] = ff_avg_h264_qpel8_mc20_mmi; + c->avg_h264_qpel_pixels_tab[1][3] = ff_avg_h264_qpel8_mc30_mmi; + c->avg_h264_qpel_pixels_tab[1][4] = ff_avg_h264_qpel8_mc01_mmi; + c->avg_h264_qpel_pixels_tab[1][5] = ff_avg_h264_qpel8_mc11_mmi; + c->avg_h264_qpel_pixels_tab[1][6] = ff_avg_h264_qpel8_mc21_mmi; + c->avg_h264_qpel_pixels_tab[1][7] = ff_avg_h264_qpel8_mc31_mmi; + c->avg_h264_qpel_pixels_tab[1][8] = ff_avg_h264_qpel8_mc02_mmi; + c->avg_h264_qpel_pixels_tab[1][9] = ff_avg_h264_qpel8_mc12_mmi; + c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_mmi; + c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_mmi; + c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_mmi; + c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_mmi; + c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_mmi; + c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_mmi; + + c->avg_h264_qpel_pixels_tab[2][0] = ff_avg_h264_qpel4_mc00_mmi; + c->avg_h264_qpel_pixels_tab[2][1] = ff_avg_h264_qpel4_mc10_mmi; + c->avg_h264_qpel_pixels_tab[2][2] = ff_avg_h264_qpel4_mc20_mmi; + c->avg_h264_qpel_pixels_tab[2][3] = ff_avg_h264_qpel4_mc30_mmi; + c->avg_h264_qpel_pixels_tab[2][4] = ff_avg_h264_qpel4_mc01_mmi; + c->avg_h264_qpel_pixels_tab[2][5] = ff_avg_h264_qpel4_mc11_mmi; + c->avg_h264_qpel_pixels_tab[2][6] = ff_avg_h264_qpel4_mc21_mmi; + c->avg_h264_qpel_pixels_tab[2][7] = ff_avg_h264_qpel4_mc31_mmi; + c->avg_h264_qpel_pixels_tab[2][8] = ff_avg_h264_qpel4_mc02_mmi; + c->avg_h264_qpel_pixels_tab[2][9] = ff_avg_h264_qpel4_mc12_mmi; + c->avg_h264_qpel_pixels_tab[2][10] = ff_avg_h264_qpel4_mc22_mmi; + c->avg_h264_qpel_pixels_tab[2][11] = ff_avg_h264_qpel4_mc32_mmi; + c->avg_h264_qpel_pixels_tab[2][12] = ff_avg_h264_qpel4_mc03_mmi; + c->avg_h264_qpel_pixels_tab[2][13] = ff_avg_h264_qpel4_mc13_mmi; + c->avg_h264_qpel_pixels_tab[2][14] = ff_avg_h264_qpel4_mc23_mmi; + c->avg_h264_qpel_pixels_tab[2][15] = ff_avg_h264_qpel4_mc33_mmi; + } + } + + if (have_msa(cpu_flags)) { + if (bit_depth == 8) { + c->put_h264_qpel_pixels_tab[0][0] = ff_put_h264_qpel16_mc00_msa; + c->put_h264_qpel_pixels_tab[0][1] = ff_put_h264_qpel16_mc10_msa; + c->put_h264_qpel_pixels_tab[0][2] = ff_put_h264_qpel16_mc20_msa; + c->put_h264_qpel_pixels_tab[0][3] = ff_put_h264_qpel16_mc30_msa; + c->put_h264_qpel_pixels_tab[0][4] = ff_put_h264_qpel16_mc01_msa; + c->put_h264_qpel_pixels_tab[0][5] = ff_put_h264_qpel16_mc11_msa; + c->put_h264_qpel_pixels_tab[0][6] = ff_put_h264_qpel16_mc21_msa; + c->put_h264_qpel_pixels_tab[0][7] = ff_put_h264_qpel16_mc31_msa; + c->put_h264_qpel_pixels_tab[0][8] = ff_put_h264_qpel16_mc02_msa; + c->put_h264_qpel_pixels_tab[0][9] = ff_put_h264_qpel16_mc12_msa; + c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_msa; + c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_msa; + c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_msa; + c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_msa; + c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_msa; + c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_msa; + + c->put_h264_qpel_pixels_tab[1][0] = ff_put_h264_qpel8_mc00_msa; + c->put_h264_qpel_pixels_tab[1][1] = ff_put_h264_qpel8_mc10_msa; + c->put_h264_qpel_pixels_tab[1][2] = ff_put_h264_qpel8_mc20_msa; + c->put_h264_qpel_pixels_tab[1][3] = ff_put_h264_qpel8_mc30_msa; + c->put_h264_qpel_pixels_tab[1][4] = ff_put_h264_qpel8_mc01_msa; + c->put_h264_qpel_pixels_tab[1][5] = ff_put_h264_qpel8_mc11_msa; + c->put_h264_qpel_pixels_tab[1][6] = ff_put_h264_qpel8_mc21_msa; + c->put_h264_qpel_pixels_tab[1][7] = ff_put_h264_qpel8_mc31_msa; + c->put_h264_qpel_pixels_tab[1][8] = ff_put_h264_qpel8_mc02_msa; + c->put_h264_qpel_pixels_tab[1][9] = ff_put_h264_qpel8_mc12_msa; + c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_msa; + c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_msa; + c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_msa; + c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_msa; + c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_msa; + c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_msa; + + c->put_h264_qpel_pixels_tab[2][1] = ff_put_h264_qpel4_mc10_msa; + c->put_h264_qpel_pixels_tab[2][2] = ff_put_h264_qpel4_mc20_msa; + c->put_h264_qpel_pixels_tab[2][3] = ff_put_h264_qpel4_mc30_msa; + c->put_h264_qpel_pixels_tab[2][4] = ff_put_h264_qpel4_mc01_msa; + c->put_h264_qpel_pixels_tab[2][5] = ff_put_h264_qpel4_mc11_msa; + c->put_h264_qpel_pixels_tab[2][6] = ff_put_h264_qpel4_mc21_msa; + c->put_h264_qpel_pixels_tab[2][7] = ff_put_h264_qpel4_mc31_msa; + c->put_h264_qpel_pixels_tab[2][8] = ff_put_h264_qpel4_mc02_msa; + c->put_h264_qpel_pixels_tab[2][9] = ff_put_h264_qpel4_mc12_msa; + c->put_h264_qpel_pixels_tab[2][10] = ff_put_h264_qpel4_mc22_msa; + c->put_h264_qpel_pixels_tab[2][11] = ff_put_h264_qpel4_mc32_msa; + c->put_h264_qpel_pixels_tab[2][12] = ff_put_h264_qpel4_mc03_msa; + c->put_h264_qpel_pixels_tab[2][13] = ff_put_h264_qpel4_mc13_msa; + c->put_h264_qpel_pixels_tab[2][14] = ff_put_h264_qpel4_mc23_msa; + c->put_h264_qpel_pixels_tab[2][15] = ff_put_h264_qpel4_mc33_msa; + + c->avg_h264_qpel_pixels_tab[0][0] = ff_avg_h264_qpel16_mc00_msa; + c->avg_h264_qpel_pixels_tab[0][1] = ff_avg_h264_qpel16_mc10_msa; + c->avg_h264_qpel_pixels_tab[0][2] = ff_avg_h264_qpel16_mc20_msa; + c->avg_h264_qpel_pixels_tab[0][3] = ff_avg_h264_qpel16_mc30_msa; + c->avg_h264_qpel_pixels_tab[0][4] = ff_avg_h264_qpel16_mc01_msa; + c->avg_h264_qpel_pixels_tab[0][5] = ff_avg_h264_qpel16_mc11_msa; + c->avg_h264_qpel_pixels_tab[0][6] = ff_avg_h264_qpel16_mc21_msa; + c->avg_h264_qpel_pixels_tab[0][7] = ff_avg_h264_qpel16_mc31_msa; + c->avg_h264_qpel_pixels_tab[0][8] = ff_avg_h264_qpel16_mc02_msa; + c->avg_h264_qpel_pixels_tab[0][9] = ff_avg_h264_qpel16_mc12_msa; + c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_msa; + c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_msa; + c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_msa; + c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_msa; + c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_msa; + c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_msa; + + c->avg_h264_qpel_pixels_tab[1][0] = ff_avg_h264_qpel8_mc00_msa; + c->avg_h264_qpel_pixels_tab[1][1] = ff_avg_h264_qpel8_mc10_msa; + c->avg_h264_qpel_pixels_tab[1][2] = ff_avg_h264_qpel8_mc20_msa; + c->avg_h264_qpel_pixels_tab[1][3] = ff_avg_h264_qpel8_mc30_msa; + c->avg_h264_qpel_pixels_tab[1][4] = ff_avg_h264_qpel8_mc01_msa; + c->avg_h264_qpel_pixels_tab[1][5] = ff_avg_h264_qpel8_mc11_msa; + c->avg_h264_qpel_pixels_tab[1][6] = ff_avg_h264_qpel8_mc21_msa; + c->avg_h264_qpel_pixels_tab[1][7] = ff_avg_h264_qpel8_mc31_msa; + c->avg_h264_qpel_pixels_tab[1][8] = ff_avg_h264_qpel8_mc02_msa; + c->avg_h264_qpel_pixels_tab[1][9] = ff_avg_h264_qpel8_mc12_msa; + c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_msa; + c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_msa; + c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_msa; + c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_msa; + c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_msa; + c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_msa; + + c->avg_h264_qpel_pixels_tab[2][0] = ff_avg_h264_qpel4_mc00_msa; + c->avg_h264_qpel_pixels_tab[2][1] = ff_avg_h264_qpel4_mc10_msa; + c->avg_h264_qpel_pixels_tab[2][2] = ff_avg_h264_qpel4_mc20_msa; + c->avg_h264_qpel_pixels_tab[2][3] = ff_avg_h264_qpel4_mc30_msa; + c->avg_h264_qpel_pixels_tab[2][4] = ff_avg_h264_qpel4_mc01_msa; + c->avg_h264_qpel_pixels_tab[2][5] = ff_avg_h264_qpel4_mc11_msa; + c->avg_h264_qpel_pixels_tab[2][6] = ff_avg_h264_qpel4_mc21_msa; + c->avg_h264_qpel_pixels_tab[2][7] = ff_avg_h264_qpel4_mc31_msa; + c->avg_h264_qpel_pixels_tab[2][8] = ff_avg_h264_qpel4_mc02_msa; + c->avg_h264_qpel_pixels_tab[2][9] = ff_avg_h264_qpel4_mc12_msa; + c->avg_h264_qpel_pixels_tab[2][10] = ff_avg_h264_qpel4_mc22_msa; + c->avg_h264_qpel_pixels_tab[2][11] = ff_avg_h264_qpel4_mc32_msa; + c->avg_h264_qpel_pixels_tab[2][12] = ff_avg_h264_qpel4_mc03_msa; + c->avg_h264_qpel_pixels_tab[2][13] = ff_avg_h264_qpel4_mc13_msa; + c->avg_h264_qpel_pixels_tab[2][14] = ff_avg_h264_qpel4_mc23_msa; + c->avg_h264_qpel_pixels_tab[2][15] = ff_avg_h264_qpel4_mc33_msa; + } + } } diff --git a/libavcodec/mips/hevcdsp_init_mips.c b/libavcodec/mips/hevcdsp_init_mips.c index 88337f462..eb261e5ad 100644 --- a/libavcodec/mips/hevcdsp_init_mips.c +++ b/libavcodec/mips/hevcdsp_init_mips.c @@ -18,512 +18,500 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "libavcodec/mips/hevcdsp_mips.h" -#if HAVE_MMI -static av_cold void hevc_dsp_init_mmi(HEVCDSPContext *c, - const int bit_depth) -{ - if (8 == bit_depth) { - c->put_hevc_qpel[1][0][1] = ff_hevc_put_hevc_qpel_h4_8_mmi; - c->put_hevc_qpel[3][0][1] = ff_hevc_put_hevc_qpel_h8_8_mmi; - c->put_hevc_qpel[4][0][1] = ff_hevc_put_hevc_qpel_h12_8_mmi; - c->put_hevc_qpel[5][0][1] = ff_hevc_put_hevc_qpel_h16_8_mmi; - c->put_hevc_qpel[6][0][1] = ff_hevc_put_hevc_qpel_h24_8_mmi; - c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_8_mmi; - c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_8_mmi; - c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_8_mmi; - - c->put_hevc_qpel[1][1][1] = ff_hevc_put_hevc_qpel_hv4_8_mmi; - c->put_hevc_qpel[3][1][1] = ff_hevc_put_hevc_qpel_hv8_8_mmi; - c->put_hevc_qpel[4][1][1] = ff_hevc_put_hevc_qpel_hv12_8_mmi; - c->put_hevc_qpel[5][1][1] = ff_hevc_put_hevc_qpel_hv16_8_mmi; - c->put_hevc_qpel[6][1][1] = ff_hevc_put_hevc_qpel_hv24_8_mmi; - c->put_hevc_qpel[7][1][1] = ff_hevc_put_hevc_qpel_hv32_8_mmi; - c->put_hevc_qpel[8][1][1] = ff_hevc_put_hevc_qpel_hv48_8_mmi; - c->put_hevc_qpel[9][1][1] = ff_hevc_put_hevc_qpel_hv64_8_mmi; - - c->put_hevc_qpel_bi[1][0][1] = ff_hevc_put_hevc_qpel_bi_h4_8_mmi; - c->put_hevc_qpel_bi[3][0][1] = ff_hevc_put_hevc_qpel_bi_h8_8_mmi; - c->put_hevc_qpel_bi[4][0][1] = ff_hevc_put_hevc_qpel_bi_h12_8_mmi; - c->put_hevc_qpel_bi[5][0][1] = ff_hevc_put_hevc_qpel_bi_h16_8_mmi; - c->put_hevc_qpel_bi[6][0][1] = ff_hevc_put_hevc_qpel_bi_h24_8_mmi; - c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_qpel_bi_h32_8_mmi; - c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_qpel_bi_h48_8_mmi; - c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_qpel_bi_h64_8_mmi; - - c->put_hevc_qpel_bi[1][1][1] = ff_hevc_put_hevc_qpel_bi_hv4_8_mmi; - c->put_hevc_qpel_bi[3][1][1] = ff_hevc_put_hevc_qpel_bi_hv8_8_mmi; - c->put_hevc_qpel_bi[4][1][1] = ff_hevc_put_hevc_qpel_bi_hv12_8_mmi; - c->put_hevc_qpel_bi[5][1][1] = ff_hevc_put_hevc_qpel_bi_hv16_8_mmi; - c->put_hevc_qpel_bi[6][1][1] = ff_hevc_put_hevc_qpel_bi_hv24_8_mmi; - c->put_hevc_qpel_bi[7][1][1] = ff_hevc_put_hevc_qpel_bi_hv32_8_mmi; - c->put_hevc_qpel_bi[8][1][1] = ff_hevc_put_hevc_qpel_bi_hv48_8_mmi; - c->put_hevc_qpel_bi[9][1][1] = ff_hevc_put_hevc_qpel_bi_hv64_8_mmi; - - c->put_hevc_qpel_bi[3][0][0] = ff_hevc_put_hevc_pel_bi_pixels8_8_mmi; - c->put_hevc_qpel_bi[5][0][0] = ff_hevc_put_hevc_pel_bi_pixels16_8_mmi; - c->put_hevc_qpel_bi[6][0][0] = ff_hevc_put_hevc_pel_bi_pixels24_8_mmi; - c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_pel_bi_pixels32_8_mmi; - c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_pel_bi_pixels48_8_mmi; - c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_pel_bi_pixels64_8_mmi; - - c->put_hevc_epel_bi[3][0][0] = ff_hevc_put_hevc_pel_bi_pixels8_8_mmi; - c->put_hevc_epel_bi[5][0][0] = ff_hevc_put_hevc_pel_bi_pixels16_8_mmi; - c->put_hevc_epel_bi[6][0][0] = ff_hevc_put_hevc_pel_bi_pixels24_8_mmi; - c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_pel_bi_pixels32_8_mmi; - - c->put_hevc_epel_bi[1][1][1] = ff_hevc_put_hevc_epel_bi_hv4_8_mmi; - c->put_hevc_epel_bi[3][1][1] = ff_hevc_put_hevc_epel_bi_hv8_8_mmi; - c->put_hevc_epel_bi[4][1][1] = ff_hevc_put_hevc_epel_bi_hv12_8_mmi; - c->put_hevc_epel_bi[5][1][1] = ff_hevc_put_hevc_epel_bi_hv16_8_mmi; - c->put_hevc_epel_bi[6][1][1] = ff_hevc_put_hevc_epel_bi_hv24_8_mmi; - c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_epel_bi_hv32_8_mmi; - - c->put_hevc_qpel_uni[1][1][1] = ff_hevc_put_hevc_qpel_uni_hv4_8_mmi; - c->put_hevc_qpel_uni[3][1][1] = ff_hevc_put_hevc_qpel_uni_hv8_8_mmi; - c->put_hevc_qpel_uni[4][1][1] = ff_hevc_put_hevc_qpel_uni_hv12_8_mmi; - c->put_hevc_qpel_uni[5][1][1] = ff_hevc_put_hevc_qpel_uni_hv16_8_mmi; - c->put_hevc_qpel_uni[6][1][1] = ff_hevc_put_hevc_qpel_uni_hv24_8_mmi; - c->put_hevc_qpel_uni[7][1][1] = ff_hevc_put_hevc_qpel_uni_hv32_8_mmi; - c->put_hevc_qpel_uni[8][1][1] = ff_hevc_put_hevc_qpel_uni_hv48_8_mmi; - c->put_hevc_qpel_uni[9][1][1] = ff_hevc_put_hevc_qpel_uni_hv64_8_mmi; - } -} -#endif // #if HAVE_MMI - -#if HAVE_MSA -static av_cold void hevc_dsp_init_msa(HEVCDSPContext *c, - const int bit_depth) -{ - if (8 == bit_depth) { - c->put_hevc_qpel[1][0][0] = ff_hevc_put_hevc_pel_pixels4_8_msa; - c->put_hevc_qpel[2][0][0] = ff_hevc_put_hevc_pel_pixels6_8_msa; - c->put_hevc_qpel[3][0][0] = ff_hevc_put_hevc_pel_pixels8_8_msa; - c->put_hevc_qpel[4][0][0] = ff_hevc_put_hevc_pel_pixels12_8_msa; - c->put_hevc_qpel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_8_msa; - c->put_hevc_qpel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_8_msa; - c->put_hevc_qpel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_msa; - c->put_hevc_qpel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_8_msa; - c->put_hevc_qpel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_8_msa; - - c->put_hevc_qpel[1][0][1] = ff_hevc_put_hevc_qpel_h4_8_msa; - c->put_hevc_qpel[3][0][1] = ff_hevc_put_hevc_qpel_h8_8_msa; - c->put_hevc_qpel[4][0][1] = ff_hevc_put_hevc_qpel_h12_8_msa; - c->put_hevc_qpel[5][0][1] = ff_hevc_put_hevc_qpel_h16_8_msa; - c->put_hevc_qpel[6][0][1] = ff_hevc_put_hevc_qpel_h24_8_msa; - c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_8_msa; - c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_8_msa; - c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_8_msa; - - c->put_hevc_qpel[1][1][0] = ff_hevc_put_hevc_qpel_v4_8_msa; - c->put_hevc_qpel[3][1][0] = ff_hevc_put_hevc_qpel_v8_8_msa; - c->put_hevc_qpel[4][1][0] = ff_hevc_put_hevc_qpel_v12_8_msa; - c->put_hevc_qpel[5][1][0] = ff_hevc_put_hevc_qpel_v16_8_msa; - c->put_hevc_qpel[6][1][0] = ff_hevc_put_hevc_qpel_v24_8_msa; - c->put_hevc_qpel[7][1][0] = ff_hevc_put_hevc_qpel_v32_8_msa; - c->put_hevc_qpel[8][1][0] = ff_hevc_put_hevc_qpel_v48_8_msa; - c->put_hevc_qpel[9][1][0] = ff_hevc_put_hevc_qpel_v64_8_msa; - - c->put_hevc_qpel[1][1][1] = ff_hevc_put_hevc_qpel_hv4_8_msa; - c->put_hevc_qpel[3][1][1] = ff_hevc_put_hevc_qpel_hv8_8_msa; - c->put_hevc_qpel[4][1][1] = ff_hevc_put_hevc_qpel_hv12_8_msa; - c->put_hevc_qpel[5][1][1] = ff_hevc_put_hevc_qpel_hv16_8_msa; - c->put_hevc_qpel[6][1][1] = ff_hevc_put_hevc_qpel_hv24_8_msa; - c->put_hevc_qpel[7][1][1] = ff_hevc_put_hevc_qpel_hv32_8_msa; - c->put_hevc_qpel[8][1][1] = ff_hevc_put_hevc_qpel_hv48_8_msa; - c->put_hevc_qpel[9][1][1] = ff_hevc_put_hevc_qpel_hv64_8_msa; - - c->put_hevc_epel[1][0][0] = ff_hevc_put_hevc_pel_pixels4_8_msa; - c->put_hevc_epel[2][0][0] = ff_hevc_put_hevc_pel_pixels6_8_msa; - c->put_hevc_epel[3][0][0] = ff_hevc_put_hevc_pel_pixels8_8_msa; - c->put_hevc_epel[4][0][0] = ff_hevc_put_hevc_pel_pixels12_8_msa; - c->put_hevc_epel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_8_msa; - c->put_hevc_epel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_8_msa; - c->put_hevc_epel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_msa; - - c->put_hevc_epel[1][0][1] = ff_hevc_put_hevc_epel_h4_8_msa; - c->put_hevc_epel[2][0][1] = ff_hevc_put_hevc_epel_h6_8_msa; - c->put_hevc_epel[3][0][1] = ff_hevc_put_hevc_epel_h8_8_msa; - c->put_hevc_epel[4][0][1] = ff_hevc_put_hevc_epel_h12_8_msa; - c->put_hevc_epel[5][0][1] = ff_hevc_put_hevc_epel_h16_8_msa; - c->put_hevc_epel[6][0][1] = ff_hevc_put_hevc_epel_h24_8_msa; - c->put_hevc_epel[7][0][1] = ff_hevc_put_hevc_epel_h32_8_msa; - - c->put_hevc_epel[1][1][0] = ff_hevc_put_hevc_epel_v4_8_msa; - c->put_hevc_epel[2][1][0] = ff_hevc_put_hevc_epel_v6_8_msa; - c->put_hevc_epel[3][1][0] = ff_hevc_put_hevc_epel_v8_8_msa; - c->put_hevc_epel[4][1][0] = ff_hevc_put_hevc_epel_v12_8_msa; - c->put_hevc_epel[5][1][0] = ff_hevc_put_hevc_epel_v16_8_msa; - c->put_hevc_epel[6][1][0] = ff_hevc_put_hevc_epel_v24_8_msa; - c->put_hevc_epel[7][1][0] = ff_hevc_put_hevc_epel_v32_8_msa; - - c->put_hevc_epel[1][1][1] = ff_hevc_put_hevc_epel_hv4_8_msa; - c->put_hevc_epel[2][1][1] = ff_hevc_put_hevc_epel_hv6_8_msa; - c->put_hevc_epel[3][1][1] = ff_hevc_put_hevc_epel_hv8_8_msa; - c->put_hevc_epel[4][1][1] = ff_hevc_put_hevc_epel_hv12_8_msa; - c->put_hevc_epel[5][1][1] = ff_hevc_put_hevc_epel_hv16_8_msa; - c->put_hevc_epel[6][1][1] = ff_hevc_put_hevc_epel_hv24_8_msa; - c->put_hevc_epel[7][1][1] = ff_hevc_put_hevc_epel_hv32_8_msa; - - c->put_hevc_qpel_uni[3][0][0] = ff_hevc_put_hevc_uni_pel_pixels8_8_msa; - c->put_hevc_qpel_uni[4][0][0] = ff_hevc_put_hevc_uni_pel_pixels12_8_msa; - c->put_hevc_qpel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels16_8_msa; - c->put_hevc_qpel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels24_8_msa; - c->put_hevc_qpel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_msa; - c->put_hevc_qpel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_msa; - c->put_hevc_qpel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_msa; - - c->put_hevc_qpel_uni[1][0][1] = ff_hevc_put_hevc_uni_qpel_h4_8_msa; - c->put_hevc_qpel_uni[3][0][1] = ff_hevc_put_hevc_uni_qpel_h8_8_msa; - c->put_hevc_qpel_uni[4][0][1] = ff_hevc_put_hevc_uni_qpel_h12_8_msa; - c->put_hevc_qpel_uni[5][0][1] = ff_hevc_put_hevc_uni_qpel_h16_8_msa; - c->put_hevc_qpel_uni[6][0][1] = ff_hevc_put_hevc_uni_qpel_h24_8_msa; - c->put_hevc_qpel_uni[7][0][1] = ff_hevc_put_hevc_uni_qpel_h32_8_msa; - c->put_hevc_qpel_uni[8][0][1] = ff_hevc_put_hevc_uni_qpel_h48_8_msa; - c->put_hevc_qpel_uni[9][0][1] = ff_hevc_put_hevc_uni_qpel_h64_8_msa; - - c->put_hevc_qpel_uni[1][1][0] = ff_hevc_put_hevc_uni_qpel_v4_8_msa; - c->put_hevc_qpel_uni[3][1][0] = ff_hevc_put_hevc_uni_qpel_v8_8_msa; - c->put_hevc_qpel_uni[4][1][0] = ff_hevc_put_hevc_uni_qpel_v12_8_msa; - c->put_hevc_qpel_uni[5][1][0] = ff_hevc_put_hevc_uni_qpel_v16_8_msa; - c->put_hevc_qpel_uni[6][1][0] = ff_hevc_put_hevc_uni_qpel_v24_8_msa; - c->put_hevc_qpel_uni[7][1][0] = ff_hevc_put_hevc_uni_qpel_v32_8_msa; - c->put_hevc_qpel_uni[8][1][0] = ff_hevc_put_hevc_uni_qpel_v48_8_msa; - c->put_hevc_qpel_uni[9][1][0] = ff_hevc_put_hevc_uni_qpel_v64_8_msa; - - c->put_hevc_qpel_uni[1][1][1] = ff_hevc_put_hevc_uni_qpel_hv4_8_msa; - c->put_hevc_qpel_uni[3][1][1] = ff_hevc_put_hevc_uni_qpel_hv8_8_msa; - c->put_hevc_qpel_uni[4][1][1] = ff_hevc_put_hevc_uni_qpel_hv12_8_msa; - c->put_hevc_qpel_uni[5][1][1] = ff_hevc_put_hevc_uni_qpel_hv16_8_msa; - c->put_hevc_qpel_uni[6][1][1] = ff_hevc_put_hevc_uni_qpel_hv24_8_msa; - c->put_hevc_qpel_uni[7][1][1] = ff_hevc_put_hevc_uni_qpel_hv32_8_msa; - c->put_hevc_qpel_uni[8][1][1] = ff_hevc_put_hevc_uni_qpel_hv48_8_msa; - c->put_hevc_qpel_uni[9][1][1] = ff_hevc_put_hevc_uni_qpel_hv64_8_msa; - - c->put_hevc_epel_uni[3][0][0] = ff_hevc_put_hevc_uni_pel_pixels8_8_msa; - c->put_hevc_epel_uni[4][0][0] = ff_hevc_put_hevc_uni_pel_pixels12_8_msa; - c->put_hevc_epel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels16_8_msa; - c->put_hevc_epel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels24_8_msa; - c->put_hevc_epel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_msa; - - c->put_hevc_epel_uni[1][0][1] = ff_hevc_put_hevc_uni_epel_h4_8_msa; - c->put_hevc_epel_uni[2][0][1] = ff_hevc_put_hevc_uni_epel_h6_8_msa; - c->put_hevc_epel_uni[3][0][1] = ff_hevc_put_hevc_uni_epel_h8_8_msa; - c->put_hevc_epel_uni[4][0][1] = ff_hevc_put_hevc_uni_epel_h12_8_msa; - c->put_hevc_epel_uni[5][0][1] = ff_hevc_put_hevc_uni_epel_h16_8_msa; - c->put_hevc_epel_uni[6][0][1] = ff_hevc_put_hevc_uni_epel_h24_8_msa; - c->put_hevc_epel_uni[7][0][1] = ff_hevc_put_hevc_uni_epel_h32_8_msa; - - c->put_hevc_epel_uni[1][1][0] = ff_hevc_put_hevc_uni_epel_v4_8_msa; - c->put_hevc_epel_uni[2][1][0] = ff_hevc_put_hevc_uni_epel_v6_8_msa; - c->put_hevc_epel_uni[3][1][0] = ff_hevc_put_hevc_uni_epel_v8_8_msa; - c->put_hevc_epel_uni[4][1][0] = ff_hevc_put_hevc_uni_epel_v12_8_msa; - c->put_hevc_epel_uni[5][1][0] = ff_hevc_put_hevc_uni_epel_v16_8_msa; - c->put_hevc_epel_uni[6][1][0] = ff_hevc_put_hevc_uni_epel_v24_8_msa; - c->put_hevc_epel_uni[7][1][0] = ff_hevc_put_hevc_uni_epel_v32_8_msa; - - c->put_hevc_epel_uni[1][1][1] = ff_hevc_put_hevc_uni_epel_hv4_8_msa; - c->put_hevc_epel_uni[2][1][1] = ff_hevc_put_hevc_uni_epel_hv6_8_msa; - c->put_hevc_epel_uni[3][1][1] = ff_hevc_put_hevc_uni_epel_hv8_8_msa; - c->put_hevc_epel_uni[4][1][1] = ff_hevc_put_hevc_uni_epel_hv12_8_msa; - c->put_hevc_epel_uni[5][1][1] = ff_hevc_put_hevc_uni_epel_hv16_8_msa; - c->put_hevc_epel_uni[6][1][1] = ff_hevc_put_hevc_uni_epel_hv24_8_msa; - c->put_hevc_epel_uni[7][1][1] = ff_hevc_put_hevc_uni_epel_hv32_8_msa; - - c->put_hevc_qpel_uni_w[1][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels4_8_msa; - c->put_hevc_qpel_uni_w[3][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels8_8_msa; - c->put_hevc_qpel_uni_w[4][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels12_8_msa; - c->put_hevc_qpel_uni_w[5][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels16_8_msa; - c->put_hevc_qpel_uni_w[6][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels24_8_msa; - c->put_hevc_qpel_uni_w[7][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels32_8_msa; - c->put_hevc_qpel_uni_w[8][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels48_8_msa; - c->put_hevc_qpel_uni_w[9][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels64_8_msa; - - c->put_hevc_qpel_uni_w[1][0][1] = ff_hevc_put_hevc_uni_w_qpel_h4_8_msa; - c->put_hevc_qpel_uni_w[3][0][1] = ff_hevc_put_hevc_uni_w_qpel_h8_8_msa; - c->put_hevc_qpel_uni_w[4][0][1] = ff_hevc_put_hevc_uni_w_qpel_h12_8_msa; - c->put_hevc_qpel_uni_w[5][0][1] = ff_hevc_put_hevc_uni_w_qpel_h16_8_msa; - c->put_hevc_qpel_uni_w[6][0][1] = ff_hevc_put_hevc_uni_w_qpel_h24_8_msa; - c->put_hevc_qpel_uni_w[7][0][1] = ff_hevc_put_hevc_uni_w_qpel_h32_8_msa; - c->put_hevc_qpel_uni_w[8][0][1] = ff_hevc_put_hevc_uni_w_qpel_h48_8_msa; - c->put_hevc_qpel_uni_w[9][0][1] = ff_hevc_put_hevc_uni_w_qpel_h64_8_msa; - - c->put_hevc_qpel_uni_w[1][1][0] = ff_hevc_put_hevc_uni_w_qpel_v4_8_msa; - c->put_hevc_qpel_uni_w[3][1][0] = ff_hevc_put_hevc_uni_w_qpel_v8_8_msa; - c->put_hevc_qpel_uni_w[4][1][0] = ff_hevc_put_hevc_uni_w_qpel_v12_8_msa; - c->put_hevc_qpel_uni_w[5][1][0] = ff_hevc_put_hevc_uni_w_qpel_v16_8_msa; - c->put_hevc_qpel_uni_w[6][1][0] = ff_hevc_put_hevc_uni_w_qpel_v24_8_msa; - c->put_hevc_qpel_uni_w[7][1][0] = ff_hevc_put_hevc_uni_w_qpel_v32_8_msa; - c->put_hevc_qpel_uni_w[8][1][0] = ff_hevc_put_hevc_uni_w_qpel_v48_8_msa; - c->put_hevc_qpel_uni_w[9][1][0] = ff_hevc_put_hevc_uni_w_qpel_v64_8_msa; - - c->put_hevc_qpel_uni_w[1][1][1] = ff_hevc_put_hevc_uni_w_qpel_hv4_8_msa; - c->put_hevc_qpel_uni_w[3][1][1] = ff_hevc_put_hevc_uni_w_qpel_hv8_8_msa; - c->put_hevc_qpel_uni_w[4][1][1] = - ff_hevc_put_hevc_uni_w_qpel_hv12_8_msa; - c->put_hevc_qpel_uni_w[5][1][1] = - ff_hevc_put_hevc_uni_w_qpel_hv16_8_msa; - c->put_hevc_qpel_uni_w[6][1][1] = - ff_hevc_put_hevc_uni_w_qpel_hv24_8_msa; - c->put_hevc_qpel_uni_w[7][1][1] = - ff_hevc_put_hevc_uni_w_qpel_hv32_8_msa; - c->put_hevc_qpel_uni_w[8][1][1] = - ff_hevc_put_hevc_uni_w_qpel_hv48_8_msa; - c->put_hevc_qpel_uni_w[9][1][1] = - ff_hevc_put_hevc_uni_w_qpel_hv64_8_msa; - - c->put_hevc_epel_uni_w[1][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels4_8_msa; - c->put_hevc_epel_uni_w[2][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels6_8_msa; - c->put_hevc_epel_uni_w[3][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels8_8_msa; - c->put_hevc_epel_uni_w[4][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels12_8_msa; - c->put_hevc_epel_uni_w[5][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels16_8_msa; - c->put_hevc_epel_uni_w[6][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels24_8_msa; - c->put_hevc_epel_uni_w[7][0][0] = - ff_hevc_put_hevc_uni_w_pel_pixels32_8_msa; - - c->put_hevc_epel_uni_w[1][0][1] = ff_hevc_put_hevc_uni_w_epel_h4_8_msa; - c->put_hevc_epel_uni_w[2][0][1] = ff_hevc_put_hevc_uni_w_epel_h6_8_msa; - c->put_hevc_epel_uni_w[3][0][1] = ff_hevc_put_hevc_uni_w_epel_h8_8_msa; - c->put_hevc_epel_uni_w[4][0][1] = ff_hevc_put_hevc_uni_w_epel_h12_8_msa; - c->put_hevc_epel_uni_w[5][0][1] = ff_hevc_put_hevc_uni_w_epel_h16_8_msa; - c->put_hevc_epel_uni_w[6][0][1] = ff_hevc_put_hevc_uni_w_epel_h24_8_msa; - c->put_hevc_epel_uni_w[7][0][1] = ff_hevc_put_hevc_uni_w_epel_h32_8_msa; - - c->put_hevc_epel_uni_w[1][1][0] = ff_hevc_put_hevc_uni_w_epel_v4_8_msa; - c->put_hevc_epel_uni_w[2][1][0] = ff_hevc_put_hevc_uni_w_epel_v6_8_msa; - c->put_hevc_epel_uni_w[3][1][0] = ff_hevc_put_hevc_uni_w_epel_v8_8_msa; - c->put_hevc_epel_uni_w[4][1][0] = ff_hevc_put_hevc_uni_w_epel_v12_8_msa; - c->put_hevc_epel_uni_w[5][1][0] = ff_hevc_put_hevc_uni_w_epel_v16_8_msa; - c->put_hevc_epel_uni_w[6][1][0] = ff_hevc_put_hevc_uni_w_epel_v24_8_msa; - c->put_hevc_epel_uni_w[7][1][0] = ff_hevc_put_hevc_uni_w_epel_v32_8_msa; - - c->put_hevc_epel_uni_w[1][1][1] = ff_hevc_put_hevc_uni_w_epel_hv4_8_msa; - c->put_hevc_epel_uni_w[2][1][1] = ff_hevc_put_hevc_uni_w_epel_hv6_8_msa; - c->put_hevc_epel_uni_w[3][1][1] = ff_hevc_put_hevc_uni_w_epel_hv8_8_msa; - c->put_hevc_epel_uni_w[4][1][1] = - ff_hevc_put_hevc_uni_w_epel_hv12_8_msa; - c->put_hevc_epel_uni_w[5][1][1] = - ff_hevc_put_hevc_uni_w_epel_hv16_8_msa; - c->put_hevc_epel_uni_w[6][1][1] = - ff_hevc_put_hevc_uni_w_epel_hv24_8_msa; - c->put_hevc_epel_uni_w[7][1][1] = - ff_hevc_put_hevc_uni_w_epel_hv32_8_msa; - - c->put_hevc_qpel_bi[1][0][0] = ff_hevc_put_hevc_bi_pel_pixels4_8_msa; - c->put_hevc_qpel_bi[3][0][0] = ff_hevc_put_hevc_bi_pel_pixels8_8_msa; - c->put_hevc_qpel_bi[4][0][0] = ff_hevc_put_hevc_bi_pel_pixels12_8_msa; - c->put_hevc_qpel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_8_msa; - c->put_hevc_qpel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_8_msa; - c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_msa; - c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_8_msa; - c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_8_msa; - - c->put_hevc_qpel_bi[1][0][1] = ff_hevc_put_hevc_bi_qpel_h4_8_msa; - c->put_hevc_qpel_bi[3][0][1] = ff_hevc_put_hevc_bi_qpel_h8_8_msa; - c->put_hevc_qpel_bi[4][0][1] = ff_hevc_put_hevc_bi_qpel_h12_8_msa; - c->put_hevc_qpel_bi[5][0][1] = ff_hevc_put_hevc_bi_qpel_h16_8_msa; - c->put_hevc_qpel_bi[6][0][1] = ff_hevc_put_hevc_bi_qpel_h24_8_msa; - c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_bi_qpel_h32_8_msa; - c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_bi_qpel_h48_8_msa; - c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_bi_qpel_h64_8_msa; - - c->put_hevc_qpel_bi[1][1][0] = ff_hevc_put_hevc_bi_qpel_v4_8_msa; - c->put_hevc_qpel_bi[3][1][0] = ff_hevc_put_hevc_bi_qpel_v8_8_msa; - c->put_hevc_qpel_bi[4][1][0] = ff_hevc_put_hevc_bi_qpel_v12_8_msa; - c->put_hevc_qpel_bi[5][1][0] = ff_hevc_put_hevc_bi_qpel_v16_8_msa; - c->put_hevc_qpel_bi[6][1][0] = ff_hevc_put_hevc_bi_qpel_v24_8_msa; - c->put_hevc_qpel_bi[7][1][0] = ff_hevc_put_hevc_bi_qpel_v32_8_msa; - c->put_hevc_qpel_bi[8][1][0] = ff_hevc_put_hevc_bi_qpel_v48_8_msa; - c->put_hevc_qpel_bi[9][1][0] = ff_hevc_put_hevc_bi_qpel_v64_8_msa; - - c->put_hevc_qpel_bi[1][1][1] = ff_hevc_put_hevc_bi_qpel_hv4_8_msa; - c->put_hevc_qpel_bi[3][1][1] = ff_hevc_put_hevc_bi_qpel_hv8_8_msa; - c->put_hevc_qpel_bi[4][1][1] = ff_hevc_put_hevc_bi_qpel_hv12_8_msa; - c->put_hevc_qpel_bi[5][1][1] = ff_hevc_put_hevc_bi_qpel_hv16_8_msa; - c->put_hevc_qpel_bi[6][1][1] = ff_hevc_put_hevc_bi_qpel_hv24_8_msa; - c->put_hevc_qpel_bi[7][1][1] = ff_hevc_put_hevc_bi_qpel_hv32_8_msa; - c->put_hevc_qpel_bi[8][1][1] = ff_hevc_put_hevc_bi_qpel_hv48_8_msa; - c->put_hevc_qpel_bi[9][1][1] = ff_hevc_put_hevc_bi_qpel_hv64_8_msa; - - c->put_hevc_epel_bi[1][0][0] = ff_hevc_put_hevc_bi_pel_pixels4_8_msa; - c->put_hevc_epel_bi[2][0][0] = ff_hevc_put_hevc_bi_pel_pixels6_8_msa; - c->put_hevc_epel_bi[3][0][0] = ff_hevc_put_hevc_bi_pel_pixels8_8_msa; - c->put_hevc_epel_bi[4][0][0] = ff_hevc_put_hevc_bi_pel_pixels12_8_msa; - c->put_hevc_epel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_8_msa; - c->put_hevc_epel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_8_msa; - c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_msa; - - c->put_hevc_epel_bi[1][0][1] = ff_hevc_put_hevc_bi_epel_h4_8_msa; - c->put_hevc_epel_bi[2][0][1] = ff_hevc_put_hevc_bi_epel_h6_8_msa; - c->put_hevc_epel_bi[3][0][1] = ff_hevc_put_hevc_bi_epel_h8_8_msa; - c->put_hevc_epel_bi[4][0][1] = ff_hevc_put_hevc_bi_epel_h12_8_msa; - c->put_hevc_epel_bi[5][0][1] = ff_hevc_put_hevc_bi_epel_h16_8_msa; - c->put_hevc_epel_bi[6][0][1] = ff_hevc_put_hevc_bi_epel_h24_8_msa; - c->put_hevc_epel_bi[7][0][1] = ff_hevc_put_hevc_bi_epel_h32_8_msa; - - c->put_hevc_epel_bi[1][1][0] = ff_hevc_put_hevc_bi_epel_v4_8_msa; - c->put_hevc_epel_bi[2][1][0] = ff_hevc_put_hevc_bi_epel_v6_8_msa; - c->put_hevc_epel_bi[3][1][0] = ff_hevc_put_hevc_bi_epel_v8_8_msa; - c->put_hevc_epel_bi[4][1][0] = ff_hevc_put_hevc_bi_epel_v12_8_msa; - c->put_hevc_epel_bi[5][1][0] = ff_hevc_put_hevc_bi_epel_v16_8_msa; - c->put_hevc_epel_bi[6][1][0] = ff_hevc_put_hevc_bi_epel_v24_8_msa; - c->put_hevc_epel_bi[7][1][0] = ff_hevc_put_hevc_bi_epel_v32_8_msa; - - c->put_hevc_epel_bi[1][1][1] = ff_hevc_put_hevc_bi_epel_hv4_8_msa; - c->put_hevc_epel_bi[2][1][1] = ff_hevc_put_hevc_bi_epel_hv6_8_msa; - c->put_hevc_epel_bi[3][1][1] = ff_hevc_put_hevc_bi_epel_hv8_8_msa; - c->put_hevc_epel_bi[4][1][1] = ff_hevc_put_hevc_bi_epel_hv12_8_msa; - c->put_hevc_epel_bi[5][1][1] = ff_hevc_put_hevc_bi_epel_hv16_8_msa; - c->put_hevc_epel_bi[6][1][1] = ff_hevc_put_hevc_bi_epel_hv24_8_msa; - c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_bi_epel_hv32_8_msa; - - c->put_hevc_qpel_bi_w[1][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels4_8_msa; - c->put_hevc_qpel_bi_w[3][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels8_8_msa; - c->put_hevc_qpel_bi_w[4][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels12_8_msa; - c->put_hevc_qpel_bi_w[5][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels16_8_msa; - c->put_hevc_qpel_bi_w[6][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels24_8_msa; - c->put_hevc_qpel_bi_w[7][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels32_8_msa; - c->put_hevc_qpel_bi_w[8][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels48_8_msa; - c->put_hevc_qpel_bi_w[9][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels64_8_msa; - - c->put_hevc_qpel_bi_w[1][0][1] = ff_hevc_put_hevc_bi_w_qpel_h4_8_msa; - c->put_hevc_qpel_bi_w[3][0][1] = ff_hevc_put_hevc_bi_w_qpel_h8_8_msa; - c->put_hevc_qpel_bi_w[4][0][1] = ff_hevc_put_hevc_bi_w_qpel_h12_8_msa; - c->put_hevc_qpel_bi_w[5][0][1] = ff_hevc_put_hevc_bi_w_qpel_h16_8_msa; - c->put_hevc_qpel_bi_w[6][0][1] = ff_hevc_put_hevc_bi_w_qpel_h24_8_msa; - c->put_hevc_qpel_bi_w[7][0][1] = ff_hevc_put_hevc_bi_w_qpel_h32_8_msa; - c->put_hevc_qpel_bi_w[8][0][1] = ff_hevc_put_hevc_bi_w_qpel_h48_8_msa; - c->put_hevc_qpel_bi_w[9][0][1] = ff_hevc_put_hevc_bi_w_qpel_h64_8_msa; - - c->put_hevc_qpel_bi_w[1][1][0] = ff_hevc_put_hevc_bi_w_qpel_v4_8_msa; - c->put_hevc_qpel_bi_w[3][1][0] = ff_hevc_put_hevc_bi_w_qpel_v8_8_msa; - c->put_hevc_qpel_bi_w[4][1][0] = ff_hevc_put_hevc_bi_w_qpel_v12_8_msa; - c->put_hevc_qpel_bi_w[5][1][0] = ff_hevc_put_hevc_bi_w_qpel_v16_8_msa; - c->put_hevc_qpel_bi_w[6][1][0] = ff_hevc_put_hevc_bi_w_qpel_v24_8_msa; - c->put_hevc_qpel_bi_w[7][1][0] = ff_hevc_put_hevc_bi_w_qpel_v32_8_msa; - c->put_hevc_qpel_bi_w[8][1][0] = ff_hevc_put_hevc_bi_w_qpel_v48_8_msa; - c->put_hevc_qpel_bi_w[9][1][0] = ff_hevc_put_hevc_bi_w_qpel_v64_8_msa; - - c->put_hevc_qpel_bi_w[1][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv4_8_msa; - c->put_hevc_qpel_bi_w[3][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv8_8_msa; - c->put_hevc_qpel_bi_w[4][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv12_8_msa; - c->put_hevc_qpel_bi_w[5][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv16_8_msa; - c->put_hevc_qpel_bi_w[6][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv24_8_msa; - c->put_hevc_qpel_bi_w[7][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv32_8_msa; - c->put_hevc_qpel_bi_w[8][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv48_8_msa; - c->put_hevc_qpel_bi_w[9][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv64_8_msa; - - c->put_hevc_epel_bi_w[1][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels4_8_msa; - c->put_hevc_epel_bi_w[2][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels6_8_msa; - c->put_hevc_epel_bi_w[3][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels8_8_msa; - c->put_hevc_epel_bi_w[4][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels12_8_msa; - c->put_hevc_epel_bi_w[5][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels16_8_msa; - c->put_hevc_epel_bi_w[6][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels24_8_msa; - c->put_hevc_epel_bi_w[7][0][0] = - ff_hevc_put_hevc_bi_w_pel_pixels32_8_msa; - - c->put_hevc_epel_bi_w[1][0][1] = ff_hevc_put_hevc_bi_w_epel_h4_8_msa; - c->put_hevc_epel_bi_w[2][0][1] = ff_hevc_put_hevc_bi_w_epel_h6_8_msa; - c->put_hevc_epel_bi_w[3][0][1] = ff_hevc_put_hevc_bi_w_epel_h8_8_msa; - c->put_hevc_epel_bi_w[4][0][1] = ff_hevc_put_hevc_bi_w_epel_h12_8_msa; - c->put_hevc_epel_bi_w[5][0][1] = ff_hevc_put_hevc_bi_w_epel_h16_8_msa; - c->put_hevc_epel_bi_w[6][0][1] = ff_hevc_put_hevc_bi_w_epel_h24_8_msa; - c->put_hevc_epel_bi_w[7][0][1] = ff_hevc_put_hevc_bi_w_epel_h32_8_msa; - - c->put_hevc_epel_bi_w[1][1][0] = ff_hevc_put_hevc_bi_w_epel_v4_8_msa; - c->put_hevc_epel_bi_w[2][1][0] = ff_hevc_put_hevc_bi_w_epel_v6_8_msa; - c->put_hevc_epel_bi_w[3][1][0] = ff_hevc_put_hevc_bi_w_epel_v8_8_msa; - c->put_hevc_epel_bi_w[4][1][0] = ff_hevc_put_hevc_bi_w_epel_v12_8_msa; - c->put_hevc_epel_bi_w[5][1][0] = ff_hevc_put_hevc_bi_w_epel_v16_8_msa; - c->put_hevc_epel_bi_w[6][1][0] = ff_hevc_put_hevc_bi_w_epel_v24_8_msa; - c->put_hevc_epel_bi_w[7][1][0] = ff_hevc_put_hevc_bi_w_epel_v32_8_msa; - - c->put_hevc_epel_bi_w[1][1][1] = ff_hevc_put_hevc_bi_w_epel_hv4_8_msa; - c->put_hevc_epel_bi_w[2][1][1] = ff_hevc_put_hevc_bi_w_epel_hv6_8_msa; - c->put_hevc_epel_bi_w[3][1][1] = ff_hevc_put_hevc_bi_w_epel_hv8_8_msa; - c->put_hevc_epel_bi_w[4][1][1] = ff_hevc_put_hevc_bi_w_epel_hv12_8_msa; - c->put_hevc_epel_bi_w[5][1][1] = ff_hevc_put_hevc_bi_w_epel_hv16_8_msa; - c->put_hevc_epel_bi_w[6][1][1] = ff_hevc_put_hevc_bi_w_epel_hv24_8_msa; - c->put_hevc_epel_bi_w[7][1][1] = ff_hevc_put_hevc_bi_w_epel_hv32_8_msa; - - c->sao_band_filter[0] = - c->sao_band_filter[1] = - c->sao_band_filter[2] = - c->sao_band_filter[3] = - c->sao_band_filter[4] = ff_hevc_sao_band_filter_0_8_msa; - - c->sao_edge_filter[0] = - c->sao_edge_filter[1] = - c->sao_edge_filter[2] = - c->sao_edge_filter[3] = - c->sao_edge_filter[4] = ff_hevc_sao_edge_filter_8_msa; - - c->hevc_h_loop_filter_luma = ff_hevc_loop_filter_luma_h_8_msa; - c->hevc_v_loop_filter_luma = ff_hevc_loop_filter_luma_v_8_msa; - - c->hevc_h_loop_filter_chroma = ff_hevc_loop_filter_chroma_h_8_msa; - c->hevc_v_loop_filter_chroma = ff_hevc_loop_filter_chroma_v_8_msa; - - c->hevc_h_loop_filter_luma_c = ff_hevc_loop_filter_luma_h_8_msa; - c->hevc_v_loop_filter_luma_c = ff_hevc_loop_filter_luma_v_8_msa; - - c->hevc_h_loop_filter_chroma_c = - ff_hevc_loop_filter_chroma_h_8_msa; - c->hevc_v_loop_filter_chroma_c = - ff_hevc_loop_filter_chroma_v_8_msa; - - c->idct[0] = ff_hevc_idct_4x4_msa; - c->idct[1] = ff_hevc_idct_8x8_msa; - c->idct[2] = ff_hevc_idct_16x16_msa; - c->idct[3] = ff_hevc_idct_32x32_msa; - c->idct_dc[0] = ff_hevc_idct_dc_4x4_msa; - c->idct_dc[1] = ff_hevc_idct_dc_8x8_msa; - c->idct_dc[2] = ff_hevc_idct_dc_16x16_msa; - c->idct_dc[3] = ff_hevc_idct_dc_32x32_msa; - c->add_residual[0] = ff_hevc_addblk_4x4_msa; - c->add_residual[1] = ff_hevc_addblk_8x8_msa; - c->add_residual[2] = ff_hevc_addblk_16x16_msa; - c->add_residual[3] = ff_hevc_addblk_32x32_msa; - c->transform_4x4_luma = ff_hevc_idct_luma_4x4_msa; - } -} -#endif // #if HAVE_MSA - void ff_hevc_dsp_init_mips(HEVCDSPContext *c, const int bit_depth) { -#if HAVE_MMI - hevc_dsp_init_mmi(c, bit_depth); -#endif // #if HAVE_MMI -#if HAVE_MSA - hevc_dsp_init_msa(c, bit_depth); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + if (bit_depth == 8) { + c->put_hevc_qpel[1][0][1] = ff_hevc_put_hevc_qpel_h4_8_mmi; + c->put_hevc_qpel[3][0][1] = ff_hevc_put_hevc_qpel_h8_8_mmi; + c->put_hevc_qpel[4][0][1] = ff_hevc_put_hevc_qpel_h12_8_mmi; + c->put_hevc_qpel[5][0][1] = ff_hevc_put_hevc_qpel_h16_8_mmi; + c->put_hevc_qpel[6][0][1] = ff_hevc_put_hevc_qpel_h24_8_mmi; + c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_8_mmi; + c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_8_mmi; + c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_8_mmi; + + c->put_hevc_qpel[1][1][1] = ff_hevc_put_hevc_qpel_hv4_8_mmi; + c->put_hevc_qpel[3][1][1] = ff_hevc_put_hevc_qpel_hv8_8_mmi; + c->put_hevc_qpel[4][1][1] = ff_hevc_put_hevc_qpel_hv12_8_mmi; + c->put_hevc_qpel[5][1][1] = ff_hevc_put_hevc_qpel_hv16_8_mmi; + c->put_hevc_qpel[6][1][1] = ff_hevc_put_hevc_qpel_hv24_8_mmi; + c->put_hevc_qpel[7][1][1] = ff_hevc_put_hevc_qpel_hv32_8_mmi; + c->put_hevc_qpel[8][1][1] = ff_hevc_put_hevc_qpel_hv48_8_mmi; + c->put_hevc_qpel[9][1][1] = ff_hevc_put_hevc_qpel_hv64_8_mmi; + + c->put_hevc_qpel_bi[1][0][1] = ff_hevc_put_hevc_qpel_bi_h4_8_mmi; + c->put_hevc_qpel_bi[3][0][1] = ff_hevc_put_hevc_qpel_bi_h8_8_mmi; + c->put_hevc_qpel_bi[4][0][1] = ff_hevc_put_hevc_qpel_bi_h12_8_mmi; + c->put_hevc_qpel_bi[5][0][1] = ff_hevc_put_hevc_qpel_bi_h16_8_mmi; + c->put_hevc_qpel_bi[6][0][1] = ff_hevc_put_hevc_qpel_bi_h24_8_mmi; + c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_qpel_bi_h32_8_mmi; + c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_qpel_bi_h48_8_mmi; + c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_qpel_bi_h64_8_mmi; + + c->put_hevc_qpel_bi[1][1][1] = ff_hevc_put_hevc_qpel_bi_hv4_8_mmi; + c->put_hevc_qpel_bi[3][1][1] = ff_hevc_put_hevc_qpel_bi_hv8_8_mmi; + c->put_hevc_qpel_bi[4][1][1] = ff_hevc_put_hevc_qpel_bi_hv12_8_mmi; + c->put_hevc_qpel_bi[5][1][1] = ff_hevc_put_hevc_qpel_bi_hv16_8_mmi; + c->put_hevc_qpel_bi[6][1][1] = ff_hevc_put_hevc_qpel_bi_hv24_8_mmi; + c->put_hevc_qpel_bi[7][1][1] = ff_hevc_put_hevc_qpel_bi_hv32_8_mmi; + c->put_hevc_qpel_bi[8][1][1] = ff_hevc_put_hevc_qpel_bi_hv48_8_mmi; + c->put_hevc_qpel_bi[9][1][1] = ff_hevc_put_hevc_qpel_bi_hv64_8_mmi; + + c->put_hevc_qpel_bi[3][0][0] = ff_hevc_put_hevc_pel_bi_pixels8_8_mmi; + c->put_hevc_qpel_bi[5][0][0] = ff_hevc_put_hevc_pel_bi_pixels16_8_mmi; + c->put_hevc_qpel_bi[6][0][0] = ff_hevc_put_hevc_pel_bi_pixels24_8_mmi; + c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_pel_bi_pixels32_8_mmi; + c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_pel_bi_pixels48_8_mmi; + c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_pel_bi_pixels64_8_mmi; + + c->put_hevc_epel_bi[3][0][0] = ff_hevc_put_hevc_pel_bi_pixels8_8_mmi; + c->put_hevc_epel_bi[5][0][0] = ff_hevc_put_hevc_pel_bi_pixels16_8_mmi; + c->put_hevc_epel_bi[6][0][0] = ff_hevc_put_hevc_pel_bi_pixels24_8_mmi; + c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_pel_bi_pixels32_8_mmi; + + c->put_hevc_epel_bi[1][1][1] = ff_hevc_put_hevc_epel_bi_hv4_8_mmi; + c->put_hevc_epel_bi[3][1][1] = ff_hevc_put_hevc_epel_bi_hv8_8_mmi; + c->put_hevc_epel_bi[4][1][1] = ff_hevc_put_hevc_epel_bi_hv12_8_mmi; + c->put_hevc_epel_bi[5][1][1] = ff_hevc_put_hevc_epel_bi_hv16_8_mmi; + c->put_hevc_epel_bi[6][1][1] = ff_hevc_put_hevc_epel_bi_hv24_8_mmi; + c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_epel_bi_hv32_8_mmi; + + c->put_hevc_qpel_uni[1][1][1] = ff_hevc_put_hevc_qpel_uni_hv4_8_mmi; + c->put_hevc_qpel_uni[3][1][1] = ff_hevc_put_hevc_qpel_uni_hv8_8_mmi; + c->put_hevc_qpel_uni[4][1][1] = ff_hevc_put_hevc_qpel_uni_hv12_8_mmi; + c->put_hevc_qpel_uni[5][1][1] = ff_hevc_put_hevc_qpel_uni_hv16_8_mmi; + c->put_hevc_qpel_uni[6][1][1] = ff_hevc_put_hevc_qpel_uni_hv24_8_mmi; + c->put_hevc_qpel_uni[7][1][1] = ff_hevc_put_hevc_qpel_uni_hv32_8_mmi; + c->put_hevc_qpel_uni[8][1][1] = ff_hevc_put_hevc_qpel_uni_hv48_8_mmi; + c->put_hevc_qpel_uni[9][1][1] = ff_hevc_put_hevc_qpel_uni_hv64_8_mmi; + } + } + + if (have_msa(cpu_flags)) { + if (bit_depth == 8) { + c->put_hevc_qpel[1][0][0] = ff_hevc_put_hevc_pel_pixels4_8_msa; + c->put_hevc_qpel[2][0][0] = ff_hevc_put_hevc_pel_pixels6_8_msa; + c->put_hevc_qpel[3][0][0] = ff_hevc_put_hevc_pel_pixels8_8_msa; + c->put_hevc_qpel[4][0][0] = ff_hevc_put_hevc_pel_pixels12_8_msa; + c->put_hevc_qpel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_8_msa; + c->put_hevc_qpel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_8_msa; + c->put_hevc_qpel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_msa; + c->put_hevc_qpel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_8_msa; + c->put_hevc_qpel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_8_msa; + + c->put_hevc_qpel[1][0][1] = ff_hevc_put_hevc_qpel_h4_8_msa; + c->put_hevc_qpel[3][0][1] = ff_hevc_put_hevc_qpel_h8_8_msa; + c->put_hevc_qpel[4][0][1] = ff_hevc_put_hevc_qpel_h12_8_msa; + c->put_hevc_qpel[5][0][1] = ff_hevc_put_hevc_qpel_h16_8_msa; + c->put_hevc_qpel[6][0][1] = ff_hevc_put_hevc_qpel_h24_8_msa; + c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_8_msa; + c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_8_msa; + c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_8_msa; + + c->put_hevc_qpel[1][1][0] = ff_hevc_put_hevc_qpel_v4_8_msa; + c->put_hevc_qpel[3][1][0] = ff_hevc_put_hevc_qpel_v8_8_msa; + c->put_hevc_qpel[4][1][0] = ff_hevc_put_hevc_qpel_v12_8_msa; + c->put_hevc_qpel[5][1][0] = ff_hevc_put_hevc_qpel_v16_8_msa; + c->put_hevc_qpel[6][1][0] = ff_hevc_put_hevc_qpel_v24_8_msa; + c->put_hevc_qpel[7][1][0] = ff_hevc_put_hevc_qpel_v32_8_msa; + c->put_hevc_qpel[8][1][0] = ff_hevc_put_hevc_qpel_v48_8_msa; + c->put_hevc_qpel[9][1][0] = ff_hevc_put_hevc_qpel_v64_8_msa; + + c->put_hevc_qpel[1][1][1] = ff_hevc_put_hevc_qpel_hv4_8_msa; + c->put_hevc_qpel[3][1][1] = ff_hevc_put_hevc_qpel_hv8_8_msa; + c->put_hevc_qpel[4][1][1] = ff_hevc_put_hevc_qpel_hv12_8_msa; + c->put_hevc_qpel[5][1][1] = ff_hevc_put_hevc_qpel_hv16_8_msa; + c->put_hevc_qpel[6][1][1] = ff_hevc_put_hevc_qpel_hv24_8_msa; + c->put_hevc_qpel[7][1][1] = ff_hevc_put_hevc_qpel_hv32_8_msa; + c->put_hevc_qpel[8][1][1] = ff_hevc_put_hevc_qpel_hv48_8_msa; + c->put_hevc_qpel[9][1][1] = ff_hevc_put_hevc_qpel_hv64_8_msa; + + c->put_hevc_epel[1][0][0] = ff_hevc_put_hevc_pel_pixels4_8_msa; + c->put_hevc_epel[2][0][0] = ff_hevc_put_hevc_pel_pixels6_8_msa; + c->put_hevc_epel[3][0][0] = ff_hevc_put_hevc_pel_pixels8_8_msa; + c->put_hevc_epel[4][0][0] = ff_hevc_put_hevc_pel_pixels12_8_msa; + c->put_hevc_epel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_8_msa; + c->put_hevc_epel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_8_msa; + c->put_hevc_epel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_msa; + + c->put_hevc_epel[1][0][1] = ff_hevc_put_hevc_epel_h4_8_msa; + c->put_hevc_epel[2][0][1] = ff_hevc_put_hevc_epel_h6_8_msa; + c->put_hevc_epel[3][0][1] = ff_hevc_put_hevc_epel_h8_8_msa; + c->put_hevc_epel[4][0][1] = ff_hevc_put_hevc_epel_h12_8_msa; + c->put_hevc_epel[5][0][1] = ff_hevc_put_hevc_epel_h16_8_msa; + c->put_hevc_epel[6][0][1] = ff_hevc_put_hevc_epel_h24_8_msa; + c->put_hevc_epel[7][0][1] = ff_hevc_put_hevc_epel_h32_8_msa; + + c->put_hevc_epel[1][1][0] = ff_hevc_put_hevc_epel_v4_8_msa; + c->put_hevc_epel[2][1][0] = ff_hevc_put_hevc_epel_v6_8_msa; + c->put_hevc_epel[3][1][0] = ff_hevc_put_hevc_epel_v8_8_msa; + c->put_hevc_epel[4][1][0] = ff_hevc_put_hevc_epel_v12_8_msa; + c->put_hevc_epel[5][1][0] = ff_hevc_put_hevc_epel_v16_8_msa; + c->put_hevc_epel[6][1][0] = ff_hevc_put_hevc_epel_v24_8_msa; + c->put_hevc_epel[7][1][0] = ff_hevc_put_hevc_epel_v32_8_msa; + + c->put_hevc_epel[1][1][1] = ff_hevc_put_hevc_epel_hv4_8_msa; + c->put_hevc_epel[2][1][1] = ff_hevc_put_hevc_epel_hv6_8_msa; + c->put_hevc_epel[3][1][1] = ff_hevc_put_hevc_epel_hv8_8_msa; + c->put_hevc_epel[4][1][1] = ff_hevc_put_hevc_epel_hv12_8_msa; + c->put_hevc_epel[5][1][1] = ff_hevc_put_hevc_epel_hv16_8_msa; + c->put_hevc_epel[6][1][1] = ff_hevc_put_hevc_epel_hv24_8_msa; + c->put_hevc_epel[7][1][1] = ff_hevc_put_hevc_epel_hv32_8_msa; + + c->put_hevc_qpel_uni[3][0][0] = ff_hevc_put_hevc_uni_pel_pixels8_8_msa; + c->put_hevc_qpel_uni[4][0][0] = ff_hevc_put_hevc_uni_pel_pixels12_8_msa; + c->put_hevc_qpel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels16_8_msa; + c->put_hevc_qpel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels24_8_msa; + c->put_hevc_qpel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_msa; + c->put_hevc_qpel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_msa; + c->put_hevc_qpel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_msa; + + c->put_hevc_qpel_uni[1][0][1] = ff_hevc_put_hevc_uni_qpel_h4_8_msa; + c->put_hevc_qpel_uni[3][0][1] = ff_hevc_put_hevc_uni_qpel_h8_8_msa; + c->put_hevc_qpel_uni[4][0][1] = ff_hevc_put_hevc_uni_qpel_h12_8_msa; + c->put_hevc_qpel_uni[5][0][1] = ff_hevc_put_hevc_uni_qpel_h16_8_msa; + c->put_hevc_qpel_uni[6][0][1] = ff_hevc_put_hevc_uni_qpel_h24_8_msa; + c->put_hevc_qpel_uni[7][0][1] = ff_hevc_put_hevc_uni_qpel_h32_8_msa; + c->put_hevc_qpel_uni[8][0][1] = ff_hevc_put_hevc_uni_qpel_h48_8_msa; + c->put_hevc_qpel_uni[9][0][1] = ff_hevc_put_hevc_uni_qpel_h64_8_msa; + + c->put_hevc_qpel_uni[1][1][0] = ff_hevc_put_hevc_uni_qpel_v4_8_msa; + c->put_hevc_qpel_uni[3][1][0] = ff_hevc_put_hevc_uni_qpel_v8_8_msa; + c->put_hevc_qpel_uni[4][1][0] = ff_hevc_put_hevc_uni_qpel_v12_8_msa; + c->put_hevc_qpel_uni[5][1][0] = ff_hevc_put_hevc_uni_qpel_v16_8_msa; + c->put_hevc_qpel_uni[6][1][0] = ff_hevc_put_hevc_uni_qpel_v24_8_msa; + c->put_hevc_qpel_uni[7][1][0] = ff_hevc_put_hevc_uni_qpel_v32_8_msa; + c->put_hevc_qpel_uni[8][1][0] = ff_hevc_put_hevc_uni_qpel_v48_8_msa; + c->put_hevc_qpel_uni[9][1][0] = ff_hevc_put_hevc_uni_qpel_v64_8_msa; + + c->put_hevc_qpel_uni[1][1][1] = ff_hevc_put_hevc_uni_qpel_hv4_8_msa; + c->put_hevc_qpel_uni[3][1][1] = ff_hevc_put_hevc_uni_qpel_hv8_8_msa; + c->put_hevc_qpel_uni[4][1][1] = ff_hevc_put_hevc_uni_qpel_hv12_8_msa; + c->put_hevc_qpel_uni[5][1][1] = ff_hevc_put_hevc_uni_qpel_hv16_8_msa; + c->put_hevc_qpel_uni[6][1][1] = ff_hevc_put_hevc_uni_qpel_hv24_8_msa; + c->put_hevc_qpel_uni[7][1][1] = ff_hevc_put_hevc_uni_qpel_hv32_8_msa; + c->put_hevc_qpel_uni[8][1][1] = ff_hevc_put_hevc_uni_qpel_hv48_8_msa; + c->put_hevc_qpel_uni[9][1][1] = ff_hevc_put_hevc_uni_qpel_hv64_8_msa; + + c->put_hevc_epel_uni[3][0][0] = ff_hevc_put_hevc_uni_pel_pixels8_8_msa; + c->put_hevc_epel_uni[4][0][0] = ff_hevc_put_hevc_uni_pel_pixels12_8_msa; + c->put_hevc_epel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels16_8_msa; + c->put_hevc_epel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels24_8_msa; + c->put_hevc_epel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_msa; + + c->put_hevc_epel_uni[1][0][1] = ff_hevc_put_hevc_uni_epel_h4_8_msa; + c->put_hevc_epel_uni[2][0][1] = ff_hevc_put_hevc_uni_epel_h6_8_msa; + c->put_hevc_epel_uni[3][0][1] = ff_hevc_put_hevc_uni_epel_h8_8_msa; + c->put_hevc_epel_uni[4][0][1] = ff_hevc_put_hevc_uni_epel_h12_8_msa; + c->put_hevc_epel_uni[5][0][1] = ff_hevc_put_hevc_uni_epel_h16_8_msa; + c->put_hevc_epel_uni[6][0][1] = ff_hevc_put_hevc_uni_epel_h24_8_msa; + c->put_hevc_epel_uni[7][0][1] = ff_hevc_put_hevc_uni_epel_h32_8_msa; + + c->put_hevc_epel_uni[1][1][0] = ff_hevc_put_hevc_uni_epel_v4_8_msa; + c->put_hevc_epel_uni[2][1][0] = ff_hevc_put_hevc_uni_epel_v6_8_msa; + c->put_hevc_epel_uni[3][1][0] = ff_hevc_put_hevc_uni_epel_v8_8_msa; + c->put_hevc_epel_uni[4][1][0] = ff_hevc_put_hevc_uni_epel_v12_8_msa; + c->put_hevc_epel_uni[5][1][0] = ff_hevc_put_hevc_uni_epel_v16_8_msa; + c->put_hevc_epel_uni[6][1][0] = ff_hevc_put_hevc_uni_epel_v24_8_msa; + c->put_hevc_epel_uni[7][1][0] = ff_hevc_put_hevc_uni_epel_v32_8_msa; + + c->put_hevc_epel_uni[1][1][1] = ff_hevc_put_hevc_uni_epel_hv4_8_msa; + c->put_hevc_epel_uni[2][1][1] = ff_hevc_put_hevc_uni_epel_hv6_8_msa; + c->put_hevc_epel_uni[3][1][1] = ff_hevc_put_hevc_uni_epel_hv8_8_msa; + c->put_hevc_epel_uni[4][1][1] = ff_hevc_put_hevc_uni_epel_hv12_8_msa; + c->put_hevc_epel_uni[5][1][1] = ff_hevc_put_hevc_uni_epel_hv16_8_msa; + c->put_hevc_epel_uni[6][1][1] = ff_hevc_put_hevc_uni_epel_hv24_8_msa; + c->put_hevc_epel_uni[7][1][1] = ff_hevc_put_hevc_uni_epel_hv32_8_msa; + + c->put_hevc_qpel_uni_w[1][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels4_8_msa; + c->put_hevc_qpel_uni_w[3][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels8_8_msa; + c->put_hevc_qpel_uni_w[4][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels12_8_msa; + c->put_hevc_qpel_uni_w[5][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels16_8_msa; + c->put_hevc_qpel_uni_w[6][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels24_8_msa; + c->put_hevc_qpel_uni_w[7][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels32_8_msa; + c->put_hevc_qpel_uni_w[8][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels48_8_msa; + c->put_hevc_qpel_uni_w[9][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels64_8_msa; + + c->put_hevc_qpel_uni_w[1][0][1] = ff_hevc_put_hevc_uni_w_qpel_h4_8_msa; + c->put_hevc_qpel_uni_w[3][0][1] = ff_hevc_put_hevc_uni_w_qpel_h8_8_msa; + c->put_hevc_qpel_uni_w[4][0][1] = ff_hevc_put_hevc_uni_w_qpel_h12_8_msa; + c->put_hevc_qpel_uni_w[5][0][1] = ff_hevc_put_hevc_uni_w_qpel_h16_8_msa; + c->put_hevc_qpel_uni_w[6][0][1] = ff_hevc_put_hevc_uni_w_qpel_h24_8_msa; + c->put_hevc_qpel_uni_w[7][0][1] = ff_hevc_put_hevc_uni_w_qpel_h32_8_msa; + c->put_hevc_qpel_uni_w[8][0][1] = ff_hevc_put_hevc_uni_w_qpel_h48_8_msa; + c->put_hevc_qpel_uni_w[9][0][1] = ff_hevc_put_hevc_uni_w_qpel_h64_8_msa; + + c->put_hevc_qpel_uni_w[1][1][0] = ff_hevc_put_hevc_uni_w_qpel_v4_8_msa; + c->put_hevc_qpel_uni_w[3][1][0] = ff_hevc_put_hevc_uni_w_qpel_v8_8_msa; + c->put_hevc_qpel_uni_w[4][1][0] = ff_hevc_put_hevc_uni_w_qpel_v12_8_msa; + c->put_hevc_qpel_uni_w[5][1][0] = ff_hevc_put_hevc_uni_w_qpel_v16_8_msa; + c->put_hevc_qpel_uni_w[6][1][0] = ff_hevc_put_hevc_uni_w_qpel_v24_8_msa; + c->put_hevc_qpel_uni_w[7][1][0] = ff_hevc_put_hevc_uni_w_qpel_v32_8_msa; + c->put_hevc_qpel_uni_w[8][1][0] = ff_hevc_put_hevc_uni_w_qpel_v48_8_msa; + c->put_hevc_qpel_uni_w[9][1][0] = ff_hevc_put_hevc_uni_w_qpel_v64_8_msa; + + c->put_hevc_qpel_uni_w[1][1][1] = ff_hevc_put_hevc_uni_w_qpel_hv4_8_msa; + c->put_hevc_qpel_uni_w[3][1][1] = ff_hevc_put_hevc_uni_w_qpel_hv8_8_msa; + c->put_hevc_qpel_uni_w[4][1][1] = + ff_hevc_put_hevc_uni_w_qpel_hv12_8_msa; + c->put_hevc_qpel_uni_w[5][1][1] = + ff_hevc_put_hevc_uni_w_qpel_hv16_8_msa; + c->put_hevc_qpel_uni_w[6][1][1] = + ff_hevc_put_hevc_uni_w_qpel_hv24_8_msa; + c->put_hevc_qpel_uni_w[7][1][1] = + ff_hevc_put_hevc_uni_w_qpel_hv32_8_msa; + c->put_hevc_qpel_uni_w[8][1][1] = + ff_hevc_put_hevc_uni_w_qpel_hv48_8_msa; + c->put_hevc_qpel_uni_w[9][1][1] = + ff_hevc_put_hevc_uni_w_qpel_hv64_8_msa; + + c->put_hevc_epel_uni_w[1][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels4_8_msa; + c->put_hevc_epel_uni_w[2][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels6_8_msa; + c->put_hevc_epel_uni_w[3][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels8_8_msa; + c->put_hevc_epel_uni_w[4][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels12_8_msa; + c->put_hevc_epel_uni_w[5][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels16_8_msa; + c->put_hevc_epel_uni_w[6][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels24_8_msa; + c->put_hevc_epel_uni_w[7][0][0] = + ff_hevc_put_hevc_uni_w_pel_pixels32_8_msa; + + c->put_hevc_epel_uni_w[1][0][1] = ff_hevc_put_hevc_uni_w_epel_h4_8_msa; + c->put_hevc_epel_uni_w[2][0][1] = ff_hevc_put_hevc_uni_w_epel_h6_8_msa; + c->put_hevc_epel_uni_w[3][0][1] = ff_hevc_put_hevc_uni_w_epel_h8_8_msa; + c->put_hevc_epel_uni_w[4][0][1] = ff_hevc_put_hevc_uni_w_epel_h12_8_msa; + c->put_hevc_epel_uni_w[5][0][1] = ff_hevc_put_hevc_uni_w_epel_h16_8_msa; + c->put_hevc_epel_uni_w[6][0][1] = ff_hevc_put_hevc_uni_w_epel_h24_8_msa; + c->put_hevc_epel_uni_w[7][0][1] = ff_hevc_put_hevc_uni_w_epel_h32_8_msa; + + c->put_hevc_epel_uni_w[1][1][0] = ff_hevc_put_hevc_uni_w_epel_v4_8_msa; + c->put_hevc_epel_uni_w[2][1][0] = ff_hevc_put_hevc_uni_w_epel_v6_8_msa; + c->put_hevc_epel_uni_w[3][1][0] = ff_hevc_put_hevc_uni_w_epel_v8_8_msa; + c->put_hevc_epel_uni_w[4][1][0] = ff_hevc_put_hevc_uni_w_epel_v12_8_msa; + c->put_hevc_epel_uni_w[5][1][0] = ff_hevc_put_hevc_uni_w_epel_v16_8_msa; + c->put_hevc_epel_uni_w[6][1][0] = ff_hevc_put_hevc_uni_w_epel_v24_8_msa; + c->put_hevc_epel_uni_w[7][1][0] = ff_hevc_put_hevc_uni_w_epel_v32_8_msa; + + c->put_hevc_epel_uni_w[1][1][1] = ff_hevc_put_hevc_uni_w_epel_hv4_8_msa; + c->put_hevc_epel_uni_w[2][1][1] = ff_hevc_put_hevc_uni_w_epel_hv6_8_msa; + c->put_hevc_epel_uni_w[3][1][1] = ff_hevc_put_hevc_uni_w_epel_hv8_8_msa; + c->put_hevc_epel_uni_w[4][1][1] = + ff_hevc_put_hevc_uni_w_epel_hv12_8_msa; + c->put_hevc_epel_uni_w[5][1][1] = + ff_hevc_put_hevc_uni_w_epel_hv16_8_msa; + c->put_hevc_epel_uni_w[6][1][1] = + ff_hevc_put_hevc_uni_w_epel_hv24_8_msa; + c->put_hevc_epel_uni_w[7][1][1] = + ff_hevc_put_hevc_uni_w_epel_hv32_8_msa; + + c->put_hevc_qpel_bi[1][0][0] = ff_hevc_put_hevc_bi_pel_pixels4_8_msa; + c->put_hevc_qpel_bi[3][0][0] = ff_hevc_put_hevc_bi_pel_pixels8_8_msa; + c->put_hevc_qpel_bi[4][0][0] = ff_hevc_put_hevc_bi_pel_pixels12_8_msa; + c->put_hevc_qpel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_8_msa; + c->put_hevc_qpel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_8_msa; + c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_msa; + c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_8_msa; + c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_8_msa; + + c->put_hevc_qpel_bi[1][0][1] = ff_hevc_put_hevc_bi_qpel_h4_8_msa; + c->put_hevc_qpel_bi[3][0][1] = ff_hevc_put_hevc_bi_qpel_h8_8_msa; + c->put_hevc_qpel_bi[4][0][1] = ff_hevc_put_hevc_bi_qpel_h12_8_msa; + c->put_hevc_qpel_bi[5][0][1] = ff_hevc_put_hevc_bi_qpel_h16_8_msa; + c->put_hevc_qpel_bi[6][0][1] = ff_hevc_put_hevc_bi_qpel_h24_8_msa; + c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_bi_qpel_h32_8_msa; + c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_bi_qpel_h48_8_msa; + c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_bi_qpel_h64_8_msa; + + c->put_hevc_qpel_bi[1][1][0] = ff_hevc_put_hevc_bi_qpel_v4_8_msa; + c->put_hevc_qpel_bi[3][1][0] = ff_hevc_put_hevc_bi_qpel_v8_8_msa; + c->put_hevc_qpel_bi[4][1][0] = ff_hevc_put_hevc_bi_qpel_v12_8_msa; + c->put_hevc_qpel_bi[5][1][0] = ff_hevc_put_hevc_bi_qpel_v16_8_msa; + c->put_hevc_qpel_bi[6][1][0] = ff_hevc_put_hevc_bi_qpel_v24_8_msa; + c->put_hevc_qpel_bi[7][1][0] = ff_hevc_put_hevc_bi_qpel_v32_8_msa; + c->put_hevc_qpel_bi[8][1][0] = ff_hevc_put_hevc_bi_qpel_v48_8_msa; + c->put_hevc_qpel_bi[9][1][0] = ff_hevc_put_hevc_bi_qpel_v64_8_msa; + + c->put_hevc_qpel_bi[1][1][1] = ff_hevc_put_hevc_bi_qpel_hv4_8_msa; + c->put_hevc_qpel_bi[3][1][1] = ff_hevc_put_hevc_bi_qpel_hv8_8_msa; + c->put_hevc_qpel_bi[4][1][1] = ff_hevc_put_hevc_bi_qpel_hv12_8_msa; + c->put_hevc_qpel_bi[5][1][1] = ff_hevc_put_hevc_bi_qpel_hv16_8_msa; + c->put_hevc_qpel_bi[6][1][1] = ff_hevc_put_hevc_bi_qpel_hv24_8_msa; + c->put_hevc_qpel_bi[7][1][1] = ff_hevc_put_hevc_bi_qpel_hv32_8_msa; + c->put_hevc_qpel_bi[8][1][1] = ff_hevc_put_hevc_bi_qpel_hv48_8_msa; + c->put_hevc_qpel_bi[9][1][1] = ff_hevc_put_hevc_bi_qpel_hv64_8_msa; + + c->put_hevc_epel_bi[1][0][0] = ff_hevc_put_hevc_bi_pel_pixels4_8_msa; + c->put_hevc_epel_bi[2][0][0] = ff_hevc_put_hevc_bi_pel_pixels6_8_msa; + c->put_hevc_epel_bi[3][0][0] = ff_hevc_put_hevc_bi_pel_pixels8_8_msa; + c->put_hevc_epel_bi[4][0][0] = ff_hevc_put_hevc_bi_pel_pixels12_8_msa; + c->put_hevc_epel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_8_msa; + c->put_hevc_epel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_8_msa; + c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_msa; + + c->put_hevc_epel_bi[1][0][1] = ff_hevc_put_hevc_bi_epel_h4_8_msa; + c->put_hevc_epel_bi[2][0][1] = ff_hevc_put_hevc_bi_epel_h6_8_msa; + c->put_hevc_epel_bi[3][0][1] = ff_hevc_put_hevc_bi_epel_h8_8_msa; + c->put_hevc_epel_bi[4][0][1] = ff_hevc_put_hevc_bi_epel_h12_8_msa; + c->put_hevc_epel_bi[5][0][1] = ff_hevc_put_hevc_bi_epel_h16_8_msa; + c->put_hevc_epel_bi[6][0][1] = ff_hevc_put_hevc_bi_epel_h24_8_msa; + c->put_hevc_epel_bi[7][0][1] = ff_hevc_put_hevc_bi_epel_h32_8_msa; + + c->put_hevc_epel_bi[1][1][0] = ff_hevc_put_hevc_bi_epel_v4_8_msa; + c->put_hevc_epel_bi[2][1][0] = ff_hevc_put_hevc_bi_epel_v6_8_msa; + c->put_hevc_epel_bi[3][1][0] = ff_hevc_put_hevc_bi_epel_v8_8_msa; + c->put_hevc_epel_bi[4][1][0] = ff_hevc_put_hevc_bi_epel_v12_8_msa; + c->put_hevc_epel_bi[5][1][0] = ff_hevc_put_hevc_bi_epel_v16_8_msa; + c->put_hevc_epel_bi[6][1][0] = ff_hevc_put_hevc_bi_epel_v24_8_msa; + c->put_hevc_epel_bi[7][1][0] = ff_hevc_put_hevc_bi_epel_v32_8_msa; + + c->put_hevc_epel_bi[1][1][1] = ff_hevc_put_hevc_bi_epel_hv4_8_msa; + c->put_hevc_epel_bi[2][1][1] = ff_hevc_put_hevc_bi_epel_hv6_8_msa; + c->put_hevc_epel_bi[3][1][1] = ff_hevc_put_hevc_bi_epel_hv8_8_msa; + c->put_hevc_epel_bi[4][1][1] = ff_hevc_put_hevc_bi_epel_hv12_8_msa; + c->put_hevc_epel_bi[5][1][1] = ff_hevc_put_hevc_bi_epel_hv16_8_msa; + c->put_hevc_epel_bi[6][1][1] = ff_hevc_put_hevc_bi_epel_hv24_8_msa; + c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_bi_epel_hv32_8_msa; + + c->put_hevc_qpel_bi_w[1][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels4_8_msa; + c->put_hevc_qpel_bi_w[3][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels8_8_msa; + c->put_hevc_qpel_bi_w[4][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels12_8_msa; + c->put_hevc_qpel_bi_w[5][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels16_8_msa; + c->put_hevc_qpel_bi_w[6][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels24_8_msa; + c->put_hevc_qpel_bi_w[7][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels32_8_msa; + c->put_hevc_qpel_bi_w[8][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels48_8_msa; + c->put_hevc_qpel_bi_w[9][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels64_8_msa; + + c->put_hevc_qpel_bi_w[1][0][1] = ff_hevc_put_hevc_bi_w_qpel_h4_8_msa; + c->put_hevc_qpel_bi_w[3][0][1] = ff_hevc_put_hevc_bi_w_qpel_h8_8_msa; + c->put_hevc_qpel_bi_w[4][0][1] = ff_hevc_put_hevc_bi_w_qpel_h12_8_msa; + c->put_hevc_qpel_bi_w[5][0][1] = ff_hevc_put_hevc_bi_w_qpel_h16_8_msa; + c->put_hevc_qpel_bi_w[6][0][1] = ff_hevc_put_hevc_bi_w_qpel_h24_8_msa; + c->put_hevc_qpel_bi_w[7][0][1] = ff_hevc_put_hevc_bi_w_qpel_h32_8_msa; + c->put_hevc_qpel_bi_w[8][0][1] = ff_hevc_put_hevc_bi_w_qpel_h48_8_msa; + c->put_hevc_qpel_bi_w[9][0][1] = ff_hevc_put_hevc_bi_w_qpel_h64_8_msa; + + c->put_hevc_qpel_bi_w[1][1][0] = ff_hevc_put_hevc_bi_w_qpel_v4_8_msa; + c->put_hevc_qpel_bi_w[3][1][0] = ff_hevc_put_hevc_bi_w_qpel_v8_8_msa; + c->put_hevc_qpel_bi_w[4][1][0] = ff_hevc_put_hevc_bi_w_qpel_v12_8_msa; + c->put_hevc_qpel_bi_w[5][1][0] = ff_hevc_put_hevc_bi_w_qpel_v16_8_msa; + c->put_hevc_qpel_bi_w[6][1][0] = ff_hevc_put_hevc_bi_w_qpel_v24_8_msa; + c->put_hevc_qpel_bi_w[7][1][0] = ff_hevc_put_hevc_bi_w_qpel_v32_8_msa; + c->put_hevc_qpel_bi_w[8][1][0] = ff_hevc_put_hevc_bi_w_qpel_v48_8_msa; + c->put_hevc_qpel_bi_w[9][1][0] = ff_hevc_put_hevc_bi_w_qpel_v64_8_msa; + + c->put_hevc_qpel_bi_w[1][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv4_8_msa; + c->put_hevc_qpel_bi_w[3][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv8_8_msa; + c->put_hevc_qpel_bi_w[4][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv12_8_msa; + c->put_hevc_qpel_bi_w[5][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv16_8_msa; + c->put_hevc_qpel_bi_w[6][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv24_8_msa; + c->put_hevc_qpel_bi_w[7][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv32_8_msa; + c->put_hevc_qpel_bi_w[8][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv48_8_msa; + c->put_hevc_qpel_bi_w[9][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv64_8_msa; + + c->put_hevc_epel_bi_w[1][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels4_8_msa; + c->put_hevc_epel_bi_w[2][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels6_8_msa; + c->put_hevc_epel_bi_w[3][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels8_8_msa; + c->put_hevc_epel_bi_w[4][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels12_8_msa; + c->put_hevc_epel_bi_w[5][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels16_8_msa; + c->put_hevc_epel_bi_w[6][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels24_8_msa; + c->put_hevc_epel_bi_w[7][0][0] = + ff_hevc_put_hevc_bi_w_pel_pixels32_8_msa; + + c->put_hevc_epel_bi_w[1][0][1] = ff_hevc_put_hevc_bi_w_epel_h4_8_msa; + c->put_hevc_epel_bi_w[2][0][1] = ff_hevc_put_hevc_bi_w_epel_h6_8_msa; + c->put_hevc_epel_bi_w[3][0][1] = ff_hevc_put_hevc_bi_w_epel_h8_8_msa; + c->put_hevc_epel_bi_w[4][0][1] = ff_hevc_put_hevc_bi_w_epel_h12_8_msa; + c->put_hevc_epel_bi_w[5][0][1] = ff_hevc_put_hevc_bi_w_epel_h16_8_msa; + c->put_hevc_epel_bi_w[6][0][1] = ff_hevc_put_hevc_bi_w_epel_h24_8_msa; + c->put_hevc_epel_bi_w[7][0][1] = ff_hevc_put_hevc_bi_w_epel_h32_8_msa; + + c->put_hevc_epel_bi_w[1][1][0] = ff_hevc_put_hevc_bi_w_epel_v4_8_msa; + c->put_hevc_epel_bi_w[2][1][0] = ff_hevc_put_hevc_bi_w_epel_v6_8_msa; + c->put_hevc_epel_bi_w[3][1][0] = ff_hevc_put_hevc_bi_w_epel_v8_8_msa; + c->put_hevc_epel_bi_w[4][1][0] = ff_hevc_put_hevc_bi_w_epel_v12_8_msa; + c->put_hevc_epel_bi_w[5][1][0] = ff_hevc_put_hevc_bi_w_epel_v16_8_msa; + c->put_hevc_epel_bi_w[6][1][0] = ff_hevc_put_hevc_bi_w_epel_v24_8_msa; + c->put_hevc_epel_bi_w[7][1][0] = ff_hevc_put_hevc_bi_w_epel_v32_8_msa; + + c->put_hevc_epel_bi_w[1][1][1] = ff_hevc_put_hevc_bi_w_epel_hv4_8_msa; + c->put_hevc_epel_bi_w[2][1][1] = ff_hevc_put_hevc_bi_w_epel_hv6_8_msa; + c->put_hevc_epel_bi_w[3][1][1] = ff_hevc_put_hevc_bi_w_epel_hv8_8_msa; + c->put_hevc_epel_bi_w[4][1][1] = ff_hevc_put_hevc_bi_w_epel_hv12_8_msa; + c->put_hevc_epel_bi_w[5][1][1] = ff_hevc_put_hevc_bi_w_epel_hv16_8_msa; + c->put_hevc_epel_bi_w[6][1][1] = ff_hevc_put_hevc_bi_w_epel_hv24_8_msa; + c->put_hevc_epel_bi_w[7][1][1] = ff_hevc_put_hevc_bi_w_epel_hv32_8_msa; + + c->sao_band_filter[0] = + c->sao_band_filter[1] = + c->sao_band_filter[2] = + c->sao_band_filter[3] = + c->sao_band_filter[4] = ff_hevc_sao_band_filter_0_8_msa; + + c->sao_edge_filter[0] = + c->sao_edge_filter[1] = + c->sao_edge_filter[2] = + c->sao_edge_filter[3] = + c->sao_edge_filter[4] = ff_hevc_sao_edge_filter_8_msa; + + c->hevc_h_loop_filter_luma = ff_hevc_loop_filter_luma_h_8_msa; + c->hevc_v_loop_filter_luma = ff_hevc_loop_filter_luma_v_8_msa; + + c->hevc_h_loop_filter_chroma = ff_hevc_loop_filter_chroma_h_8_msa; + c->hevc_v_loop_filter_chroma = ff_hevc_loop_filter_chroma_v_8_msa; + + c->hevc_h_loop_filter_luma_c = ff_hevc_loop_filter_luma_h_8_msa; + c->hevc_v_loop_filter_luma_c = ff_hevc_loop_filter_luma_v_8_msa; + + c->hevc_h_loop_filter_chroma_c = + ff_hevc_loop_filter_chroma_h_8_msa; + c->hevc_v_loop_filter_chroma_c = + ff_hevc_loop_filter_chroma_v_8_msa; + + c->idct[0] = ff_hevc_idct_4x4_msa; + c->idct[1] = ff_hevc_idct_8x8_msa; + c->idct[2] = ff_hevc_idct_16x16_msa; + c->idct[3] = ff_hevc_idct_32x32_msa; + c->idct_dc[0] = ff_hevc_idct_dc_4x4_msa; + c->idct_dc[1] = ff_hevc_idct_dc_8x8_msa; + c->idct_dc[2] = ff_hevc_idct_dc_16x16_msa; + c->idct_dc[3] = ff_hevc_idct_dc_32x32_msa; + c->add_residual[0] = ff_hevc_addblk_4x4_msa; + c->add_residual[1] = ff_hevc_addblk_8x8_msa; + c->add_residual[2] = ff_hevc_addblk_16x16_msa; + c->add_residual[3] = ff_hevc_addblk_32x32_msa; + c->transform_4x4_luma = ff_hevc_idct_luma_4x4_msa; + } + } } diff --git a/libavcodec/mips/hevcpred_init_mips.c b/libavcodec/mips/hevcpred_init_mips.c index e987698d6..f7ecb34dc 100644 --- a/libavcodec/mips/hevcpred_init_mips.c +++ b/libavcodec/mips/hevcpred_init_mips.c @@ -18,32 +18,28 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "config.h" #include "libavutil/attributes.h" #include "libavcodec/mips/hevcpred_mips.h" -#if HAVE_MSA -static av_cold void hevc_pred_init_msa(HEVCPredContext *c, const int bit_depth) -{ - if (8 == bit_depth) { - c->intra_pred[2] = ff_intra_pred_8_16x16_msa; - c->intra_pred[3] = ff_intra_pred_8_32x32_msa; - c->pred_planar[0] = ff_hevc_intra_pred_planar_0_msa; - c->pred_planar[1] = ff_hevc_intra_pred_planar_1_msa; - c->pred_planar[2] = ff_hevc_intra_pred_planar_2_msa; - c->pred_planar[3] = ff_hevc_intra_pred_planar_3_msa; - c->pred_dc = ff_hevc_intra_pred_dc_msa; - c->pred_angular[0] = ff_pred_intra_pred_angular_0_msa; - c->pred_angular[1] = ff_pred_intra_pred_angular_1_msa; - c->pred_angular[2] = ff_pred_intra_pred_angular_2_msa; - c->pred_angular[3] = ff_pred_intra_pred_angular_3_msa; - } -} -#endif // #if HAVE_MSA - void ff_hevc_pred_init_mips(HEVCPredContext *c, const int bit_depth) { -#if HAVE_MSA - hevc_pred_init_msa(c, bit_depth); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_msa(cpu_flags)) { + if (bit_depth == 8) { + c->intra_pred[2] = ff_intra_pred_8_16x16_msa; + c->intra_pred[3] = ff_intra_pred_8_32x32_msa; + c->pred_planar[0] = ff_hevc_intra_pred_planar_0_msa; + c->pred_planar[1] = ff_hevc_intra_pred_planar_1_msa; + c->pred_planar[2] = ff_hevc_intra_pred_planar_2_msa; + c->pred_planar[3] = ff_hevc_intra_pred_planar_3_msa; + c->pred_dc = ff_hevc_intra_pred_dc_msa; + c->pred_angular[0] = ff_pred_intra_pred_angular_0_msa; + c->pred_angular[1] = ff_pred_intra_pred_angular_1_msa; + c->pred_angular[2] = ff_pred_intra_pred_angular_2_msa; + c->pred_angular[3] = ff_pred_intra_pred_angular_3_msa; + } + } } diff --git a/libavcodec/mips/hpeldsp_init_mips.c b/libavcodec/mips/hpeldsp_init_mips.c index d6f7a9793..77cbe99fa 100644 --- a/libavcodec/mips/hpeldsp_init_mips.c +++ b/libavcodec/mips/hpeldsp_init_mips.c @@ -19,104 +19,94 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "../hpeldsp.h" #include "libavcodec/mips/hpeldsp_mips.h" -#if HAVE_MSA -static void ff_hpeldsp_init_msa(HpelDSPContext *c, int flags) -{ - c->put_pixels_tab[0][0] = ff_put_pixels16_msa; - c->put_pixels_tab[0][1] = ff_put_pixels16_x2_msa; - c->put_pixels_tab[0][2] = ff_put_pixels16_y2_msa; - c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_msa; - - c->put_pixels_tab[1][0] = ff_put_pixels8_msa; - c->put_pixels_tab[1][1] = ff_put_pixels8_x2_msa; - c->put_pixels_tab[1][2] = ff_put_pixels8_y2_msa; - c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_msa; - - c->put_pixels_tab[2][1] = ff_put_pixels4_x2_msa; - c->put_pixels_tab[2][2] = ff_put_pixels4_y2_msa; - c->put_pixels_tab[2][3] = ff_put_pixels4_xy2_msa; - - c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_msa; - c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_msa; - c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_msa; - c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_msa; - - c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_msa; - c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_msa; - c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_msa; - c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_msa; - - c->avg_pixels_tab[0][0] = ff_avg_pixels16_msa; - c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_msa; - c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_msa; - c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_msa; - - c->avg_pixels_tab[1][0] = ff_avg_pixels8_msa; - c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_msa; - c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_msa; - c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_msa; - - c->avg_pixels_tab[2][0] = ff_avg_pixels4_msa; - c->avg_pixels_tab[2][1] = ff_avg_pixels4_x2_msa; - c->avg_pixels_tab[2][2] = ff_avg_pixels4_y2_msa; - c->avg_pixels_tab[2][3] = ff_avg_pixels4_xy2_msa; -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static void ff_hpeldsp_init_mmi(HpelDSPContext *c, int flags) -{ - c->put_pixels_tab[0][0] = ff_put_pixels16_8_mmi; - c->put_pixels_tab[0][1] = ff_put_pixels16_x2_8_mmi; - c->put_pixels_tab[0][2] = ff_put_pixels16_y2_8_mmi; - c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_8_mmi; - - c->put_pixels_tab[1][0] = ff_put_pixels8_8_mmi; - c->put_pixels_tab[1][1] = ff_put_pixels8_x2_8_mmi; - c->put_pixels_tab[1][2] = ff_put_pixels8_y2_8_mmi; - c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_8_mmi; - - c->put_pixels_tab[2][0] = ff_put_pixels4_8_mmi; - c->put_pixels_tab[2][1] = ff_put_pixels4_x2_8_mmi; - c->put_pixels_tab[2][2] = ff_put_pixels4_y2_8_mmi; - c->put_pixels_tab[2][3] = ff_put_pixels4_xy2_8_mmi; - - c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_8_mmi; - c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_8_mmi; - c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_8_mmi; - c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_8_mmi; - - c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_8_mmi; - c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_8_mmi; - c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_8_mmi; - c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_8_mmi; - - c->avg_pixels_tab[0][0] = ff_avg_pixels16_8_mmi; - c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_8_mmi; - c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_8_mmi; - c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_8_mmi; - - c->avg_pixels_tab[1][0] = ff_avg_pixels8_8_mmi; - c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_8_mmi; - c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_8_mmi; - c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_8_mmi; - - c->avg_pixels_tab[2][0] = ff_avg_pixels4_8_mmi; - c->avg_pixels_tab[2][1] = ff_avg_pixels4_x2_8_mmi; - c->avg_pixels_tab[2][2] = ff_avg_pixels4_y2_8_mmi; - c->avg_pixels_tab[2][3] = ff_avg_pixels4_xy2_8_mmi; -} -#endif // #if HAVE_MMI - void ff_hpeldsp_init_mips(HpelDSPContext *c, int flags) { -#if HAVE_MMI - ff_hpeldsp_init_mmi(c, flags); -#endif // #if HAVE_MMI -#if HAVE_MSA - ff_hpeldsp_init_msa(c, flags); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + c->put_pixels_tab[0][0] = ff_put_pixels16_8_mmi; + c->put_pixels_tab[0][1] = ff_put_pixels16_x2_8_mmi; + c->put_pixels_tab[0][2] = ff_put_pixels16_y2_8_mmi; + c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_8_mmi; + + c->put_pixels_tab[1][0] = ff_put_pixels8_8_mmi; + c->put_pixels_tab[1][1] = ff_put_pixels8_x2_8_mmi; + c->put_pixels_tab[1][2] = ff_put_pixels8_y2_8_mmi; + c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_8_mmi; + + c->put_pixels_tab[2][0] = ff_put_pixels4_8_mmi; + c->put_pixels_tab[2][1] = ff_put_pixels4_x2_8_mmi; + c->put_pixels_tab[2][2] = ff_put_pixels4_y2_8_mmi; + c->put_pixels_tab[2][3] = ff_put_pixels4_xy2_8_mmi; + + c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_8_mmi; + c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_8_mmi; + c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_8_mmi; + c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_8_mmi; + + c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_8_mmi; + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_8_mmi; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_8_mmi; + c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_8_mmi; + + c->avg_pixels_tab[0][0] = ff_avg_pixels16_8_mmi; + c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_8_mmi; + c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_8_mmi; + c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_8_mmi; + + c->avg_pixels_tab[1][0] = ff_avg_pixels8_8_mmi; + c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_8_mmi; + c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_8_mmi; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_8_mmi; + + c->avg_pixels_tab[2][0] = ff_avg_pixels4_8_mmi; + c->avg_pixels_tab[2][1] = ff_avg_pixels4_x2_8_mmi; + c->avg_pixels_tab[2][2] = ff_avg_pixels4_y2_8_mmi; + c->avg_pixels_tab[2][3] = ff_avg_pixels4_xy2_8_mmi; + } + + if (have_msa(cpu_flags)) { + c->put_pixels_tab[0][0] = ff_put_pixels16_msa; + c->put_pixels_tab[0][1] = ff_put_pixels16_x2_msa; + c->put_pixels_tab[0][2] = ff_put_pixels16_y2_msa; + c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_msa; + + c->put_pixels_tab[1][0] = ff_put_pixels8_msa; + c->put_pixels_tab[1][1] = ff_put_pixels8_x2_msa; + c->put_pixels_tab[1][2] = ff_put_pixels8_y2_msa; + c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_msa; + + c->put_pixels_tab[2][1] = ff_put_pixels4_x2_msa; + c->put_pixels_tab[2][2] = ff_put_pixels4_y2_msa; + c->put_pixels_tab[2][3] = ff_put_pixels4_xy2_msa; + + c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_msa; + c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_msa; + c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_msa; + c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_msa; + + c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_msa; + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_msa; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_msa; + c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_msa; + + c->avg_pixels_tab[0][0] = ff_avg_pixels16_msa; + c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_msa; + c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_msa; + c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_msa; + + c->avg_pixels_tab[1][0] = ff_avg_pixels8_msa; + c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_msa; + c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_msa; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_msa; + + c->avg_pixels_tab[2][0] = ff_avg_pixels4_msa; + c->avg_pixels_tab[2][1] = ff_avg_pixels4_x2_msa; + c->avg_pixels_tab[2][2] = ff_avg_pixels4_y2_msa; + c->avg_pixels_tab[2][3] = ff_avg_pixels4_xy2_msa; + } } diff --git a/libavcodec/mips/idctdsp_init_mips.c b/libavcodec/mips/idctdsp_init_mips.c index 85b76ca47..23efd9ed5 100644 --- a/libavcodec/mips/idctdsp_init_mips.c +++ b/libavcodec/mips/idctdsp_init_mips.c @@ -19,56 +19,44 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "idctdsp_mips.h" #include "xvididct_mips.h" -#if HAVE_MSA -static av_cold void idctdsp_init_msa(IDCTDSPContext *c, AVCodecContext *avctx, - unsigned high_bit_depth) -{ - if ((avctx->lowres != 1) && (avctx->lowres != 2) && (avctx->lowres != 3) && - (avctx->bits_per_raw_sample != 10) && - (avctx->bits_per_raw_sample != 12) && - (avctx->idct_algo == FF_IDCT_AUTO)) { - c->idct_put = ff_simple_idct_put_msa; - c->idct_add = ff_simple_idct_add_msa; - c->idct = ff_simple_idct_msa; - c->perm_type = FF_IDCT_PERM_NONE; - } - - c->put_pixels_clamped = ff_put_pixels_clamped_msa; - c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_msa; - c->add_pixels_clamped = ff_add_pixels_clamped_msa; -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static av_cold void idctdsp_init_mmi(IDCTDSPContext *c, AVCodecContext *avctx, - unsigned high_bit_depth) -{ - if ((avctx->lowres != 1) && (avctx->lowres != 2) && (avctx->lowres != 3) && - (avctx->bits_per_raw_sample != 10) && - (avctx->bits_per_raw_sample != 12) && - ((avctx->idct_algo == FF_IDCT_AUTO) || (avctx->idct_algo == FF_IDCT_SIMPLE))) { - c->idct_put = ff_simple_idct_put_8_mmi; - c->idct_add = ff_simple_idct_add_8_mmi; - c->idct = ff_simple_idct_8_mmi; - c->perm_type = FF_IDCT_PERM_NONE; - } - - c->put_pixels_clamped = ff_put_pixels_clamped_mmi; - c->add_pixels_clamped = ff_add_pixels_clamped_mmi; - c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmi; -} -#endif /* HAVE_MMI */ - av_cold void ff_idctdsp_init_mips(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth) { -#if HAVE_MMI - idctdsp_init_mmi(c, avctx, high_bit_depth); -#endif /* HAVE_MMI */ -#if HAVE_MSA - idctdsp_init_msa(c, avctx, high_bit_depth); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + if ((avctx->lowres != 1) && (avctx->lowres != 2) && (avctx->lowres != 3) && + (avctx->bits_per_raw_sample != 10) && + (avctx->bits_per_raw_sample != 12) && + ((avctx->idct_algo == FF_IDCT_AUTO) || (avctx->idct_algo == FF_IDCT_SIMPLE))) { + c->idct_put = ff_simple_idct_put_8_mmi; + c->idct_add = ff_simple_idct_add_8_mmi; + c->idct = ff_simple_idct_8_mmi; + c->perm_type = FF_IDCT_PERM_NONE; + } + + c->put_pixels_clamped = ff_put_pixels_clamped_mmi; + c->add_pixels_clamped = ff_add_pixels_clamped_mmi; + c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmi; + } + + if (have_msa(cpu_flags)) { + if ((avctx->lowres != 1) && (avctx->lowres != 2) && (avctx->lowres != 3) && + (avctx->bits_per_raw_sample != 10) && + (avctx->bits_per_raw_sample != 12) && + (avctx->idct_algo == FF_IDCT_AUTO)) { + c->idct_put = ff_simple_idct_put_msa; + c->idct_add = ff_simple_idct_add_msa; + c->idct = ff_simple_idct_msa; + c->perm_type = FF_IDCT_PERM_NONE; + } + + c->put_pixels_clamped = ff_put_pixels_clamped_msa; + c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_msa; + c->add_pixels_clamped = ff_add_pixels_clamped_msa; + } } diff --git a/libavcodec/mips/me_cmp_init_mips.c b/libavcodec/mips/me_cmp_init_mips.c index 219a0dc00..e3e33b8e5 100644 --- a/libavcodec/mips/me_cmp_init_mips.c +++ b/libavcodec/mips/me_cmp_init_mips.c @@ -18,39 +18,35 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "me_cmp_mips.h" -#if HAVE_MSA -static av_cold void me_cmp_msa(MECmpContext *c, AVCodecContext *avctx) -{ -#if BIT_DEPTH == 8 - c->pix_abs[0][0] = ff_pix_abs16_msa; - c->pix_abs[0][1] = ff_pix_abs16_x2_msa; - c->pix_abs[0][2] = ff_pix_abs16_y2_msa; - c->pix_abs[0][3] = ff_pix_abs16_xy2_msa; - c->pix_abs[1][0] = ff_pix_abs8_msa; - c->pix_abs[1][1] = ff_pix_abs8_x2_msa; - c->pix_abs[1][2] = ff_pix_abs8_y2_msa; - c->pix_abs[1][3] = ff_pix_abs8_xy2_msa; - - c->hadamard8_diff[0] = ff_hadamard8_diff16_msa; - c->hadamard8_diff[1] = ff_hadamard8_diff8x8_msa; - - c->hadamard8_diff[4] = ff_hadamard8_intra16_msa; - c->hadamard8_diff[5] = ff_hadamard8_intra8x8_msa; - - c->sad[0] = ff_pix_abs16_msa; - c->sad[1] = ff_pix_abs8_msa; - c->sse[0] = ff_sse16_msa; - c->sse[1] = ff_sse8_msa; - c->sse[2] = ff_sse4_msa; -#endif -} -#endif // #if HAVE_MSA - av_cold void ff_me_cmp_init_mips(MECmpContext *c, AVCodecContext *avctx) { -#if HAVE_MSA - me_cmp_msa(c, avctx); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_msa(cpu_flags)) { +#if BIT_DEPTH == 8 + c->pix_abs[0][0] = ff_pix_abs16_msa; + c->pix_abs[0][1] = ff_pix_abs16_x2_msa; + c->pix_abs[0][2] = ff_pix_abs16_y2_msa; + c->pix_abs[0][3] = ff_pix_abs16_xy2_msa; + c->pix_abs[1][0] = ff_pix_abs8_msa; + c->pix_abs[1][1] = ff_pix_abs8_x2_msa; + c->pix_abs[1][2] = ff_pix_abs8_y2_msa; + c->pix_abs[1][3] = ff_pix_abs8_xy2_msa; + + c->hadamard8_diff[0] = ff_hadamard8_diff16_msa; + c->hadamard8_diff[1] = ff_hadamard8_diff8x8_msa; + + c->hadamard8_diff[4] = ff_hadamard8_intra16_msa; + c->hadamard8_diff[5] = ff_hadamard8_intra8x8_msa; + + c->sad[0] = ff_pix_abs16_msa; + c->sad[1] = ff_pix_abs8_msa; + c->sse[0] = ff_sse16_msa; + c->sse[1] = ff_sse8_msa; + c->sse[2] = ff_sse4_msa; +#endif + } } diff --git a/libavcodec/mips/mpegaudiodsp_mips_float.c b/libavcodec/mips/mpegaudiodsp_mips_float.c index 481b69c10..ae130c752 100644 --- a/libavcodec/mips/mpegaudiodsp_mips_float.c +++ b/libavcodec/mips/mpegaudiodsp_mips_float.c @@ -287,9 +287,16 @@ static void ff_dct32_mips_float(float *out, const float *tab) val8 , val9 , val10, val11, val12, val13, val14, val15, val16, val17, val18, val19, val20, val21, val22, val23, val24, val25, val26, val27, val28, val29, val30, val31; - float fTmp1, fTmp2, fTmp3, fTmp4, fTmp5, fTmp6, fTmp7, fTmp8, - fTmp9, fTmp10, fTmp11; + float fTmp1, fTmp2, fTmp3, fTmp4, fTmp5, fTmp6, fTmp8, fTmp9; + float f1, f2, f3, f4, f5, f6, f7; + f1 = 0.50241928618815570551; + f2 = 0.50060299823519630134; + f3 = 10.19000812354805681150; + f4 = 5.10114861868916385802; + f5 = 0.67480834145500574602; + f6 = 0.74453627100229844977; + f7 = 0.50979557910415916894; /** * instructions are scheduled to minimize pipeline stall. */ @@ -298,149 +305,142 @@ static void ff_dct32_mips_float(float *out, const float *tab) "lwc1 %[fTmp2], 31*4(%[tab]) \n\t" "lwc1 %[fTmp3], 15*4(%[tab]) \n\t" "lwc1 %[fTmp4], 16*4(%[tab]) \n\t" - "li.s %[fTmp7], 0.50241928618815570551 \n\t" "add.s %[fTmp5], %[fTmp1], %[fTmp2] \n\t" "sub.s %[fTmp8], %[fTmp1], %[fTmp2] \n\t" "add.s %[fTmp6], %[fTmp3], %[fTmp4] \n\t" "sub.s %[fTmp9], %[fTmp3], %[fTmp4] \n\t" - "li.s %[fTmp10], 0.50060299823519630134 \n\t" - "li.s %[fTmp11], 10.19000812354805681150 \n\t" - "mul.s %[fTmp8], %[fTmp8], %[fTmp10] \n\t" + "mul.s %[fTmp8], %[fTmp8], %[f2] \n\t" "add.s %[val0], %[fTmp5], %[fTmp6] \n\t" "sub.s %[val15], %[fTmp5], %[fTmp6] \n\t" "lwc1 %[fTmp1], 7*4(%[tab]) \n\t" "lwc1 %[fTmp2], 24*4(%[tab]) \n\t" - "madd.s %[val16], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "nmsub.s %[val31], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "mul.s %[val15], %[val15], %[fTmp7] \n\t" + "madd.s %[val16], %[fTmp8], %[fTmp9], %[f3] \n\t" + "nmsub.s %[val31], %[fTmp8], %[fTmp9], %[f3] \n\t" + "mul.s %[val15], %[val15], %[f1] \n\t" "lwc1 %[fTmp3], 8*4(%[tab]) \n\t" "lwc1 %[fTmp4], 23*4(%[tab]) \n\t" "add.s %[fTmp5], %[fTmp1], %[fTmp2] \n\t" - "mul.s %[val31], %[val31], %[fTmp7] \n\t" + "mul.s %[val31], %[val31], %[f1] \n\t" "sub.s %[fTmp8], %[fTmp1], %[fTmp2] \n\t" "add.s %[fTmp6], %[fTmp3], %[fTmp4] \n\t" "sub.s %[fTmp9], %[fTmp3], %[fTmp4] \n\t" - "li.s %[fTmp7], 5.10114861868916385802 \n\t" - "li.s %[fTmp10], 0.67480834145500574602 \n\t" - "li.s %[fTmp11], 0.74453627100229844977 \n\t" "add.s %[val7], %[fTmp5], %[fTmp6] \n\t" "sub.s %[val8], %[fTmp5], %[fTmp6] \n\t" - "mul.s %[fTmp8], %[fTmp8], %[fTmp10] \n\t" - "li.s %[fTmp1], 0.50979557910415916894 \n\t" + "mul.s %[fTmp8], %[fTmp8], %[f5] \n\t" "sub.s %[fTmp2], %[val0], %[val7] \n\t" - "mul.s %[val8], %[val8], %[fTmp7] \n\t" - "madd.s %[val23], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "nmsub.s %[val24], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" + "mul.s %[val8], %[val8], %[f4] \n\t" + "madd.s %[val23], %[fTmp8], %[fTmp9], %[f6] \n\t" + "nmsub.s %[val24], %[fTmp8], %[fTmp9], %[f6] \n\t" "add.s %[val0], %[val0], %[val7] \n\t" - "mul.s %[val7], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val7], %[f7], %[fTmp2] \n\t" "sub.s %[fTmp2], %[val15], %[val8] \n\t" "add.s %[val8], %[val15], %[val8] \n\t" - "mul.s %[val24], %[val24], %[fTmp7] \n\t" + "mul.s %[val24], %[val24], %[f4] \n\t" "sub.s %[fTmp3], %[val16], %[val23] \n\t" "add.s %[val16], %[val16], %[val23] \n\t" - "mul.s %[val15], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val15], %[f7], %[fTmp2] \n\t" "sub.s %[fTmp4], %[val31], %[val24] \n\t" - "mul.s %[val23], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val23], %[f7], %[fTmp3] \n\t" "add.s %[val24], %[val31], %[val24] \n\t" - "mul.s %[val31], %[fTmp1], %[fTmp4] \n\t" + "mul.s %[val31], %[f7], %[fTmp4] \n\t" : [fTmp1] "=&f" (fTmp1), [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), [fTmp5] "=&f" (fTmp5), [fTmp6] "=&f" (fTmp6), - [fTmp7] "=&f" (fTmp7), [fTmp8] "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9), - [fTmp10] "=&f" (fTmp10), [fTmp11] "=&f" (fTmp11), - [val0] "=f" (val0), [val7] "=f" (val7), - [val8] "=f" (val8), [val15] "=f" (val15), - [val16] "=f" (val16), [val23] "=f" (val23), - [val24] "=f" (val24), [val31] "=f" (val31) - : [tab] "r" (tab) + [fTmp8] "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9), + [val0] "=&f" (val0), [val7] "=&f" (val7), + [val8] "=&f" (val8), [val15] "=&f" (val15), + [val16] "=&f" (val16), [val23] "=&f" (val23), + [val24] "=&f" (val24), [val31] "=&f" (val31) + : [tab] "r" (tab), [f1]"f"(f1), [f2]"f"(f2), [f3]"f"(f3), + [f4]"f"(f4), [f5]"f"(f5), [f6]"f"(f6), [f7]"f"(f7) : "memory" ); + f1 = 0.64682178335999012954; + f2 = 0.53104259108978417447; + f3 = 1.48416461631416627724; + f4 = 0.78815462345125022473; + f5 = 0.55310389603444452782; + f6 = 1.16943993343288495515; + f7 = 2.56291544774150617881; __asm__ volatile ( "lwc1 %[fTmp1], 3*4(%[tab]) \n\t" "lwc1 %[fTmp2], 28*4(%[tab]) \n\t" "lwc1 %[fTmp3], 12*4(%[tab]) \n\t" "lwc1 %[fTmp4], 19*4(%[tab]) \n\t" - "li.s %[fTmp7], 0.64682178335999012954 \n\t" "add.s %[fTmp5], %[fTmp1], %[fTmp2] \n\t" "sub.s %[fTmp8], %[fTmp1], %[fTmp2] \n\t" "add.s %[fTmp6], %[fTmp3], %[fTmp4] \n\t" "sub.s %[fTmp9], %[fTmp3], %[fTmp4] \n\t" - "li.s %[fTmp10], 0.53104259108978417447 \n\t" - "li.s %[fTmp11], 1.48416461631416627724 \n\t" - "mul.s %[fTmp8], %[fTmp8], %[fTmp10] \n\t" + "mul.s %[fTmp8], %[fTmp8], %[f2] \n\t" "add.s %[val3], %[fTmp5], %[fTmp6] \n\t" "sub.s %[val12], %[fTmp5], %[fTmp6] \n\t" "lwc1 %[fTmp1], 4*4(%[tab]) \n\t" "lwc1 %[fTmp2], 27*4(%[tab]) \n\t" - "madd.s %[val19], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "nmsub.s %[val28], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "mul.s %[val12], %[val12], %[fTmp7] \n\t" + "madd.s %[val19], %[fTmp8], %[fTmp9], %[f3] \n\t" + "nmsub.s %[val28], %[fTmp8], %[fTmp9], %[f3] \n\t" + "mul.s %[val12], %[val12], %[f1] \n\t" "lwc1 %[fTmp3], 11*4(%[tab]) \n\t" "lwc1 %[fTmp4], 20*4(%[tab]) \n\t" "add.s %[fTmp5], %[fTmp1], %[fTmp2] \n\t" - "mul.s %[val28], %[val28], %[fTmp7] \n\t" + "mul.s %[val28], %[val28], %[f1] \n\t" "sub.s %[fTmp8], %[fTmp1], %[fTmp2] \n\t" - "li.s %[fTmp7], 0.78815462345125022473 \n\t" "add.s %[fTmp6], %[fTmp3], %[fTmp4] \n\t" "sub.s %[fTmp9], %[fTmp3], %[fTmp4] \n\t" - "li.s %[fTmp10], 0.55310389603444452782 \n\t" - "li.s %[fTmp11], 1.16943993343288495515 \n\t" - "mul.s %[fTmp8], %[fTmp8], %[fTmp10] \n\t" + "mul.s %[fTmp8], %[fTmp8], %[f5] \n\t" "add.s %[val4], %[fTmp5], %[fTmp6] \n\t" "sub.s %[val11], %[fTmp5], %[fTmp6] \n\t" - "li.s %[fTmp1], 2.56291544774150617881 \n\t" - "madd.s %[val20], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "nmsub.s %[val27], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "mul.s %[val11], %[val11], %[fTmp7] \n\t" + "madd.s %[val20], %[fTmp8], %[fTmp9], %[f6] \n\t" + "nmsub.s %[val27], %[fTmp8], %[fTmp9], %[f6] \n\t" + "mul.s %[val11], %[val11], %[f4] \n\t" "sub.s %[fTmp2], %[val3], %[val4] \n\t" "add.s %[val3], %[val3], %[val4] \n\t" "sub.s %[fTmp4], %[val19], %[val20] \n\t" - "mul.s %[val27], %[val27], %[fTmp7] \n\t" + "mul.s %[val27], %[val27], %[f4] \n\t" "sub.s %[fTmp3], %[val12], %[val11] \n\t" - "mul.s %[val4], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val4], %[f7], %[fTmp2] \n\t" "add.s %[val11], %[val12], %[val11] \n\t" "add.s %[val19], %[val19], %[val20] \n\t" - "mul.s %[val20], %[fTmp1], %[fTmp4] \n\t" - "mul.s %[val12], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val20], %[f7], %[fTmp4] \n\t" + "mul.s %[val12], %[f7], %[fTmp3] \n\t" "sub.s %[fTmp2], %[val28], %[val27] \n\t" "add.s %[val27], %[val28], %[val27] \n\t" - "mul.s %[val28], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val28], %[f7], %[fTmp2] \n\t" : [fTmp1] "=&f" (fTmp1), [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), [fTmp5] "=&f" (fTmp5), [fTmp6] "=&f" (fTmp6), - [fTmp7] "=&f" (fTmp7), [fTmp8] "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9), - [fTmp10] "=&f" (fTmp10), [fTmp11] "=&f" (fTmp11), - [val3] "=f" (val3), [val4] "=f" (val4), - [val11] "=f" (val11), [val12] "=f" (val12), - [val19] "=f" (val19), [val20] "=f" (val20), - [val27] "=f" (val27), [val28] "=f" (val28) - : [tab] "r" (tab) + [fTmp8] "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9), + [val3] "=&f" (val3), [val4] "=&f" (val4), + [val11] "=&f" (val11), [val12] "=&f" (val12), + [val19] "=&f" (val19), [val20] "=&f" (val20), + [val27] "=&f" (val27), [val28] "=&f" (val28) + : [tab] "r" (tab), [f1]"f"(f1), [f2]"f"(f2), [f3]"f"(f3), + [f4]"f"(f4), [f5]"f"(f5), [f6]"f"(f6), [f7]"f"(f7) : "memory" ); + f1 = 0.54119610014619698439; __asm__ volatile ( - "li.s %[fTmp1], 0.54119610014619698439 \n\t" "sub.s %[fTmp2], %[val0], %[val3] \n\t" "add.s %[val0], %[val0], %[val3] \n\t" "sub.s %[fTmp3], %[val7], %[val4] \n\t" "add.s %[val4], %[val7], %[val4] \n\t" "sub.s %[fTmp4], %[val8], %[val11] \n\t" - "mul.s %[val3], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val3], %[f1], %[fTmp2] \n\t" "add.s %[val8], %[val8], %[val11] \n\t" - "mul.s %[val7], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val7], %[f1], %[fTmp3] \n\t" "sub.s %[fTmp2], %[val15], %[val12] \n\t" - "mul.s %[val11], %[fTmp1], %[fTmp4] \n\t" + "mul.s %[val11], %[f1], %[fTmp4] \n\t" "add.s %[val12], %[val15], %[val12] \n\t" - "mul.s %[val15], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val15], %[f1], %[fTmp2] \n\t" - : [val0] "+f" (val0), [val3] "+f" (val3), - [val4] "+f" (val4), [val7] "+f" (val7), - [val8] "+f" (val8), [val11] "+f" (val11), - [val12] "+f" (val12), [val15] "+f" (val15), - [fTmp1] "=f" (fTmp1), [fTmp2] "=&f" (fTmp2), + : [val0] "+&f" (val0), [val3] "+&f" (val3), + [val4] "+&f" (val4), [val7] "+&f" (val7), + [val8] "+&f" (val8), [val11] "+&f" (val11), + [val12] "+&f" (val12), [val15] "+&f" (val15), + [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4) - : + : [f1] "f" (f1) ); __asm__ volatile ( @@ -449,169 +449,169 @@ static void ff_dct32_mips_float(float *out, const float *tab) "sub.s %[fTmp3], %[val23], %[val20] \n\t" "add.s %[val20], %[val23], %[val20] \n\t" "sub.s %[fTmp4], %[val24], %[val27] \n\t" - "mul.s %[val19], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val19], %[f1], %[fTmp2] \n\t" "add.s %[val24], %[val24], %[val27] \n\t" - "mul.s %[val23], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val23], %[f1], %[fTmp3] \n\t" "sub.s %[fTmp2], %[val31], %[val28] \n\t" - "mul.s %[val27], %[fTmp1], %[fTmp4] \n\t" + "mul.s %[val27], %[f1], %[fTmp4] \n\t" "add.s %[val28], %[val31], %[val28] \n\t" - "mul.s %[val31], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val31], %[f1], %[fTmp2] \n\t" : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), - [val16] "+f" (val16), [val19] "+f" (val19), [val20] "+f" (val20), - [val23] "+f" (val23), [val24] "+f" (val24), [val27] "+f" (val27), - [val28] "+f" (val28), [val31] "+f" (val31) - : [fTmp1] "f" (fTmp1) + [val16] "+&f" (val16), [val19] "+&f" (val19), [val20] "+&f" (val20), + [val23] "+&f" (val23), [val24] "+&f" (val24), [val27] "+&f" (val27), + [val28] "+&f" (val28), [val31] "+&f" (val31) + : [f1] "f" (f1) ); + f1 = 0.52249861493968888062; + f2 = 0.50547095989754365998; + f3 = 3.40760841846871878570; + f4 = 1.72244709823833392782; + f5 = 0.62250412303566481615; + f6 = 0.83934964541552703873; + f7 = 0.60134488693504528054; __asm__ volatile ( "lwc1 %[fTmp1], 1*4(%[tab]) \n\t" "lwc1 %[fTmp2], 30*4(%[tab]) \n\t" "lwc1 %[fTmp3], 14*4(%[tab]) \n\t" "lwc1 %[fTmp4], 17*4(%[tab]) \n\t" - "li.s %[fTmp7], 0.52249861493968888062 \n\t" "add.s %[fTmp5], %[fTmp1], %[fTmp2] \n\t" "sub.s %[fTmp8], %[fTmp1], %[fTmp2] \n\t" "add.s %[fTmp6], %[fTmp3], %[fTmp4] \n\t" "sub.s %[fTmp9], %[fTmp3], %[fTmp4] \n\t" - "li.s %[fTmp10], 0.50547095989754365998 \n\t" - "li.s %[fTmp11], 3.40760841846871878570 \n\t" - "mul.s %[fTmp8], %[fTmp8], %[fTmp10] \n\t" + "mul.s %[fTmp8], %[fTmp8], %[f2] \n\t" "add.s %[val1], %[fTmp5], %[fTmp6] \n\t" "sub.s %[val14], %[fTmp5], %[fTmp6] \n\t" "lwc1 %[fTmp1], 6*4(%[tab]) \n\t" "lwc1 %[fTmp2], 25*4(%[tab]) \n\t" - "madd.s %[val17], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "nmsub.s %[val30], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "mul.s %[val14], %[val14], %[fTmp7] \n\t" + "madd.s %[val17], %[fTmp8], %[fTmp9], %[f3] \n\t" + "nmsub.s %[val30], %[fTmp8], %[fTmp9], %[f3] \n\t" + "mul.s %[val14], %[val14], %[f1] \n\t" "lwc1 %[fTmp3], 9*4(%[tab]) \n\t" "lwc1 %[fTmp4], 22*4(%[tab]) \n\t" "add.s %[fTmp5], %[fTmp1], %[fTmp2] \n\t" - "mul.s %[val30], %[val30], %[fTmp7] \n\t" + "mul.s %[val30], %[val30], %[f1] \n\t" "sub.s %[fTmp8], %[fTmp1], %[fTmp2] \n\t" "add.s %[fTmp6], %[fTmp3], %[fTmp4] \n\t" "sub.s %[fTmp9], %[fTmp3], %[fTmp4] \n\t" - "li.s %[fTmp7], 1.72244709823833392782 \n\t" - "li.s %[fTmp10], 0.62250412303566481615 \n\t" - "li.s %[fTmp11], 0.83934964541552703873 \n\t" "add.s %[val6], %[fTmp5], %[fTmp6] \n\t" "sub.s %[val9], %[fTmp5], %[fTmp6] \n\t" - "mul.s %[fTmp8], %[fTmp8], %[fTmp10] \n\t" - "li.s %[fTmp1], 0.60134488693504528054 \n\t" + "mul.s %[fTmp8], %[fTmp8], %[f5] \n\t" "sub.s %[fTmp2], %[val1], %[val6] \n\t" "add.s %[val1], %[val1], %[val6] \n\t" - "mul.s %[val9], %[val9], %[fTmp7] \n\t" - "madd.s %[val22], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "nmsub.s %[val25], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "mul.s %[val6], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val9], %[val9], %[f4] \n\t" + "madd.s %[val22], %[fTmp8], %[fTmp9], %[f6] \n\t" + "nmsub.s %[val25], %[fTmp8], %[fTmp9], %[f6] \n\t" + "mul.s %[val6], %[f7], %[fTmp2] \n\t" "sub.s %[fTmp2], %[val14], %[val9] \n\t" "add.s %[val9], %[val14], %[val9] \n\t" - "mul.s %[val25], %[val25], %[fTmp7] \n\t" + "mul.s %[val25], %[val25], %[f4] \n\t" "sub.s %[fTmp3], %[val17], %[val22] \n\t" "add.s %[val17], %[val17], %[val22] \n\t" - "mul.s %[val14], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val14], %[f7], %[fTmp2] \n\t" "sub.s %[fTmp2], %[val30], %[val25] \n\t" - "mul.s %[val22], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val22], %[f7], %[fTmp3] \n\t" "add.s %[val25], %[val30], %[val25] \n\t" - "mul.s %[val30], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val30], %[f7], %[fTmp2] \n\t" : [fTmp1] "=&f" (fTmp1), [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), [fTmp5] "=&f" (fTmp5), [fTmp6] "=&f" (fTmp6), - [fTmp7] "=&f" (fTmp7), [fTmp8] "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9), - [fTmp10] "=&f" (fTmp10), [fTmp11] "=&f" (fTmp11), - [val1] "=f" (val1), [val6] "=f" (val6), - [val9] "=f" (val9), [val14] "=f" (val14), - [val17] "=f" (val17), [val22] "=f" (val22), - [val25] "=f" (val25), [val30] "=f" (val30) - : [tab] "r" (tab) + [fTmp8] "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9), + [val1] "=&f" (val1), [val6] "=&f" (val6), + [val9] "=&f" (val9), [val14] "=&f" (val14), + [val17] "=&f" (val17), [val22] "=&f" (val22), + [val25] "=&f" (val25), [val30] "=&f" (val30) + : [tab] "r" (tab), [f1]"f"(f1), [f2]"f"(f2), [f3]"f"(f3), + [f4]"f"(f4), [f5]"f"(f5), [f6]"f"(f6), [f7]"f"(f7) : "memory" ); + f1 = 0.56694403481635770368; + f2 = 0.51544730992262454697; + f3 = 2.05778100995341155085; + f4 = 1.06067768599034747134; + f5 = 0.58293496820613387367; + f6 = 0.97256823786196069369; + f7 = 0.89997622313641570463; __asm__ volatile ( "lwc1 %[fTmp1], 2*4(%[tab]) \n\t" "lwc1 %[fTmp2], 29*4(%[tab]) \n\t" "lwc1 %[fTmp3], 13*4(%[tab]) \n\t" "lwc1 %[fTmp4], 18*4(%[tab]) \n\t" - "li.s %[fTmp7], 0.56694403481635770368 \n\t" "add.s %[fTmp5], %[fTmp1], %[fTmp2] \n\t" "sub.s %[fTmp8], %[fTmp1], %[fTmp2] \n\t" "add.s %[fTmp6], %[fTmp3], %[fTmp4] \n\t" "sub.s %[fTmp9], %[fTmp3], %[fTmp4] \n\t" - "li.s %[fTmp10], 0.51544730992262454697 \n\t" - "li.s %[fTmp11], 2.05778100995341155085 \n\t" - "mul.s %[fTmp8], %[fTmp8], %[fTmp10] \n\t" + "mul.s %[fTmp8], %[fTmp8], %[f2] \n\t" "add.s %[val2], %[fTmp5], %[fTmp6] \n\t" "sub.s %[val13], %[fTmp5], %[fTmp6] \n\t" "lwc1 %[fTmp1], 5*4(%[tab]) \n\t" "lwc1 %[fTmp2], 26*4(%[tab]) \n\t" - "madd.s %[val18], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "nmsub.s %[val29], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "mul.s %[val13], %[val13], %[fTmp7] \n\t" + "madd.s %[val18], %[fTmp8], %[fTmp9], %[f3] \n\t" + "nmsub.s %[val29], %[fTmp8], %[fTmp9], %[f3] \n\t" + "mul.s %[val13], %[val13], %[f1] \n\t" "lwc1 %[fTmp3], 10*4(%[tab]) \n\t" "lwc1 %[fTmp4], 21*4(%[tab]) \n\t" - "mul.s %[val29], %[val29], %[fTmp7] \n\t" + "mul.s %[val29], %[val29], %[f1] \n\t" "add.s %[fTmp5], %[fTmp1], %[fTmp2] \n\t" "sub.s %[fTmp8], %[fTmp1], %[fTmp2] \n\t" "add.s %[fTmp6], %[fTmp3], %[fTmp4] \n\t" "sub.s %[fTmp9], %[fTmp3], %[fTmp4] \n\t" - "li.s %[fTmp7], 1.06067768599034747134 \n\t" - "li.s %[fTmp10], 0.58293496820613387367 \n\t" - "li.s %[fTmp11], 0.97256823786196069369 \n\t" "add.s %[val5], %[fTmp5], %[fTmp6] \n\t" "sub.s %[val10], %[fTmp5], %[fTmp6] \n\t" - "mul.s %[fTmp8], %[fTmp8], %[fTmp10] \n\t" - "li.s %[fTmp1], 0.89997622313641570463 \n\t" + "mul.s %[fTmp8], %[fTmp8], %[f5] \n\t" "sub.s %[fTmp2], %[val2], %[val5] \n\t" - "mul.s %[val10], %[val10], %[fTmp7] \n\t" - "madd.s %[val21], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" - "nmsub.s %[val26], %[fTmp8], %[fTmp9], %[fTmp11] \n\t" + "mul.s %[val10], %[val10], %[f4] \n\t" + "madd.s %[val21], %[fTmp8], %[fTmp9], %[f6] \n\t" + "nmsub.s %[val26], %[fTmp8], %[fTmp9], %[f6] \n\t" "add.s %[val2], %[val2], %[val5] \n\t" - "mul.s %[val5], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val5], %[f7], %[fTmp2] \n\t" "sub.s %[fTmp3], %[val13], %[val10] \n\t" "add.s %[val10], %[val13], %[val10] \n\t" - "mul.s %[val26], %[val26], %[fTmp7] \n\t" + "mul.s %[val26], %[val26], %[f4] \n\t" "sub.s %[fTmp4], %[val18], %[val21] \n\t" "add.s %[val18], %[val18], %[val21] \n\t" - "mul.s %[val13], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val13], %[f7], %[fTmp3] \n\t" "sub.s %[fTmp2], %[val29], %[val26] \n\t" "add.s %[val26], %[val29], %[val26] \n\t" - "mul.s %[val21], %[fTmp1], %[fTmp4] \n\t" - "mul.s %[val29], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val21], %[f7], %[fTmp4] \n\t" + "mul.s %[val29], %[f7], %[fTmp2] \n\t" : [fTmp1] "=&f" (fTmp1), [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), [fTmp5] "=&f" (fTmp5), [fTmp6] "=&f" (fTmp6), - [fTmp7] "=&f" (fTmp7), [fTmp8] "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9), - [fTmp10] "=&f" (fTmp10), [fTmp11] "=&f" (fTmp11), - [val2] "=f" (val2), [val5] "=f" (val5), - [val10] "=f" (val10), [val13] "=f" (val13), - [val18] "=f" (val18), [val21] "=f" (val21), - [val26] "=f" (val26), [val29] "=f" (val29) - : [tab] "r" (tab) + [fTmp8] "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9), + [val2] "=&f" (val2), [val5] "=&f" (val5), + [val10] "=&f" (val10), [val13] "=&f" (val13), + [val18] "=&f" (val18), [val21] "=&f" (val21), + [val26] "=&f" (val26), [val29] "=&f" (val29) + : [tab] "r" (tab), [f1]"f"(f1), [f2]"f"(f2), [f3]"f"(f3), + [f4]"f"(f4), [f5]"f"(f5), [f6]"f"(f6), [f7]"f"(f7) : "memory" ); + f1 = 1.30656296487637652785; __asm__ volatile ( - "li.s %[fTmp1], 1.30656296487637652785 \n\t" "sub.s %[fTmp2], %[val1], %[val2] \n\t" "add.s %[val1], %[val1], %[val2] \n\t" "sub.s %[fTmp3], %[val6], %[val5] \n\t" "add.s %[val5], %[val6], %[val5] \n\t" "sub.s %[fTmp4], %[val9], %[val10] \n\t" - "mul.s %[val2], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val2], %[f1], %[fTmp2] \n\t" "add.s %[val9], %[val9], %[val10] \n\t" - "mul.s %[val6], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val6], %[f1], %[fTmp3] \n\t" "sub.s %[fTmp2], %[val14], %[val13] \n\t" - "mul.s %[val10], %[fTmp1], %[fTmp4] \n\t" + "mul.s %[val10], %[f1], %[fTmp4] \n\t" "add.s %[val13], %[val14], %[val13] \n\t" - "mul.s %[val14], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val14], %[f1], %[fTmp2] \n\t" - : [fTmp1] "=f" (fTmp1), [fTmp2] "=&f" (fTmp2), + : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), - [val1] "+f" (val1), [val2] "+f" (val2), - [val5] "+f" (val5), [val6] "+f" (val6), - [val9] "+f" (val9), [val10] "+f" (val10), - [val13] "+f" (val13), [val14] "+f" (val14) - : + [val1] "+&f" (val1), [val2] "+&f" (val2), + [val5] "+&f" (val5), [val6] "+&f" (val6), + [val9] "+&f" (val9), [val10] "+&f" (val10), + [val13] "+&f" (val13), [val14] "+&f" (val14) + : [f1]"f"(f1) ); __asm__ volatile ( @@ -620,39 +620,39 @@ static void ff_dct32_mips_float(float *out, const float *tab) "sub.s %[fTmp3], %[val22], %[val21] \n\t" "add.s %[val21], %[val22], %[val21] \n\t" "sub.s %[fTmp4], %[val25], %[val26] \n\t" - "mul.s %[val18], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val18], %[f1], %[fTmp2] \n\t" "add.s %[val25], %[val25], %[val26] \n\t" - "mul.s %[val22], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val22], %[f1], %[fTmp3] \n\t" "sub.s %[fTmp2], %[val30], %[val29] \n\t" - "mul.s %[val26], %[fTmp1], %[fTmp4] \n\t" + "mul.s %[val26], %[f1], %[fTmp4] \n\t" "add.s %[val29], %[val30], %[val29] \n\t" - "mul.s %[val30], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val30], %[f1], %[fTmp2] \n\t" : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), - [val17] "+f" (val17), [val18] "+f" (val18), [val21] "+f" (val21), - [val22] "+f" (val22), [val25] "+f" (val25), [val26] "+f" (val26), - [val29] "+f" (val29), [val30] "+f" (val30) - : [fTmp1] "f" (fTmp1) + [val17] "+&f" (val17), [val18] "+&f" (val18), [val21] "+&f" (val21), + [val22] "+&f" (val22), [val25] "+&f" (val25), [val26] "+&f" (val26), + [val29] "+&f" (val29), [val30] "+&f" (val30) + : [f1] "f" (f1) ); + f1 = 0.70710678118654752439; __asm__ volatile ( - "li.s %[fTmp1], 0.70710678118654752439 \n\t" "sub.s %[fTmp2], %[val0], %[val1] \n\t" "add.s %[val0], %[val0], %[val1] \n\t" "sub.s %[fTmp3], %[val3], %[val2] \n\t" "add.s %[val2], %[val3], %[val2] \n\t" "sub.s %[fTmp4], %[val4], %[val5] \n\t" - "mul.s %[val1], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val1], %[f1], %[fTmp2] \n\t" "swc1 %[val0], 0(%[out]) \n\t" - "mul.s %[val3], %[fTmp3], %[fTmp1] \n\t" + "mul.s %[val3], %[fTmp3], %[f1] \n\t" "add.s %[val4], %[val4], %[val5] \n\t" - "mul.s %[val5], %[fTmp1], %[fTmp4] \n\t" + "mul.s %[val5], %[f1], %[fTmp4] \n\t" "swc1 %[val1], 16*4(%[out]) \n\t" "sub.s %[fTmp2], %[val7], %[val6] \n\t" "add.s %[val2], %[val2], %[val3] \n\t" "swc1 %[val3], 24*4(%[out]) \n\t" "add.s %[val6], %[val7], %[val6] \n\t" - "mul.s %[val7], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val7], %[f1], %[fTmp2] \n\t" "swc1 %[val2], 8*4(%[out]) \n\t" "add.s %[val6], %[val6], %[val7] \n\t" "swc1 %[val7], 28*4(%[out]) \n\t" @@ -663,13 +663,13 @@ static void ff_dct32_mips_float(float *out, const float *tab) "swc1 %[val5], 20*4(%[out]) \n\t" "swc1 %[val6], 12*4(%[out]) \n\t" - : [fTmp1] "=f" (fTmp1), [fTmp2] "=&f" (fTmp2), + : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), - [val0] "+f" (val0), [val1] "+f" (val1), - [val2] "+f" (val2), [val3] "+f" (val3), - [val4] "+f" (val4), [val5] "+f" (val5), - [val6] "+f" (val6), [val7] "+f" (val7) - : [out] "r" (out) + [val0] "+&f" (val0), [val1] "+&f" (val1), + [val2] "+&f" (val2), [val3] "+&f" (val3), + [val4] "+&f" (val4), [val5] "+&f" (val5), + [val6] "+&f" (val6), [val7] "+&f" (val7) + : [out] "r" (out), [f1]"f"(f1) ); __asm__ volatile ( @@ -678,14 +678,14 @@ static void ff_dct32_mips_float(float *out, const float *tab) "sub.s %[fTmp3], %[val11], %[val10] \n\t" "add.s %[val10], %[val11], %[val10] \n\t" "sub.s %[fTmp4], %[val12], %[val13] \n\t" - "mul.s %[val9], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val9], %[f1], %[fTmp2] \n\t" "add.s %[val12], %[val12], %[val13] \n\t" - "mul.s %[val11], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val11], %[f1], %[fTmp3] \n\t" "sub.s %[fTmp2], %[val15], %[val14] \n\t" - "mul.s %[val13], %[fTmp1], %[fTmp4] \n\t" + "mul.s %[val13], %[f1], %[fTmp4] \n\t" "add.s %[val14], %[val15], %[val14] \n\t" "add.s %[val10], %[val10], %[val11] \n\t" - "mul.s %[val15], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val15], %[f1], %[fTmp2] \n\t" "add.s %[val14], %[val14], %[val15] \n\t" "add.s %[val12], %[val12], %[val14] \n\t" "add.s %[val14], %[val14], %[val13] \n\t" @@ -707,10 +707,10 @@ static void ff_dct32_mips_float(float *out, const float *tab) "swc1 %[val15], 30*4(%[out]) \n\t" : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), - [val8] "+f" (val8), [val9] "+f" (val9), [val10] "+f" (val10), - [val11] "+f" (val11), [val12] "+f" (val12), [val13] "+f" (val13), - [val14] "+f" (val14), [val15] "+f" (val15) - : [fTmp1] "f" (fTmp1), [out] "r" (out) + [val8] "+&f" (val8), [val9] "+&f" (val9), [val10] "+&f" (val10), + [val11] "+&f" (val11), [val12] "+&f" (val12), [val13] "+&f" (val13), + [val14] "+&f" (val14), [val15] "+&f" (val15) + : [f1] "f" (f1), [out] "r" (out) ); __asm__ volatile ( @@ -719,24 +719,24 @@ static void ff_dct32_mips_float(float *out, const float *tab) "sub.s %[fTmp3], %[val19], %[val18] \n\t" "add.s %[val18], %[val19], %[val18] \n\t" "sub.s %[fTmp4], %[val20], %[val21] \n\t" - "mul.s %[val17], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val17], %[f1], %[fTmp2] \n\t" "add.s %[val20], %[val20], %[val21] \n\t" - "mul.s %[val19], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val19], %[f1], %[fTmp3] \n\t" "sub.s %[fTmp2], %[val23], %[val22] \n\t" - "mul.s %[val21], %[fTmp1], %[fTmp4] \n\t" + "mul.s %[val21], %[f1], %[fTmp4] \n\t" "add.s %[val22], %[val23], %[val22] \n\t" "add.s %[val18], %[val18], %[val19] \n\t" - "mul.s %[val23], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val23], %[f1], %[fTmp2] \n\t" "add.s %[val22], %[val22], %[val23] \n\t" "add.s %[val20], %[val20], %[val22] \n\t" "add.s %[val22], %[val22], %[val21] \n\t" "add.s %[val21], %[val21], %[val23] \n\t" : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), - [val16] "+f" (val16), [val17] "+f" (val17), [val18] "+f" (val18), - [val19] "+f" (val19), [val20] "+f" (val20), [val21] "+f" (val21), - [val22] "+f" (val22), [val23] "+f" (val23) - : [fTmp1] "f" (fTmp1) + [val16] "+&f" (val16), [val17] "+&f" (val17), [val18] "+&f" (val18), + [val19] "+&f" (val19), [val20] "+&f" (val20), [val21] "+&f" (val21), + [val22] "+&f" (val22), [val23] "+&f" (val23) + : [f1] "f" (f1) ); __asm__ volatile ( @@ -745,14 +745,14 @@ static void ff_dct32_mips_float(float *out, const float *tab) "sub.s %[fTmp3], %[val27], %[val26] \n\t" "add.s %[val26], %[val27], %[val26] \n\t" "sub.s %[fTmp4], %[val28], %[val29] \n\t" - "mul.s %[val25], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val25], %[f1], %[fTmp2] \n\t" "add.s %[val28], %[val28], %[val29] \n\t" - "mul.s %[val27], %[fTmp1], %[fTmp3] \n\t" + "mul.s %[val27], %[f1], %[fTmp3] \n\t" "sub.s %[fTmp2], %[val31], %[val30] \n\t" - "mul.s %[val29], %[fTmp1], %[fTmp4] \n\t" + "mul.s %[val29], %[f1], %[fTmp4] \n\t" "add.s %[val30], %[val31], %[val30] \n\t" "add.s %[val26], %[val26], %[val27] \n\t" - "mul.s %[val31], %[fTmp1], %[fTmp2] \n\t" + "mul.s %[val31], %[f1], %[fTmp2] \n\t" "add.s %[val30], %[val30], %[val31] \n\t" "add.s %[val28], %[val28], %[val30] \n\t" "add.s %[val30], %[val30], %[val29] \n\t" @@ -766,10 +766,10 @@ static void ff_dct32_mips_float(float *out, const float *tab) "add.s %[val27], %[val27], %[val31] \n\t" : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4), - [val24] "+f" (val24), [val25] "+f" (val25), [val26] "+f" (val26), - [val27] "+f" (val27), [val28] "+f" (val28), [val29] "+f" (val29), - [val30] "+f" (val30), [val31] "+f" (val31) - : [fTmp1] "f" (fTmp1) + [val24] "+&f" (val24), [val25] "+&f" (val25), [val26] "+&f" (val26), + [val27] "+&f" (val27), [val28] "+&f" (val28), [val29] "+&f" (val29), + [val30] "+&f" (val30), [val31] "+&f" (val31) + : [f1] "f" (f1) ); out[ 1] = val16 + val24; @@ -797,7 +797,7 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) /* temporary variables */ float in1, in2, in3, in4, in5, in6; float out1, out2, out3, out4, out5; - float c1, c2, c3, c4, c5, c6, c7, c8, c9; + float f1, f2, f3, f4, f5, f6, f7, f8, f9; /** * all loops are unrolled totally, and instructions are scheduled to @@ -881,33 +881,36 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) ); /* loop 3 */ + f1 = 0.5; + f2 = 0.93969262078590838405; + f3 = -0.76604444311897803520; + f4 = -0.17364817766693034885; + f5 = -0.86602540378443864676; + f6 = 0.98480775301220805936; + f7 = -0.34202014332566873304; + f8 = 0.86602540378443864676; + f9 = -0.64278760968653932632; __asm__ volatile ( - "li.s %[c1], 0.5 \t\n" "lwc1 %[in1], 8*4(%[in]) \t\n" "lwc1 %[in2], 16*4(%[in]) \t\n" "lwc1 %[in3], 4*4(%[in]) \t\n" "lwc1 %[in4], 0(%[in]) \t\n" "lwc1 %[in5], 12*4(%[in]) \t\n" - "li.s %[c2], 0.93969262078590838405 \t\n" "add.s %[t2], %[in1], %[in2] \t\n" "add.s %[t0], %[in1], %[in3] \t\n" - "li.s %[c3], -0.76604444311897803520 \t\n" - "madd.s %[t3], %[in4], %[in5], %[c1] \t\n" + "madd.s %[t3], %[in4], %[in5], %[f1] \t\n" "sub.s %[t1], %[in4], %[in5] \t\n" "sub.s %[t2], %[t2], %[in3] \t\n" - "mul.s %[t0], %[t0], %[c2] \t\n" - "li.s %[c4], -0.17364817766693034885 \t\n" - "li.s %[c5], -0.86602540378443864676 \t\n" - "li.s %[c6], 0.98480775301220805936 \t\n" - "nmsub.s %[out1], %[t1], %[t2], %[c1] \t\n" + "mul.s %[t0], %[t0], %[f2] \t\n" + "nmsub.s %[out1], %[t1], %[t2], %[f1] \t\n" "add.s %[out2], %[t1], %[t2] \t\n" "add.s %[t2], %[in2], %[in3] \t\n" "sub.s %[t1], %[in1], %[in2] \t\n" "sub.s %[out3], %[t3], %[t0] \t\n" "swc1 %[out1], 6*4(%[tmp]) \t\n" "swc1 %[out2], 16*4(%[tmp]) \t\n" - "mul.s %[t2], %[t2], %[c3] \t\n" - "mul.s %[t1], %[t1], %[c4] \t\n" + "mul.s %[t2], %[t2], %[f3] \t\n" + "mul.s %[t1], %[t1], %[f4] \t\n" "add.s %[out1], %[t3], %[t0] \t\n" "lwc1 %[in1], 10*4(%[in]) \t\n" "lwc1 %[in2], 14*4(%[in]) \t\n" @@ -923,19 +926,16 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "add.s %[t2], %[in1], %[in3] \t\n" "sub.s %[t3], %[in1], %[in2] \t\n" "swc1 %[out2], 14*4(%[tmp]) \t\n" - "li.s %[c7], -0.34202014332566873304 \t\n" "sub.s %[out1], %[out1], %[in3] \t\n" - "mul.s %[t2], %[t2], %[c6] \t\n" - "mul.s %[t3], %[t3], %[c7] \t\n" - "li.s %[c8], 0.86602540378443864676 \t\n" - "mul.s %[t0], %[in4], %[c8] \t\n" - "mul.s %[out1], %[out1], %[c5] \t\n" + "mul.s %[t2], %[t2], %[f6] \t\n" + "mul.s %[t3], %[t3], %[f7] \t\n" + "mul.s %[t0], %[in4], %[f8] \t\n" + "mul.s %[out1], %[out1], %[f5] \t\n" "add.s %[t1], %[in2], %[in3] \t\n" - "li.s %[c9], -0.64278760968653932632 \t\n" "add.s %[out2], %[t2], %[t3] \t\n" "lwc1 %[in1], 9*4(%[in]) \t\n" "swc1 %[out1], 4*4(%[tmp]) \t\n" - "mul.s %[t1], %[t1], %[c9] \t\n" + "mul.s %[t1], %[t1], %[f9] \t\n" "lwc1 %[in2], 17*4(%[in]) \t\n" "add.s %[out2], %[out2], %[t0] \t\n" "lwc1 %[in3], 5*4(%[in]) \t\n" @@ -948,21 +948,21 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "sub.s %[out3], %[out3], %[t0] \t\n" "sub.s %[out1], %[out1], %[t0] \t\n" "add.s %[t0], %[in1], %[in3] \t\n" - "madd.s %[t3], %[in4], %[in5], %[c1] \t\n" + "madd.s %[t3], %[in4], %[in5], %[f1] \t\n" "sub.s %[t2], %[t2], %[in3] \t\n" "swc1 %[out3], 12*4(%[tmp]) \t\n" "swc1 %[out1], 8*4(%[tmp]) \t\n" "sub.s %[t1], %[in4], %[in5] \t\n" - "mul.s %[t0], %[t0], %[c2] \t\n" - "nmsub.s %[out1], %[t1], %[t2], %[c1] \t\n" + "mul.s %[t0], %[t0], %[f2] \t\n" + "nmsub.s %[out1], %[t1], %[t2], %[f1] \t\n" "add.s %[out2], %[t1], %[t2] \t\n" "add.s %[t2], %[in2], %[in3] \t\n" "sub.s %[t1], %[in1], %[in2] \t\n" "sub.s %[out3], %[t3], %[t0] \t\n" "swc1 %[out1], 7*4(%[tmp]) \t\n" "swc1 %[out2], 17*4(%[tmp]) \t\n" - "mul.s %[t2], %[t2], %[c3] \t\n" - "mul.s %[t1], %[t1], %[c4] \t\n" + "mul.s %[t2], %[t2], %[f3] \t\n" + "mul.s %[t1], %[t1], %[f4] \t\n" "add.s %[out1], %[t3], %[t0] \t\n" "lwc1 %[in1], 11*4(%[in]) \t\n" "lwc1 %[in2], 15*4(%[in]) \t\n" @@ -978,14 +978,14 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "add.s %[t2], %[in1], %[in3] \t\n" "sub.s %[t3], %[in1], %[in2] \t\n" "swc1 %[out2], 15*4(%[tmp]) \t\n" - "mul.s %[t0], %[in4], %[c8] \t\n" + "mul.s %[t0], %[in4], %[f8] \t\n" "sub.s %[out3], %[out3], %[in3] \t\n" - "mul.s %[t2], %[t2], %[c6] \t\n" - "mul.s %[t3], %[t3], %[c7] \t\n" + "mul.s %[t2], %[t2], %[f6] \t\n" + "mul.s %[t3], %[t3], %[f7] \t\n" "add.s %[t1], %[in2], %[in3] \t\n" - "mul.s %[out3], %[out3], %[c5] \t\n" + "mul.s %[out3], %[out3], %[f5] \t\n" "add.s %[out1], %[t2], %[t3] \t\n" - "mul.s %[t1], %[t1], %[c9] \t\n" + "mul.s %[t1], %[t1], %[f9] \t\n" "swc1 %[out3], 5*4(%[tmp]) \t\n" "add.s %[out1], %[out1], %[t0] \t\n" "add.s %[out2], %[t2], %[t1] \t\n" @@ -1000,26 +1000,29 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) [t2] "=&f" (t2), [t3] "=&f" (t3), [in1] "=&f" (in1), [in2] "=&f" (in2), [in3] "=&f" (in3), [in4] "=&f" (in4), - [in5] "=&f" (in5), - [out1] "=&f" (out1), [out2] "=&f" (out2), - [out3] "=&f" (out3), - [c1] "=&f" (c1), [c2] "=&f" (c2), - [c3] "=&f" (c3), [c4] "=&f" (c4), - [c5] "=&f" (c5), [c6] "=&f" (c6), - [c7] "=&f" (c7), [c8] "=&f" (c8), - [c9] "=&f" (c9) - : [in] "r" (in), [tmp] "r" (tmp) + [in5] "=&f" (in5), [out1] "=&f" (out1), + [out2] "=&f" (out2), [out3] "=&f" (out3) + : [in] "r" (in), [tmp] "r" (tmp), [f1]"f"(f1), [f2]"f"(f2), + [f3]"f"(f3), [f4]"f"(f4), [f5]"f"(f5), [f6]"f"(f6), + [f7]"f"(f7), [f8]"f"(f8), [f9]"f"(f9) : "memory" ); /* loop 4 */ + f1 = 0.50190991877167369479; + f2 = 5.73685662283492756461; + f3 = 0.51763809020504152469; + f4 = 1.93185165257813657349; + f5 = 0.55168895948124587824; + f6 = 1.18310079157624925896; + f7 = 0.61038729438072803416; + f8 = 0.87172339781054900991; + f9 = 0.70710678118654752439; __asm__ volatile ( "lwc1 %[in1], 2*4(%[tmp]) \t\n" "lwc1 %[in2], 0(%[tmp]) \t\n" "lwc1 %[in3], 3*4(%[tmp]) \t\n" "lwc1 %[in4], 1*4(%[tmp]) \t\n" - "li.s %[c1], 0.50190991877167369479 \t\n" - "li.s %[c2], 5.73685662283492756461 \t\n" "add.s %[s0], %[in1], %[in2] \t\n" "sub.s %[s2], %[in1], %[in2] \t\n" "add.s %[s1], %[in3], %[in4] \t\n" @@ -1027,15 +1030,13 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "lwc1 %[in1], 9*4(%[win]) \t\n" "lwc1 %[in2], 4*9*4(%[buf]) \t\n" "lwc1 %[in3], 8*4(%[win]) \t\n" - "mul.s %[s1], %[s1], %[c1] \t\n" - "mul.s %[s3], %[s3], %[c2] \t\n" + "mul.s %[s1], %[s1], %[f1] \t\n" + "mul.s %[s3], %[s3], %[f2] \t\n" "lwc1 %[in4], 4*8*4(%[buf]) \t\n" "lwc1 %[in5], 29*4(%[win]) \t\n" "lwc1 %[in6], 28*4(%[win]) \t\n" "add.s %[t0], %[s0], %[s1] \t\n" "sub.s %[t1], %[s0], %[s1] \t\n" - "li.s %[c1], 0.51763809020504152469 \t\n" - "li.s %[c2], 1.93185165257813657349 \t\n" "mul.s %[out3], %[in5], %[t0] \t\n" "madd.s %[out1], %[in2], %[in1], %[t1] \t\n" "madd.s %[out2], %[in4], %[in3], %[t1] \t\n" @@ -1071,14 +1072,13 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "lwc1 %[in1], 10*4(%[win]) \t\n" "lwc1 %[in2], 4*10*4(%[buf]) \t\n" "lwc1 %[in3], 7*4(%[win]) \t\n" - "mul.s %[s1], %[s1], %[c1] \t\n" - "mul.s %[s3], %[s3], %[c2] \t\n" + "mul.s %[s1], %[s1], %[f3] \t\n" + "mul.s %[s3], %[s3], %[f4] \t\n" "add.s %[t0], %[s0], %[s1] \t\n" "sub.s %[t1], %[s0], %[s1] \t\n" "lwc1 %[in4], 4*7*4(%[buf]) \t\n" "lwc1 %[in5], 30*4(%[win]) \t\n" "lwc1 %[in6], 27*4(%[win]) \t\n" - "li.s %[c1], 0.55168895948124587824 \t\n" "madd.s %[out1], %[in2], %[in1], %[t1] \t\n" "madd.s %[out2], %[in4], %[in3], %[t1] \t\n" "mul.s %[out3], %[t0], %[in5] \t\n" @@ -1105,7 +1105,6 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "swc1 %[out2], 32*4(%[out]) \t\n" "swc1 %[out3], 4*16*4(%[buf]) \t\n" "swc1 %[out4], 4*1*4(%[buf]) \t\n" - "li.s %[c2], 1.18310079157624925896 \t\n" "add.s %[s0], %[in1], %[in2] \t\n" "sub.s %[s2], %[in1], %[in2] \t\n" "lwc1 %[in3], 11*4(%[tmp]) \t\n" @@ -1115,8 +1114,8 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "lwc1 %[in1], 11*4(%[win]) \t\n" "lwc1 %[in2], 4*11*4(%[buf]) \t\n" "lwc1 %[in3], 6*4(%[win]) \t\n" - "mul.s %[s1], %[s1], %[c1] \t\n" - "mul.s %[s3], %[s3], %[c2] \t\n" + "mul.s %[s1], %[s1], %[f5] \t\n" + "mul.s %[s3], %[s3], %[f6] \t\n" "lwc1 %[in4], 4*6*4(%[buf]) \t\n" "lwc1 %[in5], 31*4(%[win]) \t\n" "lwc1 %[in6], 26*4(%[win]) \t\n" @@ -1152,15 +1151,13 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "add.s %[s0], %[in1], %[in2] \t\n" "sub.s %[s2], %[in1], %[in2] \t\n" "lwc1 %[in4], 13*4(%[tmp]) \t\n" - "li.s %[c1], 0.61038729438072803416 \t\n" - "li.s %[c2], 0.87172339781054900991 \t\n" "add.s %[s1], %[in3], %[in4] \t\n" "sub.s %[s3], %[in3], %[in4] \t\n" "lwc1 %[in1], 12*4(%[win]) \t\n" "lwc1 %[in2], 4*12*4(%[buf]) \t\n" "lwc1 %[in3], 5*4(%[win]) \t\n" - "mul.s %[s1], %[s1], %[c1] \t\n" - "mul.s %[s3], %[s3], %[c2] \t\n" + "mul.s %[s1], %[s1], %[f7] \t\n" + "mul.s %[s3], %[s3], %[f8] \t\n" "lwc1 %[in4], 4*5*4(%[buf]) \t\n" "lwc1 %[in5], 32*4(%[win]) \t\n" "lwc1 %[in6], 25*4(%[win]) \t\n" @@ -1168,7 +1165,6 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "sub.s %[t1], %[s0], %[s1] \t\n" "lwc1 %[s0], 16*4(%[tmp]) \t\n" "lwc1 %[s1], 17*4(%[tmp]) \t\n" - "li.s %[c1], 0.70710678118654752439 \t\n" "mul.s %[out3], %[t0], %[in5] \t\n" "madd.s %[out1], %[in2], %[in1], %[t1] \t\n" "madd.s %[out2], %[in4], %[in3], %[t1] \t\n" @@ -1186,7 +1182,7 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "lwc1 %[in5], 34*4(%[win]) \t\n" "lwc1 %[in6], 23*4(%[win]) \t\n" "madd.s %[out1], %[in2], %[in1], %[t1] \t\n" - "mul.s %[s1], %[s1], %[c1] \t\n" + "mul.s %[s1], %[s1], %[f9] \t\n" "madd.s %[out2], %[in4], %[in3], %[t1] \t\n" "mul.s %[out3], %[in5], %[t0] \t\n" "mul.s %[out4], %[in6], %[t0] \t\n" @@ -1211,18 +1207,18 @@ static void imdct36_mips_float(float *out, float *buf, float *in, float *win) "swc1 %[out3], 4*13*4(%[buf]) \t\n" "swc1 %[out4], 4*4*4(%[buf]) \t\n" - : [c1] "=&f" (c1), [c2] "=&f" (c2), - [in1] "=&f" (in1), [in2] "=&f" (in2), + : [in1] "=&f" (in1), [in2] "=&f" (in2), [in3] "=&f" (in3), [in4] "=&f" (in4), [in5] "=&f" (in5), [in6] "=&f" (in6), [out1] "=&f" (out1), [out2] "=&f" (out2), [out3] "=&f" (out3), [out4] "=&f" (out4), [t0] "=&f" (t0), [t1] "=&f" (t1), - [t2] "=&f" (t2), [t3] "=&f" (t3), [s0] "=&f" (s0), [s1] "=&f" (s1), [s2] "=&f" (s2), [s3] "=&f" (s3) : [tmp] "r" (tmp), [win] "r" (win), - [buf] "r" (buf), [out] "r" (out) + [buf] "r" (buf), [out] "r" (out), + [f1]"f"(f1), [f2]"f"(f2), [f3]"f"(f3), [f4]"f"(f4), + [f5]"f"(f5), [f6]"f"(f6), [f7]"f"(f7), [f8]"f"(f8), [f9]"f"(f9) : "memory" ); } diff --git a/libavcodec/mips/mpegvideo_init_mips.c b/libavcodec/mips/mpegvideo_init_mips.c index be7730814..bfda90bbc 100644 --- a/libavcodec/mips/mpegvideo_init_mips.c +++ b/libavcodec/mips/mpegvideo_init_mips.c @@ -18,41 +18,31 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "h263dsp_mips.h" #include "mpegvideo_mips.h" -#if HAVE_MSA -static av_cold void dct_unquantize_init_msa(MpegEncContext *s) -{ - s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_msa; - s->dct_unquantize_h263_inter = ff_dct_unquantize_h263_inter_msa; - if (!s->q_scale_type) - s->dct_unquantize_mpeg2_inter = ff_dct_unquantize_mpeg2_inter_msa; -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static av_cold void dct_unquantize_init_mmi(MpegEncContext *s) -{ - s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_mmi; - s->dct_unquantize_h263_inter = ff_dct_unquantize_h263_inter_mmi; - s->dct_unquantize_mpeg1_intra = ff_dct_unquantize_mpeg1_intra_mmi; - s->dct_unquantize_mpeg1_inter = ff_dct_unquantize_mpeg1_inter_mmi; - - if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT)) - if (!s->q_scale_type) - s->dct_unquantize_mpeg2_intra = ff_dct_unquantize_mpeg2_intra_mmi; - - s->denoise_dct= ff_denoise_dct_mmi; -} -#endif /* HAVE_MMI */ - av_cold void ff_mpv_common_init_mips(MpegEncContext *s) { -#if HAVE_MMI - dct_unquantize_init_mmi(s); -#endif /* HAVE_MMI */ -#if HAVE_MSA - dct_unquantize_init_msa(s); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_mmi; + s->dct_unquantize_h263_inter = ff_dct_unquantize_h263_inter_mmi; + s->dct_unquantize_mpeg1_intra = ff_dct_unquantize_mpeg1_intra_mmi; + s->dct_unquantize_mpeg1_inter = ff_dct_unquantize_mpeg1_inter_mmi; + + if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT)) + if (!s->q_scale_type) + s->dct_unquantize_mpeg2_intra = ff_dct_unquantize_mpeg2_intra_mmi; + + s->denoise_dct= ff_denoise_dct_mmi; + } + + if (have_msa(cpu_flags)) { + s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_msa; + s->dct_unquantize_h263_inter = ff_dct_unquantize_h263_inter_msa; + if (!s->q_scale_type) + s->dct_unquantize_mpeg2_inter = ff_dct_unquantize_mpeg2_inter_msa; + } } diff --git a/libavcodec/mips/mpegvideoencdsp_init_mips.c b/libavcodec/mips/mpegvideoencdsp_init_mips.c index 9bfe94e4c..71831a61a 100644 --- a/libavcodec/mips/mpegvideoencdsp_init_mips.c +++ b/libavcodec/mips/mpegvideoencdsp_init_mips.c @@ -18,23 +18,18 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "libavcodec/bit_depth_template.c" #include "h263dsp_mips.h" -#if HAVE_MSA -static av_cold void mpegvideoencdsp_init_msa(MpegvideoEncDSPContext *c, - AVCodecContext *avctx) -{ -#if BIT_DEPTH == 8 - c->pix_sum = ff_pix_sum_msa; -#endif -} -#endif // #if HAVE_MSA - av_cold void ff_mpegvideoencdsp_init_mips(MpegvideoEncDSPContext *c, AVCodecContext *avctx) { -#if HAVE_MSA - mpegvideoencdsp_init_msa(c, avctx); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_msa(cpu_flags)) { +#if BIT_DEPTH == 8 + c->pix_sum = ff_pix_sum_msa; +#endif + } } diff --git a/libavcodec/mips/pixblockdsp_init_mips.c b/libavcodec/mips/pixblockdsp_init_mips.c index fd0238d79..2e2d70953 100644 --- a/libavcodec/mips/pixblockdsp_init_mips.c +++ b/libavcodec/mips/pixblockdsp_init_mips.c @@ -19,51 +19,38 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "pixblockdsp_mips.h" -#if HAVE_MSA -static av_cold void pixblockdsp_init_msa(PixblockDSPContext *c, - AVCodecContext *avctx, - unsigned high_bit_depth) -{ - c->diff_pixels = ff_diff_pixels_msa; - - switch (avctx->bits_per_raw_sample) { - case 9: - case 10: - case 12: - case 14: - c->get_pixels = ff_get_pixels_16_msa; - break; - default: - if (avctx->bits_per_raw_sample <= 8 || avctx->codec_type != - AVMEDIA_TYPE_VIDEO) { - c->get_pixels = ff_get_pixels_8_msa; - } - break; - } -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static av_cold void pixblockdsp_init_mmi(PixblockDSPContext *c, - AVCodecContext *avctx, unsigned high_bit_depth) -{ - c->diff_pixels = ff_diff_pixels_mmi; - - if (!high_bit_depth || avctx->codec_type != AVMEDIA_TYPE_VIDEO) { - c->get_pixels = ff_get_pixels_8_mmi; - } -} -#endif /* HAVE_MMI */ - void ff_pixblockdsp_init_mips(PixblockDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth) { -#if HAVE_MMI - pixblockdsp_init_mmi(c, avctx, high_bit_depth); -#endif /* HAVE_MMI */ -#if HAVE_MSA - pixblockdsp_init_msa(c, avctx, high_bit_depth); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + c->diff_pixels = ff_diff_pixels_mmi; + + if (!high_bit_depth || avctx->codec_type != AVMEDIA_TYPE_VIDEO) { + c->get_pixels = ff_get_pixels_8_mmi; + } + } + + if (have_msa(cpu_flags)) { + c->diff_pixels = ff_diff_pixels_msa; + + switch (avctx->bits_per_raw_sample) { + case 9: + case 10: + case 12: + case 14: + c->get_pixels = ff_get_pixels_16_msa; + break; + default: + if (avctx->bits_per_raw_sample <= 8 || avctx->codec_type != + AVMEDIA_TYPE_VIDEO) { + c->get_pixels = ff_get_pixels_8_msa; + } + break; + } + } } diff --git a/libavcodec/mips/qpeldsp_init_mips.c b/libavcodec/mips/qpeldsp_init_mips.c index 140e8f89c..cccf9d442 100644 --- a/libavcodec/mips/qpeldsp_init_mips.c +++ b/libavcodec/mips/qpeldsp_init_mips.c @@ -18,150 +18,146 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "qpeldsp_mips.h" -#if HAVE_MSA -static av_cold void qpeldsp_init_msa(QpelDSPContext *c) -{ - c->put_qpel_pixels_tab[0][0] = ff_copy_16x16_msa; - c->put_qpel_pixels_tab[0][1] = ff_horiz_mc_qpel_aver_src0_16width_msa; - c->put_qpel_pixels_tab[0][2] = ff_horiz_mc_qpel_16width_msa; - c->put_qpel_pixels_tab[0][3] = ff_horiz_mc_qpel_aver_src1_16width_msa; - c->put_qpel_pixels_tab[0][4] = ff_vert_mc_qpel_aver_src0_16x16_msa; - c->put_qpel_pixels_tab[0][5] = ff_hv_mc_qpel_aver_hv_src00_16x16_msa; - c->put_qpel_pixels_tab[0][6] = ff_hv_mc_qpel_aver_v_src0_16x16_msa; - c->put_qpel_pixels_tab[0][7] = ff_hv_mc_qpel_aver_hv_src10_16x16_msa; - c->put_qpel_pixels_tab[0][8] = ff_vert_mc_qpel_16x16_msa; - c->put_qpel_pixels_tab[0][9] = ff_hv_mc_qpel_aver_h_src0_16x16_msa; - c->put_qpel_pixels_tab[0][10] = ff_hv_mc_qpel_16x16_msa; - c->put_qpel_pixels_tab[0][11] = ff_hv_mc_qpel_aver_h_src1_16x16_msa; - c->put_qpel_pixels_tab[0][12] = ff_vert_mc_qpel_aver_src1_16x16_msa; - c->put_qpel_pixels_tab[0][13] = ff_hv_mc_qpel_aver_hv_src01_16x16_msa; - c->put_qpel_pixels_tab[0][14] = ff_hv_mc_qpel_aver_v_src1_16x16_msa; - c->put_qpel_pixels_tab[0][15] = ff_hv_mc_qpel_aver_hv_src11_16x16_msa; - - c->put_qpel_pixels_tab[1][0] = ff_copy_8x8_msa; - c->put_qpel_pixels_tab[1][1] = ff_horiz_mc_qpel_aver_src0_8width_msa; - c->put_qpel_pixels_tab[1][2] = ff_horiz_mc_qpel_8width_msa; - c->put_qpel_pixels_tab[1][3] = ff_horiz_mc_qpel_aver_src1_8width_msa; - c->put_qpel_pixels_tab[1][4] = ff_vert_mc_qpel_aver_src0_8x8_msa; - c->put_qpel_pixels_tab[1][5] = ff_hv_mc_qpel_aver_hv_src00_8x8_msa; - c->put_qpel_pixels_tab[1][6] = ff_hv_mc_qpel_aver_v_src0_8x8_msa; - c->put_qpel_pixels_tab[1][7] = ff_hv_mc_qpel_aver_hv_src10_8x8_msa; - c->put_qpel_pixels_tab[1][8] = ff_vert_mc_qpel_8x8_msa; - c->put_qpel_pixels_tab[1][9] = ff_hv_mc_qpel_aver_h_src0_8x8_msa; - c->put_qpel_pixels_tab[1][10] = ff_hv_mc_qpel_8x8_msa; - c->put_qpel_pixels_tab[1][11] = ff_hv_mc_qpel_aver_h_src1_8x8_msa; - c->put_qpel_pixels_tab[1][12] = ff_vert_mc_qpel_aver_src1_8x8_msa; - c->put_qpel_pixels_tab[1][13] = ff_hv_mc_qpel_aver_hv_src01_8x8_msa; - c->put_qpel_pixels_tab[1][14] = ff_hv_mc_qpel_aver_v_src1_8x8_msa; - c->put_qpel_pixels_tab[1][15] = ff_hv_mc_qpel_aver_hv_src11_8x8_msa; - - c->put_no_rnd_qpel_pixels_tab[0][0] = ff_copy_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][1] = - ff_horiz_mc_qpel_no_rnd_aver_src0_16width_msa; - c->put_no_rnd_qpel_pixels_tab[0][2] = ff_horiz_mc_qpel_no_rnd_16width_msa; - c->put_no_rnd_qpel_pixels_tab[0][3] = - ff_horiz_mc_qpel_no_rnd_aver_src1_16width_msa; - c->put_no_rnd_qpel_pixels_tab[0][4] = - ff_vert_mc_qpel_no_rnd_aver_src0_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][5] = - ff_hv_mc_qpel_no_rnd_aver_hv_src00_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][6] = - ff_hv_mc_qpel_no_rnd_aver_v_src0_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][7] = - ff_hv_mc_qpel_no_rnd_aver_hv_src10_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][8] = ff_vert_mc_qpel_no_rnd_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][9] = - ff_hv_mc_qpel_no_rnd_aver_h_src0_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][10] = ff_hv_mc_qpel_no_rnd_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][11] = - ff_hv_mc_qpel_no_rnd_aver_h_src1_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][12] = - ff_vert_mc_qpel_no_rnd_aver_src1_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][13] = - ff_hv_mc_qpel_no_rnd_aver_hv_src01_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][14] = - ff_hv_mc_qpel_no_rnd_aver_v_src1_16x16_msa; - c->put_no_rnd_qpel_pixels_tab[0][15] = - ff_hv_mc_qpel_no_rnd_aver_hv_src11_16x16_msa; - - c->put_no_rnd_qpel_pixels_tab[1][0] = ff_copy_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][1] = - ff_horiz_mc_qpel_no_rnd_aver_src0_8width_msa; - c->put_no_rnd_qpel_pixels_tab[1][2] = ff_horiz_mc_qpel_no_rnd_8width_msa; - c->put_no_rnd_qpel_pixels_tab[1][3] = - ff_horiz_mc_qpel_no_rnd_aver_src1_8width_msa; - c->put_no_rnd_qpel_pixels_tab[1][4] = - ff_vert_mc_qpel_no_rnd_aver_src0_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][5] = - ff_hv_mc_qpel_no_rnd_aver_hv_src00_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][6] = - ff_hv_mc_qpel_no_rnd_aver_v_src0_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][7] = - ff_hv_mc_qpel_no_rnd_aver_hv_src10_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][8] = ff_vert_mc_qpel_no_rnd_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][9] = - ff_hv_mc_qpel_no_rnd_aver_h_src0_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][10] = ff_hv_mc_qpel_no_rnd_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][11] = - ff_hv_mc_qpel_no_rnd_aver_h_src1_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][12] = - ff_vert_mc_qpel_no_rnd_aver_src1_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][13] = - ff_hv_mc_qpel_no_rnd_aver_hv_src01_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][14] = - ff_hv_mc_qpel_no_rnd_aver_v_src1_8x8_msa; - c->put_no_rnd_qpel_pixels_tab[1][15] = - ff_hv_mc_qpel_no_rnd_aver_hv_src11_8x8_msa; - - c->avg_qpel_pixels_tab[0][0] = ff_avg_width16_msa; - c->avg_qpel_pixels_tab[0][1] = - ff_horiz_mc_qpel_avg_dst_aver_src0_16width_msa; - c->avg_qpel_pixels_tab[0][2] = ff_horiz_mc_qpel_avg_dst_16width_msa; - c->avg_qpel_pixels_tab[0][3] = - ff_horiz_mc_qpel_avg_dst_aver_src1_16width_msa; - c->avg_qpel_pixels_tab[0][4] = ff_vert_mc_qpel_avg_dst_aver_src0_16x16_msa; - c->avg_qpel_pixels_tab[0][5] = - ff_hv_mc_qpel_avg_dst_aver_hv_src00_16x16_msa; - c->avg_qpel_pixels_tab[0][6] = ff_hv_mc_qpel_avg_dst_aver_v_src0_16x16_msa; - c->avg_qpel_pixels_tab[0][7] = - ff_hv_mc_qpel_avg_dst_aver_hv_src10_16x16_msa; - c->avg_qpel_pixels_tab[0][8] = ff_vert_mc_qpel_avg_dst_16x16_msa; - c->avg_qpel_pixels_tab[0][9] = ff_hv_mc_qpel_avg_dst_aver_h_src0_16x16_msa; - c->avg_qpel_pixels_tab[0][10] = ff_hv_mc_qpel_avg_dst_16x16_msa; - c->avg_qpel_pixels_tab[0][11] = ff_hv_mc_qpel_avg_dst_aver_h_src1_16x16_msa; - c->avg_qpel_pixels_tab[0][12] = ff_vert_mc_qpel_avg_dst_aver_src1_16x16_msa; - c->avg_qpel_pixels_tab[0][13] = - ff_hv_mc_qpel_avg_dst_aver_hv_src01_16x16_msa; - c->avg_qpel_pixels_tab[0][14] = ff_hv_mc_qpel_avg_dst_aver_v_src1_16x16_msa; - c->avg_qpel_pixels_tab[0][15] = - ff_hv_mc_qpel_avg_dst_aver_hv_src11_16x16_msa; - - c->avg_qpel_pixels_tab[1][0] = ff_avg_width8_msa; - c->avg_qpel_pixels_tab[1][1] = - ff_horiz_mc_qpel_avg_dst_aver_src0_8width_msa; - c->avg_qpel_pixels_tab[1][2] = ff_horiz_mc_qpel_avg_dst_8width_msa; - c->avg_qpel_pixels_tab[1][3] = - ff_horiz_mc_qpel_avg_dst_aver_src1_8width_msa; - c->avg_qpel_pixels_tab[1][4] = ff_vert_mc_qpel_avg_dst_aver_src0_8x8_msa; - c->avg_qpel_pixels_tab[1][5] = ff_hv_mc_qpel_avg_dst_aver_hv_src00_8x8_msa; - c->avg_qpel_pixels_tab[1][6] = ff_hv_mc_qpel_avg_dst_aver_v_src0_8x8_msa; - c->avg_qpel_pixels_tab[1][7] = ff_hv_mc_qpel_avg_dst_aver_hv_src10_8x8_msa; - c->avg_qpel_pixels_tab[1][8] = ff_vert_mc_qpel_avg_dst_8x8_msa; - c->avg_qpel_pixels_tab[1][9] = ff_hv_mc_qpel_avg_dst_aver_h_src0_8x8_msa; - c->avg_qpel_pixels_tab[1][10] = ff_hv_mc_qpel_avg_dst_8x8_msa; - c->avg_qpel_pixels_tab[1][11] = ff_hv_mc_qpel_avg_dst_aver_h_src1_8x8_msa; - c->avg_qpel_pixels_tab[1][12] = ff_vert_mc_qpel_avg_dst_aver_src1_8x8_msa; - c->avg_qpel_pixels_tab[1][13] = ff_hv_mc_qpel_avg_dst_aver_hv_src01_8x8_msa; - c->avg_qpel_pixels_tab[1][14] = ff_hv_mc_qpel_avg_dst_aver_v_src1_8x8_msa; - c->avg_qpel_pixels_tab[1][15] = ff_hv_mc_qpel_avg_dst_aver_hv_src11_8x8_msa; -} -#endif // #if HAVE_MSA - void ff_qpeldsp_init_mips(QpelDSPContext *c) { -#if HAVE_MSA - qpeldsp_init_msa(c); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_msa(cpu_flags)) { + c->put_qpel_pixels_tab[0][0] = ff_copy_16x16_msa; + c->put_qpel_pixels_tab[0][1] = ff_horiz_mc_qpel_aver_src0_16width_msa; + c->put_qpel_pixels_tab[0][2] = ff_horiz_mc_qpel_16width_msa; + c->put_qpel_pixels_tab[0][3] = ff_horiz_mc_qpel_aver_src1_16width_msa; + c->put_qpel_pixels_tab[0][4] = ff_vert_mc_qpel_aver_src0_16x16_msa; + c->put_qpel_pixels_tab[0][5] = ff_hv_mc_qpel_aver_hv_src00_16x16_msa; + c->put_qpel_pixels_tab[0][6] = ff_hv_mc_qpel_aver_v_src0_16x16_msa; + c->put_qpel_pixels_tab[0][7] = ff_hv_mc_qpel_aver_hv_src10_16x16_msa; + c->put_qpel_pixels_tab[0][8] = ff_vert_mc_qpel_16x16_msa; + c->put_qpel_pixels_tab[0][9] = ff_hv_mc_qpel_aver_h_src0_16x16_msa; + c->put_qpel_pixels_tab[0][10] = ff_hv_mc_qpel_16x16_msa; + c->put_qpel_pixels_tab[0][11] = ff_hv_mc_qpel_aver_h_src1_16x16_msa; + c->put_qpel_pixels_tab[0][12] = ff_vert_mc_qpel_aver_src1_16x16_msa; + c->put_qpel_pixels_tab[0][13] = ff_hv_mc_qpel_aver_hv_src01_16x16_msa; + c->put_qpel_pixels_tab[0][14] = ff_hv_mc_qpel_aver_v_src1_16x16_msa; + c->put_qpel_pixels_tab[0][15] = ff_hv_mc_qpel_aver_hv_src11_16x16_msa; + + c->put_qpel_pixels_tab[1][0] = ff_copy_8x8_msa; + c->put_qpel_pixels_tab[1][1] = ff_horiz_mc_qpel_aver_src0_8width_msa; + c->put_qpel_pixels_tab[1][2] = ff_horiz_mc_qpel_8width_msa; + c->put_qpel_pixels_tab[1][3] = ff_horiz_mc_qpel_aver_src1_8width_msa; + c->put_qpel_pixels_tab[1][4] = ff_vert_mc_qpel_aver_src0_8x8_msa; + c->put_qpel_pixels_tab[1][5] = ff_hv_mc_qpel_aver_hv_src00_8x8_msa; + c->put_qpel_pixels_tab[1][6] = ff_hv_mc_qpel_aver_v_src0_8x8_msa; + c->put_qpel_pixels_tab[1][7] = ff_hv_mc_qpel_aver_hv_src10_8x8_msa; + c->put_qpel_pixels_tab[1][8] = ff_vert_mc_qpel_8x8_msa; + c->put_qpel_pixels_tab[1][9] = ff_hv_mc_qpel_aver_h_src0_8x8_msa; + c->put_qpel_pixels_tab[1][10] = ff_hv_mc_qpel_8x8_msa; + c->put_qpel_pixels_tab[1][11] = ff_hv_mc_qpel_aver_h_src1_8x8_msa; + c->put_qpel_pixels_tab[1][12] = ff_vert_mc_qpel_aver_src1_8x8_msa; + c->put_qpel_pixels_tab[1][13] = ff_hv_mc_qpel_aver_hv_src01_8x8_msa; + c->put_qpel_pixels_tab[1][14] = ff_hv_mc_qpel_aver_v_src1_8x8_msa; + c->put_qpel_pixels_tab[1][15] = ff_hv_mc_qpel_aver_hv_src11_8x8_msa; + + c->put_no_rnd_qpel_pixels_tab[0][0] = ff_copy_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][1] = + ff_horiz_mc_qpel_no_rnd_aver_src0_16width_msa; + c->put_no_rnd_qpel_pixels_tab[0][2] = ff_horiz_mc_qpel_no_rnd_16width_msa; + c->put_no_rnd_qpel_pixels_tab[0][3] = + ff_horiz_mc_qpel_no_rnd_aver_src1_16width_msa; + c->put_no_rnd_qpel_pixels_tab[0][4] = + ff_vert_mc_qpel_no_rnd_aver_src0_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][5] = + ff_hv_mc_qpel_no_rnd_aver_hv_src00_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][6] = + ff_hv_mc_qpel_no_rnd_aver_v_src0_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][7] = + ff_hv_mc_qpel_no_rnd_aver_hv_src10_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][8] = ff_vert_mc_qpel_no_rnd_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][9] = + ff_hv_mc_qpel_no_rnd_aver_h_src0_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][10] = ff_hv_mc_qpel_no_rnd_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][11] = + ff_hv_mc_qpel_no_rnd_aver_h_src1_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][12] = + ff_vert_mc_qpel_no_rnd_aver_src1_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][13] = + ff_hv_mc_qpel_no_rnd_aver_hv_src01_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][14] = + ff_hv_mc_qpel_no_rnd_aver_v_src1_16x16_msa; + c->put_no_rnd_qpel_pixels_tab[0][15] = + ff_hv_mc_qpel_no_rnd_aver_hv_src11_16x16_msa; + + c->put_no_rnd_qpel_pixels_tab[1][0] = ff_copy_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][1] = + ff_horiz_mc_qpel_no_rnd_aver_src0_8width_msa; + c->put_no_rnd_qpel_pixels_tab[1][2] = ff_horiz_mc_qpel_no_rnd_8width_msa; + c->put_no_rnd_qpel_pixels_tab[1][3] = + ff_horiz_mc_qpel_no_rnd_aver_src1_8width_msa; + c->put_no_rnd_qpel_pixels_tab[1][4] = + ff_vert_mc_qpel_no_rnd_aver_src0_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][5] = + ff_hv_mc_qpel_no_rnd_aver_hv_src00_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][6] = + ff_hv_mc_qpel_no_rnd_aver_v_src0_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][7] = + ff_hv_mc_qpel_no_rnd_aver_hv_src10_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][8] = ff_vert_mc_qpel_no_rnd_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][9] = + ff_hv_mc_qpel_no_rnd_aver_h_src0_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][10] = ff_hv_mc_qpel_no_rnd_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][11] = + ff_hv_mc_qpel_no_rnd_aver_h_src1_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][12] = + ff_vert_mc_qpel_no_rnd_aver_src1_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][13] = + ff_hv_mc_qpel_no_rnd_aver_hv_src01_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][14] = + ff_hv_mc_qpel_no_rnd_aver_v_src1_8x8_msa; + c->put_no_rnd_qpel_pixels_tab[1][15] = + ff_hv_mc_qpel_no_rnd_aver_hv_src11_8x8_msa; + + c->avg_qpel_pixels_tab[0][0] = ff_avg_width16_msa; + c->avg_qpel_pixels_tab[0][1] = + ff_horiz_mc_qpel_avg_dst_aver_src0_16width_msa; + c->avg_qpel_pixels_tab[0][2] = ff_horiz_mc_qpel_avg_dst_16width_msa; + c->avg_qpel_pixels_tab[0][3] = + ff_horiz_mc_qpel_avg_dst_aver_src1_16width_msa; + c->avg_qpel_pixels_tab[0][4] = ff_vert_mc_qpel_avg_dst_aver_src0_16x16_msa; + c->avg_qpel_pixels_tab[0][5] = + ff_hv_mc_qpel_avg_dst_aver_hv_src00_16x16_msa; + c->avg_qpel_pixels_tab[0][6] = ff_hv_mc_qpel_avg_dst_aver_v_src0_16x16_msa; + c->avg_qpel_pixels_tab[0][7] = + ff_hv_mc_qpel_avg_dst_aver_hv_src10_16x16_msa; + c->avg_qpel_pixels_tab[0][8] = ff_vert_mc_qpel_avg_dst_16x16_msa; + c->avg_qpel_pixels_tab[0][9] = ff_hv_mc_qpel_avg_dst_aver_h_src0_16x16_msa; + c->avg_qpel_pixels_tab[0][10] = ff_hv_mc_qpel_avg_dst_16x16_msa; + c->avg_qpel_pixels_tab[0][11] = ff_hv_mc_qpel_avg_dst_aver_h_src1_16x16_msa; + c->avg_qpel_pixels_tab[0][12] = ff_vert_mc_qpel_avg_dst_aver_src1_16x16_msa; + c->avg_qpel_pixels_tab[0][13] = + ff_hv_mc_qpel_avg_dst_aver_hv_src01_16x16_msa; + c->avg_qpel_pixels_tab[0][14] = ff_hv_mc_qpel_avg_dst_aver_v_src1_16x16_msa; + c->avg_qpel_pixels_tab[0][15] = + ff_hv_mc_qpel_avg_dst_aver_hv_src11_16x16_msa; + + c->avg_qpel_pixels_tab[1][0] = ff_avg_width8_msa; + c->avg_qpel_pixels_tab[1][1] = + ff_horiz_mc_qpel_avg_dst_aver_src0_8width_msa; + c->avg_qpel_pixels_tab[1][2] = ff_horiz_mc_qpel_avg_dst_8width_msa; + c->avg_qpel_pixels_tab[1][3] = + ff_horiz_mc_qpel_avg_dst_aver_src1_8width_msa; + c->avg_qpel_pixels_tab[1][4] = ff_vert_mc_qpel_avg_dst_aver_src0_8x8_msa; + c->avg_qpel_pixels_tab[1][5] = ff_hv_mc_qpel_avg_dst_aver_hv_src00_8x8_msa; + c->avg_qpel_pixels_tab[1][6] = ff_hv_mc_qpel_avg_dst_aver_v_src0_8x8_msa; + c->avg_qpel_pixels_tab[1][7] = ff_hv_mc_qpel_avg_dst_aver_hv_src10_8x8_msa; + c->avg_qpel_pixels_tab[1][8] = ff_vert_mc_qpel_avg_dst_8x8_msa; + c->avg_qpel_pixels_tab[1][9] = ff_hv_mc_qpel_avg_dst_aver_h_src0_8x8_msa; + c->avg_qpel_pixels_tab[1][10] = ff_hv_mc_qpel_avg_dst_8x8_msa; + c->avg_qpel_pixels_tab[1][11] = ff_hv_mc_qpel_avg_dst_aver_h_src1_8x8_msa; + c->avg_qpel_pixels_tab[1][12] = ff_vert_mc_qpel_avg_dst_aver_src1_8x8_msa; + c->avg_qpel_pixels_tab[1][13] = ff_hv_mc_qpel_avg_dst_aver_hv_src01_8x8_msa; + c->avg_qpel_pixels_tab[1][14] = ff_hv_mc_qpel_avg_dst_aver_v_src1_8x8_msa; + c->avg_qpel_pixels_tab[1][15] = ff_hv_mc_qpel_avg_dst_aver_hv_src11_8x8_msa; + } } diff --git a/libavcodec/mips/sbrdsp_mips.c b/libavcodec/mips/sbrdsp_mips.c index 83039fd80..1c87c9925 100644 --- a/libavcodec/mips/sbrdsp_mips.c +++ b/libavcodec/mips/sbrdsp_mips.c @@ -796,9 +796,9 @@ static void sbr_hf_apply_noise_2_mips(float (*Y)[2], const float *s_m, const float *q_filt, int noise, int kx, int m_max) { - int m; + int m, temp0, temp1; float *ff_table; - float y0,y1, temp0, temp1, temp2, temp3, temp4, temp5; + float y0, y1, temp2, temp3, temp4, temp5; for (m = 0; m < m_max; m++) { @@ -808,14 +808,14 @@ static void sbr_hf_apply_noise_2_mips(float (*Y)[2], const float *s_m, __asm__ volatile( "lwc1 %[y0], 0(%[Y1]) \n\t" - "lwc1 %[temp1], 0(%[s_m1]) \n\t" + "lwc1 %[temp3], 0(%[s_m1]) \n\t" "addiu %[noise], %[noise], 1 \n\t" "andi %[noise], %[noise], 0x1ff \n\t" "sll %[temp0], %[noise], 3 \n\t" PTR_ADDU "%[ff_table],%[ff_sbr_noise_table],%[temp0] \n\t" - "sub.s %[y0], %[y0], %[temp1] \n\t" - "mfc1 %[temp3], %[temp1] \n\t" - "bne %[temp3], $0, 1f \n\t" + "sub.s %[y0], %[y0], %[temp3] \n\t" + "mfc1 %[temp1], %[temp3] \n\t" + "bne %[temp1], $0, 1f \n\t" "lwc1 %[y1], 4(%[Y1]) \n\t" "lwc1 %[temp2], 0(%[q_filt1]) \n\t" "lwc1 %[temp4], 0(%[ff_table]) \n\t" @@ -826,9 +826,10 @@ static void sbr_hf_apply_noise_2_mips(float (*Y)[2], const float *s_m, "1: \n\t" "swc1 %[y0], 0(%[Y1]) \n\t" - : [temp0]"=&r"(temp0), [ff_table]"=&r"(ff_table), [y0]"=&f"(y0), - [y1]"=&f"(y1), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2), - [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5) + : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [y0]"=&f"(y0), + [y1]"=&f"(y1), [ff_table]"=&r"(ff_table), + [temp2]"=&f"(temp2), [temp3]"=&f"(temp3), + [temp4]"=&f"(temp4), [temp5]"=&f"(temp5) : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise), [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1) : "memory" diff --git a/libavcodec/mips/simple_idct_mmi.c b/libavcodec/mips/simple_idct_mmi.c index 73d797ffb..e4b58dcfd 100644 --- a/libavcodec/mips/simple_idct_mmi.c +++ b/libavcodec/mips/simple_idct_mmi.c @@ -26,6 +26,7 @@ #include "constants.h" #include "libavutil/mips/asmdefs.h" #include "libavutil/mips/mmiutils.h" +#include "libavutil/mem_internal.h" #define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 #define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 diff --git a/libavcodec/mips/vc1dsp_init_mips.c b/libavcodec/mips/vc1dsp_init_mips.c index c0007ff65..94126f3a9 100644 --- a/libavcodec/mips/vc1dsp_init_mips.c +++ b/libavcodec/mips/vc1dsp_init_mips.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "libavutil/attributes.h" #include "libavcodec/vc1dsp.h" #include "vc1dsp_mips.h" @@ -27,104 +28,93 @@ dsp->OP##vc1_mspel_pixels_tab[1][X+4*Y] = ff_##OP##vc1_mspel_mc##X##Y##INSN; \ dsp->OP##vc1_mspel_pixels_tab[0][X+4*Y] = ff_##OP##vc1_mspel_mc##X##Y##_16##INSN -#if HAVE_MMI -static av_cold void vc1dsp_init_mmi(VC1DSPContext *dsp) -{ -#if _MIPS_SIM != _ABIO32 - dsp->vc1_inv_trans_8x8 = ff_vc1_inv_trans_8x8_mmi; - dsp->vc1_inv_trans_4x8 = ff_vc1_inv_trans_4x8_mmi; - dsp->vc1_inv_trans_8x4 = ff_vc1_inv_trans_8x4_mmi; -#endif - dsp->vc1_inv_trans_4x4 = ff_vc1_inv_trans_4x4_mmi; - dsp->vc1_inv_trans_8x8_dc = ff_vc1_inv_trans_8x8_dc_mmi; - dsp->vc1_inv_trans_4x8_dc = ff_vc1_inv_trans_4x8_dc_mmi; - dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_mmi; - dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_mmi; - - dsp->vc1_h_overlap = ff_vc1_h_overlap_mmi; - dsp->vc1_v_overlap = ff_vc1_v_overlap_mmi; - dsp->vc1_h_s_overlap = ff_vc1_h_s_overlap_mmi; - dsp->vc1_v_s_overlap = ff_vc1_v_s_overlap_mmi; - - dsp->vc1_v_loop_filter4 = ff_vc1_v_loop_filter4_mmi; - dsp->vc1_h_loop_filter4 = ff_vc1_h_loop_filter4_mmi; - dsp->vc1_v_loop_filter8 = ff_vc1_v_loop_filter8_mmi; - dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_mmi; - dsp->vc1_v_loop_filter16 = ff_vc1_v_loop_filter16_mmi; - dsp->vc1_h_loop_filter16 = ff_vc1_h_loop_filter16_mmi; - - FN_ASSIGN(put_, 0, 0, _mmi); - FN_ASSIGN(put_, 0, 1, _mmi); - FN_ASSIGN(put_, 0, 2, _mmi); - FN_ASSIGN(put_, 0, 3, _mmi); - - FN_ASSIGN(put_, 1, 0, _mmi); - //FN_ASSIGN(put_, 1, 1, _mmi);//FIXME - //FN_ASSIGN(put_, 1, 2, _mmi);//FIXME - //FN_ASSIGN(put_, 1, 3, _mmi);//FIXME - - FN_ASSIGN(put_, 2, 0, _mmi); - //FN_ASSIGN(put_, 2, 1, _mmi);//FIXME - //FN_ASSIGN(put_, 2, 2, _mmi);//FIXME - //FN_ASSIGN(put_, 2, 3, _mmi);//FIXME - - FN_ASSIGN(put_, 3, 0, _mmi); - //FN_ASSIGN(put_, 3, 1, _mmi);//FIXME - //FN_ASSIGN(put_, 3, 2, _mmi);//FIXME - //FN_ASSIGN(put_, 3, 3, _mmi);//FIXME - - FN_ASSIGN(avg_, 0, 0, _mmi); - FN_ASSIGN(avg_, 0, 1, _mmi); - FN_ASSIGN(avg_, 0, 2, _mmi); - FN_ASSIGN(avg_, 0, 3, _mmi); - - FN_ASSIGN(avg_, 1, 0, _mmi); - //FN_ASSIGN(avg_, 1, 1, _mmi);//FIXME - //FN_ASSIGN(avg_, 1, 2, _mmi);//FIXME - //FN_ASSIGN(avg_, 1, 3, _mmi);//FIXME - - FN_ASSIGN(avg_, 2, 0, _mmi); - //FN_ASSIGN(avg_, 2, 1, _mmi);//FIXME - //FN_ASSIGN(avg_, 2, 2, _mmi);//FIXME - //FN_ASSIGN(avg_, 2, 3, _mmi);//FIXME - - FN_ASSIGN(avg_, 3, 0, _mmi); - //FN_ASSIGN(avg_, 3, 1, _mmi);//FIXME - //FN_ASSIGN(avg_, 3, 2, _mmi);//FIXME - //FN_ASSIGN(avg_, 3, 3, _mmi);//FIXME - - dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_no_rnd_vc1_chroma_mc8_mmi; - dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_no_rnd_vc1_chroma_mc8_mmi; - dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = ff_put_no_rnd_vc1_chroma_mc4_mmi; - dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = ff_avg_no_rnd_vc1_chroma_mc4_mmi; -} -#endif /* HAVE_MMI */ - -#if HAVE_MSA -static av_cold void vc1dsp_init_msa(VC1DSPContext *dsp) -{ - dsp->vc1_inv_trans_8x8 = ff_vc1_inv_trans_8x8_msa; - dsp->vc1_inv_trans_4x8 = ff_vc1_inv_trans_4x8_msa; - dsp->vc1_inv_trans_8x4 = ff_vc1_inv_trans_8x4_msa; - - FN_ASSIGN(put_, 1, 1, _msa); - FN_ASSIGN(put_, 1, 2, _msa); - FN_ASSIGN(put_, 1, 3, _msa); - FN_ASSIGN(put_, 2, 1, _msa); - FN_ASSIGN(put_, 2, 2, _msa); - FN_ASSIGN(put_, 2, 3, _msa); - FN_ASSIGN(put_, 3, 1, _msa); - FN_ASSIGN(put_, 3, 2, _msa); - FN_ASSIGN(put_, 3, 3, _msa); -} -#endif /* HAVE_MSA */ - av_cold void ff_vc1dsp_init_mips(VC1DSPContext *dsp) { -#if HAVE_MMI - vc1dsp_init_mmi(dsp); -#endif /* HAVE_MMI */ -#if HAVE_MSA - vc1dsp_init_msa(dsp); -#endif /* HAVE_MSA */ + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + #if _MIPS_SIM != _ABIO32 + dsp->vc1_inv_trans_8x8 = ff_vc1_inv_trans_8x8_mmi; + dsp->vc1_inv_trans_4x8 = ff_vc1_inv_trans_4x8_mmi; + dsp->vc1_inv_trans_8x4 = ff_vc1_inv_trans_8x4_mmi; +#endif + dsp->vc1_inv_trans_4x4 = ff_vc1_inv_trans_4x4_mmi; + dsp->vc1_inv_trans_8x8_dc = ff_vc1_inv_trans_8x8_dc_mmi; + dsp->vc1_inv_trans_4x8_dc = ff_vc1_inv_trans_4x8_dc_mmi; + dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_mmi; + dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_mmi; + + dsp->vc1_h_overlap = ff_vc1_h_overlap_mmi; + dsp->vc1_v_overlap = ff_vc1_v_overlap_mmi; + dsp->vc1_h_s_overlap = ff_vc1_h_s_overlap_mmi; + dsp->vc1_v_s_overlap = ff_vc1_v_s_overlap_mmi; + + dsp->vc1_v_loop_filter4 = ff_vc1_v_loop_filter4_mmi; + dsp->vc1_h_loop_filter4 = ff_vc1_h_loop_filter4_mmi; + dsp->vc1_v_loop_filter8 = ff_vc1_v_loop_filter8_mmi; + dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_mmi; + dsp->vc1_v_loop_filter16 = ff_vc1_v_loop_filter16_mmi; + dsp->vc1_h_loop_filter16 = ff_vc1_h_loop_filter16_mmi; + + FN_ASSIGN(put_, 0, 0, _mmi); + FN_ASSIGN(put_, 0, 1, _mmi); + FN_ASSIGN(put_, 0, 2, _mmi); + FN_ASSIGN(put_, 0, 3, _mmi); + + FN_ASSIGN(put_, 1, 0, _mmi); + //FN_ASSIGN(put_, 1, 1, _mmi);//FIXME + //FN_ASSIGN(put_, 1, 2, _mmi);//FIXME + //FN_ASSIGN(put_, 1, 3, _mmi);//FIXME + + FN_ASSIGN(put_, 2, 0, _mmi); + //FN_ASSIGN(put_, 2, 1, _mmi);//FIXME + //FN_ASSIGN(put_, 2, 2, _mmi);//FIXME + //FN_ASSIGN(put_, 2, 3, _mmi);//FIXME + + FN_ASSIGN(put_, 3, 0, _mmi); + //FN_ASSIGN(put_, 3, 1, _mmi);//FIXME + //FN_ASSIGN(put_, 3, 2, _mmi);//FIXME + //FN_ASSIGN(put_, 3, 3, _mmi);//FIXME + + FN_ASSIGN(avg_, 0, 0, _mmi); + FN_ASSIGN(avg_, 0, 1, _mmi); + FN_ASSIGN(avg_, 0, 2, _mmi); + FN_ASSIGN(avg_, 0, 3, _mmi); + + FN_ASSIGN(avg_, 1, 0, _mmi); + //FN_ASSIGN(avg_, 1, 1, _mmi);//FIXME + //FN_ASSIGN(avg_, 1, 2, _mmi);//FIXME + //FN_ASSIGN(avg_, 1, 3, _mmi);//FIXME + + FN_ASSIGN(avg_, 2, 0, _mmi); + //FN_ASSIGN(avg_, 2, 1, _mmi);//FIXME + //FN_ASSIGN(avg_, 2, 2, _mmi);//FIXME + //FN_ASSIGN(avg_, 2, 3, _mmi);//FIXME + + FN_ASSIGN(avg_, 3, 0, _mmi); + //FN_ASSIGN(avg_, 3, 1, _mmi);//FIXME + //FN_ASSIGN(avg_, 3, 2, _mmi);//FIXME + //FN_ASSIGN(avg_, 3, 3, _mmi);//FIXME + + dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_no_rnd_vc1_chroma_mc8_mmi; + dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_no_rnd_vc1_chroma_mc8_mmi; + dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = ff_put_no_rnd_vc1_chroma_mc4_mmi; + dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = ff_avg_no_rnd_vc1_chroma_mc4_mmi; + } + + if (have_msa(cpu_flags)) { + dsp->vc1_inv_trans_8x8 = ff_vc1_inv_trans_8x8_msa; + dsp->vc1_inv_trans_4x8 = ff_vc1_inv_trans_4x8_msa; + dsp->vc1_inv_trans_8x4 = ff_vc1_inv_trans_8x4_msa; + + FN_ASSIGN(put_, 1, 1, _msa); + FN_ASSIGN(put_, 1, 2, _msa); + FN_ASSIGN(put_, 1, 3, _msa); + FN_ASSIGN(put_, 2, 1, _msa); + FN_ASSIGN(put_, 2, 2, _msa); + FN_ASSIGN(put_, 2, 3, _msa); + FN_ASSIGN(put_, 3, 1, _msa); + FN_ASSIGN(put_, 3, 2, _msa); + FN_ASSIGN(put_, 3, 3, _msa); + } } diff --git a/libavcodec/mips/vc1dsp_mmi.c b/libavcodec/mips/vc1dsp_mmi.c index 98378683b..8355cd1b2 100644 --- a/libavcodec/mips/vc1dsp_mmi.c +++ b/libavcodec/mips/vc1dsp_mmi.c @@ -21,10 +21,13 @@ */ #include "libavutil/avassert.h" +#include "libavutil/mem_internal.h" + #include "libavcodec/vc1dsp.h" #include "constants.h" #include "vc1dsp_mips.h" #include "hpeldsp_mips.h" +#include "libavutil/mem_internal.h" #include "libavutil/mips/mmiutils.h" #define VC1_INV_TRANCS_8_TYPE1(o1, o2, r1, r2, r3, r4, c0) \ diff --git a/libavcodec/mips/videodsp_init.c b/libavcodec/mips/videodsp_init.c index 817040420..07c23bcf7 100644 --- a/libavcodec/mips/videodsp_init.c +++ b/libavcodec/mips/videodsp_init.c @@ -18,12 +18,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "config.h" #include "libavutil/attributes.h" #include "libavutil/mips/asmdefs.h" #include "libavcodec/videodsp.h" -#if HAVE_MSA static void prefetch_mips(uint8_t *mem, ptrdiff_t stride, int h) { register const uint8_t *p = mem; @@ -41,11 +41,11 @@ static void prefetch_mips(uint8_t *mem, ptrdiff_t stride, int h) : [stride] "r" (stride) ); } -#endif // #if HAVE_MSA av_cold void ff_videodsp_init_mips(VideoDSPContext *ctx, int bpc) { -#if HAVE_MSA - ctx->prefetch = prefetch_mips; -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_msa(cpu_flags)) + ctx->prefetch = prefetch_mips; } diff --git a/libavcodec/mips/vp3dsp_init_mips.c b/libavcodec/mips/vp3dsp_init_mips.c index e183db35b..4252ff790 100644 --- a/libavcodec/mips/vp3dsp_init_mips.c +++ b/libavcodec/mips/vp3dsp_init_mips.c @@ -19,42 +19,32 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "config.h" #include "libavutil/attributes.h" #include "libavcodec/avcodec.h" #include "libavcodec/vp3dsp.h" #include "vp3dsp_mips.h" -#if HAVE_MSA -static av_cold void vp3dsp_init_msa(VP3DSPContext *c, int flags) -{ - c->put_no_rnd_pixels_l2 = ff_put_no_rnd_pixels_l2_msa; - - c->idct_add = ff_vp3_idct_add_msa; - c->idct_put = ff_vp3_idct_put_msa; - c->idct_dc_add = ff_vp3_idct_dc_add_msa; - c->v_loop_filter = ff_vp3_v_loop_filter_msa; - c->h_loop_filter = ff_vp3_h_loop_filter_msa; -} -#endif /* HAVE_MSA */ - -#if HAVE_MMI -static av_cold void vp3dsp_init_mmi(VP3DSPContext *c, int flags) -{ - c->put_no_rnd_pixels_l2 = ff_put_no_rnd_pixels_l2_mmi; - - c->idct_add = ff_vp3_idct_add_mmi; - c->idct_put = ff_vp3_idct_put_mmi; - c->idct_dc_add = ff_vp3_idct_dc_add_mmi; -} -#endif /* HAVE_MMI */ - av_cold void ff_vp3dsp_init_mips(VP3DSPContext *c, int flags) { -#if HAVE_MMI - vp3dsp_init_mmi(c, flags); -#endif /* HAVE_MMI */ -#if HAVE_MSA - vp3dsp_init_msa(c, flags); -#endif /* HAVE_MSA */ + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + c->put_no_rnd_pixels_l2 = ff_put_no_rnd_pixels_l2_mmi; + + c->idct_add = ff_vp3_idct_add_mmi; + c->idct_put = ff_vp3_idct_put_mmi; + c->idct_dc_add = ff_vp3_idct_dc_add_mmi; + } + + if (have_msa(cpu_flags)) { + c->put_no_rnd_pixels_l2 = ff_put_no_rnd_pixels_l2_msa; + + c->idct_add = ff_vp3_idct_add_msa; + c->idct_put = ff_vp3_idct_put_msa; + c->idct_dc_add = ff_vp3_idct_dc_add_msa; + c->v_loop_filter = ff_vp3_v_loop_filter_msa; + c->h_loop_filter = ff_vp3_h_loop_filter_msa; + } } diff --git a/libavcodec/mips/vp8dsp_init_mips.c b/libavcodec/mips/vp8dsp_init_mips.c index 7fd8fb0d3..92d8c792c 100644 --- a/libavcodec/mips/vp8dsp_init_mips.c +++ b/libavcodec/mips/vp8dsp_init_mips.c @@ -24,6 +24,7 @@ * VP8 compatible video decoder */ +#include "libavutil/mips/cpu.h" #include "config.h" #include "libavutil/attributes.h" #include "libavcodec/vp8dsp.h" @@ -71,132 +72,123 @@ dsp->put_vp8_bilinear_pixels_tab[IDX][0][0] = \ ff_put_vp8_pixels##SIZE##_msa; -#if HAVE_MSA -static av_cold void vp8dsp_init_msa(VP8DSPContext *dsp) -{ - dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_msa; - dsp->vp8_idct_add = ff_vp8_idct_add_msa; - dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_msa; - dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_msa; - dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_msa; - VP8_MC_MIPS_FUNC(0, 16); - VP8_MC_MIPS_FUNC(1, 8); - VP8_MC_MIPS_FUNC(2, 4); - - VP8_BILINEAR_MC_MIPS_FUNC(0, 16); - VP8_BILINEAR_MC_MIPS_FUNC(1, 8); - VP8_BILINEAR_MC_MIPS_FUNC(2, 4); - - VP8_MC_MIPS_COPY(0, 16); - VP8_MC_MIPS_COPY(1, 8); - - dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_msa; - dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_msa; - dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_msa; - dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_msa; - - dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_msa; - dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_msa; - dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_msa; - dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_msa; - - dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_msa; - dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_msa; -} -#endif // #if HAVE_MSA - -#if HAVE_MMI -static av_cold void vp8dsp_init_mmi(VP8DSPContext *dsp) -{ - dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_mmi; - dsp->vp8_luma_dc_wht_dc = ff_vp8_luma_dc_wht_dc_mmi; - dsp->vp8_idct_add = ff_vp8_idct_add_mmi; - dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmi; - dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmi; - dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmi; - - dsp->put_vp8_epel_pixels_tab[0][0][1] = ff_put_vp8_epel16_h4_mmi; - dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_mmi; - dsp->put_vp8_epel_pixels_tab[0][1][0] = ff_put_vp8_epel16_v4_mmi; - dsp->put_vp8_epel_pixels_tab[0][1][1] = ff_put_vp8_epel16_h4v4_mmi; - dsp->put_vp8_epel_pixels_tab[0][1][2] = ff_put_vp8_epel16_h6v4_mmi; - dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_mmi; - dsp->put_vp8_epel_pixels_tab[0][2][1] = ff_put_vp8_epel16_h4v6_mmi; - dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_mmi; - - dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_mmi; - dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_mmi; - dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_mmi; - dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_mmi; - dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_mmi; - dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_mmi; - dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_mmi; - dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_mmi; - - dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_mmi; - dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_mmi; - dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_mmi; - dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_mmi; - dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_mmi; - dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_mmi; - dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_mmi; - dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_mmi; - - dsp->put_vp8_bilinear_pixels_tab[0][0][1] = ff_put_vp8_bilinear16_h_mmi; - dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilinear16_h_mmi; - dsp->put_vp8_bilinear_pixels_tab[0][1][0] = ff_put_vp8_bilinear16_v_mmi; - dsp->put_vp8_bilinear_pixels_tab[0][1][1] = ff_put_vp8_bilinear16_hv_mmi; - dsp->put_vp8_bilinear_pixels_tab[0][1][2] = ff_put_vp8_bilinear16_hv_mmi; - dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilinear16_v_mmi; - dsp->put_vp8_bilinear_pixels_tab[0][2][1] = ff_put_vp8_bilinear16_hv_mmi; - dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilinear16_hv_mmi; - - dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilinear8_h_mmi; - dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilinear8_h_mmi; - dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilinear8_v_mmi; - dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilinear8_hv_mmi; - dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilinear8_hv_mmi; - dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilinear8_v_mmi; - dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilinear8_hv_mmi; - dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilinear8_hv_mmi; - - dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilinear4_h_mmi; - dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilinear4_h_mmi; - dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilinear4_v_mmi; - dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilinear4_hv_mmi; - dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilinear4_hv_mmi; - dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilinear4_v_mmi; - dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilinear4_hv_mmi; - dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilinear4_hv_mmi; - - dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmi; - dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmi; - - dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmi; - dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmi; - - dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_mmi; - dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_mmi; - dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mmi; - dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mmi; - - dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_mmi; - dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_mmi; - dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmi; - dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmi; - - dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmi; - dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmi; -} -#endif /* HAVE_MMI */ av_cold void ff_vp8dsp_init_mips(VP8DSPContext *dsp) { -#if HAVE_MMI - vp8dsp_init_mmi(dsp); -#endif /* HAVE_MMI */ -#if HAVE_MSA - vp8dsp_init_msa(dsp); -#endif // #if HAVE_MSA + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_mmi; + dsp->vp8_luma_dc_wht_dc = ff_vp8_luma_dc_wht_dc_mmi; + dsp->vp8_idct_add = ff_vp8_idct_add_mmi; + dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmi; + dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmi; + dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmi; + + dsp->put_vp8_epel_pixels_tab[0][0][1] = ff_put_vp8_epel16_h4_mmi; + dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_mmi; + dsp->put_vp8_epel_pixels_tab[0][1][0] = ff_put_vp8_epel16_v4_mmi; + dsp->put_vp8_epel_pixels_tab[0][1][1] = ff_put_vp8_epel16_h4v4_mmi; + dsp->put_vp8_epel_pixels_tab[0][1][2] = ff_put_vp8_epel16_h6v4_mmi; + dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_mmi; + dsp->put_vp8_epel_pixels_tab[0][2][1] = ff_put_vp8_epel16_h4v6_mmi; + dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_mmi; + + dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_mmi; + dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_mmi; + dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_mmi; + dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_mmi; + dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_mmi; + dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_mmi; + dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_mmi; + dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_mmi; + + dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_mmi; + dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_mmi; + dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_mmi; + dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_mmi; + dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_mmi; + dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_mmi; + dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_mmi; + dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_mmi; + + dsp->put_vp8_bilinear_pixels_tab[0][0][1] = ff_put_vp8_bilinear16_h_mmi; + dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilinear16_h_mmi; + dsp->put_vp8_bilinear_pixels_tab[0][1][0] = ff_put_vp8_bilinear16_v_mmi; + dsp->put_vp8_bilinear_pixels_tab[0][1][1] = ff_put_vp8_bilinear16_hv_mmi; + dsp->put_vp8_bilinear_pixels_tab[0][1][2] = ff_put_vp8_bilinear16_hv_mmi; + dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilinear16_v_mmi; + dsp->put_vp8_bilinear_pixels_tab[0][2][1] = ff_put_vp8_bilinear16_hv_mmi; + dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilinear16_hv_mmi; + + dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilinear8_h_mmi; + dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilinear8_h_mmi; + dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilinear8_v_mmi; + dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilinear8_hv_mmi; + dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilinear8_hv_mmi; + dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilinear8_v_mmi; + dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilinear8_hv_mmi; + dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilinear8_hv_mmi; + + dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilinear4_h_mmi; + dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilinear4_h_mmi; + dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilinear4_v_mmi; + dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilinear4_hv_mmi; + dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilinear4_hv_mmi; + dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilinear4_v_mmi; + dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilinear4_hv_mmi; + dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilinear4_hv_mmi; + + dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmi; + dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmi; + + dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmi; + dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmi; + + dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_mmi; + dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_mmi; + dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mmi; + dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mmi; + + dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_mmi; + dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_mmi; + dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmi; + dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmi; + + dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmi; + dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmi; + } + + if (have_msa(cpu_flags)) { + dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_msa; + dsp->vp8_idct_add = ff_vp8_idct_add_msa; + dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_msa; + dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_msa; + dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_msa; + + VP8_MC_MIPS_FUNC(0, 16); + VP8_MC_MIPS_FUNC(1, 8); + VP8_MC_MIPS_FUNC(2, 4); + + VP8_BILINEAR_MC_MIPS_FUNC(0, 16); + VP8_BILINEAR_MC_MIPS_FUNC(1, 8); + VP8_BILINEAR_MC_MIPS_FUNC(2, 4); + + VP8_MC_MIPS_COPY(0, 16); + VP8_MC_MIPS_COPY(1, 8); + + dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_msa; + dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_msa; + dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_msa; + dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_msa; + + dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_msa; + dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_msa; + dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_msa; + dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_msa; + + dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_msa; + dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_msa; + } } diff --git a/libavcodec/mips/vp8dsp_mmi.c b/libavcodec/mips/vp8dsp_mmi.c index bd80aa144..aa6e856dd 100644 --- a/libavcodec/mips/vp8dsp_mmi.c +++ b/libavcodec/mips/vp8dsp_mmi.c @@ -24,6 +24,7 @@ #include "vp8dsp_mips.h" #include "constants.h" #include "libavutil/mips/mmiutils.h" +#include "libavutil/mem_internal.h" #define DECLARE_DOUBLE_1 double db_1 #define DECLARE_DOUBLE_2 double db_2 diff --git a/libavcodec/mips/vp9dsp_init_mips.c b/libavcodec/mips/vp9dsp_init_mips.c index 5990fa695..5a8c599e7 100644 --- a/libavcodec/mips/vp9dsp_init_mips.c +++ b/libavcodec/mips/vp9dsp_init_mips.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "config.h" #include "libavutil/common.h" #include "libavcodec/vp9dsp.h" @@ -209,10 +210,17 @@ static av_cold void vp9dsp_init_mmi(VP9DSPContext *dsp, int bpp) av_cold void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp) { +#if HAVE_MSA || HAVE_MMI + int cpu_flags = av_get_cpu_flags(); +#endif + #if HAVE_MMI - vp9dsp_init_mmi(dsp, bpp); -#endif // #if HAVE_MMI + if (have_mmi(cpu_flags)) + vp9dsp_init_mmi(dsp, bpp); +#endif + #if HAVE_MSA - vp9dsp_init_msa(dsp, bpp); -#endif // #if HAVE_MSA + if (have_msa(cpu_flags)) + vp9dsp_init_msa(dsp, bpp); +#endif } diff --git a/libavcodec/mips/wmv2dsp_init_mips.c b/libavcodec/mips/wmv2dsp_init_mips.c index 51dd2078d..af1400731 100644 --- a/libavcodec/mips/wmv2dsp_init_mips.c +++ b/libavcodec/mips/wmv2dsp_init_mips.c @@ -18,21 +18,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "config.h" #include "libavutil/attributes.h" #include "wmv2dsp_mips.h" -#if HAVE_MMI -static av_cold void wmv2dsp_init_mmi(WMV2DSPContext *c) -{ - c->idct_add = ff_wmv2_idct_add_mmi; - c->idct_put = ff_wmv2_idct_put_mmi; -} -#endif /* HAVE_MMI */ - av_cold void ff_wmv2dsp_init_mips(WMV2DSPContext *c) { -#if HAVE_MMI - wmv2dsp_init_mmi(c); -#endif /* HAVE_MMI */ + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + c->idct_add = ff_wmv2_idct_add_mmi; + c->idct_put = ff_wmv2_idct_put_mmi; + } } diff --git a/libavcodec/mips/wmv2dsp_mips.h b/libavcodec/mips/wmv2dsp_mips.h index 22894c505..c96b3d94c 100644 --- a/libavcodec/mips/wmv2dsp_mips.h +++ b/libavcodec/mips/wmv2dsp_mips.h @@ -23,7 +23,7 @@ #include "libavcodec/wmv2dsp.h" -void ff_wmv2_idct_add_mmi(uint8_t *dest, int line_size, int16_t *block); -void ff_wmv2_idct_put_mmi(uint8_t *dest, int line_size, int16_t *block); +void ff_wmv2_idct_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_wmv2_idct_put_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block); #endif /* AVCODEC_MIPS_WMV2DSP_MIPS_H */ diff --git a/libavcodec/mips/wmv2dsp_mmi.c b/libavcodec/mips/wmv2dsp_mmi.c index 1f6ccb299..82e16f929 100644 --- a/libavcodec/mips/wmv2dsp_mmi.c +++ b/libavcodec/mips/wmv2dsp_mmi.c @@ -95,7 +95,7 @@ static void wmv2_idct_col_mmi(short * b) b[56] = (a0 + a2 - a1 - a5 + 8192) >> 14; } -void ff_wmv2_idct_add_mmi(uint8_t *dest, int line_size, int16_t *block) +void ff_wmv2_idct_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { int i; double ftmp[11]; @@ -212,7 +212,7 @@ void ff_wmv2_idct_add_mmi(uint8_t *dest, int line_size, int16_t *block) ); } -void ff_wmv2_idct_put_mmi(uint8_t *dest, int line_size, int16_t *block) +void ff_wmv2_idct_put_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { int i; double ftmp[8]; diff --git a/libavcodec/mips/xvid_idct_mmi.c b/libavcodec/mips/xvid_idct_mmi.c index d3f9acb0e..034a48d2a 100644 --- a/libavcodec/mips/xvid_idct_mmi.c +++ b/libavcodec/mips/xvid_idct_mmi.c @@ -21,6 +21,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mem_internal.h" + #include "idctdsp_mips.h" #include "xvididct_mips.h" @@ -240,13 +242,13 @@ void ff_xvid_idct_mmi(int16_t *block) ); } -void ff_xvid_idct_put_mmi(uint8_t *dest, int32_t line_size, int16_t *block) +void ff_xvid_idct_put_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_xvid_idct_mmi(block); ff_put_pixels_clamped_mmi(block, dest, line_size); } -void ff_xvid_idct_add_mmi(uint8_t *dest, int32_t line_size, int16_t *block) +void ff_xvid_idct_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_xvid_idct_mmi(block); ff_add_pixels_clamped_mmi(block, dest, line_size); diff --git a/libavcodec/mips/xvididct_init_mips.c b/libavcodec/mips/xvididct_init_mips.c index c1d82cc30..ed545cfe1 100644 --- a/libavcodec/mips/xvididct_init_mips.c +++ b/libavcodec/mips/xvididct_init_mips.c @@ -18,28 +18,23 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mips/cpu.h" #include "xvididct_mips.h" -#if HAVE_MMI -static av_cold void xvid_idct_init_mmi(IDCTDSPContext *c, AVCodecContext *avctx, - unsigned high_bit_depth) -{ - if (!high_bit_depth) { - if (avctx->idct_algo == FF_IDCT_AUTO || - avctx->idct_algo == FF_IDCT_XVID) { - c->idct_put = ff_xvid_idct_put_mmi; - c->idct_add = ff_xvid_idct_add_mmi; - c->idct = ff_xvid_idct_mmi; - c->perm_type = FF_IDCT_PERM_NONE; - } - } -} -#endif /* HAVE_MMI */ - av_cold void ff_xvid_idct_init_mips(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth) { -#if HAVE_MMI - xvid_idct_init_mmi(c, avctx, high_bit_depth); -#endif /* HAVE_MMI */ + int cpu_flags = av_get_cpu_flags(); + + if (have_mmi(cpu_flags)) { + if (!high_bit_depth) { + if (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_XVID) { + c->idct_put = ff_xvid_idct_put_mmi; + c->idct_add = ff_xvid_idct_add_mmi; + c->idct = ff_xvid_idct_mmi; + c->perm_type = FF_IDCT_PERM_NONE; + } + } + } } diff --git a/libavcodec/mips/xvididct_mips.h b/libavcodec/mips/xvididct_mips.h index 0768aaa26..bee03c139 100644 --- a/libavcodec/mips/xvididct_mips.h +++ b/libavcodec/mips/xvididct_mips.h @@ -24,7 +24,7 @@ #include "libavcodec/xvididct.h" void ff_xvid_idct_mmi(int16_t *block); -void ff_xvid_idct_put_mmi(uint8_t *dest, int32_t line_size, int16_t *block); -void ff_xvid_idct_add_mmi(uint8_t *dest, int32_t line_size, int16_t *block); +void ff_xvid_idct_put_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_xvid_idct_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block); #endif /* AVCODEC_MIPS_XVIDIDCT_MIPS_H */ diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index 70ff4cf56..766667490 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -163,5 +163,5 @@ AVCodec ff_mjpegb_decoder = { .decode = mjpegb_decode_frame, .capabilities = AV_CODEC_CAP_DR1, .max_lowres = 3, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index e7a4e08c1..2df6caa44 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -36,6 +36,7 @@ #include "avcodec.h" #include "blockdsp.h" #include "copy_block.h" +#include "decode.h" #include "hwconfig.h" #include "idctdsp.h" #include "internal.h" @@ -50,29 +51,6 @@ #include "bytestream.h" -static int build_vlc(VLC *vlc, const uint8_t *bits_table, - const uint8_t *val_table, int nb_codes, - int use_static, int is_ac) -{ - uint8_t huff_size[256] = { 0 }; - uint16_t huff_code[256]; - uint16_t huff_sym[256]; - int i; - - av_assert0(nb_codes <= 256); - - ff_mjpeg_build_huffman_codes(huff_size, huff_code, bits_table, val_table); - - for (i = 0; i < 256; i++) - huff_sym[i] = i + 16 * is_ac; - - if (is_ac) - huff_sym[0] = 16 * 256; - - return ff_init_vlc_sparse(vlc, 9, nb_codes, huff_size, 1, 1, - huff_code, 2, 2, huff_sym, 2, 2, use_static); -} - static int init_default_huffman_tables(MJpegDecodeContext *s) { static const struct { @@ -80,28 +58,28 @@ static int init_default_huffman_tables(MJpegDecodeContext *s) int index; const uint8_t *bits; const uint8_t *values; - int codes; int length; } ht[] = { { 0, 0, avpriv_mjpeg_bits_dc_luminance, - avpriv_mjpeg_val_dc, 12, 12 }, + avpriv_mjpeg_val_dc, 12 }, { 0, 1, avpriv_mjpeg_bits_dc_chrominance, - avpriv_mjpeg_val_dc, 12, 12 }, + avpriv_mjpeg_val_dc, 12 }, { 1, 0, avpriv_mjpeg_bits_ac_luminance, - avpriv_mjpeg_val_ac_luminance, 251, 162 }, + avpriv_mjpeg_val_ac_luminance, 162 }, { 1, 1, avpriv_mjpeg_bits_ac_chrominance, - avpriv_mjpeg_val_ac_chrominance, 251, 162 }, + avpriv_mjpeg_val_ac_chrominance, 162 }, { 2, 0, avpriv_mjpeg_bits_ac_luminance, - avpriv_mjpeg_val_ac_luminance, 251, 162 }, + avpriv_mjpeg_val_ac_luminance, 162 }, { 2, 1, avpriv_mjpeg_bits_ac_chrominance, - avpriv_mjpeg_val_ac_chrominance, 251, 162 }, + avpriv_mjpeg_val_ac_chrominance, 162 }, }; int i, ret; for (i = 0; i < FF_ARRAY_ELEMS(ht); i++) { - ret = build_vlc(&s->vlcs[ht[i].class][ht[i].index], - ht[i].bits, ht[i].values, ht[i].codes, - 0, ht[i].class == 1); + ff_free_vlc(&s->vlcs[ht[i].class][ht[i].index]); + ret = ff_mjpeg_build_vlc(&s->vlcs[ht[i].class][ht[i].index], + ht[i].bits, ht[i].values, + ht[i].class == 1, s->avctx); if (ret < 0) return ret; @@ -148,6 +126,10 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) s->picture_ptr = s->picture; } + s->pkt = av_packet_alloc(); + if (!s->pkt) + return AVERROR(ENOMEM); + s->avctx = avctx; ff_blockdsp_init(&s->bdsp, avctx); ff_hpeldsp_init(&s->hdsp, avctx->flags); @@ -157,7 +139,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) s->start_code = -1; s->first_picture = 1; s->got_picture = 0; - s->org_height = avctx->coded_height; + s->orig_height = avctx->coded_height; avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; avctx->colorspace = AVCOL_SPC_BT470BG; s->hwaccel_pix_fmt = s->hwaccel_sw_pix_fmt = AV_PIX_FMT_NONE; @@ -172,7 +154,8 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) if (ff_mjpeg_decode_dht(s)) { av_log(avctx, AV_LOG_ERROR, "error using external huffman table, switching back to internal\n"); - init_default_huffman_tables(s); + if ((ret = init_default_huffman_tables(s)) < 0) + return ret; } } if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */ @@ -183,7 +166,19 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) s->interlace_polarity = 1; } - if ( avctx->extradata_size > 8 + if (avctx->codec_id == AV_CODEC_ID_SMVJPEG) { + if (avctx->extradata_size >= 4) + s->smv_frames_per_jpeg = AV_RL32(avctx->extradata); + + if (s->smv_frames_per_jpeg <= 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of frames per jpeg.\n"); + return AVERROR_INVALIDDATA; + } + + s->smv_frame = av_frame_alloc(); + if (!s->smv_frame) + return AVERROR(ENOMEM); + } else if (avctx->extradata_size > 8 && AV_RL32(avctx->extradata) == 0x2C && AV_RL32(avctx->extradata+4) == 0x18) { parse_avid(s, avctx->extradata, avctx->extradata_size); @@ -240,7 +235,7 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s) /* decode huffman tables and build VLC decoders */ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) { - int len, index, i, class, n, v, code_max; + int len, index, i, class, n, v; uint8_t bits_table[17]; uint8_t val_table[256]; int ret = 0; @@ -270,11 +265,8 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) if (len < n || n > 256) return AVERROR_INVALIDDATA; - code_max = 0; for (i = 0; i < n; i++) { v = get_bits(&s->gb, 8); - if (v > code_max) - code_max = v; val_table[i] = v; } len -= n; @@ -282,15 +274,15 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) /* build VLC and flush previous vlc if present */ ff_free_vlc(&s->vlcs[class][index]); av_log(s->avctx, AV_LOG_DEBUG, "class=%d index=%d nb_codes=%d\n", - class, index, code_max + 1); - if ((ret = build_vlc(&s->vlcs[class][index], bits_table, val_table, - code_max + 1, 0, class > 0)) < 0) + class, index, n); + if ((ret = ff_mjpeg_build_vlc(&s->vlcs[class][index], bits_table, + val_table, class > 0, s->avctx)) < 0) return ret; if (class > 0) { ff_free_vlc(&s->vlcs[2][index]); - if ((ret = build_vlc(&s->vlcs[2][index], bits_table, val_table, - code_max + 1, 0, 0)) < 0) + if ((ret = ff_mjpeg_build_vlc(&s->vlcs[2][index], bits_table, + val_table, 0, s->avctx)) < 0) return ret; } @@ -442,8 +434,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* test interlaced mode */ if (s->first_picture && (s->multiscope != 2 || s->avctx->time_base.den >= 25 * s->avctx->time_base.num) && - s->org_height != 0 && - s->height < ((s->org_height * 3) / 4)) { + s->orig_height != 0 && + s->height < ((s->orig_height * 3) / 4)) { s->interlaced = 1; s->bottom_field = s->interlace_polarity; s->picture_ptr->interlaced_frame = 1; @@ -455,11 +447,22 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) if (ret < 0) return ret; + if ((s->avctx->codec_tag == MKTAG('A', 'V', 'R', 'n') || + s->avctx->codec_tag == MKTAG('A', 'V', 'D', 'J')) && + s->orig_height < height) + s->avctx->height = AV_CEIL_RSHIFT(s->orig_height, s->avctx->lowres); + s->first_picture = 0; } else { size_change = 0; } + if (s->avctx->codec_id == AV_CODEC_ID_SMVJPEG) { + s->avctx->height = s->avctx->coded_height / s->smv_frames_per_jpeg; + if (s->avctx->height <= 0) + return AVERROR_INVALIDDATA; + } + if (s->got_picture && s->interlaced && (s->bottom_field == !s->interlace_polarity)) { if (s->progressive) { avpriv_request_sample(s->avctx, "progressively coded interlaced picture"); @@ -2084,28 +2087,26 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) /* Allocate if this is the first APP2 we've seen. */ if (s->iccnum == 0) { - s->iccdata = av_mallocz(nummarkers * sizeof(*(s->iccdata))); - s->iccdatalens = av_mallocz(nummarkers * sizeof(*(s->iccdatalens))); - if (!s->iccdata || !s->iccdatalens) { + if (!FF_ALLOCZ_TYPED_ARRAY(s->iccentries, nummarkers)) { av_log(s->avctx, AV_LOG_ERROR, "Could not allocate ICC data arrays\n"); return AVERROR(ENOMEM); } s->iccnum = nummarkers; } - if (s->iccdata[seqno - 1]) { + if (s->iccentries[seqno - 1].data) { av_log(s->avctx, AV_LOG_WARNING, "Duplicate ICC sequence number\n"); goto out; } - s->iccdatalens[seqno - 1] = len; - s->iccdata[seqno - 1] = av_malloc(len); - if (!s->iccdata[seqno - 1]) { + s->iccentries[seqno - 1].length = len; + s->iccentries[seqno - 1].data = av_malloc(len); + if (!s->iccentries[seqno - 1].data) { av_log(s->avctx, AV_LOG_ERROR, "Could not allocate ICC data buffer\n"); return AVERROR(ENOMEM); } - memcpy(s->iccdata[seqno - 1], align_get_bits(&s->gb), len); + memcpy(s->iccentries[seqno - 1].data, align_get_bits(&s->gb), len); skip_bits(&s->gb, len << 3); len = 0; s->iccread++; @@ -2314,22 +2315,78 @@ static void reset_icc_profile(MJpegDecodeContext *s) { int i; - if (s->iccdata) + if (s->iccentries) { for (i = 0; i < s->iccnum; i++) - av_freep(&s->iccdata[i]); - av_freep(&s->iccdata); - av_freep(&s->iccdatalens); + av_freep(&s->iccentries[i].data); + av_freep(&s->iccentries); + } s->iccread = 0; s->iccnum = 0; } -int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, - AVPacket *avpkt) +// SMV JPEG just stacks several output frames into one JPEG picture +// we handle that by setting up the cropping parameters appropriately +static int smv_process_frame(AVCodecContext *avctx, AVFrame *frame) +{ + MJpegDecodeContext *s = avctx->priv_data; + int ret; + + if (s->smv_next_frame > 0) { + av_assert0(s->smv_frame->buf[0]); + av_frame_unref(frame); + ret = av_frame_ref(frame, s->smv_frame); + if (ret < 0) + return ret; + } else { + av_assert0(frame->buf[0]); + av_frame_unref(s->smv_frame); + ret = av_frame_ref(s->smv_frame, frame); + if (ret < 0) + return ret; + } + + av_assert0((s->smv_next_frame + 1) * avctx->height <= avctx->coded_height); + + frame->width = avctx->coded_width; + frame->height = avctx->coded_height; + frame->crop_top = FFMIN(s->smv_next_frame * avctx->height, frame->height); + frame->crop_bottom = frame->height - (s->smv_next_frame + 1) * avctx->height; + + s->smv_next_frame = (s->smv_next_frame + 1) % s->smv_frames_per_jpeg; + + if (s->smv_next_frame == 0) + av_frame_unref(s->smv_frame); + + return 0; +} + +static int mjpeg_get_packet(AVCodecContext *avctx) +{ + MJpegDecodeContext *s = avctx->priv_data; + int ret; + + av_packet_unref(s->pkt); + ret = ff_decode_get_packet(avctx, s->pkt); + if (ret < 0) + return ret; + +#if CONFIG_SP5X_DECODER || CONFIG_AMV_DECODER + if (avctx->codec_id == AV_CODEC_ID_SP5X || + avctx->codec_id == AV_CODEC_ID_AMV) { + ret = ff_sp5x_process_packet(avctx, s->pkt); + if (ret < 0) + return ret; + } +#endif + + s->buf_size = s->pkt->size; + + return 0; +} + +int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame) { - AVFrame *frame = data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; MJpegDecodeContext *s = avctx->priv_data; const uint8_t *buf_end, *buf_ptr; const uint8_t *unescaped_buf_ptr; @@ -2340,7 +2397,8 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int ret = 0; int is16bit; - s->buf_size = buf_size; + if (avctx->codec_id == AV_CODEC_ID_SMVJPEG && s->smv_next_frame > 0) + return smv_process_frame(avctx, frame); av_dict_free(&s->exif_metadata); av_freep(&s->stereo3d); @@ -2349,8 +2407,12 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (s->iccnum != 0) reset_icc_profile(s); - buf_ptr = buf; - buf_end = buf + buf_size; + ret = mjpeg_get_packet(avctx); + if (ret < 0) + return ret; + + buf_ptr = s->pkt->data; + buf_end = s->pkt->data + s->pkt->size; while (buf_ptr < buf_end) { /* find start next marker */ start_code = ff_mjpeg_find_marker(s, &buf_ptr, buf_end, @@ -2362,7 +2424,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } 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); + start_code, unescaped_buf_size, s->pkt->size); return AVERROR_INVALIDDATA; } av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%"PTRDIFF_SPECIFIER"\n", @@ -2499,6 +2561,7 @@ eoi_parser: } if (avctx->skip_frame == AVDISCARD_ALL) { s->got_picture = 0; + ret = AVERROR(EAGAIN); goto the_end_no_picture; } if (s->avctx->hwaccel) { @@ -2510,22 +2573,16 @@ eoi_parser: } if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0) return ret; - *got_frame = 1; s->got_picture = 0; - if (!s->lossless) { + frame->pkt_dts = s->pkt->dts; + + if (!s->lossless && avctx->debug & FF_DEBUG_QP) { 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); + av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", qp); } goto the_end; @@ -2762,7 +2819,7 @@ the_end: } if (s->stereo3d) { - AVStereo3D *stereo = av_stereo3d_create_side_data(data); + AVStereo3D *stereo = av_stereo3d_create_side_data(frame); if (stereo) { stereo->type = s->stereo3d->type; stereo->flags = s->stereo3d->flags; @@ -2778,9 +2835,9 @@ the_end: /* Sum size of all parts. */ for (i = 0; i < s->iccnum; i++) - total_size += s->iccdatalens[i]; + total_size += s->iccentries[i].length; - sd = av_frame_new_side_data(data, AV_FRAME_DATA_ICC_PROFILE, total_size); + sd = av_frame_new_side_data(frame, AV_FRAME_DATA_ICC_PROFILE, total_size); if (!sd) { av_log(s->avctx, AV_LOG_ERROR, "Could not allocate frame side data\n"); return AVERROR(ENOMEM); @@ -2788,21 +2845,39 @@ the_end: /* Reassemble the parts, which are now in-order. */ for (i = 0; i < s->iccnum; i++) { - memcpy(sd->data + offset, s->iccdata[i], s->iccdatalens[i]); - offset += s->iccdatalens[i]; + memcpy(sd->data + offset, s->iccentries[i].data, s->iccentries[i].length); + offset += s->iccentries[i].length; } } - av_dict_copy(&((AVFrame *) data)->metadata, s->exif_metadata, 0); + av_dict_copy(&frame->metadata, s->exif_metadata, 0); av_dict_free(&s->exif_metadata); + if (avctx->codec_id == AV_CODEC_ID_SMVJPEG) { + ret = smv_process_frame(avctx, frame); + if (ret < 0) { + av_frame_unref(frame); + return ret; + } + } + if ((avctx->codec_tag == MKTAG('A', 'V', 'R', 'n') || + avctx->codec_tag == MKTAG('A', 'V', 'D', 'J')) && + avctx->coded_height > s->orig_height) { + frame->height = AV_CEIL_RSHIFT(avctx->coded_height, avctx->lowres); + frame->crop_top = frame->height - avctx->height; + } + + ret = 0; + the_end_no_picture: av_log(avctx, AV_LOG_DEBUG, "decode frame unused %"PTRDIFF_SPECIFIER" bytes\n", buf_end - buf_ptr); -// return buf_end - buf_ptr; - return buf_ptr - buf; + + return ret; } +/* mxpeg may call the following function (with a blank MJpegDecodeContext) + * even without having called ff_mjpeg_decode_init(). */ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) { MJpegDecodeContext *s = avctx->priv_data; @@ -2818,6 +2893,10 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) } else if (s->picture_ptr) av_frame_unref(s->picture_ptr); + av_packet_free(&s->pkt); + + av_frame_free(&s->smv_frame); + av_freep(&s->buffer); av_freep(&s->stereo3d); av_freep(&s->ljpeg_buffer); @@ -2844,6 +2923,9 @@ static void decode_flush(AVCodecContext *avctx) { MJpegDecodeContext *s = avctx->priv_data; s->got_picture = 0; + + s->smv_next_frame = 0; + av_frame_unref(s->smv_frame); } #if CONFIG_MJPEG_DECODER @@ -2870,15 +2952,15 @@ AVCodec ff_mjpeg_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - .decode = ff_mjpeg_decode_frame, + .receive_frame = ff_mjpeg_receive_frame, .flush = decode_flush, .capabilities = AV_CODEC_CAP_DR1, .max_lowres = 3, .priv_class = &mjpegdec_class, .profiles = NULL_IF_CONFIG_SMALL(ff_mjpeg_profiles), - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | - FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_SETS_PKT_DTS, + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_MJPEG_NVDEC_HWACCEL HWACCEL_NVDEC(mjpeg), #endif @@ -2898,10 +2980,28 @@ AVCodec ff_thp_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - .decode = ff_mjpeg_decode_frame, + .receive_frame = ff_mjpeg_receive_frame, .flush = decode_flush, .capabilities = AV_CODEC_CAP_DR1, .max_lowres = 3, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_SETS_PKT_DTS, +}; +#endif + +#if CONFIG_SMVJPEG_DECODER +AVCodec ff_smvjpeg_decoder = { + .name = "smvjpeg", + .long_name = NULL_IF_CONFIG_SMALL("SMV JPEG"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_SMVJPEG, + .priv_data_size = sizeof(MJpegDecodeContext), + .init = ff_mjpeg_decode_init, + .close = ff_mjpeg_decode_end, + .receive_frame = ff_mjpeg_receive_frame, + .flush = decode_flush, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING | + FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index 9d1666beb..0d69d9101 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -30,6 +30,7 @@ #define AVCODEC_MJPEGDEC_H #include "libavutil/log.h" +#include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "libavutil/stereo3d.h" @@ -43,12 +44,19 @@ #define MAX_COMPONENTS 4 +typedef struct ICCEntry { + uint8_t *data; + int length; +} ICCEntry; + typedef struct MJpegDecodeContext { AVClass *class; AVCodecContext *avctx; GetBitContext gb; int buf_size; + AVPacket *pkt; + int start_code; /* current start code */ int buffer_size; uint8_t *buffer; @@ -57,7 +65,7 @@ typedef struct MJpegDecodeContext { VLC vlcs[3][4]; int qscale[4]; ///< quantizer scale calculated from quant_matrixes - int org_height; /* size given at codec init */ + int orig_height; /* size given at codec init */ int first_picture; /* true if decoding first picture */ int interlaced; /* true if interlaced */ int bottom_field; /* true if bottom field */ @@ -135,11 +143,14 @@ typedef struct MJpegDecodeContext { const AVPixFmtDescriptor *pix_desc; - uint8_t **iccdata; - int *iccdatalens; + ICCEntry *iccentries; int iccnum; int iccread; + AVFrame *smv_frame; + int smv_frames_per_jpeg; + int smv_next_frame; + // Raw stream data for hwaccel use. const uint8_t *raw_image_buffer; size_t raw_image_buffer_size; @@ -154,11 +165,11 @@ typedef struct MJpegDecodeContext { void *hwaccel_picture_private; } MJpegDecodeContext; +int ff_mjpeg_build_vlc(VLC *vlc, const uint8_t *bits_table, + const uint8_t *val_table, int is_ac, void *logctx); int ff_mjpeg_decode_init(AVCodecContext *avctx); int ff_mjpeg_decode_end(AVCodecContext *avctx); -int ff_mjpeg_decode_frame(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt); +int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame); int ff_mjpeg_decode_dqt(MJpegDecodeContext *s); int ff_mjpeg_decode_dht(MJpegDecodeContext *s); int ff_mjpeg_decode_sof(MJpegDecodeContext *s); @@ -169,4 +180,6 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, const uint8_t **buf_ptr, const uint8_t *buf_end, const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size); +int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt); + #endif /* AVCODEC_MJPEGDEC_H */ diff --git a/libavcodec/mjpegdec_common.c b/libavcodec/mjpegdec_common.c new file mode 100644 index 000000000..701ddfec0 --- /dev/null +++ b/libavcodec/mjpegdec_common.c @@ -0,0 +1,57 @@ +/* + * MJPEG decoder VLC code + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-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 + */ + +#include +#include "libavutil/avassert.h" +#include "mjpegdec.h" +#include "vlc.h" + +static int build_huffman_codes(uint8_t *huff_size, const uint8_t *bits_table) +{ + int nb_codes = 0; + for (int i = 1, j = 0; i <= 16; i++) { + nb_codes += bits_table[i]; + av_assert1(nb_codes <= 256); + for (; j < nb_codes; j++) + huff_size[j] = i; + } + return nb_codes; +} + +int ff_mjpeg_build_vlc(VLC *vlc, const uint8_t *bits_table, + const uint8_t *val_table, int is_ac, void *logctx) +{ + uint8_t huff_size[256]; + uint16_t huff_sym[256]; + int nb_codes = build_huffman_codes(huff_size, bits_table); + + for (int i = 0; i < nb_codes; i++) { + huff_sym[i] = val_table[i] + 16 * is_ac; + + if (is_ac && !val_table[i]) + huff_sym[i] = 16 * 256; + } + + return ff_init_vlc_from_lengths(vlc, 9, nb_codes, huff_size, 1, + huff_sym, 2, 2, 0, 0, logctx); +} diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index 56ccbc5fb..4d7755cc8 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -35,11 +35,198 @@ #include "avcodec.h" #include "jpegtables.h" #include "mjpegenc_common.h" +#include "mjpegenc_huffman.h" #include "mpegvideo.h" #include "mjpeg.h" #include "mjpegenc.h" #include "profiles.h" +static av_cold void init_uni_ac_vlc(const uint8_t huff_size_ac[256], + uint8_t *uni_ac_vlc_len) +{ + for (int i = 0; i < 128; i++) { + int level = i - 64; + if (!level) + continue; + for (int run = 0; run < 64; run++) { + int len, code, nbits; + int alevel = FFABS(level); + + len = (run >> 4) * huff_size_ac[0xf0]; + + nbits= av_log2_16bit(alevel) + 1; + code = ((15&run) << 4) | nbits; + + len += huff_size_ac[code] + nbits; + + uni_ac_vlc_len[UNI_AC_ENC_INDEX(run, i)] = len; + // We ignore EOB as its just a constant which does not change generally + } + } +} + +/** + * Encodes and outputs the entire frame in the JPEG format. + * + * @param s The MpegEncContext. + */ +static void mjpeg_encode_picture_frame(MpegEncContext *s) +{ + int nbits, code, table_id; + MJpegContext *m = s->mjpeg_ctx; + uint8_t *huff_size[4] = { m->huff_size_dc_luminance, + m->huff_size_dc_chrominance, + m->huff_size_ac_luminance, + m->huff_size_ac_chrominance }; + uint16_t *huff_code[4] = { m->huff_code_dc_luminance, + m->huff_code_dc_chrominance, + m->huff_code_ac_luminance, + m->huff_code_ac_chrominance }; + size_t total_bits = 0; + size_t bytes_needed; + + s->header_bits = get_bits_diff(s); + // Estimate the total size first + for (int i = 0; i < m->huff_ncode; i++) { + table_id = m->huff_buffer[i].table_id; + code = m->huff_buffer[i].code; + nbits = code & 0xf; + + total_bits += huff_size[table_id][code] + nbits; + } + + bytes_needed = (total_bits + 7) / 8; + ff_mpv_reallocate_putbitbuffer(s, bytes_needed, bytes_needed); + + for (int i = 0; i < m->huff_ncode; i++) { + table_id = m->huff_buffer[i].table_id; + code = m->huff_buffer[i].code; + nbits = code & 0xf; + + put_bits(&s->pb, huff_size[table_id][code], huff_code[table_id][code]); + if (nbits != 0) { + put_sbits(&s->pb, nbits, m->huff_buffer[i].mant); + } + } + + m->huff_ncode = 0; + s->i_tex_bits = get_bits_diff(s); +} + +/** + * Builds all 4 optimal Huffman tables. + * + * Uses the data stored in the JPEG buffer to compute the tables. + * Stores the Huffman tables in the bits_* and val_* arrays in the MJpegContext. + * + * @param m MJpegContext containing the JPEG buffer. + */ +static void mjpeg_build_optimal_huffman(MJpegContext *m) +{ + MJpegEncHuffmanContext dc_luminance_ctx; + MJpegEncHuffmanContext dc_chrominance_ctx; + MJpegEncHuffmanContext ac_luminance_ctx; + MJpegEncHuffmanContext ac_chrominance_ctx; + MJpegEncHuffmanContext *ctx[4] = { &dc_luminance_ctx, + &dc_chrominance_ctx, + &ac_luminance_ctx, + &ac_chrominance_ctx }; + for (int i = 0; i < 4; i++) + ff_mjpeg_encode_huffman_init(ctx[i]); + + for (int i = 0; i < m->huff_ncode; i++) { + int table_id = m->huff_buffer[i].table_id; + int code = m->huff_buffer[i].code; + + ff_mjpeg_encode_huffman_increment(ctx[table_id], code); + } + + ff_mjpeg_encode_huffman_close(&dc_luminance_ctx, + m->bits_dc_luminance, + m->val_dc_luminance, 12); + ff_mjpeg_encode_huffman_close(&dc_chrominance_ctx, + m->bits_dc_chrominance, + m->val_dc_chrominance, 12); + ff_mjpeg_encode_huffman_close(&ac_luminance_ctx, + m->bits_ac_luminance, + m->val_ac_luminance, 256); + ff_mjpeg_encode_huffman_close(&ac_chrominance_ctx, + m->bits_ac_chrominance, + m->val_ac_chrominance, 256); + + ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance, + m->huff_code_dc_luminance, + m->bits_dc_luminance, + m->val_dc_luminance); + ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance, + m->huff_code_dc_chrominance, + m->bits_dc_chrominance, + m->val_dc_chrominance); + ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance, + m->huff_code_ac_luminance, + m->bits_ac_luminance, + m->val_ac_luminance); + ff_mjpeg_build_huffman_codes(m->huff_size_ac_chrominance, + m->huff_code_ac_chrominance, + m->bits_ac_chrominance, + m->val_ac_chrominance); +} + +/** + * Writes the complete JPEG frame when optimal huffman tables are enabled, + * otherwise writes the stuffing. + * + * Header + values + stuffing. + * + * @param s The MpegEncContext. + * @return int Error code, 0 if successful. + */ +int ff_mjpeg_encode_stuffing(MpegEncContext *s) +{ + PutBitContext *pbc = &s->pb; + int mb_y = s->mb_y - !s->mb_x; + int ret; + MJpegContext *m; + + m = s->mjpeg_ctx; + + if (s->huffman == HUFFMAN_TABLE_OPTIMAL) { + mjpeg_build_optimal_huffman(m); + + // Replace the VLCs with the optimal ones. + // The default ones may be used for trellis during quantization. + init_uni_ac_vlc(m->huff_size_ac_luminance, m->uni_ac_vlc_len); + init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len); + s->intra_ac_vlc_length = + s->intra_ac_vlc_last_length = m->uni_ac_vlc_len; + s->intra_chroma_ac_vlc_length = + s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len; + + ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable, + s->pred, s->intra_matrix, s->chroma_intra_matrix); + mjpeg_encode_picture_frame(s); + } + + ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100, + put_bits_count(&s->pb) / 4 + 1000); + if (ret < 0) { + av_log(s->avctx, AV_LOG_ERROR, "Buffer reallocation failed\n"); + goto fail; + } + + ff_mjpeg_escape_FF(pbc, s->esc_pos); + + if ((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height - 1) + put_marker(pbc, RST0 + (mb_y&7)); + s->esc_pos = put_bits_count(pbc) >> 3; + +fail: + for (int i = 0; i < 3; i++) + s->last_dc[i] = 128 << s->intra_dc_precision; + + return ret; +} + static int alloc_huffman(MpegEncContext *s) { MJpegContext *m = s->mjpeg_ctx; @@ -106,8 +293,8 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) avpriv_mjpeg_bits_ac_chrominance, avpriv_mjpeg_val_ac_chrominance); - ff_init_uni_ac_vlc(m->huff_size_ac_luminance, m->uni_ac_vlc_len); - ff_init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len); + init_uni_ac_vlc(m->huff_size_ac_luminance, m->uni_ac_vlc_len); + init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len); s->intra_ac_vlc_length = s->intra_ac_vlc_last_length = m->uni_ac_vlc_len; s->intra_chroma_ac_vlc_length = @@ -125,8 +312,10 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) av_cold void ff_mjpeg_encode_close(MpegEncContext *s) { - av_freep(&s->mjpeg_ctx->huff_buffer); - av_freep(&s->mjpeg_ctx); + if (s->mjpeg_ctx) { + av_freep(&s->mjpeg_ctx->huff_buffer); + av_freep(&s->mjpeg_ctx); + } } /** @@ -415,7 +604,7 @@ AVCodec ff_mjpeg_encoder = { .encode2 = ff_mpv_encode_picture, .close = ff_mpv_encode_end, .capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE }, @@ -441,7 +630,7 @@ AVCodec ff_amv_encoder = { .init = ff_mpv_encode_init, .encode2 = amv_encode_picture, .close = ff_mpv_encode_end, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE }, diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h index d7ddc35ef..2e9251127 100644 --- a/libavcodec/mjpegenc.h +++ b/libavcodec/mjpegenc.h @@ -107,5 +107,6 @@ static inline void put_marker(PutBitContext *p, enum JpegMarker code) int ff_mjpeg_encode_init(MpegEncContext *s); void ff_mjpeg_encode_close(MpegEncContext *s); void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]); +int ff_mjpeg_encode_stuffing(MpegEncContext *s); #endif /* AVCODEC_MJPEGENC_H */ diff --git a/libavcodec/mjpegenc_common.c b/libavcodec/mjpegenc_common.c index 3038ebde6..12dd7be2e 100644 --- a/libavcodec/mjpegenc_common.c +++ b/libavcodec/mjpegenc_common.c @@ -23,7 +23,6 @@ #include #include -#include "libavutil/common.h" #include "libavutil/pixdesc.h" #include "libavutil/pixfmt.h" @@ -33,35 +32,8 @@ #include "put_bits.h" #include "mjpegenc.h" #include "mjpegenc_common.h" -#include "mjpegenc_huffman.h" #include "mjpeg.h" -av_cold void ff_init_uni_ac_vlc(const uint8_t huff_size_ac[256], uint8_t *uni_ac_vlc_len) -{ - int i; - - for (i = 0; i < 128; i++) { - int level = i - 64; - int run; - if (!level) - continue; - for (run = 0; run < 64; run++) { - int len, code, nbits; - int alevel = FFABS(level); - - len = (run >> 4) * huff_size_ac[0xf0]; - - nbits= av_log2_16bit(alevel) + 1; - code = ((15&run) << 4) | nbits; - - len += huff_size_ac[code] + nbits; - - uni_ac_vlc_len[UNI_AC_ENC_INDEX(run, i)] = len; - // We ignore EOB as its just a constant which does not change generally - } - } -} - /* table_class: 0 = DC coef, 1 = AC coefs */ static int put_huffman_table(PutBitContext *p, int table_class, int table_id, const uint8_t *bits_table, const uint8_t *value_table) @@ -181,7 +153,7 @@ static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p) /* JFIF header */ put_marker(p, APP0); put_bits(p, 16, 16); - avpriv_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ + ff_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ /* The most significant byte is used for major revisions, the least * significant byte for minor revisions. Version 1.02 is the current * released revision. */ @@ -199,7 +171,7 @@ static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p) flush_put_bits(p); ptr = put_bits_ptr(p); put_bits(p, 16, 0); /* patched later */ - avpriv_put_string(p, LIBAVCODEC_IDENT, 1); + ff_put_string(p, LIBAVCODEC_IDENT, 1); size = strlen(LIBAVCODEC_IDENT)+3; AV_WB16(ptr, size); } @@ -212,7 +184,7 @@ static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p) flush_put_bits(p); ptr = put_bits_ptr(p); put_bits(p, 16, 0); /* patched later */ - avpriv_put_string(p, "CS=ITU601", 1); + ff_put_string(p, "CS=ITU601", 1); size = strlen("CS=ITU601")+3; AV_WB16(ptr, size); } @@ -359,54 +331,6 @@ end: } } -/** - * Encodes and outputs the entire frame in the JPEG format. - * - * @param s The MpegEncContext. - */ -void ff_mjpeg_encode_picture_frame(MpegEncContext *s) -{ - int i, nbits, code, table_id; - MJpegContext *m = s->mjpeg_ctx; - uint8_t *huff_size[4] = {m->huff_size_dc_luminance, - m->huff_size_dc_chrominance, - m->huff_size_ac_luminance, - m->huff_size_ac_chrominance}; - uint16_t *huff_code[4] = {m->huff_code_dc_luminance, - m->huff_code_dc_chrominance, - m->huff_code_ac_luminance, - m->huff_code_ac_chrominance}; - size_t total_bits = 0; - size_t bytes_needed; - - s->header_bits = get_bits_diff(s); - // Estimate the total size first - for (i = 0; i < m->huff_ncode; i++) { - table_id = m->huff_buffer[i].table_id; - code = m->huff_buffer[i].code; - nbits = code & 0xf; - - total_bits += huff_size[table_id][code] + nbits; - } - - bytes_needed = (total_bits + 7) / 8; - ff_mpv_reallocate_putbitbuffer(s, bytes_needed, bytes_needed); - - for (i = 0; i < m->huff_ncode; i++) { - table_id = m->huff_buffer[i].table_id; - code = m->huff_buffer[i].code; - nbits = code & 0xf; - - put_bits(&s->pb, huff_size[table_id][code], huff_code[table_id][code]); - if (nbits != 0) { - put_sbits(&s->pb, nbits, m->huff_buffer[i].mant); - } - } - - m->huff_ncode = 0; - s->i_tex_bits = get_bits_diff(s); -} - void ff_mjpeg_escape_FF(PutBitContext *pb, int start) { int size; @@ -466,122 +390,25 @@ void ff_mjpeg_escape_FF(PutBitContext *pb, int start) } } -/** - * Builds all 4 optimal Huffman tables. - * - * Uses the data stored in the JPEG buffer to compute the tables. - * Stores the Huffman tables in the bits_* and val_* arrays in the MJpegContext. - * - * @param m MJpegContext containing the JPEG buffer. - */ -static void ff_mjpeg_build_optimal_huffman(MJpegContext *m) +/* isn't this function nicer than the one in the libjpeg ? */ +void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, + const uint8_t *bits_table, + const uint8_t *val_table) { - int i, table_id, code; + int k, code; - MJpegEncHuffmanContext dc_luminance_ctx; - MJpegEncHuffmanContext dc_chrominance_ctx; - MJpegEncHuffmanContext ac_luminance_ctx; - MJpegEncHuffmanContext ac_chrominance_ctx; - MJpegEncHuffmanContext *ctx[4] = {&dc_luminance_ctx, - &dc_chrominance_ctx, - &ac_luminance_ctx, - &ac_chrominance_ctx}; - for (i = 0; i < 4; i++) { - ff_mjpeg_encode_huffman_init(ctx[i]); + k = 0; + code = 0; + for (int i = 1; i <= 16; i++) { + int nb = bits_table[i]; + for (int j = 0; j < nb; j++) { + int sym = val_table[k++]; + huff_size[sym] = i; + huff_code[sym] = code; + code++; + } + code <<= 1; } - for (i = 0; i < m->huff_ncode; i++) { - table_id = m->huff_buffer[i].table_id; - code = m->huff_buffer[i].code; - - ff_mjpeg_encode_huffman_increment(ctx[table_id], code); - } - - ff_mjpeg_encode_huffman_close(&dc_luminance_ctx, - m->bits_dc_luminance, - m->val_dc_luminance, 12); - ff_mjpeg_encode_huffman_close(&dc_chrominance_ctx, - m->bits_dc_chrominance, - m->val_dc_chrominance, 12); - ff_mjpeg_encode_huffman_close(&ac_luminance_ctx, - m->bits_ac_luminance, - m->val_ac_luminance, 256); - ff_mjpeg_encode_huffman_close(&ac_chrominance_ctx, - m->bits_ac_chrominance, - m->val_ac_chrominance, 256); - - ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance, - m->huff_code_dc_luminance, - m->bits_dc_luminance, - m->val_dc_luminance); - ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance, - m->huff_code_dc_chrominance, - m->bits_dc_chrominance, - m->val_dc_chrominance); - ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance, - m->huff_code_ac_luminance, - m->bits_ac_luminance, - m->val_ac_luminance); - ff_mjpeg_build_huffman_codes(m->huff_size_ac_chrominance, - m->huff_code_ac_chrominance, - m->bits_ac_chrominance, - m->val_ac_chrominance); -} - -/** - * Writes the complete JPEG frame when optimal huffman tables are enabled, - * otherwise writes the stuffing. - * - * Header + values + stuffing. - * - * @param s The MpegEncContext. - * @return int Error code, 0 if successful. - */ -int ff_mjpeg_encode_stuffing(MpegEncContext *s) -{ - int i; - PutBitContext *pbc = &s->pb; - int mb_y = s->mb_y - !s->mb_x; - int ret; - MJpegContext *m; - - m = s->mjpeg_ctx; - - if (s->huffman == HUFFMAN_TABLE_OPTIMAL) { - ff_mjpeg_build_optimal_huffman(m); - - // Replace the VLCs with the optimal ones. - // The default ones may be used for trellis during quantization. - ff_init_uni_ac_vlc(m->huff_size_ac_luminance, m->uni_ac_vlc_len); - ff_init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len); - s->intra_ac_vlc_length = - s->intra_ac_vlc_last_length = m->uni_ac_vlc_len; - s->intra_chroma_ac_vlc_length = - s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len; - - ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable, - s->pred, s->intra_matrix, s->chroma_intra_matrix); - ff_mjpeg_encode_picture_frame(s); - } - - ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100, - put_bits_count(&s->pb) / 4 + 1000); - - if (ret < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Buffer reallocation failed\n"); - goto fail; - } - - ff_mjpeg_escape_FF(pbc, s->esc_pos); - - if((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height - 1) - put_marker(pbc, RST0 + (mb_y&7)); - s->esc_pos = put_bits_count(pbc) >> 3; -fail: - - for(i=0; i<3; i++) - s->last_dc[i] = 128 << s->intra_dc_precision; - - return ret; } void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits) diff --git a/libavcodec/mjpegenc_common.h b/libavcodec/mjpegenc_common.h index e8698d18c..b4f8a08e1 100644 --- a/libavcodec/mjpegenc_common.h +++ b/libavcodec/mjpegenc_common.h @@ -25,22 +25,20 @@ #include "avcodec.h" #include "idctdsp.h" -#include "mpegvideo.h" #include "put_bits.h" void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, ScanTable *intra_scantable, int pred, uint16_t luma_intra_matrix[64], uint16_t chroma_intra_matrix[64]); -void ff_mjpeg_encode_picture_frame(MpegEncContext *s); void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits); void ff_mjpeg_escape_FF(PutBitContext *pb, int start); -int ff_mjpeg_encode_stuffing(MpegEncContext *s); +void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, + const uint8_t *bits_table, + const uint8_t *val_table); void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[4], int vsample[4]); void ff_mjpeg_encode_dc(PutBitContext *pb, int val, uint8_t *huff_size, uint16_t *huff_code); -av_cold void ff_init_uni_ac_vlc(const uint8_t huff_size_ac[256], uint8_t *uni_ac_vlc_len); - #endif /* AVCODEC_MJPEGENC_COMMON_H */ diff --git a/libavcodec/mlp.c b/libavcodec/mlp.c index ddbab60c4..74363c3b9 100644 --- a/libavcodec/mlp.c +++ b/libavcodec/mlp.c @@ -23,6 +23,7 @@ #include "libavutil/crc.h" #include "libavutil/intreadwrite.h" +#include "libavutil/thread.h" #include "mlp.h" const uint8_t ff_mlp_huffman_tables[3][18][2] = { @@ -62,7 +63,6 @@ const uint64_t ff_mlp_channel_layouts[12] = { AV_CH_LAYOUT_4POINT1, AV_CH_LAYOUT_5POINT1_BACK, 0, }; -static int crc_init = 0; #if CONFIG_SMALL #define CRC_TABLE_SIZE 257 #else @@ -72,14 +72,17 @@ static AVCRC crc_63[CRC_TABLE_SIZE]; static AVCRC crc_1D[CRC_TABLE_SIZE]; static AVCRC crc_2D[CRC_TABLE_SIZE]; +static av_cold void mlp_init_crc(void) +{ + av_crc_init(crc_63, 0, 8, 0x63, sizeof(crc_63)); + av_crc_init(crc_1D, 0, 8, 0x1D, sizeof(crc_1D)); + av_crc_init(crc_2D, 0, 16, 0x002D, sizeof(crc_2D)); +} + av_cold void ff_mlp_init_crc(void) { - if (!crc_init) { - av_crc_init(crc_63, 0, 8, 0x63, sizeof(crc_63)); - av_crc_init(crc_1D, 0, 8, 0x1D, sizeof(crc_1D)); - av_crc_init(crc_2D, 0, 16, 0x002D, sizeof(crc_2D)); - crc_init = 1; - } + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, mlp_init_crc); } uint16_t ff_mlp_checksum16(const uint8_t *buf, unsigned int buf_size) diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 1a2c0f29a..0c30034dd 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -30,6 +30,8 @@ #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/channel_layout.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" #include "get_bits.h" #include "internal.h" #include "libavutil/crc.h" @@ -205,16 +207,13 @@ static VLC huff_vlc[3]; static av_cold void init_static(void) { - if (!huff_vlc[0].bits) { - INIT_VLC_STATIC(&huff_vlc[0], VLC_BITS, 18, - &ff_mlp_huffman_tables[0][0][1], 2, 1, - &ff_mlp_huffman_tables[0][0][0], 2, 1, VLC_STATIC_SIZE); - INIT_VLC_STATIC(&huff_vlc[1], VLC_BITS, 16, - &ff_mlp_huffman_tables[1][0][1], 2, 1, - &ff_mlp_huffman_tables[1][0][0], 2, 1, VLC_STATIC_SIZE); - INIT_VLC_STATIC(&huff_vlc[2], VLC_BITS, 15, - &ff_mlp_huffman_tables[2][0][1], 2, 1, - &ff_mlp_huffman_tables[2][0][0], 2, 1, VLC_STATIC_SIZE); + for (int i = 0; i < 3; i++) { + static VLC_TYPE vlc_buf[3 * VLC_STATIC_SIZE][2]; + huff_vlc[i].table = &vlc_buf[i * VLC_STATIC_SIZE]; + huff_vlc[i].table_allocated = VLC_STATIC_SIZE; + init_vlc(&huff_vlc[i], VLC_BITS, 18, + &ff_mlp_huffman_tables[i][0][1], 2, 1, + &ff_mlp_huffman_tables[i][0][0], 2, 1, INIT_VLC_USE_NEW_STATIC); } ff_mlp_init_crc(); @@ -279,15 +278,17 @@ static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp, static av_cold int mlp_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; MLPDecodeContext *m = avctx->priv_data; int substr; - init_static(); m->avctx = avctx; for (substr = 0; substr < MAX_SUBSTREAMS; substr++) m->substream[substr].lossless_check_data = 0xffffffff; ff_mlpdsp_init(&m->dsp); + ff_thread_once(&init_static_once, init_static); + return 0; } @@ -1338,7 +1339,8 @@ AVCodec ff_mlp_decoder = { .priv_data_size = sizeof(MLPDecodeContext), .init = mlp_decode_init, .decode = read_access_unit, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_TRUEHD_DECODER @@ -1350,6 +1352,7 @@ AVCodec ff_truehd_decoder = { .priv_data_size = sizeof(MLPDecodeContext), .init = mlp_decode_init, .decode = read_access_unit, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif /* CONFIG_TRUEHD_DECODER */ diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c index c6a7963c2..9782cb826 100644 --- a/libavcodec/mlpenc.c +++ b/libavcodec/mlpenc.c @@ -531,7 +531,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d. Supported " "sample rates are 44100, 88200, 176400, 48000, " "96000, and 192000.\n", avctx->sample_rate); - return -1; + return AVERROR(EINVAL); } ctx->coded_sample_rate[1] = -1 & 0xf; @@ -564,7 +564,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) default: av_log(avctx, AV_LOG_ERROR, "Sample format not supported. " "Only 16- and 24-bit samples are supported.\n"); - return -1; + return AVERROR(EINVAL); } ctx->coded_sample_fmt[1] = -1 & 0xf; @@ -638,7 +638,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) ctx->channel_arrangement = 12; break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n"); - return -1; + return AVERROR(EINVAL); } ctx->flags = FLAGS_DVDA; ctx->channel_occupancy = ff_mlp_ch_info[ctx->channel_arrangement].channel_occupancy; @@ -666,7 +666,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n"); - return -1; + return AVERROR(EINVAL); } ctx->flags = 0; ctx->channel_occupancy = 0; @@ -1190,7 +1190,7 @@ static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf, int total_length; if (buf_size < 4) - return -1; + return AVERROR(EINVAL); /* Frame header will be written at the end. */ buf += 4; @@ -1198,7 +1198,7 @@ static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf, if (restart_frame) { if (buf_size < 28) - return -1; + return AVERROR(EINVAL); write_major_sync(ctx, buf, buf_size); buf += 28; buf_size -= 28; @@ -1820,7 +1820,8 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel) if (!filter_state_buffer[i]) { av_log(ctx->avctx, AV_LOG_ERROR, "Not enough memory for applying filters.\n"); - return -1; + ret = AVERROR(ENOMEM); + goto free_and_return; } } @@ -1848,7 +1849,7 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel) residual = sample - (accum & mask); if (residual < SAMPLE_MIN(24) || residual > SAMPLE_MAX(24)) { - ret = -1; + ret = AVERROR_INVALIDDATA; goto free_and_return; } @@ -1946,24 +1947,16 @@ static void rematrix_channels(MLPEncodeContext *ctx) ****************************************************************************/ typedef struct { - char path[MAJOR_HEADER_INTERVAL + 3]; + char path[MAJOR_HEADER_INTERVAL + 2]; + int cur_idx; int bitcount; } PathCounter; -static const char *path_counter_codebook[] = { "0", "1", "2", "3", }; - -#define ZERO_PATH '0' #define CODEBOOK_CHANGE_BITS 21 static void clear_path_counter(PathCounter *path_counter) { - unsigned int i; - - for (i = 0; i < NUM_CODEBOOKS + 1; i++) { - path_counter[i].path[0] = ZERO_PATH; - path_counter[i].path[1] = 0x00; - path_counter[i].bitcount = 0; - } + memset(path_counter, 0, (NUM_CODEBOOKS + 1) * sizeof(*path_counter)); } static int compare_best_offset(BestOffset *prev, BestOffset *cur) @@ -1977,18 +1970,11 @@ static int compare_best_offset(BestOffset *prev, BestOffset *cur) static int best_codebook_path_cost(MLPEncodeContext *ctx, unsigned int channel, PathCounter *src, int cur_codebook) { - BestOffset *cur_bo, *prev_bo = restart_best_offset; + int idx = src->cur_idx; + BestOffset *cur_bo = ctx->best_offset[idx][channel], + *prev_bo = idx ? ctx->best_offset[idx - 1][channel] : restart_best_offset; int bitcount = src->bitcount; - char *path = src->path + 1; - int prev_codebook; - int i; - - for (i = 0; path[i]; i++) - prev_bo = ctx->best_offset[i][channel]; - - prev_codebook = path[i - 1] - ZERO_PATH; - - cur_bo = ctx->best_offset[i][channel]; + int prev_codebook = src->path[idx]; bitcount += cur_bo[cur_codebook].bitcount; @@ -2051,7 +2037,8 @@ static void set_best_codebook(MLPEncodeContext *ctx) prev_best_bitcount = temp_bitcount; if (src_path != dst_path) memcpy(dst_path, src_path, sizeof(PathCounter)); - av_strlcat(dst_path->path, path_counter_codebook[codebook], sizeof(dst_path->path)); + if (dst_path->cur_idx < FF_ARRAY_ELEMS(dst_path->path) - 1) + dst_path->path[++dst_path->cur_idx] = codebook; dst_path->bitcount = temp_bitcount; } } @@ -2068,7 +2055,7 @@ static void set_best_codebook(MLPEncodeContext *ctx) for (index = 0; index < ctx->number_of_subblocks; index++) { ChannelParams *cp = ctx->seq_channel_params + index*(ctx->avctx->channels) + channel; - best_codebook = *best_path++ - ZERO_PATH; + best_codebook = *best_path++; cur_bo = &ctx->best_offset[index][channel][best_codebook]; cp->huff_offset = cur_bo->offset; @@ -2226,9 +2213,6 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if ((ret = ff_alloc_packet2(avctx, avpkt, 87500 * avctx->channels, 0)) < 0) return ret; - if (!frame) - return 1; - /* add current frame to queue */ if ((ret = ff_af_queue_add(&ctx->afq, frame)) < 0) return ret; @@ -2267,7 +2251,7 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (ctx->frame_size[ctx->frame_index] > MAX_BLOCKSIZE) { av_log(avctx, AV_LOG_ERROR, "Invalid frame size (%d > %d)\n", ctx->frame_size[ctx->frame_index], MAX_BLOCKSIZE); - return -1; + return AVERROR_INVALIDDATA; } restart_frame = !ctx->frame_index; @@ -2389,10 +2373,11 @@ AVCodec ff_mlp_encoder = { .init = mlp_encode_init, .encode2 = mlp_encode_frame, .close = mlp_encode_close, - .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = ff_mlp_channel_layouts, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif #if CONFIG_TRUEHD_ENCODER @@ -2405,9 +2390,10 @@ AVCodec ff_truehd_encoder = { .init = mlp_encode_init, .encode2 = mlp_encode_frame, .close = mlp_encode_close, - .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = (const uint64_t[]) {AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, 0}, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c index 547bece57..cb15ac072 100644 --- a/libavcodec/mmaldec.c +++ b/libavcodec/mmaldec.c @@ -1,6 +1,6 @@ /* * MMAL Video Decoder - * Copyright (c) 2015 Rodger Combs + * Copyright (c) 2015 rcombs * * This file is part of FFmpeg. * @@ -34,6 +34,7 @@ #include #include "avcodec.h" +#include "decode.h" #include "hwconfig.h" #include "internal.h" #include "libavutil/avassert.h" @@ -808,7 +809,7 @@ static int ffmmal_decode(AVCodecContext *avctx, void *data, int *got_frame, return ret; } -static const AVCodecHWConfigInternal *mmal_hw_configs[] = { +static const AVCodecHWConfigInternal *const mmal_hw_configs[] = { HW_CONFIG_INTERNAL(MMAL), NULL }; diff --git a/libavcodec/mobiclip.c b/libavcodec/mobiclip.c new file mode 100644 index 000000000..bf47a5bc4 --- /dev/null +++ b/libavcodec/mobiclip.c @@ -0,0 +1,1355 @@ +/* + * MobiClip Video decoder + * Copyright (c) 2015-2016 Florian Nouwt + * Copyright (c) 2017 Adib Surani + * Copyright (c) 2020 Paul B Mahol + * + * 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/avassert.h" +#include "libavutil/thread.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "bswapdsp.h" +#include "get_bits.h" +#include "golomb.h" +#include "internal.h" + +#define MOBI_RL_VLC_BITS 12 +#define MOBI_MV_VLC_BITS 6 + +static const uint8_t zigzag4x4_tab[] = +{ + 0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A, + 0x0D, 0x0E, 0x0B, 0x0F +}; + +static const uint8_t quant4x4_tab[][16] = +{ + { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 }, + { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 }, + { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 }, + { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 }, + { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 }, + { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 }, +}; + +static const uint8_t quant8x8_tab[][64] = +{ + { 20, 19, 19, 25, 18, 25, 19, 24, 24, 19, 20, 18, 32, 18, 20, 19, 19, 24, 24, 19, 19, 25, 18, 25, 18, 25, 18, 25, 19, 24, 24, 19, + 19, 24, 24, 19, 18, 32, 18, 20, 18, 32, 18, 24, 24, 19, 19, 24, 24, 18, 25, 18, 25, 18, 19, 24, 24, 19, 18, 32, 18, 24, 24, 18,}, + { 22, 21, 21, 28, 19, 28, 21, 26, 26, 21, 22, 19, 35, 19, 22, 21, 21, 26, 26, 21, 21, 28, 19, 28, 19, 28, 19, 28, 21, 26, 26, 21, + 21, 26, 26, 21, 19, 35, 19, 22, 19, 35, 19, 26, 26, 21, 21, 26, 26, 19, 28, 19, 28, 19, 21, 26, 26, 21, 19, 35, 19, 26, 26, 19,}, + { 26, 24, 24, 33, 23, 33, 24, 31, 31, 24, 26, 23, 42, 23, 26, 24, 24, 31, 31, 24, 24, 33, 23, 33, 23, 33, 23, 33, 24, 31, 31, 24, + 24, 31, 31, 24, 23, 42, 23, 26, 23, 42, 23, 31, 31, 24, 24, 31, 31, 23, 33, 23, 33, 23, 24, 31, 31, 24, 23, 42, 23, 31, 31, 23,}, + { 28, 26, 26, 35, 25, 35, 26, 33, 33, 26, 28, 25, 45, 25, 28, 26, 26, 33, 33, 26, 26, 35, 25, 35, 25, 35, 25, 35, 26, 33, 33, 26, + 26, 33, 33, 26, 25, 45, 25, 28, 25, 45, 25, 33, 33, 26, 26, 33, 33, 25, 35, 25, 35, 25, 26, 33, 33, 26, 25, 45, 25, 33, 33, 25,}, + { 32, 30, 30, 40, 28, 40, 30, 38, 38, 30, 32, 28, 51, 28, 32, 30, 30, 38, 38, 30, 30, 40, 28, 40, 28, 40, 28, 40, 30, 38, 38, 30, + 30, 38, 38, 30, 28, 51, 28, 32, 28, 51, 28, 38, 38, 30, 30, 38, 38, 28, 40, 28, 40, 28, 30, 38, 38, 30, 28, 51, 28, 38, 38, 28,}, + { 36, 34, 34, 46, 32, 46, 34, 43, 43, 34, 36, 32, 58, 32, 36, 34, 34, 43, 43, 34, 34, 46, 32, 46, 32, 46, 32, 46, 34, 43, 43, 34, + 34, 43, 43, 34, 32, 58, 32, 36, 32, 58, 32, 43, 43, 34, 34, 43, 43, 32, 46, 32, 46, 32, 34, 43, 43, 34, 32, 58, 32, 43, 43, 32,}, +}; + +static const uint8_t block4x4_coefficients_tab[] = +{ + 15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6, +}; + +static const uint8_t pframe_block4x4_coefficients_tab[] = +{ + 0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6, +}; + +static const uint8_t block8x8_coefficients_tab[] = +{ + 0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D, + 0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B, + 0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14, + 0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34, + 0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C, + 0x2A, 0x28, 0x29, 0x26, +}; + +static const uint8_t pframe_block8x8_coefficients_tab[] = +{ + 0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09, + 0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20, + 0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C, + 0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36 +}; + +static const uint8_t run_residue[2][256] = +{ + { + 12, 6, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 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, 0, 0, 0, 0, + 1, 27, 11, 7, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 41, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }, + { + 27, 10, 5, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 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, + 8, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 15, 10, 8, 4, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 21, 7, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }, +}; + +static const uint8_t bits0[] = { + 9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 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, 7, 10, 10, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 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, + 6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 2, 3, 4, 4, +}; + +static const uint16_t syms0[] = { + 0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122, + 0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301, + 0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142, + 0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01, + 0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21, + 0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82, + 0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921, + 0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161, + 0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22, + 0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2, +}; + +static const uint16_t syms1[] = { + 0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83, + 0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01, + 0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21, + 0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804, + 0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901, + 0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861, + 0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22, + 0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3, +}; + +static const uint8_t mv_len[16] = +{ + 10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6, +}; + +static const uint8_t mv_bits[2][16][10] = +{ + { + { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 }, + { 2, 3, 4, 4, 3, 4, 4, 2 }, + { 3, 4, 4, 2, 4, 4, 3, 2 }, + { 1, 3, 4, 5, 5, 3, 3 }, + { 2, 4, 4, 3, 3, 4, 4, 2 }, + { 2, 3, 4, 4, 4, 4, 3, 2 }, + { 2, 3, 4, 4, 4, 4, 3, 2 }, + { 2, 2, 3, 4, 5, 5, 2 }, + { 2, 3, 4, 4, 3, 4, 4, 2 }, + { 2, 4, 4, 3, 4, 4, 3, 2 }, + { 2, 3, 3, 5, 5, 4, 3, 2 }, + { 2, 3, 4, 4, 3, 3, 2 }, + { 1, 4, 4, 3, 3, 4, 4 }, + { 2, 3, 4, 4, 3, 3, 2 }, + { 2, 3, 4, 4, 3, 3, 2 }, + { 3, 3, 2, 2, 3, 3 }, + }, + { + { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 }, + { 2, 3, 4, 5, 5, 2, 3, 3 }, + { 2, 4, 4, 3, 3, 4, 4, 2 }, + { 1, 4, 4, 3, 4, 4, 3 }, + { 3, 3, 2, 4, 5, 5, 3, 2 }, + { 3, 4, 4, 3, 3, 3, 3, 2 }, + { 1, 3, 3, 4, 4, 4, 5, 5 }, + { 1, 4, 4, 3, 3, 4, 4 }, + { 2, 4, 4, 3, 3, 4, 4, 2 }, + { 1, 3, 3, 4, 4, 4, 5, 5 }, + { 2, 3, 4, 4, 4, 4, 3, 2 }, + { 2, 3, 3, 4, 4, 3, 2 }, + { 1, 4, 4, 3, 3, 4, 4 }, + { 1, 4, 4, 3, 3, 4, 4 }, + { 2, 3, 3, 4, 4, 3, 2 }, + { 2, 3, 3, 3, 3, 2 }, + } +}; + +static const uint8_t mv_syms[2][16][10] = +{ + { + { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 }, + { 0, 9, 5, 4, 2, 3, 8, 1 }, + { 3, 9, 5, 0, 4, 8, 2, 1 }, + { 1, 3, 4, 8, 5, 2, 0 }, + { 0, 5, 4, 8, 2, 3, 9, 1 }, + { 0, 3, 5, 9, 4, 8, 2, 1 }, + { 0, 3, 9, 5, 8, 4, 2, 1 }, + { 0, 2, 3, 4, 8, 5, 1 }, + { 0, 3, 8, 4, 2, 5, 9, 1 }, + { 2, 8, 9, 3, 5, 4, 0, 1 }, + { 0, 4, 3, 8, 9, 5, 2, 1 }, + { 0, 4, 8, 5, 3, 2, 1 }, + { 1, 9, 4, 2, 0, 5, 3 }, + { 2, 4, 9, 5, 3, 0, 1 }, + { 0, 4, 9, 5, 3, 2, 1 }, + { 5, 4, 1, 0, 3, 2 }, + }, + { + { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 }, + { 9, 2, 3, 5, 4, 1, 8, 0 }, + { 0, 5, 4, 2, 9, 3, 8, 1 }, + { 1, 5, 4, 2, 8, 3, 0 }, + { 2, 9, 8, 3, 5, 4, 0, 1 }, + { 3, 5, 4, 2, 9, 8, 0, 1 }, + { 1, 2, 0, 9, 8, 3, 5, 4 }, + { 1, 8, 5, 2, 0, 4, 3 }, + { 0, 5, 4, 2, 8, 3, 9, 1 }, + { 1, 2, 0, 9, 8, 3, 5, 4 }, + { 0, 3, 9, 8, 5, 4, 2, 1 }, + { 0, 4, 3, 8, 5, 2, 1 }, + { 1, 5, 4, 2, 0, 9, 3 }, + { 1, 9, 5, 2, 0, 4, 3 }, + { 0, 5, 3, 9, 4, 2, 1 }, + { 0, 4, 5, 3, 2, 1 }, + } +}; + +typedef struct BlockXY { + int w, h; + int ax, ay; + int x, y; + int size; + uint8_t *block; + int linesize; +} BlockXY; + +typedef struct MotionXY { + int x, y; +} MotionXY; + +typedef struct MobiClipContext { + AVFrame *pic[6]; + + int current_pic; + int moflex; + int dct_tab_idx; + int quantizer; + + GetBitContext gb; + + uint8_t *bitstream; + int bitstream_size; + + int qtab[2][64]; + uint8_t pre[32]; + MotionXY *motion; + int motion_size; + + BswapDSPContext bdsp; +} MobiClipContext; + +static VLC rl_vlc[2]; +static VLC mv_vlc[2][16]; + +static av_cold void mobiclip_init_static(void) +{ + INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[0], MOBI_RL_VLC_BITS, 104, + bits0, sizeof(*bits0), + syms0, sizeof(*syms0), sizeof(*syms0), + 0, 0, 1 << MOBI_RL_VLC_BITS); + INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[1], MOBI_RL_VLC_BITS, 104, + bits0, sizeof(*bits0), + syms1, sizeof(*syms1), sizeof(*syms1), + 0, 0, 1 << MOBI_RL_VLC_BITS); + for (int i = 0; i < 2; i++) { + static VLC_TYPE vlc_buf[2 * 16 << MOBI_MV_VLC_BITS][2]; + for (int j = 0; j < 16; j++) { + mv_vlc[i][j].table = &vlc_buf[(16 * i + j) << MOBI_MV_VLC_BITS]; + mv_vlc[i][j].table_allocated = 1 << MOBI_MV_VLC_BITS; + ff_init_vlc_from_lengths(&mv_vlc[i][j], MOBI_MV_VLC_BITS, mv_len[j], + mv_bits[i][j], sizeof(*mv_bits[i][j]), + mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]), + 0, INIT_VLC_USE_NEW_STATIC, NULL); + } + } +} + +static av_cold int mobiclip_init(AVCodecContext *avctx) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + MobiClipContext *s = avctx->priv_data; + + if (avctx->width & 15 || avctx->height & 15) { + av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n"); + return AVERROR_INVALIDDATA; + } + + ff_bswapdsp_init(&s->bdsp); + + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + + s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY)); + if (!s->motion) + return AVERROR(ENOMEM); + s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY); + + for (int i = 0; i < 6; i++) { + s->pic[i] = av_frame_alloc(); + if (!s->pic[i]) + return AVERROR(ENOMEM); + } + + ff_thread_once(&init_static_once, mobiclip_init_static); + + return 0; +} + +static int setup_qtables(AVCodecContext *avctx, int quantizer) +{ + MobiClipContext *s = avctx->priv_data; + int qx, qy; + + if (quantizer < 12 || quantizer > 161) + return AVERROR_INVALIDDATA; + + s->quantizer = quantizer; + + qx = quantizer % 6; + qy = quantizer / 6; + + for (int i = 0; i < 16; i++) + s->qtab[0][i] = quant4x4_tab[qx][i] << qy; + + for (int i = 0; i < 64; i++) + s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2); + + for (int i = 0; i < 20; i++) + s->pre[i] = 9; + + return 0; +} + +static void inverse4(unsigned *rs) +{ + unsigned a = rs[0] + rs[2]; + unsigned b = rs[0] - rs[2]; + unsigned c = rs[1] + ((int)rs[3] >> 1); + unsigned d = ((int)rs[1] >> 1) - rs[3]; + + rs[0] = a + c; + rs[1] = b + d; + rs[2] = b - d; + rs[3] = a - c; +} + +static void idct(int *arr, int size) +{ + int e, f, g, h; + unsigned x3, x2, x1, x0; + int tmp[4]; + + if (size == 4) { + inverse4(arr); + return; + } + + tmp[0] = arr[0]; + tmp[1] = arr[2]; + tmp[2] = arr[4]; + tmp[3] = arr[6]; + + inverse4(tmp); + + e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1); + f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1); + g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1); + h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1); + x3 = (unsigned)g + (h >> 2); + x2 = (unsigned)e + (f >> 2); + x1 = (e >> 2) - (unsigned)f; + x0 = (unsigned)h - (g >> 2); + + arr[0] = tmp[0] + x0; + arr[1] = tmp[1] + x1; + arr[2] = tmp[2] + x2; + arr[3] = tmp[3] + x3; + arr[4] = tmp[3] - x3; + arr[5] = tmp[2] - x2; + arr[6] = tmp[1] - x1; + arr[7] = tmp[0] - x0; +} + +static void read_run_encoding(AVCodecContext *avctx, + int *last, int *run, int *level) +{ + MobiClipContext *s = avctx->priv_data; + GetBitContext *gb = &s->gb; + int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table, + MOBI_RL_VLC_BITS, 1); + + *last = (n >> 11) == 1; + *run = (n >> 5) & 0x3F; + *level = n & 0x1F; +} + +static int add_coefficients(AVCodecContext *avctx, AVFrame *frame, + int bx, int by, int size, int plane) +{ + MobiClipContext *s = avctx->priv_data; + GetBitContext *gb = &s->gb; + int mat[64] = { 0 }; + const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab; + const int *qtab = s->qtab[size == 8]; + uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx; + + for (int pos = 0; get_bits_left(gb) > 0; pos++) { + int qval, last, run, level; + + read_run_encoding(avctx, &last, &run, &level); + + if (level) { + if (get_bits1(gb)) + level = -level; + } else if (!get_bits1(gb)) { + read_run_encoding(avctx, &last, &run, &level); + level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run]; + if (get_bits1(gb)) + level = -level; + } else if (!get_bits1(gb)) { + read_run_encoding(avctx, &last, &run, &level); + run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level]; + if (get_bits1(gb)) + level = -level; + } else { + last = get_bits1(gb); + run = get_bits(gb, 6); + level = get_sbits(gb, 12); + } + + pos += run; + if (pos >= size * size) + return AVERROR_INVALIDDATA; + qval = qtab[pos]; + mat[ztab[pos]] = qval *(unsigned)level; + + if (last) + break; + } + + mat[0] += 32; + for (int y = 0; y < size; y++) + idct(&mat[y * size], size); + + for (int y = 0; y < size; y++) { + for (int x = y + 1; x < size; x++) { + int a = mat[x * size + y]; + int b = mat[y * size + x]; + + mat[y * size + x] = a; + mat[x * size + y] = b; + } + + idct(&mat[y * size], size); + for (int x = 0; x < size; x++) + dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6)); + dst += frame->linesize[plane]; + } + + return 0; +} + +static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame, + int bx, int by, int size, int plane) +{ + MobiClipContext *s = avctx->priv_data; + GetBitContext *gb = &s->gb; + int ret, idx = get_ue_golomb_31(gb); + + if (idx == 0) { + ret = add_coefficients(avctx, frame, bx, by, size, plane); + } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) { + int flags = pframe_block4x4_coefficients_tab[idx]; + + for (int y = by; y < by + 8; y += 4) { + for (int x = bx; x < bx + 8; x += 4) { + if (flags & 1) { + ret = add_coefficients(avctx, frame, x, y, 4, plane); + if (ret < 0) + return ret; + } + flags >>= 1; + } + } + } else { + ret = AVERROR_INVALIDDATA; + } + + return ret; +} + +static int adjust(int x, int size) +{ + return size == 16 ? (x + 1) >> 1 : x; +} + +static uint8_t pget(BlockXY b) +{ + BlockXY ret = b; + int x, y; + + if (b.x == -1 && b.y >= b.size) { + ret.x = -1, ret.y = b.size - 1; + } else if (b.x >= -1 && b.y >= -1) { + ret.x = b.x, ret.y = b.y; + } else if (b.x == -1 && b.y == -2) { + ret.x = 0, ret.y = -1; + } else if (b.x == -2 && b.y == -1) { + ret.x = -1, ret.y = 0; + } + + y = av_clip(ret.ay + ret.y, 0, ret.h - 1); + x = av_clip(ret.ax + ret.x, 0, ret.w - 1); + + return ret.block[y * ret.linesize + x]; +} + +static uint8_t half(int a, int b) +{ + return ((a + b) + 1) / 2; +} + +static uint8_t half3(int a, int b, int c) +{ + return ((a + b + b + c) * 2 / 4 + 1) / 2; +} + +static uint8_t pick_above(BlockXY bxy) +{ + bxy.y = bxy.y - 1; + + return pget(bxy); +} + +static uint8_t pick_left(BlockXY bxy) +{ + bxy.x = bxy.x - 1; + + return pget(bxy); +} + +static uint8_t half_horz(BlockXY bxy) +{ + BlockXY a = bxy, b = bxy, c = bxy; + + a.x -= 1; + c.x += 1; + + return half3(pget(a), pget(b), pget(c)); +} + +static uint8_t half_vert(BlockXY bxy) +{ + BlockXY a = bxy, b = bxy, c = bxy; + + a.y -= 1; + c.y += 1; + + return half3(pget(a), pget(b), pget(c)); +} + +static uint8_t pick_4(BlockXY bxy) +{ + int val; + + if ((bxy.x % 2) == 0) { + BlockXY ba, bb; + int a, b; + + ba = bxy; + ba.x = -1; + ba.y = bxy.y + bxy.x / 2; + a = pget(ba); + + bb = bxy; + bb.x = -1; + bb.y = bxy.y + bxy.x / 2 + 1; + b = pget(bb); + + val = half(a, b); + } else { + BlockXY ba; + + ba = bxy; + ba.x = -1; + ba.y = bxy.y + bxy.x / 2 + 1; + val = half_vert(ba); + } + + return val; +} + +static uint8_t pick_5(BlockXY bxy) +{ + int val; + + if (bxy.x == 0) { + BlockXY a = bxy; + BlockXY b = bxy; + + a.x = -1; + a.y -= 1; + + b.x = -1; + + val = half(pget(a), pget(b)); + } else if (bxy.y == 0) { + BlockXY a = bxy; + + a.x -= 2; + a.y -= 1; + + val = half_horz(a); + } else if (bxy.x == 1) { + BlockXY a = bxy; + + a.x -= 2; + a.y -= 1; + + val = half_vert(a); + } else { + BlockXY a = bxy; + + a.x -= 2; + a.y -= 1; + + val = pget(a); + } + + return val; +} + +static uint8_t pick_6(BlockXY bxy) +{ + int val; + + if (bxy.y == 0) { + BlockXY a = bxy; + BlockXY b = bxy; + + a.x -= 1; + a.y = -1; + + b.y = -1; + + val = half(pget(a), pget(b)); + } else if (bxy.x == 0) { + BlockXY a = bxy; + + a.x -= 1; + a.y -= 2; + + val = half_vert(a); + } else if (bxy.y == 1) { + BlockXY a = bxy; + + a.x -= 1; + a.y -= 2; + + val = half_horz(a); + } else { + BlockXY a = bxy; + + a.x -= 1; + a.y -= 2; + + val = pget(a); + } + + return val; +} + +static uint8_t pick_7(BlockXY bxy) +{ + int clr, acc1, acc2; + BlockXY a = bxy; + + a.x -= 1; + a.y -= 1; + clr = pget(a); + if (bxy.x && bxy.y) + return clr; + + if (bxy.x == 0) { + a.x = -1; + a.y = bxy.y; + } else { + a.x = bxy.x - 2; + a.y = -1; + } + acc1 = pget(a); + + if (bxy.y == 0) { + a.x = bxy.x; + a.y = -1; + } else { + a.x = -1; + a.y = bxy.y - 2; + } + acc2 = pget(a); + + return half3(acc1, clr, acc2); +} + +static uint8_t pick_8(BlockXY bxy) +{ + BlockXY ba = bxy; + BlockXY bb = bxy; + int val; + + if (bxy.y == 0) { + int a, b; + + ba.y = -1; + a = pget(ba); + + bb.x += 1; + bb.y = -1; + + b = pget(bb); + + val = half(a, b); + } else if (bxy.y == 1) { + ba.x += 1; + ba.y -= 2; + + val = half_horz(ba); + } else if (bxy.x < bxy.size - 1) { + ba.x += 1; + ba.y -= 2; + + val = pget(ba); + } else if (bxy.y % 2 == 0) { + int a, b; + + ba.x = bxy.y / 2 + bxy.size - 1; + ba.y = -1; + a = pget(ba); + + bb.x = bxy.y / 2 + bxy.size; + bb.y = -1; + + b = pget(bb); + + val = half(a, b); + } else { + ba.x = bxy.y / 2 + bxy.size; + ba.y = -1; + + val = half_horz(ba); + } + + return val; +} + +static void block_fill_simple(uint8_t *block, int size, int linesize, int fill) +{ + for (int y = 0; y < size; y++) { + memset(block, fill, size); + block += linesize; + } +} + +static void block_fill(uint8_t *block, int size, int linesize, + int w, int h, int ax, int ay, + uint8_t (*pick)(BlockXY bxy)) +{ + BlockXY bxy; + + bxy.size = size; + bxy.block = block; + bxy.linesize = linesize; + bxy.w = w; + bxy.h = h; + bxy.ay = ay; + bxy.ax = ax; + + for (int y = 0; y < size; y++) { + bxy.y = y; + for (int x = 0; x < size; x++) { + uint8_t val; + + bxy.x = x; + + val = pick(bxy); + + block[ax + x + (ay + y) * linesize] = val; + } + } +} + +static int block_sum(const uint8_t *block, int w, int h, int linesize) +{ + int sum = 0; + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + sum += block[x]; + } + block += linesize; + } + + return sum; +} + +static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay, + int pmode, int add_coeffs, int size, int plane) +{ + MobiClipContext *s = avctx->priv_data; + GetBitContext *gb = &s->gb; + int w = avctx->width >> !!plane, h = avctx->height >> !!plane; + int ret = 0; + + switch (pmode) { + case 0: + block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above); + break; + case 1: + block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left); + break; + case 2: + { + int arr1[16]; + int arr2[16]; + uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax; + uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0); + int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)]; + int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1]; + int avg = (bottommost + rightmost + 1) / 2 + 2 * av_clip(get_se_golomb(gb), -(1<<16), 1<<16); + int r6 = adjust(avg - bottommost, size); + int r9 = adjust(avg - rightmost, size); + int shift = adjust(size, size) == 8 ? 3 : 2; + uint8_t *block; + + for (int x = 0; x < size; x++) { + int val = top[x]; + arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size); + } + + for (int y = 0; y < size; y++) { + int val = left[y * frame->linesize[plane]]; + arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size); + } + + block = frame->data[plane] + ay * frame->linesize[plane] + ax; + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) + + arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF; + } + block += frame->linesize[plane]; + left += frame->linesize[plane]; + } + } + break; + case 3: + { + uint8_t fill; + + if (ax == 0 && ay == 0) { + fill = 0x80; + } else if (ax >= 1 && ay >= 1) { + int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1, + 1, size, frame->linesize[plane]); + int top = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax, + size, 1, frame->linesize[plane]); + + fill = ((left + top) * 2 / (2 * size) + 1) / 2; + } else if (ax >= 1) { + fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1, + 1, size, frame->linesize[plane]) * 2 / size + 1) / 2; + } else if (ay >= 1) { + fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax, + size, 1, frame->linesize[plane]) * 2 / size + 1) / 2; + } else { + return -1; + } + + block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax, + size, frame->linesize[plane], fill); + } + break; + case 4: + block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4); + break; + case 5: + block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5); + break; + case 6: + block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6); + break; + case 7: + block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7); + break; + case 8: + block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8); + break; + } + + if (add_coeffs) + ret = add_coefficients(avctx, frame, ax, ay, size, plane); + + return ret; +} + +static int get_prediction(AVCodecContext *avctx, int x, int y, int size) +{ + MobiClipContext *s = avctx->priv_data; + GetBitContext *gb = &s->gb; + int index = (y & 0xC) | (x / 4 % 4); + + uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]); + if (val == 9) + val = 3; + + if (!get_bits1(gb)) { + int x = get_bits(gb, 3); + val = x + (x >= val ? 1 : 0); + } + + s->pre[index + 4] = val; + if (size == 8) + s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val; + + return val; +} + +static int process_block(AVCodecContext *avctx, AVFrame *frame, + int x, int y, int pmode, int has_coeffs, int plane) +{ + MobiClipContext *s = avctx->priv_data; + GetBitContext *gb = &s->gb; + int tmp, ret; + + if (!has_coeffs) { + if (pmode < 0) + pmode = get_prediction(avctx, x, y, 8); + return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane); + } + + tmp = get_ue_golomb_31(gb); + if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab)) + return AVERROR_INVALIDDATA; + + if (tmp == 0) { + if (pmode < 0) + pmode = get_prediction(avctx, x, y, 8); + ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane); + } else { + int flags = block4x4_coefficients_tab[tmp - 1]; + + for (int by = y; by < y + 8; by += 4) { + for (int bx = x; bx < x + 8; bx += 4) { + int new_pmode = pmode; + + if (new_pmode < 0) + new_pmode = get_prediction(avctx, bx, by, 4); + ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane); + if (ret < 0) + return ret; + flags >>= 1; + } + } + } + + return ret; +} + +static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame, + int x, int y, int predict) +{ + MobiClipContext *s = avctx->priv_data; + GetBitContext *gb = &s->gb; + int flags, pmode_uv, idx = get_ue_golomb(gb); + int ret = 0; + + if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab)) + return AVERROR_INVALIDDATA; + + flags = block8x8_coefficients_tab[idx]; + + if (predict) { + ret = process_block(avctx, frame, x, y, -1, flags & 1, 0); + if (ret < 0) + return ret; + flags >>= 1; + ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0); + if (ret < 0) + return ret; + flags >>= 1; + ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0); + if (ret < 0) + return ret; + flags >>= 1; + ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0); + if (ret < 0) + return ret; + flags >>= 1; + } else { + int pmode = get_bits(gb, 3); + + if (pmode == 2) { + ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0); + if (ret < 0) + return ret; + pmode = 9; + } + + ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0); + if (ret < 0) + return ret; + flags >>= 1; + ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0); + if (ret < 0) + return ret; + flags >>= 1; + ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0); + if (ret < 0) + return ret; + flags >>= 1; + ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0); + if (ret < 0) + return ret; + flags >>= 1; + } + + pmode_uv = get_bits(gb, 3); + if (pmode_uv == 2) { + ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex); + if (ret < 0) + return ret; + ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex); + if (ret < 0) + return ret; + pmode_uv = 9; + } + + ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex); + if (ret < 0) + return ret; + flags >>= 1; + ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex); + if (ret < 0) + return ret; + + return 0; +} + +static int get_index(int x) +{ + return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0; +} + +static int predict_motion(AVCodecContext *avctx, + int width, int height, int index, + int offsetm, int offsetx, int offsety) +{ + MobiClipContext *s = avctx->priv_data; + MotionXY *motion = s->motion; + GetBitContext *gb = &s->gb; + int fheight = avctx->height; + int fwidth = avctx->width; + + if (index <= 5) { + int sidx = -FFMAX(1, index) + s->current_pic; + MotionXY mv = s->motion[0]; + + if (sidx < 0) + sidx += 6; + + if (index > 0) { + mv.x = mv.x + (unsigned)get_se_golomb(gb); + mv.y = mv.y + (unsigned)get_se_golomb(gb); + } + if (mv.x >= INT_MAX || mv.y >= INT_MAX) + return AVERROR_INVALIDDATA; + + motion[offsetm].x = mv.x; + motion[offsetm].y = mv.y; + + for (int i = 0; i < 3; i++) { + int method, src_linesize, dst_linesize; + uint8_t *src, *dst; + + if (i == 1) { + offsetx = offsetx >> 1; + offsety = offsety >> 1; + mv.x = mv.x >> 1; + mv.y = mv.y >> 1; + width = width >> 1; + height = height >> 1; + fwidth = fwidth >> 1; + fheight = fheight >> 1; + } + + av_assert0(s->pic[sidx]); + av_assert0(s->pic[s->current_pic]); + av_assert0(s->pic[s->current_pic]->data[i]); + if (!s->pic[sidx]->data[i]) + return AVERROR_INVALIDDATA; + + method = (mv.x & 1) | ((mv.y & 1) << 1); + src_linesize = s->pic[sidx]->linesize[i]; + dst_linesize = s->pic[s->current_pic]->linesize[i]; + dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize; + + if (offsetx + (mv.x >> 1) < 0 || + offsety + (mv.y >> 1) < 0 || + offsetx + width + (mv.x + 1 >> 1) > fwidth || + offsety + height + (mv.y + 1 >> 1) > fheight) + return AVERROR_INVALIDDATA; + + switch (method) { + case 0: + src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) + + (offsety + (mv.y >> 1)) * src_linesize; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) + dst[x] = src[x]; + dst += dst_linesize; + src += src_linesize; + } + break; + case 1: + src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) + + (offsety + (mv.y >> 1)) * src_linesize; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1)); + } + + dst += dst_linesize; + src += src_linesize; + } + break; + case 2: + src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) + + (offsety + (mv.y >> 1)) * src_linesize; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1)); + } + + dst += dst_linesize; + src += src_linesize; + } + break; + case 3: + src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) + + (offsety + (mv.y >> 1)) * src_linesize; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) + + (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1)); + } + + dst += dst_linesize; + src += src_linesize; + } + break; + } + } + } else { + int tidx; + int adjx = index == 8 ? 0 : width / 2; + int adjy = index == 8 ? height / 2 : 0; + + width = width - adjx; + height = height - adjy; + tidx = get_index(height) * 4 + get_index(width); + + for (int i = 0; i < 2; i++) { + int ret, idx2; + + idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table, + MOBI_MV_VLC_BITS, 1); + + ret = predict_motion(avctx, width, height, idx2, + offsetm, offsetx + i * adjx, offsety + i * adjy); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static int mobiclip_decode(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *pkt) +{ + MobiClipContext *s = avctx->priv_data; + GetBitContext *gb = &s->gb; + AVFrame *frame = s->pic[s->current_pic]; + int ret; + + av_fast_padded_malloc(&s->bitstream, &s->bitstream_size, + pkt->size); + + if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0) + return ret; + + s->bdsp.bswap16_buf((uint16_t *)s->bitstream, + (uint16_t *)pkt->data, + (pkt->size + 1) >> 1); + + ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2)); + if (ret < 0) + return ret; + + if (get_bits1(gb)) { + frame->pict_type = AV_PICTURE_TYPE_I; + frame->key_frame = 1; + s->moflex = get_bits1(gb); + s->dct_tab_idx = get_bits1(gb); + + ret = setup_qtables(avctx, get_bits(gb, 6)); + if (ret < 0) + return ret; + + for (int y = 0; y < avctx->height; y += 16) { + for (int x = 0; x < avctx->width; x += 16) { + ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb)); + if (ret < 0) + return ret; + } + } + } else { + MotionXY *motion = s->motion; + + memset(motion, 0, s->motion_size); + + frame->pict_type = AV_PICTURE_TYPE_P; + frame->key_frame = 0; + s->dct_tab_idx = 0; + + ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb)); + if (ret < 0) + return ret; + + for (int y = 0; y < avctx->height; y += 16) { + for (int x = 0; x < avctx->width; x += 16) { + int idx; + + motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x); + motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y); + motion[x / 16 + 2].x = 0; + motion[x / 16 + 2].y = 0; + + idx = get_vlc2(gb, mv_vlc[s->moflex][0].table, + MOBI_MV_VLC_BITS, 1); + + if (idx == 6 || idx == 7) { + ret = decode_macroblock(avctx, frame, x, y, idx == 7); + if (ret < 0) + return ret; + } else { + int flags, idx2; + ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y); + if (ret < 0) + return ret; + idx2 = get_ue_golomb(gb); + if (idx2 >= FF_ARRAY_ELEMS(pframe_block8x8_coefficients_tab)) + return AVERROR_INVALIDDATA; + flags = pframe_block8x8_coefficients_tab[idx2]; + + for (int sy = y; sy < y + 16; sy += 8) { + for (int sx = x; sx < x + 16; sx += 8) { + if (flags & 1) + add_pframe_coefficients(avctx, frame, sx, sy, 8, 0); + flags >>= 1; + } + } + + if (flags & 1) + add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex); + flags >>= 1; + if (flags & 1) + add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex); + } + } + } + } + + if (!s->moflex) + avctx->colorspace = AVCOL_SPC_YCGCO; + + s->current_pic = (s->current_pic + 1) % 6; + ret = av_frame_ref(data, frame); + if (ret < 0) + return ret; + *got_frame = 1; + + return 0; +} + +static void mobiclip_flush(AVCodecContext *avctx) +{ + MobiClipContext *s = avctx->priv_data; + + for (int i = 0; i < 6; i++) + av_frame_unref(s->pic[i]); +} + +static av_cold int mobiclip_close(AVCodecContext *avctx) +{ + MobiClipContext *s = avctx->priv_data; + + av_freep(&s->bitstream); + s->bitstream_size = 0; + av_freep(&s->motion); + s->motion_size = 0; + + for (int i = 0; i < 6; i++) { + av_frame_free(&s->pic[i]); + } + + return 0; +} + +AVCodec ff_mobiclip_decoder = { + .name = "mobiclip", + .long_name = NULL_IF_CONFIG_SMALL("MobiClip Video"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_MOBICLIP, + .priv_data_size = sizeof(MobiClipContext), + .init = mobiclip_init, + .decode = mobiclip_decode, + .flush = mobiclip_flush, + .close = mobiclip_close, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, +}; diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index 02c75fd47..5b0958733 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -109,8 +109,8 @@ static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, co me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel){ MotionEstContext * const c= &s->me; const int stride= c->stride; - const int hx= subx + (x<<(1+qpel)); - const int hy= suby + (y<<(1+qpel)); + const int hx = subx + x * (1 << (1 + qpel)); + const int hy = suby + y * (1 << (1 + qpel)); uint8_t * const * const ref= c->ref[ref_index]; uint8_t * const * const src= c->src[src_index]; int d; @@ -578,7 +578,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) int dmin_sum=0, mx4_sum=0, my4_sum=0, i; int same=1; const int stride= c->stride; - uint8_t *mv_penalty= c->current_mv_penalty; + const uint8_t *mv_penalty = c->current_mv_penalty; int safety_clipping= s->unrestricted_mv && (s->width&15) && (s->height&15); init_mv4_ref(c); @@ -599,7 +599,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; - if(P_LEFT[0] > (c->xmax<xmax< c->xmax * (1 << shift)) P_LEFT[0] = c->xmax * (1 << shift); /* special case for first line */ if (s->first_slice_line && block<2) { @@ -610,10 +610,10 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0]; P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1]; - if(P_TOP[1] > (c->ymax<ymax<xmin<xmin< (c->xmax<xmax< (c->ymax<ymax< c->ymax * (1 << shift)) P_TOP[1] = c->ymax * (1 << shift); + if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift); + if (P_TOPRIGHT[0] > c->xmax * (1 << shift)) P_TOPRIGHT[0] = c->xmax * (1 << shift); + if (P_TOPRIGHT[1] > c->ymax * (1 << shift)) P_TOPRIGHT[1] = c->ymax * (1 << shift); P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); @@ -629,8 +629,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) continue; if (i>4 && i<9) continue; - if(P[i][0] > (c->xmax<xmax< (c->ymax<ymax< c->xmax * (1 << shift)) P[i][0] = c->xmax * (1 << shift); + if (P[i][1] > c->ymax * (1 << shift)) P[i][1] = c->ymax * (1 <p_mv_table, (1<<16)>>shift, 1); @@ -743,7 +743,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index, const int h=8; int block; int P[10][2]; - uint8_t * const mv_penalty= c->current_mv_penalty; + const uint8_t * const mv_penalty = c->current_mv_penalty; int same=1; const int stride= 2*s->linesize; int dmin_sum= 0; @@ -785,7 +785,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index, P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0]; P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1]; if(P_TOP[1] > (c->ymax<<1)) P_TOP[1] = (c->ymax<<1); - if(P_TOPRIGHT[0] < (c->xmin<<1)) P_TOPRIGHT[0]= (c->xmin<<1); + if (P_TOPRIGHT[0] < c->xmin * (1 << 1)) P_TOPRIGHT[0] = c->xmin * (1 << 1); if(P_TOPRIGHT[0] > (c->xmax<<1)) P_TOPRIGHT[0]= (c->xmax<<1); if(P_TOPRIGHT[1] > (c->ymax<<1)) P_TOPRIGHT[1]= (c->ymax<<1); @@ -839,7 +839,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index, dmin_sum += best_dmin; } - c->ymin<<=1; + c->ymin *= 2; c->ymax<<=1; c->stride>>=1; c->uvstride>>=1; @@ -981,8 +981,8 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, if(mx || my) mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference }else{ - mx <<=shift; - my <<=shift; + mx *= 1 << shift; + my *= 1 << shift; } if ((s->avctx->flags & AV_CODEC_FLAG_4MV) && !c->skip && varc>50<<8 && vard>10<<8){ @@ -1120,7 +1120,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, const int shift= 1+s->quarter_sample; const int mot_stride = s->mb_stride; const int mot_xy = mb_y*mot_stride + mb_x; - uint8_t * const mv_penalty= c->mv_penalty[f_code] + MAX_DMV; + const uint8_t * const mv_penalty = c->mv_penalty[f_code] + MAX_DMV; int mv_scale; c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); @@ -1143,7 +1143,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0]; P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1][1]; if (P_TOP[1] > (c->ymax << shift)) P_TOP[1] = (c->ymax << shift); - if (P_TOPRIGHT[0] < (c->xmin << shift)) P_TOPRIGHT[0] = (c->xmin << shift); + if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift); if (P_TOPRIGHT[1] > (c->ymax << shift)) P_TOPRIGHT[1] = (c->ymax << shift); P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); @@ -1155,7 +1155,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, if(mv_table == s->b_forw_mv_table){ mv_scale= (s->pb_time<<16) / (s->pp_time<pb_time - s->pp_time)<<16) / (s->pp_time<pb_time - s->pp_time) * (1 << 16)) / (s->pp_time<p_mv_table, mv_scale, 0, 16); @@ -1184,8 +1184,8 @@ static inline int check_bidir_mv(MpegEncContext * s, //FIXME better f_code prediction (max mv & distance) //FIXME pointers MotionEstContext * const c= &s->me; - uint8_t * const mv_penalty_f= c->mv_penalty[s->f_code] + MAX_DMV; // f_code of the prev frame - uint8_t * const mv_penalty_b= c->mv_penalty[s->b_code] + MAX_DMV; // f_code of the prev frame + const uint8_t * const mv_penalty_f = c->mv_penalty[s->f_code] + MAX_DMV; // f_code of the prev frame + const uint8_t * const mv_penalty_b = c->mv_penalty[s->b_code] + MAX_DMV; // f_code of the prev frame int stride= c->stride; uint8_t *dest_y = c->scratchpad; uint8_t *ptr; @@ -1255,8 +1255,8 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y) const int flags= c->sub_flags; const int qpel= flags&FLAG_QPEL; const int shift= 1+qpel; - const int xmin= c->xmin<ymin<xmin * (1 << shift); + const int ymin= c->ymin * (1 << shift); const int xmax= c->xmax<ymax<pred_x=0; c->pred_y=0; - P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin<first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped - P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin<motion_est != FF_ME_ZERO) { int score[8]; int i, y, range= s->avctx->me_range ? s->avctx->me_range : (INT_MAX/2); - uint8_t * fcode_tab= s->fcode_tab; + const uint8_t * fcode_tab = s->fcode_tab; int best_fcode=-1; int best_score=-10000000; diff --git a/libavcodec/motion_est.h b/libavcodec/motion_est.h index 817220f34..5742e5148 100644 --- a/libavcodec/motion_est.h +++ b/libavcodec/motion_est.h @@ -90,8 +90,8 @@ typedef struct MotionEstContext { op_pixels_func(*hpel_avg)[4]; qpel_mc_func(*qpel_put)[16]; qpel_mc_func(*qpel_avg)[16]; - uint8_t (*mv_penalty)[MAX_DMV * 2 + 1]; ///< bit amount needed to encode a MV - uint8_t *current_mv_penalty; + const uint8_t (*mv_penalty)[MAX_DMV * 2 + 1]; ///< bit amount needed to encode a MV + const uint8_t *current_mv_penalty; int (*sub_motion_search)(struct MpegEncContext *s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c index 13e73f265..6ab0ea13d 100644 --- a/libavcodec/motion_est_template.c +++ b/libavcodec/motion_est_template.c @@ -34,7 +34,7 @@ const int av_unused ymin= c->ymin;\ const int av_unused xmax= c->xmax;\ const int av_unused ymax= c->ymax;\ - uint8_t *mv_penalty= c->current_mv_penalty;\ + const uint8_t *mv_penalty = c->current_mv_penalty; \ const int pred_x= c->pred_x;\ const int pred_y= c->pred_y;\ @@ -82,7 +82,7 @@ static int hpel_motion_search(MpegEncContext * s, if (mx > xmin && mx < xmax && my > ymin && my < ymax) { int d= dmin; - const int index= (my<penalty_factor; const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)] @@ -95,13 +95,13 @@ static int hpel_motion_search(MpegEncContext * s, #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 unsigned key; unsigned map_generation= c->map_generation; - key= ((my-1)<map[(index-(1<map[(index+(1<map[(index+1)&(ME_MAP_SIZE-1)] == key); - key= ((my)<map[(index-1)&(ME_MAP_SIZE-1)] == key); #endif if(t<=b){ @@ -246,7 +246,7 @@ static int qpel_motion_search(MpegEncContext * s, int bx=4*mx, by=4*my; int d= dmin; int i, nx, ny; - const int index= (my<priv_data; int w4 = (avctx->width + 3) & ~3; int h4 = (avctx->height + 3) & ~3; @@ -74,26 +78,23 @@ static av_cold int mp_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - motionpixels_tableinit(); mp->avctx = avctx; ff_bswapdsp_init(&mp->bdsp); mp->changes_map = av_mallocz_array(avctx->width, h4); mp->offset_bits_len = av_log2(avctx->width * avctx->height) + 1; mp->vpt = av_mallocz_array(avctx->height, sizeof(YuvPixel)); mp->hpt = av_mallocz_array(h4 / 4, w4 / 4 * sizeof(YuvPixel)); - if (!mp->changes_map || !mp->vpt || !mp->hpt) { - av_freep(&mp->changes_map); - av_freep(&mp->vpt); - av_freep(&mp->hpt); + if (!mp->changes_map || !mp->vpt || !mp->hpt) return AVERROR(ENOMEM); - } avctx->pix_fmt = AV_PIX_FMT_RGB555; mp->frame = av_frame_alloc(); - if (!mp->frame) { - mp_decode_end(avctx); + if (!mp->frame) return AVERROR(ENOMEM); - } + +#if !CONFIG_HARDCODED_TABLES + ff_thread_once(&init_static_once, motionpixels_tableinit); +#endif return 0; } @@ -127,7 +128,7 @@ static void mp_read_changes_map(MotionPixelsContext *mp, GetBitContext *gb, int } } -static int mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size, int code) +static int mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size) { while (get_bits1(gb)) { ++size; @@ -135,16 +136,14 @@ static int mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size, int av_log(mp->avctx, AV_LOG_ERROR, "invalid code size %d/%d\n", size, mp->max_codes_bits); return AVERROR_INVALIDDATA; } - code <<= 1; - if (mp_get_code(mp, gb, size, code + 1) < 0) + if (mp_get_code(mp, gb, size) < 0) return AVERROR_INVALIDDATA; } - if (mp->current_codes_count >= MAX_HUFF_CODES) { + if (mp->current_codes_count >= mp->codes_count) { av_log(mp->avctx, AV_LOG_ERROR, "too many codes\n"); return AVERROR_INVALIDDATA; } - mp->codes[mp->current_codes_count ].code = code; mp->codes[mp->current_codes_count++].size = size; return 0; } @@ -161,7 +160,7 @@ static int mp_read_codes_table(MotionPixelsContext *mp, GetBitContext *gb) for (i = 0; i < mp->codes_count; ++i) mp->codes[i].delta = get_bits(gb, 4); mp->current_codes_count = 0; - if ((ret = mp_get_code(mp, gb, 0, 0)) < 0) + if ((ret = mp_get_code(mp, gb, 0)) < 0) return ret; if (mp->current_codes_count < mp->codes_count) { av_log(mp->avctx, AV_LOG_ERROR, "too few codes\n"); @@ -198,12 +197,8 @@ static void mp_set_rgb_from_yuv(MotionPixelsContext *mp, int x, int y, const Yuv static av_always_inline int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb) { - int i; - - i = (mp->codes_count == 1) ? 0 : get_vlc2(gb, mp->vlc.table, mp->max_codes_bits, 1); - if (i < 0) - return i; - return mp->codes[i].delta; + return mp->vlc.table ? get_vlc2(gb, mp->vlc.table, mp->max_codes_bits, 1) + : mp->codes[0].delta; } static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y) @@ -330,10 +325,16 @@ static int mp_decode_frame(AVCodecContext *avctx, if (sz == 0) goto end; - if (mp->max_codes_bits <= 0) - goto end; - if (init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0)) - goto end; + if (mp->codes_count > 1) { + /* The entries of the mp->codes array are sorted from right to left + * in the Huffman tree, hence -(int)sizeof(HuffCode). */ + ret = ff_init_vlc_from_lengths(&mp->vlc, mp->max_codes_bits, mp->codes_count, + &mp->codes[mp->codes_count - 1].size, -(int)sizeof(HuffCode), + &mp->codes[mp->codes_count - 1].delta, -(int)sizeof(HuffCode), 1, + 0, 0, avctx); + if (ret < 0) + goto end; + } mp_decode_frame_helper(mp, &gb); ff_free_vlc(&mp->vlc); @@ -354,4 +355,5 @@ AVCodec ff_motionpixels_decoder = { .close = mp_decode_end, .decode = mp_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/motionpixels_tablegen.h b/libavcodec/motionpixels_tablegen.h index 9239b6a66..fd10c80cb 100644 --- a/libavcodec/motionpixels_tablegen.h +++ b/libavcodec/motionpixels_tablegen.h @@ -84,8 +84,7 @@ static av_cold void mp_build_rgb_yuv_table(YuvPixel *p) static av_cold void motionpixels_tableinit(void) { - if (!mp_rgb_yuv_table[0].u) - mp_build_rgb_yuv_table(mp_rgb_yuv_table); + mp_build_rgb_yuv_table(mp_rgb_yuv_table); } #endif /* CONFIG_HARDCODED_TABLES */ diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c index 4a21dbf36..7adc16d26 100644 --- a/libavcodec/movtextdec.c +++ b/libavcodec/movtextdec.c @@ -27,6 +27,7 @@ #include "libavutil/bprint.h" #include "libavutil/intreadwrite.h" #include "libavutil/mem.h" +#include "bytestream.h" #define STYLE_FLAG_BOLD (1<<0) #define STYLE_FLAG_ITALIC (1<<1) @@ -98,19 +99,16 @@ typedef struct { typedef struct { AVClass *class; - StyleBox **s; - StyleBox *s_temp; + StyleBox *s; HighlightBox h; HilightcolorBox c; - FontRecord **ftab; - FontRecord *ftab_temp; + FontRecord *ftab; TextWrapBox w; MovTextDefault d; uint8_t box_flags; uint16_t style_entries, ftab_entries; uint64_t tracksize; int size_var; - int count_s, count_f; int readorder; int frame_width; int frame_height; @@ -119,55 +117,42 @@ typedef struct { typedef struct { uint32_t type; size_t base_size; - int (*decode)(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt); + int (*decode)(const uint8_t *tsmb, MovTextContext *m, const AVPacket *avpkt); } Box; static void mov_text_cleanup(MovTextContext *m) { - int i; if (m->box_flags & STYL_BOX) { - for(i = 0; i < m->count_s; i++) { - av_freep(&m->s[i]); - } av_freep(&m->s); - m->count_s = 0; m->style_entries = 0; } } static void mov_text_cleanup_ftab(MovTextContext *m) { - int i; - if (m->ftab_temp) - av_freep(&m->ftab_temp->font); - av_freep(&m->ftab_temp); - if (m->ftab) { - for(i = 0; i < m->count_f; i++) { - av_freep(&m->ftab[i]->font); - av_freep(&m->ftab[i]); - } - } + for (unsigned i = 0; i < m->ftab_entries; i++) + av_freep(&m->ftab[i].font); av_freep(&m->ftab); + m->ftab_entries = 0; } static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) { - uint8_t *tx3g_ptr = avctx->extradata; - int i, box_size, font_length; + const uint8_t *tx3g_ptr = avctx->extradata; + int i, j = -1, font_length, remaining = avctx->extradata_size - BOX_SIZE_INITIAL; int8_t v_align, h_align; + unsigned ftab_entries; StyleBox s_default; - m->count_f = 0; m->ftab_entries = 0; - box_size = BOX_SIZE_INITIAL; /* Size till ftab_entries */ - if (avctx->extradata_size < box_size) + if (remaining < 0) return -1; // Display Flags tx3g_ptr += 4; // Alignment - h_align = *tx3g_ptr++; - v_align = *tx3g_ptr++; + h_align = bytestream_get_byte(&tx3g_ptr); + v_align = bytestream_get_byte(&tx3g_ptr); if (h_align == 0) { if (v_align == 0) m->d.alignment = TOP_LEFT; @@ -193,158 +178,133 @@ static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) m->d.alignment = BOTTOM_RIGHT; } // Background Color - m->d.back_color = AV_RB24(tx3g_ptr); - tx3g_ptr += 3; - m->d.back_alpha = AV_RB8(tx3g_ptr); - tx3g_ptr += 1; + m->d.back_color = bytestream_get_be24(&tx3g_ptr); + m->d.back_alpha = bytestream_get_byte(&tx3g_ptr); // BoxRecord tx3g_ptr += 8; // StyleRecord tx3g_ptr += 4; // fontID - m->d.fontID = AV_RB16(tx3g_ptr); - tx3g_ptr += 2; + m->d.fontID = bytestream_get_be16(&tx3g_ptr); // face-style-flags - s_default.style_flag = *tx3g_ptr++; + s_default.style_flag = bytestream_get_byte(&tx3g_ptr); m->d.bold = !!(s_default.style_flag & STYLE_FLAG_BOLD); m->d.italic = !!(s_default.style_flag & STYLE_FLAG_ITALIC); m->d.underline = !!(s_default.style_flag & STYLE_FLAG_UNDERLINE); // fontsize - m->d.fontsize = *tx3g_ptr++; + m->d.fontsize = bytestream_get_byte(&tx3g_ptr); // Primary color - m->d.color = AV_RB24(tx3g_ptr); - tx3g_ptr += 3; - m->d.alpha = AV_RB8(tx3g_ptr); - tx3g_ptr += 1; + m->d.color = bytestream_get_be24(&tx3g_ptr); + m->d.alpha = bytestream_get_byte(&tx3g_ptr); // FontRecord // FontRecord Size tx3g_ptr += 4; // ftab tx3g_ptr += 4; - m->ftab_entries = AV_RB16(tx3g_ptr); - tx3g_ptr += 2; - - for (i = 0; i < m->ftab_entries; i++) { - - box_size += 3; - if (avctx->extradata_size < box_size) { - mov_text_cleanup_ftab(m); - m->ftab_entries = 0; - return -1; - } - m->ftab_temp = av_mallocz(sizeof(*m->ftab_temp)); - if (!m->ftab_temp) { - mov_text_cleanup_ftab(m); - return AVERROR(ENOMEM); - } - m->ftab_temp->fontID = AV_RB16(tx3g_ptr); - tx3g_ptr += 2; - font_length = *tx3g_ptr++; - - box_size = box_size + font_length; - if (avctx->extradata_size < box_size) { - mov_text_cleanup_ftab(m); - m->ftab_entries = 0; - return -1; - } - m->ftab_temp->font = av_malloc(font_length + 1); - if (!m->ftab_temp->font) { - mov_text_cleanup_ftab(m); - return AVERROR(ENOMEM); - } - memcpy(m->ftab_temp->font, tx3g_ptr, font_length); - m->ftab_temp->font[font_length] = '\0'; - av_dynarray_add(&m->ftab, &m->count_f, m->ftab_temp); - if (!m->ftab) { - mov_text_cleanup_ftab(m); - return AVERROR(ENOMEM); - } - m->ftab_temp = NULL; - tx3g_ptr = tx3g_ptr + font_length; - } // In case of broken header, init default font m->d.font = ASS_DEFAULT_FONT; + + ftab_entries = bytestream_get_be16(&tx3g_ptr); + if (!ftab_entries) + return 0; + remaining -= 3 * ftab_entries; + if (remaining < 0) + return AVERROR_INVALIDDATA; + m->ftab = av_calloc(ftab_entries, sizeof(*m->ftab)); + if (!m->ftab) + return AVERROR(ENOMEM); + m->ftab_entries = ftab_entries; + for (i = 0; i < m->ftab_entries; i++) { - if (m->d.fontID == m->ftab[i]->fontID) - m->d.font = m->ftab[i]->font; + m->ftab[i].fontID = bytestream_get_be16(&tx3g_ptr); + if (m->ftab[i].fontID == m->d.fontID) + j = i; + font_length = bytestream_get_byte(&tx3g_ptr); + + remaining -= font_length; + if (remaining < 0) { + mov_text_cleanup_ftab(m); + return -1; + } + m->ftab[i].font = av_malloc(font_length + 1); + if (!m->ftab[i].font) { + mov_text_cleanup_ftab(m); + return AVERROR(ENOMEM); + } + bytestream_get_buffer(&tx3g_ptr, m->ftab[i].font, font_length); + m->ftab[i].font[font_length] = '\0'; } + if (j >= 0) + m->d.font = m->ftab[j].font; return 0; } -static int decode_twrp(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) +static int decode_twrp(const uint8_t *tsmb, MovTextContext *m, const AVPacket *avpkt) { m->box_flags |= TWRP_BOX; - m->w.wrap_flag = *tsmb++; + m->w.wrap_flag = bytestream_get_byte(&tsmb); return 0; } -static int decode_hlit(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) +static int decode_hlit(const uint8_t *tsmb, MovTextContext *m, const AVPacket *avpkt) { m->box_flags |= HLIT_BOX; - m->h.hlit_start = AV_RB16(tsmb); - tsmb += 2; - m->h.hlit_end = AV_RB16(tsmb); - tsmb += 2; + m->h.hlit_start = bytestream_get_be16(&tsmb); + m->h.hlit_end = bytestream_get_be16(&tsmb); return 0; } -static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) +static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, const AVPacket *avpkt) { m->box_flags |= HCLR_BOX; - memcpy(m->c.hlit_color, tsmb, 4); - tsmb += 4; + bytestream_get_buffer(&tsmb, m->c.hlit_color, 4); return 0; } -static int decode_styl(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) +static int decode_styl(const uint8_t *tsmb, MovTextContext *m, const AVPacket *avpkt) { int i; - int style_entries = AV_RB16(tsmb); - tsmb += 2; + int style_entries = bytestream_get_be16(&tsmb); + StyleBox *tmp; + // A single style record is of length 12 bytes. if (m->tracksize + m->size_var + 2 + style_entries * 12 > avpkt->size) return -1; + tmp = av_realloc_array(m->s, style_entries, sizeof(*m->s)); + if (!tmp) + return AVERROR(ENOMEM); + m->s = tmp; m->style_entries = style_entries; m->box_flags |= STYL_BOX; for(i = 0; i < m->style_entries; i++) { - m->s_temp = av_malloc(sizeof(*m->s_temp)); - if (!m->s_temp) { + StyleBox *style = &m->s[i]; + + style->style_start = bytestream_get_be16(&tsmb); + style->style_end = bytestream_get_be16(&tsmb); + if ( style->style_end < style->style_start + || (i && style->style_start < m->s[i - 1].style_end)) { mov_text_cleanup(m); return AVERROR(ENOMEM); } - m->s_temp->style_start = AV_RB16(tsmb); - tsmb += 2; - m->s_temp->style_end = AV_RB16(tsmb); - - if ( m->s_temp->style_end < m->s_temp->style_start - || (m->count_s && m->s_temp->style_start < m->s[m->count_s - 1]->style_end)) { - av_freep(&m->s_temp); - mov_text_cleanup(m); - return AVERROR(ENOMEM); + if (style->style_start == style->style_end) { + /* Skip this style as it applies to no character */ + tsmb += 8; + m->style_entries--; + i--; + continue; } - tsmb += 2; - m->s_temp->style_fontID = AV_RB16(tsmb); - tsmb += 2; - m->s_temp->style_flag = AV_RB8(tsmb); - m->s_temp->bold = !!(m->s_temp->style_flag & STYLE_FLAG_BOLD); - m->s_temp->italic = !!(m->s_temp->style_flag & STYLE_FLAG_ITALIC); - m->s_temp->underline = !!(m->s_temp->style_flag & STYLE_FLAG_UNDERLINE); - tsmb++; - m->s_temp->fontsize = AV_RB8(tsmb); - tsmb++; - m->s_temp->color = AV_RB24(tsmb); - tsmb += 3; - m->s_temp->alpha = AV_RB8(tsmb); - tsmb++; - av_dynarray_add(&m->s, &m->count_s, m->s_temp); - if(!m->s) { - mov_text_cleanup(m); - return AVERROR(ENOMEM); - } + style->style_fontID = bytestream_get_be16(&tsmb); + style->style_flag = bytestream_get_byte(&tsmb); + style->bold = !!(style->style_flag & STYLE_FLAG_BOLD); + style->italic = !!(style->style_flag & STYLE_FLAG_ITALIC); + style->underline = !!(style->style_flag & STYLE_FLAG_UNDERLINE); + style->fontsize = bytestream_get_byte(&tsmb); + style->color = bytestream_get_be24(&tsmb); + style->alpha = bytestream_get_byte(&tsmb); } return 0; } @@ -378,7 +338,6 @@ static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end, MovTextContext *m = avctx->priv_data; int i = 0; int text_pos = 0; - int style_active = 0; int entry = 0; int color = m->d.color; @@ -394,35 +353,33 @@ static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end, int len; if ((m->box_flags & STYL_BOX) && entry < m->style_entries) { - if (text_pos == m->s[entry]->style_start) { - style_active = 1; - if (m->s[entry]->bold ^ m->d.bold) - av_bprintf(buf, "{\\b%d}", m->s[entry]->bold); - if (m->s[entry]->italic ^ m->d.italic) - av_bprintf(buf, "{\\i%d}", m->s[entry]->italic); - if (m->s[entry]->underline ^ m->d.underline) - av_bprintf(buf, "{\\u%d}", m->s[entry]->underline); - if (m->s[entry]->fontsize != m->d.fontsize) - av_bprintf(buf, "{\\fs%d}", m->s[entry]->fontsize); - if (m->s[entry]->style_fontID != m->d.fontID) + const StyleBox *style = &m->s[entry]; + if (text_pos == style->style_end) { + av_bprintf(buf, "{\\r}"); + color = m->d.color; + entry++; + style++; + } + if (entry < m->style_entries && text_pos == style->style_start) { + if (style->bold ^ m->d.bold) + av_bprintf(buf, "{\\b%d}", style->bold); + if (style->italic ^ m->d.italic) + av_bprintf(buf, "{\\i%d}", style->italic); + if (style->underline ^ m->d.underline) + av_bprintf(buf, "{\\u%d}", style->underline); + if (style->fontsize != m->d.fontsize) + av_bprintf(buf, "{\\fs%d}", style->fontsize); + if (style->style_fontID != m->d.fontID) for (i = 0; i < m->ftab_entries; i++) { - if (m->s[entry]->style_fontID == m->ftab[i]->fontID) - av_bprintf(buf, "{\\fn%s}", m->ftab[i]->font); + if (style->style_fontID == m->ftab[i].fontID) + av_bprintf(buf, "{\\fn%s}", m->ftab[i].font); } - if (m->d.color != m->s[entry]->color) { - color = m->s[entry]->color; + if (m->d.color != style->color) { + color = style->color; av_bprintf(buf, "{\\1c&H%X&}", RGB_TO_BGR(color)); } - if (m->d.alpha != m->s[entry]->alpha) - av_bprintf(buf, "{\\1a&H%02X&}", 255 - m->s[entry]->alpha); - } - if (text_pos == m->s[entry]->style_end) { - if (style_active) { - av_bprintf(buf, "{\\r}"); - style_active = 0; - color = m->d.color; - } - entry++; + if (m->d.alpha != style->alpha) + av_bprintf(buf, "{\\1a&H%02X&}", 255 - style->alpha); } } if (m->box_flags & HLIT_BOX) { @@ -455,19 +412,17 @@ static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end, av_log(avctx, AV_LOG_ERROR, "invalid UTF-8 byte in subtitle\n"); len = 1; } - for (i = 0; i < len; i++) { - switch (*text) { - case '\r': - break; - case '\n': - av_bprintf(buf, "\\N"); - break; - default: - av_bprint_chars(buf, *text, 1); - break; - } - text++; + switch (*text) { + case '\r': + break; + case '\n': + av_bprintf(buf, "\\N"); + break; + default: + av_bprint_append_data(buf, text, len); + break; } + text += len; text_pos++; } @@ -544,7 +499,6 @@ static int mov_text_decode_frame(AVCodecContext *avctx, m->tracksize = 2 + text_length; m->style_entries = 0; m->box_flags = 0; - m->count_s = 0; // Note that the spec recommends lines be no longer than 2048 characters. av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); if (text_length + 2 != avpkt->size) { diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c index b2368b641..cf30adbd0 100644 --- a/libavcodec/movtextenc.c +++ b/libavcodec/movtextenc.c @@ -29,6 +29,8 @@ #include "libavutil/common.h" #include "ass_split.h" #include "ass.h" +#include "bytestream.h" +#include "internal.h" #define STYLE_FLAG_BOLD (1<<0) #define STYLE_FLAG_ITALIC (1<<1) @@ -45,7 +47,7 @@ #define DEFAULT_STYLE_COLOR 0xffffffff #define DEFAULT_STYLE_FLAG 0x00 -#define BGR_TO_RGB(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((c) >> 16) & 0xff)) +#define BGR_TO_RGB(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((uint32_t)(c) >> 16) & 0xff)) #define FONTSIZE_SCALE(s,fs) ((fs) * (s)->font_scale_factor + 0.5) #define av_bprint_append_any(buf, data, size) av_bprint_append_data(buf, ((const char*)data), size) @@ -73,108 +75,92 @@ typedef struct { ASSSplitContext *ass_ctx; ASSStyle *ass_dialog_style; + StyleBox *style_attributes; + unsigned count; + unsigned style_attributes_bytes_allocated; + StyleBox style_attributes_temp; AVBPrint buffer; - StyleBox **style_attributes; - StyleBox *style_attributes_temp; HighlightBox hlit; HilightcolorBox hclr; - int count; uint8_t box_flags; StyleBox d; uint16_t text_pos; uint16_t byte_count; - char ** fonts; + char **fonts; int font_count; double font_scale_factor; int frame_height; } MovTextContext; typedef struct { - uint32_t type; - void (*encode)(MovTextContext *s, uint32_t tsmb_type); + void (*encode)(MovTextContext *s); } Box; static void mov_text_cleanup(MovTextContext *s) { - int j; - if (s->box_flags & STYL_BOX) { - for (j = 0; j < s->count; j++) { - av_freep(&s->style_attributes[j]); - } - av_freep(&s->style_attributes); - } - if (s->style_attributes_temp) { - *s->style_attributes_temp = s->d; - } + s->count = 0; + s->style_attributes_temp = s->d; } -static void encode_styl(MovTextContext *s, uint32_t tsmb_type) +static void encode_styl(MovTextContext *s) { - int j; - uint32_t tsmb_size; - uint16_t style_entries; if ((s->box_flags & STYL_BOX) && s->count) { - tsmb_size = s->count * STYLE_RECORD_SIZE + SIZE_ADD; - tsmb_size = AV_RB32(&tsmb_size); - style_entries = AV_RB16(&s->count); + uint8_t buf[12], *p = buf; + + bytestream_put_be32(&p, s->count * STYLE_RECORD_SIZE + SIZE_ADD); + bytestream_put_be32(&p, MKBETAG('s','t','y','l')); + bytestream_put_be16(&p, s->count); /*The above three attributes are hard coded for now but will come from ASS style in the future*/ - av_bprint_append_any(&s->buffer, &tsmb_size, 4); - av_bprint_append_any(&s->buffer, &tsmb_type, 4); - av_bprint_append_any(&s->buffer, &style_entries, 2); - for (j = 0; j < s->count; j++) { - uint16_t style_start, style_end, style_fontID; - uint32_t style_color; + av_bprint_append_any(&s->buffer, buf, 10); + for (unsigned j = 0; j < s->count; j++) { + const StyleBox *style = &s->style_attributes[j]; - style_start = AV_RB16(&s->style_attributes[j]->style_start); - style_end = AV_RB16(&s->style_attributes[j]->style_end); - style_color = AV_RB32(&s->style_attributes[j]->style_color); - style_fontID = AV_RB16(&s->style_attributes[j]->style_fontID); + p = buf; + bytestream_put_be16(&p, style->style_start); + bytestream_put_be16(&p, style->style_end); + bytestream_put_be16(&p, style->style_fontID); + bytestream_put_byte(&p, style->style_flag); + bytestream_put_byte(&p, style->style_fontsize); + bytestream_put_be32(&p, style->style_color); - av_bprint_append_any(&s->buffer, &style_start, 2); - av_bprint_append_any(&s->buffer, &style_end, 2); - av_bprint_append_any(&s->buffer, &style_fontID, 2); - av_bprint_append_any(&s->buffer, &s->style_attributes[j]->style_flag, 1); - av_bprint_append_any(&s->buffer, &s->style_attributes[j]->style_fontsize, 1); - av_bprint_append_any(&s->buffer, &style_color, 4); + av_bprint_append_any(&s->buffer, buf, 12); } } mov_text_cleanup(s); } -static void encode_hlit(MovTextContext *s, uint32_t tsmb_type) +static void encode_hlit(MovTextContext *s) { - uint32_t tsmb_size; - uint16_t start, end; if (s->box_flags & HLIT_BOX) { - tsmb_size = 12; - tsmb_size = AV_RB32(&tsmb_size); - start = AV_RB16(&s->hlit.start); - end = AV_RB16(&s->hlit.end); - av_bprint_append_any(&s->buffer, &tsmb_size, 4); - av_bprint_append_any(&s->buffer, &tsmb_type, 4); - av_bprint_append_any(&s->buffer, &start, 2); - av_bprint_append_any(&s->buffer, &end, 2); + uint8_t buf[12], *p = buf; + + bytestream_put_be32(&p, 12); + bytestream_put_be32(&p, MKBETAG('h','l','i','t')); + bytestream_put_be16(&p, s->hlit.start); + bytestream_put_be16(&p, s->hlit.end); + + av_bprint_append_any(&s->buffer, buf, 12); } } -static void encode_hclr(MovTextContext *s, uint32_t tsmb_type) +static void encode_hclr(MovTextContext *s) { - uint32_t tsmb_size, color; if (s->box_flags & HCLR_BOX) { - tsmb_size = 12; - tsmb_size = AV_RB32(&tsmb_size); - color = AV_RB32(&s->hclr.color); - av_bprint_append_any(&s->buffer, &tsmb_size, 4); - av_bprint_append_any(&s->buffer, &tsmb_type, 4); - av_bprint_append_any(&s->buffer, &color, 4); + uint8_t buf[12], *p = buf; + + bytestream_put_be32(&p, 12); + bytestream_put_be32(&p, MKBETAG('h','c','l','r')); + bytestream_put_be32(&p, s->hclr.color); + + av_bprint_append_any(&s->buffer, buf, 12); } } static const Box box_types[] = { - { MKTAG('s','t','y','l'), encode_styl }, - { MKTAG('h','l','i','t'), encode_hlit }, - { MKTAG('h','c','l','r'), encode_hclr }, + { encode_styl }, + { encode_hlit }, + { encode_hclr }, }; const static size_t box_count = FF_ARRAY_ELEMS(box_types); @@ -182,45 +168,34 @@ const static size_t box_count = FF_ARRAY_ELEMS(box_types); static int mov_text_encode_close(AVCodecContext *avctx) { MovTextContext *s = avctx->priv_data; - int i; ff_ass_split_free(s->ass_ctx); - if (s->style_attributes) { - for (i = 0; i < s->count; i++) { - av_freep(&s->style_attributes[i]); - } - av_freep(&s->style_attributes); - } + av_freep(&s->style_attributes); av_freep(&s->fonts); - av_freep(&s->style_attributes_temp); av_bprint_finalize(&s->buffer, NULL); return 0; } static int encode_sample_description(AVCodecContext *avctx) { - ASS * ass; - ASSStyle * style; + ASS *ass; + ASSStyle *style; int i, j; - uint32_t tsmb_size, tsmb_type, back_color, style_color; - uint16_t style_start, style_end, fontID, count; + uint32_t back_color = 0; int font_names_total_len = 0; MovTextContext *s = avctx->priv_data; + uint8_t buf[30], *p = buf; - static const uint8_t display_and_justification[] = { - 0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags - 0x01, // int8_t horizontal-justification - 0xFF, // int8_t vertical-justification - }; + // 0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags + // 0x01, // int8_t horizontal-justification + // 0xFF, // int8_t vertical-justification // 0x00, 0x00, 0x00, 0x00, // uint8_t background-color-rgba[4] - static const uint8_t box_record[] = { // BoxRecord { - 0x00, 0x00, // int16_t top - 0x00, 0x00, // int16_t left - 0x00, 0x00, // int16_t bottom - 0x00, 0x00, // int16_t right + // 0x00, 0x00, // int16_t top + // 0x00, 0x00, // int16_t left + // 0x00, 0x00, // int16_t bottom + // 0x00, 0x00, // int16_t right // }; - }; // StyleRecord { // 0x00, 0x00, // uint16_t startChar // 0x00, 0x00, // uint16_t endChar @@ -268,25 +243,19 @@ static int encode_sample_description(AVCodecContext *avctx) (255 - ((uint32_t)style->back_color >> 24)); } - av_bprint_append_any(&s->buffer, display_and_justification, - sizeof(display_and_justification)); - back_color = AV_RB32(&back_color); - av_bprint_append_any(&s->buffer, &back_color, 4); - // BoxRecord { - av_bprint_append_any(&s->buffer, box_record, sizeof(box_record)); - // }; + bytestream_put_be32(&p, 0); // displayFlags + bytestream_put_be16(&p, 0x01FF); // horizontal/vertical justification (2x int8_t) + bytestream_put_be32(&p, back_color); + bytestream_put_be64(&p, 0); // BoxRecord - 4xint16_t: top, left, bottom, right // StyleRecord { - style_start = AV_RB16(&s->d.style_start); - style_end = AV_RB16(&s->d.style_end); - fontID = AV_RB16(&s->d.style_fontID); - style_color = AV_RB32(&s->d.style_color); - av_bprint_append_any(&s->buffer, &style_start, 2); - av_bprint_append_any(&s->buffer, &style_end, 2); - av_bprint_append_any(&s->buffer, &fontID, 2); - av_bprint_append_any(&s->buffer, &s->d.style_flag, 1); - av_bprint_append_any(&s->buffer, &s->d.style_fontsize, 1); - av_bprint_append_any(&s->buffer, &style_color, 4); + bytestream_put_be16(&p, s->d.style_start); + bytestream_put_be16(&p, s->d.style_end); + bytestream_put_be16(&p, s->d.style_fontID); + bytestream_put_byte(&p, s->d.style_flag); + bytestream_put_byte(&p, s->d.style_fontsize); + bytestream_put_be32(&p, s->d.style_color); // }; + av_bprint_append_any(&s->buffer, buf, 30); // Build font table // We can't build a complete font table since that would require @@ -294,10 +263,14 @@ static int encode_sample_description(AVCodecContext *avctx) // is avaiable in the ASS header if (style && ass->styles_count) { // Find unique font names - av_dynarray_add(&s->fonts, &s->font_count, style->font_name); - font_names_total_len += strlen(style->font_name); + if (style->font_name) { + av_dynarray_add(&s->fonts, &s->font_count, style->font_name); + font_names_total_len += strlen(style->font_name); + } for (i = 0; i < ass->styles_count; i++) { int found = 0; + if (!ass->styles[i].font_name) + continue; for (j = 0; j < s->font_count; j++) { if (!strcmp(s->fonts[j], ass->styles[i].font_name)) { found = 1; @@ -314,21 +287,21 @@ static int encode_sample_description(AVCodecContext *avctx) av_dynarray_add(&s->fonts, &s->font_count, (char*)"Serif"); // FontTableBox { - tsmb_size = SIZE_ADD + 3 * s->font_count + font_names_total_len; - tsmb_size = AV_RB32(&tsmb_size); - tsmb_type = MKTAG('f','t','a','b'); - count = AV_RB16(&s->font_count); - av_bprint_append_any(&s->buffer, &tsmb_size, 4); - av_bprint_append_any(&s->buffer, &tsmb_type, 4); - av_bprint_append_any(&s->buffer, &count, 2); + p = buf; + bytestream_put_be32(&p, SIZE_ADD + 3 * s->font_count + font_names_total_len); // Size + bytestream_put_be32(&p, MKBETAG('f','t','a','b')); + bytestream_put_be16(&p, s->font_count); + + av_bprint_append_any(&s->buffer, buf, 10); // FontRecord { for (i = 0; i < s->font_count; i++) { - int len; - fontID = i + 1; - fontID = AV_RB16(&fontID); - av_bprint_append_any(&s->buffer, &fontID, 2); - len = strlen(s->fonts[i]); - av_bprint_append_any(&s->buffer, &len, 1); + size_t len = strlen(s->fonts[i]); + + p = buf; + bytestream_put_be16(&p, i + 1); //fontID + bytestream_put_byte(&p, len); + + av_bprint_append_any(&s->buffer, buf, 3); av_bprint_append_any(&s->buffer, s->fonts[i], len); } // }; @@ -358,56 +331,48 @@ static av_cold int mov_text_encode_init(AVCodecContext *avctx) av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED); - s->style_attributes_temp = av_mallocz(sizeof(*s->style_attributes_temp)); - if (!s->style_attributes_temp) { - ret = AVERROR(ENOMEM); - goto fail; - } - s->ass_ctx = ff_ass_split(avctx->subtitle_header); - if (!s->ass_ctx) { - ret = AVERROR_INVALIDDATA; - goto fail; - } + if (!s->ass_ctx) + return AVERROR_INVALIDDATA; ret = encode_sample_description(avctx); if (ret < 0) - goto fail; + return ret; return 0; - -fail: - mov_text_encode_close(avctx); - return ret; } // Start a new style box if needed static int mov_text_style_start(MovTextContext *s) { // there's an existing style entry - if (s->style_attributes_temp->style_start == s->text_pos) + if (s->style_attributes_temp.style_start == s->text_pos) // Still at same text pos, use same entry return 1; - if (s->style_attributes_temp->style_flag != s->d.style_flag || - s->style_attributes_temp->style_color != s->d.style_color || - s->style_attributes_temp->style_fontID != s->d.style_fontID || - s->style_attributes_temp->style_fontsize != s->d.style_fontsize) { + if (s->style_attributes_temp.style_flag != s->d.style_flag || + s->style_attributes_temp.style_color != s->d.style_color || + s->style_attributes_temp.style_fontID != s->d.style_fontID || + s->style_attributes_temp.style_fontsize != s->d.style_fontsize) { + StyleBox *tmp; + // last style != defaults, end the style entry and start a new one - s->box_flags |= STYL_BOX; - s->style_attributes_temp->style_end = s->text_pos; - av_dynarray_add(&s->style_attributes, &s->count, s->style_attributes_temp); - s->style_attributes_temp = av_malloc(sizeof(*s->style_attributes_temp)); - if (!s->style_attributes_temp) { + if (s->count + 1 > FFMIN(SIZE_MAX / sizeof(*s->style_attributes), UINT16_MAX) || + !(tmp = av_fast_realloc(s->style_attributes, + &s->style_attributes_bytes_allocated, + (s->count + 1) * sizeof(*s->style_attributes)))) { mov_text_cleanup(s); av_bprint_clear(&s->buffer); s->box_flags &= ~STYL_BOX; return 0; } - - *s->style_attributes_temp = s->d; - s->style_attributes_temp->style_start = s->text_pos; + s->style_attributes = tmp; + s->style_attributes_temp.style_end = s->text_pos; + s->style_attributes[s->count++] = s->style_attributes_temp; + s->box_flags |= STYL_BOX; + s->style_attributes_temp = s->d; + s->style_attributes_temp.style_start = s->text_pos; } else { // style entry matches defaults, drop entry - *s->style_attributes_temp = s->d; - s->style_attributes_temp->style_start = s->text_pos; + s->style_attributes_temp = s->d; + s->style_attributes_temp.style_start = s->text_pos; } return 1; } @@ -432,13 +397,12 @@ static uint8_t mov_text_style_to_flag(const char style) static void mov_text_style_set(MovTextContext *s, uint8_t style_flags) { - if (!s->style_attributes_temp || - !((s->style_attributes_temp->style_flag & style_flags) ^ style_flags)) { + if (!((s->style_attributes_temp.style_flag & style_flags) ^ style_flags)) { // setting flags that that are already set return; } if (mov_text_style_start(s)) - s->style_attributes_temp->style_flag |= style_flags; + s->style_attributes_temp.style_flag |= style_flags; } static void mov_text_style_cb(void *priv, const char style, int close) @@ -446,29 +410,27 @@ static void mov_text_style_cb(void *priv, const char style, int close) MovTextContext *s = priv; uint8_t style_flag = mov_text_style_to_flag(style); - if (!s->style_attributes_temp || - !!(s->style_attributes_temp->style_flag & style_flag) != close) { + if (!!(s->style_attributes_temp.style_flag & style_flag) != close) { // setting flag that is already set return; } if (mov_text_style_start(s)) { if (!close) - s->style_attributes_temp->style_flag |= style_flag; + s->style_attributes_temp.style_flag |= style_flag; else - s->style_attributes_temp->style_flag &= ~style_flag; + s->style_attributes_temp.style_flag &= ~style_flag; } } static void mov_text_color_set(MovTextContext *s, uint32_t color) { - if (!s->style_attributes_temp || - (s->style_attributes_temp->style_color & 0xffffff00) == color) { + if ((s->style_attributes_temp.style_color & 0xffffff00) == color) { // color hasn't changed return; } if (mov_text_style_start(s)) - s->style_attributes_temp->style_color = (color & 0xffffff00) | - (s->style_attributes_temp->style_color & 0xff); + s->style_attributes_temp.style_color = (color & 0xffffff00) | + (s->style_attributes_temp.style_color & 0xff); } static void mov_text_color_cb(void *priv, unsigned int color, unsigned int color_id) @@ -481,7 +443,7 @@ static void mov_text_color_cb(void *priv, unsigned int color, unsigned int color } else if (color_id == 2) { //secondary color changes if (!(s->box_flags & HCLR_BOX)) // Highlight alpha not set yet, use current primary alpha - s->hclr.color = s->style_attributes_temp->style_color; + s->hclr.color = s->style_attributes_temp.style_color; if (!(s->box_flags & HLIT_BOX) || s->hlit.start == s->text_pos) { s->box_flags |= HCLR_BOX; s->box_flags |= HLIT_BOX; @@ -500,14 +462,13 @@ static void mov_text_color_cb(void *priv, unsigned int color, unsigned int color static void mov_text_alpha_set(MovTextContext *s, uint8_t alpha) { - if (!s->style_attributes_temp || - (s->style_attributes_temp->style_color & 0xff) == alpha) { + if ((s->style_attributes_temp.style_color & 0xff) == alpha) { // color hasn't changed return; } if (mov_text_style_start(s)) - s->style_attributes_temp->style_color = - (s->style_attributes_temp->style_color & 0xffffff00) | alpha; + s->style_attributes_temp.style_color = + (s->style_attributes_temp.style_color & 0xffffff00) | alpha; } static void mov_text_alpha_cb(void *priv, int alpha, int alpha_id) @@ -520,7 +481,7 @@ static void mov_text_alpha_cb(void *priv, int alpha, int alpha_id) else if (alpha_id == 2) { //secondary alpha changes if (!(s->box_flags & HCLR_BOX)) // Highlight color not set yet, use current primary color - s->hclr.color = s->style_attributes_temp->style_color; + s->hclr.color = s->style_attributes_temp.style_color; if (!(s->box_flags & HLIT_BOX) || s->hlit.start == s->text_pos) { s->box_flags |= HCLR_BOX; s->box_flags |= HLIT_BOX; @@ -533,7 +494,7 @@ static void mov_text_alpha_cb(void *priv, int alpha, int alpha_id) // Movtext does not support changes to other alpha_id (outline, background) } -static uint16_t find_font_id(MovTextContext * s, const char * name) +static uint16_t find_font_id(MovTextContext *s, const char *name) { int i; for (i = 0; i < s->font_count; i++) { @@ -546,13 +507,12 @@ static uint16_t find_font_id(MovTextContext * s, const char * name) static void mov_text_font_name_set(MovTextContext *s, const char *name) { int fontID = find_font_id(s, name); - if (!s->style_attributes_temp || - s->style_attributes_temp->style_fontID == fontID) { + if (s->style_attributes_temp.style_fontID == fontID) { // color hasn't changed return; } if (mov_text_style_start(s)) - s->style_attributes_temp->style_fontID = fontID; + s->style_attributes_temp.style_fontID = fontID; } static void mov_text_font_name_cb(void *priv, const char *name) @@ -563,13 +523,12 @@ static void mov_text_font_name_cb(void *priv, const char *name) static void mov_text_font_size_set(MovTextContext *s, int size) { size = FONTSIZE_SCALE(s, size); - if (!s->style_attributes_temp || - s->style_attributes_temp->style_fontsize == size) { + if (s->style_attributes_temp.style_fontsize == size) { // color hasn't changed return; } if (mov_text_style_start(s)) - s->style_attributes_temp->style_fontsize = size; + s->style_attributes_temp.style_fontsize = size; } static void mov_text_font_size_cb(void *priv, int size) @@ -607,16 +566,16 @@ static void mov_text_ass_style_set(MovTextContext *s, ASSStyle *style) static void mov_text_dialog(MovTextContext *s, ASSDialog *dialog) { - ASSStyle * style = ff_ass_style_get(s->ass_ctx, dialog->style); + ASSStyle *style = ff_ass_style_get(s->ass_ctx, dialog->style); s->ass_dialog_style = style; mov_text_ass_style_set(s, style); } -static void mov_text_cancel_overrides_cb(void *priv, const char * style_name) +static void mov_text_cancel_overrides_cb(void *priv, const char *style_name) { MovTextContext *s = priv; - ASSStyle * style; + ASSStyle *style; if (!style_name || !*style_name) style = s->ass_dialog_style; @@ -717,7 +676,7 @@ static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf, #endif for (j = 0; j < box_count; j++) { - box_types[j].encode(s, box_types[j].type); + box_types[j].encode(s); } } @@ -772,4 +731,5 @@ AVCodec ff_movtext_encoder = { .init = mov_text_encode_init, .encode_sub = mov_text_encode_frame, .close = mov_text_encode_close, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/mpc.c b/libavcodec/mpc.c index e56b608d8..e29b82346 100644 --- a/libavcodec/mpc.c +++ b/libavcodec/mpc.c @@ -34,11 +34,6 @@ #include "mpc.h" #include "mpcdata.h" -av_cold void ff_mpc_init(void) -{ - ff_mpa_synth_init_fixed(ff_mpa_synth_window_fixed); -} - /** * Process decoded Musepack data and produce PCM */ diff --git a/libavcodec/mpc.h b/libavcodec/mpc.h index df462af6b..f8093796a 100644 --- a/libavcodec/mpc.h +++ b/libavcodec/mpc.h @@ -30,6 +30,7 @@ #define AVCODEC_MPC_H #include "libavutil/lfg.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "bswapdsp.h" @@ -70,7 +71,6 @@ typedef struct MPCContext { DECLARE_ALIGNED(16, int32_t, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT]; } MPCContext; -void ff_mpc_init(void); void ff_mpc_dequantize_and_synth(MPCContext *c, int maxband, int16_t **out, int channels); #endif /* AVCODEC_MPC_H */ diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index e09f1b604..af12a6fd8 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -28,6 +28,9 @@ #include "libavutil/channel_layout.h" #include "libavutil/internal.h" #include "libavutil/lfg.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" + #include "avcodec.h" #include "get_bits.h" #include "internal.h" @@ -38,25 +41,42 @@ static VLC scfi_vlc, dscf_vlc, hdr_vlc, quant_vlc[MPC7_QUANT_VLC_TABLES][2]; -static const uint16_t quant_offsets[MPC7_QUANT_VLC_TABLES*2 + 1] = +static av_cold void mpc7_init_static(void) { - 0, 512, 1024, 1536, 2052, 2564, 3076, 3588, 4100, 4612, 5124, - 5636, 6164, 6676, 7224 -}; + static VLC_TYPE quant_tables[7224][2]; + const uint8_t *raw_quant_table = mpc7_quant_vlcs; + INIT_VLC_STATIC_FROM_LENGTHS(&scfi_vlc, MPC7_SCFI_BITS, MPC7_SCFI_SIZE, + &mpc7_scfi[1], 2, + &mpc7_scfi[0], 2, 1, 0, 0, 1 << MPC7_SCFI_BITS); + INIT_VLC_STATIC_FROM_LENGTHS(&dscf_vlc, MPC7_DSCF_BITS, MPC7_DSCF_SIZE, + &mpc7_dscf[1], 2, + &mpc7_dscf[0], 2, 1, -7, 0, 1 << MPC7_DSCF_BITS); + INIT_VLC_STATIC_FROM_LENGTHS(&hdr_vlc, MPC7_HDR_BITS, MPC7_HDR_SIZE, + &mpc7_hdr[1], 2, + &mpc7_hdr[0], 2, 1, -5, 0, 1 << MPC7_HDR_BITS); + for (unsigned i = 0, offset = 0; i < MPC7_QUANT_VLC_TABLES; i++){ + for (int j = 0; j < 2; j++) { + quant_vlc[i][j].table = &quant_tables[offset]; + quant_vlc[i][j].table_allocated = FF_ARRAY_ELEMS(quant_tables) - offset; + ff_init_vlc_from_lengths(&quant_vlc[i][j], 9, mpc7_quant_vlc_sizes[i], + &raw_quant_table[1], 2, + &raw_quant_table[0], 2, 1, + mpc7_quant_vlc_off[i], + INIT_VLC_STATIC_OVERLONG, NULL); + raw_quant_table += 2 * mpc7_quant_vlc_sizes[i]; + offset += quant_vlc[i][j].table_size; + } + } + ff_mpa_synth_init_fixed(); +} static av_cold int mpc7_decode_init(AVCodecContext * avctx) { - int i, j, ret; + static AVOnce init_static_once = AV_ONCE_INIT; MPCContext *c = avctx->priv_data; GetBitContext gb; LOCAL_ALIGNED_16(uint8_t, buf, [16]); - static int vlc_initialized = 0; - - static VLC_TYPE scfi_table[1 << MPC7_SCFI_BITS][2]; - static VLC_TYPE dscf_table[1 << MPC7_DSCF_BITS][2]; - static VLC_TYPE hdr_table[1 << MPC7_HDR_BITS][2]; - static VLC_TYPE quant_tables[7224][2]; /* Musepack SV7 is always stereo */ if (avctx->channels != 2) { @@ -73,7 +93,6 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) ff_bswapdsp_init(&c->bdsp); ff_mpadsp_init(&c->mpadsp); c->bdsp.bswap_buf((uint32_t *) buf, (const uint32_t *) avctx->extradata, 4); - ff_mpc_init(); init_get_bits(&gb, buf, 128); c->IS = get_bits1(&gb); @@ -93,45 +112,7 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) avctx->sample_fmt = AV_SAMPLE_FMT_S16P; avctx->channel_layout = AV_CH_LAYOUT_STEREO; - if(vlc_initialized) return 0; - av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); - scfi_vlc.table = scfi_table; - scfi_vlc.table_allocated = 1 << MPC7_SCFI_BITS; - if ((ret = init_vlc(&scfi_vlc, MPC7_SCFI_BITS, MPC7_SCFI_SIZE, - &mpc7_scfi[1], 2, 1, - &mpc7_scfi[0], 2, 1, INIT_VLC_USE_NEW_STATIC))) { - av_log(avctx, AV_LOG_ERROR, "Cannot init SCFI VLC\n"); - return ret; - } - dscf_vlc.table = dscf_table; - dscf_vlc.table_allocated = 1 << MPC7_DSCF_BITS; - if ((ret = init_vlc(&dscf_vlc, MPC7_DSCF_BITS, MPC7_DSCF_SIZE, - &mpc7_dscf[1], 2, 1, - &mpc7_dscf[0], 2, 1, INIT_VLC_USE_NEW_STATIC))) { - av_log(avctx, AV_LOG_ERROR, "Cannot init DSCF VLC\n"); - return ret; - } - hdr_vlc.table = hdr_table; - hdr_vlc.table_allocated = 1 << MPC7_HDR_BITS; - if ((ret = init_vlc(&hdr_vlc, MPC7_HDR_BITS, MPC7_HDR_SIZE, - &mpc7_hdr[1], 2, 1, - &mpc7_hdr[0], 2, 1, INIT_VLC_USE_NEW_STATIC))) { - av_log(avctx, AV_LOG_ERROR, "Cannot init HDR VLC\n"); - return ret; - } - for(i = 0; i < MPC7_QUANT_VLC_TABLES; i++){ - for(j = 0; j < 2; j++){ - quant_vlc[i][j].table = &quant_tables[quant_offsets[i*2 + j]]; - quant_vlc[i][j].table_allocated = quant_offsets[i*2 + j + 1] - quant_offsets[i*2 + j]; - if ((ret = init_vlc(&quant_vlc[i][j], 9, mpc7_quant_vlc_sizes[i], - &mpc7_quant_vlc[i][j][1], 4, 2, - &mpc7_quant_vlc[i][j][0], 4, 2, INIT_VLC_USE_NEW_STATIC))) { - av_log(avctx, AV_LOG_ERROR, "Cannot init QUANT VLC %i,%i\n",i,j); - return ret; - } - } - } - vlc_initialized = 1; + ff_thread_once(&init_static_once, mpc7_init_static); return 0; } @@ -168,7 +149,7 @@ static inline void idx_to_quant(MPCContext *c, GetBitContext *gb, int idx, int * case 3: case 4: case 5: case 6: case 7: i1 = get_bits1(gb); for(i = 0; i < SAMPLES_PER_BAND; i++) - *dst++ = get_vlc2(gb, quant_vlc[idx-1][i1].table, 9, 2) - mpc7_quant_vlc_off[idx-1]; + *dst++ = get_vlc2(gb, quant_vlc[idx-1][i1].table, 9, 2); break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: @@ -183,7 +164,7 @@ static inline void idx_to_quant(MPCContext *c, GetBitContext *gb, int idx, int * static int get_scale_idx(GetBitContext *gb, int ref) { - int t = get_vlc2(gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; + int t = get_vlc2(gb, dscf_vlc.table, MPC7_DSCF_BITS, 1); if (t == 8) return get_bits(gb, 6); return ref + t; @@ -238,8 +219,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data, /* read subband indexes */ for(i = 0; i <= c->maxbands; i++){ for(ch = 0; ch < 2; ch++){ - int t = 4; - if(i) t = get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5; + int t = i ? get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) : 4; if(t == 4) bands[i].res[ch] = get_bits(&gb, 4); else bands[i].res[ch] = bands[i-1].res[ch] + t; if (bands[i].res[ch] < -1 || bands[i].res[ch] > 17) { @@ -341,4 +321,5 @@ AVCodec ff_mpc7_decoder = { .capabilities = AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/mpc7data.h b/libavcodec/mpc7data.h index 5609e8fbf..ee77393fc 100644 --- a/libavcodec/mpc7data.h +++ b/libavcodec/mpc7data.h @@ -33,139 +33,103 @@ static const int8_t mpc7_idx51[] = { -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, #define MPC7_SCFI_SIZE 4 #define MPC7_SCFI_BITS 3 static const uint8_t mpc7_scfi[MPC7_SCFI_SIZE * 2] = { - 0x2, 3, 0x1, 1, 0x3, 3, 0x0, 2 + 0x03, 2, 0x00, 3, 0x02, 3, 0x01, 1, }; #define MPC7_DSCF_SIZE 16 #define MPC7_DSCF_BITS 6 static const uint8_t mpc7_dscf[MPC7_DSCF_SIZE * 2] = { - 0x20, 6, 0x04, 5, 0x11, 5, 0x1E, 5, 0x0D, 4, 0x00, 3, 0x03, 3, 0x09, 4, - 0x05, 3, 0x02, 3, 0x0E, 4, 0x03, 4, 0x1F, 5, 0x05, 5, 0x21, 6, 0x0C, 4 + 0x05, 3, 0x01, 5, 0x0D, 5, 0x0B, 4, 0x09, 3, 0x06, 3, 0x00, 6, 0x0E, 6, + 0x02, 5, 0x07, 4, 0x08, 3, 0x0F, 4, 0x04, 4, 0x0A, 4, 0x03, 5, 0x0C, 5, }; #define MPC7_HDR_SIZE 10 #define MPC7_HDR_BITS 9 static const uint8_t mpc7_hdr[MPC7_HDR_SIZE * 2] = { - 0x5C, 8, 0x2F, 7, 0x0A, 5, 0x04, 4, 0x00, 2, - 0x01, 1, 0x03, 3, 0x16, 6, 0xBB, 9, 0xBA, 9 + 0x04, 2, 0x03, 4, 0x02, 5, 0x07, 6, 0x00, 8, + 0x09, 9, 0x08, 9, 0x01, 7, 0x06, 3, 0x05, 1, }; #define MPC7_QUANT_VLC_TABLES 7 -static const uint8_t mpc7_quant_vlc_sizes[MPC7_QUANT_VLC_TABLES * 2] = { +static const uint8_t mpc7_quant_vlc_sizes[MPC7_QUANT_VLC_TABLES] = { 27, 25, 7, 9, 15, 31, 63 }; -static const uint8_t mpc7_quant_vlc_off[MPC7_QUANT_VLC_TABLES] = { - 0, 0, 3, 4, 7, 15, 31 +static const int8_t mpc7_quant_vlc_off[MPC7_QUANT_VLC_TABLES] = { + 0, 0, -3, -4, -7, -15, -31 }; -static const uint16_t mpc7_quant_vlc[MPC7_QUANT_VLC_TABLES][2][64 * 2] = { -{ - { - 0x0036, 6, 0x0009, 5, 0x0020, 6, 0x0005, 5, 0x000A, 4, 0x0007, 5, - 0x0034, 6, 0x0000, 5, 0x0023, 6, 0x000A, 5, 0x0006, 4, 0x0004, 5, - 0x000B, 4, 0x0007, 3, 0x000C, 4, 0x0003, 5, 0x0007, 4, 0x000B, 5, - 0x0022, 6, 0x0001, 5, 0x0035, 6, 0x0006, 5, 0x0009, 4, 0x0002, 5, - 0x0021, 6, 0x0008, 5, 0x0037, 6 - }, - { - 0x0067, 8, 0x003E, 7, 0x00E1, 9, 0x0037, 7, 0x0003, 4, 0x0034, 7, - 0x0065, 8, 0x003C, 7, 0x00E3, 9, 0x0018, 6, 0x0000, 4, 0x003D, 7, - 0x0004, 4, 0x0001, 1, 0x0005, 4, 0x003F, 7, 0x0001, 4, 0x003B, 7, - 0x00E2, 9, 0x0039, 7, 0x0064, 8, 0x0035, 7, 0x0002, 4, 0x0036, 7, - 0x00E0, 9, 0x003A, 7, 0x0066, 8 - } -}, -{ - { - 0x0059, 7, 0x002F, 6, 0x000F, 5, 0x0000, 5, 0x005B, 7, 0x0004, 5, - 0x0006, 4, 0x000D, 4, 0x0004, 4, 0x0005, 5, 0x0014, 5, 0x000C, 4, - 0x0004, 3, 0x000F, 4, 0x000E, 5, 0x0003, 5, 0x0003, 4, 0x000E, 4, - 0x0005, 4, 0x0001, 5, 0x005A, 7, 0x0002, 5, 0x0015, 5, 0x002E, 6, - 0x0058, 7 - }, - { - 0x0399, 10, 0x0071, 7, 0x0033, 6, 0x00E7, 8, 0x039A, 10, 0x0068, 7, - 0x001E, 5, 0x0000, 3, 0x001D, 5, 0x0069, 7, 0x0032, 6, 0x0001, 3, - 0x0002, 2, 0x0003, 3, 0x0031, 6, 0x006B, 7, 0x001B, 5, 0x0002, 3, - 0x001F, 5, 0x0070, 7, 0x0398, 10, 0x006A, 7, 0x0030, 6, 0x0072, 7, - 0x039B, 10 - } -}, -{ - { - 0x000C, 4, 0x0004, 3, 0x0000, 2, 0x0001, 2, 0x0007, 3, 0x0005, 3, 0x000D, 4 - }, - { - 0x0004, 5, 0x0003, 4, 0x0002, 2, 0x0003, 2, 0x0001, 2, 0x0000, 3, 0x0005, 5 - } -}, -{ - { - 0x0005, 4, 0x0000, 3, 0x0004, 3, 0x0006, 3, 0x0007, 3, 0x0005, 3, 0x0003, 3, 0x0001, 3, 0x0004, 4 - }, - { - 0x0009, 5, 0x000C, 4, 0x0003, 3, 0x0000, 2, 0x0002, 2, 0x0007, 3, 0x000D, 4, 0x0005, 4, 0x0008, 5 - } -}, -{ - { - 0x0039, 6, 0x0017, 5, 0x0008, 4, 0x000A, 4, 0x000D, 4, 0x0000, 3, - 0x0002, 3, 0x0003, 3, 0x0001, 3, 0x000F, 4, 0x000C, 4, 0x0009, 4, - 0x001D, 5, 0x0016, 5, 0x0038, 6, - }, - { - 0x00E5, 8, 0x0038, 6, 0x0007, 5, 0x0002, 4, 0x0000, 3, 0x0003, 3, - 0x0005, 3, 0x0006, 3, 0x0004, 3, 0x0002, 3, 0x000F, 4, 0x001D, 5, - 0x0006, 5, 0x0073, 7, 0x00E4, 8, - }, -}, -{ - { - 0x0041, 7, 0x0006, 6, 0x002C, 6, 0x002D, 6, 0x003B, 6, 0x000D, 5, - 0x0011, 5, 0x0013, 5, 0x0017, 5, 0x0015, 5, 0x001A, 5, 0x001E, 5, - 0x0000, 4, 0x0002, 4, 0x0005, 4, 0x0007, 4, 0x0003, 4, 0x0004, 4, - 0x001F, 5, 0x001C, 5, 0x0019, 5, 0x001B, 5, 0x0018, 5, 0x0014, 5, - 0x0012, 5, 0x000C, 5, 0x0002, 5, 0x003A, 6, 0x0021, 6, 0x0007, 6, - 0x0040, 7 - }, - { - 0x1948, 13, 0x194A, 13, 0x0328, 10, 0x0195, 9, 0x00CB, 8, 0x0066, 7, - 0x0031, 6, 0x0009, 5, 0x000F, 5, 0x001F, 5, 0x0002, 4, 0x0006, 4, - 0x0008, 4, 0x000B, 4, 0x000D, 4, 0x0000, 3, 0x000E, 4, 0x000A, 4, - 0x0009, 4, 0x0005, 4, 0x0003, 4, 0x001E, 5, 0x000E, 5, 0x0008, 5, - 0x0030, 6, 0x0067, 7, 0x00C9, 8, 0x00C8, 8, 0x0653, 11, 0x1949, 13, - 0x194B, 13 - } -}, -{ - { - 0x0067, 8, 0x0099, 8, 0x00B5, 8, 0x00E9, 8, 0x0040, 7, 0x0041, 7, - 0x004D, 7, 0x0051, 7, 0x005B, 7, 0x0071, 7, 0x0070, 7, 0x0018, 6, - 0x001D, 6, 0x0023, 6, 0x0025, 6, 0x0029, 6, 0x002C, 6, 0x002E, 6, - 0x0033, 6, 0x0031, 6, 0x0036, 6, 0x0037, 6, 0x0039, 6, 0x003C, 6, - 0x0000, 5, 0x0002, 5, 0x000A, 5, 0x0005, 5, 0x0009, 5, 0x0006, 5, - 0x000D, 5, 0x0007, 5, 0x000B, 5, 0x000F, 5, 0x0008, 5, 0x0004, 5, - 0x0003, 5, 0x0001, 5, 0x003F, 6, 0x003E, 6, 0x003D, 6, 0x0035, 6, - 0x003B, 6, 0x0034, 6, 0x0030, 6, 0x002F, 6, 0x002B, 6, 0x002A, 6, - 0x0027, 6, 0x0024, 6, 0x0021, 6, 0x001C, 6, 0x0075, 7, 0x0065, 7, - 0x0064, 7, 0x0050, 7, 0x0045, 7, 0x0044, 7, 0x0032, 7, 0x00E8, 8, - 0x00B4, 8, 0x0098, 8, 0x0066, 8 - }, - { - 0x37A4, 14, 0x37AD, 14, 0x37A6, 14, 0x37AE, 14, 0x0DEA, 12, 0x02F0, 10, - 0x02F1, 10, 0x00A0, 9, 0x00A2, 9, 0x01BC, 9, 0x007A, 8, 0x00DF, 8, - 0x003C, 7, 0x0049, 7, 0x006E, 7, 0x000E, 6, 0x0018, 6, 0x0019, 6, - 0x0022, 6, 0x0025, 6, 0x0036, 6, 0x0003, 5, 0x0009, 5, 0x000B, 5, - 0x0010, 5, 0x0013, 5, 0x0015, 5, 0x0018, 5, 0x001A, 5, 0x001D, 5, - 0x001F, 5, 0x0002, 4, 0x0000, 4, 0x001E, 5, 0x001C, 5, 0x0019, 5, - 0x0016, 5, 0x0014, 5, 0x000E, 5, 0x000D, 5, 0x0008, 5, 0x0006, 5, - 0x0002, 5, 0x002E, 6, 0x0023, 6, 0x001F, 6, 0x0015, 6, 0x000F, 6, - 0x005F, 7, 0x0048, 7, 0x0029, 7, 0x00BD, 8, 0x007B, 8, 0x0179, 9, - 0x00A1, 9, 0x037B, 10, 0x0147, 10, 0x0146, 10, 0x0DE8, 12, 0x37AF, 14, - 0x37A7, 14, 0x37AC, 14, 0x37A5, 14 - } -} +static const uint8_t mpc7_quant_vlcs[177 * 2 * 2] = { + /* quant_vlc[0][0] - 27 entries */ + 0x07, 5, 0x13, 5, 0x17, 5, 0x0F, 5, 0x0B, 5, 0x03, 5, 0x15, 5, + 0x05, 5, 0x19, 5, 0x01, 5, 0x09, 5, 0x11, 5, 0x0A, 4, 0x10, 4, + 0x02, 6, 0x18, 6, 0x12, 6, 0x08, 6, 0x16, 4, 0x04, 4, 0x0C, 4, + 0x0E, 4, 0x06, 6, 0x14, 6, 0x00, 6, 0x1A, 6, 0x0D, 3, + /* quant_vlc[0][1] - 27 entries */ + 0x0A, 4, 0x10, 4, 0x16, 4, 0x04, 4, 0x0C, 4, 0x0E, 4, 0x09, 6, + 0x14, 8, 0x06, 8, 0x1A, 8, 0x00, 8, 0x05, 7, 0x15, 7, 0x17, 7, + 0x03, 7, 0x18, 9, 0x02, 9, 0x12, 9, 0x08, 9, 0x13, 7, 0x19, 7, + 0x11, 7, 0x07, 7, 0x0B, 7, 0x01, 7, 0x0F, 7, 0x0D, 1, + /* quant_vlc[1][0] - 25 entries */ + 0x03, 5, 0x13, 5, 0x15, 5, 0x0F, 5, 0x05, 5, 0x09, 5, 0x10, 4, + 0x08, 4, 0x12, 4, 0x06, 4, 0x0E, 5, 0x02, 5, 0x0C, 3, 0x0A, 5, + 0x16, 5, 0x18, 7, 0x00, 7, 0x14, 7, 0x04, 7, 0x17, 6, 0x01, 6, + 0x0B, 4, 0x07, 4, 0x11, 4, 0x0D, 4, + /* quant_vlc[1][1] - 25 entries */ + 0x07, 3, 0x0B, 3, 0x11, 3, 0x0D, 3, 0x0C, 2, 0x16, 6, 0x0E, 6, + 0x0A, 6, 0x02, 6, 0x05, 7, 0x09, 7, 0x15, 7, 0x0F, 7, 0x10, 5, + 0x13, 7, 0x01, 7, 0x17, 7, 0x14, 10, 0x00, 10, 0x04, 10, 0x18, 10, + 0x03, 8, 0x08, 5, 0x06, 5, 0x12, 5, + /* quant_vlc[2][0] - 7 entries */ + 0x02, 2, 0x03, 2, 0x01, 3, 0x05, 3, 0x00, 4, 0x06, 4, 0x04, 3, + /* quant_vlc[2][1] - 7 entries */ + 0x05, 3, 0x00, 5, 0x06, 5, 0x01, 4, 0x04, 2, 0x02, 2, 0x03, 2, + /* quant_vlc[3][0] - 9 entries */ + 0x01, 3, 0x07, 3, 0x08, 4, 0x00, 4, 0x06, 3, 0x02, 3, 0x05, 3, + 0x03, 3, 0x04, 3, + /* quant_vlc[3][1] - 9 entries */ + 0x03, 2, 0x08, 5, 0x00, 5, 0x07, 4, 0x02, 3, 0x04, 2, 0x01, 4, + 0x06, 4, 0x05, 3, + /* quant_vlc[4][0] - 15 entries */ + 0x05, 3, 0x08, 3, 0x06, 3, 0x07, 3, 0x02, 4, 0x0B, 4, 0x03, 4, + 0x0D, 5, 0x01, 5, 0x0A, 4, 0x04, 4, 0x0E, 6, 0x00, 6, 0x0C, 5, + 0x09, 4, + /* quant_vlc[4][1] - 15 entries */ + 0x04, 3, 0x03, 4, 0x0C, 5, 0x02, 5, 0x09, 3, 0x05, 3, 0x08, 3, + 0x06, 3, 0x07, 3, 0x01, 6, 0x0E, 8, 0x00, 8, 0x0D, 7, 0x0B, 5, + 0x0A, 4, + /* quant_vlc[5][0] - 31 entries */ + 0x0C, 4, 0x1A, 5, 0x01, 6, 0x1D, 6, 0x0D, 4, 0x10, 4, 0x11, 4, + 0x0E, 4, 0x19, 5, 0x05, 5, 0x0F, 4, 0x1E, 7, 0x00, 7, 0x1C, 6, + 0x06, 5, 0x18, 5, 0x07, 5, 0x17, 5, 0x09, 5, 0x02, 6, 0x03, 6, + 0x08, 5, 0x16, 5, 0x14, 5, 0x0A, 5, 0x15, 5, 0x13, 5, 0x1B, 6, + 0x04, 6, 0x0B, 5, 0x12, 5, + /* quant_vlc[5][1] - 31 entries */ + 0x0F, 3, 0x0A, 4, 0x14, 4, 0x17, 5, 0x07, 5, 0x13, 4, 0x0B, 4, + 0x16, 5, 0x08, 5, 0x0C, 4, 0x12, 4, 0x11, 4, 0x0D, 4, 0x18, 6, + 0x06, 6, 0x1B, 8, 0x1A, 8, 0x02, 10, 0x00, 13, 0x1D, 13, 0x01, 13, + 0x1E, 13, 0x1C, 11, 0x03, 9, 0x04, 8, 0x05, 7, 0x19, 7, 0x0E, 4, + 0x10, 4, 0x15, 5, 0x09, 5, + /* quant_vlc[6][0] - 63 entries */ + 0x18, 5, 0x25, 5, 0x19, 5, 0x24, 5, 0x23, 5, 0x1B, 5, 0x1D, 5, + 0x1F, 5, 0x22, 5, 0x1C, 5, 0x1A, 5, 0x20, 5, 0x0B, 6, 0x3A, 7, + 0x3E, 8, 0x00, 8, 0x1E, 5, 0x33, 6, 0x0C, 6, 0x21, 5, 0x04, 7, + 0x05, 7, 0x32, 6, 0x39, 7, 0x38, 7, 0x0D, 6, 0x31, 6, 0x0E, 6, + 0x3D, 8, 0x01, 8, 0x06, 7, 0x30, 6, 0x37, 7, 0x07, 7, 0x0F, 6, + 0x2F, 6, 0x2E, 6, 0x10, 6, 0x3C, 8, 0x02, 8, 0x08, 7, 0x11, 6, + 0x2D, 6, 0x2C, 6, 0x13, 6, 0x36, 7, 0x35, 7, 0x12, 6, 0x2B, 6, + 0x29, 6, 0x14, 6, 0x15, 6, 0x0A, 7, 0x09, 7, 0x16, 6, 0x3B, 8, + 0x03, 8, 0x34, 7, 0x2A, 6, 0x17, 6, 0x28, 6, 0x27, 6, 0x26, 6, + /* quant_vlc[6][1] - 63 entries */ + 0x20, 4, 0x2A, 5, 0x15, 5, 0x1F, 4, 0x29, 5, 0x0F, 6, 0x2F, 6, + 0x28, 5, 0x16, 5, 0x07, 9, 0x36, 9, 0x08, 9, 0x39, 10, 0x38, 10, + 0x32, 7, 0x2E, 6, 0x17, 5, 0x10, 6, 0x11, 6, 0x27, 5, 0x26, 5, + 0x0C, 7, 0x0A, 8, 0x34, 8, 0x2D, 6, 0x18, 5, 0x12, 6, 0x2C, 6, + 0x31, 7, 0x0D, 7, 0x13, 6, 0x19, 5, 0x25, 5, 0x1A, 5, 0x24, 5, + 0x2B, 6, 0x05, 10, 0x06, 10, 0x35, 9, 0x33, 8, 0x30, 7, 0x1B, 5, + 0x23, 5, 0x1C, 5, 0x14, 6, 0x0E, 7, 0x09, 9, 0x3A, 12, 0x00, 14, + 0x3E, 14, 0x02, 14, 0x3C, 14, 0x04, 12, 0x3D, 14, 0x01, 14, 0x03, 14, + 0x3B, 14, 0x37, 10, 0x0B, 8, 0x22, 5, 0x1D, 5, 0x21, 5, 0x1E, 5, }; #endif /* AVCODEC_MPC7DATA_H */ diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c index 03838a935..e9919aea6 100644 --- a/libavcodec/mpc8.c +++ b/libavcodec/mpc8.c @@ -27,6 +27,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/lfg.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "get_bits.h" #include "internal.h" @@ -39,9 +40,6 @@ static VLC band_vlc, scfi_vlc[2], dscf_vlc[2], res_vlc[2]; static VLC q1_vlc, q2_vlc[2], q3_vlc[2], quant_vlc[4][2], q9up_vlc; -static const int q3_offsets[2] = { MPC8_Q3_OFFSET, MPC8_Q4_OFFSET }; -static const int quant_offsets[6] = { MPC8_Q5_OFFSET, MPC8_Q6_OFFSET, MPC8_Q7_OFFSET, MPC8_Q8_OFFSET }; - static inline int mpc8_dec_base(GetBitContext *gb, int k, int n) { int len = mpc8_cnk_len[k-1][n-1] - 1; @@ -89,29 +87,63 @@ static int mpc8_get_mask(GetBitContext *gb, int size, int t) return mask; } -static const uint16_t vlc_offsets[13] = { - 0, 640, 1184, 1748, 2298, 2426, 2554, 3066, 3578, 4106, 4618, 5196, 5708 -}; +static av_cold void build_vlc(VLC *vlc, unsigned *buf_offset, + const uint8_t codes_counts[16], + const uint8_t **syms, int offset) +{ + static VLC_TYPE vlc_buf[9296][2]; + uint8_t len[MPC8_MAX_VLC_SIZE]; + unsigned num = 0; + + vlc->table = &vlc_buf[*buf_offset]; + vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *buf_offset; + + for (int i = 16; i > 0; i--) + for (unsigned tmp = num + codes_counts[i - 1]; num < tmp; num++) + len[num] = i; + + ff_init_vlc_from_lengths(vlc, FFMIN(len[0], 9), num, len, 1, + *syms, 1, 1, offset, INIT_VLC_STATIC_OVERLONG, NULL); + *buf_offset += vlc->table_size; + *syms += num; +} + +static av_cold void mpc8_init_static(void) +{ + const uint8_t *q_syms = mpc8_q_syms, *bands_syms = mpc8_bands_syms; + const uint8_t *res_syms = mpc8_res_syms, *scfi_syms = mpc8_scfi_syms; + const uint8_t *dscf_syms = mpc8_dscf_syms; + unsigned offset = 0; + + build_vlc(&band_vlc, &offset, mpc8_bands_len_counts, &bands_syms, 0); + + build_vlc(&q1_vlc, &offset, mpc8_q1_len_counts, &q_syms, 0); + build_vlc(&q9up_vlc, &offset, mpc8_q9up_len_counts, &q_syms, 0); + + for (int i = 0; i < 2; i++){ + build_vlc(&scfi_vlc[i], &offset, mpc8_scfi_len_counts[i], &scfi_syms, 0); + + build_vlc(&dscf_vlc[i], &offset, mpc8_dscf_len_counts[i], &dscf_syms, 0); + + build_vlc(&res_vlc[i], &offset, mpc8_res_len_counts[i], &res_syms, 0); + + build_vlc(&q2_vlc[i], &offset, mpc8_q2_len_counts[i], &q_syms, 0); + build_vlc(&q3_vlc[i], &offset, mpc8_q34_len_counts[i], + &q_syms, -48 - 16 * i); + for (int j = 0; j < 4; j++) + build_vlc(&quant_vlc[j][i], &offset, mpc8_q5_8_len_counts[i][j], + &q_syms, -((8 << j) - 1)); + } + ff_mpa_synth_init_fixed(); +} static av_cold int mpc8_decode_init(AVCodecContext * avctx) { - int i; + static AVOnce init_static_once = AV_ONCE_INIT; MPCContext *c = avctx->priv_data; GetBitContext gb; - static int vlc_initialized = 0; int channels; - static VLC_TYPE band_table[542][2]; - static VLC_TYPE q1_table[520][2]; - static VLC_TYPE q9up_table[524][2]; - static VLC_TYPE scfi0_table[1 << MPC8_SCFI0_BITS][2]; - static VLC_TYPE scfi1_table[1 << MPC8_SCFI1_BITS][2]; - static VLC_TYPE dscf0_table[560][2]; - static VLC_TYPE dscf1_table[598][2]; - static VLC_TYPE q3_0_table[512][2]; - static VLC_TYPE q3_1_table[516][2]; - static VLC_TYPE codes_table[5708][2]; - if(avctx->extradata_size < 2){ av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size); return -1; @@ -120,8 +152,6 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) av_lfg_init(&c->rnd, 0xDEADBEEF); ff_mpadsp_init(&c->mpadsp); - ff_mpc_init(); - init_get_bits(&gb, avctx->extradata, 16); skip_bits(&gb, 3);//sample rate @@ -142,96 +172,7 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) avctx->channel_layout = (channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; avctx->channels = channels; - if(vlc_initialized) return 0; - av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); - - band_vlc.table = band_table; - band_vlc.table_allocated = 542; - init_vlc(&band_vlc, MPC8_BANDS_BITS, MPC8_BANDS_SIZE, - mpc8_bands_bits, 1, 1, - mpc8_bands_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - - q1_vlc.table = q1_table; - q1_vlc.table_allocated = 520; - init_vlc(&q1_vlc, MPC8_Q1_BITS, MPC8_Q1_SIZE, - mpc8_q1_bits, 1, 1, - mpc8_q1_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - q9up_vlc.table = q9up_table; - q9up_vlc.table_allocated = 524; - init_vlc(&q9up_vlc, MPC8_Q9UP_BITS, MPC8_Q9UP_SIZE, - mpc8_q9up_bits, 1, 1, - mpc8_q9up_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - - scfi_vlc[0].table = scfi0_table; - scfi_vlc[0].table_allocated = 1 << MPC8_SCFI0_BITS; - init_vlc(&scfi_vlc[0], MPC8_SCFI0_BITS, MPC8_SCFI0_SIZE, - mpc8_scfi0_bits, 1, 1, - mpc8_scfi0_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - scfi_vlc[1].table = scfi1_table; - scfi_vlc[1].table_allocated = 1 << MPC8_SCFI1_BITS; - init_vlc(&scfi_vlc[1], MPC8_SCFI1_BITS, MPC8_SCFI1_SIZE, - mpc8_scfi1_bits, 1, 1, - mpc8_scfi1_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - - dscf_vlc[0].table = dscf0_table; - dscf_vlc[0].table_allocated = 560; - init_vlc(&dscf_vlc[0], MPC8_DSCF0_BITS, MPC8_DSCF0_SIZE, - mpc8_dscf0_bits, 1, 1, - mpc8_dscf0_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - dscf_vlc[1].table = dscf1_table; - dscf_vlc[1].table_allocated = 598; - init_vlc(&dscf_vlc[1], MPC8_DSCF1_BITS, MPC8_DSCF1_SIZE, - mpc8_dscf1_bits, 1, 1, - mpc8_dscf1_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - - q3_vlc[0].table = q3_0_table; - q3_vlc[0].table_allocated = 512; - ff_init_vlc_sparse(&q3_vlc[0], MPC8_Q3_BITS, MPC8_Q3_SIZE, - mpc8_q3_bits, 1, 1, - mpc8_q3_codes, 1, 1, - mpc8_q3_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); - q3_vlc[1].table = q3_1_table; - q3_vlc[1].table_allocated = 516; - ff_init_vlc_sparse(&q3_vlc[1], MPC8_Q4_BITS, MPC8_Q4_SIZE, - mpc8_q4_bits, 1, 1, - mpc8_q4_codes, 1, 1, - mpc8_q4_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); - - for(i = 0; i < 2; i++){ - res_vlc[i].table = &codes_table[vlc_offsets[0+i]]; - res_vlc[i].table_allocated = vlc_offsets[1+i] - vlc_offsets[0+i]; - init_vlc(&res_vlc[i], MPC8_RES_BITS, MPC8_RES_SIZE, - &mpc8_res_bits[i], 1, 1, - &mpc8_res_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - - q2_vlc[i].table = &codes_table[vlc_offsets[2+i]]; - q2_vlc[i].table_allocated = vlc_offsets[3+i] - vlc_offsets[2+i]; - init_vlc(&q2_vlc[i], MPC8_Q2_BITS, MPC8_Q2_SIZE, - &mpc8_q2_bits[i], 1, 1, - &mpc8_q2_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - - quant_vlc[0][i].table = &codes_table[vlc_offsets[4+i]]; - quant_vlc[0][i].table_allocated = vlc_offsets[5+i] - vlc_offsets[4+i]; - init_vlc(&quant_vlc[0][i], MPC8_Q5_BITS, MPC8_Q5_SIZE, - &mpc8_q5_bits[i], 1, 1, - &mpc8_q5_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - quant_vlc[1][i].table = &codes_table[vlc_offsets[6+i]]; - quant_vlc[1][i].table_allocated = vlc_offsets[7+i] - vlc_offsets[6+i]; - init_vlc(&quant_vlc[1][i], MPC8_Q6_BITS, MPC8_Q6_SIZE, - &mpc8_q6_bits[i], 1, 1, - &mpc8_q6_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - quant_vlc[2][i].table = &codes_table[vlc_offsets[8+i]]; - quant_vlc[2][i].table_allocated = vlc_offsets[9+i] - vlc_offsets[8+i]; - init_vlc(&quant_vlc[2][i], MPC8_Q7_BITS, MPC8_Q7_SIZE, - &mpc8_q7_bits[i], 1, 1, - &mpc8_q7_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - quant_vlc[3][i].table = &codes_table[vlc_offsets[10+i]]; - quant_vlc[3][i].table_allocated = vlc_offsets[11+i] - vlc_offsets[10+i]; - init_vlc(&quant_vlc[3][i], MPC8_Q8_BITS, MPC8_Q8_SIZE, - &mpc8_q8_bits[i], 1, 1, - &mpc8_q8_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - vlc_initialized = 1; + ff_thread_once(&init_static_once, mpc8_init_static); return 0; } @@ -382,9 +323,9 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, case 3: case 4: for(j = 0; j < SAMPLES_PER_BAND; j += 2){ - t = get_vlc2(gb, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2) + q3_offsets[res - 3]; + t = get_vlc2(gb, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2); c->Q[ch][off + j + 1] = t >> 4; - c->Q[ch][off + j + 0] = (t & 8) ? (t & 0xF) - 16 : (t & 0xF); + c->Q[ch][off + j + 0] = sign_extend(t, 4); } break; case 5: @@ -393,8 +334,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, case 8: cnt = 2 * mpc8_thres[res]; for(j = 0; j < SAMPLES_PER_BAND; j++){ - t = get_vlc2(gb, quant_vlc[res - 5][cnt > mpc8_thres[res]].table, quant_vlc[res - 5][cnt > mpc8_thres[res]].bits, 2) + quant_offsets[res - 5]; - c->Q[ch][off + j] = t; + const VLC *vlc = &quant_vlc[res - 5][cnt > mpc8_thres[res]]; + c->Q[ch][off + j] = get_vlc2(gb, vlc->table, vlc->bits, 2); cnt = (cnt >> 1) + FFABS(c->Q[ch][off + j]); } break; @@ -451,7 +392,8 @@ AVCodec ff_mpc8_decoder = { .init = mpc8_decode_init, .decode = mpc8_decode_frame, .flush = mpc8_decode_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/mpc8huff.h b/libavcodec/mpc8huff.h index 0566c910c..51997df3e 100644 --- a/libavcodec/mpc8huff.h +++ b/libavcodec/mpc8huff.h @@ -24,555 +24,207 @@ #include +#define MPC8_MAX_VLC_SIZE 256 + #define MPC8_BANDS_SIZE 33 #define MPC8_BANDS_BITS 9 -static const uint8_t mpc8_bands_codes[MPC8_BANDS_SIZE] = { - 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, - 0x05, 0x06, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x01, 0x09, 0x0A, 0x0B, 0x07, - 0x08, 0x09, 0x06, 0x07, 0x05, 0x05, 0x03, 0x03, - 0x01, +static const uint8_t mpc8_bands_syms[MPC8_BANDS_SIZE] = { + 13, 19, 10, 11, 12, 14, 15, 16, 17, 18, 20, 21, 22, 9, 23, 24, 25, 8, 26, + 27, 7, 28, 5, 6, 29, 4, 3, 30, 2, 31, 1, 32, 0 }; -static const uint8_t mpc8_bands_bits[MPC8_BANDS_SIZE] = { - 1, 3, 5, 6, 7, 8, 8, 9, - 10, 11, 12, 12, 12, 13, 12, 12, - 12, 12, 12, 13, 12, 12, 12, 11, - 11, 11, 10, 10, 9, 8, 6, 5, - 2, +static const uint8_t mpc8_bands_len_counts[16] = { + 1, 1, 1, 0, 2, 2, 1, 3, 2, 3, 4, 11, 2, 0, 0, 0 }; -#define MPC8_SCFI0_SIZE 4 -#define MPC8_SCFI0_BITS 3 - -static const uint8_t mpc8_scfi0_codes[MPC8_SCFI0_SIZE] = { - 0x00, 0x01, 0x01, 0x01, -}; -static const uint8_t mpc8_scfi0_bits[MPC8_SCFI0_SIZE] = { - 3, 3, 1, 2, +static const uint8_t mpc8_scfi_syms[] = { + /* SCFI[0] VLC symbols - 4 entries */ + 0, 1, 3, 2, + /* SCFI[1] VLC symbols - 16 entries */ + 1, 4, 0, 2, 3, 8, 12, 5, 6, 7, 9, 13, 11, 14, 10, 15 }; -#define MPC8_SCFI1_SIZE 16 -#define MPC8_SCFI1_BITS 7 - -static const uint8_t mpc8_scfi1_codes[MPC8_SCFI1_SIZE] = { - 0x01, 0x00, 0x02, 0x03, 0x01, 0x03, 0x04, 0x05, - 0x04, 0x06, 0x02, 0x02, 0x05, 0x07, 0x03, 0x03, - -}; -static const uint8_t mpc8_scfi1_bits[MPC8_SCFI1_SIZE] = { - 6, 7, 6, 6, 7, 5, 5, 5, - 6, 5, 2, 3, 6, 5, 3, 2, - +static const uint8_t mpc8_scfi_len_counts[2][16] = { + { 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 2, 2, 0, 5, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }; -#define MPC8_DSCF0_SIZE 64 #define MPC8_DSCF0_BITS 9 - -static const uint8_t mpc8_dscf0_codes[MPC8_DSCF0_SIZE] = { - 0x03, 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x07, 0x08, 0x09, 0x0A, 0x07, - 0x08, 0x09, 0x0A, 0x07, 0x08, 0x09, 0x0A, 0x06, - 0x07, 0x05, 0x04, 0x05, 0x06, 0x06, 0x07, 0x0A, - 0x08, 0x05, 0x06, 0x07, 0x09, 0x07, 0x08, 0x09, - 0x0B, 0x0B, 0x0C, 0x0D, 0x0B, 0x0C, 0x0D, 0x0B, - 0x0C, 0x0D, 0x07, 0x08, 0x09, 0x06, 0x07, 0x03, - 0x04, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, -}; -static const uint8_t mpc8_dscf0_bits[MPC8_DSCF0_SIZE] = { - 12, 12, 12, 11, 11, 11, 10, 10, - 10, 10, 10, 9, 9, 9, 9, 8, - 8, 8, 8, 7, 7, 7, 7, 6, - 6, 5, 4, 4, 5, 4, 4, 10, - 4, 3, 3, 3, 4, 5, 6, 6, - 7, 8, 8, 8, 9, 9, 9, 10, - 10, 10, 11, 11, 11, 12, 12, 13, - 13, 13, 14, 14, 14, 14, 14, 14, - -}; - -#define MPC8_DSCF1_SIZE 65 #define MPC8_DSCF1_BITS 9 -static const uint8_t mpc8_dscf1_codes[MPC8_DSCF1_SIZE] = { - 0x00, 0x03, 0x04, 0x04, 0x05, 0x06, 0x05, 0x06, - 0x07, 0x08, 0x07, 0x08, 0x09, 0x0A, 0x07, 0x08, - 0x09, 0x0A, 0x07, 0x08, 0x09, 0x06, 0x07, 0x05, - 0x06, 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x05, 0x04, 0x05, 0x05, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0B, 0x0C, 0x0D, 0x0B, 0x0C, - 0x0D, 0x09, 0x0A, 0x0B, 0x0C, 0x07, 0x08, 0x09, - 0x05, 0x06, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x0D, +static const uint8_t mpc8_dscf_syms[] = { + /* DSCF[0] VLC symbols - 64 entries */ + 58, 59, 60, 61, 62, 63, 55, 56, 57, 0, 1, 2, 53, 54, 3, 4, 5, 50, 51, + 52, 6, 7, 8, 9, 10, 31, 47, 48, 49, 11, 12, 13, 14, 44, 45, 46, 15, 16, + 17, 18, 41, 42, 43, 19, 20, 21, 22, 40, 23, 24, 38, 39, 25, 28, 37, 26, 27, + 29, 30, 32, 36, 33, 34, 35, + /* DSCF[1] VLC symbols - 65 entries */ + 0, 59, 60, 61, 62, 63, 1, 2, 56, 57, 58, 3, 4, 5, 53, 54, 55, 6, 7, + 8, 9, 49, 50, 51, 52, 64, 10, 11, 12, 13, 46, 47, 48, 14, 15, 16, 17, 43, + 44, 45, 18, 19, 20, 41, 42, 21, 22, 39, 40, 23, 24, 38, 25, 37, 26, 35, 36, + 27, 28, 34, 29, 30, 31, 32, 33, }; -static const uint8_t mpc8_dscf1_bits[MPC8_DSCF1_SIZE] = { - 15, 14, 14, 13, 13, 13, 12, 12, - 12, 12, 11, 11, 11, 11, 10, 10, - 10, 10, 9, 9, 9, 8, 8, 7, - 7, 6, 5, 4, 4, 3, 3, 3, - 3, 3, 4, 5, 5, 6, 7, 8, - 8, 9, 9, 10, 10, 10, 11, 11, - 11, 12, 12, 12, 12, 13, 13, 13, - 14, 14, 14, 15, 15, 15, 15, 15, - 12, + +static const uint8_t mpc8_dscf_len_counts[2][16] = { + { 0, 0, 3, 6, 3, 4, 5, 7, 7, 9, 6, 5, 3, 6, 0, 0 }, + { 0, 0, 5, 3, 3, 2, 3, 4, 5, 7, 7, 9, 6, 5, 6, 0 }, }; -#define MPC8_RES_SIZE 17 #define MPC8_RES_BITS 9 -static const uint8_t mpc8_res_codes[2][MPC8_RES_SIZE] = { - { - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, - 0x01, - }, - { - 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, 0x01, - 0x03, - } +static const uint8_t mpc8_res_syms[] = { + /* RES[0] VLC symbols - 17 entries */ + 13, 14, 12, 11, 10, 9, 8, 7, 6, 15, 5, 4, 3, 2, 16, 1, 0, + /* RES[1] VLC symbols - 17 entries */ + 8, 9, 10, 11, 7, 12, 6, 13, 5, 4, 14, 3, 15, 2, 0, 1, 16, }; -static const uint8_t mpc8_res_bits[2][MPC8_RES_SIZE] = { - { - 1, 2, 4, 5, 6, 7, 9, 10, - 11, 12, 13, 14, 15, 16, 16, 8, - 3, - }, - { - 2, 2, 3, 5, 7, 8, 10, 12, - 14, 14, 14, 14, 11, 9, 6, 4, - 2, - } + +static const uint8_t mpc8_res_len_counts[2][16] = { + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 }, + { 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, 0, 0 }, }; -#define MPC8_Q1_SIZE 19 #define MPC8_Q1_BITS 9 -static const uint8_t mpc8_q1_codes[MPC8_Q1_SIZE] = { - 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x03, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x01, -}; -static const uint8_t mpc8_q1_bits[MPC8_Q1_SIZE] = { - 6, 4, 4, 3, 3, 3, 3, 3, - 4, 4, 4, 5, 7, 8, 9, 10, - 11, 12, 12, +static const uint8_t mpc8_q1_len_counts[16] = { + 0, 0, 5, 5, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0 }; -#define MPC8_Q9UP_SIZE 256 #define MPC8_Q9UP_BITS 9 -static const uint8_t mpc8_q9up_codes[MPC8_Q9UP_SIZE] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x26, 0x27, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, - 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, - 0x28, 0x26, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, - 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, - 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, - 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, - 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6A, 0x56, 0x57, 0x58, 0x59, - 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x3E, - 0x3F, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7A, 0x6B, 0x7B, 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, 0x86, - 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, - 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, - 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0x27, 0x28, 0x29, - 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, - 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, - 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4A, 0x4B, 0x06, 0x07, 0x08, 0x09, 0x00, 0x01, -}; -static const uint8_t mpc8_q9up_bits[MPC8_Q9UP_SIZE] = { - 10, 10, 10, 10, 10, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 8, 8, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 8, 9, 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, 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, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 6, - 6, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 8, 7, 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, 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, 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, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 10, 10, 10, 10, 11, 11, +static const uint8_t mpc8_q9up_len_counts[16] = { + 0, 0, 0, 0, 0, 2, 38, 134, 71, 9, 2, 0, 0, 0, 0, 0 }; -#define MPC8_Q2_SIZE 125 #define MPC8_Q2_BITS 9 -static const uint8_t mpc8_q2_codes[2][MPC8_Q2_SIZE] = { -{ - 0x02, 0x03, 0x0F, 0x04, 0x00, 0x05, 0x0C, 0x12, - 0x0D, 0x06, 0x07, 0x13, 0x15, 0x14, 0x08, 0x09, - 0x0E, 0x15, 0x0F, 0x0A, 0x03, 0x0B, 0x10, 0x0C, - 0x01, 0x0D, 0x10, 0x16, 0x11, 0x0E, 0x12, 0x0F, - 0x10, 0x16, 0x13, 0x17, 0x11, 0x08, 0x12, 0x18, - 0x14, 0x13, 0x14, 0x17, 0x15, 0x0F, 0x16, 0x19, - 0x17, 0x10, 0x11, 0x1A, 0x18, 0x1B, 0x12, 0x1C, - 0x15, 0x09, 0x16, 0x1D, 0x19, 0x0A, 0x07, 0x0B, - 0x1A, 0x1E, 0x17, 0x0C, 0x18, 0x1F, 0x13, 0x20, - 0x1B, 0x21, 0x14, 0x11, 0x18, 0x22, 0x19, 0x12, - 0x1A, 0x19, 0x1A, 0x1B, 0x1B, 0x23, 0x1C, 0x0D, - 0x1D, 0x24, 0x1C, 0x1C, 0x1E, 0x1F, 0x1D, 0x13, - 0x1E, 0x25, 0x1F, 0x14, 0x02, 0x15, 0x15, 0x16, - 0x04, 0x17, 0x20, 0x26, 0x21, 0x18, 0x16, 0x27, - 0x1D, 0x28, 0x19, 0x1A, 0x22, 0x29, 0x23, 0x1B, - 0x03, 0x1C, 0x17, 0x1D, 0x05, -}, -{ - 0x02, 0x03, 0x0F, 0x04, 0x00, 0x05, 0x0C, 0x0D, - 0x0E, 0x06, 0x07, 0x0F, 0x1E, 0x10, 0x10, 0x08, - 0x11, 0x12, 0x13, 0x09, 0x03, 0x0A, 0x11, 0x0B, - 0x01, 0x0C, 0x14, 0x15, 0x16, 0x0D, 0x17, 0x12, - 0x0E, 0x13, 0x18, 0x19, 0x14, 0x0F, 0x10, 0x1A, - 0x1B, 0x15, 0x11, 0x16, 0x1C, 0x0E, 0x1D, 0x1E, - 0x1F, 0x0F, 0x12, 0x20, 0x1F, 0x21, 0x13, 0x22, - 0x12, 0x13, 0x14, 0x23, 0x20, 0x15, 0x0F, 0x16, - 0x21, 0x24, 0x17, 0x18, 0x19, 0x25, 0x14, 0x26, - 0x22, 0x27, 0x15, 0x10, 0x28, 0x29, 0x2A, 0x11, - 0x2B, 0x17, 0x1A, 0x18, 0x2C, 0x2D, 0x1B, 0x1C, - 0x19, 0x2E, 0x2F, 0x1A, 0x1D, 0x1B, 0x30, 0x12, - 0x31, 0x32, 0x33, 0x13, 0x02, 0x14, 0x15, 0x16, - 0x04, 0x17, 0x34, 0x35, 0x36, 0x18, 0x16, 0x37, - 0x23, 0x38, 0x19, 0x1A, 0x39, 0x3A, 0x3B, 0x1B, - 0x03, 0x1C, 0x17, 0x1D, 0x05, -} -}; -static const uint8_t mpc8_q2_bits[2][MPC8_Q2_SIZE] = { -{ - 12, 11, 10, 11, 13, 11, 9, 8, - 9, 11, 11, 8, 7, 8, 11, 11, - 9, 8, 9, 11, 12, 11, 10, 11, - 13, 11, 9, 8, 9, 11, 9, 6, - 6, 7, 9, 8, 6, 4, 6, 8, - 9, 6, 6, 7, 9, 11, 9, 8, - 9, 11, 10, 8, 7, 8, 10, 8, - 6, 4, 6, 8, 7, 4, 3, 4, - 7, 8, 6, 4, 6, 8, 10, 8, - 7, 8, 10, 11, 9, 8, 9, 11, - 9, 6, 6, 6, 9, 8, 6, 4, - 6, 8, 9, 7, 6, 6, 9, 11, - 9, 8, 9, 11, 13, 11, 10, 11, - 12, 11, 9, 8, 9, 11, 10, 8, - 7, 8, 11, 11, 9, 8, 9, 11, - 13, 11, 10, 11, 12, -}, -{ - 11, 10, 9, 10, 12, 10, 8, 8, - 8, 10, 10, 8, 7, 8, 9, 10, - 8, 8, 8, 10, 11, 10, 9, 10, - 12, 10, 8, 8, 8, 10, 8, 6, - 5, 6, 8, 8, 6, 5, 5, 8, - 8, 6, 5, 6, 8, 10, 8, 8, - 8, 10, 9, 8, 7, 8, 9, 8, - 5, 5, 5, 8, 7, 5, 4, 5, - 7, 8, 5, 5, 5, 8, 9, 8, - 7, 8, 9, 10, 8, 8, 8, 10, - 8, 6, 5, 6, 8, 8, 5, 5, - 6, 8, 8, 6, 5, 6, 8, 10, - 8, 8, 8, 10, 12, 10, 10, 10, - 11, 10, 8, 8, 8, 10, 9, 8, - 7, 8, 10, 10, 8, 8, 8, 10, - 12, 10, 9, 10, 11, -} +static const uint8_t mpc8_q2_len_counts[2][16] = { + { 0, 0, 1, 6, 0, 17, 9, 24, 24, 9, 27, 4, 4, 0, 0, 0 }, + { 0, 0, 0, 1, 16, 10, 6, 48, 9, 27, 4, 4, 0, 0, 0, 0 }, }; -#define MPC8_Q3_SIZE 49 #define MPC8_Q3_BITS 9 -#define MPC8_Q3_OFFSET -48 - -static const uint8_t mpc8_q3_codes[MPC8_Q3_SIZE] = { - 0x07, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x0F, - 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x13, 0x12, 0x11, - 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, - 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, - 0x09, 0x08, 0x07, 0x06, 0x05, 0x09, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, - 0x00, -}; -static const uint8_t mpc8_q3_bits[MPC8_Q3_SIZE] = { - 3, 4, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 8, 8, 8, - 8, 8, 8, 8, 8, 9, 9, 9, - 9, -}; -static const uint8_t mpc8_q3_syms[MPC8_Q3_SIZE] = { - 48, 65, 64, 49, 63, 32, 47, 80, - 79, 50, 62, 33, 16, 82, 81, 95, - 94, 66, 78, 34, 46, 17, 31, 30, - 97, 96, 111, 67, 77, 51, 61, 35, - 45, 18, 1, 0, 15, 98, 110, 83, - 93, 19, 29, 2, 14, 99, 109, 3, - 13, -}; - -#define MPC8_Q4_SIZE 81 #define MPC8_Q4_BITS 9 -#define MPC8_Q4_OFFSET -64 -static const uint8_t mpc8_q4_codes[MPC8_Q4_SIZE] = { - 0x0F, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, - 0x16, 0x15, 0x14, 0x13, 0x12, 0x23, 0x22, 0x21, - 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, - 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, - 0x10, 0x0F, 0x0E, 0x0D, 0x19, 0x18, 0x17, 0x16, - 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, - 0x0D, 0x0C, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, - 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, - 0x09, 0x08, 0x07, 0x06, 0x05, 0x09, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, - 0x00, -}; -static const uint8_t mpc8_q4_bits[MPC8_Q4_SIZE] = { - 4, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 9, 9, 9, - 9, 9, 9, 9, 9, 10, 10, 10, - 10, -}; -static const uint8_t mpc8_q4_syms[MPC8_Q4_SIZE] = { - 64, 96, 81, 80, 95, 66, 65, 79, - 78, 49, 48, 63, 32, 113, 112, 98, - 97, 111, 110, 83, 82, 94, 93, 67, - 77, 51, 50, 62, 61, 34, 33, 47, - 46, 17, 16, 31, 128, 114, 127, 126, - 99, 109, 68, 76, 35, 45, 18, 30, - 0, 15, 130, 129, 143, 142, 115, 125, - 100, 108, 84, 92, 52, 60, 36, 44, - 19, 29, 2, 1, 14, 131, 141, 116, - 124, 20, 28, 3, 13, 132, 140, 4, - 12, +static const uint8_t mpc8_q34_len_counts[2][16] = { + { 0, 0, 1, 6, 6, 11, 13, 8, 4, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 1, 12, 23, 14, 19, 8, 4, 0, 0, 0, 0, 0, 0 }, }; -#define MPC8_Q5_SIZE 15 -#define MPC8_Q5_BITS 7 -#define MPC8_Q5_OFFSET -7 - -static const uint8_t mpc8_q5_codes[2][MPC8_Q5_SIZE] = { -{ - 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, - 0x04, 0x05, 0x03, 0x03, 0x03, 0x02, 0x03, -}, -{ - 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x04, 0x05, 0x03, 0x02, 0x03, -} -}; -static const uint8_t mpc8_q5_bits[2][MPC8_Q5_SIZE] = { -{ - 7, 7, 6, 5, 4, 3, 3, 2, - 3, 3, 4, 5, 6, 7, 7, -}, -{ - 6, 6, 5, 4, 4, 3, 3, 3, - 3, 3, 4, 4, 5, 6, 6, -} +static const uint8_t mpc8_q5_8_len_counts[2][4][16] = { + { /* Q5[0], Q6[0], Q7[0], Q8[0] */ + { 0, 1, 4, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 2, 4, 3, 7, 2, 4, 8, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 2, 2, 4, 6, 10, 10, 12, 16, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 2, 1, 3, 8, 8, 15, 24, 42, 17, 6, 0, 0, 0, 0 }, + }, + { /* Q5[1], Q6[1], Q7[1], Q8[1] */ + { 0, 0, 5, 4, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 11, 6, 4, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 20, 15, 10, 14, 4, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 26, 55, 38, 8, 0, 0, 0, 0, 0, 0, 0 }, + } }; -#define MPC8_Q6_SIZE 31 -#define MPC8_Q6_BITS 9 -#define MPC8_Q6_OFFSET -15 - -static const uint8_t mpc8_q6_codes[2][MPC8_Q6_SIZE] = { -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x03, - 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x04, 0x03, - 0x05, 0x06, 0x07, 0x07, 0x06, 0x07, 0x08, 0x09, - 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07, -}, -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x05, 0x04, - 0x05, 0x06, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x07, 0x08, 0x09, - 0x06, 0x07, 0x05, 0x06, 0x07, 0x02, 0x03, -} -}; -static const uint8_t mpc8_q6_bits[2][MPC8_Q6_SIZE] = { -{ - 9, 9, 9, 9, 8, 8, 7, 6, - 6, 6, 5, 5, 4, 4, 3, 2, - 3, 4, 4, 5, 6, 6, 6, 6, - 7, 8, 8, 9, 9, 9, 9, -}, -{ - 8, 8, 7, 7, 7, 6, 6, 5, - 5, 5, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 5, 5, 5, - 6, 6, 7, 7, 7, 8, 8, -} -}; - -#define MPC8_Q7_SIZE 63 -#define MPC8_Q7_BITS 9 -#define MPC8_Q7_OFFSET -31 - -static const uint8_t mpc8_q7_codes[2][MPC8_Q7_SIZE] = { -{ - 0x00, 0x01, 0x02, 0x08, 0x09, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x0A, 0x0B, 0x0C, 0x0D, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0A, 0x0B, 0x0C, 0x08, 0x09, 0x06, 0x04, 0x03, - 0x05, 0x07, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x0F, - 0x10, 0x11, 0x12, 0x0F, 0x13, 0x10, 0x11, 0x12, - 0x13, 0x0E, 0x0F, 0x10, 0x11, 0x08, 0x09, 0x0A, - 0x0B, 0x0C, 0x12, 0x13, 0x0D, 0x0E, 0x0F, -}, -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x09, 0x0A, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, - 0x1E, 0x1F, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x17, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x09, 0x0A, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x02, 0x03, -} -}; -static const uint8_t mpc8_q7_bits[2][MPC8_Q7_SIZE] = { -{ - 10, 10, 10, 9, 9, 10, 10, 10, - 10, 10, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 7, 7, 7, 7, 7, - 6, 6, 6, 5, 5, 4, 3, 2, - 3, 4, 5, 5, 6, 6, 6, 7, - 7, 7, 7, 8, 7, 8, 8, 8, - 8, 9, 9, 9, 9, 10, 10, 10, - 10, 10, 9, 9, 10, 10, 10, -}, -{ - 9, 9, 8, 8, 8, 8, 8, 8, - 8, 7, 7, 7, 7, 7, 6, 6, - 6, 6, 6, 6, 6, 6, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 6, 6, 6, 6, 6, 6, - 6, 7, 7, 7, 7, 7, 8, 8, - 8, 8, 8, 8, 8, 9, 9, -} -}; - -#define MPC8_Q8_SIZE 127 -#define MPC8_Q8_BITS 9 -#define MPC8_Q8_OFFSET -63 - -static const uint8_t mpc8_q8_codes[2][MPC8_Q8_SIZE] = { -{ - 0x03, 0x04, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x1A, - 0x0F, 0x1B, 0x10, 0x00, 0x01, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x11, 0x0C, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1C, 0x1A, - 0x1B, 0x1C, 0x1D, 0x1E, 0x1D, 0x1E, 0x1F, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x19, 0x25, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F, 0x14, 0x15, 0x16, 0x17, - 0x0E, 0x0F, 0x10, 0x11, 0x0B, 0x07, 0x04, 0x03, - 0x05, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x18, - 0x19, 0x1A, 0x1B, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x26, 0x27, 0x28, 0x29, 0x2A, - 0x2B, 0x2C, 0x2D, 0x2E, 0x1F, 0x20, 0x2F, 0x21, - 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x0D, 0x0E, 0x2A, 0x0F, 0x10, 0x11, 0x12, 0x02, - 0x13, 0x03, 0x04, 0x05, 0x2B, 0x2C, 0x30, 0x31, - 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, -}, -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 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, 0x30, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, - 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0x3E, 0x31, 0x3F, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, - 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x16, - 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, - 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x04, 0x05, 0x06, 0x07, -} -}; -static const uint8_t mpc8_q8_bits[2][MPC8_Q8_SIZE] = { -{ - 11, 11, 10, 10, 10, 10, 10, 9, - 10, 9, 10, 12, 12, 11, 11, 11, - 11, 11, 11, 11, 10, 11, 10, 10, - 10, 10, 10, 10, 10, 10, 9, 10, - 10, 10, 10, 10, 9, 9, 9, 9, - 9, 9, 9, 9, 8, 9, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, - 6, 6, 6, 6, 5, 4, 3, 2, - 3, 5, 5, 6, 6, 6, 6, 7, - 7, 7, 7, 8, 8, 8, 8, 8, - 8, 8, 8, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 10, 10, 9, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 10, 11, 11, 11, 11, 12, - 11, 12, 12, 12, 10, 10, 9, 9, - 10, 10, 10, 10, 10, 10, 10, -}, -{ - 9, 9, 9, 9, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 7, 6, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 9, 9, 9, 9, -} +static const uint8_t mpc8_q_syms[] = { + /* Q1 VLC symbols - 19 entries */ + 17, 18, 16, 15, 14, 13, 12, 0, 11, 1, 2, 8, 9, 10, 3, + 4, 5, 6, 7, + /* Q9UP VLC symbols - 256 entries */ + 254, 255, 0, 1, 2, 3, 4, 250, 251, 252, 253, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, + 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, 19, 20, 40, 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, 147, 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, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 148, 127, + 128, + /* Q2[0] VLC symbols - 125 entries */ + 4, 24, 100, 120, 0, 20, 104, 124, 1, 3, 5, 9, 10, 14, 15, + 19, 21, 23, 25, 29, 45, 49, 75, 79, 95, 99, 101, 103, 105, 109, + 114, 115, 119, 121, 123, 2, 22, 50, 54, 70, 74, 102, 110, 122, 6, + 8, 16, 18, 26, 28, 30, 34, 40, 44, 46, 48, 76, 78, 80, 84, + 90, 94, 96, 98, 106, 108, 116, 118, 7, 11, 13, 17, 27, 35, 39, + 47, 51, 53, 55, 59, 65, 69, 71, 73, 77, 85, 89, 97, 107, 111, + 113, 117, 12, 33, 43, 52, 60, 64, 72, 91, 112, 31, 32, 36, 38, + 41, 42, 56, 58, 66, 68, 81, 82, 83, 86, 88, 92, 93, 37, 57, + 61, 63, 67, 87, 62, + /* Q3 VLC symbols - 49 entries */ + 13, 3, 109, 99, 14, 2, 29, 19, 93, 83, 110, 98, 15, 0, 1, + 18, 45, 35, 61, 51, 77, 67, 111, 96, 97, 30, 31, 17, 46, 34, + 78, 66, 94, 95, 81, 82, 16, 33, 62, 50, 79, 80, 47, 32, 63, + 49, 64, 65, 48, + /* Q5[0] VLC symbols - 15 entries */ + 0, 1, 13, 14, 2, 12, 3, 11, 4, 10, 5, 6, 8, 9, 7, + /* Q6[0] VLC symbols - 31 entries */ + 0, 1, 2, 3, 27, 28, 29, 30, 4, 5, 25, 26, 6, 24, 7, + 8, 9, 20, 21, 22, 23, 10, 11, 19, 12, 13, 17, 18, 14, 16, + 15, + /* Q7[0] VLC symbols - 63 entries */ + 0, 1, 2, 5, 6, 7, 8, 9, 53, 54, 55, 56, 57, 60, 61, + 62, 3, 4, 10, 11, 12, 13, 49, 50, 51, 52, 58, 59, 14, 15, + 16, 17, 18, 43, 45, 46, 47, 48, 19, 20, 21, 22, 23, 39, 40, + 41, 42, 44, 24, 25, 26, 36, 37, 38, 27, 28, 34, 35, 29, 33, + 30, 32, 31, + /* Q8[0] VLC symbols - 127 entries */ + 11, 12, 111, 113, 114, 115, 0, 1, 13, 14, 15, 16, 17, 18, 19, + 21, 104, 105, 107, 108, 109, 110, 112, 2, 3, 4, 5, 6, 8, 10, + 20, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35, 92, + 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 106, 116, 117, 120, 121, + 122, 123, 124, 125, 126, 7, 9, 30, 36, 37, 38, 39, 40, 41, 42, + 43, 45, 83, 84, 85, 86, 87, 88, 89, 90, 91, 94, 118, 119, 44, + 46, 47, 48, 49, 50, 51, 75, 76, 77, 78, 79, 80, 81, 82, 52, + 53, 54, 55, 71, 72, 73, 74, 56, 57, 58, 59, 67, 68, 69, 70, + 60, 65, 66, 61, 62, 64, 63, + /* Q2[1] VLC symbols - 125 entries */ + 4, 24, 100, 120, 0, 20, 104, 124, 1, 3, 5, 9, 10, 15, 19, + 21, 23, 25, 29, 45, 49, 75, 79, 95, 99, 101, 102, 103, 105, 109, + 114, 115, 119, 121, 123, 2, 14, 22, 50, 54, 70, 74, 110, 122, 6, + 7, 8, 11, 13, 16, 17, 18, 26, 27, 28, 30, 34, 35, 39, 40, + 44, 46, 47, 48, 51, 53, 55, 59, 65, 69, 71, 73, 76, 77, 78, + 80, 84, 85, 89, 90, 94, 96, 97, 98, 106, 107, 108, 111, 113, 116, + 117, 118, 12, 52, 60, 64, 72, 112, 31, 33, 36, 41, 43, 81, 83, + 88, 91, 93, 32, 37, 38, 42, 56, 57, 58, 61, 63, 66, 67, 68, + 82, 86, 87, 92, 62, + /* Q4 VLC symbols - 81 entries */ + 12, 4, 140, 132, 13, 3, 28, 20, 124, 116, 141, 131, 14, 1, 2, + 29, 19, 44, 36, 60, 52, 92, 84, 108, 100, 125, 115, 142, 143, 129, + 130, 15, 0, 30, 18, 45, 35, 76, 68, 109, 99, 126, 127, 114, 128, + 31, 16, 17, 46, 47, 33, 34, 61, 62, 50, 51, 77, 67, 93, 94, + 82, 83, 110, 111, 97, 98, 112, 113, 32, 63, 48, 49, 78, 79, 65, + 66, 95, 80, 81, 96, 64, + /* Q5[1] VLC symbols - 15 entries */ + 0, 1, 13, 14, 2, 12, 3, 4, 10, 11, 5, 6, 7, 8, 9, + /* Q6[1] VLC symbols - 31 entries */ + 0, 1, 29, 30, 2, 3, 4, 26, 27, 28, 5, 6, 24, 25, 7, + 8, 9, 21, 22, 23, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, + /* Q7[1] VLC symbols - 63 entries */ + 0, 1, 61, 62, 2, 3, 4, 5, 6, 7, 8, 54, 55, 56, 57, + 58, 59, 60, 9, 10, 11, 12, 13, 49, 50, 51, 52, 53, 14, 15, + 16, 17, 18, 19, 20, 21, 42, 43, 44, 45, 46, 47, 48, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, + /* Q8[1] VLC symbols - 127 entries */ + 0, 1, 2, 3, 123, 124, 125, 126, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 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, 75, + 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, 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, 76, }; #endif /* AVCODEC_MPC8HUFF_H */ diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index ab6c19c61..1aacd07e4 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -30,6 +30,7 @@ #include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/timecode.h" +#include "libavutil/thread.h" #include "internal.h" #include "avcodec.h" @@ -41,8 +42,6 @@ #include "bytestream.h" #include "thread.h" -uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; - static const uint8_t table_mb_ptype[7][2] = { { 3, 5 }, // 0x01 MB_INTRA { 1, 2 }, // 0x02 MB_PAT @@ -134,41 +133,39 @@ VLC ff_mb_ptype_vlc; VLC ff_mb_btype_vlc; VLC ff_mb_pat_vlc; +static av_cold void mpeg12_init_vlcs(void) +{ + INIT_VLC_STATIC(&ff_dc_lum_vlc, DC_VLC_BITS, 12, + ff_mpeg12_vlc_dc_lum_bits, 1, 1, + ff_mpeg12_vlc_dc_lum_code, 2, 2, 512); + 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(&ff_mv_vlc, MV_VLC_BITS, 17, + &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1, + &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 266); + 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(&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(&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(&ff_mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, + &table_mb_btype[0][1], 2, 1, + &table_mb_btype[0][0], 2, 1, 64); + + INIT_2D_VLC_RL(ff_rl_mpeg1, 680, 0); + INIT_2D_VLC_RL(ff_rl_mpeg2, 674, 0); +} + av_cold void ff_mpeg12_init_vlcs(void) { - static int done = 0; - - if (!done) { - done = 1; - - INIT_VLC_STATIC(&ff_dc_lum_vlc, DC_VLC_BITS, 12, - ff_mpeg12_vlc_dc_lum_bits, 1, 1, - ff_mpeg12_vlc_dc_lum_code, 2, 2, 512); - 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(&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(&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(&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(&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(&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_rl_init(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); - ff_rl_init(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); - - INIT_2D_VLC_RL(ff_rl_mpeg1, 680, 0); - INIT_2D_VLC_RL(ff_rl_mpeg2, 674, 0); - } + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, mpeg12_init_vlcs); } /** diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h index 1ec99f17e..4cd48b5d2 100644 --- a/libavcodec/mpeg12.h +++ b/libavcodec/mpeg12.h @@ -25,8 +25,6 @@ #include "mpeg12vlc.h" #include "mpegvideo.h" -extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; - void ff_mpeg12_common_init(MpegEncContext *s); #define INIT_2D_VLC_RL(rl, static_size, flags)\ @@ -37,6 +35,7 @@ void ff_mpeg12_common_init(MpegEncContext *s); } void ff_init_2d_vlc_rl(RLTable *rl, unsigned static_size, int flags); +void ff_mpeg1_init_uni_ac_vlc(const RLTable *rl, uint8_t *uni_ac_vlc_len); static inline int decode_dc(GetBitContext *gb, int component) { @@ -47,10 +46,6 @@ static inline int decode_dc(GetBitContext *gb, int component) } else { code = get_vlc2(gb, ff_dc_chroma_vlc.table, DC_VLC_BITS, 2); } - if (code < 0){ - av_log(NULL, AV_LOG_ERROR, "invalid dc code at\n"); - return 0xffff; - } if (code == 0) { diff = 0; } else { diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 99e56532a..94221da2c 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -31,7 +31,9 @@ #include "libavutil/attributes.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/stereo3d.h" +#include "libavutil/video_enc_params.h" #include "avcodec.h" #include "bytestream.h" @@ -50,6 +52,8 @@ #include "version.h" #include "xvmc_internal.h" +#define A53_MAX_CC_COUNT 2000 + typedef struct Mpeg1Context { MpegEncContext mpeg_enc_ctx; int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ @@ -57,8 +61,7 @@ typedef struct Mpeg1Context { AVPanScan pan_scan; /* some temporary storage for the panscan */ AVStereo3D stereo3d; int has_stereo3d; - uint8_t *a53_caption; - int a53_caption_size; + AVBufferRef *a53_buf_ref; uint8_t afd; int has_afd; int slice_count; @@ -491,8 +494,6 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, component = (n & 1) + 1; } diff = decode_dc(&s->gb, component); - if (diff >= 0xffff) - return AVERROR_INVALIDDATA; dc = s->last_dc[component]; dc += diff; s->last_dc[component] = dc; @@ -527,10 +528,9 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, } else { /* escape */ run = SHOW_UBITS(re, &s->gb, 6) + 1; - LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); + SKIP_BITS(re, &s->gb, 6); level = SHOW_SBITS(re, &s->gb, 12); - SKIP_BITS(re, &s->gb, 12); + LAST_SKIP_BITS(re, &s->gb, 12); i += run; if (i > MAX_INDEX) break; @@ -579,8 +579,6 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, component = (n & 1) + 1; } diff = decode_dc(&s->gb, component); - if (diff >= 0xffff) - return AVERROR_INVALIDDATA; dc = s->last_dc[component]; dc += diff; s->last_dc[component] = dc; @@ -611,10 +609,9 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, } else { /* escape */ run = SHOW_UBITS(re, &s->gb, 6) + 1; - LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); + SKIP_BITS(re, &s->gb, 6); level = SHOW_SBITS(re, &s->gb, 12); - SKIP_BITS(re, &s->gb, 12); + LAST_SKIP_BITS(re, &s->gb, 12); i += run; j = scantable[i]; if (level < 0) { @@ -1055,15 +1052,11 @@ static av_cold int mpeg_decode_init(AVCodecContext *avctx) Mpeg1Context *s = avctx->priv_data; MpegEncContext *s2 = &s->mpeg_enc_ctx; - ff_mpv_decode_defaults(s2); - if ( avctx->codec_tag != AV_RL32("VCR2") && avctx->codec_tag != AV_RL32("BW10")) avctx->coded_width = avctx->coded_height = 0; // do not trust dimensions from input ff_mpv_decode_init(s2, avctx); - s->mpeg_enc_ctx.avctx = avctx; - /* we need some permutation to store matrices, * until the decoder sets the real permutation. */ ff_mpv_idct_init(s2); @@ -1635,13 +1628,13 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) return AVERROR(ENOMEM); memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan)); - if (s1->a53_caption) { - AVFrameSideData *sd = av_frame_new_side_data( + if (s1->a53_buf_ref) { + AVFrameSideData *sd = av_frame_new_side_data_from_buf( s->current_picture_ptr->f, AV_FRAME_DATA_A53_CC, - s1->a53_caption_size); - if (sd) - memcpy(sd->data, s1->a53_caption, s1->a53_caption_size); - av_freep(&s1->a53_caption); + s1->a53_buf_ref); + if (!sd) + av_buffer_unref(&s1->a53_buf_ref); + s1->a53_buf_ref = NULL; } if (s1->has_stereo3d) { @@ -2242,14 +2235,18 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, /* extract A53 Part 4 CC data */ int cc_count = p[5] & 0x1f; if (cc_count > 0 && buf_size >= 7 + cc_count * 3) { - av_freep(&s1->a53_caption); - s1->a53_caption_size = cc_count * 3; - s1->a53_caption = av_malloc(s1->a53_caption_size); - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } else { - memcpy(s1->a53_caption, p + 7, s1->a53_caption_size); - } + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count + * UINT64_C(3)); + int ret; + + if (new_size > 3*A53_MAX_CC_COUNT) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); + if (ret >= 0) + memcpy(s1->a53_buf_ref->data + old_size, p + 7, cc_count * UINT64_C(3)); + avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } return 1; @@ -2258,19 +2255,23 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, /* extract SCTE-20 CC data */ GetBitContext gb; int cc_count = 0; - int i; + int i, ret; init_get_bits(&gb, p + 2, buf_size - 2); cc_count = get_bits(&gb, 5); if (cc_count > 0) { - av_freep(&s1->a53_caption); - s1->a53_caption_size = cc_count * 3; - s1->a53_caption = av_mallocz(s1->a53_caption_size); - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } else { + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count + * UINT64_C(3)); + if (new_size > 3*A53_MAX_CC_COUNT) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); + if (ret >= 0) { uint8_t field, cc1, cc2; - uint8_t *cap = s1->a53_caption; + uint8_t *cap = s1->a53_buf_ref->data; + + memset(s1->a53_buf_ref->data + old_size, 0, cc_count * 3); for (i = 0; i < cc_count && get_bits_left(&gb) >= 26; i++) { skip_bits(&gb, 2); // priority field = get_bits(&gb, 2); @@ -2322,21 +2323,23 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, * on the even field. There also exist DVDs in the wild that encode an odd field count and the * caption_extra_field_added/caption_odd_field_first bits change per packet to allow that. */ int cc_count = 0; - int i; + int i, ret; // There is a caption count field in the data, but it is often // incorrect. So count the number of captions present. for (i = 5; i + 6 <= buf_size && ((p[i] & 0xfe) == 0xfe); i += 6) cc_count++; // Transform the DVD format into A53 Part 4 format if (cc_count > 0) { - av_freep(&s1->a53_caption); - s1->a53_caption_size = cc_count * 6; - s1->a53_caption = av_malloc(s1->a53_caption_size); - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } else { + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count + * UINT64_C(6)); + if (new_size > 3*A53_MAX_CC_COUNT) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); + if (ret >= 0) { uint8_t field1 = !!(p[4] & 0x80); - uint8_t *cap = s1->a53_caption; + uint8_t *cap = s1->a53_buf_ref->data; p += 5; for (i = 0; i < cc_count; i++) { cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd; @@ -2846,6 +2849,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, void *data, s2->current_picture_ptr = NULL; if (s2->timecode_frame_start != -1 && *got_output) { + char tcbuf[AV_TIMECODE_STR_SIZE]; AVFrameSideData *tcside = av_frame_new_side_data(picture, AV_FRAME_DATA_GOP_TIMECODE, sizeof(int64_t)); @@ -2853,6 +2857,9 @@ static int mpeg_decode_frame(AVCodecContext *avctx, void *data, return AVERROR(ENOMEM); memcpy(tcside->data, &s2->timecode_frame_start, sizeof(int64_t)); + av_timecode_make_mpeg_tc_string(tcbuf, s2->timecode_frame_start); + av_dict_set(&picture->metadata, "timecode", tcbuf, 0); + s2->timecode_frame_start = -1; } } @@ -2875,7 +2882,7 @@ static av_cold int mpeg_decode_end(AVCodecContext *avctx) if (s->mpeg_enc_ctx_allocated) ff_mpv_common_end(&s->mpeg_enc_ctx); - av_freep(&s->a53_caption); + av_buffer_unref(&s->a53_buf_ref); return 0; } @@ -2891,11 +2898,12 @@ AVCodec ff_mpeg1video_decoder = { .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = flush, .max_lowres = 3, .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context), - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_MPEG1_NVDEC_HWACCEL HWACCEL_NVDEC(mpeg1), #endif @@ -2924,11 +2932,12 @@ AVCodec ff_mpeg2video_decoder = { .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = flush, .max_lowres = 3, .profiles = NULL_IF_CONFIG_SMALL(ff_mpeg2_video_profiles), - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_MPEG2_DXVA2_HWACCEL HWACCEL_DXVA2(mpeg2), #endif @@ -2968,7 +2977,167 @@ AVCodec ff_mpegvideo_decoder = { .close = mpeg_decode_end, .decode = mpeg_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = flush, .max_lowres = 3, }; + +typedef struct IPUContext { + MpegEncContext m; + + int flags; + DECLARE_ALIGNED(32, int16_t, block)[6][64]; +} IPUContext; + +static int ipu_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + IPUContext *s = avctx->priv_data; + MpegEncContext *m = &s->m; + GetBitContext *gb = &m->gb; + AVFrame * const frame = data; + int ret; + + ret = ff_get_buffer(avctx, frame, 0); + if (ret < 0) + return ret; + + ret = init_get_bits8(gb, avpkt->data, avpkt->size); + if (ret < 0) + return ret; + + s->flags = get_bits(gb, 8); + m->intra_dc_precision = s->flags & 3; + m->q_scale_type = !!(s->flags & 0x40); + m->intra_vlc_format = !!(s->flags & 0x20); + m->alternate_scan = !!(s->flags & 0x10); + + if (s->flags & 0x10) { + ff_init_scantable(m->idsp.idct_permutation, &m->inter_scantable, ff_alternate_vertical_scan); + ff_init_scantable(m->idsp.idct_permutation, &m->intra_scantable, ff_alternate_vertical_scan); + } else { + ff_init_scantable(m->idsp.idct_permutation, &m->inter_scantable, ff_zigzag_direct); + ff_init_scantable(m->idsp.idct_permutation, &m->intra_scantable, ff_zigzag_direct); + } + + m->last_dc[0] = m->last_dc[1] = m->last_dc[2] = 1 << (7 + (s->flags & 3)); + m->qscale = 1; + + for (int y = 0; y < avctx->height; y += 16) { + int intraquant; + + for (int x = 0; x < avctx->width; x += 16) { + if (x || y) { + if (!get_bits1(gb)) + return AVERROR_INVALIDDATA; + } + if (get_bits1(gb)) { + intraquant = 0; + } else { + if (!get_bits1(gb)) + return AVERROR_INVALIDDATA; + intraquant = 1; + } + + if (s->flags & 4) + skip_bits1(gb); + + if (intraquant) + m->qscale = mpeg_get_qscale(m); + + memset(s->block, 0, sizeof(s->block)); + + for (int n = 0; n < 6; n++) { + if (s->flags & 0x80) { + ret = ff_mpeg1_decode_block_intra(&m->gb, + m->intra_matrix, + m->intra_scantable.permutated, + m->last_dc, s->block[n], + n, m->qscale); + if (ret >= 0) + m->block_last_index[n] = ret; + } else { + ret = mpeg2_decode_block_intra(m, s->block[n], n); + } + + if (ret < 0) + return ret; + } + + m->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x, + frame->linesize[0], s->block[0]); + m->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8, + frame->linesize[0], s->block[1]); + m->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x, + frame->linesize[0], s->block[2]); + m->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8, + frame->linesize[0], s->block[3]); + m->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1), + frame->linesize[1], s->block[4]); + m->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1), + frame->linesize[2], s->block[5]); + } + } + + align_get_bits(gb); + if (get_bits_left(gb) != 32) + return AVERROR_INVALIDDATA; + + frame->pict_type = AV_PICTURE_TYPE_I; + frame->key_frame = 1; + *got_frame = 1; + + return avpkt->size; +} + +static av_cold int ipu_decode_init(AVCodecContext *avctx) +{ + IPUContext *s = avctx->priv_data; + MpegEncContext *m = &s->m; + + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + + ff_mpv_decode_init(m, avctx); + ff_mpv_idct_init(m); + ff_mpeg12_common_init(m); + ff_mpeg12_init_vlcs(); + + for (int i = 0; i < 64; i++) { + int j = m->idsp.idct_permutation[i]; + int v = ff_mpeg1_default_intra_matrix[i]; + m->intra_matrix[j] = v; + m->chroma_intra_matrix[j] = v; + } + + for (int i = 0; i < 64; i++) { + int j = m->idsp.idct_permutation[i]; + int v = ff_mpeg1_default_non_intra_matrix[i]; + m->inter_matrix[j] = v; + m->chroma_inter_matrix[j] = v; + } + + return 0; +} + +static av_cold int ipu_decode_end(AVCodecContext *avctx) +{ + IPUContext *s = avctx->priv_data; + + ff_mpv_common_end(&s->m); + + return 0; +} + +AVCodec ff_ipu_decoder = { + .name = "ipu", + .long_name = NULL_IF_CONFIG_SMALL("IPU Video"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_IPU, + .priv_data_size = sizeof(IPUContext), + .init = ipu_decode_init, + .decode = ipu_decode_frame, + .close = ipu_decode_end, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, +}; diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index 9fbbcef60..a05c2db6c 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -27,10 +27,12 @@ #include +#include "config.h" #include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/log.h" #include "libavutil/opt.h" +#include "libavutil/thread.h" #include "libavutil/timecode.h" #include "libavutil/stereo3d.h" @@ -43,6 +45,7 @@ #include "mpegvideo.h" #include "profiles.h" +#if CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER static const uint8_t svcd_scan_offset_placeholder[] = { 0x10, 0x0E, 0x00, 0x80, 0x81, 0x00, 0x80, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -59,12 +62,10 @@ static uint8_t uni_mpeg2_ac_vlc_len[64 * 64 * 2]; 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]; - #define A53_MAX_CC_COUNT 0x1f +#endif /* CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER */ -static av_cold void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len) +av_cold void ff_mpeg1_init_uni_ac_vlc(const RLTable *rl, uint8_t *uni_ac_vlc_len) { int i; @@ -99,6 +100,7 @@ static av_cold void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len) } } +#if CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER static int find_frame_rate_index(MpegEncContext *s) { int i; @@ -233,7 +235,7 @@ FF_ENABLE_DEPRECATION_WARNINGS static void put_header(MpegEncContext *s, int header) { - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); put_bits(&s->pb, 16, header >> 16); put_sbits(&s->pb, 16, header); } @@ -717,8 +719,8 @@ next_coef: MASK_ABS(sign, alevel); sign &= 1; - if (alevel <= mpeg1_max_level[0][run]) { - code = mpeg1_index_run[0][run] + alevel - 1; + if (alevel <= ff_rl_mpeg1.max_level[0][run]) { + code = ff_rl_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); @@ -1034,84 +1036,77 @@ void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64], mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8); } +static av_cold void mpeg12_encode_init_static(void) +{ + static uint8_t mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; + + ff_rl_init(&ff_rl_mpeg1, mpeg12_static_rl_table_store[0]); + ff_rl_init(&ff_rl_mpeg2, mpeg12_static_rl_table_store[1]); + + ff_mpeg1_init_uni_ac_vlc(&ff_rl_mpeg1, uni_mpeg1_ac_vlc_len); + ff_mpeg1_init_uni_ac_vlc(&ff_rl_mpeg2, uni_mpeg2_ac_vlc_len); + + /* build unified dc encoding tables */ + for (int 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] << index) + + av_mod_uintp2(diff, index); + mpeg1_lum_dc_uni[i + 255] = bits + (code << 8); + + bits = ff_mpeg12_vlc_dc_chroma_bits[index] + index; + code = (ff_mpeg12_vlc_dc_chroma_code[index] << index) + + av_mod_uintp2(diff, index); + mpeg1_chr_dc_uni[i + 255] = bits + (code << 8); + } + + for (int f_code = 1; f_code <= MAX_FCODE; f_code++) + for (int mv = -MAX_DMV; mv <= MAX_DMV; mv++) { + int len; + + if (mv == 0) { + len = ff_mpeg12_mbMotionVectorTable[0][1]; + } else { + int val, bit_size, code; + + bit_size = f_code - 1; + + val = mv; + if (val < 0) + val = -val; + val--; + code = (val >> 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; + } + + mv_penalty[f_code][mv + MAX_DMV] = len; + } + + + for (int f_code = MAX_FCODE; f_code > 0; f_code--) + for (int mv = -(8 << f_code); mv < (8 << f_code); mv++) + fcode_tab[mv + MAX_MV] = f_code; +} + av_cold void ff_mpeg1_encode_init(MpegEncContext *s) { - static int done = 0; + static AVOnce init_static_once = AV_ONCE_INIT; ff_mpeg12_common_init(s); - if (!done) { - int f_code; - int mv; - int i; - - done = 1; - ff_rl_init(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); - ff_rl_init(&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]; - } - - init_uni_ac_vlc(&ff_rl_mpeg1, uni_mpeg1_ac_vlc_len); - 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] << index) + - av_mod_uintp2(diff, index); - mpeg1_lum_dc_uni[i + 255] = bits + (code << 8); - - bits = ff_mpeg12_vlc_dc_chroma_bits[index] + index; - code = (ff_mpeg12_vlc_dc_chroma_code[index] << index) + - av_mod_uintp2(diff, index); - mpeg1_chr_dc_uni[i + 255] = bits + (code << 8); - } - - for (f_code = 1; f_code <= MAX_FCODE; f_code++) - for (mv = -MAX_DMV; mv <= MAX_DMV; mv++) { - int len; - - if (mv == 0) { - len = ff_mpeg12_mbMotionVectorTable[0][1]; - } else { - int val, bit_size, code; - - bit_size = f_code - 1; - - val = mv; - if (val < 0) - val = -val; - val--; - code = (val >> 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; - } - - mv_penalty[f_code][mv + MAX_DMV] = len; - } - - - 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; - } s->me.mv_penalty = mv_penalty; s->fcode_tab = fcode_tab; if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) { @@ -1130,6 +1125,8 @@ av_cold void ff_mpeg1_encode_init(MpegEncContext *s) } s->inter_ac_vlc_length = s->inter_ac_vlc_last_length = uni_mpeg1_ac_vlc_len; + + ff_thread_once(&init_static_once, mpeg12_encode_init_static); } #define OFFSET(x) offsetof(MpegEncContext, x) @@ -1137,8 +1134,6 @@ av_cold void ff_mpeg1_encode_init(MpegEncContext *s) #define COMMON_OPTS \ { "gop_timecode", "MPEG GOP Timecode in hh:mm:ss[:;.]ff format. Overrides timecode_frame_start.", \ OFFSET(tc_opt_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE },\ - { "intra_vlc", "Use MPEG-2 intra VLC table.", \ - OFFSET(intra_vlc_format), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \ { "drop_frame_timecode", "Timecode is in drop frame format.", \ OFFSET(drop_frame_timecode), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \ { "scan_offset", "Reserve space for SVCD scan offset user data.", \ @@ -1154,6 +1149,8 @@ static const AVOption mpeg1_options[] = { static const AVOption mpeg2_options[] = { COMMON_OPTS + { "intra_vlc", "Use MPEG-2 intra VLC table.", + OFFSET(intra_vlc_format), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "non_linear_quant", "Use nonlinear quantizer.", OFFSET(q_scale_type), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "seq_disp_ext", "Write sequence_display_extension blocks.", OFFSET(seq_disp_ext), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE, "seq_disp_ext" }, @@ -1167,6 +1164,12 @@ static const AVOption mpeg2_options[] = { { "secam", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_FORMAT_SECAM }, 0, 0, VE, "video_format" }, { "mac", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_FORMAT_MAC }, 0, 0, VE, "video_format" }, { "unspecified", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_FORMAT_UNSPECIFIED}, 0, 0, VE, "video_format" }, +#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, { .i64 = value }, 0, 0, VE, "avctx.level" + { LEVEL("high", 4) }, + { LEVEL("high1440", 6) }, + { LEVEL("main", 8) }, + { LEVEL("low", 10) }, +#undef LEVEL FF_MPV_COMMON_OPTS FF_MPEG2_PROFILE_OPTS { NULL }, @@ -1196,7 +1199,7 @@ AVCodec ff_mpeg1video_encoder = { .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .priv_class = &mpeg1_class, }; @@ -1214,6 +1217,7 @@ AVCodec ff_mpeg2video_encoder = { AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE }, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .priv_class = &mpeg2_class, }; +#endif /* CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER */ diff --git a/libavcodec/mpeg12vlc.h b/libavcodec/mpeg12vlc.h index c5abae96b..70aca645c 100644 --- a/libavcodec/mpeg12vlc.h +++ b/libavcodec/mpeg12vlc.h @@ -31,7 +31,7 @@ #include "vlc.h" #define DC_VLC_BITS 9 -#define MV_VLC_BITS 9 +#define MV_VLC_BITS 8 #define TEX_VLC_BITS 9 #define MBINCR_VLC_BITS 9 diff --git a/libavcodec/mpeg2_metadata_bsf.c b/libavcodec/mpeg2_metadata_bsf.c index b1e2d6128..11b46c0ae 100644 --- a/libavcodec/mpeg2_metadata_bsf.c +++ b/libavcodec/mpeg2_metadata_bsf.c @@ -21,16 +21,13 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_mpeg2.h" #include "mpeg12.h" typedef struct MPEG2MetadataContext { - const AVClass *class; - - CodedBitstreamContext *cbc; - CodedBitstreamFragment fragment; + CBSBSFContext common; MPEG2RawExtensionData sequence_display_extension; @@ -48,6 +45,7 @@ typedef struct MPEG2MetadataContext { static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, + AVPacket *pkt, CodedBitstreamFragment *frag) { MPEG2MetadataContext *ctx = bsf->priv_data; @@ -137,7 +135,7 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, se->vertical_size_extension << 12 | sh->vertical_size_value, }; - err = ff_cbs_insert_unit_content(ctx->cbc, frag, se_pos + 1, + err = ff_cbs_insert_unit_content(frag, se_pos + 1, MPEG2_START_EXTENSION, &ctx->sequence_display_extension, NULL); @@ -170,49 +168,16 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, return 0; } -static int mpeg2_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) -{ - MPEG2MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->fragment; - int err; - - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = ff_cbs_read_packet(ctx->cbc, frag, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } - - err = mpeg2_metadata_update_fragment(bsf, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to update frame fragment.\n"); - goto fail; - } - - err = ff_cbs_write_packet(ctx->cbc, pkt, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; - } - - err = 0; -fail: - ff_cbs_fragment_reset(ctx->cbc, frag); - - if (err < 0) - av_packet_unref(pkt); - - return err; -} +static const CBSBSFType mpeg2_metadata_type = { + .codec_id = AV_CODEC_ID_MPEG2VIDEO, + .fragment_name = "frame", + .unit_name = "start code", + .update_fragment = &mpeg2_metadata_update_fragment, +}; static int mpeg2_metadata_init(AVBSFContext *bsf) { MPEG2MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->fragment; - int err; #define VALIDITY_CHECK(name) do { \ if (!ctx->name) { \ @@ -226,42 +191,7 @@ static int mpeg2_metadata_init(AVBSFContext *bsf) VALIDITY_CHECK(matrix_coefficients); #undef VALIDITY_CHECK - err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_MPEG2VIDEO, bsf); - if (err < 0) - return err; - - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - err = mpeg2_metadata_update_fragment(bsf, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to update metadata fragment.\n"); - goto fail; - } - - err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; - } - } - - err = 0; -fail: - ff_cbs_fragment_reset(ctx->cbc, frag); - return err; -} - -static void mpeg2_metadata_close(AVBSFContext *bsf) -{ - MPEG2MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(ctx->cbc, &ctx->fragment); - ff_cbs_close(&ctx->cbc); + return ff_cbs_bsf_generic_init(bsf, &mpeg2_metadata_type); } #define OFFSET(x) offsetof(MPEG2MetadataContext, x) @@ -307,7 +237,7 @@ const AVBitStreamFilter ff_mpeg2_metadata_bsf = { .priv_data_size = sizeof(MPEG2MetadataContext), .priv_class = &mpeg2_metadata_class, .init = &mpeg2_metadata_init, - .close = &mpeg2_metadata_close, - .filter = &mpeg2_metadata_filter, + .close = &ff_cbs_bsf_generic_close, + .filter = &ff_cbs_bsf_generic_filter, .codec_ids = mpeg2_metadata_codec_ids, }; diff --git a/libavcodec/mpeg4audio.c b/libavcodec/mpeg4audio.c index 0d83fb8d2..2286303b5 100644 --- a/libavcodec/mpeg4audio.c +++ b/libavcodec/mpeg4audio.c @@ -30,7 +30,7 @@ * @param[in] c MPEG4AudioConfig structure to fill * @return on success 0 is returned, otherwise a value < 0 */ -static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c) +static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c, void *logctx) { if (get_bits_left(gb) < 112) return AVERROR_INVALIDDATA; @@ -43,7 +43,7 @@ static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c) c->sample_rate = get_bits_long(gb, 32); if (c->sample_rate <= 0) { - av_log(NULL, AV_LOG_ERROR, "Invalid sample rate %d\n", c->sample_rate); + av_log(logctx, AV_LOG_ERROR, "Invalid sample rate %d\n", c->sample_rate); return AVERROR_INVALIDDATA; } @@ -64,8 +64,21 @@ const int avpriv_mpeg4audio_sample_rates[16] = { 24000, 22050, 16000, 12000, 11025, 8000, 7350 }; -const uint8_t ff_mpeg4audio_channels[8] = { - 0, 1, 2, 3, 4, 5, 6, 8 +const uint8_t ff_mpeg4audio_channels[14] = { + 0, + 1, // mono (1/0) + 2, // stereo (2/0) + 3, // 3/0 + 4, // 3/1 + 5, // 3/2 + 6, // 3/2.1 + 8, // 5/2.1 + 0, + 0, + 0, + 7, // 3/3.1 + 8, // 3/2/2.1 + 24 // 3/3/3 - 5/2/3 - 3/0/0.2 }; static inline int get_object_type(GetBitContext *gb) @@ -123,7 +136,7 @@ int ff_mpeg4audio_get_config_gb(MPEG4AudioConfig *c, GetBitContext *gb, specific_config_bitindex = get_bits_count(gb); - ret = parse_config_ALS(gb, c); + ret = parse_config_ALS(gb, c, logctx); if (ret < 0) return ret; } diff --git a/libavcodec/mpeg4audio.h b/libavcodec/mpeg4audio.h index 4b390e0f4..b274e92b6 100644 --- a/libavcodec/mpeg4audio.h +++ b/libavcodec/mpeg4audio.h @@ -46,7 +46,7 @@ typedef struct MPEG4AudioConfig { } MPEG4AudioConfig; extern av_export_avcodec const int avpriv_mpeg4audio_sample_rates[16]; -extern const uint8_t ff_mpeg4audio_channels[8]; +extern const uint8_t ff_mpeg4audio_channels[14]; /** * Parse MPEG-4 systems extradata from a potentially unaligned GetBitContext to retrieve audio configuration. @@ -165,7 +165,7 @@ static inline int ff_copy_pce_data(PutBitContext *pb, GetBitContext *gb) ff_pce_copy_bits(pb, gb, 16); if (bits) ff_pce_copy_bits(pb, gb, bits); - avpriv_align_put_bits(pb); + align_put_bits(pb); align_get_bits(gb); comment_size = ff_pce_copy_bits(pb, gb, 8); for (; comment_size > 0; comment_size--) diff --git a/libavcodec/mpeg4data.h b/libavcodec/mpeg4data.h index 4756e9ea1..30179d980 100644 --- a/libavcodec/mpeg4data.h +++ b/libavcodec/mpeg4data.h @@ -323,10 +323,8 @@ RLTable ff_rvlc_rl_intra = { intra_rvlc_level, }; -const uint16_t ff_sprite_trajectory_tab[15][2] = { - {0x00, 2}, {0x02, 3}, {0x03, 3}, {0x04, 3}, {0x05, 3}, {0x06, 3}, - {0x0E, 4}, {0x1E, 5}, {0x3E, 6}, {0x7E, 7}, {0xFE, 8}, - {0x1FE, 9},{0x3FE, 10},{0x7FE, 11},{0xFFE, 12}, +const uint8_t ff_sprite_trajectory_lens[15] = { + 2, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, }; const uint8_t ff_mb_type_b_tab[4][2] = { @@ -374,119 +372,91 @@ const uint8_t ff_mpeg4_dc_threshold[8]={ }; /* Note these are different in studio mode */ -const uint16_t ff_mpeg4_studio_dc_luma[19][2]={ - {0x0e, 6}, {0x06, 5}, {0x00, 4}, {0x02, 4}, - {0x07, 3}, {0x05, 3}, {0x03, 3}, {0x02, 3}, - {0x04, 3}, {0x06, 3}, {0x01, 4}, {0x1e, 7}, - {0x3e, 8}, {0x7e, 9}, {0xfe, 10}, {0x1fe, 11}, - {0x3fe, 12}, {0x7fe, 13}, {0x7ff, 13} +const uint8_t ff_mpeg4_studio_dc_luma[19][2] = { + { 2, 4 }, { 10, 4 }, { 3, 4 }, { 1, 5 }, { 0, 6 }, { 11, 7 }, + { 12, 8 }, { 13, 9 }, { 14, 10 }, { 15, 11 }, { 16, 12 }, { 17, 13 }, + { 18, 13 }, { 7, 3 }, { 6, 3 }, { 8, 3 }, { 5, 3 }, { 9, 3 }, + { 4, 3 }, }; -const uint16_t ff_mpeg4_studio_dc_chroma[19][2]={ - {0x00, 4}, {0x02, 4}, {0x07, 3}, {0x05, 3}, - {0x03, 3}, {0x02, 3}, {0x04, 3}, {0x06, 3}, - {0x01, 4}, {0x06, 5}, {0x0e, 6}, {0x1e, 7}, - {0x3e, 8}, {0x7e, 9}, {0xfe, 10}, {0x1fe, 11}, - {0x3fe, 12}, {0x7fe, 13}, {0x7ff, 13} +const uint8_t ff_mpeg4_studio_dc_chroma[19][2] = { + { 0, 4 }, { 8, 4 }, { 1, 4 }, { 9, 5 }, { 10, 6 }, { 11, 7 }, + { 12, 8 }, { 13, 9 }, { 14, 10 }, { 15, 11 }, { 16, 12 }, { 17, 13 }, + { 18, 13 }, { 5, 3 }, { 4, 3 }, { 6, 3 }, { 3, 3 }, { 7, 3 }, + { 2, 3 }, }; -const uint16_t ff_mpeg4_studio_intra[12][22][2]={ +const uint8_t ff_mpeg4_studio_intra[12][24][2] = { { - {0x05, 4}, {0x04, 4}, {0x05, 7}, {0x09, 9}, - {0x21, 11}, {0x41, 12}, {0x81, 13}, {0x03, 4}, - {0x03, 5}, {0x05, 6}, {0x04, 7}, {0x03, 7}, - {0x05, 8}, {0x03, 2}, {0x05, 3}, {0x04, 3}, - {0x03, 3}, {0x02, 4}, {0x04, 6}, {0x03, 6}, - {0x11, 10}, {0x80, 13} + { 0, -6 }, { 21, 13 }, { 6, 13 }, { 5, 12 }, { 4, 11 }, { 20, 10 }, + { 3, 9 }, { 12, 8 }, { 11, 7 }, { 10, 7 }, { 2, 7 }, { 19, 6 }, + { 18, 6 }, { 9, 6 }, { 8, 5 }, { 17, 4 }, { 7, 4 }, { 1, 4 }, + { 0, 4 }, { 16, 3 }, { 15, 3 }, { 14, 3 }, { 13, 2 }, }, { - {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, - {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, - {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, - {0x00, 0}, {0x00, 0}, {0x01, 1}, {0x01, 2}, - {0x01, 3}, {0x01, 4}, {0x01, 5}, {0x03, 7}, - {0x05, 8}, {0x04, 8} + { 0, -6 }, { 21, 8 }, { 20, 8 }, { 19, 7 }, { 18, 5 }, { 17, 4 }, + { 16, 3 }, { 15, 2 }, { 14, 1 }, }, { - {0x05, 3}, {0x03, 5}, {0x02, 5}, {0x03, 7}, - {0x09, 9}, {0x103, 14}, {0x102, 14}, {0x04, 3}, - {0x03, 3}, {0x03, 4}, {0x02, 4}, {0x03, 6}, - {0x11, 10}, {0x03, 2}, {0x02, 3}, {0x02, 6}, - {0x05, 8}, {0x21, 11}, {0x83, 13}, {0x101, 14}, - {0x201, 15}, {0x82, 13} + { 0, -6 }, { 0,-15 }, { 20, 15 }, { 19, 14 }, { 6, 14 }, { 5, 14 }, + { 21, 13 }, { 18, 13 }, { 17, 11 }, { 12, 10 }, { 4, 9 }, { 16, 8 }, + { 3, 7 }, { 15, 6 }, { 11, 6 }, { 2, 5 }, { 1, 5 }, { 10, 4 }, + { 9, 4 }, { 14, 3 }, { 8, 3 }, { 7, 3 }, { 0, 3 }, { 13, 2 }, }, { - {0x05, 5}, {0x05, 4}, {0x04, 5}, {0x03, 6}, - {0x09, 9}, {0x83, 13}, {0x82, 13}, {0x03, 3}, - {0x04, 4}, {0x03, 4}, {0x03, 5}, {0x05, 8}, - {0x81, 13}, {0x03, 2}, {0x02, 2}, {0x02, 5}, - {0x02, 6}, {0x03, 7}, {0x11, 10}, {0x43, 12}, - {0x80, 13}, {0x42, 12} + { 0, -6 }, { 20, 13 }, { 12, 13 }, { 6, 13 }, { 5, 13 }, { 21, 12 }, + { 19, 12 }, { 18, 10 }, { 4, 9 }, { 11, 8 }, { 17, 7 }, { 16, 6 }, + { 3, 6 }, { 15, 5 }, { 10, 5 }, { 2, 5 }, { 0, 5 }, { 9, 4 }, + { 8, 4 }, { 1, 4 }, { 7, 3 }, { 14, 2 }, { 13, 2 }, }, { - {0x05, 7}, {0x03, 4}, {0x03, 5}, {0x04, 7}, - {0x09, 9}, {0x83, 13}, {0x101, 14}, {0x03, 3}, - {0x02, 4}, {0x05, 6}, {0x03, 7}, {0x11, 10}, - {0x201, 15}, {0x03, 2}, {0x02, 2}, {0x02, 3}, - {0x04, 6}, {0x03, 6}, {0x05, 8}, {0x21, 11}, - {0x82, 13}, {0x81, 13} + { 0, -6 }, { 0,-15 }, { 12, 15 }, { 6, 14 }, { 21, 13 }, { 20, 13 }, + { 5, 13 }, { 19, 11 }, { 11, 10 }, { 4, 9 }, { 18, 8 }, { 10, 7 }, + { 3, 7 }, { 0, 7 }, { 17, 6 }, { 16, 6 }, { 9, 6 }, { 2, 5 }, + { 8, 4 }, { 1, 4 }, { 15, 3 }, { 7, 3 }, { 14, 2 }, { 13, 2 }, }, { - {0x13, 10}, {0x03, 5}, {0x05, 7}, {0x12, 10}, - {0x43, 12}, {0x83, 13}, {0x82, 13}, {0x02, 5}, - {0x04, 7}, {0x05, 8}, {0x23, 11}, {0x81, 13}, - {0x101, 14}, {0x03, 2}, {0x02, 2}, {0x01, 2}, - {0x01, 3}, {0x03, 6}, {0x03, 7}, {0x22, 11}, - {0x201, 15}, {0x42, 12} + { 0, -6 }, { 0,-15 }, { 20, 15 }, { 12, 14 }, { 11, 13 }, { 6, 13 }, + { 5, 13 }, { 21, 12 }, { 4, 12 }, { 19, 11 }, { 10, 11 }, { 3, 10 }, + { 0, 10 }, { 9, 8 }, { 18, 7 }, { 8, 7 }, { 2, 7 }, { 17, 6 }, + { 7, 5 }, { 1, 5 }, { 16, 3 }, { 15, 2 }, { 14, 2 }, { 13, 2 }, }, { - {0x23, 11}, {0x01, 4}, {0x07, 8}, {0x13, 10}, - {0x22, 11}, {0x103, 14}, {0x102, 14}, {0x03, 6}, - {0x06, 8}, {0x12, 10}, {0x43, 12}, {0x101, 14}, - {0x201, 15}, {0x03, 3}, {0x02, 3}, {0x03, 2}, - {0x02, 2}, {0x01, 3}, {0x02, 6}, {0x05, 8}, - {0x42, 12}, {0x41, 12} + { 0, -6 }, { 0,-15 }, { 12, 15 }, { 11, 14 }, { 6, 14 }, { 5, 14 }, + { 21, 12 }, { 20, 12 }, { 10, 12 }, { 4, 11 }, { 0, 11 }, { 9, 10 }, + { 3, 10 }, { 19, 8 }, { 8, 8 }, { 2, 8 }, { 18, 6 }, { 7, 6 }, + { 1, 4 }, { 17, 3 }, { 14, 3 }, { 13, 3 }, { 16, 2 }, { 15, 2 }, }, { - {0x0b, 9}, {0x03, 5}, {0x07, 8}, {0x07, 7}, - {0x06, 7}, {0x23, 11}, {0x41, 12}, {0x05, 7}, - {0x06, 8}, {0x0a, 9}, {0x13, 10}, {0x22, 11}, - {0x40, 12}, {0x03, 4}, {0x02, 4}, {0x03, 2}, - {0x02, 2}, {0x01, 2}, {0x02, 5}, {0x04, 7}, - {0x12, 10}, {0x21, 11} + { 0, -6 }, { 12, 12 }, { 6, 12 }, { 21, 11 }, { 11, 11 }, { 5, 11 }, + { 20, 10 }, { 10, 10 }, { 9, 9 }, { 0, 9 }, { 8, 8 }, { 2, 8 }, + { 19, 7 }, { 7, 7 }, { 4, 7 }, { 3, 7 }, { 18, 5 }, { 1, 5 }, + { 14, 4 }, { 13, 4 }, { 17, 2 }, { 16, 2 }, { 15, 2 }, }, { - {0x15, 10}, {0x03, 6}, {0x14, 10}, {0x23, 11}, - {0x07, 8}, {0x43, 12}, {0x81, 13}, {0x06, 8}, - {0x0b, 9}, {0x13, 10}, {0x12, 10}, {0x42, 12}, - {0x80, 13}, {0x01, 4}, {0x03, 3}, {0x02, 3}, - {0x03, 2}, {0x02, 2}, {0x01, 3}, {0x02, 6}, - {0x22, 11}, {0x41, 12} + { 0, -6 }, { 12, 13 }, { 6, 13 }, { 21, 12 }, { 11, 12 }, { 5, 12 }, + { 20, 11 }, { 3, 11 }, { 10, 10 }, { 9, 10 }, { 2, 10 }, { 0, 10 }, + { 8, 9 }, { 7, 8 }, { 4, 8 }, { 19, 6 }, { 1, 6 }, { 13, 4 }, + { 18, 3 }, { 15, 3 }, { 14, 3 }, { 17, 2 }, { 16, 2 }, }, { - {0x43, 12}, {0x05, 6}, {0x07, 8}, {0x04, 6}, - {0x03, 6}, {0x13, 10}, {0x42, 12}, {0x05, 7}, - {0x04, 7}, {0x06, 8}, {0x12, 10}, {0x41, 12}, - {0x40, 12}, {0x03, 5}, {0x03, 4}, {0x03, 3}, - {0x02, 3}, {0x03, 2}, {0x02, 2}, {0x02, 4}, - {0x05, 8}, {0x11, 10} + { 0, -6 }, { 12, 12 }, { 11, 12 }, { 6, 12 }, { 0, 12 }, { 21, 10 }, + { 10, 10 }, { 5, 10 }, { 20, 8 }, { 9, 8 }, { 2, 8 }, { 8, 7 }, + { 7, 7 }, { 4, 6 }, { 3, 6 }, { 1, 6 }, { 13, 5 }, { 19, 4 }, + { 14, 4 }, { 16, 3 }, { 15, 3 }, { 18, 2 }, { 17, 2 }, }, { - {0x83, 13}, {0x05, 7}, {0x07, 8}, {0x03, 4}, - {0x21, 11}, {0x82, 13}, {0x81, 13}, {0x04, 7}, - {0x06, 8}, {0x0b, 9}, {0x0a, 9}, {0x11, 10}, - {0x80, 13}, {0x03, 5}, {0x02, 5}, {0x02, 4}, - {0x03, 3}, {0x02, 3}, {0x03, 2}, {0x02, 2}, - {0x03, 6}, {0x09, 9} + { 0, -6 }, { 12, 13 }, { 6, 13 }, { 5, 13 }, { 0, 13 }, { 4, 11 }, + { 11, 10 }, { 21, 9 }, { 10, 9 }, { 9, 9 }, { 8, 8 }, { 2, 8 }, + { 7, 7 }, { 1, 7 }, { 20, 6 }, { 14, 5 }, { 13, 5 }, { 15, 4 }, + { 3, 4 }, { 17, 3 }, { 16, 3 }, { 19, 2 }, { 18, 2 }, }, { - {0x13, 10}, {0x03, 5}, {0x03, 6}, {0x0d, 9}, - {0x0c, 9}, {0x21, 11}, {0x20, 11}, {0x02, 5}, - {0x02, 6}, {0x07, 8}, {0x0b, 9}, {0x12, 10}, - {0x11, 10}, {0x05, 3}, {0x04, 3}, {0x05, 4}, - {0x04, 4}, {0x03, 4}, {0x02, 4}, {0x03, 3}, - {0x03, 2}, {0x0a, 9} - } + { 0, -6 }, { 6, 11 }, { 5, 11 }, { 12, 10 }, { 11, 10 }, { 0, 10 }, + { 21, 9 }, { 10, 9 }, { 4, 9 }, { 3, 9 }, { 9, 8 }, { 8, 6 }, + { 2, 6 }, { 7, 5 }, { 1, 5 }, { 18, 4 }, { 17, 4 }, { 16, 4 }, + { 15, 4 }, { 19, 3 }, { 14, 3 }, { 13, 3 }, { 20, 2 }, + }, }; #endif /* AVCODEC_MPEG4DATA_H */ diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h index 1a5da3192..e919db87a 100644 --- a/libavcodec/mpeg4video.h +++ b/libavcodec/mpeg4video.h @@ -115,10 +115,6 @@ typedef struct Mpeg4DecContext { int cplx_estimation_trash_p; int cplx_estimation_trash_b; - VLC studio_intra_tab[12]; - VLC studio_luma_dc; - VLC studio_chroma_dc; - int rgb; } Mpeg4DecContext; @@ -138,7 +134,7 @@ extern RLTable ff_mpeg4_rl_intra; extern RLTable ff_rvlc_rl_inter; extern RLTable ff_rvlc_rl_intra; -extern const uint16_t ff_sprite_trajectory_tab[15][2]; +extern const uint8_t ff_sprite_trajectory_lens[15]; extern const uint8_t ff_mb_type_b_tab[4][2]; /* these matrixes will be permuted for the idct */ @@ -151,9 +147,9 @@ extern const uint16_t ff_mpeg4_resync_prefix[8]; extern const uint8_t ff_mpeg4_dc_threshold[8]; -extern const uint16_t ff_mpeg4_studio_dc_luma[19][2]; -extern const uint16_t ff_mpeg4_studio_dc_chroma[19][2]; -extern const uint16_t ff_mpeg4_studio_intra[12][22][2]; +extern const uint8_t ff_mpeg4_studio_dc_luma[19][2]; +extern const uint8_t ff_mpeg4_studio_dc_chroma[19][2]; +extern const uint8_t ff_mpeg4_studio_intra[12][24][2]; void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 610e365c3..2c440a502 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -25,6 +25,7 @@ #include "libavutil/internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" +#include "libavutil/thread.h" #include "error_resilience.h" #include "hwconfig.h" #include "idctdsp.h" @@ -48,11 +49,12 @@ #define MB_TYPE_B_VLC_BITS 4 #define STUDIO_INTRA_BITS 9 -static int decode_studio_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb); - static VLC dc_lum, dc_chrom; static VLC sprite_trajectory; static VLC mb_type_b_vlc; +static VLC studio_intra_tab[12]; +static VLC studio_luma_dc; +static VLC studio_chroma_dc; static const int mb_type_b_map[4] = { MB_TYPE_DIRECT2 | MB_TYPE_L0L1, @@ -195,22 +197,18 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g if (w <= 0 || h <= 0) return AVERROR_INVALIDDATA; - /* the decoder was not properly initialized and we cannot continue */ - if (sprite_trajectory.table == NULL) - return AVERROR_INVALIDDATA; - for (i = 0; i < ctx->num_sprite_warping_points; i++) { int length; int x = 0, y = 0; - length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); + length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 2); if (length > 0) x = get_xbits(gb, length); if (!(ctx->divx_version == 500 && ctx->divx_build == 413)) check_marker(s->avctx, gb, "before sprite_trajectory"); - length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); + length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 2); if (length > 0) y = get_xbits(gb, length); @@ -1820,7 +1818,7 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n int cc, dct_dc_size, dct_diff, code, j, idx = 1, group = 0, run = 0, additional_code_len, sign, mismatch; - VLC *cur_vlc = &ctx->studio_intra_tab[0]; + const VLC *cur_vlc = &studio_intra_tab[0]; uint8_t *const scantable = s->intra_scantable.permutated; const uint16_t *quant_matrix; uint32_t flc; @@ -1834,21 +1832,18 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n if (n < 4) { cc = 0; - dct_dc_size = get_vlc2(&s->gb, ctx->studio_luma_dc.table, STUDIO_INTRA_BITS, 2); + dct_dc_size = get_vlc2(&s->gb, studio_luma_dc.table, STUDIO_INTRA_BITS, 2); quant_matrix = s->intra_matrix; } else { cc = (n & 1) + 1; if (ctx->rgb) - dct_dc_size = get_vlc2(&s->gb, ctx->studio_luma_dc.table, STUDIO_INTRA_BITS, 2); + dct_dc_size = get_vlc2(&s->gb, studio_luma_dc.table, STUDIO_INTRA_BITS, 2); else - dct_dc_size = get_vlc2(&s->gb, ctx->studio_chroma_dc.table, STUDIO_INTRA_BITS, 2); + dct_dc_size = get_vlc2(&s->gb, studio_chroma_dc.table, STUDIO_INTRA_BITS, 2); quant_matrix = s->chroma_intra_matrix; } - if (dct_dc_size < 0) { - av_log(s->avctx, AV_LOG_ERROR, "illegal dct_dc_size vlc\n"); - return AVERROR_INVALIDDATA; - } else if (dct_dc_size == 0) { + if (dct_dc_size == 0) { dct_diff = 0; } else { dct_diff = get_xbits(&s->gb, dct_dc_size); @@ -1881,7 +1876,7 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n } additional_code_len = ac_state_tab[group][0]; - cur_vlc = &ctx->studio_intra_tab[ac_state_tab[group][1]]; + cur_vlc = &studio_intra_tab[ac_state_tab[group][1]]; if (group == 0) { /* End of Block */ @@ -2147,6 +2142,158 @@ static void mpeg4_load_default_matrices(MpegEncContext *s) } } +static int read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb) +{ + int i, j, v; + + if (get_bits1(gb)) { + if (get_bits_left(gb) < 64*8) + return AVERROR_INVALIDDATA; + /* intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + v = get_bits(gb, 8); + j = s->idsp.idct_permutation[ff_zigzag_direct[i]]; + s->intra_matrix[j] = v; + s->chroma_intra_matrix[j] = v; + } + } + + if (get_bits1(gb)) { + if (get_bits_left(gb) < 64*8) + return AVERROR_INVALIDDATA; + /* non_intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + get_bits(gb, 8); + } + } + + if (get_bits1(gb)) { + if (get_bits_left(gb) < 64*8) + return AVERROR_INVALIDDATA; + /* chroma_intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + v = get_bits(gb, 8); + j = s->idsp.idct_permutation[ff_zigzag_direct[i]]; + s->chroma_intra_matrix[j] = v; + } + } + + if (get_bits1(gb)) { + if (get_bits_left(gb) < 64*8) + return AVERROR_INVALIDDATA; + /* chroma_non_intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + get_bits(gb, 8); + } + } + + next_start_code_studio(gb); + return 0; +} + +static void extension_and_user_data(MpegEncContext *s, GetBitContext *gb, int id) +{ + uint32_t startcode; + uint8_t extension_type; + + startcode = show_bits_long(gb, 32); + if (startcode == USER_DATA_STARTCODE || startcode == EXT_STARTCODE) { + + if ((id == 2 || id == 4) && startcode == EXT_STARTCODE) { + skip_bits_long(gb, 32); + extension_type = get_bits(gb, 4); + if (extension_type == QUANT_MATRIX_EXT_ID) + read_quant_matrix_ext(s, gb); + } + } +} + +static int decode_studio_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) +{ + MpegEncContext *s = &ctx->m; + int width, height; + int bits_per_raw_sample; + int rgb, chroma_format; + + // random_accessible_vol and video_object_type_indication have already + // been read by the caller decode_vol_header() + skip_bits(gb, 4); /* video_object_layer_verid */ + ctx->shape = get_bits(gb, 2); /* video_object_layer_shape */ + skip_bits(gb, 4); /* video_object_layer_shape_extension */ + skip_bits1(gb); /* progressive_sequence */ + if (ctx->shape != RECT_SHAPE) { + avpriv_request_sample(s->avctx, "MPEG-4 Studio profile non rectangular shape"); + return AVERROR_PATCHWELCOME; + } + if (ctx->shape != BIN_ONLY_SHAPE) { + rgb = get_bits1(gb); /* rgb_components */ + chroma_format = get_bits(gb, 2); /* chroma_format */ + if (!chroma_format || chroma_format == CHROMA_420 || (rgb && chroma_format == CHROMA_422)) { + av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n"); + return AVERROR_INVALIDDATA; + } + + bits_per_raw_sample = get_bits(gb, 4); /* bit_depth */ + if (bits_per_raw_sample == 10) { + if (rgb) { + s->avctx->pix_fmt = AV_PIX_FMT_GBRP10; + } else { + s->avctx->pix_fmt = chroma_format == CHROMA_422 ? AV_PIX_FMT_YUV422P10 : AV_PIX_FMT_YUV444P10; + } + } else { + avpriv_request_sample(s->avctx, "MPEG-4 Studio profile bit-depth %u", bits_per_raw_sample); + return AVERROR_PATCHWELCOME; + } + if (rgb != ctx->rgb || s->chroma_format != chroma_format) + s->context_reinit = 1; + s->avctx->bits_per_raw_sample = bits_per_raw_sample; + ctx->rgb = rgb; + s->chroma_format = chroma_format; + } + if (ctx->shape == RECT_SHAPE) { + check_marker(s->avctx, gb, "before video_object_layer_width"); + width = get_bits(gb, 14); /* video_object_layer_width */ + check_marker(s->avctx, gb, "before video_object_layer_height"); + height = get_bits(gb, 14); /* video_object_layer_height */ + check_marker(s->avctx, gb, "after video_object_layer_height"); + + /* Do the same check as non-studio profile */ + if (width && height) { + if (s->width && s->height && + (s->width != width || s->height != height)) + s->context_reinit = 1; + s->width = width; + s->height = height; + } + } + 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]; + } + skip_bits(gb, 4); /* frame_rate_code */ + skip_bits(gb, 15); /* first_half_bit_rate */ + check_marker(s->avctx, gb, "after first_half_bit_rate"); + skip_bits(gb, 15); /* latter_half_bit_rate */ + check_marker(s->avctx, gb, "after latter_half_bit_rate"); + skip_bits(gb, 15); /* first_half_vbv_buffer_size */ + check_marker(s->avctx, gb, "after first_half_vbv_buffer_size"); + skip_bits(gb, 3); /* latter_half_vbv_buffer_size */ + skip_bits(gb, 11); /* first_half_vbv_buffer_size */ + check_marker(s->avctx, gb, "after first_half_vbv_buffer_size"); + skip_bits(gb, 15); /* latter_half_vbv_occupancy */ + check_marker(s->avctx, gb, "after latter_half_vbv_occupancy"); + s->low_delay = get_bits1(gb); + s->mpeg_quant = get_bits1(gb); /* mpeg2_stream */ + + next_start_code_studio(gb); + extension_and_user_data(s, gb, 2); + + return 0; +} + static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) { MpegEncContext *s = &ctx->m; @@ -2971,72 +3118,6 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) return 0; } -static int read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb) -{ - int i, j, v; - - if (get_bits1(gb)) { - if (get_bits_left(gb) < 64*8) - return AVERROR_INVALIDDATA; - /* intra_quantiser_matrix */ - for (i = 0; i < 64; i++) { - v = get_bits(gb, 8); - j = s->idsp.idct_permutation[ff_zigzag_direct[i]]; - s->intra_matrix[j] = v; - s->chroma_intra_matrix[j] = v; - } - } - - if (get_bits1(gb)) { - if (get_bits_left(gb) < 64*8) - return AVERROR_INVALIDDATA; - /* non_intra_quantiser_matrix */ - for (i = 0; i < 64; i++) { - get_bits(gb, 8); - } - } - - if (get_bits1(gb)) { - if (get_bits_left(gb) < 64*8) - return AVERROR_INVALIDDATA; - /* chroma_intra_quantiser_matrix */ - for (i = 0; i < 64; i++) { - v = get_bits(gb, 8); - j = s->idsp.idct_permutation[ff_zigzag_direct[i]]; - s->chroma_intra_matrix[j] = v; - } - } - - if (get_bits1(gb)) { - if (get_bits_left(gb) < 64*8) - return AVERROR_INVALIDDATA; - /* chroma_non_intra_quantiser_matrix */ - for (i = 0; i < 64; i++) { - get_bits(gb, 8); - } - } - - next_start_code_studio(gb); - return 0; -} - -static void extension_and_user_data(MpegEncContext *s, GetBitContext *gb, int id) -{ - uint32_t startcode; - uint8_t extension_type; - - startcode = show_bits_long(gb, 32); - if (startcode == USER_DATA_STARTCODE || startcode == EXT_STARTCODE) { - - if ((id == 2 || id == 4) && startcode == EXT_STARTCODE) { - skip_bits_long(gb, 32); - extension_type = get_bits(gb, 4); - if (extension_type == QUANT_MATRIX_EXT_ID) - read_quant_matrix_ext(s, gb); - } - } -} - static void decode_smpte_tc(Mpeg4DecContext *ctx, GetBitContext *gb) { MpegEncContext *s = &ctx->m; @@ -3116,103 +3197,15 @@ static int decode_studiovisualobject(Mpeg4DecContext *ctx, GetBitContext *gb) MpegEncContext *s = &ctx->m; int visual_object_type; - skip_bits(gb, 4); /* visual_object_verid */ - visual_object_type = get_bits(gb, 4); - if (visual_object_type != VOT_VIDEO_ID) { - avpriv_request_sample(s->avctx, "VO type %u", visual_object_type); - return AVERROR_PATCHWELCOME; - } + skip_bits(gb, 4); /* visual_object_verid */ + visual_object_type = get_bits(gb, 4); + if (visual_object_type != VOT_VIDEO_ID) { + avpriv_request_sample(s->avctx, "VO type %u", visual_object_type); + return AVERROR_PATCHWELCOME; + } - next_start_code_studio(gb); - extension_and_user_data(s, gb, 1); - - return 0; -} - -static int decode_studio_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) -{ - MpegEncContext *s = &ctx->m; - int width, height; - int bits_per_raw_sample; - int rgb, chroma_format; - - // random_accessible_vol and video_object_type_indication have already - // been read by the caller decode_vol_header() - skip_bits(gb, 4); /* video_object_layer_verid */ - ctx->shape = get_bits(gb, 2); /* video_object_layer_shape */ - skip_bits(gb, 4); /* video_object_layer_shape_extension */ - skip_bits1(gb); /* progressive_sequence */ - if (ctx->shape != RECT_SHAPE) { - avpriv_request_sample(s->avctx, "MPEG-4 Studio profile non rectangular shape"); - return AVERROR_PATCHWELCOME; - } - if (ctx->shape != BIN_ONLY_SHAPE) { - rgb = get_bits1(gb); /* rgb_components */ - chroma_format = get_bits(gb, 2); /* chroma_format */ - if (!chroma_format || chroma_format == CHROMA_420 || (rgb && chroma_format == CHROMA_422)) { - av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n"); - return AVERROR_INVALIDDATA; - } - - bits_per_raw_sample = get_bits(gb, 4); /* bit_depth */ - if (bits_per_raw_sample == 10) { - if (rgb) { - s->avctx->pix_fmt = AV_PIX_FMT_GBRP10; - } - else { - s->avctx->pix_fmt = chroma_format == CHROMA_422 ? AV_PIX_FMT_YUV422P10 : AV_PIX_FMT_YUV444P10; - } - } - else { - avpriv_request_sample(s->avctx, "MPEG-4 Studio profile bit-depth %u", bits_per_raw_sample); - return AVERROR_PATCHWELCOME; - } - if (rgb != ctx->rgb || s->chroma_format != chroma_format) - s->context_reinit = 1; - s->avctx->bits_per_raw_sample = bits_per_raw_sample; - ctx->rgb = rgb; - s->chroma_format = chroma_format; - } - if (ctx->shape == RECT_SHAPE) { - check_marker(s->avctx, gb, "before video_object_layer_width"); - width = get_bits(gb, 14); /* video_object_layer_width */ - check_marker(s->avctx, gb, "before video_object_layer_height"); - height = get_bits(gb, 14); /* video_object_layer_height */ - check_marker(s->avctx, gb, "after video_object_layer_height"); - - /* Do the same check as non-studio profile */ - if (width && height) { - if (s->width && s->height && - (s->width != width || s->height != height)) - s->context_reinit = 1; - s->width = width; - s->height = height; - } - } - 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]; - } - skip_bits(gb, 4); /* frame_rate_code */ - skip_bits(gb, 15); /* first_half_bit_rate */ - check_marker(s->avctx, gb, "after first_half_bit_rate"); - skip_bits(gb, 15); /* latter_half_bit_rate */ - check_marker(s->avctx, gb, "after latter_half_bit_rate"); - skip_bits(gb, 15); /* first_half_vbv_buffer_size */ - check_marker(s->avctx, gb, "after first_half_vbv_buffer_size"); - skip_bits(gb, 3); /* latter_half_vbv_buffer_size */ - skip_bits(gb, 11); /* first_half_vbv_buffer_size */ - check_marker(s->avctx, gb, "after first_half_vbv_buffer_size"); - skip_bits(gb, 15); /* latter_half_vbv_occupancy */ - check_marker(s->avctx, gb, "after latter_half_vbv_occupancy"); - s->low_delay = get_bits1(gb); - s->mpeg_quant = get_bits1(gb); /* mpeg2_stream */ - - next_start_code_studio(gb); - extension_and_user_data(s, gb, 2); + next_start_code_studio(gb); + extension_and_user_data(s, gb, 1); return 0; } @@ -3347,7 +3340,7 @@ int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb, int next_start_code_studio(gb); extension_and_user_data(s, gb, 0); } else if (s->studio_profile) { - avpriv_request_sample(s->avctx, "Mixes studio and non studio profile\n"); + avpriv_request_sample(s->avctx, "Mix of studio and non studio profile"); return AVERROR_PATCHWELCOME; } s->avctx->profile = profile; @@ -3388,18 +3381,18 @@ av_cold void ff_mpeg4videodec_static_init(void) { ff_rl_init(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); ff_rl_init(&ff_rvlc_rl_inter, ff_mpeg4_static_rl_table_store[1]); ff_rl_init(&ff_rvlc_rl_intra, ff_mpeg4_static_rl_table_store[2]); - INIT_VLC_RL(ff_mpeg4_rl_intra, 554); + INIT_FIRST_VLC_RL(ff_mpeg4_rl_intra, 554); INIT_VLC_RL(ff_rvlc_rl_inter, 1072); - INIT_VLC_RL(ff_rvlc_rl_intra, 1072); + INIT_FIRST_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); 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); - 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); + INIT_VLC_STATIC_FROM_LENGTHS(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, + ff_sprite_trajectory_lens, 1, + NULL, 0, 0, 0, 0, 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); @@ -3504,39 +3497,36 @@ static int mpeg4_update_thread_context(AVCodecContext *dst, } #endif -static av_cold int init_studio_vlcs(Mpeg4DecContext *ctx) +static av_cold void mpeg4_init_static(void) { - int i, ret; + INIT_VLC_STATIC_FROM_LENGTHS(&studio_luma_dc, STUDIO_INTRA_BITS, 19, + &ff_mpeg4_studio_dc_luma[0][1], 2, + &ff_mpeg4_studio_dc_luma[0][0], 2, 1, + 0, 0, 528); - for (i = 0; i < 12; i++) { - ret = init_vlc(&ctx->studio_intra_tab[i], STUDIO_INTRA_BITS, 22, - &ff_mpeg4_studio_intra[i][0][1], 4, 2, - &ff_mpeg4_studio_intra[i][0][0], 4, 2, - 0); + INIT_VLC_STATIC_FROM_LENGTHS(&studio_chroma_dc, STUDIO_INTRA_BITS, 19, + &ff_mpeg4_studio_dc_chroma[0][1], 2, + &ff_mpeg4_studio_dc_chroma[0][0], 2, 1, + 0, 0, 528); - if (ret < 0) - return ret; + for (unsigned i = 0, offset = 0; i < 12; i++) { + static VLC_TYPE vlc_buf[6498][2]; + + studio_intra_tab[i].table = &vlc_buf[offset]; + studio_intra_tab[i].table_allocated = FF_ARRAY_ELEMS(vlc_buf) - offset; + ff_init_vlc_from_lengths(&studio_intra_tab[i], + STUDIO_INTRA_BITS, 24, + &ff_mpeg4_studio_intra[i][0][1], 2, + &ff_mpeg4_studio_intra[i][0][0], 2, 1, + 0, INIT_VLC_STATIC_OVERLONG, NULL); + offset += studio_intra_tab[i].table_size; } - - ret = init_vlc(&ctx->studio_luma_dc, STUDIO_INTRA_BITS, 19, - &ff_mpeg4_studio_dc_luma[0][1], 4, 2, - &ff_mpeg4_studio_dc_luma[0][0], 4, 2, - 0); - if (ret < 0) - return ret; - - ret = init_vlc(&ctx->studio_chroma_dc, STUDIO_INTRA_BITS, 19, - &ff_mpeg4_studio_dc_chroma[0][1], 4, 2, - &ff_mpeg4_studio_dc_chroma[0][0], 4, 2, - 0); - if (ret < 0) - return ret; - - return 0; + ff_mpeg4videodec_static_init(); } static av_cold int decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; Mpeg4DecContext *ctx = avctx->priv_data; MpegEncContext *s = &ctx->m; int ret; @@ -3549,10 +3539,6 @@ static av_cold int decode_init(AVCodecContext *avctx) if ((ret = ff_h263_decode_init(avctx)) < 0) return ret; - ff_mpeg4videodec_static_init(); - if ((ret = init_studio_vlcs(ctx)) < 0) - return ret; - 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; @@ -3560,26 +3546,16 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; + ff_thread_once(&init_static_once, mpeg4_init_static); + return 0; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - Mpeg4DecContext *ctx = avctx->priv_data; - int i; - - for (i = 0; i < 12; i++) - ff_free_vlc(&ctx->studio_intra_tab[i]); - - ff_free_vlc(&ctx->studio_luma_dc); - ff_free_vlc(&ctx->studio_chroma_dc); - - return ff_h263_decode_end(avctx); -} - +#define OFFSET(x) offsetof(MpegEncContext, x) +#define FLAGS AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY static const AVOption mpeg4_options[] = { - {"quarter_sample", "1/4 subpel MC", offsetof(MpegEncContext, quarter_sample), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 0}, - {"divx_packed", "divx style packed b frames", offsetof(MpegEncContext, divx_packed), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 0}, + {"quarter_sample", "1/4 subpel MC", OFFSET(quarter_sample), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS}, + {"divx_packed", "divx style packed b frames", OFFSET(divx_packed), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS}, {NULL} }; @@ -3597,7 +3573,7 @@ AVCodec ff_mpeg4_decoder = { .id = AV_CODEC_ID_MPEG4, .priv_data_size = sizeof(Mpeg4DecContext), .init = decode_init, - .close = decode_end, + .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | @@ -3610,7 +3586,7 @@ AVCodec ff_mpeg4_decoder = { .profiles = NULL_IF_CONFIG_SMALL(ff_mpeg4_video_profiles), .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context), .priv_class = &mpeg4_class, - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_MPEG4_NVDEC_HWACCEL HWACCEL_NVDEC(mpeg4), #endif diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index a6a15e302..a879d2fd1 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -961,9 +961,6 @@ static void mpeg4_encode_vol_header(MpegEncContext *s, { int vo_ver_id; - if (!CONFIG_MPEG4_ENCODER) - return; - if (s->max_b_frames || s->quarter_sample) { vo_ver_id = 5; s->vo_type = ADV_SIMPLE_VO_TYPE; @@ -1054,7 +1051,7 @@ static void mpeg4_encode_vol_header(MpegEncContext *s, if (!(s->avctx->flags & AV_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); + ff_put_string(&s->pb, LIBAVCODEC_IDENT, 0); } } @@ -1307,6 +1304,8 @@ static av_cold int encode_init(AVCodecContext *avctx) if (s->avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { s->avctx->extradata = av_malloc(1024); + if (!s->avctx->extradata) + return AVERROR(ENOMEM); init_put_bits(&s->pb, s->avctx->extradata, 1024); if (!(s->workaround_bugs & FF_BUG_MS)) @@ -1354,8 +1353,8 @@ void ff_mpeg4_merge_partitions(MpegEncContext *s) 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->tex_pb.buf, tex_pb_len); + ff_copy_bits(&s->pb, s->pb2.buf, pb2_len); + ff_copy_bits(&s->pb, s->tex_pb.buf, tex_pb_len); s->last_bits = put_bits_count(&s->pb); } diff --git a/libavcodec/mpegaudio_tablegen.c b/libavcodec/mpegaudio_tablegen.c index ede7c8e22..7c598f777 100644 --- a/libavcodec/mpegaudio_tablegen.c +++ b/libavcodec/mpegaudio_tablegen.c @@ -22,6 +22,7 @@ #include #define CONFIG_HARDCODED_TABLES 0 +#define BUILD_TABLES #include "libavutil/tablegen.h" #include "mpegaudio_tablegen.h" #include "tableprint.h" @@ -32,8 +33,6 @@ int main(void) write_fileheader(); - WRITE_ARRAY("static const", int8_t, table_4_3_exp); - WRITE_ARRAY("static const", uint32_t, table_4_3_value); WRITE_ARRAY("static const", uint32_t, exp_table_fixed); WRITE_ARRAY("static const", float, exp_table_float); WRITE_2D_ARRAY("static const", uint32_t, expval_table_fixed); diff --git a/libavcodec/mpegaudio_tablegen.h b/libavcodec/mpegaudio_tablegen.h index 0b0ea4068..bae6962ac 100644 --- a/libavcodec/mpegaudio_tablegen.h +++ b/libavcodec/mpegaudio_tablegen.h @@ -27,19 +27,22 @@ #include #include "libavutil/attributes.h" -#define TABLE_4_3_SIZE (8191 + 16)*4 #if CONFIG_HARDCODED_TABLES #define mpegaudio_tableinit() #include "libavcodec/mpegaudio_tables.h" #else -static int8_t table_4_3_exp[TABLE_4_3_SIZE]; -static uint32_t table_4_3_value[TABLE_4_3_SIZE]; +#if defined(BUILD_TABLES) || !USE_FLOATS +#define FIXED_TABLE static uint32_t exp_table_fixed[512]; static uint32_t expval_table_fixed[512][16]; +#endif + +#if defined(BUILD_TABLES) || USE_FLOATS +#define FLOAT_TABLE static float exp_table_float[512]; static float expval_table_float[512][16]; +#endif -#define FRAC_BITS 23 #define IMDCT_SCALAR 1.759 static av_cold void mpegaudio_tableinit(void) @@ -51,41 +54,36 @@ static av_cold void mpegaudio_tableinit(void) M_SQRT2 , /* 2 ^ (2 * 0.25) */ 1.68179283050742908606, /* 2 ^ (3 * 0.25) */ }; - static double pow43_lut[16]; + double pow43_lut[16]; double exp2_base = 2.11758236813575084767080625169910490512847900390625e-22; // 2^(-72) double exp2_val; - double pow43_val = 0; + for (i = 0; i < 16; ++i) pow43_lut[i] = i * cbrt(i); - for (i = 1; i < TABLE_4_3_SIZE; i++) { - double f, fm; - int e, m; - double value = i / 4; - if ((i & 3) == 0) - pow43_val = value / IMDCT_SCALAR * cbrt(value); - f = pow43_val * exp2_lut[i & 3]; - fm = frexp(f, &e); - m = llrint(fm * (1LL << 31)); - e += FRAC_BITS - 31 + 5 - 100; - - /* normalized to FRAC_BITS */ - table_4_3_value[i] = m; - table_4_3_exp[i] = -e; - } for (exponent = 0; exponent < 512; exponent++) { if (exponent && (exponent & 3) == 0) exp2_base *= 2; exp2_val = exp2_base * exp2_lut[exponent & 3] / IMDCT_SCALAR; for (value = 0; value < 16; value++) { double f = pow43_lut[value] * exp2_val; +#ifdef FIXED_TABLE expval_table_fixed[exponent][value] = (f < 0xFFFFFFFF ? llrint(f) : 0xFFFFFFFF); +#endif +#ifdef FLOAT_TABLE expval_table_float[exponent][value] = f; +#endif } +#ifdef FIXED_TABLE exp_table_fixed[exponent] = expval_table_fixed[exponent][1]; +#endif +#ifdef FLOAT_TABLE exp_table_float[exponent] = expval_table_float[exponent][1]; +#endif } } +#undef FLOAT_TABLE +#undef FIXED_TABLE #endif /* CONFIG_HARDCODED_TABLES */ #endif /* AVCODEC_MPEGAUDIO_TABLEGEN_H */ diff --git a/libavcodec/mpegaudiodata.h b/libavcodec/mpegaudiodata.h index a188150cb..0a425ef6a 100644 --- a/libavcodec/mpegaudiodata.h +++ b/libavcodec/mpegaudiodata.h @@ -29,7 +29,10 @@ #include +#include "config.h" + #include "internal.h" +#include "vlc.h" #define MODE_EXT_MS_STEREO 2 #define MODE_EXT_I_STEREO 1 @@ -41,4 +44,40 @@ extern const int ff_mpa_quant_steps[17]; extern const int ff_mpa_quant_bits[17]; extern const unsigned char * const ff_mpa_alloc_tables[5]; +#define TABLE_4_3_SIZE ((8191 + 16)*4) +#if CONFIG_HARDCODED_TABLES +extern const int8_t ff_table_4_3_exp [TABLE_4_3_SIZE]; +extern const uint32_t ff_table_4_3_value[TABLE_4_3_SIZE]; +#else +extern int8_t ff_table_4_3_exp [TABLE_4_3_SIZE]; +extern uint32_t ff_table_4_3_value[TABLE_4_3_SIZE]; +#endif + +/* VLCs for decoding layer 3 huffman tables */ +extern VLC ff_huff_vlc[16]; +extern VLC ff_huff_quad_vlc[2]; + +/* layer3 scale factor size */ +extern const uint8_t ff_slen_table[2][16]; +/* number of lsf scale factors for a given size */ +extern const uint8_t ff_lsf_nsf_table[6][3][4]; +extern const uint8_t ff_mpa_huff_data[32][2]; + +/* band size tables */ +extern const uint8_t ff_band_size_long[9][22]; +extern const uint8_t ff_band_size_short[9][13]; +/* computed from ff_band_size_long */ +extern uint16_t ff_band_index_long[9][23]; + +extern int16_t *const ff_division_tabs[4]; + +/* lower 2 bits: modulo 3, higher bits: shift */ +extern uint16_t ff_scale_factor_modshift[64]; + +extern const uint8_t ff_mpa_pretab[2][22]; + +/* Initialize tables shared between the fixed and + * floating point MPEG audio decoders. */ +void ff_mpegaudiodec_common_init_static(void); + #endif /* AVCODEC_MPEGAUDIODATA_H */ diff --git a/libavcodec/mpegaudiodec_common.c b/libavcodec/mpegaudiodec_common.c new file mode 100644 index 000000000..a963f6683 --- /dev/null +++ b/libavcodec/mpegaudiodec_common.c @@ -0,0 +1,482 @@ +/* + * MPEG Audio decoder + * 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 + * mpeg audio layer decoder tables. + */ + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/thread.h" + +#include "mpegaudiodata.h" + +#include "mpegaudiodec_common_tablegen.h" + +uint16_t ff_scale_factor_modshift[64]; + +static int16_t division_tab3[1 << 6 ]; +static int16_t division_tab5[1 << 8 ]; +static int16_t division_tab9[1 << 11]; + +int16_t *const ff_division_tabs[4] = { + division_tab3, division_tab5, NULL, division_tab9 +}; + + +/*******************************************************/ +/* layer 3 tables */ + +const uint8_t ff_slen_table[2][16] = { + { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, + { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 }, +}; + +const uint8_t ff_lsf_nsf_table[6][3][4] = { + { { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } }, + { { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } }, + { { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } }, + { { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } }, + { { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } }, + { { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } }, +}; + +/* mpegaudio layer 3 huffman tables */ +VLC ff_huff_vlc[16]; +static VLC_TYPE huff_vlc_tables[128 + 128 + 128 + 130 + 128 + 154 + 166 + 142 + + 204 + 190 + 170 + 542 + 460 + 662 + 414][2]; +VLC ff_huff_quad_vlc[2]; +static VLC_TYPE huff_quad_vlc_tables[64 + 16][2]; + +static const uint8_t mpa_hufflens[] = { + /* Huffman table 1 - 4 entries */ + 3, 3, 2, 1, + /* Huffman table 2 - 9 entries */ + 6, 6, 5, 5, 5, 3, 3, 3, 1, + /* Huffman table 3 - 9 entries */ + 6, 6, 5, 5, 5, 3, 2, 2, 2, + /* Huffman table 5 - 16 entries */ + 8, 8, 7, 6, 7, 7, 7, 7, 6, 6, 6, 6, 3, 3, 3, 1, + /* Huffman table 6 - 16 entries */ + 7, 7, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 3, 2, 3, 3, + /* Huffman table 7 - 36 entries */ + 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 9, 9, 8, 9, 9, 8, 8, 7, 7, + 7, 8, 8, 8, 8, 7, 7, 7, 7, 6, 5, 6, 6, 4, 3, 3, 1, + /* Huffman table 8 - 36 entries */ + 11, 11, 10, 9, 10, 10, 9, 9, 9, 8, 8, 9, 9, 9, 9, 8, 8, 8, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 4, 4, 2, 3, 3, 2, + /* Huffman table 9 - 36 entries */ + 9, 9, 8, 8, 9, 9, 8, 8, 8, 8, 7, 7, 7, 8, 8, 7, 7, 7, 7, + 6, 6, 6, 6, 5, 5, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, + /* Huffman table 10 - 64 entries */ + 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 11, 11, 10, 9, 9, 10, + 10, 9, 9, 10, 10, 9, 10, 10, 8, 8, 9, 9, 10, 10, 9, 9, 10, 10, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 6, + 6, 6, 6, 4, 3, 3, 1, + /* Huffman table 11 - 64 entries */ + 10, 10, 10, 10, 10, 10, 10, 11, 11, 10, 10, 9, 9, 9, 10, 10, 10, 10, 8, + 8, 9, 9, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 7, 8, 8, 7, 7, + 8, 8, 8, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 7, 7, 6, 5, + 4, 5, 5, 3, 3, 3, 2, + /* Huffman table 12 - 64 entries */ + 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 9, 9, 8, 8, 8, 8, 8, 8, + 9, 9, 8, 8, 8, 8, 8, 9, 9, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, + 7, 7, 7, 8, 8, 7, 7, 7, 6, 6, 6, 6, 7, 7, 6, 5, 5, 5, 4, + 4, 5, 5, 4, 3, 3, 3, + /* Huffman table 13 - 256 entries */ + 19, 19, 18, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 15, 15, 16, + 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 15, 16, 16, 14, 14, 15, + 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 14, 13, 14, + 14, 13, 13, 14, 14, 13, 14, 14, 13, 14, 14, 13, 14, 14, 13, 13, 14, 14, 12, + 12, 12, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 12, 12, 13, 13, 12, 12, 12, 12, 13, 13, 13, 13, 12, + 13, 13, 12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 12, 12, 11, + 11, 12, 12, 11, 12, 12, 12, 12, 11, 11, 12, 12, 11, 12, 12, 11, 12, 12, 11, + 12, 12, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 11, 11, + 10, 11, 11, 10, 11, 11, 11, 11, 10, 10, 11, 11, 10, 10, 11, 11, 11, 11, 11, + 11, 9, 9, 10, 10, 10, 10, 10, 11, 11, 9, 9, 9, 10, 10, 9, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 8, 9, 9, 9, 9, 9, 9, 10, 10, 9, 9, + 9, 8, 8, 9, 9, 9, 9, 9, 9, 8, 7, 8, 8, 8, 8, 7, 7, 7, 7, + 7, 6, 6, 6, 6, 4, 4, 3, 1, + /* Huffman table 15 - 256 entries */ + 13, 13, 13, 13, 12, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, + 13, 11, 11, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 12, 12, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 11, 11, 11, 11, 11, + 11, 10, 11, 11, 11, 11, 11, 11, 10, 10, 11, 11, 10, 10, 10, 10, 11, 11, 10, + 10, 10, 10, 10, 10, 10, 11, 11, 10, 10, 10, 10, 10, 11, 11, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 10, 10, 10, 10, 9, 10, 10, 9, 10, + 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 10, 10, 9, 9, 9, + 9, 9, 9, 10, 10, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, + 8, 8, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 9, 8, 7, 8, 8, 7, 7, + 7, 7, 8, 8, 7, 7, 7, 7, 7, 6, 7, 7, 6, 6, 7, 7, 6, 6, 6, + 5, 5, 5, 5, 5, 3, 4, 4, 3, + /* Huffman table 16 - 256 entries */ + 11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 10, 10, 10, 10, 10, 8, + 10, 10, 9, 9, 9, 9, 10, 16, 17, 17, 15, 15, 16, 16, 14, 15, 15, 14, 14, + 15, 15, 14, 14, 15, 15, 15, 15, 14, 15, 15, 14, 13, 8, 9, 9, 8, 8, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 14, 14, 14, 14, 13, 14, 14, + 13, 13, 13, 14, 14, 14, 14, 13, 13, 14, 14, 13, 14, 14, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 13, 13, 13, 13, 12, 13, + 13, 12, 12, 13, 13, 11, 12, 12, 12, 12, 12, 12, 12, 13, 13, 11, 12, 12, 12, + 12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 11, 11, 11, 12, 12, + 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 12, 12, 11, 12, 12, 11, 12, 12, 11, + 10, 10, 11, 11, 11, 11, 11, 11, 10, 10, 11, 11, 10, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 10, 11, 11, 10, 10, 10, 11, 11, 10, 10, 11, 11, 10, 10, 11, 11, + 10, 9, 9, 10, 10, 10, 10, 10, 10, 9, 9, 9, 10, 10, 9, 10, 10, 9, 9, + 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 9, 9, 8, 8, 7, 7, 8, 8, + 7, 6, 6, 6, 6, 4, 4, 3, 1, + /* Huffman table 24 - 256 entries */ + 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 7, 7, 8, 8, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 4, 11, 11, 11, 11, 12, 12, 11, 10, 11, 11, 10, 10, 10, 10, 11, 11, 10, + 10, 10, 10, 11, 11, 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, 10, + 10, 10, 10, 10, 10, 10, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 10, 11, 11, 10, 9, 10, 10, 10, 10, 11, 11, 10, 9, 9, 10, + 10, 9, 10, 10, 10, 10, 9, 9, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 9, 9, 9, 10, 10, 8, 9, 9, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 8, 8, 8, 8, 8, + 8, 9, 9, 7, 8, 8, 7, 7, 7, 7, 7, 8, 8, 7, 7, 6, 6, 7, 7, + 6, 5, 5, 6, 6, 4, 4, 4, 4, +}; + +static const uint8_t mpa_huffsymbols[] = { + /* Huffman table 1 - 4 entries */ + 0x11, 0x01, 0x10, 0x00, + /* Huffman table 2 - 9 entries */ + 0x22, 0x02, 0x12, 0x21, 0x20, 0x11, 0x01, 0x10, 0x00, + /* Huffman table 3 - 9 entries */ + 0x22, 0x02, 0x12, 0x21, 0x20, 0x10, 0x11, 0x01, 0x00, + /* Huffman table 5 - 16 entries */ + 0x33, 0x23, 0x32, 0x31, 0x13, 0x03, 0x30, 0x22, 0x12, 0x21, 0x02, 0x20, + 0x11, 0x01, 0x10, 0x00, + /* Huffman table 6 - 16 entries */ + 0x33, 0x03, 0x23, 0x32, 0x30, 0x13, 0x31, 0x22, 0x02, 0x12, 0x21, 0x20, + 0x01, 0x11, 0x10, 0x00, + /* Huffman table 7 - 36 entries */ + 0x55, 0x45, 0x54, 0x53, 0x35, 0x44, 0x25, 0x52, 0x15, 0x51, 0x05, 0x34, + 0x50, 0x43, 0x33, 0x24, 0x42, 0x14, 0x41, 0x40, 0x04, 0x23, 0x32, 0x03, + 0x13, 0x31, 0x30, 0x22, 0x12, 0x21, 0x02, 0x20, 0x11, 0x01, 0x10, 0x00, + /* Huffman table 8 - 36 entries */ + 0x55, 0x54, 0x45, 0x53, 0x35, 0x44, 0x25, 0x52, 0x05, 0x15, 0x51, 0x34, + 0x43, 0x50, 0x33, 0x24, 0x42, 0x14, 0x41, 0x04, 0x40, 0x23, 0x32, 0x13, + 0x31, 0x03, 0x30, 0x22, 0x02, 0x20, 0x12, 0x21, 0x11, 0x01, 0x10, 0x00, + /* Huffman table 9 - 36 entries */ + 0x55, 0x45, 0x35, 0x53, 0x54, 0x05, 0x44, 0x25, 0x52, 0x15, 0x51, 0x34, + 0x43, 0x50, 0x04, 0x24, 0x42, 0x33, 0x40, 0x14, 0x41, 0x23, 0x32, 0x13, + 0x31, 0x03, 0x30, 0x22, 0x02, 0x12, 0x21, 0x20, 0x11, 0x01, 0x10, 0x00, + /* Huffman table 10 - 64 entries */ + 0x77, 0x67, 0x76, 0x57, 0x75, 0x66, 0x47, 0x74, 0x56, 0x65, 0x37, 0x73, + 0x46, 0x55, 0x54, 0x63, 0x27, 0x72, 0x64, 0x07, 0x70, 0x62, 0x45, 0x35, + 0x06, 0x53, 0x44, 0x17, 0x71, 0x36, 0x26, 0x25, 0x52, 0x15, 0x51, 0x34, + 0x43, 0x16, 0x61, 0x60, 0x05, 0x50, 0x24, 0x42, 0x33, 0x04, 0x14, 0x41, + 0x40, 0x23, 0x32, 0x03, 0x13, 0x31, 0x30, 0x22, 0x12, 0x21, 0x02, 0x20, + 0x11, 0x01, 0x10, 0x00, + /* Huffman table 11 - 64 entries */ + 0x77, 0x67, 0x76, 0x75, 0x66, 0x47, 0x74, 0x57, 0x55, 0x56, 0x65, 0x37, + 0x73, 0x46, 0x45, 0x54, 0x35, 0x53, 0x27, 0x72, 0x64, 0x07, 0x71, 0x17, + 0x70, 0x36, 0x63, 0x60, 0x44, 0x25, 0x52, 0x05, 0x15, 0x62, 0x26, 0x06, + 0x16, 0x61, 0x51, 0x34, 0x50, 0x43, 0x33, 0x24, 0x42, 0x14, 0x41, 0x04, + 0x40, 0x23, 0x32, 0x13, 0x31, 0x03, 0x30, 0x22, 0x21, 0x12, 0x02, 0x20, + 0x11, 0x01, 0x10, 0x00, + /* Huffman table 12 - 64 entries */ + 0x77, 0x67, 0x76, 0x57, 0x75, 0x66, 0x47, 0x74, 0x65, 0x56, 0x37, 0x73, + 0x55, 0x27, 0x72, 0x46, 0x64, 0x17, 0x71, 0x07, 0x70, 0x36, 0x63, 0x45, + 0x54, 0x44, 0x06, 0x05, 0x26, 0x62, 0x61, 0x16, 0x60, 0x35, 0x53, 0x25, + 0x52, 0x15, 0x51, 0x34, 0x43, 0x50, 0x04, 0x24, 0x42, 0x14, 0x33, 0x41, + 0x23, 0x32, 0x40, 0x03, 0x30, 0x13, 0x31, 0x22, 0x12, 0x21, 0x02, 0x20, + 0x00, 0x11, 0x01, 0x10, + /* Huffman table 13 - 256 entries */ + 0xFE, 0xFC, 0xFD, 0xED, 0xFF, 0xEF, 0xDF, 0xEE, 0xCF, 0xDE, 0xBF, 0xFB, + 0xCE, 0xDC, 0xAF, 0xE9, 0xEC, 0xDD, 0xFA, 0xCD, 0xBE, 0xEB, 0x9F, 0xF9, + 0xEA, 0xBD, 0xDB, 0x8F, 0xF8, 0xCC, 0xAE, 0x9E, 0x8E, 0x7F, 0x7E, 0xF7, + 0xDA, 0xAD, 0xBC, 0xCB, 0xF6, 0x6F, 0xE8, 0x5F, 0x9D, 0xD9, 0xF5, 0xE7, + 0xAC, 0xBB, 0x4F, 0xF4, 0xCA, 0xE6, 0xF3, 0x3F, 0x8D, 0xD8, 0x2F, 0xF2, + 0x6E, 0x9C, 0x0F, 0xC9, 0x5E, 0xAB, 0x7D, 0xD7, 0x4E, 0xC8, 0xD6, 0x3E, + 0xB9, 0x9B, 0xAA, 0x1F, 0xF1, 0xF0, 0xBA, 0xE5, 0xE4, 0x8C, 0x6D, 0xE3, + 0xE2, 0x2E, 0x0E, 0x1E, 0xE1, 0xE0, 0x5D, 0xD5, 0x7C, 0xC7, 0x4D, 0x8B, + 0xB8, 0xD4, 0x9A, 0xA9, 0x6C, 0xC6, 0x3D, 0xD3, 0x7B, 0x2D, 0xD2, 0x1D, + 0xB7, 0x5C, 0xC5, 0x99, 0x7A, 0xC3, 0xA7, 0x97, 0x4B, 0xD1, 0x0D, 0xD0, + 0x8A, 0xA8, 0x4C, 0xC4, 0x6B, 0xB6, 0x3C, 0x2C, 0xC2, 0x5B, 0xB5, 0x89, + 0x1C, 0xC1, 0x98, 0x0C, 0xC0, 0xB4, 0x6A, 0xA6, 0x79, 0x3B, 0xB3, 0x88, + 0x5A, 0x2B, 0xA5, 0x69, 0xA4, 0x78, 0x87, 0x94, 0x77, 0x76, 0xB2, 0x1B, + 0xB1, 0x0B, 0xB0, 0x96, 0x4A, 0x3A, 0xA3, 0x59, 0x95, 0x2A, 0xA2, 0x1A, + 0xA1, 0x0A, 0x68, 0xA0, 0x86, 0x49, 0x93, 0x39, 0x58, 0x85, 0x67, 0x29, + 0x92, 0x57, 0x75, 0x38, 0x83, 0x66, 0x47, 0x74, 0x56, 0x65, 0x73, 0x19, + 0x91, 0x09, 0x90, 0x48, 0x84, 0x72, 0x46, 0x64, 0x28, 0x82, 0x18, 0x37, + 0x27, 0x17, 0x71, 0x55, 0x07, 0x70, 0x36, 0x63, 0x45, 0x54, 0x26, 0x62, + 0x35, 0x81, 0x08, 0x80, 0x16, 0x61, 0x06, 0x60, 0x53, 0x44, 0x25, 0x52, + 0x05, 0x15, 0x51, 0x34, 0x43, 0x50, 0x24, 0x42, 0x33, 0x14, 0x41, 0x04, + 0x40, 0x23, 0x32, 0x13, 0x31, 0x03, 0x30, 0x22, 0x12, 0x21, 0x02, 0x20, + 0x11, 0x01, 0x10, 0x00, + /* Huffman table 15 - 256 entries */ + 0xFF, 0xEF, 0xFE, 0xDF, 0xEE, 0xFD, 0xCF, 0xFC, 0xDE, 0xED, 0xBF, 0xFB, + 0xCE, 0xEC, 0xDD, 0xAF, 0xFA, 0xBE, 0xEB, 0xCD, 0xDC, 0x9F, 0xF9, 0xEA, + 0xBD, 0xDB, 0x8F, 0xF8, 0xCC, 0x9E, 0xE9, 0x7F, 0xF7, 0xAD, 0xDA, 0xBC, + 0x6F, 0xAE, 0x0F, 0xCB, 0xF6, 0x8E, 0xE8, 0x5F, 0x9D, 0xF5, 0x7E, 0xE7, + 0xAC, 0xCA, 0xBB, 0xD9, 0x8D, 0x4F, 0xF4, 0x3F, 0xF3, 0xD8, 0xE6, 0x2F, + 0xF2, 0x6E, 0xF0, 0x1F, 0xF1, 0x9C, 0xC9, 0x5E, 0xAB, 0xBA, 0xE5, 0x7D, + 0xD7, 0x4E, 0xE4, 0x8C, 0xC8, 0x3E, 0x6D, 0xD6, 0xE3, 0x9B, 0xB9, 0x2E, + 0xAA, 0xE2, 0x1E, 0xE1, 0x0E, 0xE0, 0x5D, 0xD5, 0x7C, 0xC7, 0x4D, 0x8B, + 0xD4, 0xB8, 0x9A, 0xA9, 0x6C, 0xC6, 0x3D, 0xD3, 0xD2, 0x2D, 0x0D, 0x1D, + 0x7B, 0xB7, 0xD1, 0x5C, 0xD0, 0xC5, 0x8A, 0xA8, 0x4C, 0xC4, 0x6B, 0xB6, + 0x99, 0x0C, 0x3C, 0xC3, 0x7A, 0xA7, 0xA6, 0xC0, 0x0B, 0xC2, 0x2C, 0x5B, + 0xB5, 0x1C, 0x89, 0x98, 0xC1, 0x4B, 0xB4, 0x6A, 0x3B, 0x79, 0xB3, 0x97, + 0x88, 0x2B, 0x5A, 0xB2, 0xA5, 0x1B, 0xB1, 0xB0, 0x69, 0x96, 0x4A, 0xA4, + 0x78, 0x87, 0x3A, 0xA3, 0x59, 0x95, 0x2A, 0xA2, 0x1A, 0xA1, 0x0A, 0xA0, + 0x68, 0x86, 0x49, 0x94, 0x39, 0x93, 0x77, 0x09, 0x58, 0x85, 0x29, 0x67, + 0x76, 0x92, 0x91, 0x19, 0x90, 0x48, 0x84, 0x57, 0x75, 0x38, 0x83, 0x66, + 0x47, 0x28, 0x82, 0x18, 0x81, 0x74, 0x08, 0x80, 0x56, 0x65, 0x37, 0x73, + 0x46, 0x27, 0x72, 0x64, 0x17, 0x55, 0x71, 0x07, 0x70, 0x36, 0x63, 0x45, + 0x54, 0x26, 0x62, 0x16, 0x06, 0x60, 0x35, 0x61, 0x53, 0x44, 0x25, 0x52, + 0x15, 0x51, 0x05, 0x50, 0x34, 0x43, 0x24, 0x42, 0x33, 0x41, 0x14, 0x04, + 0x23, 0x32, 0x40, 0x03, 0x13, 0x31, 0x30, 0x22, 0x12, 0x21, 0x02, 0x20, + 0x11, 0x01, 0x10, 0x00, + /* Huffman table 16 - 256 entries */ + 0xEF, 0xFE, 0xDF, 0xFD, 0xCF, 0xFC, 0xBF, 0xFB, 0xAF, 0xFA, 0x9F, 0xF9, + 0xF8, 0x8F, 0x7F, 0xF7, 0x6F, 0xF6, 0xFF, 0x5F, 0xF5, 0x4F, 0xF4, 0xF3, + 0xF0, 0x3F, 0xCE, 0xEC, 0xDD, 0xDE, 0xE9, 0xEA, 0xD9, 0xEE, 0xED, 0xEB, + 0xBE, 0xCD, 0xDC, 0xDB, 0xAE, 0xCC, 0xAD, 0xDA, 0x7E, 0xAC, 0xCA, 0xC9, + 0x7D, 0x5E, 0xBD, 0xF2, 0x2F, 0x0F, 0x1F, 0xF1, 0x9E, 0xBC, 0xCB, 0x8E, + 0xE8, 0x9D, 0xE7, 0xBB, 0x8D, 0xD8, 0x6E, 0xE6, 0x9C, 0xAB, 0xBA, 0xE5, + 0xD7, 0x4E, 0xE4, 0x8C, 0xC8, 0x3E, 0x6D, 0xD6, 0x9B, 0xB9, 0xAA, 0xE1, + 0xD4, 0xB8, 0xA9, 0x7B, 0xB7, 0xD0, 0xE3, 0x0E, 0xE0, 0x5D, 0xD5, 0x7C, + 0xC7, 0x4D, 0x8B, 0x9A, 0x6C, 0xC6, 0x3D, 0x5C, 0xC5, 0x0D, 0x8A, 0xA8, + 0x99, 0x4C, 0xB6, 0x7A, 0x3C, 0x5B, 0x89, 0x1C, 0xC0, 0x98, 0x79, 0xE2, + 0x2E, 0x1E, 0xD3, 0x2D, 0xD2, 0xD1, 0x3B, 0x97, 0x88, 0x1D, 0xC4, 0x6B, + 0xC3, 0xA7, 0x2C, 0xC2, 0xB5, 0xC1, 0x0C, 0x4B, 0xB4, 0x6A, 0xA6, 0xB3, + 0x5A, 0xA5, 0x2B, 0xB2, 0x1B, 0xB1, 0x0B, 0xB0, 0x69, 0x96, 0x4A, 0xA4, + 0x78, 0x87, 0xA3, 0x3A, 0x59, 0x2A, 0x95, 0x68, 0xA1, 0x86, 0x77, 0x94, + 0x49, 0x57, 0x67, 0xA2, 0x1A, 0x0A, 0xA0, 0x39, 0x93, 0x58, 0x85, 0x29, + 0x92, 0x76, 0x09, 0x19, 0x91, 0x90, 0x48, 0x84, 0x75, 0x38, 0x83, 0x66, + 0x28, 0x82, 0x47, 0x74, 0x18, 0x81, 0x80, 0x08, 0x56, 0x37, 0x73, 0x65, + 0x46, 0x27, 0x72, 0x64, 0x55, 0x07, 0x17, 0x71, 0x70, 0x36, 0x63, 0x45, + 0x54, 0x26, 0x62, 0x16, 0x61, 0x06, 0x60, 0x53, 0x35, 0x44, 0x25, 0x52, + 0x51, 0x15, 0x05, 0x34, 0x43, 0x50, 0x24, 0x42, 0x33, 0x14, 0x41, 0x04, + 0x40, 0x23, 0x32, 0x13, 0x31, 0x03, 0x30, 0x22, 0x12, 0x21, 0x02, 0x20, + 0x11, 0x01, 0x10, 0x00, + /* Huffman table 24 - 256 entries */ + 0xEF, 0xFE, 0xDF, 0xFD, 0xCF, 0xFC, 0xBF, 0xFB, 0xFA, 0xAF, 0x9F, 0xF9, + 0xF8, 0x8F, 0x7F, 0xF7, 0x6F, 0xF6, 0x5F, 0xF5, 0x4F, 0xF4, 0x3F, 0xF3, + 0x2F, 0xF2, 0xF1, 0x1F, 0xF0, 0x0F, 0xEE, 0xDE, 0xED, 0xCE, 0xEC, 0xDD, + 0xBE, 0xEB, 0xCD, 0xDC, 0xAE, 0xEA, 0xBD, 0xDB, 0xCC, 0x9E, 0xE9, 0xAD, + 0xDA, 0xBC, 0xCB, 0x8E, 0xE8, 0x9D, 0xD9, 0x7E, 0xE7, 0xAC, 0xFF, 0xCA, + 0xBB, 0x8D, 0xD8, 0x0E, 0xE0, 0x0D, 0xE6, 0x6E, 0x9C, 0xC9, 0x5E, 0xBA, + 0xE5, 0xAB, 0x7D, 0xD7, 0xE4, 0x8C, 0xC8, 0x4E, 0x2E, 0x3E, 0x6D, 0xD6, + 0xE3, 0x9B, 0xB9, 0xAA, 0xE2, 0x1E, 0xE1, 0x5D, 0xD5, 0x7C, 0xC7, 0x4D, + 0x8B, 0xB8, 0xD4, 0x9A, 0xA9, 0x6C, 0xC6, 0x3D, 0xD3, 0x2D, 0xD2, 0x1D, + 0x7B, 0xB7, 0xD1, 0x5C, 0xC5, 0x8A, 0xA8, 0x99, 0x4C, 0xC4, 0x6B, 0xB6, + 0xD0, 0x0C, 0x3C, 0xC3, 0x7A, 0xA7, 0x2C, 0xC2, 0x5B, 0xB5, 0x1C, 0x89, + 0x98, 0xC1, 0x4B, 0xC0, 0x0B, 0x3B, 0xB0, 0x0A, 0x1A, 0xB4, 0x6A, 0xA6, + 0x79, 0x97, 0xA0, 0x09, 0x90, 0xB3, 0x88, 0x2B, 0x5A, 0xB2, 0xA5, 0x1B, + 0xB1, 0x69, 0x96, 0xA4, 0x4A, 0x78, 0x87, 0x3A, 0xA3, 0x59, 0x95, 0x2A, + 0xA2, 0xA1, 0x68, 0x86, 0x77, 0x49, 0x94, 0x39, 0x93, 0x58, 0x85, 0x29, + 0x67, 0x76, 0x92, 0x19, 0x91, 0x48, 0x84, 0x57, 0x75, 0x38, 0x83, 0x66, + 0x28, 0x82, 0x18, 0x47, 0x74, 0x81, 0x08, 0x80, 0x56, 0x65, 0x17, 0x07, + 0x70, 0x73, 0x37, 0x27, 0x72, 0x46, 0x64, 0x55, 0x71, 0x36, 0x63, 0x45, + 0x54, 0x26, 0x62, 0x16, 0x61, 0x06, 0x60, 0x35, 0x53, 0x44, 0x25, 0x52, + 0x15, 0x05, 0x50, 0x51, 0x34, 0x43, 0x24, 0x42, 0x33, 0x14, 0x41, 0x04, + 0x40, 0x23, 0x32, 0x13, 0x31, 0x03, 0x30, 0x22, 0x12, 0x21, 0x02, 0x20, + 0x11, 0x01, 0x10, 0x00, +}; + +static const uint8_t mpa_huff_sizes_minus_one[] = +{ + 3, 8, 8, 15, 15, 35, 35, 35, 63, 63, 63, 255, 255, 255, 255 +}; + +const uint8_t ff_mpa_huff_data[32][2] = { +{ 0, 0 }, +{ 1, 0 }, +{ 2, 0 }, +{ 3, 0 }, +{ 0, 0 }, +{ 4, 0 }, +{ 5, 0 }, +{ 6, 0 }, +{ 7, 0 }, +{ 8, 0 }, +{ 9, 0 }, +{ 10, 0 }, +{ 11, 0 }, +{ 12, 0 }, +{ 0, 0 }, +{ 13, 0 }, +{ 14, 1 }, +{ 14, 2 }, +{ 14, 3 }, +{ 14, 4 }, +{ 14, 6 }, +{ 14, 8 }, +{ 14, 10 }, +{ 14, 13 }, +{ 15, 4 }, +{ 15, 5 }, +{ 15, 6 }, +{ 15, 7 }, +{ 15, 8 }, +{ 15, 9 }, +{ 15, 11 }, +{ 15, 13 }, +}; + + +/* huffman tables for quadrules */ +static const uint8_t mpa_quad_codes[2][16] = { + { 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1, }, + { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, }, +}; + +static const uint8_t mpa_quad_bits[2][16] = { + { 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6, }, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, }, +}; + +const uint8_t ff_band_size_long[9][22] = { +{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, + 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, }, /* 44100 */ +{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, + 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192, }, /* 48000 */ +{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, + 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26, }, /* 32000 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 22050 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 18, 22, 26, 32, 38, 46, 52, 64, 70, 76, 36, }, /* 24000 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 16000 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 11025 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 12000 */ +{ 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, + 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2, }, /* 8000 */ +}; + +const uint8_t ff_band_size_short[9][13] = { +{ 4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56, }, /* 44100 */ +{ 4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66, }, /* 48000 */ +{ 4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12, }, /* 32000 */ +{ 4, 4, 4, 6, 6, 8, 10, 14, 18, 26, 32, 42, 18, }, /* 22050 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 32, 44, 12, }, /* 24000 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 16000 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 11025 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 12000 */ +{ 8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26, }, /* 8000 */ +}; + +uint16_t ff_band_index_long[9][23]; + +const uint8_t ff_mpa_pretab[2][22] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 2, 2, 3, 3, 3, 2, 0 }, +}; + +static av_cold void mpegaudiodec_common_init_static(void) +{ + const uint8_t *huff_sym = mpa_huffsymbols, *huff_lens = mpa_hufflens; + int offset; + + /* scale factors table for layer 1/2 */ + for (int i = 0; i < 64; i++) { + int shift, mod; + /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */ + shift = i / 3; + mod = i % 3; + ff_scale_factor_modshift[i] = mod | (shift << 2); + } + + /* huffman decode tables */ + offset = 0; + for (int i = 0; i < 15;) { + uint16_t tmp_symbols[256]; + int nb_codes_minus_one = mpa_huff_sizes_minus_one[i]; + int j; + + for (j = 0; j <= nb_codes_minus_one; j++) { + uint8_t high = huff_sym[j] & 0xF0, low = huff_sym[j] & 0xF; + + tmp_symbols[j] = high << 1 | ((high && low) << 4) | low; + } + + ff_huff_vlc[++i].table = huff_vlc_tables + offset; + ff_huff_vlc[i].table_allocated = FF_ARRAY_ELEMS(huff_vlc_tables) - offset; + ff_init_vlc_from_lengths(&ff_huff_vlc[i], 7, j, + huff_lens, 1, tmp_symbols, 2, 2, + 0, INIT_VLC_STATIC_OVERLONG, NULL); + offset += ff_huff_vlc[i].table_size; + huff_lens += j; + huff_sym += j; + } + av_assert0(offset == FF_ARRAY_ELEMS(huff_vlc_tables)); + + offset = 0; + for (int i = 0; i < 2; i++) { + int bits = i == 0 ? 6 : 4; + ff_huff_quad_vlc[i].table = huff_quad_vlc_tables + offset; + ff_huff_quad_vlc[i].table_allocated = 1 << bits; + offset += 1 << bits; + init_vlc(&ff_huff_quad_vlc[i], bits, 16, + mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1, + INIT_VLC_USE_NEW_STATIC); + } + av_assert0(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables)); + + for (int i = 0; i < 9; i++) { + int k = 0; + for (int j = 0; j < 22; j++) { + ff_band_index_long[i][j] = k; + k += ff_band_size_long[i][j] >> 1; + } + ff_band_index_long[i][22] = k; + } + + for (int i = 0; i < 4; i++) { + if (ff_mpa_quant_bits[i] < 0) { + for (int 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; + ff_division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8); + } + } + } + mpegaudiodec_common_tableinit(); +} + +av_cold void ff_mpegaudiodec_common_init_static(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + + ff_thread_once(&init_static_once, mpegaudiodec_common_init_static); +} diff --git a/libavcodec/mpegaudiodec_common_tablegen.c b/libavcodec/mpegaudiodec_common_tablegen.c new file mode 100644 index 000000000..a319df65a --- /dev/null +++ b/libavcodec/mpegaudiodec_common_tablegen.c @@ -0,0 +1,40 @@ +/* + * Generate a header file for hardcoded shared mpegaudiodec tables + * + * Copyright (c) 2009 Reimar Döffinger + * Copyright (c) 2020 Andreas Rheinhardt + * + * 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 +#define CONFIG_HARDCODED_TABLES 0 +#include "libavutil/tablegen.h" +#include "mpegaudiodec_common_tablegen.h" +#include "tableprint.h" + +int main(void) +{ + mpegaudiodec_common_tableinit(); + + write_fileheader(); + + WRITE_ARRAY("const", int8_t, ff_table_4_3_exp); + WRITE_ARRAY("const", uint32_t, ff_table_4_3_value); + + return 0; +} diff --git a/libavcodec/mpegaudiodec_common_tablegen.h b/libavcodec/mpegaudiodec_common_tablegen.h new file mode 100644 index 000000000..bf402c9d8 --- /dev/null +++ b/libavcodec/mpegaudiodec_common_tablegen.h @@ -0,0 +1,72 @@ +/* + * Header file for hardcoded shared mpegaudiodec tables + * + * Copyright (c) 2009 Reimar Döffinger + * Copyright (c) 2020 Andreas Rheinhardt + * + * 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_MPEGAUDIODEC_COMMON_TABLEGEN_H +#define AVCODEC_MPEGAUDIODEC_COMMON_TABLEGEN_H + +#include + +#define TABLE_4_3_SIZE ((8191 + 16)*4) + +#if CONFIG_HARDCODED_TABLES +#define mpegaudiodec_common_tableinit() +#include "libavcodec/mpegaudiodec_common_tables.h" +#else +#include +#include "libavutil/attributes.h" + +int8_t ff_table_4_3_exp [TABLE_4_3_SIZE]; +uint32_t ff_table_4_3_value[TABLE_4_3_SIZE]; + +#define FRAC_BITS 23 +#define IMDCT_SCALAR 1.759 + +static av_cold void mpegaudiodec_common_tableinit(void) +{ + static const double exp2_lut[4] = { + 1.00000000000000000000, /* 2 ^ (0 * 0.25) */ + 1.18920711500272106672, /* 2 ^ (1 * 0.25) */ + M_SQRT2 , /* 2 ^ (2 * 0.25) */ + 1.68179283050742908606, /* 2 ^ (3 * 0.25) */ + }; + double pow43_val = 0; + + for (int i = 1; i < TABLE_4_3_SIZE; i++) { + double f, fm; + int e, m; + double value = i / 4; + if ((i & 3) == 0) + pow43_val = value / IMDCT_SCALAR * cbrt(value); + f = pow43_val * exp2_lut[i & 3]; + fm = frexp(f, &e); + m = llrint(fm * (1LL << 31)); + e += FRAC_BITS - 31 + 5 - 100; + + /* normalized to FRAC_BITS */ + ff_table_4_3_value[i] = m; + ff_table_4_3_exp [i] = -e; + } +} + +#endif /* CONFIG_HARDCODED_TABLES */ +#endif /* AVCODEC_MPEGAUDIODEC_COMMON_TABLEGEN_H */ diff --git a/libavcodec/mpegaudiodec_fixed.c b/libavcodec/mpegaudiodec_fixed.c index ad7ceb20b..a3c8ddc21 100644 --- a/libavcodec/mpegaudiodec_fixed.c +++ b/libavcodec/mpegaudiodec_fixed.c @@ -36,6 +36,26 @@ #define OUT_FMT AV_SAMPLE_FMT_S16 #define OUT_FMT_P AV_SAMPLE_FMT_S16P +/* Intensity stereo table. See commit b91d46614df189e7905538e7f5c4ed9c7ed0d274 + * (float based mp1/mp2/mp3 decoders.) for how they were created. */ +static const int32_t is_table[2][16] = { + { 0x000000, 0x1B0CB1, 0x2ED9EC, 0x400000, 0x512614, 0x64F34F, 0x800000 }, + { 0x800000, 0x64F34F, 0x512614, 0x400000, 0x2ED9EC, 0x1B0CB1, 0x000000 } +}; + +/* Antialiasing table. See commit ce4a29c066cddfc180979ed86396812f24337985 + * (optimize antialias) for how they were created. */ +static const int32_t csa_table[8][4] = { + { 0x36E129F8, 0xDF128056, 0x15F3AA4E, 0xA831565E }, + { 0x386E75F2, 0xE1CF24A5, 0x1A3D9A97, 0xA960AEB3 }, + { 0x3CC6B73A, 0xEBF19FA6, 0x28B856E0, 0xAF2AE86C }, + { 0x3EEEA054, 0xF45B88BC, 0x334A2910, 0xB56CE868 }, + { 0x3FB6905C, 0xF9F27F18, 0x39A90F74, 0xBA3BEEBC }, + { 0x3FF23F20, 0xFD60D1E4, 0x3D531104, 0xBD6E92C4 }, + { 0x3FFE5932, 0xFF175EE4, 0x3F15B816, 0xBF1905B2 }, + { 0x3FFFE34A, 0xFFC3612F, 0x3FC34479, 0xBFC37DE5 } +}; + #include "mpegaudiodec_template.c" #if CONFIG_MP1_DECODER @@ -47,11 +67,13 @@ AVCodec ff_mp1_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_MP2_DECODER @@ -63,11 +85,13 @@ AVCodec ff_mp2_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_MP3_DECODER @@ -79,11 +103,13 @@ AVCodec ff_mp3_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_MP3ADU_DECODER @@ -95,11 +121,13 @@ AVCodec ff_mp3adu_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame_adu, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_MP3ON4_DECODER @@ -112,9 +140,11 @@ AVCodec ff_mp3on4_decoder = { .init = decode_init_mp3on4, .close = decode_close_mp3on4, .decode = decode_frame_mp3on4, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush_mp3on4, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c index ddfa5e0da..3ab7651d5 100644 --- a/libavcodec/mpegaudiodec_float.c +++ b/libavcodec/mpegaudiodec_float.c @@ -36,6 +36,39 @@ #define OUT_FMT AV_SAMPLE_FMT_FLT #define OUT_FMT_P AV_SAMPLE_FMT_FLTP +/* Intensity stereo table. See commit b91d46614df189e7905538e7f5c4ed9c7ed0d274 + * (float based mp1/mp2/mp3 decoders.) for how they were created. */ +static const float is_table[2][16] = { + { 0.000000000000000000e+00, 2.113248705863952637e-01, 3.660253882408142090e-01, + 5.000000000000000000e-01, 6.339746117591857910e-01, 7.886751294136047363e-01, + 1.000000000000000000e+00 }, + { 1.000000000000000000e+00, 7.886751294136047363e-01, 6.339746117591857910e-01, + 5.000000000000000000e-01, 3.660253882408142090e-01, 2.113248705863952637e-01, + 0.000000000000000000e+00 } +}; + +/* Antialiasing table. See commit 6f1ec38ce2193d3d4cacd87edb452c6d7ba751ec + * (mpegaudio: clean up compute_antialias() definition) for how they were + * created. */ +static const float csa_table[8][4] = { + { 8.574929237365722656e-01, -5.144957900047302246e-01, + 3.429971337318420410e-01, -1.371988654136657715e+00 }, + { 8.817420005798339844e-01, -4.717319905757904053e-01, + 4.100100100040435791e-01, -1.353474020957946777e+00 }, + { 9.496286511421203613e-01, -3.133774697780609131e-01, + 6.362511515617370605e-01, -1.263006091117858887e+00 }, + { 9.833145737648010254e-01, -1.819131970405578613e-01, + 8.014013767242431641e-01, -1.165227770805358887e+00 }, + { 9.955177903175354004e-01, -9.457419067621231079e-02, + 9.009436368942260742e-01, -1.090092062950134277e+00 }, + { 9.991605877876281738e-01, -4.096558317542076111e-02, + 9.581949710845947266e-01, -1.040126085281372070e+00 }, + { 9.998992085456848145e-01, -1.419856864959001541e-02, + 9.857006072998046875e-01, -1.014097809791564941e+00 }, + { 9.999931454658508301e-01, -3.699974622577428818e-03, + 9.962931871414184570e-01, -1.003693103790283203e+00 } +}; + #include "mpegaudiodec_template.c" #if CONFIG_MP1FLOAT_DECODER @@ -46,13 +79,14 @@ AVCodec ff_mp1float_decoder = { .id = AV_CODEC_ID_MP1, .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, - .close = decode_close, .decode = decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_MP2FLOAT_DECODER @@ -64,12 +98,13 @@ AVCodec ff_mp2float_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, - .close = decode_close, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_MP3FLOAT_DECODER @@ -80,13 +115,14 @@ AVCodec ff_mp3float_decoder = { .id = AV_CODEC_ID_MP3, .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, - .close = decode_close, .decode = decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_MP3ADUFLOAT_DECODER @@ -97,13 +133,14 @@ AVCodec ff_mp3adufloat_decoder = { .id = AV_CODEC_ID_MP3ADU, .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, - .close = decode_close, .decode = decode_frame_adu, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_MP3ON4FLOAT_DECODER @@ -116,9 +153,11 @@ AVCodec ff_mp3on4float_decoder = { .init = decode_init_mp3on4, .close = decode_close_mp3on4, .decode = decode_frame_mp3on4, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .flush = flush_mp3on4, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index 3d7e3ba4f..4fd9e3a69 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -30,6 +30,9 @@ #include "libavutil/crc.h" #include "libavutil/float_dsp.h" #include "libavutil/libm.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" + #include "avcodec.h" #include "get_bits.h" #include "internal.h" @@ -87,46 +90,19 @@ typedef struct MPADecodeContext { int err_recognition; AVCodecContext* avctx; MPADSPContext mpadsp; - AVFloatDSPContext *fdsp; + void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len); AVFrame *frame; + uint32_t crc; } MPADecodeContext; #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 */ @@ -177,10 +153,10 @@ static void 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; + g->region_size[0] = ff_band_index_long[s->sample_rate_index][ra1 + 1]; /* should not overflow */ l = FFMIN(ra1 + ra2 + 2, 22); - g->region_size[1] = band_index_long[s->sample_rate_index][ l] >> 1; + g->region_size[1] = ff_band_index_long[s->sample_rate_index][ l]; } static void compute_band_indexes(MPADecodeContext *s, GranuleDef *g) @@ -215,7 +191,7 @@ static inline int l1_unscale(int n, int mant, int scale_factor) int shift, mod; int64_t val; - shift = scale_factor_modshift[scale_factor]; + shift = ff_scale_factor_modshift[scale_factor]; mod = shift & 3; shift >>= 2; val = MUL64((int)(mant + (-1U << n) + 1), scale_factor_mult[n-1][mod]); @@ -228,7 +204,7 @@ static inline int l2_unscale_group(int steps, int mant, int scale_factor) { int shift, mod, val; - shift = scale_factor_modshift[scale_factor]; + shift = ff_scale_factor_modshift[scale_factor]; mod = shift & 3; shift >>= 2; @@ -245,8 +221,8 @@ 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 = ff_table_4_3_exp [4 * value + (exponent & 3)]; + m = ff_table_4_3_value[4 * value + (exponent & 3)]; e -= exponent >> 2; #ifdef DEBUG if(e < 1) @@ -254,24 +230,14 @@ static inline int l3_unscale(int value, int exponent) #endif if (e > (SUINT)31) return 0; - m = (m + ((1U << e)>>1)) >> e; + m = (m + ((1U << 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); - } + int i, j; /* scale factor multiply for layer 1 */ for (i = 0; i < 15; i++) { @@ -288,92 +254,10 @@ static av_cold void decode_init_static(void) 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; @@ -389,52 +273,26 @@ static av_cold void decode_init_static(void) (float) is_table_lsf[j][1][i]); } } - - for (i = 0; i < 8; i++) { - double ci, cs, ca; - ci = ci_table[i]; - cs = 1.0 / sqrt(1.0 + ci * ci); - ca = cs * ci; -#if !USE_FLOATS - 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 - } + RENAME(ff_mpa_synth_init)(); + ff_mpegaudiodec_common_init_static(); } -#if USE_FLOATS -static av_cold int decode_close(AVCodecContext * avctx) -{ - MPADecodeContext *s = avctx->priv_data; - av_freep(&s->fdsp); - - return 0; -} -#endif - static av_cold int decode_init(AVCodecContext * avctx) { - static int initialized_tables = 0; + static AVOnce init_static_once = AV_ONCE_INIT; MPADecodeContext *s = avctx->priv_data; - if (!initialized_tables) { - decode_init_static(); - initialized_tables = 1; - } - s->avctx = avctx; #if USE_FLOATS - s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); - if (!s->fdsp) - return AVERROR(ENOMEM); + { + AVFloatDSPContext *fdsp; + fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!fdsp) + return AVERROR(ENOMEM); + s->butterflies_float = fdsp->butterflies_float; + av_free(fdsp); + } #endif ff_mpadsp_init(&s->mpadsp); @@ -449,6 +307,8 @@ static av_cold int decode_init(AVCodecContext * avctx) if (avctx->codec_id == AV_CODEC_ID_MP3ADU) s->adu_mode = 1; + ff_thread_once(&init_static_once, decode_init_static); + return 0; } @@ -500,12 +360,43 @@ static void imdct12(INTFLOAT *out, SUINTFLOAT *in) out[11] = in0 + in5; } +static int handle_crc(MPADecodeContext *s, int sec_len) +{ + if (s->error_protection && (s->err_recognition & AV_EF_CRCCHECK)) { + const uint8_t *buf = s->gb.buffer - HEADER_SIZE; + int sec_byte_len = sec_len >> 3; + int sec_rem_bits = sec_len & 7; + const AVCRC *crc_tab = av_crc_get_table(AV_CRC_16_ANSI); + uint8_t tmp_buf[4]; + uint32_t crc_val = av_crc(crc_tab, UINT16_MAX, &buf[2], 2); + crc_val = av_crc(crc_tab, crc_val, &buf[6], sec_byte_len); + + AV_WB32(tmp_buf, + ((buf[6 + sec_byte_len] & (0xFF00 >> sec_rem_bits)) << 24) + + ((s->crc << 16) >> sec_rem_bits)); + + crc_val = av_crc(crc_tab, crc_val, tmp_buf, 3); + + if (crc_val) { + av_log(s->avctx, AV_LOG_ERROR, "CRC mismatch %X!\n", crc_val); + if (s->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + } + } + return 0; +} + /* 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]; + int ret; + + ret = handle_crc(s, (s->nb_channels == 1) ? 8*16 : 8*32); + if (ret < 0) + return ret; if (s->mode == MPA_JSTEREO) bound = (s->mode_ext + 1) * 4; @@ -575,6 +466,7 @@ static int mp_decode_layer2(MPADecodeContext *s) 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; + int ret; /* select decoding table */ table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels, @@ -617,6 +509,10 @@ static int mp_decode_layer2(MPADecodeContext *s) } } + ret = handle_crc(s, get_bits_count(&s->gb) - 16); + if (ret < 0) + return ret; + /* scale factors */ for (i = 0; i < sblimit; i++) { for (ch = 0; ch < s->nb_channels; ch++) { @@ -665,7 +561,7 @@ static int mp_decode_layer2(MPADecodeContext *s) int v2; /* 3 values at the same time */ v = get_bits(&s->gb, -bits); - v2 = division_tabs[qindex][v]; + v2 = ff_division_tabs[qindex][v]; steps = ff_mpa_quant_steps[qindex]; s->sb_samples[ch][k * 12 + l + 0][i] = @@ -698,7 +594,7 @@ static int mp_decode_layer2(MPADecodeContext *s) int mant, scale0, scale1; scale0 = scale_factors[0][i][k]; scale1 = scale_factors[1][i][k]; - qindex = alloc_table[j+b]; + qindex = alloc_table[j + b]; bits = ff_mpa_quant_bits[qindex]; if (bits < 0) { /* 3 values at the same time */ @@ -793,8 +689,8 @@ static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g, gain = g->global_gain - 210; shift = g->scalefac_scale + 1; - bstab = band_size_long[s->sample_rate_index]; - pretab = mpa_pretab[g->preflag]; + bstab = ff_band_size_long[s->sample_rate_index]; + pretab = ff_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]; @@ -803,7 +699,7 @@ static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g, } if (g->short_start < 13) { - bstab = band_size_short[s->sample_rate_index]; + bstab = ff_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); @@ -868,9 +764,9 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, 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]; + l = ff_mpa_huff_data[k][0]; + linbits = ff_mpa_huff_data[k][1]; + vlc = &ff_huff_vlc[l]; if (!l) { memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * 2 * j); @@ -892,8 +788,8 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, y = get_vlc2(&s->gb, vlc->table, 7, 3); if (!y) { - g->sb_hybrid[s_index ] = - g->sb_hybrid[s_index+1] = 0; + g->sb_hybrid[s_index ] = + g->sb_hybrid[s_index + 1] = 0; s_index += 2; continue; } @@ -921,7 +817,7 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, v = l3_unscale(y, exponent); if (get_bits1(&s->gb)) v = -v; - g->sb_hybrid[s_index+1] = v; + g->sb_hybrid[s_index + 1] = v; } } else { x = y >> 5; @@ -943,7 +839,7 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, } /* high frequencies */ - vlc = &huff_quad_vlc[g->count1table_select]; + vlc = &ff_huff_quad_vlc[g->count1table_select]; last_pos = 0; while (s_index <= 572) { int pos, code; @@ -967,10 +863,10 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1); ff_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; + 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; @@ -1020,7 +916,7 @@ static void reorder_block(MPADecodeContext *s, GranuleDef *g) } for (i = g->short_start; i < 13; i++) { - len = band_size_short[s->sample_rate_index][i]; + len = ff_band_size_short[s->sample_rate_index][i]; ptr1 = ptr; dst = tmp; for (j = len; j > 0; j--) { @@ -1040,7 +936,8 @@ 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, v1, v2; + INTFLOAT *tab0, *tab1, v1, v2; + const INTFLOAT (*is_tab)[16]; SUINTFLOAT tmp0, tmp1; int non_zero_found_short[3]; @@ -1065,7 +962,7 @@ static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1) /* for last band, use previous scale factor */ if (i != 11) k -= 3; - len = band_size_short[s->sample_rate_index][i]; + len = ff_band_size_short[s->sample_rate_index][i]; for (l = 2; l >= 0; l--) { tab0 -= len; tab1 -= len; @@ -1109,7 +1006,7 @@ found1: non_zero_found_short[2]; for (i = g1->long_end - 1;i >= 0;i--) { - len = band_size_long[s->sample_rate_index][i]; + len = ff_band_size_long[s->sample_rate_index][i]; tab0 -= len; tab1 -= len; /* test if non zero band. if so, stop doing i-stereo */ @@ -1151,7 +1048,7 @@ found2: /* NOTE: the 1/sqrt(2) normalization factor is included in the global gain */ #if USE_FLOATS - s->fdsp->butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576); + s->butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576); #else tab0 = g0->sb_hybrid; tab1 = g1->sb_hybrid; @@ -1310,13 +1207,16 @@ static int mp_decode_layer3(MPADecodeContext *s) int gr, ch, blocksplit_flag, i, j, k, n, bits_pos; GranuleDef *g; int16_t exponents[576]; //FIXME try INTFLOAT + int ret; /* read side info */ if (s->lsf) { + ret = handle_crc(s, ((s->nb_channels == 1) ? 8*9 : 8*17)); main_data_begin = get_bits(&s->gb, 8); skip_bits(&s->gb, s->nb_channels); nb_granules = 1; } else { + ret = handle_crc(s, ((s->nb_channels == 1) ? 8*17 : 8*32)); main_data_begin = get_bits(&s->gb, 9); if (s->nb_channels == 2) skip_bits(&s->gb, 3); @@ -1328,6 +1228,8 @@ static int mp_decode_layer3(MPADecodeContext *s) s->granules[ch][1].scfsi = get_bits(&s->gb, 4); } } + if (ret < 0) + return ret; for (gr = 0; gr < nb_granules; gr++) { for (ch = 0; ch < s->nb_channels; ch++) { @@ -1391,7 +1293,7 @@ static int mp_decode_layer3(MPADecodeContext *s) if (!s->adu_mode) { int skip; - const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); + const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb) >> 3); s->extrasize = av_clip((get_bits_left(&s->gb) >> 3) - s->extrasize, 0, FFMAX(0, LAST_BUF_SIZE - s->last_buf_size)); av_assert1((get_bits_count(&s->gb) & 7) == 0); @@ -1435,8 +1337,8 @@ static int mp_decode_layer3(MPADecodeContext *s) int slen, slen1, slen2; /* MPEG-1 scale factors */ - slen1 = slen_table[0][g->scalefac_compress]; - slen2 = slen_table[1][g->scalefac_compress]; + slen1 = ff_slen_table[0][g->scalefac_compress]; + slen2 = ff_slen_table[1][g->scalefac_compress]; ff_dlog(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2); if (g->block_type == 2) { n = g->switch_point ? 17 : 18; @@ -1521,7 +1423,7 @@ static int mp_decode_layer3(MPADecodeContext *s) j = 0; for (k = 0; k < 4; k++) { - n = lsf_nsf_table[tindex2][tindex][k]; + n = ff_lsf_nsf_table[tindex2][tindex][k]; sl = slen[k]; if (sl) { for (i = 0; i < n; i++) @@ -1565,23 +1467,8 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples, OUT_INT *samples_ptr; init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8); - - if (s->error_protection) { - uint16_t crc = get_bits(&s->gb, 16); - if (s->err_recognition & AV_EF_CRCCHECK) { - const int sec_len = s->lsf ? ((s->nb_channels == 1) ? 9 : 17) : - ((s->nb_channels == 1) ? 17 : 32); - const AVCRC *crc_tab = av_crc_get_table(AV_CRC_16_ANSI); - uint32_t crc_cal = av_crc(crc_tab, UINT16_MAX, &buf[2], 2); - crc_cal = av_crc(crc_tab, crc_cal, &buf[6], sec_len); - - if (av_bswap16(crc) ^ crc_cal) { - av_log(s->avctx, AV_LOG_ERROR, "CRC mismatch!\n"); - if (s->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - } - } - } + if (s->error_protection) + s->crc = get_bits(&s->gb, 16); switch(s->layer) { case 1: @@ -1602,7 +1489,7 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples, align_get_bits(&s->gb); i = (get_bits_left(&s->gb) >> 3) - s->extrasize; if (i >= 0 && i <= BACKSTEP_SIZE) { - memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i); + 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); @@ -1679,7 +1566,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, return AVERROR_INVALIDDATA; header = AV_RB32(buf); - if (header>>8 == AV_RB32("TAG")>>8) { + if (header >> 8 == AV_RB32("TAG") >> 8) { av_log(avctx, AV_LOG_DEBUG, "discarding ID3 tag\n"); return buf_size + skipped; } @@ -1844,9 +1731,6 @@ static av_cold int decode_close_mp3on4(AVCodecContext * avctx) MP3On4DecodeContext *s = avctx->priv_data; int i; - if (s->mp3decctx[0]) - av_freep(&s->mp3decctx[0]->fdsp); - for (i = 0; i < s->frames; i++) av_freep(&s->mp3decctx[i]); @@ -1858,7 +1742,7 @@ static av_cold int decode_init_mp3on4(AVCodecContext * avctx) { MP3On4DecodeContext *s = avctx->priv_data; MPEG4AudioConfig cfg; - int i; + int i, ret; if ((avctx->extradata_size < 2) || !avctx->extradata) { av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n"); @@ -1889,12 +1773,14 @@ static av_cold int decode_init_mp3on4(AVCodecContext * avctx) // Allocate zeroed memory for the first decoder context s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext)); if (!s->mp3decctx[0]) - goto alloc_fail; + return AVERROR(ENOMEM); // Put decoder context in place to make init_decode() happy avctx->priv_data = s->mp3decctx[0]; - decode_init(avctx); + ret = decode_init(avctx); // Restore mp3on4 context pointer avctx->priv_data = s; + if (ret < 0) + return ret; s->mp3decctx[0]->adu_mode = 1; // Set adu mode /* Create a separate codec/context for each frame (first is already ok). @@ -1903,17 +1789,14 @@ static av_cold int decode_init_mp3on4(AVCodecContext * avctx) for (i = 1; i < s->frames; i++) { s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext)); if (!s->mp3decctx[i]) - goto alloc_fail; + return AVERROR(ENOMEM); s->mp3decctx[i]->adu_mode = 1; s->mp3decctx[i]->avctx = avctx; s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp; - s->mp3decctx[i]->fdsp = s->mp3decctx[0]->fdsp; + s->mp3decctx[i]->butterflies_float = s->mp3decctx[0]->butterflies_float; } return 0; -alloc_fail: - decode_close_mp3on4(avctx); - return AVERROR(ENOMEM); } diff --git a/libavcodec/mpegaudiodsp.c b/libavcodec/mpegaudiodsp.c index 3cafca27b..f03e24464 100644 --- a/libavcodec/mpegaudiodsp.c +++ b/libavcodec/mpegaudiodsp.c @@ -21,20 +21,69 @@ #include "config.h" #include "libavutil/attributes.h" #include "libavutil/thread.h" +#include "mpegaudio.h" #include "mpegaudiodsp.h" #include "dct.h" #include "dct32.h" -static AVOnce mpadsp_float_table_init = AV_ONCE_INIT; -static AVOnce mpadsp_fixed_table_init = AV_ONCE_INIT; +static AVOnce mpadsp_table_init = AV_ONCE_INIT; + +static av_cold void mpadsp_init_tabs(void) +{ + int i, j; + /* compute mdct windows */ + for (i = 0; i < 36; i++) { + for (j = 0; j < 4; j++) { + double d; + + if (j == 2 && i % 3 != 1) + continue; + + d = sin(M_PI * (i + 0.5) / 36.0); + if (j == 1) { + if (i >= 30) d = 0; + else if (i >= 24) d = sin(M_PI * (i - 18 + 0.5) / 12.0); + else if (i >= 18) d = 1; + } else if (j == 3) { + if (i < 6) d = 0; + else if (i < 12) d = sin(M_PI * (i - 6 + 0.5) / 12.0); + else if (i < 18) d = 1; + } + //merge last stage of imdct into the window coefficients + d *= 0.5 * IMDCT_SCALAR / cos(M_PI * (2 * i + 19) / 72); + + if (j == 2) { + ff_mdct_win_float[j][i/3] = d / (1 << 5); + ff_mdct_win_fixed[j][i/3] = d / (1 << 5) * (1LL << 32) + 0.5; + } else { + int idx = i < 18 ? i : i + (MDCT_BUF_SIZE/2 - 18); + ff_mdct_win_float[j][idx] = d / (1 << 5); + ff_mdct_win_fixed[j][idx] = d / (1 << 5) * (1LL << 32) + 0.5; + } + } + } + + /* NOTE: we do frequency inversion after the MDCT by changing + the sign of the right window coefs */ + for (j = 0; j < 4; j++) { + for (i = 0; i < MDCT_BUF_SIZE; i += 2) { + ff_mdct_win_float[j + 4][i ] = ff_mdct_win_float[j][i ]; + ff_mdct_win_float[j + 4][i + 1] = -ff_mdct_win_float[j][i + 1]; + ff_mdct_win_fixed[j + 4][i ] = ff_mdct_win_fixed[j][i ]; + ff_mdct_win_fixed[j + 4][i + 1] = -ff_mdct_win_fixed[j][i + 1]; + } + } + + if (ARCH_X86) + ff_mpadsp_init_x86_tabs(); +} av_cold void ff_mpadsp_init(MPADSPContext *s) { DCTContext dct; ff_dct_init(&dct, 5, DCT_II); - ff_thread_once(&mpadsp_float_table_init, &ff_init_mpadsp_tabs_float); - ff_thread_once(&mpadsp_fixed_table_init, &ff_init_mpadsp_tabs_fixed); + ff_thread_once(&mpadsp_table_init, &mpadsp_init_tabs); s->apply_window_float = ff_mpadsp_apply_window_float; s->apply_window_fixed = ff_mpadsp_apply_window_fixed; diff --git a/libavcodec/mpegaudiodsp.h b/libavcodec/mpegaudiodsp.h index 0e4352dea..4577d515d 100644 --- a/libavcodec/mpegaudiodsp.h +++ b/libavcodec/mpegaudiodsp.h @@ -63,11 +63,12 @@ void ff_mpadsp_init_aarch64(MPADSPContext *s); 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_x86_tabs(void); void ff_mpadsp_init_mipsfpu(MPADSPContext *s); void ff_mpadsp_init_mipsdsp(MPADSPContext *s); -void ff_mpa_synth_init_float(float *window); -void ff_mpa_synth_init_fixed(int32_t *window); +void ff_mpa_synth_init_float(void); +void ff_mpa_synth_init_fixed(void); void ff_mpadsp_apply_window_float(float *synth_buf, float *window, int *dither_state, float *samples, @@ -82,9 +83,6 @@ void ff_imdct36_blocks_float(float *out, float *buf, float *in, void ff_imdct36_blocks_fixed(int *out, int *buf, int *in, int count, int switch_point, int block_type); -void ff_init_mpadsp_tabs_float(void); -void ff_init_mpadsp_tabs_fixed(void); - /** For SSE implementation, MDCT_BUF_SIZE/2 should be 128-bit aligned */ #define MDCT_BUF_SIZE FFALIGN(36, 2*4) diff --git a/libavcodec/mpegaudiodsp_template.c b/libavcodec/mpegaudiodsp_template.c index e531f8a90..97317967a 100644 --- a/libavcodec/mpegaudiodsp_template.c +++ b/libavcodec/mpegaudiodsp_template.c @@ -22,6 +22,9 @@ #include "libavutil/attributes.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" + #include "dct32.h" #include "mathops.h" #include "mpegaudiodsp.h" @@ -192,7 +195,7 @@ void RENAME(ff_mpa_synth_filter)(MPADSPContext *s, MPA_INT *synth_buf_ptr, *synth_buf_offset = offset; } -av_cold void RENAME(ff_mpa_synth_init)(MPA_INT *window) +static av_cold void mpa_synth_init(MPA_INT *window) { int i, j; @@ -221,48 +224,17 @@ av_cold void RENAME(ff_mpa_synth_init)(MPA_INT *window) window[512+128+16*i+j] = window[64*i+48-j]; } -av_cold void RENAME(ff_init_mpadsp_tabs)(void) +static av_cold void mpa_synth_window_init(void) { - int i, j; - /* compute mdct windows */ - for (i = 0; i < 36; i++) { - for (j = 0; j < 4; j++) { - double d; - - if (j == 2 && i % 3 != 1) - continue; - - d = sin(M_PI * (i + 0.5) / 36.0); - if (j == 1) { - if (i >= 30) d = 0; - else if (i >= 24) d = sin(M_PI * (i - 18 + 0.5) / 12.0); - else if (i >= 18) d = 1; - } else if (j == 3) { - if (i < 6) d = 0; - else if (i < 12) d = sin(M_PI * (i - 6 + 0.5) / 12.0); - else if (i < 18) d = 1; - } - //merge last stage of imdct into the window coefficients - d *= 0.5 * IMDCT_SCALAR / cos(M_PI * (2 * i + 19) / 72); - - if (j == 2) - RENAME(ff_mdct_win)[j][i/3] = FIXHR((d / (1<<5))); - else { - int idx = i < 18 ? i : i + (MDCT_BUF_SIZE/2 - 18); - RENAME(ff_mdct_win)[j][idx] = FIXHR((d / (1<<5))); - } - } - } - - /* NOTE: we do frequency inversion adter the MDCT by changing - the sign of the right window coefs */ - for (j = 0; j < 4; j++) { - for (i = 0; i < MDCT_BUF_SIZE; i += 2) { - RENAME(ff_mdct_win)[j + 4][i ] = RENAME(ff_mdct_win)[j][i ]; - RENAME(ff_mdct_win)[j + 4][i + 1] = -RENAME(ff_mdct_win)[j][i + 1]; - } - } + mpa_synth_init(RENAME(ff_mpa_synth_window)); } + +av_cold void RENAME(ff_mpa_synth_init)(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, mpa_synth_window_init); +} + /* cos(pi*i/18) */ #define C1 FIXHR(0.98480775301220805936/2) #define C2 FIXHR(0.93969262078590838405/2) diff --git a/libavcodec/mpegpicture.c b/libavcodec/mpegpicture.c index 5fce25ec6..0652b7c87 100644 --- a/libavcodec/mpegpicture.c +++ b/libavcodec/mpegpicture.c @@ -78,20 +78,18 @@ int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, // at uvlinesize. It supports only YUV420 so 24x24 is enough // linesize * interlaced * MBsize // we also use this buffer for encoding in encode_mb_internal() needig an additional 32 lines - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, sc->edge_emu_buffer, alloc_size, EMU_EDGE_HEIGHT, - fail); + if (!FF_ALLOCZ_TYPED_ARRAY(sc->edge_emu_buffer, alloc_size * EMU_EDGE_HEIGHT) || + !FF_ALLOCZ_TYPED_ARRAY(me->scratchpad, alloc_size * 4 * 16 * 2)) { + av_freep(&sc->edge_emu_buffer); + return AVERROR(ENOMEM); + } - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, me->scratchpad, alloc_size, 4 * 16 * 2, - fail) me->temp = me->scratchpad; sc->rd_scratchpad = me->scratchpad; sc->b_scratchpad = me->scratchpad; sc->obmc_scratchpad = me->scratchpad + 16; return 0; -fail: - av_freep(&sc->edge_emu_buffer); - return AVERROR(ENOMEM); } /** @@ -208,9 +206,6 @@ static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encodin } if (out_format == FMT_H263 || encoding || -#if FF_API_DEBUG_MV - avctx->debug_mv || -#endif (avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) { int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t); int ref_index_size = 4 * mb_array_size; @@ -225,6 +220,7 @@ static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encodin pic->alloc_mb_width = mb_width; pic->alloc_mb_height = mb_height; + pic->alloc_mb_stride = mb_stride; return 0; } @@ -320,30 +316,22 @@ void ff_mpeg_unref_picture(AVCodecContext *avctx, Picture *pic) int ff_update_picture_tables(Picture *dst, Picture *src) { - int i; + int i, ret; -#define UPDATE_TABLE(table) \ -do { \ - if (src->table && \ - (!dst->table || dst->table->buffer != src->table->buffer)) { \ - av_buffer_unref(&dst->table); \ - dst->table = av_buffer_ref(src->table); \ - if (!dst->table) { \ - ff_free_picture_tables(dst); \ - return AVERROR(ENOMEM); \ - } \ - } \ -} while (0) - - UPDATE_TABLE(mb_var_buf); - UPDATE_TABLE(mc_mb_var_buf); - UPDATE_TABLE(mb_mean_buf); - UPDATE_TABLE(mbskip_table_buf); - UPDATE_TABLE(qscale_table_buf); - UPDATE_TABLE(mb_type_buf); + ret = av_buffer_replace(&dst->mb_var_buf, src->mb_var_buf); + ret |= av_buffer_replace(&dst->mc_mb_var_buf, src->mc_mb_var_buf); + ret |= av_buffer_replace(&dst->mb_mean_buf, src->mb_mean_buf); + ret |= av_buffer_replace(&dst->mbskip_table_buf, src->mbskip_table_buf); + ret |= av_buffer_replace(&dst->qscale_table_buf, src->qscale_table_buf); + ret |= av_buffer_replace(&dst->mb_type_buf, src->mb_type_buf); for (i = 0; i < 2; i++) { - UPDATE_TABLE(motion_val_buf[i]); - UPDATE_TABLE(ref_index_buf[i]); + ret |= av_buffer_replace(&dst->motion_val_buf[i], src->motion_val_buf[i]); + ret |= av_buffer_replace(&dst->ref_index_buf[i], src->ref_index_buf[i]); + } + + if (ret < 0) { + ff_free_picture_tables(dst); + return ret; } dst->mb_var = src->mb_var; @@ -359,6 +347,7 @@ do { \ dst->alloc_mb_width = src->alloc_mb_width; dst->alloc_mb_height = src->alloc_mb_height; + dst->alloc_mb_stride = src->alloc_mb_stride; return 0; } diff --git a/libavcodec/mpegpicture.h b/libavcodec/mpegpicture.h index 2db3d6733..4bcd66679 100644 --- a/libavcodec/mpegpicture.h +++ b/libavcodec/mpegpicture.h @@ -69,6 +69,7 @@ typedef struct Picture { int alloc_mb_width; ///< mb_width used to allocate tables int alloc_mb_height; ///< mb_height used to allocate tables + int alloc_mb_stride; ///< mb_stride used to allocate tables AVBufferRef *mb_mean_buf; uint8_t *mb_mean; ///< Table for MB luminance diff --git a/libavcodec/mpegutils.c b/libavcodec/mpegutils.c index c0ee3aae8..e5105ecc5 100644 --- a/libavcodec/mpegutils.c +++ b/libavcodec/mpegutils.c @@ -262,132 +262,4 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_ av_log(avctx, AV_LOG_DEBUG, "\n"); } } - -#if FF_API_DEBUG_MV - if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || - (avctx->debug_mv)) { - int mb_y; - int i, ret; - int h_chroma_shift, v_chroma_shift, block_height; - const int mv_sample_log2 = avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_SVQ3 ? 2 : 1; - const int mv_stride = (mb_width << mv_sample_log2) + - (avctx->codec->id == AV_CODEC_ID_H264 ? 0 : 1); - - if (low_delay) - *low_delay = 0; // needed to see the vectors without trashing the buffers - - ret = av_pix_fmt_get_chroma_sub_sample (avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); - if (ret) - return ret; - - av_frame_make_writable(pict); - - pict->opaque = NULL; - block_height = 16 >> v_chroma_shift; - - for (mb_y = 0; mb_y < mb_height; mb_y++) { - int mb_x; - for (mb_x = 0; mb_x < mb_width; mb_x++) { - const int mb_index = mb_x + mb_y * mb_stride; - if ((avctx->debug & FF_DEBUG_VIS_QP)) { - uint64_t c = (qscale_table[mb_index] * 128 / 31) * - 0x0101010101010101ULL; - int y; - for (y = 0; y < block_height; y++) { - *(uint64_t *)(pict->data[1] + 8 * mb_x + - (block_height * mb_y + y) * - pict->linesize[1]) = c; - *(uint64_t *)(pict->data[2] + 8 * mb_x + - (block_height * mb_y + y) * - pict->linesize[2]) = c; - } - } - if ((avctx->debug & FF_DEBUG_VIS_MB_TYPE) && - motion_val[0]) { - int mb_type = mbtype_table[mb_index]; - uint64_t u,v; - int y; -#define COLOR(theta, r) \ - u = (int)(128 + r * cos(theta * M_PI / 180)); \ - v = (int)(128 + r * sin(theta * M_PI / 180)); - - - u = v = 128; - if (IS_PCM(mb_type)) { - COLOR(120, 48) - } else if ((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) || - IS_INTRA16x16(mb_type)) { - COLOR(30, 48) - } else if (IS_INTRA4x4(mb_type)) { - COLOR(90, 48) - } else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type)) { - // COLOR(120, 48) - } else if (IS_DIRECT(mb_type)) { - COLOR(150, 48) - } else if (IS_GMC(mb_type) && IS_SKIP(mb_type)) { - COLOR(170, 48) - } else if (IS_GMC(mb_type)) { - COLOR(190, 48) - } else if (IS_SKIP(mb_type)) { - // COLOR(180, 48) - } else if (!USES_LIST(mb_type, 1)) { - COLOR(240, 48) - } else if (!USES_LIST(mb_type, 0)) { - COLOR(0, 48) - } else { - av_assert2(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1)); - COLOR(300,48) - } - - u *= 0x0101010101010101ULL; - v *= 0x0101010101010101ULL; - for (y = 0; y < block_height; y++) { - *(uint64_t *)(pict->data[1] + 8 * mb_x + - (block_height * mb_y + y) * pict->linesize[1]) = u; - *(uint64_t *)(pict->data[2] + 8 * mb_x + - (block_height * mb_y + y) * pict->linesize[2]) = v; - } - - // segmentation - if (IS_8X8(mb_type) || IS_16X8(mb_type)) { - *(uint64_t *)(pict->data[0] + 16 * mb_x + 0 + - (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL; - *(uint64_t *)(pict->data[0] + 16 * mb_x + 8 + - (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL; - } - if (IS_8X8(mb_type) || IS_8X16(mb_type)) { - for (y = 0; y < 16; y++) - pict->data[0][16 * mb_x + 8 + (16 * mb_y + y) * - pict->linesize[0]] ^= 0x80; - } - if (IS_8X8(mb_type) && mv_sample_log2 >= 2) { - int dm = 1 << (mv_sample_log2 - 2); - for (i = 0; i < 4; i++) { - int sx = mb_x * 16 + 8 * (i & 1); - int sy = mb_y * 16 + 8 * (i >> 1); - int xy = (mb_x * 2 + (i & 1) + - (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1); - // FIXME bidir - int32_t *mv = (int32_t *) &motion_val[0][xy]; - if (mv[0] != mv[dm] || - mv[dm * mv_stride] != mv[dm * (mv_stride + 1)]) - for (y = 0; y < 8; y++) - pict->data[0][sx + 4 + (sy + y) * pict->linesize[0]] ^= 0x80; - if (mv[0] != mv[dm * mv_stride] || mv[dm] != mv[dm * (mv_stride + 1)]) - *(uint64_t *)(pict->data[0] + sx + (sy + 4) * - pict->linesize[0]) ^= 0x8080808080808080ULL; - } - } - - if (IS_INTERLACED(mb_type) && - avctx->codec->id == AV_CODEC_ID_H264) { - // hmm - } - } - if (mbskip_table) - mbskip_table[mb_index] = 0; - } - } - } -#endif } diff --git a/libavcodec/mpegutils.h b/libavcodec/mpegutils.h index 1ed21c19b..81f0b73bb 100644 --- a/libavcodec/mpegutils.h +++ b/libavcodec/mpegutils.h @@ -125,6 +125,7 @@ enum OutputFormat { FMT_H261, FMT_H263, FMT_MJPEG, + FMT_SPEEDHQ, }; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 49fd1c999..5de0719f8 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -32,6 +32,8 @@ #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/motion_vector.h" +#include "libavutil/video_enc_params.h" + #include "avcodec.h" #include "blockdsp.h" #include "h264chroma.h" @@ -364,33 +366,28 @@ static int init_duplicate_context(MpegEncContext *s) if (s->mb_height & 1) yc_size += 2*s->b8_stride + 2*s->mb_stride; - s->sc.edge_emu_buffer = - s->me.scratchpad = - s->me.temp = - s->sc.rd_scratchpad = - s->sc.b_scratchpad = - s->sc.obmc_scratchpad = NULL; - if (s->encoding) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->me.map, - ME_MAP_SIZE * sizeof(uint32_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->me.score_map, - ME_MAP_SIZE * sizeof(uint32_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->me.map, ME_MAP_SIZE) || + !FF_ALLOCZ_TYPED_ARRAY(s->me.score_map, ME_MAP_SIZE)) + return AVERROR(ENOMEM); + if (s->noise_reduction) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_error_sum, - 2 * 64 * sizeof(int), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_error_sum, 2)) + return AVERROR(ENOMEM); } } - FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64 * 12 * 2 * sizeof(int16_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->blocks, 2)) + return AVERROR(ENOMEM); s->block = s->blocks[0]; for (i = 0; i < 12; i++) { s->pblocks[i] = &s->block[i]; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->block32, sizeof(*s->block32), fail) + if (!(s->block32 = av_mallocz(sizeof(*s->block32))) || + !(s->dpcm_macroblock = av_mallocz(sizeof(*s->dpcm_macroblock)))) + return AVERROR(ENOMEM); s->dpcm_direction = 0; - FF_ALLOCZ_OR_GOTO(s->avctx, s->dpcm_macroblock, sizeof(*s->dpcm_macroblock), fail) if (s->avctx->codec_tag == AV_RL32("VCR2")) { // exchange uv @@ -399,16 +396,43 @@ static int init_duplicate_context(MpegEncContext *s) if (s->out_format == FMT_H263) { /* ac values */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_val_base, - yc_size * sizeof(int16_t) * 16, fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->ac_val_base, yc_size)) + return AVERROR(ENOMEM); s->ac_val[0] = s->ac_val_base + s->b8_stride + 1; s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1; s->ac_val[2] = s->ac_val[1] + c_size; } return 0; -fail: - return AVERROR(ENOMEM); // free() through ff_mpv_common_end() +} + +/** + * Initialize an MpegEncContext's thread contexts. Presumes that + * slice_context_count is already set and that all the fields + * that are freed/reset in free_duplicate_context() are NULL. + */ +static int init_duplicate_contexts(MpegEncContext *s) +{ + int nb_slices = s->slice_context_count, ret; + + /* We initialize the copies before the original so that + * fields allocated in init_duplicate_context are NULL after + * copying. This prevents double-frees upon allocation error. */ + for (int i = 1; i < nb_slices; i++) { + s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); + if (!s->thread_context[i]) + return AVERROR(ENOMEM); + if ((ret = init_duplicate_context(s->thread_context[i])) < 0) + return ret; + s->thread_context[i]->start_mb_y = + (s->mb_height * (i ) + nb_slices / 2) / nb_slices; + s->thread_context[i]->end_mb_y = + (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; + } + s->start_mb_y = 0; + s->end_mb_y = nb_slices > 1 ? (s->mb_height + nb_slices / 2) / nb_slices + : s->mb_height; + return init_duplicate_context(s); } static void free_duplicate_context(MpegEncContext *s) @@ -433,6 +457,15 @@ static void free_duplicate_context(MpegEncContext *s) s->block = NULL; } +static void free_duplicate_contexts(MpegEncContext *s) +{ + for (int i = 1; i < s->slice_context_count; i++) { + free_duplicate_context(s->thread_context[i]); + av_freep(&s->thread_context[i]); + } + free_duplicate_context(s); +} + static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src) { #define COPY(a) bak->a = src->a @@ -522,7 +555,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, } if (s->height != s1->height || s->width != s1->width || s->context_reinit) { - s->context_reinit = 0; s->height = s1->height; s->width = s1->width; if ((ret = ff_mpv_common_frame_size_change(s)) < 0) @@ -660,17 +692,14 @@ void ff_mpv_common_defaults(MpegEncContext *s) } /** - * Set the given MpegEncContext to defaults for decoding. + * Initialize the given MpegEncContext for decoding. * the changed fields will not depend upon * the prior state of the MpegEncContext. */ -void ff_mpv_decode_defaults(MpegEncContext *s) -{ - ff_mpv_common_defaults(s); -} - void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx) { + ff_mpv_common_defaults(s); + s->avctx = avctx; s->width = avctx->coded_width; s->height = avctx->coded_height; @@ -715,8 +744,8 @@ static int init_context_frame(MpegEncContext *s) if (s->mb_height & 1) yc_size += 2*s->b8_stride + 2*s->mb_stride; - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int), - fail); // error resilience code looks cleaner with this + if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_index2xy, s->mb_num + 1)) + return AVERROR(ENOMEM); for (y = 0; y < s->mb_height; y++) for (x = 0; x < s->mb_width; x++) s->mb_index2xy[x + y * s->mb_width] = x + y * s->mb_stride; @@ -725,12 +754,13 @@ static int init_context_frame(MpegEncContext *s) if (s->encoding) { /* Allocate MV tables */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->p_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_forw_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_back_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_forw_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_back_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_direct_mv_table_base, mv_table_size)) + return AVERROR(ENOMEM); s->p_mv_table = s->p_mv_table_base + s->mb_stride + 1; s->b_forw_mv_table = s->b_forw_mv_table_base + s->mb_stride + 1; s->b_back_mv_table = s->b_back_mv_table_base + s->mb_stride + 1; @@ -739,15 +769,11 @@ static int init_context_frame(MpegEncContext *s) s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1; /* Allocate MB type table */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type, mb_array_size * sizeof(uint16_t), fail) // needed for encoding - - FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail) - - FF_ALLOC_OR_GOTO(s->avctx, s->cplx_tab, - mb_array_size * sizeof(float), fail); - FF_ALLOC_OR_GOTO(s->avctx, s->bits_tab, - mb_array_size * sizeof(float), fail); - + if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type, mb_array_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size) || + !FF_ALLOC_TYPED_ARRAY (s->cplx_tab, mb_array_size) || + !FF_ALLOC_TYPED_ARRAY (s->bits_tab, mb_array_size)) + return AVERROR(ENOMEM); } if (s->codec_id == AV_CODEC_ID_MPEG4 || @@ -757,34 +783,34 @@ static int init_context_frame(MpegEncContext *s) int j, k; for (j = 0; j < 2; j++) { for (k = 0; k < 2; k++) { - FF_ALLOCZ_OR_GOTO(s->avctx, - s->b_field_mv_table_base[i][j][k], - mv_table_size * 2 * sizeof(int16_t), - fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_mv_table_base[i][j][k], mv_table_size)) + return AVERROR(ENOMEM); s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + s->mb_stride + 1; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], mb_array_size * 2 * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], mv_table_size * 2 * sizeof(int16_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_select_table [i][j], mv_table_size * 2) || + !FF_ALLOCZ_TYPED_ARRAY(s->p_field_mv_table_base[i][j], mv_table_size)) + return AVERROR(ENOMEM); s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + s->mb_stride + 1; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], mb_array_size * 2 * sizeof(uint8_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_select_table[i], mv_table_size * 2)) + return AVERROR(ENOMEM); } } if (s->out_format == FMT_H263) { - /* cbp values */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->coded_block_base, y_size + (s->mb_height&1)*2*s->b8_stride, fail); + /* cbp values, cbp, ac_pred, pred_dir */ + if (!FF_ALLOCZ_TYPED_ARRAY(s->coded_block_base, y_size + (s->mb_height&1)*2*s->b8_stride) || + !FF_ALLOCZ_TYPED_ARRAY(s->cbp_table, mb_array_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->pred_dir_table, mb_array_size)) + return AVERROR(ENOMEM); s->coded_block = s->coded_block_base + s->b8_stride + 1; - - /* cbp, ac_pred, pred_dir */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table , mb_array_size * sizeof(uint8_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size * sizeof(uint8_t), fail); } if (s->h263_pred || s->h263_plus || !s->encoding) { /* dc values */ // MN: we need these for error resilience of intra-frames - FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->dc_val_base, yc_size)) + return AVERROR(ENOMEM); s->dc_val[0] = s->dc_val_base + s->b8_stride + 1; s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1; s->dc_val[2] = s->dc_val[1] + c_size; @@ -792,17 +818,14 @@ static int init_context_frame(MpegEncContext *s) s->dc_val_base[i] = 1024; } - /* which mb is an intra block */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mbintra_table, mb_array_size, fail); + /* which mb is an intra block, init macroblock skip table */ + if (!FF_ALLOC_TYPED_ARRAY(s->mbintra_table, mb_array_size) || + // Note the + 1 is for a quicker MPEG-4 slice_end detection + !FF_ALLOCZ_TYPED_ARRAY(s->mbskip_table, mb_array_size + 2)) + return AVERROR(ENOMEM); memset(s->mbintra_table, 1, mb_array_size); - /* init macroblock skip table */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size + 2, fail); - // Note the + 1 is for a quicker MPEG-4 slice_end detection - return ff_mpeg_er_init(s); -fail: - return AVERROR(ENOMEM); } static void clear_context(MpegEncContext *s) @@ -934,57 +957,34 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) if (ret) return ret; - FF_ALLOCZ_OR_GOTO(s->avctx, s->picture, - MAX_PICTURE_COUNT * sizeof(Picture), fail_nomem); + if (!FF_ALLOCZ_TYPED_ARRAY(s->picture, MAX_PICTURE_COUNT)) + return AVERROR(ENOMEM); for (i = 0; i < MAX_PICTURE_COUNT; i++) { s->picture[i].f = av_frame_alloc(); if (!s->picture[i].f) goto fail_nomem; } - s->next_picture.f = av_frame_alloc(); - if (!s->next_picture.f) - goto fail_nomem; - s->last_picture.f = av_frame_alloc(); - if (!s->last_picture.f) - goto fail_nomem; - s->current_picture.f = av_frame_alloc(); - if (!s->current_picture.f) - goto fail_nomem; - s->new_picture.f = av_frame_alloc(); - if (!s->new_picture.f) + + if (!(s->next_picture.f = av_frame_alloc()) || + !(s->last_picture.f = av_frame_alloc()) || + !(s->current_picture.f = av_frame_alloc()) || + !(s->new_picture.f = av_frame_alloc())) goto fail_nomem; if ((ret = init_context_frame(s))) - goto fail_nomem; + goto fail; s->parse_context.state = -1; s->context_initialized = 1; memset(s->thread_context, 0, sizeof(s->thread_context)); s->thread_context[0] = s; + s->slice_context_count = nb_slices; // if (s->width && s->height) { - if (nb_slices > 1) { - for (i = 0; i < nb_slices; i++) { - if (i) { - s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); - if (!s->thread_context[i]) - goto fail_nomem; - } - if ((ret = init_duplicate_context(s->thread_context[i])) < 0) - goto fail; - s->thread_context[i]->start_mb_y = - (s->mb_height * (i) + nb_slices / 2) / nb_slices; - s->thread_context[i]->end_mb_y = - (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; - } - } else { - if ((ret = init_duplicate_context(s)) < 0) - goto fail; - s->start_mb_y = 0; - s->end_mb_y = s->mb_height; - } - s->slice_context_count = nb_slices; + ret = init_duplicate_contexts(s); + if (ret < 0) + goto fail; // } return 0; @@ -996,7 +996,8 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) } /** - * Frees and resets MpegEncContext fields depending on the resolution. + * Frees and resets MpegEncContext fields depending on the resolution + * as well as the slice thread contexts. * Is used during resolution changes to avoid a full reinitialization of the * codec. */ @@ -1004,6 +1005,8 @@ static void free_context_frame(MpegEncContext *s) { int i, j, k; + free_duplicate_contexts(s); + av_freep(&s->mb_type); av_freep(&s->p_mv_table_base); av_freep(&s->b_forw_mv_table_base); @@ -1056,16 +1059,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) if (!s->context_initialized) return AVERROR(EINVAL); - if (s->slice_context_count > 1) { - for (i = 0; i < s->slice_context_count; i++) { - free_duplicate_context(s->thread_context[i]); - } - for (i = 1; i < s->slice_context_count; i++) { - av_freep(&s->thread_context[i]); - } - } else - free_duplicate_context(s); - free_context_frame(s); if (s->picture) @@ -1087,6 +1080,13 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) (err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) goto fail; + /* set chroma shifts */ + err = av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, + &s->chroma_x_shift, + &s->chroma_y_shift); + if (err < 0) + goto fail; + if ((err = init_context_frame(s))) goto fail; @@ -1094,36 +1094,16 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) s->thread_context[0] = s; if (s->width && s->height) { - int nb_slices = s->slice_context_count; - if (nb_slices > 1) { - for (i = 0; i < nb_slices; i++) { - if (i) { - s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); - if (!s->thread_context[i]) { - err = AVERROR(ENOMEM); - goto fail; - } - } - if ((err = init_duplicate_context(s->thread_context[i])) < 0) - goto fail; - s->thread_context[i]->start_mb_y = - (s->mb_height * (i) + nb_slices / 2) / nb_slices; - s->thread_context[i]->end_mb_y = - (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; - } - } else { - err = init_duplicate_context(s); - if (err < 0) - goto fail; - s->start_mb_y = 0; - s->end_mb_y = s->mb_height; - } - s->slice_context_count = nb_slices; + err = init_duplicate_contexts(s); + if (err < 0) + goto fail; } + s->context_reinit = 0; return 0; fail: - ff_mpv_common_end(s); + free_context_frame(s); + s->context_reinit = 1; return err; } @@ -1133,17 +1113,11 @@ void ff_mpv_common_end(MpegEncContext *s) int i; if (!s) - return ; + return; - if (s->slice_context_count > 1) { - for (i = 0; i < s->slice_context_count; i++) { - free_duplicate_context(s->thread_context[i]); - } - for (i = 1; i < s->slice_context_count; i++) { - av_freep(&s->thread_context[i]); - } + free_context_frame(s); + if (s->slice_context_count > 1) s->slice_context_count = 1; - } else free_duplicate_context(s); av_freep(&s->parse_context.buffer); s->parse_context.buffer_size = 0; @@ -1151,6 +1125,9 @@ void ff_mpv_common_end(MpegEncContext *s) av_freep(&s->bitstream_buffer); s->allocated_bitstream_buffer_size = 0; + if (!s->avctx) + return; + if (s->picture) { for (i = 0; i < MAX_PICTURE_COUNT; i++) { ff_free_picture_tables(&s->picture[i]); @@ -1172,9 +1149,8 @@ void ff_mpv_common_end(MpegEncContext *s) ff_mpeg_unref_picture(s->avctx, &s->new_picture); av_frame_free(&s->new_picture.f); - free_context_frame(s); - s->context_initialized = 0; + s->context_reinit = 0; s->last_picture_ptr = s->next_picture_ptr = s->current_picture_ptr = NULL; @@ -1443,14 +1419,33 @@ void ff_print_debug_info(MpegEncContext *s, Picture *p, AVFrame *pict) int ff_mpv_export_qp_table(MpegEncContext *s, AVFrame *f, Picture *p, int qp_type) { - AVBufferRef *ref = av_buffer_ref(p->qscale_table_buf); - int offset = 2*s->mb_stride + 1; - if(!ref) + AVVideoEncParams *par; + int mult = (qp_type == FF_QSCALE_TYPE_MPEG1) ? 2 : 1; + unsigned int nb_mb = p->alloc_mb_height * p->alloc_mb_width; + unsigned int x, y; + + if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS)) + return 0; + + par = av_video_enc_params_create_side_data(f, AV_VIDEO_ENC_PARAMS_MPEG2, nb_mb); + if (!par) return AVERROR(ENOMEM); - av_assert0(ref->size >= offset + s->mb_stride * ((f->height+15)/16)); - ref->size -= offset; - ref->data += offset; - return av_frame_set_qp_table(f, ref, s->mb_stride, qp_type); + + for (y = 0; y < p->alloc_mb_height; y++) + for (x = 0; x < p->alloc_mb_width; x++) { + const unsigned int block_idx = y * p->alloc_mb_width + x; + const unsigned int mb_xy = y * p->alloc_mb_stride + x; + AVVideoBlockParams *b = av_video_enc_params_block(par, block_idx); + + b->src_x = x * 16; + b->src_y = y * 16; + b->w = 16; + b->h = 16; + + b->delta_qp = p->qscale_table[mb_xy] * mult; + } + + return 0; } static inline int hpel_motion_lowres(MpegEncContext *s, diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 29e692f24..5a99c1965 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -276,7 +276,7 @@ typedef struct MpegEncContext { int mv[2][4][2]; int field_select[2][2]; int last_mv[2][2][2]; ///< last MV, used for MV prediction in MPEG-1 & B-frame MPEG-4 - uint8_t *fcode_tab; ///< smallest fcode needed for each MV + const uint8_t *fcode_tab; ///< smallest fcode needed for each MV int16_t direct_scale_mv[2][64]; ///< precomputed to avoid divisions in ff_mpeg4_set_direct_mv MotionEstContext me; @@ -369,7 +369,9 @@ typedef struct MpegEncContext { uint8_t *mb_info_ptr; int mb_info_size; int ehc_mode; +#if FF_API_MPV_RC_STRATEGY int rc_strategy; ///< deprecated +#endif /* H.263+ specific */ int umvplus; ///< == H.263+ && unrestricted_mv @@ -444,6 +446,9 @@ typedef struct MpegEncContext { int inter_intra_pred; int mspel; + /* SpeedHQ specific */ + int slice_start; + /* decompression specific */ GetBitContext gb; @@ -612,6 +617,14 @@ typedef struct MpegEncContext { #ifndef FF_MPV_OFFSET #define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x) #endif +#if FF_API_MPV_RC_STRATEGY +#define FF_MPV_RC_STRATEGY_OPTS \ +{"rc_strategy", "ratecontrol method", FF_MPV_OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED, "rc_strategy" }, \ + { "ffmpeg", "deprecated, does nothing", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED, "rc_strategy" }, \ + { "xvid", "deprecated, does nothing", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED, "rc_strategy" }, +#else +#define FF_MPV_RC_STRATEGY_OPTS +#endif #define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) #define FF_MPV_COMMON_OPTS \ FF_MPV_OPT_CMP_FUNC, \ @@ -645,9 +658,6 @@ FF_MPV_OPT_CMP_FUNC, \ {"lmax", "maximum Lagrange factor (VBR)", FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \ {"ibias", "intra quant bias", FF_MPV_OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ {"pbias", "inter quant bias", FF_MPV_OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ -{"rc_strategy", "ratecontrol method", FF_MPV_OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED, "rc_strategy" }, \ - { "ffmpeg", "deprecated, does nothing", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED, "rc_strategy" }, \ - { "xvid", "deprecated, does nothing", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED, "rc_strategy" }, \ {"motion_est", "motion estimation algorithm", FF_MPV_OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, "motion_est" }, \ { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \ { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \ @@ -668,6 +678,7 @@ FF_MPV_OPT_CMP_FUNC, \ {"mepre", "pre motion estimation", FF_MPV_OFFSET(me_pre), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ {"intra_penalty", "Penalty for intra blocks in block decision", FF_MPV_OFFSET(intra_penalty), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX/2, FF_MPV_OPT_FLAGS }, \ {"a53cc", "Use A53 Closed Captions (if available)", FF_MPV_OFFSET(a53_cc), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FF_MPV_OPT_FLAGS }, \ +FF_MPV_RC_STRATEGY_OPTS extern const AVOption ff_mpv_generic_options[]; @@ -691,7 +702,6 @@ void ff_mpv_common_init_mips(MpegEncContext *s); int ff_mpv_common_frame_size_change(MpegEncContext *s); void ff_mpv_common_end(MpegEncContext *s); -void ff_mpv_decode_defaults(MpegEncContext *s); void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx); void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]); void ff_mpv_report_decode_progress(MpegEncContext *s); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index d1e2bd997..eb13d57d2 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -36,8 +36,10 @@ #include "libavutil/internal.h" #include "libavutil/intmath.h" #include "libavutil/mathematics.h" +#include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "libavutil/opt.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "dct.h" #include "idctdsp.h" @@ -51,6 +53,7 @@ #include "mathops.h" #include "mpegutils.h" #include "mjpegenc.h" +#include "speedhqenc.h" #include "msmpeg4.h" #include "pixblockdsp.h" #include "qpeldsp.h" @@ -64,7 +67,6 @@ #include "wmv2.h" #include "rv10.h" #include "packet_internal.h" -#include "libxvid.h" #include #include "sp5x.h" @@ -247,18 +249,24 @@ static void update_duplicate_context_after_me(MpegEncContext *dst, #undef COPY } +static void mpv_encode_init_static(void) +{ + for (int i = -16; i < 16; i++) + default_fcode_tab[i + MAX_MV] = 1; +} + /** * Set the given MpegEncContext to defaults for encoding. * the changed fields will not depend upon the prior state of the MpegEncContext. */ static void mpv_encode_defaults(MpegEncContext *s) { - int i; + static AVOnce init_static_once = AV_ONCE_INIT; + ff_mpv_common_defaults(s); - for (i = -16; i < 16; i++) { - default_fcode_tab[i + MAX_MV] = 1; - } + ff_thread_once(&init_static_once, mpv_encode_init_static); + s->me.mv_penalty = default_mv_penalty; s->fcode_tab = default_fcode_tab; @@ -326,6 +334,15 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } break; + case AV_CODEC_ID_SPEEDHQ: + if (avctx->pix_fmt != AV_PIX_FMT_YUV420P && + avctx->pix_fmt != AV_PIX_FMT_YUV422P && + avctx->pix_fmt != AV_PIX_FMT_YUV444P) { + av_log(avctx, AV_LOG_ERROR, + "only YUV420/YUV422/YUV444 are supported (no alpha support yet)\n"); + return AVERROR(EINVAL); + } + break; default: if (avctx->pix_fmt != AV_PIX_FMT_YUV420P) { av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n"); @@ -418,16 +435,16 @@ FF_ENABLE_DEPRECATION_WARNINGS /* Fixed QSCALE */ s->fixed_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE); - s->adaptive_quant = (s->avctx->lumi_masking || - s->avctx->dark_masking || - s->avctx->temporal_cplx_masking || - s->avctx->spatial_cplx_masking || - s->avctx->p_masking || + s->adaptive_quant = (avctx->lumi_masking || + avctx->dark_masking || + avctx->temporal_cplx_masking || + avctx->spatial_cplx_masking || + avctx->p_masking || s->border_masking || (s->mpv_flags & FF_MPV_FLAG_QP_RD)) && !s->fixed_qscale; - s->loop_filter = !!(s->avctx->flags & AV_CODEC_FLAG_LOOP_FILTER); + s->loop_filter = !!(avctx->flags & AV_CODEC_FLAG_LOOP_FILTER); if (avctx->rc_max_rate && !avctx->rc_buffer_size) { switch(avctx->codec_id) { @@ -497,25 +514,25 @@ FF_ENABLE_DEPRECATION_WARNINGS avctx->bit_rate_tolerance = 5 * avctx->bit_rate * av_q2d(avctx->time_base); } - if (s->avctx->rc_max_rate && - s->avctx->rc_min_rate == s->avctx->rc_max_rate && + if (avctx->rc_max_rate && + avctx->rc_min_rate == avctx->rc_max_rate && (s->codec_id == AV_CODEC_ID_MPEG1VIDEO || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) && 90000LL * (avctx->rc_buffer_size - 1) > - s->avctx->rc_max_rate * 0xFFFFLL) { + avctx->rc_max_rate * 0xFFFFLL) { av_log(avctx, AV_LOG_INFO, "Warning vbv_delay will be set to 0xFFFF (=VBR) as the " "specified vbv buffer is too large for the given bitrate!\n"); } - if ((s->avctx->flags & AV_CODEC_FLAG_4MV) && s->codec_id != AV_CODEC_ID_MPEG4 && + if ((avctx->flags & AV_CODEC_FLAG_4MV) && s->codec_id != AV_CODEC_ID_MPEG4 && s->codec_id != AV_CODEC_ID_H263 && s->codec_id != AV_CODEC_ID_H263P && s->codec_id != AV_CODEC_ID_FLV1) { av_log(avctx, AV_LOG_ERROR, "4MV not supported by codec\n"); return AVERROR(EINVAL); } - if (s->obmc && s->avctx->mb_decision != FF_MB_DECISION_SIMPLE) { + if (s->obmc && avctx->mb_decision != FF_MB_DECISION_SIMPLE) { av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with simple mb decision\n"); return AVERROR(EINVAL); @@ -601,7 +618,7 @@ FF_ENABLE_DEPRECATION_WARNINGS return AVERROR(EINVAL); } - if ((s->avctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME)) && + if ((avctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME)) && s->codec_id != AV_CODEC_ID_MPEG4 && s->codec_id != AV_CODEC_ID_MPEG2VIDEO) { av_log(avctx, AV_LOG_ERROR, "interlacing not supported by codec\n"); return AVERROR(EINVAL); @@ -610,7 +627,7 @@ FF_ENABLE_DEPRECATION_WARNINGS #if FF_API_PRIVATE_OPT FF_DISABLE_DEPRECATION_WARNINGS if (avctx->mpeg_quant) - s->mpeg_quant = avctx->mpeg_quant; + s->mpeg_quant = 1; FF_ENABLE_DEPRECATION_WARNINGS #endif @@ -628,7 +645,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } if ((s->mpv_flags & FF_MPV_FLAG_QP_RD) && - s->avctx->mb_decision != FF_MB_DECISION_RD) { + avctx->mb_decision != FF_MB_DECISION_RD) { av_log(avctx, AV_LOG_ERROR, "QP RD needs mbd=2\n"); return AVERROR(EINVAL); } @@ -650,14 +667,14 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif if (s->scenechange_threshold < 1000000000 && - (s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP)) { + (avctx->flags & AV_CODEC_FLAG_CLOSED_GOP)) { av_log(avctx, AV_LOG_ERROR, "closed gop with scene change detection are not supported yet, " "set threshold to 1000000000\n"); return AVERROR_PATCHWELCOME; } - if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY) { + if (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) { if (s->codec_id != AV_CODEC_ID_MPEG2VIDEO && s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) { av_log(avctx, AV_LOG_ERROR, @@ -686,7 +703,7 @@ FF_ENABLE_DEPRECATION_WARNINGS return AVERROR(EINVAL); } - if (s->avctx->thread_count > 1 && + if (avctx->thread_count > 1 && s->codec_id != AV_CODEC_ID_MPEG4 && s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->codec_id != AV_CODEC_ID_MPEG2VIDEO && @@ -697,7 +714,7 @@ FF_ENABLE_DEPRECATION_WARNINGS return AVERROR_PATCHWELCOME; } - if (s->avctx->thread_count < 1) { + if (avctx->thread_count < 1) { av_log(avctx, AV_LOG_ERROR, "automatic thread number detection not supported by codec, " "patch welcome\n"); @@ -732,7 +749,7 @@ FF_ENABLE_DEPRECATION_WARNINGS //return -1; } - if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG1VIDEO || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || s->codec_id == AV_CODEC_ID_MJPEG || s->codec_id==AV_CODEC_ID_AMV) { + if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG1VIDEO || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || s->codec_id == AV_CODEC_ID_MJPEG || s->codec_id == AV_CODEC_ID_AMV || s->codec_id == AV_CODEC_ID_SPEEDHQ) { // (a + x * 3 / 8) / x s->intra_quant_bias = 3 << (QUANT_BIAS_SHIFT - 3); s->inter_quant_bias = 0; @@ -750,25 +767,25 @@ FF_ENABLE_DEPRECATION_WARNINGS av_log(avctx, AV_LOG_DEBUG, "intra_quant_bias = %d inter_quant_bias = %d\n",s->intra_quant_bias,s->inter_quant_bias); if (avctx->codec_id == AV_CODEC_ID_MPEG4 && - s->avctx->time_base.den > (1 << 16) - 1) { + avctx->time_base.den > (1 << 16) - 1) { av_log(avctx, AV_LOG_ERROR, "timebase %d/%d not supported by MPEG 4 standard, " "the maximum admitted value for the timebase denominator " - "is %d\n", s->avctx->time_base.num, s->avctx->time_base.den, + "is %d\n", avctx->time_base.num, avctx->time_base.den, (1 << 16) - 1); return AVERROR(EINVAL); } - s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; + s->time_increment_bits = av_log2(avctx->time_base.den - 1) + 1; switch (avctx->codec->id) { case AV_CODEC_ID_MPEG1VIDEO: s->out_format = FMT_MPEG1; - s->low_delay = !!(s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY); + s->low_delay = !!(avctx->flags & AV_CODEC_FLAG_LOW_DELAY); avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1); break; case AV_CODEC_ID_MPEG2VIDEO: s->out_format = FMT_MPEG1; - s->low_delay = !!(s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY); + s->low_delay = !!(avctx->flags & AV_CODEC_FLAG_LOW_DELAY); avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1); s->rtp_mode = 1; break; @@ -783,6 +800,16 @@ FF_ENABLE_DEPRECATION_WARNINGS avctx->delay = 0; s->low_delay = 1; break; + case AV_CODEC_ID_SPEEDHQ: + s->out_format = FMT_SPEEDHQ; + s->intra_only = 1; /* force intra only for SHQ */ + if (!CONFIG_SPEEDHQ_ENCODER) + return AVERROR_ENCODER_NOT_FOUND; + if ((ret = ff_speedhq_encode_init(s)) < 0) + return ret; + avctx->delay = 0; + s->low_delay = 1; + break; case AV_CODEC_ID_H261: if (!CONFIG_H261_ENCODER) return AVERROR_ENCODER_NOT_FOUND; @@ -925,27 +952,25 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_qpeldsp_init(&s->qdsp); 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); + int ac_stats_size = 2 * 2 * (MAX_LEVEL + 1) * (MAX_RUN + 1) * 2 * sizeof(int); + if (!(s->ac_stats = av_mallocz(ac_stats_size))) + return AVERROR(ENOMEM); } - 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 (!(avctx->stats_out = av_mallocz(256)) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix16, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix16, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->input_picture, MAX_PICTURE_COUNT) || + !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_PICTURE_COUNT)) + return AVERROR(ENOMEM); if (s->noise_reduction) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, - 2 * 64 * sizeof(uint16_t), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2)) + return AVERROR(ENOMEM); } ff_dct_encode_init(s); @@ -975,7 +1000,7 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif - ff_set_cmp(&s->mecc, s->mecc.ildct_cmp, s->avctx->ildct_cmp); + ff_set_cmp(&s->mecc, s->mecc.ildct_cmp, avctx->ildct_cmp); ff_set_cmp(&s->mecc, s->mecc.frame_skip_cmp, s->frame_skip_cmp); if (CONFIG_H261_ENCODER && s->out_format == FMT_H261) @@ -983,8 +1008,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) ff_h263_encode_init(s); if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version) - if ((ret = ff_msmpeg4_encode_init(s)) < 0) - return ret; + ff_msmpeg4_encode_init(s); if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) && s->out_format == FMT_MPEG1) ff_mpeg1_encode_init(s); @@ -999,16 +1023,19 @@ FF_ENABLE_DEPRECATION_WARNINGS } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) { s->intra_matrix[j] = s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; + } else if (CONFIG_SPEEDHQ_ENCODER && s->codec_id == AV_CODEC_ID_SPEEDHQ) { + s->intra_matrix[j] = + s->inter_matrix[j] = ff_mpeg1_default_intra_matrix[i]; } else { /* MPEG-1/2 */ s->chroma_intra_matrix[j] = s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i]; s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; } - if (s->avctx->intra_matrix) - s->intra_matrix[j] = s->avctx->intra_matrix[i]; - if (s->avctx->inter_matrix) - s->inter_matrix[j] = s->avctx->inter_matrix[i]; + if (avctx->intra_matrix) + s->intra_matrix[j] = avctx->intra_matrix[i]; + if (avctx->inter_matrix) + s->inter_matrix[j] = avctx->inter_matrix[i]; } /* precompute matrix */ @@ -1060,8 +1087,6 @@ FF_ENABLE_DEPRECATION_WARNINGS cpb_props->buffer_size = avctx->rc_buffer_size; return 0; -fail: - return AVERROR_UNKNOWN; } av_cold int ff_mpv_encode_end(AVCodecContext *avctx) @@ -1082,9 +1107,9 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx) av_frame_free(&s->tmp_frames[i]); ff_free_picture_tables(&s->new_picture); - ff_mpeg_unref_picture(s->avctx, &s->new_picture); + ff_mpeg_unref_picture(avctx, &s->new_picture); - av_freep(&s->avctx->stats_out); + av_freep(&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); @@ -1339,23 +1364,20 @@ static int skip_check(MpegEncContext *s, Picture *p, Picture *ref) return 0; } -static int encode_frame(AVCodecContext *c, AVFrame *frame) +static int encode_frame(AVCodecContext *c, AVFrame *frame, AVPacket *pkt) { - AVPacket pkt = { 0 }; int ret; int size = 0; - av_init_packet(&pkt); - ret = avcodec_send_frame(c, frame); if (ret < 0) return ret; do { - ret = avcodec_receive_packet(c, &pkt); + ret = avcodec_receive_packet(c, pkt); if (ret >= 0) { - size += pkt.size; - av_packet_unref(&pkt); + size += pkt->size; + av_packet_unref(pkt); } else if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) return ret; } while (ret >= 0); @@ -1366,6 +1388,7 @@ static int encode_frame(AVCodecContext *c, AVFrame *frame) static int estimate_best_b_count(MpegEncContext *s) { const AVCodec *codec = avcodec_find_encoder(s->avctx->codec_id); + AVPacket *pkt; const int scale = s->brd_scale; int width = s->width >> scale; int height = s->height >> scale; @@ -1376,6 +1399,10 @@ static int estimate_best_b_count(MpegEncContext *s) av_assert0(scale >= 0 && scale <= 3); + pkt = av_packet_alloc(); + if (!pkt) + return AVERROR(ENOMEM); + //emms_c(); //s->next_picture_ptr->quality; p_lambda = s->last_lambda_for[AV_PICTURE_TYPE_P]; @@ -1427,8 +1454,10 @@ static int estimate_best_b_count(MpegEncContext *s) break; c = avcodec_alloc_context3(NULL); - if (!c) - return AVERROR(ENOMEM); + if (!c) { + ret = AVERROR(ENOMEM); + goto fail; + } c->width = width; c->height = height; @@ -1446,10 +1475,11 @@ static int estimate_best_b_count(MpegEncContext *s) if (ret < 0) goto fail; + s->tmp_frames[0]->pict_type = AV_PICTURE_TYPE_I; s->tmp_frames[0]->quality = 1 * FF_QP2LAMBDA; - out_size = encode_frame(c, s->tmp_frames[0]); + out_size = encode_frame(c, s->tmp_frames[0], pkt); if (out_size < 0) { ret = out_size; goto fail; @@ -1464,7 +1494,7 @@ static int estimate_best_b_count(MpegEncContext *s) AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B; s->tmp_frames[i + 1]->quality = is_p ? p_lambda : b_lambda; - out_size = encode_frame(c, s->tmp_frames[i + 1]); + out_size = encode_frame(c, s->tmp_frames[i + 1], pkt); if (out_size < 0) { ret = out_size; goto fail; @@ -1474,7 +1504,7 @@ static int estimate_best_b_count(MpegEncContext *s) } /* get the delayed frames */ - out_size = encode_frame(c, NULL); + out_size = encode_frame(c, NULL, pkt); if (out_size < 0) { ret = out_size; goto fail; @@ -1490,10 +1520,15 @@ static int estimate_best_b_count(MpegEncContext *s) fail: avcodec_free_context(&c); - if (ret < 0) - return ret; + av_packet_unref(pkt); + if (ret < 0) { + best_b_count = ret; + break; + } } + av_packet_free(&pkt); + return best_b_count; } @@ -1660,7 +1695,8 @@ no_output_pic: // input is not a shared pix -> reuse buffer for current_pix s->current_picture_ptr = s->reordered_input_picture[0]; for (i = 0; i < 4; i++) { - s->new_picture.f->data[i] += INPLACE_OFFSET; + if (s->new_picture.f->data[i]) + s->new_picture.f->data[i] += INPLACE_OFFSET; } } ff_mpeg_unref_picture(s->avctx, &s->current_picture); @@ -1896,7 +1932,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (avctx->rc_buffer_size) { RateControlContext *rcc = &s->rc_context; int max_size = FFMAX(rcc->buffer_index * avctx->rc_max_available_vbv_use, rcc->buffer_index - 500); - int hq = (s->avctx->mb_decision == FF_MB_DECISION_RD || s->avctx->trellis); + int hq = (avctx->mb_decision == FF_MB_DECISION_RD || avctx->trellis); int min_step = hq ? 1 : (1<<(FF_LAMBDA_SHIFT + 7))/139; if (put_bits_count(&s->pb) > max_size && @@ -1928,14 +1964,14 @@ FF_ENABLE_DEPRECATION_WARNINGS init_put_bits(pb, pb->buf, pb->buf_end - pb->buf); } s->vbv_ignore_qmax = 1; - av_log(s->avctx, AV_LOG_VERBOSE, "reencoding frame due to VBV\n"); + av_log(avctx, AV_LOG_VERBOSE, "reencoding frame due to VBV\n"); goto vbv_retry; } - av_assert0(s->avctx->rc_max_rate); + av_assert0(avctx->rc_max_rate); } - if (s->avctx->flags & AV_CODEC_FLAG_PASS1) + if (avctx->flags & AV_CODEC_FLAG_PASS1) ff_write_pass1_stats(s); for (i = 0; i < 4; i++) { @@ -1944,10 +1980,10 @@ FF_ENABLE_DEPRECATION_WARNINGS } ff_side_data_set_encoder_stats(pkt, s->current_picture.f->quality, s->current_picture_ptr->encoding_error, - (s->avctx->flags&AV_CODEC_FLAG_PSNR) ? 4 : 0, + (avctx->flags&AV_CODEC_FLAG_PSNR) ? 4 : 0, s->pict_type); - if (s->avctx->flags & AV_CODEC_FLAG_PASS1) + if (avctx->flags & AV_CODEC_FLAG_PASS1) assert(put_bits_count(&s->pb) == s->header_bits + s->mv_bits + s->misc_bits + s->i_tex_bits + s->p_tex_bits); @@ -1959,7 +1995,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (stuffing_count) { if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < stuffing_count + 50) { - av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n"); + av_log(avctx, AV_LOG_ERROR, "stuffing too large\n"); return -1; } @@ -1979,37 +2015,37 @@ FF_ENABLE_DEPRECATION_WARNINGS } break; default: - av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n"); + av_log(avctx, AV_LOG_ERROR, "vbv buffer overflow\n"); } flush_put_bits(&s->pb); s->frame_bits = put_bits_count(&s->pb); } /* update MPEG-1/2 vbv_delay for CBR */ - if (s->avctx->rc_max_rate && - s->avctx->rc_min_rate == s->avctx->rc_max_rate && + if (avctx->rc_max_rate && + avctx->rc_min_rate == avctx->rc_max_rate && s->out_format == FMT_MPEG1 && 90000LL * (avctx->rc_buffer_size - 1) <= - s->avctx->rc_max_rate * 0xFFFFLL) { + avctx->rc_max_rate * 0xFFFFLL) { AVCPBProperties *props; size_t props_size; int vbv_delay, min_delay; - double inbits = s->avctx->rc_max_rate * - av_q2d(s->avctx->time_base); + double inbits = avctx->rc_max_rate * + av_q2d(avctx->time_base); int minbits = s->frame_bits - 8 * (s->vbv_delay_ptr - s->pb.buf - 1); double bits = s->rc_context.buffer_index + minbits - inbits; if (bits < 0) - av_log(s->avctx, AV_LOG_ERROR, + av_log(avctx, AV_LOG_ERROR, "Internal error, negative bits\n"); av_assert1(s->repeat_first_field == 0); - vbv_delay = bits * 90000 / s->avctx->rc_max_rate; - min_delay = (minbits * 90000LL + s->avctx->rc_max_rate - 1) / - s->avctx->rc_max_rate; + vbv_delay = bits * 90000 / avctx->rc_max_rate; + min_delay = (minbits * 90000LL + avctx->rc_max_rate - 1) / + avctx->rc_max_rate; vbv_delay = FFMAX(vbv_delay, min_delay); @@ -2067,7 +2103,7 @@ FF_ENABLE_DEPRECATION_WARNINGS /* release non-reference frames */ for (i = 0; i < MAX_PICTURE_COUNT; i++) { if (!s->picture[i].reference) - ff_mpeg_unref_picture(s->avctx, &s->picture[i]); + ff_mpeg_unref_picture(avctx, &s->picture[i]); } av_assert1((s->frame_bits & 7) == 0); @@ -2566,6 +2602,10 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, if (CONFIG_MJPEG_ENCODER) ff_mjpeg_encode_mb(s, s->block); break; + case AV_CODEC_ID_SPEEDHQ: + if (CONFIG_SPEEDHQ_ENCODER) + ff_speedhq_encode_mb(s, s->block); + break; default: av_assert1(0); } @@ -2762,8 +2802,6 @@ static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){ static int estimate_motion_thread(AVCodecContext *c, void *arg){ MpegEncContext *s= *(void**)arg; - ff_check_alignment(); - s->me.dia_size= s->avctx->dia_size; s->first_slice_line=1; for(s->mb_y= s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { @@ -2790,8 +2828,6 @@ static int mb_var_thread(AVCodecContext *c, void *arg){ MpegEncContext *s= *(void**)arg; int mb_x, mb_y; - ff_check_alignment(); - for(mb_y=s->start_mb_y; mb_y < s->end_mb_y; mb_y++) { for(mb_x=0; mb_x < s->mb_width; mb_x++) { int xx = mb_x * 16; @@ -2820,9 +2856,10 @@ static void write_slice_end(MpegEncContext *s){ ff_mpeg4_stuffing(&s->pb); }else if(CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG){ ff_mjpeg_encode_stuffing(s); + } else if (CONFIG_SPEEDHQ_ENCODER && s->out_format == FMT_SPEEDHQ) { + ff_speedhq_end_slice(s); } - avpriv_align_put_bits(&s->pb); flush_put_bits(&s->pb); if ((s->avctx->flags & AV_CODEC_FLAG_PASS1) && !s->partitioned_frame) @@ -2910,7 +2947,7 @@ int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t s static int encode_thread(AVCodecContext *c, void *arg){ MpegEncContext *s= *(void**)arg; - int mb_x, mb_y; + int mb_x, mb_y, mb_y_order; int chr_h= 16>>s->chroma_y_shift; int i, j; MpegEncContext best_s = { 0 }, backup_s; @@ -2919,8 +2956,6 @@ static int encode_thread(AVCodecContext *c, void *arg){ uint8_t bit_buf_tex[2][MAX_MB_BYTES]; PutBitContext pb[2], pb2[2], tex_pb[2]; - ff_check_alignment(); - for(i=0; i<2; i++){ init_put_bits(&pb [i], bit_buf [i], MAX_MB_BYTES); init_put_bits(&pb2 [i], bit_buf2 [i], MAX_MB_BYTES); @@ -2971,7 +3006,16 @@ static int encode_thread(AVCodecContext *c, void *arg){ s->resync_mb_y=0; s->first_slice_line = 1; s->ptr_lastgob = s->pb.buf; - for(mb_y= s->start_mb_y; mb_y < s->end_mb_y; mb_y++) { + for (mb_y_order = s->start_mb_y; mb_y_order < s->end_mb_y; mb_y_order++) { + if (CONFIG_SPEEDHQ_ENCODER && s->codec_id == AV_CODEC_ID_SPEEDHQ) { + int first_in_slice; + mb_y = ff_speedhq_mb_y_order_to_mb(mb_y_order, s->mb_height, &first_in_slice); + if (first_in_slice && mb_y_order != s->start_mb_y) + ff_speedhq_end_slice(s); + s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 1024 << s->intra_dc_precision; + } else { + mb_y = mb_y_order; + } s->mb_x=0; s->mb_y= mb_y; @@ -3356,18 +3400,18 @@ FF_ENABLE_DEPRECATION_WARNINGS pb_bits_count= put_bits_count(&s->pb); flush_put_bits(&s->pb); - avpriv_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count); + ff_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count); s->pb= backup_s.pb; if(s->data_partitioning){ pb2_bits_count= put_bits_count(&s->pb2); flush_put_bits(&s->pb2); - avpriv_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count); + ff_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count); s->pb2= backup_s.pb2; tex_pb_bits_count= put_bits_count(&s->tex_pb); flush_put_bits(&s->tex_pb); - avpriv_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count); + ff_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count); s->tex_pb= backup_s.tex_pb; } s->last_bits= put_bits_count(&s->pb); @@ -3594,7 +3638,7 @@ static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src) av_assert1(put_bits_count(&src->pb) % 8 ==0); av_assert1(put_bits_count(&dst->pb) % 8 ==0); - avpriv_copy_bits(&dst->pb, src->pb.buf, put_bits_count(&src->pb)); + ff_copy_bits(&dst->pb, src->pb.buf, put_bits_count(&src->pb)); flush_put_bits(&dst->pb); } @@ -3846,8 +3890,8 @@ static int encode_picture(MpegEncContext *s, int picture_number) for(i=1;i<64;i++){ int j= s->idsp.idct_permutation[ff_zigzag_direct[i]]; - s->intra_matrix[j] = sp5x_quant_table[5*2+0][i]; - s->chroma_intra_matrix[j] = sp5x_quant_table[5*2+1][i]; + s->intra_matrix[j] = sp5x_qscale_five_quant_table[0][i]; + s->chroma_intra_matrix[j] = sp5x_qscale_five_quant_table[1][i]; } s->y_dc_scale_table= y; s->c_dc_scale_table= c; @@ -3860,6 +3904,11 @@ static int encode_picture(MpegEncContext *s, int picture_number) s->qscale= 8; } + if (s->out_format == FMT_SPEEDHQ) { + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg2_dc_scale_table[3]; + } + //FIXME var duplication s->current_picture_ptr->f->key_frame = s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I; //FIXME pic_ptr @@ -3877,6 +3926,10 @@ static int encode_picture(MpegEncContext *s, int picture_number) ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable, s->pred, s->intra_matrix, s->chroma_intra_matrix); break; + case FMT_SPEEDHQ: + if (CONFIG_SPEEDHQ_ENCODER) + ff_speedhq_encode_picture_header(s); + break; case FMT_H261: if (CONFIG_H261_ENCODER) ff_h261_encode_picture_header(s, picture_number); @@ -3918,7 +3971,7 @@ static int encode_picture(MpegEncContext *s, int picture_number) s->avctx->execute(s->avctx, encode_thread, &s->thread_context[0], NULL, context_count, sizeof(void*)); for(i=1; ipb.buf_end == s->thread_context[i]->pb.buf) - set_put_bits_buffer_size(&s->pb, FFMIN(s->thread_context[i]->pb.buf_end - s->pb.buf, INT_MAX/8-32)); + set_put_bits_buffer_size(&s->pb, FFMIN(s->thread_context[i]->pb.buf_end - s->pb.buf, INT_MAX/8-BUF_BITS)); merge_context_after_encode(s, s->thread_context[i]); } emms_c(); diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c index 5624c1062..427bc9688 100644 --- a/libavcodec/mpegvideo_motion.c +++ b/libavcodec/mpegvideo_motion.c @@ -21,19 +21,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include - #include "libavutil/avassert.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "h261.h" #include "mpegutils.h" #include "mpegvideo.h" -#include "mjpegenc.h" -#include "msmpeg4.h" #include "qpeldsp.h" #include "wmv2.h" -#include static void gmc1_motion(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, @@ -211,16 +208,16 @@ static inline int hpel_motion(MpegEncContext *s, dxy |= (motion_y & 1) << 1; src += src_y * s->linesize + src_x; - if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 1) - 7, 0) || - (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 1) - 7, 0)) { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src, - s->linesize, s->linesize, - 9, 9, - src_x, src_y, - s->h_edge_pos, s->v_edge_pos); - src = s->sc.edge_emu_buffer; - emu = 1; - } + if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 1) - 7, 0) || + (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 1) - 7, 0)) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src, + s->linesize, s->linesize, + 9, 9, + src_x, src_y, + s->h_edge_pos, s->v_edge_pos); + src = s->sc.edge_emu_buffer; + emu = 1; + } pix_op[dxy](dest, src, s->linesize, 8); return emu; } @@ -304,9 +301,9 @@ void mpeg_motion_internal(MpegEncContext *s, if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 1) - 15 , 0) || (unsigned)src_y >= FFMAX( v_edge_pos - (motion_y & 1) - h + 1, 0)) { - if (is_mpeg12 || - s->codec_id == AV_CODEC_ID_MPEG2VIDEO || - s->codec_id == AV_CODEC_ID_MPEG1VIDEO) { + if (is_mpeg12 || (CONFIG_SMALL && + (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); @@ -851,7 +848,7 @@ static av_always_inline void mpv_motion_internal(MpegEncContext *s, switch (s->mv_type) { case MV_TYPE_16X16: - if (s->mcsel) { + if (!is_mpeg12 && s->mcsel) { if (s->real_sprite_warping_points == 1) { gmc1_motion(s, dest_y, dest_cb, dest_cr, ref_picture); @@ -913,60 +910,63 @@ static av_always_inline void mpv_motion_internal(MpegEncContext *s, } break; case MV_TYPE_16X8: - 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) && 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], - 8, 1, (mb_y & ~1) + i); - - 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++) { - int 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); - pix_op = s->hdsp.avg_pixels_tab; - } - } else { - if (!ref_picture[0]) { - ref_picture = s->current_picture_ptr->f->data; - } + if (CONFIG_SMALL || is_mpeg12) { 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) && + ref_picture[0]) { + ref2picture = ref_picture; + } else { + ref2picture = s->current_picture_ptr->f->data; + } + mpeg_motion(s, dest_y, dest_cb, dest_cr, - s->picture_structure != i + 1, - ref_picture, pix_op, - s->mv[dir][2 * i][0], s->mv[dir][2 * i][1], - 16, 0, mb_y >> 1); + s->field_select[dir][i], + ref2picture, pix_op, + s->mv[dir][i][0], s->mv[dir][i][1], + 8, 1, (mb_y & ~1) + i); - // after put we make avg of the same block - pix_op = s->hdsp.avg_pixels_tab; - - /* opposite parity is always in the same frame if this is - * second field */ - if (!s->first_field) { + 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 (CONFIG_SMALL || is_mpeg12) { + if (s->picture_structure == PICT_FRAME) { + for (i = 0; i < 2; i++) { + for (int 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); + pix_op = s->hdsp.avg_pixels_tab; + } + } 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, + ref_picture, pix_op, + s->mv[dir][2 * i][0], s->mv[dir][2 * i][1], + 16, 0, mb_y >> 1); + + // after put we make avg of the same block + pix_op = s->hdsp.avg_pixels_tab; + + /* 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); } } diff --git a/libavcodec/mqc.h b/libavcodec/mqc.h index 8bf7223d4..73604d5ef 100644 --- a/libavcodec/mqc.h +++ b/libavcodec/mqc.h @@ -54,9 +54,6 @@ void ff_mqc_initenc(MqcState *mqc, uint8_t *bp); /** code bit d with context cx */ void ff_mqc_encode(MqcState *mqc, uint8_t *cxstate, int d); -/** number of encoded bytes */ -int ff_mqc_length(MqcState *mqc); - /** flush the encoder [returns number of bytes encoded] */ int ff_mqc_flush(MqcState *mqc); int ff_mqc_flush_to(MqcState *mqc, uint8_t *dst, int *dst_len); diff --git a/libavcodec/mqcenc.c b/libavcodec/mqcenc.c index 7c9e1a0df..c941f849d 100644 --- a/libavcodec/mqcenc.c +++ b/libavcodec/mqcenc.c @@ -102,11 +102,6 @@ void ff_mqc_encode(MqcState *mqc, uint8_t *cxstate, int d) } } -int ff_mqc_length(MqcState *mqc) -{ - return mqc->bp - mqc->bpstart; -} - int ff_mqc_flush(MqcState *mqc) { setbits(mqc); diff --git a/libavcodec/mscc.c b/libavcodec/mscc.c index 86e4e88ed..fe0264962 100644 --- a/libavcodec/mscc.c +++ b/libavcodec/mscc.c @@ -152,7 +152,7 @@ static int decode_frame(AVCodecContext *avctx, } if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { - int size; + buffer_size_t size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); if (pal && size == AVPALETTE_SIZE) { diff --git a/libavcodec/msmpeg4.h b/libavcodec/msmpeg4.h index bcdb96740..483c965b9 100644 --- a/libavcodec/msmpeg4.h +++ b/libavcodec/msmpeg4.h @@ -50,7 +50,7 @@ void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my); int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr); -int ff_msmpeg4_encode_init(MpegEncContext *s); +void ff_msmpeg4_encode_init(MpegEncContext *s); void ff_msmpeg4_encode_picture_header(MpegEncContext *s, int picture_number); void ff_msmpeg4_encode_ext_header(MpegEncContext *s); void ff_msmpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], @@ -59,7 +59,7 @@ void ff_msmpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], int ff_msmpeg4_decode_init(AVCodecContext *avctx); int ff_msmpeg4_decode_picture_header(MpegEncContext *s); int ff_msmpeg4_decode_ext_header(MpegEncContext *s, int buf_size); -int ff_msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr); +void ff_msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr); int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block, int n, int coded, const uint8_t *scan_table); int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, diff --git a/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c index b9c1d8ec0..fb0c6185b 100644 --- a/libavcodec/msmpeg4data.c +++ b/libavcodec/msmpeg4data.c @@ -1771,13 +1771,11 @@ static const uint8_t table1_mvy[1099] = { }; MVTable ff_mv_tables[2] = { - { 1099, - table0_mv_code, + { table0_mv_code, table0_mv_bits, table0_mvx, table0_mvy, }, - { 1099, - table1_mv_code, + { table1_mv_code, table1_mv_bits, table1_mvx, table1_mvy, } diff --git a/libavcodec/msmpeg4data.h b/libavcodec/msmpeg4data.h index 02199d012..68a1d14f5 100644 --- a/libavcodec/msmpeg4data.h +++ b/libavcodec/msmpeg4data.h @@ -37,7 +37,6 @@ /* motion vector table */ typedef struct MVTable { - int n; const uint16_t *table_mv_code; const uint8_t *table_mv_bits; const uint8_t *table_mvx; @@ -69,6 +68,7 @@ extern const uint8_t ff_wmv1_y_dc_scale_table[32]; extern const uint8_t ff_wmv1_c_dc_scale_table[32]; extern const uint8_t ff_old_ff_y_dc_scale_table[32]; +#define MSMPEG4_MV_TABLES_NB_ELEMS 1099 extern MVTable ff_mv_tables[2]; extern const uint8_t ff_v2_mb_type[8][2]; diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c index 16b67192b..63f9faa1b 100644 --- a/libavcodec/msmpeg4dec.c +++ b/libavcodec/msmpeg4dec.c @@ -38,7 +38,6 @@ #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 @@ -66,7 +65,6 @@ 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 H.263 except that its range is multiplied by 2. */ @@ -74,7 +72,7 @@ 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); + code = get_vlc2(&s->gb, ff_h263_mv_vlc.table, H263_MV_VLC_BITS, 2); ff_dlog(s, "MV code %d at %d %d pred: %d\n", code, s->mb_x,s->mb_y, pred); if (code < 0) return 0xffff; @@ -230,8 +228,6 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64]) } 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; @@ -239,8 +235,6 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64]) } 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++) { @@ -261,8 +255,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64]) 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; + ff_msmpeg4_decode_motion(s, &mx, &my); s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; s->mv[0][0][0] = mx; @@ -317,19 +310,22 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) for(i=0;ivlc, MV_VLC_BITS, mv->n + 1, + INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, MSMPEG4_MV_TABLES_NB_ELEMS + 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, + INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, MSMPEG4_MV_TABLES_NB_ELEMS + 1, mv->table_mv_bits, 1, 1, mv->table_mv_code, 2, 2, 2694); @@ -359,9 +355,6 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) 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, @@ -614,11 +607,6 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) } 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"); - *dir_ptr = 0; - return -1; - } if (level == DC_MAX) { level = get_bits(&s->gb, 8); @@ -840,8 +828,7 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block, return 0; } -int ff_msmpeg4_decode_motion(MpegEncContext * s, - int *mx_ptr, int *my_ptr) +void ff_msmpeg4_decode_motion(MpegEncContext *s, int *mx_ptr, int *my_ptr) { MVTable *mv; int code, mx, my; @@ -849,11 +836,7 @@ int ff_msmpeg4_decode_motion(MpegEncContext * s, 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) { + if (code == MSMPEG4_MV_TABLES_NB_ELEMS) { mx = get_bits(&s->gb, 6); my = get_bits(&s->gb, 6); } else { @@ -875,7 +858,6 @@ int ff_msmpeg4_decode_motion(MpegEncContext * s, my -= 64; *mx_ptr = mx; *my_ptr = my; - return 0; } AVCodec ff_msmpeg4v1_decoder = { diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c index 144468b24..59a18532c 100644 --- a/libavcodec/msmpeg4enc.c +++ b/libavcodec/msmpeg4enc.c @@ -32,7 +32,6 @@ #include "libavutil/attributes.h" #include "libavutil/avutil.h" -#include "libavutil/mem.h" #include "mpegvideo.h" #include "h263.h" #include "internal.h" @@ -46,25 +45,21 @@ 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 av_cold int init_mv_table(MVTable *tab) +static av_cold void init_mv_table(MVTable *tab, uint16_t table_mv_index[4096]) { int i, x, y; - tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096); - if (!tab->table_mv_index) - return AVERROR(ENOMEM); + tab->table_mv_index = table_mv_index; /* mark all entries as not used */ for(i=0;i<4096;i++) - tab->table_mv_index[i] = tab->n; + tab->table_mv_index[i] = MSMPEG4_MV_TABLES_NB_ELEMS; - for(i=0;in;i++) { + for (i = 0; i < MSMPEG4_MV_TABLES_NB_ELEMS; i++) { x = tab->table_mvx[i]; y = tab->table_mvy[i]; tab->table_mv_index[(x << 6) | y] = i; } - - return 0; } void ff_msmpeg4_code012(PutBitContext *pb, int n) @@ -118,10 +113,10 @@ static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, return size; } -av_cold int ff_msmpeg4_encode_init(MpegEncContext *s) +av_cold void ff_msmpeg4_encode_init(MpegEncContext *s) { static int init_done=0; - int i, ret; + int i; ff_msmpeg4_common_init(s); if(s->msmpeg4_version>=4){ @@ -130,12 +125,12 @@ av_cold int ff_msmpeg4_encode_init(MpegEncContext *s) } if (!init_done) { + static uint16_t mv_index_tables[2][4096]; /* init various encoding tables */ init_done = 1; - if ((ret = init_mv_table(&ff_mv_tables[0])) < 0) - return ret; - if ((ret = init_mv_table(&ff_mv_tables[1])) < 0) - return ret; + init_mv_table(&ff_mv_tables[0], mv_index_tables[0]); + init_mv_table(&ff_mv_tables[1], mv_index_tables[1]); + for(i=0;ipb); + align_put_bits(&s->pb); put_bits(&s->pb, 2, s->pict_type - 1); put_bits(&s->pb, 5, s->qscale); @@ -320,7 +313,7 @@ void ff_msmpeg4_encode_motion(MpegEncContext * s, put_bits(&s->pb, mv->table_mv_bits[code], mv->table_mv_code[code]); - if (code == mv->n) { + if (code == MSMPEG4_MV_TABLES_NB_ELEMS) { /* escape : code literally */ put_bits(&s->pb, 6, mx); put_bits(&s->pb, 6, my); diff --git a/libavcodec/msp2dec.c b/libavcodec/msp2dec.c new file mode 100644 index 000000000..16c5ac6f0 --- /dev/null +++ b/libavcodec/msp2dec.c @@ -0,0 +1,103 @@ +/* + * Microsoft Paint (MSP) version 2 decoder + * Copyright (c) 2020 Peter Ross (pross@xvid.org) + * + * 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 + * Microsoft Paint (MSP) version 2 decoder + */ + +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" + +static int msp2_decode_frame(AVCodecContext *avctx, + void *data, int *got_frame, + AVPacket *avpkt) +{ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + AVFrame *p = data; + int ret; + unsigned int x, y, width = (avctx->width + 7) / 8; + GetByteContext idx, gb; + + if (buf_size <= 2 * avctx->height) + return AVERROR_INVALIDDATA; + + avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; + + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) + return ret; + + p->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; + + bytestream2_init(&idx, buf, 2 * avctx->height); + buf += 2 * avctx->height; + buf_size -= 2 * avctx->height; + + for (y = 0; y < avctx->height; y++) { + unsigned int pkt_size = bytestream2_get_le16(&idx); + if (!pkt_size) { + memset(p->data[0] + y * p->linesize[0], 0xFF, width); + continue; + } + + if (pkt_size > buf_size) { + av_log(avctx, AV_LOG_WARNING, "image probably corrupt\n"); + pkt_size = buf_size; + } + + bytestream2_init(&gb, buf, pkt_size); + x = 0; + while (bytestream2_get_bytes_left(&gb) && x < width) { + int size = bytestream2_get_byte(&gb); + if (size) { + size = FFMIN(size, bytestream2_get_bytes_left(&gb)); + memcpy(p->data[0] + y * p->linesize[0] + x, gb.buffer, FFMIN(size, width - x)); + bytestream2_skip(&gb, size); + } else { + int value; + size = bytestream2_get_byte(&gb); + if (!size) + avpriv_request_sample(avctx, "escape value"); + value = bytestream2_get_byte(&gb); + memset(p->data[0] + y * p->linesize[0] + x, value, FFMIN(size, width - x)); + } + x += size; + } + + buf += pkt_size; + buf_size -= pkt_size; + } + + *got_frame = 1; + return buf_size; +} + +AVCodec ff_msp2_decoder = { + .name = "msp2", + .long_name = NULL_IF_CONFIG_SMALL("Microsoft Paint (MSP) version 2"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_MSP2, + .decode = msp2_decode_frame, + .capabilities = AV_CODEC_CAP_DR1, +}; diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c index 9233b34cc..feea2b60b 100644 --- a/libavcodec/msrle.c +++ b/libavcodec/msrle.c @@ -97,7 +97,7 @@ static int msrle_decode_frame(AVCodecContext *avctx, return ret; if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) { - int size; + buffer_size_t size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); if (pal && size == AVPALETTE_SIZE) { diff --git a/libavcodec/mss12.c b/libavcodec/mss12.c index 5a5bd9a91..5afdaacfe 100644 --- a/libavcodec/mss12.c +++ b/libavcodec/mss12.c @@ -291,14 +291,15 @@ static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx, return decode_pixel(acoder, pctx, ref_pix, nlen, 1); } -static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic, +static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_dst, int x, int y, int width, int height, ptrdiff_t stride, ptrdiff_t rgb_stride, PixContext *pctx, const uint32_t *pal) { int i, j, p; - uint8_t *rgb_dst = rgb_pic + x * 3 + y * rgb_stride; + rgb_stride = rgb_dst ? rgb_stride : 0; + rgb_dst = rgb_dst ? rgb_dst + x * 3 + y * rgb_stride : NULL; dst += x + y * stride; for (j = 0; j < height; j++) { @@ -312,11 +313,11 @@ static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic, return p; dst[i] = p; - if (rgb_pic) + if (rgb_dst) AV_WB24(rgb_dst + i * 3, pal[p]); } dst += stride; - rgb_dst += rgb_stride; + rgb_dst = FF_PTR_ADD(rgb_dst, rgb_stride); } return 0; @@ -476,17 +477,19 @@ static int decode_region_intra(SliceContext *sc, ArithCoder *acoder, ptrdiff_t stride = c->pal_stride; ptrdiff_t rgb_stride = c->rgb_stride; uint8_t *dst = c->pal_pic + x + y * stride; - uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * rgb_stride; + uint8_t *rgb_dst = c->rgb_pic ? c->rgb_pic + x * 3 + y * rgb_stride : NULL; pix = decode_pixel(acoder, &sc->intra_pix_ctx, NULL, 0, 0); if (pix < 0) return pix; rgb_pix = c->pal[pix]; - for (i = 0; i < height; i++, dst += stride, rgb_dst += rgb_stride) { + for (i = 0; i < height; i++, dst += stride) { memset(dst, pix, width); - if (c->rgb_pic) + if (rgb_dst) { for (j = 0; j < width * 3; j += 3) AV_WB24(rgb_dst + j, rgb_pix); + rgb_dst += rgb_stride; + } } } else { return decode_region(acoder, c->pal_pic, c->rgb_pic, diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c index 113af5ba3..74f4b5e67 100644 --- a/libavcodec/mss3.c +++ b/libavcodec/mss3.c @@ -844,20 +844,13 @@ 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--; - } return AVERROR(ENOMEM); } } c->pic = av_frame_alloc(); - if (!c->pic) { - mss3_decode_end(avctx); + if (!c->pic) return AVERROR(ENOMEM); - } avctx->pix_fmt = AV_PIX_FMT_YUV420P; @@ -876,4 +869,5 @@ AVCodec ff_msa1_decoder = { .close = mss3_decode_end, .decode = mss3_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c index 432df294d..7f11f30dc 100644 --- a/libavcodec/mss4.c +++ b/libavcodec/mss4.c @@ -25,10 +25,13 @@ * aka Microsoft Expression Encoder Screen) decoder */ +#include "libavutil/thread.h" + #include "avcodec.h" #include "bytestream.h" #include "get_bits.h" #include "internal.h" +#include "jpegtables.h" #include "mss34dsp.h" #include "unary.h" @@ -57,56 +60,6 @@ static const uint8_t mss4_dc_vlc_lens[2][16] = { { 0, 3, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0 } }; -static const uint8_t mss4_ac_vlc_lens[2][16] = { - { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 }, - { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 } -}; - -static const uint8_t mss4_ac_vlc_syms[2][162] = { - { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, - 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, - 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, - 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, - 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, - 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, - 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, - 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, - 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, - 0xF9, 0xFA }, - { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, - 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, - 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, - 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, - 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, - 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, - 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, - 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, - 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, - 0xF9, 0xFA } -}; - static const uint8_t vec_len_syms[2][4] = { { 4, 2, 3, 1 }, { 4, 1, 2, 3 } @@ -127,8 +80,6 @@ static const uint8_t mss4_vec_entry_vlc_syms[2][9] = { typedef struct MSS4Context { AVFrame *pic; - VLC dc_vlc[2], ac_vlc[2]; - VLC vec_entry_vlc[2]; int block[64]; uint8_t imgbuf[3][16 * 16]; @@ -142,56 +93,43 @@ typedef struct MSS4Context { int prev_vec[3][4]; } MSS4Context; -static av_cold int mss4_init_vlc(VLC *vlc, const uint8_t *lens, - const uint8_t *syms, int num_syms) +static VLC dc_vlc[2], ac_vlc[2]; +static VLC vec_entry_vlc[2]; + +static av_cold void mss4_init_vlc(VLC *vlc, unsigned *offset, + const uint8_t *lens, const uint8_t *syms) { + static VLC_TYPE vlc_buf[2146][2]; uint8_t bits[MAX_ENTRIES]; - uint16_t codes[MAX_ENTRIES]; int i, j; - int prefix = 0, max_bits = 0, idx = 0; + int idx = 0; for (i = 0; i < 16; i++) { for (j = 0; j < lens[i]; j++) { bits[idx] = i + 1; - codes[idx] = prefix++; - max_bits = i + 1; idx++; } - prefix <<= 1; } - return ff_init_vlc_sparse(vlc, FFMIN(max_bits, 9), num_syms, bits, 1, 1, - codes, 2, 2, syms, 1, 1, 0); + vlc->table = &vlc_buf[*offset]; + vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *offset; + ff_init_vlc_from_lengths(vlc, FFMIN(bits[idx - 1], 9), idx, + bits, 1, syms, 1, 1, + 0, INIT_VLC_STATIC_OVERLONG, NULL); + *offset += vlc->table_size; } -static av_cold int mss4_init_vlcs(MSS4Context *ctx) +static av_cold void mss4_init_vlcs(void) { - int ret, i; - - for (i = 0; i < 2; i++) { - ret = mss4_init_vlc(&ctx->dc_vlc[i], mss4_dc_vlc_lens[i], NULL, 12); - if (ret) - return ret; - ret = mss4_init_vlc(&ctx->ac_vlc[i], mss4_ac_vlc_lens[i], - mss4_ac_vlc_syms[i], 162); - if (ret) - return ret; - ret = mss4_init_vlc(&ctx->vec_entry_vlc[i], mss4_vec_entry_vlc_lens[i], - mss4_vec_entry_vlc_syms[i], 9); - if (ret) - return ret; - } - return 0; -} - -static av_cold void mss4_free_vlcs(MSS4Context *ctx) -{ - int i; - - for (i = 0; i < 2; i++) { - ff_free_vlc(&ctx->dc_vlc[i]); - ff_free_vlc(&ctx->ac_vlc[i]); - ff_free_vlc(&ctx->vec_entry_vlc[i]); + for (unsigned i = 0, offset = 0; i < 2; i++) { + mss4_init_vlc(&dc_vlc[i], &offset, mss4_dc_vlc_lens[i], NULL); + mss4_init_vlc(&ac_vlc[i], &offset, + i ? avpriv_mjpeg_bits_ac_chrominance + 1 + : avpriv_mjpeg_bits_ac_luminance + 1, + i ? avpriv_mjpeg_val_ac_chrominance + : avpriv_mjpeg_val_ac_luminance); + mss4_init_vlc(&vec_entry_vlc[i], &offset, mss4_vec_entry_vlc_lens[i], + mss4_vec_entry_vlc_syms[i]); } } @@ -289,7 +227,7 @@ static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb, int xpos = mb_x * 2 + i; c->dc_cache[j][TOP_LEFT] = c->dc_cache[j][TOP]; c->dc_cache[j][TOP] = c->prev_dc[0][mb_x * 2 + i]; - ret = mss4_decode_dct(gb, c->dc_vlc, c->ac_vlc, c->block, + ret = mss4_decode_dct(gb, &dc_vlc[0], &ac_vlc[0], c->block, c->dc_cache[j], xpos, mb_y * 2 + j, c->quant_mat[0]); if (ret) @@ -305,7 +243,7 @@ static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb, for (i = 1; i < 3; i++) { c->dc_cache[i + 1][TOP_LEFT] = c->dc_cache[i + 1][TOP]; c->dc_cache[i + 1][TOP] = c->prev_dc[i][mb_x]; - ret = mss4_decode_dct(gb, c->dc_vlc + 1, c->ac_vlc + 1, + ret = mss4_decode_dct(gb, &dc_vlc[1], &ac_vlc[1], c->block, c->dc_cache[i + 1], mb_x, mb_y, c->quant_mat[1]); if (ret) @@ -397,7 +335,7 @@ static int mss4_decode_image_block(MSS4Context *ctx, GetBitContext *gb, for (i = 0; i < 3; i++) { vec_len[i] = vec_len_syms[!!i][get_unary(gb, 0, 3)]; for (j = 0; j < vec_len[i]; j++) { - vec[i][j] = get_coeff(gb, &ctx->vec_entry_vlc[!!i]); + vec[i][j] = get_coeff(gb, &vec_entry_vlc[!!i]); vec[i][j] += ctx->prev_vec[i][j]; ctx->prev_vec[i][j] = vec[i][j]; } @@ -636,39 +574,33 @@ static av_cold int mss4_decode_end(AVCodecContext *avctx) 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) { + static AVOnce init_static_once = AV_ONCE_INIT; MSS4Context * const c = avctx->priv_data; int i; - if (mss4_init_vlcs(c)) { - av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n"); - mss4_free_vlcs(c); - return AVERROR(ENOMEM); - } for (i = 0; i < 3; i++) { c->dc_stride[i] = FFALIGN(avctx->width, 16) >> (2 + !!i); c->prev_dc[i] = av_malloc_array(c->dc_stride[i], sizeof(**c->prev_dc)); if (!c->prev_dc[i]) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate buffer\n"); - mss4_free_vlcs(c); return AVERROR(ENOMEM); } } c->pic = av_frame_alloc(); - if (!c->pic) { - mss4_decode_end(avctx); + if (!c->pic) return AVERROR(ENOMEM); - } avctx->pix_fmt = AV_PIX_FMT_YUV444P; + ff_thread_once(&init_static_once, mss4_init_vlcs); + return 0; } @@ -682,4 +614,5 @@ AVCodec ff_mts2_decoder = { .close = mss4_decode_end, .decode = mss4_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c index c9bcce552..b4b5ea466 100644 --- a/libavcodec/msvideo1.c +++ b/libavcodec/msvideo1.c @@ -314,7 +314,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, return ret; if (s->mode_8bit) { - int size; + buffer_size_t size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); if (pal && size == AVPALETTE_SIZE) { diff --git a/libavcodec/mv30.c b/libavcodec/mv30.c index 59088d84f..7ae264e0f 100644 --- a/libavcodec/mv30.c +++ b/libavcodec/mv30.c @@ -35,6 +35,8 @@ #include "internal.h" #include "aandcttab.h" +#define CBP_VLC_BITS 9 + typedef struct MV30Context { GetBitContext gb; @@ -377,10 +379,7 @@ static int decode_coeffs(GetBitContext *gb, int16_t *coeffs, int nb_codes) memset(coeffs, 0, nb_codes * sizeof(*coeffs)); for (int i = 0; i < nb_codes;) { - int value = get_vlc2(gb, cbp_tab.table, cbp_tab.bits, 1); - - if (value < 0) - return AVERROR_INVALIDDATA; + int value = get_vlc2(gb, cbp_tab.table, CBP_VLC_BITS, 1); if (value > 0) { int x = get_bits(gb, value); @@ -654,18 +653,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } -static const uint16_t cbp_codes[] = { - 0, 1, 4, 5, 6, 0xE, 0x1E, 0x3E, 0x7E, 0xFE, 0x1FE, 0x1FF, -}; - static const uint8_t cbp_bits[] = { 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9, 9, }; static av_cold void init_static_data(void) { - INIT_VLC_SPARSE_STATIC(&cbp_tab, 9, FF_ARRAY_ELEMS(cbp_bits), - cbp_bits, 1, 1, cbp_codes, 2, 2, NULL, 0, 0, 512); + INIT_VLC_STATIC_FROM_LENGTHS(&cbp_tab, CBP_VLC_BITS, FF_ARRAY_ELEMS(cbp_bits), + cbp_bits, 1, NULL, 0, 0, 0, 0, 1 << CBP_VLC_BITS); } static av_cold int decode_init(AVCodecContext *avctx) diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c index f89226fef..763ce5871 100644 --- a/libavcodec/mxpegdec.c +++ b/libavcodec/mxpegdec.c @@ -67,10 +67,8 @@ static av_cold int mxpeg_decode_init(AVCodecContext *avctx) s->picture[0] = av_frame_alloc(); s->picture[1] = av_frame_alloc(); - if (!s->picture[0] || !s->picture[1]) { - mxpeg_decode_end(avctx); + if (!s->picture[0] || !s->picture[1]) return AVERROR(ENOMEM); - } s->jpg.picture_ptr = s->picture[0]; return ff_mjpeg_decode_init(avctx); @@ -352,5 +350,5 @@ AVCodec ff_mxpeg_decoder = { .decode = mxpeg_decode_frame, .capabilities = AV_CODEC_CAP_DR1, .max_lowres = 3, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index b0deb79cf..e091ec94b 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -34,6 +34,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" #include "libavutil/lfg.h" +#include "libavutil/mem_internal.h" #include "libavutil/random_seed.h" #define BITSTREAM_READER_LE @@ -128,13 +129,12 @@ static av_cold int decode_init(AVCodecContext * avctx) { s->scale_bias = 1.0/(32768*8); avctx->sample_fmt = AV_SAMPLE_FMT_FLT; - /* Generate overlap window */ - if (!ff_sine_128[127]) - ff_init_ff_sine_windows(7); - avctx->channels = 1; avctx->channel_layout = AV_CH_LAYOUT_MONO; + /* Generate overlap window */ + ff_init_ff_sine_windows(7); + return 0; } @@ -143,7 +143,6 @@ static int decode_tag(AVCodecContext *avctx, void *data, { AVFrame *frame = data; const uint8_t *buf = avpkt->data; - const uint8_t *side=av_packet_get_side_data(avpkt, 'F', NULL); int buf_size = avpkt->size; NellyMoserDecodeContext *s = avctx->priv_data; int blocks, i, ret; @@ -160,15 +159,6 @@ static int decode_tag(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_WARNING, "Leftover bytes: %d.\n", buf_size % NELLY_BLOCK_LEN); } - /* Normal numbers of blocks for sample rates: - * 8000 Hz - 1 - * 11025 Hz - 2 - * 16000 Hz - 3 - * 22050 Hz - 4 - * 44100 Hz - 8 - */ - if(side && blocks>1 && avctx->sample_rate%11025==0 && (1<<((side[0]>>2)&3)) == blocks) - avctx->sample_rate= 11025*(blocks/2); /* get output buffer */ frame->nb_samples = NELLY_SAMPLES * blocks; @@ -205,7 +195,8 @@ AVCodec ff_nellymoser_decoder = { .init = decode_init, .close = decode_end, .decode = decode_tag, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 9d22ac8cc..99ede2f42 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -38,6 +38,7 @@ #include "libavutil/common.h" #include "libavutil/float_dsp.h" #include "libavutil/mathematics.h" +#include "libavutil/thread.h" #include "audio_frame_queue.h" #include "avcodec.h" @@ -147,10 +148,29 @@ static av_cold int encode_end(AVCodecContext *avctx) return 0; } +static av_cold void nellymoser_init_static(void) +{ + /* faster way of doing + for (int i = 0; i < POW_TABLE_SIZE; i++) + pow_table[i] = 2^(-i / 2048.0 - 3.0 + POW_TABLE_OFFSET); */ + pow_table[0] = 1; + pow_table[1024] = M_SQRT1_2; + for (int i = 1; i < 513; i++) { + double tmp = exp2(-i / 2048.0); + pow_table[i] = tmp; + pow_table[1024-i] = M_SQRT1_2 / tmp; + pow_table[1024+i] = tmp * M_SQRT1_2; + pow_table[2048-i] = 0.5 / tmp; + } + /* Generate overlap window */ + ff_init_ff_sine_windows(7); +} + static av_cold int encode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; NellyMoserEncodeContext *s = avctx->priv_data; - int i, ret; + int ret; if (avctx->channels != 1) { av_log(avctx, AV_LOG_ERROR, "Nellymoser supports only 1 channel\n"); @@ -170,41 +190,21 @@ static av_cold int encode_init(AVCodecContext *avctx) ff_af_queue_init(avctx, &s->afq); s->avctx = avctx; if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0) - goto error; + return ret; s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); - if (!s->fdsp) { - ret = AVERROR(ENOMEM); - goto error; - } - - /* Generate overlap window */ - ff_init_ff_sine_windows(7); - /* faster way of doing - for (i = 0; i < POW_TABLE_SIZE; i++) - pow_table[i] = 2^(-i / 2048.0 - 3.0 + POW_TABLE_OFFSET); */ - pow_table[0] = 1; - pow_table[1024] = M_SQRT1_2; - for (i = 1; i < 513; i++) { - double tmp = exp2(-i / 2048.0); - pow_table[i] = tmp; - pow_table[1024-i] = M_SQRT1_2 / tmp; - pow_table[1024+i] = tmp * M_SQRT1_2; - pow_table[2048-i] = 0.5 / tmp; - } + if (!s->fdsp) + return AVERROR(ENOMEM); if (s->avctx->trellis) { s->opt = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(float )); s->path = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(uint8_t)); - if (!s->opt || !s->path) { - ret = AVERROR(ENOMEM); - goto error; - } + if (!s->opt || !s->path) + return AVERROR(ENOMEM); } + ff_thread_once(&init_static_once, nellymoser_init_static); + return 0; -error: - encode_end(avctx); - return ret; } #define find_best(val, table, LUT, LUT_add, LUT_size) \ @@ -431,4 +431,5 @@ AVCodec ff_nellymoser_encoder = { .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/notchlc.c b/libavcodec/notchlc.c index 9e6534339..9a53cad9c 100644 --- a/libavcodec/notchlc.c +++ b/libavcodec/notchlc.c @@ -51,7 +51,7 @@ typedef struct NotchLCContext { unsigned y_data_offset; unsigned uv_data_offset; unsigned y_data_size; - unsigned uv_count_size; + unsigned a_data_offset; unsigned uv_count_offset; unsigned a_count_size; unsigned data_end; @@ -62,7 +62,7 @@ typedef struct NotchLCContext { static av_cold int decode_init(AVCodecContext *avctx) { - avctx->pix_fmt = AV_PIX_FMT_YUV444P12; + avctx->pix_fmt = AV_PIX_FMT_YUVA444P12; avctx->color_range = AVCOL_RANGE_JPEG; avctx->colorspace = AVCOL_SPC_RGB; avctx->color_primaries = AVCOL_PRI_BT709; @@ -108,8 +108,7 @@ static int lz4_decompress(AVCodecContext *avctx, if (bytestream2_get_bytes_left(gb) <= 0) break; - delta = bytestream2_get_byte(gb); - delta |= (unsigned)bytestream2_get_byte(gb) << 8; + delta = bytestream2_get_le16(gb); if (delta == 0) return 0; match_length = 4 + (token & 0x0F); @@ -196,11 +195,11 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p, ThreadFrame *frame, if (s->y_data_size >= UINT_MAX / 4) return AVERROR_INVALIDDATA; - s->uv_count_size = bytestream2_get_le32(gb); - if (s->uv_count_size >= UINT_MAX / 4) + s->a_data_offset = bytestream2_get_le32(gb); + if (s->a_data_offset >= UINT_MAX / 4) return AVERROR_INVALIDDATA; - s->uv_count_size *= 4; - if (s->uv_count_size >= uncompressed_size) + s->a_data_offset *= 4; + if (s->a_data_offset >= uncompressed_size) return AVERROR_INVALIDDATA; s->a_count_size = bytestream2_get_le32(gb); @@ -218,9 +217,9 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p, ThreadFrame *frame, if (s->data_end <= s->y_data_size) return AVERROR_INVALIDDATA; s->y_data_offset = s->data_end - s->y_data_size; - if (s->y_data_offset <= s->uv_count_size) + if (s->y_data_offset <= s->a_data_offset) return AVERROR_INVALIDDATA; - s->uv_count_offset = s->y_data_offset - s->uv_count_size; + s->uv_count_offset = s->y_data_offset - s->a_data_offset; if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0) return ret; @@ -230,6 +229,9 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p, ThreadFrame *frame, bytestream2_seek(&rgb, s->y_data_row_offsets, SEEK_SET); bytestream2_seek(gb, s->y_control_data_offset, SEEK_SET); + if (bytestream2_get_bytes_left(gb) < (avctx->height + 3) / 4 * ((avctx->width + 3) / 4) * 4) + return AVERROR_INVALIDDATA; + dsty = (uint16_t *)p->data[0]; dsta = (uint16_t *)p->data[3]; ylinesize = p->linesize[0] / 2; @@ -266,13 +268,79 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p, ThreadFrame *frame, } dsty += 4 * ylinesize; - dsta += 4 * alinesize; } rgb = *gb; dgb = *gb; - bytestream2_seek(&rgb, s->uv_offset_data_offset, SEEK_SET); bytestream2_seek(gb, s->a_control_word_offset, SEEK_SET); + if (s->uv_count_offset == s->a_control_word_offset) { + for (int y = 0; y < avctx->height; y++) { + for (int x = 0; x < avctx->width; x++) + dsta[x] = 4095; + dsta += alinesize; + } + } else { + if (bytestream2_get_bytes_left(gb) < (avctx->height + 15) / 16 * ((avctx->width + 15) / 16) * 8) + return AVERROR_INVALIDDATA; + + for (int y = 0; y < avctx->height; y += 16) { + for (int x = 0; x < avctx->width; x += 16) { + unsigned m = bytestream2_get_le32(gb); + unsigned offset = bytestream2_get_le32(gb); + unsigned alpha0, alpha1; + uint64_t control; + + if (offset >= UINT_MAX / 4) + return AVERROR_INVALIDDATA; + offset = offset * 4 + s->uv_data_offset + s->a_data_offset; + if (offset >= s->data_end) + return AVERROR_INVALIDDATA; + + bytestream2_seek(&dgb, offset, SEEK_SET); + control = bytestream2_get_le64(&dgb); + alpha0 = control & 0xFF; + alpha1 = (control >> 8) & 0xFF; + control = control >> 16; + + for (int by = 0; by < 4; by++) { + for (int bx = 0; bx < 4; bx++) { + switch (m & 3) { + case 0: + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dsta[x + (i + by * 4) * alinesize + bx * 4 + j] = 0; + } + } + break; + case 1: + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dsta[x + (i + by * 4) * alinesize + bx * 4 + j] = 4095; + } + } + break; + case 2: + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dsta[x + (i + by * 4) * alinesize + bx * 4 + j] = (alpha0 + (alpha1 - alpha0) * (control & 7)) << 4; + } + } + break; + default: + return AVERROR_INVALIDDATA; + } + + control >>= 3; + m >>= 2; + } + } + } + + dsta += 16 * alinesize; + } + } + + bytestream2_seek(&rgb, s->uv_offset_data_offset, SEEK_SET); dstu = (uint16_t *)p->data[1]; dstv = (uint16_t *)p->data[2]; @@ -428,6 +496,9 @@ static int decode_frame(AVCodecContext *avctx, bytestream2_init(gb, s->lzf_buffer, uncompressed_size); } else if (s->format == 1) { + if (bytestream2_get_bytes_left(gb) < uncompressed_size / 255) + return AVERROR_INVALIDDATA; + av_fast_padded_malloc(&s->uncompressed_buffer, &s->uncompressed_size, uncompressed_size); if (!s->uncompressed_buffer) diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index 6168a7e3f..d6b660886 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -62,6 +62,9 @@ typedef struct NVDECFramePool { static int map_avcodec_id(enum AVCodecID id) { switch (id) { +#if CONFIG_AV1_NVDEC_HWACCEL + case AV_CODEC_ID_AV1: return cudaVideoCodec_AV1; +#endif case AV_CODEC_ID_H264: return cudaVideoCodec_H264; case AV_CODEC_ID_HEVC: return cudaVideoCodec_HEVC; case AV_CODEC_ID_MJPEG: return cudaVideoCodec_JPEG; @@ -80,6 +83,9 @@ static int map_chroma_format(enum AVPixelFormat pix_fmt) { int shift_h = 0, shift_v = 0; + if (av_pix_fmt_count_planes(pix_fmt) == 1) + return cudaVideoChromaFormat_Monochrome; + av_pix_fmt_get_chroma_sub_sample(pix_fmt, &shift_h, &shift_v); if (shift_h == 1 && shift_v == 1) @@ -236,7 +242,7 @@ fail: return ret; } -static AVBufferRef *nvdec_decoder_frame_alloc(void *opaque, int size) +static AVBufferRef *nvdec_decoder_frame_alloc(void *opaque, buffer_size_t size) { NVDECFramePool *pool = opaque; AVBufferRef *ret; @@ -258,6 +264,7 @@ int ff_nvdec_decode_uninit(AVCodecContext *avctx) NVDECContext *ctx = avctx->internal->hwaccel_priv_data; av_freep(&ctx->bitstream); + av_freep(&ctx->bitstream_internal); ctx->bitstream_len = 0; ctx->bitstream_allocated = 0; @@ -276,7 +283,7 @@ static void nvdec_free_dummy(struct AVHWFramesContext *ctx) av_buffer_pool_uninit(&ctx->pool); } -static AVBufferRef *nvdec_alloc_dummy(int size) +static AVBufferRef *nvdec_alloc_dummy(buffer_size_t size) { return av_buffer_create(NULL, 0, NULL, NULL, 0); } @@ -441,6 +448,7 @@ static void nvdec_fdd_priv_free(void *priv) av_buffer_unref(&cf->idx_ref); av_buffer_unref(&cf->decoder_ref); + av_buffer_unref(&cf->ref_idx_ref); av_freep(&priv); } @@ -465,6 +473,7 @@ static void nvdec_unmap_mapped_frame(void *opaque, uint8_t *data) finish: av_buffer_unref(&unmap_data->idx_ref); av_buffer_unref(&unmap_data->decoder_ref); + av_buffer_unref(&unmap_data->ref_idx_ref); av_free(unmap_data); } @@ -576,7 +585,7 @@ int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame) ret = AVERROR(ENOMEM); goto fail; } - cf->idx = *(unsigned int*)cf->idx_ref->data; + cf->ref_idx = cf->idx = *(unsigned int*)cf->idx_ref->data; fdd->hwaccel_priv = cf; fdd->hwaccel_priv_free = nvdec_fdd_priv_free; @@ -589,6 +598,40 @@ fail: } +int ff_nvdec_start_frame_sep_ref(AVCodecContext *avctx, AVFrame *frame, int has_sep_ref) +{ + NVDECContext *ctx = avctx->internal->hwaccel_priv_data; + FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data; + NVDECFrame *cf; + int ret; + + ret = ff_nvdec_start_frame(avctx, frame); + if (ret < 0) + return ret; + + cf = fdd->hwaccel_priv; + + if (has_sep_ref) { + if (!cf->ref_idx_ref) { + cf->ref_idx_ref = av_buffer_pool_get(ctx->decoder_pool); + if (!cf->ref_idx_ref) { + av_log(avctx, AV_LOG_ERROR, "No decoder surfaces left\n"); + ret = AVERROR(ENOMEM); + goto fail; + } + } + cf->ref_idx = *(unsigned int*)cf->ref_idx_ref->data; + } else { + av_buffer_unref(&cf->ref_idx_ref); + cf->ref_idx = cf->idx; + } + + return 0; +fail: + nvdec_fdd_priv_free(cf); + return ret; +} + int ff_nvdec_end_frame(AVCodecContext *avctx) { NVDECContext *ctx = avctx->internal->hwaccel_priv_data; @@ -714,5 +757,5 @@ int ff_nvdec_get_ref_idx(AVFrame *frame) if (!cf) return -1; - return cf->idx; + return cf->ref_idx; } diff --git a/libavcodec/nvdec.h b/libavcodec/nvdec.h index 09ae8c37e..66f3ca59e 100644 --- a/libavcodec/nvdec.h +++ b/libavcodec/nvdec.h @@ -43,7 +43,9 @@ typedef struct NVDECFrame { unsigned int idx; + unsigned int ref_idx; AVBufferRef *idx_ref; + AVBufferRef *ref_idx_ref; AVBufferRef *decoder_ref; } NVDECFrame; @@ -57,6 +59,7 @@ typedef struct NVDECContext { uint8_t *bitstream; int bitstream_len; unsigned int bitstream_allocated; + uint8_t *bitstream_internal; unsigned *slice_offsets; int nb_slices; @@ -68,6 +71,7 @@ typedef struct NVDECContext { int ff_nvdec_decode_init(AVCodecContext *avctx); int ff_nvdec_decode_uninit(AVCodecContext *avctx); int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame); +int ff_nvdec_start_frame_sep_ref(AVCodecContext *avctx, AVFrame *frame, int has_sep_ref); int ff_nvdec_end_frame(AVCodecContext *avctx); int ff_nvdec_simple_end_frame(AVCodecContext *avctx); int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, diff --git a/libavcodec/nvdec_av1.c b/libavcodec/nvdec_av1.c new file mode 100644 index 000000000..1ce846a60 --- /dev/null +++ b/libavcodec/nvdec_av1.c @@ -0,0 +1,352 @@ +/* + * AV1 HW decode acceleration through NVDEC + * + * Copyright (c) 2020 Timo Rothenpieler + * + * 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 "avcodec.h" +#include "nvdec.h" +#include "decode.h" +#include "internal.h" +#include "av1dec.h" + + +static int get_bit_depth_from_seq(const AV1RawSequenceHeader *seq) +{ + if (seq->seq_profile == 2 && seq->color_config.high_bitdepth) + return seq->color_config.twelve_bit ? 12 : 10; + else if (seq->seq_profile <= 2 && seq->color_config.high_bitdepth) + return 10; + else + return 8; +} + +static int nvdec_av1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + const AV1DecContext *s = avctx->priv_data; + const AV1RawSequenceHeader *seq = s->raw_seq; + const AV1RawFrameHeader *frame_header = s->raw_frame_header; + const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain; + + NVDECContext *ctx = avctx->internal->hwaccel_priv_data; + CUVIDPICPARAMS *pp = &ctx->pic_params; + CUVIDAV1PICPARAMS *ppc = &pp->CodecSpecific.av1; + FrameDecodeData *fdd; + NVDECFrame *cf; + AVFrame *cur_frame = s->cur_frame.tf.f; + + unsigned char remap_lr_type[4] = { AV1_RESTORE_NONE, AV1_RESTORE_SWITCHABLE, AV1_RESTORE_WIENER, AV1_RESTORE_SGRPROJ }; + + int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && film_grain->apply_grain; + int ret, i, j; + + ret = ff_nvdec_start_frame_sep_ref(avctx, cur_frame, apply_grain); + if (ret < 0) + return ret; + + fdd = (FrameDecodeData*)cur_frame->private_ref->data; + cf = (NVDECFrame*)fdd->hwaccel_priv; + + *pp = (CUVIDPICPARAMS) { + .PicWidthInMbs = (cur_frame->width + 15) / 16, + .FrameHeightInMbs = (cur_frame->height + 15) / 16, + .CurrPicIdx = cf->idx, + .ref_pic_flag = !!frame_header->refresh_frame_flags, + .intra_pic_flag = frame_header->frame_type == AV1_FRAME_INTRA_ONLY || + frame_header->frame_type == AV1_FRAME_KEY, + + .CodecSpecific.av1 = { + .width = cur_frame->width, + .height = cur_frame->height, + + .frame_offset = frame_header->order_hint, + .decodePicIdx = cf->ref_idx, + + /* Sequence Header */ + .profile = seq->seq_profile, + .use_128x128_superblock = seq->use_128x128_superblock, + .subsampling_x = seq->color_config.subsampling_x, + .subsampling_y = seq->color_config.subsampling_y, + .mono_chrome = seq->color_config.mono_chrome, + .bit_depth_minus8 = get_bit_depth_from_seq(seq) - 8, + .enable_filter_intra = seq->enable_filter_intra, + .enable_intra_edge_filter = seq->enable_intra_edge_filter, + .enable_interintra_compound = seq->enable_interintra_compound, + .enable_masked_compound = seq->enable_masked_compound, + .enable_dual_filter = seq->enable_dual_filter, + .enable_order_hint = seq->enable_order_hint, + .order_hint_bits_minus1 = seq->order_hint_bits_minus_1, + .enable_jnt_comp = seq->enable_jnt_comp, + .enable_superres = seq->enable_superres, + .enable_cdef = seq->enable_cdef, + .enable_restoration = seq->enable_restoration, + .enable_fgs = seq->film_grain_params_present && + !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN), + + /* Frame Header */ + .frame_type = frame_header->frame_type, + .show_frame = frame_header->show_frame, + .disable_cdf_update = frame_header->disable_cdf_update, + .allow_screen_content_tools = frame_header->allow_screen_content_tools, + .force_integer_mv = frame_header->force_integer_mv || + frame_header->frame_type == AV1_FRAME_INTRA_ONLY || + frame_header->frame_type == AV1_FRAME_KEY, + .coded_denom = frame_header->coded_denom, + .allow_intrabc = frame_header->allow_intrabc, + .allow_high_precision_mv = frame_header->allow_high_precision_mv, + .interp_filter = frame_header->interpolation_filter, + .switchable_motion_mode = frame_header->is_motion_mode_switchable, + .use_ref_frame_mvs = frame_header->use_ref_frame_mvs, + .disable_frame_end_update_cdf = frame_header->disable_frame_end_update_cdf, + .delta_q_present = frame_header->delta_q_present, + .delta_q_res = frame_header->delta_q_res, + .using_qmatrix = frame_header->using_qmatrix, + .coded_lossless = s->cur_frame.coded_lossless, + .use_superres = frame_header->use_superres, + .tx_mode = frame_header->tx_mode, + .reference_mode = frame_header->reference_select, + .allow_warped_motion = frame_header->allow_warped_motion, + .reduced_tx_set = frame_header->reduced_tx_set, + .skip_mode = frame_header->skip_mode_present, + + /* Tiling Info */ + .num_tile_cols = frame_header->tile_cols, + .num_tile_rows = frame_header->tile_rows, + .context_update_tile_id = frame_header->context_update_tile_id, + + /* CDEF */ + .cdef_damping_minus_3 = frame_header->cdef_damping_minus_3, + .cdef_bits = frame_header->cdef_bits, + + /* SkipModeFrames */ + .SkipModeFrame0 = frame_header->skip_mode_present ? + s->cur_frame.skip_mode_frame_idx[0] : 0, + .SkipModeFrame1 = frame_header->skip_mode_present ? + s->cur_frame.skip_mode_frame_idx[1] : 0, + + /* QP Information */ + .base_qindex = frame_header->base_q_idx, + .qp_y_dc_delta_q = frame_header->delta_q_y_dc, + .qp_u_dc_delta_q = frame_header->delta_q_u_dc, + .qp_v_dc_delta_q = frame_header->delta_q_v_dc, + .qp_u_ac_delta_q = frame_header->delta_q_u_ac, + .qp_v_ac_delta_q = frame_header->delta_q_v_ac, + .qm_y = frame_header->qm_y, + .qm_u = frame_header->qm_u, + .qm_v = frame_header->qm_v, + + /* Segmentation */ + .segmentation_enabled = frame_header->segmentation_enabled, + .segmentation_update_map = frame_header->segmentation_update_map, + .segmentation_update_data = frame_header->segmentation_update_data, + .segmentation_temporal_update = frame_header->segmentation_temporal_update, + + /* Loopfilter */ + .loop_filter_level[0] = frame_header->loop_filter_level[0], + .loop_filter_level[1] = frame_header->loop_filter_level[1], + .loop_filter_level_u = frame_header->loop_filter_level[2], + .loop_filter_level_v = frame_header->loop_filter_level[3], + .loop_filter_sharpness = frame_header->loop_filter_sharpness, + .loop_filter_delta_enabled = frame_header->loop_filter_delta_enabled, + .loop_filter_delta_update = frame_header->loop_filter_delta_update, + .loop_filter_mode_deltas[0] = frame_header->loop_filter_mode_deltas[0], + .loop_filter_mode_deltas[1] = frame_header->loop_filter_mode_deltas[1], + .delta_lf_present = frame_header->delta_lf_present, + .delta_lf_res = frame_header->delta_lf_res, + .delta_lf_multi = frame_header->delta_lf_multi, + + /* Restoration */ + .lr_type[0] = remap_lr_type[frame_header->lr_type[0]], + .lr_type[1] = remap_lr_type[frame_header->lr_type[1]], + .lr_type[2] = remap_lr_type[frame_header->lr_type[2]], + .lr_unit_size[0] = 1 + frame_header->lr_unit_shift, + .lr_unit_size[1] = 1 + frame_header->lr_unit_shift - frame_header->lr_uv_shift, + .lr_unit_size[2] = 1 + frame_header->lr_unit_shift - frame_header->lr_uv_shift, + + /* Reference Frames */ + .temporal_layer_id = s->cur_frame.temporal_id, + .spatial_layer_id = s->cur_frame.spatial_id, + + /* Film Grain Params */ + .apply_grain = apply_grain, + .overlap_flag = film_grain->overlap_flag, + .scaling_shift_minus8 = film_grain->grain_scaling_minus_8, + .chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma, + .ar_coeff_lag = film_grain->ar_coeff_lag, + .ar_coeff_shift_minus6 = film_grain->ar_coeff_shift_minus_6, + .grain_scale_shift = film_grain->grain_scale_shift, + .clip_to_restricted_range = film_grain->clip_to_restricted_range, + .num_y_points = film_grain->num_y_points, + .num_cb_points = film_grain->num_cb_points, + .num_cr_points = film_grain->num_cr_points, + .random_seed = film_grain->grain_seed, + .cb_mult = film_grain->cb_mult, + .cb_luma_mult = film_grain->cb_luma_mult, + .cb_offset = film_grain->cb_offset, + .cr_mult = film_grain->cr_mult, + .cr_luma_mult = film_grain->cr_luma_mult, + .cr_offset = film_grain->cr_offset + } + }; + + /* Tiling Info */ + for (i = 0; i < frame_header->tile_cols; ++i) { + ppc->tile_widths[i] = frame_header->width_in_sbs_minus_1[i] + 1; + } + for (i = 0; i < frame_header->tile_rows; ++i) { + ppc->tile_heights[i] = frame_header->height_in_sbs_minus_1[i] + 1; + } + + /* CDEF */ + for (i = 0; i < (1 << frame_header->cdef_bits); ++i) { + ppc->cdef_y_strength[i] = (frame_header->cdef_y_pri_strength[i] & 0x0F) | (frame_header->cdef_y_sec_strength[i] << 4); + ppc->cdef_uv_strength[i] = (frame_header->cdef_uv_pri_strength[i] & 0x0F) | (frame_header->cdef_uv_sec_strength[i] << 4); + } + + /* Segmentation */ + for (i = 0; i < AV1_MAX_SEGMENTS; ++i) { + ppc->segmentation_feature_mask[i] = 0; + for (j = 0; j < AV1_SEG_LVL_MAX; ++j) { + ppc->segmentation_feature_mask[i] |= frame_header->feature_enabled[i][j] << j; + ppc->segmentation_feature_data[i][j] = frame_header->feature_value[i][j]; + } + } + + for (i = 0; i < AV1_NUM_REF_FRAMES; ++i) { + /* Loopfilter */ + ppc->loop_filter_ref_deltas[i] = frame_header->loop_filter_ref_deltas[i]; + + /* Reference Frames */ + ppc->ref_frame_map[i] = ff_nvdec_get_ref_idx(s->ref[i].tf.f); + } + + if (frame_header->primary_ref_frame == AV1_PRIMARY_REF_NONE) { + ppc->primary_ref_frame = -1; + } else { + int8_t pri_ref_idx = frame_header->ref_frame_idx[frame_header->primary_ref_frame]; + ppc->primary_ref_frame = ppc->ref_frame_map[pri_ref_idx]; + } + + for (i = 0; i < AV1_REFS_PER_FRAME; ++i) { + /* Ref Frame List */ + int8_t ref_idx = frame_header->ref_frame_idx[i]; + AVFrame *ref_frame = s->ref[ref_idx].tf.f; + + ppc->ref_frame[i].index = ppc->ref_frame_map[ref_idx]; + ppc->ref_frame[i].width = ref_frame->width; + ppc->ref_frame[i].height = ref_frame->height; + + /* Global Motion */ + ppc->global_motion[i].invalid = !frame_header->is_global[AV1_REF_FRAME_LAST + i]; + ppc->global_motion[i].wmtype = s->cur_frame.gm_type[AV1_REF_FRAME_LAST + i]; + for (j = 0; j < 6; ++j) { + ppc->global_motion[i].wmmat[j] = s->cur_frame.gm_params[AV1_REF_FRAME_LAST + i][j]; + } + } + + /* Film Grain Params */ + if (apply_grain) { + for (i = 0; i < 14; ++i) { + ppc->scaling_points_y[i][0] = film_grain->point_y_value[i]; + ppc->scaling_points_y[i][1] = film_grain->point_y_scaling[i]; + } + for (i = 0; i < 10; ++i) { + ppc->scaling_points_cb[i][0] = film_grain->point_cb_value[i]; + ppc->scaling_points_cb[i][1] = film_grain->point_cb_scaling[i]; + ppc->scaling_points_cr[i][0] = film_grain->point_cr_value[i]; + ppc->scaling_points_cr[i][1] = film_grain->point_cr_scaling[i]; + } + for (i = 0; i < 24; ++i) { + ppc->ar_coeffs_y[i] = (short)film_grain->ar_coeffs_y_plus_128[i] - 128; + } + for (i = 0; i < 25; ++i) { + ppc->ar_coeffs_cb[i] = (short)film_grain->ar_coeffs_cb_plus_128[i] - 128; + ppc->ar_coeffs_cr[i] = (short)film_grain->ar_coeffs_cr_plus_128[i] - 128; + } + } + + return 0; +} + +static int nvdec_av1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + const AV1DecContext *s = avctx->priv_data; + const AV1RawFrameHeader *frame_header = s->raw_frame_header; + NVDECContext *ctx = avctx->internal->hwaccel_priv_data; + void *tmp; + + ctx->nb_slices = frame_header->tile_cols * frame_header->tile_rows; + + tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated, + ctx->nb_slices * 2 * sizeof(*ctx->slice_offsets)); + if (!tmp) { + return AVERROR(ENOMEM); + } + ctx->slice_offsets = tmp; + + /* Shortcut if all tiles are in the same buffer */ + if (ctx->nb_slices == s->tg_end - s->tg_start + 1) { + ctx->bitstream = (uint8_t*)buffer; + ctx->bitstream_len = size; + + for (int i = 0; i < ctx->nb_slices; ++i) { + ctx->slice_offsets[i*2 ] = s->tile_group_info[i].tile_offset; + ctx->slice_offsets[i*2 + 1] = ctx->slice_offsets[i*2] + s->tile_group_info[i].tile_size; + } + + return 0; + } + + tmp = av_fast_realloc(ctx->bitstream_internal, &ctx->bitstream_allocated, + ctx->bitstream_len + size); + if (!tmp) { + return AVERROR(ENOMEM); + } + ctx->bitstream = ctx->bitstream_internal = tmp; + + memcpy(ctx->bitstream + ctx->bitstream_len, buffer, size); + + for (uint32_t tile_num = s->tg_start; tile_num <= s->tg_end; ++tile_num) { + ctx->slice_offsets[tile_num*2 ] = ctx->bitstream_len + s->tile_group_info[tile_num].tile_offset; + ctx->slice_offsets[tile_num*2 + 1] = ctx->slice_offsets[tile_num*2] + s->tile_group_info[tile_num].tile_size; + } + ctx->bitstream_len += size; + + return 0; +} + +static int nvdec_av1_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx) +{ + /* Maximum of 8 reference frames, but potentially stored twice due to film grain */ + return ff_nvdec_frame_params(avctx, hw_frames_ctx, 8 * 2, 0); +} + +const AVHWAccel ff_av1_nvdec_hwaccel = { + .name = "av1_nvdec", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_AV1, + .pix_fmt = AV_PIX_FMT_CUDA, + .start_frame = nvdec_av1_start_frame, + .end_frame = ff_nvdec_simple_end_frame, + .decode_slice = nvdec_av1_decode_slice, + .frame_params = nvdec_av1_frame_params, + .init = ff_nvdec_decode_init, + .uninit = ff_nvdec_decode_uninit, + .priv_data_size = sizeof(NVDECContext), +}; diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 03fdd7002..dddee8cac 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -22,6 +22,7 @@ #include "config.h" #include "nvenc.h" +#include "hevc_sei.h" #include "libavutil/hwcontext_cuda.h" #include "libavutil/hwcontext.h" @@ -30,6 +31,8 @@ #include "libavutil/avassert.h" #include "libavutil/mem.h" #include "libavutil/pixdesc.h" +#include "atsc_a53.h" +#include "encode.h" #include "internal.h" #include "packet_internal.h" @@ -56,7 +59,7 @@ const enum AVPixelFormat ff_nvenc_pix_fmts[] = { AV_PIX_FMT_NONE }; -const AVCodecHWConfigInternal *ff_nvenc_hw_configs[] = { +const AVCodecHWConfigInternal *const ff_nvenc_hw_configs[] = { HW_CONFIG_ENCODER_FRAMES(CUDA, CUDA), HW_CONFIG_ENCODER_DEVICE(NONE, CUDA), #if CONFIG_D3D11VA @@ -143,8 +146,20 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err, static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level) { -#if NVENCAPI_CHECK_VERSION(9, 2) +#if NVENCAPI_CHECK_VERSION(11, 1) const char *minver = "(unknown)"; +#elif NVENCAPI_CHECK_VERSION(11, 0) +# if defined(_WIN32) || defined(__CYGWIN__) + const char *minver = "456.71"; +# else + const char *minver = "455.28"; +# endif +#elif NVENCAPI_CHECK_VERSION(10, 0) +# if defined(_WIN32) || defined(__CYGWIN__) + const char *minver = "450.51"; +# else + const char *minver = "445.87"; +# endif #elif NVENCAPI_CHECK_VERSION(9, 1) # if defined(_WIN32) || defined(__CYGWIN__) const char *minver = "436.15"; @@ -410,7 +425,7 @@ static int nvenc_check_capabilities(AVCodecContext *avctx) #ifdef NVENC_HAVE_BFRAME_REF_MODE ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE); - if (ctx->b_ref_mode == NV_ENC_BFRAME_REF_MODE_EACH && ret != 1) { + if (ctx->b_ref_mode == NV_ENC_BFRAME_REF_MODE_EACH && ret != 1 && ret != 3) { av_log(avctx, AV_LOG_WARNING, "Each B frame as reference is not supported\n"); return AVERROR(ENOSYS); } else if (ctx->b_ref_mode != NV_ENC_BFRAME_REF_MODE_DISABLED && ret == 0) { @@ -636,6 +651,28 @@ typedef struct GUIDTuple { static void nvenc_map_preset(NvencContext *ctx) { GUIDTuple presets[] = { +#ifdef NVENC_HAVE_NEW_PRESETS + PRESET(P1), + PRESET(P2), + PRESET(P3), + PRESET(P4), + PRESET(P5), + PRESET(P6), + PRESET(P7), + PRESET_ALIAS(SLOW, P7, NVENC_TWO_PASSES), + PRESET_ALIAS(MEDIUM, P4, NVENC_ONE_PASS), + PRESET_ALIAS(FAST, P1, NVENC_ONE_PASS), + // Compat aliases + PRESET_ALIAS(DEFAULT, P4, NVENC_DEPRECATED_PRESET), + PRESET_ALIAS(HP, P1, NVENC_DEPRECATED_PRESET), + PRESET_ALIAS(HQ, P7, NVENC_DEPRECATED_PRESET), + PRESET_ALIAS(BD, P5, NVENC_DEPRECATED_PRESET), + PRESET_ALIAS(LOW_LATENCY_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY), + PRESET_ALIAS(LOW_LATENCY_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY), + PRESET_ALIAS(LOW_LATENCY_HQ, P7, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY), + PRESET_ALIAS(LOSSLESS_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS), + PRESET_ALIAS(LOSSLESS_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS), +#else PRESET(DEFAULT), PRESET(HP), PRESET(HQ), @@ -648,6 +685,7 @@ static void nvenc_map_preset(NvencContext *ctx) PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY), PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS), PRESET(LOSSLESS_HP, NVENC_LOSSLESS), +#endif }; GUIDTuple *t = &presets[ctx->preset]; @@ -857,6 +895,24 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) if (avctx->rc_max_rate > 0) ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate; +#ifdef NVENC_HAVE_MULTIPASS + ctx->encode_config.rcParams.multiPass = ctx->multipass; + + if (ctx->flags & NVENC_ONE_PASS) + ctx->encode_config.rcParams.multiPass = NV_ENC_MULTI_PASS_DISABLED; + if (ctx->flags & NVENC_TWO_PASSES || ctx->twopass > 0) + ctx->encode_config.rcParams.multiPass = NV_ENC_TWO_PASS_FULL_RESOLUTION; + + if (ctx->rc < 0) { + if (ctx->cbr) { + ctx->rc = NV_ENC_PARAMS_RC_CBR; + } else if (ctx->cqp >= 0) { + ctx->rc = NV_ENC_PARAMS_RC_CONSTQP; + } else if (ctx->quality >= 0.0f) { + ctx->rc = NV_ENC_PARAMS_RC_VBR; + } + } +#else if (ctx->rc < 0) { if (ctx->flags & NVENC_ONE_PASS) ctx->twopass = 0; @@ -880,17 +936,20 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) ctx->rc = NV_ENC_PARAMS_RC_VBR_MINQP; } } +#endif if (ctx->rc >= 0 && ctx->rc & RC_MODE_DEPRECATED) { av_log(avctx, AV_LOG_WARNING, "Specified rc mode is deprecated.\n"); - av_log(avctx, AV_LOG_WARNING, "\tll_2pass_quality -> cbr_ld_hq\n"); - av_log(avctx, AV_LOG_WARNING, "\tll_2pass_size -> cbr_hq\n"); - av_log(avctx, AV_LOG_WARNING, "\tvbr_2pass -> vbr_hq\n"); - av_log(avctx, AV_LOG_WARNING, "\tvbr_minqp -> (no replacement)\n"); + av_log(avctx, AV_LOG_WARNING, "Use -rc constqp/cbr/vbr, -tune and -multipass instead.\n"); ctx->rc &= ~RC_MODE_DEPRECATED; } +#ifdef NVENC_HAVE_LDKFS + if (ctx->ldkfs) + ctx->encode_config.rcParams.lowDelayKeyFrameScale = ctx->ldkfs; +#endif + if (ctx->flags & NVENC_LOSSLESS) { set_lossless(avctx); } else if (ctx->rc >= 0) { @@ -1197,13 +1256,29 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx) nvenc_map_preset(ctx); + if (ctx->flags & NVENC_DEPRECATED_PRESET) + av_log(avctx, AV_LOG_WARNING, "The selected preset is deprecated. Use p1 to p7 + -tune or fast/medium/slow.\n"); + preset_config.version = NV_ENC_PRESET_CONFIG_VER; preset_config.presetCfg.version = NV_ENC_CONFIG_VER; +#ifdef NVENC_HAVE_NEW_PRESETS + ctx->init_encode_params.tuningInfo = ctx->tuning_info; + + if (ctx->flags & NVENC_LOWLATENCY) + ctx->init_encode_params.tuningInfo = NV_ENC_TUNING_INFO_LOW_LATENCY; + + nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder, + ctx->init_encode_params.encodeGUID, + ctx->init_encode_params.presetGUID, + ctx->init_encode_params.tuningInfo, + &preset_config); +#else nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder, - ctx->init_encode_params.encodeGUID, - ctx->init_encode_params.presetGUID, - &preset_config); + ctx->init_encode_params.encodeGUID, + ctx->init_encode_params.presetGUID, + &preset_config); +#endif if (nv_status != NV_ENC_SUCCESS) return nvenc_print_error(avctx, nv_status, "Cannot get the preset configuration"); @@ -1226,6 +1301,17 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx) ctx->init_encode_params.enableEncodeAsync = 0; ctx->init_encode_params.enablePTD = 1; +#ifdef NVENC_HAVE_NEW_PRESETS + /* If lookahead isn't set from CLI, use value from preset. + * P6 & P7 presets may enable lookahead for better quality. + * */ + if (ctx->rc_lookahead == 0 && ctx->encode_config.rcParams.enableLookahead) + ctx->rc_lookahead = ctx->encode_config.rcParams.lookaheadDepth; + + if (ctx->init_encode_params.tuningInfo == NV_ENC_TUNING_INFO_LOSSLESS) + ctx->flags |= NVENC_LOSSLESS; +#endif + if (ctx->weighted_pred == 1) ctx->init_encode_params.enableWeightedPrediction = 1; @@ -1383,7 +1469,6 @@ static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx) } ctx->surfaces[idx].output_surface = allocOut.bitstreamBuffer; - ctx->surfaces[idx].size = allocOut.size; av_fifo_generic_write(ctx->unused_surface_queue, &tmp_surface, sizeof(tmp_surface), NULL); @@ -1509,6 +1594,8 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) av_freep(&ctx->surfaces); ctx->nb_surfaces = 0; + av_frame_free(&ctx->frame); + if (ctx->nvencoder) { p_nvenc->nvEncDestroyEncoder(ctx->nvencoder); @@ -1562,6 +1649,10 @@ av_cold int ff_nvenc_encode_init(AVCodecContext *avctx) ctx->data_pix_fmt = avctx->pix_fmt; } + ctx->frame = av_frame_alloc(); + if (!ctx->frame) + return AVERROR(ENOMEM); + if ((ret = nvenc_load_libraries(avctx)) < 0) return ret; @@ -1776,7 +1867,8 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, NV_ENC_PIC_PARAMS *params, - NV_ENC_SEI_PAYLOAD *sei_data) + NV_ENC_SEI_PAYLOAD *sei_data, + int sei_count) { NvencContext *ctx = avctx->priv_data; @@ -1786,9 +1878,9 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, ctx->encode_config.encodeCodecConfig.h264Config.sliceMode; params->codecPicParams.h264PicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData; - if (sei_data) { + if (sei_count > 0) { params->codecPicParams.h264PicParams.seiPayloadArray = sei_data; - params->codecPicParams.h264PicParams.seiPayloadArrayCnt = 1; + params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count; } break; @@ -1797,9 +1889,9 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode; params->codecPicParams.hevcPicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData; - if (sei_data) { + if (sei_count > 0) { params->codecPicParams.hevcPicParams.seiPayloadArray = sei_data; - params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = 1; + params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = sei_count; } break; @@ -1829,7 +1921,7 @@ static int nvenc_set_timestamp(AVCodecContext *avctx, pkt->pts = params->outputTimeStamp; pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list); - pkt->dts -= FFMAX(avctx->max_b_frames, 0) * FFMAX(avctx->ticks_per_frame, 1); + pkt->dts -= FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1); return 0; } @@ -1879,9 +1971,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur goto error; } - res = pkt->data ? - ff_alloc_packet2(avctx, pkt, lock_params.bitstreamSizeInBytes, lock_params.bitstreamSizeInBytes) : - av_new_packet(pkt, lock_params.bitstreamSizeInBytes); + res = ff_get_encode_buffer(avctx, pkt, lock_params.bitstreamSizeInBytes, 0); if (res < 0) { p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface); @@ -2067,13 +2157,14 @@ static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame) } } -int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) +static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) { NVENCSTATUS nv_status; NvencSurface *tmp_out_surf, *in_surf; int res, res2; - NV_ENC_SEI_PAYLOAD *sei_data = NULL; - size_t sei_size; + NV_ENC_SEI_PAYLOAD sei_data[8]; + int sei_count = 0; + int i; NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; @@ -2085,15 +2176,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder) return AVERROR(EINVAL); - if (ctx->encoder_flushing) { - if (avctx->internal->draining) - return AVERROR_EOF; - - ctx->encoder_flushing = 0; - av_fifo_reset(ctx->timestamp_list); - } - - if (frame) { + if (frame && frame->buf[0]) { in_surf = get_free_frame(ctx); if (!in_surf) return AVERROR(EAGAIN); @@ -2139,21 +2222,40 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) pic_params.inputTimeStamp = frame->pts; if (ctx->a53_cc && av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC)) { - if (ff_alloc_a53_sei(frame, sizeof(NV_ENC_SEI_PAYLOAD), (void**)&sei_data, &sei_size) < 0) { + void *a53_data = NULL; + size_t a53_size = 0; + + if (ff_alloc_a53_sei(frame, 0, (void**)&a53_data, &a53_size) < 0) { av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n"); } - if (sei_data) { - sei_data->payloadSize = (uint32_t)sei_size; - sei_data->payloadType = 4; - sei_data->payload = (uint8_t*)(sei_data + 1); + if (a53_data) { + sei_data[sei_count].payloadSize = (uint32_t)a53_size; + sei_data[sei_count].payloadType = 4; + sei_data[sei_count].payload = (uint8_t*)a53_data; + sei_count ++; } } - nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data); + if (ctx->s12m_tc && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) { + void *tc_data = NULL; + size_t tc_size = 0; + + if (ff_alloc_timecode_sei(frame, avctx->framerate, 0, (void**)&tc_data, &tc_size) < 0) { + av_log(ctx, AV_LOG_ERROR, "Not enough memory for timecode sei, skipping\n"); + } + + if (tc_data) { + sei_data[sei_count].payloadSize = (uint32_t)tc_size; + sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE; + sei_data[sei_count].payload = (uint8_t*)tc_data; + sei_count ++; + } + } + + nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data, sei_count); } else { pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; - ctx->encoder_flushing = 1; } res = nvenc_push_context(avctx); @@ -2161,7 +2263,9 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) return res; nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params); - av_free(sei_data); + + for ( i = 0; i < sei_count; i++) + av_freep(&sei_data[i].payload); res = nvenc_pop_context(avctx); if (res < 0) @@ -2171,7 +2275,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) nv_status != NV_ENC_ERR_NEED_MORE_INPUT) return nvenc_print_error(avctx, nv_status, "EncodePicture failed!"); - if (frame) { + if (frame && frame->buf[0]) { av_fifo_generic_write(ctx->output_surface_queue, &in_surf, sizeof(in_surf), NULL); timestamp_queue_enqueue(ctx->timestamp_list, frame->pts); } @@ -2194,10 +2298,25 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) NvencContext *ctx = avctx->priv_data; + AVFrame *frame = ctx->frame; + if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder) return AVERROR(EINVAL); - if (output_ready(avctx, ctx->encoder_flushing)) { + if (!frame->buf[0]) { + res = ff_encode_get_frame(avctx, frame); + if (res < 0 && res != AVERROR_EOF) + return res; + } + + res = nvenc_send_frame(avctx, frame); + if (res < 0) { + if (res != AVERROR(EAGAIN)) + return res; + } else + av_frame_unref(frame); + + if (output_ready(avctx, avctx->internal->draining)) { av_fifo_generic_read(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); res = nvenc_push_context(avctx); @@ -2214,7 +2333,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) return res; av_fifo_generic_write(ctx->unused_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); - } else if (ctx->encoder_flushing) { + } else if (avctx->internal->draining) { return AVERROR_EOF; } else { return AVERROR(EAGAIN); @@ -2223,31 +2342,10 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) return 0; } -int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *frame, int *got_packet) -{ - NvencContext *ctx = avctx->priv_data; - int res; - - if (!ctx->encoder_flushing) { - res = ff_nvenc_send_frame(avctx, frame); - if (res < 0) - return res; - } - - res = ff_nvenc_receive_packet(avctx, pkt); - if (res == AVERROR(EAGAIN) || res == AVERROR_EOF) { - *got_packet = 0; - } else if (res < 0) { - return res; - } else { - *got_packet = 1; - } - - return 0; -} - av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx) { - ff_nvenc_send_frame(avctx, NULL); + NvencContext *ctx = avctx->priv_data; + + nvenc_send_frame(avctx, NULL); + av_fifo_reset(ctx->timestamp_list); } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 7a415a483..fefc5f7f0 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -62,6 +62,14 @@ typedef void ID3D11Device; #define NVENC_HAVE_GETLASTERRORSTRING #endif +// SDK 10.0 compile time feature checks +#if NVENCAPI_CHECK_VERSION(10, 0) +#define NVENC_HAVE_NEW_PRESETS +#define NVENC_HAVE_MULTIPASS +#define NVENC_HAVE_LDKFS +#define NVENC_HAVE_H264_LVL6 +#endif + typedef struct NvencSurface { NV_ENC_INPUT_PTR input_surface; @@ -73,7 +81,6 @@ typedef struct NvencSurface NV_ENC_OUTPUT_PTR output_surface; NV_ENC_BUFFER_FORMAT format; - int size; } NvencSurface; typedef struct NvencDynLoadFunctions @@ -98,6 +105,15 @@ enum { PRESET_LOW_LATENCY_HP, PRESET_LOSSLESS_DEFAULT, // lossless presets must be the last ones PRESET_LOSSLESS_HP, +#ifdef NVENC_HAVE_NEW_PRESETS + PRESET_P1, + PRESET_P2, + PRESET_P3, + PRESET_P4, + PRESET_P5, + PRESET_P6, + PRESET_P7, +#endif }; enum { @@ -118,6 +134,8 @@ enum { NVENC_LOSSLESS = 2, NVENC_ONE_PASS = 4, NVENC_TWO_PASSES = 8, + + NVENC_DEPRECATED_PRESET = 0x8000, }; enum { @@ -138,6 +156,8 @@ typedef struct NvencContext CUstream cu_stream; ID3D11Device *d3d11_device; + AVFrame *frame; + int nb_surfaces; NvencSurface *surfaces; @@ -146,8 +166,6 @@ typedef struct NvencContext AVFifoBuffer *output_surface_ready_queue; AVFifoBuffer *timestamp_list; - int encoder_flushing; - struct { void *ptr; int ptr_index; @@ -196,23 +214,22 @@ typedef struct NvencContext int coder; int b_ref_mode; int a53_cc; + int s12m_tc; int dpb_size; + int tuning_info; + int multipass; + int ldkfs; } NvencContext; int ff_nvenc_encode_init(AVCodecContext *avctx); int ff_nvenc_encode_close(AVCodecContext *avctx); -int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame); - int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt); -int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *frame, int *got_packet); - void ff_nvenc_encode_flush(AVCodecContext *avctx); extern const enum AVPixelFormat ff_nvenc_pix_fmts[]; -extern const AVCodecHWConfigInternal *ff_nvenc_hw_configs[]; +extern const AVCodecHWConfigInternal *const ff_nvenc_hw_configs[]; #endif /* AVCODEC_NVENC_H */ diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index c877cf4a3..4c2585876 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -26,7 +26,11 @@ #define OFFSET(x) offsetof(NvencContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { +#ifdef NVENC_HAVE_NEW_PRESETS + { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_P4 }, PRESET_DEFAULT, PRESET_P7, VE, "preset" }, +#else { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" }, +#endif { "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" }, { "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" }, { "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" }, @@ -39,12 +43,30 @@ static const AVOption options[] = { { "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" }, { "lossless", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" }, { "losslesshp", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" }, +#ifdef NVENC_HAVE_NEW_PRESETS + { "p1", "fastest (lowest quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P1 }, 0, 0, VE, "preset" }, + { "p2", "faster (lower quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P2 }, 0, 0, VE, "preset" }, + { "p3", "fast (low quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P3 }, 0, 0, VE, "preset" }, + { "p4", "medium (default)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P4 }, 0, 0, VE, "preset" }, + { "p5", "slow (good quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P5 }, 0, 0, VE, "preset" }, + { "p6", "slower (better quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P6 }, 0, 0, VE, "preset" }, + { "p7", "slowest (best quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P7 }, 0, 0, VE, "preset" }, + { "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_LOSSLESS, VE, "tune" }, + { "hq", "High quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, 0, 0, VE, "tune" }, + { "ll", "Low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOW_LATENCY }, 0, 0, VE, "tune" }, + { "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, "tune" }, + { "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, "tune" }, +#endif { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_H264_PROFILE_MAIN }, NV_ENC_H264_PROFILE_BASELINE, NV_ENC_H264_PROFILE_HIGH_444P, VE, "profile" }, { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_BASELINE }, 0, 0, VE, "profile" }, { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_MAIN }, 0, 0, VE, "profile" }, { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH }, 0, 0, VE, "profile" }, { "high444p", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH_444P }, 0, 0, VE, "profile" }, - { "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_51, VE, "level" }, +#ifdef NVENC_HAVE_H264_LVL6 + { "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_62, VE, "level" }, +#else + { "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_52, VE, "level" }, +#endif { "auto", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, 0, 0, VE, "level" }, { "1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_1 }, 0, 0, VE, "level" }, { "1.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_1 }, 0, 0, VE, "level" }, @@ -68,6 +90,12 @@ static const AVOption options[] = { { "5", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_5 }, 0, 0, VE, "level" }, { "5.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_5 }, 0, 0, VE, "level" }, { "5.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_51 }, 0, 0, VE, "level" }, + { "5.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_52 }, 0, 0, VE, "level" }, +#ifdef NVENC_HAVE_H264_LVL6 + { "6.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_60 }, 0, 0, VE, "level" }, + { "6.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_61 }, 0, 0, VE, "level" }, + { "6.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_62 }, 0, 0, VE, "level" }, +#endif { "rc", "Override the preset rate-control", OFFSET(rc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "rc" }, { "constqp", "Constant QP mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CONSTQP }, 0, 0, VE, "rc" }, { "vbr", "Variable bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_VBR }, 0, 0, VE, "rc" }, @@ -78,9 +106,9 @@ static const AVOption options[] = { { "ll_2pass_size", "Multi-pass optimized for constant frame size (deprecated)", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP) }, 0, 0, VE, "rc" }, { "vbr_2pass", "Multi-pass variable bitrate mode (deprecated)", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_2_PASS_VBR) }, 0, 0, VE, "rc" }, - { "cbr_ld_hq", "Constant bitrate low delay high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ }, 0, 0, VE, "rc" }, - { "cbr_hq", "Constant bitrate high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CBR_HQ }, 0, 0, VE, "rc" }, - { "vbr_hq", "Variable bitrate high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_VBR_HQ }, 0, 0, VE, "rc" }, + { "cbr_ld_hq", "Constant bitrate low delay high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ) }, 0, 0, VE, "rc" }, + { "cbr_hq", "Constant bitrate high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_CBR_HQ) }, 0, 0, VE, "rc" }, + { "vbr_hq", "Variable bitrate high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_VBR_HQ) }, 0, 0, VE, "rc" }, { "rc-lookahead", "Number of frames to look ahead for rate-control", OFFSET(rc_lookahead), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, { "surfaces", "Number of concurrent surfaces", OFFSET(nb_surfaces), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_REGISTERED_FRAMES, VE }, @@ -142,6 +170,18 @@ static const AVOption options[] = { { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, { "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)", OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, +#ifdef NVENC_HAVE_MULTIPASS + { "multipass", "Set the multipass encoding", OFFSET(multipass), AV_OPT_TYPE_INT, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, NV_ENC_MULTI_PASS_DISABLED, NV_ENC_TWO_PASS_FULL_RESOLUTION, VE, "multipass" }, + { "disabled", "Single Pass", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, 0, 0, VE, "multipass" }, + { "qres", "Two Pass encoding is enabled where first Pass is quarter resolution", + 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_QUARTER_RESOLUTION }, 0, 0, VE, "multipass" }, + { "fullres", "Two Pass encoding is enabled where first Pass is full resolution", + 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_FULL_RESOLUTION }, 0, 0, VE, "multipass" }, +#endif +#ifdef NVENC_HAVE_LDKFS + { "ldkfs", "Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR", + OFFSET(ldkfs), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UCHAR_MAX, VE }, +#endif { NULL } }; @@ -153,7 +193,7 @@ static const AVCodecDefault defaults[] = { { "qblur", "-1" }, { "qcomp", "-1" }, { "g", "250" }, - { "bf", "0" }, + { "bf", "-1" }, { "refs", "0" }, { NULL }, }; @@ -180,9 +220,7 @@ AVCodec ff_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = nvenc_old_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .flush = ff_nvenc_encode_flush, .priv_data_size = sizeof(NvencContext), @@ -212,9 +250,7 @@ AVCodec ff_nvenc_h264_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = nvenc_old_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .flush = ff_nvenc_encode_flush, .priv_data_size = sizeof(NvencContext), @@ -244,16 +280,14 @@ AVCodec ff_h264_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = ff_nvenc_encode_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .flush = ff_nvenc_encode_flush, .priv_data_size = sizeof(NvencContext), .priv_class = &h264_nvenc_class, .defaults = defaults, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_ENCODER_FLUSH, + AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = ff_nvenc_pix_fmts, .wrapper_name = "nvenc", diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index 7f12b56a4..441e7871d 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -26,7 +26,11 @@ #define OFFSET(x) offsetof(NvencContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { +#ifdef NVENC_HAVE_NEW_PRESETS + { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_P4 }, PRESET_DEFAULT, PRESET_P7, VE, "preset" }, +#else { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" }, +#endif { "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" }, { "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" }, { "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" }, @@ -39,6 +43,20 @@ static const AVOption options[] = { { "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" }, { "lossless", "lossless", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" }, { "losslesshp", "lossless hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" }, +#ifdef NVENC_HAVE_NEW_PRESETS + { "p1", "fastest (lowest quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P1 }, 0, 0, VE, "preset" }, + { "p2", "faster (lower quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P2 }, 0, 0, VE, "preset" }, + { "p3", "fast (low quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P3 }, 0, 0, VE, "preset" }, + { "p4", "medium (default)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P4 }, 0, 0, VE, "preset" }, + { "p5", "slow (good quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P5 }, 0, 0, VE, "preset" }, + { "p6", "slower (better quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P6 }, 0, 0, VE, "preset" }, + { "p7", "slowest (best quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P7 }, 0, 0, VE, "preset" }, + { "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_LOSSLESS, VE, "tune" }, + { "hq", "High quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, 0, 0, VE, "tune" }, + { "ll", "Low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOW_LATENCY }, 0, 0, VE, "tune" }, + { "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, "tune" }, + { "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, "tune" }, +#endif { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, NV_ENC_HEVC_PROFILE_MAIN, FF_PROFILE_HEVC_REXT, VE, "profile" }, { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" }, { "main10", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, "profile" }, @@ -77,9 +95,9 @@ static const AVOption options[] = { { "ll_2pass_size", "Multi-pass optimized for constant frame size (deprecated)", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP) }, 0, 0, VE, "rc" }, { "vbr_2pass", "Multi-pass variable bitrate mode (deprecated)", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_2_PASS_VBR) }, 0, 0, VE, "rc" }, - { "cbr_ld_hq", "Constant bitrate low delay high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ }, 0, 0, VE, "rc" }, - { "cbr_hq", "Constant bitrate high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CBR_HQ }, 0, 0, VE, "rc" }, - { "vbr_hq", "Variable bitrate high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_VBR_HQ }, 0, 0, VE, "rc" }, + { "cbr_ld_hq", "Constant bitrate low delay high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ) }, 0, 0, VE, "rc" }, + { "cbr_hq", "Constant bitrate high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_CBR_HQ) }, 0, 0, VE, "rc" }, + { "vbr_hq", "Variable bitrate high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = RCD(NV_ENC_PARAMS_RC_VBR_HQ) }, 0, 0, VE, "rc" }, { "rc-lookahead", "Number of frames to look ahead for rate-control", OFFSET(rc_lookahead), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, { "surfaces", "Number of concurrent surfaces", OFFSET(nb_surfaces), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_REGISTERED_FRAMES, VE }, @@ -129,8 +147,22 @@ static const AVOption options[] = { { "each", "", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "b_ref_mode" }, { "middle", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, "b_ref_mode" }, #endif + { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, + { "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, { "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)", OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, +#ifdef NVENC_HAVE_MULTIPASS + { "multipass", "Set the multipass encoding", OFFSET(multipass), AV_OPT_TYPE_INT, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, NV_ENC_MULTI_PASS_DISABLED, NV_ENC_TWO_PASS_FULL_RESOLUTION, VE, "multipass" }, + { "disabled", "Single Pass", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, 0, 0, VE, "multipass" }, + { "qres", "Two Pass encoding is enabled where first Pass is quarter resolution", + 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_QUARTER_RESOLUTION }, 0, 0, VE, "multipass" }, + { "fullres", "Two Pass encoding is enabled where first Pass is full resolution", + 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_FULL_RESOLUTION }, 0, 0, VE, "multipass" }, +#endif +#ifdef NVENC_HAVE_LDKFS + { "ldkfs", "Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR", + OFFSET(ldkfs), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UCHAR_MAX, VE }, +#endif { NULL } }; @@ -142,7 +174,7 @@ static const AVCodecDefault defaults[] = { { "qblur", "-1" }, { "qcomp", "-1" }, { "g", "250" }, - { "bf", "0" }, + { "bf", "-1" }, { "refs", "0" }, { NULL }, }; @@ -168,10 +200,9 @@ AVCodec ff_nvenc_hevc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = nvenc_old_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, + .flush = ff_nvenc_encode_flush, .priv_data_size = sizeof(NvencContext), .priv_class = &nvenc_hevc_class, .defaults = defaults, @@ -198,9 +229,7 @@ AVCodec ff_hevc_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = ff_nvenc_encode_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .flush = ff_nvenc_encode_flush, .priv_data_size = sizeof(NvencContext), @@ -208,7 +237,7 @@ AVCodec ff_hevc_nvenc_encoder = { .defaults = defaults, .pix_fmts = ff_nvenc_pix_fmts, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_ENCODER_FLUSH, + AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .wrapper_name = "nvenc", .hw_configs = ff_nvenc_hw_configs, diff --git a/libavcodec/on2avc.c b/libavcodec/on2avc.c index 00e5bf539..d7a3e4945 100644 --- a/libavcodec/on2avc.c +++ b/libavcodec/on2avc.c @@ -23,6 +23,8 @@ #include "libavutil/channel_layout.h" #include "libavutil/ffmath.h" #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "bytestream.h" #include "fft.h" @@ -169,7 +171,7 @@ static int on2avc_decode_band_scales(On2AVCContext *c, GetBitContext *gb) scale = get_bits(gb, 7); first = 0; } else { - scale += get_vlc2(gb, c->scale_diff.table, 9, 3) - 60; + scale += get_vlc2(gb, c->scale_diff.table, 9, 3); } if (scale < 0 || scale > 127) { av_log(c->avctx, AV_LOG_ERROR, "Invalid scale value %d\n", @@ -195,7 +197,7 @@ static int on2avc_decode_quads(On2AVCContext *c, GetBitContext *gb, float *dst, int i, j, val, val1; for (i = 0; i < dst_size; i += 4) { - val = get_vlc2(gb, c->cb_vlc[type].table, 9, 3); + val = get_vlc2(gb, c->cb_vlc[type].table, 9, 2); for (j = 0; j < 4; j++) { val1 = sign_extend((val >> (12 - j * 4)) & 0xF, 4); @@ -228,7 +230,7 @@ static int on2avc_decode_pairs(On2AVCContext *c, GetBitContext *gb, float *dst, int i, val, val1, val2, sign; for (i = 0; i < dst_size; i += 2) { - val = get_vlc2(gb, c->cb_vlc[type].table, 9, 3); + val = get_vlc2(gb, c->cb_vlc[type].table, 9, 2); val1 = sign_extend(val >> 8, 8); val2 = sign_extend(val & 0xFF, 8); @@ -906,7 +908,9 @@ static av_cold void on2avc_free_vlcs(On2AVCContext *c) static av_cold int on2avc_decode_init(AVCodecContext *avctx) { On2AVCContext *c = avctx->priv_data; - int i; + const uint8_t *lens = ff_on2avc_cb_lens; + const uint16_t *syms = ff_on2avc_cb_syms; + int i, ret; if (avctx->channels > 2U) { avpriv_request_sample(avctx, "Decoding more than 2 channels"); @@ -956,36 +960,26 @@ static av_cold int on2avc_decode_init(AVCodecContext *avctx) if (!c->fdsp) return AVERROR(ENOMEM); - if (init_vlc(&c->scale_diff, 9, ON2AVC_SCALE_DIFFS, - ff_on2avc_scale_diff_bits, 1, 1, - ff_on2avc_scale_diff_codes, 4, 4, 0)) { + ret = ff_init_vlc_from_lengths(&c->scale_diff, 9, ON2AVC_SCALE_DIFFS, + ff_on2avc_scale_diff_bits, 1, + ff_on2avc_scale_diff_syms, 1, 1, -60, 0, avctx); + if (ret < 0) goto vlc_fail; - } - for (i = 1; i < 9; i++) { + for (i = 1; i < 16; i++) { int idx = i - 1; - if (ff_init_vlc_sparse(&c->cb_vlc[i], 9, ff_on2avc_quad_cb_elems[idx], - ff_on2avc_quad_cb_bits[idx], 1, 1, - ff_on2avc_quad_cb_codes[idx], 4, 4, - ff_on2avc_quad_cb_syms[idx], 2, 2, 0)) { + ret = ff_init_vlc_from_lengths(&c->cb_vlc[i], 9, ff_on2avc_cb_elems[idx], + lens, 1, + syms, 2, 2, 0, 0, avctx); + if (ret < 0) goto vlc_fail; - } - } - for (i = 9; i < 16; i++) { - int idx = i - 9; - if (ff_init_vlc_sparse(&c->cb_vlc[i], 9, ff_on2avc_pair_cb_elems[idx], - ff_on2avc_pair_cb_bits[idx], 1, 1, - ff_on2avc_pair_cb_codes[idx], 2, 2, - ff_on2avc_pair_cb_syms[idx], 2, 2, 0)) { - goto vlc_fail; - } + lens += ff_on2avc_cb_elems[idx]; + syms += ff_on2avc_cb_elems[idx]; } return 0; vlc_fail: av_log(avctx, AV_LOG_ERROR, "Cannot init VLC\n"); - on2avc_free_vlcs(c); - av_freep(&c->fdsp); - return AVERROR(ENOMEM); + return ret; } static av_cold int on2avc_decode_close(AVCodecContext *avctx) diff --git a/libavcodec/on2avcdata.c b/libavcodec/on2avcdata.c index ec983572e..bde50615c 100644 --- a/libavcodec/on2avcdata.c +++ b/libavcodec/on2avcdata.c @@ -110,6779 +110,2227 @@ const On2AVCMode ff_on2avc_modes_44[8] = { { 1, 49, on2avc_swb_start_long }, }; -const uint32_t ff_on2avc_scale_diff_codes[ON2AVC_SCALE_DIFFS] = { - 0x6FFFF, 0xBFFF2, 0xBFFF3, 0xBFFF4, 0xBFFF5, 0xBFFF6, - 0xBFFF7, 0xBFFF8, 0xBFFF9, 0xBFFFA, 0xBFFFB, 0xBFFFC, - 0xBFFFD, 0xBFFFE, 0xBFFFF, 0xDF9A0, 0xDF9A1, 0xDF9A2, - 0xDF9A3, 0xDF9A4, 0xDF9A5, 0xDF9A6, 0xDF9A7, 0xDF9A8, - 0xDF9A9, 0x37FFE, 0x6FCDE, 0x6FFFA, 0x0BFF7, 0x0B7FF, - 0x0DF9F, 0x05FF8, 0x0B7FE, 0x05FF9, 0x06FCE, 0x05BFE, - 0x037FE, 0x02DFE, 0x00DFA, 0x00DFE, 0x017FC, 0x00DBE, - 0x00B7E, 0x005FE, 0x0037D, 0x002DE, 0x0017E, 0x0016C, - 0x000DE, 0x000BE, 0x0006C, 0x0005A, 0x0003E, 0x00034, - 0x0002C, 0x0001F, 0x0000E, 0x0000E, 0x00006, 0x00002, - 0x00000, 0x00004, 0x0000A, 0x0000C, 0x0001E, 0x0001E, - 0x0002E, 0x00035, 0x0003F, 0x0005E, 0x0006E, 0x000DA, - 0x0016D, 0x0016E, 0x001B6, 0x002FE, 0x0036E, 0x0037C, - 0x005BE, 0x006DE, 0x006FE, 0x00DBF, 0x00DFB, 0x016FE, - 0x017FD, 0x01BFE, 0x01BF2, 0x02FFE, 0x06FCC, 0x05FFE, - 0x05FFA, 0x06FFE, 0x0BFF6, 0x0BFFE, 0x0DF9E, 0x00DF8, - 0x0DFFE, 0x37FFC, 0x6FFFB, 0x5FFF8, 0xDF9AA, 0xDF9AB, - 0xDF9AC, 0xDF9AD, 0xDF9AE, 0xDF9AF, 0xDF9B0, 0xDF9B1, - 0xDF9B2, 0xDF9B3, 0x6FFFE, 0xDF9B4, 0xDF9B5, 0xDF9B6, - 0xDF9B7, 0xDF9B8, 0xDF9B9, 0xDF9BA, 0xDF9BB, 0xDF9BE, - 0xDF9BF, +const uint8_t ff_on2avc_scale_diff_syms[ON2AVC_SCALE_DIFFS] = { + 60, 59, 63, 53, 67, 50, 71, 74, 76, 79, 41, 81, 70, 48, 77, + 44, 95, 86, 88, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 111, 112, 113, 114, 115, 116, + 117, 118, 26, 119, 120, 34, 94, 30, 38, 82, 80, 39, 85, 36, 91, + 96, 97, 27, 98, 25, 110, 0, 56, 65, 52, 68, 61, 62, 54, 51, + 47, 72, 73, 45, 78, 42, 83, 37, 35, 32, 29, 66, 69, 49, 46, + 75, 43, 40, 84, 31, 33, 90, 92, 28, 87, 89, 93, 99, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 58, 57, 64, + 55 }; const uint8_t ff_on2avc_scale_diff_bits[ON2AVC_SCALE_DIFFS] = { - 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, - 20, 20, 20, 21, 21, 21, - 21, 21, 21, 21, 21, 21, - 21, 19, 20, 20, 16, 16, - 17, 15, 16, 15, 16, 15, - 15, 14, 13, 13, 13, 13, - 12, 11, 11, 10, 9, 9, - 9, 8, 8, 7, 7, 7, - 6, 5, 5, 4, 3, 3, - 2, 3, 4, 5, 5, 6, - 6, 7, 7, 7, 8, 9, - 9, 9, 10, 10, 11, 11, - 11, 12, 12, 13, 13, 13, - 13, 14, 14, 14, 16, 15, - 15, 16, 16, 16, 17, 13, - 17, 19, 20, 19, 21, 21, - 21, 21, 21, 21, 21, 21, - 21, 21, 20, 21, 21, 21, - 21, 21, 21, 21, 21, 21, - 21, + 2, 3, 5, 7, 7, 8, 9, 10, 11, 12, 13, 13, 8, 9, 11, 11, 13, 14, 16, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 16, 17, 17, 13, 13, 12, 13, + 14, 15, 16, 17, 19, 20, 20, 19, 20, 20, 5, 6, 7, 7, 3, 4, 6, 7, 9, + 9, 9, 10, 11, 12, 13, 14, 15, 16, 16, 6, 7, 8, 9, 10, 11, 13, 13, 15, + 15, 15, 16, 16, 14, 15, 16, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 3, 4, 5, 5 }; -#define ON2AVC_CB1_CODES 41 -static const uint32_t on2avc_cb1_codes[ON2AVC_CB1_CODES] = { - 0x0000, 0x0022, 0x001C, 0x001B, 0x0024, 0x0030, - 0x0029, 0x0027, 0x0021, 0x002B, 0x002E, 0x0020, - 0x0026, 0x0033, 0x0031, 0x002C, 0x002A, 0x001E, - 0x0094, 0x01FF, 0x01F7, 0x012E, 0x001A, 0x01F5, - 0x007E, 0x012C, 0x01FC, 0x002D, 0x0032, 0x0028, - 0x002F, 0x001D, 0x01FD, 0x012D, 0x007C, 0x01F4, - 0x0023, 0x012F, 0x01F6, 0x01FE, 0x0095, +#define ON2AVC_CB_1_2_CODES 41 +#define ON2AVC_CB_3_4_CODES 313 +#define ON2AVC_CB_5_6_CODES 1201 +#define ON2AVC_CB_7_8_CODES 3281 +#define ON2AVC_CB_9_10_CODES 121 +#define ON2AVC_CB_11_CODES 225 +#define ON2AVC_CB_12_CODES 441 +#define ON2AVC_CB_13_CODES 625 +#define ON2AVC_CB_14_CODES 729 +#define ON2AVC_CB_15_CODES 1089 + +const uint8_t ff_on2avc_cb_lens[] = { + /* Codebook 1 - 41 entries */ + 1, 6, 6, 6, 6, 6, 8, 8, 9, 9, 9, 9, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 7, 9, 9, 9, 9, 7, 9, + 9, 9, 9, + /* Codebook 2 - 41 entries */ + 5, 7, 7, 7, 7, 5, 5, 5, 7, 7, 7, 7, 5, 5, 5, 5, 5, 7, 7, + 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 3, 5, + 5, 5, 5, + /* Codebook 3 - 313 entries */ + 1, 7, 7, 7, 9, 9, 10, 11, 12, 14, 14, 14, 15, 15, 10, 10, 7, 9, 9, + 9, 10, 11, 12, 12, 7, 10, 11, 11, 12, 12, 12, 13, 14, 15, 15, 11, 11, 9, + 9, 7, 9, 10, 11, 12, 12, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, + 11, 12, 13, 13, 11, 12, 13, 13, 9, 9, 7, 7, 7, 9, 9, 9, 10, 11, 11, + 9, 9, 9, 10, 13, 14, 16, 16, 16, 16, 13, 13, 12, 13, 13, 10, 12, 12, 12, + 14, 14, 14, 14, 10, 11, 12, 12, 9, 10, 10, 10, 11, 11, 10, 10, 9, 10, 13, + 14, 14, 13, 13, 12, 13, 14, 14, 9, 10, 10, 9, 10, 10, 6, 6, 6, 6, 8, + 11, 12, 14, 15, 15, 14, 14, 11, 12, 13, 13, 11, 13, 14, 15, 15, 13, 13, 11, + 11, 8, 9, 10, 10, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 14, 9, 10, + 11, 12, 12, 6, 9, 10, 10, 9, 10, 12, 13, 14, 15, 16, 17, 17, 12, 13, 14, + 15, 15, 8, 10, 11, 12, 13, 14, 14, 10, 10, 8, 10, 12, 12, 12, 12, 10, 10, + 9, 10, 11, 12, 13, 14, 15, 15, 10, 10, 10, 10, 9, 9, 9, 10, 12, 13, 14, + 15, 16, 16, 12, 12, 9, 10, 10, 9, 10, 10, 6, 6, 6, 6, 6, 9, 9, 11, + 12, 13, 14, 14, 11, 12, 12, 10, 10, 9, 10, 10, 9, 10, 11, 12, 13, 14, 14, + 9, 10, 12, 12, 12, 13, 14, 15, 16, 16, 9, 10, 10, 9, 10, 11, 12, 12, 9, + 10, 11, 12, 13, 13, 9, 9, 9, 11, 12, 13, 14, 14, 11, 11, 8, 9, 11, 12, + 13, 13, 11, 12, 13, 15, 15, 15, 15, + /* Codebook 4 - 313 entries */ + 7, 7, 7, 9, 9, 9, 10, 11, 12, 12, 6, 6, 6, 7, 9, 9, 9, 9, 6, + 6, 6, 7, 9, 9, 9, 9, 6, 6, 6, 7, 7, 6, 6, 9, 9, 9, 11, 12, + 12, 11, 11, 9, 9, 9, 11, 11, 11, 12, 12, 7, 9, 9, 9, 9, 7, 9, 9, + 9, 11, 11, 11, 11, 7, 9, 9, 9, 9, 6, 6, 6, 7, 9, 9, 9, 11, 11, + 11, 11, 6, 9, 9, 9, 9, 9, 9, 9, 9, 6, 6, 6, 6, 6, 9, 9, 9, + 11, 11, 11, 11, 9, 9, 9, 9, 6, 9, 10, 12, 13, 13, 12, 12, 9, 9, 9, + 9, 9, 9, 9, 11, 12, 12, 11, 12, 12, 9, 9, 9, 9, 9, 9, 9, 11, 12, + 12, 12, 12, 12, 12, 9, 10, 10, 10, 11, 12, 12, 10, 10, 9, 10, 10, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 12, 12, 12, 12, 11, 12, 12, 9, 9, 9, 9, 9, + 10, 10, 6, 9, 10, 10, 9, 9, 9, 10, 10, 9, 10, 10, 4, 6, 9, 10, 11, + 12, 12, 9, 10, 10, 9, 10, 11, 11, 10, 10, 10, 11, 12, 12, 9, 10, 10, 10, + 11, 12, 12, 10, 10, 8, 10, 10, 10, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 11, 12, 13, 14, 14, 10, 10, 8, 10, 10, 10, 11, 12, 12, 8, 10, 10, 10, + 10, 8, 8, 8, 10, 10, 10, 11, 11, 8, 8, 8, 10, 10, 10, 11, 11, 8, 10, + 11, 11, 10, 10, 8, 8, 8, 10, 10, 10, 10, 8, 10, 11, 11, 10, 10, 8, 9, + 10, 11, 13, 13, 13, 13, 9, 10, 10, 10, 11, 11, 10, 10, 6, 6, 5, 5, 5, + 6, 8, 9, 9, 8, 9, 10, 11, 11, + /* Codebook 5 - 1201 entries */ + 1, 7, 8, 10, 10, 10, 11, 12, 14, 14, 14, 14, 7, 10, 11, 14, 14, 14, 14, + 13, 13, 10, 12, 13, 15, 15, 15, 15, 12, 12, 10, 10, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 14, 14, 14, 14, 11, 12, 12, 7, + 10, 11, 13, 13, 13, 13, 11, 12, 12, 11, 11, 10, 11, 11, 10, 14, 14, 14, 14, + 14, 14, 14, 14, 12, 12, 7, 10, 10, 11, 12, 13, 14, 14, 12, 12, 12, 12, 10, + 13, 13, 13, 13, 12, 12, 12, 13, 16, 17, 17, 16, 16, 16, 16, 16, 16, 12, 12, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 14, 14, 14, + 14, 14, 14, 14, 14, 12, 13, 14, 14, 12, 12, 10, 11, 12, 12, 10, 12, 13, 13, + 12, 12, 10, 12, 12, 12, 12, 10, 11, 11, 10, 11, 11, 10, 10, 11, 14, 15, 15, + 14, 14, 14, 14, 14, 14, 11, 12, 13, 13, 8, 9, 10, 10, 9, 10, 12, 12, 12, + 13, 13, 9, 10, 11, 12, 13, 15, 15, 15, 15, 8, 8, 8, 11, 12, 12, 11, 12, + 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, + 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 12, 13, 13, 9, 12, 12, + 12, 13, 13, 11, 12, 12, 9, 10, 11, 13, 13, 13, 14, 15, 17, 17, 17, 17, 8, + 9, 11, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 8, 10, + 13, 14, 14, 13, 13, 12, 12, 11, 12, 13, 14, 17, 17, 17, 17, 17, 17, 17, 17, + 11, 11, 10, 11, 13, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 16, 17, 17, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, 12, 9, 11, 12, + 13, 14, 14, 12, 13, 13, 12, 12, 10, 11, 11, 10, 12, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 8, 14, 14, 14, 14, 13, 14, 14, 13, 13, 13, 13, 12, + 13, 13, 12, 13, 13, 10, 11, 12, 12, 7, 7, 7, 7, 7, 11, 12, 13, 13, 11, + 12, 13, 15, 16, 16, 15, 15, 12, 12, 12, 12, 11, 11, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, + 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, + 13, 13, 13, 12, 12, 12, 12, 12, 12, 7, 7, 7, 11, 12, 12, 11, 11, 11, 12, + 13, 14, 14, 11, 12, 13, 13, 9, 10, 12, 13, 13, 12, 12, 7, 7, 7, 7, 7, + 9, 12, 13, 14, 14, 12, 12, 11, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 13, + 14, 14, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, 12, 11, 12, 13, 14, 16, 16, + 16, 16, 7, 10, 10, 11, 12, 12, 11, 11, 9, 13, 13, 13, 13, 12, 13, 13, 12, + 12, 12, 13, 16, 16, 16, 16, 16, 16, 16, 16, 7, 8, 9, 11, 12, 12, 11, 12, + 12, 7, 11, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, + 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 11, + 11, 12, 12, 12, 12, 8, 9, 11, 13, 14, 14, 13, 13, 13, 13, 13, 13, 12, 13, + 13, 8, 8, 10, 12, 12, 12, 12, 10, 11, 12, 12, 9, 12, 12, 12, 12, 11, 11, + 11, 11, 11, 11, 10, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, + 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 11, 11, 7, + 11, 11, 11, 11, 11, 11, 11, 12, 12, 11, 11, 11, 12, 13, 13, 10, 10, 9, 12, + 13, 13, 12, 12, 11, 11, 9, 10, 11, 12, 13, 15, 15, 15, 15, 8, 9, 11, 11, + 11, 12, 15, 15, 15, 15, 15, 15, 15, 15, 9, 10, 11, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9, 15, 15, 15, 15, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 13, 14, 14, 13, 13, 13, 13, 12, 13, 13, 9, 11, 12, + 12, 11, 11, 11, 12, 13, 13, 11, 12, 12, 10, 11, 12, 13, 13, 6, 6, 6, 10, + 11, 11, 10, 10, 11, 13, 13, 13, 13, 11, 12, 13, 14, 15, 18, 18, 18, 18, 18, + 18, 18, 18, 10, 12, 12, 12, 12, 9, 9, 9, 9, 6, 11, 14, 14, 14, 14, 14, + 14, 14, 14, 13, 14, 14, 13, 13, 12, 13, 13, 12, 12, 12, 12, 11, 11, 11, 12, + 12, 11, 11, 10, 11, 12, 13, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 13, 13, 13, 13, 13, 13, 13, 13, 11, 12, 12, 11, 12, 13, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 18, 11, 11, 11, 11, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, + 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 14, 14, 14, 14, 13, 14, 14, 11, + 13, 13, 13, 13, + /* Codebook 6 - 1201 entries */ + 8, 10, 12, 13, 13, 12, 13, 14, 16, 17, 17, 16, 16, 10, 11, 11, 8, 10, 11, + 11, 10, 10, 10, 10, 11, 12, 13, 14, 14, 11, 11, 10, 10, 10, 11, 12, 12, 8, + 10, 11, 12, 12, 10, 11, 11, 8, 10, 10, 10, 11, 13, 13, 13, 13, 10, 11, 12, + 13, 13, 10, 10, 10, 11, 12, 12, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 12, + 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 10, 12, 12, 12, 13, + 14, 15, 15, 10, 10, 10, 11, 12, 12, 10, 11, 12, 12, 9, 10, 11, 11, 10, 13, + 13, 13, 13, 12, 12, 10, 11, 11, 10, 11, 12, 12, 10, 10, 10, 11, 11, 11, 11, + 11, 11, 10, 10, 11, 11, 11, 14, 15, 15, 14, 14, 13, 13, 10, 13, 13, 13, 13, + 12, 12, 11, 11, 11, 11, 10, 10, 11, 12, 13, 14, 14, 11, 11, 10, 10, 10, 10, + 11, 11, 11, 11, 10, 10, 10, 11, 12, 13, 13, 10, 10, 10, 11, 11, 10, 13, 13, + 13, 13, 12, 13, 13, 11, 12, 12, 11, 11, 10, 10, 10, 10, 11, 11, 11, 11, 9, + 10, 11, 12, 12, 11, 12, 13, 14, 14, 11, 11, 11, 11, 11, 11, 10, 10, 13, 13, + 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 10, 11, 11, 10, 11, 11, 10, 12, 13, + 13, 12, 12, 11, 11, 11, 11, 10, 11, 11, 10, 11, 11, 11, 11, 11, 11, 10, 11, + 13, 13, 13, 13, 9, 10, 13, 13, 13, 13, 12, 12, 11, 11, 11, 11, 10, 11, 11, + 10, 11, 12, 12, 11, 11, 11, 11, 11, 12, 12, 11, 11, 10, 11, 11, 9, 10, 10, + 11, 12, 14, 15, 16, 17, 17, 14, 14, 11, 11, 12, 13, 13, 12, 12, 11, 12, 12, + 11, 11, 11, 11, 11, 11, 11, 11, 9, 10, 11, 12, 13, 13, 10, 10, 10, 10, 11, + 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 7, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 12, 13, 13, 12, 12, 12, 12, 11, 11, 10, 10, 10, 11, 12, 12, 10, 11, 11, + 10, 11, 12, 12, 10, 11, 12, 14, 14, 14, 14, 11, 11, 11, 11, 11, 11, 11, 11, + 10, 10, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 10, 11, + 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 12, 12, 12, 12, 11, 12, 12, 11, 11, + 11, 11, 10, 11, 11, 11, 11, 11, 11, 10, 11, 11, 10, 11, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, + 11, 11, 10, 10, 11, 12, 13, 15, 16, 17, 17, 15, 15, 11, 11, 10, 10, 7, 10, + 12, 12, 12, 12, 11, 11, 11, 11, 9, 11, 12, 14, 14, 14, 14, 11, 11, 7, 11, + 11, 11, 11, 10, 10, 10, 10, 10, 10, 7, 13, 13, 13, 13, 12, 12, 11, 11, 11, + 11, 11, 11, 9, 10, 11, 11, 10, 10, 10, 12, 13, 14, 14, 12, 12, 11, 11, 11, + 11, 11, 11, 11, 11, 10, 10, 10, 11, 11, 10, 11, 11, 11, 11, 11, 11, 10, 10, + 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 11, 12, 12, 11, 11, 11, 11, + 11, 11, 10, 11, 11, 10, 10, 10, 11, 12, 13, 14, 14, 10, 11, 12, 12, 7, 7, + 10, 11, 11, 11, 11, 11, 11, 10, 11, 12, 14, 14, 14, 14, 11, 11, 11, 11, 10, + 10, 10, 11, 13, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, 12, 11, 11, 11, + 11, 7, 9, 10, 11, 11, 11, 11, 11, 11, 10, 11, 11, 7, 9, 10, 10, 9, 10, + 10, 12, 12, 12, 12, 11, 11, 10, 11, 11, 10, 11, 11, 10, 10, 9, 10, 11, 11, + 13, 14, 14, 13, 13, 13, 13, 13, 13, 11, 11, 11, 11, 11, 11, 7, 10, 10, 10, + 11, 12, 13, 13, 9, 10, 11, 11, 7, 10, 11, 11, 11, 11, 11, 11, 9, 10, 11, + 11, 7, 7, 7, 7, 9, 10, 10, 10, 11, 12, 13, 13, 11, 11, 11, 11, 10, 10, + 10, 10, 9, 10, 10, 9, 10, 13, 13, 13, 13, 12, 12, 9, 11, 12, 12, 11, 11, + 10, 11, 12, 12, 10, 10, 9, 10, 11, 11, 7, 7, 7, 11, 12, 12, 11, 11, 10, + 11, 11, 10, 11, 11, 10, 11, 11, 7, 9, 10, 13, 13, 13, 13, 13, 13, 13, 13, + 10, 11, 12, 13, 13, 10, 11, 12, 12, 9, 10, 11, 11, 10, 10, 10, 11, 12, 12, + 9, 10, 11, 11, 9, 10, 10, 7, 9, 10, 11, 12, 14, 15, 16, 17, 17, 14, 14, + 10, 10, 11, 11, 11, 11, 10, 11, 11, 10, 10, 9, 10, 10, 9, 10, 10, 9, 10, + 13, 13, 13, 13, 13, 13, 13, 13, 7, 12, 12, 12, 12, 11, 12, 12, 10, 10, 10, + 11, 11, 10, 11, 11, 7, 7, 7, 10, 10, 10, 10, 9, 10, 10, 7, 9, 10, 12, + 13, 13, 12, 12, 9, 12, 12, 12, 12, 11, 11, 7, 7, 7, 9, 10, 10, 10, 10, + 10, 11, 12, 13, 13, 10, 10, 10, 11, 13, 13, 13, 13, 9, 10, 13, 13, 13, 13, + 12, 12, 9, 10, 10, 9, 10, 11, 12, 12, 10, 10, 10, 10, 10, 11, 11, 10, 11, + 11, 9, 10, 10, 9, 9, 9, 12, 12, 12, 12, 11, 11, 10, 10, 10, 10, 9, 9, + 9, 10, 11, 12, 13, 14, 14, 7, 9, 9, 9, 10, 11, 11, 7, 9, 9, 10, 11, + 12, 13, 13, 10, 10, 7, 10, 10, 10, 11, 11, 10, 11, 11, 10, 10, 9, 10, 10, + 9, 10, 10, 9, 9, 9, 9, 9, 11, 12, 12, 11, 11, 9, 10, 11, 12, 12, 10, + 10, 10, 10, 9, 10, 11, 11, 9, 9, 9, 10, 10, 9, 10, 11, 12, 12, 9, 10, + 10, 7, 9, 10, 10, 10, 11, 12, 12, 10, 10, 7, 9, 10, 10, 9, 10, 12, 12, + 12, 12, 7, 10, 11, 11, 10, 10, 9, 9, 7, 9, 10, 10, 9, 10, 10, 9, 10, + 10, 10, 11, 12, 12, 10, 10, 9, 9, 10, 12, 12, 12, 12, 10, 11, 11, 7, 9, + 10, 10, 9, 10, 11, 11, 7, 9, 9, 10, 10, 10, 10, 9, 10, 10, 9, 9, 9, + 10, 13, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 10, 10, 7, + 9, 10, 11, 12, 12, 9, 9, 9, 10, 10, 9, 9, 12, 12, 12, 12, 11, 11, 10, + 10, 9, 10, 11, 13, 13, 13, 13, 9, 9, 9, 9, 12, 12, 12, 12, 11, 11, 10, + 10, 9, 10, 10, + /* Codebook 7 - 3281 entries */ + 1, 7, 11, 12, 12, 12, 13, 14, 15, 15, 13, 13, 13, 13, 13, 13, 13, 14, 14, + 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, 13, + 13, 10, 12, 13, 13, 12, 12, 7, 7, 7, 11, 12, 13, 13, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 11, 12, 13, 15, 15, 15, 15, 11, + 11, 12, 12, 12, 12, 11, 11, 7, 7, 7, 9, 9, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 11, 11, + 9, 11, 11, 12, 13, 14, 14, 12, 12, 10, 11, 12, 12, 13, 13, 13, 13, 12, 13, + 13, 11, 12, 12, 11, 12, 13, 14, 14, 11, 12, 12, 11, 11, 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, 13, 14, 14, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, + 12, 12, 12, 12, 11, 11, 10, 12, 13, 13, 12, 12, 12, 12, 12, 12, 11, 11, 11, + 12, 13, 13, 11, 11, 9, 10, 11, 13, 13, 13, 13, 7, 13, 13, 13, 13, 12, 13, + 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 11, 12, 12, 11, 16, + 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, + 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, + 12, 12, 12, 11, 12, 12, 11, 11, 11, 11, 11, 12, 12, 10, 11, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, 12, 11, 11, + 9, 12, 13, 14, 14, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 11, 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, 7, 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, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 7, 9, 9, 10, 11, + 12, 13, 13, 12, 12, 12, 12, 11, 12, 12, 7, 7, 7, 7, 7, 9, 11, 11, 11, + 13, 13, 13, 13, 10, 13, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, 12, 12, + 12, 7, 9, 11, 12, 12, 11, 12, 13, 15, 16, 17, 17, 15, 15, 10, 11, 12, 12, + 10, 12, 12, 12, 12, 7, 7, 9, 12, 12, 12, 12, 11, 12, 12, 9, 10, 11, 12, + 15, 15, 15, 15, 15, 15, 15, 15, 9, 10, 11, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 7, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 14, 15, 15, 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, 13, 13, 13, 13, + 13, 13, 13, 13, 7, 13, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, 12, 12, + 12, 11, 11, 9, 11, 12, 13, 13, 11, 11, 7, 9, 10, 12, 12, 12, 12, 9, 12, + 12, 12, 12, 11, 12, 12, 7, 9, 11, 12, 13, 13, 11, 13, 13, 13, 13, 9, 9, + 7, 9, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 11, + 11, 11, 11, 12, 12, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 11, 11, 11, 11, 8, 11, 14, 15, + 17, 17, 17, 17, 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, 14, 14, 13, 14, 14, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 12, 12, 12, 12, 11, 12, 12, 10, 11, 11, 9, 10, 11, 12, 13, 13, 10, + 11, 11, 11, 12, 12, 12, 12, 12, 12, 8, 9, 12, 12, 12, 12, 11, 11, 8, 10, + 11, 12, 13, 13, 10, 11, 11, 8, 10, 11, 11, 10, 13, 13, 13, 13, 13, 13, 13, + 13, 8, 12, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 8, + 10, 11, 11, 10, 11, 12, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 6, 8, 11, 11, 11, 11, 10, 12, 12, 12, 12, 8, 12, 12, 12, + 12, 12, 12, 12, 12, 11, 12, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 11, 11, 11, 11, 11, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 10, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 17, + 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 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, 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, 12, 12, 11, 12, 12, 10, 11, 11, + /* Codebook 8 - 3281 entries */ + 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, 13, 14, 14, 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, 12, 13, 13, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 11, 11, 10, + 11, 11, 9, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 9, 11, 11, 11, 11, 9, 13, 14, + 14, 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, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 9, 10, 11, 11, 11, 11, + 11, 11, 10, 11, 11, 10, 11, 12, 12, 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, 11, 12, 12, 11, + 11, 11, 11, 10, 10, 11, 11, 11, 11, 9, 10, 11, 11, 10, 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, 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, 14, 14, 14, 14, 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, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 12, 13, 13, 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, 11, 12, 12, 11, 11, 11, 11, 10, 11, 11, 10, 10, 9, 11, 11, 11, + 11, 11, 11, 11, 11, 10, 11, 11, 9, 10, 10, 12, 13, 14, 15, 15, 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, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 10, 10, 9, 10, 11, 11, 9, 11, 11, 11, 11, 11, 11, 11, 11, 10, + 10, 9, 9, 10, 11, 13, 13, 13, 13, 10, 10, 9, 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, + 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, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, + 11, 10, 11, 11, 10, 10, 10, 10, 9, 9, 11, 12, 13, 15, 15, 15, 15, 11, 11, + 11, 11, 11, 11, 10, 11, 11, 10, 10, 9, 9, 10, 11, 12, 12, 10, 10, 7, 9, + 10, 12, 12, 12, 12, 9, 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, 11, 12, 12, 11, + 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 10, 10, 10, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 9, 10, 11, 11, 10, 10, 10, 10, 8, 9, + 10, 10, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 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, + 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 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, 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, 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, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 9, 10, 10, + 9, 10, 10, 9, 10, 10, 9, 9, 9, 11, 12, 13, 14, 15, 16, 16, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 10, 10, 7, 10, 11, + 12, 12, 10, 10, 10, 10, 10, 10, 8, 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, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 10, 11, 11, 10, 10, 10, 11, + 12, 13, 13, 10, 10, 10, 10, 10, 10, 9, 10, 10, 9, 9, 7, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 9, 9, 10, 11, 13, + 13, 13, 13, 10, 13, 13, 13, 13, 13, 13, 13, 13, 9, 9, 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, 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, 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, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 10, 11, 11, 10, 10, 10, 10, 9, 10, 10, 8, 9, 10, 10, 9, 10, 10, + 9, 11, 12, 13, 14, 14, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 10, 11, 11, 10, 10, 10, 10, 9, 10, 10, 9, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 12, 12, 12, 12, 9, 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, 11, 12, + 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 10, + 10, 10, 10, 9, 10, 10, 10, 11, 12, 14, 14, 14, 14, 10, 10, 9, 10, 10, 9, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 10, 10, + 10, 10, 9, 9, 9, 10, 11, 14, 14, 14, 14, 14, 14, 14, 14, 9, 10, 10, 8, + 10, 10, 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, 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, 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, + 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, + 12, 13, 13, 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, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 10, 10, 9, 10, 10, 6, 8, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 10, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 10, 10, 10, 10, + 10, 10, 9, 9, 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, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 10, 10, 10, 10, 10, 11, 12, 13, 14, 16, 16, 16, 16, 10, 10, + 6, 10, 10, 10, 10, 9, 10, 10, 9, 9, 11, 11, 11, 11, 11, 11, 11, 11, 6, + 11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 9, 9, 10, 10, 10, 10, + 10, 10, 10, 10, 9, 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, 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, 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, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 10, 10, 9, + 9, 10, 11, 11, 10, 10, 9, 10, 10, 9, 9, 9, 9, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 7, 10, + 10, 10, 11, 12, 12, 10, 10, 10, 10, 9, 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, 11, 12, + 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 10, 10, 10, 10, 9, 10, 10, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 10, 11, 11, 10, 10, 10, 10, 10, 10, 9, 10, 10, 9, 10, 10, 9, + 10, 10, 7, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, + 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, + 15, 15, 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, 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, 14, 14, 14, + 14, 14, 14, 14, 14, 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, + /* Codebook 9 - 121 entries */ + 1, 5, 8, 9, 10, 11, 11, 9, 10, 11, 11, 10, 12, 12, 12, 12, 11, 11, 11, + 11, 9, 10, 11, 12, 13, 13, 10, 11, 11, 10, 10, 8, 9, 11, 12, 12, 11, 11, + 5, 8, 9, 10, 10, 8, 9, 10, 10, 8, 8, 8, 9, 10, 11, 12, 12, 8, 9, + 9, 8, 9, 9, 8, 8, 8, 11, 12, 12, 11, 11, 10, 11, 11, 7, 8, 9, 10, + 10, 8, 8, 8, 9, 9, 5, 9, 10, 11, 11, 9, 10, 11, 11, 8, 9, 9, 8, + 8, 8, 8, 5, 5, 5, 9, 11, 12, 12, 11, 11, 9, 9, 8, 9, 10, 10, 8, + 8, 8, 9, 10, 10, 4, 4, + /* Codebook 10 - 121 entries */ + 9, 9, 9, 9, 8, 9, 9, 7, 8, 9, 9, 8, 9, 9, 8, 8, 8, 8, 8, + 8, 5, 6, 8, 8, 8, 8, 7, 8, 8, 7, 7, 7, 8, 9, 9, 7, 8, 8, + 7, 7, 7, 8, 9, 9, 6, 7, 7, 5, 6, 7, 7, 6, 7, 8, 9, 9, 6, + 6, 5, 6, 6, 5, 7, 7, 7, 7, 6, 7, 7, 6, 7, 8, 8, 5, 7, 7, + 7, 7, 5, 7, 8, 8, 8, 8, 8, 8, 5, 6, 7, 7, 6, 7, 8, 8, 6, + 7, 8, 8, 5, 6, 7, 8, 8, 7, 7, 8, 9, 9, 8, 8, 6, 7, 8, 8, + 6, 7, 8, 8, 6, 7, 7, + /* Codebook 11 - 225 entries */ + 2, 10, 10, 10, 10, 9, 10, 11, 11, 10, 10, 10, 10, 9, 9, 9, 10, 11, 11, + 9, 10, 10, 10, 11, 12, 12, 10, 11, 11, 9, 9, 9, 10, 10, 9, 9, 8, 10, + 11, 11, 10, 10, 9, 10, 10, 10, 10, 10, 11, 11, 9, 10, 10, 9, 10, 10, 8, + 9, 10, 10, 9, 10, 11, 11, 9, 10, 10, 9, 10, 11, 11, 9, 10, 10, 9, 10, + 10, 10, 10, 10, 10, 8, 9, 10, 11, 11, 8, 9, 9, 9, 10, 10, 9, 10, 11, + 11, 9, 10, 10, 9, 10, 11, 11, 9, 10, 10, 9, 10, 10, 9, 10, 11, 11, 9, + 9, 9, 10, 10, 9, 9, 9, 9, 9, 10, 11, 11, 7, 9, 10, 10, 9, 9, 7, + 9, 10, 10, 10, 10, 10, 10, 5, 7, 7, 7, 7, 5, 5, 5, 9, 10, 10, 9, + 10, 10, 9, 9, 10, 11, 11, 10, 10, 7, 7, 9, 10, 10, 9, 10, 10, 8, 10, + 10, 10, 10, 9, 10, 10, 9, 9, 8, 9, 9, 7, 8, 10, 10, 10, 10, 7, 8, + 9, 10, 10, 7, 9, 10, 10, 9, 10, 10, 8, 8, 9, 9, 9, 10, 10, 7, 8, + 9, 10, 10, 8, 9, 10, 10, 9, 9, 9, 10, 10, 4, 4, 4, 4, + /* Codebook 12 - 441 entries */ + 2, 10, 11, 11, 11, 12, 12, 11, 11, 10, 12, 12, 12, 12, 10, 11, 11, 12, 12, + 12, 12, 11, 11, 10, 11, 11, 10, 12, 13, 13, 12, 12, 10, 12, 12, 12, 12, 10, + 11, 12, 12, 10, 12, 12, 12, 12, 11, 12, 12, 11, 12, 12, 11, 11, 11, 11, 10, + 11, 11, 10, 10, 12, 12, 12, 12, 11, 12, 12, 10, 11, 12, 12, 10, 11, 11, 10, + 11, 11, 11, 12, 12, 11, 11, 10, 10, 10, 10, 10, 11, 12, 13, 13, 10, 11, 12, + 12, 12, 12, 12, 12, 11, 11, 10, 11, 11, 11, 12, 13, 13, 12, 12, 12, 12, 11, + 12, 12, 11, 11, 10, 11, 12, 12, 9, 10, 10, 10, 11, 12, 12, 11, 11, 11, 11, + 10, 11, 11, 10, 10, 9, 11, 11, 11, 11, 9, 10, 11, 11, 9, 10, 11, 13, 14, + 14, 13, 13, 8, 9, 12, 12, 12, 12, 11, 11, 9, 10, 11, 11, 9, 10, 11, 12, + 12, 8, 10, 11, 12, 12, 10, 11, 11, 10, 11, 12, 12, 10, 10, 11, 11, 11, 11, + 10, 11, 12, 12, 10, 11, 11, 11, 11, 11, 11, 9, 10, 11, 11, 8, 9, 10, 11, + 11, 5, 10, 11, 12, 12, 10, 11, 11, 9, 10, 10, 8, 10, 11, 12, 12, 10, 11, + 11, 11, 11, 11, 11, 10, 10, 9, 9, 9, 11, 12, 13, 13, 12, 12, 12, 12, 11, + 11, 11, 11, 10, 10, 5, 5, 5, 9, 10, 11, 12, 12, 11, 11, 11, 12, 12, 11, + 11, 11, 11, 10, 10, 10, 11, 11, 11, 11, 11, 11, 10, 12, 12, 12, 12, 11, 12, + 12, 11, 11, 10, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 10, 11, 12, 12, + 10, 11, 11, 7, 9, 9, 10, 11, 11, 10, 10, 7, 7, 7, 10, 11, 11, 10, 10, + 10, 10, 10, 11, 12, 12, 7, 7, 7, 7, 7, 10, 11, 12, 12, 10, 11, 11, 10, + 11, 11, 10, 11, 11, 7, 10, 10, 10, 10, 9, 10, 10, 7, 10, 10, 10, 11, 11, + 10, 10, 10, 11, 12, 12, 7, 10, 11, 11, 10, 11, 11, 9, 10, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 9, 10, 11, 11, 10, 10, 10, 10, 9, 11, 11, 11, 11, 10, + 11, 11, 10, 11, 12, 12, 9, 10, 11, 11, 10, 11, 11, 10, 10, 10, 11, 12, 12, + 10, 11, 11, 10, 10, 10, 10, 9, 9, 10, 11, 11, 10, 10, 9, 11, 11, 11, 11, + 4, 4, 4, 4, + /* Codebook 13 - 625 entries */ + 1, 8, 10, 10, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 12, 12, 9, 12, 12, 12, 12, 11, 12, 12, 8, 9, 10, 11, + 12, 12, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 11, 12, 12, 11, 11, 10, 11, 12, 13, 13, 11, 11, 11, 11, 11, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 8, 8, 13, 13, 13, 13, 13, 13, + 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 5, 8, 11, 12, 12, + 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 10, 11, 11, 10, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 10, 11, 11, 8, 8, 11, 11, 11, 11, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 5, 5, 5, 11, 11, 11, 11, 10, 11, 11, 11, 11, + 11, 11, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, + 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 11, 11, 10, 11, 13, 14, 16, 16, 16, + 16, 13, 13, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 12, 12, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 11, 12, 12, 11, 11, 10, 11, 12, 15, 15, 15, 15, 14, 14, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 10, 11, 11, + 10, 11, 12, 13, 14, 15, 15, 11, 11, 11, 11, 11, 11, 11, 11, 10, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 11, 11, + 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 11, 12, 13, 13, 11, 11, 11, 11, 11, + 11, 10, 11, 11, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 5, 12, 12, + 12, 12, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 11, + 12, 13, 14, 14, 10, 11, 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 10, 10, 10, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, + 10, 11, 11, 10, 10, 5, 5, 5, 7, 8, 10, 10, 11, 12, 14, 14, 14, 14, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 8, 9, 9, + /* Codebook 14 - 729 entries */ + 1, 6, 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, 12, 13, 13, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 11, + 11, 11, 11, 11, 11, 11, 6, 8, 10, 11, 11, 10, 11, 12, 13, 13, 8, 11, 11, + 11, 11, 10, 10, 6, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 9, + 10, 10, 8, 8, 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, 11, 11, 5, 8, 10, 11, 11, 10, 11, + 12, 13, 13, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 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, 5, 5, 5, 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, 12, 13, 13, 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, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 10, 11, 11, 9, 10, 10, 9, 10, 10, 10, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 9, 10, 12, 12, 12, + 12, 9, 9, 9, 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, 11, 12, 12, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, + 10, 7, 9, 10, 10, 9, 9, 7, 9, 10, 10, 10, 10, 10, 10, 8, 9, 10, 11, + 11, 8, 9, 11, 11, 11, 11, 8, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 10, 10, 10, 10, 10, 10, 9, 10, 10, 9, 9, 9, 10, 10, 9, 9, 5, 9, + 9, 9, 9, 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, 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, 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, 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, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, + /* Codebook 15 - 1089 entries */ + 2, 5, 8, 8, 12, 12, 12, 12, 11, 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, 12, 12, 11, 11, 11, 11, 8, 11, 12, 13, 14, 14, 11, 12, 12, 11, + 11, 11, 11, 11, 11, 11, 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, 13, 14, 14, 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, 5, 5, 5, 6, 6, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 11, + 11, 11, 11, 11, 11, 11, 11, 10, 11, 12, 12, 10, 11, 12, 12, 11, 12, 13, 14, + 17, 17, 17, 17, 16, 16, 11, 11, 11, 11, 11, 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, 11, 12, 12, 10, 11, 11, 9, 9, 9, 11, 11, 12, 12, 12, 12, 11, 12, 12, + 11, 11, 11, 11, 11, 11, 9, 10, 11, 11, 9, 10, 11, 11, 16, 16, 16, 16, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 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, 9, 12, 13, 13, 12, 12, 11, 12, + 13, 14, 14, 11, 12, 12, 12, 12, 12, 12, 10, 11, 12, 12, 9, 10, 11, 11, 10, + 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, 12, 13, 13, 12, 12, 12, 12, 11, 12, 12, 11, 11, 10, + 11, 12, 12, 9, 11, 11, 11, 11, 10, 11, 11, 10, 10, 12, 12, 12, 12, 12, 12, + 12, 12, 10, 11, 12, 12, 9, 10, 11, 12, 14, 14, 14, 14, 9, 10, 11, 11, 9, + 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 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, 12, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 9, 11, 12, 12, 12, + 12, 12, 12, 9, 9, 8, 12, 12, 12, 12, 11, 11, 10, 10, 5, 9, 10, 11, 13, + 13, 13, 13, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 9, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 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, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, + 12, 11, 11, 10, 11, 11, 10, 10, 5, 5, 5, 5, 5, 7, 10, 10, 10, 10, 10, + 12, 13, 15, 15, 15, 15, 12, 12, 10, 10, 8, 10, 10, 12, 12, 12, 12, 12, 12, + 12, 12, 8, 12, 12, 12, 12, 12, 12, 12, 12, 10, 11, 12, 12, 10, 10, 10, 11, + 11, 10, 10, 10, 10, 9, 10, 10, 14, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 13, 14, 14, 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, 12, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 11, 12, 12, 10, 10, 10, 11, 12, 12, 9, 10, 10, 9, 11, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 10, 11, 12, 12, 10, 11, 11, 10, 11, 11, + 9, 10, 10, 7, 10, 11, 13, 14, 14, 13, 13, 10, 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, 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, 11, + 12, 12, 10, 11, 11, 10, 10, 10, 11, 12, 12, 7, 10, 10, 10, 10, 10, 10, 10, + 10, 7, 9, 10, 10, 10, 10, 10, 10, 7, 7, 7, 10, 10, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 7, + 10, 10, 10, 11, 11, 10, 11, 11, 11, 11, 11, 11, 7, 10, 10, 10, 10, 9, 10, + 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 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, 12, 13, 13, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, + 11, 10, 11, 11, 10, 10 }; -static const uint8_t on2avc_cb1_bits[ON2AVC_CB1_CODES] = { - 1, 6, 5, 5, 6, 6, - 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 5, - 8, 9, 9, 9, 5, 9, - 7, 9, 9, 6, 6, 6, - 6, 5, 9, 9, 7, 9, - 6, 9, 9, 9, 8, +const uint16_t ff_on2avc_cb_syms[] = { + /* Codebook 1 - 41 entries */ + 0x0000, 0x0F10, 0x01F0, 0x0011, 0xFF00, 0x00FF, 0x1111, 0xFFFF, 0x1FF1, + 0xF11F, 0x11FF, 0xFF11, 0x0FF0, 0x0110, 0xF010, 0x010F, 0x10F0, 0x0F01, + 0x1010, 0xF001, 0x0F0F, 0xF0F0, 0x0101, 0x100F, 0xF00F, 0x1001, 0x1F00, + 0x00F1, 0x001F, 0xF100, 0x1100, 0xF1F1, 0xF1FF, 0x1F11, 0xFF1F, 0x11F1, + 0x1F1F, 0x1FFF, 0xF111, 0xFFF1, 0x111F, + /* Codebook 2 - 41 entries */ + 0x00FF, 0xFFFF, 0x1111, 0x11FF, 0xFF11, 0xFF00, 0x0011, 0x100F, 0x1FF1, + 0xF11F, 0x1FFF, 0x11F1, 0xF001, 0x10F0, 0x0F10, 0x010F, 0xF010, 0x1F11, + 0xF111, 0xF1FF, 0x111F, 0x0F01, 0x01F0, 0x0110, 0x1001, 0x0FF0, 0xF00F, + 0x1010, 0xF0F0, 0x0101, 0x0F0F, 0x1100, 0xFFF1, 0xFF1F, 0x1F1F, 0xF1F1, + 0x0000, 0xF100, 0x1F00, 0x00F1, 0x001F, + /* Codebook 3 - 313 entries */ + 0x0000, 0xE000, 0x0F10, 0x000E, 0x01F2, 0x0F1E, 0xEE00, 0x1021, 0x22E0, + 0x02E2, 0xE1F2, 0xEEE0, 0xE2E2, 0xE20E, 0x0FEF, 0x2200, 0x0002, 0xF2F0, + 0xFFFF, 0x1E10, 0x00E2, 0xFE0F, 0x0EE2, 0x022E, 0xF001, 0xF111, 0x20F1, + 0x1F02, 0xFFEE, 0xE2F1, 0xF221, 0xE121, 0xEEEE, 0x20EE, 0x2FFE, 0x1201, + 0xE011, 0x1EF0, 0x0F2F, 0x0101, 0xFE10, 0x002E, 0xE01F, 0xE220, 0x1E21, + 0xE110, 0xF210, 0x100F, 0x1010, 0x0F0F, 0x0F01, 0x1001, 0xF010, 0x10F0, + 0xF00F, 0x010F, 0x2FF0, 0xF10E, 0x2EE0, 0x0E02, 0x2FEF, 0x110E, 0xF2EF, + 0xE020, 0x1EF2, 0x01EF, 0x12F0, 0xF0F0, 0x0FF0, 0x0110, 0x01E1, 0x0F21, + 0x012F, 0xFF20, 0xFF02, 0x0220, 0x011E, 0x0FF2, 0x0FE1, 0xF120, 0xE12F, + 0xE11E, 0xE0E2, 0x2E0E, 0x22EE, 0x202E, 0xFEF2, 0x21E1, 0x02EE, 0xFE12, + 0x2E22, 0x1FE0, 0x12E1, 0xFFE2, 0x1EEF, 0xE0E0, 0xE1EF, 0x0222, 0x21FE, + 0x0E11, 0x20FF, 0xFE2F, 0xF1EE, 0x01FE, 0xF1E0, 0x0E1F, 0x11E0, 0x1F0E, + 0x0EE0, 0x02FF, 0x0EF1, 0x0F12, 0x00EE, 0xF21E, 0xFE1E, 0x2020, 0xEE20, + 0x121E, 0x1F22, 0xEF2F, 0x0EEE, 0xE2E0, 0x2F10, 0x1F20, 0x021F, 0xE1F0, + 0x02F1, 0x0022, 0x001F, 0xF100, 0x1F00, 0x00F1, 0x0E00, 0xE0F1, 0x12EF, + 0x0202, 0xE022, 0x2E02, 0x2121, 0x212F, 0x201F, 0xFEE1, 0xEF21, 0x21EF, + 0xF102, 0xE1E1, 0x21F2, 0x220E, 0xE02E, 0x12FE, 0x2F2F, 0xFF0E, 0x2011, + 0x0200, 0x2110, 0xE10F, 0x10F2, 0x00E0, 0x0020, 0x2F0F, 0xF0F2, 0xF01E, + 0xF22F, 0xFE21, 0x1EE1, 0x2220, 0x2222, 0xEF1E, 0x2F12, 0xEFF0, 0x102F, + 0x1102, 0x112E, 0xEE1F, 0x0011, 0xF11F, 0x101E, 0xF02F, 0x1FF1, 0xF0E1, + 0x122F, 0x2FE1, 0x0E0E, 0x222E, 0xEE0E, 0x2022, 0xE0EE, 0xE211, 0xF2F2, + 0x2112, 0xEE2E, 0x20E2, 0x1F1F, 0x10E1, 0xE0FF, 0x22F1, 0x2E20, 0x1EFE, + 0x2002, 0x1E0F, 0xF20F, 0xF1F1, 0xE101, 0x1FE2, 0xF122, 0x11EE, 0x1FEE, + 0x1E01, 0x120F, 0x21F0, 0xF201, 0xEEFF, 0x2EFF, 0x1E1E, 0x2F1E, 0x2EE2, + 0xE2EE, 0x10EF, 0x1120, 0x210F, 0x2F01, 0x0112, 0xEF10, 0xF1FF, 0xF021, + 0x22FF, 0xEFEF, 0xEFF2, 0xEE02, 0xEEE2, 0x2EEE, 0xFF22, 0x221F, 0x1F11, + 0xFE01, 0xEF01, 0x0FFE, 0x0EFF, 0x02E0, 0xFF00, 0x1100, 0x2000, 0x00FF, + 0x01F0, 0xFF1F, 0x11F1, 0xFEEF, 0xF12E, 0x12F2, 0xE112, 0x200E, 0x1F2E, + 0xFF2E, 0xEE11, 0x10FE, 0xF012, 0x2E00, 0xFFE0, 0x0E20, 0x1FFF, 0x0211, + 0x2211, 0x2EF1, 0xF212, 0xEFFE, 0xE1FE, 0xE200, 0xF0FE, 0x11E2, 0x2E11, + 0x20E0, 0xEF12, 0x2E2E, 0x22E2, 0xE22E, 0x2202, 0x1210, 0xEF0F, 0x2101, + 0x111F, 0xF0EF, 0x2E1F, 0xE21F, 0xEEF1, 0x11FF, 0x1012, 0xF1E2, 0x1E12, + 0x0E2E, 0x2FF2, 0xFF11, 0xFFF1, 0x0121, 0xF2E1, 0x020E, 0xEFE1, 0x211E, + 0xE00E, 0x1E2F, 0x1122, 0x1111, 0xFEF0, 0x1221, 0xE2FF, 0x1212, 0x2F21, + 0x0E22, 0xF2FE, 0xFEFE, 0xE002, 0xEE22, 0xE202, 0xE222, + /* Codebook 4 - 313 entries */ + 0x1FF1, 0xF111, 0x111F, 0xF01E, 0xE011, 0x20FF, 0xFFEE, 0xF2FE, 0x220E, + 0x20EE, 0x0110, 0x0F01, 0x0011, 0xF1F1, 0x20F1, 0x2F0F, 0x10F2, 0x110E, + 0xF010, 0xF001, 0x10F0, 0xFFF1, 0xFF02, 0xE01F, 0x021F, 0xFE01, 0x010F, + 0x0FF0, 0x1001, 0x1FFF, 0x1F1F, 0x100F, 0xF00F, 0x2101, 0x1F02, 0xE10F, + 0xFFE2, 0xEE02, 0x0E20, 0x2F12, 0x1EFE, 0x1FE0, 0xF10E, 0x120F, 0x21F2, + 0xEFF2, 0xEFEF, 0x2E20, 0xE022, 0xFF1F, 0x10EF, 0x0EF1, 0xF0FE, 0xF120, + 0x1F11, 0x02FF, 0xEF0F, 0xE101, 0xEF1E, 0xE112, 0xEFE1, 0xF212, 0xF1FF, + 0x101E, 0xF20F, 0xE000, 0x10E1, 0xF100, 0x001F, 0x1F00, 0x11F1, 0xFE0F, + 0xF021, 0x1E01, 0xE1EF, 0x2F21, 0x212F, 0x12F2, 0x0101, 0x0E00, 0x0E11, + 0xF0F2, 0x11E0, 0x201F, 0xF02F, 0x1E0F, 0x1201, 0x0F0F, 0x00F1, 0x1010, + 0xF0F0, 0x0F10, 0x0EFF, 0x2011, 0x0E1F, 0xFE1E, 0x2FFE, 0xE1FE, 0x211E, + 0x0200, 0xE0F1, 0xFF20, 0xF1E0, 0x01F0, 0xFFE0, 0xEEF1, 0x2E00, 0xE0E2, + 0x2EE0, 0x02E2, 0xE22E, 0x0211, 0xF201, 0x1F20, 0xF102, 0x02F1, 0x1021, + 0x1102, 0xE020, 0xE20E, 0xE200, 0x20E0, 0x22EE, 0xE2E0, 0xFF0E, 0xF0E1, + 0x1F0E, 0x102F, 0x1120, 0xE0FF, 0xF0EF, 0x0E02, 0x2EE2, 0x0E2E, 0x2E02, + 0x002E, 0x20E2, 0xEE22, 0x2000, 0xF122, 0x1FEE, 0x21FE, 0x020E, 0x2EEE, + 0x00E2, 0x221F, 0x2E1F, 0x0F1E, 0xEF12, 0xE2F1, 0x0F12, 0x01FE, 0xE110, + 0x2FF0, 0xF2F0, 0x0F2F, 0x1E10, 0x000E, 0x01F2, 0x22E2, 0xE2EE, 0xE02E, + 0x2E0E, 0x200E, 0x222E, 0xEE2E, 0x01E1, 0x011E, 0x0020, 0x01EF, 0xF210, + 0xF1E2, 0x1E2F, 0xFFFF, 0x0F21, 0xE21F, 0x22FF, 0x12F0, 0x0002, 0x012F, + 0xEE11, 0xE12F, 0x0FF2, 0xF2E1, 0x1F2E, 0x0000, 0x1111, 0x1EF0, 0x2E11, + 0x2002, 0x02E0, 0xE0EE, 0x00E0, 0x2FEF, 0xFE12, 0xFE10, 0x1EEF, 0x2020, + 0x0EE0, 0xF22F, 0xEEEE, 0x2EF1, 0x2220, 0xEE0E, 0xEEE2, 0x0FE1, 0x12FE, + 0xE2FF, 0x22F1, 0xE002, 0x202E, 0x2202, 0x21EF, 0x1EF2, 0x2110, 0x11EE, + 0x12E1, 0x2FE1, 0xF21E, 0xEFF0, 0x2EFF, 0xE211, 0xFEE1, 0x2FF2, 0xFE2F, + 0x1FE2, 0xFE21, 0x21E1, 0xEF21, 0xE0E0, 0x2022, 0xE220, 0x0E22, 0x2E22, + 0xF2EF, 0xFEF2, 0x0112, 0xE11E, 0xF221, 0x1EE1, 0xE00E, 0xE202, 0xE222, + 0xF012, 0x122F, 0x11E2, 0xF12E, 0x2F2F, 0x0FEF, 0x0FFE, 0xEF01, 0xFF22, + 0x2222, 0x121E, 0x2E2E, 0x0222, 0x1210, 0x210F, 0x2F10, 0x1212, 0x112E, + 0xEF2F, 0xEEE0, 0x0022, 0xFEF0, 0xFEFE, 0x0EEE, 0x0202, 0xEE1F, 0xF1EE, + 0x0121, 0x10FE, 0xEF10, 0x2F1E, 0x2121, 0xFF2E, 0x1E21, 0x21F0, 0xE121, + 0x0E0E, 0xE2E2, 0x1E1E, 0xF2F2, 0x2F01, 0x2211, 0x1E12, 0x0220, 0x22E0, + 0x0EE2, 0x02EE, 0x022E, 0x1221, 0xEFFE, 0xE1E1, 0x12EF, 0x00EE, 0x2200, + 0x2112, 0xE1F2, 0xFF11, 0x11FF, 0x1100, 0x00FF, 0xFF00, 0xF11F, 0xE1F0, + 0xFEEF, 0xEEFF, 0x1012, 0x1122, 0x1F22, 0xEE00, 0xEE20, + /* Codebook 5 - 1201 entries */ + 0x0000, 0x1100, 0x3F00, 0xF1FF, 0x010D, 0x0F30, 0xFE30, 0x10FE, 0xD021, + 0xE23F, 0xE3EF, 0xFF33, 0xFF00, 0x03F0, 0x0301, 0xF1EE, 0xF3D1, 0xF30E, + 0x023D, 0xFEDE, 0xFE0F, 0x1F11, 0xF11D, 0x10E3, 0xEDF2, 0xEEEE, 0xEE1F, + 0xEF1E, 0xF00D, 0xF131, 0xFF1F, 0x1FFF, 0xEF2F, 0xE1ED, 0xE1FE, 0xE2E0, + 0xE3F2, 0xF31D, 0x03ED, 0x1D3F, 0x131D, 0x2DFE, 0x2FFE, 0x202E, 0x22FD, + 0x220E, 0x3E12, 0x32F2, 0x0F2F, 0xED30, 0xF22D, 0x11EE, 0x33FF, 0x03EF, + 0x0121, 0x03D0, 0x0011, 0x0D10, 0x0112, 0xDE01, 0xF1E2, 0x1D31, 0x2D2F, + 0xE1F0, 0x2E00, 0x300F, 0xF1DF, 0x0FDE, 0x111F, 0x0132, 0x1DFF, 0x1F31, + 0xD221, 0xFEE1, 0x033E, 0x0330, 0x1E21, 0x12E1, 0x20D1, 0x213E, 0x012F, + 0x1FDF, 0x00FF, 0xFFD1, 0xFFF1, 0x01F2, 0xFFF3, 0xDF20, 0x22FF, 0x2332, + 0xF0FE, 0xF113, 0x0DE1, 0x31FF, 0xF311, 0xD1D1, 0xFFD3, 0x1E2F, 0x1122, + 0xFD11, 0x0FEF, 0x3111, 0x113D, 0xDDD3, 0x330E, 0xDD3D, 0xDED0, 0xDEF2, + 0xDE23, 0xDE3E, 0xD0E1, 0xD230, 0x00D3, 0x1FFD, 0x131F, 0xD30E, 0xE002, + 0xE3E3, 0xFD1D, 0xFE1E, 0xF33D, 0x1DFD, 0x1D1D, 0x13DD, 0x13F3, 0x2D2D, + 0x2E02, 0x2F03, 0x203D, 0x22F3, 0x2202, 0x23E3, 0x230D, 0x232D, 0x233E, + 0x3D2E, 0x3F3F, 0x31DF, 0x31E2, 0x33DF, 0x33FD, 0x332E, 0x3333, 0xDF3F, + 0xD3E0, 0xED1E, 0xEEDF, 0xEEF3, 0xE112, 0xE12D, 0xE21D, 0xFF3D, 0xF212, + 0xF223, 0x0E3D, 0x0202, 0x2ED3, 0x2002, 0x212F, 0x2130, 0x222E, 0x2233, + 0x2312, 0x3ED0, 0x3FEE, 0xEFEF, 0x30F2, 0x31EE, 0xE211, 0xFF2E, 0xF122, + 0x0312, 0x1DEE, 0x12ED, 0x2D21, 0x21D2, 0x00EE, 0x201F, 0x23D0, 0x3021, + 0x00E2, 0x2200, 0x0123, 0x00E0, 0x3001, 0x02D1, 0x11FF, 0x1210, 0x0EFF, + 0x31E0, 0xFF31, 0xF230, 0xF111, 0x030F, 0x1003, 0x3FFF, 0xD00F, 0x0FED, + 0x01ED, 0x3EF0, 0x0031, 0x003D, 0x0FFE, 0x0130, 0xDE10, 0x10D0, 0xDEE1, + 0x331F, 0xDE1E, 0xE11E, 0x1EEF, 0x2ED1, 0x223F, 0x231E, 0x3120, 0x32F0, + 0x0D01, 0x02E0, 0x10EF, 0x00F3, 0x0103, 0x113F, 0x0310, 0xFFFF, 0x013E, + 0x2D0F, 0x2F01, 0x111D, 0xE2F1, 0xFEED, 0x1111, 0x0DF0, 0x13F1, 0x2F0F, + 0x10D2, 0xD032, 0xD331, 0xEDD0, 0xEE13, 0xD0F0, 0xDF00, 0x001D, 0x1F3F, + 0xDF11, 0xD1FF, 0xF030, 0x13FF, 0x3F11, 0xEFDE, 0xE220, 0xF203, 0xF3FD, + 0x0EE2, 0x020E, 0x0332, 0x1302, 0x2E2E, 0x2F0D, 0x2F32, 0x20E2, 0x21E3, + 0x221D, 0x23F2, 0x3F0E, 0xDDE0, 0x31D1, 0x3122, 0xDFE0, 0xED12, 0xE121, + 0xE132, 0xFD31, 0x0DFE, 0x1D02, 0x1E12, 0x20DF, 0x302F, 0xF03E, 0xF032, + 0xEE00, 0xF2EF, 0x10DE, 0xF1F1, 0xFDF1, 0x12D0, 0x3FF1, 0x1221, 0xE130, + 0x0020, 0xF0F2, 0x101E, 0x0F0D, 0x0E31, 0x0033, 0xE30F, 0xF0EF, 0x1230, + 0xDD3F, 0x32FE, 0xDFFD, 0xD113, 0xD13D, 0xD133, 0x0013, 0x1F1F, 0xD210, + 0xDFF1, 0xE101, 0x11D1, 0xD02F, 0xEEDD, 0xE1E1, 0xFDEE, 0xF331, 0x0DE3, + 0x02D3, 0x0220, 0x12E3, 0x1212, 0x13E2, 0x2EF1, 0x3100, 0x0F23, 0x0D12, + 0x2E11, 0x2FF2, 0x230F, 0x3221, 0x311F, 0xFF13, 0x012D, 0xF2DE, 0xFEEF, + 0x2F1E, 0xD2DE, 0xD3DF, 0xD32E, 0xEE3D, 0xE0EE, 0xE0E2, 0x2022, 0x22DD, + 0x0F32, 0x00DD, 0x0FD0, 0x0E00, 0xFEE3, 0x1E3E, 0x11E2, 0x22E2, 0x23ED, + 0x3D0E, 0x3D3D, 0x3E0D, 0x3E03, 0x3E2D, 0x3E3E, 0x3E32, 0x3FDD, 0x3003, + 0x311D, 0xDD02, 0x32DE, 0x33D3, 0xFF20, 0x0022, 0x10F2, 0xDEDE, 0xED32, + 0xEE1D, 0xE0E0, 0xE033, 0xE2D3, 0xE2EE, 0xE202, 0xFDF3, 0xFD33, 0xF313, + 0x2DE3, 0x2D23, 0x2F12, 0x2033, 0x2220, 0x2330, 0x3DE2, 0x3E30, 0x3FDF, + 0x3FFD, 0x3F2E, 0x3F31, 0x30FE, 0xDD2E, 0x32ED, 0x33EE, 0xDEFE, 0xDE12, + 0xD1EE, 0xEFED, 0xEFE1, 0xE0FD, 0xE02E, 0xE020, 0xE022, 0xE123, 0xE32D, + 0xF302, 0x0E0E, 0x0323, 0x1D0E, 0x2D3E, 0x2FED, 0x2F3E, 0x20F3, 0x22E0, + 0x2213, 0x3E21, 0xDF2E, 0xEDDE, 0xEDE1, 0xEF12, 0xE330, 0xFE2D, 0xFFE2, + 0xF2FE, 0xF22F, 0x0D32, 0x02DD, 0x1E1E, 0x121E, 0x130E, 0x2EE0, 0x2E3F, + 0x2FE1, 0x20E0, 0x2031, 0x2222, 0x2231, 0x3F20, 0xD030, 0xEF30, 0xFE32, + 0xF2E1, 0x02F3, 0x1ED2, 0xF3E0, 0x2DE1, 0x3DFF, 0x0231, 0x2301, 0xD111, + 0xFDE0, 0x1012, 0x20F1, 0x1D00, 0x0200, 0x2101, 0xDD1F, 0x33D1, 0xDE21, + 0xE301, 0x0DDE, 0x0DD2, 0xF201, 0x0EF1, 0x01DE, 0x02DF, 0x21F0, 0x023F, + 0xED0F, 0xEF32, 0xE13E, 0xE2DF, 0xE2E2, 0xE312, 0xF21E, 0xF3DF, 0x0E02, + 0x11D3, 0x12EF, 0x2FDE, 0x2FEF, 0x00FD, 0x2F2F, 0x22F1, 0x3DDF, 0x3D11, + 0xD3F1, 0x30E1, 0x32D0, 0xF1DD, 0x03FE, 0x031E, 0x1133, 0x1032, 0x12D2, + 0x1223, 0x3D00, 0x3D1F, 0xD311, 0x0FD2, 0x0F12, 0xF0D2, 0x021F, 0x0F10, + 0x01F0, 0x10F0, 0x100F, 0x0F01, 0x23F0, 0xF1E0, 0xEE3F, 0x032D, 0xE310, + 0x11E0, 0x33F1, 0xD0F2, 0x33E2, 0xDFEE, 0xD01E, 0xD102, 0x0DD0, 0x0D2F, + 0x0E3F, 0x120F, 0x2FF0, 0xF3F1, 0xD2F2, 0xD3E2, 0xD322, 0xEDFE, 0xEE2E, + 0xEFE3, 0xEF0D, 0xEF2D, 0xE01D, 0xE1E3, 0xE10D, 0xE213, 0xFD13, 0x0D3E, + 0x02E2, 0x030D, 0x1D3D, 0x2D03, 0x2D1E, 0x2EE2, 0x2E1D, 0x20FD, 0x203F, + 0x21F2, 0xDD11, 0x2112, 0x321E, 0xD3FF, 0xEFD0, 0xEF21, 0xE1D0, 0xE3FE, + 0xE31E, 0xFE12, 0xF133, 0x0E2E, 0x12F2, 0x1203, 0x2E31, 0x21DE, 0x211E, + 0xED01, 0xFDE2, 0xF2E3, 0xF232, 0x1F3D, 0x13DF, 0xEF0F, 0xE0F1, 0xFED2, + 0xFF0E, 0x1E32, 0x11FD, 0x1010, 0xF010, 0xF001, 0xED10, 0x110E, 0x20FF, + 0xF1D1, 0x0FE3, 0x1D1F, 0x02FF, 0x3E2F, 0x3320, 0xDF22, 0xE110, 0x1102, + 0xFDD1, 0xFD3F, 0xF300, 0x01D2, 0xD201, 0xF3E2, 0xF33F, 0xF023, 0x1E30, + 0x0F0F, 0x1001, 0x010F, 0x0101, 0xF00F, 0x1300, 0xED2F, 0x1E23, 0xEF3E, + 0xE12F, 0xF0DE, 0x102D, 0x2DF0, 0x103E, 0x31F1, 0xFDD3, 0xFD2E, 0xFEFE, + 0x0E22, 0x03F2, 0x1EF2, 0x12DE, 0x1322, 0xDD20, 0x2E20, 0x21E1, 0xF20D, + 0x1DE2, 0xDE0F, 0x13D1, 0x132E, 0xFED0, 0xF120, 0x02F1, 0x03E1, 0x1320, + 0x2321, 0x01FE, 0x3201, 0x21D0, 0x3DE0, 0xDFE2, 0xDFF3, 0xDF13, 0xDF33, + 0xF0F0, 0x0D0F, 0x0ED1, 0xEF10, 0xF10E, 0x10ED, 0x1EF0, 0x2D10, 0xFD00, + 0xF1D3, 0x0EE0, 0x122D, 0x133F, 0xF0E1, 0x2EDF, 0x2FD0, 0x1F20, 0x102F, + 0x2DEF, 0x221F, 0xD0D0, 0xD03E, 0xD2ED, 0xD2E3, 0xD212, 0xD22D, 0xED0D, + 0xED03, 0x0110, 0x3010, 0xD010, 0x13E0, 0xEEFF, 0xF2D0, 0x1E10, 0x0DEF, + 0x1E0F, 0x0FF0, 0x01EF, 0x1F02, 0xED3E, 0xEEE2, 0xEFF2, 0xE0D3, 0xE00E, + 0xE03D, 0xE23D, 0xE323, 0xE33E, 0xFD3D, 0xF3D3, 0x0D2D, 0x1313, 0x1333, + 0x2DED, 0x2E0E, 0x011E, 0x2E3D, 0x212D, 0x223D, 0x3DD1, 0x3D22, 0x3EDE, + 0x3EE3, 0x3E23, 0x3F22, 0x30D0, 0x300D, 0x313F, 0xDFD1, 0x32D2, 0x331D, + 0xDF0E, 0xDF02, 0xD012, 0xEDD2, 0xEED3, 0xEFFE, 0xE1EF, 0xE103, 0xE3DE, + 0xE332, 0xFDDD, 0xFE0D, 0x03E3, 0x2D32, 0x2EF3, 0x2E22, 0x200E, 0x201D, + 0x3EFE, 0x3EF2, 0xDDEE, 0x312E, 0x3212, 0xDDFF, 0xD131, 0xEEE0, 0xE0DF, + 0xE0D1, 0xE1D2, 0xE1F2, 0xE3D2, 0xFD02, 0xFEF2, 0xFE21, 0x0D23, 0x02EE, + 0x0222, 0x120D, 0x2DF2, 0x2D12, 0x2F2D, 0x21ED, 0x2121, 0xDEEF, 0x22DF, + 0x301E, 0xEE11, 0xF3EE, 0x0213, 0x1D22, 0x1EDE, 0x1E03, 0x1F2E, 0x3EEF, + 0xE011, 0x0EDF, 0x0E11, 0x2011, 0xF1F3, 0x0FF2, 0x3FE0, 0x1ED0, 0x1021, + 0x123E, 0xE000, 0x30F0, 0x2310, 0xD2E1, 0x3322, 0xDDF1, 0xEEF1, 0xFFDD, + 0x0D30, 0x03DE, 0x1D33, 0x1FDD, 0xD300, 0x112E, 0x22D1, 0x0002, 0x2000, + 0xEDF0, 0xE0FF, 0xFFEE, 0x0E1F, 0x1023, 0x3210, 0x0F21, 0xE321, 0xF02F, + 0x1FF1, 0xF021, 0x1F0E, 0x1232, 0x3E01, 0x01E1, 0xEF01, 0xFD20, 0xF2F0, + 0xF210, 0x1FD1, 0x3E10, 0x3300, 0xD0EF, 0xD2EF, 0xE03F, 0xE031, 0x0EEE, + 0x022E, 0x0233, 0x03D2, 0x13EE, 0x133D, 0x2FE3, 0x21EF, 0xD1E0, 0x21FE, + 0x30EF, 0xE2D1, 0xE2FF, 0xE21F, 0xE231, 0xFE3E, 0xF12E, 0xF2ED, 0x1EE3, + 0x1E2D, 0x122F, 0x2DD0, 0x3EE1, 0x1E01, 0x10E1, 0xFE10, 0xF320, 0xD100, + 0x1113, 0xF012, 0x0F3E, 0x1DE0, 0x11DF, 0x12F0, 0xF003, 0xFF02, 0x0211, + 0xF31F, 0x0FE1, 0x1DF1, 0x320F, 0x1DD1, 0x1FE2, 0xD2F0, 0xDD00, 0x11F1, + 0xEDEF, 0x1F22, 0x11DD, 0x1D20, 0x1201, 0x1F13, 0x11F3, 0x0F2D, 0xF0D0, + 0xD1F1, 0xF20F, 0x32E1, 0xDDDF, 0xDD31, 0xDEE3, 0xDE32, 0x000E, 0x01D0, + 0x1D11, 0x3F1F, 0xFFDF, 0x2E1F, 0xDF31, 0xD0FE, 0xD13F, 0xD2D2, 0xD2FE, + 0xD23E, 0xD3EE, 0xD33F, 0x00D1, 0xDEF0, 0xFF3F, 0xEDE3, 0xEEFD, 0xEF03, + 0xE0F3, 0xE013, 0xE1DE, 0xE2F3, 0xE233, 0xE3D0, 0x1D13, 0x1EFE, 0x2DD2, + 0x2D30, 0x2E13, 0x210D, 0x2132, 0x0F03, 0x22D3, 0x22EE, 0x23D2, 0x3012, + 0xDE30, 0xD10E, 0xEFD2, 0xFE03, 0xF3DD, 0x1DF3, 0x1EED, 0x1E0D, 0x12FE, + 0x1331, 0xDE2F, 0x2013, 0x23FE, 0xFE23, 0xFF22, 0xF32E, 0x0DF2, 0xE3E1, + 0x1DDF, 0x1FD3, 0xFF11, 0xFDFF, 0x021D, 0x0321, 0x1FF3, 0xF1FD, 0x100D, + 0xF02D, 0x32EF, 0xD22F, 0xFEF0, 0x1FE0, 0x1F33, 0x0F1E, 0xF13F, 0x2211, + 0xD31F, 0xF23E, 0x001F, 0xF100, 0x1F00, 0x2110, 0xFFFD, 0x0D21, 0xFD1F, + 0x2F10, 0xDFFF, 0xF322, 0x0E1D, 0x23EF, 0x33E0, 0x210F, 0xF102, 0x3311, + 0xD12E, 0x3331, 0xDDFD, 0xDDF3, 0xDD0E, 0xDD22, 0xDD33, 0xDED2, 0xDEED, + 0xDE0D, 0xEFF0, 0xE01F, 0xF0ED, 0xF0E3, 0x02FD, 0x01E3, 0xF11F, 0x003F, + 0x00DF, 0x00F1, 0xF01E, 0xD122, 0xEED1, 0xEE20, 0xFD0E, 0x0EDD, 0x2EFF, + 0x20EE, 0x2020, 0xED21, 0x3D20, 0x3E1E, 0x0E33, 0x1D2E, 0xFE01, 0x2F30, + 0x232F, 0xFFE0, 0x0ED3, 0x0E13, 0x23E1, 0xE3F0, 0x1311, 0xFF1D, 0x3E0F, + 0xD120, 0x1131, 0xD001, 0x1030, 0x1F1D, 0x1120, 0xD320, 0x3F02, 0xDE03, + 0xDE2D, 0xDFDD, 0xDFD3, 0xDF1D, 0xD0DE, 0xD0E3, 0xD1DD, 0xD20D, 0xD3DD, + 0xD3FD, 0xD3F3, 0xD302, 0xD31D, 0xD313, 0xD33D, 0xEE31, 0xE32F, 0xFD22, + 0xF13D, 0x0EFD, 0x0E20, 0x1FEE, 0x2D01, 0xD11F, 0xD20F, 0xF2D2, 0xF3FF, + 0x0EF3, 0x3DF1, 0x0D0D, 0x1DD3, 0x2D0D, 0x2323, 0x3DDD, 0x3DD3, 0x3DF3, + 0x3D1D, 0x3D13, 0x3EED, 0x3FD3, 0x3F13, 0x3F3D, 0x3F33, 0x30E3, 0x302D, + 0x3023, 0x3032, 0x31D3, 0x31FD, 0x310E, 0x3113, 0x313D, 0x3133, 0x3203, + 0x323E, 0x33DD, 0x33F3, 0xDD1D, 0x3302, 0x333D, 0xE200, 0xDF1F, 0xE10F, + 0x032F, 0xDD13, 0xDFDF, 0xDF3D, 0xD0D2, 0xD0ED, 0xD003, 0xD023, 0xD1D3, + 0xD1FD, 0xD11D, 0xD2D0, 0xD203, 0xD223, 0xD3D3, 0xD333, 0xED2D, 0xED23, + 0xEE0E, 0xEE33, 0xE30D, 0x1DDD, 0x2E33, 0x20D3, 0x2303, 0x3DEE, 0x3DFD, + 0x3D02, 0x3D33, 0x3F1D, 0x30DE, 0x30ED, 0x303E, 0x3030, 0x31DD, 0x3131, + 0x32E3, 0x320D, 0x322D, 0x3223, 0x3232, 0xDDD1, 0x3313, 0x333F, 0xD00D, + 0xD02D, 0xD1DF, 0xD1F3, 0xD232, 0xD3D1, 0xEDED, 0xEE02, 0xE2DD, 0xE222, + 0xE303, 0xF333, 0x0D03, 0x0303, 0x20DD, 0x23DE, 0x3D3F, 0x3D31, 0x3ED2, + 0x3FF3, 0x30D2, 0x31F3, 0xDDDD, 0xDDE2, 0xD1E2, 0xEE22, 0xE0DD, 0xE20E, + 0xE22E, 0xE3ED, 0xFDFD, 0xF3F3, 0x0DED, 0x13D3, 0x13FD, 0x2DDE, 0x2EDD, + 0x2EEE, 0x2F21, 0x2F23, 0x2103, 0x2123, 0x3FD1, 0x3FE2, 0xD21E, 0x3102, + 0x3230, 0xEF23, 0xE2FD, 0x0D1E, 0x2EFD, 0xFDDF, 0x2FD2, 0x322F, 0x002E, + 0xFE2F, 0xF2F2, 0xF221, 0x1EE1, + /* Codebook 6 - 1201 entries */ + 0xFF1F, 0x1EF0, 0x0D32, 0x3E30, 0x0D0F, 0x2E02, 0x0D10, 0xD0E3, 0xD33D, + 0xDDD3, 0xD030, 0x0DD0, 0x3DD3, 0x1E10, 0x2DE1, 0x20EE, 0x11F1, 0xF0F2, + 0xFE1E, 0x1D22, 0xEEFF, 0xE0F1, 0xFEEF, 0xE101, 0xDEF2, 0x2EE2, 0x00FD, + 0x0D0D, 0x3D13, 0xEFF2, 0xF212, 0x0F2F, 0x1120, 0x2F0F, 0x1E2D, 0x2F30, + 0xD3E0, 0x1F11, 0x1122, 0xEFE1, 0xE02E, 0x2F03, 0xF20F, 0xF02D, 0x22FD, + 0xF1FF, 0xFE10, 0xFF20, 0x21FE, 0xFE2F, 0xED2D, 0xF3D3, 0x023F, 0x20DD, + 0xF2F0, 0xD1E0, 0x203F, 0x3010, 0x330E, 0x02FF, 0xE0FF, 0xFFE0, 0xF1EE, + 0x0EE2, 0x0103, 0xF0EF, 0x0EFF, 0x0FE1, 0x1E01, 0x10E1, 0xFF0E, 0x0F21, + 0x2EFF, 0x21ED, 0xEDDE, 0x0130, 0xDEE3, 0xD003, 0xD02D, 0xE303, 0xF333, + 0x0DDE, 0x23E3, 0x3DD1, 0xDE32, 0xDF1D, 0xE332, 0x0D3E, 0x0F0D, 0x1D1D, + 0xDF11, 0xE0E0, 0x2DD0, 0x22E0, 0x23DE, 0x3030, 0xDFD3, 0x00DD, 0x201F, + 0x1D11, 0x1221, 0x211E, 0xF311, 0x133F, 0xFFEE, 0x31EE, 0x2031, 0x2213, + 0xD00F, 0xF02F, 0x2E3F, 0x321E, 0xEEF1, 0xEDD2, 0x03EF, 0x2ED3, 0x32D0, + 0xE0DF, 0xFFDD, 0xEF12, 0xDEE1, 0x223F, 0xF102, 0xDDF1, 0x3F1D, 0x010D, + 0x02F1, 0x12F0, 0xF201, 0xD10E, 0xF2D0, 0x0D2F, 0x1E21, 0x22F1, 0x231E, + 0xF1E0, 0x0211, 0x3F2E, 0xED01, 0xFDE0, 0xD032, 0x0033, 0x3D33, 0xFD33, + 0x3DF3, 0xD322, 0xF300, 0xE000, 0x3D02, 0x3D3F, 0x3EDE, 0x30E3, 0xEDED, + 0xF13D, 0xEF23, 0x1E30, 0x212F, 0x22DF, 0xF0E1, 0x1DF1, 0xE132, 0x0312, + 0x3100, 0x3133, 0xDDFD, 0xF2EF, 0x03FE, 0xFE0F, 0xF1FD, 0x11F3, 0x2211, + 0xD021, 0xE2D1, 0x0DF2, 0x1023, 0xD210, 0x102F, 0x2011, 0x21D0, 0x2E20, + 0xDE2D, 0xD3EE, 0x0E1F, 0x1F20, 0x1113, 0x00EE, 0x30F2, 0x1201, 0xD32E, + 0xE23D, 0x0ED1, 0x3DEE, 0xE1DE, 0x31F3, 0x3302, 0xF3E2, 0x0EDD, 0x2103, + 0x2FDE, 0x2F1E, 0xF113, 0xD001, 0xF11D, 0x1FFD, 0xF0ED, 0x112E, 0x12F2, + 0x2E31, 0xD1F1, 0x1E0F, 0x2233, 0xE20E, 0x0E22, 0x2200, 0x0202, 0xDD22, + 0xDFDD, 0x3FD3, 0x0D12, 0x02D1, 0x1DE2, 0x1EFE, 0x3F0E, 0x30E1, 0xF3FF, + 0x1021, 0xD230, 0x00D1, 0x01D2, 0x013E, 0x1DFD, 0x1D13, 0x32DE, 0x32E3, + 0xEE2E, 0xF302, 0x0E2E, 0x02E2, 0xF31F, 0x331F, 0xEE31, 0x000E, 0x3EF2, + 0x3E21, 0x2000, 0xEE0E, 0x33EE, 0xDD13, 0xE0E2, 0x03DE, 0xDDFF, 0xD1E2, + 0xD3F1, 0xD311, 0x0002, 0xFEE3, 0xFE3E, 0x01EF, 0x12DE, 0xD02F, 0xEEE0, + 0xE1EF, 0x0EE0, 0x031E, 0x11DF, 0x1D20, 0xDFFD, 0xD3D1, 0xE3DE, 0xFE30, + 0x3F1F, 0x131F, 0x0DE3, 0x0F2D, 0x2DDE, 0x3131, 0xF203, 0x1FD3, 0xF2ED, + 0x0231, 0x1ED2, 0x1EE3, 0xF3F1, 0x2F12, 0x3212, 0x13FF, 0xFE23, 0x3D20, + 0xDDDF, 0x0E13, 0x030F, 0x1E03, 0x1230, 0xDD1F, 0xDF3F, 0xEFD0, 0xEEDD, + 0xEEDF, 0xD20F, 0xF23E, 0x1E23, 0x3001, 0x1FEE, 0xF122, 0xEDF2, 0x0233, + 0xD3FD, 0xDD33, 0xDD1D, 0x33D3, 0xDD3D, 0xE0DD, 0x331D, 0x1322, 0x2DF2, + 0xE0D1, 0xDE3E, 0xFDD3, 0xE0EE, 0xFF33, 0xDDEE, 0x0E33, 0x2D3E, 0xDF0E, + 0xD2FE, 0xD3FF, 0xD300, 0xF20D, 0xF3E0, 0x12ED, 0x13E2, 0x3F11, 0x221F, + 0x2EF3, 0x3FFD, 0x13F3, 0xDD0E, 0xFDF1, 0xFFFD, 0x11D1, 0x23E1, 0xED12, + 0xFD22, 0x0EDF, 0x02FD, 0x1032, 0x12D2, 0x3DFF, 0x310E, 0x2321, 0x33F1, + 0x3322, 0xD13F, 0xEE20, 0x11DD, 0x2E0E, 0xDFE0, 0x10DE, 0x1320, 0x2332, + 0xDFEE, 0xF0D2, 0x0EF3, 0x3F22, 0x3122, 0x322F, 0x0000, 0x1F3F, 0xED2F, + 0xD302, 0xEED3, 0xFD00, 0xFD1D, 0x0DF0, 0x0D03, 0x2DD2, 0x22D3, 0x223D, + 0x23D2, 0x23ED, 0x3EE3, 0xED30, 0x30D0, 0x32D2, 0xE2E0, 0x0DD2, 0x0D30, + 0x2022, 0x1D02, 0x30EF, 0xFFF3, 0xFD11, 0x32F0, 0xFDEE, 0x2330, 0xF31D, + 0xEDEF, 0x0D01, 0x103E, 0x111D, 0x2E1D, 0x0E3D, 0x033E, 0xDEEF, 0xDF02, + 0x222E, 0xDDF3, 0xD133, 0x032D, 0x13DD, 0xE1E3, 0xE21D, 0xFE32, 0x021D, + 0x0220, 0x13D1, 0x2231, 0x3F02, 0x2DEF, 0x2310, 0x30D2, 0x302D, 0x3032, + 0x31DD, 0xD03E, 0xD232, 0xD331, 0x1313, 0x2DED, 0x232D, 0x02EE, 0x3ED0, + 0x3ED2, 0x2EEE, 0x202E, 0x320F, 0xD0FE, 0xE13E, 0xE2DF, 0x00E2, 0x2F2D, + 0x30FE, 0xD201, 0x301E, 0x32F2, 0xFF3F, 0x1FDF, 0xDDE2, 0xDD20, 0xD131, + 0x2202, 0xEEFD, 0x3DE0, 0x3331, 0xE312, 0xFD2E, 0x122D, 0x3D1F, 0x2DF0, + 0x3FEE, 0xDF2E, 0xE3FE, 0xF22D, 0x0022, 0x10D2, 0xFEDE, 0x13EE, 0x2123, + 0x3E0F, 0x3FE2, 0xDDD1, 0xD023, 0xD2ED, 0xFDFD, 0x0D2D, 0x03ED, 0x0323, + 0x3D0E, 0x3EED, 0x3023, 0x3230, 0x33E2, 0xD320, 0xEEE2, 0xE2D3, 0x0F03, + 0x0132, 0x03F0, 0x1302, 0x131D, 0xD0EF, 0xED1E, 0xE022, 0x302F, 0x31E2, + 0x3102, 0xE310, 0xF00D, 0xE31E, 0x2E3D, 0x33FD, 0x1D33, 0xD3DD, 0xD333, + 0x003D, 0x3DDD, 0x333D, 0x2D1E, 0x3EFE, 0xF21E, 0x121E, 0x00FF, 0x1311, + 0xE3D2, 0xFDDD, 0x22E2, 0x3FD1, 0xD0E1, 0xD0F2, 0xE031, 0x1DEE, 0xD1FF, + 0x1EED, 0x3FF3, 0xD1DD, 0xD31D, 0x0303, 0x3DFD, 0x0E02, 0x002E, 0x1100, + 0x2DFE, 0x2FD2, 0x2FE3, 0x3F20, 0xFDFF, 0x3E01, 0xDE01, 0xF1D1, 0xF131, + 0x2D2F, 0x0011, 0xD30E, 0xED32, 0x1D3D, 0x2D23, 0xD1DF, 0xFDF3, 0xDEFE, + 0xEF3E, 0xFD3F, 0x201D, 0x21E3, 0x2220, 0xF012, 0xFF31, 0xEFE3, 0x3120, + 0x3EF0, 0xDE0F, 0xF1DF, 0xDEDE, 0x230D, 0x3D3D, 0xD0D2, 0x30F0, 0x31FD, + 0xEED1, 0xEF2D, 0xE020, 0xE3F2, 0xFE2D, 0x020E, 0x0222, 0x213E, 0xF13F, + 0x2D10, 0xD2E1, 0x23F2, 0xD1EE, 0x1EF2, 0xEF32, 0xE2F3, 0x2F3E, 0x20D1, + 0x23FE, 0x3021, 0x0E00, 0x21EF, 0xDE03, 0xE033, 0xE2DD, 0xE30D, 0x0E31, + 0x13D3, 0x133D, 0x2EDD, 0xEDD0, 0xEE3D, 0xF030, 0x0FDE, 0xD01E, 0x31DF, + 0x3232, 0xEDFE, 0xEE00, 0xEE22, 0xE1D2, 0xE200, 0xF322, 0x1232, 0x130E, + 0x20E0, 0x22FF, 0x1FD1, 0x3221, 0xF30E, 0x332E, 0x33DF, 0xD20D, 0xD223, + 0x1DE0, 0x20DF, 0xDFD1, 0x3F13, 0xFF00, 0x1111, 0xFD20, 0xDE1E, 0xEF0D, + 0xE03F, 0x1FDD, 0x2FED, 0x21DE, 0x0200, 0xD122, 0x33E0, 0xF33D, 0x3F3D, + 0x3F33, 0x33DD, 0xFE03, 0xF0DE, 0xF223, 0x02E0, 0xE12F, 0x0FE3, 0x00E0, + 0x220E, 0xEE33, 0xFD3D, 0x2E33, 0x20D3, 0xD2D2, 0x3DDF, 0x3E2D, 0xE33E, + 0xE330, 0x0013, 0x02D3, 0x31D1, 0x3113, 0xE12D, 0xFFD3, 0x0EEE, 0x2E13, + 0x1001, 0x0FFE, 0xFFDF, 0x2F32, 0x212D, 0x0E0E, 0x120D, 0x13DF, 0x20F3, + 0xE3F0, 0x2013, 0x2132, 0x10F0, 0x210F, 0xE321, 0xFEED, 0x300F, 0x11EE, + 0x12FE, 0xF3F3, 0x3FDF, 0x32ED, 0x3223, 0xEFDE, 0xEF03, 0x1223, 0xF32E, + 0xF331, 0x3201, 0x3320, 0xDFE2, 0xED10, 0x0020, 0x0112, 0xF003, 0xEFED, + 0x1D31, 0xD0ED, 0x33F3, 0xD00D, 0xD113, 0xD3DF, 0x00F3, 0x03E3, 0x2D03, + 0x3E32, 0xD102, 0xEE02, 0xE22E, 0xF1DD, 0x12E3, 0x20FD, 0xF001, 0xF320, + 0x1131, 0x23F0, 0x21D2, 0xD010, 0x322D, 0x323E, 0xEFF0, 0x012D, 0xF03E, + 0x3311, 0x100F, 0x232F, 0xD012, 0xFD02, 0xF133, 0xF3D1, 0x0EFD, 0x03F2, + 0x2110, 0xFEF2, 0x1DDF, 0x210D, 0xF00F, 0x0F01, 0x010F, 0xFFFF, 0xEF01, + 0xD2EF, 0x100D, 0x13E0, 0xD212, 0xD23E, 0xDD3F, 0xED03, 0xE1D0, 0xFFD1, + 0xF032, 0xF1D3, 0xDE2F, 0xEE11, 0xF221, 0x2FE1, 0x0FEF, 0xE3E1, 0x2EDF, + 0x3FF1, 0x2FEF, 0x0D23, 0x2DE3, 0x203D, 0x300D, 0xDF13, 0xDF31, 0xFF02, + 0xE002, 0x0332, 0x13FD, 0x1331, 0x200E, 0xE11E, 0x221D, 0x2D32, 0xF3FD, + 0xE301, 0x02DF, 0xD11F, 0x2222, 0xE213, 0x0E1D, 0xF010, 0x0110, 0x0FF0, + 0x1DD1, 0x2D2D, 0x2323, 0xE01D, 0x00D3, 0xF023, 0x1133, 0x312E, 0x2D21, + 0xD3E2, 0xE013, 0x1E3E, 0xFED0, 0xF33F, 0x001F, 0xFEF0, 0x123E, 0xD3D3, + 0xE0D3, 0x2D0D, 0x2033, 0x3E0D, 0x3E03, 0x3E23, 0x30DE, 0xFE12, 0xE10D, + 0x2D30, 0x30ED, 0x3313, 0x32E1, 0xFE0D, 0x3F31, 0x0FD0, 0x311F, 0x22D1, + 0xE123, 0x22F3, 0x1E32, 0x2FD0, 0xEDE1, 0x3D11, 0x0F30, 0x001D, 0x3FFF, + 0x1003, 0xDDDD, 0x0E20, 0x10FE, 0xF1E2, 0x3E2F, 0xF100, 0x0121, 0xEF21, + 0x2F23, 0x2E22, 0xDF3D, 0x313D, 0x03D0, 0x3300, 0xDD00, 0xD1D1, 0x1DD3, + 0xE3EF, 0xF2E1, 0xEE1D, 0xE00E, 0xE103, 0x0213, 0xD120, 0x2E00, 0x33FF, + 0xEEEE, 0x1ED0, 0x110E, 0x122F, 0xEFEF, 0x21F0, 0xE2F1, 0x0DE1, 0x1012, + 0x23EF, 0xDD31, 0xD0D0, 0xD100, 0xD203, 0x01DE, 0x22DD, 0x2303, 0x3203, + 0x1010, 0xDE10, 0xD11D, 0xE222, 0xE3D0, 0xE0FD, 0x02DD, 0x0301, 0xDF20, + 0xE32F, 0x01ED, 0xE0F3, 0xE2FD, 0xE121, 0xF3DF, 0x2312, 0x1F00, 0xF0F0, + 0x0F10, 0xF2D2, 0xF2FE, 0xF2F2, 0xED0F, 0xFF13, 0xE21F, 0x032F, 0x0101, + 0x1FE0, 0x1EE1, 0xDED0, 0x33D1, 0xDF33, 0xD0F0, 0xD1FD, 0x3111, 0xE202, + 0x1333, 0x3E3E, 0x3F3F, 0xFDDF, 0x113D, 0x01F0, 0x11FF, 0x0F0F, 0x31F1, + 0xEE1F, 0xE30F, 0x3012, 0xD2F2, 0x11E2, 0xD31F, 0x3003, 0xD2DE, 0xD33F, + 0xEF2F, 0xE231, 0x3EE1, 0x1F31, 0xED0D, 0xE3ED, 0xE323, 0x0DED, 0xDEF0, + 0x2FF2, 0x01D0, 0x030D, 0x1DDD, 0x333F, 0xD2D0, 0xE2EE, 0xF0FE, 0xD221, + 0xF22F, 0xD2F0, 0xFEE1, 0xDD11, 0x0F23, 0x3F00, 0x0D21, 0x21E1, 0x2112, + 0x2301, 0x3EEF, 0xFD31, 0x1D3F, 0xDE21, 0x113F, 0x2130, 0xEF10, 0x1EEF, + 0x2D01, 0x1210, 0x2FF0, 0xDFFF, 0xDD02, 0xDE23, 0xEDF0, 0x003F, 0x1E0D, + 0x1F33, 0x3FE0, 0xE2FF, 0x1E2F, 0x2D0F, 0xD111, 0x11E0, 0x3E10, 0x2EF1, + 0xFD0E, 0x3D22, 0xDE0D, 0xD13D, 0x3D1D, 0x1FFF, 0x0F12, 0x1F02, 0x10F2, + 0x1E12, 0x1D0E, 0x1F3D, 0xFF11, 0xF021, 0x13F1, 0xD22F, 0x2020, 0xDFDF, + 0x0FD2, 0x3D31, 0xE130, 0xFDE2, 0x00F1, 0xF232, 0xF3EE, 0x31E0, 0xDDE0, + 0xEEF3, 0xEE3F, 0x2002, 0x3DF1, 0xE23F, 0xF2E3, 0xDFF1, 0x10ED, 0x2F2F, + 0xE01F, 0xF0E3, 0x3D00, 0xF10E, 0x01FE, 0x20F1, 0xE011, 0x0FF2, 0xE1ED, + 0x0310, 0xDFF3, 0x22EE, 0x23D0, 0xEF0F, 0xFED2, 0x3D2E, 0xD1F3, 0xD2E3, + 0xFE21, 0xF2DE, 0x1F2E, 0x1F22, 0x2101, 0x2E1F, 0x02F3, 0x2EE0, 0xFD1F, + 0x101E, 0x3210, 0x1EDE, 0x2ED1, 0xF120, 0x3E1E, 0x2EFD, 0x313F, 0xEDE3, + 0x01F2, 0xFF2E, 0xF12E, 0x1FF1, 0x10EF, 0xF230, 0xE1F2, 0x1FE2, 0x0DFE, + 0xED3E, 0x0031, 0xD12E, 0xE1FE, 0xF11F, 0x0E11, 0x03E1, 0x2FFE, 0x011E, + 0x32EF, 0x01E3, 0x023D, 0x1D00, 0x3DE2, 0x111F, 0x32FE, 0x0D1E, 0x2E2E, + 0xFF22, 0x0F32, 0xE1F0, 0xE10F, 0xFFF1, 0x012F, 0x12E1, 0xDF22, 0xF210, + 0xE1E1, 0x0E3F, 0x31FF, 0x102D, 0x3E12, 0xED21, 0x11D3, 0xDD2E, 0xDEED, + 0xEF30, 0xE211, 0x0F1E, 0x2F01, 0x12D0, 0xED23, 0xE32D, 0xFD13, 0x10D0, + 0x0DEF, 0xEFD2, 0x2F0D, 0xF111, 0x120F, 0x1D2E, 0x1212, 0x11FD, 0x2E11, + 0x3333, 0xE2E2, 0xF1F1, 0xFF1D, 0x0EF1, 0xD21E, 0x2F21, 0x21F2, 0x230F, + 0x021F, 0xEE13, 0xEFFE, 0x01E1, 0x2F10, 0x1D1F, 0x2121, 0xD0DE, 0xD313, + 0x0ED3, 0xD3F3, 0xF3DD, 0x00DF, 0x1300, 0x303E, 0x31D3, 0xDE30, 0x03D2, + 0x1DF3, 0x1030, 0xFDD1, 0xFF3D, 0xE112, 0x12EF, 0x1F1F, 0xF1F3, 0x2D12, + 0x20E2, 0xDED2, 0xDF00, 0xFE01, 0xE110, 0xF01E, 0xFFE2, 0xEF1E, 0x1DFF, + 0x1FF3, 0xE233, 0xF0D0, 0xF313, 0x311D, 0xE220, 0x0123, 0xDE12, 0x0F3E, + 0xDF1F, 0x0321, 0x022E, 0xD1D3, 0xE03D, 0x3FDD, 0x320D, 0x1F0E, 0x1F1D, + 0x1F13, 0x1102, 0xD22D, 0xE3E3, 0x0330, 0x233E, 0x0FED, 0x1203, 0xFEFE, + 0x1E1E, 0x20FF, 0x10E3, 0x132E, + /* Codebook 7 - 3281 entries */ + 0x0000, 0x00FF, 0x3F00, 0xCC00, 0x1C10, 0x1140, 0xFCEF, 0x4220, 0x43C1, + 0xCCCE, 0xFF40, 0xF2DC, 0xF21C, 0x1E4F, 0x114C, 0x2E1F, 0x30F0, 0xC020, + 0xC2E0, 0x0022, 0x01C1, 0x014F, 0x1012, 0x104D, 0xEF21, 0xFEDC, 0xFFE2, + 0xFF42, 0xF003, 0xF2FE, 0xF212, 0xF4CD, 0x0C40, 0x0DF4, 0x0224, 0x033C, + 0x1EF2, 0x1E21, 0x1FEE, 0x1F22, 0x103C, 0x1212, 0x142D, 0x1421, 0x2DC1, + 0x2FFE, 0x21FE, 0x2141, 0x22FF, 0x2420, 0x4CDF, 0x4C1F, 0x4D01, 0x4E20, + 0x4121, 0x441F, 0xCF01, 0xC301, 0x002C, 0xF3CE, 0xFCD2, 0x0143, 0x012F, + 0x20F1, 0x1F00, 0x00F1, 0x001F, 0x2F10, 0xC400, 0x112C, 0xF40F, 0xF1C2, + 0x002E, 0x1E10, 0x140F, 0x2101, 0x0F4D, 0x004C, 0x0044, 0x02E0, 0x1E43, + 0x10CF, 0xE200, 0x2C11, 0x4F0F, 0x0F4F, 0x1F2C, 0x0200, 0x14E1, 0x401F, + 0xC00E, 0xC3D2, 0xC330, 0xC4F1, 0xCF10, 0x1041, 0xF0F2, 0x0DC1, 0x1F0E, + 0x2F0F, 0x0134, 0x0FDC, 0xFF00, 0x0011, 0x1100, 0x0114, 0xFFFF, 0xC41F, + 0xC431, 0xDC01, 0xDE4F, 0xDE43, 0xDF40, 0xD001, 0xD14E, 0xD2E1, 0xD24F, + 0xD432, 0xECC4, 0xECF3, 0xEDCD, 0xEE42, 0xEFFC, 0xEF1E, 0xEF30, 0xEF41, + 0xE1C1, 0xE2E0, 0xE33C, 0xE42E, 0xE43D, 0xFCC3, 0xFCDE, 0xFCF2, 0xFDCC, + 0xFD4E, 0xFEED, 0xFF1D, 0xFF3D, 0xFF3F, 0xFF31, 0xF030, 0xF1D3, 0xF1FD, + 0xF3FF, 0xF311, 0x0CE4, 0x0C24, 0x0C33, 0x0C42, 0x0D10, 0x0ED1, 0x0E0E, + 0x0E4C, 0x0FD0, 0x003D, 0x01DE, 0x01D0, 0x0132, 0x0310, 0x1CE3, 0x1DFF, + 0x1E2D, 0x1FDF, 0x10C3, 0x1133, 0x12CD, 0x131F, 0x2CE2, 0x2C02, 0x2C22, + 0x2EC2, 0x2EE2, 0x2E20, 0x20C2, 0x20EE, 0x200E, 0x2334, 0x24C2, 0x243D, + 0x3DC0, 0x3E2F, 0x3FF1, 0x3111, 0x3221, 0x34EF, 0x3443, 0x4DD0, 0x4DE1, + 0x4DF2, 0x4D21, 0x4FC1, 0x4FD0, 0x4F12, 0x4F21, 0x42DF, 0x42EE, 0x43D0, + 0x44EE, 0xCD0F, 0xCFEF, 0xDCDE, 0xED10, 0xEEE0, 0xEE1F, 0xEF12, 0xE1F2, + 0xFEFE, 0xF2F4, 0xF22F, 0xF3EC, 0xF41E, 0x0D4F, 0x0222, 0x03F0, 0x1CCF, + 0x1DCE, 0x1DE0, 0x1E4D, 0x1FE2, 0x1F1D, 0x10D4, 0x11C4, 0x11E2, 0x111D, + 0x2343, 0x241F, 0x3CD0, 0x3E10, 0xD401, 0x3F1F, 0x320F, 0xEC40, 0xE2F1, + 0xFED4, 0xF2E1, 0xF340, 0x0CE2, 0x00C4, 0x042E, 0x020C, 0x1104, 0x24FF, + 0x022C, 0x2200, 0x00F3, 0x001D, 0x1111, 0x00C2, 0x41F0, 0xCE11, 0x4EE0, + 0x44D1, 0xCCFF, 0xFDC2, 0x004E, 0x00EC, 0x2110, 0x01E1, 0x134E, 0xC01F, + 0xF1EC, 0x0FED, 0x1FEC, 0xE4F1, 0x10C1, 0x2CE0, 0x011C, 0x0CD1, 0x44F1, + 0xE1F0, 0xEF0F, 0x23C1, 0xCF2F, 0xC121, 0x0E40, 0x02EC, 0x1210, 0x3100, + 0x0F14, 0xD1F1, 0xEC31, 0xE34F, 0xE422, 0xFC32, 0xFDE4, 0xFE4D, 0xFF22, + 0xFF4E, 0xF03C, 0xF23C, 0xF3CC, 0xF3C0, 0xF324, 0xF4D0, 0x0D34, 0x0EE0, + 0x0E02, 0x0FDE, 0x0031, 0x02EE, 0x024C, 0x03FC, 0x04CE, 0x04C0, 0x04EE, + 0x1EEF, 0x1FCC, 0x10CD, 0x10E3, 0x12F2, 0x1223, 0x123C, 0x1243, 0x1342, + 0x1344, 0x2ECE, 0x2EFF, 0x2FE1, 0x2F2F, 0x20C0, 0x21F2, 0x2121, 0x3D00, + 0x340F, 0x3421, 0x4DCF, 0x4D0F, 0xD4F0, 0x4FEF, 0x44FF, 0xEC11, 0xEEEE, + 0xFE4F, 0xF041, 0xF043, 0x0E4E, 0xE01F, 0x1221, 0x14EF, 0xFEC3, 0xF2CD, + 0xF2F0, 0x0FC3, 0x00CE, 0x1EF0, 0xE110, 0x0F41, 0x1C0F, 0x10F4, 0x40FF, + 0xCE20, 0xC321, 0xF4F0, 0x0D41, 0x0EC0, 0x02C0, 0x2C00, 0x0F12, 0x0020, + 0xDF00, 0x2E00, 0xC21F, 0xC220, 0x0FF4, 0x00FD, 0x1F1F, 0x0024, 0x4DF0, + 0xFCF0, 0xF14E, 0x0EE4, 0x0F23, 0x10F0, 0x1DC0, 0x1F44, 0x110C, 0x112E, + 0xFF02, 0x143E, 0x32C1, 0xF0E1, 0x0E1F, 0x0411, 0xF102, 0x0C20, 0x0C31, + 0x0F0D, 0x01DC, 0x014D, 0x0240, 0x101C, 0x120F, 0x0FFC, 0x01CF, 0x124D, + 0x1410, 0x0E00, 0xCC2E, 0x4442, 0xCCC0, 0xCEDF, 0xCE02, 0xCF4F, 0xCF41, + 0xC002, 0xC031, 0xC040, 0xC132, 0xC2EE, 0xC34F, 0xC341, 0xDCC1, 0xDC03, + 0xDC34, 0xDC41, 0xDDEE, 0xDD42, 0xDEC1, 0xDEDC, 0xDEF2, 0xDE12, 0xDE2F, + 0xDE23, 0xDE32, 0xDE4D, 0xDE41, 0xDF0C, 0xDF20, 0xDF3F, 0xD012, 0xD030, + 0xD032, 0xD04F, 0xD041, 0xD1EE, 0xD1E2, 0xD1E4, 0xD120, 0xD14C, 0xD142, + 0xD2D2, 0xD2FE, 0xD2F2, 0xD232, 0xD243, 0xD3D3, 0xD30E, 0xD31D, 0xD320, + 0xD33D, 0xD331, 0xD42D, 0xD44F, 0xECCC, 0xECC2, 0xECD1, 0xECD3, 0xECE4, + 0xEC02, 0xEDD4, 0xEDF2, 0xED14, 0xEECC, 0xEEC2, 0xEEC4, 0xEEFD, 0xEE1D, + 0xEE2E, 0xEE33, 0xEFCF, 0xEFDE, 0xEF3C, 0xEF32, 0xE0F3, 0xE1CD, 0xE123, + 0xE2C2, 0xE2C4, 0xE2EC, 0xE2E4, 0xE233, 0xE3C1, 0xE3DC, 0xE3D0, 0xE3F2, + 0xE3F4, 0xE31E, 0xE4CE, 0xE4C2, 0xE4E4, 0xE402, 0xFCD4, 0xFDDF, 0xFDE0, + 0xFD04, 0xFED0, 0xFE03, 0xFE43, 0xFFD3, 0xF03E, 0xF032, 0xF133, 0xF20D, + 0xF223, 0xF3EE, 0xF3E0, 0xF3F1, 0xF33F, 0xF4D4, 0xF414, 0x0CCE, 0x0CC0, + 0x0CC2, 0x0CC4, 0x0C0E, 0x0C04, 0x0C44, 0x0DDC, 0x0DD2, 0x0DE1, 0x0D1E, + 0x0EDF, 0x0EF3, 0x02C4, 0x02F3, 0x0213, 0x023D, 0x03E1, 0x03FE, 0x0301, + 0x032F, 0x033E, 0x0332, 0x04C2, 0x04DD, 0x04D3, 0x0402, 0x042C, 0x1CD4, + 0x1C43, 0x1DDF, 0x1D2C, 0x1EED, 0x1EE3, 0x1FD3, 0x10D2, 0x11DD, 0x122D, + 0x123E, 0x13CC, 0x13D1, 0x13FD, 0x1320, 0x1324, 0x1432, 0x1434, 0x1443, + 0x2C13, 0x2C4E, 0x2D0F, 0x2D1E, 0x2D3C, 0x2D30, 0x2D4D, 0x2E0C, 0x2E1D, + 0x2E2C, 0x2E44, 0x2FD0, 0x2FED, 0x2F4D, 0x20CC, 0x20DF, 0x201D, 0x2013, + 0x202E, 0x21D2, 0x21ED, 0x213C, 0x213E, 0x22CC, 0x22EE, 0x22E2, 0x22FD, + 0x2202, 0x23C3, 0x23E1, 0x23F4, 0x2310, 0x232F, 0x24CC, 0x240C, 0x240E, + 0x241D, 0x2422, 0x244C, 0x2442, 0x3C2D, 0x3C32, 0x3C4F, 0x3C43, 0x3DC2, + 0x3D3F, 0x3EE1, 0x3E1E, 0x3E14, 0x3E2D, 0x3E21, 0x3E43, 0x3FE2, 0x3F4E, + 0x30E1, 0x3012, 0x302F, 0x31CC, 0x3120, 0x3122, 0x3142, 0x32CF, 0x32C3, + 0x32FC, 0x32F4, 0x324F, 0x33E0, 0x33FF, 0x3311, 0x3331, 0x3342, 0x34DE, + 0x34E3, 0x3412, 0x3432, 0x4DCD, 0x4DC1, 0x4DD2, 0x4D32, 0x4D4F, 0x4EC2, + 0x4E0E, 0x4E31, 0x4FCD, 0x4FD2, 0x4F1E, 0x4F30, 0x40DF, 0x402E, 0x403F, + 0x4040, 0x41DE, 0x41F2, 0x414F, 0x42E4, 0x4202, 0x4222, 0x423F, 0x43CD, + 0x43CF, 0x43F2, 0x432D, 0x4323, 0x44DF, 0x44D3, 0xCCD1, 0x44FD, 0x4402, + 0xCD30, 0xCE22, 0xCE31, 0xCFD0, 0xCFE1, 0xC0EE, 0xC0E0, 0xC2D1, 0xC202, + 0xC22E, 0xC3F2, 0xDCD2, 0xDCF2, 0xDC3E, 0xDDFF, 0xDD40, 0xDEEF, 0xD20F, + 0xD201, 0xD311, 0xD32C, 0xD4ED, 0xD430, 0xEC33, 0xEDDC, 0xEE22, 0xEFC3, + 0xEFE1, 0xEF34, 0xE0E0, 0xE042, 0xE11C, 0xE22E, 0xE3F0, 0xE301, 0xE321, + 0xE4DF, 0xE4FD, 0xFCC1, 0xFCE3, 0xFC23, 0xFDF1, 0xFE30, 0xF0ED, 0xF14C, + 0xF2E3, 0xF2FC, 0xF21E, 0xF3E2, 0xF3E4, 0xF4ED, 0xF4F2, 0xF432, 0x0C13, + 0x0DD4, 0x0E1D, 0x0E3F, 0x0FE3, 0x0F30, 0x01D2, 0x02DF, 0x021D, 0x0233, + 0x03CD, 0x031C, 0x0321, 0x04F3, 0x0422, 0x044C, 0x1C2D, 0x1C34, 0x1DEC, + 0x1D04, 0x1D24, 0x1FC4, 0x1F3F, 0x10DE, 0x11D1, 0x12F4, 0x120D, 0x134C, + 0x141C, 0x143C, 0x2CEE, 0x2D2F, 0x2EEE, 0x2FCD, 0x2FD4, 0x2F1E, 0x2F41, + 0x2F43, 0x202C, 0x2044, 0x21DC, 0x21F4, 0x2112, 0x214D, 0x214F, 0x22E0, + 0x2231, 0x224E, 0x2242, 0x24CE, 0x24E2, 0x2440, 0x3CDE, 0x3C30, 0x3EEF, + 0x321E, 0x33C0, 0x3344, 0x4D1E, 0x4D3E, 0x4EC0, 0x4E3F, 0x4FF2, 0x40EE, + 0x4020, 0x4022, 0x411E, 0x4112, 0x412F, 0xC1EF, 0xC231, 0xDCE1, 0xDC21, + 0xDE01, 0xDE10, 0xDF1F, 0xECE2, 0xECF1, 0xE2E2, 0xE220, 0xFC41, 0xFD20, + 0xFECD, 0xFE21, 0xFF2E, 0xF00D, 0xF02D, 0xF023, 0xF1EE, 0xF11D, 0xF2C3, + 0xF31F, 0xF43E, 0x0C2E, 0x0EC4, 0x0EEE, 0x0F3E, 0x003F, 0x0033, 0x013E, + 0x034D, 0x1CF2, 0x1C23, 0x1D44, 0x1ED4, 0x1EFE, 0x10DC, 0x10ED, 0x100D, + 0x1113, 0x1311, 0x1340, 0x14CF, 0x14DE, 0x1430, 0x2E40, 0x21CF, 0x2321, + 0x4CF1, 0x432F, 0x4420, 0xCE1F, 0xDC10, 0xF04F, 0xF10C, 0x0FCD, 0x02C2, + 0x11C2, 0x12C1, 0x20E0, 0x41EF, 0xC2FF, 0xFFC0, 0xF01C, 0xF02F, 0xF021, + 0xF1E0, 0x0E24, 0x11E0, 0xFFC2, 0x1102, 0x201F, 0xF410, 0x24F1, 0x4FF0, + 0x42F1, 0x43F0, 0x0E11, 0x2C1F, 0x4310, 0x0FF2, 0xD010, 0xE341, 0xFC21, + 0xF124, 0xF241, 0x0C22, 0x012D, 0x0123, 0x0420, 0x1CE1, 0x1E2F, 0x1241, + 0xE0FF, 0x2EF1, 0x3410, 0xFE0F, 0xFFEC, 0x0E04, 0x00EE, 0x02F1, 0x1F24, + 0x2CFF, 0x01FC, 0x4000, 0xD421, 0x4321, 0xCC3F, 0xCD01, 0xFC2F, 0x0E42, + 0x0FD4, 0x1FE0, 0x1F20, 0x10EF, 0xF401, 0x110E, 0x2DCF, 0x2FF0, 0x21F0, + 0xC11E, 0xC12F, 0xC130, 0xC4E0, 0xDF11, 0xD00F, 0xD340, 0xECCE, 0xECDF, + 0xEC2E, 0xED41, 0xEE11, 0xE00E, 0xE1EF, 0xE112, 0xE24E, 0xE4E0, 0xFC12, + 0xFE12, 0xFE14, 0xFE3C, 0xFFCC, 0xFFDF, 0xFFF3, 0xFF4C, 0xF1C4, 0xF12E, + 0xF2EF, 0xF24D, 0xF320, 0x0CDF, 0x0D14, 0x01F0, 0x0E13, 0x0E22, 0x0E31, + 0x0FD2, 0x00D1, 0x0242, 0x1DE4, 0x1EFC, 0x1E1C, 0x1FCE, 0x1F13, 0x102D, + 0x1034, 0x11EE, 0x11F3, 0x2C3F, 0x2E42, 0x2FC1, 0x22C2, 0x22EC, 0x23F0, + 0x3CCF, 0x3CE1, 0x3F11, 0x300F, 0x342F, 0x4F2F, 0x41E1, 0xCEE0, 0xED4F, + 0xE21F, 0xE420, 0xFECF, 0xFE41, 0xFFC4, 0xF430, 0x0E2C, 0x04DF, 0x1E1E, + 0x1F4C, 0x13C0, 0x14FE, 0xC0F1, 0x2411, 0x3C2F, 0xC411, 0xEEFF, 0xFFE0, + 0xF0DC, 0xF0F4, 0xF10E, 0xF20F, 0x0C11, 0x0EC2, 0x0FCF, 0x0141, 0x024E, + 0xEF01, 0x11E4, 0x1122, 0xF001, 0xF1F1, 0x1FF1, 0xF421, 0x01FE, 0x3401, + 0x4D2F, 0xCD2F, 0xC2F1, 0xFE01, 0xF104, 0x00E2, 0xE411, 0x10E1, 0x3CF0, + 0x0F01, 0x100F, 0xF010, 0x010F, 0xF00F, 0x111F, 0x00E0, 0x14F0, 0xF01E, + 0xECE0, 0xFCD0, 0xFEFC, 0xFE2F, 0xCDF0, 0xF0D4, 0xF4DE, 0x1CD0, 0x1ECF, + 0xE0F1, 0x1EE1, 0x1EF4, 0xE431, 0xFF0E, 0xFF24, 0xF0FC, 0xF201, 0x021F, + 0x1E0F, 0x2CC0, 0x1001, 0xFF1F, 0x12F0, 0x2011, 0x4E1F, 0xC310, 0x410F, + 0x121E, 0xCCDD, 0x4433, 0xCCC2, 0xCCC4, 0xCCDF, 0xCCE2, 0xC200, 0xEF10, + 0xCC1F, 0xFDCE, 0xCE00, 0xFFCE, 0xF120, 0x0EF1, 0x02CE, 0x0F10, 0x0FF0, + 0xFF11, 0x1EC1, 0x1E01, 0x2211, 0x3CEF, 0x011E, 0x3010, 0x4EF1, 0xC000, + 0x0F3C, 0x10FE, 0x4E11, 0xCC20, 0xCC31, 0xCD1E, 0xCD4F, 0xCED1, 0xCE2E, + 0xCFFE, 0xCF32, 0xC1F0, 0xE400, 0x104F, 0xC03F, 0xC1F2, 0xC2DF, 0xC20E, + 0xC3FE, 0xC32F, 0xC4E2, 0xC42E, 0xDC12, 0xDF2E, 0xD1E0, 0xD4D2, 0xD42F, + 0xEC22, 0xEC4E, 0xEDC1, 0x1FFF, 0xCFF0, 0xF0F0, 0xEDC3, 0xEDEF, 0xED2F, + 0xEEDD, 0xEFCD, 0xEFFE, 0xEF4D, 0xEF43, 0xE0C2, 0xE0EE, 0xE0E4, 0xE002, + 0xE004, 0xE022, 0xE13E, 0xE132, 0xE143, 0xE2D3, 0xE20E, 0xE22C, 0xE231, + 0xE3CD, 0xE3C3, 0xE3E1, 0xE3FE, 0xE310, 0xE4C0, 0xE4EC, 0xE4E2, 0xE442, + 0xFCED, 0xFC43, 0xFDD1, 0xFDEE, 0xFDFF, 0xFD22, 0xFEDE, 0xFED2, 0xFEF2, + 0xFF13, 0xFF33, 0xF0D2, 0xF2D2, 0xF230, 0xF243, 0xF3C4, 0xF331, 0xF4C1, + 0xF4DC, 0xF4FE, 0x0D43, 0x03D4, 0x03F4, 0x0334, 0x04E2, 0x04FD, 0x041D, + 0x1C4D, 0x1DC2, 0x1D11, 0x1ECD, 0x1ED2, 0x1FD1, 0x1F33, 0x10D0, 0x11D3, + 0x12DE, 0x12D0, 0x12D4, 0x12E3, 0x13EC, 0x13F1, 0x14C3, 0x14F2, 0x141E, + 0x2C0E, 0x2C1D, 0x2DDE, 0x2DEF, 0x2D14, 0x2D4F, 0x2EEC, 0x2E3F, 0x2E31, + 0x2FCF, 0x2FC3, 0x2FDC, 0x2F3C, 0x20E2, 0x20E4, 0x2022, 0x2024, 0x204E, + 0x2042, 0x21E3, 0x2132, 0x22CE, 0x22D1, 0x224C, 0x2341, 0x242E, 0x243F, + 0x244E, 0x3CC1, 0x3CD2, 0x3CED, 0x3DF1, 0x3D1F, 0x3D11, 0x3D40, 0x3ECF, + 0x3ED4, 0x3FFF, 0x32ED, 0x3201, 0x341E, 0x343E, 0x4C20, 0x4DDE, 0x4ED1, + 0x4E22, 0x4FFE, 0x42E2, 0x43DE, 0xCF30, 0x43FE, 0x4332, 0xDD00, 0xDFE0, + 0xD300, 0xD4E1, 0xD4F2, 0xEDDE, 0xEEC0, 0xEE04, 0xEE24, 0xEE4E, 0xE242, + 0xFC1E, 0xFD11, 0xFE1C, 0xFE1E, 0xFFD1, 0xF44F, 0x0C3F, 0x0EE2, 0x0E2E, + 0x0130, 0x02E4, 0x020E, 0x0341, 0x1CD2, 0x1C32, 0x1C41, 0x1DF1, 0x1EC3, + 0x1FF3, 0x1030, 0x11CC, 0x11DF, 0x1131, 0x1144, 0x1300, 0x132C, 0x2CD1, + 0x2D41, 0x21E1, 0x211E, 0x2220, 0x23CF, 0x3E0F, 0x34C1, 0x4EDF, 0x4EEE, + 0x430F, 0xD210, 0xD241, 0xEFEF, 0xE11E, 0xF1E2, 0x0F2D, 0x0220, 0x1E34, + 0x0110, 0x11CE, 0x12CF, 0x12EF, 0x121C, 0xFEEF, 0x221F, 0x31FF, 0xF014, + 0xF2C1, 0x0C1F, 0x0EFF, 0x1F02, 0x24E0, 0x3C10, 0x42E0, 0xF0C1, 0x114E, + 0xF11F, 0xFC10, 0x42FF, 0x40E0, 0xC1E1, 0x0FC1, 0x1F42, 0x0F0F, 0x11FF, + 0x0112, 0xC211, 0xD410, 0xFFEE, 0xFF20, 0xF1FF, 0x01C3, 0x010D, 0x1CEF, + 0x1F4E, 0x0042, 0x102F, 0x1021, 0x1010, 0xFFF1, 0xFC0F, 0x34E1, 0xC30F, + 0xC4FF, 0x2400, 0xD1FF, 0xD140, 0xD2F0, 0xEEF1, 0x4110, 0xF111, 0x0101, + 0x11F1, 0xFCE1, 0xF0CD, 0xF142, 0xF144, 0xF300, 0xF34E, 0x0E20, 0x1C12, + 0x1C21, 0x1C30, 0x1D00, 0x1E14, 0x1E3C, 0x1FC2, 0x12E1, 0x12FC, 0x1214, + 0x21C1, 0x34D0, 0x4EFF, 0xCEFF, 0x43E1, 0x4301, 0xC101, 0xECFF, 0xE011, + 0xFF0C, 0xFF2C, 0x02FF, 0x041F, 0x1C2F, 0xFE10, 0x14D0, 0x3210, 0xF1CE, + 0x0FE1, 0x0F21, 0x101E, 0x2CDF, 0x4211, 0xC011, 0xEE40, 0xE240, 0xF1C0, + 0xF2CF, 0x0CFF, 0x0F2F, 0x4E00, 0x0F43, 0x10F2, 0x4D10, 0xEC20, 0xF0EF, + 0xF42F, 0x04FF, 0x1C01, 0x1FC0, 0x1043, 0x1120, 0x1201, 0x2CF1, 0x24D1, + 0x4CFF, 0x4F01, 0x4011, 0x00E4, 0xFEC1, 0xF0CF, 0x1401, 0x4C00, 0x2000, + 0xE101, 0xCCE0, 0x44E0, 0xCCD3, 0xCCEC, 0xCCE4, 0xCCFD, 0xCDE1, 0xCD21, + 0xC1D0, 0xC23F, 0xC420, 0xD11F, 0xD3FF, 0xD40F, 0xD441, 0xEDF0, 0xEE02, + 0xE0C0, 0xE1D4, 0xE1E1, 0xE1FE, 0xE4D1, 0xE43F, 0xFDEC, 0xFD00, 0xFD1F, + 0xFE23, 0xFFDD, 0xFFFD, 0xF1DF, 0xF113, 0xF13F, 0xF214, 0xF234, 0xF412, + 0x0CF3, 0x0D0F, 0x0ECC, 0x00D3, 0x022E, 0x04D1, 0x040E, 0x1CC1, 0x1C1E, + 0x1C4F, 0x1E12, 0x1E3E, 0x1F31, 0x103E, 0x113D, 0x113F, 0x13CE, 0x13E0, + 0x14C1, 0x14ED, 0x144D, 0x2C2E, 0x2D10, 0x2D21, 0x2EE0, 0x2E02, 0x2E4E, + 0x2F21, 0x2F4F, 0x220E, 0x2240, 0x234D, 0x3CF2, 0x3C01, 0x3C21, 0x34D2, + 0x4CE0, 0xCE3F, 0x42D1, 0x43EF, 0xCF21, 0xC3E1, 0xE121, 0xE2FF, 0xE211, + 0xFDC4, 0xFEE1, 0xFE34, 0xFF04, 0xF122, 0xF2D4, 0x0EEC, 0x00DF, 0x0204, + 0x043F, 0x044E, 0x1D40, 0x1FFD, 0x1F04, 0x12FE, 0x122F, 0x144F, 0x2C20, + 0x2222, 0xCDEF, 0xD0F0, 0xE440, 0xF1CC, 0xFEF0, 0x0CF1, 0x0F34, 0x00C0, + 0xF012, 0x0121, 0x1F11, 0x0C00, 0x1E41, 0x4101, 0x40F1, 0xDFF1, 0x01F2, + 0xEC3F, 0x01CD, 0x2F01, 0xDCF0, 0xFC30, 0xFFE4, 0xF24F, 0x00CC, 0x1FE4, + 0x0004, 0x4F10, 0x11EC, 0x1234, 0x22C0, 0x24C0, 0xEC00, 0x0FEF, 0x01F4, + 0x0F1E, 0x2EC0, 0x3C0F, 0xD111, 0xEF2F, 0x4200, 0xEC1F, 0xEE00, 0x0002, + 0xC110, 0xF210, 0x1CF0, 0x0FFE, 0xE141, 0xE4FF, 0xF034, 0xF221, 0xF4E1, + 0x0DC3, 0x1003, 0x11FD, 0xE000, 0xCF0F, 0x21EF, 0x31F1, 0xDEF0, 0xE040, + 0xF4EF, 0x013C, 0x0211, 0x04E0, 0x1D42, 0x1F2E, 0x10FC, 0x11C0, 0x03CF, + 0x1124, 0x34F0, 0x0F1C, 0xD100, 0x034F, 0x1142, 0xCD10, 0xC3F0, 0x421F, + 0x4431, 0xCCF3, 0xCC0C, 0xCC02, 0xCC04, 0xCC1D, 0xCC13, 0xCC2C, 0xCC24, + 0xCC3D, 0xCC33, 0xCC4C, 0xCC4E, 0xCC42, 0xCC44, 0xCDCD, 0xCDCF, 0xF100, + 0x000C, 0xE10F, 0x1F40, 0x20FF, 0x210F, 0xEFF0, 0xCEF1, 0xC0FF, 0xE41F, + 0xFC01, 0x000E, 0xFD40, 0xF0C3, 0xF1E4, 0xF12C, 0xF140, 0x01E3, 0x1F0C, + 0x1014, 0x01EF, 0x4411, 0xCDC1, 0xCDDC, 0xCDD4, 0xCDE3, 0xCDFC, 0xCDF4, + 0xCD0D, 0xCD03, 0xCD1C, 0xCD14, 0xCD2D, 0xCD23, 0xCD3C, 0xCD34, 0xCD4D, + 0xCD41, 0xCECC, 0xCECE, 0xCEC0, 0xCEC2, 0xCEC4, 0xCED3, 0xCEEC, 0xCEEE, + 0xCEE2, 0xCEFD, 0xCEF3, 0xCE0C, 0xCE04, 0xCE1D, 0xCE13, 0xCE2C, 0x0040, + 0x04F1, 0x0400, 0x124F, 0x4400, 0xCE24, 0xCE3D, 0xCE33, 0xCE4C, 0xCE42, + 0xCE44, 0xCFCD, 0xCFCF, 0xCFC1, 0xCFC3, 0xCFDC, 0xCFD2, 0xCFD4, 0xCFED, + 0xCFE3, 0xCFFC, 0xCFF2, 0xCFF4, 0xCF0D, 0xCF03, 0xCF1C, 0xCF1E, 0xCF3C, + 0xCF34, 0xCF4D, 0xCF43, 0xC0CC, 0xC0CE, 0xC0C0, 0xC0C2, 0xC0C4, 0xC0D1, + 0xC0D3, 0xC0EC, 0xC0E2, 0xC0E4, 0xC0F3, 0xC00C, 0xC004, 0xC013, 0xC02C, + 0xC022, 0xC024, 0xC03D, 0xC033, 0xC04E, 0xC042, 0xC044, 0xC1CF, 0xC1C3, + 0xC1DC, 0xC1D2, 0xC1D4, 0xC1ED, 0xC1E3, 0xC1FC, 0xC1F4, 0xC10D, 0xC11C, + 0xC112, 0xC114, 0xC12D, 0xC123, 0xC13C, 0x0013, 0xC134, 0xC14D, 0xC14F, + 0xC143, 0xC2CC, 0xC2CE, 0xC2C0, 0xC2C2, 0xC2C4, 0xC2D3, 0xC2EC, 0xC2E4, + 0xC2FD, 0xC20C, 0xC204, 0xC21D, 0xC213, 0xC22C, 0xC224, 0xC23D, 0xC233, + 0xC24C, 0xC24E, 0xC240, 0xC3CD, 0xC3C3, 0xC3DC, 0xC3D4, 0xC3ED, 0xC3F4, + 0xC30D, 0xC303, 0xC31C, 0xC312, 0xC314, 0xC32D, 0xC33C, 0xC33E, 0xC334, + 0xC34D, 0xC4CC, 0xC4CE, 0xC4C0, 0xC4C2, 0xC4C4, 0xC4DF, 0xC4EC, 0xC4EE, + 0xC4FD, 0xC4F3, 0xC40E, 0xC402, 0xC404, 0xC41D, 0xC413, 0xC42C, 0xC424, + 0xC43D, 0xC433, 0xC44C, 0xC442, 0xC444, 0xDCCF, 0xDCDC, 0xDCED, 0xDCE3, + 0xDCFC, 0xDCF4, 0xDC0D, 0xDC1C, 0xDC14, 0xDC3C, 0xDC43, 0xDDCE, 0xDDC4, + 0xDDD1, 0xDDD3, 0xDDE2, 0xDDE4, 0xDDFD, 0xDDF3, 0xDD0C, 0xDD0E, 0xDD1D, + 0xDD1F, 0xDD13, 0xDD24, 0xDD3D, 0xDD3F, 0xDD31, 0xDD33, 0xDD4C, 0xDD44, + 0xDECD, 0xDEC3, 0xDED0, 0xDED2, 0xDEED, 0xDEE3, 0xDEFC, 0xDEF4, 0xDE0D, + 0xDE03, 0xDE1C, 0xDE1E, 0xDE14, 0xDE2D, 0xDE3C, 0xDE3E, 0xDE30, 0xDFCC, + 0xDFC0, 0xDFC2, 0xDFC4, 0xDFDD, 0xDFD1, 0xDFD3, 0xDFEC, 0xDFE2, 0xDFFD, + 0xDFF3, 0xDF02, 0xDF04, 0xDF1D, 0xDF24, 0xDF3D, 0xDF31, 0xDF33, 0xDF4C, + 0xDF4E, 0xDF44, 0xD0CD, 0xD0CF, 0xD0C3, 0xD0DC, 0xD0D0, 0xD0D2, 0xD0D4, + 0xD0ED, 0xD0EF, 0xD0E1, 0xD0FC, 0xD0FE, 0xD0F4, 0xD00D, 0xD003, 0xD014, + 0xD02D, 0xD023, 0xD03C, 0xD034, 0xD04D, 0xD1C4, 0xD1DD, 0xD1DF, 0xD1D1, + 0xD1D3, 0xD1FD, 0xD1F3, 0xD10C, 0xD10E, 0xD102, 0xD11D, 0xD113, 0xD12E, + 0xD122, 0xD124, 0xD13D, 0xD13F, 0xD131, 0xD133, 0xD144, 0xD2CD, 0xD2CF, + 0xD2C1, 0xD2C3, 0xD2DE, 0xD2D0, 0xD2D4, 0xD2ED, 0xD20D, 0xD203, 0xD21C, + 0xD21E, 0xD212, 0xD223, 0xD23C, 0xD230, 0xD234, 0xD24D, 0xD3CC, 0xD3CE, + 0xD3DD, 0xD3DF, 0xD3D1, 0xD3EE, 0xD3E2, 0xD3E4, 0xD3FD, 0xD3F3, 0xD30C, + 0xD302, 0xD304, 0xD31F, 0xD313, 0xD32E, 0xD324, 0xD33F, 0xD333, 0xD34C, + 0xD34E, 0xD344, 0xD4CD, 0xD4CF, 0xD4DC, 0xD4DE, 0xD4D0, 0xD4D4, 0xD4FC, + 0xD4FE, 0xD4F4, 0xD40D, 0xD403, 0xD41C, 0xD412, 0xD414, 0xD423, 0xD43C, + 0xD43E, 0xD434, 0xD44D, 0xECC0, 0xECDD, 0xECEC, 0xEC0C, 0xEC04, 0xEC1D, + 0xEC2C, 0xEC3D, 0xEC4C, 0xEC42, 0xEC44, 0xEDD0, 0xEDD2, 0xEDED, 0xEDE1, + 0xEDE3, 0xEDFC, 0xEDFE, 0xEDF4, 0xED0D, 0xED03, 0xED1C, 0xED1E, 0xED12, + 0xED2D, 0xED23, 0xED3E, 0xED32, 0xEED1, 0xEED3, 0xEEE4, 0xEE0E, 0xEE2C, + 0xEE3D, 0xEE3F, 0xEE4C, 0xEE44, 0xEFD0, 0xEFD2, 0xEF0D, 0xEF03, 0xEF1C, + 0xEF2D, 0xE0CC, 0xE0DD, 0xE0DF, 0xE0D1, 0xE0D3, 0xE0FD, 0xE01D, 0xE03D, + 0xE033, 0xE044, 0xE1DC, 0xE1DE, 0xE1D0, 0xE1D2, 0xE1ED, 0xE10D, 0xE103, + 0xE13C, 0xE2DD, 0xE2FD, 0xE2F3, 0xE23D, 0xE23F, 0xE244, 0xE3D2, 0xE3ED, + 0xE3E3, 0xE30D, 0xE303, 0xE312, 0xE314, 0xE32D, 0xE323, 0xE33E, 0xE332, + 0xE334, 0xE4CC, 0xE4C4, 0xE4F3, 0xE40C, 0xE404, 0xE41D, 0xE424, 0xE433, + 0xE44C, 0xE444, 0xFCFC, 0xFC1C, 0xFC14, 0xFC2D, 0xFC3C, 0xFC3E, 0xFDD3, + 0xFDE2, 0xFDFD, 0xFDF3, 0xFD0C, 0xFD0E, 0xFD1D, 0xFD13, 0xFD2C, 0xFD3D, + 0xFD3F, 0xFD33, 0xFD4C, 0xF1DD, 0xF13D, 0xF203, 0xF22D, 0xF232, 0xF3DD, + 0xF3DF, 0xF3D1, 0xF3FD, 0xF3F3, 0xF302, 0xF31D, 0xF313, 0xF32E, 0xF33D, + 0xF333, 0xF4C3, 0xF4E3, 0xF4FC, 0xF4F4, 0xF41C, 0xF423, 0xF434, 0xF443, + 0x0CDD, 0x0CEC, 0x0C2C, 0x0C3D, 0x0DED, 0x0DE3, 0x0DFC, 0x0DFE, 0x0D0D, + 0x0D03, 0x0D1C, 0x0D12, 0x0D23, 0x0D3C, 0x0D3E, 0x0D30, 0x0ED3, 0x0EFD, + 0x0E3D, 0x02D1, 0x0231, 0x03DE, 0x03D0, 0x03D2, 0x03ED, 0x03E3, 0x03F2, + 0x030F, 0x0303, 0x031E, 0x032D, 0x0323, 0x0330, 0x04CC, 0x04C4, 0x04E4, + 0x0404, 0x0413, 0x0424, 0x0433, 0x0444, 0x1CCD, 0x1CC3, 0x1CDC, 0x1CF4, + 0x1C0D, 0x1C1C, 0x1C3C, 0x1DCC, 0x1DEE, 0x1DFD, 0x1DF3, 0x1D0C, 0x1D13, + 0x1D2E, 0x1D22, 0x1D3D, 0x1D3F, 0x1D33, 0x1D4C, 0x1ED0, 0x1E0D, 0x1E03, + 0x1E32, 0x1023, 0x12C3, 0x12D2, 0x12ED, 0x1203, 0x13C4, 0x13DD, 0x13DF, + 0x13D3, 0x13EE, 0x13E2, 0x13E4, 0x13F3, 0x130C, 0x1302, 0x1304, 0x1313, + 0x1322, 0x133D, 0x1331, 0x14CD, 0x14D4, 0x14F4, 0x1403, 0x1412, 0x1414, + 0x1423, 0x2CCC, 0x2CC2, 0x2CC4, 0x2CDD, 0x2CE4, 0x2CFD, 0x2CF3, 0x2C0C, + 0x2C04, 0x2C2C, 0x2C24, 0x2C33, 0x2C4C, 0x2C40, 0x2C44, 0x2DCD, 0x2DC3, + 0x2DD0, 0x2DD2, 0x2DD4, 0x2DED, 0x2DE1, 0x2DFE, 0x2DF2, 0x2D0D, 0x2D03, + 0x2D1C, 0x2D12, 0x2D2D, 0x2D23, 0x2D3E, 0x2D32, 0x2D43, 0x2EDD, 0x2ED3, + 0x2EFD, 0x2E0E, 0x2E04, 0x2E13, 0x2E3D, 0x2E33, 0x2E4C, 0x2FD2, 0x2FFC, + 0x2F0D, 0x2F03, 0x2F1C, 0x2F14, 0x2F23, 0x2F30, 0x2F32, 0x20C4, 0x20DD, + 0x20D3, 0x203D, 0x203F, 0x2031, 0x2033, 0x204C, 0x21D4, 0x2103, 0x212D, + 0x2130, 0x2143, 0x22C4, 0x22DD, 0x22DF, 0x22D3, 0x22F3, 0x221D, 0x222C, + 0x223D, 0x223F, 0x23CD, 0x23D2, 0x23ED, 0x23E3, 0x23F2, 0x230D, 0x2314, + 0x232D, 0x2323, 0x233C, 0x233E, 0x24C4, 0x24EC, 0x24F3, 0x2402, 0x2404, + 0x2413, 0x2424, 0x3CCD, 0x3CC3, 0x3CDC, 0x3CD4, 0x3CE3, 0x3CFC, 0x3CF4, + 0x3C0D, 0x3C1E, 0x3C3C, 0x3C34, 0x3DCC, 0x3DCE, 0x3DC4, 0x3DDD, 0x3DDF, + 0x3DD1, 0x3DD3, 0x3DEC, 0x3DEE, 0x3DE0, 0x3DE2, 0x3DE4, 0x3DFD, 0x3DF3, + 0x3D0C, 0x3D0E, 0x3D02, 0x3D04, 0x3D1D, 0x3D2E, 0x3D20, 0x3D24, 0x3D31, + 0x3D4C, 0x3D44, 0x3ECD, 0x3EC3, 0x3ED0, 0x3ED2, 0x3EED, 0x3EFC, 0x3EFE, + 0x3EF2, 0x3EF4, 0x3E0D, 0x3E03, 0x3E1C, 0x3E23, 0x3E3E, 0x3E30, 0x3E32, + 0x3E4D, 0x3FC4, 0x3FDD, 0x3FD1, 0x3FEC, 0x3FEE, 0x3FE0, 0x3FE4, 0x3FFD, + 0x3F0C, 0x3F04, 0x3F1D, 0x3F13, 0x3F2E, 0x3F22, 0x3F24, 0x3F3D, 0x3F3F, + 0x3F31, 0x3F33, 0x3F4C, 0x3F40, 0x3F42, 0x3F44, 0x30CD, 0x30CF, 0x30C1, + 0x30C3, 0x30DC, 0x30DE, 0x30D0, 0x30D2, 0x30ED, 0x30E3, 0x30F4, 0x300D, + 0x3003, 0x301C, 0x302D, 0x3021, 0x3023, 0x303C, 0x303E, 0x3030, 0x3032, + 0x3034, 0x304F, 0x3041, 0x3043, 0x31C2, 0x31C4, 0x31D3, 0x31E4, 0x31FD, + 0x31F3, 0x310C, 0x3102, 0x3104, 0x311D, 0x3113, 0x312E, 0x3124, 0x313D, + 0x313F, 0x3131, 0x3133, 0x314C, 0x3140, 0x32CD, 0x32DC, 0x32DE, 0x32D0, + 0x32D2, 0x32D4, 0x32E3, 0x320D, 0x3203, 0x3212, 0x3214, 0x322D, 0x3223, + 0x323E, 0x3230, 0x3234, 0x324D, 0x3241, 0x3243, 0x33CC, 0x33DD, 0x33DF, + 0x33D1, 0x33D3, 0x33EE, 0x33E2, 0x33E4, 0x33F3, 0x330C, 0x330E, 0x3302, + 0x3304, 0x331D, 0x3313, 0x3320, 0x333D, 0x333F, 0x3340, 0x34CD, 0x34C3, + 0x34D4, 0x34FC, 0x34F4, 0x3403, 0x341C, 0x3414, 0x342D, 0x3423, 0x3434, + 0x344D, 0x344F, 0x3441, 0x4CCC, 0x4CCE, 0x4CC0, 0x4CC2, 0x4CC4, 0x4CDD, + 0x4CD1, 0x4CD3, 0x4CEC, 0x4CEE, 0x4CE2, 0x4CE4, 0x4CFD, 0x4CF3, 0x4C0C, + 0x4C02, 0x4C04, 0x4C1D, 0x4C13, 0x4C2C, 0x4C2E, 0x4C22, 0x4C3F, 0x4C31, + 0x4C4C, 0x4C4E, 0x4C40, 0x4C42, 0x4C44, 0x4DC3, 0x4DDC, 0x4DD4, 0x4DED, + 0x4DE3, 0x4DFC, 0x4DF4, 0x4D0D, 0x4D03, 0x4D1C, 0x4D14, 0x4D2D, 0x4D3C, + 0x4D30, 0x4D34, 0x4D4D, 0x4D41, 0x4D43, 0x4ECC, 0x4EC4, 0x4EDD, 0x4ED3, + 0x4EEC, 0x4EF3, 0x4E0C, 0x4E1D, 0x4E13, 0x4E2C, 0x4E24, 0x4E33, 0x4E40, + 0x4E44, 0x4FC3, 0x4FDC, 0x4FD4, 0x4FED, 0x4FE3, 0x4FFC, 0x4FF4, 0x4F0D, + 0x4F1C, 0x4F14, 0x4F2D, 0x4F23, 0x4F3C, 0x4F34, 0x4F4D, 0x4F4F, 0x4F43, + 0x40CC, 0x40C2, 0x40C4, 0x40DD, 0x40D3, 0x40EC, 0x40E2, 0x40E4, 0x40FD, + 0x40F3, 0x400C, 0x4002, 0x4004, 0x401D, 0x4013, 0x402C, 0x4024, 0x403D, + 0x4033, 0x404C, 0x404E, 0x4042, 0x4044, 0x41CD, 0x41CF, 0x41C1, 0x41C3, + 0x41DC, 0x41D2, 0x41D4, 0x41ED, 0x41E3, 0x41FC, 0x41F4, 0x410D, 0x4103, + 0x411C, 0x4114, 0x412D, 0x4123, 0x4132, 0x4134, 0x414D, 0x4141, 0x4143, + 0x42CC, 0x42CE, 0x42C2, 0x42C4, 0x42DD, 0x42EC, 0x42FD, 0x42F3, 0x420C, + 0x4204, 0x421D, 0x422C, 0x4224, 0x423D, 0x4233, 0x424C, 0x424E, 0x4240, + 0x4242, 0x4244, 0x43C3, 0x43DC, 0x43D2, 0x43D4, 0x43E3, 0x43FC, 0x43F4, + 0x430D, 0x4303, 0x431C, 0x4314, 0x433C, 0x433E, 0x4330, 0x4334, 0x434D, + 0x434F, 0x4341, 0x4343, 0x44CC, 0x44CE, 0x44C0, 0x44C4, 0x44DD, 0x44EC, + 0x44E4, 0x44F3, 0x440C, 0x4404, 0x4413, 0x442C, 0x4422, 0x4424, 0x443D, + 0x444C, 0x444E, 0xCCCC, 0x4440, 0x4444, 0xCC0E, 0xCC40, 0xCDC3, 0xCDD2, + 0xCDED, 0xCDF2, 0xCD12, 0xCD32, 0xCD43, 0xCEDD, 0xCEE4, 0xCE4E, 0xCFDE, + 0xCF14, 0xCF2D, 0xCF23, 0xCF3E, 0xC0DD, 0xC0DF, 0xC0FD, 0xC01D, 0xC02E, + 0xC04C, 0xC1CD, 0xC1C1, 0xC1DE, 0xC103, 0xC141, 0xC2DD, 0xC2F3, 0xC222, + 0xC242, 0xC244, 0xC3CF, 0xC3C1, 0xC3DE, 0xC3D0, 0xC3FC, 0xC31E, 0xC323, + 0xC343, 0xC4DD, 0xC4D1, 0xC4E4, 0xC40C, 0xC422, 0xC44E, 0xDCCD, 0xDCC3, + 0xDCD4, 0xDC1E, 0xDC2D, 0xDC23, 0xDC32, 0xDC4D, 0xDDC0, 0xDDC2, 0xDDDF, + 0xDDEC, 0xDDE0, 0xDD02, 0xDD04, 0xDD2C, 0xDD2E, 0xDD20, 0xDD22, 0xDD4E, + 0xDEDE, 0xDED4, 0xDEFE, 0xDE34, 0xDFCE, 0xDFDF, 0xDFEE, 0xDFE4, 0xDF0E, + 0xDF13, 0xDF2C, 0xDF22, 0xD0C1, 0xD0DE, 0xD0E3, 0xD0F2, 0xD01C, 0xD01E, + 0xD02F, 0xD021, 0xD03E, 0xD043, 0xD1CC, 0xD1C0, 0xD104, 0xD2DC, 0xD2E3, + 0xD2FC, 0xD2F4, 0xD22D, 0xD23E, 0xD3C0, 0xD3C2, 0xD3C4, 0xD3EC, 0xD3E0, + 0xD3F1, 0xD322, 0xD4C1, 0xD4C3, 0xD4E3, 0xD443, 0xECFD, 0xEC0E, 0xEC13, + 0xEC24, 0xEDCF, 0xED0F, 0xED21, 0xED30, 0xEEDF, 0xEEEC, 0xEEF3, 0xEE0C, + 0xEFED, 0xEFE3, 0xEFF2, 0xEF14, 0xEF23, 0xEF3E, 0xE0CE, 0xE0C4, 0xE0E2, + 0xE013, 0xE02C, 0xE02E, 0xE03F, 0xE031, 0xE04E, 0xE1E3, 0xE1FC, 0xE130, + 0xE134, 0xE2CC, 0xE2DF, 0xE2D1, 0xE2EE, 0xE20C, 0xE202, 0xE21D, 0xE24C, + 0xE3DE, 0xE3EF, 0xE3FC, 0xE31C, 0xE330, 0xE34D, 0xE413, 0xFCCD, 0xFCF4, + 0xFC0D, 0xFC03, 0xFC34, 0xFC4D, 0xFDDD, 0xFD2E, 0xFD31, 0xFD44, 0xFE0D, + 0xFE3E, 0xFE32, 0xFF44, 0xF2DE, 0xF2D0, 0xF3D3, 0xF30C, 0xF30E, 0xF304, + 0xF322, 0xF34C, 0xF344, 0xF40D, 0xF403, 0xF42D, 0xF43C, 0xF44D, 0x0CCC, + 0x0CD3, 0x0CFD, 0x0C0C, 0x0C1D, 0x0C4C, 0x0C4E, 0x0DCD, 0x0DDE, 0x0DD0, + 0x0DEF, 0x0DF2, 0x0D4D, 0x0EDD, 0x0E33, 0x02DD, 0x02D3, 0x02FD, 0x0202, + 0x023F, 0x0244, 0x03C3, 0x030D, 0x0312, 0x0314, 0x0343, 0x04EC, 0x040C, + 0x043D, 0x0442, 0x1CFC, 0x1C14, 0x1DD3, 0x1D0E, 0x1D02, 0x1D1D, 0x1D31, + 0x1EDE, 0x1E23, 0x1032, 0x1230, 0x13FF, 0x130E, 0x131D, 0x133F, 0x14DC, + 0x14E3, 0x14FC, 0x140D, 0x2CCE, 0x2CEC, 0x2DE3, 0x2DFC, 0x2ECC, 0x2EC4, + 0x2ED1, 0x2E22, 0x2FDE, 0x2FF4, 0x2F2D, 0x2F3E, 0x20FD, 0x2040, 0x21C3, + 0x21DE, 0x21FC, 0x210D, 0x2134, 0x22E4, 0x220C, 0x2204, 0x2213, 0x222E, + 0x2224, 0x23DC, 0x23DE, 0x23D0, 0x23D4, 0x23EF, 0x23FE, 0x2303, 0x231E, + 0x2312, 0x2330, 0x24DD, 0x24E4, 0x24FD, 0x2433, 0x3C03, 0x3C1C, 0x3C12, + 0x3C14, 0x3C23, 0x3C4D, 0x3D13, 0x3D22, 0x3D3D, 0x3D33, 0x3D42, 0x3EDE, + 0x3EE3, 0x3E12, 0x3E3C, 0x3E34, 0x3E41, 0x3FCC, 0x3FCE, 0x3FC2, 0x3FDF, + 0x3FD3, 0x3FF3, 0x3F0E, 0x3F02, 0x3F20, 0x30D4, 0x30EF, 0x30FC, 0x30FE, + 0x30F2, 0x301E, 0x3014, 0x304D, 0x31DD, 0x31DF, 0x31D1, 0x31EC, 0x31E2, + 0x310E, 0x312C, 0x3144, 0x32EF, 0x32E1, 0x32F2, 0x321C, 0x323C, 0x3232, + 0x33CE, 0x33C4, 0x33EC, 0x33FD, 0x33F1, 0x3300, 0x331F, 0x332C, 0x3322, + 0x3324, 0x334C, 0x334E, 0x34ED, 0x34F2, 0x340D, 0x343C, 0x3430, 0x4C24, + 0x4C3D, 0x4C33, 0x4DFE, 0x4D12, 0x4D23, 0x4ECE, 0x4EE4, 0x4EFD, 0x4E02, + 0x4E04, 0x4E4C, 0x4E4E, 0x4E42, 0x4FCF, 0x4F03, 0x4F3E, 0x4F32, 0x4F41, + 0x40CE, 0x40C0, 0x400E, 0x4031, 0x413C, 0x413E, 0x4130, 0x42D3, 0x420E, + 0x4213, 0x4231, 0x43ED, 0x431E, 0x4312, 0x44C2, 0x44E2, 0x440E, 0x441D, + 0x442E, 0xCCEE, 0xCC22, 0xCDD0, 0xCDFE, 0xCD3E, 0xCE0E, 0xCF12, 0xC1FE, + 0xC13E, 0xC2E2, 0xC3E3, 0xC332, 0xC4D3, 0xC43F, 0xC440, 0xDCD0, 0xDCFE, + 0xDDCC, 0xDDDD, 0xDDF1, 0xDD11, 0xDECF, 0xDEE1, 0xDE21, 0xDF42, 0xD1CE, + 0xD1C2, 0xD1EC, 0xD12C, 0xD2EF, 0xD214, 0xD22F, 0xD221, 0xD342, 0xD41E, + 0xED01, 0xED3C, 0xED34, 0xED4D, 0xED43, 0xEEE2, 0xEE13, 0xEE31, 0xEFDC, + 0xEFD4, 0xEFF4, 0xE0EC, 0xE00C, 0xE024, 0xE04C, 0xE1C3, 0xE114, 0xE12D, + 0xE14D, 0xE14F, 0xE2CE, 0xE2C0, 0xE204, 0xE213, 0xE222, 0xE224, 0xE3D4, + 0xE30F, 0xE32F, 0xE4DD, 0xE4D3, 0xE4EE, 0xE40E, 0xE42C, 0xE44E, 0xFCCF, + 0xFCDC, 0xFCFE, 0xFD02, 0xFD42, 0xFEE3, 0xFE2D, 0xF0DE, 0xF0D0, 0xF04D, + 0xF131, 0xF2ED, 0xF23E, 0xF32C, 0x0CEE, 0x0D2D, 0x0D21, 0x0D32, 0x03EF, + 0x0431, 0x0440, 0x1CDE, 0x1CED, 0x1C03, 0x1DDD, 0x1DE2, 0x1D1F, 0x1D20, + 0x1EDC, 0x1E30, 0x1FDD, 0x1F3D, 0x1232, 0x132E, 0x1333, 0x2CD3, 0x2C3D, + 0x2C31, 0x2C42, 0x2DDC, 0x2D01, 0x2EDF, 0x2EE4, 0x2EF3, 0x2E24, 0x2FE3, + 0x2F12, 0x2F34, 0x20CE, 0x20D1, 0x20EC, 0x20F3, 0x200C, 0x2002, 0x2004, + 0x21CD, 0x21D0, 0x211C, 0x2114, 0x2123, 0x2233, 0x2244, 0x23FC, 0x230F, + 0x2301, 0x231C, 0x234F, 0x24D3, 0x242C, 0x2444, 0x3CFE, 0x3C3E, 0x3C41, + 0x3DFF, 0x3D2C, 0x3D4E, 0x3EC1, 0x3EDC, 0x3E4F, 0x3F2C, 0x31CE, 0x31C0, + 0x31E0, 0x314E, 0x32FE, 0x322F, 0x33C2, 0x332E, 0x3333, 0x34CF, 0x34DC, + 0x34FE, 0x4C0E, 0x4E2E, 0x4E3D, 0x4FDE, 0x40D1, 0x42C0, 0xCC11, 0x422E, + 0x443F, 0xCDDE, 0xCE40, 0xC3EF, 0xDC30, 0xDE0F, 0xD4EF, 0xECEE, 0xEECE, + 0xEFC1, 0xE1CF, 0xE1F4, 0xE3CF, 0xE343, 0xFC4F, 0xFDC0, 0xFD24, 0xF0E3, + 0xF1D1, 0xF3C2, 0xF342, 0xF4D2, 0x0C02, 0x0DF0, 0x0D01, 0x0D2F, 0x0E44, + 0x0F32, 0x00DD, 0x01ED, 0x02CC, 0x03C1, 0x1CFE, 0x1C3E, 0x1DC4, 0x1DD1, + 0x1D4E, 0x13C2, 0x14D2, 0x1441, 0x2DF0, 0x2DF4, 0x2D34, 0x2E2E, 0x2FF2, + 0x2020, 0x212F, 0x2332, 0x24EE, 0x3E01, 0x3FC0, 0x31EE, 0x311F, 0x4C11, + 0x4EE2, 0x41D0, 0x41FE, 0xCCF1, 0xDCEF, 0xDC4F, 0xDFFF, 0xEE20, 0xEF4F, + 0xE020, 0xE12F, 0xFEF4, 0xF1F3, 0xF2F2, 0xF4CF, 0xF441, 0x0DCF, 0x0ECE, + 0x0E0C, 0x02E2, 0x03DC, 0x12DC, 0x142F, 0x2E11, 0x2FEF, 0x22F1, 0x24DF, + 0x2431, 0x3EF0, 0x3001, 0x32F0, 0x4DEF, 0x4FE1, 0xC10F, 0xDC0F, 0xF0FE, + 0xDC2F, 0x0F03, 0x01D4, 0x0CE0, 0x0103, + /* Codebook 8 - 3281 entries */ + 0x0E24, 0x0E3D, 0x0FDC, 0x0FFC, 0x0F3E, 0x0134, 0x02CC, 0x024C, 0x03D0, + 0x030F, 0x04CE, 0x04F3, 0x1C41, 0x1D1D, 0x1D20, 0x1D33, 0x1E03, 0x10D0, + 0x10D2, 0x102D, 0x103E, 0x1030, 0x11D3, 0x12D0, 0x13F3, 0x134E, 0x144D, + 0x2DDC, 0x2DE3, 0x2DFC, 0x2D2D, 0x2D23, 0x2D32, 0x2EC0, 0x2E31, 0x21E3, + 0x223D, 0x23D0, 0x2323, 0x2330, 0x24FD, 0x3DC0, 0x3EC3, 0x3EE3, 0x3FDD, + 0x30C1, 0x30DE, 0x31CC, 0x3102, 0x324D, 0x331D, 0x333F, 0x334E, 0x34CF, + 0x4CE0, 0x4C11, 0x4C20, 0x4C3F, 0x4F23, 0x422C, 0xCCE2, 0x423F, 0x4233, + 0xCE1D, 0xCF30, 0xC1E3, 0xC3EF, 0xDCE3, 0xDC23, 0xDEF4, 0xDE10, 0xDF0E, + 0xDF02, 0xD2F2, 0xD212, 0xD4EF, 0xECCC, 0xED12, 0xED41, 0xEF34, 0xE0CE, + 0xE0E0, 0xE1CD, 0xE3F0, 0xE33C, 0xFFD3, 0xF1F3, 0xF2ED, 0xF23C, 0xF243, + 0xF30E, 0x0DEF, 0x0FDE, 0x00EC, 0x1D22, 0x1E3E, 0x1F31, 0x10CD, 0x100D, + 0x122D, 0x13EC, 0x13E4, 0x2CD3, 0x2DFE, 0x2F03, 0x20DF, 0x20F3, 0x2004, + 0x21D2, 0x214D, 0x23DC, 0x23FE, 0x23F0, 0x23F2, 0x2312, 0x2444, 0x32ED, + 0x331F, 0x332E, 0x3412, 0x3423, 0x4D1E, 0x4FED, 0xC222, 0x442E, 0x443F, + 0xEF14, 0xF11D, 0x0C3F, 0x020E, 0x0200, 0x2FC1, 0x20E0, 0x20E2, 0x232F, + 0x32FE, 0x4E22, 0x422E, 0x0F21, 0x1C21, 0x1EC1, 0x2EF1, 0x2F41, 0x2011, + 0x4002, 0x4121, 0xFF0E, 0x0E1F, 0x0042, 0x1E0F, 0x1F20, 0xFC0F, 0x1120, + 0x2C2E, 0xFF11, 0x41F2, 0xECCE, 0xECE2, 0xEDF2, 0xEE20, 0xEF41, 0xFD42, + 0x0C2E, 0x0E2E, 0x1F1D, 0x1113, 0x2E0E, 0x2E02, 0x2E20, 0x2422, 0xC1F2, + 0xE1F2, 0xF0EF, 0xF2F0, 0xF201, 0x0FE1, 0x2F0F, 0x2F1E, 0xFFE4, 0x0CF1, + 0x0C20, 0x0F2F, 0xF11F, 0x1EF2, 0x11E2, 0x21EF, 0x212F, 0x11FF, 0xCCCE, + 0x4422, 0xCCFF, 0xC022, 0xC10D, 0xC213, 0xDDE0, 0xDDE2, 0xDE21, 0xDFCE, + 0xDF13, 0xDF24, 0xD012, 0xD1EC, 0xD12E, 0xD2EF, 0xD210, 0xD221, 0xD243, + 0xED0F, 0xEECC, 0xEEDF, 0xEF03, 0xE1DE, 0xE12D, 0xE2DF, 0xE23D, 0xE3F2, + 0xE34F, 0xE41D, 0xFCC1, 0xFC41, 0xFFD1, 0xF0E3, 0xF03E, 0xF23E, 0xF33F, + 0x0D1C, 0x0ECC, 0x0E13, 0x0FE3, 0x0013, 0x003F, 0x1DE0, 0x1E32, 0x10C3, + 0x1144, 0x1223, 0x1423, 0x2C1D, 0x2D1E, 0x2D12, 0x2D3E, 0x2FCD, 0x201D, + 0x3CF2, 0x3E01, 0x3F20, 0x3122, 0x3243, 0x330E, 0x3430, 0x4F30, 0x401D, + 0x42DD, 0xCF32, 0xC202, 0xDDCC, 0xDF11, 0xEEC0, 0xE0E2, 0xE2EE, 0xE20E, + 0x0143, 0x30FC, 0x4E02, 0x43FE, 0xCF21, 0xC12F, 0xC2E0, 0xEE1F, 0xEFEF, + 0xEFF2, 0xE0F1, 0xE2FF, 0xE41F, 0xFEE1, 0x0C11, 0x012F, 0x11EE, 0x110C, + 0x1FF1, 0x0110, 0x2121, 0x24E0, 0xFE0F, 0x00CE, 0x02FF, 0x0211, 0x210F, + 0x112E, 0x2E1F, 0xF2CF, 0x2E11, 0xC0EE, 0xDC0F, 0x01F0, 0xDE23, 0xD1FF, + 0xEFF4, 0xE020, 0xE024, 0xE1CF, 0xE141, 0xE2E0, 0xF032, 0xF4DE, 0x02E0, + 0x1131, 0x131F, 0x1342, 0x2EEE, 0x2E22, 0x2E24, 0x2002, 0x202C, 0x2022, + 0x2042, 0x2242, 0x2332, 0x3221, 0xF0E1, 0x4EE0, 0x42EE, 0xF1E0, 0xF2F2, + 0x1E1C, 0x1201, 0xF012, 0x00FF, 0xF02F, 0x0F1E, 0x12FE, 0x1212, 0x4E00, + 0x0F01, 0x2EE2, 0x2F14, 0x011C, 0xCC02, 0xCC13, 0xCC22, 0xCC31, 0xCDCD, + 0xCDDC, 0xCDD2, 0xCE3D, 0xCE42, 0xCF03, 0xC0F3, 0xC2C2, 0xC2D3, 0xC2FD, + 0xC303, 0xDC03, 0xDC41, 0xDD22, 0xDD4E, 0xDECF, 0xDED4, 0xDE0D, 0xDE3C, + 0xDFD1, 0xDF04, 0xDF3F, 0xDF33, 0xDF40, 0xD0CF, 0xD0D2, 0xD0F4, 0xD032, + 0xD1DF, 0xD214, 0xD223, 0xD3C4, 0xD3D3, 0xD3E0, 0xD3F1, 0xD3F3, 0xD324, + 0xD403, 0xED3E, 0xEFD0, 0xE03D, 0xE332, 0xE4CE, 0xE4C0, 0xFC0D, 0xFDC2, + 0xFF3D, 0xF1DD, 0xF14C, 0xF3D1, 0xF3FD, 0xF3F3, 0x0CC0, 0x0CE0, 0x0C42, + 0x0DED, 0x0D3E, 0x0E3F, 0x003D, 0x014D, 0x02EC, 0x03FC, 0x030D, 0x0334, + 0x04E4, 0x04FD, 0x041D, 0x0440, 0x1CCD, 0x1CD4, 0x1CF4, 0x1C1C, 0x1DD3, + 0x1D00, 0x1003, 0x113D, 0x1142, 0x13D1, 0x13D3, 0x1300, 0x14FC, 0x1414, + 0x143C, 0x143E, 0x2C2C, 0x2DDE, 0x2DEF, 0x2E1D, 0x2E44, 0x2F43, 0x203F, + 0x22CC, 0x3DDF, 0x3DF3, 0x3D04, 0x3D3D, 0x3D3F, 0x3D33, 0x3EF4, 0x3E03, + 0x3FC4, 0x3FF3, 0x3F2C, 0x301E, 0x31D1, 0x32D2, 0x32F4, 0x33CC, 0x33DF, + 0x33EC, 0x33E2, 0x34E3, 0x4CEE, 0x4CE2, 0x4C2E, 0x4D23, 0x4D4F, 0x4ECE, + 0x4E2C, 0x4E24, 0x4FFC, 0x4F41, 0x42C2, 0x4224, 0x43DC, 0x43FC, 0x4330, + 0x4343, 0xCD12, 0xCED1, 0xCEF3, 0xCFD0, 0xCFED, 0xCFE3, 0xC1D0, 0xC2F3, + 0xC312, 0xDCCF, 0xDD13, 0xDE3E, 0xDFEC, 0xDFEE, 0xD0F0, 0xD1E4, 0xD201, + 0xD31F, 0xD4D0, 0xD40F, 0xED43, 0xEEF3, 0xEE31, 0xEFC3, 0xEFD4, 0xE0C0, + 0xE0C2, 0xE0F3, 0xE031, 0xE033, 0xE04E, 0xE130, 0xE2EC, 0xE3FE, 0xE312, + 0xE321, 0xE4C2, 0xFCF4, 0xFC32, 0xFDCC, 0xFD20, 0xFE43, 0xFFDD, 0xF0D2, + 0xF13F, 0xF2D0, 0xF3E2, 0xF423, 0x0D2D, 0x0E1D, 0x00D1, 0x02D1, 0x02F3, + 0x03FE, 0x1DEE, 0x1D02, 0x1D11, 0x1D2C, 0x1EC3, 0x1E0D, 0x120D, 0x13E0, + 0x131D, 0x1344, 0x1443, 0x2CCE, 0x2DCD, 0x2DF0, 0x2ED3, 0x2F3C, 0x21DC, + 0x23F4, 0x3EC1, 0x3E3C, 0x31CE, 0x31DF, 0x31EC, 0x31E0, 0x31E4, 0x312E, + 0x32CF, 0x32F2, 0x3223, 0x3232, 0x3234, 0x4EDF, 0xDDCE, 0x4E33, 0x4F0D, + 0xDE12, 0xD42F, 0xECDF, 0xECD1, 0xEC31, 0xEDDC, 0xEE24, 0xEE42, 0xEFCD, + 0xEF23, 0xE0EE, 0xE132, 0xF113, 0xF432, 0x0CE2, 0x0ECE, 0x0FCD, 0x0224, + 0x03C1, 0x1FF3, 0x1F13, 0x10D4, 0x12E3, 0x13F1, 0x2CD1, 0x2C4E, 0x2EE4, + 0x2FDE, 0x20CE, 0x20C2, 0x200E, 0x224E, 0x31EE, 0x3210, 0xC121, 0x341E, + 0x402E, 0xE4E2, 0x01E1, 0x1E2F, 0x142F, 0xCE1F, 0x2F12, 0x4222, 0xC01F, + 0x4112, 0x4F12, 0xEEE0, 0xEF1E, 0xE112, 0xFEDC, 0xFE2F, 0xF2F4, 0xF412, + 0x112C, 0x1C10, 0x121E, 0x4FE1, 0xFFF1, 0x1124, 0x2222, 0xCCCC, 0x41E3, + 0x443D, 0xCCC0, 0xCCC2, 0xCDFE, 0xC020, 0xDEDC, 0xD2E1, 0xD4D2, 0xECEE, + 0xEE13, 0xEE2E, 0xE00E, 0xE13C, 0xE3C1, 0xE42E, 0xFFF3, 0xFF3F, 0xF2D4, + 0xF3C0, 0x0E02, 0x002E, 0x0204, 0x04D1, 0x1CDE, 0x1DC0, 0x1DF1, 0x1ECD, + 0x1ED2, 0x12C3, 0x2C0E, 0x2EEC, 0x2134, 0x22E0, 0x22FD, 0x3F1F, 0x4D0F, + 0x430F, 0xD401, 0xEFC1, 0xE022, 0xE4E0, 0xF140, 0xF22F, 0xF24F, 0x1FC0, + 0x241F, 0x41EF, 0x1C2F, 0x4D10, 0x0011, 0xC1E1, 0x42E0, 0xDC10, 0xFF00, + 0xE4FF, 0xFC01, 0xFFCE, 0x0141, 0x0240, 0x1EFC, 0x1FCE, 0x211E, 0xF0C1, + 0xF100, 0xF111, 0x1FFF, 0x0F12, 0x24FF, 0xCCF1, 0xCEFD, 0xC01D, 0xC123, + 0x10FE, 0x1012, 0x11F1, 0xC132, 0xC2DF, 0xC3D2, 0xC33E, 0xDCDC, 0xDD11, + 0xDEC1, 0xDE2F, 0xDF2C, 0xDF42, 0xD0EF, 0xD1EE, 0xD122, 0xD131, 0xD24D, + 0xEC1D, 0xEDC1, 0xED23, 0xED3C, 0xEEFD, 0xE00C, 0xE1DC, 0xE1ED, 0xE204, + 0xE3D2, 0xE31E, 0xE32F, 0xE334, 0xFC23, 0xFC4F, 0xFDE0, 0xFDF3, 0xFD2E, + 0xFD24, 0xFEC3, 0xFED0, 0xFE03, 0xF00D, 0xF02D, 0xF24D, 0xF311, 0xF4C1, + 0xF42D, 0x0DCD, 0x0DE1, 0x0D10, 0x0D4D, 0x0FD0, 0x0F23, 0x00DF, 0x00FD, + 0x00F3, 0x01DE, 0x01E3, 0x022C, 0x031C, 0x031E, 0x0310, 0x1CED, 0x1DC2, + 0x1DEC, 0x1DE4, 0x1D04, 0x1D3F, 0x13C2, 0x130E, 0x132C, 0x1331, 0x1340, + 0x14C1, 0x14ED, 0x2C13, 0x2C3D, 0x2C33, 0x2D1C, 0x2D2F, 0x2EFD, 0x20DD, + 0x2040, 0x213C, 0x22DD, 0x2231, 0x2244, 0x23ED, 0x23EF, 0x2314, 0x234D, + 0x240E, 0x2413, 0x3C4D, 0x3DF1, 0x3ECD, 0x3E4F, 0x3E43, 0x30F2, 0x3021, + 0x31E2, 0x3140, 0x33E0, 0x4C22, 0x4D30, 0x4E1D, 0x4F32, 0x40DF, 0x40FD, + 0x4130, 0x42DF, 0x42FD, 0xCE22, 0xDC21, 0xDEF0, 0xEDDE, 0xEDE1, 0xE402, + 0xFEDE, 0xFE14, 0xF133, 0x0D4F, 0x0233, 0x0431, 0x1034, 0x14D2, 0x2EE0, + 0x20EC, 0x22EC, 0x234F, 0x3CFE, 0x3C1E, 0x31FF, 0x321E, 0xCF2F, 0x34F2, + 0x4312, 0xFE1C, 0xF2E1, 0x0E42, 0x0FCF, 0x02CE, 0x1E21, 0x1FE4, 0x2C11, + 0xEEEE, 0x214F, 0x2343, 0xEF10, 0xE4F1, 0x0FF4, 0x1E41, 0x4E1F, 0x1F1F, + 0xEF2F, 0x4444, 0x4323, 0xCC1D, 0xCC4C, 0xCC42, 0xCDD4, 0xE21F, 0xE211, + 0xFE41, 0xFF2E, 0xF21C, 0x1E12, 0xEF01, 0x1FE2, 0x12EF, 0x01FC, 0x1F42, + 0xF1F1, 0x14E1, 0x21FE, 0x2C20, 0xC0E2, 0xC22E, 0xC21F, 0xFFEE, 0x4011, + 0xCE00, 0x1FEC, 0xDE4F, 0xEE0E, 0xEFDC, 0xE0E4, 0xF1FF, 0xE200, 0xE224, + 0xE23F, 0xE4DF, 0xFD02, 0xFE3C, 0xF3FF, 0x0CDF, 0x0123, 0x02E2, 0x043F, + 0x1C30, 0x1DCE, 0x1EDE, 0x1E2D, 0x1FFD, 0x2ED1, 0x2E13, 0x2E42, 0x2FE3, + 0x2143, 0x2233, 0x2321, 0x3ECF, 0x3F11, 0x322F, 0x3322, 0x3344, 0xEC11, + 0x4013, 0x43E1, 0xEF1C, 0xE11C, 0xE4D1, 0xFF04, 0xFF42, 0x00E0, 0x1E14, + 0x11CE, 0xC211, 0x2EFF, 0x21CF, 0x0411, 0x2C1F, 0xFEC1, 0xF2C1, 0x1FE0, + 0x4FF2, 0xE1E1, 0xFC1E, 0xFEFE, 0xFFE2, 0x02C0, 0x1C12, 0x1E1E, 0x1234, + 0x14FE, 0x2114, 0x2334, 0x3CEF, 0x4200, 0x0F10, 0x3C10, 0x432F, 0x2FF0, + 0xC3F0, 0x0FEF, 0x0F41, 0xC0FF, 0xC0F1, 0x11E4, 0x4F21, 0xFF1F, 0xCD4D, + 0xCD43, 0xCECE, 0xCEC2, 0xCEEC, 0xCEE4, 0xCF4D, 0xC0C2, 0xC0D3, 0xC1C3, + 0xC143, 0xC2CE, 0xC2DD, 0xC2E4, 0xC24C, 0xC3CF, 0xC3DC, 0xC3D4, 0xC310, + 0xC334, 0xC4C2, 0xC4DD, 0xC41D, 0xC41F, 0xC431, 0xC44C, 0xDCC1, 0xDCC3, + 0xDC14, 0xDDD1, 0xDFC4, 0xD0CD, 0xD0DE, 0xD0FC, 0xD234, 0xD302, 0xD31D, + 0xD313, 0xD344, 0xD443, 0xEE4C, 0xE0C4, 0xE3DE, 0xE3F4, 0xE30D, 0xE4DD, + 0xE44C, 0xFCD4, 0xFC1C, 0xFC14, 0xFC34, 0xFD33, 0xF144, 0xF2CD, 0xF4FC, + 0x0CC4, 0x0CDD, 0x0CFD, 0x0C24, 0x0C4C, 0x00E4, 0x0044, 0x020C, 0x03F4, + 0x0303, 0x0323, 0x044E, 0x1CDC, 0x1D0E, 0x1D44, 0x134C, 0x14D4, 0x2CC4, + 0x2D34, 0x20CC, 0x2033, 0x24C2, 0x24C4, 0x240C, 0x3CC3, 0x3C1C, 0x3C34, + 0x3DC2, 0x3DDD, 0x3DD3, 0x3D0E, 0x3E32, 0x3E34, 0x3F33, 0x3F40, 0x30D0, + 0x303E, 0x31D3, 0x313D, 0x3203, 0x321C, 0x34DC, 0x34FC, 0x340D, 0x341C, + 0x4CCE, 0x4CC4, 0x4CF3, 0x4C2C, 0x4D3C, 0x4D4D, 0x4D43, 0x4E0C, 0x4E04, + 0x4E4E, 0x40CC, 0x40C0, 0x41CD, 0x414D, 0x4204, 0x43CF, 0x43C3, 0x4303, + 0x4334, 0x44CE, 0xCC2E, 0x44DD, 0x44D3, 0xCDCF, 0xCDD0, 0xCE44, 0xCFDC, + 0xC134, 0xC22C, 0xC23D, 0xC23F, 0xC24E, 0xC3DE, 0xC30D, 0xC323, 0xC332, + 0xC341, 0xC4C4, 0xC4D3, 0xDD33, 0xDD40, 0xDEE3, 0xDEFC, 0xDE03, 0xDFDF, + 0xDFFD, 0xDFF3, 0xDF1D, 0xDF44, 0xD0F2, 0xD02D, 0xD03C, 0xD03E, 0xD034, + 0xD04F, 0xD043, 0xD1CE, 0xD1DD, 0xD1D1, 0xD1FD, 0xD102, 0xD104, 0xD133, + 0xD144, 0xD2DC, 0xD2D0, 0xD20D, 0xD320, 0xD33F, 0xD4DE, 0xD4ED, 0xD4FC, + 0xD41C, 0xD423, 0xECE4, 0xEC42, 0xEEC4, 0xEED3, 0xE0DF, 0xE0D3, 0xE044, + 0xE240, 0xE330, 0xE4C4, 0xFC43, 0xFDFD, 0xF3CE, 0xF3DD, 0xF3D3, 0xF304, + 0xF33D, 0xF333, 0xF4ED, 0xF40D, 0xF403, 0x0CC2, 0x0C33, 0x0DC1, 0x0DDC, + 0x0DFC, 0x0D32, 0x01D2, 0x012D, 0x02D3, 0x02FD, 0x03CF, 0x03DE, 0x03E3, + 0x0314, 0x032D, 0x0332, 0x1DDF, 0x133F, 0x140D, 0x1434, 0x2CDD, 0x2CEC, + 0x2CE4, 0x2C24, 0x2DD0, 0x2D03, 0x2D3C, 0x2F30, 0x22C4, 0x23D2, 0x24D3, + 0x3CDE, 0x3CED, 0x3C14, 0x3C41, 0x3DD1, 0x3DEC, 0x3DE2, 0x3DE4, 0x3D0C, + 0x3D4C, 0x3E0D, 0x3E23, 0x3FE4, 0x3F13, 0x3F3F, 0x3F31, 0x30C3, 0x301C, + 0x3043, 0x3113, 0x313F, 0x3133, 0x322D, 0x33CE, 0x33D3, 0x333D, 0x343E, + 0x3434, 0x3441, 0x4C02, 0x4C13, 0x4C3D, 0x4C31, 0x4DD0, 0x4DD4, 0x4EEC, + 0x4FCD, 0x4033, 0x41C1, 0x41DC, 0x41FC, 0x4242, 0x43CD, 0x43D0, 0x44DF, + 0x44EC, 0x44FD, 0xCF23, 0xC1ED, 0xC130, 0xC14F, 0xC21D, 0xC32D, 0xC420, + 0xDCD0, 0xDC2D, 0xDEDE, 0xDE2D, 0xDF4E, 0xD0E1, 0xD021, 0xD11D, 0xD3FF, + 0xD342, 0xD4C3, 0xD412, 0xD44F, 0xEC24, 0xED10, 0xED21, 0xEED1, 0xEF0D, + 0xEF2D, 0xEF4D, 0xE042, 0xE1D2, 0xE2D3, 0xE3CF, 0xE3EF, 0xE343, 0xE4FD, + 0xE413, 0xFCED, 0xFC03, 0xFD00, 0xFD31, 0xFED2, 0xFE0D, 0xFE23, 0xF0D0, + 0xF203, 0xF230, 0xF3EC, 0xF3E4, 0xF300, 0xF320, 0xF344, 0x0DCF, 0x0DE3, + 0x0EFD, 0x0E31, 0x0F03, 0x0F30, 0x01D0, 0x03E1, 0x03F2, 0x0321, 0x1CC1, + 0x1C4F, 0x1DE2, 0x1DFF, 0x1DF3, 0x1D24, 0x1FCC, 0x1FD1, 0x1F3D, 0x1230, + 0x13DF, 0x130C, 0x1313, 0x1403, 0x144F, 0x2CC2, 0x2ECC, 0x2EDD, 0x2E3D, + 0x2FC3, 0x2FD0, 0x2FD4, 0x20D1, 0x20FD, 0x2031, 0x21DE, 0x21D4, 0x2204, + 0x223F, 0x23E3, 0x232D, 0x24DD, 0x24F3, 0x3CD2, 0x3C12, 0x3C21, 0x3D11, + 0x3EDC, 0x3EFE, 0x3E1E, 0x3E4D, 0x3FCE, 0x3FC2, 0x3F0E, 0x3F2E, 0x3F4E, + 0x30CF, 0x30E1, 0x30F4, 0x310E, 0x3100, 0x3124, 0x314E, 0x32D4, 0x324F, + 0x3241, 0x33FF, 0x3311, 0x3320, 0x4DF0, 0x4D2D, 0x4D32, 0x4FD0, 0x4FE3, + 0x403F, 0x41DE, 0xCCDD, 0xCD23, 0xC002, 0xC31E, 0xDCFE, 0xDCF2, 0xDC01, + 0xDF22, 0xD2CF, 0xD21E, 0xD4F2, 0xEDCF, 0xED14, 0xE1C3, 0xE2C0, 0xE20C, + 0xE244, 0xE4D3, 0xE422, 0xFCDE, 0xFED4, 0xFEED, 0xF023, 0xF03C, 0xF1C4, + 0xF3EE, 0x0C02, 0x02EE, 0x0244, 0x1C2D, 0x1E34, 0x10DC, 0x10E3, 0x12CD, + 0x13C0, 0x1311, 0x2DF2, 0x2D41, 0x2024, 0x22E4, 0x2202, 0x221D, 0x231E, + 0x3EF2, 0x31F1, 0x3214, 0x3333, 0x34EF, 0x4E3F, 0x40E0, 0x42D1, 0x43EF, + 0xEFCF, 0xE1FC, 0xFE1E, 0xF4F2, 0x0000, 0x1EDC, 0x1F04, 0x1412, 0x2F1C, + 0x21F4, 0x3C0F, 0x431E, 0xECFF, 0xFFC2, 0xF01C, 0x1FEE, 0x120F, 0x124F, + 0xC200, 0x1401, 0x20FF, 0x010F, 0xEC20, 0xF120, 0xC101, 0x114E, 0x221F, + 0x001F, 0x111F, 0x4FF0, 0xCDDE, 0x4431, 0x4213, 0x44F3, 0x4400, 0xCCC4, + 0xCCEC, 0xCEEE, 0xCF1E, 0xC0E0, 0xDCDE, 0xE2C2, 0xFF4E, 0xF20F, 0xF4FE, + 0x0F34, 0x1CFE, 0x1E4D, 0x12FC, 0x201F, 0x342F, 0xE420, 0xF0FE, 0x4E11, + 0x0E11, 0x1104, 0x4000, 0x21F0, 0x4E0E, 0xCCDF, 0xCD21, 0xEEF1, 0xFFEC, + 0x01FE, 0x2CE0, 0x20F1, 0x2110, 0xCFF0, 0xC02E, 0xC3FE, 0xC4F1, 0xDC12, + 0xDF20, 0xEC0E, 0xEDEF, 0xE21D, 0xE43F, 0xFDE2, 0xFD11, 0xFF31, 0xF0D4, + 0xF342, 0x0E0C, 0x0E22, 0x1C32, 0x1F3F, 0x12DC, 0x13CE, 0x132E, 0x2C31, + 0x2EDF, 0x2FED, 0x20E4, 0x21C3, 0x2123, 0x22CE, 0x23E1, 0x23FC, 0x241D, + 0x243F, 0x3EE1, 0x3E0F, 0x3FFF, 0x32E1, 0xCE02, 0x32F0, 0x4D3E, 0xC301, + 0xEDCD, 0xE2E2, 0xFECD, 0xFEFC, 0xF2EF, 0xF41E, 0x00EE, 0x022E, 0x041F, + 0x0420, 0x1CF2, 0x2E40, 0x2FFE, 0x2F2F, 0x2F4F, 0x21C1, 0x2200, 0x24E2, + 0x2420, 0xC10F, 0xF0CF, 0x3401, 0x4D2F, 0xF42F, 0x0FC1, 0x01CF, 0x4020, + 0x4442, 0xCCE0, 0xCC0E, 0xFF2C, 0xF0F2, 0xF01E, 0xF1C2, 0x0112, 0x1F0C, + 0x1F11, 0x10E1, 0x110E, 0x1100, 0x4F1E, 0x4F01, 0xC11E, 0xC220, 0xDCCD, + 0xEFFC, 0xF241, 0x0EE2, 0x0E2C, 0x024E, 0x121C, 0x2CEE, 0x2E2C, 0x2FCF, + 0xFCEF, 0x0FFE, 0x014F, 0x1F4E, 0x10F4, 0x1221, 0x1F00, 0x40F1, 0xFC21, + 0x24D1, 0xCDED, 0xCDE3, 0xCE33, 0xC0DF, 0x0F14, 0xC03D, 0xC3D0, 0xC330, + 0xC34F, 0xDDC2, 0xDD02, 0xDD24, 0xDE0F, 0xFC2F, 0x4101, 0xDFDD, 0xDFE4, + 0xDF00, 0xD00F, 0xD041, 0xD10C, 0xD10E, 0xD113, 0xD22F, 0xD3E4, 0xD32C, + 0xD322, 0xD43E, 0xECC0, 0xEDD4, 0xEDED, 0xEDFC, 0xED01, 0xE0FD, 0xE01D, + 0xE2DD, 0xE2F3, 0xE30F, 0xE43D, 0xE442, 0xFCE3, 0xFD0C, 0xFD0E, 0xFD1D, + 0xFE34, 0xFF33, 0xFF4C, 0xF3C4, 0xF322, 0xF44F, 0x0DDE, 0x0DFE, 0x0D1E, + 0x0D12, 0x0D14, 0x0EDF, 0x0E44, 0x002C, 0x010D, 0x021D, 0x03C3, 0x0413, + 0x1D0C, 0x1032, 0x1041, 0x1333, 0x142D, 0x2DCF, 0x2E3F, 0x2F0D, 0x2F32, + 0x21D0, 0x213E, 0x2130, 0x22DF, 0x230D, 0x2301, 0x233E, 0x242C, 0x3CD0, + 0x3C32, 0x3C4F, 0x3DCE, 0x3D1F, 0x3D20, 0x3D24, 0x3EDE, 0x3EFC, 0x3FDF, + 0x3FEC, 0x3FE0, 0x3F42, 0x30D2, 0x30FE, 0x3012, 0x302F, 0x304F, 0x3041, + 0x310C, 0x3131, 0x32DC, 0x32DE, 0x3201, 0x3230, 0x33EE, 0x3331, 0x342D, + 0x4CD1, 0x4C1F, 0x4DED, 0x4EDD, 0x4ED3, 0x4F03, 0x40EC, 0x40E2, 0x412D, + 0x4123, 0x42D3, 0x42F3, 0xCE13, 0xC1D2, 0xC231, 0xDEFE, 0xD2FE, 0xD24F, + 0xECF3, 0xEEE4, 0xEE2C, 0xEF3E, 0xE123, 0xE202, 0xE3E1, 0xFDFF, 0xFDF1, + 0xFE4D, 0xF0ED, 0xF1FD, 0xF22D, 0xF34E, 0x032F, 0x0341, 0x0402, 0x1EED, + 0x11DF, 0x111D, 0x13FF, 0x14DE, 0x1430, 0x1432, 0x2D14, 0x2E0C, 0x2E00, + 0x2E04, 0x2FDC, 0x2F4D, 0x212D, 0x24DF, 0x3FEE, 0x34FE, 0xCF12, 0x4DE1, + 0x4E31, 0xECE0, 0xEC2E, 0xE2CE, 0xFEF4, 0xF10C, 0x0022, 0x1C1E, 0x12E1, + 0x12F4, 0x1241, 0x2224, 0x242E, 0xEEFF, 0x4D01, 0x41FE, 0xF0FC, 0x011E, + 0x1410, 0x2211, 0xCF0F, 0x2400, 0x2411, 0xFFFF, 0xC2F1, 0xEC00, 0x01F2, + 0xF00F, 0x021F, 0x12F0, 0x0FF0, 0xCDEF, 0x4231, 0x44E2, 0xCCFD, 0xCC33, + 0xCEE0, 0xCEE2, 0xCE20, 0xEE02, 0xE2E4, 0xF041, 0xF212, 0x0F4D, 0x1EF4, + 0x1FC2, 0x141E, 0x2ECE, 0x22EE, 0x3CF0, 0xC1EF, 0x3C2F, 0x4321, 0xFE01, + 0xFF0C, 0x0F4F, 0x1F02, 0xC2FF, 0x2101, 0xE01F, 0x00F1, 0xF122, 0x0CFF, + 0x1F0E, 0x10EF, 0x10FC, 0x1102, 0x1122, 0x2F01, 0x412F, 0xCD1E, 0xCFDE, + 0xC00E, 0xC3F2, 0xF010, 0xDCD2, 0xDC1E, 0xDEEF, 0xDE01, 0xDE14, 0xDE34, + 0xD1E2, 0xD4FE, 0xECDD, 0xEC22, 0xEE0C, 0xEFED, 0xEF3C, 0xEF32, 0xE002, + 0xE1D4, 0xE1E3, 0xE143, 0xE231, 0xE4F3, 0xFDC0, 0xFD1F, 0xFF1D, 0xF003, + 0xF034, 0xF1DF, 0xF31F, 0x0EEC, 0x0E0E, 0x0202, 0x1CD2, 0x1D1F, 0x1EE3, + 0x1E43, 0x1FDD, 0x1023, 0x12D2, 0x1320, 0x22F3, 0x2402, 0x3CE1, 0x3EEF, + 0x3E41, 0x32EF, 0x320F, 0x4D12, 0x4ED1, 0x4EF3, 0xCDF2, 0x4FD2, 0x40F3, + 0xCD0F, 0xDCEF, 0xDC2F, 0xD410, 0xFECF, 0xFE21, 0xF04F, 0xF14E, 0x0020, + 0x01C3, 0x0242, 0x042E, 0x1E3C, 0x1F22, 0xEF12, 0x1043, 0x2C3F, 0xFF02, + 0xF0F4, 0xF1CE, 0xF102, 0x1001, 0xF124, 0x04FF, 0xE12F, 0x20EE, 0x43ED, + 0xCC4E, 0xCDFC, 0xCDF0, 0xCD0D, 0x1EF0, 0x1021, 0xE411, 0x2CF1, 0x4EF1, + 0x4F2F, 0xC112, 0xC3E1, 0xEE00, 0xEFE1, 0xE1EF, 0xE431, 0xF12E, 0x02C2, + 0x1EFE, 0x1232, 0x21F2, 0x2240, 0xCE11, 0x2431, 0x3421, 0xCFE1, 0xCFFE, + 0xF021, 0xF210, 0x2C00, 0x2FE1, 0xCF10, 0xF0F0, 0xCEF1, 0x400E, 0x3432, + 0xCD3E, 0xCD4F, 0xCED3, 0xCE0C, 0xCE4E, 0xCFFC, 0xCF1C, 0xCF4F, 0xCF01, + 0xFEF0, 0x0400, 0x4110, 0x2112, 0x411E, 0xC13C, 0xC141, 0xC2C0, 0xC204, + 0xC3FC, 0xC4EE, 0xC4FD, 0xC40E, 0xC43F, 0xDCD4, 0xDCF4, 0xDC4D, 0xDDEC, + 0xDD04, 0xDD2C, 0xDD2E, 0xDD42, 0xDED0, 0xDED2, 0xDE1C, 0xDFC2, 0xD0C1, + 0xD0D0, 0xD01C, 0xD014, 0xD030, 0xD1C4, 0xD100, 0xD140, 0xD142, 0xD2E3, + 0xD241, 0xD3FD, 0xD300, 0xD333, 0xD4C1, 0xD40D, 0xED0D, 0xED30, 0xEE44, + 0xE103, 0xE323, 0xE33E, 0xE400, 0xE42C, 0xE424, 0xE433, 0xFCCD, 0xFDD3, + 0xFD3D, 0xFD4C, 0xF043, 0xF30C, 0xF313, 0xF4F4, 0xF44D, 0xF441, 0x0CCC, + 0x0C13, 0x0D0D, 0x0D01, 0x0EC4, 0x0F43, 0x0033, 0x0330, 0x0442, 0x1CCF, + 0x1CC3, 0x1C0F, 0x1C43, 0x1DDD, 0x1F4C, 0x1F44, 0x133D, 0x14C3, 0x140F, + 0x2E33, 0x203D, 0x204C, 0x224C, 0x23DE, 0x233C, 0x244E, 0x3CC1, 0x3D02, + 0x3D13, 0x3D40, 0x3E14, 0x3FFD, 0x3F0C, 0x30CD, 0x30D4, 0x30ED, 0x31C0, + 0x31C4, 0x31FD, 0x311D, 0x32C3, 0x32E3, 0x323C, 0x323E, 0x33E4, 0x3313, + 0x332C, 0x3340, 0x344F, 0x4C4C, 0x4C4E, 0x4DC1, 0x4DDE, 0x4DE3, 0x4EC0, + 0x4E3D, 0x4FCF, 0x4FC3, 0x4F14, 0x40DD, 0x40D3, 0x403D, 0x42C0, 0x43D2, + 0x43E3, 0x431C, 0x4341, 0xCCF3, 0xCC11, 0xCD2D, 0xCD34, 0xCE24, 0xC033, + 0xC1DE, 0xC4D1, 0xC4E0, 0xC4E2, 0xC422, 0xDC3E, 0xDC34, 0xDE32, 0xDFC0, + 0xDFE0, 0xD001, 0xD010, 0xD02F, 0xD1E0, 0xD13F, 0xD2C3, 0xD22D, 0xD23E, + 0xD3CE, 0xD3C2, 0xD3E2, 0xD311, 0xD32E, 0xD34E, 0xD42D, 0xECD3, 0xEDFE, + 0xED4D, 0xEE04, 0xEE1D, 0xEE40, 0xEFD2, 0xEF30, 0xE013, 0xE1D0, 0xE10D, + 0xE2CC, 0xE213, 0xE3CD, 0xE3DC, 0xE301, 0xE310, 0xFCCF, 0xFDD1, 0xFD13, + 0xF030, 0xF20D, 0xF4C3, 0xF4E3, 0x0CD3, 0x0C4E, 0x0D03, 0x0E04, 0x0E4C, + 0x02C4, 0x023F, 0x0231, 0x03D2, 0x03EF, 0x1DD1, 0x1D13, 0x1D4C, 0x1FC4, + 0x13FD, 0x1324, 0x14F4, 0x2CF3, 0x2C40, 0x2DC3, 0x2DD4, 0x2DF4, 0x2D10, + 0x2F23, 0x22D3, 0x231C, 0x243D, 0x3C23, 0x3C30, 0x3D2C, 0x3D22, 0x3D42, + 0x3ED2, 0x3ED4, 0x3E2D, 0x3FC0, 0x3FD3, 0x300F, 0x33C2, 0x33FD, 0x330C, + 0x34C1, 0x4DD2, 0x4EFD, 0x41D0, 0x4103, 0x42EC, 0xCE31, 0x423D, 0x441D, + 0xCFD2, 0xC2D1, 0xC32F, 0xDC32, 0xD11F, 0xED1E, 0xE0EC, 0xE14D, 0xFDE4, + 0xFD22, 0xFE32, 0xF1D1, 0xF32E, 0x0CEE, 0x0D21, 0x0FD2, 0x0F32, 0x001D, + 0x02DF, 0x1CE3, 0x1E30, 0x10ED, 0x12ED, 0x1203, 0x123E, 0x2C02, 0x2EF3, + 0x2F2D, 0x202E, 0x220C, 0x2213, 0x230F, 0x3C3E, 0x3E21, 0x3FE2, 0x3F02, + 0x3324, 0x340F, 0x4EEE, 0x41ED, 0xCDE1, 0x413E, 0x441F, 0xCD01, 0xC20E, + 0xDCE1, 0xEECE, 0xEEC2, 0xE134, 0xE222, 0xE242, 0xFCF2, 0xFC12, 0xF2C3, + 0x0FD4, 0x1214, 0x14D0, 0x2F21, 0x21ED, 0xE10F, 0x4022, 0x420E, 0xFCE1, + 0xF1E4, 0x0F0F, 0x0121, 0x14F0, 0x1E4F, 0x1014, 0xC1F0, 0x1111, 0x410F, + 0x0C1F, 0xCFF2, 0xF014, 0xF4F0, 0x1F40, 0x10F2, 0x11E0, 0x12C1, 0x1210, + 0xF410, 0x41E1, 0xCEDF, 0xC30F, 0xE1F4, 0xFCFE, 0xFD40, 0x013C, 0x1CD0, + 0x1D4E, 0x11F3, 0x14F2, 0xEF0F, 0x2141, 0x220E, 0xE011, 0xE1F0, 0xFCF0, + 0xF1E2, 0xF40F, 0x0FF2, 0x1ECF, 0x2FF2, 0x2F10, 0xEE11, 0x2CFF, 0xEFF0, + 0xE101, 0xE11E, 0xFF22, 0x2FEF, 0x42FF, 0xEC1F, 0xFC10, 0xCCEE, 0xCEDD, + 0xDDDF, 0xDDF1, 0xDECD, 0xDE1E, 0xDFE2, 0xDF2E, 0xD0FE, 0xD01E, 0xD4E3, + 0xEC02, 0xEFDE, 0xE004, 0xE02C, 0xE03F, 0xE31C, 0xFC2D, 0xFE2D, 0xFE3E, + 0xFFC4, 0xF2D2, 0xF3F1, 0x0EDD, 0x0132, 0x0213, 0x040E, 0x0422, 0x1C23, + 0x1ED0, 0x1ED4, 0x11D1, 0x1133, 0x13E2, 0x204E, 0x21CD, 0x2132, 0x222C, + 0x23CF, 0x2310, 0x2433, 0x3CE3, 0x3C01, 0x3EF0, 0x3E1C, 0x3E2F, 0x3F24, + 0x30EF, 0x30F0, 0x3212, 0x4E13, 0x4FDE, 0x4F2D, 0x40EE, 0x41D2, 0x43DE, + 0xEF4F, 0xE14F, 0xE341, 0xE4EE, 0xF0CD, 0xF131, 0xF142, 0x0EEE, 0x0EE4, + 0x0E20, 0x0002, 0x02E4, 0x103C, 0x123C, 0x2C22, 0x20C0, 0x2000, 0x21FC, + 0x24EE, 0x4301, 0xCFEF, 0xEF21, 0xFF24, 0x0040, 0x1421, 0x4332, 0x43F2, + 0xCC20, 0x4413, 0xCCE4, 0xCC0C, 0xCC2C, 0xCC40, 0xECF1, 0xFEF2, 0x4F10, + 0xFFE0, 0xF1C0, 0xF2FE, 0x12CF, 0x24F1, 0x22FF, 0x4E2E, 0x1010, 0x4211, + 0xD421, 0xFC30, 0xFF13, 0xF234, 0xF430, 0x00E2, 0x1FDF, 0x10CF, 0xC000, + 0x124D, 0x1243, 0x2CE2, 0x2D4F, 0x2EC2, 0x2FFC, 0x2220, 0x3111, 0xF221, + 0x34F0, 0x4DEF, 0xF4EF, 0x1EEF, 0x1CEF, 0x0101, 0xC1FE, 0xFEEF, 0xFE4F, + 0xF21E, 0x0EC2, 0x0EF1, 0x1C01, 0x21E1, 0x421F, 0xCD03, 0xCD30, 0xCD41, + 0xCF34, 0xCF43, 0xC03F, 0xC031, 0xC103, 0xC13E, 0xC402, 0xDDFF, 0xDDF3, + 0xDE4D, 0xDF0C, 0xD1F3, 0xD124, 0xD13D, 0xD14E, 0xD2CD, 0xD2DE, 0xD2D2, + 0xD3C0, 0xD3EC, 0xD3EE, 0xD41E, 0xD432, 0xD441, 0xECFD, 0xEC4E, 0xEDD0, + 0xEDD2, 0xED34, 0xE13E, 0xE233, 0xE314, 0xE34D, 0xE44E, 0xFCC3, 0xFCDC, + 0xFDDD, 0xFDEC, 0xFD04, 0xFD3F, 0xFE30, 0xFF44, 0xF13D, 0xF302, 0xF331, + 0x0CF3, 0x0C1D, 0x0C31, 0x0DD0, 0x0DD2, 0x0DD4, 0x0DF0, 0x0D0F, 0x0F0D, + 0x00D3, 0x0031, 0x02DD, 0x03D4, 0x03ED, 0x03F0, 0x0301, 0x0312, 0x04DD, + 0x043D, 0x1C03, 0x1C14, 0x1D31, 0x1FD3, 0x10DE, 0x104D, 0x1302, 0x1304, + 0x14CD, 0x1441, 0x2CFD, 0x2DD2, 0x2D43, 0x2EC4, 0x2FD2, 0x210D, 0x23C3, + 0x24CE, 0x24EC, 0x2424, 0x3C2D, 0x3DFF, 0x3D2E, 0x3ED0, 0x3E3E, 0x30DC, + 0x31DD, 0x3104, 0x33DD, 0x33F1, 0x34DE, 0x34ED, 0x4EE4, 0x4FD4, 0x40D1, + 0x410D, 0x433E, 0xDEE1, 0xDEF2, 0xDFF1, 0xD111, 0xD12C, 0xD2C1, 0xD2FC, + 0xD2F0, 0xD21C, 0xEDF0, 0xEE3F, 0xEE4E, 0xEF43, 0xE2C4, 0xE2FD, 0xE3D4, + 0xFDEE, 0xFD2C, 0xFFDF, 0xF1D3, 0xF2DE, 0xF2E3, 0xF43E, 0x0DF2, 0x0D3C, + 0x0ED1, 0x0F2D, 0x01ED, 0x013E, 0x0343, 0x1D2E, 0x1E23, 0x12DE, 0x1322, + 0x14E3, 0x2C42, 0x2D21, 0x200C, 0x2013, 0x2103, 0x22E2, 0x3D4E, 0x3E10, + 0x3FD1, 0x3001, 0x311F, 0x3142, 0x32FC, 0x3342, 0x4DF2, 0x4F3E, 0x4031, + 0xCE2E, 0x4132, 0x44E0, 0xC2EE, 0xE000, 0xE02E, 0xE220, 0xF214, 0xF232, + 0xF4D0, 0xF4D2, 0x0C22, 0x0D41, 0x0EE0, 0x0E4E, 0x000E, 0x1D40, 0x1D42, + 0x10C1, 0x11FD, 0x2DC1, 0xF1EC, 0x2D4D, 0x2E4E, 0x04E0, 0x1CE1, 0x1F2E, + 0x1F24, 0xF401, 0x40FF, 0xC011, 0x2FF4, 0xCE0E, 0xF1EE, 0xF10E, 0xF4E1, + 0x11EC, 0x22F1, 0xCEFF, 0x04F1, 0x1CF0, 0x41F0, 0xDDEE, 0xDF1F, 0xD1F1, + 0xEEE2, 0xE1C1, 0xE114, 0xE22C, 0xE3C3, 0xFFFD, 0xF3C2, 0x0E00, 0x0FED, + 0x0220, 0x0222, 0x04DF, 0x04EE, 0x2E2E, 0x2020, 0x2442, 0x3FF1, 0xE0FF, + 0x3443, 0x42E2, 0x4F0F, 0xE121, 0xFE10, 0xE110, 0x4220, 0xCF2D, 0xCF3E, + 0xE2F1, 0xFF40, 0xF12C, 0x14EF, 0x100F, 0x4E20, 0xDC30, 0xDE41, 0xD1C2, + 0xD2F4, 0xD20F, 0xEC13, 0xEDC3, 0xEDF4, 0xEEDD, 0xE2D1, 0xE24E, 0xFDDF, + 0xFEE3, 0xFFCC, 0xF0DE, 0xF04D, 0xF223, 0xF3E0, 0x0C0E, 0x0D2F, 0x0EF3, + 0x03CD, 0x1C3E, 0x1DCC, 0x11DD, 0x113F, 0x13EE, 0x14CF, 0x2DE1, 0x2D0F, + 0x2D01, 0x2E4C, 0x2F3E, 0x2F34, 0x22D1, 0x3E12, 0x3F00, 0x3F04, 0x3F22, + 0x3010, 0x31C2, 0x312C, 0x3410, 0x4202, 0xC2E2, 0x43F0, 0x430D, 0xDDDD, + 0xDFFF, 0xED4F, 0xEEEC, 0xE22E, 0xFC3E, 0xFD4E, 0xF0C3, 0x01DC, 0x04E2, + 0x11C2, 0x12D4, 0x12F2, 0x22C0, 0x22C2, 0x222E, 0x4EE2, 0x4433, 0xFFC0, + 0xF2FC, 0x004E, 0x01C1, 0xC110, 0x1EE1, 0xEFFE, 0x1F2C, 0xE1FE, 0xFE12, + 0xF104, 0x101E, 0x11C0, 0x122F, 0xCD2F, 0xDCF0, 0xEE22, 0xF340, 0x211C, + 0x23C1, 0x2341, 0x34E1, 0xD4F0, 0x4DFE, 0x4D21, 0xFF20, 0x0EFF, 0x01EF, + 0x1E10, 0x102F, 0x1140, 0xF001, 0x4FEF, 0x4FFE, 0x4EFF, 0xD4E1, 0x02F1, + 0x10F0, 0x1E01, 0x101C, 0x401F, 0x104F, 0xCDC3, 0xCDF4, 0xCD1C, 0xCEC4, + 0xCE2C, 0xCE3F, 0xCE4C, 0xCE40, 0xCFCD, 0xCFD4, 0xCFF4, 0xCF14, 0xC0CC, + 0xC0C0, 0xC0C4, 0xC0EC, 0xC0E4, 0xC004, 0xC1DC, 0xC1D4, 0xC1FC, 0xC1F4, + 0xC114, 0xC2CC, 0xC2C4, 0xC20C, 0xC224, 0xC244, 0xC3C1, 0xC3C3, 0xC31C, + 0xC34D, 0xC4CC, 0xC4EC, 0xC4FF, 0xC40C, 0xC400, 0xC404, 0xC411, 0xC424, + 0xC433, 0xC440, 0xC442, 0xC444, 0xDCFC, 0xDC0D, 0xDD0C, 0xDD3D, 0xDD4C, + 0xDE43, 0xD0C3, 0xD0ED, 0xD00D, 0xD04D, 0xD1CC, 0xD3CC, 0xD30E, 0xD34C, + 0xD414, 0xD434, 0xECC4, 0xEC04, 0xEC3F, 0xEC4C, 0xE0DD, 0xE040, 0xE4CC, + 0xE4EC, 0xE404, 0xE440, 0xFCD0, 0xFDC4, 0xF1CC, 0xF3CC, 0xF4CD, 0xF4CF, + 0xF4D4, 0xF414, 0xF421, 0x0C0C, 0x0C00, 0x0C40, 0x0D34, 0x0E40, 0x0F3C, + 0x00CC, 0x00C0, 0x00C2, 0x00DD, 0x0004, 0x01CD, 0x0103, 0x03DC, 0x033C, + 0x034D, 0x034F, 0x04C0, 0x04C4, 0x040C, 0x0404, 0x0433, 0x044C, 0x11C4, + 0x114C, 0x13C4, 0x2CC0, 0x2C4C, 0x2DED, 0x2D0D, 0x20C4, 0x2044, 0x24CC, + 0x24C0, 0x244C, 0x2440, 0x3CCD, 0x3CCF, 0x3CDC, 0x3DCC, 0x3DC4, 0x3DE0, + 0x3DFD, 0x3D00, 0x3F3D, 0x3F4C, 0x3F44, 0x30E3, 0x3023, 0x303C, 0x33C0, + 0x33C4, 0x33D1, 0x33F3, 0x3300, 0x4CCC, 0x4CC0, 0x4CC2, 0x4CDD, 0x4CD3, + 0x4C0C, 0x4C00, 0x4C04, 0x4C24, 0x4C40, 0x4C44, 0x4DCD, 0x4DC3, 0x4D14, + 0x4D34, 0x4E4C, 0x4F3C, 0x4F4D, 0x4F43, 0x40C2, 0x40C4, 0x40E4, 0x400C, + 0x402C, 0x404C, 0x404E, 0x4040, 0x4044, 0x41CF, 0x41F4, 0x4114, 0x4141, + 0x4143, 0x42CC, 0x42C4, 0x42E4, 0x43C1, 0x43D4, 0x43F4, 0x4310, 0x4314, + 0x434D, 0x44CC, 0x44C4, 0x44FF, 0x440C, 0x4404, 0x4411, 0x442C, 0x444C, + 0xCCD3, 0x444E, 0x4440, 0xCC00, 0xCC04, 0xCC3D, 0xCD10, 0xCD3C, 0xCFCF, + 0xCFC3, 0xCF3C, 0xC0CE, 0xC0DD, 0xC00C, 0xC013, 0xC02C, 0xC04C, 0xC04E, + 0xC040, 0xC044, 0xC1CD, 0xC1CF, 0xC14D, 0xC233, 0xC240, 0xC3CD, 0xC3F4, + 0xC314, 0xC343, 0xC4CE, 0xC4C0, 0xC4DF, 0xC4E4, 0xC42C, 0xC44E, 0xDC3C, + 0xDC4F, 0xDC43, 0xDDC0, 0xDDC4, 0xDDFD, 0xDD1D, 0xDD31, 0xDD44, 0xDEC3, + 0xDE30, 0xDF3D, 0xD0DC, 0xD0D4, 0xD0E3, 0xD003, 0xD1D3, 0xD203, 0xD340, + 0xD4CD, 0xD4DC, 0xD4F4, 0xEC0C, 0xEC2C, 0xEC40, 0xEC44, 0xE0CC, 0xE04C, + 0xE303, 0xE4E4, 0xE40C, 0xFCFC, 0xF2DC, 0xF324, 0xF34C, 0xF4DC, 0xF434, + 0x0CEC, 0x0CE4, 0x0C04, 0x0C2C, 0x0C3D, 0x0C44, 0x0DC3, 0x0EC0, 0x0E33, + 0x0FC3, 0x0F1C, 0x00C4, 0x000C, 0x004C, 0x01F4, 0x0114, 0x023D, 0x04CC, + 0x04C2, 0x1CFC, 0x1C0D, 0x1C3C, 0x1C34, 0x1DC4, 0x2CCC, 0x2C04, 0x20D3, + 0x24E4, 0x3CFC, 0x3CF4, 0x3C0D, 0x3D44, 0x3F1D, 0x300D, 0x3003, 0x3030, + 0x304D, 0x31F3, 0x314C, 0x3144, 0x3302, 0x3304, 0x34D4, 0x34F4, 0x3403, + 0x344D, 0x4CDF, 0x4CEC, 0x4CFD, 0x4C42, 0x4DCF, 0x4DDC, 0x4DFC, 0x4D0D, + 0x4D03, 0x4D1C, 0x4D41, 0x4ECC, 0x4E42, 0x4E44, 0x4FC1, 0x4FF4, 0x4F1C, + 0x4F34, 0x4F4F, 0x40CE, 0x4004, 0x4024, 0x41C3, 0x4134, 0x414F, 0x420C, + 0x421D, 0x424C, 0x424E, 0x4244, 0x433C, 0x434F, 0x44EE, 0x44E4, 0x44F1, + 0xCC24, 0x4402, 0x4424, 0xCC3F, 0xCC44, 0xCDC1, 0xCD14, 0xCECC, 0xCE04, + 0xCFC1, 0xCF0D, 0xC0D1, 0xC0FD, 0xC024, 0xC042, 0xC11C, 0xC12D, 0xC2EC, + 0xC242, 0xC3ED, 0xC3E3, 0xC4F3, 0xC413, 0xC43D, 0xDC1C, 0xDDD3, 0xDDE4, + 0xDD00, 0xDD3F, 0xDFCC, 0xDFD3, 0xDF4C, 0xD023, 0xD14C, 0xD23C, 0xD3DD, + 0xD3D1, 0xD304, 0xD331, 0xD4CF, 0xD43C, 0xD430, 0xD44D, 0xECC2, 0xECEC, + 0xEDE3, 0xED32, 0xEE3D, 0xE24C, 0xE3D0, 0xE3E3, 0xE444, 0xFC3C, 0xFD44, + 0xF0DC, 0xF3DF, 0xF41C, 0xF43C, 0xF443, 0x0CCE, 0x0CD1, 0x0DF4, 0x0D30, + 0x0024, 0x01D4, 0x0130, 0x033E, 0x04D3, 0x04EC, 0x042C, 0x0424, 0x0444, + 0x1C4D, 0x1DFD, 0x1D3D, 0x1F33, 0x11CC, 0x13CC, 0x13DD, 0x14DC, 0x141C, + 0x2CDF, 0x2C0C, 0x2C44, 0x2D30, 0x23CD, 0x23D4, 0x2303, 0x2404, 0x3CD4, + 0x3C03, 0x3C3C, 0x3C43, 0x3DEE, 0x3D1D, 0x3D31, 0x3EED, 0x3E30, 0x3FCC, + 0x3014, 0x302D, 0x3032, 0x3034, 0x3120, 0x32CD, 0x32C1, 0x32D0, 0x320D, + 0x334C, 0x34CD, 0x34C3, 0x34D0, 0x34D2, 0x3414, 0x343C, 0x4CE4, 0x4CFF, + 0x4CF1, 0x4C0E, 0x4C1D, 0x4C33, 0x4DF4, 0x4EC2, 0x4EC4, 0x4E40, 0x4FDC, + 0x4042, 0x41D4, 0x411C, 0x413C, 0x42CE, 0x42F1, 0x4240, 0x432D, 0x44C0, + 0x44C2, 0x44D1, 0x440E, 0x4420, 0xCCD1, 0xCC1F, 0xCD32, 0xCEC0, 0xCF41, + 0xC1C1, 0xC321, 0xC33C, 0xC42E, 0xDCED, 0xDD0E, 0xDD1F, 0xDD20, 0xDEED, + 0xDF31, 0xD1C0, 0xD120, 0xD2D4, 0xD2ED, 0xD230, 0xD232, 0xD3DF, 0xD30C, + 0xD33D, 0xD4D4, 0xEC3D, 0xEC33, 0xED03, 0xED1C, 0xED2D, 0xED2F, 0xEE33, + 0xEFE3, 0xE0D1, 0xE3ED, 0xE3FC, 0xE32D, 0xE40E, 0xFCD2, 0xFC4D, 0xFDCE, + 0xF31D, 0xF32C, 0x0D23, 0x0D43, 0x0ED3, + /* Codebook 9 - 121 entries */ + 0x0000, 0xFF00, 0x05FF, 0x02FB, 0xFE02, 0xFDFE, 0x03FE, 0x05FE, 0x0301, + 0x0400, 0x02FD, 0x0103, 0xFCFE, 0x02FC, 0x0303, 0x04FD, 0x0004, 0x00FC, + 0x0302, 0x04FF, 0x0502, 0xFC05, 0xFC01, 0xFDFC, 0xFC04, 0x03FC, 0x0504, + 0xFFFC, 0xFCFF, 0xFBFC, 0xFCFB, 0xFE00, 0xFEFB, 0xFEFD, 0x0304, 0xFD04, + 0xFE03, 0x0401, 0x00FF, 0x0002, 0x0205, 0x04FB, 0x0405, 0x00FE, 0xFD05, + 0x0003, 0xFB04, 0xFFFB, 0xFF05, 0x01FB, 0x03FB, 0x00FD, 0xFC02, 0xFC03, + 0xFCFD, 0xFB00, 0x0503, 0xFBFE, 0x0105, 0xFDFB, 0x0305, 0x0501, 0xFB01, + 0x0005, 0x01FC, 0x0403, 0xFCFC, 0xFC00, 0xFF04, 0x05FC, 0x0104, 0xFD03, + 0x0500, 0xFBFF, 0x05FD, 0x0300, 0xFD00, 0x00FB, 0x0200, 0xFE05, 0xFBFD, + 0xFB03, 0xFF01, 0x03FF, 0xFB05, 0x0204, 0x03FD, 0xFEFE, 0xFBFB, 0xFDFD, + 0x04FE, 0x01FE, 0xFF03, 0xFFFD, 0x02FF, 0xFF02, 0xFEFF, 0x0201, 0x01FF, + 0xFFFF, 0x0101, 0xFD01, 0xFEFC, 0x04FC, 0x0404, 0xFE04, 0x0402, 0x01FD, + 0xFDFF, 0xFB02, 0x02FE, 0x05FB, 0x0505, 0xFFFE, 0xFE01, 0x0102, 0x0202, + 0x0203, 0xFD02, 0x0100, 0x0001, + /* Codebook 10 - 121 entries */ + 0x04FE, 0x0401, 0x04FB, 0x04FD, 0xFDFD, 0xFFFC, 0xFCFC, 0xFE00, 0x03FB, + 0xFC03, 0x04FF, 0xFD00, 0x03FC, 0x0404, 0x0405, 0xFCFB, 0xFD05, 0xFB03, + 0x05FD, 0x03FD, 0x0101, 0x05FF, 0x0504, 0xFBFC, 0xFD03, 0x0003, 0x05FE, + 0x0500, 0x0300, 0x0203, 0xFBFE, 0xFFFB, 0x00FD, 0xFB05, 0xFC00, 0x0501, + 0x0005, 0xFEFC, 0x0205, 0xFF05, 0xFDFE, 0x0505, 0x0004, 0x00FC, 0x0102, + 0xFB01, 0xFEFD, 0x01FF, 0xFFFE, 0xFEFB, 0x01FB, 0x01FE, 0x0502, 0x0204, + 0x0400, 0x05FB, 0x0201, 0xFF02, 0xFFFF, 0x02FF, 0xFEFF, 0xFF01, 0xFDFF, + 0x0301, 0x03FF, 0x0302, 0xFE01, 0x0105, 0x03FE, 0xFEFE, 0x01FD, 0x0304, + 0xFB00, 0xFF00, 0xFFFD, 0xFE03, 0x0103, 0xFBFF, 0x00FF, 0xFB02, 0xFB04, + 0x0402, 0xFBFB, 0xFCFE, 0x00FB, 0xFC05, 0x0100, 0x0000, 0xFD01, 0x02FB, + 0x0202, 0xFF03, 0x05FC, 0x0403, 0x0200, 0xFE05, 0xFDFC, 0xFE04, 0x0001, + 0x02FE, 0x02FD, 0x02FC, 0xFD04, 0xFD02, 0x0305, 0xFCFF, 0x04FC, 0xFC04, + 0xFC01, 0xFF04, 0xFE02, 0xFBFD, 0xFC02, 0xFCFD, 0x0002, 0x0303, 0x01FC, + 0x0104, 0x00FE, 0xFDFB, 0x0503, + /* Codebook 11 - 225 entries */ + 0x0000, 0xFA04, 0xFBFA, 0xFAFB, 0xFE04, 0x0103, 0xFDFC, 0xFB03, 0x0504, + 0x04FF, 0xFF07, 0x04FE, 0x0506, 0x01FA, 0xFDFE, 0xFAFF, 0x07FF, 0xFD05, + 0x05F9, 0x0302, 0xFE07, 0xF902, 0x0701, 0x0005, 0xF907, 0x07F9, 0xFC02, + 0x05FE, 0xF9FA, 0xFA01, 0x0203, 0xFF06, 0x0304, 0x0702, 0x03FE, 0xFEFD, + 0xFEFE, 0xFFF9, 0x0607, 0xF905, 0xF9FE, 0x0307, 0x0106, 0x06FC, 0xF900, + 0x0404, 0x0605, 0x01F9, 0x0500, 0x00FB, 0x0601, 0x04FD, 0x07FE, 0xFD02, + 0x02F9, 0x0403, 0x0202, 0x02FD, 0xFEF9, 0xFC03, 0xFE06, 0x03F9, 0xFB07, + 0xFAF9, 0xFFFA, 0xFCFD, 0x0007, 0xFE03, 0xFD04, 0x04FB, 0x05FC, 0x0206, + 0x0606, 0x0703, 0x06FE, 0xF9FF, 0xFAFA, 0x0207, 0xF9FD, 0x0107, 0x06FB, + 0x02FE, 0x0303, 0x0400, 0xFB04, 0xFBFB, 0xFE02, 0xFA02, 0x02FA, 0xFEFA, + 0xFB06, 0x0004, 0xFAFE, 0x0700, 0xFB00, 0xF906, 0x00FD, 0x03FC, 0xFA05, + 0x00FA, 0xFD07, 0xFC05, 0x06F9, 0xFDFD, 0x07FD, 0xFCFC, 0x0300, 0xF903, + 0xFDF9, 0x0602, 0x05FA, 0xF9F9, 0xFB05, 0x0600, 0x0006, 0xFD00, 0x00FC, + 0x07FC, 0x0306, 0xFDFA, 0xFD06, 0x0003, 0x0603, 0x0407, 0xFA07, 0x07FA, + 0xFFFE, 0xFAFD, 0x00F9, 0xFCF9, 0x0604, 0x06FD, 0x0201, 0x03FA, 0xF9FC, + 0x01FB, 0x0704, 0xFBFD, 0xFEFB, 0x0105, 0xFFFF, 0x02FF, 0xFE01, 0x01FE, + 0xFEFF, 0x0101, 0xFF01, 0x01FF, 0xFCFA, 0x0205, 0xFC00, 0xFD03, 0xFF05, + 0x04F9, 0x03FD, 0xFA03, 0x05FF, 0x0707, 0x05FB, 0xF904, 0xFBF9, 0x0102, + 0xFF02, 0xFAFC, 0xFFFB, 0xFB01, 0x0104, 0x06FA, 0x07FB, 0x06FF, 0xFA06, + 0xFE05, 0x0502, 0xFBFF, 0x0401, 0xFC04, 0xFDFB, 0xFA00, 0x0204, 0x0301, + 0x01FC, 0x0406, 0x0200, 0xFD01, 0x0305, 0x0507, 0x0705, 0xFC07, 0x0002, + 0xFF03, 0xFC06, 0x02FB, 0xFB02, 0x00FE, 0xFC01, 0xFCFB, 0x0501, 0xFF04, + 0x04FC, 0x0503, 0x03FF, 0xFFFD, 0x04FA, 0xFEFC, 0x0402, 0x03FB, 0x0505, + 0xFE00, 0x01FD, 0x02FC, 0x0706, 0xFBFE, 0xFDFF, 0xFFFC, 0xF9FB, 0xFBFC, + 0xFCFE, 0xF901, 0xFCFF, 0x05FD, 0x0405, 0x0100, 0xFF00, 0x0001, 0x00FF, + /* Codebook 12 - 441 entries */ + 0x0000, 0xFD03, 0x09FE, 0xFBFF, 0xF701, 0xF7F8, 0x0606, 0xFBFC, 0x0904, + 0x08FF, 0xFB05, 0x0207, 0x04F6, 0x0AFA, 0x0801, 0xF703, 0xFD05, 0xF904, + 0xFAF6, 0xFA02, 0x03F9, 0xF7FD, 0xFBFD, 0x04FF, 0x03F7, 0x0502, 0x0208, + 0x0AFB, 0x0007, 0xF709, 0xF604, 0xFB0A, 0x0204, 0x05F6, 0x0507, 0x0706, + 0xFA00, 0xFE08, 0xFDFB, 0xFD07, 0xFE07, 0x0401, 0x0006, 0x0107, 0x05FA, + 0x0506, 0x0009, 0x0702, 0x0703, 0x05FD, 0x0909, 0xF707, 0xF702, 0xFDF7, + 0xFD09, 0xFFFA, 0xFF08, 0x02F6, 0x0903, 0x04FE, 0x0402, 0xF8F6, 0xFCF9, + 0xFC0A, 0x02F9, 0xFF05, 0x0701, 0x070A, 0x03FD, 0x0905, 0x08F8, 0xFAF9, + 0xF8FE, 0xFC04, 0xFC09, 0xFFF8, 0x09FC, 0x09FD, 0xF7FE, 0x07FF, 0x09F8, + 0xFB09, 0xFCFB, 0xF801, 0xFC01, 0x02F8, 0x0104, 0x03F8, 0x0106, 0x090A, + 0xF90A, 0xF608, 0xFCFE, 0x0504, 0xF7F6, 0x00FA, 0x0407, 0x06FB, 0x09F9, + 0x0A04, 0xFF0A, 0x04FB, 0xF803, 0x00FC, 0x0405, 0x0604, 0xF6FA, 0xF60A, + 0x0AF7, 0xF809, 0xF901, 0xFF07, 0x04FA, 0xFBFB, 0x0707, 0x0A06, 0x0206, + 0x0509, 0xFC02, 0x0906, 0x0A07, 0x0607, 0x03FF, 0x01FC, 0x08FE, 0xF8FF, + 0xFCF7, 0x08F7, 0x0A0A, 0xFB00, 0xFB03, 0xFDFA, 0x01F6, 0x0802, 0x0505, + 0x0601, 0x0803, 0xFE04, 0x0103, 0xF7FC, 0xFAF7, 0xFA01, 0x00F7, 0x01FD, + 0xFFFC, 0x0309, 0x05FC, 0xFD01, 0xF8FD, 0x08FB, 0xF80A, 0xF70A, 0x0AF6, + 0x07FA, 0x0AF8, 0xFEFE, 0xFFFD, 0xF6F6, 0xF902, 0xF909, 0xFBF6, 0xF705, + 0xFEF6, 0xFD02, 0x0308, 0x0602, 0x0603, 0x0301, 0x02FC, 0x010A, 0xF6F9, + 0xF905, 0x0202, 0xFF04, 0xFAFE, 0xF906, 0x01F9, 0xFCFF, 0xFA08, 0xFC05, + 0xFDF8, 0x06FE, 0x07FB, 0x05F9, 0xFD08, 0x0408, 0xFAFF, 0xFE0A, 0x00FB, + 0x04F7, 0x0108, 0x0409, 0x0705, 0x0A09, 0x0800, 0xF6FF, 0x07F8, 0x0709, + 0xF601, 0xF7F9, 0xFE06, 0x0302, 0xFEFC, 0x01FA, 0x0AFF, 0x02FE, 0xFDFF, + 0x02F7, 0xF7F7, 0xFDF6, 0x01FF, 0xF8FC, 0xFEFA, 0x0A05, 0xF606, 0xFDFC, + 0xFFF6, 0x08FA, 0xFDFE, 0xFCFD, 0x0205, 0xFE02, 0x08FD, 0xF603, 0xF903, + 0x06F6, 0x0508, 0x02FA, 0x0900, 0xF704, 0xFB04, 0xFCF6, 0xFD06, 0xFD04, + 0x0403, 0xFEFD, 0x02FD, 0xFF03, 0x0A01, 0xF9FD, 0x09F6, 0x08F6, 0xF900, + 0xFA0A, 0x04F9, 0x06FA, 0xF807, 0xFBF7, 0x00F6, 0x0AFD, 0xFBF8, 0x0404, + 0x0101, 0xFFFF, 0xFF01, 0x03FE, 0x0008, 0x020A, 0x080A, 0xF6F7, 0x06F7, + 0x06F8, 0xF7FB, 0xF607, 0x0600, 0xFAFB, 0xFAFC, 0x03F6, 0x05F7, 0x0209, + 0x0304, 0x04FD, 0x0609, 0xFAFD, 0x0306, 0x0605, 0x0704, 0x08F9, 0x0804, + 0xF9F6, 0xFB07, 0x06F9, 0x07FD, 0xFA03, 0x0AF9, 0x0A08, 0x0005, 0x0AFE, + 0xF805, 0xFE09, 0xFE03, 0xFC00, 0xFC08, 0x0501, 0xF9F7, 0xFA09, 0xFCFA, + 0xFDF9, 0xFF06, 0x0AFC, 0xFAF8, 0xF6FD, 0xFA06, 0x0700, 0xFB02, 0xF9FB, + 0x000A, 0x02FF, 0x00FD, 0x0203, 0xF804, 0x06FD, 0xF602, 0xFEF7, 0xFE05, + 0xFEFF, 0x0201, 0xFF02, 0xFC03, 0xF9FF, 0xFBFA, 0x02FB, 0x0400, 0x05FE, + 0x08FC, 0x0902, 0x040A, 0xF609, 0xF907, 0x01FE, 0x0002, 0xFE00, 0xFFFE, + 0x00FE, 0x0608, 0xF908, 0x07FC, 0x09F7, 0xF800, 0xFEF9, 0x0A02, 0xF8F9, + 0xF808, 0xFA05, 0xFB01, 0x03FA, 0x0907, 0xFE01, 0xFFF7, 0x01F7, 0x0109, + 0x04F8, 0x0003, 0xFCF8, 0xFCFC, 0x0200, 0x00F8, 0x0806, 0xFBFE, 0xF7FA, + 0xFD0A, 0xFEFB, 0x05FF, 0xF8FB, 0x0406, 0x07F6, 0x060A, 0x0102, 0x0105, + 0xF600, 0xF8F7, 0xF9F8, 0xF806, 0x06FC, 0xFD00, 0xFF09, 0x0805, 0x0809, + 0xF6FE, 0xF9FC, 0xFAFA, 0x0307, 0x0500, 0x07F7, 0x0908, 0xFEF8, 0x0503, + 0x0A00, 0xF605, 0xF8F8, 0xF8FA, 0xFB08, 0x05F8, 0x01F8, 0xFB06, 0xFFF9, + 0x030A, 0x05FB, 0xF7FF, 0x050A, 0x09FB, 0x0807, 0x0A03, 0xF6F8, 0xFA07, + 0x0303, 0x0004, 0xF6FB, 0xF9FE, 0x09FF, 0xFC07, 0x09FA, 0xFFFB, 0x04FC, + 0x0901, 0xF708, 0x07F9, 0x00F9, 0x01FB, 0xFA04, 0xFBF9, 0x03FB, 0x03FC, + 0x0708, 0x0808, 0x0300, 0xFDFD, 0x06FF, 0xF9F9, 0xF6FC, 0xF700, 0x0305, + 0xF802, 0xF706, 0xF9FA, 0xFC06, 0x07FE, 0x0001, 0x0100, 0xFF00, 0x00FF, + /* Codebook 13 - 625 entries */ + 0x0000, 0x0201, 0xFDFF, 0x03FE, 0x0302, 0xF909, 0xF90A, 0xFA00, 0xFA0A, + 0x00F7, 0x08F6, 0x09F6, 0x09F8, 0x0901, 0x0AF7, 0x0A03, 0x0BF4, 0xF6F7, + 0xF6FB, 0xF6FF, 0xF600, 0xF706, 0xF801, 0xF806, 0xF808, 0xFDF6, 0xFF09, + 0xFF0A, 0x00F8, 0x0109, 0x02F7, 0x04F7, 0x05F7, 0x05F8, 0x06F7, 0x07F7, + 0x09FA, 0x09FD, 0x0AFB, 0xF6FC, 0x0AFC, 0x0AFD, 0xF60C, 0xF7FF, 0xF8F9, + 0xFA08, 0xFB07, 0xFCF9, 0xFD08, 0x00F9, 0x0208, 0x0409, 0x05FA, 0x05FB, + 0x06FB, 0x0603, 0x060A, 0x0704, 0x0707, 0x0AF5, 0x0A09, 0x0CF5, 0xF4F8, + 0xF5F9, 0x0202, 0xF508, 0xF509, 0xFC0C, 0x0408, 0x0BFC, 0x05FF, 0x0B0A, + 0xFEFF, 0xFEFE, 0xFFFD, 0xFDFD, 0x0CFC, 0xF404, 0xFE00, 0x00FE, 0xFF02, + 0xF506, 0xF507, 0xF7F4, 0xFA01, 0xFB04, 0xFC05, 0x000C, 0x0105, 0x0106, + 0x04FB, 0x05FD, 0x0505, 0x0506, 0x0605, 0x060C, 0x070C, 0xFDFC, 0x0BF8, + 0x0CFB, 0xFE06, 0x0502, 0xFE03, 0xFD03, 0x0C09, 0xF40C, 0xF6F9, 0xFEF5, + 0xFFF4, 0x020C, 0x04F5, 0x0B02, 0xF7F9, 0xF701, 0xF70C, 0xF8FA, 0xF9FD, + 0xF903, 0xFBF7, 0xFC07, 0xFDF8, 0x0108, 0x02F6, 0x0209, 0xFE01, 0x02FF, + 0x0002, 0x020A, 0x03F8, 0x050A, 0x06F8, 0x07FA, 0x07FC, 0x08F7, 0x08FF, + 0xF406, 0xF80C, 0xFA05, 0xFBFF, 0xFE07, 0x0207, 0x06F4, 0x06FE, 0x0601, + 0x0607, 0x07F4, 0x0706, 0xFF00, 0x01FE, 0xF5FB, 0x080C, 0x0CFA, 0xFAF5, + 0x03FC, 0x030B, 0x0B03, 0xF504, 0x0C00, 0x0A08, 0xF601, 0x0CF4, 0xF609, + 0xF60A, 0xFD01, 0xFBF5, 0xFB02, 0xFF03, 0xF5FA, 0xF9F4, 0xF902, 0xF90C, + 0xFBF9, 0xFBFA, 0xFEF8, 0xFFFB, 0xFF06, 0x0306, 0x0405, 0x050C, 0x03FF, + 0xF5FD, 0x0403, 0x0102, 0xFFFE, 0xF401, 0xFBFE, 0x01F4, 0x02FB, 0xF605, + 0xF80A, 0xF9F7, 0xF908, 0xFA07, 0xFBF6, 0xFB08, 0xFB0A, 0xFC09, 0xFD0A, + 0x010A, 0x040A, 0x08FA, 0x0800, 0x09FB, 0x09FC, 0xF4F4, 0x0900, 0x0A00, + 0xF4F5, 0xF6F8, 0xF7F8, 0xF7FA, 0xF9FF, 0xFB05, 0x00FA, 0x0007, 0x01F8, + 0x04F9, 0x0600, 0x07F8, 0x07FF, 0x08FD, 0x0808, 0x09F9, 0x0BF5, 0x0CF8, + 0xF40A, 0xF8FE, 0xFAFD, 0xFA0C, 0xFEFA, 0x0004, 0x05FC, 0x0507, 0x090B, + 0x0C06, 0x00FF, 0x0001, 0x0100, 0xF4FD, 0xF505, 0xF9F5, 0xFC03, 0x0103, + 0x00F5, 0x01FC, 0x050B, 0xF4FF, 0xFE05, 0xFF04, 0xFD02, 0x0B05, 0xF4F9, + 0xF5F6, 0xF50B, 0xF9FC, 0xF906, 0xFD04, 0xFE08, 0x0508, 0x090A, 0x0BF7, + 0x0B0B, 0x0B0C, 0x0CF9, 0x0C08, 0xFA0B, 0xFCF5, 0xFCFD, 0x000B, 0x0B04, + 0x0CFF, 0x02FD, 0x0C01, 0xF500, 0xFBFB, 0x060B, 0x0BFB, 0x0B09, 0xFDFE, + 0x0C03, 0xF6FA, 0x0A02, 0xF708, 0x0AF6, 0x0AF8, 0x0A01, 0xF602, 0xF7FB, + 0x01FD, 0x0203, 0xF702, 0xF8FF, 0xF800, 0xF802, 0xF805, 0xF905, 0xF907, + 0xFAF6, 0xFAF7, 0xFCF6, 0xFD09, 0x03F7, 0x06FD, 0x08FC, 0x0806, 0x09F4, + 0x0903, 0x0908, 0x0AF9, 0x0AFE, 0x0AFF, 0x0A04, 0x0A05, 0x0A06, 0xF4FB, + 0x0A0A, 0x0C0C, 0xF9FB, 0xFA04, 0xFC04, 0xFEF7, 0xFFF8, 0xFFF9, 0x0005, + 0x02F8, 0x03FA, 0x0308, 0xF402, 0x0407, 0x0701, 0xF503, 0xFBFD, 0xFE0C, + 0x080B, 0x0BFD, 0x0B06, 0x0CFD, 0x0CFE, 0xFBFC, 0xFC01, 0xFEFB, 0xFF0C, + 0x04FF, 0x040C, 0x070B, 0x0BFA, 0x0B08, 0xF40B, 0xF803, 0xFE0B, 0xF9F9, + 0xF9FA, 0xF901, 0xFB06, 0xFEF9, 0xFFFA, 0x00FB, 0x0307, 0x0400, 0x08F4, + 0x08FB, 0x08FE, 0xF4FE, 0x0807, 0x09F5, 0xFCFF, 0x0205, 0xFF0B, 0x0501, + 0x0C0A, 0xF50C, 0xF700, 0xFB09, 0x000A, 0xF603, 0xF7FC, 0xFB03, 0xFB0C, + 0xFCFC, 0xFDF4, 0xFDFB, 0x0206, 0x03F5, 0x030C, 0x0602, 0x0B00, 0x0B07, + 0xF709, 0xF70A, 0xFFF6, 0x0009, 0x03F6, 0x04F6, 0x06F6, 0x07F6, 0xF7F6, + 0x07F9, 0x08F8, 0xF7F7, 0xF7FE, 0xF8F6, 0xFE0A, 0x00F6, 0x0008, 0x01F7, + 0x04F8, 0x0509, 0x06FA, 0x07FB, 0x0700, 0x0709, 0x08F9, 0x09F7, 0x09FE, + 0x09FF, 0x0902, 0xF407, 0xF6F4, 0xF6F6, 0xF8F8, 0xF8FC, 0xF80B, 0xFC06, + 0x0006, 0x01FA, 0x0107, 0x03F9, 0x0604, 0x0608, 0x0703, 0xF403, 0xF5F5, + 0xF6F5, 0xFBF4, 0x0300, 0xFFFC, 0xFF05, 0x0303, 0x08F5, 0x0AF4, 0x0904, + 0x0907, 0x0AFA, 0xF604, 0xF5F7, 0xFCFB, 0x0404, 0x0406, 0x05FE, 0x0606, + 0x0BF9, 0x0C02, 0x0402, 0xF4F6, 0xF60B, 0xF8F7, 0xFAF8, 0xFAF9, 0xFAFB, + 0xFAFF, 0xFBF8, 0xFDF7, 0xFFF7, 0x02F9, 0x0309, 0x04FA, 0x0609, 0x07FD, + 0x0804, 0xF8F5, 0x0809, 0x0A0C, 0xF9FE, 0xFAFC, 0xFAFE, 0xFC0B, 0x02FA, + 0x0305, 0x0503, 0x0504, 0xFD00, 0x07FE, 0x0A0B, 0xFD0B, 0x01F5, 0xF400, + 0x0BF6, 0xF6FE, 0xF606, 0xF5FC, 0xF7F5, 0xFA02, 0xFB01, 0xFB0B, 0x00F4, + 0xF502, 0x04FC, 0x05F4, 0x0003, 0xF5FF, 0xF501, 0x010B, 0xF7FD, 0xF704, + 0xF705, 0xF804, 0xF809, 0xF9F6, 0xF900, 0xFA09, 0xFC08, 0xFC0A, 0xFE09, + 0x01F6, 0x030A, 0x05F6, 0x06F9, 0x06FC, 0x070A, 0x0801, 0x0905, 0x0906, + 0xF4F7, 0x0909, 0x0A07, 0xF408, 0xF50A, 0xF8FB, 0xFCF7, 0x01FF, 0xFD06, + 0xFEF6, 0xFF07, 0x05F9, 0xF4FA, 0x0802, 0x0CF6, 0xFCF4, 0x010C, 0x02F4, + 0x03F4, 0x0304, 0x0401, 0x05F5, 0x07F5, 0xFCFE, 0xFDF5, 0x02FC, 0x04FE, + 0x020B, 0x0C04, 0x0CF7, 0x0C07, 0xF6FD, 0xF607, 0x040B, 0xF4FC, 0xF5F8, + 0xF90B, 0xFAF4, 0xFDFA, 0x01FB, 0xFEFC, 0x04F4, 0x04FD, 0xFE04, 0x0BFE, + 0xFFF5, 0x03FD, 0x0BFF, 0xF409, 0xF8F4, 0xF8FD, 0xF9F8, 0xF904, 0xFA06, + 0xFB00, 0xFCF8, 0xFDF9, 0xFD07, 0xFF08, 0x01F9, 0x0500, 0x0708, 0x0803, + 0x0805, 0xF405, 0x080A, 0x090C, 0xFC02, 0xFC00, 0xFD05, 0x0104, 0x02F5, + 0xFF01, 0x0101, 0xFFFF, 0x0200, 0x02FE, 0x0204, 0x0B01, 0x03FB, 0x0C0B, + 0xF608, 0xF703, 0xF707, 0xF807, 0xF5F4, 0xF70B, 0xFAFA, 0xFA03, 0xFCFA, + 0xFD0C, 0x00FC, 0x06F5, 0x06FF, 0x0702, 0xF5FE, 0x0705, 0x0C05, 0xFEF4, + 0x00FD, 0xFE02, 0xFEFD, 0x0301, + /* Codebook 14 - 729 entries */ + 0x0000, 0x01FF, 0xF9F8, 0xF9F9, 0xF907, 0xFA04, 0xFBF8, 0xFB07, 0xFB08, + 0xFB0A, 0xFC07, 0xFC0A, 0xFDF5, 0xFDF6, 0xFEF5, 0xFFFB, 0xFF08, 0xFF0B, + 0x01F5, 0x02F6, 0x03F9, 0x04FA, 0x04FB, 0x04FC, 0x040C, 0x05FF, 0x06FD, + 0x0600, 0x0605, 0x060B, 0x0701, 0x08FA, 0x08FB, 0x08FD, 0x08FF, 0x0801, + 0x0802, 0x0807, 0x080B, 0x080C, 0x09FD, 0x0900, 0x0905, 0x0907, 0x0A03, + 0x0A06, 0x0A07, 0x0B02, 0x0B0B, 0x0C05, 0xF50D, 0x0C07, 0x0C0B, 0xF9FF, + 0xFA02, 0xFCFE, 0xFC00, 0xFE06, 0xFE07, 0x0005, 0x02FB, 0x0207, 0x03FA, + 0x04F7, 0x0406, 0x0407, 0x0408, 0x0506, 0x0808, 0x0AF3, 0x0C0D, 0xF3F3, + 0x0DF5, 0x0D06, 0xFBFD, 0xFC02, 0xFE04, 0xFFFC, 0x0104, 0x04FE, 0x0404, + 0x07F3, 0xFFFF, 0x00FE, 0xF3FC, 0x0D09, 0x0D0D, 0xFD0D, 0xF9F3, 0x0D0B, + 0x0DF4, 0xF4F4, 0x02FF, 0x04FD, 0x05FD, 0x0B0D, 0x0DF8, 0xFDFD, 0xFEF3, + 0x0101, 0xFE01, 0xFEFF, 0xFFFE, 0xFF02, 0x01FE, 0x0DFD, 0xF300, 0xF302, + 0xFCF3, 0xFEFD, 0xFFFD, 0xFF0D, 0x02F3, 0xFEFE, 0x02FD, 0x0203, 0x0002, + 0x0201, 0x040D, 0xF40D, 0xFAFB, 0xFAFC, 0xFAFD, 0xFAFF, 0xFA01, 0xFCF9, + 0xFCFF, 0xFF09, 0x0209, 0x0306, 0x0307, 0x0405, 0x05FA, 0x06FA, 0x0601, + 0x0706, 0x0708, 0x09FE, 0x0903, 0x0906, 0x090A, 0x0A0A, 0x0CF3, 0xF307, + 0xF5F3, 0xFF00, 0x0102, 0x00FD, 0xFBFE, 0xFCFC, 0x030D, 0x0304, 0x0DFA, + 0xF402, 0xF5F6, 0xF303, 0xFB0D, 0xFFF3, 0x0103, 0x050D, 0xF3F7, 0xF7F3, + 0xFB03, 0x0205, 0x04FF, 0x0403, 0x0504, 0x0505, 0x06FE, 0x0D0C, 0x060D, + 0xFBF3, 0x03FE, 0x0303, 0x04F3, 0x0DFB, 0x0D02, 0x0D04, 0x0D05, 0xF6FB, + 0xF606, 0xF7F6, 0xF703, 0xF705, 0xF8F5, 0xF8FE, 0xF8FF, 0xF9FC, 0xF901, + 0xF904, 0xF906, 0xF908, 0xFAF9, 0xFA00, 0xFA09, 0xFA0A, 0xFBF5, 0xFBF7, + 0xFB06, 0xFB09, 0xFCF6, 0xFCF7, 0xFC08, 0xFEF7, 0xFEF8, 0xFFF6, 0xFFF8, + 0xFFF9, 0x00F6, 0x00F7, 0x00FA, 0x0007, 0x0009, 0x0106, 0x0109, 0x010C, + 0x02F4, 0x02F5, 0x02F7, 0x0100, 0x00FF, 0x0001, 0x020A, 0x020C, 0x040A, + 0x06F5, 0x06F7, 0x06F8, 0x07F5, 0x07F7, 0x07F9, 0x07FA, 0x07FB, 0x07FF, + 0x0700, 0x08F6, 0x0805, 0x0809, 0x080A, 0x0904, 0x0908, 0x090C, 0x0AF4, + 0x0AFF, 0x0A08, 0x0BF6, 0x0B01, 0x0B05, 0x0B07, 0x0B0C, 0xF3F6, 0x0CF9, + 0x0C01, 0xF30A, 0xF502, 0xF6F7, 0xF8FA, 0xF8FB, 0xF9FB, 0xF905, 0xFA03, + 0xFA05, 0xFA08, 0xFB01, 0xFB04, 0xFCFA, 0xFCFB, 0xFC05, 0xFC06, 0xFDF7, + 0xFD09, 0xFF07, 0x0008, 0x0107, 0x0309, 0x04F9, 0x0401, 0x05FC, 0x0501, + 0x0508, 0x0509, 0x06FF, 0x0604, 0x070A, 0x08FC, 0x0804, 0x0902, 0x0A01, + 0x0B03, 0x0B09, 0x0B0A, 0x0C0C, 0x0DF3, 0xF3F9, 0xF30B, 0xF70D, 0xF80D, + 0xF90D, 0xFAFE, 0xFBFA, 0xFC01, 0xFDFB, 0xFD07, 0x02F9, 0x0208, 0x03FC, + 0x0305, 0x0502, 0x0602, 0x00F3, 0x0DF6, 0x0D0A, 0xFF03, 0x0D00, 0xF3F8, + 0x0300, 0xFE03, 0x0003, 0x0DFC, 0xF3F5, 0xF308, 0xFA0D, 0xFCFD, 0xFC03, + 0xFDF9, 0xFD06, 0x02FA, 0x0400, 0x05FB, 0x0607, 0x08F3, 0x090D, 0x0A0D, + 0xF3FA, 0xFC0D, 0xFDF3, 0xFE0D, 0xF3FF, 0x02FC, 0xF30C, 0xF5FF, 0xF603, + 0xF607, 0xF301, 0x0DFF, 0x0D01, 0xF60B, 0xF7F5, 0xF7F9, 0xF7FB, 0xF7FC, + 0xF7FD, 0xF8F9, 0xF803, 0xF9FA, 0xF9FD, 0xF903, 0xFA06, 0xFA07, 0xFBF9, + 0xFBFB, 0xFDF8, 0xFD0A, 0xFE08, 0xFE09, 0xFFFA, 0xFF05, 0x00FB, 0x01F7, + 0x01FB, 0x02F8, 0x0308, 0x05F7, 0x05F8, 0x05F9, 0x0503, 0x0507, 0x06FB, + 0x06FC, 0x0609, 0x060A, 0x07FE, 0x0703, 0x0705, 0x070B, 0x0803, 0x0806, + 0x09F9, 0x0AF9, 0x0A0B, 0xF3F4, 0x0C09, 0x0C0A, 0xF309, 0xF60D, 0xF8F3, + 0xF902, 0xFAFA, 0xFBFC, 0xFB02, 0xFC04, 0xFEFA, 0xFE05, 0xFF06, 0x0004, + 0x0206, 0x0402, 0x05FE, 0x0603, 0x0606, 0x0608, 0x0702, 0x0707, 0x09F3, + 0x0909, 0x0BF3, 0x0DF7, 0xF3FD, 0xF304, 0xFE00, 0xFD00, 0xF306, 0xFAF3, + 0xFD02, 0x0301, 0x0200, 0x03FF, 0xFD04, 0xFDFC, 0xFEFC, 0x0105, 0x03FD, + 0x05F3, 0x0202, 0x03F3, 0x06F3, 0xF6F3, 0xF7FE, 0xFE02, 0x0DFE, 0xF802, + 0xF9FE, 0xFAF7, 0xFBFF, 0x02FE, 0xFDFA, 0xFD05, 0xFD08, 0xFEF9, 0xFEFB, + 0xFF04, 0x00FC, 0x01FA, 0x01FC, 0x03FB, 0x0409, 0x080D, 0xF3FB, 0xF305, + 0xF4F3, 0xFD03, 0x0204, 0x070D, 0x010D, 0x0D08, 0x000D, 0xFDFE, 0xFDFF, + 0xFD01, 0x0DF9, 0x0D07, 0x020D, 0x0D03, 0xFF01, 0xF3FE, 0x01F3, 0x01FD, + 0x0302, 0xF4F8, 0xF4F9, 0xF4FA, 0xF4FB, 0xF4FC, 0xF4FD, 0xF400, 0xF401, + 0xF403, 0xF404, 0xF406, 0xF407, 0xF408, 0xF409, 0xF40A, 0xF40B, 0xF40C, + 0xF5F8, 0xF5FA, 0xF5FC, 0xF5FE, 0xF500, 0xF501, 0xF503, 0xF504, 0xF505, + 0xF506, 0xF507, 0xF508, 0xF509, 0xF50A, 0xF50B, 0xF50C, 0xF6F4, 0xF6FF, + 0xF600, 0xF604, 0xF608, 0xF609, 0xF60A, 0xF60C, 0xF7F4, 0xF7F8, 0xF7FA, + 0xF700, 0xF708, 0xF709, 0xF70A, 0xF70B, 0xF70C, 0xF8F4, 0xF8F7, 0xF800, + 0xF809, 0xF80A, 0xF80B, 0xF80C, 0xF9F4, 0xF90A, 0xF90B, 0xF90C, 0xFAF6, + 0xFA0C, 0xFBF6, 0xFB05, 0xFB0B, 0xFB0C, 0xFCF4, 0xFCF5, 0xFCF8, 0xFC09, + 0xFC0C, 0xFD0B, 0xFEF4, 0xFE0C, 0xFFF4, 0xFFF7, 0xFF0A, 0xFF0C, 0x00F4, + 0x00F5, 0x00F8, 0x0006, 0x000A, 0x000B, 0x000C, 0x01F4, 0x01F8, 0x01F9, + 0x010A, 0x020B, 0x03F4, 0x03F5, 0x03F6, 0x03F7, 0x030C, 0x04F4, 0x04F6, + 0x040B, 0x05F4, 0x05F6, 0x0500, 0x050A, 0x050B, 0x050C, 0x06F4, 0x06F6, + 0x07F4, 0x07F8, 0x07FD, 0x0709, 0x070C, 0x08F4, 0x08F5, 0x08F8, 0x08F9, + 0x08FE, 0x09F4, 0x09F5, 0x09F6, 0x09F7, 0x09F8, 0x09FA, 0x09FF, 0x0901, + 0x090B, 0x0AF5, 0x0AF8, 0x0AFC, 0x0AFE, 0x0A02, 0x0A04, 0x0A09, 0x0A0C, + 0x0BF4, 0x0BF5, 0x0BF7, 0x0BF8, 0x0BF9, 0x0BFA, 0x0BFB, 0x0BFC, 0x0BFD, + 0x0B00, 0x0B04, 0x0B06, 0x0CF4, 0x0CF7, 0x0CFB, 0x0CFC, 0x0CFD, 0x0CFF, + 0x0C00, 0x0C03, 0x0C04, 0x0C06, 0xF4F5, 0xF4F6, 0xF4FE, 0xF4FF, 0xF5F9, + 0xF5FB, 0xF5FD, 0xF6F5, 0xF6F6, 0xF6FC, 0xF6FE, 0xF601, 0xF605, 0xF7FF, + 0xF702, 0xF704, 0xF707, 0xF8F8, 0xF801, 0xF804, 0xF805, 0xF807, 0xF808, + 0xF9F5, 0xF9F7, 0xF900, 0xF909, 0xFAF4, 0xFAF5, 0xFAF8, 0xFA0B, 0xFBF4, + 0xFB00, 0xFC0B, 0xFDF4, 0xFD0C, 0xFEF6, 0xFE0A, 0xFE0B, 0xFFF5, 0x00F9, + 0x01F6, 0x0108, 0x010B, 0x03F8, 0x030A, 0x030B, 0x04F5, 0x04F8, 0x05F5, + 0x06F9, 0x060C, 0x07F6, 0x07FC, 0x0704, 0x08F7, 0x0800, 0x09FB, 0x09FC, + 0x0AF6, 0x0AF7, 0x0AFA, 0x0AFB, 0x0AFD, 0x0A00, 0x0A05, 0x0BFE, 0x0BFF, + 0x0B08, 0x0CF5, 0x0CF6, 0x0CF8, 0x0CFA, 0x0CFE, 0xF30D, 0x0C02, 0x0C08, + 0xF4F7, 0xF405, 0xF5F4, 0xF5F5, 0xF5F7, 0xF6F8, 0xF6F9, 0xF6FA, 0xF6FD, + 0xF602, 0xF7F7, 0xF701, 0xF706, 0xF8F6, 0xF8FC, 0xF8FD, 0xF806, 0xF9F6, + /* Codebook 15 - 1089 entries */ + 0x0000, 0x00FF, 0xFEFF, 0x0201, 0xFAFF, 0xFBFB, 0xFF06, 0x06FE, 0x100E, + 0xF2F6, 0xF2FF, 0xF205, 0xF3F3, 0xF6F2, 0xF8F5, 0xF90B, 0xFAF8, 0xFAF9, + 0xFA06, 0xFCF2, 0x0008, 0x0209, 0x030E, 0x04F2, 0x040E, 0x040F, 0x05F7, + 0x06F1, 0x07FD, 0x0807, 0x09F1, 0x09FC, 0x09FE, 0x0AF1, 0x0A03, 0x0A0B, + 0x0B08, 0x0B0C, 0x0CF1, 0x0C0E, 0x0E0B, 0xFF07, 0x03F8, 0xF002, 0xF00A, + 0xF00B, 0x0DF0, 0xFE01, 0xFFF0, 0x06FD, 0x0F07, 0xF20E, 0xF3F7, 0xF009, + 0xFAFB, 0xFC05, 0xF510, 0x0205, 0x07F0, 0x1008, 0xF0F4, 0xF007, 0x100A, + 0xF3FC, 0xF305, 0xF308, 0xF30F, 0xF4FE, 0xF40F, 0xF505, 0xF508, 0xF50A, + 0xF60B, 0xF60C, 0xF60D, 0xF7F4, 0xF7FB, 0xF701, 0xF708, 0xF70F, 0xF800, + 0xF9F3, 0xF90C, 0xFBF5, 0xFBF6, 0xFC0D, 0xFDF5, 0x000A, 0x020D, 0x08F1, + 0x0901, 0x0AF2, 0x0A02, 0x0BF4, 0x0BFC, 0x0BFE, 0x0B06, 0x0CF4, 0x0C02, + 0x0C07, 0x0DF5, 0x0DF6, 0x0DF8, 0xF1F1, 0x0D03, 0x0D04, 0xF1F3, 0xF1F7, + 0xF103, 0xF107, 0xF2FA, 0xF4F4, 0xF5F2, 0xF5FA, 0xF6F5, 0xF6FC, 0xF70E, + 0xF8F1, 0xF8F6, 0xF900, 0xF90E, 0xFB0A, 0xFCF7, 0xFC08, 0xFC0B, 0xFDF2, + 0xFEF2, 0xFF0A, 0x020E, 0x06F7, 0x07FA, 0x0709, 0x08FC, 0x0906, 0x0A06, + 0x0EF8, 0x0001, 0x0100, 0xFF00, 0xF010, 0x10F0, 0x0E01, 0x0E09, 0x0E0A, + 0x0F08, 0xF204, 0xFDF9, 0xFEFA, 0x0407, 0x0601, 0x0704, 0xF0FD, 0xFCFC, + 0x0BF0, 0x1004, 0xF0F1, 0xF00C, 0x1005, 0x1009, 0x03FD, 0x100D, 0xF903, + 0xFBFA, 0xFD03, 0xF310, 0x0107, 0x0506, 0xFDFB, 0x0D0E, 0xF104, 0x0EF1, + 0xF307, 0x000D, 0x0C00, 0x0D01, 0xF10F, 0xF4FF, 0xFE05, 0x00F0, 0x01FB, + 0x100C, 0x100F, 0xF2FB, 0xF2FD, 0xF200, 0xF4F9, 0xF606, 0xF9F6, 0xF9FF, + 0xFAF7, 0xFA09, 0xFC0A, 0xFD09, 0x0109, 0x030A, 0x040A, 0x05F6, 0x05F9, + 0x0509, 0x070A, 0x070B, 0x0809, 0x090B, 0x0AFA, 0x0B0F, 0x0EF5, 0x0EF9, + 0x0E08, 0x0FFC, 0x0FFF, 0x0010, 0xF905, 0x0602, 0x0104, 0x0105, 0x09F0, + 0xFFFD, 0x01FD, 0x0103, 0x01F0, 0x1006, 0x00FB, 0x02F2, 0x0206, 0x0408, + 0xF0FE, 0x0500, 0x06FA, 0xF004, 0xF008, 0xF610, 0x04FC, 0x10F6, 0x10F7, + 0xFF03, 0xFFFC, 0x10FD, 0x10FE, 0xFD01, 0xFF04, 0x10F1, 0x1001, 0xF401, + 0x000C, 0x01F3, 0x0C01, 0xF30D, 0xF4F6, 0xFEF3, 0x02F5, 0x0A00, 0x0BF3, + 0x0B00, 0x0D00, 0x0EF2, 0x0FF2, 0xF20F, 0xF3FF, 0xF301, 0xF306, 0xF309, + 0xF30C, 0xF405, 0xF40B, 0xF40D, 0xF5F8, 0xF5FB, 0xF509, 0xF700, 0xF90F, + 0xFCF4, 0xFCF5, 0xFF0C, 0x00F5, 0x01F5, 0x060D, 0x08FF, 0x0AF4, 0x0A0D, + 0x0BF6, 0x0B01, 0x0B0B, 0x0CF2, 0x0CFA, 0x0CFE, 0x0DF7, 0x0DFA, 0x0DFD, + 0x0D0A, 0x0FF4, 0xF1F2, 0xF1F9, 0xF20A, 0xF20C, 0xF3F1, 0xF4F5, 0xF5F4, + 0xF6F6, 0xF7F3, 0xF7F5, 0xF7FE, 0xF709, 0xF8F2, 0xF80E, 0xF9F5, 0xFA00, + 0xFBF1, 0xFC07, 0xFDF4, 0xFD0B, 0xFE0A, 0xFFF6, 0xFFF8, 0x00FA, 0x0208, + 0x020B, 0x04F6, 0x04F7, 0x06F8, 0x060B, 0x07F2, 0x07F6, 0x07F9, 0x070F, + 0x08FA, 0x0903, 0x0904, 0x0A07, 0x0A08, 0x0A0E, 0x0CF7, 0x0D0F, 0x0EF7, + 0x0EFC, 0x0301, 0xF8FD, 0x0E0D, 0x0F03, 0xF9F2, 0xFBFF, 0xFFFB, 0x0803, + 0x0F0D, 0x0FFD, 0xF10D, 0x10F3, 0xF9FD, 0xF901, 0xF902, 0xFB07, 0xFEF9, + 0x0006, 0xF2F0, 0xF00D, 0x0307, 0x04F9, 0xFD00, 0x03F0, 0x0FF0, 0xF410, + 0xFDF0, 0xF1F6, 0xF1F8, 0xF101, 0xF2F3, 0xF207, 0xF4FA, 0xF4FC, 0xF5F5, + 0xF5F7, 0xF6F3, 0xF6F4, 0xF609, 0xF705, 0xF706, 0xF8F9, 0xF8FB, 0xF804, + 0xF909, 0xFCF1, 0xFEF1, 0xFEF7, 0xFE0B, 0x01F1, 0x02F7, 0x04F5, 0x050C, + 0x06F6, 0x06F9, 0x0609, 0x07F1, 0x08F5, 0x08FB, 0x0805, 0x080F, 0x0AF7, + 0x0B05, 0x0B0A, 0x0C08, 0x0C0B, 0x0C0D, 0x0D08, 0x0E07, 0x0FF6, 0x0FFA, + 0xFDFA, 0x0F02, 0x0F0A, 0xFD0E, 0x02F9, 0x0308, 0x0507, 0xFB03, 0x06FC, + 0x0702, 0xFCFB, 0x02FB, 0xF5F0, 0x05FD, 0x0703, 0xF2F1, 0x0003, 0xF0FC, + 0xF00F, 0xFBFE, 0xFF05, 0xFCF0, 0x10F5, 0x10FF, 0xFCFF, 0x01FC, 0xF9FB, + 0xFA02, 0xFB08, 0xFD08, 0xFEF8, 0xFE0E, 0x01FA, 0x0207, 0xFE04, 0xFBFD, + 0x0604, 0x07FC, 0x0300, 0x0410, 0xF001, 0x09FD, 0xF302, 0xF402, 0xF406, + 0xF40E, 0xFDFF, 0xFD10, 0xF110, 0x10F9, 0x03FF, 0xFBF0, 0xF5F9, 0xF5FC, + 0xF501, 0xF503, 0xF50F, 0xF600, 0xF607, 0xF70B, 0xF70C, 0xF908, 0xFBF3, + 0xFFF3, 0x00F3, 0x0009, 0x010C, 0x010D, 0x03F3, 0x08F4, 0x0A05, 0x0CF8, + 0x0CFC, 0x0DF1, 0x0DF2, 0x0DFB, 0xF1F4, 0xF1F5, 0xF1FE, 0xF2F4, 0xF2F8, + 0xF2F9, 0xF20D, 0xF4F3, 0xF5F1, 0xF5FE, 0xF50D, 0xF6FE, 0xF7F8, 0xF8FF, + 0xF808, 0xF80C, 0xF9F4, 0xFA0A, 0xFA0C, 0xFBF2, 0xFBF4, 0xFFF7, 0x02F6, + 0x030C, 0x030F, 0x0409, 0x07F4, 0x08F6, 0x08F9, 0x0808, 0x080A, 0x0908, + 0x090D, 0x0AFC, 0x0AFD, 0x0BF7, 0x0C0F, 0x0D05, 0x0D07, 0x0EF4, 0xF2FE, + 0x0F00, 0x0F01, 0xF7FD, 0xF8FC, 0xF9F9, 0xFB00, 0xFE07, 0x00F9, 0x050E, + 0x06FF, 0x0705, 0x080E, 0x0A0F, 0x0EFD, 0xFD06, 0x03FB, 0x0502, 0x0503, + 0x0EF0, 0x10F2, 0xF1F0, 0x04FF, 0x06F0, 0xFCFE, 0x00FD, 0x10FC, 0x0E0F, + 0xF9F7, 0xF9F8, 0xF9FA, 0xFA05, 0xFBF8, 0x03FE, 0x02FD, 0x02FE, 0xFBF9, + 0x04FA, 0x0708, 0x08FD, 0xFB02, 0x0005, 0x02FC, 0x0401, 0x01FF, 0xFEFD, + 0x0310, 0x0305, 0xF1FA, 0xF106, 0xF209, 0xF20B, 0xFC01, 0xFDFC, 0xFEF0, + 0xFE10, 0x02F0, 0xF7F0, 0x00FC, 0xF3F4, 0xF3F5, 0xF3F6, 0xF3F9, 0xF408, + 0xF5F6, 0xF504, 0xF50B, 0x0203, 0xF6F7, 0xF6F9, 0xF60F, 0xF8F3, 0xF806, + 0xF80D, 0xF80F, 0xF90D, 0xFAF4, 0xFAF5, 0xFA08, 0xFC0C, 0xFD0C, 0xFE0C, + 0xFF0B, 0x00F1, 0x0202, 0x00F7, 0x000F, 0x02F4, 0x020C, 0x03F5, 0x05F5, + 0x060A, 0x07F3, 0x07F7, 0x0700, 0x0701, 0x08F7, 0x08F8, 0x09F8, 0x09FF, + 0x0AF8, 0x0AFF, 0x0A0C, 0x0BFA, 0x0BFB, 0x0B03, 0x0C0A, 0x0D0C, 0x0EF6, + 0x0FF5, 0x0FF9, 0x0FFE, 0x0F0E, 0xF3F2, 0xF802, 0xF803, 0xF9F1, 0xF9FE, + 0xFAFA, 0xFB06, 0xFC0E, 0xFF0E, 0x0508, 0xF00E, 0x07FF, 0x0EFB, 0xFC04, + 0xFD05, 0xF8F0, 0x02FA, 0x0505, 0xFC10, 0x0510, 0xFF01, 0x0101, 0xFFFF, + 0xF0F0, 0x1010, 0x0002, 0x0C10, 0xFB10, 0xFEFC, 0x0400, 0xF4F0, 0x0FFB, + 0x0F0F, 0xF10E, 0xF3FE, 0xF404, 0x01F4, 0xF2F5, 0xF202, 0xF9F0, 0x0210, + 0xFE02, 0x05F0, 0x0610, 0xF7F1, 0xF8F8, 0xF9FC, 0xF904, 0xFAF1, 0xFDF6, + 0xFD07, 0xFE08, 0xFEFE, 0x01F9, 0x02F8, 0x0605, 0x0608, 0x070E, 0x0D0D, + 0x0EFF, 0x0E05, 0xFAF0, 0x10F4, 0x0E06, 0x0E0C, 0x0D10, 0xF6F0, 0x04FE, + 0xFBFC, 0x05FE, 0x0204, 0x0402, 0x0710, 0xFC02, 0xFE03, 0xFD04, 0x0004, + 0xF10A, 0x0CFF, 0x0DF3, 0xF3FD, 0xF4F1, 0xF40A, 0xF5FF, 0xF50C, 0xF6F1, + 0xF608, 0xF70D, 0xFB0B, 0xFEF6, 0xFFF4, 0x00F4, 0x030D, 0x0CF6, 0xF1FB, + 0x0CF9, 0x0DF9, 0xF1FC, 0xF100, 0xF10C, 0xF403, 0xF409, 0xF5FD, 0xF502, + 0xF50E, 0xF6FA, 0xF601, 0xF605, 0xF60E, 0xF7FF, 0xF8F4, 0xF807, 0xF80A, + 0xF90A, 0xFA0F, 0xFB0C, 0xFB0D, 0xFB0F, 0xFD0D, 0xFE09, 0xFF09, 0x00F6, + 0x00F8, 0x010B, 0x010F, 0x020A, 0x040D, 0x05FA, 0x050B, 0x06F3, 0x060C, + 0x08F2, 0x0800, 0x080B, 0x080D, 0x09F6, 0x09F7, 0x09FA, 0x090C, 0x0AFB, + 0x0AFE, 0x0BF1, 0x0BF8, 0x0BFD, 0x0B04, 0x0CF5, 0x0CFD, 0x0C04, 0x0C0C, + 0x0DFC, 0x0EF3, 0xF8F7, 0x0E00, 0x0FF7, 0xF8FE, 0xFA04, 0xFCF8, 0xFDF8, + 0xFFF2, 0x040B, 0x05F8, 0x0607, 0x060E, 0x090F, 0x0306, 0x0EFE, 0x0E04, + 0xF0FB, 0x0E10, 0x0403, 0x0603, 0x0E0E, 0xF2F2, 0xFD02, 0xF3F0, 0x0810, + 0x0302, 0xFE06, 0xF4F7, 0xF702, 0xF801, 0xF805, 0xFAF2, 0xFBF7, 0xFB09, + 0xFCF6, 0xFF08, 0x010E, 0x060F, 0x0707, 0x0804, 0x0909, 0x03FC, 0x05FC, + 0x090E, 0x0E03, 0x08F0, 0x05FF, 0xF0FF, 0xFCFD, 0xFA01, 0xFB01, 0xFDFE, + 0x0110, 0x0404, 0x00FE, 0xF0F5, 0x0606, 0xF1FF, 0x0FF1, 0xF3FA, 0xF102, + 0xF105, 0x1002, 0xF108, 0xF109, 0xF2F7, 0xF3F8, 0xF4FD, 0xF407, 0xF5F3, + 0xF6F8, 0xF6FB, 0xF6FF, 0xF602, 0xF603, 0xF7F9, 0xF704, 0xF707, 0xF70A, + 0xF809, 0xFAF3, 0xFA0D, 0xFCF3, 0xFDF3, 0xFEF4, 0xFEF5, 0xFFF5, 0x010A, + 0x030B, 0x04F3, 0x04F4, 0x040C, 0x05F3, 0x050A, 0x050D, 0x06F4, 0x06F5, + 0x07F5, 0x080C, 0x09F2, 0x09F4, 0x09F5, 0x090A, 0x0AF3, 0x0A01, 0x0BF2, + 0x0BF5, 0x0BF9, 0x0B0D, 0x0CF3, 0x0CFB, 0x0DF4, 0x0FF8, 0x0F09, 0x0F0B, + 0xF1FD, 0xF4F2, 0xF7F7, 0xF7FA, 0xF906, 0xF907, 0xFA07, 0xFA0E, 0xFB05, + 0xFB0E, 0xFC0F, 0xFDF1, 0xFDF7, 0xFE0F, 0x0007, 0x000E, 0x01F7, 0x03F6, + 0x04F8, 0x0406, 0x050F, 0x06F2, 0x0600, 0x07FE, 0x0706, 0x08FE, 0x0801, + 0x0802, 0x0806, 0x0A09, 0xF210, 0x0A0A, 0x0B09, 0xF0F6, 0x0106, 0x03FA, + 0xF003, 0xFA10, 0xF0F2, 0x0504, 0x0E02, 0xF201, 0xFFFE, 0xF0F9, 0xF810, + 0x04F0, 0x0B10, 0x0F10, 0x10FA, 0x1007, 0x100B, 0x01FE, 0x0303, 0xF0F8, + 0x0AF0, 0x10FB, 0x1003, 0xF0F7, 0xF910, 0x0102, 0x02FF, 0xFE00, 0xFEFB, + 0xFF10, 0xF203, 0xF206, 0xF208, 0xF7F6, 0xF7FC, 0xFC06, 0xFD0A, 0xFFF1, + 0x01F8, 0x020F, 0x03F1, 0x0309, 0x04F1, 0x05F1, 0x05F2, 0x06FB, 0x07F8, + 0x070C, 0x09F9, 0x0902, 0xFA03, 0x0B07, 0x0B0E, 0xFF02, 0xFC00, 0x0304, + 0x0910, 0x0405, 0xFAFC, 0xFC03, 0xFAFD, 0xFAFE, 0xFCF9, 0xFCFA, 0x04FB, + 0x0501, 0x0200, 0xF0FA, 0xF005, 0xF006, 0x04FD, 0xFDFD, 0x10F8, 0xF710, + 0xF300, 0xF303, 0xF304, 0xF4FB, 0xF400, 0xF40C, 0xF500, 0xFF0D, 0x000B, + 0x0AF9, 0x0BFF, 0x0DFE, 0xF10B, 0x0DFF, 0x0D0B, 0xF2FC, 0xF3FB, 0xF30A, + 0xF30B, 0xF30E, 0xF4F8, 0xF506, 0xF507, 0xF6FD, 0xF604, 0xF60A, 0xF80B, + 0xFA0B, 0xFE0D, 0x00F2, 0x01F6, 0x0108, 0x02F3, 0x03F4, 0x05F4, 0x070D, + 0x08F3, 0x09F3, 0x0900, 0x0AF5, 0x0AF6, 0x0A04, 0x0B02, 0x0C03, 0x0C05, + 0x0C06, 0x0C09, 0x0D02, 0x0D06, 0x0D09, 0x0FF3, 0xF7F2, 0x0F04, 0x0F0C, + 0xF703, 0xF8FA, 0xFAF6, 0xFC09, 0xFD0F, 0xFFF9, 0xFF0F, 0x01F2, 0x02F1, + 0x03F2, 0x03F7, 0x03F9, 0x05FB, 0x07FB, 0x09FB, 0x0905, 0x0907, 0x0EFA, + 0x0F05, 0x0F06, 0xF000, 0xFB04, 0xF0F3, 0xFFFA, 0x1000, 0x0A10, 0x0CF0 }; -static const uint16_t on2avc_cb1_syms[ON2AVC_CB1_CODES] = { - 0x0000, 0x0011, 0x001F, 0x00F1, 0x00FF, 0x0101, - 0x010F, 0x0110, 0x01F0, 0x0F01, 0x0F0F, 0x0F10, - 0x0FF0, 0x1001, 0x100F, 0x1010, 0x10F0, 0x1100, - 0x1111, 0x111F, 0x11F1, 0x11FF, 0x1F00, 0x1F11, - 0x1F1F, 0x1FF1, 0x1FFF, 0xF001, 0xF00F, 0xF010, - 0xF0F0, 0xF100, 0xF111, 0xF11F, 0xF1F1, 0xF1FF, - 0xFF00, 0xFF11, 0xFF1F, 0xFFF1, 0xFFFF, -}; - -#define ON2AVC_CB2_CODES 41 -static const uint32_t on2avc_cb2_codes[ON2AVC_CB2_CODES] = { - 0x0006, 0x0003, 0x001F, 0x001E, 0x0000, 0x0014, - 0x0009, 0x000E, 0x000D, 0x000C, 0x0015, 0x0008, - 0x0010, 0x000F, 0x0004, 0x0012, 0x0007, 0x0016, - 0x0005, 0x002F, 0x0017, 0x0006, 0x001D, 0x002C, - 0x005E, 0x0014, 0x0016, 0x0006, 0x0011, 0x000A, - 0x0013, 0x001C, 0x002D, 0x0015, 0x005F, 0x002E, - 0x0002, 0x0007, 0x005D, 0x005C, 0x0004, -}; - -static const uint8_t on2avc_cb2_bits[ON2AVC_CB2_CODES] = { - 3, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, - 7, 7, 7, 7, 5, 7, - 7, 7, 7, 5, 5, 5, - 5, 5, 7, 7, 7, 7, - 5, 7, 7, 7, 7, -}; - -static const uint16_t on2avc_cb2_syms[ON2AVC_CB2_CODES] = { - 0x0000, 0x0011, 0x001F, 0x00F1, 0x00FF, 0x0101, - 0x010F, 0x0110, 0x01F0, 0x0F01, 0x0F0F, 0x0F10, - 0x0FF0, 0x1001, 0x100F, 0x1010, 0x10F0, 0x1100, - 0x1111, 0x111F, 0x11F1, 0x11FF, 0x1F00, 0x1F11, - 0x1F1F, 0x1FF1, 0x1FFF, 0xF001, 0xF00F, 0xF010, - 0xF0F0, 0xF100, 0xF111, 0xF11F, 0xF1F1, 0xF1FF, - 0xFF00, 0xFF11, 0xFF1F, 0xFFF1, 0xFFFF, -}; - -#define ON2AVC_CB3_CODES 313 -static const uint32_t on2avc_cb3_codes[ON2AVC_CB3_CODES] = { - 0x00000, 0x00044, 0x00042, 0x00034, 0x0002E, 0x000CD, - 0x002DF, 0x0024A, 0x000CC, 0x0022E, 0x002D6, 0x00031, - 0x0003B, 0x00048, 0x00052, 0x00056, 0x001B8, 0x00160, - 0x001FA, 0x0015E, 0x0015C, 0x0014E, 0x0003C, 0x0010C, - 0x00166, 0x000CA, 0x0324C, 0x00FDA, 0x003DE, 0x002DB, - 0x0057F, 0x02C9E, 0x008BF, 0x0037F, 0x021DC, 0x00B1E, - 0x002DE, 0x002D2, 0x000C8, 0x014D6, 0x03576, 0x002CA, - 0x002CF, 0x003DB, 0x007FE, 0x01F7E, 0x005A3, 0x008BE, - 0x02D7E, 0x002D3, 0x0037E, 0x0004D, 0x0004C, 0x00041, - 0x0016A, 0x0010D, 0x0015D, 0x0011F, 0x00162, 0x0021E, - 0x00055, 0x00161, 0x001BE, 0x0004E, 0x0004A, 0x0004B, - 0x003EE, 0x00352, 0x0043A, 0x0033E, 0x0035C, 0x0036C, - 0x00050, 0x0032F, 0x003D6, 0x00039, 0x0067E, 0x00536, - 0x000FE, 0x001F4, 0x0036D, 0x007EF, 0x00CFE, 0x002D0, - 0x00F8C, 0x00D96, 0x001E9, 0x001F6, 0x00476, 0x00367, - 0x001F2, 0x01FF6, 0x016BB, 0x007FC, 0x00D5C, 0x00B24, - 0x00C92, 0x0014F, 0x01EA6, 0x01936, 0x00366, 0x0035E, - 0x00116, 0x00FBE, 0x01B5E, 0x0092F, 0x007EE, 0x00CEE, - 0x00B26, 0x0011E, 0x014DF, 0x035DE, 0x00030, 0x00473, - 0x005A2, 0x001BC, 0x000D6, 0x002DA, 0x00B5E, 0x007AA, - 0x002C8, 0x00D94, 0x00D97, 0x001AA, 0x001EE, 0x0003A, - 0x035DF, 0x03D4F, 0x0064F, 0x0064A, 0x02D73, 0x1ABBE, - 0x0B1CF, 0x00F8E, 0x06AFF, 0x0475E, 0x00472, 0x00596, - 0x003E7, 0x0036E, 0x00196, 0x0357E, 0x03F6E, 0x0324E, - 0x0324F, 0x0163B, 0x0192F, 0x001B4, 0x0326A, 0x02C9F, - 0x0021F, 0x0F8FF, 0x064D6, 0x007BE, 0x00DDF, 0x033BC, - 0x033BD, 0x06AEE, 0x00876, 0x07C7E, 0x0B1CE, 0x00D76, - 0x00DDC, 0x001EC, 0x0649B, 0x0B1CD, 0x00F8D, 0x007D6, - 0x01AEE, 0x0163F, 0x03E3E, 0x00A6A, 0x06D7E, 0x0DDDF, - 0x00F7E, 0x00DAE, 0x0036F, 0x00338, 0x0016C, 0x033BF, - 0x036BE, 0x01FF7, 0x01937, 0x01ABA, 0x014D7, 0x0014C, - 0x01F7F, 0x0475F, 0x00040, 0x07FFC, 0x03F6F, 0x00477, - 0x00496, 0x014DE, 0x0649A, 0x064D7, 0x02C9C, 0x0B1CC, - 0x1ABBF, 0x00648, 0x006BA, 0x00364, 0x0032E, 0x00126, - 0x03D4E, 0x02C72, 0x011D6, 0x01638, 0x01934, 0x02C9D, - 0x0016E, 0x021DD, 0x03DFF, 0x001F0, 0x07FFE, 0x043BF, - 0x00D5E, 0x00FAE, 0x0092E, 0x07FFF, 0x0F8FE, 0x02D7F, - 0x043BE, 0x06D7F, 0x008E9, 0x00FFA, 0x0021C, 0x06EEE, - 0x0D5DE, 0x00F57, 0x00CFF, 0x016BA, 0x07FFD, 0x06AFE, - 0x021DE, 0x0DDDE, 0x023AE, 0x00FAF, 0x006D6, 0x0037B, - 0x003E6, 0x001B9, 0x01F1E, 0x033BE, 0x0192E, 0x016BE, - 0x01FB6, 0x01BBA, 0x0019E, 0x03776, 0x03DFE, 0x00046, - 0x00051, 0x0004F, 0x003D7, 0x0033A, 0x00376, 0x00353, - 0x00356, 0x003EA, 0x00054, 0x00339, 0x003E2, 0x0002F, - 0x0064C, 0x00534, 0x00238, 0x001A8, 0x002C6, 0x00D95, - 0x00F52, 0x002CE, 0x007DE, 0x00B2F, 0x000D8, 0x001BA, - 0x0036A, 0x0035F, 0x00127, 0x01EFE, 0x016B8, 0x008EA, - 0x00CEC, 0x007EC, 0x00A6E, 0x00114, 0x01ABE, 0x00FFE, - 0x0037A, 0x0045E, 0x00124, 0x0163E, 0x02D72, 0x00CED, - 0x00B2E, 0x00C96, 0x007A8, 0x001FE, 0x0163A, 0x01FFE, - 0x00038, 0x0057E, 0x0064E, 0x001F8, 0x001E8, 0x002BE, - 0x00DDE, 0x00F56, 0x003DA, 0x00B25, 0x008E8, 0x001F9, - 0x00115, -}; - -static const uint8_t on2avc_cb3_bits[ON2AVC_CB3_CODES] = { - 1, 7, 7, 6, 6, 8, - 10, 10, 8, 10, 10, 6, - 6, 7, 7, 7, 9, 9, - 9, 9, 9, 9, 6, 9, - 9, 8, 14, 12, 10, 10, - 11, 14, 12, 10, 14, 12, - 10, 10, 8, 13, 14, 10, - 10, 10, 11, 13, 11, 12, - 14, 10, 10, 7, 7, 7, - 9, 9, 9, 9, 9, 10, - 7, 9, 9, 7, 7, 7, - 10, 10, 11, 10, 10, 10, - 7, 10, 10, 6, 11, 11, - 8, 9, 10, 11, 12, 10, - 12, 12, 9, 9, 11, 10, - 9, 13, 13, 11, 12, 12, - 12, 9, 13, 13, 10, 10, - 9, 12, 13, 12, 11, 12, - 12, 9, 13, 14, 6, 11, - 11, 9, 8, 10, 12, 11, - 10, 12, 12, 9, 9, 6, - 14, 14, 11, 11, 14, 17, - 16, 12, 15, 15, 11, 11, - 10, 10, 9, 14, 14, 14, - 14, 13, 13, 9, 14, 14, - 10, 16, 15, 11, 12, 14, - 14, 15, 12, 15, 16, 12, - 12, 9, 15, 16, 12, 11, - 13, 13, 14, 12, 15, 16, - 12, 12, 10, 10, 9, 14, - 14, 13, 13, 13, 13, 9, - 13, 15, 7, 15, 14, 11, - 11, 13, 15, 15, 14, 16, - 17, 11, 11, 10, 10, 9, - 14, 14, 13, 13, 13, 14, - 9, 14, 14, 9, 15, 15, - 12, 12, 12, 15, 16, 14, - 15, 15, 12, 12, 10, 15, - 16, 12, 12, 13, 15, 15, - 14, 16, 14, 12, 11, 10, - 10, 9, 13, 14, 13, 13, - 13, 13, 9, 14, 14, 7, - 7, 7, 10, 10, 10, 10, - 10, 10, 7, 10, 10, 6, - 11, 11, 10, 9, 10, 12, - 12, 10, 11, 12, 8, 9, - 10, 10, 9, 13, 13, 12, - 12, 11, 12, 9, 13, 12, - 10, 11, 9, 13, 14, 12, - 12, 12, 11, 9, 13, 13, - 6, 11, 11, 9, 9, 10, - 12, 12, 10, 12, 12, 9, - 9, -}; - -static const uint16_t on2avc_cb3_syms[ON2AVC_CB3_CODES] = { - 0x0000, 0x0002, 0x000E, 0x0011, 0x001F, 0x0020, - 0x0022, 0x002E, 0x00E0, 0x00E2, 0x00EE, 0x00F1, - 0x00FF, 0x0101, 0x010F, 0x0110, 0x0112, 0x011E, - 0x0121, 0x012F, 0x01E1, 0x01EF, 0x01F0, 0x01F2, - 0x01FE, 0x0200, 0x0202, 0x020E, 0x0211, 0x021F, - 0x0220, 0x0222, 0x022E, 0x02E0, 0x02E2, 0x02EE, - 0x02F1, 0x02FF, 0x0E00, 0x0E02, 0x0E0E, 0x0E11, - 0x0E1F, 0x0E20, 0x0E22, 0x0E2E, 0x0EE0, 0x0EE2, - 0x0EEE, 0x0EF1, 0x0EFF, 0x0F01, 0x0F0F, 0x0F10, - 0x0F12, 0x0F1E, 0x0F21, 0x0F2F, 0x0FE1, 0x0FEF, - 0x0FF0, 0x0FF2, 0x0FFE, 0x1001, 0x100F, 0x1010, - 0x1012, 0x101E, 0x1021, 0x102F, 0x10E1, 0x10EF, - 0x10F0, 0x10F2, 0x10FE, 0x1100, 0x1102, 0x110E, - 0x1111, 0x111F, 0x1120, 0x1122, 0x112E, 0x11E0, - 0x11E2, 0x11EE, 0x11F1, 0x11FF, 0x1201, 0x120F, - 0x1210, 0x1212, 0x121E, 0x1221, 0x122F, 0x12E1, - 0x12EF, 0x12F0, 0x12F2, 0x12FE, 0x1E01, 0x1E0F, - 0x1E10, 0x1E12, 0x1E1E, 0x1E21, 0x1E2F, 0x1EE1, - 0x1EEF, 0x1EF0, 0x1EF2, 0x1EFE, 0x1F00, 0x1F02, - 0x1F0E, 0x1F11, 0x1F1F, 0x1F20, 0x1F22, 0x1F2E, - 0x1FE0, 0x1FE2, 0x1FEE, 0x1FF1, 0x1FFF, 0x2000, - 0x2002, 0x200E, 0x2011, 0x201F, 0x2020, 0x2022, - 0x202E, 0x20E0, 0x20E2, 0x20EE, 0x20F1, 0x20FF, - 0x2101, 0x210F, 0x2110, 0x2112, 0x211E, 0x2121, - 0x212F, 0x21E1, 0x21EF, 0x21F0, 0x21F2, 0x21FE, - 0x2200, 0x2202, 0x220E, 0x2211, 0x221F, 0x2220, - 0x2222, 0x222E, 0x22E0, 0x22E2, 0x22EE, 0x22F1, - 0x22FF, 0x2E00, 0x2E02, 0x2E0E, 0x2E11, 0x2E1F, - 0x2E20, 0x2E22, 0x2E2E, 0x2EE0, 0x2EE2, 0x2EEE, - 0x2EF1, 0x2EFF, 0x2F01, 0x2F0F, 0x2F10, 0x2F12, - 0x2F1E, 0x2F21, 0x2F2F, 0x2FE1, 0x2FEF, 0x2FF0, - 0x2FF2, 0x2FFE, 0xE000, 0xE002, 0xE00E, 0xE011, - 0xE01F, 0xE020, 0xE022, 0xE02E, 0xE0E0, 0xE0E2, - 0xE0EE, 0xE0F1, 0xE0FF, 0xE101, 0xE10F, 0xE110, - 0xE112, 0xE11E, 0xE121, 0xE12F, 0xE1E1, 0xE1EF, - 0xE1F0, 0xE1F2, 0xE1FE, 0xE200, 0xE202, 0xE20E, - 0xE211, 0xE21F, 0xE220, 0xE222, 0xE22E, 0xE2E0, - 0xE2E2, 0xE2EE, 0xE2F1, 0xE2FF, 0xEE00, 0xEE02, - 0xEE0E, 0xEE11, 0xEE1F, 0xEE20, 0xEE22, 0xEE2E, - 0xEEE0, 0xEEE2, 0xEEEE, 0xEEF1, 0xEEFF, 0xEF01, - 0xEF0F, 0xEF10, 0xEF12, 0xEF1E, 0xEF21, 0xEF2F, - 0xEFE1, 0xEFEF, 0xEFF0, 0xEFF2, 0xEFFE, 0xF001, - 0xF00F, 0xF010, 0xF012, 0xF01E, 0xF021, 0xF02F, - 0xF0E1, 0xF0EF, 0xF0F0, 0xF0F2, 0xF0FE, 0xF100, - 0xF102, 0xF10E, 0xF111, 0xF11F, 0xF120, 0xF122, - 0xF12E, 0xF1E0, 0xF1E2, 0xF1EE, 0xF1F1, 0xF1FF, - 0xF201, 0xF20F, 0xF210, 0xF212, 0xF21E, 0xF221, - 0xF22F, 0xF2E1, 0xF2EF, 0xF2F0, 0xF2F2, 0xF2FE, - 0xFE01, 0xFE0F, 0xFE10, 0xFE12, 0xFE1E, 0xFE21, - 0xFE2F, 0xFEE1, 0xFEEF, 0xFEF0, 0xFEF2, 0xFEFE, - 0xFF00, 0xFF02, 0xFF0E, 0xFF11, 0xFF1F, 0xFF20, - 0xFF22, 0xFF2E, 0xFFE0, 0xFFE2, 0xFFEE, 0xFFF1, - 0xFFFF, -}; - -#define ON2AVC_CB4_CODES 313 -static const uint32_t on2avc_cb4_codes[ON2AVC_CB4_CODES] = { - 0x000A, 0x013B, 0x0127, 0x0004, 0x0015, 0x012C, - 0x065F, 0x08CD, 0x016A, 0x08E7, 0x06BA, 0x001B, - 0x001D, 0x0018, 0x000A, 0x0002, 0x00C0, 0x012B, - 0x00CE, 0x013C, 0x012A, 0x012D, 0x0020, 0x0128, - 0x0121, 0x00FC, 0x066B, 0x0472, 0x010A, 0x004E, - 0x06AE, 0x063F, 0x1ABF, 0x0B4E, 0x084E, 0x1ABE, - 0x010E, 0x0094, 0x00C8, 0x0464, 0x069A, 0x00C9, - 0x00FA, 0x041B, 0x2FDE, 0x08CB, 0x05B7, 0x1ABD, - 0x066A, 0x008D, 0x00F8, 0x0003, 0x001A, 0x001E, - 0x0120, 0x011E, 0x0138, 0x0125, 0x0170, 0x00C4, - 0x000B, 0x013E, 0x00C5, 0x000C, 0x000E, 0x001C, - 0x00FE, 0x009C, 0x010F, 0x0115, 0x009F, 0x008C, - 0x0008, 0x002E, 0x00CF, 0x001C, 0x0110, 0x002F, - 0x002C, 0x0002, 0x0116, 0x01FE, 0x032D, 0x00CB, - 0x030D, 0x02EC, 0x002E, 0x0037, 0x00CF, 0x0086, - 0x00C8, 0x032C, 0x031E, 0x01AC, 0x030C, 0x02ED, - 0x035C, 0x013A, 0x02FF, 0x02E2, 0x00BE, 0x00CE, - 0x0126, 0x0356, 0x034E, 0x0347, 0x025F, 0x0306, - 0x02DA, 0x0168, 0x02E7, 0x020F, 0x0016, 0x0081, - 0x0114, 0x0024, 0x001B, 0x010C, 0x03FE, 0x027F, - 0x0084, 0x02F9, 0x0237, 0x0000, 0x001A, 0x011A, - 0x05A6, 0x04A6, 0x00F9, 0x00CC, 0x05B6, 0x0BF6, - 0x0B96, 0x0446, 0x08CE, 0x007F, 0x002C, 0x000E, - 0x0080, 0x00C9, 0x00BA, 0x035E, 0x03EF, 0x0345, - 0x02FE, 0x02FB, 0x02E6, 0x00D2, 0x021C, 0x0238, - 0x06BB, 0x0B97, 0x007E, 0x01AA, 0x023A, 0x05BE, - 0x031D, 0x094E, 0x1ABC, 0x0948, 0x088E, 0x02E4, - 0x0273, 0x084C, 0x08CC, 0x094B, 0x02D2, 0x023B, - 0x043E, 0x2FDF, 0x063E, 0x109B, 0x08CA, 0x08E6, - 0x02DE, 0x02F4, 0x00D4, 0x002D, 0x00CA, 0x020E, - 0x0344, 0x02FD, 0x030F, 0x02EE, 0x02D6, 0x0123, - 0x02F7, 0x03ED, 0x009E, 0x05CA, 0x060E, 0x000D, - 0x004D, 0x0444, 0x043F, 0x094A, 0x05FA, 0x109A, - 0x0B4F, 0x00FD, 0x0117, 0x0096, 0x0082, 0x0122, - 0x025D, 0x0304, 0x034C, 0x027B, 0x035B, 0x02FC, - 0x00FC, 0x035F, 0x03EE, 0x088B, 0x0C1E, 0x088A, - 0x02F5, 0x0272, 0x17EE, 0x0C1F, 0x084F, 0x088F, - 0x069B, 0x0949, 0x023F, 0x02E3, 0x07FE, 0x041A, - 0x0B7E, 0x027A, 0x0336, 0x07FF, 0x08CF, 0x094F, - 0x065E, 0x0B7F, 0x02DD, 0x0212, 0x01FB, 0x00C6, - 0x0095, 0x00D0, 0x023E, 0x025C, 0x02FC, 0x032E, - 0x025E, 0x021E, 0x00BC, 0x021D, 0x035A, 0x0007, - 0x000F, 0x0006, 0x00C2, 0x000C, 0x00BD, 0x00CD, - 0x0113, 0x0118, 0x001D, 0x00CA, 0x008E, 0x0014, - 0x010D, 0x0085, 0x0001, 0x003E, 0x008F, 0x0236, - 0x030E, 0x00FF, 0x025E, 0x0337, 0x000A, 0x0026, - 0x010B, 0x009D, 0x012E, 0x025F, 0x02EF, 0x0305, - 0x02DC, 0x027E, 0x02FE, 0x0124, 0x034F, 0x003E, - 0x004F, 0x00BC, 0x016C, 0x02D7, 0x03EC, 0x02FA, - 0x02F8, 0x02F6, 0x01FA, 0x00CC, 0x02FF, 0x0334, - 0x001E, 0x004C, 0x0112, 0x0036, 0x0022, 0x00FE, - 0x031C, 0x0346, 0x0108, 0x020C, 0x001E, 0x0012, - 0x0026, -}; - -static const uint8_t on2avc_cb4_bits[ON2AVC_CB4_CODES] = { - 4, 9, 9, 6, 6, 9, - 11, 12, 9, 12, 11, 6, - 5, 6, 6, 6, 8, 9, - 8, 9, 9, 9, 6, 9, - 9, 9, 11, 11, 9, 9, - 11, 11, 13, 12, 12, 13, - 9, 9, 9, 11, 11, 9, - 9, 12, 14, 12, 11, 13, - 11, 9, 9, 6, 6, 6, - 9, 9, 9, 9, 9, 8, - 6, 9, 8, 6, 6, 6, - 8, 9, 9, 9, 9, 9, - 6, 9, 8, 5, 9, 9, - 6, 7, 9, 9, 10, 9, - 10, 10, 7, 6, 9, 9, - 8, 10, 10, 9, 10, 10, - 10, 9, 11, 10, 9, 9, - 9, 10, 10, 10, 10, 10, - 10, 9, 10, 11, 6, 9, - 9, 7, 7, 9, 10, 10, - 9, 10, 10, 7, 7, 9, - 11, 11, 9, 9, 11, 12, - 12, 11, 12, 12, 9, 9, - 9, 8, 8, 10, 11, 10, - 11, 10, 10, 8, 11, 10, - 11, 12, 12, 9, 10, 11, - 10, 12, 13, 12, 12, 10, - 10, 12, 12, 12, 10, 10, - 12, 14, 11, 13, 12, 12, - 10, 10, 8, 9, 8, 11, - 10, 11, 10, 10, 10, 9, - 10, 11, 9, 11, 11, 9, - 9, 11, 12, 12, 11, 13, - 12, 9, 9, 9, 9, 9, - 11, 10, 10, 10, 10, 11, - 8, 10, 11, 12, 12, 12, - 10, 10, 13, 12, 12, 12, - 11, 12, 10, 10, 11, 12, - 12, 10, 10, 11, 12, 12, - 11, 12, 10, 10, 9, 8, - 9, 8, 10, 11, 10, 10, - 11, 11, 8, 11, 10, 6, - 6, 6, 8, 9, 9, 9, - 9, 9, 6, 9, 9, 6, - 9, 9, 7, 6, 9, 10, - 10, 9, 10, 10, 7, 7, - 9, 9, 9, 11, 10, 10, - 10, 10, 10, 9, 10, 11, - 9, 9, 9, 10, 11, 10, - 10, 10, 9, 8, 10, 10, - 5, 9, 9, 6, 7, 9, - 10, 10, 9, 11, 10, 7, - 6, -}; - -static const uint16_t on2avc_cb4_syms[ON2AVC_CB4_CODES] = { - 0x0000, 0x0002, 0x000E, 0x0011, 0x001F, 0x0020, - 0x0022, 0x002E, 0x00E0, 0x00E2, 0x00EE, 0x00F1, - 0x00FF, 0x0101, 0x010F, 0x0110, 0x0112, 0x011E, - 0x0121, 0x012F, 0x01E1, 0x01EF, 0x01F0, 0x01F2, - 0x01FE, 0x0200, 0x0202, 0x020E, 0x0211, 0x021F, - 0x0220, 0x0222, 0x022E, 0x02E0, 0x02E2, 0x02EE, - 0x02F1, 0x02FF, 0x0E00, 0x0E02, 0x0E0E, 0x0E11, - 0x0E1F, 0x0E20, 0x0E22, 0x0E2E, 0x0EE0, 0x0EE2, - 0x0EEE, 0x0EF1, 0x0EFF, 0x0F01, 0x0F0F, 0x0F10, - 0x0F12, 0x0F1E, 0x0F21, 0x0F2F, 0x0FE1, 0x0FEF, - 0x0FF0, 0x0FF2, 0x0FFE, 0x1001, 0x100F, 0x1010, - 0x1012, 0x101E, 0x1021, 0x102F, 0x10E1, 0x10EF, - 0x10F0, 0x10F2, 0x10FE, 0x1100, 0x1102, 0x110E, - 0x1111, 0x111F, 0x1120, 0x1122, 0x112E, 0x11E0, - 0x11E2, 0x11EE, 0x11F1, 0x11FF, 0x1201, 0x120F, - 0x1210, 0x1212, 0x121E, 0x1221, 0x122F, 0x12E1, - 0x12EF, 0x12F0, 0x12F2, 0x12FE, 0x1E01, 0x1E0F, - 0x1E10, 0x1E12, 0x1E1E, 0x1E21, 0x1E2F, 0x1EE1, - 0x1EEF, 0x1EF0, 0x1EF2, 0x1EFE, 0x1F00, 0x1F02, - 0x1F0E, 0x1F11, 0x1F1F, 0x1F20, 0x1F22, 0x1F2E, - 0x1FE0, 0x1FE2, 0x1FEE, 0x1FF1, 0x1FFF, 0x2000, - 0x2002, 0x200E, 0x2011, 0x201F, 0x2020, 0x2022, - 0x202E, 0x20E0, 0x20E2, 0x20EE, 0x20F1, 0x20FF, - 0x2101, 0x210F, 0x2110, 0x2112, 0x211E, 0x2121, - 0x212F, 0x21E1, 0x21EF, 0x21F0, 0x21F2, 0x21FE, - 0x2200, 0x2202, 0x220E, 0x2211, 0x221F, 0x2220, - 0x2222, 0x222E, 0x22E0, 0x22E2, 0x22EE, 0x22F1, - 0x22FF, 0x2E00, 0x2E02, 0x2E0E, 0x2E11, 0x2E1F, - 0x2E20, 0x2E22, 0x2E2E, 0x2EE0, 0x2EE2, 0x2EEE, - 0x2EF1, 0x2EFF, 0x2F01, 0x2F0F, 0x2F10, 0x2F12, - 0x2F1E, 0x2F21, 0x2F2F, 0x2FE1, 0x2FEF, 0x2FF0, - 0x2FF2, 0x2FFE, 0xE000, 0xE002, 0xE00E, 0xE011, - 0xE01F, 0xE020, 0xE022, 0xE02E, 0xE0E0, 0xE0E2, - 0xE0EE, 0xE0F1, 0xE0FF, 0xE101, 0xE10F, 0xE110, - 0xE112, 0xE11E, 0xE121, 0xE12F, 0xE1E1, 0xE1EF, - 0xE1F0, 0xE1F2, 0xE1FE, 0xE200, 0xE202, 0xE20E, - 0xE211, 0xE21F, 0xE220, 0xE222, 0xE22E, 0xE2E0, - 0xE2E2, 0xE2EE, 0xE2F1, 0xE2FF, 0xEE00, 0xEE02, - 0xEE0E, 0xEE11, 0xEE1F, 0xEE20, 0xEE22, 0xEE2E, - 0xEEE0, 0xEEE2, 0xEEEE, 0xEEF1, 0xEEFF, 0xEF01, - 0xEF0F, 0xEF10, 0xEF12, 0xEF1E, 0xEF21, 0xEF2F, - 0xEFE1, 0xEFEF, 0xEFF0, 0xEFF2, 0xEFFE, 0xF001, - 0xF00F, 0xF010, 0xF012, 0xF01E, 0xF021, 0xF02F, - 0xF0E1, 0xF0EF, 0xF0F0, 0xF0F2, 0xF0FE, 0xF100, - 0xF102, 0xF10E, 0xF111, 0xF11F, 0xF120, 0xF122, - 0xF12E, 0xF1E0, 0xF1E2, 0xF1EE, 0xF1F1, 0xF1FF, - 0xF201, 0xF20F, 0xF210, 0xF212, 0xF21E, 0xF221, - 0xF22F, 0xF2E1, 0xF2EF, 0xF2F0, 0xF2F2, 0xF2FE, - 0xFE01, 0xFE0F, 0xFE10, 0xFE12, 0xFE1E, 0xFE21, - 0xFE2F, 0xFEE1, 0xFEEF, 0xFEF0, 0xFEF2, 0xFEFE, - 0xFF00, 0xFF02, 0xFF0E, 0xFF11, 0xFF1F, 0xFF20, - 0xFF22, 0xFF2E, 0xFFE0, 0xFFE2, 0xFFEE, 0xFFF1, - 0xFFFF, -}; - -#define ON2AVC_CB5_CODES 1201 -static const uint32_t on2avc_cb5_codes[ON2AVC_CB5_CODES] = { - 0x00000, 0x000D6, 0x000E2, 0x00044, 0x0009E, 0x0009A, - 0x0003A, 0x004E6, 0x00A29, 0x007FE, 0x0024A, 0x004EE, - 0x00496, 0x001EE, 0x001C8, 0x008FA, 0x0050F, 0x001EF, - 0x00486, 0x00906, 0x00904, 0x0003E, 0x00094, 0x000A6, - 0x00046, 0x00061, 0x0012A, 0x0020D, 0x00060, 0x00066, - 0x00452, 0x00692, 0x0087E, 0x00242, 0x0050C, 0x008BE, - 0x0024C, 0x0045A, 0x0025A, 0x001C6, 0x002EE, 0x00294, - 0x006CE, 0x001EC, 0x00492, 0x00690, 0x00055, 0x00474, - 0x0063E, 0x00524, 0x04802, 0x04DC5, 0x00DEF, 0x01A62, - 0x00E6A, 0x00A7F, 0x027FB, 0x034B5, 0x036C5, 0x00A3A, - 0x036C6, 0x0219B, 0x00296, 0x0090F, 0x027FA, 0x028C8, - 0x0052A, 0x0127E, 0x0598E, 0x034B4, 0x00C78, 0x0146E, - 0x00F5F, 0x00BAA, 0x00432, 0x0FF63, 0x0598F, 0x0091C, - 0x00257, 0x0240B, 0x014E6, 0x00E6B, 0x05173, 0x01647, - 0x007F9, 0x022F3, 0x04DC6, 0x022F2, 0x0087F, 0x036C7, - 0x01AB9, 0x00C79, 0x06944, 0x043C6, 0x0043E, 0x00218, - 0x031C4, 0x014E5, 0x0093E, 0x0FF62, 0x3FAE0, 0x00328, - 0x00228, 0x01428, 0x03FEA, 0x007A3, 0x034B3, 0x0D23B, - 0x00B29, 0x01AB8, 0x028C7, 0x0598D, 0x00B28, 0x0149B, - 0x0149A, 0x008EE, 0x027F9, 0x07FC0, 0x00CFE, 0x0025E, - 0x01CBB, 0x026EF, 0x00512, 0x0297B, 0x05172, 0x00D36, - 0x00FCA, 0x01EA5, 0x00D86, 0x01FC5, 0x031C3, 0x02CD6, - 0x00276, 0x01F8A, 0x04801, 0x00B2A, 0x00329, 0x00FC9, - 0x03F0C, 0x00D35, 0x01971, 0x04DC4, 0x036C4, 0x00A4F, - 0x00FEA, 0x01FC4, 0x0122A, 0x00058, 0x001CA, 0x0013A, - 0x0005E, 0x00054, 0x0053E, 0x0039E, 0x006C6, 0x00284, - 0x001C2, 0x0087A, 0x0020E, 0x0050E, 0x006F2, 0x00288, - 0x0029E, 0x00457, 0x006F9, 0x005D3, 0x00248, 0x008F7, - 0x00068, 0x0069D, 0x00497, 0x0005F, 0x0091D, 0x00738, - 0x00057, 0x0005A, 0x00A3E, 0x009CF, 0x00D3E, 0x00D87, - 0x00C6B, 0x00CBD, 0x003F6, 0x00A74, 0x00C6E, 0x0049C, - 0x012FE, 0x0137F, 0x00DBB, 0x010DA, 0x00CAB, 0x0127F, - 0x00056, 0x00A2A, 0x0083E, 0x00040, 0x00BAE, 0x00BA2, - 0x0012E, 0x006F0, 0x0096E, 0x0022C, 0x00FDE, 0x011EB, - 0x01ABE, 0x007EA, 0x014E7, 0x011F2, 0x00256, 0x009FC, - 0x0297C, 0x01C13, 0x006F4, 0x00B26, 0x0144E, 0x021EE, - 0x001C0, 0x00707, 0x00B3F, 0x00244, 0x00E0B, 0x02CD8, - 0x034B6, 0x00B2B, 0x00914, 0x027FD, 0x028CA, 0x01396, - 0x014EB, 0x01972, 0x01B71, 0x013BE, 0x00D9A, 0x00D3F, - 0x009C9, 0x014EA, 0x031C6, 0x022F5, 0x027FC, 0x0240D, - 0x0297D, 0x006F5, 0x02CD7, 0x0396A, 0x0018C, 0x04DC7, - 0x028CB, 0x007E7, 0x0D23C, 0x043C8, 0x008FC, 0x00C7A, - 0x031C7, 0x018EB, 0x0396B, 0x0D23D, 0x036C9, 0x01973, - 0x018EA, 0x07FC1, 0x08FD8, 0x01673, 0x0067C, 0x027FE, - 0x036C8, 0x004BE, 0x08FD9, 0x07FC2, 0x009B6, 0x00148, - 0x026F0, 0x05174, 0x0071C, 0x07279, 0x08FD7, 0x005D4, - 0x00E0A, 0x01A63, 0x01F8B, 0x0114E, 0x01ABA, 0x05990, - 0x043C7, 0x01BEE, 0x3FAE1, 0x1FE94, 0x01CBE, 0x006F3, - 0x018E7, 0x0240C, 0x006FA, 0x03967, 0x08FD6, 0x0045B, - 0x00DBA, 0x01A65, 0x03969, 0x00CFF, 0x0067E, 0x026F1, - 0x028C9, 0x022F4, 0x018D2, 0x01B70, 0x011EA, 0x00BBF, - 0x00B3E, 0x0144D, 0x00D3D, 0x0146F, 0x01A64, 0x01FFF, - 0x01B6F, 0x03968, 0x024EB, 0x00656, 0x031C5, 0x0727A, - 0x0003C, 0x00D22, 0x00D99, 0x0021A, 0x00706, 0x007EE, - 0x0013E, 0x00CBC, 0x01C12, 0x01A66, 0x0022E, 0x00E77, - 0x01672, 0x004D8, 0x006D3, 0x01CBF, 0x01ABB, 0x008BF, - 0x00E76, 0x01BEF, 0x01FC6, 0x001B2, 0x00736, 0x008FB, - 0x0021D, 0x000D7, 0x04804, 0x06948, 0x00D37, 0x0396E, - 0x06949, 0x0120A, 0x03F0F, 0x1437E, 0x043CB, 0x028D0, - 0x0A2BE, 0x08FDD, 0x05996, 0x022F6, 0x1FE96, 0x0FF64, - 0x026F2, 0x028CF, 0x04DCB, 0x03F0E, 0x00A3F, 0x05178, - 0x05995, 0x00BA3, 0x00A4A, 0x07FC8, 0x0727E, 0x007AA, - 0x003D0, 0x0599A, 0x02CDB, 0x034BB, 0x07FC9, 0x0D261, - 0x04805, 0x04806, 0x0727F, 0x022F7, 0x018FE, 0x0240F, - 0x02CDA, 0x031CB, 0x04DCC, 0x034BA, 0x036CB, 0x0052B, - 0x05997, 0x036CE, 0x00907, 0x08FDF, 0x043CD, 0x00E7E, - 0x0517A, 0x04DCD, 0x0197E, 0x0A2BF, 0x028D1, 0x04807, - 0x028D2, 0x04808, 0x0D262, 0x024ED, 0x01ABF, 0x072C0, - 0x1437F, 0x034BE, 0x05179, 0x144F0, 0x072C1, 0x029C1, - 0x08FDE, 0x043CC, 0x023AE, 0x00A3B, 0x1FE97, 0x08FE1, - 0x0142A, 0x006AC, 0x04809, 0x024EE, 0x00C7B, 0x3FAE3, - 0x08FE2, 0x01F8F, 0x0A2C0, 0x023AF, 0x08FE3, 0x02416, - 0x072C2, 0x0FF65, 0x00FCB, 0x08FE0, 0x144F1, 0x01EA6, - 0x00590, 0x04DCE, 0x0396F, 0x01FC7, 0x05991, 0x3FAE2, - 0x0096C, 0x00657, 0x034B8, 0x05992, 0x0240E, 0x0A2BC, - 0x08FDA, 0x0114F, 0x0727C, 0x06945, 0x05175, 0x01B72, - 0x0727B, 0x07FC3, 0x01472, 0x0A2BB, 0x0D23E, 0x00CBE, - 0x00636, 0x034B7, 0x043C9, 0x008AA, 0x08FDB, 0x0D23F, - 0x02852, 0x0727D, 0x05994, 0x00E3E, 0x031CA, 0x06947, - 0x04DC8, 0x02CD9, 0x1FE95, 0x0D260, 0x028CD, 0x024EC, - 0x04803, 0x07FC4, 0x01976, 0x028CC, 0x05993, 0x07FC5, - 0x027FF, 0x06946, 0x03FEB, 0x03F0D, 0x0096D, 0x08FDC, - 0x04DC9, 0x0097E, 0x003D3, 0x0A2BD, 0x0286E, 0x07FC6, - 0x07FC7, 0x034B9, 0x029C0, 0x01F8E, 0x04DCA, 0x05177, - 0x01977, 0x03FEE, 0x0297E, 0x028CE, 0x036CA, 0x05176, - 0x0297F, 0x00596, 0x02853, 0x043CA, 0x0090E, 0x144FA, - 0x0D26A, 0x008AB, 0x000CE, 0x072C3, 0x034BF, 0x02417, - 0x3FAF0, 0x3FAEF, 0x026F3, 0x1FEA0, 0x3FAF1, 0x1FE9F, - 0x0D269, 0x0FF6A, 0x1FE9D, 0x029C6, 0x3FAEE, 0x1FE9E, - 0x036CF, 0x001AA, 0x0480E, 0x0A2C7, 0x000A0, 0x07FCE, - 0x3FAF4, 0x008F8, 0x3FAF5, 0x144FB, 0x00A16, 0x024EF, - 0x04DD3, 0x0694E, 0x1FEA2, 0x3FAF7, 0x3FAF6, 0x0D26B, - 0x04DD2, 0x3FAF2, 0x1FEA1, 0x08FE6, 0x0122B, 0x08FE7, - 0x0480F, 0x00C6F, 0x0FF6B, 0x3FAF3, 0x008EF, 0x00C7E, - 0x3FAF8, 0x1FEA4, 0x00DF6, 0x00362, 0x0694F, 0x0599B, - 0x0142B, 0x1FEA6, 0x1FEA5, 0x03FEF, 0x07FCF, 0x1FEA7, - 0x3FAF9, 0x029C7, 0x0D26E, 0x144FE, 0x01C3E, 0x1FEA3, - 0x0A2CA, 0x01CE6, 0x0049E, 0x043CF, 0x04EFE, 0x0036B, - 0x3FAFE, 0x11F32, 0x01EAE, 0x1FEAA, 0x0D26F, 0x049D2, - 0x02EAE, 0x0356A, 0x08FEA, 0x07ABE, 0x08FEB, 0x3FAFF, - 0x1FEAB, 0x0292E, 0x144FF, 0x3FAFA, 0x08FE8, 0x01EA7, - 0x0B27A, 0x0A2CB, 0x0164E, 0x3FAFB, 0x08FE9, 0x021EF, - 0x00A76, 0x1FE9A, 0x144F2, 0x029C3, 0x3FAE8, 0x3FAE7, - 0x014EE, 0x03F12, 0x0D264, 0x08FE4, 0x0FF67, 0x1FE9B, - 0x144F3, 0x0FF66, 0x0D263, 0x3FAE5, 0x3FAE4, 0x029C2, - 0x031FE, 0x0A2C1, 0x1FE98, 0x01FD6, 0x3FAE6, 0x1FE99, - 0x01473, 0x00D9B, 0x144F5, 0x144F4, 0x00FD2, 0x0036A, - 0x043CE, 0x03F13, 0x0517B, 0x0D267, 0x144F6, 0x01756, - 0x0A2C2, 0x144F8, 0x144F7, 0x0480A, 0x0FF68, 0x0D265, - 0x01B73, 0x0D266, 0x3FAE9, 0x01A67, 0x00493, 0x0694B, - 0x0694A, 0x00082, 0x03F7E, 0x04DCF, 0x009B7, 0x3FAEB, - 0x1FE9C, 0x0071D, 0x028D3, 0x0D268, 0x0A2C5, 0x0A2C6, - 0x3FAED, 0x3FAEC, 0x08FE5, 0x07FCA, 0x3FAEA, 0x144F9, - 0x0A2C3, 0x00D3C, 0x07FCB, 0x0480B, 0x009CA, 0x0FF69, - 0x0A2C4, 0x0091E, 0x007EB, 0x1FE85, 0x0FF56, 0x0091F, - 0x0019E, 0x0693A, 0x0593E, 0x020FC, 0x1FE86, 0x0FF57, - 0x027F4, 0x0146A, 0x04BFC, 0x0CBF9, 0x0CBF8, 0x1FE83, - 0x3F7F5, 0x08F9E, 0x3F7F6, 0x1FE84, 0x036C0, 0x00098, - 0x0593C, 0x071F9, 0x0006E, 0x0593F, 0x03963, 0x00A3C, - 0x13BFD, 0x1FE89, 0x007F2, 0x00FD3, 0x03F08, 0x03D5E, - 0x034A9, 0x13BFF, 0x13BFE, 0x071FA, 0x011E8, 0x1FE87, - 0x3F7F7, 0x0FF58, 0x01B66, 0x07FB8, 0x05168, 0x0070E, - 0x0FF59, 0x1FE88, 0x009B3, 0x00BBC, 0x1FE8B, 0x3F7F8, - 0x00FE6, 0x004FC, 0x0CBFC, 0x03FE6, 0x022F0, 0x1FE8C, - 0x0CBFD, 0x01CE7, 0x08F9F, 0x0FF5A, 0x071FD, 0x1FE8A, - 0x071FB, 0x14378, 0x01AB4, 0x0CBFB, 0x0CBFA, 0x036C1, - 0x0037E, 0x05980, 0x071FC, 0x00D5E, 0x3F7FC, 0x08FD0, - 0x014EF, 0x3F7FE, 0x3F7FD, 0x01CFE, 0x01FBE, 0x05982, - 0x1437A, 0x04BFD, 0x1FE8E, 0x3F7FF, 0x071FF, 0x0FF5B, - 0x1FE8D, 0x3F7F9, 0x14379, 0x047F7, 0x05981, 0x071FE, - 0x014E2, 0x3F7FB, 0x3F7FA, 0x02CCE, 0x0037F, 0x0A27E, - 0x3D5FA, 0x02CCC, 0x1FE80, 0x1FD7E, 0x01496, 0x018E4, - 0x3D5FB, 0x05164, 0x070FD, 0x3D5FC, 0x11F33, 0x0277E, - 0x0FF54, 0x08F98, 0x07FB6, 0x070FC, 0x026E8, 0x07FB7, - 0x034A6, 0x0356B, 0x3D5F9, 0x3D5F8, 0x034A8, 0x0114C, - 0x3F7F0, 0x3D5FF, 0x00C74, 0x0024D, 0x05167, 0x049D3, - 0x0292F, 0x08F9C, 0x3F7F1, 0x01CB6, 0x03962, 0x070FF, - 0x08F9D, 0x08F9A, 0x3D5FD, 0x0A2B0, 0x024E8, 0x070FE, - 0x3D5FE, 0x01A5E, 0x00392, 0x08F9B, 0x05166, 0x00099, - 0x06939, 0x06938, 0x009B2, 0x0C7FE, 0x3F7F4, 0x007F7, - 0x011D6, 0x02EAF, 0x028BE, 0x071F8, 0x0C7FF, 0x1FE82, - 0x047F6, 0x06936, 0x3F7F3, 0x3F7F2, 0x1FE81, 0x026EA, - 0x0C7FC, 0x0B27B, 0x009FA, 0x0C7FD, 0x13BFC, 0x007A8, - 0x000D4, 0x08FD1, 0x0D234, 0x00D34, 0x07274, 0x05988, - 0x00F5C, 0x0516D, 0x0516E, 0x0516C, 0x036C3, 0x0A2B4, - 0x0D235, 0x036C2, 0x034AC, 0x0D233, 0x07FBA, 0x034AB, - 0x0A2B3, 0x1437D, 0x1437C, 0x00B3B, 0x07273, 0x0516B, - 0x00D84, 0x009FB, 0x0693F, 0x0598A, 0x007F8, 0x005D6, - 0x047FB, 0x024EA, 0x026EC, 0x0516F, 0x047FC, 0x031A7, - 0x01397, 0x026ED, 0x02975, 0x02CD1, 0x034AD, 0x07275, - 0x027F6, 0x05989, 0x043C1, 0x0693E, 0x00454, 0x034AE, - 0x043C2, 0x007F6, 0x0A2B7, 0x07FBB, 0x02408, 0x0598B, - 0x047FD, 0x01B6A, 0x04DC1, 0x0FF5F, 0x07FBC, 0x01B6B, - 0x07277, 0x0D236, 0x020FD, 0x01B68, 0x0A2B5, 0x0FF5E, - 0x02976, 0x043C3, 0x02977, 0x0A2B6, 0x012DE, 0x07276, - 0x03FE9, 0x01B69, 0x00A4C, 0x0FF60, 0x1FE93, 0x013BC, - 0x00592, 0x02978, 0x02CD3, 0x00D8E, 0x0D237, 0x05170, - 0x01FC1, 0x028C2, 0x06941, 0x0D238, 0x07278, 0x034AF, - 0x06940, 0x00E5E, 0x08FD2, 0x07FBD, 0x020FE, 0x007E6, - 0x043C4, 0x02CD2, 0x0166E, 0x0CBFF, 0x0CBFE, 0x00A5C, - 0x005D0, 0x026EB, 0x047F8, 0x01F88, 0x1FE90, 0x1FE8F, - 0x00C68, 0x021EC, 0x0A2B1, 0x0D230, 0x04BFE, 0x0693B, - 0x028BF, 0x028C0, 0x07270, 0x0FF5C, 0x00E08, 0x00360, - 0x0436C, 0x05983, 0x009BE, 0x0FF5D, 0x1FE91, 0x01A60, - 0x04BFF, 0x0A2B2, 0x0436E, 0x03F0A, 0x07FB9, 0x05984, - 0x01FC0, 0x1FE92, 0x1437B, 0x01646, 0x03F09, 0x0693C, - 0x027F5, 0x047F9, 0x034AA, 0x0D231, 0x0436D, 0x01AB6, - 0x047FA, 0x07271, 0x00CFA, 0x006CF, 0x07272, 0x05986, - 0x00B3A, 0x00654, 0x028C1, 0x0436F, 0x02CD0, 0x03FE8, - 0x05987, 0x043C0, 0x0146B, 0x02974, 0x031A6, 0x02CCF, - 0x03964, 0x04DC0, 0x0516A, 0x05985, 0x05169, 0x02406, - 0x003D6, 0x0D232, 0x0693D, 0x0005C, 0x006F6, 0x0086E, - 0x00062, 0x0005B, 0x006F1, 0x007E0, 0x00D98, 0x00BBE, - 0x00E72, 0x00D8F, 0x004DA, 0x0137B, 0x0137A, 0x00386, - 0x00A7E, 0x00C6A, 0x00CBA, 0x00F5E, 0x00F5D, 0x013BD, - 0x00064, 0x009CE, 0x008EC, 0x0003B, 0x00F56, 0x00CAA, - 0x00246, 0x008ED, 0x0086C, 0x001ED, 0x00C77, 0x0240A, - 0x01B6D, 0x0086F, 0x02CD5, 0x01FC3, 0x0073E, 0x005D2, - 0x01970, 0x014E4, 0x00456, 0x00B22, 0x0114D, 0x02198, - 0x00138, 0x0069C, 0x00737, 0x0020C, 0x00A4E, 0x04DC2, - 0x018E6, 0x00E1E, 0x006D2, 0x047FF, 0x02979, 0x01FFE, - 0x04800, 0x021ED, 0x028C6, 0x00917, 0x01671, 0x01CFF, - 0x00CFB, 0x00FE7, 0x00A1A, 0x0146D, 0x01670, 0x01B6E, - 0x0137E, 0x006D1, 0x01FFD, 0x028C5, 0x00176, 0x05171, - 0x0219A, 0x0023C, 0x0A2BA, 0x043C5, 0x006F8, 0x006DF, - 0x01EA4, 0x01CBA, 0x027F8, 0x0FF61, 0x08FD5, 0x0177B, - 0x02199, 0x0D23A, 0x03966, 0x0297A, 0x00A38, 0x0177A, - 0x01A61, 0x00597, 0x07FBF, 0x04DC3, 0x007F4, 0x00196, - 0x034B0, 0x03F0B, 0x008F6, 0x0598C, 0x08FD3, 0x003D2, - 0x006D0, 0x01FC2, 0x031C1, 0x026EE, 0x0A2B9, 0x0D239, - 0x0175F, 0x0175E, 0x031C0, 0x06942, 0x01FF6, 0x00A3D, - 0x0166F, 0x027F7, 0x009C8, 0x0A2B8, 0x07FBE, 0x00734, - 0x00FC6, 0x03965, 0x06943, 0x010CF, 0x006DE, 0x02CD4, - 0x08FD4, 0x034B2, 0x01CB8, 0x028C3, 0x01FFC, 0x0041E, - 0x0146C, 0x01B6C, 0x00C76, 0x00B3C, 0x010CE, 0x022F1, - 0x0144C, 0x012DF, 0x01436, 0x0073A, 0x034B1, 0x031C2, - 0x00042, 0x00DEE, 0x00B3D, 0x001CC, 0x00A17, 0x007E8, - 0x0021C, 0x00A28, 0x01CB9, 0x02409, 0x00916, 0x020FF, - 0x047FE, 0x00726, 0x00238, 0x011E9, 0x01AB7, 0x0071E, - 0x00FC8, 0x028C4, 0x00D85, 0x00239, 0x008EA, 0x007A2, - 0x0012C, -}; - -static const uint8_t on2avc_cb5_bits[ON2AVC_CB5_CODES] = { - 1, 8, 8, 7, 8, 8, - 6, 11, 12, 11, 10, 11, - 11, 9, 9, 12, 11, 9, - 11, 12, 12, 6, 8, 8, - 7, 7, 9, 10, 7, 7, - 11, 11, 12, 10, 11, 12, - 10, 11, 10, 9, 10, 10, - 11, 9, 11, 11, 7, 11, - 11, 11, 15, 15, 12, 13, - 12, 12, 14, 14, 14, 12, - 14, 14, 10, 12, 14, 14, - 11, 13, 15, 14, 12, 13, - 12, 12, 11, 16, 15, 12, - 10, 14, 13, 12, 15, 13, - 11, 14, 15, 14, 12, 14, - 13, 12, 15, 15, 11, 10, - 14, 13, 12, 16, 18, 10, - 10, 13, 14, 11, 14, 16, - 12, 13, 14, 15, 12, 13, - 13, 12, 14, 15, 12, 10, - 13, 14, 11, 14, 15, 12, - 12, 13, 12, 13, 14, 14, - 10, 13, 15, 12, 10, 12, - 14, 12, 13, 15, 14, 12, - 12, 13, 13, 7, 9, 9, - 7, 7, 11, 10, 11, 10, - 9, 12, 10, 11, 11, 10, - 10, 11, 11, 11, 10, 12, - 7, 11, 11, 7, 12, 11, - 7, 7, 12, 12, 12, 12, - 12, 12, 10, 12, 12, 11, - 13, 13, 12, 13, 12, 13, - 7, 12, 12, 7, 12, 12, - 9, 11, 12, 10, 12, 13, - 13, 11, 13, 13, 10, 12, - 14, 13, 11, 12, 13, 14, - 9, 11, 12, 10, 12, 14, - 14, 12, 12, 14, 14, 13, - 13, 13, 13, 13, 12, 12, - 12, 13, 14, 14, 14, 14, - 14, 11, 14, 14, 9, 15, - 14, 11, 16, 15, 12, 12, - 14, 13, 14, 16, 14, 13, - 13, 15, 16, 13, 11, 14, - 14, 11, 16, 15, 12, 9, - 14, 15, 11, 15, 16, 11, - 12, 13, 13, 13, 13, 15, - 15, 13, 18, 17, 13, 11, - 13, 14, 11, 14, 16, 11, - 12, 13, 14, 12, 11, 14, - 14, 14, 13, 13, 13, 12, - 12, 13, 12, 13, 13, 13, - 13, 14, 14, 11, 14, 15, - 6, 12, 12, 10, 11, 11, - 9, 12, 13, 13, 10, 12, - 13, 11, 11, 13, 13, 12, - 12, 13, 13, 9, 11, 12, - 10, 8, 15, 15, 12, 14, - 15, 13, 14, 17, 15, 14, - 16, 16, 15, 14, 17, 16, - 14, 14, 15, 14, 12, 15, - 15, 12, 12, 15, 15, 11, - 10, 15, 14, 14, 15, 16, - 15, 15, 15, 14, 13, 14, - 14, 14, 15, 14, 14, 11, - 15, 14, 12, 16, 15, 12, - 15, 15, 13, 16, 14, 15, - 14, 15, 16, 14, 13, 15, - 17, 14, 15, 17, 15, 14, - 16, 15, 14, 12, 17, 16, - 13, 11, 15, 14, 12, 18, - 16, 13, 16, 14, 16, 14, - 15, 16, 12, 16, 17, 13, - 11, 15, 14, 13, 15, 18, - 12, 11, 14, 15, 14, 16, - 16, 13, 15, 15, 15, 13, - 15, 15, 13, 16, 16, 12, - 11, 14, 15, 12, 16, 16, - 14, 15, 15, 12, 14, 15, - 15, 14, 17, 16, 14, 14, - 15, 15, 13, 14, 15, 15, - 14, 15, 14, 14, 12, 16, - 15, 12, 10, 16, 14, 15, - 15, 14, 14, 13, 15, 15, - 13, 14, 14, 14, 14, 15, - 14, 11, 14, 15, 12, 17, - 16, 12, 8, 15, 14, 14, - 18, 18, 14, 17, 18, 17, - 16, 16, 17, 14, 18, 17, - 14, 9, 15, 16, 8, 15, - 18, 12, 18, 17, 12, 14, - 15, 15, 17, 18, 18, 16, - 15, 18, 17, 16, 13, 16, - 15, 12, 16, 18, 12, 12, - 18, 17, 12, 10, 15, 15, - 13, 17, 17, 14, 15, 17, - 18, 14, 16, 17, 13, 17, - 16, 13, 11, 15, 15, 10, - 18, 17, 13, 17, 16, 15, - 14, 14, 16, 15, 16, 18, - 17, 14, 17, 18, 16, 13, - 16, 16, 13, 18, 16, 14, - 12, 17, 17, 14, 18, 18, - 13, 14, 16, 16, 16, 17, - 17, 16, 16, 18, 18, 14, - 14, 16, 17, 13, 18, 17, - 13, 12, 17, 17, 12, 10, - 15, 14, 15, 16, 17, 13, - 16, 17, 17, 15, 16, 16, - 13, 16, 18, 13, 11, 15, - 15, 8, 14, 15, 12, 18, - 17, 11, 14, 16, 16, 16, - 18, 18, 16, 15, 18, 17, - 16, 12, 15, 15, 12, 16, - 16, 12, 11, 17, 16, 12, - 9, 15, 15, 14, 17, 16, - 14, 13, 15, 16, 16, 17, - 18, 16, 18, 17, 14, 8, - 15, 15, 7, 15, 14, 12, - 17, 17, 11, 12, 14, 14, - 14, 17, 17, 15, 13, 17, - 18, 16, 13, 15, 15, 11, - 16, 17, 12, 12, 17, 18, - 12, 11, 16, 14, 14, 17, - 16, 13, 16, 16, 15, 17, - 15, 17, 13, 16, 16, 14, - 10, 15, 15, 12, 18, 16, - 13, 18, 18, 13, 13, 15, - 17, 15, 17, 18, 15, 16, - 17, 18, 17, 15, 15, 15, - 13, 18, 18, 14, 10, 16, - 18, 14, 17, 17, 13, 13, - 18, 15, 15, 18, 17, 14, - 16, 16, 15, 15, 14, 15, - 14, 14, 18, 18, 14, 13, - 18, 18, 12, 10, 15, 15, - 14, 16, 18, 13, 14, 15, - 16, 16, 18, 16, 14, 15, - 18, 13, 10, 16, 15, 8, - 15, 15, 12, 16, 18, 11, - 13, 14, 14, 15, 16, 17, - 15, 15, 18, 18, 17, 14, - 16, 16, 12, 16, 17, 11, - 8, 16, 16, 12, 15, 15, - 12, 15, 15, 15, 14, 16, - 16, 14, 14, 16, 15, 14, - 16, 17, 17, 12, 15, 15, - 12, 12, 15, 15, 11, 11, - 15, 14, 14, 15, 15, 14, - 13, 14, 14, 14, 14, 15, - 14, 15, 15, 15, 11, 14, - 15, 11, 16, 15, 14, 15, - 15, 13, 15, 16, 15, 13, - 15, 16, 14, 13, 16, 16, - 14, 15, 14, 16, 13, 15, - 14, 13, 12, 16, 17, 13, - 11, 14, 14, 12, 16, 15, - 13, 14, 15, 16, 15, 14, - 15, 12, 16, 15, 14, 11, - 15, 14, 13, 16, 16, 12, - 11, 14, 15, 13, 17, 17, - 12, 14, 16, 16, 15, 15, - 14, 14, 15, 16, 12, 10, - 15, 15, 12, 16, 17, 13, - 15, 16, 15, 14, 15, 15, - 13, 17, 17, 13, 14, 15, - 14, 15, 14, 16, 15, 13, - 15, 15, 12, 11, 15, 15, - 12, 11, 14, 15, 14, 14, - 15, 15, 13, 14, 14, 14, - 14, 15, 15, 15, 15, 14, - 10, 16, 15, 7, 11, 12, - 7, 7, 11, 11, 12, 12, - 12, 12, 11, 13, 13, 10, - 12, 12, 12, 12, 12, 13, - 7, 12, 12, 6, 12, 12, - 10, 12, 12, 9, 12, 14, - 13, 12, 14, 13, 11, 11, - 13, 13, 11, 12, 13, 14, - 9, 11, 11, 10, 12, 15, - 13, 12, 11, 15, 14, 13, - 15, 14, 14, 12, 13, 13, - 12, 12, 12, 13, 13, 13, - 13, 11, 13, 14, 9, 15, - 14, 10, 16, 15, 11, 11, - 13, 13, 14, 16, 16, 13, - 14, 16, 14, 14, 12, 13, - 13, 11, 15, 15, 11, 9, - 14, 14, 12, 15, 16, 10, - 11, 13, 14, 14, 16, 16, - 13, 13, 14, 15, 13, 12, - 13, 14, 12, 16, 15, 11, - 12, 14, 15, 13, 11, 14, - 16, 14, 13, 14, 13, 11, - 13, 13, 12, 12, 13, 14, - 13, 13, 13, 11, 14, 14, - 7, 12, 12, 9, 12, 11, - 10, 12, 13, 14, 12, 14, - 15, 11, 10, 13, 13, 11, - 12, 14, 12, 10, 12, 11, - 9, -}; - -static const uint16_t on2avc_cb5_syms[ON2AVC_CB5_CODES] = { - 0x0000, 0x0002, 0x000E, 0x0011, 0x0013, 0x001D, - 0x001F, 0x0020, 0x0022, 0x002E, 0x0031, 0x0033, - 0x003D, 0x003F, 0x00D1, 0x00D3, 0x00DD, 0x00DF, - 0x00E0, 0x00E2, 0x00EE, 0x00F1, 0x00F3, 0x00FD, - 0x00FF, 0x0101, 0x0103, 0x010D, 0x010F, 0x0110, - 0x0112, 0x011E, 0x0121, 0x0123, 0x012D, 0x012F, - 0x0130, 0x0132, 0x013E, 0x01D0, 0x01D2, 0x01DE, - 0x01E1, 0x01E3, 0x01ED, 0x01EF, 0x01F0, 0x01F2, - 0x01FE, 0x0200, 0x0202, 0x020E, 0x0211, 0x0213, - 0x021D, 0x021F, 0x0220, 0x0222, 0x022E, 0x0231, - 0x0233, 0x023D, 0x023F, 0x02D1, 0x02D3, 0x02DD, - 0x02DF, 0x02E0, 0x02E2, 0x02EE, 0x02F1, 0x02F3, - 0x02FD, 0x02FF, 0x0301, 0x0303, 0x030D, 0x030F, - 0x0310, 0x0312, 0x031E, 0x0321, 0x0323, 0x032D, - 0x032F, 0x0330, 0x0332, 0x033E, 0x03D0, 0x03D2, - 0x03DE, 0x03E1, 0x03E3, 0x03ED, 0x03EF, 0x03F0, - 0x03F2, 0x03FE, 0x0D01, 0x0D03, 0x0D0D, 0x0D0F, - 0x0D10, 0x0D12, 0x0D1E, 0x0D21, 0x0D23, 0x0D2D, - 0x0D2F, 0x0D30, 0x0D32, 0x0D3E, 0x0DD0, 0x0DD2, - 0x0DDE, 0x0DE1, 0x0DE3, 0x0DED, 0x0DEF, 0x0DF0, - 0x0DF2, 0x0DFE, 0x0E00, 0x0E02, 0x0E0E, 0x0E11, - 0x0E13, 0x0E1D, 0x0E1F, 0x0E20, 0x0E22, 0x0E2E, - 0x0E31, 0x0E33, 0x0E3D, 0x0E3F, 0x0ED1, 0x0ED3, - 0x0EDD, 0x0EDF, 0x0EE0, 0x0EE2, 0x0EEE, 0x0EF1, - 0x0EF3, 0x0EFD, 0x0EFF, 0x0F01, 0x0F03, 0x0F0D, - 0x0F0F, 0x0F10, 0x0F12, 0x0F1E, 0x0F21, 0x0F23, - 0x0F2D, 0x0F2F, 0x0F30, 0x0F32, 0x0F3E, 0x0FD0, - 0x0FD2, 0x0FDE, 0x0FE1, 0x0FE3, 0x0FED, 0x0FEF, - 0x0FF0, 0x0FF2, 0x0FFE, 0x1001, 0x1003, 0x100D, - 0x100F, 0x1010, 0x1012, 0x101E, 0x1021, 0x1023, - 0x102D, 0x102F, 0x1030, 0x1032, 0x103E, 0x10D0, - 0x10D2, 0x10DE, 0x10E1, 0x10E3, 0x10ED, 0x10EF, - 0x10F0, 0x10F2, 0x10FE, 0x1100, 0x1102, 0x110E, - 0x1111, 0x1113, 0x111D, 0x111F, 0x1120, 0x1122, - 0x112E, 0x1131, 0x1133, 0x113D, 0x113F, 0x11D1, - 0x11D3, 0x11DD, 0x11DF, 0x11E0, 0x11E2, 0x11EE, - 0x11F1, 0x11F3, 0x11FD, 0x11FF, 0x1201, 0x1203, - 0x120D, 0x120F, 0x1210, 0x1212, 0x121E, 0x1221, - 0x1223, 0x122D, 0x122F, 0x1230, 0x1232, 0x123E, - 0x12D0, 0x12D2, 0x12DE, 0x12E1, 0x12E3, 0x12ED, - 0x12EF, 0x12F0, 0x12F2, 0x12FE, 0x1300, 0x1302, - 0x130E, 0x1311, 0x1313, 0x131D, 0x131F, 0x1320, - 0x1322, 0x132E, 0x1331, 0x1333, 0x133D, 0x133F, - 0x13D1, 0x13D3, 0x13DD, 0x13DF, 0x13E0, 0x13E2, - 0x13EE, 0x13F1, 0x13F3, 0x13FD, 0x13FF, 0x1D00, - 0x1D02, 0x1D0E, 0x1D11, 0x1D13, 0x1D1D, 0x1D1F, - 0x1D20, 0x1D22, 0x1D2E, 0x1D31, 0x1D33, 0x1D3D, - 0x1D3F, 0x1DD1, 0x1DD3, 0x1DDD, 0x1DDF, 0x1DE0, - 0x1DE2, 0x1DEE, 0x1DF1, 0x1DF3, 0x1DFD, 0x1DFF, - 0x1E01, 0x1E03, 0x1E0D, 0x1E0F, 0x1E10, 0x1E12, - 0x1E1E, 0x1E21, 0x1E23, 0x1E2D, 0x1E2F, 0x1E30, - 0x1E32, 0x1E3E, 0x1ED0, 0x1ED2, 0x1EDE, 0x1EE1, - 0x1EE3, 0x1EED, 0x1EEF, 0x1EF0, 0x1EF2, 0x1EFE, - 0x1F00, 0x1F02, 0x1F0E, 0x1F11, 0x1F13, 0x1F1D, - 0x1F1F, 0x1F20, 0x1F22, 0x1F2E, 0x1F31, 0x1F33, - 0x1F3D, 0x1F3F, 0x1FD1, 0x1FD3, 0x1FDD, 0x1FDF, - 0x1FE0, 0x1FE2, 0x1FEE, 0x1FF1, 0x1FF3, 0x1FFD, - 0x1FFF, 0x2000, 0x2002, 0x200E, 0x2011, 0x2013, - 0x201D, 0x201F, 0x2020, 0x2022, 0x202E, 0x2031, - 0x2033, 0x203D, 0x203F, 0x20D1, 0x20D3, 0x20DD, - 0x20DF, 0x20E0, 0x20E2, 0x20EE, 0x20F1, 0x20F3, - 0x20FD, 0x20FF, 0x2101, 0x2103, 0x210D, 0x210F, - 0x2110, 0x2112, 0x211E, 0x2121, 0x2123, 0x212D, - 0x212F, 0x2130, 0x2132, 0x213E, 0x21D0, 0x21D2, - 0x21DE, 0x21E1, 0x21E3, 0x21ED, 0x21EF, 0x21F0, - 0x21F2, 0x21FE, 0x2200, 0x2202, 0x220E, 0x2211, - 0x2213, 0x221D, 0x221F, 0x2220, 0x2222, 0x222E, - 0x2231, 0x2233, 0x223D, 0x223F, 0x22D1, 0x22D3, - 0x22DD, 0x22DF, 0x22E0, 0x22E2, 0x22EE, 0x22F1, - 0x22F3, 0x22FD, 0x22FF, 0x2301, 0x2303, 0x230D, - 0x230F, 0x2310, 0x2312, 0x231E, 0x2321, 0x2323, - 0x232D, 0x232F, 0x2330, 0x2332, 0x233E, 0x23D0, - 0x23D2, 0x23DE, 0x23E1, 0x23E3, 0x23ED, 0x23EF, - 0x23F0, 0x23F2, 0x23FE, 0x2D01, 0x2D03, 0x2D0D, - 0x2D0F, 0x2D10, 0x2D12, 0x2D1E, 0x2D21, 0x2D23, - 0x2D2D, 0x2D2F, 0x2D30, 0x2D32, 0x2D3E, 0x2DD0, - 0x2DD2, 0x2DDE, 0x2DE1, 0x2DE3, 0x2DED, 0x2DEF, - 0x2DF0, 0x2DF2, 0x2DFE, 0x2E00, 0x2E02, 0x2E0E, - 0x2E11, 0x2E13, 0x2E1D, 0x2E1F, 0x2E20, 0x2E22, - 0x2E2E, 0x2E31, 0x2E33, 0x2E3D, 0x2E3F, 0x2ED1, - 0x2ED3, 0x2EDD, 0x2EDF, 0x2EE0, 0x2EE2, 0x2EEE, - 0x2EF1, 0x2EF3, 0x2EFD, 0x2EFF, 0x2F01, 0x2F03, - 0x2F0D, 0x2F0F, 0x2F10, 0x2F12, 0x2F1E, 0x2F21, - 0x2F23, 0x2F2D, 0x2F2F, 0x2F30, 0x2F32, 0x2F3E, - 0x2FD0, 0x2FD2, 0x2FDE, 0x2FE1, 0x2FE3, 0x2FED, - 0x2FEF, 0x2FF0, 0x2FF2, 0x2FFE, 0x3001, 0x3003, - 0x300D, 0x300F, 0x3010, 0x3012, 0x301E, 0x3021, - 0x3023, 0x302D, 0x302F, 0x3030, 0x3032, 0x303E, - 0x30D0, 0x30D2, 0x30DE, 0x30E1, 0x30E3, 0x30ED, - 0x30EF, 0x30F0, 0x30F2, 0x30FE, 0x3100, 0x3102, - 0x310E, 0x3111, 0x3113, 0x311D, 0x311F, 0x3120, - 0x3122, 0x312E, 0x3131, 0x3133, 0x313D, 0x313F, - 0x31D1, 0x31D3, 0x31DD, 0x31DF, 0x31E0, 0x31E2, - 0x31EE, 0x31F1, 0x31F3, 0x31FD, 0x31FF, 0x3201, - 0x3203, 0x320D, 0x320F, 0x3210, 0x3212, 0x321E, - 0x3221, 0x3223, 0x322D, 0x322F, 0x3230, 0x3232, - 0x323E, 0x32D0, 0x32D2, 0x32DE, 0x32E1, 0x32E3, - 0x32ED, 0x32EF, 0x32F0, 0x32F2, 0x32FE, 0x3300, - 0x3302, 0x330E, 0x3311, 0x3313, 0x331D, 0x331F, - 0x3320, 0x3322, 0x332E, 0x3331, 0x3333, 0x333D, - 0x333F, 0x33D1, 0x33D3, 0x33DD, 0x33DF, 0x33E0, - 0x33E2, 0x33EE, 0x33F1, 0x33F3, 0x33FD, 0x33FF, - 0x3D00, 0x3D02, 0x3D0E, 0x3D11, 0x3D13, 0x3D1D, - 0x3D1F, 0x3D20, 0x3D22, 0x3D2E, 0x3D31, 0x3D33, - 0x3D3D, 0x3D3F, 0x3DD1, 0x3DD3, 0x3DDD, 0x3DDF, - 0x3DE0, 0x3DE2, 0x3DEE, 0x3DF1, 0x3DF3, 0x3DFD, - 0x3DFF, 0x3E01, 0x3E03, 0x3E0D, 0x3E0F, 0x3E10, - 0x3E12, 0x3E1E, 0x3E21, 0x3E23, 0x3E2D, 0x3E2F, - 0x3E30, 0x3E32, 0x3E3E, 0x3ED0, 0x3ED2, 0x3EDE, - 0x3EE1, 0x3EE3, 0x3EED, 0x3EEF, 0x3EF0, 0x3EF2, - 0x3EFE, 0x3F00, 0x3F02, 0x3F0E, 0x3F11, 0x3F13, - 0x3F1D, 0x3F1F, 0x3F20, 0x3F22, 0x3F2E, 0x3F31, - 0x3F33, 0x3F3D, 0x3F3F, 0x3FD1, 0x3FD3, 0x3FDD, - 0x3FDF, 0x3FE0, 0x3FE2, 0x3FEE, 0x3FF1, 0x3FF3, - 0x3FFD, 0x3FFF, 0xD001, 0xD003, 0xD00D, 0xD00F, - 0xD010, 0xD012, 0xD01E, 0xD021, 0xD023, 0xD02D, - 0xD02F, 0xD030, 0xD032, 0xD03E, 0xD0D0, 0xD0D2, - 0xD0DE, 0xD0E1, 0xD0E3, 0xD0ED, 0xD0EF, 0xD0F0, - 0xD0F2, 0xD0FE, 0xD100, 0xD102, 0xD10E, 0xD111, - 0xD113, 0xD11D, 0xD11F, 0xD120, 0xD122, 0xD12E, - 0xD131, 0xD133, 0xD13D, 0xD13F, 0xD1D1, 0xD1D3, - 0xD1DD, 0xD1DF, 0xD1E0, 0xD1E2, 0xD1EE, 0xD1F1, - 0xD1F3, 0xD1FD, 0xD1FF, 0xD201, 0xD203, 0xD20D, - 0xD20F, 0xD210, 0xD212, 0xD21E, 0xD221, 0xD223, - 0xD22D, 0xD22F, 0xD230, 0xD232, 0xD23E, 0xD2D0, - 0xD2D2, 0xD2DE, 0xD2E1, 0xD2E3, 0xD2ED, 0xD2EF, - 0xD2F0, 0xD2F2, 0xD2FE, 0xD300, 0xD302, 0xD30E, - 0xD311, 0xD313, 0xD31D, 0xD31F, 0xD320, 0xD322, - 0xD32E, 0xD331, 0xD333, 0xD33D, 0xD33F, 0xD3D1, - 0xD3D3, 0xD3DD, 0xD3DF, 0xD3E0, 0xD3E2, 0xD3EE, - 0xD3F1, 0xD3F3, 0xD3FD, 0xD3FF, 0xDD00, 0xDD02, - 0xDD0E, 0xDD11, 0xDD13, 0xDD1D, 0xDD1F, 0xDD20, - 0xDD22, 0xDD2E, 0xDD31, 0xDD33, 0xDD3D, 0xDD3F, - 0xDDD1, 0xDDD3, 0xDDDD, 0xDDDF, 0xDDE0, 0xDDE2, - 0xDDEE, 0xDDF1, 0xDDF3, 0xDDFD, 0xDDFF, 0xDE01, - 0xDE03, 0xDE0D, 0xDE0F, 0xDE10, 0xDE12, 0xDE1E, - 0xDE21, 0xDE23, 0xDE2D, 0xDE2F, 0xDE30, 0xDE32, - 0xDE3E, 0xDED0, 0xDED2, 0xDEDE, 0xDEE1, 0xDEE3, - 0xDEED, 0xDEEF, 0xDEF0, 0xDEF2, 0xDEFE, 0xDF00, - 0xDF02, 0xDF0E, 0xDF11, 0xDF13, 0xDF1D, 0xDF1F, - 0xDF20, 0xDF22, 0xDF2E, 0xDF31, 0xDF33, 0xDF3D, - 0xDF3F, 0xDFD1, 0xDFD3, 0xDFDD, 0xDFDF, 0xDFE0, - 0xDFE2, 0xDFEE, 0xDFF1, 0xDFF3, 0xDFFD, 0xDFFF, - 0xE000, 0xE002, 0xE00E, 0xE011, 0xE013, 0xE01D, - 0xE01F, 0xE020, 0xE022, 0xE02E, 0xE031, 0xE033, - 0xE03D, 0xE03F, 0xE0D1, 0xE0D3, 0xE0DD, 0xE0DF, - 0xE0E0, 0xE0E2, 0xE0EE, 0xE0F1, 0xE0F3, 0xE0FD, - 0xE0FF, 0xE101, 0xE103, 0xE10D, 0xE10F, 0xE110, - 0xE112, 0xE11E, 0xE121, 0xE123, 0xE12D, 0xE12F, - 0xE130, 0xE132, 0xE13E, 0xE1D0, 0xE1D2, 0xE1DE, - 0xE1E1, 0xE1E3, 0xE1ED, 0xE1EF, 0xE1F0, 0xE1F2, - 0xE1FE, 0xE200, 0xE202, 0xE20E, 0xE211, 0xE213, - 0xE21D, 0xE21F, 0xE220, 0xE222, 0xE22E, 0xE231, - 0xE233, 0xE23D, 0xE23F, 0xE2D1, 0xE2D3, 0xE2DD, - 0xE2DF, 0xE2E0, 0xE2E2, 0xE2EE, 0xE2F1, 0xE2F3, - 0xE2FD, 0xE2FF, 0xE301, 0xE303, 0xE30D, 0xE30F, - 0xE310, 0xE312, 0xE31E, 0xE321, 0xE323, 0xE32D, - 0xE32F, 0xE330, 0xE332, 0xE33E, 0xE3D0, 0xE3D2, - 0xE3DE, 0xE3E1, 0xE3E3, 0xE3ED, 0xE3EF, 0xE3F0, - 0xE3F2, 0xE3FE, 0xED01, 0xED03, 0xED0D, 0xED0F, - 0xED10, 0xED12, 0xED1E, 0xED21, 0xED23, 0xED2D, - 0xED2F, 0xED30, 0xED32, 0xED3E, 0xEDD0, 0xEDD2, - 0xEDDE, 0xEDE1, 0xEDE3, 0xEDED, 0xEDEF, 0xEDF0, - 0xEDF2, 0xEDFE, 0xEE00, 0xEE02, 0xEE0E, 0xEE11, - 0xEE13, 0xEE1D, 0xEE1F, 0xEE20, 0xEE22, 0xEE2E, - 0xEE31, 0xEE33, 0xEE3D, 0xEE3F, 0xEED1, 0xEED3, - 0xEEDD, 0xEEDF, 0xEEE0, 0xEEE2, 0xEEEE, 0xEEF1, - 0xEEF3, 0xEEFD, 0xEEFF, 0xEF01, 0xEF03, 0xEF0D, - 0xEF0F, 0xEF10, 0xEF12, 0xEF1E, 0xEF21, 0xEF23, - 0xEF2D, 0xEF2F, 0xEF30, 0xEF32, 0xEF3E, 0xEFD0, - 0xEFD2, 0xEFDE, 0xEFE1, 0xEFE3, 0xEFED, 0xEFEF, - 0xEFF0, 0xEFF2, 0xEFFE, 0xF001, 0xF003, 0xF00D, - 0xF00F, 0xF010, 0xF012, 0xF01E, 0xF021, 0xF023, - 0xF02D, 0xF02F, 0xF030, 0xF032, 0xF03E, 0xF0D0, - 0xF0D2, 0xF0DE, 0xF0E1, 0xF0E3, 0xF0ED, 0xF0EF, - 0xF0F0, 0xF0F2, 0xF0FE, 0xF100, 0xF102, 0xF10E, - 0xF111, 0xF113, 0xF11D, 0xF11F, 0xF120, 0xF122, - 0xF12E, 0xF131, 0xF133, 0xF13D, 0xF13F, 0xF1D1, - 0xF1D3, 0xF1DD, 0xF1DF, 0xF1E0, 0xF1E2, 0xF1EE, - 0xF1F1, 0xF1F3, 0xF1FD, 0xF1FF, 0xF201, 0xF203, - 0xF20D, 0xF20F, 0xF210, 0xF212, 0xF21E, 0xF221, - 0xF223, 0xF22D, 0xF22F, 0xF230, 0xF232, 0xF23E, - 0xF2D0, 0xF2D2, 0xF2DE, 0xF2E1, 0xF2E3, 0xF2ED, - 0xF2EF, 0xF2F0, 0xF2F2, 0xF2FE, 0xF300, 0xF302, - 0xF30E, 0xF311, 0xF313, 0xF31D, 0xF31F, 0xF320, - 0xF322, 0xF32E, 0xF331, 0xF333, 0xF33D, 0xF33F, - 0xF3D1, 0xF3D3, 0xF3DD, 0xF3DF, 0xF3E0, 0xF3E2, - 0xF3EE, 0xF3F1, 0xF3F3, 0xF3FD, 0xF3FF, 0xFD00, - 0xFD02, 0xFD0E, 0xFD11, 0xFD13, 0xFD1D, 0xFD1F, - 0xFD20, 0xFD22, 0xFD2E, 0xFD31, 0xFD33, 0xFD3D, - 0xFD3F, 0xFDD1, 0xFDD3, 0xFDDD, 0xFDDF, 0xFDE0, - 0xFDE2, 0xFDEE, 0xFDF1, 0xFDF3, 0xFDFD, 0xFDFF, - 0xFE01, 0xFE03, 0xFE0D, 0xFE0F, 0xFE10, 0xFE12, - 0xFE1E, 0xFE21, 0xFE23, 0xFE2D, 0xFE2F, 0xFE30, - 0xFE32, 0xFE3E, 0xFED0, 0xFED2, 0xFEDE, 0xFEE1, - 0xFEE3, 0xFEED, 0xFEEF, 0xFEF0, 0xFEF2, 0xFEFE, - 0xFF00, 0xFF02, 0xFF0E, 0xFF11, 0xFF13, 0xFF1D, - 0xFF1F, 0xFF20, 0xFF22, 0xFF2E, 0xFF31, 0xFF33, - 0xFF3D, 0xFF3F, 0xFFD1, 0xFFD3, 0xFFDD, 0xFFDF, - 0xFFE0, 0xFFE2, 0xFFEE, 0xFFF1, 0xFFF3, 0xFFFD, - 0xFFFF, -}; - -#define ON2AVC_CB6_CODES 1201 -static const uint32_t on2avc_cb6_codes[ON2AVC_CB6_CODES] = { - 0x0018, 0x0088, 0x0082, 0x0024, 0x05B4, 0x08DF, - 0x0044, 0x0197, 0x01DE, 0x021F, 0x0D77, 0x0A72, - 0x7E77, 0x0B8B, 0x03F1, 0x0433, 0x073F, 0x1E5C, - 0x016A, 0x01C5, 0x00D2, 0x0062, 0x0CE4, 0x0096, - 0x0020, 0x0052, 0x00B7, 0x0127, 0x003A, 0x0041, - 0x00CC, 0x01B6, 0x0124, 0x07D3, 0x01AE, 0x01C4, - 0x00DA, 0x03D8, 0x03F3, 0x1638, 0x03F2, 0x12FC, - 0x01E2, 0x0DBC, 0x026C, 0x008A, 0x0054, 0x01A6, - 0x0195, 0x0164, 0x01E2, 0x026D, 0x0051, 0x049F, - 0x01B3, 0x01E0, 0x01B4, 0x026E, 0x07DE, 0x0129, - 0x0292, 0x0DBD, 0x013E, 0x00F3, 0x05B5, 0x09A6, - 0x01FB, 0x02CF, 0x01FF, 0x037C, 0x004A, 0x067E, - 0x016B, 0x002A, 0x09A7, 0x10EE, 0x1639, 0x0135, - 0x0CCA, 0x016A, 0x011B, 0x03EE, 0x07A2, 0x0D7E, - 0x028F, 0x0FE2, 0x07DA, 0x0357, 0x92F6, 0x0F31, - 0x0217, 0x036A, 0x0CE5, 0x07A1, 0x0229, 0x03D9, - 0x0377, 0x00B7, 0x01A6, 0x0655, 0x012E, 0x002B, - 0x002E, 0x00F2, 0x06F2, 0x02D0, 0x0F98, 0x07A0, - 0x009C, 0x0332, 0x0014, 0x01BD, 0x017E, 0x0331, - 0x0371, 0x025B, 0x0498, 0x161F, 0x039E, 0x0654, - 0x00C2, 0x06BA, 0x0140, 0x021E, 0x02F8, 0x01B4, - 0x0134, 0x03FF, 0x0066, 0x0477, 0x01DF, 0x01FE, - 0x0A14, 0x029E, 0x0356, 0x038F, 0x035A, 0x3CB3, - 0x01B2, 0x016A, 0x011A, 0x00B6, 0x02DE, 0x01DD, - 0x017C, 0x0376, 0x002F, 0x0039, 0x03D7, 0x01BE, - 0x0056, 0x0050, 0x017C, 0x01CC, 0x0034, 0x0B3E, - 0x0499, 0x0014, 0x08DE, 0x037B, 0x03EB, 0x08BF, - 0x186E, 0x050F, 0x0030, 0x0169, 0x07F2, 0x00F6, - 0x0042, 0x0198, 0x00BC, 0x002E, 0x023A, 0x01E3, - 0x0036, 0x004C, 0x012E, 0x01A1, 0x007D, 0x00C3, - 0x0392, 0x0063, 0x0F33, 0x016C, 0x01A7, 0x0E77, - 0x01DF, 0x0177, 0x0032, 0x03FE, 0x0322, 0x01AC, - 0x0030, 0x017E, 0x011E, 0x0022, 0x01FB, 0x012A, - 0x002B, 0x0068, 0x00D4, 0x006E, 0x0015, 0x001C, - 0x00E5, 0x01A9, 0x0436, 0x053F, 0x05AE, 0x00B2, - 0x072A, 0x02EA, 0x008E, 0x0175, 0x02BE, 0x018E, - 0x0002, 0x005E, 0x01D6, 0x0055, 0x006A, 0x07F3, - 0x02F9, 0x01D4, 0x016E, 0x03AB, 0x00FF, 0x003C, - 0x0192, 0x01D6, 0x0256, 0x0137, 0x0148, 0x022A, - 0x039C, 0x016D, 0x0116, 0x038A, 0x033E, 0x0156, - 0x03CF, 0x004B, 0x00E6, 0x018F, 0x1E5D, 0x03DA, - 0x0292, 0x0108, 0x06F5, 0x03DB, 0x0092, 0x0178, - 0x014A, 0x03FF, 0x03EE, 0x0A79, 0x0A16, 0x00F7, - 0x01B5, 0x0A15, 0x0D7F, 0x02FA, 0x01E4, 0x0157, - 0x01E2, 0x0185, 0x057E, 0x07DB, 0x0098, 0x0DBE, - 0x019A, 0x05FE, 0x003B, 0x03F5, 0x01BF, 0x01E4, - 0x011E, 0x001B, 0x03AA, 0x0337, 0x1F9C, 0x0942, - 0x05AB, 0x0430, 0x24BF, 0x163A, 0x037E, 0x014E, - 0x00F4, 0x0217, 0x0059, 0x0F32, 0x03F4, 0x01F2, - 0x0031, 0x0136, 0x05C6, 0x0076, 0x0006, 0x02FE, - 0x03FB, 0x009D, 0x013F, 0x002E, 0x02E6, 0x00AD, - 0x0234, 0x021E, 0x0253, 0x012A, 0x0346, 0x029A, - 0x012B, 0x021C, 0x02DA, 0x0004, 0x013C, 0x00F5, - 0x004E, 0x017D, 0x01F8, 0x0006, 0x01FA, 0x01F9, - 0x007A, 0x0067, 0x033B, 0x033A, 0x0586, 0x05C7, - 0x05FF, 0x00C8, 0x014B, 0x024F, 0x02C5, 0x00E7, - 0x014C, 0x035C, 0x00A2, 0x006A, 0x01F3, 0x0071, - 0x005E, 0x0084, 0x063A, 0x03EF, 0x0064, 0x02FE, - 0x0255, 0x003A, 0x061A, 0x0333, 0x037F, 0x00FE, - 0x115B, 0x0F9A, 0x00A6, 0x027D, 0x0B5F, 0x013F, - 0x029E, 0x0293, 0x07B6, 0x000F, 0x0196, 0x02FB, - 0x033F, 0x01FE, 0x019E, 0x01B3, 0x037F, 0x00C4, - 0x00DE, 0x02D2, 0x007A, 0x03CA, 0x01E3, 0x02F7, - 0x00AE, 0x05AF, 0x02FF, 0x026F, 0x00CA, 0x0356, - 0x02C7, 0x02D1, 0x0256, 0x006B, 0x0141, 0x012C, - 0x03BE, 0x0026, 0x00F0, 0x03A3, 0x02D6, 0x005F, - 0x00FF, 0x03F2, 0x00AE, 0x0257, 0x01FE, 0x035E, - 0x01B6, 0x00EE, 0x0658, 0x008F, 0x0232, 0x0657, - 0x12FD, 0x00AF, 0x00E6, 0x0426, 0x0666, 0x009E, - 0x0467, 0x003F, 0x014A, 0x02D3, 0x12FE, 0x099A, - 0x03BF, 0x00DD, 0x04DF, 0x009F, 0x00B8, 0x0863, - 0x06F7, 0x01B8, 0x0346, 0x0179, 0x0FE3, 0x0667, - 0x0659, 0x01CE, 0x00B3, 0x0372, 0x065A, 0x025E, - 0x01AA, 0x0276, 0x027E, 0x02DB, 0x0CE6, 0x115A, - 0x02E7, 0x0139, 0x03DA, 0x01FA, 0x021C, 0x0943, - 0x0862, 0x011F, 0x08B6, 0x07E6, 0x029F, 0x00E5, - 0x0656, 0x049A, 0x000E, 0x0F99, 0x06F6, 0x00DC, - 0x00EC, 0x014B, 0x0230, 0x04A2, 0x0016, 0x02EB, - 0x03AE, 0x02DF, 0x01AA, 0x033E, 0x0196, 0x092E, - 0x06F3, 0x00E7, 0x0B5E, 0x03F2, 0x0086, 0x0347, - 0x022A, 0x0A17, 0x01EF, 0x067F, 0x004A, 0x037E, - 0x02EE, 0x015E, 0x0696, 0x006A, 0x01CD, 0x0077, - 0x073F, 0x0016, 0x01E3, 0x012E, 0x00DB, 0x03BD, - 0x0496, 0x01C6, 0x0323, 0x005E, 0x02F6, 0x027C, - 0x0235, 0x0231, 0x00DA, 0x01EB, 0x0232, 0x02C6, - 0x01F2, 0x016F, 0x02C6, 0x036B, 0x0050, 0x0AFE, - 0x0F9B, 0x00C6, 0x014E, 0x02BC, 0x01CA, 0x027F, - 0x07A5, 0x0DE1, 0x01F1, 0x039E, 0x0DE2, 0x1E5E, - 0x065E, 0x0DE0, 0x115F, 0x00F7, 0x02AB, 0x116E, - 0x019B, 0x04CE, 0x00D3, 0x01C7, 0x02D6, 0x01F3, - 0x016F, 0x014E, 0x05B7, 0x0FA3, 0x0118, 0x025F, - 0x017E, 0x0437, 0x049B, 0x05AE, 0x497A, 0x0D2E, - 0x05B6, 0x1E5F, 0x0DE3, 0x0512, 0x031A, 0x01F2, - 0x007E, 0x015C, 0x035E, 0x04CF, 0x01C8, 0x0194, - 0x12FF, 0x1F7F, 0x00E0, 0x01A2, 0x012F, 0x0087, - 0x014C, 0x0643, 0x0D5E, 0x017F, 0x07A6, 0x0513, - 0x0D5F, 0x022B, 0x065F, 0x03F6, 0x022E, 0x03F7, - 0x0642, 0x036E, 0x00D0, 0x01CB, 0x0378, 0x125EE, - 0x035F, 0x014F, 0x035F, 0x116F, 0x0A4F, 0x0102, - 0x032A, 0x0173, 0x0536, 0x03A7, 0x075E, 0x1F9F, - 0x163B, 0x14DA, 0x526E, 0x165F, 0x0A6E, 0x0596, - 0x07A7, 0x042A, 0x0172, 0x19C2, 0x07E6, 0x04A3, - 0x0327, 0x02A8, 0x07A3, 0x046E, 0x012F, 0x2EFF, - 0x01D7, 0x0266, 0x0BBE, 0x066E, 0x186F, 0x0A73, - 0x1336, 0x02A9, 0x0373, 0x017F, 0x1F9E, 0x0B62, - 0x03A6, 0x0DBF, 0x035B, 0x063B, 0x053B, 0x10EF, - 0x016E, 0x011B, 0x115D, 0x115C, 0x00F2, 0x0176, - 0x0393, 0x034A, 0x0107, 0x115E, 0x0B63, 0x023F, - 0x002A, 0x0CE7, 0x0A7A, 0x06FA, 0x06FB, 0x02AA, - 0x02C2, 0x065B, 0x07A4, 0x02D4, 0x0130, 0x0106, - 0x01FB, 0x0B3F, 0x01B7, 0x00F6, 0x0056, 0x053F, - 0x0126, 0x0048, 0x0233, 0x017D, 0x00A4, 0x08BE, - 0x165E, 0x165D, 0x0A7B, 0x0427, 0x078F, 0x1F7E, - 0x0641, 0x02E4, 0x01E6, 0x01DA, 0x00F8, 0x043A, - 0x02BE, 0x011C, 0x006F, 0x036D, 0x19C3, 0x0020, - 0x06AE, 0x0372, 0x0288, 0x00C0, 0x079D, 0x036E, - 0x0117, 0x02FB, 0x0538, 0x06F2, 0x12F9, 0x1337, - 0x1E58, 0x0214, 0x005E, 0x0CE0, 0x01EE, 0x0A6E, - 0x0215, 0x01C2, 0x12FA, 0x033A, 0x009A, 0x0174, - 0x0CE2, 0x09A1, 0x00FE, 0x0250, 0x02CA, 0x035E, - 0x03A2, 0x0D7D, 0x2EFE, 0x02E8, 0x24BE, 0x1F7C, - 0x10EC, 0x04A2, 0x0052, 0x010D, 0x0277, 0x003A, - 0x0CDE, 0x0A6F, 0x0086, 0x00E4, 0x12FB, 0x14DE, - 0x009E, 0x0062, 0x03CA, 0x03BC, 0x02CA, 0x14DF, - 0x0FE0, 0x030C, 0x03F0, 0x06F3, 0x0796, 0x0B1E, - 0x05B0, 0x15FE, 0x013A, 0x0CDF, 0x079E, 0x01E2, - 0x0166, 0x02BD, 0x0151, 0x0153, 0x0650, 0x0940, - 0x010F, 0x3CB2, 0x10ED, 0x057E, 0x03D4, 0x029E, - 0x0358, 0x06F4, 0x7E76, 0x017C, 0x15FF, 0x047D, - 0x1158, 0x3F3A, 0x0CE3, 0x005F, 0x043A, 0x032F, - 0x010E, 0x1E5A, 0x0A4C, 0x0152, 0x125EF, 0x0B88, - 0x057F, 0x059E, 0x042B, 0x2936, 0x0138, 0x03A1, - 0x03C6, 0x0E56, 0x12F8, 0x149A, 0x526F, 0x0F2E, - 0x079C, 0x02FA, 0x0476, 0x0267, 0x0636, 0x03A0, - 0x014E, 0x0092, 0x0D7C, 0x05AF, 0x010C, 0x011C, - 0x0A10, 0x177E, 0x0131, 0x09A0, 0x03EA, 0x02C2, - 0x02D6, 0x0B89, 0x032E, 0x01E8, 0x0F30, 0x01BA, - 0x0532, 0x0A6C, 0x0F6E, 0x04CC, 0x008E, 0x036C, - 0x0E57, 0x00D6, 0x0162, 0x0024, 0x0252, 0x0F6F, - 0x01AE, 0x0150, 0x0038, 0x07CE, 0x01BB, 0x01F6, - 0x026A, 0x038B, 0x01DB, 0x07CF, 0x14DB, 0x24BC, - 0x0272, 0x053E, 0x073E, 0x078E, 0x0C36, 0x0176, - 0x032B, 0x017A, 0x0190, 0x0CCB, 0x047C, 0x0170, - 0x0054, 0x03EC, 0x049D, 0x0197, 0x043B, 0x0432, - 0x0192, 0x026A, 0x01F0, 0x0076, 0x0216, 0x0A11, - 0x1F7D, 0x02C4, 0x0298, 0x1159, 0x0A4E, 0x0116, - 0x00E4, 0x0216, 0x029A, 0x000F, 0x04DA, 0x04D2, - 0x002B, 0x0011, 0x049E, 0x045A, 0x01BF, 0x01EF, - 0x03CE, 0x01F8, 0x026E, 0x0466, 0x02DC, 0x0168, - 0x030E, 0x00B4, 0x01C3, 0x03CC, 0x028D, 0x01AE, - 0x038E, 0x01B0, 0x0664, 0x0119, 0x01BE, 0x035B, - 0x035F, 0x028E, 0x0A78, 0x01DE, 0x0397, 0x03FE, - 0x01B1, 0x028E, 0x07D2, 0x09A2, 0x033C, 0x02C1, - 0x0FA0, 0x0359, 0x031E, 0x00C1, 0x03D6, 0x0A12, - 0x01C4, 0x0330, 0x075F, 0x0B1F, 0x025A, 0x027B, - 0x04DB, 0x02E5, 0x01FA, 0x036F, 0x0A13, 0x02BB, - 0x00FA, 0x01D4, 0x01F8, 0x018A, 0x161E, 0x0E75, - 0x026B, 0x05B3, 0x01BC, 0x05B2, 0x09A3, 0x0424, - 0x047E, 0x01EE, 0x0FE1, 0x161D, 0x024C, 0x017E, - 0x026B, 0x01DC, 0x00A5, 0x0F2F, 0x161C, 0x028B, - 0x0196, 0x0168, 0x01EF, 0x0394, 0x0E74, 0x013C, - 0x00C9, 0x032E, 0x0941, 0x0D76, 0x050C, 0x0228, - 0x006C, 0x0236, 0x0D2F, 0x0156, 0x00D2, 0x0B8A, - 0x0148, 0x028A, 0x028B, 0x033B, 0x0214, 0x01E9, - 0x03C2, 0x049C, 0x02BA, 0x02E9, 0x028C, 0x01FC, - 0x0103, 0x0B5C, 0x050D, 0x031C, 0x0268, 0x0651, - 0x013A, 0x013B, 0x0118, 0x03D5, 0x0252, 0x0044, - 0x0637, 0x01D2, 0x000E, 0x00F0, 0x0323, 0x02C3, - 0x019A, 0x016C, 0x0046, 0x03E3, 0x024A, 0x00AC, - 0x0269, 0x02C0, 0x0396, 0x027A, 0x0253, 0x0273, - 0x073E, 0x0322, 0x003A, 0x025E, 0x0336, 0x0257, - 0x00D6, 0x0026, 0x03C3, 0x0034, 0x019A, 0x00FB, - 0x0038, 0x0040, 0x0096, 0x01F0, 0x0184, 0x021A, - 0x003E, 0x0042, 0x050E, 0x03CE, 0x035E, 0x0FA1, - 0x017B, 0x02CD, 0x0058, 0x0326, 0x00E4, 0x002E, - 0x004F, 0x000C, 0x0164, 0x0048, 0x0048, 0x0194, - 0x0074, 0x006E, 0x0070, 0x006C, 0x01A4, 0x00A3, - 0x034F, 0x011E, 0x0374, 0x0157, 0x0138, 0x011D, - 0x03CF, 0x033D, 0x0132, 0x0050, 0x023E, 0x005A, - 0x0076, 0x01EC, 0x005D, 0x0008, 0x004C, 0x024E, - 0x0154, 0x001E, 0x01C6, 0x0027, 0x00FE, 0x01EA, - 0x02CE, 0x01DD, 0x02CB, 0x035A, 0x0318, 0x013E, - 0x009B, 0x0288, 0x0339, 0x024D, 0x031F, 0x0128, - 0x00B6, 0x0028, 0x028A, 0x0289, 0x029F, 0x01FD, - 0x029A, 0x00F6, 0x0FA2, 0x0347, 0x0080, 0x01A8, - 0x028F, 0x0326, 0x0327, 0x0370, 0x165C, 0x043F, - 0x0375, 0x013D, 0x1E5B, 0x04DE, 0x0155, 0x00D8, - 0x0319, 0x0096, 0x0640, 0x07E7, 0x007C, 0x0652, - 0x0373, 0x05DE, 0x00CF, 0x0E76, 0x0653, 0x01A0, - 0x0160, 0x0169, 0x01D5, 0x05AA, 0x053A, 0x0B5D, - 0x0254, 0x079A, 0x0533, 0x0425, 0x053E, 0x00A6, - 0x030F, 0x01A2, 0x00B0, 0x04A3, 0x079F, 0x011A, - 0x01EE, 0x02CC, 0x045E, 0x005C, 0x0024, 0x022C, - 0x001A, 0x0338, 0x0132, 0x026C, 0x004E, 0x047F, - 0x01B2, 0x0113, 0x043E, 0x0336, 0x00F0, 0x02CE, - 0x0112, 0x018B, 0x0010, 0x0114, 0x01BE, 0x03FA, - 0x002A, 0x00FA, 0x0033, 0x0060, 0x0146, 0x01DC, - 0x0000, 0x0025, 0x037A, 0x034E, 0x012E, 0x029B, - 0x079B, 0x00E6, 0x03CD, 0x02DD, 0x0117, 0x017A, - 0x002C, 0x03E2, 0x003E, 0x0070, 0x00CE, 0x00B1, - 0x003B, -}; - -static const uint8_t on2avc_cb6_bits[ON2AVC_CB6_CODES] = { - 7, 10, 10, 7, 12, 12, - 7, 10, 11, 11, 12, 15, - 17, 12, 13, 11, 15, 13, - 10, 11, 11, 7, 13, 13, - 7, 7, 12, 12, 7, 7, - 9, 9, 9, 11, 10, 9, - 12, 12, 13, 13, 13, 13, - 9, 12, 10, 10, 7, 9, - 9, 10, 12, 11, 10, 11, - 11, 9, 11, 11, 11, 11, - 12, 12, 13, 11, 12, 12, - 10, 11, 12, 12, 10, 11, - 11, 10, 12, 14, 13, 11, - 12, 12, 11, 10, 13, 14, - 10, 12, 12, 12, 16, 12, - 12, 10, 13, 13, 13, 12, - 11, 11, 11, 13, 14, 13, - 13, 11, 11, 10, 13, 13, - 11, 12, 12, 13, 16, 12, - 14, 10, 13, 13, 10, 13, - 11, 11, 10, 11, 11, 9, - 11, 11, 10, 11, 12, 12, - 13, 12, 12, 10, 13, 14, - 12, 11, 11, 12, 11, 9, - 11, 11, 10, 7, 12, 13, - 7, 7, 9, 9, 10, 12, - 13, 10, 12, 10, 10, 12, - 13, 12, 10, 10, 11, 9, - 7, 9, 9, 7, 10, 10, - 7, 7, 9, 9, 10, 11, - 10, 10, 12, 11, 11, 12, - 11, 11, 10, 10, 10, 9, - 7, 9, 9, 7, 9, 9, - 7, 10, 10, 7, 10, 10, - 11, 10, 11, 11, 11, 10, - 11, 12, 10, 9, 10, 10, - 8, 10, 9, 7, 10, 11, - 11, 9, 9, 10, 10, 10, - 10, 11, 10, 11, 10, 10, - 10, 11, 11, 10, 11, 11, - 10, 10, 11, 10, 13, 12, - 11, 10, 13, 12, 10, 11, - 11, 10, 11, 12, 13, 12, - 11, 13, 14, 11, 10, 11, - 11, 9, 13, 12, 10, 12, - 11, 11, 10, 13, 13, 9, - 11, 11, 10, 11, 15, 13, - 11, 11, 14, 13, 11, 10, - 11, 11, 10, 12, 13, 9, - 10, 11, 11, 10, 10, 10, - 10, 11, 11, 11, 10, 11, - 10, 10, 10, 11, 10, 10, - 11, 11, 10, 10, 10, 11, - 7, 9, 9, 8, 9, 9, - 7, 10, 10, 10, 11, 11, - 11, 10, 10, 12, 11, 10, - 9, 10, 10, 7, 9, 10, - 7, 10, 11, 11, 10, 11, - 11, 10, 11, 12, 12, 12, - 13, 13, 12, 11, 13, 13, - 11, 11, 11, 11, 9, 11, - 11, 9, 9, 12, 11, 9, - 9, 10, 11, 10, 11, 11, - 11, 11, 11, 11, 11, 11, - 11, 10, 11, 11, 10, 9, - 10, 10, 11, 12, 11, 10, - 12, 11, 10, 11, 10, 12, - 11, 11, 13, 11, 10, 13, - 13, 11, 12, 12, 11, 11, - 11, 11, 10, 10, 13, 13, - 10, 10, 11, 11, 10, 12, - 13, 10, 12, 11, 12, 11, - 13, 13, 10, 14, 13, 10, - 10, 11, 11, 10, 13, 13, - 10, 10, 10, 11, 10, 13, - 12, 10, 12, 12, 12, 12, - 13, 13, 11, 13, 13, 10, - 10, 11, 11, 11, 12, 12, - 10, 11, 11, 10, 12, 12, - 11, 11, 13, 12, 11, 10, - 13, 13, 10, 11, 12, 12, - 10, 11, 11, 11, 9, 12, - 11, 10, 9, 11, 11, 10, - 11, 11, 10, 12, 11, 11, - 10, 11, 11, 10, 11, 11, - 10, 9, 10, 10, 9, 12, - 13, 9, 13, 10, 11, 11, - 13, 14, 11, 14, 14, 13, - 13, 14, 13, 11, 13, 13, - 11, 12, 11, 11, 13, 11, - 11, 9, 12, 12, 9, 11, - 11, 11, 13, 14, 15, 12, - 12, 13, 14, 12, 10, 11, - 11, 9, 13, 12, 9, 10, - 13, 13, 10, 9, 11, 11, - 10, 12, 13, 11, 13, 12, - 13, 13, 13, 13, 10, 13, - 12, 10, 10, 11, 10, 17, - 13, 13, 11, 13, 14, 11, - 11, 11, 12, 12, 11, 15, - 13, 13, 17, 14, 13, 12, - 13, 13, 11, 14, 13, 11, - 10, 13, 13, 11, 14, 14, - 11, 12, 12, 11, 13, 15, - 14, 13, 14, 16, 15, 13, - 12, 12, 13, 11, 14, 14, - 11, 10, 13, 13, 10, 9, - 10, 10, 11, 13, 13, 10, - 13, 13, 12, 13, 13, 13, - 10, 13, 13, 10, 10, 11, - 11, 12, 11, 11, 9, 12, - 12, 9, 11, 11, 11, 12, - 14, 14, 12, 12, 14, 13, - 12, 10, 11, 11, 9, 12, - 12, 9, 10, 14, 14, 9, - 12, 11, 11, 11, 13, 14, - 11, 17, 14, 13, 13, 14, - 13, 11, 14, 13, 11, 12, - 11, 11, 13, 11, 11, 9, - 13, 12, 9, 10, 11, 10, - 12, 14, 14, 12, 14, 13, - 14, 12, 11, 11, 11, 9, - 12, 12, 9, 10, 13, 14, - 10, 10, 11, 10, 10, 14, - 12, 10, 13, 13, 12, 12, - 12, 13, 10, 12, 13, 10, - 9, 10, 11, 11, 13, 13, - 11, 14, 14, 11, 12, 13, - 13, 13, 17, 16, 13, 13, - 13, 16, 13, 12, 11, 13, - 11, 13, 14, 11, 17, 12, - 13, 11, 13, 16, 11, 12, - 13, 12, 13, 15, 17, 13, - 13, 17, 11, 12, 11, 12, - 11, 11, 14, 14, 11, 10, - 13, 13, 10, 12, 10, 11, - 10, 12, 13, 10, 12, 13, - 13, 12, 12, 12, 11, 14, - 12, 10, 9, 11, 11, 12, - 11, 11, 10, 12, 13, 9, - 10, 10, 11, 12, 13, 14, - 12, 12, 15, 14, 12, 11, - 11, 11, 9, 12, 13, 9, - 10, 11, 11, 9, 11, 11, - 9, 11, 11, 12, 11, 13, - 13, 11, 12, 13, 14, 12, - 12, 12, 12, 10, 11, 11, - 10, 10, 11, 11, 9, 9, - 10, 10, 10, 11, 11, 10, - 10, 11, 11, 11, 11, 12, - 10, 11, 11, 11, 9, 10, - 10, 11, 12, 12, 10, 11, - 11, 10, 11, 12, 11, 10, - 12, 13, 10, 11, 12, 13, - 11, 12, 11, 12, 10, 11, - 11, 10, 10, 14, 13, 10, - 10, 11, 11, 10, 13, 12, - 10, 12, 13, 12, 12, 12, - 13, 10, 12, 13, 10, 10, - 11, 11, 11, 13, 13, 10, - 10, 11, 11, 10, 12, 13, - 10, 12, 13, 12, 12, 13, - 11, 10, 12, 12, 10, 12, - 11, 11, 11, 11, 12, 10, - 10, 11, 10, 12, 11, 12, - 11, 13, 12, 10, 11, 13, - 11, 11, 11, 12, 10, 10, - 11, 11, 10, 9, 11, 11, - 9, 9, 10, 10, 10, 11, - 11, 10, 10, 11, 11, 12, - 11, 11, 11, 11, 11, 10, - 9, 11, 10, 7, 10, 10, - 7, 7, 9, 9, 9, 10, - 11, 10, 12, 11, 11, 12, - 11, 11, 10, 10, 11, 10, - 7, 10, 9, 7, 10, 9, - 7, 10, 10, 7, 9, 10, - 10, 10, 11, 12, 10, 10, - 11, 11, 10, 10, 10, 11, - 7, 9, 10, 8, 10, 12, - 11, 10, 9, 11, 10, 10, - 11, 11, 10, 10, 10, 11, - 11, 10, 10, 10, 10, 11, - 11, 10, 10, 10, 13, 12, - 11, 12, 12, 12, 10, 10, - 11, 11, 11, 14, 14, 11, - 11, 13, 13, 11, 11, 11, - 10, 10, 12, 12, 10, 13, - 11, 11, 10, 12, 13, 9, - 10, 11, 11, 11, 14, 13, - 11, 11, 13, 12, 11, 11, - 10, 11, 10, 12, 13, 10, - 9, 11, 11, 10, 10, 10, - 11, 10, 11, 11, 11, 13, - 11, 11, 11, 10, 10, 10, - 11, 10, 10, 9, 10, 10, - 7, 9, 10, 7, 9, 9, - 8, 10, 10, 10, 10, 12, - 11, 10, 11, 11, 12, 10, - 10, 10, 10, 7, 10, 10, - 7, -}; - -static const uint16_t on2avc_cb6_syms[ON2AVC_CB6_CODES] = { - 0x0000, 0x0002, 0x000E, 0x0011, 0x0013, 0x001D, - 0x001F, 0x0020, 0x0022, 0x002E, 0x0031, 0x0033, - 0x003D, 0x003F, 0x00D1, 0x00D3, 0x00DD, 0x00DF, - 0x00E0, 0x00E2, 0x00EE, 0x00F1, 0x00F3, 0x00FD, - 0x00FF, 0x0101, 0x0103, 0x010D, 0x010F, 0x0110, - 0x0112, 0x011E, 0x0121, 0x0123, 0x012D, 0x012F, - 0x0130, 0x0132, 0x013E, 0x01D0, 0x01D2, 0x01DE, - 0x01E1, 0x01E3, 0x01ED, 0x01EF, 0x01F0, 0x01F2, - 0x01FE, 0x0200, 0x0202, 0x020E, 0x0211, 0x0213, - 0x021D, 0x021F, 0x0220, 0x0222, 0x022E, 0x0231, - 0x0233, 0x023D, 0x023F, 0x02D1, 0x02D3, 0x02DD, - 0x02DF, 0x02E0, 0x02E2, 0x02EE, 0x02F1, 0x02F3, - 0x02FD, 0x02FF, 0x0301, 0x0303, 0x030D, 0x030F, - 0x0310, 0x0312, 0x031E, 0x0321, 0x0323, 0x032D, - 0x032F, 0x0330, 0x0332, 0x033E, 0x03D0, 0x03D2, - 0x03DE, 0x03E1, 0x03E3, 0x03ED, 0x03EF, 0x03F0, - 0x03F2, 0x03FE, 0x0D01, 0x0D03, 0x0D0D, 0x0D0F, - 0x0D10, 0x0D12, 0x0D1E, 0x0D21, 0x0D23, 0x0D2D, - 0x0D2F, 0x0D30, 0x0D32, 0x0D3E, 0x0DD0, 0x0DD2, - 0x0DDE, 0x0DE1, 0x0DE3, 0x0DED, 0x0DEF, 0x0DF0, - 0x0DF2, 0x0DFE, 0x0E00, 0x0E02, 0x0E0E, 0x0E11, - 0x0E13, 0x0E1D, 0x0E1F, 0x0E20, 0x0E22, 0x0E2E, - 0x0E31, 0x0E33, 0x0E3D, 0x0E3F, 0x0ED1, 0x0ED3, - 0x0EDD, 0x0EDF, 0x0EE0, 0x0EE2, 0x0EEE, 0x0EF1, - 0x0EF3, 0x0EFD, 0x0EFF, 0x0F01, 0x0F03, 0x0F0D, - 0x0F0F, 0x0F10, 0x0F12, 0x0F1E, 0x0F21, 0x0F23, - 0x0F2D, 0x0F2F, 0x0F30, 0x0F32, 0x0F3E, 0x0FD0, - 0x0FD2, 0x0FDE, 0x0FE1, 0x0FE3, 0x0FED, 0x0FEF, - 0x0FF0, 0x0FF2, 0x0FFE, 0x1001, 0x1003, 0x100D, - 0x100F, 0x1010, 0x1012, 0x101E, 0x1021, 0x1023, - 0x102D, 0x102F, 0x1030, 0x1032, 0x103E, 0x10D0, - 0x10D2, 0x10DE, 0x10E1, 0x10E3, 0x10ED, 0x10EF, - 0x10F0, 0x10F2, 0x10FE, 0x1100, 0x1102, 0x110E, - 0x1111, 0x1113, 0x111D, 0x111F, 0x1120, 0x1122, - 0x112E, 0x1131, 0x1133, 0x113D, 0x113F, 0x11D1, - 0x11D3, 0x11DD, 0x11DF, 0x11E0, 0x11E2, 0x11EE, - 0x11F1, 0x11F3, 0x11FD, 0x11FF, 0x1201, 0x1203, - 0x120D, 0x120F, 0x1210, 0x1212, 0x121E, 0x1221, - 0x1223, 0x122D, 0x122F, 0x1230, 0x1232, 0x123E, - 0x12D0, 0x12D2, 0x12DE, 0x12E1, 0x12E3, 0x12ED, - 0x12EF, 0x12F0, 0x12F2, 0x12FE, 0x1300, 0x1302, - 0x130E, 0x1311, 0x1313, 0x131D, 0x131F, 0x1320, - 0x1322, 0x132E, 0x1331, 0x1333, 0x133D, 0x133F, - 0x13D1, 0x13D3, 0x13DD, 0x13DF, 0x13E0, 0x13E2, - 0x13EE, 0x13F1, 0x13F3, 0x13FD, 0x13FF, 0x1D00, - 0x1D02, 0x1D0E, 0x1D11, 0x1D13, 0x1D1D, 0x1D1F, - 0x1D20, 0x1D22, 0x1D2E, 0x1D31, 0x1D33, 0x1D3D, - 0x1D3F, 0x1DD1, 0x1DD3, 0x1DDD, 0x1DDF, 0x1DE0, - 0x1DE2, 0x1DEE, 0x1DF1, 0x1DF3, 0x1DFD, 0x1DFF, - 0x1E01, 0x1E03, 0x1E0D, 0x1E0F, 0x1E10, 0x1E12, - 0x1E1E, 0x1E21, 0x1E23, 0x1E2D, 0x1E2F, 0x1E30, - 0x1E32, 0x1E3E, 0x1ED0, 0x1ED2, 0x1EDE, 0x1EE1, - 0x1EE3, 0x1EED, 0x1EEF, 0x1EF0, 0x1EF2, 0x1EFE, - 0x1F00, 0x1F02, 0x1F0E, 0x1F11, 0x1F13, 0x1F1D, - 0x1F1F, 0x1F20, 0x1F22, 0x1F2E, 0x1F31, 0x1F33, - 0x1F3D, 0x1F3F, 0x1FD1, 0x1FD3, 0x1FDD, 0x1FDF, - 0x1FE0, 0x1FE2, 0x1FEE, 0x1FF1, 0x1FF3, 0x1FFD, - 0x1FFF, 0x2000, 0x2002, 0x200E, 0x2011, 0x2013, - 0x201D, 0x201F, 0x2020, 0x2022, 0x202E, 0x2031, - 0x2033, 0x203D, 0x203F, 0x20D1, 0x20D3, 0x20DD, - 0x20DF, 0x20E0, 0x20E2, 0x20EE, 0x20F1, 0x20F3, - 0x20FD, 0x20FF, 0x2101, 0x2103, 0x210D, 0x210F, - 0x2110, 0x2112, 0x211E, 0x2121, 0x2123, 0x212D, - 0x212F, 0x2130, 0x2132, 0x213E, 0x21D0, 0x21D2, - 0x21DE, 0x21E1, 0x21E3, 0x21ED, 0x21EF, 0x21F0, - 0x21F2, 0x21FE, 0x2200, 0x2202, 0x220E, 0x2211, - 0x2213, 0x221D, 0x221F, 0x2220, 0x2222, 0x222E, - 0x2231, 0x2233, 0x223D, 0x223F, 0x22D1, 0x22D3, - 0x22DD, 0x22DF, 0x22E0, 0x22E2, 0x22EE, 0x22F1, - 0x22F3, 0x22FD, 0x22FF, 0x2301, 0x2303, 0x230D, - 0x230F, 0x2310, 0x2312, 0x231E, 0x2321, 0x2323, - 0x232D, 0x232F, 0x2330, 0x2332, 0x233E, 0x23D0, - 0x23D2, 0x23DE, 0x23E1, 0x23E3, 0x23ED, 0x23EF, - 0x23F0, 0x23F2, 0x23FE, 0x2D01, 0x2D03, 0x2D0D, - 0x2D0F, 0x2D10, 0x2D12, 0x2D1E, 0x2D21, 0x2D23, - 0x2D2D, 0x2D2F, 0x2D30, 0x2D32, 0x2D3E, 0x2DD0, - 0x2DD2, 0x2DDE, 0x2DE1, 0x2DE3, 0x2DED, 0x2DEF, - 0x2DF0, 0x2DF2, 0x2DFE, 0x2E00, 0x2E02, 0x2E0E, - 0x2E11, 0x2E13, 0x2E1D, 0x2E1F, 0x2E20, 0x2E22, - 0x2E2E, 0x2E31, 0x2E33, 0x2E3D, 0x2E3F, 0x2ED1, - 0x2ED3, 0x2EDD, 0x2EDF, 0x2EE0, 0x2EE2, 0x2EEE, - 0x2EF1, 0x2EF3, 0x2EFD, 0x2EFF, 0x2F01, 0x2F03, - 0x2F0D, 0x2F0F, 0x2F10, 0x2F12, 0x2F1E, 0x2F21, - 0x2F23, 0x2F2D, 0x2F2F, 0x2F30, 0x2F32, 0x2F3E, - 0x2FD0, 0x2FD2, 0x2FDE, 0x2FE1, 0x2FE3, 0x2FED, - 0x2FEF, 0x2FF0, 0x2FF2, 0x2FFE, 0x3001, 0x3003, - 0x300D, 0x300F, 0x3010, 0x3012, 0x301E, 0x3021, - 0x3023, 0x302D, 0x302F, 0x3030, 0x3032, 0x303E, - 0x30D0, 0x30D2, 0x30DE, 0x30E1, 0x30E3, 0x30ED, - 0x30EF, 0x30F0, 0x30F2, 0x30FE, 0x3100, 0x3102, - 0x310E, 0x3111, 0x3113, 0x311D, 0x311F, 0x3120, - 0x3122, 0x312E, 0x3131, 0x3133, 0x313D, 0x313F, - 0x31D1, 0x31D3, 0x31DD, 0x31DF, 0x31E0, 0x31E2, - 0x31EE, 0x31F1, 0x31F3, 0x31FD, 0x31FF, 0x3201, - 0x3203, 0x320D, 0x320F, 0x3210, 0x3212, 0x321E, - 0x3221, 0x3223, 0x322D, 0x322F, 0x3230, 0x3232, - 0x323E, 0x32D0, 0x32D2, 0x32DE, 0x32E1, 0x32E3, - 0x32ED, 0x32EF, 0x32F0, 0x32F2, 0x32FE, 0x3300, - 0x3302, 0x330E, 0x3311, 0x3313, 0x331D, 0x331F, - 0x3320, 0x3322, 0x332E, 0x3331, 0x3333, 0x333D, - 0x333F, 0x33D1, 0x33D3, 0x33DD, 0x33DF, 0x33E0, - 0x33E2, 0x33EE, 0x33F1, 0x33F3, 0x33FD, 0x33FF, - 0x3D00, 0x3D02, 0x3D0E, 0x3D11, 0x3D13, 0x3D1D, - 0x3D1F, 0x3D20, 0x3D22, 0x3D2E, 0x3D31, 0x3D33, - 0x3D3D, 0x3D3F, 0x3DD1, 0x3DD3, 0x3DDD, 0x3DDF, - 0x3DE0, 0x3DE2, 0x3DEE, 0x3DF1, 0x3DF3, 0x3DFD, - 0x3DFF, 0x3E01, 0x3E03, 0x3E0D, 0x3E0F, 0x3E10, - 0x3E12, 0x3E1E, 0x3E21, 0x3E23, 0x3E2D, 0x3E2F, - 0x3E30, 0x3E32, 0x3E3E, 0x3ED0, 0x3ED2, 0x3EDE, - 0x3EE1, 0x3EE3, 0x3EED, 0x3EEF, 0x3EF0, 0x3EF2, - 0x3EFE, 0x3F00, 0x3F02, 0x3F0E, 0x3F11, 0x3F13, - 0x3F1D, 0x3F1F, 0x3F20, 0x3F22, 0x3F2E, 0x3F31, - 0x3F33, 0x3F3D, 0x3F3F, 0x3FD1, 0x3FD3, 0x3FDD, - 0x3FDF, 0x3FE0, 0x3FE2, 0x3FEE, 0x3FF1, 0x3FF3, - 0x3FFD, 0x3FFF, 0xD001, 0xD003, 0xD00D, 0xD00F, - 0xD010, 0xD012, 0xD01E, 0xD021, 0xD023, 0xD02D, - 0xD02F, 0xD030, 0xD032, 0xD03E, 0xD0D0, 0xD0D2, - 0xD0DE, 0xD0E1, 0xD0E3, 0xD0ED, 0xD0EF, 0xD0F0, - 0xD0F2, 0xD0FE, 0xD100, 0xD102, 0xD10E, 0xD111, - 0xD113, 0xD11D, 0xD11F, 0xD120, 0xD122, 0xD12E, - 0xD131, 0xD133, 0xD13D, 0xD13F, 0xD1D1, 0xD1D3, - 0xD1DD, 0xD1DF, 0xD1E0, 0xD1E2, 0xD1EE, 0xD1F1, - 0xD1F3, 0xD1FD, 0xD1FF, 0xD201, 0xD203, 0xD20D, - 0xD20F, 0xD210, 0xD212, 0xD21E, 0xD221, 0xD223, - 0xD22D, 0xD22F, 0xD230, 0xD232, 0xD23E, 0xD2D0, - 0xD2D2, 0xD2DE, 0xD2E1, 0xD2E3, 0xD2ED, 0xD2EF, - 0xD2F0, 0xD2F2, 0xD2FE, 0xD300, 0xD302, 0xD30E, - 0xD311, 0xD313, 0xD31D, 0xD31F, 0xD320, 0xD322, - 0xD32E, 0xD331, 0xD333, 0xD33D, 0xD33F, 0xD3D1, - 0xD3D3, 0xD3DD, 0xD3DF, 0xD3E0, 0xD3E2, 0xD3EE, - 0xD3F1, 0xD3F3, 0xD3FD, 0xD3FF, 0xDD00, 0xDD02, - 0xDD0E, 0xDD11, 0xDD13, 0xDD1D, 0xDD1F, 0xDD20, - 0xDD22, 0xDD2E, 0xDD31, 0xDD33, 0xDD3D, 0xDD3F, - 0xDDD1, 0xDDD3, 0xDDDD, 0xDDDF, 0xDDE0, 0xDDE2, - 0xDDEE, 0xDDF1, 0xDDF3, 0xDDFD, 0xDDFF, 0xDE01, - 0xDE03, 0xDE0D, 0xDE0F, 0xDE10, 0xDE12, 0xDE1E, - 0xDE21, 0xDE23, 0xDE2D, 0xDE2F, 0xDE30, 0xDE32, - 0xDE3E, 0xDED0, 0xDED2, 0xDEDE, 0xDEE1, 0xDEE3, - 0xDEED, 0xDEEF, 0xDEF0, 0xDEF2, 0xDEFE, 0xDF00, - 0xDF02, 0xDF0E, 0xDF11, 0xDF13, 0xDF1D, 0xDF1F, - 0xDF20, 0xDF22, 0xDF2E, 0xDF31, 0xDF33, 0xDF3D, - 0xDF3F, 0xDFD1, 0xDFD3, 0xDFDD, 0xDFDF, 0xDFE0, - 0xDFE2, 0xDFEE, 0xDFF1, 0xDFF3, 0xDFFD, 0xDFFF, - 0xE000, 0xE002, 0xE00E, 0xE011, 0xE013, 0xE01D, - 0xE01F, 0xE020, 0xE022, 0xE02E, 0xE031, 0xE033, - 0xE03D, 0xE03F, 0xE0D1, 0xE0D3, 0xE0DD, 0xE0DF, - 0xE0E0, 0xE0E2, 0xE0EE, 0xE0F1, 0xE0F3, 0xE0FD, - 0xE0FF, 0xE101, 0xE103, 0xE10D, 0xE10F, 0xE110, - 0xE112, 0xE11E, 0xE121, 0xE123, 0xE12D, 0xE12F, - 0xE130, 0xE132, 0xE13E, 0xE1D0, 0xE1D2, 0xE1DE, - 0xE1E1, 0xE1E3, 0xE1ED, 0xE1EF, 0xE1F0, 0xE1F2, - 0xE1FE, 0xE200, 0xE202, 0xE20E, 0xE211, 0xE213, - 0xE21D, 0xE21F, 0xE220, 0xE222, 0xE22E, 0xE231, - 0xE233, 0xE23D, 0xE23F, 0xE2D1, 0xE2D3, 0xE2DD, - 0xE2DF, 0xE2E0, 0xE2E2, 0xE2EE, 0xE2F1, 0xE2F3, - 0xE2FD, 0xE2FF, 0xE301, 0xE303, 0xE30D, 0xE30F, - 0xE310, 0xE312, 0xE31E, 0xE321, 0xE323, 0xE32D, - 0xE32F, 0xE330, 0xE332, 0xE33E, 0xE3D0, 0xE3D2, - 0xE3DE, 0xE3E1, 0xE3E3, 0xE3ED, 0xE3EF, 0xE3F0, - 0xE3F2, 0xE3FE, 0xED01, 0xED03, 0xED0D, 0xED0F, - 0xED10, 0xED12, 0xED1E, 0xED21, 0xED23, 0xED2D, - 0xED2F, 0xED30, 0xED32, 0xED3E, 0xEDD0, 0xEDD2, - 0xEDDE, 0xEDE1, 0xEDE3, 0xEDED, 0xEDEF, 0xEDF0, - 0xEDF2, 0xEDFE, 0xEE00, 0xEE02, 0xEE0E, 0xEE11, - 0xEE13, 0xEE1D, 0xEE1F, 0xEE20, 0xEE22, 0xEE2E, - 0xEE31, 0xEE33, 0xEE3D, 0xEE3F, 0xEED1, 0xEED3, - 0xEEDD, 0xEEDF, 0xEEE0, 0xEEE2, 0xEEEE, 0xEEF1, - 0xEEF3, 0xEEFD, 0xEEFF, 0xEF01, 0xEF03, 0xEF0D, - 0xEF0F, 0xEF10, 0xEF12, 0xEF1E, 0xEF21, 0xEF23, - 0xEF2D, 0xEF2F, 0xEF30, 0xEF32, 0xEF3E, 0xEFD0, - 0xEFD2, 0xEFDE, 0xEFE1, 0xEFE3, 0xEFED, 0xEFEF, - 0xEFF0, 0xEFF2, 0xEFFE, 0xF001, 0xF003, 0xF00D, - 0xF00F, 0xF010, 0xF012, 0xF01E, 0xF021, 0xF023, - 0xF02D, 0xF02F, 0xF030, 0xF032, 0xF03E, 0xF0D0, - 0xF0D2, 0xF0DE, 0xF0E1, 0xF0E3, 0xF0ED, 0xF0EF, - 0xF0F0, 0xF0F2, 0xF0FE, 0xF100, 0xF102, 0xF10E, - 0xF111, 0xF113, 0xF11D, 0xF11F, 0xF120, 0xF122, - 0xF12E, 0xF131, 0xF133, 0xF13D, 0xF13F, 0xF1D1, - 0xF1D3, 0xF1DD, 0xF1DF, 0xF1E0, 0xF1E2, 0xF1EE, - 0xF1F1, 0xF1F3, 0xF1FD, 0xF1FF, 0xF201, 0xF203, - 0xF20D, 0xF20F, 0xF210, 0xF212, 0xF21E, 0xF221, - 0xF223, 0xF22D, 0xF22F, 0xF230, 0xF232, 0xF23E, - 0xF2D0, 0xF2D2, 0xF2DE, 0xF2E1, 0xF2E3, 0xF2ED, - 0xF2EF, 0xF2F0, 0xF2F2, 0xF2FE, 0xF300, 0xF302, - 0xF30E, 0xF311, 0xF313, 0xF31D, 0xF31F, 0xF320, - 0xF322, 0xF32E, 0xF331, 0xF333, 0xF33D, 0xF33F, - 0xF3D1, 0xF3D3, 0xF3DD, 0xF3DF, 0xF3E0, 0xF3E2, - 0xF3EE, 0xF3F1, 0xF3F3, 0xF3FD, 0xF3FF, 0xFD00, - 0xFD02, 0xFD0E, 0xFD11, 0xFD13, 0xFD1D, 0xFD1F, - 0xFD20, 0xFD22, 0xFD2E, 0xFD31, 0xFD33, 0xFD3D, - 0xFD3F, 0xFDD1, 0xFDD3, 0xFDDD, 0xFDDF, 0xFDE0, - 0xFDE2, 0xFDEE, 0xFDF1, 0xFDF3, 0xFDFD, 0xFDFF, - 0xFE01, 0xFE03, 0xFE0D, 0xFE0F, 0xFE10, 0xFE12, - 0xFE1E, 0xFE21, 0xFE23, 0xFE2D, 0xFE2F, 0xFE30, - 0xFE32, 0xFE3E, 0xFED0, 0xFED2, 0xFEDE, 0xFEE1, - 0xFEE3, 0xFEED, 0xFEEF, 0xFEF0, 0xFEF2, 0xFEFE, - 0xFF00, 0xFF02, 0xFF0E, 0xFF11, 0xFF13, 0xFF1D, - 0xFF1F, 0xFF20, 0xFF22, 0xFF2E, 0xFF31, 0xFF33, - 0xFF3D, 0xFF3F, 0xFFD1, 0xFFD3, 0xFFDD, 0xFFDF, - 0xFFE0, 0xFFE2, 0xFFEE, 0xFFF1, 0xFFF3, 0xFFFD, - 0xFFFF, -}; - -#define ON2AVC_CB7_CODES 3281 -static const uint32_t on2avc_cb7_codes[ON2AVC_CB7_CODES] = { - 0x00000, 0x000EA, 0x000E6, 0x000F4, 0x000F6, 0x00047, - 0x003E2, 0x004A7, 0x00044, 0x004D3, 0x0082A, 0x0026E, - 0x0020E, 0x008A5, 0x02603, 0x02895, 0x049B0, 0x02894, - 0x007BE, 0x0069E, 0x01154, 0x01153, 0x0095F, 0x0038E, - 0x004AC, 0x0128E, 0x00E5E, 0x00992, 0x02A84, 0x0386A, - 0x03F6F, 0x01C54, 0x005D4, 0x00AFB, 0x001BE, 0x00258, - 0x00A59, 0x00043, 0x004A6, 0x004D7, 0x00040, 0x0006C, - 0x007FF, 0x00D39, 0x0005B, 0x00066, 0x0034A, 0x00124, - 0x004B6, 0x00626, 0x0071F, 0x014A3, 0x014A2, 0x0083E, - 0x032D4, 0x049B3, 0x0045E, 0x00ED5, 0x02896, 0x00ABA, - 0x0107B, 0x009EC, 0x0082C, 0x0082B, 0x00D38, 0x0072B, - 0x004FC, 0x049B2, 0x050B1, 0x003FE, 0x009EB, 0x049B1, - 0x00966, 0x00F75, 0x03F70, 0x007BC, 0x00054, 0x00394, - 0x000E8, 0x0052F, 0x0057A, 0x00458, 0x0FB4B, 0x01C55, - 0x00948, 0x032D6, 0x00ED6, 0x0A05F, 0x050B3, 0x00BBD, - 0x0197E, 0x024FC, 0x020C6, 0x0094A, 0x0386B, 0x1F2FF, - 0x050B4, 0x0A060, 0x0FB4C, 0x009ED, 0x02A85, 0x0FB4D, - 0x02605, 0x00ABB, 0x009A2, 0x0145B, 0x0A05D, 0x03F71, - 0x00BFF, 0x1F2FE, 0x0FB49, 0x0FB48, 0x050B2, 0x01155, - 0x01FD6, 0x032D5, 0x00976, 0x02604, 0x00A5A, 0x0A05E, - 0x0FB4A, 0x00DB9, 0x0A063, 0x1F307, 0x0FB4F, 0x1F306, - 0x049B4, 0x0FB50, 0x0FB51, 0x050B6, 0x1F308, 0x050B7, - 0x1F30A, 0x1F309, 0x0A064, 0x1F30B, 0x0A066, 0x06535, - 0x020C7, 0x0A065, 0x032D7, 0x0FB52, 0x02897, 0x0077A, - 0x03F72, 0x0FB4E, 0x050B5, 0x0076E, 0x1F301, 0x1F302, - 0x06533, 0x01FD7, 0x1F300, 0x0A061, 0x1F304, 0x1F303, - 0x07E54, 0x024FD, 0x1F305, 0x06534, 0x02606, 0x0A062, - 0x007C0, 0x0A06A, 0x1F30F, 0x0FB54, 0x0386D, 0x009E6, - 0x1F310, 0x06538, 0x00DBA, 0x014A4, 0x050B9, 0x1F311, - 0x0A06B, 0x0128F, 0x07E55, 0x1F312, 0x0FB55, 0x01C56, - 0x07E56, 0x0FB56, 0x1F313, 0x050BA, 0x01C57, 0x02608, - 0x0A067, 0x1F30D, 0x1F30C, 0x02607, 0x0386C, 0x0A069, - 0x0A068, 0x01557, 0x00ED7, 0x06536, 0x1F30E, 0x0FB53, - 0x02609, 0x007BF, 0x050B8, 0x06537, 0x00DE5, 0x00392, - 0x03F69, 0x0A055, 0x0FB3C, 0x0A054, 0x00AB7, 0x050AB, - 0x0FB3D, 0x00CE6, 0x009E8, 0x014A1, 0x049A8, 0x1F2ED, - 0x02890, 0x009E9, 0x049A9, 0x1F2EE, 0x032D1, 0x020C4, - 0x049AA, 0x0A056, 0x0FB3E, 0x0FB3F, 0x0A051, 0x0A052, - 0x0A053, 0x0FB39, 0x0A050, 0x0096E, 0x0FB3A, 0x1F2EB, - 0x029FE, 0x007FE, 0x0128D, 0x049A7, 0x1F2EC, 0x07E50, - 0x00E36, 0x03867, 0x0FB3B, 0x006EA, 0x03F6B, 0x1F2F4, - 0x1F2F3, 0x03868, 0x049AB, 0x1F2F6, 0x029FF, 0x1F2F5, - 0x0A05A, 0x07E52, 0x1F2F7, 0x07E51, 0x03F6C, 0x1F2FA, - 0x07E53, 0x025FF, 0x1F2F8, 0x1F2F9, 0x009A0, 0x06532, - 0x0FB45, 0x024FB, 0x008B9, 0x01D7D, 0x0FB40, 0x01FD3, - 0x0FB42, 0x0A058, 0x050AC, 0x0A057, 0x0FB41, 0x0A059, - 0x1F2F0, 0x1F2EF, 0x0FB43, 0x03F6A, 0x0FB44, 0x020C5, - 0x1F2F1, 0x1F2F2, 0x004FE, 0x02601, 0x00A58, 0x01FD5, - 0x049AD, 0x00A46, 0x02A80, 0x050AD, 0x009E5, 0x01B56, - 0x02A81, 0x00A36, 0x01556, 0x032D3, 0x02A82, 0x0FB47, - 0x1F2FD, 0x050AE, 0x004BA, 0x00A6B, 0x03F6D, 0x049AE, - 0x01317, 0x009A1, 0x00AB8, 0x02891, 0x03869, 0x01FD4, - 0x049AC, 0x1F2FB, 0x0FB46, 0x0A05B, 0x02600, 0x032D2, - 0x0137E, 0x01C53, 0x02892, 0x00BFE, 0x0A05C, 0x1F2FC, - 0x00CE7, 0x00058, 0x00FF7, 0x009EA, 0x00068, 0x00060, - 0x004D2, 0x004BD, 0x000EE, 0x003A4, 0x006E2, 0x0137F, - 0x0197D, 0x006EB, 0x050B0, 0x03F6E, 0x00E37, 0x00316, - 0x02893, 0x004CB, 0x006EE, 0x01152, 0x008AE, 0x0067E, - 0x00991, 0x0145A, 0x00AB9, 0x049AF, 0x02A83, 0x00A6C, - 0x0045F, 0x02602, 0x006E1, 0x050AF, 0x012D2, 0x0073F, - 0x00061, 0x00526, 0x004D6, 0x0013E, 0x003AE, 0x0005E, - 0x01D7E, 0x0289F, 0x00059, 0x0006A, 0x0082D, 0x00F77, - 0x009EE, 0x006E3, 0x00D3F, 0x1F32B, 0x02A8B, 0x00D3E, - 0x032DE, 0x0FB60, 0x02A8C, 0x020CC, 0x03874, 0x0045B, - 0x00DE8, 0x0082E, 0x00636, 0x012D6, 0x049B9, 0x0260C, - 0x01157, 0x06540, 0x0A073, 0x02504, 0x0289D, 0x050C2, - 0x00AFE, 0x0260D, 0x0289E, 0x00A6F, 0x0004E, 0x006EF, - 0x0099C, 0x00EDA, 0x0062E, 0x00048, 0x00A3A, 0x01292, - 0x013C2, 0x00A72, 0x0012A, 0x028A0, 0x02507, 0x00174, - 0x00DE9, 0x00ABF, 0x00EDE, 0x01146, 0x013C3, 0x032E1, - 0x049BA, 0x03875, 0x03876, 0x00824, 0x0077B, 0x032E2, - 0x01050, 0x00677, 0x00EDB, 0x0145C, 0x02505, 0x032DF, - 0x019C0, 0x050C3, 0x06541, 0x0A074, 0x032E0, 0x00A37, - 0x02506, 0x00ABE, 0x00E78, 0x02A8D, 0x001B4, 0x02A8E, - 0x01D7F, 0x001A4, 0x00DEA, 0x1F32F, 0x050C5, 0x009EF, - 0x00977, 0x020CD, 0x01B60, 0x019C3, 0x017DE, 0x0131A, - 0x0260F, 0x0A075, 0x01C5C, 0x0FB61, 0x07E62, 0x00E79, - 0x02610, 0x0A076, 0x014A7, 0x02611, 0x009FA, 0x007C1, - 0x0145D, 0x1F32C, 0x049BB, 0x019C1, 0x06543, 0x1F32D, - 0x06544, 0x01FD8, 0x06542, 0x01B5E, 0x06545, 0x1F32E, - 0x019C2, 0x005F4, 0x0260E, 0x050C4, 0x01B5F, 0x01C5B, - 0x032E3, 0x1F339, 0x1F33A, 0x1F338, 0x0FB63, 0x028A1, - 0x1F33B, 0x0FB64, 0x049BC, 0x0A07A, 0x1F33C, 0x0A07B, - 0x032E4, 0x07E63, 0x1F33E, 0x07E64, 0x1F33D, 0x0FB65, - 0x028A2, 0x02612, 0x02613, 0x050C6, 0x00967, 0x0155A, - 0x03F78, 0x1F330, 0x0A077, 0x03877, 0x0A078, 0x1F333, - 0x1F331, 0x1F332, 0x03878, 0x1F335, 0x1F336, 0x06546, - 0x1F334, 0x06547, 0x1F337, 0x0A079, 0x0FB62, 0x006FE, - 0x1F342, 0x0FB69, 0x008A7, 0x009FB, 0x1F343, 0x1F344, - 0x050C7, 0x0654A, 0x020CF, 0x1F345, 0x020CE, 0x01FD9, - 0x028A5, 0x0A07C, 0x0A07D, 0x050C8, 0x013C6, 0x03F7A, - 0x0A07E, 0x0387B, 0x01C5D, 0x03879, 0x06548, 0x1F33F, - 0x028A3, 0x00DBE, 0x03F79, 0x1F340, 0x0FB66, 0x028A4, - 0x008B2, 0x0FB67, 0x0387A, 0x0131B, 0x005D5, 0x06549, - 0x1F341, 0x0FB68, 0x0155B, 0x00DE6, 0x07E59, 0x1F318, - 0x00266, 0x00823, 0x01B57, 0x0FB58, 0x1F319, 0x0386F, - 0x01B58, 0x02899, 0x050BB, 0x00DBB, 0x01B59, 0x032D9, - 0x050BC, 0x1F31A, 0x03F74, 0x032DA, 0x0A06D, 0x06539, - 0x03870, 0x0386E, 0x1F315, 0x1F314, 0x024FE, 0x0176A, - 0x032D8, 0x0A06C, 0x1F316, 0x07E57, 0x014A5, 0x049B5, - 0x07E58, 0x00D3A, 0x0075B, 0x02898, 0x1F317, 0x0FB57, - 0x03F73, 0x01B5A, 0x0FB5B, 0x050BE, 0x1F31F, 0x0FB5A, - 0x0653B, 0x1F320, 0x0FB5C, 0x07E5C, 0x07E5D, 0x1F322, - 0x050BF, 0x0A06F, 0x1F321, 0x0FB5D, 0x1F325, 0x1F323, - 0x1F324, 0x01C58, 0x00ED8, 0x0289A, 0x1F326, 0x03F77, - 0x013C0, 0x0653A, 0x03F75, 0x1F31B, 0x024FF, 0x03F76, - 0x0FB59, 0x07E5A, 0x0A06E, 0x02500, 0x07E5B, 0x02A86, - 0x050BD, 0x1F31C, 0x032DB, 0x1F31E, 0x1F31D, 0x049B6, - 0x00C49, 0x1F329, 0x1F328, 0x00BBE, 0x008A6, 0x03871, - 0x01B5B, 0x02A88, 0x01558, 0x020C9, 0x0FB5F, 0x049B7, - 0x014A6, 0x07E5F, 0x1F32A, 0x0197F, 0x01B5C, 0x03872, - 0x00726, 0x01156, 0x02501, 0x0104F, 0x00C48, 0x032DC, - 0x0653C, 0x0176B, 0x1F327, 0x0653D, 0x0289B, 0x07E5E, - 0x0FB5E, 0x0176E, 0x0A071, 0x0A070, 0x0260A, 0x00993, - 0x020C8, 0x0176F, 0x02A87, 0x0289C, 0x00042, 0x00CE8, - 0x01C5A, 0x00F76, 0x008BA, 0x001C8, 0x02A8A, 0x02503, - 0x00136, 0x00A6E, 0x020CB, 0x00A5B, 0x008AF, 0x00ED9, - 0x03873, 0x0653F, 0x07E61, 0x050C1, 0x007A9, 0x0067F, - 0x013C1, 0x01559, 0x00D3B, 0x00DE7, 0x01B5D, 0x050C0, - 0x0260B, 0x02A89, 0x0653E, 0x0A072, 0x07E60, 0x049B8, - 0x00A6D, 0x02502, 0x00E5F, 0x012D3, 0x020CA, 0x0015D, - 0x032DD, 0x01C59, 0x0018E, 0x000E0, 0x07E77, 0x07E78, - 0x07E76, 0x049C5, 0x00BEA, 0x0A090, 0x0A08F, 0x00A3B, - 0x03F80, 0x0655A, 0x0655B, 0x050D1, 0x0A091, 0x1F37E, - 0x1F37F, 0x1F37C, 0x1F37D, 0x0FB77, 0x0655D, 0x050D2, - 0x1F380, 0x0655C, 0x02618, 0x049C3, 0x1F379, 0x0A08D, - 0x07E72, 0x07E73, 0x1F37B, 0x1F37A, 0x0A08E, 0x0145E, - 0x06558, 0x06559, 0x07E74, 0x049C4, 0x0083F, 0x07E75, - 0x0FB76, 0x007AA, 0x008A8, 0x1F382, 0x0FB7B, 0x007AB, - 0x004B2, 0x050D5, 0x07E7C, 0x07E7B, 0x032E8, 0x0261A, - 0x07E7D, 0x1F383, 0x03F81, 0x1F384, 0x0655F, 0x0FB7C, - 0x0A094, 0x0A095, 0x020D3, 0x1F385, 0x050D6, 0x050D7, - 0x01B61, 0x0FB78, 0x07E79, 0x028A7, 0x07E7A, 0x0A092, - 0x1F381, 0x050D3, 0x0FB79, 0x032E7, 0x0655E, 0x0A093, - 0x01DA2, 0x0053B, 0x02619, 0x050D4, 0x0FB7A, 0x020D2, - 0x0094B, 0x0A09A, 0x0FB7F, 0x0FB7E, 0x03884, 0x00C4A, - 0x0FB80, 0x1F38B, 0x019C6, 0x032E9, 0x01C5F, 0x0FB82, - 0x1F38C, 0x0FB81, 0x050D9, 0x07E7E, 0x1F38D, 0x1F38E, - 0x03885, 0x050DB, 0x07E7F, 0x06562, 0x050DA, 0x00E7A, - 0x02A92, 0x1F386, 0x0A096, 0x06560, 0x06561, 0x1F389, - 0x1F387, 0x1F388, 0x050D8, 0x0A098, 0x0FB7D, 0x02A93, - 0x0A097, 0x01FDC, 0x1F38A, 0x0A099, 0x020D4, 0x07E82, - 0x0FB89, 0x1F394, 0x07E81, 0x0A09E, 0x0FB8B, 0x1F395, - 0x07E83, 0x0FB8A, 0x028A8, 0x1F397, 0x1F396, 0x0A09F, - 0x0FB8C, 0x03F82, 0x049C6, 0x1F398, 0x1F399, 0x06563, - 0x02508, 0x03886, 0x07E84, 0x012E6, 0x0A09B, 0x1F38F, - 0x032EA, 0x0FB85, 0x1F390, 0x0FB86, 0x0FB83, 0x0FB84, - 0x0A09C, 0x1F392, 0x1F391, 0x0FB87, 0x02A94, 0x1F393, - 0x0A09D, 0x07E80, 0x0FB88, 0x006B6, 0x1F39D, 0x1F39E, - 0x0A0A1, 0x0A0A2, 0x0155E, 0x1F39F, 0x0A0A3, 0x02509, - 0x020D5, 0x0A0A4, 0x1F3A0, 0x07E86, 0x06564, 0x01FDE, - 0x0FB90, 0x049C8, 0x06565, 0x050DE, 0x0A0A6, 0x07E87, - 0x0A0A5, 0x06566, 0x00E7B, 0x049C7, 0x1F39A, 0x0A0A0, - 0x050DC, 0x00DEC, 0x07E85, 0x0FB8D, 0x01FDD, 0x00CE9, - 0x050DD, 0x0FB8E, 0x1F39B, 0x03F83, 0x0051F, 0x1F39C, - 0x0FB8F, 0x01293, 0x009A3, 0x049BE, 0x1F34E, 0x1F34D, - 0x0654B, 0x0115A, 0x0A07F, 0x0654C, 0x00A47, 0x01C5E, - 0x049BF, 0x1F350, 0x1F34F, 0x0387C, 0x07E67, 0x1F351, - 0x07E66, 0x02A8F, 0x1F353, 0x07E68, 0x1F354, 0x1F352, - 0x0A080, 0x00BBF, 0x1F347, 0x1F348, 0x1F346, 0x0FB6A, - 0x032E5, 0x07E65, 0x1F349, 0x006E4, 0x012D7, 0x049BD, - 0x1F34A, 0x0FB6B, 0x050C9, 0x00DEB, 0x1F34C, 0x1F34B, - 0x0052E, 0x07E6A, 0x1F35F, 0x1F35E, 0x0A081, 0x0387D, - 0x1F361, 0x0654F, 0x1F360, 0x0A082, 0x0387E, 0x1F363, - 0x1F362, 0x050CA, 0x0A084, 0x1F365, 0x03F7D, 0x0A083, - 0x1F364, 0x032E6, 0x1F366, 0x0A085, 0x06550, 0x020D0, - 0x1F356, 0x1F355, 0x00A73, 0x1F357, 0x1F358, 0x1F359, - 0x07E69, 0x0654D, 0x1F35B, 0x0FB6C, 0x1F35A, 0x0654E, - 0x03F7B, 0x1F35D, 0x03F7C, 0x0FB6D, 0x1F35C, 0x009AA, - 0x03880, 0x1F36B, 0x0A086, 0x1F36A, 0x01FDA, 0x1F36C, - 0x0A087, 0x01051, 0x049C2, 0x0FB71, 0x07E6E, 0x0A088, - 0x03F7E, 0x06553, 0x1F36E, 0x1F36D, 0x06552, 0x028A6, - 0x02A90, 0x0A089, 0x1F36F, 0x03881, 0x0074A, 0x049C0, - 0x0FB6F, 0x0FB6E, 0x02614, 0x0FB70, 0x1F368, 0x1F367, - 0x07E6B, 0x0387F, 0x049C1, 0x07E6C, 0x06551, 0x050CB, - 0x014AA, 0x07E6D, 0x1F369, 0x02615, 0x0072C, 0x1F373, - 0x1F372, 0x008BB, 0x00450, 0x07E70, 0x1F375, 0x1F374, - 0x050CE, 0x03882, 0x1F376, 0x0FB74, 0x02617, 0x1F377, - 0x1F378, 0x07E71, 0x06557, 0x0FB75, 0x050CF, 0x050D0, - 0x0A08C, 0x03883, 0x02A91, 0x06555, 0x050CC, 0x06554, - 0x0A08A, 0x1F370, 0x050CD, 0x06556, 0x0FB72, 0x02616, - 0x07E6F, 0x0A08B, 0x01FDB, 0x0053A, 0x03F7F, 0x0FB73, - 0x1F371, 0x020D1, 0x01FE0, 0x1F3F9, 0x1F3F8, 0x02A98, - 0x00C4E, 0x0A0B6, 0x0FBB1, 0x1F3FA, 0x0FBB0, 0x1F3FC, - 0x1F3FD, 0x1F3FB, 0x0A0B7, 0x1F400, 0x1F401, 0x1F402, - 0x1F3FE, 0x1F3FF, 0x1F404, 0x1F405, 0x0FBB2, 0x1F403, - 0x1F3EF, 0x1F3F0, 0x1F3ED, 0x1F3EE, 0x1F3F3, 0x1F3F4, - 0x0FBAB, 0x1F3F1, 0x1F3F2, 0x0A0B5, 0x1F3F6, 0x1F3F5, - 0x0FBAC, 0x01052, 0x0FBAF, 0x1F3F7, 0x0FBAD, 0x0FBAE, - 0x004BC, 0x1F40D, 0x1F40E, 0x1F40C, 0x0FBB8, 0x049CC, - 0x1F410, 0x1F40F, 0x03F87, 0x0A0B9, 0x0A0BA, 0x1F412, - 0x0FBB9, 0x1F411, 0x1F415, 0x1F416, 0x1F413, 0x1F414, - 0x1F418, 0x0A0BB, 0x0FBBA, 0x1F417, 0x07E95, 0x07E93, - 0x1F406, 0x1F407, 0x0A0B8, 0x07E92, 0x0FBB5, 0x1F408, - 0x0FBB3, 0x0FBB4, 0x07E94, 0x0FBB7, 0x1F409, 0x0FBB6, - 0x03F86, 0x01DA3, 0x1F40B, 0x1F40A, 0x019C7, 0x06572, - 0x1F421, 0x1F420, 0x0250F, 0x00DBF, 0x1F422, 0x1F423, - 0x0FBBE, 0x050E2, 0x049CD, 0x1F425, 0x1F424, 0x07E97, - 0x1F427, 0x0FBC0, 0x1F428, 0x0FBBF, 0x1F426, 0x1F42A, - 0x1F42B, 0x1F429, 0x0A0C0, 0x013C7, 0x0A0BD, 0x1F419, - 0x0A0BC, 0x1F41C, 0x1F41D, 0x1F41E, 0x1F41A, 0x1F41B, - 0x0FBBC, 0x1F41F, 0x06571, 0x0FBBB, 0x01FE1, 0x0FBBD, - 0x0A0BF, 0x0A0BE, 0x07E96, 0x0FBC6, 0x1F437, 0x1F438, - 0x1F435, 0x1F436, 0x0A0C3, 0x1F43A, 0x1F439, 0x0FBC7, - 0x1F43B, 0x0FBC9, 0x0FBCA, 0x0FBC8, 0x07E99, 0x0A0C4, - 0x07E9A, 0x1F43C, 0x1F43D, 0x1F43E, 0x0A0C5, 0x050E4, - 0x0FBCB, 0x0FBCC, 0x050E3, 0x07E98, 0x0FBC2, 0x1F42C, - 0x0FBC1, 0x1F42F, 0x1F430, 0x1F42D, 0x1F42E, 0x0A0C1, - 0x1F432, 0x1F433, 0x0FBC3, 0x1F431, 0x0FBC5, 0x1F434, - 0x0FBC4, 0x0A0C2, 0x00AF6, 0x1F444, 0x0FBCF, 0x0261C, - 0x014AB, 0x0A0C8, 0x1F446, 0x1F445, 0x06573, 0x0261D, - 0x1F448, 0x1F447, 0x02A99, 0x0FBD1, 0x0A0C9, 0x1F449, - 0x0FBD0, 0x06574, 0x1F44C, 0x049CF, 0x1F44A, 0x1F44B, - 0x032EC, 0x1F440, 0x1F43F, 0x07E9B, 0x01B62, 0x0388A, - 0x1F441, 0x07E9C, 0x0A0C6, 0x00D6A, 0x0A0C7, 0x0FBCD, - 0x049CE, 0x00EDF, 0x0FBCE, 0x1F443, 0x1F442, 0x07E9D, - 0x03888, 0x0FB91, 0x1F3A8, 0x00E96, 0x00CEA, 0x0FB93, - 0x0FB94, 0x0FB92, 0x1F3A9, 0x03889, 0x0FB95, 0x0A0A7, - 0x0155F, 0x050E0, 0x0A0A8, 0x1F3AB, 0x1F3AA, 0x07E89, - 0x07E8A, 0x0A0AA, 0x0FB96, 0x0A0A9, 0x06567, 0x1F3A2, - 0x1F3A1, 0x02A95, 0x0250A, 0x06568, 0x1F3A4, 0x1F3A3, - 0x050DF, 0x02A96, 0x1F3A5, 0x06569, 0x00C4B, 0x00AFF, - 0x03887, 0x1F3A7, 0x1F3A6, 0x07E88, 0x0261B, 0x1F3BC, - 0x1F3BD, 0x1F3BA, 0x1F3BB, 0x0656C, 0x0FB97, 0x1F3BE, - 0x0656B, 0x1F3C0, 0x0FB98, 0x1F3C1, 0x07E8C, 0x1F3BF, - 0x1F3C2, 0x0FB9A, 0x0FB99, 0x0A0AC, 0x0656D, 0x0FB9B, - 0x1F3C4, 0x1F3C3, 0x07E8D, 0x049C9, 0x0A0AB, 0x1F3AE, - 0x1F3AC, 0x1F3AD, 0x1F3B1, 0x1F3B2, 0x1F3AF, 0x1F3B0, - 0x1F3B5, 0x1F3B6, 0x1F3B7, 0x1F3B3, 0x1F3B4, 0x0656A, - 0x1F3B9, 0x1F3B8, 0x07E8B, 0x03F84, 0x1F3CF, 0x1F3CE, - 0x032EB, 0x0250B, 0x0FB9E, 0x0A0AF, 0x1F3D0, 0x0A0AE, - 0x0A0B1, 0x1F3D1, 0x0A0B0, 0x049CA, 0x1F3D3, 0x1F3D4, - 0x0FBA0, 0x0FB9F, 0x1F3D2, 0x0FBA1, 0x0A0B2, 0x1F3D5, - 0x07E90, 0x07E8E, 0x1F3C6, 0x1F3C5, 0x0656E, 0x1F3C7, - 0x1F3C8, 0x0656F, 0x07E8F, 0x0FB9C, 0x0A0AD, 0x0FB9D, - 0x1F3C9, 0x050E1, 0x01FDF, 0x1F3CC, 0x1F3CD, 0x1F3CA, - 0x1F3CB, 0x00410, 0x0FBA9, 0x1F3DF, 0x1F3DE, 0x0FBA8, - 0x02A97, 0x1F3E1, 0x1F3E0, 0x0250E, 0x0FBAA, 0x1F3E3, - 0x1F3E4, 0x07E91, 0x1F3E2, 0x1F3E7, 0x1F3E8, 0x1F3E5, - 0x1F3E6, 0x1F3EA, 0x1F3EB, 0x1F3EC, 0x1F3E9, 0x0A0B4, - 0x03F85, 0x0FBA4, 0x1F3D6, 0x0FBA2, 0x0FBA3, 0x1F3D8, - 0x0FBA6, 0x1F3D7, 0x0FBA5, 0x1F3DB, 0x0A0B3, 0x1F3DC, - 0x1F3D9, 0x1F3DA, 0x049CB, 0x0FBA7, 0x1F3DD, 0x06570, - 0x0014C, 0x1F4A6, 0x1F4A7, 0x1F4A5, 0x0FBE7, 0x00DEF, - 0x1F4A9, 0x1F4A8, 0x01166, 0x050EB, 0x050EC, 0x1F4AB, - 0x1F4AA, 0x0A0D7, 0x0FBE8, 0x1F4AD, 0x1F4AC, 0x0A0D8, - 0x0A0D9, 0x1F4B0, 0x1F4B1, 0x1F4AE, 0x1F4AF, 0x0FBE6, - 0x1F49C, 0x1F49D, 0x1F49B, 0x0FBE5, 0x07EA2, 0x1F49F, - 0x1F49E, 0x0A0D6, 0x019F6, 0x1F4A1, 0x1F4A2, 0x1F4A0, - 0x050EA, 0x01C9E, 0x1F4A4, 0x1F4A3, 0x0133A, 0x00E4E, - 0x1F4BE, 0x1F4BD, 0x00BEE, 0x001AE, 0x050EE, 0x1F4C0, - 0x1F4BF, 0x050ED, 0x020DA, 0x1F4C2, 0x1F4C1, 0x050EF, - 0x0FBEB, 0x1F4C3, 0x1F4C4, 0x0FBE9, 0x0FBEA, 0x1F4C6, - 0x1F4C7, 0x1F4C5, 0x0A0DC, 0x1F4B4, 0x1F4B5, 0x1F4B2, - 0x1F4B3, 0x03F8A, 0x1F4B7, 0x1F4B8, 0x1F4B6, 0x0A0DA, - 0x02A9B, 0x1F4BA, 0x1F4B9, 0x0145F, 0x004AD, 0x0A0DB, - 0x1F4BC, 0x1F4BB, 0x03F8B, 0x003A6, 0x0A0DE, 0x1F4D1, - 0x1F4D0, 0x0FBED, 0x00DCA, 0x0FBEE, 0x1F4D2, 0x00EFE, - 0x02096, 0x0A0DF, 0x1F4D4, 0x1F4D3, 0x07EA6, 0x0FBEF, - 0x1F4D6, 0x1F4D5, 0x0A0E0, 0x1F4D9, 0x1F4DA, 0x1F4DB, - 0x1F4D7, 0x1F4D8, 0x07EA3, 0x1F4CA, 0x1F4CB, 0x1F4C8, - 0x1F4C9, 0x0388E, 0x0FBEC, 0x1F4CC, 0x049D8, 0x00CEB, - 0x0657A, 0x0A0DD, 0x1F4CD, 0x049D9, 0x00521, 0x1F4CF, - 0x1F4CE, 0x00CFA, 0x01B67, 0x1F4E4, 0x1F4E3, 0x032EF, - 0x00292, 0x0FBF2, 0x1F4E6, 0x1F4E5, 0x0FBF1, 0x014D2, - 0x0A0E5, 0x0A0E4, 0x028AA, 0x1F4E9, 0x0657F, 0x1F4EA, - 0x1F4E7, 0x1F4E8, 0x1F4ED, 0x1F4EE, 0x1F4EB, 0x1F4EC, - 0x0412E, 0x1F4DC, 0x0A0E1, 0x0A0E2, 0x049DA, 0x1F4DE, - 0x1F4DF, 0x1F4DD, 0x0657B, 0x01B66, 0x1F4E0, 0x0FBF0, - 0x0388F, 0x00522, 0x0A0E3, 0x1F4E2, 0x1F4E1, 0x0657E, - 0x007C2, 0x0A0EB, 0x1F4F8, 0x1F4F7, 0x0FBF5, 0x00F7A, - 0x1F4F9, 0x0FBF6, 0x020DB, 0x028AB, 0x1F4FB, 0x1F4FC, - 0x1F4FA, 0x0FBF7, 0x01DFE, 0x0BEFA, 0x1F4FD, 0x07EA7, - 0x1F502, 0x13FC2, 0x1F503, 0x1F4FE, 0x1F4FF, 0x1F4F1, - 0x0FBF3, 0x1F4F2, 0x1F4EF, 0x1F4F0, 0x02576, 0x0A0E7, - 0x1F4F3, 0x0A0E6, 0x07092, 0x0FBF4, 0x1F4F5, 0x1F4F4, - 0x049DB, 0x0096F, 0x1F4F6, 0x0A0EA, 0x02623, 0x006FF, - 0x1F45C, 0x1F45D, 0x1F45B, 0x07E9E, 0x03F88, 0x1F45F, - 0x1F45E, 0x020D7, 0x06575, 0x1F462, 0x0FBD2, 0x1F460, - 0x1F461, 0x1F464, 0x0FBD4, 0x0FBD3, 0x1F463, 0x1F467, - 0x1F468, 0x1F469, 0x1F465, 0x1F466, 0x1F44F, 0x1F450, - 0x1F451, 0x1F44D, 0x1F44E, 0x1F453, 0x1F454, 0x1F452, - 0x020D6, 0x0388B, 0x1F457, 0x1F458, 0x1F455, 0x1F456, - 0x028A9, 0x1F45A, 0x1F459, 0x00DED, 0x020D8, 0x1F472, - 0x1F471, 0x0261F, 0x006F0, 0x0FBD6, 0x1F474, 0x1F473, - 0x050E5, 0x049D3, 0x0FBD7, 0x1F475, 0x015EE, 0x1F477, - 0x0A0CD, 0x1F478, 0x1F476, 0x050E6, 0x1F47A, 0x1F47B, - 0x1F479, 0x0A0CE, 0x0A0CB, 0x1F46A, 0x0A0CA, 0x0261E, - 0x049D0, 0x0A0CC, 0x1F46C, 0x1F46B, 0x06576, 0x049D1, - 0x1F46E, 0x1F46D, 0x01FE2, 0x004DE, 0x049D2, 0x1F470, - 0x1F46F, 0x0FBD5, 0x00376, 0x0FBDB, 0x0FBDC, 0x1F482, - 0x0A0D0, 0x00C5E, 0x1F484, 0x1F483, 0x00BEB, 0x020D9, - 0x06578, 0x1F486, 0x1F485, 0x07E9F, 0x0A0D1, 0x1F487, - 0x07EA0, 0x050E8, 0x1F488, 0x0FBDF, 0x1F489, 0x0FBDD, - 0x0FBDE, 0x050E7, 0x0A0CF, 0x1F47D, 0x1F47C, 0x0FBD8, - 0x06577, 0x1F47F, 0x1F47E, 0x032ED, 0x012BA, 0x03F89, - 0x0FBD9, 0x1F480, 0x032EE, 0x00C4F, 0x1F481, 0x0FBDA, - 0x01B63, 0x00DEE, 0x0FBE1, 0x1F491, 0x0115B, 0x001CE, - 0x049D6, 0x1F493, 0x1F492, 0x0A0D4, 0x049D7, 0x1F495, - 0x1F494, 0x02A9A, 0x0A0D5, 0x0FBE3, 0x1F497, 0x1F496, - 0x0FBE2, 0x0FBE4, 0x1F49A, 0x1F498, 0x1F499, 0x049D4, - 0x1F48A, 0x0A0D2, 0x0FBE0, 0x049D5, 0x0A0D3, 0x1F48C, - 0x1F48B, 0x07EA1, 0x01FE3, 0x1F48E, 0x1F48D, 0x02622, - 0x00520, 0x050E9, 0x1F490, 0x1F48F, 0x06579, 0x0018A, - 0x09FE6, 0x1F0E6, 0x1F0E5, 0x0459C, 0x00DCB, 0x1F0E7, - 0x0FA96, 0x012D0, 0x020A6, 0x1F0E9, 0x1F0EA, 0x1F0E8, - 0x0FA97, 0x09FE7, 0x1F0EC, 0x1F0EB, 0x06370, 0x09FE8, - 0x1F0EE, 0x1F0EF, 0x0FA98, 0x1F0ED, 0x1F0DC, 0x1F0DD, - 0x1F0DE, 0x1F0DA, 0x1F0DB, 0x1F0DF, 0x1F0E0, 0x0FA93, - 0x0FA94, 0x0507C, 0x1F0E2, 0x1F0E3, 0x1F0E1, 0x0507B, - 0x00AAE, 0x1F0E4, 0x0FA95, 0x00F5D, 0x00DB4, 0x0FA9C, - 0x1F0F9, 0x00FF2, 0x003AC, 0x1F0FB, 0x1F0FC, 0x1F0FA, - 0x029E0, 0x025CF, 0x1F0FE, 0x1F0FD, 0x029E1, 0x029E2, - 0x09FE9, 0x1F180, 0x1F0FF, 0x07E04, 0x0FA9D, 0x1F183, - 0x1F181, 0x1F182, 0x0FA9A, 0x1F0F1, 0x0FA99, 0x1F0F0, - 0x0384C, 0x1F0F3, 0x1F0F4, 0x1F0F2, 0x0FA9B, 0x019F7, - 0x1F0F6, 0x1F0F5, 0x02878, 0x0018C, 0x06371, 0x1F0F8, - 0x1F0F7, 0x07E03, 0x002FC, 0x0507E, 0x1F18E, 0x1F18D, - 0x06373, 0x00D2C, 0x1F190, 0x1F18F, 0x01356, 0x01357, - 0x0FAA0, 0x1F192, 0x1F191, 0x0507F, 0x02879, 0x1F194, - 0x1F193, 0x0384D, 0x1F197, 0x0FAA1, 0x0FAA2, 0x1F195, - 0x1F196, 0x1F186, 0x1F187, 0x1F188, 0x1F184, 0x1F185, - 0x0507D, 0x1F189, 0x0FA9E, 0x06372, 0x020A7, 0x07E05, - 0x1F18B, 0x1F18A, 0x09FEA, 0x00AF8, 0x0FA9F, 0x1F18C, - 0x00A30, 0x0106F, 0x1F19F, 0x1F19E, 0x01AD6, 0x005F6, - 0x1F1A1, 0x1F1A2, 0x1F1A0, 0x0FAA8, 0x0099E, 0x0FAA9, - 0x1F1A3, 0x06375, 0x0459E, 0x07E07, 0x1F1A6, 0x1F1A4, - 0x1F1A5, 0x09FEC, 0x0FAAA, 0x1F1A7, 0x09FEB, 0x0FAA4, - 0x1F199, 0x1F198, 0x0FAA3, 0x0FAA6, 0x0459D, 0x1F19B, - 0x1F19A, 0x0FAA5, 0x01C49, 0x07E06, 0x1F19C, 0x03F56, - 0x0077E, 0x05080, 0x1F19D, 0x0FAA7, 0x06374, 0x008A2, - 0x1F1B3, 0x1F1B4, 0x0FAAE, 0x1F1B2, 0x00AB0, 0x1F1B6, - 0x1F1B5, 0x04980, 0x0384E, 0x0FAAF, 0x1F1B8, 0x1F1B7, - 0x06377, 0x04981, 0x1F1BA, 0x1F1B9, 0x07E09, 0x07E0A, - 0x1F1BC, 0x1F1BD, 0x1F1BB, 0x0FAB0, 0x1F1AA, 0x1F1AB, - 0x1F1AC, 0x1F1A8, 0x1F1A9, 0x0FAAC, 0x07E08, 0x0FAAB, - 0x1F1AD, 0x029E3, 0x06376, 0x0FAAD, 0x1F1AE, 0x1F1AF, - 0x0459F, 0x1F1B1, 0x1F1B0, 0x01AD7, 0x00822, 0x1DFF2, - 0x1DFF3, 0x1DFF1, 0x0FA82, 0x03F52, 0x1DFF5, 0x1DFF4, - 0x00BF6, 0x062F8, 0x07DFD, 0x1DFF7, 0x1DFF6, 0x09FE0, - 0x062F9, 0x1DFF9, 0x1DFF8, 0x029A6, 0x0FA83, 0x1DFFC, - 0x1DFFD, 0x1DFFA, 0x1DFFB, 0x13FC3, 0x17DF6, 0x17DF7, - 0x0FA80, 0x0412F, 0x05074, 0x1C24C, 0x05F7C, 0x05F7E, - 0x03848, 0x05F7F, 0x1C24E, 0x1C24D, 0x07DFC, 0x01FC6, - 0x1DFF0, 0x1C24F, 0x02577, 0x029A7, 0x1EF67, 0x1EF66, - 0x024EE, 0x003BE, 0x0FA88, 0x1EF69, 0x1EF68, 0x062FA, - 0x0384B, 0x1EF6B, 0x1EF6A, 0x015EF, 0x05076, 0x0FA89, - 0x1EF6D, 0x1EF6C, 0x07E00, 0x1EF6F, 0x0FA8A, 0x1EF6E, - 0x062FB, 0x1EF60, 0x0FA84, 0x1DFFE, 0x1DFFF, 0x07DFE, - 0x0FA85, 0x1EF62, 0x1EF61, 0x03F54, 0x0384A, 0x1EF63, - 0x0FA86, 0x00E30, 0x002EC, 0x0FA87, 0x1EF65, 0x1EF64, - 0x07DFF, 0x002FE, 0x09FE3, 0x1EF7C, 0x1EF7B, 0x07E01, - 0x0095C, 0x1EF7E, 0x1EF7D, 0x01456, 0x0133B, 0x05077, - 0x1F0C0, 0x1EF7F, 0x062FD, 0x05078, 0x1F0C2, 0x1F0C1, - 0x01C46, 0x03F55, 0x1F0C4, 0x1F0C5, 0x1F0C3, 0x0FA8D, - 0x1EF72, 0x1EF73, 0x1EF74, 0x1EF70, 0x1EF71, 0x062FC, - 0x1EF75, 0x0FA8B, 0x09FE2, 0x0154E, 0x1EF78, 0x0FA8C, - 0x1EF76, 0x1EF77, 0x00F5C, 0x1EF7A, 0x1EF79, 0x00DB2, - 0x0106E, 0x1F0D3, 0x1F0D2, 0x00ED0, 0x0045A, 0x07E02, - 0x0FA8F, 0x1F0D4, 0x1F0D5, 0x01C48, 0x0FA91, 0x0FA90, - 0x025CE, 0x032BE, 0x062FF, 0x1F0D7, 0x1F0D6, 0x0FA92, - 0x09FE5, 0x1F0D9, 0x1F0D8, 0x09FE4, 0x1F0C8, 0x1F0C9, - 0x1F0C6, 0x1F0C7, 0x05079, 0x1F0CB, 0x1F0CC, 0x1F0CA, - 0x0FA8E, 0x0507A, 0x1F0CE, 0x1F0CD, 0x024EF, 0x0018F, - 0x1F0D0, 0x1F0D1, 0x1F0CF, 0x062FE, 0x04986, 0x1F211, - 0x1F210, 0x029E5, 0x0149C, 0x09FFF, 0x1F212, 0x0FAD5, - 0x0FAD6, 0x0FAD8, 0x1F214, 0x1F213, 0x0FAD7, 0x0A000, - 0x0A001, 0x1F216, 0x1F215, 0x0FAD9, 0x0A003, 0x0FADA, - 0x1F217, 0x0A002, 0x0FAD1, 0x1F205, 0x1F203, 0x1F204, - 0x1F207, 0x1F208, 0x1F209, 0x1F206, 0x0FAD2, 0x1F20C, - 0x0FAD3, 0x1F20A, 0x1F20B, 0x00E31, 0x0FAD4, 0x1F20F, - 0x1F20D, 0x1F20E, 0x003BC, 0x1F221, 0x0FADD, 0x1F21F, - 0x1F220, 0x01D2E, 0x1F223, 0x1F222, 0x0384F, 0x0A007, - 0x1F225, 0x1F226, 0x07E18, 0x1F224, 0x1F229, 0x1F22A, - 0x1F227, 0x1F228, 0x01ADD, 0x0A009, 0x1F22B, 0x0A008, - 0x04987, 0x0FADC, 0x07E16, 0x1F218, 0x0FADB, 0x07E15, - 0x1F21B, 0x1F21C, 0x1F219, 0x1F21A, 0x0637A, 0x0A005, - 0x0A006, 0x07E17, 0x0A004, 0x025F0, 0x1F21E, 0x1F21D, - 0x01ADC, 0x05088, 0x1F235, 0x1F234, 0x05087, 0x01978, - 0x1F238, 0x07E1A, 0x1F236, 0x1F237, 0x07E1C, 0x1F239, - 0x0FAE2, 0x07E1B, 0x1F23B, 0x0A00D, 0x1F23C, 0x1F23A, - 0x0FAE3, 0x01979, 0x0A00E, 0x1F23D, 0x04989, 0x1F22E, - 0x1F22F, 0x1F22C, 0x1F22D, 0x1F231, 0x0A00A, 0x1F232, - 0x0FADE, 0x1F230, 0x04988, 0x0FADF, 0x1F233, 0x07E19, - 0x01ADE, 0x0A00C, 0x0FAE1, 0x0FAE0, 0x0A00B, 0x032C2, - 0x1F249, 0x1F24A, 0x1F248, 0x0A010, 0x05089, 0x1F24C, - 0x0A011, 0x1F24B, 0x0A012, 0x0FAEA, 0x1F24E, 0x0508A, - 0x1F24D, 0x0A014, 0x1F250, 0x0A013, 0x1F24F, 0x029E6, - 0x07E1D, 0x1F253, 0x1F251, 0x1F252, 0x0FAE4, 0x0FAE5, - 0x0FAE6, 0x1F23E, 0x1F23F, 0x1F242, 0x0A00F, 0x1F240, - 0x1F241, 0x0FAE8, 0x1F244, 0x1F245, 0x0FAE7, 0x1F243, - 0x0FAE9, 0x1F247, 0x1F246, 0x03850, 0x01286, 0x1F25E, - 0x1F25D, 0x03851, 0x00D2D, 0x1F260, 0x1F261, 0x1F25F, - 0x07E1E, 0x00A68, 0x1F262, 0x0A015, 0x0637C, 0x0508C, - 0x0498A, 0x1F265, 0x1F263, 0x1F264, 0x03852, 0x0FAEE, - 0x1F266, 0x0A016, 0x0FAEB, 0x0FAEC, 0x1F254, 0x1F255, - 0x1F258, 0x0637B, 0x1F259, 0x1F256, 0x1F257, 0x032C3, - 0x0FAED, 0x0508B, 0x03F59, 0x01310, 0x032C4, 0x1F25C, - 0x1F25A, 0x1F25B, 0x04982, 0x09FEE, 0x1F1C4, 0x00FF3, - 0x01457, 0x06378, 0x1F1C6, 0x1F1C5, 0x0FAB4, 0x0287B, - 0x0FAB6, 0x0FAB5, 0x00FF6, 0x03F57, 0x0FAB7, 0x09FEF, - 0x1F1C7, 0x05083, 0x09FF0, 0x1F1C8, 0x0FAB8, 0x01FC8, - 0x09FED, 0x0FAB2, 0x0FAB1, 0x1F1BE, 0x07E0B, 0x05081, - 0x0FAB3, 0x1F1BF, 0x024F0, 0x0287A, 0x1F1C1, 0x1F1C0, - 0x01FC7, 0x00E5A, 0x05082, 0x1F1C3, 0x1F1C2, 0x07E0C, - 0x032C0, 0x0FABE, 0x0FABF, 0x1F1D1, 0x1F1D2, 0x07E10, - 0x1F1D5, 0x1F1D3, 0x1F1D4, 0x0FAC2, 0x0FAC3, 0x1F1D6, - 0x0FAC0, 0x0FAC1, 0x1F1D9, 0x1F1DA, 0x1F1D7, 0x1F1D8, - 0x05085, 0x09FF2, 0x1F1DC, 0x1F1DB, 0x0FAC4, 0x0FAB9, - 0x0FABA, 0x1F1CA, 0x07E0D, 0x1F1C9, 0x1F1CB, 0x1F1CC, - 0x07E0E, 0x0FABB, 0x0FABD, 0x1F1CD, 0x1F1CE, 0x0FABC, - 0x09FF1, 0x07E0F, 0x1F1D0, 0x1F1CF, 0x05084, 0x0287C, - 0x1F1E6, 0x1F1E5, 0x03F58, 0x0287D, 0x09FF6, 0x1F1E9, - 0x1F1E7, 0x1F1E8, 0x07E13, 0x09FF8, 0x1F1EA, 0x09FF7, - 0x1F1ED, 0x09FF9, 0x0FAC8, 0x1F1EB, 0x1F1EC, 0x09FFB, - 0x04984, 0x09FFA, 0x04983, 0x09FF3, 0x1F1DE, 0x1F1DD, - 0x07E11, 0x1F1DF, 0x1F1E0, 0x0FAC6, 0x09FF4, 0x0FAC5, - 0x07E12, 0x1F1E2, 0x1F1E1, 0x05086, 0x00ED2, 0x09FF5, - 0x1F1E4, 0x1F1E3, 0x0FAC7, 0x004D4, 0x1F1F9, 0x1F1FA, - 0x09FFC, 0x0FACD, 0x029E4, 0x0FACE, 0x1F1FB, 0x0287E, - 0x09FFD, 0x0FAD0, 0x1F1FC, 0x0FACF, 0x06379, 0x1F1FE, - 0x1F1FF, 0x1F1FD, 0x09FFE, 0x04985, 0x07E14, 0x1F202, - 0x1F200, 0x1F201, 0x1F1EF, 0x1F1F0, 0x1F1F1, 0x1F1EE, - 0x0FAC9, 0x1F1F3, 0x1F1F4, 0x1F1F2, 0x0FACA, 0x032C1, - 0x1F1F6, 0x0FACC, 0x1F1F5, 0x0FACB, 0x01C9F, 0x1F1F8, - 0x1F1F7, 0x01FC9, 0x000EC, 0x0650B, 0x0650C, 0x07E2B, - 0x029EC, 0x00DB6, 0x0FB04, 0x1F298, 0x0098C, 0x01FCC, - 0x0650D, 0x07E2C, 0x0FB05, 0x0FB06, 0x0FB08, 0x1F29A, - 0x1F299, 0x0FB07, 0x00ED3, 0x05094, 0x1F29B, 0x07E2D, - 0x0FB09, 0x03855, 0x06508, 0x0FB02, 0x1F292, 0x0FB01, - 0x1F295, 0x1F296, 0x1F293, 0x1F294, 0x05093, 0x0FB03, - 0x0650A, 0x07E2A, 0x06509, 0x00BB6, 0x0A02B, 0x1F297, - 0x00A54, 0x00708, 0x1F2A2, 0x1F2A1, 0x007A8, 0x004CA, - 0x029EE, 0x07E2F, 0x05095, 0x0197B, 0x01C4A, 0x0A02D, - 0x07E30, 0x01FCD, 0x0FB0C, 0x0650F, 0x0FB0D, 0x1F2A3, - 0x0650E, 0x01D78, 0x06510, 0x07E31, 0x07E32, 0x04993, - 0x07E2E, 0x0A02C, 0x03F5D, 0x1F29E, 0x1F29F, 0x03856, - 0x1F29C, 0x1F29D, 0x03857, 0x0FB0A, 0x1F2A0, 0x029ED, - 0x004B8, 0x024F5, 0x03F5E, 0x0FB0B, 0x03858, 0x008AC, - 0x0FB13, 0x07E35, 0x0FB12, 0x06512, 0x01C4C, 0x07E36, - 0x0FB14, 0x01550, 0x02882, 0x07E37, 0x07E38, 0x06513, - 0x05096, 0x06514, 0x0A032, 0x1F2A7, 0x1F2A8, 0x006E7, - 0x032CA, 0x1F2A9, 0x0FB15, 0x029EF, 0x07E34, 0x0A02E, - 0x0A02F, 0x0FB0E, 0x07E33, 0x0FB10, 0x06511, 0x1F2A4, - 0x0FB0F, 0x04994, 0x02881, 0x0A031, 0x0A030, 0x0FB11, - 0x01289, 0x1F2A6, 0x1F2A5, 0x01C4B, 0x05098, 0x1F2AE, - 0x1F2AD, 0x07E3A, 0x06519, 0x1F2AF, 0x1F2B0, 0x0FB19, - 0x0A038, 0x05099, 0x1F2B2, 0x1F2B1, 0x07E3B, 0x0FB1A, - 0x1F2B4, 0x1F2B5, 0x04995, 0x1F2B3, 0x0149D, 0x03F60, - 0x0FB1B, 0x025F2, 0x0A033, 0x06516, 0x06515, 0x03F5F, - 0x0A035, 0x1F2AA, 0x07E39, 0x0A034, 0x0FB16, 0x06517, - 0x1F2AC, 0x1F2AB, 0x0FB17, 0x05097, 0x0A036, 0x0A037, - 0x0FB18, 0x06518, 0x0031A, 0x0A03C, 0x1F2BA, 0x1F2B9, - 0x07E3F, 0x0057E, 0x0FB1C, 0x1F2BB, 0x00F5E, 0x01551, - 0x025F3, 0x1F2BC, 0x07E40, 0x04996, 0x00BB8, 0x1F2BD, - 0x04997, 0x0385A, 0x00E32, 0x0651D, 0x1F2BF, 0x1F2BE, - 0x07E41, 0x0651A, 0x0A03A, 0x1F2B7, 0x1F2B6, 0x0A039, - 0x03859, 0x07E3D, 0x07E3C, 0x0509A, 0x029F0, 0x0651C, - 0x0A03B, 0x0651B, 0x07E3E, 0x0096A, 0x1F2B8, 0x0509B, - 0x01D79, 0x0073E, 0x0A01C, 0x1F26B, 0x1F26A, 0x0FAF0, - 0x01312, 0x0FAF1, 0x1F26C, 0x0074E, 0x00DE2, 0x0637D, - 0x0FAF2, 0x1F26D, 0x029E9, 0x025F1, 0x0508D, 0x1F26E, - 0x0072A, 0x01288, 0x1F270, 0x1F271, 0x1F26F, 0x0637E, - 0x1F267, 0x0A018, 0x0498B, 0x0A017, 0x029E7, 0x0A019, - 0x0A01A, 0x1F268, 0x029E8, 0x0175C, 0x0287F, 0x0A01B, - 0x1F269, 0x03F5A, 0x02880, 0x0498C, 0x0FAEF, 0x00DB5, - 0x07E1F, 0x1F27B, 0x1F27A, 0x0FAF4, 0x024F1, 0x1F27E, - 0x0A01F, 0x1F27C, 0x1F27D, 0x0FAF5, 0x1F280, 0x1F27F, - 0x06502, 0x0FAF6, 0x1F282, 0x07E21, 0x07E20, 0x1F281, - 0x029EA, 0x07E23, 0x07E22, 0x0154F, 0x0637F, 0x06500, - 0x0498D, 0x0FAF3, 0x1F272, 0x1F273, 0x0A01D, 0x0508E, - 0x032C5, 0x1F275, 0x1F276, 0x1F274, 0x06501, 0x03853, - 0x0A01E, 0x1F279, 0x1F277, 0x1F278, 0x0074F, 0x03854, - 0x032C7, 0x0FAFA, 0x1F286, 0x029EB, 0x07E25, 0x0A024, - 0x024F3, 0x01FCA, 0x0508F, 0x032C8, 0x1F287, 0x0A025, - 0x07E26, 0x0A026, 0x1F288, 0x1F289, 0x006E6, 0x0498E, - 0x1F28B, 0x1F28A, 0x032C9, 0x032C6, 0x0A021, 0x0A022, - 0x0A020, 0x03F5B, 0x1F283, 0x1F284, 0x06503, 0x0FAF7, - 0x024F2, 0x07E24, 0x1F285, 0x0FAF8, 0x01313, 0x01ADF, - 0x0FAF9, 0x0A023, 0x00AB1, 0x0055E, 0x1F28F, 0x1F28E, - 0x00972, 0x005FA, 0x024F4, 0x0FAFE, 0x1F290, 0x04990, - 0x020BC, 0x0FAFF, 0x1F291, 0x01D2F, 0x04991, 0x0A02A, - 0x05092, 0x0A029, 0x0FB00, 0x04992, 0x06507, 0x06506, - 0x01FCB, 0x03F5C, 0x05090, 0x06504, 0x0A027, 0x1F28C, - 0x1F28D, 0x07E28, 0x07E27, 0x0A028, 0x05091, 0x0FAFC, - 0x0FAFB, 0x0197A, 0x003D6, 0x0FAFD, 0x07E29, 0x0498F, - 0x06505, 0x00056, 0x020C0, 0x02888, 0x0005C, 0x0005A, - 0x0071E, 0x00CE4, 0x00A32, 0x005D6, 0x00A34, 0x0288A, - 0x02889, 0x00A33, 0x049A2, 0x0A046, 0x01D7A, 0x025F9, - 0x0A045, 0x01315, 0x01316, 0x07E4B, 0x01458, 0x00676, - 0x00F71, 0x01B51, 0x006FD, 0x07E4A, 0x06529, 0x01768, - 0x00AB3, 0x07E49, 0x009E4, 0x03F64, 0x050A1, 0x00DE3, - 0x00064, 0x008B8, 0x00AB4, 0x00BBB, 0x007FA, 0x0003C, - 0x009E7, 0x00AFA, 0x01459, 0x00AB5, 0x001AF, 0x03862, - 0x0288C, 0x0019E, 0x00BFD, 0x01C51, 0x0149F, 0x00F73, - 0x029FA, 0x07E4C, 0x0A047, 0x1F2D4, 0x03863, 0x00F74, - 0x01B52, 0x01B53, 0x050A2, 0x0137D, 0x006E8, 0x008A4, - 0x029F9, 0x00E33, 0x006E0, 0x03F65, 0x049A3, 0x1F2D3, - 0x03861, 0x00A35, 0x0197C, 0x00F72, 0x012D1, 0x0288B, - 0x0015C, 0x01FCF, 0x049A4, 0x001A6, 0x00BBC, 0x1F2D5, - 0x0A048, 0x00AB6, 0x0075A, 0x020C2, 0x03864, 0x0104E, - 0x050A5, 0x01D7B, 0x0A049, 0x1F2D6, 0x024F8, 0x0652B, - 0x1F2D7, 0x03865, 0x025FA, 0x07E4E, 0x014A0, 0x0652C, - 0x029FC, 0x00E5D, 0x00CE5, 0x0288D, 0x0098F, 0x006E9, - 0x0FB2C, 0x0652A, 0x01C52, 0x0104D, 0x0FB2B, 0x0128B, - 0x050A3, 0x07E4D, 0x029FB, 0x00990, 0x01FD0, 0x024F7, - 0x050A4, 0x020C1, 0x01B54, 0x1F2DD, 0x0FB30, 0x0FB2E, - 0x0FB2F, 0x049A6, 0x1F2DF, 0x1F2DE, 0x0288E, 0x029FD, - 0x0FB31, 0x025FD, 0x07E4F, 0x1F2E0, 0x0652E, 0x1F2E2, - 0x1F2E1, 0x0A04D, 0x0128C, 0x03F67, 0x0FB33, 0x0FB32, - 0x01B55, 0x025FC, 0x03F66, 0x0652D, 0x025FB, 0x0083C, - 0x1F2DA, 0x0FB2D, 0x1F2D8, 0x1F2D9, 0x0A04B, 0x050A6, - 0x050A7, 0x024F9, 0x0A04A, 0x0A04C, 0x1F2DC, 0x1F2DB, - 0x049A5, 0x00538, 0x0FB35, 0x0FB34, 0x01147, 0x0051E, - 0x03866, 0x0A04F, 0x1F2E7, 0x024FA, 0x002BC, 0x1F2E8, - 0x0FB36, 0x00DE4, 0x01555, 0x050AA, 0x1F2E9, 0x0FB37, - 0x0288F, 0x01FD2, 0x1F2EA, 0x0FB38, 0x032D0, 0x0652F, - 0x1F2E3, 0x020C3, 0x01FD1, 0x025FE, 0x03F68, 0x0A04E, - 0x06530, 0x01769, 0x01D7C, 0x1F2E4, 0x050A8, 0x00ED4, - 0x0099F, 0x050A9, 0x1F2E6, 0x1F2E5, 0x06531, 0x00F5F, - 0x0FB20, 0x0FB1F, 0x006B4, 0x0067C, 0x029F1, 0x1F2C2, - 0x1F2C1, 0x032CB, 0x0149E, 0x0509E, 0x1F2C3, 0x00A6A, - 0x00E5B, 0x025F4, 0x0FB21, 0x1F2C4, 0x1F2C5, 0x02883, - 0x0651F, 0x0FB22, 0x03F61, 0x0509C, 0x04998, 0x0FB1D, - 0x07E42, 0x0175D, 0x0107A, 0x0A03D, 0x07E43, 0x04999, - 0x01B50, 0x0509D, 0x0651E, 0x0104A, 0x0137C, 0x0499A, - 0x0FB1E, 0x1F2C0, 0x07E44, 0x0385C, 0x07E45, 0x0A040, - 0x1F2CA, 0x1F2CB, 0x032CC, 0x1F2CD, 0x1F2CC, 0x0385D, - 0x02884, 0x06523, 0x03F63, 0x1F2CE, 0x0FB24, 0x0FB25, - 0x1F2D1, 0x1F2CF, 0x1F2D0, 0x00F70, 0x07E46, 0x0FB26, - 0x1F2D2, 0x0499C, 0x03F62, 0x0095E, 0x01C4D, 0x0499B, - 0x00BF7, 0x06520, 0x1F2C6, 0x0FB23, 0x0A03E, 0x0A03F, - 0x1F2C7, 0x025F5, 0x0385B, 0x06521, 0x0509F, 0x1F2C9, - 0x1F2C8, 0x06522, 0x00AF9, 0x0A042, 0x0FB27, 0x00A56, - 0x006DE, 0x029F2, 0x029F3, 0x032CD, 0x032CE, 0x02886, - 0x0385E, 0x07E48, 0x0175F, 0x050A0, 0x0FB29, 0x01C4F, - 0x029F4, 0x0FB28, 0x01553, 0x0A043, 0x025F6, 0x01314, - 0x006FC, 0x0098E, 0x02885, 0x01552, 0x0A041, 0x06525, - 0x0128A, 0x020BD, 0x06524, 0x01C4E, 0x07E47, 0x0499D, - 0x00CE2, 0x0071A, 0x06526, 0x01FCE, 0x0175E, 0x024F6, - 0x00046, 0x009E2, 0x01C50, 0x00DB7, 0x00BB9, 0x00188, - 0x06527, 0x0499E, 0x0017C, 0x00D2F, 0x025F7, 0x00BBA, - 0x00DB8, 0x02887, 0x049A1, 0x06528, 0x0499F, 0x049A0, - 0x0104C, 0x020BF, 0x0FB2A, 0x029F8, 0x025F8, 0x00A31, - 0x0051C, 0x01554, 0x029F5, 0x00BFC, 0x032CF, 0x0A044, - 0x0385F, 0x029F6, 0x00AB2, 0x020BE, 0x00E5C, 0x00A57, - 0x00D2E, 0x001AC, 0x029F7, 0x03860, 0x00125, -}; - -static const uint8_t on2avc_cb7_bits[ON2AVC_CB7_CODES] = { - 1, 8, 8, 8, 8, 7, - 10, 11, 7, 11, 12, 10, - 10, 12, 14, 14, 15, 14, - 11, 11, 13, 13, 12, 10, - 11, 13, 12, 12, 14, 14, - 14, 13, 11, 12, 9, 10, - 12, 7, 11, 11, 7, 7, - 11, 12, 7, 7, 10, 9, - 11, 11, 11, 13, 13, 12, - 14, 15, 11, 12, 14, 12, - 13, 12, 12, 12, 12, 11, - 11, 15, 15, 10, 12, 15, - 12, 12, 14, 11, 7, 10, - 8, 11, 11, 11, 16, 13, - 12, 14, 12, 16, 15, 12, - 13, 14, 14, 12, 14, 17, - 15, 16, 16, 12, 14, 16, - 14, 12, 12, 13, 16, 14, - 12, 17, 16, 16, 15, 13, - 13, 14, 12, 14, 12, 16, - 16, 12, 16, 17, 16, 17, - 15, 16, 16, 15, 17, 15, - 17, 17, 16, 17, 16, 15, - 14, 16, 14, 16, 14, 11, - 14, 16, 15, 11, 17, 17, - 15, 13, 17, 16, 17, 17, - 15, 14, 17, 15, 14, 16, - 11, 16, 17, 16, 14, 12, - 17, 15, 12, 13, 15, 17, - 16, 13, 15, 17, 16, 13, - 15, 16, 17, 15, 13, 14, - 16, 17, 17, 14, 14, 16, - 16, 13, 12, 15, 17, 16, - 14, 11, 15, 15, 12, 10, - 14, 16, 16, 16, 12, 15, - 16, 12, 12, 13, 15, 17, - 14, 12, 15, 17, 14, 14, - 15, 16, 16, 16, 16, 16, - 16, 16, 16, 12, 16, 17, - 14, 11, 13, 15, 17, 15, - 12, 14, 16, 11, 14, 17, - 17, 14, 15, 17, 14, 17, - 16, 15, 17, 15, 14, 17, - 15, 14, 17, 17, 12, 15, - 16, 14, 12, 13, 16, 13, - 16, 16, 15, 16, 16, 16, - 17, 17, 16, 14, 16, 14, - 17, 17, 11, 14, 12, 13, - 15, 12, 14, 15, 12, 13, - 14, 12, 13, 14, 14, 16, - 17, 15, 11, 12, 14, 15, - 13, 12, 12, 14, 14, 13, - 15, 17, 16, 16, 14, 14, - 13, 13, 14, 12, 16, 17, - 12, 7, 12, 12, 7, 7, - 11, 11, 8, 10, 11, 13, - 13, 11, 15, 14, 12, 10, - 14, 11, 11, 13, 12, 11, - 12, 13, 12, 15, 14, 12, - 11, 14, 11, 15, 13, 11, - 7, 11, 11, 9, 10, 7, - 13, 14, 7, 7, 12, 12, - 12, 11, 12, 17, 14, 12, - 14, 16, 14, 14, 14, 11, - 12, 12, 11, 13, 15, 14, - 13, 15, 16, 14, 14, 15, - 12, 14, 14, 12, 7, 11, - 12, 12, 11, 7, 12, 13, - 13, 12, 9, 14, 14, 9, - 12, 12, 12, 13, 13, 14, - 15, 14, 14, 12, 11, 14, - 13, 11, 12, 13, 14, 14, - 13, 15, 15, 16, 14, 12, - 14, 12, 12, 14, 9, 14, - 13, 9, 12, 17, 15, 12, - 12, 14, 13, 13, 13, 13, - 14, 16, 13, 16, 15, 12, - 14, 16, 13, 14, 12, 11, - 13, 17, 15, 13, 15, 17, - 15, 13, 15, 13, 15, 17, - 13, 11, 14, 15, 13, 13, - 14, 17, 17, 17, 16, 14, - 17, 16, 15, 16, 17, 16, - 14, 15, 17, 15, 17, 16, - 14, 14, 14, 15, 12, 13, - 14, 17, 16, 14, 16, 17, - 17, 17, 14, 17, 17, 15, - 17, 15, 17, 16, 16, 11, - 17, 16, 12, 12, 17, 17, - 15, 15, 14, 17, 14, 13, - 14, 16, 16, 15, 13, 14, - 16, 14, 13, 14, 15, 17, - 14, 12, 14, 17, 16, 14, - 12, 16, 14, 13, 11, 15, - 17, 16, 13, 12, 15, 17, - 10, 12, 13, 16, 17, 14, - 13, 14, 15, 12, 13, 14, - 15, 17, 14, 14, 16, 15, - 14, 14, 17, 17, 14, 13, - 14, 16, 17, 15, 13, 15, - 15, 12, 11, 14, 17, 16, - 14, 13, 16, 15, 17, 16, - 15, 17, 16, 15, 15, 17, - 15, 16, 17, 16, 17, 17, - 17, 13, 12, 14, 17, 14, - 13, 15, 14, 17, 14, 14, - 16, 15, 16, 14, 15, 14, - 15, 17, 14, 17, 17, 15, - 12, 17, 17, 12, 12, 14, - 13, 14, 13, 14, 16, 15, - 13, 15, 17, 13, 13, 14, - 11, 13, 14, 13, 12, 14, - 15, 13, 17, 15, 14, 15, - 16, 13, 16, 16, 14, 12, - 14, 13, 14, 14, 7, 12, - 13, 12, 12, 9, 14, 14, - 9, 12, 14, 12, 12, 12, - 14, 15, 15, 15, 11, 11, - 13, 13, 12, 12, 13, 15, - 14, 14, 15, 16, 15, 15, - 12, 14, 12, 13, 14, 9, - 14, 13, 9, 8, 15, 15, - 15, 15, 12, 16, 16, 12, - 14, 15, 15, 15, 16, 17, - 17, 17, 17, 16, 15, 15, - 17, 15, 14, 15, 17, 16, - 15, 15, 17, 17, 16, 13, - 15, 15, 15, 15, 12, 15, - 16, 11, 12, 17, 16, 11, - 11, 15, 15, 15, 14, 14, - 15, 17, 14, 17, 15, 16, - 16, 16, 14, 17, 15, 15, - 13, 16, 15, 14, 15, 16, - 17, 15, 16, 14, 15, 16, - 13, 11, 14, 15, 16, 14, - 12, 16, 16, 16, 14, 12, - 16, 17, 13, 14, 13, 16, - 17, 16, 15, 15, 17, 17, - 14, 15, 15, 15, 15, 12, - 14, 17, 16, 15, 15, 17, - 17, 17, 15, 16, 16, 14, - 16, 13, 17, 16, 14, 15, - 16, 17, 15, 16, 16, 17, - 15, 16, 14, 17, 17, 16, - 16, 14, 15, 17, 17, 15, - 14, 14, 15, 13, 16, 17, - 14, 16, 17, 16, 16, 16, - 16, 17, 17, 16, 14, 17, - 16, 15, 16, 11, 17, 17, - 16, 16, 13, 17, 16, 14, - 14, 16, 17, 15, 15, 13, - 16, 15, 15, 15, 16, 15, - 16, 15, 12, 15, 17, 16, - 15, 12, 15, 16, 13, 12, - 15, 16, 17, 14, 11, 17, - 16, 13, 12, 15, 17, 17, - 15, 13, 16, 15, 12, 13, - 15, 17, 17, 14, 15, 17, - 15, 14, 17, 15, 17, 17, - 16, 12, 17, 17, 17, 16, - 14, 15, 17, 11, 13, 15, - 17, 16, 15, 12, 17, 17, - 11, 15, 17, 17, 16, 14, - 17, 15, 17, 16, 14, 17, - 17, 15, 16, 17, 14, 16, - 17, 14, 17, 16, 15, 14, - 17, 17, 12, 17, 17, 17, - 15, 15, 17, 16, 17, 15, - 14, 17, 14, 16, 17, 12, - 14, 17, 16, 17, 13, 17, - 16, 13, 15, 16, 15, 16, - 14, 15, 17, 17, 15, 14, - 14, 16, 17, 14, 11, 15, - 16, 16, 14, 16, 17, 17, - 15, 14, 15, 15, 15, 15, - 13, 15, 17, 14, 11, 17, - 17, 12, 11, 15, 17, 17, - 15, 14, 17, 16, 14, 17, - 17, 15, 15, 16, 15, 15, - 16, 14, 14, 15, 15, 15, - 16, 17, 15, 15, 16, 14, - 15, 16, 13, 11, 14, 16, - 17, 14, 13, 17, 17, 14, - 12, 16, 16, 17, 16, 17, - 17, 17, 16, 17, 17, 17, - 17, 17, 17, 17, 16, 17, - 17, 17, 17, 17, 17, 17, - 16, 17, 17, 16, 17, 17, - 16, 13, 16, 17, 16, 16, - 11, 17, 17, 17, 16, 15, - 17, 17, 14, 16, 16, 17, - 16, 17, 17, 17, 17, 17, - 17, 16, 16, 17, 15, 15, - 17, 17, 16, 15, 16, 17, - 16, 16, 15, 16, 17, 16, - 14, 13, 17, 17, 13, 15, - 17, 17, 14, 12, 17, 17, - 16, 15, 15, 17, 17, 15, - 17, 16, 17, 16, 17, 17, - 17, 17, 16, 13, 16, 17, - 16, 17, 17, 17, 17, 17, - 16, 17, 15, 16, 13, 16, - 16, 16, 15, 16, 17, 17, - 17, 17, 16, 17, 17, 16, - 17, 16, 16, 16, 15, 16, - 15, 17, 17, 17, 16, 15, - 16, 16, 15, 15, 16, 17, - 16, 17, 17, 17, 17, 16, - 17, 17, 16, 17, 16, 17, - 16, 16, 12, 17, 16, 14, - 13, 16, 17, 17, 15, 14, - 17, 17, 14, 16, 16, 17, - 16, 15, 17, 15, 17, 17, - 14, 17, 17, 15, 13, 14, - 17, 15, 16, 12, 16, 16, - 15, 12, 16, 17, 17, 15, - 14, 16, 17, 12, 12, 16, - 16, 16, 17, 14, 16, 16, - 13, 15, 16, 17, 17, 15, - 15, 16, 16, 16, 15, 17, - 17, 14, 14, 15, 17, 17, - 15, 14, 17, 15, 12, 12, - 14, 17, 17, 15, 14, 17, - 17, 17, 17, 15, 16, 17, - 15, 17, 16, 17, 15, 17, - 17, 16, 16, 16, 15, 16, - 17, 17, 15, 15, 16, 17, - 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 15, - 17, 17, 15, 14, 17, 17, - 14, 14, 16, 16, 17, 16, - 16, 17, 16, 15, 17, 17, - 16, 16, 17, 16, 16, 17, - 15, 15, 17, 17, 15, 17, - 17, 15, 15, 16, 16, 16, - 17, 15, 13, 17, 17, 17, - 17, 11, 16, 17, 17, 16, - 14, 17, 17, 14, 16, 17, - 17, 15, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 16, - 14, 16, 17, 16, 16, 17, - 16, 17, 16, 17, 16, 17, - 17, 17, 15, 16, 17, 15, - 9, 17, 17, 17, 16, 12, - 17, 17, 13, 15, 15, 17, - 17, 16, 16, 17, 17, 16, - 16, 17, 17, 17, 17, 16, - 17, 17, 17, 16, 15, 17, - 17, 16, 13, 17, 17, 17, - 15, 13, 17, 17, 13, 12, - 17, 17, 12, 9, 15, 17, - 17, 15, 14, 17, 17, 15, - 16, 17, 17, 16, 16, 17, - 17, 17, 16, 17, 17, 17, - 17, 14, 17, 17, 17, 16, - 14, 17, 17, 13, 11, 16, - 17, 17, 14, 10, 16, 17, - 17, 16, 12, 16, 17, 12, - 14, 16, 17, 17, 15, 16, - 17, 17, 16, 17, 17, 17, - 17, 17, 15, 17, 17, 17, - 17, 14, 16, 17, 15, 12, - 15, 16, 17, 15, 11, 17, - 17, 12, 13, 17, 17, 14, - 10, 16, 17, 17, 16, 13, - 16, 16, 14, 17, 15, 17, - 17, 17, 17, 17, 17, 17, - 15, 17, 16, 16, 15, 17, - 17, 17, 15, 13, 17, 16, - 14, 11, 16, 17, 17, 15, - 11, 16, 17, 17, 16, 12, - 17, 16, 14, 14, 17, 17, - 17, 16, 13, 16, 17, 15, - 17, 17, 17, 17, 17, 17, - 16, 17, 17, 17, 14, 16, - 17, 16, 15, 16, 17, 17, - 15, 12, 17, 16, 14, 11, - 17, 17, 17, 15, 14, 17, - 17, 14, 15, 17, 16, 17, - 17, 17, 16, 16, 17, 17, - 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, - 14, 14, 17, 17, 17, 17, - 14, 17, 17, 12, 14, 17, - 17, 14, 11, 16, 17, 17, - 15, 15, 16, 17, 13, 17, - 16, 17, 17, 15, 17, 17, - 17, 16, 16, 17, 16, 14, - 15, 16, 17, 17, 15, 15, - 17, 17, 13, 11, 15, 17, - 17, 16, 10, 16, 16, 17, - 16, 12, 17, 17, 12, 14, - 15, 17, 17, 15, 16, 17, - 15, 15, 17, 16, 17, 16, - 16, 15, 16, 17, 17, 16, - 15, 17, 17, 14, 13, 14, - 16, 17, 14, 12, 17, 16, - 13, 12, 16, 17, 13, 9, - 15, 17, 17, 16, 15, 17, - 17, 14, 16, 16, 17, 17, - 16, 16, 17, 17, 17, 15, - 17, 16, 16, 15, 16, 17, - 17, 15, 13, 17, 17, 14, - 11, 15, 17, 17, 15, 9, - 16, 17, 17, 15, 12, 17, - 16, 13, 14, 17, 17, 17, - 16, 16, 17, 17, 15, 16, - 17, 17, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 16, - 16, 15, 17, 17, 17, 15, - 12, 17, 16, 12, 12, 16, - 17, 12, 10, 17, 17, 17, - 14, 14, 17, 17, 14, 14, - 16, 17, 17, 15, 16, 17, - 17, 17, 16, 17, 16, 17, - 14, 17, 17, 17, 16, 13, - 17, 17, 14, 9, 15, 17, - 17, 15, 10, 15, 17, 17, - 15, 12, 17, 17, 13, 13, - 16, 17, 17, 15, 14, 17, - 17, 14, 17, 16, 16, 17, - 17, 17, 17, 17, 17, 17, - 15, 17, 16, 15, 14, 15, - 17, 17, 16, 12, 16, 17, - 12, 13, 17, 17, 13, 11, - 17, 17, 17, 16, 12, 16, - 17, 15, 15, 15, 17, 17, - 17, 16, 16, 17, 16, 16, - 17, 17, 16, 16, 15, 17, - 17, 16, 13, 15, 17, 14, - 11, 15, 17, 16, 15, 12, - 17, 17, 16, 17, 12, 17, - 17, 15, 14, 16, 17, 17, - 15, 15, 17, 17, 15, 15, - 17, 17, 17, 16, 17, 17, - 17, 17, 17, 16, 15, 16, - 17, 14, 15, 16, 17, 17, - 15, 17, 17, 13, 12, 17, - 17, 17, 16, 14, 17, 17, - 12, 15, 15, 17, 17, 16, - 15, 17, 17, 14, 16, 17, - 17, 17, 17, 17, 17, 17, - 16, 15, 15, 17, 15, 15, - 14, 15, 17, 17, 15, 13, - 17, 17, 14, 14, 17, 17, - 14, 10, 16, 17, 17, 15, - 14, 17, 17, 13, 15, 16, - 17, 17, 15, 17, 16, 17, - 15, 17, 16, 17, 17, 15, - 16, 17, 17, 14, 14, 17, - 16, 12, 10, 16, 17, 17, - 15, 10, 16, 17, 17, 15, - 12, 17, 17, 13, 13, 15, - 17, 17, 15, 15, 17, 17, - 13, 14, 17, 17, 17, 16, - 17, 17, 17, 17, 17, 15, - 17, 16, 16, 13, 17, 16, - 17, 17, 12, 17, 17, 12, - 13, 17, 17, 12, 11, 15, - 16, 17, 17, 13, 16, 16, - 14, 14, 15, 17, 17, 16, - 16, 17, 17, 16, 17, 17, - 17, 17, 15, 17, 17, 17, - 16, 15, 17, 17, 14, 9, - 17, 17, 17, 15, 15, 17, - 17, 14, 13, 16, 17, 16, - 16, 16, 17, 17, 16, 16, - 16, 17, 17, 16, 16, 16, - 17, 16, 16, 17, 17, 17, - 17, 17, 17, 17, 16, 17, - 16, 17, 17, 12, 16, 17, - 17, 17, 10, 17, 16, 17, - 17, 13, 17, 17, 14, 16, - 17, 17, 15, 17, 17, 17, - 17, 17, 13, 16, 17, 16, - 15, 16, 15, 17, 16, 15, - 17, 17, 17, 17, 15, 16, - 16, 15, 16, 14, 17, 17, - 13, 15, 17, 17, 15, 13, - 17, 15, 17, 17, 15, 17, - 16, 15, 17, 16, 17, 17, - 16, 13, 16, 17, 15, 17, - 17, 17, 17, 17, 16, 17, - 16, 17, 15, 16, 17, 15, - 13, 16, 16, 16, 16, 14, - 17, 17, 17, 16, 15, 17, - 16, 17, 16, 16, 17, 15, - 17, 16, 17, 16, 17, 14, - 15, 17, 17, 17, 16, 16, - 16, 17, 17, 17, 16, 17, - 17, 16, 17, 17, 16, 17, - 16, 17, 17, 14, 13, 17, - 17, 14, 12, 17, 17, 17, - 15, 12, 17, 16, 15, 15, - 15, 17, 17, 17, 14, 16, - 17, 16, 16, 16, 17, 17, - 17, 15, 17, 17, 17, 14, - 16, 15, 14, 13, 14, 17, - 17, 17, 15, 16, 17, 12, - 13, 15, 17, 17, 16, 14, - 16, 16, 12, 14, 16, 16, - 17, 15, 16, 17, 16, 13, - 16, 16, 16, 17, 15, 15, - 16, 17, 14, 14, 17, 17, - 13, 12, 15, 17, 17, 15, - 14, 16, 16, 17, 17, 15, - 17, 17, 17, 16, 16, 17, - 16, 16, 17, 17, 17, 17, - 15, 16, 17, 17, 16, 16, - 16, 17, 15, 17, 17, 17, - 15, 16, 16, 17, 17, 16, - 16, 15, 17, 17, 15, 14, - 17, 17, 14, 14, 16, 17, - 17, 17, 15, 16, 17, 16, - 17, 16, 16, 17, 17, 16, - 15, 16, 15, 16, 17, 17, - 15, 17, 17, 16, 16, 16, - 15, 17, 17, 15, 12, 16, - 17, 17, 16, 11, 17, 17, - 16, 16, 14, 16, 17, 14, - 16, 16, 17, 16, 15, 17, - 17, 17, 16, 15, 15, 17, - 17, 17, 17, 17, 17, 17, - 16, 17, 17, 17, 16, 14, - 17, 16, 17, 16, 13, 17, - 17, 13, 8, 15, 15, 15, - 14, 12, 16, 17, 12, 13, - 15, 15, 16, 16, 16, 17, - 17, 16, 12, 15, 17, 15, - 16, 14, 15, 16, 17, 16, - 17, 17, 17, 17, 15, 16, - 15, 15, 15, 12, 16, 17, - 12, 11, 17, 17, 11, 11, - 14, 15, 15, 13, 13, 16, - 15, 13, 16, 15, 16, 17, - 15, 13, 15, 15, 15, 15, - 15, 16, 14, 17, 17, 14, - 17, 17, 14, 16, 17, 14, - 11, 14, 14, 16, 14, 12, - 16, 15, 16, 15, 13, 15, - 16, 13, 14, 15, 15, 15, - 15, 15, 16, 17, 17, 11, - 14, 17, 16, 14, 15, 16, - 16, 16, 15, 16, 15, 17, - 16, 15, 14, 16, 16, 16, - 13, 17, 17, 13, 15, 17, - 17, 15, 15, 17, 17, 16, - 16, 15, 17, 17, 15, 16, - 17, 17, 15, 17, 13, 14, - 16, 14, 16, 15, 15, 14, - 16, 17, 15, 16, 16, 15, - 17, 17, 16, 15, 16, 16, - 16, 15, 10, 16, 17, 17, - 15, 11, 16, 17, 12, 13, - 14, 17, 15, 15, 12, 17, - 15, 14, 12, 15, 17, 17, - 15, 15, 16, 17, 17, 16, - 14, 15, 15, 15, 14, 15, - 16, 15, 15, 12, 17, 15, - 13, 11, 16, 17, 17, 16, - 13, 16, 17, 11, 12, 15, - 16, 17, 14, 14, 15, 17, - 11, 13, 17, 17, 17, 15, - 17, 16, 15, 16, 14, 16, - 16, 17, 14, 13, 14, 16, - 17, 14, 14, 15, 16, 12, - 15, 17, 17, 16, 14, 17, - 16, 17, 17, 16, 17, 17, - 15, 16, 17, 15, 15, 17, - 14, 15, 15, 13, 15, 15, - 15, 16, 17, 17, 16, 15, - 14, 17, 17, 17, 15, 14, - 16, 17, 17, 17, 11, 14, - 14, 16, 17, 14, 15, 16, - 14, 13, 15, 14, 17, 16, - 15, 16, 17, 17, 11, 15, - 17, 17, 14, 14, 16, 16, - 16, 14, 17, 17, 15, 16, - 14, 15, 17, 16, 13, 13, - 16, 16, 12, 11, 17, 17, - 12, 11, 14, 16, 17, 15, - 14, 16, 17, 13, 15, 16, - 15, 16, 16, 15, 15, 15, - 13, 14, 15, 15, 16, 17, - 17, 15, 15, 16, 15, 16, - 16, 13, 10, 16, 15, 15, - 15, 7, 14, 14, 7, 7, - 11, 12, 12, 11, 12, 14, - 14, 12, 15, 16, 13, 14, - 16, 13, 13, 15, 13, 11, - 12, 13, 11, 15, 15, 13, - 12, 15, 12, 14, 15, 12, - 7, 12, 12, 12, 11, 6, - 12, 12, 13, 12, 9, 14, - 14, 9, 12, 13, 13, 12, - 14, 15, 16, 17, 14, 12, - 13, 13, 15, 13, 11, 12, - 14, 12, 11, 14, 15, 17, - 14, 12, 13, 12, 13, 14, - 9, 13, 15, 9, 12, 17, - 16, 12, 11, 14, 14, 13, - 15, 13, 16, 17, 14, 15, - 17, 14, 14, 15, 13, 15, - 14, 12, 12, 14, 12, 11, - 16, 15, 13, 13, 16, 13, - 15, 15, 14, 12, 13, 14, - 15, 14, 13, 17, 16, 16, - 16, 15, 17, 17, 14, 14, - 16, 14, 15, 17, 15, 17, - 17, 16, 13, 14, 16, 16, - 13, 14, 14, 15, 14, 12, - 17, 16, 17, 17, 16, 15, - 15, 14, 16, 16, 17, 17, - 15, 11, 16, 16, 13, 11, - 14, 16, 17, 14, 10, 17, - 16, 12, 13, 15, 17, 16, - 14, 13, 17, 16, 14, 15, - 17, 14, 13, 14, 14, 16, - 15, 13, 13, 17, 15, 12, - 12, 15, 17, 17, 15, 12, - 16, 16, 11, 11, 14, 17, - 17, 14, 13, 15, 17, 12, - 12, 14, 16, 17, 17, 14, - 15, 16, 14, 15, 15, 16, - 15, 13, 13, 16, 15, 15, - 13, 15, 15, 13, 13, 15, - 16, 17, 15, 14, 15, 16, - 17, 17, 14, 17, 17, 14, - 14, 15, 14, 17, 16, 16, - 17, 17, 17, 12, 15, 16, - 17, 15, 14, 12, 13, 15, - 12, 15, 17, 16, 16, 16, - 17, 14, 14, 15, 15, 17, - 17, 15, 12, 16, 16, 12, - 11, 14, 14, 14, 14, 14, - 14, 15, 13, 15, 16, 13, - 14, 16, 13, 16, 14, 13, - 11, 12, 14, 13, 16, 15, - 13, 14, 15, 13, 15, 15, - 12, 11, 15, 13, 13, 14, - 7, 12, 13, 12, 12, 9, - 15, 15, 9, 12, 14, 12, - 12, 14, 15, 15, 15, 15, - 13, 14, 16, 14, 14, 12, - 11, 13, 14, 12, 14, 16, - 14, 14, 12, 14, 12, 12, - 12, 9, 14, 14, 9, -}; - -static const uint16_t on2avc_cb7_syms[ON2AVC_CB7_CODES] = { - 0x0000, 0x0002, 0x0004, 0x000C, 0x000E, 0x0011, - 0x0013, 0x001D, 0x001F, 0x0020, 0x0022, 0x0024, - 0x002C, 0x002E, 0x0031, 0x0033, 0x003D, 0x003F, - 0x0040, 0x0042, 0x0044, 0x004C, 0x004E, 0x00C0, - 0x00C2, 0x00C4, 0x00CC, 0x00CE, 0x00D1, 0x00D3, - 0x00DD, 0x00DF, 0x00E0, 0x00E2, 0x00E4, 0x00EC, - 0x00EE, 0x00F1, 0x00F3, 0x00FD, 0x00FF, 0x0101, - 0x0103, 0x010D, 0x010F, 0x0110, 0x0112, 0x0114, - 0x011C, 0x011E, 0x0121, 0x0123, 0x012D, 0x012F, - 0x0130, 0x0132, 0x0134, 0x013C, 0x013E, 0x0141, - 0x0143, 0x014D, 0x014F, 0x01C1, 0x01C3, 0x01CD, - 0x01CF, 0x01D0, 0x01D2, 0x01D4, 0x01DC, 0x01DE, - 0x01E1, 0x01E3, 0x01ED, 0x01EF, 0x01F0, 0x01F2, - 0x01F4, 0x01FC, 0x01FE, 0x0200, 0x0202, 0x0204, - 0x020C, 0x020E, 0x0211, 0x0213, 0x021D, 0x021F, - 0x0220, 0x0222, 0x0224, 0x022C, 0x022E, 0x0231, - 0x0233, 0x023D, 0x023F, 0x0240, 0x0242, 0x0244, - 0x024C, 0x024E, 0x02C0, 0x02C2, 0x02C4, 0x02CC, - 0x02CE, 0x02D1, 0x02D3, 0x02DD, 0x02DF, 0x02E0, - 0x02E2, 0x02E4, 0x02EC, 0x02EE, 0x02F1, 0x02F3, - 0x02FD, 0x02FF, 0x0301, 0x0303, 0x030D, 0x030F, - 0x0310, 0x0312, 0x0314, 0x031C, 0x031E, 0x0321, - 0x0323, 0x032D, 0x032F, 0x0330, 0x0332, 0x0334, - 0x033C, 0x033E, 0x0341, 0x0343, 0x034D, 0x034F, - 0x03C1, 0x03C3, 0x03CD, 0x03CF, 0x03D0, 0x03D2, - 0x03D4, 0x03DC, 0x03DE, 0x03E1, 0x03E3, 0x03ED, - 0x03EF, 0x03F0, 0x03F2, 0x03F4, 0x03FC, 0x03FE, - 0x0400, 0x0402, 0x0404, 0x040C, 0x040E, 0x0411, - 0x0413, 0x041D, 0x041F, 0x0420, 0x0422, 0x0424, - 0x042C, 0x042E, 0x0431, 0x0433, 0x043D, 0x043F, - 0x0440, 0x0442, 0x0444, 0x044C, 0x044E, 0x04C0, - 0x04C2, 0x04C4, 0x04CC, 0x04CE, 0x04D1, 0x04D3, - 0x04DD, 0x04DF, 0x04E0, 0x04E2, 0x04E4, 0x04EC, - 0x04EE, 0x04F1, 0x04F3, 0x04FD, 0x04FF, 0x0C00, - 0x0C02, 0x0C04, 0x0C0C, 0x0C0E, 0x0C11, 0x0C13, - 0x0C1D, 0x0C1F, 0x0C20, 0x0C22, 0x0C24, 0x0C2C, - 0x0C2E, 0x0C31, 0x0C33, 0x0C3D, 0x0C3F, 0x0C40, - 0x0C42, 0x0C44, 0x0C4C, 0x0C4E, 0x0CC0, 0x0CC2, - 0x0CC4, 0x0CCC, 0x0CCE, 0x0CD1, 0x0CD3, 0x0CDD, - 0x0CDF, 0x0CE0, 0x0CE2, 0x0CE4, 0x0CEC, 0x0CEE, - 0x0CF1, 0x0CF3, 0x0CFD, 0x0CFF, 0x0D01, 0x0D03, - 0x0D0D, 0x0D0F, 0x0D10, 0x0D12, 0x0D14, 0x0D1C, - 0x0D1E, 0x0D21, 0x0D23, 0x0D2D, 0x0D2F, 0x0D30, - 0x0D32, 0x0D34, 0x0D3C, 0x0D3E, 0x0D41, 0x0D43, - 0x0D4D, 0x0D4F, 0x0DC1, 0x0DC3, 0x0DCD, 0x0DCF, - 0x0DD0, 0x0DD2, 0x0DD4, 0x0DDC, 0x0DDE, 0x0DE1, - 0x0DE3, 0x0DED, 0x0DEF, 0x0DF0, 0x0DF2, 0x0DF4, - 0x0DFC, 0x0DFE, 0x0E00, 0x0E02, 0x0E04, 0x0E0C, - 0x0E0E, 0x0E11, 0x0E13, 0x0E1D, 0x0E1F, 0x0E20, - 0x0E22, 0x0E24, 0x0E2C, 0x0E2E, 0x0E31, 0x0E33, - 0x0E3D, 0x0E3F, 0x0E40, 0x0E42, 0x0E44, 0x0E4C, - 0x0E4E, 0x0EC0, 0x0EC2, 0x0EC4, 0x0ECC, 0x0ECE, - 0x0ED1, 0x0ED3, 0x0EDD, 0x0EDF, 0x0EE0, 0x0EE2, - 0x0EE4, 0x0EEC, 0x0EEE, 0x0EF1, 0x0EF3, 0x0EFD, - 0x0EFF, 0x0F01, 0x0F03, 0x0F0D, 0x0F0F, 0x0F10, - 0x0F12, 0x0F14, 0x0F1C, 0x0F1E, 0x0F21, 0x0F23, - 0x0F2D, 0x0F2F, 0x0F30, 0x0F32, 0x0F34, 0x0F3C, - 0x0F3E, 0x0F41, 0x0F43, 0x0F4D, 0x0F4F, 0x0FC1, - 0x0FC3, 0x0FCD, 0x0FCF, 0x0FD0, 0x0FD2, 0x0FD4, - 0x0FDC, 0x0FDE, 0x0FE1, 0x0FE3, 0x0FED, 0x0FEF, - 0x0FF0, 0x0FF2, 0x0FF4, 0x0FFC, 0x0FFE, 0x1001, - 0x1003, 0x100D, 0x100F, 0x1010, 0x1012, 0x1014, - 0x101C, 0x101E, 0x1021, 0x1023, 0x102D, 0x102F, - 0x1030, 0x1032, 0x1034, 0x103C, 0x103E, 0x1041, - 0x1043, 0x104D, 0x104F, 0x10C1, 0x10C3, 0x10CD, - 0x10CF, 0x10D0, 0x10D2, 0x10D4, 0x10DC, 0x10DE, - 0x10E1, 0x10E3, 0x10ED, 0x10EF, 0x10F0, 0x10F2, - 0x10F4, 0x10FC, 0x10FE, 0x1100, 0x1102, 0x1104, - 0x110C, 0x110E, 0x1111, 0x1113, 0x111D, 0x111F, - 0x1120, 0x1122, 0x1124, 0x112C, 0x112E, 0x1131, - 0x1133, 0x113D, 0x113F, 0x1140, 0x1142, 0x1144, - 0x114C, 0x114E, 0x11C0, 0x11C2, 0x11C4, 0x11CC, - 0x11CE, 0x11D1, 0x11D3, 0x11DD, 0x11DF, 0x11E0, - 0x11E2, 0x11E4, 0x11EC, 0x11EE, 0x11F1, 0x11F3, - 0x11FD, 0x11FF, 0x1201, 0x1203, 0x120D, 0x120F, - 0x1210, 0x1212, 0x1214, 0x121C, 0x121E, 0x1221, - 0x1223, 0x122D, 0x122F, 0x1230, 0x1232, 0x1234, - 0x123C, 0x123E, 0x1241, 0x1243, 0x124D, 0x124F, - 0x12C1, 0x12C3, 0x12CD, 0x12CF, 0x12D0, 0x12D2, - 0x12D4, 0x12DC, 0x12DE, 0x12E1, 0x12E3, 0x12ED, - 0x12EF, 0x12F0, 0x12F2, 0x12F4, 0x12FC, 0x12FE, - 0x1300, 0x1302, 0x1304, 0x130C, 0x130E, 0x1311, - 0x1313, 0x131D, 0x131F, 0x1320, 0x1322, 0x1324, - 0x132C, 0x132E, 0x1331, 0x1333, 0x133D, 0x133F, - 0x1340, 0x1342, 0x1344, 0x134C, 0x134E, 0x13C0, - 0x13C2, 0x13C4, 0x13CC, 0x13CE, 0x13D1, 0x13D3, - 0x13DD, 0x13DF, 0x13E0, 0x13E2, 0x13E4, 0x13EC, - 0x13EE, 0x13F1, 0x13F3, 0x13FD, 0x13FF, 0x1401, - 0x1403, 0x140D, 0x140F, 0x1410, 0x1412, 0x1414, - 0x141C, 0x141E, 0x1421, 0x1423, 0x142D, 0x142F, - 0x1430, 0x1432, 0x1434, 0x143C, 0x143E, 0x1441, - 0x1443, 0x144D, 0x144F, 0x14C1, 0x14C3, 0x14CD, - 0x14CF, 0x14D0, 0x14D2, 0x14D4, 0x14DC, 0x14DE, - 0x14E1, 0x14E3, 0x14ED, 0x14EF, 0x14F0, 0x14F2, - 0x14F4, 0x14FC, 0x14FE, 0x1C01, 0x1C03, 0x1C0D, - 0x1C0F, 0x1C10, 0x1C12, 0x1C14, 0x1C1C, 0x1C1E, - 0x1C21, 0x1C23, 0x1C2D, 0x1C2F, 0x1C30, 0x1C32, - 0x1C34, 0x1C3C, 0x1C3E, 0x1C41, 0x1C43, 0x1C4D, - 0x1C4F, 0x1CC1, 0x1CC3, 0x1CCD, 0x1CCF, 0x1CD0, - 0x1CD2, 0x1CD4, 0x1CDC, 0x1CDE, 0x1CE1, 0x1CE3, - 0x1CED, 0x1CEF, 0x1CF0, 0x1CF2, 0x1CF4, 0x1CFC, - 0x1CFE, 0x1D00, 0x1D02, 0x1D04, 0x1D0C, 0x1D0E, - 0x1D11, 0x1D13, 0x1D1D, 0x1D1F, 0x1D20, 0x1D22, - 0x1D24, 0x1D2C, 0x1D2E, 0x1D31, 0x1D33, 0x1D3D, - 0x1D3F, 0x1D40, 0x1D42, 0x1D44, 0x1D4C, 0x1D4E, - 0x1DC0, 0x1DC2, 0x1DC4, 0x1DCC, 0x1DCE, 0x1DD1, - 0x1DD3, 0x1DDD, 0x1DDF, 0x1DE0, 0x1DE2, 0x1DE4, - 0x1DEC, 0x1DEE, 0x1DF1, 0x1DF3, 0x1DFD, 0x1DFF, - 0x1E01, 0x1E03, 0x1E0D, 0x1E0F, 0x1E10, 0x1E12, - 0x1E14, 0x1E1C, 0x1E1E, 0x1E21, 0x1E23, 0x1E2D, - 0x1E2F, 0x1E30, 0x1E32, 0x1E34, 0x1E3C, 0x1E3E, - 0x1E41, 0x1E43, 0x1E4D, 0x1E4F, 0x1EC1, 0x1EC3, - 0x1ECD, 0x1ECF, 0x1ED0, 0x1ED2, 0x1ED4, 0x1EDC, - 0x1EDE, 0x1EE1, 0x1EE3, 0x1EED, 0x1EEF, 0x1EF0, - 0x1EF2, 0x1EF4, 0x1EFC, 0x1EFE, 0x1F00, 0x1F02, - 0x1F04, 0x1F0C, 0x1F0E, 0x1F11, 0x1F13, 0x1F1D, - 0x1F1F, 0x1F20, 0x1F22, 0x1F24, 0x1F2C, 0x1F2E, - 0x1F31, 0x1F33, 0x1F3D, 0x1F3F, 0x1F40, 0x1F42, - 0x1F44, 0x1F4C, 0x1F4E, 0x1FC0, 0x1FC2, 0x1FC4, - 0x1FCC, 0x1FCE, 0x1FD1, 0x1FD3, 0x1FDD, 0x1FDF, - 0x1FE0, 0x1FE2, 0x1FE4, 0x1FEC, 0x1FEE, 0x1FF1, - 0x1FF3, 0x1FFD, 0x1FFF, 0x2000, 0x2002, 0x2004, - 0x200C, 0x200E, 0x2011, 0x2013, 0x201D, 0x201F, - 0x2020, 0x2022, 0x2024, 0x202C, 0x202E, 0x2031, - 0x2033, 0x203D, 0x203F, 0x2040, 0x2042, 0x2044, - 0x204C, 0x204E, 0x20C0, 0x20C2, 0x20C4, 0x20CC, - 0x20CE, 0x20D1, 0x20D3, 0x20DD, 0x20DF, 0x20E0, - 0x20E2, 0x20E4, 0x20EC, 0x20EE, 0x20F1, 0x20F3, - 0x20FD, 0x20FF, 0x2101, 0x2103, 0x210D, 0x210F, - 0x2110, 0x2112, 0x2114, 0x211C, 0x211E, 0x2121, - 0x2123, 0x212D, 0x212F, 0x2130, 0x2132, 0x2134, - 0x213C, 0x213E, 0x2141, 0x2143, 0x214D, 0x214F, - 0x21C1, 0x21C3, 0x21CD, 0x21CF, 0x21D0, 0x21D2, - 0x21D4, 0x21DC, 0x21DE, 0x21E1, 0x21E3, 0x21ED, - 0x21EF, 0x21F0, 0x21F2, 0x21F4, 0x21FC, 0x21FE, - 0x2200, 0x2202, 0x2204, 0x220C, 0x220E, 0x2211, - 0x2213, 0x221D, 0x221F, 0x2220, 0x2222, 0x2224, - 0x222C, 0x222E, 0x2231, 0x2233, 0x223D, 0x223F, - 0x2240, 0x2242, 0x2244, 0x224C, 0x224E, 0x22C0, - 0x22C2, 0x22C4, 0x22CC, 0x22CE, 0x22D1, 0x22D3, - 0x22DD, 0x22DF, 0x22E0, 0x22E2, 0x22E4, 0x22EC, - 0x22EE, 0x22F1, 0x22F3, 0x22FD, 0x22FF, 0x2301, - 0x2303, 0x230D, 0x230F, 0x2310, 0x2312, 0x2314, - 0x231C, 0x231E, 0x2321, 0x2323, 0x232D, 0x232F, - 0x2330, 0x2332, 0x2334, 0x233C, 0x233E, 0x2341, - 0x2343, 0x234D, 0x234F, 0x23C1, 0x23C3, 0x23CD, - 0x23CF, 0x23D0, 0x23D2, 0x23D4, 0x23DC, 0x23DE, - 0x23E1, 0x23E3, 0x23ED, 0x23EF, 0x23F0, 0x23F2, - 0x23F4, 0x23FC, 0x23FE, 0x2400, 0x2402, 0x2404, - 0x240C, 0x240E, 0x2411, 0x2413, 0x241D, 0x241F, - 0x2420, 0x2422, 0x2424, 0x242C, 0x242E, 0x2431, - 0x2433, 0x243D, 0x243F, 0x2440, 0x2442, 0x2444, - 0x244C, 0x244E, 0x24C0, 0x24C2, 0x24C4, 0x24CC, - 0x24CE, 0x24D1, 0x24D3, 0x24DD, 0x24DF, 0x24E0, - 0x24E2, 0x24E4, 0x24EC, 0x24EE, 0x24F1, 0x24F3, - 0x24FD, 0x24FF, 0x2C00, 0x2C02, 0x2C04, 0x2C0C, - 0x2C0E, 0x2C11, 0x2C13, 0x2C1D, 0x2C1F, 0x2C20, - 0x2C22, 0x2C24, 0x2C2C, 0x2C2E, 0x2C31, 0x2C33, - 0x2C3D, 0x2C3F, 0x2C40, 0x2C42, 0x2C44, 0x2C4C, - 0x2C4E, 0x2CC0, 0x2CC2, 0x2CC4, 0x2CCC, 0x2CCE, - 0x2CD1, 0x2CD3, 0x2CDD, 0x2CDF, 0x2CE0, 0x2CE2, - 0x2CE4, 0x2CEC, 0x2CEE, 0x2CF1, 0x2CF3, 0x2CFD, - 0x2CFF, 0x2D01, 0x2D03, 0x2D0D, 0x2D0F, 0x2D10, - 0x2D12, 0x2D14, 0x2D1C, 0x2D1E, 0x2D21, 0x2D23, - 0x2D2D, 0x2D2F, 0x2D30, 0x2D32, 0x2D34, 0x2D3C, - 0x2D3E, 0x2D41, 0x2D43, 0x2D4D, 0x2D4F, 0x2DC1, - 0x2DC3, 0x2DCD, 0x2DCF, 0x2DD0, 0x2DD2, 0x2DD4, - 0x2DDC, 0x2DDE, 0x2DE1, 0x2DE3, 0x2DED, 0x2DEF, - 0x2DF0, 0x2DF2, 0x2DF4, 0x2DFC, 0x2DFE, 0x2E00, - 0x2E02, 0x2E04, 0x2E0C, 0x2E0E, 0x2E11, 0x2E13, - 0x2E1D, 0x2E1F, 0x2E20, 0x2E22, 0x2E24, 0x2E2C, - 0x2E2E, 0x2E31, 0x2E33, 0x2E3D, 0x2E3F, 0x2E40, - 0x2E42, 0x2E44, 0x2E4C, 0x2E4E, 0x2EC0, 0x2EC2, - 0x2EC4, 0x2ECC, 0x2ECE, 0x2ED1, 0x2ED3, 0x2EDD, - 0x2EDF, 0x2EE0, 0x2EE2, 0x2EE4, 0x2EEC, 0x2EEE, - 0x2EF1, 0x2EF3, 0x2EFD, 0x2EFF, 0x2F01, 0x2F03, - 0x2F0D, 0x2F0F, 0x2F10, 0x2F12, 0x2F14, 0x2F1C, - 0x2F1E, 0x2F21, 0x2F23, 0x2F2D, 0x2F2F, 0x2F30, - 0x2F32, 0x2F34, 0x2F3C, 0x2F3E, 0x2F41, 0x2F43, - 0x2F4D, 0x2F4F, 0x2FC1, 0x2FC3, 0x2FCD, 0x2FCF, - 0x2FD0, 0x2FD2, 0x2FD4, 0x2FDC, 0x2FDE, 0x2FE1, - 0x2FE3, 0x2FED, 0x2FEF, 0x2FF0, 0x2FF2, 0x2FF4, - 0x2FFC, 0x2FFE, 0x3001, 0x3003, 0x300D, 0x300F, - 0x3010, 0x3012, 0x3014, 0x301C, 0x301E, 0x3021, - 0x3023, 0x302D, 0x302F, 0x3030, 0x3032, 0x3034, - 0x303C, 0x303E, 0x3041, 0x3043, 0x304D, 0x304F, - 0x30C1, 0x30C3, 0x30CD, 0x30CF, 0x30D0, 0x30D2, - 0x30D4, 0x30DC, 0x30DE, 0x30E1, 0x30E3, 0x30ED, - 0x30EF, 0x30F0, 0x30F2, 0x30F4, 0x30FC, 0x30FE, - 0x3100, 0x3102, 0x3104, 0x310C, 0x310E, 0x3111, - 0x3113, 0x311D, 0x311F, 0x3120, 0x3122, 0x3124, - 0x312C, 0x312E, 0x3131, 0x3133, 0x313D, 0x313F, - 0x3140, 0x3142, 0x3144, 0x314C, 0x314E, 0x31C0, - 0x31C2, 0x31C4, 0x31CC, 0x31CE, 0x31D1, 0x31D3, - 0x31DD, 0x31DF, 0x31E0, 0x31E2, 0x31E4, 0x31EC, - 0x31EE, 0x31F1, 0x31F3, 0x31FD, 0x31FF, 0x3201, - 0x3203, 0x320D, 0x320F, 0x3210, 0x3212, 0x3214, - 0x321C, 0x321E, 0x3221, 0x3223, 0x322D, 0x322F, - 0x3230, 0x3232, 0x3234, 0x323C, 0x323E, 0x3241, - 0x3243, 0x324D, 0x324F, 0x32C1, 0x32C3, 0x32CD, - 0x32CF, 0x32D0, 0x32D2, 0x32D4, 0x32DC, 0x32DE, - 0x32E1, 0x32E3, 0x32ED, 0x32EF, 0x32F0, 0x32F2, - 0x32F4, 0x32FC, 0x32FE, 0x3300, 0x3302, 0x3304, - 0x330C, 0x330E, 0x3311, 0x3313, 0x331D, 0x331F, - 0x3320, 0x3322, 0x3324, 0x332C, 0x332E, 0x3331, - 0x3333, 0x333D, 0x333F, 0x3340, 0x3342, 0x3344, - 0x334C, 0x334E, 0x33C0, 0x33C2, 0x33C4, 0x33CC, - 0x33CE, 0x33D1, 0x33D3, 0x33DD, 0x33DF, 0x33E0, - 0x33E2, 0x33E4, 0x33EC, 0x33EE, 0x33F1, 0x33F3, - 0x33FD, 0x33FF, 0x3401, 0x3403, 0x340D, 0x340F, - 0x3410, 0x3412, 0x3414, 0x341C, 0x341E, 0x3421, - 0x3423, 0x342D, 0x342F, 0x3430, 0x3432, 0x3434, - 0x343C, 0x343E, 0x3441, 0x3443, 0x344D, 0x344F, - 0x34C1, 0x34C3, 0x34CD, 0x34CF, 0x34D0, 0x34D2, - 0x34D4, 0x34DC, 0x34DE, 0x34E1, 0x34E3, 0x34ED, - 0x34EF, 0x34F0, 0x34F2, 0x34F4, 0x34FC, 0x34FE, - 0x3C01, 0x3C03, 0x3C0D, 0x3C0F, 0x3C10, 0x3C12, - 0x3C14, 0x3C1C, 0x3C1E, 0x3C21, 0x3C23, 0x3C2D, - 0x3C2F, 0x3C30, 0x3C32, 0x3C34, 0x3C3C, 0x3C3E, - 0x3C41, 0x3C43, 0x3C4D, 0x3C4F, 0x3CC1, 0x3CC3, - 0x3CCD, 0x3CCF, 0x3CD0, 0x3CD2, 0x3CD4, 0x3CDC, - 0x3CDE, 0x3CE1, 0x3CE3, 0x3CED, 0x3CEF, 0x3CF0, - 0x3CF2, 0x3CF4, 0x3CFC, 0x3CFE, 0x3D00, 0x3D02, - 0x3D04, 0x3D0C, 0x3D0E, 0x3D11, 0x3D13, 0x3D1D, - 0x3D1F, 0x3D20, 0x3D22, 0x3D24, 0x3D2C, 0x3D2E, - 0x3D31, 0x3D33, 0x3D3D, 0x3D3F, 0x3D40, 0x3D42, - 0x3D44, 0x3D4C, 0x3D4E, 0x3DC0, 0x3DC2, 0x3DC4, - 0x3DCC, 0x3DCE, 0x3DD1, 0x3DD3, 0x3DDD, 0x3DDF, - 0x3DE0, 0x3DE2, 0x3DE4, 0x3DEC, 0x3DEE, 0x3DF1, - 0x3DF3, 0x3DFD, 0x3DFF, 0x3E01, 0x3E03, 0x3E0D, - 0x3E0F, 0x3E10, 0x3E12, 0x3E14, 0x3E1C, 0x3E1E, - 0x3E21, 0x3E23, 0x3E2D, 0x3E2F, 0x3E30, 0x3E32, - 0x3E34, 0x3E3C, 0x3E3E, 0x3E41, 0x3E43, 0x3E4D, - 0x3E4F, 0x3EC1, 0x3EC3, 0x3ECD, 0x3ECF, 0x3ED0, - 0x3ED2, 0x3ED4, 0x3EDC, 0x3EDE, 0x3EE1, 0x3EE3, - 0x3EED, 0x3EEF, 0x3EF0, 0x3EF2, 0x3EF4, 0x3EFC, - 0x3EFE, 0x3F00, 0x3F02, 0x3F04, 0x3F0C, 0x3F0E, - 0x3F11, 0x3F13, 0x3F1D, 0x3F1F, 0x3F20, 0x3F22, - 0x3F24, 0x3F2C, 0x3F2E, 0x3F31, 0x3F33, 0x3F3D, - 0x3F3F, 0x3F40, 0x3F42, 0x3F44, 0x3F4C, 0x3F4E, - 0x3FC0, 0x3FC2, 0x3FC4, 0x3FCC, 0x3FCE, 0x3FD1, - 0x3FD3, 0x3FDD, 0x3FDF, 0x3FE0, 0x3FE2, 0x3FE4, - 0x3FEC, 0x3FEE, 0x3FF1, 0x3FF3, 0x3FFD, 0x3FFF, - 0x4000, 0x4002, 0x4004, 0x400C, 0x400E, 0x4011, - 0x4013, 0x401D, 0x401F, 0x4020, 0x4022, 0x4024, - 0x402C, 0x402E, 0x4031, 0x4033, 0x403D, 0x403F, - 0x4040, 0x4042, 0x4044, 0x404C, 0x404E, 0x40C0, - 0x40C2, 0x40C4, 0x40CC, 0x40CE, 0x40D1, 0x40D3, - 0x40DD, 0x40DF, 0x40E0, 0x40E2, 0x40E4, 0x40EC, - 0x40EE, 0x40F1, 0x40F3, 0x40FD, 0x40FF, 0x4101, - 0x4103, 0x410D, 0x410F, 0x4110, 0x4112, 0x4114, - 0x411C, 0x411E, 0x4121, 0x4123, 0x412D, 0x412F, - 0x4130, 0x4132, 0x4134, 0x413C, 0x413E, 0x4141, - 0x4143, 0x414D, 0x414F, 0x41C1, 0x41C3, 0x41CD, - 0x41CF, 0x41D0, 0x41D2, 0x41D4, 0x41DC, 0x41DE, - 0x41E1, 0x41E3, 0x41ED, 0x41EF, 0x41F0, 0x41F2, - 0x41F4, 0x41FC, 0x41FE, 0x4200, 0x4202, 0x4204, - 0x420C, 0x420E, 0x4211, 0x4213, 0x421D, 0x421F, - 0x4220, 0x4222, 0x4224, 0x422C, 0x422E, 0x4231, - 0x4233, 0x423D, 0x423F, 0x4240, 0x4242, 0x4244, - 0x424C, 0x424E, 0x42C0, 0x42C2, 0x42C4, 0x42CC, - 0x42CE, 0x42D1, 0x42D3, 0x42DD, 0x42DF, 0x42E0, - 0x42E2, 0x42E4, 0x42EC, 0x42EE, 0x42F1, 0x42F3, - 0x42FD, 0x42FF, 0x4301, 0x4303, 0x430D, 0x430F, - 0x4310, 0x4312, 0x4314, 0x431C, 0x431E, 0x4321, - 0x4323, 0x432D, 0x432F, 0x4330, 0x4332, 0x4334, - 0x433C, 0x433E, 0x4341, 0x4343, 0x434D, 0x434F, - 0x43C1, 0x43C3, 0x43CD, 0x43CF, 0x43D0, 0x43D2, - 0x43D4, 0x43DC, 0x43DE, 0x43E1, 0x43E3, 0x43ED, - 0x43EF, 0x43F0, 0x43F2, 0x43F4, 0x43FC, 0x43FE, - 0x4400, 0x4402, 0x4404, 0x440C, 0x440E, 0x4411, - 0x4413, 0x441D, 0x441F, 0x4420, 0x4422, 0x4424, - 0x442C, 0x442E, 0x4431, 0x4433, 0x443D, 0x443F, - 0x4440, 0x4442, 0x4444, 0x444C, 0x444E, 0x44C0, - 0x44C2, 0x44C4, 0x44CC, 0x44CE, 0x44D1, 0x44D3, - 0x44DD, 0x44DF, 0x44E0, 0x44E2, 0x44E4, 0x44EC, - 0x44EE, 0x44F1, 0x44F3, 0x44FD, 0x44FF, 0x4C00, - 0x4C02, 0x4C04, 0x4C0C, 0x4C0E, 0x4C11, 0x4C13, - 0x4C1D, 0x4C1F, 0x4C20, 0x4C22, 0x4C24, 0x4C2C, - 0x4C2E, 0x4C31, 0x4C33, 0x4C3D, 0x4C3F, 0x4C40, - 0x4C42, 0x4C44, 0x4C4C, 0x4C4E, 0x4CC0, 0x4CC2, - 0x4CC4, 0x4CCC, 0x4CCE, 0x4CD1, 0x4CD3, 0x4CDD, - 0x4CDF, 0x4CE0, 0x4CE2, 0x4CE4, 0x4CEC, 0x4CEE, - 0x4CF1, 0x4CF3, 0x4CFD, 0x4CFF, 0x4D01, 0x4D03, - 0x4D0D, 0x4D0F, 0x4D10, 0x4D12, 0x4D14, 0x4D1C, - 0x4D1E, 0x4D21, 0x4D23, 0x4D2D, 0x4D2F, 0x4D30, - 0x4D32, 0x4D34, 0x4D3C, 0x4D3E, 0x4D41, 0x4D43, - 0x4D4D, 0x4D4F, 0x4DC1, 0x4DC3, 0x4DCD, 0x4DCF, - 0x4DD0, 0x4DD2, 0x4DD4, 0x4DDC, 0x4DDE, 0x4DE1, - 0x4DE3, 0x4DED, 0x4DEF, 0x4DF0, 0x4DF2, 0x4DF4, - 0x4DFC, 0x4DFE, 0x4E00, 0x4E02, 0x4E04, 0x4E0C, - 0x4E0E, 0x4E11, 0x4E13, 0x4E1D, 0x4E1F, 0x4E20, - 0x4E22, 0x4E24, 0x4E2C, 0x4E2E, 0x4E31, 0x4E33, - 0x4E3D, 0x4E3F, 0x4E40, 0x4E42, 0x4E44, 0x4E4C, - 0x4E4E, 0x4EC0, 0x4EC2, 0x4EC4, 0x4ECC, 0x4ECE, - 0x4ED1, 0x4ED3, 0x4EDD, 0x4EDF, 0x4EE0, 0x4EE2, - 0x4EE4, 0x4EEC, 0x4EEE, 0x4EF1, 0x4EF3, 0x4EFD, - 0x4EFF, 0x4F01, 0x4F03, 0x4F0D, 0x4F0F, 0x4F10, - 0x4F12, 0x4F14, 0x4F1C, 0x4F1E, 0x4F21, 0x4F23, - 0x4F2D, 0x4F2F, 0x4F30, 0x4F32, 0x4F34, 0x4F3C, - 0x4F3E, 0x4F41, 0x4F43, 0x4F4D, 0x4F4F, 0x4FC1, - 0x4FC3, 0x4FCD, 0x4FCF, 0x4FD0, 0x4FD2, 0x4FD4, - 0x4FDC, 0x4FDE, 0x4FE1, 0x4FE3, 0x4FED, 0x4FEF, - 0x4FF0, 0x4FF2, 0x4FF4, 0x4FFC, 0x4FFE, 0xC000, - 0xC002, 0xC004, 0xC00C, 0xC00E, 0xC011, 0xC013, - 0xC01D, 0xC01F, 0xC020, 0xC022, 0xC024, 0xC02C, - 0xC02E, 0xC031, 0xC033, 0xC03D, 0xC03F, 0xC040, - 0xC042, 0xC044, 0xC04C, 0xC04E, 0xC0C0, 0xC0C2, - 0xC0C4, 0xC0CC, 0xC0CE, 0xC0D1, 0xC0D3, 0xC0DD, - 0xC0DF, 0xC0E0, 0xC0E2, 0xC0E4, 0xC0EC, 0xC0EE, - 0xC0F1, 0xC0F3, 0xC0FD, 0xC0FF, 0xC101, 0xC103, - 0xC10D, 0xC10F, 0xC110, 0xC112, 0xC114, 0xC11C, - 0xC11E, 0xC121, 0xC123, 0xC12D, 0xC12F, 0xC130, - 0xC132, 0xC134, 0xC13C, 0xC13E, 0xC141, 0xC143, - 0xC14D, 0xC14F, 0xC1C1, 0xC1C3, 0xC1CD, 0xC1CF, - 0xC1D0, 0xC1D2, 0xC1D4, 0xC1DC, 0xC1DE, 0xC1E1, - 0xC1E3, 0xC1ED, 0xC1EF, 0xC1F0, 0xC1F2, 0xC1F4, - 0xC1FC, 0xC1FE, 0xC200, 0xC202, 0xC204, 0xC20C, - 0xC20E, 0xC211, 0xC213, 0xC21D, 0xC21F, 0xC220, - 0xC222, 0xC224, 0xC22C, 0xC22E, 0xC231, 0xC233, - 0xC23D, 0xC23F, 0xC240, 0xC242, 0xC244, 0xC24C, - 0xC24E, 0xC2C0, 0xC2C2, 0xC2C4, 0xC2CC, 0xC2CE, - 0xC2D1, 0xC2D3, 0xC2DD, 0xC2DF, 0xC2E0, 0xC2E2, - 0xC2E4, 0xC2EC, 0xC2EE, 0xC2F1, 0xC2F3, 0xC2FD, - 0xC2FF, 0xC301, 0xC303, 0xC30D, 0xC30F, 0xC310, - 0xC312, 0xC314, 0xC31C, 0xC31E, 0xC321, 0xC323, - 0xC32D, 0xC32F, 0xC330, 0xC332, 0xC334, 0xC33C, - 0xC33E, 0xC341, 0xC343, 0xC34D, 0xC34F, 0xC3C1, - 0xC3C3, 0xC3CD, 0xC3CF, 0xC3D0, 0xC3D2, 0xC3D4, - 0xC3DC, 0xC3DE, 0xC3E1, 0xC3E3, 0xC3ED, 0xC3EF, - 0xC3F0, 0xC3F2, 0xC3F4, 0xC3FC, 0xC3FE, 0xC400, - 0xC402, 0xC404, 0xC40C, 0xC40E, 0xC411, 0xC413, - 0xC41D, 0xC41F, 0xC420, 0xC422, 0xC424, 0xC42C, - 0xC42E, 0xC431, 0xC433, 0xC43D, 0xC43F, 0xC440, - 0xC442, 0xC444, 0xC44C, 0xC44E, 0xC4C0, 0xC4C2, - 0xC4C4, 0xC4CC, 0xC4CE, 0xC4D1, 0xC4D3, 0xC4DD, - 0xC4DF, 0xC4E0, 0xC4E2, 0xC4E4, 0xC4EC, 0xC4EE, - 0xC4F1, 0xC4F3, 0xC4FD, 0xC4FF, 0xCC00, 0xCC02, - 0xCC04, 0xCC0C, 0xCC0E, 0xCC11, 0xCC13, 0xCC1D, - 0xCC1F, 0xCC20, 0xCC22, 0xCC24, 0xCC2C, 0xCC2E, - 0xCC31, 0xCC33, 0xCC3D, 0xCC3F, 0xCC40, 0xCC42, - 0xCC44, 0xCC4C, 0xCC4E, 0xCCC0, 0xCCC2, 0xCCC4, - 0xCCCC, 0xCCCE, 0xCCD1, 0xCCD3, 0xCCDD, 0xCCDF, - 0xCCE0, 0xCCE2, 0xCCE4, 0xCCEC, 0xCCEE, 0xCCF1, - 0xCCF3, 0xCCFD, 0xCCFF, 0xCD01, 0xCD03, 0xCD0D, - 0xCD0F, 0xCD10, 0xCD12, 0xCD14, 0xCD1C, 0xCD1E, - 0xCD21, 0xCD23, 0xCD2D, 0xCD2F, 0xCD30, 0xCD32, - 0xCD34, 0xCD3C, 0xCD3E, 0xCD41, 0xCD43, 0xCD4D, - 0xCD4F, 0xCDC1, 0xCDC3, 0xCDCD, 0xCDCF, 0xCDD0, - 0xCDD2, 0xCDD4, 0xCDDC, 0xCDDE, 0xCDE1, 0xCDE3, - 0xCDED, 0xCDEF, 0xCDF0, 0xCDF2, 0xCDF4, 0xCDFC, - 0xCDFE, 0xCE00, 0xCE02, 0xCE04, 0xCE0C, 0xCE0E, - 0xCE11, 0xCE13, 0xCE1D, 0xCE1F, 0xCE20, 0xCE22, - 0xCE24, 0xCE2C, 0xCE2E, 0xCE31, 0xCE33, 0xCE3D, - 0xCE3F, 0xCE40, 0xCE42, 0xCE44, 0xCE4C, 0xCE4E, - 0xCEC0, 0xCEC2, 0xCEC4, 0xCECC, 0xCECE, 0xCED1, - 0xCED3, 0xCEDD, 0xCEDF, 0xCEE0, 0xCEE2, 0xCEE4, - 0xCEEC, 0xCEEE, 0xCEF1, 0xCEF3, 0xCEFD, 0xCEFF, - 0xCF01, 0xCF03, 0xCF0D, 0xCF0F, 0xCF10, 0xCF12, - 0xCF14, 0xCF1C, 0xCF1E, 0xCF21, 0xCF23, 0xCF2D, - 0xCF2F, 0xCF30, 0xCF32, 0xCF34, 0xCF3C, 0xCF3E, - 0xCF41, 0xCF43, 0xCF4D, 0xCF4F, 0xCFC1, 0xCFC3, - 0xCFCD, 0xCFCF, 0xCFD0, 0xCFD2, 0xCFD4, 0xCFDC, - 0xCFDE, 0xCFE1, 0xCFE3, 0xCFED, 0xCFEF, 0xCFF0, - 0xCFF2, 0xCFF4, 0xCFFC, 0xCFFE, 0xD001, 0xD003, - 0xD00D, 0xD00F, 0xD010, 0xD012, 0xD014, 0xD01C, - 0xD01E, 0xD021, 0xD023, 0xD02D, 0xD02F, 0xD030, - 0xD032, 0xD034, 0xD03C, 0xD03E, 0xD041, 0xD043, - 0xD04D, 0xD04F, 0xD0C1, 0xD0C3, 0xD0CD, 0xD0CF, - 0xD0D0, 0xD0D2, 0xD0D4, 0xD0DC, 0xD0DE, 0xD0E1, - 0xD0E3, 0xD0ED, 0xD0EF, 0xD0F0, 0xD0F2, 0xD0F4, - 0xD0FC, 0xD0FE, 0xD100, 0xD102, 0xD104, 0xD10C, - 0xD10E, 0xD111, 0xD113, 0xD11D, 0xD11F, 0xD120, - 0xD122, 0xD124, 0xD12C, 0xD12E, 0xD131, 0xD133, - 0xD13D, 0xD13F, 0xD140, 0xD142, 0xD144, 0xD14C, - 0xD14E, 0xD1C0, 0xD1C2, 0xD1C4, 0xD1CC, 0xD1CE, - 0xD1D1, 0xD1D3, 0xD1DD, 0xD1DF, 0xD1E0, 0xD1E2, - 0xD1E4, 0xD1EC, 0xD1EE, 0xD1F1, 0xD1F3, 0xD1FD, - 0xD1FF, 0xD201, 0xD203, 0xD20D, 0xD20F, 0xD210, - 0xD212, 0xD214, 0xD21C, 0xD21E, 0xD221, 0xD223, - 0xD22D, 0xD22F, 0xD230, 0xD232, 0xD234, 0xD23C, - 0xD23E, 0xD241, 0xD243, 0xD24D, 0xD24F, 0xD2C1, - 0xD2C3, 0xD2CD, 0xD2CF, 0xD2D0, 0xD2D2, 0xD2D4, - 0xD2DC, 0xD2DE, 0xD2E1, 0xD2E3, 0xD2ED, 0xD2EF, - 0xD2F0, 0xD2F2, 0xD2F4, 0xD2FC, 0xD2FE, 0xD300, - 0xD302, 0xD304, 0xD30C, 0xD30E, 0xD311, 0xD313, - 0xD31D, 0xD31F, 0xD320, 0xD322, 0xD324, 0xD32C, - 0xD32E, 0xD331, 0xD333, 0xD33D, 0xD33F, 0xD340, - 0xD342, 0xD344, 0xD34C, 0xD34E, 0xD3C0, 0xD3C2, - 0xD3C4, 0xD3CC, 0xD3CE, 0xD3D1, 0xD3D3, 0xD3DD, - 0xD3DF, 0xD3E0, 0xD3E2, 0xD3E4, 0xD3EC, 0xD3EE, - 0xD3F1, 0xD3F3, 0xD3FD, 0xD3FF, 0xD401, 0xD403, - 0xD40D, 0xD40F, 0xD410, 0xD412, 0xD414, 0xD41C, - 0xD41E, 0xD421, 0xD423, 0xD42D, 0xD42F, 0xD430, - 0xD432, 0xD434, 0xD43C, 0xD43E, 0xD441, 0xD443, - 0xD44D, 0xD44F, 0xD4C1, 0xD4C3, 0xD4CD, 0xD4CF, - 0xD4D0, 0xD4D2, 0xD4D4, 0xD4DC, 0xD4DE, 0xD4E1, - 0xD4E3, 0xD4ED, 0xD4EF, 0xD4F0, 0xD4F2, 0xD4F4, - 0xD4FC, 0xD4FE, 0xDC01, 0xDC03, 0xDC0D, 0xDC0F, - 0xDC10, 0xDC12, 0xDC14, 0xDC1C, 0xDC1E, 0xDC21, - 0xDC23, 0xDC2D, 0xDC2F, 0xDC30, 0xDC32, 0xDC34, - 0xDC3C, 0xDC3E, 0xDC41, 0xDC43, 0xDC4D, 0xDC4F, - 0xDCC1, 0xDCC3, 0xDCCD, 0xDCCF, 0xDCD0, 0xDCD2, - 0xDCD4, 0xDCDC, 0xDCDE, 0xDCE1, 0xDCE3, 0xDCED, - 0xDCEF, 0xDCF0, 0xDCF2, 0xDCF4, 0xDCFC, 0xDCFE, - 0xDD00, 0xDD02, 0xDD04, 0xDD0C, 0xDD0E, 0xDD11, - 0xDD13, 0xDD1D, 0xDD1F, 0xDD20, 0xDD22, 0xDD24, - 0xDD2C, 0xDD2E, 0xDD31, 0xDD33, 0xDD3D, 0xDD3F, - 0xDD40, 0xDD42, 0xDD44, 0xDD4C, 0xDD4E, 0xDDC0, - 0xDDC2, 0xDDC4, 0xDDCC, 0xDDCE, 0xDDD1, 0xDDD3, - 0xDDDD, 0xDDDF, 0xDDE0, 0xDDE2, 0xDDE4, 0xDDEC, - 0xDDEE, 0xDDF1, 0xDDF3, 0xDDFD, 0xDDFF, 0xDE01, - 0xDE03, 0xDE0D, 0xDE0F, 0xDE10, 0xDE12, 0xDE14, - 0xDE1C, 0xDE1E, 0xDE21, 0xDE23, 0xDE2D, 0xDE2F, - 0xDE30, 0xDE32, 0xDE34, 0xDE3C, 0xDE3E, 0xDE41, - 0xDE43, 0xDE4D, 0xDE4F, 0xDEC1, 0xDEC3, 0xDECD, - 0xDECF, 0xDED0, 0xDED2, 0xDED4, 0xDEDC, 0xDEDE, - 0xDEE1, 0xDEE3, 0xDEED, 0xDEEF, 0xDEF0, 0xDEF2, - 0xDEF4, 0xDEFC, 0xDEFE, 0xDF00, 0xDF02, 0xDF04, - 0xDF0C, 0xDF0E, 0xDF11, 0xDF13, 0xDF1D, 0xDF1F, - 0xDF20, 0xDF22, 0xDF24, 0xDF2C, 0xDF2E, 0xDF31, - 0xDF33, 0xDF3D, 0xDF3F, 0xDF40, 0xDF42, 0xDF44, - 0xDF4C, 0xDF4E, 0xDFC0, 0xDFC2, 0xDFC4, 0xDFCC, - 0xDFCE, 0xDFD1, 0xDFD3, 0xDFDD, 0xDFDF, 0xDFE0, - 0xDFE2, 0xDFE4, 0xDFEC, 0xDFEE, 0xDFF1, 0xDFF3, - 0xDFFD, 0xDFFF, 0xE000, 0xE002, 0xE004, 0xE00C, - 0xE00E, 0xE011, 0xE013, 0xE01D, 0xE01F, 0xE020, - 0xE022, 0xE024, 0xE02C, 0xE02E, 0xE031, 0xE033, - 0xE03D, 0xE03F, 0xE040, 0xE042, 0xE044, 0xE04C, - 0xE04E, 0xE0C0, 0xE0C2, 0xE0C4, 0xE0CC, 0xE0CE, - 0xE0D1, 0xE0D3, 0xE0DD, 0xE0DF, 0xE0E0, 0xE0E2, - 0xE0E4, 0xE0EC, 0xE0EE, 0xE0F1, 0xE0F3, 0xE0FD, - 0xE0FF, 0xE101, 0xE103, 0xE10D, 0xE10F, 0xE110, - 0xE112, 0xE114, 0xE11C, 0xE11E, 0xE121, 0xE123, - 0xE12D, 0xE12F, 0xE130, 0xE132, 0xE134, 0xE13C, - 0xE13E, 0xE141, 0xE143, 0xE14D, 0xE14F, 0xE1C1, - 0xE1C3, 0xE1CD, 0xE1CF, 0xE1D0, 0xE1D2, 0xE1D4, - 0xE1DC, 0xE1DE, 0xE1E1, 0xE1E3, 0xE1ED, 0xE1EF, - 0xE1F0, 0xE1F2, 0xE1F4, 0xE1FC, 0xE1FE, 0xE200, - 0xE202, 0xE204, 0xE20C, 0xE20E, 0xE211, 0xE213, - 0xE21D, 0xE21F, 0xE220, 0xE222, 0xE224, 0xE22C, - 0xE22E, 0xE231, 0xE233, 0xE23D, 0xE23F, 0xE240, - 0xE242, 0xE244, 0xE24C, 0xE24E, 0xE2C0, 0xE2C2, - 0xE2C4, 0xE2CC, 0xE2CE, 0xE2D1, 0xE2D3, 0xE2DD, - 0xE2DF, 0xE2E0, 0xE2E2, 0xE2E4, 0xE2EC, 0xE2EE, - 0xE2F1, 0xE2F3, 0xE2FD, 0xE2FF, 0xE301, 0xE303, - 0xE30D, 0xE30F, 0xE310, 0xE312, 0xE314, 0xE31C, - 0xE31E, 0xE321, 0xE323, 0xE32D, 0xE32F, 0xE330, - 0xE332, 0xE334, 0xE33C, 0xE33E, 0xE341, 0xE343, - 0xE34D, 0xE34F, 0xE3C1, 0xE3C3, 0xE3CD, 0xE3CF, - 0xE3D0, 0xE3D2, 0xE3D4, 0xE3DC, 0xE3DE, 0xE3E1, - 0xE3E3, 0xE3ED, 0xE3EF, 0xE3F0, 0xE3F2, 0xE3F4, - 0xE3FC, 0xE3FE, 0xE400, 0xE402, 0xE404, 0xE40C, - 0xE40E, 0xE411, 0xE413, 0xE41D, 0xE41F, 0xE420, - 0xE422, 0xE424, 0xE42C, 0xE42E, 0xE431, 0xE433, - 0xE43D, 0xE43F, 0xE440, 0xE442, 0xE444, 0xE44C, - 0xE44E, 0xE4C0, 0xE4C2, 0xE4C4, 0xE4CC, 0xE4CE, - 0xE4D1, 0xE4D3, 0xE4DD, 0xE4DF, 0xE4E0, 0xE4E2, - 0xE4E4, 0xE4EC, 0xE4EE, 0xE4F1, 0xE4F3, 0xE4FD, - 0xE4FF, 0xEC00, 0xEC02, 0xEC04, 0xEC0C, 0xEC0E, - 0xEC11, 0xEC13, 0xEC1D, 0xEC1F, 0xEC20, 0xEC22, - 0xEC24, 0xEC2C, 0xEC2E, 0xEC31, 0xEC33, 0xEC3D, - 0xEC3F, 0xEC40, 0xEC42, 0xEC44, 0xEC4C, 0xEC4E, - 0xECC0, 0xECC2, 0xECC4, 0xECCC, 0xECCE, 0xECD1, - 0xECD3, 0xECDD, 0xECDF, 0xECE0, 0xECE2, 0xECE4, - 0xECEC, 0xECEE, 0xECF1, 0xECF3, 0xECFD, 0xECFF, - 0xED01, 0xED03, 0xED0D, 0xED0F, 0xED10, 0xED12, - 0xED14, 0xED1C, 0xED1E, 0xED21, 0xED23, 0xED2D, - 0xED2F, 0xED30, 0xED32, 0xED34, 0xED3C, 0xED3E, - 0xED41, 0xED43, 0xED4D, 0xED4F, 0xEDC1, 0xEDC3, - 0xEDCD, 0xEDCF, 0xEDD0, 0xEDD2, 0xEDD4, 0xEDDC, - 0xEDDE, 0xEDE1, 0xEDE3, 0xEDED, 0xEDEF, 0xEDF0, - 0xEDF2, 0xEDF4, 0xEDFC, 0xEDFE, 0xEE00, 0xEE02, - 0xEE04, 0xEE0C, 0xEE0E, 0xEE11, 0xEE13, 0xEE1D, - 0xEE1F, 0xEE20, 0xEE22, 0xEE24, 0xEE2C, 0xEE2E, - 0xEE31, 0xEE33, 0xEE3D, 0xEE3F, 0xEE40, 0xEE42, - 0xEE44, 0xEE4C, 0xEE4E, 0xEEC0, 0xEEC2, 0xEEC4, - 0xEECC, 0xEECE, 0xEED1, 0xEED3, 0xEEDD, 0xEEDF, - 0xEEE0, 0xEEE2, 0xEEE4, 0xEEEC, 0xEEEE, 0xEEF1, - 0xEEF3, 0xEEFD, 0xEEFF, 0xEF01, 0xEF03, 0xEF0D, - 0xEF0F, 0xEF10, 0xEF12, 0xEF14, 0xEF1C, 0xEF1E, - 0xEF21, 0xEF23, 0xEF2D, 0xEF2F, 0xEF30, 0xEF32, - 0xEF34, 0xEF3C, 0xEF3E, 0xEF41, 0xEF43, 0xEF4D, - 0xEF4F, 0xEFC1, 0xEFC3, 0xEFCD, 0xEFCF, 0xEFD0, - 0xEFD2, 0xEFD4, 0xEFDC, 0xEFDE, 0xEFE1, 0xEFE3, - 0xEFED, 0xEFEF, 0xEFF0, 0xEFF2, 0xEFF4, 0xEFFC, - 0xEFFE, 0xF001, 0xF003, 0xF00D, 0xF00F, 0xF010, - 0xF012, 0xF014, 0xF01C, 0xF01E, 0xF021, 0xF023, - 0xF02D, 0xF02F, 0xF030, 0xF032, 0xF034, 0xF03C, - 0xF03E, 0xF041, 0xF043, 0xF04D, 0xF04F, 0xF0C1, - 0xF0C3, 0xF0CD, 0xF0CF, 0xF0D0, 0xF0D2, 0xF0D4, - 0xF0DC, 0xF0DE, 0xF0E1, 0xF0E3, 0xF0ED, 0xF0EF, - 0xF0F0, 0xF0F2, 0xF0F4, 0xF0FC, 0xF0FE, 0xF100, - 0xF102, 0xF104, 0xF10C, 0xF10E, 0xF111, 0xF113, - 0xF11D, 0xF11F, 0xF120, 0xF122, 0xF124, 0xF12C, - 0xF12E, 0xF131, 0xF133, 0xF13D, 0xF13F, 0xF140, - 0xF142, 0xF144, 0xF14C, 0xF14E, 0xF1C0, 0xF1C2, - 0xF1C4, 0xF1CC, 0xF1CE, 0xF1D1, 0xF1D3, 0xF1DD, - 0xF1DF, 0xF1E0, 0xF1E2, 0xF1E4, 0xF1EC, 0xF1EE, - 0xF1F1, 0xF1F3, 0xF1FD, 0xF1FF, 0xF201, 0xF203, - 0xF20D, 0xF20F, 0xF210, 0xF212, 0xF214, 0xF21C, - 0xF21E, 0xF221, 0xF223, 0xF22D, 0xF22F, 0xF230, - 0xF232, 0xF234, 0xF23C, 0xF23E, 0xF241, 0xF243, - 0xF24D, 0xF24F, 0xF2C1, 0xF2C3, 0xF2CD, 0xF2CF, - 0xF2D0, 0xF2D2, 0xF2D4, 0xF2DC, 0xF2DE, 0xF2E1, - 0xF2E3, 0xF2ED, 0xF2EF, 0xF2F0, 0xF2F2, 0xF2F4, - 0xF2FC, 0xF2FE, 0xF300, 0xF302, 0xF304, 0xF30C, - 0xF30E, 0xF311, 0xF313, 0xF31D, 0xF31F, 0xF320, - 0xF322, 0xF324, 0xF32C, 0xF32E, 0xF331, 0xF333, - 0xF33D, 0xF33F, 0xF340, 0xF342, 0xF344, 0xF34C, - 0xF34E, 0xF3C0, 0xF3C2, 0xF3C4, 0xF3CC, 0xF3CE, - 0xF3D1, 0xF3D3, 0xF3DD, 0xF3DF, 0xF3E0, 0xF3E2, - 0xF3E4, 0xF3EC, 0xF3EE, 0xF3F1, 0xF3F3, 0xF3FD, - 0xF3FF, 0xF401, 0xF403, 0xF40D, 0xF40F, 0xF410, - 0xF412, 0xF414, 0xF41C, 0xF41E, 0xF421, 0xF423, - 0xF42D, 0xF42F, 0xF430, 0xF432, 0xF434, 0xF43C, - 0xF43E, 0xF441, 0xF443, 0xF44D, 0xF44F, 0xF4C1, - 0xF4C3, 0xF4CD, 0xF4CF, 0xF4D0, 0xF4D2, 0xF4D4, - 0xF4DC, 0xF4DE, 0xF4E1, 0xF4E3, 0xF4ED, 0xF4EF, - 0xF4F0, 0xF4F2, 0xF4F4, 0xF4FC, 0xF4FE, 0xFC01, - 0xFC03, 0xFC0D, 0xFC0F, 0xFC10, 0xFC12, 0xFC14, - 0xFC1C, 0xFC1E, 0xFC21, 0xFC23, 0xFC2D, 0xFC2F, - 0xFC30, 0xFC32, 0xFC34, 0xFC3C, 0xFC3E, 0xFC41, - 0xFC43, 0xFC4D, 0xFC4F, 0xFCC1, 0xFCC3, 0xFCCD, - 0xFCCF, 0xFCD0, 0xFCD2, 0xFCD4, 0xFCDC, 0xFCDE, - 0xFCE1, 0xFCE3, 0xFCED, 0xFCEF, 0xFCF0, 0xFCF2, - 0xFCF4, 0xFCFC, 0xFCFE, 0xFD00, 0xFD02, 0xFD04, - 0xFD0C, 0xFD0E, 0xFD11, 0xFD13, 0xFD1D, 0xFD1F, - 0xFD20, 0xFD22, 0xFD24, 0xFD2C, 0xFD2E, 0xFD31, - 0xFD33, 0xFD3D, 0xFD3F, 0xFD40, 0xFD42, 0xFD44, - 0xFD4C, 0xFD4E, 0xFDC0, 0xFDC2, 0xFDC4, 0xFDCC, - 0xFDCE, 0xFDD1, 0xFDD3, 0xFDDD, 0xFDDF, 0xFDE0, - 0xFDE2, 0xFDE4, 0xFDEC, 0xFDEE, 0xFDF1, 0xFDF3, - 0xFDFD, 0xFDFF, 0xFE01, 0xFE03, 0xFE0D, 0xFE0F, - 0xFE10, 0xFE12, 0xFE14, 0xFE1C, 0xFE1E, 0xFE21, - 0xFE23, 0xFE2D, 0xFE2F, 0xFE30, 0xFE32, 0xFE34, - 0xFE3C, 0xFE3E, 0xFE41, 0xFE43, 0xFE4D, 0xFE4F, - 0xFEC1, 0xFEC3, 0xFECD, 0xFECF, 0xFED0, 0xFED2, - 0xFED4, 0xFEDC, 0xFEDE, 0xFEE1, 0xFEE3, 0xFEED, - 0xFEEF, 0xFEF0, 0xFEF2, 0xFEF4, 0xFEFC, 0xFEFE, - 0xFF00, 0xFF02, 0xFF04, 0xFF0C, 0xFF0E, 0xFF11, - 0xFF13, 0xFF1D, 0xFF1F, 0xFF20, 0xFF22, 0xFF24, - 0xFF2C, 0xFF2E, 0xFF31, 0xFF33, 0xFF3D, 0xFF3F, - 0xFF40, 0xFF42, 0xFF44, 0xFF4C, 0xFF4E, 0xFFC0, - 0xFFC2, 0xFFC4, 0xFFCC, 0xFFCE, 0xFFD1, 0xFFD3, - 0xFFDD, 0xFFDF, 0xFFE0, 0xFFE2, 0xFFE4, 0xFFEC, - 0xFFEE, 0xFFF1, 0xFFF3, 0xFFFD, 0xFFFF, -}; - -#define ON2AVC_CB8_CODES 3281 -static const uint32_t on2avc_cb8_codes[ON2AVC_CB8_CODES] = { - 0x028C, 0x05E6, 0xFAD9, 0x7DEF, 0x06CE, 0x004C, - 0x0178, 0x0A1D, 0x00AE, 0x046E, 0x03D5, 0x3F58, - 0x0EAA, 0x0233, 0x1A6A, 0x271F, 0x05CE, 0x0179, - 0x02FB, 0x0029, 0x237D, 0x7DF0, 0x03BA, 0xFAD6, - 0xFAD7, 0x7DEE, 0xFAD5, 0x0081, 0x033C, 0x1A69, - 0xFAD8, 0x05A1, 0x01F1, 0x063D, 0x237C, 0x003E, - 0x0323, 0x010C, 0x05A3, 0x05A2, 0x0051, 0x019D, - 0xFADB, 0x0EAB, 0x00AA, 0x003E, 0x01A6, 0x7DF2, - 0x0058, 0x01F1, 0x029B, 0x03C0, 0x122D, 0x0075, - 0x3F5A, 0x0B98, 0x0005, 0x058B, 0x0D68, 0x013F, - 0x00D0, 0x05CF, 0x01C0, 0x03BB, 0x046F, 0xFADA, - 0x01A0, 0x0972, 0x122C, 0x3F59, 0x0766, 0x05A4, - 0x00ED, 0x05A5, 0x0D67, 0x03D0, 0x0046, 0x01FF, - 0x7DF1, 0x00D6, 0x017C, 0x0034, 0x08B5, 0x0234, - 0x237E, 0x0033, 0x0083, 0x0B99, 0x0EAC, 0x0202, - 0x0714, 0x0715, 0x01C3, 0x05A6, 0x0324, 0x13EC, - 0x02F8, 0x7DF3, 0x13EB, 0x0140, 0x0470, 0x04F8, - 0x0007, 0x0377, 0x0208, 0x04A3, 0x13EA, 0x0006, - 0x0188, 0x033D, 0x122E, 0x1A6B, 0x0A1E, 0x0126, - 0x03C1, 0x05E7, 0x05D0, 0x04F7, 0x03DB, 0x033E, - 0x122F, 0x0082, 0x1A6F, 0x2380, 0x05D2, 0x0009, - 0x05A9, 0x1A70, 0x1233, 0x05A7, 0x05A8, 0x0975, - 0x2381, 0x1234, 0x0788, 0x2720, 0x1235, 0x05D3, - 0xFADD, 0x3F5B, 0x0789, 0x0D69, 0xFADE, 0xFADF, - 0x01C4, 0x0EAD, 0x0EA1, 0x1230, 0x0008, 0x13ED, - 0x1A6C, 0xFADC, 0x1231, 0x0973, 0x1232, 0x1A6D, - 0x13EE, 0x1A6E, 0x0974, 0x237F, 0x05D1, 0x033F, - 0x0267, 0x078A, 0xFAE3, 0xFAE2, 0x0B9A, 0x00FC, - 0x0EAE, 0x05D6, 0x0325, 0x0326, 0x0B9B, 0x3F5F, - 0x3F5E, 0x0471, 0x02F9, 0xFAE4, 0x1A72, 0x03C2, - 0x05D7, 0x2721, 0x3F60, 0xFAE5, 0x2382, 0xFAE0, - 0x7DF5, 0xFAE1, 0x7DF4, 0x000A, 0x0235, 0x3F5C, - 0x1A71, 0x0716, 0x036C, 0x0767, 0x05D4, 0x3F5D, - 0x0717, 0x01BF, 0x000B, 0x05D5, 0x0243, 0xFAD0, - 0x04F6, 0x7DE5, 0xFACF, 0x0E9E, 0x0074, 0x271A, - 0x1A61, 0x015B, 0x0046, 0x06CA, 0x237A, 0x7DE6, - 0x0070, 0x1A62, 0x1227, 0x7DE7, 0x0032, 0xFAD1, - 0x05CA, 0x7DE8, 0x237B, 0x13E6, 0x05C8, 0x1226, - 0x2377, 0x2719, 0x3F54, 0x3F55, 0x13E5, 0x2378, - 0x03BF, 0x05C9, 0x01C0, 0x7DE4, 0x7DE3, 0x0A19, - 0x0045, 0x1A60, 0x2379, 0x021B, 0x271C, 0x13E7, - 0x271B, 0x1A67, 0x059D, 0x0EA6, 0x0EA7, 0x0174, - 0x0EA5, 0x0A1A, 0x1FFD, 0x033A, 0x0E9F, 0x3F57, - 0x122B, 0xFAD2, 0x0D64, 0x05CC, 0x06CB, 0x1FFE, - 0x059E, 0x02F7, 0x1228, 0x7DE9, 0x059B, 0x096C, - 0x1A63, 0x1A64, 0x1A65, 0x1229, 0x0EA3, 0x059C, - 0x096D, 0x05CB, 0x003C, 0x1A66, 0x0D63, 0x3F56, - 0x122A, 0x0EA4, 0x0712, 0x0232, 0x13E8, 0x061E, - 0x08B4, 0x016E, 0x0176, 0x033B, 0x0028, 0x05E5, - 0x061F, 0x0000, 0x0376, 0x0071, 0x096F, 0x7DEB, - 0x0001, 0x05CD, 0xFAD3, 0x0186, 0x0EA9, 0x13E9, - 0x06CD, 0x7DEA, 0x0340, 0x271D, 0x0175, 0x01C1, - 0x0D65, 0x1FFF, 0x0B97, 0x0EA8, 0x06CC, 0x0375, - 0x05E4, 0x08B3, 0x05E3, 0x0341, 0x0EA0, 0x096E, - 0x03CF, 0x0056, 0x0970, 0x1A68, 0x029A, 0x010A, - 0x00A8, 0x01CA, 0x7DED, 0x00A5, 0x001E, 0x05A0, - 0x0D66, 0x0047, 0x0971, 0x0A1C, 0x02CE, 0xFAD4, - 0x0004, 0x010F, 0x271E, 0x0415, 0x0212, 0x019F, - 0x7DEC, 0x01C2, 0x0187, 0x059F, 0x0A1B, 0x0527, - 0x0002, 0x003D, 0x0041, 0x0177, 0x0713, 0x010E, - 0x0102, 0x02CF, 0x00CA, 0x0003, 0x01BF, 0x0120, - 0x05DE, 0x0043, 0x01D0, 0x018C, 0x00AB, 0x029F, - 0x03DF, 0x03C5, 0x0247, 0x08BB, 0x0013, 0x03D2, - 0x0015, 0x0EB0, 0x02FA, 0x05E8, 0x0014, 0x0EB1, - 0x0476, 0x1A78, 0x01F4, 0x06D1, 0x017C, 0x0042, - 0x063F, 0x0011, 0x0012, 0x01C7, 0x04FB, 0x1A77, - 0x01AA, 0x04FC, 0x0A21, 0x021D, 0x01EE, 0x02BC, - 0x01C2, 0x021E, 0x00AA, 0x00D6, 0x021F, 0x016F, - 0x0077, 0x01AB, 0x00AC, 0x0073, 0x078D, 0x00AF, - 0x002E, 0x0220, 0x0086, 0x0103, 0x0086, 0x0127, - 0x0BA0, 0x05DF, 0x0EA5, 0x03D3, 0x05E0, 0x017D, - 0xFAE7, 0x015A, 0x03C6, 0x0768, 0xFAE6, 0x3F65, - 0x01F3, 0x0B9F, 0x0016, 0x0EA4, 0x078C, 0x02BD, - 0x004D, 0x0116, 0x037A, 0x0076, 0x0056, 0x058E, - 0x06D2, 0x0014, 0x009F, 0x0A23, 0x0346, 0x014E, - 0x02BF, 0x00A7, 0x0528, 0x0378, 0x0106, 0x01C3, - 0x017E, 0x0044, 0x03C7, 0x097F, 0x04A5, 0x020B, - 0x05E9, 0x0A24, 0x03D9, 0x0661, 0x0660, 0x014F, - 0x02BE, 0x023B, 0x04FD, 0x0313, 0x0017, 0x08BC, - 0x0769, 0x0622, 0x0D6C, 0x03D7, 0x01C8, 0x0A22, - 0x01AB, 0x0203, 0x076A, 0x03D8, 0x02D1, 0x00A6, - 0x05E3, 0x1A79, 0x1A7A, 0x0981, 0x05B1, 0x04FF, - 0x0982, 0x0348, 0x0128, 0x08BD, 0x0D6D, 0x13F4, - 0x05B2, 0x0624, 0x05B3, 0x0EB2, 0x2729, 0x1237, - 0x05B4, 0x0129, 0x0349, 0x2386, 0x0019, 0x04FE, - 0x05B0, 0xFAE8, 0x3F66, 0x0623, 0x05E1, 0x05E2, - 0x3F67, 0x0980, 0x0347, 0x0BA1, 0x0046, 0x0045, - 0x0EA6, 0x01C9, 0x0018, 0x13F3, 0x078E, 0x0152, - 0x0983, 0x1238, 0x272B, 0x01F2, 0x028F, 0x05E5, - 0x3F69, 0x0418, 0x02FC, 0x017F, 0x0EB3, 0x00EF, - 0x0790, 0x0791, 0x1239, 0x05E6, 0x05E7, 0x1A7C, - 0x034A, 0x001A, 0x0984, 0x05B5, 0x272A, 0x1A7B, - 0x0EA7, 0x0529, 0x02FB, 0x2387, 0x3F68, 0x078F, - 0x006D, 0x0D6E, 0x05B6, 0x039F, 0x014E, 0x058F, - 0x13F5, 0x05E4, 0x020C, 0x0342, 0x1A73, 0x7DF7, - 0x2724, 0x0082, 0x0209, 0x1A74, 0x05DB, 0x03D6, - 0x001F, 0x0B9C, 0x04F9, 0x0096, 0x03C3, 0x0620, - 0x7DF9, 0x7DF8, 0x0EA2, 0x000C, 0x2725, 0x3F61, - 0x0977, 0x0976, 0x2723, 0x05D8, 0x2722, 0x058C, - 0x08B6, 0x05D9, 0x2383, 0x0236, 0x036D, 0x0A1F, - 0x05AA, 0x019C, 0x01C0, 0x0327, 0x05DA, 0x7DF6, - 0x02CF, 0x05DD, 0x0341, 0x05AE, 0x0EAF, 0x2384, - 0x0342, 0x13F0, 0x000D, 0x08B7, 0x000E, 0x003F, - 0x097B, 0x0343, 0x0D6A, 0x1A75, 0x000F, 0x3F63, - 0x05AF, 0x06CF, 0x06D0, 0x2385, 0x13F1, 0x058D, - 0x0237, 0x05AB, 0x7DFA, 0x0EA3, 0x03C4, 0x13EF, - 0x05DC, 0x2726, 0x1236, 0x017A, 0x0978, 0x05AD, - 0x05AC, 0x0340, 0x0238, 0x097A, 0x3F62, 0x0979, - 0x03DE, 0x0010, 0x0345, 0x002A, 0x03D1, 0x01A7, - 0x01F2, 0x009E, 0x020A, 0x0189, 0x0D6B, 0x03C6, - 0x00EE, 0x0A20, 0x017B, 0x04FA, 0x0472, 0x0040, - 0x00CB, 0x08B9, 0x02D0, 0x029E, 0x0020, 0x0344, - 0x0239, 0x02D0, 0x0B9D, 0x023A, 0x0B9E, 0x028D, - 0x03C5, 0x03BE, 0x08B8, 0x078B, 0x0337, 0x0246, - 0x004C, 0x0416, 0x0141, 0x04A4, 0x00E2, 0x0213, - 0x028E, 0x01A7, 0x021C, 0x00D4, 0x01C6, 0x0072, - 0x0067, 0x002B, 0x0473, 0x036F, 0x01E0, 0x036E, - 0x0041, 0x3F64, 0x097E, 0x0621, 0x02BB, 0x00D7, - 0x2728, 0x2727, 0x01C1, 0x0129, 0x0417, 0x13F2, - 0x097C, 0x0142, 0x097D, 0x1A76, 0x08BA, 0x063E, - 0x0100, 0x01AA, 0x018A, 0x00EA, 0x014D, 0x001E, - 0x01C5, 0x03C7, 0x0053, 0x05EC, 0x012D, 0x004C, - 0x0D71, 0x01D0, 0x0023, 0x0D72, 0x0185, 0x02D2, - 0x0719, 0x012F, 0x0502, 0x012E, 0x0A28, 0x098E, - 0x238B, 0x272D, 0x05EE, 0x05BE, 0x0130, 0xFAEE, - 0x272E, 0x0BA2, 0x05EB, 0x01CF, 0xFAED, 0x238A, - 0x01CE, 0x098C, 0x7DFD, 0x05BD, 0x004A, 0x0036, - 0x0037, 0x0628, 0x02FD, 0x048A, 0x017E, 0x004B, - 0x098D, 0x0153, 0x0216, 0x0D73, 0x1A82, 0x0042, - 0x017F, 0x026C, 0x020D, 0x0794, 0x0143, 0x007E, - 0x062A, 0x0798, 0x004F, 0x0EBA, 0x0BA4, 0x023E, - 0x05BF, 0x0EB9, 0x0592, 0x03CC, 0x004E, 0x018E, - 0x032C, 0x0629, 0x0BA3, 0x01F7, 0x0EB8, 0x004D, - 0x0990, 0x0350, 0x098F, 0x0343, 0x0023, 0x052B, - 0x004E, 0x0178, 0x04A6, 0x0291, 0x05ED, 0x00DC, - 0x032D, 0x0504, 0x0991, 0x0A29, 0x0593, 0x01F3, - 0x0A2A, 0x0505, 0x015B, 0x0666, 0x0087, 0x03DA, - 0x0BA5, 0x076D, 0x05C1, 0x03CD, 0x0024, 0x0992, - 0x04A7, 0x0131, 0x05C2, 0x272F, 0x01D1, 0x076B, - 0x076C, 0x1242, 0x05EF, 0x062B, 0x0EAE, 0x13FD, - 0x05C0, 0x0EBB, 0x023F, 0x0D74, 0x0503, 0x02FE, - 0x041A, 0x037B, 0x08BE, 0x0240, 0x0316, 0x0EBD, - 0x3F70, 0x0EBC, 0x0A2B, 0x0BA7, 0x0053, 0x05C5, - 0x13FE, 0x0506, 0x03CE, 0x0026, 0x0994, 0x0038, - 0x0027, 0x0132, 0x020E, 0x2731, 0x0EBE, 0x0796, - 0x018F, 0x05C6, 0x02FF, 0x0795, 0x1A83, 0x3F6E, - 0x0BA6, 0x0025, 0x1243, 0x3F6F, 0x004F, 0x2730, - 0x062C, 0x0993, 0x05C3, 0x05C4, 0x0051, 0x0052, - 0x0351, 0x062D, 0x0050, 0x01F6, 0x08BF, 0x3F71, - 0x238E, 0x05C7, 0x01F7, 0x05C8, 0x062E, 0x012A, - 0x032F, 0x0077, 0x1A86, 0x0EBF, 0x03DB, 0x04AA, - 0x0BA8, 0x13FF, 0x062F, 0xFAF2, 0x071A, 0x0054, - 0xFAF1, 0x2732, 0xFAF0, 0x238C, 0x238D, 0xFAEF, - 0x1A84, 0x0392, 0x1244, 0x0995, 0x0799, 0x007F, - 0x032E, 0x7DFE, 0x1A85, 0x05EE, 0x018A, 0x0996, - 0x0028, 0x0152, 0x025A, 0x0A25, 0x7DFC, 0x3F6B, - 0x023C, 0x018B, 0x05B7, 0x0180, 0x00FD, 0x01BA, - 0x05EA, 0x123D, 0x05E8, 0x002F, 0x0625, 0x05B9, - 0x05B8, 0x0477, 0x13F7, 0x0D6F, 0x3F6C, 0xFAEA, - 0x01CB, 0xFAE9, 0x0985, 0x2388, 0x7DFB, 0x034B, - 0x01CA, 0x0047, 0x123A, 0x3F6A, 0x017D, 0x0662, - 0x123C, 0x123B, 0x0379, 0x024A, 0x13F6, 0x1A7D, - 0x016A, 0x0EAA, 0x123F, 0xFAEC, 0x0EA9, 0x13FB, - 0x0182, 0x0792, 0x05BA, 0x0181, 0x0D70, 0x001F, - 0x001E, 0x05BB, 0x3F6D, 0x0020, 0x2389, 0x1240, - 0x0183, 0x0501, 0x1A7F, 0x06D6, 0x0663, 0x06D3, - 0x13F8, 0x034C, 0x0EB4, 0x123E, 0x1A7E, 0x13F9, - 0x001B, 0x05E9, 0x0EA8, 0x001C, 0xFAEB, 0x05EA, - 0x034D, 0x0500, 0x13FA, 0x001D, 0x0048, 0x0794, - 0x0075, 0x0795, 0x0793, 0x0074, 0x008A, 0x03C9, - 0x05EB, 0x0087, 0x0076, 0x012B, 0x012C, 0x037A, - 0x0718, 0x0022, 0x272C, 0x0988, 0x0EB5, 0x0328, - 0x03CA, 0x05EC, 0x0EAB, 0x06D7, 0x0021, 0x0664, - 0x1A80, 0x0986, 0x0419, 0x03C8, 0x034E, 0x0987, - 0x0626, 0x02FC, 0x00AE, 0x01CC, 0x023D, 0x012A, - 0x0021, 0x0A26, 0x05BC, 0x01F6, 0x0221, 0x0049, - 0x0EB6, 0x0042, 0x02D2, 0x00F2, 0x00AF, 0x0290, - 0x0043, 0x052A, 0x13FC, 0x0A27, 0x032A, 0x1241, - 0x0EB7, 0x0EAD, 0x034F, 0x0EAC, 0x0022, 0x05ED, - 0x0797, 0x032B, 0x0035, 0x0989, 0x0184, 0x037B, - 0x098A, 0x1A81, 0x098B, 0x0796, 0x01CD, 0x025B, - 0x03CB, 0x0627, 0x02DA, 0x010C, 0x02D1, 0x06EA, - 0x0665, 0x0329, 0x0D78, 0x7E05, 0x7E04, 0x140A, - 0x0EB3, 0x0ECF, 0x3F7C, 0x1256, 0x05FB, 0x05CF, - 0xFAFF, 0x3F7D, 0x0ED0, 0x7E06, 0x3F7E, 0x3F7F, - 0xFB00, 0x239B, 0x0ED2, 0x1257, 0x7E07, 0x0ED1, - 0x002D, 0x1255, 0x273A, 0x09A4, 0x239A, 0x0ECD, - 0x273B, 0x1A8C, 0x002E, 0x09A5, 0xFAFE, 0x273C, - 0x0BAF, 0x0BB0, 0x05CE, 0x09A6, 0x00D1, 0x0ECE, - 0x09A8, 0x0030, 0x1A8E, 0x0ED3, 0x09A7, 0x0667, - 0x1258, 0x2740, 0x0D79, 0x3F80, 0x0189, 0x09A9, - 0x0EB5, 0x0359, 0x0ED4, 0x125A, 0x239D, 0x1259, - 0x05D1, 0x0D7A, 0x7E0A, 0x7E09, 0x09AA, 0x273D, - 0x0EB4, 0x273E, 0x002F, 0x0354, 0x05FC, 0x239C, - 0x1A8D, 0x0355, 0x0357, 0x05D0, 0x0358, 0x0356, - 0x01D2, 0x0508, 0x7E08, 0x273F, 0x0302, 0x0ED7, - 0x239E, 0x3F84, 0x08C4, 0x01D3, 0x0BB1, 0x0509, - 0x239F, 0x0303, 0x0133, 0x035C, 0x125B, 0x03D1, - 0x0ED8, 0x035D, 0x035E, 0x2743, 0x2744, 0x09AD, - 0x018A, 0x0031, 0x09AC, 0x3F82, 0x2741, 0x3F81, - 0x035A, 0x3F83, 0x05FD, 0x09AB, 0x0ED5, 0x0ED6, - 0x0633, 0x2742, 0x0055, 0x08C3, 0x0636, 0x035B, - 0x05FE, 0x0D7B, 0x0039, 0xFB05, 0x7E0B, 0x7E0C, - 0x140D, 0x018B, 0x09AF, 0x2746, 0x0032, 0x0056, - 0x09B0, 0x03D2, 0x0A30, 0x2747, 0x0057, 0x0EDA, - 0x050A, 0x125E, 0x0033, 0x2748, 0x0D7C, 0x03D3, - 0x3F85, 0x0034, 0xFB01, 0x140B, 0xFB02, 0x05FF, - 0x125C, 0xFB03, 0x125D, 0x1A8F, 0x0600, 0x05D2, - 0x0602, 0x2745, 0x0601, 0x0ED9, 0x1A90, 0xFB04, - 0x140C, 0x09AE, 0x033A, 0x7E0F, 0x23A2, 0x0A31, - 0x0EB6, 0x0058, 0x3F8A, 0x23A3, 0x01D6, 0x04AB, - 0x0059, 0x0EDB, 0x02D3, 0x018C, 0x04C6, 0x1260, - 0x3F8B, 0x125F, 0x1261, 0x071E, 0x7E10, 0x2749, - 0x140E, 0x3F87, 0x3F86, 0x0035, 0x3F88, 0x3F89, - 0x7E0D, 0x23A0, 0x1A91, 0x0797, 0x0603, 0x1A92, - 0x050B, 0x066A, 0x0306, 0x7E0E, 0x23A1, 0x079B, - 0x0BAA, 0x3F73, 0x7E01, 0x0292, 0x0216, 0x0998, - 0x1247, 0x2390, 0x0301, 0x0999, 0x1400, 0x1A87, - 0x041E, 0x1401, 0x0EC1, 0x2391, 0x3F74, 0x0A2C, - 0x1248, 0x3F75, 0x05C9, 0x0EC2, 0x2733, 0x238F, - 0xFAF3, 0xFAF4, 0x0EC0, 0x0997, 0x3F72, 0xFAF5, - 0x1245, 0x08C0, 0x0BA9, 0x1246, 0x020F, 0x041B, - 0x0186, 0x7E00, 0x7DFF, 0x0300, 0xFAFA, 0x2734, - 0x05F2, 0x124D, 0x2395, 0x099A, 0x2735, 0x3F77, - 0x0EC4, 0x0EC5, 0x1403, 0x0EC6, 0x1402, 0x1A89, - 0x3F78, 0x05F5, 0x05F3, 0x05F4, 0x2736, 0x1404, - 0x7E02, 0x124E, 0x0D75, 0x0029, 0x2392, 0xFAF7, - 0xFAF6, 0x0EC3, 0x1249, 0x2394, 0x2393, 0x05F0, - 0xFAF8, 0x124B, 0x124C, 0x124A, 0x3F76, 0x05CA, - 0x05F1, 0xFAF9, 0x1A88, 0x0187, 0x05F7, 0x124F, - 0x0631, 0x0D76, 0x0EAF, 0x2737, 0x0BAC, 0x099D, - 0x0A2D, 0x1250, 0x1407, 0x0BAD, 0x3F7A, 0x2396, - 0x2397, 0x0353, 0x1A8B, 0x08C2, 0x05CD, 0x099E, - 0x05CC, 0x0352, 0x002A, 0x05CB, 0x03CF, 0x1A8A, - 0x1405, 0x1406, 0x099B, 0x0EC7, 0x0630, 0x002B, - 0x3F79, 0x08C1, 0x0BAB, 0x0507, 0x05F6, 0x0EC8, - 0x099C, 0x0EB0, 0x0A2F, 0x0EB1, 0x2739, 0x09A1, - 0x03D0, 0x1252, 0x7E03, 0x0241, 0x0188, 0x0EB2, - 0x0BAE, 0x05FA, 0x09A2, 0x1254, 0x2398, 0xFAFB, - 0x1253, 0x2399, 0x0ECC, 0xFAFD, 0xFAFC, 0x09A3, - 0x1408, 0x09A0, 0x05F8, 0x3F7B, 0x099F, 0x0D77, - 0x1409, 0x002C, 0x0EC9, 0x0ECB, 0x0A2E, 0x1251, - 0x0ECA, 0x079A, 0x071B, 0x05F9, 0x2738, 0x0632, - 0x002E, 0x0012, 0x7E25, 0xFB1C, 0x0262, 0x001C, - 0x03D6, 0x018E, 0x007C, 0x0342, 0x052E, 0x7E26, - 0xFB1D, 0x01D7, 0x0D7F, 0x126A, 0x2756, 0x09B6, - 0xFB20, 0x3F97, 0xFB21, 0xFB1E, 0xFB1F, 0x23AF, - 0xFB19, 0xFB1A, 0x23AE, 0x7E24, 0x1A95, 0x2755, - 0x2754, 0x05D7, 0x050D, 0x0EE3, 0xFB1B, 0x0EE2, - 0x0BB5, 0x00E3, 0x08CB, 0x05D8, 0x01B9, 0x00E7, - 0x1412, 0x1A96, 0x015A, 0x009A, 0x007B, 0xFB24, - 0x3F99, 0x026D, 0x0026, 0x0EE5, 0x0EE4, 0x0222, - 0x05D9, 0x0D82, 0x7E28, 0x3F9A, 0x0A36, 0xFB25, - 0xFB26, 0x23B1, 0x7E29, 0x126B, 0x7E27, 0x23B0, - 0xFB22, 0x1411, 0x0BB6, 0x3F98, 0x126C, 0x09B7, - 0x02C2, 0x0442, 0x0A33, 0x012B, 0x01C1, 0x0034, - 0xFB23, 0x126D, 0x03DF, 0x0084, 0x0EB7, 0x23B2, - 0x7E2A, 0x052F, 0x018D, 0x0B16, 0x7E2B, 0x01A2, - 0x0736, 0x00F3, 0x060F, 0x003B, 0x003B, 0x081A, - 0x003F, 0x1416, 0x003E, 0x3F9D, 0x126E, 0x7E2E, - 0x7E2C, 0x7E2D, 0x2757, 0x060E, 0xFB28, 0xFB27, - 0x3F9B, 0x050E, 0x0EE6, 0x018F, 0x05DA, 0x0136, - 0x071F, 0xFB29, 0x1413, 0x0137, 0x3F9C, 0x0EE7, - 0x05DB, 0x02DB, 0x05EF, 0x23B5, 0x0EBB, 0x0243, - 0xFB2D, 0x0307, 0xFB2E, 0x275A, 0x0293, 0x041F, - 0x0686, 0x3F9E, 0x0217, 0x0612, 0x05FA, 0x23B6, - 0x7E2F, 0x1A97, 0x275B, 0x0613, 0xFB2F, 0x7E30, - 0xFB2A, 0x23B4, 0x126F, 0x23B3, 0x1270, 0x2758, - 0xFB2B, 0x0610, 0x0BB7, 0x03D7, 0x2759, 0x0916, - 0x050F, 0x0EBA, 0x0BF6, 0xFB2C, 0x0611, 0x00D3, - 0x2C5E, 0x7E36, 0xFB34, 0xFB33, 0x3FA2, 0xFB35, - 0x2FDE, 0x1417, 0x0A37, 0x3FA3, 0x02A2, 0x7E37, - 0xFB36, 0x005E, 0x058A, 0x076F, 0x0886, 0x005F, - 0xFB3B, 0x0686, 0x0342, 0xFB37, 0xFB3A, 0x3F9F, - 0x3FA0, 0xFB31, 0xFB30, 0x23B7, 0x3FA1, 0x23BB, - 0x23BA, 0x1271, 0x0D83, 0x1036, 0x7E32, 0x1272, - 0x7E31, 0x7E33, 0x162E, 0x1273, 0xFB32, 0xFB0C, - 0x1262, 0xFB0D, 0xFB0B, 0x3F8F, 0x0037, 0x1263, - 0x3F90, 0x0EDD, 0x0038, 0x05D3, 0xFB0E, 0x23A7, - 0x0606, 0x1265, 0x3F91, 0x1264, 0x0039, 0xFB0F, - 0x7E14, 0xFB10, 0x274A, 0x274B, 0xFB07, 0xFB08, - 0x23A5, 0xFB06, 0x23A4, 0x0EDC, 0xFB0A, 0xFB09, - 0x7E11, 0x0036, 0x0605, 0x3F8C, 0x7E12, 0x0604, - 0x3F8E, 0x23A6, 0x7E13, 0x3F8D, 0x03DE, 0x7E19, - 0x7E18, 0x0242, 0x0097, 0x08C5, 0xFB13, 0x7E1A, - 0x005A, 0x079B, 0x0607, 0x09B2, 0x033B, 0x05D4, - 0x09B3, 0xFB14, 0x23A8, 0x0637, 0x7E1B, 0x23AA, - 0x23A9, 0x0608, 0x274C, 0xFB12, 0xFB11, 0x7E15, - 0x1266, 0x140F, 0x1267, 0x7E16, 0x274D, 0x079E, - 0x274E, 0x0EDE, 0x066B, 0x09B1, 0x0D7D, 0x3F92, - 0x7E17, 0x079A, 0x002A, 0x00D2, 0x23AC, 0x23AB, - 0x02F2, 0x00B6, 0x0BB2, 0x05D5, 0x0066, 0x03A2, - 0x003A, 0x060B, 0x060A, 0x0317, 0x079F, 0x0362, - 0x2750, 0x050C, 0x3F95, 0x7E1D, 0x7E1E, 0xFB15, - 0x23AD, 0x274F, 0x3F93, 0x3F94, 0x7E1C, 0x0609, - 0x08C6, 0x0EE0, 0x0EDF, 0x035F, 0x0136, 0x076E, - 0x1A93, 0x1268, 0x0A32, 0x024B, 0x08C7, 0x1410, - 0x01EC, 0x0036, 0x0EE1, 0x0363, 0x0072, 0x0030, - 0x003E, 0x2753, 0x7E21, 0x00D7, 0x0117, 0x003A, - 0x0BB4, 0x0126, 0x018D, 0x05D6, 0x7E22, 0xFB16, - 0x0D7E, 0x060D, 0xFB18, 0xFB17, 0x7E23, 0x7E1F, - 0x2752, 0x1269, 0x2751, 0x09B4, 0x08CA, 0x1A94, - 0x3F96, 0x0BB3, 0x0107, 0x09B5, 0x005B, 0x03D6, - 0x00B0, 0x0101, 0x7E20, 0x060C, 0x03D7, 0x0032, - 0x04DE, 0xFA91, 0x7DA8, 0x088E, 0x0374, 0x7DA9, - 0x054E, 0x007A, 0x0223, 0x0152, 0x3F26, 0x7DAA, - 0x0610, 0x1A36, 0x13B3, 0x0E58, 0x1A35, 0x7DAD, - 0x3F27, 0x7DAE, 0x7DAB, 0x7DAC, 0xFA8D, 0x2347, - 0xFA8E, 0xFA8C, 0x7DA6, 0x3F24, 0x2348, 0x7DA7, - 0x0E4F, 0x02C8, 0x0376, 0xFA90, 0xFA8F, 0x0116, - 0x008A, 0x059A, 0x3F25, 0x0044, 0x00AC, 0x1A37, - 0x0153, 0x0066, 0x01DE, 0x049C, 0xFA96, 0x3F28, - 0x0370, 0x00EA, 0x054F, 0x3F29, 0x006B, 0x093C, - 0x0570, 0x11E2, 0x26E0, 0x1A38, 0x26E1, 0x234A, - 0x7DB1, 0x093D, 0x1FD7, 0x2349, 0x7DAF, 0x7DB0, - 0x0310, 0x0775, 0xFA93, 0xFA92, 0x13B4, 0x009A, - 0x0022, 0x093B, 0x020E, 0x002A, 0x003C, 0xFA95, - 0xFA94, 0x033C, 0x00A8, 0x00C9, 0x26E3, 0xFA99, - 0x051D, 0x00FA, 0x0154, 0x093E, 0x00DE, 0x0371, - 0x002E, 0xFA9A, 0x11E3, 0x0377, 0x0776, 0x7DB2, - 0x11E4, 0x11E5, 0x7DB3, 0x3F2B, 0xFA9B, 0x234E, - 0x11E6, 0x26E2, 0x059B, 0xFA98, 0xFA97, 0x234B, - 0x0A0D, 0x059C, 0x234C, 0x0571, 0x006C, 0x075C, - 0x234D, 0x3F2A, 0x06C2, 0x00FE, 0x0311, 0x059D, - 0x010A, 0x031C, 0x059E, 0x11E8, 0x0587, 0x2352, - 0x0312, 0x7DB6, 0xFA9E, 0x04DF, 0x1FD8, 0x11E9, - 0x093F, 0x0A0E, 0x0E5A, 0x11EA, 0x2353, 0x1FD9, - 0x0573, 0x11EB, 0x7DB7, 0xFA9F, 0x0E5B, 0xFA9C, - 0xFA9D, 0x7DB4, 0x234F, 0x0E59, 0x0572, 0x2351, - 0x2350, 0x11E7, 0x049D, 0x3F2D, 0x3F2C, 0x0023, - 0x010D, 0x088F, 0x7DB5, 0x26E4, 0x0611, 0xFAA4, - 0x1A39, 0xFAA5, 0xFAA3, 0x26E7, 0xFAA6, 0x3F2F, - 0x2356, 0x2357, 0x0940, 0x13B8, 0xFAA7, 0x7DBC, - 0x1FDA, 0x2358, 0xFAA8, 0x3F30, 0x26E8, 0xFAA9, - 0xFAAA, 0xFAAB, 0x2359, 0x7DBD, 0x7DB9, 0x2354, - 0x11EC, 0xFAA0, 0x7DB8, 0x13B5, 0x11ED, 0x2355, - 0x7DBA, 0x13B6, 0x13B7, 0x7DBB, 0xFAA1, 0x26E5, - 0x0612, 0x3F2E, 0x26E6, 0xFAA2, 0x7D9E, 0x0590, - 0x7D9F, 0xBF7D, 0x0D0F, 0x13AF, 0x0591, 0x1A1C, - 0x1FD3, 0x17EE, 0x0592, 0x3F1A, 0xBF7E, 0x11DC, - 0x0593, 0x206F, 0x7DA0, 0x3F1C, 0xBF7F, 0x1A1E, - 0x3F1D, 0x1A1D, 0x245C, 0x110E, 0x110F, 0x58BE, - 0x0220, 0x0150, 0x1FD2, 0x7D9C, 0x04DC, 0x05E6, - 0x0D0E, 0x001E, 0xBF7C, 0x58BF, 0x0B80, 0x054C, - 0x13AE, 0x206E, 0x02A3, 0x051C, 0x1A30, 0x245F, - 0x0466, 0x7DA1, 0x030A, 0x3F1F, 0xFA82, 0x088C, - 0x05E7, 0x04DD, 0x13B0, 0x0790, 0x1A31, 0x1FD4, - 0x13B1, 0x7DA2, 0x2638, 0x1A32, 0x2341, 0x2340, - 0x2639, 0x3F1E, 0xFA80, 0x0594, 0x11DE, 0x11DF, - 0x0596, 0x1A1F, 0x0595, 0x02C4, 0x051A, 0x0E4D, - 0x0E4C, 0x040C, 0x245E, 0x0464, 0xFA81, 0x245D, - 0x0222, 0x0074, 0x031A, 0x3F21, 0x263B, 0x06EB, - 0x0254, 0x0774, 0x0020, 0x0078, 0x0410, 0x02EE, - 0x13B2, 0xFA84, 0x06C0, 0x0A0A, 0x0E4E, 0x0597, - 0xFA85, 0xFA87, 0x0598, 0x11E0, 0xFA86, 0x263C, - 0x1FD5, 0x2343, 0xFA83, 0x3F20, 0x2342, 0x030B, - 0x263A, 0x0B81, 0x0586, 0x040E, 0x040F, 0x2345, - 0x2344, 0x02C6, 0x0130, 0x030C, 0x054D, 0x01BE, - 0x0132, 0x0599, 0x3F23, 0x00FA, 0x012E, 0x03CE, - 0xFA8B, 0x263E, 0x02C7, 0x006A, 0x093A, 0x0E6E, - 0x0182, 0x0021, 0x00C8, 0x1A33, 0x7DA5, 0x0E6F, - 0x1FD6, 0x1A34, 0x2346, 0x263F, 0x3F22, 0x7DA4, - 0xFA88, 0x7DA3, 0x030D, 0x0A0C, 0xFA89, 0x11E1, - 0x088D, 0x0256, 0x030F, 0x030E, 0x02F8, 0x0060, - 0x02B8, 0xFA8A, 0x263D, 0x0257, 0x13BE, 0x7DCD, - 0xFAB4, 0x0E83, 0x13BF, 0x015B, 0x26F8, 0x26F7, - 0x0B89, 0x0947, 0x3F39, 0x11F9, 0x13C0, 0x26F9, - 0x05AF, 0x11FC, 0x11FA, 0x11FB, 0x0E84, 0x11FE, - 0xFAB5, 0x11FD, 0x26F5, 0xFAB2, 0x235F, 0x05AC, - 0x26F6, 0x05AD, 0x7DCB, 0x7DCA, 0x2360, 0x0946, - 0x7DCC, 0xFAB3, 0x057A, 0x0318, 0x11F8, 0x05AE, - 0x2361, 0x0B88, 0x26FB, 0x1203, 0x1204, 0x0E85, - 0x0E86, 0x0D4F, 0x0E87, 0x0948, 0x0A10, 0x1FE2, - 0x057C, 0x1A3F, 0x0D50, 0x015D, 0x057D, 0x1205, - 0x1A40, 0x13C2, 0x26FC, 0x26FD, 0x1206, 0x3F3A, - 0x1A41, 0x1FE1, 0x0E8E, 0x26FA, 0xFAB6, 0x11FF, - 0x1201, 0x7DCE, 0x1200, 0x05B0, 0x13C1, 0x089E, - 0x0319, 0x015C, 0x057B, 0x070A, 0x1A3E, 0x1202, - 0x011D, 0x031A, 0x7DCF, 0x1209, 0x0E90, 0x015F, - 0x002B, 0x05B1, 0x0D54, 0x04E5, 0x0160, 0x05B2, - 0x13C4, 0x0E88, 0x1FE5, 0x1FE6, 0x2362, 0x3F3B, - 0x13C5, 0x26FF, 0x0161, 0x057E, 0x0779, 0x0D51, - 0x13C3, 0x1A42, 0x04E4, 0x1208, 0x1A44, 0x1FE3, - 0x1207, 0x1A43, 0x0225, 0x26FE, 0x1FE4, 0x015E, - 0x0D53, 0x002A, 0x0E8F, 0x0D52, 0x0778, 0x2701, - 0x2363, 0x3F3E, 0x1FE8, 0xFAB8, 0x13C9, 0x2365, - 0x2364, 0x031B, 0x120A, 0x0E8B, 0x05B8, 0x0E8A, - 0x13CA, 0x3F3F, 0x2702, 0x1FE9, 0x120B, 0x7DD0, - 0x094A, 0x2366, 0xFAB9, 0x13CB, 0x1A45, 0x13C7, - 0x05B3, 0xFAB7, 0x13C6, 0x3F3D, 0x05B4, 0x3F3C, - 0x1FE7, 0x05B5, 0x13C8, 0x0E89, 0x1A46, 0x1A47, - 0x05B6, 0x05B7, 0x2700, 0x0949, 0x0122, 0x05B9, - 0x2704, 0x031D, 0x0469, 0x094C, 0xFABA, 0x120F, - 0x1A48, 0x0638, 0x1210, 0x13CC, 0x01B3, 0x3F42, - 0x1A49, 0xFABB, 0x3F41, 0x0E8C, 0x1A4A, 0x2367, - 0x3F43, 0x094D, 0x2703, 0x094B, 0x7DD1, 0x3F40, - 0x031C, 0x0226, 0x1FEA, 0x7DD2, 0x120C, 0x03DA, - 0x0B8A, 0x120D, 0x002C, 0x03CC, 0x04E6, 0x7DD3, - 0x120E, 0x089F, 0x04E2, 0x059F, 0xFAAD, 0x0117, - 0x0137, 0x0613, 0x235C, 0x3F31, 0x0899, 0x02EF, - 0x0025, 0x0942, 0x0468, 0x0E8C, 0x0A0F, 0x13BA, - 0x7DBE, 0x13B9, 0x05A0, 0x7DC0, 0x26EB, 0x7DBF, - 0x235A, 0x235B, 0x0372, 0x0313, 0x0941, 0x0898, - 0x26E9, 0x0574, 0x02C9, 0x051E, 0x0024, 0x1FDB, - 0x0467, 0x0791, 0x04E1, 0x26EA, 0xFAAC, 0x04E0, - 0x3F34, 0x0E5D, 0x26ED, 0xFAAE, 0x1FDC, 0x0575, - 0x0314, 0x7DC4, 0x1FDD, 0x1FDE, 0x05A1, 0x0E5E, - 0x26EE, 0x26EF, 0x7DC5, 0x11EE, 0xFAAF, 0x3F35, - 0x11EF, 0x26F0, 0x7DC6, 0xFAB0, 0x05A2, 0x7DC1, - 0x0E5C, 0x7DC2, 0x00CA, 0x01B0, 0x235D, 0x3F32, - 0x075E, 0x0B82, 0x0155, 0x0156, 0x3F33, 0x26EC, - 0x0708, 0x0B83, 0x1A3B, 0x7DC3, 0x1A3A, 0x089B, - 0x11F2, 0x05A5, 0x0E5F, 0x0027, 0x01B2, 0x089C, - 0x26F3, 0x0B85, 0x0157, 0x011C, 0x0944, 0x0577, - 0x7DC8, 0x13BB, 0x089D, 0x05A6, 0x0315, 0x0E8D, - 0xFAB1, 0x1A3C, 0x03AC, 0x0576, 0x7DC7, 0x0B84, - 0x05A3, 0x26F1, 0x26F2, 0x05A4, 0x0224, 0x0943, - 0x0D4C, 0x11F0, 0x1FDF, 0x089A, 0x02F0, 0x0D4D, - 0x0026, 0x11F1, 0x0777, 0x0E82, 0x0029, 0x05A8, - 0x1A3D, 0x0028, 0x00CB, 0x0159, 0x11F6, 0x0709, - 0x0614, 0x04E3, 0x015A, 0x0578, 0x0B87, 0x1FE0, - 0x05AA, 0x7DC9, 0x05A9, 0x05AB, 0x0579, 0x11F7, - 0x3F38, 0x0945, 0x13BC, 0x26F4, 0x235E, 0x3F36, - 0x0158, 0x05A7, 0x3F37, 0x0E80, 0x11F3, 0x13BD, - 0x0B86, 0x0E81, 0x0316, 0x0317, 0x0D4E, 0x11F5, - 0x11F4, 0x075F, 0x06C3, 0x08A6, 0x0B8D, 0x0584, - 0x022A, 0x02CA, 0x13D5, 0x0E93, 0x0217, 0x011F, - 0x0124, 0x0120, 0x0B8E, 0x06C4, 0x0326, 0x0327, - 0x05BC, 0x0B8F, 0xFAC1, 0x0955, 0x1217, 0x7DD9, - 0x0328, 0x0323, 0x0324, 0x2369, 0x7DD8, 0x0031, - 0x1FF3, 0x1216, 0xFAC0, 0x1215, 0x0032, 0x00CD, - 0x03AF, 0x0A12, 0x01BC, 0x0070, 0x0325, 0x0E92, - 0x038E, 0x02D7, 0x2708, 0x13D7, 0x0296, 0x039A, - 0x00FE, 0x070D, 0x01ED, 0x02D8, 0x0398, 0x077E, - 0x0167, 0x0244, 0x0329, 0x01BD, 0x0521, 0x022B, - 0x1A50, 0x0122, 0x08A9, 0x0A13, 0x05DD, 0x070C, - 0x04E9, 0x0033, 0x0121, 0x13D6, 0x0956, 0x08A7, - 0x0585, 0x0166, 0x0204, 0x08A8, 0x0586, 0x04A0, - 0x02CB, 0x003D, 0x0588, 0x0289, 0x03C2, 0x03B8, - 0x077F, 0x0587, 0x04EB, 0x00CF, 0x01A3, 0x13D9, - 0x0617, 0x01A2, 0x06C5, 0x0522, 0x03B9, 0x070E, - 0x0762, 0x08AA, 0x1A51, 0x0169, 0x03BA, 0x1218, - 0x0523, 0x04EC, 0x3F49, 0x0E96, 0x04EA, 0x02CA, - 0x0D59, 0x13D8, 0x03D2, 0x0E95, 0x0957, 0x0E94, - 0x0168, 0x0123, 0x031E, 0x0412, 0x032A, 0x00CE, - 0x039C, 0x0E95, 0x0D5A, 0x0071, 0x13DC, 0x7DDA, - 0x236C, 0x0E96, 0x13DD, 0x032C, 0x1A52, 0x0B90, - 0x0589, 0x032D, 0x2709, 0x1FF6, 0x058A, 0x1219, - 0x05BD, 0x058B, 0x0035, 0x270A, 0x05DE, 0x095A, - 0x1A53, 0x016B, 0x022C, 0x070F, 0x13DA, 0x0958, - 0x3F4A, 0x0588, 0x0D5B, 0x13DB, 0x236A, 0x0780, - 0x3F4B, 0x1FF4, 0x0959, 0x0034, 0x016A, 0x236B, - 0x1FF5, 0x032B, 0x270B, 0x02F3, 0xFAC4, 0x7DDC, - 0x1FF7, 0x0124, 0x095C, 0x016C, 0x0072, 0x016A, - 0x04EE, 0x270D, 0x270C, 0x022D, 0x04A1, 0x270E, - 0x0E97, 0x0618, 0xFAC5, 0x0E98, 0x3F4C, 0x236E, - 0x1A54, 0x05BF, 0x032E, 0x121A, 0xFAC2, 0x05BE, - 0x01EE, 0x04ED, 0x236D, 0x03BB, 0x0125, 0x00EC, - 0x7DDB, 0xFAC3, 0x05DF, 0x00C9, 0x08AB, 0x095B, - 0x013C, 0x01FE, 0x0B8B, 0xFABD, 0x7DD4, 0x0615, - 0x01EA, 0x0E91, 0x057F, 0x016E, 0x0156, 0x08A1, - 0x094E, 0x7DD5, 0x03D1, 0x01B6, 0x1FEC, 0x1FEB, - 0xFABE, 0x7DD6, 0x1212, 0x7DD7, 0xFABF, 0x1A4C, - 0x0E8D, 0x3F44, 0xFABC, 0x002D, 0x006A, 0x01B5, - 0x13CD, 0x08A0, 0x01B4, 0x03D0, 0x006B, 0x1211, - 0x3F45, 0x0227, 0x02FE, 0x077A, 0x1A4B, 0x014A, - 0x0E91, 0x1FED, 0x2705, 0x0162, 0x094F, 0x002E, - 0x04E8, 0x1FEE, 0x0A11, 0x0950, 0x0581, 0x1FEF, - 0x1FF0, 0x2706, 0x3F47, 0x1A4F, 0x0582, 0x05BA, - 0x002F, 0x031E, 0x13CF, 0x0760, 0x0580, 0x0E92, - 0x031D, 0x04E7, 0x1A4D, 0x1A4E, 0x0E8E, 0x01B7, - 0x02F1, 0x02F2, 0x3F46, 0x0E8F, 0x0616, 0x0D55, - 0x006C, 0x0E93, 0x0E90, 0x13CE, 0x049E, 0x0411, - 0x13D0, 0x08A2, 0x03AD, 0x02D3, 0x0228, 0x13D1, - 0x006D, 0x006D, 0x0792, 0x01B8, 0x077C, 0x0229, - 0x0320, 0x1FF1, 0x3F48, 0x0D56, 0x13D2, 0x01B9, - 0x2707, 0x2368, 0x0D57, 0x00CC, 0x0520, 0x1213, - 0x0163, 0x051F, 0x0951, 0x1214, 0x0E94, 0x0164, - 0x00FC, 0x070B, 0x077B, 0x0761, 0x00C6, 0x017A, - 0x031F, 0x0583, 0x01EE, 0x00D4, 0x0165, 0x0952, - 0x02C8, 0x00C8, 0x023A, 0x0030, 0x01EC, 0x00FD, - 0x02F9, 0x01BB, 0x0953, 0x01A0, 0x13D4, 0x08A5, - 0x0030, 0x08A4, 0x077D, 0x006E, 0x0D58, 0x0954, - 0x05DC, 0x0123, 0x0321, 0x01BA, 0x0288, 0x05BB, - 0x13D3, 0x0322, 0x03AE, 0x0B8C, 0x049F, 0x1FF2, - 0x08A3, 0x006E, 0x02D6, 0x006F, 0x011E, 0x0373, - 0x03BF, 0x01EA, 0x08AF, 0x0595, 0x0100, 0x0112, - 0x0050, 0x02B9, 0x014C, 0x01A4, 0x0258, 0x04F2, - 0x0596, 0x00A4, 0x13E1, 0x0124, 0x08B0, 0x04F3, - 0x0171, 0x0413, 0x2713, 0x0E9B, 0x046C, 0x00A2, - 0x0765, 0x05E0, 0x019C, 0x0964, 0x0335, 0x061C, - 0x3F4F, 0x0E9A, 0x009A, 0x0170, 0x0784, 0x003E, - 0x012F, 0x01A3, 0x023D, 0x01F0, 0x016B, 0x00A3, - 0x023F, 0x03C4, 0x03D4, 0x0377, 0x0052, 0x01BE, - 0x0031, 0x0012, 0x0157, 0x021A, 0x0242, 0x039E, - 0x04A2, 0x05E1, 0x02F6, 0x1A5D, 0x0336, 0x0126, - 0x05E2, 0x2374, 0x05C4, 0x046D, 0x0311, 0x01A5, - 0x04F4, 0xFAC8, 0x023E, 0x0A17, 0x0D5F, 0x05C3, - 0x08B1, 0x009C, 0x02CD, 0x0299, 0x036A, 0x0376, - 0x006C, 0x0037, 0x0785, 0x0076, 0x0040, 0x0965, - 0x13E2, 0x02CC, 0x0259, 0x0414, 0x06C6, 0x01A6, - 0x033F, 0x0334, 0x0E9C, 0x0786, 0x0127, 0x0966, - 0x06C7, 0x063B, 0x0039, 0x0172, 0x0374, 0x003A, - 0x0597, 0x0128, 0x00FF, 0x0526, 0x2375, 0x0044, - 0x0337, 0x0B95, 0x0230, 0x7DDE, 0x0D60, 0x0185, - 0x0D61, 0x0038, 0x0321, 0x003F, 0x009D, 0x0101, - 0x03B9, 0x0312, 0x0969, 0x1A5E, 0x1220, 0x2714, - 0x003B, 0x0598, 0x2715, 0x1FFB, 0x08B2, 0x096A, - 0x0EA1, 0x7DDF, 0x1FFC, 0x0A18, 0x1A5F, 0x1222, - 0x1221, 0x0173, 0x0793, 0x061D, 0x096B, 0x7DE0, - 0x0787, 0x0231, 0x0711, 0x0EA0, 0xFAC9, 0x121D, - 0x05C5, 0x121F, 0x121E, 0x3F50, 0x0E9D, 0x0338, - 0x0968, 0x0967, 0x04F5, 0x0B96, 0x05C7, 0x05C6, - 0x03BE, 0x01B8, 0x1225, 0x1224, 0x02CE, 0x0160, - 0x0102, 0xFACD, 0x3F51, 0x0322, 0xFACE, 0x0339, - 0x059A, 0x019E, 0x063C, 0x01BF, 0x7DE2, 0x3F52, - 0x0D62, 0x2718, 0x3F53, 0x2717, 0x0EA2, 0x0599, - 0x13E3, 0xFACA, 0xFACB, 0x06C8, 0x06C9, 0xFACC, - 0x7DE1, 0x0125, 0x01BC, 0x13E4, 0x1223, 0x0336, - 0x02BA, 0x028B, 0x2716, 0x2376, 0x02CD, 0x013D, - 0x095E, 0x05C0, 0x0016, 0x016F, 0x0525, 0x2371, - 0x2370, 0x0205, 0x01C8, 0x058C, 0x0B91, 0x00E6, - 0x0639, 0x0330, 0x2372, 0x3F4D, 0x0763, 0x016E, - 0x121B, 0x1FF9, 0x058D, 0x016D, 0x1A55, 0x270F, - 0x13DE, 0xFAC6, 0x1FF8, 0x236F, 0x1A56, 0x04EF, - 0x0298, 0x0E99, 0x095D, 0x01BE, 0x02CC, 0x0524, - 0x032F, 0x7DDD, 0x0589, 0x095F, 0x03BC, 0x1A59, - 0x0E9A, 0x0E9B, 0x061A, 0x13E0, 0x0E9C, 0x08AD, - 0x0332, 0x0A15, 0x0591, 0x0D5D, 0x0590, 0x0960, - 0x2373, 0x2711, 0x1A5A, 0x058A, 0x006F, 0x3F4E, - 0x2712, 0x0764, 0x08AC, 0x05C1, 0xFAC7, 0x0331, - 0x1FFA, 0x13DF, 0x2710, 0x1A57, 0x0E97, 0x058E, - 0x0619, 0x0A14, 0x1A58, 0x0D5C, 0x0782, 0x058F, - 0x121C, 0x0781, 0x0210, 0x0594, 0x0962, 0x0080, - 0x0399, 0x03C3, 0x02F5, 0x0184, 0x028A, 0x046B, - 0x0963, 0x0B92, 0x0100, 0x1A5B, 0x0A16, 0x0E9D, - 0x03BD, 0x0B93, 0x01A4, 0x0333, 0x0783, 0x033E, - 0x00FE, 0x0592, 0x031F, 0x046A, 0x0593, 0x0961, - 0x04F0, 0x00FF, 0x02F4, 0x0073, 0x0E98, 0x04F1, - 0x033D, 0x0266, 0x02FF, 0x03D3, 0x0320, 0x0206, - 0x004E, 0x023C, 0x01EF, 0x0211, 0x0027, 0x000C, - 0x063A, 0x08AE, 0x008C, 0x03CE, 0x02D9, 0x02FA, - 0x01A2, 0x01A5, 0x061B, 0x0E9E, 0x05C2, 0x022F, - 0x039D, 0x01F0, 0x1A5C, 0x0E9F, 0x02CB, 0x03B8, - 0x014B, 0x0B94, 0x0E99, 0x013E, 0x016F, 0x0036, - 0x0334, 0x0D5E, 0x0310, 0x0207, 0x0044, 0x017B, - 0x00DF, 0x0042, 0x022E, 0x0710, 0x007E, -}; - -static const uint8_t on2avc_cb8_bits[ON2AVC_CB8_CODES] = { - 11, 11, 16, 15, 11, 9, - 13, 12, 9, 11, 11, 14, - 13, 12, 13, 14, 14, 13, - 10, 11, 15, 15, 10, 16, - 16, 15, 16, 11, 13, 13, - 16, 13, 11, 11, 15, 13, - 11, 9, 13, 13, 10, 9, - 16, 13, 9, 10, 10, 15, - 10, 10, 10, 12, 14, 11, - 14, 12, 14, 11, 12, 11, - 12, 14, 10, 10, 11, 16, - 10, 13, 14, 14, 11, 13, - 11, 13, 12, 10, 10, 10, - 15, 10, 10, 12, 12, 12, - 15, 12, 11, 12, 13, 10, - 11, 11, 12, 13, 11, 13, - 12, 15, 13, 11, 11, 12, - 14, 11, 11, 11, 13, 14, - 11, 13, 14, 13, 12, 12, - 12, 11, 14, 12, 10, 13, - 14, 11, 13, 15, 14, 14, - 13, 13, 14, 13, 13, 13, - 15, 14, 12, 14, 14, 14, - 16, 14, 12, 12, 16, 16, - 12, 13, 12, 14, 14, 13, - 13, 16, 14, 13, 14, 13, - 13, 13, 13, 15, 14, 13, - 10, 12, 16, 16, 12, 10, - 13, 14, 11, 11, 12, 14, - 14, 11, 12, 16, 13, 12, - 14, 14, 14, 16, 15, 16, - 15, 16, 15, 14, 12, 14, - 13, 11, 10, 11, 14, 14, - 11, 9, 14, 14, 10, 16, - 12, 15, 16, 12, 11, 14, - 13, 9, 11, 11, 15, 15, - 12, 13, 14, 15, 12, 16, - 14, 15, 15, 13, 14, 14, - 15, 14, 14, 14, 13, 15, - 12, 14, 12, 15, 15, 12, - 11, 13, 15, 10, 14, 13, - 14, 13, 13, 13, 13, 13, - 13, 12, 13, 13, 12, 14, - 14, 16, 12, 14, 11, 13, - 13, 12, 14, 15, 13, 13, - 13, 13, 13, 14, 13, 13, - 13, 14, 13, 13, 12, 14, - 14, 13, 11, 12, 13, 12, - 12, 10, 13, 13, 11, 11, - 12, 14, 11, 12, 13, 15, - 14, 14, 16, 11, 13, 13, - 11, 15, 10, 14, 13, 12, - 12, 13, 12, 13, 11, 11, - 11, 12, 11, 10, 12, 13, - 10, 10, 13, 13, 10, 10, - 10, 10, 15, 11, 11, 13, - 12, 11, 13, 12, 11, 16, - 14, 10, 14, 11, 10, 10, - 15, 12, 11, 13, 12, 11, - 14, 13, 11, 13, 11, 10, - 9, 10, 10, 14, 10, 9, - 14, 13, 9, 9, 10, 10, - 10, 10, 10, 12, 14, 10, - 14, 13, 12, 11, 14, 13, - 11, 13, 9, 11, 13, 13, - 11, 14, 14, 12, 12, 13, - 10, 12, 12, 10, 9, 10, - 10, 10, 10, 9, 10, 10, - 11, 10, 8, 12, 12, 9, - 11, 10, 10, 11, 11, 12, - 12, 14, 12, 10, 14, 13, - 16, 10, 10, 11, 16, 14, - 11, 12, 14, 12, 12, 10, - 11, 10, 10, 11, 9, 11, - 11, 9, 11, 12, 13, 10, - 10, 11, 11, 11, 11, 10, - 13, 13, 10, 13, 11, 11, - 11, 12, 11, 11, 11, 10, - 10, 12, 12, 10, 14, 12, - 11, 12, 12, 11, 12, 12, - 11, 10, 11, 11, 11, 11, - 14, 13, 13, 13, 13, 12, - 13, 13, 12, 12, 12, 13, - 13, 12, 13, 13, 14, 14, - 13, 12, 13, 15, 14, 12, - 13, 16, 14, 12, 14, 14, - 14, 13, 13, 12, 13, 13, - 12, 12, 14, 13, 12, 10, - 13, 14, 14, 10, 11, 14, - 14, 11, 10, 13, 13, 11, - 12, 12, 14, 14, 14, 13, - 13, 14, 13, 13, 14, 13, - 12, 11, 12, 15, 14, 12, - 9, 12, 13, 10, 9, 11, - 13, 14, 11, 10, 13, 15, - 14, 10, 11, 13, 14, 11, - 11, 12, 12, 10, 12, 12, - 15, 15, 12, 14, 14, 14, - 13, 13, 14, 14, 14, 11, - 12, 14, 15, 12, 10, 12, - 13, 9, 9, 11, 14, 15, - 11, 14, 13, 13, 13, 15, - 13, 13, 14, 12, 14, 13, - 13, 13, 12, 13, 14, 14, - 13, 11, 11, 15, 13, 11, - 12, 13, 15, 12, 12, 13, - 14, 14, 14, 13, 13, 13, - 13, 13, 12, 13, 14, 13, - 10, 14, 13, 11, 10, 11, - 11, 11, 11, 11, 12, 12, - 11, 12, 13, 12, 11, 13, - 10, 12, 11, 10, 11, 13, - 12, 10, 12, 12, 12, 11, - 12, 10, 12, 12, 10, 10, - 11, 11, 11, 11, 9, 10, - 11, 10, 10, 9, 12, 12, - 9, 11, 11, 10, 9, 10, - 13, 14, 13, 12, 10, 10, - 14, 14, 10, 11, 11, 13, - 13, 11, 13, 13, 12, 11, - 10, 11, 11, 10, 10, 9, - 12, 12, 9, 11, 12, 13, - 12, 12, 11, 12, 13, 11, - 11, 12, 12, 12, 12, 13, - 15, 14, 14, 13, 12, 16, - 14, 12, 11, 12, 16, 15, - 12, 13, 15, 13, 13, 12, - 12, 12, 12, 11, 10, 13, - 13, 10, 10, 12, 13, 10, - 10, 10, 11, 11, 11, 11, - 12, 12, 11, 13, 12, 12, - 13, 13, 11, 12, 13, 11, - 11, 12, 12, 11, 13, 13, - 13, 13, 13, 10, 14, 11, - 11, 10, 11, 11, 11, 10, - 11, 12, 13, 12, 11, 10, - 12, 12, 10, 11, 10, 11, - 12, 11, 13, 12, 14, 13, - 11, 12, 13, 14, 12, 11, - 11, 14, 14, 12, 12, 13, - 13, 13, 12, 12, 12, 12, - 11, 10, 12, 12, 10, 13, - 14, 13, 12, 12, 13, 13, - 13, 12, 12, 14, 13, 12, - 14, 12, 11, 14, 13, 11, - 11, 13, 12, 11, 13, 14, - 12, 14, 14, 14, 13, 14, - 12, 13, 13, 13, 13, 13, - 13, 12, 13, 10, 12, 14, - 15, 13, 10, 13, 12, 11, - 11, 12, 13, 13, 11, 11, - 12, 13, 12, 16, 11, 13, - 16, 14, 16, 15, 15, 16, - 13, 11, 14, 13, 12, 11, - 11, 15, 13, 11, 9, 13, - 14, 11, 10, 12, 15, 14, - 12, 11, 13, 13, 10, 11, - 11, 14, 14, 11, 12, 13, - 13, 11, 13, 12, 14, 16, - 12, 16, 13, 15, 15, 13, - 12, 13, 14, 14, 10, 11, - 14, 14, 11, 10, 13, 13, - 9, 12, 14, 16, 12, 13, - 13, 12, 13, 13, 12, 14, - 14, 13, 14, 14, 15, 14, - 13, 12, 13, 11, 11, 11, - 13, 13, 13, 14, 13, 13, - 14, 14, 12, 14, 16, 14, - 13, 12, 13, 14, 13, 12, - 12, 12, 12, 12, 11, 12, - 14, 11, 12, 12, 12, 11, - 11, 14, 14, 13, 13, 11, - 12, 14, 12, 11, 14, 11, - 13, 13, 11, 12, 13, 13, - 12, 12, 11, 12, 12, 12, - 11, 12, 13, 11, 10, 13, - 13, 11, 10, 11, 11, 11, - 11, 11, 13, 12, 11, 14, - 13, 12, 13, 12, 11, 14, - 12, 11, 12, 13, 13, 11, - 13, 13, 13, 12, 12, 10, - 12, 12, 10, 10, 10, 11, - 11, 11, 12, 15, 15, 13, - 12, 13, 14, 14, 14, 13, - 16, 14, 13, 15, 14, 14, - 16, 15, 13, 14, 15, 13, - 14, 14, 14, 13, 15, 13, - 14, 13, 14, 13, 16, 14, - 12, 12, 13, 13, 12, 13, - 13, 14, 13, 13, 13, 11, - 14, 14, 12, 14, 13, 13, - 12, 13, 13, 14, 15, 14, - 13, 12, 15, 15, 13, 14, - 12, 14, 14, 13, 14, 15, - 13, 13, 13, 13, 13, 13, - 12, 12, 15, 14, 12, 13, - 15, 14, 12, 12, 12, 12, - 15, 12, 12, 13, 14, 12, - 13, 13, 13, 14, 14, 13, - 13, 14, 13, 14, 14, 14, - 13, 14, 14, 13, 13, 13, - 12, 14, 13, 12, 12, 13, - 14, 12, 12, 16, 15, 15, - 13, 13, 13, 14, 14, 13, - 13, 12, 12, 14, 13, 13, - 12, 14, 14, 14, 12, 12, - 14, 14, 16, 13, 16, 14, - 14, 16, 14, 13, 14, 13, - 14, 14, 14, 13, 13, 16, - 13, 13, 11, 15, 15, 12, - 12, 13, 14, 15, 12, 11, - 13, 13, 11, 13, 11, 14, - 14, 14, 14, 11, 15, 14, - 13, 14, 14, 14, 14, 14, - 15, 15, 13, 11, 14, 13, - 12, 11, 12, 15, 15, 12, - 12, 14, 15, 11, 11, 13, - 14, 15, 12, 13, 13, 13, - 11, 13, 13, 15, 14, 12, - 14, 14, 13, 13, 14, 15, - 16, 16, 13, 13, 14, 16, - 14, 12, 12, 14, 11, 11, - 13, 15, 15, 12, 16, 14, - 14, 14, 15, 13, 14, 14, - 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 14, 13, - 15, 14, 12, 14, 15, 16, - 16, 13, 14, 15, 15, 14, - 16, 14, 14, 14, 14, 13, - 14, 16, 13, 13, 14, 14, - 12, 12, 12, 14, 12, 13, - 12, 14, 13, 12, 14, 15, - 15, 13, 13, 12, 13, 13, - 13, 13, 14, 13, 12, 13, - 13, 13, 13, 13, 12, 14, - 14, 12, 12, 12, 14, 13, - 13, 12, 12, 12, 14, 13, - 12, 14, 15, 12, 13, 12, - 12, 14, 13, 14, 15, 16, - 14, 15, 13, 16, 16, 13, - 13, 13, 14, 14, 13, 12, - 13, 14, 13, 13, 12, 14, - 13, 12, 11, 14, 14, 12, - 7, 10, 15, 16, 10, 7, - 12, 13, 7, 11, 11, 15, - 16, 12, 12, 14, 14, 13, - 16, 14, 16, 16, 16, 15, - 16, 16, 15, 15, 13, 14, - 14, 13, 12, 13, 16, 13, - 12, 9, 12, 13, 9, 9, - 13, 13, 9, 8, 10, 16, - 14, 10, 11, 13, 13, 10, - 13, 12, 15, 14, 12, 16, - 16, 15, 15, 14, 15, 15, - 16, 13, 12, 14, 14, 13, - 10, 13, 12, 11, 9, 11, - 16, 14, 11, 9, 12, 15, - 15, 11, 9, 13, 15, 9, - 11, 11, 14, 14, 12, 12, - 14, 13, 14, 14, 14, 15, - 15, 15, 14, 14, 16, 16, - 14, 12, 13, 13, 13, 11, - 11, 16, 13, 12, 14, 13, - 13, 10, 11, 15, 12, 12, - 16, 12, 16, 14, 11, 11, - 13, 14, 11, 14, 11, 15, - 15, 13, 14, 14, 16, 15, - 16, 15, 14, 15, 14, 14, - 16, 14, 12, 12, 14, 12, - 12, 12, 12, 16, 14, 12, - 15, 15, 16, 16, 14, 16, - 14, 13, 12, 14, 14, 15, - 16, 13, 12, 11, 14, 13, - 16, 12, 12, 16, 16, 14, - 14, 16, 16, 15, 14, 15, - 15, 14, 12, 13, 15, 14, - 15, 15, 14, 14, 16, 16, - 14, 16, 16, 14, 14, 14, - 14, 13, 14, 13, 16, 15, - 14, 14, 14, 14, 14, 16, - 15, 16, 14, 14, 16, 16, - 15, 16, 15, 13, 16, 16, - 15, 14, 14, 14, 15, 14, - 14, 15, 15, 14, 11, 15, - 15, 12, 10, 12, 16, 15, - 13, 11, 14, 13, 11, 13, - 13, 16, 15, 12, 15, 15, - 15, 14, 14, 16, 16, 15, - 14, 13, 14, 15, 14, 12, - 14, 13, 11, 13, 12, 14, - 15, 11, 9, 12, 15, 15, - 11, 9, 12, 13, 9, 10, - 12, 14, 14, 10, 12, 13, - 14, 12, 14, 15, 15, 16, - 15, 14, 14, 14, 15, 14, - 12, 13, 13, 13, 12, 11, - 13, 14, 12, 10, 12, 13, - 9, 7, 13, 13, 7, 6, - 9, 14, 15, 9, 10, 14, - 12, 9, 13, 13, 15, 16, - 12, 14, 16, 16, 15, 15, - 14, 14, 14, 13, 12, 13, - 14, 12, 11, 13, 13, 10, - 9, 10, 15, 14, 10, 6, - 12, 16, 15, 12, 10, 15, - 13, 10, 12, 13, 14, 15, - 12, 13, 13, 13, 13, 15, - 14, 15, 15, 15, 16, 15, - 16, 16, 15, 14, 15, 15, - 13, 11, 12, 16, 16, 12, - 9, 14, 14, 8, 9, 13, - 13, 8, 9, 11, 16, 14, - 11, 11, 13, 14, 11, 13, - 13, 14, 14, 13, 14, 15, - 15, 13, 13, 15, 15, 15, - 13, 12, 16, 16, 13, 10, - 13, 13, 10, 6, 11, 16, - 16, 10, 9, 12, 14, 16, - 11, 10, 13, 13, 10, 11, - 12, 16, 14, 12, 12, 15, - 14, 14, 15, 14, 16, 15, - 14, 14, 14, 16, 16, 15, - 12, 14, 15, 13, 11, 11, - 15, 14, 11, 9, 13, 14, - 9, 11, 14, 14, 11, 15, - 13, 15, 16, 12, 13, 14, - 13, 12, 13, 14, 15, 13, - 13, 14, 15, 16, 13, 16, - 16, 15, 15, 13, 13, 15, - 15, 14, 11, 14, 14, 13, - 10, 12, 15, 14, 12, 16, - 13, 16, 16, 14, 16, 14, - 15, 15, 13, 13, 16, 15, - 13, 15, 16, 14, 14, 16, - 16, 16, 15, 15, 15, 15, - 14, 16, 15, 13, 14, 15, - 15, 13, 13, 15, 16, 14, - 12, 14, 14, 16, 15, 14, - 15, 16, 13, 13, 14, 15, - 13, 13, 14, 14, 16, 14, - 14, 14, 15, 14, 16, 15, - 14, 15, 14, 15, 15, 16, - 12, 13, 13, 15, 12, 12, - 13, 13, 16, 16, 12, 13, - 13, 14, 14, 11, 13, 14, - 11, 15, 13, 14, 16, 12, - 12, 12, 13, 11, 13, 13, - 13, 15, 14, 13, 15, 15, - 14, 14, 16, 14, 14, 14, - 14, 15, 14, 11, 11, 13, - 13, 11, 14, 11, 16, 14, - 12, 9, 11, 14, 14, 11, - 10, 12, 13, 10, 11, 12, - 13, 16, 11, 12, 13, 14, - 16, 16, 14, 14, 16, 14, - 13, 15, 16, 14, 15, 13, - 14, 12, 11, 11, 11, 15, - 15, 11, 9, 13, 13, 9, - 9, 14, 14, 9, 9, 11, - 16, 14, 11, 11, 13, 12, - 11, 13, 12, 13, 15, 12, - 13, 13, 15, 14, 14, 15, - 16, 15, 13, 12, 16, 14, - 12, 10, 13, 13, 10, 8, - 10, 16, 14, 10, 13, 15, - 16, 13, 13, 13, 14, 14, - 12, 13, 14, 14, 13, 14, - 14, 14, 14, 14, 13, 14, - 16, 14, 14, 16, 15, 14, - 14, 14, 15, 15, 15, 13, - 15, 16, 13, 13, 14, 14, - 15, 12, 14, 14, 14, 13, - 13, 12, 13, 13, 12, 13, - 13, 13, 12, 13, 13, 14, - 13, 13, 14, 14, 14, 14, - 13, 13, 12, 14, 16, 14, - 14, 15, 14, 14, 13, 12, - 13, 13, 13, 11, 13, 14, - 12, 13, 15, 14, 12, 13, - 13, 14, 12, 12, 13, 14, - 13, 13, 13, 13, 15, 14, - 13, 14, 13, 13, 12, 12, - 13, 13, 12, 14, 13, 13, - 14, 13, 12, 14, 13, 13, - 12, 13, 12, 12, 12, 14, - 15, 14, 13, 16, 13, 15, - 15, 13, 14, 13, 14, 13, - 13, 14, 14, 13, 14, 15, - 13, 15, 16, 13, 13, 13, - 14, 16, 13, 14, 14, 14, - 13, 14, 13, 13, 13, 13, - 14, 14, 14, 13, 11, 14, - 14, 13, 11, 13, 16, 14, - 13, 11, 14, 13, 12, 14, - 13, 16, 14, 13, 13, 15, - 14, 13, 14, 13, 15, 14, - 13, 12, 13, 15, 14, 10, - 12, 14, 13, 10, 12, 15, - 14, 12, 12, 14, 16, 12, - 11, 12, 15, 14, 12, 12, - 13, 13, 11, 12, 12, 13, - 15, 13, 14, 15, 14, 15, - 15, 15, 11, 13, 13, 12, - 14, 13, 11, 11, 13, 13, - 11, 11, 12, 14, 16, 12, - 14, 13, 14, 16, 13, 13, - 13, 15, 13, 13, 14, 13, - 14, 14, 15, 14, 16, 14, - 14, 14, 15, 16, 14, 15, - 13, 15, 12, 12, 15, 14, - 11, 12, 13, 13, 14, 14, - 11, 12, 13, 15, 13, 12, - 14, 14, 13, 13, 12, 12, - 14, 12, 13, 12, 13, 13, - 15, 13, 12, 14, 13, 12, - 16, 13, 12, 13, 15, 12, - 14, 14, 14, 14, 12, 13, - 12, 14, 13, 12, 12, 12, - 13, 14, 12, 13, 13, 14, - 13, 13, 12, 13, 14, 11, - 12, 12, 13, 13, 12, 13, - 14, 15, 14, 14, 13, 14, - 14, 13, 13, 14, 15, 14, - 13, 14, 14, 13, 14, 13, - 12, 13, 13, 13, 12, 14, - 14, 11, 11, 12, 12, 13, - 12, 10, 13, 13, 10, 12, - 11, 12, 12, 11, 13, 13, - 14, 12, 16, 13, 14, 15, - 13, 13, 13, 15, 15, 13, - 13, 14, 16, 14, 13, 12, - 12, 12, 12, 11, 13, 13, - 10, 10, 14, 13, 10, 10, - 11, 11, 11, 10, 10, 12, - 13, 10, 13, 12, 11, 12, - 13, 12, 12, 12, 11, 11, - 12, 13, 12, 13, 13, 12, - 13, 13, 11, 12, 13, 11, - 10, 11, 11, 11, 10, 12, - 12, 13, 12, 12, 11, 13, - 12, 11, 11, 11, 12, 11, - 11, 12, 13, 13, 12, 14, - 11, 12, 14, 12, 12, 11, - 12, 13, 11, 12, 13, 13, - 13, 12, 11, 11, 13, 12, - 10, 13, 12, 11, 13, 15, - 15, 13, 13, 13, 13, 12, - 13, 13, 14, 13, 13, 14, - 14, 13, 13, 14, 11, 13, - 13, 13, 12, 11, 13, 13, - 14, 13, 12, 13, 15, 12, - 14, 13, 13, 13, 13, 15, - 13, 13, 14, 12, 16, 15, - 13, 9, 13, 13, 11, 10, - 12, 14, 14, 12, 11, 14, - 13, 12, 16, 13, 14, 15, - 13, 14, 13, 14, 16, 14, - 11, 12, 15, 12, 11, 11, - 15, 16, 11, 10, 12, 13, - 11, 10, 12, 16, 15, 12, - 11, 12, 13, 9, 10, 12, - 13, 15, 11, 12, 13, 13, - 16, 15, 14, 15, 16, 13, - 13, 14, 16, 13, 12, 12, - 13, 12, 12, 11, 12, 14, - 14, 12, 10, 12, 13, 10, - 13, 13, 14, 13, 13, 13, - 12, 13, 12, 13, 13, 13, - 13, 14, 14, 13, 13, 14, - 13, 13, 13, 11, 13, 12, - 11, 12, 13, 13, 13, 12, - 12, 12, 14, 13, 12, 12, - 12, 12, 13, 13, 11, 11, - 13, 12, 12, 10, 12, 13, - 11, 12, 11, 12, 12, 12, - 13, 13, 14, 12, 13, 12, - 14, 15, 12, 12, 11, 14, - 13, 11, 13, 14, 12, 13, - 11, 11, 12, 11, 10, 10, - 13, 13, 10, 10, 13, 13, - 10, 10, 10, 12, 11, 11, - 10, 12, 13, 11, 13, 12, - 13, 12, 12, 12, 12, 13, - 11, 11, 13, 12, 11, 14, - 13, 13, 12, 12, 11, 13, - 12, 11, 10, 11, 12, 11, - 10, 9, 12, 13, 9, 9, - 10, 10, 10, 10, 10, 12, - 13, 11, 13, 12, 12, 12, - 13, 11, 14, 12, 11, 10, - 11, 11, 10, 13, 13, 12, - 14, 12, 11, 13, 12, 11, - 9, 10, 10, 10, 10, 10, - 10, 10, 11, 10, 9, 12, - 12, 9, 10, 10, 10, 10, - 11, 11, 12, 13, 13, 11, - 11, 15, 14, 11, 10, 10, - 12, 16, 10, 12, 12, 14, - 12, 11, 10, 10, 10, 10, - 9, 13, 12, 9, 11, 13, - 13, 11, 10, 11, 11, 11, - 10, 10, 12, 12, 11, 13, - 11, 11, 13, 13, 11, 13, - 13, 11, 10, 11, 15, 10, - 13, 12, 12, 15, 12, 11, - 12, 13, 11, 11, 11, 11, - 10, 10, 13, 13, 14, 14, - 13, 13, 14, 13, 12, 13, - 13, 15, 13, 12, 13, 14, - 14, 13, 11, 12, 13, 15, - 12, 12, 11, 13, 16, 14, - 14, 14, 14, 14, 12, 13, - 13, 13, 12, 12, 14, 14, - 12, 9, 14, 14, 10, 9, - 11, 16, 14, 11, 16, 13, - 13, 10, 11, 12, 15, 14, - 12, 14, 14, 14, 13, 13, - 13, 16, 16, 11, 11, 16, - 15, 12, 9, 13, 14, 10, - 10, 11, 14, 15, 11, 11, - 13, 14, 10, 9, 11, 15, - 15, 11, 10, 13, 12, 9, - 11, 13, 15, 14, 11, 13, - 14, 13, 13, 13, 13, 14, - 13, 16, 13, 15, 13, 12, - 10, 13, 13, 10, 10, 11, - 13, 15, 11, 13, 12, 13, - 13, 13, 12, 13, 13, 12, - 13, 12, 13, 12, 13, 13, - 15, 14, 13, 11, 12, 14, - 14, 11, 12, 14, 16, 13, - 13, 13, 14, 13, 12, 13, - 12, 12, 13, 12, 12, 13, - 14, 12, 10, 13, 13, 11, - 10, 10, 12, 11, 11, 11, - 13, 12, 11, 13, 12, 13, - 12, 12, 11, 13, 12, 10, - 10, 13, 11, 11, 13, 13, - 12, 11, 12, 11, 12, 12, - 10, 10, 10, 11, 11, 11, - 9, 10, 11, 10, 11, 9, - 11, 12, 9, 10, 10, 10, - 10, 11, 12, 13, 14, 12, - 10, 11, 13, 13, 11, 10, - 10, 12, 12, 11, 13, 13, - 13, 12, 10, 11, 11, 10, - 10, 9, 12, 11, 8, -}; - -static const uint16_t on2avc_cb8_syms[ON2AVC_CB8_CODES] = { - 0x0000, 0x0002, 0x0004, 0x000C, 0x000E, 0x0011, - 0x0013, 0x001D, 0x001F, 0x0020, 0x0022, 0x0024, - 0x002C, 0x002E, 0x0031, 0x0033, 0x003D, 0x003F, - 0x0040, 0x0042, 0x0044, 0x004C, 0x004E, 0x00C0, - 0x00C2, 0x00C4, 0x00CC, 0x00CE, 0x00D1, 0x00D3, - 0x00DD, 0x00DF, 0x00E0, 0x00E2, 0x00E4, 0x00EC, - 0x00EE, 0x00F1, 0x00F3, 0x00FD, 0x00FF, 0x0101, - 0x0103, 0x010D, 0x010F, 0x0110, 0x0112, 0x0114, - 0x011C, 0x011E, 0x0121, 0x0123, 0x012D, 0x012F, - 0x0130, 0x0132, 0x0134, 0x013C, 0x013E, 0x0141, - 0x0143, 0x014D, 0x014F, 0x01C1, 0x01C3, 0x01CD, - 0x01CF, 0x01D0, 0x01D2, 0x01D4, 0x01DC, 0x01DE, - 0x01E1, 0x01E3, 0x01ED, 0x01EF, 0x01F0, 0x01F2, - 0x01F4, 0x01FC, 0x01FE, 0x0200, 0x0202, 0x0204, - 0x020C, 0x020E, 0x0211, 0x0213, 0x021D, 0x021F, - 0x0220, 0x0222, 0x0224, 0x022C, 0x022E, 0x0231, - 0x0233, 0x023D, 0x023F, 0x0240, 0x0242, 0x0244, - 0x024C, 0x024E, 0x02C0, 0x02C2, 0x02C4, 0x02CC, - 0x02CE, 0x02D1, 0x02D3, 0x02DD, 0x02DF, 0x02E0, - 0x02E2, 0x02E4, 0x02EC, 0x02EE, 0x02F1, 0x02F3, - 0x02FD, 0x02FF, 0x0301, 0x0303, 0x030D, 0x030F, - 0x0310, 0x0312, 0x0314, 0x031C, 0x031E, 0x0321, - 0x0323, 0x032D, 0x032F, 0x0330, 0x0332, 0x0334, - 0x033C, 0x033E, 0x0341, 0x0343, 0x034D, 0x034F, - 0x03C1, 0x03C3, 0x03CD, 0x03CF, 0x03D0, 0x03D2, - 0x03D4, 0x03DC, 0x03DE, 0x03E1, 0x03E3, 0x03ED, - 0x03EF, 0x03F0, 0x03F2, 0x03F4, 0x03FC, 0x03FE, - 0x0400, 0x0402, 0x0404, 0x040C, 0x040E, 0x0411, - 0x0413, 0x041D, 0x041F, 0x0420, 0x0422, 0x0424, - 0x042C, 0x042E, 0x0431, 0x0433, 0x043D, 0x043F, - 0x0440, 0x0442, 0x0444, 0x044C, 0x044E, 0x04C0, - 0x04C2, 0x04C4, 0x04CC, 0x04CE, 0x04D1, 0x04D3, - 0x04DD, 0x04DF, 0x04E0, 0x04E2, 0x04E4, 0x04EC, - 0x04EE, 0x04F1, 0x04F3, 0x04FD, 0x04FF, 0x0C00, - 0x0C02, 0x0C04, 0x0C0C, 0x0C0E, 0x0C11, 0x0C13, - 0x0C1D, 0x0C1F, 0x0C20, 0x0C22, 0x0C24, 0x0C2C, - 0x0C2E, 0x0C31, 0x0C33, 0x0C3D, 0x0C3F, 0x0C40, - 0x0C42, 0x0C44, 0x0C4C, 0x0C4E, 0x0CC0, 0x0CC2, - 0x0CC4, 0x0CCC, 0x0CCE, 0x0CD1, 0x0CD3, 0x0CDD, - 0x0CDF, 0x0CE0, 0x0CE2, 0x0CE4, 0x0CEC, 0x0CEE, - 0x0CF1, 0x0CF3, 0x0CFD, 0x0CFF, 0x0D01, 0x0D03, - 0x0D0D, 0x0D0F, 0x0D10, 0x0D12, 0x0D14, 0x0D1C, - 0x0D1E, 0x0D21, 0x0D23, 0x0D2D, 0x0D2F, 0x0D30, - 0x0D32, 0x0D34, 0x0D3C, 0x0D3E, 0x0D41, 0x0D43, - 0x0D4D, 0x0D4F, 0x0DC1, 0x0DC3, 0x0DCD, 0x0DCF, - 0x0DD0, 0x0DD2, 0x0DD4, 0x0DDC, 0x0DDE, 0x0DE1, - 0x0DE3, 0x0DED, 0x0DEF, 0x0DF0, 0x0DF2, 0x0DF4, - 0x0DFC, 0x0DFE, 0x0E00, 0x0E02, 0x0E04, 0x0E0C, - 0x0E0E, 0x0E11, 0x0E13, 0x0E1D, 0x0E1F, 0x0E20, - 0x0E22, 0x0E24, 0x0E2C, 0x0E2E, 0x0E31, 0x0E33, - 0x0E3D, 0x0E3F, 0x0E40, 0x0E42, 0x0E44, 0x0E4C, - 0x0E4E, 0x0EC0, 0x0EC2, 0x0EC4, 0x0ECC, 0x0ECE, - 0x0ED1, 0x0ED3, 0x0EDD, 0x0EDF, 0x0EE0, 0x0EE2, - 0x0EE4, 0x0EEC, 0x0EEE, 0x0EF1, 0x0EF3, 0x0EFD, - 0x0EFF, 0x0F01, 0x0F03, 0x0F0D, 0x0F0F, 0x0F10, - 0x0F12, 0x0F14, 0x0F1C, 0x0F1E, 0x0F21, 0x0F23, - 0x0F2D, 0x0F2F, 0x0F30, 0x0F32, 0x0F34, 0x0F3C, - 0x0F3E, 0x0F41, 0x0F43, 0x0F4D, 0x0F4F, 0x0FC1, - 0x0FC3, 0x0FCD, 0x0FCF, 0x0FD0, 0x0FD2, 0x0FD4, - 0x0FDC, 0x0FDE, 0x0FE1, 0x0FE3, 0x0FED, 0x0FEF, - 0x0FF0, 0x0FF2, 0x0FF4, 0x0FFC, 0x0FFE, 0x1001, - 0x1003, 0x100D, 0x100F, 0x1010, 0x1012, 0x1014, - 0x101C, 0x101E, 0x1021, 0x1023, 0x102D, 0x102F, - 0x1030, 0x1032, 0x1034, 0x103C, 0x103E, 0x1041, - 0x1043, 0x104D, 0x104F, 0x10C1, 0x10C3, 0x10CD, - 0x10CF, 0x10D0, 0x10D2, 0x10D4, 0x10DC, 0x10DE, - 0x10E1, 0x10E3, 0x10ED, 0x10EF, 0x10F0, 0x10F2, - 0x10F4, 0x10FC, 0x10FE, 0x1100, 0x1102, 0x1104, - 0x110C, 0x110E, 0x1111, 0x1113, 0x111D, 0x111F, - 0x1120, 0x1122, 0x1124, 0x112C, 0x112E, 0x1131, - 0x1133, 0x113D, 0x113F, 0x1140, 0x1142, 0x1144, - 0x114C, 0x114E, 0x11C0, 0x11C2, 0x11C4, 0x11CC, - 0x11CE, 0x11D1, 0x11D3, 0x11DD, 0x11DF, 0x11E0, - 0x11E2, 0x11E4, 0x11EC, 0x11EE, 0x11F1, 0x11F3, - 0x11FD, 0x11FF, 0x1201, 0x1203, 0x120D, 0x120F, - 0x1210, 0x1212, 0x1214, 0x121C, 0x121E, 0x1221, - 0x1223, 0x122D, 0x122F, 0x1230, 0x1232, 0x1234, - 0x123C, 0x123E, 0x1241, 0x1243, 0x124D, 0x124F, - 0x12C1, 0x12C3, 0x12CD, 0x12CF, 0x12D0, 0x12D2, - 0x12D4, 0x12DC, 0x12DE, 0x12E1, 0x12E3, 0x12ED, - 0x12EF, 0x12F0, 0x12F2, 0x12F4, 0x12FC, 0x12FE, - 0x1300, 0x1302, 0x1304, 0x130C, 0x130E, 0x1311, - 0x1313, 0x131D, 0x131F, 0x1320, 0x1322, 0x1324, - 0x132C, 0x132E, 0x1331, 0x1333, 0x133D, 0x133F, - 0x1340, 0x1342, 0x1344, 0x134C, 0x134E, 0x13C0, - 0x13C2, 0x13C4, 0x13CC, 0x13CE, 0x13D1, 0x13D3, - 0x13DD, 0x13DF, 0x13E0, 0x13E2, 0x13E4, 0x13EC, - 0x13EE, 0x13F1, 0x13F3, 0x13FD, 0x13FF, 0x1401, - 0x1403, 0x140D, 0x140F, 0x1410, 0x1412, 0x1414, - 0x141C, 0x141E, 0x1421, 0x1423, 0x142D, 0x142F, - 0x1430, 0x1432, 0x1434, 0x143C, 0x143E, 0x1441, - 0x1443, 0x144D, 0x144F, 0x14C1, 0x14C3, 0x14CD, - 0x14CF, 0x14D0, 0x14D2, 0x14D4, 0x14DC, 0x14DE, - 0x14E1, 0x14E3, 0x14ED, 0x14EF, 0x14F0, 0x14F2, - 0x14F4, 0x14FC, 0x14FE, 0x1C01, 0x1C03, 0x1C0D, - 0x1C0F, 0x1C10, 0x1C12, 0x1C14, 0x1C1C, 0x1C1E, - 0x1C21, 0x1C23, 0x1C2D, 0x1C2F, 0x1C30, 0x1C32, - 0x1C34, 0x1C3C, 0x1C3E, 0x1C41, 0x1C43, 0x1C4D, - 0x1C4F, 0x1CC1, 0x1CC3, 0x1CCD, 0x1CCF, 0x1CD0, - 0x1CD2, 0x1CD4, 0x1CDC, 0x1CDE, 0x1CE1, 0x1CE3, - 0x1CED, 0x1CEF, 0x1CF0, 0x1CF2, 0x1CF4, 0x1CFC, - 0x1CFE, 0x1D00, 0x1D02, 0x1D04, 0x1D0C, 0x1D0E, - 0x1D11, 0x1D13, 0x1D1D, 0x1D1F, 0x1D20, 0x1D22, - 0x1D24, 0x1D2C, 0x1D2E, 0x1D31, 0x1D33, 0x1D3D, - 0x1D3F, 0x1D40, 0x1D42, 0x1D44, 0x1D4C, 0x1D4E, - 0x1DC0, 0x1DC2, 0x1DC4, 0x1DCC, 0x1DCE, 0x1DD1, - 0x1DD3, 0x1DDD, 0x1DDF, 0x1DE0, 0x1DE2, 0x1DE4, - 0x1DEC, 0x1DEE, 0x1DF1, 0x1DF3, 0x1DFD, 0x1DFF, - 0x1E01, 0x1E03, 0x1E0D, 0x1E0F, 0x1E10, 0x1E12, - 0x1E14, 0x1E1C, 0x1E1E, 0x1E21, 0x1E23, 0x1E2D, - 0x1E2F, 0x1E30, 0x1E32, 0x1E34, 0x1E3C, 0x1E3E, - 0x1E41, 0x1E43, 0x1E4D, 0x1E4F, 0x1EC1, 0x1EC3, - 0x1ECD, 0x1ECF, 0x1ED0, 0x1ED2, 0x1ED4, 0x1EDC, - 0x1EDE, 0x1EE1, 0x1EE3, 0x1EED, 0x1EEF, 0x1EF0, - 0x1EF2, 0x1EF4, 0x1EFC, 0x1EFE, 0x1F00, 0x1F02, - 0x1F04, 0x1F0C, 0x1F0E, 0x1F11, 0x1F13, 0x1F1D, - 0x1F1F, 0x1F20, 0x1F22, 0x1F24, 0x1F2C, 0x1F2E, - 0x1F31, 0x1F33, 0x1F3D, 0x1F3F, 0x1F40, 0x1F42, - 0x1F44, 0x1F4C, 0x1F4E, 0x1FC0, 0x1FC2, 0x1FC4, - 0x1FCC, 0x1FCE, 0x1FD1, 0x1FD3, 0x1FDD, 0x1FDF, - 0x1FE0, 0x1FE2, 0x1FE4, 0x1FEC, 0x1FEE, 0x1FF1, - 0x1FF3, 0x1FFD, 0x1FFF, 0x2000, 0x2002, 0x2004, - 0x200C, 0x200E, 0x2011, 0x2013, 0x201D, 0x201F, - 0x2020, 0x2022, 0x2024, 0x202C, 0x202E, 0x2031, - 0x2033, 0x203D, 0x203F, 0x2040, 0x2042, 0x2044, - 0x204C, 0x204E, 0x20C0, 0x20C2, 0x20C4, 0x20CC, - 0x20CE, 0x20D1, 0x20D3, 0x20DD, 0x20DF, 0x20E0, - 0x20E2, 0x20E4, 0x20EC, 0x20EE, 0x20F1, 0x20F3, - 0x20FD, 0x20FF, 0x2101, 0x2103, 0x210D, 0x210F, - 0x2110, 0x2112, 0x2114, 0x211C, 0x211E, 0x2121, - 0x2123, 0x212D, 0x212F, 0x2130, 0x2132, 0x2134, - 0x213C, 0x213E, 0x2141, 0x2143, 0x214D, 0x214F, - 0x21C1, 0x21C3, 0x21CD, 0x21CF, 0x21D0, 0x21D2, - 0x21D4, 0x21DC, 0x21DE, 0x21E1, 0x21E3, 0x21ED, - 0x21EF, 0x21F0, 0x21F2, 0x21F4, 0x21FC, 0x21FE, - 0x2200, 0x2202, 0x2204, 0x220C, 0x220E, 0x2211, - 0x2213, 0x221D, 0x221F, 0x2220, 0x2222, 0x2224, - 0x222C, 0x222E, 0x2231, 0x2233, 0x223D, 0x223F, - 0x2240, 0x2242, 0x2244, 0x224C, 0x224E, 0x22C0, - 0x22C2, 0x22C4, 0x22CC, 0x22CE, 0x22D1, 0x22D3, - 0x22DD, 0x22DF, 0x22E0, 0x22E2, 0x22E4, 0x22EC, - 0x22EE, 0x22F1, 0x22F3, 0x22FD, 0x22FF, 0x2301, - 0x2303, 0x230D, 0x230F, 0x2310, 0x2312, 0x2314, - 0x231C, 0x231E, 0x2321, 0x2323, 0x232D, 0x232F, - 0x2330, 0x2332, 0x2334, 0x233C, 0x233E, 0x2341, - 0x2343, 0x234D, 0x234F, 0x23C1, 0x23C3, 0x23CD, - 0x23CF, 0x23D0, 0x23D2, 0x23D4, 0x23DC, 0x23DE, - 0x23E1, 0x23E3, 0x23ED, 0x23EF, 0x23F0, 0x23F2, - 0x23F4, 0x23FC, 0x23FE, 0x2400, 0x2402, 0x2404, - 0x240C, 0x240E, 0x2411, 0x2413, 0x241D, 0x241F, - 0x2420, 0x2422, 0x2424, 0x242C, 0x242E, 0x2431, - 0x2433, 0x243D, 0x243F, 0x2440, 0x2442, 0x2444, - 0x244C, 0x244E, 0x24C0, 0x24C2, 0x24C4, 0x24CC, - 0x24CE, 0x24D1, 0x24D3, 0x24DD, 0x24DF, 0x24E0, - 0x24E2, 0x24E4, 0x24EC, 0x24EE, 0x24F1, 0x24F3, - 0x24FD, 0x24FF, 0x2C00, 0x2C02, 0x2C04, 0x2C0C, - 0x2C0E, 0x2C11, 0x2C13, 0x2C1D, 0x2C1F, 0x2C20, - 0x2C22, 0x2C24, 0x2C2C, 0x2C2E, 0x2C31, 0x2C33, - 0x2C3D, 0x2C3F, 0x2C40, 0x2C42, 0x2C44, 0x2C4C, - 0x2C4E, 0x2CC0, 0x2CC2, 0x2CC4, 0x2CCC, 0x2CCE, - 0x2CD1, 0x2CD3, 0x2CDD, 0x2CDF, 0x2CE0, 0x2CE2, - 0x2CE4, 0x2CEC, 0x2CEE, 0x2CF1, 0x2CF3, 0x2CFD, - 0x2CFF, 0x2D01, 0x2D03, 0x2D0D, 0x2D0F, 0x2D10, - 0x2D12, 0x2D14, 0x2D1C, 0x2D1E, 0x2D21, 0x2D23, - 0x2D2D, 0x2D2F, 0x2D30, 0x2D32, 0x2D34, 0x2D3C, - 0x2D3E, 0x2D41, 0x2D43, 0x2D4D, 0x2D4F, 0x2DC1, - 0x2DC3, 0x2DCD, 0x2DCF, 0x2DD0, 0x2DD2, 0x2DD4, - 0x2DDC, 0x2DDE, 0x2DE1, 0x2DE3, 0x2DED, 0x2DEF, - 0x2DF0, 0x2DF2, 0x2DF4, 0x2DFC, 0x2DFE, 0x2E00, - 0x2E02, 0x2E04, 0x2E0C, 0x2E0E, 0x2E11, 0x2E13, - 0x2E1D, 0x2E1F, 0x2E20, 0x2E22, 0x2E24, 0x2E2C, - 0x2E2E, 0x2E31, 0x2E33, 0x2E3D, 0x2E3F, 0x2E40, - 0x2E42, 0x2E44, 0x2E4C, 0x2E4E, 0x2EC0, 0x2EC2, - 0x2EC4, 0x2ECC, 0x2ECE, 0x2ED1, 0x2ED3, 0x2EDD, - 0x2EDF, 0x2EE0, 0x2EE2, 0x2EE4, 0x2EEC, 0x2EEE, - 0x2EF1, 0x2EF3, 0x2EFD, 0x2EFF, 0x2F01, 0x2F03, - 0x2F0D, 0x2F0F, 0x2F10, 0x2F12, 0x2F14, 0x2F1C, - 0x2F1E, 0x2F21, 0x2F23, 0x2F2D, 0x2F2F, 0x2F30, - 0x2F32, 0x2F34, 0x2F3C, 0x2F3E, 0x2F41, 0x2F43, - 0x2F4D, 0x2F4F, 0x2FC1, 0x2FC3, 0x2FCD, 0x2FCF, - 0x2FD0, 0x2FD2, 0x2FD4, 0x2FDC, 0x2FDE, 0x2FE1, - 0x2FE3, 0x2FED, 0x2FEF, 0x2FF0, 0x2FF2, 0x2FF4, - 0x2FFC, 0x2FFE, 0x3001, 0x3003, 0x300D, 0x300F, - 0x3010, 0x3012, 0x3014, 0x301C, 0x301E, 0x3021, - 0x3023, 0x302D, 0x302F, 0x3030, 0x3032, 0x3034, - 0x303C, 0x303E, 0x3041, 0x3043, 0x304D, 0x304F, - 0x30C1, 0x30C3, 0x30CD, 0x30CF, 0x30D0, 0x30D2, - 0x30D4, 0x30DC, 0x30DE, 0x30E1, 0x30E3, 0x30ED, - 0x30EF, 0x30F0, 0x30F2, 0x30F4, 0x30FC, 0x30FE, - 0x3100, 0x3102, 0x3104, 0x310C, 0x310E, 0x3111, - 0x3113, 0x311D, 0x311F, 0x3120, 0x3122, 0x3124, - 0x312C, 0x312E, 0x3131, 0x3133, 0x313D, 0x313F, - 0x3140, 0x3142, 0x3144, 0x314C, 0x314E, 0x31C0, - 0x31C2, 0x31C4, 0x31CC, 0x31CE, 0x31D1, 0x31D3, - 0x31DD, 0x31DF, 0x31E0, 0x31E2, 0x31E4, 0x31EC, - 0x31EE, 0x31F1, 0x31F3, 0x31FD, 0x31FF, 0x3201, - 0x3203, 0x320D, 0x320F, 0x3210, 0x3212, 0x3214, - 0x321C, 0x321E, 0x3221, 0x3223, 0x322D, 0x322F, - 0x3230, 0x3232, 0x3234, 0x323C, 0x323E, 0x3241, - 0x3243, 0x324D, 0x324F, 0x32C1, 0x32C3, 0x32CD, - 0x32CF, 0x32D0, 0x32D2, 0x32D4, 0x32DC, 0x32DE, - 0x32E1, 0x32E3, 0x32ED, 0x32EF, 0x32F0, 0x32F2, - 0x32F4, 0x32FC, 0x32FE, 0x3300, 0x3302, 0x3304, - 0x330C, 0x330E, 0x3311, 0x3313, 0x331D, 0x331F, - 0x3320, 0x3322, 0x3324, 0x332C, 0x332E, 0x3331, - 0x3333, 0x333D, 0x333F, 0x3340, 0x3342, 0x3344, - 0x334C, 0x334E, 0x33C0, 0x33C2, 0x33C4, 0x33CC, - 0x33CE, 0x33D1, 0x33D3, 0x33DD, 0x33DF, 0x33E0, - 0x33E2, 0x33E4, 0x33EC, 0x33EE, 0x33F1, 0x33F3, - 0x33FD, 0x33FF, 0x3401, 0x3403, 0x340D, 0x340F, - 0x3410, 0x3412, 0x3414, 0x341C, 0x341E, 0x3421, - 0x3423, 0x342D, 0x342F, 0x3430, 0x3432, 0x3434, - 0x343C, 0x343E, 0x3441, 0x3443, 0x344D, 0x344F, - 0x34C1, 0x34C3, 0x34CD, 0x34CF, 0x34D0, 0x34D2, - 0x34D4, 0x34DC, 0x34DE, 0x34E1, 0x34E3, 0x34ED, - 0x34EF, 0x34F0, 0x34F2, 0x34F4, 0x34FC, 0x34FE, - 0x3C01, 0x3C03, 0x3C0D, 0x3C0F, 0x3C10, 0x3C12, - 0x3C14, 0x3C1C, 0x3C1E, 0x3C21, 0x3C23, 0x3C2D, - 0x3C2F, 0x3C30, 0x3C32, 0x3C34, 0x3C3C, 0x3C3E, - 0x3C41, 0x3C43, 0x3C4D, 0x3C4F, 0x3CC1, 0x3CC3, - 0x3CCD, 0x3CCF, 0x3CD0, 0x3CD2, 0x3CD4, 0x3CDC, - 0x3CDE, 0x3CE1, 0x3CE3, 0x3CED, 0x3CEF, 0x3CF0, - 0x3CF2, 0x3CF4, 0x3CFC, 0x3CFE, 0x3D00, 0x3D02, - 0x3D04, 0x3D0C, 0x3D0E, 0x3D11, 0x3D13, 0x3D1D, - 0x3D1F, 0x3D20, 0x3D22, 0x3D24, 0x3D2C, 0x3D2E, - 0x3D31, 0x3D33, 0x3D3D, 0x3D3F, 0x3D40, 0x3D42, - 0x3D44, 0x3D4C, 0x3D4E, 0x3DC0, 0x3DC2, 0x3DC4, - 0x3DCC, 0x3DCE, 0x3DD1, 0x3DD3, 0x3DDD, 0x3DDF, - 0x3DE0, 0x3DE2, 0x3DE4, 0x3DEC, 0x3DEE, 0x3DF1, - 0x3DF3, 0x3DFD, 0x3DFF, 0x3E01, 0x3E03, 0x3E0D, - 0x3E0F, 0x3E10, 0x3E12, 0x3E14, 0x3E1C, 0x3E1E, - 0x3E21, 0x3E23, 0x3E2D, 0x3E2F, 0x3E30, 0x3E32, - 0x3E34, 0x3E3C, 0x3E3E, 0x3E41, 0x3E43, 0x3E4D, - 0x3E4F, 0x3EC1, 0x3EC3, 0x3ECD, 0x3ECF, 0x3ED0, - 0x3ED2, 0x3ED4, 0x3EDC, 0x3EDE, 0x3EE1, 0x3EE3, - 0x3EED, 0x3EEF, 0x3EF0, 0x3EF2, 0x3EF4, 0x3EFC, - 0x3EFE, 0x3F00, 0x3F02, 0x3F04, 0x3F0C, 0x3F0E, - 0x3F11, 0x3F13, 0x3F1D, 0x3F1F, 0x3F20, 0x3F22, - 0x3F24, 0x3F2C, 0x3F2E, 0x3F31, 0x3F33, 0x3F3D, - 0x3F3F, 0x3F40, 0x3F42, 0x3F44, 0x3F4C, 0x3F4E, - 0x3FC0, 0x3FC2, 0x3FC4, 0x3FCC, 0x3FCE, 0x3FD1, - 0x3FD3, 0x3FDD, 0x3FDF, 0x3FE0, 0x3FE2, 0x3FE4, - 0x3FEC, 0x3FEE, 0x3FF1, 0x3FF3, 0x3FFD, 0x3FFF, - 0x4000, 0x4002, 0x4004, 0x400C, 0x400E, 0x4011, - 0x4013, 0x401D, 0x401F, 0x4020, 0x4022, 0x4024, - 0x402C, 0x402E, 0x4031, 0x4033, 0x403D, 0x403F, - 0x4040, 0x4042, 0x4044, 0x404C, 0x404E, 0x40C0, - 0x40C2, 0x40C4, 0x40CC, 0x40CE, 0x40D1, 0x40D3, - 0x40DD, 0x40DF, 0x40E0, 0x40E2, 0x40E4, 0x40EC, - 0x40EE, 0x40F1, 0x40F3, 0x40FD, 0x40FF, 0x4101, - 0x4103, 0x410D, 0x410F, 0x4110, 0x4112, 0x4114, - 0x411C, 0x411E, 0x4121, 0x4123, 0x412D, 0x412F, - 0x4130, 0x4132, 0x4134, 0x413C, 0x413E, 0x4141, - 0x4143, 0x414D, 0x414F, 0x41C1, 0x41C3, 0x41CD, - 0x41CF, 0x41D0, 0x41D2, 0x41D4, 0x41DC, 0x41DE, - 0x41E1, 0x41E3, 0x41ED, 0x41EF, 0x41F0, 0x41F2, - 0x41F4, 0x41FC, 0x41FE, 0x4200, 0x4202, 0x4204, - 0x420C, 0x420E, 0x4211, 0x4213, 0x421D, 0x421F, - 0x4220, 0x4222, 0x4224, 0x422C, 0x422E, 0x4231, - 0x4233, 0x423D, 0x423F, 0x4240, 0x4242, 0x4244, - 0x424C, 0x424E, 0x42C0, 0x42C2, 0x42C4, 0x42CC, - 0x42CE, 0x42D1, 0x42D3, 0x42DD, 0x42DF, 0x42E0, - 0x42E2, 0x42E4, 0x42EC, 0x42EE, 0x42F1, 0x42F3, - 0x42FD, 0x42FF, 0x4301, 0x4303, 0x430D, 0x430F, - 0x4310, 0x4312, 0x4314, 0x431C, 0x431E, 0x4321, - 0x4323, 0x432D, 0x432F, 0x4330, 0x4332, 0x4334, - 0x433C, 0x433E, 0x4341, 0x4343, 0x434D, 0x434F, - 0x43C1, 0x43C3, 0x43CD, 0x43CF, 0x43D0, 0x43D2, - 0x43D4, 0x43DC, 0x43DE, 0x43E1, 0x43E3, 0x43ED, - 0x43EF, 0x43F0, 0x43F2, 0x43F4, 0x43FC, 0x43FE, - 0x4400, 0x4402, 0x4404, 0x440C, 0x440E, 0x4411, - 0x4413, 0x441D, 0x441F, 0x4420, 0x4422, 0x4424, - 0x442C, 0x442E, 0x4431, 0x4433, 0x443D, 0x443F, - 0x4440, 0x4442, 0x4444, 0x444C, 0x444E, 0x44C0, - 0x44C2, 0x44C4, 0x44CC, 0x44CE, 0x44D1, 0x44D3, - 0x44DD, 0x44DF, 0x44E0, 0x44E2, 0x44E4, 0x44EC, - 0x44EE, 0x44F1, 0x44F3, 0x44FD, 0x44FF, 0x4C00, - 0x4C02, 0x4C04, 0x4C0C, 0x4C0E, 0x4C11, 0x4C13, - 0x4C1D, 0x4C1F, 0x4C20, 0x4C22, 0x4C24, 0x4C2C, - 0x4C2E, 0x4C31, 0x4C33, 0x4C3D, 0x4C3F, 0x4C40, - 0x4C42, 0x4C44, 0x4C4C, 0x4C4E, 0x4CC0, 0x4CC2, - 0x4CC4, 0x4CCC, 0x4CCE, 0x4CD1, 0x4CD3, 0x4CDD, - 0x4CDF, 0x4CE0, 0x4CE2, 0x4CE4, 0x4CEC, 0x4CEE, - 0x4CF1, 0x4CF3, 0x4CFD, 0x4CFF, 0x4D01, 0x4D03, - 0x4D0D, 0x4D0F, 0x4D10, 0x4D12, 0x4D14, 0x4D1C, - 0x4D1E, 0x4D21, 0x4D23, 0x4D2D, 0x4D2F, 0x4D30, - 0x4D32, 0x4D34, 0x4D3C, 0x4D3E, 0x4D41, 0x4D43, - 0x4D4D, 0x4D4F, 0x4DC1, 0x4DC3, 0x4DCD, 0x4DCF, - 0x4DD0, 0x4DD2, 0x4DD4, 0x4DDC, 0x4DDE, 0x4DE1, - 0x4DE3, 0x4DED, 0x4DEF, 0x4DF0, 0x4DF2, 0x4DF4, - 0x4DFC, 0x4DFE, 0x4E00, 0x4E02, 0x4E04, 0x4E0C, - 0x4E0E, 0x4E11, 0x4E13, 0x4E1D, 0x4E1F, 0x4E20, - 0x4E22, 0x4E24, 0x4E2C, 0x4E2E, 0x4E31, 0x4E33, - 0x4E3D, 0x4E3F, 0x4E40, 0x4E42, 0x4E44, 0x4E4C, - 0x4E4E, 0x4EC0, 0x4EC2, 0x4EC4, 0x4ECC, 0x4ECE, - 0x4ED1, 0x4ED3, 0x4EDD, 0x4EDF, 0x4EE0, 0x4EE2, - 0x4EE4, 0x4EEC, 0x4EEE, 0x4EF1, 0x4EF3, 0x4EFD, - 0x4EFF, 0x4F01, 0x4F03, 0x4F0D, 0x4F0F, 0x4F10, - 0x4F12, 0x4F14, 0x4F1C, 0x4F1E, 0x4F21, 0x4F23, - 0x4F2D, 0x4F2F, 0x4F30, 0x4F32, 0x4F34, 0x4F3C, - 0x4F3E, 0x4F41, 0x4F43, 0x4F4D, 0x4F4F, 0x4FC1, - 0x4FC3, 0x4FCD, 0x4FCF, 0x4FD0, 0x4FD2, 0x4FD4, - 0x4FDC, 0x4FDE, 0x4FE1, 0x4FE3, 0x4FED, 0x4FEF, - 0x4FF0, 0x4FF2, 0x4FF4, 0x4FFC, 0x4FFE, 0xC000, - 0xC002, 0xC004, 0xC00C, 0xC00E, 0xC011, 0xC013, - 0xC01D, 0xC01F, 0xC020, 0xC022, 0xC024, 0xC02C, - 0xC02E, 0xC031, 0xC033, 0xC03D, 0xC03F, 0xC040, - 0xC042, 0xC044, 0xC04C, 0xC04E, 0xC0C0, 0xC0C2, - 0xC0C4, 0xC0CC, 0xC0CE, 0xC0D1, 0xC0D3, 0xC0DD, - 0xC0DF, 0xC0E0, 0xC0E2, 0xC0E4, 0xC0EC, 0xC0EE, - 0xC0F1, 0xC0F3, 0xC0FD, 0xC0FF, 0xC101, 0xC103, - 0xC10D, 0xC10F, 0xC110, 0xC112, 0xC114, 0xC11C, - 0xC11E, 0xC121, 0xC123, 0xC12D, 0xC12F, 0xC130, - 0xC132, 0xC134, 0xC13C, 0xC13E, 0xC141, 0xC143, - 0xC14D, 0xC14F, 0xC1C1, 0xC1C3, 0xC1CD, 0xC1CF, - 0xC1D0, 0xC1D2, 0xC1D4, 0xC1DC, 0xC1DE, 0xC1E1, - 0xC1E3, 0xC1ED, 0xC1EF, 0xC1F0, 0xC1F2, 0xC1F4, - 0xC1FC, 0xC1FE, 0xC200, 0xC202, 0xC204, 0xC20C, - 0xC20E, 0xC211, 0xC213, 0xC21D, 0xC21F, 0xC220, - 0xC222, 0xC224, 0xC22C, 0xC22E, 0xC231, 0xC233, - 0xC23D, 0xC23F, 0xC240, 0xC242, 0xC244, 0xC24C, - 0xC24E, 0xC2C0, 0xC2C2, 0xC2C4, 0xC2CC, 0xC2CE, - 0xC2D1, 0xC2D3, 0xC2DD, 0xC2DF, 0xC2E0, 0xC2E2, - 0xC2E4, 0xC2EC, 0xC2EE, 0xC2F1, 0xC2F3, 0xC2FD, - 0xC2FF, 0xC301, 0xC303, 0xC30D, 0xC30F, 0xC310, - 0xC312, 0xC314, 0xC31C, 0xC31E, 0xC321, 0xC323, - 0xC32D, 0xC32F, 0xC330, 0xC332, 0xC334, 0xC33C, - 0xC33E, 0xC341, 0xC343, 0xC34D, 0xC34F, 0xC3C1, - 0xC3C3, 0xC3CD, 0xC3CF, 0xC3D0, 0xC3D2, 0xC3D4, - 0xC3DC, 0xC3DE, 0xC3E1, 0xC3E3, 0xC3ED, 0xC3EF, - 0xC3F0, 0xC3F2, 0xC3F4, 0xC3FC, 0xC3FE, 0xC400, - 0xC402, 0xC404, 0xC40C, 0xC40E, 0xC411, 0xC413, - 0xC41D, 0xC41F, 0xC420, 0xC422, 0xC424, 0xC42C, - 0xC42E, 0xC431, 0xC433, 0xC43D, 0xC43F, 0xC440, - 0xC442, 0xC444, 0xC44C, 0xC44E, 0xC4C0, 0xC4C2, - 0xC4C4, 0xC4CC, 0xC4CE, 0xC4D1, 0xC4D3, 0xC4DD, - 0xC4DF, 0xC4E0, 0xC4E2, 0xC4E4, 0xC4EC, 0xC4EE, - 0xC4F1, 0xC4F3, 0xC4FD, 0xC4FF, 0xCC00, 0xCC02, - 0xCC04, 0xCC0C, 0xCC0E, 0xCC11, 0xCC13, 0xCC1D, - 0xCC1F, 0xCC20, 0xCC22, 0xCC24, 0xCC2C, 0xCC2E, - 0xCC31, 0xCC33, 0xCC3D, 0xCC3F, 0xCC40, 0xCC42, - 0xCC44, 0xCC4C, 0xCC4E, 0xCCC0, 0xCCC2, 0xCCC4, - 0xCCCC, 0xCCCE, 0xCCD1, 0xCCD3, 0xCCDD, 0xCCDF, - 0xCCE0, 0xCCE2, 0xCCE4, 0xCCEC, 0xCCEE, 0xCCF1, - 0xCCF3, 0xCCFD, 0xCCFF, 0xCD01, 0xCD03, 0xCD0D, - 0xCD0F, 0xCD10, 0xCD12, 0xCD14, 0xCD1C, 0xCD1E, - 0xCD21, 0xCD23, 0xCD2D, 0xCD2F, 0xCD30, 0xCD32, - 0xCD34, 0xCD3C, 0xCD3E, 0xCD41, 0xCD43, 0xCD4D, - 0xCD4F, 0xCDC1, 0xCDC3, 0xCDCD, 0xCDCF, 0xCDD0, - 0xCDD2, 0xCDD4, 0xCDDC, 0xCDDE, 0xCDE1, 0xCDE3, - 0xCDED, 0xCDEF, 0xCDF0, 0xCDF2, 0xCDF4, 0xCDFC, - 0xCDFE, 0xCE00, 0xCE02, 0xCE04, 0xCE0C, 0xCE0E, - 0xCE11, 0xCE13, 0xCE1D, 0xCE1F, 0xCE20, 0xCE22, - 0xCE24, 0xCE2C, 0xCE2E, 0xCE31, 0xCE33, 0xCE3D, - 0xCE3F, 0xCE40, 0xCE42, 0xCE44, 0xCE4C, 0xCE4E, - 0xCEC0, 0xCEC2, 0xCEC4, 0xCECC, 0xCECE, 0xCED1, - 0xCED3, 0xCEDD, 0xCEDF, 0xCEE0, 0xCEE2, 0xCEE4, - 0xCEEC, 0xCEEE, 0xCEF1, 0xCEF3, 0xCEFD, 0xCEFF, - 0xCF01, 0xCF03, 0xCF0D, 0xCF0F, 0xCF10, 0xCF12, - 0xCF14, 0xCF1C, 0xCF1E, 0xCF21, 0xCF23, 0xCF2D, - 0xCF2F, 0xCF30, 0xCF32, 0xCF34, 0xCF3C, 0xCF3E, - 0xCF41, 0xCF43, 0xCF4D, 0xCF4F, 0xCFC1, 0xCFC3, - 0xCFCD, 0xCFCF, 0xCFD0, 0xCFD2, 0xCFD4, 0xCFDC, - 0xCFDE, 0xCFE1, 0xCFE3, 0xCFED, 0xCFEF, 0xCFF0, - 0xCFF2, 0xCFF4, 0xCFFC, 0xCFFE, 0xD001, 0xD003, - 0xD00D, 0xD00F, 0xD010, 0xD012, 0xD014, 0xD01C, - 0xD01E, 0xD021, 0xD023, 0xD02D, 0xD02F, 0xD030, - 0xD032, 0xD034, 0xD03C, 0xD03E, 0xD041, 0xD043, - 0xD04D, 0xD04F, 0xD0C1, 0xD0C3, 0xD0CD, 0xD0CF, - 0xD0D0, 0xD0D2, 0xD0D4, 0xD0DC, 0xD0DE, 0xD0E1, - 0xD0E3, 0xD0ED, 0xD0EF, 0xD0F0, 0xD0F2, 0xD0F4, - 0xD0FC, 0xD0FE, 0xD100, 0xD102, 0xD104, 0xD10C, - 0xD10E, 0xD111, 0xD113, 0xD11D, 0xD11F, 0xD120, - 0xD122, 0xD124, 0xD12C, 0xD12E, 0xD131, 0xD133, - 0xD13D, 0xD13F, 0xD140, 0xD142, 0xD144, 0xD14C, - 0xD14E, 0xD1C0, 0xD1C2, 0xD1C4, 0xD1CC, 0xD1CE, - 0xD1D1, 0xD1D3, 0xD1DD, 0xD1DF, 0xD1E0, 0xD1E2, - 0xD1E4, 0xD1EC, 0xD1EE, 0xD1F1, 0xD1F3, 0xD1FD, - 0xD1FF, 0xD201, 0xD203, 0xD20D, 0xD20F, 0xD210, - 0xD212, 0xD214, 0xD21C, 0xD21E, 0xD221, 0xD223, - 0xD22D, 0xD22F, 0xD230, 0xD232, 0xD234, 0xD23C, - 0xD23E, 0xD241, 0xD243, 0xD24D, 0xD24F, 0xD2C1, - 0xD2C3, 0xD2CD, 0xD2CF, 0xD2D0, 0xD2D2, 0xD2D4, - 0xD2DC, 0xD2DE, 0xD2E1, 0xD2E3, 0xD2ED, 0xD2EF, - 0xD2F0, 0xD2F2, 0xD2F4, 0xD2FC, 0xD2FE, 0xD300, - 0xD302, 0xD304, 0xD30C, 0xD30E, 0xD311, 0xD313, - 0xD31D, 0xD31F, 0xD320, 0xD322, 0xD324, 0xD32C, - 0xD32E, 0xD331, 0xD333, 0xD33D, 0xD33F, 0xD340, - 0xD342, 0xD344, 0xD34C, 0xD34E, 0xD3C0, 0xD3C2, - 0xD3C4, 0xD3CC, 0xD3CE, 0xD3D1, 0xD3D3, 0xD3DD, - 0xD3DF, 0xD3E0, 0xD3E2, 0xD3E4, 0xD3EC, 0xD3EE, - 0xD3F1, 0xD3F3, 0xD3FD, 0xD3FF, 0xD401, 0xD403, - 0xD40D, 0xD40F, 0xD410, 0xD412, 0xD414, 0xD41C, - 0xD41E, 0xD421, 0xD423, 0xD42D, 0xD42F, 0xD430, - 0xD432, 0xD434, 0xD43C, 0xD43E, 0xD441, 0xD443, - 0xD44D, 0xD44F, 0xD4C1, 0xD4C3, 0xD4CD, 0xD4CF, - 0xD4D0, 0xD4D2, 0xD4D4, 0xD4DC, 0xD4DE, 0xD4E1, - 0xD4E3, 0xD4ED, 0xD4EF, 0xD4F0, 0xD4F2, 0xD4F4, - 0xD4FC, 0xD4FE, 0xDC01, 0xDC03, 0xDC0D, 0xDC0F, - 0xDC10, 0xDC12, 0xDC14, 0xDC1C, 0xDC1E, 0xDC21, - 0xDC23, 0xDC2D, 0xDC2F, 0xDC30, 0xDC32, 0xDC34, - 0xDC3C, 0xDC3E, 0xDC41, 0xDC43, 0xDC4D, 0xDC4F, - 0xDCC1, 0xDCC3, 0xDCCD, 0xDCCF, 0xDCD0, 0xDCD2, - 0xDCD4, 0xDCDC, 0xDCDE, 0xDCE1, 0xDCE3, 0xDCED, - 0xDCEF, 0xDCF0, 0xDCF2, 0xDCF4, 0xDCFC, 0xDCFE, - 0xDD00, 0xDD02, 0xDD04, 0xDD0C, 0xDD0E, 0xDD11, - 0xDD13, 0xDD1D, 0xDD1F, 0xDD20, 0xDD22, 0xDD24, - 0xDD2C, 0xDD2E, 0xDD31, 0xDD33, 0xDD3D, 0xDD3F, - 0xDD40, 0xDD42, 0xDD44, 0xDD4C, 0xDD4E, 0xDDC0, - 0xDDC2, 0xDDC4, 0xDDCC, 0xDDCE, 0xDDD1, 0xDDD3, - 0xDDDD, 0xDDDF, 0xDDE0, 0xDDE2, 0xDDE4, 0xDDEC, - 0xDDEE, 0xDDF1, 0xDDF3, 0xDDFD, 0xDDFF, 0xDE01, - 0xDE03, 0xDE0D, 0xDE0F, 0xDE10, 0xDE12, 0xDE14, - 0xDE1C, 0xDE1E, 0xDE21, 0xDE23, 0xDE2D, 0xDE2F, - 0xDE30, 0xDE32, 0xDE34, 0xDE3C, 0xDE3E, 0xDE41, - 0xDE43, 0xDE4D, 0xDE4F, 0xDEC1, 0xDEC3, 0xDECD, - 0xDECF, 0xDED0, 0xDED2, 0xDED4, 0xDEDC, 0xDEDE, - 0xDEE1, 0xDEE3, 0xDEED, 0xDEEF, 0xDEF0, 0xDEF2, - 0xDEF4, 0xDEFC, 0xDEFE, 0xDF00, 0xDF02, 0xDF04, - 0xDF0C, 0xDF0E, 0xDF11, 0xDF13, 0xDF1D, 0xDF1F, - 0xDF20, 0xDF22, 0xDF24, 0xDF2C, 0xDF2E, 0xDF31, - 0xDF33, 0xDF3D, 0xDF3F, 0xDF40, 0xDF42, 0xDF44, - 0xDF4C, 0xDF4E, 0xDFC0, 0xDFC2, 0xDFC4, 0xDFCC, - 0xDFCE, 0xDFD1, 0xDFD3, 0xDFDD, 0xDFDF, 0xDFE0, - 0xDFE2, 0xDFE4, 0xDFEC, 0xDFEE, 0xDFF1, 0xDFF3, - 0xDFFD, 0xDFFF, 0xE000, 0xE002, 0xE004, 0xE00C, - 0xE00E, 0xE011, 0xE013, 0xE01D, 0xE01F, 0xE020, - 0xE022, 0xE024, 0xE02C, 0xE02E, 0xE031, 0xE033, - 0xE03D, 0xE03F, 0xE040, 0xE042, 0xE044, 0xE04C, - 0xE04E, 0xE0C0, 0xE0C2, 0xE0C4, 0xE0CC, 0xE0CE, - 0xE0D1, 0xE0D3, 0xE0DD, 0xE0DF, 0xE0E0, 0xE0E2, - 0xE0E4, 0xE0EC, 0xE0EE, 0xE0F1, 0xE0F3, 0xE0FD, - 0xE0FF, 0xE101, 0xE103, 0xE10D, 0xE10F, 0xE110, - 0xE112, 0xE114, 0xE11C, 0xE11E, 0xE121, 0xE123, - 0xE12D, 0xE12F, 0xE130, 0xE132, 0xE134, 0xE13C, - 0xE13E, 0xE141, 0xE143, 0xE14D, 0xE14F, 0xE1C1, - 0xE1C3, 0xE1CD, 0xE1CF, 0xE1D0, 0xE1D2, 0xE1D4, - 0xE1DC, 0xE1DE, 0xE1E1, 0xE1E3, 0xE1ED, 0xE1EF, - 0xE1F0, 0xE1F2, 0xE1F4, 0xE1FC, 0xE1FE, 0xE200, - 0xE202, 0xE204, 0xE20C, 0xE20E, 0xE211, 0xE213, - 0xE21D, 0xE21F, 0xE220, 0xE222, 0xE224, 0xE22C, - 0xE22E, 0xE231, 0xE233, 0xE23D, 0xE23F, 0xE240, - 0xE242, 0xE244, 0xE24C, 0xE24E, 0xE2C0, 0xE2C2, - 0xE2C4, 0xE2CC, 0xE2CE, 0xE2D1, 0xE2D3, 0xE2DD, - 0xE2DF, 0xE2E0, 0xE2E2, 0xE2E4, 0xE2EC, 0xE2EE, - 0xE2F1, 0xE2F3, 0xE2FD, 0xE2FF, 0xE301, 0xE303, - 0xE30D, 0xE30F, 0xE310, 0xE312, 0xE314, 0xE31C, - 0xE31E, 0xE321, 0xE323, 0xE32D, 0xE32F, 0xE330, - 0xE332, 0xE334, 0xE33C, 0xE33E, 0xE341, 0xE343, - 0xE34D, 0xE34F, 0xE3C1, 0xE3C3, 0xE3CD, 0xE3CF, - 0xE3D0, 0xE3D2, 0xE3D4, 0xE3DC, 0xE3DE, 0xE3E1, - 0xE3E3, 0xE3ED, 0xE3EF, 0xE3F0, 0xE3F2, 0xE3F4, - 0xE3FC, 0xE3FE, 0xE400, 0xE402, 0xE404, 0xE40C, - 0xE40E, 0xE411, 0xE413, 0xE41D, 0xE41F, 0xE420, - 0xE422, 0xE424, 0xE42C, 0xE42E, 0xE431, 0xE433, - 0xE43D, 0xE43F, 0xE440, 0xE442, 0xE444, 0xE44C, - 0xE44E, 0xE4C0, 0xE4C2, 0xE4C4, 0xE4CC, 0xE4CE, - 0xE4D1, 0xE4D3, 0xE4DD, 0xE4DF, 0xE4E0, 0xE4E2, - 0xE4E4, 0xE4EC, 0xE4EE, 0xE4F1, 0xE4F3, 0xE4FD, - 0xE4FF, 0xEC00, 0xEC02, 0xEC04, 0xEC0C, 0xEC0E, - 0xEC11, 0xEC13, 0xEC1D, 0xEC1F, 0xEC20, 0xEC22, - 0xEC24, 0xEC2C, 0xEC2E, 0xEC31, 0xEC33, 0xEC3D, - 0xEC3F, 0xEC40, 0xEC42, 0xEC44, 0xEC4C, 0xEC4E, - 0xECC0, 0xECC2, 0xECC4, 0xECCC, 0xECCE, 0xECD1, - 0xECD3, 0xECDD, 0xECDF, 0xECE0, 0xECE2, 0xECE4, - 0xECEC, 0xECEE, 0xECF1, 0xECF3, 0xECFD, 0xECFF, - 0xED01, 0xED03, 0xED0D, 0xED0F, 0xED10, 0xED12, - 0xED14, 0xED1C, 0xED1E, 0xED21, 0xED23, 0xED2D, - 0xED2F, 0xED30, 0xED32, 0xED34, 0xED3C, 0xED3E, - 0xED41, 0xED43, 0xED4D, 0xED4F, 0xEDC1, 0xEDC3, - 0xEDCD, 0xEDCF, 0xEDD0, 0xEDD2, 0xEDD4, 0xEDDC, - 0xEDDE, 0xEDE1, 0xEDE3, 0xEDED, 0xEDEF, 0xEDF0, - 0xEDF2, 0xEDF4, 0xEDFC, 0xEDFE, 0xEE00, 0xEE02, - 0xEE04, 0xEE0C, 0xEE0E, 0xEE11, 0xEE13, 0xEE1D, - 0xEE1F, 0xEE20, 0xEE22, 0xEE24, 0xEE2C, 0xEE2E, - 0xEE31, 0xEE33, 0xEE3D, 0xEE3F, 0xEE40, 0xEE42, - 0xEE44, 0xEE4C, 0xEE4E, 0xEEC0, 0xEEC2, 0xEEC4, - 0xEECC, 0xEECE, 0xEED1, 0xEED3, 0xEEDD, 0xEEDF, - 0xEEE0, 0xEEE2, 0xEEE4, 0xEEEC, 0xEEEE, 0xEEF1, - 0xEEF3, 0xEEFD, 0xEEFF, 0xEF01, 0xEF03, 0xEF0D, - 0xEF0F, 0xEF10, 0xEF12, 0xEF14, 0xEF1C, 0xEF1E, - 0xEF21, 0xEF23, 0xEF2D, 0xEF2F, 0xEF30, 0xEF32, - 0xEF34, 0xEF3C, 0xEF3E, 0xEF41, 0xEF43, 0xEF4D, - 0xEF4F, 0xEFC1, 0xEFC3, 0xEFCD, 0xEFCF, 0xEFD0, - 0xEFD2, 0xEFD4, 0xEFDC, 0xEFDE, 0xEFE1, 0xEFE3, - 0xEFED, 0xEFEF, 0xEFF0, 0xEFF2, 0xEFF4, 0xEFFC, - 0xEFFE, 0xF001, 0xF003, 0xF00D, 0xF00F, 0xF010, - 0xF012, 0xF014, 0xF01C, 0xF01E, 0xF021, 0xF023, - 0xF02D, 0xF02F, 0xF030, 0xF032, 0xF034, 0xF03C, - 0xF03E, 0xF041, 0xF043, 0xF04D, 0xF04F, 0xF0C1, - 0xF0C3, 0xF0CD, 0xF0CF, 0xF0D0, 0xF0D2, 0xF0D4, - 0xF0DC, 0xF0DE, 0xF0E1, 0xF0E3, 0xF0ED, 0xF0EF, - 0xF0F0, 0xF0F2, 0xF0F4, 0xF0FC, 0xF0FE, 0xF100, - 0xF102, 0xF104, 0xF10C, 0xF10E, 0xF111, 0xF113, - 0xF11D, 0xF11F, 0xF120, 0xF122, 0xF124, 0xF12C, - 0xF12E, 0xF131, 0xF133, 0xF13D, 0xF13F, 0xF140, - 0xF142, 0xF144, 0xF14C, 0xF14E, 0xF1C0, 0xF1C2, - 0xF1C4, 0xF1CC, 0xF1CE, 0xF1D1, 0xF1D3, 0xF1DD, - 0xF1DF, 0xF1E0, 0xF1E2, 0xF1E4, 0xF1EC, 0xF1EE, - 0xF1F1, 0xF1F3, 0xF1FD, 0xF1FF, 0xF201, 0xF203, - 0xF20D, 0xF20F, 0xF210, 0xF212, 0xF214, 0xF21C, - 0xF21E, 0xF221, 0xF223, 0xF22D, 0xF22F, 0xF230, - 0xF232, 0xF234, 0xF23C, 0xF23E, 0xF241, 0xF243, - 0xF24D, 0xF24F, 0xF2C1, 0xF2C3, 0xF2CD, 0xF2CF, - 0xF2D0, 0xF2D2, 0xF2D4, 0xF2DC, 0xF2DE, 0xF2E1, - 0xF2E3, 0xF2ED, 0xF2EF, 0xF2F0, 0xF2F2, 0xF2F4, - 0xF2FC, 0xF2FE, 0xF300, 0xF302, 0xF304, 0xF30C, - 0xF30E, 0xF311, 0xF313, 0xF31D, 0xF31F, 0xF320, - 0xF322, 0xF324, 0xF32C, 0xF32E, 0xF331, 0xF333, - 0xF33D, 0xF33F, 0xF340, 0xF342, 0xF344, 0xF34C, - 0xF34E, 0xF3C0, 0xF3C2, 0xF3C4, 0xF3CC, 0xF3CE, - 0xF3D1, 0xF3D3, 0xF3DD, 0xF3DF, 0xF3E0, 0xF3E2, - 0xF3E4, 0xF3EC, 0xF3EE, 0xF3F1, 0xF3F3, 0xF3FD, - 0xF3FF, 0xF401, 0xF403, 0xF40D, 0xF40F, 0xF410, - 0xF412, 0xF414, 0xF41C, 0xF41E, 0xF421, 0xF423, - 0xF42D, 0xF42F, 0xF430, 0xF432, 0xF434, 0xF43C, - 0xF43E, 0xF441, 0xF443, 0xF44D, 0xF44F, 0xF4C1, - 0xF4C3, 0xF4CD, 0xF4CF, 0xF4D0, 0xF4D2, 0xF4D4, - 0xF4DC, 0xF4DE, 0xF4E1, 0xF4E3, 0xF4ED, 0xF4EF, - 0xF4F0, 0xF4F2, 0xF4F4, 0xF4FC, 0xF4FE, 0xFC01, - 0xFC03, 0xFC0D, 0xFC0F, 0xFC10, 0xFC12, 0xFC14, - 0xFC1C, 0xFC1E, 0xFC21, 0xFC23, 0xFC2D, 0xFC2F, - 0xFC30, 0xFC32, 0xFC34, 0xFC3C, 0xFC3E, 0xFC41, - 0xFC43, 0xFC4D, 0xFC4F, 0xFCC1, 0xFCC3, 0xFCCD, - 0xFCCF, 0xFCD0, 0xFCD2, 0xFCD4, 0xFCDC, 0xFCDE, - 0xFCE1, 0xFCE3, 0xFCED, 0xFCEF, 0xFCF0, 0xFCF2, - 0xFCF4, 0xFCFC, 0xFCFE, 0xFD00, 0xFD02, 0xFD04, - 0xFD0C, 0xFD0E, 0xFD11, 0xFD13, 0xFD1D, 0xFD1F, - 0xFD20, 0xFD22, 0xFD24, 0xFD2C, 0xFD2E, 0xFD31, - 0xFD33, 0xFD3D, 0xFD3F, 0xFD40, 0xFD42, 0xFD44, - 0xFD4C, 0xFD4E, 0xFDC0, 0xFDC2, 0xFDC4, 0xFDCC, - 0xFDCE, 0xFDD1, 0xFDD3, 0xFDDD, 0xFDDF, 0xFDE0, - 0xFDE2, 0xFDE4, 0xFDEC, 0xFDEE, 0xFDF1, 0xFDF3, - 0xFDFD, 0xFDFF, 0xFE01, 0xFE03, 0xFE0D, 0xFE0F, - 0xFE10, 0xFE12, 0xFE14, 0xFE1C, 0xFE1E, 0xFE21, - 0xFE23, 0xFE2D, 0xFE2F, 0xFE30, 0xFE32, 0xFE34, - 0xFE3C, 0xFE3E, 0xFE41, 0xFE43, 0xFE4D, 0xFE4F, - 0xFEC1, 0xFEC3, 0xFECD, 0xFECF, 0xFED0, 0xFED2, - 0xFED4, 0xFEDC, 0xFEDE, 0xFEE1, 0xFEE3, 0xFEED, - 0xFEEF, 0xFEF0, 0xFEF2, 0xFEF4, 0xFEFC, 0xFEFE, - 0xFF00, 0xFF02, 0xFF04, 0xFF0C, 0xFF0E, 0xFF11, - 0xFF13, 0xFF1D, 0xFF1F, 0xFF20, 0xFF22, 0xFF24, - 0xFF2C, 0xFF2E, 0xFF31, 0xFF33, 0xFF3D, 0xFF3F, - 0xFF40, 0xFF42, 0xFF44, 0xFF4C, 0xFF4E, 0xFFC0, - 0xFFC2, 0xFFC4, 0xFFCC, 0xFFCE, 0xFFD1, 0xFFD3, - 0xFFDD, 0xFFDF, 0xFFE0, 0xFFE2, 0xFFE4, 0xFFEC, - 0xFFEE, 0xFFF1, 0xFFF3, 0xFFFD, 0xFFFF, -}; - -#define ON2AVC_CB9_CODES 121 -static const uint16_t on2avc_cb9_codes[ON2AVC_CB9_CODES] = { - 0x0000, 0x000F, 0x0098, 0x026E, 0x045C, 0x00A6, - 0x00AC, 0x045D, 0x027E, 0x009A, 0x0012, 0x000E, - 0x001A, 0x00DE, 0x022C, 0x053E, 0x00A2, 0x009E, - 0x0538, 0x01B2, 0x00BA, 0x0018, 0x00AD, 0x00BF, - 0x01BE, 0x037E, 0x05C6, 0x0132, 0x0112, 0x08B5, - 0x0457, 0x01B6, 0x00BC, 0x02AE, 0x022A, 0x045E, - 0x08B6, 0x08FA, 0x0147, 0x013E, 0x119F, 0x05C7, - 0x044F, 0x0170, 0x0456, 0x047F, 0x06C7, 0x0A72, - 0x0D8B, 0x0267, 0x0266, 0x0D8A, 0x08B7, 0x05CF, - 0x045F, 0x0054, 0x00A4, 0x0118, 0x0142, 0x0234, - 0x036F, 0x036E, 0x029E, 0x0156, 0x0114, 0x0088, - 0x00A0, 0x00A5, 0x00DA, 0x015F, 0x026F, 0x02E2, - 0x02E6, 0x0236, 0x015E, 0x0143, 0x00AA, 0x053A, - 0x0466, 0x04FE, 0x09FE, 0x119E, 0x0232, 0x0237, - 0x0A73, 0x09FF, 0x08B4, 0x046B, 0x02AF, 0x01B0, - 0x037F, 0x053F, 0x08FB, 0x0136, 0x0146, 0x08CE, - 0x05CE, 0x044E, 0x01B3, 0x008E, 0x00DD, 0x0226, - 0x047E, 0x06C6, 0x00AE, 0x011E, 0x06C4, 0x047C, - 0x0172, 0x00BE, 0x0010, 0x0016, 0x00BD, 0x0176, - 0x053B, 0x009D, 0x009C, 0x046A, 0x0177, 0x00DC, - 0x0019, -}; - -static const uint8_t on2avc_cb9_bits[ON2AVC_CB9_CODES] = { - 1, 4, 8, 10, 11, 8, - 8, 11, 10, 8, 5, 4, - 5, 8, 10, 11, 8, 8, - 11, 9, 8, 5, 8, 8, - 9, 10, 11, 9, 9, 12, - 11, 9, 8, 10, 10, 11, - 12, 12, 9, 9, 13, 11, - 11, 9, 11, 11, 11, 12, - 12, 10, 10, 12, 12, 11, - 11, 7, 8, 9, 9, 10, - 10, 10, 10, 9, 9, 8, - 8, 8, 8, 9, 10, 10, - 10, 10, 9, 9, 8, 11, - 11, 11, 12, 13, 10, 10, - 12, 12, 12, 11, 10, 9, - 10, 11, 12, 9, 9, 12, - 11, 11, 9, 8, 8, 10, - 11, 11, 8, 9, 11, 11, - 9, 8, 5, 5, 8, 9, - 11, 8, 8, 11, 9, 8, - 5, -}; - -static const uint16_t on2avc_cb9_syms[ON2AVC_CB9_CODES] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, 0x0100, - 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x01FB, - 0x01FC, 0x01FD, 0x01FE, 0x01FF, 0x0200, 0x0201, - 0x0202, 0x0203, 0x0204, 0x0205, 0x02FB, 0x02FC, - 0x02FD, 0x02FE, 0x02FF, 0x0300, 0x0301, 0x0302, - 0x0303, 0x0304, 0x0305, 0x03FB, 0x03FC, 0x03FD, - 0x03FE, 0x03FF, 0x0400, 0x0401, 0x0402, 0x0403, - 0x0404, 0x0405, 0x04FB, 0x04FC, 0x04FD, 0x04FE, - 0x04FF, 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, - 0x0505, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF, - 0xFB00, 0xFB01, 0xFB02, 0xFB03, 0xFB04, 0xFB05, - 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF, 0xFC00, - 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFCFB, - 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, - 0xFD02, 0xFD03, 0xFD04, 0xFD05, 0xFDFB, 0xFDFC, - 0xFDFD, 0xFDFE, 0xFDFF, 0xFE00, 0xFE01, 0xFE02, - 0xFE03, 0xFE04, 0xFE05, 0xFEFB, 0xFEFC, 0xFEFD, - 0xFEFE, 0xFEFF, 0xFF00, 0xFF01, 0xFF02, 0xFF03, - 0xFF04, 0xFF05, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, - 0xFFFF, -}; - -#define ON2AVC_CB10_CODES 121 -static const uint16_t on2avc_cb10_codes[ON2AVC_CB10_CODES] = { - 0x002E, 0x001A, 0x003C, 0x001F, 0x006E, 0x002E, - 0x00AE, 0x006F, 0x002A, 0x003E, 0x0014, 0x0016, - 0x0002, 0x000E, 0x004E, 0x00F7, 0x0042, 0x0027, - 0x00F6, 0x0046, 0x0014, 0x0008, 0x0032, 0x0016, - 0x0030, 0x0012, 0x0056, 0x0018, 0x005F, 0x00DE, - 0x006E, 0x0036, 0x001A, 0x0023, 0x003D, 0x003F, - 0x007A, 0x008E, 0x0071, 0x0006, 0x0012, 0x000F, - 0x0043, 0x003E, 0x00AE, 0x0001, 0x00AB, 0x00C7, - 0x0013, 0x000A, 0x0002, 0x01CA, 0x0003, 0x0000, - 0x000F, 0x0022, 0x0016, 0x002A, 0x007F, 0x001C, - 0x0036, 0x00AF, 0x00C6, 0x000E, 0x0010, 0x0006, - 0x008F, 0x001E, 0x0054, 0x000D, 0x00AA, 0x0056, - 0x00AC, 0x001D, 0x0076, 0x0013, 0x004F, 0x0057, - 0x00E6, 0x00EE, 0x000E, 0x01CB, 0x00AF, 0x000B, - 0x0007, 0x00EF, 0x00AD, 0x00E4, 0x0008, 0x005E, - 0x0070, 0x001E, 0x00DF, 0x000C, 0x007E, 0x00CE, - 0x0002, 0x001A, 0x003C, 0x0002, 0x0020, 0x003A, - 0x004D, 0x00CF, 0x0066, 0x0026, 0x002F, 0x001F, - 0x0022, 0x001B, 0x0012, 0x000E, 0x0017, 0x0062, - 0x00E7, 0x0019, 0x0014, 0x0006, 0x004C, 0x0012, - 0x000C, -}; - -static const uint8_t on2avc_cb10_bits[ON2AVC_CB10_CODES] = { - 6, 5, 6, 8, 9, 8, - 8, 9, 8, 6, 5, 5, - 5, 6, 7, 8, 7, 7, - 8, 7, 6, 5, 6, 6, - 6, 7, 8, 7, 7, 8, - 7, 6, 6, 8, 7, 7, - 7, 8, 7, 8, 9, 8, - 7, 7, 9, 9, 8, 8, - 9, 8, 9, 9, 9, 9, - 9, 8, 7, 7, 7, 8, - 8, 9, 8, 8, 7, 6, - 8, 7, 7, 8, 8, 9, - 8, 8, 7, 7, 7, 9, - 8, 8, 9, 9, 8, 8, - 9, 8, 8, 8, 8, 7, - 7, 8, 8, 8, 7, 8, - 8, 7, 7, 7, 6, 6, - 7, 8, 7, 7, 8, 7, - 6, 6, 5, 5, 6, 7, - 8, 7, 7, 9, 7, 6, - 5, -}; - -static const uint16_t on2avc_cb10_syms[ON2AVC_CB10_CODES] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, 0x0100, - 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x01FB, - 0x01FC, 0x01FD, 0x01FE, 0x01FF, 0x0200, 0x0201, - 0x0202, 0x0203, 0x0204, 0x0205, 0x02FB, 0x02FC, - 0x02FD, 0x02FE, 0x02FF, 0x0300, 0x0301, 0x0302, - 0x0303, 0x0304, 0x0305, 0x03FB, 0x03FC, 0x03FD, - 0x03FE, 0x03FF, 0x0400, 0x0401, 0x0402, 0x0403, - 0x0404, 0x0405, 0x04FB, 0x04FC, 0x04FD, 0x04FE, - 0x04FF, 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, - 0x0505, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF, - 0xFB00, 0xFB01, 0xFB02, 0xFB03, 0xFB04, 0xFB05, - 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF, 0xFC00, - 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFCFB, - 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, - 0xFD02, 0xFD03, 0xFD04, 0xFD05, 0xFDFB, 0xFDFC, - 0xFDFD, 0xFDFE, 0xFDFF, 0xFE00, 0xFE01, 0xFE02, - 0xFE03, 0xFE04, 0xFE05, 0xFEFB, 0xFEFC, 0xFEFD, - 0xFEFE, 0xFEFF, 0xFF00, 0xFF01, 0xFF02, 0xFF03, - 0xFF04, 0xFF05, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, - 0xFFFF, -}; - -#define ON2AVC_CB11_CODES 225 -static const uint16_t on2avc_cb11_codes[ON2AVC_CB11_CODES] = { - 0x0000, 0x000E, 0x0056, 0x00CD, 0x0173, 0x0232, - 0x00C7, 0x014F, 0x01AA, 0x00BE, 0x026F, 0x0192, - 0x00BC, 0x0058, 0x000F, 0x000C, 0x0010, 0x004E, - 0x0082, 0x0142, 0x01BF, 0x0098, 0x015E, 0x0136, - 0x0086, 0x01BB, 0x014E, 0x00BA, 0x003E, 0x0012, - 0x0054, 0x0036, 0x0050, 0x008F, 0x014B, 0x0262, - 0x00AA, 0x015C, 0x013E, 0x00B7, 0x02BE, 0x0176, - 0x00A2, 0x0058, 0x003C, 0x00C2, 0x00A6, 0x008A, - 0x00B2, 0x0122, 0x02AC, 0x00CA, 0x012F, 0x014A, - 0x00DC, 0x02DE, 0x017A, 0x0134, 0x0092, 0x00B4, - 0x0166, 0x0148, 0x016E, 0x013F, 0x0134, 0x02FF, - 0x014F, 0x019E, 0x0267, 0x016C, 0x02A6, 0x02CE, - 0x013A, 0x010A, 0x0108, 0x026E, 0x02CB, 0x028E, - 0x02CF, 0x020F, 0x02DF, 0x010B, 0x02AD, 0x0227, - 0x018A, 0x04DB, 0x02A7, 0x02FE, 0x0236, 0x026C, - 0x00C6, 0x009C, 0x00C4, 0x00CE, 0x00D6, 0x0135, - 0x0156, 0x025A, 0x02FF, 0x0286, 0x015F, 0x0132, - 0x00D7, 0x00AC, 0x00A2, 0x0176, 0x0118, 0x0123, - 0x0157, 0x01BC, 0x02AE, 0x02EE, 0x04DA, 0x0467, - 0x033F, 0x0287, 0x0193, 0x0182, 0x013B, 0x0112, - 0x0133, 0x017D, 0x0117, 0x0186, 0x026E, 0x025B, - 0x02EF, 0x0466, 0x0316, 0x0237, 0x02F6, 0x01BA, - 0x015D, 0x012E, 0x015A, 0x014A, 0x008E, 0x00B6, - 0x0135, 0x0100, 0x017B, 0x028C, 0x033E, 0x0297, - 0x015B, 0x0102, 0x0140, 0x00D4, 0x00BA, 0x0088, - 0x02EE, 0x0283, 0x02BF, 0x020E, 0x02CE, 0x0317, - 0x0172, 0x0296, 0x026F, 0x0101, 0x02CF, 0x02F7, - 0x01BD, 0x02EF, 0x028F, 0x0263, 0x0164, 0x011A, - 0x0147, 0x0292, 0x02FE, 0x015E, 0x02AF, 0x01AB, - 0x0130, 0x02CA, 0x0183, 0x014E, 0x017C, 0x017E, - 0x00C8, 0x00AA, 0x009E, 0x0132, 0x0152, 0x0226, - 0x00CC, 0x017E, 0x0187, 0x00CB, 0x0293, 0x0106, - 0x00C0, 0x0087, 0x00BC, 0x005C, 0x003D, 0x005A, - 0x00A8, 0x0103, 0x028D, 0x00A4, 0x0116, 0x0146, - 0x00B8, 0x01BE, 0x016D, 0x0093, 0x004A, 0x003F, - 0x000D, 0x0011, 0x004F, 0x00AE, 0x0166, 0x0266, - 0x0090, 0x0109, 0x012C, 0x00A6, 0x0282, 0x017A, - 0x00B5, 0x0034, 0x000E, -}; - -static const uint8_t on2avc_cb11_bits[ON2AVC_CB11_CODES] = { - 2, 4, 7, 9, 10, 11, - 9, 10, 10, 9, 11, 10, - 9, 7, 4, 4, 5, 7, - 9, 9, 10, 9, 10, 10, - 9, 10, 9, 8, 7, 5, - 7, 7, 8, 9, 9, 10, - 9, 10, 10, 9, 10, 9, - 9, 8, 7, 9, 8, 9, - 9, 10, 10, 9, 10, 10, - 9, 10, 10, 9, 9, 8, - 10, 9, 9, 10, 10, 10, - 9, 10, 10, 9, 11, 10, - 10, 10, 10, 11, 10, 10, - 10, 11, 10, 10, 10, 11, - 10, 11, 11, 10, 11, 10, - 9, 9, 9, 9, 9, 10, - 10, 11, 11, 10, 10, 10, - 9, 9, 8, 10, 10, 10, - 10, 10, 10, 10, 11, 12, - 11, 10, 10, 10, 10, 10, - 10, 9, 10, 10, 10, 11, - 11, 12, 11, 11, 10, 10, - 10, 10, 10, 9, 9, 9, - 9, 10, 10, 10, 11, 11, - 10, 10, 9, 9, 9, 9, - 11, 10, 10, 11, 11, 11, - 10, 11, 10, 10, 11, 10, - 10, 10, 10, 10, 9, 10, - 10, 10, 11, 9, 10, 10, - 9, 10, 10, 10, 9, 9, - 9, 8, 9, 9, 10, 11, - 9, 10, 10, 9, 10, 10, - 9, 9, 8, 7, 7, 8, - 9, 10, 10, 9, 10, 10, - 9, 10, 9, 9, 8, 7, - 4, 5, 7, 8, 9, 10, - 9, 10, 10, 9, 10, 9, - 8, 7, 5, -}; - -static const uint16_t on2avc_cb11_syms[ON2AVC_CB11_CODES] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x00F9, 0x00FA, 0x00FB, 0x00FC, - 0x00FD, 0x00FE, 0x00FF, 0x0100, 0x0101, 0x0102, - 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x01F9, - 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF, - 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, - 0x0206, 0x0207, 0x02F9, 0x02FA, 0x02FB, 0x02FC, - 0x02FD, 0x02FE, 0x02FF, 0x0300, 0x0301, 0x0302, - 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x03F9, - 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF, - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, - 0x0406, 0x0407, 0x04F9, 0x04FA, 0x04FB, 0x04FC, - 0x04FD, 0x04FE, 0x04FF, 0x0500, 0x0501, 0x0502, - 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 0x05F9, - 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF, - 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, - 0x0606, 0x0607, 0x06F9, 0x06FA, 0x06FB, 0x06FC, - 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, - 0x0703, 0x0704, 0x0705, 0x0706, 0x0707, 0x07F9, - 0x07FA, 0x07FB, 0x07FC, 0x07FD, 0x07FE, 0x07FF, - 0xF900, 0xF901, 0xF902, 0xF903, 0xF904, 0xF905, - 0xF906, 0xF907, 0xF9F9, 0xF9FA, 0xF9FB, 0xF9FC, - 0xF9FD, 0xF9FE, 0xF9FF, 0xFA00, 0xFA01, 0xFA02, - 0xFA03, 0xFA04, 0xFA05, 0xFA06, 0xFA07, 0xFAF9, - 0xFAFA, 0xFAFB, 0xFAFC, 0xFAFD, 0xFAFE, 0xFAFF, - 0xFB00, 0xFB01, 0xFB02, 0xFB03, 0xFB04, 0xFB05, - 0xFB06, 0xFB07, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, - 0xFBFD, 0xFBFE, 0xFBFF, 0xFC00, 0xFC01, 0xFC02, - 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFCF9, - 0xFCFA, 0xFCFB, 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, - 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04, 0xFD05, - 0xFD06, 0xFD07, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, - 0xFDFD, 0xFDFE, 0xFDFF, 0xFE00, 0xFE01, 0xFE02, - 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07, 0xFEF9, - 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0xFEFF, - 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, - 0xFF06, 0xFF07, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, - 0xFFFD, 0xFFFE, 0xFFFF, -}; - -#define ON2AVC_CB12_CODES 441 -static const uint16_t on2avc_cb12_codes[ON2AVC_CB12_CODES] = { - 0x0000, 0x000C, 0x004F, 0x0156, 0x02E6, 0x0462, - 0x044C, 0x086A, 0x0222, 0x0228, 0x047F, 0x037A, - 0x028F, 0x02B8, 0x0BB7, 0x04B7, 0x02DA, 0x0262, - 0x0124, 0x0052, 0x000F, 0x000D, 0x000E, 0x0058, - 0x00A2, 0x0129, 0x02C8, 0x0256, 0x044D, 0x016E, - 0x02AA, 0x02BE, 0x027F, 0x02A9, 0x016E, 0x0597, - 0x02EE, 0x02EE, 0x013A, 0x00A4, 0x004E, 0x000C, - 0x0056, 0x004B, 0x0058, 0x0125, 0x010E, 0x01A7, - 0x026A, 0x0415, 0x010C, 0x0228, 0x0446, 0x0232, - 0x017E, 0x0128, 0x0473, 0x035E, 0x026A, 0x015E, - 0x00DB, 0x005E, 0x0048, 0x017A, 0x00AE, 0x00BA, - 0x0172, 0x0229, 0x02FB, 0x0458, 0x05A4, 0x015A, - 0x0296, 0x05BE, 0x044E, 0x0216, 0x012A, 0x0423, - 0x053E, 0x02F0, 0x02F1, 0x011E, 0x0110, 0x009C, - 0x026B, 0x0112, 0x011B, 0x01B3, 0x01BF, 0x0263, - 0x057E, 0x04B8, 0x016B, 0x02DE, 0x04DE, 0x0416, - 0x02DB, 0x02AB, 0x06EE, 0x04CF, 0x025F, 0x02EB, - 0x022A, 0x011A, 0x010A, 0x05A5, 0x0238, 0x0217, - 0x02D6, 0x025A, 0x0282, 0x044F, 0x043D, 0x01AE, - 0x026B, 0x05C2, 0x043C, 0x044F, 0x02DB, 0x05A7, - 0x044E, 0x05BF, 0x0297, 0x022A, 0x026C, 0x02BD, - 0x0897, 0x0283, 0x02B6, 0x02B7, 0x0264, 0x0459, - 0x040B, 0x04DF, 0x0298, 0x0456, 0x0AFF, 0x06B7, - 0x0448, 0x0449, 0x08BE, 0x06EF, 0x04B9, 0x0597, - 0x049A, 0x02D2, 0x02F8, 0x08F7, 0x0476, 0x0452, - 0x0453, 0x045A, 0x05BE, 0x043E, 0x04D2, 0x02F2, - 0x02E4, 0x0477, 0x0AFE, 0x05A6, 0x02E3, 0x0BB6, - 0x0A7E, 0x05A6, 0x0A66, 0x08BF, 0x05FF, 0x0492, - 0x0170, 0x0106, 0x0140, 0x0142, 0x022E, 0x02CF, - 0x02B9, 0x02E2, 0x02F3, 0x05A0, 0x088E, 0x0DD7, - 0x04F6, 0x047E, 0x045B, 0x0347, 0x029E, 0x026D, - 0x01AC, 0x013B, 0x0104, 0x035F, 0x02EC, 0x026E, - 0x0233, 0x0207, 0x023E, 0x026E, 0x053F, 0x05A7, - 0x0456, 0x04AE, 0x0DD6, 0x0A67, 0x0493, 0x04BA, - 0x05D3, 0x05C3, 0x0246, 0x0247, 0x0202, 0x02E8, - 0x05AE, 0x0374, 0x0537, 0x05C6, 0x04BB, 0x0686, - 0x04D3, 0x04DE, 0x08C3, 0x05BF, 0x04F7, 0x14FB, - 0x0997, 0x0A7F, 0x08C2, 0x0417, 0x0434, 0x0477, - 0x037B, 0x0463, 0x02EF, 0x0592, 0x02E5, 0x049B, - 0x035A, 0x0436, 0x05AF, 0x0687, 0x0896, 0x095F, - 0x09BE, 0x0996, 0x0558, 0x088F, 0x0B8E, 0x057E, - 0x04CA, 0x05CE, 0x05F3, 0x047A, 0x05A1, 0x02E2, - 0x02FA, 0x0204, 0x022C, 0x020E, 0x0360, 0x02AE, - 0x05FC, 0x0457, 0x05DA, 0x086B, 0x14FA, 0x04B6, - 0x02FE, 0x040A, 0x02E6, 0x0576, 0x044A, 0x028C, - 0x0212, 0x0248, 0x02E0, 0x029A, 0x0126, 0x017E, - 0x0130, 0x024C, 0x0232, 0x0596, 0x0378, 0x053A, - 0x04CC, 0x0A7C, 0x0470, 0x0593, 0x02D8, 0x029C, - 0x02D9, 0x02BE, 0x01A0, 0x014E, 0x0120, 0x013C, - 0x06EC, 0x04CD, 0x0559, 0x06B6, 0x0420, 0x057F, - 0x0596, 0x09BF, 0x0532, 0x055A, 0x095E, 0x08BC, - 0x0472, 0x02CA, 0x05F2, 0x05FD, 0x047E, 0x05A2, - 0x06EA, 0x05CF, 0x04D2, 0x043F, 0x028E, 0x0422, - 0x0460, 0x05DE, 0x053B, 0x08F6, 0x0B8F, 0x02CE, - 0x0473, 0x06ED, 0x0421, 0x028D, 0x023C, 0x047F, - 0x05A3, 0x044C, 0x044D, 0x0457, 0x02CA, 0x02D8, - 0x027C, 0x029E, 0x023E, 0x027D, 0x0361, 0x0414, - 0x05BC, 0x08BD, 0x02DA, 0x024A, 0x0437, 0x055B, - 0x0379, 0x01BE, 0x05DF, 0x04D3, 0x0268, 0x0206, - 0x0213, 0x02BA, 0x0203, 0x0236, 0x0127, 0x0136, - 0x0268, 0x0242, 0x02CF, 0x05FE, 0x05D2, 0x0237, - 0x0243, 0x0472, 0x0362, 0x027A, 0x02AE, 0x0471, - 0x0474, 0x024B, 0x02AF, 0x01A6, 0x012C, 0x0166, - 0x0166, 0x00A6, 0x00AC, 0x0100, 0x01B2, 0x020F, - 0x0363, 0x0446, 0x016A, 0x022E, 0x0577, 0x02FF, - 0x022D, 0x0168, 0x0475, 0x027E, 0x0222, 0x01A2, - 0x017B, 0x00D2, 0x00BE, 0x0050, 0x0054, 0x006A, - 0x011A, 0x0143, 0x024F, 0x02E7, 0x0447, 0x0110, - 0x0233, 0x02D9, 0x02AF, 0x024E, 0x016A, 0x0536, - 0x0342, 0x02BC, 0x0176, 0x00DA, 0x0054, 0x004A, - 0x000E, 0x0010, 0x004C, 0x00DC, 0x0164, 0x023A, - 0x0476, 0x04CE, 0x0118, 0x02CE, 0x025E, 0x0346, - 0x02A8, 0x0122, 0x05BD, 0x022F, 0x02EA, 0x014A, - 0x00AA, 0x0051, 0x000F, -}; - -static const uint8_t on2avc_cb12_bits[ON2AVC_CB12_CODES] = { - 2, 4, 7, 9, 10, 11, - 12, 13, 10, 11, 11, 11, - 11, 10, 12, 12, 11, 11, - 9, 7, 4, 4, 5, 7, - 9, 10, 10, 11, 12, 10, - 10, 11, 11, 10, 9, 12, - 11, 10, 10, 9, 7, 5, - 7, 7, 8, 9, 10, 10, - 11, 12, 10, 10, 11, 11, - 10, 10, 12, 11, 10, 10, - 9, 8, 7, 9, 9, 9, - 9, 10, 10, 11, 11, 10, - 11, 11, 11, 11, 10, 12, - 11, 10, 10, 10, 9, 9, - 10, 10, 10, 10, 10, 11, - 11, 12, 10, 11, 11, 12, - 11, 10, 12, 12, 11, 10, - 10, 10, 10, 11, 10, 11, - 10, 11, 11, 12, 12, 10, - 11, 11, 12, 11, 10, 12, - 12, 11, 11, 11, 10, 10, - 12, 11, 11, 11, 11, 11, - 12, 12, 10, 11, 12, 12, - 11, 11, 12, 12, 12, 11, - 11, 11, 10, 12, 12, 12, - 12, 11, 12, 12, 12, 10, - 11, 12, 12, 11, 11, 12, - 13, 12, 12, 12, 11, 12, - 10, 10, 10, 10, 10, 10, - 10, 10, 10, 11, 12, 13, - 12, 12, 11, 11, 11, 10, - 10, 10, 10, 11, 10, 10, - 11, 11, 11, 11, 11, 11, - 12, 12, 13, 12, 12, 12, - 11, 11, 11, 11, 11, 10, - 11, 11, 11, 11, 12, 12, - 12, 12, 12, 12, 12, 14, - 13, 13, 12, 12, 12, 11, - 11, 11, 11, 11, 11, 11, - 11, 12, 11, 12, 12, 13, - 12, 13, 12, 12, 12, 12, - 12, 11, 11, 11, 11, 11, - 10, 11, 11, 11, 11, 11, - 11, 12, 11, 13, 14, 12, - 11, 12, 11, 11, 11, 11, - 11, 11, 10, 10, 10, 9, - 10, 10, 10, 11, 11, 11, - 12, 13, 12, 11, 10, 10, - 10, 10, 10, 10, 10, 10, - 12, 12, 12, 12, 12, 12, - 12, 12, 11, 12, 13, 12, - 11, 10, 11, 11, 11, 11, - 12, 11, 11, 12, 11, 12, - 11, 11, 11, 12, 12, 11, - 11, 12, 12, 11, 10, 12, - 11, 11, 11, 11, 11, 11, - 11, 10, 10, 11, 11, 12, - 11, 12, 10, 11, 12, 12, - 11, 10, 11, 11, 11, 11, - 11, 10, 11, 10, 10, 10, - 10, 11, 11, 11, 11, 10, - 11, 12, 11, 11, 10, 12, - 11, 11, 10, 10, 10, 10, - 9, 9, 9, 10, 10, 11, - 11, 12, 10, 11, 11, 11, - 11, 10, 11, 11, 11, 10, - 9, 9, 9, 7, 7, 8, - 9, 10, 10, 11, 12, 10, - 10, 11, 11, 10, 9, 11, - 11, 10, 10, 9, 8, 7, - 4, 5, 7, 9, 10, 11, - 11, 12, 10, 10, 11, 11, - 10, 10, 11, 11, 10, 10, - 9, 7, 5, -}; - -static const uint16_t on2avc_cb12_syms[ON2AVC_CB12_CODES] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x00F6, - 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, - 0x00FD, 0x00FE, 0x00FF, 0x0100, 0x0101, 0x0102, - 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, - 0x0109, 0x010A, 0x01F6, 0x01F7, 0x01F8, 0x01F9, - 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF, - 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, - 0x0206, 0x0207, 0x0208, 0x0209, 0x020A, 0x02F6, - 0x02F7, 0x02F8, 0x02F9, 0x02FA, 0x02FB, 0x02FC, - 0x02FD, 0x02FE, 0x02FF, 0x0300, 0x0301, 0x0302, - 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, - 0x0309, 0x030A, 0x03F6, 0x03F7, 0x03F8, 0x03F9, - 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF, - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, - 0x0406, 0x0407, 0x0408, 0x0409, 0x040A, 0x04F6, - 0x04F7, 0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, - 0x04FD, 0x04FE, 0x04FF, 0x0500, 0x0501, 0x0502, - 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 0x0508, - 0x0509, 0x050A, 0x05F6, 0x05F7, 0x05F8, 0x05F9, - 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF, - 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, - 0x0606, 0x0607, 0x0608, 0x0609, 0x060A, 0x06F6, - 0x06F7, 0x06F8, 0x06F9, 0x06FA, 0x06FB, 0x06FC, - 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, - 0x0703, 0x0704, 0x0705, 0x0706, 0x0707, 0x0708, - 0x0709, 0x070A, 0x07F6, 0x07F7, 0x07F8, 0x07F9, - 0x07FA, 0x07FB, 0x07FC, 0x07FD, 0x07FE, 0x07FF, - 0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, - 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x08F6, - 0x08F7, 0x08F8, 0x08F9, 0x08FA, 0x08FB, 0x08FC, - 0x08FD, 0x08FE, 0x08FF, 0x0900, 0x0901, 0x0902, - 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 0x0908, - 0x0909, 0x090A, 0x09F6, 0x09F7, 0x09F8, 0x09F9, - 0x09FA, 0x09FB, 0x09FC, 0x09FD, 0x09FE, 0x09FF, - 0x0A00, 0x0A01, 0x0A02, 0x0A03, 0x0A04, 0x0A05, - 0x0A06, 0x0A07, 0x0A08, 0x0A09, 0x0A0A, 0x0AF6, - 0x0AF7, 0x0AF8, 0x0AF9, 0x0AFA, 0x0AFB, 0x0AFC, - 0x0AFD, 0x0AFE, 0x0AFF, 0xF600, 0xF601, 0xF602, - 0xF603, 0xF604, 0xF605, 0xF606, 0xF607, 0xF608, - 0xF609, 0xF60A, 0xF6F6, 0xF6F7, 0xF6F8, 0xF6F9, - 0xF6FA, 0xF6FB, 0xF6FC, 0xF6FD, 0xF6FE, 0xF6FF, - 0xF700, 0xF701, 0xF702, 0xF703, 0xF704, 0xF705, - 0xF706, 0xF707, 0xF708, 0xF709, 0xF70A, 0xF7F6, - 0xF7F7, 0xF7F8, 0xF7F9, 0xF7FA, 0xF7FB, 0xF7FC, - 0xF7FD, 0xF7FE, 0xF7FF, 0xF800, 0xF801, 0xF802, - 0xF803, 0xF804, 0xF805, 0xF806, 0xF807, 0xF808, - 0xF809, 0xF80A, 0xF8F6, 0xF8F7, 0xF8F8, 0xF8F9, - 0xF8FA, 0xF8FB, 0xF8FC, 0xF8FD, 0xF8FE, 0xF8FF, - 0xF900, 0xF901, 0xF902, 0xF903, 0xF904, 0xF905, - 0xF906, 0xF907, 0xF908, 0xF909, 0xF90A, 0xF9F6, - 0xF9F7, 0xF9F8, 0xF9F9, 0xF9FA, 0xF9FB, 0xF9FC, - 0xF9FD, 0xF9FE, 0xF9FF, 0xFA00, 0xFA01, 0xFA02, - 0xFA03, 0xFA04, 0xFA05, 0xFA06, 0xFA07, 0xFA08, - 0xFA09, 0xFA0A, 0xFAF6, 0xFAF7, 0xFAF8, 0xFAF9, - 0xFAFA, 0xFAFB, 0xFAFC, 0xFAFD, 0xFAFE, 0xFAFF, - 0xFB00, 0xFB01, 0xFB02, 0xFB03, 0xFB04, 0xFB05, - 0xFB06, 0xFB07, 0xFB08, 0xFB09, 0xFB0A, 0xFBF6, - 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, - 0xFBFD, 0xFBFE, 0xFBFF, 0xFC00, 0xFC01, 0xFC02, - 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08, - 0xFC09, 0xFC0A, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, - 0xFCFA, 0xFCFB, 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, - 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04, 0xFD05, - 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFDF6, - 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, - 0xFDFD, 0xFDFE, 0xFDFF, 0xFE00, 0xFE01, 0xFE02, - 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07, 0xFE08, - 0xFE09, 0xFE0A, 0xFEF6, 0xFEF7, 0xFEF8, 0xFEF9, - 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0xFEFF, - 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, - 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFFF6, - 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, - 0xFFFD, 0xFFFE, 0xFFFF, -}; - -#define ON2AVC_CB13_CODES 625 -static const uint16_t on2avc_cb13_codes[ON2AVC_CB13_CODES] = { - 0x0000, 0x0015, 0x008E, 0x0338, 0x09FB, 0x0BEC, - 0x0C61, 0x13E1, 0x18A7, 0x313B, 0x61BB, 0x05D9, - 0x0896, 0x066B, 0x05C6, 0x18A6, 0x40E4, 0x2081, - 0x104F, 0x13E0, 0x0C22, 0x07E4, 0x03F7, 0x0087, - 0x0014, 0x0016, 0x001D, 0x009C, 0x02E2, 0x037E, - 0x0897, 0x0898, 0x0C63, 0x117D, 0x2082, 0x27AA, - 0x033B, 0x06C5, 0x04F2, 0x0331, 0x19EB, 0x18A8, - 0x13E2, 0x0DE7, 0x0C62, 0x06DF, 0x05C7, 0x02F4, - 0x0098, 0x001A, 0x007C, 0x0080, 0x0106, 0x02F5, - 0x03EC, 0x0617, 0x0621, 0x08F9, 0x1050, 0x117F, - 0x11E0, 0x036A, 0x045A, 0x06C6, 0x037F, 0x117E, - 0x2083, 0x0BED, 0x0C9E, 0x0658, 0x04F3, 0x0368, - 0x02EE, 0x00FA, 0x008D, 0x031C, 0x01FF, 0x0206, - 0x031E, 0x06C8, 0x0659, 0x09B5, 0x0C23, 0x0BEF, - 0x0C9F, 0x19EC, 0x04CC, 0x0623, 0x06C7, 0x0622, - 0x313C, 0x17BB, 0x11E1, 0x0C64, 0x0BEE, 0x07DC, - 0x04CB, 0x0375, 0x0205, 0x026E, 0x0C24, 0x06C9, - 0x0324, 0x04DF, 0x0642, 0x09B6, 0x0643, 0x0BF2, - 0x083B, 0x1051, 0x27AB, 0x036C, 0x0607, 0x06E2, - 0x045B, 0x313D, 0x2084, 0x18A9, 0x13E3, 0x0CA0, - 0x0899, 0x066E, 0x06E3, 0x0369, 0x0606, 0x0DE8, - 0x061A, 0x0453, 0x065A, 0x065B, 0x089B, 0x089C, - 0x09FD, 0x0BA5, 0x18AA, 0x11E2, 0x05C8, 0x09B7, - 0x066F, 0x06CA, 0x19ED, 0x2085, 0x2086, 0x0D83, - 0x1052, 0x1053, 0x09FC, 0x089A, 0x0644, 0x083E, - 0x13E4, 0x08FC, 0x0624, 0x1055, 0x0C65, 0x089D, - 0x0645, 0x08FD, 0x0C66, 0x0CA1, 0x1056, 0x05E1, - 0x089E, 0x08FA, 0x07E5, 0x313E, 0x2087, 0x11E3, - 0x19EE, 0x18AB, 0x1054, 0x19EF, 0x17BC, 0x08FB, - 0x07E6, 0x18AD, 0x0BF3, 0x07E7, 0x0C67, 0x1057, - 0x07EA, 0x08FF, 0x1058, 0x0DE9, 0x18AE, 0x19F0, - 0x0608, 0x089F, 0x08FE, 0x06CB, 0x313F, 0x2088, - 0x13E5, 0x3142, 0x11E4, 0x18AC, 0x11E5, 0x0CA2, - 0x065E, 0x13E6, 0x27AD, 0x19F1, 0x0D86, 0x0DEA, - 0x0CA3, 0x0DEB, 0x17BE, 0x0C2A, 0x13E8, 0x0CA6, - 0x0DEE, 0x05FD, 0x0992, 0x0C25, 0x063E, 0x40E5, - 0x11E6, 0x3143, 0x18AF, 0x27AC, 0x0C26, 0x17BD, - 0x13E7, 0x0C27, 0x11E7, 0x27B2, 0x40E8, 0x18B3, - 0x17C0, 0x18FE, 0x19F2, 0x19F3, 0x31FE, 0x17C1, - 0x19F6, 0x0BA6, 0x09FE, 0x0DEF, 0x17BF, 0x0C2B, - 0x40E6, 0x18B0, 0x40E7, 0x13E9, 0x2089, 0x27AE, - 0x27AF, 0x208A, 0x18B1, 0x18B2, 0x27B3, 0xBCEF, - 0x2F3A, 0x40EA, 0x17C5, 0x17C6, 0x17C7, 0x19F7, - 0x133E, 0x105A, 0x17CA, 0x065F, 0x0CA7, 0x0C7E, - 0x1059, 0xBCED, 0x40E9, 0xBCEE, 0x17C2, 0x63FE, - 0x208B, 0x208E, 0x208F, 0x17C3, 0x17C4, 0x0625, - 0x03ED, 0x045C, 0x04CD, 0x05DA, 0x05CE, 0x05FF, - 0x0626, 0x060A, 0x05E3, 0x083F, 0x0BA8, 0x0BA9, - 0x40EB, 0x13EA, 0x0CCA, 0x0BA7, 0x08A2, 0x0646, - 0x0609, 0x05E2, 0x041E, 0x05FE, 0x0373, 0x0376, - 0x099E, 0x05DE, 0x0647, 0x05E6, 0x06D6, 0x07EB, - 0x09FF, 0x1B5E, 0x0BAB, 0x08AE, 0x0C36, 0x0FBA, - 0x17CB, 0x4CFE, 0x105B, 0x0D87, 0x0DAE, 0x13EB, - 0x0BAA, 0x0993, 0x08A3, 0x085E, 0x0600, 0x0601, - 0x05DB, 0x0664, 0x04F0, 0x05F8, 0x0634, 0x085F, - 0x06F6, 0x08F4, 0x0C5A, 0x0CFC, 0x0DDC, 0x09F6, - 0x0C16, 0x115E, 0x13D8, 0x13DA, 0x0C94, 0x0CFA, - 0x082E, 0x0B9E, 0x06C2, 0x0BE4, 0x06DA, 0x05C0, - 0x0614, 0x05C9, 0x05DF, 0x033A, 0x0336, 0x05FA, - 0x04CE, 0x05C1, 0x0890, 0x0891, 0x0838, 0x0839, - 0x0CFD, 0x0BA0, 0x61B8, 0x07DE, 0x0635, 0x0B9F, - 0x0640, 0x06DB, 0x082F, 0x09AC, 0x04C8, 0x0666, - 0x04DE, 0x03F4, 0x0339, 0x2079, 0x267E, 0x179E, - 0x30DE, 0x63FF, 0x27A0, 0x1997, 0x36BF, 0x3EEC, - 0x99FE, 0x99FF, 0x0C95, 0x1048, 0x0C5B, 0x0636, - 0x0C5C, 0x2076, 0x13DB, 0x115F, 0x179C, 0x2077, - 0x1046, 0x36BE, 0x1996, 0x2078, 0x61B9, 0x1175, - 0x17B0, 0x3EED, 0x19E1, 0x19E2, 0x207A, 0x3EEE, - 0xBCEC, 0x3138, 0x3139, 0x07DF, 0x1176, 0x0892, - 0x0667, 0x18A0, 0x18A2, 0x13DC, 0x1174, 0x13DD, - 0x179F, 0x30DF, 0x19E0, 0x18A3, 0x1049, 0x17B2, - 0x207B, 0x17B3, 0x0C17, 0x19E3, 0x17B4, 0x207C, - 0x3EEF, 0x207D, 0x19E4, 0x27A1, 0x0C5F, 0x08F5, - 0x0DDD, 0x0652, 0x18A4, 0x0C96, 0x0C5D, 0x104A, - 0x1177, 0x0CFE, 0x0C5E, 0x0DDE, 0x09F7, 0x17B1, - 0x19E6, 0x0C1E, 0x09AE, 0x1179, 0x0DE0, 0x17B5, - 0x0BA2, 0x17B6, 0x27A3, 0x40E0, 0x40E1, 0x06DC, - 0x09AF, 0x09AD, 0x05C2, 0x19E5, 0x27A2, 0x0DDF, - 0x0C1C, 0x0C1D, 0x0BE6, 0x0BA1, 0x1178, 0x0654, - 0x13DE, 0x40E2, 0x0893, 0x0668, 0x07E1, 0x0BE7, - 0x08F6, 0x0DE1, 0x27A4, 0x104B, 0x19E7, 0x40E3, - 0x05D6, 0x09F9, 0x06DD, 0x04CA, 0x17B7, 0x17B8, - 0x0C97, 0x0C98, 0x07E0, 0x0C99, 0x0655, 0x09F8, - 0x0656, 0x0C9A, 0x0DE2, 0x0669, 0x04D3, 0x061C, - 0x0894, 0x13DF, 0x0C1F, 0x104C, 0x27A6, 0x61BA, - 0x27A7, 0x066A, 0x061D, 0x0637, 0x04D2, 0x27A5, - 0x117A, 0x0C9B, 0x09B0, 0x09B1, 0x05E0, 0x0602, - 0x05FB, 0x04F1, 0x08F7, 0x06FA, 0x0603, 0x037C, - 0x05C3, 0x0BE8, 0x0895, 0x0C60, 0x117B, 0x19E8, - 0x27A8, 0x19E9, 0x0657, 0x083A, 0x06C4, 0x05D7, - 0x17B9, 0x0CFF, 0x0DE3, 0x104D, 0x07E2, 0x0641, - 0x061E, 0x05D8, 0x0366, 0x0616, 0x032E, 0x0268, - 0x02E6, 0x0456, 0x0BA3, 0x06FB, 0x0D80, 0x0DE5, - 0x104E, 0x17BA, 0x27A9, 0x0330, 0x07E3, 0x061F, - 0x0367, 0x207E, 0x0C9C, 0x117C, 0x0DE4, 0x06DE, - 0x0620, 0x0450, 0x042E, 0x02F2, 0x0204, 0x0086, - 0x008C, 0x00FE, 0x022A, 0x0372, 0x05CA, 0x0452, - 0x08F8, 0x0BA4, 0x19EA, 0x18A5, 0x0306, 0x05FC, - 0x03F6, 0x0458, 0x0D81, 0x0BE9, 0x09B2, 0x0C20, - 0x09FA, 0x0604, 0x0370, 0x01FE, 0x010A, 0x0084, - 0x0012, 0x001C, 0x0088, 0x026A, 0x05CB, 0x063B, - 0x09B4, 0x0D82, 0x0DE6, 0x207F, 0x2080, 0x030C, - 0x0605, 0x0459, 0x0374, 0x313A, 0x0C9D, 0x0BEA, - 0x0BEB, 0x0C21, 0x09B3, 0x063A, 0x0216, 0x009D, - 0x001E, -}; - -static const uint8_t on2avc_cb13_bits[ON2AVC_CB13_CODES] = { - 1, 5, 8, 10, 12, 12, - 12, 13, 13, 14, 15, 11, - 12, 11, 11, 13, 15, 14, - 13, 13, 12, 11, 10, 8, - 5, 5, 5, 8, 10, 10, - 12, 12, 12, 13, 14, 14, - 10, 11, 11, 10, 13, 13, - 13, 12, 12, 11, 11, 10, - 8, 5, 7, 8, 9, 10, - 10, 11, 11, 12, 13, 13, - 13, 10, 11, 11, 10, 13, - 14, 12, 12, 11, 11, 10, - 10, 8, 8, 10, 9, 10, - 10, 11, 11, 12, 12, 12, - 12, 13, 11, 11, 11, 11, - 14, 13, 13, 12, 12, 11, - 11, 10, 10, 10, 12, 11, - 10, 11, 11, 12, 11, 12, - 12, 13, 14, 10, 11, 11, - 11, 14, 14, 13, 13, 12, - 12, 11, 11, 10, 11, 12, - 11, 11, 11, 11, 12, 12, - 12, 12, 13, 13, 11, 12, - 11, 11, 13, 14, 14, 12, - 13, 13, 12, 12, 11, 12, - 13, 12, 11, 13, 12, 12, - 11, 12, 12, 12, 13, 11, - 12, 12, 11, 14, 14, 13, - 13, 13, 13, 13, 13, 12, - 11, 13, 12, 11, 12, 13, - 11, 12, 13, 12, 13, 13, - 11, 12, 12, 11, 14, 14, - 13, 14, 13, 13, 13, 12, - 11, 13, 14, 13, 12, 12, - 12, 12, 13, 12, 13, 12, - 12, 11, 12, 12, 11, 15, - 13, 14, 13, 14, 12, 13, - 13, 12, 13, 14, 15, 13, - 13, 13, 13, 13, 14, 13, - 13, 12, 12, 12, 13, 12, - 15, 13, 15, 13, 14, 14, - 14, 14, 13, 13, 14, 16, - 14, 15, 13, 13, 13, 13, - 13, 13, 13, 11, 12, 12, - 13, 16, 15, 16, 13, 15, - 14, 14, 14, 13, 13, 11, - 10, 11, 11, 11, 11, 11, - 11, 11, 11, 12, 12, 12, - 15, 13, 12, 12, 12, 11, - 11, 11, 11, 11, 10, 10, - 12, 11, 11, 11, 11, 11, - 12, 13, 12, 12, 12, 12, - 13, 15, 13, 12, 12, 13, - 12, 12, 12, 12, 11, 11, - 11, 11, 11, 11, 11, 12, - 11, 12, 12, 12, 12, 12, - 12, 13, 13, 13, 12, 12, - 12, 12, 11, 12, 11, 11, - 11, 11, 11, 10, 10, 11, - 11, 11, 12, 12, 12, 12, - 12, 12, 15, 11, 11, 12, - 11, 11, 12, 12, 11, 11, - 11, 10, 10, 14, 14, 13, - 14, 15, 14, 13, 14, 14, - 16, 16, 12, 13, 12, 11, - 12, 14, 13, 13, 13, 14, - 13, 14, 13, 14, 15, 13, - 13, 14, 13, 13, 14, 14, - 16, 14, 14, 11, 13, 12, - 11, 13, 13, 13, 13, 13, - 13, 14, 13, 13, 13, 13, - 14, 13, 12, 13, 13, 14, - 14, 14, 13, 14, 12, 12, - 12, 11, 13, 12, 12, 13, - 13, 12, 12, 12, 12, 13, - 13, 12, 12, 13, 12, 13, - 12, 13, 14, 15, 15, 11, - 12, 12, 11, 13, 14, 12, - 12, 12, 12, 12, 13, 11, - 13, 15, 12, 11, 11, 12, - 12, 12, 14, 13, 13, 15, - 11, 12, 11, 11, 13, 13, - 12, 12, 11, 12, 11, 12, - 11, 12, 12, 11, 11, 11, - 12, 13, 12, 13, 14, 15, - 14, 11, 11, 11, 11, 14, - 13, 12, 12, 12, 11, 11, - 11, 11, 12, 11, 11, 10, - 11, 12, 12, 12, 13, 13, - 14, 13, 11, 12, 11, 11, - 13, 12, 12, 13, 11, 11, - 11, 11, 10, 11, 10, 10, - 10, 11, 12, 11, 12, 12, - 13, 13, 14, 10, 11, 11, - 10, 14, 12, 13, 12, 11, - 11, 11, 11, 10, 10, 8, - 8, 8, 10, 10, 11, 11, - 12, 12, 13, 13, 10, 11, - 10, 11, 12, 12, 12, 12, - 12, 11, 10, 9, 9, 8, - 5, 5, 8, 10, 11, 11, - 12, 12, 12, 14, 14, 10, - 11, 11, 10, 14, 12, 12, - 12, 12, 12, 11, 10, 8, - 5, -}; - -static const uint16_t on2avc_cb13_syms[ON2AVC_CB13_CODES] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, - 0x000C, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, - 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, - 0x00FF, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, - 0x0105, 0x0106, 0x0107, 0x0108, 0x0109, 0x010A, - 0x010B, 0x010C, 0x01F4, 0x01F5, 0x01F6, 0x01F7, - 0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, 0x01FD, - 0x01FE, 0x01FF, 0x0200, 0x0201, 0x0202, 0x0203, - 0x0204, 0x0205, 0x0206, 0x0207, 0x0208, 0x0209, - 0x020A, 0x020B, 0x020C, 0x02F4, 0x02F5, 0x02F6, - 0x02F7, 0x02F8, 0x02F9, 0x02FA, 0x02FB, 0x02FC, - 0x02FD, 0x02FE, 0x02FF, 0x0300, 0x0301, 0x0302, - 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, - 0x0309, 0x030A, 0x030B, 0x030C, 0x03F4, 0x03F5, - 0x03F6, 0x03F7, 0x03F8, 0x03F9, 0x03FA, 0x03FB, - 0x03FC, 0x03FD, 0x03FE, 0x03FF, 0x0400, 0x0401, - 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, - 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x04F4, - 0x04F5, 0x04F6, 0x04F7, 0x04F8, 0x04F9, 0x04FA, - 0x04FB, 0x04FC, 0x04FD, 0x04FE, 0x04FF, 0x0500, - 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, - 0x0507, 0x0508, 0x0509, 0x050A, 0x050B, 0x050C, - 0x05F4, 0x05F5, 0x05F6, 0x05F7, 0x05F8, 0x05F9, - 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF, - 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, - 0x0606, 0x0607, 0x0608, 0x0609, 0x060A, 0x060B, - 0x060C, 0x06F4, 0x06F5, 0x06F6, 0x06F7, 0x06F8, - 0x06F9, 0x06FA, 0x06FB, 0x06FC, 0x06FD, 0x06FE, - 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, - 0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, - 0x070B, 0x070C, 0x07F4, 0x07F5, 0x07F6, 0x07F7, - 0x07F8, 0x07F9, 0x07FA, 0x07FB, 0x07FC, 0x07FD, - 0x07FE, 0x07FF, 0x0800, 0x0801, 0x0802, 0x0803, - 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, - 0x080A, 0x080B, 0x080C, 0x08F4, 0x08F5, 0x08F6, - 0x08F7, 0x08F8, 0x08F9, 0x08FA, 0x08FB, 0x08FC, - 0x08FD, 0x08FE, 0x08FF, 0x0900, 0x0901, 0x0902, - 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 0x0908, - 0x0909, 0x090A, 0x090B, 0x090C, 0x09F4, 0x09F5, - 0x09F6, 0x09F7, 0x09F8, 0x09F9, 0x09FA, 0x09FB, - 0x09FC, 0x09FD, 0x09FE, 0x09FF, 0x0A00, 0x0A01, - 0x0A02, 0x0A03, 0x0A04, 0x0A05, 0x0A06, 0x0A07, - 0x0A08, 0x0A09, 0x0A0A, 0x0A0B, 0x0A0C, 0x0AF4, - 0x0AF5, 0x0AF6, 0x0AF7, 0x0AF8, 0x0AF9, 0x0AFA, - 0x0AFB, 0x0AFC, 0x0AFD, 0x0AFE, 0x0AFF, 0x0B00, - 0x0B01, 0x0B02, 0x0B03, 0x0B04, 0x0B05, 0x0B06, - 0x0B07, 0x0B08, 0x0B09, 0x0B0A, 0x0B0B, 0x0B0C, - 0x0BF4, 0x0BF5, 0x0BF6, 0x0BF7, 0x0BF8, 0x0BF9, - 0x0BFA, 0x0BFB, 0x0BFC, 0x0BFD, 0x0BFE, 0x0BFF, - 0x0C00, 0x0C01, 0x0C02, 0x0C03, 0x0C04, 0x0C05, - 0x0C06, 0x0C07, 0x0C08, 0x0C09, 0x0C0A, 0x0C0B, - 0x0C0C, 0x0CF4, 0x0CF5, 0x0CF6, 0x0CF7, 0x0CF8, - 0x0CF9, 0x0CFA, 0x0CFB, 0x0CFC, 0x0CFD, 0x0CFE, - 0x0CFF, 0xF400, 0xF401, 0xF402, 0xF403, 0xF404, - 0xF405, 0xF406, 0xF407, 0xF408, 0xF409, 0xF40A, - 0xF40B, 0xF40C, 0xF4F4, 0xF4F5, 0xF4F6, 0xF4F7, - 0xF4F8, 0xF4F9, 0xF4FA, 0xF4FB, 0xF4FC, 0xF4FD, - 0xF4FE, 0xF4FF, 0xF500, 0xF501, 0xF502, 0xF503, - 0xF504, 0xF505, 0xF506, 0xF507, 0xF508, 0xF509, - 0xF50A, 0xF50B, 0xF50C, 0xF5F4, 0xF5F5, 0xF5F6, - 0xF5F7, 0xF5F8, 0xF5F9, 0xF5FA, 0xF5FB, 0xF5FC, - 0xF5FD, 0xF5FE, 0xF5FF, 0xF600, 0xF601, 0xF602, - 0xF603, 0xF604, 0xF605, 0xF606, 0xF607, 0xF608, - 0xF609, 0xF60A, 0xF60B, 0xF60C, 0xF6F4, 0xF6F5, - 0xF6F6, 0xF6F7, 0xF6F8, 0xF6F9, 0xF6FA, 0xF6FB, - 0xF6FC, 0xF6FD, 0xF6FE, 0xF6FF, 0xF700, 0xF701, - 0xF702, 0xF703, 0xF704, 0xF705, 0xF706, 0xF707, - 0xF708, 0xF709, 0xF70A, 0xF70B, 0xF70C, 0xF7F4, - 0xF7F5, 0xF7F6, 0xF7F7, 0xF7F8, 0xF7F9, 0xF7FA, - 0xF7FB, 0xF7FC, 0xF7FD, 0xF7FE, 0xF7FF, 0xF800, - 0xF801, 0xF802, 0xF803, 0xF804, 0xF805, 0xF806, - 0xF807, 0xF808, 0xF809, 0xF80A, 0xF80B, 0xF80C, - 0xF8F4, 0xF8F5, 0xF8F6, 0xF8F7, 0xF8F8, 0xF8F9, - 0xF8FA, 0xF8FB, 0xF8FC, 0xF8FD, 0xF8FE, 0xF8FF, - 0xF900, 0xF901, 0xF902, 0xF903, 0xF904, 0xF905, - 0xF906, 0xF907, 0xF908, 0xF909, 0xF90A, 0xF90B, - 0xF90C, 0xF9F4, 0xF9F5, 0xF9F6, 0xF9F7, 0xF9F8, - 0xF9F9, 0xF9FA, 0xF9FB, 0xF9FC, 0xF9FD, 0xF9FE, - 0xF9FF, 0xFA00, 0xFA01, 0xFA02, 0xFA03, 0xFA04, - 0xFA05, 0xFA06, 0xFA07, 0xFA08, 0xFA09, 0xFA0A, - 0xFA0B, 0xFA0C, 0xFAF4, 0xFAF5, 0xFAF6, 0xFAF7, - 0xFAF8, 0xFAF9, 0xFAFA, 0xFAFB, 0xFAFC, 0xFAFD, - 0xFAFE, 0xFAFF, 0xFB00, 0xFB01, 0xFB02, 0xFB03, - 0xFB04, 0xFB05, 0xFB06, 0xFB07, 0xFB08, 0xFB09, - 0xFB0A, 0xFB0B, 0xFB0C, 0xFBF4, 0xFBF5, 0xFBF6, - 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, - 0xFBFD, 0xFBFE, 0xFBFF, 0xFC00, 0xFC01, 0xFC02, - 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08, - 0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFCF4, 0xFCF5, - 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB, - 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, - 0xFD02, 0xFD03, 0xFD04, 0xFD05, 0xFD06, 0xFD07, - 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFDF4, - 0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, - 0xFDFB, 0xFDFC, 0xFDFD, 0xFDFE, 0xFDFF, 0xFE00, - 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 0xFE06, - 0xFE07, 0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, - 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 0xFEF9, - 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0xFEFF, - 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, - 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, - 0xFF0C, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7, 0xFFF8, - 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, - 0xFFFF, -}; - -#define ON2AVC_CB14_CODES 729 -static const uint16_t on2avc_cb14_codes[ON2AVC_CB14_CODES] = { - 0x0000, 0x0018, 0x009C, 0x033F, 0x06CF, 0x0860, - 0x3ED2, 0x15F8, 0x0CA3, 0x15F9, 0x3ED3, 0x3ED4, - 0x3ED5, 0x03B3, 0x0336, 0x3ECF, 0x3ED0, 0x15F5, - 0x15F6, 0x3ED1, 0x1FB6, 0x15F7, 0x0D6D, 0x074E, - 0x02A4, 0x008C, 0x0017, 0x0016, 0x0024, 0x00A8, - 0x02AB, 0x043C, 0x038D, 0x15FA, 0x0CA4, 0x1FB8, - 0x15FB, 0x3ED9, 0x1FB9, 0x15FC, 0x01D8, 0x01F1, - 0x3ED6, 0x1090, 0x1FB7, 0x0D6E, 0x3ED7, 0x3ED8, - 0x074F, 0x0D6F, 0x0750, 0x01F2, 0x0098, 0x0020, - 0x0070, 0x009D, 0x00E4, 0x026F, 0x03AE, 0x055D, - 0x06D0, 0x0862, 0x0667, 0x09ED, 0x1900, 0x3EDA, - 0x1901, 0x01DE, 0x026B, 0x15FD, 0x15FE, 0x1091, - 0x15FF, 0x0D70, 0x0666, 0x0689, 0x0861, 0x034E, - 0x026E, 0x00E8, 0x008E, 0x019E, 0x01BF, 0x01F3, - 0x02B5, 0x054E, 0x0669, 0x09EE, 0x09EF, 0x0D71, - 0x0CA5, 0x1FBB, 0x1FBC, 0x3EDF, 0x02A6, 0x01CA, - 0x3EDB, 0x3EDC, 0x3EDD, 0x3EDE, 0x1FBA, 0x1092, - 0x0863, 0x0751, 0x0668, 0x038E, 0x02B4, 0x01C4, - 0x068A, 0x0CA7, 0x06D1, 0x055F, 0x043E, 0x09F0, - 0x0865, 0x0866, 0x0867, 0x0752, 0x1902, 0x3EE2, - 0x1096, 0x0278, 0x02B6, 0x3EE0, 0x1FBD, 0x3EE1, - 0x0864, 0x1FBE, 0x0CA6, 0x1093, 0x1094, 0x1095, - 0x0478, 0x043D, 0x055E, 0x3EE5, 0x0CA9, 0x066A, - 0x0D75, 0x0560, 0x0561, 0x0868, 0x0D76, 0x0CAA, - 0x0CAB, 0x3EE6, 0x3EE7, 0x3EE8, 0x02AC, 0x038F, - 0x3EE3, 0x1FBF, 0x3EE4, 0x0D72, 0x0D73, 0x0D74, - 0x09F1, 0x068B, 0x0CA8, 0x0479, 0x06D2, 0x1097, - 0x1099, 0x09F3, 0x066B, 0x06D3, 0x0CAD, 0x109A, - 0x06D4, 0x068C, 0x06D5, 0x0D79, 0x0D7A, 0x109B, - 0x1FC1, 0x02B2, 0x0396, 0x3EE9, 0x1903, 0x3EEA, - 0x1904, 0x1905, 0x1FC0, 0x09F2, 0x0D77, 0x0D78, - 0x1098, 0x0562, 0x0CAC, 0x190C, 0x109C, 0x06D6, - 0x0D7C, 0x1FC4, 0x0D7D, 0x09F4, 0x06D7, 0x09F5, - 0x3EEE, 0x0CAE, 0x0D7E, 0x3EEF, 0x03AF, 0x043F, - 0x3EEB, 0x1906, 0x1FC2, 0x1907, 0x3EEC, 0x1908, - 0x1909, 0x190A, 0x1FC3, 0x3EED, 0x0D7B, 0x190B, - 0x1FC6, 0x10A1, 0x10A2, 0x0D7F, 0x0CB0, 0x190E, - 0x0D80, 0x10A3, 0x0869, 0x190F, 0x1910, 0x10A4, - 0x10A5, 0x0753, 0x068D, 0x3EF0, 0x3EF1, 0x190D, - 0x1FC5, 0x3EF2, 0x3EF3, 0x109D, 0x109E, 0x0CAF, - 0x109F, 0x3EF4, 0x10A0, 0x10A7, 0x3EFC, 0x0CB1, - 0x09F7, 0x1911, 0x10A8, 0x09F8, 0x10A9, 0x1912, - 0x06D9, 0x09F9, 0x3EFD, 0x1913, 0x068E, 0x06D8, - 0x3EF5, 0x3EF6, 0x3EF7, 0x3EF8, 0x3EF9, 0x0D81, - 0x3EFA, 0x1FC7, 0x1FC8, 0x10A6, 0x09F6, 0x3EFB, - 0x1FCE, 0x0CB2, 0x3F02, 0x10AA, 0x3F03, 0x1FCF, - 0x10AB, 0x10AC, 0x1916, 0x3F04, 0x09FA, 0x0D83, - 0x3F05, 0x068F, 0x086A, 0x1914, 0x3EFE, 0x1FC9, - 0x1FCA, 0x3EFF, 0x0D82, 0x1FCB, 0x1FCC, 0x3F00, - 0x1FCD, 0x3F01, 0x1915, 0x3F0F, 0x1918, 0x10AD, - 0x0CB3, 0x3F10, 0x1919, 0x3F11, 0x191A, 0x1FD2, - 0x0CB4, 0x0CB5, 0x10AE, 0x191B, 0x047A, 0x06DA, - 0x3F06, 0x3F07, 0x1917, 0x3F08, 0x3F09, 0x3F0A, - 0x3F0B, 0x3F0C, 0x3F0D, 0x3F0E, 0x1FD0, 0x1FD1, - 0x3F18, 0x191F, 0x1FDA, 0x3F19, 0x3F1A, 0x10AF, - 0x3F1B, 0x10B2, 0x1FDB, 0x0D86, 0x0D87, 0x10B3, - 0x0CB6, 0x086B, 0x09FB, 0x3F12, 0x1FD3, 0x1FD4, - 0x3F13, 0x1FD5, 0x191E, 0x1FD6, 0x3F14, 0x3F15, - 0x3F16, 0x1FD7, 0x3F17, 0x033A, 0x01AA, 0x02B8, - 0x01DF, 0x02B9, 0x02BA, 0x086F, 0x03BB, 0x03B2, - 0x046A, 0x066F, 0x08DE, 0x0563, 0x046B, 0x0CB7, - 0x11BE, 0x086E, 0x066E, 0x06DB, 0x047B, 0x03BA, - 0x0A9E, 0x02B7, 0x0340, 0x0264, 0x01CE, 0x01A9, - 0x0265, 0x01A8, 0x0266, 0x02A8, 0x036F, 0x03AB, - 0x037A, 0x04FE, 0x0683, 0x06C4, 0x0C90, 0x065D, - 0x0D3C, 0x0FEC, 0x0436, 0x06C2, 0x0682, 0x0C8E, - 0x055A, 0x033B, 0x065C, 0x0348, 0x03AA, 0x0234, - 0x036E, 0x01F0, 0x01A6, 0x3E86, 0x3E87, 0x153E, - 0x3E88, 0x3E89, 0x0FEF, 0x3E8A, 0x3E8B, 0x3E8C, - 0x3E8D, 0x3E8E, 0x3E8F, 0x3E90, 0x09E4, 0x03AC, - 0x11BF, 0x1F8E, 0x1F8F, 0x0FEE, 0x3E80, 0x3E81, - 0x3E82, 0x3E83, 0x3E84, 0x3E85, 0x1F90, 0x1F91, - 0x3E95, 0x3E96, 0x0C91, 0x3E97, 0x3E98, 0x3E99, - 0x3E9A, 0x3E9B, 0x3E9C, 0x3E9D, 0x3E9E, 0x3E9F, - 0x3EA0, 0x0858, 0x04FF, 0x0FF0, 0x0FF1, 0x153F, - 0x0FF2, 0x3E91, 0x1F92, 0x3E92, 0x1F93, 0x3E93, - 0x1F94, 0x3E94, 0x0D3D, 0x3EA3, 0x1F99, 0x0FF7, - 0x0D3E, 0x3EA4, 0x1F9A, 0x15D9, 0x0D3F, 0x3EA5, - 0x3EA6, 0x3EA7, 0x0D58, 0x3EA8, 0x06C5, 0x072E, - 0x3EA1, 0x1F95, 0x1F96, 0x0C92, 0x0FF3, 0x0FF4, - 0x0FF5, 0x15D8, 0x1F97, 0x0FF6, 0x1F98, 0x3EA2, - 0x3EAC, 0x0FF9, 0x1F9C, 0x15DB, 0x1F9D, 0x15DC, - 0x0FFA, 0x1F9E, 0x3EAD, 0x3EAE, 0x3EAF, 0x3EB0, - 0x3EB1, 0x065E, 0x055B, 0x3EA9, 0x0D59, 0x15DA, - 0x0FF8, 0x3EAA, 0x0D5A, 0x3EAB, 0x0D5B, 0x0D5C, - 0x0D5D, 0x072F, 0x1F9B, 0x3EB4, 0x1FA0, 0x073C, - 0x0D5F, 0x1FA1, 0x1FA2, 0x0FFE, 0x1FA3, 0x1FA4, - 0x3EB5, 0x3EB6, 0x3EB7, 0x3EB8, 0x065F, 0x06C6, - 0x3EB2, 0x15DD, 0x0FFB, 0x3EB3, 0x1F9F, 0x0D5E, - 0x0C93, 0x0C94, 0x0FFC, 0x0FFD, 0x15DE, 0x15DF, - 0x1FA7, 0x15E1, 0x06C7, 0x0D62, 0x15E2, 0x0C96, - 0x15E3, 0x1082, 0x15E4, 0x1FA8, 0x3EBA, 0x3EBB, - 0x3EBC, 0x0660, 0x046E, 0x3EB9, 0x1FA5, 0x0FFF, - 0x1FA6, 0x1080, 0x1081, 0x0D60, 0x0C95, 0x15E0, - 0x0D61, 0x073D, 0x085A, 0x15E6, 0x09E9, 0x085B, - 0x0C97, 0x1083, 0x0C98, 0x0D63, 0x0D64, 0x0C99, - 0x15E7, 0x15E8, 0x1FAC, 0x3EBE, 0x0684, 0x037B, - 0x1FA9, 0x1FAA, 0x3EBD, 0x073E, 0x1FAB, 0x15E5, - 0x06C8, 0x09E5, 0x09E6, 0x09E7, 0x0661, 0x09E8, - 0x1FAE, 0x0C9A, 0x06CA, 0x055C, 0x0C9B, 0x3EC0, - 0x15EB, 0x1085, 0x1086, 0x15EC, 0x1087, 0x3EC1, - 0x3EC2, 0x02A9, 0x02B3, 0x1FAD, 0x15E9, 0x3EBF, - 0x15EA, 0x1084, 0x0D65, 0x0662, 0x0D66, 0x06C9, - 0x0438, 0x054A, 0x073F, 0x085D, 0x0663, 0x0439, - 0x0686, 0x06CB, 0x0C9E, 0x0C9F, 0x1088, 0x15EF, - 0x3EC6, 0x1089, 0x1FAF, 0x3EC7, 0x0349, 0x0267, - 0x3EC3, 0x3EC4, 0x15ED, 0x15EE, 0x3EC5, 0x09EA, - 0x0C9C, 0x0C9D, 0x054B, 0x0685, 0x085C, 0x09EB, - 0x01BC, 0x01DC, 0x01BE, 0x03AD, 0x038A, 0x0749, - 0x0688, 0x0665, 0x074A, 0x0CA1, 0x0D68, 0x3EC8, - 0x1FB1, 0x0236, 0x034A, 0x1FB0, 0x108A, 0x108B, - 0x0CA0, 0x0D67, 0x0687, 0x0748, 0x0664, 0x038B, - 0x023E, 0x01DA, 0x01DB, 0x006E, 0x0094, 0x00E6, - 0x033E, 0x043A, 0x06CD, 0x085E, 0x085F, 0x0D69, - 0x0D6A, 0x1FB3, 0x1FB4, 0x3ECA, 0x034B, 0x023F, - 0x3EC9, 0x108C, 0x1FB2, 0x15F0, 0x15F1, 0x074B, - 0x06CC, 0x074C, 0x038C, 0x0268, 0x0136, 0x0095, - 0x0014, 0x001E, 0x0097, 0x019C, 0x074D, 0x0D6C, - 0x06CE, 0x0CA2, 0x108E, 0x09EC, 0x3ECD, 0x108F, - 0x3ECE, 0x026A, 0x02AA, 0x3ECB, 0x1FB5, 0x15F2, - 0x3ECC, 0x15F3, 0x15F4, 0x0D6B, 0x108D, 0x043B, - 0x0269, 0x0096, 0x0022, -}; - -static const uint8_t on2avc_cb14_bits[ON2AVC_CB14_CODES] = { - 1, 5, 8, 10, 11, 12, - 14, 13, 12, 13, 14, 14, - 14, 10, 10, 14, 14, 13, - 13, 14, 13, 13, 12, 11, - 10, 8, 5, 5, 6, 8, - 10, 11, 10, 13, 12, 13, - 13, 14, 13, 13, 9, 9, - 14, 13, 13, 12, 14, 14, - 11, 12, 11, 9, 8, 6, - 7, 8, 8, 10, 10, 11, - 11, 12, 11, 12, 13, 14, - 13, 9, 10, 13, 13, 13, - 13, 12, 11, 11, 12, 10, - 10, 8, 8, 9, 9, 9, - 10, 11, 11, 12, 12, 12, - 12, 13, 13, 14, 10, 9, - 14, 14, 14, 14, 13, 13, - 12, 11, 11, 10, 10, 9, - 11, 12, 11, 11, 11, 12, - 12, 12, 12, 11, 13, 14, - 13, 10, 10, 14, 13, 14, - 12, 13, 12, 13, 13, 13, - 11, 11, 11, 14, 12, 11, - 12, 11, 11, 12, 12, 12, - 12, 14, 14, 14, 10, 10, - 14, 13, 14, 12, 12, 12, - 12, 11, 12, 11, 11, 13, - 13, 12, 11, 11, 12, 13, - 11, 11, 11, 12, 12, 13, - 13, 10, 10, 14, 13, 14, - 13, 13, 13, 12, 12, 12, - 13, 11, 12, 13, 13, 11, - 12, 13, 12, 12, 11, 12, - 14, 12, 12, 14, 10, 11, - 14, 13, 13, 13, 14, 13, - 13, 13, 13, 14, 12, 13, - 13, 13, 13, 12, 12, 13, - 12, 13, 12, 13, 13, 13, - 13, 11, 11, 14, 14, 13, - 13, 14, 14, 13, 13, 12, - 13, 14, 13, 13, 14, 12, - 12, 13, 13, 12, 13, 13, - 11, 12, 14, 13, 11, 11, - 14, 14, 14, 14, 14, 12, - 14, 13, 13, 13, 12, 14, - 13, 12, 14, 13, 14, 13, - 13, 13, 13, 14, 12, 12, - 14, 11, 12, 13, 14, 13, - 13, 14, 12, 13, 13, 14, - 13, 14, 13, 14, 13, 13, - 12, 14, 13, 14, 13, 13, - 12, 12, 13, 13, 11, 11, - 14, 14, 13, 14, 14, 14, - 14, 14, 14, 14, 13, 13, - 14, 13, 13, 14, 14, 13, - 14, 13, 13, 12, 12, 13, - 12, 12, 12, 14, 13, 13, - 14, 13, 13, 13, 14, 14, - 14, 13, 14, 10, 9, 10, - 9, 10, 10, 12, 10, 10, - 11, 11, 12, 11, 11, 12, - 13, 12, 11, 11, 11, 10, - 12, 10, 10, 10, 9, 9, - 10, 9, 10, 10, 10, 10, - 10, 11, 11, 11, 12, 11, - 12, 12, 11, 11, 11, 12, - 11, 10, 11, 10, 10, 10, - 10, 9, 9, 14, 14, 13, - 14, 14, 12, 14, 14, 14, - 14, 14, 14, 14, 12, 10, - 13, 13, 13, 12, 14, 14, - 14, 14, 14, 14, 13, 13, - 14, 14, 12, 14, 14, 14, - 14, 14, 14, 14, 14, 14, - 14, 12, 11, 12, 12, 13, - 12, 14, 13, 14, 13, 14, - 13, 14, 12, 14, 13, 12, - 12, 14, 13, 13, 12, 14, - 14, 14, 12, 14, 11, 11, - 14, 13, 13, 12, 12, 12, - 12, 13, 13, 12, 13, 14, - 14, 12, 13, 13, 13, 13, - 12, 13, 14, 14, 14, 14, - 14, 11, 11, 14, 12, 13, - 12, 14, 12, 14, 12, 12, - 12, 11, 13, 14, 13, 11, - 12, 13, 13, 12, 13, 13, - 14, 14, 14, 14, 11, 11, - 14, 13, 12, 14, 13, 12, - 12, 12, 12, 12, 13, 13, - 13, 13, 11, 12, 13, 12, - 13, 13, 13, 13, 14, 14, - 14, 11, 11, 14, 13, 12, - 13, 13, 13, 12, 12, 13, - 12, 11, 12, 13, 12, 12, - 12, 13, 12, 12, 12, 12, - 13, 13, 13, 14, 11, 10, - 13, 13, 14, 11, 13, 13, - 11, 12, 12, 12, 11, 12, - 13, 12, 11, 11, 12, 14, - 13, 13, 13, 13, 13, 14, - 14, 10, 10, 13, 13, 14, - 13, 13, 12, 11, 12, 11, - 11, 11, 11, 12, 11, 11, - 11, 11, 12, 12, 13, 13, - 14, 13, 13, 14, 10, 10, - 14, 14, 13, 13, 14, 12, - 12, 12, 11, 11, 12, 12, - 9, 9, 9, 10, 10, 11, - 11, 11, 11, 12, 12, 14, - 13, 10, 10, 13, 13, 13, - 12, 12, 11, 11, 11, 10, - 10, 9, 9, 7, 8, 8, - 10, 11, 11, 12, 12, 12, - 12, 13, 13, 14, 10, 10, - 14, 13, 13, 13, 13, 11, - 11, 11, 10, 10, 9, 8, - 5, 5, 8, 9, 11, 12, - 11, 12, 13, 12, 14, 13, - 14, 10, 10, 14, 13, 13, - 14, 13, 13, 12, 13, 11, - 10, 8, 6, -}; - -static const uint16_t on2avc_cb14_syms[ON2AVC_CB14_CODES] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, - 0x000C, 0x000D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, - 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, - 0x00FD, 0x00FE, 0x00FF, 0x0100, 0x0101, 0x0102, - 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, - 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x01F3, - 0x01F4, 0x01F5, 0x01F6, 0x01F7, 0x01F8, 0x01F9, - 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF, - 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, - 0x0206, 0x0207, 0x0208, 0x0209, 0x020A, 0x020B, - 0x020C, 0x020D, 0x02F3, 0x02F4, 0x02F5, 0x02F6, - 0x02F7, 0x02F8, 0x02F9, 0x02FA, 0x02FB, 0x02FC, - 0x02FD, 0x02FE, 0x02FF, 0x0300, 0x0301, 0x0302, - 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, - 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x03F3, - 0x03F4, 0x03F5, 0x03F6, 0x03F7, 0x03F8, 0x03F9, - 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF, - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, - 0x0406, 0x0407, 0x0408, 0x0409, 0x040A, 0x040B, - 0x040C, 0x040D, 0x04F3, 0x04F4, 0x04F5, 0x04F6, - 0x04F7, 0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, - 0x04FD, 0x04FE, 0x04FF, 0x0500, 0x0501, 0x0502, - 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 0x0508, - 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x05F3, - 0x05F4, 0x05F5, 0x05F6, 0x05F7, 0x05F8, 0x05F9, - 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF, - 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, - 0x0606, 0x0607, 0x0608, 0x0609, 0x060A, 0x060B, - 0x060C, 0x060D, 0x06F3, 0x06F4, 0x06F5, 0x06F6, - 0x06F7, 0x06F8, 0x06F9, 0x06FA, 0x06FB, 0x06FC, - 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, - 0x0703, 0x0704, 0x0705, 0x0706, 0x0707, 0x0708, - 0x0709, 0x070A, 0x070B, 0x070C, 0x070D, 0x07F3, - 0x07F4, 0x07F5, 0x07F6, 0x07F7, 0x07F8, 0x07F9, - 0x07FA, 0x07FB, 0x07FC, 0x07FD, 0x07FE, 0x07FF, - 0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, - 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B, - 0x080C, 0x080D, 0x08F3, 0x08F4, 0x08F5, 0x08F6, - 0x08F7, 0x08F8, 0x08F9, 0x08FA, 0x08FB, 0x08FC, - 0x08FD, 0x08FE, 0x08FF, 0x0900, 0x0901, 0x0902, - 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 0x0908, - 0x0909, 0x090A, 0x090B, 0x090C, 0x090D, 0x09F3, - 0x09F4, 0x09F5, 0x09F6, 0x09F7, 0x09F8, 0x09F9, - 0x09FA, 0x09FB, 0x09FC, 0x09FD, 0x09FE, 0x09FF, - 0x0A00, 0x0A01, 0x0A02, 0x0A03, 0x0A04, 0x0A05, - 0x0A06, 0x0A07, 0x0A08, 0x0A09, 0x0A0A, 0x0A0B, - 0x0A0C, 0x0A0D, 0x0AF3, 0x0AF4, 0x0AF5, 0x0AF6, - 0x0AF7, 0x0AF8, 0x0AF9, 0x0AFA, 0x0AFB, 0x0AFC, - 0x0AFD, 0x0AFE, 0x0AFF, 0x0B00, 0x0B01, 0x0B02, - 0x0B03, 0x0B04, 0x0B05, 0x0B06, 0x0B07, 0x0B08, - 0x0B09, 0x0B0A, 0x0B0B, 0x0B0C, 0x0B0D, 0x0BF3, - 0x0BF4, 0x0BF5, 0x0BF6, 0x0BF7, 0x0BF8, 0x0BF9, - 0x0BFA, 0x0BFB, 0x0BFC, 0x0BFD, 0x0BFE, 0x0BFF, - 0x0C00, 0x0C01, 0x0C02, 0x0C03, 0x0C04, 0x0C05, - 0x0C06, 0x0C07, 0x0C08, 0x0C09, 0x0C0A, 0x0C0B, - 0x0C0C, 0x0C0D, 0x0CF3, 0x0CF4, 0x0CF5, 0x0CF6, - 0x0CF7, 0x0CF8, 0x0CF9, 0x0CFA, 0x0CFB, 0x0CFC, - 0x0CFD, 0x0CFE, 0x0CFF, 0x0D00, 0x0D01, 0x0D02, - 0x0D03, 0x0D04, 0x0D05, 0x0D06, 0x0D07, 0x0D08, - 0x0D09, 0x0D0A, 0x0D0B, 0x0D0C, 0x0D0D, 0x0DF3, - 0x0DF4, 0x0DF5, 0x0DF6, 0x0DF7, 0x0DF8, 0x0DF9, - 0x0DFA, 0x0DFB, 0x0DFC, 0x0DFD, 0x0DFE, 0x0DFF, - 0xF300, 0xF301, 0xF302, 0xF303, 0xF304, 0xF305, - 0xF306, 0xF307, 0xF308, 0xF309, 0xF30A, 0xF30B, - 0xF30C, 0xF30D, 0xF3F3, 0xF3F4, 0xF3F5, 0xF3F6, - 0xF3F7, 0xF3F8, 0xF3F9, 0xF3FA, 0xF3FB, 0xF3FC, - 0xF3FD, 0xF3FE, 0xF3FF, 0xF400, 0xF401, 0xF402, - 0xF403, 0xF404, 0xF405, 0xF406, 0xF407, 0xF408, - 0xF409, 0xF40A, 0xF40B, 0xF40C, 0xF40D, 0xF4F3, - 0xF4F4, 0xF4F5, 0xF4F6, 0xF4F7, 0xF4F8, 0xF4F9, - 0xF4FA, 0xF4FB, 0xF4FC, 0xF4FD, 0xF4FE, 0xF4FF, - 0xF500, 0xF501, 0xF502, 0xF503, 0xF504, 0xF505, - 0xF506, 0xF507, 0xF508, 0xF509, 0xF50A, 0xF50B, - 0xF50C, 0xF50D, 0xF5F3, 0xF5F4, 0xF5F5, 0xF5F6, - 0xF5F7, 0xF5F8, 0xF5F9, 0xF5FA, 0xF5FB, 0xF5FC, - 0xF5FD, 0xF5FE, 0xF5FF, 0xF600, 0xF601, 0xF602, - 0xF603, 0xF604, 0xF605, 0xF606, 0xF607, 0xF608, - 0xF609, 0xF60A, 0xF60B, 0xF60C, 0xF60D, 0xF6F3, - 0xF6F4, 0xF6F5, 0xF6F6, 0xF6F7, 0xF6F8, 0xF6F9, - 0xF6FA, 0xF6FB, 0xF6FC, 0xF6FD, 0xF6FE, 0xF6FF, - 0xF700, 0xF701, 0xF702, 0xF703, 0xF704, 0xF705, - 0xF706, 0xF707, 0xF708, 0xF709, 0xF70A, 0xF70B, - 0xF70C, 0xF70D, 0xF7F3, 0xF7F4, 0xF7F5, 0xF7F6, - 0xF7F7, 0xF7F8, 0xF7F9, 0xF7FA, 0xF7FB, 0xF7FC, - 0xF7FD, 0xF7FE, 0xF7FF, 0xF800, 0xF801, 0xF802, - 0xF803, 0xF804, 0xF805, 0xF806, 0xF807, 0xF808, - 0xF809, 0xF80A, 0xF80B, 0xF80C, 0xF80D, 0xF8F3, - 0xF8F4, 0xF8F5, 0xF8F6, 0xF8F7, 0xF8F8, 0xF8F9, - 0xF8FA, 0xF8FB, 0xF8FC, 0xF8FD, 0xF8FE, 0xF8FF, - 0xF900, 0xF901, 0xF902, 0xF903, 0xF904, 0xF905, - 0xF906, 0xF907, 0xF908, 0xF909, 0xF90A, 0xF90B, - 0xF90C, 0xF90D, 0xF9F3, 0xF9F4, 0xF9F5, 0xF9F6, - 0xF9F7, 0xF9F8, 0xF9F9, 0xF9FA, 0xF9FB, 0xF9FC, - 0xF9FD, 0xF9FE, 0xF9FF, 0xFA00, 0xFA01, 0xFA02, - 0xFA03, 0xFA04, 0xFA05, 0xFA06, 0xFA07, 0xFA08, - 0xFA09, 0xFA0A, 0xFA0B, 0xFA0C, 0xFA0D, 0xFAF3, - 0xFAF4, 0xFAF5, 0xFAF6, 0xFAF7, 0xFAF8, 0xFAF9, - 0xFAFA, 0xFAFB, 0xFAFC, 0xFAFD, 0xFAFE, 0xFAFF, - 0xFB00, 0xFB01, 0xFB02, 0xFB03, 0xFB04, 0xFB05, - 0xFB06, 0xFB07, 0xFB08, 0xFB09, 0xFB0A, 0xFB0B, - 0xFB0C, 0xFB0D, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6, - 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, - 0xFBFD, 0xFBFE, 0xFBFF, 0xFC00, 0xFC01, 0xFC02, - 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08, - 0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFCF3, - 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, - 0xFCFA, 0xFCFB, 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, - 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04, 0xFD05, - 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, - 0xFD0C, 0xFD0D, 0xFDF3, 0xFDF4, 0xFDF5, 0xFDF6, - 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, - 0xFDFD, 0xFDFE, 0xFDFF, 0xFE00, 0xFE01, 0xFE02, - 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07, 0xFE08, - 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFEF3, - 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 0xFEF9, - 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0xFEFF, - 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, - 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, - 0xFF0C, 0xFF0D, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, - 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, - 0xFFFD, 0xFFFE, 0xFFFF, -}; - -#define ON2AVC_CB15_CODES 1089 -static const uint16_t on2avc_cb15_codes[ON2AVC_CB15_CODES] = { - 0x00000, 0x0000A, 0x00064, 0x00104, 0x0034B, 0x0047B, - 0x007D7, 0x00E14, 0x00957, 0x021FD, 0x013B0, 0x03F08, - 0x07A01, 0x0E579, 0x00E15, 0x013A1, 0x003A2, 0x00397, - 0x0137F, 0x01F96, 0x021FC, 0x034CD, 0x01E97, 0x01A82, - 0x013A0, 0x01A83, 0x0089D, 0x00F6B, 0x0076C, 0x0026A, - 0x00118, 0x0006E, 0x00008, 0x0000B, 0x00015, 0x00076, - 0x000EC, 0x001D2, 0x003A6, 0x00716, 0x00726, 0x01F98, - 0x00E77, 0x01BF0, 0x01A84, 0x021FE, 0x021FF, 0x00D93, - 0x01A85, 0x0036E, 0x003B4, 0x00FFE, 0x00FDF, 0x07A02, - 0x065AF, 0x01E98, 0x01F97, 0x00E16, 0x00F30, 0x00CF0, - 0x00846, 0x00398, 0x0020F, 0x000EB, 0x00074, 0x00012, - 0x0007C, 0x00049, 0x0009C, 0x00136, 0x00344, 0x0026D, - 0x0076E, 0x00847, 0x00F6C, 0x00958, 0x01A86, 0x00F6D, - 0x013A3, 0x013B1, 0x009F8, 0x00F31, 0x0032F, 0x00268, - 0x00FE0, 0x0076D, 0x01F99, 0x013A2, 0x03D05, 0x0111A, - 0x00FFF, 0x00CF1, 0x0080D, 0x004FA, 0x0040B, 0x0023E, - 0x0011B, 0x0008E, 0x00077, 0x0010A, 0x000F8, 0x001B0, - 0x001D4, 0x003D9, 0x004C6, 0x006AE, 0x007DE, 0x0080E, - 0x00F33, 0x00E78, 0x01BF1, 0x0111B, 0x034CE, 0x00959, - 0x0111C, 0x00262, 0x001FA, 0x00F32, 0x00FE1, 0x02200, - 0x01F9A, 0x013A4, 0x00E17, 0x00FE2, 0x004B7, 0x00FE3, - 0x00717, 0x00453, 0x00366, 0x001C6, 0x0011A, 0x0010E, - 0x0032B, 0x0023F, 0x00345, 0x0035A, 0x0036F, 0x007B6, - 0x00E19, 0x00705, 0x0076F, 0x0111D, 0x00E79, 0x00D57, - 0x01BF4, 0x01A87, 0x0095B, 0x0095C, 0x00216, 0x0039A, - 0x00F34, 0x0095A, 0x01BF2, 0x01BF3, 0x01000, 0x00F6E, - 0x00F6F, 0x00E18, 0x007DF, 0x008F1, 0x007BE, 0x003BD, - 0x003EB, 0x00342, 0x0022D, 0x00772, 0x007BF, 0x00454, - 0x00455, 0x0071E, 0x004FB, 0x00727, 0x0080F, 0x009E7, - 0x00E7C, 0x01BF6, 0x01A89, 0x01001, 0x01BF7, 0x0089E, - 0x00E1A, 0x0027F, 0x00334, 0x00F35, 0x00F36, 0x01BF5, - 0x01F9B, 0x013A5, 0x00E7A, 0x0095D, 0x00D58, 0x00E7B, - 0x01A88, 0x00FE4, 0x006CE, 0x0040E, 0x00687, 0x006D2, - 0x00E1C, 0x00706, 0x00747, 0x006B6, 0x0084E, 0x00CF2, - 0x006F2, 0x00D59, 0x00CF3, 0x01004, 0x013A6, 0x00F71, - 0x01A8B, 0x01E99, 0x00D5A, 0x00D94, 0x00335, 0x0022E, - 0x0095E, 0x00E1B, 0x01A8A, 0x01BF8, 0x01BF9, 0x01002, - 0x009F9, 0x00F70, 0x01003, 0x00773, 0x00F37, 0x00812, - 0x004D2, 0x004A3, 0x0089F, 0x013A9, 0x013AA, 0x00813, - 0x0081E, 0x00707, 0x008A0, 0x00E1E, 0x00D95, 0x008F2, - 0x009FB, 0x00E7D, 0x00E7E, 0x00F39, 0x01F9C, 0x00CF4, - 0x00F75, 0x00346, 0x0026E, 0x01005, 0x00F72, 0x013A7, - 0x0111E, 0x01BFA, 0x00F73, 0x013A8, 0x00F38, 0x00F74, - 0x009FA, 0x00FE5, 0x0084F, 0x0095F, 0x00E1D, 0x009EA, - 0x01A8D, 0x00E20, 0x00E21, 0x007CE, 0x00D96, 0x01008, - 0x00E22, 0x00960, 0x01121, 0x00E7F, 0x01122, 0x01A8E, - 0x01BFB, 0x01A8F, 0x008A1, 0x01009, 0x0035F, 0x00368, - 0x013B2, 0x01A8C, 0x01F9D, 0x02201, 0x01006, 0x0111F, - 0x013AB, 0x013AC, 0x01120, 0x00F76, 0x01007, 0x009FC, - 0x008F3, 0x00E1F, 0x01E9A, 0x01F9F, 0x013B3, 0x00F3B, - 0x00F77, 0x00F78, 0x00FE7, 0x009FD, 0x00FE8, 0x01123, - 0x00D97, 0x01BFF, 0x00E80, 0x01A93, 0x01124, 0x00D9E, - 0x00D5B, 0x003DA, 0x003A7, 0x00961, 0x01BFC, 0x01F9E, - 0x01BFD, 0x01BFE, 0x01A90, 0x01A91, 0x013AD, 0x00F3A, - 0x01A92, 0x00FE6, 0x00962, 0x0085E, 0x00963, 0x013AE, - 0x03D06, 0x01C01, 0x013B5, 0x00965, 0x01FA2, 0x02202, - 0x009FE, 0x00F79, 0x00F7A, 0x00E23, 0x00E26, 0x00966, - 0x013B1, 0x01E9C, 0x00F7B, 0x008A2, 0x003FE, 0x003AB, - 0x00964, 0x013B4, 0x01C00, 0x01E9B, 0x01FA0, 0x01FA1, - 0x0100A, 0x013AF, 0x03F09, 0x00E81, 0x01A94, 0x01125, - 0x01126, 0x01A95, 0x013B0, 0x03D08, 0x01E9E, 0x01FA3, - 0x013B4, 0x01A99, 0x0100B, 0x013B9, 0x00F3E, 0x00967, - 0x00E27, 0x0100C, 0x01E9F, 0x00968, 0x01C05, 0x00F3F, - 0x00E82, 0x0039B, 0x00386, 0x01A96, 0x01C02, 0x03D07, - 0x013B6, 0x01C03, 0x01E9D, 0x01127, 0x01A97, 0x01C04, - 0x013B2, 0x013B3, 0x013B7, 0x01A98, 0x013B8, 0x03F0A, - 0x0E57A, 0x07A03, 0x013BB, 0x01FA4, 0x01A9C, 0x01FA5, - 0x01FA6, 0x013BC, 0x0100D, 0x01FA7, 0x013B5, 0x0100E, - 0x01A9D, 0x0100F, 0x0096A, 0x01128, 0x00328, 0x003FF, - 0x00969, 0x01EA0, 0x01C06, 0x013BA, 0x01A9A, 0x034CF, - 0x00F7C, 0x02203, 0x034D2, 0x01EA1, 0x01C07, 0x02204, - 0x01A9B, 0x01EA2, 0x06982, 0x03D09, 0x0E57B, 0x01FA8, - 0x013C2, 0x013C3, 0x01129, 0x01FA9, 0x0112A, 0x01010, - 0x01FAA, 0x01EA6, 0x03F0F, 0x013B6, 0x00CF5, 0x0072A, - 0x00F7D, 0x00340, 0x0025F, 0x02205, 0x02206, 0x06983, - 0x01C08, 0x013BD, 0x013BE, 0x01EA3, 0x013BF, 0x034D3, - 0x01EA4, 0x02207, 0x01A9E, 0x01EA5, 0x03F0B, 0x03F0E, - 0x01AA2, 0x00E00, 0x00E3E, 0x00D9F, 0x00D5F, 0x00CF7, - 0x00CFE, 0x01011, 0x00E85, 0x00E01, 0x00E02, 0x0096B, - 0x00CFF, 0x00F92, 0x00D6E, 0x008CA, 0x00359, 0x00456, - 0x01CAE, 0x03D0A, 0x01A9F, 0x0112B, 0x00E83, 0x013B7, - 0x00F7E, 0x009FF, 0x00E84, 0x00FE9, 0x009EB, 0x00F7F, - 0x008A3, 0x00D5E, 0x00CF6, 0x0112E, 0x0112F, 0x01016, - 0x00F93, 0x01FAE, 0x00FEA, 0x00FEB, 0x009A6, 0x00E03, - 0x01C0A, 0x01017, 0x01C0B, 0x01FAF, 0x00F9E, 0x013BB, - 0x0196A, 0x0039C, 0x003F6, 0x0379A, 0x03D0B, 0x01FAB, - 0x01EA7, 0x013B8, 0x01012, 0x01AA3, 0x01C09, 0x013B9, - 0x01013, 0x00CB4, 0x00E86, 0x01F3E, 0x013BA, 0x00E87, - 0x007FB, 0x003CF, 0x0037A, 0x003AD, 0x00387, 0x0038A, - 0x003B5, 0x0039E, 0x0026F, 0x0038B, 0x00272, 0x0039F, - 0x00399, 0x0038E, 0x00252, 0x0039A, 0x00018, 0x0001B, - 0x003CE, 0x00457, 0x003E8, 0x0067E, 0x0041A, 0x003BE, - 0x003BF, 0x003EE, 0x00437, 0x0039D, 0x003AC, 0x00464, - 0x003C6, 0x003C7, 0x0041B, 0x007F6, 0x0042E, 0x0025C, - 0x0038C, 0x003BA, 0x003E9, 0x003EA, 0x00271, 0x003BB, - 0x0026A, 0x0025D, 0x0025E, 0x00389, 0x003EE, 0x004F4, - 0x00415, 0x0001A, 0x00017, 0x00388, 0x0038E, 0x003FC, - 0x00270, 0x00378, 0x0038A, 0x003AE, 0x003AA, 0x00398, - 0x003E8, 0x00358, 0x00414, 0x00384, 0x003B8, 0x006D3, - 0x01A6B, 0x00FEA, 0x01BCE, 0x009E4, 0x00E56, 0x01BCF, - 0x0131D, 0x009E5, 0x01BD8, 0x01BD9, 0x034C0, 0x01F86, - 0x01A6C, 0x01F3F, 0x065AC, 0x072BE, 0x00436, 0x0022C, - 0x009E0, 0x00F54, 0x009E2, 0x01104, 0x01105, 0x00FE8, - 0x009E3, 0x00FE9, 0x00F55, 0x0131C, 0x01A68, 0x01A6A, - 0x00E06, 0x01106, 0x01BCC, 0x00E6E, 0x00E3F, 0x00CB7, - 0x00F28, 0x00702, 0x0094E, 0x00F29, 0x00FEC, 0x00F2A, - 0x0131E, 0x00F56, 0x0131F, 0x00F57, 0x0110A, 0x0134E, - 0x01E86, 0x00712, 0x001F6, 0x0081F, 0x00D6F, 0x00FEB, - 0x01107, 0x00CB6, 0x0094C, 0x01BDA, 0x01108, 0x01109, - 0x009E6, 0x00E6C, 0x01F88, 0x00E6D, 0x00896, 0x0094D, - 0x03F00, 0x01E88, 0x0217C, 0x03F01, 0x03F02, 0x01399, - 0x01E89, 0x0E578, 0x0139A, 0x01E8A, 0x01F8A, 0x01F8B, - 0x01E8B, 0x03D02, 0x01F8C, 0x0139B, 0x00392, 0x0035E, - 0x00F58, 0x009DE, 0x0094F, 0x01358, 0x01359, 0x0135A, - 0x0134F, 0x01BDB, 0x0135B, 0x0379B, 0x01F89, 0x01398, - 0x034C2, 0x065AD, 0x01E87, 0x03F04, 0x07A00, 0x0217D, - 0x01A6D, 0x065AE, 0x01E8C, 0x0217E, 0x01BDD, 0x0135C, - 0x01A6E, 0x034C4, 0x01E8D, 0x03F05, 0x01E8E, 0x0217F, - 0x0139D, 0x003F7, 0x0032C, 0x034C3, 0x00E07, 0x0110B, - 0x009E7, 0x00F59, 0x03D03, 0x00D8A, 0x01F8D, 0x00E6F, - 0x00FED, 0x03F03, 0x00FEE, 0x01BDC, 0x0139C, 0x072BF, - 0x03F06, 0x021F2, 0x01A70, 0x021F3, 0x0135E, 0x0139E, - 0x01F8E, 0x01F8F, 0x0139F, 0x01E91, 0x013A0, 0x0135F, - 0x034C6, 0x0110E, 0x01A71, 0x021F4, 0x0026C, 0x00206, - 0x0110C, 0x009E8, 0x01BDE, 0x00F5A, 0x00FEF, 0x0135D, - 0x00FF0, 0x01E8F, 0x021F0, 0x009E9, 0x01E90, 0x021F1, - 0x01A6F, 0x0110D, 0x034C5, 0x021F5, 0x01A73, 0x01BE2, - 0x01BE3, 0x01F91, 0x01A74, 0x00E70, 0x021F6, 0x034C8, - 0x00FF3, 0x01F92, 0x013A1, 0x013A2, 0x013A3, 0x01A75, - 0x01372, 0x003BC, 0x00341, 0x034C7, 0x00950, 0x00FF1, - 0x00FF2, 0x009EA, 0x00F5B, 0x01370, 0x01BDF, 0x01371, - 0x01A72, 0x01BE0, 0x009EB, 0x01F90, 0x0110F, 0x01BE1, - 0x01E92, 0x013A6, 0x00D8B, 0x00FD8, 0x01BE5, 0x00FF4, - 0x00FF5, 0x01BE6, 0x013A7, 0x00F5F, 0x01BE7, 0x021F7, - 0x021F8, 0x034C9, 0x009EC, 0x013A8, 0x003EF, 0x00269, - 0x00CD8, 0x00FD6, 0x00F5C, 0x013A4, 0x00F5D, 0x00F2B, - 0x00E08, 0x01110, 0x01BE4, 0x00E09, 0x013A5, 0x00F2C, - 0x00898, 0x00F5E, 0x01A76, 0x013A9, 0x00D8C, 0x009DF, - 0x009E0, 0x00FF8, 0x00D8D, 0x01374, 0x01A78, 0x01112, - 0x01BE8, 0x01A79, 0x01F93, 0x01113, 0x01375, 0x00F61, - 0x01376, 0x00399, 0x0027C, 0x009ED, 0x00F60, 0x01373, - 0x01A77, 0x00951, 0x009EE, 0x00D50, 0x00CD9, 0x00FF6, - 0x00FD9, 0x00FF7, 0x00899, 0x007C8, 0x00D52, 0x01111, - 0x009EF, 0x007D3, 0x007D4, 0x0071E, 0x00CDB, 0x00746, - 0x00E0A, 0x00E0B, 0x021F9, 0x00FF9, 0x01A7A, 0x00952, - 0x013AB, 0x01377, 0x009F0, 0x01E93, 0x003AF, 0x0032E, - 0x009E1, 0x007CA, 0x013AA, 0x01114, 0x00F62, 0x00E71, - 0x008CB, 0x008CC, 0x0089A, 0x008CD, 0x00840, 0x00CDA, - 0x007D2, 0x009E2, 0x00E72, 0x00F63, 0x006D6, 0x00841, - 0x0079E, 0x00D53, 0x008CE, 0x00955, 0x00E0C, 0x0137A, - 0x00E74, 0x01115, 0x01F94, 0x01116, 0x01BEA, 0x00E0D, - 0x01A7B, 0x0038D, 0x0033E, 0x00CDC, 0x00D8E, 0x01BE9, - 0x01378, 0x01379, 0x00FDA, 0x00E73, 0x00953, 0x00954, - 0x009E3, 0x004D6, 0x007B7, 0x007BA, 0x007BB, 0x004A0, - 0x0089B, 0x006D7, 0x0047A, 0x00408, 0x007F7, 0x00E0E, - 0x009E4, 0x007D5, 0x00842, 0x00D90, 0x009F1, 0x034CA, - 0x01A7C, 0x01A7D, 0x00E0F, 0x01A7E, 0x00329, 0x0021E, - 0x00F64, 0x01117, 0x021FA, 0x01118, 0x013AC, 0x013AD, - 0x00D8F, 0x008CF, 0x008F0, 0x0071F, 0x004A1, 0x00686, - 0x00426, 0x00416, 0x007CB, 0x003D8, 0x00264, 0x00347, - 0x003DC, 0x004F6, 0x004D7, 0x00F2D, 0x00F65, 0x009F3, - 0x00FDB, 0x00E75, 0x009F4, 0x0137B, 0x013AE, 0x009E5, - 0x00E10, 0x0027E, 0x0020C, 0x00FFA, 0x00956, 0x01BEB, - 0x01E94, 0x01E95, 0x00D91, 0x009F2, 0x00D54, 0x007BC, - 0x007BD, 0x0040A, 0x00385, 0x0036A, 0x0022F, 0x0020E, - 0x000FC, 0x000F2, 0x001AE, 0x001C8, 0x0034A, 0x004F7, - 0x00452, 0x00CDE, 0x00843, 0x00E76, 0x00F2E, 0x00F67, - 0x0137C, 0x01A7F, 0x0080C, 0x00FDC, 0x0021A, 0x001FC, - 0x00E11, 0x009F5, 0x01BEC, 0x00F66, 0x013AF, 0x00CDD, - 0x00E12, 0x00D55, 0x00703, 0x0080A, 0x00394, 0x00265, - 0x001F6, 0x001B6, 0x0010C, 0x00078, 0x0004C, 0x000CC, - 0x001A4, 0x00212, 0x00396, 0x006C4, 0x0089C, 0x00CDF, - 0x01A80, 0x00F68, 0x00FFD, 0x0137D, 0x01F95, 0x00845, - 0x00E13, 0x00267, 0x00266, 0x00FFB, 0x009F6, 0x03D04, - 0x01BED, 0x01BEE, 0x034CB, 0x00FFC, 0x00844, 0x007D6, - 0x00704, 0x003C8, 0x0032A, 0x00130, 0x000CE, 0x00048, - 0x0000C, 0x00014, 0x0007A, 0x000F0, 0x001E6, 0x00417, - 0x004A2, 0x004B6, 0x00D92, 0x01A81, 0x009F7, 0x0137E, - 0x01E96, 0x03F07, 0x009E6, 0x00FDE, 0x003C9, 0x00268, - 0x00F2F, 0x00D56, 0x021FB, 0x034CC, 0x01BEF, 0x00F69, - 0x01119, 0x00F6A, 0x00FDD, 0x007FA, 0x003E6, 0x001E2, - 0x000EA, 0x00072, 0x00016, -}; - -static const uint8_t on2avc_cb15_bits[ON2AVC_CB15_CODES] = { - 2, 5, 7, 9, 10, 11, - 12, 12, 13, 14, 14, 14, - 16, 17, 12, 13, 11, 11, - 13, 13, 14, 14, 14, 13, - 13, 13, 12, 13, 12, 10, - 9, 7, 5, 5, 5, 7, - 9, 10, 11, 11, 12, 13, - 13, 13, 13, 14, 14, 12, - 13, 10, 11, 13, 12, 16, - 15, 14, 13, 12, 12, 12, - 12, 11, 10, 9, 7, 5, - 7, 8, 8, 9, 10, 11, - 12, 12, 13, 13, 13, 13, - 13, 14, 13, 12, 10, 10, - 12, 12, 13, 13, 15, 13, - 13, 12, 12, 11, 11, 10, - 9, 8, 7, 9, 9, 9, - 9, 10, 11, 11, 12, 12, - 12, 13, 13, 13, 14, 13, - 13, 10, 10, 12, 12, 14, - 13, 13, 12, 12, 12, 12, - 11, 11, 10, 10, 9, 9, - 10, 10, 10, 10, 10, 11, - 12, 12, 12, 13, 13, 12, - 13, 13, 13, 13, 10, 10, - 12, 13, 13, 13, 13, 13, - 13, 12, 12, 12, 11, 11, - 10, 10, 10, 12, 11, 11, - 11, 11, 11, 12, 12, 12, - 13, 13, 13, 13, 13, 12, - 12, 10, 10, 12, 12, 13, - 13, 13, 13, 13, 12, 13, - 13, 12, 11, 11, 11, 11, - 12, 12, 12, 11, 12, 12, - 11, 12, 12, 13, 13, 13, - 13, 14, 12, 12, 10, 10, - 13, 12, 13, 13, 13, 13, - 13, 13, 13, 12, 12, 12, - 12, 12, 12, 13, 13, 12, - 12, 12, 12, 12, 12, 12, - 13, 13, 13, 12, 13, 12, - 13, 10, 11, 13, 13, 13, - 13, 13, 13, 13, 12, 13, - 13, 12, 12, 13, 12, 12, - 13, 12, 12, 12, 12, 13, - 12, 13, 13, 13, 13, 13, - 13, 13, 12, 13, 10, 10, - 14, 13, 13, 14, 13, 13, - 13, 13, 13, 13, 13, 13, - 12, 12, 14, 13, 14, 12, - 13, 13, 12, 13, 12, 13, - 12, 13, 13, 13, 13, 12, - 12, 10, 11, 13, 13, 13, - 13, 13, 13, 13, 13, 12, - 13, 12, 13, 12, 13, 13, - 15, 13, 14, 13, 13, 14, - 13, 13, 13, 12, 12, 13, - 13, 14, 13, 12, 10, 10, - 13, 14, 13, 14, 13, 13, - 13, 13, 14, 13, 13, 13, - 13, 13, 13, 15, 14, 13, - 13, 13, 13, 14, 12, 13, - 12, 13, 14, 13, 13, 12, - 13, 10, 11, 13, 13, 15, - 14, 13, 14, 13, 13, 13, - 13, 13, 14, 13, 14, 14, - 17, 16, 14, 13, 13, 13, - 13, 14, 13, 13, 13, 13, - 13, 13, 13, 13, 10, 10, - 13, 14, 13, 14, 13, 14, - 13, 14, 14, 14, 13, 14, - 13, 14, 15, 15, 17, 13, - 14, 14, 13, 13, 13, 13, - 13, 14, 14, 13, 12, 12, - 13, 10, 11, 14, 14, 15, - 13, 14, 14, 14, 14, 14, - 14, 14, 13, 14, 14, 14, - 13, 13, 12, 12, 12, 12, - 12, 13, 13, 13, 13, 13, - 12, 13, 12, 12, 10, 11, - 14, 15, 13, 13, 13, 13, - 13, 13, 13, 12, 12, 13, - 12, 12, 12, 13, 13, 13, - 13, 13, 12, 12, 13, 13, - 13, 13, 13, 13, 13, 13, - 13, 10, 11, 14, 15, 13, - 14, 13, 13, 13, 13, 13, - 13, 12, 13, 14, 13, 13, - 11, 11, 10, 10, 11, 11, - 11, 10, 11, 11, 11, 10, - 11, 11, 11, 11, 5, 6, - 11, 11, 11, 11, 11, 11, - 11, 10, 11, 10, 10, 11, - 11, 11, 11, 11, 11, 11, - 10, 11, 10, 10, 11, 11, - 11, 11, 11, 11, 11, 11, - 11, 6, 5, 11, 10, 10, - 11, 10, 10, 10, 10, 10, - 10, 10, 11, 11, 11, 11, - 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 14, 13, - 13, 14, 15, 16, 11, 10, - 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, - 12, 13, 13, 13, 12, 12, - 12, 12, 13, 12, 13, 12, - 13, 13, 13, 13, 13, 14, - 14, 11, 10, 12, 12, 13, - 13, 12, 13, 13, 13, 13, - 13, 13, 13, 13, 12, 13, - 14, 14, 14, 14, 14, 14, - 14, 17, 14, 14, 13, 13, - 14, 15, 13, 14, 11, 10, - 13, 12, 13, 13, 13, 13, - 14, 13, 13, 14, 13, 14, - 14, 15, 14, 14, 16, 14, - 13, 15, 14, 14, 13, 13, - 13, 14, 14, 14, 14, 14, - 14, 11, 10, 14, 12, 13, - 13, 13, 15, 12, 13, 13, - 13, 14, 13, 13, 14, 16, - 14, 14, 13, 14, 13, 14, - 13, 13, 14, 14, 14, 13, - 14, 13, 13, 14, 11, 10, - 13, 13, 13, 13, 13, 13, - 13, 14, 14, 13, 14, 14, - 13, 13, 14, 14, 13, 13, - 13, 13, 13, 13, 14, 14, - 13, 13, 14, 14, 14, 13, - 13, 11, 10, 14, 13, 13, - 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, - 14, 14, 12, 12, 13, 13, - 13, 13, 14, 13, 13, 14, - 14, 14, 13, 14, 10, 10, - 12, 12, 13, 14, 13, 12, - 12, 13, 13, 12, 14, 12, - 12, 13, 13, 14, 12, 12, - 12, 13, 12, 13, 13, 13, - 13, 13, 13, 13, 13, 13, - 13, 10, 10, 13, 13, 13, - 13, 13, 13, 12, 12, 13, - 12, 13, 12, 12, 12, 13, - 13, 12, 12, 12, 12, 12, - 12, 12, 14, 13, 13, 13, - 14, 13, 13, 14, 10, 10, - 12, 12, 14, 13, 13, 13, - 12, 12, 12, 12, 12, 12, - 12, 12, 13, 13, 11, 12, - 11, 12, 12, 13, 12, 13, - 13, 13, 13, 13, 13, 12, - 13, 10, 10, 12, 12, 13, - 13, 13, 12, 13, 13, 13, - 12, 12, 11, 11, 11, 12, - 12, 11, 11, 11, 11, 12, - 12, 12, 12, 12, 13, 14, - 13, 13, 12, 13, 10, 10, - 13, 13, 14, 13, 14, 14, - 12, 12, 12, 12, 12, 11, - 11, 11, 12, 10, 10, 10, - 10, 11, 12, 12, 13, 13, - 12, 13, 13, 13, 14, 12, - 12, 10, 10, 13, 13, 13, - 14, 14, 12, 13, 12, 11, - 11, 11, 11, 10, 10, 10, - 9, 9, 9, 10, 10, 11, - 11, 12, 12, 13, 12, 13, - 13, 13, 12, 12, 10, 10, - 12, 13, 13, 13, 14, 12, - 12, 12, 12, 12, 11, 10, - 9, 9, 9, 7, 8, 8, - 9, 10, 11, 11, 12, 12, - 13, 13, 13, 13, 13, 12, - 12, 10, 10, 13, 13, 15, - 13, 13, 14, 13, 12, 12, - 12, 10, 10, 9, 8, 8, - 5, 5, 7, 9, 10, 11, - 12, 12, 12, 13, 13, 13, - 14, 14, 12, 12, 10, 11, - 12, 12, 14, 14, 13, 13, - 13, 13, 12, 11, 11, 10, - 9, 7, 5, -}; - -static const uint16_t on2avc_cb15_syms[ON2AVC_CB15_CODES] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, - 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x00F0, - 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, - 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, - 0x00FD, 0x00FE, 0x00FF, 0x0100, 0x0101, 0x0102, - 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, - 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, - 0x010F, 0x0110, 0x01F0, 0x01F1, 0x01F2, 0x01F3, - 0x01F4, 0x01F5, 0x01F6, 0x01F7, 0x01F8, 0x01F9, - 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF, - 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, - 0x0206, 0x0207, 0x0208, 0x0209, 0x020A, 0x020B, - 0x020C, 0x020D, 0x020E, 0x020F, 0x0210, 0x02F0, - 0x02F1, 0x02F2, 0x02F3, 0x02F4, 0x02F5, 0x02F6, - 0x02F7, 0x02F8, 0x02F9, 0x02FA, 0x02FB, 0x02FC, - 0x02FD, 0x02FE, 0x02FF, 0x0300, 0x0301, 0x0302, - 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, - 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, - 0x030F, 0x0310, 0x03F0, 0x03F1, 0x03F2, 0x03F3, - 0x03F4, 0x03F5, 0x03F6, 0x03F7, 0x03F8, 0x03F9, - 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF, - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, - 0x0406, 0x0407, 0x0408, 0x0409, 0x040A, 0x040B, - 0x040C, 0x040D, 0x040E, 0x040F, 0x0410, 0x04F0, - 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, 0x04F6, - 0x04F7, 0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, - 0x04FD, 0x04FE, 0x04FF, 0x0500, 0x0501, 0x0502, - 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 0x0508, - 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x050E, - 0x050F, 0x0510, 0x05F0, 0x05F1, 0x05F2, 0x05F3, - 0x05F4, 0x05F5, 0x05F6, 0x05F7, 0x05F8, 0x05F9, - 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF, - 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, - 0x0606, 0x0607, 0x0608, 0x0609, 0x060A, 0x060B, - 0x060C, 0x060D, 0x060E, 0x060F, 0x0610, 0x06F0, - 0x06F1, 0x06F2, 0x06F3, 0x06F4, 0x06F5, 0x06F6, - 0x06F7, 0x06F8, 0x06F9, 0x06FA, 0x06FB, 0x06FC, - 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, - 0x0703, 0x0704, 0x0705, 0x0706, 0x0707, 0x0708, - 0x0709, 0x070A, 0x070B, 0x070C, 0x070D, 0x070E, - 0x070F, 0x0710, 0x07F0, 0x07F1, 0x07F2, 0x07F3, - 0x07F4, 0x07F5, 0x07F6, 0x07F7, 0x07F8, 0x07F9, - 0x07FA, 0x07FB, 0x07FC, 0x07FD, 0x07FE, 0x07FF, - 0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, - 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B, - 0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x08F0, - 0x08F1, 0x08F2, 0x08F3, 0x08F4, 0x08F5, 0x08F6, - 0x08F7, 0x08F8, 0x08F9, 0x08FA, 0x08FB, 0x08FC, - 0x08FD, 0x08FE, 0x08FF, 0x0900, 0x0901, 0x0902, - 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 0x0908, - 0x0909, 0x090A, 0x090B, 0x090C, 0x090D, 0x090E, - 0x090F, 0x0910, 0x09F0, 0x09F1, 0x09F2, 0x09F3, - 0x09F4, 0x09F5, 0x09F6, 0x09F7, 0x09F8, 0x09F9, - 0x09FA, 0x09FB, 0x09FC, 0x09FD, 0x09FE, 0x09FF, - 0x0A00, 0x0A01, 0x0A02, 0x0A03, 0x0A04, 0x0A05, - 0x0A06, 0x0A07, 0x0A08, 0x0A09, 0x0A0A, 0x0A0B, - 0x0A0C, 0x0A0D, 0x0A0E, 0x0A0F, 0x0A10, 0x0AF0, - 0x0AF1, 0x0AF2, 0x0AF3, 0x0AF4, 0x0AF5, 0x0AF6, - 0x0AF7, 0x0AF8, 0x0AF9, 0x0AFA, 0x0AFB, 0x0AFC, - 0x0AFD, 0x0AFE, 0x0AFF, 0x0B00, 0x0B01, 0x0B02, - 0x0B03, 0x0B04, 0x0B05, 0x0B06, 0x0B07, 0x0B08, - 0x0B09, 0x0B0A, 0x0B0B, 0x0B0C, 0x0B0D, 0x0B0E, - 0x0B0F, 0x0B10, 0x0BF0, 0x0BF1, 0x0BF2, 0x0BF3, - 0x0BF4, 0x0BF5, 0x0BF6, 0x0BF7, 0x0BF8, 0x0BF9, - 0x0BFA, 0x0BFB, 0x0BFC, 0x0BFD, 0x0BFE, 0x0BFF, - 0x0C00, 0x0C01, 0x0C02, 0x0C03, 0x0C04, 0x0C05, - 0x0C06, 0x0C07, 0x0C08, 0x0C09, 0x0C0A, 0x0C0B, - 0x0C0C, 0x0C0D, 0x0C0E, 0x0C0F, 0x0C10, 0x0CF0, - 0x0CF1, 0x0CF2, 0x0CF3, 0x0CF4, 0x0CF5, 0x0CF6, - 0x0CF7, 0x0CF8, 0x0CF9, 0x0CFA, 0x0CFB, 0x0CFC, - 0x0CFD, 0x0CFE, 0x0CFF, 0x0D00, 0x0D01, 0x0D02, - 0x0D03, 0x0D04, 0x0D05, 0x0D06, 0x0D07, 0x0D08, - 0x0D09, 0x0D0A, 0x0D0B, 0x0D0C, 0x0D0D, 0x0D0E, - 0x0D0F, 0x0D10, 0x0DF0, 0x0DF1, 0x0DF2, 0x0DF3, - 0x0DF4, 0x0DF5, 0x0DF6, 0x0DF7, 0x0DF8, 0x0DF9, - 0x0DFA, 0x0DFB, 0x0DFC, 0x0DFD, 0x0DFE, 0x0DFF, - 0x0E00, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, - 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, - 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, 0x0E10, 0x0EF0, - 0x0EF1, 0x0EF2, 0x0EF3, 0x0EF4, 0x0EF5, 0x0EF6, - 0x0EF7, 0x0EF8, 0x0EF9, 0x0EFA, 0x0EFB, 0x0EFC, - 0x0EFD, 0x0EFE, 0x0EFF, 0x0F00, 0x0F01, 0x0F02, - 0x0F03, 0x0F04, 0x0F05, 0x0F06, 0x0F07, 0x0F08, - 0x0F09, 0x0F0A, 0x0F0B, 0x0F0C, 0x0F0D, 0x0F0E, - 0x0F0F, 0x0F10, 0x0FF0, 0x0FF1, 0x0FF2, 0x0FF3, - 0x0FF4, 0x0FF5, 0x0FF6, 0x0FF7, 0x0FF8, 0x0FF9, - 0x0FFA, 0x0FFB, 0x0FFC, 0x0FFD, 0x0FFE, 0x0FFF, - 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, - 0x1006, 0x1007, 0x1008, 0x1009, 0x100A, 0x100B, - 0x100C, 0x100D, 0x100E, 0x100F, 0x1010, 0x10F0, - 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, - 0x10F7, 0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, - 0x10FD, 0x10FE, 0x10FF, 0xF000, 0xF001, 0xF002, - 0xF003, 0xF004, 0xF005, 0xF006, 0xF007, 0xF008, - 0xF009, 0xF00A, 0xF00B, 0xF00C, 0xF00D, 0xF00E, - 0xF00F, 0xF010, 0xF0F0, 0xF0F1, 0xF0F2, 0xF0F3, - 0xF0F4, 0xF0F5, 0xF0F6, 0xF0F7, 0xF0F8, 0xF0F9, - 0xF0FA, 0xF0FB, 0xF0FC, 0xF0FD, 0xF0FE, 0xF0FF, - 0xF100, 0xF101, 0xF102, 0xF103, 0xF104, 0xF105, - 0xF106, 0xF107, 0xF108, 0xF109, 0xF10A, 0xF10B, - 0xF10C, 0xF10D, 0xF10E, 0xF10F, 0xF110, 0xF1F0, - 0xF1F1, 0xF1F2, 0xF1F3, 0xF1F4, 0xF1F5, 0xF1F6, - 0xF1F7, 0xF1F8, 0xF1F9, 0xF1FA, 0xF1FB, 0xF1FC, - 0xF1FD, 0xF1FE, 0xF1FF, 0xF200, 0xF201, 0xF202, - 0xF203, 0xF204, 0xF205, 0xF206, 0xF207, 0xF208, - 0xF209, 0xF20A, 0xF20B, 0xF20C, 0xF20D, 0xF20E, - 0xF20F, 0xF210, 0xF2F0, 0xF2F1, 0xF2F2, 0xF2F3, - 0xF2F4, 0xF2F5, 0xF2F6, 0xF2F7, 0xF2F8, 0xF2F9, - 0xF2FA, 0xF2FB, 0xF2FC, 0xF2FD, 0xF2FE, 0xF2FF, - 0xF300, 0xF301, 0xF302, 0xF303, 0xF304, 0xF305, - 0xF306, 0xF307, 0xF308, 0xF309, 0xF30A, 0xF30B, - 0xF30C, 0xF30D, 0xF30E, 0xF30F, 0xF310, 0xF3F0, - 0xF3F1, 0xF3F2, 0xF3F3, 0xF3F4, 0xF3F5, 0xF3F6, - 0xF3F7, 0xF3F8, 0xF3F9, 0xF3FA, 0xF3FB, 0xF3FC, - 0xF3FD, 0xF3FE, 0xF3FF, 0xF400, 0xF401, 0xF402, - 0xF403, 0xF404, 0xF405, 0xF406, 0xF407, 0xF408, - 0xF409, 0xF40A, 0xF40B, 0xF40C, 0xF40D, 0xF40E, - 0xF40F, 0xF410, 0xF4F0, 0xF4F1, 0xF4F2, 0xF4F3, - 0xF4F4, 0xF4F5, 0xF4F6, 0xF4F7, 0xF4F8, 0xF4F9, - 0xF4FA, 0xF4FB, 0xF4FC, 0xF4FD, 0xF4FE, 0xF4FF, - 0xF500, 0xF501, 0xF502, 0xF503, 0xF504, 0xF505, - 0xF506, 0xF507, 0xF508, 0xF509, 0xF50A, 0xF50B, - 0xF50C, 0xF50D, 0xF50E, 0xF50F, 0xF510, 0xF5F0, - 0xF5F1, 0xF5F2, 0xF5F3, 0xF5F4, 0xF5F5, 0xF5F6, - 0xF5F7, 0xF5F8, 0xF5F9, 0xF5FA, 0xF5FB, 0xF5FC, - 0xF5FD, 0xF5FE, 0xF5FF, 0xF600, 0xF601, 0xF602, - 0xF603, 0xF604, 0xF605, 0xF606, 0xF607, 0xF608, - 0xF609, 0xF60A, 0xF60B, 0xF60C, 0xF60D, 0xF60E, - 0xF60F, 0xF610, 0xF6F0, 0xF6F1, 0xF6F2, 0xF6F3, - 0xF6F4, 0xF6F5, 0xF6F6, 0xF6F7, 0xF6F8, 0xF6F9, - 0xF6FA, 0xF6FB, 0xF6FC, 0xF6FD, 0xF6FE, 0xF6FF, - 0xF700, 0xF701, 0xF702, 0xF703, 0xF704, 0xF705, - 0xF706, 0xF707, 0xF708, 0xF709, 0xF70A, 0xF70B, - 0xF70C, 0xF70D, 0xF70E, 0xF70F, 0xF710, 0xF7F0, - 0xF7F1, 0xF7F2, 0xF7F3, 0xF7F4, 0xF7F5, 0xF7F6, - 0xF7F7, 0xF7F8, 0xF7F9, 0xF7FA, 0xF7FB, 0xF7FC, - 0xF7FD, 0xF7FE, 0xF7FF, 0xF800, 0xF801, 0xF802, - 0xF803, 0xF804, 0xF805, 0xF806, 0xF807, 0xF808, - 0xF809, 0xF80A, 0xF80B, 0xF80C, 0xF80D, 0xF80E, - 0xF80F, 0xF810, 0xF8F0, 0xF8F1, 0xF8F2, 0xF8F3, - 0xF8F4, 0xF8F5, 0xF8F6, 0xF8F7, 0xF8F8, 0xF8F9, - 0xF8FA, 0xF8FB, 0xF8FC, 0xF8FD, 0xF8FE, 0xF8FF, - 0xF900, 0xF901, 0xF902, 0xF903, 0xF904, 0xF905, - 0xF906, 0xF907, 0xF908, 0xF909, 0xF90A, 0xF90B, - 0xF90C, 0xF90D, 0xF90E, 0xF90F, 0xF910, 0xF9F0, - 0xF9F1, 0xF9F2, 0xF9F3, 0xF9F4, 0xF9F5, 0xF9F6, - 0xF9F7, 0xF9F8, 0xF9F9, 0xF9FA, 0xF9FB, 0xF9FC, - 0xF9FD, 0xF9FE, 0xF9FF, 0xFA00, 0xFA01, 0xFA02, - 0xFA03, 0xFA04, 0xFA05, 0xFA06, 0xFA07, 0xFA08, - 0xFA09, 0xFA0A, 0xFA0B, 0xFA0C, 0xFA0D, 0xFA0E, - 0xFA0F, 0xFA10, 0xFAF0, 0xFAF1, 0xFAF2, 0xFAF3, - 0xFAF4, 0xFAF5, 0xFAF6, 0xFAF7, 0xFAF8, 0xFAF9, - 0xFAFA, 0xFAFB, 0xFAFC, 0xFAFD, 0xFAFE, 0xFAFF, - 0xFB00, 0xFB01, 0xFB02, 0xFB03, 0xFB04, 0xFB05, - 0xFB06, 0xFB07, 0xFB08, 0xFB09, 0xFB0A, 0xFB0B, - 0xFB0C, 0xFB0D, 0xFB0E, 0xFB0F, 0xFB10, 0xFBF0, - 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6, - 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, - 0xFBFD, 0xFBFE, 0xFBFF, 0xFC00, 0xFC01, 0xFC02, - 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08, - 0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, - 0xFC0F, 0xFC10, 0xFCF0, 0xFCF1, 0xFCF2, 0xFCF3, - 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, - 0xFCFA, 0xFCFB, 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, - 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04, 0xFD05, - 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, - 0xFD0C, 0xFD0D, 0xFD0E, 0xFD0F, 0xFD10, 0xFDF0, - 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4, 0xFDF5, 0xFDF6, - 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, - 0xFDFD, 0xFDFE, 0xFDFF, 0xFE00, 0xFE01, 0xFE02, - 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07, 0xFE08, - 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, - 0xFE0F, 0xFE10, 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, - 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 0xFEF9, - 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0xFEFF, - 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, - 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, - 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F, 0xFF10, 0xFFF0, - 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, - 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, - 0xFFFD, 0xFFFE, 0xFFFF, -}; - -const uint32_t * const ff_on2avc_quad_cb_codes[] = { - on2avc_cb1_codes, on2avc_cb2_codes, on2avc_cb3_codes, on2avc_cb4_codes, - on2avc_cb5_codes, on2avc_cb6_codes, on2avc_cb7_codes, on2avc_cb8_codes -}; - -const uint8_t * const ff_on2avc_quad_cb_bits[] = { - on2avc_cb1_bits, on2avc_cb2_bits, on2avc_cb3_bits, on2avc_cb4_bits, - on2avc_cb5_bits, on2avc_cb6_bits, on2avc_cb7_bits, on2avc_cb8_bits -}; - -const uint16_t * const ff_on2avc_quad_cb_syms[] = { - on2avc_cb1_syms, on2avc_cb2_syms, on2avc_cb3_syms, on2avc_cb4_syms, - on2avc_cb5_syms, on2avc_cb6_syms, on2avc_cb7_syms, on2avc_cb8_syms -}; - -const int ff_on2avc_quad_cb_elems[] = { - ON2AVC_CB1_CODES, ON2AVC_CB2_CODES, ON2AVC_CB3_CODES, ON2AVC_CB4_CODES, - ON2AVC_CB5_CODES, ON2AVC_CB6_CODES, ON2AVC_CB7_CODES, ON2AVC_CB8_CODES, -}; - -const uint16_t * const ff_on2avc_pair_cb_codes[] = { - on2avc_cb9_codes, on2avc_cb10_codes, on2avc_cb11_codes, on2avc_cb12_codes, - on2avc_cb13_codes, on2avc_cb14_codes, on2avc_cb15_codes -}; - -const uint8_t * const ff_on2avc_pair_cb_bits[] = { - on2avc_cb9_bits, on2avc_cb10_bits, on2avc_cb11_bits, on2avc_cb12_bits, - on2avc_cb13_bits, on2avc_cb14_bits, on2avc_cb15_bits -}; - -const uint16_t * const ff_on2avc_pair_cb_syms[] = { - on2avc_cb9_syms, on2avc_cb10_syms, on2avc_cb11_syms, on2avc_cb12_syms, - on2avc_cb13_syms, on2avc_cb14_syms, on2avc_cb15_syms -}; - -const int ff_on2avc_pair_cb_elems[] = { - ON2AVC_CB9_CODES, ON2AVC_CB10_CODES, ON2AVC_CB11_CODES, ON2AVC_CB12_CODES, - ON2AVC_CB13_CODES, ON2AVC_CB14_CODES, ON2AVC_CB15_CODES, +const int ff_on2avc_cb_elems[] = { + ON2AVC_CB_1_2_CODES, ON2AVC_CB_1_2_CODES, ON2AVC_CB_3_4_CODES, + ON2AVC_CB_3_4_CODES, ON2AVC_CB_5_6_CODES, ON2AVC_CB_5_6_CODES, + ON2AVC_CB_7_8_CODES, ON2AVC_CB_7_8_CODES, ON2AVC_CB_9_10_CODES, + ON2AVC_CB_9_10_CODES, ON2AVC_CB_11_CODES, ON2AVC_CB_12_CODES, + ON2AVC_CB_13_CODES, ON2AVC_CB_14_CODES, ON2AVC_CB_15_CODES }; const float ff_on2avc_window_long_32000[1024] = { diff --git a/libavcodec/on2avcdata.h b/libavcodec/on2avcdata.h index dc7833fef..c5e7c80b6 100644 --- a/libavcodec/on2avcdata.h +++ b/libavcodec/on2avcdata.h @@ -38,17 +38,12 @@ extern const On2AVCMode ff_on2avc_modes_40[8]; extern const On2AVCMode ff_on2avc_modes_44[8]; #define ON2AVC_SCALE_DIFFS 121 -extern const uint32_t ff_on2avc_scale_diff_codes[]; -extern const uint8_t ff_on2avc_scale_diff_bits[]; +extern const uint8_t ff_on2avc_scale_diff_syms[]; +extern const uint8_t ff_on2avc_scale_diff_bits[]; -extern const uint32_t * const ff_on2avc_quad_cb_codes[]; -extern const uint8_t * const ff_on2avc_quad_cb_bits[]; -extern const uint16_t * const ff_on2avc_quad_cb_syms[]; -extern const int ff_on2avc_quad_cb_elems[]; -extern const uint16_t * const ff_on2avc_pair_cb_codes[]; -extern const uint8_t * const ff_on2avc_pair_cb_bits[]; -extern const uint16_t * const ff_on2avc_pair_cb_syms[]; -extern const int ff_on2avc_pair_cb_elems[]; +extern const uint8_t ff_on2avc_cb_lens[]; +extern const uint16_t ff_on2avc_cb_syms[]; +extern const int ff_on2avc_cb_elems[]; extern const float ff_on2avc_window_long_32000[1024]; extern const float ff_on2avc_window_long_24000[1024]; diff --git a/libavcodec/options.c b/libavcodec/options.c index 7706a0329..61689b48d 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -53,6 +53,7 @@ static void *codec_child_next(void *obj, void *prev) return NULL; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *codec_child_class_next(const AVClass *prev) { void *iter = NULL; @@ -69,6 +70,17 @@ static const AVClass *codec_child_class_next(const AVClass *prev) return c->priv_class; return NULL; } +#endif + +static const AVClass *codec_child_class_iterate(void **iter) +{ + const AVCodec *c; + /* find next codec with priv options */ + while (c = av_codec_iterate(iter)) + if (c->priv_class) + return c->priv_class; + return NULL; +} static AVClassCategory get_category(void *ptr) { @@ -84,7 +96,10 @@ static const AVClass av_codec_context_class = { .version = LIBAVUTIL_VERSION_INT, .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset), .child_next = codec_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = codec_child_class_next, +#endif + .child_class_iterate = codec_child_class_iterate, .category = AV_CLASS_CATEGORY_ENCODER, .get_category = get_category, }; @@ -115,6 +130,7 @@ static int init_context_defaults(AVCodecContext *s, const AVCodec *codec) s->pkt_timebase = (AVRational){ 0, 1 }; s->get_buffer2 = avcodec_default_get_buffer2; s->get_format = avcodec_default_get_format; + s->get_encode_buffer = avcodec_default_get_encode_buffer; s->execute = avcodec_default_execute; s->execute2 = avcodec_default_execute2; s->sample_aspect_ratio = (AVRational){0,1}; @@ -297,6 +313,7 @@ const AVClass *avcodec_get_class(void) return &av_codec_context_class; } +#if FF_API_GET_FRAME_CLASS #define FOFFSET(x) offsetof(AVFrame,x) static const AVOption frame_options[]={ @@ -323,6 +340,7 @@ const AVClass *avcodec_get_frame_class(void) { return &av_frame_class; } +#endif #define SROFFSET(x) offsetof(AVSubtitleRect,x) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 8ba137f51..e12159f73 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -83,6 +83,7 @@ static const AVOption avcodec_options[] = { {"mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_MVS}, INT_MIN, INT_MAX, V|D, "export_side_data"}, {"prft", "export Producer Reference Time through packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_PRFT}, INT_MIN, INT_MAX, A|V|S|E, "export_side_data"}, {"venc_params", "export video encoding parameters through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS}, INT_MIN, INT_MAX, V|D, "export_side_data"}, +{"film_grain", "export film grain parameters through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_FILM_GRAIN}, INT_MIN, INT_MAX, V|D, "export_side_data"}, {"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, INT_MAX}, {"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E}, {"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, @@ -139,15 +140,15 @@ static const AVOption avcodec_options[] = { {"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, {"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, A|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 = 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"}, -{"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, 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 | AV_EF_CAREFUL }, 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 | AV_EF_COMPLIANT | AV_EF_CAREFUL}, 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|S|D|E, "err_detect"}, +{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"}, +{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"}, +{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"}, +{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"}, +{"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, A|V|S|D|E, "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|S|D|E, "err_detect"}, +{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT | AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"}, +{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE | AV_EF_COMPLIANT | AV_EF_CAREFUL}, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"}, {"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, {"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, #if FF_API_PRIVATE_OPT @@ -207,9 +208,6 @@ static const AVOption avcodec_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"}, {"green_metadata", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_GREEN_MD }, 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"}, @@ -217,10 +215,6 @@ static const AVOption avcodec_options[] = { {"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"}, {"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"}, {"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"}, -#if FF_API_DEBUG_MV -{"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"}, -#endif {"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|A|D, "debug"}, {"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"}, @@ -264,8 +258,8 @@ static const AVOption avcodec_options[] = { {"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, "avctx.profile"}, {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "avctx.profile"}, {"main10", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_HEVC_MAIN_10 }, INT_MIN, INT_MAX, V|E, "avctx.profile"}, -{"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, -{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, +{"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, "avctx.level"}, +{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "avctx.level"}, {"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D}, #if FF_API_PRIVATE_OPT {"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, @@ -381,21 +375,24 @@ static const AVOption avcodec_options[] = { {"bt2020_12bit", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, {"smpte428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, {"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "colorspace_type"}, -{"rgb", "RGB", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"fcc", "FCC", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"ycgco", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"bt2020nc", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"bt2020c", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"smpte2085", "SMPTE 2085", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE2085 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"ycocg", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"rgb", "RGB", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"fcc", "FCC", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ycgco", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020nc", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020c", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte2085", "SMPTE 2085", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE2085 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"chroma-derived-nc", "Chroma-derived NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_CHROMA_DERIVED_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"chroma-derived-c", "Chroma-derived CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_CHROMA_DERIVED_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ictcp", "ICtCp", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_ICTCP }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ycocg", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX, V|E|D, "color_range_type"}, {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, {"tv", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, @@ -444,7 +441,9 @@ static const AVOption avcodec_options[] = { #if FF_API_ASS_TIMING {"ass_with_timings", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, INT_MIN, INT_MAX, S|D, "sub_text_format"}, #endif +#if FF_API_OLD_ENCDEC {"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, A|V|D }, +#endif #if FF_API_SIDEDATA_ONLY_PKT {"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, A|V|E }, #endif diff --git a/libavcodec/opus.h b/libavcodec/opus.h index 63ecd0aff..b73949a81 100644 --- a/libavcodec/opus.h +++ b/libavcodec/opus.h @@ -28,6 +28,7 @@ #include "libavutil/audio_fifo.h" #include "libavutil/float_dsp.h" #include "libavutil/frame.h" +#include "libavutil/mem_internal.h" #include "libswresample/swresample.h" @@ -101,6 +102,15 @@ typedef struct OpusStreamContext { AVCodecContext *avctx; int output_channels; + /* number of decoded samples for this stream */ + int decoded_samples; + /* current output buffers for this stream */ + float *out[2]; + int out_size; + /* Buffer with samples from this stream for synchronizing + * the streams when they have different resampling delays */ + AVAudioFifo *sync_buffer; + OpusRangeCoder rc; OpusRangeCoder redundancy_rc; SilkContext *silk; @@ -115,9 +125,9 @@ typedef struct OpusStreamContext { DECLARE_ALIGNED(32, float, redundancy_buf)[2][960]; float *redundancy_output[2]; - /* data buffers for the final output data */ - float *out[2]; - int out_size; + /* buffers for the next samples to be decoded */ + float *cur_out[2]; + int remaining_out_size; float *out_dummy; int out_dummy_allocated_size; @@ -154,15 +164,6 @@ typedef struct OpusContext { OpusStreamContext *streams; int apply_phase_inv; - /* current output buffers for each streams */ - float **out; - int *out_size; - /* Buffers for synchronizing the streams when they have different - * resampling delays */ - AVAudioFifo **sync_buffers; - /* number of decoded samples for each stream */ - int *decoded_samples; - int nb_streams; int nb_stereo_streams; diff --git a/libavcodec/opus_celt.h b/libavcodec/opus_celt.h index 7c1c5316b..661ca251d 100644 --- a/libavcodec/opus_celt.h +++ b/libavcodec/opus_celt.h @@ -33,6 +33,7 @@ #include "mdct15.h" #include "libavutil/float_dsp.h" #include "libavutil/libm.h" +#include "libavutil/mem_internal.h" #define CELT_VECTORS 11 #define CELT_ALLOC_STEPS 6 diff --git a/libavcodec/opus_pvq.h b/libavcodec/opus_pvq.h index 52f9a4e6d..b30407f5a 100644 --- a/libavcodec/opus_pvq.h +++ b/libavcodec/opus_pvq.h @@ -23,6 +23,8 @@ #ifndef AVCODEC_OPUS_PVQ_H #define AVCODEC_OPUS_PVQ_H +#include "libavutil/mem_internal.h" + #include "opus_celt.h" #define QUANT_FN(name) uint32_t (name)(struct CeltPVQ *pvq, CeltFrame *f, \ diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c index 03086dea9..f0d7ed62a 100644 --- a/libavcodec/opusdec.c +++ b/libavcodec/opusdec.c @@ -87,7 +87,7 @@ static int opus_flush_resample(OpusStreamContext *s, int nb_samples) int celt_size = av_audio_fifo_size(s->celt_delay); int ret, i; ret = swr_convert(s->swr, - (uint8_t**)s->out, nb_samples, + (uint8_t**)s->cur_out, nb_samples, NULL, 0); if (ret < 0) return ret; @@ -104,7 +104,7 @@ static int opus_flush_resample(OpusStreamContext *s, int nb_samples) } av_audio_fifo_read(s->celt_delay, (void**)s->celt_output, nb_samples); for (i = 0; i < s->output_channels; i++) { - s->fdsp->vector_fmac_scalar(s->out[i], + s->fdsp->vector_fmac_scalar(s->cur_out[i], s->celt_output[i], 1.0, nb_samples); } @@ -112,15 +112,15 @@ static int opus_flush_resample(OpusStreamContext *s, int nb_samples) if (s->redundancy_idx) { for (i = 0; i < s->output_channels; i++) - opus_fade(s->out[i], s->out[i], + opus_fade(s->cur_out[i], s->cur_out[i], s->redundancy_output[i] + 120 + s->redundancy_idx, ff_celt_window2 + s->redundancy_idx, 120 - s->redundancy_idx); s->redundancy_idx = 0; } - s->out[0] += nb_samples; - s->out[1] += nb_samples; - s->out_size -= nb_samples * sizeof(float); + s->cur_out[0] += nb_samples; + s->cur_out[1] += nb_samples; + s->remaining_out_size -= nb_samples * sizeof(float); return 0; } @@ -199,7 +199,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size return samples; } samples = swr_convert(s->swr, - (uint8_t**)s->out, s->packet.frame_duration, + (uint8_t**)s->cur_out, s->packet.frame_duration, (const uint8_t**)s->silk_output, samples); if (samples < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error resampling SILK data.\n"); @@ -240,7 +240,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size /* decode the CELT frame */ if (s->packet.mode == OPUS_MODE_CELT || s->packet.mode == OPUS_MODE_HYBRID) { - float *out_tmp[2] = { s->out[0], s->out[1] }; + float *out_tmp[2] = { s->cur_out[0], s->cur_out[1] }; float **dst = (s->packet.mode == OPUS_MODE_CELT) ? out_tmp : s->celt_output; int celt_output_samples = samples; @@ -295,7 +295,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size if (s->redundancy_idx) { for (i = 0; i < s->output_channels; i++) - opus_fade(s->out[i], s->out[i], + opus_fade(s->cur_out[i], s->cur_out[i], s->redundancy_output[i] + 120 + s->redundancy_idx, ff_celt_window2 + s->redundancy_idx, 120 - s->redundancy_idx); s->redundancy_idx = 0; @@ -308,8 +308,8 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size return ret; for (i = 0; i < s->output_channels; i++) { - opus_fade(s->out[i] + samples - 120 + delayed_samples, - s->out[i] + samples - 120 + delayed_samples, + opus_fade(s->cur_out[i] + samples - 120 + delayed_samples, + s->cur_out[i] + samples - 120 + delayed_samples, s->redundancy_output[i] + 120, ff_celt_window2, 120 - delayed_samples); if (delayed_samples) @@ -317,10 +317,10 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size } } else { for (i = 0; i < s->output_channels; i++) { - memcpy(s->out[i] + delayed_samples, s->redundancy_output[i], 120 * sizeof(float)); - opus_fade(s->out[i] + 120 + delayed_samples, + memcpy(s->cur_out[i] + delayed_samples, s->redundancy_output[i], 120 * sizeof(float)); + opus_fade(s->cur_out[i] + 120 + delayed_samples, s->redundancy_output[i] + 120, - s->out[i] + 120 + delayed_samples, + s->cur_out[i] + 120 + delayed_samples, ff_celt_window2, 120); } } @@ -331,16 +331,15 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size static int opus_decode_subpacket(OpusStreamContext *s, const uint8_t *buf, int buf_size, - float **out, int out_size, int nb_samples) { int output_samples = 0; int flush_needed = 0; int i, j, ret; - s->out[0] = out[0]; - s->out[1] = out[1]; - s->out_size = out_size; + s->cur_out[0] = s->out[0]; + s->cur_out[1] = s->out[1]; + s->remaining_out_size = s->out_size; /* check if we need to flush the resampler */ if (swr_is_initialized(s->swr)) { @@ -357,15 +356,16 @@ static int opus_decode_subpacket(OpusStreamContext *s, return 0; /* use dummy output buffers if the channel is not mapped to anything */ - if (!s->out[0] || - (s->output_channels == 2 && !s->out[1])) { - av_fast_malloc(&s->out_dummy, &s->out_dummy_allocated_size, s->out_size); + if (!s->cur_out[0] || + (s->output_channels == 2 && !s->cur_out[1])) { + av_fast_malloc(&s->out_dummy, &s->out_dummy_allocated_size, + s->remaining_out_size); if (!s->out_dummy) return AVERROR(ENOMEM); - if (!s->out[0]) - s->out[0] = s->out_dummy; - if (!s->out[1]) - s->out[1] = s->out_dummy; + if (!s->cur_out[0]) + s->cur_out[0] = s->out_dummy; + if (!s->cur_out[1]) + s->cur_out[1] = s->out_dummy; } /* flush the resampler if necessary */ @@ -394,19 +394,19 @@ static int opus_decode_subpacket(OpusStreamContext *s, return samples; for (j = 0; j < s->output_channels; j++) - memset(s->out[j], 0, s->packet.frame_duration * sizeof(float)); + memset(s->cur_out[j], 0, s->packet.frame_duration * sizeof(float)); samples = s->packet.frame_duration; } output_samples += samples; for (j = 0; j < s->output_channels; j++) - s->out[j] += samples; - s->out_size -= samples * sizeof(float); + s->cur_out[j] += samples; + s->remaining_out_size -= samples * sizeof(float); } finish: - s->out[0] = s->out[1] = NULL; - s->out_size = 0; + s->cur_out[0] = s->cur_out[1] = NULL; + s->remaining_out_size = 0; return output_samples; } @@ -429,7 +429,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, s->out[0] = s->out[1] = NULL; delayed_samples = FFMAX(delayed_samples, - s->delayed_samples + av_audio_fifo_size(c->sync_buffers[i])); + s->delayed_samples + av_audio_fifo_size(s->sync_buffer)); } /* decode the header of the first sub-packet to find out the sample count */ @@ -458,17 +458,17 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, return ret; frame->nb_samples = 0; - memset(c->out, 0, c->nb_streams * 2 * sizeof(*c->out)); for (i = 0; i < avctx->channels; i++) { ChannelMap *map = &c->channel_maps[i]; if (!map->copy) - c->out[2 * map->stream_idx + map->channel_idx] = (float*)frame->extended_data[i]; + c->streams[map->stream_idx].out[map->channel_idx] = (float*)frame->extended_data[i]; } /* read the data from the sync buffers */ for (i = 0; i < c->nb_streams; i++) { - float **out = c->out + 2 * i; - int sync_size = av_audio_fifo_size(c->sync_buffers[i]); + OpusStreamContext *s = &c->streams[i]; + float **out = s->out; + int sync_size = av_audio_fifo_size(s->sync_buffer); float sync_dummy[32]; int out_dummy = (!out[0]) | ((!out[1]) << 1); @@ -480,7 +480,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, if (out_dummy && sync_size > FF_ARRAY_ELEMS(sync_dummy)) return AVERROR_BUG; - ret = av_audio_fifo_read(c->sync_buffers[i], (void**)out, sync_size); + ret = av_audio_fifo_read(s->sync_buffer, (void**)out, sync_size); if (ret < 0) return ret; @@ -493,7 +493,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, else out[1] += ret; - c->out_size[i] = frame->linesize[0] - ret * sizeof(float); + s->out_size = frame->linesize[0] - ret * sizeof(float); } /* decode each sub-packet */ @@ -516,10 +516,10 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, } ret = opus_decode_subpacket(&c->streams[i], buf, s->packet.data_size, - c->out + 2 * i, c->out_size[i], coded_samples); + coded_samples); if (ret < 0) return ret; - c->decoded_samples[i] = ret; + s->decoded_samples = ret; decoded_samples = FFMIN(decoded_samples, ret); buf += s->packet.packet_size; @@ -528,13 +528,14 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, /* buffer the extra samples */ for (i = 0; i < c->nb_streams; i++) { - int buffer_samples = c->decoded_samples[i] - decoded_samples; + OpusStreamContext *s = &c->streams[i]; + int buffer_samples = s->decoded_samples - decoded_samples; if (buffer_samples) { - float *buf[2] = { c->out[2 * i + 0] ? c->out[2 * i + 0] : (float*)frame->extended_data[0], - c->out[2 * i + 1] ? c->out[2 * i + 1] : (float*)frame->extended_data[0] }; + float *buf[2] = { s->out[0] ? s->out[0] : (float*)frame->extended_data[0], + s->out[1] ? s->out[1] : (float*)frame->extended_data[0] }; buf[0] += decoded_samples; buf[1] += decoded_samples; - ret = av_audio_fifo_write(c->sync_buffers[i], (void**)buf, buffer_samples); + ret = av_audio_fifo_write(s->sync_buffer, (void**)buf, buffer_samples); if (ret < 0) return ret; } @@ -576,11 +577,10 @@ static av_cold void opus_decode_flush(AVCodecContext *ctx) memset(&s->packet, 0, sizeof(s->packet)); s->delayed_samples = 0; - if (s->celt_delay) - av_audio_fifo_drain(s->celt_delay, av_audio_fifo_size(s->celt_delay)); + av_audio_fifo_drain(s->celt_delay, av_audio_fifo_size(s->celt_delay)); swr_close(s->swr); - av_audio_fifo_drain(c->sync_buffers[i], av_audio_fifo_size(c->sync_buffers[i])); + av_audio_fifo_drain(s->sync_buffer, av_audio_fifo_size(s->sync_buffer)); ff_silk_flush(s->silk); ff_celt_flush(s->celt); @@ -601,21 +601,13 @@ static av_cold int opus_decode_close(AVCodecContext *avctx) av_freep(&s->out_dummy); s->out_dummy_allocated_size = 0; + av_audio_fifo_free(s->sync_buffer); av_audio_fifo_free(s->celt_delay); swr_free(&s->swr); } av_freep(&c->streams); - if (c->sync_buffers) { - for (i = 0; i < c->nb_streams; i++) - av_audio_fifo_free(c->sync_buffers[i]); - } - av_freep(&c->sync_buffers); - av_freep(&c->decoded_samples); - av_freep(&c->out); - av_freep(&c->out_size); - c->nb_streams = 0; av_freep(&c->channel_maps); @@ -638,21 +630,14 @@ static av_cold int opus_decode_init(AVCodecContext *avctx) /* find out the channel configuration */ ret = ff_opus_parse_extradata(avctx, c); - if (ret < 0) { - av_freep(&c->fdsp); + if (ret < 0) return ret; - } /* allocate and init each independent decoder */ c->streams = av_mallocz_array(c->nb_streams, sizeof(*c->streams)); - c->out = av_mallocz_array(c->nb_streams, 2 * sizeof(*c->out)); - c->out_size = av_mallocz_array(c->nb_streams, sizeof(*c->out_size)); - c->sync_buffers = av_mallocz_array(c->nb_streams, sizeof(*c->sync_buffers)); - c->decoded_samples = av_mallocz_array(c->nb_streams, sizeof(*c->decoded_samples)); - if (!c->streams || !c->sync_buffers || !c->decoded_samples || !c->out || !c->out_size) { + if (!c->streams) { c->nb_streams = 0; - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } for (i = 0; i < c->nb_streams; i++) { @@ -673,7 +658,7 @@ static av_cold int opus_decode_init(AVCodecContext *avctx) s->swr =swr_alloc(); if (!s->swr) - goto fail; + return AVERROR(ENOMEM); layout = (s->output_channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; av_opt_set_int(s->swr, "in_sample_fmt", avctx->sample_fmt, 0); @@ -685,31 +670,24 @@ static av_cold int opus_decode_init(AVCodecContext *avctx) ret = ff_silk_init(avctx, &s->silk, s->output_channels); if (ret < 0) - goto fail; + return ret; ret = ff_celt_init(avctx, &s->celt, s->output_channels, c->apply_phase_inv); if (ret < 0) - goto fail; + return ret; s->celt_delay = av_audio_fifo_alloc(avctx->sample_fmt, s->output_channels, 1024); - if (!s->celt_delay) { - ret = AVERROR(ENOMEM); - goto fail; - } + if (!s->celt_delay) + return AVERROR(ENOMEM); - c->sync_buffers[i] = av_audio_fifo_alloc(avctx->sample_fmt, - s->output_channels, 32); - if (!c->sync_buffers[i]) { - ret = AVERROR(ENOMEM); - goto fail; - } + s->sync_buffer = av_audio_fifo_alloc(avctx->sample_fmt, + s->output_channels, 32); + if (!s->sync_buffer) + return AVERROR(ENOMEM); } return 0; -fail: - opus_decode_close(avctx); - return ret; } #define OFFSET(x) offsetof(OpusContext, x) @@ -737,5 +715,6 @@ AVCodec ff_opus_decoder = { .close = opus_decode_close, .decode = opus_decode_packet, .flush = opus_decode_flush, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c index 953749af3..8bc9e9dc4 100644 --- a/libavcodec/opusenc.c +++ b/libavcodec/opusenc.c @@ -25,6 +25,7 @@ #include "opustab.h" #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "internal.h" #include "bytestream.h" diff --git a/libavcodec/opusenc_psy.h b/libavcodec/opusenc_psy.h index b91e4f1b8..d4fb096a3 100644 --- a/libavcodec/opusenc_psy.h +++ b/libavcodec/opusenc_psy.h @@ -22,6 +22,8 @@ #ifndef AVCODEC_OPUSENC_PSY_H #define AVCODEC_OPUSENC_PSY_H +#include "libavutil/mem_internal.h" + #include "opusenc.h" #include "opusenc_utils.h" #include "libavfilter/window_func.h" diff --git a/libavcodec/opustab.c b/libavcodec/opustab.c index 64070f829..b23ca4fea 100644 --- a/libavcodec/opustab.c +++ b/libavcodec/opustab.c @@ -20,6 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mem_internal.h" + #include "opustab.h" const uint8_t ff_opus_default_coupled_streams[] = { 0, 1, 1, 2, 2, 2, 2, 3 }; @@ -950,7 +952,7 @@ const uint16_t ff_celt_qn_exp2[] = { 16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048 }; -const uint32_t ff_celt_pvq_u[1272] = { +static const uint32_t celt_pvq_u[1272] = { /* N = 0, K = 0...176 */ 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, @@ -1130,7 +1132,7 @@ DECLARE_ALIGNED(32, static const float, ff_celt_window_padded)[136] = { 1.00000000f, 1.00000000f, 1.00000000f, }; -const float *ff_celt_window = &ff_celt_window_padded[8]; +const float *const ff_celt_window = &ff_celt_window_padded[8]; /* square of the window, used for the postfilter */ const float ff_celt_window2[120] = { @@ -1153,9 +1155,9 @@ const float ff_celt_window2[120] = { }; const uint32_t * const ff_celt_pvq_u_row[15] = { - ff_celt_pvq_u + 0, ff_celt_pvq_u + 176, ff_celt_pvq_u + 351, - ff_celt_pvq_u + 525, ff_celt_pvq_u + 698, ff_celt_pvq_u + 870, - ff_celt_pvq_u + 1041, ff_celt_pvq_u + 1131, ff_celt_pvq_u + 1178, - ff_celt_pvq_u + 1207, ff_celt_pvq_u + 1226, ff_celt_pvq_u + 1240, - ff_celt_pvq_u + 1248, ff_celt_pvq_u + 1254, ff_celt_pvq_u + 1257 + celt_pvq_u + 0, celt_pvq_u + 176, celt_pvq_u + 351, + celt_pvq_u + 525, celt_pvq_u + 698, celt_pvq_u + 870, + celt_pvq_u + 1041, celt_pvq_u + 1131, celt_pvq_u + 1178, + celt_pvq_u + 1207, celt_pvq_u + 1226, celt_pvq_u + 1240, + celt_pvq_u + 1248, celt_pvq_u + 1254, celt_pvq_u + 1257 }; diff --git a/libavcodec/opustab.h b/libavcodec/opustab.h index 892126bb2..452583794 100644 --- a/libavcodec/opustab.h +++ b/libavcodec/opustab.h @@ -152,12 +152,11 @@ extern const uint8_t ff_celt_bit_deinterleave[]; extern const uint8_t ff_celt_hadamard_order[]; extern const uint16_t ff_celt_qn_exp2[]; -extern const uint32_t ff_celt_pvq_u[1272]; extern const float ff_celt_postfilter_taps[3][3]; extern const float ff_celt_window2[120]; -extern const float *ff_celt_window; +extern const float *const ff_celt_window; extern const uint32_t * const ff_celt_pvq_u_row[15]; diff --git a/libavcodec/packet.h b/libavcodec/packet.h index 41485f452..ca18ae631 100644 --- a/libavcodec/packet.h +++ b/libavcodec/packet.h @@ -282,6 +282,14 @@ enum AVPacketSideDataType { */ AV_PKT_DATA_DOVI_CONF, + /** + * Timecode which conforms to SMPTE ST 12-1:2014. The data is an array of 4 uint32_t + * where the first uint32_t describes how many (1-3) of the other timecodes are used. + * The timecode format is described in the documentation of av_timecode_get_smpte_from_framenum() + * function in libavutil/timecode.h. + */ + AV_PKT_DATA_S12M_TIMECODE, + /** * The number of side data types. * This is not part of the public API/ABI in the sense that it may @@ -297,7 +305,11 @@ enum AVPacketSideDataType { typedef struct AVPacketSideData { uint8_t *data; +#if FF_API_BUFFER_SIZE_T int size; +#else + size_t size; +#endif enum AVPacketSideDataType type; } AVPacketSideData; @@ -311,10 +323,6 @@ typedef struct AVPacketSideData { * packets, with no compressed data, containing only side data * (e.g. to update some stream parameters at the end of encoding). * - * AVPacket is one of the few structs in FFmpeg, whose size is a part of public - * ABI. Thus it may be allocated on stack and no new fields can be added to it - * without libavcodec and libavformat major bump. - * * The semantics of data ownership depends on the buf field. * If it is set, the packet data is dynamically allocated and is * valid indefinitely until a call to av_packet_unref() reduces the @@ -326,6 +334,12 @@ typedef struct AVPacketSideData { * The side data is always allocated with av_malloc(), copied by * av_packet_ref() and freed by av_packet_unref(). * + * sizeof(AVPacket) being a part of the public ABI is deprecated. once + * av_init_packet() is removed, new packets will only be able to be allocated + * with av_packet_alloc(), and new fields may be added to the end of the struct + * with a minor bump. + * + * @see av_packet_alloc * @see av_packet_ref * @see av_packet_unref */ @@ -385,6 +399,14 @@ typedef struct AVPacket { #endif } AVPacket; +#if FF_API_INIT_PACKET +attribute_deprecated +typedef struct AVPacketList { + AVPacket pkt; + struct AVPacketList *next; +} AVPacketList; +#endif + #define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe #define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted /** @@ -447,6 +469,7 @@ AVPacket *av_packet_clone(const AVPacket *src); */ void av_packet_free(AVPacket **pkt); +#if FF_API_INIT_PACKET /** * Initialize optional fields of a packet with default values. * @@ -454,8 +477,16 @@ void av_packet_free(AVPacket **pkt); * initialized separately. * * @param pkt packet + * + * @see av_packet_alloc + * @see av_packet_unref + * + * @deprecated This function is deprecated. Once it's removed, + sizeof(AVPacket) will not be a part of the ABI anymore. */ +attribute_deprecated void av_init_packet(AVPacket *pkt); +#endif /** * Allocate the payload of a packet and initialize its fields with @@ -546,7 +577,11 @@ void av_free_packet(AVPacket *pkt); * @return pointer to fresh allocated data or NULL otherwise */ uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, +#if FF_API_BUFFER_SIZE_T int size); +#else + size_t size); +#endif /** * Wrap an existing array as a packet side data. @@ -573,18 +608,27 @@ int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, * @return 0 on success, < 0 on failure */ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, +#if FF_API_BUFFER_SIZE_T int size); +#else + size_t size); +#endif /** * Get side information from packet. * * @param pkt packet * @param type desired side information type - * @param size pointer for side information size to store (optional) + * @param size If supplied, *size will be set to the size of the side data + * or to zero if the desired side data is not present. * @return pointer to data if present or NULL otherwise */ uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, +#if FF_API_BUFFER_SIZE_T int *size); +#else + size_t *size); +#endif #if FF_API_MERGE_SD_API attribute_deprecated @@ -603,7 +647,11 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type); * @param size pointer to store the size of the returned data * @return pointer to data if successful, NULL otherwise */ +#if FF_API_BUFFER_SIZE_T uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size); +#else +uint8_t *av_packet_pack_dictionary(AVDictionary *dict, size_t *size); +#endif /** * Unpack a dictionary from side_data. * @@ -612,8 +660,12 @@ uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size); * @param dict the metadata storage dictionary * @return 0 on success, < 0 on failure */ +#if FF_API_BUFFER_SIZE_T int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict); - +#else +int av_packet_unpack_dictionary(const uint8_t *data, size_t size, + AVDictionary **dict); +#endif /** * Convenience function to free all the side data stored. diff --git a/libavcodec/packet_internal.h b/libavcodec/packet_internal.h index cdb9a27f2..b1d91f634 100644 --- a/libavcodec/packet_internal.h +++ b/libavcodec/packet_internal.h @@ -23,6 +23,52 @@ #include "packet.h" +typedef struct PacketList { + AVPacket pkt; + struct PacketList *next; +} PacketList; + +/** + * Append an AVPacket to the list. + * + * @param head List head element + * @param tail List tail element + * @param pkt The packet being appended. The data described in it will + * be made reference counted if it isn't already. + * @param copy A callback to copy the contents of the packet to the list. + May be null, in which case the packet's reference will be + moved to the list. + * @return 0 on success, negative AVERROR value on failure. On failure, + the packet and the list are unchanged. + */ +int avpriv_packet_list_put(PacketList **head, PacketList **tail, + AVPacket *pkt, + int (*copy)(AVPacket *dst, const AVPacket *src), + int flags); + +/** + * Remove the oldest AVPacket in the list and return it. + * + * @note The pkt will be overwritten completely on success. The caller + * owns the packet and must unref it by itself. + * + * @param head List head element + * @param tail List tail element + * @param pkt Pointer to an AVPacket struct + * @return 0 on success, and a packet is returned. AVERROR(EAGAIN) if + * the list was empty. + */ +int avpriv_packet_list_get(PacketList **head, PacketList **tail, + AVPacket *pkt); + +/** + * Wipe the list and unref all the packets in it. + * + * @param head List head element + * @param tail List tail element + */ +void avpriv_packet_list_free(PacketList **head, PacketList **tail); + int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type); int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp); diff --git a/libavcodec/pafaudio.c b/libavcodec/pafaudio.c index 12f473ae0..f306e3b96 100644 --- a/libavcodec/pafaudio.c +++ b/libavcodec/pafaudio.c @@ -79,4 +79,5 @@ AVCodec ff_paf_audio_decoder = { .init = paf_audio_init, .decode = paf_audio_decode, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/pafvideo.c b/libavcodec/pafvideo.c index 07fa05caf..1e5d89133 100644 --- a/libavcodec/pafvideo.c +++ b/libavcodec/pafvideo.c @@ -104,10 +104,8 @@ static av_cold int paf_video_init(AVCodecContext *avctx) c->video_size = avctx->width * avctx->height; for (i = 0; i < 4; i++) { c->frame[i] = av_mallocz(c->frame_size); - if (!c->frame[i]) { - paf_video_close(avctx); + if (!c->frame[i]) return AVERROR(ENOMEM); - } } return 0; @@ -419,4 +417,5 @@ AVCodec ff_paf_video_decoder = { .close = paf_video_close, .decode = paf_video_decode, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/parser.c b/libavcodec/parser.c index a63f532c4..11c41d6a0 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -179,6 +179,9 @@ int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, /* offset of the next frame */ s->next_frame_offset = s->cur_offset + index; s->fetch_timestamp = 1; + } else { + /* Don't return a pointer to dummy_buf. */ + *poutbuf = NULL; } if (index < 0) index = 0; @@ -186,6 +189,7 @@ int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, return index; } +#if FF_API_PARSER_CHANGE int av_parser_change(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe) @@ -220,7 +224,7 @@ int av_parser_change(AVCodecParserContext *s, AVCodecContext *avctx, return 0; } - +#endif void av_parser_close(AVCodecParserContext *s) { if (s) { diff --git a/libavcodec/parsers.c b/libavcodec/parsers.c index 7d75cea83..3d944f522 100644 --- a/libavcodec/parsers.c +++ b/libavcodec/parsers.c @@ -21,6 +21,7 @@ #include "libavutil/thread.h" #include "avcodec.h" +#include "version.h" extern AVCodecParser ff_aac_parser; extern AVCodecParser ff_aac_latm_parser; @@ -28,12 +29,15 @@ extern AVCodecParser ff_ac3_parser; extern AVCodecParser ff_adx_parser; extern AVCodecParser ff_av1_parser; extern AVCodecParser ff_avs2_parser; +extern AVCodecParser ff_avs3_parser; extern AVCodecParser ff_bmp_parser; extern AVCodecParser ff_cavsvideo_parser; extern AVCodecParser ff_cook_parser; +extern AVCodecParser ff_cri_parser; extern AVCodecParser ff_dca_parser; extern AVCodecParser ff_dirac_parser; extern AVCodecParser ff_dnxhd_parser; +extern AVCodecParser ff_dolby_e_parser; extern AVCodecParser ff_dpx_parser; extern AVCodecParser ff_dvaudio_parser; extern AVCodecParser ff_dvbsub_parser; @@ -48,6 +52,7 @@ extern AVCodecParser ff_h261_parser; extern AVCodecParser ff_h263_parser; extern AVCodecParser ff_h264_parser; extern AVCodecParser ff_hevc_parser; +extern AVCodecParser ff_ipu_parser; extern AVCodecParser ff_jpeg2000_parser; extern AVCodecParser ff_mjpeg_parser; extern AVCodecParser ff_mlp_parser; @@ -68,10 +73,13 @@ extern AVCodecParser ff_vp3_parser; extern AVCodecParser ff_vp8_parser; extern AVCodecParser ff_vp9_parser; extern AVCodecParser ff_webp_parser; +extern AVCodecParser ff_xbm_parser; extern AVCodecParser ff_xma_parser; #include "libavcodec/parser_list.c" +#if FF_API_NEXT +FF_DISABLE_DEPRECATION_WARNINGS static AVOnce av_parser_next_init = AV_ONCE_INIT; static void av_parser_init_next(void) @@ -95,6 +103,13 @@ AVCodecParser *av_parser_next(const AVCodecParser *p) return (AVCodecParser*)parser_list[0]; } +void av_register_codec_parser(AVCodecParser *parser) +{ + ff_thread_once(&av_parser_next_init, av_parser_init_next); +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif + const AVCodecParser *av_parser_iterate(void **opaque) { uintptr_t i = (uintptr_t)*opaque; @@ -105,8 +120,3 @@ const AVCodecParser *av_parser_iterate(void **opaque) return p; } - -void av_register_codec_parser(AVCodecParser *parser) -{ - ff_thread_once(&av_parser_next_init, av_parser_init_next); -} diff --git a/libavcodec/pcm-bluray.c b/libavcodec/pcm-bluray.c index 517d7b518..8e6f562b5 100644 --- a/libavcodec/pcm-bluray.c +++ b/libavcodec/pcm-bluray.c @@ -307,7 +307,7 @@ AVCodec ff_pcm_bluray_decoder = { .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_PCM_BLURAY, .decode = pcm_bluray_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, diff --git a/libavcodec/pcm-dvd.c b/libavcodec/pcm-dvd.c index 0a751a819..3dda218bf 100644 --- a/libavcodec/pcm-dvd.c +++ b/libavcodec/pcm-dvd.c @@ -34,8 +34,9 @@ typedef struct PCMDVDContext { int last_block_size; // Size of the last block of samples in bytes int samples_per_block; // Number of samples per channel per block int groups_per_block; // Number of 20/24-bit sample groups per block - uint8_t *extra_samples; // Pointer to leftover samples from a frame int extra_sample_count; // Number of leftover samples in the buffer + uint8_t extra_samples[8 * 3 * 4]; // Space for leftover samples from a frame + // (8 channels, 3B/sample, 4 samples/block) } PCMDVDContext; static av_cold int pcm_dvd_decode_init(AVCodecContext *avctx) @@ -44,18 +45,6 @@ static av_cold int pcm_dvd_decode_init(AVCodecContext *avctx) /* Invalid header to force parsing of the first header */ s->last_header = -1; - /* reserve space for 8 channels, 3 bytes/sample, 4 samples/block */ - if (!(s->extra_samples = av_malloc(8 * 3 * 4))) - return AVERROR(ENOMEM); - - return 0; -} - -static av_cold int pcm_dvd_decode_uninit(AVCodecContext *avctx) -{ - PCMDVDContext *s = avctx->priv_data; - - av_freep(&s->extra_samples); return 0; } @@ -310,9 +299,10 @@ AVCodec ff_pcm_dvd_decoder = { .priv_data_size = sizeof(PCMDVDContext), .init = pcm_dvd_decode_init, .decode = pcm_dvd_decode_frame, - .close = pcm_dvd_decode_uninit, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE - } + }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/pcm-dvdenc.c b/libavcodec/pcm-dvdenc.c index d26eaf071..97ac77833 100644 --- a/libavcodec/pcm-dvdenc.c +++ b/libavcodec/pcm-dvdenc.c @@ -170,11 +170,6 @@ static int pcm_dvd_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, return 0; } -static av_cold int pcm_dvd_encode_close(AVCodecContext *avctx) -{ - return 0; -} - AVCodec ff_pcm_dvd_encoder = { .name = "pcm_dvd", .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for DVD media"), @@ -182,7 +177,6 @@ AVCodec ff_pcm_dvd_encoder = { .id = AV_CODEC_ID_PCM_DVD, .priv_data_size = sizeof(PCMDVDContext), .init = pcm_dvd_encode_init, - .close = pcm_dvd_encode_close, .encode2 = pcm_dvd_encode_frame, .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME, .supported_samplerates = (const int[]) { 48000, 96000, 0}, @@ -194,4 +188,5 @@ AVCodec ff_pcm_dvd_encoder = { .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 96a68f7fe..19d04e918 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -24,8 +24,10 @@ * PCM codecs */ +#include "config.h" #include "libavutil/attributes.h" #include "libavutil/float_dsp.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "bytestream.h" #include "internal.h" @@ -35,19 +37,22 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx) { avctx->frame_size = 0; +#if !CONFIG_HARDCODED_TABLES switch (avctx->codec->id) { - case AV_CODEC_ID_PCM_ALAW: - pcm_alaw_tableinit(); - break; - case AV_CODEC_ID_PCM_MULAW: - pcm_ulaw_tableinit(); - break; - case AV_CODEC_ID_PCM_VIDC: - pcm_vidc_tableinit(); - break; +#define INIT_ONCE(id, name) \ + case AV_CODEC_ID_PCM_ ## id: \ + if (CONFIG_PCM_ ## id ## _ENCODER) { \ + static AVOnce init_static_once = AV_ONCE_INIT; \ + ff_thread_once(&init_static_once, pcm_ ## name ## _tableinit); \ + } \ + break + INIT_ONCE(ALAW, alaw); + INIT_ONCE(MULAW, ulaw); + INIT_ONCE(VIDC, vidc); default: break; } +#endif avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); avctx->block_align = avctx->channels * avctx->bits_per_coded_sample / 8; @@ -235,13 +240,15 @@ static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, typedef struct PCMDecode { short table[256]; - AVFloatDSPContext *fdsp; + void (*vector_fmul_scalar)(float *dst, const float *src, float mul, + int len); float scale; } PCMDecode; static av_cold int pcm_decode_init(AVCodecContext *avctx) { PCMDecode *s = avctx->priv_data; + AVFloatDSPContext *fdsp; int i; if (avctx->channels <= 0) { @@ -268,9 +275,11 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; s->scale = 1. / (1 << (avctx->bits_per_coded_sample - 1)); - s->fdsp = avpriv_float_dsp_alloc(0); - if (!s->fdsp) + fdsp = avpriv_float_dsp_alloc(0); + if (!fdsp) return AVERROR(ENOMEM); + s->vector_fmul_scalar = fdsp->vector_fmul_scalar; + av_free(fdsp); break; default: break; @@ -284,15 +293,6 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx) return 0; } -static av_cold int pcm_decode_close(AVCodecContext *avctx) -{ - PCMDecode *s = avctx->priv_data; - - av_freep(&s->fdsp); - - return 0; -} - /** * Read PCM samples macro * @param size Data size of native machine format @@ -419,6 +419,14 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, for (; n > 0; n--) *samples++ = *src++ + 128; break; + case AV_CODEC_ID_PCM_SGA: + for (; n > 0; n--) { + int sign = *src >> 7; + int magn = *src & 0x7f; + *samples++ = sign ? 128 - magn : 128 + magn; + src++; + } + break; case AV_CODEC_ID_PCM_S8_PLANAR: n /= avctx->channels; for (c = 0; c < avctx->channels; c++) { @@ -529,9 +537,9 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, if (avctx->codec_id == AV_CODEC_ID_PCM_F16LE || avctx->codec_id == AV_CODEC_ID_PCM_F24LE) { - s->fdsp->vector_fmul_scalar((float *)frame->extended_data[0], - (const float *)frame->extended_data[0], - s->scale, FFALIGN(frame->nb_samples * avctx->channels, 4)); + s->vector_fmul_scalar((float *)frame->extended_data[0], + (const float *)frame->extended_data[0], + s->scale, FFALIGN(frame->nb_samples * avctx->channels, 4)); emms_c(); } @@ -552,6 +560,7 @@ AVCodec ff_ ## name_ ## _encoder = { \ .capabilities = AV_CODEC_CAP_VARIABLE_FRAME_SIZE, \ .sample_fmts = (const enum AVSampleFormat[]){ sample_fmt_, \ AV_SAMPLE_FMT_NONE }, \ + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \ } #define PCM_ENCODER_2(cf, id, sample_fmt, name, long_name) \ @@ -570,11 +579,11 @@ AVCodec ff_ ## name_ ## _decoder = { \ .id = AV_CODEC_ID_ ## id_, \ .priv_data_size = sizeof(PCMDecode), \ .init = pcm_decode_init, \ - .close = pcm_decode_close, \ .decode = pcm_decode_frame, \ .capabilities = AV_CODEC_CAP_DR1, \ .sample_fmts = (const enum AVSampleFormat[]){ sample_fmt_, \ AV_SAMPLE_FMT_NONE }, \ + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \ } #define PCM_DECODER_2(cf, id, sample_fmt, name, long_name) \ @@ -621,3 +630,4 @@ PCM_CODEC (PCM_U32LE, AV_SAMPLE_FMT_S32, pcm_u32le, "PCM unsigned PCM_CODEC (PCM_S64BE, AV_SAMPLE_FMT_S64, pcm_s64be, "PCM signed 64-bit big-endian"); PCM_CODEC (PCM_S64LE, AV_SAMPLE_FMT_S64, pcm_s64le, "PCM signed 64-bit little-endian"); PCM_CODEC (PCM_VIDC, AV_SAMPLE_FMT_S16, pcm_vidc, "PCM Archimedes VIDC"); +PCM_DECODER(PCM_SGA, AV_SAMPLE_FMT_U8, pcm_sga, "PCM SGA"); diff --git a/libavcodec/pgxdec.c b/libavcodec/pgxdec.c new file mode 100644 index 000000000..65b292928 --- /dev/null +++ b/libavcodec/pgxdec.c @@ -0,0 +1,168 @@ +/* + * PGX image format + * Copyright (c) 2020 Gautam Ramakrishnan + * + * 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 "avcodec.h" +#include "internal.h" +#include "bytestream.h" +#include "libavutil/imgutils.h" + +static int pgx_get_number(AVCodecContext *avctx, GetByteContext *g, int *number) { + int ret = AVERROR_INVALIDDATA; + char digit; + + *number = 0; + while (1) { + uint64_t temp; + if (!bytestream2_get_bytes_left(g)) + return AVERROR_INVALIDDATA; + digit = bytestream2_get_byte(g); + if (digit == ' ' || digit == 0xA || digit == 0xD) + break; + else if (digit < '0' || digit > '9') + return AVERROR_INVALIDDATA; + + temp = (uint64_t)10 * (*number) + (digit - '0'); + if (temp > INT_MAX) + return AVERROR_INVALIDDATA; + *number = temp; + ret = 0; + } + + return ret; +} + +static int pgx_decode_header(AVCodecContext *avctx, GetByteContext *g, + int *depth, int *width, int *height, + int *sign) +{ + int byte; + + if (bytestream2_get_bytes_left(g) < 6) { + return AVERROR_INVALIDDATA; + } + + bytestream2_skip(g, 6); + + // Is the component signed? + byte = bytestream2_peek_byte(g); + if (byte == '+') { + *sign = 0; + bytestream2_skip(g, 1); + } else if (byte == '-') { + *sign = 1; + bytestream2_skip(g, 1); + } else if (byte == 0) + goto error; + + byte = bytestream2_peek_byte(g); + if (byte == ' ') + bytestream2_skip(g, 1); + else if (byte == 0) + goto error; + + if (pgx_get_number(avctx, g, depth)) + goto error; + if (pgx_get_number(avctx, g, width)) + goto error; + if (pgx_get_number(avctx, g, height)) + goto error; + + if (bytestream2_peek_byte(g) == 0xA) + bytestream2_skip(g, 1); + return 0; + +error: + av_log(avctx, AV_LOG_ERROR, "Error in decoding header.\n"); + return AVERROR_INVALIDDATA; +} + +#define WRITE_FRAME(D, PIXEL, suffix) \ + static inline void write_frame_ ##D(AVFrame *frame, GetByteContext *g, \ + int width, int height, int sign, int depth) \ + { \ + int i, j; \ + for (i = 0; i < height; i++) { \ + PIXEL *line = (PIXEL*)frame->data[0] + i*frame->linesize[0]/sizeof(PIXEL); \ + for (j = 0; j < width; j++) { \ + unsigned val; \ + if (sign) \ + val = (PIXEL)bytestream2_get_ ##suffix(g) + (1 << (depth - 1)); \ + else \ + val = bytestream2_get_ ##suffix(g); \ + val <<= (D - depth); \ + *(line + j) = val; \ + } \ + } \ + } \ + +WRITE_FRAME(8, int8_t, byte) +WRITE_FRAME(16, int16_t, be16) + +static int pgx_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + AVFrame *p = data; + int ret; + int bpp; + int width, height, depth; + int sign = 0; + GetByteContext g; + bytestream2_init(&g, avpkt->data, avpkt->size); + + if ((ret = pgx_decode_header(avctx, &g, &depth, &width, &height, &sign)) < 0) + return ret; + + if ((ret = ff_set_dimensions(avctx, width, height)) < 0) + return ret; + + if (depth > 0 && depth <= 8) { + avctx->pix_fmt = AV_PIX_FMT_GRAY8; + bpp = 8; + } else if (depth > 0 && depth <= 16) { + avctx->pix_fmt = AV_PIX_FMT_GRAY16; + bpp = 16; + } else { + av_log(avctx, AV_LOG_ERROR, "depth %d is invalid or unsupported.\n", depth); + return AVERROR_PATCHWELCOME; + } + if (bytestream2_get_bytes_left(&g) < width * height * (bpp >> 3)) + return AVERROR_INVALIDDATA; + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) + return ret; + p->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; + avctx->bits_per_raw_sample = depth; + if (bpp == 8) + write_frame_8(p, &g, width, height, sign, depth); + else if (bpp == 16) + write_frame_16(p, &g, width, height, sign, depth); + *got_frame = 1; + return 0; +} + +AVCodec ff_pgx_decoder = { + .name = "pgx", + .long_name = NULL_IF_CONFIG_SMALL("PGX (JPEG2000 Test Format)"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_PGX, + .decode = pgx_decode_frame, + .capabilities = AV_CODEC_CAP_DR1, +}; diff --git a/libavcodec/photocd.c b/libavcodec/photocd.c new file mode 100644 index 000000000..408ddeaac --- /dev/null +++ b/libavcodec/photocd.c @@ -0,0 +1,473 @@ +/* + * Kodak PhotoCD (a.k.a. ImagePac) image decoder + * + * Copyright (c) 1996-2002 Gerd Knorr + * Copyright (c) 2010 Kenneth Vermeirsch + * Copyright (c) 2020 Paul B Mahol + * + * 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 + * Kodak PhotoCD (a.k.a. ImagePac) image decoder + * + * Supports resolutions up to 3072x2048. + */ + +#define CACHED_BITSTREAM_READER !ARCH_X86_32 + +#include "libavutil/avassert.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "bytestream.h" +#include "get_bits.h" +#include "internal.h" +#include "thread.h" + +typedef struct PhotoCDContext { + AVClass *class; + int lowres; + + GetByteContext gb; + int thumbnails; //* number of thumbnails; 0 for normal image */ + int resolution; + int orientation; + + int streampos; + + uint8_t bits[256]; + uint16_t codes[256]; + uint8_t syms[256]; + + VLC vlc[3]; +} PhotoCDContext; + +typedef struct ImageInfo { + uint32_t start; + uint16_t width, height; +} ImageInfo; + +static const ImageInfo img_info[6] = { + {8192, 192, 128}, + {47104, 384, 256}, + {196608, 768, 512}, + {0, 1536, 1024}, + {0, 3072, 2048}, + {0, 6144, 4096}, +}; + +static av_noinline void interp_lowres(PhotoCDContext *s, AVFrame *picture, + int width, int height) +{ + GetByteContext *gb = &s->gb; + int start = s->streampos + img_info[2].start; + uint8_t *ptr, *ptr1, *ptr2; + uint8_t *dst; + int fill; + + ptr = picture->data[0]; + ptr1 = picture->data[1]; + ptr2 = picture->data[2]; + + bytestream2_seek(gb, start, SEEK_SET); + + for (int y = 0; y < height; y += 2) { + dst = ptr; + for (int x = 0; x < width - 1; x++) { + fill = bytestream2_get_byte(gb); + *(dst++) = fill; + *(dst++) = (fill + bytestream2_peek_byte(gb) + 1) >> 1; + } + fill = bytestream2_get_byte(gb); + *(dst++) = fill; + *(dst++) = fill; + + ptr += picture->linesize[0] << 1; + + dst = ptr; + for (int x = 0; x < width - 1; x++) { + fill = bytestream2_get_byte(gb); + *(dst++) = fill; + *(dst++) = (fill + bytestream2_peek_byte(gb) + 1) >> 1; + } + fill = bytestream2_get_byte(gb); + *(dst++) = fill; + *(dst++) = fill; + + ptr += picture->linesize[0] << 1; + + dst = ptr1; + for (int x = 0; x < (width >> 1) - 1; x++) { + fill = bytestream2_get_byte(gb); + *(dst++) = fill; + *(dst++) = (fill + bytestream2_peek_byte(gb) + 1) >> 1; + } + fill = bytestream2_get_byte(gb); + *(dst++) = fill; + *(dst++) = fill; + + ptr1 += picture->linesize[1] << 1; + + dst = ptr2; + for (int x = 0; x < (width >> 1) - 1; x++) { + fill = bytestream2_get_byte(gb); + *(dst++) = fill; + *(dst++) = (fill + bytestream2_peek_byte(gb) + 1) >> 1; + } + fill = bytestream2_get_byte(gb); + *(dst++) = fill; + *(dst++) = fill; + + ptr2 += picture->linesize[2] << 1; + } + + s->streampos += bytestream2_tell(gb) - start; +} + +static av_noinline void interp_lines(uint8_t *ptr, int linesize, + int width, int height) +{ + const uint8_t *src1; + uint8_t *dst; + int x; + + for (int y = 0; y < height - 2; y += 2) { + const uint8_t *src1 = ptr; + uint8_t *dst = ptr + linesize; + const uint8_t *src2 = dst + linesize; + for (x = 0; x < width - 2; x += 2) { + dst[x] = (src1[x] + src2[x] + 1) >> 1; + dst[x + 1] = (src1[x] + src2[x] + src1[x + 2] + src2[x + 2] + 2) >> 2; + } + dst[x] = dst[x + 1] = (src1[x] + src2[x] + 1) >> 1; + + ptr += linesize << 1; + } + + src1 = ptr; + dst = ptr + linesize; + for (x = 0; x < width - 2; x += 2) { + dst[x] = src1[x]; + dst[x + 1] = (src1[x] + src1[x + 2] + 1) >> 1; + } + dst[x] = dst[x + 1] = src1[x]; +} + +static av_noinline void interp_pixels(uint8_t *ptr, int linesize, + int width, int height) +{ + for (int y = height - 2; y >= 0; y -= 2) { + const uint8_t *src = ptr + (y >> 1) * linesize; + uint8_t *dst = ptr + y * linesize; + + dst[width - 2] = dst[width - 1] = src[(width >> 1) - 1]; + for (int x = width - 4; x >= 0; x -= 2) { + dst[x] = src[x >> 1]; + dst[x + 1] = (src[x >> 1] + src[(x >> 1) + 1] + 1) >> 1; + } + } +} + +static av_noinline int read_hufftable(AVCodecContext *avctx, VLC *vlc) +{ + PhotoCDContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + int start = s->streampos; + int count, ret; + + bytestream2_seek(gb, start, SEEK_SET); + + count = bytestream2_get_byte(gb) + 1; + if (bytestream2_get_bytes_left(gb) < count * 4) + return AVERROR_INVALIDDATA; + + for (int j = 0; j < count; j++) { + const int bit = bytestream2_get_byteu(gb) + 1; + const int code = bytestream2_get_be16u(gb); + const int sym = bytestream2_get_byteu(gb); + + if (bit > 16) + return AVERROR_INVALIDDATA; + + s->bits[j] = bit; + s->codes[j] = code >> (16 - bit); + s->syms[j] = sym; + } + + ff_free_vlc(vlc); + ret = ff_init_vlc_sparse(vlc, 12, count, + s->bits, sizeof(*s->bits), sizeof(*s->bits), + s->codes, sizeof(*s->codes), sizeof(*s->codes), + s->syms, sizeof(*s->syms), sizeof(*s->syms), 0); + + s->streampos = bytestream2_tell(gb); + + return ret; +} + +static av_noinline int decode_huff(AVCodecContext *avctx, AVFrame *frame, + int target_res, int curr_res) +{ + PhotoCDContext *s = avctx->priv_data; + GetBitContext g; + GetByteContext *gb = &s->gb; + int ret, y = 0, type, height; + int start = s->streampos; + unsigned shiftreg; + const int scaling = target_res - curr_res; + const uint8_t type2idx[] = { 0, 0xff, 1, 2 }; + + bytestream2_seek(gb, start, SEEK_SET); + ret = init_get_bits8(&g, gb->buffer, bytestream2_get_bytes_left(gb)); + if (ret < 0) + return ret; + + height = img_info[curr_res].height; + + while (y < height) { + uint8_t *data; + int x2, idx; + + for (; get_bits_left(&g) > 0;) { + if (show_bits(&g, 12) == 0xfff) + break; + skip_bits(&g, 8); + } + + shiftreg = show_bits(&g, 24); + while (shiftreg != 0xfffffe) { + if (get_bits_left(&g) <= 0) + return AVERROR_INVALIDDATA; + skip_bits(&g, 1); + shiftreg = show_bits(&g, 24); + } + skip_bits(&g, 24); + y = show_bits(&g, 15) & 0x1fff; + if (y >= height) + break; + type = get_bits(&g, 2); + skip_bits(&g, 14); + + if (type == 1) + return AVERROR_INVALIDDATA; + idx = type2idx[type]; + + data = frame->data[idx] + (y >> !!idx) * frame->linesize[idx]; + + x2 = avctx->width >> (scaling + !!idx); + for (int x = 0; x < x2; x++) { + int m; + + if (get_bits_left(&g) <= 0) + return AVERROR_INVALIDDATA; + m = get_vlc2(&g, s->vlc[idx].table, s->vlc[idx].bits, 2); + if (m < 0) + return AVERROR_INVALIDDATA; + m = sign_extend(m, 8); + data[x] = av_clip_uint8(data[x] + m); + } + } + + s->streampos += (get_bits_count(&g) + 7) >> 3; + s->streampos = (s->streampos + 0x6000 + 2047) & ~0x7ff; + + return 0; +} + +static int photocd_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + PhotoCDContext *s = avctx->priv_data; + ThreadFrame frame = { .f = data }; + const uint8_t *buf = avpkt->data; + GetByteContext *gb = &s->gb; + AVFrame *p = data; + uint8_t *ptr, *ptr1, *ptr2; + int ret; + + if (avpkt->size < img_info[0].start) + return AVERROR_INVALIDDATA; + + if (!memcmp("PCD_OPA", buf, 7)) { + s->thumbnails = AV_RL16(buf + 10); + av_log(avctx, AV_LOG_WARNING, "this is a thumbnails file, " + "reading first thumbnail only\n"); + } else if (avpkt->size < 786432) { + return AVERROR_INVALIDDATA; + } else if (memcmp("PCD_IPI", buf + 0x800, 7)) { + return AVERROR_INVALIDDATA; + } + + s->orientation = s->thumbnails ? buf[12] & 3 : buf[0x48] & 3; + + if (s->thumbnails) + s->resolution = 0; + else if (avpkt->size <= 788480) + s->resolution = 2; + else + s->resolution = av_clip(4 - s->lowres, 0, 4); + + ret = ff_set_dimensions(avctx, img_info[s->resolution].width, img_info[s->resolution].height); + if (ret < 0) + return ret; + + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) + return ret; + + p->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; + + bytestream2_init(gb, avpkt->data, avpkt->size); + + if (s->resolution < 3) { + ptr = p->data[0]; + ptr1 = p->data[1]; + ptr2 = p->data[2]; + + if (s->thumbnails) + bytestream2_seek(gb, 10240, SEEK_SET); + else + bytestream2_seek(gb, img_info[s->resolution].start, SEEK_SET); + + for (int y = 0; y < avctx->height; y += 2) { + bytestream2_get_buffer(gb, ptr, avctx->width); + ptr += p->linesize[0]; + + bytestream2_get_buffer(gb, ptr, avctx->width); + ptr += p->linesize[0]; + + bytestream2_get_buffer(gb, ptr1, avctx->width >> 1); + ptr1 += p->linesize[1]; + + bytestream2_get_buffer(gb, ptr2, avctx->width >> 1); + ptr2 += p->linesize[2]; + } + } else { + s->streampos = 0; + ptr = p->data[0]; + ptr1 = p->data[1]; + ptr2 = p->data[2]; + + interp_lowres(s, p, img_info[2].width, img_info[2].height); + + interp_lines(ptr1, p->linesize[1], img_info[2].width, img_info[2].height); + interp_lines(ptr2, p->linesize[2], img_info[2].width, img_info[2].height); + + if (s->resolution == 4) { + interp_pixels(ptr1, p->linesize[1], img_info[3].width, img_info[3].height); + interp_lines (ptr1, p->linesize[1], img_info[3].width, img_info[3].height); + interp_pixels(ptr2, p->linesize[2], img_info[3].width, img_info[3].height); + interp_lines (ptr2, p->linesize[2], img_info[3].width, img_info[3].height); + } + + interp_lines(ptr, p->linesize[0], img_info[3].width, img_info[3].height); + + s->streampos = 0xc2000; + for (int n = 0; n < 3; n++) { + if ((ret = read_hufftable(avctx, &s->vlc[n])) < 0) + return ret; + } + s->streampos = (s->streampos + 2047) & ~0x3ff; + if (decode_huff(avctx, p, s->resolution, 3) < 0) + return AVERROR_INVALIDDATA; + + if (s->resolution == 4) { + interp_pixels(ptr, p->linesize[0], img_info[4].width, img_info[4].height); + interp_lines (ptr, p->linesize[0], img_info[4].width, img_info[4].height); + + for (int n = 0; n < 3; n++) { + if ((ret = read_hufftable(avctx, &s->vlc[n])) < 0) + return ret; + } + s->streampos = (s->streampos + 2047) & ~0x3ff; + if (decode_huff(avctx, p, 4, 4) < 0) + return AVERROR_INVALIDDATA; + } + } + + { + ptr1 = p->data[1]; + ptr2 = p->data[2]; + + for (int y = 0; y < avctx->height >> 1; y++) { + for (int x = 0; x < avctx->width >> 1; x++) { + ptr1[x] = av_clip_uint8(ptr1[x] - 28); + ptr2[x] = av_clip_uint8(ptr2[x] - 9); + } + + ptr1 += p->linesize[1]; + ptr2 += p->linesize[2]; + } + } + + *got_frame = 1; + + return 0; +} + +static av_cold int photocd_decode_init(AVCodecContext *avctx) +{ + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + avctx->colorspace = AVCOL_SPC_BT709; + avctx->color_primaries = AVCOL_PRI_BT709; + avctx->color_trc = AVCOL_TRC_IEC61966_2_1; + avctx->color_range = AVCOL_RANGE_JPEG; + + return 0; +} + +static av_cold int photocd_decode_close(AVCodecContext *avctx) +{ + PhotoCDContext *s = avctx->priv_data; + + for (int i = 0; i < 3; i++) + ff_free_vlc(&s->vlc[i]); + + return 0; +} + +#define OFFSET(x) offsetof(PhotoCDContext, x) +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM + +static const AVOption options[] = { + { "lowres", "Lower the decoding resolution by a power of two", + OFFSET(lowres), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 4, VD }, + { NULL }, +}; + +static const AVClass photocd_class = { + .class_name = "photocd", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_photocd_decoder = { + .name = "photocd", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_PHOTOCD, + .priv_data_size = sizeof(PhotoCDContext), + .priv_class = &photocd_class, + .init = photocd_decode_init, + .close = photocd_decode_close, + .decode = photocd_decode_frame, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .long_name = NULL_IF_CONFIG_SMALL("Kodak Photo CD"), + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, +}; diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c index 78f571cd5..ad9d830af 100644 --- a/libavcodec/pixlet.c +++ b/libavcodec/pixlet.c @@ -58,6 +58,7 @@ typedef struct PixletContext { int16_t *filter[2]; int16_t *prediction; int64_t scaling[4][2][NB_LEVELS]; + uint16_t lut[65536]; SubBand band[4][NB_LEVELS * 3 + 1]; } PixletContext; @@ -462,11 +463,27 @@ static void reconstruction(AVCodecContext *avctx, int16_t *dest, } } -static void postprocess_luma(AVFrame *frame, int w, int h, int depth) +static void build_luma_lut(AVCodecContext *avctx, int depth) { + PixletContext *ctx = avctx->priv_data; + int max = (1 << depth) - 1; + + if (ctx->depth == depth) + return; + ctx->depth = depth; + + for (int i = 0; i < FF_ARRAY_ELEMS(ctx->lut); i++) + ctx->lut[i] = ((int64_t)i * i * 65535LL) / max / max; +} + +static void postprocess_luma(AVCodecContext *avctx, AVFrame *frame, + int w, int h, int depth) +{ + PixletContext *ctx = avctx->priv_data; uint16_t *dsty = (uint16_t *)frame->data[0]; int16_t *srcy = (int16_t *)frame->data[0]; ptrdiff_t stridey = frame->linesize[0] / 2; + uint16_t *lut = ctx->lut; int i, j; for (j = 0; j < h; j++) { @@ -476,8 +493,7 @@ static void postprocess_luma(AVFrame *frame, int w, int h, int depth) else if (srcy[i] > ((1 << depth) - 1)) dsty[i] = 65535; else - dsty[i] = ((int64_t) srcy[i] * srcy[i] * 65535) / - ((1 << depth) - 1) / ((1 << depth) - 1); + dsty[i] = lut[srcy[i]]; } dsty += stridey; srcy += stridey; @@ -509,7 +525,7 @@ static void postprocess_chroma(AVFrame *frame, int w, int h, int depth) } static int decode_plane(AVCodecContext *avctx, int plane, - AVPacket *avpkt, AVFrame *frame) + const AVPacket *avpkt, AVFrame *frame) { PixletContext *ctx = avctx->priv_data; ptrdiff_t stride = frame->linesize[plane] / 2; @@ -591,7 +607,7 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data, int i, w, h, width, height, ret, version; AVFrame *p = data; ThreadFrame frame = { .f = data }; - uint32_t pktsize; + uint32_t pktsize, depth; bytestream2_init(&ctx->gb, avpkt->data, avpkt->size); @@ -623,12 +639,14 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data, ctx->levels = bytestream2_get_be32(&ctx->gb); if (ctx->levels != NB_LEVELS) return AVERROR_INVALIDDATA; - ctx->depth = bytestream2_get_be32(&ctx->gb); - if (ctx->depth < 8 || ctx->depth > 15) { - avpriv_request_sample(avctx, "Depth %d", ctx->depth); + depth = bytestream2_get_be32(&ctx->gb); + if (depth < 8 || depth > 15) { + avpriv_request_sample(avctx, "Depth %d", depth); return AVERROR_INVALIDDATA; } + build_luma_lut(avctx, depth); + ret = ff_set_dimensions(avctx, w, h); if (ret < 0) return ret; @@ -667,7 +685,7 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data, break; } - postprocess_luma(frame.f, ctx->w, ctx->h, ctx->depth); + postprocess_luma(avctx, frame.f, ctx->w, ctx->h, ctx->depth); postprocess_chroma(frame.f, ctx->w >> 1, ctx->h >> 1, ctx->depth); *got_frame = 1; diff --git a/libavcodec/png.h b/libavcodec/png.h index e967fcf38..a15560131 100644 --- a/libavcodec/png.h +++ b/libavcodec/png.h @@ -24,6 +24,8 @@ #include +#include "pngdsp.h" + #define PNG_COLOR_MASK_PALETTE 1 #define PNG_COLOR_MASK_COLOR 2 #define PNG_COLOR_MASK_ALPHA 4 @@ -61,4 +63,7 @@ int ff_png_pass_row_size(int pass, int bits_per_pixel, int width); void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); +void ff_png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, + uint8_t *src, uint8_t *last, int size, int bpp); + #endif /* AVCODEC_PNG_H */ diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 647e7f0a7..f3b212d50 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -54,10 +54,21 @@ typedef struct PNGDecContext { AVCodecContext *avctx; GetByteContext gb; - ThreadFrame previous_picture; ThreadFrame last_picture; ThreadFrame picture; + AVDictionary *frame_metadata; + + uint8_t iccp_name[82]; + uint8_t *iccp_data; + size_t iccp_data_len; + + int stereo_mode; + + int have_chrm; + uint32_t white_point[2]; + uint32_t display_primaries[3][2]; + enum PNGHeaderState hdr_state; enum PNGImageState pic_state; int width, height; @@ -78,8 +89,8 @@ typedef struct PNGDecContext { int has_trns; uint8_t transparent_color_be[6]; - uint8_t *image_buf; - int image_linesize; + uint8_t *background_buf; + unsigned background_buf_allocated; uint32_t palette[256]; uint8_t *crow_buf; uint8_t *last_row; @@ -250,8 +261,8 @@ void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, } /* NOTE: 'dst' can be equal to 'last' */ -static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, - uint8_t *src, uint8_t *last, int size, int bpp) +void ff_png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, + uint8_t *src, uint8_t *last, int size, int bpp) { int i, p, r, g, b, a; @@ -331,27 +342,27 @@ static int percent_missing(PNGDecContext *s) } /* process exactly one decompressed row */ -static void png_handle_row(PNGDecContext *s) +static void png_handle_row(PNGDecContext *s, uint8_t *dst, ptrdiff_t dst_stride) { uint8_t *ptr, *last_row; int got_line; if (!s->interlace_type) { - ptr = s->image_buf + s->image_linesize * (s->y + s->y_offset) + s->x_offset * s->bpp; + ptr = dst + dst_stride * (s->y + s->y_offset) + s->x_offset * s->bpp; if (s->y == 0) last_row = s->last_row; else - last_row = ptr - s->image_linesize; + last_row = ptr - dst_stride; - png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1, - last_row, s->row_size, s->bpp); + ff_png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1, + last_row, s->row_size, s->bpp); /* loco lags by 1 row so that it doesn't interfere with top prediction */ if (s->filter_type == PNG_FILTER_TYPE_LOCO && s->y > 0) { if (s->bit_depth == 16) { - deloco_rgb16((uint16_t *)(ptr - s->image_linesize), s->row_size / 2, + deloco_rgb16((uint16_t *)(ptr - dst_stride), s->row_size / 2, s->color_type == PNG_COLOR_TYPE_RGB_ALPHA); } else { - deloco_rgb8(ptr - s->image_linesize, s->row_size, + deloco_rgb8(ptr - dst_stride, s->row_size, s->color_type == PNG_COLOR_TYPE_RGB_ALPHA); } } @@ -371,14 +382,14 @@ static void png_handle_row(PNGDecContext *s) } else { got_line = 0; for (;;) { - ptr = s->image_buf + s->image_linesize * (s->y + s->y_offset) + s->x_offset * s->bpp; + ptr = dst + dst_stride * (s->y + s->y_offset) + s->x_offset * s->bpp; if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) { /* if we already read one row, it is time to stop to * wait for the next one */ if (got_line) break; - 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); + ff_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; @@ -412,7 +423,8 @@ the_end:; } } -static int png_decode_idat(PNGDecContext *s, int length) +static int png_decode_idat(PNGDecContext *s, int length, + uint8_t *dst, ptrdiff_t dst_stride) { int ret; s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb)); @@ -428,7 +440,7 @@ static int png_decode_idat(PNGDecContext *s, int length) } if (s->zstream.avail_out == 0) { if (!(s->pic_state & PNG_ALLIMAGE)) { - png_handle_row(s); + png_handle_row(s, dst, dst_stride); } s->zstream.avail_out = s->crow_size; s->zstream.next_out = s->crow_buf; @@ -510,8 +522,7 @@ static uint8_t *iso88591_to_utf8(const uint8_t *in, size_t size_in) return out; } -static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed, - AVDictionary **dict) +static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed) { int ret, method; const uint8_t *data = s->gb.buffer; @@ -553,7 +564,7 @@ static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed, return AVERROR(ENOMEM); } - av_dict_set(dict, kw_utf8, txt_utf8, + av_dict_set(&s->frame_metadata, kw_utf8, txt_utf8, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); return 0; } @@ -711,13 +722,10 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, s->bpp += byte_depth; } + ff_thread_release_buffer(avctx, &s->picture); if ((ret = ff_thread_get_buffer(avctx, &s->picture, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - if (avctx->codec_id == AV_CODEC_ID_APNG && s->last_dispose_op != APNG_DISPOSE_OP_PREVIOUS) { - ff_thread_release_buffer(avctx, &s->previous_picture); - if ((ret = ff_thread_get_buffer(avctx, &s->previous_picture, AV_GET_BUFFER_FLAG_REF)) < 0) - return ret; - } + p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; p->interlaced_frame = !!s->interlace_type; @@ -736,8 +744,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, } ff_dlog(avctx, "row_size=%d crow_size =%d\n", s->row_size, s->crow_size); - s->image_buf = p->data[0]; - s->image_linesize = p->linesize[0]; + /* copy the palette if needed */ if (avctx->pix_fmt == AV_PIX_FMT_PAL8) memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t)); @@ -768,7 +775,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE) s->bpp -= byte_depth; - ret = png_decode_idat(s, length); + ret = png_decode_idat(s, length, p->data[0], p->linesize[0]); if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE) s->bpp += byte_depth; @@ -855,21 +862,21 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s, static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f) { int ret, cnt = 0; - uint8_t *data, profile_name[82]; AVBPrint bp; - AVFrameSideData *sd; - while ((profile_name[cnt++] = bytestream2_get_byte(&s->gb)) && cnt < 81); + while ((s->iccp_name[cnt++] = bytestream2_get_byte(&s->gb)) && cnt < 81); if (cnt > 80) { av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid name!\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } length = FFMAX(length - cnt, 0); if (bytestream2_get_byte(&s->gb) != 0) { av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid compression!\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } length = FFMAX(length - 1, 0); @@ -877,24 +884,19 @@ static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f) if ((ret = decode_zbuf(&bp, s->gb.buffer, s->gb.buffer + length)) < 0) return ret; - ret = av_bprint_finalize(&bp, (char **)&data); + av_freep(&s->iccp_data); + ret = av_bprint_finalize(&bp, (char **)&s->iccp_data); if (ret < 0) return ret; - - sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, bp.len); - if (!sd) { - av_free(data); - return AVERROR(ENOMEM); - } - - av_dict_set(&sd->metadata, "name", profile_name, 0); - memcpy(sd->data, data, bp.len); - av_free(data); + s->iccp_data_len = bp.len; /* ICC compressed data and CRC */ bytestream2_skip(&s->gb, length + 4); return 0; +fail: + s->iccp_name[0] = 0; + return ret; } static void handle_small_bpp(PNGDecContext *s, AVFrame *p) @@ -917,7 +919,7 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p) pd[8*i + 1]= (pd[i]>>6) & 1; pd[8*i + 0]= pd[i]>>7; } - pd += s->image_linesize; + pd += p->linesize[0]; } } else if (s->bits_per_pixel == 2) { int i, j; @@ -945,7 +947,7 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p) pd[4*i + 0]= ( pd[i]>>6 )*0x55; } } - pd += s->image_linesize; + pd += p->linesize[0]; } } else if (s->bits_per_pixel == 4) { int i, j; @@ -965,7 +967,7 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p) pd[2*i + 0] = (pd[i] >> 4) * 0x11; } } - pd += s->image_linesize; + pd += p->linesize[0]; } } } @@ -1020,7 +1022,7 @@ static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s, return AVERROR_INVALIDDATA; } - if ((sequence_number == 0 || !s->previous_picture.f->data[0]) && + if ((sequence_number == 0 || !s->last_picture.f->data[0]) && dispose_op == APNG_DISPOSE_OP_PREVIOUS) { // No previous frame to revert to for the first frame // Spec says to just treat it as a APNG_DISPOSE_OP_BACKGROUND @@ -1060,8 +1062,8 @@ static void handle_p_frame_png(PNGDecContext *s, AVFrame *p) for (j = 0; j < s->height; j++) { for (i = 0; i < ls; i++) pd[i] += pd_last[i]; - pd += s->image_linesize; - pd_last += s->image_linesize; + pd += p->linesize[0]; + pd_last += s->last_picture.f->linesize[0]; } } @@ -1072,8 +1074,12 @@ static void handle_p_frame_png(PNGDecContext *s, AVFrame *p) static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, AVFrame *p) { + uint8_t *dst = p->data[0]; + ptrdiff_t dst_stride = p->linesize[0]; + const uint8_t *src = s->last_picture.f->data[0]; + ptrdiff_t src_stride = s->last_picture.f->linesize[0]; + size_t x, y; - uint8_t *buffer; if (s->blend_op == APNG_BLEND_OP_OVER && avctx->pix_fmt != AV_PIX_FMT_RGBA && @@ -1084,37 +1090,42 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, return AVERROR_PATCHWELCOME; } - buffer = av_malloc_array(s->image_linesize, s->height); - if (!buffer) - return AVERROR(ENOMEM); + ff_thread_await_progress(&s->last_picture, INT_MAX, 0); + // need to reset a rectangle to background: + if (s->last_dispose_op == APNG_DISPOSE_OP_BACKGROUND) { + av_fast_malloc(&s->background_buf, &s->background_buf_allocated, + src_stride * p->height); + if (!s->background_buf) + return AVERROR(ENOMEM); - // Do the disposal operation specified by the last frame on the frame - if (s->last_dispose_op != APNG_DISPOSE_OP_PREVIOUS) { - ff_thread_await_progress(&s->last_picture, INT_MAX, 0); - memcpy(buffer, s->last_picture.f->data[0], s->image_linesize * s->height); + memcpy(s->background_buf, src, src_stride * p->height); - if (s->last_dispose_op == APNG_DISPOSE_OP_BACKGROUND) - for (y = s->last_y_offset; y < s->last_y_offset + s->last_h; ++y) - memset(buffer + s->image_linesize * y + s->bpp * s->last_x_offset, 0, s->bpp * s->last_w); + for (y = s->last_y_offset; y < s->last_y_offset + s->last_h; y++) { + memset(s->background_buf + src_stride * y + + s->bpp * s->last_x_offset, 0, s->bpp * s->last_w); + } - memcpy(s->previous_picture.f->data[0], buffer, s->image_linesize * s->height); - ff_thread_report_progress(&s->previous_picture, INT_MAX, 0); - } else { - ff_thread_await_progress(&s->previous_picture, INT_MAX, 0); - memcpy(buffer, s->previous_picture.f->data[0], s->image_linesize * s->height); + src = s->background_buf; } - // Perform blending - if (s->blend_op == APNG_BLEND_OP_SOURCE) { + // copy unchanged rectangles from the last frame + for (y = 0; y < s->y_offset; y++) + memcpy(dst + y * dst_stride, src + y * src_stride, p->width * s->bpp); + for (y = s->y_offset; y < s->y_offset + s->cur_h; y++) { + memcpy(dst + y * dst_stride, src + y * src_stride, s->x_offset * s->bpp); + memcpy(dst + y * dst_stride + (s->x_offset + s->cur_w) * s->bpp, + src + y * src_stride + (s->x_offset + s->cur_w) * s->bpp, + (p->width - s->cur_w - s->x_offset) * s->bpp); + } + for (y = s->y_offset + s->cur_h; y < p->height; y++) + memcpy(dst + y * dst_stride, src + y * src_stride, p->width * s->bpp); + + if (s->blend_op == APNG_BLEND_OP_OVER) { + // Perform blending for (y = s->y_offset; y < s->y_offset + s->cur_h; ++y) { - size_t row_start = s->image_linesize * y + s->bpp * s->x_offset; - memcpy(buffer + row_start, p->data[0] + row_start, s->bpp * s->cur_w); - } - } else { // APNG_BLEND_OP_OVER - for (y = s->y_offset; y < s->y_offset + s->cur_h; ++y) { - uint8_t *foreground = p->data[0] + s->image_linesize * y + s->bpp * s->x_offset; - uint8_t *background = buffer + s->image_linesize * y + s->bpp * s->x_offset; + uint8_t *foreground = dst + dst_stride * y + s->bpp * s->x_offset; + const uint8_t *background = src + src_stride * y + s->bpp * s->x_offset; for (x = s->x_offset; x < s->x_offset + s->cur_w; ++x, foreground += s->bpp, background += s->bpp) { size_t b; uint8_t foreground_alpha, background_alpha, output_alpha; @@ -1141,18 +1152,17 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, break; } - if (foreground_alpha == 0) + if (foreground_alpha == 255) continue; - if (foreground_alpha == 255) { - memcpy(background, foreground, s->bpp); + if (foreground_alpha == 0) { + memcpy(foreground, background, s->bpp); continue; } if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { // TODO: Alpha blending with PAL8 will likely need the entire image converted over to RGBA first avpriv_request_sample(avctx, "Alpha blending palette samples"); - background[0] = foreground[0]; continue; } @@ -1170,23 +1180,18 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, } } output[b] = output_alpha; - memcpy(background, output, s->bpp); + memcpy(foreground, output, s->bpp); } } } - // Copy blended buffer into the frame and free - memcpy(p->data[0], buffer, s->image_linesize * s->height); - av_free(buffer); - return 0; } static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, - AVFrame *p, AVPacket *avpkt) + AVFrame *p, const AVPacket *avpkt) { const AVCRC *crc_tab = av_crc_get_table(AV_CRC_32_IEEE_LE); - AVDictionary **metadatap = NULL; uint32_t tag, length; int decode_next_dat = 0; int i, ret; @@ -1215,7 +1220,7 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, } length = bytestream2_get_be32(&s->gb); - if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) { + if (length > 0x7fffffff || length + 8 > bytestream2_get_bytes_left(&s->gb)) { av_log(avctx, AV_LOG_ERROR, "chunk too big\n"); ret = AVERROR_INVALIDDATA; goto fail; @@ -1254,7 +1259,6 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, } } - metadatap = &p->metadata; switch (tag) { case MKTAG('I', 'H', 'D', 'R'): if ((ret = decode_ihdr_chunk(avctx, s, length)) < 0) @@ -1296,26 +1300,20 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, goto skip_tag; break; case MKTAG('t', 'E', 'X', 't'): - if (decode_text_chunk(s, length, 0, metadatap) < 0) + if (decode_text_chunk(s, length, 0) < 0) av_log(avctx, AV_LOG_WARNING, "Broken tEXt chunk\n"); bytestream2_skip(&s->gb, length + 4); break; case MKTAG('z', 'T', 'X', 't'): - if (decode_text_chunk(s, length, 1, metadatap) < 0) + if (decode_text_chunk(s, length, 1) < 0) av_log(avctx, AV_LOG_WARNING, "Broken zTXt chunk\n"); bytestream2_skip(&s->gb, length + 4); break; case MKTAG('s', 'T', 'E', 'R'): { int mode = bytestream2_get_byte(&s->gb); - AVStereo3D *stereo3d = av_stereo3d_create_side_data(p); - if (!stereo3d) { - ret = AVERROR(ENOMEM); - goto fail; - } if (mode == 0 || mode == 1) { - stereo3d->type = AV_STEREO3D_SIDEBYSIDE; - stereo3d->flags = mode ? 0 : AV_STEREO3D_FLAG_INVERT; + s->stereo_mode = mode; } else { av_log(avctx, AV_LOG_WARNING, "Unknown value in sTER chunk (%d)\n", mode); @@ -1329,22 +1327,17 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, break; } case MKTAG('c', 'H', 'R', 'M'): { - AVMasteringDisplayMetadata *mdm = av_mastering_display_metadata_create_side_data(p); - if (!mdm) { - ret = AVERROR(ENOMEM); - goto fail; - } + s->have_chrm = 1; - mdm->white_point[0] = av_make_q(bytestream2_get_be32(&s->gb), 100000); - mdm->white_point[1] = av_make_q(bytestream2_get_be32(&s->gb), 100000); + s->white_point[0] = bytestream2_get_be32(&s->gb); + s->white_point[1] = bytestream2_get_be32(&s->gb); /* RGB Primaries */ for (i = 0; i < 3; i++) { - mdm->display_primaries[i][0] = av_make_q(bytestream2_get_be32(&s->gb), 100000); - mdm->display_primaries[i][1] = av_make_q(bytestream2_get_be32(&s->gb), 100000); + s->display_primaries[i][0] = bytestream2_get_be32(&s->gb); + s->display_primaries[i][1] = bytestream2_get_be32(&s->gb); } - mdm->has_primaries = 1; bytestream2_skip(&s->gb, 4); /* crc */ break; } @@ -1359,7 +1352,7 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, if (ret < 0) return ret; - av_dict_set(&p->metadata, "gamma", gamma_str, AV_DICT_DONT_STRDUP_VAL); + av_dict_set(&s->frame_metadata, "gamma", gamma_str, AV_DICT_DONT_STRDUP_VAL); bytestream2_skip(&s->gb, 4); /* crc */ break; @@ -1402,7 +1395,7 @@ exit_loop: av_assert0(s->bit_depth > 1); for (y = 0; y < s->height; ++y) { - uint8_t *row = &s->image_buf[s->image_linesize * y]; + uint8_t *row = &p->data[0][p->linesize[0] * y]; if (s->bpp == 2 && byte_depth == 1) { uint8_t *pixel = &row[2 * s->width - 1]; @@ -1448,22 +1441,88 @@ exit_loop: if (CONFIG_PNG_DECODER && avctx->codec_id != AV_CODEC_ID_APNG) handle_p_frame_png(s, p); else if (CONFIG_APNG_DECODER && - s->previous_picture.f->width == p->width && - s->previous_picture.f->height== p->height && - s->previous_picture.f->format== p->format && avctx->codec_id == AV_CODEC_ID_APNG && (ret = handle_p_frame_apng(avctx, s, p)) < 0) goto fail; } } ff_thread_report_progress(&s->picture, INT_MAX, 0); - ff_thread_report_progress(&s->previous_picture, INT_MAX, 0); return 0; fail: ff_thread_report_progress(&s->picture, INT_MAX, 0); - ff_thread_report_progress(&s->previous_picture, INT_MAX, 0); + return ret; +} + +static void clear_frame_metadata(PNGDecContext *s) +{ + av_freep(&s->iccp_data); + s->iccp_data_len = 0; + s->iccp_name[0] = 0; + + s->stereo_mode = -1; + + s->have_chrm = 0; + + av_dict_free(&s->frame_metadata); +} + +static int output_frame(PNGDecContext *s, AVFrame *f, + const AVFrame *src) +{ + int ret; + + ret = av_frame_ref(f, src); + if (ret < 0) + return ret; + + if (s->iccp_data) { + AVFrameSideData *sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, s->iccp_data_len); + if (!sd) { + ret = AVERROR(ENOMEM); + goto fail; + } + memcpy(sd->data, s->iccp_data, s->iccp_data_len); + + av_dict_set(&sd->metadata, "name", s->iccp_name, 0); + } + + if (s->stereo_mode >= 0) { + AVStereo3D *stereo3d = av_stereo3d_create_side_data(f); + if (!stereo3d) { + ret = AVERROR(ENOMEM); + goto fail; + } + + stereo3d->type = AV_STEREO3D_SIDEBYSIDE; + stereo3d->flags = s->stereo_mode ? 0 : AV_STEREO3D_FLAG_INVERT; + } + + if (s->have_chrm) { + AVMasteringDisplayMetadata *mdm = av_mastering_display_metadata_create_side_data(f); + if (!mdm) { + ret = AVERROR(ENOMEM); + goto fail; + } + + mdm->white_point[0] = av_make_q(s->white_point[0], 100000); + mdm->white_point[1] = av_make_q(s->white_point[1], 100000); + + /* RGB Primaries */ + for (int i = 0; i < 3; i++) { + mdm->display_primaries[i][0] = av_make_q(s->display_primaries[i][0], 100000); + mdm->display_primaries[i][1] = av_make_q(s->display_primaries[i][1], 100000); + } + + mdm->has_primaries = 1; + } + + FFSWAP(AVDictionary*, f->metadata, s->frame_metadata); + + return 0; +fail: + av_frame_unref(f); return ret; } @@ -1475,13 +1534,12 @@ static int decode_frame_png(AVCodecContext *avctx, PNGDecContext *const s = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVFrame *p; + AVFrame *dst_frame = data; + AVFrame *p = s->picture.f; int64_t sig; int ret; - ff_thread_release_buffer(avctx, &s->last_picture); - FFSWAP(ThreadFrame, s->picture, s->last_picture); - p = s->picture.f; + clear_frame_metadata(s); bytestream2_init(&s->gb, buf, buf_size); @@ -1516,9 +1574,15 @@ static int decode_frame_png(AVCodecContext *avctx, goto the_end; } - if ((ret = av_frame_ref(data, s->picture.f)) < 0) + ret = output_frame(s, dst_frame, s->picture.f); + if (ret < 0) goto the_end; + if (!(avctx->active_thread_type & FF_THREAD_FRAME)) { + ff_thread_release_buffer(avctx, &s->last_picture); + FFSWAP(ThreadFrame, s->picture, s->last_picture); + } + *got_frame = 1; ret = bytestream2_tell(&s->gb); @@ -1535,12 +1599,11 @@ static int decode_frame_apng(AVCodecContext *avctx, AVPacket *avpkt) { PNGDecContext *const s = avctx->priv_data; + AVFrame *dst_frame = data; int ret; - AVFrame *p; + AVFrame *p = s->picture.f; - ff_thread_release_buffer(avctx, &s->last_picture); - FFSWAP(ThreadFrame, s->picture, s->last_picture); - p = s->picture.f; + clear_frame_metadata(s); if (!(s->hdr_state & PNG_IHDR)) { if (!avctx->extradata_size) @@ -1573,9 +1636,20 @@ static int decode_frame_apng(AVCodecContext *avctx, ret = AVERROR_INVALIDDATA; goto end; } - if ((ret = av_frame_ref(data, s->picture.f)) < 0) + + ret = output_frame(s, dst_frame, s->picture.f); + if (ret < 0) goto end; + if (!(avctx->active_thread_type & FF_THREAD_FRAME)) { + if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS) { + ff_thread_release_buffer(avctx, &s->picture); + } else if (s->dispose_op == APNG_DISPOSE_OP_NONE) { + ff_thread_release_buffer(avctx, &s->last_picture); + FFSWAP(ThreadFrame, s->picture, s->last_picture); + } + } + *got_frame = 1; ret = bytestream2_tell(&s->gb); @@ -1585,161 +1659,19 @@ end: } #endif -#if CONFIG_LSCR_DECODER -static int decode_frame_lscr(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt) -{ - PNGDecContext *const s = avctx->priv_data; - GetByteContext *gb = &s->gb; - AVFrame *frame = data; - int ret, nb_blocks, offset = 0; - - if (avpkt->size < 2) - return AVERROR_INVALIDDATA; - - bytestream2_init(gb, avpkt->data, avpkt->size); - - if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) - return ret; - - nb_blocks = bytestream2_get_le16(gb); - if (bytestream2_get_bytes_left(gb) < 2 + nb_blocks * (12 + 8)) - return AVERROR_INVALIDDATA; - - if (s->last_picture.f->data[0]) { - ret = av_frame_copy(frame, s->last_picture.f); - if (ret < 0) - return ret; - } - - for (int b = 0; b < nb_blocks; b++) { - int x, y, x2, y2, w, h, left; - uint32_t csize, size; - - s->zstream.zalloc = ff_png_zalloc; - s->zstream.zfree = ff_png_zfree; - s->zstream.opaque = NULL; - - if ((ret = inflateInit(&s->zstream)) != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret); - ret = AVERROR_EXTERNAL; - goto end; - } - - bytestream2_seek(gb, 2 + b * 12, SEEK_SET); - - x = bytestream2_get_le16(gb); - y = bytestream2_get_le16(gb); - x2 = bytestream2_get_le16(gb); - y2 = bytestream2_get_le16(gb); - s->width = s->cur_w = w = x2-x; - s->height = s->cur_h = h = y2-y; - - if (w <= 0 || x < 0 || x >= avctx->width || w + x > avctx->width || - h <= 0 || y < 0 || y >= avctx->height || h + y > avctx->height) { - ret = AVERROR_INVALIDDATA; - goto end; - } - - size = bytestream2_get_le32(gb); - - frame->key_frame = (nb_blocks == 1) && - (w == avctx->width) && - (h == avctx->height) && - (x == 0) && (y == 0); - - bytestream2_seek(gb, 2 + nb_blocks * 12 + offset, SEEK_SET); - csize = bytestream2_get_be32(gb); - if (bytestream2_get_le32(gb) != MKTAG('I', 'D', 'A', 'T')) { - ret = AVERROR_INVALIDDATA; - goto end; - } - - offset += size; - left = size; - - s->y = 0; - s->row_size = w * 3; - - av_fast_padded_malloc(&s->buffer, &s->buffer_size, s->row_size + 16); - if (!s->buffer) { - ret = AVERROR(ENOMEM); - goto end; - } - - av_fast_padded_malloc(&s->last_row, &s->last_row_size, s->row_size); - if (!s->last_row) { - ret = AVERROR(ENOMEM); - goto end; - } - - s->crow_size = w * 3 + 1; - s->crow_buf = s->buffer + 15; - s->zstream.avail_out = s->crow_size; - s->zstream.next_out = s->crow_buf; - s->image_buf = frame->data[0] + (avctx->height - y - 1) * frame->linesize[0] + x * 3; - s->image_linesize =-frame->linesize[0]; - s->bpp = 3; - s->pic_state = 0; - - while (left > 16) { - ret = png_decode_idat(s, csize); - if (ret < 0) - goto end; - left -= csize + 16; - if (left > 16) { - bytestream2_skip(gb, 4); - csize = bytestream2_get_be32(gb); - if (bytestream2_get_le32(gb) != MKTAG('I', 'D', 'A', 'T')) { - ret = AVERROR_INVALIDDATA; - goto end; - } - } - } - - inflateEnd(&s->zstream); - } - - frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - - av_frame_unref(s->last_picture.f); - if ((ret = av_frame_ref(s->last_picture.f, frame)) < 0) - return ret; - - *got_frame = 1; -end: - inflateEnd(&s->zstream); - - if (ret < 0) - return ret; - return avpkt->size; -} - -static void decode_flush(AVCodecContext *avctx) -{ - PNGDecContext *s = avctx->priv_data; - - av_frame_unref(s->last_picture.f); -} - -#endif - #if HAVE_THREADS static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { PNGDecContext *psrc = src->priv_data; PNGDecContext *pdst = dst->priv_data; + ThreadFrame *src_frame = NULL; int ret; if (dst == src) return 0; - ff_thread_release_buffer(dst, &pdst->picture); - if (psrc->picture.f->data[0] && - (ret = ff_thread_ref_frame(&pdst->picture, &psrc->picture)) < 0) - return ret; if (CONFIG_APNG_DECODER && dst->codec_id == AV_CODEC_ID_APNG) { + pdst->width = psrc->width; pdst->height = psrc->height; pdst->bit_depth = psrc->bit_depth; @@ -1759,15 +1691,15 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) memcpy(pdst->palette, psrc->palette, sizeof(pdst->palette)); pdst->hdr_state |= psrc->hdr_state; + } - ff_thread_release_buffer(dst, &pdst->last_picture); - if (psrc->last_picture.f->data[0] && - (ret = ff_thread_ref_frame(&pdst->last_picture, &psrc->last_picture)) < 0) - return ret; + src_frame = psrc->dispose_op == APNG_DISPOSE_OP_NONE ? + &psrc->picture : &psrc->last_picture; - ff_thread_release_buffer(dst, &pdst->previous_picture); - if (psrc->previous_picture.f->data[0] && - (ret = ff_thread_ref_frame(&pdst->previous_picture, &psrc->previous_picture)) < 0) + ff_thread_release_buffer(dst, &pdst->last_picture); + if (src_frame && src_frame->f->data[0]) { + ret = ff_thread_ref_frame(&pdst->last_picture, src_frame); + if (ret < 0) return ret; } @@ -1781,15 +1713,10 @@ static av_cold int png_dec_init(AVCodecContext *avctx) avctx->color_range = AVCOL_RANGE_JPEG; - if (avctx->codec_id == AV_CODEC_ID_LSCR) - avctx->pix_fmt = AV_PIX_FMT_BGR24; - s->avctx = avctx; - s->previous_picture.f = av_frame_alloc(); s->last_picture.f = av_frame_alloc(); s->picture.f = av_frame_alloc(); - if (!s->previous_picture.f || !s->last_picture.f || !s->picture.f) { - av_frame_free(&s->previous_picture.f); + if (!s->last_picture.f || !s->picture.f) { av_frame_free(&s->last_picture.f); av_frame_free(&s->picture.f); return AVERROR(ENOMEM); @@ -1804,8 +1731,6 @@ static av_cold int png_dec_end(AVCodecContext *avctx) { PNGDecContext *s = avctx->priv_data; - ff_thread_release_buffer(avctx, &s->previous_picture); - av_frame_free(&s->previous_picture.f); ff_thread_release_buffer(avctx, &s->last_picture); av_frame_free(&s->last_picture.f); ff_thread_release_buffer(avctx, &s->picture); @@ -1816,6 +1741,10 @@ static av_cold int png_dec_end(AVCodecContext *avctx) s->last_row_size = 0; av_freep(&s->tmp_row); s->tmp_row_size = 0; + av_freep(&s->background_buf); + + av_freep(&s->iccp_data); + av_dict_free(&s->frame_metadata); return 0; } @@ -1853,20 +1782,3 @@ AVCodec ff_png_decoder = { FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #endif - -#if CONFIG_LSCR_DECODER -AVCodec ff_lscr_decoder = { - .name = "lscr", - .long_name = NULL_IF_CONFIG_SMALL("LEAD Screen Capture"), - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_LSCR, - .priv_data_size = sizeof(PNGDecContext), - .init = png_dec_init, - .close = png_dec_end, - .decode = decode_frame_lscr, - .flush = decode_flush, - .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE | - FF_CODEC_CAP_ALLOCATE_PROGRESS, -}; -#endif diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c index efcae8c49..eebb16444 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -1174,7 +1174,7 @@ AVCodec ff_apng_encoder = { AV_PIX_FMT_PAL8, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_YA16BE, - AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE + AV_PIX_FMT_NONE }, .priv_class = &apngenc_class, }; diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c index aad23c7ae..958f2a342 100644 --- a/libavcodec/pnm.c +++ b/libavcodec/pnm.c @@ -72,6 +72,7 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) s->bytestream[0] != 'P' || (s->bytestream[1] < '1' || s->bytestream[1] > '7' && + s->bytestream[1] != 'f' && s->bytestream[1] != 'F')) { s->bytestream += s->bytestream_end > s->bytestream; s->bytestream += s->bytestream_end > s->bytestream; @@ -82,6 +83,8 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) if (buf1[1] == 'F') { avctx->pix_fmt = AV_PIX_FMT_GBRPF32; + } else if (buf1[1] == 'f') { + avctx->pix_fmt = AV_PIX_FMT_GRAYF32; } else if (s->type==1 || s->type==4) { avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; } else if (s->type==2 || s->type==5) { @@ -177,7 +180,7 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) if (ret < 0) return ret; - if (avctx->pix_fmt == AV_PIX_FMT_GBRPF32) { + if (avctx->pix_fmt == AV_PIX_FMT_GBRPF32 || avctx->pix_fmt == AV_PIX_FMT_GRAYF32) { pnm_get(s, buf1, sizeof(buf1)); if (av_sscanf(buf1, "%f", &s->scale) != 1 || s->scale == 0.0 || !isfinite(s->scale)) { av_log(avctx, AV_LOG_ERROR, "Invalid scale.\n"); @@ -218,7 +221,8 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) return AVERROR_INVALIDDATA; /* more check if YUV420 */ - if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR) { + if ((av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR) && + avctx->pix_fmt != AV_PIX_FMT_GBRPF32) { if ((avctx->width & 1) != 0) return AVERROR_INVALIDDATA; h = (avctx->height * 2); diff --git a/libavcodec/pnm_parser.c b/libavcodec/pnm_parser.c index f3be6d640..a822c17a2 100644 --- a/libavcodec/pnm_parser.c +++ b/libavcodec/pnm_parser.c @@ -111,7 +111,7 @@ retry: } else { int ret = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1); next = pnmctx.bytestream - pnmctx.bytestream_start + skip; - if (ret >= 0) + if (ret >= 0 && next + (uint64_t)ret <= INT_MAX) next += ret; } if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip) diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c index 9add5cfc8..4d5ce0bcb 100644 --- a/libavcodec/pnmdec.c +++ b/libavcodec/pnmdec.c @@ -297,6 +297,30 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, } } break; + case AV_PIX_FMT_GRAYF32: + if (avctx->width * avctx->height * 4 > s->bytestream_end - s->bytestream) + return AVERROR_INVALIDDATA; + scale = 1.f / s->scale; + if (s->endian) { + float *g = (float *)p->data[0]; + for (int i = 0; i < avctx->height; i++) { + for (int j = 0; j < avctx->width; j++) { + g[j] = av_int2float(AV_RL32(s->bytestream)) * scale; + s->bytestream += 4; + } + g += p->linesize[0] / 4; + } + } else { + float *g = (float *)p->data[0]; + for (int i = 0; i < avctx->height; i++) { + for (int j = 0; j < avctx->width; j++) { + g[j] = av_int2float(AV_RB32(s->bytestream)) * scale; + s->bytestream += 4; + } + g += p->linesize[0] / 4; + } + } + break; } *got_frame = 1; diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c index ba9478d0d..276504bf1 100644 --- a/libavcodec/pnmenc.c +++ b/libavcodec/pnmenc.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" #include "libavutil/pixdesc.h" #include "avcodec.h" @@ -77,19 +78,46 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, n = avctx->width * 2; h1 = (h * 3) / 2; break; + case AV_PIX_FMT_GBRPF32: + c = 'F'; + n = avctx->width * 4; + break; default: return -1; } snprintf(bytestream, bytestream_end - bytestream, "P%c\n%d %d\n", c, avctx->width, h1); bytestream += strlen(bytestream); - if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) { + if (avctx->pix_fmt == AV_PIX_FMT_GBRPF32) + snprintf(bytestream, bytestream_end - bytestream, + "%f\n", avctx->pix_fmt == AV_PIX_FMT_GBRPF32BE ? 1.f: -1.f); + bytestream += strlen(bytestream); + if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE && + avctx->pix_fmt != AV_PIX_FMT_GBRPF32) { int maxdepth = (1 << av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth) - 1; snprintf(bytestream, bytestream_end - bytestream, "%d\n", maxdepth); bytestream += strlen(bytestream); } + if (avctx->pix_fmt == AV_PIX_FMT_GBRPF32) { + float *r = (float *)p->data[2]; + float *g = (float *)p->data[0]; + float *b = (float *)p->data[1]; + + for (int i = 0; i < avctx->height; i++) { + for (int j = 0; j < avctx->width; j++) { + AV_WN32(bytestream + 0, av_float2int(r[j])); + AV_WN32(bytestream + 4, av_float2int(g[j])); + AV_WN32(bytestream + 8, av_float2int(b[j])); + bytestream += 12; + } + + r += p->linesize[2] / 4; + g += p->linesize[0] / 4; + b += p->linesize[1] / 4; + } + } else { ptr = p->data[0]; linesize = p->linesize[0]; for (i = 0; i < h; i++) { @@ -97,6 +125,7 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream += n; ptr += linesize; } + } if (avctx->pix_fmt == AV_PIX_FMT_YUV420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P16BE) { h >>= 1; @@ -142,6 +171,7 @@ AVCodec ff_pgm_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif @@ -156,6 +186,7 @@ AVCodec ff_pgmyuv_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif @@ -170,6 +201,7 @@ AVCodec ff_ppm_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif @@ -183,5 +215,20 @@ AVCodec ff_pbm_encoder = { .encode2 = pnm_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, +}; +#endif + +#if CONFIG_PFM_ENCODER +AVCodec ff_pfm_encoder = { + .name = "pfm", + .long_name = NULL_IF_CONFIG_SMALL("PFM (Portable FloatMap) image"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_PFM, + .init = pnm_encode_init, + .encode2 = pnm_encode_frame, + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_GBRPF32, + AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif diff --git a/libavcodec/ppc/h264chroma_template.c b/libavcodec/ppc/h264chroma_template.c index 8f43e5dee..eda98c67e 100644 --- a/libavcodec/ppc/h264chroma_template.c +++ b/libavcodec/ppc/h264chroma_template.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/ppc/util_altivec.h" /* this code assume that stride % 16 == 0 */ diff --git a/libavcodec/ppc/h264dsp.c b/libavcodec/ppc/h264dsp.c index d8a3baa34..779092fd7 100644 --- a/libavcodec/ppc/h264dsp.c +++ b/libavcodec/ppc/h264dsp.c @@ -26,7 +26,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/ppc/cpu.h" #include "libavutil/ppc/util_altivec.h" diff --git a/libavcodec/ppc/h264qpel.c b/libavcodec/ppc/h264qpel.c index bef421fa4..fe896c845 100644 --- a/libavcodec/ppc/h264qpel.c +++ b/libavcodec/ppc/h264qpel.c @@ -23,6 +23,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "libavutil/ppc/cpu.h" #include "libavutil/ppc/util_altivec.h" diff --git a/libavcodec/ppc/mpegaudiodsp_altivec.c b/libavcodec/ppc/mpegaudiodsp_altivec.c index efa9fd5fe..6794ed092 100644 --- a/libavcodec/ppc/mpegaudiodsp_altivec.c +++ b/libavcodec/ppc/mpegaudiodsp_altivec.c @@ -23,6 +23,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/ppc/cpu.h" #include "libavutil/ppc/util_altivec.h" #include "libavcodec/mpegaudiodsp.h" diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c index 2c6ff9165..bcb59ba84 100644 --- a/libavcodec/ppc/mpegvideo_altivec.c +++ b/libavcodec/ppc/mpegvideo_altivec.c @@ -28,6 +28,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/ppc/cpu.h" #include "libavutil/ppc/util_altivec.h" diff --git a/libavcodec/ppc/mpegvideodsp.c b/libavcodec/ppc/mpegvideodsp.c index 990a974a4..81f4845e6 100644 --- a/libavcodec/ppc/mpegvideodsp.c +++ b/libavcodec/ppc/mpegvideodsp.c @@ -21,7 +21,7 @@ */ #include "libavutil/cpu.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/ppc/cpu.h" #include "libavutil/ppc/util_altivec.h" diff --git a/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c index 31201ed2d..64ee703dc 100644 --- a/libavcodec/ppc/vp8dsp_altivec.c +++ b/libavcodec/ppc/vp8dsp_altivec.c @@ -23,7 +23,7 @@ #include "config.h" #include "libavutil/cpu.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/ppc/cpu.h" #include "libavutil/ppc/util_altivec.h" diff --git a/libavcodec/profiles.c b/libavcodec/profiles.c index e59a3a5c1..7af7fbeb1 100644 --- a/libavcodec/profiles.c +++ b/libavcodec/profiles.c @@ -74,6 +74,12 @@ const AVProfile ff_h264_profiles[] = { { FF_PROFILE_UNKNOWN }, }; +const AVProfile ff_vvc_profiles[] = { + { FF_PROFILE_VVC_MAIN_10, "Main 10" }, + { FF_PROFILE_VVC_MAIN_10_444, "Main 10 4:4:4" }, + { FF_PROFILE_UNKNOWN }, +}; + const AVProfile ff_hevc_profiles[] = { { FF_PROFILE_HEVC_MAIN, "Main" }, { FF_PROFILE_HEVC_MAIN_10, "Main 10" }, diff --git a/libavcodec/profiles.h b/libavcodec/profiles.h index d2419257d..41a19aa9a 100644 --- a/libavcodec/profiles.h +++ b/libavcodec/profiles.h @@ -51,11 +51,17 @@ FF_AVCTX_PROFILE_OPTION("main", NULL, VIDEO, FF_PROFILE_MPEG2_MAIN)\ FF_AVCTX_PROFILE_OPTION("simple", NULL, VIDEO, FF_PROFILE_MPEG2_SIMPLE)\ +#define FF_AV1_PROFILE_OPTS \ + FF_AVCTX_PROFILE_OPTION("main", NULL, VIDEO, FF_PROFILE_AV1_MAIN)\ + FF_AVCTX_PROFILE_OPTION("high", NULL, VIDEO, FF_PROFILE_AV1_HIGH)\ + FF_AVCTX_PROFILE_OPTION("professional", NULL, VIDEO, FF_PROFILE_AV1_PROFESSIONAL)\ + extern const AVProfile ff_aac_profiles[]; extern const AVProfile ff_dca_profiles[]; extern const AVProfile ff_dnxhd_profiles[]; extern const AVProfile ff_h264_profiles[]; extern const AVProfile ff_hevc_profiles[]; +extern const AVProfile ff_vvc_profiles[]; extern const AVProfile ff_jpeg2000_profiles[]; extern const AVProfile ff_mpeg2_video_profiles[]; extern const AVProfile ff_mpeg4_video_profiles[]; diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index d5fbfc671..5a01c89c4 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -29,6 +29,8 @@ #define LONG_BITSTREAM_READER #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "get_bits.h" #include "idctdsp.h" @@ -289,7 +291,7 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, } permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr); } else { - memset(ctx->qmat_chroma, 4, 64); + memcpy(ctx->qmat_chroma, ctx->qmat_luma, 64); } return hdr_size; @@ -621,8 +623,8 @@ 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, a_data_size; - uint8_t *dest_y, *dest_u, *dest_v, *dest_a; + int y_data_size, u_data_size, v_data_size, a_data_size, offset; + uint8_t *dest_y, *dest_u, *dest_v; LOCAL_ALIGNED_16(int16_t, qmat_luma_scaled, [64]); LOCAL_ALIGNED_16(int16_t, qmat_chroma_scaled,[64]); int mb_x_shift; @@ -674,16 +676,16 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int log2_chroma_blocks_per_mb = 1; } - dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); + offset = (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); + dest_y = pic->data[0] + offset; 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]; + offset += pic->linesize[3]; } ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride, @@ -720,10 +722,12 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int } /* decode alpha plane if available */ - if (ctx->alpha_info && pic->data[3] && a_data_size) + if (ctx->alpha_info && pic->data[3] && a_data_size) { + uint8_t *dest_a = pic->data[3] + offset; 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; @@ -818,7 +822,7 @@ static av_cold int decode_close(AVCodecContext *avctx) AVCodec ff_prores_decoder = { .name = "prores", - .long_name = NULL_IF_CONFIG_SMALL("ProRes (iCodec Pro)"), + .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PRORES, .priv_data_size = sizeof(ProresContext), diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c index 112897833..2d03f4d8c 100644 --- a/libavcodec/proresenc_anatoliy.c +++ b/libavcodec/proresenc_anatoliy.c @@ -27,6 +27,7 @@ * Known FOURCCs: 'ap4h' (444), 'apch' (HQ), 'apcn' (422), 'apcs' (LT), 'acpo' (Proxy) */ +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "avcodec.h" #include "dct.h" @@ -49,15 +50,16 @@ static const AVProfile profiles[] = { { FF_PROFILE_UNKNOWN } }; -static const int qp_start_table[6] = { 8, 3, 2, 1, 1, 1}; -static const int qp_end_table[6] = { 13, 9, 6, 6, 5, 4}; -static const int bitrate_table[6] = { 1000, 2100, 3500, 5400, 7000, 10000}; +static const int qp_start_table[] = { 8, 3, 2, 1, 1, 1}; +static const int qp_end_table[] = { 13, 9, 6, 6, 5, 4}; +static const int bitrate_table[] = { 1000, 2100, 3500, 5400, 7000, 10000}; -static const int valid_primaries[9] = { AVCOL_PRI_RESERVED0, AVCOL_PRI_BT709, AVCOL_PRI_UNSPECIFIED, AVCOL_PRI_BT470BG, - AVCOL_PRI_SMPTE170M, AVCOL_PRI_BT2020, AVCOL_PRI_SMPTE431, AVCOL_PRI_SMPTE432,INT_MAX }; -static const int valid_trc[4] = { AVCOL_TRC_RESERVED0, AVCOL_TRC_BT709, AVCOL_TRC_UNSPECIFIED, INT_MAX }; -static const int valid_colorspace[5] = { AVCOL_SPC_BT709, AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_SMPTE170M, - AVCOL_SPC_BT2020_NCL, INT_MAX }; +static const int valid_primaries[] = { AVCOL_PRI_RESERVED0, AVCOL_PRI_BT709, AVCOL_PRI_UNSPECIFIED, AVCOL_PRI_BT470BG, + AVCOL_PRI_SMPTE170M, AVCOL_PRI_BT2020, AVCOL_PRI_SMPTE431, AVCOL_PRI_SMPTE432, INT_MAX }; +static const int valid_trc[] = { AVCOL_TRC_RESERVED0, AVCOL_TRC_BT709, AVCOL_TRC_UNSPECIFIED, AVCOL_TRC_SMPTE2084, + AVCOL_TRC_ARIB_STD_B67, INT_MAX }; +static const int valid_colorspace[] = { AVCOL_SPC_BT709, AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_SMPTE170M, + AVCOL_SPC_BT2020_NCL, INT_MAX }; static const uint8_t QMAT_LUMA[6][64] = { { @@ -955,6 +957,7 @@ AVCodec ff_prores_aw_encoder = { .capabilities = AV_CODEC_CAP_FRAME_THREADS, .priv_class = &proresaw_enc_class, .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles), + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; AVCodec ff_prores_encoder = { @@ -970,4 +973,5 @@ AVCodec ff_prores_encoder = { .capabilities = AV_CODEC_CAP_FRAME_THREADS, .priv_class = &prores_enc_class, .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles), + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c index 8e6f905a9..0e70163bc 100644 --- a/libavcodec/proresenc_kostya.c +++ b/libavcodec/proresenc_kostya.c @@ -23,6 +23,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avcodec.h" diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 572471586..14b7cca4f 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -56,7 +56,7 @@ static void validate_thread_parameters(AVCodecContext *avctx) } else if (avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS && avctx->thread_type & FF_THREAD_SLICE) { avctx->active_thread_type = FF_THREAD_SLICE; - } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_AUTO_THREADS)) { + } else if (!(avctx->codec->caps_internal & FF_CODEC_CAP_AUTO_THREADS)) { avctx->thread_count = 1; avctx->active_thread_type = 0; } diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 601f17044..9176027f1 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -64,6 +64,12 @@ enum { STATE_SETUP_FINISHED, }; +enum { + UNINITIALIZED, ///< Thread has not been created, AVCodec->close mustn't be called + NEEDS_CLOSE, ///< AVCodec->close needs to be called + INITIALIZED, ///< Thread has been properly set up +}; + /** * Context used by codec threads and stored in their AVCodecInternal thread_ctx. */ @@ -72,6 +78,7 @@ typedef struct PerThreadContext { pthread_t thread; int thread_init; + unsigned pthread_init_cnt;///< Number of successfully initialized mutexes/conditions 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. @@ -81,7 +88,7 @@ typedef struct PerThreadContext { AVCodecContext *avctx; ///< Context used to decode packets passed to this thread. - AVPacket avpkt; ///< Input packet (for decoding) or output (for encoding). + AVPacket *avpkt; ///< Input packet (for decoding) or output (for encoding). 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. @@ -89,6 +96,7 @@ typedef struct PerThreadContext { atomic_int state; +#if FF_API_THREAD_SAFE_CALLBACKS /** * Array of frames passed to ff_thread_release_buffer(). * Frames are released after all threads referencing them are finished. @@ -102,6 +110,7 @@ typedef struct PerThreadContext { const enum AVPixelFormat *available_formats; ///< Format array for get_format() enum AVPixelFormat result_format; ///< get_format() result +#endif int die; ///< Set when the thread should exit. @@ -118,6 +127,7 @@ typedef struct FrameThreadContext { PerThreadContext *threads; ///< The contexts for each thread. PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on. + unsigned pthread_init_cnt; ///< Number of successfully initialized mutexes/conditions pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer(). /** * This lock is used for ensuring threads run in serial when hwaccel @@ -137,8 +147,10 @@ typedef struct FrameThreadContext { */ } FrameThreadContext; +#if FF_API_THREAD_SAFE_CALLBACKS #define THREAD_SAFE_CALLBACKS(avctx) \ ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2) +#endif static void async_lock(FrameThreadContext *fctx) { @@ -178,8 +190,14 @@ static attribute_align_arg void *frame_worker_thread(void *arg) if (p->die) break; - if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx)) +FF_DISABLE_DEPRECATION_WARNINGS + if (!codec->update_thread_context +#if FF_API_THREAD_SAFE_CALLBACKS + && THREAD_SAFE_CALLBACKS(avctx) +#endif + ) ff_thread_finish_setup(avctx); +FF_ENABLE_DEPRECATION_WARNINGS /* If a decoder supports hwaccel, then it must call ff_get_format(). * Since that call must happen before ff_thread_finish_setup(), the @@ -198,7 +216,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg) av_frame_unref(p->frame); p->got_frame = 0; - p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt); + p->result = codec->decode(avctx, p->frame, &p->got_frame, p->avpkt); if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) { if (avctx->codec->caps_internal & FF_CODEC_CAP_ALLOCATE_PROGRESS) @@ -246,7 +264,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, { int err = 0; - if (dst != src && (for_user || !(src->codec_descriptor->props & AV_CODEC_PROP_INTRA_ONLY))) { + if (dst != src && (for_user || src->codec->update_thread_context)) { dst->time_base = src->time_base; dst->framerate = src->framerate; dst->width = src->width; @@ -297,16 +315,9 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, dst->hwaccel_flags = src->hwaccel_flags; - if (!!dst->internal->pool != !!src->internal->pool || - (dst->internal->pool && dst->internal->pool->data != src->internal->pool->data)) { - av_buffer_unref(&dst->internal->pool); - - if (src->internal->pool) { - dst->internal->pool = av_buffer_ref(src->internal->pool); - if (!dst->internal->pool) - return AVERROR(ENOMEM); - } - } + err = av_buffer_replace(&dst->internal->pool, src->internal->pool); + if (err < 0) + return err; } if (for_user) { @@ -339,7 +350,6 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) dst->opaque = src->opaque; dst->debug = src->debug; - dst->debug_mv = src->debug_mv; dst->slice_flags = src->slice_flags; dst->flags2 = src->flags2; @@ -351,7 +361,11 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) dst->frame_number = src->frame_number; dst->reordered_opaque = src->reordered_opaque; +#if FF_API_THREAD_SAFE_CALLBACKS +FF_DISABLE_DEPRECATION_WARNINGS dst->thread_safe_callbacks = src->thread_safe_callbacks; +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (src->slice_count && src->slice_offset) { if (dst->slice_count < src->slice_count) { @@ -367,6 +381,7 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) return 0; } +#if FF_API_THREAD_SAFE_CALLBACKS /// Releases the buffers that this decoding thread was the last user of. static void release_delayed_buffers(PerThreadContext *p) { @@ -387,6 +402,7 @@ static void release_delayed_buffers(PerThreadContext *p) pthread_mutex_unlock(&fctx->buffer_mutex); } } +#endif static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, AVPacket *avpkt) @@ -410,7 +426,9 @@ static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, (p->avctx->debug & FF_DEBUG_THREADS) != 0, memory_order_relaxed); +#if FF_API_THREAD_SAFE_CALLBACKS release_delayed_buffers(p); +#endif if (prev_thread) { int err; @@ -428,8 +446,8 @@ static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, } } - av_packet_unref(&p->avpkt); - ret = av_packet_ref(&p->avpkt, avpkt); + av_packet_unref(p->avpkt); + ret = av_packet_ref(p->avpkt, avpkt); if (ret < 0) { pthread_mutex_unlock(&p->mutex); av_log(p->avctx, AV_LOG_ERROR, "av_packet_ref() failed in submit_packet()\n"); @@ -440,6 +458,8 @@ static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, pthread_cond_signal(&p->input_cond); pthread_mutex_unlock(&p->mutex); +#if FF_API_THREAD_SAFE_CALLBACKS +FF_DISABLE_DEPRECATION_WARNINGS /* * If the client doesn't have a thread-safe get_buffer(), * then decoding threads call back to the main thread, @@ -473,6 +493,8 @@ static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, pthread_mutex_unlock(&p->progress_mutex); } } +FF_ENABLE_DEPRECATION_WARNINGS +#endif fctx->prev_thread = p; fctx->next_decoding++; @@ -536,7 +558,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, av_frame_move_ref(picture, p->frame); *got_picture_ptr = p->got_frame; - picture->pkt_dts = p->avpkt.dts; + picture->pkt_dts = p->avpkt->dts; err = p->result; /* @@ -660,11 +682,64 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count async_lock(fctx); } +#define SENTINEL 0 // This forbids putting a mutex/condition variable at the front. +#define OFFSET_ARRAY(...) __VA_ARGS__, SENTINEL +#define DEFINE_OFFSET_ARRAY(type, name, mutexes, conds) \ +static const unsigned name ## _offsets[] = { offsetof(type, pthread_init_cnt),\ + OFFSET_ARRAY mutexes, \ + OFFSET_ARRAY conds } + +#define OFF(member) offsetof(FrameThreadContext, member) +DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, + (OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)), + (OFF(async_cond))); +#undef OFF + +#define OFF(member) offsetof(PerThreadContext, member) +DEFINE_OFFSET_ARRAY(PerThreadContext, per_thread, + (OFF(progress_mutex), OFF(mutex)), + (OFF(input_cond), OFF(progress_cond), OFF(output_cond))); +#undef OFF + +static av_cold void free_pthread(void *obj, const unsigned offsets[]) +{ + unsigned cnt = *(unsigned*)((char*)obj + offsets[0]); + const unsigned *cur_offset = offsets; + + for (; *(++cur_offset) != SENTINEL && cnt; cnt--) + pthread_mutex_destroy((pthread_mutex_t*)((char*)obj + *cur_offset)); + for (; *(++cur_offset) != SENTINEL && cnt; cnt--) + pthread_cond_destroy ((pthread_cond_t *)((char*)obj + *cur_offset)); +} + +static av_cold int init_pthread(void *obj, const unsigned offsets[]) +{ + const unsigned *cur_offset = offsets; + unsigned cnt = 0; + int err; + +#define PTHREAD_INIT_LOOP(type) \ + for (; *(++cur_offset) != SENTINEL; cnt++) { \ + pthread_ ## type ## _t *dst = (void*)((char*)obj + *cur_offset); \ + err = pthread_ ## type ## _init(dst, NULL); \ + if (err) { \ + err = AVERROR(err); \ + goto fail; \ + } \ + } + PTHREAD_INIT_LOOP(mutex) + PTHREAD_INIT_LOOP(cond) + +fail: + *(unsigned*)((char*)obj + offsets[0]) = cnt; + return err; +} + void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) { FrameThreadContext *fctx = avctx->internal->thread_ctx; const AVCodec *codec = avctx->codec; - int i, j; + int i; park_frame_worker_threads(fctx, thread_count); @@ -684,59 +759,49 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; + AVCodecContext *ctx = p->avctx; - pthread_mutex_lock(&p->mutex); - p->die = 1; - pthread_cond_signal(&p->input_cond); - pthread_mutex_unlock(&p->mutex); + if (ctx->internal) { + if (p->thread_init == INITIALIZED) { + pthread_mutex_lock(&p->mutex); + p->die = 1; + pthread_cond_signal(&p->input_cond); + pthread_mutex_unlock(&p->mutex); - if (p->thread_init) - pthread_join(p->thread, NULL); - p->thread_init=0; + pthread_join(p->thread, NULL); + } + if (codec->close && p->thread_init != UNINITIALIZED) + codec->close(ctx); - if (codec->close && p->avctx) - codec->close(p->avctx); +#if FF_API_THREAD_SAFE_CALLBACKS + release_delayed_buffers(p); + for (int j = 0; j < p->released_buffers_allocated; j++) + av_frame_free(&p->released_buffers[j]); + av_freep(&p->released_buffers); +#endif + if (ctx->priv_data) { + if (codec->priv_class) + av_opt_free(ctx->priv_data); + av_freep(&ctx->priv_data); + } + + av_freep(&ctx->slice_offset); + + av_buffer_unref(&ctx->internal->pool); + av_freep(&ctx->internal); + av_buffer_unref(&ctx->hw_frames_ctx); + } - release_delayed_buffers(p); av_frame_free(&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_packet_unref(&p->avpkt); - - for (j = 0; j < p->released_buffers_allocated; j++) - av_frame_free(&p->released_buffers[j]); - av_freep(&p->released_buffers); - - if (p->avctx) { - if (codec->priv_class) - av_opt_free(p->avctx->priv_data); - av_freep(&p->avctx->priv_data); - - av_freep(&p->avctx->slice_offset); - } - - if (p->avctx) { - av_buffer_unref(&p->avctx->internal->pool); - av_freep(&p->avctx->internal); - av_buffer_unref(&p->avctx->hw_frames_ctx); - } + free_pthread(p, per_thread_offsets); + av_packet_free(&p->avpkt); av_freep(&p->avctx); } av_freep(&fctx->threads); - pthread_mutex_destroy(&fctx->buffer_mutex); - pthread_mutex_destroy(&fctx->hwaccel_mutex); - pthread_mutex_destroy(&fctx->async_mutex); - pthread_cond_destroy(&fctx->async_cond); + free_pthread(fctx, thread_ctx_offsets); av_freep(&avctx->internal->thread_ctx); @@ -745,20 +810,92 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) avctx->codec = NULL; } +static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, + FrameThreadContext *fctx, AVCodecContext *avctx, + AVCodecContext *src, const AVCodec *codec, int first) +{ + AVCodecContext *copy; + int err; + + atomic_init(&p->state, STATE_INPUT_READY); + + copy = av_memdup(src, sizeof(*src)); + if (!copy) + return AVERROR(ENOMEM); + copy->priv_data = NULL; + + /* From now on, this PerThreadContext will be cleaned up by + * ff_frame_thread_free in case of errors. */ + (*threads_to_free)++; + + p->parent = fctx; + p->avctx = copy; + + copy->internal = av_memdup(src->internal, sizeof(*src->internal)); + if (!copy->internal) + return AVERROR(ENOMEM); + copy->internal->thread_ctx = p; + + copy->delay = avctx->delay; + + if (codec->priv_data_size) { + copy->priv_data = av_mallocz(codec->priv_data_size); + if (!copy->priv_data) + return AVERROR(ENOMEM); + + if (codec->priv_class) { + *(const AVClass **)copy->priv_data = codec->priv_class; + err = av_opt_copy(copy->priv_data, src->priv_data); + if (err < 0) + return err; + } + } + + err = init_pthread(p, per_thread_offsets); + if (err < 0) + return err; + + if (!(p->frame = av_frame_alloc()) || + !(p->avpkt = av_packet_alloc())) + return AVERROR(ENOMEM); + copy->internal->last_pkt_props = p->avpkt; + + if (!first) + copy->internal->is_copy = 1; + + if (codec->init) { + err = codec->init(copy); + if (err < 0) { + if (codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP) + p->thread_init = NEEDS_CLOSE; + return err; + } + } + p->thread_init = NEEDS_CLOSE; + + if (first) + update_context_from_thread(avctx, copy, 1); + + atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); + + err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); + if (err < 0) + return err; + p->thread_init = INITIALIZED; + + return 0; +} + int ff_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; + int err, i = 0; if (!thread_count) { int nb_cpus = av_cpu_count(); -#if FF_API_DEBUG_MV - if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv) - nb_cpus = 1; -#endif // 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); @@ -775,101 +912,38 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (!fctx) return AVERROR(ENOMEM); - fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); - if (!fctx->threads) { + err = init_pthread(fctx, thread_ctx_offsets); + if (err < 0) { + free_pthread(fctx, thread_ctx_offsets); av_freep(&avctx->internal->thread_ctx); - return AVERROR(ENOMEM); + return err; } - pthread_mutex_init(&fctx->buffer_mutex, NULL); - pthread_mutex_init(&fctx->hwaccel_mutex, NULL); - pthread_mutex_init(&fctx->async_mutex, NULL); - pthread_cond_init(&fctx->async_cond, NULL); - fctx->async_lock = 1; fctx->delaying = 1; if (codec->type == AVMEDIA_TYPE_VIDEO) avctx->delay = src->thread_count - 1; - for (i = 0; i < thread_count; i++) { - AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); + fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); + if (!fctx->threads) { + err = AVERROR(ENOMEM); + goto error; + } + + for (; i < thread_count; ) { PerThreadContext *p = &fctx->threads[i]; + int first = !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->frame = av_frame_alloc(); - if (!p->frame) { - av_freep(©); - err = AVERROR(ENOMEM); - goto error; - } - - p->parent = fctx; - p->avctx = copy; - - if (!copy) { - err = AVERROR(ENOMEM); - goto error; - } - - *copy = *src; - - copy->internal = av_malloc(sizeof(AVCodecInternal)); - if (!copy->internal) { - copy->priv_data = NULL; - err = AVERROR(ENOMEM); - goto error; - } - *copy->internal = *src->internal; - copy->internal->thread_ctx = p; - copy->internal->last_pkt_props = &p->avpkt; - - copy->delay = avctx->delay; - - if (codec->priv_data_size) { - copy->priv_data = av_mallocz(codec->priv_data_size); - if (!copy->priv_data) { - err = AVERROR(ENOMEM); - goto error; - } - - if (codec->priv_class) { - *(const AVClass **)copy->priv_data = codec->priv_class; - err = av_opt_copy(copy->priv_data, src->priv_data); - if (err < 0) - goto error; - } - } - - if (i) - copy->internal->is_copy = 1; - - if (codec->init) - err = codec->init(copy); - - if (err) goto error; - - if (!i) - update_context_from_thread(avctx, copy, 1); - - atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); - - err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); - p->thread_init= !err; - if(!p->thread_init) + err = init_thread(p, &i, fctx, avctx, src, codec, first); + if (err < 0) goto error; } return 0; error: - ff_frame_thread_free(avctx, i+1); - + ff_frame_thread_free(avctx, i); return err; } @@ -896,7 +970,9 @@ void ff_thread_flush(AVCodecContext *avctx) av_frame_unref(p->frame); p->result = 0; +#if FF_API_THREAD_SAFE_CALLBACKS release_delayed_buffers(p); +#endif if (avctx->codec->flush) avctx->codec->flush(p->avctx); @@ -906,10 +982,16 @@ void ff_thread_flush(AVCodecContext *avctx) int ff_thread_can_start_frame(AVCodecContext *avctx) { PerThreadContext *p = avctx->internal->thread_ctx; +FF_DISABLE_DEPRECATION_WARNINGS if ((avctx->active_thread_type&FF_THREAD_FRAME) && atomic_load(&p->state) != STATE_SETTING_UP && - (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { + (avctx->codec->update_thread_context +#if FF_API_THREAD_SAFE_CALLBACKS + || !THREAD_SAFE_CALLBACKS(avctx) +#endif + )) { return 0; } +FF_ENABLE_DEPRECATION_WARNINGS return 1; } @@ -923,8 +1005,14 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int if (!(avctx->active_thread_type & FF_THREAD_FRAME)) return ff_get_buffer(avctx, f->f, flags); +FF_DISABLE_DEPRECATION_WARNINGS if (atomic_load(&p->state) != STATE_SETTING_UP && - (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { + (avctx->codec->update_thread_context +#if FF_API_THREAD_SAFE_CALLBACKS + || !THREAD_SAFE_CALLBACKS(avctx) +#endif + )) { +FF_ENABLE_DEPRECATION_WARNINGS av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); return -1; } @@ -942,6 +1030,10 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int } pthread_mutex_lock(&p->parent->buffer_mutex); +#if !FF_API_THREAD_SAFE_CALLBACKS + err = ff_get_buffer(avctx, f->f, flags); +#else +FF_DISABLE_DEPRECATION_WARNINGS if (THREAD_SAFE_CALLBACKS(avctx)) { err = ff_get_buffer(avctx, f->f, flags); } else { @@ -961,6 +1053,8 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int } if (!THREAD_SAFE_CALLBACKS(avctx) && !avctx->codec->update_thread_context) ff_thread_finish_setup(avctx); +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (err) av_buffer_unref(&f->progress); @@ -969,6 +1063,8 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int return err; } +#if FF_API_THREAD_SAFE_CALLBACKS +FF_DISABLE_DEPRECATION_WARNINGS enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) { enum AVPixelFormat res; @@ -994,6 +1090,8 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe return res; } +FF_ENABLE_DEPRECATION_WARNINGS +#endif int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) { @@ -1005,12 +1103,16 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) { +#if FF_API_THREAD_SAFE_CALLBACKS +FF_DISABLE_DEPRECATION_WARNINGS PerThreadContext *p = avctx->internal->thread_ctx; FrameThreadContext *fctx; AVFrame *dst; int ret = 0; int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) || THREAD_SAFE_CALLBACKS(avctx); +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (!f->f) return; @@ -1021,6 +1123,9 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) av_buffer_unref(&f->progress); f->owner[0] = f->owner[1] = NULL; +#if !FF_API_THREAD_SAFE_CALLBACKS + av_frame_unref(f->f); +#else // when the frame buffers are not allocated, just reset it to clean state if (can_direct_free || !f->f->buf[0]) { av_frame_unref(f->f); @@ -1062,4 +1167,5 @@ fail: memset(f->f->extended_buf, 0, f->f->nb_extended_buf * sizeof(*f->f->extended_buf)); av_frame_unref(f->f); } +#endif } diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c index 77cfe3c9f..80c4579fc 100644 --- a/libavcodec/pthread_slice.c +++ b/libavcodec/pthread_slice.c @@ -130,7 +130,7 @@ int ff_slice_thread_init(AVCodecContext *avctx) { SliceThreadContext *c; int thread_count = avctx->thread_count; - static void (*mainfunc)(void *); + void (*mainfunc)(void *); // We cannot do this in the encoder init as the threads are created before if (av_codec_is_encoder(avctx->codec) && diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index 7d11a3576..f07944a8f 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -29,11 +29,20 @@ #include #include +#include "config.h" #include "libavutil/intreadwrite.h" #include "libavutil/avassert.h" +#include "version.h" + +typedef uint32_t BitBuf; +#define AV_WBBUF AV_WB32 +#define AV_WLBUF AV_WL32 + +static const int BUF_BITS = 8 * sizeof(BitBuf); + typedef struct PutBitContext { - uint32_t bit_buf; + BitBuf bit_buf; int bit_left; uint8_t *buf, *buf_ptr, *buf_end; int size_in_bits; @@ -57,7 +66,7 @@ static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, s->buf = buffer; s->buf_end = s->buf + buffer_size; s->buf_ptr = s->buf; - s->bit_left = 32; + s->bit_left = BUF_BITS; s->bit_buf = 0; } @@ -66,7 +75,7 @@ static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, */ static inline int put_bits_count(PutBitContext *s) { - return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; + return (s->buf_ptr - s->buf) * 8 + BUF_BITS - s->bit_left; } /** @@ -92,7 +101,7 @@ static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer, */ static inline int put_bits_left(PutBitContext* s) { - return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; + return (s->buf_end - s->buf_ptr) * 8 - BUF_BITS + s->bit_left; } /** @@ -101,52 +110,52 @@ static inline int put_bits_left(PutBitContext* s) static inline void flush_put_bits(PutBitContext *s) { #ifndef BITSTREAM_WRITER_LE - if (s->bit_left < 32) + if (s->bit_left < BUF_BITS) s->bit_buf <<= s->bit_left; #endif - while (s->bit_left < 32) { + while (s->bit_left < BUF_BITS) { av_assert0(s->buf_ptr < s->buf_end); #ifdef BITSTREAM_WRITER_LE *s->buf_ptr++ = s->bit_buf; s->bit_buf >>= 8; #else - *s->buf_ptr++ = s->bit_buf >> 24; + *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8); s->bit_buf <<= 8; #endif s->bit_left += 8; } - s->bit_left = 32; + s->bit_left = BUF_BITS; s->bit_buf = 0; } static inline void flush_put_bits_le(PutBitContext *s) { - while (s->bit_left < 32) { + while (s->bit_left < BUF_BITS) { av_assert0(s->buf_ptr < s->buf_end); *s->buf_ptr++ = s->bit_buf; s->bit_buf >>= 8; s->bit_left += 8; } - s->bit_left = 32; + s->bit_left = BUF_BITS; s->bit_buf = 0; } -#ifdef BITSTREAM_WRITER_LE -#define avpriv_align_put_bits align_put_bits_unsupported_here -#define avpriv_put_string ff_put_string_unsupported_here -#define avpriv_copy_bits avpriv_copy_bits_unsupported_here -#else -/** - * Pad the bitstream with zeros up to the next byte boundary. - */ +#if FF_API_AVPRIV_PUT_BITS void avpriv_align_put_bits(PutBitContext *s); +void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length); +#endif + +#ifdef BITSTREAM_WRITER_LE +#define ff_put_string ff_put_string_unsupported_here +#define ff_copy_bits ff_copy_bits_unsupported_here +#else /** * Put the string string in the bitstream. * * @param terminate_string 0-terminates the written string if value is 1 */ -void avpriv_put_string(PutBitContext *pb, const char *string, +void ff_put_string(PutBitContext *pb, const char *string, int terminate_string); /** @@ -154,36 +163,30 @@ void avpriv_put_string(PutBitContext *pb, const char *string, * * @param length the number of bits of src to copy */ -void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length); +void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length); #endif -/** - * Write up to 31 bits into a bitstream. - * Use put_bits32 to write 32 bits. - */ -static inline void put_bits(PutBitContext *s, int n, unsigned int value) +static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value) { - unsigned int bit_buf; + BitBuf bit_buf; int bit_left; - av_assert2(n <= 31 && value < (1U << n)); - bit_buf = s->bit_buf; bit_left = s->bit_left; /* XXX: optimize */ #ifdef BITSTREAM_WRITER_LE - bit_buf |= value << (32 - bit_left); + bit_buf |= value << (BUF_BITS - bit_left); if (n >= bit_left) { - if (3 < s->buf_end - s->buf_ptr) { - AV_WL32(s->buf_ptr, bit_buf); - s->buf_ptr += 4; + if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { + AV_WLBUF(s->buf_ptr, bit_buf); + s->buf_ptr += sizeof(BitBuf); } else { av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); av_assert2(0); } bit_buf = value >> bit_left; - bit_left += 32; + bit_left += BUF_BITS; } bit_left -= n; #else @@ -193,14 +196,14 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) } else { bit_buf <<= bit_left; bit_buf |= value >> (n - bit_left); - if (3 < s->buf_end - s->buf_ptr) { - AV_WB32(s->buf_ptr, bit_buf); - s->buf_ptr += 4; + if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { + AV_WBBUF(s->buf_ptr, bit_buf); + s->buf_ptr += sizeof(BitBuf); } else { av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); av_assert2(0); } - bit_left += 32 - n; + bit_left += BUF_BITS - n; bit_buf = value; } #endif @@ -209,27 +212,37 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) s->bit_left = bit_left; } -static inline void put_bits_le(PutBitContext *s, int n, unsigned int value) +/** + * Write up to 31 bits into a bitstream. + * Use put_bits32 to write 32 bits. + */ +static inline void put_bits(PutBitContext *s, int n, BitBuf value) { - unsigned int bit_buf; + av_assert2(n <= 31 && value < (1UL << n)); + put_bits_no_assert(s, n, value); +} + +static inline void put_bits_le(PutBitContext *s, int n, BitBuf value) +{ + BitBuf bit_buf; int bit_left; - av_assert2(n <= 31 && value < (1U << n)); + av_assert2(n <= 31 && value < (1UL << n)); bit_buf = s->bit_buf; bit_left = s->bit_left; - bit_buf |= value << (32 - bit_left); + bit_buf |= value << (BUF_BITS - bit_left); if (n >= bit_left) { - if (3 < s->buf_end - s->buf_ptr) { - AV_WL32(s->buf_ptr, bit_buf); - s->buf_ptr += 4; + if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { + AV_WLBUF(s->buf_ptr, bit_buf); + s->buf_ptr += sizeof(BitBuf); } else { av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); av_assert2(0); } bit_buf = value >> bit_left; - bit_left += 32; + bit_left += BUF_BITS; } bit_left -= n; @@ -249,17 +262,22 @@ static inline void put_sbits(PutBitContext *pb, int n, int32_t value) */ static void av_unused put_bits32(PutBitContext *s, uint32_t value) { - unsigned int bit_buf; + BitBuf bit_buf; int bit_left; + if (BUF_BITS > 32) { + put_bits_no_assert(s, 32, value); + return; + } + bit_buf = s->bit_buf; bit_left = s->bit_left; #ifdef BITSTREAM_WRITER_LE - bit_buf |= value << (32 - bit_left); - if (3 < s->buf_end - s->buf_ptr) { - AV_WL32(s->buf_ptr, bit_buf); - s->buf_ptr += 4; + bit_buf |= (BitBuf)value << (BUF_BITS - bit_left); + if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { + AV_WLBUF(s->buf_ptr, bit_buf); + s->buf_ptr += sizeof(BitBuf); } else { av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); av_assert2(0); @@ -267,10 +285,10 @@ static void av_unused put_bits32(PutBitContext *s, uint32_t value) bit_buf = (uint64_t)value >> bit_left; #else bit_buf = (uint64_t)bit_buf << bit_left; - bit_buf |= value >> (32 - bit_left); - if (3 < s->buf_end - s->buf_ptr) { - AV_WB32(s->buf_ptr, bit_buf); - s->buf_ptr += 4; + bit_buf |= (BitBuf)value >> (BUF_BITS - bit_left); + if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { + AV_WBBUF(s->buf_ptr, bit_buf); + s->buf_ptr += sizeof(BitBuf); } else { av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); av_assert2(0); @@ -333,7 +351,7 @@ static inline uint8_t *put_bits_ptr(PutBitContext *s) static inline void skip_put_bytes(PutBitContext *s, int n) { av_assert2((put_bits_count(s) & 7) == 0); - av_assert2(s->bit_left == 32); + av_assert2(s->bit_left == BUF_BITS); av_assert0(n <= s->buf_end - s->buf_ptr); s->buf_ptr += n; } @@ -341,13 +359,13 @@ static inline void skip_put_bytes(PutBitContext *s, int n) /** * Skip the given number of bits. * Must only be used if the actual values in the bitstream do not matter. - * If n is 0 the behavior is undefined. + * If n is < 0 the behavior is undefined. */ static inline void skip_put_bits(PutBitContext *s, int n) { - s->bit_left -= n; - s->buf_ptr -= 4 * (s->bit_left >> 5); - s->bit_left &= 31; + unsigned bits = BUF_BITS - s->bit_left + n; + s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS); + s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1)); } /** @@ -357,9 +375,20 @@ static inline void skip_put_bits(PutBitContext *s, int n) */ static inline void set_put_bits_buffer_size(PutBitContext *s, int size) { - av_assert0(size <= INT_MAX/8 - 32); + av_assert0(size <= INT_MAX/8 - BUF_BITS); s->buf_end = s->buf + size; s->size_in_bits = 8*size; } +/** + * Pad the bitstream with zeros up to the next byte boundary. + */ +static inline void align_put_bits(PutBitContext *s) +{ + put_bits(s, s->bit_left & 7, 0); +} + +#undef AV_WBBUF +#undef AV_WLBUF + #endif /* AVCODEC_PUT_BITS_H */ diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c index b4afda2fb..4878af5a2 100644 --- a/libavcodec/qcelpdec.c +++ b/libavcodec/qcelpdec.c @@ -797,6 +797,6 @@ AVCodec ff_qcelp_decoder = { .id = AV_CODEC_ID_QCELP, .init = qcelp_decode_init, .decode = qcelp_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .priv_data_size = sizeof(QCELPContext), }; diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 657b2da64..07dea55a7 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -36,6 +36,8 @@ #include #include "libavutil/channel_layout.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" #define BITSTREAM_READER_LE #include "avcodec.h" @@ -205,7 +207,7 @@ static int qdm2_get_vlc(GetBitContext *gb, const VLC *vlc, int flag, int depth) value = get_vlc2(gb, vlc->table, vlc->bits, depth); /* stage-2, 3 bits exponent escape sequence */ - if (value-- == 0) + if (value < 0) value = get_bits(gb, get_bits(gb, 3) + 1); /* stage-3, optional */ @@ -1594,22 +1596,14 @@ static void qdm2_synthesis_filter(QDM2Context *q, int index) /** * Init static data (does not depend on specific file) - * - * @param q context */ static av_cold void qdm2_init_static_data(void) { - static int done; - - if(done) - return; - qdm2_init_vlc(); - ff_mpa_synth_init_float(ff_mpa_synth_window_float); softclip_table_init(); rnd_table_init(); init_noise_samples(); - done = 1; + ff_mpa_synth_init_float(); } /** @@ -1617,12 +1611,11 @@ static av_cold void qdm2_init_static_data(void) { */ static av_cold int qdm2_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; QDM2Context *s = avctx->priv_data; int tmp_val, tmp, size; GetByteContext gb; - qdm2_init_static_data(); - /* extradata parsing Structure: @@ -1768,6 +1761,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_S16; + ff_thread_once(&init_static_once, qdm2_init_static_data); + return 0; } @@ -1883,5 +1878,6 @@ AVCodec ff_qdm2_decoder = { .init = qdm2_decode_init, .close = qdm2_decode_close, .decode = qdm2_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/qdm2_tablegen.h b/libavcodec/qdm2_tablegen.h index 2331ebfbb..ca47fea2d 100644 --- a/libavcodec/qdm2_tablegen.h +++ b/libavcodec/qdm2_tablegen.h @@ -109,151 +109,46 @@ static VLC vlc_tab_type30; static VLC vlc_tab_type34; static VLC vlc_tab_fft_tone_offset[5]; -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 VLC_TYPE qdm2_table[3838][2]; +static av_cold void build_vlc(VLC *vlc, int nb_bits, int nb_codes, + unsigned *offset, const uint8_t tab[][2]) +{ + vlc->table = &qdm2_table[*offset]; + vlc->table_allocated = FF_ARRAY_ELEMS(qdm2_table) - *offset; + ff_init_vlc_from_lengths(vlc, nb_bits, nb_codes, + &tab[0][1], 2, &tab[0][0], 2, 1, + -1, INIT_VLC_STATIC_OVERLONG | INIT_VLC_LE, NULL); + *offset += vlc->table_size; +} + static av_cold void qdm2_init_vlc(void) { - 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); + const uint8_t (*tab)[2] = tab_fft_tone_offset; + unsigned offset = 0; - 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); + build_vlc(&vlc_tab_level, 8, 24, &offset, tab_level); + build_vlc(&vlc_tab_diff, 8, 33, &offset, tab_diff); + build_vlc(&vlc_tab_run, 5, 6, &offset, tab_run); - 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); + build_vlc(&fft_level_exp_alt_vlc, 8, 28, &offset, fft_level_exp_alt); + build_vlc(&fft_level_exp_vlc, 8, 20, &offset, fft_level_exp); - 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); + build_vlc(&fft_stereo_exp_vlc, 6, 7, &offset, fft_stereo_exp); + build_vlc(&fft_stereo_phase_vlc, 6, 9, &offset, fft_stereo_phase); - 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); + build_vlc(&vlc_tab_tone_level_idx_hi1, 8, 20, &offset, tab_tone_level_idx_hi1); + build_vlc(&vlc_tab_tone_level_idx_mid, 8, 13, &offset, tab_tone_level_idx_mid); + build_vlc(&vlc_tab_tone_level_idx_hi2, 8, 18, &offset, tab_tone_level_idx_hi2); - 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); + build_vlc(&vlc_tab_type30, 6, 9, &offset, tab_type30); + build_vlc(&vlc_tab_type34, 5, 10, &offset, tab_type34); - 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); + for (int i = 0; i < 5; i++) { + build_vlc(&vlc_tab_fft_tone_offset[i], 8, tab_fft_tone_offset_sizes[i], + &offset, tab); + tab += tab_fft_tone_offset_sizes[i]; + } } #endif /* CONFIG_HARDCODED_TABLES */ diff --git a/libavcodec/qdm2data.h b/libavcodec/qdm2data.h index 355d61387..713f58426 100644 --- a/libavcodec/qdm2data.h +++ b/libavcodec/qdm2data.h @@ -35,200 +35,130 @@ /** VLC TABLES **/ /* values in this table range from -1..23; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_level_huffcodes[24] = { - 0x037c, 0x0004, 0x003c, 0x004c, 0x003a, 0x002c, 0x001c, 0x001a, - 0x0024, 0x0014, 0x0001, 0x0002, 0x0000, 0x0003, 0x0007, 0x0005, - 0x0006, 0x0008, 0x0009, 0x000a, 0x000c, 0x00fc, 0x007c, 0x017c -}; - -static const uint8_t vlc_tab_level_huffbits[24] = { - 10, 6, 7, 7, 6, 6, 6, 6, 6, 5, 4, 4, 4, 3, 3, 3, 3, 4, 4, 5, 7, 8, 9, 10 +static const uint8_t tab_level[24][2] = { + { 12, 4 }, { 17, 4 }, { 1, 6 }, { 8, 6 }, { 9, 5 }, { 20, 7 }, + { 3, 7 }, { 5, 6 }, { 6, 6 }, { 2, 7 }, { 22, 9 }, { 23, 10 }, + { 0, 10 }, { 21, 8 }, { 11, 4 }, { 19, 5 }, { 7, 6 }, { 4, 6 }, + { 16, 3 }, { 10, 4 }, { 18, 4 }, { 15, 3 }, { 13, 3 }, { 14, 3 }, }; /* values in this table range from -1..36; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_diff_huffcodes[37] = { - 0x1c57, 0x0004, 0x0000, 0x0001, 0x0003, 0x0002, 0x000f, 0x000e, - 0x0007, 0x0016, 0x0037, 0x0027, 0x0026, 0x0066, 0x0006, 0x0097, - 0x0046, 0x01c6, 0x0017, 0x0786, 0x0086, 0x0257, 0x00d7, 0x0357, - 0x00c6, 0x0386, 0x0186, 0x0000, 0x0157, 0x0c57, 0x0057, 0x0000, - 0x0b86, 0x0000, 0x1457, 0x0000, 0x0457 -}; - -static const uint8_t vlc_tab_diff_huffbits[37] = { - 13, 3, 3, 2, 3, 3, 4, 4, 6, 5, 6, 6, 7, 7, 8, 8, - 8, 9, 8, 11, 9, 10, 8, 10, 9, 12, 10, 0, 10, 13, 11, 0, - 12, 0, 13, 0, 13 +static const uint8_t tab_diff[33][2] = { + { 2, 3 }, { 1, 3 }, { 5, 3 }, { 14, 8 }, { 20, 9 }, { 26, 10 }, + { 25, 12 }, { 32, 12 }, { 19, 11 }, { 16, 8 }, { 24, 9 }, { 17, 9 }, + { 12, 7 }, { 13, 7 }, { 9, 5 }, { 7, 4 }, { 3, 2 }, { 4, 3 }, + { 8, 6 }, { 11, 6 }, { 18, 8 }, { 15, 8 }, { 30, 11 }, { 36, 13 }, + { 34, 13 }, { 29, 13 }, { 0, 13 }, { 21, 10 }, { 28, 10 }, { 23, 10 }, + { 22, 8 }, { 10, 6 }, { 6, 4 }, }; /* values in this table range from -1..5; adjust retrieved value by -1 */ -static const uint8_t vlc_tab_run_huffcodes[6] = { - 0x1f, 0x00, 0x01, 0x03, 0x07, 0x0f -}; - -static const uint8_t vlc_tab_run_huffbits[6] = { - 5, 1, 2, 3, 4, 5 +static const uint8_t tab_run[6][2] = { + { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 0, 5 }, }; /* values in this table range from -1..19; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_tone_level_idx_hi1_huffcodes[20] = { - 0x5714, 0x000c, 0x0002, 0x0001, 0x0000, 0x0004, 0x0034, 0x0054, - 0x0094, 0x0014, 0x0114, 0x0214, 0x0314, 0x0614, 0x0e14, 0x0f14, - 0x2714, 0x0714, 0x1714, 0x3714 -}; - -static const uint8_t vlc_tab_tone_level_idx_hi1_huffbits[20] = { - 15, 4, 2, 1, 3, 5, 6, 7, 8, 10, 10, 11, 11, 12, 12, 12, 14, 14, 15, 14 +static const uint8_t tab_tone_level_idx_hi1[20][2] = { + { 4, 3 }, { 5, 5 }, { 9, 10 }, { 11, 11 }, { 13, 12 }, { 14, 12 }, + { 10, 10 }, { 12, 11 }, { 17, 14 }, { 16, 14 }, { 18, 15 }, { 0, 15 }, + { 19, 14 }, { 15, 12 }, { 8, 8 }, { 7, 7 }, { 6, 6 }, { 1, 4 }, + { 2, 2 }, { 3, 1 }, }; /* values in this table range from -1..23; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_tone_level_idx_mid_huffcodes[24] = { - 0x0fea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x03ea, 0x00ea, 0x002a, 0x001a, - 0x0006, 0x0001, 0x0000, 0x0002, 0x000a, 0x006a, 0x01ea, 0x07ea -}; - -static const uint8_t vlc_tab_tone_level_idx_mid_huffbits[24] = { - 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 9, 7, 5, 3, 1, 2, 4, 6, 8, 10, 12 +static const uint8_t tab_tone_level_idx_mid[13][2] = { + { 18, 2 }, { 19, 4 }, { 20, 6 }, { 14, 7 }, { 21, 8 }, { 13, 9 }, + { 22, 10 }, { 12, 11 }, { 23, 12 }, { 0, 12 }, { 15, 5 }, { 16, 3 }, + { 17, 1 }, }; /* values in this table range from -1..23; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_tone_level_idx_hi2_huffcodes[24] = { - 0x0664, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0064, 0x00e4, - 0x00a4, 0x0068, 0x0004, 0x0008, 0x0014, 0x0018, 0x0000, 0x0001, - 0x0002, 0x0003, 0x000c, 0x0028, 0x0024, 0x0164, 0x0000, 0x0264 -}; - -static const uint8_t vlc_tab_tone_level_idx_hi2_huffbits[24] = { - 11, 0, 0, 0, 0, 0, 10, 8, 8, 7, 6, 6, 5, 5, 4, 2, 2, 2, 4, 7, 8, 9, 0, 11 +static const uint8_t tab_tone_level_idx_hi2[18][2] = { + { 14, 4 }, { 11, 6 }, { 19, 7 }, { 9, 7 }, { 13, 5 }, { 10, 6 }, + { 20, 8 }, { 8, 8 }, { 6, 10 }, { 23, 11 }, { 0, 11 }, { 21, 9 }, + { 7, 8 }, { 12, 5 }, { 18, 4 }, { 16, 2 }, { 15, 2 }, { 17, 2 }, }; /* values in this table range from -1..8; adjust retrieved value by -1 */ -static const uint8_t vlc_tab_type30_huffcodes[9] = { - 0x3c, 0x06, 0x00, 0x01, 0x03, 0x02, 0x04, 0x0c, 0x1c -}; - -static const uint8_t vlc_tab_type30_huffbits[9] = { - 6, 3, 3, 2, 2, 3, 4, 5, 6 +static const uint8_t tab_type30[9][2] = { + { 2, 3 }, { 6, 4 }, { 7, 5 }, { 8, 6 }, { 0, 6 }, { 5, 3 }, { 1, 3 }, + { 3, 2 }, { 4, 2 }, }; /* values in this table range from -1..9; adjust retrieved value by -1 */ -static const uint8_t vlc_tab_type34_huffcodes[10] = { - 0x18, 0x00, 0x01, 0x04, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08 +static const uint8_t tab_type34[10][2] = { + { 1, 4 }, { 9, 5 }, { 0, 5 }, { 3, 3 }, { 7, 3 }, { 8, 3 }, { 2, 3 }, + { 4, 3 }, { 6, 3 }, { 5, 3 }, }; -static const uint8_t vlc_tab_type34_huffbits[10] = { - 5, 4, 3, 3, 3, 3, 3, 3, 3, 5 +static const uint8_t tab_fft_tone_offset_sizes[] = { + 23, 28, 31, 34, 37 }; -/* values in this table range from -1..22; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_0_huffcodes[23] = { - 0x038e, 0x0001, 0x0000, 0x0022, 0x000a, 0x0006, 0x0012, 0x0002, - 0x001e, 0x003e, 0x0056, 0x0016, 0x000e, 0x0032, 0x0072, 0x0042, - 0x008e, 0x004e, 0x00f2, 0x002e, 0x0036, 0x00c2, 0x018e -}; - -static const uint8_t vlc_tab_fft_tone_offset_0_huffbits[23] = { - 10, 1, 2, 6, 4, 5, 6, 7, 6, 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 6, 6, 8, 10 -}; - -/* values in this table range from -1..27; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_1_huffcodes[28] = { - 0x07a4, 0x0001, 0x0020, 0x0012, 0x001c, 0x0008, 0x0006, 0x0010, - 0x0000, 0x0014, 0x0004, 0x0032, 0x0070, 0x000c, 0x0002, 0x003a, - 0x001a, 0x002c, 0x002a, 0x0022, 0x0024, 0x000a, 0x0064, 0x0030, - 0x0062, 0x00a4, 0x01a4, 0x03a4 -}; - -static const uint8_t vlc_tab_fft_tone_offset_1_huffbits[28] = { - 11, 1, 6, 6, 5, 4, 3, 6, 6, 5, 6, 6, 7, 6, 6, 6, - 6, 6, 6, 7, 8, 6, 7, 7, 7, 9, 10, 11 -}; - -/* values in this table range from -1..31; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_2_huffcodes[32] = { - 0x1760, 0x0001, 0x0000, 0x0082, 0x000c, 0x0006, 0x0003, 0x0007, - 0x0008, 0x0004, 0x0010, 0x0012, 0x0022, 0x001a, 0x0000, 0x0020, - 0x000a, 0x0040, 0x004a, 0x006a, 0x002a, 0x0042, 0x0002, 0x0060, - 0x00aa, 0x00e0, 0x00c2, 0x01c2, 0x0160, 0x0360, 0x0760, 0x0f60 -}; - -static const uint8_t vlc_tab_fft_tone_offset_2_huffbits[32] = { - 13, 2, 0, 8, 4, 3, 3, 3, 4, 4, 5, 5, 6, 5, 7, 7, - 7, 7, 7, 7, 8, 8, 8, 9, 8, 8, 9, 9, 10, 11, 13, 12 -}; - -/* values in this table range from -1..34; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_3_huffcodes[35] = { - 0x33ea, 0x0005, 0x0000, 0x000c, 0x0000, 0x0006, 0x0003, 0x0008, - 0x0002, 0x0001, 0x0004, 0x0007, 0x001a, 0x000f, 0x001c, 0x002c, - 0x000a, 0x001d, 0x002d, 0x002a, 0x000d, 0x004c, 0x008c, 0x006a, - 0x00cd, 0x004d, 0x00ea, 0x020c, 0x030c, 0x010c, 0x01ea, 0x07ea, - 0x0bea, 0x03ea, 0x13ea -}; - -static const uint8_t vlc_tab_fft_tone_offset_3_huffbits[35] = { - 14, 4, 0, 10, 4, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, - 6, 5, 6, 7, 7, 7, 8, 8, 8, 8, 9, 10, 10, 10, 10, 11, - 12, 13, 14 -}; - -/* values in this table range from -1..37; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_4_huffcodes[38] = { - 0x5282, 0x0016, 0x0000, 0x0136, 0x0004, 0x0000, 0x0007, 0x000a, - 0x000e, 0x0003, 0x0001, 0x000d, 0x0006, 0x0009, 0x0012, 0x0005, - 0x0025, 0x0022, 0x0015, 0x0002, 0x0076, 0x0035, 0x0042, 0x00c2, - 0x0182, 0x00b6, 0x0036, 0x03c2, 0x0482, 0x01c2, 0x0682, 0x0882, - 0x0a82, 0x0082, 0x0282, 0x1282, 0x3282, 0x2282 -}; - -static const uint8_t vlc_tab_fft_tone_offset_4_huffbits[38] = { - 15, 6, 0, 9, 3, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, - 6, 6, 6, 8, 7, 6, 8, 9, 9, 8, 9, 10, 11, 10, 11, 12, - 12, 12, 14, 15, 14, 14 +static const uint8_t tab_fft_tone_offset[][2] = { + /* First table - 23 entries with range -1..21 */ + { 2, 2 }, { 7, 7 }, { 15, 8 }, { 21, 8 }, { 3, 6 }, { 6, 6 }, + { 13, 7 }, { 14, 8 }, { 18, 8 }, { 4, 4 }, { 5, 5 }, { 11, 7 }, + { 10, 7 }, { 20, 6 }, { 12, 8 }, { 16, 9 }, { 22, 10 }, { 0, 10 }, + { 17, 7 }, { 19, 6 }, { 8, 6 }, { 9, 6 }, { 1, 1 }, + /* Second table - 28 entries with range -1..26 */ + { 8, 6 }, { 2, 6 }, { 7, 6 }, { 23, 7 }, { 12, 7 }, { 5, 4 }, + { 10, 6 }, { 20, 8 }, { 25, 9 }, { 26, 10 }, { 27, 11 }, { 0, 11 }, + { 22, 7 }, { 9, 5 }, { 13, 6 }, { 17, 6 }, { 4, 5 }, { 14, 6 }, + { 19, 7 }, { 24, 7 }, { 3, 6 }, { 11, 6 }, { 21, 6 }, { 18, 6 }, + { 16, 6 }, { 15, 6 }, { 6, 3 }, { 1, 1 }, + /* Third table - 31 entries with range -1..30 (1 omitted) */ + { 14, 7 }, { 17, 7 }, { 15, 7 }, { 23, 9 }, { 28, 10 }, { 29, 11 }, + { 30, 13 }, { 0, 13 }, { 31, 12 }, { 25, 8 }, { 10, 5 }, { 8, 4 }, + { 9, 4 }, { 4, 4 }, { 22, 8 }, { 3, 8 }, { 21, 8 }, { 26, 9 }, + { 27, 9 }, { 12, 6 }, { 11, 5 }, { 16, 7 }, { 18, 7 }, { 20, 8 }, + { 24, 8 }, { 19, 7 }, { 13, 5 }, { 5, 3 }, { 1, 2 }, { 6, 3 }, + { 7, 3 }, + /* Fourth table - 34 entries with range -1..33 (1 omitted) */ + { 4, 4 }, { 7, 4 }, { 10, 4 }, { 3, 10 }, { 27, 10 }, { 29, 10 }, + { 28, 10 }, { 22, 8 }, { 21, 7 }, { 15, 6 }, { 14, 5 }, { 8, 4 }, + { 16, 6 }, { 19, 7 }, { 23, 8 }, { 26, 9 }, { 30, 10 }, { 33, 13 }, + { 34, 14 }, { 0, 14 }, { 32, 12 }, { 31, 11 }, { 12, 5 }, { 5, 3 }, + { 9, 3 }, { 1, 4 }, { 20, 7 }, { 25, 8 }, { 24, 8 }, { 18, 6 }, + { 17, 5 }, { 6, 3 }, { 11, 4 }, { 13, 4 }, + /* Fifth table - 37 entries with range -1..36 (1 omitted) */ + { 5, 3 }, { 4, 3 }, { 19, 8 }, { 33, 12 }, { 31, 12 }, { 28, 11 }, + { 34, 14 }, { 37, 14 }, { 35, 15 }, { 0, 15 }, { 36, 14 }, { 32, 12 }, + { 30, 11 }, { 24, 9 }, { 22, 8 }, { 23, 9 }, { 29, 10 }, { 27, 10 }, + { 17, 6 }, { 14, 5 }, { 7, 4 }, { 12, 5 }, { 1, 6 }, { 26, 9 }, + { 3, 9 }, { 25, 8 }, { 20, 7 }, { 8, 4 }, { 10, 4 }, { 13, 4 }, + { 15, 6 }, { 16, 6 }, { 18, 6 }, { 21, 6 }, { 11, 4 }, { 9, 3 }, + { 6, 3 }, }; /** FFT TABLES **/ /* values in this table range from -1..27; adjust retrieved value by -1 */ -static const uint16_t fft_level_exp_alt_huffcodes[28] = { - 0x1ec6, 0x0006, 0x00c2, 0x0142, 0x0242, 0x0246, 0x00c6, 0x0046, - 0x0042, 0x0146, 0x00a2, 0x0062, 0x0026, 0x0016, 0x000e, 0x0005, - 0x0004, 0x0003, 0x0000, 0x0001, 0x000a, 0x0012, 0x0002, 0x0022, - 0x01c6, 0x02c6, 0x06c6, 0x0ec6 -}; - -static const uint8_t fft_level_exp_alt_huffbits[28] = { - 13, 7, 8, 9, 10, 10, 10, 10, 10, 9, 8, 7, 6, 5, 4, 3, - 3, 2, 3, 3, 4, 5, 7, 8, 9, 11, 12, 13 +static const uint8_t fft_level_exp_alt[28][2] = { + { 18, 3 }, { 16, 3 }, { 22, 7 }, { 8, 10 }, { 4, 10 }, { 3, 9 }, + { 2, 8 }, { 23, 8 }, { 10, 8 }, { 11, 7 }, { 21, 5 }, { 20, 4 }, + { 1, 7 }, { 7, 10 }, { 5, 10 }, { 9, 9 }, { 6, 10 }, { 25, 11 }, + { 26, 12 }, { 27, 13 }, { 0, 13 }, { 24, 9 }, { 12, 6 }, { 13, 5 }, + { 14, 4 }, { 19, 3 }, { 15, 3 }, { 17, 2 }, }; /* values in this table range from -1..19; adjust retrieved value by -1 */ -static const uint16_t fft_level_exp_huffcodes[20] = { - 0x0f24, 0x0001, 0x0002, 0x0000, 0x0006, 0x0005, 0x0007, 0x000c, - 0x000b, 0x0014, 0x0013, 0x0004, 0x0003, 0x0023, 0x0064, 0x00a4, - 0x0024, 0x0124, 0x0324, 0x0724 -}; - -static const uint8_t fft_level_exp_huffbits[20] = { - 12, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 10, 11, 12 +static const uint8_t fft_level_exp[20][2] = { + { 3, 3 }, { 11, 6 }, { 16, 9 }, { 17, 10 }, { 18, 11 }, { 19, 12 }, + { 0, 12 }, { 15, 8 }, { 14, 7 }, { 9, 5 }, { 7, 4 }, { 2, 3 }, + { 4, 3 }, { 1, 3 }, { 5, 3 }, { 12, 6 }, { 13, 6 }, { 10, 5 }, + { 8, 4 }, { 6, 3 }, }; /* values in this table range from -1..6; adjust retrieved value by -1 */ -static const uint8_t fft_stereo_exp_huffcodes[7] = { - 0x3e, 0x01, 0x00, 0x02, 0x06, 0x0e, 0x1e -}; - -static const uint8_t fft_stereo_exp_huffbits[7] = { - 6, 1, 2, 3, 4, 5, 6 +static const uint8_t fft_stereo_exp[7][2] = { + { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 0, 6 }, { 1, 1 }, }; /* values in this table range from -1..8; adjust retrieved value by -1 */ -static const uint8_t fft_stereo_phase_huffcodes[9] = { - 0x35, 0x02, 0x00, 0x01, 0x0d, 0x15, 0x05, 0x09, 0x03 -}; - -static const uint8_t fft_stereo_phase_huffbits[9] = { - 6, 2, 2, 4, 4, 6, 5, 4, 2 +static const uint8_t fft_stereo_phase[9][2] = { + { 2, 2 }, { 1, 2 }, { 3, 4 }, { 7, 4 }, { 6, 5 }, { 5, 6 }, { 0, 6 }, + { 4, 4 }, { 8, 2 }, }; static const int fft_cutoff_index_table[4][2] = { diff --git a/libavcodec/qdmc.c b/libavcodec/qdmc.c index 10ceb7aa5..a8c930f0e 100644 --- a/libavcodec/qdmc.c +++ b/libavcodec/qdmc.c @@ -119,109 +119,62 @@ static const uint8_t noise_bands_selector[] = { 4, 3, 2, 1, 0, 0, 0, }; -static const uint8_t noise_value_bits[] = { - 12, 7, 9, 7, 10, 9, 11, 9, 9, 2, 9, 9, 9, 9, - 9, 3, 9, 10, 10, 12, 2, 3, 3, 5, 5, 6, 7, +static const uint8_t qdmc_hufftab[][2] = { + /* Noise value - 27 entries */ + { 1, 2 }, { 10, 7 }, { 26, 9 }, { 22, 9 }, { 24, 9 }, { 14, 9 }, + { 8, 6 }, { 6, 5 }, { 7, 5 }, { 9, 7 }, { 30, 9 }, { 32, 10 }, + { 13, 10 }, { 20, 9 }, { 28, 9 }, { 12, 7 }, { 15, 11 }, { 36, 12 }, + { 0, 12 }, { 34, 10 }, { 18, 9 }, { 11, 9 }, { 16, 9 }, { 5, 3 }, + { 2, 3 }, { 4, 3 }, { 3, 2 }, + /* Noise segment length - 12 entries */ + { 1, 1 }, { 2, 2 }, { 3, 4 }, { 8, 9 }, { 9, 10 }, { 0, 10 }, + { 13, 8 }, { 7, 7 }, { 6, 6 }, { 17, 5 }, { 4, 4 }, { 5, 4 }, + /* Amplitude - 28 entries */ + { 18, 3 }, { 16, 3 }, { 22, 7 }, { 8, 10 }, { 4, 10 }, { 3, 9 }, + { 2, 8 }, { 23, 8 }, { 10, 8 }, { 11, 7 }, { 21, 5 }, { 20, 4 }, + { 1, 7 }, { 7, 10 }, { 5, 10 }, { 9, 9 }, { 6, 10 }, { 25, 11 }, + { 26, 12 }, { 27, 13 }, { 0, 13 }, { 24, 9 }, { 12, 6 }, { 13, 5 }, + { 14, 4 }, { 19, 3 }, { 15, 3 }, { 17, 2 }, + /* Frequency differences - 47 entries */ + { 2, 4 }, { 14, 6 }, { 26, 7 }, { 31, 8 }, { 32, 9 }, { 35, 9 }, + { 7, 5 }, { 10, 5 }, { 22, 7 }, { 27, 7 }, { 19, 7 }, { 20, 7 }, + { 4, 5 }, { 13, 5 }, { 17, 6 }, { 15, 6 }, { 8, 5 }, { 5, 4 }, + { 28, 7 }, { 33, 9 }, { 36, 11 }, { 38, 12 }, { 42, 14 }, { 45, 16 }, + { 44, 18 }, { 0, 18 }, { 46, 17 }, { 43, 15 }, { 40, 13 }, { 37, 11 }, + { 39, 12 }, { 41, 12 }, { 34, 8 }, { 16, 6 }, { 11, 5 }, { 9, 4 }, + { 1, 2 }, { 3, 4 }, { 30, 7 }, { 29, 7 }, { 23, 6 }, { 24, 6 }, + { 18, 6 }, { 6, 4 }, { 12, 5 }, { 21, 6 }, { 25, 6 }, + /* Amplitude differences - 9 entries */ + { 1, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 }, + { 8, 8 }, { 0, 8 }, { 2, 1 }, + /* Phase differences - 9 entries */ + { 2, 2 }, { 1, 2 }, { 3, 4 }, { 7, 4 }, { 6, 5 }, { 5, 6 }, + { 0, 6 }, { 4, 4 }, { 8, 2 }, }; -static const uint8_t noise_value_symbols[] = { - 0, 10, 11, 12, 13, 14, 15, 16, 18, 1, 20, 22, 24, - 26, 28, 2, 30, 32, 34, 36, 3, 4, 5, 6, 7, 8, 9, +static const uint8_t huff_sizes[] = { + 27, 12, 28, 47, 9, 9 }; -static const uint16_t noise_value_codes[] = { - 0xC7A, 0x002, 0x0FA, 0x03A, 0x35A, 0x1C2, 0x07A, 0x1FA, - 0x17A, 0x000, 0x0DA, 0x142, 0x0C2, 0x042, 0x1DA, 0x001, - 0x05A, 0x15A, 0x27A, 0x47A, 0x003, 0x005, 0x006, 0x012, - 0x00A, 0x022, 0x01A, +static const uint8_t huff_bits[] = { + 12, 10, 12, 12, 8, 6 }; -static const uint8_t noise_segment_length_bits[] = { - 10, 8, 5, 1, 2, 4, 4, 4, 6, 7, 9, 10, -}; - -static const uint8_t noise_segment_length_symbols[] = { - 0, 13, 17, 1, 2, 3, 4, 5, 6, 7, 8, 9, -}; - -static const uint16_t noise_segment_length_codes[] = { - 0x30B, 0x8B, 0x1B, 0x0, 0x1, 0x3, 0x7, 0xF, 0x2b, 0x4B, 0xB, 0x10B, -}; - -static const uint8_t freq_diff_bits[] = { - 18, 2, 4, 4, 5, 4, 4, 5, 5, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 6, - 7, 6, 6, 6, 7, 7, 7, 7, 7, 8, 9, 9, 8, 9, 11, 11, 12, 12, 13, 12, - 14, 15, 18, 16, 17, -}; - -static const uint32_t freq_diff_codes[] = { - 0x2AD46, 0x1, 0x0, 0x3, 0xC, 0xA, 0x7, 0x18, 0x12, 0xE, 0x4, 0x16, - 0xF, 0x1C, 0x8, 0x22, 0x26, 0x2, 0x3B, 0x34, 0x74, 0x1F, 0x14, 0x2B, - 0x1B, 0x3F, 0x28, 0x54, 0x6, 0x4B, 0xB, 0x68, 0xE8, 0x46, 0xC6, 0x1E8, - 0x146, 0x346, 0x546, 0x746, 0x1D46, 0xF46, 0xD46, 0x6D46, 0xAD46, 0x2D46, - 0x1AD46, -}; - -static const uint8_t amplitude_bits[] = { - 13, 7, 8, 9, 10, 10, 10, 10, 10, 9, 8, 7, 6, - 5, 4, 3, 3, 2, 3, 3, 4, 5, 7, 8, 9, 11, 12, 13, -}; - -static const uint16_t amplitude_codes[] = { - 0x1EC6, 0x6, 0xC2, 0x142, 0x242, 0x246, 0xC6, 0x46, 0x42, 0x146, 0xA2, - 0x62, 0x26, 0x16, 0xE, 0x5, 0x4, 0x3, 0x0, 0x1, 0xA, 0x12, 0x2, 0x22, - 0x1C6, 0x2C6, 0x6C6, 0xEC6, -}; - -static const uint8_t amplitude_diff_bits[] = { - 8, 2, 1, 3, 4, 5, 6, 7, 8, -}; - -static const uint8_t amplitude_diff_codes[] = { - 0xFE, 0x0, 0x1, 0x2, 0x6, 0xE, 0x1E, 0x3E, 0x7E, -}; - -static const uint8_t phase_diff_bits[] = { - 6, 2, 2, 4, 4, 6, 5, 4, 2, -}; - -static const uint8_t phase_diff_codes[] = { - 0x35, 0x2, 0x0, 0x1, 0xD, 0x15, 0x5, 0x9, 0x3, -}; - -#define INIT_VLC_STATIC_LE(vlc, nb_bits, nb_codes, \ - bits, bits_wrap, bits_size, \ - codes, codes_wrap, codes_size, \ - symbols, symbols_wrap, symbols_size, \ - static_size) \ - do { \ - static VLC_TYPE table[static_size][2]; \ - (vlc)->table = table; \ - (vlc)->table_allocated = static_size; \ - ff_init_vlc_sparse(vlc, nb_bits, nb_codes, \ - bits, bits_wrap, bits_size, \ - codes, codes_wrap, codes_size, \ - symbols, symbols_wrap, symbols_size, \ - INIT_VLC_LE | INIT_VLC_USE_NEW_STATIC); \ - } while (0) - static av_cold void qdmc_init_static_data(void) { + const uint8_t (*hufftab)[2] = qdmc_hufftab; int i; - INIT_VLC_STATIC_LE(&vtable[0], 12, FF_ARRAY_ELEMS(noise_value_bits), - noise_value_bits, 1, 1, noise_value_codes, 2, 2, noise_value_symbols, 1, 1, 4096); - INIT_VLC_STATIC_LE(&vtable[1], 10, FF_ARRAY_ELEMS(noise_segment_length_bits), - noise_segment_length_bits, 1, 1, noise_segment_length_codes, 2, 2, - noise_segment_length_symbols, 1, 1, 1024); - INIT_VLC_STATIC_LE(&vtable[2], 13, FF_ARRAY_ELEMS(amplitude_bits), - amplitude_bits, 1, 1, amplitude_codes, 2, 2, NULL, 0, 0, 8192); - INIT_VLC_STATIC_LE(&vtable[3], 18, FF_ARRAY_ELEMS(freq_diff_bits), - freq_diff_bits, 1, 1, freq_diff_codes, 4, 4, NULL, 0, 0, 262144); - INIT_VLC_STATIC_LE(&vtable[4], 8, FF_ARRAY_ELEMS(amplitude_diff_bits), - amplitude_diff_bits, 1, 1, amplitude_diff_codes, 1, 1, NULL, 0, 0, 256); - INIT_VLC_STATIC_LE(&vtable[5], 6, FF_ARRAY_ELEMS(phase_diff_bits), - phase_diff_bits, 1, 1, phase_diff_codes, 1, 1, NULL, 0, 0, 64); + for (unsigned i = 0, offset = 0; i < FF_ARRAY_ELEMS(vtable); i++) { + static VLC_TYPE vlc_buffer[13698][2]; + vtable[i].table = &vlc_buffer[offset]; + vtable[i].table_allocated = FF_ARRAY_ELEMS(vlc_buffer) - offset; + ff_init_vlc_from_lengths(&vtable[i], huff_bits[i], huff_sizes[i], + &hufftab[0][1], 2, &hufftab[0][0], 2, 1, -1, + INIT_VLC_LE | INIT_VLC_STATIC_OVERLONG, NULL); + hufftab += huff_sizes[i]; + offset += vtable[i].table_size; + } for (i = 0; i < 512; i++) sin_table[i] = sin(2.0f * i * M_PI * 0.001953125f); @@ -369,12 +322,8 @@ static int qdmc_get_vlc(GetBitContext *gb, VLC *table, int flag) if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; - v = get_vlc2(gb, table->table, table->bits, 1); + v = get_vlc2(gb, table->table, table->bits, 2); if (v < 0) - return AVERROR_INVALIDDATA; - if (v) - v = v - 1; - else v = get_bits(gb, get_bits(gb, 3) + 1); if (flag) { @@ -786,5 +735,6 @@ AVCodec ff_qdmc_decoder = { .close = qdmc_decode_close, .decode = qdmc_decode_frame, .flush = qdmc_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index 84304cae3..f4edc4b16 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -101,8 +101,11 @@ static void qpeg_decode_intra(QpegContext *qctx, uint8_t *dst, } else { if (bytestream2_get_bytes_left(&qctx->buffer) < copy) copy = bytestream2_get_bytes_left(&qctx->buffer); - for(i = 0; i < copy; i++) { - dst[filled++] = bytestream2_get_byte(&qctx->buffer); + while (copy > 0) { + int step = FFMIN(copy, width - filled); + bytestream2_get_bufferu(&qctx->buffer, dst + filled, step); + filled += step; + copy -= step; if (filled >= width) { filled = 0; dst -= stride; @@ -115,9 +118,9 @@ static void qpeg_decode_intra(QpegContext *qctx, uint8_t *dst, } } -static const int qpeg_table_h[16] = +static const uint8_t qpeg_table_h[16] = { 0x00, 0x20, 0x20, 0x20, 0x18, 0x10, 0x10, 0x20, 0x10, 0x08, 0x18, 0x08, 0x08, 0x18, 0x10, 0x04}; -static const int qpeg_table_w[16] = +static const uint8_t qpeg_table_w[16] = { 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04}; /* Decodes delta frames */ @@ -271,7 +274,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame * const ref = a->ref; uint8_t* outdata; int delta, intra, ret; - int pal_size; + buffer_size_t pal_size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &pal_size); if (avpkt->size < 0x86) { diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 17720070f..6e3154e1a 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -64,6 +64,10 @@ int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) case AV_CODEC_ID_VP9: return MFX_CODEC_VP9; #endif +#if QSV_VERSION_ATLEAST(1, 34) + case AV_CODEC_ID_AV1: + return MFX_CODEC_AV1; +#endif default: break; @@ -357,6 +361,7 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) av_dict_set(&child_device_opts, "driver", "iHD", 0); ret = av_hwdevice_ctx_create(&qs->va_device_ref, AV_HWDEVICE_TYPE_VAAPI, NULL, child_device_opts, 0); + av_dict_free(&child_device_opts); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to create a VAAPI device.\n"); return ret; @@ -371,8 +376,6 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) } } - av_dict_free(&child_device_opts); - return 0; } #endif //AVCODEC_QSV_LINUX_SESSION_HANDLE diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 6489836a6..6b2fbbe25 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -21,6 +21,8 @@ #ifndef AVCODEC_QSV_INTERNAL_H #define AVCODEC_QSV_INTERNAL_H +#include "config.h" + #if CONFIG_VAAPI #define AVCODEC_QSV_LINUX_SESSION_HANDLE #endif //CONFIG_VAAPI diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index fc25dc73e..5f2e64137 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -21,17 +21,20 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include #include #include "libavutil/common.h" +#include "libavutil/fifo.h" +#include "libavutil/frame.h" #include "libavutil/hwcontext.h" #include "libavutil/hwcontext_qsv.h" #include "libavutil/mem.h" #include "libavutil/log.h" -#include "libavutil/pixdesc.h" +#include "libavutil/opt.h" #include "libavutil/pixfmt.h" #include "libavutil/time.h" #include "libavutil/imgutils.h" @@ -39,11 +42,49 @@ #include "avcodec.h" #include "internal.h" #include "decode.h" +#include "hwconfig.h" #include "qsv.h" #include "qsv_internal.h" -#include "qsvdec.h" -const AVCodecHWConfigInternal *ff_qsv_hw_configs[] = { +typedef struct QSVContext { + // the session used for decoding + mfxSession session; + + // the session we allocated internally, in case the caller did not provide + // one + QSVSession internal_qs; + + QSVFramesContext frames_ctx; + + /** + * a linked list of frames currently being used by QSV + */ + QSVFrame *work_frames; + + AVFifoBuffer *async_fifo; + int zero_consume_run; + int buffered_count; + int reinit_flag; + + enum AVPixelFormat orig_pix_fmt; + uint32_t fourcc; + mfxFrameInfo frame_info; + AVBufferPool *pool; + + int initialized; + + // options set by the caller + int async_depth; + int iopattern; + int gpu_copy; + + char *load_plugins; + + mfxExtBuffer **ext_buffers; + int nb_ext_buffers; +} QSVContext; + +static const AVCodecHWConfigInternal *const qsv_hw_configs[] = { &(const AVCodecHWConfigInternal) { .public = { .pix_fmt = AV_PIX_FMT_QSV, @@ -56,7 +97,8 @@ const AVCodecHWConfigInternal *ff_qsv_hw_configs[] = { NULL }; -static int ff_qsv_get_continuous_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferPool *pool) +static int qsv_get_continuous_buffer(AVCodecContext *avctx, AVFrame *frame, + AVBufferPool *pool) { int ret = 0; @@ -228,7 +270,7 @@ static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixel return 0; } -static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, mfxVideoParam *param) +static int qsv_decode_init_context(AVCodecContext *avctx, QSVContext *q, mfxVideoParam *param) { int ret; @@ -254,7 +296,9 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, mfxVideoParam * return 0; } -static int qsv_decode_header(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt, enum AVPixelFormat pix_fmt, mfxVideoParam *param) +static int qsv_decode_header(AVCodecContext *avctx, QSVContext *q, + const AVPacket *avpkt, enum AVPixelFormat pix_fmt, + mfxVideoParam *param) { int ret; @@ -298,7 +342,7 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame) int ret; if (q->pool) - ret = ff_qsv_get_continuous_buffer(avctx, frame->frame, q->pool); + ret = qsv_get_continuous_buffer(avctx, frame->frame, q->pool); else ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF); @@ -399,7 +443,7 @@ static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf) static int qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, - AVPacket *avpkt) + const AVPacket *avpkt) { QSVFrame *out_frame; mfxFrameSurface1 *insurf; @@ -530,7 +574,7 @@ FF_ENABLE_DEPRECATION_WARNINGS return bs.DataOffset; } -int ff_qsv_decode_close(QSVContext *q) +static void qsv_decode_close_qsvcontext(QSVContext *q) { QSVFrame *cur = q->work_frames; @@ -562,12 +606,10 @@ int ff_qsv_decode_close(QSVContext *q) av_buffer_unref(&q->frames_ctx.hw_frames_ctx); av_buffer_unref(&q->frames_ctx.mids_buf); av_buffer_pool_uninit(&q->pool); - - return 0; } -int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q, - AVFrame *frame, int *got_frame, AVPacket *pkt) +static int qsv_process_data(AVCodecContext *avctx, QSVContext *q, + AVFrame *frame, int *got_frame, const AVPacket *pkt) { int ret; mfxVideoParam param = { 0 }; @@ -615,7 +657,7 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q, } if (!q->initialized) { - ret = qsv_decode_init(avctx, q, ¶m); + ret = qsv_decode_init_context(avctx, q, ¶m); if (ret < 0) goto reinit_fail; q->initialized = 1; @@ -628,8 +670,248 @@ reinit_fail: return ret; } -void ff_qsv_decode_flush(AVCodecContext *avctx, QSVContext *q) +enum LoadPlugin { + LOAD_PLUGIN_NONE, + LOAD_PLUGIN_HEVC_SW, + LOAD_PLUGIN_HEVC_HW, +}; + +typedef struct QSVDecContext { + AVClass *class; + QSVContext qsv; + + int load_plugin; + + AVFifoBuffer *packet_fifo; + + AVPacket buffer_pkt; +} QSVDecContext; + +static void qsv_clear_buffers(QSVDecContext *s) { - q->orig_pix_fmt = AV_PIX_FMT_NONE; - q->initialized = 0; + AVPacket pkt; + while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) { + av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL); + av_packet_unref(&pkt); + } + + av_packet_unref(&s->buffer_pkt); } + +static av_cold int qsv_decode_close(AVCodecContext *avctx) +{ + QSVDecContext *s = avctx->priv_data; + + av_freep(&s->qsv.load_plugins); + + qsv_decode_close_qsvcontext(&s->qsv); + + qsv_clear_buffers(s); + + av_fifo_free(s->packet_fifo); + + return 0; +} + +static av_cold int qsv_decode_init(AVCodecContext *avctx) +{ + QSVDecContext *s = avctx->priv_data; + int ret; + const char *uid = NULL; + + if (avctx->codec_id == AV_CODEC_ID_VP8) { + uid = "f622394d8d87452f878c51f2fc9b4131"; + } else if (avctx->codec_id == AV_CODEC_ID_VP9) { + uid = "a922394d8d87452f878c51f2fc9b4131"; + } + else if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != LOAD_PLUGIN_NONE) { + static const char * const uid_hevcdec_sw = "15dd936825ad475ea34e35f3f54217a6"; + static const char * const uid_hevcdec_hw = "33a61c0b4c27454ca8d85dde757c6f8e"; + + if (s->qsv.load_plugins[0]) { + av_log(avctx, AV_LOG_WARNING, + "load_plugins is not empty, but load_plugin is not set to 'none'." + "The load_plugin value will be ignored.\n"); + } else { + if (s->load_plugin == LOAD_PLUGIN_HEVC_SW) + uid = uid_hevcdec_sw; + else + uid = uid_hevcdec_hw; + } + } + if (uid) { + av_freep(&s->qsv.load_plugins); + s->qsv.load_plugins = av_strdup(uid); + if (!s->qsv.load_plugins) + return AVERROR(ENOMEM); + } + + s->qsv.orig_pix_fmt = AV_PIX_FMT_NV12; + s->packet_fifo = av_fifo_alloc(sizeof(AVPacket)); + if (!s->packet_fifo) { + ret = AVERROR(ENOMEM); + goto fail; + } + + return 0; +fail: + qsv_decode_close(avctx); + return ret; +} + +static int qsv_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + QSVDecContext *s = avctx->priv_data; + AVFrame *frame = data; + int ret; + + /* buffer the input packet */ + if (avpkt->size) { + AVPacket input_ref; + + if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) { + ret = av_fifo_realloc2(s->packet_fifo, + av_fifo_size(s->packet_fifo) + sizeof(input_ref)); + if (ret < 0) + return ret; + } + + ret = av_packet_ref(&input_ref, avpkt); + if (ret < 0) + return ret; + av_fifo_generic_write(s->packet_fifo, &input_ref, sizeof(input_ref), NULL); + } + + /* process buffered data */ + while (!*got_frame) { + /* prepare the input data */ + if (s->buffer_pkt.size <= 0) { + /* no more data */ + if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket)) + return avpkt->size ? avpkt->size : qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt); + /* in progress of reinit, no read from fifo and keep the buffer_pkt */ + if (!s->qsv.reinit_flag) { + av_packet_unref(&s->buffer_pkt); + av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, sizeof(s->buffer_pkt), NULL); + } + } + + ret = qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->buffer_pkt); + if (ret < 0){ + /* Drop buffer_pkt when failed to decode the packet. Otherwise, + the decoder will keep decoding the failure packet. */ + av_packet_unref(&s->buffer_pkt); + return ret; + } + if (s->qsv.reinit_flag) + continue; + + s->buffer_pkt.size -= ret; + s->buffer_pkt.data += ret; + } + + return avpkt->size; +} + +static void qsv_decode_flush(AVCodecContext *avctx) +{ + QSVDecContext *s = avctx->priv_data; + + qsv_clear_buffers(s); + + s->qsv.orig_pix_fmt = AV_PIX_FMT_NONE; + s->qsv.initialized = 0; +} + +#define OFFSET(x) offsetof(QSVDecContext, x) +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM + +#define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt) \ +static const AVClass x##_qsv_class = { \ + .class_name = #x "_qsv", \ + .item_name = av_default_item_name, \ + .option = opt, \ + .version = LIBAVUTIL_VERSION_INT, \ +}; \ +AVCodec ff_##x##_qsv_decoder = { \ + .name = #x "_qsv", \ + .long_name = NULL_IF_CONFIG_SMALL(#X " video (Intel Quick Sync Video acceleration)"), \ + .priv_data_size = sizeof(QSVDecContext), \ + .type = AVMEDIA_TYPE_VIDEO, \ + .id = AV_CODEC_ID_##X, \ + .init = qsv_decode_init, \ + .decode = qsv_decode_frame, \ + .flush = qsv_decode_flush, \ + .close = qsv_decode_close, \ + .bsfs = bsf_name, \ + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID, \ + .priv_class = &x##_qsv_class, \ + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \ + AV_PIX_FMT_P010, \ + AV_PIX_FMT_QSV, \ + AV_PIX_FMT_NONE }, \ + .hw_configs = qsv_hw_configs, \ + .wrapper_name = "qsv", \ +}; \ + +#define DEFINE_QSV_DECODER(x, X, bsf_name) DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, options) + +#if CONFIG_HEVC_QSV_DECODER +static const AVOption hevc_options[] = { + { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD }, + + { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_HW }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VD, "load_plugin" }, + { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE }, 0, 0, VD, "load_plugin" }, + { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VD, "load_plugin" }, + { "hevc_hw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_HW }, 0, 0, VD, "load_plugin" }, + + { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session", + OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD }, + + { "gpu_copy", "A GPU-accelerated copy between video and system memory", OFFSET(qsv.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, VD, "gpu_copy"}, + { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, VD, "gpu_copy"}, + { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, VD, "gpu_copy"}, + { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, VD, "gpu_copy"}, + { NULL }, +}; +DEFINE_QSV_DECODER_WITH_OPTION(hevc, HEVC, "hevc_mp4toannexb", hevc_options) +#endif + +static const AVOption options[] = { + { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD }, + + { "gpu_copy", "A GPU-accelerated copy between video and system memory", OFFSET(qsv.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, VD, "gpu_copy"}, + { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, VD, "gpu_copy"}, + { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, VD, "gpu_copy"}, + { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, VD, "gpu_copy"}, + { NULL }, +}; + +#if CONFIG_H264_QSV_DECODER +DEFINE_QSV_DECODER(h264, H264, "h264_mp4toannexb") +#endif + +#if CONFIG_MPEG2_QSV_DECODER +DEFINE_QSV_DECODER(mpeg2, MPEG2VIDEO, NULL) +#endif + +#if CONFIG_VC1_QSV_DECODER +DEFINE_QSV_DECODER(vc1, VC1, NULL) +#endif + +#if CONFIG_MJPEG_QSV_DECODER +DEFINE_QSV_DECODER(mjpeg, MJPEG, NULL) +#endif + +#if CONFIG_VP8_QSV_DECODER +DEFINE_QSV_DECODER(vp8, VP8, NULL) +#endif + +#if CONFIG_VP9_QSV_DECODER +DEFINE_QSV_DECODER(vp9, VP9, NULL) +#endif + +#if CONFIG_AV1_QSV_DECODER +DEFINE_QSV_DECODER(av1, AV1, NULL) +#endif diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index ed4539f69..566a5c855 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -735,6 +735,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if (q->adaptive_b >= 0) q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; #endif + } + + if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC) { + if (q->extbrc >= 0) + q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; #if QSV_VERSION_ATLEAST(1, 9) if (avctx->qmin >= 0 && avctx->qmax >= 0 && avctx->qmin > avctx->qmax) { @@ -750,12 +755,6 @@ FF_ENABLE_DEPRECATION_WARNINGS q->extco2.MaxQPP = q->extco2.MaxQPB = q->extco2.MaxQPI; } #endif - } - - if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC) { - if (q->extbrc >= 0) - q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; - q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2; q->extco2.Header.BufferSz = sizeof(q->extco2); @@ -1133,6 +1132,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) if (!iopattern) iopattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY; q->param.IOPattern = iopattern; + ff_qsv_print_iopattern(avctx, iopattern, "Encoder"); ret = qsvenc_init_session(avctx, q); if (ret < 0) @@ -1656,7 +1656,7 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q) return 0; } -const AVCodecHWConfigInternal *ff_qsv_enc_hw_configs[] = { +const AVCodecHWConfigInternal *const ff_qsv_enc_hw_configs[] = { HW_CONFIG_ENCODER_FRAMES(QSV, QSV), HW_CONFIG_ENCODER_DEVICE(NV12, QSV), HW_CONFIG_ENCODER_DEVICE(P010, QSV), diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index 4f579d1db..6d305f87d 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -98,7 +98,7 @@ { "forced_idr", "Forcing I frames as IDR frames", OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE }, \ { "low_power", "enable low power mode(experimental: many limitations by mfx version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, VE},\ -extern const AVCodecHWConfigInternal *ff_qsv_enc_hw_configs[]; +extern const AVCodecHWConfigInternal *const ff_qsv_enc_hw_configs[]; typedef int SetEncodeCtrlCB (AVCodecContext *avctx, const AVFrame *frame, mfxEncodeCtrl* enc_ctrl); diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c index 364975bea..ddafc45ec 100644 --- a/libavcodec/qsvenc_h264.c +++ b/libavcodec/qsvenc_h264.c @@ -34,6 +34,7 @@ #include "qsv.h" #include "qsv_internal.h" #include "qsvenc.h" +#include "atsc_a53.h" typedef struct QSVH264EncContext { AVClass *class; diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index 88c78a813..347f30655 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -263,6 +263,8 @@ static const AVCodecDefault qsv_enc_defaults[] = { // same as the x264 default { "g", "248" }, { "bf", "8" }, + { "qmin", "-1" }, + { "qmax", "-1" }, { "trellis", "-1" }, { "flags", "+cgop" }, #if FF_API_PRIVATE_OPT diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index 52394f526..e04fd3143 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -36,6 +36,7 @@ #include #include "avcodec.h" +#include "decode.h" #include "bytestream.h" #include "internal.h" @@ -539,7 +540,7 @@ static int qtrle_decode_frame(AVCodecContext *avctx, } if(has_palette) { - int size; + buffer_size_t size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); if (pal && size == AVPALETTE_SIZE) { diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c index 6669c1302..f7eee4a59 100644 --- a/libavcodec/qtrleenc.c +++ b/libavcodec/qtrleenc.c @@ -155,10 +155,14 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui int sec_lowest_bulk_cost; int sec_lowest_bulk_cost_index; - uint8_t *this_line = p-> data[0] + line*p-> linesize[0] + - (width - 1)*s->pixel_size; - uint8_t *prev_line = s->previous_frame->data[0] + line * s->previous_frame->linesize[0] + - (width - 1)*s->pixel_size; + const uint8_t *this_line = p->data[0] + line * p->linesize[0] + width * s->pixel_size; + /* There might be no earlier frame if the current frame is a keyframe. + * So just use a pointer to the current frame to avoid a check + * to avoid NULL - s->pixel_size (which is undefined behaviour). */ + const uint8_t *prev_line = s->key_frame ? this_line + : s->previous_frame->data[0] + + line * s->previous_frame->linesize[0] + + width * s->pixel_size; s->length_table[width] = 0; skipcount = 0; @@ -175,6 +179,9 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui int prev_bulk_cost; + this_line -= s->pixel_size; + prev_line -= s->pixel_size; + /* If our lowest bulk cost index is too far away, replace it * with the next lowest bulk cost */ if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) { @@ -259,10 +266,6 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui /* These bulk costs increase every iteration */ lowest_bulk_cost += s->pixel_size; sec_lowest_bulk_cost += s->pixel_size; - if (this_line >= p->data[0] + s->pixel_size) - this_line -= s->pixel_size; - if (prev_line >= s->previous_frame->data[0] + s->pixel_size) - prev_line -= s->pixel_size; } /* Good! Now we have the best sequence for this line, let's output it. */ @@ -369,7 +372,8 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size, 0)) < 0) return ret; - if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) { + if (avctx->gop_size == 0 || !s->previous_frame->data[0] || + (s->avctx->frame_number % avctx->gop_size) == 0) { /* I-Frame */ s->key_frame = 1; } else { @@ -413,4 +417,5 @@ 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 }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/ra144.h b/libavcodec/ra144.h index 19a4ce09f..82ef85288 100644 --- a/libavcodec/ra144.h +++ b/libavcodec/ra144.h @@ -23,6 +23,9 @@ #define AVCODEC_RA144_H #include + +#include "libavutil/mem_internal.h" + #include "lpc.h" #include "audio_frame_queue.h" #include "audiodsp.h" diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index c716c32e6..40b278895 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -134,5 +134,5 @@ AVCodec ff_ra_144_decoder = { .priv_data_size = sizeof(RA144Context), .init = ra144_decode_init, .decode = ra144_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c index 059f58233..c6965c5c4 100644 --- a/libavcodec/ra144enc.c +++ b/libavcodec/ra144enc.c @@ -65,14 +65,11 @@ static av_cold int ra144_encode_init(AVCodecContext * avctx) ret = ff_lpc_init(&ractx->lpc_ctx, avctx->frame_size, LPC_ORDER, FF_LPC_TYPE_LEVINSON); if (ret < 0) - goto error; + return ret; ff_af_queue_init(avctx, &ractx->afq); return 0; -error: - ra144_encode_close(avctx); - return ret; } diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c index aa4bd5d90..0eb2a661c 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -22,6 +22,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #define BITSTREAM_READER_LE #include "avcodec.h" @@ -39,7 +40,8 @@ #define RA288_BLOCKS_PER_FRAME 32 typedef struct RA288Context { - AVFloatDSPContext *fdsp; + void (*vector_fmul)(float *dst, const float *src0, const float *src1, + int len); DECLARE_ALIGNED(32, float, sp_lpc)[FFALIGN(36, 16)]; ///< LPC coefficients for speech data (spec: A) DECLARE_ALIGNED(32, float, gain_lpc)[FFALIGN(10, 16)]; ///< LPC coefficients for gain (spec: GB) @@ -60,18 +62,10 @@ typedef struct RA288Context { float gain_rec[11]; } RA288Context; -static av_cold int ra288_decode_close(AVCodecContext *avctx) -{ - RA288Context *ractx = avctx->priv_data; - - av_freep(&ractx->fdsp); - - return 0; -} - static av_cold int ra288_decode_init(AVCodecContext *avctx) { RA288Context *ractx = avctx->priv_data; + AVFloatDSPContext *fdsp; avctx->channels = 1; avctx->channel_layout = AV_CH_LAYOUT_MONO; @@ -82,9 +76,11 @@ static av_cold int ra288_decode_init(AVCodecContext *avctx) return AVERROR_PATCHWELCOME; } - ractx->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); - if (!ractx->fdsp) + fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!fdsp) return AVERROR(ENOMEM); + ractx->vector_fmul = fdsp->vector_fmul; + av_free(fdsp); return 0; } @@ -158,7 +154,7 @@ static void do_hybrid_window(RA288Context *ractx, av_assert2(order>=0); - ractx->fdsp->vector_fmul(work, window, hist, FFALIGN(order + n + non_rec, 16)); + ractx->vector_fmul(work, window, hist, FFALIGN(order + n + non_rec, 16)); convolve(buffer1, work + order , n , order); convolve(buffer2, work + order + n, non_rec, order); @@ -185,7 +181,7 @@ static void backward_filter(RA288Context *ractx, do_hybrid_window(ractx, order, n, non_rec, temp, hist, rec, window); if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1)) - ractx->fdsp->vector_fmul(lpc, lpc, tab, FFALIGN(order, 16)); + ractx->vector_fmul(lpc, lpc, tab, FFALIGN(order, 16)); memmove(hist, hist + n, move_size*sizeof(*hist)); } @@ -249,6 +245,5 @@ AVCodec ff_ra_288_decoder = { .priv_data_size = sizeof(RA288Context), .init = ra288_decode_init, .decode = ra288_decode_frame, - .close = ra288_decode_close, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; diff --git a/libavcodec/ra288.h b/libavcodec/ra288.h index fa0b528b8..96b074bff 100644 --- a/libavcodec/ra288.h +++ b/libavcodec/ra288.h @@ -24,6 +24,7 @@ #include #include "libavutil/common.h" +#include "libavutil/mem_internal.h" static const float amptable[8]={ 0.515625, 0.90234375, 1.57910156, 2.76342773, diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c index 0080b2394..dc012d71b 100644 --- a/libavcodec/ralf.c +++ b/libavcodec/ralf.c @@ -535,7 +535,8 @@ AVCodec ff_ralf_decoder = { .close = decode_close, .decode = decode_frame, .flush = decode_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, }; diff --git a/libavcodec/rangecoder.c b/libavcodec/rangecoder.c index a6a3f082e..fa7d5526d 100644 --- a/libavcodec/rangecoder.c +++ b/libavcodec/rangecoder.c @@ -121,22 +121,3 @@ int ff_rac_terminate(RangeCoder *c, int version) return c->bytestream - c->bytestream_start; } - -int ff_rac_check_termination(RangeCoder *c, int version) -{ - if (version == 1) { - RangeCoder tmp = *c; - get_rac(c, (uint8_t[]) { 129 }); - - if (c->bytestream == tmp.bytestream && c->bytestream > c->bytestream_start) - tmp.low -= *--tmp.bytestream; - tmp.bytestream_end = tmp.bytestream; - - if (get_rac(&tmp, (uint8_t[]) { 129 })) - return AVERROR_INVALIDDATA; - } else { - if (c->bytestream_end != c->bytestream) - return AVERROR_INVALIDDATA; - } - return 0; -} diff --git a/libavcodec/rangecoder.h b/libavcodec/rangecoder.h index 4d4ca4d52..4495f6df1 100644 --- a/libavcodec/rangecoder.h +++ b/libavcodec/rangecoder.h @@ -57,15 +57,6 @@ void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size); */ int ff_rac_terminate(RangeCoder *c, int version); -/** - * Check if at the current position there is a valid looking termination - * @param version version 0 requires the decoder to know the data size in bytes - * version 1 needs about 1 bit more space but does not need to - * carry the size from encoder to decoder - * @returns negative AVERROR code on error or non negative. - */ -int ff_rac_check_termination(RangeCoder *c, int version); - void ff_build_rac_states(RangeCoder *c, int factor, int max_p); static inline void renorm_encoder(RangeCoder *c) diff --git a/libavcodec/rasc.c b/libavcodec/rasc.c index 706940bf5..207d50c45 100644 --- a/libavcodec/rasc.c +++ b/libavcodec/rasc.c @@ -112,7 +112,7 @@ static int init_frames(AVCodecContext *avctx) } static int decode_fint(AVCodecContext *avctx, - AVPacket *avpkt, unsigned size) + const AVPacket *avpkt, unsigned size) { RASCContext *s = avctx->priv_data; GetByteContext *gb = &s->gb; @@ -171,7 +171,7 @@ static int decode_fint(AVCodecContext *avctx, return 0; } -static int decode_zlib(AVCodecContext *avctx, AVPacket *avpkt, +static int decode_zlib(AVCodecContext *avctx, const AVPacket *avpkt, unsigned size, unsigned uncompressed_size) { RASCContext *s = avctx->priv_data; @@ -205,7 +205,7 @@ static int decode_zlib(AVCodecContext *avctx, AVPacket *avpkt, } static int decode_move(AVCodecContext *avctx, - AVPacket *avpkt, unsigned size) + const AVPacket *avpkt, unsigned size) { RASCContext *s = avctx->priv_data; GetByteContext *gb = &s->gb; @@ -329,7 +329,7 @@ static int decode_move(AVCodecContext *avctx, len--; static int decode_dlta(AVCodecContext *avctx, - AVPacket *avpkt, unsigned size) + const AVPacket *avpkt, unsigned size) { RASCContext *s = avctx->priv_data; GetByteContext *gb = &s->gb; @@ -471,7 +471,7 @@ static int decode_dlta(AVCodecContext *avctx, } static int decode_kfrm(AVCodecContext *avctx, - AVPacket *avpkt, unsigned size) + const AVPacket *avpkt, unsigned size) { RASCContext *s = avctx->priv_data; GetByteContext *gb = &s->gb; @@ -534,7 +534,7 @@ static int decode_kfrm(AVCodecContext *avctx, } static int decode_mous(AVCodecContext *avctx, - AVPacket *avpkt, unsigned size) + const AVPacket *avpkt, unsigned size) { RASCContext *s = avctx->priv_data; GetByteContext *gb = &s->gb; @@ -574,7 +574,7 @@ static int decode_mous(AVCodecContext *avctx, } static int decode_mpos(AVCodecContext *avctx, - AVPacket *avpkt, unsigned size) + const AVPacket *avpkt, unsigned size) { RASCContext *s = avctx->priv_data; GetByteContext *gb = &s->gb; diff --git a/libavcodec/raw.c b/libavcodec/raw.c index b6fb91c1c..079d5c5d1 100644 --- a/libavcodec/raw.c +++ b/libavcodec/raw.c @@ -246,6 +246,7 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { AV_PIX_FMT_GRAY16BE,MKTAG('b', '1', '6', 'g') }, { AV_PIX_FMT_RGB48BE, MKTAG('b', '4', '8', 'r') }, { AV_PIX_FMT_RGBA64BE,MKTAG('b', '6', '4', 'a') }, + { AV_PIX_FMT_BAYER_RGGB16BE, MKTAG('B', 'G', 'G', 'R') }, /* vlc */ { AV_PIX_FMT_YUV410P, MKTAG('I', '4', '1', '0') }, diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index a110a690f..aaafbd46e 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -26,6 +26,7 @@ #include "avcodec.h" #include "bswapdsp.h" +#include "decode.h" #include "get_bits.h" #include "internal.h" #include "raw.h" @@ -366,7 +367,7 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, } if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { - int pal_size; + buffer_size_t pal_size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &pal_size); int ret; @@ -492,6 +493,7 @@ static av_cold int raw_close_decoder(AVCodecContext *avctx) RawVideoContext *context = avctx->priv_data; av_buffer_unref(&context->palette); + av_freep(&context->bitstream_buf); return 0; } diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c index 248020d5d..a60962dc8 100644 --- a/libavcodec/rkmppdec.c +++ b/libavcodec/rkmppdec.c @@ -548,7 +548,7 @@ static void rkmpp_flush(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Failed to reset MPI (code = %d)\n", ret); } -static const AVCodecHWConfigInternal *rkmpp_hw_configs[] = { +static const AVCodecHWConfigInternal *const rkmpp_hw_configs[] = { HW_CONFIG_INTERNAL(DRM_PRIME), NULL }; diff --git a/libavcodec/rl.c b/libavcodec/rl.c index 6eac306b8..93153ff72 100644 --- a/libavcodec/rl.c +++ b/libavcodec/rl.c @@ -25,27 +25,16 @@ #include "rl.h" -void ff_rl_free(RLTable *rl) -{ - int i; - - for (i = 0; i < 2; i++) { - av_freep(&rl->max_run[i]); - av_freep(&rl->max_level[i]); - av_freep(&rl->index_run[i]); - } -} - -av_cold int ff_rl_init(RLTable *rl, - uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3]) +av_cold void ff_rl_init(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]; int last, run, level, start, end, i; - /* If table is static, we can quit if rl->max_level[0] is not NULL */ - if (static_store && rl->max_level[0]) - return 0; + /* If rl->max_level[0] is set, this RLTable has already been initialized */ + if (rl->max_level[0]) + return; /* compute max_level[], max_run[] and index_run[] */ for (last = 0; last < 2; last++) { @@ -70,36 +59,13 @@ av_cold int ff_rl_init(RLTable *rl, if (run > max_run[level]) max_run[level] = run; } - if (static_store) - rl->max_level[last] = static_store[last]; - else { - rl->max_level[last] = av_malloc(MAX_RUN + 1); - if (!rl->max_level[last]) - goto fail; - } + rl->max_level[last] = static_store[last]; memcpy(rl->max_level[last], max_level, MAX_RUN + 1); - if (static_store) - rl->max_run[last] = static_store[last] + MAX_RUN + 1; - else { - rl->max_run[last] = av_malloc(MAX_LEVEL + 1); - if (!rl->max_run[last]) - goto fail; - } + rl->max_run[last] = static_store[last] + MAX_RUN + 1; memcpy(rl->max_run[last], max_run, MAX_LEVEL + 1); - if (static_store) - rl->index_run[last] = static_store[last] + MAX_RUN + MAX_LEVEL + 2; - else { - rl->index_run[last] = av_malloc(MAX_RUN + 1); - if (!rl->index_run[last]) - goto fail; - } + rl->index_run[last] = static_store[last] + MAX_RUN + MAX_LEVEL + 2; memcpy(rl->index_run[last], index_run, MAX_RUN + 1); } - return 0; - -fail: - ff_rl_free(rl); - return AVERROR(ENOMEM); } av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size) @@ -114,6 +80,9 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size) int qmul = q * 2; int qadd = (q - 1) | 1; + if (!rl->rl_vlc[q]) + return; + if (q == 0) { qmul = 1; qadd = 0; diff --git a/libavcodec/rl.h b/libavcodec/rl.h index 9a767bc5f..26e0b32a9 100644 --- a/libavcodec/rl.h +++ b/libavcodec/rl.h @@ -49,17 +49,12 @@ typedef struct RLTable { } RLTable; /** - * @param static_store static uint8_t array[2][2*MAX_RUN + MAX_LEVEL + 3] which will hold - * the level and run tables, if this is NULL av_malloc() will be used + * @param static_store static uint8_t array[2][2*MAX_RUN + MAX_LEVEL + 3] + * to hold the level and run tables. */ -int ff_rl_init(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]); +void ff_rl_init(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]); void ff_rl_init_vlc(RLTable *rl, unsigned static_size); -/** - * Free the contents of a dynamically allocated table. - */ -void ff_rl_free(RLTable *rl); - #define INIT_VLC_RL(rl, static_size)\ {\ int q;\ @@ -73,6 +68,14 @@ void ff_rl_free(RLTable *rl); }\ } +#define INIT_FIRST_VLC_RL(rl, static_size) \ +do { \ + static RL_VLC_ELEM rl_vlc_table[static_size]; \ + \ + rl.rl_vlc[0] = rl_vlc_table; \ + ff_rl_init_vlc(&rl, static_size); \ +} while (0) + static inline int get_rl_index(const RLTable *rl, int last, int run, int level) { int index; diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c index 5154604be..c09212d3d 100644 --- a/libavcodec/roqaudioenc.c +++ b/libavcodec/roqaudioenc.c @@ -53,7 +53,6 @@ static av_cold int roq_dpcm_encode_close(AVCodecContext *avctx) static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx) { ROQDPCMContext *context = avctx->priv_data; - int ret; if (avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "Audio must be mono or stereo\n"); @@ -70,17 +69,12 @@ static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx) context->frame_buffer = av_malloc(8 * ROQ_FRAME_SIZE * avctx->channels * sizeof(*context->frame_buffer)); - if (!context->frame_buffer) { - ret = AVERROR(ENOMEM); - goto error; - } + if (!context->frame_buffer) + return AVERROR(ENOMEM); context->lastSample[0] = context->lastSample[1] = 0; return 0; -error: - roq_dpcm_encode_close(avctx); - return ret; } static unsigned char dpcm_predict(short *previous, short current) diff --git a/libavcodec/roqvideo.h b/libavcodec/roqvideo.h index 3da6eaa99..8318b6e5a 100644 --- a/libavcodec/roqvideo.h +++ b/libavcodec/roqvideo.h @@ -22,9 +22,7 @@ #ifndef AVCODEC_ROQVIDEO_H #define AVCODEC_ROQVIDEO_H -#include "libavutil/lfg.h" #include "avcodec.h" -#include "bytestream.h" typedef struct roq_cell { unsigned char y[4]; @@ -39,40 +37,15 @@ typedef struct motion_vect { int d[2]; } motion_vect; -struct RoqTempData; - typedef struct RoqContext { - const AVClass *class; AVCodecContext *avctx; AVFrame *last_frame; AVFrame *current_frame; - int first_frame; + int width, height; roq_cell cb2x2[256]; roq_qcell cb4x4[256]; - - GetByteContext gb; - int width, height; - - /* Encoder only data */ - AVLFG randctx; - uint64_t lambda; - - motion_vect *this_motion4; - motion_vect *last_motion4; - - motion_vect *this_motion8; - motion_vect *last_motion8; - - unsigned int framesSinceKeyframe; - - const AVFrame *frame_to_enc; - uint8_t *out_buf; - struct RoqTempData *tmpData; - - int quake3_compat; // Quake 3 compatibility option - } RoqContext; #define RoQ_INFO 0x1001 diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c index a0c293f2f..36b4ddf75 100644 --- a/libavcodec/roqvideodec.c +++ b/libavcodec/roqvideodec.c @@ -33,20 +33,19 @@ #include "internal.h" #include "roqvideo.h" -static void roqvideo_decode_frame(RoqContext *ri) +static void roqvideo_decode_frame(RoqContext *ri, GetByteContext *gb) { unsigned int chunk_id = 0, chunk_arg = 0; unsigned long chunk_size = 0; int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1; int vqid, xpos, ypos, xp, yp, x, y, mx, my; - int frame_stats[2][4] = {{0},{0}}; roq_qcell *qcell; int64_t chunk_start; - while (bytestream2_get_bytes_left(&ri->gb) >= 8) { - chunk_id = bytestream2_get_le16(&ri->gb); - chunk_size = bytestream2_get_le32(&ri->gb); - chunk_arg = bytestream2_get_le16(&ri->gb); + while (bytestream2_get_bytes_left(gb) >= 8) { + chunk_id = bytestream2_get_le16(gb); + chunk_size = bytestream2_get_le32(gb); + chunk_arg = bytestream2_get_le16(gb); if(chunk_id == RoQ_QUAD_VQ) break; @@ -56,54 +55,53 @@ static void roqvideo_decode_frame(RoqContext *ri) if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size) nv2 = 256; for(i = 0; i < nv1; i++) { - ri->cb2x2[i].y[0] = bytestream2_get_byte(&ri->gb); - ri->cb2x2[i].y[1] = bytestream2_get_byte(&ri->gb); - ri->cb2x2[i].y[2] = bytestream2_get_byte(&ri->gb); - ri->cb2x2[i].y[3] = bytestream2_get_byte(&ri->gb); - ri->cb2x2[i].u = bytestream2_get_byte(&ri->gb); - ri->cb2x2[i].v = bytestream2_get_byte(&ri->gb); + ri->cb2x2[i].y[0] = bytestream2_get_byte(gb); + ri->cb2x2[i].y[1] = bytestream2_get_byte(gb); + ri->cb2x2[i].y[2] = bytestream2_get_byte(gb); + ri->cb2x2[i].y[3] = bytestream2_get_byte(gb); + ri->cb2x2[i].u = bytestream2_get_byte(gb); + ri->cb2x2[i].v = bytestream2_get_byte(gb); } for(i = 0; i < nv2; i++) for(j = 0; j < 4; j++) - ri->cb4x4[i].idx[j] = bytestream2_get_byte(&ri->gb); + ri->cb4x4[i].idx[j] = bytestream2_get_byte(gb); } } - chunk_start = bytestream2_tell(&ri->gb); + chunk_start = bytestream2_tell(gb); xpos = ypos = 0; - if (chunk_size > bytestream2_get_bytes_left(&ri->gb)) { + if (chunk_size > bytestream2_get_bytes_left(gb)) { av_log(ri->avctx, AV_LOG_ERROR, "Chunk does not fit in input buffer\n"); - chunk_size = bytestream2_get_bytes_left(&ri->gb); + chunk_size = bytestream2_get_bytes_left(gb); } - while (bytestream2_tell(&ri->gb) < chunk_start + chunk_size) { + while (bytestream2_tell(gb) < chunk_start + chunk_size) { for (yp = ypos; yp < ypos + 16; yp += 8) for (xp = xpos; xp < xpos + 16; xp += 8) { - if (bytestream2_tell(&ri->gb) >= chunk_start + chunk_size) { + if (bytestream2_tell(gb) >= chunk_start + chunk_size) { av_log(ri->avctx, AV_LOG_VERBOSE, "Chunk is too short\n"); return; } if (vqflg_pos < 0) { - vqflg = bytestream2_get_le16(&ri->gb); + vqflg = bytestream2_get_le16(gb); vqflg_pos = 7; } vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; - frame_stats[0][vqid]++; vqflg_pos--; switch(vqid) { case RoQ_ID_MOT: break; case RoQ_ID_FCC: { - int byte = bytestream2_get_byte(&ri->gb); + int byte = bytestream2_get_byte(gb); mx = 8 - (byte >> 4) - ((signed char) (chunk_arg >> 8)); my = 8 - (byte & 0xf) - ((signed char) chunk_arg); ff_apply_motion_8x8(ri, xp, yp, mx, my); break; } case RoQ_ID_SLD: - qcell = ri->cb4x4 + bytestream2_get_byte(&ri->gb); + qcell = ri->cb4x4 + bytestream2_get_byte(gb); ff_apply_vector_4x4(ri, xp, yp, ri->cb2x2 + qcell->idx[0]); ff_apply_vector_4x4(ri, xp + 4, yp, ri->cb2x2 + qcell->idx[1]); ff_apply_vector_4x4(ri, xp, yp + 4, ri->cb2x2 + qcell->idx[2]); @@ -115,39 +113,38 @@ static void roqvideo_decode_frame(RoqContext *ri) if(k & 0x01) x += 4; if(k & 0x02) y += 4; - if (bytestream2_tell(&ri->gb) >= chunk_start + chunk_size) { + if (bytestream2_tell(gb) >= chunk_start + chunk_size) { av_log(ri->avctx, AV_LOG_VERBOSE, "Chunk is too short\n"); return; } if (vqflg_pos < 0) { - vqflg = bytestream2_get_le16(&ri->gb); + vqflg = bytestream2_get_le16(gb); vqflg_pos = 7; } vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; - frame_stats[1][vqid]++; vqflg_pos--; switch(vqid) { case RoQ_ID_MOT: break; case RoQ_ID_FCC: { - int byte = bytestream2_get_byte(&ri->gb); + int byte = bytestream2_get_byte(gb); mx = 8 - (byte >> 4) - ((signed char) (chunk_arg >> 8)); my = 8 - (byte & 0xf) - ((signed char) chunk_arg); ff_apply_motion_4x4(ri, x, y, mx, my); break; } case RoQ_ID_SLD: - qcell = ri->cb4x4 + bytestream2_get_byte(&ri->gb); + qcell = ri->cb4x4 + bytestream2_get_byte(gb); ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + qcell->idx[0]); ff_apply_vector_2x2(ri, x + 2, y, ri->cb2x2 + qcell->idx[1]); ff_apply_vector_2x2(ri, x, y + 2, ri->cb2x2 + qcell->idx[2]); ff_apply_vector_2x2(ri, x + 2, y + 2, ri->cb2x2 + qcell->idx[3]); break; case RoQ_ID_CCC: - ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + bytestream2_get_byte(&ri->gb)); - ff_apply_vector_2x2(ri, x + 2, y, ri->cb2x2 + bytestream2_get_byte(&ri->gb)); - ff_apply_vector_2x2(ri, x, y + 2, ri->cb2x2 + bytestream2_get_byte(&ri->gb)); - ff_apply_vector_2x2(ri, x + 2, y + 2, ri->cb2x2 + bytestream2_get_byte(&ri->gb)); + ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + bytestream2_get_byte(gb)); + ff_apply_vector_2x2(ri, x + 2, y, ri->cb2x2 + bytestream2_get_byte(gb)); + ff_apply_vector_2x2(ri, x, y + 2, ri->cb2x2 + bytestream2_get_byte(gb)); + ff_apply_vector_2x2(ri, x + 2, y + 2, ri->cb2x2 + bytestream2_get_byte(gb)); break; } } @@ -184,11 +181,8 @@ static av_cold int roq_decode_init(AVCodecContext *avctx) s->last_frame = av_frame_alloc(); s->current_frame = av_frame_alloc(); - if (!s->current_frame || !s->last_frame) { - av_frame_free(&s->current_frame); - av_frame_free(&s->last_frame); + if (!s->current_frame || !s->last_frame) return AVERROR(ENOMEM); - } avctx->pix_fmt = AV_PIX_FMT_YUVJ444P; avctx->color_range = AVCOL_RANGE_JPEG; @@ -204,6 +198,7 @@ static int roq_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; RoqContext *s = avctx->priv_data; int copy = !s->current_frame->data[0] && s->last_frame->data[0]; + GetByteContext gb; int ret; if ((ret = ff_reget_buffer(avctx, s->current_frame, 0)) < 0) @@ -215,8 +210,8 @@ static int roq_decode_frame(AVCodecContext *avctx, return ret; } - bytestream2_init(&s->gb, buf, buf_size); - roqvideo_decode_frame(s); + bytestream2_init(&gb, buf, buf_size); + roqvideo_decode_frame(s, &gb); if ((ret = av_frame_ref(data, s->current_frame)) < 0) return ret; @@ -248,4 +243,5 @@ AVCodec ff_roq_decoder = { .close = roq_decode_end, .decode = roq_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index ac05123dc..1ab0de0ab 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -57,6 +57,7 @@ #include #include "libavutil/attributes.h" +#include "libavutil/lfg.h" #include "libavutil/opt.h" #include "roqvideo.h" #include "bytestream.h" @@ -77,6 +78,85 @@ /* The cast is useful when multiplying it by INT_MAX */ #define ROQ_LAMBDA_SCALE ((uint64_t) FF_LAMBDA_SCALE) +typedef struct RoqCodebooks { + int numCB4; + int numCB2; + int usedCB2[MAX_CBS_2x2]; + int usedCB4[MAX_CBS_4x4]; + uint8_t unpacked_cb2[MAX_CBS_2x2*2*2*3]; + uint8_t unpacked_cb4[MAX_CBS_4x4*4*4*3]; + uint8_t unpacked_cb4_enlarged[MAX_CBS_4x4*8*8*3]; +} RoqCodebooks; + +/** + * Temporary vars + */ +typedef struct RoqTempData +{ + int f2i4[MAX_CBS_4x4]; + int i2f4[MAX_CBS_4x4]; + int f2i2[MAX_CBS_2x2]; + int i2f2[MAX_CBS_2x2]; + + int mainChunkSize; + + int numCB4; + int numCB2; + + RoqCodebooks codebooks; + + int used_option[4]; +} RoqTempData; + +typedef struct SubcelEvaluation { + int eval_dist[4]; + int best_bit_use; + int best_coding; + + int subCels[4]; + motion_vect motion; + int cbEntry; +} SubcelEvaluation; + +typedef struct CelEvaluation { + int eval_dist[4]; + int best_coding; + + SubcelEvaluation subCels[4]; + + motion_vect motion; + int cbEntry; + + int sourceX, sourceY; +} CelEvaluation; + +typedef struct RoqEncContext { + RoqContext common; + AVLFG randctx; + uint64_t lambda; + + motion_vect *this_motion4; + motion_vect *last_motion4; + + motion_vect *this_motion8; + motion_vect *last_motion8; + + unsigned int framesSinceKeyframe; + + const AVFrame *frame_to_enc; + uint8_t *out_buf; + RoqTempData tmp_data; + roq_cell results4[4 * MAX_CBS_4x4]; + int tmp_codebook_buf[FFMAX(24 * MAX_CBS_4x4, 6 * MAX_CBS_2x2)]; + + CelEvaluation *cel_evals; + int *closest_cb; + int *points; // Allocated together with closest_cb + + int first_frame; + int quake3_compat; // Quake 3 compatibility option +} RoqEncContext; + /* Macroblock support functions */ static void unpack_roq_cell(roq_cell *cell, uint8_t u[4*3]) { @@ -143,9 +223,10 @@ static int block_sse(uint8_t * const *buf1, uint8_t * const *buf2, int x1, int y return sse; } -static int eval_motion_dist(RoqContext *enc, int x, int y, motion_vect vect, +static int eval_motion_dist(RoqEncContext *enc, int x, int y, motion_vect vect, int size) { + RoqContext *const roq = &enc->common; int mx=vect.d[0]; int my=vect.d[1]; @@ -158,12 +239,12 @@ static int eval_motion_dist(RoqContext *enc, int x, int y, motion_vect vect, mx += x; my += y; - if ((unsigned) mx > enc->width-size || (unsigned) my > enc->height-size) + if ((unsigned) mx > roq->width-size || (unsigned) my > roq->height-size) return INT_MAX; - return block_sse(enc->frame_to_enc->data, enc->last_frame->data, x, y, + return block_sse(enc->frame_to_enc->data, roq->last_frame->data, x, y, mx, my, - enc->frame_to_enc->linesize, enc->last_frame->linesize, + enc->frame_to_enc->linesize, roq->last_frame->linesize, size); } @@ -184,78 +265,23 @@ static inline int squared_diff_macroblock(uint8_t a[], uint8_t b[], int size) return sdiff; } -typedef struct SubcelEvaluation { - int eval_dist[4]; - int best_bit_use; - int best_coding; - - int subCels[4]; - motion_vect motion; - int cbEntry; -} SubcelEvaluation; - -typedef struct CelEvaluation { - int eval_dist[4]; - int best_coding; - - SubcelEvaluation subCels[4]; - - motion_vect motion; - int cbEntry; - - int sourceX, sourceY; -} CelEvaluation; - -typedef struct RoqCodebooks { - int numCB4; - int numCB2; - int usedCB2[MAX_CBS_2x2]; - int usedCB4[MAX_CBS_4x4]; - uint8_t unpacked_cb2[MAX_CBS_2x2*2*2*3]; - uint8_t unpacked_cb4[MAX_CBS_4x4*4*4*3]; - uint8_t unpacked_cb4_enlarged[MAX_CBS_4x4*8*8*3]; -} RoqCodebooks; - -/** - * Temporary vars - */ -typedef struct RoqTempData -{ - CelEvaluation *cel_evals; - - int f2i4[MAX_CBS_4x4]; - int i2f4[MAX_CBS_4x4]; - int f2i2[MAX_CBS_2x2]; - int i2f2[MAX_CBS_2x2]; - - int mainChunkSize; - - int numCB4; - int numCB2; - - RoqCodebooks codebooks; - - int *closest_cb2; - int used_option[4]; -} RoqTempdata; - /** * Initialize cel evaluators and set their source coordinates */ -static int create_cel_evals(RoqContext *enc, RoqTempdata *tempData) +static int create_cel_evals(RoqEncContext *enc) { - int n=0, x, y, i; + RoqContext *const roq = &enc->common; - tempData->cel_evals = av_malloc_array(enc->width*enc->height/64, sizeof(CelEvaluation)); - if (!tempData->cel_evals) + enc->cel_evals = av_malloc_array(roq->width * roq->height / 64, sizeof(CelEvaluation)); + if (!enc->cel_evals) return AVERROR(ENOMEM); /* Map to the ROQ quadtree order */ - for (y=0; yheight; y+=16) - for (x=0; xwidth; x+=16) - for(i=0; i<4; i++) { - tempData->cel_evals[n ].sourceX = x + (i&1)*8; - tempData->cel_evals[n++].sourceY = y + (i&2)*4; + for (int y = 0, n = 0; y < roq->height; y += 16) + for (int x = 0; x < roq->width; x += 16) + for(int i = 0; i < 4; i++) { + enc->cel_evals[n ].sourceX = x + (i&1)*8; + enc->cel_evals[n++].sourceY = y + (i&2)*4; } return 0; @@ -307,7 +333,7 @@ static int index_mb(uint8_t cluster[], uint8_t cb[], int numCB, } \ } while(0) -static void motion_search(RoqContext *enc, int blocksize) +static void motion_search(RoqEncContext *enc, int blocksize) { static const motion_vect offsets[8] = { {{ 0,-1}}, @@ -320,6 +346,7 @@ static void motion_search(RoqContext *enc, int blocksize) {{ 1, 1}}, }; + RoqContext *const roq = &enc->common; int diff, lowestdiff, oldbest; int off[3]; motion_vect bestpick = {{0,0}}; @@ -328,8 +355,7 @@ static void motion_search(RoqContext *enc, int blocksize) motion_vect *last_motion; motion_vect *this_motion; motion_vect vect, vect2; - - int max=(enc->width/blocksize)*enc->height/blocksize; + const int max = (roq->width / blocksize) * roq->height / blocksize; if (blocksize == 4) { last_motion = enc->last_motion4; @@ -339,17 +365,17 @@ static void motion_search(RoqContext *enc, int blocksize) this_motion = enc->this_motion8; } - for (i=0; iheight; i+=blocksize) - for (j=0; jwidth; j+=blocksize) { + for (i = 0; i< roq->height; i += blocksize) + for (j = 0; j < roq->width; j += blocksize) { lowestdiff = eval_motion_dist(enc, j, i, (motion_vect) {{0,0}}, blocksize); bestpick.d[0] = 0; bestpick.d[1] = 0; if (blocksize == 4) - EVAL_MOTION(enc->this_motion8[(i/8)*(enc->width/8) + j/8]); + EVAL_MOTION(enc->this_motion8[(i/8) * (roq->width/8) + j/8]); - offset = (i/blocksize)*enc->width/blocksize + j/blocksize; + offset = (i/blocksize) * roq->width / blocksize + j / blocksize; if (offset < max && offset >= 0) EVAL_MOTION(last_motion[offset]); @@ -357,12 +383,12 @@ static void motion_search(RoqContext *enc, int blocksize) if (offset < max && offset >= 0) EVAL_MOTION(last_motion[offset]); - offset = (i/blocksize + 1)*enc->width/blocksize + j/blocksize; + offset = (i/blocksize + 1) * roq->width / blocksize + j / blocksize; if (offset < max && offset >= 0) EVAL_MOTION(last_motion[offset]); - off[0]= (i/blocksize)*enc->width/blocksize + j/blocksize - 1; - off[1]= off[0] - enc->width/blocksize + 1; + off[0]= (i/blocksize) * roq->width / blocksize + j/blocksize - 1; + off[1]= off[0] - roq->width / blocksize + 1; off[2]= off[1] + 1; if (i) { @@ -391,7 +417,7 @@ static void motion_search(RoqContext *enc, int blocksize) } vect = bestpick; } - offset = (i/blocksize)*enc->width/blocksize + j/blocksize; + offset = (i/blocksize) * roq->width / blocksize + j/blocksize; this_motion[offset] = bestpick; } } @@ -400,8 +426,10 @@ static void motion_search(RoqContext *enc, int blocksize) * Get distortion for all options available to a subcel */ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, - int y, RoqContext *enc, RoqTempdata *tempData) + int y, RoqEncContext *enc) { + RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; uint8_t mb4[4*4*3]; uint8_t mb2[2*2*3]; int cluster_index; @@ -410,25 +438,25 @@ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, static const int bitsUsed[4] = {2, 10, 10, 34}; if (enc->framesSinceKeyframe >= 1) { - subcel->motion = enc->this_motion4[y*enc->width/16 + x/4]; + subcel->motion = enc->this_motion4[y * roq->width / 16 + x / 4]; subcel->eval_dist[RoQ_ID_FCC] = eval_motion_dist(enc, x, y, - enc->this_motion4[y*enc->width/16 + x/4], 4); + enc->this_motion4[y * roq->width / 16 + x / 4], 4); } else subcel->eval_dist[RoQ_ID_FCC] = INT_MAX; if (enc->framesSinceKeyframe >= 2) subcel->eval_dist[RoQ_ID_MOT] = block_sse(enc->frame_to_enc->data, - enc->current_frame->data, x, + roq->current_frame->data, x, y, x, y, enc->frame_to_enc->linesize, - enc->current_frame->linesize, + roq->current_frame->linesize, 4); else subcel->eval_dist[RoQ_ID_MOT] = INT_MAX; - cluster_index = y*enc->width/16 + x/4; + cluster_index = y * roq->width / 16 + x / 4; get_frame_mb(enc->frame_to_enc, x, y, mb4, 4); @@ -440,7 +468,7 @@ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, subcel->eval_dist[RoQ_ID_CCC] = 0; for(i=0;i<4;i++) { - subcel->subCels[i] = tempData->closest_cb2[cluster_index*4+i]; + subcel->subCels[i] = enc->closest_cb[cluster_index*4+i]; get_frame_mb(enc->frame_to_enc, x+2*(i&1), y+(i&2), mb2, 2); @@ -463,11 +491,12 @@ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, /** * Get distortion for all options available to a cel */ -static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, - RoqTempdata *tempData) +static void gather_data_for_cel(CelEvaluation *cel, RoqEncContext *enc) { + RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; uint8_t mb8[8*8*3]; - int index = cel->sourceY*enc->width/64 + cel->sourceX/8; + int index = cel->sourceY * roq->width / 64 + cel->sourceX/8; int i, j, best_dist, divide_bit_use; int bitsUsed[4] = {2, 10, 10, 0}; @@ -483,11 +512,11 @@ static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, if (enc->framesSinceKeyframe >= 2) cel->eval_dist[RoQ_ID_MOT] = block_sse(enc->frame_to_enc->data, - enc->current_frame->data, + roq->current_frame->data, cel->sourceX, cel->sourceY, cel->sourceX, cel->sourceY, enc->frame_to_enc->linesize, - enc->current_frame->linesize,8); + roq->current_frame->linesize,8); else cel->eval_dist[RoQ_ID_MOT] = INT_MAX; @@ -497,10 +526,10 @@ static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, index_mb(mb8, tempData->codebooks.unpacked_cb4_enlarged, tempData->codebooks.numCB4, &cel->cbEntry, 8); - gather_data_for_subcel(cel->subCels + 0, cel->sourceX+0, cel->sourceY+0, enc, tempData); - gather_data_for_subcel(cel->subCels + 1, cel->sourceX+4, cel->sourceY+0, enc, tempData); - gather_data_for_subcel(cel->subCels + 2, cel->sourceX+0, cel->sourceY+4, enc, tempData); - gather_data_for_subcel(cel->subCels + 3, cel->sourceX+4, cel->sourceY+4, enc, tempData); + gather_data_for_subcel(cel->subCels + 0, cel->sourceX+0, cel->sourceY+0, enc); + gather_data_for_subcel(cel->subCels + 1, cel->sourceX+4, cel->sourceY+0, enc); + gather_data_for_subcel(cel->subCels + 2, cel->sourceX+0, cel->sourceY+4, enc); + gather_data_for_subcel(cel->subCels + 3, cel->sourceX+4, cel->sourceY+4, enc); cel->eval_dist[RoQ_ID_CCC] = 0; divide_bit_use = 0; @@ -537,8 +566,10 @@ static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, } } -static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData) +static void remap_codebooks(RoqEncContext *enc) { + RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; int i, j, idx=0; /* Make remaps for the final codebook usage */ @@ -547,7 +578,7 @@ static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData) tempData->i2f4[i] = idx; tempData->f2i4[idx] = i; for (j=0; j<4; j++) - tempData->codebooks.usedCB2[enc->cb4x4[i].idx[j]]++; + tempData->codebooks.usedCB2[roq->cb4x4[i].idx[j]]++; idx++; } } @@ -569,8 +600,10 @@ static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData) /** * Write codebook chunk */ -static void write_codebooks(RoqContext *enc, RoqTempdata *tempData) +static void write_codebooks(RoqEncContext *enc) { + RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; int i, j; uint8_t **outp= &enc->out_buf; @@ -581,14 +614,14 @@ static void write_codebooks(RoqContext *enc, RoqTempdata *tempData) bytestream_put_byte(outp, tempData->numCB2); for (i=0; inumCB2; i++) { - bytestream_put_buffer(outp, enc->cb2x2[tempData->f2i2[i]].y, 4); - bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].u); - bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].v); + bytestream_put_buffer(outp, roq->cb2x2[tempData->f2i2[i]].y, 4); + bytestream_put_byte(outp, roq->cb2x2[tempData->f2i2[i]].u); + bytestream_put_byte(outp, roq->cb2x2[tempData->f2i2[i]].v); } for (i=0; inumCB4; i++) for (j=0; j<4; j++) - bytestream_put_byte(outp, tempData->i2f2[enc->cb4x4[tempData->f2i4[i]].idx[j]]); + bytestream_put_byte(outp, tempData->i2f2[roq->cb4x4[tempData->f2i4[i]].idx[j]]); } } @@ -623,8 +656,11 @@ static void write_typecode(CodingSpool *s, uint8_t type) } } -static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, int w, int h, int numBlocks) +static void reconstruct_and_encode_image(RoqEncContext *enc, + int w, int h, int numBlocks) { + RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; int i, j, k; int x, y; int subX, subY; @@ -650,7 +686,7 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&enc->out_buf, 0x0); for (i=0; icel_evals + i; + eval = enc->cel_evals + i; x = eval->sourceX; y = eval->sourceY; @@ -665,7 +701,7 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, motion_arg(eval->motion)); write_typecode(&spool, RoQ_ID_FCC); - ff_apply_motion_8x8(enc, x, y, + ff_apply_motion_8x8(roq, x, y, eval->motion.d[0], eval->motion.d[1]); break; @@ -673,11 +709,11 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, tempData->i2f4[eval->cbEntry]); write_typecode(&spool, RoQ_ID_SLD); - qcell = enc->cb4x4 + eval->cbEntry; - ff_apply_vector_4x4(enc, x , y , enc->cb2x2 + qcell->idx[0]); - ff_apply_vector_4x4(enc, x+4, y , enc->cb2x2 + qcell->idx[1]); - ff_apply_vector_4x4(enc, x , y+4, enc->cb2x2 + qcell->idx[2]); - ff_apply_vector_4x4(enc, x+4, y+4, enc->cb2x2 + qcell->idx[3]); + qcell = roq->cb4x4 + eval->cbEntry; + ff_apply_vector_4x4(roq, x , y , roq->cb2x2 + qcell->idx[0]); + ff_apply_vector_4x4(roq, x+4, y , roq->cb2x2 + qcell->idx[1]); + ff_apply_vector_4x4(roq, x , y+4, roq->cb2x2 + qcell->idx[2]); + ff_apply_vector_4x4(roq, x+4, y+4, roq->cb2x2 + qcell->idx[3]); break; case RoQ_ID_CCC: @@ -695,7 +731,7 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, motion_arg(eval->subCels[j].motion)); - ff_apply_motion_4x4(enc, subX, subY, + ff_apply_motion_4x4(roq, subX, subY, eval->subCels[j].motion.d[0], eval->subCels[j].motion.d[1]); break; @@ -704,16 +740,16 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, tempData->i2f4[eval->subCels[j].cbEntry]); - qcell = enc->cb4x4 + eval->subCels[j].cbEntry; + qcell = roq->cb4x4 + eval->subCels[j].cbEntry; - ff_apply_vector_2x2(enc, subX , subY , - enc->cb2x2 + qcell->idx[0]); - ff_apply_vector_2x2(enc, subX+2, subY , - enc->cb2x2 + qcell->idx[1]); - ff_apply_vector_2x2(enc, subX , subY+2, - enc->cb2x2 + qcell->idx[2]); - ff_apply_vector_2x2(enc, subX+2, subY+2, - enc->cb2x2 + qcell->idx[3]); + ff_apply_vector_2x2(roq, subX , subY , + roq->cb2x2 + qcell->idx[0]); + ff_apply_vector_2x2(roq, subX+2, subY , + roq->cb2x2 + qcell->idx[1]); + ff_apply_vector_2x2(roq, subX , subY+2, + roq->cb2x2 + qcell->idx[2]); + ff_apply_vector_2x2(roq, subX+2, subY+2, + roq->cb2x2 + qcell->idx[3]); break; case RoQ_ID_CCC: @@ -722,8 +758,8 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, tempData->i2f2[cb_idx]); - ff_apply_vector_2x2(enc, subX + 2*(k&1), subY + (k&2), - enc->cb2x2 + cb_idx); + ff_apply_vector_2x2(roq, subX + 2*(k&1), subY + (k&2), + roq->cb2x2 + cb_idx); } break; } @@ -742,7 +778,7 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, /** * Create a single YUV cell from a 2x2 section of the image */ -static inline void frame_block_to_cell(uint8_t *block, uint8_t * const *data, +static inline void frame_block_to_cell(int *block, uint8_t * const *data, int top, int left, const int *stride) { int i, j, u=0, v=0; @@ -756,14 +792,14 @@ static inline void frame_block_to_cell(uint8_t *block, uint8_t * const *data, v += data[2][x]; } - *block++ = (u+2)/4; - *block++ = (v+2)/4; + *block++ = (u + 2) / 4 * CHROMA_BIAS; + *block++ = (v + 2) / 4 * CHROMA_BIAS; } /** * Create YUV clusters for the entire image */ -static void create_clusters(const AVFrame *frame, int w, int h, uint8_t *yuvClusters) +static void create_clusters(const AVFrame *frame, int w, int h, int *points) { int i, j, k, l; @@ -771,42 +807,30 @@ static void create_clusters(const AVFrame *frame, int w, int h, uint8_t *yuvClus for (j=0; jdata, + frame_block_to_cell(points + (l + 2*k)*6, frame->data, i+2*k, j+2*l, frame->linesize); - yuvClusters += 24; + points += 24; } } -static int generate_codebook(RoqContext *enc, RoqTempdata *tempdata, +static int generate_codebook(RoqEncContext *enc, int *points, int inputCount, roq_cell *results, int size, int cbsize) { int i, j, k, ret = 0; int c_size = size*size/4; int *buf; - int *codebook = av_malloc_array(6*c_size, cbsize*sizeof(int)); - int *closest_cb; - - if (!codebook) - return AVERROR(ENOMEM); - - if (size == 4) { - closest_cb = av_malloc_array(6*c_size, inputCount*sizeof(int)); - if (!closest_cb) { - ret = AVERROR(ENOMEM); - goto out; - } - } else - closest_cb = tempdata->closest_cb2; + int *codebook = enc->tmp_codebook_buf; + int *closest_cb = enc->closest_cb; ret = avpriv_init_elbg(points, 6 * c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); if (ret < 0) - goto out; + return ret; ret = avpriv_do_elbg(points, 6 * c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); if (ret < 0) - goto out; + return ret; buf = codebook; for (i=0; iv = (*buf++ + CHROMA_BIAS/2)/CHROMA_BIAS; results++; } -out: - if (size == 4) - av_free(closest_cb); - av_free(codebook); - return ret; + return 0; } -static int generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData) +static int generate_new_codebooks(RoqEncContext *enc) { int i, j, ret = 0; - RoqCodebooks *codebooks = &tempData->codebooks; - int max = enc->width*enc->height/16; + RoqCodebooks *codebooks = &enc->tmp_data.codebooks; + RoqContext *const roq = &enc->common; + int max = roq->width * roq->height / 16; uint8_t mb2[3*4]; - roq_cell *results4 = av_malloc(sizeof(roq_cell)*MAX_CBS_4x4*4); - uint8_t *yuvClusters=av_malloc_array(max, sizeof(int)*6*4); - int *points = av_malloc_array(max, 6*4*sizeof(int)); - int bias; - - if (!results4 || !yuvClusters || !points) { - ret = AVERROR(ENOMEM); - goto out; - } + int *points = enc->points; /* Subsample YUV data */ - create_clusters(enc->frame_to_enc, enc->width, enc->height, yuvClusters); - - /* Cast to integer and apply chroma bias */ - for (i=0; iquake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4))) < 0) - goto out; + create_clusters(enc->frame_to_enc, roq->width, roq->height, points); codebooks->numCB4 = (enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4); - tempData->closest_cb2 = av_malloc_array(max, 4*sizeof(int)); - if (!tempData->closest_cb2) { - ret = AVERROR(ENOMEM); - goto out; - } + /* Create 4x4 codebooks */ + if ((ret = generate_codebook(enc, points, max, enc->results4, + 4, codebooks->numCB4)) < 0) + return ret; /* Create 2x2 codebooks */ - if ((ret = generate_codebook(enc, tempData, points, max * 4, - enc->cb2x2, 2, MAX_CBS_2x2)) < 0) - goto out; + if ((ret = generate_codebook(enc, points, max * 4, + roq->cb2x2, 2, MAX_CBS_2x2)) < 0) + return ret; codebooks->numCB2 = MAX_CBS_2x2; /* Unpack 2x2 codebook clusters */ for (i=0; inumCB2; i++) - unpack_roq_cell(enc->cb2x2 + i, codebooks->unpacked_cb2 + i*2*2*3); + unpack_roq_cell(roq->cb2x2 + i, codebooks->unpacked_cb2 + i*2*2*3); /* Index all 4x4 entries to the 2x2 entries, unpack, and enlarge */ for (i=0; inumCB4; i++) { for (j=0; j<4; j++) { - unpack_roq_cell(&results4[4*i + j], mb2); + unpack_roq_cell(&enc->results4[4*i + j], mb2); index_mb(mb2, codebooks->unpacked_cb2, codebooks->numCB2, - &enc->cb4x4[i].idx[j], 2); + &roq->cb4x4[i].idx[j], 2); } - unpack_roq_qcell(codebooks->unpacked_cb2, enc->cb4x4 + i, + unpack_roq_qcell(codebooks->unpacked_cb2, roq->cb4x4 + i, codebooks->unpacked_cb4 + i*4*4*3); enlarge_roq_mb4(codebooks->unpacked_cb4 + i*4*4*3, codebooks->unpacked_cb4_enlarged + i*8*8*3); } -out: - av_free(yuvClusters); - av_free(points); - av_free(results4); - return ret; + + return 0; } -static int roq_encode_video(RoqContext *enc) +static int roq_encode_video(RoqEncContext *enc) { - RoqTempdata *tempData = enc->tmpData; - int i, ret; + RoqTempData *const tempData = &enc->tmp_data; + RoqContext *const roq = &enc->common; + int ret; memset(tempData, 0, sizeof(*tempData)); - ret = create_cel_evals(enc, tempData); - if (ret < 0) - return ret; - - ret = generate_new_codebooks(enc, tempData); + ret = generate_new_codebooks(enc); if (ret < 0) return ret; @@ -914,16 +909,16 @@ static int roq_encode_video(RoqContext *enc) } retry_encode: - for (i=0; iwidth*enc->height/64; i++) - gather_data_for_cel(tempData->cel_evals + i, enc, tempData); + for (int i = 0; i < roq->width * roq->height / 64; i++) + gather_data_for_cel(enc->cel_evals + i, enc); /* Quake 3 can't handle chunks bigger than 65535 bytes */ if (tempData->mainChunkSize/8 > 65535 && enc->quake3_compat) { if (enc->lambda > 100000) { - av_log(enc->avctx, AV_LOG_ERROR, "Cannot encode video in Quake compatible form\n"); + av_log(roq->avctx, AV_LOG_ERROR, "Cannot encode video in Quake compatible form\n"); return AVERROR(EINVAL); } - av_log(enc->avctx, AV_LOG_ERROR, + av_log(roq->avctx, AV_LOG_ERROR, "Warning, generated a frame too big for Quake (%d > 65535), " "now switching to a bigger qscale value.\n", tempData->mainChunkSize/8); @@ -938,21 +933,18 @@ static int roq_encode_video(RoqContext *enc) goto retry_encode; } - remap_codebooks(enc, tempData); + remap_codebooks(enc); - write_codebooks(enc, tempData); + write_codebooks(enc); - reconstruct_and_encode_image(enc, tempData, enc->width, enc->height, - enc->width*enc->height/64); + reconstruct_and_encode_image(enc, roq->width, roq->height, + roq->width * roq->height / 64); /* Rotate frame history */ - FFSWAP(AVFrame *, enc->current_frame, enc->last_frame); + FFSWAP(AVFrame *, roq->current_frame, roq->last_frame); FFSWAP(motion_vect *, enc->last_motion4, enc->this_motion4); FFSWAP(motion_vect *, enc->last_motion8, enc->this_motion8); - av_freep(&tempData->cel_evals); - av_freep(&tempData->closest_cb2); - enc->framesSinceKeyframe++; return 0; @@ -960,12 +952,13 @@ static int roq_encode_video(RoqContext *enc) static av_cold int roq_encode_end(AVCodecContext *avctx) { - RoqContext *enc = avctx->priv_data; + RoqEncContext *const enc = avctx->priv_data; - av_frame_free(&enc->current_frame); - av_frame_free(&enc->last_frame); + av_frame_free(&enc->common.current_frame); + av_frame_free(&enc->common.last_frame); - av_freep(&enc->tmpData); + av_freep(&enc->cel_evals); + av_freep(&enc->closest_cb); av_freep(&enc->this_motion4); av_freep(&enc->last_motion4); av_freep(&enc->this_motion8); @@ -976,11 +969,12 @@ static av_cold int roq_encode_end(AVCodecContext *avctx) static av_cold int roq_encode_init(AVCodecContext *avctx) { - RoqContext *enc = avctx->priv_data; + RoqEncContext *const enc = avctx->priv_data; + RoqContext *const roq = &enc->common; av_lfg_init(&enc->randctx, 1); - enc->avctx = avctx; + roq->avctx = avctx; enc->framesSinceKeyframe = 0; if ((avctx->width & 0xf) || (avctx->height & 0xf)) { @@ -996,43 +990,44 @@ static av_cold int roq_encode_init(AVCodecContext *avctx) if (((avctx->width)&(avctx->width-1))||((avctx->height)&(avctx->height-1))) av_log(avctx, AV_LOG_ERROR, "Warning: dimensions not power of two, this is not supported by quake\n"); - enc->width = avctx->width; - enc->height = avctx->height; + roq->width = avctx->width; + roq->height = avctx->height; enc->framesSinceKeyframe = 0; enc->first_frame = 1; - enc->last_frame = av_frame_alloc(); - enc->current_frame = av_frame_alloc(); - if (!enc->last_frame || !enc->current_frame) { - roq_encode_end(avctx); + roq->last_frame = av_frame_alloc(); + roq->current_frame = av_frame_alloc(); + if (!roq->last_frame || !roq->current_frame) return AVERROR(ENOMEM); - } - - enc->tmpData = av_malloc(sizeof(RoqTempdata)); enc->this_motion4 = - av_mallocz_array((enc->width*enc->height/16), sizeof(motion_vect)); + av_mallocz_array(roq->width * roq->height / 16, sizeof(motion_vect)); enc->last_motion4 = - av_malloc_array ((enc->width*enc->height/16), sizeof(motion_vect)); + av_malloc_array (roq->width * roq->height / 16, sizeof(motion_vect)); enc->this_motion8 = - av_mallocz_array((enc->width*enc->height/64), sizeof(motion_vect)); + av_mallocz_array(roq->width * roq->height / 64, sizeof(motion_vect)); enc->last_motion8 = - av_malloc_array ((enc->width*enc->height/64), sizeof(motion_vect)); + av_malloc_array (roq->width * roq->height / 64, sizeof(motion_vect)); - if (!enc->tmpData || !enc->this_motion4 || !enc->last_motion4 || - !enc->this_motion8 || !enc->last_motion8) { - roq_encode_end(avctx); + /* 4x4 codebook needs 6 * 4 * 4 / 4 * width * height / 16 * sizeof(int); + * and so does the points buffer. */ + enc->closest_cb = + av_malloc_array(roq->width * roq->height, 3 * sizeof(int)); + + if (!enc->this_motion4 || !enc->last_motion4 || + !enc->this_motion8 || !enc->last_motion8 || !enc->closest_cb) return AVERROR(ENOMEM); - } - return 0; + enc->points = enc->closest_cb + roq->width * roq->height * 3 / 2; + + return create_cel_evals(enc); } -static void roq_write_video_info_chunk(RoqContext *enc) +static void roq_write_video_info_chunk(RoqEncContext *enc) { /* ROQ info chunk */ bytestream_put_le16(&enc->out_buf, RoQ_INFO); @@ -1045,10 +1040,10 @@ static void roq_write_video_info_chunk(RoqContext *enc) bytestream_put_byte(&enc->out_buf, 0x00); /* Width */ - bytestream_put_le16(&enc->out_buf, enc->width); + bytestream_put_le16(&enc->out_buf, enc->common.width); /* Height */ - bytestream_put_le16(&enc->out_buf, enc->height); + bytestream_put_le16(&enc->out_buf, enc->common.height); /* Unused in Quake 3, mimics the output of the real encoder */ bytestream_put_byte(&enc->out_buf, 0x08); @@ -1060,10 +1055,11 @@ static void roq_write_video_info_chunk(RoqContext *enc) static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { - RoqContext *enc = avctx->priv_data; + RoqEncContext *const enc = avctx->priv_data; + RoqContext *const roq = &enc->common; int size, ret; - enc->avctx = avctx; + roq->avctx = avctx; enc->frame_to_enc = frame; @@ -1074,7 +1070,7 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, /* 138 bits max per 8x8 block + * 256 codebooks*(6 bytes 2x2 + 4 bytes 4x4) + 8 bytes frame header */ - size = ((enc->width * enc->height / 64) * 138 + 7) / 8 + 256 * (6 + 4) + 8; + size = ((roq->width * roq->height / 64) * 138 + 7) / 8 + 256 * (6 + 4) + 8; if ((ret = ff_alloc_packet2(avctx, pkt, size, 0)) < 0) return ret; enc->out_buf = pkt->data; @@ -1086,8 +1082,8 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if (enc->first_frame) { /* Alloc memory for the reconstruction data (we must know the stride for that) */ - if ((ret = ff_get_buffer(avctx, enc->current_frame, 0)) < 0 || - (ret = ff_get_buffer(avctx, enc->last_frame, 0)) < 0) + if ((ret = ff_get_buffer(avctx, roq->current_frame, 0)) < 0 || + (ret = ff_get_buffer(avctx, roq->last_frame, 0)) < 0) return ret; /* Before the first video frame, write a "video info" chunk */ @@ -1109,7 +1105,7 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -#define OFFSET(x) offsetof(RoqContext, x) +#define OFFSET(x) offsetof(RoqEncContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { { "quake3_compat", "Whether to respect known limitations in Quake 3 decoder", OFFSET(quake3_compat), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, @@ -1128,11 +1124,12 @@ AVCodec ff_roq_encoder = { .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ROQ, - .priv_data_size = sizeof(RoqContext), + .priv_data_size = sizeof(RoqEncContext), .init = roq_encode_init, .encode2 = roq_encode_frame, .close = roq_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE }, .priv_class = &roq_class, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/rpzaenc.c b/libavcodec/rpzaenc.c new file mode 100644 index 000000000..baf067c20 --- /dev/null +++ b/libavcodec/rpzaenc.c @@ -0,0 +1,858 @@ +/* + * QuickTime RPZA Video Encoder + * + * 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 rpzaenc.c + * QT RPZA Video Encoder by Todd Kirby and David Adler + */ + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/opt.h" + +#include "avcodec.h" +#include "internal.h" +#include "put_bits.h" + +typedef struct RpzaContext { + AVClass *avclass; + + int skip_frame_thresh; + int start_one_color_thresh; + int continue_one_color_thresh; + int sixteen_color_thresh; + + AVFrame *prev_frame; // buffer for previous source frame + PutBitContext pb; // buffer for encoded frame data. + + int frame_width; // width in pixels of source frame + int frame_height; // height in pixesl of source frame + + int first_frame; // flag set to one when the first frame is being processed + // so that comparisons with previous frame data in not attempted +} RpzaContext; + +typedef enum channel_offset { + RED = 2, + GREEN = 1, + BLUE = 0, +} channel_offset; + +typedef struct rgb { + uint8_t r; + uint8_t g; + uint8_t b; +} rgb; + +#define SQR(x) ((x) * (x)) + +/* 15 bit components */ +#define GET_CHAN(color, chan) (((color) >> ((chan) * 5) & 0x1F) * 8) +#define R(color) GET_CHAN(color, RED) +#define G(color) GET_CHAN(color, GREEN) +#define B(color) GET_CHAN(color, BLUE) + +typedef struct BlockInfo { + int row; + int col; + int block_width; + int block_height; + int image_width; + int image_height; + int block_index; + uint16_t start; + int rowstride; + int blocks_per_row; + int total_blocks; +} BlockInfo; + +static void get_colors(uint8_t *min, uint8_t *max, uint8_t color4[4][3]) +{ + uint8_t step; + + color4[0][0] = min[0]; + color4[0][1] = min[1]; + color4[0][2] = min[2]; + + color4[3][0] = max[0]; + color4[3][1] = max[1]; + color4[3][2] = max[2]; + + // red components + step = (color4[3][0] - color4[0][0] + 1) / 3; + color4[1][0] = color4[0][0] + step; + color4[2][0] = color4[3][0] - step; + + // green components + step = (color4[3][1] - color4[0][1] + 1) / 3; + color4[1][1] = color4[0][1] + step; + color4[2][1] = color4[3][1] - step; + + // blue components + step = (color4[3][2] - color4[0][2] + 1) / 3; + color4[1][2] = color4[0][2] + step; + color4[2][2] = color4[3][2] - step; +} + +/* Fill BlockInfo struct with information about a 4x4 block of the image */ +static int get_block_info(BlockInfo *bi, int block) +{ + bi->row = block / bi->blocks_per_row; + bi->col = block % bi->blocks_per_row; + + // test for right edge block + if (bi->col == bi->blocks_per_row - 1 && (bi->image_width % 4) != 0) { + bi->block_width = bi->image_width % 4; + } else { + bi->block_width = 4; + } + + // test for bottom edge block + if (bi->row == (bi->image_height / 4) && (bi->image_height % 4) != 0) { + bi->block_height = bi->image_height % 4; + } else { + bi->block_height = 4; + } + + return block ? (bi->col * 4) + (bi->row * bi->rowstride * 4) : 0; +} + +static uint16_t rgb24_to_rgb555(uint8_t *rgb24) +{ + uint16_t rgb555 = 0; + uint32_t r, g, b; + + r = rgb24[0] >> 3; + g = rgb24[1] >> 3; + b = rgb24[2] >> 3; + + rgb555 |= (r << 10); + rgb555 |= (g << 5); + rgb555 |= (b << 0); + + return rgb555; +} + +/* + * Returns the total difference between two 24 bit color values + */ +static int diff_colors(uint8_t *colorA, uint8_t *colorB) +{ + int tot; + + tot = SQR(colorA[0] - colorB[0]); + tot += SQR(colorA[1] - colorB[1]); + tot += SQR(colorA[2] - colorB[2]); + + return tot; +} + +/* + * Returns the maximum channel difference + */ +static int max_component_diff(uint16_t *colorA, uint16_t *colorB) +{ + int diff, max = 0; + + diff = FFABS(R(colorA[0]) - R(colorB[0])); + if (diff > max) { + max = diff; + } + diff = FFABS(G(colorA[0]) - G(colorB[0])); + if (diff > max) { + max = diff; + } + diff = FFABS(B(colorA[0]) - B(colorB[0])); + if (diff > max) { + max = diff; + } + return max * 8; +} + +/* + * Find the channel that has the largest difference between minimum and maximum + * color values. Put the minimum value in min, maximum in max and the channel + * in chan. + */ +static void get_max_component_diff(BlockInfo *bi, uint16_t *block_ptr, + uint8_t *min, uint8_t *max, channel_offset *chan) +{ + int x, y; + uint8_t min_r, max_r, min_g, max_g, min_b, max_b; + uint8_t r, g, b; + + // fix warning about uninitialized vars + min_r = min_g = min_b = UINT8_MAX; + max_r = max_g = max_b = 0; + + // loop thru and compare pixels + for (y = 0; y < bi->block_height; y++) { + for (x = 0; x < bi->block_width; x++){ + // TODO: optimize + min_r = FFMIN(R(block_ptr[x]), min_r); + min_g = FFMIN(G(block_ptr[x]), min_g); + min_b = FFMIN(B(block_ptr[x]), min_b); + + max_r = FFMAX(R(block_ptr[x]), max_r); + max_g = FFMAX(G(block_ptr[x]), max_g); + max_b = FFMAX(B(block_ptr[x]), max_b); + } + block_ptr += bi->rowstride; + } + + r = max_r - min_r; + g = max_g - min_g; + b = max_b - min_b; + + if (r > g && r > b) { + *max = max_r; + *min = min_r; + *chan = RED; + } else if (g > b && g >= r) { + *max = max_g; + *min = min_g; + *chan = GREEN; + } else { + *max = max_b; + *min = min_b; + *chan = BLUE; + } +} + +/* + * Compare two 4x4 blocks to determine if the total difference between the + * blocks is greater than the thresh parameter. Returns -1 if difference + * exceeds threshold or zero otherwise. + */ +static int compare_blocks(uint16_t *block1, uint16_t *block2, BlockInfo *bi, int thresh) +{ + int x, y, diff = 0; + for (y = 0; y < bi->block_height; y++) { + for (x = 0; x < bi->block_width; x++) { + diff = max_component_diff(&block1[x], &block2[x]); + if (diff >= thresh) { + return -1; + } + } + block1 += bi->rowstride; + block2 += bi->rowstride; + } + return 0; +} + +/* + * Determine the fit of one channel to another within a 4x4 block. This + * is used to determine the best palette choices for 4-color encoding. + */ +static int leastsquares(uint16_t *block_ptr, BlockInfo *bi, + channel_offset xchannel, channel_offset ychannel, + double *slope, double *y_intercept, double *correlation_coef) +{ + double sumx = 0, sumy = 0, sumx2 = 0, sumy2 = 0, sumxy = 0, + sumx_sq = 0, sumy_sq = 0, tmp, tmp2; + int i, j, count; + uint8_t x, y; + + count = bi->block_height * bi->block_width; + + if (count < 2) + return -1; + + for (i = 0; i < bi->block_height; i++) { + for (j = 0; j < bi->block_width; j++){ + x = GET_CHAN(block_ptr[j], xchannel); + y = GET_CHAN(block_ptr[j], ychannel); + sumx += x; + sumy += y; + sumx2 += x * x; + sumy2 += y * y; + sumxy += x * y; + } + block_ptr += bi->rowstride; + } + + sumx_sq = sumx * sumx; + tmp = (count * sumx2 - sumx_sq); + + // guard against div/0 + if (tmp == 0) + return -2; + + sumy_sq = sumy * sumy; + + *slope = (sumx * sumy - sumxy) / tmp; + *y_intercept = (sumy - (*slope) * sumx) / count; + + tmp2 = count * sumy2 - sumy_sq; + if (tmp2 == 0) { + *correlation_coef = 0.0; + } else { + *correlation_coef = (count * sumxy - sumx * sumy) / + sqrt(tmp * tmp2); + } + + return 0; // success +} + +/* + * Determine the amount of error in the leastsquares fit. + */ +static int calc_lsq_max_fit_error(uint16_t *block_ptr, BlockInfo *bi, + int min, int max, int tmp_min, int tmp_max, + channel_offset xchannel, channel_offset ychannel) +{ + int i, j, x, y; + int err; + int max_err = 0; + + for (i = 0; i < bi->block_height; i++) { + for (j = 0; j < bi->block_width; j++){ + int x_inc, lin_y, lin_x; + x = GET_CHAN(block_ptr[j], xchannel); + y = GET_CHAN(block_ptr[j], ychannel); + + /* calculate x_inc as the 4-color index (0..3) */ + x_inc = floor( (x - min) * 3.0 / (max - min) + 0.5); + x_inc = FFMAX(FFMIN(3, x_inc), 0); + + /* calculate lin_y corresponding to x_inc */ + lin_y = (int)(tmp_min + (tmp_max - tmp_min) * x_inc / 3.0 + 0.5); + + err = FFABS(lin_y - y); + if (err > max_err) + max_err = err; + + /* calculate lin_x corresponding to x_inc */ + lin_x = (int)(min + (max - min) * x_inc / 3.0 + 0.5); + + err = FFABS(lin_x - x); + if (err > max_err) + max_err += err; + } + block_ptr += bi->rowstride; + } + + return max_err; +} + +/* + * Find the closest match to a color within the 4-color palette + */ +static int match_color(uint16_t *color, uint8_t colors[4][3]) +{ + int ret = 0; + int smallest_variance = INT_MAX; + uint8_t dithered_color[3]; + + for (int channel = 0; channel < 3; channel++) { + dithered_color[channel] = GET_CHAN(color[0], channel); + } + + for (int palette_entry = 0; palette_entry < 4; palette_entry++) { + int variance = diff_colors(dithered_color, colors[palette_entry]); + + if (variance < smallest_variance) { + smallest_variance = variance; + ret = palette_entry; + } + } + + return ret; +} + +/* + * Encode a block using the 4-color opcode and palette. return number of + * blocks encoded (until we implement multi-block 4 color runs this will + * always be 1) + */ +static int encode_four_color_block(uint8_t *min_color, uint8_t *max_color, + PutBitContext *pb, uint16_t *block_ptr, BlockInfo *bi) +{ + int x, y, idx; + uint8_t color4[4][3]; + uint16_t rounded_max, rounded_min; + + // round min and max wider + rounded_min = rgb24_to_rgb555(min_color); + rounded_max = rgb24_to_rgb555(max_color); + + // put a and b colors + // encode 4 colors = first 16 bit color with MSB zeroed and... + put_bits(pb, 16, rounded_max & ~0x8000); + // ...second 16 bit color with MSB on. + put_bits(pb, 16, rounded_min | 0x8000); + + get_colors(min_color, max_color, color4); + + for (y = 0; y < 4; y++) { + for (x = 0; x < 4; x++) { + idx = match_color(&block_ptr[x], color4); + put_bits(pb, 2, idx); + } + block_ptr += bi->rowstride; + } + return 1; // num blocks encoded +} + +/* + * Copy a 4x4 block from the current frame buffer to the previous frame buffer. + */ +static void update_block_in_prev_frame(const uint16_t *src_pixels, + uint16_t *dest_pixels, + const BlockInfo *bi, int block_counter) +{ + for (int y = 0; y < 4; y++) { + memcpy(dest_pixels, src_pixels, 8); + dest_pixels += bi->rowstride; + src_pixels += bi->rowstride; + } +} + +/* + * update statistics for the specified block. If first_block, + * it initializes the statistics. Otherwise it updates the statistics IF THIS + * BLOCK IS SUITABLE TO CONTINUE A 1-COLOR RUN. That is, it checks whether + * the range of colors (since the routine was called first_block != 0) are + * all close enough intensities to be represented by a single color. + + * The routine returns 0 if this block is too different to be part of + * the same run of 1-color blocks. The routine returns 1 if this + * block can be part of the same 1-color block run. + + * If the routine returns 1, it also updates its arguments to include + * the statistics of this block. Otherwise, the stats are unchanged + * and don't include the current block. + */ +static int update_block_stats(RpzaContext *s, BlockInfo *bi, uint16_t *block, + uint8_t min_color[3], uint8_t max_color[3], + int *total_rgb, int *total_pixels, + uint8_t avg_color[3], int first_block) +{ + int x, y; + int is_in_range; + int total_pixels_blk; + int threshold; + + uint8_t min_color_blk[3], max_color_blk[3]; + int total_rgb_blk[3]; + uint8_t avg_color_blk[3]; + + if (first_block) { + min_color[0] = UINT8_MAX; + min_color[1] = UINT8_MAX; + min_color[2] = UINT8_MAX; + max_color[0] = 0; + max_color[1] = 0; + max_color[2] = 0; + total_rgb[0] = 0; + total_rgb[1] = 0; + total_rgb[2] = 0; + *total_pixels = 0; + threshold = s->start_one_color_thresh; + } else { + threshold = s->continue_one_color_thresh; + } + + /* + The *_blk variables will include the current block. + Initialize them based on the blocks so far. + */ + min_color_blk[0] = min_color[0]; + min_color_blk[1] = min_color[1]; + min_color_blk[2] = min_color[2]; + max_color_blk[0] = max_color[0]; + max_color_blk[1] = max_color[1]; + max_color_blk[2] = max_color[2]; + total_rgb_blk[0] = total_rgb[0]; + total_rgb_blk[1] = total_rgb[1]; + total_rgb_blk[2] = total_rgb[2]; + total_pixels_blk = *total_pixels + bi->block_height * bi->block_width; + + /* + Update stats for this block's pixels + */ + for (y = 0; y < bi->block_height; y++) { + for (x = 0; x < bi->block_width; x++) { + total_rgb_blk[0] += R(block[x]); + total_rgb_blk[1] += G(block[x]); + total_rgb_blk[2] += B(block[x]); + + min_color_blk[0] = FFMIN(R(block[x]), min_color_blk[0]); + min_color_blk[1] = FFMIN(G(block[x]), min_color_blk[1]); + min_color_blk[2] = FFMIN(B(block[x]), min_color_blk[2]); + + max_color_blk[0] = FFMAX(R(block[x]), max_color_blk[0]); + max_color_blk[1] = FFMAX(G(block[x]), max_color_blk[1]); + max_color_blk[2] = FFMAX(B(block[x]), max_color_blk[2]); + } + block += bi->rowstride; + } + + /* + Calculate average color including current block. + */ + avg_color_blk[0] = total_rgb_blk[0] / total_pixels_blk; + avg_color_blk[1] = total_rgb_blk[1] / total_pixels_blk; + avg_color_blk[2] = total_rgb_blk[2] / total_pixels_blk; + + /* + Are all the pixels within threshold of the average color? + */ + is_in_range = (max_color_blk[0] - avg_color_blk[0] <= threshold && + max_color_blk[1] - avg_color_blk[1] <= threshold && + max_color_blk[2] - avg_color_blk[2] <= threshold && + avg_color_blk[0] - min_color_blk[0] <= threshold && + avg_color_blk[1] - min_color_blk[1] <= threshold && + avg_color_blk[2] - min_color_blk[2] <= threshold); + + if (is_in_range) { + /* + Set the output variables to include this block. + */ + min_color[0] = min_color_blk[0]; + min_color[1] = min_color_blk[1]; + min_color[2] = min_color_blk[2]; + max_color[0] = max_color_blk[0]; + max_color[1] = max_color_blk[1]; + max_color[2] = max_color_blk[2]; + total_rgb[0] = total_rgb_blk[0]; + total_rgb[1] = total_rgb_blk[1]; + total_rgb[2] = total_rgb_blk[2]; + *total_pixels = total_pixels_blk; + avg_color[0] = avg_color_blk[0]; + avg_color[1] = avg_color_blk[1]; + avg_color[2] = avg_color_blk[2]; + } + + return is_in_range; +} + +static void rpza_encode_stream(RpzaContext *s, const AVFrame *pict) +{ + BlockInfo bi; + int block_counter = 0; + int n_blocks; + int total_blocks; + int prev_block_offset; + int block_offset = 0; + uint8_t min = 0, max = 0; + channel_offset chan; + int i; + int tmp_min, tmp_max; + int total_rgb[3]; + uint8_t avg_color[3]; + int pixel_count; + uint8_t min_color[3], max_color[3]; + double slope, y_intercept, correlation_coef; + uint16_t *src_pixels = (uint16_t *)pict->data[0]; + uint16_t *prev_pixels = (uint16_t *)s->prev_frame->data[0]; + + /* Number of 4x4 blocks in frame. */ + total_blocks = ((s->frame_width + 3) / 4) * ((s->frame_height + 3) / 4); + + bi.image_width = s->frame_width; + bi.image_height = s->frame_height; + bi.rowstride = pict->linesize[0] / 2; + + bi.blocks_per_row = (s->frame_width + 3) / 4; + + while (block_counter < total_blocks) { + // SKIP CHECK + // make sure we have a valid previous frame and we're not writing + // a key frame + if (!s->first_frame) { + n_blocks = 0; + prev_block_offset = 0; + + while (n_blocks < 32 && block_counter + n_blocks < total_blocks) { + + block_offset = get_block_info(&bi, block_counter + n_blocks); + + // multi-block opcodes cannot span multiple rows. + // If we're starting a new row, break out and write the opcode + /* TODO: Should eventually use bi.row here to determine when a + row break occurs, but that is currently breaking the + quicktime player. This is probably due to a bug in the + way I'm calculating the current row. + */ + if (prev_block_offset && block_offset - prev_block_offset > 12) { + break; + } + + prev_block_offset = block_offset; + + if (compare_blocks(&prev_pixels[block_offset], + &src_pixels[block_offset], &bi, s->skip_frame_thresh) != 0) { + // write out skipable blocks + if (n_blocks) { + + // write skip opcode + put_bits(&s->pb, 8, 0x80 | (n_blocks - 1)); + block_counter += n_blocks; + + goto post_skip; + } + break; + } + + /* + * NOTE: we don't update skipped blocks in the previous frame buffer + * since skipped needs always to be compared against the first skipped + * block to avoid artifacts during gradual fade in/outs. + */ + + // update_block_in_prev_frame(&src_pixels[block_offset], + // &prev_pixels[block_offset], &bi, block_counter + n_blocks); + + n_blocks++; + } + + // we're either at the end of the frame or we've reached the maximum + // of 32 blocks in a run. Write out the run. + if (n_blocks) { + // write skip opcode + put_bits(&s->pb, 8, 0x80 | (n_blocks - 1)); + block_counter += n_blocks; + + continue; + } + + } else { + block_offset = get_block_info(&bi, block_counter); + } +post_skip : + + // ONE COLOR CHECK + if (update_block_stats(s, &bi, &src_pixels[block_offset], + min_color, max_color, + total_rgb, &pixel_count, avg_color, 1)) { + prev_block_offset = block_offset; + + n_blocks = 1; + + /* update this block in the previous frame buffer */ + update_block_in_prev_frame(&src_pixels[block_offset], + &prev_pixels[block_offset], &bi, block_counter + n_blocks); + + // check for subsequent blocks with the same color + while (n_blocks < 32 && block_counter + n_blocks < total_blocks) { + block_offset = get_block_info(&bi, block_counter + n_blocks); + + // multi-block opcodes cannot span multiple rows. + // If we've hit end of a row, break out and write the opcode + if (block_offset - prev_block_offset > 12) { + break; + } + + if (!update_block_stats(s, &bi, &src_pixels[block_offset], + min_color, max_color, + total_rgb, &pixel_count, avg_color, 0)) { + break; + } + + prev_block_offset = block_offset; + + /* update this block in the previous frame buffer */ + update_block_in_prev_frame(&src_pixels[block_offset], + &prev_pixels[block_offset], &bi, block_counter + n_blocks); + + n_blocks++; + } + + // write one color opcode. + put_bits(&s->pb, 8, 0xa0 | (n_blocks - 1)); + // write color to encode. + put_bits(&s->pb, 16, rgb24_to_rgb555(avg_color)); + // skip past the blocks we've just encoded. + block_counter += n_blocks; + } else { // FOUR COLOR CHECK + int err = 0; + + // get max component diff for block + get_max_component_diff(&bi, &src_pixels[block_offset], &min, &max, &chan); + + min_color[0] = 0; + max_color[0] = 0; + min_color[1] = 0; + max_color[1] = 0; + min_color[2] = 0; + max_color[2] = 0; + + // run least squares against other two components + for (i = 0; i < 3; i++) { + if (i == chan) { + min_color[i] = min; + max_color[i] = max; + continue; + } + + slope = y_intercept = correlation_coef = 0; + + if (leastsquares(&src_pixels[block_offset], &bi, chan, i, + &slope, &y_intercept, &correlation_coef)) { + min_color[i] = GET_CHAN(src_pixels[block_offset], i); + max_color[i] = GET_CHAN(src_pixels[block_offset], i); + } else { + tmp_min = (int)(0.5 + min * slope + y_intercept); + tmp_max = (int)(0.5 + max * slope + y_intercept); + + av_assert0(tmp_min <= tmp_max); + // clamp min and max color values + tmp_min = av_clip_uint8(tmp_min); + tmp_max = av_clip_uint8(tmp_max); + + err = FFMAX(calc_lsq_max_fit_error(&src_pixels[block_offset], &bi, + min, max, tmp_min, tmp_max, chan, i), err); + + min_color[i] = tmp_min; + max_color[i] = tmp_max; + } + } + + if (err > s->sixteen_color_thresh) { // DO SIXTEEN COLOR BLOCK + uint16_t *row_ptr; + int rgb555; + + block_offset = get_block_info(&bi, block_counter); + + row_ptr = &src_pixels[block_offset]; + + for (int y = 0; y < 4; y++) { + for (int x = 0; x < 4; x++){ + rgb555 = row_ptr[x] & ~0x8000; + + put_bits(&s->pb, 16, rgb555); + } + row_ptr += bi.rowstride; + } + + block_counter++; + } else { // FOUR COLOR BLOCK + block_counter += encode_four_color_block(min_color, max_color, + &s->pb, &src_pixels[block_offset], &bi); + } + + /* update this block in the previous frame buffer */ + update_block_in_prev_frame(&src_pixels[block_offset], + &prev_pixels[block_offset], &bi, block_counter); + } + } +} + +static int rpza_encode_init(AVCodecContext *avctx) +{ + RpzaContext *s = avctx->priv_data; + + s->frame_width = avctx->width; + s->frame_height = avctx->height; + + s->prev_frame = av_frame_alloc(); + if (!s->prev_frame) + return AVERROR(ENOMEM); + + return 0; +} + +static int rpza_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *frame, int *got_packet) +{ + RpzaContext *s = avctx->priv_data; + const AVFrame *pict = frame; + uint8_t *buf; + int ret; + + if ((ret = ff_alloc_packet2(avctx, pkt, 6LL * avctx->height * avctx->width, 0)) < 0) + return ret; + + init_put_bits(&s->pb, pkt->data, pkt->size); + + // skip 4 byte header, write it later once the size of the chunk is known + put_bits32(&s->pb, 0x00); + + if (!s->prev_frame->data[0]) { + s->first_frame = 1; + s->prev_frame->format = pict->format; + s->prev_frame->width = pict->width; + s->prev_frame->height = pict->height; + ret = av_frame_get_buffer(s->prev_frame, 0); + if (ret < 0) + return ret; + } else { + s->first_frame = 0; + } + + rpza_encode_stream(s, pict); + + flush_put_bits(&s->pb); + + av_shrink_packet(pkt, put_bits_count(&s->pb) >> 3); + buf = pkt->data; + + // write header opcode + buf[0] = 0xe1; // chunk opcode + + // write chunk length + AV_WB24(buf + 1, pkt->size); + + *got_packet = 1; + + return 0; +} + +static int rpza_encode_end(AVCodecContext *avctx) +{ + RpzaContext *s = (RpzaContext *)avctx->priv_data; + + av_frame_free(&s->prev_frame); + + return 0; +} + +#define OFFSET(x) offsetof(RpzaContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "skip_frame_thresh", NULL, OFFSET(skip_frame_thresh), AV_OPT_TYPE_INT, {.i64=1}, 0, 24, VE}, + { "start_one_color_thresh", NULL, OFFSET(start_one_color_thresh), AV_OPT_TYPE_INT, {.i64=1}, 0, 24, VE}, + { "continue_one_color_thresh", NULL, OFFSET(continue_one_color_thresh), AV_OPT_TYPE_INT, {.i64=0}, 0, 24, VE}, + { "sixteen_color_thresh", NULL, OFFSET(sixteen_color_thresh), AV_OPT_TYPE_INT, {.i64=1}, 0, 24, VE}, + { NULL }, +}; + +static const AVClass rpza_class = { + .class_name = "rpza", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_rpza_encoder = { + .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), + .priv_class = &rpza_class, + .init = rpza_encode_init, + .encode2 = rpza_encode_frame, + .close = rpza_encode_end, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB555, + AV_PIX_FMT_NONE}, +}; diff --git a/libavcodec/rscc.c b/libavcodec/rscc.c index 07a7c3dca..79b02da44 100644 --- a/libavcodec/rscc.c +++ b/libavcodec/rscc.c @@ -346,7 +346,7 @@ static int rscc_decode_frame(AVCodecContext *avctx, void *data, /* Palette handling */ if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { - int size; + buffer_size_t size; const uint8_t *palette = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); diff --git a/libavcodec/rtjpeg.h b/libavcodec/rtjpeg.h index d22ff4070..d4dc07440 100644 --- a/libavcodec/rtjpeg.h +++ b/libavcodec/rtjpeg.h @@ -24,7 +24,7 @@ #include -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "idctdsp.h" #define RTJPEG_FILE_VERSION 0 diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index 3b41d30b9..bd70689ca 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -28,6 +28,7 @@ #include #include "libavutil/imgutils.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "error_resilience.h" @@ -45,7 +46,8 @@ #define RV_GET_MINOR_VER(x) (((x) >> 20) & 0xFF) #define RV_GET_MICRO_VER(x) (((x) >> 12) & 0xFF) -#define DC_VLC_BITS 14 // FIXME find a better solution +#define MAX_VLC_ENTRIES 1023 // Note: Does not include the skip entries. +#define DC_VLC_BITS 9 typedef struct RVDecContext { MpegEncContext m; @@ -53,144 +55,25 @@ typedef struct RVDecContext { int orig_width, orig_height; } 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, +/* (run, length) encoded value for the symbols table. The actual symbols + * are run..run - length (mod 256). + * The last two entries in the following table apply to luma only. + * The skip values are not included in this list. */ +static const uint8_t rv_sym_run_len[][2] = { + { 0, 0 }, { 1, 0 }, { 255, 0 }, { 3, 1 }, { 254, 1 }, + { 7, 3 }, { 252, 3 }, { 15, 7 }, { 248, 7 }, { 31, 15 }, + { 240, 15 }, { 63, 31 }, { 224, 31 }, { 127, 63 }, { 192, 63 }, + { 255, 127 }, { 128, 127 }, { 127, 255 }, { 128, 255 }, }; -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, +/* entry[i] of the following tables gives + * the number of VLC codes of length i + 2. */ +static const uint16_t rv_lum_len_count[15] = { + 1, 0, 2, 4, 8, 16, 32, 0, 64, 0, 128, 0, 256, 0, 512, }; -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 uint16_t rv_chrom_len_count[15] = { + 1, 2, 4, 0, 8, 0, 16, 0, 32, 0, 64, 0, 128, 0, 256, }; static VLC rv_dc_lum, rv_dc_chrom; @@ -201,48 +84,14 @@ int ff_rv_decode_dc(MpegEncContext *s, int n) if (n < 4) { code = get_vlc2(&s->gb, rv_dc_lum.table, DC_VLC_BITS, 2); - if (code < 0) { - /* XXX: I don't understand why they use LONGER codes than - * necessary. The following code would be completely useless - * if they had thought about it !!! */ - code = get_bits(&s->gb, 7); - if (code == 0x7c) { - code = (int8_t) (get_bits(&s->gb, 7) + 1); - } else if (code == 0x7d) { - code = -128 + get_bits(&s->gb, 7); - } else if (code == 0x7e) { - if (get_bits1(&s->gb) == 0) - code = (int8_t) (get_bits(&s->gb, 8) + 1); - else - code = (int8_t) (get_bits(&s->gb, 8)); - } else if (code == 0x7f) { - skip_bits(&s->gb, 11); - code = 1; - } - } else { - code -= 128; - } } else { code = get_vlc2(&s->gb, rv_dc_chrom.table, DC_VLC_BITS, 2); - /* same remark */ if (code < 0) { - code = get_bits(&s->gb, 9); - if (code == 0x1fc) { - code = (int8_t) (get_bits(&s->gb, 7) + 1); - } else if (code == 0x1fd) { - code = -128 + get_bits(&s->gb, 7); - } else if (code == 0x1fe) { - skip_bits(&s->gb, 9); - code = 1; - } else { - av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n"); - return 0xffff; - } - } else { - code -= 128; + av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n"); + return -1; } } - return -code; + return code; } /* read RV 1.0 compatible frame header */ @@ -377,7 +226,7 @@ static int rv20_decode_picture_header(RVDecContext *rv) new_w = rv->orig_width; new_h = rv->orig_height; } - if (new_w != s->width || new_h != s->height) { + if (new_w != s->width || new_h != s->height || !s->context_initialized) { 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); @@ -463,11 +312,58 @@ static int rv20_decode_picture_header(RVDecContext *rv) return s->mb_width * s->mb_height - mb_pos; } +static av_cold void rv10_build_vlc(VLC *vlc, const uint16_t len_count[15], + const uint8_t sym_rl[][2], int sym_rl_elems) +{ + uint16_t syms[MAX_VLC_ENTRIES]; + uint8_t lens[MAX_VLC_ENTRIES]; + unsigned nb_syms = 0, nb_lens = 0; + + for (unsigned i = 0; i < sym_rl_elems; i++) { + unsigned cur_sym = sym_rl[i][0]; + for (unsigned tmp = nb_syms + sym_rl[i][1]; nb_syms <= tmp; nb_syms++) + syms[nb_syms] = 0xFF & cur_sym--; + } + + for (unsigned i = 0; i < 15; i++) + for (unsigned tmp = nb_lens + len_count[i]; nb_lens < tmp; nb_lens++) + lens[nb_lens] = i + 2; + av_assert1(nb_lens == nb_syms); + ff_init_vlc_from_lengths(vlc, DC_VLC_BITS, nb_lens, lens, 1, + syms, 2, 2, 0, INIT_VLC_STATIC_OVERLONG, NULL); +} + +static av_cold void rv10_init_static(void) +{ + static VLC_TYPE table[1472 + 992][2]; + + rv_dc_lum.table = table; + rv_dc_lum.table_allocated = 1472; + rv10_build_vlc(&rv_dc_lum, rv_lum_len_count, + rv_sym_run_len, FF_ARRAY_ELEMS(rv_sym_run_len)); + for (int i = 0; i < 1 << (DC_VLC_BITS - 7 /* Length of skip prefix */); i++) { + /* All codes beginning with 0x7F have the same length and value. + * Modifying the table directly saves us the useless subtables. */ + rv_dc_lum.table[(0x7F << (DC_VLC_BITS - 7)) + i][0] = 255; + rv_dc_lum.table[(0x7F << (DC_VLC_BITS - 7)) + i][1] = 18; + } + rv_dc_chrom.table = &table[1472]; + rv_dc_chrom.table_allocated = 992; + rv10_build_vlc(&rv_dc_chrom, rv_chrom_len_count, + rv_sym_run_len, FF_ARRAY_ELEMS(rv_sym_run_len) - 2); + for (int i = 0; i < 1 << (DC_VLC_BITS - 9 /* Length of skip prefix */); i++) { + /* Same as above. */ + rv_dc_chrom.table[(0x1FE << (DC_VLC_BITS - 9)) + i][0] = 255; + rv_dc_chrom.table[(0x1FE << (DC_VLC_BITS - 9)) + i][1] = 18; + } + ff_h263_decode_init_vlc(); +} + static av_cold int rv10_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; RVDecContext *rv = avctx->priv_data; MpegEncContext *s = &rv->m; - static int done = 0; int major_ver, minor_ver, micro_ver, ret; if (avctx->extradata_size < 8) { @@ -478,7 +374,6 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) avctx->coded_height, 0, avctx)) < 0) return ret; - ff_mpv_decode_defaults(s); ff_mpv_decode_init(s, avctx); s->out_format = FMT_H263; @@ -525,18 +420,9 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) 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); - INIT_VLC_STATIC(&rv_dc_chrom, DC_VLC_BITS, 256, - rv_chrom_bits, 1, 1, - rv_chrom_code, 2, 2, 16388); - done = 1; - } + /* init static VLCs */ + ff_thread_once(&init_static_once, rv10_init_static); return 0; } diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c index 55538148f..42316836c 100644 --- a/libavcodec/rv10enc.c +++ b/libavcodec/rv10enc.c @@ -33,7 +33,7 @@ int ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) { int full_frame= 0; - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); put_bits(&s->pb, 1, 1); /* marker */ diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index ec0cd2791..99e580a09 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -24,8 +24,12 @@ * RV30/40 decoder common data */ +#include "libavutil/avassert.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" +#include "libavutil/video_enc_params.h" #include "avcodec.h" #include "error_resilience.h" @@ -75,27 +79,6 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type); * @{ */ -static const int table_offs[] = { - 0, 1818, 3622, 4144, 4698, 5234, 5804, 5868, 5900, 5932, - 5996, 6252, 6316, 6348, 6380, 7674, 8944, 10274, 11668, 12250, - 14060, 15846, 16372, 16962, 17512, 18148, 18180, 18212, 18244, 18308, - 18564, 18628, 18660, 18692, 20036, 21314, 22648, 23968, 24614, 26384, - 28190, 28736, 29366, 29938, 30608, 30640, 30672, 30704, 30768, 31024, - 31088, 31120, 31184, 32570, 33898, 35236, 36644, 37286, 39020, 40802, - 41368, 42052, 42692, 43348, 43380, 43412, 43444, 43476, 43604, 43668, - 43700, 43732, 45100, 46430, 47778, 49160, 49802, 51550, 53340, 53972, - 54648, 55348, 55994, 56122, 56154, 56186, 56218, 56346, 56410, 56442, - 56474, 57878, 59290, 60636, 62036, 62682, 64460, 64524, 64588, 64716, - 64844, 66076, 67466, 67978, 68542, 69064, 69648, 70296, 72010, 72074, - 72138, 72202, 72330, 73572, 74936, 75454, 76030, 76566, 77176, 77822, - 79582, 79646, 79678, 79742, 79870, 81180, 82536, 83064, 83672, 84242, - 84934, 85576, 87384, 87448, 87480, 87544, 87672, 88982, 90340, 90902, - 91598, 92182, 92846, 93488, 95246, 95278, 95310, 95374, 95502, 96878, - 98266, 98848, 99542, 100234, 100884, 101524, 103320, 103352, 103384, 103416, - 103480, 104874, 106222, 106910, 107584, 108258, 108902, 109544, 111366, 111398, - 111430, 111462, 111494, 112878, 114320, 114988, 115660, 116310, 116950, 117592 -}; - static VLC_TYPE table_data[117592][2]; /** @@ -106,37 +89,34 @@ static VLC_TYPE table_data[117592][2]; * @param insyms symbols for input codes (NULL for default ones) * @param num VLC table number (for static initialization) */ -static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms, - const int num) +static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *syms, + int *offset) { - int i; int counts[17] = {0}, codes[17]; - uint16_t cw[MAX_VLC_SIZE], syms[MAX_VLC_SIZE]; - uint8_t bits2[MAX_VLC_SIZE]; - int maxbits = 0, realsize = 0; + uint16_t cw[MAX_VLC_SIZE]; + int maxbits; - for(i = 0; i < size; i++){ - if(bits[i]){ - bits2[realsize] = bits[i]; - syms[realsize] = insyms ? insyms[i] : i; - realsize++; - maxbits = FFMAX(maxbits, bits[i]); - counts[bits[i]]++; - } - } + for (int i = 0; i < size; i++) + counts[bits[i]]++; - codes[0] = 0; - for(i = 0; i < 16; i++) + /* bits[0] is zero for some tables, i.e. syms actually starts at 1. + * So we reset it here. The code assigned to this element is 0x00. */ + codes[0] = counts[0] = 0; + for (int i = 0; i < 16; i++) { codes[i+1] = (codes[i] + counts[i]) << 1; - for(i = 0; i < realsize; i++) - cw[i] = codes[bits2[i]]++; + if (counts[i]) + maxbits = i; + } + for (int i = 0; i < size; i++) + cw[i] = codes[bits[i]]++; - vlc->table = &table_data[table_offs[num]]; - vlc->table_allocated = table_offs[num + 1] - table_offs[num]; - ff_init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize, - bits2, 1, 1, + vlc->table = &table_data[*offset]; + vlc->table_allocated = FF_ARRAY_ELEMS(table_data) - *offset; + ff_init_vlc_sparse(vlc, FFMIN(maxbits, 9), size, + bits, 1, 1, cw, 2, 2, - syms, 2, 2, INIT_VLC_USE_NEW_STATIC); + syms, !!syms, !!syms, INIT_VLC_STATIC_OVERLONG); + *offset += vlc->table_size; } /** @@ -144,34 +124,46 @@ static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t */ static av_cold void rv34_init_tables(void) { - int i, j, k; + int i, j, k, offset = 0; for(i = 0; i < NUM_INTRA_TABLES; i++){ for(j = 0; j < 2; j++){ - rv34_gen_vlc(rv34_table_intra_cbppat [i][j], CBPPAT_VLC_SIZE, &intra_vlcs[i].cbppattern[j], NULL, 19*i + 0 + j); - rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL, 19*i + 2 + j); - rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j], NULL, 19*i + 4 + j); + rv34_gen_vlc(rv34_table_intra_cbppat [i][j], CBPPAT_VLC_SIZE, + &intra_vlcs[i].cbppattern[j], NULL, &offset); + rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, + &intra_vlcs[i].second_pattern[j], NULL, &offset); + rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, + &intra_vlcs[i].third_pattern[j], NULL, &offset); for(k = 0; k < 4; k++){ - rv34_gen_vlc(rv34_table_intra_cbp[i][j+k*2], CBP_VLC_SIZE, &intra_vlcs[i].cbp[j][k], rv34_cbp_code, 19*i + 6 + j*4 + k); + rv34_gen_vlc(rv34_table_intra_cbp[i][j+k*2], CBP_VLC_SIZE, + &intra_vlcs[i].cbp[j][k], rv34_cbp_code, &offset); } } for(j = 0; j < 4; j++){ - rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL, 19*i + 14 + j); + rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, + &intra_vlcs[i].first_pattern[j], NULL, &offset); } - rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL, 19*i + 18); + rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, + &intra_vlcs[i].coefficient, NULL, &offset); } for(i = 0; i < NUM_INTER_TABLES; i++){ - rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL, i*12 + 95); + rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, + &inter_vlcs[i].cbppattern[0], NULL, &offset); for(j = 0; j < 4; j++){ - rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code, i*12 + 96 + j); + rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, + &inter_vlcs[i].cbp[0][j], rv34_cbp_code, &offset); } for(j = 0; j < 2; j++){ - rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j], NULL, i*12 + 100 + j); - rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL, i*12 + 102 + j); - rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j], NULL, i*12 + 104 + j); + rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, + &inter_vlcs[i].first_pattern[j], NULL, &offset); + rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, + &inter_vlcs[i].second_pattern[j], NULL, &offset); + rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, + &inter_vlcs[i].third_pattern[j], NULL, &offset); } - rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106); + rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, + &inter_vlcs[i].coefficient, NULL, &offset); } } @@ -343,8 +335,9 @@ static inline RV34VLC* choose_vlc_set(int quant, int mod, int type) { if(mod == 2 && quant < 19) quant += 10; else if(mod && quant < 26) quant += 5; - return type ? &inter_vlcs[rv34_quant_to_vlc_set[1][av_clip(quant, 0, 30)]] - : &intra_vlcs[rv34_quant_to_vlc_set[0][av_clip(quant, 0, 30)]]; + av_assert2(quant >= 0 && quant < 32); + return type ? &inter_vlcs[rv34_quant_to_vlc_set[1][quant]] + : &intra_vlcs[rv34_quant_to_vlc_set[0][quant]]; } /** @@ -1390,6 +1383,7 @@ static int rv34_decoder_alloc(RV34DecContext *r) if (!(r->cbp_chroma && r->cbp_luma && r->deblock_coefs && r->intra_types_hist && r->mb_type)) { + r->s.context_reinit = 1; rv34_decoder_free(r); return AVERROR(ENOMEM); } @@ -1491,11 +1485,11 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int */ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; RV34DecContext *r = avctx->priv_data; MpegEncContext *s = &r->s; int ret; - ff_mpv_decode_defaults(s); ff_mpv_decode_init(s, avctx); s->out_format = FMT_H263; @@ -1523,8 +1517,7 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) return ret; } - if(!intra_vlcs[0].cbppattern[0].bits) - rv34_init_tables(); + ff_thread_once(&init_static_once, rv34_init_tables); return 0; } @@ -1538,7 +1531,7 @@ int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecConte if (dst == src || !s1->context_initialized) return 0; - if (s->height != s1->height || s->width != s1->width) { + if (s->height != s1->height || s->width != s1->width || s->context_reinit) { s->height = s1->height; s->width = s1->width; if ((err = ff_mpv_common_frame_size_change(s)) < 0) @@ -1675,11 +1668,12 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, if (s->mb_num_left > 0 && s->current_picture_ptr) { av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.\n", s->mb_num_left); - ff_er_frame_end(&s->er); + if (!s->context_reinit) + ff_er_frame_end(&s->er); ff_mpv_frame_end(s); } - if (s->width != si.width || s->height != si.height) { + if (s->width != si.width || s->height != si.height || s->context_reinit) { int err; av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n", @@ -1697,7 +1691,6 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, 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) @@ -1752,6 +1745,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, } s->mb_x = s->mb_y = 0; ff_thread_finish_setup(s->avctx); + } else if (s->context_reinit) { + av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames to " + "reinitialize (start MB is %d).\n", si.start); + return AVERROR_INVALIDDATA; } else if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) { av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames in frame " diff --git a/libavcodec/rv34.h b/libavcodec/rv34.h index 1d5522538..53b29dc24 100644 --- a/libavcodec/rv34.h +++ b/libavcodec/rv34.h @@ -27,6 +27,8 @@ #ifndef AVCODEC_RV34_H #define AVCODEC_RV34_H +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "mpegvideo.h" diff --git a/libavcodec/rv34data.h b/libavcodec/rv34data.h index 4b2701fee..4509e1fee 100644 --- a/libavcodec/rv34data.h +++ b/libavcodec/rv34data.h @@ -90,26 +90,13 @@ static const uint16_t rv34_qscale_tab[32] = { /** * tables used to translate a quantizer value into a VLC set for decoding - * The first table is used for intraframes. + * The first table is used for intraframes. The two last entries are invalid. */ -static const uint8_t rv34_quant_to_vlc_set[2][31] = { +static const uint8_t rv34_quant_to_vlc_set[2][32] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0 }, + 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, - 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6 }, -}; - -/** - * table for obtaining the quantizer difference - * @todo Use with ff_modified_quant_tab from h263data.h. - */ -static const uint8_t rv34_dquant_tab[2][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, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9,10,11,12,13,14,15,16,17,18,18,19,20,21,22,23,24,25,26,27,28 -},{ - 0, 2, 3, 4, 5, 6, 7, 8, 9,10,11,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,29,30,31,31,31,26 -} + 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6 }, }; /** diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index 462024c81..e0903226b 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -24,6 +24,8 @@ * RV40 decoder */ +#include "config.h" + #include "libavutil/imgutils.h" #include "avcodec.h" @@ -39,59 +41,61 @@ static VLC aic_top_vlc; static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM]; static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS]; -static const int16_t mode2_offs[] = { - 0, 614, 1222, 1794, 2410, 3014, 3586, 4202, 4792, 5382, 5966, 6542, - 7138, 7716, 8292, 8864, 9444, 10030, 10642, 11212, 11814 -}; +static av_cold void rv40_init_table(VLC *vlc, unsigned *offset, int nb_bits, + int nb_codes, const uint8_t (*tab)[2]) +{ + static VLC_TYPE vlc_buf[11776][2]; + + vlc->table = &vlc_buf[*offset]; + vlc->table_allocated = 1 << nb_bits; + *offset += 1 << nb_bits; + + ff_init_vlc_from_lengths(vlc, nb_bits, nb_codes, + &tab[0][1], 2, &tab[0][0], 2, 1, + 0, INIT_VLC_USE_NEW_STATIC, NULL); +} /** * Initialize all tables. */ static av_cold void rv40_init_tables(void) { - int i; - static VLC_TYPE aic_table[1 << AIC_TOP_BITS][2]; - static VLC_TYPE aic_mode1_table[AIC_MODE1_NUM << AIC_MODE1_BITS][2]; + int i, offset = 0; static VLC_TYPE aic_mode2_table[11814][2]; - static VLC_TYPE ptype_table[NUM_PTYPE_VLCS << PTYPE_VLC_BITS][2]; - static VLC_TYPE btype_table[NUM_BTYPE_VLCS << BTYPE_VLC_BITS][2]; - aic_top_vlc.table = aic_table; - aic_top_vlc.table_allocated = 1 << AIC_TOP_BITS; - init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE, - rv40_aic_top_vlc_bits, 1, 1, - rv40_aic_top_vlc_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); + rv40_init_table(&aic_top_vlc, &offset, AIC_TOP_BITS, AIC_TOP_SIZE, + rv40_aic_top_vlc_tab); for(i = 0; i < AIC_MODE1_NUM; i++){ // Every tenth VLC table is empty if((i % 10) == 9) continue; - aic_mode1_vlc[i].table = &aic_mode1_table[i << AIC_MODE1_BITS]; - aic_mode1_vlc[i].table_allocated = 1 << AIC_MODE1_BITS; - init_vlc(&aic_mode1_vlc[i], AIC_MODE1_BITS, AIC_MODE1_SIZE, - aic_mode1_vlc_bits[i], 1, 1, - aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + rv40_init_table(&aic_mode1_vlc[i], &offset, AIC_MODE1_BITS, + AIC_MODE1_SIZE, aic_mode1_vlc_tabs[i]); } - for(i = 0; i < AIC_MODE2_NUM; i++){ - aic_mode2_vlc[i].table = &aic_mode2_table[mode2_offs[i]]; - aic_mode2_vlc[i].table_allocated = mode2_offs[i + 1] - mode2_offs[i]; - init_vlc(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE, - aic_mode2_vlc_bits[i], 1, 1, - aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); + for (unsigned i = 0, offset = 0; i < AIC_MODE2_NUM; i++){ + uint16_t syms[AIC_MODE2_SIZE]; + + for (int j = 0; j < AIC_MODE2_SIZE; j++) { + int first = aic_mode2_vlc_syms[i][j] >> 4; + int second = aic_mode2_vlc_syms[i][j] & 0xF; + if (HAVE_BIGENDIAN) + syms[j] = (first << 8) | second; + else + syms[j] = first | (second << 8); + } + aic_mode2_vlc[i].table = &aic_mode2_table[offset]; + aic_mode2_vlc[i].table_allocated = FF_ARRAY_ELEMS(aic_mode2_table) - offset; + ff_init_vlc_from_lengths(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE, + aic_mode2_vlc_bits[i], 1, + syms, 2, 2, 0, INIT_VLC_STATIC_OVERLONG, NULL); + offset += aic_mode2_vlc[i].table_size; } for(i = 0; i < NUM_PTYPE_VLCS; i++){ - ptype_vlc[i].table = &ptype_table[i << PTYPE_VLC_BITS]; - ptype_vlc[i].table_allocated = 1 << PTYPE_VLC_BITS; - ff_init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE, - ptype_vlc_bits[i], 1, 1, - ptype_vlc_codes[i], 1, 1, - ptype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); + rv40_init_table(&ptype_vlc[i], &offset, PTYPE_VLC_BITS, PTYPE_VLC_SIZE, + ptype_vlc_tabs[i]); } for(i = 0; i < NUM_BTYPE_VLCS; i++){ - btype_vlc[i].table = &btype_table[i << BTYPE_VLC_BITS]; - btype_vlc[i].table_allocated = 1 << BTYPE_VLC_BITS; - ff_init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE, - btype_vlc_bits[i], 1, 1, - btype_vlc_codes[i], 1, 1, - btype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); + rv40_init_table(&btype_vlc[i], &offset, BTYPE_VLC_BITS, BTYPE_VLC_SIZE, + btype_vlc_tabs[i]); } } @@ -194,9 +198,8 @@ static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t if(pattern == rv40_aic_table_index[k]) break; if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients - v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2); - *ptr++ = v/9; - *ptr++ = v%9; + AV_WN16(ptr, get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2)); + ptr += 2; j++; }else{ if(B != -1 && C != -1) diff --git a/libavcodec/rv40vlc2.h b/libavcodec/rv40vlc2.h index 15119a145..fec47ff4a 100644 --- a/libavcodec/rv40vlc2.h +++ b/libavcodec/rv40vlc2.h @@ -33,15 +33,12 @@ * codes used for the first four block types */ //@{ -#define AIC_TOP_BITS 8 +#define AIC_TOP_BITS 7 #define AIC_TOP_SIZE 16 -static const uint8_t rv40_aic_top_vlc_codes[AIC_TOP_SIZE] = { - 0x01, 0x05, 0x01, 0x00, 0x03, 0x3D, 0x1D, 0x02, - 0x04, 0x3C, 0x3F, 0x1C, 0x0D, 0x3E, 0x0C, 0x01 -}; - -static const uint8_t rv40_aic_top_vlc_bits[AIC_TOP_SIZE] = { - 1, 4, 5, 5, 5, 7, 6, 5, 4, 7, 7, 6, 5, 7, 5, 3 +static const uint8_t rv40_aic_top_vlc_tab[AIC_TOP_SIZE][2] = { + { 0x3, 5 }, { 0x2, 5 }, { 0x7, 5 }, { 0x4, 5 }, { 0xF, 3 }, { 0x8, 4 }, + { 0x1, 4 }, { 0xE, 5 }, { 0xC, 5 }, { 0xB, 6 }, { 0x6, 6 }, { 0x9, 7 }, + { 0x5, 7 }, { 0xD, 7 }, { 0xA, 7 }, { 0x0, 1 }, }; //@} @@ -53,370 +50,330 @@ static const uint8_t rv40_aic_top_vlc_bits[AIC_TOP_SIZE] = { #define AIC_MODE2_SIZE 81 #define AIC_MODE2_BITS 9 -static const uint16_t aic_mode2_vlc_codes[AIC_MODE2_NUM][AIC_MODE2_SIZE] = { -{ 0x0001, 0x0001, 0x0005, 0x01F5, 0x0011, 0x0049, 0x0000, 0x0048, 0x004B, - 0x0035, 0x0003, 0x0034, 0x03C9, 0x01F4, 0x00C9, 0x004A, 0x0FD9, 0x03C8, - 0x0010, 0x0037, 0x0001, 0x00C8, 0x0075, 0x01F7, 0x00CB, 0x0074, 0x0002, - 0x01F6, 0x00CA, 0x01F1, 0x01F0, 0x1F81, 0x07F9, 0x1F80, 0x1F83, 0x07F8, - 0x0077, 0x00F5, 0x0036, 0x07FB, 0x0076, 0x1F82, 0x00F4, 0x00F7, 0x07FA, - 0x0071, 0x00F6, 0x03CB, 0x03CA, 0x0FD8, 0x00F1, 0x03F5, 0x1F8D, 0x07E5, - 0x0013, 0x0031, 0x00F0, 0x0FDB, 0x00F3, 0x07E4, 0x0030, 0x01F3, 0x07E7, - 0x03F4, 0x07E6, 0x0070, 0x3F19, 0x01F2, 0x3F18, 0x0FDA, 0x0033, 0x07E1, - 0x01FD, 0x01FC, 0x0073, 0x01FF, 0x0FC5, 0x0FC4, 0x0FC7, 0x03F7, 0x0072, }, -{ 0x0005, 0x0005, 0x0005, 0x0079, 0x0005, 0x000D, 0x001D, 0x0078, 0x0069, - 0x0004, 0x0001, 0x0007, 0x0068, 0x001C, 0x001F, 0x0004, 0x006B, 0x000C, - 0x0004, 0x001E, 0x0006, 0x006A, 0x0015, 0x000F, 0x0014, 0x0017, 0x0007, - 0x0016, 0x000E, 0x0011, 0x0009, 0x00D1, 0x00D0, 0x0181, 0x00D3, 0x007B, - 0x0010, 0x0013, 0x0004, 0x00D2, 0x0007, 0x0319, 0x0008, 0x007A, 0x00DD, - 0x0019, 0x0006, 0x000B, 0x0065, 0x00DC, 0x0012, 0x0064, 0x0180, 0x00DF, - 0x0006, 0x0018, 0x0001, 0x00DE, 0x001D, 0x00D9, 0x001B, 0x0067, 0x000A, - 0x00D8, 0x00DB, 0x001C, 0x0318, 0x00DA, 0x0635, 0x0183, 0x0000, 0x00C5, - 0x0066, 0x0061, 0x0035, 0x00C4, 0x0182, 0x0634, 0x031B, 0x00C7, 0x001F, }, -{ 0x0005, 0x0001, 0x001D, 0x01C1, 0x0035, 0x00F1, 0x006D, 0x00F0, 0x0049, - 0x0000, 0x0004, 0x0003, 0x00F3, 0x0048, 0x0034, 0x006C, 0x01C0, 0x01C3, - 0x0007, 0x0006, 0x0001, 0x006F, 0x0002, 0x004B, 0x006E, 0x001C, 0x0005, - 0x0069, 0x0068, 0x006B, 0x0037, 0x01C2, 0x00F2, 0x0395, 0x01CD, 0x00FD, - 0x006A, 0x0036, 0x0015, 0x01CC, 0x0014, 0x0394, 0x004A, 0x00FC, 0x00FF, - 0x0017, 0x0031, 0x00FE, 0x01CF, 0x0397, 0x00F9, 0x01CE, 0x0725, 0x0396, - 0x0016, 0x0030, 0x0075, 0x0724, 0x00F8, 0x0727, 0x0033, 0x0391, 0x0390, - 0x0011, 0x0032, 0x001F, 0x00FB, 0x0074, 0x0726, 0x00FA, 0x001E, 0x0077, - 0x0019, 0x0018, 0x0004, 0x0010, 0x003D, 0x0076, 0x0071, 0x0013, 0x0001, }, -{ 0x000D, 0x0019, 0x0011, 0x0015, 0x0061, 0x0019, 0x0014, 0x01AD, 0x0060, - 0x0018, 0x0001, 0x0005, 0x001B, 0x0010, 0x0019, 0x0005, 0x0017, 0x0018, - 0x0016, 0x0004, 0x0004, 0x0013, 0x000C, 0x0012, 0x001A, 0x0018, 0x0005, - 0x000F, 0x001B, 0x0004, 0x001D, 0x0011, 0x001C, 0x0010, 0x000E, 0x001B, - 0x0013, 0x001F, 0x001A, 0x0029, 0x0005, 0x0063, 0x001E, 0x0009, 0x0062, - 0x0008, 0x0007, 0x0007, 0x0019, 0x0004, 0x001A, 0x0018, 0x006D, 0x0007, - 0x001B, 0x0007, 0x001A, 0x006C, 0x0006, 0x0012, 0x0005, 0x006F, 0x000B, - 0x006E, 0x0069, 0x001D, 0x0359, 0x0028, 0x002B, 0x002A, 0x001C, 0x00D5, - 0x0358, 0x001F, 0x0001, 0x001E, 0x0068, 0x00D4, 0x00D7, 0x0019, 0x0000, }, -{ 0x00B9, 0x0061, 0x0060, 0x00B8, 0x02B5, 0x01AD, 0x00BB, 0x0AF5, 0x0151, - 0x0001, 0x0001, 0x0005, 0x0000, 0x0003, 0x0005, 0x0004, 0x0063, 0x0025, - 0x00BA, 0x0004, 0x0007, 0x0062, 0x00A5, 0x0024, 0x006D, 0x0002, 0x006C, - 0x02B4, 0x000D, 0x006F, 0x0027, 0x00A4, 0x0026, 0x01AC, 0x0150, 0x01AF, - 0x01AE, 0x0021, 0x006E, 0x02B7, 0x0020, 0x0153, 0x0023, 0x00A7, 0x0152, - 0x00A6, 0x0006, 0x000C, 0x0022, 0x01A9, 0x0019, 0x002D, 0x02B6, 0x01A8, - 0x000F, 0x0007, 0x000E, 0x00A1, 0x0069, 0x002C, 0x0001, 0x01AB, 0x00A0, - 0x02B1, 0x00A3, 0x002F, 0x0AF4, 0x02B0, 0x0AF7, 0x02B3, 0x0068, 0x015D, - 0x0AF6, 0x01AA, 0x0055, 0x015C, 0x02B2, 0x0579, 0x0578, 0x015F, 0x00A2, }, -{ 0x0905, 0x013D, 0x013C, 0x0904, 0x121D, 0x049D, 0x049C, 0x243D, 0x0907, - 0x00ED, 0x0001, 0x0015, 0x0041, 0x013F, 0x0031, 0x0014, 0x025D, 0x025C, - 0x013E, 0x000D, 0x0000, 0x0040, 0x0139, 0x0043, 0x0030, 0x0017, 0x0033, - 0x0906, 0x0032, 0x0042, 0x00EC, 0x025F, 0x00EF, 0x025E, 0x049F, 0x0138, - 0x0901, 0x013B, 0x0259, 0x121C, 0x049E, 0x0900, 0x0258, 0x243C, 0x121F, - 0x0903, 0x003D, 0x00EE, 0x025B, 0x025A, 0x004D, 0x013A, 0x0902, 0x0245, - 0x00E9, 0x0016, 0x00E8, 0x0499, 0x0125, 0x0244, 0x004C, 0x0498, 0x090D, - 0x00EB, 0x003C, 0x0011, 0x049B, 0x049A, 0x0485, 0x00EA, 0x003F, 0x0124, - 0x090C, 0x003E, 0x0039, 0x0095, 0x0247, 0x0246, 0x0484, 0x0094, 0x0038, }, -{ 0x0F09, 0x00CD, 0x01FD, 0x0791, 0x1E6D, 0x0790, 0x03D9, 0x3CD1, 0x3CD0, - 0x0075, 0x0001, 0x0001, 0x0035, 0x00CC, 0x0011, 0x0000, 0x03D8, 0x01FC, - 0x03DB, 0x0010, 0x0003, 0x00CF, 0x03DA, 0x00CE, 0x0074, 0x0034, 0x0077, - 0x0793, 0x0013, 0x0076, 0x0071, 0x03C5, 0x0070, 0x01FF, 0x0792, 0x01FE, - 0x01F9, 0x0037, 0x00C9, 0x0F08, 0x01F8, 0x03C4, 0x00C8, 0x0F0B, 0x079D, - 0x03C7, 0x0001, 0x0012, 0x0073, 0x00CB, 0x0005, 0x0036, 0x03C6, 0x0072, - 0x007D, 0x0002, 0x00CA, 0x079C, 0x01FB, 0x00F5, 0x0031, 0x079F, 0x0F0A, - 0x0F35, 0x079E, 0x01FA, 0x1E6C, 0x1E6F, 0x3CD3, 0x0799, 0x03C1, 0x1E6E, - 0x3CD2, 0x0030, 0x00F4, 0x007C, 0x03C0, 0x03C3, 0x0798, 0x01E5, 0x00F7, }, -{ 0x01A5, 0x0001, 0x001D, 0x0021, 0x00A1, 0x000D, 0x0061, 0x06B9, 0x00A0, - 0x0060, 0x0001, 0x0005, 0x000C, 0x0020, 0x001C, 0x0004, 0x01A4, 0x01A7, - 0x00A3, 0x001F, 0x001E, 0x0023, 0x0022, 0x002D, 0x002C, 0x0063, 0x0062, - 0x1A81, 0x01A6, 0x01A1, 0x06B8, 0x06BB, 0x00A2, 0x06BA, 0x0D59, 0x06A5, - 0x01A0, 0x000F, 0x006D, 0x06A4, 0x002F, 0x00AD, 0x006C, 0x06A7, 0x00AC, - 0x0D58, 0x000E, 0x01A3, 0x00AF, 0x00AE, 0x006F, 0x01A2, 0x0D5B, 0x00A9, - 0x0019, 0x0001, 0x0009, 0x00A8, 0x006E, 0x002E, 0x0000, 0x01AD, 0x00AB, - 0x00AA, 0x0355, 0x0029, 0x1A80, 0x1A83, 0x1A82, 0x0354, 0x01AC, 0x0D5A, - 0x1A8D, 0x01AF, 0x0357, 0x0D45, 0x0D44, 0x0D47, 0x1A8C, 0x06A6, 0x06A1, }, -{ 0x0001, 0x0011, 0x0005, 0x0775, 0x00F9, 0x00F8, 0x0031, 0x0030, 0x0049, - 0x00FB, 0x0010, 0x0033, 0x0EC9, 0x038D, 0x038C, 0x00FA, 0x038F, 0x0774, - 0x0048, 0x0032, 0x0000, 0x01D5, 0x00E5, 0x038E, 0x00E4, 0x0013, 0x000D, - 0x0389, 0x0777, 0x0388, 0x038B, 0x1DF9, 0x0EC8, 0x3BC9, 0x1DF8, 0x038A, - 0x03B5, 0x0776, 0x00E7, 0x3BC8, 0x01D4, 0x3BCB, 0x0ECB, 0x0771, 0x0ECA, - 0x01D7, 0x03B4, 0x01D6, 0x1DFB, 0x0EF5, 0x0770, 0x0EF4, 0x3BCA, 0x0773, - 0x00E6, 0x03B7, 0x004B, 0x1DFA, 0x03B6, 0x0EF7, 0x00E1, 0x0EF6, 0x0EF1, - 0x03B1, 0x01D1, 0x003D, 0x0EF0, 0x0772, 0x077D, 0x077C, 0x003C, 0x01D0, - 0x03B0, 0x01D3, 0x003F, 0x03B3, 0x01D2, 0x0EF3, 0x077F, 0x00E0, 0x004A, }, -{ 0x0015, 0x0049, 0x0014, 0x07D1, 0x03FD, 0x03FC, 0x01C1, 0x01C0, 0x00F1, - 0x0017, 0x0001, 0x0001, 0x01C3, 0x0048, 0x004B, 0x0016, 0x0031, 0x01C2, - 0x004A, 0x0011, 0x0000, 0x01CD, 0x00F0, 0x01CC, 0x0075, 0x0010, 0x000D, - 0x03FF, 0x01CF, 0x01CE, 0x07D0, 0x0F81, 0x07D3, 0x1F1D, 0x0F80, 0x07D2, - 0x01C9, 0x03FE, 0x0074, 0x07DD, 0x00F3, 0x1F1C, 0x07DC, 0x03F9, 0x07DF, - 0x00F2, 0x00FD, 0x0077, 0x07DE, 0x07D9, 0x01C8, 0x07D8, 0x0F83, 0x03F8, - 0x0030, 0x0076, 0x0013, 0x0F82, 0x00FC, 0x03FB, 0x0033, 0x03FA, 0x03E5, - 0x03E4, 0x01CB, 0x0032, 0x1F1F, 0x03E7, 0x07DB, 0x07DA, 0x003D, 0x01CA, - 0x07C5, 0x03E6, 0x0071, 0x0F8D, 0x07C4, 0x1F1E, 0x0F8C, 0x03E1, 0x01F5, }, -{ 0x0019, 0x0065, 0x0018, 0x0351, 0x0350, 0x0353, 0x0021, 0x0020, 0x0064, - 0x001D, 0x0005, 0x0005, 0x01A5, 0x0023, 0x0067, 0x0005, 0x0066, 0x0022, - 0x001B, 0x0004, 0x0001, 0x0004, 0x001C, 0x0061, 0x001A, 0x0005, 0x0004, - 0x0007, 0x002D, 0x0006, 0x002C, 0x01A4, 0x002F, 0x0352, 0x035D, 0x0060, - 0x0001, 0x002E, 0x001F, 0x035C, 0x0000, 0x06B1, 0x01A7, 0x0029, 0x01A6, - 0x0028, 0x0063, 0x0062, 0x035F, 0x01A1, 0x002B, 0x06B0, 0x06B3, 0x01A0, - 0x0003, 0x006D, 0x001E, 0x035E, 0x006C, 0x06B2, 0x0002, 0x01A3, 0x01A2, - 0x000D, 0x0005, 0x0007, 0x01AD, 0x006F, 0x002A, 0x006E, 0x0004, 0x0004, - 0x000C, 0x0007, 0x0006, 0x000F, 0x000E, 0x00D5, 0x0009, 0x0006, 0x0007, }, -{ 0x0065, 0x0181, 0x0064, 0x36C9, 0x06D5, 0x0DB5, 0x0379, 0x0180, 0x0183, - 0x00D5, 0x001D, 0x001C, 0x0DB4, 0x0182, 0x0378, 0x00D4, 0x00D7, 0x06D4, - 0x0067, 0x001F, 0x0001, 0x00D6, 0x00D1, 0x018D, 0x0066, 0x0001, 0x0000, - 0x037B, 0x06D7, 0x037A, 0x0DB7, 0x36C8, 0x06D6, 0x0DB6, 0x1B79, 0x0DB1, - 0x018C, 0x0365, 0x00D0, 0x1B78, 0x00D3, 0x1B7B, 0x0364, 0x06D1, 0x06D0, - 0x018F, 0x018E, 0x00D2, 0x36CB, 0x0367, 0x0366, 0x06D3, 0x0DB0, 0x06D2, - 0x0361, 0x06DD, 0x0189, 0x36CA, 0x0360, 0x36F5, 0x0188, 0x0DB3, 0x36F4, - 0x0009, 0x0008, 0x0005, 0x06DC, 0x00DD, 0x018B, 0x00DC, 0x0004, 0x000B, - 0x018A, 0x0061, 0x0003, 0x0363, 0x00DF, 0x06DF, 0x0362, 0x000A, 0x001E, }, -{ 0x001D, 0x0061, 0x000D, 0x0D55, 0x06B9, 0x06B8, 0x01A5, 0x0021, 0x0020, - 0x0023, 0x000C, 0x0060, 0x0D54, 0x00AD, 0x00AC, 0x0022, 0x00AF, 0x06BB, - 0x000F, 0x001C, 0x0001, 0x002D, 0x0063, 0x01A4, 0x000E, 0x0001, 0x0005, - 0x01A7, 0x06BA, 0x01A6, 0x06A5, 0x0D57, 0x0D56, 0x1ABD, 0x0D51, 0x00AE, - 0x002C, 0x00A9, 0x002F, 0x0D50, 0x01A1, 0x1ABC, 0x06A4, 0x06A7, 0x06A6, - 0x00A8, 0x06A1, 0x01A0, 0x1ABF, 0x0D53, 0x06A0, 0x0D52, 0x1ABE, 0x06A3, - 0x0062, 0x002E, 0x0009, 0x0D5D, 0x01A3, 0x0D5C, 0x006D, 0x00AB, 0x06A2, - 0x006C, 0x001F, 0x0001, 0x06AD, 0x0029, 0x01A2, 0x0028, 0x0004, 0x001E, - 0x01AD, 0x006F, 0x0000, 0x01AC, 0x01AF, 0x06AC, 0x00AA, 0x006E, 0x0019, }, -{ 0x0019, 0x007D, 0x0018, 0x01B5, 0x000D, 0x01B4, 0x007C, 0x007F, 0x01B7, - 0x000C, 0x001B, 0x001A, 0x01B6, 0x000F, 0x00D5, 0x0019, 0x007E, 0x00D4, - 0x0018, 0x001B, 0x0001, 0x000E, 0x0011, 0x0009, 0x0005, 0x0005, 0x0005, - 0x00D7, 0x01B1, 0x0008, 0x01B0, 0x0079, 0x06FD, 0x0371, 0x0370, 0x00D6, - 0x0078, 0x01B3, 0x0010, 0x0373, 0x0013, 0x06FC, 0x007B, 0x007A, 0x00D1, - 0x00D0, 0x00D3, 0x0065, 0x0372, 0x06FF, 0x0064, 0x06FE, 0x037D, 0x00D2, - 0x00DD, 0x0067, 0x0004, 0x037C, 0x0012, 0x01B2, 0x0007, 0x0066, 0x01BD, - 0x0006, 0x0061, 0x0004, 0x01BC, 0x001A, 0x0060, 0x001D, 0x0004, 0x001C, - 0x0063, 0x0001, 0x0007, 0x000B, 0x0000, 0x0062, 0x000A, 0x0005, 0x0007, }, -{ 0x0069, 0x0045, 0x0068, 0x04BD, 0x0255, 0x04BC, 0x00E5, 0x00E4, 0x0031, - 0x0030, 0x0019, 0x0001, 0x0121, 0x00E7, 0x00E6, 0x0033, 0x00E1, 0x00E0, - 0x006B, 0x0018, 0x0001, 0x0044, 0x0032, 0x0047, 0x006A, 0x001B, 0x0005, - 0x003D, 0x0046, 0x0015, 0x0041, 0x0120, 0x0123, 0x04BF, 0x0122, 0x0040, - 0x003C, 0x00E3, 0x0014, 0x0254, 0x0043, 0x0975, 0x012D, 0x00E2, 0x00ED, - 0x0042, 0x00EC, 0x004D, 0x0257, 0x0256, 0x0251, 0x04BE, 0x0974, 0x0250, - 0x00EF, 0x00EE, 0x004C, 0x04B9, 0x012C, 0x04B8, 0x004F, 0x04BB, 0x0253, - 0x003F, 0x0017, 0x0001, 0x0252, 0x00E9, 0x00E8, 0x00EB, 0x0000, 0x0003, - 0x0016, 0x0002, 0x0004, 0x004E, 0x003E, 0x00EA, 0x0049, 0x000D, 0x0007, }, -{ 0x000D, 0x01BD, 0x000C, 0x0D31, 0x0D30, 0x0D33, 0x0359, 0x0358, 0x002D, - 0x0065, 0x001D, 0x001C, 0x0D32, 0x035B, 0x035A, 0x002C, 0x01BC, 0x0345, - 0x000F, 0x001F, 0x0001, 0x002F, 0x0064, 0x01BF, 0x0067, 0x0001, 0x0005, - 0x0066, 0x002E, 0x0061, 0x0029, 0x0695, 0x0694, 0x0697, 0x0696, 0x0060, - 0x01BE, 0x0D3D, 0x0028, 0x1A49, 0x0344, 0x1A48, 0x1A4B, 0x0D3C, 0x0691, - 0x002B, 0x01B9, 0x002A, 0x0D3F, 0x0690, 0x0347, 0x0D3E, 0x1A4A, 0x0346, - 0x00D5, 0x0341, 0x0063, 0x0D39, 0x0340, 0x0D38, 0x01B8, 0x0D3B, 0x0D3A, - 0x00D4, 0x0062, 0x0000, 0x0693, 0x01BB, 0x0343, 0x0342, 0x001E, 0x000E, - 0x006D, 0x0009, 0x0001, 0x006C, 0x00D7, 0x034D, 0x01BA, 0x0008, 0x0004, }, -{ 0x0075, 0x00CD, 0x0035, 0x03C1, 0x03C0, 0x07F9, 0x03C3, 0x1F8D, 0x00CC, - 0x0074, 0x0011, 0x0010, 0x03C2, 0x0FD9, 0x01F1, 0x00CF, 0x03CD, 0x00CE, - 0x0034, 0x0001, 0x0001, 0x0037, 0x00C9, 0x00C8, 0x0036, 0x0000, 0x0001, - 0x0FD8, 0x03CC, 0x00CB, 0x01F0, 0x07F8, 0x03CF, 0x07FB, 0x07FA, 0x00CA, - 0x01F3, 0x03CE, 0x00F5, 0x0FDB, 0x00F4, 0x07E5, 0x07E4, 0x07E7, 0x01F2, - 0x07E6, 0x03C9, 0x01FD, 0x0FDA, 0x1F8C, 0x07E1, 0x1F8F, 0x1F8E, 0x03C8, - 0x03CB, 0x0077, 0x0076, 0x0FC5, 0x03CA, 0x07E0, 0x00F7, 0x0FC4, 0x03F5, - 0x00F6, 0x01FC, 0x0003, 0x03F4, 0x0071, 0x03F7, 0x00F1, 0x0013, 0x0031, - 0x0030, 0x0070, 0x0005, 0x0012, 0x0073, 0x01FF, 0x0072, 0x007D, 0x0002, }, -{ 0x0061, 0x0055, 0x0060, 0x02C9, 0x02C8, 0x02CB, 0x0171, 0x00B5, 0x0054, - 0x0001, 0x0001, 0x0001, 0x0057, 0x0001, 0x0063, 0x001D, 0x0062, 0x0039, - 0x006D, 0x0000, 0x0005, 0x0038, 0x0056, 0x00B4, 0x006C, 0x0003, 0x001C, - 0x006F, 0x003B, 0x0002, 0x003A, 0x0170, 0x00B7, 0x0173, 0x0051, 0x006E, - 0x0025, 0x0050, 0x0069, 0x02CA, 0x0024, 0x0027, 0x0172, 0x00B6, 0x00B1, - 0x000D, 0x000C, 0x001F, 0x017D, 0x0026, 0x0068, 0x0053, 0x017C, 0x006B, - 0x001E, 0x000F, 0x0004, 0x017F, 0x006A, 0x02F5, 0x0019, 0x0021, 0x0052, - 0x02F4, 0x02F7, 0x0020, 0x0BCD, 0x05E5, 0x05E4, 0x0BCC, 0x0023, 0x00B0, - 0x02F6, 0x00B3, 0x0022, 0x02F1, 0x02F0, 0x0BCF, 0x0BCE, 0x017E, 0x005D, }, -{ 0x00BD, 0x0025, 0x01A1, 0x0159, 0x0299, 0x00BC, 0x0024, 0x0505, 0x0504, - 0x01A0, 0x0001, 0x001D, 0x006D, 0x001C, 0x0001, 0x0005, 0x0027, 0x01A3, - 0x0158, 0x001F, 0x001E, 0x01A2, 0x0026, 0x0021, 0x000D, 0x0020, 0x0023, - 0x0298, 0x006C, 0x0022, 0x00BF, 0x00BE, 0x01AD, 0x002D, 0x029B, 0x00B9, - 0x01AC, 0x00B8, 0x01AF, 0x029A, 0x006F, 0x015B, 0x006E, 0x0285, 0x0284, - 0x01AE, 0x0019, 0x002C, 0x01A9, 0x01A8, 0x000C, 0x000F, 0x015A, 0x00BB, - 0x000E, 0x0000, 0x0069, 0x01AB, 0x0018, 0x01AA, 0x0004, 0x0055, 0x00BA, - 0x0507, 0x0145, 0x0054, 0x0506, 0x00A5, 0x0501, 0x00A4, 0x0057, 0x0500, - 0x0A05, 0x0144, 0x00A7, 0x0287, 0x0286, 0x0503, 0x0147, 0x0A04, 0x0146, }, -{ 0x0759, 0x0041, 0x00E5, 0x03BD, 0x0E9D, 0x012D, 0x012C, 0x3A1D, 0x03BC, - 0x012F, 0x000D, 0x0040, 0x00E4, 0x03BF, 0x0043, 0x0042, 0x0758, 0x03BE, - 0x00E7, 0x0001, 0x0000, 0x003D, 0x00E6, 0x0015, 0x0014, 0x0017, 0x003C, - 0x743D, 0x012E, 0x03B9, 0x03B8, 0x0E9C, 0x03BB, 0x075B, 0x3A1C, 0x0E9F, - 0x0129, 0x00E1, 0x0128, 0x0E9E, 0x012B, 0x075A, 0x00E0, 0x0E99, 0x0745, - 0x3A1F, 0x03BA, 0x0744, 0x0E98, 0x1D0D, 0x03A5, 0x0E9B, 0x743C, 0x0E9A, - 0x012A, 0x004D, 0x00E3, 0x0E85, 0x01D5, 0x0E84, 0x004C, 0x0747, 0x1D0C, - 0x01D4, 0x003F, 0x0016, 0x0746, 0x03A4, 0x0741, 0x004F, 0x003E, 0x01D7, - 0x0740, 0x000C, 0x0011, 0x004E, 0x00E2, 0x00ED, 0x00EC, 0x0049, 0x0048, }, +static const uint8_t aic_mode2_vlc_syms[AIC_MODE2_NUM][AIC_MODE2_SIZE] = { + { + 0x06, 0x01, 0x28, 0x11, 0x22, 0x20, 0x04, 0x07, 0x05, 0x16, 0x08, 0x60, + 0x02, 0x66, 0x61, 0x23, 0x15, 0x31, 0x26, 0x77, 0x12, 0x10, 0x42, 0x21, + 0x72, 0x50, 0x88, 0x82, 0x27, 0x24, 0x44, 0x40, 0x62, 0x55, 0x18, 0x13, + 0x53, 0x52, 0x64, 0x46, 0x41, 0x51, 0x47, 0x33, 0x32, 0x74, 0x67, 0x14, + 0x03, 0x30, 0x25, 0x36, 0x34, 0x45, 0x37, 0x78, 0x85, 0x84, 0x75, 0x73, + 0x57, 0x86, 0x65, 0x58, 0x71, 0x68, 0x70, 0x56, 0x54, 0x17, 0x76, 0x63, + 0x87, 0x81, 0x80, 0x38, 0x35, 0x48, 0x43, 0x83, 0x00, + }, + { + 0x77, 0x62, 0x46, 0x33, 0x68, 0x52, 0x18, 0x05, 0x31, 0x25, 0x42, 0x04, + 0x51, 0x44, 0x40, 0x32, 0x55, 0x41, 0x26, 0x24, 0x30, 0x27, 0x57, 0x36, + 0x84, 0x76, 0x81, 0x83, 0x78, 0x73, 0x45, 0x85, 0x75, 0x86, 0x87, 0x56, + 0x53, 0x80, 0x67, 0x35, 0x34, 0x43, 0x37, 0x82, 0x70, 0x65, 0x74, 0x71, + 0x54, 0x48, 0x63, 0x58, 0x72, 0x64, 0x07, 0x03, 0x47, 0x38, 0x88, 0x20, + 0x01, 0x60, 0x28, 0x16, 0x02, 0x61, 0x50, 0x13, 0x08, 0x23, 0x17, 0x66, + 0x14, 0x06, 0x21, 0x15, 0x10, 0x00, 0x22, 0x12, 0x11, + }, + { + 0x10, 0x01, 0x24, 0x12, 0x88, 0x83, 0x70, 0x14, 0x08, 0x46, 0x25, 0x87, + 0x44, 0x42, 0x60, 0x50, 0x61, 0x51, 0x71, 0x66, 0x15, 0x04, 0x41, 0x33, + 0x17, 0x03, 0x34, 0x18, 0x86, 0x68, 0x67, 0x63, 0x57, 0x75, 0x65, 0x45, + 0x36, 0x58, 0x54, 0x43, 0x37, 0x56, 0x53, 0x74, 0x62, 0x85, 0x78, 0x07, + 0x05, 0x35, 0x13, 0x84, 0x64, 0x55, 0x76, 0x73, 0x47, 0x38, 0x52, 0x48, + 0x11, 0x00, 0x21, 0x20, 0x82, 0x28, 0x81, 0x80, 0x31, 0x30, 0x40, 0x32, + 0x16, 0x06, 0x26, 0x23, 0x27, 0x02, 0x77, 0x72, 0x22, + }, + { + 0x88, 0x82, 0x50, 0x47, 0x74, 0x43, 0x76, 0x75, 0x68, 0x24, 0x00, 0x37, + 0x30, 0x54, 0x44, 0x64, 0x58, 0x36, 0x34, 0x65, 0x40, 0x06, 0x03, 0x20, + 0x17, 0x08, 0x04, 0x48, 0x45, 0x87, 0x84, 0x71, 0x85, 0x78, 0x80, 0x73, + 0x07, 0x86, 0x63, 0x57, 0x70, 0x67, 0x77, 0x72, 0x83, 0x81, 0x32, 0x28, + 0x18, 0x05, 0x42, 0x38, 0x52, 0x14, 0x02, 0x25, 0x23, 0x66, 0x56, 0x53, + 0x62, 0x60, 0x35, 0x33, 0x46, 0x41, 0x21, 0x12, 0x10, 0x01, 0x26, 0x13, + 0x61, 0x22, 0x16, 0x27, 0x15, 0x55, 0x31, 0x51, 0x11, + }, + { + 0x13, 0x10, 0x27, 0x14, 0x66, 0x44, 0x41, 0x53, 0x46, 0x25, 0x18, 0x35, + 0x33, 0x68, 0x63, 0x88, 0x71, 0x34, 0x24, 0x50, 0x47, 0x37, 0x08, 0x48, + 0x45, 0x82, 0x74, 0x70, 0x84, 0x76, 0x30, 0x04, 0x57, 0x43, 0x83, 0x78, + 0x86, 0x85, 0x73, 0x07, 0x80, 0x75, 0x87, 0x65, 0x56, 0x03, 0x00, 0x20, + 0x06, 0x72, 0x52, 0x31, 0x62, 0x60, 0x21, 0x15, 0x51, 0x22, 0x16, 0x12, + 0x02, 0x01, 0x23, 0x17, 0x55, 0x77, 0x64, 0x58, 0x54, 0x81, 0x67, 0x36, + 0x05, 0x40, 0x38, 0x28, 0x26, 0x42, 0x32, 0x61, 0x11, + }, + { + 0x22, 0x11, 0x23, 0x13, 0x32, 0x25, 0x72, 0x45, 0x40, 0x57, 0x50, 0x03, + 0x00, 0x30, 0x08, 0x86, 0x75, 0x80, 0x68, 0x43, 0x04, 0x47, 0x07, 0x48, + 0x65, 0x58, 0x85, 0x84, 0x78, 0x64, 0x67, 0x63, 0x74, 0x73, 0x06, 0x05, + 0x44, 0x37, 0x87, 0x83, 0x46, 0x42, 0x54, 0x53, 0x18, 0x17, 0x36, 0x34, + 0x66, 0x55, 0x38, 0x24, 0x56, 0x41, 0x02, 0x01, 0x20, 0x14, 0x16, 0x12, + 0x61, 0x27, 0x26, 0x15, 0x31, 0x28, 0x21, 0x88, 0x82, 0x62, 0x60, 0x76, + 0x70, 0x33, 0x10, 0x52, 0x35, 0x71, 0x51, 0x81, 0x77, + }, + { + 0x16, 0x12, 0x61, 0x22, 0x51, 0x21, 0x15, 0x52, 0x31, 0x55, 0x81, 0x66, + 0x46, 0x42, 0x62, 0x54, 0x14, 0x01, 0x25, 0x23, 0x27, 0x13, 0x56, 0x41, + 0x35, 0x33, 0x58, 0x53, 0x26, 0x10, 0x32, 0x28, 0x84, 0x77, 0x43, 0x00, + 0x68, 0x47, 0x85, 0x45, 0x34, 0x57, 0x50, 0x05, 0x03, 0x37, 0x30, 0x87, + 0x86, 0x76, 0x08, 0x07, 0x80, 0x75, 0x70, 0x73, 0x04, 0x78, 0x74, 0x63, + 0x48, 0x71, 0x67, 0x82, 0x65, 0x17, 0x06, 0x24, 0x20, 0x88, 0x83, 0x60, + 0x44, 0x40, 0x72, 0x64, 0x18, 0x02, 0x38, 0x36, 0x11, + }, + { + 0x66, 0x01, 0x14, 0x03, 0x24, 0x23, 0x62, 0x08, 0x04, 0x35, 0x20, 0x72, + 0x63, 0x58, 0x70, 0x68, 0x48, 0x45, 0x54, 0x53, 0x26, 0x25, 0x65, 0x44, + 0x13, 0x05, 0x51, 0x41, 0x61, 0x16, 0x12, 0x10, 0x06, 0x28, 0x27, 0x60, + 0x40, 0x32, 0x56, 0x52, 0x17, 0x00, 0x31, 0x18, 0x73, 0x30, 0x75, 0x74, + 0x88, 0x84, 0x83, 0x86, 0x80, 0x85, 0x43, 0x38, 0x87, 0x47, 0x76, 0x71, + 0x50, 0x37, 0x78, 0x57, 0x82, 0x77, 0x67, 0x33, 0x07, 0x36, 0x34, 0x81, + 0x46, 0x42, 0x64, 0x55, 0x15, 0x02, 0x22, 0x21, 0x11, + }, + { + 0x22, 0x00, 0x11, 0x01, 0x20, 0x08, 0x88, 0x62, 0x27, 0x02, 0x07, 0x06, + 0x21, 0x12, 0x28, 0x87, 0x66, 0x32, 0x30, 0x38, 0x33, 0x15, 0x14, 0x25, + 0x17, 0x26, 0x24, 0x60, 0x42, 0x78, 0x71, 0x84, 0x81, 0x44, 0x23, 0x52, + 0x50, 0x80, 0x70, 0x35, 0x13, 0x48, 0x46, 0x83, 0x51, 0x40, 0x64, 0x61, + 0x55, 0x47, 0x74, 0x58, 0x18, 0x03, 0x41, 0x31, 0x73, 0x68, 0x43, 0x36, + 0x57, 0x45, 0x85, 0x56, 0x54, 0x67, 0x65, 0x76, 0x75, 0x37, 0x34, 0x63, + 0x53, 0x86, 0x77, 0x72, 0x05, 0x04, 0x16, 0x10, 0x82, + }, + { + 0x22, 0x12, 0x27, 0x21, 0x14, 0x01, 0x20, 0x15, 0x62, 0x02, 0x00, 0x16, + 0x10, 0x60, 0x17, 0x72, 0x66, 0x28, 0x07, 0x06, 0x18, 0x13, 0x82, 0x55, + 0x40, 0x78, 0x71, 0x25, 0x23, 0x32, 0x31, 0x42, 0x26, 0x61, 0x52, 0x24, + 0x08, 0x50, 0x44, 0x77, 0x37, 0x34, 0x63, 0x57, 0x87, 0x84, 0x80, 0x86, + 0x83, 0x45, 0x36, 0x85, 0x73, 0x70, 0x68, 0x81, 0x74, 0x33, 0x03, 0x38, + 0x35, 0x88, 0x56, 0x54, 0x76, 0x75, 0x46, 0x43, 0x53, 0x48, 0x64, 0x51, + 0x58, 0x47, 0x67, 0x65, 0x05, 0x04, 0x41, 0x30, 0x11, + }, + { + 0x44, 0x40, 0x66, 0x60, 0x23, 0x16, 0x32, 0x30, 0x07, 0x06, 0x18, 0x14, + 0x86, 0x50, 0x47, 0x75, 0x55, 0x33, 0x31, 0x41, 0x35, 0x80, 0x70, 0x84, + 0x83, 0x78, 0x71, 0x87, 0x81, 0x77, 0x12, 0x38, 0x25, 0x52, 0x51, 0x08, + 0x01, 0x17, 0x15, 0x58, 0x54, 0x68, 0x67, 0x34, 0x13, 0x48, 0x46, 0x04, + 0x03, 0x36, 0x05, 0x85, 0x56, 0x45, 0x65, 0x57, 0x73, 0x43, 0x37, 0x63, + 0x53, 0x64, 0x61, 0x76, 0x74, 0x24, 0x10, 0x62, 0x42, 0x21, 0x11, 0x02, + 0x00, 0x26, 0x20, 0x88, 0x28, 0x27, 0x82, 0x72, 0x22, + }, + { + 0x28, 0x27, 0x71, 0x70, 0x87, 0x78, 0x82, 0x22, 0x77, 0x72, 0x07, 0x01, + 0x14, 0x08, 0x81, 0x66, 0x62, 0x80, 0x75, 0x40, 0x25, 0x51, 0x50, 0x02, + 0x00, 0x26, 0x20, 0x42, 0x24, 0x52, 0x44, 0x16, 0x10, 0x23, 0x17, 0x64, + 0x60, 0x86, 0x83, 0x46, 0x41, 0x55, 0x54, 0x48, 0x47, 0x58, 0x56, 0x18, + 0x04, 0x35, 0x31, 0x57, 0x38, 0x34, 0x03, 0x63, 0x53, 0x67, 0x13, 0x05, + 0x36, 0x33, 0x73, 0x61, 0x43, 0x37, 0x68, 0x65, 0x45, 0x85, 0x76, 0x74, + 0x15, 0x06, 0x32, 0x30, 0x84, 0x12, 0x11, 0x88, 0x21, + }, + { + 0x82, 0x27, 0x08, 0x07, 0x16, 0x10, 0x62, 0x76, 0x74, 0x50, 0x41, 0x86, + 0x67, 0x15, 0x14, 0x38, 0x17, 0x40, 0x23, 0x61, 0x42, 0x11, 0x02, 0x26, + 0x20, 0x72, 0x77, 0x28, 0x12, 0x01, 0x60, 0x24, 0x88, 0x52, 0x44, 0x75, + 0x64, 0x25, 0x06, 0x32, 0x30, 0x55, 0x51, 0x68, 0x58, 0x46, 0x33, 0x48, + 0x47, 0x43, 0x37, 0x56, 0x54, 0x13, 0x03, 0x35, 0x34, 0x85, 0x73, 0x65, + 0x63, 0x45, 0x36, 0x57, 0x53, 0x83, 0x80, 0x05, 0x04, 0x31, 0x18, 0x84, + 0x70, 0x66, 0x87, 0x81, 0x21, 0x00, 0x78, 0x71, 0x22, + }, + { + 0x84, 0x81, 0x32, 0x25, 0x86, 0x83, 0x10, 0x04, 0x23, 0x14, 0x62, 0x26, + 0x70, 0x66, 0x42, 0x24, 0x64, 0x44, 0x87, 0x75, 0x71, 0x85, 0x80, 0x55, + 0x52, 0x67, 0x61, 0x50, 0x48, 0x58, 0x51, 0x18, 0x15, 0x38, 0x30, 0x33, + 0x31, 0x65, 0x41, 0x05, 0x03, 0x13, 0x08, 0x37, 0x36, 0x53, 0x43, 0x60, + 0x73, 0x68, 0x63, 0x57, 0x45, 0x35, 0x56, 0x54, 0x78, 0x76, 0x40, 0x34, + 0x47, 0x46, 0x06, 0x01, 0x17, 0x07, 0x77, 0x28, 0x02, 0x00, 0x12, 0x11, + 0x88, 0x72, 0x27, 0x20, 0x16, 0x74, 0x21, 0x82, 0x22, + }, + { + 0x77, 0x12, 0x81, 0x78, 0x72, 0x38, 0x33, 0x50, 0x44, 0x23, 0x01, 0x31, + 0x25, 0x34, 0x13, 0x37, 0x35, 0x86, 0x58, 0x55, 0x73, 0x68, 0x43, 0x04, + 0x54, 0x53, 0x64, 0x46, 0x65, 0x63, 0x57, 0x45, 0x67, 0x05, 0x03, 0x56, + 0x36, 0x62, 0x52, 0x83, 0x66, 0x42, 0x32, 0x80, 0x71, 0x10, 0x08, 0x24, + 0x16, 0x87, 0x18, 0x17, 0x47, 0x41, 0x07, 0x06, 0x15, 0x14, 0x75, 0x74, + 0x85, 0x76, 0x51, 0x48, 0x61, 0x60, 0x40, 0x30, 0x84, 0x70, 0x22, 0x82, + 0x28, 0x21, 0x11, 0x02, 0x00, 0x26, 0x20, 0x27, 0x88, + }, + { + 0x72, 0x27, 0x87, 0x81, 0x42, 0x33, 0x52, 0x50, 0x16, 0x08, 0x31, 0x23, + 0x02, 0x00, 0x78, 0x20, 0x82, 0x88, 0x28, 0x38, 0x32, 0x71, 0x62, 0x24, + 0x10, 0x30, 0x26, 0x64, 0x61, 0x76, 0x75, 0x44, 0x18, 0x58, 0x55, 0x54, + 0x48, 0x45, 0x43, 0x57, 0x46, 0x73, 0x35, 0x34, 0x37, 0x36, 0x04, 0x03, + 0x13, 0x05, 0x85, 0x65, 0x63, 0x68, 0x67, 0x47, 0x41, 0x56, 0x53, 0x70, + 0x60, 0x07, 0x06, 0x15, 0x14, 0x84, 0x83, 0x80, 0x66, 0x51, 0x86, 0x74, + 0x17, 0x01, 0x40, 0x25, 0x12, 0x11, 0x77, 0x21, 0x22, + }, + { + 0x27, 0x21, 0x88, 0x72, 0x28, 0x12, 0x11, 0x83, 0x77, 0x82, 0x80, 0x78, + 0x25, 0x24, 0x38, 0x32, 0x08, 0x01, 0x18, 0x16, 0x20, 0x02, 0x26, 0x23, + 0x81, 0x74, 0x86, 0x84, 0x10, 0x00, 0x62, 0x61, 0x04, 0x03, 0x13, 0x06, + 0x76, 0x58, 0x51, 0x64, 0x60, 0x31, 0x17, 0x41, 0x35, 0x44, 0x42, 0x70, + 0x66, 0x33, 0x15, 0x48, 0x40, 0x87, 0x65, 0x55, 0x67, 0x63, 0x54, 0x07, + 0x57, 0x56, 0x46, 0x45, 0x50, 0x47, 0x73, 0x68, 0x30, 0x14, 0x53, 0x43, + 0x75, 0x71, 0x52, 0x34, 0x05, 0x37, 0x36, 0x85, 0x22, + }, + { + 0x21, 0x14, 0x32, 0x27, 0x10, 0x72, 0x67, 0x82, 0x77, 0x44, 0x40, 0x54, + 0x45, 0x41, 0x37, 0x68, 0x56, 0x08, 0x01, 0x24, 0x13, 0x78, 0x48, 0x04, + 0x03, 0x43, 0x05, 0x81, 0x25, 0x07, 0x47, 0x35, 0x34, 0x06, 0x46, 0x36, + 0x88, 0x84, 0x83, 0x75, 0x74, 0x76, 0x73, 0x86, 0x85, 0x70, 0x65, 0x80, + 0x71, 0x57, 0x53, 0x87, 0x63, 0x51, 0x50, 0x23, 0x18, 0x33, 0x31, 0x61, + 0x12, 0x62, 0x22, 0x02, 0x00, 0x17, 0x15, 0x66, 0x55, 0x42, 0x64, 0x58, + 0x26, 0x20, 0x38, 0x30, 0x28, 0x16, 0x60, 0x52, 0x11, + }, + { + 0x61, 0x15, 0x27, 0x25, 0x32, 0x28, 0x06, 0x01, 0x24, 0x17, 0x78, 0x75, + 0x87, 0x80, 0x85, 0x08, 0x07, 0x73, 0x70, 0x48, 0x47, 0x84, 0x83, 0x81, + 0x71, 0x88, 0x86, 0x76, 0x74, 0x30, 0x04, 0x43, 0x37, 0x82, 0x72, 0x67, + 0x20, 0x03, 0x57, 0x45, 0x77, 0x52, 0x36, 0x41, 0x38, 0x68, 0x58, 0x05, + 0x00, 0x34, 0x33, 0x55, 0x26, 0x60, 0x56, 0x11, 0x66, 0x16, 0x64, 0x51, + 0x10, 0x02, 0x23, 0x18, 0x62, 0x54, 0x53, 0x65, 0x63, 0x40, 0x35, 0x50, + 0x42, 0x31, 0x13, 0x46, 0x44, 0x14, 0x12, 0x22, 0x21, + }, + { + 0x22, 0x21, 0x12, 0x01, 0x16, 0x15, 0x82, 0x88, 0x87, 0x42, 0x40, 0x60, + 0x44, 0x06, 0x05, 0x31, 0x10, 0x66, 0x61, 0x83, 0x76, 0x26, 0x25, 0x72, + 0x27, 0x81, 0x11, 0x46, 0x41, 0x84, 0x62, 0x13, 0x02, 0x24, 0x20, 0x80, + 0x75, 0x65, 0x63, 0x68, 0x54, 0x37, 0x07, 0x57, 0x30, 0x50, 0x52, 0x48, + 0x73, 0x67, 0x74, 0x55, 0x53, 0x47, 0x58, 0x56, 0x34, 0x04, 0x43, 0x38, + 0x70, 0x64, 0x17, 0x00, 0x45, 0x36, 0x78, 0x86, 0x85, 0x33, 0x32, 0x51, + 0x35, 0x08, 0x03, 0x18, 0x14, 0x28, 0x23, 0x77, 0x71, + }, }; static const uint8_t aic_mode2_vlc_bits[AIC_MODE2_NUM][AIC_MODE2_SIZE] = { -{ 1, 5, 4, 10, 6, 8, 5, 8, 8, - 7, 5, 7, 11, 10, 9, 8, 13, 11, - 6, 7, 3, 9, 8, 10, 9, 8, 5, - 10, 9, 10, 10, 14, 12, 14, 14, 12, - 8, 9, 7, 12, 8, 14, 9, 9, 12, - 8, 9, 11, 11, 13, 9, 11, 14, 12, - 6, 7, 9, 13, 9, 12, 7, 10, 12, - 11, 12, 8, 15, 10, 15, 13, 7, 12, - 10, 10, 8, 10, 13, 13, 13, 11, 8, }, -{ 4, 6, 5, 11, 8, 10, 7, 11, 9, - 4, 1, 4, 9, 7, 7, 5, 9, 10, - 6, 7, 4, 9, 9, 10, 9, 9, 6, - 9, 10, 9, 10, 12, 12, 13, 12, 11, - 9, 9, 8, 12, 8, 14, 10, 11, 12, - 7, 8, 10, 11, 12, 9, 11, 13, 12, - 6, 7, 8, 12, 9, 12, 7, 11, 10, - 12, 12, 9, 14, 12, 15, 13, 8, 12, - 11, 11, 10, 12, 13, 15, 14, 12, 9, }, -{ 5, 7, 6, 12, 9, 11, 8, 11, 10, - 7, 5, 7, 11, 10, 9, 8, 12, 12, - 5, 5, 1, 8, 7, 10, 8, 6, 4, - 8, 8, 8, 9, 12, 11, 13, 12, 11, - 8, 9, 8, 12, 8, 13, 10, 11, 11, - 8, 9, 11, 12, 13, 11, 12, 14, 13, - 8, 9, 10, 14, 11, 14, 9, 13, 13, - 8, 9, 6, 11, 10, 14, 11, 6, 10, - 6, 6, 4, 8, 9, 10, 10, 8, 5, }, -{ 11, 7, 8, 10, 12, 9, 10, 14, 12, - 7, 1, 5, 7, 8, 6, 4, 10, 9, - 10, 5, 4, 8, 11, 8, 7, 6, 7, - 11, 6, 7, 8, 10, 8, 10, 11, 9, - 10, 8, 9, 13, 9, 12, 8, 11, 12, - 11, 4, 7, 8, 9, 6, 8, 12, 9, - 8, 5, 8, 12, 9, 10, 6, 12, 11, - 12, 12, 10, 15, 13, 13, 13, 10, 13, - 15, 10, 9, 10, 12, 13, 13, 10, 9, }, -{ 11, 8, 8, 11, 13, 10, 11, 15, 12, - 7, 1, 4, 7, 7, 5, 4, 8, 9, - 11, 5, 5, 8, 11, 9, 8, 7, 8, - 13, 7, 8, 9, 11, 9, 10, 12, 10, - 10, 9, 8, 13, 9, 12, 9, 11, 12, - 11, 5, 7, 9, 10, 6, 9, 13, 10, - 7, 4, 7, 11, 8, 9, 5, 10, 11, - 13, 11, 9, 15, 13, 15, 13, 8, 12, - 15, 10, 10, 12, 13, 14, 14, 12, 11, }, -{ 12, 9, 9, 12, 13, 11, 11, 14, 12, - 8, 2, 5, 7, 9, 6, 5, 10, 10, - 9, 4, 2, 7, 9, 7, 6, 5, 6, - 12, 6, 7, 8, 10, 8, 10, 11, 9, - 12, 9, 10, 13, 11, 12, 10, 14, 13, - 12, 6, 8, 10, 10, 7, 9, 12, 10, - 8, 5, 8, 11, 9, 10, 7, 11, 12, - 8, 6, 5, 11, 11, 11, 8, 6, 9, - 12, 6, 6, 8, 10, 10, 11, 8, 6, }, -{ 13, 9, 10, 12, 14, 12, 11, 15, 15, - 8, 1, 5, 7, 9, 6, 5, 11, 10, - 11, 6, 5, 9, 11, 9, 8, 7, 8, - 12, 6, 8, 8, 11, 8, 10, 12, 10, - 10, 7, 9, 13, 10, 11, 9, 13, 12, - 11, 3, 6, 8, 9, 4, 7, 11, 8, - 8, 5, 9, 12, 10, 9, 7, 12, 13, - 13, 12, 10, 14, 14, 15, 12, 11, 14, - 15, 7, 9, 8, 11, 11, 12, 10, 9, }, -{ 10, 5, 6, 9, 11, 7, 8, 12, 11, - 8, 1, 4, 7, 9, 6, 4, 10, 10, - 11, 6, 6, 9, 9, 9, 9, 8, 8, - 14, 10, 10, 12, 12, 11, 12, 13, 12, - 10, 7, 8, 12, 9, 11, 8, 12, 11, - 13, 7, 10, 11, 11, 8, 10, 13, 11, - 6, 3, 7, 11, 8, 9, 5, 10, 11, - 11, 11, 9, 14, 14, 14, 11, 10, 13, - 14, 10, 11, 13, 13, 13, 14, 12, 12, }, -{ 2, 5, 3, 11, 8, 8, 6, 6, 7, - 8, 5, 6, 12, 10, 10, 8, 10, 11, - 7, 6, 2, 9, 8, 10, 8, 5, 4, - 10, 11, 10, 10, 13, 12, 14, 13, 10, - 10, 11, 8, 14, 9, 14, 12, 11, 12, - 9, 10, 9, 13, 12, 11, 12, 14, 11, - 8, 10, 7, 13, 10, 12, 8, 12, 12, - 10, 9, 6, 12, 11, 11, 11, 6, 9, - 10, 9, 6, 10, 9, 12, 11, 8, 7, }, -{ 6, 8, 6, 12, 11, 11, 10, 10, 9, - 6, 1, 3, 10, 8, 8, 6, 7, 10, - 8, 6, 3, 10, 9, 10, 8, 6, 5, - 11, 10, 10, 12, 13, 12, 14, 13, 12, - 10, 11, 8, 12, 9, 14, 12, 11, 12, - 9, 9, 8, 12, 12, 10, 12, 13, 11, - 7, 8, 6, 13, 9, 11, 7, 11, 11, - 11, 10, 7, 14, 11, 12, 12, 7, 10, - 12, 11, 8, 13, 12, 14, 13, 11, 10, }, -{ 7, 10, 7, 13, 13, 13, 11, 11, 10, - 8, 5, 6, 12, 11, 10, 9, 10, 11, - 7, 5, 1, 9, 8, 10, 7, 4, 4, - 9, 11, 9, 11, 12, 11, 13, 13, 10, - 9, 11, 8, 13, 9, 14, 12, 11, 12, - 11, 10, 10, 13, 12, 11, 14, 14, 12, - 9, 10, 8, 13, 10, 14, 9, 12, 12, - 9, 7, 4, 12, 10, 11, 10, 6, 7, - 9, 7, 4, 9, 9, 11, 9, 7, 5, }, -{ 7, 9, 7, 14, 11, 12, 10, 9, 9, - 8, 5, 5, 12, 9, 10, 8, 8, 11, - 7, 5, 2, 8, 8, 9, 7, 4, 4, - 10, 11, 10, 12, 14, 11, 12, 13, 12, - 9, 10, 8, 13, 8, 13, 10, 11, 11, - 9, 9, 8, 14, 10, 10, 11, 12, 11, - 10, 11, 9, 14, 10, 14, 9, 12, 14, - 6, 6, 3, 11, 8, 9, 8, 3, 6, - 9, 7, 4, 10, 8, 11, 10, 6, 5, }, -{ 6, 8, 7, 13, 12, 12, 10, 9, 9, - 9, 7, 8, 13, 11, 11, 9, 11, 12, - 7, 6, 1, 9, 8, 10, 7, 5, 4, - 10, 12, 10, 12, 13, 13, 14, 13, 11, - 9, 11, 9, 13, 10, 14, 12, 12, 12, - 11, 12, 10, 14, 13, 12, 13, 14, 12, - 8, 9, 7, 13, 10, 13, 8, 11, 12, - 8, 6, 3, 12, 9, 10, 9, 4, 6, - 10, 8, 5, 10, 10, 12, 11, 8, 6, }, -{ 7, 10, 7, 12, 9, 12, 10, 10, 12, - 9, 7, 7, 12, 9, 11, 6, 10, 11, - 6, 6, 1, 9, 8, 9, 7, 4, 5, - 11, 12, 9, 12, 10, 14, 13, 13, 11, - 10, 12, 8, 13, 8, 14, 10, 10, 11, - 11, 11, 10, 13, 14, 10, 14, 13, 11, - 11, 10, 7, 13, 8, 12, 7, 10, 12, - 7, 10, 4, 12, 6, 10, 8, 5, 8, - 10, 7, 4, 9, 7, 10, 9, 6, 5, }, -{ 7, 9, 7, 13, 12, 13, 10, 10, 8, - 8, 5, 6, 11, 10, 10, 8, 10, 10, - 7, 5, 2, 9, 8, 9, 7, 5, 3, - 8, 9, 7, 9, 11, 11, 13, 11, 9, - 8, 10, 7, 12, 9, 14, 11, 10, 10, - 9, 10, 9, 12, 12, 12, 13, 14, 12, - 10, 10, 9, 13, 11, 13, 9, 13, 12, - 8, 7, 4, 12, 10, 10, 10, 6, 6, - 7, 6, 3, 9, 8, 10, 9, 6, 3, }, -{ 7, 10, 7, 13, 13, 13, 11, 11, 9, - 8, 6, 6, 13, 11, 11, 9, 10, 11, - 7, 6, 1, 9, 8, 10, 8, 5, 4, - 8, 9, 8, 9, 12, 12, 12, 12, 8, - 10, 13, 9, 14, 11, 14, 14, 13, 12, - 9, 10, 9, 13, 12, 11, 13, 14, 11, - 9, 11, 8, 13, 11, 13, 10, 13, 13, - 9, 8, 5, 12, 10, 11, 11, 6, 7, - 8, 7, 3, 8, 9, 11, 10, 7, 4, }, -{ 8, 9, 7, 11, 11, 12, 11, 14, 9, - 8, 6, 6, 11, 13, 10, 9, 11, 9, - 7, 5, 1, 7, 9, 9, 7, 5, 3, - 13, 11, 9, 10, 12, 11, 12, 12, 9, - 10, 11, 9, 13, 9, 12, 12, 12, 10, - 12, 11, 10, 13, 14, 12, 14, 14, 11, - 11, 8, 8, 13, 11, 12, 9, 13, 11, - 9, 10, 5, 11, 8, 11, 9, 6, 7, - 7, 8, 4, 6, 8, 10, 8, 8, 5, }, -{ 8, 10, 8, 13, 13, 13, 12, 11, 10, - 5, 1, 3, 10, 7, 8, 6, 8, 9, - 8, 7, 4, 9, 10, 11, 8, 7, 6, - 8, 9, 7, 9, 12, 11, 12, 10, 8, - 9, 10, 8, 13, 9, 9, 12, 11, 11, - 7, 7, 6, 12, 9, 8, 10, 12, 8, - 6, 7, 4, 12, 8, 13, 6, 9, 10, - 13, 13, 9, 15, 14, 14, 15, 9, 11, - 13, 11, 9, 13, 13, 15, 15, 12, 10, }, -{ 10, 8, 9, 11, 12, 10, 8, 13, 13, - 9, 2, 5, 7, 5, 4, 3, 8, 9, - 11, 5, 5, 9, 8, 8, 6, 8, 8, - 12, 7, 8, 10, 10, 9, 8, 12, 10, - 9, 10, 9, 12, 7, 11, 7, 12, 12, - 9, 5, 8, 9, 9, 6, 6, 11, 10, - 6, 4, 7, 9, 5, 9, 3, 9, 10, - 13, 11, 9, 13, 10, 13, 10, 9, 13, - 14, 11, 10, 12, 12, 13, 11, 14, 11, }, -{ 11, 7, 8, 10, 12, 9, 9, 14, 10, - 9, 4, 7, 8, 10, 7, 7, 11, 10, - 8, 2, 2, 6, 8, 5, 5, 5, 6, - 15, 9, 10, 10, 12, 10, 11, 14, 12, - 9, 8, 9, 12, 9, 11, 8, 12, 11, - 14, 10, 11, 12, 13, 10, 12, 15, 12, - 9, 7, 8, 12, 9, 12, 7, 11, 13, - 9, 6, 5, 11, 10, 11, 7, 6, 9, - 11, 4, 5, 7, 8, 8, 8, 7, 7, }, + { + 5, 5, 5, 5, 3, 6, 6, 8, 8, 8, 8, 6, 4, 7, 7, 9, 9, + 9, 9, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, + 11, 11, 11, 11, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 14, 14, 14, 14, 12, 13, 13, 15, 15, 14, 13, 12, 12, 12, 12, 11, 11, + 13, 13, 13, 13, 11, 10, 10, 12, 12, 12, 12, 10, 1, + }, + { + 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 13, 13, 13, 13, 11, 12, 12, 14, 14, 15, 15, 14, + 12, 11, 11, 11, 11, 12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 12, 12, + 12, 9, 9, 11, 11, 11, 11, 9, 6, 6, 6, 6, 5, 5, 7, 7, 9, + 9, 9, 9, 7, 7, 7, 7, 7, 4, 4, 4, 4, 1, + }, + { + 7, 7, 7, 7, 5, 8, 8, 10, 10, 10, 10, 8, 8, 8, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 12, 12, 12, 12, 10, 13, 13, 14, 14, 14, + 14, 13, 13, 13, 13, 12, 12, 12, 12, 10, 10, 10, 10, 11, 11, 11, 11, + 9, 11, 11, 11, 11, 11, 11, 11, 11, 5, 5, 5, 5, 4, 4, 6, 6, + 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 1, + }, + { + 9, 9, 11, 11, 13, 13, 13, 13, 11, 11, 11, 11, 11, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 10, 12, 12, 13, 13, + 15, 15, 14, 13, 12, 12, 12, 12, 10, 10, 10, 10, 7, 7, 9, 9, 9, + 9, 7, 8, 8, 8, 8, 6, 8, 8, 8, 8, 8, 8, 8, 8, 5, 5, + 7, 7, 7, 7, 5, 4, 4, 6, 6, 6, 6, 4, 1, + }, + { + 7, 7, 7, 7, 5, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 10, 13, 13, 13, 13, 13, 13, 13, 13, + 12, 12, 14, 14, 15, 15, 15, 15, 12, 9, 9, 11, 11, 11, 11, 9, 7, + 7, 7, 7, 5, 5, 5, 5, 4, 4, 8, 8, 8, 8, 6, 8, 8, 10, + 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 4, 1, + }, + { + 2, 2, 7, 7, 7, 7, 5, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, + 12, 12, 13, 13, 14, 14, 13, 10, 10, 10, 10, 9, 9, 11, 11, 11, 11, + 11, 11, 11, 11, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 7, 7, 9, + 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 6, 6, 6, 6, 4, 6, + 6, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, + }, + { + 5, 5, 5, 5, 3, 6, 6, 6, 6, 4, 7, 7, 9, 9, 9, 9, 9, + 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 11, 11, + 13, 13, 13, 13, 11, 11, 11, 11, 11, 12, 12, 12, 12, 10, 12, 12, 15, + 15, 15, 15, 13, 14, 14, 14, 14, 12, 12, 12, 12, 9, 9, 11, 11, 11, + 11, 9, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 1, + }, + { + 5, 5, 9, 9, 9, 9, 7, 11, 11, 11, 11, 9, 11, 11, 11, 11, 11, + 11, 11, 11, 9, 9, 9, 9, 7, 7, 7, 7, 3, 4, 4, 8, 8, 8, + 8, 6, 10, 10, 10, 10, 10, 10, 10, 10, 14, 14, 14, 14, 12, 13, 13, + 14, 14, 13, 12, 12, 12, 12, 11, 11, 13, 13, 13, 13, 11, 10, 10, 12, + 12, 12, 12, 10, 8, 8, 8, 8, 6, 6, 6, 6, 1, + }, + { + 2, 2, 5, 5, 7, 7, 7, 7, 5, 3, 6, 6, 6, 6, 4, 8, 8, + 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 10, 10, 12, 12, 12, 12, 10, 10, 10, 10, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 12, 12, 14, 14, 14, 14, 12, 12, 12, 12, 12, 11, + 11, 13, 13, 13, 13, 11, 6, 6, 8, 8, 8, 8, 6, + }, + { + 3, 3, 6, 6, 8, 8, 8, 8, 6, 6, 6, 6, 6, 7, 7, 7, 7, + 5, 10, 10, 10, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, + 8, 9, 9, 9, 9, 7, 13, 13, 13, 13, 11, 12, 12, 13, 13, 14, 14, + 14, 14, 11, 11, 11, 11, 12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 12, + 12, 12, 9, 9, 11, 11, 11, 11, 11, 11, 11, 11, 1, + }, + { + 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 9, 11, 11, 11, 11, + 11, 11, 11, 11, 9, 9, 9, 9, 7, 7, 7, 7, 6, 6, 10, 10, 10, + 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 11, 14, 14, 14, 14, 12, 13, 13, 13, 13, 10, 10, 10, 10, 8, 8, 8, + 8, 5, 5, 7, 7, 7, 7, 5, 4, 4, 4, 4, 1, + }, + { + 4, 4, 6, 6, 6, 6, 4, 2, 3, 3, 9, 9, 9, 9, 7, 9, 9, + 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, + 8, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 14, 14, 14, 14, 12, 12, 12, 12, 12, 11, 11, 13, 13, 14, 14, + 13, 11, 8, 8, 10, 10, 10, 10, 8, 5, 5, 5, 5, + }, + { + 5, 5, 9, 9, 9, 9, 7, 9, 9, 11, 11, 11, 11, 11, 11, 11, 11, + 9, 9, 9, 9, 7, 7, 7, 7, 3, 4, 4, 8, 8, 8, 8, 6, 10, + 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, + 13, 13, 13, 13, 13, 13, 12, 12, 13, 13, 14, 14, 14, 14, 10, 10, 12, + 12, 12, 12, 10, 8, 8, 8, 8, 6, 6, 6, 6, 1, + }, + { + 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, + 8, 6, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 11, 12, 12, 13, + 13, 14, 14, 14, 14, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 5, 5, + 7, 7, 7, 7, 5, 4, 4, 6, 6, 6, 6, 4, 1, + }, + { + 6, 6, 6, 6, 4, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, + 9, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 13, 13, 14, 14, 13, 13, + 13, 13, 13, 9, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, 8, 6, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, + 8, 8, 2, 3, 3, 5, 5, 7, 7, 7, 7, 5, 3, + }, + { + 5, 5, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 3, + 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11, 11, 11, + 11, 12, 12, 14, 14, 14, 14, 12, 12, 12, 12, 12, 13, 13, 13, 13, 11, + 13, 13, 13, 13, 13, 13, 13, 13, 9, 9, 11, 11, 11, 11, 9, 8, 8, + 10, 10, 10, 10, 10, 10, 10, 10, 6, 6, 6, 6, 1, + }, + { + 5, 5, 5, 5, 3, 6, 6, 6, 6, 4, 7, 7, 9, 9, 9, 9, 9, + 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 11, 11, + 11, 11, 9, 11, 11, 11, 11, 11, 11, 11, 11, 9, 9, 9, 9, 10, 10, + 10, 10, 8, 12, 12, 13, 13, 14, 14, 14, 14, 12, 12, 12, 12, 11, 11, + 13, 13, 13, 13, 11, 10, 10, 12, 12, 12, 12, 10, 1, + }, + { + 7, 7, 7, 7, 5, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, + 10, 10, 10, 10, 11, 11, 13, 13, 13, 13, 11, 11, 11, 11, 11, 12, 12, + 12, 12, 10, 13, 13, 14, 14, 15, 15, 15, 15, 13, 13, 13, 13, 12, 12, + 12, 12, 7, 7, 9, 9, 9, 9, 7, 3, 4, 4, 8, 8, 8, 8, 6, + 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 1, + }, + { + 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 13, 13, 14, 14, 13, 13, 13, + 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 12, 12, 12, 12, 10, + 9, 9, 11, 11, 11, 11, 9, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, + 6, 6, 6, 6, 2, 3, 3, 5, 5, 9, 9, 9, 9, 7, 9, 9, 9, + 9, 9, 9, 9, 9, 7, 7, 7, 7, 5, 5, 5, 5, + }, + { + 2, 2, 7, 7, 7, 7, 5, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, + 7, 7, 7, 7, 5, 5, 5, 5, 4, 4, 8, 8, 8, 8, 8, 8, 8, + 8, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 14, 11, 11, 11, 11, 10, + 10, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 11, 11, 11, 11, 9, 8, + 8, 10, 10, 10, 10, 10, 10, 10, 10, 6, 6, 6, 6, + }, }; //@} @@ -428,206 +385,178 @@ static const uint8_t aic_mode2_vlc_bits[AIC_MODE2_NUM][AIC_MODE2_SIZE] = { #define AIC_MODE1_SIZE 9 #define AIC_MODE1_BITS 7 -static const uint8_t aic_mode1_vlc_codes[AIC_MODE1_NUM][AIC_MODE1_SIZE] = { - { 0x01, 0x01, 0x01, 0x11, 0x00, 0x09, 0x03, 0x10, 0x05,}, - { 0x09, 0x01, 0x01, 0x05, 0x11, 0x00, 0x03, 0x21, 0x20,}, - { 0x01, 0x01, 0x01, 0x11, 0x09, 0x10, 0x05, 0x00, 0x03,}, - { 0x01, 0x01, 0x00, 0x03, 0x21, 0x05, 0x09, 0x20, 0x11,}, - { 0x01, 0x09, 0x00, 0x29, 0x08, 0x15, 0x03, 0x0B, 0x28,}, - { 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x02,}, - { 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x01, 0x09, 0x08,}, - { 0x01, 0x01, 0x01, 0x09, 0x01, 0x08, 0x00, 0x03, 0x05,}, - { 0x01, 0x01, 0x01, 0x00, 0x05, 0x11, 0x09, 0x10, 0x03,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x01, 0x01, 0x05, 0x01, 0x00, 0x03, 0x09, 0x08,}, - { 0x09, 0x01, 0x01, 0x05, 0x11, 0x00, 0x03, 0x21, 0x20,}, - { 0x01, 0x01, 0x01, 0x0D, 0x05, 0x04, 0x00, 0x07, 0x0C,}, - { 0x01, 0x01, 0x00, 0x05, 0x11, 0x03, 0x09, 0x21, 0x20,}, - { 0x05, 0x01, 0x01, 0x11, 0x00, 0x09, 0x03, 0x21, 0x20,}, - { 0x09, 0x01, 0x01, 0x00, 0x05, 0x01, 0x03, 0x11, 0x10,}, - { 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x02,}, - { 0x01, 0x01, 0x01, 0x09, 0x00, 0x05, 0x01, 0x03, 0x08,}, - { 0x01, 0x01, 0x01, 0x09, 0x11, 0x05, 0x00, 0x10, 0x03,}, - { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x00, 0x01, 0x09, 0x08, 0x15, 0x14, 0x0B, 0x03,}, - { 0x0D, 0x01, 0x01, 0x05, 0x0C, 0x04, 0x01, 0x00, 0x07,}, - { 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x03, 0x01, 0x01,}, - { 0x05, 0x01, 0x01, 0x04, 0x19, 0x07, 0x18, 0x0D, 0x00,}, - { 0x11, 0x09, 0x01, 0x21, 0x05, 0x20, 0x01, 0x00, 0x03,}, - { 0x41, 0x01, 0x00, 0x05, 0x40, 0x03, 0x09, 0x21, 0x11,}, - { 0x29, 0x01, 0x00, 0x28, 0x09, 0x15, 0x03, 0x08, 0x0B,}, - { 0x01, 0x00, 0x01, 0x11, 0x09, 0x10, 0x05, 0x01, 0x03,}, - { 0x05, 0x01, 0x01, 0x04, 0x0D, 0x0C, 0x07, 0x00, 0x01,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x00, 0x03, 0x05, 0x11, 0x10, 0x25, 0x24, 0x13,}, - { 0x21, 0x01, 0x01, 0x00, 0x11, 0x03, 0x05, 0x20, 0x09,}, - { 0x01, 0x01, 0x01, 0x00, 0x09, 0x11, 0x10, 0x05, 0x03,}, - { 0x21, 0x05, 0x01, 0x01, 0x09, 0x00, 0x11, 0x20, 0x03,}, - { 0x05, 0x01, 0x00, 0x04, 0x01, 0x19, 0x07, 0x18, 0x0D,}, - { 0x11, 0x01, 0x00, 0x01, 0x09, 0x01, 0x03, 0x10, 0x05,}, - { 0x1D, 0x01, 0x05, 0x0D, 0x0C, 0x04, 0x00, 0x1C, 0x0F,}, - { 0x05, 0x19, 0x01, 0x04, 0x00, 0x18, 0x1B, 0x1A, 0x07,}, - { 0x09, 0x01, 0x00, 0x01, 0x05, 0x03, 0x11, 0x10, 0x01,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x00, 0x03, 0x41, 0x05, 0x40, 0x09, 0x11, 0x21,}, - { 0x05, 0x01, 0x01, 0x19, 0x04, 0x07, 0x00, 0x18, 0x0D,}, - { 0x01, 0x01, 0x01, 0x05, 0x01, 0x04, 0x01, 0x00, 0x03,}, - { 0x01, 0x05, 0x00, 0x0D, 0x01, 0x04, 0x07, 0x19, 0x18,}, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, - { 0x31, 0x01, 0x05, 0x19, 0x04, 0x07, 0x00, 0x30, 0x0D,}, - { 0x01, 0x00, 0x03, 0x11, 0x01, 0x05, 0x01, 0x09, 0x10,}, - { 0x01, 0x05, 0x01, 0x11, 0x01, 0x10, 0x00, 0x03, 0x09,}, - { 0x01, 0x09, 0x00, 0x29, 0x03, 0x08, 0x28, 0x15, 0x0B,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x01, 0x00, 0x09, 0x15, 0x03, 0x08, 0x14, 0x0B,}, - { 0x11, 0x01, 0x01, 0x00, 0x09, 0x01, 0x03, 0x10, 0x05,}, - { 0x01, 0x00, 0x03, 0x25, 0x11, 0x05, 0x10, 0x24, 0x13,}, - { 0x11, 0x01, 0x00, 0x01, 0x09, 0x01, 0x05, 0x10, 0x03,}, - { 0x05, 0x01, 0x00, 0x0D, 0x0C, 0x04, 0x0F, 0x1D, 0x1C,}, - { 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x02,}, - { 0x21, 0x01, 0x05, 0x09, 0x11, 0x00, 0x03, 0x41, 0x40,}, - { 0x05, 0x01, 0x00, 0x1D, 0x1C, 0x0D, 0x0C, 0x0F, 0x04,}, - { 0x05, 0x01, 0x00, 0x0D, 0x31, 0x04, 0x19, 0x30, 0x07,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x01, 0x00, 0x21, 0x05, 0x11, 0x03, 0x09, 0x20,}, - { 0x01, 0x01, 0x00, 0x11, 0x03, 0x05, 0x01, 0x09, 0x10,}, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, - { 0x05, 0x01, 0x04, 0x19, 0x07, 0x0D, 0x00, 0x31, 0x30,}, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, - { 0x05, 0x01, 0x01, 0x11, 0x09, 0x00, 0x03, 0x21, 0x20,}, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, - { 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x01, 0x01, 0x02,}, - { 0x09, 0x01, 0x00, 0x29, 0x08, 0x15, 0x03, 0x28, 0x0B,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x01, 0x01, 0x05, 0x01, 0x04, 0x00, 0x01, 0x03,}, - { 0x09, 0x01, 0x00, 0x29, 0x28, 0x15, 0x08, 0x03, 0x0B,}, - { 0x01, 0x00, 0x01, 0x11, 0x05, 0x10, 0x09, 0x01, 0x03,}, - { 0x05, 0x04, 0x01, 0x1D, 0x0D, 0x0C, 0x1C, 0x00, 0x0F,}, - { 0x09, 0x11, 0x01, 0x41, 0x00, 0x40, 0x05, 0x03, 0x21,}, - { 0x0D, 0x05, 0x01, 0x1D, 0x1C, 0x0C, 0x04, 0x00, 0x0F,}, - { 0x41, 0x09, 0x01, 0x40, 0x00, 0x11, 0x05, 0x03, 0x21,}, - { 0x01, 0x01, 0x01, 0x05, 0x01, 0x04, 0x00, 0x01, 0x03,}, - { 0x05, 0x04, 0x01, 0x0D, 0x01, 0x0C, 0x07, 0x01, 0x00,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x05, 0x04, 0x01, 0x07, 0x19, 0x31, 0x30, 0x0D, 0x00,}, - { 0x21, 0x01, 0x01, 0x00, 0x11, 0x09, 0x20, 0x05, 0x03,}, - { 0x05, 0x01, 0x01, 0x04, 0x07, 0x0D, 0x0C, 0x00, 0x01,}, - { 0x21, 0x09, 0x01, 0x00, 0x20, 0x05, 0x23, 0x22, 0x03,}, - { 0x31, 0x0D, 0x01, 0x19, 0x05, 0x30, 0x04, 0x07, 0x00,}, - { 0x31, 0x05, 0x01, 0x04, 0x19, 0x00, 0x0D, 0x30, 0x07,}, - { 0x31, 0x01, 0x00, 0x0D, 0x05, 0x19, 0x04, 0x30, 0x07,}, - { 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01,}, - { 0x01, 0x00, 0x01, 0x01, 0x05, 0x09, 0x08, 0x03, 0x01,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, -}; - -static const uint8_t aic_mode1_vlc_bits[AIC_MODE1_NUM][AIC_MODE1_SIZE] = { - { 1, 4, 2, 7, 4, 6, 4, 7, 5,}, - { 5, 1, 3, 4, 6, 3, 3, 7, 7,}, - { 1, 4, 2, 7, 6, 7, 5, 4, 4,}, - { 1, 3, 3, 3, 7, 4, 5, 7, 6,}, - { 2, 4, 2, 6, 4, 5, 2, 4, 6,}, - { 7, 2, 3, 4, 7, 1, 5, 7, 7,}, - { 5, 1, 3, 6, 5, 5, 2, 7, 7,}, - { 2, 5, 1, 7, 3, 7, 5, 5, 6,}, - { 2, 4, 1, 4, 5, 7, 6, 7, 4,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 2, 1, 3, 6, 5, 5, 5, 7, 7,}, - { 5, 1, 3, 4, 6, 3, 3, 7, 7,}, - { 4, 1, 2, 6, 5, 5, 4, 5, 6,}, - { 3, 1, 3, 4, 6, 3, 5, 7, 7,}, - { 4, 1, 3, 6, 3, 5, 3, 7, 7,}, - { 6, 1, 4, 4, 5, 2, 4, 7, 7,}, - { 7, 1, 5, 7, 4, 3, 2, 7, 7,}, - { 5, 3, 2, 7, 5, 6, 1, 5, 7,}, - { 4, 1, 2, 6, 7, 5, 4, 7, 4,}, - { 1, 0, 1, 0, 0, 0, 0, 0, 0,}, - - { 3, 3, 1, 5, 5, 6, 6, 5, 3,}, - { 6, 2, 1, 5, 6, 5, 4, 4, 5,}, - { 6, 4, 1, 7, 6, 7, 6, 3, 2,}, - { 4, 3, 1, 4, 6, 4, 6, 5, 3,}, - { 6, 5, 1, 7, 4, 7, 3, 3, 3,}, - { 7, 2, 2, 3, 7, 2, 4, 6, 5,}, - { 6, 2, 2, 6, 4, 5, 2, 4, 4,}, - { 4, 4, 1, 7, 6, 7, 5, 2, 4,}, - { 5, 4, 1, 5, 6, 6, 5, 4, 2,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 2, 2, 2, 3, 5, 5, 6, 6, 5,}, - { 7, 1, 3, 3, 6, 3, 4, 7, 5,}, - { 2, 4, 1, 4, 6, 7, 7, 5, 4,}, - { 7, 4, 3, 1, 5, 3, 6, 7, 3,}, - { 4, 3, 3, 4, 1, 6, 4, 6, 5,}, - { 7, 4, 4, 2, 6, 1, 4, 7, 5,}, - { 5, 2, 3, 4, 4, 3, 2, 5, 4,}, - { 3, 5, 2, 3, 2, 5, 5, 5, 3,}, - { 6, 4, 4, 2, 5, 4, 7, 7, 1,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 2, 2, 2, 7, 3, 7, 4, 5, 6,}, - { 4, 1, 3, 6, 4, 4, 3, 6, 5,}, - { 2, 4, 1, 7, 3, 7, 6, 6, 6,}, - { 3, 4, 3, 5, 1, 4, 4, 6, 6,}, - { 4, 5, 2, 7, 1, 7, 3, 7, 7,}, - { 6, 2, 3, 5, 3, 3, 2, 6, 4,}, - { 4, 4, 4, 7, 2, 5, 1, 6, 7,}, - { 4, 5, 2, 7, 1, 7, 4, 4, 6,}, - { 2, 4, 2, 6, 2, 4, 6, 5, 4,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 1, 3, 3, 5, 6, 3, 5, 6, 5,}, - { 7, 1, 4, 4, 6, 2, 4, 7, 5,}, - { 2, 2, 2, 6, 5, 3, 5, 6, 5,}, - { 7, 4, 4, 2, 6, 1, 5, 7, 4,}, - { 3, 2, 2, 4, 4, 3, 4, 5, 5,}, - { 7, 2, 5, 3, 7, 1, 4, 7, 7,}, - { 6, 2, 3, 4, 5, 2, 2, 7, 7,}, - { 3, 2, 2, 5, 5, 4, 4, 4, 3,}, - { 3, 2, 2, 4, 6, 3, 5, 6, 3,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 1, 3, 3, 7, 4, 6, 3, 5, 7,}, - { 4, 1, 4, 7, 4, 5, 2, 6, 7,}, - { 2, 4, 1, 7, 5, 7, 3, 7, 7,}, - { 3, 2, 3, 5, 3, 4, 2, 6, 6,}, - { 3, 5, 4, 7, 2, 7, 1, 7, 7,}, - { 4, 1, 3, 6, 5, 3, 3, 7, 7,}, - { 4, 2, 5, 7, 3, 7, 1, 7, 7,}, - { 7, 4, 1, 7, 3, 7, 2, 5, 7,}, - { 4, 2, 2, 6, 4, 5, 2, 6, 4,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 3, 4, 1, 7, 6, 7, 6, 2, 6,}, - { 4, 2, 2, 6, 6, 5, 4, 2, 4,}, - { 4, 4, 1, 7, 5, 7, 6, 2, 4,}, - { 3, 3, 2, 5, 4, 4, 5, 2, 4,}, - { 4, 5, 2, 7, 2, 7, 3, 2, 6,}, - { 4, 3, 2, 5, 5, 4, 3, 2, 4,}, - { 7, 4, 2, 7, 2, 5, 3, 2, 6,}, - { 4, 6, 2, 7, 3, 7, 6, 1, 6,}, - { 5, 5, 1, 6, 4, 6, 5, 2, 4,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 3, 3, 2, 3, 5, 6, 6, 4, 2,}, - { 7, 1, 3, 3, 6, 5, 7, 4, 3,}, - { 5, 4, 1, 5, 5, 6, 6, 4, 2,}, - { 6, 4, 2, 2, 6, 3, 6, 6, 2,}, - { 6, 4, 2, 5, 3, 6, 3, 3, 2,}, - { 6, 3, 2, 3, 5, 2, 4, 6, 3,}, - { 6, 2, 2, 4, 3, 5, 3, 6, 3,}, - { 7, 5, 1, 7, 4, 7, 7, 3, 2,}, - { 5, 5, 2, 3, 6, 7, 7, 5, 1,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, +static const uint8_t aic_mode1_vlc_tabs[AIC_MODE1_NUM][AIC_MODE1_SIZE][2] = { + { { 4, 4 }, { 1, 4 }, { 7, 7 }, { 3, 7 }, { 5, 6 }, + { 8, 5 }, { 6, 4 }, { 2, 2 }, { 0, 1 } }, + { { 5, 3 }, { 2, 3 }, { 8, 7 }, { 7, 7 }, { 4, 6 }, + { 0, 5 }, { 3, 4 }, { 6, 3 }, { 1, 1 } }, + { { 7, 4 }, { 1, 4 }, { 5, 7 }, { 3, 7 }, { 4, 6 }, + { 6, 5 }, { 8, 4 }, { 2, 2 }, { 0, 1 } }, + { { 2, 3 }, { 1, 3 }, { 7, 7 }, { 4, 7 }, { 8, 6 }, + { 6, 5 }, { 5, 4 }, { 3, 3 }, { 0, 1 } }, + { { 2, 2 }, { 0, 2 }, { 4, 4 }, { 1, 4 }, { 8, 6 }, + { 3, 6 }, { 5, 5 }, { 7, 4 }, { 6, 2 } }, + { { 4, 7 }, { 0, 7 }, { 8, 7 }, { 7, 7 }, { 6, 5 }, + { 3, 4 }, { 2, 3 }, { 1, 2 }, { 5, 1 } }, + { { 4, 5 }, { 0, 5 }, { 8, 7 }, { 7, 7 }, { 3, 6 }, + { 5, 5 }, { 2, 3 }, { 6, 2 }, { 1, 1 } }, + { { 6, 5 }, { 1, 5 }, { 5, 7 }, { 3, 7 }, { 8, 6 }, + { 7, 5 }, { 4, 3 }, { 0, 2 }, { 2, 1 } }, + { { 3, 4 }, { 1, 4 }, { 7, 7 }, { 5, 7 }, { 6, 6 }, + { 4, 5 }, { 8, 4 }, { 0, 2 }, { 2, 1 } }, + { { 0 } }, /* unused */ + { { 5, 5 }, { 4, 5 }, { 8, 7 }, { 7, 7 }, { 3, 6 }, + { 6, 5 }, { 2, 3 }, { 0, 2 }, { 1, 1 } }, + { { 5, 3 }, { 2, 3 }, { 8, 7 }, { 7, 7 }, { 4, 6 }, + { 0, 5 }, { 3, 4 }, { 6, 3 }, { 1, 1 } }, + { { 6, 4 }, { 0, 4 }, { 5, 5 }, { 4, 5 }, { 8, 6 }, + { 3, 6 }, { 7, 5 }, { 2, 2 }, { 1, 1 } }, + { { 2, 3 }, { 0, 3 }, { 8, 7 }, { 7, 7 }, { 4, 6 }, + { 6, 5 }, { 3, 4 }, { 5, 3 }, { 1, 1 } }, + { { 4, 3 }, { 2, 3 }, { 8, 7 }, { 7, 7 }, { 3, 6 }, + { 5, 5 }, { 0, 4 }, { 6, 3 }, { 1, 1 } }, + { { 3, 4 }, { 2, 4 }, { 8, 7 }, { 7, 7 }, { 0, 6 }, + { 4, 5 }, { 6, 4 }, { 5, 2 }, { 1, 1 } }, + { { 3, 7 }, { 0, 7 }, { 8, 7 }, { 7, 7 }, { 2, 5 }, + { 4, 4 }, { 5, 3 }, { 6, 2 }, { 1, 1 } }, + { { 4, 5 }, { 0, 5 }, { 8, 7 }, { 3, 7 }, { 5, 6 }, + { 7, 5 }, { 1, 3 }, { 2, 2 }, { 6, 1 } }, + { { 6, 4 }, { 0, 4 }, { 7, 7 }, { 4, 7 }, { 3, 6 }, + { 5, 5 }, { 8, 4 }, { 2, 2 }, { 1, 1 } }, + { { 2, 1 }, { 0, 1 } }, /* Unused */ + { { 1, 3 }, { 0, 3 }, { 4, 5 }, { 3, 5 }, { 6, 6 }, + { 5, 6 }, { 7, 5 }, { 8, 3 }, { 2, 1 } }, + { { 7, 4 }, { 6, 4 }, { 5, 5 }, { 3, 5 }, { 4, 6 }, + { 0, 6 }, { 8, 5 }, { 1, 2 }, { 2, 1 } }, + { { 4, 6 }, { 0, 6 }, { 5, 7 }, { 3, 7 }, { 6, 6 }, + { 1, 4 }, { 7, 3 }, { 8, 2 }, { 2, 1 } }, + { { 8, 3 }, { 1, 3 }, { 3, 4 }, { 0, 4 }, { 6, 6 }, + { 4, 6 }, { 7, 5 }, { 5, 4 }, { 2, 1 } }, + { { 7, 3 }, { 6, 3 }, { 5, 7 }, { 3, 7 }, { 0, 6 }, + { 1, 5 }, { 4, 4 }, { 8, 3 }, { 2, 1 } }, + { { 2, 2 }, { 1, 2 }, { 4, 7 }, { 0, 7 }, { 7, 6 }, + { 8, 5 }, { 6, 4 }, { 3, 3 }, { 5, 2 } }, + { { 2, 2 }, { 1, 2 }, { 7, 4 }, { 4, 4 }, { 3, 6 }, + { 0, 6 }, { 5, 5 }, { 8, 4 }, { 6, 2 } }, + { { 1, 4 }, { 0, 4 }, { 5, 7 }, { 3, 7 }, { 4, 6 }, + { 6, 5 }, { 8, 4 }, { 7, 2 }, { 2, 1 } }, + { { 7, 4 }, { 1, 4 }, { 3, 5 }, { 0, 5 }, { 5, 6 }, + { 4, 6 }, { 6, 5 }, { 8, 2 }, { 2, 1 } }, + { { 0 } }, /* unused */ + { { 1, 2 }, { 0, 2 }, { 5, 5 }, { 4, 5 }, { 7, 6 }, + { 6, 6 }, { 8, 5 }, { 3, 3 }, { 2, 2 } }, + { { 3, 3 }, { 2, 3 }, { 7, 7 }, { 0, 7 }, { 4, 6 }, + { 8, 5 }, { 6, 4 }, { 5, 3 }, { 1, 1 } }, + { { 3, 4 }, { 1, 4 }, { 6, 7 }, { 5, 7 }, { 4, 6 }, + { 7, 5 }, { 8, 4 }, { 0, 2 }, { 2, 1 } }, + { { 5, 3 }, { 2, 3 }, { 7, 7 }, { 0, 7 }, { 6, 6 }, + { 4, 5 }, { 1, 4 }, { 8, 3 }, { 3, 1 } }, + { { 2, 3 }, { 1, 3 }, { 3, 4 }, { 0, 4 }, { 7, 6 }, + { 5, 6 }, { 8, 5 }, { 6, 4 }, { 4, 1 } }, + { { 2, 4 }, { 1, 4 }, { 7, 7 }, { 0, 7 }, { 4, 6 }, + { 8, 5 }, { 6, 4 }, { 3, 2 }, { 5, 1 } }, + { { 6, 2 }, { 1, 2 }, { 5, 3 }, { 2, 3 }, { 4, 4 }, + { 3, 4 }, { 7, 5 }, { 0, 5 }, { 8, 4 } }, + { { 4, 2 }, { 2, 2 }, { 3, 3 }, { 0, 3 }, { 5, 5 }, + { 1, 5 }, { 7, 5 }, { 6, 5 }, { 8, 3 } }, + { { 2, 4 }, { 1, 4 }, { 7, 7 }, { 6, 7 }, { 0, 6 }, + { 4, 5 }, { 5, 4 }, { 3, 2 }, { 8, 1 } }, + { { 0 } }, /* unused */ + { { 1, 2 }, { 0, 2 }, { 5, 7 }, { 3, 7 }, { 8, 6 }, + { 7, 5 }, { 6, 4 }, { 4, 3 }, { 2, 2 } }, + { { 6, 3 }, { 2, 3 }, { 4, 4 }, { 0, 4 }, { 7, 6 }, + { 3, 6 }, { 8, 5 }, { 5, 4 }, { 1, 1 } }, + { { 7, 6 }, { 6, 6 }, { 5, 7 }, { 3, 7 }, { 8, 6 }, + { 1, 4 }, { 4, 3 }, { 0, 2 }, { 2, 1 } }, + { { 2, 3 }, { 0, 3 }, { 5, 4 }, { 1, 4 }, { 8, 6 }, + { 7, 6 }, { 3, 5 }, { 6, 4 }, { 4, 1 } }, + { { 5, 7 }, { 3, 7 }, { 8, 7 }, { 7, 7 }, { 1, 5 }, + { 0, 4 }, { 6, 3 }, { 2, 2 }, { 4, 1 } }, + { { 6, 2 }, { 1, 2 }, { 4, 3 }, { 2, 3 }, { 7, 6 }, + { 0, 6 }, { 3, 5 }, { 8, 4 }, { 5, 3 } }, + { { 1, 4 }, { 0, 4 }, { 8, 7 }, { 3, 7 }, { 7, 6 }, + { 5, 5 }, { 2, 4 }, { 4, 2 }, { 6, 1 } }, + { { 6, 4 }, { 0, 4 }, { 5, 7 }, { 3, 7 }, { 8, 6 }, + { 1, 5 }, { 7, 4 }, { 2, 2 }, { 4, 1 } }, + { { 2, 2 }, { 0, 2 }, { 5, 4 }, { 1, 4 }, { 6, 6 }, + { 3, 6 }, { 7, 5 }, { 8, 4 }, { 4, 2 } }, + { { 0 } }, /* unused */ + { { 2, 3 }, { 1, 3 }, { 6, 5 }, { 3, 5 }, { 7, 6 }, + { 4, 6 }, { 8, 5 }, { 5, 3 }, { 0, 1 } }, + { { 3, 4 }, { 2, 4 }, { 7, 7 }, { 0, 7 }, { 4, 6 }, + { 8, 5 }, { 6, 4 }, { 5, 2 }, { 1, 1 } }, + { { 1, 2 }, { 0, 2 }, { 6, 5 }, { 4, 5 }, { 7, 6 }, + { 3, 6 }, { 8, 5 }, { 5, 3 }, { 2, 2 } }, + { { 2, 4 }, { 1, 4 }, { 7, 7 }, { 0, 7 }, { 4, 6 }, + { 6, 5 }, { 8, 4 }, { 3, 2 }, { 5, 1 } }, + { { 2, 2 }, { 1, 2 }, { 5, 3 }, { 0, 3 }, { 4, 4 }, + { 3, 4 }, { 8, 5 }, { 7, 5 }, { 6, 4 } }, + { { 4, 7 }, { 0, 7 }, { 8, 7 }, { 7, 7 }, { 2, 5 }, + { 6, 4 }, { 3, 3 }, { 1, 2 }, { 5, 1 } }, + { { 5, 2 }, { 1, 2 }, { 8, 7 }, { 7, 7 }, { 0, 6 }, + { 4, 5 }, { 3, 4 }, { 2, 3 }, { 6, 2 } }, + { { 2, 2 }, { 1, 2 }, { 8, 3 }, { 0, 3 }, { 6, 4 }, + { 5, 4 }, { 4, 5 }, { 3, 5 }, { 7, 4 } }, + { { 2, 2 }, { 1, 2 }, { 5, 3 }, { 0, 3 }, { 7, 6 }, + { 4, 6 }, { 6, 5 }, { 3, 4 }, { 8, 3 } }, + { { 0 } }, /* unused */ + { { 2, 3 }, { 1, 3 }, { 8, 7 }, { 3, 7 }, { 5, 6 }, + { 7, 5 }, { 4, 4 }, { 6, 3 }, { 0, 1 } }, + { { 2, 4 }, { 0, 4 }, { 8, 7 }, { 3, 7 }, { 7, 6 }, + { 5, 5 }, { 4, 4 }, { 6, 2 }, { 1, 1 } }, + { { 5, 7 }, { 3, 7 }, { 8, 7 }, { 7, 7 }, { 4, 5 }, + { 1, 4 }, { 6, 3 }, { 0, 2 }, { 2, 1 } }, + { { 6, 2 }, { 1, 2 }, { 2, 3 }, { 0, 3 }, { 8, 6 }, + { 7, 6 }, { 3, 5 }, { 5, 4 }, { 4, 3 } }, + { { 5, 7 }, { 3, 7 }, { 8, 7 }, { 7, 7 }, { 1, 5 }, + { 2, 4 }, { 0, 3 }, { 4, 2 }, { 6, 1 } }, + { { 5, 3 }, { 2, 3 }, { 8, 7 }, { 7, 7 }, { 3, 6 }, + { 4, 5 }, { 0, 4 }, { 6, 3 }, { 1, 1 } }, + { { 5, 7 }, { 3, 7 }, { 8, 7 }, { 7, 7 }, { 2, 5 }, + { 0, 4 }, { 4, 3 }, { 1, 2 }, { 6, 1 } }, + { { 3, 7 }, { 0, 7 }, { 8, 7 }, { 5, 7 }, { 7, 5 }, + { 1, 4 }, { 4, 3 }, { 6, 2 }, { 2, 1 } }, + { { 2, 2 }, { 1, 2 }, { 4, 4 }, { 0, 4 }, { 7, 6 }, + { 3, 6 }, { 5, 5 }, { 8, 4 }, { 6, 2 } }, + { { 0 } }, /* unused */ + { { 6, 6 }, { 4, 6 }, { 5, 7 }, { 3, 7 }, { 8, 6 }, + { 1, 4 }, { 0, 3 }, { 7, 2 }, { 2, 1 } }, + { { 2, 2 }, { 1, 2 }, { 6, 4 }, { 0, 4 }, { 4, 6 }, + { 3, 6 }, { 5, 5 }, { 8, 4 }, { 7, 2 } }, + { { 1, 4 }, { 0, 4 }, { 5, 7 }, { 3, 7 }, { 6, 6 }, + { 4, 5 }, { 8, 4 }, { 7, 2 }, { 2, 1 } }, + { { 7, 2 }, { 2, 2 }, { 1, 3 }, { 0, 3 }, { 5, 4 }, + { 4, 4 }, { 6, 5 }, { 3, 5 }, { 8, 4 } }, + { { 4, 2 }, { 2, 2 }, { 5, 7 }, { 3, 7 }, { 8, 6 }, + { 1, 5 }, { 0, 4 }, { 6, 3 }, { 7, 2 } }, + { { 7, 2 }, { 2, 2 }, { 6, 3 }, { 1, 3 }, { 5, 4 }, + { 0, 4 }, { 4, 5 }, { 3, 5 }, { 8, 4 } }, + { { 4, 2 }, { 2, 2 }, { 3, 7 }, { 0, 7 }, { 8, 6 }, + { 5, 5 }, { 1, 4 }, { 6, 3 }, { 7, 2 } }, + { { 6, 6 }, { 1, 6 }, { 5, 7 }, { 3, 7 }, { 8, 6 }, + { 0, 4 }, { 4, 3 }, { 2, 2 }, { 7, 1 } }, + { { 8, 4 }, { 4, 4 }, { 1, 5 }, { 0, 5 }, { 5, 6 }, + { 3, 6 }, { 6, 5 }, { 7, 2 }, { 2, 1 } }, + { { 0 } }, /* unused */ + { { 8, 2 }, { 2, 2 }, { 1, 3 }, { 0, 3 }, { 6, 6 }, + { 5, 6 }, { 4, 5 }, { 7, 4 }, { 3, 3 } }, + { { 3, 3 }, { 2, 3 }, { 6, 7 }, { 0, 7 }, { 4, 6 }, + { 5, 5 }, { 7, 4 }, { 8, 3 }, { 1, 1 } }, + { { 7, 4 }, { 1, 4 }, { 3, 5 }, { 0, 5 }, { 6, 6 }, + { 5, 6 }, { 4, 5 }, { 8, 2 }, { 2, 1 } }, + { { 3, 2 }, { 2, 2 }, { 4, 6 }, { 0, 6 }, { 7, 6 }, + { 6, 6 }, { 1, 4 }, { 5, 3 }, { 8, 2 } }, + { { 8, 2 }, { 2, 2 }, { 6, 3 }, { 4, 3 }, { 5, 6 }, + { 0, 6 }, { 3, 5 }, { 1, 4 }, { 7, 3 } }, + { { 5, 2 }, { 2, 2 }, { 3, 3 }, { 1, 3 }, { 7, 6 }, + { 0, 6 }, { 4, 5 }, { 6, 4 }, { 8, 3 } }, + { { 2, 2 }, { 1, 2 }, { 6, 3 }, { 4, 3 }, { 7, 6 }, + { 0, 6 }, { 5, 5 }, { 3, 4 }, { 8, 3 } }, + { { 3, 7 }, { 0, 7 }, { 6, 7 }, { 5, 7 }, { 1, 5 }, + { 4, 4 }, { 7, 3 }, { 8, 2 }, { 2, 1 } }, + { { 1, 5 }, { 0, 5 }, { 6, 7 }, { 5, 7 }, { 4, 6 }, + { 7, 5 }, { 3, 3 }, { 2, 2 }, { 8, 1 } }, + { { 0 } }, /* unused */ }; //@} @@ -640,31 +569,23 @@ static const uint8_t aic_mode1_vlc_bits[AIC_MODE1_NUM][AIC_MODE1_SIZE] = { #define PTYPE_VLC_SIZE 8 #define PTYPE_VLC_BITS 7 -static const uint8_t ptype_vlc_codes[NUM_PTYPE_VLCS][PTYPE_VLC_SIZE] = { - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x0D, 0x05, 0x01, 0x04, 0x01, 0x00, 0x07, 0x0C }, - { 0x09, 0x11, 0x01, 0x00, 0x05, 0x03, 0x21, 0x20 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 } +static const uint8_t ptype_vlc_tabs[NUM_PTYPE_VLCS][PTYPE_VLC_SIZE][2] = { + { { PBTYPE_ESCAPE, 7 }, { 11, 7 }, { 3, 6 }, { 8, 5 }, + { 9, 4 }, { 2, 3 }, { 1, 2 }, { 0, 1 } }, + { { PBTYPE_ESCAPE, 7 }, { 3, 7 }, { 8, 6 }, { 9, 5 }, + { 11, 4 }, { 0, 3 }, { 2, 2 }, { 1, 1 } }, + { { 9, 3 }, { 8, 3 }, { 3, 4 }, { 1, 4 }, { PBTYPE_ESCAPE, 5 }, + { 0, 5 }, { 11, 4 }, { 2, 1 } }, + { { 3, 2 }, { 2, 2 }, { PBTYPE_ESCAPE, 6 }, { 11, 6 }, + { 1, 5 }, { 0, 4 }, { 8, 3 }, { 9, 2 } }, + { { PBTYPE_ESCAPE, 7 }, { 11, 7 }, { 1, 6 }, { 0, 5 }, + { 3, 4 }, { 9, 3 }, { 8, 2 }, { 2, 1 } }, + { { PBTYPE_ESCAPE, 7 }, { 11, 7 }, { 1, 6 }, { 0, 5 }, + { 3, 4 }, { 8, 3 }, { 9, 2 }, { 2, 1 } }, + { { PBTYPE_ESCAPE, 7 }, { 3, 7 }, { 0, 6 }, { 8, 5 }, + { 9, 4 }, { 1, 3 }, { 2, 2 }, { 11, 1 } }, }; -static const uint8_t ptype_vlc_bits[NUM_PTYPE_VLCS][PTYPE_VLC_SIZE] = { - { 1, 2, 3, 6, 5, 4, 7, 7 }, - { 3, 1, 2, 7, 6, 5, 4, 7 }, - { 5, 4, 1, 4, 3, 3, 4, 5 }, - { 4, 5, 2, 2, 3, 2, 6, 6 }, - { 5, 6, 1, 4, 2, 3, 7, 7 }, - { 5, 6, 1, 4, 3, 2, 7, 7 }, - { 6, 3, 2, 7, 5, 4, 1, 7 } -}; - -static const uint8_t ptype_vlc_syms[PTYPE_VLC_SIZE] = { - 0, 1, 2, 3, 8, 9, 11, PBTYPE_ESCAPE -}; - -/** reverse of ptype_vlc_syms */ static const uint8_t block_num_to_ptype_vlc_num[12] = { 0, 1, 2, 3, 0, 0, 2, 0, 4, 5, 0, 6 }; @@ -676,29 +597,21 @@ static const uint8_t block_num_to_ptype_vlc_num[12] = { #define BTYPE_VLC_SIZE 7 #define BTYPE_VLC_BITS 6 -static const uint8_t btype_vlc_codes[NUM_BTYPE_VLCS][BTYPE_VLC_SIZE] = { - { 0x01, 0x05, 0x00, 0x03, 0x11, 0x09, 0x10 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x09, 0x01, 0x00, 0x01, 0x05, 0x03, 0x08 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 } +static const uint8_t btype_vlc_tabs[NUM_BTYPE_VLCS][BTYPE_VLC_SIZE][2] = { + { { 4, 2 }, { 0, 2 }, { PBTYPE_ESCAPE, 5 }, + { 10, 5 }, { 7, 4 }, { 1, 3 }, { 5, 2 } }, + { { PBTYPE_ESCAPE, 6 }, { 10, 6 }, { 7, 5 }, + { 0, 4 }, { 4, 3 }, { 5, 2 }, { 1, 1 } }, + { { PBTYPE_ESCAPE, 6 }, { 0, 6 }, { 10, 5 }, + { 1, 4 }, { 7, 3 }, { 5, 2 }, { 4, 1 } }, + { { 4, 3 }, { 1, 3 }, { PBTYPE_ESCAPE, 5 }, + { 0, 5 }, { 10, 4 }, { 7, 3 }, { 5, 1 } }, + { { PBTYPE_ESCAPE, 6 }, { 0, 6 }, { 1, 5 }, + { 10, 4 }, { 4, 3 }, { 5, 2 }, { 7, 1 } }, + { { PBTYPE_ESCAPE, 6 }, { 0, 6 }, { 1, 5 }, + { 10, 4 }, { 4, 3 }, { 7, 2 }, { 5, 1 } }, }; -static const uint8_t btype_vlc_bits[NUM_BTYPE_VLCS][PTYPE_VLC_SIZE] = { - { 2, 3, 2, 2, 5, 4, 5 }, - { 4, 1, 3, 2, 6, 5, 6 }, - { 6, 4, 1, 2, 5, 3, 6 }, - { 5, 3, 3, 1, 4, 3, 5 }, - { 6, 5, 3, 2, 4, 1, 6 }, - { 6, 5, 3, 1, 4, 2, 6 } -}; - -static const uint8_t btype_vlc_syms[BTYPE_VLC_SIZE] = { - 0, 1, 4, 5, 10, 7, PBTYPE_ESCAPE -}; - -/** reverse of btype_vlc_syms */ static const uint8_t block_num_to_btype_vlc_num[12] = { 0, 1, 0, 0, 2, 3, 0, 5, 0, 0, 4, 0 }; diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c index 584b58e28..113590aee 100644 --- a/libavcodec/s302m.c +++ b/libavcodec/s302m.c @@ -225,6 +225,7 @@ AVCodec ff_s302m_decoder = { .id = AV_CODEC_ID_S302M, .priv_data_size = sizeof(S302Context), .decode = s302m_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .priv_class = &s302m_class, }; diff --git a/libavcodec/sbc.h b/libavcodec/sbc.h index de9c8d9ae..419c8eab9 100644 --- a/libavcodec/sbc.h +++ b/libavcodec/sbc.h @@ -35,6 +35,7 @@ #include "avcodec.h" #include "libavutil/crc.h" +#include "libavutil/mem_internal.h" #define MSBC_BLOCKS 15 diff --git a/libavcodec/sbc_parser.c b/libavcodec/sbc_parser.c index f56564147..5549b1951 100644 --- a/libavcodec/sbc_parser.c +++ b/libavcodec/sbc_parser.c @@ -42,7 +42,6 @@ static int sbc_parse_header(AVCodecParserContext *s, AVCodecContext *avctx, if (data[0] == MSBC_SYNCWORD && data[1] == 0 && data[2] == 0) { avctx->channels = 1; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; avctx->sample_rate = 16000; avctx->frame_size = 120; s->duration = avctx->frame_size; @@ -66,7 +65,6 @@ static int sbc_parse_header(AVCodecParserContext *s, AVCodecContext *avctx, + (joint * subbands)) + 7) / 8; avctx->channels = channels; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; avctx->sample_rate = sample_rates[sr]; avctx->frame_size = subbands * blocks; s->duration = avctx->frame_size; diff --git a/libavcodec/sbcdec.c b/libavcodec/sbcdec.c index 5361ee2c8..bb590e8a0 100644 --- a/libavcodec/sbcdec.c +++ b/libavcodec/sbcdec.c @@ -33,6 +33,7 @@ #include "avcodec.h" #include "internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "sbc.h" #include "sbcdec_data.h" @@ -370,7 +371,7 @@ AVCodec ff_sbc_decoder = { .priv_data_size = sizeof(SBCDecContext), .init = sbc_decode_init, .decode = sbc_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, 0}, diff --git a/libavcodec/sbcdsp.h b/libavcodec/sbcdsp.h index 334c058e6..24264df51 100644 --- a/libavcodec/sbcdsp.h +++ b/libavcodec/sbcdsp.h @@ -32,6 +32,8 @@ #ifndef AVCODEC_SBCDSP_H #define AVCODEC_SBCDSP_H +#include "libavutil/mem_internal.h" + #include "sbc.h" #include "sbcdsp_data.h" diff --git a/libavcodec/sbcdsp_data.c b/libavcodec/sbcdsp_data.c index 78c07c007..ad6390c7c 100644 --- a/libavcodec/sbcdsp_data.c +++ b/libavcodec/sbcdsp_data.c @@ -29,6 +29,8 @@ * miscellaneous SBC tables */ +#include "libavutil/mem_internal.h" + #include "sbcdsp_data.h" #define F_PROTO(x) ((int32_t) (((x) * 2) * ((int32_t) 1 << 15) + 0.5)) diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h index eb7d1aec0..f80f122c5 100644 --- a/libavcodec/sbr.h +++ b/libavcodec/sbr.h @@ -30,6 +30,9 @@ #define AVCODEC_SBR_H #include + +#include "libavutil/mem_internal.h" + #include "fft.h" #include "aacps.h" #include "sbrdsp.h" diff --git a/libavcodec/scpr3.c b/libavcodec/scpr3.c index 1ed764baa..78c58889c 100644 --- a/libavcodec/scpr3.c +++ b/libavcodec/scpr3.c @@ -524,32 +524,16 @@ static int update_model1_to_4(PixelModel3 *m, uint32_t val) static int update_model1_to_5(PixelModel3 *m, uint32_t val) { - PixelModel3 n = {0}; int i, size, freqs; uint32_t a; + update_model1_to_4(m, val); size = m->size; - n.size = size; - for (i = 0; i < size; i++) { - n.symbols[i] = m->symbols[i]; - } - AV_QSORT(n.symbols, size, uint8_t, cmpbytes); - size = n.size; - for (i = 0; i < size; i++) { - if (val == n.symbols[i]) { - n.freqs[i] = 100; - n.maxpos = i; - } else { - n.freqs[i] = 50; - } - } a = 256 - size; for (i = 0; i < size; i++, a += freqs) - freqs = n.freqs[i]; - n.type = 5; - n.cntsum = a; - - memcpy(m, &n, sizeof(n)); + freqs = m->freqs[i]; + m->type = 5; + m->cntsum = a; return 0; } diff --git a/libavcodec/sei.h b/libavcodec/sei.h new file mode 100644 index 000000000..5513590b5 --- /dev/null +++ b/libavcodec/sei.h @@ -0,0 +1,140 @@ +/* + * 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_SEI_H +#define AVCODEC_SEI_H + +// SEI payload types form a common namespace between the H.264, H.265 +// and H.266 standards. A given payload type always has the same +// meaning, but some names have different payload types in different +// standards (e.g. scalable-nesting is 30 in H.264 but 133 in H.265). +// The content of the payload data depends on the standard, though +// many generic parts have the same interpretation everywhere (such as +// mastering-display-colour-volume and user-data-unregistered). +enum { + SEI_TYPE_BUFFERING_PERIOD = 0, + SEI_TYPE_PIC_TIMING = 1, + SEI_TYPE_PAN_SCAN_RECT = 2, + SEI_TYPE_FILLER_PAYLOAD = 3, + SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35 = 4, + SEI_TYPE_USER_DATA_UNREGISTERED = 5, + SEI_TYPE_RECOVERY_POINT = 6, + SEI_TYPE_DEC_REF_PIC_MARKING_REPETITION = 7, + SEI_TYPE_SPARE_PIC = 8, + SEI_TYPE_SCENE_INFO = 9, + SEI_TYPE_SUB_SEQ_INFO = 10, + SEI_TYPE_SUB_SEQ_LAYER_CHARACTERISTICS = 11, + SEI_TYPE_SUB_SEQ_CHARACTERISTICS = 12, + SEI_TYPE_FULL_FRAME_FREEZE = 13, + SEI_TYPE_FULL_FRAME_FREEZE_RELEASE = 14, + SEI_TYPE_FULL_FRAME_SNAPSHOT = 15, + SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_START = 16, + SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_END = 17, + SEI_TYPE_MOTION_CONSTRAINED_SLICE_GROUP_SET = 18, + SEI_TYPE_FILM_GRAIN_CHARACTERISTICS = 19, + SEI_TYPE_DEBLOCKING_FILTER_DISPLAY_PREFERENCE = 20, + SEI_TYPE_STEREO_VIDEO_INFO = 21, + SEI_TYPE_POST_FILTER_HINT = 22, + SEI_TYPE_TONE_MAPPING_INFO = 23, + SEI_TYPE_SCALABILITY_INFO = 24, + SEI_TYPE_SUB_PIC_SCALABLE_LAYER = 25, + SEI_TYPE_NON_REQUIRED_LAYER_REP = 26, + SEI_TYPE_PRIORITY_LAYER_INFO = 27, + SEI_TYPE_LAYERS_NOT_PRESENT_4 = 28, + SEI_TYPE_LAYER_DEPENDENCY_CHANGE = 29, + SEI_TYPE_SCALABLE_NESTING_4 = 30, + SEI_TYPE_BASE_LAYER_TEMPORAL_HRD = 31, + SEI_TYPE_QUALITY_LAYER_INTEGRITY_CHECK = 32, + SEI_TYPE_REDUNDANT_PIC_PROPERTY = 33, + SEI_TYPE_TL0_DEP_REP_INDEX = 34, + SEI_TYPE_TL_SWITCHING_POINT = 35, + SEI_TYPE_PARALLEL_DECODING_INFO = 36, + SEI_TYPE_MVC_SCALABLE_NESTING = 37, + SEI_TYPE_VIEW_SCALABILITY_INFO = 38, + SEI_TYPE_MULTIVIEW_SCENE_INFO_4 = 39, + SEI_TYPE_MULTIVIEW_ACQUISITION_INFO_4 = 40, + SEI_TYPE_NON_REQUIRED_VIEW_COMPONENT = 41, + SEI_TYPE_VIEW_DEPENDENCY_CHANGE = 42, + SEI_TYPE_OPERATION_POINTS_NOT_PRESENT = 43, + SEI_TYPE_BASE_VIEW_TEMPORAL_HRD = 44, + SEI_TYPE_FRAME_PACKING_ARRANGEMENT = 45, + SEI_TYPE_MULTIVIEW_VIEW_POSITION_4 = 46, + SEI_TYPE_DISPLAY_ORIENTATION = 47, + SEI_TYPE_MVCD_SCALABLE_NESTING = 48, + SEI_TYPE_MVCD_VIEW_SCALABILITY_INFO = 49, + SEI_TYPE_DEPTH_REPRESENTATION_INFO_4 = 50, + SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO_4 = 51, + SEI_TYPE_DEPTH_TIMING = 52, + SEI_TYPE_DEPTH_SAMPLING_INFO = 53, + SEI_TYPE_CONSTRAINED_DEPTH_PARAMETER_SET_IDENTIFIER = 54, + SEI_TYPE_GREEN_METADATA = 56, + SEI_TYPE_STRUCTURE_OF_PICTURES_INFO = 128, + SEI_TYPE_ACTIVE_PARAMETER_SETS = 129, + SEI_TYPE_PARAMETER_SETS_INCLUSION_INDICATION = SEI_TYPE_ACTIVE_PARAMETER_SETS, + SEI_TYPE_DECODING_UNIT_INFO = 130, + SEI_TYPE_TEMPORAL_SUB_LAYER_ZERO_IDX = 131, + SEI_TYPE_DECODED_PICTURE_HASH = 132, + SEI_TYPE_SCALABLE_NESTING_5 = 133, + SEI_TYPE_REGION_REFRESH_INFO = 134, + SEI_TYPE_NO_DISPLAY = 135, + SEI_TYPE_TIME_CODE = 136, + SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME = 137, + SEI_TYPE_SEGMENTED_RECT_FRAME_PACKING_ARRANGEMENT = 138, + SEI_TYPE_TEMPORAL_MOTION_CONSTRAINED_TILE_SETS = 139, + SEI_TYPE_CHROMA_RESAMPLING_FILTER_HINT = 140, + SEI_TYPE_KNEE_FUNCTION_INFO = 141, + SEI_TYPE_COLOUR_REMAPPING_INFO = 142, + SEI_TYPE_DEINTERLACED_FIELD_IDENTIFICATION = 143, + SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO = 144, + SEI_TYPE_DEPENDENT_RAP_INDICATION = 145, + SEI_TYPE_CODED_REGION_COMPLETION = 146, + SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS = 147, + SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT = 148, + SEI_TYPE_CONTENT_COLOUR_VOLUME = 149, + SEI_TYPE_EQUIRECTANGULAR_PROJECTION = 150, + SEI_TYPE_CUBEMAP_PROJECTION = 151, + SEI_TYPE_FISHEYE_VIDEO_INFO = 152, + SEI_TYPE_SPHERE_ROTATION = 154, + SEI_TYPE_REGIONWISE_PACKING = 155, + SEI_TYPE_OMNI_VIEWPORT = 156, + SEI_TYPE_REGIONAL_NESTING = 157, + SEI_TYPE_MCTS_EXTRACTION_INFO_SETS = 158, + SEI_TYPE_MCTS_EXTRACTION_INFO_NESTING = 159, + SEI_TYPE_LAYERS_NOT_PRESENT_5 = 160, + SEI_TYPE_INTER_LAYER_CONSTRAINED_TILE_SETS = 161, + SEI_TYPE_BSP_NESTING = 162, + SEI_TYPE_BSP_INITIAL_ARRIVAL_TIME = 163, + SEI_TYPE_SUB_BITSTREAM_PROPERTY = 164, + SEI_TYPE_ALPHA_CHANNEL_INFO = 165, + SEI_TYPE_OVERLAY_INFO = 166, + SEI_TYPE_TEMPORAL_MV_PREDICTION_CONSTRAINTS = 167, + SEI_TYPE_FRAME_FIELD_INFO = 168, + SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO = 176, + SEI_TYPE_DEPTH_REPRESENTATION_INFO_5 = 177, + SEI_TYPE_MULTIVIEW_SCENE_INFO_5 = 178, + SEI_TYPE_MULTIVIEW_ACQUISITION_INFO_5 = 179, + SEI_TYPE_MULTIVIEW_VIEW_POSITION_5 = 180, + SEI_TYPE_ALTERNATIVE_DEPTH_INFO = 181, + SEI_TYPE_SEI_MANIFEST = 200, + SEI_TYPE_SEI_PREFIX_INDICATION = 201, + SEI_TYPE_ANNOTATED_REGIONS = 202, + SEI_TYPE_SUBPIC_LEVEL_INFO = 203, + SEI_TYPE_SAMPLE_ASPECT_RATIO_INFO = 204, +}; + +#endif /* AVCODEC_SEI_H */ diff --git a/libavcodec/setts_bsf.c b/libavcodec/setts_bsf.c new file mode 100644 index 000000000..2558e38f5 --- /dev/null +++ b/libavcodec/setts_bsf.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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 + * Change the PTS/DTS timestamps. + */ + +#include "libavutil/opt.h" +#include "libavutil/eval.h" + +#include "avcodec.h" +#include "bsf.h" +#include "bsf_internal.h" + +static const char *const var_names[] = { + "N", ///< frame number (starting at zero) + "TS", + "POS", ///< original position in the file of the frame + "PREV_INPTS", ///< previous input PTS + "PREV_INDTS", ///< previous input DTS + "PREV_OUTPTS", ///< previous output PTS + "PREV_OUTDTS", ///< previous output DTS + "PTS", ///< original PTS in the file of the frame + "DTS", ///< original DTS in the file of the frame + "STARTPTS", ///< PTS at start of movie + "STARTDTS", ///< DTS at start of movie + "TB", ///< timebase of the stream + "SR", ///< sample rate of the stream + NULL +}; + +enum var_name { + VAR_N, + VAR_TS, + VAR_POS, + VAR_PREV_INPTS, + VAR_PREV_INDTS, + VAR_PREV_OUTPTS, + VAR_PREV_OUTDTS, + VAR_PTS, + VAR_DTS, + VAR_STARTPTS, + VAR_STARTDTS, + VAR_TB, + VAR_SR, + VAR_VARS_NB +}; + +typedef struct SetTSContext { + const AVClass *class; + + char *ts_str; + char *pts_str; + char *dts_str; + + int64_t frame_number; + + int64_t start_pts; + int64_t start_dts; + int64_t prev_inpts; + int64_t prev_indts; + int64_t prev_outpts; + int64_t prev_outdts; + + double var_values[VAR_VARS_NB]; + + AVExpr *ts_expr; + AVExpr *pts_expr; + AVExpr *dts_expr; +} SetTSContext; + +static int setts_init(AVBSFContext *ctx) +{ + SetTSContext *s = ctx->priv_data; + int ret; + + if ((ret = av_expr_parse(&s->ts_expr, s->ts_str, + var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { + av_log(ctx, AV_LOG_ERROR, "Error while parsing ts expression '%s'\n", s->ts_str); + return ret; + } + + if (s->pts_str) { + if ((ret = av_expr_parse(&s->pts_expr, s->pts_str, + var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { + av_log(ctx, AV_LOG_ERROR, "Error while parsing pts expression '%s'\n", s->pts_str); + return ret; + } + } + + if (s->dts_str) { + if ((ret = av_expr_parse(&s->dts_expr, s->dts_str, + var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { + av_log(ctx, AV_LOG_ERROR, "Error while parsing dts expression '%s'\n", s->dts_str); + return ret; + } + } + + s->frame_number= 0; + s->start_pts = AV_NOPTS_VALUE; + s->start_dts = AV_NOPTS_VALUE; + s->prev_inpts = AV_NOPTS_VALUE; + s->prev_indts = AV_NOPTS_VALUE; + s->prev_outpts = AV_NOPTS_VALUE; + s->prev_outdts = AV_NOPTS_VALUE; + + return 0; +} + +static int setts_filter(AVBSFContext *ctx, AVPacket *pkt) +{ + SetTSContext *s = ctx->priv_data; + int64_t new_ts, new_pts, new_dts; + int ret; + + ret = ff_bsf_get_packet_ref(ctx, pkt); + if (ret < 0) + return ret; + + if (s->start_pts == AV_NOPTS_VALUE) + s->start_pts = pkt->pts; + + if (s->start_dts == AV_NOPTS_VALUE) + s->start_dts = pkt->dts; + + s->var_values[VAR_N] = s->frame_number++; + s->var_values[VAR_TS] = pkt->dts; + s->var_values[VAR_POS] = pkt->pos; + s->var_values[VAR_PTS] = pkt->pts; + s->var_values[VAR_DTS] = pkt->dts; + s->var_values[VAR_PREV_INPTS] = s->prev_inpts; + s->var_values[VAR_PREV_INDTS] = s->prev_indts; + s->var_values[VAR_PREV_OUTPTS] = s->prev_outpts; + s->var_values[VAR_PREV_OUTDTS] = s->prev_outdts; + s->var_values[VAR_STARTPTS] = s->start_pts; + s->var_values[VAR_STARTDTS] = s->start_dts; + s->var_values[VAR_TB] = ctx->time_base_out.den ? av_q2d(ctx->time_base_out) : 0; + s->var_values[VAR_SR] = ctx->par_in->sample_rate; + + new_ts = llrint(av_expr_eval(s->ts_expr, s->var_values, NULL)); + + if (s->pts_str) { + s->var_values[VAR_TS] = pkt->pts; + new_pts = llrint(av_expr_eval(s->pts_expr, s->var_values, NULL)); + } else { + new_pts = new_ts; + } + + if (s->dts_str) { + s->var_values[VAR_TS] = pkt->dts; + new_dts = llrint(av_expr_eval(s->dts_expr, s->var_values, NULL)); + } else { + new_dts = new_ts; + } + + s->var_values[VAR_PREV_INPTS] = pkt->pts; + s->var_values[VAR_PREV_INDTS] = pkt->dts; + s->var_values[VAR_PREV_OUTPTS] = new_pts; + s->var_values[VAR_PREV_OUTDTS] = new_dts; + + pkt->pts = new_pts; + pkt->dts = new_dts; + + return ret; +} + +static void setts_close(AVBSFContext *bsf) +{ + SetTSContext *s = bsf->priv_data; + + av_expr_free(s->ts_expr); + s->ts_expr = NULL; + av_expr_free(s->pts_expr); + s->pts_expr = NULL; + av_expr_free(s->dts_expr); + s->dts_expr = NULL; +} + +#define OFFSET(x) offsetof(SetTSContext, x) +#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_SUBTITLE_PARAM|AV_OPT_FLAG_BSF_PARAM) + +static const AVOption options[] = { + { "ts", "set expression for packet PTS and DTS", OFFSET(ts_str), AV_OPT_TYPE_STRING, {.str="TS"}, 0, 0, FLAGS }, + { "pts", "set expression for packet PTS", OFFSET(pts_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { "dts", "set expression for packet DTS", OFFSET(dts_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { NULL }, +}; + +static const AVClass setts_class = { + .class_name = "setts_bsf", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVBitStreamFilter ff_setts_bsf = { + .name = "setts", + .priv_data_size = sizeof(SetTSContext), + .priv_class = &setts_class, + .init = setts_init, + .close = setts_close, + .filter = setts_filter, +}; diff --git a/libavcodec/sga.c b/libavcodec/sga.c new file mode 100644 index 000000000..7e6bea530 --- /dev/null +++ b/libavcodec/sga.c @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/avassert.h" +#include "libavutil/common.h" +#include "avcodec.h" +#include "get_bits.h" +#include "bytestream.h" +#include "internal.h" + +#define PALDATA_FOLLOWS_TILEDATA 4 +#define HAVE_COMPRESSED_TILEMAP 32 +#define HAVE_TILEMAP 128 + +typedef struct SGAVideoContext { + GetByteContext gb; + + int metadata_size; + int tiledata_size; + int tiledata_offset; + int tilemapdata_size; + int tilemapdata_offset; + int paldata_size; + int paldata_offset; + int palmapdata_offset; + int palmapdata_size; + + int flags; + int nb_pal; + int nb_tiles; + int tiles_w, tiles_h; + int shift; + int plus; + int swap; + + uint32_t pal[256]; + uint8_t *tileindex_data; + unsigned tileindex_size; + uint8_t *palmapindex_data; + unsigned palmapindex_size; + uint8_t uncompressed[65536]; +} SGAVideoContext; + +static av_cold int sga_decode_init(AVCodecContext *avctx) +{ + avctx->pix_fmt = AV_PIX_FMT_PAL8; + return 0; +} + +static int decode_palette(GetByteContext *gb, uint32_t *pal) +{ + GetBitContext gbit; + + if (bytestream2_get_bytes_left(gb) < 18) + return AVERROR_INVALIDDATA; + + memset(pal, 0, 16 * sizeof(*pal)); + init_get_bits8(&gbit, gb->buffer, 18); + + for (int RGBIndex = 0; RGBIndex < 3; RGBIndex++) { + for (int index = 0; index < 16; index++) { + unsigned color = get_bits1(&gbit) << RGBIndex; + pal[15 - index] |= color << (5 + 16); + } + } + + for (int RGBIndex = 0; RGBIndex < 3; RGBIndex++) { + for (int index = 0; index < 16; index++) { + unsigned color = get_bits1(&gbit) << RGBIndex; + pal[15 - index] |= color << (5 + 8); + } + } + + for (int RGBIndex = 0; RGBIndex < 3; RGBIndex++) { + for (int index = 0; index < 16; index++) { + unsigned color = get_bits1(&gbit) << RGBIndex; + pal[15 - index] |= color << (5 + 0); + } + } + + for (int index = 0; index < 16; index++) + pal[index] = (0xFFU << 24) | pal[index] | (pal[index] >> 3); + + bytestream2_skip(gb, 18); + + return 0; +} + +static int decode_index_palmap(SGAVideoContext *s, AVFrame *frame) +{ + const uint8_t *tt = s->tileindex_data; + + for (int y = 0; y < s->tiles_h; y++) { + for (int x = 0; x < s->tiles_w; x++) { + int pal_idx = s->palmapindex_data[y * s->tiles_w + x] * 16; + uint8_t *dst = frame->data[0] + y * 8 * frame->linesize[0] + x * 8; + + for (int yy = 0; yy < 8; yy++) { + for (int xx = 0; xx < 8; xx++) + dst[xx] = pal_idx + tt[xx]; + tt += 8; + + dst += frame->linesize[0]; + } + } + } + + return 0; +} + +static int decode_index_tilemap(SGAVideoContext *s, AVFrame *frame) +{ + GetByteContext *gb = &s->gb; + GetBitContext pm; + + bytestream2_seek(gb, s->tilemapdata_offset, SEEK_SET); + if (bytestream2_get_bytes_left(gb) < s->tilemapdata_size) + return AVERROR_INVALIDDATA; + + init_get_bits8(&pm, gb->buffer, s->tilemapdata_size); + + for (int y = 0; y < s->tiles_h; y++) { + for (int x = 0; x < s->tiles_w; x++) { + uint8_t tile[64]; + int tilemap = get_bits(&pm, 16); + int flip_x = (tilemap >> 11) & 1; + int flip_y = (tilemap >> 12) & 1; + int tindex = av_clip((tilemap & 511) - 1, 0, s->nb_tiles - 1); + const uint8_t *tt = s->tileindex_data + tindex * 64; + int pal_idx = ((tilemap >> 13) & 3) * 16; + uint8_t *dst = frame->data[0] + y * 8 * frame->linesize[0] + x * 8; + + if (!flip_x && !flip_y) { + memcpy(tile, tt, 64); + } else if (flip_x && flip_y) { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) + tile[i * 8 + j] = tt[(7 - i) * 8 + 7 - j]; + } + } else if (flip_x) { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) + tile[i * 8 + j] = tt[i * 8 + 7 - j]; + } + } else { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) + tile[i * 8 + j] = tt[(7 - i) * 8 + j]; + } + } + + for (int yy = 0; yy < 8; yy++) { + for (int xx = 0; xx < 8; xx++) + dst[xx] = pal_idx + tile[xx + yy * 8]; + + dst += frame->linesize[0]; + } + } + } + + return 0; +} + +static int decode_index(SGAVideoContext *s, AVFrame *frame) +{ + const uint8_t *src = s->tileindex_data; + uint8_t *dst = frame->data[0]; + + for (int y = 0; y < frame->height; y += 8) { + for (int x = 0; x < frame->width; x += 8) { + for (int yy = 0; yy < 8; yy++) { + for (int xx = 0; xx < 8; xx++) + dst[x + xx + yy * frame->linesize[0]] = src[xx]; + src += 8; + } + } + + dst += 8 * frame->linesize[0]; + } + + return 0; +} + +static int lzss_decompress(AVCodecContext *avctx, + GetByteContext *gb, uint8_t *dst, + int dst_size, int shift, int plus) +{ + int oi = 0; + + while (bytestream2_get_bytes_left(gb) > 0 && oi < dst_size) { + uint16_t displace, header = bytestream2_get_be16(gb); + int count, offset; + + for (int i = 0; i < 16; i++) { + switch (header >> 15) { + case 0: + if (oi + 2 < dst_size) { + dst[oi++] = bytestream2_get_byte(gb); + dst[oi++] = bytestream2_get_byte(gb); + } + break; + case 1: + displace = bytestream2_get_be16(gb); + count = displace >> shift; + offset = displace & ((1 << shift) - 1); + + if (displace == 0) { + while (bytestream2_get_bytes_left(gb) > 0 && + oi < dst_size) + dst[oi++] = bytestream2_get_byte(gb); + return oi; + } + + count += plus; + + if (offset <= 0) + offset = 1; + if (oi < offset || oi + count * 2 > dst_size) + return AVERROR_INVALIDDATA; + for (int j = 0; j < count * 2; j++) { + dst[oi] = dst[oi - offset]; + oi++; + } + break; + } + + header <<= 1; + } + } + + return AVERROR_INVALIDDATA; +} + +static int decode_palmapdata(AVCodecContext *avctx) +{ + SGAVideoContext *s = avctx->priv_data; + const int bits = (s->nb_pal + 1) / 2; + GetByteContext *gb = &s->gb; + GetBitContext pm; + + bytestream2_seek(gb, s->palmapdata_offset, SEEK_SET); + if (bytestream2_get_bytes_left(gb) < s->palmapdata_size) + return AVERROR_INVALIDDATA; + init_get_bits8(&pm, gb->buffer, s->palmapdata_size); + + for (int y = 0; y < s->tiles_h; y++) { + uint8_t *dst = s->palmapindex_data + y * s->tiles_w; + + for (int x = 0; x < s->tiles_w; x++) + dst[x] = get_bits(&pm, bits); + + dst += s->tiles_w; + } + + return 0; +} + +static int decode_tiledata(AVCodecContext *avctx) +{ + SGAVideoContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + GetBitContext tm; + + bytestream2_seek(gb, s->tiledata_offset, SEEK_SET); + if (bytestream2_get_bytes_left(gb) < s->tiledata_size) + return AVERROR_INVALIDDATA; + init_get_bits8(&tm, gb->buffer, s->tiledata_size); + + for (int n = 0; n < s->nb_tiles; n++) { + uint8_t *dst = s->tileindex_data + n * 64; + + for (int yy = 0; yy < 8; yy++) { + for (int xx = 0; xx < 8; xx++) + dst[xx] = get_bits(&tm, 4); + + dst += 8; + } + } + + for (int i = 0; i < s->nb_tiles && s->swap; i++) { + uint8_t *dst = s->tileindex_data + i * 64; + + for (int j = 8; j < 64; j += 16) { + for (int k = 0; k < 8; k += 2) + FFSWAP(uint8_t, dst[j + k], dst[j+k+1]); + } + } + + return 0; +} + +static int sga_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + SGAVideoContext *s = avctx->priv_data; + GetByteContext *gb = &s->gb; + AVFrame *frame = data; + int ret, type; + + if (avpkt->size <= 14) + return AVERROR_INVALIDDATA; + + s->flags = avpkt->data[8]; + s->nb_pal = avpkt->data[9]; + s->tiles_w = avpkt->data[10]; + s->tiles_h = avpkt->data[11]; + + if (s->nb_pal > 4) + return AVERROR_INVALIDDATA; + + if ((ret = ff_set_dimensions(avctx, + s->tiles_w * 8, + s->tiles_h * 8)) < 0) + return ret; + + av_fast_padded_malloc(&s->tileindex_data, &s->tileindex_size, + avctx->width * avctx->height); + if (!s->tileindex_data) + return AVERROR(ENOMEM); + + av_fast_padded_malloc(&s->palmapindex_data, &s->palmapindex_size, + s->tiles_w * s->tiles_h); + if (!s->palmapindex_data) + return AVERROR(ENOMEM); + + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + bytestream2_init(gb, avpkt->data, avpkt->size); + + type = bytestream2_get_byte(gb); + s->metadata_size = 12 + ((!!(s->flags & HAVE_TILEMAP)) * 2); + s->nb_tiles = s->flags & HAVE_TILEMAP ? AV_RB16(avpkt->data + 12) : s->tiles_w * s->tiles_h; + if (s->nb_tiles > s->tiles_w * s->tiles_h) + return AVERROR_INVALIDDATA; + + av_log(avctx, AV_LOG_DEBUG, "type: %X flags: %X nb_tiles: %d\n", type, s->flags, s->nb_tiles); + + switch (type) { + case 0xE7: + case 0xCB: + case 0xCD: + s->swap = 1; + s->shift = 12; + s->plus = 1; + break; + case 0xC9: + s->swap = 1; + s->shift = 13; + s->plus = 1; + break; + case 0xC8: + s->swap = 1; + s->shift = 13; + s->plus = 0; + break; + case 0xC7: + s->swap = 0; + s->shift = 13; + s->plus = 1; + break; + case 0xC6: + s->swap = 0; + s->shift = 13; + s->plus = 0; + break; + } + + if (type == 0xE7) { + int offset = s->metadata_size, left; + int sizes[3]; + + bytestream2_seek(gb, s->metadata_size, SEEK_SET); + + for (int i = 0; i < 3; i++) + sizes[i] = bytestream2_get_be16(gb); + + for (int i = 0; i < 3; i++) { + int size = sizes[i]; + int raw = size >> 15; + + size &= (1 << 15) - 1; + + if (raw) { + if (bytestream2_get_bytes_left(gb) < size) + return AVERROR_INVALIDDATA; + + if (sizeof(s->uncompressed) - offset < size) + return AVERROR_INVALIDDATA; + + memcpy(s->uncompressed + offset, gb->buffer, size); + bytestream2_skip(gb, size); + } else { + GetByteContext gb2; + + if (bytestream2_get_bytes_left(gb) < size) + return AVERROR_INVALIDDATA; + + bytestream2_init(&gb2, gb->buffer, size); + ret = lzss_decompress(avctx, &gb2, s->uncompressed + offset, + sizeof(s->uncompressed) - offset, s->shift, s->plus); + if (ret < 0) + return ret; + bytestream2_skip(gb, size); + size = ret; + } + + offset += size; + } + + left = bytestream2_get_bytes_left(gb); + if (sizeof(s->uncompressed) - offset < left) + return AVERROR_INVALIDDATA; + + bytestream2_get_buffer(gb, s->uncompressed + offset, left); + + offset += left; + bytestream2_init(gb, s->uncompressed, offset); + } + + switch (type) { + case 0xCD: + case 0xCB: + case 0xC9: + case 0xC8: + case 0xC7: + case 0xC6: + bytestream2_seek(gb, s->metadata_size, SEEK_SET); + ret = lzss_decompress(avctx, gb, s->uncompressed + s->metadata_size, + sizeof(s->uncompressed) - s->metadata_size, s->shift, s->plus); + if (ret < 0) + return ret; + bytestream2_init(gb, s->uncompressed, ret + s->metadata_size); + case 0xE7: + case 0xC1: + s->tiledata_size = s->nb_tiles * 32; + s->paldata_size = s->nb_pal * 18; + s->tiledata_offset = s->flags & PALDATA_FOLLOWS_TILEDATA ? s->metadata_size : s->metadata_size + s->paldata_size; + s->paldata_offset = s->flags & PALDATA_FOLLOWS_TILEDATA ? s->metadata_size + s->tiledata_size : s->metadata_size; + s->palmapdata_offset = (s->flags & HAVE_TILEMAP) ? -1 : s->paldata_offset + s->paldata_size; + s->palmapdata_size = (s->flags & HAVE_TILEMAP) || s->nb_pal < 2 ? 0 : (s->tiles_w * s->tiles_h * ((s->nb_pal + 1) / 2) + 7) / 8; + s->tilemapdata_size = (s->flags & HAVE_TILEMAP) ? s->tiles_w * s->tiles_h * 2 : 0; + s->tilemapdata_offset = (s->flags & HAVE_TILEMAP) ? s->paldata_offset + s->paldata_size: -1; + + bytestream2_seek(gb, s->paldata_offset, SEEK_SET); + for (int n = 0; n < s->nb_pal; n++) { + ret = decode_palette(gb, s->pal + 16 * n); + if (ret < 0) + return ret; + } + + if (s->tiledata_size > 0) { + ret = decode_tiledata(avctx); + if (ret < 0) + return ret; + } + + if (s->palmapdata_size > 0) { + ret = decode_palmapdata(avctx); + if (ret < 0) + return ret; + } + + if (s->palmapdata_size > 0 && s->tiledata_size > 0) { + ret = decode_index_palmap(s, frame); + if (ret < 0) + return ret; + } else if (s->tilemapdata_size > 0 && s->tiledata_size > 0) { + ret = decode_index_tilemap(s, frame); + if (ret < 0) + return ret; + } else if (s->tiledata_size > 0) { + ret = decode_index(s, frame); + if (ret < 0) + return ret; + } + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown type: %X\n", type); + return AVERROR_INVALIDDATA; + } + + memcpy(frame->data[1], s->pal, AVPALETTE_SIZE); + frame->palette_has_changed = 1; + frame->pict_type = AV_PICTURE_TYPE_I; + frame->key_frame = 1; + + *got_frame = 1; + + return avpkt->size; +} + +static av_cold int sga_decode_end(AVCodecContext *avctx) +{ + SGAVideoContext *s = avctx->priv_data; + + av_freep(&s->tileindex_data); + s->tileindex_size = 0; + + av_freep(&s->palmapindex_data); + s->palmapindex_size = 0; + + return 0; +} + +AVCodec ff_sga_decoder = { + .name = "sga", + .long_name = NULL_IF_CONFIG_SMALL("Digital Pictures SGA Video"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_SGA_VIDEO, + .priv_data_size = sizeof(SGAVideoContext), + .init = sga_decode_init, + .decode = sga_decode_frame, + .close = sga_decode_end, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, +}; diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c index 02ad1e116..e95414025 100644 --- a/libavcodec/sgidec.c +++ b/libavcodec/sgidec.c @@ -297,4 +297,5 @@ AVCodec ff_sgi_decoder = { .decode = decode_frame, .init = sgi_decode_init, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c index 13756f160..3aa0c7f4a 100644 --- a/libavcodec/sgienc.c +++ b/libavcodec/sgienc.c @@ -39,9 +39,9 @@ typedef struct SgiContext { static av_cold int encode_init(AVCodecContext *avctx) { if (avctx->width > 65535 || avctx->height > 65535) { - av_log(avctx, AV_LOG_ERROR, - "Unsupported resolution %dx%d.\n", avctx->width, avctx->height); - av_log(avctx, AV_LOG_ERROR, "SGI does not support resolutions above 65535x65535\n"); + av_log(avctx, AV_LOG_ERROR, "Unsupported resolution %dx%d. " + "SGI does not support resolutions above 65535x65535\n", + avctx->width, avctx->height); return AVERROR_INVALIDDATA; } @@ -219,7 +219,15 @@ FF_ENABLE_DEPRECATION_WARNINGS bytestream2_put_be32(&taboff_pcb, bytestream2_tell_p(&pbc)); for (x = 0; x < width * bytes_per_channel; x += bytes_per_channel) - encode_buf[x] = in_buf[depth * x]; + if (bytes_per_channel == 1) { + encode_buf[x] = in_buf[depth * x]; + } else if (HAVE_BIGENDIAN ^ put_be) { + encode_buf[x + 1] = in_buf[depth * x]; + encode_buf[x] = in_buf[depth * x + 1]; + } else { + encode_buf[x] = in_buf[depth * x]; + encode_buf[x + 1] = in_buf[depth * x + 1]; + } length = sgi_rle_encode(&pbc, encode_buf, width, bytes_per_channel); @@ -292,4 +300,5 @@ AVCodec ff_sgi_encoder = { AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/sgirledec.c b/libavcodec/sgirledec.c index aa4f0e7e1..9cb637b07 100644 --- a/libavcodec/sgirledec.c +++ b/libavcodec/sgirledec.c @@ -139,4 +139,5 @@ AVCodec ff_sgirle_decoder = { .init = sgirle_decode_init, .decode = sgirle_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/sheervideo.c b/libavcodec/sheervideo.c index 1a43727a3..b3fb92b6b 100644 --- a/libavcodec/sheervideo.c +++ b/libavcodec/sheervideo.c @@ -23,6 +23,9 @@ #include #include +#define CACHED_BITSTREAM_READER !ARCH_X86_32 +#define SHEER_VLC_BITS 12 + #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "get_bits.h" @@ -62,10 +65,10 @@ static void decode_ca4i(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int y, u, v, a; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred[3] = (a + pred[3]) & 0x3ff; dst_y[x] = pred[0] = (y + pred[0]) & 0x3ff; @@ -105,10 +108,10 @@ static void decode_ca4p(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int y, u, v, a; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred[3] = (a + pred[3]) & 0x3ff; dst_y[x] = pred[0] = (y + pred[0]) & 0x3ff; @@ -145,10 +148,10 @@ static void decode_ca4p(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[2] = dst_v[-p->linesize[2] / 2 + x]; pred_T[3] = dst_a[-p->linesize[3] / 2 + x]; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred_L[3] = (a + ((3 * (pred_T[3] + pred_L[3]) - 2 * pred_TL[3]) >> 2)) & 0x3ff; dst_y[x] = pred_L[0] = (y + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0x3ff; @@ -192,9 +195,9 @@ static void decode_ybr10i(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int y, u, v; - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x] = pred[0] = (y + pred[0]) & 0x3ff; dst_u[x] = pred[1] = (u + pred[1]) & 0x3ff; @@ -230,9 +233,9 @@ static void decode_ybr10(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int y, u, v; - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x] = pred[0] = (y + pred[0]) & 0x3ff; dst_u[x] = pred[1] = (u + pred[1]) & 0x3ff; @@ -264,9 +267,9 @@ static void decode_ybr10(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[1] = dst_u[-p->linesize[1] / 2 + x]; pred_T[2] = dst_v[-p->linesize[2] / 2 + x]; - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x] = pred_L[0] = (y + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0x3ff; dst_u[x] = pred_L[1] = (u + ((3 * (pred_T[1] + pred_L[1]) - 2 * pred_TL[1]) >> 2)) & 0x3ff; @@ -308,10 +311,10 @@ static void decode_yry10i(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x += 2) { int y1, y2, u, v; - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred[0] = (y1 + pred[0]) & 0x3ff; dst_u[x / 2] = pred[1] = (u + pred[1]) & 0x3ff; @@ -349,10 +352,10 @@ static void decode_yry10(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x += 2) { int y1, y2, u, v; - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred[0] = (y1 + pred[0]) & 0x3ff; dst_u[x / 2] = pred[1] = (u + pred[1]) & 0x3ff; @@ -387,10 +390,10 @@ static void decode_yry10(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[1] = dst_u[-p->linesize[1] / 2 + x / 2]; pred_T[2] = dst_v[-p->linesize[2] / 2 + x / 2]; - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred_L[0] = (y1 + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0x3ff; dst_u[x / 2] = pred_L[1] = (u + (((pred_L[1] - pred_TL[1]) >> 1) + pred_T[1])) & 0x3ff; @@ -436,12 +439,12 @@ static void decode_ca2i(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x += 2) { int y1, y2, u, v, a1, a2; - a1 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - a2 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a1 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + a2 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred[0] = (y1 + pred[0]) & 0x3ff; dst_u[x / 2] = pred[1] = (u + pred[1]) & 0x3ff; @@ -485,12 +488,12 @@ static void decode_ca2p(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x += 2) { int y1, y2, u, v, a1, a2; - a1 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - a2 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a1 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + a2 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred[0] = (y1 + pred[0]) & 0x3ff; dst_u[x / 2] = pred[1] = (u + pred[1]) & 0x3ff; @@ -533,12 +536,12 @@ static void decode_ca2p(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[4] = dst_a[-p->linesize[3] / 2 + x]; pred_T[5] = dst_a[-p->linesize[3] / 2 + x + 1]; - a1 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - a2 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a1 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + a2 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred_L[0] = (y1 + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0x3ff; dst_u[x / 2] = pred_L[1] = (u + (((pred_L[1] - pred_TL[1]) >> 1) + pred_T[1])) & 0x3ff; @@ -588,12 +591,12 @@ static void decode_c82i(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x += 2) { int y1, y2, u, v, a1, a2; - a1 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - a2 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a1 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + a2 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred[0] = (y1 + pred[0]) & 0xff; dst_y[x + 1] = pred[0] = (y2 + pred[0]) & 0xff; @@ -637,12 +640,12 @@ static void decode_c82p(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x += 2) { int y1, y2, u, v, a1, a2; - a1 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - a2 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a1 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + a2 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred[0] = (y1 + pred[0]) & 0xff; dst_u[x / 2] = pred[1] = (u + pred[1]) & 0xff; @@ -685,12 +688,12 @@ static void decode_c82p(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[4] = dst_a[-p->linesize[3] + x]; pred_T[5] = dst_a[-p->linesize[3] + x + 1]; - a1 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - a2 = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a1 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + a2 = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred_L[0] = (y1 + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0xff; dst_u[x / 2] = pred_L[1] = (u + (((pred_L[1] - pred_TL[1]) >> 1) + pred_T[1])) & 0xff; @@ -736,10 +739,10 @@ static void decode_ybyr(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x += 2) { int y1, y2, u, v; - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred[0] = (y1 + pred[0]) & 0xff; dst_u[x / 2] = pred[1] = (u + pred[1]) & 0xff; @@ -774,10 +777,10 @@ static void decode_ybyr(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[1] = dst_u[-p->linesize[1] + x / 2]; pred_T[2] = dst_v[-p->linesize[2] + x / 2]; - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred_L[0] = (y1 + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0xff; dst_u[x / 2] = pred_L[1] = (u + (((pred_L[1] - pred_TL[1]) >> 1) + pred_T[1])) & 0xff; @@ -819,10 +822,10 @@ static void decode_byryi(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x += 2) { int y1, y2, u, v; - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred[0] = (y1 + pred[0]) & 0xff; dst_u[x / 2] = pred[1] = (u + pred[1]) & 0xff; @@ -852,10 +855,10 @@ static void decode_byryi(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_L[2] = dst_v[-p->linesize[2]]; for (x = 0; x < avctx->width; x += 2) { - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred_L[0] = (y1 + pred_L[0]) & 0xff; dst_u[x / 2] = pred_L[1] = (u + pred_L[1]) & 0xff; @@ -893,10 +896,10 @@ static void decode_byry(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x += 2) { int y1, y2, u, v; - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred[0] = (y1 + pred[0]) & 0xff; dst_u[x / 2] = pred[1] = (u + pred[1]) & 0xff; @@ -931,10 +934,10 @@ static void decode_byry(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[1] = dst_u[-p->linesize[1] + x / 2]; pred_T[2] = dst_v[-p->linesize[2] + x / 2]; - y1 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y2 = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y1 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y2 = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x ] = pred_L[0] = (y1 + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0xff; dst_u[x / 2] = pred_L[1] = (u + (((pred_L[1] - pred_TL[1]) >> 1) + pred_T[1])) & 0xff; @@ -975,9 +978,9 @@ static void decode_ybri(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int y, u, v; - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x] = pred[0] = (y + pred[0]) & 0xff; dst_u[x] = pred[1] = (u + pred[1]) & 0xff; @@ -1005,9 +1008,9 @@ static void decode_ybri(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_L[2] = dst_v[-p->linesize[2]]; for (x = 0; x < avctx->width; x++) { - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x] = pred_L[0] = (y + pred_L[0]) & 0xff; dst_u[x] = pred_L[1] = (u + pred_L[1]) & 0xff; @@ -1043,9 +1046,9 @@ static void decode_ybr(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int y, u, v; - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x] = pred[0] = (y + pred[0]) & 0xff; dst_u[x] = pred[1] = (u + pred[1]) & 0xff; @@ -1077,9 +1080,9 @@ static void decode_ybr(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[1] = dst_u[-p->linesize[1] + x]; pred_T[2] = dst_v[-p->linesize[2] + x]; - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_y[x] = pred_L[0] = (y + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0xff; dst_u[x] = pred_L[1] = (u + ((3 * (pred_T[1] + pred_L[1]) - 2 * pred_TL[1]) >> 2)) & 0xff; @@ -1121,10 +1124,10 @@ static void decode_aybri(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int a, y, u, v; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred[0] = (a + pred[0]) & 0xff; dst_y[x] = pred[1] = (y + pred[1]) & 0xff; @@ -1156,10 +1159,10 @@ static void decode_aybri(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_L[3] = dst_v[-p->linesize[2]]; for (x = 0; x < avctx->width; x++) { - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred_L[0] = (a + pred_L[0]) & 0xff; dst_y[x] = pred_L[1] = (y + pred_L[1]) & 0xff; @@ -1199,10 +1202,10 @@ static void decode_aybr(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int a, y, u, v; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred[0] = (a + pred[0]) & 0xff; dst_y[x] = pred[1] = (y + pred[1]) & 0xff; @@ -1239,10 +1242,10 @@ static void decode_aybr(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[2] = dst_u[-p->linesize[1] + x]; pred_T[3] = dst_v[-p->linesize[2] + x]; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - y = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - u = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - v = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + y = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + u = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + v = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred_L[0] = (a + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0xff; dst_y[x] = pred_L[1] = (y + ((3 * (pred_T[1] + pred_L[1]) - 2 * pred_TL[1]) >> 2)) & 0xff; @@ -1288,10 +1291,10 @@ static void decode_argxi(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int r, g, b, a; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred[3] = (a + pred[3]) & 0x3ff; dst_r[x] = pred[0] = (r + pred[0]) & 0x3ff; @@ -1331,10 +1334,10 @@ static void decode_argx(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int r, g, b, a; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred[3] = (a + pred[3]) & 0x3ff; dst_r[x] = pred[0] = (r + pred[0]) & 0x3ff; @@ -1371,10 +1374,10 @@ static void decode_argx(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[2] = dst_b[-p->linesize[1] / 2 + x]; pred_T[3] = dst_a[-p->linesize[3] / 2 + x]; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_a[x] = pred_L[3] = (a + ((3 * (pred_T[3] + pred_L[3]) - 2 * pred_TL[3]) >> 2)) & 0x3ff; dst_r[x] = pred_L[0] = (r + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0x3ff; @@ -1418,9 +1421,9 @@ static void decode_rgbxi(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int r, g, b; - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_r[x] = pred[0] = (r + pred[0]) & 0x3ff; dst_g[x] = pred[1] = (r + g + pred[1]) & 0x3ff; @@ -1456,9 +1459,9 @@ static void decode_rgbx(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int r, g, b; - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_r[x] = pred[0] = (r + pred[0]) & 0x3ff; dst_g[x] = pred[1] = (r + g + pred[1]) & 0x3ff; @@ -1490,9 +1493,9 @@ static void decode_rgbx(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[1] = dst_g[-p->linesize[0] / 2 + x]; pred_T[2] = dst_b[-p->linesize[1] / 2 + x]; - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst_r[x] = pred_L[0] = (r + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0x3ff; dst_g[x] = pred_L[1] = (r + g + ((3 * (pred_T[1] + pred_L[1]) - 2 * pred_TL[1]) >> 2)) & 0x3ff; @@ -1530,10 +1533,10 @@ static void decode_argbi(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int a, r, g, b; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst[4 * x + 0] = pred[0] = (a + pred[0]) & 0xff; dst[4 * x + 1] = pred[1] = (r + pred[1]) & 0xff; @@ -1561,10 +1564,10 @@ static void decode_argbi(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_L[3] = dst[-p->linesize[0] + 3]; for (x = 0; x < avctx->width; x++) { - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst[4 * x + 0] = pred_L[0] = (a + pred_L[0]) & 0xff; dst[4 * x + 1] = pred_L[1] = (r + pred_L[1]) & 0xff; @@ -1596,10 +1599,10 @@ static void decode_argb(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int a, r, g, b; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst[4 * x + 0] = pred[0] = (a + pred[0]) & 0xff; dst[4 * x + 1] = pred[1] = (r + pred[1]) & 0xff; @@ -1632,10 +1635,10 @@ static void decode_argb(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[2] = dst[-p->linesize[0] + 4 * x + 2]; pred_T[3] = dst[-p->linesize[0] + 4 * x + 3]; - a = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + a = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst[4 * x + 0] = pred_L[0] = (a + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0xff; dst[4 * x + 1] = pred_L[1] = (r + ((3 * (pred_T[1] + pred_L[1]) - 2 * pred_TL[1]) >> 2)) & 0xff; @@ -1671,9 +1674,9 @@ static void decode_rgbi(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int r, g, b; - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst[4 * x + 0] = pred[0] = (r + pred[0]) & 0xff; dst[4 * x + 1] = pred[1] = (r + g + pred[1]) & 0xff; @@ -1698,9 +1701,9 @@ static void decode_rgbi(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_L[2] = dst[-p->linesize[0] + 2]; for (x = 0; x < avctx->width; x++) { - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst[4 * x + 0] = pred_L[0] = (r + pred_L[0]) & 0xff; dst[4 * x + 1] = pred_L[1] = (r + g + pred_L[1]) & 0xff; @@ -1730,9 +1733,9 @@ static void decode_rgb(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) for (x = 0; x < avctx->width; x++) { int r, g, b; - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst[4 * x + 0] = pred[0] = (r + pred[0]) & 0xff; dst[4 * x + 1] = pred[1] = (r + g + pred[1]) & 0xff; @@ -1761,9 +1764,9 @@ static void decode_rgb(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) pred_T[1] = dst[-p->linesize[0] + 4 * x + 1]; pred_T[2] = dst[-p->linesize[0] + 4 * x + 2]; - r = get_vlc2(gb, s->vlc[0].table, s->vlc[0].bits, 2); - g = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); - b = get_vlc2(gb, s->vlc[1].table, s->vlc[1].bits, 2); + r = get_vlc2(gb, s->vlc[0].table, SHEER_VLC_BITS, 2); + g = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); + b = get_vlc2(gb, s->vlc[1].table, SHEER_VLC_BITS, 2); dst[4 * x + 0] = pred_L[0] = (r + ((3 * (pred_T[0] + pred_L[0]) - 2 * pred_TL[0]) >> 2)) & 0xff; dst[4 * x + 1] = pred_L[1] = (r + g + ((3 * (pred_T[1] + pred_L[1]) - 2 * pred_TL[1]) >> 2)) & 0xff; @@ -1778,27 +1781,28 @@ static void decode_rgb(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) } } -static int build_vlc(VLC *vlc, const uint8_t *len, int count) +static av_cold int build_vlc(VLC *vlc, const SheerTable *table) { - uint32_t codes[1024]; - uint8_t bits[1024]; - uint16_t syms[1024]; - uint64_t index; - int i; + const uint8_t *cur = table->lens; + uint8_t lens[1024]; + unsigned count = 0; - index = 0; - for (i = 0; i < count; i++) { - codes[i] = index >> (32 - len[i]); - bits[i] = len[i]; - syms[i] = i; - index += 1ULL << (32 - len[i]); + for (int step = 1, len = 1; len > 0; len += step) { + unsigned new_count = count; + + if (len == 16) { + new_count += table->nb_16s; + step = -1; + } else + new_count += *cur++; + + for (; count < new_count; count++) + lens[count] = len; } ff_free_vlc(vlc); - return ff_init_vlc_sparse(vlc, 16, count, - bits, sizeof(*bits), sizeof(*bits), - codes, sizeof(*codes), sizeof(*codes), - syms, sizeof(*syms), sizeof(*syms), 0); + return ff_init_vlc_from_lengths(vlc, SHEER_VLC_BITS, count, + lens, sizeof(*lens), NULL, 0, 0, 0, 0, NULL); } static int decode_frame(AVCodecContext *avctx, @@ -1807,6 +1811,7 @@ static int decode_frame(AVCodecContext *avctx, { SheerVideoContext *s = avctx->priv_data; ThreadFrame frame = { .f = data }; + const SheerTable *table; AVFrame *p = data; GetBitContext gb; unsigned format; @@ -1826,227 +1831,154 @@ static int decode_frame(AVCodecContext *avctx, case MKTAG(' ', 'R', 'G', 'B'): avctx->pix_fmt = AV_PIX_FMT_RGB0; s->decode_frame = decode_rgb; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_r_rgb, 256); - ret |= build_vlc(&s->vlc[1], l_g_rgb, 256); - } + table = rgb; break; case MKTAG(' ', 'r', 'G', 'B'): avctx->pix_fmt = AV_PIX_FMT_RGB0; s->decode_frame = decode_rgbi; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_r_rgbi, 256); - ret |= build_vlc(&s->vlc[1], l_g_rgbi, 256); - } + table = rgbi; break; case MKTAG('A', 'R', 'G', 'X'): avctx->pix_fmt = AV_PIX_FMT_GBRAP10; s->decode_frame = decode_argx; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_r_rgbx, 1024); - ret |= build_vlc(&s->vlc[1], l_g_rgbx, 1024); - } + table = rgbx; break; case MKTAG('A', 'r', 'G', 'X'): avctx->pix_fmt = AV_PIX_FMT_GBRAP10; s->decode_frame = decode_argxi; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_r_rgbxi, 1024); - ret |= build_vlc(&s->vlc[1], l_g_rgbxi, 1024); - } + table = rgbxi; break; case MKTAG('R', 'G', 'B', 'X'): avctx->pix_fmt = AV_PIX_FMT_GBRP10; s->decode_frame = decode_rgbx; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_r_rgbx, 1024); - ret |= build_vlc(&s->vlc[1], l_g_rgbx, 1024); - } + table = rgbx; break; case MKTAG('r', 'G', 'B', 'X'): avctx->pix_fmt = AV_PIX_FMT_GBRP10; s->decode_frame = decode_rgbxi; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_r_rgbxi, 1024); - ret |= build_vlc(&s->vlc[1], l_g_rgbxi, 1024); - } + table = rgbxi; break; case MKTAG('A', 'R', 'G', 'B'): avctx->pix_fmt = AV_PIX_FMT_ARGB; s->decode_frame = decode_argb; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_r_rgb, 256); - ret |= build_vlc(&s->vlc[1], l_g_rgb, 256); - } + table = rgb; break; case MKTAG('A', 'r', 'G', 'B'): avctx->pix_fmt = AV_PIX_FMT_ARGB; s->decode_frame = decode_argbi; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_r_rgbi, 256); - ret |= build_vlc(&s->vlc[1], l_g_rgbi, 256); - } + table = rgbi; break; case MKTAG('A', 'Y', 'B', 'R'): s->alt = 1; case MKTAG('A', 'Y', 'b', 'R'): avctx->pix_fmt = AV_PIX_FMT_YUVA444P; s->decode_frame = decode_aybr; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_ybr, 256); - ret |= build_vlc(&s->vlc[1], l_u_ybr, 256); - } + table = ybr; break; case MKTAG('A', 'y', 'B', 'R'): s->alt = 1; case MKTAG('A', 'y', 'b', 'R'): avctx->pix_fmt = AV_PIX_FMT_YUVA444P; s->decode_frame = decode_aybri; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_ybri, 256); - ret |= build_vlc(&s->vlc[1], l_u_ybri, 256); - } + table = ybri; break; case MKTAG(' ', 'Y', 'B', 'R'): s->alt = 1; case MKTAG(' ', 'Y', 'b', 'R'): avctx->pix_fmt = AV_PIX_FMT_YUV444P; s->decode_frame = decode_ybr; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_ybr, 256); - ret |= build_vlc(&s->vlc[1], l_u_ybr, 256); - } + table = ybr; break; case MKTAG(' ', 'y', 'B', 'R'): s->alt = 1; case MKTAG(' ', 'y', 'b', 'R'): avctx->pix_fmt = AV_PIX_FMT_YUV444P; s->decode_frame = decode_ybri; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_ybri, 256); - ret |= build_vlc(&s->vlc[1], l_u_ybri, 256); - } + table = ybri; break; case MKTAG('Y', 'B', 'R', 0x0a): avctx->pix_fmt = AV_PIX_FMT_YUV444P10; s->decode_frame = decode_ybr10; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_ybr10, 1024); - ret |= build_vlc(&s->vlc[1], l_u_ybr10, 1024); - } + table = ybr10; break; case MKTAG('y', 'B', 'R', 0x0a): avctx->pix_fmt = AV_PIX_FMT_YUV444P10; s->decode_frame = decode_ybr10i; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_ybr10i, 1024); - ret |= build_vlc(&s->vlc[1], l_u_ybr10i, 1024); - } + table = ybr10i; break; case MKTAG('C', 'A', '4', 'p'): avctx->pix_fmt = AV_PIX_FMT_YUVA444P10; s->decode_frame = decode_ca4p; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_ybr10, 1024); - ret |= build_vlc(&s->vlc[1], l_u_ybr10, 1024); - } + table = ybr10; break; case MKTAG('C', 'A', '4', 'i'): avctx->pix_fmt = AV_PIX_FMT_YUVA444P10; s->decode_frame = decode_ca4i; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_ybr10i, 1024); - ret |= build_vlc(&s->vlc[1], l_u_ybr10i, 1024); - } + table = ybr10i; break; case MKTAG('B', 'Y', 'R', 'Y'): avctx->pix_fmt = AV_PIX_FMT_YUV422P; s->decode_frame = decode_byry; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_byry, 256); - ret |= build_vlc(&s->vlc[1], l_u_byry, 256); - } + table = byry; break; case MKTAG('B', 'Y', 'R', 'y'): avctx->pix_fmt = AV_PIX_FMT_YUV422P; s->decode_frame = decode_byryi; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_byryi, 256); - ret |= build_vlc(&s->vlc[1], l_u_byryi, 256); - } + table = byryi; break; case MKTAG('Y', 'b', 'Y', 'r'): avctx->pix_fmt = AV_PIX_FMT_YUV422P; s->decode_frame = decode_ybyr; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_ybyr, 256); - ret |= build_vlc(&s->vlc[1], l_u_ybyr, 256); - } + table = ybyr; break; case MKTAG('C', '8', '2', 'p'): avctx->pix_fmt = AV_PIX_FMT_YUVA422P; s->decode_frame = decode_c82p; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_byry, 256); - ret |= build_vlc(&s->vlc[1], l_u_byry, 256); - } + table = byry; break; case MKTAG('C', '8', '2', 'i'): avctx->pix_fmt = AV_PIX_FMT_YUVA422P; s->decode_frame = decode_c82i; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_byryi, 256); - ret |= build_vlc(&s->vlc[1], l_u_byryi, 256); - } + table = byryi; break; case MKTAG(0xa2, 'Y', 'R', 'Y'): avctx->pix_fmt = AV_PIX_FMT_YUV422P10; s->decode_frame = decode_yry10; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_yry10, 1024); - ret |= build_vlc(&s->vlc[1], l_u_yry10, 1024); - } + table = yry10; break; case MKTAG(0xa2, 'Y', 'R', 'y'): avctx->pix_fmt = AV_PIX_FMT_YUV422P10; s->decode_frame = decode_yry10i; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_yry10i, 1024); - ret |= build_vlc(&s->vlc[1], l_u_yry10i, 1024); - } + table = yry10i; break; case MKTAG('C', 'A', '2', 'p'): avctx->pix_fmt = AV_PIX_FMT_YUVA422P10; s->decode_frame = decode_ca2p; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_yry10, 1024); - ret |= build_vlc(&s->vlc[1], l_u_yry10, 1024); - } + table = yry10; break; case MKTAG('C', 'A', '2', 'i'): avctx->pix_fmt = AV_PIX_FMT_YUVA422P10; s->decode_frame = decode_ca2i; - if (s->format != format) { - ret = build_vlc(&s->vlc[0], l_y_yry10i, 1024); - ret |= build_vlc(&s->vlc[1], l_u_yry10i, 1024); - } + table = yry10i; break; default: avpriv_request_sample(avctx, "unsupported format: 0x%X", format); return AVERROR_PATCHWELCOME; } + if (s->format != format) { + if ((ret = build_vlc(&s->vlc[0], &table[0])) < 0 || + (ret = build_vlc(&s->vlc[1], &table[1])) < 0) { + s->format = 0; + return ret; + } + s->format = format; + } if (avpkt->size < 20 + avctx->width * avctx->height / 16) { av_log(avctx, AV_LOG_ERROR, "Input packet too small\n"); return AVERROR_INVALIDDATA; } - if (s->format != format) { - if (ret < 0) - return ret; - s->format = format; - } - p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; diff --git a/libavcodec/sheervideodata.h b/libavcodec/sheervideodata.h index 3b6e2f659..fbce3a412 100644 --- a/libavcodec/sheervideodata.h +++ b/libavcodec/sheervideodata.h @@ -24,1074 +24,152 @@ #include "libavutil/common.h" -static const uint8_t l_r_rgb[256] = { - 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, - 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, - 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, - 8, 8, 8, 7, 7, 7, 7, 7, 6, 6, 6, 5, 5, 4, 4, 4, +typedef struct SheerTable { + uint8_t lens[2 * 15]; + uint16_t nb_16s; +} SheerTable; + +static const SheerTable rgb[2] = { + { + { 0, 0, 2, 2, 3, 3, 5, 5, 8, 8, 10, 9, 14, 15, 18, + 17, 16, 13, 10, 10, 8, 7, 6, 5, 3, 2, 3, 0, 0, 0 }, 54 + }, + { + { 0, 2, 0, 2, 0, 1, 1, 0, 2, 1, 3, 3, 4, 7, 13, + 11, 8, 4, 3, 3, 1, 2, 1, 0, 1, 0, 1, 2, 0, 0 }, 180 + } }; -static const uint8_t l_r_rgbi[256] = { - 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 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, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, - 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 4, 4, 4, +static const SheerTable rgbi[2] = { + { + { 0, 0, 1, 3, 3, 3, 6, 8, 8, 11, 12, 15, 18, 21, 38, + 0, 22, 19, 15, 12, 11, 7, 8, 6, 4, 2, 3, 0, 0, 0 }, 0 + }, + { + { 1, 0, 1, 1, 1, 1, 2, 1, 2, 4, 3, 5, 5, 6, 12, + 14, 6, 6, 5, 3, 3, 3, 2, 1, 1, 2, 0, 1, 0, 0 }, 164 + } }; -static const uint8_t l_g_rgbi[256] = { - 1, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 10, 10, 11, 11, - 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, - 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, - 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, - 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 7, 6, 5, 5, 3, +static const SheerTable ybr[2] = { + { + { 0, 0, 2, 2, 2, 3, 5, 5, 7, 7, 8, 9, 13, 13, 19, + 16, 14, 12, 9, 9, 7, 6, 6, 4, 4, 1, 2, 1, 0, 0 }, 70 + }, + { + { 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 2, 2, 3, 5, 5, + 5, 5, 3, 2, 2, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0 }, 212 + } }; -static const uint8_t l_g_rgb[256] = { - 2, 2, 4, 4, 6, 7, 9, 9, 10, 11, 11, 11, 12, 12, 12, 13, - 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, - 13, 13, 12, 12, 12, 11, 11, 11, 10, 9, 9, 8, 6, 4, 3, 3, +static const SheerTable ybyr[2] = { + { + { 0, 0, 2, 2, 3, 3, 5, 5, 8, 8, 10, 10, 13, 15, 19, + 18, 15, 12, 10, 10, 8, 7, 6, 5, 3, 2, 3, 0, 0, 0 }, 54 + }, + { + { 1, 1, 0, 1, 0, 1, 0, 1, 1, 2, 2, 3, 2, 5, 5, + 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 1, 0, 0 }, 208 + } }; -static const uint8_t l_y_ybr[256] = { - 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, - 8, 8, 8, 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, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 4, 4, 3, +static const SheerTable byry[2] = { + { + { 0, 0, 2, 2, 2, 3, 5, 5, 7, 7, 8, 11, 10, 14, 19, + 14, 16, 12, 10, 8, 7, 6, 6, 4, 4, 1, 2, 1, 0, 0 }, 70 + }, + { + { 1, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2, 2, 3, 4, 6, + 6, 4, 2, 3, 2, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0 }, 208 + } }; -static const uint8_t l_u_ybr[256] = { - 1, 2, 4, 6, 9, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, - 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, - 14, 14, 14, 14, 14, 13, 13, 13, 12, 12, 11, 11, 10, 8, 5, 3, +static const SheerTable ybr10i[2] = { + { + { 0, 0, 1, 0, 3, 8, 9, 12, 19, 27, 27, 39, 50, 63, 93, + 89, 64, 50, 38, 26, 26, 20, 12, 9, 8, 3, 0, 0, 0, 0 }, 328 + }, + { + { 0, 1, 1, 2, 2, 1, 2, 2, 4, 4, 6, 7, 9, 13, 28, + 28, 12, 11, 6, 7, 5, 3, 3, 1, 1, 2, 2, 1, 0, 0 }, 860 + } }; -static const uint8_t l_y_ybyr[256] = { - 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, - 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, - 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, - 8, 8, 8, 7, 7, 7, 7, 7, 6, 6, 6, 5, 5, 4, 4, 4, +static const SheerTable ybr10[2] = { + { + { 0, 0, 0, 1, 6, 6, 8, 12, 18, 21, 27, 29, 36, 47, 71, + 72, 46, 36, 29, 27, 21, 17, 13, 7, 7, 5, 0, 0, 0, 0 }, 462 + }, + { + { 0, 1, 2, 1, 2, 1, 1, 1, 2, 3, 2, 5, 6, 10, 20, + 20, 10, 6, 4, 3, 2, 2, 2, 1, 1, 1, 2, 1, 0, 0 }, 912 + } }; -static const uint8_t l_u_ybyr[256] = { - 1, 2, 4, 6, 8, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, - 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 14, 14, - 14, 14, 13, 13, 13, 12, 12, 11, 11, 10, 10, 9, 8, 7, 6, 3, +static const SheerTable rgbx[2] = { + { + { 0, 0, 0, 1, 3, 9, 10, 13, 19, 26, 28, 35, 40, 53, 77, + 77, 50, 42, 34, 28, 25, 19, 13, 10, 8, 4, 0, 0, 0, 0 }, 400 + }, + { + { 0, 0, 1, 2, 6, 4, 3, 2, 3, 4, 6, 8, 10, 18, 39, + 39, 18, 11, 8, 6, 4, 4, 1, 3, 5, 4, 3, 0, 0, 0 }, 812 + } }; -static const uint8_t l_y_byry[256] = { - 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, - 8, 8, 8, 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, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, - 11, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 4, 4, 3, +static const SheerTable yry10[2] = { + { + { 0, 0, 0, 1, 6, 6, 8, 12, 18, 21, 27, 29, 36, 47, 71, + 72, 46, 36, 29, 27, 21, 17, 13, 7, 7, 5, 0, 0, 0, 0 }, 462 + }, + { + { 0, 1, 2, 1, 1, 1, 2, 3, 2, 4, 5, 5, 8, 14, 16, + 18, 11, 7, 7, 4, 4, 3, 2, 2, 1, 1, 2, 1, 0, 0 }, 896 + } }; -static const uint8_t l_u_byry[256] = { - 1, 2, 4, 6, 8, 9, 9, 10, 11, 11, 12, 12, 13, 13, 13, 14, - 14, 14, 14, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, - 14, 14, 14, 13, 13, 12, 12, 12, 11, 11, 10, 9, 8, 7, 6, 3, +static const SheerTable yry10i[2] = { + { + { 0, 0, 1, 0, 3, 8, 9, 12, 19, 27, 27, 40, 48, 64, 93, + 89, 65, 49, 38, 26, 26, 20, 12, 9, 8, 3, 0, 0, 0, 0 }, 328 + }, + { + { 0, 1, 0, 3, 1, 3, 3, 3, 6, 7, 7, 12, 11, 19, 23, + 20, 18, 12, 12, 8, 6, 5, 4, 3, 2, 2, 2, 1, 0, 0 }, 830 + } }; -static const uint8_t l_y_ybr10i[1024] = { - 3, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 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, 9, 9, 9, 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, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 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, 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, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 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, - 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, 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, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 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, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, +static const SheerTable ybri[2] = { + { + { 0, 0, 2, 2, 2, 3, 5, 5, 7, 10, 11, 13, 15, 13, 26, + 20, 16, 17, 12, 11, 9, 7, 5, 5, 3, 3, 1, 1, 0, 0 }, 32 + }, + { + { 1, 0, 1, 0, 1, 1, 0, 2, 1, 2, 2, 2, 3, 6, 6, + 5, 6, 3, 2, 2, 2, 1, 2, 0, 1, 1, 0, 0, 1, 0 }, 202 + } }; -static const uint8_t l_y_ybr10[1024] = { - 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, - 7, 7, 7, 7, 7, 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, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 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, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 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, 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, 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, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, - 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, +static const SheerTable byryi[2] = { + { + { 0, 0, 2, 2, 2, 2, 6, 5, 8, 8, 12, 12, 16, 14, 24, + 20, 16, 18, 12, 12, 8, 7, 5, 6, 3, 1, 2, 1, 0, 0 }, 32 + }, + { + { 1, 0, 1, 1, 0, 2, 1, 2, 2, 3, 3, 4, 5, 4, 6, + 7, 5, 4, 4, 3, 3, 2, 2, 2, 0, 1, 1, 1, 0, 0 }, 186 + } }; -static const uint8_t l_u_ybr10i[1024] = { - 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 10, - 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 10, 10, - 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 6, 5, 5, 4, 4, 3, -}; - -static const uint8_t l_u_ybr10[1024] = { - 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, 10, 11, 11, - 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 12, - 12, 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 6, 5, 4, 4, 3, -}; - -static const uint8_t l_r_rgbx[1024] = { - 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 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, 9, 9, 9, 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, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 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, 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, 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, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 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, 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, 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, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 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, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, -}; - -static const uint8_t l_g_rgbx[1024] = { - 3, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, - 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, - 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, - 12, 12, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, - 8, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, -}; - -static const uint8_t l_y_yry10[1024] = { - 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, - 7, 7, 7, 7, 7, 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, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 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, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 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, 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, 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, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, - 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, -}; - -static const uint8_t l_y_yry10i[1024] = { - 3, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 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, 9, 9, 9, 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, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 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, 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, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 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, - 14, 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, 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, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 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, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, -}; - -static const uint8_t l_u_yry10[1024] = { - 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, - 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, - 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, - 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, - 10, 10, 10, 10, 9, 9, 9, 8, 8, 7, 7, 6, 5, 4, 4, 3, -}; - -static const uint8_t l_u_yry10i[1024] = { - 2, 4, 4, 4, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, - 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, - 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, - 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 9, 9, 9, - 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 5, 4, 4, 3, -}; - -static const uint8_t l_y_ybri[256] = { - 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, - 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 7, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 3, -}; - -static const uint8_t l_u_ybri[256] = { - 1, 3, 5, 6, 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 13, - 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, - 14, 13, 13, 13, 12, 12, 11, 11, 10, 10, 9, 8, 8, 6, 5, 2, -}; - -static const uint8_t l_y_byryi[256] = { - 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, - 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, - 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, - 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 5, 4, 4, 3, -}; - -static const uint8_t l_u_byryi[256] = { - 1, 3, 4, 6, 6, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, - 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, - 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, - 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, - 12, 11, 11, 11, 10, 10, 10, 9, 9, 8, 8, 7, 7, 5, 4, 3, -}; - -static const uint8_t l_r_rgbxi[1024] = { - 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 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, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 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, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 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, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5, 4, 4, 4, -}; - -static const uint8_t l_g_rgbxi[1024] = { - 2, 3, 4, 4, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, - 11, 11, 11, 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, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, - 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, - 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 4, 4, 3, +static const SheerTable rgbxi[2] = { + { + { 0, 0, 1, 3, 2, 3, 4, 6, 16, 23, 27, 29, 24, 29, 76, + 78, 29, 21, 29, 27, 23, 15, 7, 4, 3, 2, 3, 0, 0, 0 }, 540 + }, + { + { 0, 1, 1, 2, 0, 2, 6, 4, 3, 9, 7, 12, 13, 16, 29, + 32, 17, 14, 12, 7, 8, 4, 4, 6, 2, 0, 2, 1, 0, 0 }, 810 + } }; #endif /* AVCODEC_SHEERVIDEODATA_H */ diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 4134af74c..70d164a0b 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -808,8 +808,12 @@ AVCodec ff_shorten_decoder = { .init = shorten_decode_init, .close = shorten_decode_close, .decode = shorten_decode_frame, - .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DELAY | + AV_CODEC_CAP_DR1 | + AV_CODEC_CAP_SUBFRAMES , .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/sinewin.c b/libavcodec/sinewin.c index 4532dc735..1fa0e953f 100644 --- a/libavcodec/sinewin.c +++ b/libavcodec/sinewin.c @@ -16,6 +16,5 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define USE_FIXED 0 #include "sinewin.h" #include "sinewin_tablegen.h" diff --git a/libavcodec/sinewin.h b/libavcodec/sinewin.h index 329e9bb5b..fc4e69a58 100644 --- a/libavcodec/sinewin.h +++ b/libavcodec/sinewin.h @@ -22,8 +22,7 @@ #define AVCODEC_SINEWIN_H #include "config.h" -#include "libavutil/mem.h" -#include "libavcodec/aac_defines.h" +#include "libavutil/mem_internal.h" #if CONFIG_HARDCODED_TABLES # define SINETABLE_CONST const @@ -31,40 +30,31 @@ # define SINETABLE_CONST #endif -#ifndef USE_FIXED -#define USE_FIXED 0 -#endif - #define SINETABLE(size) \ - SINETABLE_CONST DECLARE_ALIGNED(32, INTFLOAT, AAC_RENAME(ff_sine_##size))[size] - -#define SINETABLE120960(size) \ - DECLARE_ALIGNED(32, INTFLOAT, AAC_RENAME(ff_sine_##size))[size] + SINETABLE_CONST DECLARE_ALIGNED(32, float, ff_sine_##size)[size] /** * Generate a sine window. * @param window pointer to half window * @param n size of half window */ -void AAC_RENAME(ff_sine_window_init)(INTFLOAT *window, int n); +void ff_sine_window_init(float *window, int n); /** * initialize the specified entry of ff_sine_windows */ -void AAC_RENAME(ff_init_ff_sine_windows)(int index); +void ff_init_ff_sine_windows(int index); extern SINETABLE( 32); extern SINETABLE( 64); -extern SINETABLE120960(120); extern SINETABLE( 128); extern SINETABLE( 256); extern SINETABLE( 512); -extern SINETABLE120960(960); extern SINETABLE(1024); extern SINETABLE(2048); extern SINETABLE(4096); extern SINETABLE(8192); -extern SINETABLE_CONST INTFLOAT * const AAC_RENAME(ff_sine_windows)[16]; +extern SINETABLE_CONST float *const ff_sine_windows[]; #endif /* AVCODEC_SINEWIN_H */ diff --git a/libavcodec/sinewin_fixed_tablegen.c b/libavcodec/sinewin_fixed_tablegen.c index 977e6f3cb..61e5274af 100644 --- a/libavcodec/sinewin_fixed_tablegen.c +++ b/libavcodec/sinewin_fixed_tablegen.c @@ -20,5 +20,23 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define USE_FIXED 1 -#include "sinewin_tablegen_template.c" +#include "tableprint.h" + +#define BUILD_TABLES +#define CONFIG_HARDCODED_TABLES 0 +#include "sinewin_fixed_tablegen.h" + +int main(void) +{ + write_fileheader(); + + init_sine_windows_fixed(); +#define PRINT_TABLE(size) \ + printf("SINETABLE("#size") = {\n"); \ + write_int32_t_array(sine_ ## size ## _fixed, size); \ + printf("};\n") + PRINT_TABLE(128); + PRINT_TABLE(512); + PRINT_TABLE(1024); + return 0; +} diff --git a/libavcodec/sinewin_fixed_tablegen.h b/libavcodec/sinewin_fixed_tablegen.h new file mode 100644 index 000000000..c52c90bed --- /dev/null +++ b/libavcodec/sinewin_fixed_tablegen.h @@ -0,0 +1,67 @@ +/* + * Header file for hardcoded sine windows + * + * Copyright (c) 2009 Reimar Döffinger + * + * 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_SINEWIN_FIXED_TABLEGEN_H +#define AVCODEC_SINEWIN_FIXED_TABLEGEN_H + +#ifdef BUILD_TABLES +#undef DECLARE_ALIGNED +#define DECLARE_ALIGNED(align, type, name) type name +#else +#include "libavutil/mem_internal.h" +#endif + +#define SINETABLE(size) \ + static SINETABLE_CONST DECLARE_ALIGNED(32, int, sine_##size##_fixed)[size] + +#if CONFIG_HARDCODED_TABLES +#define init_sine_windows_fixed() +#define SINETABLE_CONST const +#include "libavcodec/sinewin_fixed_tables.h" +#else +// do not use libavutil/libm.h since this is compiled both +// for the host and the target and config.h is only valid for the target +#include +#include "libavutil/attributes.h" + +#define SINETABLE_CONST +SINETABLE( 128); +SINETABLE( 512); +SINETABLE(1024); + +#define SIN_FIX(a) (int)floor((a) * 0x80000000 + 0.5) + +// Generate a sine window. +static av_cold void sine_window_init_fixed(int *window, int n) +{ + for (int i = 0; i < n; i++) + window[i] = SIN_FIX(sinf((i + 0.5) * (M_PI / (2.0 * n)))); +} + +static av_cold void init_sine_windows_fixed(void) +{ + sine_window_init_fixed(sine_128_fixed, 128); + sine_window_init_fixed(sine_512_fixed, 512); + sine_window_init_fixed(sine_1024_fixed, 1024); +} +#endif /* CONFIG_HARDCODED_TABLES */ +#endif /* AVCODEC_SINEWIN_FIXED_TABLEGEN_H */ diff --git a/libavcodec/sinewin_tablegen.c b/libavcodec/sinewin_tablegen.c index dd602668e..438030ea8 100644 --- a/libavcodec/sinewin_tablegen.c +++ b/libavcodec/sinewin_tablegen.c @@ -20,5 +20,26 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define USE_FIXED 0 -#include "sinewin_tablegen_template.c" +#define CONFIG_HARDCODED_TABLES 0 +#define BUILD_TABLES + +#define SINETABLE_CONST +#define SINETABLE(size) \ + float ff_sine_##size[size] +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) +#include "sinewin_tablegen.h" +#include "tableprint.h" + +int main(void) +{ + write_fileheader(); + + for (int i = 5; i <= 13; i++) { + ff_init_ff_sine_windows(i); + printf("SINETABLE(%4i) = {\n", 1 << i); + write_float_array(ff_sine_windows[i], 1 << i); + printf("};\n"); + } + + return 0; +} diff --git a/libavcodec/sinewin_tablegen.h b/libavcodec/sinewin_tablegen.h index dc52234ed..6887d59cf 100644 --- a/libavcodec/sinewin_tablegen.h +++ b/libavcodec/sinewin_tablegen.h @@ -27,15 +27,14 @@ // do not use libavutil/libm.h since this is compiled both // for the host and the target and config.h is only valid for the target #include -#include "libavcodec/aac_defines.h" #include "libavutil/attributes.h" #include "libavutil/common.h" -#if !USE_FIXED -SINETABLE120960(120); -SINETABLE120960(960); -#endif #if !CONFIG_HARDCODED_TABLES +#ifndef BUILD_TABLES +#include "libavutil/thread.h" +#endif + SINETABLE( 32); SINETABLE( 64); SINETABLE( 128); @@ -46,37 +45,68 @@ SINETABLE(2048); SINETABLE(4096); SINETABLE(8192); #else -#if USE_FIXED -#include "libavcodec/sinewin_fixed_tables.h" -#else #include "libavcodec/sinewin_tables.h" #endif -#endif -#if USE_FIXED -#define SIN_FIX(a) (int)floor((a) * 0x80000000 + 0.5) -#else -#define SIN_FIX(a) a -#endif - -SINETABLE_CONST INTFLOAT * const AAC_RENAME(ff_sine_windows)[] = { +SINETABLE_CONST float *const ff_sine_windows[] = { NULL, NULL, NULL, NULL, NULL, // unused - AAC_RENAME(ff_sine_32) , AAC_RENAME(ff_sine_64), AAC_RENAME(ff_sine_128), - AAC_RENAME(ff_sine_256), AAC_RENAME(ff_sine_512), AAC_RENAME(ff_sine_1024), - AAC_RENAME(ff_sine_2048), AAC_RENAME(ff_sine_4096), AAC_RENAME(ff_sine_8192), + ff_sine_32, ff_sine_64, ff_sine_128, + ff_sine_256, ff_sine_512, ff_sine_1024, + ff_sine_2048, ff_sine_4096, ff_sine_8192, }; // Generate a sine window. -av_cold void AAC_RENAME(ff_sine_window_init)(INTFLOAT *window, int n) { +av_cold void ff_sine_window_init(float *window, int n) +{ int i; for(i = 0; i < n; i++) - window[i] = SIN_FIX(sinf((i + 0.5) * (M_PI / (2.0 * n)))); + window[i] = sinf((i + 0.5) * (M_PI / (2.0 * n))); } -av_cold void AAC_RENAME(ff_init_ff_sine_windows)(int index) { - assert(index >= 0 && index < FF_ARRAY_ELEMS(AAC_RENAME(ff_sine_windows))); +#if !CONFIG_HARDCODED_TABLES && !defined(BUILD_TABLES) +#define INIT_FF_SINE_WINDOW_INIT_FUNC(index) \ +static void init_ff_sine_window_ ## index(void) \ +{ \ + ff_sine_window_init(ff_sine_windows[index], 1 << index);\ +} + +INIT_FF_SINE_WINDOW_INIT_FUNC(5) +INIT_FF_SINE_WINDOW_INIT_FUNC(6) +INIT_FF_SINE_WINDOW_INIT_FUNC(7) +INIT_FF_SINE_WINDOW_INIT_FUNC(8) +INIT_FF_SINE_WINDOW_INIT_FUNC(9) +INIT_FF_SINE_WINDOW_INIT_FUNC(10) +INIT_FF_SINE_WINDOW_INIT_FUNC(11) +INIT_FF_SINE_WINDOW_INIT_FUNC(12) +INIT_FF_SINE_WINDOW_INIT_FUNC(13) + +static void (*const sine_window_init_func_array[])(void) = { + init_ff_sine_window_5, + init_ff_sine_window_6, + init_ff_sine_window_7, + init_ff_sine_window_8, + init_ff_sine_window_9, + init_ff_sine_window_10, + init_ff_sine_window_11, + init_ff_sine_window_12, + init_ff_sine_window_13, +}; + +static AVOnce init_sine_window_once[9] = { + AV_ONCE_INIT, AV_ONCE_INIT, AV_ONCE_INIT, AV_ONCE_INIT, AV_ONCE_INIT, + AV_ONCE_INIT, AV_ONCE_INIT, AV_ONCE_INIT, AV_ONCE_INIT +}; +#endif + +av_cold void ff_init_ff_sine_windows(int index) +{ + assert(index >= 5 && index < FF_ARRAY_ELEMS(ff_sine_windows)); #if !CONFIG_HARDCODED_TABLES - AAC_RENAME(ff_sine_window_init)(AAC_RENAME(ff_sine_windows)[index], 1 << index); +#ifdef BUILD_TABLES + ff_sine_window_init(ff_sine_windows[index], 1 << index); +#else + ff_thread_once(&init_sine_window_once[index - 5], sine_window_init_func_array[index - 5]); +#endif #endif } diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index 1b6de25ff..7ba9fd4a0 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -570,5 +570,6 @@ AVCodec ff_sipr_decoder = { .priv_data_size = sizeof(SiprContext), .init = sipr_decoder_init, .decode = sipr_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/sipr.h b/libavcodec/sipr.h index 34f7f994c..e1ef35d65 100644 --- a/libavcodec/sipr.h +++ b/libavcodec/sipr.h @@ -26,7 +26,7 @@ #include "avcodec.h" #include "acelp_pitch_delay.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #define LP_FILTER_ORDER_16k 16 #define L_SUBFR_16k 80 diff --git a/libavcodec/siren.c b/libavcodec/siren.c index 1998fa4e6..22b699717 100644 --- a/libavcodec/siren.c +++ b/libavcodec/siren.c @@ -23,6 +23,7 @@ #include "libavutil/tx.h" #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "get_bits.h" @@ -352,6 +353,7 @@ static const float noise_category6[21] = { }; #define FRAME_SIZE 320 +#define REGION_SIZE 20 typedef struct SirenContext { GetBitContext gb; @@ -361,7 +363,6 @@ typedef struct SirenContext { int number_of_regions; int scale_factor; int sample_rate_bits; - int region_size; unsigned dw1, dw2, dw3, dw4; @@ -402,7 +403,6 @@ static av_cold int siren_init(AVCodecContext *avctx) s->esf_adjustment = 7; s->number_of_regions = 14; s->scale_factor = 22; - s->region_size = 20; s->dw1 = s->dw2 = s->dw3 = s->dw4 = 1; for (i = 0; i < 64; i++) { @@ -574,7 +574,7 @@ static int decode_vector(SirenContext *s, int number_of_regions, for (region = 0; region < number_of_regions; region++) { category = power_categories[region]; - coefs_ptr = coefs + (region * s->region_size); + coefs_ptr = coefs + (region * REGION_SIZE); if (category >= 0 && category < 7) { decoder_tree = decoder_tables[category]; @@ -623,32 +623,27 @@ static int decode_vector(SirenContext *s, int number_of_regions, } } - coefs_ptr = coefs + (region * s->region_size); + coefs_ptr = coefs + (region * REGION_SIZE); - if (category == 5) { + if (category == 5 || category == 6) { i = 0; - for (j = 0; j < s->region_size; j++) { + for (j = 0; j < REGION_SIZE; j++) { if (*coefs_ptr != 0) i++; coefs_ptr++; } - noise = decoder_standard_deviation[region] * noise_category5[i]; - } else if (category == 6) { - i = 0; - for (j = 0; j < s->region_size; j++) { - if (*coefs_ptr++ != 0) - i++; - } - - noise = decoder_standard_deviation[region] * noise_category6[i]; + if (category == 5) { + noise = decoder_standard_deviation[region] * noise_category5[i]; + } else + noise = decoder_standard_deviation[region] * noise_category6[i]; } else if (category == 7) { noise = decoder_standard_deviation[region] * 0.70711f; } else { noise = 0; } - coefs_ptr = coefs + (region * s->region_size); + coefs_ptr = coefs + (region * REGION_SIZE); if (category == 5 || category == 6 || category == 7) { dw1 = get_dw(s); @@ -774,7 +769,8 @@ AVCodec ff_siren_decoder = { .close = siren_close, .decode = siren_decode, .flush = siren_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | + AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index 07c713c90..8db33c927 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -33,19 +33,27 @@ #include "libavutil/channel_layout.h" -#define BITSTREAM_READER_LE #include "avcodec.h" -#include "bytestream.h" -#include "get_bits.h" -#include "internal.h" -#include "mathops.h" #define SMKTREE_BITS 9 #define SMK_NODE 0x80000000 -#define SMKTREE_DECODE_MAX_RECURSION 32 +#define SMKTREE_DECODE_MAX_RECURSION FFMIN(32, 3 * SMKTREE_BITS) #define SMKTREE_DECODE_BIG_MAX_RECURSION 500 +/* The maximum possible unchecked overread happens in decode_header_trees: + * Decoding the MMAP tree can overread by 6 * SMKTREE_BITS + 1, followed by + * three get_bits1, followed by at most 2 + 3 * 16 read bits when reading + * the TYPE tree before the next check. 64 is because of 64 bit reads. */ +#if (6 * SMKTREE_BITS + 1 + 3 + (2 + 3 * 16) + 64) <= 8 * AV_INPUT_BUFFER_PADDING_SIZE +#define UNCHECKED_BITSTREAM_READER 1 +#endif +#define BITSTREAM_READER_LE +#include "bytestream.h" +#include "get_bits.h" +#include "internal.h" +#include "mathops.h" + typedef struct SmackVContext { AVCodecContext *avctx; AVFrame *pic; @@ -54,25 +62,27 @@ typedef struct SmackVContext { int mmap_last[3], mclr_last[3], full_last[3], type_last[3]; } SmackVContext; +typedef struct HuffEntry { + uint8_t value; + uint8_t length; +} HuffEntry; + /** * Context used for code reconstructing */ typedef struct HuffContext { - int length; - int maxlength; int current; - uint32_t *bits; - int *lengths; - int *values; + HuffEntry entries[256]; } HuffContext; /* common parameters used for decode_bigtree */ typedef struct DBCtx { + int current, length; + int *values; VLC *v1, *v2; - int *recode1, *recode2; + uint8_t vals[2]; int escapes[3]; int *last; - int lcur; } DBCtx; /* possible runs of blocks */ @@ -94,8 +104,11 @@ enum SmkBlockTypes { /** * Decode local frame tree + * + * Can read SMKTREE_DECODE_MAX_RECURSION before the first check; + * does not overread gb on success. */ -static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length) +static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, int length) { if (length > SMKTREE_DECODE_MAX_RECURSION || length > 3 * SMKTREE_BITS) { av_log(NULL, AV_LOG_ERROR, "Maximum tree recursion level exceeded.\n"); @@ -103,37 +116,30 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref } if(!get_bits1(gb)){ //Leaf - if(hc->current >= hc->length){ + if (hc->current >= 256) { av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); return AVERROR_INVALIDDATA; } - if(length){ - hc->bits[hc->current] = prefix; - hc->lengths[hc->current] = length; - } else { - hc->bits[hc->current] = 0; - hc->lengths[hc->current] = 0; - } - hc->values[hc->current] = get_bits(gb, 8); - hc->current++; - if(hc->maxlength < length) - hc->maxlength = length; + if (get_bits_left(gb) < 8) + return AVERROR_INVALIDDATA; + hc->entries[hc->current++] = (HuffEntry){ get_bits(gb, 8), length }; return 0; } else { //Node int r; length++; - r = smacker_decode_tree(gb, hc, prefix, length); + r = smacker_decode_tree(gb, hc, length); if(r) return r; - return smacker_decode_tree(gb, hc, prefix | (1 << (length - 1)), length); + return smacker_decode_tree(gb, hc, length); } } /** * Decode header tree + * + * Checks before the first read, can overread by 6 * SMKTREE_BITS on success. */ -static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, - DBCtx *ctx, int length) +static int smacker_decode_bigtree(GetBitContext *gb, DBCtx *ctx, int length) { // Larger length can cause segmentation faults due to too deep recursion. if (length > SMKTREE_DECODE_BIG_MAX_RECURSION) { @@ -141,40 +147,42 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, return AVERROR_INVALIDDATA; } - if (hc->current + 1 >= hc->length) { + if (ctx->current >= ctx->length) { av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); return AVERROR_INVALIDDATA; } + if (get_bits_left(gb) <= 0) + return AVERROR_INVALIDDATA; if(!get_bits1(gb)){ //Leaf int val, i1, i2; - i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) : 0; - i2 = ctx->v2->table ? get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3) : 0; - if (i1 < 0 || i2 < 0) - return AVERROR_INVALIDDATA; - val = ctx->recode1[i1] | (ctx->recode2[i2] << 8); + i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) + : ctx->vals[0]; + i2 = ctx->v2->table ? get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3) + : ctx->vals[1]; + val = i1 | (i2 << 8); if(val == ctx->escapes[0]) { - ctx->last[0] = hc->current; + ctx->last[0] = ctx->current; val = 0; } else if(val == ctx->escapes[1]) { - ctx->last[1] = hc->current; + ctx->last[1] = ctx->current; val = 0; } else if(val == ctx->escapes[2]) { - ctx->last[2] = hc->current; + ctx->last[2] = ctx->current; val = 0; } - hc->values[hc->current++] = val; + ctx->values[ctx->current++] = val; return 1; } else { //Node int r = 0, r_new, t; - t = hc->current++; - r = smacker_decode_bigtree(gb, hc, ctx, length + 1); + t = ctx->current++; + r = smacker_decode_bigtree(gb, ctx, length + 1); if(r < 0) return r; - hc->values[t] = SMK_NODE | r; + ctx->values[t] = SMK_NODE | r; r++; - r_new = smacker_decode_bigtree(gb, hc, ctx, length + 1); + r_new = smacker_decode_bigtree(gb, ctx, length + 1); if (r_new < 0) return r_new; return r + r_new; @@ -183,82 +191,46 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, /** * Store large tree as FFmpeg's vlc codes + * + * Can read FFMAX(1 + SMKTREE_DECODE_MAX_RECURSION, 2 + 3 * 16) bits + * before the first check; can overread by 6 * SMKTREE_BITS + 1 on success. */ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size) { - int res; - HuffContext huff; - HuffContext tmp1, tmp2; VLC vlc[2] = { { 0 } }; int escapes[3]; DBCtx ctx; - int err = 0; + int err; if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow av_log(smk->avctx, AV_LOG_ERROR, "size too large\n"); return AVERROR_INVALIDDATA; } - tmp1.length = 256; - tmp1.maxlength = 0; - tmp1.current = 0; - tmp1.bits = av_mallocz(256 * 4); - tmp1.lengths = av_mallocz(256 * sizeof(int)); - tmp1.values = av_mallocz(256 * sizeof(int)); - - tmp2.length = 256; - tmp2.maxlength = 0; - tmp2.current = 0; - 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) { - err = res; - goto error; + for (int i = 0; i < 2; i++) { + HuffContext h; + h.current = 0; + if (!get_bits1(gb)) { + ctx.vals[i] = 0; + av_log(smk->avctx, AV_LOG_ERROR, "Skipping %s bytes tree\n", + i ? "high" : "low"); + continue; } + err = smacker_decode_tree(gb, &h, 0); + if (err < 0) + goto error; skip_bits1(gb); - if(tmp1.current > 1) { - res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length, - tmp1.lengths, sizeof(int), sizeof(int), - tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); - if(res < 0) { + if (h.current > 1) { + err = ff_init_vlc_from_lengths(&vlc[i], SMKTREE_BITS, h.current, + &h.entries[0].length, sizeof(*h.entries), + &h.entries[0].value, sizeof(*h.entries), 1, + 0, INIT_VLC_OUTPUT_LE, smk->avctx); + if (err < 0) { av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - err = res; goto error; } - } - } - if (!vlc[0].table) { - av_log(smk->avctx, AV_LOG_ERROR, "Skipping low bytes tree\n"); - } - if(get_bits1(gb)){ - res = smacker_decode_tree(gb, &tmp2, 0, 0); - if (res < 0) { - err = res; - goto error; - } - skip_bits1(gb); - if(tmp2.current > 1) { - res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length, - tmp2.lengths, sizeof(int), sizeof(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"); - err = res; - goto error; - } - } - } - if (!vlc[1].table) { - av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n"); + } else + ctx.vals[i] = h.entries[0].value; } escapes[0] = get_bits(gb, 16); @@ -272,46 +244,29 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int ctx.escapes[2] = escapes[2]; ctx.v1 = &vlc[0]; ctx.v2 = &vlc[1]; - ctx.recode1 = tmp1.values; - ctx.recode2 = tmp2.values; ctx.last = last; - - huff.length = ((size + 3) >> 2) + 4; - huff.maxlength = 0; - huff.current = 0; - huff.values = av_mallocz_array(huff.length, sizeof(int)); - if (!huff.values) { + ctx.length = (size + 3) >> 2; + ctx.current = 0; + ctx.values = av_malloc_array(ctx.length + 3, sizeof(ctx.values[0])); + if (!ctx.values) { err = AVERROR(ENOMEM); goto error; } + *recodes = ctx.values; - res = smacker_decode_bigtree(gb, &huff, &ctx, 0); - if (res < 0) - err = res; + err = smacker_decode_bigtree(gb, &ctx, 0); + if (err < 0) + goto error; skip_bits1(gb); - 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 (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; + if (ctx.last[0] == -1) ctx.last[0] = ctx.current++; + if (ctx.last[1] == -1) ctx.last[1] = ctx.current++; + if (ctx.last[2] == -1) ctx.last[2] = ctx.current++; + err = 0; error: - if(vlc[0].table) - ff_free_vlc(&vlc[0]); - if(vlc[1].table) - ff_free_vlc(&vlc[1]); - av_free(tmp1.bits); - av_free(tmp1.lengths); - av_free(tmp1.values); - av_free(tmp2.bits); - av_free(tmp2.lengths); - av_free(tmp2.values); + for (int i = 0; i < 2; i++) { + ff_free_vlc(&vlc[i]); + } return err; } @@ -382,7 +337,7 @@ static int decode_header_trees(SmackVContext *smk) { if (ret < 0) return ret; } - if (skip == 4) + if (skip == 4 || get_bits_left(&gb) < 0) return AVERROR_INVALIDDATA; return 0; @@ -392,7 +347,8 @@ static av_always_inline void last_reset(int *recode, int *last) { recode[last[0]] = recode[last[1]] = recode[last[2]] = 0; } -/* get code and update history */ +/* Get code and update history. + * Checks before reading, does not overread. */ static av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *last) { register int *table = recode; int v; @@ -600,15 +556,13 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); /* decode huffman trees from extradata */ - if(avctx->extradata_size < 16){ + if (avctx->extradata_size <= 16){ av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n"); - decode_end(avctx); return AVERROR(EINVAL); } ret = decode_header_trees(c); if (ret < 0) { - decode_end(avctx); return ret; } @@ -638,15 +592,14 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; GetBitContext gb; - HuffContext h[4] = { { 0 } }; VLC vlc[4] = { { 0 } }; int16_t *samples; uint8_t *samples8; - int val; + uint8_t values[4]; int i, res, ret; int unp_size; int bits, stereo; - int pred[2] = {0, 0}; + unsigned pred[2], val; if (buf_size <= 4) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); @@ -693,91 +646,48 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, // Initialize for(i = 0; i < (1 << (bits + stereo)); i++) { - h[i].length = 256; - h[i].maxlength = 0; - h[i].current = 0; - 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; - } + HuffContext h; + h.current = 0; skip_bits1(&gb); - if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { - ret = AVERROR_INVALIDDATA; + if ((ret = smacker_decode_tree(&gb, &h, 0)) < 0) goto error; - } skip_bits1(&gb); - if(h[i].current > 1) { - res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, - h[i].lengths, sizeof(int), sizeof(int), - h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); - if(res < 0) { + if (h.current > 1) { + ret = ff_init_vlc_from_lengths(&vlc[i], SMKTREE_BITS, h.current, + &h.entries[0].length, sizeof(*h.entries), + &h.entries[0].value, sizeof(*h.entries), 1, + 0, INIT_VLC_OUTPUT_LE, avctx); + if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - ret = AVERROR_INVALIDDATA; goto error; } - } + } else + values[i] = h.entries[0].value; } /* 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); + pred[i] = av_bswap16(get_bits(&gb, 16)); for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { + unsigned idx = 2 * (i & stereo); if (get_bits_left(&gb) < 0) { ret = AVERROR_INVALIDDATA; goto error; } - if(i & stereo) { - if(vlc[2].table) - res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); - else - res = 0; - if (res < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); - ret = AVERROR_INVALIDDATA; - goto error; - } - val = h[2].values[res]; - if(vlc[3].table) - res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); - else - res = 0; - if (res < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); - ret = AVERROR_INVALIDDATA; - goto error; - } - val |= h[3].values[res] << 8; - pred[1] += (unsigned)sign_extend(val, 16); - *samples++ = pred[1]; - } else { - if(vlc[0].table) - res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); - else - res = 0; - if (res < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); - ret = AVERROR_INVALIDDATA; - goto error; - } - val = h[0].values[res]; - if(vlc[1].table) - res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); - else - res = 0; - if (res < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); - ret = AVERROR_INVALIDDATA; - goto error; - } - val |= h[1].values[res] << 8; - pred[0] += (unsigned)sign_extend(val, 16); - *samples++ = pred[0]; - } + if (vlc[idx].table) + res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3); + else + res = values[idx]; + val = res; + if (vlc[++idx].table) + res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3); + else + res = values[idx]; + val |= res << 8; + pred[idx / 2] += val; + *samples++ = pred[idx / 2]; } } else { //8-bit data for(i = stereo; i >= 0; i--) @@ -785,35 +695,17 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; for(; i < unp_size; i++) { + unsigned idx = i & stereo; if (get_bits_left(&gb) < 0) { ret = AVERROR_INVALIDDATA; goto error; } - if(i & stereo){ - if(vlc[1].table) - res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); - else - res = 0; - if (res < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); - ret = AVERROR_INVALIDDATA; - goto error; - } - pred[1] += sign_extend(h[1].values[res], 8); - *samples8++ = pred[1]; - } else { - if(vlc[0].table) - res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); - else - res = 0; - if (res < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); - ret = AVERROR_INVALIDDATA; - goto error; - } - pred[0] += sign_extend(h[0].values[res], 8); - *samples8++ = pred[0]; - } + if (vlc[idx].table) + val = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3); + else + val = values[idx]; + pred[idx] += val; + *samples8++ = pred[idx]; } } @@ -822,11 +714,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, error: for(i = 0; i < 4; i++) { - if(vlc[i].table) - ff_free_vlc(&vlc[i]); - av_free(h[i].bits); - av_free(h[i].lengths); - av_free(h[i].values); + ff_free_vlc(&vlc[i]); } return ret; @@ -842,6 +730,7 @@ AVCodec ff_smacker_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; AVCodec ff_smackaud_decoder = { @@ -852,4 +741,5 @@ AVCodec ff_smackaud_decoder = { .init = smka_decode_init, .decode = smka_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/smc.c b/libavcodec/smc.c index 2beb1ce29..33581bbf8 100644 --- a/libavcodec/smc.c +++ b/libavcodec/smc.c @@ -435,7 +435,7 @@ static int smc_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; SmcContext *s = avctx->priv_data; - int pal_size; + buffer_size_t pal_size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &pal_size); int ret; int total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4); @@ -484,4 +484,5 @@ AVCodec ff_smc_decoder = { .close = smc_decode_end, .decode = smc_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/snow.c b/libavcodec/snow.c index a3e6afc86..bb65a6f43 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -21,6 +21,7 @@ #include "libavutil/intmath.h" #include "libavutil/log.h" #include "libavutil/opt.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "me_cmp.h" #include "snow_dwt.h" @@ -427,10 +428,19 @@ mca( 8, 0,8) mca( 0, 8,8) mca( 8, 8,8) +static av_cold void snow_static_init(void) +{ + for (int i = 0; i < MAX_REF_FRAMES; i++) + for (int j = 0; j < MAX_REF_FRAMES; j++) + ff_scale_mv_ref[i][j] = 256 * (i + 1) / (j + 1); + init_qexp(); +} + av_cold int ff_snow_common_init(AVCodecContext *avctx){ + static AVOnce init_static_once = AV_ONCE_INIT; SnowContext *s = avctx->priv_data; int width, height; - int i, j; + int i; s->avctx= avctx; s->max_ref_frames=1; //just make sure it's not an invalid value in case of no initial keyframe @@ -480,35 +490,32 @@ av_cold int ff_snow_common_init(AVCodecContext *avctx){ mcfh(0, 8) mcfh(8, 8) - init_qexp(); - // dec += FFMAX(s->chroma_h_shift, s->chroma_v_shift); width= s->avctx->width; height= s->avctx->height; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->spatial_idwt_buffer, width, height * sizeof(IDWTELEM), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->spatial_dwt_buffer, width, height * sizeof(DWTELEM), fail); //FIXME this does not belong here - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->temp_dwt_buffer, width, sizeof(DWTELEM), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->temp_idwt_buffer, width, sizeof(IDWTELEM), fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->run_buffer, ((width + 1) >> 1), ((height + 1) >> 1) * sizeof(*s->run_buffer), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->spatial_idwt_buffer, width * height) || + !FF_ALLOCZ_TYPED_ARRAY(s->spatial_dwt_buffer, width * height) || //FIXME this does not belong here + !FF_ALLOCZ_TYPED_ARRAY(s->temp_dwt_buffer, width) || + !FF_ALLOCZ_TYPED_ARRAY(s->temp_idwt_buffer, width) || + !FF_ALLOCZ_TYPED_ARRAY(s->run_buffer, ((width + 1) >> 1) * ((height + 1) >> 1))) + return AVERROR(ENOMEM); for(i=0; ilast_picture[i] = av_frame_alloc(); if (!s->last_picture[i]) - goto fail; + return AVERROR(ENOMEM); } s->mconly_picture = av_frame_alloc(); s->current_picture = av_frame_alloc(); if (!s->mconly_picture || !s->current_picture) - goto fail; + return AVERROR(ENOMEM); + + ff_thread_once(&init_static_once, snow_static_init); return 0; -fail: - return AVERROR(ENOMEM); } int ff_snow_common_init_after_header(AVCodecContext *avctx) { @@ -520,9 +527,10 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) { if ((ret = ff_get_buffer(s->avctx, s->mconly_picture, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - FF_ALLOCZ_ARRAY_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 (!FF_ALLOCZ_TYPED_ARRAY(s->scratchbuf, FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256) * 7 * MB_SIZE) || + !FF_ALLOCZ_TYPED_ARRAY(s->emu_edge_buffer, emu_buf_size)) + return AVERROR(ENOMEM); } if(s->mconly_picture->format != avctx->pix_fmt) { @@ -571,7 +579,7 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) { av_freep(&b->x_coeff); b->x_coeff=av_mallocz_array(((b->width+1) * b->height+1), sizeof(x_and_coeff)); if (!b->x_coeff) - goto fail; + return AVERROR(ENOMEM); } w= (w+1)>>1; h= (h+1)>>1; @@ -579,8 +587,6 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) { } return 0; -fail: - return AVERROR(ENOMEM); } #define USE_HALFPEL_PLANE 0 diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c index 5e69f3902..68afe0df2 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -422,17 +422,6 @@ static int decode_header(SnowContext *s){ return 0; } -static av_cold int decode_init(AVCodecContext *avctx) -{ - int ret; - - if ((ret = ff_snow_common_init(avctx)) < 0) { - return ret; - } - - return 0; -} - static int decode_blocks(SnowContext *s){ int x, y; int w= s->b_width; @@ -665,7 +654,7 @@ AVCodec ff_snow_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SNOW, .priv_data_size = sizeof(SnowContext), - .init = decode_init, + .init = ff_snow_common_init, .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/, diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index b1cf1426e..16d2b7c30 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -1948,6 +1948,11 @@ static const AVOption options[] = { { "pred", "Spatial decomposition type", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, DWT_97, DWT_53, VE, "pred" }, { "dwt97", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, { "dwt53", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" }, + { "rc_eq", "Set rate control equation. When computing the expression, besides the standard functions " + "defined in the section 'Expression Evaluation', the following functions are available: " + "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv " + "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.", + OFFSET(m.rc_eq), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE }, { NULL }, }; diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c index c635005be..c049f6aed 100644 --- a/libavcodec/sonic.c +++ b/libavcodec/sonic.c @@ -458,8 +458,8 @@ static void predictor_init_state(int *k, int *state, int order) for (j = 0, p = i+1; p < order; j++,p++) { - int tmp = x + shift_down(k[j] * state[p], LATTICE_SHIFT); - state[p] += shift_down(k[j]*x, LATTICE_SHIFT); + int tmp = x + shift_down(k[j] * (unsigned)state[p], LATTICE_SHIFT); + state[p] += shift_down(k[j]* (unsigned)x, LATTICE_SHIFT); x = tmp; } } @@ -467,7 +467,7 @@ static void predictor_init_state(int *k, int *state, int order) static int predictor_calc_error(int *k, int *state, int order, int error) { - int i, x = error - shift_down(k[order-1] * state[order-1], LATTICE_SHIFT); + int i, x = error - shift_down(k[order-1] * (unsigned)state[order-1], LATTICE_SHIFT); #if 1 int *k_ptr = &(k[order-2]), @@ -475,13 +475,13 @@ static int predictor_calc_error(int *k, int *state, int order, int error) for (i = order-2; i >= 0; i--, k_ptr--, state_ptr--) { int k_value = *k_ptr, state_value = *state_ptr; - x -= shift_down(k_value * (unsigned)state_value, LATTICE_SHIFT); + x -= (unsigned)shift_down(k_value * (unsigned)state_value, LATTICE_SHIFT); state_ptr[1] = state_value + shift_down(k_value * (unsigned)x, LATTICE_SHIFT); } #else for (i = order-2; i >= 0; i--) { - x -= shift_down(k[i] * state[i], LATTICE_SHIFT); + x -= (unsigned)shift_down(k[i] * state[i], LATTICE_SHIFT); state[i+1] = state[i] + shift_down(k[i] * x, LATTICE_SHIFT); } #endif @@ -500,16 +500,13 @@ static int predictor_calc_error(int *k, int *state, int order, int error) // copes better with quantization, and calculates the // actual whitened result as it goes. -static int modified_levinson_durbin(int *window, int window_entries, +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_calloc(window_entries, sizeof(*state)); + int *state = window + window_entries; - if (!state) - return AVERROR(ENOMEM); - - memcpy(state, window, 4* window_entries); + memcpy(state, window, window_entries * sizeof(*state)); for (i = 0; i < out_entries; i++) { @@ -571,9 +568,6 @@ static int modified_levinson_durbin(int *window, int window_entries, } #endif } - - av_free(state); - return 0; } static inline int code_samplerate(int samplerate) @@ -596,6 +590,7 @@ static inline int code_samplerate(int samplerate) static av_cold int sonic_encode_init(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; + int *coded_samples; PutBitContext pb; int i; @@ -655,17 +650,16 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx) if (!s->predictor_k) return AVERROR(ENOMEM); - for (i = 0; i < s->channels; i++) - { - s->coded_samples[i] = av_calloc(s->block_align, sizeof(**s->coded_samples)); - if (!s->coded_samples[i]) - return AVERROR(ENOMEM); - } + coded_samples = av_calloc(s->block_align, s->channels * sizeof(**s->coded_samples)); + if (!coded_samples) + return AVERROR(ENOMEM); + for (i = 0; i < s->channels; i++, coded_samples += s->block_align) + s->coded_samples[i] = coded_samples; 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_calloc(s->window_size, sizeof(*s->window)); + s->window = av_calloc(s->window_size, 2 * sizeof(*s->window)); if (!s->window || !s->int_samples) return AVERROR(ENOMEM); @@ -706,11 +700,8 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx) static av_cold int sonic_encode_close(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; - int i; - - for (i = 0; i < s->channels; i++) - av_freep(&s->coded_samples[i]); + av_freep(&s->coded_samples[0]); av_freep(&s->predictor_k); av_freep(&s->tail); av_freep(&s->tap_quant); @@ -764,7 +755,7 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, break; } - memset(s->window, 0, 4* s->window_size); + memset(s->window, 0, s->window_size * sizeof(*s->window)); for (i = 0; i < s->tail_size; i++) s->window[x++] = s->tail[i]; @@ -779,10 +770,8 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, s->tail[i] = s->int_samples[s->frame_size - s->tail_size + i]; // generate taps - ret = modified_levinson_durbin(s->window, s->window_size, + modified_levinson_durbin(s->window, s->window_size, s->predictor_k, s->num_taps, s->channels, s->tap_quant); - if (ret < 0) - return ret; if ((ret = intlist_write(&c, state, s->predictor_k, s->num_taps, 0)) < 0) return ret; @@ -859,6 +848,7 @@ static const int samplerate_table[] = static av_cold int sonic_decode_init(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; + int *tmp; GetBitContext gb; int i; int ret; @@ -951,19 +941,18 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) s->predictor_k = av_calloc(s->num_taps, sizeof(*s->predictor_k)); - for (i = 0; i < s->channels; i++) - { - s->predictor_state[i] = av_calloc(s->num_taps, sizeof(**s->predictor_state)); - if (!s->predictor_state[i]) - return AVERROR(ENOMEM); - } + tmp = av_calloc(s->num_taps, s->channels * sizeof(**s->predictor_state)); + if (!tmp) + return AVERROR(ENOMEM); + for (i = 0; i < s->channels; i++, tmp += s->num_taps) + s->predictor_state[i] = tmp; + + tmp = av_calloc(s->block_align, s->channels * sizeof(**s->coded_samples)); + if (!tmp) + return AVERROR(ENOMEM); + for (i = 0; i < s->channels; i++, tmp += s->block_align) + s->coded_samples[i] = tmp; - for (i = 0; i < s->channels; i++) - { - s->coded_samples[i] = av_calloc(s->block_align, sizeof(**s->coded_samples)); - if (!s->coded_samples[i]) - return AVERROR(ENOMEM); - } s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples)); if (!s->int_samples) return AVERROR(ENOMEM); @@ -975,15 +964,12 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) static av_cold int sonic_decode_close(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; - int i; av_freep(&s->int_samples); av_freep(&s->tap_quant); av_freep(&s->predictor_k); - for (i = 0; i < MAX_CHANNELS; i++) { - av_freep(&s->predictor_state[i]); - av_freep(&s->coded_samples[i]); - } + av_freep(&s->predictor_state[0]); + av_freep(&s->coded_samples[0]); return 0; } @@ -1095,7 +1081,8 @@ AVCodec ff_sonic_decoder = { .init = sonic_decode_init, .close = sonic_decode_close, .decode = sonic_decode_frame, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif /* CONFIG_SONIC_DECODER */ @@ -1110,6 +1097,7 @@ AVCodec ff_sonic_encoder = { .encode2 = sonic_encode_frame, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .capabilities = AV_CODEC_CAP_EXPERIMENTAL, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .close = sonic_encode_close, }; #endif @@ -1125,6 +1113,7 @@ AVCodec ff_sonic_ls_encoder = { .encode2 = sonic_encode_frame, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .capabilities = AV_CODEC_CAP_EXPERIMENTAL, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .close = sonic_encode_close, }; #endif diff --git a/libavcodec/sp5x.h b/libavcodec/sp5x.h index 21c45715d..d84d85176 100644 --- a/libavcodec/sp5x.h +++ b/libavcodec/sp5x.h @@ -132,58 +132,8 @@ static const uint8_t sp5x_data_dht[] = { }; -static const uint8_t sp5x_quant_table[20][64]= +static const uint8_t sp5x_qscale_five_quant_table[][64]= { - /* index 0, Q50 */ - { 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, - 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51, - 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80,109, 81, 87, - 95, 98,103,104,103, 62, 77,113,121,112,100,120, 92,101,103, 99 }, - { 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }, - - /* index 1, Q70 */ - { 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24, - 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31, - 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52, - 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59 }, - { 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59 }, - - /* index 2, Q80 */ - { 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16, - 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20, - 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35, - 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40 }, - { 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 }, - - /* index 3, Q85 */ - { 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12, - 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15, - 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26, - 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30 }, - { 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 }, - - /* index 4, Q90 */ - { 3, 2, 2, 3, 2, 2, 3, 3, 3, 3, 4, 3, 3, 4, 5, 8, - 5, 5, 4, 4, 5, 10, 7, 7, 6, 8, 12, 10, 12, 12, 11, 10, - 11, 11, 13, 14, 18, 16, 13, 14, 17, 14, 11, 11, 16, 22, 16, 17, - 19, 20, 21, 21, 21, 12, 15, 23, 24, 22, 20, 24, 18, 20, 21, 20 }, - { 3, 4, 4, 5, 4, 5, 9, 5, 5, 9, 20, 13, 11, 13, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 }, - /* index 5, Q60 */ { 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32, 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41, @@ -193,46 +143,6 @@ static const uint8_t sp5x_quant_table[20][64]= 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79 }, - - /* index 6, Q25 */ - { 32, 22, 24, 28, 24, 20, 32, 28, 26, 28, 36, 34, 32, 38, 48, 80, - 52, 48, 44, 44, 48, 98, 70, 74, 58, 80,116,102,122,120,114,102, - 112,110,128,144,184,156,128,136,174,138,110,112,160,218,162,174, - 190,196,206,208,206,124,154,226,242,224,200,240,184,202,206,198 }, - { 34, 36, 36, 48, 42, 48, 94, 52, 52, 94,198,132,112,132,198,198, - 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, - 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, - 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198 }, - - /* index 7, Q95 */ - { 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 4, - 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, - 6, 6, 6, 7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, - 10, 10, 10, 10, 10, 6, 8, 11, 12, 11, 10, 12, 9, 10, 10, 10 }, - { 2, 2, 2, 2, 2, 2, 5, 3, 3, 5, 10, 7, 6, 7, 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, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 }, - - /* index 8, Q93 */ - { 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 3, 2, 2, 3, 3, 6, - 4, 3, 3, 3, 3, 7, 5, 5, 4, 6, 8, 7, 9, 8, 8, 7, - 8, 8, 9, 10, 13, 11, 9, 10, 12, 10, 8, 8, 11, 15, 11, 12, - 13, 14, 14, 15, 14, 9, 11, 16, 17, 16, 14, 17, 13, 14, 14, 14 }, - { 2, 3, 3, 3, 3, 3, 7, 4, 4, 7, 14, 9, 8, 9, 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 }, - - /* index 9, Q40 */ - { 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50, - 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64, - 70, 69, 80, 90,115, 98, 80, 85,109, 86, 69, 70,100,136,101,109, - 119,123,129,130,129, 78, 96,141,151,140,125,150,115,126,129,124 }, - { 21, 23, 23, 30, 26, 30, 59, 33, 33, 59,124, 83, 70, 83,124,124, - 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, - 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, - 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124 } }; #endif /* AVCODEC_SP5X_H */ diff --git a/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c index 815f9ad50..0b2b2d841 100644 --- a/libavcodec/sp5xdec.c +++ b/libavcodec/sp5xdec.c @@ -30,32 +30,29 @@ #include "mjpegdec.h" #include "sp5x.h" - -static int sp5x_decode_frame(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt) +int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVPacket avpkt_recoded; - const int qscale = 5; + AVBufferRef *buf_recoded; uint8_t *recoded; int i = 0, j = 0; if (!avctx->width || !avctx->height) return -1; - recoded = av_mallocz(buf_size + 1024); - if (!recoded) + buf_recoded = av_buffer_allocz(buf_size + 1024); + if (!buf_recoded) return -1; + recoded = buf_recoded->data; /* SOI */ recoded[j++] = 0xFF; recoded[j++] = 0xD8; memcpy(recoded+j, &sp5x_data_dqt[0], sizeof(sp5x_data_dqt)); - memcpy(recoded+j+5, &sp5x_quant_table[qscale * 2], 64); - memcpy(recoded+j+70, &sp5x_quant_table[(qscale * 2) + 1], 64); + memcpy(recoded + j + 5, &sp5x_qscale_five_quant_table[0], 64); + memcpy(recoded + j + 70, &sp5x_qscale_five_quant_table[1], 64); j += sizeof(sp5x_data_dqt); memcpy(recoded+j, &sp5x_data_dht[0], sizeof(sp5x_data_dht)); @@ -84,14 +81,12 @@ static int sp5x_decode_frame(AVCodecContext *avctx, recoded[j++] = 0xFF; recoded[j++] = 0xD9; - av_init_packet(&avpkt_recoded); - avpkt_recoded.data = recoded; - avpkt_recoded.size = j; - i = ff_mjpeg_decode_frame(avctx, data, got_frame, &avpkt_recoded); + av_buffer_unref(&avpkt->buf); + avpkt->buf = buf_recoded; + avpkt->data = recoded; + avpkt->size = j; - av_free(recoded); - - return i < 0 ? i : avpkt->size; + return 0; } #if CONFIG_SP5X_DECODER @@ -103,10 +98,11 @@ AVCodec ff_sp5x_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - .decode = sp5x_decode_frame, + .receive_frame = ff_mjpeg_receive_frame, .capabilities = AV_CODEC_CAP_DR1, .max_lowres = 3, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_SETS_PKT_DTS, }; #endif #if CONFIG_AMV_DECODER @@ -118,9 +114,10 @@ AVCodec ff_amv_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - .decode = sp5x_decode_frame, + .receive_frame = ff_mjpeg_receive_frame, .max_lowres = 3, .capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_SETS_PKT_DTS, }; #endif diff --git a/libavcodec/speedhq.c b/libavcodec/speedhq.c index 890b8253c..711bcd66d 100644 --- a/libavcodec/speedhq.c +++ b/libavcodec/speedhq.c @@ -26,7 +26,9 @@ #define BITSTREAM_READER_LE +#include "config.h" #include "libavutil/attributes.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "get_bits.h" @@ -132,14 +134,15 @@ static const uint8_t speedhq_run[121] = { 31, }; -static RLTable ff_rl_speedhq = { +RLTable ff_rl_speedhq = { 121, 121, - (const uint16_t (*)[])speedhq_vlc, + speedhq_vlc, speedhq_run, speedhq_level, }; +#if CONFIG_SPEEDHQ_DECODER /* NOTE: The first element is always 16, unscaled. */ static const uint8_t unscaled_quant_matrix[64] = { 16, 16, 19, 22, 26, 27, 29, 34, @@ -152,25 +155,21 @@ static const uint8_t unscaled_quant_matrix[64] = { 27, 29, 35, 38, 46, 56, 69, 83 }; -static uint8_t ff_speedhq_static_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; +static uint8_t speedhq_static_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; -static VLC ff_dc_lum_vlc_le; -static VLC ff_dc_chroma_vlc_le; -static VLC ff_dc_alpha_run_vlc_le; -static VLC ff_dc_alpha_level_vlc_le; +static VLC dc_lum_vlc_le; +static VLC dc_chroma_vlc_le; +static VLC dc_alpha_run_vlc_le; +static VLC dc_alpha_level_vlc_le; static inline int decode_dc_le(GetBitContext *gb, int component) { int code, diff; if (component == 0 || component == 3) { - code = get_vlc2(gb, ff_dc_lum_vlc_le.table, DC_VLC_BITS, 2); + code = get_vlc2(gb, dc_lum_vlc_le.table, DC_VLC_BITS, 2); } else { - code = get_vlc2(gb, ff_dc_chroma_vlc_le.table, DC_VLC_BITS, 2); - } - if (code < 0) { - av_log(NULL, AV_LOG_ERROR, "invalid dc code at\n"); - return 0xffff; + code = get_vlc2(gb, dc_chroma_vlc_le.table, DC_VLC_BITS, 2); } if (!code) { diff = 0; @@ -194,7 +193,7 @@ static inline int decode_alpha_block(const SHQContext *s, GetBitContext *gb, uin int run, level; UPDATE_CACHE_LE(re, gb); - GET_VLC(run, re, gb, ff_dc_alpha_run_vlc_le.table, ALPHA_VLC_BITS, 2); + GET_VLC(run, re, gb, dc_alpha_run_vlc_le.table, ALPHA_VLC_BITS, 2); if (run < 0) break; i += run; @@ -202,7 +201,7 @@ static inline int decode_alpha_block(const SHQContext *s, GetBitContext *gb, uin return AVERROR_INVALIDDATA; UPDATE_CACHE_LE(re, gb); - GET_VLC(level, re, gb, ff_dc_alpha_level_vlc_le.table, ALPHA_VLC_BITS, 2); + GET_VLC(level, re, gb, dc_alpha_level_vlc_le.table, ALPHA_VLC_BITS, 2); block[i++] = level; } @@ -277,6 +276,78 @@ static inline int decode_dct_block(const SHQContext *s, GetBitContext *gb, int l return 0; } +static int decode_speedhq_border(const SHQContext *s, GetBitContext *gb, AVFrame *frame, int field_number, int line_stride) +{ + int linesize_y = frame->linesize[0] * line_stride; + int linesize_cb = frame->linesize[1] * line_stride; + int linesize_cr = frame->linesize[2] * line_stride; + int linesize_a; + int ret; + + if (s->alpha_type != SHQ_NO_ALPHA) + linesize_a = frame->linesize[3] * line_stride; + + for (int y = 0; y < frame->height; y += 16 * line_stride) { + int last_dc[4] = { 1024, 1024, 1024, 1024 }; + uint8_t *dest_y, *dest_cb, *dest_cr, *dest_a; + uint8_t last_alpha[16]; + int x = frame->width - 8; + + dest_y = frame->data[0] + frame->linesize[0] * (y + field_number) + x; + if (s->subsampling == SHQ_SUBSAMPLING_420) { + dest_cb = frame->data[1] + frame->linesize[1] * (y/2 + field_number) + x / 2; + dest_cr = frame->data[2] + frame->linesize[2] * (y/2 + field_number) + x / 2; + } else if (s->subsampling == SHQ_SUBSAMPLING_422) { + dest_cb = frame->data[1] + frame->linesize[1] * (y + field_number) + x / 2; + dest_cr = frame->data[2] + frame->linesize[2] * (y + field_number) + x / 2; + } + if (s->alpha_type != SHQ_NO_ALPHA) { + memset(last_alpha, 255, sizeof(last_alpha)); + dest_a = frame->data[3] + frame->linesize[3] * (y + field_number) + x; + } + + if ((ret = decode_dct_block(s, gb, last_dc, 0, dest_y, linesize_y)) < 0) + return ret; + if ((ret = decode_dct_block(s, gb, last_dc, 0, dest_y + 8, linesize_y)) < 0) + return ret; + if ((ret = decode_dct_block(s, gb, last_dc, 0, dest_y + 8 * linesize_y, linesize_y)) < 0) + return ret; + if ((ret = decode_dct_block(s, gb, last_dc, 0, dest_y + 8 * linesize_y + 8, linesize_y)) < 0) + return ret; + if ((ret = decode_dct_block(s, gb, last_dc, 1, dest_cb, linesize_cb)) < 0) + return ret; + if ((ret = decode_dct_block(s, gb, last_dc, 2, dest_cr, linesize_cr)) < 0) + return ret; + + if (s->subsampling != SHQ_SUBSAMPLING_420) { + if ((ret = decode_dct_block(s, gb, last_dc, 1, dest_cb + 8 * linesize_cb, linesize_cb)) < 0) + return ret; + if ((ret = decode_dct_block(s, gb, last_dc, 2, dest_cr + 8 * linesize_cr, linesize_cr)) < 0) + return ret; + } + + if (s->alpha_type == SHQ_RLE_ALPHA) { + /* Alpha coded using 16x8 RLE blocks. */ + if ((ret = decode_alpha_block(s, gb, last_alpha, dest_a, linesize_a)) < 0) + return ret; + if ((ret = decode_alpha_block(s, gb, last_alpha, dest_a + 8 * linesize_a, linesize_a)) < 0) + return ret; + } else if (s->alpha_type == SHQ_DCT_ALPHA) { + /* Alpha encoded exactly like luma. */ + if ((ret = decode_dct_block(s, gb, last_dc, 3, dest_a, linesize_a)) < 0) + return ret; + if ((ret = decode_dct_block(s, gb, last_dc, 3, dest_a + 8, linesize_a)) < 0) + return ret; + if ((ret = decode_dct_block(s, gb, last_dc, 3, dest_a + 8 * linesize_a, linesize_a)) < 0) + return ret; + if ((ret = decode_dct_block(s, gb, last_dc, 3, dest_a + 8 * linesize_a + 8, linesize_a)) < 0) + return ret; + } + } + + return 0; +} + static int decode_speedhq_field(const SHQContext *s, const uint8_t *buf, int buf_size, AVFrame *frame, int field_number, int start, int end, int line_stride) { int ret, slice_number, slice_offsets[5]; @@ -284,6 +355,7 @@ static int decode_speedhq_field(const SHQContext *s, const uint8_t *buf, int buf int linesize_cb = frame->linesize[1] * line_stride; int linesize_cr = frame->linesize[2] * line_stride; int linesize_a; + GetBitContext gb; if (s->alpha_type != SHQ_NO_ALPHA) linesize_a = frame->linesize[3] * line_stride; @@ -305,7 +377,6 @@ static int decode_speedhq_field(const SHQContext *s, const uint8_t *buf, int buf } for (slice_number = 0; slice_number < 4; slice_number++) { - GetBitContext gb; uint32_t slice_begin, slice_end; int x, y; @@ -334,7 +405,7 @@ static int decode_speedhq_field(const SHQContext *s, const uint8_t *buf, int buf dest_a = frame->data[3] + frame->linesize[3] * (y + field_number); } - for (x = 0; x < frame->width; x += 16) { + for (x = 0; x < frame->width - 8 * (s->subsampling != SHQ_SUBSAMPLING_444); x += 16) { /* Decode the four luma blocks. */ if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y, linesize_y)) < 0) return ret; @@ -403,6 +474,9 @@ static int decode_speedhq_field(const SHQContext *s, const uint8_t *buf, int buf } } + if (s->subsampling != SHQ_SUBSAMPLING_444 && (frame->width & 15)) + return decode_speedhq_border(s, &gb, frame, field_number, line_stride); + return 0; } @@ -424,7 +498,7 @@ static int speedhq_decode_frame(AVCodecContext *avctx, uint32_t second_field_offset; int ret; - if (buf_size < 4) + if (buf_size < 4 || avctx->width < 8) return AVERROR_INVALIDDATA; quality = buf[0]; @@ -447,7 +521,7 @@ static int speedhq_decode_frame(AVCodecContext *avctx, } frame->key_frame = 1; - if (second_field_offset == 4) { + if (second_field_offset == 4 || second_field_offset == (buf_size-4)) { /* * Overlapping first and second fields is used to signal * encoding only a single field. In this case, "height" @@ -515,7 +589,7 @@ static av_cold void compute_alpha_vlcs(void) av_assert0(entry == FF_ARRAY_ELEMS(run_code)); - INIT_LE_VLC_SPARSE_STATIC(&ff_dc_alpha_run_vlc_le, ALPHA_VLC_BITS, + INIT_LE_VLC_SPARSE_STATIC(&dc_alpha_run_vlc_le, ALPHA_VLC_BITS, FF_ARRAY_ELEMS(run_code), run_bits, 1, 1, run_code, 2, 2, @@ -555,49 +629,26 @@ static av_cold void compute_alpha_vlcs(void) av_assert0(entry == FF_ARRAY_ELEMS(level_code)); - INIT_LE_VLC_SPARSE_STATIC(&ff_dc_alpha_level_vlc_le, ALPHA_VLC_BITS, + INIT_LE_VLC_SPARSE_STATIC(&dc_alpha_level_vlc_le, ALPHA_VLC_BITS, FF_ARRAY_ELEMS(level_code), level_bits, 1, 1, level_code, 2, 2, level_symbols, 2, 2, 288); } -static uint32_t reverse(uint32_t num, int bits) -{ - return bitswap_32(num) >> (32 - bits); -} - -static void reverse_code(const uint16_t *code, const uint8_t *bits, - uint16_t *reversed_code, int num_entries) -{ - int i; - for (i = 0; i < num_entries; i++) { - reversed_code[i] = reverse(code[i], bits[i]); - } -} - static av_cold void speedhq_static_init(void) { - uint16_t ff_mpeg12_vlc_dc_lum_code_reversed[12]; - uint16_t ff_mpeg12_vlc_dc_chroma_code_reversed[12]; + /* Exactly the same as MPEG-2, except for a little-endian reader. */ + INIT_CUSTOM_VLC_STATIC(&dc_lum_vlc_le, DC_VLC_BITS, 12, + ff_mpeg12_vlc_dc_lum_bits, 1, 1, + ff_mpeg12_vlc_dc_lum_code, 2, 2, + INIT_VLC_OUTPUT_LE, 512); + INIT_CUSTOM_VLC_STATIC(&dc_chroma_vlc_le, DC_VLC_BITS, 12, + ff_mpeg12_vlc_dc_chroma_bits, 1, 1, + ff_mpeg12_vlc_dc_chroma_code, 2, 2, + INIT_VLC_OUTPUT_LE, 514); - /* Exactly the same as MPEG-2, except little-endian. */ - reverse_code(ff_mpeg12_vlc_dc_lum_code, - ff_mpeg12_vlc_dc_lum_bits, - ff_mpeg12_vlc_dc_lum_code_reversed, - 12); - INIT_LE_VLC_STATIC(&ff_dc_lum_vlc_le, DC_VLC_BITS, 12, - ff_mpeg12_vlc_dc_lum_bits, 1, 1, - ff_mpeg12_vlc_dc_lum_code_reversed, 2, 2, 512); - reverse_code(ff_mpeg12_vlc_dc_chroma_code, - ff_mpeg12_vlc_dc_chroma_bits, - ff_mpeg12_vlc_dc_chroma_code_reversed, - 12); - INIT_LE_VLC_STATIC(&ff_dc_chroma_vlc_le, DC_VLC_BITS, 12, - ff_mpeg12_vlc_dc_chroma_bits, 1, 1, - ff_mpeg12_vlc_dc_chroma_code_reversed, 2, 2, 514); - - ff_rl_init(&ff_rl_speedhq, ff_speedhq_static_rl_table_store); + ff_rl_init(&ff_rl_speedhq, speedhq_static_rl_table_store); INIT_2D_VLC_RL(ff_rl_speedhq, 674, INIT_VLC_LE); compute_alpha_vlcs(); @@ -683,3 +734,4 @@ AVCodec ff_speedhq_decoder = { .decode = speedhq_decode_frame, .capabilities = AV_CODEC_CAP_DR1, }; +#endif /* CONFIG_SPEEDHQ_DECODER */ diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c new file mode 100644 index 000000000..a5bedd530 --- /dev/null +++ b/libavcodec/speedhqenc.c @@ -0,0 +1,308 @@ +/* + * SpeedHQ encoder + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-2004 Michael Niedermayer + * Copyright (c) 2020 FFmpeg + * + * 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 + * SpeedHQ encoder. + */ + +#include "libavutil/pixdesc.h" +#include "libavutil/thread.h" + +#include "avcodec.h" +#include "mpeg12.h" +#include "mpegvideo.h" +#include "speedhqenc.h" + +extern RLTable ff_rl_speedhq; +static uint8_t speedhq_static_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; + +static uint16_t mpeg12_vlc_dc_lum_code_reversed[12]; +static uint16_t mpeg12_vlc_dc_chroma_code_reversed[12]; + +/* simple include everything table for dc, first byte is bits + * number next 3 are code */ +static uint32_t speedhq_lum_dc_uni[512]; +static uint32_t speedhq_chr_dc_uni[512]; + +static uint8_t uni_speedhq_ac_vlc_len[64 * 64 * 2]; + +static uint32_t reverse(uint32_t num, int bits) +{ + return bitswap_32(num) >> (32 - bits); +} + +static void reverse_code(const uint16_t *code, const uint8_t *bits, + uint16_t *reversed_code, int num_entries) +{ + for (int i = 0; i < num_entries; i++) + reversed_code[i] = reverse(code[i], bits[i]); +} + +static av_cold void speedhq_init_static_data(void) +{ + /* Exactly the same as MPEG-2, except little-endian. */ + reverse_code(ff_mpeg12_vlc_dc_lum_code, + ff_mpeg12_vlc_dc_lum_bits, + mpeg12_vlc_dc_lum_code_reversed, + 12); + reverse_code(ff_mpeg12_vlc_dc_chroma_code, + ff_mpeg12_vlc_dc_chroma_bits, + mpeg12_vlc_dc_chroma_code_reversed, + 12); + + ff_rl_init(&ff_rl_speedhq, speedhq_static_rl_table_store); + + /* build unified dc encoding tables */ + for (int 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 = mpeg12_vlc_dc_lum_code_reversed[index] + + (av_mod_uintp2(diff, index) << ff_mpeg12_vlc_dc_lum_bits[index]); + speedhq_lum_dc_uni[i + 255] = bits + (code << 8); + + bits = ff_mpeg12_vlc_dc_chroma_bits[index] + index; + code = mpeg12_vlc_dc_chroma_code_reversed[index] + + (av_mod_uintp2(diff, index) << ff_mpeg12_vlc_dc_chroma_bits[index]); + speedhq_chr_dc_uni[i + 255] = bits + (code << 8); + } + + ff_mpeg1_init_uni_ac_vlc(&ff_rl_speedhq, uni_speedhq_ac_vlc_len); +} + +av_cold int ff_speedhq_encode_init(MpegEncContext *s) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + + av_assert0(s->slice_context_count == 1); + + if (s->width > 65500 || s->height > 65500) { + av_log(s, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n"); + return AVERROR(EINVAL); + } + + s->min_qcoeff = -2048; + s->max_qcoeff = 2047; + + ff_thread_once(&init_static_once, speedhq_init_static_data); + + s->intra_ac_vlc_length = + s->intra_ac_vlc_last_length = + s->intra_chroma_ac_vlc_length = + s->intra_chroma_ac_vlc_last_length = uni_speedhq_ac_vlc_len; + + switch (s->avctx->pix_fmt) { + case AV_PIX_FMT_YUV420P: + s->avctx->codec_tag = MKTAG('S','H','Q','0'); + break; + case AV_PIX_FMT_YUV422P: + s->avctx->codec_tag = MKTAG('S','H','Q','2'); + break; + case AV_PIX_FMT_YUV444P: + s->avctx->codec_tag = MKTAG('S','H','Q','4'); + break; + default: + av_assert0(0); + } + + return 0; +} + +void ff_speedhq_encode_picture_header(MpegEncContext *s) +{ + put_bits_le(&s->pb, 8, 100 - s->qscale * 2); /* FIXME why doubled */ + put_bits_le(&s->pb, 24, 4); /* no second field */ + + /* length of first slice, will be filled out later */ + s->slice_start = 4; + put_bits_le(&s->pb, 24, 0); +} + +void ff_speedhq_end_slice(MpegEncContext *s) +{ + int slice_len; + + flush_put_bits_le(&s->pb); + slice_len = s->pb.buf_ptr - (s->pb.buf + s->slice_start); + AV_WL24(s->pb.buf + s->slice_start, slice_len); + + /* length of next slice, will be filled out later */ + s->slice_start = s->pb.buf_ptr - s->pb.buf; + put_bits_le(&s->pb, 24, 0); +} + +static inline void encode_dc(PutBitContext *pb, int diff, int component) +{ + unsigned int diff_u = diff + 255; + if (diff_u >= 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_le(pb, + ff_mpeg12_vlc_dc_lum_bits[index] + index, + mpeg12_vlc_dc_lum_code_reversed[index] + + (av_mod_uintp2(diff, index) << ff_mpeg12_vlc_dc_lum_bits[index])); + else + put_bits_le(pb, + ff_mpeg12_vlc_dc_chroma_bits[index] + index, + mpeg12_vlc_dc_chroma_code_reversed[index] + + (av_mod_uintp2(diff, index) << ff_mpeg12_vlc_dc_chroma_bits[index])); + } else { + if (component == 0) + put_bits_le(pb, + speedhq_lum_dc_uni[diff + 255] & 0xFF, + speedhq_lum_dc_uni[diff + 255] >> 8); + else + put_bits_le(pb, + speedhq_chr_dc_uni[diff + 255] & 0xFF, + speedhq_chr_dc_uni[diff + 255] >> 8); + } +} + +static void encode_block(MpegEncContext *s, int16_t *block, int n) +{ + int alevel, level, last_non_zero, dc, i, j, run, last_index, sign; + int code; + int component, val; + + /* DC coef */ + component = (n <= 3 ? 0 : (n&1) + 1); + dc = block[0]; /* overflow is impossible */ + val = s->last_dc[component] - dc; /* opposite of most codecs */ + encode_dc(&s->pb, val, component); + s->last_dc[component] = dc; + + /* now quantify & encode AC coefs */ + last_non_zero = 0; + last_index = s->block_last_index[n]; + + for (i = 1; i <= last_index; i++) { + j = s->intra_scantable.permutated[i]; + level = block[j]; + + /* encode using VLC */ + if (level != 0) { + run = i - last_non_zero - 1; + + alevel = level; + MASK_ABS(sign, alevel); + sign &= 1; + + if (alevel <= ff_rl_speedhq.max_level[0][run]) { + code = ff_rl_speedhq.index_run[0][run] + alevel - 1; + /* store the VLC & sign at once */ + put_bits_le(&s->pb, ff_rl_speedhq.table_vlc[code][1] + 1, + ff_rl_speedhq.table_vlc[code][0] + (sign << ff_rl_speedhq.table_vlc[code][1])); + } else { + /* escape seems to be pretty rare <5% so I do not optimize it */ + put_bits_le(&s->pb, ff_rl_speedhq.table_vlc[121][1], ff_rl_speedhq.table_vlc[121][0]); + /* escape: only clip in this case */ + put_bits_le(&s->pb, 6, run); + put_bits_le(&s->pb, 12, level + 2048); + } + last_non_zero = i; + } + } + /* end of block */ + put_bits_le(&s->pb, ff_rl_speedhq.table_vlc[122][1], ff_rl_speedhq.table_vlc[122][0]); +} + +void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]) +{ + int i; + for(i=0;i<6;i++) { + encode_block(s, block[i], i); + } + if (s->chroma_format == CHROMA_444) { + encode_block(s, block[8], 8); + encode_block(s, block[9], 9); + + encode_block(s, block[6], 6); + encode_block(s, block[7], 7); + + encode_block(s, block[10], 10); + encode_block(s, block[11], 11); + } else if (s->chroma_format == CHROMA_422) { + encode_block(s, block[6], 6); + encode_block(s, block[7], 7); + } + + s->i_tex_bits += get_bits_diff(s); +} + +static int ff_speedhq_mb_rows_in_slice(int slice_num, int mb_height) +{ + return mb_height / 4 + (slice_num < (mb_height % 4)); +} + +int ff_speedhq_mb_y_order_to_mb(int mb_y_order, int mb_height, int *first_in_slice) +{ + int slice_num = 0; + while (mb_y_order >= ff_speedhq_mb_rows_in_slice(slice_num, mb_height)) { + mb_y_order -= ff_speedhq_mb_rows_in_slice(slice_num, mb_height); + slice_num++; + } + *first_in_slice = (mb_y_order == 0); + return mb_y_order * 4 + slice_num; +} + +#if CONFIG_SPEEDHQ_ENCODER +static const AVClass speedhq_class = { + .class_name = "speedhq encoder", + .item_name = av_default_item_name, + .option = ff_mpv_generic_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_speedhq_encoder = { + .name = "speedhq", + .long_name = NULL_IF_CONFIG_SMALL("NewTek SpeedHQ"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_SPEEDHQ, + .priv_data_size = sizeof(MpegEncContext), + .init = ff_mpv_encode_init, + .encode2 = ff_mpv_encode_picture, + .close = ff_mpv_encode_end, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_NONE + }, + .priv_class = &speedhq_class, +}; +#endif diff --git a/libavcodec/speedhqenc.h b/libavcodec/speedhqenc.h new file mode 100644 index 000000000..5100bb2d3 --- /dev/null +++ b/libavcodec/speedhqenc.h @@ -0,0 +1,48 @@ +/* + * SpeedHQ encoder + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-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 + * SpeedHQ encoder. + */ + +#ifndef AVCODEC_SPEEDHQENC_H +#define AVCODEC_SPEEDHQENC_H + +#include + +#include "mjpeg.h" +#include "mjpegenc_common.h" +#include "mpegvideo.h" +#include "put_bits.h" + +int ff_speedhq_encode_init(MpegEncContext *s); +void ff_speedhq_encode_close(MpegEncContext *s); +void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]); + +void ff_speedhq_encode_picture_header(MpegEncContext *s); +void ff_speedhq_end_slice(MpegEncContext *s); + +int ff_speedhq_mb_y_order_to_mb(int mb_y_order, int mb_height, int *first_in_slice); + +#endif /* AVCODEC_SPEEDHQENC_H */ diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c index ecc080159..98f84ac67 100644 --- a/libavcodec/srtdec.c +++ b/libavcodec/srtdec.c @@ -58,7 +58,8 @@ static int srt_decode_frame(AVCodecContext *avctx, AVSubtitle *sub = data; AVBPrint buffer; int x1 = -1, y1 = -1, x2 = -1, y2 = -1; - int size, ret; + int ret; + buffer_size_t size; const uint8_t *p = av_packet_get_side_data(avpkt, AV_PKT_DATA_SUBTITLE_POSITION, &size); FFASSDecoderContext *s = avctx->priv_data; diff --git a/libavcodec/svq1_cb.h b/libavcodec/svq1_cb.h index 11f79691c..30cca19ac 100644 --- a/libavcodec/svq1_cb.h +++ b/libavcodec/svq1_cb.h @@ -34,7 +34,7 @@ #include #include -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" /* 6x16-entry codebook for inter-coded 4x2 vectors */ DECLARE_ALIGNED(4, static const int8_t, svq1_inter_codebook_4x2)[768] = { diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 25bd3d025..d6b6bec72 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -33,6 +33,7 @@ */ #include "libavutil/crc.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "get_bits.h" @@ -42,6 +43,7 @@ #include "mathops.h" #include "svq1.h" +#define SVQ1_BLOCK_TYPE_VLC_BITS 3 static VLC svq1_block_type; static VLC svq1_motion_component; static VLC svq1_intra_multistage[6]; @@ -63,6 +65,9 @@ typedef struct SVQ1Context { uint8_t *pkt_swapped; int pkt_swapped_allocated; + svq1_pmv *pmv; + int pmv_allocated; + int width; int height; int frame_code; @@ -455,7 +460,8 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, int result = 0; /* get block type */ - block_type = get_vlc2(bitbuf, svq1_block_type.table, 2, 2); + block_type = get_vlc2(bitbuf, svq1_block_type.table, + SVQ1_BLOCK_TYPE_VLC_BITS, 1); /* reset motion vectors */ if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) { @@ -619,7 +625,6 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, AVFrame *cur = data; uint8_t *current; int result, i, x, y, width, height; - svq1_pmv *pmv; int ret; /* initialize bit buffer */ @@ -679,8 +684,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, if (result < 0) return result; - pmv = av_malloc((FFALIGN(s->width, 16) / 8 + 3) * sizeof(*pmv)); - if (!pmv) + av_fast_padded_malloc(&s->pmv, &s->pmv_allocated, (FFALIGN(s->width, 16) / 8 + 3) * sizeof(*s->pmv)); + if (!s->pmv) return AVERROR(ENOMEM); /* decode y, u and v components */ @@ -708,7 +713,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Error in svq1_decode_block %i (keyframe)\n", result); - goto err; + return result; } } current += 16 * linesize; @@ -719,28 +724,27 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, 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; + return AVERROR_INVALIDDATA; } - memset(pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv)); + memset(s->pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv)); for (y = 0; y < height; y += 16) { for (x = 0; x < width; x += 16) { result = svq1_decode_delta_block(avctx, &s->hdsp, &s->gb, ¤t[x], previous, linesize, - pmv, x, y, width, height); + s->pmv, x, y, width, height); if (result != 0) { ff_dlog(avctx, "Error in svq1_decode_delta_block %i\n", result); - goto err; + return result; } } - pmv[0].x = - pmv[0].y = 0; + s->pmv[0].x = + s->pmv[0].y = 0; current += 16 * linesize; } @@ -751,42 +755,26 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, av_frame_unref(s->prev); result = av_frame_ref(s->prev, cur); if (result < 0) - goto err; + return result; } *got_frame = 1; result = buf_size; -err: - av_free(pmv); return result; } -static av_cold int svq1_decode_init(AVCodecContext *avctx) +static av_cold void svq1_static_init(void) { - SVQ1Context *s = avctx->priv_data; - int i; - int offset = 0; - - s->prev = av_frame_alloc(); - if (!s->prev) - return AVERROR(ENOMEM); - - s->width = avctx->width + 3 & ~3; - s->height = avctx->height + 3 & ~3; - avctx->pix_fmt = AV_PIX_FMT_YUV410P; - - ff_hpeldsp_init(&s->hdsp, avctx->flags); - - INIT_VLC_STATIC(&svq1_block_type, 2, 4, + INIT_VLC_STATIC(&svq1_block_type, SVQ1_BLOCK_TYPE_VLC_BITS, 4, &ff_svq1_block_type_vlc[0][1], 2, 1, - &ff_svq1_block_type_vlc[0][0], 2, 1, 6); + &ff_svq1_block_type_vlc[0][0], 2, 1, 8); INIT_VLC_STATIC(&svq1_motion_component, 7, 33, &ff_mvtab[0][1], 2, 1, &ff_mvtab[0][0], 2, 1, 176); - for (i = 0; i < 6; i++) { + for (int i = 0, offset = 0; i < 6; i++) { static const uint8_t sizes[2][6] = { { 14, 10, 14, 18, 16, 18 }, { 10, 10, 14, 14, 14, 16 } }; static VLC_TYPE table[168][2]; @@ -813,6 +801,24 @@ static av_cold int svq1_decode_init(AVCodecContext *avctx) INIT_VLC_STATIC(&svq1_inter_mean, 9, 512, &ff_svq1_inter_mean_vlc[0][1], 4, 2, &ff_svq1_inter_mean_vlc[0][0], 4, 2, 1434); +} + +static av_cold int svq1_decode_init(AVCodecContext *avctx) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + SVQ1Context *s = avctx->priv_data; + + s->prev = av_frame_alloc(); + if (!s->prev) + return AVERROR(ENOMEM); + + s->width = avctx->width + 3 & ~3; + s->height = avctx->height + 3 & ~3; + avctx->pix_fmt = AV_PIX_FMT_YUV410P; + + ff_hpeldsp_init(&s->hdsp, avctx->flags); + + ff_thread_once(&init_static_once, svq1_static_init); return 0; } @@ -824,6 +830,8 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx) av_frame_free(&s->prev); av_freep(&s->pkt_swapped); s->pkt_swapped_allocated = 0; + av_freep(&s->pmv); + s->pmv_allocated = 0; return 0; } @@ -848,4 +856,5 @@ AVCodec ff_svq1_decoder = { .flush = svq1_flush, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index cb215c250..4fac0c26e 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -472,7 +472,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane, if (best != 2) for (i = 5; i >= 0; i--) - avpriv_copy_bits(&s->pb, reorder_buffer[best][i], + ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]); if (best == 0) s->hdsp.put_pixels_tab[0][0](decoded, temp, stride, 16); @@ -529,7 +529,6 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) s->current_picture = av_frame_alloc(); s->last_picture = av_frame_alloc(); if (!s->current_picture || !s->last_picture) { - svq1_encode_end(avctx); return AVERROR(ENOMEM); } @@ -546,7 +545,6 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) s->m.avctx = avctx; if ((ret = ff_mpv_common_init(&s->m)) < 0) { - svq1_encode_end(avctx); return ret; } @@ -564,7 +562,6 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) if (!s->m.me.temp || !s->m.me.scratchpad || !s->m.me.map || !s->m.me.score_map || !s->mb_type || !s->dummy) { - svq1_encode_end(avctx); return AVERROR(ENOMEM); } @@ -650,7 +647,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } } - // avpriv_align_put_bits(&s->pb); + // align_put_bits(&s->pb); while (put_bits_count(&s->pb) & 31) put_bits(&s->pb, 1, 0); @@ -692,6 +689,7 @@ AVCodec ff_svq1_encoder = { .init = svq1_encode_init, .encode2 = svq1_encode_frame, .close = svq1_encode_end, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P, AV_PIX_FMT_NONE }, }; diff --git a/libavcodec/svq1enc.h b/libavcodec/svq1enc.h index b4ef76341..bb6af082d 100644 --- a/libavcodec/svq1enc.h +++ b/libavcodec/svq1enc.h @@ -24,6 +24,7 @@ #include #include "libavutil/frame.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "hpeldsp.h" diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index c8db08a32..54ef4add0 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -44,6 +44,7 @@ #include "libavutil/attributes.h" #include "libavutil/crc.h" +#include "libavutil/mem_internal.h" #include "internal.h" #include "avcodec.h" @@ -70,15 +71,10 @@ typedef struct SVQ3Frame { AVFrame *f; - AVBufferRef *motion_val_buf[2]; + int16_t (*motion_val_buf[2])[2]; int16_t (*motion_val[2])[2]; - AVBufferRef *mb_type_buf; - uint32_t *mb_type; - - - AVBufferRef *ref_index_buf[2]; - int8_t *ref_index[2]; + uint32_t *mb_type_buf, *mb_type; } SVQ3Frame; typedef struct SVQ3Context { @@ -147,6 +143,7 @@ typedef struct SVQ3Context { DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15 * 8]; uint32_t dequant4_coeff[QP_MAX_NUM + 1][16]; int block_offset[2 * (16 * 3)]; + SVQ3Frame frames[3]; } SVQ3Context; #define FULLPEL_MODE 1 @@ -221,8 +218,6 @@ static const uint32_t svq3_dequant_coeff[32] = { 61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533 }; -static int svq3_decode_end(AVCodecContext *avctx); - static void svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp) { const unsigned qmul = svq3_dequant_coeff[qp]; @@ -1135,13 +1130,9 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) 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) { - ret = AVERROR(ENOMEM); - goto fail; - } + s->cur_pic = &s->frames[0]; + s->last_pic = &s->frames[1]; + s->next_pic = &s->frames[2]; s->cur_pic->f = av_frame_alloc(); s->last_pic->f = av_frame_alloc(); @@ -1188,10 +1179,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) int w,h; size = AV_RB32(&extradata[4]); - if (size > extradata_end - extradata - 8) { - ret = AVERROR_INVALIDDATA; - goto fail; - } + if (size > extradata_end - extradata - 8) + return AVERROR_INVALIDDATA; init_get_bits(&gb, extradata + 8, size * 8); /* 'frame size code' and optional 'width, height' */ @@ -1232,7 +1221,7 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) } ret = ff_set_dimensions(avctx, w, h); if (ret < 0) - goto fail; + return ret; s->halfpel_flag = get_bits1(&gb); s->thirdpel_flag = get_bits1(&gb); @@ -1251,10 +1240,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "Unknown fields %d %d %d %d %d\n", unk0, unk1, unk2, unk3, unk4); - if (skip_1stop_8data_bits(&gb) < 0) { - ret = AVERROR_INVALIDDATA; - goto fail; - } + if (skip_1stop_8data_bits(&gb) < 0) + return AVERROR_INVALIDDATA; s->has_watermark = get_bits1(&gb); avctx->has_b_frames = !s->low_delay; @@ -1272,16 +1259,13 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) uint8_t *buf; if (watermark_height <= 0 || - (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) { - ret = -1; - goto fail; - } + (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) + return AVERROR_INVALIDDATA; buf = av_malloc(buf_len); - if (!buf) { - ret = AVERROR(ENOMEM); - goto fail; - } + if (!buf) + return AVERROR(ENOMEM); + av_log(avctx, AV_LOG_DEBUG, "watermark size: %ux%u\n", watermark_width, watermark_height); av_log(avctx, AV_LOG_DEBUG, @@ -1292,8 +1276,7 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "could not uncompress watermark logo\n"); av_free(buf); - ret = -1; - goto fail; + return -1; } s->watermark_key = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_CCITT), 0, buf, buf_len)); @@ -1304,8 +1287,7 @@ 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"); - ret = -1; - goto fail; + return AVERROR(ENOSYS); #endif } } @@ -1337,19 +1319,15 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) init_dequant4_coeff_table(s); return 0; -fail: - svq3_decode_end(avctx); - return ret; } static void free_picture(AVCodecContext *avctx, SVQ3Frame *pic) { int i; for (i = 0; i < 2; i++) { - av_buffer_unref(&pic->motion_val_buf[i]); - av_buffer_unref(&pic->ref_index_buf[i]); + av_freep(&pic->motion_val_buf[i]); } - av_buffer_unref(&pic->mb_type_buf); + av_freep(&pic->mb_type_buf); av_frame_unref(pic->f); } @@ -1358,7 +1336,6 @@ static int get_buffer(AVCodecContext *avctx, SVQ3Frame *pic) { SVQ3Context *s = avctx->priv_data; const int big_mb_num = s->mb_stride * (s->mb_height + 1) + 1; - const int mb_array_size = s->mb_stride * s->mb_height; const int b4_stride = s->mb_width * 4 + 1; const int b4_array_size = b4_stride * s->mb_height * 4; int ret; @@ -1366,21 +1343,19 @@ static int get_buffer(AVCodecContext *avctx, SVQ3Frame *pic) if (!pic->motion_val_buf[0]) { int i; - pic->mb_type_buf = av_buffer_allocz((big_mb_num + s->mb_stride) * sizeof(uint32_t)); + pic->mb_type_buf = av_calloc(big_mb_num + s->mb_stride, sizeof(uint32_t)); if (!pic->mb_type_buf) return AVERROR(ENOMEM); - pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * s->mb_stride + 1; + pic->mb_type = pic->mb_type_buf + 2 * s->mb_stride + 1; for (i = 0; i < 2; i++) { - pic->motion_val_buf[i] = av_buffer_allocz(2 * (b4_array_size + 4) * sizeof(int16_t)); - pic->ref_index_buf[i] = av_buffer_allocz(4 * mb_array_size); - if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) { + pic->motion_val_buf[i] = av_calloc(b4_array_size + 4, 2 * sizeof(int16_t)); + if (!pic->motion_val_buf[i]) { ret = AVERROR(ENOMEM); goto fail; } - pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4; - pic->ref_index[i] = pic->ref_index_buf[i]->data; + pic->motion_val[i] = pic->motion_val_buf[i] + 4; } } @@ -1631,9 +1606,6 @@ static av_cold int svq3_decode_end(AVCodecContext *avctx) av_frame_free(&s->cur_pic->f); av_frame_free(&s->next_pic->f); av_frame_free(&s->last_pic->f); - av_freep(&s->cur_pic); - av_freep(&s->next_pic); - av_freep(&s->last_pic); av_freep(&s->slice_buf); av_freep(&s->intra4x4_pred_mode); av_freep(&s->edge_emu_buffer); @@ -1660,4 +1632,5 @@ AVCodec ff_svq3_decoder = { AV_CODEC_CAP_DELAY, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE}, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 9fa1cb1f7..931e5d3fb 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -26,6 +26,7 @@ */ #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/samplefmt.h" #define BITSTREAM_READER_LE @@ -947,7 +948,7 @@ AVCodec ff_tak_decoder = { .close = tak_decode_close, .decode = tak_decode_frame, .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P, diff --git a/libavcodec/tdsc.c b/libavcodec/tdsc.c index 361791107..9e7381c2b 100644 --- a/libavcodec/tdsc.c +++ b/libavcodec/tdsc.c @@ -53,6 +53,7 @@ typedef struct TDSCContext { GetByteContext gbc; AVFrame *refframe; // full decoded frame (without cursor) + AVPacket *jpkt; // encoded JPEG tile AVFrame *jpgframe; // decoded JPEG tile uint8_t *tilebuffer; // buffer containing tile data @@ -80,6 +81,7 @@ static av_cold int tdsc_close(AVCodecContext *avctx) av_frame_free(&ctx->refframe); av_frame_free(&ctx->jpgframe); + av_packet_free(&ctx->jpkt); av_freep(&ctx->deflatebuffer); av_freep(&ctx->tilebuffer); av_freep(&ctx->cursor); @@ -111,7 +113,8 @@ static av_cold int tdsc_init(AVCodecContext *avctx) /* Allocate reference and JPEG frame */ ctx->refframe = av_frame_alloc(); ctx->jpgframe = av_frame_alloc(); - if (!ctx->refframe || !ctx->jpgframe) + ctx->jpkt = av_packet_alloc(); + if (!ctx->refframe || !ctx->jpgframe || !ctx->jpkt) return AVERROR(ENOMEM); /* Prepare everything needed for JPEG decoding */ @@ -125,7 +128,7 @@ static av_cold int tdsc_init(AVCodecContext *avctx) ctx->jpeg_avctx->flags2 = avctx->flags2; ctx->jpeg_avctx->dct_algo = avctx->dct_algo; ctx->jpeg_avctx->idct_algo = avctx->idct_algo; - ret = ff_codec_open2_recursive(ctx->jpeg_avctx, codec, NULL); + ret = avcodec_open2(ctx->jpeg_avctx, codec, NULL); if (ret < 0) return ret; @@ -342,15 +345,14 @@ static int tdsc_decode_jpeg_tile(AVCodecContext *avctx, int tile_size, int x, int y, int w, int h) { TDSCContext *ctx = avctx->priv_data; - AVPacket jpkt; int ret; /* Prepare a packet and send to the MJPEG decoder */ - av_init_packet(&jpkt); - jpkt.data = ctx->tilebuffer; - jpkt.size = tile_size; + av_packet_unref(ctx->jpkt); + ctx->jpkt->data = ctx->tilebuffer; + ctx->jpkt->size = tile_size; - ret = avcodec_send_packet(ctx->jpeg_avctx, &jpkt); + ret = avcodec_send_packet(ctx->jpeg_avctx, ctx->jpkt); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); return ret; @@ -529,10 +531,15 @@ static int tdsc_decode_frame(AVCodecContext *avctx, void *data, /* Resize deflate buffer on resolution change */ if (ctx->width != avctx->width || ctx->height != avctx->height) { - ctx->deflatelen = avctx->width * avctx->height * (3 + 1); - ret = av_reallocp(&ctx->deflatebuffer, ctx->deflatelen); - if (ret < 0) - return ret; + int deflatelen = avctx->width * avctx->height * (3 + 1); + if (deflatelen != ctx->deflatelen) { + ctx->deflatelen =deflatelen; + ret = av_reallocp(&ctx->deflatebuffer, ctx->deflatelen); + if (ret < 0) { + ctx->deflatelen = 0; + return ret; + } + } } dlen = ctx->deflatelen; diff --git a/libavcodec/tests/avpacket.c b/libavcodec/tests/avpacket.c index 90b72341f..7a70ade4c 100644 --- a/libavcodec/tests/avpacket.c +++ b/libavcodec/tests/avpacket.c @@ -63,9 +63,6 @@ static int initializations(AVPacket* avpkt) const static uint8_t* data = "selftest for av_packet_clone(...)"; int ret = 0; - /* initialize avpkt */ - av_init_packet(avpkt); - /* set values for avpkt */ avpkt->pts = 17; avpkt->dts = 2; @@ -82,16 +79,24 @@ static int initializations(AVPacket* avpkt) int main(void) { - AVPacket avpkt; + AVPacket *avpkt = NULL; AVPacket *avpkt_clone = NULL; int ret = 0; - if(initializations(&avpkt) < 0){ + /* test av_packet_alloc */ + avpkt = av_packet_alloc(); + if(!avpkt) { + av_log(NULL, AV_LOG_ERROR, "av_packet_alloc failed to allcoate AVPacket\n"); + return 1; + } + + if (initializations(avpkt) < 0) { printf("failed to initialize variables\n"); + av_packet_free(&avpkt); return 1; } /* test av_packet_clone*/ - avpkt_clone = av_packet_clone(&avpkt); + avpkt_clone = av_packet_clone(avpkt); if(!avpkt_clone) { av_log(NULL, AV_LOG_ERROR,"av_packet_clone failed to clone AVPacket\n"); @@ -121,7 +126,7 @@ int main(void) } /*clean up*/ av_packet_free(&avpkt_clone); - av_packet_unref(&avpkt); + av_packet_free(&avpkt); return ret; diff --git a/libavcodec/tests/cabac.c b/libavcodec/tests/cabac.c index affe4eb14..a8bd131c9 100644 --- a/libavcodec/tests/cabac.c +++ b/libavcodec/tests/cabac.c @@ -24,41 +24,51 @@ #include "libavutil/lfg.h" #include "libavcodec/avcodec.h" +#include "libavcodec/put_bits.h" -static inline void put_cabac_bit(CABACContext *c, int b){ +typedef struct CABACTestContext { + CABACContext dec; + int outstanding_count; + PutBitContext pb; +} CABACTestContext; + +static inline void put_cabac_bit(CABACTestContext *c, int b) +{ put_bits(&c->pb, 1, b); for(;c->outstanding_count; c->outstanding_count--){ put_bits(&c->pb, 1, 1-b); } } -static inline void renorm_cabac_encoder(CABACContext *c){ - while(c->range < 0x100){ +static inline void renorm_cabac_encoder(CABACTestContext *c) +{ + while (c->dec.range < 0x100) { //FIXME optimize - if(c->low<0x100){ + if (c->dec.low < 0x100) { put_cabac_bit(c, 0); - }else if(c->low<0x200){ + } else if (c->dec.low < 0x200) { c->outstanding_count++; - c->low -= 0x100; + c->dec.low -= 0x100; }else{ put_cabac_bit(c, 1); - c->low -= 0x200; + c->dec.low -= 0x200; } - c->range+= c->range; - c->low += c->low; + c->dec.range += c->dec.range; + c->dec.low += c->dec.low; } } -static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ - int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state]; +static void put_cabac(CABACTestContext *c, uint8_t * const state, int bit) +{ + int RangeLPS = ff_h264_lps_range[2 * (c->dec.range & 0xC0) + *state]; if(bit == ((*state)&1)){ - c->range -= RangeLPS; + c->dec.range -= RangeLPS; *state = ff_h264_mlps_state[128 + *state]; }else{ - c->low += c->range - RangeLPS; - c->range = RangeLPS; + c->dec.low += c->dec.range - RangeLPS; + c->dec.range = RangeLPS; *state= ff_h264_mlps_state[127 - *state]; } @@ -68,21 +78,22 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ /** * @param bit 0 -> write zero bit, !=0 write one bit */ -static void put_cabac_bypass(CABACContext *c, int bit){ - c->low += c->low; +static void put_cabac_bypass(CABACTestContext *c, int bit) +{ + c->dec.low += c->dec.low; if(bit){ - c->low += c->range; + c->dec.low += c->dec.range; } //FIXME optimize - if(c->low<0x200){ + if (c->dec.low < 0x200) { put_cabac_bit(c, 0); - }else if(c->low<0x400){ + } else if (c->dec.low < 0x400) { c->outstanding_count++; - c->low -= 0x200; + c->dec.low -= 0x200; }else{ put_cabac_bit(c, 1); - c->low -= 0x400; + c->dec.low -= 0x400; } } @@ -90,20 +101,21 @@ static void put_cabac_bypass(CABACContext *c, int bit){ * * @return the number of bytes written */ -static int put_cabac_terminate(CABACContext *c, int bit){ - c->range -= 2; +static int put_cabac_terminate(CABACTestContext *c, int bit) +{ + c->dec.range -= 2; if(!bit){ renorm_cabac_encoder(c); }else{ - c->low += c->range; - c->range= 2; + c->dec.low += c->dec.range; + c->dec.range = 2; renorm_cabac_encoder(c); - av_assert0(c->low <= 0x1FF); - put_cabac_bit(c, c->low>>9); - put_bits(&c->pb, 2, ((c->low>>7)&3)|1); + av_assert0(c->dec.low <= 0x1FF); + put_cabac_bit(c, c->dec.low >> 9); + put_bits(&c->pb, 2, ((c->dec.low >> 7) & 3) | 1); flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong } @@ -111,8 +123,21 @@ static int put_cabac_terminate(CABACContext *c, int bit){ return (put_bits_count(&c->pb)+7)>>3; } +/** + * @param buf_size size of buf in bits + */ +static void init_cabac_encoder(CABACTestContext *c, uint8_t *buf, int buf_size) +{ + init_put_bits(&c->pb, buf, buf_size); + + c->dec.low = 0; + c->dec.range = 0x1FE; + c->outstanding_count = 0; + c->pb.bit_left++; //avoids firstBitFlag +} + int main(void){ - CABACContext c; + CABACTestContext c; uint8_t b[9*SIZE]; uint8_t r[9*SIZE]; int i, ret = 0; @@ -120,7 +145,7 @@ int main(void){ AVLFG prng; av_lfg_init(&prng, 1); - ff_init_cabac_encoder(&c, b, SIZE); + init_cabac_encoder(&c, b, SIZE); for(i=0; ibytestream == tmp.bytestream && c->bytestream > c->bytestream_start) + tmp.low -= *--tmp.bytestream; + tmp.bytestream_end = tmp.bytestream; + + if (get_rac(&tmp, (uint8_t[]) { 129 })) + return AVERROR_INVALIDDATA; + } else { + if (c->bytestream_end != c->bytestream) + return AVERROR_INVALIDDATA; + } + return 0; +} + int main(void) { RangeCoder c; @@ -61,7 +87,7 @@ int main(void) return 1; } - if (ff_rac_check_termination(&c, version) < 0) { + if (rac_check_termination(&c, version) < 0) { av_log(NULL, AV_LOG_ERROR, "rac failure at termination pass %d version %d\n", p, version); return 1; } diff --git a/libavcodec/tests/x86/dct.c b/libavcodec/tests/x86/dct.c index afb03b194..f5c238efc 100644 --- a/libavcodec/tests/x86/dct.c +++ b/libavcodec/tests/x86/dct.c @@ -18,6 +18,8 @@ #include "config.h" +#include "libavutil/mem_internal.h" + #include "libavcodec/x86/fdct.h" #include "libavcodec/x86/xvididct.h" #include "libavcodec/x86/simple_idct.h" diff --git a/libavcodec/thread.h b/libavcodec/thread.h index 540135fbc..413196269 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -96,6 +96,7 @@ void ff_thread_report_progress(ThreadFrame *f, int progress, int field); */ void ff_thread_await_progress(ThreadFrame *f, int progress, int field); +#if FF_API_THREAD_SAFE_CALLBACKS /** * Wrapper around get_format() for frame-multithreaded codecs. * Call this function instead of avctx->get_format(). @@ -105,6 +106,9 @@ void ff_thread_await_progress(ThreadFrame *f, int progress, int field); * @param fmt The list of available formats. */ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt); +#else +#define ff_thread_get_format ff_get_format +#endif /** * Wrapper around get_buffer() for frame-multithreaded codecs. @@ -129,7 +133,7 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags); */ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f); -int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src); +int ff_thread_ref_frame(ThreadFrame *dst, const ThreadFrame *src); int ff_thread_init(AVCodecContext *s); int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 59a993ec8..f8c68f1e7 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -58,6 +58,7 @@ typedef struct TiffContext { /* JPEG decoding for DNG */ AVCodecContext *avctx_mjpeg; // wrapper context for MJPEG + AVPacket *jpkt; // encoded JPEG tile AVFrame *jpgframe; // decoded JPEG tile int get_subimage; @@ -132,8 +133,8 @@ static void free_geotags(TiffContext *const s) #define RET_GEOKEY(TYPE, array, element)\ if (key >= TIFF_##TYPE##_KEY_ID_OFFSET &&\ - key - TIFF_##TYPE##_KEY_ID_OFFSET < FF_ARRAY_ELEMS(ff_tiff_##array##_name_type_map))\ - return ff_tiff_##array##_name_type_map[key - TIFF_##TYPE##_KEY_ID_OFFSET].element; + key - TIFF_##TYPE##_KEY_ID_OFFSET < FF_ARRAY_ELEMS(tiff_##array##_name_type_map))\ + return tiff_##array##_name_type_map[key - TIFF_##TYPE##_KEY_ID_OFFSET].element; static const char *get_geokey_name(int key) { @@ -180,8 +181,8 @@ static char *get_geokey_val(int key, int val) #define RET_GEOKEY_VAL(TYPE, array)\ if (val >= TIFF_##TYPE##_OFFSET &&\ - val - TIFF_##TYPE##_OFFSET < FF_ARRAY_ELEMS(ff_tiff_##array##_codes))\ - return av_strdup(ff_tiff_##array##_codes[val - TIFF_##TYPE##_OFFSET]); + val - TIFF_##TYPE##_OFFSET < FF_ARRAY_ELEMS(tiff_##array##_codes))\ + return av_strdup(tiff_##array##_codes[val - TIFF_##TYPE##_OFFSET]); switch (key) { case TIFF_GT_MODEL_TYPE_GEOKEY: @@ -214,11 +215,11 @@ static char *get_geokey_val(int key, int val) RET_GEOKEY_VAL(PRIME_MERIDIAN, prime_meridian); break; case TIFF_PROJECTED_CS_TYPE_GEOKEY: - ap = av_strdup(search_keyval(ff_tiff_proj_cs_type_codes, FF_ARRAY_ELEMS(ff_tiff_proj_cs_type_codes), val)); + ap = av_strdup(search_keyval(tiff_proj_cs_type_codes, FF_ARRAY_ELEMS(tiff_proj_cs_type_codes), val)); if(ap) return ap; break; case TIFF_PROJECTION_GEOKEY: - ap = av_strdup(search_keyval(ff_tiff_projection_codes, FF_ARRAY_ELEMS(ff_tiff_projection_codes), val)); + ap = av_strdup(search_keyval(tiff_projection_codes, FF_ARRAY_ELEMS(tiff_projection_codes), val)); if(ap) return ap; break; case TIFF_PROJ_COORD_TRANS_GEOKEY: @@ -274,9 +275,101 @@ static int add_metadata(int count, int type, }; } +/** + * Map stored raw sensor values into linear reference values (see: DNG Specification - Chapter 5) + */ +static uint16_t av_always_inline dng_process_color16(uint16_t value, + const uint16_t *lut, + uint16_t black_level, + float scale_factor) +{ + float value_norm; + + // Lookup table lookup + if (lut) + value = lut[value]; + + // Black level subtraction + value = av_clip_uint16_c((unsigned)value - black_level); + + // Color scaling + value_norm = (float)value * scale_factor; + + value = av_clip_uint16_c(value_norm * 65535); + + return value; +} + +static uint16_t av_always_inline dng_process_color8(uint16_t value, + const uint16_t *lut, + uint16_t black_level, + float scale_factor) +{ + return dng_process_color16(value, lut, black_level, scale_factor) >> 8; +} + static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int width, int height, - int is_single_comp, int is_u16); + int is_single_comp, int is_u16) +{ + int line, col; + float scale_factor; + + scale_factor = 1.0f / (s->white_level - s->black_level); + + if (is_single_comp) { + if (!is_u16) + return; /* <= 8bpp unsupported */ + + /* Image is double the width and half the height we need, each row comprises 2 rows of the output + (split vertically in the middle). */ + for (line = 0; line < height / 2; line++) { + uint16_t *dst_u16 = (uint16_t *)dst; + uint16_t *src_u16 = (uint16_t *)src; + + /* Blit first half of input row row to initial row of output */ + for (col = 0; col < width; col++) + *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); + + /* Advance the destination pointer by a row (source pointer remains in the same place) */ + dst += dst_stride * sizeof(uint16_t); + dst_u16 = (uint16_t *)dst; + + /* Blit second half of input row row to next row of output */ + for (col = 0; col < width; col++) + *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); + + dst += dst_stride * sizeof(uint16_t); + src += src_stride * sizeof(uint16_t); + } + } else { + /* Input and output image are the same size and the MJpeg decoder has done per-component + deinterleaving, so blitting here is straightforward. */ + if (is_u16) { + for (line = 0; line < height; line++) { + uint16_t *dst_u16 = (uint16_t *)dst; + uint16_t *src_u16 = (uint16_t *)src; + + for (col = 0; col < width; col++) + *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); + + dst += dst_stride * sizeof(uint16_t); + src += src_stride * sizeof(uint16_t); + } + } else { + for (line = 0; line < height; line++) { + uint8_t *dst_u8 = dst; + const uint8_t *src_u8 = src; + + for (col = 0; col < width; col++) + *dst_u8++ = dng_process_color8(*src_u8++, s->dng_lut, s->black_level, scale_factor); + + dst += dst_stride; + src += src_stride; + } + } + } +} static void av_always_inline horizontal_fill(TiffContext *s, unsigned int bpp, uint8_t* dst, @@ -552,7 +645,108 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride, return ret; } -static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame); +static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame, + int tile_byte_count, int dst_x, int dst_y, int w, int h) +{ + TiffContext *s = avctx->priv_data; + uint8_t *dst_data, *src_data; + uint32_t dst_offset; /* offset from dst buffer in pixels */ + int is_single_comp, is_u16, pixel_size; + int ret; + + if (tile_byte_count < 0 || tile_byte_count > bytestream2_get_bytes_left(&s->gb)) + return AVERROR_INVALIDDATA; + + /* Prepare a packet and send to the MJPEG decoder */ + av_packet_unref(s->jpkt); + s->jpkt->data = (uint8_t*)s->gb.buffer; + s->jpkt->size = tile_byte_count; + + if (s->is_bayer) { + MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data; + /* We have to set this information here, there is no way to know if a given JPEG is a DNG-embedded + image or not from its own data (and we need that information when decoding it). */ + mjpegdecctx->bayer = 1; + } + + ret = avcodec_send_packet(s->avctx_mjpeg, s->jpkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); + return ret; + } + + ret = avcodec_receive_frame(s->avctx_mjpeg, s->jpgframe); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "JPEG decoding error: %s.\n", av_err2str(ret)); + + /* Normally skip, error if explode */ + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + else + return 0; + } + + is_u16 = (s->bpp > 8); + + /* Copy the outputted tile's pixels from 'jpgframe' to 'frame' (final buffer) */ + + if (s->jpgframe->width != s->avctx_mjpeg->width || + s->jpgframe->height != s->avctx_mjpeg->height || + s->jpgframe->format != s->avctx_mjpeg->pix_fmt) + return AVERROR_INVALIDDATA; + + /* See dng_blit for explanation */ + if (s->avctx_mjpeg->width == w * 2 && + s->avctx_mjpeg->height == h / 2 && + s->avctx_mjpeg->pix_fmt == AV_PIX_FMT_GRAY16LE) { + is_single_comp = 1; + } else if (s->avctx_mjpeg->width >= w && + s->avctx_mjpeg->height >= h && + s->avctx_mjpeg->pix_fmt == (is_u16 ? AV_PIX_FMT_GRAY16 : AV_PIX_FMT_GRAY8) + ) { + is_single_comp = 0; + } else + return AVERROR_INVALIDDATA; + + pixel_size = (is_u16 ? sizeof(uint16_t) : sizeof(uint8_t)); + + if (is_single_comp && !is_u16) { + av_log(s->avctx, AV_LOG_ERROR, "DNGs with bpp <= 8 and 1 component are unsupported\n"); + av_frame_unref(s->jpgframe); + return AVERROR_PATCHWELCOME; + } + + dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size; + dst_data = frame->data[0] + dst_offset * pixel_size; + src_data = s->jpgframe->data[0]; + + dng_blit(s, + dst_data, + frame->linesize[0] / pixel_size, + src_data, + s->jpgframe->linesize[0] / pixel_size, + w, + h, + is_single_comp, + is_u16); + + av_frame_unref(s->jpgframe); + + return 0; +} + +static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame) +{ + TiffContext *s = avctx->priv_data; + + s->jpgframe->width = s->width; + s->jpgframe->height = s->height; + + s->avctx_mjpeg->width = s->width; + s->avctx_mjpeg->height = s->height; + + return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, s->height); +} static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int stride, const uint8_t *src, int size, int strip_start, int lines) @@ -779,192 +973,8 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid return 0; } -/** - * Map stored raw sensor values into linear reference values (see: DNG Specification - Chapter 5) - */ -static uint16_t av_always_inline dng_process_color16(uint16_t value, - const uint16_t *lut, - uint16_t black_level, - float scale_factor) { - float value_norm; - - // Lookup table lookup - if (lut) - value = lut[value]; - - // Black level subtraction - value = av_clip_uint16_c((unsigned)value - black_level); - - // Color scaling - value_norm = (float)value * scale_factor; - - value = av_clip_uint16_c(value_norm * 65535); - - return value; -} - -static uint16_t av_always_inline dng_process_color8(uint16_t value, - const uint16_t *lut, - uint16_t black_level, - float scale_factor) { - return dng_process_color16(value, lut, black_level, scale_factor) >> 8; -} - -static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride, - const uint8_t *src, int src_stride, - int width, int height, int is_single_comp, int is_u16) -{ - int line, col; - float scale_factor; - - scale_factor = 1.0f / (s->white_level - s->black_level); - - if (is_single_comp) { - if (!is_u16) - return; /* <= 8bpp unsupported */ - - /* Image is double the width and half the height we need, each row comprises 2 rows of the output - (split vertically in the middle). */ - for (line = 0; line < height / 2; line++) { - uint16_t *dst_u16 = (uint16_t *)dst; - uint16_t *src_u16 = (uint16_t *)src; - - /* Blit first half of input row row to initial row of output */ - for (col = 0; col < width; col++) - *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); - - /* Advance the destination pointer by a row (source pointer remains in the same place) */ - dst += dst_stride * sizeof(uint16_t); - dst_u16 = (uint16_t *)dst; - - /* Blit second half of input row row to next row of output */ - for (col = 0; col < width; col++) - *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); - - dst += dst_stride * sizeof(uint16_t); - src += src_stride * sizeof(uint16_t); - } - } else { - /* Input and output image are the same size and the MJpeg decoder has done per-component - deinterleaving, so blitting here is straightforward. */ - if (is_u16) { - for (line = 0; line < height; line++) { - uint16_t *dst_u16 = (uint16_t *)dst; - uint16_t *src_u16 = (uint16_t *)src; - - for (col = 0; col < width; col++) - *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); - - dst += dst_stride * sizeof(uint16_t); - src += src_stride * sizeof(uint16_t); - } - } else { - for (line = 0; line < height; line++) { - uint8_t *dst_u8 = dst; - const uint8_t *src_u8 = src; - - for (col = 0; col < width; col++) - *dst_u8++ = dng_process_color8(*src_u8++, s->dng_lut, s->black_level, scale_factor); - - dst += dst_stride; - src += src_stride; - } - } - } -} - -static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame, - int tile_byte_count, int dst_x, int dst_y, int w, int h) -{ - TiffContext *s = avctx->priv_data; - AVPacket jpkt; - uint8_t *dst_data, *src_data; - uint32_t dst_offset; /* offset from dst buffer in pixels */ - int is_single_comp, is_u16, pixel_size; - int ret; - - if (tile_byte_count < 0 || tile_byte_count > bytestream2_get_bytes_left(&s->gb)) - return AVERROR_INVALIDDATA; - - /* Prepare a packet and send to the MJPEG decoder */ - av_init_packet(&jpkt); - jpkt.data = (uint8_t*)s->gb.buffer; - jpkt.size = tile_byte_count; - - if (s->is_bayer) { - MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data; - /* We have to set this information here, there is no way to know if a given JPEG is a DNG-embedded - image or not from its own data (and we need that information when decoding it). */ - mjpegdecctx->bayer = 1; - } - - ret = avcodec_send_packet(s->avctx_mjpeg, &jpkt); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); - return ret; - } - - ret = avcodec_receive_frame(s->avctx_mjpeg, s->jpgframe); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "JPEG decoding error: %s.\n", av_err2str(ret)); - - /* Normally skip, error if explode */ - if (avctx->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - else - return 0; - } - - is_u16 = (s->bpp > 8); - - /* Copy the outputted tile's pixels from 'jpgframe' to 'frame' (final buffer) */ - - if (s->jpgframe->width != s->avctx_mjpeg->width || - s->jpgframe->height != s->avctx_mjpeg->height || - s->jpgframe->format != s->avctx_mjpeg->pix_fmt) - return AVERROR_INVALIDDATA; - - /* See dng_blit for explanation */ - if (s->avctx_mjpeg->width == w * 2 && - s->avctx_mjpeg->height == h / 2 && - s->avctx_mjpeg->pix_fmt == AV_PIX_FMT_GRAY16LE) { - is_single_comp = 1; - } else if (s->avctx_mjpeg->width == w && - s->avctx_mjpeg->height == h && - s->avctx_mjpeg->pix_fmt == (is_u16 ? AV_PIX_FMT_GRAY16 : AV_PIX_FMT_GRAY8) - ) { - is_single_comp = 0; - } else - return AVERROR_INVALIDDATA; - - pixel_size = (is_u16 ? sizeof(uint16_t) : sizeof(uint8_t)); - - if (is_single_comp && !is_u16) { - av_log(s->avctx, AV_LOG_ERROR, "DNGs with bpp <= 8 and 1 component are unsupported\n"); - av_frame_unref(s->jpgframe); - return AVERROR_PATCHWELCOME; - } - - dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size; - dst_data = frame->data[0] + dst_offset * pixel_size; - src_data = s->jpgframe->data[0]; - - dng_blit(s, - dst_data, - frame->linesize[0] / pixel_size, - src_data, - s->jpgframe->linesize[0] / pixel_size, - w, - h, - is_single_comp, - is_u16); - - av_frame_unref(s->jpgframe); - - return 0; -} - -static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, AVPacket *avpkt) +static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, + const AVPacket *avpkt) { TiffContext *s = avctx->priv_data; int tile_idx; @@ -1039,19 +1049,6 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, AVPacket *avp return avpkt->size; } -static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame) -{ - TiffContext *s = avctx->priv_data; - - s->jpgframe->width = s->width; - s->jpgframe->height = s->height; - - s->avctx_mjpeg->width = s->width; - s->avctx_mjpeg->height = s->height; - - return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, s->height); -} - static int init_image(TiffContext *s, ThreadFrame *frame) { int ret; @@ -1590,7 +1587,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) break; case TIFF_GEO_KEY_DIRECTORY: if (s->geotag_count) { - avpriv_request_sample(s->avctx, "Multiple geo key directories\n"); + avpriv_request_sample(s->avctx, "Multiple geo key directories"); return AVERROR_INVALIDDATA; } ADD_METADATA(1, "GeoTIFF_Version", NULL); @@ -1682,9 +1679,6 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) } break; case TIFF_ICC_PROFILE: - if (type != TIFF_UNDEFINED) - return AVERROR_INVALIDDATA; - gb_temp = s->gb; bytestream2_seek(&gb_temp, SEEK_SET, off); @@ -1863,7 +1857,7 @@ again: return AVERROR_INVALIDDATA; } if (off <= last_off) { - avpriv_request_sample(s->avctx, "non increasing IFD offset\n"); + avpriv_request_sample(s->avctx, "non increasing IFD offset"); return AVERROR_INVALIDDATA; } if (off >= UINT_MAX - 14 || avpkt->size < off + 14) { @@ -1926,15 +1920,17 @@ again: has_strip_bits = s->strippos || s->strips || s->stripoff || s->rps || s->sot || s->sstype || s->stripsize || s->stripsizesoff; if (has_tile_bits && has_strip_bits) { - av_log(avctx, AV_LOG_ERROR, "Tiled TIFF is not allowed to strip\n"); - return AVERROR_INVALIDDATA; + int tiled_dng = s->is_tiled && is_dng; + av_log(avctx, tiled_dng ? AV_LOG_WARNING : AV_LOG_ERROR, "Tiled TIFF is not allowed to strip\n"); + if (!tiled_dng) + return AVERROR_INVALIDDATA; } /* now we have the data and may start decoding */ if ((ret = init_image(s, &frame)) < 0) return ret; - if (!s->is_tiled) { + if (!s->is_tiled || has_strip_bits) { if (s->strips == 1 && !s->stripsize) { av_log(avctx, AV_LOG_WARNING, "Image data size missing\n"); s->stripsize = avpkt->size - s->stripoff; @@ -2158,7 +2154,8 @@ static av_cold int tiff_init(AVCodecContext *avctx) /* Allocate JPEG frame */ s->jpgframe = av_frame_alloc(); - if (!s->jpgframe) + s->jpkt = av_packet_alloc(); + if (!s->jpgframe || !s->jpkt) return AVERROR(ENOMEM); /* Prepare everything needed for JPEG decoding */ @@ -2172,7 +2169,7 @@ static av_cold int tiff_init(AVCodecContext *avctx) s->avctx_mjpeg->flags2 = avctx->flags2; s->avctx_mjpeg->dct_algo = avctx->dct_algo; s->avctx_mjpeg->idct_algo = avctx->idct_algo; - ret = ff_codec_open2_recursive(s->avctx_mjpeg, codec, NULL); + ret = avcodec_open2(s->avctx_mjpeg, codec, NULL); if (ret < 0) { return ret; } @@ -2194,6 +2191,7 @@ static av_cold int tiff_end(AVCodecContext *avctx) av_freep(&s->fax_buffer); s->fax_buffer_size = 0; av_frame_free(&s->jpgframe); + av_packet_free(&s->jpkt); avcodec_free_context(&s->avctx_mjpeg); return 0; } @@ -2223,6 +2221,6 @@ AVCodec ff_tiff_decoder = { .close = tiff_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .priv_class = &tiff_decoder_class, }; diff --git a/libavcodec/tiff_common.h b/libavcodec/tiff_common.h index 03558c31a..019d23e6d 100644 --- a/libavcodec/tiff_common.h +++ b/libavcodec/tiff_common.h @@ -79,26 +79,6 @@ double ff_tget_double(GetByteContext *gb, int le); /** Reads a byte from the bytestream using given endianness. */ unsigned ff_tget(GetByteContext *gb, int type, int le); -/** Returns an allocated string containing count - * rational values using the given separator. - */ -char *ff_trationals2str(int *rp, int count, const char *sep); - -/** Returns an allocated string containing count - * long values using the given separator. - */ -char *ff_tlongs2str(int32_t *lp, int count, const char *sep); - -/** Returns an allocated string containing count - * double values using the given separator. - */ -char *ff_tdoubles2str(double *dp, int count, const char *sep); - -/** Returns an allocated string containing count - * short values using the given separator. - */ -char *ff_tshorts2str(int16_t *sp, int count, const char *sep); - /** Adds count rationals converted to a string * into the metadata dictionary. */ diff --git a/libavcodec/tiff_data.h b/libavcodec/tiff_data.h index 57515f903..9b123ca8d 100644 --- a/libavcodec/tiff_data.h +++ b/libavcodec/tiff_data.h @@ -33,60 +33,1863 @@ #include "tiff.h" #define TIFF_CONF_KEY_ID_OFFSET 1024 -extern const TiffGeoTagNameType ff_tiff_conf_name_type_map[3]; +static const TiffGeoTagNameType tiff_conf_name_type_map[] = { + {"GTModelTypeGeoKey", GEOTIFF_SHORT }, + {"GTRasterTypeGeoKey", GEOTIFF_SHORT }, + {"GTCitationGeoKey", GEOTIFF_STRING} +}; #define TIFF_GEOG_KEY_ID_OFFSET 2048 -extern const TiffGeoTagNameType ff_tiff_geog_name_type_map[14]; +static const TiffGeoTagNameType tiff_geog_name_type_map[] = { + {"GeographicTypeGeoKey", GEOTIFF_SHORT }, + {"GeogCitationGeoKey", GEOTIFF_STRING}, + {"GeogGeodeticDatumGeoKey", GEOTIFF_SHORT }, + {"GeogPrimeMeridianGeoKey", GEOTIFF_SHORT }, + {"GeogLinearUnitsGeoKey", GEOTIFF_SHORT }, + {"GeogLinearUnitSizeGeoKey", GEOTIFF_DOUBLE}, + {"GeogAngularUnitsGeoKey", GEOTIFF_SHORT }, + {"GeogAngularUnitSizeGeoKey", GEOTIFF_DOUBLE}, + {"GeogEllipsoidGeoKey", GEOTIFF_SHORT }, + {"GeogSemiMajorAxisGeoKey", GEOTIFF_DOUBLE}, + {"GeogSemiMinorAxisGeoKey", GEOTIFF_DOUBLE}, + {"GeogInvFlatteningGeoKey", GEOTIFF_DOUBLE}, + {"GeogAzimuthUnitsGeoKey", GEOTIFF_SHORT }, + {"GeogPrimeMeridianLongGeoKey", GEOTIFF_DOUBLE} +}; #define TIFF_PROJ_KEY_ID_OFFSET 3072 -extern const TiffGeoTagNameType ff_tiff_proj_name_type_map[24]; +static const TiffGeoTagNameType tiff_proj_name_type_map[] = { + {"ProjectedCSTypeGeoKey", GEOTIFF_SHORT }, + {"PCSCitationGeoKey", GEOTIFF_STRING}, + {"ProjectionGeoKey", GEOTIFF_SHORT }, + {"ProjCoordTransGeoKey", GEOTIFF_SHORT }, + {"ProjLinearUnitsGeoKey", GEOTIFF_SHORT }, + {"ProjLinearUnitSizeGeoKey", GEOTIFF_DOUBLE}, + {"ProjStdParallel1GeoKey", GEOTIFF_DOUBLE}, + {"ProjStdParallel2GeoKey", GEOTIFF_DOUBLE}, + {"ProjNatOriginLongGeoKey", GEOTIFF_DOUBLE}, + {"ProjNatOriginLatGeoKey", GEOTIFF_DOUBLE}, + {"ProjFalseEastingGeoKey", GEOTIFF_DOUBLE}, + {"ProjFalseNorthingGeoKey", GEOTIFF_DOUBLE}, + {"ProjFalseOriginLongGeoKey", GEOTIFF_DOUBLE}, + {"ProjFalseOriginLatGeoKey", GEOTIFF_DOUBLE}, + {"ProjFalseOriginEastingGeoKey", GEOTIFF_DOUBLE}, + {"ProjFalseOriginNorthingGeoKey", GEOTIFF_DOUBLE}, + {"ProjCenterLongGeoKey", GEOTIFF_DOUBLE}, + {"ProjCenterLatGeoKey", GEOTIFF_DOUBLE}, + {"ProjCenterEastingGeoKey", GEOTIFF_DOUBLE}, + {"ProjCenterNorthingGeoKey", GEOTIFF_DOUBLE}, + {"ProjScaleAtNatOriginGeoKey", GEOTIFF_DOUBLE}, + {"ProjScaleAtCenterGeoKey", GEOTIFF_DOUBLE}, + {"ProjAzimuthAngleGeoKey", GEOTIFF_DOUBLE}, + {"ProjStraightVertPoleLongGeoKey", GEOTIFF_DOUBLE} +}; #define TIFF_VERT_KEY_ID_OFFSET 4096 -extern const TiffGeoTagNameType ff_tiff_vert_name_type_map[4]; +static const TiffGeoTagNameType tiff_vert_name_type_map[] = { + {"VerticalCSTypeGeoKey", GEOTIFF_SHORT }, + {"VerticalCitationGeoKey", GEOTIFF_STRING}, + {"VerticalDatumGeoKey", GEOTIFF_SHORT }, + {"VerticalUnitsGeoKey", GEOTIFF_SHORT } +}; #define TIFF_GEO_KEY_UNDEFINED 0 #define TIFF_GEO_KEY_USER_DEFINED 32767 #define TIFF_GT_MODEL_TYPE_OFFSET 1 -extern const char *const ff_tiff_gt_model_type_codes[3]; +static const char *const tiff_gt_model_type_codes[] = { + "ModelTypeProjected", + "ModelTypeGeographic", + "ModelTypeGeocentric" +}; #define TIFF_GT_RASTER_TYPE_OFFSET 1 -extern const char *const ff_tiff_gt_raster_type_codes[2]; +static const char *const tiff_gt_raster_type_codes[] = { + "RasterPixelIsArea", + "RasterPixelIsPoint" +}; #define TIFF_LINEAR_UNIT_OFFSET 9001 -extern const char *const ff_tiff_linear_unit_codes[15]; +static const char *const tiff_linear_unit_codes[] = { + "Linear_Meter", + "Linear_Foot", + "Linear_Foot_US_Survey", + "Linear_Foot_Modified_American", + "Linear_Foot_Clarke", + "Linear_Foot_Indian", + "Linear_Link", + "Linear_Link_Benoit", + "Linear_Link_Sears", + "Linear_Chain_Benoit", + "Linear_Chain_Sears", + "Linear_Yard_Sears", + "Linear_Yard_Indian", + "Linear_Fathom", + "Linear_Mile_International_Nautical" +}; #define TIFF_ANGULAR_UNIT_OFFSET 9101 -extern const char *const ff_tiff_angular_unit_codes[8]; +static const char *const tiff_angular_unit_codes[] = { + "Angular_Radian", + "Angular_Degree", + "Angular_Arc_Minute", + "Angular_Arc_Second", + "Angular_Grad", + "Angular_Gon", + "Angular_DMS", + "Angular_DMS_Hemisphere" +}; #define TIFF_GCS_TYPE_OFFSET 4201 -extern const char *const ff_tiff_gcs_type_codes[133]; +static const char *const tiff_gcs_type_codes[] = { + "GCS_Adindan", + "GCS_AGD66", + "GCS_AGD84", + "GCS_Ain_el_Abd", + "GCS_Afgooye", + "GCS_Agadez", + "GCS_Lisbon", + "GCS_Aratu", + "GCS_Arc_1950", + "GCS_Arc_1960", + "GCS_Batavia", + "GCS_Barbados", + "GCS_Beduaram", + "GCS_Beijing_1954", + "GCS_Belge_1950", + "GCS_Bermuda_1957", + "GCS_Bern_1898", + "GCS_Bogota", + "GCS_Bukit_Rimpah", + "GCS_Camacupa", + "GCS_Campo_Inchauspe", + "GCS_Cape", + "GCS_Carthage", + "GCS_Chua", + "GCS_Corrego_Alegre", + "GCS_Cote_d_Ivoire", + "GCS_Deir_ez_Zor", + "GCS_Douala", + "GCS_Egypt_1907", + "GCS_ED50", + "GCS_ED87", + "GCS_Fahud", + "GCS_Gandajika_1970", + "GCS_Garoua", + "GCS_Guyane_Francaise", + "GCS_Hu_Tzu_Shan", + "GCS_HD72", + "GCS_ID74", + "GCS_Indian_1954", + "GCS_Indian_1975", + "GCS_Jamaica_1875", + "GCS_JAD69", + "GCS_Kalianpur", + "GCS_Kandawala", + "GCS_Kertau", + "GCS_KOC", + "GCS_La_Canoa", + "GCS_PSAD56", + "GCS_Lake", + "GCS_Leigon", + "GCS_Liberia_1964", + "GCS_Lome", + "GCS_Luzon_1911", + "GCS_Hito_XVIII_1963", + "GCS_Herat_North", + "GCS_Mahe_1971", + "GCS_Makassar", + "GCS_EUREF89", + "GCS_Malongo_1987", + "GCS_Manoca", + "GCS_Merchich", + "GCS_Massawa", + "GCS_Minna", + "GCS_Mhast", + "GCS_Monte_Mario", + "GCS_M_poraloko", + "GCS_NAD27", + "GCS_NAD_Michigan", + "GCS_NAD83", + "GCS_Nahrwan_1967", + "GCS_Naparima_1972", + "GCS_GD49", + "GCS_NGO_1948", + "GCS_Datum_73", + "GCS_NTF", + "GCS_NSWC_9Z_2", + "GCS_OSGB_1936", + "GCS_OSGB70", + "GCS_OS_SN80", + "GCS_Padang", + "GCS_Palestine_1923", + "GCS_Pointe_Noire", + "GCS_GDA94", + "GCS_Pulkovo_1942", + "GCS_Qatar", + "GCS_Qatar_1948", + "GCS_Qornoq", + "GCS_Loma_Quintana", + "GCS_Amersfoort", + "GCS_RT38", + "GCS_SAD69", + "GCS_Sapper_Hill_1943", + "GCS_Schwarzeck", + "GCS_Segora", + "GCS_Serindung", + "GCS_Sudan", + "GCS_Tananarive", + "GCS_Timbalai_1948", + "GCS_TM65", + "GCS_TM75", + "GCS_Tokyo", + "GCS_Trinidad_1903", + "GCS_TC_1948", + "GCS_Voirol_1875", + "GCS_Voirol_Unifie", + "GCS_Bern_1938", + "GCS_Nord_Sahara_1959", + "GCS_Stockholm_1938", + "GCS_Yacare", + "GCS_Yoff", + "GCS_Zanderij", + "GCS_MGI", + "GCS_Belge_1972", + "GCS_DHDN", + "GCS_Conakry_1905", + "GCS_WGS_72", + "GCS_WGS_72BE", + "GCS_WGS_84", + "GCS_Bern_1898_Bern", + "GCS_Bogota_Bogota", + "GCS_Lisbon_Lisbon", + "GCS_Makassar_Jakarta", + "GCS_MGI_Ferro", + "GCS_Monte_Mario_Rome", + "GCS_NTF_Paris", + "GCS_Padang_Jakarta", + "GCS_Belge_1950_Brussels", + "GCS_Tananarive_Paris", + "GCS_Voirol_1875_Paris", + "GCS_Voirol_Unifie_Paris", + "GCS_Batavia_Jakarta", + "GCS_ATF_Paris", + "GCS_NDG_Paris" +}; #define TIFF_GCSE_TYPE_OFFSET 4001 -extern const char *const ff_tiff_gcse_type_codes[35]; +static const char *const tiff_gcse_type_codes[] = { + "GCSE_Airy1830", + "GCSE_AiryModified1849", + "GCSE_AustralianNationalSpheroid", + "GCSE_Bessel1841", + "GCSE_BesselModified", + "GCSE_BesselNamibia", + "GCSE_Clarke1858", + "GCSE_Clarke1866", + "GCSE_Clarke1866Michigan", + "GCSE_Clarke1880_Benoit", + "GCSE_Clarke1880_IGN", + "GCSE_Clarke1880_RGS", + "GCSE_Clarke1880_Arc", + "GCSE_Clarke1880_SGA1922", + "GCSE_Everest1830_1937Adjustment", + "GCSE_Everest1830_1967Definition", + "GCSE_Everest1830_1975Definition", + "GCSE_Everest1830Modified", + "GCSE_GRS1980", + "GCSE_Helmert1906", + "GCSE_IndonesianNationalSpheroid", + "GCSE_International1924", + "GCSE_International1967", + "GCSE_Krassowsky1940", + "GCSE_NWL9D", + "GCSE_NWL10D", + "GCSE_Plessis1817", + "GCSE_Struve1860", + "GCSE_WarOffice", + "GCSE_WGS84", + "GCSE_GEM10C", + "GCSE_OSU86F", + "GCSE_OSU91A", + "GCSE_Clarke1880", + "GCSE_Sphere" +}; #define TIFF_GEODETIC_DATUM_OFFSET 6201 -extern const char *const ff_tiff_geodetic_datum_codes[120]; +static const char *const tiff_geodetic_datum_codes[] = { + "Datum_Adindan", + "Datum_Australian_Geodetic_Datum_1966", + "Datum_Australian_Geodetic_Datum_1984", + "Datum_Ain_el_Abd_1970", + "Datum_Afgooye", + "Datum_Agadez", + "Datum_Lisbon", + "Datum_Aratu", + "Datum_Arc_1950", + "Datum_Arc_1960", + "Datum_Batavia", + "Datum_Barbados", + "Datum_Beduaram", + "Datum_Beijing_1954", + "Datum_Reseau_National_Belge_1950", + "Datum_Bermuda_1957", + "Datum_Bern_1898", + "Datum_Bogota", + "Datum_Bukit_Rimpah", + "Datum_Camacupa", + "Datum_Campo_Inchauspe", + "Datum_Cape", + "Datum_Carthage", + "Datum_Chua", + "Datum_Corrego_Alegre", + "Datum_Cote_d_Ivoire", + "Datum_Deir_ez_Zor", + "Datum_Douala", + "Datum_Egypt_1907", + "Datum_European_Datum_1950", + "Datum_European_Datum_1987", + "Datum_Fahud", + "Datum_Gandajika_1970", + "Datum_Garoua", + "Datum_Guyane_Francaise", + "Datum_Hu_Tzu_Shan", + "Datum_Hungarian_Datum_1972", + "Datum_Indonesian_Datum_1974", + "Datum_Indian_1954", + "Datum_Indian_1975", + "Datum_Jamaica_1875", + "Datum_Jamaica_1969", + "Datum_Kalianpur", + "Datum_Kandawala", + "Datum_Kertau", + "Datum_Kuwait_Oil_Company", + "Datum_La_Canoa", + "Datum_Provisional_S_American_Datum_1956", + "Datum_Lake", + "Datum_Leigon", + "Datum_Liberia_1964", + "Datum_Lome", + "Datum_Luzon_1911", + "Datum_Hito_XVIII_1963", + "Datum_Herat_North", + "Datum_Mahe_1971", + "Datum_Makassar", + "Datum_European_Reference_System_1989", + "Datum_Malongo_1987", + "Datum_Manoca", + "Datum_Merchich", + "Datum_Massawa", + "Datum_Minna", + "Datum_Mhast", + "Datum_Monte_Mario", + "Datum_M_poraloko", + "Datum_North_American_Datum_1927", + "Datum_NAD_Michigan", + "Datum_North_American_Datum_1983", + "Datum_Nahrwan_1967", + "Datum_Naparima_1972", + "Datum_New_Zealand_Geodetic_Datum_1949", + "Datum_NGO_1948", + "Datum_Datum_73", + "Datum_Nouvelle_Triangulation_Francaise", + "Datum_NSWC_9Z_2", + "Datum_OSGB_1936", + "Datum_OSGB_1970_SN", + "Datum_OS_SN_1980", + "Datum_Padang_1884", + "Datum_Palestine_1923", + "Datum_Pointe_Noire", + "Datum_Geocentric_Datum_of_Australia_1994", + "Datum_Pulkovo_1942", + "Datum_Qatar", + "Datum_Qatar_1948", + "Datum_Qornoq", + "Datum_Loma_Quintana", + "Datum_Amersfoort", + "Datum_RT38", + "Datum_South_American_Datum_1969", + "Datum_Sapper_Hill_1943", + "Datum_Schwarzeck", + "Datum_Segora", + "Datum_Serindung", + "Datum_Sudan", + "Datum_Tananarive_1925", + "Datum_Timbalai_1948", + "Datum_TM65", + "Datum_TM75", + "Datum_Tokyo", + "Datum_Trinidad_1903", + "Datum_Trucial_Coast_1948", + "Datum_Voirol_1875", + "Datum_Voirol_Unifie_1960", + "Datum_Bern_1938", + "Datum_Nord_Sahara_1959", + "Datum_Stockholm_1938", + "Datum_Yacare", + "Datum_Yoff", + "Datum_Zanderij", + "Datum_Militar_Geographische_Institut", + "Datum_Reseau_National_Belge_1972", + "Datum_Deutsche_Hauptdreiecksnetz", + "Datum_Conakry_1905", + "Datum_WGS72", + "Datum_WGS72_Transit_Broadcast_Ephemeris", + "Datum_WGS84", + "Datum_Ancienne_Triangulation_Francaise", + "Datum_Nord_de_Guerre" +}; #define TIFF_GEODETIC_DATUM_E_OFFSET 6001 -extern const char *const ff_tiff_geodetic_datum_e_codes[35]; +static const char *const tiff_geodetic_datum_e_codes[] = { + "DatumE_Airy1830", + "DatumE_AiryModified1849", + "DatumE_AustralianNationalSpheroid", + "DatumE_Bessel1841", + "DatumE_BesselModified", + "DatumE_BesselNamibia", + "DatumE_Clarke1858", + "DatumE_Clarke1866", + "DatumE_Clarke1866Michigan", + "DatumE_Clarke1880_Benoit", + "DatumE_Clarke1880_IGN", + "DatumE_Clarke1880_RGS", + "DatumE_Clarke1880_Arc", + "DatumE_Clarke1880_SGA1922", + "DatumE_Everest1830_1937Adjustment", + "DatumE_Everest1830_1967Definition", + "DatumE_Everest1830_1975Definition", + "DatumE_Everest1830Modified", + "DatumE_GRS1980", + "DatumE_Helmert1906", + "DatumE_IndonesianNationalSpheroid", + "DatumE_International1924", + "DatumE_International1967", + "DatumE_Krassowsky1960", + "DatumE_NWL9D", + "DatumE_NWL10D", + "DatumE_Plessis1817", + "DatumE_Struve1860", + "DatumE_WarOffice", + "DatumE_WGS84", + "DatumE_GEM10C", + "DatumE_OSU86F", + "DatumE_OSU91A", + "DatumE_Clarke1880", + "DatumE_Sphere" +}; #define TIFF_ELLIPSOID_OFFSET 7001 -extern const char *const ff_tiff_ellipsoid_codes[35]; +static const char *const tiff_ellipsoid_codes[] = { + "Ellipse_Airy_1830", + "Ellipse_Airy_Modified_1849", + "Ellipse_Australian_National_Spheroid", + "Ellipse_Bessel_1841", + "Ellipse_Bessel_Modified", + "Ellipse_Bessel_Namibia", + "Ellipse_Clarke_1858", + "Ellipse_Clarke_1866", + "Ellipse_Clarke_1866_Michigan", + "Ellipse_Clarke_1880_Benoit", + "Ellipse_Clarke_1880_IGN", + "Ellipse_Clarke_1880_RGS", + "Ellipse_Clarke_1880_Arc", + "Ellipse_Clarke_1880_SGA_1922", + "Ellipse_Everest_1830_1937_Adjustment", + "Ellipse_Everest_1830_1967_Definition", + "Ellipse_Everest_1830_1975_Definition", + "Ellipse_Everest_1830_Modified", + "Ellipse_GRS_1980", + "Ellipse_Helmert_1906", + "Ellipse_Indonesian_National_Spheroid", + "Ellipse_International_1924", + "Ellipse_International_1967", + "Ellipse_Krassowsky_1940", + "Ellipse_NWL_9D", + "Ellipse_NWL_10D", + "Ellipse_Plessis_1817", + "Ellipse_Struve_1860", + "Ellipse_War_Office", + "Ellipse_WGS_84", + "Ellipse_GEM_10C", + "Ellipse_OSU86F", + "Ellipse_OSU91A", + "Ellipse_Clarke_1880", + "Ellipse_Sphere" +}; #define TIFF_PRIME_MERIDIAN_OFFSET 8901 -extern const char *const ff_tiff_prime_meridian_codes[11]; +static const char *const tiff_prime_meridian_codes[] = { + "PM_Greenwich", + "PM_Lisbon", + "PM_Paris", + "PM_Bogota", + "PM_Madrid", + "PM_Rome", + "PM_Bern", + "PM_Jakarta", + "PM_Ferro", + "PM_Brussels", + "PM_Stockholm" +}; -extern const TiffGeoTagKeyName ff_tiff_proj_cs_type_codes[978]; +static const TiffGeoTagKeyName tiff_proj_cs_type_codes[] = { + {20137, "PCS_Adindan_UTM_zone_37N"}, + {20138, "PCS_Adindan_UTM_zone_38N"}, + {20248, "PCS_AGD66_AMG_zone_48"}, + {20249, "PCS_AGD66_AMG_zone_49"}, + {20250, "PCS_AGD66_AMG_zone_50"}, + {20251, "PCS_AGD66_AMG_zone_51"}, + {20252, "PCS_AGD66_AMG_zone_52"}, + {20253, "PCS_AGD66_AMG_zone_53"}, + {20254, "PCS_AGD66_AMG_zone_54"}, + {20255, "PCS_AGD66_AMG_zone_55"}, + {20256, "PCS_AGD66_AMG_zone_56"}, + {20257, "PCS_AGD66_AMG_zone_57"}, + {20258, "PCS_AGD66_AMG_zone_58"}, + {20348, "PCS_AGD84_AMG_zone_48"}, + {20349, "PCS_AGD84_AMG_zone_49"}, + {20350, "PCS_AGD84_AMG_zone_50"}, + {20351, "PCS_AGD84_AMG_zone_51"}, + {20352, "PCS_AGD84_AMG_zone_52"}, + {20353, "PCS_AGD84_AMG_zone_53"}, + {20354, "PCS_AGD84_AMG_zone_54"}, + {20355, "PCS_AGD84_AMG_zone_55"}, + {20356, "PCS_AGD84_AMG_zone_56"}, + {20357, "PCS_AGD84_AMG_zone_57"}, + {20358, "PCS_AGD84_AMG_zone_58"}, + {20437, "PCS_Ain_el_Abd_UTM_zone_37N"}, + {20438, "PCS_Ain_el_Abd_UTM_zone_38N"}, + {20439, "PCS_Ain_el_Abd_UTM_zone_39N"}, + {20499, "PCS_Ain_el_Abd_Bahrain_Grid"}, + {20538, "PCS_Afgooye_UTM_zone_38N"}, + {20539, "PCS_Afgooye_UTM_zone_39N"}, + {20700, "PCS_Lisbon_Portugese_Grid"}, + {20822, "PCS_Aratu_UTM_zone_22S"}, + {20823, "PCS_Aratu_UTM_zone_23S"}, + {20824, "PCS_Aratu_UTM_zone_24S"}, + {20973, "PCS_Arc_1950_Lo13"}, + {20975, "PCS_Arc_1950_Lo15"}, + {20977, "PCS_Arc_1950_Lo17"}, + {20979, "PCS_Arc_1950_Lo19"}, + {20981, "PCS_Arc_1950_Lo21"}, + {20983, "PCS_Arc_1950_Lo23"}, + {20985, "PCS_Arc_1950_Lo25"}, + {20987, "PCS_Arc_1950_Lo27"}, + {20989, "PCS_Arc_1950_Lo29"}, + {20991, "PCS_Arc_1950_Lo31"}, + {20993, "PCS_Arc_1950_Lo33"}, + {20995, "PCS_Arc_1950_Lo35"}, + {21100, "PCS_Batavia_NEIEZ"}, + {21148, "PCS_Batavia_UTM_zone_48S"}, + {21149, "PCS_Batavia_UTM_zone_49S"}, + {21150, "PCS_Batavia_UTM_zone_50S"}, + {21413, "PCS_Beijing_Gauss_zone_13"}, + {21414, "PCS_Beijing_Gauss_zone_14"}, + {21415, "PCS_Beijing_Gauss_zone_15"}, + {21416, "PCS_Beijing_Gauss_zone_16"}, + {21417, "PCS_Beijing_Gauss_zone_17"}, + {21418, "PCS_Beijing_Gauss_zone_18"}, + {21419, "PCS_Beijing_Gauss_zone_19"}, + {21420, "PCS_Beijing_Gauss_zone_20"}, + {21421, "PCS_Beijing_Gauss_zone_21"}, + {21422, "PCS_Beijing_Gauss_zone_22"}, + {21423, "PCS_Beijing_Gauss_zone_23"}, + {21473, "PCS_Beijing_Gauss_13N"}, + {21474, "PCS_Beijing_Gauss_14N"}, + {21475, "PCS_Beijing_Gauss_15N"}, + {21476, "PCS_Beijing_Gauss_16N"}, + {21477, "PCS_Beijing_Gauss_17N"}, + {21478, "PCS_Beijing_Gauss_18N"}, + {21479, "PCS_Beijing_Gauss_19N"}, + {21480, "PCS_Beijing_Gauss_20N"}, + {21481, "PCS_Beijing_Gauss_21N"}, + {21482, "PCS_Beijing_Gauss_22N"}, + {21483, "PCS_Beijing_Gauss_23N"}, + {21500, "PCS_Belge_Lambert_50"}, + {21790, "PCS_Bern_1898_Swiss_Old"}, + {21817, "PCS_Bogota_UTM_zone_17N"}, + {21818, "PCS_Bogota_UTM_zone_18N"}, + {21891, "PCS_Bogota_Colombia_3W"}, + {21892, "PCS_Bogota_Colombia_Bogota"}, + {21893, "PCS_Bogota_Colombia_3E"}, + {21894, "PCS_Bogota_Colombia_6E"}, + {22032, "PCS_Camacupa_UTM_32S"}, + {22033, "PCS_Camacupa_UTM_33S"}, + {22191, "PCS_C_Inchauspe_Argentina_1"}, + {22192, "PCS_C_Inchauspe_Argentina_2"}, + {22193, "PCS_C_Inchauspe_Argentina_3"}, + {22194, "PCS_C_Inchauspe_Argentina_4"}, + {22195, "PCS_C_Inchauspe_Argentina_5"}, + {22196, "PCS_C_Inchauspe_Argentina_6"}, + {22197, "PCS_C_Inchauspe_Argentina_7"}, + {22332, "PCS_Carthage_UTM_zone_32N"}, + {22391, "PCS_Carthage_Nord_Tunisie"}, + {22392, "PCS_Carthage_Sud_Tunisie"}, + {22523, "PCS_Corrego_Alegre_UTM_23S"}, + {22524, "PCS_Corrego_Alegre_UTM_24S"}, + {22832, "PCS_Douala_UTM_zone_32N"}, + {22992, "PCS_Egypt_1907_Red_Belt"}, + {22993, "PCS_Egypt_1907_Purple_Belt"}, + {22994, "PCS_Egypt_1907_Ext_Purple"}, + {23028, "PCS_ED50_UTM_zone_28N"}, + {23029, "PCS_ED50_UTM_zone_29N"}, + {23030, "PCS_ED50_UTM_zone_30N"}, + {23031, "PCS_ED50_UTM_zone_31N"}, + {23032, "PCS_ED50_UTM_zone_32N"}, + {23033, "PCS_ED50_UTM_zone_33N"}, + {23034, "PCS_ED50_UTM_zone_34N"}, + {23035, "PCS_ED50_UTM_zone_35N"}, + {23036, "PCS_ED50_UTM_zone_36N"}, + {23037, "PCS_ED50_UTM_zone_37N"}, + {23038, "PCS_ED50_UTM_zone_38N"}, + {23239, "PCS_Fahud_UTM_zone_39N"}, + {23240, "PCS_Fahud_UTM_zone_40N"}, + {23433, "PCS_Garoua_UTM_zone_33N"}, + {23846, "PCS_ID74_UTM_zone_46N"}, + {23847, "PCS_ID74_UTM_zone_47N"}, + {23848, "PCS_ID74_UTM_zone_48N"}, + {23849, "PCS_ID74_UTM_zone_49N"}, + {23850, "PCS_ID74_UTM_zone_50N"}, + {23851, "PCS_ID74_UTM_zone_51N"}, + {23852, "PCS_ID74_UTM_zone_52N"}, + {23853, "PCS_ID74_UTM_zone_53N"}, + {23886, "PCS_ID74_UTM_zone_46S"}, + {23887, "PCS_ID74_UTM_zone_47S"}, + {23888, "PCS_ID74_UTM_zone_48S"}, + {23889, "PCS_ID74_UTM_zone_49S"}, + {23890, "PCS_ID74_UTM_zone_50S"}, + {23891, "PCS_ID74_UTM_zone_51S"}, + {23892, "PCS_ID74_UTM_zone_52S"}, + {23893, "PCS_ID74_UTM_zone_53S"}, + {23894, "PCS_ID74_UTM_zone_54S"}, + {23947, "PCS_Indian_1954_UTM_47N"}, + {23948, "PCS_Indian_1954_UTM_48N"}, + {24047, "PCS_Indian_1975_UTM_47N"}, + {24048, "PCS_Indian_1975_UTM_48N"}, + {24100, "PCS_Jamaica_1875_Old_Grid"}, + {24200, "PCS_JAD69_Jamaica_Grid"}, + {24370, "PCS_Kalianpur_India_0"}, + {24371, "PCS_Kalianpur_India_I"}, + {24372, "PCS_Kalianpur_India_IIa"}, + {24373, "PCS_Kalianpur_India_IIIa"}, + {24374, "PCS_Kalianpur_India_IVa"}, + {24382, "PCS_Kalianpur_India_IIb"}, + {24383, "PCS_Kalianpur_India_IIIb"}, + {24384, "PCS_Kalianpur_India_IVb"}, + {24500, "PCS_Kertau_Singapore_Grid"}, + {24547, "PCS_Kertau_UTM_zone_47N"}, + {24548, "PCS_Kertau_UTM_zone_48N"}, + {24720, "PCS_La_Canoa_UTM_zone_20N"}, + {24721, "PCS_La_Canoa_UTM_zone_21N"}, + {24818, "PCS_PSAD56_UTM_zone_18N"}, + {24819, "PCS_PSAD56_UTM_zone_19N"}, + {24820, "PCS_PSAD56_UTM_zone_20N"}, + {24821, "PCS_PSAD56_UTM_zone_21N"}, + {24877, "PCS_PSAD56_UTM_zone_17S"}, + {24878, "PCS_PSAD56_UTM_zone_18S"}, + {24879, "PCS_PSAD56_UTM_zone_19S"}, + {24880, "PCS_PSAD56_UTM_zone_20S"}, + {24891, "PCS_PSAD56_Peru_west_zone"}, + {24892, "PCS_PSAD56_Peru_central"}, + {24893, "PCS_PSAD56_Peru_east_zone"}, + {25000, "PCS_Leigon_Ghana_Grid"}, + {25231, "PCS_Lome_UTM_zone_31N"}, + {25391, "PCS_Luzon_Philippines_I"}, + {25392, "PCS_Luzon_Philippines_II"}, + {25393, "PCS_Luzon_Philippines_III"}, + {25394, "PCS_Luzon_Philippines_IV"}, + {25395, "PCS_Luzon_Philippines_V"}, + {25700, "PCS_Makassar_NEIEZ"}, + {25932, "PCS_Malongo_1987_UTM_32S"}, + {26191, "PCS_Merchich_Nord_Maroc"}, + {26192, "PCS_Merchich_Sud_Maroc"}, + {26193, "PCS_Merchich_Sahara"}, + {26237, "PCS_Massawa_UTM_zone_37N"}, + {26331, "PCS_Minna_UTM_zone_31N"}, + {26332, "PCS_Minna_UTM_zone_32N"}, + {26391, "PCS_Minna_Nigeria_West"}, + {26392, "PCS_Minna_Nigeria_Mid_Belt"}, + {26393, "PCS_Minna_Nigeria_East"}, + {26432, "PCS_Mhast_UTM_zone_32S"}, + {26591, "PCS_Monte_Mario_Italy_1"}, + {26592, "PCS_Monte_Mario_Italy_2"}, + {26632, "PCS_M_poraloko_UTM_32N"}, + {26692, "PCS_M_poraloko_UTM_32S"}, + {26703, "PCS_NAD27_UTM_zone_3N"}, + {26704, "PCS_NAD27_UTM_zone_4N"}, + {26705, "PCS_NAD27_UTM_zone_5N"}, + {26706, "PCS_NAD27_UTM_zone_6N"}, + {26707, "PCS_NAD27_UTM_zone_7N"}, + {26708, "PCS_NAD27_UTM_zone_8N"}, + {26709, "PCS_NAD27_UTM_zone_9N"}, + {26710, "PCS_NAD27_UTM_zone_10N"}, + {26711, "PCS_NAD27_UTM_zone_11N"}, + {26712, "PCS_NAD27_UTM_zone_12N"}, + {26713, "PCS_NAD27_UTM_zone_13N"}, + {26714, "PCS_NAD27_UTM_zone_14N"}, + {26715, "PCS_NAD27_UTM_zone_15N"}, + {26716, "PCS_NAD27_UTM_zone_16N"}, + {26717, "PCS_NAD27_UTM_zone_17N"}, + {26718, "PCS_NAD27_UTM_zone_18N"}, + {26719, "PCS_NAD27_UTM_zone_19N"}, + {26720, "PCS_NAD27_UTM_zone_20N"}, + {26721, "PCS_NAD27_UTM_zone_21N"}, + {26722, "PCS_NAD27_UTM_zone_22N"}, + {26729, "PCS_NAD27_Alabama_East"}, + {26730, "PCS_NAD27_Alabama_West"}, + {26731, "PCS_NAD27_Alaska_zone_1"}, + {26732, "PCS_NAD27_Alaska_zone_2"}, + {26733, "PCS_NAD27_Alaska_zone_3"}, + {26734, "PCS_NAD27_Alaska_zone_4"}, + {26735, "PCS_NAD27_Alaska_zone_5"}, + {26736, "PCS_NAD27_Alaska_zone_6"}, + {26737, "PCS_NAD27_Alaska_zone_7"}, + {26738, "PCS_NAD27_Alaska_zone_8"}, + {26739, "PCS_NAD27_Alaska_zone_9"}, + {26740, "PCS_NAD27_Alaska_zone_10"}, + {26741, "PCS_NAD27_California_I"}, + {26742, "PCS_NAD27_California_II"}, + {26743, "PCS_NAD27_California_III"}, + {26744, "PCS_NAD27_California_IV"}, + {26745, "PCS_NAD27_California_V"}, + {26746, "PCS_NAD27_California_VI"}, + {26747, "PCS_NAD27_California_VII"}, + {26748, "PCS_NAD27_Arizona_East"}, + {26749, "PCS_NAD27_Arizona_Central"}, + {26750, "PCS_NAD27_Arizona_West"}, + {26751, "PCS_NAD27_Arkansas_North"}, + {26752, "PCS_NAD27_Arkansas_South"}, + {26753, "PCS_NAD27_Colorado_North"}, + {26754, "PCS_NAD27_Colorado_Central"}, + {26755, "PCS_NAD27_Colorado_South"}, + {26756, "PCS_NAD27_Connecticut"}, + {26757, "PCS_NAD27_Delaware"}, + {26758, "PCS_NAD27_Florida_East"}, + {26759, "PCS_NAD27_Florida_West"}, + {26760, "PCS_NAD27_Florida_North"}, + {26761, "PCS_NAD27_Hawaii_zone_1"}, + {26762, "PCS_NAD27_Hawaii_zone_2"}, + {26763, "PCS_NAD27_Hawaii_zone_3"}, + {26764, "PCS_NAD27_Hawaii_zone_4"}, + {26765, "PCS_NAD27_Hawaii_zone_5"}, + {26766, "PCS_NAD27_Georgia_East"}, + {26767, "PCS_NAD27_Georgia_West"}, + {26768, "PCS_NAD27_Idaho_East"}, + {26769, "PCS_NAD27_Idaho_Central"}, + {26770, "PCS_NAD27_Idaho_West"}, + {26771, "PCS_NAD27_Illinois_East"}, + {26772, "PCS_NAD27_Illinois_West"}, + {26773, "PCS_NAD27_Indiana_East"}, + {26774, "PCS_NAD27_BLM_14N_feet"}, + {26774, "PCS_NAD27_Indiana_West"}, + {26775, "PCS_NAD27_BLM_15N_feet"}, + {26775, "PCS_NAD27_Iowa_North"}, + {26776, "PCS_NAD27_BLM_16N_feet"}, + {26776, "PCS_NAD27_Iowa_South"}, + {26777, "PCS_NAD27_BLM_17N_feet"}, + {26777, "PCS_NAD27_Kansas_North"}, + {26778, "PCS_NAD27_Kansas_South"}, + {26779, "PCS_NAD27_Kentucky_North"}, + {26780, "PCS_NAD27_Kentucky_South"}, + {26781, "PCS_NAD27_Louisiana_North"}, + {26782, "PCS_NAD27_Louisiana_South"}, + {26783, "PCS_NAD27_Maine_East"}, + {26784, "PCS_NAD27_Maine_West"}, + {26785, "PCS_NAD27_Maryland"}, + {26786, "PCS_NAD27_Massachusetts"}, + {26787, "PCS_NAD27_Massachusetts_Is"}, + {26788, "PCS_NAD27_Michigan_North"}, + {26789, "PCS_NAD27_Michigan_Central"}, + {26790, "PCS_NAD27_Michigan_South"}, + {26791, "PCS_NAD27_Minnesota_North"}, + {26792, "PCS_NAD27_Minnesota_Cent"}, + {26793, "PCS_NAD27_Minnesota_South"}, + {26794, "PCS_NAD27_Mississippi_East"}, + {26795, "PCS_NAD27_Mississippi_West"}, + {26796, "PCS_NAD27_Missouri_East"}, + {26797, "PCS_NAD27_Missouri_Central"}, + {26798, "PCS_NAD27_Missouri_West"}, + {26801, "PCS_NAD_Michigan_Michigan_East"}, + {26802, "PCS_NAD_Michigan_Michigan_Old_Central"}, + {26803, "PCS_NAD_Michigan_Michigan_West"}, + {26903, "PCS_NAD83_UTM_zone_3N"}, + {26904, "PCS_NAD83_UTM_zone_4N"}, + {26905, "PCS_NAD83_UTM_zone_5N"}, + {26906, "PCS_NAD83_UTM_zone_6N"}, + {26907, "PCS_NAD83_UTM_zone_7N"}, + {26908, "PCS_NAD83_UTM_zone_8N"}, + {26909, "PCS_NAD83_UTM_zone_9N"}, + {26910, "PCS_NAD83_UTM_zone_10N"}, + {26911, "PCS_NAD83_UTM_zone_11N"}, + {26912, "PCS_NAD83_UTM_zone_12N"}, + {26913, "PCS_NAD83_UTM_zone_13N"}, + {26914, "PCS_NAD83_UTM_zone_14N"}, + {26915, "PCS_NAD83_UTM_zone_15N"}, + {26916, "PCS_NAD83_UTM_zone_16N"}, + {26917, "PCS_NAD83_UTM_zone_17N"}, + {26918, "PCS_NAD83_UTM_zone_18N"}, + {26919, "PCS_NAD83_UTM_zone_19N"}, + {26920, "PCS_NAD83_UTM_zone_20N"}, + {26921, "PCS_NAD83_UTM_zone_21N"}, + {26922, "PCS_NAD83_UTM_zone_22N"}, + {26923, "PCS_NAD83_UTM_zone_23N"}, + {26929, "PCS_NAD83_Alabama_East"}, + {26930, "PCS_NAD83_Alabama_West"}, + {26931, "PCS_NAD83_Alaska_zone_1"}, + {26932, "PCS_NAD83_Alaska_zone_2"}, + {26933, "PCS_NAD83_Alaska_zone_3"}, + {26934, "PCS_NAD83_Alaska_zone_4"}, + {26935, "PCS_NAD83_Alaska_zone_5"}, + {26936, "PCS_NAD83_Alaska_zone_6"}, + {26937, "PCS_NAD83_Alaska_zone_7"}, + {26938, "PCS_NAD83_Alaska_zone_8"}, + {26939, "PCS_NAD83_Alaska_zone_9"}, + {26940, "PCS_NAD83_Alaska_zone_10"}, + {26941, "PCS_NAD83_California_1"}, + {26942, "PCS_NAD83_California_2"}, + {26943, "PCS_NAD83_California_3"}, + {26944, "PCS_NAD83_California_4"}, + {26945, "PCS_NAD83_California_5"}, + {26946, "PCS_NAD83_California_6"}, + {26948, "PCS_NAD83_Arizona_East"}, + {26949, "PCS_NAD83_Arizona_Central"}, + {26950, "PCS_NAD83_Arizona_West"}, + {26951, "PCS_NAD83_Arkansas_North"}, + {26952, "PCS_NAD83_Arkansas_South"}, + {26953, "PCS_NAD83_Colorado_North"}, + {26954, "PCS_NAD83_Colorado_Central"}, + {26955, "PCS_NAD83_Colorado_South"}, + {26956, "PCS_NAD83_Connecticut"}, + {26957, "PCS_NAD83_Delaware"}, + {26958, "PCS_NAD83_Florida_East"}, + {26959, "PCS_NAD83_Florida_West"}, + {26960, "PCS_NAD83_Florida_North"}, + {26961, "PCS_NAD83_Hawaii_zone_1"}, + {26962, "PCS_NAD83_Hawaii_zone_2"}, + {26963, "PCS_NAD83_Hawaii_zone_3"}, + {26964, "PCS_NAD83_Hawaii_zone_4"}, + {26965, "PCS_NAD83_Hawaii_zone_5"}, + {26966, "PCS_NAD83_Georgia_East"}, + {26967, "PCS_NAD83_Georgia_West"}, + {26968, "PCS_NAD83_Idaho_East"}, + {26969, "PCS_NAD83_Idaho_Central"}, + {26970, "PCS_NAD83_Idaho_West"}, + {26971, "PCS_NAD83_Illinois_East"}, + {26972, "PCS_NAD83_Illinois_West"}, + {26973, "PCS_NAD83_Indiana_East"}, + {26974, "PCS_NAD83_Indiana_West"}, + {26975, "PCS_NAD83_Iowa_North"}, + {26976, "PCS_NAD83_Iowa_South"}, + {26977, "PCS_NAD83_Kansas_North"}, + {26978, "PCS_NAD83_Kansas_South"}, + {26979, "PCS_NAD83_Kentucky_North"}, + {26980, "PCS_NAD83_Kentucky_South"}, + {26981, "PCS_NAD83_Louisiana_North"}, + {26982, "PCS_NAD83_Louisiana_South"}, + {26983, "PCS_NAD83_Maine_East"}, + {26984, "PCS_NAD83_Maine_West"}, + {26985, "PCS_NAD83_Maryland"}, + {26986, "PCS_NAD83_Massachusetts"}, + {26987, "PCS_NAD83_Massachusetts_Is"}, + {26988, "PCS_NAD83_Michigan_North"}, + {26989, "PCS_NAD83_Michigan_Central"}, + {26990, "PCS_NAD83_Michigan_South"}, + {26991, "PCS_NAD83_Minnesota_North"}, + {26992, "PCS_NAD83_Minnesota_Cent"}, + {26993, "PCS_NAD83_Minnesota_South"}, + {26994, "PCS_NAD83_Mississippi_East"}, + {26995, "PCS_NAD83_Mississippi_West"}, + {26996, "PCS_NAD83_Missouri_East"}, + {26997, "PCS_NAD83_Missouri_Central"}, + {26998, "PCS_NAD83_Missouri_West"}, + {27038, "PCS_Nahrwan_1967_UTM_38N"}, + {27039, "PCS_Nahrwan_1967_UTM_39N"}, + {27040, "PCS_Nahrwan_1967_UTM_40N"}, + {27120, "PCS_Naparima_UTM_20N"}, + {27200, "PCS_GD49_NZ_Map_Grid"}, + {27291, "PCS_GD49_North_Island_Grid"}, + {27292, "PCS_GD49_South_Island_Grid"}, + {27429, "PCS_Datum_73_UTM_zone_29N"}, + {27500, "PCS_ATF_Nord_de_Guerre"}, + {27581, "PCS_NTF_France_I"}, + {27582, "PCS_NTF_France_II"}, + {27583, "PCS_NTF_France_III"}, + {27591, "PCS_NTF_Nord_France"}, + {27592, "PCS_NTF_Centre_France"}, + {27593, "PCS_NTF_Sud_France"}, + {27700, "PCS_British_National_Grid"}, + {28232, "PCS_Point_Noire_UTM_32S"}, + {28348, "PCS_GDA94_MGA_zone_48"}, + {28349, "PCS_GDA94_MGA_zone_49"}, + {28350, "PCS_GDA94_MGA_zone_50"}, + {28351, "PCS_GDA94_MGA_zone_51"}, + {28352, "PCS_GDA94_MGA_zone_52"}, + {28353, "PCS_GDA94_MGA_zone_53"}, + {28354, "PCS_GDA94_MGA_zone_54"}, + {28355, "PCS_GDA94_MGA_zone_55"}, + {28356, "PCS_GDA94_MGA_zone_56"}, + {28357, "PCS_GDA94_MGA_zone_57"}, + {28358, "PCS_GDA94_MGA_zone_58"}, + {28404, "PCS_Pulkovo_Gauss_zone_4"}, + {28405, "PCS_Pulkovo_Gauss_zone_5"}, + {28406, "PCS_Pulkovo_Gauss_zone_6"}, + {28407, "PCS_Pulkovo_Gauss_zone_7"}, + {28408, "PCS_Pulkovo_Gauss_zone_8"}, + {28409, "PCS_Pulkovo_Gauss_zone_9"}, + {28410, "PCS_Pulkovo_Gauss_zone_10"}, + {28411, "PCS_Pulkovo_Gauss_zone_11"}, + {28412, "PCS_Pulkovo_Gauss_zone_12"}, + {28413, "PCS_Pulkovo_Gauss_zone_13"}, + {28414, "PCS_Pulkovo_Gauss_zone_14"}, + {28415, "PCS_Pulkovo_Gauss_zone_15"}, + {28416, "PCS_Pulkovo_Gauss_zone_16"}, + {28417, "PCS_Pulkovo_Gauss_zone_17"}, + {28418, "PCS_Pulkovo_Gauss_zone_18"}, + {28419, "PCS_Pulkovo_Gauss_zone_19"}, + {28420, "PCS_Pulkovo_Gauss_zone_20"}, + {28421, "PCS_Pulkovo_Gauss_zone_21"}, + {28422, "PCS_Pulkovo_Gauss_zone_22"}, + {28423, "PCS_Pulkovo_Gauss_zone_23"}, + {28424, "PCS_Pulkovo_Gauss_zone_24"}, + {28425, "PCS_Pulkovo_Gauss_zone_25"}, + {28426, "PCS_Pulkovo_Gauss_zone_26"}, + {28427, "PCS_Pulkovo_Gauss_zone_27"}, + {28428, "PCS_Pulkovo_Gauss_zone_28"}, + {28429, "PCS_Pulkovo_Gauss_zone_29"}, + {28430, "PCS_Pulkovo_Gauss_zone_30"}, + {28431, "PCS_Pulkovo_Gauss_zone_31"}, + {28432, "PCS_Pulkovo_Gauss_zone_32"}, + {28464, "PCS_Pulkovo_Gauss_4N"}, + {28465, "PCS_Pulkovo_Gauss_5N"}, + {28466, "PCS_Pulkovo_Gauss_6N"}, + {28467, "PCS_Pulkovo_Gauss_7N"}, + {28468, "PCS_Pulkovo_Gauss_8N"}, + {28469, "PCS_Pulkovo_Gauss_9N"}, + {28470, "PCS_Pulkovo_Gauss_10N"}, + {28471, "PCS_Pulkovo_Gauss_11N"}, + {28472, "PCS_Pulkovo_Gauss_12N"}, + {28473, "PCS_Pulkovo_Gauss_13N"}, + {28474, "PCS_Pulkovo_Gauss_14N"}, + {28475, "PCS_Pulkovo_Gauss_15N"}, + {28476, "PCS_Pulkovo_Gauss_16N"}, + {28477, "PCS_Pulkovo_Gauss_17N"}, + {28478, "PCS_Pulkovo_Gauss_18N"}, + {28479, "PCS_Pulkovo_Gauss_19N"}, + {28480, "PCS_Pulkovo_Gauss_20N"}, + {28481, "PCS_Pulkovo_Gauss_21N"}, + {28482, "PCS_Pulkovo_Gauss_22N"}, + {28483, "PCS_Pulkovo_Gauss_23N"}, + {28484, "PCS_Pulkovo_Gauss_24N"}, + {28485, "PCS_Pulkovo_Gauss_25N"}, + {28486, "PCS_Pulkovo_Gauss_26N"}, + {28487, "PCS_Pulkovo_Gauss_27N"}, + {28488, "PCS_Pulkovo_Gauss_28N"}, + {28489, "PCS_Pulkovo_Gauss_29N"}, + {28490, "PCS_Pulkovo_Gauss_30N"}, + {28491, "PCS_Pulkovo_Gauss_31N"}, + {28492, "PCS_Pulkovo_Gauss_32N"}, + {28600, "PCS_Qatar_National_Grid"}, + {28991, "PCS_RD_Netherlands_Old"}, + {28992, "PCS_RD_Netherlands_New"}, + {29118, "PCS_SAD69_UTM_zone_18N"}, + {29119, "PCS_SAD69_UTM_zone_19N"}, + {29120, "PCS_SAD69_UTM_zone_20N"}, + {29121, "PCS_SAD69_UTM_zone_21N"}, + {29122, "PCS_SAD69_UTM_zone_22N"}, + {29177, "PCS_SAD69_UTM_zone_17S"}, + {29178, "PCS_SAD69_UTM_zone_18S"}, + {29179, "PCS_SAD69_UTM_zone_19S"}, + {29180, "PCS_SAD69_UTM_zone_20S"}, + {29181, "PCS_SAD69_UTM_zone_21S"}, + {29182, "PCS_SAD69_UTM_zone_22S"}, + {29183, "PCS_SAD69_UTM_zone_23S"}, + {29184, "PCS_SAD69_UTM_zone_24S"}, + {29185, "PCS_SAD69_UTM_zone_25S"}, + {29220, "PCS_Sapper_Hill_UTM_20S"}, + {29221, "PCS_Sapper_Hill_UTM_21S"}, + {29333, "PCS_Schwarzeck_UTM_33S"}, + {29635, "PCS_Sudan_UTM_zone_35N"}, + {29636, "PCS_Sudan_UTM_zone_36N"}, + {29700, "PCS_Tananarive_Laborde"}, + {29738, "PCS_Tananarive_UTM_38S"}, + {29739, "PCS_Tananarive_UTM_39S"}, + {29800, "PCS_Timbalai_1948_Borneo"}, + {29849, "PCS_Timbalai_1948_UTM_49N"}, + {29850, "PCS_Timbalai_1948_UTM_50N"}, + {29900, "PCS_TM65_Irish_Nat_Grid"}, + {30200, "PCS_Trinidad_1903_Trinidad"}, + {30339, "PCS_TC_1948_UTM_zone_39N"}, + {30340, "PCS_TC_1948_UTM_zone_40N"}, + {30491, "PCS_Voirol_N_Algerie_ancien"}, + {30492, "PCS_Voirol_S_Algerie_ancien"}, + {30591, "PCS_Voirol_Unifie_N_Algerie"}, + {30592, "PCS_Voirol_Unifie_S_Algerie"}, + {30600, "PCS_Bern_1938_Swiss_New"}, + {30729, "PCS_Nord_Sahara_UTM_29N"}, + {30730, "PCS_Nord_Sahara_UTM_30N"}, + {30731, "PCS_Nord_Sahara_UTM_31N"}, + {30732, "PCS_Nord_Sahara_UTM_32N"}, + {31028, "PCS_Yoff_UTM_zone_28N"}, + {31121, "PCS_Zanderij_UTM_zone_21N"}, + {31291, "PCS_MGI_Austria_West"}, + {31292, "PCS_MGI_Austria_Central"}, + {31293, "PCS_MGI_Austria_East"}, + {31300, "PCS_Belge_Lambert_72"}, + {31491, "PCS_DHDN_Germany_zone_1"}, + {31492, "PCS_DHDN_Germany_zone_2"}, + {31493, "PCS_DHDN_Germany_zone_3"}, + {31494, "PCS_DHDN_Germany_zone_4"}, + {31495, "PCS_DHDN_Germany_zone_5"}, + {32001, "PCS_NAD27_Montana_North"}, + {32002, "PCS_NAD27_Montana_Central"}, + {32003, "PCS_NAD27_Montana_South"}, + {32005, "PCS_NAD27_Nebraska_North"}, + {32006, "PCS_NAD27_Nebraska_South"}, + {32007, "PCS_NAD27_Nevada_East"}, + {32008, "PCS_NAD27_Nevada_Central"}, + {32009, "PCS_NAD27_Nevada_West"}, + {32010, "PCS_NAD27_New_Hampshire"}, + {32011, "PCS_NAD27_New_Jersey"}, + {32012, "PCS_NAD27_New_Mexico_East"}, + {32013, "PCS_NAD27_New_Mexico_Cent"}, + {32014, "PCS_NAD27_New_Mexico_West"}, + {32015, "PCS_NAD27_New_York_East"}, + {32016, "PCS_NAD27_New_York_Central"}, + {32017, "PCS_NAD27_New_York_West"}, + {32018, "PCS_NAD27_New_York_Long_Is"}, + {32019, "PCS_NAD27_North_Carolina"}, + {32020, "PCS_NAD27_North_Dakota_N"}, + {32021, "PCS_NAD27_North_Dakota_S"}, + {32022, "PCS_NAD27_Ohio_North"}, + {32023, "PCS_NAD27_Ohio_South"}, + {32024, "PCS_NAD27_Oklahoma_North"}, + {32025, "PCS_NAD27_Oklahoma_South"}, + {32026, "PCS_NAD27_Oregon_North"}, + {32027, "PCS_NAD27_Oregon_South"}, + {32028, "PCS_NAD27_Pennsylvania_N"}, + {32029, "PCS_NAD27_Pennsylvania_S"}, + {32030, "PCS_NAD27_Rhode_Island"}, + {32031, "PCS_NAD27_South_Carolina_N"}, + {32033, "PCS_NAD27_South_Carolina_S"}, + {32034, "PCS_NAD27_South_Dakota_N"}, + {32035, "PCS_NAD27_South_Dakota_S"}, + {32036, "PCS_NAD27_Tennessee"}, + {32037, "PCS_NAD27_Texas_North"}, + {32038, "PCS_NAD27_Texas_North_Cen"}, + {32039, "PCS_NAD27_Texas_Central"}, + {32040, "PCS_NAD27_Texas_South_Cen"}, + {32041, "PCS_NAD27_Texas_South"}, + {32042, "PCS_NAD27_Utah_North"}, + {32043, "PCS_NAD27_Utah_Central"}, + {32044, "PCS_NAD27_Utah_South"}, + {32045, "PCS_NAD27_Vermont"}, + {32046, "PCS_NAD27_Virginia_North"}, + {32047, "PCS_NAD27_Virginia_South"}, + {32048, "PCS_NAD27_Washington_North"}, + {32049, "PCS_NAD27_Washington_South"}, + {32050, "PCS_NAD27_West_Virginia_N"}, + {32051, "PCS_NAD27_West_Virginia_S"}, + {32052, "PCS_NAD27_Wisconsin_North"}, + {32053, "PCS_NAD27_Wisconsin_Cen"}, + {32054, "PCS_NAD27_Wisconsin_South"}, + {32055, "PCS_NAD27_Wyoming_East"}, + {32056, "PCS_NAD27_Wyoming_E_Cen"}, + {32057, "PCS_NAD27_Wyoming_W_Cen"}, + {32058, "PCS_NAD27_Wyoming_West"}, + {32059, "PCS_NAD27_Puerto_Rico"}, + {32060, "PCS_NAD27_St_Croix"}, + {32100, "PCS_NAD83_Montana"}, + {32104, "PCS_NAD83_Nebraska"}, + {32107, "PCS_NAD83_Nevada_East"}, + {32108, "PCS_NAD83_Nevada_Central"}, + {32109, "PCS_NAD83_Nevada_West"}, + {32110, "PCS_NAD83_New_Hampshire"}, + {32111, "PCS_NAD83_New_Jersey"}, + {32112, "PCS_NAD83_New_Mexico_East"}, + {32113, "PCS_NAD83_New_Mexico_Cent"}, + {32114, "PCS_NAD83_New_Mexico_West"}, + {32115, "PCS_NAD83_New_York_East"}, + {32116, "PCS_NAD83_New_York_Central"}, + {32117, "PCS_NAD83_New_York_West"}, + {32118, "PCS_NAD83_New_York_Long_Is"}, + {32119, "PCS_NAD83_North_Carolina"}, + {32120, "PCS_NAD83_North_Dakota_N"}, + {32121, "PCS_NAD83_North_Dakota_S"}, + {32122, "PCS_NAD83_Ohio_North"}, + {32123, "PCS_NAD83_Ohio_South"}, + {32124, "PCS_NAD83_Oklahoma_North"}, + {32125, "PCS_NAD83_Oklahoma_South"}, + {32126, "PCS_NAD83_Oregon_North"}, + {32127, "PCS_NAD83_Oregon_South"}, + {32128, "PCS_NAD83_Pennsylvania_N"}, + {32129, "PCS_NAD83_Pennsylvania_S"}, + {32130, "PCS_NAD83_Rhode_Island"}, + {32133, "PCS_NAD83_South_Carolina"}, + {32134, "PCS_NAD83_South_Dakota_N"}, + {32135, "PCS_NAD83_South_Dakota_S"}, + {32136, "PCS_NAD83_Tennessee"}, + {32137, "PCS_NAD83_Texas_North"}, + {32138, "PCS_NAD83_Texas_North_Cen"}, + {32139, "PCS_NAD83_Texas_Central"}, + {32140, "PCS_NAD83_Texas_South_Cen"}, + {32141, "PCS_NAD83_Texas_South"}, + {32142, "PCS_NAD83_Utah_North"}, + {32143, "PCS_NAD83_Utah_Central"}, + {32144, "PCS_NAD83_Utah_South"}, + {32145, "PCS_NAD83_Vermont"}, + {32146, "PCS_NAD83_Virginia_North"}, + {32147, "PCS_NAD83_Virginia_South"}, + {32148, "PCS_NAD83_Washington_North"}, + {32149, "PCS_NAD83_Washington_South"}, + {32150, "PCS_NAD83_West_Virginia_N"}, + {32151, "PCS_NAD83_West_Virginia_S"}, + {32152, "PCS_NAD83_Wisconsin_North"}, + {32153, "PCS_NAD83_Wisconsin_Cen"}, + {32154, "PCS_NAD83_Wisconsin_South"}, + {32155, "PCS_NAD83_Wyoming_East"}, + {32156, "PCS_NAD83_Wyoming_E_Cen"}, + {32157, "PCS_NAD83_Wyoming_W_Cen"}, + {32158, "PCS_NAD83_Wyoming_West"}, + {32161, "PCS_NAD83_Puerto_Rico_Virgin_Is"}, + {32201, "PCS_WGS72_UTM_zone_1N"}, + {32202, "PCS_WGS72_UTM_zone_2N"}, + {32203, "PCS_WGS72_UTM_zone_3N"}, + {32204, "PCS_WGS72_UTM_zone_4N"}, + {32205, "PCS_WGS72_UTM_zone_5N"}, + {32206, "PCS_WGS72_UTM_zone_6N"}, + {32207, "PCS_WGS72_UTM_zone_7N"}, + {32208, "PCS_WGS72_UTM_zone_8N"}, + {32209, "PCS_WGS72_UTM_zone_9N"}, + {32210, "PCS_WGS72_UTM_zone_10N"}, + {32211, "PCS_WGS72_UTM_zone_11N"}, + {32212, "PCS_WGS72_UTM_zone_12N"}, + {32213, "PCS_WGS72_UTM_zone_13N"}, + {32214, "PCS_WGS72_UTM_zone_14N"}, + {32215, "PCS_WGS72_UTM_zone_15N"}, + {32216, "PCS_WGS72_UTM_zone_16N"}, + {32217, "PCS_WGS72_UTM_zone_17N"}, + {32218, "PCS_WGS72_UTM_zone_18N"}, + {32219, "PCS_WGS72_UTM_zone_19N"}, + {32220, "PCS_WGS72_UTM_zone_20N"}, + {32221, "PCS_WGS72_UTM_zone_21N"}, + {32222, "PCS_WGS72_UTM_zone_22N"}, + {32223, "PCS_WGS72_UTM_zone_23N"}, + {32224, "PCS_WGS72_UTM_zone_24N"}, + {32225, "PCS_WGS72_UTM_zone_25N"}, + {32226, "PCS_WGS72_UTM_zone_26N"}, + {32227, "PCS_WGS72_UTM_zone_27N"}, + {32228, "PCS_WGS72_UTM_zone_28N"}, + {32229, "PCS_WGS72_UTM_zone_29N"}, + {32230, "PCS_WGS72_UTM_zone_30N"}, + {32231, "PCS_WGS72_UTM_zone_31N"}, + {32232, "PCS_WGS72_UTM_zone_32N"}, + {32233, "PCS_WGS72_UTM_zone_33N"}, + {32234, "PCS_WGS72_UTM_zone_34N"}, + {32235, "PCS_WGS72_UTM_zone_35N"}, + {32236, "PCS_WGS72_UTM_zone_36N"}, + {32237, "PCS_WGS72_UTM_zone_37N"}, + {32238, "PCS_WGS72_UTM_zone_38N"}, + {32239, "PCS_WGS72_UTM_zone_39N"}, + {32240, "PCS_WGS72_UTM_zone_40N"}, + {32241, "PCS_WGS72_UTM_zone_41N"}, + {32242, "PCS_WGS72_UTM_zone_42N"}, + {32243, "PCS_WGS72_UTM_zone_43N"}, + {32244, "PCS_WGS72_UTM_zone_44N"}, + {32245, "PCS_WGS72_UTM_zone_45N"}, + {32246, "PCS_WGS72_UTM_zone_46N"}, + {32247, "PCS_WGS72_UTM_zone_47N"}, + {32248, "PCS_WGS72_UTM_zone_48N"}, + {32249, "PCS_WGS72_UTM_zone_49N"}, + {32250, "PCS_WGS72_UTM_zone_50N"}, + {32251, "PCS_WGS72_UTM_zone_51N"}, + {32252, "PCS_WGS72_UTM_zone_52N"}, + {32253, "PCS_WGS72_UTM_zone_53N"}, + {32254, "PCS_WGS72_UTM_zone_54N"}, + {32255, "PCS_WGS72_UTM_zone_55N"}, + {32256, "PCS_WGS72_UTM_zone_56N"}, + {32257, "PCS_WGS72_UTM_zone_57N"}, + {32258, "PCS_WGS72_UTM_zone_58N"}, + {32259, "PCS_WGS72_UTM_zone_59N"}, + {32260, "PCS_WGS72_UTM_zone_60N"}, + {32301, "PCS_WGS72_UTM_zone_1S"}, + {32302, "PCS_WGS72_UTM_zone_2S"}, + {32303, "PCS_WGS72_UTM_zone_3S"}, + {32304, "PCS_WGS72_UTM_zone_4S"}, + {32305, "PCS_WGS72_UTM_zone_5S"}, + {32306, "PCS_WGS72_UTM_zone_6S"}, + {32307, "PCS_WGS72_UTM_zone_7S"}, + {32308, "PCS_WGS72_UTM_zone_8S"}, + {32309, "PCS_WGS72_UTM_zone_9S"}, + {32310, "PCS_WGS72_UTM_zone_10S"}, + {32311, "PCS_WGS72_UTM_zone_11S"}, + {32312, "PCS_WGS72_UTM_zone_12S"}, + {32313, "PCS_WGS72_UTM_zone_13S"}, + {32314, "PCS_WGS72_UTM_zone_14S"}, + {32315, "PCS_WGS72_UTM_zone_15S"}, + {32316, "PCS_WGS72_UTM_zone_16S"}, + {32317, "PCS_WGS72_UTM_zone_17S"}, + {32318, "PCS_WGS72_UTM_zone_18S"}, + {32319, "PCS_WGS72_UTM_zone_19S"}, + {32320, "PCS_WGS72_UTM_zone_20S"}, + {32321, "PCS_WGS72_UTM_zone_21S"}, + {32322, "PCS_WGS72_UTM_zone_22S"}, + {32323, "PCS_WGS72_UTM_zone_23S"}, + {32324, "PCS_WGS72_UTM_zone_24S"}, + {32325, "PCS_WGS72_UTM_zone_25S"}, + {32326, "PCS_WGS72_UTM_zone_26S"}, + {32327, "PCS_WGS72_UTM_zone_27S"}, + {32328, "PCS_WGS72_UTM_zone_28S"}, + {32329, "PCS_WGS72_UTM_zone_29S"}, + {32330, "PCS_WGS72_UTM_zone_30S"}, + {32331, "PCS_WGS72_UTM_zone_31S"}, + {32332, "PCS_WGS72_UTM_zone_32S"}, + {32333, "PCS_WGS72_UTM_zone_33S"}, + {32334, "PCS_WGS72_UTM_zone_34S"}, + {32335, "PCS_WGS72_UTM_zone_35S"}, + {32336, "PCS_WGS72_UTM_zone_36S"}, + {32337, "PCS_WGS72_UTM_zone_37S"}, + {32338, "PCS_WGS72_UTM_zone_38S"}, + {32339, "PCS_WGS72_UTM_zone_39S"}, + {32340, "PCS_WGS72_UTM_zone_40S"}, + {32341, "PCS_WGS72_UTM_zone_41S"}, + {32342, "PCS_WGS72_UTM_zone_42S"}, + {32343, "PCS_WGS72_UTM_zone_43S"}, + {32344, "PCS_WGS72_UTM_zone_44S"}, + {32345, "PCS_WGS72_UTM_zone_45S"}, + {32346, "PCS_WGS72_UTM_zone_46S"}, + {32347, "PCS_WGS72_UTM_zone_47S"}, + {32348, "PCS_WGS72_UTM_zone_48S"}, + {32349, "PCS_WGS72_UTM_zone_49S"}, + {32350, "PCS_WGS72_UTM_zone_50S"}, + {32351, "PCS_WGS72_UTM_zone_51S"}, + {32352, "PCS_WGS72_UTM_zone_52S"}, + {32353, "PCS_WGS72_UTM_zone_53S"}, + {32354, "PCS_WGS72_UTM_zone_54S"}, + {32355, "PCS_WGS72_UTM_zone_55S"}, + {32356, "PCS_WGS72_UTM_zone_56S"}, + {32357, "PCS_WGS72_UTM_zone_57S"}, + {32358, "PCS_WGS72_UTM_zone_58S"}, + {32359, "PCS_WGS72_UTM_zone_59S"}, + {32360, "PCS_WGS72_UTM_zone_60S"}, + {32401, "PCS_WGS72BE_UTM_zone_1N"}, + {32402, "PCS_WGS72BE_UTM_zone_2N"}, + {32403, "PCS_WGS72BE_UTM_zone_3N"}, + {32404, "PCS_WGS72BE_UTM_zone_4N"}, + {32405, "PCS_WGS72BE_UTM_zone_5N"}, + {32406, "PCS_WGS72BE_UTM_zone_6N"}, + {32407, "PCS_WGS72BE_UTM_zone_7N"}, + {32408, "PCS_WGS72BE_UTM_zone_8N"}, + {32409, "PCS_WGS72BE_UTM_zone_9N"}, + {32410, "PCS_WGS72BE_UTM_zone_10N"}, + {32411, "PCS_WGS72BE_UTM_zone_11N"}, + {32412, "PCS_WGS72BE_UTM_zone_12N"}, + {32413, "PCS_WGS72BE_UTM_zone_13N"}, + {32414, "PCS_WGS72BE_UTM_zone_14N"}, + {32415, "PCS_WGS72BE_UTM_zone_15N"}, + {32416, "PCS_WGS72BE_UTM_zone_16N"}, + {32417, "PCS_WGS72BE_UTM_zone_17N"}, + {32418, "PCS_WGS72BE_UTM_zone_18N"}, + {32419, "PCS_WGS72BE_UTM_zone_19N"}, + {32420, "PCS_WGS72BE_UTM_zone_20N"}, + {32421, "PCS_WGS72BE_UTM_zone_21N"}, + {32422, "PCS_WGS72BE_UTM_zone_22N"}, + {32423, "PCS_WGS72BE_UTM_zone_23N"}, + {32424, "PCS_WGS72BE_UTM_zone_24N"}, + {32425, "PCS_WGS72BE_UTM_zone_25N"}, + {32426, "PCS_WGS72BE_UTM_zone_26N"}, + {32427, "PCS_WGS72BE_UTM_zone_27N"}, + {32428, "PCS_WGS72BE_UTM_zone_28N"}, + {32429, "PCS_WGS72BE_UTM_zone_29N"}, + {32430, "PCS_WGS72BE_UTM_zone_30N"}, + {32431, "PCS_WGS72BE_UTM_zone_31N"}, + {32432, "PCS_WGS72BE_UTM_zone_32N"}, + {32433, "PCS_WGS72BE_UTM_zone_33N"}, + {32434, "PCS_WGS72BE_UTM_zone_34N"}, + {32435, "PCS_WGS72BE_UTM_zone_35N"}, + {32436, "PCS_WGS72BE_UTM_zone_36N"}, + {32437, "PCS_WGS72BE_UTM_zone_37N"}, + {32438, "PCS_WGS72BE_UTM_zone_38N"}, + {32439, "PCS_WGS72BE_UTM_zone_39N"}, + {32440, "PCS_WGS72BE_UTM_zone_40N"}, + {32441, "PCS_WGS72BE_UTM_zone_41N"}, + {32442, "PCS_WGS72BE_UTM_zone_42N"}, + {32443, "PCS_WGS72BE_UTM_zone_43N"}, + {32444, "PCS_WGS72BE_UTM_zone_44N"}, + {32445, "PCS_WGS72BE_UTM_zone_45N"}, + {32446, "PCS_WGS72BE_UTM_zone_46N"}, + {32447, "PCS_WGS72BE_UTM_zone_47N"}, + {32448, "PCS_WGS72BE_UTM_zone_48N"}, + {32449, "PCS_WGS72BE_UTM_zone_49N"}, + {32450, "PCS_WGS72BE_UTM_zone_50N"}, + {32451, "PCS_WGS72BE_UTM_zone_51N"}, + {32452, "PCS_WGS72BE_UTM_zone_52N"}, + {32453, "PCS_WGS72BE_UTM_zone_53N"}, + {32454, "PCS_WGS72BE_UTM_zone_54N"}, + {32455, "PCS_WGS72BE_UTM_zone_55N"}, + {32456, "PCS_WGS72BE_UTM_zone_56N"}, + {32457, "PCS_WGS72BE_UTM_zone_57N"}, + {32458, "PCS_WGS72BE_UTM_zone_58N"}, + {32459, "PCS_WGS72BE_UTM_zone_59N"}, + {32460, "PCS_WGS72BE_UTM_zone_60N"}, + {32501, "PCS_WGS72BE_UTM_zone_1S"}, + {32502, "PCS_WGS72BE_UTM_zone_2S"}, + {32503, "PCS_WGS72BE_UTM_zone_3S"}, + {32504, "PCS_WGS72BE_UTM_zone_4S"}, + {32505, "PCS_WGS72BE_UTM_zone_5S"}, + {32506, "PCS_WGS72BE_UTM_zone_6S"}, + {32507, "PCS_WGS72BE_UTM_zone_7S"}, + {32508, "PCS_WGS72BE_UTM_zone_8S"}, + {32509, "PCS_WGS72BE_UTM_zone_9S"}, + {32510, "PCS_WGS72BE_UTM_zone_10S"}, + {32511, "PCS_WGS72BE_UTM_zone_11S"}, + {32512, "PCS_WGS72BE_UTM_zone_12S"}, + {32513, "PCS_WGS72BE_UTM_zone_13S"}, + {32514, "PCS_WGS72BE_UTM_zone_14S"}, + {32515, "PCS_WGS72BE_UTM_zone_15S"}, + {32516, "PCS_WGS72BE_UTM_zone_16S"}, + {32517, "PCS_WGS72BE_UTM_zone_17S"}, + {32518, "PCS_WGS72BE_UTM_zone_18S"}, + {32519, "PCS_WGS72BE_UTM_zone_19S"}, + {32520, "PCS_WGS72BE_UTM_zone_20S"}, + {32521, "PCS_WGS72BE_UTM_zone_21S"}, + {32522, "PCS_WGS72BE_UTM_zone_22S"}, + {32523, "PCS_WGS72BE_UTM_zone_23S"}, + {32524, "PCS_WGS72BE_UTM_zone_24S"}, + {32525, "PCS_WGS72BE_UTM_zone_25S"}, + {32526, "PCS_WGS72BE_UTM_zone_26S"}, + {32527, "PCS_WGS72BE_UTM_zone_27S"}, + {32528, "PCS_WGS72BE_UTM_zone_28S"}, + {32529, "PCS_WGS72BE_UTM_zone_29S"}, + {32530, "PCS_WGS72BE_UTM_zone_30S"}, + {32531, "PCS_WGS72BE_UTM_zone_31S"}, + {32532, "PCS_WGS72BE_UTM_zone_32S"}, + {32533, "PCS_WGS72BE_UTM_zone_33S"}, + {32534, "PCS_WGS72BE_UTM_zone_34S"}, + {32535, "PCS_WGS72BE_UTM_zone_35S"}, + {32536, "PCS_WGS72BE_UTM_zone_36S"}, + {32537, "PCS_WGS72BE_UTM_zone_37S"}, + {32538, "PCS_WGS72BE_UTM_zone_38S"}, + {32539, "PCS_WGS72BE_UTM_zone_39S"}, + {32540, "PCS_WGS72BE_UTM_zone_40S"}, + {32541, "PCS_WGS72BE_UTM_zone_41S"}, + {32542, "PCS_WGS72BE_UTM_zone_42S"}, + {32543, "PCS_WGS72BE_UTM_zone_43S"}, + {32544, "PCS_WGS72BE_UTM_zone_44S"}, + {32545, "PCS_WGS72BE_UTM_zone_45S"}, + {32546, "PCS_WGS72BE_UTM_zone_46S"}, + {32547, "PCS_WGS72BE_UTM_zone_47S"}, + {32548, "PCS_WGS72BE_UTM_zone_48S"}, + {32549, "PCS_WGS72BE_UTM_zone_49S"}, + {32550, "PCS_WGS72BE_UTM_zone_50S"}, + {32551, "PCS_WGS72BE_UTM_zone_51S"}, + {32552, "PCS_WGS72BE_UTM_zone_52S"}, + {32553, "PCS_WGS72BE_UTM_zone_53S"}, + {32554, "PCS_WGS72BE_UTM_zone_54S"}, + {32555, "PCS_WGS72BE_UTM_zone_55S"}, + {32556, "PCS_WGS72BE_UTM_zone_56S"}, + {32557, "PCS_WGS72BE_UTM_zone_57S"}, + {32558, "PCS_WGS72BE_UTM_zone_58S"}, + {32559, "PCS_WGS72BE_UTM_zone_59S"}, + {32560, "PCS_WGS72BE_UTM_zone_60S"}, + {32601, "PCS_WGS84_UTM_zone_1N"}, + {32602, "PCS_WGS84_UTM_zone_2N"}, + {32603, "PCS_WGS84_UTM_zone_3N"}, + {32604, "PCS_WGS84_UTM_zone_4N"}, + {32605, "PCS_WGS84_UTM_zone_5N"}, + {32606, "PCS_WGS84_UTM_zone_6N"}, + {32607, "PCS_WGS84_UTM_zone_7N"}, + {32608, "PCS_WGS84_UTM_zone_8N"}, + {32609, "PCS_WGS84_UTM_zone_9N"}, + {32610, "PCS_WGS84_UTM_zone_10N"}, + {32611, "PCS_WGS84_UTM_zone_11N"}, + {32612, "PCS_WGS84_UTM_zone_12N"}, + {32613, "PCS_WGS84_UTM_zone_13N"}, + {32614, "PCS_WGS84_UTM_zone_14N"}, + {32615, "PCS_WGS84_UTM_zone_15N"}, + {32616, "PCS_WGS84_UTM_zone_16N"}, + {32617, "PCS_WGS84_UTM_zone_17N"}, + {32618, "PCS_WGS84_UTM_zone_18N"}, + {32619, "PCS_WGS84_UTM_zone_19N"}, + {32620, "PCS_WGS84_UTM_zone_20N"}, + {32621, "PCS_WGS84_UTM_zone_21N"}, + {32622, "PCS_WGS84_UTM_zone_22N"}, + {32623, "PCS_WGS84_UTM_zone_23N"}, + {32624, "PCS_WGS84_UTM_zone_24N"}, + {32625, "PCS_WGS84_UTM_zone_25N"}, + {32626, "PCS_WGS84_UTM_zone_26N"}, + {32627, "PCS_WGS84_UTM_zone_27N"}, + {32628, "PCS_WGS84_UTM_zone_28N"}, + {32629, "PCS_WGS84_UTM_zone_29N"}, + {32630, "PCS_WGS84_UTM_zone_30N"}, + {32631, "PCS_WGS84_UTM_zone_31N"}, + {32632, "PCS_WGS84_UTM_zone_32N"}, + {32633, "PCS_WGS84_UTM_zone_33N"}, + {32634, "PCS_WGS84_UTM_zone_34N"}, + {32635, "PCS_WGS84_UTM_zone_35N"}, + {32636, "PCS_WGS84_UTM_zone_36N"}, + {32637, "PCS_WGS84_UTM_zone_37N"}, + {32638, "PCS_WGS84_UTM_zone_38N"}, + {32639, "PCS_WGS84_UTM_zone_39N"}, + {32640, "PCS_WGS84_UTM_zone_40N"}, + {32641, "PCS_WGS84_UTM_zone_41N"}, + {32642, "PCS_WGS84_UTM_zone_42N"}, + {32643, "PCS_WGS84_UTM_zone_43N"}, + {32644, "PCS_WGS84_UTM_zone_44N"}, + {32645, "PCS_WGS84_UTM_zone_45N"}, + {32646, "PCS_WGS84_UTM_zone_46N"}, + {32647, "PCS_WGS84_UTM_zone_47N"}, + {32648, "PCS_WGS84_UTM_zone_48N"}, + {32649, "PCS_WGS84_UTM_zone_49N"}, + {32650, "PCS_WGS84_UTM_zone_50N"}, + {32651, "PCS_WGS84_UTM_zone_51N"}, + {32652, "PCS_WGS84_UTM_zone_52N"}, + {32653, "PCS_WGS84_UTM_zone_53N"}, + {32654, "PCS_WGS84_UTM_zone_54N"}, + {32655, "PCS_WGS84_UTM_zone_55N"}, + {32656, "PCS_WGS84_UTM_zone_56N"}, + {32657, "PCS_WGS84_UTM_zone_57N"}, + {32658, "PCS_WGS84_UTM_zone_58N"}, + {32659, "PCS_WGS84_UTM_zone_59N"}, + {32660, "PCS_WGS84_UTM_zone_60N"}, + {32701, "PCS_WGS84_UTM_zone_1S"}, + {32702, "PCS_WGS84_UTM_zone_2S"}, + {32703, "PCS_WGS84_UTM_zone_3S"}, + {32704, "PCS_WGS84_UTM_zone_4S"}, + {32705, "PCS_WGS84_UTM_zone_5S"}, + {32706, "PCS_WGS84_UTM_zone_6S"}, + {32707, "PCS_WGS84_UTM_zone_7S"}, + {32708, "PCS_WGS84_UTM_zone_8S"}, + {32709, "PCS_WGS84_UTM_zone_9S"}, + {32710, "PCS_WGS84_UTM_zone_10S"}, + {32711, "PCS_WGS84_UTM_zone_11S"}, + {32712, "PCS_WGS84_UTM_zone_12S"}, + {32713, "PCS_WGS84_UTM_zone_13S"}, + {32714, "PCS_WGS84_UTM_zone_14S"}, + {32715, "PCS_WGS84_UTM_zone_15S"}, + {32716, "PCS_WGS84_UTM_zone_16S"}, + {32717, "PCS_WGS84_UTM_zone_17S"}, + {32718, "PCS_WGS84_UTM_zone_18S"}, + {32719, "PCS_WGS84_UTM_zone_19S"}, + {32720, "PCS_WGS84_UTM_zone_20S"}, + {32721, "PCS_WGS84_UTM_zone_21S"}, + {32722, "PCS_WGS84_UTM_zone_22S"}, + {32723, "PCS_WGS84_UTM_zone_23S"}, + {32724, "PCS_WGS84_UTM_zone_24S"}, + {32725, "PCS_WGS84_UTM_zone_25S"}, + {32726, "PCS_WGS84_UTM_zone_26S"}, + {32727, "PCS_WGS84_UTM_zone_27S"}, + {32728, "PCS_WGS84_UTM_zone_28S"}, + {32729, "PCS_WGS84_UTM_zone_29S"}, + {32730, "PCS_WGS84_UTM_zone_30S"}, + {32731, "PCS_WGS84_UTM_zone_31S"}, + {32732, "PCS_WGS84_UTM_zone_32S"}, + {32733, "PCS_WGS84_UTM_zone_33S"}, + {32734, "PCS_WGS84_UTM_zone_34S"}, + {32735, "PCS_WGS84_UTM_zone_35S"}, + {32736, "PCS_WGS84_UTM_zone_36S"}, + {32737, "PCS_WGS84_UTM_zone_37S"}, + {32738, "PCS_WGS84_UTM_zone_38S"}, + {32739, "PCS_WGS84_UTM_zone_39S"}, + {32740, "PCS_WGS84_UTM_zone_40S"}, + {32741, "PCS_WGS84_UTM_zone_41S"}, + {32742, "PCS_WGS84_UTM_zone_42S"}, + {32743, "PCS_WGS84_UTM_zone_43S"}, + {32744, "PCS_WGS84_UTM_zone_44S"}, + {32745, "PCS_WGS84_UTM_zone_45S"}, + {32746, "PCS_WGS84_UTM_zone_46S"}, + {32747, "PCS_WGS84_UTM_zone_47S"}, + {32748, "PCS_WGS84_UTM_zone_48S"}, + {32749, "PCS_WGS84_UTM_zone_49S"}, + {32750, "PCS_WGS84_UTM_zone_50S"}, + {32751, "PCS_WGS84_UTM_zone_51S"}, + {32752, "PCS_WGS84_UTM_zone_52S"}, + {32753, "PCS_WGS84_UTM_zone_53S"}, + {32754, "PCS_WGS84_UTM_zone_54S"}, + {32755, "PCS_WGS84_UTM_zone_55S"}, + {32756, "PCS_WGS84_UTM_zone_56S"}, + {32757, "PCS_WGS84_UTM_zone_57S"}, + {32758, "PCS_WGS84_UTM_zone_58S"}, + {32759, "PCS_WGS84_UTM_zone_59S"}, + {32760, "PCS_WGS84_UTM_zone_60S"} +}; -extern const TiffGeoTagKeyName ff_tiff_projection_codes[298]; +static const TiffGeoTagKeyName tiff_projection_codes[] = { + {10101, "Proj_Alabama_CS27_East"}, + {10102, "Proj_Alabama_CS27_West"}, + {10131, "Proj_Alabama_CS83_East"}, + {10132, "Proj_Alabama_CS83_West"}, + {10201, "Proj_Arizona_Coordinate_System_east"}, + {10202, "Proj_Arizona_Coordinate_System_Central"}, + {10203, "Proj_Arizona_Coordinate_System_west"}, + {10231, "Proj_Arizona_CS83_east"}, + {10232, "Proj_Arizona_CS83_Central"}, + {10233, "Proj_Arizona_CS83_west"}, + {10301, "Proj_Arkansas_CS27_North"}, + {10302, "Proj_Arkansas_CS27_South"}, + {10331, "Proj_Arkansas_CS83_North"}, + {10332, "Proj_Arkansas_CS83_South"}, + {10401, "Proj_California_CS27_I"}, + {10402, "Proj_California_CS27_II"}, + {10403, "Proj_California_CS27_III"}, + {10404, "Proj_California_CS27_IV"}, + {10405, "Proj_California_CS27_V"}, + {10406, "Proj_California_CS27_VI"}, + {10407, "Proj_California_CS27_VII"}, + {10431, "Proj_California_CS83_1"}, + {10432, "Proj_California_CS83_2"}, + {10433, "Proj_California_CS83_3"}, + {10434, "Proj_California_CS83_4"}, + {10435, "Proj_California_CS83_5"}, + {10436, "Proj_California_CS83_6"}, + {10501, "Proj_Colorado_CS27_North"}, + {10502, "Proj_Colorado_CS27_Central"}, + {10503, "Proj_Colorado_CS27_South"}, + {10531, "Proj_Colorado_CS83_North"}, + {10532, "Proj_Colorado_CS83_Central"}, + {10533, "Proj_Colorado_CS83_South"}, + {10600, "Proj_Connecticut_CS27"}, + {10630, "Proj_Connecticut_CS83"}, + {10700, "Proj_Delaware_CS27"}, + {10730, "Proj_Delaware_CS83"}, + {10901, "Proj_Florida_CS27_East"}, + {10902, "Proj_Florida_CS27_West"}, + {10903, "Proj_Florida_CS27_North"}, + {10931, "Proj_Florida_CS83_East"}, + {10932, "Proj_Florida_CS83_West"}, + {10933, "Proj_Florida_CS83_North"}, + {11001, "Proj_Georgia_CS27_East"}, + {11002, "Proj_Georgia_CS27_West"}, + {11031, "Proj_Georgia_CS83_East"}, + {11032, "Proj_Georgia_CS83_West"}, + {11101, "Proj_Idaho_CS27_East"}, + {11102, "Proj_Idaho_CS27_Central"}, + {11103, "Proj_Idaho_CS27_West"}, + {11131, "Proj_Idaho_CS83_East"}, + {11132, "Proj_Idaho_CS83_Central"}, + {11133, "Proj_Idaho_CS83_West"}, + {11201, "Proj_Illinois_CS27_East"}, + {11202, "Proj_Illinois_CS27_West"}, + {11231, "Proj_Illinois_CS83_East"}, + {11232, "Proj_Illinois_CS83_West"}, + {11301, "Proj_Indiana_CS27_East"}, + {11302, "Proj_Indiana_CS27_West"}, + {11331, "Proj_Indiana_CS83_East"}, + {11332, "Proj_Indiana_CS83_West"}, + {11401, "Proj_Iowa_CS27_North"}, + {11402, "Proj_Iowa_CS27_South"}, + {11431, "Proj_Iowa_CS83_North"}, + {11432, "Proj_Iowa_CS83_South"}, + {11501, "Proj_Kansas_CS27_North"}, + {11502, "Proj_Kansas_CS27_South"}, + {11531, "Proj_Kansas_CS83_North"}, + {11532, "Proj_Kansas_CS83_South"}, + {11601, "Proj_Kentucky_CS27_North"}, + {11602, "Proj_Kentucky_CS27_South"}, + {11631, "Proj_Kentucky_CS83_North"}, + {11632, "Proj_Kentucky_CS83_South"}, + {11701, "Proj_Louisiana_CS27_North"}, + {11702, "Proj_Louisiana_CS27_South"}, + {11731, "Proj_Louisiana_CS83_North"}, + {11732, "Proj_Louisiana_CS83_South"}, + {11801, "Proj_Maine_CS27_East"}, + {11802, "Proj_Maine_CS27_West"}, + {11831, "Proj_Maine_CS83_East"}, + {11832, "Proj_Maine_CS83_West"}, + {11900, "Proj_Maryland_CS27"}, + {11930, "Proj_Maryland_CS83"}, + {12001, "Proj_Massachusetts_CS27_Mainland"}, + {12002, "Proj_Massachusetts_CS27_Island"}, + {12031, "Proj_Massachusetts_CS83_Mainland"}, + {12032, "Proj_Massachusetts_CS83_Island"}, + {12101, "Proj_Michigan_State_Plane_East"}, + {12102, "Proj_Michigan_State_Plane_Old_Central"}, + {12103, "Proj_Michigan_State_Plane_West"}, + {12111, "Proj_Michigan_CS27_North"}, + {12112, "Proj_Michigan_CS27_Central"}, + {12113, "Proj_Michigan_CS27_South"}, + {12141, "Proj_Michigan_CS83_North"}, + {12142, "Proj_Michigan_CS83_Central"}, + {12143, "Proj_Michigan_CS83_South"}, + {12201, "Proj_Minnesota_CS27_North"}, + {12202, "Proj_Minnesota_CS27_Central"}, + {12203, "Proj_Minnesota_CS27_South"}, + {12231, "Proj_Minnesota_CS83_North"}, + {12232, "Proj_Minnesota_CS83_Central"}, + {12233, "Proj_Minnesota_CS83_South"}, + {12301, "Proj_Mississippi_CS27_East"}, + {12302, "Proj_Mississippi_CS27_West"}, + {12331, "Proj_Mississippi_CS83_East"}, + {12332, "Proj_Mississippi_CS83_West"}, + {12401, "Proj_Missouri_CS27_East"}, + {12402, "Proj_Missouri_CS27_Central"}, + {12403, "Proj_Missouri_CS27_West"}, + {12431, "Proj_Missouri_CS83_East"}, + {12432, "Proj_Missouri_CS83_Central"}, + {12433, "Proj_Missouri_CS83_West"}, + {12501, "Proj_Montana_CS27_North"}, + {12502, "Proj_Montana_CS27_Central"}, + {12503, "Proj_Montana_CS27_South"}, + {12530, "Proj_Montana_CS83"}, + {12601, "Proj_Nebraska_CS27_North"}, + {12602, "Proj_Nebraska_CS27_South"}, + {12630, "Proj_Nebraska_CS83"}, + {12701, "Proj_Nevada_CS27_East"}, + {12702, "Proj_Nevada_CS27_Central"}, + {12703, "Proj_Nevada_CS27_West"}, + {12731, "Proj_Nevada_CS83_East"}, + {12732, "Proj_Nevada_CS83_Central"}, + {12733, "Proj_Nevada_CS83_West"}, + {12800, "Proj_New_Hampshire_CS27"}, + {12830, "Proj_New_Hampshire_CS83"}, + {12900, "Proj_New_Jersey_CS27"}, + {12930, "Proj_New_Jersey_CS83"}, + {13001, "Proj_New_Mexico_CS27_East"}, + {13002, "Proj_New_Mexico_CS27_Central"}, + {13003, "Proj_New_Mexico_CS27_West"}, + {13031, "Proj_New_Mexico_CS83_East"}, + {13032, "Proj_New_Mexico_CS83_Central"}, + {13033, "Proj_New_Mexico_CS83_West"}, + {13101, "Proj_New_York_CS27_East"}, + {13102, "Proj_New_York_CS27_Central"}, + {13103, "Proj_New_York_CS27_West"}, + {13104, "Proj_New_York_CS27_Long_Island"}, + {13131, "Proj_New_York_CS83_East"}, + {13132, "Proj_New_York_CS83_Central"}, + {13133, "Proj_New_York_CS83_West"}, + {13134, "Proj_New_York_CS83_Long_Island"}, + {13200, "Proj_North_Carolina_CS27"}, + {13230, "Proj_North_Carolina_CS83"}, + {13301, "Proj_North_Dakota_CS27_North"}, + {13302, "Proj_North_Dakota_CS27_South"}, + {13331, "Proj_North_Dakota_CS83_North"}, + {13332, "Proj_North_Dakota_CS83_South"}, + {13401, "Proj_Ohio_CS27_North"}, + {13402, "Proj_Ohio_CS27_South"}, + {13431, "Proj_Ohio_CS83_North"}, + {13432, "Proj_Ohio_CS83_South"}, + {13501, "Proj_Oklahoma_CS27_North"}, + {13502, "Proj_Oklahoma_CS27_South"}, + {13531, "Proj_Oklahoma_CS83_North"}, + {13532, "Proj_Oklahoma_CS83_South"}, + {13601, "Proj_Oregon_CS27_North"}, + {13602, "Proj_Oregon_CS27_South"}, + {13631, "Proj_Oregon_CS83_North"}, + {13632, "Proj_Oregon_CS83_South"}, + {13701, "Proj_Pennsylvania_CS27_North"}, + {13702, "Proj_Pennsylvania_CS27_South"}, + {13731, "Proj_Pennsylvania_CS83_North"}, + {13732, "Proj_Pennsylvania_CS83_South"}, + {13800, "Proj_Rhode_Island_CS27"}, + {13830, "Proj_Rhode_Island_CS83"}, + {13901, "Proj_South_Carolina_CS27_North"}, + {13902, "Proj_South_Carolina_CS27_South"}, + {13930, "Proj_South_Carolina_CS83"}, + {14001, "Proj_South_Dakota_CS27_North"}, + {14002, "Proj_South_Dakota_CS27_South"}, + {14031, "Proj_South_Dakota_CS83_North"}, + {14032, "Proj_South_Dakota_CS83_South"}, + {14100, "Proj_Tennessee_CS27"}, + {14130, "Proj_Tennessee_CS83"}, + {14201, "Proj_Texas_CS27_North"}, + {14202, "Proj_Texas_CS27_North_Central"}, + {14203, "Proj_Texas_CS27_Central"}, + {14204, "Proj_Texas_CS27_South_Central"}, + {14205, "Proj_Texas_CS27_South"}, + {14231, "Proj_Texas_CS83_North"}, + {14232, "Proj_Texas_CS83_North_Central"}, + {14233, "Proj_Texas_CS83_Central"}, + {14234, "Proj_Texas_CS83_South_Central"}, + {14235, "Proj_Texas_CS83_South"}, + {14301, "Proj_Utah_CS27_North"}, + {14302, "Proj_Utah_CS27_Central"}, + {14303, "Proj_Utah_CS27_South"}, + {14331, "Proj_Utah_CS83_North"}, + {14332, "Proj_Utah_CS83_Central"}, + {14333, "Proj_Utah_CS83_South"}, + {14400, "Proj_Vermont_CS27"}, + {14430, "Proj_Vermont_CS83"}, + {14501, "Proj_Virginia_CS27_North"}, + {14502, "Proj_Virginia_CS27_South"}, + {14531, "Proj_Virginia_CS83_North"}, + {14532, "Proj_Virginia_CS83_South"}, + {14601, "Proj_Washington_CS27_North"}, + {14602, "Proj_Washington_CS27_South"}, + {14631, "Proj_Washington_CS83_North"}, + {14632, "Proj_Washington_CS83_South"}, + {14701, "Proj_West_Virginia_CS27_North"}, + {14702, "Proj_West_Virginia_CS27_South"}, + {14731, "Proj_West_Virginia_CS83_North"}, + {14732, "Proj_West_Virginia_CS83_South"}, + {14801, "Proj_Wisconsin_CS27_North"}, + {14802, "Proj_Wisconsin_CS27_Central"}, + {14803, "Proj_Wisconsin_CS27_South"}, + {14831, "Proj_Wisconsin_CS83_North"}, + {14832, "Proj_Wisconsin_CS83_Central"}, + {14833, "Proj_Wisconsin_CS83_South"}, + {14901, "Proj_Wyoming_CS27_East"}, + {14902, "Proj_Wyoming_CS27_East_Central"}, + {14903, "Proj_Wyoming_CS27_West_Central"}, + {14904, "Proj_Wyoming_CS27_West"}, + {14931, "Proj_Wyoming_CS83_East"}, + {14932, "Proj_Wyoming_CS83_East_Central"}, + {14933, "Proj_Wyoming_CS83_West_Central"}, + {14934, "Proj_Wyoming_CS83_West"}, + {15001, "Proj_Alaska_CS27_1"}, + {15002, "Proj_Alaska_CS27_2"}, + {15003, "Proj_Alaska_CS27_3"}, + {15004, "Proj_Alaska_CS27_4"}, + {15005, "Proj_Alaska_CS27_5"}, + {15006, "Proj_Alaska_CS27_6"}, + {15007, "Proj_Alaska_CS27_7"}, + {15008, "Proj_Alaska_CS27_8"}, + {15009, "Proj_Alaska_CS27_9"}, + {15010, "Proj_Alaska_CS27_10"}, + {15031, "Proj_Alaska_CS83_1"}, + {15032, "Proj_Alaska_CS83_2"}, + {15033, "Proj_Alaska_CS83_3"}, + {15034, "Proj_Alaska_CS83_4"}, + {15035, "Proj_Alaska_CS83_5"}, + {15036, "Proj_Alaska_CS83_6"}, + {15037, "Proj_Alaska_CS83_7"}, + {15038, "Proj_Alaska_CS83_8"}, + {15039, "Proj_Alaska_CS83_9"}, + {15040, "Proj_Alaska_CS83_10"}, + {15101, "Proj_Hawaii_CS27_1"}, + {15102, "Proj_Hawaii_CS27_2"}, + {15103, "Proj_Hawaii_CS27_3"}, + {15104, "Proj_Hawaii_CS27_4"}, + {15105, "Proj_Hawaii_CS27_5"}, + {15131, "Proj_Hawaii_CS83_1"}, + {15132, "Proj_Hawaii_CS83_2"}, + {15133, "Proj_Hawaii_CS83_3"}, + {15134, "Proj_Hawaii_CS83_4"}, + {15135, "Proj_Hawaii_CS83_5"}, + {15201, "Proj_Puerto_Rico_CS27"}, + {15202, "Proj_St_Croix"}, + {15230, "Proj_Puerto_Rico_Virgin_Is"}, + {15914, "Proj_BLM_14N_feet"}, + {15915, "Proj_BLM_15N_feet"}, + {15916, "Proj_BLM_16N_feet"}, + {15917, "Proj_BLM_17N_feet"}, + {17348, "Proj_Map_Grid_of_Australia_48"}, + {17349, "Proj_Map_Grid_of_Australia_49"}, + {17350, "Proj_Map_Grid_of_Australia_50"}, + {17351, "Proj_Map_Grid_of_Australia_51"}, + {17352, "Proj_Map_Grid_of_Australia_52"}, + {17353, "Proj_Map_Grid_of_Australia_53"}, + {17354, "Proj_Map_Grid_of_Australia_54"}, + {17355, "Proj_Map_Grid_of_Australia_55"}, + {17356, "Proj_Map_Grid_of_Australia_56"}, + {17357, "Proj_Map_Grid_of_Australia_57"}, + {17358, "Proj_Map_Grid_of_Australia_58"}, + {17448, "Proj_Australian_Map_Grid_48"}, + {17449, "Proj_Australian_Map_Grid_49"}, + {17450, "Proj_Australian_Map_Grid_50"}, + {17451, "Proj_Australian_Map_Grid_51"}, + {17452, "Proj_Australian_Map_Grid_52"}, + {17453, "Proj_Australian_Map_Grid_53"}, + {17454, "Proj_Australian_Map_Grid_54"}, + {17455, "Proj_Australian_Map_Grid_55"}, + {17456, "Proj_Australian_Map_Grid_56"}, + {17457, "Proj_Australian_Map_Grid_57"}, + {17458, "Proj_Australian_Map_Grid_58"}, + {18031, "Proj_Argentina_1"}, + {18032, "Proj_Argentina_2"}, + {18033, "Proj_Argentina_3"}, + {18034, "Proj_Argentina_4"}, + {18035, "Proj_Argentina_5"}, + {18036, "Proj_Argentina_6"}, + {18037, "Proj_Argentina_7"}, + {18051, "Proj_Colombia_3W"}, + {18052, "Proj_Colombia_Bogota"}, + {18053, "Proj_Colombia_3E"}, + {18054, "Proj_Colombia_6E"}, + {18072, "Proj_Egypt_Red_Belt"}, + {18073, "Proj_Egypt_Purple_Belt"}, + {18074, "Proj_Extended_Purple_Belt"}, + {18141, "Proj_New_Zealand_North_Island_Nat_Grid"}, + {18142, "Proj_New_Zealand_South_Island_Nat_Grid"}, + {19900, "Proj_Bahrain_Grid"}, + {19905, "Proj_Netherlands_E_Indies_Equatorial"}, + {19912, "Proj_RSO_Borneo"} +}; #define TIFF_COORD_TRANS_OFFSET 1 -extern const char *const ff_tiff_coord_trans_codes[27]; +static const char *const tiff_coord_trans_codes[] = { + "CT_TransverseMercator", + "CT_TransvMercator_Modified_Alaska", + "CT_ObliqueMercator", + "CT_ObliqueMercator_Laborde", + "CT_ObliqueMercator_Rosenmund", + "CT_ObliqueMercator_Spherical", + "CT_Mercator", + "CT_LambertConfConic_2SP", + "CT_LambertConfConic_Helmert", + "CT_LambertAzimEqualArea", + "CT_AlbersEqualArea", + "CT_AzimuthalEquidistant", + "CT_EquidistantConic", + "CT_Stereographic", + "CT_PolarStereographic", + "CT_ObliqueStereographic", + "CT_Equirectangular", + "CT_CassiniSoldner", + "CT_Gnomonic", + "CT_MillerCylindrical", + "CT_Orthographic", + "CT_Polyconic", + "CT_Robinson", + "CT_Sinusoidal", + "CT_VanDerGrinten", + "CT_NewZealandMapGrid", + "CT_TransvMercator_SouthOriented" +}; #define TIFF_VERT_CS_OFFSET 5001 -extern const char *const ff_tiff_vert_cs_codes[32]; +static const char *const tiff_vert_cs_codes[] = { + "VertCS_Airy_1830_ellipsoid", + "VertCS_Airy_Modified_1849_ellipsoid", + "VertCS_ANS_ellipsoid", + "VertCS_Bessel_1841_ellipsoid", + "VertCS_Bessel_Modified_ellipsoid", + "VertCS_Bessel_Namibia_ellipsoid", + "VertCS_Clarke_1858_ellipsoid", + "VertCS_Clarke_1866_ellipsoid", + "VertCS_Clarke_1880_Benoit_ellipsoid", + "VertCS_Clarke_1880_IGN_ellipsoid", + "VertCS_Clarke_1880_RGS_ellipsoid", + "VertCS_Clarke_1880_Arc_ellipsoid", + "VertCS_Clarke_1880_SGA_1922_ellipsoid", + "VertCS_Everest_1830_1937_Adjustment_ellipsoid", + "VertCS_Everest_1830_1967_Definition_ellipsoid", + "VertCS_Everest_1830_1975_Definition_ellipsoid", + "VertCS_Everest_1830_Modified_ellipsoid", + "VertCS_GRS_1980_ellipsoid", + "VertCS_Helmert_1906_ellipsoid", + "VertCS_INS_ellipsoid", + "VertCS_International_1924_ellipsoid", + "VertCS_International_1967_ellipsoid", + "VertCS_Krassowsky_1940_ellipsoid", + "VertCS_NWL_9D_ellipsoid", + "VertCS_NWL_10D_ellipsoid", + "VertCS_Plessis_1817_ellipsoid", + "VertCS_Struve_1860_ellipsoid", + "VertCS_War_Office_ellipsoid", + "VertCS_WGS_84_ellipsoid", + "VertCS_GEM_10C_ellipsoid", + "VertCS_OSU86F_ellipsoid", + "VertCS_OSU91A_ellipsoid" +}; #define TIFF_ORTHO_VERT_CS_OFFSET 5101 -extern const char *const ff_tiff_ortho_vert_cs_codes[6]; +static const char *const tiff_ortho_vert_cs_codes[] = { + "VertCS_Newlyn", + "VertCS_North_American_Vertical_Datum_1929", + "VertCS_North_American_Vertical_Datum_1988", + "VertCS_Yellow_Sea_1956", + "VertCS_Baltic_Sea", + "VertCS_Caspian_Sea" +}; + #endif diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c index a122f51de..6661e59d3 100644 --- a/libavcodec/tiffenc.c +++ b/libavcodec/tiffenc.c @@ -421,7 +421,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, 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); + 12, FF_LZW_TIFF, 0); } s->strip_offsets[i / s->rps] = ptr - pkt->data; } @@ -440,7 +440,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, 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); + ret = ff_lzw_encode_flush(s->lzws); s->strip_sizes[(i / s->rps)] += ret; ptr += ret; } diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c index b738fcb10..f8485cda5 100644 --- a/libavcodec/tmv.c +++ b/libavcodec/tmv.c @@ -94,4 +94,5 @@ AVCodec ff_tmv_decoder = { .init = tmv_decode_init, .decode = tmv_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/trace_headers_bsf.c b/libavcodec/trace_headers_bsf.c index 8ee4dbd66..b891730ba 100644 --- a/libavcodec/trace_headers_bsf.c +++ b/libavcodec/trace_headers_bsf.c @@ -52,7 +52,7 @@ static int trace_headers_init(AVBSFContext *bsf) err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in); - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); } return err; @@ -62,7 +62,7 @@ static void trace_headers_close(AVBSFContext *bsf) { TraceHeadersContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->cbc, &ctx->fragment); + ff_cbs_fragment_free(&ctx->fragment); ff_cbs_close(&ctx->cbc); } @@ -97,7 +97,7 @@ static int trace_headers(AVBSFContext *bsf, AVPacket *pkt) err = ff_cbs_read_packet(ctx->cbc, frag, pkt); - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); if (err < 0) av_packet_unref(pkt); diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index b6481cbd7..94782fef4 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -491,10 +491,8 @@ static av_cold int truemotion1_decode_init(AVCodecContext *avctx) /* 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) { - av_frame_free(&s->frame); + if (!s->vert_pred) return AVERROR(ENOMEM); - } return 0; } @@ -922,4 +920,5 @@ AVCodec ff_truemotion1_decoder = { .close = truemotion1_decode_end, .decode = truemotion1_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index d90a8baff..012ad4ffd 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -81,7 +81,7 @@ typedef struct TM2Context { int *clast; /* data for current and previous frame */ - int *Y1_base, *U1_base, *V1_base, *Y2_base, *U2_base, *V2_base; + int *Y_base, *UV_base; int *Y1, *U1, *V1, *Y2, *U2, *V2; int y_stride, uv_stride; int cur; @@ -108,15 +108,14 @@ typedef struct TM2Huff { int num; ///< current number filled int max_num; ///< total number of codes int *nums; ///< literals - uint32_t *bits; ///< codes - int *lens; ///< codelengths + uint8_t *lens; ///< codelengths } TM2Huff; /** * * @returns the length of the longest code or an AVERROR code */ -static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff *huff) +static int tm2_read_tree(TM2Context *ctx, int length, TM2Huff *huff) { int ret, ret2; if (length > huff->max_bits) { @@ -134,14 +133,13 @@ static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff * return AVERROR_INVALIDDATA; } huff->nums[huff->num] = get_bits_long(&ctx->gb, huff->val_bits); - huff->bits[huff->num] = prefix; huff->lens[huff->num] = length; huff->num++; return length; } else { /* non-terminal node */ - if ((ret2 = tm2_read_tree(ctx, prefix << 1, length + 1, huff)) < 0) + if ((ret2 = tm2_read_tree(ctx, length + 1, huff)) < 0) return ret2; - if ((ret = tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff)) < 0) + if ((ret = tm2_read_tree(ctx, length + 1, huff)) < 0) return ret; } return FFMAX(ret, ret2); @@ -177,15 +175,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_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)); + huff.lens = av_mallocz(huff.max_num); - if (!huff.nums || !huff.bits || !huff.lens) { + if (!huff.nums || !huff.lens) { res = AVERROR(ENOMEM); goto out; } - res = tm2_read_tree(ctx, 0, 0, &huff); + res = tm2_read_tree(ctx, 0, &huff); if (res >= 0 && res != huff.max_bits) { av_log(ctx->avctx, AV_LOG_ERROR, "Got less bits than expected: %i of %i\n", @@ -200,30 +197,22 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code) /* convert codes to vlc_table */ if (res >= 0) { - int i; - - res = init_vlc(&code->vlc, huff.max_bits, huff.max_num, - huff.lens, sizeof(int), sizeof(int), - huff.bits, sizeof(uint32_t), sizeof(uint32_t), 0); + res = ff_init_vlc_from_lengths(&code->vlc, huff.max_bits, huff.max_num, + huff.lens, sizeof(huff.lens[0]), + NULL, 0, 0, 0, 0, ctx->avctx); if (res < 0) av_log(ctx->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); else { code->bits = huff.max_bits; code->length = huff.max_num; - code->recode = av_malloc_array(code->length, sizeof(int)); - if (!code->recode) { - res = AVERROR(ENOMEM); - goto out; - } - for (i = 0; i < code->length; i++) - code->recode[i] = huff.nums[i]; + code->recode = huff.nums; + huff.nums = NULL; } } out: /* free allocated memory */ av_free(huff.nums); - av_free(huff.bits); av_free(huff.lens); return res; @@ -957,7 +946,7 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_init(AVCodecContext *avctx) { TM2Context * const l = avctx->priv_data; - int i, w = avctx->width, h = avctx->height; + int w = avctx->width, h = avctx->height; if ((avctx->width & 3) || (avctx->height & 3)) { av_log(avctx, AV_LOG_ERROR, "Width and height must be multiple of 4\n"); @@ -973,47 +962,29 @@ static av_cold int decode_init(AVCodecContext *avctx) ff_bswapdsp_init(&l->bdsp); - 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; - l->tok_lens[i] = 0; - } + l->last = av_malloc_array(w, 2 * sizeof(*l->last)); + if (!l->last) + return AVERROR(ENOMEM); + l->clast = l->last + w; w += 8; h += 8; - l->Y1_base = av_calloc(w * h, sizeof(*l->Y1_base)); - l->Y2_base = av_calloc(w * h, sizeof(*l->Y2_base)); + l->Y_base = av_calloc(w * h, 2 * sizeof(*l->Y_base)); + if (!l->Y_base) + return AVERROR(ENOMEM); l->y_stride = w; + l->Y1 = l->Y_base + l->y_stride * 4 + 4; + l->Y2 = l->Y1 + w * h; w = (w + 1) >> 1; h = (h + 1) >> 1; - 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_frame_free(&l->pic); + l->UV_base = av_calloc(w * h, 4 * sizeof(*l->UV_base)); + if (!l->UV_base) return AVERROR(ENOMEM); - } - l->Y1 = l->Y1_base + l->y_stride * 4 + 4; - l->Y2 = l->Y2_base + l->y_stride * 4 + 4; - l->U1 = l->U1_base + l->uv_stride * 2 + 2; - l->U2 = l->U2_base + l->uv_stride * 2 + 2; - l->V1 = l->V1_base + l->uv_stride * 2 + 2; - l->V2 = l->V2_base + l->uv_stride * 2 + 2; + l->uv_stride = w; + l->U1 = l->UV_base + l->uv_stride * 2 + 2; + l->U2 = l->U1 + w * h; + l->V1 = l->U2 + w * h; + l->V2 = l->V1 + w * h; return 0; } @@ -1023,18 +994,12 @@ static av_cold int decode_end(AVCodecContext *avctx) TM2Context * const l = avctx->priv_data; int i; - av_free(l->last); - av_free(l->clast); + av_freep(&l->last); for (i = 0; i < TM2_NUM_STREAMS; i++) av_freep(&l->tokens[i]); - if (l->Y1) { - av_freep(&l->Y1_base); - av_freep(&l->U1_base); - av_freep(&l->V1_base); - av_freep(&l->Y2_base); - av_freep(&l->U2_base); - av_freep(&l->V2_base); - } + + av_freep(&l->Y_base); + av_freep(&l->UV_base); av_freep(&l->buffer); l->buffer_size = 0; @@ -1053,4 +1018,5 @@ AVCodec ff_truemotion2_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index 3cdae8c55..272fc43de 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -21,6 +21,8 @@ #include "libavutil/channel_layout.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "bswapdsp.h" #include "get_bits.h" diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c index 6d03081bb..d33639f3a 100644 --- a/libavcodec/tscc.c +++ b/libavcodec/tscc.c @@ -72,7 +72,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int palette_has_changed = 0; if (c->avctx->pix_fmt == AV_PIX_FMT_PAL8) { - int size; + buffer_size_t size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); if (pal && size == AVPALETTE_SIZE) { diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c index 65fbb010f..13e7a41a3 100644 --- a/libavcodec/tscc2.c +++ b/libavcodec/tscc2.c @@ -26,6 +26,8 @@ #include +#include "libavutil/thread.h" + #define BITSTREAM_READER_LE #include "avcodec.h" #include "bytestream.h" @@ -34,6 +36,8 @@ #include "mathops.h" #include "tscc2data.h" +#define TSCC2_VLC_BITS 9 + typedef struct TSCC2Context { AVCodecContext *avctx; AVFrame *pic; @@ -43,52 +47,43 @@ typedef struct TSCC2Context { int q[2][3]; GetBitContext gb; - VLC dc_vlc, nc_vlc[NUM_VLC_SETS], ac_vlc[NUM_VLC_SETS]; int block[16]; } TSCC2Context; -static av_cold void free_vlcs(TSCC2Context *c) -{ - int i; +static VLC dc_vlc, nc_vlc[NUM_VLC_SETS], ac_vlc[NUM_VLC_SETS]; - ff_free_vlc(&c->dc_vlc); - for (i = 0; i < NUM_VLC_SETS; i++) { - ff_free_vlc(c->nc_vlc + i); - ff_free_vlc(c->ac_vlc + i); - } +static av_cold void tscc2_init_vlc(VLC *vlc, int *offset, int nb_codes, + const uint8_t *lens, const void *syms, + int sym_length) +{ + static VLC_TYPE vlc_buf[15442][2]; + + vlc->table = &vlc_buf[*offset]; + vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *offset; + ff_init_vlc_from_lengths(vlc, TSCC2_VLC_BITS, nb_codes, + lens, 1, syms, sym_length, sym_length, 0, + INIT_VLC_STATIC_OVERLONG | INIT_VLC_OUTPUT_LE, NULL); + *offset += vlc->table_size; } -static av_cold int init_vlcs(TSCC2Context *c) +static av_cold void tscc2_init_vlcs(void) { - int i, ret; + const uint16_t *ac_vlc_syms = tscc2_ac_vlc_syms; + const uint8_t *ac_vlc_lens = tscc2_ac_vlc_lens; + int i, offset = 0; - ret = ff_init_vlc_sparse(&c->dc_vlc, 9, DC_VLC_COUNT, - tscc2_dc_vlc_bits, 1, 1, - tscc2_dc_vlc_codes, 2, 2, - tscc2_dc_vlc_syms, 2, 2, INIT_VLC_LE); - if (ret) - return ret; + tscc2_init_vlc(&dc_vlc, &offset, DC_VLC_COUNT, + tscc2_dc_vlc_lens, tscc2_dc_vlc_syms, 2); for (i = 0; i < NUM_VLC_SETS; i++) { - ret = ff_init_vlc_sparse(c->nc_vlc + i, 9, 16, - tscc2_nc_vlc_bits[i], 1, 1, - tscc2_nc_vlc_codes[i], 2, 2, - tscc2_nc_vlc_syms, 1, 1, INIT_VLC_LE); - if (ret) { - free_vlcs(c); - return ret; - } - ret = ff_init_vlc_sparse(c->ac_vlc + i, 9, tscc2_ac_vlc_sizes[i], - tscc2_ac_vlc_bits[i], 1, 1, - tscc2_ac_vlc_codes[i], 2, 2, - tscc2_ac_vlc_syms[i], 2, 2, INIT_VLC_LE); - if (ret) { - free_vlcs(c); - return ret; - } - } + tscc2_init_vlc(&nc_vlc[i], &offset, 16, + tscc2_nc_vlc_lens[i], tscc2_nc_vlc_syms[i], 1); - return 0; + tscc2_init_vlc(&ac_vlc[i], &offset, tscc2_ac_vlc_sizes[i], + ac_vlc_lens, ac_vlc_syms, 2); + ac_vlc_lens += tscc2_ac_vlc_sizes[i]; + ac_vlc_syms += tscc2_ac_vlc_sizes[i]; + } } #define DEQUANT(val, q) (((q) * (val) + 0x80) >> 8) @@ -154,9 +149,7 @@ static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set, if (!(j | k)) { dc = get_bits(gb, 8); } else { - dc = get_vlc2(gb, c->dc_vlc.table, 9, 2); - if (dc == -1) - return AVERROR_INVALIDDATA; + dc = get_vlc2(gb, dc_vlc.table, TSCC2_VLC_BITS, 2); if (dc == 0x100) dc = get_bits(gb, 8); } @@ -164,16 +157,12 @@ static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set, prev_dc = dc; c->block[0] = dc; - nc = get_vlc2(gb, c->nc_vlc[vlc_set].table, 9, 1); - if (nc == -1) - return AVERROR_INVALIDDATA; + nc = get_vlc2(gb, nc_vlc[vlc_set].table, TSCC2_VLC_BITS, 1); bpos = 1; memset(c->block + 1, 0, 15 * sizeof(*c->block)); for (l = 0; l < nc; l++) { - ac = get_vlc2(gb, c->ac_vlc[vlc_set].table, 9, 2); - if (ac == -1) - return AVERROR_INVALIDDATA; + ac = get_vlc2(gb, ac_vlc[vlc_set].table, TSCC2_VLC_BITS, 2); if (ac == 0x1000) ac = get_bits(gb, 12); bpos += ac & 0xF; @@ -336,7 +325,6 @@ static av_cold int tscc2_decode_end(AVCodecContext *avctx) av_frame_free(&c->pic); av_freep(&c->slice_quants); - free_vlcs(c); return 0; } @@ -344,31 +332,25 @@ static av_cold int tscc2_decode_end(AVCodecContext *avctx) static av_cold int tscc2_decode_init(AVCodecContext *avctx) { TSCC2Context * const c = avctx->priv_data; - int ret; + static AVOnce init_static_once = AV_ONCE_INIT; c->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_YUV444P; - if ((ret = init_vlcs(c)) < 0) { - av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n"); - return ret; - } - c->mb_width = FFALIGN(avctx->width, 16) >> 4; c->mb_height = FFALIGN(avctx->height, 8) >> 3; c->slice_quants = av_malloc(c->mb_width * c->mb_height); if (!c->slice_quants) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate slice information\n"); - free_vlcs(c); return AVERROR(ENOMEM); } c->pic = av_frame_alloc(); - if (!c->pic) { - tscc2_decode_end(avctx); + if (!c->pic) return AVERROR(ENOMEM); - } + + ff_thread_once(&init_static_once, tscc2_init_vlcs); return 0; } @@ -383,4 +365,5 @@ AVCodec ff_tscc2_decoder = { .close = tscc2_decode_end, .decode = tscc2_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/tscc2data.h b/libavcodec/tscc2data.h index 5e8d18b3f..63f561914 100644 --- a/libavcodec/tscc2data.h +++ b/libavcodec/tscc2data.h @@ -37,892 +37,399 @@ static const uint16_t tscc2_quants[NUM_VLC_SETS][3] = { #define DC_VLC_COUNT 47 static const uint16_t tscc2_dc_vlc_syms[DC_VLC_COUNT] = { - 0x100, 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, - 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, - 0xF0, 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0x17, - 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, - 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x0FF, 0x001, 0x0FC, 0x0F1, 0x0EA, 0x017, 0x00E, 0x016, 0x0EB, 0x009, + 0x0F6, 0x004, 0x006, 0x0F2, 0x015, 0x014, 0x00D, 0x0EC, 0x0ED, 0x100, + 0x0FA, 0x0F7, 0x008, 0x00C, 0x013, 0x0EE, 0x0F3, 0x0F4, 0x005, 0x0FE, + 0x002, 0x0FB, 0x0F8, 0x012, 0x011, 0x00B, 0x0FD, 0x003, 0x007, 0x0EF, + 0x0F0, 0x0F5, 0x0F9, 0x00F, 0x010, 0x00A, 0x000, }; -static const uint16_t tscc2_dc_vlc_codes[DC_VLC_COUNT] = { - 0x000A, 0x0000, 0x0006, 0x002E, 0x0002, 0x000E, 0x001A, 0x007E, - 0x004E, 0x005A, 0x00E2, 0x01BE, 0x01BA, 0x00BA, 0x0072, 0x0022, - 0x02BE, 0x00BE, 0x033A, 0x03F2, 0x01F2, 0x03A2, 0x0122, 0x0322, - 0x01A2, 0x0172, 0x0372, 0x013A, 0x00CE, 0x02CE, 0x02FE, 0x00FE, - 0x00A2, 0x00F2, 0x003A, 0x01CE, 0x01FE, 0x0062, 0x00DA, 0x003E, - 0x0032, 0x007A, 0x0012, 0x001E, 0x0016, 0x0004, 0x0001, +static const uint8_t tscc2_dc_vlc_lens[DC_VLC_COUNT] = { + 3, 3, 6, 9, 10, 10, 9, 10, 10, 8, 8, 6, 7, 9, 10, 10, 9, 10, + 10, 5, 7, 8, 8, 9, 10, 10, 9, 9, 7, 5, 5, 7, 8, 10, 10, 9, + 6, 6, 8, 10, 10, 9, 8, 10, 10, 9, 1, }; -static const uint8_t tscc2_dc_vlc_bits[DC_VLC_COUNT] = { - 5, 3, 5, 6, 6, 7, 7, 8, - 8, 8, 8, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 9, 9, 9, 9, 9, 8, 8, 8, - 7, 7, 6, 6, 5, 3, 1, +static const uint8_t tscc2_nc_vlc_syms[NUM_VLC_SETS][16] = { + { 0x00, 0x08, 0x0C, 0x0B, 0x0D, 0x07, 0x06, 0x04, + 0x02, 0x0E, 0x0F, 0x09, 0x0A, 0x05, 0x03, 0x01 }, + { 0x0A, 0x0C, 0x07, 0x0F, 0x0B, 0x0D, 0x04, 0x02, + 0x06, 0x0E, 0x05, 0x09, 0x08, 0x03, 0x01, 0x00 }, + { 0x08, 0x0D, 0x04, 0x0C, 0x07, 0x0A, 0x0E, 0x02, + 0x0B, 0x06, 0x05, 0x0F, 0x09, 0x03, 0x01, 0x00 }, + { 0x04, 0x0E, 0x0C, 0x09, 0x08, 0x07, 0x0A, 0x02, + 0x06, 0x0B, 0x05, 0x0F, 0x0D, 0x03, 0x01, 0x00 }, + { 0x0D, 0x0C, 0x04, 0x09, 0x08, 0x0B, 0x07, 0x02, + 0x06, 0x0A, 0x0F, 0x0E, 0x05, 0x03, 0x01, 0x00 }, + { 0x01, 0x0A, 0x06, 0x07, 0x05, 0x03, 0x0D, 0x0C, + 0x04, 0x0F, 0x0E, 0x0B, 0x09, 0x08, 0x02, 0x00 }, + { 0x01, 0x08, 0x06, 0x07, 0x0D, 0x0C, 0x05, 0x04, + 0x0F, 0x0E, 0x0B, 0x09, 0x0A, 0x03, 0x02, 0x00 }, + { 0x01, 0x0D, 0x0C, 0x08, 0x06, 0x07, 0x05, 0x0F, + 0x0E, 0x0B, 0x04, 0x0A, 0x09, 0x03, 0x02, 0x00 }, + { 0x01, 0x0D, 0x0F, 0x0E, 0x08, 0x07, 0x06, 0x0C, + 0x0B, 0x05, 0x04, 0x0A, 0x09, 0x03, 0x02, 0x00 }, + { 0x03, 0x02, 0x09, 0x08, 0x0C, 0x0B, 0x07, 0x06, + 0x05, 0x04, 0x0D, 0x0F, 0x0E, 0x0A, 0x01, 0x00 }, + { 0x03, 0x02, 0x09, 0x0C, 0x0B, 0x08, 0x07, 0x06, + 0x0D, 0x0F, 0x0E, 0x0A, 0x05, 0x04, 0x01, 0x00 }, + { 0x03, 0x02, 0x09, 0x0C, 0x0B, 0x08, 0x07, 0x06, + 0x0D, 0x0F, 0x0E, 0x0A, 0x04, 0x05, 0x01, 0x00 }, + { 0x03, 0x02, 0x09, 0x0C, 0x0B, 0x08, 0x07, 0x0D, + 0x0F, 0x0E, 0x0A, 0x06, 0x05, 0x04, 0x01, 0x00 }, }; -static const uint8_t tscc2_nc_vlc_syms[16] = { - 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, +static const uint8_t tscc2_nc_vlc_lens[NUM_VLC_SETS][16] = { + { 1, 6, 6, 6, 6, 6, 6, 5, 3, 6, 6, 7, 7, 6, 4, 3 }, + { 6, 6, 6, 6, 6, 6, 5, 3, 6, 6, 6, 7, 7, 4, 3, 1 }, + { 6, 6, 5, 6, 6, 6, 6, 3, 6, 6, 6, 7, 7, 4, 3, 1 }, + { 5, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 7, 7, 4, 3, 1 }, + { 6, 6, 5, 6, 6, 6, 6, 3, 6, 6, 7, 7, 6, 4, 3, 1 }, + { 2, 6, 6, 6, 6, 4, 7, 7, 6, 8, 8, 7, 7, 7, 4, 1 }, + { 2, 6, 6, 6, 7, 7, 6, 6, 8, 8, 7, 7, 7, 4, 4, 1 }, + { 2, 7, 7, 6, 6, 6, 6, 8, 8, 7, 6, 7, 7, 4, 4, 1 }, + { 2, 7, 8, 8, 6, 6, 6, 7, 7, 6, 6, 7, 7, 4, 4, 1 }, + { 3, 3, 6, 6, 7, 7, 6, 6, 6, 6, 8, 9, 9, 7, 3, 1 }, + { 3, 3, 6, 7, 7, 6, 6, 6, 8, 9, 9, 7, 6, 6, 3, 1 }, + { 3, 3, 6, 7, 7, 6, 6, 6, 8, 9, 9, 7, 6, 6, 3, 1 }, + { 3, 3, 6, 7, 7, 6, 6, 8, 9, 9, 7, 6, 6, 6, 3, 1 }, }; -static const uint16_t tscc2_nc_vlc_codes[NUM_VLC_SETS][16] = { - { 0x0023, 0x0003, 0x0031, 0x0021, 0x0011, 0x0053, 0x0013, 0x0001, - 0x0009, 0x0029, 0x0033, 0x0019, 0x000B, 0x0005, 0x0007, 0x0000, }, - { 0x0030, 0x0022, 0x0028, 0x0020, 0x0008, 0x0000, 0x0032, 0x0072, - 0x0010, 0x0002, 0x0012, 0x0018, 0x000A, 0x0004, 0x0006, 0x0001, }, - { 0x0032, 0x0038, 0x0020, 0x0008, 0x0002, 0x0018, 0x0072, 0x0000, - 0x0028, 0x0022, 0x0012, 0x0010, 0x000A, 0x0004, 0x0006, 0x0001, }, - { 0x0032, 0x0010, 0x0072, 0x0030, 0x0022, 0x0038, 0x0008, 0x0028, - 0x0018, 0x0002, 0x0012, 0x0000, 0x000A, 0x0004, 0x0006, 0x0001, }, - { 0x0012, 0x0052, 0x0000, 0x0020, 0x0018, 0x0022, 0x0008, 0x0028, - 0x0038, 0x0002, 0x0032, 0x0010, 0x000A, 0x0004, 0x0006, 0x0001, }, - { 0x0016, 0x0096, 0x0006, 0x0046, 0x0056, 0x0002, 0x0036, 0x0076, - 0x0012, 0x0022, 0x0032, 0x0026, 0x000A, 0x000E, 0x0000, 0x0001, }, - { 0x001A, 0x009A, 0x0032, 0x0072, 0x005A, 0x007A, 0x003A, 0x0002, - 0x0012, 0x0022, 0x000A, 0x002A, 0x0006, 0x000E, 0x0000, 0x0001, }, - { 0x002A, 0x00AA, 0x0002, 0x0042, 0x006A, 0x003A, 0x007A, 0x0022, - 0x0032, 0x0012, 0x000A, 0x001A, 0x0006, 0x000E, 0x0000, 0x0001, }, - { 0x0042, 0x00C2, 0x0002, 0x000A, 0x004A, 0x003A, 0x007A, 0x0022, - 0x0012, 0x0032, 0x002A, 0x001A, 0x0006, 0x000E, 0x0000, 0x0001, }, - { 0x00BA, 0x01BA, 0x003A, 0x0012, 0x0052, 0x007A, 0x0002, 0x0022, - 0x0032, 0x000A, 0x002A, 0x001A, 0x0000, 0x0004, 0x0006, 0x0001, }, - { 0x00AA, 0x01AA, 0x002A, 0x0022, 0x0062, 0x006A, 0x0002, 0x0012, - 0x0032, 0x000A, 0x001A, 0x003A, 0x0000, 0x0004, 0x0006, 0x0001, }, - { 0x00AA, 0x01AA, 0x002A, 0x0022, 0x0062, 0x006A, 0x0002, 0x0012, - 0x0032, 0x000A, 0x003A, 0x001A, 0x0000, 0x0004, 0x0006, 0x0001, }, - { 0x008A, 0x018A, 0x000A, 0x0022, 0x0062, 0x004A, 0x0002, 0x0012, - 0x0032, 0x002A, 0x001A, 0x003A, 0x0000, 0x0004, 0x0006, 0x0001, }, +static const uint16_t tscc2_ac_vlc_syms[] = { + /* Descriptor 0 - 172 entries */ + 0x0FC0, 0x0040, 0x0FF1, 0x0011, 0x0FA0, 0x0FE5, 0x0140, 0x0280, 0x0D60, + 0x0210, 0x0FC6, 0x0FD6, 0x0200, 0x0F95, 0x0101, 0x0190, 0x0FF5, 0x0FF2, + 0x0060, 0x0FE1, 0x0021, 0x0F41, 0x0270, 0x0D80, 0x0055, 0x0FB2, 0x00F1, + 0x0120, 0x0F30, 0x0015, 0x0090, 0x0FE3, 0x0FA1, 0x0E00, 0x01F0, 0x0F81, + 0x0EE0, 0x0FD1, 0x0F70, 0x0FA3, 0x0121, 0x0FC5, 0x0E70, 0x0023, 0x0180, + 0x00C1, 0x0F51, 0x0FE2, 0x0031, 0x0012, 0x0061, 0x00A5, 0x0ED1, 0x0D90, + 0x0091, 0x0E10, 0x0FE4, 0x0043, 0x0024, 0x0E80, 0x01E0, 0x0DA0, 0x0FA5, + 0x00D0, 0x0022, 0x0110, 0x0FE0, 0x0020, 0x0EF0, 0x0F45, 0x0260, 0x0045, + 0x0081, 0x0F40, 0x0F80, 0x0080, 0x00C0, 0x0E20, 0x0250, 0x0052, 0x0063, + 0x0018, 0x0FC3, 0x0170, 0x0111, 0x0F73, 0x0240, 0x0DC0, 0x0FB0, 0x0F00, + 0x0100, 0x0FC1, 0x0160, 0x0DB0, 0x00B1, 0x0026, 0x0F31, 0x0FF8, 0x0EA0, + 0x0150, 0x0065, 0x0FE6, 0x0E90, 0x0E30, 0x01C0, 0x0FD0, 0x0030, 0x0FF0, + 0x0010, 0x0050, 0x00B0, 0x0FF4, 0x0FF3, 0x0046, 0x0053, 0x0230, 0x0FB3, + 0x0EB0, 0x0035, 0x0FB5, 0x00E1, 0x0CD1, 0x0ED5, 0x0F50, 0x0041, 0x0F10, + 0x01B0, 0x01D0, 0x0F91, 0x0F90, 0x0070, 0x00F0, 0x0FB1, 0x0E40, 0x0DD0, + 0x0075, 0x0E50, 0x0FC2, 0x0F83, 0x0FD2, 0x00A1, 0x0EC0, 0x0013, 0x0014, + 0x0F61, 0x01A1, 0x0220, 0x0FD5, 0x0DE0, 0x0F21, 0x0016, 0x0F60, 0x0032, + 0x01A0, 0x0036, 0x00D1, 0x0FD3, 0x0025, 0x0130, 0x1000, 0x0051, 0x0FF6, + 0x0ED0, 0x0E60, 0x0042, 0x0DF0, 0x0F20, 0x00E0, 0x0033, 0x0F71, 0x0071, + 0x00A0, + /* Descriptor 1 - 169 entries */ + 0x00D0, 0x0E50, 0x00D1, 0x0091, 0x0160, 0x0F31, 0x0EE1, 0x0250, 0x0F70, + 0x0051, 0x0F41, 0x0063, 0x0150, 0x0EF0, 0x01A0, 0x0F51, 0x0FD5, 0x0F93, + 0x0DC0, 0x0240, 0x0095, 0x0FD2, 0x00C0, 0x0FC0, 0x0040, 0x0090, 0x0016, + 0x0F40, 0x0FA0, 0x0026, 0x0EB0, 0x0EF1, 0x0DF0, 0x0053, 0x0F01, 0x01F0, + 0x0FC2, 0x0FF6, 0x0FF5, 0x0060, 0x0015, 0x0F85, 0x0DE1, 0x0032, 0x0100, + 0x0046, 0x0DB0, 0x0FB5, 0x0F81, 0x0FA1, 0x0012, 0x0011, 0x0FF1, 0x0FF2, + 0x0F00, 0x0E00, 0x0F21, 0x0F45, 0x0FD3, 0x0E60, 0x00C1, 0x0E80, 0x0035, + 0x0045, 0x0140, 0x0042, 0x0FB2, 0x0EB6, 0x0033, 0x0FC5, 0x0190, 0x0FE6, + 0x0024, 0x0F61, 0x0085, 0x0E33, 0x0E70, 0x0EC0, 0x00B0, 0x0F50, 0x0F80, + 0x0080, 0x0023, 0x0FE4, 0x01E0, 0x0F11, 0x0081, 0x0FC1, 0x0FD1, 0x0052, + 0x0FA5, 0x0F95, 0x0EC6, 0x00B1, 0x0111, 0x0061, 0x00F0, 0x0FE3, 0x0FE1, + 0x0021, 0x0041, 0x0FE2, 0x0055, 0x0FC6, 0x0E10, 0x0180, 0x0E20, 0x0DE0, + 0x0022, 0x0025, 0x0FB3, 0x0FA3, 0x0036, 0x0FC3, 0x00E0, 0x0FE0, 0x0020, + 0x0050, 0x0FB0, 0x1000, 0x0031, 0x01D0, 0x0018, 0x00A1, 0x0FB6, 0x00C6, + 0x0043, 0x0F10, 0x0F20, 0x0101, 0x0E30, 0x0FA6, 0x00F1, 0x0ED0, 0x0FD0, + 0x00A0, 0x0FD6, 0x0DA0, 0x0E31, 0x0120, 0x0130, 0x0170, 0x01C0, 0x00E1, + 0x0F60, 0x0014, 0x0070, 0x0F90, 0x0030, 0x0FB1, 0x0075, 0x0E90, 0x0F91, + 0x0FF4, 0x0013, 0x0FF3, 0x0EE0, 0x0FF8, 0x0065, 0x0E40, 0x01B0, 0x0F30, + 0x0071, 0x0FE5, 0x0EA0, 0x0F71, 0x0110, 0x0FF0, 0x0010, + /* Descriptor 2 - 165 entries */ + 0x0051, 0x0E61, 0x0E81, 0x0E80, 0x0FF7, 0x0E00, 0x0E30, 0x0F71, 0x0130, + 0x00F0, 0x0170, 0x0E70, 0x0F81, 0x0F40, 0x0FF3, 0x0040, 0x0013, 0x0FA0, + 0x0FC0, 0x0060, 0x0065, 0x0E40, 0x0ED0, 0x0043, 0x0086, 0x0F93, 0x0036, + 0x0035, 0x0F10, 0x0EA1, 0x01B3, 0x0F36, 0x0FD5, 0x0FA1, 0x0F41, 0x0096, + 0x0EB3, 0x0F26, 0x0F16, 0x0FB6, 0x0FB5, 0x0160, 0x0FD6, 0x0F80, 0x0080, + 0x1000, 0x00B0, 0x0FE5, 0x0091, 0x0E90, 0x0241, 0x0231, 0x0FF5, 0x0015, + 0x0081, 0x0120, 0x0EA0, 0x0053, 0x0F51, 0x0FC2, 0x0F50, 0x0FF6, 0x0061, + 0x0EB1, 0x0018, 0x0FF8, 0x0240, 0x0042, 0x0085, 0x0EF1, 0x0FD1, 0x0FF2, + 0x0012, 0x0016, 0x0FD2, 0x0FC6, 0x0063, 0x00A5, 0x0F20, 0x0055, 0x0052, + 0x0E10, 0x0150, 0x00C1, 0x01D0, 0x0F95, 0x0032, 0x00E0, 0x01A0, 0x0EE1, + 0x0024, 0x0EF0, 0x0FC1, 0x0F60, 0x0031, 0x0190, 0x0F11, 0x0FB2, 0x0F21, + 0x0110, 0x0FC3, 0x0FE4, 0x0F01, 0x0095, 0x0FD3, 0x0FB3, 0x0E71, 0x0F61, + 0x0EB0, 0x0026, 0x00A0, 0x00D0, 0x0045, 0x00A1, 0x00B1, 0x0180, 0x01C0, + 0x0FF1, 0x0011, 0x0FB0, 0x0050, 0x0F90, 0x0041, 0x0033, 0x0F91, 0x0F30, + 0x0FE1, 0x0FE0, 0x0020, 0x0FD0, 0x0070, 0x0FE2, 0x0E50, 0x0FA3, 0x0F75, + 0x0EA3, 0x01B0, 0x0140, 0x0023, 0x0FE3, 0x0021, 0x0030, 0x0100, 0x0071, + 0x0FC5, 0x0EC0, 0x0F00, 0x0090, 0x0022, 0x0F06, 0x0F31, 0x0FA5, 0x00D1, + 0x0E60, 0x0075, 0x0F70, 0x0014, 0x0FF4, 0x0025, 0x0FB1, 0x0FE6, 0x0EE0, + 0x00C0, 0x0FF0, 0x0010, + /* Descriptor 3 - 162 entries */ + 0x0FC5, 0x0EC1, 0x0033, 0x0FE3, 0x0FD6, 0x0110, 0x00E0, 0x0071, 0x0F36, + 0x0095, 0x01A1, 0x0F71, 0x0060, 0x0FA0, 0x0FE2, 0x0F20, 0x0F21, 0x0085, + 0x0150, 0x0053, 0x0023, 0x0022, 0x0FF4, 0x0043, 0x0E70, 0x0034, 0x0017, + 0x0140, 0x0170, 0x0EF0, 0x0F50, 0x0F80, 0x00B0, 0x0F26, 0x00D1, 0x0065, + 0x0113, 0x0FF7, 0x0073, 0x01E1, 0x0EF3, 0x0F31, 0x0FB5, 0x0FC0, 0x0040, + 0x0080, 0x0FA1, 0x0FD3, 0x0075, 0x0F41, 0x0FD4, 0x0F83, 0x0EB0, 0x0061, + 0x0013, 0x0FF3, 0x0F10, 0x0F30, 0x0100, 0x0EB1, 0x0F93, 0x0130, 0x00D0, + 0x00A0, 0x00C1, 0x0F95, 0x0FB3, 0x0FC3, 0x0FE5, 0x0FF5, 0x0F81, 0x0F00, + 0x0091, 0x0F66, 0x01B1, 0x0F51, 0x0F60, 0x0FD1, 0x0180, 0x0FF8, 0x0076, + 0x0FB2, 0x0063, 0x0042, 0x0081, 0x0052, 0x0EE1, 0x0FC2, 0x0160, 0x0036, + 0x01D0, 0x0FD2, 0x0EA0, 0x0018, 0x0E80, 0x0FD5, 0x0070, 0x0F90, 0x0FB0, + 0x0015, 0x0032, 0x0123, 0x0F01, 0x0EE3, 0x0ED1, 0x00C0, 0x0FC1, 0x0FF2, + 0x0012, 0x0050, 0x00A1, 0x00F0, 0x0ED0, 0x0FC6, 0x0ED3, 0x01D1, 0x0120, + 0x0016, 0x0031, 0x0FF6, 0x0F40, 0x0EC0, 0x0E90, 0x0F91, 0x0041, 0x0EF1, + 0x0F61, 0x0035, 0x0FB1, 0x0FF1, 0x0011, 0x0FE0, 0x0020, 0x0FE1, 0x0090, + 0x00B1, 0x0163, 0x0055, 0x0024, 0x0F56, 0x0FA3, 0x0FE4, 0x0F46, 0x0FE6, + 0x0025, 0x0026, 0x0EE0, 0x0FA5, 0x01C1, 0x0F70, 0x0FD0, 0x0030, 0x1000, + 0x0045, 0x0F11, 0x0066, 0x0F85, 0x0051, 0x0014, 0x0021, 0x0FF0, 0x0010, + /* Descriptor 4 - 131 entries */ + 0x0010, 0x0FB0, 0x0050, 0x0070, 0x0FF5, 0x0FC1, 0x0090, 0x0FD1, 0x00E0, + 0x0161, 0x0085, 0x0F41, 0x0F20, 0x0FD6, 0x0F70, 0x0FD3, 0x0032, 0x0FD2, + 0x0055, 0x0191, 0x0063, 0x0091, 0x0081, 0x0F91, 0x0015, 0x0031, 0x0065, + 0x0036, 0x00B1, 0x0130, 0x0018, 0x0F93, 0x0F50, 0x0041, 0x0FD5, 0x0100, + 0x0F51, 0x00B0, 0x0FE6, 0x0FC5, 0x0F40, 0x0FF2, 0x0FE0, 0x0012, 0x0FE1, + 0x0043, 0x0F61, 0x0FA3, 0x0140, 0x0120, 0x0FB1, 0x0051, 0x0EE0, 0x0F21, + 0x0066, 0x0F03, 0x0F01, 0x0060, 0x0016, 0x0FF6, 0x0FA0, 0x0020, 0x0FF1, + 0x0FD0, 0x0030, 0x0011, 0x0021, 0x0071, 0x00D0, 0x0FE4, 0x0024, 0x0F30, + 0x0080, 0x0123, 0x00A1, 0x0F71, 0x0F00, 0x0180, 0x0EC0, 0x00F3, 0x0F31, + 0x0EF0, 0x0033, 0x0014, 0x0FC0, 0x0F80, 0x0FE3, 0x0FE2, 0x0025, 0x0FC3, + 0x00F0, 0x0053, 0x0075, 0x0F66, 0x0FF4, 0x0040, 0x0F60, 0x0022, 0x00A0, + 0x0ED0, 0x0F13, 0x0181, 0x0F76, 0x0F23, 0x0045, 0x1000, 0x0023, 0x00C0, + 0x0F56, 0x0171, 0x0F10, 0x0FA1, 0x0EB0, 0x0056, 0x0026, 0x0035, 0x0FB5, + 0x0FB3, 0x0EF1, 0x0FF3, 0x0013, 0x0F90, 0x0FA5, 0x0FC2, 0x0F11, 0x0F81, + 0x0110, 0x0042, 0x0061, 0x0FE5, 0x0FF0, + /* Descriptor 5 - 132 entries */ + 0x0010, 0x0F81, 0x0FC5, 0x0F20, 0x0F76, 0x0061, 0x0F41, 0x00D3, 0x0FB3, + 0x0023, 0x0F31, 0x0EC0, 0x00B1, 0x0045, 0x0F50, 0x0FF5, 0x0042, 0x00C1, + 0x0EC1, 0x00D0, 0x0F33, 0x0F93, 0x0FF8, 0x0EF0, 0x0140, 0x0035, 0x0071, + 0x0FD1, 0x0FE3, 0x0FC1, 0x0FF3, 0x0013, 0x0052, 0x0F85, 0x0F51, 0x0046, + 0x0065, 0x0F21, 0x0F30, 0x0041, 0x0031, 0x0034, 0x0FD4, 0x0F43, 0x0032, + 0x0FB5, 0x0FD2, 0x0FE5, 0x0EE0, 0x0120, 0x0F23, 0x0F00, 0x0015, 0x0FE1, + 0x0FE0, 0x0020, 0x1000, 0x0081, 0x0018, 0x0075, 0x0043, 0x00C3, 0x0121, + 0x00A0, 0x0080, 0x0FA0, 0x0060, 0x0FD0, 0x0030, 0x0FF2, 0x0012, 0x0FF1, + 0x0F80, 0x0F91, 0x0141, 0x00A1, 0x0F96, 0x0FB1, 0x00C0, 0x0111, 0x0F66, + 0x00F0, 0x0F40, 0x0FE6, 0x0016, 0x0021, 0x0FC0, 0x0051, 0x00E0, 0x0F86, + 0x0033, 0x0FF6, 0x0F75, 0x0F11, 0x0055, 0x0F61, 0x0FA3, 0x0131, 0x0FD5, + 0x0FA1, 0x0FC3, 0x0024, 0x0056, 0x0FD6, 0x0F60, 0x0011, 0x0040, 0x0025, + 0x0FE4, 0x0103, 0x0091, 0x0026, 0x0F10, 0x0014, 0x0FE2, 0x0022, 0x0070, + 0x0090, 0x0100, 0x0FC2, 0x0151, 0x0FD3, 0x0FF4, 0x0050, 0x0F70, 0x0053, + 0x0110, 0x0F71, 0x00B0, 0x0F90, 0x0FB0, 0x0FF0, + /* Descriptor 6 - 130 entries */ + 0x0010, 0x0FF4, 0x0F96, 0x0F71, 0x00D1, 0x0FF7, 0x00E3, 0x0045, 0x0FC1, + 0x1000, 0x00C0, 0x0042, 0x0120, 0x00A0, 0x0F80, 0x0FD1, 0x0F43, 0x0F63, + 0x0EF0, 0x0F86, 0x0F60, 0x0023, 0x0080, 0x00F0, 0x0FB3, 0x00E0, 0x0063, + 0x0110, 0x0F41, 0x0F93, 0x0FF8, 0x0081, 0x0FF5, 0x0041, 0x0FD2, 0x0F30, + 0x0F81, 0x00B1, 0x00E1, 0x0F00, 0x0031, 0x0060, 0x0035, 0x0F51, 0x0FB5, + 0x0FE3, 0x0FF3, 0x0013, 0x0FE0, 0x0032, 0x0075, 0x0FD4, 0x0046, 0x0F40, + 0x0F91, 0x0FE5, 0x00B3, 0x00C3, 0x0EE1, 0x0F31, 0x0FA0, 0x0FE1, 0x0FD0, + 0x0020, 0x0030, 0x0F10, 0x00A1, 0x0FA3, 0x0033, 0x0111, 0x0FA6, 0x0100, + 0x0F61, 0x0026, 0x0FB1, 0x0061, 0x0025, 0x0F95, 0x0FD6, 0x0036, 0x0034, + 0x0F20, 0x00B0, 0x0121, 0x0018, 0x0131, 0x0051, 0x0FF2, 0x0040, 0x0021, + 0x0FC0, 0x0015, 0x0090, 0x0043, 0x0FC5, 0x0056, 0x0055, 0x0016, 0x0FF1, + 0x0011, 0x0012, 0x0FF6, 0x0F50, 0x0FC2, 0x0053, 0x0F76, 0x0F85, 0x0FD3, + 0x0091, 0x0101, 0x0071, 0x0070, 0x0F90, 0x0FB0, 0x0FC3, 0x0065, 0x00F1, + 0x0F53, 0x00D0, 0x0FE2, 0x0FA1, 0x0024, 0x0FE4, 0x0022, 0x0050, 0x0FE6, + 0x0FD5, 0x0F70, 0x0014, 0x0FF0, + /* Descriptor 7 - 125 entries */ + 0x0010, 0x0022, 0x0FD5, 0x0F71, 0x0F63, 0x0052, 0x0F31, 0x0042, 0x0024, + 0x0FE4, 0x0F86, 0x0F93, 0x00C1, 0x0025, 0x0FD1, 0x0FE6, 0x0F95, 0x00D1, + 0x0FA6, 0x0FD2, 0x00E1, 0x0017, 0x0FF7, 0x0081, 0x0FB3, 0x0046, 0x0014, + 0x0FF4, 0x0FC1, 0x0023, 0x0031, 0x0060, 0x0FA0, 0x0061, 0x00B0, 0x00C3, + 0x0F00, 0x0121, 0x0F80, 0x0FF5, 0x0041, 0x0FF8, 0x0100, 0x0032, 0x0090, + 0x0F81, 0x0F30, 0x0045, 0x0F61, 0x00C0, 0x0063, 0x0FD4, 0x0055, 0x0F70, + 0x0FF3, 0x0FD0, 0x0030, 0x0FE0, 0x0020, 0x0013, 0x0FE1, 0x0FE3, 0x0FB1, + 0x0093, 0x00B1, 0x0026, 0x0F10, 0x00F0, 0x0FA5, 0x0FB5, 0x0070, 0x0F90, + 0x0FC0, 0x0040, 0x0033, 0x0F40, 0x0FE5, 0x00A1, 0x0034, 0x0036, 0x0F96, + 0x0F91, 0x0043, 0x0F01, 0x0053, 0x0FC5, 0x0035, 0x0F51, 0x00A3, 0x0FC2, + 0x0FA3, 0x0F50, 0x00F1, 0x0071, 0x0051, 0x0021, 0x0FF2, 0x0FF1, 0x0012, + 0x0015, 0x0016, 0x00A0, 0x0FD3, 0x0065, 0x0111, 0x0FC3, 0x0091, 0x0018, + 0x0F20, 0x0050, 0x1000, 0x0FF6, 0x0FB0, 0x0FA1, 0x0101, 0x0F53, 0x00E0, + 0x0080, 0x0F60, 0x00D0, 0x0F41, 0x0F73, 0x0FE2, 0x0011, 0x0FF0, + /* Descriptor 8 - 121 entries */ + 0x0010, 0x0F60, 0x0093, 0x00A3, 0x0F95, 0x0018, 0x0FE2, 0x0FA6, 0x0FA1, + 0x0022, 0x0090, 0x0042, 0x0F86, 0x0F93, 0x0036, 0x0FE6, 0x0F50, 0x0FD1, + 0x0060, 0x0FA0, 0x0025, 0x0FD2, 0x0046, 0x0F70, 0x0031, 0x0045, 0x0F40, + 0x0F81, 0x0FB3, 0x0111, 0x0073, 0x0023, 0x0FC1, 0x0FE4, 0x0024, 0x0081, + 0x0FA5, 0x0032, 0x0014, 0x0FF4, 0x0FD0, 0x0030, 0x0041, 0x0070, 0x0FF5, + 0x00E1, 0x0061, 0x0F73, 0x0063, 0x0F41, 0x00B3, 0x0FD5, 0x00F1, 0x0017, + 0x0FF7, 0x00A0, 0x0055, 0x00C1, 0x0F30, 0x0043, 0x0FD4, 0x0065, 0x0FF8, + 0x0FB1, 0x1000, 0x0020, 0x0FE0, 0x0040, 0x0FC0, 0x0FE1, 0x0FF3, 0x0013, + 0x0FE3, 0x0FA3, 0x0083, 0x0F96, 0x00D1, 0x0026, 0x0033, 0x0101, 0x00B1, + 0x0FB6, 0x0F90, 0x0080, 0x00E0, 0x0071, 0x0034, 0x0FC2, 0x0F20, 0x00A1, + 0x0021, 0x0050, 0x00B0, 0x0F71, 0x0FC5, 0x0F91, 0x0F80, 0x0035, 0x0F63, + 0x0053, 0x00C0, 0x0FF1, 0x0FF2, 0x0FB0, 0x0016, 0x0FB5, 0x0F51, 0x0091, + 0x0F21, 0x0FD3, 0x0FC3, 0x00D0, 0x0F83, 0x0F61, 0x0012, 0x0015, 0x0051, + 0x0FE5, 0x0FF6, 0x0011, 0x0FF0, + /* Descriptor 9 - 114 entries */ + 0x0010, 0x0015, 0x0042, 0x0091, 0x0FD2, 0x0036, 0x0FE2, 0x0022, 0x00C0, + 0x0121, 0x0065, 0x0F31, 0x0018, 0x0F60, 0x0FF6, 0x0070, 0x00B0, 0x0045, + 0x0F71, 0x0FD1, 0x0FC1, 0x0FA1, 0x0055, 0x0FB5, 0x0FB2, 0x0F93, 0x0FC5, + 0x0023, 0x0F70, 0x0083, 0x0061, 0x0031, 0x0025, 0x0FA5, 0x0FB3, 0x0032, + 0x0FD5, 0x0081, 0x0F61, 0x0FE4, 0x0F21, 0x0073, 0x0F73, 0x0024, 0x0041, + 0x0030, 0x0FD0, 0x0014, 0x0FF4, 0x0040, 0x0FE0, 0x0FC0, 0x0080, 0x0043, + 0x00E1, 0x00D1, 0x0FE3, 0x1000, 0x0F90, 0x0FE1, 0x0FB1, 0x0026, 0x0FD4, + 0x0063, 0x0034, 0x0FA3, 0x00A3, 0x0F80, 0x0F40, 0x0017, 0x0FF7, 0x0F83, + 0x0FF5, 0x0020, 0x0050, 0x0FB0, 0x0021, 0x0013, 0x0FF3, 0x0FF1, 0x0F51, + 0x0093, 0x0FF8, 0x0F91, 0x0F50, 0x0071, 0x00B1, 0x0051, 0x0033, 0x0090, + 0x00D0, 0x00F1, 0x0FC2, 0x0FE6, 0x0FA6, 0x0FB6, 0x0FA0, 0x0FF2, 0x0060, + 0x0FD3, 0x0F30, 0x00A1, 0x0F96, 0x0053, 0x0035, 0x00A0, 0x0016, 0x00C1, + 0x0FC3, 0x0F81, 0x0FE5, 0x0012, 0x0011, 0x0FF0, + /* Descriptor A - 110 entries */ + 0x0010, 0x0F60, 0x0051, 0x0F90, 0x0FE2, 0x0044, 0x0FA5, 0x0053, 0x00A1, + 0x0035, 0x0022, 0x0026, 0x0073, 0x0080, 0x0FD1, 0x0015, 0x0FE5, 0x0090, + 0x0091, 0x0055, 0x0F73, 0x0F51, 0x00D1, 0x0023, 0x0FA1, 0x0061, 0x0FB3, + 0x0FC5, 0x0031, 0x0FF6, 0x1000, 0x0FD5, 0x0F91, 0x0FC1, 0x0032, 0x0F41, + 0x00B0, 0x00B1, 0x0081, 0x0FB2, 0x0F96, 0x0FD0, 0x0030, 0x0040, 0x0025, + 0x0F81, 0x0F70, 0x0FE3, 0x0FB6, 0x00A0, 0x0018, 0x0FA3, 0x0F31, 0x0FE0, + 0x0FC0, 0x0FB0, 0x0050, 0x0FE1, 0x0014, 0x0F80, 0x0FE6, 0x0FE4, 0x0043, + 0x0083, 0x0024, 0x0FB1, 0x0020, 0x0FF4, 0x0041, 0x0F50, 0x0FF8, 0x0F93, + 0x00C1, 0x0033, 0x0021, 0x0FF5, 0x0060, 0x0063, 0x0034, 0x0FD4, 0x0FC2, + 0x0071, 0x0FC6, 0x0093, 0x0045, 0x0FA6, 0x00C0, 0x0013, 0x0FF1, 0x0FF3, + 0x0F71, 0x00E1, 0x0F40, 0x0FC3, 0x0FB5, 0x0070, 0x0042, 0x0F61, 0x0F83, + 0x0FF7, 0x0017, 0x0FD2, 0x0036, 0x0FD3, 0x0016, 0x0FA0, 0x0FF2, 0x0012, + 0x0011, 0x0FF0, + /* Descriptor B - 101 entries */ + 0x0010, 0x0012, 0x0023, 0x0091, 0x0061, 0x0FA1, 0x0FD1, 0x0015, 0x0030, + 0x0FD0, 0x0FB3, 0x0F71, 0x0F60, 0x0FA6, 0x0063, 0x0032, 0x0FC1, 0x0031, + 0x0040, 0x0080, 0x0FD5, 0x0FE3, 0x0050, 0x0FC0, 0x0FB0, 0x0FF6, 0x0F81, + 0x0FB6, 0x0F70, 0x0F91, 0x0025, 0x1000, 0x0FE1, 0x00A1, 0x0FA3, 0x00F1, + 0x0F61, 0x0F51, 0x0081, 0x00C1, 0x0018, 0x0060, 0x0041, 0x0073, 0x0FE4, + 0x0F80, 0x0FE0, 0x0020, 0x0021, 0x0FC5, 0x0055, 0x0042, 0x0026, 0x0070, + 0x0024, 0x0043, 0x00A0, 0x0033, 0x0FF8, 0x0071, 0x0014, 0x0FF4, 0x0FB1, + 0x0FB5, 0x0034, 0x0F41, 0x0036, 0x0F90, 0x0FC6, 0x0090, 0x0FF5, 0x0FA0, + 0x0FD4, 0x0F83, 0x0083, 0x0051, 0x00B1, 0x0FD3, 0x0FF1, 0x0013, 0x0FF3, + 0x0FF2, 0x0035, 0x0045, 0x0FC2, 0x00D1, 0x0FE2, 0x0016, 0x0FC3, 0x0FD2, + 0x00B0, 0x0FE6, 0x0F93, 0x0F50, 0x0FF7, 0x0017, 0x0053, 0x0022, 0x0FE5, + 0x0011, 0x0FF0, + /* Descriptor C - 96 entries */ + 0x0010, 0x0012, 0x0FC3, 0x00B1, 0x00A1, 0x0022, 0x0FE5, 0x0F93, 0x0090, + 0x0061, 0x0055, 0x0042, 0x0FE6, 0x0040, 0x0030, 0x0FD1, 0x0050, 0x0015, + 0x0FD0, 0x0FC0, 0x0023, 0x0FC1, 0x0017, 0x00C1, 0x0032, 0x0FB5, 0x0FF7, + 0x00A0, 0x0060, 0x0031, 0x0041, 0x0FE3, 0x0FD5, 0x0091, 0x0053, 0x0FF8, + 0x0FA0, 0x0FF6, 0x0FB0, 0x0070, 0x0080, 0x1000, 0x0FE1, 0x0FE0, 0x0020, + 0x0021, 0x0063, 0x0033, 0x0FA1, 0x0F60, 0x0F61, 0x0043, 0x0073, 0x0FC6, + 0x0FE4, 0x00E1, 0x0034, 0x0018, 0x0F91, 0x0F80, 0x0024, 0x0026, 0x0014, + 0x0FF4, 0x0FB1, 0x0FB6, 0x0071, 0x0FA6, 0x0FD4, 0x0035, 0x0F70, 0x0036, + 0x0051, 0x0FF5, 0x0FF1, 0x0FD3, 0x0045, 0x0F81, 0x0F90, 0x0083, 0x0081, + 0x0FA3, 0x0FE2, 0x0FC5, 0x0F51, 0x0F71, 0x0FD2, 0x0FB3, 0x0FC2, 0x0025, + 0x0016, 0x0013, 0x0FF3, 0x0FF2, 0x0011, 0x0FF0, }; -static const uint8_t tscc2_nc_vlc_bits[NUM_VLC_SETS][16] = { - { 6, 6, 6, 6, 6, 7, 7, 6, 6, 6, 6, 5, 4, 3, 3, 1 }, - { 6, 6, 6, 6, 6, 6, 7, 7, 6, 6, 6, 5, 4, 3, 3, 1 }, - { 7, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 5, 4, 3, 3, 1 }, - { 7, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 4, 3, 3, 1 }, - { 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 4, 3, 3, 1 }, - { 8, 8, 7, 7, 7, 6, 7, 7, 6, 6, 6, 6, 4, 4, 2, 1 }, - { 8, 8, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 4, 4, 2, 1 }, - { 8, 8, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 4, 4, 2, 1 }, - { 8, 8, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 4, 4, 2, 1 }, - { 9, 9, 8, 7, 7, 7, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1 }, - { 9, 9, 8, 7, 7, 7, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1 }, - { 9, 9, 8, 7, 7, 7, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1 }, - { 9, 9, 8, 7, 7, 7, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1 }, -}; - -static const uint16_t ac_vlc_desc0_syms[172] = { - 0x1000, 0xFF8, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, 0xFF1, - 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, 0xFE0, - 0xFD6, 0xFD5, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC6, 0xFC5, - 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB5, 0xFB3, 0xFB2, 0xFB1, - 0xFB0, 0xFA5, 0xFA3, 0xFA1, 0xFA0, 0xF95, 0xF91, 0xF90, - 0xF83, 0xF81, 0xF80, 0xF73, 0xF71, 0xF70, 0xF61, 0xF60, - 0xF51, 0xF50, 0xF45, 0xF41, 0xF40, 0xF31, 0xF30, 0xF21, - 0xF20, 0xF10, 0xF00, 0xEF0, 0xEE0, 0xED5, 0xED1, 0xED0, - 0xEC0, 0xEB0, 0xEA0, 0xE90, 0xE80, 0xE70, 0xE60, 0xE50, - 0xE40, 0xE30, 0xE20, 0xE10, 0xE00, 0xDF0, 0xDE0, 0xDD0, - 0xDC0, 0xDB0, 0xDA0, 0xD90, 0xD80, 0xD60, 0xCD1, 0x280, - 0x270, 0x260, 0x250, 0x240, 0x230, 0x220, 0x210, 0x200, - 0x1F0, 0x1E0, 0x1D0, 0x1C0, 0x1B0, 0x1A1, 0x1A0, 0x190, - 0x180, 0x170, 0x160, 0x150, 0x140, 0x130, 0x121, 0x120, - 0x111, 0x110, 0x101, 0x100, 0x0F1, 0x0F0, 0x0E1, 0x0E0, - 0x0D1, 0x0D0, 0x0C1, 0x0C0, 0x0B1, 0x0B0, 0x0A5, 0x0A1, - 0x0A0, 0x091, 0x090, 0x081, 0x080, 0x075, 0x071, 0x070, - 0x065, 0x063, 0x061, 0x060, 0x055, 0x053, 0x052, 0x051, - 0x050, 0x046, 0x045, 0x043, 0x042, 0x041, 0x040, 0x036, - 0x035, 0x033, 0x032, 0x031, 0x030, 0x026, 0x025, 0x024, - 0x023, 0x022, 0x021, 0x020, 0x018, 0x016, 0x015, 0x014, - 0x013, 0x012, 0x011, 0x010, -}; - -static const uint16_t ac_vlc_desc0_codes[172] = { - 0x001F, 0x0D71, 0x013F, 0x006C, 0x00A7, 0x0067, 0x001C, 0x0008, - 0x0005, 0x06F1, 0x002C, 0x04BA, 0x0072, 0x01AA, 0x0002, 0x0006, - 0x06AC, 0x02AF, 0x06EF, 0x018F, 0x000A, 0x0009, 0x02AC, 0x042A, - 0x06E1, 0x068F, 0x00B1, 0x0000, 0x0317, 0x0C17, 0x0612, 0x010F, - 0x0011, 0x0FBA, 0x002A, 0x0172, 0x000C, 0x05AC, 0x03D7, 0x0037, - 0x0E8F, 0x02F2, 0x0041, 0x0BE1, 0x057F, 0x004A, 0x00AF, 0x006F, - 0x06AA, 0x0097, 0x0101, 0x0012, 0x0081, 0x0571, 0x0092, 0x0EAF, - 0x01BF, 0x00D7, 0x0031, 0x0001, 0x01F2, 0x0F17, 0x053A, 0x00BF, - 0x038F, 0x0217, 0x0371, 0x01F1, 0x01BA, 0x022A, 0x02BF, 0x028F, - 0x008F, 0x03F1, 0x00E1, 0x00BA, 0x00F2, 0x0EBF, 0x06AF, 0x048F, - 0x0FE1, 0x0271, 0x07BA, 0x0D3A, 0x0C12, 0x08AC, 0x0717, 0x00AC, - 0x0412, 0x0901, 0x04E1, 0x07E1, 0x0417, 0x0CAF, 0x04AC, 0x01AC, - 0x04F2, 0x03BA, 0x05D7, 0x07F1, 0x01D7, 0x04AF, 0x04EF, 0x03AC, - 0x00AA, 0x01E1, 0x0071, 0x00F1, 0x012C, 0x03EF, 0x082A, 0x0112, - 0x03E1, 0x01FA, 0x0DAC, 0x0131, 0x0E12, 0x000F, 0x0B17, 0x007F, - 0x0AEF, 0x007A, 0x02AA, 0x0061, 0x0671, 0x0027, 0x013A, 0x058F, - 0x00FF, 0x033A, 0x0032, 0x0301, 0x0021, 0x0C8F, 0x037F, 0x0077, - 0x02F1, 0x02E1, 0x003A, 0x003C, 0x0212, 0x0817, 0x0CE1, 0x003F, - 0x0007, 0x0017, 0x0501, 0x02BA, 0x06BF, 0x0057, 0x0010, 0x02EF, - 0x0117, 0x017F, 0x00EF, 0x006A, 0x0019, 0x0171, 0x01EF, 0x06BA, - 0x012A, 0x00FA, 0x0022, 0x000E, 0x0AE1, 0x01AF, 0x0052, 0x002F, - 0x004F, 0x001A, 0x0004, 0x0003, -}; - -static const uint8_t ac_vlc_desc0_bits[172] = { - 6, 12, 9, 7, 8, 7, 6, 4, - 3, 11, 9, 11, 9, 9, 6, 4, - 11, 11, 11, 11, 7, 5, 11, 11, - 11, 12, 8, 5, 12, 12, 12, 9, - 6, 12, 12, 9, 6, 12, 10, 7, - 12, 10, 7, 12, 11, 7, 11, 8, - 11, 8, 12, 11, 8, 12, 8, 12, - 9, 9, 9, 9, 9, 12, 12, 10, - 10, 10, 10, 10, 10, 10, 11, 11, - 11, 11, 11, 11, 11, 12, 12, 12, - 12, 11, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 11, 11, - 11, 11, 11, 11, 11, 12, 11, 10, - 10, 10, 10, 10, 9, 10, 12, 9, - 12, 9, 12, 9, 12, 9, 12, 9, - 12, 8, 11, 8, 11, 8, 11, 11, - 8, 10, 7, 10, 7, 12, 10, 7, - 11, 12, 9, 6, 11, 12, 12, 9, - 6, 12, 11, 11, 12, 8, 5, 12, - 10, 11, 11, 7, 5, 11, 10, 11, - 9, 9, 6, 4, 12, 9, 7, 8, - 7, 6, 4, 3, -}; - -static const uint16_t ac_vlc_desc1_syms[169] = { - 0x1000, 0xFF8, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, 0xFF1, - 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, 0xFE0, - 0xFD6, 0xFD5, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC6, 0xFC5, - 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB6, 0xFB5, 0xFB3, 0xFB2, - 0xFB1, 0xFB0, 0xFA6, 0xFA5, 0xFA3, 0xFA1, 0xFA0, 0xF95, - 0xF93, 0xF91, 0xF90, 0xF85, 0xF81, 0xF80, 0xF71, 0xF70, - 0xF61, 0xF60, 0xF51, 0xF50, 0xF45, 0xF41, 0xF40, 0xF31, - 0xF30, 0xF21, 0xF20, 0xF11, 0xF10, 0xF01, 0xF00, 0xEF1, - 0xEF0, 0xEE1, 0xEE0, 0xED0, 0xEC6, 0xEC0, 0xEB6, 0xEB0, - 0xEA0, 0xE90, 0xE80, 0xE70, 0xE60, 0xE50, 0xE40, 0xE33, - 0xE31, 0xE30, 0xE20, 0xE10, 0xE00, 0xDF0, 0xDE1, 0xDE0, - 0xDC0, 0xDB0, 0xDA0, 0x250, 0x240, 0x1F0, 0x1E0, 0x1D0, - 0x1C0, 0x1B0, 0x1A0, 0x190, 0x180, 0x170, 0x160, 0x150, - 0x140, 0x130, 0x120, 0x111, 0x110, 0x101, 0x100, 0x0F1, - 0x0F0, 0x0E1, 0x0E0, 0x0D1, 0x0D0, 0x0C6, 0x0C1, 0x0C0, - 0x0B1, 0x0B0, 0x0A1, 0x0A0, 0x095, 0x091, 0x090, 0x085, - 0x081, 0x080, 0x075, 0x071, 0x070, 0x065, 0x063, 0x061, - 0x060, 0x055, 0x053, 0x052, 0x051, 0x050, 0x046, 0x045, - 0x043, 0x042, 0x041, 0x040, 0x036, 0x035, 0x033, 0x032, - 0x031, 0x030, 0x026, 0x025, 0x024, 0x023, 0x022, 0x021, - 0x020, 0x018, 0x016, 0x015, 0x014, 0x013, 0x012, 0x011, - 0x010, -}; - -static const uint16_t ac_vlc_desc1_codes[169] = { - 0x0019, 0x027D, 0x0084, 0x0044, 0x009D, 0x003D, 0x000A, 0x0002, - 0x0003, 0x00EA, 0x02FD, 0x017A, 0x01C6, 0x00B6, 0x0026, 0x000E, - 0x0095, 0x0260, 0x032A, 0x0360, 0x0006, 0x0005, 0x05B6, 0x036A, - 0x06F6, 0x0704, 0x00FA, 0x0010, 0x0279, 0x04D4, 0x00F6, 0x066A, - 0x001D, 0x0029, 0x05F9, 0x0846, 0x04F6, 0x01D4, 0x0038, 0x0446, - 0x0160, 0x031D, 0x0075, 0x0054, 0x02D4, 0x005A, 0x05FD, 0x0040, - 0x06EA, 0x0055, 0x0460, 0x009A, 0x052A, 0x00A0, 0x00D8, 0x0380, - 0x017D, 0x092A, 0x00F9, 0x0D7A, 0x0179, 0x0304, 0x002A, 0x0104, - 0x01A0, 0x0780, 0x007D, 0x03F9, 0x0C46, 0x03EA, 0x0E6A, 0x0204, - 0x01FD, 0x051D, 0x02AA, 0x05EA, 0x00AA, 0x0080, 0x067D, 0x09EA, - 0x0C95, 0x09F9, 0x07B6, 0x0DB6, 0x012A, 0x0904, 0x0454, 0x0FB6, - 0x0960, 0x08D4, 0x0495, 0x0F80, 0x0560, 0x0B04, 0x057A, 0x0079, - 0x0795, 0x0E7D, 0x0060, 0x076A, 0x03B6, 0x0395, 0x0180, 0x02A0, - 0x006A, 0x0195, 0x0295, 0x0646, 0x03FD, 0x01F9, 0x0154, 0x0DF9, - 0x00C6, 0x0F95, 0x01F6, 0x0480, 0x0000, 0x0A79, 0x04AA, 0x00E0, - 0x0246, 0x001A, 0x0479, 0x0015, 0x0D60, 0x0280, 0x0018, 0x01EA, - 0x037A, 0x003A, 0x011D, 0x00FD, 0x0035, 0x0A7D, 0x04A0, 0x0146, - 0x0024, 0x01B6, 0x0504, 0x0046, 0x0020, 0x0009, 0x00D4, 0x03AA, - 0x0679, 0x026A, 0x0036, 0x0008, 0x02F6, 0x01AA, 0x016A, 0x0254, - 0x0039, 0x000D, 0x0004, 0x0176, 0x02EA, 0x007A, 0x0076, 0x0016, - 0x0001, 0x0879, 0x0058, 0x0014, 0x00D5, 0x005D, 0x0034, 0x000C, - 0x0007, -}; - -static const uint8_t ac_vlc_desc1_bits[169] = { - 6, 12, 8, 7, 8, 7, 6, 4, - 3, 10, 10, 11, 9, 9, 6, 4, - 11, 10, 10, 10, 7, 5, 12, 11, - 11, 11, 8, 5, 12, 11, 11, 12, - 9, 6, 12, 12, 11, 9, 6, 12, - 12, 10, 7, 11, 10, 7, 11, 7, - 11, 8, 11, 8, 11, 11, 8, 11, - 9, 12, 9, 12, 9, 12, 9, 12, - 9, 12, 10, 10, 12, 10, 12, 10, - 11, 11, 10, 11, 11, 11, 12, 12, - 12, 12, 12, 12, 12, 12, 11, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 11, 11, 11, 11, 10, 10, - 10, 10, 10, 11, 10, 12, 9, 12, - 9, 12, 9, 11, 8, 12, 11, 8, - 11, 8, 11, 8, 12, 10, 7, 12, - 10, 7, 11, 10, 7, 12, 11, 9, - 6, 11, 11, 12, 8, 6, 12, 10, - 11, 11, 8, 5, 11, 10, 10, 10, - 7, 5, 10, 9, 11, 9, 9, 6, - 4, 12, 8, 7, 8, 7, 6, 4, - 3, -}; - -static const uint16_t ac_vlc_desc2_syms[165] = { - 0x1000, 0xFF8, 0xFF7, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, - 0xFF1, 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, - 0xFE0, 0xFD6, 0xFD5, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC6, - 0xFC5, 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB6, 0xFB5, 0xFB3, - 0xFB2, 0xFB1, 0xFB0, 0xFA5, 0xFA3, 0xFA1, 0xFA0, 0xF95, - 0xF93, 0xF91, 0xF90, 0xF81, 0xF80, 0xF75, 0xF71, 0xF70, - 0xF61, 0xF60, 0xF51, 0xF50, 0xF41, 0xF40, 0xF36, 0xF31, - 0xF30, 0xF26, 0xF21, 0xF20, 0xF16, 0xF11, 0xF10, 0xF06, - 0xF01, 0xF00, 0xEF1, 0xEF0, 0xEE1, 0xEE0, 0xED0, 0xEC0, - 0xEB3, 0xEB1, 0xEB0, 0xEA3, 0xEA1, 0xEA0, 0xE90, 0xE81, - 0xE80, 0xE71, 0xE70, 0xE61, 0xE60, 0xE50, 0xE40, 0xE30, - 0xE10, 0xE00, 0x241, 0x240, 0x231, 0x1D0, 0x1C0, 0x1B3, - 0x1B0, 0x1A0, 0x190, 0x180, 0x170, 0x160, 0x150, 0x140, - 0x130, 0x120, 0x110, 0x100, 0x0F0, 0x0E0, 0x0D1, 0x0D0, - 0x0C1, 0x0C0, 0x0B1, 0x0B0, 0x0A5, 0x0A1, 0x0A0, 0x096, - 0x095, 0x091, 0x090, 0x086, 0x085, 0x081, 0x080, 0x075, - 0x071, 0x070, 0x065, 0x063, 0x061, 0x060, 0x055, 0x053, - 0x052, 0x051, 0x050, 0x045, 0x043, 0x042, 0x041, 0x040, - 0x036, 0x035, 0x033, 0x032, 0x031, 0x030, 0x026, 0x025, - 0x024, 0x023, 0x022, 0x021, 0x020, 0x018, 0x016, 0x015, - 0x014, 0x013, 0x012, 0x011, 0x010, -}; - -static const uint16_t ac_vlc_desc2_codes[165] = { - 0x0034, 0x059C, 0x0280, 0x001C, 0x004C, 0x00BD, 0x0020, 0x003C, - 0x000A, 0x0003, 0x00FD, 0x008C, 0x0332, 0x01D5, 0x0055, 0x003E, - 0x0001, 0x07E4, 0x0264, 0x00B2, 0x00A2, 0x005C, 0x0005, 0x02A2, - 0x011D, 0x0132, 0x076C, 0x0012, 0x0018, 0x01E4, 0x05E4, 0x02B2, - 0x0432, 0x017D, 0x000E, 0x055D, 0x0955, 0x0164, 0x0028, 0x0D62, - 0x0B24, 0x02DE, 0x001E, 0x0340, 0x0014, 0x0555, 0x0180, 0x00DD, - 0x01B2, 0x0092, 0x036C, 0x00EC, 0x00E4, 0x00C0, 0x0C64, 0x095D, - 0x01DE, 0x0AE4, 0x0C32, 0x01A2, 0x06E4, 0x0832, 0x01A4, 0x015D, - 0x0732, 0x031D, 0x0F9C, 0x03E2, 0x09E2, 0x02FD, 0x0224, 0x051D, - 0x02E4, 0x019C, 0x05B2, 0x0355, 0x0064, 0x016C, 0x038C, 0x0880, - 0x0480, 0x06B2, 0x0540, 0x0080, 0x075D, 0x0155, 0x0424, 0x0680, - 0x0A62, 0x0A80, 0x078C, 0x0D9C, 0x0F8C, 0x0562, 0x0FF2, 0x0464, - 0x0B55, 0x01E2, 0x0032, 0x07F2, 0x0140, 0x03E4, 0x0662, 0x0755, - 0x0380, 0x026C, 0x0232, 0x001D, 0x0040, 0x00E2, 0x035D, 0x00F2, - 0x0162, 0x01FD, 0x03F2, 0x000C, 0x0EA2, 0x05F2, 0x0072, 0x04E4, - 0x0F32, 0x018C, 0x009D, 0x0324, 0x079C, 0x006C, 0x0054, 0x0F5D, - 0x021D, 0x0015, 0x0024, 0x06A2, 0x009C, 0x0004, 0x0062, 0x056C, - 0x0262, 0x0000, 0x002E, 0x01F2, 0x0124, 0x039C, 0x005E, 0x0010, - 0x0724, 0x00A4, 0x00DE, 0x0362, 0x0052, 0x000D, 0x03B2, 0x007D, - 0x05E2, 0x00D5, 0x005D, 0x0035, 0x0009, 0x099C, 0x0022, 0x002C, - 0x003D, 0x0008, 0x0002, 0x0006, 0x0007, -}; - -static const uint8_t ac_vlc_desc2_bits[165] = { - 6, 12, 12, 8, 7, 8, 6, 6, - 4, 3, 10, 9, 11, 9, 9, 6, - 4, 11, 10, 10, 10, 7, 5, 11, - 11, 10, 11, 8, 5, 11, 11, 11, - 12, 9, 6, 11, 12, 9, 6, 12, - 12, 10, 7, 10, 7, 11, 10, 8, - 11, 8, 11, 8, 11, 8, 12, 12, - 9, 12, 12, 9, 11, 12, 9, 12, - 12, 10, 12, 10, 12, 10, 10, 11, - 12, 12, 11, 12, 11, 11, 11, 12, - 11, 11, 11, 12, 12, 12, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 11, 11, 11, 11, - 10, 10, 10, 10, 9, 9, 11, 9, - 11, 9, 11, 8, 12, 11, 8, 11, - 12, 10, 8, 12, 12, 10, 7, 12, - 10, 7, 11, 12, 9, 6, 10, 11, - 12, 8, 6, 11, 10, 11, 8, 5, - 11, 9, 10, 10, 7, 5, 10, 9, - 11, 9, 9, 6, 4, 12, 8, 7, - 8, 6, 6, 4, 3, -}; - -static const uint16_t ac_vlc_desc3_syms[162] = { - 0x1000, 0xFF8, 0xFF7, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, - 0xFF1, 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, - 0xFE0, 0xFD6, 0xFD5, 0xFD4, 0xFD3, 0xFD2, 0xFD1, 0xFD0, - 0xFC6, 0xFC5, 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB5, 0xFB3, - 0xFB2, 0xFB1, 0xFB0, 0xFA5, 0xFA3, 0xFA1, 0xFA0, 0xF95, - 0xF93, 0xF91, 0xF90, 0xF85, 0xF83, 0xF81, 0xF80, 0xF71, - 0xF70, 0xF66, 0xF61, 0xF60, 0xF56, 0xF51, 0xF50, 0xF46, - 0xF41, 0xF40, 0xF36, 0xF31, 0xF30, 0xF26, 0xF21, 0xF20, - 0xF11, 0xF10, 0xF01, 0xF00, 0xEF3, 0xEF1, 0xEF0, 0xEE3, - 0xEE1, 0xEE0, 0xED3, 0xED1, 0xED0, 0xEC1, 0xEC0, 0xEB1, - 0xEB0, 0xEA0, 0xE90, 0xE80, 0xE70, 0x1E1, 0x1D1, 0x1D0, - 0x1C1, 0x1B1, 0x1A1, 0x180, 0x170, 0x163, 0x160, 0x150, - 0x140, 0x130, 0x123, 0x120, 0x113, 0x110, 0x100, 0x0F0, - 0x0E0, 0x0D1, 0x0D0, 0x0C1, 0x0C0, 0x0B1, 0x0B0, 0x0A1, - 0x0A0, 0x095, 0x091, 0x090, 0x085, 0x081, 0x080, 0x076, - 0x075, 0x073, 0x071, 0x070, 0x066, 0x065, 0x063, 0x061, - 0x060, 0x055, 0x053, 0x052, 0x051, 0x050, 0x045, 0x043, - 0x042, 0x041, 0x040, 0x036, 0x035, 0x034, 0x033, 0x032, - 0x031, 0x030, 0x026, 0x025, 0x024, 0x023, 0x022, 0x021, - 0x020, 0x018, 0x017, 0x016, 0x015, 0x014, 0x013, 0x012, - 0x011, 0x010, -}; - -static const uint16_t ac_vlc_desc3_codes[162] = { - 0x001D, 0x087C, 0x0AE8, 0x003A, 0x001C, 0x0008, 0x000C, 0x0032, - 0x0006, 0x0003, 0x03A5, 0x01EC, 0x01A5, 0x0080, 0x0030, 0x0005, - 0x0001, 0x0040, 0x03FC, 0x02D4, 0x0154, 0x02FC, 0x003C, 0x0015, - 0x051A, 0x0000, 0x02EC, 0x077C, 0x00D2, 0x0018, 0x03E8, 0x04EC, - 0x027C, 0x01FA, 0x0022, 0x0765, 0x0EA5, 0x0054, 0x0010, 0x08EC, - 0x0AAC, 0x03BA, 0x0042, 0x065D, 0x0AD4, 0x005C, 0x0028, 0x03C0, - 0x00E5, 0x035C, 0x04FA, 0x00DC, 0x06A5, 0x075C, 0x00C8, 0x05A5, - 0x04D4, 0x00BA, 0x01C0, 0x05E8, 0x012C, 0x00E8, 0x01B0, 0x00B0, - 0x025D, 0x002C, 0x0A52, 0x025C, 0x01E8, 0x00FA, 0x0348, 0x0652, - 0x0B7C, 0x0365, 0x031A, 0x0E52, 0x011A, 0x0200, 0x01BA, 0x02AC, - 0x06D4, 0x01FC, 0x05BA, 0x0DFC, 0x0248, 0x0EE8, 0x0B1A, 0x0CFC, - 0x0F65, 0x0B5C, 0x0DC0, 0x007C, 0x0548, 0x08A5, 0x00FC, 0x03B0, - 0x0148, 0x06AC, 0x0252, 0x071A, 0x02E8, 0x0240, 0x00AC, 0x021A, - 0x0140, 0x08E8, 0x01AC, 0x00EC, 0x0152, 0x00A5, 0x0068, 0x001A, - 0x006C, 0x05C0, 0x015C, 0x0025, 0x05B0, 0x017C, 0x0014, 0x047C, - 0x00D4, 0x06E8, 0x00C0, 0x0002, 0x0A5D, 0x04E8, 0x0A7C, 0x01D4, - 0x0020, 0x04A5, 0x07B0, 0x037C, 0x015D, 0x002A, 0x005D, 0x0048, - 0x067C, 0x007A, 0x0004, 0x04FC, 0x02FA, 0x0648, 0x0100, 0x0052, - 0x005A, 0x000D, 0x0165, 0x0065, 0x02A5, 0x0070, 0x00F0, 0x003D, - 0x0009, 0x05FC, 0x0E48, 0x009A, 0x0012, 0x00DD, 0x0034, 0x000A, - 0x000E, 0x0007, -}; - -static const uint8_t ac_vlc_desc3_bits[162] = { - 7, 12, 12, 8, 7, 7, 6, 6, - 4, 3, 10, 9, 11, 8, 8, 6, - 4, 10, 10, 12, 9, 10, 7, 5, - 11, 10, 10, 11, 8, 5, 10, 11, - 12, 9, 6, 12, 12, 9, 6, 12, - 12, 10, 7, 11, 12, 10, 7, 10, - 8, 12, 11, 8, 12, 11, 8, 11, - 11, 9, 11, 11, 9, 12, 11, 9, - 12, 9, 12, 10, 11, 11, 10, 12, - 12, 11, 12, 12, 11, 10, 11, 12, - 11, 11, 11, 12, 11, 12, 12, 12, - 12, 12, 12, 12, 11, 12, 11, 11, - 11, 11, 12, 11, 12, 10, 10, 10, - 9, 12, 9, 12, 9, 12, 8, 10, - 8, 12, 10, 8, 11, 10, 7, 11, - 11, 12, 9, 7, 12, 11, 12, 9, - 6, 11, 11, 12, 9, 6, 10, 10, - 11, 8, 5, 12, 10, 12, 9, 10, - 7, 5, 10, 9, 11, 8, 8, 6, - 4, 12, 12, 8, 7, 8, 6, 6, +static const uint8_t tscc2_ac_vlc_lens[] = { + /* Descriptor 0 - 172 entries */ + 5, 5, 4, 4, 6, 9, 9, 12, 12, 11, 11, 11, 11, 12, 12, 10, 7, 6, + 6, 6, 6, 11, 12, 12, 11, 12, 12, 9, 8, 7, 7, 9, 9, 11, 11, 10, + 9, 7, 7, 12, 12, 11, 10, 9, 10, 11, 11, 9, 7, 6, 9, 11, 12, 12, + 10, 11, 11, 11, 11, 10, 11, 12, 12, 8, 9, 9, 4, 4, 9, 12, 12, 11, + 10, 8, 7, 7, 8, 11, 12, 12, 12, 12, 11, 10, 12, 12, 12, 12, 6, 9, + 9, 8, 10, 11, 11, 11, 12, 12, 10, 10, 11, 11, 10, 11, 11, 5, 5, 3, + 3, 6, 8, 8, 7, 12, 12, 12, 12, 10, 10, 12, 12, 12, 12, 8, 8, 9, + 11, 11, 10, 7, 7, 9, 9, 11, 12, 12, 11, 12, 12, 11, 11, 10, 7, 8, + 11, 12, 12, 11, 12, 12, 9, 8, 11, 11, 12, 12, 11, 10, 10, 6, 9, 9, + 10, 11, 12, 12, 9, 9, 11, 11, 10, 8, + /* Descriptor 1 - 169 entries */ + 8, 11, 11, 10, 10, 11, 12, 12, 7, 8, 11, 11, 10, 9, 11, 11, 10, 12, + 12, 12, 12, 10, 8, 5, 5, 7, 8, 8, 6, 10, 10, 12, 12, 11, 12, 12, + 11, 8, 7, 6, 7, 11, 11, 10, 9, 12, 12, 11, 10, 9, 6, 4, 4, 6, + 9, 12, 12, 11, 10, 11, 11, 10, 10, 10, 10, 11, 12, 12, 10, 11, 11, 10, + 11, 11, 12, 12, 11, 10, 8, 8, 7, 7, 9, 11, 12, 12, 10, 8, 7, 12, + 12, 12, 12, 11, 11, 9, 9, 9, 6, 6, 8, 9, 11, 12, 12, 11, 12, 12, + 9, 9, 11, 11, 11, 11, 9, 4, 4, 6, 6, 6, 7, 12, 12, 11, 12, 12, + 11, 9, 9, 12, 12, 12, 12, 10, 5, 8, 11, 12, 12, 10, 10, 11, 12, 12, + 8, 8, 7, 7, 5, 9, 11, 11, 10, 8, 7, 7, 10, 12, 12, 12, 12, 9, + 10, 10, 11, 11, 10, 3, 3, + /* Descriptor 2 - 165 entries */ + 8, 12, 12, 11, 12, 12, 11, 10, 10, 9, 11, 11, 10, 8, 6, 5, 6, 6, + 5, 6, 11, 11, 10, 10, 12, 12, 11, 9, 9, 11, 12, 12, 10, 9, 11, 11, + 12, 12, 11, 11, 11, 11, 11, 7, 7, 6, 8, 9, 10, 11, 12, 12, 7, 7, + 10, 10, 11, 11, 11, 11, 8, 8, 9, 12, 12, 12, 12, 11, 12, 12, 7, 6, + 6, 8, 10, 11, 12, 12, 9, 10, 12, 12, 11, 11, 12, 12, 10, 9, 12, 12, + 11, 10, 8, 8, 7, 12, 12, 12, 12, 10, 10, 11, 12, 12, 10, 11, 11, 11, + 11, 10, 8, 9, 11, 11, 11, 12, 12, 4, 4, 6, 6, 7, 8, 10, 10, 9, + 6, 4, 4, 5, 7, 9, 12, 12, 11, 12, 12, 11, 9, 9, 6, 5, 10, 10, + 11, 11, 10, 8, 9, 12, 12, 11, 11, 12, 12, 8, 8, 8, 9, 9, 10, 10, + 9, 3, 3, + /* Descriptor 3 - 162 entries */ + 10, 10, 9, 8, 10, 10, 9, 9, 11, 12, 12, 10, 6, 6, 8, 9, 11, 11, + 11, 11, 8, 8, 7, 10, 11, 12, 12, 11, 11, 10, 8, 7, 8, 12, 12, 11, + 12, 12, 12, 12, 11, 11, 10, 5, 5, 7, 9, 9, 11, 11, 12, 12, 11, 9, + 6, 6, 9, 9, 10, 12, 12, 11, 9, 8, 12, 12, 11, 10, 9, 7, 10, 10, + 10, 12, 12, 11, 8, 7, 12, 12, 11, 12, 12, 11, 10, 12, 12, 11, 11, 12, + 12, 10, 11, 12, 12, 10, 7, 7, 6, 7, 10, 12, 12, 12, 12, 9, 8, 6, + 6, 6, 10, 10, 11, 11, 12, 12, 11, 8, 7, 8, 9, 11, 11, 10, 8, 11, + 11, 10, 9, 4, 4, 4, 4, 6, 8, 12, 12, 11, 11, 12, 12, 11, 11, 10, + 9, 10, 11, 12, 12, 8, 5, 5, 7, 10, 12, 12, 11, 9, 8, 6, 3, 3, + /* Descriptor 4 - 131 entries */ + 2, 6, 6, 7, 7, 8, 8, 7, 10, 12, 12, 11, 10, 10, 8, 9, 10, 10, + 11, 12, 12, 10, 10, 10, 7, 7, 11, 12, 12, 11, 12, 12, 9, 8, 10, 11, + 11, 9, 10, 10, 9, 6, 4, 6, 6, 11, 11, 12, 12, 11, 9, 9, 11, 11, + 11, 12, 12, 7, 8, 8, 7, 4, 4, 5, 5, 4, 6, 10, 10, 11, 11, 10, + 8, 12, 12, 11, 11, 12, 12, 12, 12, 11, 10, 8, 6, 8, 9, 9, 9, 11, + 11, 12, 12, 11, 8, 6, 9, 9, 9, 11, 12, 12, 12, 12, 11, 7, 9, 10, + 12, 12, 11, 10, 12, 12, 11, 10, 12, 12, 11, 7, 7, 8, 11, 12, 12, 11, + 12, 12, 10, 10, 3, + /* Descriptor 5 - 132 entries */ + 2, 10, 10, 10, 10, 9, 10, 11, 11, 8, 11, 12, 12, 10, 9, 7, 11, 12, + 12, 10, 11, 12, 12, 11, 11, 9, 9, 7, 8, 8, 6, 6, 12, 12, 11, 11, + 11, 10, 10, 8, 7, 12, 12, 11, 10, 10, 10, 9, 11, 12, 12, 10, 7, 6, + 4, 4, 7, 11, 12, 12, 11, 12, 12, 9, 8, 7, 7, 5, 5, 6, 6, 4, + 8, 10, 11, 12, 12, 9, 10, 12, 12, 11, 10, 10, 8, 6, 6, 9, 11, 11, + 10, 8, 12, 12, 11, 11, 12, 12, 10, 10, 11, 11, 11, 11, 9, 4, 6, 9, + 11, 12, 12, 11, 11, 8, 9, 9, 8, 9, 11, 12, 12, 10, 8, 7, 9, 12, + 12, 11, 10, 8, 7, 3, + /* Descriptor 6 - 130 entries */ + 2, 7, 10, 10, 12, 12, 11, 10, 8, 7, 10, 11, 11, 9, 8, 7, 11, 12, + 12, 10, 9, 8, 8, 11, 11, 10, 12, 12, 11, 12, 12, 11, 7, 8, 10, 10, + 10, 12, 12, 11, 7, 7, 9, 10, 10, 8, 6, 6, 4, 10, 12, 12, 11, 10, + 10, 9, 11, 12, 12, 10, 7, 6, 5, 4, 5, 11, 12, 12, 10, 11, 12, 12, + 11, 11, 9, 9, 9, 12, 12, 12, 12, 10, 10, 11, 12, 12, 9, 6, 6, 6, + 6, 7, 9, 11, 11, 11, 11, 8, 4, 4, 6, 8, 10, 12, 12, 12, 12, 10, + 12, 12, 11, 8, 8, 7, 11, 12, 12, 11, 11, 9, 10, 11, 11, 9, 7, 10, + 10, 9, 8, 3, + /* Descriptor 7 - 125 entries */ + 2, 8, 9, 10, 10, 12, 12, 11, 10, 10, 11, 12, 12, 8, 7, 9, 11, 11, + 10, 10, 11, 12, 12, 11, 11, 10, 7, 7, 8, 8, 7, 7, 7, 9, 10, 11, + 12, 12, 8, 7, 8, 11, 11, 10, 9, 10, 10, 10, 10, 10, 12, 12, 11, 9, + 6, 5, 5, 4, 4, 6, 6, 8, 9, 12, 12, 11, 12, 12, 12, 12, 8, 8, + 6, 6, 10, 10, 9, 12, 12, 11, 10, 10, 11, 12, 12, 10, 10, 10, 11, 12, + 12, 10, 11, 11, 9, 6, 6, 4, 6, 7, 8, 10, 10, 12, 12, 11, 12, 12, + 11, 7, 8, 8, 7, 10, 11, 12, 12, 9, 10, 11, 12, 12, 9, 4, 3, + /* Descriptor 8 - 121 entries */ + 2, 9, 10, 12, 12, 11, 8, 9, 9, 8, 9, 11, 12, 12, 10, 9, 9, 7, + 7, 7, 8, 10, 10, 9, 7, 10, 10, 10, 11, 12, 12, 8, 8, 10, 10, 11, + 11, 10, 7, 7, 5, 5, 8, 8, 7, 10, 10, 10, 12, 12, 11, 10, 11, 12, + 12, 10, 11, 11, 11, 11, 12, 12, 11, 9, 8, 4, 4, 6, 6, 6, 6, 6, + 8, 12, 12, 11, 11, 11, 10, 12, 12, 11, 8, 9, 11, 11, 12, 12, 12, 12, + 6, 7, 10, 10, 10, 10, 9, 10, 12, 12, 11, 4, 6, 7, 8, 12, 12, 12, + 12, 10, 11, 12, 12, 10, 6, 7, 9, 9, 8, 4, 3, + /* Descriptor 9 - 114 entries */ + 2, 6, 11, 11, 10, 9, 8, 8, 11, 12, 12, 11, 11, 9, 7, 8, 10, 10, + 9, 7, 8, 9, 11, 11, 12, 12, 11, 8, 9, 10, 10, 7, 8, 11, 11, 10, + 9, 11, 11, 10, 12, 12, 11, 10, 8, 5, 5, 7, 7, 6, 4, 6, 9, 11, + 11, 10, 8, 8, 8, 6, 9, 11, 12, 12, 12, 12, 11, 9, 11, 12, 12, 10, + 7, 4, 7, 7, 6, 6, 6, 4, 12, 12, 11, 10, 10, 11, 11, 9, 10, 10, + 11, 12, 12, 10, 10, 10, 8, 6, 8, 10, 12, 12, 12, 12, 10, 10, 8, 11, + 11, 10, 9, 6, 4, 3, + /* Descriptor A - 110 entries */ + 2, 9, 9, 8, 8, 12, 12, 11, 10, 9, 8, 10, 10, 9, 7, 6, 8, 9, + 11, 11, 12, 12, 11, 8, 9, 10, 11, 11, 7, 7, 8, 9, 9, 8, 10, 11, + 11, 10, 11, 12, 12, 5, 5, 6, 8, 9, 9, 8, 9, 10, 11, 12, 12, 4, + 6, 7, 7, 6, 7, 9, 10, 10, 11, 11, 10, 9, 4, 7, 8, 11, 11, 10, + 10, 10, 6, 7, 8, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 6, 4, 6, + 11, 12, 12, 11, 11, 9, 12, 12, 11, 12, 12, 11, 10, 10, 8, 8, 6, 6, 4, 3, -}; - -static const uint16_t ac_vlc_desc4_syms[131] = { - 0x1000, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, 0xFF1, 0xFF0, - 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, 0xFE0, 0xFD6, - 0xFD5, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC5, 0xFC3, 0xFC2, - 0xFC1, 0xFC0, 0xFB5, 0xFB3, 0xFB1, 0xFB0, 0xFA5, 0xFA3, - 0xFA1, 0xFA0, 0xF93, 0xF91, 0xF90, 0xF81, 0xF80, 0xF76, - 0xF71, 0xF70, 0xF66, 0xF61, 0xF60, 0xF56, 0xF51, 0xF50, - 0xF41, 0xF40, 0xF31, 0xF30, 0xF23, 0xF21, 0xF20, 0xF13, - 0xF11, 0xF10, 0xF03, 0xF01, 0xF00, 0xEF1, 0xEF0, 0xEE0, - 0xED0, 0xEC0, 0xEB0, 0x191, 0x181, 0x180, 0x171, 0x161, - 0x140, 0x130, 0x123, 0x120, 0x110, 0x100, 0x0F3, 0x0F0, - 0x0E0, 0x0D0, 0x0C0, 0x0B1, 0x0B0, 0x0A1, 0x0A0, 0x091, - 0x090, 0x085, 0x081, 0x080, 0x075, 0x071, 0x070, 0x066, - 0x065, 0x063, 0x061, 0x060, 0x056, 0x055, 0x053, 0x051, - 0x050, 0x045, 0x043, 0x042, 0x041, 0x040, 0x036, 0x035, - 0x033, 0x032, 0x031, 0x030, 0x026, 0x025, 0x024, 0x023, - 0x022, 0x021, 0x020, 0x018, 0x016, 0x015, 0x014, 0x013, - 0x012, 0x011, 0x010, -}; - -static const uint16_t ac_vlc_desc4_codes[131] = { - 0x006B, 0x00BE, 0x0052, 0x00F3, 0x005B, 0x003A, 0x0009, 0x0007, - 0x00DA, 0x03FB, 0x0123, 0x00B3, 0x01B3, 0x002E, 0x0006, 0x030A, - 0x005A, 0x004A, 0x034A, 0x0072, 0x0005, 0x02DA, 0x0173, 0x04FB, - 0x0032, 0x0013, 0x039B, 0x0B9B, 0x011E, 0x0002, 0x00FB, 0x021E, - 0x009B, 0x007E, 0x0E1A, 0x03CA, 0x007B, 0x02FB, 0x0033, 0x03AB, - 0x0463, 0x008A, 0x0773, 0x041E, 0x002B, 0x031B, 0x065A, 0x011A, - 0x060A, 0x01DA, 0x0963, 0x0323, 0x0BAB, 0x059E, 0x010A, 0x05AB, - 0x0CFB, 0x071B, 0x079E, 0x0F9E, 0x0263, 0x079B, 0x0563, 0x019E, - 0x01AB, 0x0E63, 0x029B, 0x04CA, 0x0DAB, 0x0663, 0x0B1B, 0x020A, - 0x0A1E, 0x021A, 0x0063, 0x061E, 0x06FB, 0x025A, 0x0163, 0x0573, - 0x000A, 0x0223, 0x011B, 0x0C1A, 0x015A, 0x0863, 0x00AB, 0x02CA, - 0x00B2, 0x0A0A, 0x01CA, 0x00A3, 0x0B73, 0x0023, 0x0012, 0x039E, - 0x001A, 0x0CCA, 0x01FB, 0x005E, 0x0A9B, 0x00CA, 0x0373, 0x009E, - 0x0022, 0x07AB, 0x001E, 0x0EFB, 0x009A, 0x000B, 0x041A, 0x019B, - 0x0363, 0x014A, 0x006A, 0x0015, 0x069B, 0x0073, 0x0523, 0x001B, - 0x012B, 0x0003, 0x0001, 0x061A, 0x003E, 0x002A, 0x00E3, 0x003B, - 0x000E, 0x000D, 0x0000, -}; - -static const uint8_t ac_vlc_desc4_bits[131] = { - 7, 8, 7, 8, 7, 6, 4, 3, - 10, 10, 11, 9, 9, 6, 4, 10, - 10, 9, 10, 7, 5, 10, 11, 12, - 8, 6, 12, 12, 9, 6, 11, 12, - 10, 7, 12, 10, 8, 11, 8, 12, - 11, 8, 11, 11, 9, 12, 11, 9, - 11, 9, 12, 10, 12, 11, 10, 12, - 12, 11, 12, 12, 11, 11, 11, 11, - 11, 12, 12, 12, 12, 12, 12, 12, - 12, 11, 12, 11, 12, 11, 12, 11, - 10, 10, 10, 12, 9, 12, 9, 10, - 8, 12, 10, 8, 12, 10, 7, 11, - 11, 12, 10, 7, 12, 11, 12, 9, - 6, 11, 11, 12, 8, 6, 12, 10, - 10, 10, 7, 5, 11, 9, 11, 9, - 9, 6, 4, 12, 8, 7, 8, 7, - 6, 4, 2, -}; - -static const uint16_t ac_vlc_desc5_syms[132] = { - 0x1000, 0xFF8, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, 0xFF1, - 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, 0xFE0, - 0xFD6, 0xFD5, 0xFD4, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC5, - 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB5, 0xFB3, 0xFB1, 0xFB0, - 0xFA3, 0xFA1, 0xFA0, 0xF96, 0xF93, 0xF91, 0xF90, 0xF86, - 0xF85, 0xF81, 0xF80, 0xF76, 0xF75, 0xF71, 0xF70, 0xF66, - 0xF61, 0xF60, 0xF51, 0xF50, 0xF43, 0xF41, 0xF40, 0xF33, - 0xF31, 0xF30, 0xF23, 0xF21, 0xF20, 0xF11, 0xF10, 0xF00, - 0xEF0, 0xEE0, 0xEC1, 0xEC0, 0x151, 0x141, 0x140, 0x131, - 0x121, 0x120, 0x111, 0x110, 0x103, 0x100, 0x0F0, 0x0E0, - 0x0D3, 0x0D0, 0x0C3, 0x0C1, 0x0C0, 0x0B1, 0x0B0, 0x0A1, - 0x0A0, 0x091, 0x090, 0x081, 0x080, 0x075, 0x071, 0x070, - 0x065, 0x061, 0x060, 0x056, 0x055, 0x053, 0x052, 0x051, - 0x050, 0x046, 0x045, 0x043, 0x042, 0x041, 0x040, 0x035, - 0x034, 0x033, 0x032, 0x031, 0x030, 0x026, 0x025, 0x024, - 0x023, 0x022, 0x021, 0x020, 0x018, 0x016, 0x015, 0x014, - 0x013, 0x012, 0x011, 0x010, -}; - -static const uint16_t ac_vlc_desc5_codes[132] = { - 0x0001, 0x0D62, 0x00BD, 0x0022, 0x009B, 0x0032, 0x0019, 0x0005, - 0x0007, 0x034D, 0x009A, 0x012B, 0x0052, 0x006B, 0x003A, 0x0006, - 0x06FD, 0x017D, 0x081A, 0x031B, 0x031A, 0x0012, 0x0011, 0x0202, - 0x00FD, 0x051B, 0x00D2, 0x001D, 0x011A, 0x0782, 0x018D, 0x007B, - 0x067D, 0x037D, 0x0021, 0x0E8D, 0x0562, 0x008D, 0x00BB, 0x053D, - 0x082A, 0x0002, 0x000D, 0x0302, 0x007D, 0x053B, 0x003B, 0x0A4D, - 0x027D, 0x01FD, 0x042A, 0x01C2, 0x041A, 0x0182, 0x014D, 0x0162, - 0x00C2, 0x032A, 0x0D9A, 0x012A, 0x0102, 0x087D, 0x072B, 0x039A, - 0x0362, 0x019A, 0x0C62, 0x04C2, 0x0D1B, 0x028D, 0x0762, 0x0E7D, - 0x0E41, 0x059A, 0x024D, 0x093B, 0x052B, 0x011B, 0x064D, 0x013D, - 0x0382, 0x0262, 0x0641, 0x0462, 0x004D, 0x0CC2, 0x033B, 0x068D, - 0x0141, 0x0D2B, 0x001B, 0x0041, 0x00C1, 0x0C41, 0x01E2, 0x00EB, - 0x062A, 0x0082, 0x0061, 0x02FD, 0x047D, 0x013B, 0x002A, 0x003D, - 0x005B, 0x022A, 0x02C2, 0x0241, 0x0062, 0x00AA, 0x000B, 0x00E2, - 0x001A, 0x033D, 0x021A, 0x006A, 0x0009, 0x032B, 0x002B, 0x04FD, - 0x0042, 0x016B, 0x002D, 0x000E, 0x0441, 0x00CD, 0x005A, 0x00AB, - 0x000A, 0x0039, 0x0003, 0x0000, -}; - -static const uint8_t ac_vlc_desc5_bits[132] = { - 7, 12, 8, 7, 8, 6, 6, 4, - 3, 10, 9, 11, 8, 9, 6, 4, - 11, 10, 12, 10, 10, 7, 5, 10, - 11, 12, 8, 6, 10, 11, 9, 7, - 12, 10, 7, 12, 12, 10, 8, 11, - 12, 10, 8, 10, 12, 11, 9, 12, - 11, 9, 11, 9, 11, 10, 10, 11, - 11, 10, 12, 10, 10, 12, 11, 10, - 11, 11, 12, 12, 12, 11, 11, 12, - 12, 12, 12, 12, 12, 11, 11, 11, - 11, 10, 12, 12, 10, 12, 10, 12, - 9, 12, 9, 11, 8, 12, 9, 8, - 11, 9, 7, 11, 11, 12, 12, 9, - 7, 11, 10, 11, 11, 8, 6, 9, - 12, 10, 10, 7, 5, 11, 9, 11, - 8, 9, 6, 4, 12, 8, 7, 8, - 6, 6, 4, 2, -}; - -static const uint16_t ac_vlc_desc6_syms[130] = { - 0x1000, 0xFF8, 0xFF7, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, - 0xFF1, 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, - 0xFE0, 0xFD6, 0xFD5, 0xFD4, 0xFD3, 0xFD2, 0xFD1, 0xFD0, - 0xFC5, 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB5, 0xFB3, 0xFB1, - 0xFB0, 0xFA6, 0xFA3, 0xFA1, 0xFA0, 0xF96, 0xF95, 0xF93, - 0xF91, 0xF90, 0xF86, 0xF85, 0xF81, 0xF80, 0xF76, 0xF71, - 0xF70, 0xF63, 0xF61, 0xF60, 0xF53, 0xF51, 0xF50, 0xF43, - 0xF41, 0xF40, 0xF31, 0xF30, 0xF20, 0xF10, 0xF00, 0xEF0, - 0xEE1, 0x131, 0x121, 0x120, 0x111, 0x110, 0x101, 0x100, - 0x0F1, 0x0F0, 0x0E3, 0x0E1, 0x0E0, 0x0D1, 0x0D0, 0x0C3, - 0x0C0, 0x0B3, 0x0B1, 0x0B0, 0x0A1, 0x0A0, 0x091, 0x090, - 0x081, 0x080, 0x075, 0x071, 0x070, 0x065, 0x063, 0x061, - 0x060, 0x056, 0x055, 0x053, 0x051, 0x050, 0x046, 0x045, - 0x043, 0x042, 0x041, 0x040, 0x036, 0x035, 0x034, 0x033, - 0x032, 0x031, 0x030, 0x026, 0x025, 0x024, 0x023, 0x022, - 0x021, 0x020, 0x018, 0x016, 0x015, 0x014, 0x013, 0x012, - 0x011, 0x010, -}; - -static const uint16_t ac_vlc_desc6_codes[130] = { - 0x0022, 0x0BB2, 0x0942, 0x002B, 0x0072, 0x0002, 0x001A, 0x0039, - 0x000D, 0x0007, 0x007B, 0x008E, 0x06DB, 0x00EA, 0x015B, 0x002E, - 0x0006, 0x0959, 0x027B, 0x0A0E, 0x01AB, 0x008A, 0x0012, 0x001E, - 0x0575, 0x005B, 0x02AB, 0x00C2, 0x0015, 0x036A, 0x04B2, 0x0099, - 0x001B, 0x0519, 0x0C19, 0x00DB, 0x004E, 0x0042, 0x0159, 0x03B2, - 0x030E, 0x00EB, 0x0252, 0x0EAB, 0x018A, 0x00E2, 0x06AB, 0x0242, - 0x017B, 0x0452, 0x0319, 0x0152, 0x025B, 0x016A, 0x00AB, 0x0052, - 0x05B2, 0x010E, 0x038E, 0x028A, 0x0359, 0x0019, 0x078A, 0x0C52, - 0x0D8E, 0x0ED9, 0x02D9, 0x0662, 0x0119, 0x09B2, 0x0BAB, 0x0D19, - 0x0C5B, 0x00B2, 0x0542, 0x0B8A, 0x02B2, 0x0142, 0x065B, 0x058E, - 0x0062, 0x018E, 0x038A, 0x00D9, 0x0419, 0x0162, 0x03AB, 0x0075, - 0x07B2, 0x0032, 0x020E, 0x07AB, 0x006B, 0x045B, 0x01B2, 0x0199, - 0x002A, 0x0375, 0x0775, 0x0AAB, 0x01D9, 0x003B, 0x060E, 0x0342, - 0x0175, 0x0262, 0x000A, 0x0005, 0x0559, 0x006A, 0x0D59, 0x0219, - 0x000E, 0x004A, 0x0009, 0x0719, 0x0059, 0x02DB, 0x00D2, 0x01DB, - 0x0025, 0x0001, 0x06D9, 0x00F5, 0x0035, 0x00FB, 0x003A, 0x000B, - 0x0003, 0x0000, -}; - -static const uint8_t ac_vlc_desc6_bits[130] = { - 7, 12, 12, 8, 7, 7, 6, 6, - 4, 3, 10, 9, 11, 8, 9, 6, - 4, 12, 10, 12, 10, 10, 7, 5, - 11, 11, 12, 8, 6, 10, 11, 9, - 7, 12, 12, 10, 7, 10, 12, 12, - 10, 8, 10, 12, 10, 8, 12, 10, - 9, 12, 11, 9, 11, 10, 10, 11, - 11, 10, 10, 10, 10, 11, 11, 12, - 12, 12, 11, 11, 11, 12, 12, 12, - 12, 11, 11, 12, 10, 12, 11, 12, - 10, 11, 12, 10, 12, 9, 12, 9, - 11, 8, 12, 11, 8, 12, 12, 9, - 7, 11, 11, 12, 9, 7, 11, 10, - 11, 11, 8, 6, 12, 9, 12, 10, - 10, 7, 5, 11, 9, 11, 8, 9, - 6, 4, 12, 8, 7, 8, 6, 6, - 4, 2, -}; - -static const uint16_t ac_vlc_desc7_syms[125] = { - 0x1000, 0xFF8, 0xFF7, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, - 0xFF1, 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, - 0xFE0, 0xFD5, 0xFD4, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC5, - 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB5, 0xFB3, 0xFB1, 0xFB0, - 0xFA6, 0xFA5, 0xFA3, 0xFA1, 0xFA0, 0xF96, 0xF95, 0xF93, - 0xF91, 0xF90, 0xF86, 0xF81, 0xF80, 0xF73, 0xF71, 0xF70, - 0xF63, 0xF61, 0xF60, 0xF53, 0xF51, 0xF50, 0xF41, 0xF40, - 0xF31, 0xF30, 0xF20, 0xF10, 0xF01, 0xF00, 0x121, 0x111, - 0x101, 0x100, 0x0F1, 0x0F0, 0x0E1, 0x0E0, 0x0D1, 0x0D0, - 0x0C3, 0x0C1, 0x0C0, 0x0B1, 0x0B0, 0x0A3, 0x0A1, 0x0A0, - 0x093, 0x091, 0x090, 0x081, 0x080, 0x071, 0x070, 0x065, - 0x063, 0x061, 0x060, 0x055, 0x053, 0x052, 0x051, 0x050, - 0x046, 0x045, 0x043, 0x042, 0x041, 0x040, 0x036, 0x035, - 0x034, 0x033, 0x032, 0x031, 0x030, 0x026, 0x025, 0x024, - 0x023, 0x022, 0x021, 0x020, 0x018, 0x017, 0x016, 0x015, - 0x014, 0x013, 0x012, 0x011, 0x010, -}; - -static const uint16_t ac_vlc_desc7_codes[125] = { - 0x0053, 0x009A, 0x0EE2, 0x00D3, 0x006A, 0x0052, 0x003A, 0x0035, - 0x000D, 0x0007, 0x0062, 0x0125, 0x0142, 0x0019, 0x01F3, 0x0029, - 0x000E, 0x0082, 0x0ADA, 0x02E3, 0x00E2, 0x0022, 0x0006, 0x0065, - 0x05E3, 0x0765, 0x0032, 0x0039, 0x0F99, 0x05E2, 0x0099, 0x0033, - 0x0362, 0x0799, 0x0F65, 0x0073, 0x004A, 0x02A5, 0x0162, 0x0742, - 0x01A5, 0x00D9, 0x0342, 0x005A, 0x00AA, 0x0EF3, 0x0182, 0x01DA, - 0x0382, 0x035A, 0x00F3, 0x0673, 0x0165, 0x00E5, 0x06F3, 0x0225, - 0x0842, 0x025A, 0x07E3, 0x0399, 0x07A5, 0x072A, 0x0F2A, 0x09E3, - 0x0273, 0x049A, 0x02E5, 0x0B99, 0x02E2, 0x0E73, 0x0562, 0x02F3, - 0x032A, 0x0F42, 0x00DA, 0x0999, 0x012A, 0x0365, 0x00A5, 0x00E3, - 0x0199, 0x03E3, 0x019A, 0x01E2, 0x0173, 0x06E5, 0x0059, 0x01E3, - 0x02DA, 0x002A, 0x000A, 0x06DA, 0x0FA5, 0x0042, 0x01E5, 0x0013, - 0x03E2, 0x015A, 0x03A5, 0x0442, 0x001A, 0x0005, 0x04A5, 0x0265, - 0x08A5, 0x0025, 0x029A, 0x0072, 0x0016, 0x0599, 0x00C2, 0x0242, - 0x00B2, 0x0002, 0x0015, 0x0001, 0x0BE3, 0x06E2, 0x0063, 0x0023, - 0x0012, 0x0009, 0x0003, 0x000B, 0x0000, -}; - -static const uint8_t ac_vlc_desc7_bits[125] = { - 8, 11, 12, 8, 7, 7, 6, 6, - 4, 3, 9, 9, 10, 8, 9, 6, - 4, 9, 12, 10, 10, 7, 5, 10, - 11, 12, 8, 6, 12, 11, 9, 7, - 10, 12, 12, 10, 7, 10, 11, 12, - 10, 8, 11, 10, 8, 12, 10, 9, - 10, 10, 10, 12, 10, 10, 12, 10, - 12, 10, 11, 12, 12, 12, 12, 12, - 11, 11, 11, 12, 11, 12, 11, 11, - 11, 12, 10, 12, 10, 11, 12, 10, - 12, 12, 9, 11, 9, 11, 8, 12, - 12, 9, 7, 11, 12, 12, 9, 7, - 10, 10, 11, 11, 8, 6, 11, 10, - 12, 10, 10, 7, 5, 11, 8, 10, - 8, 8, 6, 4, 12, 12, 8, 7, - 7, 6, 6, 4, 2, -}; - -static const uint16_t ac_vlc_desc8_syms[121] = { - 0x1000, 0xFF8, 0xFF7, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, - 0xFF1, 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, - 0xFE0, 0xFD5, 0xFD4, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC5, - 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB6, 0xFB5, 0xFB3, 0xFB1, - 0xFB0, 0xFA6, 0xFA5, 0xFA3, 0xFA1, 0xFA0, 0xF96, 0xF95, - 0xF93, 0xF91, 0xF90, 0xF86, 0xF83, 0xF81, 0xF80, 0xF73, - 0xF71, 0xF70, 0xF63, 0xF61, 0xF60, 0xF51, 0xF50, 0xF41, - 0xF40, 0xF30, 0xF21, 0xF20, 0x111, 0x101, 0x0F1, 0x0E1, - 0x0E0, 0x0D1, 0x0D0, 0x0C1, 0x0C0, 0x0B3, 0x0B1, 0x0B0, - 0x0A3, 0x0A1, 0x0A0, 0x093, 0x091, 0x090, 0x083, 0x081, - 0x080, 0x073, 0x071, 0x070, 0x065, 0x063, 0x061, 0x060, - 0x055, 0x053, 0x051, 0x050, 0x046, 0x045, 0x043, 0x042, - 0x041, 0x040, 0x036, 0x035, 0x034, 0x033, 0x032, 0x031, - 0x030, 0x026, 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, - 0x018, 0x017, 0x016, 0x015, 0x014, 0x013, 0x012, 0x011, - 0x010, -}; - -static const uint16_t ac_vlc_desc8_codes[121] = { - 0x00F6, 0x0676, 0x0EB6, 0x00F3, 0x0056, 0x006A, 0x0039, 0x0003, - 0x000D, 0x0007, 0x00A2, 0x0173, 0x00CA, 0x0025, 0x0082, 0x0019, - 0x0001, 0x00B6, 0x0276, 0x02E3, 0x00B2, 0x0062, 0x001A, 0x0175, - 0x01E3, 0x0BE5, 0x004A, 0x0029, 0x07A5, 0x00E3, 0x030A, 0x0176, - 0x0023, 0x0042, 0x05CA, 0x00A5, 0x0142, 0x0052, 0x04A5, 0x0B02, - 0x0D22, 0x0375, 0x0065, 0x0522, 0x0DE3, 0x010A, 0x00F5, 0x0136, - 0x0275, 0x01B2, 0x03F5, 0x03E3, 0x0002, 0x08E3, 0x01A2, 0x0B36, - 0x020A, 0x0076, 0x0CE3, 0x07E5, 0x070A, 0x03A5, 0x02B6, 0x0036, - 0x01E5, 0x02A5, 0x05E3, 0x07B6, 0x07F5, 0x0736, 0x0BA5, 0x0075, - 0x0302, 0x0FE5, 0x01B6, 0x0102, 0x04E3, 0x0022, 0x08A5, 0x01CA, - 0x00E5, 0x0F0A, 0x05E5, 0x0096, 0x0A76, 0x0336, 0x0236, 0x0012, - 0x03B6, 0x0BF5, 0x0073, 0x0035, 0x02B2, 0x000A, 0x0476, 0x0122, - 0x0016, 0x0009, 0x0322, 0x01F5, 0x03E5, 0x01A5, 0x03CA, 0x0072, - 0x0006, 0x06A5, 0x0032, 0x02CA, 0x008A, 0x00C2, 0x0015, 0x000E, - 0x0702, 0x06B6, 0x0063, 0x0033, 0x002A, 0x0005, 0x0013, 0x000B, - 0x0000, -}; - -static const uint8_t ac_vlc_desc8_bits[121] = { - 8, 11, 12, 8, 7, 7, 6, 6, - 4, 3, 9, 9, 10, 8, 8, 6, - 4, 10, 12, 10, 10, 7, 5, 10, - 11, 12, 8, 6, 11, 12, 11, 9, - 7, 9, 11, 12, 9, 7, 11, 12, - 12, 10, 8, 12, 12, 10, 9, 10, - 10, 9, 12, 10, 9, 12, 9, 12, - 10, 11, 12, 12, 12, 12, 11, 10, - 11, 11, 12, 11, 11, 11, 12, 10, - 12, 12, 10, 10, 12, 9, 12, 11, - 9, 12, 11, 8, 12, 12, 10, 7, - 11, 12, 9, 7, 10, 10, 11, 11, - 8, 6, 10, 10, 12, 10, 10, 7, - 5, 11, 8, 10, 8, 8, 6, 4, - 11, 12, 8, 7, 7, 6, 6, 4, - 2, -}; - -static const uint16_t ac_vlc_desc9_syms[114] = { - 0x1000, 0xFF8, 0xFF7, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, - 0xFF1, 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, - 0xFE0, 0xFD5, 0xFD4, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC5, - 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB6, 0xFB5, 0xFB3, 0xFB2, - 0xFB1, 0xFB0, 0xFA6, 0xFA5, 0xFA3, 0xFA1, 0xFA0, 0xF96, - 0xF93, 0xF91, 0xF90, 0xF83, 0xF81, 0xF80, 0xF73, 0xF71, - 0xF70, 0xF61, 0xF60, 0xF51, 0xF50, 0xF40, 0xF31, 0xF30, - 0xF21, 0x121, 0x0F1, 0x0E1, 0x0D1, 0x0D0, 0x0C1, 0x0C0, - 0x0B1, 0x0B0, 0x0A3, 0x0A1, 0x0A0, 0x093, 0x091, 0x090, - 0x083, 0x081, 0x080, 0x073, 0x071, 0x070, 0x065, 0x063, - 0x061, 0x060, 0x055, 0x053, 0x051, 0x050, 0x045, 0x043, - 0x042, 0x041, 0x040, 0x036, 0x035, 0x034, 0x033, 0x032, - 0x031, 0x030, 0x026, 0x025, 0x024, 0x023, 0x022, 0x021, - 0x020, 0x018, 0x017, 0x016, 0x015, 0x014, 0x013, 0x012, - 0x011, 0x010, -}; - -static const uint16_t ac_vlc_desc9_codes[114] = { - 0x0061, 0x0403, 0x0DB1, 0x0012, 0x0071, 0x0056, 0x0035, 0x0023, - 0x000D, 0x0007, 0x0243, 0x01D3, 0x026A, 0x00A1, 0x00A2, 0x0011, - 0x000E, 0x01AA, 0x0531, 0x0093, 0x0222, 0x0032, 0x0006, 0x07F2, - 0x04D3, 0x0C43, 0x0072, 0x0001, 0x0343, 0x05F2, 0x04AA, 0x03F2, - 0x0031, 0x0045, 0x0143, 0x00AA, 0x0B31, 0x00F2, 0x00C3, 0x0693, - 0x0BF2, 0x0203, 0x00E1, 0x03B1, 0x02D3, 0x00B1, 0x056A, 0x01D2, - 0x008A, 0x046A, 0x01E2, 0x0003, 0x0103, 0x01B1, 0x02E2, 0x0293, - 0x016A, 0x04E2, 0x0443, 0x0521, 0x0321, 0x0043, 0x00D3, 0x00E2, - 0x0703, 0x00D2, 0x0731, 0x0A93, 0x0393, 0x0803, 0x0422, 0x0383, - 0x018A, 0x006A, 0x0021, 0x096A, 0x0303, 0x0052, 0x0CE2, 0x0D31, - 0x038A, 0x0013, 0x01F2, 0x0E93, 0x0083, 0x0005, 0x02D2, 0x0121, - 0x0022, 0x00EA, 0x0036, 0x0122, 0x0193, 0x0331, 0x0183, 0x02AA, - 0x004A, 0x001A, 0x0131, 0x002A, 0x036A, 0x000A, 0x0062, 0x0025, - 0x0009, 0x06E2, 0x05B1, 0x0053, 0x0002, 0x0016, 0x0015, 0x0033, - 0x000B, 0x0000, -}; - -static const uint8_t ac_vlc_desc9_bits[114] = { - 8, 11, 12, 7, 7, 7, 6, 6, - 4, 3, 10, 9, 10, 8, 8, 6, - 4, 9, 12, 10, 10, 7, 5, 11, - 11, 12, 8, 6, 10, 11, 11, 12, - 9, 7, 10, 11, 12, 9, 8, 12, - 12, 10, 8, 10, 10, 9, 11, 9, - 9, 11, 9, 12, 10, 11, 11, 12, - 12, 12, 12, 11, 10, 11, 11, 11, - 11, 10, 11, 12, 10, 12, 11, 10, - 10, 11, 9, 12, 11, 8, 12, 12, - 10, 8, 11, 12, 9, 7, 10, 11, - 11, 8, 6, 9, 10, 12, 10, 10, - 7, 5, 11, 8, 10, 8, 8, 6, - 4, 11, 12, 8, 6, 7, 6, 6, - 4, 2, -}; - -static const uint16_t ac_vlc_descA_syms[110] = { - 0x1000, 0xFF8, 0xFF7, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, - 0xFF1, 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, - 0xFE0, 0xFD5, 0xFD4, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC6, - 0xFC5, 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB6, 0xFB5, 0xFB3, - 0xFB2, 0xFB1, 0xFB0, 0xFA6, 0xFA5, 0xFA3, 0xFA1, 0xFA0, - 0xF96, 0xF93, 0xF91, 0xF90, 0xF83, 0xF81, 0xF80, 0xF73, - 0xF71, 0xF70, 0xF61, 0xF60, 0xF51, 0xF50, 0xF41, 0xF40, - 0xF31, 0x0E1, 0x0D1, 0x0C1, 0x0C0, 0x0B1, 0x0B0, 0x0A1, - 0x0A0, 0x093, 0x091, 0x090, 0x083, 0x081, 0x080, 0x073, - 0x071, 0x070, 0x063, 0x061, 0x060, 0x055, 0x053, 0x051, - 0x050, 0x045, 0x044, 0x043, 0x042, 0x041, 0x040, 0x036, - 0x035, 0x034, 0x033, 0x032, 0x031, 0x030, 0x026, 0x025, - 0x024, 0x023, 0x022, 0x021, 0x020, 0x018, 0x017, 0x016, - 0x015, 0x014, 0x013, 0x012, 0x011, 0x010, -}; - -static const uint16_t ac_vlc_descA_codes[110] = { - 0x002A, 0x04C5, 0x02A3, 0x004A, 0x0015, 0x0005, 0x0003, 0x0013, - 0x000D, 0x0007, 0x0171, 0x0032, 0x0371, 0x0076, 0x0042, 0x0011, - 0x000E, 0x00AA, 0x04D5, 0x03A3, 0x06A3, 0x0062, 0x001A, 0x06D5, - 0x07F2, 0x0223, 0x0CD5, 0x006A, 0x0001, 0x00F6, 0x0623, 0x03F2, - 0x07EA, 0x01F1, 0x0021, 0x03D5, 0x08C2, 0x07F6, 0x00F2, 0x00E3, - 0x0FEA, 0x02C5, 0x01AA, 0x0082, 0x04A3, 0x00B6, 0x0071, 0x03B2, - 0x0023, 0x01B6, 0x08A3, 0x0002, 0x0BB2, 0x00C5, 0x02EA, 0x0C23, - 0x0FF6, 0x0423, 0x07B2, 0x01C5, 0x07D5, 0x01EA, 0x06EA, 0x02C2, - 0x01F6, 0x01D5, 0x01B2, 0x00B2, 0x04F1, 0x03EA, 0x01A2, 0x02A2, - 0x02D5, 0x0123, 0x00D5, 0x01F2, 0x0055, 0x05B2, 0x04C2, 0x0102, - 0x0061, 0x05D5, 0x00C2, 0x00F1, 0x00A3, 0x0045, 0x0016, 0x01A3, - 0x01C2, 0x08D5, 0x03C5, 0x00EA, 0x000A, 0x0006, 0x00A2, 0x0036, - 0x02F1, 0x0072, 0x0022, 0x0025, 0x0009, 0x03F6, 0x0AA3, 0x0063, - 0x0012, 0x0031, 0x0035, 0x0033, 0x000B, 0x0000, -}; - -static const uint8_t ac_vlc_descA_bits[110] = { - 8, 11, 12, 7, 7, 7, 6, 6, - 4, 3, 10, 8, 10, 8, 8, 6, - 4, 9, 12, 10, 11, 7, 5, 11, - 11, 11, 12, 8, 6, 9, 11, 11, - 12, 9, 7, 11, 12, 12, 9, 8, - 12, 10, 9, 8, 11, 9, 9, 12, - 11, 9, 12, 9, 12, 11, 11, 12, - 12, 12, 11, 10, 11, 10, 11, 10, - 10, 11, 11, 9, 11, 11, 9, 10, - 11, 9, 12, 10, 8, 11, 11, 9, - 7, 11, 12, 11, 12, 8, 6, 10, - 9, 12, 10, 10, 7, 5, 10, 8, - 10, 8, 8, 6, 4, 11, 12, 8, - 6, 7, 6, 6, 4, 2, -}; - -static const uint16_t ac_vlc_descB_syms[101] = { - 0x1000, 0xFF8, 0xFF7, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, - 0xFF1, 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, - 0xFE0, 0xFD5, 0xFD4, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC6, - 0xFC5, 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB6, 0xFB5, 0xFB3, - 0xFB1, 0xFB0, 0xFA6, 0xFA3, 0xFA1, 0xFA0, 0xF93, 0xF91, - 0xF90, 0xF83, 0xF81, 0xF80, 0xF71, 0xF70, 0xF61, 0xF60, - 0xF51, 0xF50, 0xF41, 0x0F1, 0x0D1, 0x0C1, 0x0B1, 0x0B0, - 0x0A1, 0x0A0, 0x091, 0x090, 0x083, 0x081, 0x080, 0x073, - 0x071, 0x070, 0x063, 0x061, 0x060, 0x055, 0x053, 0x051, - 0x050, 0x045, 0x043, 0x042, 0x041, 0x040, 0x036, 0x035, - 0x034, 0x033, 0x032, 0x031, 0x030, 0x026, 0x025, 0x024, - 0x023, 0x022, 0x021, 0x020, 0x018, 0x017, 0x016, 0x015, - 0x014, 0x013, 0x012, 0x011, 0x010, -}; - -static const uint16_t ac_vlc_descB_codes[101] = { - 0x00EE, 0x03A5, 0x0B73, 0x004E, 0x0035, 0x0015, 0x0023, 0x0013, - 0x000D, 0x0007, 0x0673, 0x01F3, 0x02FE, 0x0096, 0x0133, 0x001E, - 0x0001, 0x0116, 0x00F5, 0x03F5, 0x0473, 0x0052, 0x001A, 0x01D5, - 0x0025, 0x0073, 0x0633, 0x0086, 0x0036, 0x012E, 0x0155, 0x0006, - 0x0055, 0x000E, 0x0106, 0x023E, 0x0192, 0x0075, 0x0173, 0x01AE, - 0x00D5, 0x08F5, 0x002E, 0x01FE, 0x0406, 0x00AE, 0x0E3E, 0x0206, - 0x013E, 0x0373, 0x0D55, 0x063E, 0x0E33, 0x033E, 0x01F5, 0x0273, - 0x003E, 0x06A5, 0x0092, 0x03D5, 0x04F5, 0x053E, 0x0016, 0x00FE, - 0x07A5, 0x0125, 0x0506, 0x0292, 0x00BE, 0x0425, 0x0F73, 0x02F5, - 0x0056, 0x0233, 0x02A5, 0x0C25, 0x007E, 0x0026, 0x0355, 0x0033, - 0x0555, 0x01A5, 0x0306, 0x0046, 0x000A, 0x0225, 0x006E, 0x00A5, - 0x0012, 0x00F3, 0x0005, 0x0009, 0x073E, 0x0773, 0x00B3, 0x0032, - 0x0065, 0x0003, 0x0002, 0x000B, 0x0000, -}; - -static const uint8_t ac_vlc_descB_bits[101] = { - 8, 11, 12, 7, 7, 7, 6, 6, - 4, 3, 11, 9, 10, 8, 9, 6, - 4, 9, 12, 10, 11, 7, 5, 10, - 11, 11, 12, 8, 6, 9, 11, 11, - 9, 7, 11, 11, 9, 8, 10, 9, - 9, 12, 9, 9, 11, 9, 12, 10, - 11, 12, 12, 12, 12, 11, 10, 11, - 10, 11, 10, 10, 11, 11, 9, 10, - 11, 9, 11, 10, 8, 12, 12, 10, - 7, 11, 11, 12, 8, 6, 10, 10, - 12, 10, 10, 7, 5, 10, 8, 10, - 8, 9, 6, 4, 11, 12, 8, 6, - 7, 6, 5, 4, 2, -}; - -static const uint16_t ac_vlc_descC_syms[96] = { - 0x1000, 0xFF8, 0xFF7, 0xFF6, 0xFF5, 0xFF4, 0xFF3, 0xFF2, - 0xFF1, 0xFF0, 0xFE6, 0xFE5, 0xFE4, 0xFE3, 0xFE2, 0xFE1, - 0xFE0, 0xFD5, 0xFD4, 0xFD3, 0xFD2, 0xFD1, 0xFD0, 0xFC6, - 0xFC5, 0xFC3, 0xFC2, 0xFC1, 0xFC0, 0xFB6, 0xFB5, 0xFB3, - 0xFB1, 0xFB0, 0xFA6, 0xFA3, 0xFA1, 0xFA0, 0xF93, 0xF91, - 0xF90, 0xF81, 0xF80, 0xF71, 0xF70, 0xF61, 0xF60, 0xF51, - 0x0E1, 0x0C1, 0x0B1, 0x0A1, 0x0A0, 0x091, 0x090, 0x083, - 0x081, 0x080, 0x073, 0x071, 0x070, 0x063, 0x061, 0x060, - 0x055, 0x053, 0x051, 0x050, 0x045, 0x043, 0x042, 0x041, - 0x040, 0x036, 0x035, 0x034, 0x033, 0x032, 0x031, 0x030, - 0x026, 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x018, - 0x017, 0x016, 0x015, 0x014, 0x013, 0x012, 0x011, 0x010, -}; - -static const uint16_t ac_vlc_descC_codes[96] = { - 0x00DE, 0x072E, 0x0576, 0x006E, 0x0075, 0x0055, 0x0013, 0x0033, - 0x000D, 0x0007, 0x07D2, 0x0052, 0x0065, 0x00CE, 0x0183, 0x003E, - 0x0001, 0x002E, 0x0F35, 0x0003, 0x0243, 0x001A, 0x0006, 0x01A5, - 0x0043, 0x0012, 0x0E43, 0x00B6, 0x0016, 0x0135, 0x0176, 0x0643, - 0x0035, 0x001E, 0x0735, 0x0283, 0x0125, 0x00AE, 0x00D2, 0x0165, - 0x0103, 0x0603, 0x00E5, 0x0C43, 0x02B5, 0x04A5, 0x00A5, 0x0443, - 0x0265, 0x0476, 0x0212, 0x0112, 0x0376, 0x012E, 0x02D2, 0x0083, - 0x0483, 0x015E, 0x06A5, 0x0335, 0x005E, 0x0025, 0x01D2, 0x00F6, - 0x03D2, 0x032E, 0x03B5, 0x005A, 0x0203, 0x02A5, 0x0BD2, 0x004E, - 0x0032, 0x01B5, 0x00B5, 0x0A65, 0x0225, 0x0276, 0x000E, 0x000A, - 0x03E5, 0x0143, 0x01E5, 0x0036, 0x0092, 0x0005, 0x0009, 0x0665, - 0x0076, 0x00C3, 0x003A, 0x0015, 0x0023, 0x0002, 0x000B, 0x0000, -}; - -static const uint8_t ac_vlc_descC_bits[96] = { - 8, 11, 11, 7, 7, 7, 6, 6, - 4, 3, 11, 8, 10, 8, 9, 6, - 4, 9, 12, 10, 11, 7, 5, 9, - 11, 10, 12, 8, 6, 10, 11, 12, - 9, 7, 12, 10, 9, 8, 10, 9, - 9, 11, 9, 12, 10, 11, 11, 12, - 12, 11, 10, 9, 10, 10, 10, 11, - 11, 9, 11, 11, 9, 10, 10, 8, - 12, 11, 10, 7, 11, 11, 12, 8, - 6, 10, 10, 12, 10, 10, 7, 5, - 10, 9, 10, 8, 8, 6, 4, 11, - 11, 8, 6, 7, 6, 5, 4, 2, + /* Descriptor B - 101 entries */ + 2, 5, 8, 10, 10, 9, 7, 6, 5, 5, 11, 11, 10, 11, 11, 10, 8, 7, + 6, 9, 9, 8, 7, 6, 7, 7, 9, 9, 9, 9, 8, 8, 6, 10, 11, 12, + 12, 11, 11, 11, 11, 8, 8, 10, 10, 9, 4, 4, 6, 11, 12, 12, 10, 9, + 10, 11, 11, 10, 11, 11, 7, 7, 9, 11, 12, 12, 10, 9, 10, 10, 7, 8, + 12, 12, 11, 10, 10, 10, 4, 6, 6, 6, 10, 11, 12, 12, 9, 8, 11, 11, + 11, 11, 10, 12, 12, 12, 12, 9, 9, 4, 3, + /* Descriptor C - 96 entries */ + 2, 5, 10, 10, 9, 8, 8, 10, 10, 10, 12, 12, 11, 6, 5, 7, 7, 6, + 5, 6, 8, 8, 11, 11, 10, 11, 11, 10, 8, 7, 8, 8, 9, 10, 11, 11, + 8, 7, 7, 9, 9, 8, 6, 4, 4, 6, 10, 10, 9, 11, 11, 11, 11, 9, + 10, 12, 12, 11, 9, 9, 10, 10, 7, 7, 9, 10, 11, 12, 12, 10, 10, 10, + 10, 7, 4, 10, 11, 11, 9, 11, 11, 10, 9, 11, 12, 12, 11, 12, 12, 9, + 8, 6, 6, 6, 4, 3, }; static const int tscc2_ac_vlc_sizes[NUM_VLC_SETS] = { 172, 169, 165, 162, 131, 132, 130, 125, 121, 114, 110, 101, 96 }; -static const uint16_t * const tscc2_ac_vlc_syms[NUM_VLC_SETS] = { - ac_vlc_desc0_syms, ac_vlc_desc1_syms, ac_vlc_desc2_syms, ac_vlc_desc3_syms, - ac_vlc_desc4_syms, ac_vlc_desc5_syms, ac_vlc_desc6_syms, ac_vlc_desc7_syms, - ac_vlc_desc8_syms, ac_vlc_desc9_syms, ac_vlc_descA_syms, ac_vlc_descB_syms, - ac_vlc_descC_syms, -}; - -static const uint16_t * const tscc2_ac_vlc_codes[NUM_VLC_SETS] = { - ac_vlc_desc0_codes, ac_vlc_desc1_codes, ac_vlc_desc2_codes, - ac_vlc_desc3_codes, ac_vlc_desc4_codes, ac_vlc_desc5_codes, - ac_vlc_desc6_codes, ac_vlc_desc7_codes, ac_vlc_desc8_codes, - ac_vlc_desc9_codes, ac_vlc_descA_codes, ac_vlc_descB_codes, - ac_vlc_descC_codes, -}; - -static const uint8_t * const tscc2_ac_vlc_bits[NUM_VLC_SETS] = { - ac_vlc_desc0_bits, ac_vlc_desc1_bits, ac_vlc_desc2_bits, ac_vlc_desc3_bits, - ac_vlc_desc4_bits, ac_vlc_desc5_bits, ac_vlc_desc6_bits, ac_vlc_desc7_bits, - ac_vlc_desc8_bits, ac_vlc_desc9_bits, ac_vlc_descA_bits, ac_vlc_descB_bits, - ac_vlc_descC_bits, -}; - #endif /* AVCODEC_TSCC2DATA_H */ diff --git a/libavcodec/tta.c b/libavcodec/tta.c index e68e4fbb3..f1e159b03 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -423,6 +423,6 @@ AVCodec ff_tta_decoder = { .init = tta_decode_init, .close = tta_decode_close, .decode = tta_decode_frame, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF, .priv_class = &tta_decoder_class, }; diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c new file mode 100644 index 000000000..3972b4368 --- /dev/null +++ b/libavcodec/ttmlenc.c @@ -0,0 +1,210 @@ +/* + * TTML subtitle encoder + * Copyright (c) 2020 24i + * + * 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 + * TTML subtitle encoder + * @see https://www.w3.org/TR/ttml1/ + * @see https://www.w3.org/TR/ttml2/ + * @see https://www.w3.org/TR/ttml-imsc/rec + */ + +#include "avcodec.h" +#include "internal.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" +#include "libavutil/internal.h" +#include "ass_split.h" +#include "ass.h" +#include "ttmlenc.h" + +typedef struct { + AVCodecContext *avctx; + ASSSplitContext *ass_ctx; + AVBPrint buffer; +} TTMLContext; + +static void ttml_text_cb(void *priv, const char *text, int len) +{ + TTMLContext *s = priv; + AVBPrint cur_line = { 0 }; + AVBPrint *buffer = &s->buffer; + + av_bprint_init(&cur_line, len, AV_BPRINT_SIZE_UNLIMITED); + + av_bprint_append_data(&cur_line, text, len); + if (!av_bprint_is_complete(&cur_line)) { + av_log(s->avctx, AV_LOG_ERROR, + "Failed to move the current subtitle dialog to AVBPrint!\n"); + av_bprint_finalize(&cur_line, NULL); + return; + } + + + av_bprint_escape(buffer, cur_line.str, NULL, AV_ESCAPE_MODE_XML, + 0); + + av_bprint_finalize(&cur_line, NULL); +} + +static void ttml_new_line_cb(void *priv, int forced) +{ + TTMLContext *s = priv; + + av_bprintf(&s->buffer, "
"); +} + +static const ASSCodesCallbacks ttml_callbacks = { + .text = ttml_text_cb, + .new_line = ttml_new_line_cb, +}; + +static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf, + int bufsize, const AVSubtitle *sub) +{ + TTMLContext *s = avctx->priv_data; + ASSDialog *dialog; + int i; + + av_bprint_clear(&s->buffer); + + for (i=0; inum_rects; i++) { + 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 AVERROR(EINVAL); + } + +#if FF_API_ASS_TIMING + if (!strncmp(ass, "Dialogue: ", 10)) { + int num; + dialog = ff_ass_split_dialog(s->ass_ctx, ass, 0, &num); + + for (; dialog && num--; dialog++) { + int ret = ff_ass_split_override_codes(&ttml_callbacks, s, + dialog->text); + int log_level = (ret != AVERROR_INVALIDDATA || + avctx->err_recognition & AV_EF_EXPLODE) ? + AV_LOG_ERROR : AV_LOG_WARNING; + + if (ret < 0) { + av_log(avctx, log_level, + "Splitting received ASS dialog failed: %s\n", + av_err2str(ret)); + + if (log_level == AV_LOG_ERROR) + return ret; + } + } + } else { +#endif + dialog = ff_ass_split_dialog2(s->ass_ctx, ass); + if (!dialog) + return AVERROR(ENOMEM); + + { + int ret = ff_ass_split_override_codes(&ttml_callbacks, s, + dialog->text); + int log_level = (ret != AVERROR_INVALIDDATA || + avctx->err_recognition & AV_EF_EXPLODE) ? + AV_LOG_ERROR : AV_LOG_WARNING; + + if (ret < 0) { + av_log(avctx, log_level, + "Splitting received ASS dialog text %s failed: %s\n", + dialog->text, + av_err2str(ret)); + + if (log_level == AV_LOG_ERROR) { + ff_ass_free_dialog(&dialog); + return ret; + } + } + + ff_ass_free_dialog(&dialog); + } +#if FF_API_ASS_TIMING + } +#endif + } + + if (!av_bprint_is_complete(&s->buffer)) + return AVERROR(ENOMEM); + if (!s->buffer.len) + return 0; + + // force null-termination, so in case our destination buffer is + // too small, the return value is larger than bufsize minus null. + if (av_strlcpy(buf, s->buffer.str, bufsize) > bufsize - 1) { + av_log(avctx, AV_LOG_ERROR, "Buffer too small for TTML event.\n"); + return AVERROR_BUFFER_TOO_SMALL; + } + + return s->buffer.len; +} + +static av_cold int ttml_encode_close(AVCodecContext *avctx) +{ + TTMLContext *s = avctx->priv_data; + + ff_ass_split_free(s->ass_ctx); + + av_bprint_finalize(&s->buffer, NULL); + + return 0; +} + +static av_cold int ttml_encode_init(AVCodecContext *avctx) +{ + TTMLContext *s = avctx->priv_data; + + s->avctx = avctx; + + if (!(s->ass_ctx = ff_ass_split(avctx->subtitle_header))) { + return AVERROR_INVALIDDATA; + } + + if (!(avctx->extradata = av_mallocz(TTMLENC_EXTRADATA_SIGNATURE_SIZE + + 1 + AV_INPUT_BUFFER_PADDING_SIZE))) { + return AVERROR(ENOMEM); + } + + avctx->extradata_size = TTMLENC_EXTRADATA_SIGNATURE_SIZE; + memcpy(avctx->extradata, TTMLENC_EXTRADATA_SIGNATURE, + TTMLENC_EXTRADATA_SIGNATURE_SIZE); + + av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED); + + return 0; +} + +AVCodec ff_ttml_encoder = { + .name = "ttml", + .long_name = NULL_IF_CONFIG_SMALL("TTML subtitle"), + .type = AVMEDIA_TYPE_SUBTITLE, + .id = AV_CODEC_ID_TTML, + .priv_data_size = sizeof(TTMLContext), + .init = ttml_encode_init, + .encode_sub = ttml_encode_frame, + .close = ttml_encode_close, + .capabilities = FF_CODEC_CAP_INIT_CLEANUP, +}; diff --git a/libavcodec/ttmlenc.h b/libavcodec/ttmlenc.h new file mode 100644 index 000000000..c1dd5ec99 --- /dev/null +++ b/libavcodec/ttmlenc.h @@ -0,0 +1,28 @@ +/* + * TTML subtitle encoder shared functionality + * Copyright (c) 2020 24i + * + * 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_TTMLENC_H +#define AVCODEC_TTMLENC_H + +#define TTMLENC_EXTRADATA_SIGNATURE "lavc-ttmlenc" +#define TTMLENC_EXTRADATA_SIGNATURE_SIZE (sizeof(TTMLENC_EXTRADATA_SIGNATURE) - 1) + +#endif /* AVCODEC_TTMLENC_H */ diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 34ca1846b..6dfaf06b1 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -538,6 +538,7 @@ static av_cold int init_mdct_win(TwinVQContext *tctx) int size_m = mtab->size / mtab->fmode[TWINVQ_FT_MEDIUM].sub; int channels = tctx->avctx->channels; float norm = channels == 1 ? 2.0 : 1.0; + int table_size = 2 * mtab->size * channels; for (i = 0; i < 3; i++) { int bsize = tctx->mtab->size / tctx->mtab->fmode[i].sub; @@ -546,25 +547,17 @@ static av_cold int init_mdct_win(TwinVQContext *tctx) return ret; } - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->tmp_buf, - mtab->size, sizeof(*tctx->tmp_buf), alloc_fail); - - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->spectrum, - 2 * mtab->size, channels * sizeof(*tctx->spectrum), - alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->curr_frame, - 2 * mtab->size, channels * sizeof(*tctx->curr_frame), - alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->prev_frame, - 2 * mtab->size, channels * sizeof(*tctx->prev_frame), - alloc_fail); + if (!FF_ALLOC_TYPED_ARRAY(tctx->tmp_buf, mtab->size) || + !FF_ALLOC_TYPED_ARRAY(tctx->spectrum, table_size) || + !FF_ALLOC_TYPED_ARRAY(tctx->curr_frame, table_size) || + !FF_ALLOC_TYPED_ARRAY(tctx->prev_frame, table_size)) + return AVERROR(ENOMEM); for (i = 0; i < 3; i++) { int m = 4 * mtab->size / mtab->fmode[i].sub; double freq = 2 * M_PI / m; - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->cos_tabs[i], - (m / 4), sizeof(*tctx->cos_tabs[i]), alloc_fail); - + if (!FF_ALLOC_TYPED_ARRAY(tctx->cos_tabs[i], m / 4)) + return AVERROR(ENOMEM); for (j = 0; j <= m / 8; j++) tctx->cos_tabs[i][j] = cos((2 * j + 1) * freq); for (j = 1; j < m / 8; j++) @@ -576,9 +569,6 @@ static av_cold int init_mdct_win(TwinVQContext *tctx) ff_init_ff_sine_windows(av_log2(mtab->size)); return 0; - -alloc_fail: - return AVERROR(ENOMEM); } /** diff --git a/libavcodec/twinvq_data.h b/libavcodec/twinvq_data.h index 375acc245..1d9678ef1 100644 --- a/libavcodec/twinvq_data.h +++ b/libavcodec/twinvq_data.h @@ -135,7 +135,6 @@ static const uint16_t bark_tab_s44_128[] = { * without risking a segfault on malformed files. */ static const struct twinvq_data { - float lsp08[504]; int16_t fcb08l[640]; int16_t fcb08m[320]; int16_t fcb08s[320]; @@ -159,7 +158,6 @@ static const struct twinvq_data { int16_t fcb11m[320]; int16_t fcb11s[320]; int16_t shape11[1280]; - float lsp11[1312]; int16_t cb1110l0[1280]; int16_t cb1110l1[1280]; @@ -172,7 +170,6 @@ static const struct twinvq_data { int16_t fcb16m[320]; int16_t fcb16s[320]; int16_t shape16[1920]; - float lsp16[1400]; int16_t cb1616l0[1024]; int16_t cb1616l1[1024]; @@ -192,7 +189,6 @@ static const struct twinvq_data { int16_t fcb22m_1[640]; int16_t fcb22s_1[640]; int16_t shape22_1[1152]; - float lsp22_1[1312]; int16_t cb2224l0[960]; int16_t cb2224l1[960]; @@ -225,7 +221,6 @@ static const struct twinvq_data { int16_t fcb44m[640]; int16_t fcb44s[640]; int16_t shape44[1152]; - float lsp44[1640]; int16_t cb4448l0[896]; int16_t cb4448l1[896]; @@ -10036,584 +10031,6 @@ static const struct twinvq_data { -3976, -66, -594, 6181, -110, 292, 1129, -591 }, -.lsp08 = { - 0.2702, 0.5096, 0.6437, 0.7672, 0.9639, 1.0696, 1.2625, 1.5789, - 1.9285, 2.2383, 2.5129, 2.8470, 0.1740, 0.3677, 0.6082, 0.8387, - 1.1084, 1.3721, 1.6362, 1.8733, 2.0640, 2.3442, 2.6087, 2.8548, - 0.1536, 0.3279, 0.5143, 0.6859, 0.9763, 1.2744, 1.5605, 1.8566, - 2.1007, 2.3450, 2.6075, 2.8850, 0.2075, 0.4533, 0.7709, 1.0377, - 1.2953, 1.5132, 1.7826, 2.0351, 2.2590, 2.4996, 2.6795, 2.8748, - 0.1393, 0.2453, 0.3754, 0.5453, 0.8148, 1.1289, 1.4389, 1.7592, - 2.0353, 2.3215, 2.5934, 2.8588, 0.1250, 0.3627, 0.7613, 1.1380, - 1.4163, 1.5565, 1.6920, 1.8130, 1.8678, 2.0427, 2.4318, 2.8544, - 0.2256, 0.4223, 0.6452, 0.8599, 1.0673, 1.3118, 1.5486, 1.8366, - 2.0759, 2.3026, 2.5284, 2.8030, 0.2304, 0.4404, 0.6891, 0.8964, - 1.1510, 1.4202, 1.6483, 1.8580, 2.1181, 2.3686, 2.6078, 2.9128, - 0.2230, 0.3816, 0.5520, 0.6062, 0.7909, 1.0988, 1.4330, 1.7846, - 2.0713, 2.3457, 2.6048, 2.8708, 0.2447, 0.5800, 0.8249, 0.9905, - 1.1721, 1.3990, 1.6694, 1.9064, 2.1307, 2.4255, 2.6815, 2.9117, - 0.1974, 0.3812, 0.5802, 0.7759, 0.9280, 1.1547, 1.4170, 1.6369, - 1.8890, 2.2587, 2.5626, 2.8239, 0.1209, 0.2510, 0.4841, 0.8048, - 1.1197, 1.3563, 1.6073, 1.8926, 2.1350, 2.3669, 2.6291, 2.8985, - 0.2352, 0.4347, 0.6582, 0.8178, 0.9548, 1.1654, 1.4942, 1.8812, - 2.1703, 2.3779, 2.6412, 2.8871, 0.2091, 0.4084, 0.6730, 0.9151, - 1.1259, 1.3262, 1.5937, 1.8129, 2.0237, 2.3317, 2.5778, 2.8620, - 0.1167, 0.2406, 0.4520, 0.7298, 0.9848, 1.2448, 1.5137, 1.7874, - 2.0280, 2.3020, 2.5914, 2.8794, 0.3003, 0.4966, 0.6520, 0.8505, - 1.1600, 1.3981, 1.5805, 1.8346, 2.0757, 2.3102, 2.5760, 2.8499, - 0.2451, 0.4163, 0.5960, 0.7805, 0.9507, 1.2438, 1.5587, 1.8581, - 2.0735, 2.3198, 2.5704, 2.8220, 0.3112, 0.5517, 0.7032, 0.8528, - 1.1489, 1.4257, 1.6848, 1.9388, 2.1577, 2.4265, 2.6678, 2.9051, - 0.2249, 0.3897, 0.5559, 0.7473, 1.0158, 1.3581, 1.6914, 1.9930, - 2.1843, 2.3534, 2.5512, 2.8065, 0.2600, 0.4574, 0.7349, 0.9691, - 1.1696, 1.3848, 1.6335, 1.9021, 2.1174, 2.3481, 2.5902, 2.8390, - 0.2246, 0.3372, 0.4560, 0.5249, 0.7056, 1.0273, 1.3810, 1.7132, - 1.9819, 2.2574, 2.5410, 2.8491, 0.1419, 0.4834, 0.8835, 1.1453, - 1.2839, 1.4224, 1.5593, 1.7877, 2.1285, 2.4070, 2.6043, 2.8511, - 0.1886, 0.3677, 0.5617, 0.8099, 1.1277, 1.3841, 1.5804, 1.8136, - 2.0307, 2.2805, 2.5399, 2.8322, 0.2351, 0.4151, 0.6675, 0.8713, - 1.0464, 1.3292, 1.6586, 1.9281, 2.1355, 2.3495, 2.6222, 2.8782, - 0.2700, 0.4489, 0.6206, 0.7121, 0.7737, 0.9848, 1.3658, 1.7433, - 2.0139, 2.2243, 2.4806, 2.8175, 0.2479, 0.4425, 0.6490, 0.8745, - 1.1161, 1.3849, 1.6773, 1.9566, 2.1491, 2.3624, 2.5685, 2.8114, - 0.2035, 0.3701, 0.5567, 0.7953, 1.0082, 1.2758, 1.5373, 1.7822, - 2.0175, 2.2601, 2.4759, 2.7771, 0.1856, 0.3461, 0.5998, 0.9041, - 1.2383, 1.4612, 1.6667, 1.9305, 2.1617, 2.4107, 2.6477, 2.8656, - 0.2107, 0.3715, 0.5289, 0.6651, 0.8420, 1.1168, 1.4401, 1.7230, - 1.9901, 2.2687, 2.5452, 2.8655, 0.1218, 0.2999, 0.6348, 0.9482, - 1.2745, 1.5876, 1.9129, 2.2348, 2.4020, 2.4922, 2.6351, 2.8357, - 0.1617, 0.3483, 0.5869, 0.8163, 1.0366, 1.2344, 1.4609, 1.7029, - 1.9476, 2.2337, 2.5258, 2.8442, 0.2505, 0.4894, 0.7510, 0.9152, - 1.0845, 1.3657, 1.6528, 1.8346, 2.0160, 2.2811, 2.5338, 2.8136, - 0.0947, 0.1158, 0.0578, -0.0337, -0.0066, 0.0104, -0.0447, -0.0505, --0.0778, -0.0293, 0.0251, -0.0143, 0.0349, -0.0227, -0.0909, 0.0523, - 0.0325, -0.0410, -0.1045, -0.0899, -0.0009, 0.0075, -0.0575, -0.0855, --0.0129, 0.0575, 0.0597, 0.0391, 0.0371, -0.0184, -0.0083, 0.0287, - 0.0143, 0.0167, 0.0120, -0.0168, 0.0452, 0.0223, -0.0352, 0.0119, --0.0496, -0.0965, -0.0661, -0.0072, 0.1099, 0.0843, -0.0087, -0.0478, --0.0128, -0.0120, -0.0004, 0.0731, 0.1047, 0.0630, 0.0196, -0.0103, --0.0399, -0.0986, -0.0912, -0.0390, -0.0247, -0.0694, -0.0749, -0.0066, - 0.0223, 0.0634, 0.0343, -0.0134, 0.0727, 0.0241, 0.0066, 0.0437, - 0.0610, 0.0364, 0.0248, -0.0358, -0.0686, -0.0104, 0.0426, 0.0088, --0.0137, -0.0165, 0.0671, 0.0815, -0.0863, -0.0644, -0.0088, 0.0023, - 0.0482, 0.1174, 0.1270, 0.0594, 0.0165, 0.0949, 0.1098, 0.0137, - 0.4951, 0.4999, 0.4958, 0.4907, 0.4984, 0.4965, 0.4958, 0.4996, - 0.4987, 0.4958, 0.4986, 0.4977, 0.2841, 0.2186, 0.1474, 0.1687, - 0.2217, 0.2632, 0.2706, 0.2624, 0.2162, 0.2453, 0.2460, 0.2531 -}, - -.lsp11 = { - 0.1103, 0.3862, 0.6863, 0.8447, 0.9231, 1.0261, 1.1248, 1.4057, - 1.6621, 1.8010, 1.8692, 2.0704, 2.3490, 2.6060, 2.7539, 2.8977, - 0.1273, 0.2407, 0.3812, 0.6004, 0.7767, 0.9383, 1.1344, 1.3351, - 1.5233, 1.7262, 1.9466, 2.1739, 2.3495, 2.5162, 2.7164, 2.9202, - 0.2010, 0.3330, 0.4488, 0.6465, 0.8046, 0.9889, 1.1479, 1.2964, - 1.4770, 1.6606, 1.8789, 2.1155, 2.3287, 2.5199, 2.7101, 2.9119, - 0.1168, 0.2197, 0.3279, 0.4691, 0.6268, 0.8251, 1.0533, 1.2714, - 1.4712, 1.6762, 1.8831, 2.1114, 2.3230, 2.5297, 2.7365, 2.9270, - 0.1405, 0.3109, 0.4986, 0.6891, 0.8634, 1.0583, 1.2594, 1.4349, - 1.6232, 1.8116, 1.9905, 2.1935, 2.3799, 2.5656, 2.7661, 2.9486, - 0.1703, 0.3057, 0.4403, 0.5225, 0.5969, 0.8110, 1.0729, 1.3215, - 1.5407, 1.7381, 1.9477, 2.1680, 2.3586, 2.5612, 2.7630, 2.9410, - 0.1128, 0.2628, 0.4523, 0.6495, 0.8176, 0.9816, 1.1746, 1.3710, - 1.5568, 1.7518, 1.9497, 2.1452, 2.3346, 2.5389, 2.7362, 2.9264, - 0.1809, 0.3287, 0.5205, 0.7264, 0.9298, 1.1217, 1.2970, 1.4894, - 1.6874, 1.8493, 2.0576, 2.2382, 2.4097, 2.6041, 2.7796, 2.9389, - 0.2502, 0.4709, 0.6892, 0.8346, 0.9209, 1.0455, 1.2399, 1.4616, - 1.6463, 1.8380, 2.0475, 2.2397, 2.4665, 2.6550, 2.7701, 2.8895, - 0.1040, 0.2340, 0.3964, 0.5740, 0.7764, 0.9941, 1.2000, 1.4014, - 1.6024, 1.7974, 1.9939, 2.1959, 2.3783, 2.5663, 2.7613, 2.9484, - 0.1912, 0.3393, 0.4743, 0.6313, 0.8014, 0.9879, 1.1855, 1.3922, - 1.5678, 1.7289, 1.9271, 2.1165, 2.3089, 2.5414, 2.7448, 2.9269, - 0.0965, 0.2025, 0.3398, 0.4990, 0.6934, 0.9386, 1.1730, 1.3766, - 1.5783, 1.7783, 1.9790, 2.1831, 2.3670, 2.5578, 2.7641, 2.9516, - 0.2126, 0.3652, 0.5545, 0.7170, 0.8674, 1.0640, 1.2558, 1.4061, - 1.5904, 1.8095, 1.9760, 2.1505, 2.3549, 2.5575, 2.7023, 2.8877, - 0.1827, 0.3426, 0.4894, 0.6488, 0.7960, 0.9535, 1.1217, 1.2798, - 1.4566, 1.6453, 1.8044, 2.0042, 2.2379, 2.4611, 2.6697, 2.8966, - 0.2034, 0.3822, 0.5231, 0.6960, 0.9200, 1.0394, 1.1616, 1.3772, - 1.5493, 1.7330, 1.9646, 2.1233, 2.3334, 2.5361, 2.7087, 2.9470, - 0.1050, 0.2060, 0.3705, 0.5998, 0.8337, 1.0577, 1.2559, 1.4327, - 1.6334, 1.8165, 1.9853, 2.2058, 2.4063, 2.5818, 2.7625, 2.9458, - 0.1419, 0.4053, 0.6660, 0.8911, 1.0405, 1.1547, 1.2506, 1.3926, - 1.5669, 1.7527, 1.9694, 2.2054, 2.3889, 2.5743, 2.7586, 2.9174, - 0.1514, 0.2825, 0.4309, 0.5772, 0.7470, 0.9703, 1.1462, 1.3316, - 1.5321, 1.7259, 1.9282, 2.1266, 2.3106, 2.5064, 2.7067, 2.9094, - 0.1693, 0.3156, 0.4878, 0.6635, 0.8206, 0.9569, 1.1154, 1.3064, - 1.5109, 1.7184, 1.9179, 2.1036, 2.2763, 2.4820, 2.6949, 2.9105, - 0.1432, 0.2718, 0.4241, 0.5564, 0.6939, 0.9011, 1.1582, 1.3948, - 1.6181, 1.8024, 1.9814, 2.1740, 2.3459, 2.5456, 2.7491, 2.9307, - 0.2294, 0.3857, 0.5590, 0.7434, 0.9189, 1.0941, 1.2740, 1.4456, - 1.6178, 1.7994, 1.9689, 2.1644, 2.3525, 2.5385, 2.7468, 2.9405, - 0.1667, 0.3109, 0.4612, 0.6032, 0.7375, 0.8866, 1.0840, 1.3053, - 1.4982, 1.7044, 1.9146, 2.1117, 2.2942, 2.4983, 2.7084, 2.9132, - 0.1810, 0.3205, 0.4696, 0.6231, 0.7641, 0.9959, 1.2427, 1.4361, - 1.5889, 1.7544, 1.9083, 2.0733, 2.2457, 2.4461, 2.6793, 2.9098, - 0.1164, 0.3753, 0.6068, 0.7503, 1.0100, 1.2131, 1.3793, 1.5302, - 1.6300, 1.7950, 1.9057, 2.1031, 2.3830, 2.5745, 2.6949, 2.8779, - 0.1571, 0.4378, 0.6735, 0.8312, 0.8944, 0.9818, 1.1622, 1.4094, - 1.6423, 1.8066, 1.9258, 2.1838, 2.4363, 2.6279, 2.7358, 2.8790, - 0.1398, 0.2686, 0.4248, 0.6156, 0.7870, 1.0035, 1.2012, 1.3689, - 1.5363, 1.7398, 1.9604, 2.1619, 2.3345, 2.5097, 2.7271, 2.9368, - 0.1913, 0.3338, 0.4987, 0.6446, 0.7852, 1.0163, 1.1886, 1.3610, - 1.5379, 1.7230, 1.8880, 2.0862, 2.2960, 2.4928, 2.7122, 2.9151, - 0.0908, 0.1752, 0.2899, 0.5365, 0.7761, 1.0100, 1.2124, 1.4060, - 1.6019, 1.8010, 1.9774, 2.1905, 2.3733, 2.5623, 2.7660, 2.9565, - 0.1773, 0.3179, 0.4925, 0.6864, 0.8452, 0.9897, 1.1860, 1.3722, - 1.5515, 1.7658, 1.9802, 2.1819, 2.3620, 2.5442, 2.7250, 2.9220, - 0.1286, 0.2341, 0.3689, 0.5364, 0.7176, 0.9350, 1.1083, 1.2943, - 1.4974, 1.7059, 1.9047, 2.1145, 2.3242, 2.5361, 2.7453, 2.9329, - 0.2273, 0.3834, 0.5565, 0.7192, 0.8431, 0.9962, 1.1763, 1.3571, - 1.5774, 1.7419, 1.9202, 2.1131, 2.2919, 2.4898, 2.6895, 2.9180, - 0.1775, 0.3058, 0.4274, 0.6023, 0.8151, 1.0734, 1.3211, 1.5178, - 1.6706, 1.8154, 1.9686, 2.1537, 2.3461, 2.5276, 2.7181, 2.9121, - 0.1653, 0.4304, 0.6361, 0.7824, 0.9183, 1.0452, 1.2071, 1.4077, - 1.6206, 1.8299, 2.0089, 2.1948, 2.3900, 2.5982, 2.7844, 2.9487, - 0.1492, 0.2609, 0.3820, 0.5485, 0.7243, 0.9319, 1.1538, 1.3579, - 1.5266, 1.7002, 1.8873, 2.1016, 2.3175, 2.5221, 2.7241, 2.9243, - 0.2074, 0.3781, 0.5209, 0.6869, 0.8577, 0.9875, 1.1849, 1.3568, - 1.4907, 1.7335, 1.8902, 2.1224, 2.3099, 2.4918, 2.7023, 2.8765, - 0.1359, 0.2254, 0.3286, 0.4432, 0.6586, 0.8964, 1.1125, 1.3523, - 1.5626, 1.7579, 1.9846, 2.1905, 2.3548, 2.5542, 2.7663, 2.9346, - 0.1430, 0.2966, 0.4685, 0.6493, 0.8315, 1.0304, 1.2220, 1.4082, - 1.5995, 1.7888, 1.9774, 2.1737, 2.3607, 2.5577, 2.7558, 2.9405, - 0.1477, 0.2694, 0.4056, 0.5626, 0.7051, 0.8647, 1.0491, 1.2488, - 1.4814, 1.7072, 1.9150, 2.1147, 2.3038, 2.5144, 2.7184, 2.9202, - 0.1690, 0.3033, 0.4580, 0.6686, 0.8536, 1.0293, 1.2124, 1.3998, - 1.5718, 1.7607, 1.9580, 2.1245, 2.2971, 2.4762, 2.6896, 2.9177, - 0.1092, 0.2779, 0.4853, 0.6880, 0.9011, 1.0953, 1.2752, 1.4618, - 1.6623, 1.8484, 2.0264, 2.2152, 2.4017, 2.5835, 2.7671, 2.9436, - 0.1497, 0.3637, 0.6014, 0.8032, 0.9963, 1.1835, 1.3741, 1.5698, - 1.7382, 1.9094, 2.0710, 2.2392, 2.4082, 2.5926, 2.7762, 2.9536, - 0.1434, 0.2492, 0.3966, 0.5934, 0.8033, 1.0657, 1.2796, 1.4276, - 1.5745, 1.7833, 1.9288, 2.1247, 2.3543, 2.5412, 2.7049, 2.8872, - 0.1612, 0.2926, 0.4574, 0.6387, 0.8265, 1.0180, 1.1808, 1.3526, - 1.5564, 1.7536, 1.9187, 2.1192, 2.3149, 2.5006, 2.7101, 2.9217, - 0.0828, 0.1863, 0.3235, 0.5050, 0.7250, 0.9867, 1.2093, 1.3941, - 1.5980, 1.7932, 1.9809, 2.1894, 2.3918, 2.5773, 2.7540, 2.9329, - 0.2001, 0.3655, 0.5290, 0.6761, 0.8027, 0.9972, 1.2090, 1.4255, - 1.6085, 1.7825, 1.9804, 2.1681, 2.3457, 2.5325, 2.7319, 2.9196, - 0.1505, 0.2767, 0.4254, 0.6054, 0.7821, 0.9567, 1.1294, 1.3080, - 1.4984, 1.6954, 1.8666, 2.0736, 2.2875, 2.4969, 2.7072, 2.9163, - 0.1589, 0.4151, 0.5749, 0.6651, 0.8061, 1.0470, 1.2616, 1.3690, - 1.4985, 1.7808, 1.9825, 2.1068, 2.2751, 2.5448, 2.7133, 2.8689, - 0.0916, 0.1846, 0.3788, 0.6329, 0.8774, 1.0687, 1.2653, 1.4561, - 1.6573, 1.8449, 2.0402, 2.2254, 2.3968, 2.5861, 2.7792, 2.9508, - 0.2282, 0.4159, 0.5834, 0.6899, 0.8108, 1.0321, 1.2795, 1.5262, - 1.6936, 1.8469, 2.0922, 2.2607, 2.3795, 2.5301, 2.7386, 2.9530, - 0.1651, 0.3004, 0.4555, 0.6179, 0.7891, 0.9584, 1.1372, 1.3707, - 1.5951, 1.7880, 1.9434, 2.1465, 2.3311, 2.5081, 2.6977, 2.8970, - 0.1279, 0.3828, 0.6330, 0.8323, 0.9652, 1.1175, 1.2319, 1.3511, - 1.5115, 1.6392, 1.7835, 1.9558, 2.2008, 2.4635, 2.6910, 2.9058, - 0.1193, 0.2185, 0.3521, 0.5311, 0.7378, 0.9239, 1.1105, 1.3217, - 1.5362, 1.7504, 1.9536, 2.1627, 2.3560, 2.5506, 2.7548, 2.9453, - 0.1806, 0.3432, 0.4981, 0.6948, 0.8928, 1.0527, 1.2467, 1.4140, - 1.6326, 1.7950, 1.9935, 2.1969, 2.3512, 2.5682, 2.7445, 2.9277, - 0.1846, 0.3112, 0.4568, 0.5891, 0.7317, 0.8493, 1.0204, 1.2022, - 1.3688, 1.6020, 1.8428, 2.0710, 2.2725, 2.4879, 2.7057, 2.9160, - 0.0880, 0.2514, 0.5332, 0.7272, 0.8906, 1.1354, 1.3199, 1.4941, - 1.6010, 1.7151, 1.8712, 2.0643, 2.2755, 2.5375, 2.7054, 2.8891, - 0.1382, 0.2833, 0.4658, 0.6897, 0.9071, 1.0716, 1.2469, 1.4143, - 1.5910, 1.7947, 1.9805, 2.1581, 2.3338, 2.5215, 2.7292, 2.9211, - 0.1061, 0.3494, 0.6327, 0.8570, 0.9748, 1.0560, 1.1529, 1.3250, - 1.6032, 1.8340, 1.9711, 2.1157, 2.3011, 2.5464, 2.8078, 2.9803, - 0.1603, 0.2839, 0.4307, 0.5980, 0.7980, 1.0399, 1.1971, 1.3524, - 1.5715, 1.7838, 1.9468, 2.1498, 2.3627, 2.5514, 2.7327, 2.9148, - 0.1691, 0.3117, 0.4796, 0.6895, 0.8732, 1.0164, 1.1916, 1.3707, - 1.5384, 1.7202, 1.8857, 2.0672, 2.2487, 2.4593, 2.6789, 2.8940, - 0.0965, 0.1702, 0.3191, 0.5721, 0.8100, 1.0241, 1.2272, 1.4196, - 1.6093, 1.8057, 1.9884, 2.2037, 2.3925, 2.5805, 2.7578, 2.9366, - 0.1950, 0.3519, 0.5272, 0.6973, 0.8732, 1.0656, 1.2112, 1.3959, - 1.6116, 1.7821, 1.9445, 2.1592, 2.3348, 2.5142, 2.7440, 2.9297, - 0.1388, 0.2557, 0.4120, 0.5727, 0.7354, 0.9196, 1.0985, 1.2805, - 1.4643, 1.6535, 1.8340, 2.0546, 2.2758, 2.4778, 2.6921, 2.9122, - 0.1823, 0.3336, 0.4957, 0.6771, 0.8563, 1.0137, 1.2299, 1.3849, - 1.5718, 1.7667, 1.9193, 2.1326, 2.3135, 2.5268, 2.7133, 2.8998, - 0.0790, 0.1901, 0.4083, 0.6456, 0.8463, 1.0285, 1.2297, 1.4181, - 1.6159, 1.8056, 1.9971, 2.1912, 2.3816, 2.5746, 2.7692, 2.9497, - 0.0049, 0.0116, 0.0045, 0.0039, -0.0010, -0.0122, -0.0205, -0.0034, --0.0140, -0.0041, 0.0191, -0.0322, 0.0002, -0.0124, -0.0269, 0.0059, - 0.0586, 0.0339, -0.0389, -0.0319, -0.0079, -0.0205, -0.0363, -0.0211, - 0.0241, 0.0595, 0.0469, 0.0283, 0.0176, -0.0183, -0.0173, -0.0004, - 0.0024, 0.0145, 0.0534, 0.0197, -0.0065, -0.0067, 0.0133, 0.0358, --0.0104, -0.0386, -0.0109, -0.0078, 0.0275, 0.0565, 0.0251, -0.0027, --0.0053, 0.0171, 0.0088, 0.0495, 0.0141, 0.0039, -0.0445, -0.0426, --0.0184, -0.0280, -0.0223, 0.0039, -0.0171, -0.0606, -0.0786, -0.0430, - 0.0544, 0.0595, 0.0320, -0.0012, 0.0108, 0.0185, 0.0066, 0.0408, - 0.0552, -0.0073, -0.0247, -0.0480, -0.0288, 0.0186, 0.0212, -0.0013, - 0.0403, 0.0598, 0.0690, 0.0516, -0.0298, -0.0177, 0.0278, 0.0168, --0.0106, 0.0251, 0.0386, 0.0331, -0.0052, 0.0133, 0.0291, -0.0158, --0.0329, -0.0367, 0.0287, 0.0462, -0.0176, 0.0049, 0.0242, -0.0034, - 0.0135, 0.0086, -0.0149, 0.0241, 0.0504, 0.0246, -0.0273, -0.0369, --0.0108, -0.0449, -0.0625, -0.0414, -0.0292, -0.0571, -0.0440, -0.0088, - 0.0098, 0.0009, -0.0004, 0.0007, -0.0314, -0.0208, -0.0138, -0.0277, --0.0044, 0.0522, 0.0315, -0.0270, -0.0277, -0.0256, -0.0103, -0.0201, --0.0287, -0.0279, -0.0182, 0.0472, 0.0613, 0.0450, 0.0413, 0.0333, - 0.0444, 0.0223, 0.0061, 0.0316, 0.0321, 0.0501, 0.0460, 0.0250, - 0.0227, 0.0235, 0.0099, 0.0185, -0.0347, -0.0684, -0.0189, 0.0242, --0.0190, -0.0273, -0.0012, -0.0253, 0.0293, -0.0231, -0.0219, -0.0010, - 0.0153, 0.0128, -0.0166, -0.0435, -0.0417, -0.0121, -0.0351, -0.0390, - 0.0077, -0.0278, -0.0355, 0.0092, -0.0063, 0.0005, 0.0216, 0.0461, - 0.0538, 0.0451, 0.0298, -0.0130, 0.0058, 0.0206, 0.0471, 0.0499, - 0.0280, 0.0086, -0.0007, -0.0317, 0.0259, 0.0176, 0.0043, 0.0212, - 0.0138, 0.0106, 0.0220, -0.0025, 0.0050, 0.0122, -0.0051, -0.0086, --0.0472, -0.0005, 0.0193, 0.0032, 0.0246, 0.0222, 0.0090, -0.0320, --0.0713, -0.0526, -0.0151, -0.0440, -0.0648, -0.0466, -0.0092, 0.0115, --0.0129, 0.0053, -0.0344, -0.0385, 0.0392, 0.0599, 0.0414, 0.0165, --0.0098, -0.0320, -0.0261, -0.0055, -0.0139, -0.0110, 0.0084, 0.0172, --0.0492, -0.0537, -0.0320, -0.0036, 0.0265, 0.0385, 0.0064, -0.0280, --0.0230, 0.0134, 0.0241, 0.0106, 0.0387, 0.0105, 0.0068, 0.0260, - 0.4940, 0.4911, 0.4849, 0.4820, 0.4837, 0.4839, 0.4824, 0.4799, - 0.4812, 0.4782, 0.4788, 0.4711, 0.4706, 0.4671, 0.4601, 0.4578, - 0.2954, 0.2121, 0.1859, 0.1958, 0.1474, 0.1086, 0.1351, 0.1362, - 0.1486, 0.1342, 0.1215, 0.1423, 0.1634, 0.1588, 0.1539, 0.1857 -}, - -.lsp16 = { - 0.1813, 0.3911, 0.6301, 0.8012, 1.0057, 1.2041, 1.4271, 1.6943, - 1.9402, 2.1733, 2.3521, 2.4989, 2.5839, 2.6846, 2.7634, 2.8950, - 0.1311, 0.3183, 0.4659, 0.5601, 0.6658, 0.7828, 1.0065, 1.2717, - 1.5185, 1.7339, 1.9530, 2.2189, 2.3739, 2.4991, 2.6984, 2.9256, - 0.1627, 0.4519, 0.6323, 0.7012, 0.7848, 0.9801, 1.1810, 1.3222, - 1.5413, 1.8129, 1.9338, 2.0809, 2.3180, 2.5189, 2.7066, 2.9514, - 0.1475, 0.2447, 0.4240, 0.5669, 0.7872, 0.9838, 1.1823, 1.3814, - 1.5358, 1.6820, 1.8794, 2.1419, 2.4132, 2.6112, 2.7911, 2.9511, - 0.1224, 0.2876, 0.5013, 0.6985, 0.8902, 1.0901, 1.2835, 1.4768, - 1.6596, 1.8538, 2.0467, 2.2304, 2.4124, 2.5942, 2.7729, 2.9531, - 0.1741, 0.3034, 0.4677, 0.5879, 0.7258, 0.9648, 1.1417, 1.3220, - 1.5081, 1.7151, 1.9212, 2.1286, 2.3208, 2.4938, 2.6765, 2.8891, - 0.1657, 0.3174, 0.4907, 0.6559, 0.8295, 1.0254, 1.2071, 1.3880, - 1.5737, 1.7845, 1.9027, 2.1139, 2.3323, 2.5157, 2.7323, 2.9015, - 0.1592, 0.2758, 0.4417, 0.6315, 0.8257, 0.9873, 1.1277, 1.2830, - 1.4337, 1.6315, 1.8899, 2.1356, 2.3572, 2.5632, 2.7468, 2.9420, - 0.1524, 0.4325, 0.5931, 0.7036, 0.7696, 0.8923, 1.1739, 1.4773, - 1.6609, 1.7911, 1.9666, 2.1972, 2.3754, 2.5045, 2.6613, 2.8882, - 0.2130, 0.3013, 0.3721, 0.4257, 0.5079, 0.7015, 0.9815, 1.2554, - 1.4648, 1.6966, 1.9138, 2.1075, 2.3318, 2.5292, 2.7453, 2.9347, - 0.1142, 0.3748, 0.6205, 0.7642, 0.8121, 0.9022, 0.9843, 1.1558, - 1.4467, 1.7422, 1.9574, 2.1302, 2.3812, 2.5898, 2.7720, 2.9583, - 0.1255, 0.2339, 0.3570, 0.5323, 0.7458, 1.0003, 1.1729, 1.3567, - 1.5217, 1.6977, 1.8924, 2.0942, 2.3145, 2.5408, 2.7553, 2.9337, - 0.1316, 0.2289, 0.4327, 0.6663, 0.8509, 0.9994, 1.1697, 1.3804, - 1.5609, 1.6903, 1.8572, 2.1019, 2.3687, 2.5789, 2.7715, 2.9472, - 0.1502, 0.2546, 0.3883, 0.5333, 0.6976, 0.9163, 1.1071, 1.3364, - 1.5420, 1.7525, 1.8948, 2.0839, 2.2819, 2.4651, 2.6875, 2.8987, - 0.1593, 0.3014, 0.4573, 0.6354, 0.8157, 0.9805, 1.1783, 1.3747, - 1.5678, 1.7326, 1.9286, 2.1340, 2.3253, 2.5280, 2.7180, 2.9298, - 0.1811, 0.3167, 0.4655, 0.6507, 0.8198, 1.0075, 1.1892, 1.3743, - 1.5227, 1.7090, 1.8849, 2.0743, 2.2750, 2.4830, 2.6896, 2.8953, - 0.1846, 0.3577, 0.5315, 0.7290, 0.9176, 1.1016, 1.2654, 1.4525, - 1.6315, 1.8268, 2.0238, 2.1934, 2.3868, 2.5753, 2.7682, 2.9469, - 0.0876, 0.1439, 0.2048, 0.3654, 0.6281, 0.8853, 1.0907, 1.2992, - 1.5227, 1.7373, 1.9395, 2.1419, 2.3488, 2.5486, 2.7466, 2.9348, - 0.1391, 0.4170, 0.6561, 0.7953, 0.8734, 0.9986, 1.1870, 1.4520, - 1.6042, 1.7910, 2.0135, 2.1870, 2.3358, 2.5066, 2.7409, 2.9955, - 0.0804, 0.1355, 0.2599, 0.4998, 0.7408, 0.9474, 1.1276, 1.3428, - 1.5556, 1.7712, 1.9699, 2.1535, 2.3605, 2.5548, 2.7489, 2.9325, - 0.1304, 0.3087, 0.4979, 0.6584, 0.8414, 1.0329, 1.2244, 1.4189, - 1.6118, 1.8200, 1.9985, 2.1893, 2.3915, 2.5794, 2.7647, 2.9344, - 0.1895, 0.2849, 0.3705, 0.4126, 0.6265, 0.9207, 1.1774, 1.3762, - 1.5757, 1.7728, 1.9568, 2.1662, 2.3615, 2.5575, 2.7561, 2.9416, - 0.1800, 0.3078, 0.4805, 0.6796, 0.8503, 1.0046, 1.1703, 1.3269, - 1.4862, 1.6502, 1.8454, 2.0873, 2.3175, 2.5356, 2.7516, 2.9469, - 0.1950, 0.3233, 0.4568, 0.5940, 0.7589, 0.9978, 1.1701, 1.3383, - 1.5017, 1.6565, 1.8243, 2.0605, 2.2938, 2.5147, 2.7419, 2.9396, - 0.2531, 0.4391, 0.5790, 0.7170, 0.8998, 1.1430, 1.3577, 1.5326, - 1.6328, 1.7627, 1.9726, 2.1762, 2.3563, 2.5478, 2.7385, 2.9067, - 0.1805, 0.2788, 0.3591, 0.3881, 0.5441, 0.8055, 1.0766, 1.3165, - 1.5316, 1.7508, 1.9477, 2.1374, 2.3438, 2.5484, 2.7501, 2.9410, - 0.2044, 0.3671, 0.5396, 0.7042, 0.8582, 0.9831, 1.1261, 1.3194, - 1.4769, 1.6979, 1.8717, 2.0463, 2.2620, 2.4739, 2.7054, 2.9208, - 0.1048, 0.2175, 0.4206, 0.5923, 0.7483, 0.9400, 1.1356, 1.3799, - 1.5958, 1.7320, 1.8984, 2.1296, 2.3594, 2.5492, 2.7387, 2.9305, - 0.0842, 0.1729, 0.3951, 0.6447, 0.8688, 1.0605, 1.2472, 1.4330, - 1.6232, 1.8144, 2.0216, 2.1915, 2.3878, 2.5763, 2.7685, 2.9464, - 0.1461, 0.2593, 0.4105, 0.5677, 0.7328, 0.8919, 1.0484, 1.2302, - 1.4386, 1.6635, 1.8873, 2.1024, 2.3116, 2.5268, 2.7273, 2.9269, - 0.1503, 0.3108, 0.4756, 0.6731, 0.8600, 1.0233, 1.2115, 1.3971, - 1.5915, 1.7892, 1.9517, 2.1603, 2.3487, 2.5460, 2.7308, 2.8998, - 0.2163, 0.3669, 0.5125, 0.6709, 0.8143, 0.9930, 1.2095, 1.4205, - 1.6176, 1.7112, 1.8398, 2.0896, 2.3513, 2.5290, 2.6667, 2.8960, - 0.2133, 0.4382, 0.6287, 0.8702, 1.1088, 1.3749, 1.6062, 1.7446, - 1.8333, 1.9122, 1.9614, 2.0669, 2.1789, 2.3449, 2.6038, 2.8849, - 0.1598, 0.2719, 0.3877, 0.4815, 0.5926, 0.7795, 1.0449, 1.3045, - 1.5210, 1.7391, 1.9462, 2.1397, 2.3553, 2.5458, 2.7540, 2.9392, - 0.2918, 0.5607, 0.6801, 0.7404, 0.8285, 0.9431, 1.1579, 1.4080, - 1.6332, 1.8472, 1.9738, 2.0771, 2.2890, 2.5178, 2.7445, 2.9830, - 0.1664, 0.2842, 0.3965, 0.5463, 0.8162, 1.0346, 1.1849, 1.3446, - 1.5122, 1.7563, 1.9960, 2.2002, 2.3796, 2.5689, 2.7712, 2.9550, - 0.0911, 0.2397, 0.5052, 0.7868, 1.0299, 1.1311, 1.2244, 1.3333, - 1.4395, 1.6790, 1.9369, 2.1717, 2.3689, 2.5538, 2.7340, 2.9326, - 0.1647, 0.2931, 0.3836, 0.4978, 0.6255, 0.9243, 1.1339, 1.3001, - 1.5269, 1.8010, 1.9715, 2.1419, 2.3784, 2.5503, 2.6719, 2.8745, - 0.2440, 0.3802, 0.4756, 0.6613, 0.8627, 1.0292, 1.2291, 1.4060, - 1.5198, 1.7354, 1.9044, 2.1010, 2.3147, 2.4996, 2.7171, 2.9041, - 0.1590, 0.2876, 0.4572, 0.5996, 0.7713, 0.9490, 1.1205, 1.2815, - 1.4516, 1.6385, 1.8179, 2.0457, 2.2759, 2.4785, 2.6861, 2.9080, - 0.2297, 0.4309, 0.5712, 0.6717, 0.8138, 1.0463, 1.2492, 1.4560, - 1.6796, 1.8458, 1.9642, 2.1452, 2.3636, 2.5395, 2.7456, 2.9495, - 0.2975, 0.4678, 0.4996, 0.5809, 0.6279, 0.6884, 0.8606, 1.1386, - 1.4412, 1.6876, 1.8760, 2.0932, 2.3178, 2.5166, 2.7345, 2.9280, - 0.1278, 0.3737, 0.6004, 0.7069, 0.8147, 1.0180, 1.2581, 1.3812, - 1.4855, 1.7268, 1.9970, 2.1258, 2.2936, 2.5702, 2.7563, 2.8983, - 0.1314, 0.2508, 0.3999, 0.5680, 0.7424, 0.9367, 1.1286, 1.3175, - 1.5336, 1.7404, 1.9317, 2.1404, 2.3514, 2.5562, 2.7510, 2.9402, - 0.1043, 0.2367, 0.4293, 0.6376, 0.8160, 0.9836, 1.1779, 1.3850, - 1.5835, 1.7875, 1.9765, 2.1593, 2.3654, 2.5577, 2.7465, 2.9398, - 0.1529, 0.2515, 0.3454, 0.4374, 0.7011, 0.9015, 1.0744, 1.3532, - 1.5699, 1.7545, 2.0021, 2.1259, 2.2278, 2.4546, 2.7264, 2.9425, - 0.1429, 0.2808, 0.4395, 0.6334, 0.8069, 0.9705, 1.1520, 1.3250, - 1.5109, 1.7285, 1.9356, 2.1469, 2.3479, 2.5554, 2.7512, 2.9348, - 0.1625, 0.3022, 0.4756, 0.6315, 0.8032, 0.9924, 1.1596, 1.3204, - 1.4994, 1.6929, 1.8955, 2.1090, 2.3025, 2.5018, 2.6908, 2.8980, - 0.1692, 0.3427, 0.5228, 0.7756, 0.9688, 1.0950, 1.3056, 1.4360, - 1.5675, 1.8049, 1.9376, 2.1151, 2.3407, 2.5012, 2.7192, 2.9258, - 0.0474, 0.1251, 0.1939, 0.3841, 0.6501, 0.9231, 1.1153, 1.3240, - 1.5478, 1.7599, 1.9651, 2.1510, 2.3645, 2.5552, 2.7542, 2.9393, - 0.2196, 0.4656, 0.7492, 0.9922, 1.1678, 1.2489, 1.3112, 1.3657, - 1.4223, 1.5302, 1.7212, 1.9996, 2.2523, 2.4844, 2.7036, 2.9145, - 0.1128, 0.2368, 0.3704, 0.5476, 0.7723, 0.9968, 1.1930, 1.3992, - 1.6013, 1.7957, 1.9888, 2.1857, 2.3825, 2.5705, 2.7616, 2.9434, - 0.1341, 0.2768, 0.4510, 0.6359, 0.8332, 1.0335, 1.2004, 1.3952, - 1.5762, 1.7681, 1.9815, 2.1735, 2.3657, 2.5552, 2.7514, 2.9498, - 0.1247, 0.2559, 0.3516, 0.4726, 0.6861, 0.9483, 1.1852, 1.3858, - 1.5851, 1.7815, 1.9778, 2.1737, 2.3729, 2.5664, 2.7620, 2.9429, - 0.1988, 0.3320, 0.4777, 0.6737, 0.8425, 1.0265, 1.1694, 1.3655, - 1.5463, 1.7135, 1.9385, 2.1650, 2.3529, 2.5367, 2.7545, 2.9585, - 0.1376, 0.2620, 0.4273, 0.6169, 0.7755, 0.9441, 1.1169, 1.3157, - 1.5179, 1.7020, 1.8931, 2.1059, 2.3112, 2.5136, 2.7169, 2.9198, - 0.2112, 0.4385, 0.6091, 0.7618, 0.9553, 1.1543, 1.3445, 1.5396, - 1.7153, 1.9192, 2.1263, 2.3593, 2.5958, 2.8171, 2.9394, 3.0409, - 0.1347, 0.2099, 0.2646, 0.3453, 0.5266, 0.7869, 1.0513, 1.2795, - 1.4880, 1.7181, 1.9294, 2.1332, 2.3362, 2.5442, 2.7433, 2.9362, - 0.3141, 0.5935, 0.7517, 0.8313, 0.8568, 0.9570, 1.0250, 1.1275, - 1.3422, 1.6303, 1.8577, 2.0705, 2.2957, 2.5095, 2.7244, 2.9262, - 0.0962, 0.2116, 0.3961, 0.5641, 0.7122, 0.8883, 1.1023, 1.3481, - 1.5623, 1.7554, 1.9618, 2.1675, 2.3706, 2.5556, 2.7430, 2.9337, - 0.0898, 0.1510, 0.3060, 0.5820, 0.8221, 1.0388, 1.2261, 1.4289, - 1.6054, 1.8103, 1.9941, 2.1844, 2.3742, 2.5711, 2.7632, 2.9474, - 0.1326, 0.2316, 0.3761, 0.5177, 0.6782, 0.8761, 1.0952, 1.3175, - 1.5078, 1.7034, 1.9051, 2.1245, 2.3424, 2.5484, 2.7444, 2.9389, - 0.1740, 0.3293, 0.5174, 0.6824, 0.8394, 1.0372, 1.2046, 1.3723, - 1.5656, 1.7444, 1.9442, 2.1386, 2.3139, 2.4960, 2.7071, 2.9297, - 0.2304, 0.3775, 0.4865, 0.6182, 0.7842, 0.9208, 1.1151, 1.2843, - 1.4641, 1.6988, 1.9209, 2.1260, 2.3099, 2.5229, 2.7414, 2.9276, - 0.0094, 0.0261, -0.0037, 0.0041, -0.0092, -0.0044, -0.0232, -0.0073, --0.0047, -0.0021, 0.0250, -0.0580, -0.0140, -0.0342, -0.0586, 0.0020, - 0.0449, 0.0155, -0.0523, -0.0279, 0.0299, -0.0183, -0.0736, -0.0639, --0.0017, 0.0336, 0.0209, 0.0046, 0.0077, -0.0148, -0.0114, -0.0120, - 0.0115, -0.0050, 0.0445, 0.0048, 0.0188, -0.0137, -0.0080, 0.0239, --0.0184, -0.0524, -0.0195, -0.0126, 0.0284, 0.0632, 0.0141, -0.0093, --0.0096, 0.0196, 0.0230, 0.0379, 0.0308, 0.0237, -0.0224, -0.0600, --0.0755, -0.1074, -0.0988, -0.0606, -0.1038, -0.1552, -0.1480, -0.0672, - 0.0504, 0.0676, 0.0336, -0.0042, 0.0729, 0.1013, 0.0868, 0.0846, - 0.0954, 0.0515, -0.0066, -0.0851, -0.0485, 0.0294, 0.0395, 0.0087, - 0.0078, 0.0446, 0.0881, 0.0672, -0.0384, -0.0025, 0.0415, 0.0353, - 0.0080, 0.0052, 0.0190, 0.0182, 0.0069, 0.0168, 0.0374, 0.0037, --0.0292, -0.0429, 0.0302, 0.0681, -0.0233, -0.0238, -0.0003, -0.0043, - 0.0054, -0.0029, -0.0149, 0.0642, 0.0622, 0.0341, -0.0232, -0.0461, --0.0082, -0.0469, -0.0618, -0.0326, -0.0452, -0.0649, -0.0597, -0.0398, --0.0318, -0.0116, 0.0011, 0.0009, -0.0384, -0.0384, -0.0156, -0.0260, --0.0007, 0.0473, 0.0111, -0.0358, -0.0484, -0.0204, -0.0029, -0.0090, --0.0285, -0.0495, -0.0376, 0.0917, 0.1192, 0.1026, 0.0745, 0.0397, - 0.0463, 0.0253, 0.0025, 0.0465, 0.0100, 0.0488, 0.0416, 0.0223, - 0.0263, 0.0072, -0.0053, 0.0595, 0.0060, -0.0518, -0.0316, -0.0043, --0.0133, -0.0233, -0.0075, -0.0251, 0.0277, -0.0067, -0.0136, -0.0004, - 0.0235, 0.0112, -0.0182, -0.0324, -0.0210, -0.0035, -0.0395, -0.0384, - 0.0005, -0.0150, -0.0356, 0.0127, -0.0033, -0.0034, 0.0205, 0.0747, - 0.1138, 0.1015, 0.0995, -0.0161, -0.0045, 0.0129, 0.0472, 0.0575, - 0.0222, 0.0091, 0.0037, -0.0471, 0.0371, 0.0132, 0.0208, 0.0247, - 0.0117, 0.0164, 0.0225, 0.0124, -0.0023, 0.0088, -0.0046, 0.0047, --0.0393, 0.0018, 0.0148, 0.0020, 0.0044, 0.0165, 0.0229, -0.0208, --0.0477, -0.0310, -0.0164, -0.0390, -0.0764, -0.0525, -0.0094, 0.0075, --0.0102, -0.0045, -0.0504, -0.0709, 0.0822, 0.0710, 0.0426, 0.0014, --0.0371, -0.0400, -0.0157, -0.0155, -0.0173, -0.0138, -0.0015, 0.0134, --0.0418, -0.0682, -0.0256, 0.0050, 0.0360, 0.0354, 0.0074, -0.0396, --0.0235, 0.0284, 0.0494, 0.0153, 0.0448, 0.0025, -0.0061, 0.0252, - 0.1000, 0.2260, 0.2158, 0.2116, 0.2198, 0.2055, 0.2110, 0.1873, - 0.1907, 0.2071, 0.2164, 0.2009, 0.2059, 0.2124, 0.2141, 0.2093, - 0.0875, 0.0981, 0.1177, 0.1071, 0.1033, 0.1248, 0.1048, 0.1238, - 0.1166, 0.1008, 0.1062, 0.0992, 0.0994, 0.1067, 0.0999, 0.1187, - 0.0750, 0.0794, 0.0828, 0.0854, 0.0859, 0.0801, 0.0891, 0.0933, - 0.0969, 0.0920, 0.0915, 0.0862, 0.0868, 0.0891, 0.0842, 0.0824, - 0.0625, 0.0930, 0.0815, 0.0853, 0.0898, 0.0828, 0.0822, 0.0910, - 0.0873, 0.0906, 0.0856, 0.0840, 0.0774, 0.0785, 0.0684, 0.0711, - 0.3319, 0.4219, 0.4588, 0.4090, 0.4092, 0.4014, 0.3548, 0.3353, - 0.3708, 0.3352, 0.3720, 0.3538, 0.4084, 0.4289, 0.4060, 0.4210, - 0.0588, 0.0209, -0.0082, -0.0115, -0.0343, -0.0621, -0.0541, -0.0346, --0.0346, -0.0366, -0.0220, -0.0265, -0.0102, 0.0374, 0.0306, 0.0404, - 0.0306, 0.0090, -0.0054, 0.0333, 0.0047, 0.0238, 0.0141, 0.0165, - 0.0306, 0.0420, 0.0159, 0.0124, 0.0414, 0.0158, -0.0237, 0.0141, - 0.0765, 0.0057, -0.0260, -0.0426, -0.0395, -0.0126, -0.0579, -0.0417 -}, - -.lsp22_1 = { - 0.0664, 0.1875, 0.4300, 0.6730, 0.8793, 1.0640, 1.2563, 1.4433, - 1.6394, 1.8176, 2.0029, 2.1921, 2.3796, 2.5671, 2.7595, 2.9536, - 0.2128, 0.4052, 0.5311, 0.6404, 0.7875, 0.8775, 1.0974, 1.3261, - 1.5563, 1.6790, 1.8339, 2.1195, 2.3226, 2.4609, 2.6440, 2.8947, - 0.2024, 0.3362, 0.4834, 0.6784, 0.9088, 1.0850, 1.2188, 1.4054, - 1.6102, 1.7767, 1.9679, 2.1436, 2.3445, 2.5467, 2.7429, 2.9320, - 0.1181, 0.2279, 0.4413, 0.6114, 0.7710, 0.9427, 1.1142, 1.2707, - 1.4892, 1.7416, 1.9526, 2.1466, 2.3629, 2.5445, 2.7293, 2.9205, - 0.1155, 0.2720, 0.4886, 0.6812, 0.8594, 1.0422, 1.2315, 1.4116, - 1.6137, 1.8020, 1.9758, 2.1743, 2.3602, 2.5568, 2.7472, 2.9374, - 0.1110, 0.3312, 0.4735, 0.5612, 0.7129, 0.8146, 1.0233, 1.3155, - 1.5765, 1.7746, 1.9574, 2.1416, 2.3220, 2.5384, 2.7334, 2.9318, - 0.1656, 0.3350, 0.4215, 0.5609, 0.6759, 0.8503, 1.1405, 1.4094, - 1.6057, 1.6860, 1.7639, 2.0031, 2.2680, 2.5076, 2.7263, 2.9368, - 0.1466, 0.3638, 0.4587, 0.5674, 0.7381, 0.8669, 0.9619, 1.1658, - 1.4667, 1.7440, 1.9335, 2.1018, 2.3022, 2.5281, 2.7359, 2.9261, - 0.1061, 0.2566, 0.4739, 0.6751, 0.8711, 1.0704, 1.2720, 1.4655, - 1.6605, 1.8494, 2.0290, 2.2197, 2.4008, 2.5912, 2.7772, 2.9513, - 0.1116, 0.2364, 0.3971, 0.6316, 0.8583, 1.0335, 1.1686, 1.3302, - 1.5612, 1.7877, 1.9829, 2.2052, 2.3596, 2.5460, 2.7341, 2.9290, - 0.2661, 0.4186, 0.5126, 0.6477, 0.8818, 1.1045, 1.2852, 1.4128, - 1.5851, 1.7593, 1.9399, 2.1757, 2.3684, 2.5136, 2.6927, 2.9064, - 0.1495, 0.2749, 0.4391, 0.6304, 0.8239, 1.0181, 1.1995, 1.3759, - 1.5669, 1.7722, 1.9671, 2.1635, 2.3586, 2.5528, 2.7445, 2.9311, - 0.0912, 0.1759, 0.3066, 0.5660, 0.8005, 0.9568, 1.1832, 1.4504, - 1.6259, 1.7948, 2.0113, 2.2002, 2.3654, 2.5583, 2.7929, 2.9735, - 0.1353, 0.2747, 0.4078, 0.5977, 0.7658, 0.9124, 1.1081, 1.3630, - 1.5875, 1.7847, 1.9323, 2.1181, 2.3321, 2.5046, 2.7183, 2.9225, - 0.1938, 0.4063, 0.4982, 0.6002, 0.7702, 0.9071, 1.1631, 1.3885, - 1.6043, 1.8118, 1.9306, 2.0893, 2.2724, 2.4609, 2.6283, 2.8802, - 0.1857, 0.3351, 0.4381, 0.6101, 0.7561, 0.8555, 1.0384, 1.3171, - 1.5667, 1.6904, 1.7552, 1.9689, 2.2597, 2.5260, 2.7272, 2.9337, - 0.1037, 0.2159, 0.4188, 0.6174, 0.8035, 1.0285, 1.2256, 1.4230, - 1.6400, 1.8322, 2.0144, 2.1988, 2.3810, 2.5682, 2.7613, 2.9438, - 0.1625, 0.2776, 0.4225, 0.6001, 0.7879, 0.9087, 1.0801, 1.2759, - 1.4899, 1.7448, 1.9911, 2.1770, 2.3723, 2.5777, 2.7971, 2.9444, - 0.2111, 0.3640, 0.5839, 0.7290, 0.8051, 1.0023, 1.2315, 1.4143, - 1.5878, 1.7755, 1.9804, 2.1498, 2.3312, 2.5350, 2.7613, 2.9472, - 0.1423, 0.2646, 0.4136, 0.6350, 0.8070, 0.9514, 1.1168, 1.3213, - 1.5776, 1.7721, 1.9404, 2.1545, 2.3385, 2.5137, 2.7396, 2.9553, - 0.1132, 0.2386, 0.4103, 0.5931, 0.7808, 0.9881, 1.1840, 1.3860, - 1.6021, 1.7990, 1.9922, 2.1885, 2.3852, 2.5717, 2.7640, 2.9510, - 0.1267, 0.2602, 0.3913, 0.5944, 0.7598, 0.9198, 1.0781, 1.2715, - 1.5299, 1.7573, 1.9308, 2.1346, 2.3267, 2.5419, 2.7466, 2.9320, - 0.2023, 0.3417, 0.4392, 0.6141, 0.7439, 0.8593, 1.1096, 1.3543, - 1.5185, 1.6553, 1.7862, 2.0341, 2.2718, 2.4834, 2.7103, 2.9466, - 0.1113, 0.2470, 0.3677, 0.5686, 0.7700, 0.9356, 1.0806, 1.2452, - 1.4830, 1.7344, 1.9268, 2.1404, 2.3371, 2.5169, 2.7329, 2.9012, - 0.1664, 0.3554, 0.5573, 0.7471, 0.9245, 1.0998, 1.2787, 1.4655, - 1.6654, 1.8346, 2.0179, 2.2159, 2.4096, 2.5946, 2.7790, 2.9530, - 0.1313, 0.2625, 0.4731, 0.6444, 0.8110, 0.9878, 1.1493, 1.3212, - 1.5719, 1.8138, 1.9861, 2.1943, 2.3714, 2.5578, 2.7346, 2.9296, - 0.1186, 0.3035, 0.5049, 0.6860, 0.8670, 0.9975, 1.1364, 1.3471, - 1.5695, 1.7412, 1.9346, 2.1506, 2.3413, 2.5531, 2.7794, 2.9627, - 0.1108, 0.2697, 0.4787, 0.6344, 0.7909, 0.9586, 1.1440, 1.3511, - 1.5686, 1.7601, 1.9246, 2.1241, 2.3293, 2.5390, 2.7315, 2.9333, - 0.0985, 0.2302, 0.3544, 0.5759, 0.7620, 0.9651, 1.1497, 1.3080, - 1.5500, 1.7845, 1.9518, 2.1734, 2.3565, 2.5665, 2.7605, 2.9102, - 0.1208, 0.2727, 0.4381, 0.5736, 0.7382, 0.8390, 1.0102, 1.2648, - 1.5100, 1.7440, 1.9619, 2.1430, 2.3307, 2.5159, 2.7264, 2.9211, - 0.1582, 0.2777, 0.4475, 0.6551, 0.8591, 1.0084, 1.1414, 1.3291, - 1.5902, 1.7826, 1.9543, 2.1659, 2.3233, 2.5044, 2.6935, 2.9199, - 0.1360, 0.2873, 0.4585, 0.6295, 0.7592, 0.9089, 1.0492, 1.2733, - 1.5391, 1.7768, 1.9372, 2.1329, 2.3168, 2.5015, 2.6857, 2.8837, - 0.0886, 0.1829, 0.3696, 0.6126, 0.8334, 1.0135, 1.2303, 1.4674, - 1.6743, 1.8564, 2.0530, 2.2370, 2.3960, 2.5787, 2.7756, 2.9377, - 0.2005, 0.3537, 0.4700, 0.6249, 0.7385, 0.9097, 1.1759, 1.3811, - 1.5314, 1.6705, 1.8546, 2.1229, 2.3292, 2.5251, 2.7951, 2.9646, - 0.1999, 0.3112, 0.4722, 0.7146, 0.8908, 1.0028, 1.1831, 1.3903, - 1.6125, 1.7514, 1.9083, 2.1248, 2.3271, 2.5339, 2.6945, 2.8918, - 0.1243, 0.2606, 0.4382, 0.5850, 0.7705, 0.9727, 1.1214, 1.3059, - 1.5218, 1.7406, 1.9137, 2.1353, 2.3354, 2.5299, 2.7287, 2.9068, - 0.1039, 0.2426, 0.4265, 0.6284, 0.8152, 0.9941, 1.2004, 1.4038, - 1.5912, 1.7763, 1.9650, 2.1598, 2.3474, 2.5488, 2.7419, 2.9322, - 0.1364, 0.2420, 0.3886, 0.5864, 0.7663, 0.8844, 1.0860, 1.3242, - 1.5518, 1.7893, 2.0004, 2.1562, 2.3619, 2.5516, 2.7687, 2.9181, - 0.1483, 0.2851, 0.4479, 0.6312, 0.7924, 0.9821, 1.1705, 1.3386, - 1.5375, 1.7226, 1.9053, 2.0991, 2.2898, 2.4953, 2.7000, 2.9146, - 0.2332, 0.4561, 0.5407, 0.6212, 0.7524, 0.8215, 0.9522, 1.1685, - 1.5216, 1.7132, 1.8291, 2.0647, 2.2811, 2.4857, 2.7071, 2.9281, - 0.1348, 0.3126, 0.5179, 0.7192, 0.9227, 1.1363, 1.3223, 1.4756, - 1.6509, 1.8191, 1.9991, 2.1976, 2.3877, 2.5768, 2.7590, 2.9386, - 0.1093, 0.2211, 0.4763, 0.6703, 0.8282, 0.9536, 1.1202, 1.3796, - 1.6043, 1.8031, 1.9832, 2.1604, 2.3578, 2.5856, 2.7650, 2.9291, - 0.1865, 0.3027, 0.4580, 0.6719, 0.8400, 1.0082, 1.1901, 1.3782, - 1.5448, 1.6885, 1.9477, 2.1381, 2.2797, 2.5113, 2.7465, 2.9414, - 0.1575, 0.3124, 0.4649, 0.6262, 0.8095, 0.9858, 1.1676, 1.3602, - 1.5646, 1.7582, 1.9550, 2.1671, 2.3628, 2.5734, 2.7670, 2.9519, - 0.1174, 0.2777, 0.4663, 0.6333, 0.8169, 1.0096, 1.1885, 1.3847, - 1.5803, 1.7571, 1.9380, 2.1398, 2.3414, 2.5407, 2.7360, 2.9375, - 0.1073, 0.2264, 0.4083, 0.5973, 0.7474, 0.9514, 1.1349, 1.3337, - 1.5433, 1.7348, 1.9380, 2.1436, 2.3441, 2.5438, 2.7457, 2.9383, - 0.1472, 0.2880, 0.4793, 0.6268, 0.8015, 1.0063, 1.1715, 1.3644, - 1.5525, 1.7410, 1.9258, 2.1227, 2.3214, 2.5149, 2.7148, 2.9196, - 0.1414, 0.2565, 0.4349, 0.6111, 0.7695, 0.9496, 1.1212, 1.3265, - 1.5218, 1.7209, 1.9015, 2.0887, 2.3158, 2.5077, 2.7233, 2.9421, - 0.1252, 0.2667, 0.4454, 0.6431, 0.8371, 1.0124, 1.2110, 1.4160, - 1.6240, 1.8242, 2.0047, 2.1974, 2.3902, 2.5778, 2.7637, 2.9481, - 0.1321, 0.2565, 0.3846, 0.5847, 0.7578, 0.9259, 1.0637, 1.2239, - 1.4690, 1.7346, 1.9750, 2.1882, 2.3712, 2.5509, 2.7280, 2.8885, - 0.1437, 0.2930, 0.4428, 0.6156, 0.8045, 0.9638, 1.1450, 1.3138, - 1.5144, 1.7355, 1.9469, 2.1534, 2.3414, 2.5452, 2.7353, 2.9334, - 0.1692, 0.2770, 0.3831, 0.6100, 0.7825, 0.9302, 1.0690, 1.2481, - 1.4615, 1.6799, 1.9165, 2.1739, 2.3435, 2.5349, 2.7520, 2.9163, - 0.1235, 0.2489, 0.4354, 0.6343, 0.8236, 1.0066, 1.1908, 1.3474, - 1.5656, 1.8275, 2.0620, 2.2548, 2.4135, 2.5913, 2.7639, 2.9334, - 0.1090, 0.1961, 0.3854, 0.5701, 0.7024, 0.8843, 1.1393, 1.3785, - 1.5940, 1.7797, 1.9442, 2.1740, 2.3853, 2.5773, 2.7727, 2.9406, - 0.1560, 0.3477, 0.5011, 0.6287, 0.7612, 0.9896, 1.1510, 1.3420, - 1.5435, 1.6816, 1.8731, 2.0651, 2.2613, 2.4999, 2.7027, 2.8971, - 0.1459, 0.2416, 0.3833, 0.5450, 0.7916, 0.9223, 1.0662, 1.1953, - 1.4029, 1.6616, 1.9320, 2.1459, 2.3386, 2.5081, 2.6799, 2.9195, - 0.1546, 0.3854, 0.6184, 0.8460, 1.0599, 1.2428, 1.3906, 1.5550, - 1.7388, 1.8945, 2.0757, 2.2386, 2.4014, 2.5705, 2.7574, 2.9400, - 0.1080, 0.2307, 0.4112, 0.6067, 0.7725, 0.9467, 1.1285, 1.3205, - 1.5348, 1.7609, 1.9937, 2.1878, 2.3583, 2.5515, 2.7199, 2.9049, - 0.1482, 0.3178, 0.4983, 0.6342, 0.7783, 0.9880, 1.2019, 1.3404, - 1.5223, 1.7296, 1.9211, 2.0943, 2.2928, 2.5008, 2.7136, 2.9224, - 0.1145, 0.2910, 0.4891, 0.6492, 0.8126, 0.9530, 1.1180, 1.3155, - 1.5054, 1.6893, 1.8899, 2.1188, 2.3389, 2.5512, 2.7313, 2.9224, - 0.0939, 0.1689, 0.3250, 0.5792, 0.7698, 0.9245, 1.1574, 1.3865, - 1.5959, 1.7977, 1.9821, 2.1528, 2.3326, 2.5540, 2.7553, 2.9179, - 0.1243, 0.2474, 0.3923, 0.6199, 0.7908, 0.9379, 1.1497, 1.3734, - 1.5582, 1.7420, 1.9539, 2.1385, 2.3240, 2.5277, 2.7311, 2.9178, - 0.1961, 0.3748, 0.5176, 0.6387, 0.8169, 1.0477, 1.2124, 1.3869, - 1.5604, 1.7225, 1.8770, 2.0837, 2.2960, 2.5103, 2.6945, 2.8862, - 0.1295, 0.2403, 0.4149, 0.6189, 0.7913, 0.9130, 1.0832, 1.2787, - 1.4860, 1.7112, 1.9502, 2.1348, 2.2776, 2.4982, 2.7431, 2.9522, - 0.0160, 0.0362, 0.0097, 0.0057, -0.0014, -0.0073, -0.0046, -0.0064, --0.0121, 0.0019, 0.0149, -0.0440, -0.0479, -0.0382, -0.0480, -0.0182, - 0.0170, 0.0114, -0.0298, -0.0175, -0.0033, -0.0354, -0.0510, -0.0025, - 0.0307, 0.0351, 0.0338, 0.0420, 0.0138, -0.0175, -0.0102, 0.0053, - 0.0084, -0.0003, 0.0412, -0.0027, 0.0145, -0.0039, 0.0083, 0.0400, - 0.0001, -0.0262, 0.0055, -0.0082, 0.0348, 0.0433, 0.0137, -0.0024, --0.0055, 0.0262, 0.0521, 0.0349, 0.0185, 0.0076, -0.0319, -0.0561, --0.0460, -0.0253, -0.0097, 0.0163, 0.0184, -0.0037, -0.0480, -0.0371, - 0.0628, 0.0665, 0.0296, -0.0057, 0.0253, 0.0227, 0.0350, 0.0692, - 0.0545, 0.0218, 0.0094, -0.0449, -0.0372, 0.0005, 0.0258, 0.0118, - 0.0285, 0.0760, 0.0822, 0.0527, -0.0299, -0.0049, 0.0170, 0.0195, - 0.0136, 0.0286, 0.0289, 0.0139, 0.0054, 0.0152, 0.0244, 0.0028, --0.0056, -0.0260, 0.0307, 0.0572, -0.0087, 0.0088, 0.0062, 0.0000, - 0.0125, 0.0000, -0.0292, 0.0820, 0.0872, 0.0646, 0.0346, 0.0076, --0.0022, -0.0253, -0.0567, -0.0188, -0.0336, -0.0673, -0.0549, -0.0166, --0.0259, -0.0140, 0.0040, -0.0029, -0.0430, -0.0531, -0.0253, -0.0019, --0.0071, 0.0393, 0.0072, -0.0327, -0.0236, -0.0235, -0.0177, -0.0186, --0.0280, -0.0201, -0.0077, 0.0383, 0.0418, 0.0321, 0.0294, 0.0169, - 0.0468, 0.0301, 0.0133, 0.0363, 0.0516, 0.0937, 0.1240, 0.1404, - 0.1325, 0.1178, 0.0999, 0.0251, -0.0037, -0.0495, -0.0703, -0.0219, --0.0261, -0.0304, -0.0204, -0.0372, 0.0355, 0.0131, -0.0093, -0.0099, --0.0069, -0.0034, -0.0065, -0.0208, -0.0231, -0.0117, -0.0211, -0.0243, - 0.0046, -0.0107, -0.0070, 0.0123, 0.0230, 0.0152, 0.0164, 0.0412, - 0.0619, 0.0858, 0.0862, -0.0056, 0.0125, 0.0182, 0.0347, 0.0388, - 0.0456, 0.0407, -0.0249, -0.0460, 0.0206, 0.0299, 0.0253, 0.0207, - 0.0177, 0.0238, 0.0253, 0.0030, 0.0042, 0.0020, -0.0081, -0.0136, --0.0290, -0.0042, 0.0122, 0.0051, 0.0107, 0.0228, 0.0211, -0.0068, --0.0436, -0.0299, -0.0078, -0.0779, -0.1157, -0.0679, 0.0172, 0.0150, --0.0051, 0.0081, -0.0512, -0.0616, 0.0576, 0.0799, 0.0803, 0.0336, - 0.0001, -0.0298, -0.0747, -0.0115, -0.0101, -0.0170, -0.0050, 0.0174, --0.0290, -0.0601, -0.0150, 0.0121, 0.0165, 0.0230, 0.0028, -0.0317, --0.0165, 0.0356, 0.0451, 0.0120, 0.0321, 0.0084, -0.0058, 0.0122, - 0.1935, 0.1802, 0.2195, 0.2410, 0.2201, 0.1915, 0.1840, 0.1935, - 0.2213, 0.2079, 0.1858, 0.1974, 0.2239, 0.2173, 0.1840, 0.2120, - 0.4912, 0.4777, 0.4607, 0.4395, 0.4426, 0.4388, 0.4416, 0.4345, - 0.4239, 0.4331, 0.4522, 0.4423, 0.4475, 0.4387, 0.4525, 0.4446 -}, - .lsp22_2 = { 0.0712, 0.1830, 0.4167, 0.6669, 0.8738, 1.0696, 1.2555, 1.4426, 1.6427, 1.8138, 1.9966, 2.1925, 2.3872, 2.5748, 2.7713, 2.9597, @@ -10781,213 +10198,6 @@ static const struct twinvq_data { 0.4938, 0.4951, 0.4994, 0.4971, 0.4981, 0.4983, 0.4967, 0.4789 }, -.lsp44 = { - 0.0927, 0.2291, 0.4059, 0.5779, 0.7288, 0.8821, 1.0377, 1.1915, - 1.3433, 1.4931, 1.6475, 1.7989, 1.9381, 2.0858, 2.2321, 2.3765, - 2.5187, 2.6530, 2.7895, 2.9354, 0.0944, 0.1974, 0.3046, 0.4714, - 0.6116, 0.7829, 0.9027, 1.0375, 1.1869, 1.3488, 1.5036, 1.6781, - 1.8276, 1.9983, 2.1449, 2.3089, 2.4534, 2.6113, 2.7553, 2.9062, - 0.1168, 0.2843, 0.4907, 0.6706, 0.8100, 0.9417, 1.0753, 1.2014, - 1.3151, 1.4496, 1.5832, 1.7379, 1.8642, 2.0230, 2.1681, 2.3250, - 2.4676, 2.6242, 2.7602, 2.9066, 0.1353, 0.2335, 0.3370, 0.4380, - 0.5819, 0.7353, 0.8671, 1.0160, 1.1435, 1.2977, 1.4860, 1.6739, - 1.8412, 2.0028, 2.1537, 2.3124, 2.4741, 2.6272, 2.7862, 2.9536, - 0.1003, 0.2226, 0.3584, 0.4971, 0.6291, 0.7710, 0.9157, 1.0669, - 1.2143, 1.3624, 1.5104, 1.6681, 1.8164, 1.9823, 2.1394, 2.3082, - 2.4677, 2.6306, 2.7909, 2.9382, 0.1056, 0.2027, 0.2956, 0.4005, - 0.5215, 0.6708, 0.8545, 1.0557, 1.2344, 1.4023, 1.5676, 1.7278, - 1.8808, 2.0381, 2.1846, 2.3376, 2.4887, 2.6377, 2.7878, 2.9504, - 0.1015, 0.2462, 0.4122, 0.5783, 0.7233, 0.8833, 1.0377, 1.1903, - 1.3341, 1.4727, 1.6138, 1.7582, 1.8912, 2.0370, 2.1701, 2.3125, - 2.4500, 2.6006, 2.7507, 2.9166, 0.1787, 0.2418, 0.3265, 0.5379, - 0.6584, 0.7681, 0.9545, 1.1050, 1.2125, 1.3528, 1.4763, 1.6705, - 1.8136, 1.9594, 2.0936, 2.2724, 2.4394, 2.5919, 2.7037, 2.8747, - 0.0859, 0.1600, 0.2980, 0.4933, 0.6696, 0.8285, 0.9958, 1.1545, - 1.3107, 1.4591, 1.6127, 1.7652, 1.9143, 2.0680, 2.2171, 2.3643, - 2.5141, 2.6611, 2.8143, 2.9691, 0.0910, 0.2110, 0.3364, 0.4718, - 0.5856, 0.7298, 0.8910, 1.0514, 1.1988, 1.3572, 1.5178, 1.6861, - 1.8399, 2.0099, 2.1639, 2.3225, 2.4774, 2.6321, 2.7863, 2.9412, - 0.1904, 0.2874, 0.3681, 0.4981, 0.6248, 0.7880, 0.9121, 1.0750, - 1.2185, 1.3809, 1.5296, 1.7007, 1.8592, 2.0470, 2.1913, 2.3250, - 2.4519, 2.5984, 2.7408, 2.9023, 0.0917, 0.2067, 0.3246, 0.4961, - 0.6310, 0.8024, 0.9438, 1.1008, 1.2362, 1.3892, 1.5407, 1.7033, - 1.8427, 2.0061, 2.1498, 2.3117, 2.4550, 2.6053, 2.7462, 2.9029, - 0.0989, 0.2193, 0.3756, 0.5410, 0.6929, 0.8368, 0.9801, 1.1250, - 1.2677, 1.4184, 1.5677, 1.7292, 1.8770, 2.0311, 2.1803, 2.3306, - 2.4836, 2.6339, 2.7943, 2.9549, 0.0861, 0.1943, 0.3057, 0.4867, - 0.6194, 0.7592, 0.9184, 1.1052, 1.2486, 1.4064, 1.5609, 1.7273, - 1.8703, 2.0291, 2.1686, 2.3225, 2.4628, 2.6115, 2.7471, 2.9005, - 0.0932, 0.2110, 0.3737, 0.5479, 0.7120, 0.8570, 0.9975, 1.1364, - 1.2772, 1.4220, 1.5612, 1.7089, 1.8410, 1.9827, 2.1263, 2.2859, - 2.4459, 2.6172, 2.7788, 2.9395, 0.1193, 0.2341, 0.3523, 0.5029, - 0.6437, 0.7803, 0.9367, 1.1007, 1.2392, 1.3869, 1.5425, 1.7168, - 1.8709, 2.0248, 2.1584, 2.2949, 2.4308, 2.5823, 2.7235, 2.9034, - 0.0834, 0.1988, 0.3557, 0.5261, 0.6767, 0.8427, 1.0029, 1.1683, - 1.3138, 1.4527, 1.6046, 1.7583, 1.9011, 2.0517, 2.1928, 2.3397, - 2.4839, 2.6291, 2.7771, 2.9329, 0.0938, 0.1967, 0.3213, 0.4675, - 0.6068, 0.7664, 0.9418, 1.1120, 1.2535, 1.3932, 1.5243, 1.6801, - 1.8346, 1.9931, 2.1376, 2.3035, 2.4636, 2.6244, 2.7829, 2.9371, - 0.1017, 0.2552, 0.4327, 0.6017, 0.7467, 0.8797, 1.0097, 1.1442, - 1.2628, 1.4049, 1.5541, 1.7090, 1.8461, 1.9982, 2.1486, 2.3029, - 2.4513, 2.6075, 2.7594, 2.9209, 0.1031, 0.2295, 0.3747, 0.5122, - 0.6596, 0.7935, 0.9345, 1.1050, 1.2384, 1.3543, 1.4739, 1.6136, - 1.7447, 1.8914, 2.0434, 2.1916, 2.3557, 2.5396, 2.7419, 2.9401, - 0.1007, 0.2374, 0.3715, 0.5173, 0.6465, 0.8069, 0.9553, 1.1145, - 1.2594, 1.4143, 1.5617, 1.7166, 1.8457, 2.0012, 2.1462, 2.2864, - 2.4258, 2.5910, 2.7372, 2.9018, 0.0808, 0.1726, 0.2849, 0.4592, - 0.6118, 0.7853, 0.9588, 1.1256, 1.2751, 1.4392, 1.5898, 1.7514, - 1.8977, 2.0554, 2.1937, 2.3430, 2.4831, 2.6249, 2.7601, 2.9155, - 0.1669, 0.2574, 0.3694, 0.5569, 0.6773, 0.8061, 1.0160, 1.1667, - 1.2791, 1.4041, 1.5452, 1.7207, 1.8524, 2.0038, 2.1414, 2.3338, - 2.4747, 2.6157, 2.7303, 2.8848, 0.1598, 0.2521, 0.3416, 0.5149, - 0.6703, 0.7941, 0.9408, 1.1164, 1.2017, 1.3293, 1.4908, 1.6783, - 1.8438, 1.9927, 2.1149, 2.2698, 2.4420, 2.6193, 2.7583, 2.9103, - 0.0902, 0.1978, 0.3265, 0.4578, 0.5878, 0.7439, 0.9110, 1.0906, - 1.2556, 1.4125, 1.5688, 1.7295, 1.8829, 2.0472, 2.2058, 2.3537, - 2.5075, 2.6548, 2.8058, 2.9538, 0.0818, 0.1695, 0.2794, 0.4470, - 0.6069, 0.7641, 0.9313, 1.0946, 1.2411, 1.4072, 1.5640, 1.7186, - 1.8651, 2.0254, 2.1726, 2.3286, 2.4784, 2.6287, 2.7750, 2.9339, - 0.1980, 0.3134, 0.4099, 0.4975, 0.6491, 0.8376, 0.9441, 1.0298, - 1.1795, 1.3866, 1.5784, 1.7209, 1.8137, 1.9271, 2.0863, 2.2930, - 2.4696, 2.6184, 2.7587, 2.9251, 0.1338, 0.2341, 0.3566, 0.4797, - 0.6129, 0.7580, 0.9093, 1.0491, 1.1911, 1.3313, 1.4841, 1.6503, - 1.8035, 1.9685, 2.1128, 2.2694, 2.4093, 2.5728, 2.7206, 2.8994, - 0.0937, 0.2034, 0.3447, 0.5032, 0.6370, 0.7993, 0.9674, 1.1323, - 1.2830, 1.4199, 1.5492, 1.7010, 1.8513, 2.0087, 2.1550, 2.3115, - 2.4643, 2.6237, 2.7812, 2.9392, 0.1085, 0.2152, 0.3126, 0.4569, - 0.5718, 0.7213, 0.8837, 1.0604, 1.2053, 1.3755, 1.5397, 1.7001, - 1.8409, 2.0039, 2.1498, 2.3080, 2.4535, 2.6063, 2.7505, 2.9110, - 0.0562, 0.2066, 0.4034, 0.5490, 0.6682, 0.7924, 0.9495, 1.0800, - 1.1869, 1.3156, 1.4834, 1.6619, 1.8404, 2.0199, 2.1509, 2.2755, - 2.4072, 2.5580, 2.6993, 2.8913, 0.0939, 0.2303, 0.3742, 0.5260, - 0.6662, 0.8294, 0.9769, 1.1315, 1.2792, 1.4153, 1.5436, 1.6701, - 1.8215, 1.9920, 2.1310, 2.3005, 2.4534, 2.5786, 2.7204, 2.9068, - 0.1005, 0.2442, 0.3898, 0.5398, 0.6958, 0.8474, 1.0008, 1.1556, - 1.3020, 1.4456, 1.5954, 1.7470, 1.8922, 2.0500, 2.2019, 2.3492, - 2.4963, 2.6412, 2.7890, 2.9423, 0.1022, 0.2031, 0.3213, 0.4402, - 0.5637, 0.7117, 0.8673, 1.0242, 1.1727, 1.3206, 1.4846, 1.6465, - 1.8015, 1.9655, 2.1233, 2.2873, 2.4464, 2.6074, 2.7685, 2.9409, - 0.1985, 0.3497, 0.4622, 0.5982, 0.7489, 0.8752, 0.9925, 1.1679, - 1.3288, 1.4606, 1.5820, 1.7492, 1.8922, 2.0511, 2.1780, 2.3373, - 2.4760, 2.6233, 2.7466, 2.8978, 0.1284, 0.2433, 0.3630, 0.4852, - 0.6117, 0.7460, 0.8904, 1.0360, 1.1738, 1.3142, 1.4696, 1.6185, - 1.7719, 1.9318, 2.0961, 2.2697, 2.4408, 2.6046, 2.7681, 2.9451, - 0.1042, 0.2286, 0.3598, 0.5064, 0.6438, 0.7899, 0.9350, 1.0891, - 1.2323, 1.3807, 1.5225, 1.6747, 1.8153, 1.9669, 2.1145, 2.2832, - 2.4430, 2.6085, 2.7748, 2.9346, 0.0780, 0.1724, 0.2440, 0.3489, - 0.5280, 0.7426, 0.9272, 1.0914, 1.2562, 1.4188, 1.5804, 1.7376, - 1.8909, 2.0473, 2.1946, 2.3457, 2.4950, 2.6424, 2.7926, 2.9549, - 0.1103, 0.2608, 0.4087, 0.5538, 0.6923, 0.8418, 0.9940, 1.1507, - 1.2919, 1.4406, 1.5802, 1.7262, 1.8638, 2.0085, 2.1572, 2.2975, - 2.4329, 2.5866, 2.7380, 2.9107, 0.1297, 0.2532, 0.4003, 0.5329, - 0.6733, 0.7950, 0.9557, 1.0859, 1.2235, 1.3538, 1.5037, 1.6389, - 1.7964, 1.9285, 2.0898, 2.2541, 2.4231, 2.5711, 2.6875, 2.8947, - 0.0871, 0.1968, 0.3425, 0.4949, 0.6424, 0.7959, 0.9534, 1.1132, - 1.2656, 1.4229, 1.5785, 1.7271, 1.8729, 2.0355, 2.1998, 2.3562, - 2.5151, 2.6663, 2.8145, 2.9534, 0.1038, 0.2204, 0.3248, 0.4566, - 0.5947, 0.7443, 0.8811, 1.0379, 1.2031, 1.3772, 1.5430, 1.7092, - 1.8625, 2.0322, 2.1904, 2.3417, 2.4960, 2.6458, 2.7979, 2.9485, - 0.1329, 0.2763, 0.3943, 0.5147, 0.6512, 0.8071, 0.9410, 1.0879, - 1.2298, 1.3850, 1.5282, 1.6674, 1.8137, 1.9993, 2.1344, 2.2749, - 2.4257, 2.5863, 2.7410, 2.9184, 0.1052, 0.2142, 0.3584, 0.5033, - 0.6387, 0.7804, 0.9320, 1.0780, 1.2172, 1.3764, 1.5421, 1.6887, - 1.8246, 1.9833, 2.1245, 2.2797, 2.4237, 2.5779, 2.7257, 2.9097, - 0.1092, 0.2676, 0.4071, 0.5355, 0.6661, 0.8142, 0.9621, 1.1173, - 1.2628, 1.4185, 1.5696, 1.7220, 1.8595, 2.0178, 2.1720, 2.3221, - 2.4718, 2.6259, 2.7775, 2.9334, 0.0929, 0.2017, 0.3073, 0.4570, - 0.5775, 0.7635, 0.9299, 1.0832, 1.2334, 1.3935, 1.5420, 1.7112, - 1.8601, 2.0309, 2.1735, 2.3230, 2.4543, 2.6034, 2.7418, 2.8988, - 0.0775, 0.2005, 0.3490, 0.5200, 0.6747, 0.8383, 0.9885, 1.1738, - 1.3141, 1.4236, 1.5892, 1.7402, 1.8474, 2.0210, 2.1593, 2.2730, - 2.4235, 2.5604, 2.7128, 2.9005, 0.1104, 0.2292, 0.3353, 0.4732, - 0.6152, 0.7675, 0.9164, 1.0907, 1.2594, 1.4064, 1.5218, 1.6426, - 1.8018, 1.9937, 2.1362, 2.2961, 2.4523, 2.6083, 2.7613, 2.9202, - 0.0826, 0.2000, 0.3384, 0.5144, 0.6694, 0.8377, 0.9870, 1.1461, - 1.2950, 1.4495, 1.5872, 1.7387, 1.8793, 2.0329, 2.1723, 2.3114, - 2.4415, 2.5908, 2.7354, 2.9028, 0.1063, 0.2268, 0.3442, 0.4735, - 0.6116, 0.7507, 0.9028, 1.0768, 1.2426, 1.4052, 1.5566, 1.7015, - 1.8243, 1.9742, 2.1276, 2.2824, 2.4262, 2.5953, 2.7627, 2.9290, - 0.1150, 0.2814, 0.4543, 0.6095, 0.7373, 0.8592, 0.9908, 1.1108, - 1.2339, 1.3590, 1.4864, 1.6168, 1.7392, 1.8752, 2.0212, 2.1688, - 2.3128, 2.4869, 2.7019, 2.9239, 0.0948, 0.2074, 0.3433, 0.4943, - 0.6346, 0.7645, 0.8809, 1.0610, 1.2307, 1.3487, 1.4655, 1.6186, - 1.7534, 1.8859, 2.0486, 2.2200, 2.3835, 2.5581, 2.7565, 2.9502, - 0.1062, 0.2239, 0.3683, 0.5197, 0.6704, 0.8184, 0.9642, 1.1127, - 1.2556, 1.3976, 1.5405, 1.6940, 1.8375, 1.9888, 2.1377, 2.2980, - 2.4555, 2.6184, 2.7849, 2.9452, 0.0888, 0.2005, 0.2847, 0.4322, - 0.5763, 0.7577, 0.9262, 1.1095, 1.2719, 1.4331, 1.5843, 1.7452, - 1.8845, 2.0385, 2.1805, 2.3345, 2.4750, 2.6217, 2.7555, 2.9013, - 0.1713, 0.2617, 0.3868, 0.5859, 0.7073, 0.8535, 1.0593, 1.1778, - 1.3109, 1.4508, 1.5910, 1.7463, 1.8911, 2.0651, 2.2035, 2.3355, - 2.4947, 2.6440, 2.7424, 2.8943, 0.1346, 0.2549, 0.4089, 0.5488, - 0.6949, 0.8394, 0.9810, 1.1145, 1.2528, 1.4044, 1.5423, 1.6872, - 1.8274, 1.9726, 2.1403, 2.2809, 2.4128, 2.5564, 2.6887, 2.8895, - 0.0776, 0.1621, 0.2553, 0.4191, 0.5988, 0.7921, 0.9651, 1.1350, - 1.2930, 1.4475, 1.6011, 1.7585, 1.9068, 2.0638, 2.2102, 2.3594, - 2.5096, 2.6581, 2.8099, 2.9654, 0.0864, 0.1778, 0.2854, 0.4235, - 0.5568, 0.7220, 0.8963, 1.0609, 1.2217, 1.3830, 1.5422, 1.7018, - 1.8551, 2.0206, 2.1783, 2.3328, 2.4869, 2.6366, 2.7923, 2.9539, - 0.1144, 0.2576, 0.4186, 0.5594, 0.6875, 0.8221, 0.9598, 1.0944, - 1.2273, 1.3713, 1.5152, 1.6628, 1.8070, 1.9525, 2.0965, 2.2535, - 2.4132, 2.5725, 2.7250, 2.9150, 0.1079, 0.2221, 0.3334, 0.4845, - 0.6083, 0.7516, 0.9018, 1.0594, 1.2060, 1.3673, 1.5212, 1.6880, - 1.8208, 1.9831, 2.1269, 2.2909, 2.4366, 2.6027, 2.7339, 2.8924, - 0.0994, 0.2233, 0.3634, 0.5145, 0.6568, 0.8131, 0.9746, 1.1296, - 1.2666, 1.4116, 1.5748, 1.7264, 1.8649, 2.0217, 2.1716, 2.3293, - 2.4900, 2.6455, 2.7818, 2.9362, 0.1120, 0.2079, 0.3128, 0.4124, - 0.5291, 0.6816, 0.8478, 1.0150, 1.1772, 1.3456, 1.5208, 1.6882, - 1.8458, 2.0078, 2.1627, 2.3198, 2.4733, 2.6251, 2.7796, 2.9489, - 0.0853, 0.2030, 0.3669, 0.5326, 0.6678, 0.8086, 0.9526, 1.1142, - 1.2551, 1.4158, 1.5694, 1.7073, 1.8431, 1.9686, 2.1153, 2.2376, - 2.3686, 2.5591, 2.7320, 2.9104, 0.0905, 0.2166, 0.3539, 0.5201, - 0.6700, 0.8346, 0.9883, 1.1457, 1.2714, 1.3845, 1.5172, 1.6688, - 1.8008, 1.9535, 2.1019, 2.2708, 2.4135, 2.5974, 2.7486, 2.9033, - 0.0084, 0.0374, 0.0164, -0.0153, 0.0288, 0.0107, -0.0255, -0.0242, - 0.0000, -0.0055, -0.0081, -0.0075, -0.0022, -0.0052, -0.0069, -0.0017, - 0.0003, 0.0091, 0.0028, -0.0027, 0.0085, 0.0043, -0.0235, -0.0411, - 0.0202, 0.0359, 0.0376, 0.0321, 0.0306, -0.0358, -0.0276, -0.0090, - 0.0032, 0.0048, 0.0309, 0.0332, 0.0284, 0.0237, 0.0051, -0.0101, --0.0233, -0.0428, -0.0585, -0.0387, 0.0039, 0.0081, 0.0029, -0.0017, --0.0006, -0.0068, 0.0044, 0.0182, 0.0376, 0.0387, -0.0334, -0.0269, --0.0182, -0.0069, -0.0026, 0.0035, -0.0049, -0.0212, -0.0408, -0.0245, - 0.0186, 0.0189, 0.0153, 0.0120, 0.0157, 0.0055, -0.0046, 0.0179, - 0.0284, -0.0032, -0.0261, -0.0205, -0.0039, 0.0174, 0.0299, 0.0207, - 0.0012, -0.0056, 0.0010, 0.0141, -0.0119, 0.0190, 0.0315, 0.0033, --0.0128, 0.0300, 0.0328, 0.0308, 0.0353, 0.0266, 0.0066, -0.0328, --0.0273, 0.0054, 0.0145, 0.0175, 0.0015, -0.0171, 0.0062, -0.0164, - 0.0045, -0.0071, 0.0025, 0.0278, 0.0283, 0.0117, -0.0026, -0.0285, --0.0408, -0.0366, -0.0059, -0.0208, -0.0354, -0.0334, -0.0263, -0.0064, - 0.0072, -0.0006, -0.0235, -0.0037, -0.0307, -0.0294, -0.0163, -0.0197, --0.0235, 0.0192, 0.0013, -0.0219, -0.0123, -0.0004, -0.0081, -0.0096, --0.0123, -0.0101, 0.0021, 0.0151, 0.0106, 0.0151, 0.0292, 0.0033, - 0.0283, 0.0124, 0.0058, -0.0017, -0.0038, 0.0152, 0.0141, 0.0132, - 0.0178, 0.0157, 0.0073, 0.0176, 0.0141, 0.0097, -0.0092, -0.0163, --0.0230, -0.0134, -0.0099, -0.0147, 0.0040, -0.0183, -0.0175, -0.0080, --0.0083, -0.0290, -0.0417, -0.0398, -0.0269, -0.0199, -0.0143, -0.0053, --0.0099, -0.0054, -0.0199, -0.0219, -0.0170, 0.0107, 0.0194, 0.0035, - 0.0437, 0.0406, 0.0215, 0.0120, 0.0053, -0.0028, 0.0238, 0.0337, - 0.0217, 0.0011, 0.0227, 0.0244, 0.0327, 0.0378, 0.0437, 0.0356, --0.0033, 0.0113, 0.0407, 0.0334, -0.0125, -0.0003, -0.0141, -0.0273, --0.0137, -0.0079, -0.0145, -0.0071, 0.0114, 0.0181, 0.0150, 0.0085, --0.0077, -0.0038, -0.0219, -0.0263, -0.0187, -0.0233, 0.0133, 0.0265, --0.0156, -0.0091, -0.0110, -0.0016, 0.0143, 0.0177, 0.0240, 0.0082, --0.0143, -0.0257, -0.0014, 0.0002, 0.0082, 0.0180, 0.0325, 0.0340, --0.0153, -0.0389, -0.0240, 0.0082, 0.0140, 0.0046, -0.0138, -0.0378, --0.0366, 0.0297, 0.0252, 0.0078, 0.0063, 0.0006, 0.0044, 0.0074, - 0.0094, 0.0113, 0.0105, 0.0137, 0.0438, 0.0262, -0.0078, -0.0185, --0.0215, -0.0407, -0.0435, -0.0208, -0.0004, -0.0144, -0.0205, -0.0248, --0.0159, -0.0069, -0.0153, 0.0132, 0.0355, 0.0298, 0.0120, 0.0072, - 0.0236, 0.0526, 0.0479, 0.0233, -0.0133, -0.0283, -0.0468, -0.0549, --0.0370, 0.0032, 0.0056, 0.0023, 0.0050, 0.0024, 0.0279, 0.0116, --0.0045, -0.0012, 0.0107, 0.0190, 0.0253, 0.0191, 0.0043, 0.0193, --0.0348, -0.0246, 0.0123, 0.0210, 0.0135, -0.0096, -0.0109, -0.0076, --0.0156, -0.0290, 0.0160, 0.0194, 0.0219, 0.0259, 0.0250, 0.0195, - 0.4948, 0.4961, 0.4940, 0.4878, 0.4849, 0.4727, 0.4571, 0.4551, - 0.4534, 0.4468, 0.4412, 0.4354, 0.4298, 0.4272, 0.4498, 0.4506, - 0.4560, 0.4592, 0.4758, 0.4941, 0.2476, 0.1771, 0.1974, 0.1881, - 0.1667, 0.1826, 0.2067, 0.2031, 0.1734, 0.1534, 0.1415, 0.1761, - 0.1897, 0.1772, 0.1651, 0.1247, 0.1041, 0.1231, 0.1809, 0.2234 - }, }; static const uint8_t tab7[][35] = { diff --git a/libavcodec/twinvqdec.c b/libavcodec/twinvqdec.c index c00ebb2ad..0c1782ecb 100644 --- a/libavcodec/twinvqdec.c +++ b/libavcodec/twinvqdec.c @@ -27,6 +27,7 @@ #include "get_bits.h" #include "internal.h" #include "twinvq.h" +#include "metasound_data.h" #include "twinvq_data.h" static const TwinVQModeTab mode_08_08 = { @@ -35,7 +36,7 @@ static const TwinVQModeTab mode_08_08 = { { 2, bark_tab_m08_256, 20, tab.fcb08m, 2, 5, tab.cb0808m0, tab.cb0808m1, 16 }, { 1, bark_tab_l08_512, 30, tab.fcb08l, 3, 6, tab.cb0808l0, tab.cb0808l1, 17 } }, - 512, 12, tab.lsp08, 1, 5, 3, 3, tab.shape08, 8, 28, 20, 6, 40 + 512, 12, ff_metasound_lsp8, 1, 5, 3, 3, tab.shape08, 8, 28, 20, 6, 40 }; static const TwinVQModeTab mode_11_08 = { @@ -44,7 +45,7 @@ static const TwinVQModeTab mode_11_08 = { { 2, bark_tab_m11_256, 20, tab.fcb11m, 2, 5, tab.cb1108m0, tab.cb1108m1, 24 }, { 1, bark_tab_l11_512, 30, tab.fcb11l, 3, 6, tab.cb1108l0, tab.cb1108l1, 27 } }, - 512, 16, tab.lsp11, 1, 6, 4, 3, tab.shape11, 9, 36, 30, 7, 90 + 512, 16, ff_metasound_lsp11, 1, 6, 4, 3, tab.shape11, 9, 36, 30, 7, 90 }; static const TwinVQModeTab mode_11_10 = { @@ -53,7 +54,7 @@ static const TwinVQModeTab mode_11_10 = { { 2, bark_tab_m11_256, 20, tab.fcb11m, 2, 5, tab.cb1110m0, tab.cb1110m1, 18 }, { 1, bark_tab_l11_512, 30, tab.fcb11l, 3, 6, tab.cb1110l0, tab.cb1110l1, 20 } }, - 512, 16, tab.lsp11, 1, 6, 4, 3, tab.shape11, 9, 36, 30, 7, 90 + 512, 16, ff_metasound_lsp11, 1, 6, 4, 3, tab.shape11, 9, 36, 30, 7, 90 }; static const TwinVQModeTab mode_16_16 = { @@ -62,7 +63,7 @@ static const TwinVQModeTab mode_16_16 = { { 2, bark_tab_m16_512, 20, tab.fcb16m, 2, 5, tab.cb1616m0, tab.cb1616m1, 15 }, { 1, bark_tab_l16_1024, 30, tab.fcb16l, 3, 6, tab.cb1616l0, tab.cb1616l1, 16 } }, - 1024, 16, tab.lsp16, 1, 6, 4, 3, tab.shape16, 9, 56, 60, 7, 180 + 1024, 16, ff_metasound_lsp16, 1, 6, 4, 3, tab.shape16, 9, 56, 60, 7, 180 }; static const TwinVQModeTab mode_22_20 = { @@ -71,7 +72,7 @@ static const TwinVQModeTab mode_22_20 = { { 2, bark_tab_m22_512, 20, tab.fcb22m_1, 2, 6, tab.cb2220m0, tab.cb2220m1, 17 }, { 1, bark_tab_l22_1024, 32, tab.fcb22l_1, 4, 6, tab.cb2220l0, tab.cb2220l1, 18 } }, - 1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144 + 1024, 16, ff_metasound_lsp22, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144 }; static const TwinVQModeTab mode_22_24 = { @@ -80,7 +81,7 @@ static const TwinVQModeTab mode_22_24 = { { 2, bark_tab_m22_512, 20, tab.fcb22m_1, 2, 6, tab.cb2224m0, tab.cb2224m1, 14 }, { 1, bark_tab_l22_1024, 32, tab.fcb22l_1, 4, 6, tab.cb2224l0, tab.cb2224l1, 15 } }, - 1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144 + 1024, 16, ff_metasound_lsp22, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144 }; static const TwinVQModeTab mode_22_32 = { @@ -98,7 +99,7 @@ static const TwinVQModeTab mode_44_40 = { { 4, bark_tab_m44_512, 20, tab.fcb44m, 2, 6, tab.cb4440m0, tab.cb4440m1, 17 }, { 1, bark_tab_l44_2048, 40, tab.fcb44l, 4, 6, tab.cb4440l0, tab.cb4440l1, 17 } }, - 2048, 20, tab.lsp44, 1, 6, 4, 4, tab.shape44, 9, 84, 54, 7, 432 + 2048, 20, ff_metasound_lsp44, 1, 6, 4, 4, tab.shape44, 9, 84, 54, 7, 432 }; static const TwinVQModeTab mode_44_48 = { @@ -107,7 +108,7 @@ static const TwinVQModeTab mode_44_48 = { { 4, bark_tab_m44_512, 20, tab.fcb44m, 2, 6, tab.cb4448m0, tab.cb4448m1, 14 }, { 1, bark_tab_l44_2048, 40, tab.fcb44l, 4, 6, tab.cb4448l0, tab.cb4448l1, 14 } }, - 2048, 20, tab.lsp44, 1, 6, 4, 4, tab.shape44, 9, 84, 54, 7, 432 + 2048, 20, ff_metasound_lsp44, 1, 6, 4, 4, tab.shape44, 9, 84, 54, 7, 432 }; /** @@ -422,7 +423,7 @@ AVCodec ff_twinvq_decoder = { .init = twinvq_decode_init, .close = ff_twinvq_decode_close, .decode = ff_twinvq_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c index e6fb661f6..cf6891d53 100644 --- a/libavcodec/ulti.c +++ b/libavcodec/ulti.c @@ -428,4 +428,5 @@ AVCodec ff_ulti_decoder = { .close = ulti_decode_end, .decode = ulti_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 5dcfb8a50..896b99dc3 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -26,46 +26,26 @@ */ #include "config.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/hwcontext.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" +#include "libavutil/intreadwrite.h" #include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" -#include "libavutil/samplefmt.h" -#include "libavutil/dict.h" -#include "libavutil/thread.h" +#include "libavutil/pixfmt.h" #include "avcodec.h" -#include "decode.h" +#include "codec.h" #include "hwconfig.h" -#include "libavutil/opt.h" -#include "mpegvideo.h" #include "thread.h" -#include "frame_thread_encoder.h" #include "internal.h" +#include "put_bits.h" #include "raw.h" -#include "bytestream.h" #include "version.h" #include #include #include #include #include -#if CONFIG_ICONV -# include -#endif - -#include "libavutil/ffversion.h" -const char av_codec_ffversion[] = "FFmpeg version " FFMPEG_VERSION; - -static AVMutex codec_mutex = AV_MUTEX_INITIALIZER; void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size) { @@ -93,7 +73,7 @@ void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size) int av_codec_is_encoder(const AVCodec *codec) { - return codec && (codec->encode_sub || codec->encode2 ||codec->send_frame); + return codec && (codec->encode_sub || codec->encode2 || codec->receive_packet); } int av_codec_is_decoder(const AVCodec *codec) @@ -438,32 +418,6 @@ void ff_color_frame(AVFrame *frame, const int c[4]) } } -int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) -{ - int i; - - for (i = 0; i < count; i++) { - int r = func(c, (char *)arg + i * size); - if (ret) - ret[i] = r; - } - emms_c(); - return 0; -} - -int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int jobnr, int threadnr), void *arg, int *ret, int count) -{ - int i; - - for (i = 0; i < count; i++) { - int r = func(c, arg, i, 0); - if (ret) - ret[i] = r; - } - emms_c(); - return 0; -} - enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc) { @@ -497,701 +451,10 @@ int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec){ return !!(codec->caps_internal & FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM); } -static int64_t get_bit_rate(AVCodecContext *ctx) -{ - int64_t bit_rate; - int bits_per_sample; - - switch (ctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: - case AVMEDIA_TYPE_DATA: - case AVMEDIA_TYPE_SUBTITLE: - case AVMEDIA_TYPE_ATTACHMENT: - bit_rate = ctx->bit_rate; - break; - case AVMEDIA_TYPE_AUDIO: - bits_per_sample = av_get_bits_per_sample(ctx->codec_id); - if (bits_per_sample) { - bit_rate = ctx->sample_rate * (int64_t)ctx->channels; - if (bit_rate > INT64_MAX / bits_per_sample) { - bit_rate = 0; - } else - bit_rate *= bits_per_sample; - } else - bit_rate = ctx->bit_rate; - break; - default: - bit_rate = 0; - break; - } - return bit_rate; -} - - -static void ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec) -{ - if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init) - ff_mutex_lock(&codec_mutex); -} - -static void ff_unlock_avcodec(const AVCodec *codec) -{ - if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init) - ff_mutex_unlock(&codec_mutex); -} - -int attribute_align_arg ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) -{ - int ret = 0; - - ff_unlock_avcodec(codec); - - ret = avcodec_open2(avctx, codec, options); - - ff_lock_avcodec(avctx, codec); - return ret; -} - -int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) -{ - int ret = 0; - int codec_init_ok = 0; - AVDictionary *tmp = NULL; - const AVPixFmtDescriptor *pixdesc; - AVCodecInternal *avci; - - if (avcodec_is_open(avctx)) - return 0; - - if (!codec && !avctx->codec) { - av_log(avctx, AV_LOG_ERROR, "No codec provided to avcodec_open2()\n"); - return AVERROR(EINVAL); - } - if (codec && avctx->codec && codec != avctx->codec) { - av_log(avctx, AV_LOG_ERROR, "This AVCodecContext was allocated for %s, " - "but %s passed to avcodec_open2()\n", avctx->codec->name, codec->name); - return AVERROR(EINVAL); - } - if (!codec) - codec = avctx->codec; - - if (avctx->extradata_size < 0 || avctx->extradata_size >= FF_MAX_EXTRADATA_SIZE) - return AVERROR(EINVAL); - - if (options) - av_dict_copy(&tmp, *options, 0); - - ff_lock_avcodec(avctx, codec); - - avci = av_mallocz(sizeof(*avci)); - if (!avci) { - ret = AVERROR(ENOMEM); - goto end; - } - avctx->internal = avci; - - avci->to_free = av_frame_alloc(); - avci->compat_decode_frame = av_frame_alloc(); - avci->buffer_frame = av_frame_alloc(); - avci->buffer_pkt = av_packet_alloc(); - avci->ds.in_pkt = av_packet_alloc(); - avci->last_pkt_props = av_packet_alloc(); - if (!avci->to_free || !avci->compat_decode_frame || - !avci->buffer_frame || !avci->buffer_pkt || - !avci->ds.in_pkt || !avci->last_pkt_props) { - ret = AVERROR(ENOMEM); - goto free_and_end; - } - - avci->skip_samples_multiplier = 1; - - if (codec->priv_data_size > 0) { - if (!avctx->priv_data) { - avctx->priv_data = av_mallocz(codec->priv_data_size); - if (!avctx->priv_data) { - ret = AVERROR(ENOMEM); - goto end; - } - if (codec->priv_class) { - *(const AVClass **)avctx->priv_data = codec->priv_class; - av_opt_set_defaults(avctx->priv_data); - } - } - if (codec->priv_class && (ret = av_opt_set_dict(avctx->priv_data, &tmp)) < 0) - goto free_and_end; - } else { - avctx->priv_data = NULL; - } - if ((ret = av_opt_set_dict(avctx, &tmp)) < 0) - goto free_and_end; - - if (avctx->codec_whitelist && av_match_list(codec->name, avctx->codec_whitelist, ',') <= 0) { - av_log(avctx, AV_LOG_ERROR, "Codec (%s) not on whitelist \'%s\'\n", codec->name, avctx->codec_whitelist); - ret = AVERROR(EINVAL); - goto free_and_end; - } - - // only call ff_set_dimensions() for non H.264/VP6F/DXV 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 || avctx->codec_id == AV_CODEC_ID_DXV))) { - if (avctx->coded_width && avctx->coded_height) - ret = ff_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); - else if (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_size2(avctx->coded_width, avctx->coded_height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0 - || av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0)) { - av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n"); - ff_set_dimensions(avctx, 0, 0); - } - - if (avctx->width > 0 && avctx->height > 0) { - if (av_image_check_sar(avctx->width, avctx->height, - avctx->sample_aspect_ratio) < 0) { - av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", - avctx->sample_aspect_ratio.num, - avctx->sample_aspect_ratio.den); - avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; - } - } - - /* if the decoder init function was already called previously, - * free the already allocated subtitle_header before overwriting it */ - if (av_codec_is_decoder(codec)) - av_freep(&avctx->subtitle_header); - - if (avctx->channels > FF_SANE_NB_CHANNELS || avctx->channels < 0) { - av_log(avctx, AV_LOG_ERROR, "Too many or invalid channels: %d\n", avctx->channels); - ret = AVERROR(EINVAL); - goto free_and_end; - } - if (avctx->sample_rate < 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid sample rate: %d\n", avctx->sample_rate); - ret = AVERROR(EINVAL); - goto free_and_end; - } - if (avctx->block_align < 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid block align: %d\n", avctx->block_align); - ret = AVERROR(EINVAL); - goto free_and_end; - } - - avctx->codec = codec; - if ((avctx->codec_type == AVMEDIA_TYPE_UNKNOWN || avctx->codec_type == codec->type) && - avctx->codec_id == AV_CODEC_ID_NONE) { - avctx->codec_type = codec->type; - avctx->codec_id = codec->id; - } - if (avctx->codec_id != codec->id || (avctx->codec_type != codec->type - && avctx->codec_type != AVMEDIA_TYPE_ATTACHMENT)) { - av_log(avctx, AV_LOG_ERROR, "Codec type or id mismatches\n"); - ret = AVERROR(EINVAL); - goto free_and_end; - } - avctx->frame_number = 0; - avctx->codec_descriptor = avcodec_descriptor_get(avctx->codec_id); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) && - avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { - const char *codec_string = av_codec_is_encoder(codec) ? "encoder" : "decoder"; - AVCodec *codec2; - 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 & AV_CODEC_CAP_EXPERIMENTAL)) - 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; - } - - if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && - (!avctx->time_base.num || !avctx->time_base.den)) { - avctx->time_base.num = 1; - avctx->time_base.den = avctx->sample_rate; - } - - if (!HAVE_THREADS) - av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n"); - - if (CONFIG_FRAME_THREAD_ENCODER && av_codec_is_encoder(avctx->codec)) { - ff_unlock_avcodec(codec); //we will instantiate a few encoders thus kick the counter to prevent false detection of a problem - ret = ff_frame_thread_encoder_init(avctx, options ? *options : NULL); - ff_lock_avcodec(avctx, codec); - if (ret < 0) - goto free_and_end; - } - - if (av_codec_is_decoder(avctx->codec)) { - ret = ff_decode_bsfs_init(avctx); - if (ret < 0) - goto free_and_end; - } - - if (HAVE_THREADS - && !(avci->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) { - ret = ff_thread_init(avctx); - if (ret < 0) { - goto free_and_end; - } - } - if (!HAVE_THREADS && !(codec->capabilities & AV_CODEC_CAP_AUTO_THREADS)) - avctx->thread_count = 1; - - if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) { - av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n", - avctx->codec->max_lowres); - avctx->lowres = avctx->codec->max_lowres; - } - - if (av_codec_is_encoder(avctx->codec)) { - int i; -#if FF_API_CODED_FRAME -FF_DISABLE_DEPRECATION_WARNINGS - avctx->coded_frame = av_frame_alloc(); - if (!avctx->coded_frame) { - ret = AVERROR(ENOMEM); - goto free_and_end; - } -FF_ENABLE_DEPRECATION_WARNINGS -#endif - - if (avctx->time_base.num <= 0 || avctx->time_base.den <= 0) { - av_log(avctx, AV_LOG_ERROR, "The encoder timebase is not set.\n"); - ret = AVERROR(EINVAL); - goto free_and_end; - } - - if (avctx->codec->sample_fmts) { - for (i = 0; avctx->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) { - if (avctx->sample_fmt == avctx->codec->sample_fmts[i]) - break; - if (avctx->channels == 1 && - av_get_planar_sample_fmt(avctx->sample_fmt) == - av_get_planar_sample_fmt(avctx->codec->sample_fmts[i])) { - avctx->sample_fmt = avctx->codec->sample_fmts[i]; - break; - } - } - if (avctx->codec->sample_fmts[i] == AV_SAMPLE_FMT_NONE) { - char buf[128]; - snprintf(buf, sizeof(buf), "%d", avctx->sample_fmt); - av_log(avctx, AV_LOG_ERROR, "Specified sample format %s is invalid or not supported\n", - (char *)av_x_if_null(av_get_sample_fmt_name(avctx->sample_fmt), buf)); - ret = AVERROR(EINVAL); - goto free_and_end; - } - } - if (avctx->codec->pix_fmts) { - for (i = 0; avctx->codec->pix_fmts[i] != AV_PIX_FMT_NONE; i++) - if (avctx->pix_fmt == avctx->codec->pix_fmts[i]) - break; - if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE - && !((avctx->codec_id == AV_CODEC_ID_MJPEG || avctx->codec_id == AV_CODEC_ID_LJPEG) - && avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL)) { - char buf[128]; - snprintf(buf, sizeof(buf), "%d", avctx->pix_fmt); - av_log(avctx, AV_LOG_ERROR, "Specified pixel format %s is invalid or not supported\n", - (char *)av_x_if_null(av_get_pix_fmt_name(avctx->pix_fmt), buf)); - ret = AVERROR(EINVAL); - goto free_and_end; - } - if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ420P || - avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ411P || - avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ422P || - avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ440P || - avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ444P) - avctx->color_range = AVCOL_RANGE_JPEG; - } - if (avctx->codec->supported_samplerates) { - for (i = 0; avctx->codec->supported_samplerates[i] != 0; i++) - if (avctx->sample_rate == avctx->codec->supported_samplerates[i]) - break; - if (avctx->codec->supported_samplerates[i] == 0) { - av_log(avctx, AV_LOG_ERROR, "Specified sample rate %d is not supported\n", - avctx->sample_rate); - ret = AVERROR(EINVAL); - goto free_and_end; - } - } - if (avctx->sample_rate < 0) { - av_log(avctx, AV_LOG_ERROR, "Specified sample rate %d is not supported\n", - avctx->sample_rate); - ret = AVERROR(EINVAL); - goto free_and_end; - } - if (avctx->codec->channel_layouts) { - if (!avctx->channel_layout) { - av_log(avctx, AV_LOG_WARNING, "Channel layout not specified\n"); - } else { - for (i = 0; avctx->codec->channel_layouts[i] != 0; i++) - if (avctx->channel_layout == avctx->codec->channel_layouts[i]) - break; - if (avctx->codec->channel_layouts[i] == 0) { - char buf[512]; - av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); - av_log(avctx, AV_LOG_ERROR, "Specified channel layout '%s' is not supported\n", buf); - ret = AVERROR(EINVAL); - goto free_and_end; - } - } - } - if (avctx->channel_layout && avctx->channels) { - int channels = av_get_channel_layout_nb_channels(avctx->channel_layout); - if (channels != avctx->channels) { - char buf[512]; - av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); - av_log(avctx, AV_LOG_ERROR, - "Channel layout '%s' with %d channels does not match number of specified channels %d\n", - buf, channels, avctx->channels); - ret = AVERROR(EINVAL); - goto free_and_end; - } - } else if (avctx->channel_layout) { - avctx->channels = av_get_channel_layout_nb_channels(avctx->channel_layout); - } - if (avctx->channels < 0) { - av_log(avctx, AV_LOG_ERROR, "Specified number of channels %d is not supported\n", - avctx->channels); - ret = AVERROR(EINVAL); - goto free_and_end; - } - if(avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - pixdesc = av_pix_fmt_desc_get(avctx->pix_fmt); - if ( avctx->bits_per_raw_sample < 0 - || (avctx->bits_per_raw_sample > 8 && pixdesc->comp[0].depth <= 8)) { - av_log(avctx, AV_LOG_WARNING, "Specified bit depth %d not possible with the specified pixel formats depth %d\n", - avctx->bits_per_raw_sample, pixdesc->comp[0].depth); - avctx->bits_per_raw_sample = pixdesc->comp[0].depth; - } - if (avctx->width <= 0 || avctx->height <= 0) { - av_log(avctx, AV_LOG_ERROR, "dimensions not set\n"); - ret = AVERROR(EINVAL); - goto free_and_end; - } - } - if ( (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO) - && avctx->bit_rate>0 && avctx->bit_rate<1000) { - av_log(avctx, AV_LOG_WARNING, "Bitrate %"PRId64" is extremely low, maybe you mean %"PRId64"k\n", avctx->bit_rate, avctx->bit_rate); - } - - if (!avctx->rc_initial_buffer_occupancy) - avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3LL / 4; - - if (avctx->ticks_per_frame && avctx->time_base.num && - avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { - av_log(avctx, AV_LOG_ERROR, - "ticks_per_frame %d too large for the timebase %d/%d.", - avctx->ticks_per_frame, - avctx->time_base.num, - avctx->time_base.den); - goto free_and_end; - } - - if (avctx->hw_frames_ctx) { - AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; - if (frames_ctx->format != avctx->pix_fmt) { - av_log(avctx, AV_LOG_ERROR, - "Mismatching AVCodecContext.pix_fmt and AVHWFramesContext.format\n"); - ret = AVERROR(EINVAL); - goto free_and_end; - } - if (avctx->sw_pix_fmt != AV_PIX_FMT_NONE && - avctx->sw_pix_fmt != frames_ctx->sw_format) { - av_log(avctx, AV_LOG_ERROR, - "Mismatching AVCodecContext.sw_pix_fmt (%s) " - "and AVHWFramesContext.sw_format (%s)\n", - av_get_pix_fmt_name(avctx->sw_pix_fmt), - av_get_pix_fmt_name(frames_ctx->sw_format)); - ret = AVERROR(EINVAL); - goto free_and_end; - } - avctx->sw_pix_fmt = frames_ctx->sw_format; - } - } - - avctx->pts_correction_num_faulty_pts = - avctx->pts_correction_num_faulty_dts = 0; - avctx->pts_correction_last_pts = - avctx->pts_correction_last_dts = INT64_MIN; - - if ( !CONFIG_GRAY && avctx->flags & AV_CODEC_FLAG_GRAY - && avctx->codec_descriptor->type == AVMEDIA_TYPE_VIDEO) - av_log(avctx, AV_LOG_WARNING, - "gray decoding requested but not enabled at configuration time\n"); - if (avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS) { - avctx->export_side_data |= AV_CODEC_EXPORT_DATA_MVS; - } - - if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME) - || avci->frame_thread_encoder)) { - ret = avctx->codec->init(avctx); - if (ret < 0) { - goto free_and_end; - } - codec_init_ok = 1; - } - - ret=0; - - if (av_codec_is_decoder(avctx->codec)) { - if (!avctx->bit_rate) - avctx->bit_rate = get_bit_rate(avctx); - /* validate channel layout from the decoder */ - if (avctx->channel_layout) { - int channels = av_get_channel_layout_nb_channels(avctx->channel_layout); - if (!avctx->channels) - avctx->channels = channels; - else if (channels != avctx->channels) { - char buf[512]; - av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); - av_log(avctx, AV_LOG_WARNING, - "Channel layout '%s' with %d channels does not match specified number of channels %d: " - "ignoring specified channel layout\n", - buf, channels, avctx->channels); - avctx->channel_layout = 0; - } - } - if (avctx->channels && avctx->channels < 0 || - avctx->channels > FF_SANE_NB_CHANNELS) { - ret = AVERROR(EINVAL); - goto free_and_end; - } - if (avctx->bits_per_coded_sample < 0) { - ret = AVERROR(EINVAL); - goto free_and_end; - } - if (avctx->sub_charenc) { - if (avctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { - av_log(avctx, AV_LOG_ERROR, "Character encoding is only " - "supported with subtitles codecs\n"); - ret = AVERROR(EINVAL); - goto free_and_end; - } else if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) { - av_log(avctx, AV_LOG_WARNING, "Codec '%s' is bitmap-based, " - "subtitles character encoding will be ignored\n", - avctx->codec_descriptor->name); - avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_DO_NOTHING; - } else { - /* input character encoding is set for a text based subtitle - * codec at this point */ - if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_AUTOMATIC) - avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_PRE_DECODER; - - if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_PRE_DECODER) { -#if CONFIG_ICONV - iconv_t cd = iconv_open("UTF-8", avctx->sub_charenc); - if (cd == (iconv_t)-1) { - ret = AVERROR(errno); - av_log(avctx, AV_LOG_ERROR, "Unable to open iconv context " - "with input character encoding \"%s\"\n", avctx->sub_charenc); - goto free_and_end; - } - iconv_close(cd); -#else - av_log(avctx, AV_LOG_ERROR, "Character encoding subtitles " - "conversion needs a libavcodec built with iconv support " - "for this codec\n"); - ret = AVERROR(ENOSYS); - goto free_and_end; -#endif - } - } - } - -#if FF_API_AVCTX_TIMEBASE - if (avctx->framerate.num > 0 && avctx->framerate.den > 0) - avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); -#endif - } - if (codec->priv_data_size > 0 && avctx->priv_data && codec->priv_class) { - av_assert0(*(const AVClass **)avctx->priv_data == codec->priv_class); - } - -end: - ff_unlock_avcodec(codec); - if (options) { - av_dict_free(options); - *options = tmp; - } - - return ret; -free_and_end: - if (avctx->codec && avctx->codec->close && - (codec_init_ok || - (avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP))) - avctx->codec->close(avctx); - - if (HAVE_THREADS && avci->thread_ctx) - ff_thread_free(avctx); - - if (codec->priv_class && codec->priv_data_size) - av_opt_free(avctx->priv_data); - av_opt_free(avctx); - -#if FF_API_CODED_FRAME -FF_DISABLE_DEPRECATION_WARNINGS - av_frame_free(&avctx->coded_frame); -FF_ENABLE_DEPRECATION_WARNINGS -#endif - - av_dict_free(&tmp); - av_freep(&avctx->priv_data); - av_freep(&avctx->subtitle_header); - if (avci) { - av_frame_free(&avci->to_free); - av_frame_free(&avci->compat_decode_frame); - av_frame_free(&avci->buffer_frame); - av_packet_free(&avci->buffer_pkt); - av_packet_free(&avci->last_pkt_props); - - av_packet_free(&avci->ds.in_pkt); - av_bsf_free(&avci->bsf); - - av_buffer_unref(&avci->pool); - } - av_freep(&avci); - avctx->internal = NULL; - avctx->codec = NULL; - goto end; -} - -void avcodec_flush_buffers(AVCodecContext *avctx) -{ - AVCodecInternal *avci = avctx->internal; - - if (av_codec_is_encoder(avctx->codec)) { - int caps = avctx->codec->capabilities; - - if (!(caps & AV_CODEC_CAP_ENCODER_FLUSH)) { - // Only encoders that explicitly declare support for it can be - // flushed. Otherwise, this is a no-op. - av_log(avctx, AV_LOG_WARNING, "Ignoring attempt to flush encoder " - "that doesn't support it\n"); - return; - } - - // We haven't implemented flushing for frame-threaded encoders. - av_assert0(!(caps & AV_CODEC_CAP_FRAME_THREADS)); - } - - avci->draining = 0; - avci->draining_done = 0; - avci->nb_draining_errors = 0; - av_frame_unref(avci->buffer_frame); - av_frame_unref(avci->compat_decode_frame); - av_packet_unref(avci->buffer_pkt); - avci->buffer_pkt_valid = 0; - - av_packet_unref(avci->ds.in_pkt); - - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ff_thread_flush(avctx); - else if (avctx->codec->flush) - avctx->codec->flush(avctx); - - avctx->pts_correction_last_pts = - avctx->pts_correction_last_dts = INT64_MIN; - - if (av_codec_is_decoder(avctx->codec)) - av_bsf_flush(avci->bsf); - - if (!avctx->refcounted_frames) - av_frame_unref(avci->to_free); -} - -void avsubtitle_free(AVSubtitle *sub) -{ - int i; - - for (i = 0; i < sub->num_rects; i++) { - av_freep(&sub->rects[i]->data[0]); - av_freep(&sub->rects[i]->data[1]); - av_freep(&sub->rects[i]->data[2]); - av_freep(&sub->rects[i]->data[3]); - av_freep(&sub->rects[i]->text); - av_freep(&sub->rects[i]->ass); - av_freep(&sub->rects[i]); - } - - av_freep(&sub->rects); - - memset(sub, 0, sizeof(*sub)); -} - -av_cold int avcodec_close(AVCodecContext *avctx) -{ - int i; - - if (!avctx) - return 0; - - if (avcodec_is_open(avctx)) { - if (CONFIG_FRAME_THREAD_ENCODER && - avctx->internal->frame_thread_encoder && avctx->thread_count > 1) { - ff_frame_thread_encoder_free(avctx); - } - if (HAVE_THREADS && avctx->internal->thread_ctx) - ff_thread_free(avctx); - if (avctx->codec && avctx->codec->close) - avctx->codec->close(avctx); - avctx->internal->byte_buffer_size = 0; - av_freep(&avctx->internal->byte_buffer); - av_frame_free(&avctx->internal->to_free); - av_frame_free(&avctx->internal->compat_decode_frame); - av_frame_free(&avctx->internal->buffer_frame); - av_packet_free(&avctx->internal->buffer_pkt); - av_packet_free(&avctx->internal->last_pkt_props); - - av_packet_free(&avctx->internal->ds.in_pkt); - - av_buffer_unref(&avctx->internal->pool); - - if (avctx->hwaccel && avctx->hwaccel->uninit) - avctx->hwaccel->uninit(avctx); - av_freep(&avctx->internal->hwaccel_priv_data); - - av_bsf_free(&avctx->internal->bsf); - - av_freep(&avctx->internal); - } - - for (i = 0; i < avctx->nb_coded_side_data; i++) - av_freep(&avctx->coded_side_data[i].data); - av_freep(&avctx->coded_side_data); - avctx->nb_coded_side_data = 0; - - av_buffer_unref(&avctx->hw_frames_ctx); - av_buffer_unref(&avctx->hw_device_ctx); - - if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) - av_opt_free(avctx->priv_data); - av_opt_free(avctx); - av_freep(&avctx->priv_data); - if (av_codec_is_encoder(avctx->codec)) { - av_freep(&avctx->extradata); -#if FF_API_CODED_FRAME -FF_DISABLE_DEPRECATION_WARNINGS - av_frame_free(&avctx->coded_frame); -FF_ENABLE_DEPRECATION_WARNINGS -#endif - } - avctx->codec = NULL; - avctx->active_thread_type = 0; - - return 0; -} - const char *avcodec_get_name(enum AVCodecID id) { const AVCodecDescriptor *cd; - AVCodec *codec; + const AVCodec *codec; if (id == AV_CODEC_ID_NONE) return "none"; @@ -1208,6 +471,7 @@ const char *avcodec_get_name(enum AVCodecID id) return "unknown_codec"; } +#if FF_API_TAG_STRING size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag) { int i, len, ret = 0; @@ -1227,201 +491,7 @@ size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_ta } return ret; } - -void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) -{ - const char *codec_type; - const char *codec_name; - const char *profile = NULL; - int64_t bitrate; - int new_line = 0; - AVRational display_aspect_ratio; - const char *separator = enc->dump_separator ? (const char *)enc->dump_separator : ", "; - - if (!buf || buf_size <= 0) - return; - codec_type = av_get_media_type_string(enc->codec_type); - codec_name = avcodec_get_name(enc->codec_id); - profile = avcodec_profile_name(enc->codec_id, enc->profile); - - 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_type == AVMEDIA_TYPE_VIDEO - && av_log_get_level() >= AV_LOG_VERBOSE - && enc->refs) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d reference frame%s", - enc->refs, enc->refs > 1 ? "s" : ""); - - if (enc->codec_tag) - snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s / 0x%04X)", - av_fourcc2str(enc->codec_tag), enc->codec_tag); - - switch (enc->codec_type) { - case AVMEDIA_TYPE_VIDEO: - { - char detail[256] = "("; - - av_strlcat(buf, separator, buf_size); - - snprintf(buf + strlen(buf), buf_size - strlen(buf), - "%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" : - av_get_pix_fmt_name(enc->pix_fmt)); - if (enc->bits_per_raw_sample && enc->pix_fmt != AV_PIX_FMT_NONE && - enc->bits_per_raw_sample < av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth) - av_strlcatf(detail, sizeof(detail), "%d bpc, ", enc->bits_per_raw_sample); - if (enc->color_range != AVCOL_RANGE_UNSPECIFIED) - av_strlcatf(detail, sizeof(detail), "%s, ", - av_color_range_name(enc->color_range)); - - if (enc->colorspace != AVCOL_SPC_UNSPECIFIED || - enc->color_primaries != AVCOL_PRI_UNSPECIFIED || - enc->color_trc != AVCOL_TRC_UNSPECIFIED) { - if (enc->colorspace != (int)enc->color_primaries || - enc->colorspace != (int)enc->color_trc) { - new_line = 1; - av_strlcatf(detail, sizeof(detail), "%s/%s/%s, ", - av_color_space_name(enc->colorspace), - av_color_primaries_name(enc->color_primaries), - av_color_transfer_name(enc->color_trc)); - } else - av_strlcatf(detail, sizeof(detail), "%s, ", - av_get_colorspace_name(enc->colorspace)); - } - - if (enc->field_order != AV_FIELD_UNKNOWN) { - const char *field_order = "progressive"; - if (enc->field_order == AV_FIELD_TT) - field_order = "top first"; - else if (enc->field_order == AV_FIELD_BB) - field_order = "bottom first"; - else if (enc->field_order == AV_FIELD_TB) - field_order = "top coded first (swapped)"; - else if (enc->field_order == AV_FIELD_BT) - field_order = "bottom coded first (swapped)"; - - av_strlcatf(detail, sizeof(detail), "%s, ", field_order); - } - - if (av_log_get_level() >= AV_LOG_VERBOSE && - enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) - av_strlcatf(detail, sizeof(detail), "%s, ", - av_chroma_location_name(enc->chroma_sample_location)); - - if (strlen(detail) > 1) { - detail[strlen(detail) - 2] = 0; - av_strlcatf(buf, buf_size, "%s)", detail); - } - } - - if (enc->width) { - av_strlcat(buf, new_line ? separator : ", ", buf_size); - - snprintf(buf + strlen(buf), buf_size - strlen(buf), - "%dx%d", - enc->width, enc->height); - - if (av_log_get_level() >= AV_LOG_VERBOSE && - (enc->width != enc->coded_width || - enc->height != enc->coded_height)) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " (%dx%d)", enc->coded_width, enc->coded_height); - - if (enc->sample_aspect_ratio.num) { - av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, - enc->width * (int64_t)enc->sample_aspect_ratio.num, - enc->height * (int64_t)enc->sample_aspect_ratio.den, - 1024 * 1024); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " [SAR %d:%d DAR %d:%d]", - enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den, - display_aspect_ratio.num, display_aspect_ratio.den); - } - if (av_log_get_level() >= AV_LOG_DEBUG) { - int g = av_gcd(enc->time_base.num, enc->time_base.den); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d/%d", - enc->time_base.num / g, enc->time_base.den / g); - } - } - if (encode) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", q=%d-%d", enc->qmin, enc->qmax); - } else { - if (enc->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", Closed Captions"); - if (enc->properties & FF_CODEC_PROPERTY_LOSSLESS) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", lossless"); - } - break; - case AVMEDIA_TYPE_AUDIO: - av_strlcat(buf, separator, buf_size); - - if (enc->sample_rate) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - "%d Hz, ", enc->sample_rate); - } - av_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout); - if (enc->sample_fmt != AV_SAMPLE_FMT_NONE) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %s", av_get_sample_fmt_name(enc->sample_fmt)); - } - if ( enc->bits_per_raw_sample > 0 - && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " (%d bit)", enc->bits_per_raw_sample); - if (av_log_get_level() >= AV_LOG_VERBOSE) { - if (enc->initial_padding) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", delay %d", enc->initial_padding); - if (enc->trailing_padding) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", padding %d", enc->trailing_padding); - } - break; - case AVMEDIA_TYPE_DATA: - if (av_log_get_level() >= AV_LOG_DEBUG) { - int g = av_gcd(enc->time_base.num, enc->time_base.den); - if (g) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d/%d", - 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; - } - if (encode) { - if (enc->flags & AV_CODEC_FLAG_PASS1) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", pass 1"); - if (enc->flags & AV_CODEC_FLAG_PASS2) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", pass 2"); - } - bitrate = get_bit_rate(enc); - if (bitrate != 0) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %"PRId64" kb/s", bitrate / 1000); - } else if (enc->rc_max_rate > 0) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", max. %"PRId64" kb/s", enc->rc_max_rate / 1000); - } -} +#endif const char *av_get_profile_name(const AVCodec *codec, int profile) { @@ -1451,34 +521,17 @@ const char *avcodec_profile_name(enum AVCodecID codec_id, int profile) return NULL; } -unsigned avcodec_version(void) -{ - av_assert0(AV_CODEC_ID_PCM_S8_PLANAR==65563); - av_assert0(AV_CODEC_ID_ADPCM_G722==69660); - av_assert0(AV_CODEC_ID_SRT==94216); - av_assert0(LIBAVCODEC_VERSION_MICRO >= 100); - - return LIBAVCODEC_VERSION_INT; -} - -const char *avcodec_configuration(void) -{ - return FFMPEG_CONFIGURATION; -} - -const char *avcodec_license(void) -{ -#define LICENSE_PREFIX "libavcodec license: " - return &LICENSE_PREFIX FFMPEG_LICENSE[sizeof(LICENSE_PREFIX) - 1]; -} - int av_get_exact_bits_per_sample(enum AVCodecID codec_id) { switch (codec_id) { case AV_CODEC_ID_8SVX_EXP: case AV_CODEC_ID_8SVX_FIB: + case AV_CODEC_ID_ADPCM_ARGO: case AV_CODEC_ID_ADPCM_CT: + case AV_CODEC_ID_ADPCM_IMA_ALP: + case AV_CODEC_ID_ADPCM_IMA_AMV: case AV_CODEC_ID_ADPCM_IMA_APC: + case AV_CODEC_ID_ADPCM_IMA_APM: case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: case AV_CODEC_ID_ADPCM_IMA_OKI: case AV_CODEC_ID_ADPCM_IMA_WS: @@ -1496,6 +549,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) case AV_CODEC_ID_PCM_VIDC: case AV_CODEC_ID_PCM_S8: case AV_CODEC_ID_PCM_S8_PLANAR: + case AV_CODEC_ID_PCM_SGA: case AV_CODEC_ID_PCM_U8: case AV_CODEC_ID_SDX2_DPCM: case AV_CODEC_ID_DERF_DPCM: @@ -1617,14 +671,10 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, return 256 * sr / 245; else if (id == AV_CODEC_ID_DST) return 588 * sr / 44100; - - if (ch > 0) { - /* calc from sample rate and channels */ - if (id == AV_CODEC_ID_BINKAUDIO_DCT) { - if (sr / 22050 > 22) - return 0; - return (480 << (sr / 22050)) / ch; - } + else if (id == AV_CODEC_ID_BINKAUDIO_DCT) { + if (sr / 22050 > 22) + return 0; + return (480 << (sr / 22050)); } if (id == AV_CODEC_ID_MP3) @@ -1666,6 +716,10 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (ch > 0 && ch < INT_MAX/16) { /* calc from frame_bytes and channels */ switch (id) { + case AV_CODEC_ID_FASTAUDIO: + return frame_bytes / (40 * ch) * 256; + case AV_CODEC_ID_ADPCM_IMA_MOFLEX: + return (frame_bytes - 4 * ch) / (128 * ch) * 256; case AV_CODEC_ID_ADPCM_AFC: return frame_bytes / (9 * ch) * 16; case AV_CODEC_ID_ADPCM_PSX: @@ -1681,7 +735,7 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, case AV_CODEC_ID_ADPCM_IMA_SMJPEG: return (frame_bytes - 4) * 2 / ch; case AV_CODEC_ID_ADPCM_IMA_AMV: - return (frame_bytes - 8) * 2 / ch; + return (frame_bytes - 8) * 2; case AV_CODEC_ID_ADPCM_THP: case AV_CODEC_ID_ADPCM_THP_LE: if (extradata) @@ -1731,7 +785,7 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, 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); + return blocks * (2 + (ba - 7 * ch) * 2LL / ch); case AV_CODEC_ID_ADPCM_MTAF: return blocks * (ba - 16) * 2 / ch; } @@ -1838,13 +892,6 @@ void av_register_hwaccel(AVHWAccel *hwaccel) } #endif -#if FF_API_LOCKMGR -int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) -{ - return 0; -} -#endif - unsigned int avpriv_toupper4(unsigned int x) { return av_toupper(x & 0xFF) + @@ -1853,7 +900,7 @@ unsigned int avpriv_toupper4(unsigned int x) ((unsigned)av_toupper((x >> 24) & 0xFF) << 24); } -int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) +int ff_thread_ref_frame(ThreadFrame *dst, const ThreadFrame *src) { int ret; @@ -1930,34 +977,6 @@ void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, in #endif -int avcodec_is_open(AVCodecContext *s) -{ - return !!s->internal; -} - -int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf) -{ - int ret; - char *str; - - ret = av_bprint_finalize(buf, &str); - if (ret < 0) - return ret; - if (!av_bprint_is_complete(buf)) { - av_free(str); - return AVERROR(ENOMEM); - } - - avctx->extradata = str; - /* Note: the string is NUL terminated (so extradata can be read as a - * string), but the ending character is not accounted in the size (in - * binary formats you are likely not supposed to mux that character). When - * extradata is copied, it is also padded with AV_INPUT_BUFFER_PADDING_SIZE - * zeros. */ - 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) @@ -2036,218 +1055,75 @@ AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx) return props; } -static void codec_parameters_reset(AVCodecParameters *par) +static unsigned bcd2uint(uint8_t bcd) { - av_freep(&par->extradata); - - memset(par, 0, sizeof(*par)); - - par->codec_type = AVMEDIA_TYPE_UNKNOWN; - par->codec_id = AV_CODEC_ID_NONE; - par->format = -1; - par->field_order = AV_FIELD_UNKNOWN; - par->color_range = AVCOL_RANGE_UNSPECIFIED; - par->color_primaries = AVCOL_PRI_UNSPECIFIED; - par->color_trc = AVCOL_TRC_UNSPECIFIED; - par->color_space = AVCOL_SPC_UNSPECIFIED; - par->chroma_location = AVCHROMA_LOC_UNSPECIFIED; - par->sample_aspect_ratio = (AVRational){ 0, 1 }; - par->profile = FF_PROFILE_UNKNOWN; - par->level = FF_LEVEL_UNKNOWN; + unsigned low = bcd & 0xf; + unsigned high = bcd >> 4; + if (low > 9 || high > 9) + return 0; + return low + 10*high; } -AVCodecParameters *avcodec_parameters_alloc(void) -{ - AVCodecParameters *par = av_mallocz(sizeof(*par)); - - if (!par) - return NULL; - codec_parameters_reset(par); - return par; -} - -void avcodec_parameters_free(AVCodecParameters **ppar) -{ - AVCodecParameters *par = *ppar; - - if (!par) - return; - codec_parameters_reset(par); - - av_freep(ppar); -} - -int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src) -{ - codec_parameters_reset(dst); - memcpy(dst, src, sizeof(*dst)); - - dst->extradata = NULL; - dst->extradata_size = 0; - if (src->extradata) { - dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!dst->extradata) - return AVERROR(ENOMEM); - memcpy(dst->extradata, src->extradata, src->extradata_size); - dst->extradata_size = src->extradata_size; - } - - return 0; -} - -int avcodec_parameters_from_context(AVCodecParameters *par, - const AVCodecContext *codec) -{ - codec_parameters_reset(par); - - par->codec_type = codec->codec_type; - par->codec_id = codec->codec_id; - par->codec_tag = codec->codec_tag; - - par->bit_rate = codec->bit_rate; - par->bits_per_coded_sample = codec->bits_per_coded_sample; - par->bits_per_raw_sample = codec->bits_per_raw_sample; - par->profile = codec->profile; - par->level = codec->level; - - switch (par->codec_type) { - case AVMEDIA_TYPE_VIDEO: - par->format = codec->pix_fmt; - par->width = codec->width; - par->height = codec->height; - par->field_order = codec->field_order; - par->color_range = codec->color_range; - par->color_primaries = codec->color_primaries; - par->color_trc = codec->color_trc; - par->color_space = codec->colorspace; - par->chroma_location = codec->chroma_sample_location; - par->sample_aspect_ratio = codec->sample_aspect_ratio; - par->video_delay = codec->has_b_frames; - break; - case AVMEDIA_TYPE_AUDIO: - par->format = codec->sample_fmt; - par->channel_layout = codec->channel_layout; - par->channels = codec->channels; - par->sample_rate = codec->sample_rate; - par->block_align = codec->block_align; - par->frame_size = codec->frame_size; - par->initial_padding = codec->initial_padding; - par->trailing_padding = codec->trailing_padding; - par->seek_preroll = codec->seek_preroll; - break; - case AVMEDIA_TYPE_SUBTITLE: - par->width = codec->width; - par->height = codec->height; - break; - } - - if (codec->extradata) { - par->extradata = av_mallocz(codec->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!par->extradata) - return AVERROR(ENOMEM); - memcpy(par->extradata, codec->extradata, codec->extradata_size); - par->extradata_size = codec->extradata_size; - } - - return 0; -} - -int avcodec_parameters_to_context(AVCodecContext *codec, - const AVCodecParameters *par) -{ - codec->codec_type = par->codec_type; - codec->codec_id = par->codec_id; - codec->codec_tag = par->codec_tag; - - codec->bit_rate = par->bit_rate; - codec->bits_per_coded_sample = par->bits_per_coded_sample; - codec->bits_per_raw_sample = par->bits_per_raw_sample; - codec->profile = par->profile; - codec->level = par->level; - - switch (par->codec_type) { - case AVMEDIA_TYPE_VIDEO: - codec->pix_fmt = par->format; - codec->width = par->width; - codec->height = par->height; - codec->field_order = par->field_order; - codec->color_range = par->color_range; - codec->color_primaries = par->color_primaries; - codec->color_trc = par->color_trc; - codec->colorspace = par->color_space; - codec->chroma_sample_location = par->chroma_location; - codec->sample_aspect_ratio = par->sample_aspect_ratio; - codec->has_b_frames = par->video_delay; - break; - case AVMEDIA_TYPE_AUDIO: - codec->sample_fmt = par->format; - codec->channel_layout = par->channel_layout; - codec->channels = par->channels; - codec->sample_rate = par->sample_rate; - codec->block_align = par->block_align; - codec->frame_size = par->frame_size; - codec->delay = - codec->initial_padding = par->initial_padding; - codec->trailing_padding = par->trailing_padding; - codec->seek_preroll = par->seek_preroll; - break; - case AVMEDIA_TYPE_SUBTITLE: - codec->width = par->width; - codec->height = par->height; - break; - } - - if (par->extradata) { - av_freep(&codec->extradata); - codec->extradata = av_mallocz(par->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!codec->extradata) - return AVERROR(ENOMEM); - memcpy(codec->extradata, par->extradata, par->extradata_size); - codec->extradata_size = par->extradata_size; - } - - return 0; -} - -int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, +int ff_alloc_timecode_sei(const AVFrame *frame, AVRational rate, size_t prefix_len, void **data, size_t *sei_size) { - AVFrameSideData *side_data = NULL; + AVFrameSideData *sd = NULL; uint8_t *sei_data; + PutBitContext pb; + uint32_t *tc; + int m; if (frame) - side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC); + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE); - if (!side_data) { + if (!sd) { *data = NULL; return 0; } + tc = (uint32_t*)sd->data; + m = tc[0] & 3; - *sei_size = side_data->size + 11; + *sei_size = sizeof(uint32_t) * 4; *data = av_mallocz(*sei_size + prefix_len); if (!*data) return AVERROR(ENOMEM); sei_data = (uint8_t*)*data + prefix_len; - // country code - sei_data[0] = 181; - sei_data[1] = 0; - sei_data[2] = 49; + init_put_bits(&pb, sei_data, *sei_size); + put_bits(&pb, 2, m); // num_clock_ts - /** - * 'GA94' is standard in North America for ATSC, but hard coding - * this style may not be the right thing to do -- other formats - * do exist. This information is not available in the side_data - * so we are going with this right now. - */ - AV_WL32(sei_data + 3, MKTAG('G', 'A', '9', '4')); - sei_data[7] = 3; - sei_data[8] = ((side_data->size/3) & 0x1f) | 0x40; - sei_data[9] = 0; + for (int j = 1; j <= m; j++) { + uint32_t tcsmpte = tc[j]; + unsigned hh = bcd2uint(tcsmpte & 0x3f); // 6-bit hours + unsigned mm = bcd2uint(tcsmpte>>8 & 0x7f); // 7-bit minutes + unsigned ss = bcd2uint(tcsmpte>>16 & 0x7f); // 7-bit seconds + unsigned ff = bcd2uint(tcsmpte>>24 & 0x3f); // 6-bit frames + unsigned drop = tcsmpte & 1<<30 && !0; // 1-bit drop if not arbitrary bit - memcpy(sei_data + 10, side_data->data, side_data->size); + /* Calculate frame number of HEVC by SMPTE ST 12-1:2014 Sec 12.2 if rate > 30FPS */ + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { + unsigned pc; + ff *= 2; + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) + pc = !!(tcsmpte & 1 << 7); + else + pc = !!(tcsmpte & 1 << 23); + ff = (ff + pc) & 0x7f; + } - sei_data[side_data->size+10] = 255; + put_bits(&pb, 1, 1); // clock_timestamp_flag + put_bits(&pb, 1, 1); // units_field_based_flag + put_bits(&pb, 5, 0); // counting_type + put_bits(&pb, 1, 1); // full_timestamp_flag + put_bits(&pb, 1, 0); // discontinuity_flag + put_bits(&pb, 1, drop); + put_bits(&pb, 9, ff); + put_bits(&pb, 6, ss); + put_bits(&pb, 6, mm); + put_bits(&pb, 5, hh); + put_bits(&pb, 5, 0); + } + flush_put_bits(&pb); return 0; } diff --git a/libavcodec/utvideo.h b/libavcodec/utvideo.h index cf0bb28c4..9da9329ff 100644 --- a/libavcodec/utvideo.h +++ b/libavcodec/utvideo.h @@ -61,9 +61,6 @@ enum { UTVIDEO_444 = MKTAG('Y', 'V', '2', '4'), }; -/* Mapping of libavcodec prediction modes to Ut Video's */ -extern const int ff_ut_pred_order[5]; - typedef struct UtvideoContext { const AVClass *class; AVCodecContext *avctx; @@ -91,14 +88,4 @@ typedef struct UtvideoContext { size_t control_stream_size[4][256]; } UtvideoContext; -typedef struct HuffEntry { - uint16_t sym; - uint8_t len; - uint32_t code; -} HuffEntry; - -/* Compare huffman tree nodes */ -int ff_ut_huff_cmp_len(const void *a, const void *b); -int ff_ut10_huff_cmp_len(const void *a, const void *b); - #endif /* AVCODEC_UTVIDEO_H */ diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index c07636d43..1b10b3bd0 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -40,91 +40,51 @@ #include "thread.h" #include "utvideo.h" -static int build_huff10(const uint8_t *src, VLC *vlc, int *fsym) +typedef struct HuffEntry { + uint8_t len; + uint16_t sym; +} HuffEntry; + +static int build_huff(UtvideoContext *c, const uint8_t *src, VLC *vlc, + int *fsym, unsigned nb_elems) { int i; HuffEntry he[1024]; - int last; - uint32_t codes[1024]; uint8_t bits[1024]; - uint16_t syms[1024]; - uint32_t code; + uint16_t codes_count[33] = { 0 }; *fsym = -1; - for (i = 0; i < 1024; i++) { - he[i].sym = i; - he[i].len = *src++; - } - qsort(he, 1024, sizeof(*he), ff_ut10_huff_cmp_len); + for (i = 0; i < nb_elems; i++) { + if (src[i] == 0) { + *fsym = i; + return 0; + } else if (src[i] == 255) { + bits[i] = 0; + } else if (src[i] <= 32) { + bits[i] = src[i]; + } else + return AVERROR_INVALIDDATA; - if (!he[0].len) { - *fsym = he[0].sym; - return 0; + codes_count[bits[i]]++; } + if (codes_count[0] == nb_elems) + return AVERROR_INVALIDDATA; - last = 1023; - while (he[last].len == 255 && last) - last--; + /* For Ut Video, longer codes are to the left of the tree and + * for codes with the same length the symbol is descending from + * left to right. So after the next loop --codes_count[i] will + * be the index of the first (lowest) symbol of length i when + * indexed by the position in the tree with left nodes being first. */ + for (int i = 31; i >= 0; i--) + codes_count[i] += codes_count[i + 1]; - if (he[last].len > 32) { - return -1; - } + for (unsigned i = 0; i < nb_elems; i++) + he[--codes_count[bits[i]]] = (HuffEntry) { bits[i], i }; - code = 1; - for (i = last; i >= 0; i--) { - codes[i] = code >> (32 - he[i].len); - bits[i] = he[i].len; - syms[i] = he[i].sym; - code += 0x80000000u >> (he[i].len - 1); - } #define VLC_BITS 11 - return ff_init_vlc_sparse(vlc, VLC_BITS, last + 1, - bits, sizeof(*bits), sizeof(*bits), - codes, sizeof(*codes), sizeof(*codes), - syms, sizeof(*syms), sizeof(*syms), 0); -} - -static int build_huff(const uint8_t *src, VLC *vlc, int *fsym) -{ - int i; - HuffEntry he[256]; - int last; - uint32_t codes[256]; - uint8_t bits[256]; - uint8_t syms[256]; - uint32_t code; - - *fsym = -1; - for (i = 0; i < 256; i++) { - he[i].sym = i; - he[i].len = *src++; - } - qsort(he, 256, sizeof(*he), ff_ut_huff_cmp_len); - - if (!he[0].len) { - *fsym = he[0].sym; - return 0; - } - - last = 255; - while (he[last].len == 255 && last) - last--; - - if (he[last].len > 32) - return -1; - - code = 1; - for (i = last; i >= 0; i--) { - codes[i] = code >> (32 - he[i].len); - bits[i] = he[i].len; - syms[i] = he[i].sym; - code += 0x80000000u >> (he[i].len - 1); - } - - return ff_init_vlc_sparse(vlc, VLC_BITS, last + 1, - bits, sizeof(*bits), sizeof(*bits), - codes, sizeof(*codes), sizeof(*codes), - syms, sizeof(*syms), sizeof(*syms), 0); + return ff_init_vlc_from_lengths(vlc, VLC_BITS, codes_count[0], + &he[0].len, sizeof(*he), + &he[0].sym, sizeof(*he), 2, 0, 0, c->avctx); } static int decode_plane10(UtvideoContext *c, int plane_no, @@ -139,7 +99,7 @@ static int decode_plane10(UtvideoContext *c, int plane_no, GetBitContext gb; int prev, fsym; - if ((ret = build_huff10(huff, &vlc, &fsym)) < 0) { + if ((ret = build_huff(c, huff, &vlc, &fsym, 1024)) < 0) { av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); return ret; } @@ -299,7 +259,7 @@ static int decode_plane(UtvideoContext *c, int plane_no, return 0; } - if (build_huff(src, &vlc, &fsym)) { + if (build_huff(c, src, &vlc, &fsym, 256)) { av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c index f1b9d11c9..5c87eb50a 100644 --- a/libavcodec/utvideoenc.c +++ b/libavcodec/utvideoenc.c @@ -37,6 +37,25 @@ #include "utvideo.h" #include "huffman.h" +typedef struct HuffEntry { + uint16_t sym; + uint8_t len; + uint32_t code; +} HuffEntry; + +#if FF_API_PRIVATE_OPT +static const int ut_pred_order[5] = { + PRED_LEFT, PRED_MEDIAN, PRED_MEDIAN, PRED_NONE, PRED_GRADIENT +}; +#endif + +/* Compare huffman tree nodes */ +static int ut_huff_cmp_len(const void *a, const void *b) +{ + const HuffEntry *aa = a, *bb = b; + return (aa->len - bb->len)*256 + aa->sym - bb->sym; +} + /* Compare huffentry symbols */ static int huff_cmp_sym(const void *a, const void *b) { @@ -139,7 +158,7 @@ FF_DISABLE_DEPRECATION_WARNINGS /* Convert from libavcodec prediction type to Ut Video's */ if (avctx->prediction_method) - c->frame_pred = ff_ut_pred_order[avctx->prediction_method]; + c->frame_pred = ut_pred_order[avctx->prediction_method]; FF_ENABLE_DEPRECATION_WARNINGS #endif @@ -340,13 +359,13 @@ static void calculate_codes(HuffEntry *he) int last, i; uint32_t code; - qsort(he, 256, sizeof(*he), ff_ut_huff_cmp_len); + qsort(he, 256, sizeof(*he), ut_huff_cmp_len); last = 255; while (he[last].len == 255 && last) last--; - code = 1; + code = 0; for (i = last; i >= 0; i--) { he[i].code = code >> (32 - he[i].len); code += 0x80000000u >> (he[i].len - 1); diff --git a/libavcodec/v308enc.c b/libavcodec/v308enc.c index 29b7f8bed..0891251de 100644 --- a/libavcodec/v308enc.c +++ b/libavcodec/v308enc.c @@ -68,11 +68,6 @@ static int v308_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int v308_encode_close(AVCodecContext *avctx) -{ - return 0; -} - AVCodec ff_v308_encoder = { .name = "v308", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), @@ -80,6 +75,5 @@ AVCodec ff_v308_encoder = { .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 }, }; diff --git a/libavcodec/v408enc.c b/libavcodec/v408enc.c index a2ab66d91..d2d84d9c4 100644 --- a/libavcodec/v408enc.c +++ b/libavcodec/v408enc.c @@ -73,11 +73,6 @@ static int v408_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int v408_encode_close(AVCodecContext *avctx) -{ - return 0; -} - #if CONFIG_AYUV_ENCODER AVCodec ff_ayuv_encoder = { .name = "ayuv", @@ -86,7 +81,6 @@ AVCodec ff_ayuv_encoder = { .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 }, }; #endif @@ -98,7 +92,6 @@ AVCodec ff_v408_encoder = { .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 }, }; #endif diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c index 02f23d954..4b2679eb3 100644 --- a/libavcodec/v4l2_buffers.c +++ b/libavcodec/v4l2_buffers.c @@ -274,7 +274,7 @@ static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) return ret; } -static int v4l2_bufref_to_buf(V4L2Buffer *out, int plane, const uint8_t* data, int size, int offset, AVBufferRef* bref) +static int v4l2_bufref_to_buf(V4L2Buffer *out, int plane, const uint8_t* data, int size, int offset) { unsigned int bytesused, length; @@ -386,7 +386,7 @@ static int v4l2_buffer_swframe_to_buf(const AVFrame *frame, V4L2Buffer *out) h = AV_CEIL_RSHIFT(h, desc->log2_chroma_h); } size = frame->linesize[i] * h; - ret = v4l2_bufref_to_buf(out, 0, frame->data[i], size, offset, frame->buf[i]); + ret = v4l2_bufref_to_buf(out, 0, frame->data[i], size, offset); if (ret) return ret; offset += size; @@ -395,7 +395,7 @@ static int v4l2_buffer_swframe_to_buf(const AVFrame *frame, V4L2Buffer *out) } for (i = 0; i < out->num_planes; i++) { - ret = v4l2_bufref_to_buf(out, i, frame->buf[i]->data, frame->buf[i]->size, 0, frame->buf[i]); + ret = v4l2_bufref_to_buf(out, i, frame->buf[i]->data, frame->buf[i]->size, 0); if (ret) return ret; } @@ -479,7 +479,7 @@ int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out) { int ret; - ret = v4l2_bufref_to_buf(out, 0, pkt->data, pkt->size, 0, pkt->buf); + ret = v4l2_bufref_to_buf(out, 0, pkt->data, pkt->size, 0); if (ret) return ret; diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index 29b144ed7..ff1ea8e57 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -599,7 +599,7 @@ int ff_v4l2_context_enqueue_frame(V4L2Context* ctx, const AVFrame* frame) avbuf = v4l2_getfree_v4l2buf(ctx); if (!avbuf) - return AVERROR(ENOMEM); + return AVERROR(EAGAIN); ret = ff_v4l2_buffer_avframe_to_buf(frame, avbuf); if (ret) diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c index e48b3a8cc..cdfd57981 100644 --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c @@ -329,6 +329,9 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context) sem_destroy(&s->refsync); close(s->fd); + av_frame_unref(s->frame); + av_frame_free(&s->frame); + av_packet_unref(&s->buf_pkt); av_free(s); } @@ -338,13 +341,18 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) V4L2m2mContext *s = priv->context; int ret; - ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); - if (ret) - av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name); + if (!s) + return 0; - ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); - if (ret) - av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name); + if (s->fd >= 0) { + ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); + if (ret) + av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name); + + ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); + if (ret) + av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name); + } ff_v4l2_context_release(&s->output); @@ -415,5 +423,12 @@ int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **s) priv->context->self_ref = priv->context_ref; priv->context->fd = -1; + priv->context->frame = av_frame_alloc(); + if (!priv->context->frame) { + av_buffer_unref(&priv->context_ref); + *s = NULL; /* freed when unreferencing context_ref */ + return AVERROR(ENOMEM); + } + return 0; } diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h index 456281f48..b67b21633 100644 --- a/libavcodec/v4l2_m2m.h +++ b/libavcodec/v4l2_m2m.h @@ -58,6 +58,9 @@ typedef struct V4L2m2mContext { int draining; AVPacket buf_pkt; + /* Reference to a frame. Only used during encoding */ + AVFrame *frame; + /* Reference to self; only valid while codec is active. */ AVBufferRef *self_ref; diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c index 3e17e0fca..ab07c0a24 100644 --- a/libavcodec/v4l2_m2m_dec.c +++ b/libavcodec/v4l2_m2m_dec.c @@ -138,14 +138,10 @@ static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame) V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; V4L2Context *const capture = &s->capture; V4L2Context *const output = &s->output; - AVPacket avpkt = {0}; int ret; - if (s->buf_pkt.size) { - avpkt = s->buf_pkt; - memset(&s->buf_pkt, 0, sizeof(AVPacket)); - } else { - ret = ff_decode_get_packet(avctx, &avpkt); + if (!s->buf_pkt.size) { + ret = ff_decode_get_packet(avctx, &s->buf_pkt); if (ret < 0 && ret != AVERROR_EOF) return ret; } @@ -153,32 +149,29 @@ static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame) if (s->draining) goto dequeue; - ret = ff_v4l2_context_enqueue_packet(output, &avpkt); - if (ret < 0) { - if (ret != AVERROR(EAGAIN)) - return ret; + ret = ff_v4l2_context_enqueue_packet(output, &s->buf_pkt); + if (ret < 0 && ret != AVERROR(EAGAIN)) + goto fail; - s->buf_pkt = avpkt; - /* no input buffers available, continue dequeing */ - } + /* if EAGAIN don't unref packet and try to enqueue in the next iteration */ + if (ret != AVERROR(EAGAIN)) + av_packet_unref(&s->buf_pkt); - if (avpkt.size) { + if (!s->draining) { ret = v4l2_try_start(avctx); if (ret) { - av_packet_unref(&avpkt); - /* cant recover */ - if (ret == AVERROR(ENOMEM)) - return ret; - - return 0; + if (ret != AVERROR(ENOMEM)) + ret = 0; + goto fail; } } dequeue: - if (!s->buf_pkt.size) - av_packet_unref(&avpkt); return ff_v4l2_context_dequeue_frame(capture, frame, -1); +fail: + av_packet_unref(&s->buf_pkt); + return ret; } static av_cold int v4l2_decode_init(AVCodecContext *avctx) @@ -212,9 +205,6 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) ret = ff_v4l2_m2m_codec_init(priv); if (ret) { av_log(avctx, AV_LOG_ERROR, "can't configure decoder\n"); - s->self_ref = NULL; - av_buffer_unref(&priv->context_ref); - return ret; } @@ -223,10 +213,7 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) static av_cold int v4l2_decode_close(AVCodecContext *avctx) { - V4L2m2mPriv *priv = avctx->priv_data; - V4L2m2mContext *s = priv->context; - av_packet_unref(&s->buf_pkt); - return ff_v4l2_m2m_codec_end(priv); + return ff_v4l2_m2m_codec_end(avctx->priv_data); } #define OFFSET(x) offsetof(V4L2m2mPriv, x) @@ -261,7 +248,7 @@ static const AVOption options[] = { .close = v4l2_decode_close, \ .bsfs = bsf_name, \ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \ - .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, \ + .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_INIT_CLEANUP, \ .wrapper_name = "v4l2m2m", \ } diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index 32321f392..f644b5013 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -24,6 +24,7 @@ #include #include #include +#include "encode.h" #include "libavcodec/avcodec.h" #include "libavcodec/internal.h" #include "libavutil/pixdesc.h" @@ -288,11 +289,28 @@ static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; V4L2Context *const capture = &s->capture; V4L2Context *const output = &s->output; + AVFrame *frame = s->frame; int ret; if (s->draining) goto dequeue; + if (!frame->buf[0]) { + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + + if (ret == AVERROR_EOF) + frame = NULL; + } + + ret = v4l2_send_frame(avctx, frame); + if (ret != AVERROR(EAGAIN)) + av_frame_unref(frame); + + if (ret < 0 && ret != AVERROR(EAGAIN)) + return ret; + if (!output->streamon) { ret = ff_v4l2_context_set_status(output, VIDIOC_STREAMON); if (ret) { @@ -411,11 +429,11 @@ static const AVCodecDefault v4l2_m2m_defaults[] = { .priv_data_size = sizeof(V4L2m2mPriv), \ .priv_class = &v4l2_m2m_ ## NAME ##_enc_class, \ .init = v4l2_encode_init, \ - .send_frame = v4l2_send_frame, \ .receive_packet = v4l2_receive_packet, \ .close = v4l2_encode_close, \ .defaults = v4l2_m2m_defaults, \ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \ + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \ .wrapper_name = "v4l2m2m", \ } diff --git a/libavcodec/vaapi_av1.c b/libavcodec/vaapi_av1.c new file mode 100644 index 000000000..1809b485a --- /dev/null +++ b/libavcodec/vaapi_av1.c @@ -0,0 +1,319 @@ +/* + * AV1 HW decode acceleration through VA API + * + * 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/pixdesc.h" +#include "hwconfig.h" +#include "vaapi_decode.h" +#include "av1dec.h" + +static VASurfaceID vaapi_av1_surface_id(AV1Frame *vf) +{ + if (vf) + return ff_vaapi_get_surface_id(vf->tf.f); + else + return VA_INVALID_SURFACE; +} + +static int8_t vaapi_av1_get_bit_depth_idx(AVCodecContext *avctx) +{ + AV1DecContext *s = avctx->priv_data; + const AV1RawSequenceHeader *seq = s->raw_seq; + int8_t bit_depth = 8; + + if (seq->seq_profile == 2 && seq->color_config.high_bitdepth) + bit_depth = seq->color_config.twelve_bit ? 12 : 10; + else if (seq->seq_profile <= 2) + bit_depth = seq->color_config.high_bitdepth ? 10 : 8; + else { + av_log(avctx, AV_LOG_ERROR, + "Couldn't get bit depth from profile:%d.\n", seq->seq_profile); + return -1; + } + return bit_depth == 8 ? 0 : bit_depth == 10 ? 1 : 2; +} + +static int vaapi_av1_start_frame(AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + AV1DecContext *s = avctx->priv_data; + const AV1RawSequenceHeader *seq = s->raw_seq; + const AV1RawFrameHeader *frame_header = s->raw_frame_header; + const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain; + VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private; + VADecPictureParameterBufferAV1 pic_param; + int8_t bit_depth_idx; + int err = 0; + int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && film_grain->apply_grain; + uint8_t remap_lr_type[4] = {AV1_RESTORE_NONE, AV1_RESTORE_SWITCHABLE, AV1_RESTORE_WIENER, AV1_RESTORE_SGRPROJ}; + + pic->output_surface = vaapi_av1_surface_id(&s->cur_frame); + + bit_depth_idx = vaapi_av1_get_bit_depth_idx(avctx); + if (bit_depth_idx < 0) + goto fail; + + memset(&pic_param, 0, sizeof(VADecPictureParameterBufferAV1)); + pic_param = (VADecPictureParameterBufferAV1) { + .profile = seq->seq_profile, + .order_hint_bits_minus_1 = seq->order_hint_bits_minus_1, + .bit_depth_idx = bit_depth_idx, + .current_frame = pic->output_surface, + .current_display_picture = pic->output_surface, + .frame_width_minus1 = frame_header->frame_width_minus_1, + .frame_height_minus1 = frame_header->frame_height_minus_1, + .primary_ref_frame = frame_header->primary_ref_frame, + .order_hint = frame_header->order_hint, + .tile_cols = frame_header->tile_cols, + .tile_rows = frame_header->tile_rows, + .context_update_tile_id = frame_header->context_update_tile_id, + .interp_filter = frame_header->interpolation_filter, + .filter_level[0] = frame_header->loop_filter_level[0], + .filter_level[1] = frame_header->loop_filter_level[1], + .filter_level_u = frame_header->loop_filter_level[2], + .filter_level_v = frame_header->loop_filter_level[3], + .base_qindex = frame_header->base_q_idx, + .cdef_damping_minus_3 = frame_header->cdef_damping_minus_3, + .cdef_bits = frame_header->cdef_bits, + .seq_info_fields.fields = { + .still_picture = seq->still_picture, + .use_128x128_superblock = seq->use_128x128_superblock, + .enable_filter_intra = seq->enable_filter_intra, + .enable_intra_edge_filter = seq->enable_intra_edge_filter, + .enable_interintra_compound = seq->enable_interintra_compound, + .enable_masked_compound = seq->enable_masked_compound, + .enable_dual_filter = seq->enable_dual_filter, + .enable_order_hint = seq->enable_order_hint, + .enable_jnt_comp = seq->enable_jnt_comp, + .enable_cdef = seq->enable_cdef, + .mono_chrome = seq->color_config.mono_chrome, + .color_range = seq->color_config.color_range, + .subsampling_x = seq->color_config.subsampling_x, + .subsampling_y = seq->color_config.subsampling_y, + .chroma_sample_position = seq->color_config.chroma_sample_position, + .film_grain_params_present = seq->film_grain_params_present && + !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN), + }, + .seg_info.segment_info_fields.bits = { + .enabled = frame_header->segmentation_enabled, + .update_map = frame_header->segmentation_update_map, + .temporal_update = frame_header->segmentation_temporal_update, + .update_data = frame_header->segmentation_update_data, + }, + .film_grain_info = { + .film_grain_info_fields.bits = { + .apply_grain = apply_grain, + .chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma, + .grain_scaling_minus_8 = film_grain->grain_scaling_minus_8, + .ar_coeff_lag = film_grain->ar_coeff_lag, + .ar_coeff_shift_minus_6 = film_grain->ar_coeff_shift_minus_6, + .grain_scale_shift = film_grain->grain_scale_shift, + .overlap_flag = film_grain->overlap_flag, + .clip_to_restricted_range = film_grain->clip_to_restricted_range, + }, + .grain_seed = film_grain->grain_seed, + .num_y_points = film_grain->num_y_points, + .num_cb_points = film_grain->num_cb_points, + .num_cr_points = film_grain->num_cr_points, + .cb_mult = film_grain->cb_mult, + .cb_luma_mult = film_grain->cb_luma_mult, + .cb_offset = film_grain->cb_offset, + .cr_mult = film_grain->cr_mult, + .cr_luma_mult = film_grain->cr_luma_mult, + .cr_offset = film_grain->cr_offset, + }, + .pic_info_fields.bits = { + .frame_type = frame_header->frame_type, + .show_frame = frame_header->show_frame, + .showable_frame = frame_header->showable_frame, + .error_resilient_mode = frame_header->error_resilient_mode, + .disable_cdf_update = frame_header->disable_cdf_update, + .allow_screen_content_tools = frame_header->allow_screen_content_tools, + .force_integer_mv = frame_header->force_integer_mv, + .allow_intrabc = frame_header->allow_intrabc, + .use_superres = frame_header->use_superres, + .allow_high_precision_mv = frame_header->allow_high_precision_mv, + .is_motion_mode_switchable = frame_header->is_motion_mode_switchable, + .use_ref_frame_mvs = frame_header->use_ref_frame_mvs, + .disable_frame_end_update_cdf = frame_header->disable_frame_end_update_cdf, + .uniform_tile_spacing_flag = frame_header->uniform_tile_spacing_flag, + .allow_warped_motion = frame_header->allow_warped_motion, + }, + .loop_filter_info_fields.bits = { + .sharpness_level = frame_header->loop_filter_sharpness, + .mode_ref_delta_enabled = frame_header->loop_filter_delta_enabled, + .mode_ref_delta_update = frame_header->loop_filter_delta_update, + }, + .mode_control_fields.bits = { + .delta_q_present_flag = frame_header->delta_q_present, + .log2_delta_q_res = frame_header->delta_q_res, + .tx_mode = frame_header->tx_mode, + .reference_select = frame_header->reference_select, + .reduced_tx_set_used = frame_header->reduced_tx_set, + .skip_mode_present = frame_header->skip_mode_present, + }, + .loop_restoration_fields.bits = { + .yframe_restoration_type = remap_lr_type[frame_header->lr_type[0]], + .cbframe_restoration_type = remap_lr_type[frame_header->lr_type[1]], + .crframe_restoration_type = remap_lr_type[frame_header->lr_type[2]], + .lr_unit_shift = frame_header->lr_unit_shift, + .lr_uv_shift = frame_header->lr_uv_shift, + }, + .qmatrix_fields.bits = { + .using_qmatrix = frame_header->using_qmatrix, + } + }; + + for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) { + if (pic_param.pic_info_fields.bits.frame_type == AV1_FRAME_KEY) + pic_param.ref_frame_map[i] = VA_INVALID_ID; + else + pic_param.ref_frame_map[i] = vaapi_av1_surface_id(&s->ref[i]); + } + for (int i = 0; i < AV1_REFS_PER_FRAME; i++) { + pic_param.ref_frame_idx[i] = frame_header->ref_frame_idx[i]; + } + for (int i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) { + pic_param.ref_deltas[i] = frame_header->loop_filter_ref_deltas[i]; + } + for (int i = 0; i < 2; i++) { + pic_param.mode_deltas[i] = frame_header->loop_filter_mode_deltas[i]; + } + for (int i = 0; i < (1 << frame_header->cdef_bits); i++) { + pic_param.cdef_y_strengths[i] = + (frame_header->cdef_y_pri_strength[i] << 2) + + frame_header->cdef_y_sec_strength[i]; + pic_param.cdef_uv_strengths[i] = + (frame_header->cdef_uv_pri_strength[i] << 2) + + frame_header->cdef_uv_sec_strength[i]; + } + for (int i = 0; i < frame_header->tile_cols; i++) { + pic_param.width_in_sbs_minus_1[i] = + frame_header->width_in_sbs_minus_1[i]; + } + for (int i = 0; i < frame_header->tile_rows; i++) { + pic_param.height_in_sbs_minus_1[i] = + frame_header->height_in_sbs_minus_1[i]; + } + for (int i = AV1_REF_FRAME_LAST; i <= AV1_REF_FRAME_ALTREF; i++) { + pic_param.wm[i - 1].wmtype = s->cur_frame.gm_type[i]; + for (int j = 0; j < 6; j++) + pic_param.wm[i - 1].wmmat[j] = s->cur_frame.gm_params[i][j]; + } + if (apply_grain) { + for (int i = 0; i < film_grain->num_y_points; i++) { + pic_param.film_grain_info.point_y_value[i] = + film_grain->point_y_value[i]; + pic_param.film_grain_info.point_y_scaling[i] = + film_grain->point_y_scaling[i]; + } + for (int i = 0; i < film_grain->num_cb_points; i++) { + pic_param.film_grain_info.point_cb_value[i] = + film_grain->point_cb_value[i]; + pic_param.film_grain_info.point_cb_scaling[i] = + film_grain->point_cb_scaling[i]; + } + for (int i = 0; i < film_grain->num_cr_points; i++) { + pic_param.film_grain_info.point_cr_value[i] = + film_grain->point_cr_value[i]; + pic_param.film_grain_info.point_cr_scaling[i] = + film_grain->point_cr_scaling[i]; + } + for (int i = 0; i < 24; i++) { + pic_param.film_grain_info.ar_coeffs_y[i] = + film_grain->ar_coeffs_y_plus_128[i] - 128; + } + for (int i = 0; i < 25; i++) { + pic_param.film_grain_info.ar_coeffs_cb[i] = + film_grain->ar_coeffs_cb_plus_128[i] - 128; + pic_param.film_grain_info.ar_coeffs_cr[i] = + film_grain->ar_coeffs_cr_plus_128[i] - 128; + } + } + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAPictureParameterBufferType, + &pic_param, sizeof(pic_param)); + if (err < 0) + goto fail; + + return 0; + +fail: + ff_vaapi_decode_cancel(avctx, pic); + return err; +} + +static int vaapi_av1_end_frame(AVCodecContext *avctx) +{ + const AV1DecContext *s = avctx->priv_data; + VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private; + return ff_vaapi_decode_issue(avctx, pic); +} + +static int vaapi_av1_decode_slice(AVCodecContext *avctx, + const uint8_t *buffer, + uint32_t size) +{ + const AV1DecContext *s = avctx->priv_data; + VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private; + VASliceParameterBufferAV1 slice_param; + int err = 0; + + for (int i = s->tg_start; i <= s->tg_end; i++) { + memset(&slice_param, 0, sizeof(VASliceParameterBufferAV1)); + + slice_param = (VASliceParameterBufferAV1) { + .slice_data_size = s->tile_group_info[i].tile_size, + .slice_data_offset = s->tile_group_info[i].tile_offset, + .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, + .tile_row = s->tile_group_info[i].tile_row, + .tile_column = s->tile_group_info[i].tile_column, + .tg_start = s->tg_start, + .tg_end = s->tg_end, + }; + + err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &slice_param, + sizeof(VASliceParameterBufferAV1), + buffer, + s->tile_group_info[i].tile_size); + if (err) { + ff_vaapi_decode_cancel(avctx, pic); + return err; + } + } + + return 0; +} + +const AVHWAccel ff_av1_vaapi_hwaccel = { + .name = "av1_vaapi", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_AV1, + .pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = vaapi_av1_start_frame, + .end_frame = vaapi_av1_end_frame, + .decode_slice = vaapi_av1_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePicture), + .init = ff_vaapi_decode_init, + .uninit = ff_vaapi_decode_uninit, + .frame_params = ff_vaapi_common_frame_params, + .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 5e4f62baa..57a0eb4e6 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -410,6 +410,11 @@ static const struct { #if VA_CHECK_VERSION(0, 39, 0) MAP(VP9, VP9_2, VP9Profile2 ), #endif +#if VA_CHECK_VERSION(1, 8, 0) + MAP(AV1, AV1_MAIN, AV1Profile0), + MAP(AV1, AV1_HIGH, AV1Profile1), +#endif + #undef MAP }; @@ -575,6 +580,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx, frames->initial_pool_size += 16; break; case AV_CODEC_ID_VP9: + case AV_CODEC_ID_AV1: frames->initial_pool_size += 8; break; case AV_CODEC_ID_VP8: diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index cb05ebd77..607858435 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -21,13 +21,15 @@ #include "libavutil/avassert.h" #include "libavutil/common.h" +#include "libavutil/internal.h" #include "libavutil/log.h" #include "libavutil/pixdesc.h" #include "vaapi_encode.h" +#include "encode.h" #include "avcodec.h" -const AVCodecHWConfigInternal *ff_vaapi_encode_hw_configs[] = { +const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[] = { HW_CONFIG_ENCODER_FRAMES(VAAPI, VAAPI), NULL, }; @@ -162,6 +164,88 @@ static int vaapi_encode_wait(AVCodecContext *avctx, return 0; } +static int vaapi_encode_make_row_slice(AVCodecContext *avctx, + VAAPIEncodePicture *pic) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeSlice *slice; + int i, rounding; + + for (i = 0; i < pic->nb_slices; i++) + pic->slices[i].row_size = ctx->slice_size; + + rounding = ctx->slice_block_rows - ctx->nb_slices * ctx->slice_size; + if (rounding > 0) { + // Place rounding error at top and bottom of frame. + av_assert0(rounding < pic->nb_slices); + // Some Intel drivers contain a bug where the encoder will fail + // if the last slice is smaller than the one before it. Since + // that's straightforward to avoid here, just do so. + if (rounding <= 2) { + for (i = 0; i < rounding; i++) + ++pic->slices[i].row_size; + } else { + for (i = 0; i < (rounding + 1) / 2; i++) + ++pic->slices[pic->nb_slices - i - 1].row_size; + for (i = 0; i < rounding / 2; i++) + ++pic->slices[i].row_size; + } + } else if (rounding < 0) { + // Remove rounding error from last slice only. + av_assert0(rounding < ctx->slice_size); + pic->slices[pic->nb_slices - 1].row_size += rounding; + } + + for (i = 0; i < pic->nb_slices; i++) { + slice = &pic->slices[i]; + slice->index = i; + if (i == 0) { + slice->row_start = 0; + slice->block_start = 0; + } else { + const VAAPIEncodeSlice *prev = &pic->slices[i - 1]; + slice->row_start = prev->row_start + prev->row_size; + slice->block_start = prev->block_start + prev->block_size; + } + slice->block_size = slice->row_size * ctx->slice_block_cols; + + av_log(avctx, AV_LOG_DEBUG, "Slice %d: %d-%d (%d rows), " + "%d-%d (%d blocks).\n", i, slice->row_start, + slice->row_start + slice->row_size - 1, slice->row_size, + slice->block_start, slice->block_start + slice->block_size - 1, + slice->block_size); + } + + return 0; +} + +static int vaapi_encode_make_tile_slice(AVCodecContext *avctx, + VAAPIEncodePicture *pic) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeSlice *slice; + int i, j, index; + + for (i = 0; i < ctx->tile_cols; i++) { + for (j = 0; j < ctx->tile_rows; j++) { + index = j * ctx->tile_cols + i; + slice = &pic->slices[index]; + slice->index = index; + + pic->slices[index].block_start = ctx->col_bd[i] + + ctx->row_bd[j] * ctx->slice_block_cols; + pic->slices[index].block_size = ctx->row_height[j] * ctx->col_width[i]; + + av_log(avctx, AV_LOG_DEBUG, "Slice %2d: (%2d, %2d) start at: %4d " + "width:%2d height:%2d (%d blocks).\n", index, ctx->col_bd[i], + ctx->row_bd[j], slice->block_start, ctx->col_width[i], + ctx->row_height[j], slice->block_size); + } + } + + return 0; +} + static int vaapi_encode_issue(AVCodecContext *avctx, VAAPIEncodePicture *pic) { @@ -345,57 +429,20 @@ static int vaapi_encode_issue(AVCodecContext *avctx, if (pic->nb_slices == 0) pic->nb_slices = ctx->nb_slices; if (pic->nb_slices > 0) { - int rounding; - pic->slices = av_mallocz_array(pic->nb_slices, sizeof(*pic->slices)); if (!pic->slices) { err = AVERROR(ENOMEM); goto fail; } - for (i = 0; i < pic->nb_slices; i++) - pic->slices[i].row_size = ctx->slice_size; - - rounding = ctx->slice_block_rows - ctx->nb_slices * ctx->slice_size; - if (rounding > 0) { - // Place rounding error at top and bottom of frame. - av_assert0(rounding < pic->nb_slices); - // Some Intel drivers contain a bug where the encoder will fail - // if the last slice is smaller than the one before it. Since - // that's straightforward to avoid here, just do so. - if (rounding <= 2) { - for (i = 0; i < rounding; i++) - ++pic->slices[i].row_size; - } else { - for (i = 0; i < (rounding + 1) / 2; i++) - ++pic->slices[pic->nb_slices - i - 1].row_size; - for (i = 0; i < rounding / 2; i++) - ++pic->slices[i].row_size; - } - } else if (rounding < 0) { - // Remove rounding error from last slice only. - av_assert0(rounding < ctx->slice_size); - pic->slices[pic->nb_slices - 1].row_size += rounding; - } + if (ctx->tile_rows && ctx->tile_cols) + vaapi_encode_make_tile_slice(avctx, pic); + else + vaapi_encode_make_row_slice(avctx, pic); } + for (i = 0; i < pic->nb_slices; i++) { slice = &pic->slices[i]; - slice->index = i; - if (i == 0) { - slice->row_start = 0; - slice->block_start = 0; - } else { - const VAAPIEncodeSlice *prev = &pic->slices[i - 1]; - slice->row_start = prev->row_start + prev->row_size; - slice->block_start = prev->block_start + prev->block_size; - } - slice->block_size = slice->row_size * ctx->slice_block_cols; - - av_log(avctx, AV_LOG_DEBUG, "Slice %d: %d-%d (%d rows), " - "%d-%d (%d blocks).\n", i, slice->row_start, - slice->row_start + slice->row_size - 1, slice->row_size, - slice->block_start, slice->block_start + slice->block_size - 1, - slice->block_size); if (ctx->codec->slice_params_size > 0) { slice->codec_slice_params = av_mallocz(ctx->codec->slice_params_size); @@ -561,11 +608,9 @@ fail_with_picture: fail: for(i = 0; i < pic->nb_param_buffers; i++) vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]); - for (i = 0; i < pic->nb_slices; i++) { - if (pic->slices) { - av_freep(&pic->slices[i].priv_data); + if (pic->slices) { + for (i = 0; i < pic->nb_slices; i++) av_freep(&pic->slices[i].codec_slice_params); - } } fail_at_end: av_freep(&pic->codec_picture_params); @@ -605,7 +650,7 @@ static int vaapi_encode_output(AVCodecContext *avctx, for (buf = buf_list; buf; buf = buf->next) total_size += buf->size; - err = av_new_packet(pkt, total_size); + err = ff_get_encode_buffer(avctx, pkt, total_size, 0); ptr = pkt->data; if (err < 0) @@ -696,11 +741,9 @@ static int vaapi_encode_free(AVCodecContext *avctx, if (pic->encode_issued) vaapi_encode_discard(avctx, pic); - for (i = 0; i < pic->nb_slices; i++) { - if (pic->slices) { - av_freep(&pic->slices[i].priv_data); + if (pic->slices) { + for (i = 0; i < pic->nb_slices; i++) av_freep(&pic->slices[i].codec_slice_params); - } } av_freep(&pic->codec_picture_params); @@ -1043,7 +1086,7 @@ static int vaapi_encode_check_frame(AVCodecContext *avctx, return 0; } -int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame) +static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame) { VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodePicture *pic; @@ -1066,9 +1109,6 @@ int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame) err = AVERROR(ENOMEM); goto fail; } - err = av_frame_ref(pic->input_image, frame); - if (err < 0) - goto fail; if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I) pic->force_idr = 1; @@ -1076,6 +1116,8 @@ int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame) pic->input_surface = (VASurfaceID)(uintptr_t)frame->data[3]; pic->pts = frame->pts; + av_frame_move_ref(pic->input_image, frame); + if (ctx->input_order == 0) ctx->first_pts = pic->pts; if (ctx->input_order == ctx->decode_delay) @@ -1114,8 +1156,20 @@ int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt) { VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodePicture *pic; + AVFrame *frame = ctx->frame; int err; + err = ff_encode_get_frame(avctx, frame); + if (err < 0 && err != AVERROR_EOF) + return err; + + if (err == AVERROR_EOF) + frame = NULL; + + err = vaapi_encode_send_frame(avctx, frame); + if (err < 0) + return err; + if (!ctx->pic_start) { if (ctx->end_of_stream) return AVERROR_EOF; @@ -1191,6 +1245,9 @@ static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[] = { { "YUV400", VA_RT_FORMAT_YUV400, 8, 1, }, { "YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 }, { "YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 }, +#if VA_CHECK_VERSION(1, 2, 0) + { "YUV422_10", VA_RT_FORMAT_YUV422_10, 10, 3, 1, 0 }, +#endif { "YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 }, { "YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 }, #if VA_CHECK_VERSION(0, 38, 1) @@ -1828,52 +1885,12 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) return 0; } -static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) +static av_cold int vaapi_encode_init_row_slice_structure(AVCodecContext *avctx, + uint32_t slice_structure) { VAAPIEncodeContext *ctx = avctx->priv_data; - VAConfigAttrib attr[2] = { { VAConfigAttribEncMaxSlices }, - { VAConfigAttribEncSliceStructure } }; - VAStatus vas; - uint32_t max_slices, slice_structure; int req_slices; - if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) { - if (avctx->slices > 0) { - av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested " - "but this codec does not support controlling slices.\n"); - } - return 0; - } - - ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) / - ctx->slice_block_height; - ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) / - ctx->slice_block_width; - - if (avctx->slices <= 1) { - ctx->nb_slices = 1; - ctx->slice_size = ctx->slice_block_rows; - return 0; - } - - vas = vaGetConfigAttributes(ctx->hwctx->display, - ctx->va_profile, - ctx->va_entrypoint, - attr, FF_ARRAY_ELEMS(attr)); - if (vas != VA_STATUS_SUCCESS) { - av_log(avctx, AV_LOG_ERROR, "Failed to query slice " - "attributes: %d (%s).\n", vas, vaErrorStr(vas)); - return AVERROR_EXTERNAL; - } - max_slices = attr[0].value; - slice_structure = attr[1].value; - if (max_slices == VA_ATTRIB_NOT_SUPPORTED || - slice_structure == VA_ATTRIB_NOT_SUPPORTED) { - av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding " - "pictures as multiple slices.\n."); - return AVERROR(EINVAL); - } - // For fixed-size slices currently we only support whole rows, making // rectangular slices. This could be extended to arbitrary runs of // blocks, but since slices tend to be a conformance requirement and @@ -1910,6 +1927,142 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) return AVERROR(EINVAL); } + return 0; +} + +static av_cold int vaapi_encode_init_tile_slice_structure(AVCodecContext *avctx, + uint32_t slice_structure) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + int i, req_tiles; + + if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS || + (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS && + ctx->tile_cols == 1))) { + av_log(avctx, AV_LOG_ERROR, "Supported slice structure (%#x) doesn't work for " + "current tile requirement.\n", slice_structure); + return AVERROR(EINVAL); + } + + if (ctx->tile_rows > ctx->slice_block_rows || + ctx->tile_cols > ctx->slice_block_cols) { + av_log(avctx, AV_LOG_WARNING, "Not enough block rows/cols (%d x %d) " + "for configured number of tile (%d x %d); ", + ctx->slice_block_rows, ctx->slice_block_cols, + ctx->tile_rows, ctx->tile_cols); + ctx->tile_rows = ctx->tile_rows > ctx->slice_block_rows ? + ctx->slice_block_rows : ctx->tile_rows; + ctx->tile_cols = ctx->tile_cols > ctx->slice_block_cols ? + ctx->slice_block_cols : ctx->tile_cols; + av_log(avctx, AV_LOG_WARNING, "using allowed maximum (%d x %d).\n", + ctx->tile_rows, ctx->tile_cols); + } + + req_tiles = ctx->tile_rows * ctx->tile_cols; + + // Tile slice is not allowed to cross the boundary of a tile due to + // the constraints of media-driver. Currently we support one slice + // per tile. This could be extended to multiple slices per tile. + if (avctx->slices != req_tiles) + av_log(avctx, AV_LOG_WARNING, "The number of requested slices " + "mismatches with configured number of tile (%d != %d); " + "using requested tile number for slice.\n", + avctx->slices, req_tiles); + + ctx->nb_slices = req_tiles; + + // Default in uniform spacing + // 6-3, 6-5 + for (i = 0; i < ctx->tile_cols; i++) { + ctx->col_width[i] = ( i + 1 ) * ctx->slice_block_cols / ctx->tile_cols - + i * ctx->slice_block_cols / ctx->tile_cols; + ctx->col_bd[i + 1] = ctx->col_bd[i] + ctx->col_width[i]; + } + // 6-4, 6-6 + for (i = 0; i < ctx->tile_rows; i++) { + ctx->row_height[i] = ( i + 1 ) * ctx->slice_block_rows / ctx->tile_rows - + i * ctx->slice_block_rows / ctx->tile_rows; + ctx->row_bd[i + 1] = ctx->row_bd[i] + ctx->row_height[i]; + } + + av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d x %d tile.\n", + ctx->tile_rows, ctx->tile_cols); + + return 0; +} + +static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices }, + { VAConfigAttribEncSliceStructure }, +#if VA_CHECK_VERSION(1, 1, 0) + { VAConfigAttribEncTileSupport }, +#endif + }; + VAStatus vas; + uint32_t max_slices, slice_structure; + int ret; + + if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) { + if (avctx->slices > 0) { + av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested " + "but this codec does not support controlling slices.\n"); + } + return 0; + } + + ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) / + ctx->slice_block_height; + ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) / + ctx->slice_block_width; + + if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) { + ctx->nb_slices = 1; + ctx->slice_size = ctx->slice_block_rows; + return 0; + } + + vas = vaGetConfigAttributes(ctx->hwctx->display, + ctx->va_profile, + ctx->va_entrypoint, + attr, FF_ARRAY_ELEMS(attr)); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query slice " + "attributes: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR_EXTERNAL; + } + max_slices = attr[0].value; + slice_structure = attr[1].value; + if (max_slices == VA_ATTRIB_NOT_SUPPORTED || + slice_structure == VA_ATTRIB_NOT_SUPPORTED) { + av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding " + "pictures as multiple slices.\n."); + return AVERROR(EINVAL); + } + + if (ctx->tile_rows && ctx->tile_cols) { +#if VA_CHECK_VERSION(1, 1, 0) + uint32_t tile_support = attr[2].value; + if (tile_support == VA_ATTRIB_NOT_SUPPORTED) { + av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding " + "pictures as multiple tiles.\n."); + return AVERROR(EINVAL); + } +#else + av_log(avctx, AV_LOG_ERROR, "Tile encoding option is " + "not supported with this VAAPI version.\n"); + return AVERROR(EINVAL); +#endif + } + + if (ctx->tile_rows && ctx->tile_cols) + ret = vaapi_encode_init_tile_slice_structure(avctx, slice_structure); + else + ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure); + if (ret < 0) + return ret; + if (ctx->nb_slices > avctx->slices) { av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to " "%d (from %d) due to driver constraints on slice " @@ -1922,9 +2075,8 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) return AVERROR(EINVAL); } - av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices " - "(default size %d block rows).\n", - ctx->nb_slices, ctx->slice_size); + av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices.\n", + ctx->nb_slices); return 0; } @@ -2083,7 +2235,7 @@ static void vaapi_encode_free_output_buffer(void *opaque, } static AVBufferRef *vaapi_encode_alloc_output_buffer(void *opaque, - int size) + buffer_size_t size) { AVCodecContext *avctx = opaque; VAAPIEncodeContext *ctx = avctx->priv_data; @@ -2214,6 +2366,11 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) VAStatus vas; int err; + ctx->frame = av_frame_alloc(); + if (!ctx->frame) { + return AVERROR(ENOMEM); + } + if (!avctx->hw_frames_ctx) { av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is " "required to associate the encoding device.\n"); @@ -2391,6 +2548,8 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) ctx->va_config = VA_INVALID_ID; } + av_frame_free(&ctx->frame); + av_freep(&ctx->codec_sequence_params); av_freep(&ctx->codec_picture_params); diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index 1329f6428..b41604a88 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -43,9 +43,13 @@ enum { MAX_PICTURE_REFERENCES = 2, MAX_REORDER_DELAY = 16, MAX_PARAM_BUFFER_SIZE = 1024, + // A.4.1: table A.6 allows at most 22 tile rows for any level. + MAX_TILE_ROWS = 22, + // A.4.1: table A.6 allows at most 20 tile columns for any level. + MAX_TILE_COLS = 20, }; -extern const AVCodecHWConfigInternal *ff_vaapi_encode_hw_configs[]; +extern const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[]; enum { PICTURE_TYPE_IDR = 0, @@ -60,7 +64,6 @@ typedef struct VAAPIEncodeSlice { int row_size; int block_start; int block_size; - void *priv_data; void *codec_slice_params; } VAAPIEncodeSlice; @@ -302,6 +305,18 @@ typedef struct VAAPIEncodeContext { int nb_slices; int slice_size; + // Tile encoding. + int tile_cols; + int tile_rows; + // Tile width of the i-th column. + int col_width[MAX_TILE_COLS]; + // Tile height of i-th row. + int row_height[MAX_TILE_ROWS]; + // Location of the i-th tile column boundary. + int col_bd[MAX_TILE_COLS + 1]; + // Location of the i-th tile row boundary. + int row_bd[MAX_TILE_ROWS + 1]; + // Frame type decision. int gop_size; int closed_gop; @@ -328,6 +343,8 @@ typedef struct VAAPIEncodeContext { // If the driver does not support ROI then warn the first time we // encounter a frame with ROI side data. int roi_warned; + + AVFrame *frame; } VAAPIEncodeContext; enum { @@ -419,7 +436,6 @@ typedef struct VAAPIEncodeType { } VAAPIEncodeType; -int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame); int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt); int ff_vaapi_encode_init(AVCodecContext *avctx); diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index e195650ef..6e20e2d01 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -90,13 +90,12 @@ typedef struct VAAPIEncodeH264Context { H264RawAUD raw_aud; H264RawSPS raw_sps; H264RawPPS raw_pps; - H264RawSEI raw_sei; H264RawSlice raw_slice; H264RawSEIBufferingPeriod sei_buffering_period; H264RawSEIPicTiming sei_pic_timing; H264RawSEIRecoveryPoint sei_recovery_point; - H264RawSEIUserDataUnregistered sei_identifier; + SEIRawUserDataUnregistered sei_identifier; char *sei_identifier_string; int aud_needed; @@ -135,11 +134,10 @@ static int vaapi_encode_h264_add_nal(AVCodecContext *avctx, CodedBitstreamFragment *au, void *nal_unit) { - VAAPIEncodeH264Context *priv = avctx->priv_data; H264RawNALUnitHeader *header = nal_unit; int err; - err = ff_cbs_insert_unit_content(priv->cbc, au, -1, + err = ff_cbs_insert_unit_content(au, -1, header->nal_unit_type, nal_unit, NULL); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: " @@ -174,7 +172,7 @@ static int vaapi_encode_h264_write_sequence_header(AVCodecContext *avctx, err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -200,7 +198,7 @@ static int vaapi_encode_h264_write_slice_header(AVCodecContext *avctx, err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -211,11 +209,9 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, { VAAPIEncodeH264Context *priv = avctx->priv_data; CodedBitstreamFragment *au = &priv->current_access_unit; - int err, i; + int err; if (priv->sei_needed) { - H264RawSEI *sei = &priv->raw_sei; - if (priv->aud_needed) { err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_aud); if (err < 0) @@ -223,48 +219,42 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, priv->aud_needed = 0; } - *sei = (H264RawSEI) { - .nal_unit_header = { - .nal_unit_type = H264_NAL_SEI, - }, - }; - - i = 0; - if (priv->sei_needed & SEI_IDENTIFIER) { - sei->payload[i].payload_type = H264_SEI_TYPE_USER_DATA_UNREGISTERED; - sei->payload[i].payload.user_data_unregistered = priv->sei_identifier; - ++i; + err = ff_cbs_sei_add_message(priv->cbc, au, 1, + SEI_TYPE_USER_DATA_UNREGISTERED, + &priv->sei_identifier, NULL); + if (err < 0) + goto fail; } if (priv->sei_needed & SEI_TIMING) { if (pic->type == PICTURE_TYPE_IDR) { - sei->payload[i].payload_type = H264_SEI_TYPE_BUFFERING_PERIOD; - sei->payload[i].payload.buffering_period = priv->sei_buffering_period; - ++i; + err = ff_cbs_sei_add_message(priv->cbc, au, 1, + SEI_TYPE_BUFFERING_PERIOD, + &priv->sei_buffering_period, NULL); + if (err < 0) + goto fail; } - sei->payload[i].payload_type = H264_SEI_TYPE_PIC_TIMING; - sei->payload[i].payload.pic_timing = priv->sei_pic_timing; - ++i; + err = ff_cbs_sei_add_message(priv->cbc, au, 1, + SEI_TYPE_PIC_TIMING, + &priv->sei_pic_timing, NULL); + if (err < 0) + goto fail; } if (priv->sei_needed & SEI_RECOVERY_POINT) { - sei->payload[i].payload_type = H264_SEI_TYPE_RECOVERY_POINT; - sei->payload[i].payload.recovery_point = priv->sei_recovery_point; - ++i; + err = ff_cbs_sei_add_message(priv->cbc, au, 1, + SEI_TYPE_RECOVERY_POINT, + &priv->sei_recovery_point, NULL); + if (err < 0) + goto fail; } - sei->payload_count = i; - av_assert0(sei->payload_count > 0); - - err = vaapi_encode_h264_add_nal(avctx, au, sei); - if (err < 0) - goto fail; priv->sei_needed = 0; err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); if (err < 0) goto fail; - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); *type = VAEncPackedHeaderRawData; return 0; @@ -286,7 +276,7 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, } fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -412,30 +402,20 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) sps->vui.aspect_ratio_info_present_flag = 1; } - if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED || - avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || + // Unspecified video format, from table E-2. + sps->vui.video_format = 5; + sps->vui.video_full_range_flag = + avctx->color_range == AVCOL_RANGE_JPEG; + sps->vui.colour_primaries = avctx->color_primaries; + sps->vui.transfer_characteristics = avctx->color_trc; + sps->vui.matrix_coefficients = avctx->colorspace; + if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || avctx->color_trc != AVCOL_TRC_UNSPECIFIED || - avctx->colorspace != AVCOL_SPC_UNSPECIFIED) { + avctx->colorspace != AVCOL_SPC_UNSPECIFIED) + sps->vui.colour_description_present_flag = 1; + if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED || + sps->vui.colour_description_present_flag) sps->vui.video_signal_type_present_flag = 1; - sps->vui.video_format = 5; // Unspecified. - sps->vui.video_full_range_flag = - avctx->color_range == AVCOL_RANGE_JPEG; - - if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || - avctx->color_trc != AVCOL_TRC_UNSPECIFIED || - avctx->colorspace != AVCOL_SPC_UNSPECIFIED) { - sps->vui.colour_description_present_flag = 1; - sps->vui.colour_primaries = avctx->color_primaries; - sps->vui.transfer_characteristics = avctx->color_trc; - sps->vui.matrix_coefficients = avctx->colorspace; - } - } else { - sps->vui.video_format = 5; - sps->vui.video_full_range_flag = 0; - sps->vui.colour_primaries = avctx->color_primaries; - sps->vui.transfer_characteristics = avctx->color_trc; - sps->vui.matrix_coefficients = avctx->colorspace; - } if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) { sps->vui.chroma_loc_info_present_flag = 1; @@ -1242,7 +1222,7 @@ static av_cold int vaapi_encode_h264_close(AVCodecContext *avctx) { VAAPIEncodeH264Context *priv = avctx->priv_data; - ff_cbs_fragment_free(priv->cbc, &priv->current_access_unit); + ff_cbs_fragment_free(&priv->current_access_unit); ff_cbs_close(&priv->cbc); av_freep(&priv->sei_identifier_string); @@ -1351,11 +1331,11 @@ AVCodec ff_h264_vaapi_encoder = { .id = AV_CODEC_ID_H264, .priv_data_size = sizeof(VAAPIEncodeH264Context), .init = &vaapi_encode_h264_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &vaapi_encode_h264_close, .priv_class = &vaapi_encode_h264_class, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | + AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_h264_defaults, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 92e051091..287ac5869 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -73,11 +73,10 @@ typedef struct VAAPIEncodeH265Context { H265RawVPS raw_vps; H265RawSPS raw_sps; H265RawPPS raw_pps; - H265RawSEI raw_sei; H265RawSlice raw_slice; - H265RawSEIMasteringDisplayColourVolume sei_mastering_display; - H265RawSEIContentLightLevelInfo sei_content_light_level; + SEIRawMasteringDisplayColourVolume sei_mastering_display; + SEIRawContentLightLevelInfo sei_content_light_level; CodedBitstreamContext *cbc; CodedBitstreamFragment current_access_unit; @@ -116,11 +115,10 @@ static int vaapi_encode_h265_add_nal(AVCodecContext *avctx, CodedBitstreamFragment *au, void *nal_unit) { - VAAPIEncodeH265Context *priv = avctx->priv_data; H265RawNALUnitHeader *header = nal_unit; int err; - err = ff_cbs_insert_unit_content(priv->cbc, au, -1, + err = ff_cbs_insert_unit_content(au, -1, header->nal_unit_type, nal_unit, NULL); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: " @@ -159,7 +157,7 @@ static int vaapi_encode_h265_write_sequence_header(AVCodecContext *avctx, err = vaapi_encode_h265_write_access_unit(avctx, data, data_len, au); fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -185,7 +183,7 @@ static int vaapi_encode_h265_write_slice_header(AVCodecContext *avctx, err = vaapi_encode_h265_write_access_unit(avctx, data, data_len, au); fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -196,11 +194,9 @@ static int vaapi_encode_h265_write_extra_header(AVCodecContext *avctx, { VAAPIEncodeH265Context *priv = avctx->priv_data; CodedBitstreamFragment *au = &priv->current_access_unit; - int err, i; + int err; if (priv->sei_needed) { - H265RawSEI *sei = &priv->raw_sei; - if (priv->aud_needed) { err = vaapi_encode_h265_add_nal(avctx, au, &priv->aud); if (err < 0) @@ -208,41 +204,29 @@ static int vaapi_encode_h265_write_extra_header(AVCodecContext *avctx, priv->aud_needed = 0; } - *sei = (H265RawSEI) { - .nal_unit_header = { - .nal_unit_type = HEVC_NAL_SEI_PREFIX, - .nuh_layer_id = 0, - .nuh_temporal_id_plus1 = 1, - }, - }; - - i = 0; - if (priv->sei_needed & SEI_MASTERING_DISPLAY) { - sei->payload[i].payload_type = HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO; - sei->payload[i].payload.mastering_display = priv->sei_mastering_display; - ++i; + err = ff_cbs_sei_add_message(priv->cbc, au, 1, + SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME, + &priv->sei_mastering_display, NULL); + if (err < 0) + goto fail; } if (priv->sei_needed & SEI_CONTENT_LIGHT_LEVEL) { - sei->payload[i].payload_type = HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO; - sei->payload[i].payload.content_light_level = priv->sei_content_light_level; - ++i; + err = ff_cbs_sei_add_message(priv->cbc, au, 1, + SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO, + &priv->sei_content_light_level, NULL); + if (err < 0) + goto fail; } - sei->payload_count = i; - av_assert0(sei->payload_count > 0); - - err = vaapi_encode_h265_add_nal(avctx, au, sei); - if (err < 0) - goto fail; priv->sei_needed = 0; err = vaapi_encode_h265_write_access_unit(avctx, data, data_len, au); if (err < 0) goto fail; - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); *type = VAEncPackedHeaderRawData; return 0; @@ -251,7 +235,7 @@ static int vaapi_encode_h265_write_extra_header(AVCodecContext *avctx, } fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -345,7 +329,7 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) level = ff_h265_guess_level(ptl, avctx->bit_rate, ctx->surface_width, ctx->surface_height, - ctx->nb_slices, 1, 1, + ctx->nb_slices, ctx->tile_rows, ctx->tile_cols, (ctx->b_per_p > 0) + 1); if (level) { av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name); @@ -489,30 +473,20 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) vui->aspect_ratio_info_present_flag = 1; } - if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED || - avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || + // Unspecified video format, from table E-2. + vui->video_format = 5; + vui->video_full_range_flag = + avctx->color_range == AVCOL_RANGE_JPEG; + vui->colour_primaries = avctx->color_primaries; + vui->transfer_characteristics = avctx->color_trc; + vui->matrix_coefficients = avctx->colorspace; + if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || avctx->color_trc != AVCOL_TRC_UNSPECIFIED || - avctx->colorspace != AVCOL_SPC_UNSPECIFIED) { + avctx->colorspace != AVCOL_SPC_UNSPECIFIED) + vui->colour_description_present_flag = 1; + if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED || + vui->colour_description_present_flag) vui->video_signal_type_present_flag = 1; - vui->video_format = 5; // Unspecified. - vui->video_full_range_flag = - avctx->color_range == AVCOL_RANGE_JPEG; - - if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || - avctx->color_trc != AVCOL_TRC_UNSPECIFIED || - avctx->colorspace != AVCOL_SPC_UNSPECIFIED) { - vui->colour_description_present_flag = 1; - vui->colour_primaries = avctx->color_primaries; - vui->transfer_characteristics = avctx->color_trc; - vui->matrix_coefficients = avctx->colorspace; - } - } else { - vui->video_format = 5; - vui->video_full_range_flag = 0; - vui->colour_primaries = avctx->color_primaries; - vui->transfer_characteristics = avctx->color_trc; - vui->matrix_coefficients = avctx->colorspace; - } if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) { vui->chroma_loc_info_present_flag = 1; @@ -556,8 +530,41 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) pps->cu_qp_delta_enabled_flag = (ctx->va_rc_mode != VA_RC_CQP); pps->diff_cu_qp_delta_depth = 0; - pps->pps_loop_filter_across_slices_enabled_flag = 1; + if (ctx->tile_rows && ctx->tile_cols) { + int uniform_spacing; + pps->tiles_enabled_flag = 1; + pps->num_tile_columns_minus1 = ctx->tile_cols - 1; + pps->num_tile_rows_minus1 = ctx->tile_rows - 1; + + // Test whether the spacing provided matches the H.265 uniform + // spacing, and set the flag if it does. + uniform_spacing = 1; + for (i = 0; i <= pps->num_tile_columns_minus1 && + uniform_spacing; i++) { + if (ctx->col_width[i] != + (i + 1) * ctx->slice_block_cols / ctx->tile_cols - + i * ctx->slice_block_cols / ctx->tile_cols) + uniform_spacing = 0; + } + for (i = 0; i <= pps->num_tile_rows_minus1 && + uniform_spacing; i++) { + if (ctx->row_height[i] != + (i + 1) * ctx->slice_block_rows / ctx->tile_rows - + i * ctx->slice_block_rows / ctx->tile_rows) + uniform_spacing = 0; + } + pps->uniform_spacing_flag = uniform_spacing; + + for (i = 0; i <= pps->num_tile_columns_minus1; i++) + pps->column_width_minus1[i] = ctx->col_width[i] - 1; + for (i = 0; i <= pps->num_tile_rows_minus1; i++) + pps->row_height_minus1[i] = ctx->row_height[i] - 1; + + pps->loop_filter_across_tiles_enabled_flag = 1; + } + + pps->pps_loop_filter_across_slices_enabled_flag = 1; // Fill VAAPI parameter buffers. @@ -666,6 +673,13 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) }, }; + if (pps->tiles_enabled_flag) { + for (i = 0; i <= vpic->num_tile_rows_minus1; i++) + vpic->row_height_minus1[i] = pps->row_height_minus1[i]; + for (i = 0; i <= vpic->num_tile_columns_minus1; i++) + vpic->column_width_minus1[i] = pps->column_width_minus1[i]; + } + return 0; } @@ -752,7 +766,7 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, // SEI is needed when both the primaries and luminance are set if (mdm->has_primaries && mdm->has_luminance) { - H265RawSEIMasteringDisplayColourVolume *mdcv = + SEIRawMasteringDisplayColourVolume *mdcv = &priv->sei_mastering_display; const int mapping[3] = {1, 2, 0}; const int chroma_den = 50000; @@ -797,7 +811,7 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, if (sd) { AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data; - H265RawSEIContentLightLevelInfo *clli = + SEIRawContentLightLevelInfo *clli = &priv->sei_content_light_level; clli->max_content_light_level = FFMIN(clm->MaxCLL, 65535); @@ -1113,6 +1127,10 @@ static const VAAPIEncodeProfile vaapi_encode_h265_profiles[] = { #if VA_CHECK_VERSION(0, 37, 0) { FF_PROFILE_HEVC_MAIN_10, 10, 3, 1, 1, VAProfileHEVCMain10 }, { FF_PROFILE_HEVC_REXT, 10, 3, 1, 1, VAProfileHEVCMain10 }, +#endif +#if VA_CHECK_VERSION(1, 2, 0) + { FF_PROFILE_HEVC_REXT, 8, 3, 1, 0, VAProfileHEVCMain422_10 }, + { FF_PROFILE_HEVC_REXT, 10, 3, 1, 0, VAProfileHEVCMain422_10 }, #endif { FF_PROFILE_UNKNOWN } }; @@ -1188,7 +1206,7 @@ static av_cold int vaapi_encode_h265_close(AVCodecContext *avctx) { VAAPIEncodeH265Context *priv = avctx->priv_data; - ff_cbs_fragment_free(priv->cbc, &priv->current_access_unit); + ff_cbs_fragment_free(&priv->current_access_unit); ff_cbs_close(&priv->cbc); return ff_vaapi_encode_close(avctx); @@ -1257,6 +1275,10 @@ static const AVOption vaapi_encode_h265_options[] = { { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL }, INT_MIN, INT_MAX, FLAGS, "sei" }, + { "tiles", "Tile columns x rows", + OFFSET(common.tile_cols), AV_OPT_TYPE_IMAGE_SIZE, + { .str = NULL }, 0, 0, FLAGS }, + { NULL }, }; @@ -1287,11 +1309,11 @@ AVCodec ff_hevc_vaapi_encoder = { .id = AV_CODEC_ID_HEVC, .priv_data_size = sizeof(VAAPIEncodeH265Context), .init = &vaapi_encode_h265_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &vaapi_encode_h265_close, .priv_class = &vaapi_encode_h265_class, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | + AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_h265_defaults, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c index 9f9ed811a..3878f3eeb 100644 --- a/libavcodec/vaapi_encode_mjpeg.c +++ b/libavcodec/vaapi_encode_mjpeg.c @@ -90,34 +90,34 @@ static int vaapi_encode_mjpeg_write_image_header(AVCodecContext *avctx, int err; if (priv->jfif) { - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_APPN + 0, &priv->jfif_header, NULL); if (err < 0) goto fail; } - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_DQT, &priv->quant_tables, NULL); if (err < 0) goto fail; - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_SOF0, &priv->frame_header, NULL); if (err < 0) goto fail; if (priv->huffman) { - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_DHT, &priv->huffman_tables, NULL); if (err < 0) goto fail; } - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_SOS, &priv->scan, NULL); if (err < 0) @@ -142,7 +142,7 @@ static int vaapi_encode_mjpeg_write_image_header(AVCodecContext *avctx, err = 0; fail: - ff_cbs_fragment_reset(priv->cbc, frag); + ff_cbs_fragment_reset(frag); return err; } @@ -519,7 +519,7 @@ static av_cold int vaapi_encode_mjpeg_close(AVCodecContext *avctx) { VAAPIEncodeMJPEGContext *priv = avctx->priv_data; - ff_cbs_fragment_free(priv->cbc, &priv->current_fragment); + ff_cbs_fragment_free(&priv->current_fragment); ff_cbs_close(&priv->cbc); return ff_vaapi_encode_close(avctx); @@ -559,11 +559,10 @@ AVCodec ff_mjpeg_vaapi_encoder = { .id = AV_CODEC_ID_MJPEG, .priv_data_size = sizeof(VAAPIEncodeMJPEGContext), .init = &vaapi_encode_mjpeg_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &vaapi_encode_mjpeg_close, .priv_class = &vaapi_encode_mjpeg_class, - .capabilities = AV_CODEC_CAP_HARDWARE, + .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_mjpeg_defaults, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c index 02c76552e..4c81d785d 100644 --- a/libavcodec/vaapi_encode_mpeg2.c +++ b/libavcodec/vaapi_encode_mpeg2.c @@ -93,10 +93,9 @@ static int vaapi_encode_mpeg2_add_header(AVCodecContext *avctx, CodedBitstreamFragment *frag, int type, void *header) { - VAAPIEncodeMPEG2Context *priv = avctx->priv_data; int err; - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, type, header, NULL); + err = ff_cbs_insert_unit_content(frag, -1, type, header, NULL); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to add header: " "type = %d.\n", type); @@ -135,7 +134,7 @@ static int vaapi_encode_mpeg2_write_sequence_header(AVCodecContext *avctx, err = vaapi_encode_mpeg2_write_fragment(avctx, data, data_len, frag); fail: - ff_cbs_fragment_reset(priv->cbc, frag); + ff_cbs_fragment_reset(frag); return 0; } @@ -159,7 +158,7 @@ static int vaapi_encode_mpeg2_write_picture_header(AVCodecContext *avctx, err = vaapi_encode_mpeg2_write_fragment(avctx, data, data_len, frag); fail: - ff_cbs_fragment_reset(priv->cbc, frag); + ff_cbs_fragment_reset(frag); return 0; } @@ -293,17 +292,16 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) priv->sequence_display_extension.extension_start_code_identifier = MPEG2_EXTENSION_SEQUENCE_DISPLAY; + // Unspecified video format, from table 6-6. sde->video_format = 5; - if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || + + sde->colour_primaries = avctx->color_primaries; + sde->transfer_characteristics = avctx->color_trc; + sde->matrix_coefficients = avctx->colorspace; + sde->colour_description = + avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || avctx->color_trc != AVCOL_TRC_UNSPECIFIED || - avctx->colorspace != AVCOL_SPC_UNSPECIFIED) { - sde->colour_description = 1; - sde->colour_primaries = avctx->color_primaries; - sde->transfer_characteristics = avctx->color_trc; - sde->matrix_coefficients = avctx->colorspace; - } else { - sde->colour_description = 0; - } + avctx->colorspace != AVCOL_SPC_UNSPECIFIED; sde->display_horizontal_size = avctx->width; sde->display_vertical_size = avctx->height; @@ -633,7 +631,7 @@ static av_cold int vaapi_encode_mpeg2_close(AVCodecContext *avctx) { VAAPIEncodeMPEG2Context *priv = avctx->priv_data; - ff_cbs_fragment_free(priv->cbc, &priv->current_fragment); + ff_cbs_fragment_free(&priv->current_fragment); ff_cbs_close(&priv->cbc); return ff_vaapi_encode_close(avctx); @@ -697,11 +695,11 @@ AVCodec ff_mpeg2_vaapi_encoder = { .id = AV_CODEC_ID_MPEG2VIDEO, .priv_data_size = sizeof(VAAPIEncodeMPEG2Context), .init = &vaapi_encode_mpeg2_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &vaapi_encode_mpeg2_close, .priv_class = &vaapi_encode_mpeg2_class, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | + AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_mpeg2_defaults, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c index cff926baa..66cf2321b 100644 --- a/libavcodec/vaapi_encode_vp8.c +++ b/libavcodec/vaapi_encode_vp8.c @@ -252,11 +252,11 @@ AVCodec ff_vp8_vaapi_encoder = { .id = AV_CODEC_ID_VP8, .priv_data_size = sizeof(VAAPIEncodeVP8Context), .init = &vaapi_encode_vp8_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &ff_vaapi_encode_close, .priv_class = &vaapi_encode_vp8_class, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | + AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_vp8_defaults, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c index 8514b8599..0e1c52c92 100644 --- a/libavcodec/vaapi_encode_vp9.c +++ b/libavcodec/vaapi_encode_vp9.c @@ -286,11 +286,11 @@ AVCodec ff_vp9_vaapi_encoder = { .id = AV_CODEC_ID_VP9, .priv_data_size = sizeof(VAAPIEncodeVP9Context), .init = &vaapi_encode_vp9_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &ff_vaapi_encode_close, .priv_class = &vaapi_encode_vp9_class, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | + AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_vp9_defaults, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/libavcodec/vb.c b/libavcodec/vb.c index d9c6b93a7..fe419c766 100644 --- a/libavcodec/vb.c +++ b/libavcodec/vb.c @@ -262,11 +262,8 @@ static av_cold int decode_init(AVCodecContext *avctx) c->frame = av_mallocz(avctx->width * avctx->height); c->prev_frame = av_mallocz(avctx->width * avctx->height); - if (!c->frame || !c->prev_frame) { - av_freep(&c->frame); - av_freep(&c->prev_frame); + if (!c->frame || !c->prev_frame) return AVERROR(ENOMEM); - } return 0; } @@ -291,4 +288,5 @@ AVCodec ff_vb_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/vble.c b/libavcodec/vble.c index c48c13127..2cddd550b 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -197,7 +197,6 @@ static av_cold int vble_decode_init(AVCodecContext *avctx) if (!ctx->val) { av_log(avctx, AV_LOG_ERROR, "Could not allocate values buffer.\n"); - vble_decode_close(avctx); return AVERROR(ENOMEM); } diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 9df778bca..cd9975d8c 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -27,6 +27,7 @@ */ #include "libavutil/attributes.h" +#include "libavutil/thread.h" #include "internal.h" #include "avcodec.h" #include "mpegvideo.h" @@ -1576,21 +1577,11 @@ static const uint16_t vlc_offs[] = { 31714, 31746, 31778, 32306, 32340, 32372 }; -/** - * Init VC-1 specific tables and VC1Context members - * @param v The VC1Context to initialize - * @return Status - */ -av_cold int ff_vc1_init_common(VC1Context *v) +static av_cold void vc1_init_static(void) { - static int done = 0; int i = 0; static VLC_TYPE vlc_table[32372][2]; - v->hrd_rate = v->hrd_buffer = NULL; - - /* VLC tables */ - if (!done) { INIT_VLC_STATIC(&ff_vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23, ff_vc1_bfraction_bits, 1, 1, ff_vc1_bfraction_codes, 1, 1, 1 << VC1_BFRACTION_VLC_BITS); @@ -1697,14 +1688,27 @@ av_cold int ff_vc1_init_common(VC1Context *v) ff_vc1_if_1mv_mbmode_bits[i], 1, 1, ff_vc1_if_1mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); } - done = 1; - } +} - /* Other defaults */ +/** + * Init VC-1 specific tables and VC1Context members + * @param v The VC1Context to initialize + * @return Status + */ +av_cold int ff_vc1_init_common(VC1Context *v) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + + v->hrd_rate = v->hrd_buffer = NULL; + + /* defaults */ v->pq = -1; v->mvrange = 0; /* 7.1.1.18, p80 */ ff_vc1dsp_init(&v->vc1dsp); + /* VLC tables */ + ff_thread_once(&init_static_once, vc1_init_static); + return 0; } diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 5c3317093..b6ace3765 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -592,10 +592,6 @@ static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n, } else { dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); } - if (dcdiff < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n"); - return -1; - } if (dcdiff) { const int m = (v->pq == 1 || v->pq == 2) ? 3 - v->pq : 0; if (dcdiff == 119 /* ESC index value */) { @@ -740,10 +736,6 @@ static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n, } else { dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); } - if (dcdiff < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n"); - return -1; - } if (dcdiff) { const int m = (quant == 1 || quant == 2) ? 3 - quant : 0; if (dcdiff == 119 /* ESC index value */) { @@ -944,10 +936,6 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n, } else { dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); } - if (dcdiff < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n"); - return -1; - } if (dcdiff) { const int m = (quant == 1 || quant == 2) ? 3 - quant : 0; if (dcdiff == 119 /* ESC index value */) { diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 7809234ff..ea93e1158 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -384,7 +384,7 @@ 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 AVERROR(ENOMEM); + goto error; } ret = ff_intrax8_common_init(s->avctx, &v->x8, &s->idsp, @@ -539,12 +539,6 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) ff_h264chroma_init(&v->h264chroma, 8); ff_qpeldsp_init(&s->qdsp); - // Must happen after calling ff_vc1_decode_end - // to avoid de-allocating the sprite_output_frame - v->sprite_output_frame = av_frame_alloc(); - if (!v->sprite_output_frame) - return AVERROR(ENOMEM); - avctx->has_b_frames = !!avctx->max_b_frames; if (v->color_prim == 1 || v->color_prim == 5 || v->color_prim == 6) @@ -577,20 +571,15 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) v->sprite_height > 1 << 14 || v->output_width > 1 << 14 || v->output_height > 1 << 14) { - ret = AVERROR_INVALIDDATA; - goto error; + return AVERROR_INVALIDDATA; } if ((v->sprite_width&1) || (v->sprite_height&1)) { avpriv_request_sample(avctx, "odd sprites support"); - ret = AVERROR_PATCHWELCOME; - goto error; + return AVERROR_PATCHWELCOME; } } return 0; -error: - av_frame_free(&v->sprite_output_frame); - return ret; } /** Close a VC1/WMV3 decoder @@ -1147,6 +1136,11 @@ image: avctx->height = avctx->coded_height = v->output_height; if (avctx->skip_frame >= AVDISCARD_NONREF) goto end; + if (!v->sprite_output_frame && + !(v->sprite_output_frame = av_frame_alloc())) { + ret = AVERROR(ENOMEM); + goto err; + } #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER if ((ret = vc1_decode_sprites(v, &s->gb)) < 0) goto err; @@ -1217,7 +1211,7 @@ AVCodec ff_vc1_decoder = { .flush = ff_mpeg_flush, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, .pix_fmts = vc1_hwaccel_pixfmt_list_420, - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_VC1_DXVA2_HWACCEL HWACCEL_DXVA2(vc1), #endif @@ -1254,7 +1248,7 @@ AVCodec ff_wmv3_decoder = { .flush = ff_mpeg_flush, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, .pix_fmts = vc1_hwaccel_pixfmt_list_420, - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_WMV3_DXVA2_HWACCEL HWACCEL_DXVA2(wmv3), #endif diff --git a/libavcodec/vc2enc.c b/libavcodec/vc2enc.c index ba5a03e4e..7bd2e4c2a 100644 --- a/libavcodec/vc2enc.c +++ b/libavcodec/vc2enc.c @@ -229,12 +229,12 @@ static void encode_parse_info(VC2EncContext *s, enum DiracParseCodes pcode) { uint32_t cur_pos, dist; - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); cur_pos = put_bits_count(&s->pb) >> 3; /* Magic string */ - avpriv_put_string(&s->pb, "BBCD", 0); + ff_put_string(&s->pb, "BBCD", 0); /* Parse code */ put_bits(&s->pb, 8, pcode); @@ -399,7 +399,7 @@ static void encode_source_params(VC2EncContext *s) /* VC-2 11 - sequence_header() */ static void encode_seq_header(VC2EncContext *s) { - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); encode_parse_params(s); put_vc2_ue_uint(&s->pb, s->base_vf); encode_source_params(s); @@ -409,7 +409,7 @@ static void encode_seq_header(VC2EncContext *s) /* VC-2 12.1 - picture_header() */ static void encode_picture_header(VC2EncContext *s) { - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); put_bits32(&s->pb, s->picture_number++); } @@ -423,7 +423,7 @@ static void encode_slice_params(VC2EncContext *s) } /* 1st idx = LL, second - vertical, third - horizontal, fourth - total */ -const uint8_t vc2_qm_col_tab[][4] = { +static const uint8_t vc2_qm_col_tab[][4] = { {20, 9, 15, 4}, { 0, 6, 6, 4}, { 0, 3, 3, 5}, @@ -431,7 +431,7 @@ const uint8_t vc2_qm_col_tab[][4] = { { 0, 11, 10, 11} }; -const uint8_t vc2_qm_flat_tab[][4] = { +static const uint8_t vc2_qm_flat_tab[][4] = { { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, @@ -509,15 +509,15 @@ static void encode_transform_params(VC2EncContext *s) static void encode_wavelet_transform(VC2EncContext *s) { encode_transform_params(s); - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); } /* VC-2 12 - picture_parse() */ static void encode_picture_start(VC2EncContext *s) { - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); encode_picture_header(s); - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); encode_wavelet_transform(s); } @@ -753,7 +753,7 @@ static int encode_hq_slice(AVCodecContext *avctx, void *arg) quants[level][orientation]); } } - avpriv_align_put_bits(pb); + align_put_bits(pb); bytes_len = (put_bits_count(pb) >> 3) - bytes_start - 1; if (p == 2) { int len_diff = slice_bytes_max - (put_bits_count(pb) >> 3); @@ -780,7 +780,6 @@ static int encode_slices(VC2EncContext *s) int slice_x, slice_y, skip = 0; SliceArgs *enc_args = s->slice_args; - avpriv_align_put_bits(&s->pb); flush_put_bits(&s->pb); buf = put_bits_ptr(&s->pb); @@ -932,7 +931,7 @@ static int encode_frame(VC2EncContext *s, AVPacket *avpkt, const AVFrame *frame, /* Encoder version */ if (aux_data) { encode_parse_info(s, DIRAC_PCODE_AUX); - avpriv_put_string(&s->pb, aux_data, 1); + ff_put_string(&s->pb, aux_data, 1); } /* Picture header */ diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index 167f06d7a..fa10905c7 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -83,6 +83,8 @@ int av_vdpau_get_surface_parameters(AVCodecContext *avctx, switch (avctx->sw_pix_fmt) { case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUVJ420P: + case AV_PIX_FMT_YUV420P10: + case AV_PIX_FMT_YUV420P12: t = VDP_CHROMA_TYPE_420; w = (w + 1) & ~1; h = (h + 3) & ~3; @@ -95,6 +97,8 @@ int av_vdpau_get_surface_parameters(AVCodecContext *avctx, break; case AV_PIX_FMT_YUV444P: case AV_PIX_FMT_YUVJ444P: + case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUV444P12: t = VDP_CHROMA_TYPE_444; h = (h + 1) & ~1; break; diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index 29cb2da07..c17de0c5d 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -29,6 +29,8 @@ #include "hwconfig.h" #include "vdpau.h" #include "vdpau_internal.h" +#include "h265_profile_level.h" + static int vdpau_hevc_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) @@ -429,10 +431,93 @@ static int vdpau_hevc_end_frame(AVCodecContext *avctx) return 0; } + + +static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel *h265_raw_ptl) +{ + h265_raw_ptl->general_profile_space = general_ptl->profile_space; + h265_raw_ptl->general_tier_flag = general_ptl->tier_flag; + h265_raw_ptl->general_profile_idc = general_ptl->profile_idc; + + memcpy(h265_raw_ptl->general_profile_compatibility_flag, + general_ptl->profile_compatibility_flag, 32 * sizeof(uint8_t)); + +#define copy_field(name) h265_raw_ptl->general_ ## name = general_ptl->name + copy_field(progressive_source_flag); + copy_field(interlaced_source_flag); + copy_field(non_packed_constraint_flag); + copy_field(frame_only_constraint_flag); + copy_field(max_12bit_constraint_flag); + copy_field(max_10bit_constraint_flag); + copy_field(max_8bit_constraint_flag); + copy_field(max_422chroma_constraint_flag); + copy_field(max_420chroma_constraint_flag); + copy_field(max_monochrome_constraint_flag); + copy_field(intra_constraint_flag); + copy_field(one_picture_only_constraint_flag); + copy_field(lower_bit_rate_constraint_flag); + copy_field(max_14bit_constraint_flag); + copy_field(inbld_flag); + copy_field(level_idc); +#undef copy_field + + return 0; +} + +/* + * Find exact vdpau_profile for HEVC Range Extension + */ +static int vdpau_hevc_parse_rext_profile(AVCodecContext *avctx, VdpDecoderProfile *vdp_profile) +{ + const HEVCContext *h = avctx->priv_data; + const HEVCSPS *sps = h->ps.sps; + const PTL *ptl = &sps->ptl; + const PTLCommon *general_ptl = &ptl->general_ptl; + const H265ProfileDescriptor *profile; + H265RawProfileTierLevel h265_raw_ptl = {0}; + + /* convert PTLCommon to H265RawProfileTierLevel */ + ptl_convert(general_ptl, &h265_raw_ptl); + + profile = ff_h265_get_profile(&h265_raw_ptl); + if (!profile) { + av_log(avctx, AV_LOG_WARNING, "HEVC profile is not found.\n"); + if (avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH) { + // Default to selecting Main profile if profile mismatch is allowed + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN; + return 0; + } else + return AVERROR(ENOTSUP); + } + + if (!strcmp(profile->name, "Main 12") || + !strcmp(profile->name, "Main 12 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_12; +#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444 + else if (!strcmp(profile->name, "Main 4:4:4") || + !strcmp(profile->name, "Main 4:4:4 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444; +#endif +#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444_10 + else if (!strcmp(profile->name, "Main 4:4:4 10") || + !strcmp(profile->name, "Main 4:4:4 10 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444_10; + else if (!strcmp(profile->name, "Main 4:4:4 12") || + !strcmp(profile->name, "Main 4:4:4 12 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444_12; +#endif + else + return AVERROR(ENOTSUP); + + return 0; +} + + static int vdpau_hevc_init(AVCodecContext *avctx) { VdpDecoderProfile profile; uint32_t level = avctx->level; + int ret; switch (avctx->profile) { case FF_PROFILE_HEVC_MAIN: @@ -445,7 +530,9 @@ static int vdpau_hevc_init(AVCodecContext *avctx) profile = VDP_DECODER_PROFILE_HEVC_MAIN_STILL; break; case FF_PROFILE_HEVC_REXT: - profile = VDP_DECODER_PROFILE_HEVC_MAIN_444; + ret = vdpau_hevc_parse_rext_profile(avctx, &profile); + if (ret) + return AVERROR(ENOTSUP); break; default: return AVERROR(ENOTSUP); diff --git a/libavcodec/version.h b/libavcodec/version.h index 85fbe24dc..cfdde4696 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 91 +#define LIBAVCODEC_VERSION_MINOR 134 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ @@ -51,12 +51,6 @@ * at once through the bump. This improves the git bisect-ability of the change. */ -#ifndef FF_API_LOWRES -#define FF_API_LOWRES (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_DEBUG_MV -#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 58) -#endif #ifndef FF_API_AVCTX_TIMEBASE #define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59) #endif @@ -144,6 +138,35 @@ #ifndef FF_API_UNUSED_CODEC_CAPS #define FF_API_UNUSED_CODEC_CAPS (LIBAVCODEC_VERSION_MAJOR < 59) #endif - +#ifndef FF_API_AVPRIV_PUT_BITS +#define FF_API_AVPRIV_PUT_BITS (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OLD_ENCDEC +#define FF_API_OLD_ENCDEC (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_AVCODEC_PIX_FMT +#define FF_API_AVCODEC_PIX_FMT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_MPV_RC_STRATEGY +#define FF_API_MPV_RC_STRATEGY (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_PARSER_CHANGE +#define FF_API_PARSER_CHANGE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_THREAD_SAFE_CALLBACKS +#define FF_API_THREAD_SAFE_CALLBACKS (LIBAVCODEC_VERSION_MAJOR < 60) +#endif +#ifndef FF_API_DEBUG_MV +#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 60) +#endif +#ifndef FF_API_GET_FRAME_CLASS +#define FF_API_GET_FRAME_CLASS (LIBAVCODEC_VERSION_MAJOR < 60) +#endif +#ifndef FF_API_AUTO_THREADS +#define FF_API_AUTO_THREADS (LIBAVCODEC_VERSION_MAJOR < 60) +#endif +#ifndef FF_API_INIT_PACKET +#define FF_API_INIT_PACKET (LIBAVCODEC_VERSION_MAJOR < 60) +#endif #endif /* AVCODEC_VERSION_H */ diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 8773de339..49e726a75 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -1088,7 +1088,13 @@ static int videotoolbox_common_init(AVCodecContext *avctx) vtctx->vt_ctx->cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt2(hw_frames->sw_format, full_range); if (!vtctx->vt_ctx->cv_pix_fmt_type) { - av_log(avctx, AV_LOG_ERROR, "Unknown sw_format.\n"); + const AVPixFmtDescriptor *attempted_format = + av_pix_fmt_desc_get(hw_frames->sw_format); + av_log(avctx, AV_LOG_ERROR, + "Failed to map underlying FFmpeg pixel format %s (%s range) to " + "a VideoToolbox format!\n", + attempted_format ? attempted_format->name : "", + av_color_range_name(avctx->color_range)); err = AVERROR(EINVAL); goto fail; } diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index cc08cf6a5..9b7ee6720 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -31,6 +31,7 @@ #include "libavutil/pixdesc.h" #include "internal.h" #include +#include "atsc_a53.h" #include "h264.h" #include "h264_sei.h" #include @@ -39,6 +40,10 @@ enum { kCMVideoCodecType_HEVC = 'hvc1' }; #endif +#if !HAVE_KCMVIDEOCODECTYPE_HEVCWITHALPHA +enum { kCMVideoCodecType_HEVCWithAlpha = 'muxa' }; +#endif + #if !HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE enum { kCVPixelFormatType_420YpCbCr10BiPlanarFullRange = 'xf20' }; enum { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange = 'x420' }; @@ -87,6 +92,7 @@ static struct{ CFStringRef kVTProfileLevel_HEVC_Main10_AutoLevel; CFStringRef kVTCompressionPropertyKey_RealTime; + CFStringRef kVTCompressionPropertyKey_TargetQualityForAlpha; CFStringRef kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder; CFStringRef kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder; @@ -146,6 +152,8 @@ static void loadVTEncSymbols(){ GET_SYM(kVTProfileLevel_HEVC_Main10_AutoLevel, "HEVC_Main10_AutoLevel"); GET_SYM(kVTCompressionPropertyKey_RealTime, "RealTime"); + GET_SYM(kVTCompressionPropertyKey_TargetQualityForAlpha, + "TargetQualityForAlpha"); GET_SYM(kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder, "EnableHardwareAcceleratedVideoEncoder"); @@ -221,11 +229,14 @@ typedef struct VTEncContext { int64_t allow_sw; int64_t require_sw; + double alpha_quality; bool flushing; - bool has_b_frames; + int has_b_frames; bool warned_color_range; - bool a53_cc; + + /* can't be bool type since AVOption will access it as int */ + int a53_cc; } VTEncContext; static int vtenc_populate_extradata(AVCodecContext *avctx, @@ -291,7 +302,7 @@ static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf, E return 0; } - while (!vtctx->q_head && !vtctx->async_error && wait) { + while (!vtctx->q_head && !vtctx->async_error && wait && !vtctx->flushing) { pthread_cond_wait(&vtctx->cv_sample_sent, &vtctx->lock); } @@ -307,6 +318,7 @@ static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf, E vtctx->q_tail = NULL; } + vtctx->frame_ct_out++; pthread_mutex_unlock(&vtctx->lock); *buf = info->cm_buffer; @@ -318,7 +330,6 @@ static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf, E } av_free(info); - vtctx->frame_ct_out++; return 0; } @@ -337,7 +348,6 @@ static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer, ExtraSEI info->next = NULL; pthread_mutex_lock(&vtctx->lock); - pthread_cond_signal(&vtctx->cv_sample_sent); if (!vtctx->q_head) { vtctx->q_head = info; @@ -347,6 +357,7 @@ static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer, ExtraSEI vtctx->q_tail = info; + pthread_cond_signal(&vtctx->cv_sample_sent); pthread_mutex_unlock(&vtctx->lock); } @@ -389,11 +400,17 @@ static int count_nalus(size_t length_code_size, return 0; } -static CMVideoCodecType get_cm_codec_type(enum AVCodecID id) +static CMVideoCodecType get_cm_codec_type(enum AVCodecID id, + enum AVPixelFormat fmt, + double alpha_quality) { switch (id) { case AV_CODEC_ID_H264: return kCMVideoCodecType_H264; - case AV_CODEC_ID_HEVC: return kCMVideoCodecType_HEVC; + case AV_CODEC_ID_HEVC: + if (fmt == AV_PIX_FMT_BGRA && alpha_quality > 0.0) { + return kCMVideoCodecType_HEVCWithAlpha; + } + return kCMVideoCodecType_HEVC; default: return 0; } } @@ -570,7 +587,6 @@ static void vtenc_output_callback( ExtraSEI *sei = sourceFrameCtx; if (vtctx->async_error) { - if(sample_buffer) CFRelease(sample_buffer); return; } @@ -784,11 +800,12 @@ static int get_cv_pixel_format(AVCodecContext* avctx, *av_pixel_format = range == AVCOL_RANGE_JPEG ? kCVPixelFormatType_420YpCbCr8PlanarFullRange : kCVPixelFormatType_420YpCbCr8Planar; + } else if (fmt == AV_PIX_FMT_BGRA) { + *av_pixel_format = kCVPixelFormatType_32BGRA; } else if (fmt == AV_PIX_FMT_P010LE) { *av_pixel_format = range == AVCOL_RANGE_JPEG ? kCVPixelFormatType_420YpCbCr10BiPlanarFullRange : kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange; - *av_pixel_format = kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange; } else { return AVERROR(EINVAL); } @@ -1013,6 +1030,12 @@ static int get_cv_ycbcr_matrix(AVCodecContext *avctx, CFStringRef *matrix) { return 0; } +// constant quality only on Macs with Apple Silicon +static bool vtenc_qscale_enabled(void) +{ + return TARGET_OS_OSX && TARGET_CPU_ARM64; +} + static int vtenc_create_encoder(AVCodecContext *avctx, CMVideoCodecType codec_type, CFStringRef profile_level, @@ -1024,7 +1047,9 @@ static int vtenc_create_encoder(AVCodecContext *avctx, VTEncContext *vtctx = avctx->priv_data; SInt32 bit_rate = avctx->bit_rate; SInt32 max_rate = avctx->rc_max_rate; + Float32 quality = avctx->global_quality / FF_QP2LAMBDA; CFNumberRef bit_rate_num; + CFNumberRef quality_num; CFNumberRef bytes_per_second; CFNumberRef one_second; CFArrayRef data_rate_limits; @@ -1055,15 +1080,33 @@ static int vtenc_create_encoder(AVCodecContext *avctx, return AVERROR_EXTERNAL; } - bit_rate_num = CFNumberCreate(kCFAllocatorDefault, - kCFNumberSInt32Type, - &bit_rate); - if (!bit_rate_num) return AVERROR(ENOMEM); + if (avctx->flags & AV_CODEC_FLAG_QSCALE && !vtenc_qscale_enabled()) { + av_log(avctx, AV_LOG_ERROR, "Error: -q:v qscale not available for encoder. Use -b:v bitrate instead.\n"); + return AVERROR_EXTERNAL; + } - status = VTSessionSetProperty(vtctx->session, - kVTCompressionPropertyKey_AverageBitRate, - bit_rate_num); - CFRelease(bit_rate_num); + if (avctx->flags & AV_CODEC_FLAG_QSCALE) { + quality = quality >= 100 ? 1.0 : quality / 100; + quality_num = CFNumberCreate(kCFAllocatorDefault, + kCFNumberFloat32Type, + &quality); + if (!quality_num) return AVERROR(ENOMEM); + + status = VTSessionSetProperty(vtctx->session, + kVTCompressionPropertyKey_Quality, + quality_num); + CFRelease(quality_num); + } else { + bit_rate_num = CFNumberCreate(kCFAllocatorDefault, + kCFNumberSInt32Type, + &bit_rate); + if (!bit_rate_num) return AVERROR(ENOMEM); + + status = VTSessionSetProperty(vtctx->session, + kVTCompressionPropertyKey_AverageBitRate, + bit_rate_num); + CFRelease(bit_rate_num); + } if (status) { av_log(avctx, AV_LOG_ERROR, "Error setting bitrate property: %d\n", status); @@ -1113,15 +1156,26 @@ static int vtenc_create_encoder(AVCodecContext *avctx, } } - if (vtctx->codec_id == AV_CODEC_ID_H264) { - // kVTCompressionPropertyKey_ProfileLevel is not available for HEVC - if (profile_level) { + if (vtctx->codec_id == AV_CODEC_ID_HEVC) { + if (avctx->pix_fmt == AV_PIX_FMT_BGRA && vtctx->alpha_quality > 0.0) { + CFNumberRef alpha_quality_num = CFNumberCreate(kCFAllocatorDefault, + kCFNumberDoubleType, + &vtctx->alpha_quality); + if (!alpha_quality_num) return AVERROR(ENOMEM); + status = VTSessionSetProperty(vtctx->session, - kVTCompressionPropertyKey_ProfileLevel, - profile_level); - if (status) { - av_log(avctx, AV_LOG_ERROR, "Error setting profile/level property: %d. Output will be encoded using a supported profile/level combination.\n", status); - } + compat_keys.kVTCompressionPropertyKey_TargetQualityForAlpha, + alpha_quality_num); + CFRelease(alpha_quality_num); + } + } + + if (profile_level) { + status = VTSessionSetProperty(vtctx->session, + kVTCompressionPropertyKey_ProfileLevel, + profile_level); + if (status) { + av_log(avctx, AV_LOG_ERROR, "Error setting profile/level property: %d. Output will be encoded using a supported profile/level combination.\n", status); } } @@ -1328,13 +1382,14 @@ static int vtenc_configure_encoder(AVCodecContext *avctx) CFNumberRef gamma_level = NULL; int status; - codec_type = get_cm_codec_type(avctx->codec_id); + codec_type = get_cm_codec_type(avctx->codec_id, avctx->pix_fmt, vtctx->alpha_quality); if (!codec_type) { av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID %d\n", avctx->codec_id); return AVERROR(EINVAL); } vtctx->codec_id = avctx->codec_id; + avctx->max_b_frames = 16; if (vtctx->codec_id == AV_CODEC_ID_H264) { vtctx->get_param_set_func = CMVideoFormatDescriptionGetH264ParameterSetAtIndex; @@ -1342,7 +1397,7 @@ static int vtenc_configure_encoder(AVCodecContext *avctx) vtctx->has_b_frames = avctx->max_b_frames > 0; if(vtctx->has_b_frames && vtctx->profile == H264_PROF_BASELINE){ av_log(avctx, AV_LOG_WARNING, "Cannot use B-frames with baseline profile. Output will not contain B-frames.\n"); - vtctx->has_b_frames = false; + vtctx->has_b_frames = 0; } if (vtctx->entropy == VT_CABAC && vtctx->profile == H264_PROF_BASELINE) { @@ -1355,6 +1410,8 @@ static int vtenc_configure_encoder(AVCodecContext *avctx) vtctx->get_param_set_func = compat_keys.CMVideoFormatDescriptionGetHEVCParameterSetAtIndex; if (!vtctx->get_param_set_func) return AVERROR(EINVAL); if (!get_vt_hevc_profile_level(avctx, &profile_level)) return AVERROR(EINVAL); + // HEVC has b-byramid + vtctx->has_b_frames = avctx->max_b_frames > 0 ? 2 : 0; } enc_info = CFDictionaryCreateMutable( @@ -1450,7 +1507,8 @@ static av_cold int vtenc_init(AVCodecContext *avctx) if (!status && has_b_frames_cfbool) { //Some devices don't output B-frames for main profile, even if requested. - vtctx->has_b_frames = CFBooleanGetValue(has_b_frames_cfbool); + // HEVC has b-pyramid + vtctx->has_b_frames = (CFBooleanGetValue(has_b_frames_cfbool) && avctx->codec_id == AV_CODEC_ID_HEVC) ? 2 : 1; CFRelease(has_b_frames_cfbool); } avctx->has_b_frames = vtctx->has_b_frames; @@ -1753,7 +1811,7 @@ static int copy_replace_length_codes( remaining_dst_size--; wrote_bytes = write_sei(sei, - H264_SEI_TYPE_USER_DATA_REGISTERED, + SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35, dst_data, remaining_dst_size); @@ -1809,7 +1867,7 @@ static int copy_replace_length_codes( return status; wrote_bytes = write_sei(sei, - H264_SEI_TYPE_USER_DATA_REGISTERED, + SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35, new_sei, remaining_dst_size - old_sei_length); if (wrote_bytes < 0) @@ -1905,7 +1963,7 @@ static int vtenc_cm_to_avpacket( if (sei) { size_t msg_size = get_sei_msg_bytes(sei, - H264_SEI_TYPE_USER_DATA_REGISTERED); + SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35); sei_nalu_size = sizeof(start_code) + 1 + msg_size + 1; } @@ -2038,6 +2096,14 @@ static int get_cv_pixel_info( strides[2] = frame ? frame->linesize[2] : (avctx->width + 1) / 2; break; + case AV_PIX_FMT_BGRA: + *plane_count = 1; + + widths [0] = avctx->width; + heights[0] = avctx->height; + strides[0] = frame ? frame->linesize[0] : avctx->width * 4; + break; + case AV_PIX_FMT_P010LE: *plane_count = 2; widths[0] = avctx->width; @@ -2358,7 +2424,7 @@ static av_cold int vtenc_frame( if (vtctx->frame_ct_in == 0) { vtctx->first_pts = frame->pts; - } else if(vtctx->frame_ct_in == 1 && vtctx->has_b_frames) { + } else if(vtctx->frame_ct_in == vtctx->has_b_frames) { vtctx->dts_delta = frame->pts - vtctx->first_pts; } @@ -2493,14 +2559,17 @@ static av_cold int vtenc_close(AVCodecContext *avctx) { VTEncContext *vtctx = avctx->priv_data; - pthread_cond_destroy(&vtctx->cv_sample_sent); - pthread_mutex_destroy(&vtctx->lock); - - if(!vtctx->session) return 0; + if(!vtctx->session) { + pthread_cond_destroy(&vtctx->cv_sample_sent); + pthread_mutex_destroy(&vtctx->lock); + return 0; + } VTCompressionSessionCompleteFrames(vtctx->session, kCMTimeIndefinite); clear_frame_queue(vtctx); + pthread_cond_destroy(&vtctx->cv_sample_sent); + pthread_mutex_destroy(&vtctx->lock); CFRelease(vtctx->session); vtctx->session = NULL; @@ -2533,6 +2602,7 @@ static const enum AVPixelFormat hevc_pix_fmts[] = { AV_PIX_FMT_VIDEOTOOLBOX, AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_BGRA, AV_PIX_FMT_P010LE, AV_PIX_FMT_NONE }; @@ -2610,6 +2680,8 @@ static const AVOption hevc_options[] = { { "main", "Main Profile", 0, AV_OPT_TYPE_CONST, { .i64 = HEVC_PROF_MAIN }, INT_MIN, INT_MAX, VE, "profile" }, { "main10", "Main10 Profile", 0, AV_OPT_TYPE_CONST, { .i64 = HEVC_PROF_MAIN10 }, INT_MIN, INT_MAX, VE, "profile" }, + { "alpha_quality", "Compression quality for the alpha channel", OFFSET(alpha_quality), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0.0, 1.0, VE }, + COMMON_OPTIONS { NULL }, }; diff --git a/libavcodec/vima.c b/libavcodec/vima.c index b4620acf6..2dfc2cc5c 100644 --- a/libavcodec/vima.c +++ b/libavcodec/vima.c @@ -214,5 +214,5 @@ AVCodec ff_adpcm_vima_decoder = { .id = AV_CODEC_ID_ADPCM_VIMA, .init = decode_init, .decode = decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, }; diff --git a/libavcodec/vlc.h b/libavcodec/vlc.h index 42ccddf3f..6879c3ca6 100644 --- a/libavcodec/vlc.h +++ b/libavcodec/vlc.h @@ -49,28 +49,73 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, const void *codes, int codes_wrap, int codes_size, const void *symbols, int symbols_wrap, int symbols_size, int flags); + +/** + * Build VLC decoding tables suitable for use with get_vlc2() + * + * This function takes lengths and symbols and calculates the codes from them. + * For this the input lengths and symbols have to be sorted according to "left + * nodes in the corresponding tree first". + * + * @param[in,out] vlc The VLC to be initialized; table and table_allocated + * must have been set when initializing a static VLC, + * otherwise this will be treated as uninitialized. + * @param[in] nb_bits The number of bits to use for the VLC table; + * higher values take up more memory and cache, but + * allow to read codes with fewer reads. + * @param[in] nb_codes The number of provided length and (if supplied) symbol + * entries. + * @param[in] lens The lengths of the codes. Entries > 0 correspond to + * valid codes; entries == 0 will be skipped and entries + * with len < 0 indicate that the tree is incomplete and + * has an open end of length -len at this position. + * @param[in] lens_wrap Stride (in bytes) of the lengths. + * @param[in] symbols The symbols, i.e. what is returned from get_vlc2() + * when the corresponding code is encountered. + * May be NULL, then 0, 1, 2, 3, 4,... will be used. + * @param[in] symbols_wrap Stride (in bytes) of the symbols. + * @param[in] symbols_size Size of the symbols. 1 and 2 are supported. + * @param[in] offset An offset to apply to all the valid symbols. + * @param[in] flags A combination of the INIT_VLC_* flags; notice that + * INIT_VLC_INPUT_LE is pointless and ignored. + */ +int ff_init_vlc_from_lengths(VLC *vlc, int nb_bits, int nb_codes, + const int8_t *lens, int lens_wrap, + const void *symbols, int symbols_wrap, int symbols_size, + int offset, int flags, void *logctx); + void ff_free_vlc(VLC *vlc); -#define INIT_VLC_LE 2 +/* If INIT_VLC_INPUT_LE is set, the LSB bit of the codes used to + * initialize the VLC table is the first bit to be read. */ +#define INIT_VLC_INPUT_LE 2 +/* If set the VLC is intended for a little endian bitstream reader. */ +#define INIT_VLC_OUTPUT_LE 8 +#define INIT_VLC_LE (INIT_VLC_INPUT_LE | INIT_VLC_OUTPUT_LE) #define INIT_VLC_USE_NEW_STATIC 4 +#define INIT_VLC_STATIC_OVERLONG (1 | INIT_VLC_USE_NEW_STATIC) + +#define INIT_CUSTOM_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, \ + h, i, j, flags, static_size) \ + do { \ + static VLC_TYPE table[static_size][2]; \ + (vlc)->table = table; \ + (vlc)->table_allocated = static_size; \ + ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ + flags | INIT_VLC_USE_NEW_STATIC); \ + } while (0) #define INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ - do { \ - static VLC_TYPE table[static_size][2]; \ - (vlc)->table = table; \ - (vlc)->table_allocated = static_size; \ - ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ - INIT_VLC_USE_NEW_STATIC); \ - } while (0) + INIT_CUSTOM_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, \ + h, i, j, 0, static_size) #define INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ - do { \ - static VLC_TYPE table[static_size][2]; \ - (vlc)->table = table; \ - (vlc)->table_allocated = static_size; \ - ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ - INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); \ - } while (0) + INIT_CUSTOM_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, \ + h, i, j, INIT_VLC_LE, static_size) + +#define INIT_CUSTOM_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, flags, static_size) \ + INIT_CUSTOM_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, \ + NULL, 0, 0, flags, static_size) #define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) @@ -78,4 +123,17 @@ void ff_free_vlc(VLC *vlc); #define INIT_LE_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) +#define INIT_VLC_STATIC_FROM_LENGTHS(vlc, bits, nb_codes, lens, len_wrap, \ + symbols, symbols_wrap, symbols_size, \ + offset, flags, static_size) \ + do { \ + static VLC_TYPE table[static_size][2]; \ + (vlc)->table = table; \ + (vlc)->table_allocated = static_size; \ + ff_init_vlc_from_lengths(vlc, bits, nb_codes, lens, len_wrap, \ + symbols, symbols_wrap, symbols_size, \ + offset, flags | INIT_VLC_USE_NEW_STATIC, \ + NULL); \ + } while (0) + #endif /* AVCODEC_VLC_H */ diff --git a/libavcodec/vmdvideo.c b/libavcodec/vmdvideo.c index c1dc5b969..bb9306e4f 100644 --- a/libavcodec/vmdvideo.c +++ b/libavcodec/vmdvideo.c @@ -194,7 +194,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) unsigned char len; int ofs; - int frame_x, frame_y; + int frame_x, frame_y, prev_linesize; int frame_width, frame_height; frame_x = AV_RL16(&s->buf[6]); @@ -282,7 +282,13 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) } 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]; + if (s->prev_frame->data[0]) { + prev_linesize = s->prev_frame->linesize[0]; + pp = s->prev_frame->data[0] + frame_y * prev_linesize + frame_x; + } else { + pp = NULL; + prev_linesize = 0; + } switch (meth) { case 1: for (i = 0; i < frame_height; i++) { @@ -298,7 +304,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) ofs += len; } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) + if (ofs + len + 1 > frame_width || !pp) return AVERROR_INVALIDDATA; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -311,7 +317,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } dp += frame->linesize[0]; - pp += s->prev_frame->linesize[0]; + pp = FF_PTR_ADD(pp, prev_linesize); } break; @@ -319,7 +325,6 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) 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; @@ -347,7 +352,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) } } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) + if (ofs + len + 1 > frame_width || !pp) return AVERROR_INVALIDDATA; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -360,7 +365,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } dp += frame->linesize[0]; - pp += s->prev_frame->linesize[0]; + pp = FF_PTR_ADD(pp, prev_linesize); } break; } diff --git a/libavcodec/vorbis.h b/libavcodec/vorbis.h index 98dd14f9d..69ddbd298 100644 --- a/libavcodec/vorbis.h +++ b/libavcodec/vorbis.h @@ -26,7 +26,6 @@ extern const float ff_vorbis_floor1_inverse_db_table[256]; extern const float * const ff_vorbis_vwin[8]; extern const uint8_t ff_vorbis_channel_layout_offsets[8][8]; -extern const uint8_t ff_vorbis_encoding_channel_layout_offsets[8][8]; extern const uint64_t ff_vorbis_channel_layouts[9]; typedef struct vorbis_floor1_entry { diff --git a/libavcodec/vorbis_data.c b/libavcodec/vorbis_data.c index 063a075ce..fd7e291de 100644 --- a/libavcodec/vorbis_data.c +++ b/libavcodec/vorbis_data.c @@ -19,7 +19,8 @@ */ #include "libavutil/channel_layout.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" + #include "vorbis.h" const uint8_t ff_vorbis_channel_layout_offsets[8][8] = { @@ -33,17 +34,6 @@ const uint8_t ff_vorbis_channel_layout_offsets[8][8] = { { 0, 2, 1, 7, 5, 6, 3, 4 }, }; -const uint8_t ff_vorbis_encoding_channel_layout_offsets[8][8] = { - { 0 }, - { 0, 1 }, - { 0, 2, 1 }, - { 0, 1, 2, 3 }, - { 0, 2, 1, 3, 4 }, - { 0, 2, 1, 4, 5, 3 }, - { 0, 2, 1, 5, 6, 4, 3 }, - { 0, 2, 1, 6, 7, 4, 5, 3 }, -}; - const uint64_t ff_vorbis_channel_layouts[9] = { AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index be6d1b2d2..169df591b 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1890,7 +1890,7 @@ AVCodec ff_vorbis_decoder = { .close = vorbis_decode_close, .decode = vorbis_decode_frame, .flush = vorbis_decode_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .channel_layouts = ff_vorbis_channel_layouts, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index c79b57e12..57c6eb1ff 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -35,6 +35,7 @@ #include #include "libavutil/imgutils.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "get_bits.h" @@ -48,6 +49,10 @@ #include "vp3dsp.h" #include "xiph.h" +#define VP3_MV_VLC_BITS 6 +#define VP4_MV_VLC_BITS 6 +#define SUPERBLOCK_VLC_BITS 6 + #define FRAGMENT_PIXELS 8 // FIXME split things out into their own arrays @@ -155,6 +160,15 @@ typedef struct { #define MIN_DEQUANT_VAL 2 +typedef struct HuffEntry { + uint8_t len, sym; +} HuffEntry; + +typedef struct HuffTable { + HuffEntry entries[32]; + uint8_t nb_entries; +} HuffTable; + typedef struct Vp3DecodeContext { AVCodecContext *avctx; int theora, theora_tables, theora_header; @@ -257,11 +271,9 @@ typedef struct Vp3DecodeContext { int *nkf_coded_fragment_list; int num_kf_coded_fragment[3]; - VLC dc_vlc[16]; - VLC ac_vlc_1[16]; - VLC ac_vlc_2[16]; - VLC ac_vlc_3[16]; - VLC ac_vlc_4[16]; + /* The first 16 of the following VLCs are for the dc coefficients; + the others are four groups of 16 VLCs each for ac coefficients. */ + VLC coeff_vlc[5 * 16]; VLC superblock_run_length_vlc; /* version < 2 */ VLC fragment_run_length_vlc; /* version < 2 */ @@ -287,11 +299,7 @@ typedef struct Vp3DecodeContext { uint8_t *edge_emu_buffer; /* Huffman decode */ - int hti; - unsigned int hbits; - int entries; - int huff_code_size; - uint32_t huffman_table[80][32][2]; + HuffTable huffman_table[5 * 16]; uint8_t filter_limit_values[64]; DECLARE_ALIGNED(8, int, bounding_values_array)[256 + 2]; @@ -347,13 +355,8 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) av_frame_free(&s->last_frame.f); av_frame_free(&s->golden_frame.f); - for (i = 0; i < 16; i++) { - ff_free_vlc(&s->dc_vlc[i]); - ff_free_vlc(&s->ac_vlc_1[i]); - ff_free_vlc(&s->ac_vlc_2[i]); - ff_free_vlc(&s->ac_vlc_3[i]); - ff_free_vlc(&s->ac_vlc_4[i]); - } + for (i = 0; i < FF_ARRAY_ELEMS(s->coeff_vlc); i++) + ff_free_vlc(&s->coeff_vlc[i]); ff_free_vlc(&s->superblock_run_length_vlc); ff_free_vlc(&s->fragment_run_length_vlc); @@ -491,7 +494,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) bit ^= 1; current_run = get_vlc2(gb, s->superblock_run_length_vlc.table, - 6, 2) + 1; + SUPERBLOCK_VLC_BITS, 2); if (current_run == 34) current_run += get_bits(gb, 12); @@ -525,7 +528,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) bit ^= 1; current_run = get_vlc2(gb, s->superblock_run_length_vlc.table, - 6, 2) + 1; + SUPERBLOCK_VLC_BITS, 2); if (current_run == 34) current_run += get_bits(gb, 12); @@ -684,11 +687,6 @@ static int vp4_get_mb_count(Vp3DecodeContext *s, GetBitContext *gb) static int vp4_get_block_pattern(Vp3DecodeContext *s, GetBitContext *gb, int *next_block_pattern_table) { int v = get_vlc2(gb, s->block_pattern_vlc[*next_block_pattern_table].table, 3, 2); - if (v == -1) { - av_log(s->avctx, AV_LOG_ERROR, "Invalid block pattern\n"); - *next_block_pattern_table = 0; - return 0; - } *next_block_pattern_table = vp4_block_pattern_table_selector[v]; return v + 1; } @@ -892,7 +890,8 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) static int vp4_get_mv(Vp3DecodeContext *s, GetBitContext *gb, int axis, int last_motion) { - int v = get_vlc2(gb, s->vp4_mv_vlc[axis][vp4_mv_table_selector[FFABS(last_motion)]].table, 6, 2) - 31; + int v = get_vlc2(gb, s->vp4_mv_vlc[axis][vp4_mv_table_selector[FFABS(last_motion)]].table, + VP4_MV_VLC_BITS, 2); return last_motion < 0 ? -v : v; } @@ -949,8 +948,10 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) case MODE_INTER_PLUS_MV: /* all 6 fragments use the same motion vector */ if (coding_mode == 0) { - motion_x[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; - motion_y[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; + motion_x[0] = get_vlc2(gb, s->motion_vector_vlc.table, + VP3_MV_VLC_BITS, 2); + motion_y[0] = get_vlc2(gb, s->motion_vector_vlc.table, + VP3_MV_VLC_BITS, 2); } else if (coding_mode == 1) { motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)]; motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)]; @@ -979,8 +980,10 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) current_fragment = BLOCK_Y * s->fragment_width[0] + BLOCK_X; if (s->all_fragments[current_fragment].coding_method != MODE_COPY) { if (coding_mode == 0) { - motion_x[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; - motion_y[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; + motion_x[k] = get_vlc2(gb, s->motion_vector_vlc.table, + VP3_MV_VLC_BITS, 2); + motion_y[k] = get_vlc2(gb, s->motion_vector_vlc.table, + VP3_MV_VLC_BITS, 2); } else if (coding_mode == 1) { motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)]; motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)]; @@ -1111,7 +1114,8 @@ static int unpack_block_qpis(Vp3DecodeContext *s, GetBitContext *gb) else bit ^= 1; - run_length = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2) + 1; + run_length = get_vlc2(gb, s->superblock_run_length_vlc.table, + SUPERBLOCK_VLC_BITS, 2); if (run_length == 34) run_length += get_bits(gb, 12); blocks_decoded += run_length; @@ -1314,7 +1318,7 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) dc_c_table = get_bits(gb, 4); /* unpack the Y plane DC coefficients */ - residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0, + residual_eob_run = unpack_vlcs(s, gb, &s->coeff_vlc[dc_y_table], 0, 0, residual_eob_run); if (residual_eob_run < 0) return residual_eob_run; @@ -1325,11 +1329,11 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) reverse_dc_prediction(s, 0, s->fragment_width[0], s->fragment_height[0]); /* unpack the C plane DC coefficients */ - residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, + residual_eob_run = unpack_vlcs(s, gb, &s->coeff_vlc[dc_c_table], 0, 1, residual_eob_run); if (residual_eob_run < 0) return residual_eob_run; - residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, + residual_eob_run = unpack_vlcs(s, gb, &s->coeff_vlc[dc_c_table], 0, 2, residual_eob_run); if (residual_eob_run < 0) return residual_eob_run; @@ -1350,20 +1354,24 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) /* build tables of AC VLC tables */ for (i = 1; i <= 5; i++) { - y_tables[i] = &s->ac_vlc_1[ac_y_table]; - c_tables[i] = &s->ac_vlc_1[ac_c_table]; + /* AC VLC table group 1 */ + y_tables[i] = &s->coeff_vlc[ac_y_table + 16]; + c_tables[i] = &s->coeff_vlc[ac_c_table + 16]; } for (i = 6; i <= 14; i++) { - y_tables[i] = &s->ac_vlc_2[ac_y_table]; - c_tables[i] = &s->ac_vlc_2[ac_c_table]; + /* AC VLC table group 2 */ + y_tables[i] = &s->coeff_vlc[ac_y_table + 32]; + c_tables[i] = &s->coeff_vlc[ac_c_table + 32]; } for (i = 15; i <= 27; i++) { - y_tables[i] = &s->ac_vlc_3[ac_y_table]; - c_tables[i] = &s->ac_vlc_3[ac_c_table]; + /* AC VLC table group 3 */ + y_tables[i] = &s->coeff_vlc[ac_y_table + 48]; + c_tables[i] = &s->coeff_vlc[ac_c_table + 48]; } for (i = 28; i <= 63; i++) { - y_tables[i] = &s->ac_vlc_4[ac_y_table]; - c_tables[i] = &s->ac_vlc_4[ac_c_table]; + /* AC VLC table group 4 */ + y_tables[i] = &s->coeff_vlc[ac_y_table + 64]; + c_tables[i] = &s->coeff_vlc[ac_c_table + 64]; } /* decode all AC coefficients */ @@ -1542,23 +1550,28 @@ static int vp4_unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) /* build tables of DC/AC VLC tables */ - tables[0][0] = &s->dc_vlc[dc_y_table]; - tables[1][0] = &s->dc_vlc[dc_c_table]; + /* DC table group */ + tables[0][0] = &s->coeff_vlc[dc_y_table]; + tables[1][0] = &s->coeff_vlc[dc_c_table]; for (i = 1; i <= 5; i++) { - tables[0][i] = &s->ac_vlc_1[ac_y_table]; - tables[1][i] = &s->ac_vlc_1[ac_c_table]; + /* AC VLC table group 1 */ + tables[0][i] = &s->coeff_vlc[ac_y_table + 16]; + tables[1][i] = &s->coeff_vlc[ac_c_table + 16]; } for (i = 6; i <= 14; i++) { - tables[0][i] = &s->ac_vlc_2[ac_y_table]; - tables[1][i] = &s->ac_vlc_2[ac_c_table]; + /* AC VLC table group 2 */ + tables[0][i] = &s->coeff_vlc[ac_y_table + 32]; + tables[1][i] = &s->coeff_vlc[ac_c_table + 32]; } for (i = 15; i <= 27; i++) { - tables[0][i] = &s->ac_vlc_3[ac_y_table]; - tables[1][i] = &s->ac_vlc_3[ac_c_table]; + /* AC VLC table group 3 */ + tables[0][i] = &s->coeff_vlc[ac_y_table + 48]; + tables[1][i] = &s->coeff_vlc[ac_c_table + 48]; } for (i = 28; i <= 63; i++) { - tables[0][i] = &s->ac_vlc_4[ac_y_table]; - tables[1][i] = &s->ac_vlc_4[ac_c_table]; + /* AC VLC table group 4 */ + tables[0][i] = &s->coeff_vlc[ac_y_table + 64]; + tables[1][i] = &s->coeff_vlc[ac_c_table + 64]; } vp4_set_tokens_base(s); @@ -2287,7 +2300,6 @@ static av_cold int allocate_tables(AVCodecContext *avctx) !s->superblock_fragments || !s->macroblock_coding || !s->dc_pred_row || !s->motion_val[0] || !s->motion_val[1]) { - vp3_decode_end(avctx); return -1; } @@ -2302,12 +2314,8 @@ static av_cold int init_frames(Vp3DecodeContext *s) s->last_frame.f = av_frame_alloc(); s->golden_frame.f = av_frame_alloc(); - if (!s->current_frame.f || !s->last_frame.f || !s->golden_frame.f) { - av_frame_free(&s->current_frame.f); - av_frame_free(&s->last_frame.f); - av_frame_free(&s->golden_frame.f); + if (!s->current_frame.f || !s->last_frame.f || !s->golden_frame.f) return AVERROR(ENOMEM); - } return 0; } @@ -2417,131 +2425,84 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx) /* init VLC tables */ if (s->version < 2) { - for (i = 0; i < 16; i++) { - /* DC histograms */ - init_vlc(&s->dc_vlc[i], 11, 32, - &dc_bias[i][0][1], 4, 2, - &dc_bias[i][0][0], 4, 2, 0); - - /* group 1 AC histograms */ - init_vlc(&s->ac_vlc_1[i], 11, 32, - &ac_bias_0[i][0][1], 4, 2, - &ac_bias_0[i][0][0], 4, 2, 0); - - /* group 2 AC histograms */ - init_vlc(&s->ac_vlc_2[i], 11, 32, - &ac_bias_1[i][0][1], 4, 2, - &ac_bias_1[i][0][0], 4, 2, 0); - - /* group 3 AC histograms */ - init_vlc(&s->ac_vlc_3[i], 11, 32, - &ac_bias_2[i][0][1], 4, 2, - &ac_bias_2[i][0][0], 4, 2, 0); - - /* group 4 AC histograms */ - init_vlc(&s->ac_vlc_4[i], 11, 32, - &ac_bias_3[i][0][1], 4, 2, - &ac_bias_3[i][0][0], 4, 2, 0); + for (i = 0; i < FF_ARRAY_ELEMS(s->coeff_vlc); i++) { + ret = ff_init_vlc_from_lengths(&s->coeff_vlc[i], 11, 32, + &vp3_bias[i][0][1], 2, + &vp3_bias[i][0][0], 2, 1, + 0, 0, avctx); + if (ret < 0) + return ret; } #if CONFIG_VP4_DECODER } else { /* version >= 2 */ - for (i = 0; i < 16; i++) { - /* DC histograms */ - init_vlc(&s->dc_vlc[i], 11, 32, - &vp4_dc_bias[i][0][1], 4, 2, - &vp4_dc_bias[i][0][0], 4, 2, 0); - - /* group 1 AC histograms */ - init_vlc(&s->ac_vlc_1[i], 11, 32, - &vp4_ac_bias_0[i][0][1], 4, 2, - &vp4_ac_bias_0[i][0][0], 4, 2, 0); - - /* group 2 AC histograms */ - init_vlc(&s->ac_vlc_2[i], 11, 32, - &vp4_ac_bias_1[i][0][1], 4, 2, - &vp4_ac_bias_1[i][0][0], 4, 2, 0); - - /* group 3 AC histograms */ - init_vlc(&s->ac_vlc_3[i], 11, 32, - &vp4_ac_bias_2[i][0][1], 4, 2, - &vp4_ac_bias_2[i][0][0], 4, 2, 0); - - /* group 4 AC histograms */ - init_vlc(&s->ac_vlc_4[i], 11, 32, - &vp4_ac_bias_3[i][0][1], 4, 2, - &vp4_ac_bias_3[i][0][0], 4, 2, 0); + for (i = 0; i < FF_ARRAY_ELEMS(s->coeff_vlc); i++) { + ret = ff_init_vlc_from_lengths(&s->coeff_vlc[i], 11, 32, + &vp4_bias[i][0][1], 2, + &vp4_bias[i][0][0], 2, 1, + 0, 0, avctx); + if (ret < 0) + return ret; } #endif } } else { - for (i = 0; i < 16; i++) { - /* DC histograms */ - if (init_vlc(&s->dc_vlc[i], 11, 32, - &s->huffman_table[i][0][1], 8, 4, - &s->huffman_table[i][0][0], 8, 4, 0) < 0) - goto vlc_fail; + for (i = 0; i < FF_ARRAY_ELEMS(s->coeff_vlc); i++) { + const HuffTable *tab = &s->huffman_table[i]; - /* group 1 AC histograms */ - if (init_vlc(&s->ac_vlc_1[i], 11, 32, - &s->huffman_table[i + 16][0][1], 8, 4, - &s->huffman_table[i + 16][0][0], 8, 4, 0) < 0) - goto vlc_fail; - - /* group 2 AC histograms */ - if (init_vlc(&s->ac_vlc_2[i], 11, 32, - &s->huffman_table[i + 16 * 2][0][1], 8, 4, - &s->huffman_table[i + 16 * 2][0][0], 8, 4, 0) < 0) - goto vlc_fail; - - /* group 3 AC histograms */ - if (init_vlc(&s->ac_vlc_3[i], 11, 32, - &s->huffman_table[i + 16 * 3][0][1], 8, 4, - &s->huffman_table[i + 16 * 3][0][0], 8, 4, 0) < 0) - goto vlc_fail; - - /* group 4 AC histograms */ - if (init_vlc(&s->ac_vlc_4[i], 11, 32, - &s->huffman_table[i + 16 * 4][0][1], 8, 4, - &s->huffman_table[i + 16 * 4][0][0], 8, 4, 0) < 0) - goto vlc_fail; + ret = ff_init_vlc_from_lengths(&s->coeff_vlc[i], 11, tab->nb_entries, + &tab->entries[0].len, sizeof(*tab->entries), + &tab->entries[0].sym, sizeof(*tab->entries), 1, + 0, 0, avctx); + if (ret < 0) + return ret; } } - init_vlc(&s->superblock_run_length_vlc, 6, 34, - &superblock_run_length_vlc_table[0][1], 4, 2, - &superblock_run_length_vlc_table[0][0], 4, 2, 0); + ret = ff_init_vlc_from_lengths(&s->superblock_run_length_vlc, SUPERBLOCK_VLC_BITS, 34, + superblock_run_length_vlc_lens, 1, + NULL, 0, 0, 1, 0, avctx); + if (ret < 0) + return ret; - init_vlc(&s->fragment_run_length_vlc, 5, 30, - &fragment_run_length_vlc_table[0][1], 4, 2, - &fragment_run_length_vlc_table[0][0], 4, 2, 0); + ret = ff_init_vlc_from_lengths(&s->fragment_run_length_vlc, 5, 30, + fragment_run_length_vlc_len, 1, + NULL, 0, 0, 0, 0, avctx); + if (ret < 0) + return ret; - init_vlc(&s->mode_code_vlc, 3, 8, - &mode_code_vlc_table[0][1], 2, 1, - &mode_code_vlc_table[0][0], 2, 1, 0); + ret = ff_init_vlc_from_lengths(&s->mode_code_vlc, 3, 8, + mode_code_vlc_len, 1, + NULL, 0, 0, 0, 0, avctx); + if (ret < 0) + return ret; - init_vlc(&s->motion_vector_vlc, 6, 63, - &motion_vector_vlc_table[0][1], 2, 1, - &motion_vector_vlc_table[0][0], 2, 1, 0); + ret = ff_init_vlc_from_lengths(&s->motion_vector_vlc, VP3_MV_VLC_BITS, 63, + &motion_vector_vlc_table[0][1], 2, + &motion_vector_vlc_table[0][0], 2, 1, + -31, 0, avctx); + if (ret < 0) + return ret; #if CONFIG_VP4_DECODER for (j = 0; j < 2; j++) - for (i = 0; i < 7; i++) - init_vlc(&s->vp4_mv_vlc[j][i], 6, 63, - &vp4_mv_vlc[j][i][0][1], 4, 2, - &vp4_mv_vlc[j][i][0][0], 4, 2, 0); + for (i = 0; i < 7; i++) { + ret = ff_init_vlc_from_lengths(&s->vp4_mv_vlc[j][i], VP4_MV_VLC_BITS, 63, + &vp4_mv_vlc[j][i][0][1], 2, + &vp4_mv_vlc[j][i][0][0], 2, 1, -31, + 0, avctx); + if (ret < 0) + return ret; + } /* version >= 2 */ for (i = 0; i < 2; i++) - init_vlc(&s->block_pattern_vlc[i], 3, 14, - &vp4_block_pattern_vlc[i][0][1], 2, 1, - &vp4_block_pattern_vlc[i][0][0], 2, 1, 0); + if ((ret = init_vlc(&s->block_pattern_vlc[i], 3, 14, + &vp4_block_pattern_vlc[i][0][1], 2, 1, + &vp4_block_pattern_vlc[i][0][0], 2, 1, 0)) < 0) + return ret; #endif return allocate_tables(avctx); - -vlc_fail: - av_log(avctx, AV_LOG_FATAL, "Invalid huffman table\n"); - return -1; } /// Release and shuffle frames after decode finishes @@ -2873,36 +2834,30 @@ error: return ret; } -static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) +static int read_huffman_tree(HuffTable *huff, GetBitContext *gb, int length, + AVCodecContext *avctx) { - Vp3DecodeContext *s = avctx->priv_data; - if (get_bits1(gb)) { int token; - if (s->entries >= 32) { /* overflow */ + if (huff->nb_entries >= 32) { /* overflow */ av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n"); return -1; } token = get_bits(gb, 5); - ff_dlog(avctx, "hti %d hbits %x token %d entry : %d size %d\n", - s->hti, s->hbits, token, s->entries, s->huff_code_size); - s->huffman_table[s->hti][token][0] = s->hbits; - s->huffman_table[s->hti][token][1] = s->huff_code_size; - s->entries++; + ff_dlog(avctx, "code length %d, curr entry %d, token %d\n", + length, huff->nb_entries, token); + huff->entries[huff->nb_entries++] = (HuffEntry){ length, token }; } else { - if (s->huff_code_size >= 32) { /* overflow */ + /* The following bound follows from the fact that nb_entries <= 32. */ + if (length >= 31) { /* overflow */ av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n"); return -1; } - s->huff_code_size++; - s->hbits <<= 1; - if (read_huffman_tree(avctx, gb)) + length++; + if (read_huffman_tree(huff, gb, length, avctx)) return -1; - s->hbits |= 1; - if (read_huffman_tree(avctx, gb)) + if (read_huffman_tree(huff, gb, length, avctx)) return -1; - s->hbits >>= 1; - s->huff_code_size--; } return 0; } @@ -3030,7 +2985,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) { Vp3DecodeContext *s = avctx->priv_data; - int i, n, matrices, inter, plane; + int i, n, matrices, inter, plane, ret; if (!s->theora_header) return AVERROR_INVALIDDATA; @@ -3122,17 +3077,10 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) } /* Huffman tables */ - for (s->hti = 0; s->hti < 80; s->hti++) { - s->entries = 0; - s->huff_code_size = 1; - if (!get_bits1(gb)) { - s->hbits = 0; - if (read_huffman_tree(avctx, gb)) - return -1; - s->hbits = 1; - if (read_huffman_tree(avctx, gb)) - return -1; - } + for (int i = 0; i < FF_ARRAY_ELEMS(s->huffman_table); i++) { + s->huffman_table[i].nb_entries = 0; + if ((ret = read_huffman_tree(&s->huffman_table[i], gb, 0, avctx)) < 0) + return ret; } s->theora_tables = 1; @@ -3224,7 +3172,8 @@ AVCodec ff_theora_decoder = { AV_CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), - .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_ALLOCATE_PROGRESS, + .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_ALLOCATE_PROGRESS | + FF_CODEC_CAP_INIT_CLEANUP, }; #endif @@ -3241,7 +3190,7 @@ AVCodec ff_vp3_decoder = { AV_CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), - .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP, }; #if CONFIG_VP4_DECODER @@ -3258,6 +3207,6 @@ AVCodec ff_vp4_decoder = { AV_CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), - .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff --git a/libavcodec/vp3data.h b/libavcodec/vp3data.h index 3f24d5f7f..272af4e3a 100644 --- a/libavcodec/vp3data.h +++ b/libavcodec/vp3data.h @@ -95,95 +95,34 @@ static const uint8_t vp31_filter_limit_values[64] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static const uint16_t superblock_run_length_vlc_table[34][2] = { - { 0, 1 }, - - { 4, 3 }, { 5, 3 }, - - { 0xC, 4 }, { 0xD, 4 }, - - { 0x38, 6 }, { 0x39, 6 }, { 0x3A, 6 }, { 0x3B, 6 }, - - { 0xF0, 8 }, { 0xF1, 8 }, { 0xF2, 8 }, { 0xF3, 8 }, - { 0xF4, 8 }, { 0xF5, 8 }, { 0xF6, 8 }, { 0xF7, 8 }, - - { 0x3E0, 10 }, { 0x3E1, 10 }, { 0x3E2, 10 }, { 0x3E3, 10 }, - { 0x3E4, 10 }, { 0x3E5, 10 }, { 0x3E6, 10 }, { 0x3E7, 10 }, - { 0x3E8, 10 }, { 0x3E9, 10 }, { 0x3EA, 10 }, { 0x3EB, 10 }, - { 0x3EC, 10 }, { 0x3ED, 10 }, { 0x3EE, 10 }, { 0x3EF, 10 }, - - { 0x3F, 6 } /* this last VLC is a special case for reading 12 more - * bits from stream and adding the value 34 */ +static const uint8_t superblock_run_length_vlc_lens[34] = { + 1, 3, 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, + 6, /* This last value is a special case for reading 12 more + * bits from the stream and adding the value 34. */ }; -static const uint16_t fragment_run_length_vlc_table[30][2] = { - /* 1 -> 2 */ - { 0x0, 2 }, { 0x1, 2 }, - - /* 3 -> 4 */ - { 0x4, 3 }, { 0x5, 3 }, - - /* 5 -> 6 */ - { 0xC, 4 }, { 0xD, 4 }, - - /* 7 -> 10 */ - { 0x38, 6 }, { 0x39, 6 }, - { 0x3A, 6 }, { 0x3B, 6 }, - - /* 11 -> 14 */ - { 0x78, 7 }, { 0x79, 7 }, - { 0x7A, 7 }, { 0x7B, 7 }, - - /* 15 -> 30 */ - { 0x1F0, 9 }, { 0x1F1, 9 }, { 0x1F2, 9 }, { 0x1F3, 9 }, - { 0x1F4, 9 }, { 0x1F5, 9 }, { 0x1F6, 9 }, { 0x1F7, 9 }, - { 0x1F8, 9 }, { 0x1F9, 9 }, { 0x1FA, 9 }, { 0x1FB, 9 }, - { 0x1FC, 9 }, { 0x1FD, 9 }, { 0x1FE, 9 }, { 0x1FF, 9 } +static const uint8_t fragment_run_length_vlc_len[30] = { + 2, 2, 3, 3, 4, 4, 6, 6, 6, 6, 7, 7, 7, 7, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, }; -static const uint8_t mode_code_vlc_table[8][2] = { - { 0, 1 }, { 2, 2 }, - { 6, 3 }, { 14, 4 }, - { 30, 5 }, { 62, 6 }, - { 126, 7 }, { 127, 7 } +static const uint8_t mode_code_vlc_len[8] = { + 1, 2, 3, 4, 5, 6, 7, 7, }; static const uint8_t motion_vector_vlc_table[63][2] = { - { 0, 3 }, - { 1, 3 }, - { 2, 3 }, - - { 6, 4 }, { 7, 4 }, - - { 8, 4 }, { 9, 4 }, - - { 40, 6 }, { 41, 6 }, { 42, 6 }, { 43, 6 }, - { 44, 6 }, { 45, 6 }, { 46, 6 }, { 47, 6 }, - - { 96, 7 }, { 97, 7 }, { 98, 7 }, { 99, 7 }, - { 100, 7 }, { 101, 7 }, { 102, 7 }, { 103, 7 }, - { 104, 7 }, { 105, 7 }, { 106, 7 }, { 107, 7 }, - { 108, 7 }, { 109, 7 }, { 110, 7 }, { 111, 7 }, - - { 0xE0, 8 }, { 0xE1, 8 }, { 0xE2, 8 }, { 0xE3, 8 }, - { 0xE4, 8 }, { 0xE5, 8 }, { 0xE6, 8 }, { 0xE7, 8 }, - { 0xE8, 8 }, { 0xE9, 8 }, { 0xEA, 8 }, { 0xEB, 8 }, - { 0xEC, 8 }, { 0xED, 8 }, { 0xEE, 8 }, { 0xEF, 8 }, - - { 0xF0, 8 }, { 0xF1, 8 }, { 0xF2, 8 }, { 0xF3, 8 }, - { 0xF4, 8 }, { 0xF5, 8 }, { 0xF6, 8 }, { 0xF7, 8 }, - { 0xF8, 8 }, { 0xF9, 8 }, { 0xFA, 8 }, { 0xFB, 8 }, - { 0xFC, 8 }, { 0xFD, 8 }, { 0xFE, 8 }, { 0xFF, 8 } -}; - -static const int8_t motion_vector_table[63] = { - 0, 1, -1, - 2, -2, - 3, -3, - 4, -4, 5, -5, 6, -6, 7, -7, - 8, -8, 9, -9, 10, -10, 11, -11, 12, -12, 13, -13, 14, -14, 15, -15, - 16, -16, 17, -17, 18, -18, 19, -19, 20, -20, 21, -21, 22, -22, 23, -23, - 24, -24, 25, -25, 26, -26, 27, -27, 28, -28, 29, -29, 30, -30, 31, -31 + { 31, 3 }, { 32, 3 }, { 30, 3 }, { 33, 4 }, { 29, 4 }, { 34, 4 }, + { 28, 4 }, { 35, 6 }, { 27, 6 }, { 36, 6 }, { 26, 6 }, { 37, 6 }, + { 25, 6 }, { 38, 6 }, { 24, 6 }, { 39, 7 }, { 23, 7 }, { 40, 7 }, + { 22, 7 }, { 41, 7 }, { 21, 7 }, { 42, 7 }, { 20, 7 }, { 43, 7 }, + { 19, 7 }, { 44, 7 }, { 18, 7 }, { 45, 7 }, { 17, 7 }, { 46, 7 }, + { 16, 7 }, { 47, 8 }, { 15, 8 }, { 48, 8 }, { 14, 8 }, { 49, 8 }, + { 13, 8 }, { 50, 8 }, { 12, 8 }, { 51, 8 }, { 11, 8 }, { 52, 8 }, + { 10, 8 }, { 53, 8 }, { 9, 8 }, { 54, 8 }, { 8, 8 }, { 55, 8 }, + { 7, 8 }, { 56, 8 }, { 6, 8 }, { 57, 8 }, { 5, 8 }, { 58, 8 }, + { 4, 8 }, { 59, 8 }, { 3, 8 }, { 60, 8 }, { 2, 8 }, { 61, 8 }, + { 1, 8 }, { 62, 8 }, { 0, 8 }, }; static const int8_t fixed_motion_vector_table[64] = { @@ -240,8 +179,7 @@ static const int16_t coeff_table_token_15[2] = { 5, -5 }; static const int16_t coeff_table_token_16[2] = { 6, -6 }; static const int16_t coeff_table_token_23_24_25_26_27_28_29[2] = { 1, -1 }; -static const int16_t coeff_table_token_30[4] = { 2, 3, -2, -3 }; -static const int16_t coeff_table_token_31[4] = { 2, 3, -2, -3 }; +static const int16_t coeff_table_token_30_31[4] = { 2, 3, -2, -3 }; static const int16_t coeff_table_token_17[4] = { 7, 8, -7, -8 @@ -438,2743 +376,651 @@ static const int16_t *const coeff_tables[32] = { coeff_table_token_23_24_25_26_27_28_29, coeff_table_token_23_24_25_26_27_28_29, coeff_table_token_23_24_25_26_27_28_29, - coeff_table_token_30, - coeff_table_token_31 + coeff_table_token_30_31, + coeff_table_token_30_31 }; -static const uint16_t dc_bias[16][32][2] = { +static const uint8_t vp3_bias[5 * 16][32][2] = { { /* DC bias table 0 */ - { 0x2D, 6 }, - { 0x26, 7 }, - { 0x166, 9 }, - { 0x4E, 8 }, - { 0x2CE, 10 }, - { 0x59E, 11 }, - { 0x27D, 11 }, - { 0x8, 5 }, - { 0x4F9, 12 }, - { 0xF, 4 }, - { 0xE, 4 }, - { 0x1B, 5 }, - { 0x6, 4 }, - { 0x8, 4 }, - { 0x5, 4 }, - { 0x1A, 5 }, - { 0x15, 5 }, - { 0x7, 4 }, - { 0xC, 4 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x9, 4 }, - { 0x17, 5 }, - { 0x29, 6 }, - { 0x28, 6 }, - { 0xB2, 8 }, - { 0x4F8, 12 }, - { 0x59F, 11 }, - { 0x9E, 9 }, - { 0x13F, 10 }, - { 0x12, 6 }, - { 0x58, 7 } + { 20, 3 }, { 19, 3 }, { 7, 5 }, { 30, 6 }, { 1, 7 }, { 3, 8 }, + { 28, 9 }, { 26, 12 }, { 8, 12 }, { 6, 11 }, { 29, 10 }, { 14, 4 }, + { 12, 4 }, { 17, 4 }, { 13, 4 }, { 21, 4 }, { 24, 6 }, { 23, 6 }, + { 16, 5 }, { 31, 7 }, { 25, 8 }, { 2, 9 }, { 4, 10 }, { 5, 11 }, + { 27, 11 }, { 0, 6 }, { 22, 5 }, { 18, 4 }, { 15, 5 }, { 11, 5 }, + { 10, 4 }, { 9, 4 }, }, { /* DC bias table 1 */ - { 0x10, 5 }, - { 0x47, 7 }, - { 0x1FF, 9 }, - { 0x8C, 8 }, - { 0x3FC, 10 }, - { 0x46A, 11 }, - { 0x469, 11 }, - { 0x22, 6 }, - { 0x11A1, 13 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0x4, 4 }, - { 0x5, 4 }, - { 0x9, 4 }, - { 0x6, 4 }, - { 0x1E, 5 }, - { 0x16, 5 }, - { 0x7, 4 }, - { 0xC, 4 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xA, 4 }, - { 0x17, 5 }, - { 0x7D, 7 }, - { 0x7E, 7 }, - { 0x11B, 9 }, - { 0x8D1, 12 }, - { 0x3FD, 10 }, - { 0x46B, 11 }, - { 0x11A0, 13 }, - { 0x7C, 7 }, - { 0xFE, 8 } + { 20, 3 }, { 19, 3 }, { 11, 4 }, { 12, 4 }, { 14, 4 }, { 17, 4 }, + { 0, 5 }, { 7, 6 }, { 3, 8 }, { 29, 13 }, { 8, 13 }, { 26, 12 }, + { 6, 11 }, { 5, 11 }, { 28, 11 }, { 25, 9 }, { 1, 7 }, { 13, 4 }, + { 21, 4 }, { 16, 5 }, { 22, 5 }, { 18, 4 }, { 10, 4 }, { 9, 4 }, + { 15, 5 }, { 30, 7 }, { 23, 7 }, { 24, 7 }, { 31, 8 }, { 4, 10 }, + { 27, 10 }, { 2, 9 }, }, { /* DC bias table 2 */ - { 0x16, 5 }, - { 0x20, 6 }, - { 0x86, 8 }, - { 0x87, 8 }, - { 0x367, 10 }, - { 0x6CC, 11 }, - { 0x6CB, 11 }, - { 0x6E, 7 }, - { 0x366D, 14 }, - { 0xF, 4 }, - { 0xE, 4 }, - { 0x4, 4 }, - { 0x5, 4 }, - { 0xA, 4 }, - { 0x6, 4 }, - { 0x1A, 5 }, - { 0x11, 5 }, - { 0x7, 4 }, - { 0xC, 4 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x9, 4 }, - { 0x17, 5 }, - { 0x6F, 7 }, - { 0x6D, 7 }, - { 0x364, 10 }, - { 0xD9A, 12 }, - { 0x6CA, 11 }, - { 0x1B37, 13 }, - { 0x366C, 14 }, - { 0x42, 7 }, - { 0xD8, 8 } + { 20, 3 }, { 19, 3 }, { 11, 4 }, { 12, 4 }, { 14, 4 }, { 17, 4 }, + { 1, 6 }, { 30, 7 }, { 2, 8 }, { 3, 8 }, { 16, 5 }, { 21, 4 }, + { 13, 4 }, { 0, 5 }, { 22, 5 }, { 18, 4 }, { 15, 5 }, { 31, 8 }, + { 25, 10 }, { 27, 11 }, { 6, 11 }, { 5, 11 }, { 26, 12 }, { 29, 14 }, + { 8, 14 }, { 28, 13 }, { 4, 10 }, { 24, 7 }, { 7, 7 }, { 23, 7 }, + { 10, 4 }, { 9, 4 }, }, { /* DC bias table 3 */ - { 0x0, 4 }, - { 0x2D, 6 }, - { 0xF7, 8 }, - { 0x58, 7 }, - { 0x167, 9 }, - { 0x2CB, 10 }, - { 0x2CA, 10 }, - { 0xE, 6 }, - { 0x1661, 13 }, - { 0x3, 3 }, - { 0x2, 3 }, - { 0x8, 4 }, - { 0x9, 4 }, - { 0xD, 4 }, - { 0x2, 4 }, - { 0x1F, 5 }, - { 0x17, 5 }, - { 0x1, 4 }, - { 0xC, 4 }, - { 0xE, 4 }, - { 0xA, 4 }, - { 0x6, 5 }, - { 0x78, 7 }, - { 0xF, 6 }, - { 0x7A, 7 }, - { 0x164, 9 }, - { 0x599, 11 }, - { 0x2CD, 10 }, - { 0xB31, 12 }, - { 0x1660, 13 }, - { 0x79, 7 }, - { 0xF6, 8 } + { 0, 4 }, { 17, 4 }, { 14, 4 }, { 21, 5 }, { 7, 6 }, { 23, 6 }, + { 10, 3 }, { 9, 3 }, { 11, 4 }, { 12, 4 }, { 20, 4 }, { 3, 7 }, + { 25, 9 }, { 6, 10 }, { 5, 10 }, { 29, 13 }, { 8, 13 }, { 28, 12 }, + { 26, 11 }, { 27, 10 }, { 4, 9 }, { 1, 6 }, { 16, 5 }, { 18, 4 }, + { 13, 4 }, { 19, 4 }, { 22, 7 }, { 30, 7 }, { 24, 7 }, { 31, 8 }, + { 2, 8 }, { 15, 5 }, }, { /* DC bias table 4 */ - { 0x3, 4 }, - { 0x3C, 6 }, - { 0xF, 7 }, - { 0x7A, 7 }, - { 0x1D, 8 }, - { 0x20, 9 }, - { 0x72, 10 }, - { 0x6, 6 }, - { 0x399, 13 }, - { 0x4, 3 }, - { 0x5, 3 }, - { 0x5, 4 }, - { 0x6, 4 }, - { 0xE, 4 }, - { 0x4, 4 }, - { 0x0, 4 }, - { 0x19, 5 }, - { 0x2, 4 }, - { 0xD, 4 }, - { 0x7, 4 }, - { 0x1F, 5 }, - { 0x30, 6 }, - { 0x11, 8 }, - { 0x31, 6 }, - { 0x5, 6 }, - { 0x21, 9 }, - { 0xE7, 11 }, - { 0x38, 9 }, - { 0x1CD, 12 }, - { 0x398, 13 }, - { 0x7B, 7 }, - { 0x9, 7 } + { 15, 4 }, { 5, 9 }, { 25, 9 }, { 22, 8 }, { 31, 7 }, { 24, 6 }, + { 7, 6 }, { 27, 9 }, { 6, 10 }, { 29, 13 }, { 8, 13 }, { 28, 12 }, + { 26, 11 }, { 4, 8 }, { 2, 7 }, { 17, 4 }, { 0, 4 }, { 14, 4 }, + { 11, 4 }, { 12, 4 }, { 19, 4 }, { 9, 3 }, { 10, 3 }, { 21, 6 }, + { 23, 6 }, { 16, 5 }, { 18, 4 }, { 13, 4 }, { 1, 6 }, { 3, 7 }, + { 30, 7 }, { 20, 5 }, }, { /* DC bias table 5 */ - { 0x9, 4 }, - { 0x2, 5 }, - { 0x74, 7 }, - { 0x7, 6 }, - { 0xEC, 8 }, - { 0xD1, 9 }, - { 0x1A6, 10 }, - { 0x6, 6 }, - { 0xD21, 13 }, - { 0x5, 3 }, - { 0x6, 3 }, - { 0x8, 4 }, - { 0x7, 4 }, - { 0xF, 4 }, - { 0x4, 4 }, - { 0x0, 4 }, - { 0x1C, 5 }, - { 0x2, 4 }, - { 0x5, 4 }, - { 0x3, 4 }, - { 0xC, 5 }, - { 0x35, 7 }, - { 0x1A7, 10 }, - { 0x1B, 6 }, - { 0x77, 7 }, - { 0x1A5, 10 }, - { 0x349, 11 }, - { 0xD0, 9 }, - { 0x691, 12 }, - { 0xD20, 13 }, - { 0x75, 7 }, - { 0xED, 8 } + { 15, 4 }, { 1, 5 }, { 7, 6 }, { 3, 6 }, { 17, 4 }, { 19, 4 }, + { 14, 4 }, { 18, 4 }, { 20, 5 }, { 27, 9 }, { 5, 9 }, { 29, 13 }, + { 8, 13 }, { 28, 12 }, { 26, 11 }, { 25, 10 }, { 6, 10 }, { 22, 10 }, + { 21, 7 }, { 23, 6 }, { 12, 4 }, { 11, 4 }, { 0, 4 }, { 9, 3 }, + { 10, 3 }, { 16, 5 }, { 2, 7 }, { 30, 7 }, { 4, 8 }, { 31, 8 }, + { 24, 7 }, { 13, 4 }, }, { /* DC bias table 6 */ - { 0xA, 4 }, - { 0xC, 5 }, - { 0x12, 6 }, - { 0x1B, 6 }, - { 0xB7, 8 }, - { 0x16C, 9 }, - { 0x99, 9 }, - { 0x5A, 7 }, - { 0x16D8, 13 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x0, 3 }, - { 0x5, 4 }, - { 0x17, 5 }, - { 0xE, 5 }, - { 0x2, 4 }, - { 0x3, 4 }, - { 0xF, 5 }, - { 0x1A, 6 }, - { 0x4D, 8 }, - { 0x2DB3, 14 }, - { 0x2C, 6 }, - { 0x11, 6 }, - { 0x2DA, 10 }, - { 0x5B7, 11 }, - { 0x98, 9 }, - { 0xB6D, 12 }, - { 0x2DB2, 14 }, - { 0x10, 6 }, - { 0x27, 7 } + { 13, 3 }, { 17, 4 }, { 18, 4 }, { 30, 6 }, { 24, 6 }, { 2, 6 }, + { 27, 9 }, { 6, 9 }, { 21, 8 }, { 31, 7 }, { 14, 4 }, { 1, 5 }, + { 20, 6 }, { 3, 6 }, { 16, 5 }, { 19, 5 }, { 12, 4 }, { 11, 4 }, + { 0, 4 }, { 23, 6 }, { 7, 7 }, { 5, 9 }, { 25, 10 }, { 8, 13 }, + { 29, 14 }, { 22, 14 }, { 28, 12 }, { 26, 11 }, { 4, 8 }, { 15, 5 }, + { 10, 3 }, { 9, 3 }, }, { /* DC bias table 7 */ - { 0xD, 4 }, - { 0xF, 5 }, - { 0x1D, 6 }, - { 0x8, 5 }, - { 0x51, 7 }, - { 0x56, 8 }, - { 0xAF, 9 }, - { 0x2A, 7 }, - { 0x148A, 13 }, - { 0x7, 3 }, - { 0x0, 2 }, - { 0x8, 4 }, - { 0x9, 4 }, - { 0xC, 4 }, - { 0x6, 4 }, - { 0x17, 5 }, - { 0xB, 5 }, - { 0x16, 5 }, - { 0x15, 5 }, - { 0x9, 5 }, - { 0x50, 7 }, - { 0xAE, 9 }, - { 0x2917, 14 }, - { 0x1C, 6 }, - { 0x14, 6 }, - { 0x290, 10 }, - { 0x523, 11 }, - { 0x149, 9 }, - { 0xA44, 12 }, - { 0x2916, 14 }, - { 0x53, 7 }, - { 0xA5, 8 } + { 10, 2 }, { 3, 5 }, { 19, 5 }, { 24, 6 }, { 7, 7 }, { 5, 8 }, + { 21, 9 }, { 6, 9 }, { 16, 5 }, { 14, 4 }, { 23, 6 }, { 2, 6 }, + { 1, 5 }, { 11, 4 }, { 12, 4 }, { 20, 7 }, { 4, 7 }, { 25, 10 }, + { 28, 12 }, { 8, 13 }, { 29, 14 }, { 22, 14 }, { 26, 11 }, { 27, 9 }, + { 31, 8 }, { 30, 7 }, { 18, 5 }, { 17, 5 }, { 15, 5 }, { 13, 4 }, + { 0, 4 }, { 9, 3 }, }, { /* DC bias table 8 */ - { 0x1, 4 }, - { 0x1D, 6 }, - { 0xF5, 8 }, - { 0xF4, 8 }, - { 0x24D, 10 }, - { 0x499, 11 }, - { 0x498, 11 }, - { 0x1, 5 }, - { 0x21, 6 }, - { 0x6, 3 }, - { 0x5, 3 }, - { 0x6, 4 }, - { 0x5, 4 }, - { 0x2, 4 }, - { 0x7, 5 }, - { 0x25, 6 }, - { 0x7B, 7 }, - { 0x1C, 6 }, - { 0x20, 6 }, - { 0xD, 6 }, - { 0x48, 7 }, - { 0x92, 8 }, - { 0x127, 9 }, - { 0xE, 4 }, - { 0x4, 4 }, - { 0x11, 5 }, - { 0xC, 6 }, - { 0x3C, 6 }, - { 0xF, 5 }, - { 0x0, 5 }, - { 0x1F, 5 }, - { 0x13, 5 } + { 29, 5 }, { 7, 5 }, { 0, 4 }, { 13, 4 }, { 26, 6 }, { 19, 6 }, + { 14, 5 }, { 24, 4 }, { 12, 4 }, { 11, 4 }, { 17, 6 }, { 1, 6 }, + { 28, 5 }, { 18, 6 }, { 8, 6 }, { 25, 5 }, { 20, 7 }, { 21, 8 }, + { 6, 11 }, { 5, 11 }, { 4, 10 }, { 22, 9 }, { 15, 6 }, { 31, 5 }, + { 10, 3 }, { 9, 3 }, { 23, 4 }, { 27, 6 }, { 3, 8 }, { 2, 8 }, + { 16, 7 }, { 30, 5 }, }, { /* DC bias table 9 */ - { 0x5, 4 }, - { 0x3C, 6 }, - { 0x40, 7 }, - { 0xD, 7 }, - { 0x31, 9 }, - { 0x61, 10 }, - { 0x60, 10 }, - { 0x2, 5 }, - { 0xF5, 8 }, - { 0x6, 3 }, - { 0x5, 3 }, - { 0x7, 4 }, - { 0x6, 4 }, - { 0x2, 4 }, - { 0x9, 5 }, - { 0x25, 6 }, - { 0x7, 6 }, - { 0x21, 6 }, - { 0x24, 6 }, - { 0x10, 6 }, - { 0x41, 7 }, - { 0xF4, 8 }, - { 0x19, 8 }, - { 0xE, 4 }, - { 0x3, 4 }, - { 0x11, 5 }, - { 0x11, 6 }, - { 0x3F, 6 }, - { 0x3E, 6 }, - { 0x7B, 7 }, - { 0x0, 4 }, - { 0x13, 5 } + { 30, 4 }, { 7, 5 }, { 6, 10 }, { 5, 10 }, { 4, 9 }, { 22, 8 }, + { 3, 7 }, { 16, 6 }, { 13, 4 }, { 24, 4 }, { 19, 6 }, { 26, 6 }, + { 14, 5 }, { 0, 4 }, { 12, 4 }, { 11, 4 }, { 2, 7 }, { 20, 7 }, + { 17, 6 }, { 25, 5 }, { 18, 6 }, { 15, 6 }, { 31, 5 }, { 10, 3 }, + { 9, 3 }, { 23, 4 }, { 1, 6 }, { 21, 8 }, { 8, 8 }, { 29, 7 }, + { 28, 6 }, { 27, 6 }, }, { /* DC bias table 10 */ - { 0xA, 4 }, - { 0x7, 5 }, - { 0x1, 6 }, - { 0x9, 6 }, - { 0x131, 9 }, - { 0x261, 10 }, - { 0x260, 10 }, - { 0x15, 6 }, - { 0x1, 7 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x8, 4 }, - { 0x7, 4 }, - { 0x6, 4 }, - { 0x12, 5 }, - { 0x2F, 6 }, - { 0x14, 6 }, - { 0x27, 6 }, - { 0x2D, 6 }, - { 0x16, 6 }, - { 0x4D, 7 }, - { 0x99, 8 }, - { 0x0, 7 }, - { 0x4, 4 }, - { 0x1, 4 }, - { 0x5, 5 }, - { 0x17, 6 }, - { 0x2E, 6 }, - { 0x2C, 6 }, - { 0x8, 6 }, - { 0x6, 5 }, - { 0x1, 5 } + { 22, 7 }, { 8, 7 }, { 2, 6 }, { 31, 5 }, { 24, 4 }, { 29, 6 }, + { 3, 6 }, { 25, 5 }, { 30, 5 }, { 1, 5 }, { 23, 4 }, { 16, 6 }, + { 7, 6 }, { 19, 6 }, { 26, 6 }, { 13, 4 }, { 12, 4 }, { 11, 4 }, + { 14, 5 }, { 6, 10 }, { 5, 10 }, { 4, 9 }, { 21, 8 }, { 20, 7 }, + { 17, 6 }, { 0, 4 }, { 28, 6 }, { 18, 6 }, { 27, 6 }, { 15, 6 }, + { 10, 3 }, { 9, 3 }, }, { /* DC bias table 11 */ - { 0x0, 3 }, - { 0xE, 5 }, - { 0x17, 6 }, - { 0x2A, 6 }, - { 0x10, 7 }, - { 0xF9, 10 }, - { 0xF8, 10 }, - { 0x1E, 7 }, - { 0x3F, 8 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x6, 4 }, - { 0xF, 5 }, - { 0x5, 5 }, - { 0x16, 6 }, - { 0x29, 6 }, - { 0x2B, 6 }, - { 0x15, 6 }, - { 0x50, 7 }, - { 0x11, 7 }, - { 0x7D, 9 }, - { 0x4, 4 }, - { 0x17, 5 }, - { 0x6, 5 }, - { 0x14, 6 }, - { 0x2C, 6 }, - { 0x2D, 6 }, - { 0xE, 6 }, - { 0x9, 6 }, - { 0x51, 7 } + { 0, 3 }, { 4, 7 }, { 21, 7 }, { 30, 6 }, { 15, 5 }, { 25, 5 }, + { 29, 6 }, { 7, 7 }, { 6, 10 }, { 5, 10 }, { 22, 9 }, { 8, 8 }, + { 23, 4 }, { 26, 6 }, { 19, 6 }, { 16, 6 }, { 2, 6 }, { 13, 4 }, + { 1, 5 }, { 14, 5 }, { 12, 4 }, { 11, 4 }, { 20, 7 }, { 31, 7 }, + { 17, 6 }, { 3, 6 }, { 18, 6 }, { 27, 6 }, { 28, 6 }, { 24, 5 }, + { 10, 3 }, { 9, 3 }, }, { /* DC bias table 12 */ - { 0x2, 3 }, - { 0x18, 5 }, - { 0x2F, 6 }, - { 0xD, 5 }, - { 0x53, 7 }, - { 0x295, 10 }, - { 0x294, 10 }, - { 0xA4, 8 }, - { 0x7C, 8 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x1B, 5 }, - { 0xC, 5 }, - { 0x28, 6 }, - { 0x6A, 7 }, - { 0x1E, 6 }, - { 0x1D, 6 }, - { 0x69, 7 }, - { 0xD7, 8 }, - { 0x7D, 8 }, - { 0x14B, 9 }, - { 0x19, 5 }, - { 0x16, 5 }, - { 0x2E, 6 }, - { 0x1C, 6 }, - { 0x2B, 6 }, - { 0x2A, 6 }, - { 0x68, 7 }, - { 0x3F, 7 }, - { 0xD6, 8 } + { 9, 2 }, { 0, 3 }, { 14, 5 }, { 3, 5 }, { 26, 6 }, { 18, 6 }, + { 17, 6 }, { 8, 8 }, { 21, 8 }, { 30, 7 }, { 12, 4 }, { 11, 4 }, + { 15, 6 }, { 7, 8 }, { 6, 10 }, { 5, 10 }, { 22, 9 }, { 4, 7 }, + { 28, 6 }, { 27, 6 }, { 24, 5 }, { 25, 6 }, { 2, 6 }, { 1, 5 }, + { 23, 5 }, { 29, 7 }, { 19, 7 }, { 16, 7 }, { 31, 8 }, { 20, 8 }, + { 13, 5 }, { 10, 3 }, }, { /* DC bias table 13 */ - { 0x2, 3 }, - { 0x1B, 5 }, - { 0xC, 5 }, - { 0x18, 5 }, - { 0x29, 6 }, - { 0x7F, 8 }, - { 0x2F0, 10 }, - { 0x198, 9 }, - { 0x179, 9 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x1A, 5 }, - { 0xD, 5 }, - { 0x2A, 6 }, - { 0x64, 7 }, - { 0x1E, 6 }, - { 0x67, 7 }, - { 0x5F, 7 }, - { 0xCD, 8 }, - { 0x7E, 8 }, - { 0x2F1, 10 }, - { 0x16, 5 }, - { 0xE, 5 }, - { 0x2E, 6 }, - { 0x65, 7 }, - { 0x2B, 6 }, - { 0x28, 6 }, - { 0x3E, 7 }, - { 0xBD, 8 }, - { 0x199, 9 } + { 9, 2 }, { 0, 3 }, { 2, 5 }, { 14, 5 }, { 24, 5 }, { 17, 6 }, + { 29, 7 }, { 21, 8 }, { 5, 8 }, { 12, 4 }, { 11, 4 }, { 28, 6 }, + { 4, 6 }, { 15, 6 }, { 27, 6 }, { 23, 5 }, { 25, 6 }, { 6, 10 }, + { 22, 10 }, { 8, 9 }, { 30, 8 }, { 19, 7 }, { 3, 5 }, { 16, 7 }, + { 26, 7 }, { 7, 9 }, { 31, 9 }, { 20, 8 }, { 18, 7 }, { 13, 5 }, + { 1, 5 }, { 10, 3 }, }, { /* DC bias table 14 */ - { 0x2, 3 }, - { 0x7, 4 }, - { 0x16, 5 }, - { 0x6, 4 }, - { 0x36, 6 }, - { 0x5C, 7 }, - { 0x15D, 9 }, - { 0x15C, 9 }, - { 0x2BF, 10 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x18, 5 }, - { 0x34, 6 }, - { 0x2A, 6 }, - { 0x5E, 7 }, - { 0x6A, 7 }, - { 0x64, 7 }, - { 0x5D, 7 }, - { 0xCB, 8 }, - { 0xAD, 8 }, - { 0x2BE, 10 }, - { 0x14, 5 }, - { 0x33, 6 }, - { 0x6E, 7 }, - { 0x5F, 7 }, - { 0x6F, 7 }, - { 0x6B, 7 }, - { 0xCA, 8 }, - { 0xAC, 8 }, - { 0x15E, 9 } + { 9, 2 }, { 0, 3 }, { 3, 4 }, { 1, 4 }, { 12, 4 }, { 11, 4 }, + { 23, 5 }, { 15, 6 }, { 30, 8 }, { 21, 8 }, { 7, 9 }, { 6, 9 }, + { 31, 9 }, { 22, 10 }, { 8, 10 }, { 2, 5 }, { 5, 7 }, { 19, 7 }, + { 16, 7 }, { 26, 7 }, { 13, 5 }, { 18, 7 }, { 29, 8 }, { 20, 8 }, + { 24, 6 }, { 14, 6 }, { 17, 7 }, { 28, 7 }, { 4, 6 }, { 25, 7 }, + { 27, 7 }, { 10, 3 }, }, { /* DC bias table 15 */ - { 0xF, 4 }, - { 0x1D, 5 }, - { 0x18, 5 }, - { 0xB, 4 }, - { 0x19, 5 }, - { 0x29, 6 }, - { 0xD6, 8 }, - { 0x551, 11 }, - { 0xAA1, 12 }, - { 0x1, 2 }, - { 0x0, 2 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x1B, 5 }, - { 0x38, 6 }, - { 0x28, 6 }, - { 0x57, 7 }, - { 0x6A, 7 }, - { 0x68, 7 }, - { 0x56, 7 }, - { 0xE5, 8 }, - { 0x155, 9 }, - { 0xAA0, 12 }, - { 0x73, 7 }, - { 0x69, 7 }, - { 0xD7, 8 }, - { 0xAB, 8 }, - { 0xE4, 8 }, - { 0xA9, 8 }, - { 0x151, 9 }, - { 0x150, 9 }, - { 0x2A9, 10 } - } -}; - -static const uint16_t ac_bias_0[16][32][2] = { + { 10, 2 }, { 9, 2 }, { 12, 4 }, { 11, 4 }, { 15, 6 }, { 5, 6 }, + { 30, 9 }, { 29, 9 }, { 28, 8 }, { 22, 12 }, { 8, 12 }, { 7, 11 }, + { 31, 10 }, { 21, 9 }, { 26, 8 }, { 19, 7 }, { 16, 7 }, { 3, 4 }, + { 2, 5 }, { 4, 5 }, { 18, 7 }, { 24, 7 }, { 17, 7 }, { 6, 8 }, + { 25, 8 }, { 13, 5 }, { 14, 6 }, { 27, 8 }, { 20, 8 }, { 23, 7 }, + { 1, 5 }, { 0, 4 }, + }, { /* AC bias group 1, table 0 */ - { 0x8, 5 }, - { 0x25, 7 }, - { 0x17A, 9 }, - { 0x2F7, 10 }, - { 0xBDB, 12 }, - { 0x17B4, 13 }, - { 0x2F6B, 14 }, - { 0x1D, 5 }, - { 0x2F6A, 14 }, - { 0x8, 4 }, - { 0x7, 4 }, - { 0x1, 4 }, - { 0x2, 4 }, - { 0xA, 4 }, - { 0x6, 4 }, - { 0x0, 4 }, - { 0x1C, 5 }, - { 0x9, 4 }, - { 0xD, 4 }, - { 0xF, 4 }, - { 0xC, 4 }, - { 0x3, 4 }, - { 0xA, 5 }, - { 0x16, 5 }, - { 0x13, 6 }, - { 0x5D, 7 }, - { 0x24, 7 }, - { 0xBC, 8 }, - { 0x5C, 7 }, - { 0x5EC, 11 }, - { 0xB, 5 }, - { 0x5F, 7 } + { 15, 4 }, { 11, 4 }, { 12, 4 }, { 21, 4 }, { 0, 5 }, { 26, 7 }, + { 1, 7 }, { 24, 6 }, { 22, 5 }, { 30, 5 }, { 14, 4 }, { 10, 4 }, + { 9, 4 }, { 17, 4 }, { 13, 4 }, { 23, 5 }, { 28, 7 }, { 25, 7 }, + { 27, 8 }, { 2, 9 }, { 29, 11 }, { 5, 13 }, { 8, 14 }, { 6, 14 }, + { 4, 12 }, { 3, 10 }, { 31, 7 }, { 20, 4 }, { 18, 4 }, { 16, 5 }, + { 7, 5 }, { 19, 4 }, }, { /* AC bias group 1, table 1 */ - { 0xF, 5 }, - { 0x10, 6 }, - { 0x4B, 8 }, - { 0xC6, 8 }, - { 0x31D, 10 }, - { 0xC71, 12 }, - { 0xC70, 12 }, - { 0x1, 4 }, - { 0xC73, 12 }, - { 0x8, 4 }, - { 0x9, 4 }, - { 0x2, 4 }, - { 0x3, 4 }, - { 0xB, 4 }, - { 0x6, 4 }, - { 0x0, 4 }, - { 0x1C, 5 }, - { 0x5, 4 }, - { 0xD, 4 }, - { 0xF, 4 }, - { 0xA, 4 }, - { 0x19, 5 }, - { 0x13, 6 }, - { 0x1D, 5 }, - { 0x30, 6 }, - { 0x62, 7 }, - { 0x24, 7 }, - { 0x4A, 8 }, - { 0x18F, 9 }, - { 0xC72, 12 }, - { 0xE, 5 }, - { 0x11, 6 } + { 15, 4 }, { 7, 4 }, { 11, 4 }, { 12, 4 }, { 1, 6 }, { 31, 6 }, + { 26, 7 }, { 27, 8 }, { 2, 8 }, { 22, 6 }, { 17, 4 }, { 14, 4 }, + { 30, 5 }, { 0, 5 }, { 9, 4 }, { 10, 4 }, { 20, 4 }, { 13, 4 }, + { 24, 6 }, { 25, 7 }, { 3, 8 }, { 6, 12 }, { 5, 12 }, { 29, 12 }, + { 8, 12 }, { 4, 10 }, { 28, 9 }, { 21, 5 }, { 18, 4 }, { 16, 5 }, + { 23, 5 }, { 19, 4 }, }, { /* AC bias group 1, table 2 */ - { 0x1B, 5 }, - { 0x3, 6 }, - { 0x8D, 8 }, - { 0x40, 7 }, - { 0x239, 10 }, - { 0x471, 11 }, - { 0x8E0, 12 }, - { 0x3, 4 }, - { 0x11C3, 13 }, - { 0xA, 4 }, - { 0x9, 4 }, - { 0x4, 4 }, - { 0x5, 4 }, - { 0xE, 4 }, - { 0x7, 4 }, - { 0x1, 4 }, - { 0x1E, 5 }, - { 0x6, 4 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0x2, 4 }, - { 0x0, 5 }, - { 0x41, 7 }, - { 0x1F, 5 }, - { 0x22, 6 }, - { 0x2, 6 }, - { 0x8F, 8 }, - { 0x8C, 8 }, - { 0x11D, 9 }, - { 0x11C2, 13 }, - { 0x1A, 5 }, - { 0x21, 6 } + { 21, 5 }, { 25, 6 }, { 1, 6 }, { 15, 4 }, { 20, 4 }, { 7, 4 }, + { 11, 4 }, { 12, 4 }, { 17, 4 }, { 14, 4 }, { 3, 7 }, { 22, 7 }, + { 31, 6 }, { 24, 6 }, { 27, 8 }, { 2, 8 }, { 6, 12 }, { 29, 13 }, + { 8, 13 }, { 5, 11 }, { 4, 10 }, { 28, 9 }, { 26, 8 }, { 10, 4 }, + { 9, 4 }, { 19, 4 }, { 18, 4 }, { 30, 5 }, { 0, 5 }, { 13, 4 }, + { 16, 5 }, { 23, 5 }, }, { /* AC bias group 1, table 3 */ - { 0x1F, 5 }, - { 0x3, 6 }, - { 0x3, 7 }, - { 0x43, 7 }, - { 0xB, 9 }, - { 0x15, 10 }, - { 0x51, 12 }, - { 0x3, 4 }, - { 0x50, 12 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x4, 4 }, - { 0x6, 4 }, - { 0xE, 4 }, - { 0xA, 4 }, - { 0x1, 4 }, - { 0x1E, 5 }, - { 0x5, 4 }, - { 0x9, 4 }, - { 0x7, 4 }, - { 0x11, 5 }, - { 0x2, 6 }, - { 0x4, 8 }, - { 0x2, 4 }, - { 0x2D, 6 }, - { 0x20, 6 }, - { 0x42, 7 }, - { 0x1, 7 }, - { 0x0, 7 }, - { 0x29, 11 }, - { 0x17, 5 }, - { 0x2C, 6 } + { 28, 7 }, { 27, 7 }, { 22, 8 }, { 8, 12 }, { 6, 12 }, { 29, 11 }, + { 5, 10 }, { 4, 9 }, { 2, 7 }, { 21, 6 }, { 1, 6 }, { 15, 4 }, + { 23, 4 }, { 7, 4 }, { 11, 4 }, { 17, 4 }, { 12, 4 }, { 19, 4 }, + { 25, 6 }, { 26, 7 }, { 3, 7 }, { 20, 5 }, { 18, 4 }, { 14, 4 }, + { 31, 6 }, { 24, 6 }, { 30, 5 }, { 10, 4 }, { 9, 4 }, { 13, 4 }, + { 16, 5 }, { 0, 5 }, }, { /* AC bias group 1, table 4 */ - { 0x3, 4 }, - { 0x1F, 6 }, - { 0x3A, 7 }, - { 0x5D, 7 }, - { 0x173, 9 }, - { 0x2E4, 10 }, - { 0x172D, 13 }, - { 0x4, 4 }, - { 0x172C, 13 }, - { 0xF, 4 }, - { 0xE, 4 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0xC, 4 }, - { 0xA, 4 }, - { 0x1, 4 }, - { 0x16, 5 }, - { 0x2, 4 }, - { 0x5, 4 }, - { 0x1A, 5 }, - { 0x2F, 6 }, - { 0x38, 7 }, - { 0x5CA, 11 }, - { 0x6, 4 }, - { 0x37, 6 }, - { 0x1E, 6 }, - { 0x3B, 7 }, - { 0x39, 7 }, - { 0xB8, 8 }, - { 0xB97, 12 }, - { 0x0, 4 }, - { 0x36, 6 } + { 30, 4 }, { 15, 4 }, { 17, 4 }, { 0, 4 }, { 7, 4 }, { 18, 4 }, + { 23, 4 }, { 21, 7 }, { 27, 7 }, { 2, 7 }, { 26, 7 }, { 25, 6 }, + { 1, 6 }, { 12, 4 }, { 11, 4 }, { 14, 4 }, { 16, 5 }, { 28, 8 }, + { 5, 10 }, { 22, 11 }, { 8, 13 }, { 6, 13 }, { 29, 12 }, { 4, 9 }, + { 3, 7 }, { 20, 6 }, { 13, 4 }, { 19, 5 }, { 31, 6 }, { 24, 6 }, + { 10, 4 }, { 9, 4 }, }, { /* AC bias group 1, table 5 */ - { 0x6, 4 }, - { 0x37, 6 }, - { 0x5D, 7 }, - { 0xC, 6 }, - { 0xB9, 8 }, - { 0x2E3, 10 }, - { 0x5C4, 11 }, - { 0x4, 4 }, - { 0x1715, 13 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0x8, 4 }, - { 0x7, 4 }, - { 0xC, 4 }, - { 0x9, 4 }, - { 0x1D, 5 }, - { 0x16, 5 }, - { 0x1C, 5 }, - { 0x1A, 5 }, - { 0xB, 5 }, - { 0x5E, 7 }, - { 0x170, 9 }, - { 0x1714, 13 }, - { 0xA, 4 }, - { 0xA, 5 }, - { 0x36, 6 }, - { 0x5F, 7 }, - { 0x1B, 7 }, - { 0x1A, 7 }, - { 0xB8B, 12 }, - { 0x2, 4 }, - { 0x7, 5 } + { 9, 3 }, { 30, 4 }, { 3, 6 }, { 28, 7 }, { 27, 7 }, { 31, 5 }, + { 7, 4 }, { 24, 5 }, { 19, 5 }, { 0, 4 }, { 12, 4 }, { 11, 4 }, + { 14, 4 }, { 23, 4 }, { 16, 5 }, { 21, 9 }, { 6, 11 }, { 22, 13 }, + { 8, 13 }, { 29, 12 }, { 5, 10 }, { 4, 8 }, { 2, 7 }, { 20, 7 }, + { 26, 7 }, { 13, 4 }, { 18, 5 }, { 25, 6 }, { 1, 6 }, { 17, 5 }, + { 15, 5 }, { 10, 4 }, }, { /* AC bias group 1, table 6 */ - { 0xC, 4 }, - { 0xB, 5 }, - { 0x79, 7 }, - { 0x22, 6 }, - { 0xF0, 8 }, - { 0x119, 9 }, - { 0x230, 10 }, - { 0x1D, 5 }, - { 0x8C4, 12 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xA, 4 }, - { 0x9, 4 }, - { 0xB, 4 }, - { 0x7, 4 }, - { 0x1C, 5 }, - { 0x3D, 6 }, - { 0xD, 5 }, - { 0x8, 5 }, - { 0x15, 6 }, - { 0x8D, 8 }, - { 0x118B, 13 }, - { 0x118A, 13 }, - { 0xD, 4 }, - { 0x10, 5 }, - { 0x9, 5 }, - { 0x14, 6 }, - { 0x47, 7 }, - { 0xF1, 8 }, - { 0x463, 11 }, - { 0x1F, 5 }, - { 0xC, 5 } + { 10, 3 }, { 9, 3 }, { 18, 5 }, { 25, 5 }, { 26, 6 }, { 19, 6 }, + { 1, 5 }, { 31, 5 }, { 17, 5 }, { 14, 4 }, { 24, 5 }, { 3, 6 }, + { 6, 10 }, { 8, 12 }, { 22, 13 }, { 21, 13 }, { 29, 11 }, { 5, 9 }, + { 20, 8 }, { 27, 7 }, { 12, 4 }, { 11, 4 }, { 13, 4 }, { 0, 4 }, + { 23, 4 }, { 15, 5 }, { 7, 5 }, { 4, 8 }, { 28, 8 }, { 2, 7 }, + { 16, 6 }, { 30, 5 }, }, { /* AC bias group 1, table 7 */ - { 0x0, 3 }, - { 0x1A, 5 }, - { 0x33, 6 }, - { 0xC, 5 }, - { 0x46, 7 }, - { 0x1E3, 9 }, - { 0x3C5, 10 }, - { 0x17, 5 }, - { 0x1E21, 13 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x9, 4 }, - { 0xA, 4 }, - { 0x7, 4 }, - { 0x1B, 5 }, - { 0x3D, 6 }, - { 0x1B, 6 }, - { 0x22, 6 }, - { 0x79, 7 }, - { 0xF0, 8 }, - { 0x1E20, 13 }, - { 0x1E23, 13 }, - { 0x1E22, 13 }, - { 0xE, 4 }, - { 0x16, 5 }, - { 0x18, 5 }, - { 0x32, 6 }, - { 0x1A, 6 }, - { 0x47, 7 }, - { 0x789, 11 }, - { 0x1F, 5 }, - { 0x10, 5 } + { 0, 3 }, { 10, 3 }, { 9, 3 }, { 3, 5 }, { 27, 6 }, { 16, 6 }, + { 13, 4 }, { 31, 5 }, { 17, 6 }, { 4, 7 }, { 28, 7 }, { 11, 4 }, + { 12, 4 }, { 24, 5 }, { 7, 5 }, { 25, 5 }, { 26, 6 }, { 2, 6 }, + { 1, 5 }, { 14, 5 }, { 23, 4 }, { 19, 8 }, { 20, 13 }, { 8, 13 }, + { 22, 13 }, { 21, 13 }, { 29, 11 }, { 6, 10 }, { 5, 9 }, { 18, 7 }, + { 15, 6 }, { 30, 5 }, }, { /* AC bias group 1, table 8 */ - { 0x1D, 5 }, - { 0x61, 7 }, - { 0x4E, 8 }, - { 0x9E, 9 }, - { 0x27C, 11 }, - { 0x9F5, 13 }, - { 0x9F4, 13 }, - { 0x3, 4 }, - { 0x60, 7 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xB, 4 }, - { 0xA, 4 }, - { 0x9, 4 }, - { 0x5, 4 }, - { 0xD, 5 }, - { 0x31, 6 }, - { 0x8, 5 }, - { 0x38, 6 }, - { 0x12, 6 }, - { 0x26, 7 }, - { 0x13F, 10 }, - { 0x4FB, 12 }, - { 0xD, 4 }, - { 0x2, 4 }, - { 0xC, 5 }, - { 0x39, 6 }, - { 0x1C, 6 }, - { 0xF, 5 }, - { 0x1D, 6 }, - { 0x8, 4 }, - { 0x19, 5 } + { 9, 3 }, { 24, 4 }, { 7, 4 }, { 17, 5 }, { 19, 6 }, { 20, 7 }, + { 2, 8 }, { 3, 9 }, { 4, 11 }, { 6, 13 }, { 5, 13 }, { 22, 12 }, + { 21, 10 }, { 14, 4 }, { 25, 5 }, { 15, 5 }, { 27, 6 }, { 29, 6 }, + { 28, 5 }, { 30, 4 }, { 13, 4 }, { 12, 4 }, { 11, 4 }, { 8, 7 }, + { 1, 7 }, { 16, 6 }, { 31, 5 }, { 23, 4 }, { 18, 6 }, { 26, 6 }, + { 0, 5 }, { 10, 4 }, }, { /* AC bias group 1, table 9 */ - { 0x7, 4 }, - { 0x19, 6 }, - { 0xAB, 8 }, - { 0xAA, 8 }, - { 0x119, 10 }, - { 0x461, 12 }, - { 0x460, 12 }, - { 0x1B, 5 }, - { 0x47, 8 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0x9, 4 }, - { 0x5, 4 }, - { 0xD, 5 }, - { 0x35, 6 }, - { 0x3D, 6 }, - { 0x3C, 6 }, - { 0x18, 6 }, - { 0x22, 7 }, - { 0x8D, 9 }, - { 0x231, 11 }, - { 0xE, 4 }, - { 0x1F, 5 }, - { 0x9, 5 }, - { 0x2B, 6 }, - { 0x10, 6 }, - { 0x34, 6 }, - { 0x54, 7 }, - { 0x8, 4 }, - { 0x14, 5 } + { 10, 3 }, { 9, 3 }, { 27, 6 }, { 20, 7 }, { 6, 12 }, { 5, 12 }, + { 22, 11 }, { 4, 10 }, { 21, 9 }, { 8, 8 }, { 25, 5 }, { 14, 4 }, + { 19, 6 }, { 1, 6 }, { 15, 5 }, { 0, 4 }, { 30, 4 }, { 13, 4 }, + { 31, 5 }, { 29, 7 }, { 3, 8 }, { 2, 8 }, { 26, 6 }, { 12, 4 }, + { 11, 4 }, { 28, 6 }, { 16, 6 }, { 7, 5 }, { 23, 4 }, { 18, 6 }, + { 17, 6 }, { 24, 5 }, }, { /* AC bias group 1, table 10 */ - { 0xC, 4 }, - { 0x5, 5 }, - { 0x8, 6 }, - { 0x5B, 7 }, - { 0x4D, 9 }, - { 0x131, 11 }, - { 0x261, 12 }, - { 0x1A, 5 }, - { 0x12, 7 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xA, 4 }, - { 0x9, 4 }, - { 0x6, 4 }, - { 0x1B, 5 }, - { 0x6, 5 }, - { 0x1C, 6 }, - { 0x2C, 6 }, - { 0x15, 6 }, - { 0x5A, 7 }, - { 0x27, 8 }, - { 0x99, 10 }, - { 0x260, 12 }, - { 0xE, 4 }, - { 0x4, 4 }, - { 0xF, 5 }, - { 0x7, 5 }, - { 0x1D, 6 }, - { 0xB, 5 }, - { 0x14, 6 }, - { 0x8, 4 }, - { 0x17, 5 } + { 9, 3 }, { 2, 6 }, { 8, 7 }, { 22, 12 }, { 6, 12 }, { 5, 11 }, + { 21, 10 }, { 4, 9 }, { 20, 8 }, { 1, 5 }, { 15, 5 }, { 26, 5 }, + { 24, 4 }, { 29, 6 }, { 18, 6 }, { 28, 5 }, { 13, 4 }, { 16, 6 }, + { 27, 6 }, { 25, 5 }, { 30, 4 }, { 12, 4 }, { 11, 4 }, { 17, 6 }, + { 19, 7 }, { 3, 7 }, { 31, 5 }, { 0, 4 }, { 7, 5 }, { 14, 5 }, + { 23, 4 }, { 10, 4 }, }, { /* AC bias group 1, table 11 */ - { 0xF, 4 }, - { 0x13, 5 }, - { 0x75, 7 }, - { 0x24, 6 }, - { 0x95, 8 }, - { 0x251, 10 }, - { 0x4A0, 11 }, - { 0x10, 5 }, - { 0xC8, 8 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x1, 4 }, - { 0x0, 4 }, - { 0x1A, 5 }, - { 0x11, 5 }, - { 0x2C, 6 }, - { 0x65, 7 }, - { 0x74, 7 }, - { 0x4B, 7 }, - { 0xC9, 8 }, - { 0x129, 9 }, - { 0x943, 12 }, - { 0x942, 12 }, - { 0x3, 3 }, - { 0xA, 4 }, - { 0x1C, 5 }, - { 0x18, 5 }, - { 0x33, 6 }, - { 0x17, 5 }, - { 0x2D, 6 }, - { 0x1B, 5 }, - { 0x3B, 6 } + { 12, 4 }, { 11, 4 }, { 10, 3 }, { 9, 3 }, { 23, 3 }, { 7, 5 }, + { 14, 5 }, { 3, 6 }, { 6, 11 }, { 22, 12 }, { 21, 12 }, { 5, 10 }, + { 20, 9 }, { 4, 8 }, { 18, 7 }, { 1, 5 }, { 24, 4 }, { 15, 6 }, + { 29, 6 }, { 28, 5 }, { 26, 5 }, { 8, 8 }, { 19, 8 }, { 16, 7 }, + { 27, 6 }, { 13, 5 }, { 30, 5 }, { 25, 5 }, { 17, 7 }, { 2, 7 }, + { 31, 6 }, { 0, 4 }, }, { /* AC bias group 1, table 12 */ - { 0x3, 3 }, - { 0x1A, 5 }, - { 0x2D, 6 }, - { 0x38, 6 }, - { 0x28, 7 }, - { 0x395, 10 }, - { 0xE51, 12 }, - { 0x37, 6 }, - { 0xE4, 8 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x1F, 5 }, - { 0x1E, 5 }, - { 0x17, 5 }, - { 0x3A, 6 }, - { 0x73, 7 }, - { 0x2A, 7 }, - { 0x2B, 7 }, - { 0x29, 7 }, - { 0x1CB, 9 }, - { 0x729, 11 }, - { 0x1CA1, 13 }, - { 0x1CA0, 13 }, - { 0x4, 3 }, - { 0xA, 4 }, - { 0x4, 4 }, - { 0x18, 5 }, - { 0x36, 6 }, - { 0xB, 5 }, - { 0x2C, 6 }, - { 0x19, 5 }, - { 0x3B, 6 } + { 10, 3 }, { 9, 3 }, { 25, 4 }, { 4, 7 }, { 18, 7 }, { 16, 7 }, + { 17, 7 }, { 28, 5 }, { 0, 3 }, { 23, 3 }, { 24, 4 }, { 29, 6 }, + { 2, 6 }, { 13, 5 }, { 26, 5 }, { 30, 5 }, { 1, 5 }, { 27, 6 }, + { 7, 6 }, { 3, 6 }, { 8, 8 }, { 22, 13 }, { 21, 13 }, { 6, 12 }, + { 20, 11 }, { 5, 10 }, { 19, 9 }, { 15, 7 }, { 14, 6 }, { 31, 6 }, + { 12, 5 }, { 11, 5 }, }, { /* AC bias group 1, table 13 */ - { 0x4, 3 }, - { 0x4, 4 }, - { 0x3F, 6 }, - { 0x17, 5 }, - { 0x75, 7 }, - { 0x1F5, 9 }, - { 0x7D1, 11 }, - { 0x17, 6 }, - { 0x1F6, 9 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x1B, 5 }, - { 0x1A, 5 }, - { 0xA, 5 }, - { 0x32, 6 }, - { 0x74, 7 }, - { 0xF8, 8 }, - { 0xF9, 8 }, - { 0x1F7, 9 }, - { 0x3E9, 10 }, - { 0xFA0, 12 }, - { 0x1F43, 13 }, - { 0x1F42, 13 }, - { 0x3, 3 }, - { 0xA, 4 }, - { 0x1E, 5 }, - { 0x1C, 5 }, - { 0x3B, 6 }, - { 0x18, 5 }, - { 0x16, 6 }, - { 0x16, 5 }, - { 0x33, 6 } + { 10, 3 }, { 9, 3 }, { 1, 4 }, { 13, 5 }, { 29, 6 }, { 7, 6 }, + { 23, 3 }, { 0, 3 }, { 24, 4 }, { 30, 5 }, { 3, 5 }, { 28, 5 }, + { 14, 6 }, { 31, 6 }, { 12, 5 }, { 11, 5 }, { 26, 5 }, { 15, 7 }, + { 4, 7 }, { 27, 6 }, { 25, 5 }, { 16, 8 }, { 17, 8 }, { 20, 12 }, + { 22, 13 }, { 21, 13 }, { 6, 11 }, { 19, 10 }, { 5, 9 }, { 8, 9 }, + { 18, 9 }, { 2, 6 }, }, { /* AC bias group 1, table 14 */ - { 0x4, 3 }, - { 0x7, 4 }, - { 0x18, 5 }, - { 0x1E, 5 }, - { 0x36, 6 }, - { 0x31, 7 }, - { 0x177, 9 }, - { 0x77, 7 }, - { 0x176, 9 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x1A, 5 }, - { 0x19, 5 }, - { 0x3A, 6 }, - { 0x19, 6 }, - { 0x5C, 7 }, - { 0xBA, 8 }, - { 0x61, 8 }, - { 0xC1, 9 }, - { 0x180, 10 }, - { 0x302, 11 }, - { 0x607, 12 }, - { 0x606, 12 }, - { 0x2, 3 }, - { 0xA, 4 }, - { 0x1F, 5 }, - { 0x1C, 5 }, - { 0x37, 6 }, - { 0x16, 5 }, - { 0x76, 7 }, - { 0xD, 5 }, - { 0x2F, 6 } + { 10, 3 }, { 9, 3 }, { 23, 3 }, { 19, 10 }, { 20, 11 }, { 22, 12 }, + { 21, 12 }, { 18, 9 }, { 17, 8 }, { 5, 7 }, { 14, 6 }, { 30, 5 }, + { 1, 4 }, { 0, 3 }, { 24, 4 }, { 28, 5 }, { 15, 7 }, { 16, 8 }, + { 8, 9 }, { 6, 9 }, { 31, 6 }, { 2, 5 }, { 12, 5 }, { 11, 5 }, + { 4, 6 }, { 27, 6 }, { 26, 5 }, { 13, 6 }, { 29, 7 }, { 7, 7 }, + { 3, 5 }, { 25, 5 }, }, { /* AC bias group 1, table 15 */ - { 0x0, 3 }, - { 0xA, 4 }, - { 0x1A, 5 }, - { 0xC, 4 }, - { 0x1D, 5 }, - { 0x39, 6 }, - { 0x78, 7 }, - { 0x5E, 7 }, - { 0x393, 11 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x16, 5 }, - { 0xF, 5 }, - { 0x2E, 6 }, - { 0x5F, 7 }, - { 0x73, 8 }, - { 0xE5, 9 }, - { 0x1C8, 10 }, - { 0xE4A, 13 }, - { 0x1C97, 14 }, - { 0x1C96, 14 }, - { 0xE49, 13 }, - { 0xE48, 13 }, - { 0x4, 3 }, - { 0x6, 4 }, - { 0x1F, 5 }, - { 0x1B, 5 }, - { 0x1D, 6 }, - { 0x38, 6 }, - { 0x38, 7 }, - { 0x3D, 6 }, - { 0x79, 7 } - } -}; - -static const uint16_t ac_bias_1[16][32][2] = { + { 0, 3 }, { 10, 3 }, { 9, 3 }, { 24, 4 }, { 29, 7 }, { 17, 10 }, + { 22, 13 }, { 21, 13 }, { 18, 13 }, { 20, 14 }, { 19, 14 }, { 8, 11 }, + { 16, 9 }, { 15, 8 }, { 27, 6 }, { 12, 5 }, { 23, 3 }, { 1, 4 }, + { 11, 5 }, { 13, 6 }, { 7, 7 }, { 14, 7 }, { 3, 4 }, { 2, 5 }, + { 26, 5 }, { 28, 6 }, { 5, 6 }, { 4, 5 }, { 6, 7 }, { 31, 7 }, + { 30, 6 }, { 25, 5 }, + }, { /* AC bias group 2, table 0 */ - { 0xB, 5 }, - { 0x2B, 7 }, - { 0x54, 8 }, - { 0x1B7, 9 }, - { 0x6D9, 11 }, - { 0xDB1, 12 }, - { 0xDB0, 12 }, - { 0x2, 4 }, - { 0xAB, 9 }, - { 0x9, 4 }, - { 0xA, 4 }, - { 0x7, 4 }, - { 0x8, 4 }, - { 0xF, 4 }, - { 0xC, 4 }, - { 0x3, 4 }, - { 0x1D, 5 }, - { 0x4, 4 }, - { 0xB, 4 }, - { 0x6, 4 }, - { 0x1A, 5 }, - { 0x3, 6 }, - { 0xAA, 9 }, - { 0x1, 4 }, - { 0x0, 5 }, - { 0x14, 6 }, - { 0x6C, 7 }, - { 0xDA, 8 }, - { 0x2, 6 }, - { 0x36D, 10 }, - { 0x1C, 5 }, - { 0x37, 6 } + { 24, 5 }, { 28, 6 }, { 21, 6 }, { 23, 4 }, { 7, 4 }, { 15, 4 }, + { 17, 4 }, { 25, 6 }, { 2, 8 }, { 22, 9 }, { 8, 9 }, { 1, 7 }, + { 0, 5 }, { 19, 4 }, { 11, 4 }, { 12, 4 }, { 9, 4 }, { 10, 4 }, + { 18, 4 }, { 14, 4 }, { 20, 5 }, { 26, 7 }, { 27, 8 }, { 6, 12 }, + { 5, 12 }, { 4, 11 }, { 29, 10 }, { 3, 9 }, { 31, 6 }, { 30, 5 }, + { 16, 5 }, { 13, 4 }, }, { /* AC bias group 2, table 1 */ - { 0x1D, 5 }, - { 0x4, 6 }, - { 0xB6, 8 }, - { 0x6A, 8 }, - { 0x5B9, 11 }, - { 0x16E1, 13 }, - { 0x16E0, 13 }, - { 0x7, 4 }, - { 0x16F, 9 }, - { 0xC, 4 }, - { 0xD, 4 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0xF, 4 }, - { 0xA, 4 }, - { 0x3, 4 }, - { 0x17, 5 }, - { 0x2, 4 }, - { 0x4, 4 }, - { 0x1C, 5 }, - { 0x2C, 6 }, - { 0x6B, 8 }, - { 0xB71, 12 }, - { 0x5, 4 }, - { 0x3, 5 }, - { 0x1B, 6 }, - { 0x5A, 7 }, - { 0x34, 7 }, - { 0x5, 6 }, - { 0x2DD, 10 }, - { 0x0, 4 }, - { 0xC, 5 } + { 30, 4 }, { 1, 6 }, { 28, 6 }, { 24, 5 }, { 17, 4 }, { 15, 4 }, + { 18, 4 }, { 23, 4 }, { 31, 5 }, { 27, 7 }, { 3, 8 }, { 21, 8 }, + { 25, 6 }, { 7, 4 }, { 12, 4 }, { 11, 4 }, { 14, 4 }, { 20, 6 }, + { 26, 7 }, { 2, 8 }, { 6, 13 }, { 5, 13 }, { 22, 12 }, { 4, 11 }, + { 29, 10 }, { 8, 9 }, { 16, 5 }, { 9, 4 }, { 10, 4 }, { 19, 5 }, + { 0, 5 }, { 13, 4 }, }, { /* AC bias group 2, table 2 */ - { 0x3, 4 }, - { 0x7F, 7 }, - { 0xA1, 8 }, - { 0xA0, 8 }, - { 0x20C, 10 }, - { 0x834, 12 }, - { 0x106B, 13 }, - { 0x7, 4 }, - { 0x82, 8 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0x0, 3 }, - { 0x9, 4 }, - { 0x2, 4 }, - { 0x11, 5 }, - { 0x1E, 5 }, - { 0x15, 5 }, - { 0x3E, 6 }, - { 0x40, 7 }, - { 0x41B, 11 }, - { 0x106A, 13 }, - { 0x6, 4 }, - { 0xA, 5 }, - { 0x29, 6 }, - { 0x7E, 7 }, - { 0x51, 7 }, - { 0x21, 6 }, - { 0x107, 9 }, - { 0x4, 4 }, - { 0xB, 5 } + { 13, 3 }, { 15, 4 }, { 0, 4 }, { 30, 4 }, { 24, 5 }, { 31, 5 }, + { 23, 4 }, { 7, 4 }, { 20, 7 }, { 8, 8 }, { 4, 10 }, { 5, 12 }, + { 22, 13 }, { 6, 13 }, { 21, 11 }, { 29, 9 }, { 28, 6 }, { 16, 5 }, + { 14, 4 }, { 3, 8 }, { 2, 8 }, { 27, 7 }, { 25, 6 }, { 18, 5 }, + { 11, 4 }, { 12, 4 }, { 10, 4 }, { 9, 4 }, { 17, 5 }, { 19, 6 }, + { 26, 7 }, { 1, 7 }, }, { /* AC bias group 2, table 3 */ - { 0x7, 4 }, - { 0x1B, 6 }, - { 0xF6, 8 }, - { 0xE9, 8 }, - { 0x3A1, 10 }, - { 0x740, 11 }, - { 0xE82, 12 }, - { 0x1F, 5 }, - { 0x1EF, 9 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0xD, 4 }, - { 0x8, 4 }, - { 0x1C, 5 }, - { 0x3, 5 }, - { 0x12, 5 }, - { 0x2, 5 }, - { 0x75, 7 }, - { 0x1D1, 9 }, - { 0x1D07, 13 }, - { 0x1D06, 13 }, - { 0xA, 4 }, - { 0x13, 5 }, - { 0x3B, 6 }, - { 0x1A, 6 }, - { 0x7A, 7 }, - { 0x3C, 6 }, - { 0x1EE, 9 }, - { 0x0, 4 }, - { 0xC, 5 } + { 30, 4 }, { 18, 5 }, { 16, 5 }, { 9, 3 }, { 10, 3 }, { 31, 5 }, + { 26, 6 }, { 1, 6 }, { 0, 4 }, { 14, 4 }, { 17, 5 }, { 24, 5 }, + { 23, 4 }, { 11, 4 }, { 12, 4 }, { 13, 4 }, { 15, 5 }, { 5, 11 }, + { 6, 12 }, { 22, 13 }, { 21, 13 }, { 4, 10 }, { 20, 9 }, { 3, 8 }, + { 19, 7 }, { 25, 6 }, { 28, 6 }, { 27, 7 }, { 2, 8 }, { 29, 9 }, + { 8, 9 }, { 7, 5 }, }, { /* AC bias group 2, table 4 */ - { 0xD, 4 }, - { 0x3D, 6 }, - { 0x42, 7 }, - { 0x37, 7 }, - { 0xD9, 9 }, - { 0x362, 11 }, - { 0x6C6, 12 }, - { 0x1F, 5 }, - { 0x86, 8 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0xA, 4 }, - { 0x1, 4 }, - { 0xF, 5 }, - { 0x25, 6 }, - { 0x3C, 6 }, - { 0x1A, 6 }, - { 0x87, 8 }, - { 0x1B0, 10 }, - { 0xD8F, 13 }, - { 0xD8E, 13 }, - { 0xE, 4 }, - { 0x13, 5 }, - { 0xC, 5 }, - { 0x24, 6 }, - { 0x20, 6 }, - { 0x11, 5 }, - { 0x6D, 8 }, - { 0x0, 4 }, - { 0xE, 5 } + { 30, 4 }, { 14, 4 }, { 9, 3 }, { 10, 3 }, { 25, 5 }, { 18, 6 }, + { 20, 10 }, { 5, 11 }, { 6, 12 }, { 22, 13 }, { 21, 13 }, { 4, 9 }, + { 29, 8 }, { 3, 7 }, { 31, 5 }, { 15, 5 }, { 27, 6 }, { 2, 7 }, + { 8, 8 }, { 19, 8 }, { 28, 5 }, { 26, 6 }, { 16, 6 }, { 24, 5 }, + { 13, 4 }, { 12, 4 }, { 11, 4 }, { 0, 4 }, { 23, 4 }, { 17, 6 }, + { 1, 6 }, { 7, 5 }, }, { /* AC bias group 2, table 5 */ - { 0x0, 3 }, - { 0x12, 5 }, - { 0x76, 7 }, - { 0x77, 7 }, - { 0x14D, 9 }, - { 0x533, 11 }, - { 0x14C9, 13 }, - { 0x13, 5 }, - { 0xA5, 8 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0x8, 4 }, - { 0x1A, 5 }, - { 0x2B, 6 }, - { 0x75, 7 }, - { 0x74, 7 }, - { 0xA7, 8 }, - { 0x298, 10 }, - { 0x14C8, 13 }, - { 0x14CB, 13 }, - { 0x14CA, 13 }, - { 0xF, 4 }, - { 0x1C, 5 }, - { 0x7, 5 }, - { 0x2A, 6 }, - { 0x28, 6 }, - { 0x1B, 5 }, - { 0xA4, 8 }, - { 0x2, 4 }, - { 0x6, 5 } + { 0, 3 }, { 30, 4 }, { 31, 5 }, { 25, 5 }, { 9, 3 }, { 10, 3 }, + { 13, 4 }, { 1, 5 }, { 7, 5 }, { 27, 6 }, { 29, 8 }, { 8, 8 }, + { 19, 10 }, { 20, 13 }, { 6, 13 }, { 22, 13 }, { 21, 13 }, { 5, 11 }, + { 4, 9 }, { 18, 8 }, { 26, 6 }, { 15, 6 }, { 11, 4 }, { 12, 4 }, + { 14, 5 }, { 28, 5 }, { 24, 5 }, { 17, 7 }, { 16, 7 }, { 2, 7 }, + { 3, 7 }, { 23, 4 }, }, { /* AC bias group 2, table 6 */ - { 0x2, 3 }, - { 0x1A, 5 }, - { 0x2B, 6 }, - { 0x3A, 6 }, - { 0xED, 8 }, - { 0x283, 10 }, - { 0xA0A, 12 }, - { 0x4, 5 }, - { 0xA1, 8 }, - { 0x4, 3 }, - { 0x3, 3 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0x1F, 5 }, - { 0x6, 5 }, - { 0x77, 7 }, - { 0xA3, 8 }, - { 0xA2, 8 }, - { 0x140, 9 }, - { 0x1417, 13 }, - { 0x1416, 13 }, - { 0xA09, 12 }, - { 0xA08, 12 }, - { 0x0, 3 }, - { 0x1E, 5 }, - { 0x7, 5 }, - { 0x2A, 6 }, - { 0x29, 6 }, - { 0x1C, 5 }, - { 0xEC, 8 }, - { 0x1B, 5 }, - { 0x5, 5 } + { 23, 3 }, { 7, 5 }, { 31, 5 }, { 14, 5 }, { 25, 5 }, { 0, 3 }, + { 10, 3 }, { 9, 3 }, { 18, 9 }, { 22, 12 }, { 21, 12 }, { 6, 12 }, + { 20, 13 }, { 19, 13 }, { 5, 10 }, { 8, 8 }, { 17, 8 }, { 16, 8 }, + { 27, 6 }, { 26, 6 }, { 2, 6 }, { 11, 4 }, { 12, 4 }, { 1, 5 }, + { 30, 5 }, { 28, 5 }, { 3, 6 }, { 29, 8 }, { 4, 8 }, { 15, 7 }, + { 24, 5 }, { 13, 5 }, }, { /* AC bias group 2, table 7 */ - { 0x2, 3 }, - { 0x2, 4 }, - { 0x18, 5 }, - { 0x1D, 5 }, - { 0x35, 6 }, - { 0xE4, 8 }, - { 0x1CF, 11 }, - { 0x1D, 7 }, - { 0x72, 9 }, - { 0x4, 3 }, - { 0x5, 3 }, - { 0x6, 4 }, - { 0x7, 4 }, - { 0x6, 5 }, - { 0x73, 7 }, - { 0x38, 8 }, - { 0x1CE, 11 }, - { 0x39B, 12 }, - { 0x398, 12 }, - { 0x733, 13 }, - { 0x732, 13 }, - { 0x735, 13 }, - { 0x734, 13 }, - { 0x0, 3 }, - { 0x1F, 5 }, - { 0x1B, 5 }, - { 0x34, 6 }, - { 0xF, 6 }, - { 0x1E, 5 }, - { 0xE5, 8 }, - { 0x19, 5 }, - { 0x38, 6 } + { 23, 3 }, { 1, 4 }, { 13, 5 }, { 15, 8 }, { 8, 9 }, { 18, 12 }, + { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, { 17, 12 }, { 16, 11 }, + { 6, 11 }, { 7, 7 }, { 27, 6 }, { 0, 3 }, { 11, 4 }, { 12, 4 }, + { 9, 3 }, { 10, 3 }, { 2, 5 }, { 30, 5 }, { 26, 6 }, { 4, 6 }, + { 25, 5 }, { 31, 6 }, { 5, 8 }, { 29, 8 }, { 14, 7 }, { 3, 5 }, + { 28, 5 }, { 24, 5 }, }, { /* AC bias group 2, table 8 */ - { 0x16, 5 }, - { 0x50, 7 }, - { 0x172, 9 }, - { 0x2E7, 10 }, - { 0x1732, 13 }, - { 0x2E67, 14 }, - { 0x2E66, 14 }, - { 0x6, 4 }, - { 0x51, 7 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x9, 4 }, - { 0x1C, 5 }, - { 0x9, 5 }, - { 0x1C, 6 }, - { 0x1D, 6 }, - { 0x5D, 7 }, - { 0xB8, 8 }, - { 0x5CD, 11 }, - { 0x1731, 13 }, - { 0x1730, 13 }, - { 0xF, 4 }, - { 0x5, 4 }, - { 0xF, 5 }, - { 0x8, 5 }, - { 0x29, 6 }, - { 0x1D, 5 }, - { 0x2F, 6 }, - { 0x8, 4 }, - { 0x15, 5 } + { 10, 3 }, { 9, 3 }, { 26, 5 }, { 15, 5 }, { 24, 4 }, { 7, 4 }, + { 16, 6 }, { 17, 6 }, { 25, 5 }, { 30, 4 }, { 13, 4 }, { 1, 7 }, + { 8, 7 }, { 27, 6 }, { 31, 5 }, { 0, 5 }, { 19, 8 }, { 2, 9 }, + { 22, 13 }, { 21, 13 }, { 4, 13 }, { 6, 14 }, { 5, 14 }, { 20, 11 }, + { 3, 10 }, { 18, 7 }, { 29, 6 }, { 12, 4 }, { 11, 4 }, { 14, 5 }, + { 28, 5 }, { 23, 4 }, }, { /* AC bias group 2, table 9 */ - { 0x9, 4 }, - { 0x21, 6 }, - { 0x40, 7 }, - { 0xAD, 8 }, - { 0x2B0, 10 }, - { 0x1589, 13 }, - { 0x1588, 13 }, - { 0x1C, 5 }, - { 0x5F, 7 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x6, 4 }, - { 0x11, 5 }, - { 0x2A, 6 }, - { 0x57, 7 }, - { 0x5E, 7 }, - { 0x41, 7 }, - { 0x159, 9 }, - { 0x563, 11 }, - { 0x158B, 13 }, - { 0x158A, 13 }, - { 0x1, 3 }, - { 0x5, 4 }, - { 0x14, 5 }, - { 0x3B, 6 }, - { 0x2E, 6 }, - { 0x4, 4 }, - { 0x3A, 6 }, - { 0x7, 4 }, - { 0x16, 5 } + { 9, 3 }, { 23, 3 }, { 28, 4 }, { 24, 4 }, { 13, 4 }, { 30, 4 }, + { 2, 7 }, { 18, 7 }, { 1, 6 }, { 14, 5 }, { 0, 4 }, { 25, 5 }, + { 15, 6 }, { 4, 10 }, { 6, 13 }, { 5, 13 }, { 22, 13 }, { 21, 13 }, + { 20, 11 }, { 19, 9 }, { 3, 8 }, { 16, 7 }, { 31, 5 }, { 27, 6 }, + { 17, 7 }, { 8, 7 }, { 12, 4 }, { 11, 4 }, { 7, 5 }, { 29, 6 }, + { 26, 6 }, { 10, 4 }, }, { /* AC bias group 2, table 10 */ - { 0xE, 4 }, - { 0x7, 5 }, - { 0x46, 7 }, - { 0x45, 7 }, - { 0x64, 9 }, - { 0x32A, 12 }, - { 0x657, 13 }, - { 0x18, 5 }, - { 0xD, 6 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xA, 4 }, - { 0xB, 4 }, - { 0x1A, 5 }, - { 0x36, 6 }, - { 0x47, 7 }, - { 0x44, 7 }, - { 0x18, 7 }, - { 0x33, 8 }, - { 0xCB, 10 }, - { 0x656, 13 }, - { 0x329, 12 }, - { 0x328, 12 }, - { 0x2, 3 }, - { 0x6, 4 }, - { 0x19, 5 }, - { 0xE, 5 }, - { 0x37, 6 }, - { 0x9, 4 }, - { 0xF, 5 }, - { 0x2, 4 }, - { 0x10, 5 } + { 9, 3 }, { 30, 4 }, { 17, 7 }, { 4, 9 }, { 22, 12 }, { 21, 12 }, + { 5, 12 }, { 20, 13 }, { 6, 13 }, { 19, 10 }, { 18, 8 }, { 8, 6 }, + { 1, 5 }, { 23, 3 }, { 24, 4 }, { 26, 5 }, { 29, 5 }, { 31, 5 }, + { 16, 7 }, { 3, 7 }, { 2, 7 }, { 15, 7 }, { 28, 4 }, { 11, 4 }, + { 12, 4 }, { 7, 5 }, { 25, 5 }, { 13, 5 }, { 14, 6 }, { 27, 6 }, + { 0, 4 }, { 10, 4 }, }, { /* AC bias group 2, table 11 */ - { 0x3, 3 }, - { 0x18, 5 }, - { 0x23, 6 }, - { 0x77, 7 }, - { 0x194, 9 }, - { 0x1956, 13 }, - { 0x32AF, 14 }, - { 0x3A, 6 }, - { 0x76, 7 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x1F, 5 }, - { 0x1E, 5 }, - { 0x14, 5 }, - { 0x22, 6 }, - { 0x64, 7 }, - { 0x197, 9 }, - { 0x196, 9 }, - { 0x32B, 10 }, - { 0x654, 11 }, - { 0x32AE, 14 }, - { 0x1955, 13 }, - { 0x1954, 13 }, - { 0x0, 3 }, - { 0x9, 4 }, - { 0x1C, 5 }, - { 0x15, 5 }, - { 0x10, 5 }, - { 0xD, 4 }, - { 0x17, 5 }, - { 0x16, 5 }, - { 0x33, 6 } + { 23, 3 }, { 10, 3 }, { 9, 3 }, { 0, 3 }, { 27, 5 }, { 14, 6 }, + { 2, 6 }, { 24, 4 }, { 13, 5 }, { 26, 5 }, { 30, 5 }, { 29, 5 }, + { 1, 5 }, { 15, 7 }, { 4, 9 }, { 19, 11 }, { 22, 13 }, { 21, 13 }, + { 5, 13 }, { 20, 14 }, { 6, 14 }, { 18, 10 }, { 17, 9 }, { 16, 9 }, + { 31, 6 }, { 28, 4 }, { 25, 5 }, { 7, 6 }, { 8, 7 }, { 3, 7 }, + { 12, 5 }, { 11, 5 }, }, { /* AC bias group 2, table 12 */ - { 0x5, 3 }, - { 0x6, 4 }, - { 0x3E, 6 }, - { 0x10, 5 }, - { 0x48, 7 }, - { 0x93F, 12 }, - { 0x24FA, 14 }, - { 0x32, 6 }, - { 0x67, 7 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x1B, 5 }, - { 0x1E, 5 }, - { 0x34, 6 }, - { 0x66, 7 }, - { 0x92, 8 }, - { 0x126, 9 }, - { 0x24E, 10 }, - { 0x49E, 11 }, - { 0x49F7, 15 }, - { 0x49F6, 15 }, - { 0x24F9, 14 }, - { 0x24F8, 14 }, - { 0x0, 3 }, - { 0x7, 4 }, - { 0x18, 5 }, - { 0x11, 5 }, - { 0x3F, 6 }, - { 0xE, 4 }, - { 0x13, 5 }, - { 0x35, 6 }, - { 0x25, 6 } + { 23, 3 }, { 10, 3 }, { 9, 3 }, { 1, 4 }, { 24, 4 }, { 3, 5 }, + { 26, 5 }, { 4, 7 }, { 15, 8 }, { 16, 9 }, { 17, 10 }, { 18, 11 }, + { 22, 14 }, { 21, 14 }, { 6, 14 }, { 20, 15 }, { 19, 15 }, { 5, 12 }, + { 31, 6 }, { 29, 5 }, { 0, 3 }, { 25, 5 }, { 7, 6 }, { 14, 7 }, + { 8, 7 }, { 13, 6 }, { 30, 6 }, { 11, 5 }, { 28, 4 }, { 12, 5 }, + { 2, 6 }, { 27, 6 }, }, { /* AC bias group 2, table 13 */ - { 0x5, 3 }, - { 0x8, 4 }, - { 0x12, 5 }, - { 0x1C, 5 }, - { 0x1C, 6 }, - { 0xEA, 9 }, - { 0x1D75, 14 }, - { 0x1E, 6 }, - { 0x66, 7 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0x1B, 5 }, - { 0x1A, 5 }, - { 0x1F, 6 }, - { 0x3B, 7 }, - { 0x74, 8 }, - { 0x1D6, 10 }, - { 0x3AF, 11 }, - { 0x1D74, 14 }, - { 0x1D77, 14 }, - { 0x1D76, 14 }, - { 0xEB9, 13 }, - { 0xEB8, 13 }, - { 0xF, 4 }, - { 0x6, 4 }, - { 0x13, 5 }, - { 0x3B, 6 }, - { 0x3A, 6 }, - { 0x0, 3 }, - { 0x18, 5 }, - { 0x32, 6 }, - { 0x67, 7 } + { 28, 3 }, { 9, 3 }, { 10, 3 }, { 24, 4 }, { 4, 6 }, { 15, 8 }, + { 5, 9 }, { 16, 10 }, { 22, 13 }, { 21, 13 }, { 18, 14 }, { 6, 14 }, + { 20, 14 }, { 19, 14 }, { 17, 11 }, { 14, 7 }, { 7, 6 }, { 13, 6 }, + { 1, 4 }, { 2, 5 }, { 25, 5 }, { 0, 3 }, { 29, 5 }, { 30, 6 }, + { 8, 7 }, { 31, 7 }, { 12, 5 }, { 11, 5 }, { 3, 5 }, { 27, 6 }, + { 26, 6 }, { 23, 4 }, }, { /* AC bias group 2, table 14 */ - { 0x4, 3 }, - { 0xA, 4 }, - { 0x1B, 5 }, - { 0xC, 4 }, - { 0xD, 5 }, - { 0xE6, 8 }, - { 0x684, 11 }, - { 0x72, 7 }, - { 0xE7, 8 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x17, 5 }, - { 0x16, 5 }, - { 0x18, 6 }, - { 0xD1, 8 }, - { 0x1A0, 9 }, - { 0x686, 11 }, - { 0xD0F, 12 }, - { 0xD0A, 12 }, - { 0x1A17, 13 }, - { 0x1A16, 13 }, - { 0x1A1D, 13 }, - { 0x1A1C, 13 }, - { 0xF, 4 }, - { 0x1D, 5 }, - { 0xE, 5 }, - { 0x35, 6 }, - { 0x38, 6 }, - { 0x0, 3 }, - { 0xF, 5 }, - { 0x19, 6 }, - { 0x69, 7 } + { 28, 3 }, { 10, 3 }, { 9, 3 }, { 13, 6 }, { 30, 6 }, { 4, 5 }, + { 25, 5 }, { 29, 5 }, { 0, 3 }, { 1, 4 }, { 12, 5 }, { 11, 5 }, + { 3, 4 }, { 15, 9 }, { 6, 11 }, { 18, 12 }, { 20, 13 }, { 19, 13 }, + { 16, 11 }, { 22, 13 }, { 21, 13 }, { 17, 12 }, { 14, 8 }, { 31, 7 }, + { 26, 6 }, { 2, 5 }, { 27, 6 }, { 7, 7 }, { 5, 8 }, { 8, 8 }, + { 24, 5 }, { 23, 4 }, }, { /* AC bias group 2, table 15 */ - { 0x3, 3 }, - { 0xC, 4 }, - { 0x1B, 5 }, - { 0x0, 3 }, - { 0x3, 4 }, - { 0x2E, 6 }, - { 0x51, 9 }, - { 0xBC, 8 }, - { 0x53, 9 }, - { 0x4, 3 }, - { 0x2, 3 }, - { 0x16, 5 }, - { 0x15, 5 }, - { 0x15, 7 }, - { 0x50, 9 }, - { 0xA4, 10 }, - { 0x294, 12 }, - { 0x52B, 13 }, - { 0x52A, 13 }, - { 0x52D, 13 }, - { 0x52C, 13 }, - { 0x52F, 13 }, - { 0x52E, 13 }, - { 0xE, 4 }, - { 0x1A, 5 }, - { 0x4, 5 }, - { 0x28, 6 }, - { 0x29, 6 }, - { 0xF, 4 }, - { 0xB, 6 }, - { 0x5F, 7 }, - { 0xBD, 8 } - } -}; - -static const uint16_t ac_bias_2[16][32][2] = { + { 3, 3 }, { 25, 5 }, { 14, 9 }, { 6, 9 }, { 15, 10 }, { 16, 12 }, + { 18, 13 }, { 17, 13 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, + { 8, 9 }, { 13, 7 }, { 29, 6 }, { 4, 4 }, { 10, 3 }, { 0, 3 }, + { 9, 3 }, { 26, 6 }, { 27, 6 }, { 12, 5 }, { 11, 5 }, { 5, 6 }, + { 7, 8 }, { 31, 8 }, { 30, 7 }, { 1, 4 }, { 24, 5 }, { 2, 5 }, + { 23, 4 }, { 28, 4 }, + }, { /* AC bias group 3, table 0 */ - { 0x3, 4 }, - { 0x9, 6 }, - { 0xD0, 8 }, - { 0x1A3, 9 }, - { 0x344, 10 }, - { 0xD14, 12 }, - { 0x1A2B, 13 }, - { 0x4, 4 }, - { 0x15, 7 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0xE, 4 }, - { 0x9, 4 }, - { 0x1B, 5 }, - { 0xA, 5 }, - { 0x14, 5 }, - { 0xD, 5 }, - { 0x2A, 6 }, - { 0x14, 7 }, - { 0x68B, 11 }, - { 0x1A2A, 13 }, - { 0x8, 4 }, - { 0xB, 5 }, - { 0x2B, 6 }, - { 0xB, 6 }, - { 0x69, 7 }, - { 0x35, 6 }, - { 0x8, 6 }, - { 0x7, 4 }, - { 0xC, 5 } + { 9, 3 }, { 29, 6 }, { 1, 6 }, { 20, 7 }, { 8, 7 }, { 26, 6 }, + { 0, 4 }, { 7, 4 }, { 16, 5 }, { 24, 5 }, { 31, 5 }, { 18, 5 }, + { 30, 4 }, { 23, 4 }, { 14, 4 }, { 17, 5 }, { 19, 6 }, { 25, 6 }, + { 11, 4 }, { 12, 4 }, { 2, 8 }, { 4, 10 }, { 5, 12 }, { 22, 13 }, + { 6, 13 }, { 21, 11 }, { 3, 9 }, { 27, 7 }, { 28, 6 }, { 15, 5 }, + { 13, 4 }, { 10, 4 }, }, { /* AC bias group 3, table 1 */ - { 0xA, 4 }, - { 0x3C, 6 }, - { 0x32, 7 }, - { 0x30, 7 }, - { 0xC5, 9 }, - { 0x621, 12 }, - { 0x620, 12 }, - { 0x1F, 5 }, - { 0x33, 7 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x4, 4 }, - { 0xD, 5 }, - { 0x26, 6 }, - { 0x27, 6 }, - { 0x14, 6 }, - { 0x63, 8 }, - { 0x189, 10 }, - { 0x623, 12 }, - { 0x622, 12 }, - { 0xB, 4 }, - { 0x12, 5 }, - { 0x3D, 6 }, - { 0x22, 6 }, - { 0x15, 6 }, - { 0xB, 5 }, - { 0x23, 6 }, - { 0x7, 4 }, - { 0x10, 5 } + { 10, 3 }, { 9, 3 }, { 14, 4 }, { 18, 6 }, { 27, 6 }, { 28, 5 }, + { 3, 7 }, { 6, 12 }, { 5, 12 }, { 22, 12 }, { 21, 12 }, { 20, 10 }, + { 4, 9 }, { 19, 8 }, { 2, 7 }, { 8, 7 }, { 15, 5 }, { 30, 4 }, + { 31, 5 }, { 26, 6 }, { 29, 6 }, { 24, 5 }, { 16, 6 }, { 17, 6 }, + { 0, 4 }, { 23, 4 }, { 13, 4 }, { 12, 4 }, { 11, 4 }, { 1, 6 }, + { 25, 6 }, { 7, 5 }, }, { /* AC bias group 3, table 2 */ - { 0xF, 4 }, - { 0xC, 5 }, - { 0x43, 7 }, - { 0x10, 6 }, - { 0x44, 8 }, - { 0x114, 10 }, - { 0x455, 12 }, - { 0x18, 5 }, - { 0x23, 7 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0x9, 4 }, - { 0x19, 5 }, - { 0x9, 5 }, - { 0x17, 6 }, - { 0x16, 6 }, - { 0x42, 7 }, - { 0x8B, 9 }, - { 0x454, 12 }, - { 0x457, 12 }, - { 0x456, 12 }, - { 0xB, 4 }, - { 0x15, 5 }, - { 0xA, 5 }, - { 0x29, 6 }, - { 0x20, 6 }, - { 0xD, 5 }, - { 0x28, 6 }, - { 0x7, 4 }, - { 0x11, 5 } + { 10, 3 }, { 9, 3 }, { 3, 6 }, { 4, 8 }, { 5, 10 }, { 20, 12 }, + { 6, 12 }, { 22, 12 }, { 21, 12 }, { 19, 9 }, { 8, 7 }, { 15, 5 }, + { 25, 5 }, { 17, 6 }, { 16, 6 }, { 1, 5 }, { 28, 5 }, { 30, 4 }, + { 27, 6 }, { 18, 7 }, { 2, 7 }, { 31, 5 }, { 13, 4 }, { 29, 6 }, + { 26, 6 }, { 24, 5 }, { 23, 4 }, { 7, 5 }, { 14, 5 }, { 12, 4 }, + { 11, 4 }, { 0, 4 }, }, { /* AC bias group 3, table 3 */ - { 0x1, 3 }, - { 0x1A, 5 }, - { 0x29, 6 }, - { 0x2A, 6 }, - { 0xA0, 8 }, - { 0x285, 10 }, - { 0x1425, 13 }, - { 0x2, 5 }, - { 0x0, 7 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0x8, 4 }, - { 0x12, 5 }, - { 0x1, 6 }, - { 0x51, 7 }, - { 0x1, 7 }, - { 0x143, 9 }, - { 0x508, 11 }, - { 0x1424, 13 }, - { 0x1427, 13 }, - { 0x1426, 13 }, - { 0xF, 4 }, - { 0x1C, 5 }, - { 0x3, 5 }, - { 0x37, 6 }, - { 0x2B, 6 }, - { 0x13, 5 }, - { 0x36, 6 }, - { 0x1D, 5 }, - { 0x1, 5 } + { 8, 7 }, { 17, 7 }, { 15, 6 }, { 31, 5 }, { 7, 5 }, { 25, 5 }, + { 0, 3 }, { 9, 3 }, { 10, 3 }, { 13, 4 }, { 14, 5 }, { 28, 5 }, + { 4, 8 }, { 19, 11 }, { 20, 13 }, { 6, 13 }, { 22, 13 }, { 21, 13 }, + { 5, 10 }, { 18, 9 }, { 16, 7 }, { 2, 6 }, { 3, 6 }, { 27, 6 }, + { 12, 4 }, { 11, 4 }, { 1, 5 }, { 29, 6 }, { 26, 6 }, { 24, 5 }, + { 30, 5 }, { 23, 4 }, }, { /* AC bias group 3, table 4 */ - { 0x4, 3 }, - { 0x1F, 5 }, - { 0x3D, 6 }, - { 0x6, 5 }, - { 0x16, 7 }, - { 0x53, 9 }, - { 0x14A, 11 }, - { 0x34, 6 }, - { 0x2A, 8 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0x1C, 5 }, - { 0x37, 6 }, - { 0x17, 7 }, - { 0x2B, 8 }, - { 0x28, 8 }, - { 0xA4, 10 }, - { 0x52D, 13 }, - { 0x52C, 13 }, - { 0x52F, 13 }, - { 0x52E, 13 }, - { 0x0, 3 }, - { 0x1D, 5 }, - { 0x7, 5 }, - { 0x4, 5 }, - { 0x35, 6 }, - { 0x14, 5 }, - { 0x36, 6 }, - { 0x15, 5 }, - { 0x3C, 6 } + { 23, 3 }, { 26, 5 }, { 17, 8 }, { 18, 10 }, { 6, 11 }, { 20, 13 }, + { 19, 13 }, { 22, 13 }, { 21, 13 }, { 5, 9 }, { 8, 8 }, { 16, 8 }, + { 4, 7 }, { 15, 7 }, { 3, 5 }, { 25, 5 }, { 9, 3 }, { 10, 3 }, + { 0, 3 }, { 28, 5 }, { 30, 5 }, { 11, 4 }, { 12, 4 }, { 7, 6 }, + { 27, 6 }, { 29, 6 }, { 14, 6 }, { 13, 5 }, { 24, 5 }, { 31, 6 }, + { 2, 6 }, { 1, 5 }, }, { /* AC bias group 3, table 5 */ - { 0x4, 3 }, - { 0xA, 4 }, - { 0x7, 5 }, - { 0x1D, 5 }, - { 0x9, 6 }, - { 0x1F3, 9 }, - { 0x7C7, 11 }, - { 0x8, 6 }, - { 0x1F0, 9 }, - { 0x3, 3 }, - { 0x2, 3 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x17, 5 }, - { 0x7D, 7 }, - { 0x1F2, 9 }, - { 0x7C6, 11 }, - { 0x7C5, 11 }, - { 0x1F12, 13 }, - { 0x3E27, 14 }, - { 0x3E26, 14 }, - { 0x1F11, 13 }, - { 0x1F10, 13 }, - { 0x0, 3 }, - { 0x1E, 5 }, - { 0x6, 5 }, - { 0x39, 6 }, - { 0x38, 6 }, - { 0x3F, 6 }, - { 0x2C, 6 }, - { 0x5, 5 }, - { 0x2D, 6 } + { 23, 3 }, { 7, 6 }, { 4, 6 }, { 30, 5 }, { 25, 5 }, { 2, 5 }, + { 10, 3 }, { 9, 3 }, { 0, 3 }, { 1, 4 }, { 29, 6 }, { 31, 6 }, + { 13, 5 }, { 12, 4 }, { 11, 4 }, { 27, 6 }, { 26, 6 }, { 3, 5 }, + { 24, 5 }, { 8, 9 }, { 22, 13 }, { 21, 13 }, { 18, 13 }, { 20, 14 }, + { 19, 14 }, { 17, 11 }, { 16, 11 }, { 6, 11 }, { 15, 9 }, { 5, 9 }, + { 14, 7 }, { 28, 6 }, }, { /* AC bias group 3, table 6 */ - { 0x2, 3 }, - { 0x7, 4 }, - { 0x18, 5 }, - { 0x3, 4 }, - { 0x5, 5 }, - { 0x35, 7 }, - { 0x4F, 9 }, - { 0x12, 7 }, - { 0x4E5, 13 }, - { 0x5, 3 }, - { 0x4, 3 }, - { 0xD, 4 }, - { 0xE, 4 }, - { 0x33, 6 }, - { 0x26, 8 }, - { 0x9D, 10 }, - { 0x4E4, 13 }, - { 0x4E7, 13 }, - { 0x4E6, 13 }, - { 0x4E1, 13 }, - { 0x4E0, 13 }, - { 0x4E3, 13 }, - { 0x4E2, 13 }, - { 0x0, 3 }, - { 0x1F, 5 }, - { 0xC, 5 }, - { 0x3D, 6 }, - { 0x3C, 6 }, - { 0x32, 6 }, - { 0x34, 7 }, - { 0x1B, 6 }, - { 0x8, 6 } + { 23, 3 }, { 31, 6 }, { 7, 7 }, { 14, 8 }, { 20, 13 }, { 19, 13 }, + { 22, 13 }, { 21, 13 }, { 16, 13 }, { 8, 13 }, { 18, 13 }, { 17, 13 }, + { 15, 10 }, { 6, 9 }, { 4, 5 }, { 3, 4 }, { 0, 3 }, { 25, 5 }, + { 29, 7 }, { 5, 7 }, { 30, 6 }, { 1, 4 }, { 10, 3 }, { 9, 3 }, + { 2, 5 }, { 28, 6 }, { 13, 6 }, { 11, 4 }, { 12, 4 }, { 27, 6 }, + { 26, 6 }, { 24, 5 }, }, { /* AC bias group 3, table 7 */ - { 0x0, 3 }, - { 0x4, 4 }, - { 0x1C, 5 }, - { 0xF, 4 }, - { 0x2, 4 }, - { 0x7, 5 }, - { 0x75, 7 }, - { 0xE8, 8 }, - { 0x1D2A, 13 }, - { 0x5, 3 }, - { 0x4, 3 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x77, 7 }, - { 0xE96, 12 }, - { 0x3A57, 14 }, - { 0x3A56, 14 }, - { 0x3A5D, 14 }, - { 0x3A5C, 14 }, - { 0x3A5F, 14 }, - { 0x3A5E, 14 }, - { 0x1D29, 13 }, - { 0x1D28, 13 }, - { 0x3, 3 }, - { 0x6, 5 }, - { 0xA, 5 }, - { 0x2C, 7 }, - { 0x17, 6 }, - { 0x76, 7 }, - { 0x1D3, 9 }, - { 0x3A4, 10 }, - { 0x2D, 7 } + { 0, 3 }, { 4, 4 }, { 24, 5 }, { 5, 5 }, { 1, 4 }, { 25, 5 }, + { 26, 7 }, { 31, 7 }, { 27, 6 }, { 23, 3 }, { 10, 3 }, { 9, 3 }, + { 12, 4 }, { 11, 4 }, { 2, 5 }, { 7, 8 }, { 30, 10 }, { 22, 13 }, + { 21, 13 }, { 8, 13 }, { 16, 14 }, { 15, 14 }, { 14, 12 }, { 18, 14 }, + { 17, 14 }, { 20, 14 }, { 19, 14 }, { 29, 9 }, { 6, 7 }, { 28, 7 }, + { 13, 7 }, { 3, 4 }, }, { /* AC bias group 3, table 8 */ - { 0xA, 4 }, - { 0x24, 6 }, - { 0xBF, 8 }, - { 0x85, 8 }, - { 0x211, 10 }, - { 0x842, 12 }, - { 0x1087, 13 }, - { 0x18, 5 }, - { 0x20, 6 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0x7, 4 }, - { 0x13, 5 }, - { 0x25, 6 }, - { 0x5E, 7 }, - { 0x43, 7 }, - { 0xBE, 8 }, - { 0x109, 9 }, - { 0x1086, 13 }, - { 0x841, 12 }, - { 0x840, 12 }, - { 0xF, 4 }, - { 0x1, 4 }, - { 0x11, 5 }, - { 0x0, 5 }, - { 0x2E, 6 }, - { 0x19, 5 }, - { 0x1, 5 }, - { 0x6, 4 }, - { 0x16, 5 } + { 26, 5 }, { 29, 5 }, { 24, 4 }, { 9, 3 }, { 10, 3 }, { 30, 4 }, + { 13, 4 }, { 8, 6 }, { 22, 12 }, { 21, 12 }, { 5, 12 }, { 20, 13 }, + { 6, 13 }, { 4, 10 }, { 19, 9 }, { 3, 8 }, { 17, 7 }, { 25, 5 }, + { 1, 6 }, { 15, 6 }, { 14, 5 }, { 0, 4 }, { 31, 5 }, { 27, 6 }, + { 16, 7 }, { 18, 8 }, { 2, 8 }, { 7, 5 }, { 28, 5 }, { 12, 4 }, + { 11, 4 }, { 23, 4 }, }, { /* AC bias group 3, table 9 */ - { 0x2, 3 }, - { 0xF, 5 }, - { 0x6F, 7 }, - { 0x61, 7 }, - { 0x374, 10 }, - { 0x1BA8, 13 }, - { 0x3753, 14 }, - { 0x12, 5 }, - { 0x36, 6 }, - { 0x0, 3 }, - { 0x1, 3 }, - { 0xA, 4 }, - { 0xB, 4 }, - { 0x1A, 5 }, - { 0x31, 6 }, - { 0x60, 7 }, - { 0xDC, 8 }, - { 0x1BB, 9 }, - { 0x6EB, 11 }, - { 0x1BAB, 13 }, - { 0x3752, 14 }, - { 0x3755, 14 }, - { 0x3754, 14 }, - { 0xE, 4 }, - { 0x6, 4 }, - { 0x13, 5 }, - { 0xE, 5 }, - { 0x3E, 6 }, - { 0x8, 4 }, - { 0x1E, 5 }, - { 0x19, 5 }, - { 0x3F, 6 } + { 9, 3 }, { 10, 3 }, { 0, 3 }, { 24, 4 }, { 26, 5 }, { 1, 5 }, + { 28, 4 }, { 7, 5 }, { 25, 5 }, { 11, 4 }, { 12, 4 }, { 15, 7 }, + { 3, 7 }, { 14, 6 }, { 30, 5 }, { 13, 5 }, { 8, 6 }, { 16, 8 }, + { 4, 10 }, { 5, 13 }, { 20, 14 }, { 6, 14 }, { 22, 14 }, { 21, 14 }, + { 19, 13 }, { 18, 11 }, { 17, 9 }, { 2, 7 }, { 23, 4 }, { 29, 5 }, + { 27, 6 }, { 31, 6 }, }, { /* AC bias group 3, table 10 */ - { 0x3, 3 }, - { 0x1C, 5 }, - { 0x25, 6 }, - { 0x24, 6 }, - { 0x1DA, 9 }, - { 0x1DBD, 13 }, - { 0x3B7C, 14 }, - { 0x3C, 6 }, - { 0x3D, 6 }, - { 0x0, 3 }, - { 0x1, 3 }, - { 0xB, 4 }, - { 0xA, 4 }, - { 0xB, 5 }, - { 0x77, 7 }, - { 0xEC, 8 }, - { 0x3B6, 10 }, - { 0x76E, 11 }, - { 0x1DBF, 13 }, - { 0x76FB, 15 }, - { 0x76FA, 15 }, - { 0x3B79, 14 }, - { 0x3B78, 14 }, - { 0xD, 4 }, - { 0x1F, 5 }, - { 0x13, 5 }, - { 0xA, 5 }, - { 0x8, 5 }, - { 0xC, 4 }, - { 0x8, 4 }, - { 0x9, 5 }, - { 0x3A, 6 } + { 9, 3 }, { 10, 3 }, { 27, 5 }, { 30, 5 }, { 26, 5 }, { 13, 5 }, + { 0, 3 }, { 29, 4 }, { 3, 6 }, { 2, 6 }, { 25, 5 }, { 12, 4 }, + { 11, 4 }, { 28, 4 }, { 23, 4 }, { 1, 5 }, { 31, 6 }, { 15, 8 }, + { 4, 9 }, { 16, 10 }, { 17, 11 }, { 22, 14 }, { 21, 14 }, { 5, 13 }, + { 6, 14 }, { 20, 15 }, { 19, 15 }, { 18, 13 }, { 14, 7 }, { 7, 6 }, + { 8, 6 }, { 24, 5 }, }, { /* AC bias group 3, table 11 */ - { 0x5, 3 }, - { 0x3, 4 }, - { 0x4, 5 }, - { 0x10, 5 }, - { 0x8F, 8 }, - { 0x475, 11 }, - { 0x11D1, 13 }, - { 0x79, 7 }, - { 0x27, 6 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0x1, 4 }, - { 0x0, 4 }, - { 0x26, 6 }, - { 0x46, 7 }, - { 0x11C, 9 }, - { 0x477, 11 }, - { 0x8ED, 12 }, - { 0x11D0, 13 }, - { 0x11D3, 13 }, - { 0x11D2, 13 }, - { 0x11D9, 13 }, - { 0x11D8, 13 }, - { 0xD, 4 }, - { 0x1F, 5 }, - { 0x12, 5 }, - { 0x5, 5 }, - { 0x3D, 6 }, - { 0xC, 4 }, - { 0xE, 4 }, - { 0x22, 6 }, - { 0x78, 7 } + { 12, 4 }, { 11, 4 }, { 2, 5 }, { 26, 5 }, { 1, 4 }, { 9, 3 }, + { 10, 3 }, { 3, 5 }, { 30, 6 }, { 14, 7 }, { 15, 9 }, { 18, 13 }, + { 6, 13 }, { 20, 13 }, { 19, 13 }, { 5, 11 }, { 22, 13 }, { 21, 13 }, + { 17, 12 }, { 16, 11 }, { 4, 8 }, { 25, 5 }, { 13, 6 }, { 8, 6 }, + { 0, 3 }, { 28, 4 }, { 23, 4 }, { 29, 4 }, { 31, 7 }, { 7, 7 }, + { 27, 6 }, { 24, 5 }, }, { /* AC bias group 3, table 12 */ - { 0x5, 3 }, - { 0xC, 4 }, - { 0x1B, 5 }, - { 0x0, 4 }, - { 0x6, 6 }, - { 0x3E2, 10 }, - { 0x3E3D, 14 }, - { 0xF, 7 }, - { 0x34, 6 }, - { 0x3, 3 }, - { 0x2, 3 }, - { 0x1E, 5 }, - { 0x1D, 5 }, - { 0x7D, 7 }, - { 0x1F0, 9 }, - { 0x7C6, 11 }, - { 0x3E3C, 14 }, - { 0x3E3F, 14 }, - { 0x3E3E, 14 }, - { 0x3E39, 14 }, - { 0x3E38, 14 }, - { 0x3E3B, 14 }, - { 0x3E3A, 14 }, - { 0x8, 4 }, - { 0x1C, 5 }, - { 0x2, 5 }, - { 0x3F, 6 }, - { 0x35, 6 }, - { 0x9, 4 }, - { 0x1, 3 }, - { 0xE, 7 }, - { 0xF9, 8 } + { 3, 4 }, { 25, 5 }, { 4, 6 }, { 30, 7 }, { 7, 7 }, { 29, 3 }, + { 10, 3 }, { 9, 3 }, { 23, 4 }, { 28, 4 }, { 0, 3 }, { 1, 4 }, + { 8, 6 }, { 27, 6 }, { 2, 5 }, { 24, 5 }, { 12, 5 }, { 11, 5 }, + { 14, 9 }, { 5, 10 }, { 15, 11 }, { 20, 14 }, { 19, 14 }, { 22, 14 }, + { 21, 14 }, { 16, 14 }, { 6, 14 }, { 18, 14 }, { 17, 14 }, { 31, 8 }, + { 13, 7 }, { 26, 6 }, }, { /* AC bias group 3, table 13 */ - { 0x4, 3 }, - { 0xB, 4 }, - { 0x1, 4 }, - { 0xA, 4 }, - { 0x1E, 6 }, - { 0xE0, 9 }, - { 0xE1E, 13 }, - { 0x71, 8 }, - { 0x39, 7 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0xD, 5 }, - { 0xC, 5 }, - { 0x20, 7 }, - { 0x1C2, 10 }, - { 0x1C3F, 14 }, - { 0x1C3E, 14 }, - { 0xE19, 13 }, - { 0xE18, 13 }, - { 0xE1B, 13 }, - { 0xE1A, 13 }, - { 0xE1D, 13 }, - { 0xE1C, 13 }, - { 0x0, 4 }, - { 0x9, 5 }, - { 0x1D, 6 }, - { 0x1F, 6 }, - { 0x11, 6 }, - { 0x5, 4 }, - { 0x1, 3 }, - { 0x43, 8 }, - { 0x42, 8 } + { 23, 4 }, { 2, 4 }, { 29, 3 }, { 13, 7 }, { 31, 8 }, { 30, 8 }, + { 27, 6 }, { 24, 5 }, { 28, 4 }, { 12, 5 }, { 11, 5 }, { 5, 9 }, + { 14, 10 }, { 18, 13 }, { 17, 13 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, + { 21, 13 }, { 6, 13 }, { 16, 14 }, { 15, 14 }, { 7, 8 }, { 8, 7 }, + { 25, 6 }, { 4, 6 }, { 26, 6 }, { 0, 3 }, { 3, 4 }, { 1, 4 }, + { 10, 3 }, { 9, 3 }, }, { /* AC bias group 3, table 14 */ - { 0x4, 3 }, - { 0xD, 4 }, - { 0x7, 4 }, - { 0x2, 3 }, - { 0x14, 5 }, - { 0x16C, 9 }, - { 0x16D1, 13 }, - { 0x2DF, 10 }, - { 0x16E, 9 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x2C, 6 }, - { 0x2B, 6 }, - { 0x2DE, 10 }, - { 0x16D0, 13 }, - { 0x16D3, 13 }, - { 0x16D2, 13 }, - { 0x2DB5, 14 }, - { 0x2DB4, 14 }, - { 0x2DB7, 14 }, - { 0x2DB6, 14 }, - { 0x16D9, 13 }, - { 0x16D8, 13 }, - { 0xC, 5 }, - { 0x2A, 6 }, - { 0x5A, 7 }, - { 0x1B, 6 }, - { 0x1A, 6 }, - { 0x17, 5 }, - { 0xC, 4 }, - { 0x5B7, 11 }, - { 0x5B5, 11 } + { 9, 2 }, { 3, 3 }, { 23, 5 }, { 27, 6 }, { 26, 6 }, { 2, 4 }, + { 0, 3 }, { 4, 5 }, { 24, 6 }, { 12, 6 }, { 11, 6 }, { 25, 7 }, + { 5, 9 }, { 14, 13 }, { 6, 13 }, { 16, 13 }, { 15, 13 }, { 31, 11 }, + { 22, 13 }, { 21, 13 }, { 18, 14 }, { 17, 14 }, { 20, 14 }, { 19, 14 }, + { 30, 11 }, { 8, 9 }, { 13, 10 }, { 7, 10 }, { 28, 5 }, { 29, 4 }, + { 1, 4 }, { 10, 3 }, }, { /* AC bias group 3, table 15 */ - { 0x2, 2 }, - { 0xF, 4 }, - { 0x1C, 5 }, - { 0xC, 4 }, - { 0x3B, 6 }, - { 0x1AC, 9 }, - { 0x1AD8, 13 }, - { 0x35B3, 14 }, - { 0x35B2, 14 }, - { 0x1, 2 }, - { 0x0, 2 }, - { 0x69, 7 }, - { 0x68, 7 }, - { 0x35BD, 14 }, - { 0x35BC, 14 }, - { 0x35BF, 14 }, - { 0x35BE, 14 }, - { 0x35B9, 14 }, - { 0x35B8, 14 }, - { 0x35BB, 14 }, - { 0x35BA, 14 }, - { 0x35B5, 14 }, - { 0x35B4, 14 }, - { 0x1A9, 9 }, - { 0x1A8, 9 }, - { 0x35A, 10 }, - { 0xD7, 8 }, - { 0xD5, 8 }, - { 0x3A, 6 }, - { 0x1B, 5 }, - { 0x35B7, 14 }, - { 0x35B6, 14 } - } -}; - -static const uint16_t ac_bias_3[16][32][2] = { + { 10, 2 }, { 9, 2 }, { 0, 2 }, { 3, 4 }, { 12, 7 }, { 11, 7 }, + { 24, 9 }, { 23, 9 }, { 27, 8 }, { 5, 9 }, { 25, 10 }, { 6, 13 }, + { 8, 14 }, { 7, 14 }, { 22, 14 }, { 21, 14 }, { 31, 14 }, { 30, 14 }, + { 18, 14 }, { 17, 14 }, { 20, 14 }, { 19, 14 }, { 14, 14 }, { 13, 14 }, + { 16, 14 }, { 15, 14 }, { 26, 8 }, { 29, 5 }, { 2, 5 }, { 28, 6 }, + { 4, 6 }, { 1, 4 }, + }, { /* AC bias group 4, table 0 */ - { 0x0, 3 }, - { 0x10, 5 }, - { 0x72, 7 }, - { 0x71, 7 }, - { 0x154, 9 }, - { 0xAAB, 12 }, - { 0xAA8, 12 }, - { 0x14, 5 }, - { 0x70, 7 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0x3, 4 }, - { 0x11, 5 }, - { 0x73, 7 }, - { 0x54, 7 }, - { 0xAB, 8 }, - { 0x2AB, 10 }, - { 0x1553, 13 }, - { 0x1552, 13 }, - { 0x1555, 13 }, - { 0x1554, 13 }, - { 0xD, 4 }, - { 0x1E, 5 }, - { 0x12, 5 }, - { 0x3E, 6 }, - { 0x2B, 6 }, - { 0x2, 4 }, - { 0x3F, 6 }, - { 0x1D, 5 }, - { 0x13, 5 } + { 0, 3 }, { 28, 4 }, { 13, 4 }, { 9, 3 }, { 10, 3 }, { 1, 5 }, + { 14, 5 }, { 25, 5 }, { 31, 5 }, { 7, 5 }, { 16, 7 }, { 4, 9 }, + { 6, 12 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, { 5, 12 }, + { 18, 10 }, { 17, 8 }, { 27, 6 }, { 12, 4 }, { 11, 4 }, { 23, 4 }, + { 8, 7 }, { 3, 7 }, { 2, 7 }, { 15, 7 }, { 30, 5 }, { 24, 5 }, + { 26, 6 }, { 29, 6 }, }, { /* AC bias group 4, table 1 */ - { 0x3, 3 }, - { 0x1F, 5 }, - { 0x29, 6 }, - { 0x3D, 6 }, - { 0xC, 7 }, - { 0x69, 10 }, - { 0x345, 13 }, - { 0x2, 5 }, - { 0x28, 6 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0xE, 4 }, - { 0xC, 4 }, - { 0x15, 5 }, - { 0x7, 6 }, - { 0x1B, 8 }, - { 0x6B, 10 }, - { 0x6A, 10 }, - { 0x344, 13 }, - { 0x347, 13 }, - { 0x346, 13 }, - { 0x1A1, 12 }, - { 0x1A0, 12 }, - { 0xB, 4 }, - { 0x1A, 5 }, - { 0x12, 5 }, - { 0x0, 5 }, - { 0x3C, 6 }, - { 0x8, 4 }, - { 0x1B, 5 }, - { 0x13, 5 }, - { 0x1, 5 } + { 26, 5 }, { 31, 5 }, { 7, 5 }, { 4, 7 }, { 22, 12 }, { 21, 12 }, + { 18, 13 }, { 6, 13 }, { 20, 13 }, { 19, 13 }, { 5, 10 }, { 17, 10 }, + { 16, 10 }, { 15, 8 }, { 14, 6 }, { 10, 3 }, { 9, 3 }, { 0, 3 }, + { 28, 4 }, { 25, 5 }, { 30, 5 }, { 8, 6 }, { 2, 6 }, { 13, 5 }, + { 23, 4 }, { 12, 4 }, { 24, 5 }, { 29, 5 }, { 11, 4 }, { 27, 6 }, + { 3, 6 }, { 1, 5 }, }, { /* AC bias group 4, table 2 */ - { 0x4, 3 }, - { 0x4, 4 }, - { 0x3F, 6 }, - { 0x14, 5 }, - { 0x56, 7 }, - { 0x15C, 9 }, - { 0x15D5, 13 }, - { 0x3C, 6 }, - { 0x2A, 6 }, - { 0x0, 3 }, - { 0x1, 3 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0xC, 5 }, - { 0xAF, 8 }, - { 0x2BB, 10 }, - { 0x15D4, 13 }, - { 0x15D7, 13 }, - { 0x15D6, 13 }, - { 0x15D1, 13 }, - { 0x15D0, 13 }, - { 0x15D3, 13 }, - { 0x15D2, 13 }, - { 0xB, 4 }, - { 0x19, 5 }, - { 0xD, 5 }, - { 0x3E, 6 }, - { 0x31, 6 }, - { 0x7, 4 }, - { 0x5, 4 }, - { 0x3D, 6 }, - { 0x30, 6 } + { 9, 3 }, { 10, 3 }, { 1, 4 }, { 29, 4 }, { 13, 5 }, { 25, 5 }, + { 28, 4 }, { 0, 3 }, { 3, 5 }, { 8, 6 }, { 4, 7 }, { 5, 9 }, + { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, { 16, 13 }, { 6, 13 }, + { 18, 13 }, { 17, 13 }, { 15, 10 }, { 14, 8 }, { 23, 4 }, { 31, 6 }, + { 27, 6 }, { 24, 5 }, { 12, 4 }, { 11, 4 }, { 7, 6 }, { 30, 6 }, + { 26, 6 }, { 2, 6 }, }, { /* AC bias group 4, table 3 */ - { 0x5, 3 }, - { 0x8, 4 }, - { 0x1A, 5 }, - { 0x0, 4 }, - { 0x36, 6 }, - { 0x11, 8 }, - { 0x106, 12 }, - { 0xA, 7 }, - { 0x6E, 7 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0x3, 4 }, - { 0x2, 4 }, - { 0x6F, 7 }, - { 0x21, 9 }, - { 0x20F, 13 }, - { 0x20E, 13 }, - { 0x101, 12 }, - { 0x100, 12 }, - { 0x103, 12 }, - { 0x102, 12 }, - { 0x105, 12 }, - { 0x104, 12 }, - { 0xC, 4 }, - { 0x1E, 5 }, - { 0x3, 5 }, - { 0x3E, 6 }, - { 0x3F, 6 }, - { 0x9, 4 }, - { 0xE, 4 }, - { 0xB, 7 }, - { 0x9, 7 } + { 3, 4 }, { 18, 12 }, { 17, 12 }, { 20, 12 }, { 19, 12 }, { 22, 12 }, + { 21, 12 }, { 6, 12 }, { 16, 13 }, { 15, 13 }, { 14, 9 }, { 5, 8 }, + { 31, 7 }, { 7, 7 }, { 30, 7 }, { 25, 5 }, { 12, 4 }, { 11, 4 }, + { 9, 3 }, { 10, 3 }, { 1, 4 }, { 28, 4 }, { 0, 3 }, { 23, 4 }, + { 2, 5 }, { 4, 6 }, { 8, 7 }, { 13, 7 }, { 29, 4 }, { 24, 5 }, + { 26, 6 }, { 27, 6 }, }, { /* AC bias group 4, table 4 */ - { 0x2, 3 }, - { 0xE, 4 }, - { 0x1E, 5 }, - { 0xC, 4 }, - { 0x1F, 5 }, - { 0x6E, 7 }, - { 0xAD, 10 }, - { 0xAF, 10 }, - { 0x14, 7 }, - { 0x4, 3 }, - { 0x3, 3 }, - { 0x1A, 5 }, - { 0x17, 5 }, - { 0x2A, 8 }, - { 0x576, 13 }, - { 0xAEF, 14 }, - { 0xAEE, 14 }, - { 0x571, 13 }, - { 0x570, 13 }, - { 0x573, 13 }, - { 0x572, 13 }, - { 0x575, 13 }, - { 0x574, 13 }, - { 0x3, 4 }, - { 0x16, 5 }, - { 0x4, 5 }, - { 0x36, 6 }, - { 0xB, 6 }, - { 0xA, 4 }, - { 0x0, 3 }, - { 0x6F, 7 }, - { 0xAC, 10 } + { 29, 3 }, { 25, 5 }, { 8, 7 }, { 13, 8 }, { 31, 10 }, { 6, 10 }, + { 18, 13 }, { 17, 13 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, + { 14, 13 }, { 16, 14 }, { 15, 14 }, { 7, 10 }, { 27, 6 }, { 23, 4 }, + { 0, 3 }, { 10, 3 }, { 9, 3 }, { 28, 4 }, { 24, 5 }, { 12, 5 }, + { 3, 4 }, { 11, 5 }, { 26, 6 }, { 5, 7 }, { 30, 7 }, { 1, 4 }, + { 2, 5 }, { 4, 5 }, }, { /* AC bias group 4, table 5 */ - { 0x4, 3 }, - { 0x5, 4 }, - { 0x3, 3 }, - { 0x1, 3 }, - { 0x4, 4 }, - { 0x2F, 6 }, - { 0x526, 11 }, - { 0x1495, 13 }, - { 0xA6, 8 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x2D, 6 }, - { 0x2C, 6 }, - { 0x1494, 13 }, - { 0x1497, 13 }, - { 0x1496, 13 }, - { 0x1491, 13 }, - { 0x1490, 13 }, - { 0x1493, 13 }, - { 0x1492, 13 }, - { 0x293D, 14 }, - { 0x293C, 14 }, - { 0x293F, 14 }, - { 0x0, 3 }, - { 0x28, 6 }, - { 0xA5, 8 }, - { 0x148, 9 }, - { 0xA7, 8 }, - { 0x2E, 6 }, - { 0x15, 5 }, - { 0xA4E, 12 }, - { 0x293E, 14 } + { 23, 3 }, { 3, 3 }, { 4, 4 }, { 1, 4 }, { 2, 3 }, { 0, 3 }, + { 24, 6 }, { 26, 9 }, { 17, 13 }, { 16, 13 }, { 19, 13 }, { 18, 13 }, + { 13, 13 }, { 7, 13 }, { 15, 13 }, { 14, 13 }, { 6, 11 }, { 30, 12 }, + { 21, 14 }, { 20, 14 }, { 31, 14 }, { 22, 14 }, { 25, 8 }, { 8, 8 }, + { 27, 8 }, { 29, 5 }, { 12, 6 }, { 11, 6 }, { 28, 6 }, { 5, 6 }, + { 10, 3 }, { 9, 3 }, }, { /* AC bias group 4, table 6 */ - { 0x4, 3 }, - { 0x5, 4 }, - { 0x3, 3 }, - { 0x1, 3 }, - { 0x4, 4 }, - { 0x2F, 6 }, - { 0x526, 11 }, - { 0x1495, 13 }, - { 0xA6, 8 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x2D, 6 }, - { 0x2C, 6 }, - { 0x1494, 13 }, - { 0x1497, 13 }, - { 0x1496, 13 }, - { 0x1491, 13 }, - { 0x1490, 13 }, - { 0x1493, 13 }, - { 0x1492, 13 }, - { 0x293D, 14 }, - { 0x293C, 14 }, - { 0x293F, 14 }, - { 0x0, 3 }, - { 0x28, 6 }, - { 0xA5, 8 }, - { 0x148, 9 }, - { 0xA7, 8 }, - { 0x2E, 6 }, - { 0x15, 5 }, - { 0xA4E, 12 }, - { 0x293E, 14 } + { 23, 3 }, { 3, 3 }, { 4, 4 }, { 1, 4 }, { 2, 3 }, { 0, 3 }, + { 24, 6 }, { 26, 9 }, { 17, 13 }, { 16, 13 }, { 19, 13 }, { 18, 13 }, + { 13, 13 }, { 7, 13 }, { 15, 13 }, { 14, 13 }, { 6, 11 }, { 30, 12 }, + { 21, 14 }, { 20, 14 }, { 31, 14 }, { 22, 14 }, { 25, 8 }, { 8, 8 }, + { 27, 8 }, { 29, 5 }, { 12, 6 }, { 11, 6 }, { 28, 6 }, { 5, 6 }, + { 10, 3 }, { 9, 3 }, }, { /* AC bias group 4, table 7 */ - { 0x4, 3 }, - { 0x5, 4 }, - { 0x3, 3 }, - { 0x1, 3 }, - { 0x4, 4 }, - { 0x2F, 6 }, - { 0x526, 11 }, - { 0x1495, 13 }, - { 0xA6, 8 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x2D, 6 }, - { 0x2C, 6 }, - { 0x1494, 13 }, - { 0x1497, 13 }, - { 0x1496, 13 }, - { 0x1491, 13 }, - { 0x1490, 13 }, - { 0x1493, 13 }, - { 0x1492, 13 }, - { 0x293D, 14 }, - { 0x293C, 14 }, - { 0x293F, 14 }, - { 0x0, 3 }, - { 0x28, 6 }, - { 0xA5, 8 }, - { 0x148, 9 }, - { 0xA7, 8 }, - { 0x2E, 6 }, - { 0x15, 5 }, - { 0xA4E, 12 }, - { 0x293E, 14 } + { 23, 3 }, { 3, 3 }, { 4, 4 }, { 1, 4 }, { 2, 3 }, { 0, 3 }, + { 24, 6 }, { 26, 9 }, { 17, 13 }, { 16, 13 }, { 19, 13 }, { 18, 13 }, + { 13, 13 }, { 7, 13 }, { 15, 13 }, { 14, 13 }, { 6, 11 }, { 30, 12 }, + { 21, 14 }, { 20, 14 }, { 31, 14 }, { 22, 14 }, { 25, 8 }, { 8, 8 }, + { 27, 8 }, { 29, 5 }, { 12, 6 }, { 11, 6 }, { 28, 6 }, { 5, 6 }, + { 10, 3 }, { 9, 3 }, }, { /* AC bias group 4, table 8 */ - { 0x3, 3 }, - { 0x11, 5 }, - { 0x20, 6 }, - { 0x74, 7 }, - { 0x10D, 9 }, - { 0x863, 12 }, - { 0x860, 12 }, - { 0xA, 5 }, - { 0x75, 7 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xB, 4 }, - { 0xA, 4 }, - { 0x18, 5 }, - { 0x38, 6 }, - { 0x42, 7 }, - { 0x10F, 9 }, - { 0x10E, 9 }, - { 0x219, 10 }, - { 0x10C3, 13 }, - { 0x10C2, 13 }, - { 0x10C5, 13 }, - { 0x10C4, 13 }, - { 0xF, 4 }, - { 0x4, 4 }, - { 0x19, 5 }, - { 0xB, 5 }, - { 0x39, 6 }, - { 0x9, 4 }, - { 0x1B, 5 }, - { 0x1A, 5 }, - { 0x3B, 6 } + { 10, 3 }, { 9, 3 }, { 24, 4 }, { 7, 5 }, { 26, 5 }, { 0, 3 }, + { 2, 6 }, { 15, 7 }, { 6, 12 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, + { 21, 13 }, { 5, 12 }, { 18, 10 }, { 4, 9 }, { 17, 9 }, { 16, 9 }, + { 1, 5 }, { 28, 4 }, { 12, 4 }, { 11, 4 }, { 13, 5 }, { 25, 5 }, + { 30, 5 }, { 29, 5 }, { 14, 6 }, { 27, 6 }, { 3, 7 }, { 8, 7 }, + { 31, 6 }, { 23, 4 }, }, { /* AC bias group 4, table 9 */ - { 0x5, 3 }, - { 0x1, 4 }, - { 0x3E, 6 }, - { 0x1, 5 }, - { 0xE2, 8 }, - { 0x1C6F, 13 }, - { 0x38D9, 14 }, - { 0x39, 6 }, - { 0x1F, 6 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x0, 5 }, - { 0x70, 7 }, - { 0x1C7, 9 }, - { 0x38C, 10 }, - { 0x71A, 11 }, - { 0x38D8, 14 }, - { 0x38DB, 14 }, - { 0x38DA, 14 }, - { 0x38DD, 14 }, - { 0x38DC, 14 }, - { 0xD, 4 }, - { 0x1D, 5 }, - { 0xE, 5 }, - { 0x3F, 6 }, - { 0x3C, 6 }, - { 0xC, 4 }, - { 0x6, 4 }, - { 0x3D, 6 }, - { 0x1E, 6 } + { 13, 5 }, { 3, 5 }, { 1, 4 }, { 10, 3 }, { 9, 3 }, { 29, 4 }, + { 25, 5 }, { 31, 6 }, { 8, 6 }, { 12, 4 }, { 11, 4 }, { 0, 3 }, + { 28, 4 }, { 23, 4 }, { 14, 7 }, { 4, 8 }, { 16, 10 }, { 17, 11 }, + { 18, 14 }, { 6, 14 }, { 20, 14 }, { 19, 14 }, { 22, 14 }, { 21, 14 }, + { 5, 13 }, { 15, 9 }, { 7, 6 }, { 24, 5 }, { 27, 6 }, { 30, 6 }, + { 2, 6 }, { 26, 6 }, }, { /* AC bias group 4, table 10 */ - { 0x6, 3 }, - { 0xB, 4 }, - { 0x11, 5 }, - { 0x1E, 5 }, - { 0x74, 7 }, - { 0x3AA, 10 }, - { 0x1D5C, 13 }, - { 0x1, 6 }, - { 0x21, 6 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0x7, 4 }, - { 0x6, 4 }, - { 0x3E, 6 }, - { 0xEB, 8 }, - { 0x1D4, 9 }, - { 0xEAF, 12 }, - { 0x3ABB, 14 }, - { 0x3ABA, 14 }, - { 0x1D59, 13 }, - { 0x1D58, 13 }, - { 0x1D5B, 13 }, - { 0x1D5A, 13 }, - { 0xA, 4 }, - { 0x1C, 5 }, - { 0x1, 5 }, - { 0x3F, 6 }, - { 0x3B, 6 }, - { 0x1, 4 }, - { 0x9, 4 }, - { 0x20, 6 }, - { 0x0, 6 } + { 31, 6 }, { 7, 6 }, { 25, 5 }, { 28, 4 }, { 9, 3 }, { 10, 3 }, + { 12, 4 }, { 11, 4 }, { 30, 6 }, { 8, 6 }, { 2, 5 }, { 29, 4 }, + { 23, 4 }, { 1, 4 }, { 0, 3 }, { 24, 5 }, { 4, 7 }, { 15, 9 }, + { 5, 10 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, { 6, 13 }, + { 18, 14 }, { 17, 14 }, { 16, 12 }, { 14, 8 }, { 27, 6 }, { 3, 5 }, + { 13, 6 }, { 26, 6 }, }, { /* AC bias group 4, table 11 */ - { 0x4, 3 }, - { 0xA, 4 }, - { 0x17, 5 }, - { 0x4, 4 }, - { 0x16, 6 }, - { 0x16A, 9 }, - { 0x16B1, 13 }, - { 0x17, 7 }, - { 0x5B, 7 }, - { 0x6, 3 }, - { 0x7, 3 }, - { 0x1, 4 }, - { 0x0, 4 }, - { 0xA, 6 }, - { 0x2D7, 10 }, - { 0xB5A, 12 }, - { 0x16B0, 13 }, - { 0x16B3, 13 }, - { 0x16B2, 13 }, - { 0x2D6D, 14 }, - { 0x2D6C, 14 }, - { 0x2D6F, 14 }, - { 0x2D6E, 14 }, - { 0x6, 4 }, - { 0xA, 5 }, - { 0x4, 5 }, - { 0x2C, 6 }, - { 0x17, 6 }, - { 0x3, 4 }, - { 0x7, 4 }, - { 0x16, 7 }, - { 0xB4, 8 } + { 12, 4 }, { 11, 4 }, { 25, 5 }, { 13, 6 }, { 30, 7 }, { 7, 7 }, + { 28, 4 }, { 3, 4 }, { 24, 5 }, { 4, 6 }, { 27, 6 }, { 23, 4 }, + { 29, 4 }, { 0, 3 }, { 1, 4 }, { 26, 6 }, { 31, 8 }, { 5, 9 }, + { 16, 13 }, { 6, 13 }, { 18, 13 }, { 17, 13 }, { 15, 12 }, { 20, 14 }, + { 19, 14 }, { 22, 14 }, { 21, 14 }, { 14, 10 }, { 8, 7 }, { 2, 5 }, + { 9, 3 }, { 10, 3 }, }, { /* AC bias group 4, table 12 */ - { 0x5, 3 }, - { 0xD, 4 }, - { 0x5, 4 }, - { 0x9, 4 }, - { 0x33, 6 }, - { 0x193, 9 }, - { 0x192C, 13 }, - { 0x61, 8 }, - { 0x31, 7 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x10, 5 }, - { 0x11, 5 }, - { 0xC8, 8 }, - { 0x192F, 13 }, - { 0x325B, 14 }, - { 0x325A, 14 }, - { 0x1929, 13 }, - { 0x1928, 13 }, - { 0x192B, 13 }, - { 0x192A, 13 }, - { 0x325D, 14 }, - { 0x325C, 14 }, - { 0x18, 5 }, - { 0x1A, 6 }, - { 0x1B, 6 }, - { 0x65, 7 }, - { 0x19, 6 }, - { 0x4, 4 }, - { 0x7, 4 }, - { 0x60, 8 }, - { 0x324, 10 } + { 9, 2 }, { 28, 4 }, { 2, 4 }, { 30, 8 }, { 7, 8 }, { 8, 7 }, + { 27, 6 }, { 24, 6 }, { 25, 6 }, { 29, 4 }, { 11, 5 }, { 12, 5 }, + { 3, 4 }, { 0, 3 }, { 23, 5 }, { 13, 8 }, { 31, 10 }, { 18, 13 }, + { 17, 13 }, { 20, 13 }, { 19, 13 }, { 6, 13 }, { 16, 14 }, { 15, 14 }, + { 22, 14 }, { 21, 14 }, { 14, 13 }, { 5, 9 }, { 26, 7 }, { 4, 6 }, + { 1, 4 }, { 10, 3 }, }, { /* AC bias group 4, table 13 */ - { 0x6, 3 }, - { 0x0, 3 }, - { 0x2, 4 }, - { 0xF, 4 }, - { 0x39, 6 }, - { 0x1D9, 9 }, - { 0x1D82, 13 }, - { 0x761, 11 }, - { 0x3BE, 10 }, - { 0x1, 2 }, - { 0x2, 2 }, - { 0xF, 6 }, - { 0xE, 6 }, - { 0x762, 11 }, - { 0x3B07, 14 }, - { 0x3B06, 14 }, - { 0x3B1D, 14 }, - { 0x3B1C, 14 }, - { 0x3B1F, 14 }, - { 0x3B1E, 14 }, - { 0x3B19, 14 }, - { 0x3B18, 14 }, - { 0x3B1B, 14 }, - { 0x38, 6 }, - { 0x1DE, 9 }, - { 0xED, 8 }, - { 0x3BF, 10 }, - { 0xEE, 8 }, - { 0x3A, 6 }, - { 0x6, 5 }, - { 0xEC0, 12 }, - { 0x3B1A, 14 } + { 1, 3 }, { 2, 4 }, { 29, 5 }, { 12, 6 }, { 11, 6 }, { 9, 2 }, + { 10, 2 }, { 0, 3 }, { 23, 6 }, { 4, 6 }, { 28, 6 }, { 30, 12 }, + { 6, 13 }, { 15, 14 }, { 14, 14 }, { 7, 11 }, { 13, 11 }, { 21, 14 }, + { 20, 14 }, { 31, 14 }, { 22, 14 }, { 17, 14 }, { 16, 14 }, { 19, 14 }, + { 18, 14 }, { 5, 9 }, { 25, 8 }, { 27, 8 }, { 24, 9 }, { 8, 10 }, + { 26, 10 }, { 3, 4 }, }, { /* AC bias group 4, table 14 */ - { 0x0, 2 }, - { 0x2, 3 }, - { 0xF, 5 }, - { 0x6, 4 }, - { 0x1C, 6 }, - { 0x1D0, 10 }, - { 0xE8C, 13 }, - { 0x1D1B, 14 }, - { 0x1D1A, 14 }, - { 0x3, 2 }, - { 0x2, 2 }, - { 0xEA, 9 }, - { 0xE9, 9 }, - { 0xE89, 13 }, - { 0xE88, 13 }, - { 0xE8B, 13 }, - { 0xE8A, 13 }, - { 0x1D65, 14 }, - { 0x1D64, 14 }, - { 0x1D67, 14 }, - { 0x1D66, 14 }, - { 0x1D61, 14 }, - { 0x1D60, 14 }, - { 0x3AD, 11 }, - { 0x1D63, 14 }, - { 0x1D62, 14 }, - { 0x1D1D, 14 }, - { 0x1D1C, 14 }, - { 0x3B, 7 }, - { 0x1D7, 10 }, - { 0x1D1F, 14 }, - { 0x1D1E, 14 } + { 0, 2 }, { 1, 3 }, { 3, 4 }, { 4, 6 }, { 5, 10 }, { 14, 13 }, + { 13, 13 }, { 16, 13 }, { 15, 13 }, { 6, 13 }, { 8, 14 }, { 7, 14 }, + { 27, 14 }, { 26, 14 }, { 31, 14 }, { 30, 14 }, { 12, 9 }, { 11, 9 }, + { 22, 14 }, { 21, 14 }, { 25, 14 }, { 24, 14 }, { 18, 14 }, { 17, 14 }, + { 20, 14 }, { 19, 14 }, { 23, 11 }, { 29, 10 }, { 28, 7 }, { 2, 5 }, + { 10, 2 }, { 9, 2 }, }, { /* AC bias group 4, table 15 */ - { 0x2, 2 }, - { 0xF, 4 }, - { 0x1C, 5 }, - { 0xC, 4 }, - { 0x3B, 6 }, - { 0x1AC, 9 }, - { 0x1AD8, 13 }, - { 0x35B3, 14 }, - { 0x35B2, 14 }, - { 0x1, 2 }, - { 0x0, 2 }, - { 0x69, 7 }, - { 0x68, 7 }, - { 0x35BD, 14 }, - { 0x35BC, 14 }, - { 0x35BF, 14 }, - { 0x35BE, 14 }, - { 0x35B9, 14 }, - { 0x35B8, 14 }, - { 0x35BB, 14 }, - { 0x35BA, 14 }, - { 0x35B5, 14 }, - { 0x35B4, 14 }, - { 0x1A9, 9 }, - { 0x1A8, 9 }, - { 0x35A, 10 }, - { 0xD7, 8 }, - { 0xD5, 8 }, - { 0x3A, 6 }, - { 0x1B, 5 }, - { 0x35B7, 14 }, - { 0x35B6, 14 } - } + { 10, 2 }, { 9, 2 }, { 0, 2 }, { 3, 4 }, { 12, 7 }, { 11, 7 }, + { 24, 9 }, { 23, 9 }, { 27, 8 }, { 5, 9 }, { 25, 10 }, { 6, 13 }, + { 8, 14 }, { 7, 14 }, { 22, 14 }, { 21, 14 }, { 31, 14 }, { 30, 14 }, + { 18, 14 }, { 17, 14 }, { 20, 14 }, { 19, 14 }, { 14, 14 }, { 13, 14 }, + { 16, 14 }, { 15, 14 }, { 26, 8 }, { 29, 5 }, { 2, 5 }, { 28, 6 }, + { 4, 6 }, { 1, 4 }, + }, }; #endif /* AVCODEC_VP3DATA_H */ diff --git a/libavcodec/vp4data.h b/libavcodec/vp4data.h index 69a009eff..156cfd011 100644 --- a/libavcodec/vp4data.h +++ b/libavcodec/vp4data.h @@ -109,1078 +109,864 @@ static const uint8_t vp4_mv_table_selector[32] = { 6, 6, 6, 6, 6, 6, 6, 6, }; -static const uint16_t vp4_mv_vlc[2][7][63][2] = { +static const uint8_t vp4_mv_vlc[2][7][63][2] = { { /* x-axis tables */ { - { 0x6A, 7 }, { 0x11A, 9 }, { 0x18E, 9 }, { 0x237, 10 }, - { 0x4A, 8 }, { 0x236, 10 }, { 0x7A, 8 }, { 0xD6, 9 }, - { 0x7E, 8 }, { 0x1FD, 10 }, { 0x8C, 8 }, { 0xD7, 9 }, - { 0x87, 8 }, { 0x183, 9 }, { 0x3C, 7 }, { 0x61, 7 }, - { 0x47, 7 }, { 0x69, 8 }, { 0x40, 7 }, { 0x48, 8 }, - { 0x49, 7 }, { 0x86, 8 }, { 0x13, 6 }, { 0xD2, 8 }, - { 0x1C, 6 }, { 0x42, 7 }, { 0x25, 6 }, { 0x1B, 6 }, - { 0x13, 5 }, { 0x5, 4 }, { 0x0, 2 }, { 0x7, 3 }, - { 0x5, 3 }, { 0x1B, 5 }, { 0x19, 5 }, { 0x19, 6 }, - { 0x8, 5 }, { 0x45, 7 }, { 0x1D, 6 }, { 0xC6, 8 }, - { 0x68, 7 }, { 0x90, 8 }, { 0x41, 7 }, { 0x4B, 8 }, - { 0x31, 7 }, { 0x18F, 9 }, { 0x62, 7 }, { 0x3E, 7 }, - { 0x44, 7 }, { 0x68, 8 }, { 0x30, 7 }, { 0x182, 9 }, - { 0xC0, 8 }, { 0x1A7, 9 }, { 0x91, 8 }, { 0x92, 9 }, - { 0x7B, 8 }, { 0xFF, 9 }, { 0x1A6, 9 }, { 0x1FC, 10 }, - { 0x6A, 8 }, { 0x93, 9 }, { 0x6B, 7 } + { 30, 2 }, { 36, 5 }, { 19, 8 }, { 55, 9 }, { 61, 9 }, + { 4, 8 }, { 43, 8 }, { 22, 6 }, { 29, 4 }, { 50, 7 }, + { 44, 7 }, { 35, 6 }, { 49, 8 }, { 17, 8 }, { 60, 8 }, + { 7, 9 }, { 11, 9 }, { 27, 6 }, { 24, 6 }, { 38, 6 }, + { 14, 7 }, { 6, 8 }, { 56, 8 }, { 47, 7 }, { 8, 8 }, + { 59, 10 }, { 9, 10 }, { 57, 9 }, { 18, 7 }, { 42, 7 }, + { 25, 7 }, { 21, 8 }, { 12, 8 }, { 48, 7 }, { 37, 7 }, + { 10, 8 }, { 1, 9 }, { 5, 10 }, { 3, 10 }, { 16, 7 }, + { 41, 8 }, { 54, 8 }, { 20, 7 }, { 26, 6 }, { 28, 5 }, + { 32, 3 }, { 52, 8 }, { 51, 9 }, { 13, 9 }, { 15, 7 }, + { 46, 7 }, { 39, 8 }, { 2, 9 }, { 45, 9 }, { 34, 5 }, + { 40, 7 }, { 23, 8 }, { 58, 9 }, { 53, 9 }, { 0, 7 }, + { 62, 7 }, { 33, 5 }, { 31, 3 }, }, { - { 0x39, 7 }, { 0x259, 10 }, { 0x1B, 8 }, { 0x1D1, 10 }, - { 0x137, 9 }, { 0x1D0, 10 }, { 0x1A, 8 }, { 0x1B5, 10 }, - { 0x1D, 8 }, { 0x4BC, 11 }, { 0x6C, 8 }, { 0x38, 9 }, - { 0x71, 8 }, { 0x2D, 9 }, { 0x7D, 8 }, { 0x75, 8 }, - { 0x19, 7 }, { 0xE9, 9 }, { 0x37, 7 }, { 0x15, 8 }, - { 0x1E, 7 }, { 0xDB, 9 }, { 0x4C, 7 }, { 0x70, 8 }, - { 0xD, 6 }, { 0xC, 7 }, { 0x27, 6 }, { 0x4, 6 }, - { 0x2, 4 }, { 0x0, 4 }, { 0x5, 3 }, { 0x7, 3 }, - { 0x6, 3 }, { 0x2, 3 }, { 0x8, 4 }, { 0x24, 6 }, - { 0xC, 5 }, { 0x3B, 7 }, { 0x1E, 6 }, { 0x9A, 8 }, - { 0xE, 6 }, { 0x69, 8 }, { 0x4A, 7 }, { 0x12D, 9 }, - { 0x35, 7 }, { 0xF9, 9 }, { 0x18, 7 }, { 0x7F, 8 }, - { 0xF, 7 }, { 0xF8, 9 }, { 0x7E, 8 }, { 0x25F, 10 }, - { 0x68, 8 }, { 0x2C, 9 }, { 0x14, 8 }, { 0x258, 10 }, - { 0x136, 9 }, { 0x4BD, 11 }, { 0x12E, 9 }, { 0x1B4, 10 }, - { 0x17, 8 }, { 0x39, 9 }, { 0x1F, 7 } + { 29, 4 }, { 27, 6 }, { 54, 8 }, { 19, 8 }, { 53, 9 }, + { 13, 9 }, { 60, 8 }, { 25, 7 }, { 6, 8 }, { 2, 8 }, + { 11, 9 }, { 61, 9 }, { 8, 8 }, { 48, 7 }, { 28, 4 }, + { 46, 7 }, { 16, 7 }, { 24, 6 }, { 40, 6 }, { 20, 7 }, + { 62, 7 }, { 33, 3 }, { 36, 5 }, { 52, 8 }, { 41, 8 }, + { 44, 7 }, { 10, 8 }, { 59, 10 }, { 7, 10 }, { 21, 9 }, + { 18, 7 }, { 23, 8 }, { 12, 8 }, { 0, 7 }, { 5, 10 }, + { 3, 10 }, { 17, 9 }, { 15, 8 }, { 37, 7 }, { 38, 6 }, + { 49, 9 }, { 45, 9 }, { 14, 8 }, { 50, 8 }, { 47, 8 }, + { 34, 4 }, { 35, 6 }, { 42, 7 }, { 55, 10 }, { 1, 10 }, + { 43, 9 }, { 58, 9 }, { 9, 11 }, { 57, 11 }, { 51, 10 }, + { 22, 7 }, { 39, 8 }, { 56, 9 }, { 4, 9 }, { 26, 6 }, + { 30, 3 }, { 32, 3 }, { 31, 3 }, }, { - { 0x29, 7 }, { 0x3CB, 10 }, { 0x1F5, 9 }, { 0x263, 10 }, - { 0x1F4, 9 }, { 0x3DA, 10 }, { 0x50, 8 }, { 0x260, 10 }, - { 0x1EC, 9 }, { 0x3D3, 10 }, { 0x109, 9 }, { 0x3D2, 10 }, - { 0x51, 8 }, { 0x792, 11 }, { 0xF3, 8 }, { 0x9A, 8 }, - { 0xF7, 8 }, { 0x132, 9 }, { 0xC1, 8 }, { 0x1E8, 9 }, - { 0x2A, 7 }, { 0x85, 8 }, { 0x61, 7 }, { 0x1F7, 9 }, - { 0x78, 7 }, { 0xC7, 8 }, { 0x23, 6 }, { 0x7C, 7 }, - { 0x12, 5 }, { 0xB, 5 }, { 0xE, 4 }, { 0xD, 4 }, - { 0x0, 2 }, { 0x5, 3 }, { 0x3, 3 }, { 0x4, 4 }, - { 0x19, 5 }, { 0x20, 6 }, { 0x3F, 6 }, { 0x43, 7 }, - { 0x62, 7 }, { 0x9F, 8 }, { 0x4E, 7 }, { 0x181, 9 }, - { 0x2B, 7 }, { 0x137, 9 }, { 0xF5, 8 }, { 0x89, 8 }, - { 0xC6, 8 }, { 0x262, 10 }, { 0x88, 8 }, { 0x3C8, 10 }, - { 0x1F6, 9 }, { 0x3CA, 10 }, { 0x9E, 8 }, { 0x261, 10 }, - { 0x136, 9 }, { 0x108, 9 }, { 0x133, 9 }, { 0x793, 11 }, - { 0x180, 9 }, { 0x3DB, 10 }, { 0x45, 7 } + { 32, 2 }, { 35, 4 }, { 6, 8 }, { 12, 8 }, { 0, 7 }, + { 20, 7 }, { 44, 7 }, { 29, 5 }, { 34, 3 }, { 37, 6 }, + { 57, 9 }, { 10, 9 }, { 21, 8 }, { 39, 7 }, { 50, 8 }, + { 47, 8 }, { 62, 7 }, { 26, 6 }, { 28, 5 }, { 7, 10 }, + { 55, 10 }, { 49, 10 }, { 3, 10 }, { 17, 9 }, { 58, 9 }, + { 15, 8 }, { 56, 9 }, { 45, 9 }, { 42, 7 }, { 54, 8 }, + { 41, 8 }, { 33, 3 }, { 60, 9 }, { 43, 9 }, { 18, 8 }, + { 22, 7 }, { 40, 7 }, { 48, 8 }, { 25, 8 }, { 36, 5 }, + { 31, 4 }, { 30, 4 }, { 24, 7 }, { 51, 10 }, { 13, 11 }, + { 59, 11 }, { 53, 10 }, { 1, 10 }, { 14, 8 }, { 19, 9 }, + { 11, 10 }, { 9, 10 }, { 46, 8 }, { 8, 9 }, { 5, 10 }, + { 61, 10 }, { 16, 8 }, { 27, 7 }, { 4, 9 }, { 2, 9 }, + { 52, 9 }, { 23, 9 }, { 38, 6 }, }, { - { 0x1, 6 }, { 0x1C7, 9 }, { 0x67, 8 }, { 0xB5, 9 }, - { 0x66, 8 }, { 0x139, 9 }, { 0x99, 8 }, { 0xB4, 9 }, - { 0xC3, 8 }, { 0x130, 9 }, { 0x0, 7 }, { 0x131, 9 }, - { 0x9E, 8 }, { 0xB7, 9 }, { 0x2C, 7 }, { 0x1, 7 }, - { 0x28, 7 }, { 0x138, 9 }, { 0x4B, 7 }, { 0x31, 8 }, - { 0x60, 7 }, { 0x91, 8 }, { 0x3, 6 }, { 0x9D, 8 }, - { 0x17, 6 }, { 0x4D, 7 }, { 0x31, 6 }, { 0x70, 7 }, - { 0x7, 5 }, { 0x3A, 6 }, { 0x7, 4 }, { 0x2, 4 }, - { 0xB, 4 }, { 0x1, 4 }, { 0xF, 4 }, { 0x8, 4 }, - { 0xD, 4 }, { 0x4, 4 }, { 0xA, 4 }, { 0xD, 5 }, - { 0x19, 5 }, { 0x2, 6 }, { 0x3B, 6 }, { 0x4A, 7 }, - { 0x15, 6 }, { 0xC2, 8 }, { 0x18, 6 }, { 0x32, 7 }, - { 0x72, 7 }, { 0x1C6, 9 }, { 0x29, 7 }, { 0x1C5, 9 }, - { 0x49, 7 }, { 0x121, 9 }, { 0x1B, 7 }, { 0x30, 8 }, - { 0x1A, 7 }, { 0x1C4, 9 }, { 0x9F, 8 }, { 0xB6, 9 }, - { 0x19, 7 }, { 0x120, 9 }, { 0x73, 7 } + { 10, 7 }, { 15, 7 }, { 0, 6 }, { 41, 6 }, { 22, 6 }, + { 33, 4 }, { 31, 4 }, { 55, 8 }, { 19, 8 }, { 60, 7 }, + { 56, 7 }, { 54, 7 }, { 28, 5 }, { 37, 4 }, { 16, 7 }, + { 50, 7 }, { 44, 6 }, { 14, 7 }, { 7, 9 }, { 3, 9 }, + { 59, 9 }, { 13, 9 }, { 24, 6 }, { 46, 6 }, { 47, 7 }, + { 4, 8 }, { 2, 8 }, { 39, 5 }, { 30, 4 }, { 35, 4 }, + { 61, 9 }, { 53, 9 }, { 21, 8 }, { 52, 7 }, { 43, 7 }, + { 18, 7 }, { 9, 9 }, { 11, 9 }, { 6, 8 }, { 25, 7 }, + { 17, 9 }, { 5, 9 }, { 23, 8 }, { 12, 8 }, { 58, 8 }, + { 38, 4 }, { 32, 4 }, { 20, 7 }, { 45, 8 }, { 8, 8 }, + { 26, 6 }, { 40, 5 }, { 36, 4 }, { 27, 7 }, { 57, 9 }, + { 51, 9 }, { 49, 9 }, { 1, 9 }, { 48, 7 }, { 62, 7 }, + { 29, 6 }, { 42, 6 }, { 34, 4 }, }, { - { 0x23, 6 }, { 0x1C8, 9 }, { 0x43, 8 }, { 0x110, 9 }, - { 0xC, 7 }, { 0x153, 9 }, { 0x22, 7 }, { 0x111, 9 }, - { 0xF, 7 }, { 0x42, 8 }, { 0x23, 7 }, { 0x1C9, 9 }, - { 0x2A, 7 }, { 0x1B, 8 }, { 0x73, 7 }, { 0x45, 7 }, - { 0x6E, 7 }, { 0x89, 8 }, { 0x6C, 7 }, { 0x1A, 8 }, - { 0x6F, 7 }, { 0xB6, 8 }, { 0xB, 6 }, { 0xE5, 8 }, - { 0x25, 6 }, { 0x20, 7 }, { 0x29, 6 }, { 0x4D, 7 }, - { 0x2, 5 }, { 0x14, 6 }, { 0x1A, 5 }, { 0x17, 5 }, - { 0x1E, 5 }, { 0x27, 6 }, { 0x18, 5 }, { 0x28, 6 }, - { 0x1F, 5 }, { 0x0, 5 }, { 0x6, 4 }, { 0x10, 5 }, - { 0x7, 4 }, { 0xB, 5 }, { 0x3, 4 }, { 0x4, 5 }, - { 0x1D, 5 }, { 0x2C, 6 }, { 0x19, 5 }, { 0x2B, 6 }, - { 0x9, 5 }, { 0x55, 7 }, { 0x38, 6 }, { 0xE, 7 }, - { 0x24, 6 }, { 0xA8, 8 }, { 0xA, 6 }, { 0x99, 8 }, - { 0x5A, 7 }, { 0x98, 8 }, { 0x6D, 7 }, { 0x152, 9 }, - { 0x2B, 7 }, { 0xB7, 8 }, { 0x1, 5 } + { 37, 5 }, { 62, 5 }, { 28, 5 }, { 4, 7 }, { 19, 8 }, + { 13, 8 }, { 51, 7 }, { 8, 7 }, { 43, 5 }, { 54, 6 }, + { 22, 6 }, { 42, 4 }, { 25, 7 }, { 9, 8 }, { 2, 8 }, + { 6, 7 }, { 10, 7 }, { 48, 5 }, { 29, 6 }, { 12, 7 }, + { 60, 7 }, { 41, 5 }, { 38, 4 }, { 40, 4 }, { 39, 5 }, + { 3, 9 }, { 7, 9 }, { 17, 8 }, { 15, 7 }, { 0, 6 }, + { 52, 6 }, { 24, 6 }, { 57, 8 }, { 55, 8 }, { 27, 7 }, + { 33, 6 }, { 35, 6 }, { 26, 6 }, { 53, 8 }, { 59, 9 }, + { 5, 9 }, { 49, 7 }, { 47, 6 }, { 45, 6 }, { 56, 7 }, + { 21, 8 }, { 61, 8 }, { 31, 5 }, { 34, 5 }, { 46, 5 }, + { 30, 5 }, { 18, 7 }, { 58, 7 }, { 16, 7 }, { 20, 7 }, + { 50, 6 }, { 1, 9 }, { 11, 9 }, { 23, 8 }, { 14, 7 }, + { 44, 5 }, { 32, 5 }, { 36, 5 }, }, { - { 0x3D, 6 }, { 0xB1, 8 }, { 0xDD, 8 }, { 0x1F6, 9 }, - { 0xC5, 8 }, { 0x188, 9 }, { 0x37, 7 }, { 0x3F, 8 }, - { 0x1E, 7 }, { 0x189, 9 }, { 0xF, 7 }, { 0x3E, 8 }, - { 0x6A, 7 }, { 0x1F7, 9 }, { 0x61, 7 }, { 0x79, 7 }, - { 0x18, 6 }, { 0xB0, 8 }, { 0xE, 6 }, { 0xB3, 8 }, - { 0xC, 6 }, { 0xDF, 8 }, { 0x6, 6 }, { 0xDC, 8 }, - { 0x19, 6 }, { 0xDE, 8 }, { 0x27, 6 }, { 0xE, 7 }, - { 0x1A, 6 }, { 0x63, 7 }, { 0xF, 5 }, { 0xE, 5 }, - { 0x14, 5 }, { 0x7C, 7 }, { 0x36, 6 }, { 0x6B, 7 }, - { 0x3F, 6 }, { 0x60, 7 }, { 0x8, 5 }, { 0x74, 7 }, - { 0x9, 5 }, { 0x78, 7 }, { 0x12, 5 }, { 0xD, 6 }, - { 0x15, 5 }, { 0x2D, 6 }, { 0x2, 4 }, { 0x1C, 5 }, - { 0x5, 4 }, { 0x3B, 6 }, { 0x0, 4 }, { 0x34, 6 }, - { 0x19, 5 }, { 0x26, 6 }, { 0x10, 5 }, { 0x75, 7 }, - { 0x2, 5 }, { 0x36, 7 }, { 0x23, 6 }, { 0xB2, 8 }, - { 0x22, 6 }, { 0xFA, 8 }, { 0x17, 5 } + { 50, 4 }, { 56, 5 }, { 22, 6 }, { 27, 7 }, { 10, 7 }, + { 46, 4 }, { 20, 6 }, { 43, 6 }, { 18, 6 }, { 8, 7 }, + { 11, 8 }, { 7, 8 }, { 38, 5 }, { 40, 5 }, { 48, 4 }, + { 16, 6 }, { 24, 6 }, { 28, 6 }, { 57, 7 }, { 6, 7 }, + { 31, 5 }, { 30, 5 }, { 54, 5 }, { 60, 6 }, { 58, 6 }, + { 42, 5 }, { 53, 6 }, { 26, 6 }, { 32, 5 }, { 44, 5 }, + { 17, 8 }, { 1, 8 }, { 59, 8 }, { 19, 8 }, { 45, 6 }, + { 62, 5 }, { 37, 7 }, { 14, 7 }, { 5, 9 }, { 9, 9 }, + { 4, 8 }, { 29, 7 }, { 52, 5 }, { 51, 6 }, { 12, 7 }, + { 35, 7 }, { 34, 6 }, { 23, 8 }, { 2, 8 }, { 25, 8 }, + { 21, 8 }, { 47, 5 }, { 39, 7 }, { 55, 7 }, { 49, 6 }, + { 41, 7 }, { 15, 7 }, { 0, 6 }, { 33, 7 }, { 61, 8 }, + { 3, 9 }, { 13, 9 }, { 36, 6 }, }, { - { 0x15, 5 }, { 0xDD, 8 }, { 0x3E, 7 }, { 0x16E, 9 }, - { 0x4C, 7 }, { 0x12, 8 }, { 0x5D, 7 }, { 0xB6, 8 }, - { 0x6F, 7 }, { 0x1F1, 9 }, { 0x69, 7 }, { 0x1F0, 9 }, - { 0x1D, 7 }, { 0x16F, 9 }, { 0x2, 6 }, { 0x6B, 7 }, - { 0xC, 6 }, { 0xDC, 8 }, { 0x68, 7 }, { 0x9B, 8 }, - { 0x7D, 7 }, { 0x9A, 8 }, { 0xD, 6 }, { 0x13, 8 }, - { 0x8, 6 }, { 0xF9, 8 }, { 0x2C, 6 }, { 0x12, 7 }, - { 0x33, 6 }, { 0x4F, 7 }, { 0xD, 5 }, { 0x5, 5 }, - { 0x12, 5 }, { 0x3F, 7 }, { 0x32, 6 }, { 0x13, 7 }, - { 0x3B, 6 }, { 0x5, 6 }, { 0x2F, 6 }, { 0x5A, 7 }, - { 0x3F, 6 }, { 0x1C, 7 }, { 0x3A, 6 }, { 0x8, 7 }, - { 0x36, 6 }, { 0x5C, 7 }, { 0x10, 5 }, { 0x0, 5 }, - { 0xC, 5 }, { 0x4E, 7 }, { 0x3, 5 }, { 0x6A, 7 }, - { 0xE, 5 }, { 0x3, 6 }, { 0x14, 5 }, { 0x1E, 6 }, - { 0x1C, 5 }, { 0xF, 6 }, { 0x18, 5 }, { 0x23, 6 }, - { 0x1E, 5 }, { 0x22, 6 }, { 0x2, 3 } - } + { 47, 5 }, { 14, 6 }, { 53, 6 }, { 43, 7 }, { 5, 8 }, + { 23, 8 }, { 37, 6 }, { 50, 5 }, { 24, 6 }, { 27, 7 }, + { 35, 7 }, { 31, 5 }, { 16, 6 }, { 22, 6 }, { 41, 7 }, + { 12, 7 }, { 57, 6 }, { 62, 3 }, { 48, 5 }, { 30, 5 }, + { 52, 5 }, { 55, 6 }, { 2, 7 }, { 33, 7 }, { 46, 5 }, + { 61, 6 }, { 59, 6 }, { 32, 5 }, { 4, 7 }, { 21, 8 }, + { 19, 8 }, { 49, 7 }, { 29, 7 }, { 54, 5 }, { 0, 5 }, + { 26, 6 }, { 39, 7 }, { 7, 8 }, { 3, 9 }, { 13, 9 }, + { 45, 7 }, { 6, 7 }, { 38, 6 }, { 58, 5 }, { 34, 6 }, + { 28, 6 }, { 18, 7 }, { 10, 7 }, { 51, 7 }, { 15, 7 }, + { 44, 6 }, { 17, 8 }, { 1, 8 }, { 8, 7 }, { 56, 5 }, + { 42, 6 }, { 36, 6 }, { 60, 5 }, { 11, 9 }, { 9, 9 }, + { 25, 8 }, { 20, 7 }, { 40, 6 }, + }, }, { /* y-axis tables */ { - { 0x52, 7 }, { 0x14C, 9 }, { 0x1FA, 9 }, { 0x124, 9 }, - { 0x82, 8 }, { 0x29E, 10 }, { 0x8E, 8 }, { 0x24B, 10 }, - { 0x9C, 8 }, { 0x3F7, 10 }, { 0x86, 8 }, { 0x114, 9 }, - { 0x83, 8 }, { 0x3A5, 10 }, { 0xFA, 8 }, { 0x4F, 7 }, - { 0xFB, 8 }, { 0x13B, 9 }, { 0xFC, 8 }, { 0x172, 9 }, - { 0x44, 7 }, { 0x173, 9 }, { 0x51, 7 }, { 0x87, 8 }, - { 0x5F, 7 }, { 0xBA, 8 }, { 0x26, 6 }, { 0x5E, 7 }, - { 0x16, 5 }, { 0x15, 5 }, { 0x6, 3 }, { 0x1, 2 }, - { 0x0, 2 }, { 0x1C, 5 }, { 0x1E, 5 }, { 0x75, 7 }, - { 0x3B, 6 }, { 0xFF, 8 }, { 0x25, 6 }, { 0xBB, 8 }, - { 0x7C, 7 }, { 0x8B, 8 }, { 0x48, 7 }, { 0x171, 9 }, - { 0x42, 7 }, { 0x14E, 9 }, { 0x46, 7 }, { 0xFE, 8 }, - { 0x40, 7 }, { 0x13A, 9 }, { 0x93, 8 }, { 0x115, 9 }, - { 0x8F, 8 }, { 0x3F6, 10 }, { 0x170, 9 }, { 0x29F, 10 }, - { 0x1D1, 9 }, { 0x24A, 10 }, { 0x1D3, 9 }, { 0x3A4, 10 }, - { 0x1D0, 9 }, { 0x14D, 9 }, { 0x50, 7 } + { 32, 2 }, { 31, 2 }, { 48, 7 }, { 4, 8 }, { 12, 8 }, + { 44, 7 }, { 10, 8 }, { 23, 8 }, { 20, 7 }, { 11, 9 }, + { 51, 9 }, { 41, 8 }, { 46, 7 }, { 6, 8 }, { 52, 8 }, + { 42, 7 }, { 3, 9 }, { 57, 10 }, { 7, 10 }, { 50, 8 }, + { 38, 6 }, { 26, 6 }, { 8, 8 }, { 49, 9 }, { 17, 9 }, + { 15, 7 }, { 62, 7 }, { 22, 7 }, { 0, 7 }, { 1, 9 }, + { 61, 9 }, { 45, 9 }, { 5, 10 }, { 55, 10 }, { 29, 5 }, + { 28, 5 }, { 54, 9 }, { 43, 9 }, { 19, 9 }, { 21, 9 }, + { 25, 8 }, { 39, 8 }, { 27, 7 }, { 24, 7 }, { 30, 3 }, + { 33, 5 }, { 60, 9 }, { 56, 9 }, { 59, 10 }, { 13, 10 }, + { 58, 9 }, { 35, 7 }, { 36, 6 }, { 34, 5 }, { 40, 7 }, + { 14, 8 }, { 16, 8 }, { 18, 8 }, { 2, 9 }, { 53, 10 }, + { 9, 10 }, { 47, 8 }, { 37, 8 }, }, { - { 0xDE, 8 }, { 0x223, 10 }, { 0x136, 9 }, { 0x7C5, 11 }, - { 0x12F, 9 }, { 0x4A1, 11 }, { 0x3D7, 10 }, { 0x7AC, 11 }, - { 0x133, 9 }, { 0x7C4, 11 }, { 0x1B8, 9 }, { 0x222, 10 }, - { 0x96, 8 }, { 0x251, 10 }, { 0x95, 8 }, { 0x1F0, 9 }, - { 0xDA, 8 }, { 0x110, 9 }, { 0x9A, 8 }, { 0x360, 10 }, - { 0xDD, 8 }, { 0x12E, 9 }, { 0x48, 7 }, { 0x92, 8 }, - { 0x78, 7 }, { 0x98, 8 }, { 0x27, 6 }, { 0x45, 7 }, - { 0x1A, 5 }, { 0x10, 5 }, { 0x5, 3 }, { 0x0, 2 }, - { 0x1, 2 }, { 0xE, 4 }, { 0xC, 4 }, { 0x23, 6 }, - { 0x3F, 6 }, { 0xF4, 8 }, { 0x7D, 7 }, { 0x89, 8 }, - { 0x7B, 7 }, { 0x1BE, 9 }, { 0xF9, 8 }, { 0x3E3, 10 }, - { 0xF3, 8 }, { 0x127, 9 }, { 0xDB, 8 }, { 0x1EA, 9 }, - { 0xD9, 8 }, { 0x6E7, 11 }, { 0x1BF, 9 }, { 0x4A0, 11 }, - { 0x1B1, 9 }, { 0x6E6, 11 }, { 0x137, 9 }, { 0x7AD, 11 }, - { 0x126, 9 }, { 0x6C2, 11 }, { 0x132, 9 }, { 0x6C3, 11 }, - { 0x129, 9 }, { 0x372, 10 }, { 0xF2, 8 } + { 31, 2 }, { 32, 2 }, { 29, 5 }, { 17, 9 }, { 11, 10 }, + { 1, 10 }, { 39, 8 }, { 27, 7 }, { 35, 6 }, { 22, 7 }, + { 23, 8 }, { 56, 9 }, { 45, 9 }, { 51, 11 }, { 5, 11 }, + { 13, 10 }, { 60, 9 }, { 14, 8 }, { 12, 8 }, { 21, 9 }, + { 4, 9 }, { 25, 8 }, { 58, 9 }, { 8, 9 }, { 18, 8 }, + { 2, 9 }, { 54, 9 }, { 26, 6 }, { 30, 3 }, { 34, 4 }, + { 28, 5 }, { 19, 10 }, { 57, 11 }, { 59, 11 }, { 52, 9 }, + { 48, 8 }, { 16, 8 }, { 46, 8 }, { 10, 9 }, { 61, 10 }, + { 53, 11 }, { 49, 11 }, { 20, 8 }, { 0, 8 }, { 41, 9 }, + { 50, 9 }, { 33, 4 }, { 24, 7 }, { 62, 8 }, { 44, 8 }, + { 37, 8 }, { 47, 9 }, { 7, 11 }, { 55, 11 }, { 6, 10 }, + { 40, 7 }, { 15, 9 }, { 9, 11 }, { 3, 11 }, { 43, 10 }, + { 42, 8 }, { 38, 7 }, { 36, 6 }, }, { - { 0x16, 7 }, { 0x9C, 9 }, { 0x13C, 9 }, { 0x9E, 10 }, - { 0x12B, 9 }, { 0xBA, 10 }, { 0x181, 9 }, { 0x317, 10 }, - { 0x84, 8 }, { 0x4E, 9 }, { 0x26, 8 }, { 0x316, 10 }, - { 0x180, 9 }, { 0x5C, 9 }, { 0xC1, 8 }, { 0x2F, 8 }, - { 0x10, 7 }, { 0x45, 9 }, { 0x12, 7 }, { 0x189, 9 }, - { 0x24, 7 }, { 0x13D, 9 }, { 0x66, 7 }, { 0x23, 8 }, - { 0x67, 7 }, { 0xC6, 8 }, { 0x24, 6 }, { 0x4B, 7 }, - { 0x11, 5 }, { 0x32, 6 }, { 0xD, 4 }, { 0x0, 3 }, - { 0x7, 3 }, { 0x5, 3 }, { 0x3, 3 }, { 0x3, 4 }, - { 0x5, 4 }, { 0x20, 6 }, { 0x8, 5 }, { 0x25, 7 }, - { 0x26, 6 }, { 0x4F, 8 }, { 0x61, 7 }, { 0x2B, 8 }, - { 0x4E, 7 }, { 0x18A, 9 }, { 0x43, 7 }, { 0x9F, 8 }, - { 0x14, 7 }, { 0x254, 10 }, { 0x94, 8 }, { 0x310, 10 }, - { 0x85, 8 }, { 0x311, 10 }, { 0x2A, 8 }, { 0xBB, 10 }, - { 0x18F, 9 }, { 0x255, 10 }, { 0x9D, 9 }, { 0x9F, 10 }, - { 0x18E, 9 }, { 0x44, 9 }, { 0x26, 7 } + { 31, 3 }, { 16, 7 }, { 61, 9 }, { 17, 9 }, { 23, 8 }, + { 18, 7 }, { 10, 8 }, { 9, 9 }, { 3, 10 }, { 59, 10 }, + { 48, 7 }, { 54, 8 }, { 43, 8 }, { 0, 7 }, { 13, 9 }, + { 5, 10 }, { 55, 10 }, { 15, 8 }, { 35, 4 }, { 38, 5 }, + { 20, 7 }, { 39, 7 }, { 62, 7 }, { 1, 9 }, { 58, 9 }, + { 41, 8 }, { 36, 4 }, { 34, 3 }, { 37, 6 }, { 8, 8 }, + { 52, 8 }, { 46, 7 }, { 28, 5 }, { 26, 6 }, { 50, 8 }, + { 49, 10 }, { 57, 10 }, { 4, 9 }, { 27, 7 }, { 40, 6 }, + { 44, 7 }, { 2, 9 }, { 21, 9 }, { 47, 8 }, { 33, 3 }, + { 12, 9 }, { 6, 9 }, { 14, 8 }, { 42, 7 }, { 51, 10 }, + { 53, 10 }, { 19, 9 }, { 45, 9 }, { 11, 10 }, { 7, 10 }, + { 25, 8 }, { 60, 9 }, { 56, 9 }, { 29, 6 }, { 22, 7 }, + { 24, 7 }, { 30, 4 }, { 32, 3 }, }, { - { 0x61, 7 }, { 0x12A, 9 }, { 0xD, 8 }, { 0x3BD, 10 }, - { 0x89, 8 }, { 0x109, 9 }, { 0x18E, 9 }, { 0x210, 10 }, - { 0x1D3, 9 }, { 0x211, 10 }, { 0x88, 8 }, { 0x19, 9 }, - { 0x85, 8 }, { 0x18, 9 }, { 0xE8, 8 }, { 0xCE, 8 }, - { 0x40, 7 }, { 0x119, 9 }, { 0x45, 7 }, { 0x1D2, 9 }, - { 0x4B, 7 }, { 0x1DD, 9 }, { 0x62, 7 }, { 0x94, 8 }, - { 0x75, 7 }, { 0xC, 7 }, { 0x27, 6 }, { 0xD, 7 }, - { 0x2, 5 }, { 0x26, 6 }, { 0x6, 4 }, { 0x1E, 5 }, - { 0xD, 4 }, { 0x1F, 5 }, { 0x1, 3 }, { 0xA, 4 }, - { 0x2, 3 }, { 0x7, 4 }, { 0xB, 4 }, { 0x0, 5 }, - { 0x1C, 5 }, { 0x76, 7 }, { 0x32, 6 }, { 0x7, 7 }, - { 0x24, 6 }, { 0xC0, 8 }, { 0x7, 6 }, { 0x41, 7 }, - { 0x2, 6 }, { 0x18F, 9 }, { 0x47, 7 }, { 0x1DC, 9 }, - { 0x43, 7 }, { 0x12B, 9 }, { 0xCF, 8 }, { 0x118, 9 }, - { 0xC6, 8 }, { 0x3BC, 10 }, { 0x8D, 8 }, { 0x3BF, 10 }, - { 0xC1, 8 }, { 0x3BE, 10 }, { 0x66, 7 } + { 39, 5 }, { 48, 6 }, { 13, 9 }, { 11, 9 }, { 2, 8 }, + { 43, 7 }, { 28, 5 }, { 25, 7 }, { 27, 7 }, { 46, 6 }, + { 34, 3 }, { 36, 3 }, { 30, 4 }, { 37, 4 }, { 16, 7 }, + { 47, 7 }, { 7, 10 }, { 9, 10 }, { 5, 9 }, { 12, 8 }, + { 52, 7 }, { 10, 8 }, { 4, 8 }, { 18, 7 }, { 55, 9 }, + { 17, 9 }, { 58, 8 }, { 50, 7 }, { 44, 6 }, { 23, 8 }, + { 1, 9 }, { 53, 9 }, { 20, 7 }, { 29, 6 }, { 26, 6 }, + { 35, 4 }, { 38, 4 }, { 45, 8 }, { 60, 8 }, { 0, 7 }, + { 22, 7 }, { 56, 8 }, { 6, 9 }, { 49, 9 }, { 42, 6 }, + { 62, 7 }, { 15, 8 }, { 54, 8 }, { 32, 4 }, { 40, 5 }, + { 14, 8 }, { 19, 9 }, { 8, 9 }, { 24, 7 }, { 41, 7 }, + { 51, 9 }, { 21, 9 }, { 57, 10 }, { 3, 10 }, { 61, 10 }, + { 59, 10 }, { 31, 5 }, { 33, 5 }, }, { - { 0x7, 6 }, { 0x14D, 9 }, { 0xA0, 8 }, { 0x9E, 9 }, - { 0xCF, 8 }, { 0x39C, 10 }, { 0xA1, 8 }, { 0x39D, 10 }, - { 0xAB, 8 }, { 0x1C5, 9 }, { 0x26, 7 }, { 0x14C, 9 }, - { 0x25, 7 }, { 0x19C, 9 }, { 0x3F, 7 }, { 0xE1, 8 }, - { 0x66, 7 }, { 0x1CF, 9 }, { 0x3E, 7 }, { 0x1C4, 9 }, - { 0x72, 7 }, { 0x4E, 8 }, { 0x6, 6 }, { 0xAA, 8 }, - { 0x1C, 6 }, { 0xE6, 8 }, { 0x32, 6 }, { 0x51, 7 }, - { 0x3B, 6 }, { 0x5, 6 }, { 0x1F, 5 }, { 0x18, 5 }, - { 0x2, 4 }, { 0x3A, 6 }, { 0x0, 4 }, { 0x36, 6 }, - { 0x5, 4 }, { 0x8, 5 }, { 0x8, 4 }, { 0x16, 5 }, - { 0x9, 4 }, { 0xD, 5 }, { 0x3, 4 }, { 0x2F, 6 }, - { 0x1E, 5 }, { 0x2E, 6 }, { 0x1A, 5 }, { 0x2B, 6 }, - { 0xC, 5 }, { 0x24, 7 }, { 0x1E, 6 }, { 0xE0, 8 }, - { 0x4, 6 }, { 0xA7, 8 }, { 0x54, 7 }, { 0x1C7, 9 }, - { 0x52, 7 }, { 0x19D, 9 }, { 0x3A, 7 }, { 0x9F, 9 }, - { 0x3B, 7 }, { 0x1C6, 9 }, { 0x37, 6 } + { 34, 4 }, { 52, 6 }, { 29, 6 }, { 22, 6 }, { 0, 6 }, + { 32, 4 }, { 42, 4 }, { 37, 5 }, { 49, 7 }, { 12, 7 }, + { 10, 7 }, { 21, 8 }, { 3, 9 }, { 59, 9 }, { 36, 4 }, + { 48, 5 }, { 41, 5 }, { 24, 6 }, { 58, 7 }, { 60, 7 }, + { 50, 6 }, { 18, 7 }, { 14, 7 }, { 38, 4 }, { 40, 4 }, + { 2, 8 }, { 6, 8 }, { 27, 7 }, { 56, 7 }, { 11, 9 }, + { 1, 9 }, { 53, 8 }, { 54, 7 }, { 23, 8 }, { 8, 8 }, + { 47, 6 }, { 39, 5 }, { 45, 6 }, { 43, 6 }, { 31, 5 }, + { 26, 6 }, { 16, 7 }, { 13, 9 }, { 57, 9 }, { 4, 8 }, + { 46, 5 }, { 35, 6 }, { 62, 6 }, { 51, 8 }, { 15, 8 }, + { 19, 9 }, { 9, 9 }, { 61, 9 }, { 55, 9 }, { 20, 7 }, + { 25, 8 }, { 5, 10 }, { 7, 10 }, { 17, 9 }, { 33, 6 }, + { 28, 6 }, { 44, 5 }, { 30, 5 }, }, { - { 0x2A, 6 }, { 0x39, 8 }, { 0x25, 7 }, { 0x115, 9 }, - { 0x24, 7 }, { 0x1FA, 9 }, { 0x2F, 7 }, { 0x114, 9 }, - { 0x75, 7 }, { 0x38, 8 }, { 0xFC, 8 }, { 0x36, 8 }, - { 0x1E, 7 }, { 0x1FB, 9 }, { 0x7F, 7 }, { 0x68, 7 }, - { 0x16, 6 }, { 0x37, 8 }, { 0x1F, 7 }, { 0x5C, 8 }, - { 0x13, 6 }, { 0x8B, 8 }, { 0x1, 6 }, { 0xFB, 8 }, - { 0x21, 6 }, { 0x44, 7 }, { 0x2B, 6 }, { 0x6B, 7 }, - { 0x3B, 6 }, { 0xC, 6 }, { 0x1C, 5 }, { 0x19, 5 }, - { 0x1, 4 }, { 0x20, 6 }, { 0x16, 5 }, { 0x7C, 7 }, - { 0xC, 5 }, { 0x74, 7 }, { 0xA, 5 }, { 0x1C, 6 }, - { 0x12, 5 }, { 0x69, 7 }, { 0xF, 5 }, { 0x6A, 7 }, - { 0x14, 5 }, { 0x11, 6 }, { 0x1E, 5 }, { 0x17, 5 }, - { 0x2, 4 }, { 0x31, 6 }, { 0x1B, 5 }, { 0x30, 6 }, - { 0xD, 5 }, { 0x0, 6 }, { 0x1, 5 }, { 0x1D, 7 }, - { 0x23, 6 }, { 0x1A, 7 }, { 0x1D, 6 }, { 0x5D, 8 }, - { 0x10, 6 }, { 0xFA, 8 }, { 0x13, 5 } + { 53, 6 }, { 22, 6 }, { 54, 5 }, { 32, 4 }, { 48, 4 }, + { 29, 6 }, { 57, 7 }, { 11, 8 }, { 17, 8 }, { 9, 8 }, + { 1, 8 }, { 55, 7 }, { 12, 7 }, { 18, 7 }, { 60, 6 }, + { 45, 6 }, { 4, 7 }, { 2, 7 }, { 20, 6 }, { 38, 5 }, + { 16, 6 }, { 19, 8 }, { 59, 8 }, { 6, 7 }, { 36, 5 }, + { 52, 5 }, { 39, 6 }, { 58, 6 }, { 42, 5 }, { 33, 6 }, + { 24, 6 }, { 25, 7 }, { 7, 9 }, { 3, 9 }, { 21, 8 }, + { 56, 6 }, { 40, 5 }, { 62, 5 }, { 44, 5 }, { 0, 6 }, + { 26, 6 }, { 34, 5 }, { 47, 5 }, { 51, 6 }, { 49, 6 }, + { 31, 5 }, { 15, 7 }, { 41, 7 }, { 43, 7 }, { 27, 7 }, + { 50, 5 }, { 30, 5 }, { 37, 7 }, { 8, 7 }, { 28, 6 }, + { 46, 5 }, { 35, 7 }, { 61, 8 }, { 23, 8 }, { 10, 8 }, + { 5, 9 }, { 13, 9 }, { 14, 7 }, }, { - { 0x12, 5 }, { 0x26, 7 }, { 0x41, 7 }, { 0x22, 8 }, - { 0x1A, 7 }, { 0xA9, 8 }, { 0x4C, 7 }, { 0x1B2, 9 }, - { 0x5C, 7 }, { 0xA8, 8 }, { 0x58, 7 }, { 0x1B3, 9 }, - { 0x40, 7 }, { 0x79, 8 }, { 0xC, 6 }, { 0x55, 7 }, - { 0x1F, 6 }, { 0xD8, 8 }, { 0x76, 7 }, { 0x23, 8 }, - { 0x5F, 7 }, { 0x78, 8 }, { 0xB, 6 }, { 0x1B, 7 }, - { 0x2D, 6 }, { 0x10, 7 }, { 0x37, 6 }, { 0x6D, 7 }, - { 0x32, 6 }, { 0xA, 6 }, { 0x1A, 5 }, { 0x1E, 5 }, - { 0x1F, 5 }, { 0x2B, 6 }, { 0xD, 5 }, { 0x77, 7 }, - { 0x31, 6 }, { 0x5D, 7 }, { 0x38, 6 }, { 0x27, 7 }, - { 0xC, 5 }, { 0xE9, 8 }, { 0x33, 6 }, { 0x5E, 7 }, - { 0x30, 6 }, { 0x4D, 7 }, { 0xA, 5 }, { 0x21, 6 }, - { 0x7, 5 }, { 0x3D, 7 }, { 0x39, 6 }, { 0xE8, 8 }, - { 0xB, 5 }, { 0x59, 7 }, { 0x14, 5 }, { 0x27, 6 }, - { 0x11, 5 }, { 0x75, 7 }, { 0xE, 5 }, { 0x9, 6 }, - { 0x8, 5 }, { 0x12, 6 }, { 0x0, 3 } - } + { 62, 3 }, { 25, 7 }, { 3, 8 }, { 19, 8 }, { 59, 6 }, + { 29, 6 }, { 22, 6 }, { 14, 6 }, { 4, 7 }, { 23, 7 }, + { 48, 5 }, { 60, 5 }, { 61, 6 }, { 1, 7 }, { 39, 7 }, + { 46, 5 }, { 52, 5 }, { 40, 5 }, { 34, 5 }, { 58, 5 }, + { 21, 8 }, { 13, 8 }, { 49, 7 }, { 16, 6 }, { 12, 7 }, + { 2, 7 }, { 47, 6 }, { 56, 5 }, { 0, 5 }, { 6, 7 }, + { 45, 7 }, { 55, 6 }, { 54, 5 }, { 9, 8 }, { 5, 8 }, + { 15, 7 }, { 33, 6 }, { 10, 7 }, { 53, 7 }, { 24, 6 }, + { 8, 7 }, { 37, 7 }, { 43, 7 }, { 20, 7 }, { 44, 6 }, + { 36, 6 }, { 28, 6 }, { 42, 6 }, { 30, 5 }, { 17, 8 }, + { 7, 9 }, { 11, 9 }, { 27, 7 }, { 26, 6 }, { 38, 6 }, + { 50, 6 }, { 51, 8 }, { 41, 8 }, { 57, 7 }, { 18, 7 }, + { 35, 7 }, { 31, 5 }, { 32, 5 }, + }, } }; -static const uint16_t vp4_dc_bias[16][32][2] = { +static const uint8_t vp4_bias[5 * 16][32][2] = { { /* DC bias table 0 */ - { 0xC, 5 }, { 0x70, 7 }, { 0x1CA, 9 }, { 0x1CB, 9 }, - { 0x391, 10 }, { 0x1C9B, 13 }, { 0x3935, 14 }, { 0x71, 7 }, - { 0x3934, 14 }, { 0xB, 4 }, { 0xF, 4 }, { 0x19, 5 }, - { 0x2, 4 }, { 0x9, 4 }, { 0x3, 4 }, { 0x1D, 5 }, - { 0x18, 5 }, { 0x7, 4 }, { 0xD, 4 }, { 0x2, 3 }, - { 0x0, 3 }, { 0xA, 4 }, { 0x8, 4 }, { 0x1A, 6 }, - { 0x73, 7 }, { 0x6F, 8 }, { 0xE4C, 12 }, { 0x727, 11 }, - { 0x392, 10 }, { 0x390, 10 }, { 0x36, 7 }, { 0x6E, 8 } + { 20, 3 }, { 12, 4 }, { 14, 4 }, { 19, 3 }, { 0, 5 }, { 23, 6 }, + { 30, 7 }, { 31, 8 }, { 25, 8 }, { 17, 4 }, { 22, 4 }, { 13, 4 }, + { 21, 4 }, { 9, 4 }, { 16, 5 }, { 11, 5 }, { 18, 4 }, { 1, 7 }, + { 7, 7 }, { 29, 10 }, { 4, 10 }, { 28, 10 }, { 26, 12 }, { 8, 14 }, + { 6, 14 }, { 5, 13 }, { 27, 11 }, { 2, 9 }, { 3, 9 }, { 24, 7 }, + { 15, 5 }, { 10, 4 }, }, { /* DC bias table 1 */ - { 0x11, 5 }, { 0x7A, 7 }, { 0x83, 8 }, { 0x40, 7 }, - { 0x105, 9 }, { 0x413, 11 }, { 0x410, 11 }, { 0x7B, 7 }, - { 0x822, 12 }, { 0xE, 4 }, { 0x2, 3 }, { 0x2, 4 }, - { 0x6, 4 }, { 0xA, 4 }, { 0x7, 4 }, { 0x1F, 5 }, - { 0x17, 5 }, { 0x9, 4 }, { 0xD, 4 }, { 0x0, 3 }, - { 0xC, 4 }, { 0x3, 4 }, { 0x3C, 6 }, { 0x2C, 6 }, - { 0x21, 6 }, { 0x169, 9 }, { 0x412, 11 }, { 0x2D0, 10 }, - { 0x2D1, 10 }, { 0x823, 12 }, { 0x5B, 7 }, { 0xB5, 8 } + { 19, 3 }, { 11, 4 }, { 21, 4 }, { 10, 3 }, { 12, 4 }, { 14, 4 }, + { 3, 7 }, { 6, 11 }, { 8, 12 }, { 29, 12 }, { 26, 11 }, { 5, 11 }, + { 4, 9 }, { 2, 8 }, { 24, 6 }, { 0, 5 }, { 17, 4 }, { 13, 4 }, + { 23, 6 }, { 27, 10 }, { 28, 10 }, { 25, 9 }, { 31, 8 }, { 30, 7 }, + { 16, 5 }, { 20, 4 }, { 18, 4 }, { 9, 4 }, { 22, 6 }, { 1, 7 }, + { 7, 7 }, { 15, 5 }, }, { /* DC bias table 2 */ - { 0x17, 5 }, { 0x10, 6 }, { 0xB6, 8 }, { 0x22, 7 }, - { 0x16A, 9 }, { 0x2D0, 10 }, { 0xB48, 12 }, { 0x77, 7 }, - { 0x1692, 13 }, { 0x0, 3 }, { 0x3, 3 }, { 0x3, 4 }, - { 0x9, 4 }, { 0xC, 4 }, { 0x5, 4 }, { 0x2, 4 }, - { 0x1C, 5 }, { 0x8, 4 }, { 0xD, 4 }, { 0xF, 4 }, - { 0xA, 4 }, { 0x9, 5 }, { 0x23, 7 }, { 0x3A, 6 }, - { 0x2C, 6 }, { 0x16B, 9 }, { 0x5A5, 11 }, { 0x2D3, 10 }, - { 0x2D1, 10 }, { 0x1693, 13 }, { 0x76, 7 }, { 0xB7, 8 } + { 9, 3 }, { 15, 4 }, { 11, 4 }, { 1, 6 }, { 3, 7 }, { 22, 7 }, + { 21, 5 }, { 14, 4 }, { 10, 3 }, { 17, 4 }, { 12, 4 }, { 20, 4 }, + { 24, 6 }, { 5, 10 }, { 28, 10 }, { 6, 12 }, { 8, 13 }, { 29, 13 }, + { 26, 11 }, { 27, 10 }, { 4, 9 }, { 25, 9 }, { 2, 8 }, { 31, 8 }, + { 0, 5 }, { 13, 4 }, { 18, 4 }, { 16, 5 }, { 23, 6 }, { 30, 7 }, + { 7, 7 }, { 19, 4 }, }, { /* DC bias table 3 */ - { 0x1E, 5 }, { 0x13, 6 }, { 0xFB, 8 }, { 0x7C, 7 }, - { 0x46, 8 }, { 0x7D6, 11 }, { 0xFA9, 12 }, { 0x12, 6 }, - { 0x1F50, 13 }, { 0x1, 3 }, { 0x4, 3 }, { 0x5, 4 }, - { 0xA, 4 }, { 0xE, 4 }, { 0x7, 4 }, { 0x0, 4 }, - { 0x17, 5 }, { 0x6, 4 }, { 0xD, 4 }, { 0xC, 4 }, - { 0x1, 4 }, { 0x2C, 6 }, { 0x8F, 9 }, { 0x3F, 6 }, - { 0x2D, 6 }, { 0x1F4, 9 }, { 0x7D5, 11 }, { 0x8E, 9 }, - { 0x7D7, 11 }, { 0x1F51, 13 }, { 0x10, 6 }, { 0x22, 7 } + { 15, 4 }, { 20, 4 }, { 9, 3 }, { 30, 6 }, { 31, 7 }, { 4, 8 }, + { 27, 9 }, { 22, 9 }, { 7, 6 }, { 1, 6 }, { 11, 4 }, { 17, 4 }, + { 14, 4 }, { 10, 3 }, { 12, 4 }, { 21, 6 }, { 24, 6 }, { 16, 5 }, + { 19, 4 }, { 18, 4 }, { 13, 4 }, { 0, 5 }, { 3, 7 }, { 25, 9 }, + { 8, 13 }, { 29, 13 }, { 6, 12 }, { 26, 11 }, { 5, 11 }, { 28, 11 }, + { 2, 8 }, { 23, 6 }, }, { /* DC bias table 4 */ - { 0x1, 4 }, { 0x2B, 6 }, { 0x12, 7 }, { 0x55, 7 }, - { 0x27, 8 }, { 0x3B0, 10 }, { 0x762, 11 }, { 0x77, 7 }, - { 0x261, 12 }, { 0x2, 3 }, { 0x6, 3 }, { 0x7, 4 }, - { 0xB, 4 }, { 0xF, 4 }, { 0x8, 4 }, { 0x0, 4 }, - { 0x1C, 5 }, { 0x3, 4 }, { 0x9, 4 }, { 0x6, 4 }, - { 0x14, 5 }, { 0x54, 7 }, { 0x131, 11 }, { 0x5, 5 }, - { 0x3A, 6 }, { 0x1D9, 9 }, { 0x99, 10 }, { 0x4D, 9 }, - { 0x763, 11 }, { 0x260, 12 }, { 0x8, 6 }, { 0xED, 8 } + { 15, 4 }, { 0, 4 }, { 30, 6 }, { 2, 7 }, { 29, 12 }, { 8, 12 }, + { 22, 11 }, { 26, 10 }, { 27, 9 }, { 4, 8 }, { 23, 5 }, { 17, 4 }, + { 9, 3 }, { 19, 4 }, { 11, 4 }, { 14, 4 }, { 18, 4 }, { 20, 5 }, + { 21, 7 }, { 3, 7 }, { 1, 6 }, { 12, 4 }, { 10, 3 }, { 16, 5 }, + { 24, 6 }, { 5, 10 }, { 6, 11 }, { 28, 11 }, { 25, 9 }, { 31, 8 }, + { 7, 7 }, { 13, 4 }, }, { /* DC bias table 5 */ - { 0x4, 4 }, { 0x33, 6 }, { 0x60, 7 }, { 0x65, 7 }, - { 0xC2, 8 }, { 0x30D, 10 }, { 0x619, 11 }, { 0x64, 7 }, - { 0x1862, 13 }, { 0x4, 3 }, { 0x7, 3 }, { 0xA, 4 }, - { 0xB, 4 }, { 0xD, 4 }, { 0x6, 4 }, { 0x0, 4 }, - { 0xF, 5 }, { 0x3, 4 }, { 0x5, 4 }, { 0x2, 4 }, - { 0x2, 5 }, { 0x77, 8 }, { 0xC30, 12 }, { 0x3, 5 }, - { 0x31, 6 }, { 0x187, 9 }, { 0x1D9, 10 }, { 0xED, 9 }, - { 0x1D8, 10 }, { 0x1863, 13 }, { 0x1C, 6 }, { 0x3A, 7 } + { 15, 4 }, { 20, 5 }, { 23, 5 }, { 19, 4 }, { 17, 4 }, { 0, 4 }, + { 18, 4 }, { 14, 4 }, { 30, 6 }, { 31, 7 }, { 28, 10 }, { 26, 10 }, + { 27, 9 }, { 21, 8 }, { 16, 5 }, { 9, 3 }, { 11, 4 }, { 12, 4 }, + { 2, 7 }, { 4, 8 }, { 22, 12 }, { 8, 13 }, { 29, 13 }, { 6, 11 }, + { 5, 10 }, { 25, 9 }, { 24, 6 }, { 7, 7 }, { 3, 7 }, { 1, 6 }, + { 13, 4 }, { 10, 3 }, }, { /* DC bias table 6 */ - { 0x8, 4 }, { 0xA, 5 }, { 0x6A, 7 }, { 0x16, 6 }, - { 0x1E, 7 }, { 0x34E, 10 }, { 0x69F, 11 }, { 0x68, 7 }, - { 0xD28, 12 }, { 0x5, 3 }, { 0x7, 3 }, { 0x7, 4 }, - { 0xC, 4 }, { 0x0, 3 }, { 0x6, 4 }, { 0x1B, 5 }, - { 0x12, 5 }, { 0x2, 4 }, { 0x4, 4 }, { 0x13, 5 }, - { 0xE, 6 }, { 0x34B, 10 }, { 0x1A53, 13 }, { 0x6, 5 }, - { 0x17, 6 }, { 0x1A6, 9 }, { 0x69E, 11 }, { 0x1A4, 9 }, - { 0x695, 11 }, { 0x1A52, 13 }, { 0x6B, 7 }, { 0x1F, 7 } + { 13, 3 }, { 17, 4 }, { 23, 5 }, { 20, 6 }, { 4, 7 }, { 31, 7 }, + { 18, 4 }, { 1, 5 }, { 3, 6 }, { 24, 6 }, { 14, 4 }, { 11, 4 }, + { 0, 4 }, { 16, 5 }, { 19, 5 }, { 9, 3 }, { 12, 4 }, { 7, 7 }, + { 27, 9 }, { 8, 12 }, { 29, 13 }, { 22, 13 }, { 28, 11 }, { 21, 10 }, + { 25, 9 }, { 5, 10 }, { 26, 11 }, { 6, 11 }, { 2, 7 }, { 30, 7 }, + { 15, 5 }, { 10, 3 }, }, { /* DC bias table 7 */ - { 0xE, 4 }, { 0xF, 5 }, { 0x17, 6 }, { 0x25, 6 }, - { 0x9F, 8 }, { 0x138, 9 }, { 0x24B, 10 }, { 0x93, 8 }, - { 0x92A, 12 }, { 0x5, 3 }, { 0x0, 2 }, { 0x8, 4 }, - { 0xD, 4 }, { 0xF, 4 }, { 0x6, 4 }, { 0x4, 4 }, - { 0xE, 5 }, { 0x19, 5 }, { 0x18, 5 }, { 0xA, 5 }, - { 0x9E, 8 }, { 0x494, 11 }, { 0x1256, 13 }, { 0x26, 6 }, - { 0x16, 6 }, { 0x124, 9 }, { 0x4E5, 11 }, { 0x273, 10 }, - { 0x4E4, 11 }, { 0x1257, 13 }, { 0x48, 7 }, { 0x9D, 8 } + { 10, 2 }, { 15, 4 }, { 19, 5 }, { 24, 6 }, { 2, 6 }, { 14, 4 }, + { 16, 5 }, { 1, 5 }, { 11, 4 }, { 30, 7 }, { 25, 9 }, { 21, 11 }, + { 8, 12 }, { 22, 13 }, { 29, 13 }, { 6, 10 }, { 7, 8 }, { 3, 6 }, + { 23, 6 }, { 5, 9 }, { 28, 11 }, { 26, 11 }, { 27, 10 }, { 31, 8 }, + { 20, 8 }, { 4, 8 }, { 9, 3 }, { 18, 5 }, { 17, 5 }, { 12, 4 }, + { 0, 4 }, { 13, 4 }, }, { /* DC bias table 8 */ - { 0x4, 4 }, { 0x2C, 6 }, { 0x50, 7 }, { 0x1E, 7 }, - { 0x71, 9 }, { 0xE1, 10 }, { 0xE0, 10 }, { 0x1D, 7 }, - { 0x6, 6 }, { 0x7, 3 }, { 0x6, 3 }, { 0x7, 4 }, - { 0x5, 4 }, { 0x6, 4 }, { 0x15, 5 }, { 0x0, 5 }, - { 0x29, 6 }, { 0x2, 5 }, { 0x6, 5 }, { 0x1, 5 }, - { 0x23, 6 }, { 0x1F, 7 }, { 0x39, 8 }, { 0x9, 4 }, - { 0x2, 4 }, { 0x10, 5 }, { 0x7, 6 }, { 0x2D, 6 }, - { 0x2F, 6 }, { 0x2E, 6 }, { 0x22, 6 }, { 0x51, 7 } + { 15, 5 }, { 19, 5 }, { 17, 5 }, { 8, 6 }, { 26, 6 }, { 24, 4 }, + { 18, 5 }, { 6, 10 }, { 5, 10 }, { 4, 9 }, { 22, 8 }, { 7, 7 }, + { 3, 7 }, { 21, 7 }, { 0, 4 }, { 12, 4 }, { 13, 4 }, { 11, 4 }, + { 25, 5 }, { 30, 6 }, { 20, 6 }, { 23, 4 }, { 2, 7 }, { 31, 7 }, + { 16, 6 }, { 14, 5 }, { 1, 6 }, { 27, 6 }, { 29, 6 }, { 28, 6 }, + { 10, 3 }, { 9, 3 }, }, { /* DC bias table 9 */ - { 0x8, 4 }, { 0x2F, 6 }, { 0x51, 7 }, { 0x50, 7 }, - { 0x2ED, 10 }, { 0x5D9, 11 }, { 0x5D8, 11 }, { 0xBA, 8 }, - { 0x5C, 7 }, { 0x7, 3 }, { 0x6, 3 }, { 0x9, 4 }, - { 0x6, 4 }, { 0x7, 4 }, { 0x16, 5 }, { 0x5, 5 }, - { 0x2B, 6 }, { 0x6, 5 }, { 0xA, 5 }, { 0x1, 5 }, - { 0xF, 6 }, { 0x1D, 7 }, { 0x177, 9 }, { 0x4, 4 }, - { 0x1, 4 }, { 0x4, 5 }, { 0x1, 6 }, { 0x2A, 6 }, - { 0xB, 5 }, { 0x29, 6 }, { 0x0, 6 }, { 0x1C, 7 } + { 30, 6 }, { 26, 6 }, { 19, 5 }, { 24, 4 }, { 25, 5 }, { 15, 5 }, + { 17, 5 }, { 31, 7 }, { 21, 7 }, { 20, 6 }, { 23, 4 }, { 18, 5 }, + { 28, 5 }, { 12, 4 }, { 13, 4 }, { 0, 4 }, { 11, 4 }, { 3, 7 }, + { 2, 7 }, { 29, 6 }, { 27, 6 }, { 16, 6 }, { 14, 5 }, { 8, 7 }, + { 7, 8 }, { 6, 11 }, { 5, 11 }, { 4, 10 }, { 22, 9 }, { 1, 6 }, + { 10, 3 }, { 9, 3 }, }, { /* DC bias table 10 */ - { 0xA, 4 }, { 0x3C, 6 }, { 0x74, 7 }, { 0x4E, 7 }, - { 0x26D, 10 }, { 0x4D9, 11 }, { 0x4D8, 11 }, { 0x9A, 8 }, - { 0x4C, 7 }, { 0x0, 2 }, { 0x6, 3 }, { 0x8, 4 }, - { 0x7, 4 }, { 0x6, 4 }, { 0x16, 5 }, { 0x8, 5 }, - { 0x2E, 6 }, { 0xA, 5 }, { 0xB, 5 }, { 0x3D, 6 }, - { 0x24, 6 }, { 0xEB, 8 }, { 0x137, 9 }, { 0x1F, 5 }, - { 0x1C, 5 }, { 0x3B, 6 }, { 0x12, 6 }, { 0x25, 6 }, - { 0x2F, 6 }, { 0x13, 6 }, { 0x4F, 7 }, { 0xEA, 8 } + { 9, 2 }, { 15, 5 }, { 26, 6 }, { 29, 6 }, { 17, 5 }, { 18, 5 }, + { 13, 4 }, { 12, 4 }, { 11, 4 }, { 20, 6 }, { 27, 6 }, { 8, 7 }, + { 7, 8 }, { 6, 11 }, { 5, 11 }, { 4, 10 }, { 22, 9 }, { 3, 7 }, + { 30, 7 }, { 0, 4 }, { 14, 5 }, { 16, 6 }, { 28, 6 }, { 10, 3 }, + { 24, 5 }, { 2, 7 }, { 31, 8 }, { 21, 8 }, { 25, 6 }, { 1, 6 }, + { 19, 6 }, { 23, 5 }, }, { /* DC bias table 11 */ - { 0xA, 4 }, { 0xA, 5 }, { 0x3, 6 }, { 0x16, 6 }, - { 0x9, 8 }, { 0x21, 10 }, { 0x20, 10 }, { 0xB3, 8 }, - { 0x58, 7 }, { 0x7, 3 }, { 0x6, 3 }, { 0x7, 4 }, - { 0x6, 4 }, { 0x4, 4 }, { 0x13, 5 }, { 0x2, 5 }, - { 0x25, 6 }, { 0x0, 5 }, { 0x3, 5 }, { 0x2D, 6 }, - { 0x5D, 7 }, { 0xB2, 8 }, { 0x11, 9 }, { 0x8, 4 }, - { 0x2, 4 }, { 0x6, 5 }, { 0x17, 6 }, { 0x2F, 6 }, - { 0x7, 5 }, { 0x24, 6 }, { 0x5C, 7 }, { 0x5, 7 } + { 17, 5 }, { 6, 10 }, { 5, 10 }, { 22, 9 }, { 4, 8 }, { 31, 7 }, + { 2, 6 }, { 15, 5 }, { 18, 5 }, { 24, 4 }, { 25, 5 }, { 28, 5 }, + { 13, 4 }, { 1, 5 }, { 3, 6 }, { 26, 6 }, { 12, 4 }, { 11, 4 }, + { 23, 4 }, { 29, 6 }, { 16, 6 }, { 14, 5 }, { 0, 4 }, { 8, 7 }, + { 21, 8 }, { 7, 8 }, { 19, 6 }, { 30, 7 }, { 20, 7 }, { 27, 6 }, + { 10, 3 }, { 9, 3 }, }, { /* DC bias table 12 */ - { 0xB, 4 }, { 0x13, 5 }, { 0x1F, 6 }, { 0x31, 6 }, - { 0x21, 7 }, { 0x295, 10 }, { 0x528, 11 }, { 0xA4, 8 }, - { 0x3C, 7 }, { 0x0, 2 }, { 0x7, 3 }, { 0x6, 4 }, - { 0x5, 4 }, { 0x1B, 5 }, { 0x12, 5 }, { 0x32, 6 }, - { 0x1D, 6 }, { 0x2B, 6 }, { 0x30, 6 }, { 0x1C, 6 }, - { 0x3D, 7 }, { 0x14B, 9 }, { 0x529, 11 }, { 0x8, 4 }, - { 0x1A, 5 }, { 0x33, 6 }, { 0x11, 6 }, { 0x2A, 6 }, - { 0x9, 5 }, { 0x28, 6 }, { 0x53, 7 }, { 0x20, 7 } + { 9, 2 }, { 31, 7 }, { 4, 7 }, { 26, 6 }, { 28, 5 }, { 12, 4 }, + { 11, 4 }, { 19, 6 }, { 16, 6 }, { 8, 7 }, { 20, 7 }, { 2, 6 }, + { 23, 4 }, { 14, 5 }, { 1, 5 }, { 29, 6 }, { 7, 8 }, { 6, 11 }, + { 22, 11 }, { 5, 10 }, { 21, 9 }, { 30, 7 }, { 27, 6 }, { 17, 6 }, + { 0, 4 }, { 18, 6 }, { 3, 6 }, { 15, 6 }, { 25, 6 }, { 24, 5 }, + { 13, 5 }, { 10, 3 }, }, { /* DC bias table 13 */ - { 0xE, 4 }, { 0x15, 5 }, { 0x29, 6 }, { 0x3F, 6 }, - { 0x4D, 7 }, { 0x2F1, 10 }, { 0x5E0, 11 }, { 0x92, 8 }, - { 0x48, 7 }, { 0x0, 2 }, { 0x6, 3 }, { 0x6, 4 }, - { 0x5, 4 }, { 0x4, 4 }, { 0xF, 5 }, { 0x2E, 6 }, - { 0x1D, 6 }, { 0x28, 6 }, { 0x27, 6 }, { 0x5F, 7 }, - { 0xBD, 8 }, { 0x179, 9 }, { 0x5E1, 11 }, { 0x8, 4 }, - { 0x1E, 5 }, { 0x2D, 6 }, { 0x1C, 6 }, { 0x2C, 6 }, - { 0x3E, 6 }, { 0x25, 6 }, { 0x4C, 7 }, { 0x93, 8 } + { 9, 2 }, { 13, 4 }, { 12, 4 }, { 11, 4 }, { 26, 6 }, { 16, 6 }, + { 14, 5 }, { 23, 4 }, { 8, 7 }, { 7, 8 }, { 31, 8 }, { 29, 6 }, + { 30, 7 }, { 4, 7 }, { 18, 6 }, { 17, 6 }, { 2, 6 }, { 1, 5 }, + { 27, 6 }, { 25, 6 }, { 15, 6 }, { 6, 11 }, { 22, 11 }, { 5, 10 }, + { 21, 9 }, { 20, 8 }, { 19, 7 }, { 10, 3 }, { 0, 4 }, { 24, 5 }, + { 28, 6 }, { 3, 6 }, }, { /* DC bias table 14 */ - { 0xC, 4 }, { 0x17, 5 }, { 0x35, 6 }, { 0x13, 5 }, - { 0x21, 6 }, { 0xAD, 8 }, { 0x6F1, 11 }, { 0x1BD, 9 }, - { 0xD9, 8 }, { 0x0, 2 }, { 0x7, 3 }, { 0x7, 4 }, - { 0x6, 4 }, { 0x4, 4 }, { 0x11, 5 }, { 0x2A, 6 }, - { 0x6E, 7 }, { 0x25, 6 }, { 0x24, 6 }, { 0x57, 7 }, - { 0xD8, 8 }, { 0x379, 10 }, { 0x6F0, 11 }, { 0x5, 4 }, - { 0x16, 5 }, { 0x29, 6 }, { 0x6D, 7 }, { 0x28, 6 }, - { 0x34, 6 }, { 0x20, 6 }, { 0xDF, 8 }, { 0xAC, 8 } + { 9, 2 }, { 13, 4 }, { 23, 4 }, { 12, 4 }, { 11, 4 }, { 29, 6 }, + { 4, 6 }, { 14, 5 }, { 18, 6 }, { 17, 6 }, { 3, 5 }, { 27, 6 }, + { 25, 6 }, { 15, 6 }, { 31, 8 }, { 5, 8 }, { 19, 7 }, { 24, 5 }, + { 1, 5 }, { 0, 4 }, { 28, 6 }, { 2, 6 }, { 20, 8 }, { 8, 8 }, + { 26, 7 }, { 16, 7 }, { 22, 11 }, { 6, 11 }, { 21, 10 }, { 7, 9 }, + { 30, 8 }, { 10, 3 }, }, { /* DC bias table 15 */ - { 0x0, 3 }, { 0x1A, 5 }, { 0x6, 5 }, { 0x19, 5 }, - { 0x30, 6 }, { 0x5A, 7 }, { 0x18A, 9 }, { 0x2DD, 10 }, - { 0x18B, 9 }, { 0x1, 2 }, { 0x7, 3 }, { 0xA, 4 }, - { 0x9, 4 }, { 0x2, 4 }, { 0x10, 5 }, { 0x2E, 6 }, - { 0x6E, 7 }, { 0x2C, 6 }, { 0xE, 6 }, { 0x5E, 7 }, - { 0xC4, 8 }, { 0x5B9, 11 }, { 0x5B8, 11 }, { 0x11, 5 }, - { 0x36, 6 }, { 0x5F, 7 }, { 0x1E, 7 }, { 0x63, 7 }, - { 0x6F, 7 }, { 0x1F, 7 }, { 0xB6, 8 }, { 0x16F, 9 } - } -}; - -static const uint16_t vp4_ac_bias_0[16][32][2] = { + { 0, 3 }, { 13, 4 }, { 2, 5 }, { 18, 6 }, { 26, 7 }, { 29, 7 }, + { 9, 2 }, { 14, 5 }, { 23, 5 }, { 12, 4 }, { 11, 4 }, { 17, 6 }, + { 5, 7 }, { 30, 8 }, { 22, 11 }, { 21, 11 }, { 7, 10 }, { 31, 9 }, + { 15, 6 }, { 19, 7 }, { 25, 7 }, { 4, 6 }, { 20, 8 }, { 6, 9 }, + { 8, 9 }, { 27, 7 }, { 3, 5 }, { 1, 5 }, { 24, 6 }, { 16, 7 }, + { 28, 7 }, { 10, 3 }, + }, { /* AC bias group 1, table 0 */ - { 0x6, 5 }, { 0x1E, 7 }, { 0x1CC, 9 }, { 0x1CE, 9 }, - { 0x734, 11 }, { 0x1CD5, 13 }, { 0x1CD4, 13 }, { 0x18, 5 }, - { 0xE6B, 12 }, { 0x0, 3 }, { 0xF, 4 }, { 0x6, 4 }, - { 0x7, 4 }, { 0xD, 4 }, { 0x8, 4 }, { 0x2, 4 }, - { 0x19, 5 }, { 0x5, 4 }, { 0xB, 4 }, { 0xA, 4 }, - { 0x1D, 5 }, { 0x27, 6 }, { 0x1CF, 9 }, { 0x4, 4 }, - { 0x38, 6 }, { 0xE, 6 }, { 0x4C, 7 }, { 0x1F, 7 }, - { 0x4D, 7 }, { 0x39B, 10 }, { 0x12, 5 }, { 0x72, 7 } + { 9, 3 }, { 15, 4 }, { 0, 5 }, { 25, 6 }, { 1, 7 }, { 27, 7 }, + { 23, 4 }, { 17, 4 }, { 11, 4 }, { 12, 4 }, { 14, 4 }, { 30, 5 }, + { 26, 7 }, { 28, 7 }, { 21, 6 }, { 19, 4 }, { 18, 4 }, { 7, 5 }, + { 16, 5 }, { 13, 4 }, { 24, 6 }, { 31, 7 }, { 2, 9 }, { 4, 11 }, + { 6, 13 }, { 5, 13 }, { 8, 12 }, { 29, 10 }, { 3, 9 }, { 22, 9 }, + { 20, 5 }, { 10, 4 }, }, { /* AC bias group 1, table 1 */ - { 0x9, 5 }, { 0x4B, 7 }, { 0x90, 8 }, { 0x91, 8 }, - { 0x745, 11 }, { 0x1D11, 13 }, { 0x1D10, 13 }, { 0x19, 5 }, - { 0xE89, 12 }, { 0x0, 3 }, { 0xF, 4 }, { 0x8, 4 }, - { 0x7, 4 }, { 0xD, 4 }, { 0xB, 4 }, { 0x2, 4 }, - { 0x1C, 5 }, { 0x3, 4 }, { 0xA, 4 }, { 0x5, 4 }, - { 0x18, 5 }, { 0x10, 6 }, { 0x1D0, 9 }, { 0x6, 4 }, - { 0x3B, 6 }, { 0x11, 6 }, { 0x4A, 7 }, { 0x49, 7 }, - { 0xE9, 8 }, { 0x3A3, 10 }, { 0x13, 5 }, { 0x75, 7 } + { 9, 3 }, { 15, 4 }, { 17, 4 }, { 21, 6 }, { 25, 6 }, { 0, 5 }, + { 19, 4 }, { 23, 4 }, { 12, 4 }, { 11, 4 }, { 2, 8 }, { 3, 8 }, + { 27, 7 }, { 26, 7 }, { 1, 7 }, { 30, 5 }, { 18, 4 }, { 14, 4 }, + { 20, 5 }, { 7, 5 }, { 13, 4 }, { 16, 5 }, { 22, 9 }, { 6, 13 }, + { 5, 13 }, { 8, 12 }, { 4, 11 }, { 29, 10 }, { 28, 8 }, { 31, 7 }, + { 24, 6 }, { 10, 4 }, }, { /* AC bias group 1, table 2 */ - { 0x19, 5 }, { 0x74, 7 }, { 0x1D, 8 }, { 0xEA, 8 }, - { 0x73, 10 }, { 0x1CA, 12 }, { 0x396, 13 }, { 0x1C, 5 }, - { 0xE4, 11 }, { 0x2, 3 }, { 0x1, 3 }, { 0x7, 4 }, - { 0x8, 4 }, { 0xD, 4 }, { 0x9, 4 }, { 0x1F, 5 }, - { 0x18, 5 }, { 0x0, 4 }, { 0x6, 4 }, { 0x1E, 5 }, - { 0x3B, 6 }, { 0xEB, 8 }, { 0x397, 13 }, { 0xA, 4 }, - { 0x2, 5 }, { 0x2C, 6 }, { 0x5B, 7 }, { 0x5A, 7 }, - { 0xF, 7 }, { 0x38, 9 }, { 0x17, 5 }, { 0x6, 6 } + { 17, 4 }, { 24, 5 }, { 31, 6 }, { 29, 9 }, { 8, 11 }, { 5, 12 }, + { 6, 13 }, { 22, 13 }, { 4, 10 }, { 2, 8 }, { 28, 7 }, { 10, 3 }, + { 9, 3 }, { 18, 4 }, { 11, 4 }, { 12, 4 }, { 14, 4 }, { 23, 4 }, + { 25, 6 }, { 27, 7 }, { 26, 7 }, { 30, 5 }, { 16, 5 }, { 0, 5 }, + { 13, 4 }, { 7, 5 }, { 1, 7 }, { 3, 8 }, { 21, 8 }, { 20, 6 }, + { 19, 5 }, { 15, 5 }, }, { /* AC bias group 1, table 3 */ - { 0x1E, 5 }, { 0x6F, 7 }, { 0xAE, 8 }, { 0xAF, 8 }, - { 0x187, 10 }, { 0x61B, 12 }, { 0xC35, 13 }, { 0x1A, 5 }, - { 0x30C, 11 }, { 0x2, 3 }, { 0x1, 3 }, { 0x7, 4 }, - { 0x8, 4 }, { 0xE, 4 }, { 0x9, 4 }, { 0x1F, 5 }, - { 0x14, 5 }, { 0x0, 4 }, { 0x1, 4 }, { 0x19, 5 }, - { 0x2A, 6 }, { 0x60, 8 }, { 0xC34, 13 }, { 0xB, 4 }, - { 0xD, 5 }, { 0x36, 6 }, { 0x6E, 7 }, { 0x56, 7 }, - { 0x31, 7 }, { 0xC2, 9 }, { 0x18, 5 }, { 0x19, 6 } + { 17, 4 }, { 18, 4 }, { 10, 3 }, { 9, 3 }, { 21, 8 }, { 29, 9 }, + { 8, 11 }, { 22, 13 }, { 6, 13 }, { 5, 12 }, { 4, 10 }, { 28, 7 }, + { 31, 6 }, { 24, 5 }, { 11, 4 }, { 12, 4 }, { 14, 4 }, { 16, 5 }, + { 20, 6 }, { 27, 7 }, { 2, 8 }, { 3, 8 }, { 23, 4 }, { 30, 5 }, + { 19, 5 }, { 7, 5 }, { 25, 6 }, { 26, 7 }, { 1, 7 }, { 13, 4 }, + { 0, 5 }, { 15, 5 }, }, { /* AC bias group 1, table 4 */ - { 0x1, 4 }, { 0x2C, 6 }, { 0x5, 7 }, { 0x15, 7 }, - { 0x8, 8 }, { 0x97, 12 }, { 0x12D, 13 }, { 0x17, 5 }, - { 0x4A, 11 }, { 0x3, 3 }, { 0x2, 3 }, { 0x9, 4 }, - { 0xA, 4 }, { 0xE, 4 }, { 0x8, 4 }, { 0x1F, 5 }, - { 0x7, 5 }, { 0x1E, 5 }, { 0x1B, 5 }, { 0x4, 5 }, - { 0x5A, 7 }, { 0x24, 10 }, { 0x12C, 13 }, { 0xC, 4 }, - { 0x6, 5 }, { 0x0, 5 }, { 0x3, 6 }, { 0x5B, 7 }, - { 0x14, 7 }, { 0x13, 9 }, { 0x1A, 5 }, { 0xB, 6 } + { 25, 5 }, { 4, 8 }, { 21, 10 }, { 8, 11 }, { 22, 13 }, { 6, 13 }, + { 5, 12 }, { 29, 9 }, { 2, 7 }, { 26, 6 }, { 0, 4 }, { 19, 5 }, + { 28, 7 }, { 3, 7 }, { 31, 6 }, { 24, 5 }, { 16, 5 }, { 10, 3 }, + { 9, 3 }, { 14, 4 }, { 11, 4 }, { 12, 4 }, { 1, 6 }, { 20, 7 }, + { 27, 7 }, { 7, 5 }, { 23, 4 }, { 30, 5 }, { 18, 5 }, { 13, 4 }, + { 17, 5 }, { 15, 5 }, }, { /* AC bias group 1, table 5 */ - { 0x4, 4 }, { 0x0, 5 }, { 0x17, 7 }, { 0x63, 7 }, - { 0x18B, 9 }, { 0x310, 10 }, { 0xC44, 12 }, { 0x19, 5 }, - { 0x623, 11 }, { 0x4, 3 }, { 0x3, 3 }, { 0xA, 4 }, - { 0xB, 4 }, { 0xD, 4 }, { 0x3, 4 }, { 0x1C, 5 }, - { 0x3, 5 }, { 0xA, 5 }, { 0x4, 5 }, { 0x3, 6 }, - { 0x18A, 9 }, { 0x188B, 13 }, { 0x188A, 13 }, { 0xF, 4 }, - { 0xB, 5 }, { 0x2, 5 }, { 0xA, 6 }, { 0x2, 6 }, - { 0x16, 7 }, { 0x189, 9 }, { 0x1D, 5 }, { 0x30, 6 } + { 1, 5 }, { 27, 6 }, { 19, 6 }, { 25, 5 }, { 16, 5 }, { 18, 5 }, + { 26, 6 }, { 28, 7 }, { 2, 7 }, { 14, 4 }, { 0, 4 }, { 17, 5 }, + { 24, 5 }, { 10, 3 }, { 9, 3 }, { 11, 4 }, { 12, 4 }, { 31, 6 }, + { 5, 10 }, { 6, 12 }, { 22, 13 }, { 21, 13 }, { 8, 11 }, { 29, 9 }, + { 20, 9 }, { 4, 9 }, { 3, 7 }, { 7, 5 }, { 13, 4 }, { 15, 5 }, + { 30, 5 }, { 23, 4 }, }, { /* AC bias group 1, table 6 */ - { 0xD, 4 }, { 0x3, 5 }, { 0x77, 7 }, { 0xD, 6 }, - { 0x82, 8 }, { 0x20D, 10 }, { 0x830, 12 }, { 0x19, 5 }, - { 0x419, 11 }, { 0x3, 3 }, { 0x2, 3 }, { 0xA, 4 }, - { 0x9, 4 }, { 0xB, 4 }, { 0x2, 4 }, { 0x11, 5 }, - { 0x39, 6 }, { 0x2, 5 }, { 0x21, 6 }, { 0x40, 7 }, - { 0x1063, 13 }, { 0x20C5, 14 }, { 0x20C4, 14 }, { 0xF, 4 }, - { 0x18, 5 }, { 0x7, 5 }, { 0x38, 6 }, { 0xC, 6 }, - { 0x76, 7 }, { 0x107, 9 }, { 0x0, 4 }, { 0x3A, 6 } + { 30, 4 }, { 17, 5 }, { 1, 5 }, { 14, 4 }, { 27, 6 }, { 3, 6 }, + { 25, 5 }, { 10, 3 }, { 9, 3 }, { 19, 7 }, { 4, 8 }, { 6, 12 }, + { 22, 14 }, { 21, 14 }, { 20, 13 }, { 8, 11 }, { 5, 10 }, { 29, 9 }, + { 18, 6 }, { 15, 5 }, { 12, 4 }, { 11, 4 }, { 13, 4 }, { 24, 5 }, + { 7, 5 }, { 0, 4 }, { 26, 6 }, { 16, 6 }, { 31, 6 }, { 28, 7 }, + { 2, 7 }, { 23, 4 }, }, { /* AC bias group 1, table 7 */ - { 0xF, 4 }, { 0x1C, 5 }, { 0x36, 6 }, { 0x8, 5 }, - { 0x61, 7 }, { 0x91, 8 }, { 0x243, 10 }, { 0x9, 5 }, - { 0x120, 9 }, { 0x5, 3 }, { 0x3, 3 }, { 0x8, 4 }, - { 0x5, 4 }, { 0x1, 4 }, { 0x13, 5 }, { 0x31, 6 }, - { 0x76, 7 }, { 0x60, 7 }, { 0x93, 8 }, { 0x909, 12 }, - { 0x908, 12 }, { 0x90B, 12 }, { 0x90A, 12 }, { 0x1, 3 }, - { 0x1A, 5 }, { 0x19, 5 }, { 0x3A, 6 }, { 0x25, 6 }, - { 0x77, 7 }, { 0x92, 8 }, { 0x0, 4 }, { 0x37, 6 } + { 30, 4 }, { 13, 4 }, { 23, 3 }, { 3, 5 }, { 7, 5 }, { 12, 4 }, + { 10, 3 }, { 11, 4 }, { 8, 9 }, { 20, 12 }, { 19, 12 }, { 22, 12 }, + { 21, 12 }, { 6, 10 }, { 5, 8 }, { 29, 8 }, { 18, 8 }, { 27, 6 }, + { 14, 5 }, { 9, 3 }, { 17, 7 }, { 4, 7 }, { 15, 6 }, { 25, 5 }, + { 24, 5 }, { 2, 6 }, { 31, 6 }, { 1, 5 }, { 26, 6 }, { 16, 7 }, + { 28, 7 }, { 0, 4 }, }, { /* AC bias group 1, table 8 */ - { 0x1F, 5 }, { 0x79, 7 }, { 0xF1, 8 }, { 0xF0, 8 }, - { 0x11B, 10 }, { 0x469, 12 }, { 0x468, 12 }, { 0x3B, 6 }, - { 0x22, 7 }, { 0x5, 3 }, { 0x4, 3 }, { 0x7, 4 }, - { 0x5, 4 }, { 0x6, 4 }, { 0x1C, 5 }, { 0x1, 5 }, - { 0x35, 6 }, { 0x3D, 6 }, { 0x3A, 6 }, { 0x10, 6 }, - { 0x47, 8 }, { 0x8C, 9 }, { 0x235, 11 }, { 0x1, 3 }, - { 0x1, 4 }, { 0x19, 5 }, { 0x0, 5 }, { 0x30, 6 }, - { 0x9, 5 }, { 0x31, 6 }, { 0x1B, 5 }, { 0x34, 6 } + { 26, 5 }, { 15, 5 }, { 24, 4 }, { 23, 3 }, { 19, 6 }, { 8, 7 }, + { 21, 9 }, { 6, 12 }, { 5, 12 }, { 22, 11 }, { 4, 10 }, { 20, 8 }, + { 28, 5 }, { 12, 4 }, { 13, 4 }, { 11, 4 }, { 10, 3 }, { 9, 3 }, + { 27, 6 }, { 29, 6 }, { 25, 5 }, { 31, 6 }, { 16, 6 }, { 30, 5 }, + { 14, 5 }, { 18, 6 }, { 7, 6 }, { 3, 8 }, { 2, 8 }, { 1, 7 }, + { 17, 6 }, { 0, 5 }, }, { /* AC bias group 1, table 9 */ - { 0x3, 4 }, { 0x1B, 6 }, { 0xF3, 8 }, { 0xFD, 8 }, - { 0x3C9, 10 }, { 0xF20, 12 }, { 0x1E42, 13 }, { 0x3D, 6 }, - { 0xFC, 8 }, { 0x6, 3 }, { 0x4, 3 }, { 0x2, 4 }, - { 0x0, 4 }, { 0x1, 4 }, { 0x17, 5 }, { 0x3E, 6 }, - { 0x1A, 6 }, { 0x39, 6 }, { 0x2B, 6 }, { 0x78, 7 }, - { 0x1E5, 9 }, { 0x791, 11 }, { 0x1E43, 13 }, { 0x2, 3 }, - { 0x7, 4 }, { 0x1D, 5 }, { 0xC, 5 }, { 0x38, 6 }, - { 0x14, 5 }, { 0x7F, 7 }, { 0x16, 5 }, { 0x2A, 6 } + { 12, 4 }, { 13, 4 }, { 11, 4 }, { 0, 4 }, { 23, 3 }, { 26, 5 }, + { 16, 6 }, { 1, 6 }, { 24, 4 }, { 10, 3 }, { 28, 5 }, { 31, 6 }, + { 18, 6 }, { 30, 5 }, { 14, 5 }, { 9, 3 }, { 27, 6 }, { 17, 6 }, + { 25, 5 }, { 19, 7 }, { 5, 12 }, { 6, 13 }, { 22, 13 }, { 21, 11 }, + { 4, 10 }, { 20, 9 }, { 2, 8 }, { 7, 6 }, { 15, 6 }, { 8, 8 }, + { 3, 8 }, { 29, 7 }, }, { /* AC bias group 1, table 10 */ - { 0x7, 4 }, { 0x39, 6 }, { 0x51, 7 }, { 0x78, 7 }, - { 0x3CB, 10 }, { 0xF29, 12 }, { 0x1E51, 13 }, { 0x3D, 6 }, - { 0xF3, 8 }, { 0x6, 3 }, { 0x4, 3 }, { 0x2, 4 }, - { 0x0, 4 }, { 0x1, 4 }, { 0x17, 5 }, { 0x3E, 6 }, - { 0x7F, 7 }, { 0x2B, 6 }, { 0x7E, 7 }, { 0x50, 7 }, - { 0x1E4, 9 }, { 0x795, 11 }, { 0x1E50, 13 }, { 0x2, 3 }, - { 0x6, 4 }, { 0x1D, 5 }, { 0x6, 5 }, { 0x38, 6 }, - { 0x7, 5 }, { 0x29, 6 }, { 0x16, 5 }, { 0x2A, 6 } + { 12, 4 }, { 13, 4 }, { 11, 4 }, { 26, 5 }, { 28, 5 }, { 23, 3 }, + { 24, 4 }, { 0, 4 }, { 10, 3 }, { 19, 7 }, { 2, 7 }, { 29, 6 }, + { 31, 6 }, { 17, 6 }, { 30, 5 }, { 14, 5 }, { 9, 3 }, { 27, 6 }, + { 1, 6 }, { 25, 5 }, { 3, 7 }, { 20, 9 }, { 22, 13 }, { 6, 13 }, + { 5, 12 }, { 21, 11 }, { 4, 10 }, { 8, 8 }, { 7, 6 }, { 15, 6 }, + { 18, 7 }, { 16, 7 }, }, { /* AC bias group 1, table 11 */ - { 0x8, 4 }, { 0x3B, 6 }, { 0x1D, 7 }, { 0x72, 7 }, - { 0x1CC, 9 }, { 0x734, 11 }, { 0x1CD5, 13 }, { 0x3A, 6 }, - { 0x1C, 7 }, { 0x6, 3 }, { 0x5, 3 }, { 0x2, 4 }, - { 0x1, 4 }, { 0x0, 4 }, { 0x12, 5 }, { 0x3E, 6 }, - { 0x7F, 7 }, { 0x1E, 6 }, { 0x7E, 7 }, { 0xE7, 8 }, - { 0x39B, 10 }, { 0xE6B, 12 }, { 0x1CD4, 13 }, { 0x2, 3 }, - { 0x6, 4 }, { 0x1E, 5 }, { 0xE, 5 }, { 0x38, 6 }, - { 0x6, 5 }, { 0xF, 6 }, { 0x13, 5 }, { 0x1F, 6 } + { 13, 4 }, { 12, 4 }, { 11, 4 }, { 28, 5 }, { 8, 7 }, { 2, 7 }, + { 29, 6 }, { 23, 3 }, { 24, 4 }, { 26, 5 }, { 17, 6 }, { 31, 6 }, + { 0, 4 }, { 14, 5 }, { 30, 5 }, { 10, 3 }, { 9, 3 }, { 27, 6 }, + { 3, 7 }, { 4, 9 }, { 5, 11 }, { 22, 13 }, { 6, 13 }, { 21, 12 }, + { 20, 10 }, { 19, 8 }, { 7, 6 }, { 1, 6 }, { 25, 5 }, { 15, 6 }, + { 18, 7 }, { 16, 7 }, }, { /* AC bias group 1, table 12 */ - { 0xD, 4 }, { 0x3F, 6 }, { 0x73, 7 }, { 0xC, 6 }, - { 0xE4, 8 }, { 0x72B, 11 }, { 0xE54, 12 }, { 0x3A, 6 }, - { 0x1A, 7 }, { 0x5, 3 }, { 0x4, 3 }, { 0x2, 4 }, - { 0x1, 4 }, { 0x0, 4 }, { 0x7, 5 }, { 0x38, 6 }, - { 0x76, 7 }, { 0x77, 7 }, { 0x1B, 7 }, { 0x1CB, 9 }, - { 0x394, 10 }, { 0x1CAB, 13 }, { 0x1CAA, 13 }, { 0x2, 3 }, - { 0x6, 4 }, { 0x1E, 5 }, { 0xE, 5 }, { 0x3E, 6 }, - { 0x19, 5 }, { 0x1F, 6 }, { 0x18, 5 }, { 0x1E, 6 } + { 13, 4 }, { 12, 4 }, { 11, 4 }, { 3, 6 }, { 8, 7 }, { 18, 7 }, + { 14, 5 }, { 23, 3 }, { 24, 4 }, { 26, 5 }, { 31, 6 }, { 29, 6 }, + { 10, 3 }, { 9, 3 }, { 30, 5 }, { 28, 5 }, { 0, 4 }, { 15, 6 }, + { 4, 8 }, { 20, 10 }, { 6, 12 }, { 22, 13 }, { 21, 13 }, { 5, 11 }, + { 19, 9 }, { 2, 7 }, { 7, 6 }, { 16, 7 }, { 17, 7 }, { 25, 5 }, + { 27, 6 }, { 1, 6 }, }, { /* AC bias group 1, table 13 */ - { 0xE, 4 }, { 0x7, 5 }, { 0xC, 6 }, { 0x1C, 6 }, - { 0xBD, 8 }, { 0x2F3, 10 }, { 0xBC9, 12 }, { 0x1F, 6 }, - { 0xBF, 8 }, { 0x6, 3 }, { 0x4, 3 }, { 0x2, 4 }, - { 0x1, 4 }, { 0x1E, 5 }, { 0x1, 5 }, { 0xD, 6 }, - { 0x3A, 7 }, { 0x3B, 7 }, { 0xBE, 8 }, { 0x178, 9 }, - { 0x5E5, 11 }, { 0x1791, 13 }, { 0x1790, 13 }, { 0x2, 3 }, - { 0x6, 4 }, { 0x1F, 5 }, { 0x16, 5 }, { 0x0, 5 }, - { 0x15, 5 }, { 0x2E, 6 }, { 0x14, 5 }, { 0x1E, 6 } + { 27, 5 }, { 14, 5 }, { 12, 4 }, { 11, 4 }, { 2, 6 }, { 15, 6 }, + { 1, 5 }, { 23, 3 }, { 24, 4 }, { 3, 6 }, { 16, 7 }, { 17, 7 }, + { 31, 6 }, { 7, 6 }, { 10, 3 }, { 30, 5 }, { 28, 5 }, { 26, 5 }, + { 29, 6 }, { 19, 9 }, { 22, 13 }, { 21, 13 }, { 6, 12 }, { 20, 11 }, + { 5, 10 }, { 4, 8 }, { 18, 8 }, { 8, 8 }, { 9, 3 }, { 0, 4 }, + { 13, 5 }, { 25, 5 }, }, { /* AC bias group 1, table 14 */ - { 0x0, 3 }, { 0x1B, 5 }, { 0x31, 6 }, { 0x3A, 6 }, - { 0x60, 7 }, { 0x6F, 9 }, { 0x1B9, 11 }, { 0xE, 6 }, - { 0x1A, 7 }, { 0x5, 3 }, { 0x3, 3 }, { 0x2, 4 }, - { 0x1F, 5 }, { 0x1A, 5 }, { 0x39, 6 }, { 0xC, 6 }, - { 0xC3, 8 }, { 0xC2, 8 }, { 0x36, 8 }, { 0xDD, 10 }, - { 0x370, 12 }, { 0x6E3, 13 }, { 0x6E2, 13 }, { 0x2, 3 }, - { 0x8, 4 }, { 0x1E, 5 }, { 0x19, 5 }, { 0x3B, 6 }, - { 0x12, 5 }, { 0xF, 6 }, { 0x13, 5 }, { 0x38, 6 } + { 0, 3 }, { 11, 4 }, { 15, 6 }, { 8, 7 }, { 18, 8 }, { 20, 12 }, + { 22, 13 }, { 21, 13 }, { 6, 11 }, { 19, 10 }, { 5, 9 }, { 7, 6 }, + { 29, 6 }, { 23, 3 }, { 10, 3 }, { 24, 4 }, { 28, 5 }, { 30, 5 }, + { 9, 3 }, { 4, 7 }, { 17, 8 }, { 16, 8 }, { 2, 6 }, { 26, 5 }, + { 13, 5 }, { 1, 5 }, { 31, 6 }, { 14, 6 }, { 3, 6 }, { 27, 6 }, + { 25, 5 }, { 12, 5 }, }, { /* AC bias group 1, table 15 */ - { 0x2, 3 }, { 0x0, 4 }, { 0x3, 5 }, { 0x1C, 5 }, - { 0x32, 6 }, { 0x1C, 7 }, { 0x199, 9 }, { 0x4, 6 }, - { 0xCD, 8 }, { 0x4, 3 }, { 0x3, 3 }, { 0x1B, 5 }, - { 0x1A, 5 }, { 0x3D, 6 }, { 0x67, 7 }, { 0x3B, 8 }, - { 0x198, 9 }, { 0x75, 9 }, { 0xE9, 10 }, { 0x3A1, 12 }, - { 0x3A0, 12 }, { 0x3A3, 12 }, { 0x3A2, 12 }, { 0x5, 3 }, - { 0x2, 4 }, { 0x1F, 5 }, { 0x1D, 5 }, { 0x3C, 6 }, - { 0x18, 5 }, { 0xF, 6 }, { 0x6, 5 }, { 0x5, 6 } - } -}; - -static const uint16_t vp4_ac_bias_1[16][32][2] = { + { 1, 4 }, { 7, 6 }, { 31, 6 }, { 2, 5 }, { 24, 4 }, { 30, 5 }, + { 5, 7 }, { 20, 12 }, { 19, 12 }, { 22, 12 }, { 21, 12 }, { 18, 10 }, + { 17, 9 }, { 15, 8 }, { 29, 6 }, { 0, 3 }, { 10, 3 }, { 9, 3 }, + { 23, 3 }, { 28, 5 }, { 4, 6 }, { 16, 9 }, { 6, 9 }, { 8, 8 }, + { 14, 7 }, { 12, 5 }, { 11, 5 }, { 3, 5 }, { 26, 5 }, { 27, 6 }, + { 13, 6 }, { 25, 5 }, + }, { /* AC bias group 2, table 0 */ - { 0x4, 5 }, { 0xF5, 8 }, { 0x182, 9 }, { 0x60F, 11 }, - { 0x1839, 13 }, { 0x1838, 13 }, { 0x183B, 13 }, { 0x13, 5 }, - { 0xC0, 8 }, { 0x3, 3 }, { 0x2, 3 }, { 0xB, 4 }, - { 0xA, 4 }, { 0xE, 4 }, { 0x8, 4 }, { 0x1, 4 }, - { 0x12, 5 }, { 0x1F, 5 }, { 0x0, 4 }, { 0x6, 5 }, - { 0x7B, 7 }, { 0x306, 10 }, { 0x183A, 13 }, { 0xD, 4 }, - { 0x7, 5 }, { 0x31, 6 }, { 0xA, 6 }, { 0x61, 7 }, - { 0x3C, 6 }, { 0xF4, 8 }, { 0x19, 5 }, { 0xB, 6 } + { 18, 4 }, { 15, 4 }, { 0, 5 }, { 26, 6 }, { 31, 6 }, { 19, 5 }, + { 24, 5 }, { 10, 3 }, { 9, 3 }, { 14, 4 }, { 16, 5 }, { 7, 5 }, + { 12, 4 }, { 11, 4 }, { 8, 8 }, { 2, 9 }, { 21, 10 }, { 5, 13 }, + { 4, 13 }, { 22, 13 }, { 6, 13 }, { 3, 11 }, { 27, 7 }, { 25, 6 }, + { 30, 5 }, { 23, 4 }, { 13, 4 }, { 28, 6 }, { 29, 8 }, { 1, 8 }, + { 20, 7 }, { 17, 5 }, }, { /* AC bias group 2, table 1 */ - { 0xA, 5 }, { 0x1A, 7 }, { 0x1D8, 9 }, { 0x3B3, 10 }, - { 0xECA, 12 }, { 0x1D96, 13 }, { 0x3B2F, 14 }, { 0x14, 5 }, - { 0x36, 8 }, { 0x4, 3 }, { 0x3, 3 }, { 0xC, 4 }, - { 0xB, 4 }, { 0x0, 3 }, { 0x4, 4 }, { 0x1C, 5 }, - { 0x5, 5 }, { 0x15, 5 }, { 0x7, 5 }, { 0x17, 6 }, - { 0x37, 8 }, { 0x764, 11 }, { 0x3B2E, 14 }, { 0xF, 4 }, - { 0x1A, 5 }, { 0x3A, 6 }, { 0xC, 6 }, { 0x77, 7 }, - { 0x4, 5 }, { 0xED, 8 }, { 0x1B, 5 }, { 0x16, 6 } + { 13, 3 }, { 28, 5 }, { 16, 5 }, { 26, 6 }, { 1, 7 }, { 8, 8 }, + { 20, 8 }, { 18, 5 }, { 14, 4 }, { 0, 5 }, { 31, 6 }, { 19, 6 }, + { 10, 3 }, { 9, 3 }, { 7, 5 }, { 17, 5 }, { 12, 4 }, { 11, 4 }, + { 24, 5 }, { 30, 5 }, { 15, 5 }, { 25, 6 }, { 2, 9 }, { 21, 11 }, + { 4, 12 }, { 5, 13 }, { 22, 14 }, { 6, 14 }, { 3, 10 }, { 29, 8 }, + { 27, 7 }, { 23, 4 }, }, { /* AC bias group 2, table 2 */ - { 0x1A, 5 }, { 0x2D, 7 }, { 0x58, 8 }, { 0x1F4, 9 }, - { 0x7D4, 11 }, { 0x1F55, 13 }, { 0x1F54, 13 }, { 0x14, 5 }, - { 0x59, 8 }, { 0x4, 3 }, { 0x3, 3 }, { 0xB, 4 }, - { 0xC, 4 }, { 0xE, 4 }, { 0x4, 4 }, { 0x15, 5 }, - { 0x5, 5 }, { 0x7, 5 }, { 0x4, 5 }, { 0x7C, 7 }, - { 0x3EB, 10 }, { 0x1F57, 13 }, { 0x1F56, 13 }, { 0x0, 3 }, - { 0x1B, 5 }, { 0x3F, 6 }, { 0xD, 6 }, { 0xC, 6 }, - { 0xA, 5 }, { 0xFB, 8 }, { 0x1E, 5 }, { 0x17, 6 } + { 23, 3 }, { 18, 5 }, { 16, 5 }, { 27, 6 }, { 26, 6 }, { 17, 5 }, + { 14, 4 }, { 28, 5 }, { 2, 8 }, { 8, 8 }, { 1, 7 }, { 31, 6 }, + { 10, 3 }, { 9, 3 }, { 7, 5 }, { 15, 5 }, { 11, 4 }, { 12, 4 }, + { 0, 5 }, { 24, 5 }, { 13, 4 }, { 30, 5 }, { 19, 7 }, { 3, 9 }, + { 4, 11 }, { 6, 13 }, { 5, 13 }, { 22, 13 }, { 21, 13 }, { 20, 10 }, + { 29, 8 }, { 25, 6 }, }, { /* AC bias group 2, table 3 */ - { 0x0, 4 }, { 0x75, 7 }, { 0x4A, 8 }, { 0x97, 9 }, - { 0x25B, 11 }, { 0x969, 13 }, { 0x968, 13 }, { 0xB, 5 }, - { 0xE8, 8 }, { 0x5, 3 }, { 0x4, 3 }, { 0x7, 4 }, - { 0xC, 4 }, { 0xD, 4 }, { 0x1, 4 }, { 0xA, 5 }, - { 0x39, 6 }, { 0x3B, 6 }, { 0x18, 6 }, { 0xE9, 8 }, - { 0x12C, 10 }, { 0x96B, 13 }, { 0x96A, 13 }, { 0x1, 3 }, - { 0x1F, 5 }, { 0x8, 5 }, { 0x19, 6 }, { 0x13, 6 }, - { 0xD, 5 }, { 0x24, 7 }, { 0x1E, 5 }, { 0x38, 6 } + { 0, 4 }, { 14, 4 }, { 23, 3 }, { 25, 5 }, { 29, 7 }, { 2, 8 }, + { 20, 10 }, { 6, 13 }, { 5, 13 }, { 22, 13 }, { 21, 13 }, { 4, 11 }, + { 3, 9 }, { 27, 6 }, { 15, 5 }, { 7, 5 }, { 18, 6 }, { 26, 6 }, + { 28, 5 }, { 11, 4 }, { 10, 3 }, { 9, 3 }, { 12, 4 }, { 13, 4 }, + { 31, 6 }, { 16, 6 }, { 8, 8 }, { 19, 8 }, { 1, 7 }, { 17, 6 }, + { 30, 5 }, { 24, 5 }, }, { /* AC bias group 2, table 4 */ - { 0x4, 4 }, { 0x14, 6 }, { 0x6E, 8 }, { 0x57, 8 }, - { 0x159, 10 }, { 0x562, 12 }, { 0xAC7, 13 }, { 0xB, 5 }, - { 0x6F, 8 }, { 0x6, 3 }, { 0x5, 3 }, { 0x8, 4 }, - { 0x9, 4 }, { 0x7, 4 }, { 0x1E, 5 }, { 0x2, 5 }, - { 0x7, 6 }, { 0x6, 6 }, { 0x2A, 7 }, { 0xAD, 9 }, - { 0xAC6, 13 }, { 0x561, 12 }, { 0x560, 12 }, { 0x1, 3 }, - { 0x1F, 5 }, { 0xC, 5 }, { 0x39, 6 }, { 0x1A, 6 }, - { 0x0, 4 }, { 0x36, 7 }, { 0x1D, 5 }, { 0x38, 6 } + { 28, 4 }, { 15, 5 }, { 17, 6 }, { 16, 6 }, { 23, 3 }, { 0, 4 }, + { 1, 6 }, { 18, 7 }, { 22, 12 }, { 21, 12 }, { 5, 12 }, { 20, 13 }, + { 6, 13 }, { 4, 10 }, { 19, 9 }, { 3, 8 }, { 7, 5 }, { 25, 5 }, + { 27, 6 }, { 29, 7 }, { 2, 8 }, { 8, 8 }, { 13, 4 }, { 11, 4 }, + { 12, 4 }, { 10, 3 }, { 9, 3 }, { 31, 6 }, { 26, 6 }, { 30, 5 }, + { 14, 5 }, { 24, 5 }, }, { /* AC bias group 2, table 5 */ - { 0x7, 4 }, { 0x1B, 6 }, { 0xE, 7 }, { 0xD, 7 }, - { 0x3E1, 10 }, { 0x1F06, 13 }, { 0x3E0F, 14 }, { 0x2, 5 }, - { 0xF9, 8 }, { 0x5, 3 }, { 0x6, 3 }, { 0x8, 4 }, - { 0x9, 4 }, { 0x4, 4 }, { 0xC, 5 }, { 0x1A, 6 }, - { 0xF, 7 }, { 0xC, 7 }, { 0x1F1, 9 }, { 0x7C0, 11 }, - { 0x3E0E, 14 }, { 0x1F05, 13 }, { 0x1F04, 13 }, { 0x1, 3 }, - { 0x0, 4 }, { 0x1C, 5 }, { 0x3F, 6 }, { 0x3D, 6 }, - { 0x5, 4 }, { 0x7D, 7 }, { 0x1D, 5 }, { 0x3C, 6 } + { 24, 4 }, { 7, 5 }, { 17, 7 }, { 3, 7 }, { 2, 7 }, { 16, 7 }, + { 23, 3 }, { 13, 4 }, { 28, 4 }, { 14, 5 }, { 15, 6 }, { 1, 6 }, + { 0, 4 }, { 11, 4 }, { 12, 4 }, { 9, 3 }, { 10, 3 }, { 25, 5 }, + { 30, 5 }, { 31, 6 }, { 27, 6 }, { 19, 11 }, { 22, 13 }, { 21, 13 }, + { 5, 13 }, { 20, 14 }, { 6, 14 }, { 4, 10 }, { 18, 9 }, { 8, 8 }, + { 29, 7 }, { 26, 6 }, }, { /* AC bias group 2, table 6 */ - { 0xF, 4 }, { 0xA, 5 }, { 0x71, 7 }, { 0x6, 6 }, - { 0x1C2, 9 }, { 0x702, 11 }, { 0x1C0E, 13 }, { 0x2, 5 }, - { 0xE, 7 }, { 0x5, 3 }, { 0x4, 3 }, { 0x6, 4 }, - { 0x7, 4 }, { 0x1D, 5 }, { 0x17, 6 }, { 0xF, 7 }, - { 0x1C3, 9 }, { 0x1C1, 9 }, { 0x380, 10 }, { 0x381F, 14 }, - { 0x381E, 14 }, { 0x1C0D, 13 }, { 0x1C0C, 13 }, { 0x1, 3 }, - { 0x4, 4 }, { 0x18, 5 }, { 0x1, 5 }, { 0x0, 5 }, - { 0xD, 4 }, { 0x16, 6 }, { 0x19, 5 }, { 0x39, 6 } + { 27, 5 }, { 26, 5 }, { 7, 5 }, { 3, 6 }, { 8, 7 }, { 15, 7 }, + { 23, 3 }, { 24, 4 }, { 1, 5 }, { 29, 6 }, { 14, 6 }, { 11, 4 }, + { 12, 4 }, { 10, 3 }, { 9, 3 }, { 25, 5 }, { 30, 5 }, { 28, 4 }, + { 18, 10 }, { 5, 11 }, { 22, 13 }, { 21, 13 }, { 6, 13 }, { 20, 14 }, + { 19, 14 }, { 17, 9 }, { 4, 9 }, { 16, 9 }, { 2, 7 }, { 31, 6 }, + { 13, 5 }, { 0, 4 }, }, { /* AC bias group 2, table 7 */ - { 0x2, 3 }, { 0x1E, 5 }, { 0x3B, 6 }, { 0xD, 5 }, - { 0x61, 7 }, { 0x1FA, 9 }, { 0x1FB5, 13 }, { 0x31, 6 }, - { 0xFC, 8 }, { 0x4, 3 }, { 0x5, 3 }, { 0x1, 4 }, - { 0x7, 4 }, { 0x3A, 6 }, { 0x60, 7 }, { 0x3F7, 10 }, - { 0x7EC, 11 }, { 0x1FB7, 13 }, { 0x3F6C, 14 }, { 0x7EDB, 15 }, - { 0x7EDA, 15 }, { 0x3F69, 14 }, { 0x3F68, 14 }, { 0x1, 3 }, - { 0x0, 4 }, { 0x19, 5 }, { 0x3E, 6 }, { 0x39, 6 }, - { 0xD, 4 }, { 0x38, 6 }, { 0xC, 5 }, { 0x7F, 7 } + { 24, 4 }, { 11, 4 }, { 23, 3 }, { 0, 3 }, { 30, 5 }, { 3, 5 }, + { 12, 4 }, { 9, 3 }, { 10, 3 }, { 14, 7 }, { 4, 7 }, { 7, 6 }, + { 25, 5 }, { 28, 4 }, { 29, 6 }, { 27, 6 }, { 13, 6 }, { 2, 6 }, + { 1, 5 }, { 26, 6 }, { 8, 8 }, { 5, 9 }, { 16, 11 }, { 22, 14 }, + { 21, 14 }, { 6, 13 }, { 18, 14 }, { 20, 15 }, { 19, 15 }, { 17, 13 }, + { 15, 10 }, { 31, 7 }, }, { /* AC bias group 2, table 8 */ - { 0x1E, 5 }, { 0x70, 7 }, { 0x127, 9 }, { 0x126, 9 }, - { 0x492, 11 }, { 0x124D, 13 }, { 0x124C, 13 }, { 0x1, 5 }, - { 0x7F, 7 }, { 0x6, 3 }, { 0x5, 3 }, { 0x5, 4 }, - { 0x4, 4 }, { 0x1, 4 }, { 0x7, 5 }, { 0x25, 6 }, - { 0x71, 7 }, { 0x7E, 7 }, { 0x48, 7 }, { 0x125, 9 }, - { 0x248, 10 }, { 0x124F, 13 }, { 0x124E, 13 }, { 0x3, 3 }, - { 0x8, 4 }, { 0x1D, 5 }, { 0x6, 5 }, { 0x3E, 6 }, - { 0x2, 4 }, { 0x0, 5 }, { 0x13, 5 }, { 0x39, 6 } + { 29, 5 }, { 7, 5 }, { 13, 4 }, { 28, 4 }, { 26, 5 }, { 14, 5 }, + { 12, 4 }, { 11, 4 }, { 23, 3 }, { 24, 4 }, { 18, 7 }, { 20, 10 }, + { 4, 11 }, { 6, 13 }, { 5, 13 }, { 22, 13 }, { 21, 13 }, { 19, 9 }, + { 3, 9 }, { 2, 9 }, { 15, 6 }, { 30, 5 }, { 10, 3 }, { 9, 3 }, + { 1, 7 }, { 16, 7 }, { 31, 6 }, { 25, 5 }, { 0, 5 }, { 27, 6 }, + { 17, 7 }, { 8, 7 }, }, { /* AC bias group 2, table 9 */ - { 0x1, 4 }, { 0x1, 6 }, { 0xE7, 8 }, { 0x91, 8 }, - { 0x240, 10 }, { 0x120D, 13 }, { 0x120C, 13 }, { 0x3C, 6 }, - { 0x0, 6 }, { 0x6, 3 }, { 0x5, 3 }, { 0x5, 4 }, - { 0x4, 4 }, { 0x1F, 5 }, { 0x4, 5 }, { 0x25, 6 }, - { 0x72, 7 }, { 0x49, 7 }, { 0xE6, 8 }, { 0x121, 9 }, - { 0x482, 11 }, { 0x120F, 13 }, { 0x120E, 13 }, { 0x3, 3 }, - { 0x8, 4 }, { 0x1D, 5 }, { 0x5, 5 }, { 0x3D, 6 }, - { 0x3, 4 }, { 0x1, 5 }, { 0x13, 5 }, { 0x38, 6 } + { 8, 6 }, { 1, 6 }, { 29, 5 }, { 0, 4 }, { 14, 5 }, { 26, 5 }, + { 28, 4 }, { 12, 4 }, { 11, 4 }, { 23, 3 }, { 24, 4 }, { 4, 10 }, + { 20, 11 }, { 6, 13 }, { 5, 13 }, { 22, 13 }, { 21, 13 }, { 19, 9 }, + { 3, 8 }, { 17, 7 }, { 15, 6 }, { 30, 5 }, { 10, 3 }, { 9, 3 }, + { 31, 6 }, { 16, 7 }, { 18, 8 }, { 2, 8 }, { 25, 5 }, { 7, 6 }, + { 27, 6 }, { 13, 5 }, }, { /* AC bias group 2, table 10 */ - { 0x4, 4 }, { 0xF, 6 }, { 0xF4, 8 }, { 0x5B, 8 }, - { 0x2D3, 11 }, { 0xB4A, 13 }, { 0x1697, 14 }, { 0x3C, 6 }, - { 0xE, 6 }, { 0x6, 3 }, { 0x5, 3 }, { 0x2, 4 }, - { 0x1, 4 }, { 0x1D, 5 }, { 0x0, 5 }, { 0x7B, 7 }, - { 0x2C, 7 }, { 0xF5, 8 }, { 0xB5, 9 }, { 0x168, 10 }, - { 0x1696, 14 }, { 0xB49, 13 }, { 0xB48, 13 }, { 0x3, 3 }, - { 0x9, 4 }, { 0x1F, 5 }, { 0xA, 5 }, { 0x1, 5 }, - { 0x8, 4 }, { 0x6, 5 }, { 0x1C, 5 }, { 0x17, 6 } + { 14, 5 }, { 27, 5 }, { 12, 4 }, { 11, 4 }, { 29, 5 }, { 8, 6 }, + { 1, 6 }, { 0, 4 }, { 26, 5 }, { 16, 7 }, { 19, 10 }, { 22, 13 }, + { 21, 13 }, { 5, 13 }, { 20, 14 }, { 6, 14 }, { 4, 11 }, { 18, 9 }, + { 3, 8 }, { 31, 6 }, { 23, 3 }, { 28, 4 }, { 24, 4 }, { 10, 3 }, + { 9, 3 }, { 30, 5 }, { 13, 5 }, { 7, 6 }, { 2, 8 }, { 17, 8 }, + { 15, 7 }, { 25, 5 }, }, { /* AC bias group 2, table 11 */ - { 0x8, 4 }, { 0x39, 6 }, { 0x1A, 7 }, { 0x3, 7 }, - { 0xDB, 10 }, { 0x6D6, 13 }, { 0xDAF, 14 }, { 0x3C, 6 }, - { 0xC, 6 }, { 0x6, 3 }, { 0x5, 3 }, { 0x2, 4 }, - { 0x1, 4 }, { 0x1D, 5 }, { 0x3D, 6 }, { 0x0, 6 }, - { 0x2, 7 }, { 0x37, 8 }, { 0x6C, 9 }, { 0x1B4, 11 }, - { 0xDAE, 14 }, { 0x6D5, 13 }, { 0x6D4, 13 }, { 0x2, 3 }, - { 0x7, 4 }, { 0x1F, 5 }, { 0x7, 5 }, { 0x1, 5 }, - { 0x9, 4 }, { 0xD, 5 }, { 0xC, 5 }, { 0x38, 6 } + { 15, 6 }, { 16, 7 }, { 3, 7 }, { 27, 5 }, { 12, 4 }, { 11, 4 }, + { 8, 6 }, { 2, 7 }, { 18, 9 }, { 19, 11 }, { 22, 13 }, { 21, 13 }, + { 5, 13 }, { 20, 14 }, { 6, 14 }, { 4, 10 }, { 17, 8 }, { 26, 5 }, + { 23, 3 }, { 30, 5 }, { 29, 5 }, { 24, 4 }, { 0, 4 }, { 28, 4 }, + { 10, 3 }, { 9, 3 }, { 31, 6 }, { 1, 6 }, { 13, 5 }, { 7, 6 }, + { 14, 6 }, { 25, 5 }, }, { /* AC bias group 2, table 12 */ - { 0xF, 4 }, { 0x4, 5 }, { 0x2F, 7 }, { 0x2E, 7 }, - { 0x54, 9 }, { 0x555, 13 }, { 0x554, 13 }, { 0x16, 6 }, - { 0xE, 6 }, { 0x6, 3 }, { 0x5, 3 }, { 0x1, 4 }, - { 0x0, 4 }, { 0x9, 5 }, { 0xB, 6 }, { 0x14, 7 }, - { 0x57, 9 }, { 0x56, 9 }, { 0xAB, 10 }, { 0x557, 13 }, - { 0x556, 13 }, { 0x2A9, 12 }, { 0x2A8, 12 }, { 0x3, 3 }, - { 0x8, 4 }, { 0x13, 5 }, { 0xA, 5 }, { 0x8, 5 }, - { 0xE, 4 }, { 0x12, 5 }, { 0x6, 5 }, { 0xF, 6 } + { 12, 4 }, { 11, 4 }, { 1, 5 }, { 15, 7 }, { 4, 9 }, { 22, 12 }, + { 21, 12 }, { 6, 13 }, { 5, 13 }, { 20, 13 }, { 19, 13 }, { 18, 10 }, + { 17, 9 }, { 16, 9 }, { 14, 6 }, { 30, 5 }, { 8, 6 }, { 31, 6 }, + { 27, 5 }, { 13, 5 }, { 26, 5 }, { 7, 6 }, { 3, 7 }, { 2, 7 }, + { 23, 3 }, { 24, 4 }, { 29, 5 }, { 25, 5 }, { 10, 3 }, { 9, 3 }, + { 28, 4 }, { 0, 4 }, }, { /* AC bias group 2, table 13 */ - { 0x1, 3 }, { 0xE, 5 }, { 0x6, 6 }, { 0x4, 6 }, - { 0xDA, 9 }, { 0xDBE, 13 }, { 0x1B7E, 14 }, { 0x7, 6 }, - { 0x1A, 6 }, { 0x5, 3 }, { 0x4, 3 }, { 0x1C, 5 }, - { 0x1B, 5 }, { 0x3A, 6 }, { 0x37, 7 }, { 0x6C, 8 }, - { 0x1B6, 10 }, { 0x36E, 11 }, { 0xDBD, 13 }, { 0x36FF, 15 }, - { 0x36FE, 15 }, { 0x1B79, 14 }, { 0x1B78, 14 }, { 0x2, 3 }, - { 0xC, 4 }, { 0x0, 4 }, { 0xF, 5 }, { 0xC, 5 }, - { 0xF, 4 }, { 0x1A, 5 }, { 0x3B, 6 }, { 0x5, 6 } + { 25, 4 }, { 3, 6 }, { 31, 6 }, { 2, 6 }, { 7, 6 }, { 0, 3 }, + { 23, 3 }, { 27, 5 }, { 8, 6 }, { 15, 8 }, { 4, 9 }, { 16, 10 }, + { 17, 11 }, { 22, 14 }, { 21, 14 }, { 18, 13 }, { 5, 13 }, { 6, 14 }, + { 20, 15 }, { 19, 15 }, { 14, 7 }, { 1, 5 }, { 26, 5 }, { 10, 3 }, + { 9, 3 }, { 24, 4 }, { 29, 5 }, { 12, 5 }, { 11, 5 }, { 13, 6 }, + { 30, 6 }, { 28, 4 }, }, { /* AC bias group 2, table 14 */ - { 0x5, 3 }, { 0x1E, 5 }, { 0x3A, 6 }, { 0x3E, 6 }, - { 0xFC, 8 }, { 0xFD7, 12 }, { 0x3F55, 14 }, { 0x77, 7 }, - { 0x30, 6 }, { 0x3, 3 }, { 0x4, 3 }, { 0x1A, 5 }, - { 0x19, 5 }, { 0x7F, 7 }, { 0x1FB, 9 }, { 0x3F4, 10 }, - { 0xFD6, 12 }, { 0x1FA9, 13 }, { 0x3F54, 14 }, { 0x3F57, 14 }, - { 0x3F56, 14 }, { 0x3F51, 14 }, { 0x3F50, 14 }, { 0x1, 3 }, - { 0x4, 4 }, { 0x1C, 5 }, { 0xB, 5 }, { 0xA, 5 }, - { 0x0, 3 }, { 0x1B, 5 }, { 0x31, 6 }, { 0x76, 7 } + { 28, 3 }, { 23, 3 }, { 24, 4 }, { 27, 5 }, { 26, 5 }, { 9, 3 }, + { 10, 3 }, { 0, 3 }, { 8, 6 }, { 30, 6 }, { 12, 5 }, { 11, 5 }, + { 29, 5 }, { 25, 5 }, { 2, 6 }, { 31, 7 }, { 7, 7 }, { 1, 5 }, + { 3, 6 }, { 4, 8 }, { 15, 10 }, { 22, 14 }, { 21, 14 }, { 17, 13 }, + { 18, 14 }, { 6, 14 }, { 20, 14 }, { 19, 14 }, { 16, 12 }, { 5, 12 }, + { 14, 9 }, { 13, 7 }, }, { /* AC bias group 2, table 15 */ - { 0x5, 3 }, { 0xC, 4 }, { 0x1B, 5 }, { 0x8, 4 }, - { 0x38, 6 }, { 0x15, 8 }, { 0xA3, 11 }, { 0xE6, 8 }, - { 0x4, 6 }, { 0x1, 3 }, { 0x2, 3 }, { 0x12, 5 }, - { 0x3, 5 }, { 0xB, 7 }, { 0x29, 9 }, { 0xA0, 11 }, - { 0x142, 12 }, { 0x287, 13 }, { 0x286, 13 }, { 0x289, 13 }, - { 0x288, 13 }, { 0x28B, 13 }, { 0x28A, 13 }, { 0xF, 4 }, - { 0x1D, 5 }, { 0x13, 5 }, { 0x1, 5 }, { 0x0, 5 }, - { 0x3, 3 }, { 0x1A, 5 }, { 0x72, 7 }, { 0xE7, 8 } - } -}; - -static const uint16_t vp4_ac_bias_2[16][32][2] = { + { 27, 5 }, { 26, 5 }, { 8, 6 }, { 15, 11 }, { 16, 12 }, { 18, 13 }, + { 17, 13 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, { 6, 11 }, + { 14, 9 }, { 5, 8 }, { 13, 7 }, { 12, 5 }, { 9, 3 }, { 10, 3 }, + { 28, 3 }, { 3, 4 }, { 11, 5 }, { 25, 5 }, { 0, 3 }, { 1, 4 }, + { 29, 5 }, { 2, 5 }, { 4, 6 }, { 30, 7 }, { 7, 8 }, { 31, 8 }, + { 24, 5 }, { 23, 4 }, + }, { /* AC bias group 3, table 0 */ - { 0x9, 5 }, { 0x15, 7 }, { 0x28, 8 }, { 0x52, 9 }, - { 0x29A, 12 }, { 0x537, 13 }, { 0x536, 13 }, { 0xA, 5 }, - { 0x54, 7 }, { 0x4, 3 }, { 0x3, 3 }, { 0xC, 4 }, - { 0xB, 4 }, { 0xD, 4 }, { 0x3, 4 }, { 0x14, 5 }, - { 0x3A, 6 }, { 0x4, 5 }, { 0x38, 6 }, { 0x55, 7 }, - { 0xA7, 10 }, { 0x299, 12 }, { 0x298, 12 }, { 0x0, 3 }, - { 0x1E, 5 }, { 0x8, 5 }, { 0x2B, 6 }, { 0xB, 6 }, - { 0xB, 5 }, { 0x3B, 6 }, { 0x1F, 5 }, { 0x39, 6 } + { 23, 3 }, { 17, 5 }, { 2, 8 }, { 3, 9 }, { 22, 12 }, { 21, 12 }, + { 4, 12 }, { 6, 13 }, { 5, 13 }, { 20, 10 }, { 1, 7 }, { 27, 6 }, + { 14, 4 }, { 25, 5 }, { 0, 5 }, { 7, 5 }, { 28, 5 }, { 10, 3 }, + { 9, 3 }, { 15, 5 }, { 8, 7 }, { 19, 7 }, { 26, 6 }, { 12, 4 }, + { 11, 4 }, { 13, 4 }, { 18, 6 }, { 31, 6 }, { 16, 6 }, { 29, 6 }, + { 24, 5 }, { 30, 5 }, }, { /* AC bias group 3, table 1 */ - { 0x1D, 5 }, { 0x2F, 7 }, { 0x2, 8 }, { 0x7, 9 }, - { 0x19, 11 }, { 0x35, 12 }, { 0x34, 12 }, { 0x9, 5 }, - { 0x2E, 7 }, { 0x6, 3 }, { 0x5, 3 }, { 0x9, 4 }, - { 0x8, 4 }, { 0x7, 4 }, { 0x1F, 5 }, { 0x8, 5 }, - { 0x18, 6 }, { 0x19, 6 }, { 0x1, 6 }, { 0x0, 7 }, - { 0x18, 11 }, { 0x37, 12 }, { 0x36, 12 }, { 0x1, 3 }, - { 0x1, 4 }, { 0xA, 5 }, { 0x39, 6 }, { 0x16, 6 }, - { 0xD, 5 }, { 0x1, 5 }, { 0x1E, 5 }, { 0x38, 6 } + { 19, 7 }, { 2, 8 }, { 20, 11 }, { 4, 11 }, { 6, 12 }, { 5, 12 }, + { 22, 12 }, { 21, 12 }, { 3, 9 }, { 18, 6 }, { 29, 5 }, { 24, 4 }, + { 23, 3 }, { 15, 5 }, { 7, 5 }, { 25, 5 }, { 27, 6 }, { 8, 7 }, + { 1, 7 }, { 16, 6 }, { 17, 6 }, { 28, 5 }, { 13, 4 }, { 12, 4 }, + { 11, 4 }, { 10, 3 }, { 9, 3 }, { 31, 6 }, { 26, 6 }, { 0, 5 }, + { 30, 5 }, { 14, 5 }, }, { /* AC bias group 3, table 2 */ - { 0x1, 4 }, { 0x71, 7 }, { 0xE0, 8 }, { 0x1C3, 9 }, - { 0x708, 11 }, { 0x1C26, 13 }, { 0x384F, 14 }, { 0x1, 5 }, - { 0x31, 7 }, { 0x6, 3 }, { 0x5, 3 }, { 0x9, 4 }, - { 0x8, 4 }, { 0x5, 4 }, { 0xF, 5 }, { 0x39, 6 }, - { 0x77, 7 }, { 0x76, 7 }, { 0x30, 7 }, { 0x385, 10 }, - { 0x384E, 14 }, { 0x1C25, 13 }, { 0x1C24, 13 }, { 0x1, 3 }, - { 0x4, 4 }, { 0xD, 5 }, { 0x0, 5 }, { 0x19, 6 }, - { 0x1F, 5 }, { 0xE, 5 }, { 0x1E, 5 }, { 0x3A, 6 } + { 26, 5 }, { 7, 5 }, { 0, 4 }, { 23, 3 }, { 24, 4 }, { 13, 4 }, + { 18, 7 }, { 8, 7 }, { 27, 6 }, { 25, 5 }, { 29, 5 }, { 14, 5 }, + { 12, 4 }, { 11, 4 }, { 10, 3 }, { 9, 3 }, { 2, 8 }, { 4, 11 }, + { 22, 13 }, { 21, 13 }, { 5, 13 }, { 20, 14 }, { 6, 14 }, { 19, 10 }, + { 3, 9 }, { 1, 7 }, { 15, 6 }, { 31, 6 }, { 17, 7 }, { 16, 7 }, + { 30, 5 }, { 28, 5 }, }, { /* AC bias group 3, table 3 */ - { 0x6, 4 }, { 0xC, 6 }, { 0xD6, 8 }, { 0x7B, 8 }, - { 0x1E8, 10 }, { 0x7A4, 12 }, { 0xF4B, 13 }, { 0x36, 6 }, - { 0x6A, 7 }, { 0x7, 3 }, { 0x5, 3 }, { 0x8, 4 }, - { 0x9, 4 }, { 0x1, 4 }, { 0x7, 5 }, { 0xD, 6 }, - { 0x3C, 7 }, { 0xD7, 8 }, { 0xF5, 9 }, { 0x7A7, 12 }, - { 0xF4A, 13 }, { 0xF4D, 13 }, { 0xF4C, 13 }, { 0x2, 3 }, - { 0x2, 4 }, { 0xE, 5 }, { 0x37, 6 }, { 0x34, 6 }, - { 0x0, 4 }, { 0x19, 5 }, { 0x18, 5 }, { 0x1F, 6 } + { 28, 4 }, { 13, 4 }, { 24, 4 }, { 1, 6 }, { 15, 6 }, { 14, 5 }, + { 23, 3 }, { 0, 4 }, { 25, 5 }, { 16, 7 }, { 4, 10 }, { 5, 12 }, + { 20, 13 }, { 6, 13 }, { 22, 13 }, { 21, 13 }, { 19, 12 }, { 18, 9 }, + { 3, 8 }, { 31, 6 }, { 11, 4 }, { 12, 4 }, { 10, 3 }, { 30, 5 }, + { 29, 5 }, { 27, 6 }, { 8, 7 }, { 2, 8 }, { 17, 8 }, { 7, 6 }, + { 26, 6 }, { 9, 3 }, }, { /* AC bias group 3, table 4 */ - { 0xA, 4 }, { 0x27, 6 }, { 0xBF, 8 }, { 0xBE, 8 }, - { 0x224, 10 }, { 0x225D, 14 }, { 0x225C, 14 }, { 0x26, 6 }, - { 0x5E, 7 }, { 0x7, 3 }, { 0x6, 3 }, { 0x6, 4 }, - { 0x7, 4 }, { 0x16, 5 }, { 0x2E, 6 }, { 0x45, 7 }, - { 0x88, 8 }, { 0x113, 9 }, { 0x44A, 11 }, { 0x225F, 14 }, - { 0x225E, 14 }, { 0x112D, 13 }, { 0x112C, 13 }, { 0x2, 3 }, - { 0x2, 4 }, { 0x12, 5 }, { 0x3, 5 }, { 0x2, 5 }, - { 0x3, 4 }, { 0x0, 4 }, { 0x10, 5 }, { 0x23, 6 } + { 29, 4 }, { 27, 5 }, { 26, 5 }, { 24, 4 }, { 28, 4 }, { 23, 3 }, + { 11, 4 }, { 12, 4 }, { 30, 5 }, { 16, 8 }, { 4, 10 }, { 18, 11 }, + { 22, 13 }, { 21, 13 }, { 6, 14 }, { 5, 14 }, { 20, 14 }, { 19, 14 }, + { 17, 9 }, { 15, 7 }, { 31, 6 }, { 25, 5 }, { 7, 6 }, { 1, 6 }, + { 0, 4 }, { 13, 5 }, { 14, 6 }, { 8, 7 }, { 3, 8 }, { 2, 8 }, + { 10, 3 }, { 9, 3 }, }, { /* AC bias group 3, table 5 */ - { 0xF, 4 }, { 0x6, 5 }, { 0x75, 7 }, { 0x74, 7 }, - { 0xA, 9 }, { 0xBF, 13 }, { 0xB9, 13 }, { 0x22, 6 }, - { 0x3, 7 }, { 0x5, 3 }, { 0x6, 3 }, { 0x1, 4 }, - { 0x2, 4 }, { 0x7, 5 }, { 0x0, 6 }, { 0x4, 8 }, - { 0x16, 10 }, { 0x5E, 12 }, { 0xB8, 13 }, { 0xBB, 13 }, - { 0xBA, 13 }, { 0x17D, 14 }, { 0x17C, 14 }, { 0x2, 3 }, - { 0x6, 4 }, { 0x1C, 5 }, { 0x10, 5 }, { 0x3B, 6 }, - { 0x9, 4 }, { 0x7, 4 }, { 0x1, 5 }, { 0x23, 6 } + { 14, 6 }, { 15, 8 }, { 4, 9 }, { 16, 10 }, { 18, 13 }, { 6, 13 }, + { 20, 13 }, { 19, 13 }, { 17, 12 }, { 22, 14 }, { 21, 14 }, { 5, 13 }, + { 8, 7 }, { 30, 5 }, { 11, 4 }, { 12, 4 }, { 1, 5 }, { 13, 5 }, + { 23, 3 }, { 24, 4 }, { 29, 4 }, { 26, 5 }, { 7, 6 }, { 31, 6 }, + { 28, 4 }, { 9, 3 }, { 10, 3 }, { 25, 5 }, { 3, 7 }, { 2, 7 }, + { 27, 6 }, { 0, 4 }, }, { /* AC bias group 3, table 6 */ - { 0x1, 3 }, { 0x1C, 5 }, { 0x36, 6 }, { 0x3B, 6 }, - { 0xEA, 8 }, { 0x75B, 11 }, { 0x1D65, 13 }, { 0x19, 6 }, - { 0x74, 7 }, { 0x4, 3 }, { 0x5, 3 }, { 0x0, 4 }, - { 0x1, 4 }, { 0x37, 6 }, { 0x1D7, 9 }, { 0x75A, 11 }, - { 0x1D64, 13 }, { 0x1D67, 13 }, { 0x1D66, 13 }, { 0x1D61, 13 }, - { 0x1D60, 13 }, { 0x1D63, 13 }, { 0x1D62, 13 }, { 0x2, 3 }, - { 0x1F, 5 }, { 0x1A, 5 }, { 0xD, 5 }, { 0x3D, 6 }, - { 0xC, 4 }, { 0x7, 4 }, { 0x3C, 6 }, { 0x18, 6 } + { 11, 4 }, { 12, 4 }, { 0, 3 }, { 23, 3 }, { 31, 6 }, { 7, 6 }, + { 26, 5 }, { 29, 4 }, { 9, 3 }, { 10, 3 }, { 28, 4 }, { 25, 5 }, + { 2, 6 }, { 13, 6 }, { 1, 5 }, { 8, 7 }, { 4, 8 }, { 20, 13 }, + { 19, 13 }, { 22, 13 }, { 21, 13 }, { 16, 13 }, { 6, 13 }, { 18, 13 }, + { 17, 13 }, { 15, 11 }, { 5, 11 }, { 14, 9 }, { 3, 6 }, { 30, 6 }, + { 27, 6 }, { 24, 5 }, }, { /* AC bias group 3, table 7 */ - { 0x2, 3 }, { 0x1, 4 }, { 0x14, 5 }, { 0x0, 4 }, - { 0x2F, 6 }, { 0xBB, 8 }, { 0x2E4, 10 }, { 0x7D, 7 }, - { 0xBA, 8 }, { 0x3, 3 }, { 0x4, 3 }, { 0x16, 5 }, - { 0x1A, 5 }, { 0xB8, 8 }, { 0x172E, 13 }, { 0x2E5F, 14 }, - { 0x2E5E, 14 }, { 0x1729, 13 }, { 0x1728, 13 }, { 0x172B, 13 }, - { 0x172A, 13 }, { 0x172D, 13 }, { 0x172C, 13 }, { 0x1, 3 }, - { 0x1E, 5 }, { 0x15, 5 }, { 0x1B, 5 }, { 0x3F, 6 }, - { 0xC, 4 }, { 0xE, 4 }, { 0x7C, 7 }, { 0x173, 9 } + { 3, 4 }, { 1, 4 }, { 23, 3 }, { 0, 3 }, { 9, 3 }, { 10, 3 }, + { 2, 5 }, { 25, 5 }, { 11, 5 }, { 13, 8 }, { 6, 10 }, { 18, 13 }, + { 17, 13 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, { 14, 13 }, + { 16, 14 }, { 15, 14 }, { 31, 9 }, { 8, 8 }, { 5, 8 }, { 4, 6 }, + { 28, 4 }, { 12, 5 }, { 26, 5 }, { 29, 4 }, { 24, 5 }, { 30, 7 }, + { 7, 7 }, { 27, 6 }, }, { /* AC bias group 3, table 8 */ - { 0x3, 4 }, { 0x7B, 7 }, { 0x58, 8 }, { 0x1EA, 9 }, - { 0x1EB1, 13 }, { 0x1EB0, 13 }, { 0x1EB3, 13 }, { 0x13, 6 }, - { 0x12, 6 }, { 0x5, 3 }, { 0x6, 3 }, { 0x2, 4 }, - { 0x1, 4 }, { 0x13, 5 }, { 0x3C, 6 }, { 0x2D, 7 }, - { 0xF4, 8 }, { 0x59, 8 }, { 0x3D7, 10 }, { 0xF5B, 12 }, - { 0x1EB2, 13 }, { 0x1EB5, 13 }, { 0x1EB4, 13 }, { 0x3, 3 }, - { 0xE, 4 }, { 0x1F, 5 }, { 0x12, 5 }, { 0x8, 5 }, - { 0x8, 4 }, { 0x0, 4 }, { 0xA, 5 }, { 0x17, 6 } + { 29, 4 }, { 12, 4 }, { 11, 4 }, { 0, 4 }, { 27, 5 }, { 8, 6 }, + { 7, 6 }, { 30, 5 }, { 2, 8 }, { 17, 8 }, { 15, 7 }, { 31, 6 }, + { 23, 3 }, { 28, 4 }, { 26, 5 }, { 13, 5 }, { 9, 3 }, { 10, 3 }, + { 24, 4 }, { 14, 6 }, { 16, 8 }, { 3, 9 }, { 5, 13 }, { 4, 13 }, + { 20, 13 }, { 6, 13 }, { 22, 13 }, { 21, 13 }, { 19, 12 }, { 18, 10 }, + { 1, 7 }, { 25, 5 }, }, { /* AC bias group 3, table 9 */ - { 0x8, 4 }, { 0x3C, 6 }, { 0xF5, 8 }, { 0xF4, 8 }, - { 0x1EF7, 13 }, { 0x3DE9, 14 }, { 0x3DE8, 14 }, { 0x1C, 6 }, - { 0xD, 6 }, { 0x5, 3 }, { 0x6, 3 }, { 0x1, 4 }, - { 0x0, 4 }, { 0x7, 5 }, { 0xC, 6 }, { 0xF6, 8 }, - { 0x1EE, 9 }, { 0x3DF, 10 }, { 0x7BC, 11 }, { 0x3DEB, 14 }, - { 0x3DEA, 14 }, { 0x3DED, 14 }, { 0x3DEC, 14 }, { 0x2, 3 }, - { 0x9, 4 }, { 0x1F, 5 }, { 0xF, 5 }, { 0x5, 5 }, - { 0xE, 4 }, { 0x6, 4 }, { 0x4, 5 }, { 0x1D, 6 } + { 12, 4 }, { 11, 4 }, { 30, 5 }, { 27, 5 }, { 14, 6 }, { 8, 6 }, + { 13, 5 }, { 23, 3 }, { 29, 4 }, { 7, 6 }, { 31, 6 }, { 26, 5 }, + { 0, 4 }, { 24, 4 }, { 9, 3 }, { 10, 3 }, { 28, 4 }, { 1, 6 }, + { 3, 8 }, { 2, 8 }, { 15, 8 }, { 16, 9 }, { 18, 11 }, { 6, 14 }, + { 5, 14 }, { 20, 14 }, { 19, 14 }, { 22, 14 }, { 21, 14 }, { 4, 13 }, + { 17, 10 }, { 25, 5 }, }, { /* AC bias group 3, table 10 */ - { 0x9, 4 }, { 0x39, 6 }, { 0x19, 7 }, { 0x18, 7 }, - { 0x706, 11 }, { 0x383D, 14 }, { 0x383C, 14 }, { 0xD, 6 }, - { 0xF, 6 }, { 0x5, 3 }, { 0x6, 3 }, { 0x0, 4 }, - { 0x1D, 5 }, { 0x3, 5 }, { 0x71, 7 }, { 0xE1, 8 }, - { 0x1C0, 9 }, { 0x382, 10 }, { 0x1C1D, 13 }, { 0x383F, 14 }, - { 0x383E, 14 }, { 0x3839, 14 }, { 0x3838, 14 }, { 0x2, 3 }, - { 0x8, 4 }, { 0x2, 4 }, { 0xD, 5 }, { 0xC, 5 }, - { 0xF, 4 }, { 0x7, 4 }, { 0x2, 5 }, { 0xE, 6 } + { 11, 4 }, { 30, 5 }, { 13, 5 }, { 25, 4 }, { 3, 7 }, { 2, 7 }, + { 7, 6 }, { 31, 6 }, { 8, 6 }, { 23, 3 }, { 27, 5 }, { 26, 5 }, + { 29, 4 }, { 24, 4 }, { 0, 4 }, { 9, 3 }, { 10, 3 }, { 16, 9 }, + { 17, 10 }, { 4, 11 }, { 22, 14 }, { 21, 14 }, { 18, 13 }, { 6, 14 }, + { 5, 14 }, { 20, 14 }, { 19, 14 }, { 15, 8 }, { 14, 7 }, { 1, 6 }, + { 12, 5 }, { 28, 4 }, }, { /* AC bias group 3, table 11 */ - { 0x0, 3 }, { 0x6, 5 }, { 0x35, 7 }, { 0x34, 7 }, - { 0x777, 11 }, { 0x1DD4, 13 }, { 0x3BAB, 14 }, { 0xE, 6 }, - { 0xF, 6 }, { 0x5, 3 }, { 0x4, 3 }, { 0x1C, 5 }, - { 0x19, 5 }, { 0x3A, 6 }, { 0xEF, 8 }, { 0x1DC, 9 }, - { 0x776, 11 }, { 0x774, 11 }, { 0x3BAA, 14 }, { 0x3BAD, 14 }, - { 0x3BAC, 14 }, { 0x3BAF, 14 }, { 0x3BAE, 14 }, { 0x2, 3 }, - { 0x7, 4 }, { 0x2, 4 }, { 0x18, 5 }, { 0xC, 5 }, - { 0xF, 4 }, { 0xD, 4 }, { 0x1B, 6 }, { 0x76, 7 } + { 0, 3 }, { 25, 4 }, { 1, 5 }, { 7, 6 }, { 8, 6 }, { 23, 3 }, + { 27, 5 }, { 3, 7 }, { 2, 7 }, { 30, 6 }, { 24, 4 }, { 10, 3 }, + { 9, 3 }, { 26, 5 }, { 12, 5 }, { 29, 4 }, { 11, 5 }, { 13, 6 }, + { 31, 7 }, { 15, 9 }, { 17, 11 }, { 5, 13 }, { 18, 14 }, { 6, 14 }, + { 20, 14 }, { 19, 14 }, { 22, 14 }, { 21, 14 }, { 16, 11 }, { 4, 11 }, + { 14, 8 }, { 28, 4 }, }, { /* AC bias group 3, table 12 */ - { 0x2, 3 }, { 0x11, 5 }, { 0x6, 6 }, { 0x4F, 7 }, - { 0x130, 9 }, { 0x1319, 13 }, { 0x1318, 13 }, { 0x4E, 7 }, - { 0x7, 6 }, { 0x6, 3 }, { 0x5, 3 }, { 0x10, 5 }, - { 0xD, 5 }, { 0x5, 6 }, { 0x99, 8 }, { 0x262, 10 }, - { 0x98E, 12 }, { 0x131B, 13 }, { 0x131A, 13 }, { 0x263D, 14 }, - { 0x263C, 14 }, { 0x263F, 14 }, { 0x263E, 14 }, { 0x1, 3 }, - { 0x7, 4 }, { 0x0, 4 }, { 0x12, 5 }, { 0xC, 5 }, - { 0xE, 4 }, { 0xF, 4 }, { 0x4, 6 }, { 0x4D, 7 } + { 25, 4 }, { 30, 6 }, { 13, 6 }, { 2, 6 }, { 8, 6 }, { 23, 3 }, + { 0, 3 }, { 27, 5 }, { 12, 5 }, { 24, 4 }, { 11, 5 }, { 1, 5 }, + { 26, 5 }, { 4, 9 }, { 15, 10 }, { 6, 13 }, { 5, 13 }, { 18, 13 }, + { 17, 13 }, { 16, 12 }, { 20, 14 }, { 19, 14 }, { 22, 14 }, { 21, 14 }, + { 14, 8 }, { 31, 7 }, { 7, 7 }, { 3, 7 }, { 10, 3 }, { 9, 3 }, + { 28, 4 }, { 29, 4 }, }, { /* AC bias group 3, table 13 */ - { 0x3, 3 }, { 0x0, 4 }, { 0x2, 5 }, { 0x37, 6 }, - { 0x1B7, 9 }, { 0xDB5, 12 }, { 0x36DD, 14 }, { 0x6C, 7 }, - { 0x16, 6 }, { 0x5, 3 }, { 0x4, 3 }, { 0x3, 5 }, - { 0xA, 5 }, { 0x2E, 7 }, { 0x36C, 10 }, { 0xDB4, 12 }, - { 0x36DC, 14 }, { 0x36DF, 14 }, { 0x36DE, 14 }, { 0x36D9, 14 }, - { 0x36D8, 14 }, { 0x36DB, 14 }, { 0x36DA, 14 }, { 0xE, 4 }, - { 0x4, 4 }, { 0x1A, 5 }, { 0x19, 5 }, { 0x18, 5 }, - { 0xF, 4 }, { 0x1, 3 }, { 0x2F, 7 }, { 0xDA, 8 } + { 1, 4 }, { 2, 5 }, { 11, 5 }, { 29, 3 }, { 24, 4 }, { 12, 5 }, + { 8, 6 }, { 13, 7 }, { 30, 7 }, { 0, 3 }, { 10, 3 }, { 9, 3 }, + { 27, 5 }, { 26, 5 }, { 25, 5 }, { 7, 7 }, { 31, 8 }, { 14, 10 }, + { 15, 12 }, { 5, 12 }, { 20, 14 }, { 19, 14 }, { 22, 14 }, { 21, 14 }, + { 16, 14 }, { 6, 14 }, { 18, 14 }, { 17, 14 }, { 4, 9 }, { 3, 6 }, + { 23, 4 }, { 28, 4 }, }, { /* AC bias group 3, table 14 */ - { 0x6, 3 }, { 0x6, 4 }, { 0xF, 5 }, { 0x0, 4 }, - { 0x75, 7 }, { 0x3B8, 10 }, { 0x1DCA, 13 }, { 0x74, 7 }, - { 0x76, 7 }, { 0x4, 3 }, { 0x5, 3 }, { 0x3, 5 }, - { 0x2, 5 }, { 0x1DE, 9 }, { 0xEE6, 12 }, { 0x3B97, 14 }, - { 0x3B96, 14 }, { 0x3B9D, 14 }, { 0x3B9C, 14 }, { 0x3B9F, 14 }, - { 0x3B9E, 14 }, { 0x1DC9, 13 }, { 0x1DC8, 13 }, { 0x5, 4 }, - { 0x1C, 5 }, { 0x9, 5 }, { 0xE, 5 }, { 0x8, 5 }, - { 0xF, 4 }, { 0x1, 3 }, { 0x1DF, 9 }, { 0x1DD, 9 } + { 3, 4 }, { 12, 5 }, { 11, 5 }, { 29, 3 }, { 27, 5 }, { 25, 5 }, + { 23, 4 }, { 1, 4 }, { 26, 5 }, { 2, 5 }, { 9, 3 }, { 10, 3 }, + { 0, 3 }, { 24, 5 }, { 7, 7 }, { 4, 7 }, { 8, 7 }, { 5, 10 }, + { 22, 13 }, { 21, 13 }, { 6, 13 }, { 16, 14 }, { 15, 14 }, { 14, 12 }, + { 18, 14 }, { 17, 14 }, { 20, 14 }, { 19, 14 }, { 31, 9 }, { 13, 9 }, + { 30, 9 }, { 28, 4 }, }, { /* AC bias group 3, table 15 */ - { 0x4, 3 }, { 0xB, 4 }, { 0x1D, 5 }, { 0xC, 4 }, - { 0x14, 5 }, { 0xE0, 8 }, { 0x3875, 14 }, { 0x386, 10 }, - { 0x1C2, 9 }, { 0x0, 2 }, { 0x1, 2 }, { 0x71, 7 }, - { 0x72, 7 }, { 0x1C3F, 13 }, { 0x3874, 14 }, { 0x3877, 14 }, - { 0x3876, 14 }, { 0x3871, 14 }, { 0x3870, 14 }, { 0x3873, 14 }, - { 0x3872, 14 }, { 0x3879, 14 }, { 0x3878, 14 }, { 0x3C, 6 }, - { 0x73, 7 }, { 0x2A, 6 }, { 0x3D, 6 }, { 0x2B, 6 }, - { 0x1F, 5 }, { 0xD, 4 }, { 0x1C3E, 13 }, { 0x1C3D, 13 } - } -}; - -static const uint16_t vp4_ac_bias_3[16][32][2] = { + { 9, 2 }, { 10, 2 }, { 0, 3 }, { 4, 5 }, { 25, 6 }, { 27, 6 }, + { 1, 4 }, { 3, 4 }, { 29, 4 }, { 5, 8 }, { 8, 9 }, { 7, 10 }, + { 18, 14 }, { 17, 14 }, { 20, 14 }, { 19, 14 }, { 14, 14 }, { 6, 14 }, + { 16, 14 }, { 15, 14 }, { 22, 14 }, { 21, 14 }, { 31, 13 }, { 30, 13 }, + { 13, 13 }, { 11, 7 }, { 12, 7 }, { 24, 7 }, { 2, 5 }, { 23, 6 }, + { 26, 6 }, { 28, 5 }, + }, { /* AC bias group 4, table 0 */ - { 0x7, 4 }, { 0xF, 6 }, { 0xBB, 8 }, { 0xBA, 8 }, - { 0x5CF, 11 }, { 0x173A, 13 }, { 0x2E77, 14 }, { 0x29, 6 }, - { 0x172, 9 }, { 0x7, 3 }, { 0x6, 3 }, { 0x9, 4 }, - { 0x8, 4 }, { 0x1, 4 }, { 0x5, 5 }, { 0xD, 6 }, - { 0x1D, 7 }, { 0x1C, 7 }, { 0xB8, 8 }, { 0x2E6, 10 }, - { 0x2E76, 14 }, { 0x1739, 13 }, { 0x1738, 13 }, { 0x2, 3 }, - { 0x6, 4 }, { 0x16, 5 }, { 0x4, 5 }, { 0x28, 6 }, - { 0x15, 5 }, { 0xC, 6 }, { 0x0, 4 }, { 0x2F, 6 } + { 30, 4 }, { 13, 4 }, { 26, 5 }, { 14, 5 }, { 29, 6 }, { 15, 6 }, + { 17, 7 }, { 16, 7 }, { 1, 6 }, { 23, 3 }, { 24, 4 }, { 0, 4 }, + { 12, 4 }, { 11, 4 }, { 27, 6 }, { 7, 6 }, { 28, 5 }, { 25, 5 }, + { 18, 8 }, { 8, 9 }, { 19, 10 }, { 22, 13 }, { 21, 13 }, { 5, 13 }, + { 20, 14 }, { 6, 14 }, { 4, 11 }, { 3, 8 }, { 2, 8 }, { 31, 6 }, + { 10, 3 }, { 9, 3 }, }, { /* AC bias group 4, table 1 */ - { 0xB, 4 }, { 0x2, 5 }, { 0x54, 7 }, { 0x2F, 7 }, - { 0x2AC, 10 }, { 0x156B, 13 }, { 0x1568, 13 }, { 0x16, 6 }, - { 0x154, 9 }, { 0x7, 3 }, { 0x6, 3 }, { 0x4, 4 }, - { 0x3, 4 }, { 0x13, 5 }, { 0x28, 6 }, { 0x2E, 7 }, - { 0x157, 9 }, { 0x155, 9 }, { 0x55B, 11 }, { 0x2AD3, 14 }, - { 0x2AD2, 14 }, { 0x2AD5, 14 }, { 0x2AD4, 14 }, { 0x3, 3 }, - { 0x8, 4 }, { 0x0, 4 }, { 0xA, 5 }, { 0x3, 5 }, - { 0x2, 4 }, { 0x2B, 6 }, { 0x12, 5 }, { 0x29, 6 } + { 25, 4 }, { 1, 5 }, { 27, 5 }, { 28, 4 }, { 12, 4 }, { 11, 4 }, + { 26, 5 }, { 7, 6 }, { 15, 7 }, { 3, 7 }, { 23, 3 }, { 24, 4 }, + { 30, 5 }, { 13, 5 }, { 14, 6 }, { 31, 6 }, { 2, 7 }, { 8, 9 }, + { 17, 9 }, { 4, 10 }, { 6, 13 }, { 20, 14 }, { 19, 14 }, { 22, 14 }, + { 21, 14 }, { 5, 13 }, { 18, 11 }, { 16, 9 }, { 29, 6 }, { 0, 4 }, + { 10, 3 }, { 9, 3 }, }, { /* AC bias group 4, table 2 */ - { 0xF, 4 }, { 0x7, 5 }, { 0x1, 6 }, { 0x0, 6 }, - { 0x1C4, 9 }, { 0x703, 11 }, { 0xE02, 12 }, { 0x11, 6 }, - { 0xE1, 8 }, { 0x5, 3 }, { 0x6, 3 }, { 0x2, 4 }, - { 0x1, 4 }, { 0x9, 5 }, { 0x10, 6 }, { 0xE3, 8 }, - { 0x1C5, 9 }, { 0x1C1, 9 }, { 0x702, 11 }, { 0x1C07, 13 }, - { 0x1C06, 13 }, { 0xE01, 12 }, { 0xE00, 12 }, { 0x4, 3 }, - { 0x7, 4 }, { 0x1D, 5 }, { 0xD, 5 }, { 0x1, 5 }, - { 0x5, 4 }, { 0x6, 5 }, { 0xC, 5 }, { 0x39, 6 } + { 3, 6 }, { 2, 6 }, { 27, 5 }, { 12, 4 }, { 11, 4 }, { 29, 5 }, + { 1, 5 }, { 14, 6 }, { 7, 6 }, { 13, 5 }, { 28, 4 }, { 30, 5 }, + { 26, 5 }, { 24, 4 }, { 23, 3 }, { 9, 3 }, { 10, 3 }, { 22, 12 }, + { 21, 12 }, { 6, 12 }, { 20, 13 }, { 19, 13 }, { 18, 11 }, { 5, 11 }, + { 17, 9 }, { 8, 8 }, { 4, 9 }, { 16, 9 }, { 15, 8 }, { 31, 6 }, + { 25, 5 }, { 0, 4 }, }, { /* AC bias group 4, table 3 */ - { 0x1, 3 }, { 0x1C, 5 }, { 0x11, 6 }, { 0x13, 6 }, - { 0x42, 8 }, { 0x207, 11 }, { 0x815, 13 }, { 0x75, 7 }, - { 0x41, 8 }, { 0x5, 3 }, { 0x6, 3 }, { 0x0, 4 }, - { 0x1F, 5 }, { 0x3B, 6 }, { 0x74, 7 }, { 0x43, 8 }, - { 0x80, 9 }, { 0x206, 11 }, { 0x814, 13 }, { 0x817, 13 }, - { 0x816, 13 }, { 0x409, 12 }, { 0x408, 12 }, { 0x3, 3 }, - { 0x9, 4 }, { 0x1E, 5 }, { 0x11, 5 }, { 0x3, 5 }, - { 0x5, 4 }, { 0x10, 5 }, { 0x2, 5 }, { 0x12, 6 } + { 11, 4 }, { 30, 5 }, { 27, 5 }, { 0, 3 }, { 16, 9 }, { 22, 12 }, + { 21, 12 }, { 18, 13 }, { 6, 13 }, { 20, 13 }, { 19, 13 }, { 17, 11 }, + { 5, 11 }, { 8, 8 }, { 4, 8 }, { 15, 8 }, { 2, 6 }, { 31, 6 }, + { 3, 6 }, { 28, 4 }, { 23, 3 }, { 29, 5 }, { 26, 5 }, { 24, 4 }, + { 9, 3 }, { 10, 3 }, { 1, 5 }, { 14, 7 }, { 7, 7 }, { 13, 6 }, + { 25, 5 }, { 12, 5 }, }, { /* AC bias group 4, table 4 */ - { 0x1, 3 }, { 0x1F, 5 }, { 0x27, 6 }, { 0x1, 5 }, - { 0x4B, 8 }, { 0x123, 10 }, { 0x915, 13 }, { 0x0, 6 }, - { 0x49, 8 }, { 0x5, 3 }, { 0x6, 3 }, { 0x1D, 5 }, - { 0x1C, 5 }, { 0x13, 6 }, { 0x4A, 8 }, { 0x90, 9 }, - { 0x914, 13 }, { 0x917, 13 }, { 0x916, 13 }, { 0x911, 13 }, - { 0x910, 13 }, { 0x913, 13 }, { 0x912, 13 }, { 0x3, 3 }, - { 0x5, 4 }, { 0x1, 4 }, { 0x12, 5 }, { 0x8, 5 }, - { 0x8, 4 }, { 0x1E, 5 }, { 0x26, 6 }, { 0x1, 6 } + { 7, 6 }, { 31, 6 }, { 3, 5 }, { 25, 4 }, { 0, 3 }, { 27, 5 }, + { 15, 9 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, { 16, 13 }, + { 6, 13 }, { 18, 13 }, { 17, 13 }, { 5, 10 }, { 8, 8 }, { 14, 8 }, + { 4, 8 }, { 13, 6 }, { 24, 4 }, { 23, 3 }, { 28, 4 }, { 26, 5 }, + { 30, 6 }, { 2, 6 }, { 9, 3 }, { 10, 3 }, { 12, 5 }, { 11, 5 }, + { 29, 5 }, { 1, 5 }, }, { /* AC bias group 4, table 5 */ - { 0x3, 3 }, { 0x1, 4 }, { 0x3F, 6 }, { 0xB, 5 }, - { 0x4E, 7 }, { 0x132, 9 }, { 0x99A, 12 }, { 0x4F, 7 }, - { 0x98, 8 }, { 0x6, 3 }, { 0x5, 3 }, { 0x1D, 5 }, - { 0x1C, 5 }, { 0x7C, 7 }, { 0x267, 10 }, { 0x1331, 13 }, - { 0x1330, 13 }, { 0x1333, 13 }, { 0x1332, 13 }, { 0x266D, 14 }, - { 0x266C, 14 }, { 0x266F, 14 }, { 0x266E, 14 }, { 0x1, 3 }, - { 0x4, 4 }, { 0x1E, 5 }, { 0x12, 5 }, { 0xA, 5 }, - { 0x8, 4 }, { 0x0, 4 }, { 0x7D, 7 }, { 0x4D, 7 } + { 29, 4 }, { 1, 4 }, { 23, 3 }, { 24, 4 }, { 27, 5 }, { 3, 5 }, + { 0, 3 }, { 28, 4 }, { 26, 5 }, { 8, 8 }, { 5, 9 }, { 16, 13 }, + { 15, 13 }, { 18, 13 }, { 17, 13 }, { 6, 12 }, { 20, 14 }, { 19, 14 }, + { 22, 14 }, { 21, 14 }, { 14, 10 }, { 31, 7 }, { 4, 7 }, { 7, 7 }, + { 10, 3 }, { 9, 3 }, { 12, 5 }, { 11, 5 }, { 25, 5 }, { 13, 7 }, + { 30, 7 }, { 2, 6 }, }, { /* AC bias group 4, table 6 */ - { 0x2, 3 }, { 0x7, 4 }, { 0x15, 5 }, { 0x3, 4 }, - { 0x4, 5 }, { 0xA7, 8 }, { 0x536, 11 }, { 0x28, 6 }, - { 0x29A, 10 }, { 0x6, 3 }, { 0x4, 3 }, { 0x1C, 5 }, - { 0x17, 5 }, { 0xA4, 8 }, { 0x29BE, 14 }, { 0x537F, 15 }, - { 0x537E, 15 }, { 0x29B9, 14 }, { 0x29B8, 14 }, { 0x29BB, 14 }, - { 0x29BA, 14 }, { 0x29BD, 14 }, { 0x29BC, 14 }, { 0xF, 4 }, - { 0x0, 4 }, { 0x5, 5 }, { 0x16, 5 }, { 0x1D, 5 }, - { 0x6, 4 }, { 0x1, 4 }, { 0xA5, 8 }, { 0x14C, 9 } + { 24, 4 }, { 29, 4 }, { 4, 5 }, { 25, 5 }, { 3, 4 }, { 0, 3 }, + { 28, 4 }, { 1, 4 }, { 10, 3 }, { 7, 6 }, { 13, 8 }, { 30, 8 }, + { 31, 9 }, { 8, 10 }, { 6, 11 }, { 18, 14 }, { 17, 14 }, { 20, 14 }, + { 19, 14 }, { 22, 14 }, { 21, 14 }, { 14, 14 }, { 16, 15 }, { 15, 15 }, + { 5, 8 }, { 2, 5 }, { 26, 5 }, { 12, 5 }, { 9, 3 }, { 11, 5 }, + { 27, 5 }, { 23, 4 }, }, { /* AC bias group 4, table 7 */ - { 0x4, 3 }, { 0x7, 4 }, { 0x1A, 5 }, { 0xC, 4 }, - { 0x6, 4 }, { 0x29, 6 }, { 0x1BD, 9 }, { 0x1BE3, 13 }, - { 0x1BE0, 13 }, { 0x0, 2 }, { 0x7, 3 }, { 0x6E, 7 }, - { 0x1BC, 9 }, { 0x37C3, 14 }, { 0x37C2, 14 }, { 0x37CD, 14 }, - { 0x37CC, 14 }, { 0x37CF, 14 }, { 0x37CE, 14 }, { 0x37C9, 14 }, - { 0x37C8, 14 }, { 0x37CB, 14 }, { 0x37CA, 14 }, { 0x15, 5 }, - { 0x1BF, 9 }, { 0x37D, 10 }, { 0x36, 6 }, { 0x2, 3 }, - { 0xB, 4 }, { 0x28, 6 }, { 0x37C5, 14 }, { 0x37C4, 14 } + { 9, 2 }, { 27, 3 }, { 4, 4 }, { 1, 4 }, { 0, 3 }, { 29, 6 }, + { 5, 6 }, { 23, 5 }, { 28, 4 }, { 3, 4 }, { 2, 5 }, { 26, 6 }, + { 11, 7 }, { 12, 9 }, { 6, 9 }, { 8, 13 }, { 14, 14 }, { 13, 14 }, + { 31, 14 }, { 30, 14 }, { 7, 13 }, { 20, 14 }, { 19, 14 }, { 22, 14 }, + { 21, 14 }, { 16, 14 }, { 15, 14 }, { 18, 14 }, { 17, 14 }, { 25, 10 }, + { 24, 9 }, { 10, 3 }, }, { /* AC bias group 4, table 8 */ - { 0x1, 3 }, { 0x9, 5 }, { 0x3, 6 }, { 0x2, 6 }, - { 0x11F, 10 }, { 0x8E9, 13 }, { 0x8E8, 13 }, { 0x2D, 7 }, - { 0x22, 7 }, { 0x6, 3 }, { 0x7, 3 }, { 0x10, 5 }, - { 0x11, 5 }, { 0x17, 6 }, { 0x2C, 7 }, { 0x46, 8 }, - { 0x11E, 10 }, { 0x11C, 10 }, { 0x477, 12 }, { 0x8EB, 13 }, - { 0x8EA, 13 }, { 0x8ED, 13 }, { 0x8EC, 13 }, { 0x3, 3 }, - { 0xB, 4 }, { 0x1, 4 }, { 0x14, 5 }, { 0xA, 5 }, - { 0x9, 4 }, { 0x15, 5 }, { 0x0, 5 }, { 0x10, 6 } + { 30, 5 }, { 3, 6 }, { 2, 6 }, { 25, 4 }, { 0, 3 }, { 31, 6 }, + { 8, 7 }, { 15, 8 }, { 17, 10 }, { 6, 13 }, { 5, 13 }, { 20, 13 }, + { 19, 13 }, { 22, 13 }, { 21, 13 }, { 18, 12 }, { 16, 10 }, { 4, 10 }, + { 1, 5 }, { 27, 5 }, { 14, 7 }, { 7, 7 }, { 13, 6 }, { 23, 3 }, + { 11, 5 }, { 12, 5 }, { 28, 4 }, { 26, 5 }, { 29, 5 }, { 24, 4 }, + { 9, 3 }, { 10, 3 }, }, { /* AC bias group 4, table 9 */ - { 0x1, 3 }, { 0x1D, 5 }, { 0x22, 6 }, { 0x13, 6 }, - { 0x11E, 9 }, { 0x8FC, 12 }, { 0x23F5, 14 }, { 0x23, 7 }, - { 0x22, 7 }, { 0x5, 3 }, { 0x6, 3 }, { 0x10, 5 }, - { 0xB, 5 }, { 0x10, 6 }, { 0x8E, 8 }, { 0x23E, 10 }, - { 0x8FF, 12 }, { 0x11FD, 13 }, { 0x23F4, 14 }, { 0x23F7, 14 }, - { 0x23F6, 14 }, { 0x23F9, 14 }, { 0x23F8, 14 }, { 0x3, 3 }, - { 0x9, 4 }, { 0x0, 4 }, { 0x1C, 5 }, { 0xA, 5 }, - { 0xF, 4 }, { 0x1, 4 }, { 0x12, 6 }, { 0x46, 7 } + { 25, 4 }, { 29, 4 }, { 0, 3 }, { 13, 6 }, { 8, 7 }, { 7, 7 }, + { 30, 6 }, { 3, 6 }, { 27, 5 }, { 12, 5 }, { 23, 3 }, { 11, 5 }, + { 2, 6 }, { 31, 7 }, { 14, 8 }, { 4, 9 }, { 15, 10 }, { 5, 12 }, + { 18, 14 }, { 6, 14 }, { 20, 14 }, { 19, 14 }, { 22, 14 }, { 21, 14 }, + { 17, 13 }, { 16, 12 }, { 24, 4 }, { 9, 3 }, { 10, 3 }, { 26, 5 }, + { 1, 5 }, { 28, 4 }, }, { /* AC bias group 4, table 10 */ - { 0x3, 3 }, { 0x1F, 5 }, { 0x3C, 6 }, { 0x3D, 6 }, - { 0x86, 8 }, { 0x877, 12 }, { 0x10E8, 13 }, { 0x41, 7 }, - { 0x40, 7 }, { 0x5, 3 }, { 0x6, 3 }, { 0x7, 5 }, - { 0x6, 5 }, { 0x4, 6 }, { 0x10F, 9 }, { 0x21C, 10 }, - { 0x875, 12 }, { 0x21D3, 14 }, { 0x21D2, 14 }, { 0x21D9, 14 }, - { 0x21D8, 14 }, { 0x21DB, 14 }, { 0x21DA, 14 }, { 0x2, 3 }, - { 0x9, 4 }, { 0x0, 4 }, { 0x11, 5 }, { 0x3, 5 }, - { 0xE, 4 }, { 0x2, 4 }, { 0x5, 6 }, { 0x42, 7 } + { 25, 4 }, { 13, 6 }, { 30, 6 }, { 27, 5 }, { 29, 4 }, { 12, 5 }, + { 11, 5 }, { 23, 3 }, { 0, 3 }, { 8, 7 }, { 7, 7 }, { 31, 7 }, + { 4, 8 }, { 15, 10 }, { 6, 13 }, { 18, 14 }, { 17, 14 }, { 16, 12 }, + { 20, 14 }, { 19, 14 }, { 22, 14 }, { 21, 14 }, { 5, 12 }, { 14, 9 }, + { 26, 5 }, { 24, 4 }, { 9, 3 }, { 10, 3 }, { 28, 4 }, { 2, 6 }, + { 3, 6 }, { 1, 5 }, }, { /* AC bias group 4, table 11 */ - { 0x4, 3 }, { 0x1, 4 }, { 0x3D, 6 }, { 0x9, 5 }, - { 0xF3, 8 }, { 0x793, 11 }, { 0x1E45, 13 }, { 0x0, 7 }, - { 0x2, 7 }, { 0x5, 3 }, { 0x6, 3 }, { 0x8, 5 }, - { 0x1, 5 }, { 0x3, 7 }, { 0x1E5, 9 }, { 0x792, 11 }, - { 0x1E44, 13 }, { 0x1E47, 13 }, { 0x1E46, 13 }, { 0x1E41, 13 }, - { 0x1E40, 13 }, { 0x1E43, 13 }, { 0x1E42, 13 }, { 0x1, 3 }, - { 0x6, 4 }, { 0x1F, 5 }, { 0xF, 5 }, { 0xE, 5 }, - { 0xE, 4 }, { 0x5, 4 }, { 0x78, 7 }, { 0x1, 7 } + { 7, 7 }, { 31, 7 }, { 8, 7 }, { 13, 7 }, { 12, 5 }, { 1, 4 }, + { 23, 3 }, { 11, 5 }, { 3, 5 }, { 29, 4 }, { 24, 4 }, { 27, 5 }, + { 26, 5 }, { 0, 3 }, { 9, 3 }, { 10, 3 }, { 28, 4 }, { 30, 7 }, + { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, { 16, 13 }, { 6, 13 }, + { 18, 13 }, { 17, 13 }, { 15, 11 }, { 5, 11 }, { 14, 9 }, { 4, 8 }, + { 2, 6 }, { 25, 5 }, }, { /* AC bias group 4, table 12 */ - { 0x4, 3 }, { 0x5, 4 }, { 0xE, 5 }, { 0x17, 5 }, - { 0x3E, 7 }, { 0xF0, 9 }, { 0xF1E, 13 }, { 0x7A, 8 }, - { 0x7F, 8 }, { 0x6, 3 }, { 0x7, 3 }, { 0x5, 5 }, - { 0x4, 5 }, { 0x7B, 8 }, { 0x1E2, 10 }, { 0x1E3F, 14 }, - { 0x1E3E, 14 }, { 0xF19, 13 }, { 0xF18, 13 }, { 0xF1B, 13 }, - { 0xF1A, 13 }, { 0xF1D, 13 }, { 0xF1C, 13 }, { 0x0, 3 }, - { 0x3, 4 }, { 0x16, 5 }, { 0x9, 5 }, { 0x8, 5 }, - { 0xA, 4 }, { 0x6, 4 }, { 0x7E, 8 }, { 0x79, 8 } + { 23, 3 }, { 12, 5 }, { 11, 5 }, { 24, 4 }, { 27, 5 }, { 26, 5 }, + { 1, 4 }, { 29, 4 }, { 2, 5 }, { 5, 9 }, { 14, 10 }, { 18, 13 }, + { 17, 13 }, { 20, 13 }, { 19, 13 }, { 22, 13 }, { 21, 13 }, { 6, 13 }, + { 16, 14 }, { 15, 14 }, { 31, 8 }, { 7, 8 }, { 13, 8 }, { 4, 7 }, + { 30, 8 }, { 8, 8 }, { 0, 3 }, { 28, 4 }, { 25, 5 }, { 3, 5 }, + { 9, 3 }, { 10, 3 }, }, { /* AC bias group 4, table 13 */ - { 0x5, 3 }, { 0xC, 4 }, { 0x1A, 5 }, { 0x4, 4 }, - { 0x1A, 6 }, { 0xDE, 9 }, { 0xDF4, 13 }, { 0xDD, 9 }, - { 0x6D, 8 }, { 0x0, 2 }, { 0x7, 3 }, { 0x25, 6 }, - { 0x24, 6 }, { 0xDC, 9 }, { 0xDF7, 13 }, { 0x1BEB, 14 }, - { 0x1BEA, 14 }, { 0xDF1, 13 }, { 0xDF0, 13 }, { 0xDF3, 13 }, - { 0xDF2, 13 }, { 0x1BED, 14 }, { 0x1BEC, 14 }, { 0x8, 4 }, - { 0x13, 5 }, { 0xC, 5 }, { 0x37, 6 }, { 0x36, 6 }, - { 0x5, 4 }, { 0x7, 4 }, { 0x6C, 8 }, { 0x1BF, 10 } + { 9, 2 }, { 3, 4 }, { 28, 4 }, { 25, 5 }, { 4, 6 }, { 30, 8 }, + { 8, 8 }, { 13, 9 }, { 7, 9 }, { 5, 9 }, { 18, 13 }, { 17, 13 }, + { 20, 13 }, { 19, 13 }, { 6, 13 }, { 16, 14 }, { 15, 14 }, { 22, 14 }, + { 21, 14 }, { 14, 13 }, { 31, 10 }, { 29, 4 }, { 23, 4 }, { 12, 6 }, + { 11, 6 }, { 24, 5 }, { 0, 3 }, { 1, 4 }, { 2, 5 }, { 27, 6 }, + { 26, 6 }, { 10, 3 }, }, { /* AC bias group 4, table 14 */ - { 0x5, 3 }, { 0xD, 4 }, { 0x1F, 5 }, { 0xC, 4 }, - { 0x3B, 6 }, { 0x40, 7 }, { 0x41A, 11 }, { 0x104, 9 }, - { 0x107, 9 }, { 0x1, 2 }, { 0x0, 2 }, { 0x24, 6 }, - { 0x21, 6 }, { 0x20B, 10 }, { 0x106E, 13 }, { 0x20DF, 14 }, - { 0x20DE, 14 }, { 0x1055, 13 }, { 0x1054, 13 }, { 0x1057, 13 }, - { 0x1056, 13 }, { 0x106D, 13 }, { 0x106C, 13 }, { 0x11, 5 }, - { 0x3A, 6 }, { 0x25, 6 }, { 0x38, 6 }, { 0x39, 6 }, - { 0x13, 5 }, { 0x1E, 5 }, { 0x20C, 10 }, { 0x414, 11 } + { 10, 2 }, { 9, 2 }, { 5, 7 }, { 7, 9 }, { 31, 11 }, { 18, 13 }, + { 17, 13 }, { 20, 13 }, { 19, 13 }, { 13, 10 }, { 30, 10 }, { 6, 11 }, + { 22, 13 }, { 21, 13 }, { 14, 13 }, { 16, 14 }, { 15, 14 }, { 8, 9 }, + { 12, 6 }, { 23, 5 }, { 11, 6 }, { 25, 6 }, { 28, 5 }, { 0, 3 }, + { 3, 4 }, { 1, 4 }, { 26, 6 }, { 27, 6 }, { 24, 6 }, { 4, 6 }, + { 29, 5 }, { 2, 5 }, }, { /* AC bias group 4, table 15 */ - { 0x0, 2 }, { 0x7, 4 }, { 0xD, 5 }, { 0x5, 4 }, - { 0x9, 5 }, { 0x22, 7 }, { 0xCD1, 13 }, { 0xCD0, 13 }, - { 0xCD3, 13 }, { 0x3, 2 }, { 0x2, 2 }, { 0x8D, 9 }, - { 0xCC, 9 }, { 0x66B, 12 }, { 0xCD2, 13 }, { 0x19B5, 14 }, - { 0x19B4, 14 }, { 0x19B7, 14 }, { 0x19B6, 14 }, { 0x19B1, 14 }, - { 0x19B0, 14 }, { 0x19B3, 14 }, { 0x19B2, 14 }, { 0x47, 8 }, - { 0x8C, 9 }, { 0x337, 11 }, { 0x67, 8 }, { 0x18, 6 }, - { 0x10, 6 }, { 0x32, 7 }, { 0xCD5, 13 }, { 0xCD4, 13 } - } + { 0, 2 }, { 28, 6 }, { 5, 7 }, { 24, 9 }, { 11, 9 }, { 23, 8 }, + { 4, 5 }, { 3, 4 }, { 27, 6 }, { 29, 7 }, { 12, 9 }, { 7, 13 }, + { 6, 13 }, { 14, 13 }, { 8, 13 }, { 31, 13 }, { 30, 13 }, { 13, 12 }, + { 20, 14 }, { 19, 14 }, { 22, 14 }, { 21, 14 }, { 16, 14 }, { 15, 14 }, + { 18, 14 }, { 17, 14 }, { 25, 11 }, { 26, 8 }, { 2, 5 }, { 1, 4 }, + { 10, 2 }, { 9, 2 }, + }, }; #endif /* AVCODEC_VP4DATA_H */ diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index 65cf46870..46090f25c 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -26,6 +26,8 @@ #ifndef AVCODEC_VP56_H #define AVCODEC_VP56_H +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "get_bits.h" #include "hpeldsp.h" diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index e84fcdeaa..d16e7b6aa 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -25,6 +25,7 @@ */ #include "libavutil/imgutils.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "hwconfig.h" @@ -187,7 +188,7 @@ static av_always_inline int update_dimensions(VP8Context *s, int width, int height, int is_vp7) { AVCodecContext *avctx = s->avctx; - int i, ret; + int i, ret, dim_reset = 0; if (width != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base || height != s->avctx->height) { @@ -196,9 +197,12 @@ int update_dimensions(VP8Context *s, int width, int height, int is_vp7) ret = ff_set_dimensions(s->avctx, width, height); if (ret < 0) return ret; + + dim_reset = (s->macroblocks_base != NULL); } - if (!s->actually_webp && !is_vp7) { + if ((s->pix_fmt == AV_PIX_FMT_NONE || dim_reset) && + !s->actually_webp && !is_vp7) { s->pix_fmt = get_pixel_format(s); if (s->pix_fmt < 0) return AVERROR(EINVAL); @@ -2618,7 +2622,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, static av_always_inline int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, - AVPacket *avpkt, int is_vp7) + const AVPacket *avpkt, int is_vp7) { VP8Context *s = avctx->priv_data; int ret, i, referenced, num_jobs; @@ -2962,7 +2966,7 @@ AVCodec ff_vp8_decoder = { AV_CODEC_CAP_SLICE_THREADS, .flush = vp8_decode_flush, .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context), - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_VP8_VAAPI_HWACCEL HWACCEL_VAAPI(vp8), #endif diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h index 70d21e3c6..e6091dfe0 100644 --- a/libavcodec/vp8.h +++ b/libavcodec/vp8.h @@ -29,6 +29,7 @@ #include #include "libavutil/buffer.h" +#include "libavutil/mem_internal.h" #include "libavutil/thread.h" #include "h264pred.h" diff --git a/libavcodec/vp8data.h b/libavcodec/vp8data.h index 5e6dea761..1fcce134e 100644 --- a/libavcodec/vp8data.h +++ b/libavcodec/vp8data.h @@ -316,12 +316,6 @@ static const uint8_t vp8_pred4x4_prob_intra[10][10][9] = { }, }; -static const int8_t vp8_segmentid_tree[][2] = { - { 1, 2 }, - { -0, -1 }, // '00', '01' - { -2, -3 }, // '10', '11' -}; - static const uint8_t vp8_coeff_band[16] = { 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7 }; diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index fd0bab14a..4659f94ee 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -207,9 +207,6 @@ static int update_size(AVCodecContext *avctx, int w, int h) switch (s->pix_fmt) { case AV_PIX_FMT_YUV420P: -#if CONFIG_VP9_VDPAU_HWACCEL - *fmtp++ = AV_PIX_FMT_VDPAU; -#endif case AV_PIX_FMT_YUV420P10: #if CONFIG_VP9_DXVA2_HWACCEL *fmtp++ = AV_PIX_FMT_DXVA2_VLD; @@ -223,6 +220,9 @@ static int update_size(AVCodecContext *avctx, int w, int h) #endif #if CONFIG_VP9_VAAPI_HWACCEL *fmtp++ = AV_PIX_FMT_VAAPI; +#endif +#if CONFIG_VP9_VDPAU_HWACCEL + *fmtp++ = AV_PIX_FMT_VDPAU; #endif break; case AV_PIX_FMT_YUV420P12: @@ -231,6 +231,9 @@ static int update_size(AVCodecContext *avctx, int w, int h) #endif #if CONFIG_VP9_VAAPI_HWACCEL *fmtp++ = AV_PIX_FMT_VAAPI; +#endif +#if CONFIG_VP9_VDPAU_HWACCEL + *fmtp++ = AV_PIX_FMT_VDPAU; #endif break; } @@ -1891,7 +1894,7 @@ AVCodec ff_vp9_decoder = { .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context), .profiles = NULL_IF_CONFIG_SMALL(ff_vp9_profiles), .bsfs = "vp9_superframe_split", - .hw_configs = (const AVCodecHWConfigInternal*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_VP9_DXVA2_HWACCEL HWACCEL_DXVA2(vp9), #endif diff --git a/libavcodec/vp9_metadata_bsf.c b/libavcodec/vp9_metadata_bsf.c index 2ca494e69..d904a0088 100644 --- a/libavcodec/vp9_metadata_bsf.c +++ b/libavcodec/vp9_metadata_bsf.c @@ -21,15 +21,12 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_vp9.h" typedef struct VP9MetadataContext { - const AVClass *class; - - CodedBitstreamContext *cbc; - CodedBitstreamFragment fragment; + CBSBSFContext common; int color_space; int color_range; @@ -38,21 +35,11 @@ typedef struct VP9MetadataContext { } VP9MetadataContext; -static int vp9_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) +static int vp9_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *frag) { VP9MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->fragment; - int err, i; - - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = ff_cbs_read_packet(ctx->cbc, frag, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } + int i; for (i = 0; i < frag->nb_units; i++) { VP9RawFrame *frame = frag->units[i].content; @@ -90,35 +77,19 @@ static int vp9_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) } } - err = ff_cbs_write_packet(ctx->cbc, pkt, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; - } - - err = 0; -fail: - ff_cbs_fragment_reset(ctx->cbc, frag); - - if (err < 0) - av_packet_unref(pkt); - - return err; + return 0; } +static const CBSBSFType vp9_metadata_type = { + .codec_id = AV_CODEC_ID_VP9, + .fragment_name = "superframe", + .unit_name = "frame", + .update_fragment = &vp9_metadata_update_fragment, +}; + static int vp9_metadata_init(AVBSFContext *bsf) { - VP9MetadataContext *ctx = bsf->priv_data; - - return ff_cbs_init(&ctx->cbc, AV_CODEC_ID_VP9, bsf); -} - -static void vp9_metadata_close(AVBSFContext *bsf) -{ - VP9MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(ctx->cbc, &ctx->fragment); - ff_cbs_close(&ctx->cbc); + return ff_cbs_bsf_generic_init(bsf, &vp9_metadata_type); } #define OFFSET(x) offsetof(VP9MetadataContext, x) @@ -169,7 +140,7 @@ const AVBitStreamFilter ff_vp9_metadata_bsf = { .priv_data_size = sizeof(VP9MetadataContext), .priv_class = &vp9_metadata_class, .init = &vp9_metadata_init, - .close = &vp9_metadata_close, - .filter = &vp9_metadata_filter, + .close = &ff_cbs_bsf_generic_close, + .filter = &ff_cbs_bsf_generic_filter, .codec_ids = vp9_metadata_codec_ids, }; diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index cc2440b85..d82b258a3 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -29,6 +29,7 @@ #include #include "libavutil/buffer.h" +#include "libavutil/mem_internal.h" #include "libavutil/thread.h" #include "libavutil/internal.h" diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index f6d73f73c..41b8ad1ad 100644 --- a/libavcodec/vp9dsp.c +++ b/libavcodec/vp9dsp.c @@ -23,6 +23,8 @@ #include "libavutil/avassert.h" #include "libavutil/common.h" +#include "libavutil/mem_internal.h" + #include "vp9dsp.h" const DECLARE_ALIGNED(16, int16_t, ff_vp9_subpel_filters)[3][16][8] = { diff --git a/libavcodec/vp9recon.c b/libavcodec/vp9recon.c index 9a4e7c7a0..e38cf99ec 100644 --- a/libavcodec/vp9recon.c +++ b/libavcodec/vp9recon.c @@ -22,6 +22,7 @@ */ #include "libavutil/avassert.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "internal.h" diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index f77548e5a..2d49172ea 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -1024,13 +1024,12 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) return ret; } - av_buffer_unref(&fdst->dsd_ref); fdst->dsdctx = NULL; fdst->dsd_channels = 0; + ret = av_buffer_replace(&fdst->dsd_ref, fsrc->dsd_ref); + if (ret < 0) + return ret; if (fsrc->dsd_ref) { - fdst->dsd_ref = av_buffer_ref(fsrc->dsd_ref); - if (!fdst->dsd_ref) - return AVERROR(ENOMEM); fdst->dsdctx = (DSDContext*)fdst->dsd_ref->data; fdst->dsd_channels = fsrc->dsd_channels; } @@ -1712,6 +1711,7 @@ AVCodec ff_wavpack_decoder = { .flush = wavpack_decode_flush, .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | - AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, + AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/wavpack.h b/libavcodec/wavpack.h index 43aaac815..7e7dfce2b 100644 --- a/libavcodec/wavpack.h +++ b/libavcodec/wavpack.h @@ -124,43 +124,8 @@ static const int wv_rates[16] = { }; // 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 -}; +extern const uint8_t ff_wp_exp2_table[256]; +extern const uint8_t ff_wp_log2_table[256]; static av_always_inline int wp_exp2(int16_t val) { @@ -171,7 +136,7 @@ static av_always_inline int wp_exp2(int16_t val) neg = 1; } - res = wp_exp2_table[val & 0xFF] | 0x100; + res = ff_wp_exp2_table[val & 0xFF] | 0x100; val >>= 8; if (val > 31U) return INT_MIN; @@ -190,9 +155,9 @@ static av_always_inline int wp_log2(uint32_t val) val += val >> 9; bits = av_log2(val) + 1; if (bits < 9) - return (bits << 8) + wp_log2_table[(val << (9 - bits)) & 0xFF]; + return (bits << 8) + ff_wp_log2_table[(val << (9 - bits)) & 0xFF]; else - return (bits << 8) + wp_log2_table[(val >> (bits - 9)) & 0xFF]; + return (bits << 8) + ff_wp_log2_table[(val >> (bits - 9)) & 0xFF]; } #endif /* AVCODEC_WAVPACK_H */ diff --git a/libavcodec/wavpackdata.c b/libavcodec/wavpackdata.c new file mode 100644 index 000000000..1c777afc1 --- /dev/null +++ b/libavcodec/wavpackdata.c @@ -0,0 +1,60 @@ +/* + * WavPack decoder/encoder common data + * Copyright (c) 2006,2011 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 + */ + +#include "wavpack.h" + +const uint8_t ff_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 +}; + +const uint8_t ff_wp_log2_table[256] = { + 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 +}; diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c index 0c85fbe37..0a798438b 100644 --- a/libavcodec/wavpackenc.c +++ b/libavcodec/wavpackenc.c @@ -644,9 +644,9 @@ static uint32_t log2sample(uint32_t v, int limit, uint32_t *result) uint32_t dbits = count_bits(v); if ((v += v >> 9) < (1 << 8)) { - *result += (dbits << 8) + wp_log2_table[(v << (9 - dbits)) & 0xff]; + *result += (dbits << 8) + ff_wp_log2_table[(v << (9 - dbits)) & 0xff]; } else { - *result += dbits = (dbits << 8) + wp_log2_table[(v >> (dbits - 9)) & 0xff]; + *result += dbits = (dbits << 8) + ff_wp_log2_table[(v >> (dbits - 9)) & 0xff]; if (limit && dbits >= limit) return 1; diff --git a/libavcodec/webp.c b/libavcodec/webp.c index c6d020684..5a7aebc58 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -189,6 +189,7 @@ typedef struct WebPContext { VP8Context v; /* VP8 Context used for lossy decoding */ GetBitContext gb; /* bitstream reader for main image chunk */ AVFrame *alpha_frame; /* AVFrame for alpha data decompressed from VP8L */ + AVPacket *pkt; /* AVPacket to be passed to the underlying VP8 decoder */ AVCodecContext *avctx; /* parent AVCodecContext */ int initialized; /* set once the VP8 context is initialized */ int has_alpha; /* has a separate alpha chunk */ @@ -232,44 +233,6 @@ static void image_ctx_free(ImageContext *img) memset(img, 0, sizeof(*img)); } - -/* Differs from get_vlc2() in the following ways: - * - codes are bit-reversed - * - assumes 8-bit table to make reversal simpler - * - assumes max depth of 2 since the max code length for WebP is 15 - */ -static av_always_inline int webp_get_vlc(GetBitContext *gb, VLC_TYPE (*table)[2]) -{ - int n, nb_bits; - unsigned int index; - int code; - - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - - index = SHOW_UBITS(re, gb, 8); - index = ff_reverse[index]; - code = table[index][0]; - n = table[index][1]; - - if (n < 0) { - LAST_SKIP_BITS(re, gb, 8); - UPDATE_CACHE(re, gb); - - nb_bits = -n; - - index = SHOW_UBITS(re, gb, nb_bits); - index = (ff_reverse[index] >> (8 - nb_bits)) + code; - code = table[index][0]; - n = table[index][1]; - } - SKIP_BITS(re, gb, n); - - CLOSE_READER(re, gb); - - return code; -} - static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb) { if (r->simple) { @@ -278,10 +241,10 @@ static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb) else return r->simple_symbols[get_bits1(gb)]; } else - return webp_get_vlc(gb, r->vlc.table); + return get_vlc2(gb, r->vlc.table, 8, 2); } -static int huff_reader_build_canonical(HuffReader *r, int *code_lengths, +static int huff_reader_build_canonical(HuffReader *r, const uint8_t *code_lengths, int alphabet_size) { int len = 0, sym, code = 0, ret; @@ -332,7 +295,7 @@ static int huff_reader_build_canonical(HuffReader *r, int *code_lengths, ret = init_vlc(&r->vlc, 8, alphabet_size, code_lengths, sizeof(*code_lengths), sizeof(*code_lengths), - codes, sizeof(*codes), sizeof(*codes), 0); + codes, sizeof(*codes), sizeof(*codes), INIT_VLC_OUTPUT_LE); if (ret < 0) { av_free(codes); return ret; @@ -362,13 +325,12 @@ static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, int alphabet_size) { HuffReader code_len_hc = { { 0 }, 0, 0, { 0 } }; - int *code_lengths = NULL; - int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 }; + uint8_t *code_lengths; + uint8_t code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 }; int i, symbol, max_symbol, prev_code_len, ret; int num_codes = 4 + get_bits(&s->gb, 4); - if (num_codes > NUM_CODE_LENGTH_CODES) - return AVERROR_INVALIDDATA; + av_assert1(num_codes <= NUM_CODE_LENGTH_CODES); for (i = 0; i < num_codes; i++) code_length_code_lengths[code_length_code_order[i]] = get_bits(&s->gb, 3); @@ -376,9 +338,9 @@ static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, ret = huff_reader_build_canonical(&code_len_hc, code_length_code_lengths, NUM_CODE_LENGTH_CODES); if (ret < 0) - goto finish; + return ret; - code_lengths = av_mallocz_array(alphabet_size, sizeof(*code_lengths)); + code_lengths = av_mallocz(alphabet_size); if (!code_lengths) { ret = AVERROR(ENOMEM); goto finish; @@ -1329,7 +1291,6 @@ static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, unsigned int data_size) { WebPContext *s = avctx->priv_data; - AVPacket pkt; int ret; if (!s->initialized) { @@ -1345,11 +1306,11 @@ static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, return AVERROR_PATCHWELCOME; } - av_init_packet(&pkt); - pkt.data = data_start; - pkt.size = data_size; + av_packet_unref(s->pkt); + s->pkt->data = data_start; + s->pkt->size = data_size; - ret = ff_vp8_decode_frame(avctx, p, got_frame, &pkt); + ret = ff_vp8_decode_frame(avctx, p, got_frame, s->pkt); if (ret < 0) return ret; @@ -1566,10 +1527,23 @@ exif_end: return avpkt->size; } +static av_cold int webp_decode_init(AVCodecContext *avctx) +{ + WebPContext *s = avctx->priv_data; + + s->pkt = av_packet_alloc(); + if (!s->pkt) + return AVERROR(ENOMEM); + + return 0; +} + static av_cold int webp_decode_close(AVCodecContext *avctx) { WebPContext *s = avctx->priv_data; + av_packet_free(&s->pkt); + if (s->initialized) return ff_vp8_decode_free(avctx); @@ -1582,6 +1556,7 @@ AVCodec ff_webp_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WEBP, .priv_data_size = sizeof(WebPContext), + .init = webp_decode_init, .decode = webp_decode_frame, .close = webp_decode_close, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, diff --git a/libavcodec/wma.c b/libavcodec/wma.c index b4992095e..cfa5fa335 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -39,19 +39,17 @@ static av_cold int init_coef_vlc(VLC *vlc, uint16_t **prun_table, const uint8_t *table_bits = vlc_table->huffbits; const uint32_t *table_codes = vlc_table->huffcodes; const uint16_t *levels_table = vlc_table->levels; - uint16_t *run_table, *level_table, *int_table; + uint16_t *run_table, *int_table; float *flevel_table; int i, l, j, k, level; init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0); run_table = av_malloc_array(n, sizeof(uint16_t)); - level_table = av_malloc_array(n, sizeof(uint16_t)); flevel_table = av_malloc_array(n, sizeof(*flevel_table)); int_table = av_malloc_array(n, sizeof(uint16_t)); - if (!run_table || !level_table || !flevel_table || !int_table) { + if (!run_table || !flevel_table || !int_table) { av_freep(&run_table); - av_freep(&level_table); av_freep(&flevel_table); av_freep(&int_table); return AVERROR(ENOMEM); @@ -64,7 +62,6 @@ static av_cold int init_coef_vlc(VLC *vlc, uint16_t **prun_table, l = levels_table[k++]; for (j = 0; j < l; j++) { run_table[i] = j; - level_table[i] = level; flevel_table[i] = level; i++; } @@ -73,7 +70,6 @@ static av_cold int init_coef_vlc(VLC *vlc, uint16_t **prun_table, *prun_table = run_table; *plevel_table = flevel_table; *pint_table = int_table; - av_free(level_table); return 0; } diff --git a/libavcodec/wma.h b/libavcodec/wma.h index c7fcf5047..aea7ba28a 100644 --- a/libavcodec/wma.h +++ b/libavcodec/wma.h @@ -23,6 +23,7 @@ #define AVCODEC_WMA_H #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "fft.h" @@ -139,8 +140,7 @@ typedef struct WMACodecContext { #endif /* TRACE */ } WMACodecContext; -extern const uint16_t ff_wma_hgain_huffcodes[37]; -extern const uint8_t ff_wma_hgain_huffbits[37]; +extern const uint8_t ff_wma_hgain_hufftab[37][2]; extern const float ff_wma_lsp_codebook[NB_LSP_COEFS][16]; extern const uint32_t ff_aac_scalefactor_code[121]; extern const uint8_t ff_aac_scalefactor_bits[121]; diff --git a/libavcodec/wmadata.h b/libavcodec/wmadata.h index 641cb1813..ca485a566 100644 --- a/libavcodec/wmadata.h +++ b/libavcodec/wmadata.h @@ -51,18 +51,14 @@ static const uint8_t exponent_band_44100[3][25] = { { 17, 4, 8, 8, 4, 12, 12, 8, 8, 24, 16, 20, 24, 32, 40, 60, 80, 152, }, }; -const uint16_t ff_wma_hgain_huffcodes[37] = { - 0x00003, 0x002e7, 0x00001, 0x005cd, 0x0005d, 0x005c9, 0x0005e, 0x00003, - 0x00016, 0x0000b, 0x00001, 0x00006, 0x00001, 0x00006, 0x00004, 0x00005, - 0x00004, 0x00007, 0x00003, 0x00007, 0x00004, 0x0000a, 0x0000a, 0x00002, - 0x00003, 0x00000, 0x00005, 0x00002, 0x0005f, 0x00004, 0x00003, 0x00002, - 0x005c8, 0x000b8, 0x005ca, 0x005cb, 0x005cc, -}; - -const uint8_t ff_wma_hgain_huffbits[37] = { - 10, 12, 10, 13, 9, 13, 9, 8, 7, 5, 5, 4, 4, 3, 3, 3, - 4, 3, 4, 4, 5, 5, 6, 8, 7, 10, 8, 10, 9, 8, 9, 9, - 13, 10, 13, 13, 13, +const uint8_t ff_wma_hgain_hufftab[37][2] = { + { 25, 10 }, { 2, 10 }, { 27, 10 }, { 0, 10 }, { 31, 9 }, { 30, 9 }, + { 23, 8 }, { 7, 8 }, { 29, 8 }, { 26, 8 }, { 24, 7 }, { 10, 5 }, + { 12, 4 }, { 20, 5 }, { 22, 6 }, { 8, 7 }, { 33, 10 }, { 32, 13 }, + { 5, 13 }, { 34, 13 }, { 35, 13 }, { 36, 13 }, { 3, 13 }, { 1, 12 }, + { 4, 9 }, { 6, 9 }, { 28, 9 }, { 18, 4 }, { 16, 4 }, { 21, 5 }, + { 9, 5 }, { 11, 4 }, { 19, 4 }, { 14, 3 }, { 15, 3 }, { 13, 3 }, + { 17, 3 }, }; const float ff_wma_lsp_codebook[NB_LSP_COEFS][16] = { diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 07fd960f7..9c79556bb 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -110,9 +110,9 @@ static av_cold int wma_decode_init(AVCodecContext *avctx) ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1, 1.0 / 32768.0); if (s->use_noise_coding) { - init_vlc(&s->hgain_vlc, HGAINVLCBITS, sizeof(ff_wma_hgain_huffbits), - ff_wma_hgain_huffbits, 1, 1, - ff_wma_hgain_huffcodes, 2, 2, 0); + ff_init_vlc_from_lengths(&s->hgain_vlc, HGAINVLCBITS, FF_ARRAY_ELEMS(ff_wma_hgain_hufftab), + &ff_wma_hgain_hufftab[0][1], 2, + &ff_wma_hgain_hufftab[0][0], 2, 1, -18, 0, avctx); } if (s->use_exp_vlc) @@ -345,10 +345,6 @@ static int decode_exp_vlc(WMACodecContext *s, int ch) while (q < q_end) { code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); - if (code < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Exponent vlc invalid\n"); - return -1; - } /* NOTE: this offset is the same as MPEG-4 AAC! */ last_exp += code - 60; if ((unsigned) last_exp + 60 >= FF_ARRAY_ELEMS(pow_tab)) { @@ -549,7 +545,7 @@ static int wma_decode_block(WMACodecContext *s) } for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { - int i, n, val, code; + int i, n, val; n = s->exponent_high_sizes[bsize]; val = (int) 0x80000000; @@ -558,14 +554,8 @@ static int wma_decode_block(WMACodecContext *s) if (val == (int) 0x80000000) { val = get_bits(&s->gb, 7) - 19; } else { - code = get_vlc2(&s->gb, s->hgain_vlc.table, + val += get_vlc2(&s->gb, s->hgain_vlc.table, HGAINVLCBITS, HGAINMAX); - if (code < 0) { - av_log(s->avctx, AV_LOG_ERROR, - "hgain vlc invalid\n"); - return -1; - } - val += code - 18; } s->high_band_values[ch][i] = val; } diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index 091bc2ac3..6a7e23d01 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -343,7 +343,7 @@ static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], s->coef_vlcs[tindex]->huffcodes[1]); } if (s->version == 1 && s->avctx->channels >= 2) - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); } return 0; } @@ -358,7 +358,7 @@ static int encode_frame(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], else if (encode_block(s, src_coefs, total_gain) < 0) return INT_MAX; - avpriv_align_put_bits(&s->pb); + align_put_bits(&s->pb); return put_bits_count(&s->pb) / 8 - s->avctx->block_align; } diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index b8d0f6220..e1fcf8afe 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -26,6 +26,7 @@ #include "libavutil/attributes.h" #include "libavutil/avassert.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" #include "internal.h" @@ -1160,14 +1161,14 @@ static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len, s->num_saved_bits += len; if (!append) { - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), + ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), s->num_saved_bits); } else { int align = 8 - (get_bits_count(gb) & 7); align = FFMIN(align, len); put_bits(&s->pb, align, get_bits(gb, align)); len -= align; - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); + ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); } skip_bits_long(gb, len); diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 5d76050e3..8024ce161 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -92,6 +92,8 @@ #include "libavutil/float_dsp.h" #include "libavutil/intfloat.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "internal.h" #include "get_bits.h" @@ -1579,14 +1581,14 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, s->num_saved_bits += len; if (!append) { - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), + ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), s->num_saved_bits); } else { int align = 8 - (get_bits_count(gb) & 7); align = FFMIN(align, len); put_bits(&s->pb, align, get_bits(gb, align)); len -= align; - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); + ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); } skip_bits_long(gb, len); diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index f6550c6a7..f1e1504a8 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -29,7 +29,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/thread.h" #include "avcodec.h" #include "internal.h" @@ -367,7 +367,7 @@ static av_cold void wmavoice_flush(AVCodecContext *ctx) static av_cold int wmavoice_decode_init(AVCodecContext *ctx) { static AVOnce init_static_once = AV_ONCE_INIT; - int n, flags, pitch_range, lsp16_flag; + int n, flags, pitch_range, lsp16_flag, ret; WMAVoiceContext *s = ctx->priv_data; ff_thread_once(&init_static_once, wmavoice_init_static_data); @@ -395,10 +395,11 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) s->spillover_bitsize = 3 + av_ceil_log2(ctx->block_align); s->do_apf = flags & 0x1; if (s->do_apf) { - ff_rdft_init(&s->rdft, 7, DFT_R2C); - ff_rdft_init(&s->irdft, 7, IDFT_C2R); - ff_dct_init(&s->dct, 6, DCT_I); - ff_dct_init(&s->dst, 6, DST_I); + if ((ret = ff_rdft_init(&s->rdft, 7, DFT_R2C)) < 0 || + (ret = ff_rdft_init(&s->irdft, 7, IDFT_C2R)) < 0 || + (ret = ff_dct_init (&s->dct, 6, DCT_I)) < 0 || + (ret = ff_dct_init (&s->dst, 6, DST_I)) < 0) + return ret; ff_sine_window_init(s->cos, 256); memcpy(&s->sin[255], s->cos, 256 * sizeof(s->cos[0])); @@ -1865,7 +1866,7 @@ static int parse_packet_header(WMAVoiceContext *s) * @param size size of the source data, in bytes * @param gb bit I/O context specifying the current position in the source. * data. This function might use this to align the bit position to - * a whole-byte boundary before calling #avpriv_copy_bits() on aligned + * a whole-byte boundary before calling #ff_copy_bits() on aligned * source data * @param nbits the amount of bits to copy from source to target * @@ -1886,7 +1887,7 @@ static void copy_bits(PutBitContext *pb, rmn_bits &= 7; rmn_bytes >>= 3; if ((rmn_bits = FFMIN(rmn_bits, nbits)) > 0) put_bits(pb, rmn_bits, get_bits(gb, rmn_bits)); - avpriv_copy_bits(pb, data + size - rmn_bytes, + ff_copy_bits(pb, data + size - rmn_bytes, FFMIN(nbits - rmn_bits, rmn_bytes << 3)); } diff --git a/libavcodec/wmv2.h b/libavcodec/wmv2.h index 0f459ae5a..f425332c9 100644 --- a/libavcodec/wmv2.h +++ b/libavcodec/wmv2.h @@ -21,6 +21,8 @@ #ifndef AVCODEC_WMV2_H #define AVCODEC_WMV2_H +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "intrax8.h" #include "mpegvideo.h" diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c index afa65478e..7aae11568 100644 --- a/libavcodec/wmv2dec.c +++ b/libavcodec/wmv2dec.c @@ -278,22 +278,16 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s) return 0; } -static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr) +static inline void wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr) { MpegEncContext *const s = &w->s; - int ret; - ret = ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr); - - if (ret < 0) - return ret; + ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr); if ((((*mx_ptr) | (*my_ptr)) & 1) && s->mspel) w->hshift = get_bits1(&s->gb); else w->hshift = 0; - - return 0; } static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py) @@ -409,8 +403,6 @@ int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64]) code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[w->cbp_table_index].table, MB_NON_INTRA_VLC_BITS, 3); - if (code < 0) - return AVERROR_INVALIDDATA; s->mb_intra = (~code & 0x40) >> 6; cbp = code & 0x3f; @@ -419,11 +411,6 @@ int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64]) if (get_bits_left(&s->gb) <= 0) return AVERROR_INVALIDDATA; code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - if (code < 0) { - av_log(s->avctx, AV_LOG_ERROR, - "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y); - return AVERROR_INVALIDDATA; - } /* predict coded block pattern */ cbp = 0; for (i = 0; i < 6; i++) { @@ -456,8 +443,7 @@ int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64]) w->per_block_abt = 0; } - if ((ret = wmv2_decode_motion(w, &mx, &my)) < 0) - return ret; + wmv2_decode_motion(w, &mx, &my); s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; @@ -537,6 +523,7 @@ AVCodec ff_wmv2_decoder = { .close = wmv2_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, }; diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index 915e9c7dc..dcf417763 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -24,89 +24,72 @@ * Winnov WNV1 codec. */ +#include "libavutil/thread.h" + +#define BITSTREAM_READER_LE #include "avcodec.h" #include "get_bits.h" #include "internal.h" -#include "mathops.h" - -typedef struct WNV1Context { - int shift; - GetBitContext gb; -} WNV1Context; - -static const uint16_t code_tab[16][2] = { - { 0x1FD, 9 }, { 0xFD, 8 }, { 0x7D, 7 }, { 0x3D, 6 }, { 0x1D, 5 }, { 0x0D, 4 }, { 0x005, 3 }, - { 0x000, 1 }, - { 0x004, 3 }, { 0x0C, 4 }, { 0x1C, 5 }, { 0x3C, 6 }, { 0x7C, 7 }, { 0xFC, 8 }, { 0x1FC, 9 }, { 0xFF, 8 } +static const uint8_t code_tab[16][2] = { + { 7, 1 }, { 8, 3 }, { 6, 3 }, { 9, 4 }, { 5, 4 }, { 10, 5 }, { 4, 5 }, + { 11, 6 }, { 3, 6 }, { 12, 7 }, { 2, 7 }, { 13, 8 }, { 1, 8 }, { 14, 9 }, + { 0, 9 }, { 15, 8 } }; #define CODE_VLC_BITS 9 static VLC code_vlc; /* returns modified base_value */ -static inline int wnv1_get_code(WNV1Context *w, int base_value) +static inline int wnv1_get_code(GetBitContext *gb, int shift, int base_value) { - int v = get_vlc2(&w->gb, code_vlc.table, CODE_VLC_BITS, 1); + int v = get_vlc2(gb, code_vlc.table, CODE_VLC_BITS, 1); - if (v == 15) - return ff_reverse[get_bits(&w->gb, 8 - w->shift)]; + if (v == 8) + return get_bits(gb, 8 - shift) << shift; else - return base_value + ((v - 7U) << w->shift); + return base_value + v * (1 << shift); } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - WNV1Context * const l = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AVFrame * const p = data; + GetBitContext gb; unsigned char *Y,*U,*V; - int i, j, ret; + int i, j, ret, shift; int prev_y = 0, prev_u = 0, prev_v = 0; - uint8_t *rbuf; if (buf_size < 8 + avctx->height * (avctx->width/2)/8) { av_log(avctx, AV_LOG_ERROR, "Packet size %d is too small\n", buf_size); return AVERROR_INVALIDDATA; } - rbuf = av_malloc(buf_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!rbuf) { - av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); - return AVERROR(ENOMEM); - } - memset(rbuf + buf_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - - if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { - av_free(rbuf); + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; - } p->key_frame = 1; - for (i = 8; i < buf_size; i++) - rbuf[i] = ff_reverse[buf[i]]; - - if ((ret = init_get_bits8(&l->gb, rbuf + 8, buf_size - 8)) < 0) + if ((ret = init_get_bits8(&gb, buf + 8, buf_size - 8)) < 0) return ret; if (buf[2] >> 4 == 6) - l->shift = 2; + shift = 2; else { - l->shift = 8 - (buf[2] >> 4); - if (l->shift > 4) { + shift = 8 - (buf[2] >> 4); + if (shift > 4) { avpriv_request_sample(avctx, "Unknown WNV1 frame header value %i", buf[2] >> 4); - l->shift = 4; + shift = 4; } - if (l->shift < 1) { + if (shift < 1) { avpriv_request_sample(avctx, "Unknown WNV1 frame header value %i", buf[2] >> 4); - l->shift = 1; + shift = 1; } } @@ -115,10 +98,10 @@ static int decode_frame(AVCodecContext *avctx, V = p->data[2]; for (j = 0; j < avctx->height; j++) { for (i = 0; i < avctx->width / 2; i++) { - Y[i * 2] = wnv1_get_code(l, prev_y); - prev_u = U[i] = wnv1_get_code(l, prev_u); - prev_y = Y[(i * 2) + 1] = wnv1_get_code(l, Y[i * 2]); - prev_v = V[i] = wnv1_get_code(l, prev_v); + Y[i * 2] = wnv1_get_code(&gb, shift, prev_y); + prev_u = U[i] = wnv1_get_code(&gb, shift, prev_u); + prev_y = Y[(i * 2) + 1] = wnv1_get_code(&gb, shift, Y[i * 2]); + prev_v = V[i] = wnv1_get_code(&gb, shift, prev_v); } Y += p->linesize[0]; U += p->linesize[1]; @@ -127,22 +110,25 @@ static int decode_frame(AVCodecContext *avctx, *got_frame = 1; - av_free(rbuf); return buf_size; } +static av_cold void wnv1_init_static(void) +{ + INIT_VLC_STATIC_FROM_LENGTHS(&code_vlc, CODE_VLC_BITS, 16, + &code_tab[0][1], 2, + &code_tab[0][0], 2, 1, + -7, INIT_VLC_OUTPUT_LE, 1 << CODE_VLC_BITS); +} + static av_cold int decode_init(AVCodecContext *avctx) { - static VLC_TYPE code_table[1 << CODE_VLC_BITS][2]; + static AVOnce init_static_once = AV_ONCE_INIT; avctx->pix_fmt = AV_PIX_FMT_YUV422P; - code_vlc.table = code_table; - code_vlc.table_allocated = 1 << CODE_VLC_BITS; - init_vlc(&code_vlc, CODE_VLC_BITS, 16, - &code_tab[0][1], 4, 2, - &code_tab[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC); + ff_thread_once(&init_static_once, wnv1_init_static); return 0; } @@ -152,8 +138,8 @@ AVCodec ff_wnv1_decoder = { .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 = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c index 0f005807a..958c06773 100644 --- a/libavcodec/ws-snd1.c +++ b/libavcodec/ws-snd1.c @@ -177,5 +177,6 @@ AVCodec ff_ws_snd1_decoder = { .id = AV_CODEC_ID_WESTWOOD_SND1, .init = ws_snd_decode_init, .decode = ws_snd_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 194135daf..636116118 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -50,6 +50,8 @@ OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp_init.o OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp_init.o OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp_init.o OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp.o +OBJS-$(CONFIG_CFHD_DECODER) += x86/cfhddsp_init.o +OBJS-$(CONFIG_CFHD_ENCODER) += x86/cfhdencdsp_init.o OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp_init.o x86/synth_filter_init.o OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc_init.o OBJS-$(CONFIG_EXR_DECODER) += x86/exrdsp_init.o @@ -153,6 +155,8 @@ X86ASM-OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp.o X86ASM-OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp.o X86ASM-OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp.o X86ASM-OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsidct.o +X86ASM-OBJS-$(CONFIG_CFHD_ENCODER) += x86/cfhdencdsp.o +X86ASM-OBJS-$(CONFIG_CFHD_DECODER) += x86/cfhddsp.o X86ASM-OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp.o x86/synth_filter.o X86ASM-OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp.o \ x86/dirac_dwt.o diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm index 675ade310..4ddaa9432 100644 --- a/libavcodec/x86/ac3dsp.asm +++ b/libavcodec/x86/ac3dsp.asm @@ -35,10 +35,6 @@ pw_bap_mul2: dw 5, 7, 0, 7, 5, 7, 0, 7 cextern pd_1 pd_151: times 4 dd 151 -; used in ff_apply_window_int16() -pb_revwords: SHUFFLE_MASK_W 7, 6, 5, 4, 3, 2, 1, 0 -pd_16384: times 4 dd 16384 - SECTION .text ;----------------------------------------------------------------------------- @@ -81,133 +77,6 @@ AC3_EXPONENT_MIN %endif %undef LOOP_ALIGN -;----------------------------------------------------------------------------- -; int ff_ac3_max_msb_abs_int16(const int16_t *src, int len) -; -; This function uses 2 different methods to calculate a valid result. -; 1) logical 'or' of abs of each element -; This is used for ssse3 because of the pabsw instruction. -; It is also used for mmx because of the lack of min/max instructions. -; 2) calculate min/max for the array, then or(abs(min),abs(max)) -; This is used for mmxext and sse2 because they have pminsw/pmaxsw. -;----------------------------------------------------------------------------- - -; logical 'or' of 4 or 8 words in an mmx or xmm register into the low word -%macro OR_WORDS_HORIZ 2 ; src, tmp -%if cpuflag(sse2) - movhlps %2, %1 - por %1, %2 - pshuflw %2, %1, q0032 - por %1, %2 - pshuflw %2, %1, q0001 - por %1, %2 -%elif cpuflag(mmxext) - pshufw %2, %1, q0032 - por %1, %2 - pshufw %2, %1, q0001 - por %1, %2 -%else ; mmx - movq %2, %1 - psrlq %2, 32 - por %1, %2 - movq %2, %1 - psrlq %2, 16 - por %1, %2 -%endif -%endmacro - -%macro AC3_MAX_MSB_ABS_INT16 1 -cglobal ac3_max_msb_abs_int16, 2,2,5, src, len - pxor m2, m2 - pxor m3, m3 -.loop: -%ifidn %1, min_max - mova m0, [srcq] - mova m1, [srcq+mmsize] - pminsw m2, m0 - pminsw m2, m1 - pmaxsw m3, m0 - pmaxsw m3, m1 -%else ; or_abs -%if notcpuflag(ssse3) - mova m0, [srcq] - mova m1, [srcq+mmsize] - ABS2 m0, m1, m3, m4 -%else ; ssse3 - ; using memory args is faster for ssse3 - pabsw m0, [srcq] - pabsw m1, [srcq+mmsize] -%endif - por m2, m0 - por m2, m1 -%endif - add srcq, mmsize*2 - sub lend, mmsize - ja .loop -%ifidn %1, min_max - ABS2 m2, m3, m0, m1 - por m2, m3 -%endif - OR_WORDS_HORIZ m2, m0 - movd eax, m2 - and eax, 0xFFFF - RET -%endmacro - -INIT_MMX mmx -AC3_MAX_MSB_ABS_INT16 or_abs -INIT_MMX mmxext -AC3_MAX_MSB_ABS_INT16 min_max -INIT_XMM sse2 -AC3_MAX_MSB_ABS_INT16 min_max -INIT_XMM ssse3 -AC3_MAX_MSB_ABS_INT16 or_abs - -;----------------------------------------------------------------------------- -; macro used for ff_ac3_lshift_int16() and ff_ac3_rshift_int32() -;----------------------------------------------------------------------------- - -%macro AC3_SHIFT 3 ; l/r, 16/32, shift instruction, instruction set -cglobal ac3_%1shift_int%2, 3, 3, 5, src, len, shift - movd m0, shiftd -.loop: - mova m1, [srcq ] - mova m2, [srcq+mmsize ] - mova m3, [srcq+mmsize*2] - mova m4, [srcq+mmsize*3] - %3 m1, m0 - %3 m2, m0 - %3 m3, m0 - %3 m4, m0 - mova [srcq ], m1 - mova [srcq+mmsize ], m2 - mova [srcq+mmsize*2], m3 - mova [srcq+mmsize*3], m4 - add srcq, mmsize*4 - sub lend, mmsize*32/%2 - ja .loop -.end: - REP_RET -%endmacro - -;----------------------------------------------------------------------------- -; void ff_ac3_lshift_int16(int16_t *src, unsigned int len, unsigned int shift) -;----------------------------------------------------------------------------- - -INIT_MMX mmx -AC3_SHIFT l, 16, psllw -INIT_XMM sse2 -AC3_SHIFT l, 16, psllw - -;----------------------------------------------------------------------------- -; void ff_ac3_rshift_int32(int32_t *src, unsigned int len, unsigned int shift) -;----------------------------------------------------------------------------- - -INIT_MMX mmx -AC3_SHIFT r, 32, psrad -INIT_XMM sse2 -AC3_SHIFT r, 32, psrad - ;----------------------------------------------------------------------------- ; void ff_float_to_fixed24(int32_t *dst, const float *src, unsigned int len) ;----------------------------------------------------------------------------- @@ -423,130 +292,3 @@ AC3_EXTRACT_EXPONENTS INIT_XMM ssse3 AC3_EXTRACT_EXPONENTS %endif - -;----------------------------------------------------------------------------- -; void ff_apply_window_int16(int16_t *output, const int16_t *input, -; const int16_t *window, unsigned int len) -;----------------------------------------------------------------------------- - -%macro REVERSE_WORDS 1-2 -%if cpuflag(ssse3) && notcpuflag(atom) - pshufb %1, %2 -%elif cpuflag(sse2) - pshuflw %1, %1, 0x1B - pshufhw %1, %1, 0x1B - pshufd %1, %1, 0x4E -%elif cpuflag(mmxext) - pshufw %1, %1, 0x1B -%endif -%endmacro - -%macro MUL16FIXED 3 -%if cpuflag(ssse3) ; dst, src, unused -; dst = ((dst * src) + (1<<14)) >> 15 - pmulhrsw %1, %2 -%elif cpuflag(mmxext) ; dst, src, temp -; dst = (dst * src) >> 15 -; pmulhw cuts off the bottom bit, so we have to lshift by 1 and add it back -; in from the pmullw result. - mova %3, %1 - pmulhw %1, %2 - pmullw %3, %2 - psrlw %3, 15 - psllw %1, 1 - por %1, %3 -%endif -%endmacro - -%macro APPLY_WINDOW_INT16 1 ; %1 bitexact version -%if %1 -cglobal apply_window_int16, 4,5,6, output, input, window, offset, offset2 -%else -cglobal apply_window_int16_round, 4,5,6, output, input, window, offset, offset2 -%endif - lea offset2q, [offsetq-mmsize] -%if cpuflag(ssse3) && notcpuflag(atom) - mova m5, [pb_revwords] - ALIGN 16 -%elif %1 - mova m5, [pd_16384] -%endif -.loop: -%if cpuflag(ssse3) - ; This version does the 16x16->16 multiplication in-place without expanding - ; to 32-bit. The ssse3 version is bit-identical. - mova m0, [windowq+offset2q] - mova m1, [ inputq+offset2q] - pmulhrsw m1, m0 - REVERSE_WORDS m0, m5 - pmulhrsw m0, [ inputq+offsetq ] - mova [outputq+offset2q], m1 - mova [outputq+offsetq ], m0 -%elif %1 - ; This version expands 16-bit to 32-bit, multiplies by the window, - ; adds 16384 for rounding, right shifts 15, then repacks back to words to - ; save to the output. The window is reversed for the second half. - mova m3, [windowq+offset2q] - mova m4, [ inputq+offset2q] - pxor m0, m0 - punpcklwd m0, m3 - punpcklwd m1, m4 - pmaddwd m0, m1 - paddd m0, m5 - psrad m0, 15 - pxor m2, m2 - punpckhwd m2, m3 - punpckhwd m1, m4 - pmaddwd m2, m1 - paddd m2, m5 - psrad m2, 15 - packssdw m0, m2 - mova [outputq+offset2q], m0 - REVERSE_WORDS m3 - mova m4, [ inputq+offsetq] - pxor m0, m0 - punpcklwd m0, m3 - punpcklwd m1, m4 - pmaddwd m0, m1 - paddd m0, m5 - psrad m0, 15 - pxor m2, m2 - punpckhwd m2, m3 - punpckhwd m1, m4 - pmaddwd m2, m1 - paddd m2, m5 - psrad m2, 15 - packssdw m0, m2 - mova [outputq+offsetq], m0 -%else - ; This version does the 16x16->16 multiplication in-place without expanding - ; to 32-bit. The mmxext and sse2 versions do not use rounding, and - ; therefore are not bit-identical to the C version. - mova m0, [windowq+offset2q] - mova m1, [ inputq+offset2q] - mova m2, [ inputq+offsetq ] - MUL16FIXED m1, m0, m3 - REVERSE_WORDS m0 - MUL16FIXED m2, m0, m3 - mova [outputq+offset2q], m1 - mova [outputq+offsetq ], m2 -%endif - add offsetd, mmsize - sub offset2d, mmsize - jae .loop - REP_RET -%endmacro - -INIT_MMX mmxext -APPLY_WINDOW_INT16 0 -INIT_XMM sse2 -APPLY_WINDOW_INT16 0 - -INIT_MMX mmxext -APPLY_WINDOW_INT16 1 -INIT_XMM sse2 -APPLY_WINDOW_INT16 1 -INIT_XMM ssse3 -APPLY_WINDOW_INT16 1 -INIT_XMM ssse3, atom -APPLY_WINDOW_INT16 1 diff --git a/libavcodec/x86/ac3dsp_init.c b/libavcodec/x86/ac3dsp_init.c index 2e7e2fb6d..2ae762af4 100644 --- a/libavcodec/x86/ac3dsp_init.c +++ b/libavcodec/x86/ac3dsp_init.c @@ -30,17 +30,6 @@ 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); -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); - -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); - -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); - 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); @@ -50,28 +39,12 @@ int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]); 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); - av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) { int cpu_flags = av_get_cpu_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(cpu_flags)) { if (!bit_exact) { @@ -80,43 +53,20 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) } 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(cpu_flags)) { c->float_to_fixed24 = ff_float_to_fixed24_sse; } 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 (bit_exact) { - c->apply_window_int16 = ff_apply_window_int16_sse2; - } - } - - if (EXTERNAL_SSE2_FAST(cpu_flags)) { - 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_round_sse2; - } } if (EXTERNAL_SSSE3(cpu_flags)) { - c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_ssse3; - if (cpu_flags & AV_CPU_FLAG_ATOM) { - c->apply_window_int16 = ff_apply_window_int16_ssse3_atom; - } else { + if (!(cpu_flags & AV_CPU_FLAG_ATOM)) c->extract_exponents = ff_ac3_extract_exponents_ssse3; - c->apply_window_int16 = ff_apply_window_int16_ssse3; - } } } diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h index cfd3b759c..53d74c541 100644 --- a/libavcodec/x86/cabac.h +++ b/libavcodec/x86/cabac.h @@ -21,6 +21,8 @@ #ifndef AVCODEC_X86_CABAC_H #define AVCODEC_X86_CABAC_H +#include + #include "libavcodec/cabac.h" #include "libavutil/attributes.h" #include "libavutil/macros.h" diff --git a/libavcodec/x86/cavsdsp.c b/libavcodec/x86/cavsdsp.c index becb3a480..f974f93fc 100644 --- a/libavcodec/x86/cavsdsp.c +++ b/libavcodec/x86/cavsdsp.c @@ -25,6 +25,7 @@ #include "libavutil/attributes.h" #include "libavutil/common.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/cavsdsp.h" diff --git a/libavcodec/x86/cfhddsp.asm b/libavcodec/x86/cfhddsp.asm new file mode 100644 index 000000000..87c2df634 --- /dev/null +++ b/libavcodec/x86/cfhddsp.asm @@ -0,0 +1,697 @@ +;****************************************************************************** +;* x86-optimized functions for the CFHD decoder +;* Copyright (c) 2020 Paul B Mahol +;* +;* 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_RODATA + +factor_p1_n1: dw 1, -1, 1, -1, 1, -1, 1, -1, +factor_n1_p1: dw -1, 1, -1, 1, -1, 1, -1, 1, +factor_p11_n4: dw 11, -4, 11, -4, 11, -4, 11, -4, +factor_p5_p4: dw 5, 4, 5, 4, 5, 4, 5, 4, +pd_4: times 4 dd 4 +pw_1: times 8 dw 1 +pw_0: times 8 dw 0 +pw_1023: times 8 dw 1023 +pw_4095: times 8 dw 4095 + +SECTION .text + +%macro CFHD_HORIZ_FILTER 1 +%if %1 == 1023 +cglobal cfhd_horiz_filter_clip10, 5, 6, 8 + 4 * ARCH_X86_64, output, low, high, width, x, temp + shl widthd, 1 +%define ostrideq widthq +%define lwidthq widthq +%define hwidthq widthq +%elif %1 == 4095 +cglobal cfhd_horiz_filter_clip12, 5, 6, 8 + 4 * ARCH_X86_64, output, low, high, width, x, temp + shl widthd, 1 +%define ostrideq widthq +%define lwidthq widthq +%define hwidthq widthq +%else +%if ARCH_X86_64 +cglobal cfhd_horiz_filter, 8, 11, 12, output, ostride, low, lwidth, high, hwidth, width, height, x, y, temp + shl ostrided, 1 + shl lwidthd, 1 + shl hwidthd, 1 + shl widthd, 1 + + mov yd, heightd + neg yq +%else +cglobal cfhd_horiz_filter, 7, 7, 8, output, x, low, y, high, temp, width, height + shl xd, 1 + shl yd, 1 + shl tempd, 1 + shl widthd, 1 + + mov xmp, xq + mov ymp, yq + mov tempmp, tempq + + mov yd, r7m + neg yq + +%define ostrideq xm +%define lwidthq ym +%define hwidthq tempm +%endif +%endif + +%if ARCH_X86_64 + mova m8, [factor_p1_n1] + mova m9, [factor_n1_p1] + mova m10, [pw_1] + mova m11, [pd_4] +%endif + +%if %1 == 0 +.looph: +%endif + movsx xq, word [lowq] + imul xq, 11 + + movsx tempq, word [lowq + 2] + imul tempq, -4 + add tempq, xq + + movsx xq, word [lowq + 4] + add tempq, xq + add tempq, 4 + sar tempq, 3 + + movsx xq, word [highq] + add tempq, xq + sar tempq, 1 + +%if %1 + movd xm0, tempd + CLIPW m0, [pw_0], [pw_%1] + pextrw tempd, xm0, 0 +%endif + mov word [outputq], tempw + + movsx xq, word [lowq] + imul xq, 5 + + movsx tempq, word [lowq + 2] + imul tempq, 4 + add tempq, xq + + movsx xq, word [lowq + 4] + sub tempq, xq + add tempq, 4 + sar tempq, 3 + + movsx xq, word [highq] + sub tempq, xq + sar tempq, 1 + +%if %1 + movd xm0, tempd + CLIPW m0, [pw_0], [pw_%1] + pextrw tempd, xm0, 0 +%endif + mov word [outputq + 2], tempw + + mov xq, 0 + +.loop: + movu m4, [lowq + xq] + movu m1, [lowq + xq + 4] + + mova m5, m4 + punpcklwd m4, m1 + punpckhwd m5, m1 + + mova m6, m4 + mova m7, m5 + +%if ARCH_X86_64 + pmaddwd m4, m8 + pmaddwd m5, m8 + pmaddwd m6, m9 + pmaddwd m7, m9 + + paddd m4, m11 + paddd m5, m11 + paddd m6, m11 + paddd m7, m11 +%else + pmaddwd m4, [factor_p1_n1] + pmaddwd m5, [factor_p1_n1] + pmaddwd m6, [factor_n1_p1] + pmaddwd m7, [factor_n1_p1] + + paddd m4, [pd_4] + paddd m5, [pd_4] + paddd m6, [pd_4] + paddd m7, [pd_4] +%endif + + psrad m4, 3 + psrad m5, 3 + psrad m6, 3 + psrad m7, 3 + + movu m2, [lowq + xq + 2] + movu m3, [highq + xq + 2] + + mova m0, m2 + punpcklwd m2, m3 + punpckhwd m0, m3 + + mova m1, m2 + mova m3, m0 + +%if ARCH_X86_64 + pmaddwd m2, m10 + pmaddwd m0, m10 + pmaddwd m1, m8 + pmaddwd m3, m8 +%else + pmaddwd m2, [pw_1] + pmaddwd m0, [pw_1] + pmaddwd m1, [factor_p1_n1] + pmaddwd m3, [factor_p1_n1] +%endif + + paddd m2, m4 + paddd m0, m5 + paddd m1, m6 + paddd m3, m7 + + psrad m2, 1 + psrad m0, 1 + psrad m1, 1 + psrad m3, 1 + + packssdw m2, m0 + packssdw m1, m3 + + mova m0, m2 + punpcklwd m2, m1 + punpckhwd m0, m1 + +%if %1 + CLIPW m2, [pw_0], [pw_%1] + CLIPW m0, [pw_0], [pw_%1] +%endif + + movu [outputq + xq * 2 + 4], m2 + movu [outputq + xq * 2 + mmsize + 4], m0 + + add xq, mmsize + cmp xq, widthq + jl .loop + + add lowq, widthq + add highq, widthq + add outputq, widthq + add outputq, widthq + + movsx xq, word [lowq - 2] + imul xq, 5 + + movsx tempq, word [lowq - 4] + imul tempq, 4 + add tempq, xq + + movsx xq, word [lowq - 6] + sub tempq, xq + add tempq, 4 + sar tempq, 3 + + movsx xq, word [highq - 2] + add tempq, xq + sar tempq, 1 + +%if %1 + movd xm0, tempd + CLIPW m0, [pw_0], [pw_%1] + pextrw tempd, xm0, 0 +%endif + mov word [outputq - 4], tempw + + movsx xq, word [lowq - 2] + imul xq, 11 + + movsx tempq, word [lowq - 4] + imul tempq, -4 + add tempq, xq + + movsx xq, word [lowq - 6] + add tempq, xq + add tempq, 4 + sar tempq, 3 + + movsx xq, word [highq - 2] + sub tempq, xq + sar tempq, 1 + +%if %1 + movd xm0, tempd + CLIPW m0, [pw_0], [pw_%1] + pextrw tempd, xm0, 0 +%endif + mov word [outputq - 2], tempw + +%if %1 == 0 + sub lowq, widthq + sub highq, widthq + sub outputq, widthq + sub outputq, widthq + + add lowq, lwidthq + add highq, hwidthq + add outputq, ostrideq + add outputq, ostrideq + add yq, 1 + jl .looph +%endif + + RET +%endmacro + +INIT_XMM sse2 +CFHD_HORIZ_FILTER 0 + +INIT_XMM sse2 +CFHD_HORIZ_FILTER 1023 + +INIT_XMM sse2 +CFHD_HORIZ_FILTER 4095 + +INIT_XMM sse2 +%if ARCH_X86_64 +cglobal cfhd_vert_filter, 8, 11, 14, output, ostride, low, lwidth, high, hwidth, width, height, x, y, pos + shl ostrided, 1 + shl lwidthd, 1 + shl hwidthd, 1 + shl widthd, 1 + + dec heightd + + mova m8, [factor_p1_n1] + mova m9, [factor_n1_p1] + mova m10, [pw_1] + mova m11, [pd_4] + mova m12, [factor_p11_n4] + mova m13, [factor_p5_p4] +%else +cglobal cfhd_vert_filter, 7, 7, 8, output, x, low, y, high, pos, width, height + shl xd, 1 + shl yd, 1 + shl posd, 1 + shl widthd, 1 + + mov xmp, xq + mov ymp, yq + mov posmp, posq + + mov xq, r7m + dec xq + mov widthmp, xq + +%define ostrideq xm +%define lwidthq ym +%define hwidthq posm +%define heightq widthm + +%endif + + xor xq, xq +.loopw: + xor yq, yq + + mov posq, xq + movu m0, [lowq + posq] + add posq, lwidthq + movu m1, [lowq + posq] + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + +%if ARCH_X86_64 + pmaddwd m0, m12 + pmaddwd m2, m12 +%else + pmaddwd m0, [factor_p11_n4] + pmaddwd m2, [factor_p11_n4] +%endif + + pxor m4, m4 + add posq, lwidthq + movu m1, [lowq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + paddd m0, m4 + paddd m2, m3 + + paddd m0, [pd_4] + paddd m2, [pd_4] + + psrad m0, 3 + psrad m2, 3 + + mov posq, xq + pxor m4, m4 + movu m1, [highq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + paddd m0, m4 + paddd m2, m3 + + psrad m0, 1 + psrad m2, 1 + + packssdw m0, m2 + + movu [outputq + posq], m0 + + movu m0, [lowq + posq] + add posq, lwidthq + movu m1, [lowq + posq] + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + +%if ARCH_X86_64 + pmaddwd m0, m13 + pmaddwd m2, m13 +%else + pmaddwd m0, [factor_p5_p4] + pmaddwd m2, [factor_p5_p4] +%endif + + pxor m4, m4 + add posq, lwidthq + movu m1, [lowq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + psubd m0, m4 + psubd m2, m3 + + paddd m0, [pd_4] + paddd m2, [pd_4] + + psrad m0, 3 + psrad m2, 3 + + mov posq, xq + pxor m4, m4 + movu m1, [highq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + psubd m0, m4 + psubd m2, m3 + + psrad m0, 1 + psrad m2, 1 + + packssdw m0, m2 + + add posq, ostrideq + movu [outputq + posq], m0 + + add yq, 1 +.looph: + mov posq, lwidthq + imul posq, yq + sub posq, lwidthq + add posq, xq + + movu m4, [lowq + posq] + + add posq, lwidthq + add posq, lwidthq + movu m1, [lowq + posq] + + mova m5, m4 + punpcklwd m4, m1 + punpckhwd m5, m1 + + mova m6, m4 + mova m7, m5 + +%if ARCH_X86_64 + pmaddwd m4, m8 + pmaddwd m5, m8 + pmaddwd m6, m9 + pmaddwd m7, m9 + + paddd m4, m11 + paddd m5, m11 + paddd m6, m11 + paddd m7, m11 +%else + pmaddwd m4, [factor_p1_n1] + pmaddwd m5, [factor_p1_n1] + pmaddwd m6, [factor_n1_p1] + pmaddwd m7, [factor_n1_p1] + + paddd m4, [pd_4] + paddd m5, [pd_4] + paddd m6, [pd_4] + paddd m7, [pd_4] +%endif + + psrad m4, 3 + psrad m5, 3 + psrad m6, 3 + psrad m7, 3 + + sub posq, lwidthq + movu m0, [lowq + posq] + + mov posq, hwidthq + imul posq, yq + add posq, xq + movu m1, [highq + posq] + + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + + mova m1, m0 + mova m3, m2 + +%if ARCH_X86_64 + pmaddwd m0, m10 + pmaddwd m2, m10 + pmaddwd m1, m8 + pmaddwd m3, m8 +%else + pmaddwd m0, [pw_1] + pmaddwd m2, [pw_1] + pmaddwd m1, [factor_p1_n1] + pmaddwd m3, [factor_p1_n1] +%endif + + paddd m0, m4 + paddd m2, m5 + paddd m1, m6 + paddd m3, m7 + + psrad m0, 1 + psrad m2, 1 + psrad m1, 1 + psrad m3, 1 + + packssdw m0, m2 + packssdw m1, m3 + + mov posq, ostrideq + imul posq, 2 + imul posq, yq + add posq, xq + + movu [outputq + posq], m0 + add posq, ostrideq + movu [outputq + posq], m1 + + add yq, 1 + cmp yq, heightq + jl .looph + + mov posq, lwidthq + imul posq, yq + add posq, xq + movu m0, [lowq + posq] + sub posq, lwidthq + movu m1, [lowq + posq] + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + +%if ARCH_X86_64 + pmaddwd m0, m13 + pmaddwd m2, m13 +%else + pmaddwd m0, [factor_p5_p4] + pmaddwd m2, [factor_p5_p4] +%endif + + pxor m4, m4 + sub posq, lwidthq + movu m1, [lowq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + psubd m0, m4 + psubd m2, m3 + +%if ARCH_X86_64 + paddd m0, m11 + paddd m2, m11 +%else + paddd m0, [pd_4] + paddd m2, [pd_4] +%endif + + psrad m0, 3 + psrad m2, 3 + + mov posq, hwidthq + imul posq, yq + add posq, xq + pxor m4, m4 + movu m1, [highq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + paddd m0, m4 + paddd m2, m3 + + psrad m0, 1 + psrad m2, 1 + + packssdw m0, m2 + + mov posq, ostrideq + imul posq, 2 + imul posq, yq + add posq, xq + movu [outputq + posq], m0 + + mov posq, lwidthq + imul posq, yq + add posq, xq + movu m0, [lowq + posq] + sub posq, lwidthq + movu m1, [lowq + posq] + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + +%if ARCH_X86_64 + pmaddwd m0, m12 + pmaddwd m2, m12 +%else + pmaddwd m0, [factor_p11_n4] + pmaddwd m2, [factor_p11_n4] +%endif + + pxor m4, m4 + sub posq, lwidthq + movu m1, [lowq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + paddd m0, m4 + paddd m2, m3 + +%if ARCH_X86_64 + paddd m0, m11 + paddd m2, m11 +%else + paddd m0, [pd_4] + paddd m2, [pd_4] +%endif + + psrad m0, 3 + psrad m2, 3 + + mov posq, hwidthq + imul posq, yq + add posq, xq + pxor m4, m4 + movu m1, [highq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + psubd m0, m4 + psubd m2, m3 + + psrad m0, 1 + psrad m2, 1 + + packssdw m0, m2 + + mov posq, ostrideq + imul posq, 2 + imul posq, yq + add posq, ostrideq + add posq, xq + movu [outputq + posq], m0 + + add xq, mmsize + cmp xq, widthq + jl .loopw + RET diff --git a/libavcodec/x86/cfhddsp_init.c b/libavcodec/x86/cfhddsp_init.c new file mode 100644 index 000000000..ab7ff8308 --- /dev/null +++ b/libavcodec/x86/cfhddsp_init.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020 Paul B Mahol + * + * 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/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/cfhddsp.h" + +void ff_cfhd_horiz_filter_sse2(int16_t *output, ptrdiff_t out_stride, + const int16_t *low, ptrdiff_t low_stride, + const int16_t *high, ptrdiff_t high_stride, + int width, int height); +void ff_cfhd_vert_filter_sse2(int16_t *output, ptrdiff_t out_stride, + const int16_t *low, ptrdiff_t low_stride, + const int16_t *high, ptrdiff_t high_stride, + int width, int height); +void ff_cfhd_horiz_filter_clip10_sse2(int16_t *output, const int16_t *low, const int16_t *high, int width, int bpc); +void ff_cfhd_horiz_filter_clip12_sse2(int16_t *output, const int16_t *low, const int16_t *high, int width, int bpc); + +av_cold void ff_cfhddsp_init_x86(CFHDDSPContext *c, int depth, int bayer) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + c->horiz_filter = ff_cfhd_horiz_filter_sse2; + c->vert_filter = ff_cfhd_vert_filter_sse2; + if (depth == 10 && !bayer) + c->horiz_filter_clip = ff_cfhd_horiz_filter_clip10_sse2; + if (depth == 12 && !bayer) + c->horiz_filter_clip = ff_cfhd_horiz_filter_clip12_sse2; + } +} diff --git a/libavcodec/x86/cfhdencdsp.asm b/libavcodec/x86/cfhdencdsp.asm new file mode 100644 index 000000000..4aaeb5697 --- /dev/null +++ b/libavcodec/x86/cfhdencdsp.asm @@ -0,0 +1,432 @@ +;****************************************************************************** +;* x86-optimized functions for the CFHD encoder +;* Copyright (c) 2021 Paul B Mahol +;* +;* 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_RODATA + +pw_p1_n1: dw 1, -1, 1, -1, 1, -1, 1, -1 +pw_n1_p1: dw -1, 1, -1, 1, -1, 1, -1, 1 +pw_p5_n11: dw 5, -11, 5, -11, 5, -11, 5, -11 +pw_n5_p11: dw -5, 11, -5, 11, -5, 11, -5, 11 +pw_p11_n5: dw 11, -5, 11, -5, 11, -5, 11, -5 +pw_n11_p5: dw -11, 5, -11, 5, -11, 5, -11, 5 +pd_4: times 4 dd 4 +pw_n4: times 8 dw -4 +cextern pw_m1 +cextern pw_1 +cextern pw_4 + +SECTION .text + +%if ARCH_X86_64 +INIT_XMM sse2 +cglobal cfhdenc_horiz_filter, 8, 10, 11, input, low, high, istride, lwidth, hwidth, width, y, x, temp + shl istrideq, 1 + shl lwidthq, 1 + shl hwidthq, 1 + mova m7, [pd_4] + mova m8, [pw_1] + mova m9, [pw_m1] + mova m10,[pw_p1_n1] + movsxdifnidn yq, yd + movsxdifnidn widthq, widthd + neg yq +.looph: + movsx xq, word [inputq] + + movsx tempq, word [inputq + 2] + add tempq, xq + + movd xm0, tempd + packssdw m0, m0 + movd tempd, m0 + mov word [lowq], tempw + + movsx xq, word [inputq] + imul xq, 5 + movsx tempq, word [inputq + 2] + imul tempq, -11 + add tempq, xq + + movsx xq, word [inputq + 4] + imul xq, 4 + add tempq, xq + + movsx xq, word [inputq + 6] + imul xq, 4 + add tempq, xq + + movsx xq, word [inputq + 8] + imul xq, -1 + add tempq, xq + + movsx xq, word [inputq + 10] + imul xq, -1 + add tempq, xq + + add tempq, 4 + sar tempq, 3 + + movd xm0, tempd + packssdw m0, m0 + movd tempd, m0 + mov word [highq], tempw + + mov xq, 2 + +.loopw: + movu m0, [inputq + xq * 2] + movu m1, [inputq + xq * 2 + mmsize] + + pmaddwd m0, m8 + pmaddwd m1, m8 + + packssdw m0, m1 + movu [lowq+xq], m0 + + movu m2, [inputq + xq * 2 - 4] + movu m3, [inputq + xq * 2 - 4 + mmsize] + + pmaddwd m2, m9 + pmaddwd m3, m9 + + movu m0, [inputq + xq * 2 + 4] + movu m1, [inputq + xq * 2 + 4 + mmsize] + + pmaddwd m0, m8 + pmaddwd m1, m8 + + paddd m0, m2 + paddd m1, m3 + + paddd m0, m7 + paddd m1, m7 + + psrad m0, 3 + psrad m1, 3 + + movu m5, [inputq + xq * 2 + 0] + movu m6, [inputq + xq * 2 + mmsize] + + pmaddwd m5, m10 + pmaddwd m6, m10 + + paddd m0, m5 + paddd m1, m6 + + packssdw m0, m1 + movu [highq+xq], m0 + + add xq, mmsize + cmp xq, widthq + jl .loopw + + add lowq, widthq + add highq, widthq + lea inputq, [inputq + widthq * 2] + + movsx xq, word [inputq - 4] + movsx tempq, word [inputq - 2] + add tempq, xq + + movd xm0, tempd + packssdw m0, m0 + movd tempd, m0 + mov word [lowq-2], tempw + + movsx tempq, word [inputq - 4] + imul tempq, 11 + movsx xq, word [inputq - 2] + imul xq, -5 + add tempq, xq + + movsx xq, word [inputq - 6] + imul xq, -4 + add tempq, xq + + movsx xq, word [inputq - 8] + imul xq, -4 + add tempq, xq + + movsx xq, word [inputq - 10] + add tempq, xq + + movsx xq, word [inputq - 12] + add tempq, xq + + add tempq, 4 + sar tempq, 3 + + movd xm0, tempd + packssdw m0, m0 + movd tempd, m0 + mov word [highq-2], tempw + + sub inputq, widthq + sub inputq, widthq + sub highq, widthq + sub lowq, widthq + + add lowq, lwidthq + add highq, hwidthq + add inputq, istrideq + add yq, 1 + jl .looph + + RET +%endif + +%if ARCH_X86_64 +INIT_XMM sse2 +cglobal cfhdenc_vert_filter, 8, 11, 14, input, low, high, istride, lwidth, hwidth, width, height, x, y, pos + shl istrideq, 1 + + shl widthd, 1 + sub heightd, 2 + + xor xq, xq + + mova m7, [pd_4] + mova m8, [pw_1] + mova m9, [pw_m1] + mova m10,[pw_p1_n1] + mova m11,[pw_n1_p1] + mova m12,[pw_4] + mova m13,[pw_n4] +.loopw: + mov yq, 2 + + mov posq, xq + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + + paddsw m0, m1 + + movu [lowq + xq], m0 + + mov posq, xq + + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + add posq, istrideq + movu m2, [inputq + posq] + add posq, istrideq + movu m3, [inputq + posq] + add posq, istrideq + movu m4, [inputq + posq] + add posq, istrideq + movu m5, [inputq + posq] + + mova m6, m0 + punpcklwd m0, m1 + punpckhwd m1, m6 + + mova m6, m2 + punpcklwd m2, m3 + punpckhwd m3, m6 + + mova m6, m4 + punpcklwd m4, m5 + punpckhwd m5, m6 + + pmaddwd m0, [pw_p5_n11] + pmaddwd m1, [pw_n11_p5] + pmaddwd m2, m12 + pmaddwd m3, m12 + pmaddwd m4, m9 + pmaddwd m5, m9 + + paddd m0, m2 + paddd m1, m3 + paddd m0, m4 + paddd m1, m5 + + paddd m0, m7 + paddd m1, m7 + + psrad m0, 3 + psrad m1, 3 + packssdw m0, m1 + + movu [highq + xq], m0 + +.looph: + + mov posq, istrideq + imul posq, yq + add posq, xq + + movu m0, [inputq + posq] + + add posq, istrideq + movu m1, [inputq + posq] + + paddsw m0, m1 + + mov posq, lwidthq + imul posq, yq + add posq, xq + + movu [lowq + posq], m0 + + add yq, -2 + + mov posq, istrideq + imul posq, yq + add posq, xq + + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + add posq, istrideq + movu m2, [inputq + posq] + add posq, istrideq + movu m3, [inputq + posq] + add posq, istrideq + movu m4, [inputq + posq] + add posq, istrideq + movu m5, [inputq + posq] + + add yq, 2 + + mova m6, m0 + punpcklwd m0, m1 + punpckhwd m1, m6 + + mova m6, m2 + punpcklwd m2, m3 + punpckhwd m3, m6 + + mova m6, m4 + punpcklwd m4, m5 + punpckhwd m5, m6 + + pmaddwd m0, m9 + pmaddwd m1, m9 + pmaddwd m2, m10 + pmaddwd m3, m11 + pmaddwd m4, m8 + pmaddwd m5, m8 + + paddd m0, m4 + paddd m1, m5 + + paddd m0, m7 + paddd m1, m7 + + psrad m0, 3 + psrad m1, 3 + paddd m0, m2 + paddd m1, m3 + packssdw m0, m1 + + mov posq, hwidthq + imul posq, yq + add posq, xq + + movu [highq + posq], m0 + + add yq, 2 + cmp yq, heightq + jl .looph + + mov posq, istrideq + imul posq, yq + add posq, xq + + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + + paddsw m0, m1 + + mov posq, lwidthq + imul posq, yq + add posq, xq + + movu [lowq + posq], m0 + + sub yq, 4 + + mov posq, istrideq + imul posq, yq + add posq, xq + + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + add posq, istrideq + movu m2, [inputq + posq] + add posq, istrideq + movu m3, [inputq + posq] + add posq, istrideq + movu m4, [inputq + posq] + add posq, istrideq + movu m5, [inputq + posq] + + add yq, 4 + + mova m6, m0 + punpcklwd m0, m1 + punpckhwd m1, m6 + + mova m6, m2 + punpcklwd m2, m3 + punpckhwd m3, m6 + + mova m6, m4 + punpcklwd m4, m5 + punpckhwd m5, m6 + + pmaddwd m0, m8 + pmaddwd m1, m8 + pmaddwd m2, m13 + pmaddwd m3, m13 + pmaddwd m4, [pw_p11_n5] + pmaddwd m5, [pw_n5_p11] + + paddd m4, m2 + paddd m5, m3 + + paddd m4, m0 + paddd m5, m1 + + paddd m4, m7 + paddd m5, m7 + + psrad m4, 3 + psrad m5, 3 + packssdw m4, m5 + + mov posq, hwidthq + imul posq, yq + add posq, xq + + movu [highq + posq], m4 + + add xq, mmsize + cmp xq, widthq + jl .loopw + RET +%endif diff --git a/libavcodec/x86/cfhdencdsp_init.c b/libavcodec/x86/cfhdencdsp_init.c new file mode 100644 index 000000000..28f1dd504 --- /dev/null +++ b/libavcodec/x86/cfhdencdsp_init.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/cfhdencdsp.h" + +void ff_cfhdenc_horiz_filter_sse2(int16_t *input, int16_t *low, int16_t *high, + ptrdiff_t in_stride, ptrdiff_t low_stride, + ptrdiff_t high_stride, + int width, int height); +void ff_cfhdenc_vert_filter_sse2(int16_t *input, int16_t *low, int16_t *high, + ptrdiff_t in_stride, ptrdiff_t low_stride, + ptrdiff_t high_stride, + int width, int height); + +av_cold void ff_cfhdencdsp_init_x86(CFHDEncDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_64 + if (EXTERNAL_SSE2(cpu_flags)) { + c->horiz_filter = ff_cfhdenc_horiz_filter_sse2; + c->vert_filter = ff_cfhdenc_vert_filter_sse2; + } +#endif +} diff --git a/libavcodec/x86/constants.c b/libavcodec/x86/constants.c index 4bfb78cc3..bc7f2b17b 100644 --- a/libavcodec/x86/constants.c +++ b/libavcodec/x86/constants.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" // for xmm_reg #include "constants.h" @@ -34,7 +34,6 @@ DECLARE_ALIGNED(16, const xmm_reg, ff_pw_8) = { 0x0008000800080008ULL, 0x000 DECLARE_ASM_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_ASM_ALIGNED(16, const xmm_reg, ff_pw_18) = { 0x0012001200120012ULL, 0x0012001200120012ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_20) = { 0x0014001400140014ULL, 0x0014001400140014ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_32) = { 0x0020002000200020ULL, 0x0020002000200020ULL }; diff --git a/libavcodec/x86/diracdsp_init.c b/libavcodec/x86/diracdsp_init.c index 8cb84eb74..8baacf312 100644 --- a/libavcodec/x86/diracdsp_init.c +++ b/libavcodec/x86/diracdsp_init.c @@ -22,15 +22,6 @@ #include "libavcodec/diracdsp.h" #include "fpel.h" -DECL_DIRAC_PIXOP(put, mmx); -DECL_DIRAC_PIXOP(avg, mmx); -DECL_DIRAC_PIXOP(avg, mmxext); - -void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); -void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); -void ff_put_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); -void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); - void ff_add_rect_clamped_mmx(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int); void ff_add_rect_clamped_sse2(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int); @@ -72,89 +63,47 @@ void ff_dequant_subband_32_sse4(uint8_t *src, uint8_t *dst, ptrdiff_t stride, co } #define PIXFUNC(PFX, IDX, EXT) \ - /*MMXDISABLEDc->PFX ## _dirac_pixels_tab[0][IDX] = ff_ ## PFX ## _dirac_pixels8_ ## EXT;*/ \ - c->PFX ## _dirac_pixels_tab[1][IDX] = ff_ ## PFX ## _dirac_pixels16_ ## EXT; \ - c->PFX ## _dirac_pixels_tab[2][IDX] = ff_ ## PFX ## _dirac_pixels32_ ## EXT + /*MMXDISABLEDc->PFX ## _dirac_pixels_tab[0][IDX] = PFX ## _dirac_pixels8_ ## EXT;*/ \ + c->PFX ## _dirac_pixels_tab[1][IDX] = PFX ## _dirac_pixels16_ ## EXT; \ + c->PFX ## _dirac_pixels_tab[2][IDX] = PFX ## _dirac_pixels32_ ## EXT -#define DIRAC_PIXOP(OPNAME2, OPNAME, EXT)\ -void ff_ ## OPNAME2 ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +#define DIRAC_PIXOP(OPNAME, EXT)\ +static void OPNAME ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], \ + int stride, int h) \ {\ if (h&3)\ - ff_ ## OPNAME2 ## _dirac_pixels8_c(dst, src, stride, h);\ + ff_ ## OPNAME ## _dirac_pixels16_c(dst, src, stride, h);\ else\ - OPNAME ## _pixels8_ ## EXT(dst, src[0], stride, h);\ + ff_ ## OPNAME ## _pixels16_ ## EXT(dst, src[0], stride, h);\ }\ -void ff_ ## OPNAME2 ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ -{\ - if (h&3)\ - ff_ ## OPNAME2 ## _dirac_pixels16_c(dst, src, stride, h);\ - else\ - OPNAME ## _pixels16_ ## EXT(dst, src[0], stride, h);\ -}\ -void ff_ ## OPNAME2 ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +static void OPNAME ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], \ + int stride, int h) \ {\ if (h&3) {\ - ff_ ## OPNAME2 ## _dirac_pixels32_c(dst, src, stride, h);\ + ff_ ## OPNAME ## _dirac_pixels32_c(dst, src, stride, h);\ } else {\ - OPNAME ## _pixels16_ ## EXT(dst , src[0] , stride, h);\ - OPNAME ## _pixels16_ ## EXT(dst+16, src[0]+16, stride, h);\ + ff_ ## OPNAME ## _pixels16_ ## EXT(dst , src[0] , stride, h);\ + ff_ ## OPNAME ## _pixels16_ ## EXT(dst+16, src[0]+16, stride, h);\ }\ } -DIRAC_PIXOP(put, ff_put, mmx) -DIRAC_PIXOP(avg, ff_avg, mmx) -DIRAC_PIXOP(avg, ff_avg, mmxext) +DIRAC_PIXOP(put, mmx) +DIRAC_PIXOP(avg, mmx) +DIRAC_PIXOP(avg, mmxext) -void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) -{ - if (h&3) - ff_put_dirac_pixels16_c(dst, src, stride, h); - else - ff_put_pixels16_sse2(dst, src[0], stride, h); -} -void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) -{ - if (h&3) - ff_avg_dirac_pixels16_c(dst, src, stride, h); - else - ff_avg_pixels16_sse2(dst, src[0], stride, h); -} -void ff_put_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) -{ - if (h&3) { - ff_put_dirac_pixels32_c(dst, src, stride, h); - } else { - ff_put_pixels16_sse2(dst , src[0] , stride, h); - ff_put_pixels16_sse2(dst+16, src[0]+16, stride, h); - } -} -void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) -{ - if (h&3) { - ff_avg_dirac_pixels32_c(dst, src, stride, h); - } else { - ff_avg_pixels16_sse2(dst , src[0] , stride, h); - ff_avg_pixels16_sse2(dst+16, src[0]+16, stride, h); - } -} - -#else // HAVE_X86ASM - -#define HPEL_FILTER(MMSIZE, EXT) \ - void dirac_hpel_filter_ ## EXT(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, \ - const uint8_t *src, int stride, int width, int height); - -#define PIXFUNC(PFX, IDX, EXT) do {} while (0) - -#endif // HAVE_X86ASM +DIRAC_PIXOP(put, sse2) +DIRAC_PIXOP(avg, sse2) #if !ARCH_X86_64 HPEL_FILTER(8, mmx) #endif HPEL_FILTER(16, sse2) +#endif // HAVE_X86ASM + void ff_diracdsp_init_x86(DiracDSPContext* c) { +#if HAVE_X86ASM int mm_flags = av_get_cpu_flags(); if (EXTERNAL_MMX(mm_flags)) { @@ -182,14 +131,15 @@ void ff_diracdsp_init_x86(DiracDSPContext* c) c->add_dirac_obmc[1] = ff_add_dirac_obmc16_sse2; c->add_dirac_obmc[2] = ff_add_dirac_obmc32_sse2; - c->put_dirac_pixels_tab[1][0] = ff_put_dirac_pixels16_sse2; - c->avg_dirac_pixels_tab[1][0] = ff_avg_dirac_pixels16_sse2; - c->put_dirac_pixels_tab[2][0] = ff_put_dirac_pixels32_sse2; - c->avg_dirac_pixels_tab[2][0] = ff_avg_dirac_pixels32_sse2; + c->put_dirac_pixels_tab[1][0] = put_dirac_pixels16_sse2; + c->avg_dirac_pixels_tab[1][0] = avg_dirac_pixels16_sse2; + c->put_dirac_pixels_tab[2][0] = put_dirac_pixels32_sse2; + c->avg_dirac_pixels_tab[2][0] = avg_dirac_pixels32_sse2; } if (EXTERNAL_SSE4(mm_flags)) { c->dequant_subband[1] = ff_dequant_subband_32_sse4; c->put_signed_rect_clamped[1] = ff_put_signed_rect_clamped_10_sse4; } +#endif } diff --git a/libavcodec/x86/fdct.c b/libavcodec/x86/fdct.c index 112566ded..d77f60c86 100644 --- a/libavcodec/x86/fdct.c +++ b/libavcodec/x86/fdct.c @@ -31,6 +31,7 @@ */ #include "libavutil/common.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" #include "fdct.h" diff --git a/libavcodec/x86/h264_intrapred.asm b/libavcodec/x86/h264_intrapred.asm index f3aa3172f..b36c198fb 100644 --- a/libavcodec/x86/h264_intrapred.asm +++ b/libavcodec/x86/h264_intrapred.asm @@ -42,11 +42,7 @@ SECTION .text cextern pb_1 cextern pb_3 cextern pw_4 -cextern pw_5 cextern pw_8 -cextern pw_16 -cextern pw_17 -cextern pw_32 ;----------------------------------------------------------------------------- ; void ff_pred16x16_vertical_8(uint8_t *src, ptrdiff_t stride) diff --git a/libavcodec/x86/h264_qpel.c b/libavcodec/x86/h264_qpel.c index 0d3dbbadb..a2d8a6497 100644 --- a/libavcodec/x86/h264_qpel.c +++ b/libavcodec/x86/h264_qpel.c @@ -21,6 +21,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/h264dec.h" diff --git a/libavcodec/x86/hevcdsp_init.c b/libavcodec/x86/hevcdsp_init.c index 17cd2332a..8a3fa2744 100644 --- a/libavcodec/x86/hevcdsp_init.c +++ b/libavcodec/x86/hevcdsp_init.c @@ -22,6 +22,7 @@ #include "config.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/get_bits.h" /* required for hevcdsp.h GetBitContext */ diff --git a/libavcodec/x86/me_cmp_init.c b/libavcodec/x86/me_cmp_init.c index 6aec93e55..701eb1ab2 100644 --- a/libavcodec/x86/me_cmp_init.c +++ b/libavcodec/x86/me_cmp_init.c @@ -24,6 +24,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/me_cmp.h" diff --git a/libavcodec/x86/mpegaudiodsp.c b/libavcodec/x86/mpegaudiodsp.c index f46a5c4f3..50692f29c 100644 --- a/libavcodec/x86/mpegaudiodsp.c +++ b/libavcodec/x86/mpegaudiodsp.c @@ -22,6 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/mpegaudiodsp.h" @@ -239,10 +240,8 @@ DECL_IMDCT_BLOCKS(avx,avx) #endif #endif /* HAVE_X86ASM */ -av_cold void ff_mpadsp_init_x86(MPADSPContext *s) +av_cold void ff_mpadsp_init_x86_tabs(void) { - av_unused int cpu_flags = av_get_cpu_flags(); - int i, j; for (j = 0; j < 4; j++) { for (i = 0; i < 40; i ++) { @@ -256,6 +255,11 @@ av_cold void ff_mpadsp_init_x86(MPADSPContext *s) mdct_win_sse[1][j][4*i + 3] = ff_mdct_win_float[j + 4][i]; } } +} + +av_cold void ff_mpadsp_init_x86(MPADSPContext *s) +{ + av_unused int cpu_flags = av_get_cpu_flags(); #if HAVE_6REGS && HAVE_SSE_INLINE if (INLINE_SSE(cpu_flags)) { diff --git a/libavcodec/x86/mpegvideoenc.c b/libavcodec/x86/mpegvideoenc.c index c884cf121..4bad6a87e 100644 --- a/libavcodec/x86/mpegvideoenc.c +++ b/libavcodec/x86/mpegvideoenc.c @@ -21,6 +21,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/avcodec.h" diff --git a/libavcodec/x86/mpegvideoenc_template.c b/libavcodec/x86/mpegvideoenc_template.c index 1201be514..b32b1b035 100644 --- a/libavcodec/x86/mpegvideoenc_template.c +++ b/libavcodec/x86/mpegvideoenc_template.c @@ -23,6 +23,7 @@ #include #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" #include "libavcodec/mpegutils.h" #include "libavcodec/mpegvideo.h" diff --git a/libavcodec/x86/rv40dsp_init.c b/libavcodec/x86/rv40dsp_init.c index b57a3fc31..79a617ffb 100644 --- a/libavcodec/x86/rv40dsp_init.c +++ b/libavcodec/x86/rv40dsp_init.c @@ -29,6 +29,7 @@ #include "libavcodec/rv34dsp.h" #include "libavutil/attributes.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/cpu.h" #include "hpeldsp.h" diff --git a/libavcodec/x86/vc1dsp_mmx.c b/libavcodec/x86/vc1dsp_mmx.c index 45c8a68f2..6541dda42 100644 --- a/libavcodec/x86/vc1dsp_mmx.c +++ b/libavcodec/x86/vc1dsp_mmx.c @@ -26,6 +26,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/vc1dsp.h" diff --git a/libavcodec/x86/vp8dsp_init.c b/libavcodec/x86/vp8dsp_init.c index 397b2518c..dffa7a241 100644 --- a/libavcodec/x86/vp8dsp_init.c +++ b/libavcodec/x86/vp8dsp_init.c @@ -23,6 +23,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/x86/cpu.h" #include "libavcodec/vp8dsp.h" diff --git a/libavcodec/x86/vp9dsp_init.h b/libavcodec/x86/vp9dsp_init.h index e410cab3a..ebe7ca8ad 100644 --- a/libavcodec/x86/vp9dsp_init.h +++ b/libavcodec/x86/vp9dsp_init.h @@ -23,6 +23,8 @@ #ifndef AVCODEC_X86_VP9DSP_INIT_H #define AVCODEC_X86_VP9DSP_INIT_H +#include "libavutil/mem_internal.h" + #include "libavcodec/vp9dsp.h" // hack to force-expand BPC diff --git a/libavcodec/x86/w64xmmtest.c b/libavcodec/x86/w64xmmtest.c index 8f2b8a629..d0782b940 100644 --- a/libavcodec/x86/w64xmmtest.c +++ b/libavcodec/x86/w64xmmtest.c @@ -29,6 +29,7 @@ wrap(avcodec_open2(AVCodecContext *avctx, testxmmclobbers(avcodec_open2, avctx, codec, options); } +#if FF_API_OLD_ENCDEC wrap(avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, @@ -47,15 +48,6 @@ wrap(avcodec_decode_video2(AVCodecContext *avctx, got_picture_ptr, avpkt); } -wrap(avcodec_decode_subtitle2(AVCodecContext *avctx, - AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt)) -{ - testxmmclobbers(avcodec_decode_subtitle2, avctx, sub, - got_sub_ptr, avpkt); -} - wrap(avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, @@ -65,6 +57,22 @@ wrap(avcodec_encode_audio2(AVCodecContext *avctx, got_packet_ptr); } +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); +} +#endif + +wrap(avcodec_decode_subtitle2(AVCodecContext *avctx, + AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt)) +{ + testxmmclobbers(avcodec_decode_subtitle2, avctx, sub, + got_sub_ptr, avpkt); +} + wrap(avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub)) @@ -72,12 +80,6 @@ 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); -} - wrap(avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)) { testxmmclobbers(avcodec_send_packet, avctx, avpkt); diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 1ccf16484..6bf754f15 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -100,16 +100,12 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); s->buffer2_size = avctx->width * avctx->height; s->buffer2 = av_malloc(s->buffer2_size + 130); - if (!s->buffer2) { - av_freep(&s->buffer1); + if (!s->buffer2) return AVERROR(ENOMEM); - } s->last_frame = av_frame_alloc(); - if (!s->last_frame) { - xan_decode_end(avctx); + if (!s->last_frame) return AVERROR(ENOMEM); - } return 0; } @@ -649,4 +645,5 @@ AVCodec ff_xan_wc3_decoder = { .close = xan_decode_end, .decode = xan_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/xbm_parser.c b/libavcodec/xbm_parser.c new file mode 100644 index 000000000..6b0eea69a --- /dev/null +++ b/libavcodec/xbm_parser.c @@ -0,0 +1,106 @@ +/* + * XBM parser + * Copyright (c) 2021 Paul B Mahol + * + * 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 + * XBM parser + */ + +#include "libavutil/common.h" + +#include "parser.h" + +typedef struct XBMParseContext { + ParseContext pc; + uint16_t state16; + int count; +} XBMParseContext; + +#define KEY (((uint64_t)'\n' << 56) | ((uint64_t)'#' << 48) | \ + ((uint64_t)'d' << 40) | ((uint64_t)'e' << 32) | \ + ((uint64_t)'f' << 24) | ('i' << 16) | ('n' << 8) | \ + ('e' << 0)) + +#define END ((';' << 8) | ('\n' << 0)) + +static int xbm_init(AVCodecParserContext *s) +{ + XBMParseContext *bpc = s->priv_data; + + bpc->count = 1; + + return 0; +} + +static int xbm_parse(AVCodecParserContext *s, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + XBMParseContext *bpc = s->priv_data; + uint64_t state = bpc->pc.state64; + uint16_t state16 = bpc->state16; + int next = END_NOT_FOUND, i = 0; + + s->pict_type = AV_PICTURE_TYPE_I; + s->key_frame = 1; + s->duration = 1; + + *poutbuf_size = 0; + *poutbuf = NULL; + + for (; i < buf_size; i++) { + state = (state << 8) | buf[i]; + state16 = (state16 << 8) | buf[i]; + + if (state == KEY) + bpc->count++; + + if ((state == KEY && bpc->count == 1)) { + next = i - 6; + break; + } else if (state16 == END) { + next = i + 1; + bpc->count = 0; + break; + } + } + + bpc->pc.state64 = state; + bpc->state16 = state16; + if (ff_combine_frame(&bpc->pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + + return next; +} + +AVCodecParser ff_xbm_parser = { + .codec_ids = { AV_CODEC_ID_XBM }, + .priv_data_size = sizeof(XBMParseContext), + .parser_init = xbm_init, + .parser_parse = xbm_parse, + .parser_close = ff_parse_close, +}; diff --git a/libavcodec/xbmdec.c b/libavcodec/xbmdec.c index d19bdaee2..c1fc6cb65 100644 --- a/libavcodec/xbmdec.c +++ b/libavcodec/xbmdec.c @@ -26,26 +26,31 @@ #include "internal.h" #include "mathops.h" -static int convert(uint8_t x) +static int get_nibble(uint8_t x) { - if (x >= 'a') - x -= 87; - else if (x >= 'A') - x -= 55; - else - x -= '0'; - return x; + int ret = 255; + + if (x <= '9') { + if (x >= '0') + ret = x - '0'; + } else if (x >= 'a') { + if (x <= 'f') + ret = x - ('a' - 10); + } else if (x >= 'A' && x <= 'F') + ret = x - ('A' - 10); + return ret; } -static int parse_str_int(const uint8_t *p, int len, const uint8_t *key) +static int parse_str_int(const uint8_t *p, const uint8_t *end, const uint8_t *key) { - const uint8_t *end = p + len; + int keylen = strlen(key); + const uint8_t *e = end - keylen; - for(; p= end) return INT_MIN; @@ -72,8 +77,8 @@ static int xbm_decode_frame(AVCodecContext *avctx, void *data, avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; end = avpkt->data + avpkt->size; - width = parse_str_int(avpkt->data, avpkt->size, "_width"); - height = parse_str_int(avpkt->data, avpkt->size, "_height"); + width = parse_str_int(avpkt->data, end, "_width"); + height = parse_str_int(avpkt->data, end, "_height"); if ((ret = ff_set_dimensions(avctx, width, height)) < 0) return ret; @@ -93,22 +98,26 @@ static int xbm_decode_frame(AVCodecContext *avctx, void *data, for (i = 0; i < avctx->height; i++) { dst = p->data[0] + i * p->linesize[0]; for (j = 0; j < linesize; j++) { - uint8_t val; + uint8_t nib, val; while (ptr < end && *ptr != 'x' && *ptr != '$') ptr++; ptr ++; - if (ptr < end && av_isxdigit(*ptr)) { - val = convert(*ptr++); - if (av_isxdigit(*ptr)) - val = (val << 4) + convert(*ptr++); + if (ptr < end && (val = get_nibble(*ptr)) <= 15) { + ptr++; + if ((nib = get_nibble(*ptr)) <= 15) { + val = (val << 4) + nib; + ptr++; + } *dst++ = ff_reverse[val]; - if (av_isxdigit(*ptr) && j+1 < linesize) { + if ((val = get_nibble(*ptr)) <= 15 && j+1 < linesize) { j++; - val = convert(*ptr++); - if (av_isxdigit(*ptr)) - val = (val << 4) + convert(*ptr++); + ptr++; + if ((nib = get_nibble(*ptr)) <= 15) { + val = (val << 4) + nib; + ptr++; + } *dst++ = ff_reverse[val]; } } else { diff --git a/libavcodec/xbmenc.c b/libavcodec/xbmenc.c index b25615f2a..1cf13f6f0 100644 --- a/libavcodec/xbmenc.c +++ b/libavcodec/xbmenc.c @@ -24,14 +24,25 @@ #include "internal.h" #include "mathops.h" +#define ANSI_MIN_READLINE 509 + static int xbm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *p, int *got_packet) { - int i, j, ret, size, linesize; + int i, j, l, commas, ret, size, linesize, lineout, rowsout; uint8_t *ptr, *buf; - linesize = (avctx->width + 7) / 8; - size = avctx->height * (linesize * 7 + 2) + 110; + linesize = lineout = (avctx->width + 7) / 8; + commas = avctx->height * linesize; + + /* ANSI worst case minimum readline is 509 chars. */ + rowsout = avctx->height; + if (lineout > (ANSI_MIN_READLINE / 6)) { + lineout = ANSI_MIN_READLINE / 6; + rowsout = (commas + lineout - 1) / lineout; + } + + size = rowsout * (lineout * 6 + 1) + 106; if ((ret = ff_alloc_packet2(avctx, pkt, size, 0)) < 0) return ret; @@ -40,12 +51,21 @@ static int xbm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, buf += snprintf(buf, 32, "#define image_width %u\n", avctx->width); buf += snprintf(buf, 33, "#define image_height %u\n", avctx->height); - buf += snprintf(buf, 40, "static unsigned char image_bits[] = {\n"); - for (i = 0; i < avctx->height; i++) { - for (j = 0; j < linesize; j++) - buf += snprintf(buf, 7, " 0x%02X,", ff_reverse[*ptr++]); + buf += snprintf(buf, 39, "static unsigned char image_bits[] = {\n"); + for (i = 0, l = lineout; i < avctx->height; i++) { + for (j = 0; j < linesize; j++) { + buf += snprintf(buf, 6, " 0x%02X", ff_reverse[*ptr++]); + if (--commas <= 0) { + buf += snprintf(buf, 2, "\n"); + break; + } + buf += snprintf(buf, 2, ","); + if (--l <= 0) { + buf += snprintf(buf, 2, "\n"); + l = lineout; + } + } ptr += p->linesize[0] - linesize; - buf += snprintf(buf, 2, "\n"); } buf += snprintf(buf, 5, " };\n"); diff --git a/libavcodec/xfacedec.c b/libavcodec/xfacedec.c index ab4c0823f..763be6761 100644 --- a/libavcodec/xfacedec.c +++ b/libavcodec/xfacedec.c @@ -185,4 +185,5 @@ AVCodec ff_xface_decoder = { .init = xface_decode_init, .decode = xface_decode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/xl.c b/libavcodec/xl.c index 37ab46e4f..72fb3bf25 100644 --- a/libavcodec/xl.c +++ b/libavcodec/xl.c @@ -135,4 +135,5 @@ AVCodec ff_xl_decoder = { .init = decode_init, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c index c1c6e11dc..87ac91057 100644 --- a/libavcodec/xsubdec.c +++ b/libavcodec/xsubdec.c @@ -24,6 +24,7 @@ #include "avcodec.h" #include "get_bits.h" #include "bytestream.h" +#include "internal.h" static av_cold int decode_init(AVCodecContext *avctx) { avctx->pix_fmt = AV_PIX_FMT_PAL8; @@ -180,4 +181,5 @@ AVCodec ff_xsub_decoder = { .id = AV_CODEC_ID_XSUB, .init = decode_init, .decode = decode_frame, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c index 4d58e0f3b..ad7144db2 100644 --- a/libavcodec/xsubenc.c +++ b/libavcodec/xsubenc.c @@ -22,6 +22,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "internal.h" #include "put_bits.h" /** @@ -90,7 +91,7 @@ static int xsub_encode_rle(PutBitContext *pb, const uint8_t *bitmap, if (color != PADDING_COLOR && (PADDING + (w&1))) put_xsub_rle(pb, PADDING + (w&1), PADDING_COLOR); - avpriv_align_put_bits(pb); + align_put_bits(pb); bitmap += linesize; } @@ -206,7 +207,6 @@ FF_ENABLE_DEPRECATION_WARNINGS // 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); } flush_put_bits(&pb); @@ -231,4 +231,5 @@ AVCodec ff_xsub_encoder = { .id = AV_CODEC_ID_XSUB, .init = xsub_encoder_init, .encode_sub = xsub_encode, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index afe60e156..1dd46b36e 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -71,16 +71,12 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) if (!s->y_buffer) return AVERROR(ENOMEM); s->scratch_buffer = av_malloc(s->buffer_size + 130); - if (!s->scratch_buffer) { - xan_decode_end(avctx); + if (!s->scratch_buffer) return AVERROR(ENOMEM); - } s->pic = av_frame_alloc(); - if (!s->pic) { - xan_decode_end(avctx); + if (!s->pic) return AVERROR(ENOMEM); - } return 0; } @@ -447,4 +443,5 @@ AVCodec ff_xan_wc4_decoder = { .close = xan_decode_end, .decode = xan_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/y41pdec.c b/libavcodec/y41pdec.c index 85a39e4ae..2bfabe277 100644 --- a/libavcodec/y41pdec.c +++ b/libavcodec/y41pdec.c @@ -89,4 +89,5 @@ AVCodec ff_y41p_decoder = { .init = y41p_decode_init, .decode = y41p_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/y41penc.c b/libavcodec/y41penc.c index 63752e2b4..4340a3fbb 100644 --- a/libavcodec/y41penc.c +++ b/libavcodec/y41penc.c @@ -75,11 +75,6 @@ static int y41p_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int y41p_encode_close(AVCodecContext *avctx) -{ - return 0; -} - AVCodec ff_y41p_encoder = { .name = "y41p", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), @@ -87,7 +82,7 @@ AVCodec ff_y41p_encoder = { .id = AV_CODEC_ID_Y41P, .init = y41p_encode_init, .encode2 = y41p_encode_frame, - .close = y41p_encode_close, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/ylc.c b/libavcodec/ylc.c index 2afe3fc9d..ab1f8958f 100644 --- a/libavcodec/ylc.c +++ b/libavcodec/ylc.c @@ -22,6 +22,8 @@ #include #include +#define YLC_VLC_BITS 10 + #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" @@ -36,11 +38,9 @@ typedef struct YLCContext { VLC vlc[4]; - uint32_t table[1024]; - uint8_t *table_bits; - uint8_t *bitstream_bits; - int table_bits_size; - int bitstream_bits_size; + uint32_t table[256]; + uint8_t *buffer; + int buffer_size; BswapDSPContext bdsp; } YLCContext; @@ -56,7 +56,6 @@ static av_cold int decode_init(AVCodecContext *avctx) typedef struct Node { int16_t sym; - int16_t n0; uint32_t count; int16_t l, r; } Node; @@ -97,7 +96,6 @@ static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table) for (i = 0; i < 256; i++) { nodes[i].count = table[i]; nodes[i].sym = i; - nodes[i].n0 = -2; nodes[i].l = i; nodes[i].r = i; } @@ -139,7 +137,6 @@ static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table) } nodes[cur_node].count = nd + st; nodes[cur_node].sym = -1; - nodes[cur_node].n0 = cur_node; nodes[cur_node].l = first_node; nodes[cur_node].r = second_node; cur_node++; @@ -149,7 +146,8 @@ static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table) get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos); - return ff_init_vlc_sparse(vlc, 10, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); + return ff_init_vlc_sparse(vlc, YLC_VLC_BITS, pos, lens, 2, 2, + bits, 4, 4, xlat, 1, 1, 0); } static const uint8_t table_y1[] = { @@ -312,50 +310,39 @@ static int decode_frame(AVCodecContext *avctx, if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; - av_fast_malloc(&s->table_bits, &s->table_bits_size, - boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE); - if (!s->table_bits) + av_fast_malloc(&s->buffer, &s->buffer_size, + FFMAX(boffset - toffset, avpkt->size - boffset) + + AV_INPUT_BUFFER_PADDING_SIZE); + if (!s->buffer) return AVERROR(ENOMEM); - memcpy(s->table_bits, avpkt->data + toffset, boffset - toffset); - memset(s->table_bits + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE); - s->bdsp.bswap_buf((uint32_t *) s->table_bits, - (uint32_t *) s->table_bits, + memcpy(s->buffer, avpkt->data + toffset, boffset - toffset); + memset(s->buffer + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE); + s->bdsp.bswap_buf((uint32_t *) s->buffer, + (uint32_t *) s->buffer, (boffset - toffset + 3) >> 2); - if ((ret = init_get_bits8(&gb, s->table_bits, boffset - toffset)) < 0) + if ((ret = init_get_bits8(&gb, s->buffer, boffset - toffset)) < 0) return ret; - for (x = 0; x < 1024; x++) { - unsigned len = get_unary(&gb, 1, 31); - uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len); + for (int i = 0; i < 4; i++) { + for (x = 0; x < 256; x++) { + unsigned len = get_unary(&gb, 1, 31); + uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len); - s->table[x] = val; + s->table[x] = val; + } + + ret = build_vlc(avctx, &s->vlc[i], s->table); + if (ret < 0) + return ret; } - ret = build_vlc(avctx, &s->vlc[0], &s->table[0 ]); - if (ret < 0) - return ret; - ret = build_vlc(avctx, &s->vlc[1], &s->table[256]); - if (ret < 0) - return ret; - ret = build_vlc(avctx, &s->vlc[2], &s->table[512]); - if (ret < 0) - return ret; - ret = build_vlc(avctx, &s->vlc[3], &s->table[768]); - if (ret < 0) - return ret; - - av_fast_malloc(&s->bitstream_bits, &s->bitstream_bits_size, - avpkt->size - boffset + AV_INPUT_BUFFER_PADDING_SIZE); - if (!s->bitstream_bits) - return AVERROR(ENOMEM); - - memcpy(s->bitstream_bits, avpkt->data + boffset, avpkt->size - boffset); - memset(s->bitstream_bits + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE); - s->bdsp.bswap_buf((uint32_t *) s->bitstream_bits, - (uint32_t *) s->bitstream_bits, + memcpy(s->buffer, avpkt->data + boffset, avpkt->size - boffset); + memset(s->buffer + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE); + s->bdsp.bswap_buf((uint32_t *) s->buffer, + (uint32_t *) s->buffer, (avpkt->size - boffset) >> 2); - if ((ret = init_get_bits8(&gb, s->bitstream_bits, avpkt->size - boffset)) < 0) + if ((ret = init_get_bits8(&gb, s->buffer, avpkt->size - boffset)) < 0) return ret; dst = p->data[0]; @@ -371,7 +358,7 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; if (get_bits1(&gb)) { - int val = get_vlc2(&gb, s->vlc[0].table, s->vlc[0].bits, 3); + int val = get_vlc2(&gb, s->vlc[0].table, YLC_VLC_BITS, 3); if (val < 0) { return AVERROR_INVALIDDATA; } else if (val < 0xE1) { @@ -394,10 +381,10 @@ static int decode_frame(AVCodecContext *avctx, } else { int y1, y2, u, v; - y1 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3); - u = get_vlc2(&gb, s->vlc[2].table, s->vlc[2].bits, 3); - y2 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3); - v = get_vlc2(&gb, s->vlc[3].table, s->vlc[3].bits, 3); + y1 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3); + u = get_vlc2(&gb, s->vlc[2].table, YLC_VLC_BITS, 3); + y2 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3); + v = get_vlc2(&gb, s->vlc[3].table, YLC_VLC_BITS, 3); if (y1 < 0 || y2 < 0 || u < 0 || v < 0) return AVERROR_INVALIDDATA; dst[x ] = y1; @@ -457,14 +444,10 @@ static av_cold int decode_end(AVCodecContext *avctx) { YLCContext *s = avctx->priv_data; - ff_free_vlc(&s->vlc[0]); - ff_free_vlc(&s->vlc[1]); - ff_free_vlc(&s->vlc[2]); - ff_free_vlc(&s->vlc[3]); - av_freep(&s->table_bits); - s->table_bits_size = 0; - av_freep(&s->bitstream_bits); - s->bitstream_bits_size = 0; + for (int i = 0; i < FF_ARRAY_ELEMS(s->vlc); i++) + ff_free_vlc(&s->vlc[i]); + av_freep(&s->buffer); + s->buffer_size = 0; return 0; } diff --git a/libavcodec/yop.c b/libavcodec/yop.c index aff28ef3f..8f8ed940e 100644 --- a/libavcodec/yop.c +++ b/libavcodec/yop.c @@ -274,4 +274,5 @@ AVCodec ff_yop_decoder = { .init = yop_decode_init, .close = yop_decode_close, .decode = yop_decode_frame, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/yuv4dec.c b/libavcodec/yuv4dec.c index f89f62deb..3fb1dbac2 100644 --- a/libavcodec/yuv4dec.c +++ b/libavcodec/yuv4dec.c @@ -81,4 +81,5 @@ AVCodec ff_yuv4_decoder = { .init = yuv4_decode_init, .decode = yuv4_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/yuv4enc.c b/libavcodec/yuv4enc.c index f21b1f36c..63a7fae96 100644 --- a/libavcodec/yuv4enc.c +++ b/libavcodec/yuv4enc.c @@ -23,11 +23,6 @@ #include "avcodec.h" #include "internal.h" -static av_cold int yuv4_encode_init(AVCodecContext *avctx) -{ - return 0; -} - static int yuv4_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) { @@ -62,18 +57,11 @@ static int yuv4_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int yuv4_encode_close(AVCodecContext *avctx) -{ - return 0; -} - 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 }, }; diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 6ea62b914..0dfe47a1f 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -15,6 +15,7 @@ OBJS-$(CONFIG_SHARED) += reverse.o OBJS-$(CONFIG_ALSA_INDEV) += alsa_dec.o alsa.o timefilter.o OBJS-$(CONFIG_ALSA_OUTDEV) += alsa_enc.o alsa.o OBJS-$(CONFIG_ANDROID_CAMERA_INDEV) += android_camera.o +OBJS-$(CONFIG_AUDIOTOOLBOX_OUTDEV) += audiotoolbox.o OBJS-$(CONFIG_AVFOUNDATION_INDEV) += avfoundation.o OBJS-$(CONFIG_BKTR_INDEV) += bktr.o OBJS-$(CONFIG_CACA_OUTDEV) += caca.o diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index 863343325..92b27a1d1 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -27,6 +27,7 @@ extern AVInputFormat ff_alsa_demuxer; extern AVOutputFormat ff_alsa_muxer; extern AVInputFormat ff_android_camera_demuxer; +extern AVOutputFormat ff_audiotoolbox_muxer; extern AVInputFormat ff_avfoundation_demuxer; extern AVInputFormat ff_bktr_demuxer; extern AVOutputFormat ff_caca_muxer; @@ -66,3 +67,75 @@ void avdevice_register_all(void) { avpriv_register_devices(outdev_list, indev_list); } + +static void *next_input(const AVInputFormat *prev, AVClassCategory c2) +{ + const AVClass *pc; + const AVClassCategory c1 = AV_CLASS_CATEGORY_DEVICE_INPUT; + AVClassCategory category = AV_CLASS_CATEGORY_NA; + const AVInputFormat *fmt = NULL; + int i = 0; + + while (prev && (fmt = indev_list[i])) { + i++; + if (prev == fmt) + break; + } + + do { + fmt = indev_list[i++]; + if (!fmt) + break; + pc = fmt->priv_class; + if (!pc) + continue; + category = pc->category; + } while (category != c1 && category != c2); + return (AVInputFormat *)fmt; +} + +static void *next_output(const AVOutputFormat *prev, AVClassCategory c2) +{ + const AVClass *pc; + const AVClassCategory c1 = AV_CLASS_CATEGORY_DEVICE_OUTPUT; + AVClassCategory category = AV_CLASS_CATEGORY_NA; + const AVOutputFormat *fmt = NULL; + int i = 0; + + while (prev && (fmt = outdev_list[i])) { + i++; + if (prev == fmt) + break; + } + + do { + fmt = outdev_list[i++]; + if (!fmt) + break; + pc = fmt->priv_class; + if (!pc) + continue; + category = pc->category; + } while (category != c1 && category != c2); + return (AVOutputFormat *)fmt; +} + +AVInputFormat *av_input_audio_device_next(AVInputFormat *d) +{ + return next_input(d, AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT); +} + +AVInputFormat *av_input_video_device_next(AVInputFormat *d) +{ + return next_input(d, AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT); +} + +AVOutputFormat *av_output_audio_device_next(AVOutputFormat *d) +{ + return next_output(d, AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT); +} + +AVOutputFormat *av_output_video_device_next(AVOutputFormat *d) +{ + return next_output(d, AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT); +} diff --git a/libavdevice/alsa.c b/libavdevice/alsa.c index 117b2ea14..ee282fac1 100644 --- a/libavdevice/alsa.c +++ b/libavdevice/alsa.c @@ -286,6 +286,10 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, } } + s->pkt = av_packet_alloc(); + if (!s->pkt) + goto fail1; + s->h = h; return 0; @@ -308,6 +312,7 @@ av_cold int ff_alsa_close(AVFormatContext *s1) if (CONFIG_ALSA_INDEV) ff_timefilter_destroy(s->timefilter); snd_pcm_close(s->h); + av_packet_free(&s->pkt); return 0; } diff --git a/libavdevice/alsa.h b/libavdevice/alsa.h index 1ed8c8219..07783c983 100644 --- a/libavdevice/alsa.h +++ b/libavdevice/alsa.h @@ -58,6 +58,7 @@ typedef struct AlsaData { void *reorder_buf; int reorder_buf_size; ///< in frames int64_t timestamp; ///< current timestamp, without latency applied. + AVPacket *pkt; } AlsaData; /** diff --git a/libavdevice/alsa_dec.c b/libavdevice/alsa_dec.c index 36494e921..d8d4f3293 100644 --- a/libavdevice/alsa_dec.c +++ b/libavdevice/alsa_dec.c @@ -105,34 +105,36 @@ static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) int64_t dts; snd_pcm_sframes_t delay = 0; - if (av_new_packet(pkt, s->period_size * s->frame_size) < 0) { - return AVERROR(EIO); + if (!s->pkt->data) { + int ret = av_new_packet(s->pkt, s->period_size * s->frame_size); + if (ret < 0) + return ret; + s->pkt->size = 0; } - while ((res = snd_pcm_readi(s->h, pkt->data, s->period_size)) < 0) { + do { + while ((res = snd_pcm_readi(s->h, s->pkt->data + s->pkt->size, s->period_size - s->pkt->size / s->frame_size)) < 0) { if (res == -EAGAIN) { - av_packet_unref(pkt); - return AVERROR(EAGAIN); } + s->pkt->size = 0; if (ff_alsa_xrun_recover(s1, res) < 0) { av_log(s1, AV_LOG_ERROR, "ALSA read error: %s\n", snd_strerror(res)); - av_packet_unref(pkt); - return AVERROR(EIO); } ff_timefilter_reset(s->timefilter); - } + } + s->pkt->size += res * s->frame_size; + } while (s->pkt->size < s->period_size * s->frame_size); + av_packet_move_ref(pkt, s->pkt); dts = av_gettime(); snd_pcm_delay(s->h, &delay); dts -= av_rescale(delay + res, 1000000, s->sample_rate); pkt->pts = ff_timefilter_update(s->timefilter, dts, s->last_period); s->last_period = res; - pkt->size = res * s->frame_size; - return 0; } diff --git a/libavdevice/audiotoolbox.m b/libavdevice/audiotoolbox.m new file mode 100644 index 000000000..d8c8312a0 --- /dev/null +++ b/libavdevice/audiotoolbox.m @@ -0,0 +1,308 @@ +/* + * AudioToolbox output device + * Copyright (c) 2020 Thilo Borgmann + * + * 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 + * AudioToolbox output device + * @author Thilo Borgmann + */ + +#import +#include + +#include "libavutil/opt.h" +#include "libavformat/internal.h" +#include "libavutil/internal.h" +#include "avdevice.h" + +typedef struct +{ + AVClass *class; + + AudioQueueBufferRef buffer[2]; + pthread_mutex_t buffer_lock[2]; + int cur_buf; + AudioQueueRef queue; + + int list_devices; + int audio_device_index; + +} ATContext; + +static int check_status(AVFormatContext *avctx, OSStatus *status, const char *msg) +{ + if (*status != noErr) { + av_log(avctx, AV_LOG_ERROR, "Error: %s (%i)\n", msg, *status); + return 1; + } else { + av_log(avctx, AV_LOG_DEBUG, " OK : %s\n", msg); + return 0; + } +} + +static void queue_callback(void* atctx, AudioQueueRef inAQ, + AudioQueueBufferRef inBuffer) +{ + // unlock the buffer that has just been consumed + ATContext *ctx = (ATContext*)atctx; + for (int i = 0; i < 2; i++) { + if (inBuffer == ctx->buffer[i]) { + pthread_mutex_unlock(&ctx->buffer_lock[i]); + } + } +} + +static av_cold int at_write_header(AVFormatContext *avctx) +{ + ATContext *ctx = (ATContext*)avctx->priv_data; + OSStatus err = noErr; + CFStringRef device_UID = NULL; + AudioDeviceID *devices; + int num_devices; + + + // get devices + UInt32 data_size = 0; + AudioObjectPropertyAddress prop; + prop.mSelector = kAudioHardwarePropertyDevices; + prop.mScope = kAudioObjectPropertyScopeGlobal; + prop.mElement = kAudioObjectPropertyElementMaster; + err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &prop, 0, NULL, &data_size); + if (check_status(avctx, &err, "AudioObjectGetPropertyDataSize devices")) + return AVERROR(EINVAL); + + num_devices = data_size / sizeof(AudioDeviceID); + + devices = (AudioDeviceID*)(av_malloc(data_size)); + err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop, 0, NULL, &data_size, devices); + if (check_status(avctx, &err, "AudioObjectGetPropertyData devices")) { + av_freep(&devices); + return AVERROR(EINVAL); + } + + // list devices + if (ctx->list_devices) { + CFStringRef device_name = NULL; + prop.mScope = kAudioDevicePropertyScopeInput; + + av_log(ctx, AV_LOG_INFO, "CoreAudio devices:\n"); + for(UInt32 i = 0; i < num_devices; ++i) { + // UID + data_size = sizeof(device_UID); + prop.mSelector = kAudioDevicePropertyDeviceUID; + err = AudioObjectGetPropertyData(devices[i], &prop, 0, NULL, &data_size, &device_UID); + if (check_status(avctx, &err, "AudioObjectGetPropertyData UID")) + continue; + + // name + data_size = sizeof(device_name); + prop.mSelector = kAudioDevicePropertyDeviceNameCFString; + err = AudioObjectGetPropertyData(devices[i], &prop, 0, NULL, &data_size, &device_name); + if (check_status(avctx, &err, "AudioObjecTGetPropertyData name")) + continue; + + av_log(ctx, AV_LOG_INFO, "[%d] %30s, %s\n", i, + CFStringGetCStringPtr(device_name, kCFStringEncodingMacRoman), + CFStringGetCStringPtr(device_UID, kCFStringEncodingMacRoman)); + } + } + + // get user-defined device UID or use default device + // -audio_device_index overrides any URL given + const char *stream_name = avctx->url; + if (stream_name && ctx->audio_device_index == -1) { + sscanf(stream_name, "%d", &ctx->audio_device_index); + } + + if (ctx->audio_device_index >= 0) { + // get UID of selected device + data_size = sizeof(device_UID); + prop.mSelector = kAudioDevicePropertyDeviceUID; + err = AudioObjectGetPropertyData(devices[ctx->audio_device_index], &prop, 0, NULL, &data_size, &device_UID); + if (check_status(avctx, &err, "AudioObjecTGetPropertyData UID")) { + av_freep(&devices); + return AVERROR(EINVAL); + } + } else { + // use default device + device_UID = NULL; + } + + av_log(ctx, AV_LOG_DEBUG, "stream_name: %s\n", stream_name); + av_log(ctx, AV_LOG_DEBUG, "audio_device_idnex: %i\n", ctx->audio_device_index); + av_log(ctx, AV_LOG_DEBUG, "UID: %s\n", CFStringGetCStringPtr(device_UID, kCFStringEncodingMacRoman)); + + // check input stream + if (avctx->nb_streams != 1 || avctx->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) { + av_log(ctx, AV_LOG_ERROR, "Only a single audio stream is supported.\n"); + return AVERROR(EINVAL); + } + + av_freep(&devices); + AVCodecParameters *codecpar = avctx->streams[0]->codecpar; + + // audio format + AudioStreamBasicDescription device_format = {0}; + device_format.mSampleRate = codecpar->sample_rate; + device_format.mFormatID = kAudioFormatLinearPCM; + device_format.mFormatFlags |= (codecpar->format == AV_SAMPLE_FMT_FLT) ? kLinearPCMFormatFlagIsFloat : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_S8) ? kLinearPCMFormatFlagIsSignedInteger : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE)) ? kLinearPCMFormatFlagIsSignedInteger : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S24BE, AV_CODEC_ID_PCM_S24LE)) ? kLinearPCMFormatFlagIsSignedInteger : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S32BE, AV_CODEC_ID_PCM_S32LE)) ? kLinearPCMFormatFlagIsSignedInteger : 0; + device_format.mFormatFlags |= (av_sample_fmt_is_planar(codecpar->format)) ? kAudioFormatFlagIsNonInterleaved : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_F32BE) ? kAudioFormatFlagIsBigEndian : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_S16BE) ? kAudioFormatFlagIsBigEndian : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_S24BE) ? kAudioFormatFlagIsBigEndian : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_S32BE) ? kAudioFormatFlagIsBigEndian : 0; + device_format.mChannelsPerFrame = codecpar->channels; + device_format.mBitsPerChannel = (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S24BE, AV_CODEC_ID_PCM_S24LE)) ? 24 : (av_get_bytes_per_sample(codecpar->format) << 3); + device_format.mBytesPerFrame = (device_format.mBitsPerChannel >> 3) * device_format.mChannelsPerFrame; + device_format.mFramesPerPacket = 1; + device_format.mBytesPerPacket = device_format.mBytesPerFrame * device_format.mFramesPerPacket; + device_format.mReserved = 0; + + av_log(ctx, AV_LOG_DEBUG, "device_format.mSampleRate = %i\n", codecpar->sample_rate); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatID = %s\n", "kAudioFormatLinearPCM"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->format == AV_SAMPLE_FMT_FLT) ? "kLinearPCMFormatFlagIsFloat" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_S8) ? "kLinearPCMFormatFlagIsSignedInteger" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S32BE, AV_CODEC_ID_PCM_S32LE)) ? "kLinearPCMFormatFlagIsSignedInteger" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE)) ? "kLinearPCMFormatFlagIsSignedInteger" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S24BE, AV_CODEC_ID_PCM_S24LE)) ? "kLinearPCMFormatFlagIsSignedInteger" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (av_sample_fmt_is_planar(codecpar->format)) ? "kAudioFormatFlagIsNonInterleaved" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_F32BE) ? "kAudioFormatFlagIsBigEndian" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_S16BE) ? "kAudioFormatFlagIsBigEndian" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_S24BE) ? "kAudioFormatFlagIsBigEndian" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_S32BE) ? "kAudioFormatFlagIsBigEndian" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags == %i\n", device_format.mFormatFlags); + av_log(ctx, AV_LOG_DEBUG, "device_format.mChannelsPerFrame = %i\n", codecpar->channels); + av_log(ctx, AV_LOG_DEBUG, "device_format.mBitsPerChannel = %i\n", av_get_bytes_per_sample(codecpar->format) << 3); + av_log(ctx, AV_LOG_DEBUG, "device_format.mBytesPerFrame = %i\n", (device_format.mBitsPerChannel >> 3) * codecpar->channels); + av_log(ctx, AV_LOG_DEBUG, "device_format.mBytesPerPacket = %i\n", device_format.mBytesPerFrame); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFramesPerPacket = %i\n", 1); + av_log(ctx, AV_LOG_DEBUG, "device_format.mReserved = %i\n", 0); + + // create new output queue for the device + err = AudioQueueNewOutput(&device_format, queue_callback, ctx, + NULL, kCFRunLoopCommonModes, + 0, &ctx->queue); + if (check_status(avctx, &err, "AudioQueueNewOutput")) { + if (err == kAudioFormatUnsupportedDataFormatError) + av_log(ctx, AV_LOG_ERROR, "Unsupported output format.\n"); + return AVERROR(EINVAL); + } + + // set user-defined device or leave untouched for default + if (device_UID != NULL) { + err = AudioQueueSetProperty(ctx->queue, kAudioQueueProperty_CurrentDevice, &device_UID, sizeof(device_UID)); + if (check_status(avctx, &err, "AudioQueueSetProperty output UID")) + return AVERROR(EINVAL); + } + + // start the queue + err = AudioQueueStart(ctx->queue, NULL); + if (check_status(avctx, &err, "AudioQueueStart")) + return AVERROR(EINVAL); + + // init the mutexes for double-buffering + pthread_mutex_init(&ctx->buffer_lock[0], NULL); + pthread_mutex_init(&ctx->buffer_lock[1], NULL); + + return 0; +} + +static int at_write_packet(AVFormatContext *avctx, AVPacket *pkt) +{ + ATContext *ctx = (ATContext*)avctx->priv_data; + OSStatus err = noErr; + + // use the other buffer + ctx->cur_buf = !ctx->cur_buf; + + // lock for writing or wait for the buffer to be available + // will be unlocked by queue callback + pthread_mutex_lock(&ctx->buffer_lock[ctx->cur_buf]); + + // (re-)allocate the buffer if not existant or of different size + if (!ctx->buffer[ctx->cur_buf] || ctx->buffer[ctx->cur_buf]->mAudioDataBytesCapacity != pkt->size) { + err = AudioQueueAllocateBuffer(ctx->queue, pkt->size, &ctx->buffer[ctx->cur_buf]); + if (check_status(avctx, &err, "AudioQueueAllocateBuffer")) { + pthread_mutex_unlock(&ctx->buffer_lock[ctx->cur_buf]); + return AVERROR(ENOMEM); + } + } + + AudioQueueBufferRef buf = ctx->buffer[ctx->cur_buf]; + + // copy audio data into buffer and enqueue the buffer + memcpy(buf->mAudioData, pkt->data, buf->mAudioDataBytesCapacity); + buf->mAudioDataByteSize = buf->mAudioDataBytesCapacity; + err = AudioQueueEnqueueBuffer(ctx->queue, buf, 0, NULL); + if (check_status(avctx, &err, "AudioQueueEnqueueBuffer")) { + pthread_mutex_unlock(&ctx->buffer_lock[ctx->cur_buf]); + return AVERROR(EINVAL); + } + + return 0; +} + +static av_cold int at_write_trailer(AVFormatContext *avctx) +{ + ATContext *ctx = (ATContext*)avctx->priv_data; + OSStatus err = noErr; + + pthread_mutex_destroy(&ctx->buffer_lock[0]); + pthread_mutex_destroy(&ctx->buffer_lock[1]); + + err = AudioQueueFlush(ctx->queue); + check_status(avctx, &err, "AudioQueueFlush"); + err = AudioQueueDispose(ctx->queue, true); + check_status(avctx, &err, "AudioQueueDispose"); + + return 0; +} + +static const AVOption options[] = { + { "list_devices", "list available audio devices", offsetof(ATContext, list_devices), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, + { "audio_device_index", "select audio device by index (starts at 0)", offsetof(ATContext, audio_device_index), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, + { NULL }, +}; + +static const AVClass at_class = { + .class_name = "AudioToolbox", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, +}; + +AVOutputFormat ff_audiotoolbox_muxer = { + .name = "audiotoolbox", + .long_name = NULL_IF_CONFIG_SMALL("AudioToolbox output device"), + .priv_data_size = sizeof(ATContext), + .audio_codec = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE), + .video_codec = AV_CODEC_ID_NONE, + .write_header = at_write_header, + .write_packet = at_write_packet, + .write_trailer = at_write_trailer, + .flags = AVFMT_NOFILE, + .priv_class = &at_class, +}; diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c index 3d03d89f0..554debcf0 100644 --- a/libavdevice/avdevice.c +++ b/libavdevice/avdevice.c @@ -27,39 +27,11 @@ #include "libavutil/ffversion.h" const char av_device_ffversion[] = "FFmpeg version " FFMPEG_VERSION; -#define E AV_OPT_FLAG_ENCODING_PARAM -#define D AV_OPT_FLAG_DECODING_PARAM -#define A AV_OPT_FLAG_AUDIO_PARAM -#define V AV_OPT_FLAG_VIDEO_PARAM -#define OFFSET(x) offsetof(AVDeviceCapabilitiesQuery, x) - +#if FF_API_DEVICE_CAPABILITIES const AVOption av_device_capabilities[] = { - { "codec", "codec", OFFSET(codec), AV_OPT_TYPE_INT, - {.i64 = AV_CODEC_ID_NONE}, AV_CODEC_ID_NONE, INT_MAX, E|D|A|V }, - { "sample_format", "sample format", OFFSET(sample_format), AV_OPT_TYPE_SAMPLE_FMT, - {.i64 = AV_SAMPLE_FMT_NONE}, AV_SAMPLE_FMT_NONE, INT_MAX, E|D|A }, - { "sample_rate", "sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, - {.i64 = -1}, -1, INT_MAX, E|D|A }, - { "channels", "channels", OFFSET(channels), AV_OPT_TYPE_INT, - {.i64 = -1}, -1, INT_MAX, E|D|A }, - { "channel_layout", "channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, - {.i64 = -1}, -1, INT_MAX, E|D|A }, - { "pixel_format", "pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, - {.i64 = AV_PIX_FMT_NONE}, AV_PIX_FMT_NONE, INT_MAX, E|D|V }, - { "window_size", "window size", OFFSET(window_width), AV_OPT_TYPE_IMAGE_SIZE, - {.str = NULL}, -1, INT_MAX, E|D|V }, - { "frame_size", "frame size", OFFSET(frame_width), AV_OPT_TYPE_IMAGE_SIZE, - {.str = NULL}, -1, INT_MAX, E|D|V }, - { "fps", "fps", OFFSET(fps), AV_OPT_TYPE_RATIONAL, - {.dbl = -1}, -1, INT_MAX, E|D|V }, { NULL } }; - -#undef E -#undef D -#undef A -#undef V -#undef OFFSET +#endif unsigned avdevice_version(void) { @@ -78,52 +50,6 @@ const char * avdevice_license(void) return &LICENSE_PREFIX FFMPEG_LICENSE[sizeof(LICENSE_PREFIX) - 1]; } -static void *device_next(void *prev, int output, - AVClassCategory c1, AVClassCategory c2) -{ - const AVClass *pc; - AVClassCategory category = AV_CLASS_CATEGORY_NA; - do { - if (output) { - if (!(prev = av_oformat_next(prev))) - break; - pc = ((AVOutputFormat *)prev)->priv_class; - } else { - if (!(prev = av_iformat_next(prev))) - break; - pc = ((AVInputFormat *)prev)->priv_class; - } - if (!pc) - continue; - category = pc->category; - } while (category != c1 && category != c2); - return prev; -} - -AVInputFormat *av_input_audio_device_next(AVInputFormat *d) -{ - return device_next(d, 0, AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, - AV_CLASS_CATEGORY_DEVICE_INPUT); -} - -AVInputFormat *av_input_video_device_next(AVInputFormat *d) -{ - return device_next(d, 0, AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, - AV_CLASS_CATEGORY_DEVICE_INPUT); -} - -AVOutputFormat *av_output_audio_device_next(AVOutputFormat *d) -{ - return device_next(d, 1, AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, - AV_CLASS_CATEGORY_DEVICE_OUTPUT); -} - -AVOutputFormat *av_output_video_device_next(AVOutputFormat *d) -{ - return device_next(d, 1, AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT, - AV_CLASS_CATEGORY_DEVICE_OUTPUT); -} - int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum AVAppToDevMessageType type, void *data, size_t data_size) { @@ -140,49 +66,18 @@ int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum AVDevToA return s->control_message_cb(s, type, data, data_size); } +#if FF_API_DEVICE_CAPABILITIES int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s, AVDictionary **device_options) { - int ret; - av_assert0(s && caps); - av_assert0(s->iformat || s->oformat); - if ((s->oformat && !s->oformat->create_device_capabilities) || - (s->iformat && !s->iformat->create_device_capabilities)) - return AVERROR(ENOSYS); - *caps = av_mallocz(sizeof(**caps)); - if (!(*caps)) - return AVERROR(ENOMEM); - (*caps)->device_context = s; - if (((ret = av_opt_set_dict(s->priv_data, device_options)) < 0)) - goto fail; - if (s->iformat) { - if ((ret = s->iformat->create_device_capabilities(s, *caps)) < 0) - goto fail; - } else { - if ((ret = s->oformat->create_device_capabilities(s, *caps)) < 0) - goto fail; - } - av_opt_set_defaults(*caps); - return 0; - fail: - av_freep(caps); - return ret; + return AVERROR(ENOSYS); } void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s) { - if (!s || !caps || !(*caps)) - return; - av_assert0(s->iformat || s->oformat); - if (s->iformat) { - if (s->iformat->free_device_capabilities) - s->iformat->free_device_capabilities(s, *caps); - } else { - if (s->oformat->free_device_capabilities) - s->oformat->free_device_capabilities(s, *caps); - } - av_freep(caps); + return; } +#endif int avdevice_list_devices(AVFormatContext *s, AVDeviceInfoList **device_list) { diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h index ee9462480..85a4dcc6d 100644 --- a/libavdevice/avdevice.h +++ b/libavdevice/avdevice.h @@ -321,6 +321,7 @@ int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum AVDevToAppMessageType type, void *data, size_t data_size); +#if FF_API_DEVICE_CAPABILITIES /** * Following API allows user to probe device capabilities (supported codecs, * pixel formats, sample formats, resolutions, channel counts, etc). @@ -416,6 +417,7 @@ typedef struct AVDeviceCapabilitiesQuery { /** * AVOption table used by devices to implement device capabilities API. Should not be used by a user. */ +attribute_deprecated extern const AVOption av_device_capabilities[]; /** @@ -435,6 +437,7 @@ extern const AVOption av_device_capabilities[]; * * @return >= 0 on success, negative otherwise. */ +attribute_deprecated int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s, AVDictionary **device_options); @@ -444,7 +447,9 @@ int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatConte * @param caps Device capabilities data to be freed. * @param s Context of the device. */ +attribute_deprecated void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s); +#endif /** * Structure describes basic parameters of the device. diff --git a/libavdevice/bktr.c b/libavdevice/bktr.c index 2601adbba..0688028f9 100644 --- a/libavdevice/bktr.c +++ b/libavdevice/bktr.c @@ -225,14 +225,14 @@ static void bktr_getframe(uint64_t per_frame) { uint64_t curtime; - curtime = av_gettime(); + curtime = av_gettime_relative(); if (!last_frame_time || ((last_frame_time + per_frame) > curtime)) { if (!usleep(last_frame_time + per_frame + per_frame / 8 - curtime)) { if (!nsignals) av_log(NULL, AV_LOG_INFO, "SLEPT NO signals - %d microseconds late\n", - (int)(av_gettime() - last_frame_time - per_frame)); + (int)(av_gettime_relative() - last_frame_time - per_frame)); } } nsignals = 0; diff --git a/libavdevice/caca.c b/libavdevice/caca.c index be3ff7973..726cfda95 100644 --- a/libavdevice/caca.c +++ b/libavdevice/caca.c @@ -180,7 +180,7 @@ static int caca_write_header(AVFormatContext *s) if (!c->window_title) c->window_title = av_strdup(s->url); caca_set_display_title(c->display, c->window_title); - caca_set_display_time(c->display, av_rescale_q(1, st->codec->time_base, AV_TIME_BASE_Q)); + caca_set_display_time(c->display, av_rescale_q(1, st->time_base, AV_TIME_BASE_Q)); return 0; diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index 53b57ffe4..24aa9b1d1 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -70,9 +70,30 @@ static IDeckLinkIterator *decklink_create_iterator(AVFormatContext *avctx) #else iter = CreateDeckLinkIteratorInstance(); #endif - if (!iter) + if (!iter) { av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator. " "Make sure you have DeckLink drivers " BLACKMAGIC_DECKLINK_API_VERSION_STRING " or newer installed.\n"); + } else { + IDeckLinkAPIInformation *api; + int64_t version; +#ifdef _WIN32 + if (CoCreateInstance(CLSID_CDeckLinkAPIInformation, NULL, CLSCTX_ALL, + IID_IDeckLinkAPIInformation, (void**) &api) != S_OK) { + api = NULL; + } +#else + api = CreateDeckLinkAPIInformationInstance(); +#endif + if (api && api->GetInt(BMDDeckLinkAPIVersion, &version) == S_OK) { + if (version < BLACKMAGIC_DECKLINK_API_VERSION) + av_log(avctx, AV_LOG_WARNING, "Installed DeckLink drivers are too old and may be incompatible with the SDK this module was built against. " + "Make sure you have DeckLink drivers " BLACKMAGIC_DECKLINK_API_VERSION_STRING " or newer installed.\n"); + } else { + av_log(avctx, AV_LOG_ERROR, "Failed to check installed DeckLink API version.\n"); + } + if (api) + api->Release(); + } return iter; } @@ -272,7 +293,7 @@ int ff_decklink_set_format(AVFormatContext *avctx, #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b050000 if (direction == DIRECTION_IN) { BMDDisplayMode actualMode = ctx->bmd_mode; - if (ctx->dli->DoesSupportVideoMode(ctx->video_input, ctx->bmd_mode, (BMDPixelFormat) cctx->raw_format, + if (ctx->dli->DoesSupportVideoMode(ctx->video_input, ctx->bmd_mode, ctx->raw_format, bmdNoVideoInputConversion, bmdSupportedVideoModeDefault, &actualMode, &support) != S_OK || !support || ctx->bmd_mode != actualMode) return -1; @@ -286,7 +307,7 @@ int ff_decklink_set_format(AVFormatContext *avctx, return 0; #elif BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 if (direction == DIRECTION_IN) { - if (ctx->dli->DoesSupportVideoMode(ctx->video_input, ctx->bmd_mode, (BMDPixelFormat) cctx->raw_format, + if (ctx->dli->DoesSupportVideoMode(ctx->video_input, ctx->bmd_mode, ctx->raw_format, bmdSupportedVideoModeDefault, &support) != S_OK) return -1; @@ -303,7 +324,7 @@ int ff_decklink_set_format(AVFormatContext *avctx, return 0; #else if (direction == DIRECTION_IN) { - if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, (BMDPixelFormat) cctx->raw_format, + if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, ctx->raw_format, bmdVideoOutputFlagDefault, &support, NULL) != S_OK) return -1; diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index 27ce6a8a4..6e032956a 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -75,7 +75,7 @@ class decklink_output_callback; class decklink_input_callback; typedef struct AVPacketQueue { - AVPacketList *first_pkt, *last_pkt; + PacketList *first_pkt, *last_pkt; int nb_packets; unsigned long long size; int abort_request; @@ -120,12 +120,14 @@ struct decklink_ctx { unsigned int dropped; AVStream *audio_st; AVStream *video_st; + AVStream *klv_st; AVStream *teletext_st; uint16_t cdp_sequence_num; /* Options */ int list_devices; int list_formats; + int enable_klv; int64_t teletext_lines; double preroll; int duplex_mode; @@ -153,16 +155,14 @@ struct decklink_ctx { typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t; -#ifdef _WIN32 -#if BLACKMAGIC_DECKLINK_API_VERSION < 0x0a040000 -typedef unsigned long buffercount_type; -#else -typedef unsigned int buffercount_type; -#endif -IDeckLinkIterator *CreateDeckLinkIteratorInstance(void); -#else -typedef uint32_t buffercount_type; -#endif +static const BMDPixelFormat decklink_raw_format_map[] = { + (BMDPixelFormat)0, + bmdFormat8BitYUV, + bmdFormat10BitYUV, + bmdFormat8BitARGB, + bmdFormat8BitBGRA, + bmdFormat10BitRGB, +}; static const BMDAudioConnection decklink_audio_connection_map[] = { (BMDAudioConnection)0, @@ -193,6 +193,11 @@ static const BMDTimecodeFormat decklink_timecode_format_map[] = { bmdTimecodeVITC, bmdTimecodeVITCField2, bmdTimecodeSerial, +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 + bmdTimecodeRP188HighFrameRate, +#else + (BMDTimecodeFormat)0, +#endif }; int ff_decklink_set_configs(AVFormatContext *avctx, decklink_direction_t direction); diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index 88b1eae18..68978fa85 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -23,6 +23,8 @@ #ifndef AVDEVICE_DECKLINK_COMMON_C_H #define AVDEVICE_DECKLINK_COMMON_C_H +#include + typedef enum DecklinkPtsSource { PTS_SRC_AUDIO = 1, PTS_SRC_VIDEO = 2, @@ -40,6 +42,7 @@ struct decklink_cctx { /* Options */ int list_devices; int list_formats; + int enable_klv; int64_t teletext_lines; double preroll; int audio_channels; diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 82106aa69..79d96cd62 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -22,6 +22,7 @@ */ #include +#include using std::atomic; /* Include internal.h first to avoid conflict between winsock.h (used by @@ -34,13 +35,16 @@ extern "C" { extern "C" { #include "config.h" +#include "libavcodec/packet_internal.h" #include "libavformat/avformat.h" #include "libavutil/avassert.h" #include "libavutil/avutil.h" #include "libavutil/common.h" +#include "libavutil/internal.h" #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "libavutil/time.h" +#include "libavutil/timecode.h" #include "libavutil/mathematics.h" #include "libavutil/reverse.h" #include "avdevice.h" @@ -479,7 +483,7 @@ static void avpacket_queue_init(AVFormatContext *avctx, AVPacketQueue *q) static void avpacket_queue_flush(AVPacketQueue *q) { - AVPacketList *pkt, *pkt1; + PacketList *pkt, *pkt1; pthread_mutex_lock(&q->mutex); for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) { @@ -512,7 +516,7 @@ static unsigned long long avpacket_queue_size(AVPacketQueue *q) static int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt) { - AVPacketList *pkt1; + PacketList *pkt1; // Drop Packet if queue size is > maximum queue size if (avpacket_queue_size(q) > (uint64_t)q->max_q_size) { @@ -526,7 +530,7 @@ static int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt) return -1; } - pkt1 = (AVPacketList *)av_malloc(sizeof(AVPacketList)); + pkt1 = (PacketList *)av_malloc(sizeof(PacketList)); if (!pkt1) { av_packet_unref(pkt); return -1; @@ -554,7 +558,7 @@ static int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt) static int avpacket_queue_get(AVPacketQueue *q, AVPacket *pkt, int block) { - AVPacketList *pkt1; + PacketList *pkt1; int ret; pthread_mutex_lock(&q->mutex); @@ -583,6 +587,108 @@ static int avpacket_queue_get(AVPacketQueue *q, AVPacket *pkt, int block) return ret; } +static void handle_klv(AVFormatContext *avctx, decklink_ctx *ctx, IDeckLinkVideoInputFrame *videoFrame, int64_t pts) +{ + const uint8_t KLV_DID = 0x44; + const uint8_t KLV_IN_VANC_SDID = 0x04; + + struct KLVPacket + { + uint16_t sequence_counter; + std::vector data; + }; + + size_t total_size = 0; + std::vector> klv_packets(256); + + IDeckLinkVideoFrameAncillaryPackets *packets = nullptr; + if (videoFrame->QueryInterface(IID_IDeckLinkVideoFrameAncillaryPackets, (void**)&packets) != S_OK) + return; + + IDeckLinkAncillaryPacketIterator *it = nullptr; + if (packets->GetPacketIterator(&it) != S_OK) { + packets->Release(); + return; + } + + IDeckLinkAncillaryPacket *packet = nullptr; + while (it->Next(&packet) == S_OK) { + uint8_t *data = nullptr; + uint32_t size = 0; + + if (packet->GetDID() == KLV_DID && packet->GetSDID() == KLV_IN_VANC_SDID) { + av_log(avctx, AV_LOG_DEBUG, "Found KLV VANC packet on line: %d\n", packet->GetLineNumber()); + + if (packet->GetBytes(bmdAncillaryPacketFormatUInt8, (const void**) &data, &size) == S_OK) { + // MID and PSC + if (size > 3) { + uint8_t mid = data[0]; + uint16_t psc = data[1] << 8 | data[2]; + + av_log(avctx, AV_LOG_DEBUG, "KLV with MID: %d and PSC: %d\n", mid, psc); + + auto& list = klv_packets[mid]; + uint16_t expected_psc = list.size() + 1; + + if (psc == expected_psc) { + uint32_t data_len = size - 3; + total_size += data_len; + + KLVPacket packet{ psc }; + packet.data.resize(data_len); + memcpy(packet.data.data(), data + 3, data_len); + + list.push_back(std::move(packet)); + } else { + av_log(avctx, AV_LOG_WARNING, "Out of order PSC: %d for MID: %d\n", psc, mid); + + if (!list.empty()) { + for (auto& klv : list) + total_size -= klv.data.size(); + + list.clear(); + } + } + } + } + } + + packet->Release(); + } + + it->Release(); + packets->Release(); + + if (total_size > 0) { + std::vector klv; + klv.reserve(total_size); + + for (size_t i = 0; i < klv_packets.size(); ++i) { + auto& list = klv_packets[i]; + + if (list.empty()) + continue; + + av_log(avctx, AV_LOG_DEBUG, "Joining MID: %d\n", (int)i); + + for (auto& packet : list) + klv.insert(klv.end(), packet.data.begin(), packet.data.end()); + } + + AVPacket klv_packet = { 0 }; + klv_packet.pts = pts; + klv_packet.dts = pts; + klv_packet.flags |= AV_PKT_FLAG_KEY; + klv_packet.stream_index = ctx->klv_st->index; + klv_packet.data = klv.data(); + klv_packet.size = klv.size(); + + if (avpacket_queue_put(&ctx->queue, &klv_packet) < 0) { + ++ctx->dropped; + } + } +} + class decklink_input_callback : public IDeckLinkInputCallback { public: @@ -684,6 +790,52 @@ static int64_t get_pkt_pts(IDeckLinkVideoInputFrame *videoFrame, return pts; } +static int get_bmd_timecode(AVFormatContext *avctx, AVTimecode *tc, AVRational frame_rate, BMDTimecodeFormat tc_format, IDeckLinkVideoInputFrame *videoFrame) +{ + IDeckLinkTimecode *timecode; + int ret = AVERROR(ENOENT); +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 + int hfr = (tc_format == bmdTimecodeRP188HighFrameRate); +#else + int hfr = 0; +#endif + if (videoFrame->GetTimecode(tc_format, &timecode) == S_OK) { + uint8_t hh, mm, ss, ff; + if (timecode->GetComponents(&hh, &mm, &ss, &ff) == S_OK) { + int flags = (timecode->GetFlags() & bmdTimecodeIsDropFrame) ? AV_TIMECODE_FLAG_DROPFRAME : 0; + if (!hfr && av_cmp_q(frame_rate, av_make_q(30, 1)) == 1) + ff = ff << 1 | !!(timecode->GetFlags() & bmdTimecodeFieldMark); + ret = av_timecode_init_from_components(tc, frame_rate, flags, hh, mm, ss, ff, avctx); + } + timecode->Release(); + } + return ret; +} + +static int get_frame_timecode(AVFormatContext *avctx, decklink_ctx *ctx, AVTimecode *tc, IDeckLinkVideoInputFrame *videoFrame) +{ + AVRational frame_rate = ctx->video_st->r_frame_rate; + int ret; + /* 50/60 fps content has alternating VITC1 and VITC2 timecode (see SMPTE ST + * 12-2, section 7), so the native ordering of RP188Any (HFR, VITC1, LTC, + * VITC2) would not work because LTC might not contain the field flag. + * Therefore we query the types manually. */ + if (ctx->tc_format == bmdTimecodeRP188Any && av_cmp_q(frame_rate, av_make_q(30, 1)) == 1) { +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 + ret = get_bmd_timecode(avctx, tc, frame_rate, bmdTimecodeRP188HighFrameRate, videoFrame); + if (ret == AVERROR(ENOENT)) +#endif + ret = get_bmd_timecode(avctx, tc, frame_rate, bmdTimecodeRP188VITC1, videoFrame); + if (ret == AVERROR(ENOENT)) + ret = get_bmd_timecode(avctx, tc, frame_rate, bmdTimecodeRP188VITC2, videoFrame); + if (ret == AVERROR(ENOENT)) + ret = get_bmd_timecode(avctx, tc, frame_rate, bmdTimecodeRP188LTC, videoFrame); + } else { + ret = get_bmd_timecode(avctx, tc, frame_rate, ctx->tc_format, videoFrame); + } + return ret; +} + HRESULT decklink_input_callback::VideoInputFrameArrived( IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioFrame) { @@ -721,8 +873,7 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( // Handle Video Frame if (videoFrame) { - AVPacket pkt; - av_init_packet(&pkt); + AVPacket pkt = { 0 }; if (ctx->frameCount % 25 == 0) { unsigned long long qsize = avpacket_queue_size(&ctx->queue); av_log(avctx, AV_LOG_DEBUG, @@ -765,20 +916,27 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( // Handle Timecode (if requested) if (ctx->tc_format) { - IDeckLinkTimecode *timecode; - if (videoFrame->GetTimecode(ctx->tc_format, &timecode) == S_OK) { - const char *tc = NULL; - DECKLINK_STR decklink_tc; - if (timecode->GetString(&decklink_tc) == S_OK) { - tc = DECKLINK_STRDUP(decklink_tc); - DECKLINK_FREE(decklink_tc); - } - timecode->Release(); + AVTimecode tcr; + if (get_frame_timecode(avctx, ctx, &tcr, videoFrame) >= 0) { + char tcstr[AV_TIMECODE_STR_SIZE]; + const char *tc = av_timecode_make_string(&tcr, tcstr, 0); if (tc) { AVDictionary* metadata_dict = NULL; - int metadata_len; uint8_t* packed_metadata; - if (av_dict_set(&metadata_dict, "timecode", tc, AV_DICT_DONT_STRDUP_VAL) >= 0) { + + if (av_cmp_q(ctx->video_st->r_frame_rate, av_make_q(60, 1)) < 1) { + uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); + int size = sizeof(uint32_t) * 4; + uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); + + if (sd) { + *sd = 1; // one TC + *(sd + 1) = tc_data; // TC + } + } + + if (av_dict_set(&metadata_dict, "timecode", tc, 0) >= 0) { + buffer_size_t metadata_len; packed_metadata = av_packet_pack_dictionary(metadata_dict, &metadata_len); av_dict_free(&metadata_dict); if (packed_metadata) { @@ -817,19 +975,23 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( if (!no_video) { IDeckLinkVideoFrameAncillary *vanc; - AVPacket txt_pkt; + AVPacket txt_pkt = { 0 }; uint8_t txt_buf0[3531]; // 35 * 46 bytes decoded teletext lines + 1 byte data_identifier + 1920 bytes OP47 decode buffer uint8_t *txt_buf = txt_buf0; + if (ctx->enable_klv) { + handle_klv(avctx, ctx, videoFrame, pkt.pts); + } + if (videoFrame->GetAncillaryData(&vanc) == S_OK) { int i; - int64_t line_mask = 1; BMDPixelFormat vanc_format = vanc->GetPixelFormat(); txt_buf[0] = 0x10; // data_identifier - EBU_data txt_buf++; #if CONFIG_LIBZVBI if (ctx->bmd_mode == bmdModePAL && ctx->teletext_lines && (vanc_format == bmdFormat8BitYUV || vanc_format == bmdFormat10BitYUV)) { + int64_t line_mask = 1; av_assert0(videoFrame->GetWidth() == 720); for (i = 6; i < 336; i++, line_mask <<= 1) { uint8_t *buf; @@ -872,7 +1034,6 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( txt_buf[1] = 0x2c; // data_unit_length txt_buf += 46; } - av_init_packet(&txt_pkt); txt_pkt.pts = pkt.pts; txt_pkt.dts = pkt.dts; txt_pkt.stream_index = ctx->teletext_st->index; @@ -896,9 +1057,8 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( // Handle Audio Frame if (audioFrame) { - AVPacket pkt; + AVPacket pkt = { 0 }; BMDTimeValue audio_pts; - av_init_packet(&pkt); //hack among hacks pkt.size = audioFrame->GetSampleFrameCount() * ctx->audio_st->codecpar->channels * (ctx->audio_depth / 8); @@ -922,9 +1082,13 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( HRESULT decklink_input_callback::VideoInputFormatChanged( BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, - BMDDetectedVideoInputFormatFlags) + BMDDetectedVideoInputFormatFlags formatFlags) { + struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; ctx->bmd_mode = mode->GetDisplayMode(); + // check the C context member to make sure we set both raw_format and bmd_mode with data from the same format change callback + if (!cctx->raw_format) + ctx->raw_format = (formatFlags & bmdDetectedVideoInputRGB444) ? bmdFormat8BitARGB : bmdFormat8BitYUV; return S_OK; } @@ -1012,6 +1176,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) return AVERROR(ENOMEM); ctx->list_devices = cctx->list_devices; ctx->list_formats = cctx->list_formats; + ctx->enable_klv = cctx->enable_klv; ctx->teletext_lines = cctx->teletext_lines; ctx->preroll = cctx->preroll; ctx->duplex_mode = cctx->duplex_mode; @@ -1025,6 +1190,8 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) ctx->video_pts_source = cctx->video_pts_source; ctx->draw_bars = cctx->draw_bars; ctx->audio_depth = cctx->audio_depth; + if (cctx->raw_format > 0 && (unsigned int)cctx->raw_format < FF_ARRAY_ELEMS(decklink_raw_format_map)) + ctx->raw_format = decklink_raw_format_map[cctx->raw_format]; cctx->ctx = ctx; /* Check audio channel option for valid values: 2, 8 or 16 */ @@ -1050,7 +1217,6 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) /* List available devices. */ if (ctx->list_devices) { - av_log(avctx, AV_LOG_WARNING, "The -list_devices option is deprecated and will be removed. Please use ffmpeg -sources decklink instead.\n"); ff_decklink_list_devices_legacy(avctx, 1, 0); return AVERROR_EXIT; } @@ -1104,6 +1270,8 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) } av_log(avctx, AV_LOG_INFO, "Autodetected the input mode\n"); } + if (ctx->raw_format == (BMDPixelFormat)0) + ctx->raw_format = bmdFormat8BitYUV; if (ff_decklink_set_format(avctx, DIRECTION_IN) < 0) { av_log(avctx, AV_LOG_ERROR, "Could not set format code %s for %s\n", cctx->format_code ? cctx->format_code : "(unset)", avctx->url); @@ -1147,40 +1315,34 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) st->time_base.num = ctx->bmd_tb_num; st->r_frame_rate = av_make_q(st->time_base.den, st->time_base.num); - switch((BMDPixelFormat)cctx->raw_format) { + switch(ctx->raw_format) { case bmdFormat8BitYUV: st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; - st->codecpar->codec_tag = MKTAG('U', 'Y', 'V', 'Y'); st->codecpar->format = AV_PIX_FMT_UYVY422; st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 16, st->time_base.den, st->time_base.num); break; case bmdFormat10BitYUV: st->codecpar->codec_id = AV_CODEC_ID_V210; - st->codecpar->codec_tag = MKTAG('V','2','1','0'); st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 64, st->time_base.den, st->time_base.num * 3); - st->codecpar->bits_per_coded_sample = 10; break; case bmdFormat8BitARGB: st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; st->codecpar->format = AV_PIX_FMT_0RGB; - st->codecpar->codec_tag = avcodec_pix_fmt_to_codec_tag((enum AVPixelFormat)st->codecpar->format); st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 32, st->time_base.den, st->time_base.num); break; case bmdFormat8BitBGRA: st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; st->codecpar->format = AV_PIX_FMT_BGR0; - st->codecpar->codec_tag = avcodec_pix_fmt_to_codec_tag((enum AVPixelFormat)st->codecpar->format); st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 32, st->time_base.den, st->time_base.num); break; case bmdFormat10BitRGB: st->codecpar->codec_id = AV_CODEC_ID_R210; - st->codecpar->codec_tag = MKTAG('R','2','1','0'); - st->codecpar->format = AV_PIX_FMT_RGB48LE; st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 30, st->time_base.den, st->time_base.num); - st->codecpar->bits_per_coded_sample = 10; break; default: - av_log(avctx, AV_LOG_ERROR, "Raw Format %.4s not supported\n", (char*) &cctx->raw_format); + char fourcc_str[AV_FOURCC_MAX_STRING_SIZE] = {0}; + av_fourcc_make_string(fourcc_str, ctx->raw_format); + av_log(avctx, AV_LOG_ERROR, "Raw Format %s not supported\n", fourcc_str); ret = AVERROR(EINVAL); goto error; } @@ -1202,6 +1364,20 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) ctx->video_st=st; + if (ctx->enable_klv) { + st = avformat_new_stream(avctx, NULL); + if (!st) { + ret = AVERROR(ENOMEM); + goto error; + } + st->codecpar->codec_type = AVMEDIA_TYPE_DATA; + st->time_base.den = ctx->bmd_tb_den; + st->time_base.num = ctx->bmd_tb_num; + st->codecpar->codec_id = AV_CODEC_ID_SMPTE_KLV; + avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ + ctx->klv_st = st; + } + if (ctx->teletext_lines) { st = avformat_new_stream(avctx, NULL); if (!st) { @@ -1227,7 +1403,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) } result = ctx->dli->EnableVideoInput(ctx->bmd_mode, - (BMDPixelFormat) cctx->raw_format, + ctx->raw_format, bmdVideoInputFlagDefault); if (result != S_OK) { @@ -1259,7 +1435,7 @@ int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt) avpacket_queue_get(&ctx->queue, pkt, 1); if (ctx->tc_format && !(av_dict_get(ctx->video_st->metadata, "timecode", NULL, 0))) { - int size; + buffer_size_t size; const uint8_t *side_metadata = av_packet_get_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, &size); if (side_metadata) { if (av_packet_unpack_dictionary(side_metadata, size, &ctx->video_st->metadata) < 0) diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index b59876994..07b1b39f7 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -30,15 +30,17 @@ #define DEC AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { - { "list_devices", "list available devices" , OFFSET(list_devices), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, DEC }, + { "list_devices", "use ffmpeg -sources decklink instead", OFFSET(list_devices), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC | AV_OPT_FLAG_DEPRECATED}, { "list_formats", "list supported formats" , OFFSET(list_formats), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, DEC }, { "format_code", "set format by fourcc" , OFFSET(format_code), AV_OPT_TYPE_STRING, { .str = NULL}, 0, 0, DEC }, - { "raw_format", "pixel format to be returned by the card when capturing" , OFFSET(raw_format), AV_OPT_TYPE_INT, { .i64 = MKBETAG('2','v','u','y')}, 0, UINT_MAX, DEC, "raw_format" }, - { "uyvy422", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('2','v','u','y') }, 0, 0, DEC, "raw_format"}, - { "yuv422p10", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('v','2','1','0') }, 0, 0, DEC, "raw_format"}, - { "argb", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, 0, 0, DEC, "raw_format"}, - { "bgra", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('B','G','R','A') }, 0, 0, DEC, "raw_format"}, - { "rgb10", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('r','2','1','0') }, 0, 0, DEC, "raw_format"}, + { "raw_format", "pixel format to be returned by the card when capturing" , OFFSET(raw_format), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 5, DEC, "raw_format" }, + { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, DEC, "raw_format"}, + { "uyvy422", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, DEC, "raw_format"}, + { "yuv422p10", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, DEC, "raw_format"}, + { "argb", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, 0, 0, DEC, "raw_format"}, + { "bgra", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, 0, 0, DEC, "raw_format"}, + { "rgb10", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 5 }, 0, 0, DEC, "raw_format"}, + { "enable_klv", "output klv if present in vanc", OFFSET(enable_klv), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC }, { "teletext_lines", "teletext lines bitmask", OFFSET(teletext_lines), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, 0x7ffffffffLL, DEC, "teletext_lines"}, { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7fff9fffeLL}, 0, 0, DEC, "teletext_lines"}, { "all", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7ffffffffLL}, 0, 0, DEC, "teletext_lines"}, @@ -47,7 +49,7 @@ static const AVOption options[] = { { "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "duplex_mode"}, { "half", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "duplex_mode"}, { "full", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, "duplex_mode"}, - { "timecode_format", "timecode format", OFFSET(tc_format), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 7, DEC, "tc_format"}, + { "timecode_format", "timecode format", OFFSET(tc_format), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 8, DEC, "tc_format"}, { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "tc_format"}, { "rp188vitc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "tc_format"}, { "rp188vitc2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, "tc_format"}, @@ -56,6 +58,9 @@ static const AVOption options[] = { { "vitc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0, DEC, "tc_format"}, { "vitc2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 6}, 0, 0, DEC, "tc_format"}, { "serial", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 7}, 0, 0, DEC, "tc_format"}, +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 + { "rp188hfr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 8}, 0, 0, DEC, "tc_format"}, +#endif { "video_input", "video input", OFFSET(video_input), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 6, DEC, "video_input"}, { "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "video_input"}, { "sdi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "video_input"}, diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index 883fdeadf..114c3e1a8 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -32,6 +32,7 @@ extern "C" { extern "C" { #include "libavformat/avformat.h" +#include "libavutil/internal.h" #include "libavutil/imgutils.h" #include "avdevice.h" } @@ -312,7 +313,8 @@ static void construct_cc(AVFormatContext *avctx, struct decklink_ctx *ctx, uint16_t *cdp_words; uint16_t len; uint8_t cc_count; - int size, ret, i; + buffer_size_t size; + int ret, i; const uint8_t *data = av_packet_get_side_data(pkt, AV_PKT_DATA_A53_CC, &size); if (!data) @@ -436,7 +438,7 @@ static int decklink_write_video_packet(AVFormatContext *avctx, AVPacket *pkt) AVFrame *avframe = NULL, *tmp = (AVFrame *)pkt->data; AVPacket *avpacket = NULL; decklink_frame *frame; - buffercount_type buffered; + uint32_t buffered; HRESULT hr; if (st->codecpar->codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) { @@ -525,7 +527,7 @@ static int decklink_write_audio_packet(AVFormatContext *avctx, AVPacket *pkt) struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; int sample_count = pkt->size / (ctx->channels << 1); - buffercount_type buffered; + uint32_t buffered; ctx->dlo->GetBufferedAudioSampleFrameCount(&buffered); if (pkt->pts > 1 && !buffered) @@ -568,7 +570,6 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) /* List available devices and exit. */ if (ctx->list_devices) { - av_log(avctx, AV_LOG_WARNING, "The -list_devices option is deprecated and will be removed. Please use ffmpeg -sinks decklink instead.\n"); ff_decklink_list_devices_legacy(avctx, 0, 1); return AVERROR_EXIT; } diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c index 682c7147d..f09659909 100644 --- a/libavdevice/decklink_enc_c.c +++ b/libavdevice/decklink_enc_c.c @@ -28,7 +28,7 @@ #define OFFSET(x) offsetof(struct decklink_cctx, x) #define ENC AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { - { "list_devices", "list available devices" , OFFSET(list_devices), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, ENC }, + { "list_devices", "use ffmpeg -sinks decklink instead", OFFSET(list_devices), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC | AV_OPT_FLAG_DEPRECATED}, { "list_formats", "list supported formats" , OFFSET(list_formats), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, ENC }, { "preroll" , "video preroll in seconds", OFFSET(preroll ), AV_OPT_TYPE_DOUBLE, { .dbl = 0.5 }, 0, 5, ENC }, { "duplex_mode" , "duplex mode" , OFFSET(duplex_mode ), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 2, ENC, "duplex_mode"}, diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c index d7f5bd706..73a9a48b2 100644 --- a/libavdevice/dshow.c +++ b/libavdevice/dshow.c @@ -58,7 +58,7 @@ static int dshow_read_close(AVFormatContext *s) { struct dshow_ctx *ctx = s->priv_data; - AVPacketList *pktl; + PacketList *pktl; if (ctx->control) { IMediaControl_Stop(ctx->control); @@ -87,13 +87,13 @@ dshow_read_close(AVFormatContext *s) } if (ctx->capture_pin[VideoDevice]) - libAVPin_Release(ctx->capture_pin[VideoDevice]); + ff_dshow_pin_Release(ctx->capture_pin[VideoDevice]); if (ctx->capture_pin[AudioDevice]) - libAVPin_Release(ctx->capture_pin[AudioDevice]); + ff_dshow_pin_Release(ctx->capture_pin[AudioDevice]); if (ctx->capture_filter[VideoDevice]) - libAVFilter_Release(ctx->capture_filter[VideoDevice]); + ff_dshow_filter_Release(ctx->capture_filter[VideoDevice]); if (ctx->capture_filter[AudioDevice]) - libAVFilter_Release(ctx->capture_filter[AudioDevice]); + ff_dshow_filter_Release(ctx->capture_filter[AudioDevice]); if (ctx->device_pin[VideoDevice]) IPin_Release(ctx->device_pin[VideoDevice]); @@ -118,7 +118,7 @@ dshow_read_close(AVFormatContext *s) pktl = ctx->pktl; while (pktl) { - AVPacketList *next = pktl->next; + PacketList *next = pktl->next; av_packet_unref(&pktl->pkt); av_free(pktl); pktl = next; @@ -162,7 +162,7 @@ callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, e { AVFormatContext *s = priv_data; struct dshow_ctx *ctx = s->priv_data; - AVPacketList **ppktl, *pktl_next; + PacketList **ppktl, *pktl_next; // dump_videohdr(s, vdhdr); @@ -171,7 +171,7 @@ callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, e if(shall_we_drop(s, index, devtype)) goto fail; - pktl_next = av_mallocz(sizeof(AVPacketList)); + pktl_next = av_mallocz(sizeof(PacketList)); if(!pktl_next) goto fail; @@ -510,7 +510,7 @@ end: * Pops up a user dialog allowing them to adjust properties for the given filter, if possible. */ void -dshow_show_filter_properties(IBaseFilter *device_filter, AVFormatContext *avctx) { +ff_dshow_show_filter_properties(IBaseFilter *device_filter, AVFormatContext *avctx) { ISpecifyPropertyPages *property_pages = NULL; IUnknown *device_filter_iunknown = NULL; HRESULT hr; @@ -582,7 +582,7 @@ dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype, int should_show_properties = (devtype == VideoDevice) ? ctx->show_video_device_dialog : ctx->show_audio_device_dialog; if (should_show_properties) - dshow_show_filter_properties(device_filter, avctx); + ff_dshow_show_filter_properties(device_filter, avctx); r = IBaseFilter_EnumPins(device_filter, &pins); if (r != S_OK) { @@ -731,8 +731,8 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, char *device_filter_unique_name = NULL; IGraphBuilder *graph = ctx->graph; IPin *device_pin = NULL; - libAVPin *capture_pin = NULL; - libAVFilter *capture_filter = NULL; + DShowPin *capture_pin = NULL; + DShowFilter *capture_filter = NULL; ICaptureGraphBuilder2 *graph_builder2 = NULL; int ret = AVERROR(EIO); int r; @@ -807,7 +807,7 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, ctx->device_pin[devtype] = device_pin; - capture_filter = libAVFilter_Create(avctx, callback, devtype); + capture_filter = ff_dshow_filter_Create(avctx, callback, devtype); if (!capture_filter) { av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n"); goto error; @@ -863,7 +863,7 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, goto error; } - libAVPin_AddRef(capture_filter->pin); + ff_dshow_pin_AddRef(capture_filter->pin); capture_pin = capture_filter->pin; ctx->capture_pin[devtype] = capture_pin; @@ -887,7 +887,7 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, goto error; } - r = dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx); + r = ff_dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n"); @@ -953,7 +953,7 @@ dshow_add_device(AVFormatContext *avctx, ctx->capture_filter[devtype]->stream_index = st->index; - libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type); + ff_dshow_pin_ConnectionMediaType(ctx->capture_pin[devtype], &type); par = st->codecpar; if (devtype == VideoDevice) { @@ -1262,7 +1262,7 @@ static int dshow_check_event_queue(IMediaEvent *media_event) static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt) { struct dshow_ctx *ctx = s->priv_data; - AVPacketList *pktl = NULL; + PacketList *pktl = NULL; while (!ctx->eof && !pktl) { WaitForSingleObject(ctx->mutex, INFINITE); diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h index 475d62ba9..06ded2ba9 100644 --- a/libavdevice/dshow_capture.h +++ b/libavdevice/dshow_capture.h @@ -34,6 +34,7 @@ #include #include "libavcodec/internal.h" +#include "libavcodec/packet_internal.h" /* EC_DEVICE_LOST is not defined in MinGW dshow headers. */ #ifndef EC_DEVICE_LOST @@ -68,20 +69,20 @@ enum dshowSourceFilterType { AudioSourceDevice = 1, }; -#define DECLARE_QUERYINTERFACE(class, ...) \ -long WINAPI \ -class##_QueryInterface(class *this, const GUID *riid, void **ppvObject) \ +#define DECLARE_QUERYINTERFACE(prefix, class, ...) \ +long \ +ff_dshow_##prefix##_QueryInterface(class *this, const GUID *riid, void **ppvObject) \ { \ struct GUIDoffset ifaces[] = __VA_ARGS__; \ int i; \ - dshowdebug(AV_STRINGIFY(class)"_QueryInterface(%p, %p, %p)\n", this, riid, ppvObject); \ + dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_QueryInterface(%p, %p, %p)\n", this, riid, ppvObject); \ ff_printGUID(riid); \ if (!ppvObject) \ return E_POINTER; \ for (i = 0; i < sizeof(ifaces)/sizeof(ifaces[0]); i++) { \ if (IsEqualGUID(riid, ifaces[i].iid)) { \ void *obj = (void *) ((uint8_t *) this + ifaces[i].offset); \ - class##_AddRef(this); \ + ff_dshow_##prefix##_AddRef(this); \ dshowdebug("\tfound %d with offset %d\n", i, ifaces[i].offset); \ *ppvObject = (void *) obj; \ return S_OK; \ @@ -91,28 +92,28 @@ class##_QueryInterface(class *this, const GUID *riid, void **ppvObject) \ *ppvObject = NULL; \ return E_NOINTERFACE; \ } -#define DECLARE_ADDREF(class) \ -unsigned long WINAPI \ -class##_AddRef(class *this) \ +#define DECLARE_ADDREF(prefix, class) \ +unsigned long \ +ff_dshow_##prefix##_AddRef(class *this) \ { \ - dshowdebug(AV_STRINGIFY(class)"_AddRef(%p)\t%ld\n", this, this->ref+1); \ + dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_AddRef(%p)\t%ld\n", this, this->ref+1); \ return InterlockedIncrement(&this->ref); \ } -#define DECLARE_RELEASE(class) \ -unsigned long WINAPI \ -class##_Release(class *this) \ +#define DECLARE_RELEASE(prefix, class) \ +unsigned long \ +ff_dshow_##prefix##_Release(class *this) \ { \ long ref = InterlockedDecrement(&this->ref); \ - dshowdebug(AV_STRINGIFY(class)"_Release(%p)\t%ld\n", this, ref); \ + dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_Release(%p)\t%ld\n", this, ref); \ if (!ref) \ - class##_Destroy(this); \ + ff_dshow_##prefix##_Destroy(this); \ return ref; \ } -#define DECLARE_DESTROY(class, func) \ -void class##_Destroy(class *this) \ +#define DECLARE_DESTROY(prefix, class, func) \ +void ff_dshow_##prefix##_Destroy(class *this) \ { \ - dshowdebug(AV_STRINGIFY(class)"_Destroy(%p)\n", this); \ + dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_Destroy(%p)\n", this); \ func(this); \ if (this) { \ if (this->vtbl) \ @@ -120,12 +121,12 @@ void class##_Destroy(class *this) \ CoTaskMemFree(this); \ } \ } -#define DECLARE_CREATE(class, setup, ...) \ -class *class##_Create(__VA_ARGS__) \ +#define DECLARE_CREATE(prefix, class, setup, ...) \ +class *ff_dshow_##prefix##_Create(__VA_ARGS__) \ { \ class *this = CoTaskMemAlloc(sizeof(class)); \ void *vtbl = CoTaskMemAlloc(sizeof(*this->vtbl)); \ - dshowdebug(AV_STRINGIFY(class)"_Create(%p)\n", this); \ + dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_Create(%p)\n", this); \ if (!this || !vtbl) \ goto fail; \ ZeroMemory(this, sizeof(class)); \ @@ -134,123 +135,123 @@ class *class##_Create(__VA_ARGS__) \ this->vtbl = vtbl; \ if (!setup) \ goto fail; \ - dshowdebug("created "AV_STRINGIFY(class)" %p\n", this); \ + dshowdebug("created ff_dshow_"AV_STRINGIFY(prefix)" %p\n", this); \ return this; \ fail: \ - class##_Destroy(this); \ - dshowdebug("could not create "AV_STRINGIFY(class)"\n"); \ + ff_dshow_##prefix##_Destroy(this); \ + dshowdebug("could not create ff_dshow_"AV_STRINGIFY(prefix)"\n"); \ return NULL; \ } -#define SETVTBL(vtbl, class, fn) \ - do { (vtbl)->fn = (void *) class##_##fn; } while(0) +#define SETVTBL(vtbl, prefix, fn) \ + do { (vtbl)->fn = (void *) ff_dshow_##prefix##_##fn; } while(0) /***************************************************************************** * Forward Declarations ****************************************************************************/ -typedef struct libAVPin libAVPin; -typedef struct libAVMemInputPin libAVMemInputPin; -typedef struct libAVEnumPins libAVEnumPins; -typedef struct libAVEnumMediaTypes libAVEnumMediaTypes; -typedef struct libAVFilter libAVFilter; +typedef struct DShowPin DShowPin; +typedef struct DShowMemInputPin DShowMemInputPin; +typedef struct DShowEnumPins DShowEnumPins; +typedef struct DShowEnumMediaTypes DShowEnumMediaTypes; +typedef struct DShowFilter DShowFilter; /***************************************************************************** - * libAVPin + * DShowPin ****************************************************************************/ -struct libAVPin { +struct DShowPin { IPinVtbl *vtbl; long ref; - libAVFilter *filter; + DShowFilter *filter; IPin *connectedto; AM_MEDIA_TYPE type; IMemInputPinVtbl *imemvtbl; }; -long WINAPI libAVPin_QueryInterface (libAVPin *, const GUID *, void **); -unsigned long WINAPI libAVPin_AddRef (libAVPin *); -unsigned long WINAPI libAVPin_Release (libAVPin *); -long WINAPI libAVPin_Connect (libAVPin *, IPin *, const AM_MEDIA_TYPE *); -long WINAPI libAVPin_ReceiveConnection (libAVPin *, IPin *, const AM_MEDIA_TYPE *); -long WINAPI libAVPin_Disconnect (libAVPin *); -long WINAPI libAVPin_ConnectedTo (libAVPin *, IPin **); -long WINAPI libAVPin_ConnectionMediaType (libAVPin *, AM_MEDIA_TYPE *); -long WINAPI libAVPin_QueryPinInfo (libAVPin *, PIN_INFO *); -long WINAPI libAVPin_QueryDirection (libAVPin *, PIN_DIRECTION *); -long WINAPI libAVPin_QueryId (libAVPin *, wchar_t **); -long WINAPI libAVPin_QueryAccept (libAVPin *, const AM_MEDIA_TYPE *); -long WINAPI libAVPin_EnumMediaTypes (libAVPin *, IEnumMediaTypes **); -long WINAPI libAVPin_QueryInternalConnections(libAVPin *, IPin **, unsigned long *); -long WINAPI libAVPin_EndOfStream (libAVPin *); -long WINAPI libAVPin_BeginFlush (libAVPin *); -long WINAPI libAVPin_EndFlush (libAVPin *); -long WINAPI libAVPin_NewSegment (libAVPin *, REFERENCE_TIME, REFERENCE_TIME, double); +long ff_dshow_pin_QueryInterface (DShowPin *, const GUID *, void **); +unsigned long ff_dshow_pin_AddRef (DShowPin *); +unsigned long ff_dshow_pin_Release (DShowPin *); +long ff_dshow_pin_Connect (DShowPin *, IPin *, const AM_MEDIA_TYPE *); +long ff_dshow_pin_ReceiveConnection (DShowPin *, IPin *, const AM_MEDIA_TYPE *); +long ff_dshow_pin_Disconnect (DShowPin *); +long ff_dshow_pin_ConnectedTo (DShowPin *, IPin **); +long ff_dshow_pin_ConnectionMediaType (DShowPin *, AM_MEDIA_TYPE *); +long ff_dshow_pin_QueryPinInfo (DShowPin *, PIN_INFO *); +long ff_dshow_pin_QueryDirection (DShowPin *, PIN_DIRECTION *); +long ff_dshow_pin_QueryId (DShowPin *, wchar_t **); +long ff_dshow_pin_QueryAccept (DShowPin *, const AM_MEDIA_TYPE *); +long ff_dshow_pin_EnumMediaTypes (DShowPin *, IEnumMediaTypes **); +long ff_dshow_pin_QueryInternalConnections(DShowPin *, IPin **, unsigned long *); +long ff_dshow_pin_EndOfStream (DShowPin *); +long ff_dshow_pin_BeginFlush (DShowPin *); +long ff_dshow_pin_EndFlush (DShowPin *); +long ff_dshow_pin_NewSegment (DShowPin *, REFERENCE_TIME, REFERENCE_TIME, double); -long WINAPI libAVMemInputPin_QueryInterface (libAVMemInputPin *, const GUID *, void **); -unsigned long WINAPI libAVMemInputPin_AddRef (libAVMemInputPin *); -unsigned long WINAPI libAVMemInputPin_Release (libAVMemInputPin *); -long WINAPI libAVMemInputPin_GetAllocator (libAVMemInputPin *, IMemAllocator **); -long WINAPI libAVMemInputPin_NotifyAllocator (libAVMemInputPin *, IMemAllocator *, BOOL); -long WINAPI libAVMemInputPin_GetAllocatorRequirements(libAVMemInputPin *, ALLOCATOR_PROPERTIES *); -long WINAPI libAVMemInputPin_Receive (libAVMemInputPin *, IMediaSample *); -long WINAPI libAVMemInputPin_ReceiveMultiple (libAVMemInputPin *, IMediaSample **, long, long *); -long WINAPI libAVMemInputPin_ReceiveCanBlock (libAVMemInputPin *); +long ff_dshow_meminputpin_QueryInterface (DShowMemInputPin *, const GUID *, void **); +unsigned long ff_dshow_meminputpin_AddRef (DShowMemInputPin *); +unsigned long ff_dshow_meminputpin_Release (DShowMemInputPin *); +long ff_dshow_meminputpin_GetAllocator (DShowMemInputPin *, IMemAllocator **); +long ff_dshow_meminputpin_NotifyAllocator (DShowMemInputPin *, IMemAllocator *, BOOL); +long ff_dshow_meminputpin_GetAllocatorRequirements(DShowMemInputPin *, ALLOCATOR_PROPERTIES *); +long ff_dshow_meminputpin_Receive (DShowMemInputPin *, IMediaSample *); +long ff_dshow_meminputpin_ReceiveMultiple (DShowMemInputPin *, IMediaSample **, long, long *); +long ff_dshow_meminputpin_ReceiveCanBlock (DShowMemInputPin *); -void libAVPin_Destroy(libAVPin *); -libAVPin *libAVPin_Create (libAVFilter *filter); +void ff_dshow_pin_Destroy(DShowPin *); +DShowPin *ff_dshow_pin_Create (DShowFilter *filter); -void libAVMemInputPin_Destroy(libAVMemInputPin *); +void ff_dshow_meminputpin_Destroy(DShowMemInputPin *); /***************************************************************************** - * libAVEnumPins + * DShowEnumPins ****************************************************************************/ -struct libAVEnumPins { +struct DShowEnumPins { IEnumPinsVtbl *vtbl; long ref; int pos; - libAVPin *pin; - libAVFilter *filter; + DShowPin *pin; + DShowFilter *filter; }; -long WINAPI libAVEnumPins_QueryInterface(libAVEnumPins *, const GUID *, void **); -unsigned long WINAPI libAVEnumPins_AddRef (libAVEnumPins *); -unsigned long WINAPI libAVEnumPins_Release (libAVEnumPins *); -long WINAPI libAVEnumPins_Next (libAVEnumPins *, unsigned long, IPin **, unsigned long *); -long WINAPI libAVEnumPins_Skip (libAVEnumPins *, unsigned long); -long WINAPI libAVEnumPins_Reset (libAVEnumPins *); -long WINAPI libAVEnumPins_Clone (libAVEnumPins *, libAVEnumPins **); +long ff_dshow_enumpins_QueryInterface(DShowEnumPins *, const GUID *, void **); +unsigned long ff_dshow_enumpins_AddRef (DShowEnumPins *); +unsigned long ff_dshow_enumpins_Release (DShowEnumPins *); +long ff_dshow_enumpins_Next (DShowEnumPins *, unsigned long, IPin **, unsigned long *); +long ff_dshow_enumpins_Skip (DShowEnumPins *, unsigned long); +long ff_dshow_enumpins_Reset (DShowEnumPins *); +long ff_dshow_enumpins_Clone (DShowEnumPins *, DShowEnumPins **); -void libAVEnumPins_Destroy(libAVEnumPins *); -libAVEnumPins *libAVEnumPins_Create (libAVPin *pin, libAVFilter *filter); +void ff_dshow_enumpins_Destroy(DShowEnumPins *); +DShowEnumPins *ff_dshow_enumpins_Create (DShowPin *pin, DShowFilter *filter); /***************************************************************************** - * libAVEnumMediaTypes + * DShowEnumMediaTypes ****************************************************************************/ -struct libAVEnumMediaTypes { +struct DShowEnumMediaTypes { IEnumMediaTypesVtbl *vtbl; long ref; int pos; AM_MEDIA_TYPE type; }; -long WINAPI libAVEnumMediaTypes_QueryInterface(libAVEnumMediaTypes *, const GUID *, void **); -unsigned long WINAPI libAVEnumMediaTypes_AddRef (libAVEnumMediaTypes *); -unsigned long WINAPI libAVEnumMediaTypes_Release (libAVEnumMediaTypes *); -long WINAPI libAVEnumMediaTypes_Next (libAVEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *); -long WINAPI libAVEnumMediaTypes_Skip (libAVEnumMediaTypes *, unsigned long); -long WINAPI libAVEnumMediaTypes_Reset (libAVEnumMediaTypes *); -long WINAPI libAVEnumMediaTypes_Clone (libAVEnumMediaTypes *, libAVEnumMediaTypes **); +long ff_dshow_enummediatypes_QueryInterface(DShowEnumMediaTypes *, const GUID *, void **); +unsigned long ff_dshow_enummediatypes_AddRef (DShowEnumMediaTypes *); +unsigned long ff_dshow_enummediatypes_Release (DShowEnumMediaTypes *); +long ff_dshow_enummediatypes_Next (DShowEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *); +long ff_dshow_enummediatypes_Skip (DShowEnumMediaTypes *, unsigned long); +long ff_dshow_enummediatypes_Reset (DShowEnumMediaTypes *); +long ff_dshow_enummediatypes_Clone (DShowEnumMediaTypes *, DShowEnumMediaTypes **); -void libAVEnumMediaTypes_Destroy(libAVEnumMediaTypes *); -libAVEnumMediaTypes *libAVEnumMediaTypes_Create(const AM_MEDIA_TYPE *type); +void ff_dshow_enummediatypes_Destroy(DShowEnumMediaTypes *); +DShowEnumMediaTypes *ff_dshow_enummediatypes_Create(const AM_MEDIA_TYPE *type); /***************************************************************************** - * libAVFilter + * DShowFilter ****************************************************************************/ -struct libAVFilter { +struct DShowFilter { IBaseFilterVtbl *vtbl; long ref; const wchar_t *name; - libAVPin *pin; + DShowPin *pin; FILTER_INFO info; FILTER_STATE state; IReferenceClock *clock; @@ -261,24 +262,24 @@ struct libAVFilter { void (*callback)(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType type); }; -long WINAPI libAVFilter_QueryInterface (libAVFilter *, const GUID *, void **); -unsigned long WINAPI libAVFilter_AddRef (libAVFilter *); -unsigned long WINAPI libAVFilter_Release (libAVFilter *); -long WINAPI libAVFilter_GetClassID (libAVFilter *, CLSID *); -long WINAPI libAVFilter_Stop (libAVFilter *); -long WINAPI libAVFilter_Pause (libAVFilter *); -long WINAPI libAVFilter_Run (libAVFilter *, REFERENCE_TIME); -long WINAPI libAVFilter_GetState (libAVFilter *, DWORD, FILTER_STATE *); -long WINAPI libAVFilter_SetSyncSource (libAVFilter *, IReferenceClock *); -long WINAPI libAVFilter_GetSyncSource (libAVFilter *, IReferenceClock **); -long WINAPI libAVFilter_EnumPins (libAVFilter *, IEnumPins **); -long WINAPI libAVFilter_FindPin (libAVFilter *, const wchar_t *, IPin **); -long WINAPI libAVFilter_QueryFilterInfo(libAVFilter *, FILTER_INFO *); -long WINAPI libAVFilter_JoinFilterGraph(libAVFilter *, IFilterGraph *, const wchar_t *); -long WINAPI libAVFilter_QueryVendorInfo(libAVFilter *, wchar_t **); +long ff_dshow_filter_QueryInterface (DShowFilter *, const GUID *, void **); +unsigned long ff_dshow_filter_AddRef (DShowFilter *); +unsigned long ff_dshow_filter_Release (DShowFilter *); +long ff_dshow_filter_GetClassID (DShowFilter *, CLSID *); +long ff_dshow_filter_Stop (DShowFilter *); +long ff_dshow_filter_Pause (DShowFilter *); +long ff_dshow_filter_Run (DShowFilter *, REFERENCE_TIME); +long ff_dshow_filter_GetState (DShowFilter *, DWORD, FILTER_STATE *); +long ff_dshow_filter_SetSyncSource (DShowFilter *, IReferenceClock *); +long ff_dshow_filter_GetSyncSource (DShowFilter *, IReferenceClock **); +long ff_dshow_filter_EnumPins (DShowFilter *, IEnumPins **); +long ff_dshow_filter_FindPin (DShowFilter *, const wchar_t *, IPin **); +long ff_dshow_filter_QueryFilterInfo(DShowFilter *, FILTER_INFO *); +long ff_dshow_filter_JoinFilterGraph(DShowFilter *, IFilterGraph *, const wchar_t *); +long ff_dshow_filter_QueryVendorInfo(DShowFilter *, wchar_t **); -void libAVFilter_Destroy(libAVFilter *); -libAVFilter *libAVFilter_Create (void *, void *, enum dshowDeviceType); +void ff_dshow_filter_Destroy(DShowFilter *); +DShowFilter *ff_dshow_filter_Create (void *, void *, enum dshowDeviceType); /***************************************************************************** * dshow_ctx @@ -314,13 +315,13 @@ struct dshow_ctx { IBaseFilter *device_filter[2]; IPin *device_pin[2]; - libAVFilter *capture_filter[2]; - libAVPin *capture_pin[2]; + DShowFilter *capture_filter[2]; + DShowPin *capture_pin[2]; HANDLE mutex; HANDLE event[2]; /* event[0] is set by DirectShow * event[1] is set by callback() */ - AVPacketList *pktl; + PacketList *pktl; int eof; @@ -346,9 +347,9 @@ struct dshow_ctx { /***************************************************************************** * CrossBar ****************************************************************************/ -HRESULT dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, +HRESULT ff_dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, IBaseFilter *device_filter, enum dshowDeviceType devtype, AVFormatContext *avctx); -void dshow_show_filter_properties(IBaseFilter *pFilter, AVFormatContext *avctx); +void ff_dshow_show_filter_properties(IBaseFilter *pFilter, AVFormatContext *avctx); #endif /* AVDEVICE_DSHOW_CAPTURE_H */ diff --git a/libavdevice/dshow_crossbar.c b/libavdevice/dshow_crossbar.c index 95fb466f4..2438683cd 100644 --- a/libavdevice/dshow_crossbar.c +++ b/libavdevice/dshow_crossbar.c @@ -137,7 +137,7 @@ setup_crossbar_options(IAMCrossbar *cross_bar, enum dshowDeviceType devtype, AVF * Given a fully constructed graph, check if there is a cross bar filter, and configure its pins if so. */ HRESULT -dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, +ff_dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, IBaseFilter *device_filter, enum dshowDeviceType devtype, AVFormatContext *avctx) { struct dshow_ctx *ctx = avctx->priv_data; @@ -163,7 +163,7 @@ dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, hr = IAMCrossbar_QueryInterface(cross_bar, &IID_IBaseFilter, (void **) &cross_bar_base_filter); if (hr != S_OK) goto end; - dshow_show_filter_properties(cross_bar_base_filter, avctx); + ff_dshow_show_filter_properties(cross_bar_base_filter, avctx); } if (devtype == VideoDevice && ctx->show_analog_tv_tuner_dialog) { @@ -173,7 +173,7 @@ dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, hr = IAMCrossbar_QueryInterface(tv_tuner_filter, &IID_IBaseFilter, (void **) &tv_tuner_base_filter); if (hr != S_OK) goto end; - dshow_show_filter_properties(tv_tuner_base_filter, avctx); + ff_dshow_show_filter_properties(tv_tuner_base_filter, avctx); } else { av_log(avctx, AV_LOG_WARNING, "unable to find a tv tuner to display dialog for!"); } @@ -185,7 +185,7 @@ dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 *graph_builder2, hr = IAMCrossbar_QueryInterface(tv_audio_filter, &IID_IBaseFilter, (void **) &tv_audio_base_filter); if (hr != S_OK) goto end; - dshow_show_filter_properties(tv_audio_base_filter, avctx); + ff_dshow_show_filter_properties(tv_audio_base_filter, avctx); } else { av_log(avctx, AV_LOG_WARNING, "unable to find a tv audio tuner to display dialog for!"); } diff --git a/libavdevice/dshow_enummediatypes.c b/libavdevice/dshow_enummediatypes.c index 3a66a4de1..82944507f 100644 --- a/libavdevice/dshow_enummediatypes.c +++ b/libavdevice/dshow_enummediatypes.c @@ -21,17 +21,16 @@ #include "dshow_capture.h" -DECLARE_QUERYINTERFACE(libAVEnumMediaTypes, +DECLARE_QUERYINTERFACE(enummediatypes, DShowEnumMediaTypes, { {&IID_IUnknown,0}, {&IID_IEnumMediaTypes,0} }) -DECLARE_ADDREF(libAVEnumMediaTypes) -DECLARE_RELEASE(libAVEnumMediaTypes) +DECLARE_ADDREF(enummediatypes, DShowEnumMediaTypes) +DECLARE_RELEASE(enummediatypes, DShowEnumMediaTypes) -long WINAPI -libAVEnumMediaTypes_Next(libAVEnumMediaTypes *this, unsigned long n, +long ff_dshow_enummediatypes_Next(DShowEnumMediaTypes *this, unsigned long n, AM_MEDIA_TYPE **types, unsigned long *fetched) { int count = 0; - dshowdebug("libAVEnumMediaTypes_Next(%p)\n", this); + dshowdebug("ff_dshow_enummediatypes_Next(%p)\n", this); if (!types) return E_POINTER; if (!this->pos && n == 1) { @@ -51,29 +50,26 @@ libAVEnumMediaTypes_Next(libAVEnumMediaTypes *this, unsigned long n, return S_FALSE; return S_OK; } -long WINAPI -libAVEnumMediaTypes_Skip(libAVEnumMediaTypes *this, unsigned long n) +long ff_dshow_enummediatypes_Skip(DShowEnumMediaTypes *this, unsigned long n) { - dshowdebug("libAVEnumMediaTypes_Skip(%p)\n", this); + dshowdebug("ff_dshow_enummediatypes_Skip(%p)\n", this); if (n) /* Any skip will always fall outside of the only valid type. */ return S_FALSE; return S_OK; } -long WINAPI -libAVEnumMediaTypes_Reset(libAVEnumMediaTypes *this) +long ff_dshow_enummediatypes_Reset(DShowEnumMediaTypes *this) { - dshowdebug("libAVEnumMediaTypes_Reset(%p)\n", this); + dshowdebug("ff_dshow_enummediatypes_Reset(%p)\n", this); this->pos = 0; return S_OK; } -long WINAPI -libAVEnumMediaTypes_Clone(libAVEnumMediaTypes *this, libAVEnumMediaTypes **enums) +long ff_dshow_enummediatypes_Clone(DShowEnumMediaTypes *this, DShowEnumMediaTypes **enums) { - libAVEnumMediaTypes *new; - dshowdebug("libAVEnumMediaTypes_Clone(%p)\n", this); + DShowEnumMediaTypes *new; + dshowdebug("ff_dshow_enummediatypes_Clone(%p)\n", this); if (!enums) return E_POINTER; - new = libAVEnumMediaTypes_Create(&this->type); + new = ff_dshow_enummediatypes_Create(&this->type); if (!new) return E_OUTOFMEMORY; new->pos = this->pos; @@ -81,17 +77,16 @@ libAVEnumMediaTypes_Clone(libAVEnumMediaTypes *this, libAVEnumMediaTypes **enums return S_OK; } -static int -libAVEnumMediaTypes_Setup(libAVEnumMediaTypes *this, const AM_MEDIA_TYPE *type) +static int ff_dshow_enummediatypes_Setup(DShowEnumMediaTypes *this, const AM_MEDIA_TYPE *type) { IEnumMediaTypesVtbl *vtbl = this->vtbl; - SETVTBL(vtbl, libAVEnumMediaTypes, QueryInterface); - SETVTBL(vtbl, libAVEnumMediaTypes, AddRef); - SETVTBL(vtbl, libAVEnumMediaTypes, Release); - SETVTBL(vtbl, libAVEnumMediaTypes, Next); - SETVTBL(vtbl, libAVEnumMediaTypes, Skip); - SETVTBL(vtbl, libAVEnumMediaTypes, Reset); - SETVTBL(vtbl, libAVEnumMediaTypes, Clone); + SETVTBL(vtbl, enummediatypes, QueryInterface); + SETVTBL(vtbl, enummediatypes, AddRef); + SETVTBL(vtbl, enummediatypes, Release); + SETVTBL(vtbl, enummediatypes, Next); + SETVTBL(vtbl, enummediatypes, Skip); + SETVTBL(vtbl, enummediatypes, Reset); + SETVTBL(vtbl, enummediatypes, Clone); if (!type) { this->type.majortype = GUID_NULL; @@ -101,5 +96,5 @@ libAVEnumMediaTypes_Setup(libAVEnumMediaTypes *this, const AM_MEDIA_TYPE *type) return 1; } -DECLARE_CREATE(libAVEnumMediaTypes, libAVEnumMediaTypes_Setup(this, type), const AM_MEDIA_TYPE *type) -DECLARE_DESTROY(libAVEnumMediaTypes, nothing) +DECLARE_CREATE(enummediatypes, DShowEnumMediaTypes, ff_dshow_enummediatypes_Setup(this, type), const AM_MEDIA_TYPE *type) +DECLARE_DESTROY(enummediatypes, DShowEnumMediaTypes, nothing) diff --git a/libavdevice/dshow_enumpins.c b/libavdevice/dshow_enumpins.c index e5c11cb54..6bf59928f 100644 --- a/libavdevice/dshow_enumpins.c +++ b/libavdevice/dshow_enumpins.c @@ -21,21 +21,20 @@ #include "dshow_capture.h" -DECLARE_QUERYINTERFACE(libAVEnumPins, +DECLARE_QUERYINTERFACE(enumpins, DShowEnumPins, { {&IID_IUnknown,0}, {&IID_IEnumPins,0} }) -DECLARE_ADDREF(libAVEnumPins) -DECLARE_RELEASE(libAVEnumPins) +DECLARE_ADDREF(enumpins, DShowEnumPins) +DECLARE_RELEASE(enumpins, DShowEnumPins) -long WINAPI -libAVEnumPins_Next(libAVEnumPins *this, unsigned long n, IPin **pins, +long ff_dshow_enumpins_Next(DShowEnumPins *this, unsigned long n, IPin **pins, unsigned long *fetched) { int count = 0; - dshowdebug("libAVEnumPins_Next(%p)\n", this); + dshowdebug("ff_dshow_enumpins_Next(%p)\n", this); if (!pins) return E_POINTER; if (!this->pos && n == 1) { - libAVPin_AddRef(this->pin); + ff_dshow_pin_AddRef(this->pin); *pins = (IPin *) this->pin; count = 1; this->pos = 1; @@ -46,29 +45,26 @@ libAVEnumPins_Next(libAVEnumPins *this, unsigned long n, IPin **pins, return S_FALSE; return S_OK; } -long WINAPI -libAVEnumPins_Skip(libAVEnumPins *this, unsigned long n) +long ff_dshow_enumpins_Skip(DShowEnumPins *this, unsigned long n) { - dshowdebug("libAVEnumPins_Skip(%p)\n", this); + dshowdebug("ff_dshow_enumpins_Skip(%p)\n", this); if (n) /* Any skip will always fall outside of the only valid pin. */ return S_FALSE; return S_OK; } -long WINAPI -libAVEnumPins_Reset(libAVEnumPins *this) +long ff_dshow_enumpins_Reset(DShowEnumPins *this) { - dshowdebug("libAVEnumPins_Reset(%p)\n", this); + dshowdebug("ff_dshow_enumpins_Reset(%p)\n", this); this->pos = 0; return S_OK; } -long WINAPI -libAVEnumPins_Clone(libAVEnumPins *this, libAVEnumPins **pins) +long ff_dshow_enumpins_Clone(DShowEnumPins *this, DShowEnumPins **pins) { - libAVEnumPins *new; - dshowdebug("libAVEnumPins_Clone(%p)\n", this); + DShowEnumPins *new; + dshowdebug("ff_dshow_enumpins_Clone(%p)\n", this); if (!pins) return E_POINTER; - new = libAVEnumPins_Create(this->pin, this->filter); + new = ff_dshow_enumpins_Create(this->pin, this->filter); if (!new) return E_OUTOFMEMORY; new->pos = this->pos; @@ -76,30 +72,28 @@ libAVEnumPins_Clone(libAVEnumPins *this, libAVEnumPins **pins) return S_OK; } -static int -libAVEnumPins_Setup(libAVEnumPins *this, libAVPin *pin, libAVFilter *filter) +static int ff_dshow_enumpins_Setup(DShowEnumPins *this, DShowPin *pin, DShowFilter *filter) { IEnumPinsVtbl *vtbl = this->vtbl; - SETVTBL(vtbl, libAVEnumPins, QueryInterface); - SETVTBL(vtbl, libAVEnumPins, AddRef); - SETVTBL(vtbl, libAVEnumPins, Release); - SETVTBL(vtbl, libAVEnumPins, Next); - SETVTBL(vtbl, libAVEnumPins, Skip); - SETVTBL(vtbl, libAVEnumPins, Reset); - SETVTBL(vtbl, libAVEnumPins, Clone); + SETVTBL(vtbl, enumpins, QueryInterface); + SETVTBL(vtbl, enumpins, AddRef); + SETVTBL(vtbl, enumpins, Release); + SETVTBL(vtbl, enumpins, Next); + SETVTBL(vtbl, enumpins, Skip); + SETVTBL(vtbl, enumpins, Reset); + SETVTBL(vtbl, enumpins, Clone); this->pin = pin; this->filter = filter; - libAVFilter_AddRef(this->filter); + ff_dshow_filter_AddRef(this->filter); return 1; } -static int -libAVEnumPins_Cleanup(libAVEnumPins *this) +static int ff_dshow_enumpins_Cleanup(DShowEnumPins *this) { - libAVFilter_Release(this->filter); + ff_dshow_filter_Release(this->filter); return 1; } -DECLARE_CREATE(libAVEnumPins, libAVEnumPins_Setup(this, pin, filter), - libAVPin *pin, libAVFilter *filter) -DECLARE_DESTROY(libAVEnumPins, libAVEnumPins_Cleanup) +DECLARE_CREATE(enumpins, DShowEnumPins, ff_dshow_enumpins_Setup(this, pin, filter), + DShowPin *pin, DShowFilter *filter) +DECLARE_DESTROY(enumpins, DShowEnumPins, ff_dshow_enumpins_Cleanup) diff --git a/libavdevice/dshow_filter.c b/libavdevice/dshow_filter.c index db4bff60f..61e057a83 100644 --- a/libavdevice/dshow_filter.c +++ b/libavdevice/dshow_filter.c @@ -21,53 +21,47 @@ #include "dshow_capture.h" -DECLARE_QUERYINTERFACE(libAVFilter, +DECLARE_QUERYINTERFACE(filter, DShowFilter, { {&IID_IUnknown,0}, {&IID_IBaseFilter,0} }) -DECLARE_ADDREF(libAVFilter) -DECLARE_RELEASE(libAVFilter) +DECLARE_ADDREF(filter, DShowFilter) +DECLARE_RELEASE(filter, DShowFilter) -long WINAPI -libAVFilter_GetClassID(libAVFilter *this, CLSID *id) +long ff_dshow_filter_GetClassID(DShowFilter *this, CLSID *id) { - dshowdebug("libAVFilter_GetClassID(%p)\n", this); + dshowdebug("ff_dshow_filter_GetClassID(%p)\n", this); /* I'm not creating a ClassID just for this. */ return E_FAIL; } -long WINAPI -libAVFilter_Stop(libAVFilter *this) +long ff_dshow_filter_Stop(DShowFilter *this) { - dshowdebug("libAVFilter_Stop(%p)\n", this); + dshowdebug("ff_dshow_filter_Stop(%p)\n", this); this->state = State_Stopped; return S_OK; } -long WINAPI -libAVFilter_Pause(libAVFilter *this) +long ff_dshow_filter_Pause(DShowFilter *this) { - dshowdebug("libAVFilter_Pause(%p)\n", this); + dshowdebug("ff_dshow_filter_Pause(%p)\n", this); this->state = State_Paused; return S_OK; } -long WINAPI -libAVFilter_Run(libAVFilter *this, REFERENCE_TIME start) +long ff_dshow_filter_Run(DShowFilter *this, REFERENCE_TIME start) { - dshowdebug("libAVFilter_Run(%p) %"PRId64"\n", this, start); + dshowdebug("ff_dshow_filter_Run(%p) %"PRId64"\n", this, start); this->state = State_Running; this->start_time = start; return S_OK; } -long WINAPI -libAVFilter_GetState(libAVFilter *this, DWORD ms, FILTER_STATE *state) +long ff_dshow_filter_GetState(DShowFilter *this, DWORD ms, FILTER_STATE *state) { - dshowdebug("libAVFilter_GetState(%p)\n", this); + dshowdebug("ff_dshow_filter_GetState(%p)\n", this); if (!state) return E_POINTER; *state = this->state; return S_OK; } -long WINAPI -libAVFilter_SetSyncSource(libAVFilter *this, IReferenceClock *clock) +long ff_dshow_filter_SetSyncSource(DShowFilter *this, IReferenceClock *clock) { - dshowdebug("libAVFilter_SetSyncSource(%p)\n", this); + dshowdebug("ff_dshow_filter_SetSyncSource(%p)\n", this); if (this->clock != clock) { if (this->clock) @@ -79,10 +73,9 @@ libAVFilter_SetSyncSource(libAVFilter *this, IReferenceClock *clock) return S_OK; } -long WINAPI -libAVFilter_GetSyncSource(libAVFilter *this, IReferenceClock **clock) +long ff_dshow_filter_GetSyncSource(DShowFilter *this, IReferenceClock **clock) { - dshowdebug("libAVFilter_GetSyncSource(%p)\n", this); + dshowdebug("ff_dshow_filter_GetSyncSource(%p)\n", this); if (!clock) return E_POINTER; @@ -92,32 +85,30 @@ libAVFilter_GetSyncSource(libAVFilter *this, IReferenceClock **clock) return S_OK; } -long WINAPI -libAVFilter_EnumPins(libAVFilter *this, IEnumPins **enumpin) +long ff_dshow_filter_EnumPins(DShowFilter *this, IEnumPins **enumpin) { - libAVEnumPins *new; - dshowdebug("libAVFilter_EnumPins(%p)\n", this); + DShowEnumPins *new; + dshowdebug("ff_dshow_filter_EnumPins(%p)\n", this); if (!enumpin) return E_POINTER; - new = libAVEnumPins_Create(this->pin, this); + new = ff_dshow_enumpins_Create(this->pin, this); if (!new) return E_OUTOFMEMORY; *enumpin = (IEnumPins *) new; return S_OK; } -long WINAPI -libAVFilter_FindPin(libAVFilter *this, const wchar_t *id, IPin **pin) +long ff_dshow_filter_FindPin(DShowFilter *this, const wchar_t *id, IPin **pin) { - libAVPin *found = NULL; - dshowdebug("libAVFilter_FindPin(%p)\n", this); + DShowPin *found = NULL; + dshowdebug("ff_dshow_filter_FindPin(%p)\n", this); if (!id || !pin) return E_POINTER; if (!wcscmp(id, L"In")) { found = this->pin; - libAVPin_AddRef(found); + ff_dshow_pin_AddRef(found); } *pin = (IPin *) found; if (!found) @@ -125,10 +116,9 @@ libAVFilter_FindPin(libAVFilter *this, const wchar_t *id, IPin **pin) return S_OK; } -long WINAPI -libAVFilter_QueryFilterInfo(libAVFilter *this, FILTER_INFO *info) +long ff_dshow_filter_QueryFilterInfo(DShowFilter *this, FILTER_INFO *info) { - dshowdebug("libAVFilter_QueryFilterInfo(%p)\n", this); + dshowdebug("ff_dshow_filter_QueryFilterInfo(%p)\n", this); if (!info) return E_POINTER; @@ -138,11 +128,10 @@ libAVFilter_QueryFilterInfo(libAVFilter *this, FILTER_INFO *info) return S_OK; } -long WINAPI -libAVFilter_JoinFilterGraph(libAVFilter *this, IFilterGraph *graph, +long ff_dshow_filter_JoinFilterGraph(DShowFilter *this, IFilterGraph *graph, const wchar_t *name) { - dshowdebug("libAVFilter_JoinFilterGraph(%p)\n", this); + dshowdebug("ff_dshow_filter_JoinFilterGraph(%p)\n", this); this->info.pGraph = graph; if (name) @@ -150,10 +139,9 @@ libAVFilter_JoinFilterGraph(libAVFilter *this, IFilterGraph *graph, return S_OK; } -long WINAPI -libAVFilter_QueryVendorInfo(libAVFilter *this, wchar_t **info) +long ff_dshow_filter_QueryVendorInfo(DShowFilter *this, wchar_t **info) { - dshowdebug("libAVFilter_QueryVendorInfo(%p)\n", this); + dshowdebug("ff_dshow_filter_QueryVendorInfo(%p)\n", this); if (!info) return E_POINTER; @@ -161,27 +149,27 @@ libAVFilter_QueryVendorInfo(libAVFilter *this, wchar_t **info) } static int -libAVFilter_Setup(libAVFilter *this, void *priv_data, void *callback, +ff_dshow_filter_Setup(DShowFilter *this, void *priv_data, void *callback, enum dshowDeviceType type) { IBaseFilterVtbl *vtbl = this->vtbl; - SETVTBL(vtbl, libAVFilter, QueryInterface); - SETVTBL(vtbl, libAVFilter, AddRef); - SETVTBL(vtbl, libAVFilter, Release); - SETVTBL(vtbl, libAVFilter, GetClassID); - SETVTBL(vtbl, libAVFilter, Stop); - SETVTBL(vtbl, libAVFilter, Pause); - SETVTBL(vtbl, libAVFilter, Run); - SETVTBL(vtbl, libAVFilter, GetState); - SETVTBL(vtbl, libAVFilter, SetSyncSource); - SETVTBL(vtbl, libAVFilter, GetSyncSource); - SETVTBL(vtbl, libAVFilter, EnumPins); - SETVTBL(vtbl, libAVFilter, FindPin); - SETVTBL(vtbl, libAVFilter, QueryFilterInfo); - SETVTBL(vtbl, libAVFilter, JoinFilterGraph); - SETVTBL(vtbl, libAVFilter, QueryVendorInfo); + SETVTBL(vtbl, filter, QueryInterface); + SETVTBL(vtbl, filter, AddRef); + SETVTBL(vtbl, filter, Release); + SETVTBL(vtbl, filter, GetClassID); + SETVTBL(vtbl, filter, Stop); + SETVTBL(vtbl, filter, Pause); + SETVTBL(vtbl, filter, Run); + SETVTBL(vtbl, filter, GetState); + SETVTBL(vtbl, filter, SetSyncSource); + SETVTBL(vtbl, filter, GetSyncSource); + SETVTBL(vtbl, filter, EnumPins); + SETVTBL(vtbl, filter, FindPin); + SETVTBL(vtbl, filter, QueryFilterInfo); + SETVTBL(vtbl, filter, JoinFilterGraph); + SETVTBL(vtbl, filter, QueryVendorInfo); - this->pin = libAVPin_Create(this); + this->pin = ff_dshow_pin_Create(this); this->priv_data = priv_data; this->callback = callback; @@ -189,12 +177,11 @@ libAVFilter_Setup(libAVFilter *this, void *priv_data, void *callback, return 1; } -static int -libAVFilter_Cleanup(libAVFilter *this) +static int ff_dshow_filter_Cleanup(DShowFilter *this) { - libAVPin_Release(this->pin); + ff_dshow_pin_Release(this->pin); return 1; } -DECLARE_CREATE(libAVFilter, libAVFilter_Setup(this, priv_data, callback, type), +DECLARE_CREATE(filter, DShowFilter, ff_dshow_filter_Setup(this, priv_data, callback, type), void *priv_data, void *callback, enum dshowDeviceType type) -DECLARE_DESTROY(libAVFilter, libAVFilter_Cleanup) +DECLARE_DESTROY(filter, DShowFilter, ff_dshow_filter_Cleanup) diff --git a/libavdevice/dshow_pin.c b/libavdevice/dshow_pin.c index 53b1c9150..3dae405e6 100644 --- a/libavdevice/dshow_pin.c +++ b/libavdevice/dshow_pin.c @@ -22,26 +22,24 @@ #include "dshow_capture.h" #include -#define imemoffset offsetof(libAVPin, imemvtbl) +#define imemoffset offsetof(DShowPin, imemvtbl) -DECLARE_QUERYINTERFACE(libAVPin, +DECLARE_QUERYINTERFACE(pin, DShowPin, { {&IID_IUnknown,0}, {&IID_IPin,0}, {&IID_IMemInputPin,imemoffset} }) -DECLARE_ADDREF(libAVPin) -DECLARE_RELEASE(libAVPin) +DECLARE_ADDREF(pin, DShowPin) +DECLARE_RELEASE(pin, DShowPin) -long WINAPI -libAVPin_Connect(libAVPin *this, IPin *pin, const AM_MEDIA_TYPE *type) +long ff_dshow_pin_Connect(DShowPin *this, IPin *pin, const AM_MEDIA_TYPE *type) { - dshowdebug("libAVPin_Connect(%p, %p, %p)\n", this, pin, type); + dshowdebug("ff_dshow_pin_Connect(%p, %p, %p)\n", this, pin, type); /* Input pins receive connections. */ return S_FALSE; } -long WINAPI -libAVPin_ReceiveConnection(libAVPin *this, IPin *pin, +long ff_dshow_pin_ReceiveConnection(DShowPin *this, IPin *pin, const AM_MEDIA_TYPE *type) { enum dshowDeviceType devtype = this->filter->type; - dshowdebug("libAVPin_ReceiveConnection(%p)\n", this); + dshowdebug("ff_dshow_pin_ReceiveConnection(%p)\n", this); if (!pin) return E_POINTER; @@ -64,10 +62,9 @@ libAVPin_ReceiveConnection(libAVPin *this, IPin *pin, return S_OK; } -long WINAPI -libAVPin_Disconnect(libAVPin *this) +long ff_dshow_pin_Disconnect(DShowPin *this) { - dshowdebug("libAVPin_Disconnect(%p)\n", this); + dshowdebug("ff_dshow_pin_Disconnect(%p)\n", this); if (this->filter->state != State_Stopped) return VFW_E_NOT_STOPPED; @@ -78,10 +75,9 @@ libAVPin_Disconnect(libAVPin *this) return S_OK; } -long WINAPI -libAVPin_ConnectedTo(libAVPin *this, IPin **pin) +long ff_dshow_pin_ConnectedTo(DShowPin *this, IPin **pin) { - dshowdebug("libAVPin_ConnectedTo(%p)\n", this); + dshowdebug("ff_dshow_pin_ConnectedTo(%p)\n", this); if (!pin) return E_POINTER; @@ -92,10 +88,9 @@ libAVPin_ConnectedTo(libAVPin *this, IPin **pin) return S_OK; } -long WINAPI -libAVPin_ConnectionMediaType(libAVPin *this, AM_MEDIA_TYPE *type) +long ff_dshow_pin_ConnectionMediaType(DShowPin *this, AM_MEDIA_TYPE *type) { - dshowdebug("libAVPin_ConnectionMediaType(%p)\n", this); + dshowdebug("ff_dshow_pin_ConnectionMediaType(%p)\n", this); if (!type) return E_POINTER; @@ -104,16 +99,15 @@ libAVPin_ConnectionMediaType(libAVPin *this, AM_MEDIA_TYPE *type) return ff_copy_dshow_media_type(type, &this->type); } -long WINAPI -libAVPin_QueryPinInfo(libAVPin *this, PIN_INFO *info) +long ff_dshow_pin_QueryPinInfo(DShowPin *this, PIN_INFO *info) { - dshowdebug("libAVPin_QueryPinInfo(%p)\n", this); + dshowdebug("ff_dshow_pin_QueryPinInfo(%p)\n", this); if (!info) return E_POINTER; if (this->filter) - libAVFilter_AddRef(this->filter); + ff_dshow_filter_AddRef(this->filter); info->pFilter = (IBaseFilter *) this->filter; info->dir = PINDIR_INPUT; @@ -121,19 +115,17 @@ libAVPin_QueryPinInfo(libAVPin *this, PIN_INFO *info) return S_OK; } -long WINAPI -libAVPin_QueryDirection(libAVPin *this, PIN_DIRECTION *dir) +long ff_dshow_pin_QueryDirection(DShowPin *this, PIN_DIRECTION *dir) { - dshowdebug("libAVPin_QueryDirection(%p)\n", this); + dshowdebug("ff_dshow_pin_QueryDirection(%p)\n", this); if (!dir) return E_POINTER; *dir = PINDIR_INPUT; return S_OK; } -long WINAPI -libAVPin_QueryId(libAVPin *this, wchar_t **id) +long ff_dshow_pin_QueryId(DShowPin *this, wchar_t **id) { - dshowdebug("libAVPin_QueryId(%p)\n", this); + dshowdebug("ff_dshow_pin_QueryId(%p)\n", this); if (!id) return E_POINTER; @@ -142,67 +134,59 @@ libAVPin_QueryId(libAVPin *this, wchar_t **id) return S_OK; } -long WINAPI -libAVPin_QueryAccept(libAVPin *this, const AM_MEDIA_TYPE *type) +long ff_dshow_pin_QueryAccept(DShowPin *this, const AM_MEDIA_TYPE *type) { - dshowdebug("libAVPin_QueryAccept(%p)\n", this); + dshowdebug("ff_dshow_pin_QueryAccept(%p)\n", this); return S_FALSE; } -long WINAPI -libAVPin_EnumMediaTypes(libAVPin *this, IEnumMediaTypes **enumtypes) +long ff_dshow_pin_EnumMediaTypes(DShowPin *this, IEnumMediaTypes **enumtypes) { const AM_MEDIA_TYPE *type = NULL; - libAVEnumMediaTypes *new; - dshowdebug("libAVPin_EnumMediaTypes(%p)\n", this); + DShowEnumMediaTypes *new; + dshowdebug("ff_dshow_pin_EnumMediaTypes(%p)\n", this); if (!enumtypes) return E_POINTER; - new = libAVEnumMediaTypes_Create(type); + new = ff_dshow_enummediatypes_Create(type); if (!new) return E_OUTOFMEMORY; *enumtypes = (IEnumMediaTypes *) new; return S_OK; } -long WINAPI -libAVPin_QueryInternalConnections(libAVPin *this, IPin **pin, +long ff_dshow_pin_QueryInternalConnections(DShowPin *this, IPin **pin, unsigned long *npin) { - dshowdebug("libAVPin_QueryInternalConnections(%p)\n", this); + dshowdebug("ff_dshow_pin_QueryInternalConnections(%p)\n", this); return E_NOTIMPL; } -long WINAPI -libAVPin_EndOfStream(libAVPin *this) +long ff_dshow_pin_EndOfStream(DShowPin *this) { - dshowdebug("libAVPin_EndOfStream(%p)\n", this); + dshowdebug("ff_dshow_pin_EndOfStream(%p)\n", this); /* I don't care. */ return S_OK; } -long WINAPI -libAVPin_BeginFlush(libAVPin *this) +long ff_dshow_pin_BeginFlush(DShowPin *this) { - dshowdebug("libAVPin_BeginFlush(%p)\n", this); + dshowdebug("ff_dshow_pin_BeginFlush(%p)\n", this); /* I don't care. */ return S_OK; } -long WINAPI -libAVPin_EndFlush(libAVPin *this) +long ff_dshow_pin_EndFlush(DShowPin *this) { - dshowdebug("libAVPin_EndFlush(%p)\n", this); + dshowdebug("ff_dshow_pin_EndFlush(%p)\n", this); /* I don't care. */ return S_OK; } -long WINAPI -libAVPin_NewSegment(libAVPin *this, REFERENCE_TIME start, REFERENCE_TIME stop, +long ff_dshow_pin_NewSegment(DShowPin *this, REFERENCE_TIME start, REFERENCE_TIME stop, double rate) { - dshowdebug("libAVPin_NewSegment(%p)\n", this); + dshowdebug("ff_dshow_pin_NewSegment(%p)\n", this); /* I don't care. */ return S_OK; } -static int -libAVPin_Setup(libAVPin *this, libAVFilter *filter) +static int ff_dshow_pin_Setup(DShowPin *this, DShowFilter *filter) { IPinVtbl *vtbl = this->vtbl; IMemInputPinVtbl *imemvtbl; @@ -214,44 +198,43 @@ libAVPin_Setup(libAVPin *this, libAVFilter *filter) if (!imemvtbl) return 0; - SETVTBL(imemvtbl, libAVMemInputPin, QueryInterface); - SETVTBL(imemvtbl, libAVMemInputPin, AddRef); - SETVTBL(imemvtbl, libAVMemInputPin, Release); - SETVTBL(imemvtbl, libAVMemInputPin, GetAllocator); - SETVTBL(imemvtbl, libAVMemInputPin, NotifyAllocator); - SETVTBL(imemvtbl, libAVMemInputPin, GetAllocatorRequirements); - SETVTBL(imemvtbl, libAVMemInputPin, Receive); - SETVTBL(imemvtbl, libAVMemInputPin, ReceiveMultiple); - SETVTBL(imemvtbl, libAVMemInputPin, ReceiveCanBlock); + SETVTBL(imemvtbl, meminputpin, QueryInterface); + SETVTBL(imemvtbl, meminputpin, AddRef); + SETVTBL(imemvtbl, meminputpin, Release); + SETVTBL(imemvtbl, meminputpin, GetAllocator); + SETVTBL(imemvtbl, meminputpin, NotifyAllocator); + SETVTBL(imemvtbl, meminputpin, GetAllocatorRequirements); + SETVTBL(imemvtbl, meminputpin, Receive); + SETVTBL(imemvtbl, meminputpin, ReceiveMultiple); + SETVTBL(imemvtbl, meminputpin, ReceiveCanBlock); this->imemvtbl = imemvtbl; - SETVTBL(vtbl, libAVPin, QueryInterface); - SETVTBL(vtbl, libAVPin, AddRef); - SETVTBL(vtbl, libAVPin, Release); - SETVTBL(vtbl, libAVPin, Connect); - SETVTBL(vtbl, libAVPin, ReceiveConnection); - SETVTBL(vtbl, libAVPin, Disconnect); - SETVTBL(vtbl, libAVPin, ConnectedTo); - SETVTBL(vtbl, libAVPin, ConnectionMediaType); - SETVTBL(vtbl, libAVPin, QueryPinInfo); - SETVTBL(vtbl, libAVPin, QueryDirection); - SETVTBL(vtbl, libAVPin, QueryId); - SETVTBL(vtbl, libAVPin, QueryAccept); - SETVTBL(vtbl, libAVPin, EnumMediaTypes); - SETVTBL(vtbl, libAVPin, QueryInternalConnections); - SETVTBL(vtbl, libAVPin, EndOfStream); - SETVTBL(vtbl, libAVPin, BeginFlush); - SETVTBL(vtbl, libAVPin, EndFlush); - SETVTBL(vtbl, libAVPin, NewSegment); + SETVTBL(vtbl, pin, QueryInterface); + SETVTBL(vtbl, pin, AddRef); + SETVTBL(vtbl, pin, Release); + SETVTBL(vtbl, pin, Connect); + SETVTBL(vtbl, pin, ReceiveConnection); + SETVTBL(vtbl, pin, Disconnect); + SETVTBL(vtbl, pin, ConnectedTo); + SETVTBL(vtbl, pin, ConnectionMediaType); + SETVTBL(vtbl, pin, QueryPinInfo); + SETVTBL(vtbl, pin, QueryDirection); + SETVTBL(vtbl, pin, QueryId); + SETVTBL(vtbl, pin, QueryAccept); + SETVTBL(vtbl, pin, EnumMediaTypes); + SETVTBL(vtbl, pin, QueryInternalConnections); + SETVTBL(vtbl, pin, EndOfStream); + SETVTBL(vtbl, pin, BeginFlush); + SETVTBL(vtbl, pin, EndFlush); + SETVTBL(vtbl, pin, NewSegment); this->filter = filter; return 1; } -static void -libAVPin_Free(libAVPin *this) +static void ff_dshow_pin_Free(DShowPin *this) { if (!this) return; @@ -261,58 +244,51 @@ libAVPin_Free(libAVPin *this) this->type.pbFormat = NULL; } } -DECLARE_CREATE(libAVPin, libAVPin_Setup(this, filter), libAVFilter *filter) -DECLARE_DESTROY(libAVPin, libAVPin_Free) +DECLARE_CREATE(pin, DShowPin, ff_dshow_pin_Setup(this, filter), DShowFilter *filter) +DECLARE_DESTROY(pin, DShowPin, ff_dshow_pin_Free) /***************************************************************************** - * libAVMemInputPin + * DShowMemInputPin ****************************************************************************/ -long WINAPI -libAVMemInputPin_QueryInterface(libAVMemInputPin *this, const GUID *riid, +long ff_dshow_meminputpin_QueryInterface(DShowMemInputPin *this, const GUID *riid, void **ppvObject) { - libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset); - dshowdebug("libAVMemInputPin_QueryInterface(%p)\n", this); - return libAVPin_QueryInterface(pin, riid, ppvObject); + DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); + dshowdebug("ff_dshow_meminputpin_QueryInterface(%p)\n", this); + return ff_dshow_pin_QueryInterface(pin, riid, ppvObject); } -unsigned long WINAPI -libAVMemInputPin_AddRef(libAVMemInputPin *this) +unsigned long ff_dshow_meminputpin_AddRef(DShowMemInputPin *this) { - libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset); - dshowdebug("libAVMemInputPin_AddRef(%p)\n", this); - return libAVPin_AddRef(pin); + DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); + dshowdebug("ff_dshow_meminputpin_AddRef(%p)\n", this); + return ff_dshow_pin_AddRef(pin); } -unsigned long WINAPI -libAVMemInputPin_Release(libAVMemInputPin *this) +unsigned long ff_dshow_meminputpin_Release(DShowMemInputPin *this) { - libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset); - dshowdebug("libAVMemInputPin_Release(%p)\n", this); - return libAVPin_Release(pin); + DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); + dshowdebug("ff_dshow_meminputpin_Release(%p)\n", this); + return ff_dshow_pin_Release(pin); } -long WINAPI -libAVMemInputPin_GetAllocator(libAVMemInputPin *this, IMemAllocator **alloc) +long ff_dshow_meminputpin_GetAllocator(DShowMemInputPin *this, IMemAllocator **alloc) { - dshowdebug("libAVMemInputPin_GetAllocator(%p)\n", this); + dshowdebug("ff_dshow_meminputpin_GetAllocator(%p)\n", this); return VFW_E_NO_ALLOCATOR; } -long WINAPI -libAVMemInputPin_NotifyAllocator(libAVMemInputPin *this, IMemAllocator *alloc, +long ff_dshow_meminputpin_NotifyAllocator(DShowMemInputPin *this, IMemAllocator *alloc, BOOL rdwr) { - dshowdebug("libAVMemInputPin_NotifyAllocator(%p)\n", this); + dshowdebug("ff_dshow_meminputpin_NotifyAllocator(%p)\n", this); return S_OK; } -long WINAPI -libAVMemInputPin_GetAllocatorRequirements(libAVMemInputPin *this, +long ff_dshow_meminputpin_GetAllocatorRequirements(DShowMemInputPin *this, ALLOCATOR_PROPERTIES *props) { - dshowdebug("libAVMemInputPin_GetAllocatorRequirements(%p)\n", this); + dshowdebug("ff_dshow_meminputpin_GetAllocatorRequirements(%p)\n", this); return E_NOTIMPL; } -long WINAPI -libAVMemInputPin_Receive(libAVMemInputPin *this, IMediaSample *sample) +long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, IMediaSample *sample) { - libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset); + DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); enum dshowDeviceType devtype = pin->filter->type; void *priv_data; AVFormatContext *s; @@ -328,7 +304,7 @@ libAVMemInputPin_Receive(libAVMemInputPin *this, IMediaSample *sample) struct dshow_ctx *ctx; - dshowdebug("libAVMemInputPin_Receive(%p)\n", this); + dshowdebug("ff_dshow_meminputpin_Receive(%p)\n", this); if (!sample) return E_POINTER; @@ -366,31 +342,28 @@ libAVMemInputPin_Receive(libAVMemInputPin *this, IMediaSample *sample) return S_OK; } -long WINAPI -libAVMemInputPin_ReceiveMultiple(libAVMemInputPin *this, +long ff_dshow_meminputpin_ReceiveMultiple(DShowMemInputPin *this, IMediaSample **samples, long n, long *nproc) { int i; - dshowdebug("libAVMemInputPin_ReceiveMultiple(%p)\n", this); + dshowdebug("ff_dshow_meminputpin_ReceiveMultiple(%p)\n", this); for (i = 0; i < n; i++) - libAVMemInputPin_Receive(this, samples[i]); + ff_dshow_meminputpin_Receive(this, samples[i]); *nproc = n; return S_OK; } -long WINAPI -libAVMemInputPin_ReceiveCanBlock(libAVMemInputPin *this) +long ff_dshow_meminputpin_ReceiveCanBlock(DShowMemInputPin *this) { - dshowdebug("libAVMemInputPin_ReceiveCanBlock(%p)\n", this); + dshowdebug("ff_dshow_meminputpin_ReceiveCanBlock(%p)\n", this); /* I swear I will not block. */ return S_FALSE; } -void -libAVMemInputPin_Destroy(libAVMemInputPin *this) +void ff_dshow_meminputpin_Destroy(DShowMemInputPin *this) { - libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset); - dshowdebug("libAVMemInputPin_Destroy(%p)\n", this); - libAVPin_Destroy(pin); + DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); + dshowdebug("ff_dshow_meminputpin_Destroy(%p)\n", this); + ff_dshow_pin_Destroy(pin); } diff --git a/libavdevice/fbdev_dec.c b/libavdevice/fbdev_dec.c index 6a5181686..586caeef8 100644 --- a/libavdevice/fbdev_dec.c +++ b/libavdevice/fbdev_dec.c @@ -157,11 +157,11 @@ static int fbdev_read_packet(AVFormatContext *avctx, AVPacket *pkt) uint8_t *pin, *pout; if (fbdev->time_frame == AV_NOPTS_VALUE) - fbdev->time_frame = av_gettime(); + fbdev->time_frame = av_gettime_relative(); /* wait based on the frame rate */ while (1) { - curtime = av_gettime(); + curtime = av_gettime_relative(); delay = fbdev->time_frame - curtime; av_log(avctx, AV_LOG_TRACE, "time_frame:%"PRId64" curtime:%"PRId64" delay:%"PRId64"\n", @@ -186,7 +186,7 @@ static int fbdev_read_packet(AVFormatContext *avctx, AVPacket *pkt) "Error refreshing variable info: %s\n", av_err2str(AVERROR(errno))); } - pkt->pts = curtime; + pkt->pts = av_gettime(); /* compute visible data offset */ pin = fbdev->data + fbdev->bytes_per_pixel * fbdev->varinfo.xoffset + diff --git a/libavdevice/gdigrab.c b/libavdevice/gdigrab.c index f4444406f..9b2c55fe9 100644 --- a/libavdevice/gdigrab.c +++ b/libavdevice/gdigrab.c @@ -394,7 +394,7 @@ gdigrab_read_header(AVFormatContext *s1) gdigrab->header_size = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (bpp <= 8 ? (1 << bpp) : 0) * sizeof(RGBQUAD) /* palette size */; gdigrab->time_base = av_inv_q(gdigrab->framerate); - gdigrab->time_frame = av_gettime() / av_q2d(gdigrab->time_base); + gdigrab->time_frame = av_gettime_relative() / av_q2d(gdigrab->time_base); gdigrab->hwnd = hwnd; gdigrab->source_hdc = source_hdc; @@ -551,7 +551,7 @@ static int gdigrab_read_packet(AVFormatContext *s1, AVPacket *pkt) /* wait based on the frame rate */ for (;;) { - curtime = av_gettime(); + curtime = av_gettime_relative(); delay = time_frame * av_q2d(time_base) - curtime; if (delay <= 0) { if (delay < INT64_C(-1000000) * av_q2d(time_base)) { @@ -568,7 +568,7 @@ static int gdigrab_read_packet(AVFormatContext *s1, AVPacket *pkt) if (av_new_packet(pkt, file_size) < 0) return AVERROR(ENOMEM); - pkt->pts = curtime; + pkt->pts = av_gettime(); /* Blit screen grab */ if (!BitBlt(dest_hdc, 0, 0, diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c index d0de77487..6cc305b16 100644 --- a/libavdevice/kmsgrab.c +++ b/libavdevice/kmsgrab.c @@ -27,6 +27,11 @@ #include #include +// Required for compatibility when building against libdrm < 2.4.83. +#ifndef DRM_FORMAT_MOD_INVALID +#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) +#endif + #include "libavutil/hwcontext.h" #include "libavutil/hwcontext_drm.h" #include "libavutil/internal.h" @@ -45,6 +50,7 @@ typedef struct KMSGrabContext { AVBufferRef *device_ref; AVHWDeviceContext *device; AVDRMDeviceContext *hwctx; + int fb2_available; AVBufferRef *frames_ref; AVHWFramesContext *frames; @@ -68,8 +74,10 @@ typedef struct KMSGrabContext { static void kmsgrab_free_desc(void *opaque, uint8_t *data) { AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)data; + int i; - close(desc->objects[0].fd); + for (i = 0; i < desc->nb_objects; i++) + close(desc->objects[i].fd); av_free(desc); } @@ -81,70 +89,44 @@ static void kmsgrab_free_frame(void *opaque, uint8_t *data) av_frame_free(&frame); } -static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt) +static int kmsgrab_get_fb(AVFormatContext *avctx, + drmModePlane *plane, + AVDRMFrameDescriptor *desc) { KMSGrabContext *ctx = avctx->priv_data; - drmModePlane *plane; - drmModeFB *fb; - AVDRMFrameDescriptor *desc; - AVFrame *frame; - int64_t now; + drmModeFB *fb = NULL; int err, fd; - now = av_gettime(); - if (ctx->frame_last) { - int64_t delay; - while (1) { - delay = ctx->frame_last + ctx->frame_delay - now; - if (delay <= 0) - break; - av_usleep(delay); - now = av_gettime(); - } - } - ctx->frame_last = now; - - plane = drmModeGetPlane(ctx->hwctx->fd, ctx->plane_id); - if (!plane) { - av_log(avctx, AV_LOG_ERROR, "Failed to get plane " - "%"PRIu32".\n", ctx->plane_id); - return AVERROR(EIO); - } - if (!plane->fb_id) { - av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" no longer has " - "an associated framebuffer.\n", ctx->plane_id); - return AVERROR(EIO); - } - fb = drmModeGetFB(ctx->hwctx->fd, plane->fb_id); if (!fb) { + err = errno; av_log(avctx, AV_LOG_ERROR, "Failed to get framebuffer " - "%"PRIu32".\n", plane->fb_id); - return AVERROR(EIO); + "%"PRIu32": %s.\n", plane->fb_id, strerror(err)); + err = AVERROR(err); + goto fail; } if (fb->width != ctx->width || fb->height != ctx->height) { av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" framebuffer " "dimensions changed: now %"PRIu32"x%"PRIu32".\n", ctx->plane_id, fb->width, fb->height); - return AVERROR(EIO); + err = AVERROR(EIO); + goto fail; } if (!fb->handle) { av_log(avctx, AV_LOG_ERROR, "No handle set on framebuffer.\n"); - return AVERROR(EIO); + err = AVERROR(EIO); + goto fail; } err = drmPrimeHandleToFD(ctx->hwctx->fd, fb->handle, O_RDONLY, &fd); if (err < 0) { err = errno; av_log(avctx, AV_LOG_ERROR, "Failed to get PRIME fd from " - "framebuffer handle: %s.\n", strerror(errno)); - return AVERROR(err); + "framebuffer handle: %s.\n", strerror(err)); + err = AVERROR(err); + goto fail; } - desc = av_mallocz(sizeof(*desc)); - if (!desc) - return AVERROR(ENOMEM); - *desc = (AVDRMFrameDescriptor) { .nb_objects = 1, .objects[0] = { @@ -164,31 +146,206 @@ static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt) }, }; + err = 0; +fail: + drmModeFreeFB(fb); + return err; +} + +#if HAVE_LIBDRM_GETFB2 +static int kmsgrab_get_fb2(AVFormatContext *avctx, + drmModePlane *plane, + AVDRMFrameDescriptor *desc) +{ + KMSGrabContext *ctx = avctx->priv_data; + drmModeFB2 *fb; + int err, i, nb_objects; + uint64_t modifier = ctx->drm_format_modifier; + + fb = drmModeGetFB2(ctx->hwctx->fd, plane->fb_id); + if (!fb) { + err = errno; + av_log(avctx, AV_LOG_ERROR, "Failed to get framebuffer " + "%"PRIu32": %s.\n", plane->fb_id, strerror(err)); + return AVERROR(err); + } + if (fb->pixel_format != ctx->drm_format) { + av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" framebuffer " + "format changed: now %"PRIx32".\n", + ctx->plane_id, fb->pixel_format); + err = AVERROR(EIO); + goto fail; + } + if (fb->width != ctx->width || fb->height != ctx->height) { + av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" framebuffer " + "dimensions changed: now %"PRIu32"x%"PRIu32".\n", + ctx->plane_id, fb->width, fb->height); + err = AVERROR(EIO); + goto fail; + } + if (!fb->handles[0]) { + av_log(avctx, AV_LOG_ERROR, "No handle set on framebuffer.\n"); + err = AVERROR(EIO); + goto fail; + } + + if (fb->flags & DRM_MODE_FB_MODIFIERS) + modifier = fb->modifier; + + *desc = (AVDRMFrameDescriptor) { + .nb_layers = 1, + .layers[0] = { + .format = ctx->drm_format, + }, + }; + + nb_objects = 0; + for (i = 0; i < 4 && fb->handles[i]; i++) { + size_t size; + int dup = 0, j, obj; + + size = fb->offsets[i] + fb->height * fb->pitches[i]; + + for (j = 0; j < i; j++) { + if (fb->handles[i] == fb->handles[j]) { + dup = 1; + break; + } + } + if (dup) { + obj = desc->layers[0].planes[j].object_index; + + if (desc->objects[j].size < size) + desc->objects[j].size = size; + + desc->layers[0].planes[i] = (AVDRMPlaneDescriptor) { + .object_index = obj, + .offset = fb->offsets[i], + .pitch = fb->pitches[i], + }; + + } else { + int fd; + err = drmPrimeHandleToFD(ctx->hwctx->fd, fb->handles[i], + O_RDONLY, &fd); + if (err < 0) { + err = errno; + av_log(avctx, AV_LOG_ERROR, "Failed to get PRIME fd from " + "framebuffer handle: %s.\n", strerror(err)); + err = AVERROR(err); + goto fail; + } + + obj = nb_objects++; + desc->objects[obj] = (AVDRMObjectDescriptor) { + .fd = fd, + .size = size, + .format_modifier = modifier, + }; + desc->layers[0].planes[i] = (AVDRMPlaneDescriptor) { + .object_index = obj, + .offset = fb->offsets[i], + .pitch = fb->pitches[i], + }; + } + } + desc->nb_objects = nb_objects; + desc->layers[0].nb_planes = i; + + err = 0; +fail: + drmModeFreeFB2(fb); + return err; +} +#endif + +static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt) +{ + KMSGrabContext *ctx = avctx->priv_data; + drmModePlane *plane = NULL; + AVDRMFrameDescriptor *desc = NULL; + AVFrame *frame = NULL; + int64_t now; + int err; + + now = av_gettime_relative(); + if (ctx->frame_last) { + int64_t delay; + while (1) { + delay = ctx->frame_last + ctx->frame_delay - now; + if (delay <= 0) + break; + av_usleep(delay); + now = av_gettime_relative(); + } + } + ctx->frame_last = now; + now = av_gettime(); + + plane = drmModeGetPlane(ctx->hwctx->fd, ctx->plane_id); + if (!plane) { + err = errno; + av_log(avctx, AV_LOG_ERROR, "Failed to get plane " + "%"PRIu32": %s.\n", ctx->plane_id, strerror(err)); + err = AVERROR(err); + goto fail; + } + if (!plane->fb_id) { + av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" no longer has " + "an associated framebuffer.\n", ctx->plane_id); + err = AVERROR(EIO); + goto fail; + } + + desc = av_mallocz(sizeof(*desc)); + if (!desc) { + err = AVERROR(ENOMEM); + goto fail; + } + +#if HAVE_LIBDRM_GETFB2 + if (ctx->fb2_available) + err = kmsgrab_get_fb2(avctx, plane, desc); + else +#endif + err = kmsgrab_get_fb(avctx, plane, desc); + if (err < 0) + goto fail; + frame = av_frame_alloc(); - if (!frame) - return AVERROR(ENOMEM); + if (!frame) { + err = AVERROR(ENOMEM); + goto fail; + } frame->hw_frames_ctx = av_buffer_ref(ctx->frames_ref); - if (!frame->hw_frames_ctx) - return AVERROR(ENOMEM); + if (!frame->hw_frames_ctx) { + err = AVERROR(ENOMEM); + goto fail; + } frame->buf[0] = av_buffer_create((uint8_t*)desc, sizeof(*desc), &kmsgrab_free_desc, avctx, 0); - if (!frame->buf[0]) - return AVERROR(ENOMEM); + if (!frame->buf[0]) { + err = AVERROR(ENOMEM); + goto fail; + } frame->data[0] = (uint8_t*)desc; frame->format = AV_PIX_FMT_DRM_PRIME; - frame->width = fb->width; - frame->height = fb->height; + frame->width = ctx->width; + frame->height = ctx->height; - drmModeFreeFB(fb); drmModeFreePlane(plane); + plane = NULL; + desc = NULL; pkt->buf = av_buffer_create((uint8_t*)frame, sizeof(*frame), &kmsgrab_free_frame, avctx, 0); - if (!pkt->buf) - return AVERROR(ENOMEM); + if (!pkt->buf) { + err = AVERROR(ENOMEM); + goto fail; + } pkt->data = (uint8_t*)frame; pkt->size = sizeof(*frame); @@ -196,12 +353,19 @@ static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt) pkt->flags |= AV_PKT_FLAG_TRUSTED; return 0; + +fail: + drmModeFreePlane(plane); + av_freep(&desc); + av_frame_free(&frame); + return err; } static const struct { enum AVPixelFormat pixfmt; uint32_t drm_format; } kmsgrab_formats[] = { + // Monochrome. #ifdef DRM_FORMAT_R8 { AV_PIX_FMT_GRAY8, DRM_FORMAT_R8 }, #endif @@ -209,6 +373,7 @@ static const struct { { AV_PIX_FMT_GRAY16LE, DRM_FORMAT_R16 }, { AV_PIX_FMT_GRAY16BE, DRM_FORMAT_R16 | DRM_FORMAT_BIG_ENDIAN }, #endif + // <8-bit RGB. { AV_PIX_FMT_BGR8, DRM_FORMAT_BGR233 }, { AV_PIX_FMT_RGB555LE, DRM_FORMAT_XRGB1555 }, { AV_PIX_FMT_RGB555BE, DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN }, @@ -218,6 +383,7 @@ static const struct { { AV_PIX_FMT_RGB565BE, DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN }, { AV_PIX_FMT_BGR565LE, DRM_FORMAT_BGR565 }, { AV_PIX_FMT_BGR565BE, DRM_FORMAT_BGR565 | DRM_FORMAT_BIG_ENDIAN }, + // 8-bit RGB. { AV_PIX_FMT_RGB24, DRM_FORMAT_RGB888 }, { AV_PIX_FMT_BGR24, DRM_FORMAT_BGR888 }, { AV_PIX_FMT_0RGB, DRM_FORMAT_BGRX8888 }, @@ -228,6 +394,12 @@ static const struct { { AV_PIX_FMT_ABGR, DRM_FORMAT_RGBA8888 }, { AV_PIX_FMT_RGBA, DRM_FORMAT_ABGR8888 }, { AV_PIX_FMT_BGRA, DRM_FORMAT_ARGB8888 }, + // 10-bit RGB. + { AV_PIX_FMT_X2RGB10LE, DRM_FORMAT_XRGB2101010 }, + { AV_PIX_FMT_X2RGB10BE, DRM_FORMAT_XRGB2101010 | DRM_FORMAT_BIG_ENDIAN }, + // 8-bit YUV 4:2:0. + { AV_PIX_FMT_NV12, DRM_FORMAT_NV12 }, + // 8-bit YUV 4:2:2. { AV_PIX_FMT_YUYV422, DRM_FORMAT_YUYV }, { AV_PIX_FMT_YVYU422, DRM_FORMAT_YVYU }, { AV_PIX_FMT_UYVY422, DRM_FORMAT_UYVY }, @@ -239,21 +411,12 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx) drmModePlaneRes *plane_res = NULL; drmModePlane *plane = NULL; drmModeFB *fb = NULL; +#if HAVE_LIBDRM_GETFB2 + drmModeFB2 *fb2 = NULL; +#endif AVStream *stream; int err, i; - for (i = 0; i < FF_ARRAY_ELEMS(kmsgrab_formats); i++) { - if (kmsgrab_formats[i].pixfmt == ctx->format) { - ctx->drm_format = kmsgrab_formats[i].drm_format; - break; - } - } - if (i >= FF_ARRAY_ELEMS(kmsgrab_formats)) { - av_log(avctx, AV_LOG_ERROR, "Unsupported format %s.\n", - av_get_pix_fmt_name(ctx->format)); - return AVERROR(EINVAL); - } - err = av_hwdevice_ctx_create(&ctx->device_ref, AV_HWDEVICE_TYPE_DRM, ctx->device_path, NULL, 0); if (err < 0) { @@ -289,9 +452,10 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx) } else { plane_res = drmModeGetPlaneResources(ctx->hwctx->fd); if (!plane_res) { + err = errno; av_log(avctx, AV_LOG_ERROR, "Failed to get plane " - "resources: %s.\n", strerror(errno)); - err = AVERROR(EINVAL); + "resources: %s.\n", strerror(err)); + err = AVERROR(err); goto fail; } @@ -340,28 +504,119 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx) ctx->plane_id = plane->plane_id; - fb = drmModeGetFB(ctx->hwctx->fd, plane->fb_id); - if (!fb) { +#if HAVE_LIBDRM_GETFB2 + fb2 = drmModeGetFB2(ctx->hwctx->fd, plane->fb_id); + if (!fb2 && errno == ENOSYS) { + av_log(avctx, AV_LOG_INFO, "GETFB2 not supported, " + "will try to use GETFB instead.\n"); + } else if (!fb2) { err = errno; av_log(avctx, AV_LOG_ERROR, "Failed to get " "framebuffer %"PRIu32": %s.\n", plane->fb_id, strerror(err)); err = AVERROR(err); goto fail; + } else { + av_log(avctx, AV_LOG_INFO, "Template framebuffer is " + "%"PRIu32": %"PRIu32"x%"PRIu32" " + "format %"PRIx32" modifier %"PRIx64" flags %"PRIx32".\n", + fb2->fb_id, fb2->width, fb2->height, + fb2->pixel_format, fb2->modifier, fb2->flags); + + ctx->width = fb2->width; + ctx->height = fb2->height; + + if (!fb2->handles[0]) { + av_log(avctx, AV_LOG_ERROR, "No handle set on framebuffer: " + "maybe you need some additional capabilities?\n"); + err = AVERROR(EINVAL); + goto fail; + } + + for (i = 0; i < FF_ARRAY_ELEMS(kmsgrab_formats); i++) { + if (kmsgrab_formats[i].drm_format == fb2->pixel_format) { + if (ctx->format != AV_PIX_FMT_NONE && + ctx->format != kmsgrab_formats[i].pixfmt) { + av_log(avctx, AV_LOG_ERROR, "Framebuffer pixel format " + "%"PRIx32" does not match expected format.\n", + fb2->pixel_format); + err = AVERROR(EINVAL); + goto fail; + } + ctx->drm_format = fb2->pixel_format; + ctx->format = kmsgrab_formats[i].pixfmt; + break; + } + } + if (i == FF_ARRAY_ELEMS(kmsgrab_formats)) { + av_log(avctx, AV_LOG_ERROR, "Framebuffer pixel format " + "%"PRIx32" is not a known supported format.\n", + fb2->pixel_format); + err = AVERROR(EINVAL); + goto fail; + } + + if (fb2->flags & DRM_MODE_FB_MODIFIERS) { + if (ctx->drm_format_modifier != DRM_FORMAT_MOD_INVALID && + ctx->drm_format_modifier != fb2->modifier) { + av_log(avctx, AV_LOG_ERROR, "Framebuffer format modifier " + "%"PRIx64" does not match expected modifier.\n", + fb2->modifier); + err = AVERROR(EINVAL); + goto fail; + } else { + ctx->drm_format_modifier = fb2->modifier; + } + } + av_log(avctx, AV_LOG_VERBOSE, "Format is %s, from " + "DRM format %"PRIx32" modifier %"PRIx64".\n", + av_get_pix_fmt_name(ctx->format), + ctx->drm_format, ctx->drm_format_modifier); + + ctx->fb2_available = 1; } +#endif - av_log(avctx, AV_LOG_INFO, "Template framebuffer is %"PRIu32": " - "%"PRIu32"x%"PRIu32" %"PRIu32"bpp %"PRIu32"b depth.\n", - fb->fb_id, fb->width, fb->height, fb->bpp, fb->depth); + if (!ctx->fb2_available) { + if (ctx->format == AV_PIX_FMT_NONE) { + // Backward compatibility: assume BGR0 if no format supplied. + ctx->format = AV_PIX_FMT_BGR0; + } + for (i = 0; i < FF_ARRAY_ELEMS(kmsgrab_formats); i++) { + if (kmsgrab_formats[i].pixfmt == ctx->format) { + ctx->drm_format = kmsgrab_formats[i].drm_format; + break; + } + } + if (i >= FF_ARRAY_ELEMS(kmsgrab_formats)) { + av_log(avctx, AV_LOG_ERROR, "Unsupported format %s.\n", + av_get_pix_fmt_name(ctx->format)); + return AVERROR(EINVAL); + } - ctx->width = fb->width; - ctx->height = fb->height; + fb = drmModeGetFB(ctx->hwctx->fd, plane->fb_id); + if (!fb) { + err = errno; + av_log(avctx, AV_LOG_ERROR, "Failed to get " + "framebuffer %"PRIu32": %s.\n", + plane->fb_id, strerror(err)); + err = AVERROR(err); + goto fail; + } - if (!fb->handle) { - av_log(avctx, AV_LOG_ERROR, "No handle set on framebuffer: " - "maybe you need some additional capabilities?\n"); - err = AVERROR(EINVAL); - goto fail; + av_log(avctx, AV_LOG_INFO, "Template framebuffer is %"PRIu32": " + "%"PRIu32"x%"PRIu32" %"PRIu32"bpp %"PRIu32"b depth.\n", + fb->fb_id, fb->width, fb->height, fb->bpp, fb->depth); + + ctx->width = fb->width; + ctx->height = fb->height; + + if (!fb->handle) { + av_log(avctx, AV_LOG_ERROR, "No handle set on framebuffer: " + "maybe you need some additional capabilities?\n"); + err = AVERROR(EINVAL); + goto fail; + } } stream = avformat_new_stream(avctx, NULL); @@ -372,8 +627,8 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx) stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; stream->codecpar->codec_id = AV_CODEC_ID_WRAPPED_AVFRAME; - stream->codecpar->width = fb->width; - stream->codecpar->height = fb->height; + stream->codecpar->width = ctx->width; + stream->codecpar->height = ctx->height; stream->codecpar->format = AV_PIX_FMT_DRM_PRIME; avpriv_set_pts_info(stream, 64, 1, 1000000); @@ -387,8 +642,8 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx) ctx->frames->format = AV_PIX_FMT_DRM_PRIME; ctx->frames->sw_format = ctx->format, - ctx->frames->width = fb->width; - ctx->frames->height = fb->height; + ctx->frames->width = ctx->width; + ctx->frames->height = ctx->height; err = av_hwframe_ctx_init(ctx->frames_ref); if (err < 0) { @@ -402,13 +657,12 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx) err = 0; fail: - if (plane_res) - drmModeFreePlaneResources(plane_res); - if (plane) - drmModeFreePlane(plane); - if (fb) - drmModeFreeFB(fb); - + drmModeFreePlaneResources(plane_res); + drmModeFreePlane(plane); + drmModeFreeFB(fb); +#if HAVE_LIBDRM_GETFB2 + drmModeFreeFB2(fb2); +#endif return err; } @@ -430,10 +684,10 @@ static const AVOption options[] = { { .str = "/dev/dri/card0" }, 0, 0, FLAGS }, { "format", "Pixel format for framebuffer", OFFSET(format), AV_OPT_TYPE_PIXEL_FMT, - { .i64 = AV_PIX_FMT_BGR0 }, 0, UINT32_MAX, FLAGS }, + { .i64 = AV_PIX_FMT_NONE }, -1, INT32_MAX, FLAGS }, { "format_modifier", "DRM format modifier for framebuffer", OFFSET(drm_format_modifier), AV_OPT_TYPE_INT64, - { .i64 = DRM_FORMAT_MOD_NONE }, 0, INT64_MAX, FLAGS }, + { .i64 = DRM_FORMAT_MOD_INVALID }, 0, INT64_MAX, FLAGS }, { "crtc_id", "CRTC ID to define capture source", OFFSET(source_crtc), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, UINT32_MAX, FLAGS }, diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c index c949ff7e1..fdadff3f7 100644 --- a/libavdevice/lavfi.c +++ b/libavdevice/lavfi.c @@ -69,7 +69,7 @@ static int *create_all_formats(int n) count++; } - if (!(fmts = av_malloc((count+1) * sizeof(int)))) + if (!(fmts = av_malloc_array(count + 1, sizeof(*fmts)))) return NULL; for (j = 0, i = 0; i < n; i++) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i); @@ -362,16 +362,12 @@ static int create_subcc_packet(AVFormatContext *avctx, AVFrame *frame, { LavfiContext *lavfi = avctx->priv_data; AVFrameSideData *sd; - int stream_idx, i, ret; + int stream_idx, ret; if ((stream_idx = lavfi->sink_stream_subcc_map[sink_idx]) < 0) return 0; - for (i = 0; i < frame->nb_side_data; i++) - if (frame->side_data[i]->type == AV_FRAME_DATA_A53_CC) - break; - if (i >= frame->nb_side_data) + if (!(sd = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC))) return 0; - sd = frame->side_data[i]; if ((ret = av_new_packet(&lavfi->subcc_packet, sd->size)) < 0) return ret; memcpy(lavfi->subcc_packet.data, sd->data, sd->size); @@ -390,12 +386,10 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) AVDictionary *frame_metadata; int ret, i; int size = 0; + AVStream *st; if (lavfi->subcc_packet.size) { - *pkt = lavfi->subcc_packet; - av_init_packet(&lavfi->subcc_packet); - lavfi->subcc_packet.size = 0; - lavfi->subcc_packet.data = NULL; + av_packet_move_ref(pkt, &lavfi->subcc_packet); return pkt->size; } @@ -433,57 +427,52 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) av_buffersink_get_frame_flags(lavfi->sinks[min_pts_sink_idx], frame, 0); stream_idx = lavfi->sink_stream_map[min_pts_sink_idx]; + st = avctx->streams[stream_idx]; - if (frame->width /* FIXME best way of testing a video */) { + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { size = av_image_get_buffer_size(frame->format, frame->width, frame->height, 1); if ((ret = av_new_packet(pkt, size)) < 0) - return ret; + goto fail; av_image_copy_to_buffer(pkt->data, size, (const uint8_t **)frame->data, frame->linesize, frame->format, frame->width, frame->height, 1); - } else if (frame->channels /* FIXME test audio */) { + } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { size = frame->nb_samples * av_get_bytes_per_sample(frame->format) * frame->channels; if ((ret = av_new_packet(pkt, size)) < 0) - return ret; + goto fail; memcpy(pkt->data, frame->data[0], size); } frame_metadata = frame->metadata; if (frame_metadata) { - uint8_t *metadata; - AVDictionaryEntry *e = NULL; - AVBPrint meta_buf; + buffer_size_t size; + uint8_t *metadata = av_packet_pack_dictionary(frame_metadata, &size); - av_bprint_init(&meta_buf, 0, AV_BPRINT_SIZE_UNLIMITED); - while ((e = av_dict_get(frame_metadata, "", e, AV_DICT_IGNORE_SUFFIX))) { - av_bprintf(&meta_buf, "%s", e->key); - av_bprint_chars(&meta_buf, '\0', 1); - av_bprintf(&meta_buf, "%s", e->value); - av_bprint_chars(&meta_buf, '\0', 1); + if (!metadata) { + ret = AVERROR(ENOMEM); + goto fail; } - if (!av_bprint_is_complete(&meta_buf) || - !(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, - meta_buf.len))) { - av_bprint_finalize(&meta_buf, NULL); - return AVERROR(ENOMEM); + if ((ret = av_packet_add_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, + metadata, size)) < 0) { + av_freep(&metadata); + goto fail; } - memcpy(metadata, meta_buf.str, meta_buf.len); - av_bprint_finalize(&meta_buf, NULL); } if ((ret = create_subcc_packet(avctx, frame, min_pts_sink_idx)) < 0) { - av_frame_unref(frame); - av_packet_unref(pkt); - return ret; + goto fail; } pkt->stream_index = stream_idx; pkt->pts = frame->pts; pkt->pos = frame->pkt_pos; - pkt->size = size; av_frame_unref(frame); return size; +fail: + av_frame_unref(frame); + return ret; + } #define OFFSET(x) offsetof(LavfiContext, x) diff --git a/libavdevice/pulse_audio_dec.c b/libavdevice/pulse_audio_dec.c index 50a3c971a..3777396ef 100644 --- a/libavdevice/pulse_audio_dec.c +++ b/libavdevice/pulse_audio_dec.c @@ -48,6 +48,7 @@ typedef struct PulseData { pa_threaded_mainloop *mainloop; pa_context *context; pa_stream *stream; + size_t pa_frame_size; TimeFilter *timefilter; int last_period; @@ -149,6 +150,7 @@ static av_cold int pulse_read_header(AVFormatContext *s) pa_buffer_attr attr = { -1 }; pa_channel_map cmap; + const pa_buffer_attr *queried_attr; pa_channel_map_init_extend(&cmap, pd->channels, PA_CHANNEL_MAP_WAVEEX); @@ -217,7 +219,7 @@ static av_cold int pulse_read_header(AVFormatContext *s) ret = pa_stream_connect_record(pd->stream, device, &attr, PA_STREAM_INTERPOLATE_TIMING - |PA_STREAM_ADJUST_LATENCY + | (pd->fragment_size == -1 ? PA_STREAM_ADJUST_LATENCY : 0) |PA_STREAM_AUTO_TIMING_UPDATE); if (ret < 0) { @@ -242,6 +244,15 @@ static av_cold int pulse_read_header(AVFormatContext *s) pa_threaded_mainloop_wait(pd->mainloop); } + /* Query actual fragment size */ + queried_attr = pa_stream_get_buffer_attr(pd->stream); + if (!queried_attr || queried_attr->fragsize > INT_MAX/100) { + ret = AVERROR_EXTERNAL; + goto unlock_and_fail; + } + pd->fragment_size = queried_attr->fragsize; + pd->pa_frame_size = pa_frame_size(&ss); + pa_threaded_mainloop_unlock(pd->mainloop); /* take real parameters */ @@ -252,7 +263,7 @@ static av_cold int pulse_read_header(AVFormatContext *s) avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ pd->timefilter = ff_timefilter_new(1000000.0 / pd->sample_rate, - 1000, 1.5E-6); + pd->fragment_size / pd->pa_frame_size, 1.5E-6); if (!pd->timefilter) { pulse_close(s); @@ -277,12 +288,13 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) int64_t dts; pa_usec_t latency; int negative; + ptrdiff_t pos = 0; pa_threaded_mainloop_lock(pd->mainloop); CHECK_DEAD_GOTO(pd, ret, unlock_and_fail); - while (!read_data) { + while (pos < pd->fragment_size) { int r; r = pa_stream_peek(pd->stream, &read_data, &read_length); @@ -296,43 +308,51 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) * silence, but that wouldn't work for compressed streams. */ r = pa_stream_drop(pd->stream); CHECK_SUCCESS_GOTO(ret, r == 0, unlock_and_fail); + } else { + if (!pos) { + if (av_new_packet(pkt, pd->fragment_size) < 0) { + ret = AVERROR(ENOMEM); + goto unlock_and_fail; + } + + dts = av_gettime(); + pa_operation_unref(pa_stream_update_timing_info(pd->stream, NULL, NULL)); + + if (pa_stream_get_latency(pd->stream, &latency, &negative) >= 0) { + if (negative) { + dts += latency; + } else + dts -= latency; + } else { + av_log(s, AV_LOG_WARNING, "pa_stream_get_latency() failed\n"); + } + } + if (pkt->size - pos < read_length) { + if (pos) + break; + pa_stream_drop(pd->stream); + /* Oversized fragment??? */ + ret = AVERROR_EXTERNAL; + goto unlock_and_fail; + } + memcpy(pkt->data + pos, read_data, read_length); + pos += read_length; + pa_stream_drop(pd->stream); } } - if (av_new_packet(pkt, read_length) < 0) { - ret = AVERROR(ENOMEM); - goto unlock_and_fail; - } - - dts = av_gettime(); - pa_operation_unref(pa_stream_update_timing_info(pd->stream, NULL, NULL)); - - if (pa_stream_get_latency(pd->stream, &latency, &negative) >= 0) { - enum AVCodecID codec_id = - s->audio_codec_id == AV_CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_codec_id; - int frame_size = ((av_get_bits_per_sample(codec_id) >> 3) * pd->channels); - int frame_duration = read_length / frame_size; - - - if (negative) { - dts += latency; - } else - dts -= latency; - if (pd->wallclock) - pkt->pts = ff_timefilter_update(pd->timefilter, dts, pd->last_period); - - pd->last_period = frame_duration; - } else { - av_log(s, AV_LOG_WARNING, "pa_stream_get_latency() failed\n"); - } - - memcpy(pkt->data, read_data, read_length); - pa_stream_drop(pd->stream); - pa_threaded_mainloop_unlock(pd->mainloop); + + av_shrink_packet(pkt, pos); + + if (pd->wallclock) + pkt->pts = ff_timefilter_update(pd->timefilter, dts, pd->last_period); + pd->last_period = pkt->size / pd->pa_frame_size; + return 0; unlock_and_fail: + av_packet_unref(pkt); pa_threaded_mainloop_unlock(pd->mainloop); return ret; } diff --git a/libavdevice/timefilter.h b/libavdevice/timefilter.h index cb3d0a788..de7094506 100644 --- a/libavdevice/timefilter.h +++ b/libavdevice/timefilter.h @@ -39,16 +39,6 @@ typedef struct TimeFilter TimeFilter; /** * Create a new Delay Locked Loop time filter * - * feedback2_factor and feedback3_factor are the factors used for the - * multiplications that are respectively performed in the second and third - * feedback paths of the loop. - * - * Unless you know what you are doing, you should set these as follow: - * - * o = 2 * M_PI * bandwidth * period_in_seconds - * feedback2_factor = sqrt(2) * o - * feedback3_factor = o * o - * * Where bandwidth is up to you to choose. Smaller values will filter out more * of the jitter, but also take a longer time for the loop to settle. A good * starting point is something between 0.3 and 3 Hz. @@ -59,11 +49,8 @@ typedef struct TimeFilter TimeFilter; * @param brandwidth filtering bandwidth, in Hz * * @return a pointer to a TimeFilter struct, or NULL on error - * - * For more details about these parameters and background concepts please see: - * http://www.kokkinizita.net/papers/usingdll.pdf */ -TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor); +TimeFilter * ff_timefilter_new(double time_base, double period, double bandwidth); /** * Update the filter diff --git a/libavdevice/version.h b/libavdevice/version.h index 9ee3d3db4..c310c5ec5 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 58 -#define LIBAVDEVICE_VERSION_MINOR 10 +#define LIBAVDEVICE_VERSION_MINOR 13 #define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ @@ -46,5 +46,8 @@ * dropped at a future version bump. The defines themselves are not part of * the public API and may change, break or disappear at any time. */ +#ifndef FF_API_DEVICE_CAPABILITIES +#define FF_API_DEVICE_CAPABILITIES (LIBAVDEVICE_VERSION_MAJOR < 60) +#endif #endif /* AVDEVICE_VERSION_H */ diff --git a/libavdevice/vfwcap.c b/libavdevice/vfwcap.c index e2ab276c2..b3ef5f344 100644 --- a/libavdevice/vfwcap.c +++ b/libavdevice/vfwcap.c @@ -24,6 +24,7 @@ #include "libavutil/opt.h" #include "libavutil/parseutils.h" +#include "libavcodec/packet_internal.h" #include "libavformat/internal.h" // windows.h must no be included before winsock2.h, and libavformat internal @@ -44,7 +45,7 @@ struct vfw_ctx { HWND hwnd; HANDLE mutex; HANDLE event; - AVPacketList *pktl; + PacketList *pktl; unsigned int curbufsize; unsigned int frame_num; char *video_size; /**< A string describing video size, set by a private option. */ @@ -178,7 +179,7 @@ static LRESULT CALLBACK videostream_cb(HWND hwnd, LPVIDEOHDR vdhdr) { AVFormatContext *s; struct vfw_ctx *ctx; - AVPacketList **ppktl, *pktl_next; + PacketList **ppktl, *pktl_next; s = (AVFormatContext *) GetWindowLongPtr(hwnd, GWLP_USERDATA); ctx = s->priv_data; @@ -190,7 +191,7 @@ static LRESULT CALLBACK videostream_cb(HWND hwnd, LPVIDEOHDR vdhdr) WaitForSingleObject(ctx->mutex, INFINITE); - pktl_next = av_mallocz(sizeof(AVPacketList)); + pktl_next = av_mallocz(sizeof(PacketList)); if(!pktl_next) goto fail; @@ -219,7 +220,7 @@ fail: static int vfw_read_close(AVFormatContext *s) { struct vfw_ctx *ctx = s->priv_data; - AVPacketList *pktl; + PacketList *pktl; if(ctx->hwnd) { SendMessage(ctx->hwnd, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0); @@ -233,7 +234,7 @@ static int vfw_read_close(AVFormatContext *s) pktl = ctx->pktl; while (pktl) { - AVPacketList *next = pktl->next; + PacketList *next = pktl->next; av_packet_unref(&pktl->pkt); av_free(pktl); pktl = next; @@ -439,7 +440,7 @@ fail: static int vfw_read_packet(AVFormatContext *s, AVPacket *pkt) { struct vfw_ctx *ctx = s->priv_data; - AVPacketList *pktl = NULL; + PacketList *pktl = NULL; while(!pktl) { WaitForSingleObject(ctx->mutex, INFINITE); diff --git a/libavdevice/xcbgrab.c b/libavdevice/xcbgrab.c index 6f6b2dbf1..8e3292e57 100644 --- a/libavdevice/xcbgrab.c +++ b/libavdevice/xcbgrab.c @@ -22,6 +22,7 @@ #include "config.h" #include +#include #include #if CONFIG_LIBXCB_XFIXES @@ -59,6 +60,7 @@ typedef struct XCBGrabContext { AVRational time_base; int64_t frame_duration; + xcb_window_t window_id; int x, y; int width, height; int frame_size; @@ -69,6 +71,7 @@ typedef struct XCBGrabContext { int show_region; int region_border; int centered; + int select_region; const char *framerate; @@ -80,6 +83,7 @@ typedef struct XCBGrabContext { #define OFFSET(x) offsetof(XCBGrabContext, x) #define D AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { + { "window_id", "Window to capture.", OFFSET(window_id), AV_OPT_TYPE_INT, { .i64 = XCB_NONE }, 0, UINT32_MAX, D }, { "x", "Initial x coordinate.", OFFSET(x), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D }, { "y", "Initial y coordinate.", OFFSET(y), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D }, { "grab_x", "Initial x coordinate.", OFFSET(x), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D }, @@ -92,6 +96,7 @@ static const AVOption options[] = { { "centered", "Keep the mouse pointer at the center of grabbing region when following.", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, D, "follow_mouse" }, { "show_region", "Show the grabbing region.", OFFSET(show_region), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, { "region_border", "Set the region border thickness.", OFFSET(region_border), AV_OPT_TYPE_INT, { .i64 = 3 }, 1, 128, D }, + { "select_region", "Select the grabbing region graphically using the pointer.", OFFSET(select_region), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, { NULL }, }; @@ -154,7 +159,7 @@ static int xcbgrab_frame(AVFormatContext *s, AVPacket *pkt) XCBGrabContext *c = s->priv_data; xcb_get_image_cookie_t iq; xcb_get_image_reply_t *img; - xcb_drawable_t drawable = c->screen->root; + xcb_drawable_t drawable = c->window_id; xcb_generic_error_t *e = NULL; uint8_t *data; int length; @@ -181,8 +186,6 @@ static int xcbgrab_frame(AVFormatContext *s, AVPacket *pkt) data = xcb_get_image_data(img); length = xcb_get_image_data_length(img); - av_init_packet(pkt); - pkt->buf = av_buffer_create(data, length, xcbgrab_image_reply_free, img, 0); if (!pkt->buf) { free(img); @@ -203,7 +206,7 @@ static int64_t wait_frame(AVFormatContext *s, AVPacket *pkt) c->time_frame += c->frame_duration; for (;;) { - curtime = av_gettime(); + curtime = av_gettime_relative(); delay = c->time_frame - curtime; if (delay <= 0) break; @@ -233,7 +236,7 @@ static void free_shm_buffer(void *opaque, uint8_t *data) shmdt(data); } -static AVBufferRef *allocate_shm_buffer(void *opaque, int size) +static AVBufferRef *allocate_shm_buffer(void *opaque, buffer_size_t size) { xcb_connection_t *conn = opaque; xcb_shm_seg_t segment; @@ -264,7 +267,7 @@ static int xcbgrab_frame_shm(AVFormatContext *s, AVPacket *pkt) XCBGrabContext *c = s->priv_data; xcb_shm_get_image_cookie_t iq; xcb_shm_get_image_reply_t *img; - xcb_drawable_t drawable = c->screen->root; + xcb_drawable_t drawable = c->window_id; xcb_generic_error_t *e = NULL; AVBufferRef *buf; xcb_shm_seg_t segment; @@ -298,8 +301,6 @@ static int xcbgrab_frame_shm(AVFormatContext *s, AVPacket *pkt) free(img); - av_init_packet(pkt); - pkt->buf = buf; pkt->data = buf->data; pkt->size = c->frame_size; @@ -330,7 +331,8 @@ static int check_xfixes(xcb_connection_t *conn) static void xcbgrab_draw_mouse(AVFormatContext *s, AVPacket *pkt, xcb_query_pointer_reply_t *p, - xcb_get_geometry_reply_t *geo) + xcb_get_geometry_reply_t *geo, + int win_x, int win_y) { XCBGrabContext *gr = s->priv_data; uint32_t *cursor; @@ -352,17 +354,17 @@ static void xcbgrab_draw_mouse(AVFormatContext *s, AVPacket *pkt, cx = ci->x - ci->xhot; cy = ci->y - ci->yhot; - x = FFMAX(cx, gr->x); - y = FFMAX(cy, gr->y); + x = FFMAX(cx, win_x + gr->x); + y = FFMAX(cy, win_y + gr->y); - w = FFMIN(cx + ci->width, gr->x + gr->width) - x; - h = FFMIN(cy + ci->height, gr->y + gr->height) - y; + w = FFMIN(cx + ci->width, win_x + gr->x + gr->width) - x; + h = FFMIN(cy + ci->height, win_y + gr->y + gr->height) - y; c_off = x - cx; - i_off = x - gr->x; + i_off = x - gr->x - win_x; cursor += (y - cy) * ci->width; - image += (y - gr->y) * gr->width * stride; + image += (y - gr->y - win_y) * gr->width * stride; for (y = 0; y < h; y++) { cursor += c_off; @@ -397,11 +399,11 @@ static void xcbgrab_draw_mouse(AVFormatContext *s, AVPacket *pkt, } #endif /* CONFIG_LIBXCB_XFIXES */ -static void xcbgrab_update_region(AVFormatContext *s) +static void xcbgrab_update_region(AVFormatContext *s, int win_x, int win_y) { XCBGrabContext *c = s->priv_data; - const uint32_t args[] = { c->x - c->region_border, - c->y - c->region_border }; + const uint32_t args[] = { win_x + c->x - c->region_border, + win_y + c->y - c->region_border }; xcb_configure_window(c->conn, c->window, @@ -414,25 +416,51 @@ static int xcbgrab_read_packet(AVFormatContext *s, AVPacket *pkt) XCBGrabContext *c = s->priv_data; xcb_query_pointer_cookie_t pc; xcb_get_geometry_cookie_t gc; + xcb_translate_coordinates_cookie_t tc; xcb_query_pointer_reply_t *p = NULL; xcb_get_geometry_reply_t *geo = NULL; + xcb_translate_coordinates_reply_t *translate = NULL; int ret = 0; int64_t pts; + int win_x = 0, win_y = 0; - pts = wait_frame(s, pkt); + wait_frame(s, pkt); + pts = av_gettime(); if (c->follow_mouse || c->draw_mouse) { - pc = xcb_query_pointer(c->conn, c->screen->root); - gc = xcb_get_geometry(c->conn, c->screen->root); + pc = xcb_query_pointer(c->conn, c->window_id); + gc = xcb_get_geometry(c->conn, c->window_id); p = xcb_query_pointer_reply(c->conn, pc, NULL); + if (!p) { + av_log(s, AV_LOG_ERROR, "Failed to query xcb pointer\n"); + return AVERROR_EXTERNAL; + } geo = xcb_get_geometry_reply(c->conn, gc, NULL); + if (!geo) { + av_log(s, AV_LOG_ERROR, "Failed to get xcb geometry\n"); + free(p); + return AVERROR_EXTERNAL; + } + } + if (c->window_id != c->screen->root) { + tc = xcb_translate_coordinates(c->conn, c->window_id, c->screen->root, 0, 0); + translate = xcb_translate_coordinates_reply(c->conn, tc, NULL); + if (!translate) { + free(p); + free(geo); + av_log(s, AV_LOG_ERROR, "Failed to translate xcb geometry\n"); + return AVERROR_EXTERNAL; + } + win_x = translate->dst_x; + win_y = translate->dst_y; + free(translate); } if (c->follow_mouse && p->same_screen) xcbgrab_reposition(s, p, geo); if (c->show_region) - xcbgrab_update_region(s); + xcbgrab_update_region(s, win_x, win_y); #if CONFIG_LIBXCB_SHM if (c->has_shm && xcbgrab_frame_shm(s, pkt) < 0) { @@ -447,7 +475,7 @@ static int xcbgrab_read_packet(AVFormatContext *s, AVPacket *pkt) #if CONFIG_LIBXCB_XFIXES if (ret >= 0 && c->draw_mouse && p->same_screen) - xcbgrab_draw_mouse(s, pkt, p, geo); + xcbgrab_draw_mouse(s, pkt, p, geo, win_x, win_y); #endif free(p); @@ -501,21 +529,26 @@ static int pixfmt_from_pixmap_format(AVFormatContext *s, int depth, switch (depth) { case 32: if (fmt->bits_per_pixel == 32) - *pix_fmt = AV_PIX_FMT_0RGB; + *pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ? + AV_PIX_FMT_BGR0 : AV_PIX_FMT_0RGB; break; case 24: if (fmt->bits_per_pixel == 32) - *pix_fmt = AV_PIX_FMT_0RGB32; + *pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ? + AV_PIX_FMT_BGR0 : AV_PIX_FMT_0RGB; else if (fmt->bits_per_pixel == 24) - *pix_fmt = AV_PIX_FMT_RGB24; + *pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ? + AV_PIX_FMT_BGR24 : AV_PIX_FMT_RGB24; break; case 16: if (fmt->bits_per_pixel == 16) - *pix_fmt = AV_PIX_FMT_RGB565; + *pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ? + AV_PIX_FMT_RGB565LE : AV_PIX_FMT_RGB565BE; break; case 15: if (fmt->bits_per_pixel == 16) - *pix_fmt = AV_PIX_FMT_RGB555; + *pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ? + AV_PIX_FMT_RGB555LE : AV_PIX_FMT_RGB555BE; break; case 8: if (fmt->bits_per_pixel == 8) @@ -554,10 +587,12 @@ static int create_stream(AVFormatContext *s) avpriv_set_pts_info(st, 64, 1, 1000000); - gc = xcb_get_geometry(c->conn, c->screen->root); + gc = xcb_get_geometry(c->conn, c->window_id); geo = xcb_get_geometry_reply(c->conn, gc, NULL); - if (!geo) + if (!geo) { + av_log(s, AV_LOG_ERROR, "Can't find window '0x%x', aborting.\n", c->window_id); return AVERROR_EXTERNAL; + } if (!c->width || !c->height) { c->width = geo->width; @@ -579,7 +614,7 @@ static int create_stream(AVFormatContext *s) c->time_base = (AVRational){ st->avg_frame_rate.den, st->avg_frame_rate.num }; c->frame_duration = av_rescale_q(1, c->time_base, AV_TIME_BASE_Q); - c->time_frame = av_gettime(); + c->time_frame = av_gettime_relative(); ret = pixfmt_from_pixmap_format(s, geo->depth, &st->codecpar->format, &c->bpp); free(geo); @@ -668,6 +703,117 @@ static void setup_window(AVFormatContext *s) draw_rectangle(s); } +#define CROSSHAIR_CURSOR 34 + +static xcb_rectangle_t rectangle_from_corners(xcb_point_t *corner_a, + xcb_point_t *corner_b) +{ + xcb_rectangle_t rectangle; + rectangle.x = FFMIN(corner_a->x, corner_b->x); + rectangle.y = FFMIN(corner_a->y, corner_b->y); + rectangle.width = FFABS(corner_a->x - corner_b->x); + rectangle.height = FFABS(corner_a->y - corner_b->y); + return rectangle; +} + +static int select_region(AVFormatContext *s) +{ + XCBGrabContext *c = s->priv_data; + xcb_connection_t *conn = c->conn; + xcb_screen_t *screen = c->screen; + + int ret = 0, done = 0, was_pressed = 0; + xcb_cursor_t cursor; + xcb_font_t cursor_font; + xcb_point_t press_position; + xcb_generic_event_t *event; + xcb_rectangle_t rectangle = { 0 }; + xcb_grab_pointer_reply_t *reply; + xcb_grab_pointer_cookie_t cookie; + + xcb_window_t root_window = screen->root; + xcb_gcontext_t gc = xcb_generate_id(conn); + uint32_t mask = XCB_GC_FUNCTION | XCB_GC_SUBWINDOW_MODE; + uint32_t values[] = { XCB_GX_INVERT, XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS }; + xcb_create_gc(conn, gc, root_window, mask, values); + + cursor_font = xcb_generate_id(conn); + xcb_open_font(conn, cursor_font, strlen("cursor"), "cursor"); + cursor = xcb_generate_id(conn); + xcb_create_glyph_cursor(conn, cursor, cursor_font, cursor_font, + CROSSHAIR_CURSOR, CROSSHAIR_CURSOR + 1, 0, 0, 0, + 0xFFFF, 0xFFFF, 0xFFFF); + cookie = xcb_grab_pointer(conn, 0, root_window, + XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_BUTTON_MOTION, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, + root_window, cursor, XCB_CURRENT_TIME); + reply = xcb_grab_pointer_reply(conn, cookie, NULL); + if (!reply || reply->status != XCB_GRAB_STATUS_SUCCESS) { + av_log(s, AV_LOG_ERROR, + "Failed to select region. Could not grab pointer.\n"); + ret = AVERROR(EIO); + free(reply); + goto fail; + } + free(reply); + + xcb_grab_server(conn); + + while (!done && (event = xcb_wait_for_event(conn))) { + switch (event->response_type & ~0x80) { + case XCB_BUTTON_PRESS: { + xcb_button_press_event_t *press = (xcb_button_press_event_t *)event; + press_position = (xcb_point_t){ press->event_x, press->event_y }; + rectangle.x = press_position.x; + rectangle.y = press_position.y; + xcb_poly_rectangle(conn, root_window, gc, 1, &rectangle); + was_pressed = 1; + break; + } + case XCB_MOTION_NOTIFY: { + if (was_pressed) { + xcb_motion_notify_event_t *motion = + (xcb_motion_notify_event_t *)event; + xcb_point_t cursor_position = { motion->event_x, motion->event_y }; + xcb_poly_rectangle(conn, root_window, gc, 1, &rectangle); + rectangle = rectangle_from_corners(&press_position, &cursor_position); + xcb_poly_rectangle(conn, root_window, gc, 1, &rectangle); + } + break; + } + case XCB_BUTTON_RELEASE: { + xcb_poly_rectangle(conn, root_window, gc, 1, &rectangle); + done = 1; + break; + } + default: + break; + } + xcb_flush(conn); + free(event); + } + c->width = rectangle.width; + c->height = rectangle.height; + if (c->width && c->height) { + c->x = rectangle.x; + c->y = rectangle.y; + } else { + c->x = 0; + c->y = 0; + } + xcb_ungrab_server(conn); + xcb_ungrab_pointer(conn, XCB_CURRENT_TIME); + xcb_flush(conn); + +fail: + xcb_free_cursor(conn, cursor); + xcb_close_font(conn, cursor_font); + xcb_free_gc(conn, gc); + return ret; +} + static av_cold int xcbgrab_read_header(AVFormatContext *s) { XCBGrabContext *c = s->priv_data; @@ -702,6 +848,27 @@ static av_cold int xcbgrab_read_header(AVFormatContext *s) return AVERROR(EIO); } + if (c->window_id == XCB_NONE) + c->window_id = c->screen->root; + else { + if (c->select_region) { + av_log(s, AV_LOG_WARNING, "select_region ignored with window_id.\n"); + c->select_region = 0; + } + if (c->follow_mouse) { + av_log(s, AV_LOG_WARNING, "follow_mouse ignored with window_id.\n"); + c->follow_mouse = 0; + } + } + + if (c->select_region) { + ret = select_region(s); + if (ret < 0) { + xcbgrab_read_close(s); + return ret; + } + } + ret = create_stream(s); if (ret < 0) { diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 512354065..b2c254ea6 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -27,6 +27,7 @@ OBJS-$(HAVE_THREADS) += pthread.o # subsystems OBJS-$(CONFIG_QSVVPP) += qsvvpp.o OBJS-$(CONFIG_SCENE_SAD) += scene_sad.o +OBJS-$(CONFIG_DNN) += dnn_filter_common.o include $(SRC_PATH)/libavfilter/dnn/Makefile # audio filters @@ -41,15 +42,18 @@ OBJS-$(CONFIG_ACUE_FILTER) += f_cue.o OBJS-$(CONFIG_ADECLICK_FILTER) += af_adeclick.o OBJS-$(CONFIG_ADECLIP_FILTER) += af_adeclick.o OBJS-$(CONFIG_ADELAY_FILTER) += af_adelay.o +OBJS-$(CONFIG_ADENORM_FILTER) += af_adenorm.o OBJS-$(CONFIG_ADERIVATIVE_FILTER) += af_aderivative.o OBJS-$(CONFIG_AECHO_FILTER) += af_aecho.o OBJS-$(CONFIG_AEMPHASIS_FILTER) += af_aemphasis.o OBJS-$(CONFIG_AEVAL_FILTER) += aeval.o +OBJS-$(CONFIG_AEXCITER_FILTER) += af_aexciter.o OBJS-$(CONFIG_AFADE_FILTER) += af_afade.o OBJS-$(CONFIG_AFFTDN_FILTER) += af_afftdn.o OBJS-$(CONFIG_AFFTFILT_FILTER) += af_afftfilt.o OBJS-$(CONFIG_AFIR_FILTER) += af_afir.o OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o +OBJS-$(CONFIG_AFREQSHIFT_FILTER) += af_afreqshift.o OBJS-$(CONFIG_AGATE_FILTER) += af_agate.o OBJS-$(CONFIG_AIIR_FILTER) += af_aiir.o OBJS-$(CONFIG_AINTEGRAL_FILTER) += af_aderivative.o @@ -68,6 +72,7 @@ OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o OBJS-$(CONFIG_APAD_FILTER) += af_apad.o OBJS-$(CONFIG_APERMS_FILTER) += f_perms.o OBJS-$(CONFIG_APHASER_FILTER) += af_aphaser.o generate_wave_table.o +OBJS-$(CONFIG_APHASESHIFT_FILTER) += af_afreqshift.o OBJS-$(CONFIG_APULSATOR_FILTER) += af_apulsator.o OBJS-$(CONFIG_AREALTIME_FILTER) += f_realtime.o OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o @@ -87,6 +92,10 @@ OBJS-$(CONFIG_ASR_FILTER) += af_asr.o OBJS-$(CONFIG_ASTATS_FILTER) += af_astats.o OBJS-$(CONFIG_ASTREAMSELECT_FILTER) += f_streamselect.o framesync.o OBJS-$(CONFIG_ASUBBOOST_FILTER) += af_asubboost.o +OBJS-$(CONFIG_ASUBCUT_FILTER) += af_asupercut.o +OBJS-$(CONFIG_ASUPERCUT_FILTER) += af_asupercut.o +OBJS-$(CONFIG_ASUPERPASS_FILTER) += af_asupercut.o +OBJS-$(CONFIG_ASUPERSTOP_FILTER) += af_asupercut.o OBJS-$(CONFIG_ATEMPO_FILTER) += af_atempo.o OBJS-$(CONFIG_ATRIM_FILTER) += trim.o OBJS-$(CONFIG_AXCORRELATE_FILTER) += af_axcorrelate.o @@ -134,6 +143,7 @@ OBJS-$(CONFIG_SIDECHAINGATE_FILTER) += af_agate.o OBJS-$(CONFIG_SILENCEDETECT_FILTER) += af_silencedetect.o OBJS-$(CONFIG_SILENCEREMOVE_FILTER) += af_silenceremove.o OBJS-$(CONFIG_SOFALIZER_FILTER) += af_sofalizer.o +OBJS-$(CONFIG_SPEECHNORM_FILTER) += af_speechnorm.o OBJS-$(CONFIG_STEREOTOOLS_FILTER) += af_stereotools.o OBJS-$(CONFIG_STEREOWIDEN_FILTER) += af_stereowiden.o OBJS-$(CONFIG_SUPEREQUALIZER_FILTER) += af_superequalizer.o @@ -158,7 +168,7 @@ OBJS-$(CONFIG_ANULLSINK_FILTER) += asink_anullsink.o # video filters OBJS-$(CONFIG_ADDROI_FILTER) += vf_addroi.o OBJS-$(CONFIG_ALPHAEXTRACT_FILTER) += vf_extractplanes.o -OBJS-$(CONFIG_ALPHAMERGE_FILTER) += vf_alphamerge.o +OBJS-$(CONFIG_ALPHAMERGE_FILTER) += vf_alphamerge.o framesync.o OBJS-$(CONFIG_AMPLIFY_FILTER) += vf_amplify.o OBJS-$(CONFIG_ASS_FILTER) += vf_subtitles.o OBJS-$(CONFIG_ATADENOISE_FILTER) += vf_atadenoise.o @@ -182,11 +192,15 @@ OBJS-$(CONFIG_CAS_FILTER) += vf_cas.o OBJS-$(CONFIG_CHROMABER_VULKAN_FILTER) += vf_chromaber_vulkan.o vulkan.o OBJS-$(CONFIG_CHROMAHOLD_FILTER) += vf_chromakey.o OBJS-$(CONFIG_CHROMAKEY_FILTER) += vf_chromakey.o +OBJS-$(CONFIG_CHROMANR_FILTER) += vf_chromanr.o OBJS-$(CONFIG_CHROMASHIFT_FILTER) += vf_chromashift.o OBJS-$(CONFIG_CIESCOPE_FILTER) += vf_ciescope.o -OBJS-$(CONFIG_CODECVIEW_FILTER) += vf_codecview.o +OBJS-$(CONFIG_CODECVIEW_FILTER) += vf_codecview.o qp_table.o OBJS-$(CONFIG_COLORBALANCE_FILTER) += vf_colorbalance.o OBJS-$(CONFIG_COLORCHANNELMIXER_FILTER) += vf_colorchannelmixer.o +OBJS-$(CONFIG_COLORCONTRAST_FILTER) += vf_colorcontrast.o +OBJS-$(CONFIG_COLORCORRECT_FILTER) += vf_colorcorrect.o +OBJS-$(CONFIG_COLORIZE_FILTER) += vf_colorize.o OBJS-$(CONFIG_COLORKEY_FILTER) += vf_colorkey.o OBJS-$(CONFIG_COLORKEY_OPENCL_FILTER) += vf_colorkey_opencl.o opencl.o \ opencl/colorkey.o @@ -194,6 +208,7 @@ OBJS-$(CONFIG_COLORHOLD_FILTER) += vf_colorkey.o OBJS-$(CONFIG_COLORLEVELS_FILTER) += vf_colorlevels.o OBJS-$(CONFIG_COLORMATRIX_FILTER) += vf_colormatrix.o OBJS-$(CONFIG_COLORSPACE_FILTER) += vf_colorspace.o colorspace.o colorspacedsp.o +OBJS-$(CONFIG_COLORTEMPERATURE_FILTER) += vf_colortemperature.o OBJS-$(CONFIG_CONVOLUTION_FILTER) += vf_convolution.o OBJS-$(CONFIG_CONVOLUTION_OPENCL_FILTER) += vf_convolution_opencl.o opencl.o \ opencl/convolution.o @@ -239,10 +254,13 @@ OBJS-$(CONFIG_DRAWTEXT_FILTER) += vf_drawtext.o OBJS-$(CONFIG_EDGEDETECT_FILTER) += vf_edgedetect.o OBJS-$(CONFIG_ELBG_FILTER) += vf_elbg.o OBJS-$(CONFIG_ENTROPY_FILTER) += vf_entropy.o +OBJS-$(CONFIG_EPX_FILTER) += vf_epx.o OBJS-$(CONFIG_EQ_FILTER) += vf_eq.o OBJS-$(CONFIG_EROSION_FILTER) += vf_neighbor.o OBJS-$(CONFIG_EROSION_OPENCL_FILTER) += vf_neighbor_opencl.o opencl.o \ opencl/neighbor.o +OBJS-$(CONFIG_ESTDIF_FILTER) += vf_estdif.o +OBJS-$(CONFIG_EXPOSURE_FILTER) += vf_exposure.o OBJS-$(CONFIG_EXTRACTPLANES_FILTER) += vf_extractplanes.o OBJS-$(CONFIG_FADE_FILTER) += vf_fade.o OBJS-$(CONFIG_FFTDNOIZ_FILTER) += vf_fftdnoiz.o @@ -262,7 +280,7 @@ OBJS-$(CONFIG_FRAMESTEP_FILTER) += vf_framestep.o OBJS-$(CONFIG_FREEZEDETECT_FILTER) += vf_freezedetect.o OBJS-$(CONFIG_FREEZEFRAMES_FILTER) += vf_freezeframes.o OBJS-$(CONFIG_FREI0R_FILTER) += vf_frei0r.o -OBJS-$(CONFIG_FSPP_FILTER) += vf_fspp.o +OBJS-$(CONFIG_FSPP_FILTER) += vf_fspp.o qp_table.o OBJS-$(CONFIG_GBLUR_FILTER) += vf_gblur.o OBJS-$(CONFIG_GEQ_FILTER) += vf_geq.o OBJS-$(CONFIG_GRADFUN_FILTER) += vf_gradfun.o @@ -281,12 +299,14 @@ OBJS-$(CONFIG_HWMAP_FILTER) += vf_hwmap.o OBJS-$(CONFIG_HWUPLOAD_CUDA_FILTER) += vf_hwupload_cuda.o OBJS-$(CONFIG_HWUPLOAD_FILTER) += vf_hwupload.o OBJS-$(CONFIG_HYSTERESIS_FILTER) += vf_hysteresis.o framesync.o +OBJS-$(CONFIG_IDENTITY_FILTER) += vf_identity.o OBJS-$(CONFIG_IDET_FILTER) += vf_idet.o OBJS-$(CONFIG_IL_FILTER) += vf_il.o OBJS-$(CONFIG_INFLATE_FILTER) += vf_neighbor.o OBJS-$(CONFIG_INTERLACE_FILTER) += vf_tinterlace.o OBJS-$(CONFIG_INTERLEAVE_FILTER) += f_interleave.o OBJS-$(CONFIG_KERNDEINT_FILTER) += vf_kerndeint.o +OBJS-$(CONFIG_KIRSCH_FILTER) += vf_convolution.o OBJS-$(CONFIG_LAGFUN_FILTER) += vf_lagfun.o OBJS-$(CONFIG_LENSCORRECTION_FILTER) += vf_lenscorrection.o OBJS-$(CONFIG_LENSFUN_FILTER) += vf_lensfun.o @@ -314,6 +334,7 @@ OBJS-$(CONFIG_METADATA_FILTER) += f_metadata.o OBJS-$(CONFIG_MIDEQUALIZER_FILTER) += vf_midequalizer.o framesync.o OBJS-$(CONFIG_MINTERPOLATE_FILTER) += vf_minterpolate.o motion_estimation.o OBJS-$(CONFIG_MIX_FILTER) += vf_mix.o framesync.o +OBJS-$(CONFIG_MONOCHROME_FILTER) += vf_monochrome.o OBJS-$(CONFIG_MPDECIMATE_FILTER) += vf_mpdecimate.o OBJS-$(CONFIG_NEGATE_FILTER) += vf_lut.o OBJS-$(CONFIG_NLMEANS_FILTER) += vf_nlmeans.o @@ -343,8 +364,8 @@ OBJS-$(CONFIG_PHASE_FILTER) += vf_phase.o OBJS-$(CONFIG_PHOTOSENSITIVITY_FILTER) += vf_photosensitivity.o OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o OBJS-$(CONFIG_PIXSCOPE_FILTER) += vf_datascope.o -OBJS-$(CONFIG_PP_FILTER) += vf_pp.o -OBJS-$(CONFIG_PP7_FILTER) += vf_pp7.o +OBJS-$(CONFIG_PP_FILTER) += vf_pp.o qp_table.o +OBJS-$(CONFIG_PP7_FILTER) += vf_pp7.o qp_table.o OBJS-$(CONFIG_PREMULTIPLY_FILTER) += vf_premultiply.o framesync.o OBJS-$(CONFIG_PREWITT_FILTER) += vf_convolution.o OBJS-$(CONFIG_PREWITT_OPENCL_FILTER) += vf_convolution_opencl.o opencl.o \ @@ -371,7 +392,8 @@ OBJS-$(CONFIG_ROBERTS_OPENCL_FILTER) += vf_convolution_opencl.o opencl.o OBJS-$(CONFIG_ROTATE_FILTER) += vf_rotate.o OBJS-$(CONFIG_SAB_FILTER) += vf_sab.o OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o scale_eval.o -OBJS-$(CONFIG_SCALE_CUDA_FILTER) += vf_scale_cuda.o vf_scale_cuda.ptx.o scale_eval.o +OBJS-$(CONFIG_SCALE_CUDA_FILTER) += vf_scale_cuda.o scale_eval.o \ + vf_scale_cuda.ptx.o vf_scale_cuda_bicubic.ptx.o OBJS-$(CONFIG_SCALE_NPP_FILTER) += vf_scale_npp.o scale_eval.o OBJS-$(CONFIG_SCALE_QSV_FILTER) += vf_scale_qsv.o OBJS-$(CONFIG_SCALE_VAAPI_FILTER) += vf_scale_vaapi.o scale_eval.o vaapi_vpp.o @@ -391,9 +413,11 @@ OBJS-$(CONFIG_SETRANGE_FILTER) += vf_setparams.o OBJS-$(CONFIG_SETSAR_FILTER) += vf_aspect.o OBJS-$(CONFIG_SETTB_FILTER) += settb.o OBJS-$(CONFIG_SHARPNESS_VAAPI_FILTER) += vf_misc_vaapi.o vaapi_vpp.o +OBJS-$(CONFIG_SHEAR_FILTER) += vf_shear.o OBJS-$(CONFIG_SHOWINFO_FILTER) += vf_showinfo.o OBJS-$(CONFIG_SHOWPALETTE_FILTER) += vf_showpalette.o OBJS-$(CONFIG_SHUFFLEFRAMES_FILTER) += vf_shuffleframes.o +OBJS-$(CONFIG_SHUFFLEPIXELS_FILTER) += vf_shufflepixels.o OBJS-$(CONFIG_SHUFFLEPLANES_FILTER) += vf_shuffleplanes.o OBJS-$(CONFIG_SIDEDATA_FILTER) += f_sidedata.o OBJS-$(CONFIG_SIGNALSTATS_FILTER) += vf_signalstats.o @@ -403,7 +427,7 @@ OBJS-$(CONFIG_SOBEL_FILTER) += vf_convolution.o OBJS-$(CONFIG_SOBEL_OPENCL_FILTER) += vf_convolution_opencl.o opencl.o \ opencl/convolution.o OBJS-$(CONFIG_SPLIT_FILTER) += split.o -OBJS-$(CONFIG_SPP_FILTER) += vf_spp.o +OBJS-$(CONFIG_SPP_FILTER) += vf_spp.o qp_table.o OBJS-$(CONFIG_SR_FILTER) += vf_sr.o OBJS-$(CONFIG_SSIM_FILTER) += vf_ssim.o framesync.o OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o @@ -422,6 +446,7 @@ OBJS-$(CONFIG_TILE_FILTER) += vf_tile.o OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o OBJS-$(CONFIG_TLUT2_FILTER) += vf_lut2.o framesync.o OBJS-$(CONFIG_TMEDIAN_FILTER) += vf_xmedian.o framesync.o +OBJS-$(CONFIG_TMIDEQUALIZER_FILTER) += vf_tmidequalizer.o OBJS-$(CONFIG_TMIX_FILTER) += vf_mix.o framesync.o OBJS-$(CONFIG_TONEMAP_FILTER) += vf_tonemap.o colorspace.o OBJS-$(CONFIG_TONEMAP_OPENCL_FILTER) += vf_tonemap_opencl.o colorspace.o opencl.o \ @@ -438,7 +463,7 @@ OBJS-$(CONFIG_UNSHARP_FILTER) += vf_unsharp.o OBJS-$(CONFIG_UNSHARP_OPENCL_FILTER) += vf_unsharp_opencl.o opencl.o \ opencl/unsharp.o OBJS-$(CONFIG_UNTILE_FILTER) += vf_untile.o -OBJS-$(CONFIG_USPP_FILTER) += vf_uspp.o +OBJS-$(CONFIG_USPP_FILTER) += vf_uspp.o qp_table.o OBJS-$(CONFIG_V360_FILTER) += vf_v360.o OBJS-$(CONFIG_VAGUEDENOISER_FILTER) += vf_vaguedenoiser.o OBJS-$(CONFIG_VECTORSCOPE_FILTER) += vf_vectorscope.o @@ -447,6 +472,7 @@ OBJS-$(CONFIG_VFRDET_FILTER) += vf_vfrdet.o OBJS-$(CONFIG_VIBRANCE_FILTER) += vf_vibrance.o OBJS-$(CONFIG_VIDSTABDETECT_FILTER) += vidstabutils.o vf_vidstabdetect.o OBJS-$(CONFIG_VIDSTABTRANSFORM_FILTER) += vidstabutils.o vf_vidstabtransform.o +OBJS-$(CONFIG_VIF_FILTER) += vf_vif.o framesync.o OBJS-$(CONFIG_VIGNETTE_FILTER) += vf_vignette.o OBJS-$(CONFIG_VMAFMOTION_FILTER) += vf_vmafmotion.o framesync.o OBJS-$(CONFIG_VPP_QSV_FILTER) += vf_vpp_qsv.o @@ -534,7 +560,7 @@ TESTPROGS = drawutils filtfmts formats integral TOOLS-$(CONFIG_LIBZMQ) += zmqsend clean:: - $(RM) $(CLEANSUFFIXES:%=libavfilter/dnn/%) + $(RM) $(CLEANSUFFIXES:%=libavfilter/dnn/%) $(CLEANSUFFIXES:%=libavfilter/opencl/%) OPENCL = $(subst $(SRC_PATH)/,,$(wildcard $(SRC_PATH)/libavfilter/opencl/*.cl)) .SECONDARY: $(OPENCL:.cl=.c) diff --git a/libavfilter/aeval.c b/libavfilter/aeval.c index 32cd6de04..d5437431a 100644 --- a/libavfilter/aeval.c +++ b/libavfilter/aeval.c @@ -258,7 +258,7 @@ static int query_formats(AVFilterContext *ctx) if (ret < 0) return ret; - layouts = avfilter_make_format64_list(chlayouts); + layouts = ff_make_format64_list(chlayouts); if (!layouts) return AVERROR(ENOMEM); ret = ff_set_common_channel_layouts(ctx, layouts); @@ -362,7 +362,7 @@ static int aeval_query_formats(AVFilterContext *ctx) // inlink supports any channel layout layouts = ff_all_channel_counts(); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; if (eval->same_chlayout) { @@ -376,7 +376,7 @@ static int aeval_query_formats(AVFilterContext *ctx) eval->out_channel_layout ? eval->out_channel_layout : FF_COUNT2LAYOUT(eval->nb_channels))) < 0) return ret; - if ((ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts)) < 0) return ret; } @@ -416,8 +416,6 @@ static int aeval_config_output(AVFilterLink *outlink) return 0; } -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *in) { EvalContext *eval = inlink->dst->priv; @@ -485,6 +483,7 @@ AVFilter ff_af_aeval = { .inputs = aeval_inputs, .outputs = aeval_outputs, .priv_class = &aeval_class, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; #endif /* CONFIG_AEVAL_FILTER */ diff --git a/libavfilter/af_acrossover.c b/libavfilter/af_acrossover.c index 002f378c3..03a7ae111 100644 --- a/libavfilter/af_acrossover.c +++ b/libavfilter/af_acrossover.c @@ -27,6 +27,7 @@ #include "libavutil/avstring.h" #include "libavutil/channel_layout.h" #include "libavutil/eval.h" +#include "libavutil/float_dsp.h" #include "libavutil/internal.h" #include "libavutil/opt.h" @@ -38,32 +39,46 @@ #define MAX_SPLITS 16 #define MAX_BANDS MAX_SPLITS + 1 -typedef struct BiquadContext { - double a0, a1, a2; - double b1, b2; - double i1, i2; - double o1, o2; -} BiquadContext; +#define B0 0 +#define B1 1 +#define B2 2 +#define A1 3 +#define A2 4 -typedef struct CrossoverChannel { - BiquadContext lp[MAX_BANDS][4]; - BiquadContext hp[MAX_BANDS][4]; -} CrossoverChannel; +typedef struct BiquadCoeffs { + double cd[5]; + float cf[5]; +} BiquadCoeffs; typedef struct AudioCrossoverContext { const AVClass *class; char *splits_str; + char *gains_str; + int order_opt; + float level_in; + int order; - int filter_count; + int first_order; + int ap_filter_count; int nb_splits; - float *splits; + float splits[MAX_SPLITS]; - CrossoverChannel *xover; + float gains[MAX_BANDS]; + + BiquadCoeffs lp[MAX_BANDS][20]; + BiquadCoeffs hp[MAX_BANDS][20]; + BiquadCoeffs ap[MAX_BANDS][20]; + + AVFrame *xover; AVFrame *input_frame; AVFrame *frames[MAX_BANDS]; + + int (*filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); + + AVFloatDSPContext *fdsp; } AudioCrossoverContext; #define OFFSET(x) offsetof(AudioCrossoverContext, x) @@ -71,23 +86,67 @@ typedef struct AudioCrossoverContext { static const AVOption acrossover_options[] = { { "split", "set split frequencies", OFFSET(splits_str), AV_OPT_TYPE_STRING, {.str="500"}, 0, 0, AF }, - { "order", "set order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=1}, 0, 2, AF, "m" }, - { "2nd", "2nd order", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" }, - { "4th", "4th order", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" }, - { "8th", "8th order", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "m" }, + { "order", "set filter order", OFFSET(order_opt), AV_OPT_TYPE_INT, {.i64=1}, 0, 9, AF, "m" }, + { "2nd", "2nd order (12 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" }, + { "4th", "4th order (24 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" }, + { "6th", "6th order (36 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "m" }, + { "8th", "8th order (48 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "m" }, + { "10th", "10th order (60 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF, "m" }, + { "12th", "12th order (72 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=5}, 0, 0, AF, "m" }, + { "14th", "14th order (84 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=6}, 0, 0, AF, "m" }, + { "16th", "16th order (96 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=7}, 0, 0, AF, "m" }, + { "18th", "18th order (108 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=8}, 0, 0, AF, "m" }, + { "20th", "20th order (120 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=9}, 0, 0, AF, "m" }, + { "level", "set input gain", OFFSET(level_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, AF }, + { "gain", "set output bands gain", OFFSET(gains_str), AV_OPT_TYPE_STRING, {.str="1.f"}, 0, 0, AF }, { NULL } }; AVFILTER_DEFINE_CLASS(acrossover); +static int parse_gains(AVFilterContext *ctx) +{ + AudioCrossoverContext *s = ctx->priv; + char *p, *arg, *saveptr = NULL; + int i, ret = 0; + + saveptr = NULL; + p = s->gains_str; + for (i = 0; i < MAX_BANDS; i++) { + float gain; + char c[3] = { 0 }; + + if (!(arg = av_strtok(p, " |", &saveptr))) + break; + + p = NULL; + + if (av_sscanf(arg, "%f%2s", &gain, c) < 1) { + av_log(ctx, AV_LOG_ERROR, "Invalid syntax for gain[%d].\n", i); + ret = AVERROR(EINVAL); + break; + } + + if (c[0] == 'd' && c[1] == 'B') + s->gains[i] = expf(gain * M_LN10 / 20.f); + else + s->gains[i] = gain; + } + + for (; i < MAX_BANDS; i++) + s->gains[i] = 1.f; + + return ret; +} + static av_cold int init(AVFilterContext *ctx) { AudioCrossoverContext *s = ctx->priv; char *p, *arg, *saveptr = NULL; int i, ret = 0; - s->splits = av_calloc(MAX_SPLITS, sizeof(*s->splits)); - if (!s->splits) + s->fdsp = avpriv_float_dsp_alloc(0); + if (!s->fdsp) return AVERROR(ENOMEM); p = s->splits_str; @@ -118,6 +177,10 @@ static av_cold int init(AVFilterContext *ctx) s->nb_splits = i; + ret = parse_gains(ctx); + if (ret < 0) + return ret; + for (i = 0; i <= s->nb_splits; i++) { AVFilterPad pad = { 0 }; char *name; @@ -137,82 +200,107 @@ static av_cold int init(AVFilterContext *ctx) return ret; } -static void set_lp(BiquadContext *b, double fc, double q, double sr) +static void set_lp(BiquadCoeffs *b, double fc, double q, double sr) { - double omega = 2.0 * M_PI * fc / sr; - double sn = sin(omega); - double cs = cos(omega); - double alpha = sn / (2. * q); - double inv = 1.0 / (1.0 + alpha); + double omega = 2. * M_PI * fc / sr; + double cosine = cos(omega); + double alpha = sin(omega) / (2. * q); - b->a0 = (1. - cs) * 0.5 * inv; - b->a1 = (1. - cs) * inv; - b->a2 = b->a0; - b->b1 = -2. * cs * inv; - b->b2 = (1. - alpha) * inv; + double b0 = (1. - cosine) / 2.; + double b1 = 1. - cosine; + double b2 = (1. - cosine) / 2.; + double a0 = 1. + alpha; + double a1 = -2. * cosine; + double a2 = 1. - alpha; + + b->cd[B0] = b0 / a0; + b->cd[B1] = b1 / a0; + b->cd[B2] = b2 / a0; + b->cd[A1] = -a1 / a0; + b->cd[A2] = -a2 / a0; + + b->cf[B0] = b->cd[B0]; + b->cf[B1] = b->cd[B1]; + b->cf[B2] = b->cd[B2]; + b->cf[A1] = b->cd[A1]; + b->cf[A2] = b->cd[A2]; } -static void set_hp(BiquadContext *b, double fc, double q, double sr) +static void set_hp(BiquadCoeffs *b, double fc, double q, double sr) { - double omega = 2 * M_PI * fc / sr; - double sn = sin(omega); - double cs = cos(omega); - double alpha = sn / (2 * q); - double inv = 1.0 / (1.0 + alpha); + double omega = 2. * M_PI * fc / sr; + double cosine = cos(omega); + double alpha = sin(omega) / (2. * q); - b->a0 = inv * (1. + cs) / 2.; - b->a1 = -2. * b->a0; - b->a2 = b->a0; - b->b1 = -2. * cs * inv; - b->b2 = (1. - alpha) * inv; + double b0 = (1. + cosine) / 2.; + double b1 = -1. - cosine; + double b2 = (1. + cosine) / 2.; + double a0 = 1. + alpha; + double a1 = -2. * cosine; + double a2 = 1. - alpha; + + b->cd[B0] = b0 / a0; + b->cd[B1] = b1 / a0; + b->cd[B2] = b2 / a0; + b->cd[A1] = -a1 / a0; + b->cd[A2] = -a2 / a0; + + b->cf[B0] = b->cd[B0]; + b->cf[B1] = b->cd[B1]; + b->cf[B2] = b->cd[B2]; + b->cf[A1] = b->cd[A1]; + b->cf[A2] = b->cd[A2]; } -static int config_input(AVFilterLink *inlink) +static void set_ap(BiquadCoeffs *b, double fc, double q, double sr) { - AVFilterContext *ctx = inlink->dst; - AudioCrossoverContext *s = ctx->priv; - int ch, band, sample_rate = inlink->sample_rate; - double q; + double omega = 2. * M_PI * fc / sr; + double cosine = cos(omega); + double alpha = sin(omega) / (2. * q); - s->xover = av_calloc(inlink->channels, sizeof(*s->xover)); - if (!s->xover) - return AVERROR(ENOMEM); + double a0 = 1. + alpha; + double a1 = -2. * cosine; + double a2 = 1. - alpha; + double b0 = a2; + double b1 = a1; + double b2 = a0; - switch (s->order) { - case 0: - q = 0.5; - s->filter_count = 1; - break; - case 1: - q = M_SQRT1_2; - s->filter_count = 2; - break; - case 2: - q = 0.54; - s->filter_count = 4; - break; - } + b->cd[B0] = b0 / a0; + b->cd[B1] = b1 / a0; + b->cd[B2] = b2 / a0; + b->cd[A1] = -a1 / a0; + b->cd[A2] = -a2 / a0; - for (ch = 0; ch < inlink->channels; ch++) { - for (band = 0; band <= s->nb_splits; band++) { - set_lp(&s->xover[ch].lp[band][0], s->splits[band], q, sample_rate); - set_hp(&s->xover[ch].hp[band][0], s->splits[band], q, sample_rate); + b->cf[B0] = b->cd[B0]; + b->cf[B1] = b->cd[B1]; + b->cf[B2] = b->cd[B2]; + b->cf[A1] = b->cd[A1]; + b->cf[A2] = b->cd[A2]; +} - if (s->order > 1) { - set_lp(&s->xover[ch].lp[band][1], s->splits[band], 1.34, sample_rate); - set_hp(&s->xover[ch].hp[band][1], s->splits[band], 1.34, sample_rate); - set_lp(&s->xover[ch].lp[band][2], s->splits[band], q, sample_rate); - set_hp(&s->xover[ch].hp[band][2], s->splits[band], q, sample_rate); - set_lp(&s->xover[ch].lp[band][3], s->splits[band], 1.34, sample_rate); - set_hp(&s->xover[ch].hp[band][3], s->splits[band], 1.34, sample_rate); - } else { - set_lp(&s->xover[ch].lp[band][1], s->splits[band], q, sample_rate); - set_hp(&s->xover[ch].hp[band][1], s->splits[band], q, sample_rate); - } - } - } +static void set_ap1(BiquadCoeffs *b, double fc, double sr) +{ + double omega = 2. * M_PI * fc / sr; - return 0; + b->cd[A1] = exp(-omega); + b->cd[A2] = 0.; + b->cd[B0] = -b->cd[A1]; + b->cd[B1] = 1.; + b->cd[B2] = 0.; + + b->cf[B0] = b->cd[B0]; + b->cf[B1] = b->cd[B1]; + b->cf[B2] = b->cd[B2]; + b->cf[A1] = b->cd[A1]; + b->cf[A2] = b->cd[A2]; +} + +static void calc_q_factors(int order, double *q) +{ + double n = order / 2.; + + for (int i = 0; i < n / 2; i++) + q[i] = 1. / (-2. * cos(M_PI * (2. * (i + 1) + n - 1.) / (2. * n))); } static int query_formats(AVFilterContext *ctx) @@ -220,7 +308,7 @@ static int query_formats(AVFilterContext *ctx) AVFilterFormats *formats; AVFilterChannelLayouts *layouts; static const enum AVSampleFormat sample_fmts[] = { - AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE }; int ret; @@ -245,56 +333,176 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_samplerates(ctx, formats); } -static double biquad_process(BiquadContext *b, double in) -{ - double out = in * b->a0 + b->i1 * b->a1 + b->i2 * b->a2 - b->o1 * b->b1 - b->o2 * b->b2; - - b->i2 = b->i1; - b->o2 = b->o1; - b->i1 = in; - b->o1 = out; - - return out; +#define BIQUAD_PROCESS(name, type) \ +static void biquad_process_## name(const type *const c, \ + type *b, \ + type *dst, const type *src, \ + int nb_samples) \ +{ \ + const type b0 = c[B0]; \ + const type b1 = c[B1]; \ + const type b2 = c[B2]; \ + const type a1 = c[A1]; \ + const type a2 = c[A2]; \ + type z1 = b[0]; \ + type z2 = b[1]; \ + \ + for (int n = 0; n + 1 < nb_samples; n++) { \ + type in = src[n]; \ + type out; \ + \ + out = in * b0 + z1; \ + z1 = b1 * in + z2 + a1 * out; \ + z2 = b2 * in + a2 * out; \ + dst[n] = out; \ + \ + n++; \ + in = src[n]; \ + out = in * b0 + z1; \ + z1 = b1 * in + z2 + a1 * out; \ + z2 = b2 * in + a2 * out; \ + dst[n] = out; \ + } \ + \ + if (nb_samples & 1) { \ + const int n = nb_samples - 1; \ + const type in = src[n]; \ + type out; \ + \ + out = in * b0 + z1; \ + z1 = b1 * in + z2 + a1 * out; \ + z2 = b2 * in + a2 * out; \ + dst[n] = out; \ + } \ + \ + b[0] = z1; \ + b[1] = z2; \ } -static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +BIQUAD_PROCESS(fltp, float) +BIQUAD_PROCESS(dblp, double) + +#define XOVER_PROCESS(name, type, one, ff) \ +static int filter_channels_## name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ +{ \ + AudioCrossoverContext *s = ctx->priv; \ + AVFrame *in = s->input_frame; \ + AVFrame **frames = s->frames; \ + const int start = (in->channels * jobnr) / nb_jobs; \ + const int end = (in->channels * (jobnr+1)) / nb_jobs; \ + const int nb_samples = in->nb_samples; \ + const int nb_outs = ctx->nb_outputs; \ + const int first_order = s->first_order; \ + \ + for (int ch = start; ch < end; ch++) { \ + const type *src = (const type *)in->extended_data[ch]; \ + type *xover = (type *)s->xover->extended_data[ch]; \ + \ + s->fdsp->vector_## ff ##mul_scalar((type *)frames[0]->extended_data[ch], src, \ + s->level_in, FFALIGN(nb_samples, sizeof(type))); \ + \ + for (int band = 0; band < nb_outs; band++) { \ + for (int f = 0; band + 1 < nb_outs && f < s->filter_count; f++) { \ + const type *prv = (const type *)frames[band]->extended_data[ch]; \ + type *dst = (type *)frames[band + 1]->extended_data[ch]; \ + const type *hsrc = f == 0 ? prv : dst; \ + type *hp = xover + nb_outs * 20 + band * 20 + f * 2; \ + const type *const hpc = (type *)&s->hp[band][f].c ## ff; \ + \ + biquad_process_## name(hpc, hp, dst, hsrc, nb_samples); \ + } \ + \ + for (int f = 0; band + 1 < nb_outs && f < s->filter_count; f++) { \ + type *dst = (type *)frames[band]->extended_data[ch]; \ + const type *lsrc = dst; \ + type *lp = xover + band * 20 + f * 2; \ + const type *const lpc = (type *)&s->lp[band][f].c ## ff; \ + \ + biquad_process_## name(lpc, lp, dst, lsrc, nb_samples); \ + } \ + \ + for (int aband = band + 1; aband + 1 < nb_outs; aband++) { \ + if (first_order) { \ + const type *asrc = (const type *)frames[band]->extended_data[ch]; \ + type *dst = (type *)frames[band]->extended_data[ch]; \ + type *ap = xover + nb_outs * 40 + (aband * nb_outs + band) * 20; \ + const type *const apc = (type *)&s->ap[aband][0].c ## ff; \ + \ + biquad_process_## name(apc, ap, dst, asrc, nb_samples); \ + } \ + \ + for (int f = first_order; f < s->ap_filter_count; f++) { \ + const type *asrc = (const type *)frames[band]->extended_data[ch]; \ + type *dst = (type *)frames[band]->extended_data[ch]; \ + type *ap = xover + nb_outs * 40 + (aband * nb_outs + band) * 20 + f * 2;\ + const type *const apc = (type *)&s->ap[aband][f].c ## ff; \ + \ + biquad_process_## name(apc, ap, dst, asrc, nb_samples); \ + } \ + } \ + } \ + \ + for (int band = 0; band < nb_outs; band++) { \ + const type gain = s->gains[band] * ((band & 1 && first_order) ? -one : one); \ + type *dst = (type *)frames[band]->extended_data[ch]; \ + \ + s->fdsp->vector_## ff ##mul_scalar(dst, dst, gain, \ + FFALIGN(nb_samples, sizeof(type))); \ + } \ + } \ + \ + return 0; \ +} + +XOVER_PROCESS(fltp, float, 1.f, f) +XOVER_PROCESS(dblp, double, 1.0, d) + +static int config_input(AVFilterLink *inlink) { + AVFilterContext *ctx = inlink->dst; AudioCrossoverContext *s = ctx->priv; - AVFrame *in = s->input_frame; - AVFrame **frames = s->frames; - const int start = (in->channels * jobnr) / nb_jobs; - const int end = (in->channels * (jobnr+1)) / nb_jobs; - int f, band; + int sample_rate = inlink->sample_rate; + double q[16]; - for (int ch = start; ch < end; ch++) { - const double *src = (const double *)in->extended_data[ch]; - CrossoverChannel *xover = &s->xover[ch]; + s->order = (s->order_opt + 1) * 2; + s->filter_count = s->order / 2; + s->first_order = s->filter_count & 1; + s->ap_filter_count = s->filter_count / 2 + s->first_order; + calc_q_factors(s->order, q); - for (int i = 0; i < in->nb_samples; i++) { - double sample = src[i], lo, hi; + for (int band = 0; band <= s->nb_splits; band++) { + if (s->first_order) { + set_lp(&s->lp[band][0], s->splits[band], 0.5, sample_rate); + set_hp(&s->hp[band][0], s->splits[band], 0.5, sample_rate); + } - for (band = 0; band < ctx->nb_outputs; band++) { - double *dst = (double *)frames[band]->extended_data[ch]; + for (int n = s->first_order; n < s->filter_count; n++) { + const int idx = s->filter_count / 2 - ((n + s->first_order) / 2 - s->first_order) - 1; - lo = sample; - hi = sample; - for (f = 0; band + 1 < ctx->nb_outputs && f < s->filter_count; f++) { - BiquadContext *lp = &xover->lp[band][f]; - lo = biquad_process(lp, lo); - } + set_lp(&s->lp[band][n], s->splits[band], q[idx], sample_rate); + set_hp(&s->hp[band][n], s->splits[band], q[idx], sample_rate); + } - for (f = 0; band + 1 < ctx->nb_outputs && f < s->filter_count; f++) { - BiquadContext *hp = &xover->hp[band][f]; - hi = biquad_process(hp, hi); - } + if (s->first_order) + set_ap1(&s->ap[band][0], s->splits[band], sample_rate); - dst[i] = lo; + for (int n = s->first_order; n < s->ap_filter_count; n++) { + const int idx = (s->filter_count / 2 - ((n * 2 + s->first_order) / 2 - s->first_order) - 1); - sample = hi; - } + set_ap(&s->ap[band][n], s->splits[band], q[idx], sample_rate); } } + switch (inlink->format) { + case AV_SAMPLE_FMT_FLTP: s->filter_channels = filter_channels_fltp; break; + case AV_SAMPLE_FMT_DBLP: s->filter_channels = filter_channels_dblp; break; + } + + s->xover = ff_get_audio_buffer(inlink, 2 * (ctx->nb_outputs * 10 + ctx->nb_outputs * 10 + + ctx->nb_outputs * ctx->nb_outputs * 10)); + if (!s->xover) + return AVERROR(ENOMEM); + return 0; } @@ -320,8 +528,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) goto fail; s->input_frame = in; - ctx->internal->execute(ctx, filter_channels, NULL, NULL, FFMIN(inlink->channels, - ff_filter_get_nb_threads(ctx))); + ctx->internal->execute(ctx, s->filter_channels, NULL, NULL, FFMIN(inlink->channels, + ff_filter_get_nb_threads(ctx))); for (i = 0; i < ctx->nb_outputs; i++) { ret = ff_filter_frame(ctx->outputs[i], frames[i]); @@ -344,8 +552,8 @@ static av_cold void uninit(AVFilterContext *ctx) AudioCrossoverContext *s = ctx->priv; int i; - av_freep(&s->splits); - av_freep(&s->xover); + av_freep(&s->fdsp); + av_frame_free(&s->xover); for (i = 0; i < ctx->nb_outputs; i++) av_freep(&ctx->output_pads[i].name); diff --git a/libavfilter/af_acrusher.c b/libavfilter/af_acrusher.c index ddce74465..d3c31c20b 100644 --- a/libavfilter/af_acrusher.c +++ b/libavfilter/af_acrusher.c @@ -68,7 +68,7 @@ typedef struct ACrusherContext { } ACrusherContext; #define OFFSET(x) offsetof(ACrusherContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption acrusher_options[] = { { "level_in", "set level in", OFFSET(level_in), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, @@ -325,13 +325,27 @@ static int config_input(AVFilterLink *inlink) s->lfo.srate = inlink->sample_rate; s->lfo.amount = .5; - s->sr = av_calloc(inlink->channels, sizeof(*s->sr)); + if (!s->sr) + s->sr = av_calloc(inlink->channels, sizeof(*s->sr)); if (!s->sr) return AVERROR(ENOMEM); return 0; } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + AVFilterLink *inlink = ctx->inputs[0]; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_input(inlink); +} + static const AVFilterPad avfilter_af_acrusher_inputs[] = { { .name = "default", @@ -359,4 +373,5 @@ AVFilter ff_af_acrusher = { .query_formats = query_formats, .inputs = avfilter_af_acrusher_inputs, .outputs = avfilter_af_acrusher_outputs, + .process_command = process_command, }; diff --git a/libavfilter/af_adeclick.c b/libavfilter/af_adeclick.c index e86a1f7be..c8a41cd60 100644 --- a/libavfilter/af_adeclick.c +++ b/libavfilter/af_adeclick.c @@ -92,13 +92,21 @@ typedef struct AudioDeclickContext { #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM static const AVOption adeclick_options[] = { + { "window", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF }, { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF }, + { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF }, { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF }, + { "arorder", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 25, AF }, { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 25, AF }, + { "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 1, 100, AF }, { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 1, 100, AF }, + { "burst", "set burst fusion", OFFSET(burst), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 10, AF }, { "b", "set burst fusion", OFFSET(burst), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 10, AF }, + { "method", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" }, { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" }, + { "add", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" }, { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" }, + { "save", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" }, { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" }, { NULL } }; @@ -769,14 +777,22 @@ AVFilter ff_af_adeclick = { }; static const AVOption adeclip_options[] = { - { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF }, - { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF }, - { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF }, - { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF }, - { "n", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF }, - { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" }, - { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" }, - { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" }, + { "window", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF }, + { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF }, + { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF }, + { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF }, + { "arorder", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF }, + { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF }, + { "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF }, + { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF }, + { "hsize", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF }, + { "n", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF }, + { "method", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" }, + { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" }, + { "add", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" }, + { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" }, + { "save", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" }, + { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" }, { NULL } }; diff --git a/libavfilter/af_adenorm.c b/libavfilter/af_adenorm.c new file mode 100644 index 000000000..992a1fe56 --- /dev/null +++ b/libavfilter/af_adenorm.c @@ -0,0 +1,332 @@ +/* + * 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/avassert.h" +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "audio.h" +#include "avfilter.h" +#include "internal.h" + +enum FilterType { + DC_TYPE, + AC_TYPE, + SQ_TYPE, + PS_TYPE, + NB_TYPES, +}; + +typedef struct ADenormContext { + const AVClass *class; + + double level; + double level_db; + int type; + int64_t in_samples; + + void (*filter)(AVFilterContext *ctx, void *dst, + const void *src, int nb_samples); +} ADenormContext; + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats = NULL; + AVFilterChannelLayouts *layouts = NULL; + static const enum AVSampleFormat sample_fmts[] = { + AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_NONE + }; + int ret; + + formats = ff_make_format_list(sample_fmts); + if (!formats) + return AVERROR(ENOMEM); + ret = ff_set_common_formats(ctx, formats); + if (ret < 0) + return ret; + + layouts = ff_all_channel_counts(); + if (!layouts) + return AVERROR(ENOMEM); + + ret = ff_set_common_channel_layouts(ctx, layouts); + if (ret < 0) + return ret; + + formats = ff_all_samplerates(); + return ff_set_common_samplerates(ctx, formats); +} + +static void dc_denorm_fltp(AVFilterContext *ctx, void *dstp, + const void *srcp, int nb_samples) +{ + ADenormContext *s = ctx->priv; + const float *src = (const float *)srcp; + float *dst = (float *)dstp; + const float dc = s->level; + + for (int n = 0; n < nb_samples; n++) { + dst[n] = src[n] + dc; + } +} + +static void dc_denorm_dblp(AVFilterContext *ctx, void *dstp, + const void *srcp, int nb_samples) +{ + ADenormContext *s = ctx->priv; + const double *src = (const double *)srcp; + double *dst = (double *)dstp; + const double dc = s->level; + + for (int n = 0; n < nb_samples; n++) { + dst[n] = src[n] + dc; + } +} + +static void ac_denorm_fltp(AVFilterContext *ctx, void *dstp, + const void *srcp, int nb_samples) +{ + ADenormContext *s = ctx->priv; + const float *src = (const float *)srcp; + float *dst = (float *)dstp; + const float dc = s->level; + const int64_t N = s->in_samples; + + for (int n = 0; n < nb_samples; n++) { + dst[n] = src[n] + dc * (((N + n) & 1) ? -1.f : 1.f); + } +} + +static void ac_denorm_dblp(AVFilterContext *ctx, void *dstp, + const void *srcp, int nb_samples) +{ + ADenormContext *s = ctx->priv; + const double *src = (const double *)srcp; + double *dst = (double *)dstp; + const double dc = s->level; + const int64_t N = s->in_samples; + + for (int n = 0; n < nb_samples; n++) { + dst[n] = src[n] + dc * (((N + n) & 1) ? -1. : 1.); + } +} + +static void sq_denorm_fltp(AVFilterContext *ctx, void *dstp, + const void *srcp, int nb_samples) +{ + ADenormContext *s = ctx->priv; + const float *src = (const float *)srcp; + float *dst = (float *)dstp; + const float dc = s->level; + const int64_t N = s->in_samples; + + for (int n = 0; n < nb_samples; n++) { + dst[n] = src[n] + dc * ((((N + n) >> 8) & 1) ? -1.f : 1.f); + } +} + +static void sq_denorm_dblp(AVFilterContext *ctx, void *dstp, + const void *srcp, int nb_samples) +{ + ADenormContext *s = ctx->priv; + const double *src = (const double *)srcp; + double *dst = (double *)dstp; + const double dc = s->level; + const int64_t N = s->in_samples; + + for (int n = 0; n < nb_samples; n++) { + dst[n] = src[n] + dc * ((((N + n) >> 8) & 1) ? -1. : 1.); + } +} + +static void ps_denorm_fltp(AVFilterContext *ctx, void *dstp, + const void *srcp, int nb_samples) +{ + ADenormContext *s = ctx->priv; + const float *src = (const float *)srcp; + float *dst = (float *)dstp; + const float dc = s->level; + const int64_t N = s->in_samples; + + for (int n = 0; n < nb_samples; n++) { + dst[n] = src[n] + dc * (((N + n) & 255) ? 0.f : 1.f); + } +} + +static void ps_denorm_dblp(AVFilterContext *ctx, void *dstp, + const void *srcp, int nb_samples) +{ + ADenormContext *s = ctx->priv; + const double *src = (const double *)srcp; + double *dst = (double *)dstp; + const double dc = s->level; + const int64_t N = s->in_samples; + + for (int n = 0; n < nb_samples; n++) { + dst[n] = src[n] + dc * (((N + n) & 255) ? 0. : 1.); + } +} + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + ADenormContext *s = ctx->priv; + + switch (s->type) { + case DC_TYPE: + switch (outlink->format) { + case AV_SAMPLE_FMT_FLTP: s->filter = dc_denorm_fltp; break; + case AV_SAMPLE_FMT_DBLP: s->filter = dc_denorm_dblp; break; + } + break; + case AC_TYPE: + switch (outlink->format) { + case AV_SAMPLE_FMT_FLTP: s->filter = ac_denorm_fltp; break; + case AV_SAMPLE_FMT_DBLP: s->filter = ac_denorm_dblp; break; + } + break; + case SQ_TYPE: + switch (outlink->format) { + case AV_SAMPLE_FMT_FLTP: s->filter = sq_denorm_fltp; break; + case AV_SAMPLE_FMT_DBLP: s->filter = sq_denorm_dblp; break; + } + break; + case PS_TYPE: + switch (outlink->format) { + case AV_SAMPLE_FMT_FLTP: s->filter = ps_denorm_fltp; break; + case AV_SAMPLE_FMT_DBLP: s->filter = ps_denorm_dblp; break; + } + break; + default: + av_assert0(0); + } + + return 0; +} + +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ADenormContext *s = ctx->priv; + ThreadData *td = arg; + AVFrame *out = td->out; + AVFrame *in = td->in; + const int start = (in->channels * jobnr) / nb_jobs; + const int end = (in->channels * (jobnr+1)) / nb_jobs; + + for (int ch = start; ch < end; ch++) { + s->filter(ctx, out->extended_data[ch], + in->extended_data[ch], + in->nb_samples); + } + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + ADenormContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + ThreadData td; + AVFrame *out; + + if (av_frame_is_writable(in)) { + out = in; + } else { + out = ff_get_audio_buffer(outlink, in->nb_samples); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + } + + s->level = exp(s->level_db / 20. * M_LN10); + td.in = in; td.out = out; + ctx->internal->execute(ctx, filter_channels, &td, NULL, FFMIN(inlink->channels, + ff_filter_get_nb_threads(ctx))); + + s->in_samples += in->nb_samples; + + if (out != in) + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + AVFilterLink *outlink = ctx->outputs[0]; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_output(outlink); +} + +static const AVFilterPad adenorm_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad adenorm_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .config_props = config_output, + }, + { NULL } +}; + +#define OFFSET(x) offsetof(ADenormContext, x) +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption adenorm_options[] = { + { "level", "set level", OFFSET(level_db), AV_OPT_TYPE_DOUBLE, {.dbl=-351}, -451, -90, FLAGS }, + { "type", "set type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=DC_TYPE}, 0, NB_TYPES-1, FLAGS, "type" }, + { "dc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=DC_TYPE}, 0, 0, FLAGS, "type"}, + { "ac", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AC_TYPE}, 0, 0, FLAGS, "type"}, + { "square",NULL, 0, AV_OPT_TYPE_CONST, {.i64=SQ_TYPE}, 0, 0, FLAGS, "type"}, + { "pulse", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PS_TYPE}, 0, 0, FLAGS, "type"}, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(adenorm); + +AVFilter ff_af_adenorm = { + .name = "adenorm", + .description = NULL_IF_CONFIG_SMALL("Remedy denormals by adding extremely low-level noise."), + .query_formats = query_formats, + .priv_size = sizeof(ADenormContext), + .inputs = adenorm_inputs, + .outputs = adenorm_outputs, + .priv_class = &adenorm_class, + .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | + AVFILTER_FLAG_SLICE_THREADS, +}; diff --git a/libavfilter/af_aemphasis.c b/libavfilter/af_aemphasis.c index e1fa93aff..50999572c 100644 --- a/libavfilter/af_aemphasis.c +++ b/libavfilter/af_aemphasis.c @@ -27,13 +27,9 @@ typedef struct BiquadCoeffs { double a0, a1, a2, b1, b2; } BiquadCoeffs; -typedef struct BiquadD2 { - double a0, a1, a2, b1, b2, w1, w2; -} BiquadD2; - typedef struct RIAACurve { - BiquadD2 r1; - BiquadD2 brickw; + BiquadCoeffs r1; + BiquadCoeffs brickw; int use_brickw; } RIAACurve; @@ -42,11 +38,13 @@ typedef struct AudioEmphasisContext { int mode, type; double level_in, level_out; - RIAACurve *rc; + RIAACurve rc; + + AVFrame *w; } AudioEmphasisContext; #define OFFSET(x) offsetof(AudioEmphasisContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption aemphasis_options[] = { { "level_in", "set input gain", OFFSET(level_in), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 64, FLAGS }, @@ -69,29 +67,69 @@ static const AVOption aemphasis_options[] = { AVFILTER_DEFINE_CLASS(aemphasis); -static inline double biquad(BiquadD2 *bq, double in) +static inline void biquad_process(BiquadCoeffs *bq, double *dst, const double *src, int nb_samples, + double *w, double level_in, double level_out) { - double n = in; - double tmp = n - bq->w1 * bq->b1 - bq->w2 * bq->b2; - double out = tmp * bq->a0 + bq->w1 * bq->a1 + bq->w2 * bq->a2; + const double a0 = bq->a0; + const double a1 = bq->a1; + const double a2 = bq->a2; + const double b1 = bq->b1; + const double b2 = bq->b2; + double w1 = w[0]; + double w2 = w[1]; - bq->w2 = bq->w1; - bq->w1 = tmp; + for (int i = 0; i < nb_samples; i++) { + double n = src[i] * level_in; + double tmp = n - w1 * b1 - w2 * b2; + double out = tmp * a0 + w1 * a1 + w2 * a2; - return out; + w2 = w1; + w1 = tmp; + + dst[i] = out * level_out; + } + + w[0] = w1; + w[1] = w2; +} + +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + AudioEmphasisContext *s = ctx->priv; + const double level_out = s->level_out; + const double level_in = s->level_in; + ThreadData *td = arg; + AVFrame *out = td->out; + AVFrame *in = td->in; + const int start = (in->channels * jobnr) / nb_jobs; + const int end = (in->channels * (jobnr+1)) / nb_jobs; + + for (int ch = start; ch < end; ch++) { + const double *src = (const double *)in->extended_data[ch]; + double *w = (double *)s->w->extended_data[ch]; + double *dst = (double *)out->extended_data[ch]; + + if (s->rc.use_brickw) { + biquad_process(&s->rc.brickw, dst, src, in->nb_samples, w + 2, level_in, 1.); + biquad_process(&s->rc.r1, dst, dst, in->nb_samples, w, 1., level_out); + } else { + biquad_process(&s->rc.r1, dst, src, in->nb_samples, w, level_in, level_out); + } + } + + return 0; } static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; - AudioEmphasisContext *s = ctx->priv; - const double *src = (const double *)in->data[0]; - const double level_out = s->level_out; - const double level_in = s->level_in; + ThreadData td; AVFrame *out; - double *dst; - int n, c; if (av_frame_is_writable(in)) { out = in; @@ -103,14 +141,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } av_frame_copy_props(out, in); } - dst = (double *)out->data[0]; - for (n = 0; n < in->nb_samples; n++) { - for (c = 0; c < inlink->channels; c++) - dst[c] = level_out * biquad(&s->rc[c].r1, s->rc[c].use_brickw ? biquad(&s->rc[c].brickw, src[c] * level_in) : src[c] * level_in); - dst += inlink->channels; - src += inlink->channels; - } + td.in = in; td.out = out; + ctx->internal->execute(ctx, filter_channels, &td, NULL, FFMIN(inlink->channels, + ff_filter_get_nb_threads(ctx))); if (in != out) av_frame_free(&in); @@ -122,7 +156,7 @@ static int query_formats(AVFilterContext *ctx) AVFilterChannelLayouts *layouts; AVFilterFormats *formats; static const enum AVSampleFormat sample_fmts[] = { - AV_SAMPLE_FMT_DBL, + AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE }; int ret; @@ -147,7 +181,7 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_samplerates(ctx, formats); } -static inline void set_highshelf_rbj(BiquadD2 *bq, double freq, double q, double peak, double sr) +static inline void set_highshelf_rbj(BiquadCoeffs *bq, double freq, double q, double peak, double sr) { double A = sqrt(peak); double w0 = freq * 2 * M_PI / sr; @@ -171,7 +205,7 @@ static inline void set_highshelf_rbj(BiquadD2 *bq, double freq, double q, double bq->a2 *= ib0; } -static inline void set_lp_rbj(BiquadD2 *bq, double fc, double q, double sr, double gain) +static inline void set_lp_rbj(BiquadCoeffs *bq, double fc, double q, double sr, double gain) { double omega = 2.0 * M_PI * fc / sr; double sn = sin(omega); @@ -205,10 +239,10 @@ static int config_input(AVFilterLink *inlink) AVFilterContext *ctx = inlink->dst; AudioEmphasisContext *s = ctx->priv; BiquadCoeffs coeffs; - int ch; - s->rc = av_calloc(inlink->channels, sizeof(*s->rc)); - if (!s->rc) + if (!s->w) + s->w = ff_get_audio_buffer(inlink, 4); + if (!s->w) return AVERROR(ENOMEM); switch (s->type) { @@ -282,12 +316,12 @@ static int config_input(AVFilterLink *inlink) if (s->type == 7) q = pow((sr / 4750.0) + 19.5, -0.25); if (s->mode == 0) - set_highshelf_rbj(&s->rc[0].r1, cfreq, q, 1. / gain, sr); + set_highshelf_rbj(&s->rc.r1, cfreq, q, 1. / gain, sr); else - set_highshelf_rbj(&s->rc[0].r1, cfreq, q, gain, sr); - s->rc[0].use_brickw = 0; + set_highshelf_rbj(&s->rc.r1, cfreq, q, gain, sr); + s->rc.use_brickw = 0; } else { - s->rc[0].use_brickw = 1; + s->rc.use_brickw = 1; if (s->mode == 0) { // Reproduction g = 1. / (4.+2.*i*t+2.*k*t+i*k*t*t); a0 = (2.*t+j*t*t)*g; @@ -316,27 +350,36 @@ static int config_input(AVFilterLink *inlink) gain1kHz = freq_gain(&coeffs, 1000.0, sr); // divide one filter's x[n-m] coefficients by that value gc = 1.0 / gain1kHz; - s->rc[0].r1.a0 = coeffs.a0 * gc; - s->rc[0].r1.a1 = coeffs.a1 * gc; - s->rc[0].r1.a2 = coeffs.a2 * gc; - s->rc[0].r1.b1 = coeffs.b1; - s->rc[0].r1.b2 = coeffs.b2; + s->rc.r1.a0 = coeffs.a0 * gc; + s->rc.r1.a1 = coeffs.a1 * gc; + s->rc.r1.a2 = coeffs.a2 * gc; + s->rc.r1.b1 = coeffs.b1; + s->rc.r1.b2 = coeffs.b2; } cutfreq = FFMIN(0.45 * sr, 21000.); - set_lp_rbj(&s->rc[0].brickw, cutfreq, 0.707, sr, 1.); - - for (ch = 1; ch < inlink->channels; ch++) { - memcpy(&s->rc[ch], &s->rc[0], sizeof(RIAACurve)); - } + set_lp_rbj(&s->rc.brickw, cutfreq, 0.707, sr, 1.); return 0; } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_input(ctx->inputs[0]); +} + static av_cold void uninit(AVFilterContext *ctx) { AudioEmphasisContext *s = ctx->priv; - av_freep(&s->rc); + + av_frame_free(&s->w); } static const AVFilterPad avfilter_af_aemphasis_inputs[] = { @@ -366,4 +409,7 @@ AVFilter ff_af_aemphasis = { .query_formats = query_formats, .inputs = avfilter_af_aemphasis_inputs, .outputs = avfilter_af_aemphasis_outputs, + .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | + AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/af_aexciter.c b/libavfilter/af_aexciter.c new file mode 100644 index 000000000..f09c99984 --- /dev/null +++ b/libavfilter/af_aexciter.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) Markus Schmidt and Christian Holschuh + * + * 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/opt.h" +#include "avfilter.h" +#include "internal.h" +#include "audio.h" + +typedef struct ChannelParams { + double blend_old, drive_old; + double rdrive, rbdr, kpa, kpb, kna, knb, ap, + an, imr, kc, srct, sq, pwrq; + double prev_med, prev_out; + + double hp[5], lp[5]; + double hw[4][2], lw[2][2]; +} ChannelParams; + +typedef struct AExciterContext { + const AVClass *class; + + double level_in; + double level_out; + double amount; + double drive; + double blend; + double freq; + double ceil; + int listen; + + ChannelParams *cp; +} AExciterContext; + +#define OFFSET(x) offsetof(AExciterContext, x) +#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption aexciter_options[] = { + { "level_in", "set level in", OFFSET(level_in), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 64, A }, + { "level_out", "set level out", OFFSET(level_out), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 64, A }, + { "amount", "set amount", OFFSET(amount), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 64, A }, + { "drive", "set harmonics", OFFSET(drive), AV_OPT_TYPE_DOUBLE, {.dbl=8.5}, 0.1, 10, A }, + { "blend", "set blend harmonics", OFFSET(blend), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -10, 10, A }, + { "freq", "set scope", OFFSET(freq), AV_OPT_TYPE_DOUBLE, {.dbl=7500}, 2000, 12000, A }, + { "ceil", "set ceiling", OFFSET(ceil), AV_OPT_TYPE_DOUBLE, {.dbl=9999}, 9999, 20000, A }, + { "listen", "enable listen mode", OFFSET(listen), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(aexciter); + +static inline double M(double x) +{ + return (fabs(x) > 0.00000001) ? x : 0.0; +} + +static inline double D(double x) +{ + x = fabs(x); + + return (x > 0.00000001) ? sqrt(x) : 0.0; +} + +static void set_params(ChannelParams *p, + double blend, double drive, + double srate, double freq, + double ceil) +{ + double a0, a1, a2, b0, b1, b2, w0, alpha; + + p->rdrive = 12.0 / drive; + p->rbdr = p->rdrive / (10.5 - blend) * 780.0 / 33.0; + p->kpa = D(2.0 * (p->rdrive*p->rdrive) - 1.0) + 1.0; + p->kpb = (2.0 - p->kpa) / 2.0; + p->ap = ((p->rdrive*p->rdrive) - p->kpa + 1.0) / 2.0; + p->kc = p->kpa / D(2.0 * D(2.0 * (p->rdrive*p->rdrive) - 1.0) - 2.0 * p->rdrive*p->rdrive); + + p->srct = (0.1 * srate) / (0.1 * srate + 1.0); + p->sq = p->kc*p->kc + 1.0; + p->knb = -1.0 * p->rbdr / D(p->sq); + p->kna = 2.0 * p->kc * p->rbdr / D(p->sq); + p->an = p->rbdr*p->rbdr / p->sq; + p->imr = 2.0 * p->knb + D(2.0 * p->kna + 4.0 * p->an - 1.0); + p->pwrq = 2.0 / (p->imr + 1.0); + + w0 = 2 * M_PI * freq / srate; + alpha = sin(w0) / (2. * 0.707); + a0 = 1 + alpha; + a1 = -2 * cos(w0); + a2 = 1 - alpha; + b0 = (1 + cos(w0)) / 2; + b1 = -(1 + cos(w0)); + b2 = (1 + cos(w0)) / 2; + + p->hp[0] =-a1 / a0; + p->hp[1] =-a2 / a0; + p->hp[2] = b0 / a0; + p->hp[3] = b1 / a0; + p->hp[4] = b2 / a0; + + w0 = 2 * M_PI * ceil / srate; + alpha = sin(w0) / (2. * 0.707); + a0 = 1 + alpha; + a1 = -2 * cos(w0); + a2 = 1 - alpha; + b0 = (1 - cos(w0)) / 2; + b1 = 1 - cos(w0); + b2 = (1 - cos(w0)) / 2; + + p->lp[0] =-a1 / a0; + p->lp[1] =-a2 / a0; + p->lp[2] = b0 / a0; + p->lp[3] = b1 / a0; + p->lp[4] = b2 / a0; +} + +static double bprocess(double in, const double *const c, + double *w1, double *w2) +{ + double out = c[2] * in + *w1; + + *w1 = c[3] * in + *w2 + c[0] * out; + *w2 = c[4] * in + c[1] * out; + + return out; +} + +static double distortion_process(AExciterContext *s, ChannelParams *p, double in) +{ + double proc = in, med; + + proc = bprocess(proc, p->hp, &p->hw[0][0], &p->hw[0][1]); + proc = bprocess(proc, p->hp, &p->hw[1][0], &p->hw[1][1]); + + if (proc >= 0.0) { + med = (D(p->ap + proc * (p->kpa - proc)) + p->kpb) * p->pwrq; + } else { + med = (D(p->an - proc * (p->kna + proc)) + p->knb) * p->pwrq * -1.0; + } + + proc = p->srct * (med - p->prev_med + p->prev_out); + p->prev_med = M(med); + p->prev_out = M(proc); + + proc = bprocess(proc, p->hp, &p->hw[2][0], &p->hw[2][1]); + proc = bprocess(proc, p->hp, &p->hw[3][0], &p->hw[3][1]); + + if (s->ceil >= 10000.) { + proc = bprocess(proc, p->lp, &p->lw[0][0], &p->lw[0][1]); + proc = bprocess(proc, p->lp, &p->lw[1][0], &p->lw[1][1]); + } + + return proc; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + AExciterContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out; + const double *src = (const double *)in->data[0]; + const double level_in = s->level_in; + const double level_out = s->level_out; + const double amount = s->amount; + const double listen = 1.0 - s->listen; + double *dst; + + if (av_frame_is_writable(in)) { + out = in; + } else { + out = ff_get_audio_buffer(inlink, in->nb_samples); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + } + + dst = (double *)out->data[0]; + for (int n = 0; n < in->nb_samples; n++) { + for (int c = 0; c < inlink->channels; c++) { + double sample = src[c] * level_in; + + sample = distortion_process(s, &s->cp[c], sample); + sample = sample * amount + listen * src[c]; + + sample *= level_out; + if (ctx->is_disabled) + dst[c] = src[c]; + else + dst[c] = sample; + } + + src += inlink->channels; + dst += inlink->channels; + } + + if (in != out) + av_frame_free(&in); + + return ff_filter_frame(outlink, out); +} + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats; + AVFilterChannelLayouts *layouts; + static const enum AVSampleFormat sample_fmts[] = { + AV_SAMPLE_FMT_DBL, + AV_SAMPLE_FMT_NONE + }; + int ret; + + layouts = ff_all_channel_counts(); + if (!layouts) + return AVERROR(ENOMEM); + ret = ff_set_common_channel_layouts(ctx, layouts); + if (ret < 0) + return ret; + + formats = ff_make_format_list(sample_fmts); + if (!formats) + return AVERROR(ENOMEM); + ret = ff_set_common_formats(ctx, formats); + if (ret < 0) + return ret; + + formats = ff_all_samplerates(); + if (!formats) + return AVERROR(ENOMEM); + return ff_set_common_samplerates(ctx, formats); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + AExciterContext *s = ctx->priv; + + av_freep(&s->cp); +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + AExciterContext *s = ctx->priv; + + if (!s->cp) + s->cp = av_calloc(inlink->channels, sizeof(*s->cp)); + if (!s->cp) + return AVERROR(ENOMEM); + + for (int i = 0; i < inlink->channels; i++) + set_params(&s->cp[i], s->blend, s->drive, inlink->sample_rate, + s->freq, s->ceil); + + return 0; +} + +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + AVFilterLink *inlink = ctx->inputs[0]; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_input(inlink); +} + +static const AVFilterPad avfilter_af_aexciter_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .config_props = config_input, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad avfilter_af_aexciter_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + }, + { NULL } +}; + +AVFilter ff_af_aexciter = { + .name = "aexciter", + .description = NULL_IF_CONFIG_SMALL("Enhance high frequency part of audio."), + .priv_size = sizeof(AExciterContext), + .priv_class = &aexciter_class, + .uninit = uninit, + .query_formats = query_formats, + .inputs = avfilter_af_aexciter_inputs, + .outputs = avfilter_af_aexciter_outputs, + .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, +}; diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c index 4edfd27a3..976b6752c 100644 --- a/libavfilter/af_afade.c +++ b/libavfilter/af_afade.c @@ -51,10 +51,11 @@ typedef struct AudioFadeContext { int curve0, int curve1); } AudioFadeContext; -enum CurveType { TRI, QSIN, ESIN, HSIN, LOG, IPAR, QUA, CUB, SQU, CBR, PAR, EXP, IQSIN, IHSIN, DESE, DESI, LOSI, NONE, NB_CURVES }; +enum CurveType { NONE = -1, TRI, QSIN, ESIN, HSIN, LOG, IPAR, QUA, CUB, SQU, CBR, PAR, EXP, IQSIN, IHSIN, DESE, DESI, LOSI, SINC, ISINC, NB_CURVES }; #define OFFSET(x) offsetof(AudioFadeContext, x) #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define TFLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static int query_formats(AVFilterContext *ctx) { @@ -153,6 +154,12 @@ static double fade_gain(int curve, int64_t index, int64_t range) gain = (A - B) / (C - B); } break; + case SINC: + gain = gain >= 1.0 ? 1.0 : sin(M_PI * (1.0 - gain)) / (M_PI * (1.0 - gain)); + break; + case ISINC: + gain = gain <= 0.0 ? 0.0 : 1.0 - sin(M_PI * gain) / (M_PI * gain); + break; case NONE: gain = 1.0; break; @@ -223,8 +230,10 @@ static int config_output(AVFilterLink *outlink) if (s->duration) s->nb_samples = av_rescale(s->duration, outlink->sample_rate, AV_TIME_BASE); + s->duration = 0; if (s->start_time) s->start_sample = av_rescale(s->start_time, outlink->sample_rate, AV_TIME_BASE); + s->start_time = 0; return 0; } @@ -232,38 +241,40 @@ static int config_output(AVFilterLink *outlink) #if CONFIG_AFADE_FILTER static const AVOption afade_options[] = { - { "type", "set the fade direction", OFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FLAGS, "type" }, - { "t", "set the fade direction", OFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FLAGS, "type" }, - { "in", "fade-in", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "type" }, - { "out", "fade-out", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "type" }, - { "start_sample", "set number of first sample to start fading", OFFSET(start_sample), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, FLAGS }, - { "ss", "set number of first sample to start fading", OFFSET(start_sample), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, FLAGS }, - { "nb_samples", "set number of samples for fade duration", OFFSET(nb_samples), AV_OPT_TYPE_INT64, {.i64 = 44100}, 1, INT64_MAX, FLAGS }, - { "ns", "set number of samples for fade duration", OFFSET(nb_samples), AV_OPT_TYPE_INT64, {.i64 = 44100}, 1, INT64_MAX, FLAGS }, - { "start_time", "set time to start fading", OFFSET(start_time), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT64_MAX, FLAGS }, - { "st", "set time to start fading", OFFSET(start_time), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT64_MAX, FLAGS }, - { "duration", "set fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT64_MAX, FLAGS }, - { "d", "set fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT64_MAX, FLAGS }, - { "curve", "set fade curve type", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, 0, NB_CURVES - 1, FLAGS, "curve" }, - { "c", "set fade curve type", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, 0, NB_CURVES - 1, FLAGS, "curve" }, - { "tri", "linear slope", 0, AV_OPT_TYPE_CONST, {.i64 = TRI }, 0, 0, FLAGS, "curve" }, - { "qsin", "quarter of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = QSIN }, 0, 0, FLAGS, "curve" }, - { "esin", "exponential sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = ESIN }, 0, 0, FLAGS, "curve" }, - { "hsin", "half of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = HSIN }, 0, 0, FLAGS, "curve" }, - { "log", "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64 = LOG }, 0, 0, FLAGS, "curve" }, - { "ipar", "inverted parabola", 0, AV_OPT_TYPE_CONST, {.i64 = IPAR }, 0, 0, FLAGS, "curve" }, - { "qua", "quadratic", 0, AV_OPT_TYPE_CONST, {.i64 = QUA }, 0, 0, FLAGS, "curve" }, - { "cub", "cubic", 0, AV_OPT_TYPE_CONST, {.i64 = CUB }, 0, 0, FLAGS, "curve" }, - { "squ", "square root", 0, AV_OPT_TYPE_CONST, {.i64 = SQU }, 0, 0, FLAGS, "curve" }, - { "cbr", "cubic root", 0, AV_OPT_TYPE_CONST, {.i64 = CBR }, 0, 0, FLAGS, "curve" }, - { "par", "parabola", 0, AV_OPT_TYPE_CONST, {.i64 = PAR }, 0, 0, FLAGS, "curve" }, - { "exp", "exponential", 0, AV_OPT_TYPE_CONST, {.i64 = EXP }, 0, 0, FLAGS, "curve" }, - { "iqsin", "inverted quarter of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = IQSIN}, 0, 0, FLAGS, "curve" }, - { "ihsin", "inverted half of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = IHSIN}, 0, 0, FLAGS, "curve" }, - { "dese", "double-exponential seat", 0, AV_OPT_TYPE_CONST, {.i64 = DESE }, 0, 0, FLAGS, "curve" }, - { "desi", "double-exponential sigmoid", 0, AV_OPT_TYPE_CONST, {.i64 = DESI }, 0, 0, FLAGS, "curve" }, - { "losi", "logistic sigmoid", 0, AV_OPT_TYPE_CONST, {.i64 = LOSI }, 0, 0, FLAGS, "curve" }, - { "nofade", "no fade; keep audio as-is", 0, AV_OPT_TYPE_CONST, {.i64 = NONE }, 0, 0, FLAGS, "curve" }, + { "type", "set the fade direction", OFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, TFLAGS, "type" }, + { "t", "set the fade direction", OFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, TFLAGS, "type" }, + { "in", "fade-in", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, TFLAGS, "type" }, + { "out", "fade-out", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, TFLAGS, "type" }, + { "start_sample", "set number of first sample to start fading", OFFSET(start_sample), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, TFLAGS }, + { "ss", "set number of first sample to start fading", OFFSET(start_sample), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, TFLAGS }, + { "nb_samples", "set number of samples for fade duration", OFFSET(nb_samples), AV_OPT_TYPE_INT64, {.i64 = 44100}, 1, INT64_MAX, TFLAGS }, + { "ns", "set number of samples for fade duration", OFFSET(nb_samples), AV_OPT_TYPE_INT64, {.i64 = 44100}, 1, INT64_MAX, TFLAGS }, + { "start_time", "set time to start fading", OFFSET(start_time), AV_OPT_TYPE_DURATION, {.i64 = 0 }, 0, INT64_MAX, TFLAGS }, + { "st", "set time to start fading", OFFSET(start_time), AV_OPT_TYPE_DURATION, {.i64 = 0 }, 0, INT64_MAX, TFLAGS }, + { "duration", "set fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0 }, 0, INT64_MAX, TFLAGS }, + { "d", "set fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0 }, 0, INT64_MAX, TFLAGS }, + { "curve", "set fade curve type", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, NONE, NB_CURVES - 1, TFLAGS, "curve" }, + { "c", "set fade curve type", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, NONE, NB_CURVES - 1, TFLAGS, "curve" }, + { "nofade", "no fade; keep audio as-is", 0, AV_OPT_TYPE_CONST, {.i64 = NONE }, 0, 0, TFLAGS, "curve" }, + { "tri", "linear slope", 0, AV_OPT_TYPE_CONST, {.i64 = TRI }, 0, 0, TFLAGS, "curve" }, + { "qsin", "quarter of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = QSIN }, 0, 0, TFLAGS, "curve" }, + { "esin", "exponential sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = ESIN }, 0, 0, TFLAGS, "curve" }, + { "hsin", "half of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = HSIN }, 0, 0, TFLAGS, "curve" }, + { "log", "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64 = LOG }, 0, 0, TFLAGS, "curve" }, + { "ipar", "inverted parabola", 0, AV_OPT_TYPE_CONST, {.i64 = IPAR }, 0, 0, TFLAGS, "curve" }, + { "qua", "quadratic", 0, AV_OPT_TYPE_CONST, {.i64 = QUA }, 0, 0, TFLAGS, "curve" }, + { "cub", "cubic", 0, AV_OPT_TYPE_CONST, {.i64 = CUB }, 0, 0, TFLAGS, "curve" }, + { "squ", "square root", 0, AV_OPT_TYPE_CONST, {.i64 = SQU }, 0, 0, TFLAGS, "curve" }, + { "cbr", "cubic root", 0, AV_OPT_TYPE_CONST, {.i64 = CBR }, 0, 0, TFLAGS, "curve" }, + { "par", "parabola", 0, AV_OPT_TYPE_CONST, {.i64 = PAR }, 0, 0, TFLAGS, "curve" }, + { "exp", "exponential", 0, AV_OPT_TYPE_CONST, {.i64 = EXP }, 0, 0, TFLAGS, "curve" }, + { "iqsin", "inverted quarter of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = IQSIN}, 0, 0, TFLAGS, "curve" }, + { "ihsin", "inverted half of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = IHSIN}, 0, 0, TFLAGS, "curve" }, + { "dese", "double-exponential seat", 0, AV_OPT_TYPE_CONST, {.i64 = DESE }, 0, 0, TFLAGS, "curve" }, + { "desi", "double-exponential sigmoid", 0, AV_OPT_TYPE_CONST, {.i64 = DESI }, 0, 0, TFLAGS, "curve" }, + { "losi", "logistic sigmoid", 0, AV_OPT_TYPE_CONST, {.i64 = LOSI }, 0, 0, TFLAGS, "curve" }, + { "sinc", "sine cardinal function", 0, AV_OPT_TYPE_CONST, {.i64 = SINC }, 0, 0, TFLAGS, "curve" }, + { "isinc", "inverted sine cardinal function", 0, AV_OPT_TYPE_CONST, {.i64 = ISINC}, 0, 0, TFLAGS, "curve" }, { NULL } }; @@ -324,6 +335,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) return ff_filter_frame(outlink, out_buf); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_output(ctx->outputs[0]); +} + static const AVFilterPad avfilter_af_afade_inputs[] = { { .name = "default", @@ -351,6 +374,7 @@ AVFilter ff_af_afade = { .inputs = avfilter_af_afade_inputs, .outputs = avfilter_af_afade_outputs, .priv_class = &afade_class, + .process_command = process_command, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; @@ -361,12 +385,13 @@ AVFilter ff_af_afade = { static const AVOption acrossfade_options[] = { { "nb_samples", "set number of samples for cross fade duration", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 44100}, 1, INT32_MAX/10, FLAGS }, { "ns", "set number of samples for cross fade duration", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 44100}, 1, INT32_MAX/10, FLAGS }, - { "duration", "set cross fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, 60000000, FLAGS }, - { "d", "set cross fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, 60000000, FLAGS }, + { "duration", "set cross fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0 }, 0, 60000000, FLAGS }, + { "d", "set cross fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0 }, 0, 60000000, FLAGS }, { "overlap", "overlap 1st stream end with 2nd stream start", OFFSET(overlap), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, FLAGS }, { "o", "overlap 1st stream end with 2nd stream start", OFFSET(overlap), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, FLAGS }, - { "curve1", "set fade curve type for 1st stream", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, 0, NB_CURVES - 1, FLAGS, "curve" }, - { "c1", "set fade curve type for 1st stream", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, 0, NB_CURVES - 1, FLAGS, "curve" }, + { "curve1", "set fade curve type for 1st stream", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, NONE, NB_CURVES - 1, FLAGS, "curve" }, + { "c1", "set fade curve type for 1st stream", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, NONE, NB_CURVES - 1, FLAGS, "curve" }, + { "nofade", "no fade; keep audio as-is", 0, AV_OPT_TYPE_CONST, {.i64 = NONE }, 0, 0, FLAGS, "curve" }, { "tri", "linear slope", 0, AV_OPT_TYPE_CONST, {.i64 = TRI }, 0, 0, FLAGS, "curve" }, { "qsin", "quarter of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = QSIN }, 0, 0, FLAGS, "curve" }, { "esin", "exponential sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = ESIN }, 0, 0, FLAGS, "curve" }, @@ -384,9 +409,10 @@ static const AVOption acrossfade_options[] = { { "dese", "double-exponential seat", 0, AV_OPT_TYPE_CONST, {.i64 = DESE }, 0, 0, FLAGS, "curve" }, { "desi", "double-exponential sigmoid", 0, AV_OPT_TYPE_CONST, {.i64 = DESI }, 0, 0, FLAGS, "curve" }, { "losi", "logistic sigmoid", 0, AV_OPT_TYPE_CONST, {.i64 = LOSI }, 0, 0, FLAGS, "curve" }, - { "nofade", "no fade; keep audio as-is", 0, AV_OPT_TYPE_CONST, {.i64 = NONE }, 0, 0, FLAGS, "curve" }, - { "curve2", "set fade curve type for 2nd stream", OFFSET(curve2), AV_OPT_TYPE_INT, {.i64 = TRI }, 0, NB_CURVES - 1, FLAGS, "curve" }, - { "c2", "set fade curve type for 2nd stream", OFFSET(curve2), AV_OPT_TYPE_INT, {.i64 = TRI }, 0, NB_CURVES - 1, FLAGS, "curve" }, + { "sinc", "sine cardinal function", 0, AV_OPT_TYPE_CONST, {.i64 = SINC }, 0, 0, FLAGS, "curve" }, + { "isinc", "inverted sine cardinal function", 0, AV_OPT_TYPE_CONST, {.i64 = ISINC}, 0, 0, FLAGS, "curve" }, + { "curve2", "set fade curve type for 2nd stream", OFFSET(curve2), AV_OPT_TYPE_INT, {.i64 = TRI }, NONE, NB_CURVES - 1, FLAGS, "curve" }, + { "c2", "set fade curve type for 2nd stream", OFFSET(curve2), AV_OPT_TYPE_INT, {.i64 = TRI }, NONE, NB_CURVES - 1, FLAGS, "curve" }, { NULL } }; diff --git a/libavfilter/af_afftfilt.c b/libavfilter/af_afftfilt.c index a6156bf85..9b9001a44 100644 --- a/libavfilter/af_afftfilt.c +++ b/libavfilter/af_afftfilt.c @@ -118,7 +118,7 @@ static double realf(void *priv, double x, double ch) { return getreal(priv, x, c static double imagf(void *priv, double x, double ch) { return getimag(priv, x, ch); } static const char *const func2_names[] = { "real", "imag", NULL }; -double (*func2[])(void *, double, double) = { realf, imagf, NULL }; +static double (*const func2[])(void *, double, double) = { realf, imagf, NULL }; static int config_input(AVFilterLink *inlink) { diff --git a/libavfilter/af_afir.c b/libavfilter/af_afir.c index 5ba880f10..1b4e0a0c9 100644 --- a/libavfilter/af_afir.c +++ b/libavfilter/af_afir.c @@ -64,6 +64,16 @@ static void direct(const float *in, const FFTComplex *ir, int len, float *out) out[n] += ir[m].re * in[n - m]; } +static void fir_fadd(AudioFIRContext *s, float *dst, const float *src, int nb_samples) +{ + if ((nb_samples & 15) == 0 && nb_samples >= 16) { + s->fdsp->vector_fmac_scalar(dst, src, 1.f, nb_samples); + } else { + for (int n = 0; n < nb_samples; n++) + dst[n] += src[n]; + } +} + static int fir_quantum(AVFilterContext *ctx, AVFrame *out, int ch, int offset) { AudioFIRContext *s = ctx->priv; @@ -93,9 +103,7 @@ static int fir_quantum(AVFilterContext *ctx, AVFrame *out, int ch, int offset) memmove(src, src + s->min_part_size, (seg->input_size - s->min_part_size) * sizeof(*src)); dst += seg->output_offset[ch]; - for (n = 0; n < nb_samples; n++) { - ptr[n] += dst[n]; - } + fir_fadd(s, ptr, dst, nb_samples); continue; } @@ -153,9 +161,7 @@ static int fir_quantum(AVFilterContext *ctx, AVFrame *out, int ch, int offset) av_rdft_calc(seg->irdft[ch], sum); buf = (float *)seg->buffer->extended_data[ch]; - for (n = 0; n < seg->part_size; n++) { - buf[n] += sum[n]; - } + fir_fadd(s, buf, sum, seg->part_size); memcpy(dst, buf, seg->part_size * sizeof(*dst)); @@ -166,9 +172,7 @@ static int fir_quantum(AVFilterContext *ctx, AVFrame *out, int ch, int offset) memmove(src, src + s->min_part_size, (seg->input_size - s->min_part_size) * sizeof(*src)); - for (n = 0; n < nb_samples; n++) { - ptr[n] += dst[n]; - } + fir_fadd(s, ptr, dst, nb_samples); } if (s->min_part_size >= 8) { @@ -604,7 +608,7 @@ static int convert_coeffs(AVFilterContext *ctx) return 0; } -static int check_ir(AVFilterLink *link, AVFrame *frame) +static int check_ir(AVFilterLink *link) { AVFilterContext *ctx = link->dst; AudioFIRContext *s = ctx->priv; @@ -632,9 +636,7 @@ static int activate(AVFilterContext *ctx) if (s->response) FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[1], ctx); if (!s->eof_coeffs[s->selir]) { - AVFrame *ir = NULL; - - ret = check_ir(ctx->inputs[1 + s->selir], ir); + ret = check_ir(ctx->inputs[1 + s->selir]); if (ret < 0) return ret; @@ -727,7 +729,7 @@ static int query_formats(AVFilterContext *ctx) if (s->response) { AVFilterLink *videolink = ctx->outputs[1]; formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &videolink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &videolink->incfg.formats)) < 0) return ret; } @@ -742,16 +744,16 @@ static int query_formats(AVFilterContext *ctx) } else { AVFilterChannelLayouts *mono = NULL; + if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts)) < 0) + return ret; + if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0) + return ret; + ret = ff_add_channel_layout(&mono, AV_CH_LAYOUT_MONO); if (ret) return ret; - - if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts)) < 0) - return ret; - if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0) - return ret; for (int i = 1; i < ctx->nb_inputs; i++) { - if ((ret = ff_channel_layouts_ref(mono, &ctx->inputs[i]->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(mono, &ctx->inputs[i]->outcfg.channel_layouts)) < 0) return ret; } } @@ -796,11 +798,9 @@ static av_cold void uninit(AVFilterContext *ctx) av_frame_free(&s->ir[i]); } - for (int i = 0; i < ctx->nb_inputs; i++) + for (unsigned i = 1; i < ctx->nb_inputs; i++) av_freep(&ctx->input_pads[i].name); - for (int i = 0; i < ctx->nb_outputs; i++) - av_freep(&ctx->output_pads[i].name); av_frame_free(&s->video); } @@ -838,18 +838,13 @@ static av_cold int init(AVFilterContext *ctx) int ret; pad = (AVFilterPad) { - .name = av_strdup("main"), + .name = "main", .type = AVMEDIA_TYPE_AUDIO, }; - if (!pad.name) - return AVERROR(ENOMEM); - ret = ff_insert_inpad(ctx, 0, &pad); - if (ret < 0) { - av_freep(&pad.name); + if (ret < 0) return ret; - } for (int n = 0; n < s->nb_irs; n++) { pad = (AVFilterPad) { @@ -868,34 +863,25 @@ static av_cold int init(AVFilterContext *ctx) } pad = (AVFilterPad) { - .name = av_strdup("default"), + .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = config_output, }; - if (!pad.name) - return AVERROR(ENOMEM); - ret = ff_insert_outpad(ctx, 0, &pad); - if (ret < 0) { - av_freep(&pad.name); + if (ret < 0) return ret; - } if (s->response) { vpad = (AVFilterPad){ - .name = av_strdup("filter_response"), + .name = "filter_response", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_video, }; - if (!vpad.name) - return AVERROR(ENOMEM); ret = ff_insert_outpad(ctx, 1, &vpad); - if (ret < 0) { - av_freep(&vpad.name); + if (ret < 0) return ret; - } } s->fdsp = avpriv_float_dsp_alloc(0); diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c index 1a702778c..e669f2de8 100644 --- a/libavfilter/af_aformat.c +++ b/libavfilter/af_aformat.c @@ -60,7 +60,7 @@ static const AVOption aformat_options[] = { AVFILTER_DEFINE_CLASS(aformat); -#define PARSE_FORMATS(str, type, list, add_to_list, unref_fn, get_fmt, none, desc) \ +#define PARSE_FORMATS(str, type, list, add_to_list, get_fmt, none, desc) \ do { \ char *next, *cur = str, sep; \ int ret; \ @@ -83,7 +83,6 @@ do { \ return AVERROR(EINVAL); \ } \ if ((ret = add_to_list(&list, fmt)) < 0) { \ - unref_fn(&list); \ return ret; \ } \ \ @@ -102,16 +101,25 @@ static av_cold int init(AVFilterContext *ctx) AFormatContext *s = ctx->priv; PARSE_FORMATS(s->formats_str, enum AVSampleFormat, s->formats, - ff_add_format, ff_formats_unref, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format"); - PARSE_FORMATS(s->sample_rates_str, int, s->sample_rates, ff_add_format, ff_formats_unref, + ff_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format"); + PARSE_FORMATS(s->sample_rates_str, int, s->sample_rates, ff_add_format, get_sample_rate, 0, "sample rate"); PARSE_FORMATS(s->channel_layouts_str, uint64_t, s->channel_layouts, - ff_add_channel_layout, ff_channel_layouts_unref, av_get_channel_layout, 0, + ff_add_channel_layout, av_get_channel_layout, 0, "channel layout"); return 0; } +static av_cold void uninit(AVFilterContext *ctx) +{ + AFormatContext *s = ctx->priv; + + ff_formats_unref(&s->formats); + ff_formats_unref(&s->sample_rates); + ff_channel_layouts_unref(&s->channel_layouts); +} + static int query_formats(AVFilterContext *ctx) { AFormatContext *s = ctx->priv; @@ -119,14 +127,18 @@ static int query_formats(AVFilterContext *ctx) ret = ff_set_common_formats(ctx, s->formats ? s->formats : ff_all_formats(AVMEDIA_TYPE_AUDIO)); + s->formats = NULL; if (ret < 0) return ret; ret = ff_set_common_samplerates(ctx, s->sample_rates ? s->sample_rates : ff_all_samplerates()); + s->sample_rates = NULL; if (ret < 0) return ret; - return ff_set_common_channel_layouts(ctx, s->channel_layouts ? s->channel_layouts : + ret = ff_set_common_channel_layouts(ctx, s->channel_layouts ? s->channel_layouts : ff_all_channel_counts()); + s->channel_layouts = NULL; + return ret; } static const AVFilterPad avfilter_af_aformat_inputs[] = { @@ -149,6 +161,7 @@ AVFilter ff_af_aformat = { .name = "aformat", .description = NULL_IF_CONFIG_SMALL("Convert the input audio to one of the specified formats."), .init = init, + .uninit = uninit, .query_formats = query_formats, .priv_size = sizeof(AFormatContext), .priv_class = &aformat_class, diff --git a/libavfilter/af_afreqshift.c b/libavfilter/af_afreqshift.c new file mode 100644 index 000000000..6141730e0 --- /dev/null +++ b/libavfilter/af_afreqshift.c @@ -0,0 +1,427 @@ +/* + * Copyright (c) Paul B Mahol + * Copyright (c) Laurent de Soras, 2005 + * + * 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/channel_layout.h" +#include "libavutil/ffmath.h" +#include "libavutil/opt.h" +#include "avfilter.h" +#include "audio.h" +#include "formats.h" + +#define NB_COEFS 16 + +typedef struct AFreqShift { + const AVClass *class; + + double shift; + double level; + + double cd[NB_COEFS]; + float cf[NB_COEFS]; + + int64_t in_samples; + + AVFrame *i1, *o1; + AVFrame *i2, *o2; + + void (*filter_channel)(AVFilterContext *ctx, + int channel, + AVFrame *in, AVFrame *out); +} AFreqShift; + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats = NULL; + AVFilterChannelLayouts *layouts = NULL; + static const enum AVSampleFormat sample_fmts[] = { + AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_NONE + }; + int ret; + + formats = ff_make_format_list(sample_fmts); + if (!formats) + return AVERROR(ENOMEM); + ret = ff_set_common_formats(ctx, formats); + if (ret < 0) + return ret; + + layouts = ff_all_channel_counts(); + if (!layouts) + return AVERROR(ENOMEM); + + ret = ff_set_common_channel_layouts(ctx, layouts); + if (ret < 0) + return ret; + + formats = ff_all_samplerates(); + return ff_set_common_samplerates(ctx, formats); +} + +#define PFILTER(name, type, sin, cos, cc) \ +static void pfilter_channel_## name(AVFilterContext *ctx, \ + int ch, \ + AVFrame *in, AVFrame *out) \ +{ \ + AFreqShift *s = ctx->priv; \ + const int nb_samples = in->nb_samples; \ + const type *src = (const type *)in->extended_data[ch]; \ + type *dst = (type *)out->extended_data[ch]; \ + type *i1 = (type *)s->i1->extended_data[ch]; \ + type *o1 = (type *)s->o1->extended_data[ch]; \ + type *i2 = (type *)s->i2->extended_data[ch]; \ + type *o2 = (type *)s->o2->extended_data[ch]; \ + const type *c = s->cc; \ + const type level = s->level; \ + type shift = s->shift * M_PI; \ + type cos_theta = cos(shift); \ + type sin_theta = sin(shift); \ + \ + for (int n = 0; n < nb_samples; n++) { \ + type xn1 = src[n], xn2 = src[n]; \ + type I, Q; \ + \ + for (int j = 0; j < NB_COEFS / 2; j++) { \ + I = c[j] * (xn1 + o2[j]) - i2[j]; \ + i2[j] = i1[j]; \ + i1[j] = xn1; \ + o2[j] = o1[j]; \ + o1[j] = I; \ + xn1 = I; \ + } \ + \ + for (int j = NB_COEFS / 2; j < NB_COEFS; j++) { \ + Q = c[j] * (xn2 + o2[j]) - i2[j]; \ + i2[j] = i1[j]; \ + i1[j] = xn2; \ + o2[j] = o1[j]; \ + o1[j] = Q; \ + xn2 = Q; \ + } \ + Q = o2[NB_COEFS - 1]; \ + \ + dst[n] = (I * cos_theta - Q * sin_theta) * level; \ + } \ +} + +PFILTER(flt, float, sin, cos, cf) +PFILTER(dbl, double, sin, cos, cd) + +#define FFILTER(name, type, sin, cos, fmod, cc) \ +static void ffilter_channel_## name(AVFilterContext *ctx, \ + int ch, \ + AVFrame *in, AVFrame *out) \ +{ \ + AFreqShift *s = ctx->priv; \ + const int nb_samples = in->nb_samples; \ + const type *src = (const type *)in->extended_data[ch]; \ + type *dst = (type *)out->extended_data[ch]; \ + type *i1 = (type *)s->i1->extended_data[ch]; \ + type *o1 = (type *)s->o1->extended_data[ch]; \ + type *i2 = (type *)s->i2->extended_data[ch]; \ + type *o2 = (type *)s->o2->extended_data[ch]; \ + const type *c = s->cc; \ + const type level = s->level; \ + type ts = 1. / in->sample_rate; \ + type shift = s->shift; \ + int64_t N = s->in_samples; \ + \ + for (int n = 0; n < nb_samples; n++) { \ + type xn1 = src[n], xn2 = src[n]; \ + type I, Q, theta; \ + \ + for (int j = 0; j < NB_COEFS / 2; j++) { \ + I = c[j] * (xn1 + o2[j]) - i2[j]; \ + i2[j] = i1[j]; \ + i1[j] = xn1; \ + o2[j] = o1[j]; \ + o1[j] = I; \ + xn1 = I; \ + } \ + \ + for (int j = NB_COEFS / 2; j < NB_COEFS; j++) { \ + Q = c[j] * (xn2 + o2[j]) - i2[j]; \ + i2[j] = i1[j]; \ + i1[j] = xn2; \ + o2[j] = o1[j]; \ + o1[j] = Q; \ + xn2 = Q; \ + } \ + Q = o2[NB_COEFS - 1]; \ + \ + theta = 2. * M_PI * fmod(shift * (N + n) * ts, 1.); \ + dst[n] = (I * cos(theta) - Q * sin(theta)) * level; \ + } \ +} + +FFILTER(flt, float, sinf, cosf, fmodf, cf) +FFILTER(dbl, double, sin, cos, fmod, cd) + +static void compute_transition_param(double *K, double *Q, double transition) +{ + double kksqrt, e, e2, e4, k, q; + + k = tan((1. - transition * 2.) * M_PI / 4.); + k *= k; + kksqrt = pow(1 - k * k, 0.25); + e = 0.5 * (1. - kksqrt) / (1. + kksqrt); + e2 = e * e; + e4 = e2 * e2; + q = e * (1. + e4 * (2. + e4 * (15. + 150. * e4))); + + *Q = q; + *K = k; +} + +static double ipowp(double x, int64_t n) +{ + double z = 1.; + + while (n != 0) { + if (n & 1) + z *= x; + n >>= 1; + x *= x; + } + + return z; +} + +static double compute_acc_num(double q, int order, int c) +{ + int64_t i = 0; + int j = 1; + double acc = 0.; + double q_ii1; + + do { + q_ii1 = ipowp(q, i * (i + 1)); + q_ii1 *= sin((i * 2 + 1) * c * M_PI / order) * j; + acc += q_ii1; + + j = -j; + i++; + } while (fabs(q_ii1) > 1e-100); + + return acc; +} + +static double compute_acc_den(double q, int order, int c) +{ + int64_t i = 1; + int j = -1; + double acc = 0.; + double q_i2; + + do { + q_i2 = ipowp(q, i * i); + q_i2 *= cos(i * 2 * c * M_PI / order) * j; + acc += q_i2; + + j = -j; + i++; + } while (fabs(q_i2) > 1e-100); + + return acc; +} + +static double compute_coef(int index, double k, double q, int order) +{ + const int c = index + 1; + const double num = compute_acc_num(q, order, c) * pow(q, 0.25); + const double den = compute_acc_den(q, order, c) + 0.5; + const double ww = num / den; + const double wwsq = ww * ww; + + const double x = sqrt((1 - wwsq * k) * (1 - wwsq / k)) / (1 + wwsq); + const double coef = (1 - x) / (1 + x); + + return coef; +} + +static void compute_coefs(double *coef_arrd, float *coef_arrf, int nbr_coefs, double transition) +{ + const int order = nbr_coefs * 2 + 1; + double k, q; + + compute_transition_param(&k, &q, transition); + + for (int n = 0; n < nbr_coefs; n++) { + const int idx = (n / 2) + (n & 1) * nbr_coefs / 2; + + coef_arrd[idx] = compute_coef(n, k, q, order); + coef_arrf[idx] = coef_arrd[idx]; + } +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + AFreqShift *s = ctx->priv; + + compute_coefs(s->cd, s->cf, NB_COEFS, 2. * 20. / inlink->sample_rate); + + s->i1 = ff_get_audio_buffer(inlink, NB_COEFS); + s->o1 = ff_get_audio_buffer(inlink, NB_COEFS); + s->i2 = ff_get_audio_buffer(inlink, NB_COEFS); + s->o2 = ff_get_audio_buffer(inlink, NB_COEFS); + if (!s->i1 || !s->o1 || !s->i2 || !s->o2) + return AVERROR(ENOMEM); + + if (inlink->format == AV_SAMPLE_FMT_DBLP) { + if (!strcmp(ctx->filter->name, "afreqshift")) + s->filter_channel = ffilter_channel_dbl; + else + s->filter_channel = pfilter_channel_dbl; + } else { + if (!strcmp(ctx->filter->name, "afreqshift")) + s->filter_channel = ffilter_channel_flt; + else + s->filter_channel = pfilter_channel_flt; + } + + return 0; +} + +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + AFreqShift *s = ctx->priv; + ThreadData *td = arg; + AVFrame *out = td->out; + AVFrame *in = td->in; + const int start = (in->channels * jobnr) / nb_jobs; + const int end = (in->channels * (jobnr+1)) / nb_jobs; + + for (int ch = start; ch < end; ch++) + s->filter_channel(ctx, ch, in, out); + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + AVFilterLink *outlink = ctx->outputs[0]; + AFreqShift *s = ctx->priv; + AVFrame *out; + ThreadData td; + + if (av_frame_is_writable(in)) { + out = in; + } else { + out = ff_get_audio_buffer(outlink, in->nb_samples); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + } + + td.in = in; td.out = out; + ctx->internal->execute(ctx, filter_channels, &td, NULL, FFMIN(inlink->channels, + ff_filter_get_nb_threads(ctx))); + + s->in_samples += in->nb_samples; + + if (out != in) + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + AFreqShift *s = ctx->priv; + + av_frame_free(&s->i1); + av_frame_free(&s->o1); + av_frame_free(&s->i2); + av_frame_free(&s->o2); +} + +#define OFFSET(x) offsetof(AFreqShift, x) +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption afreqshift_options[] = { + { "shift", "set frequency shift", OFFSET(shift), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -INT_MAX, INT_MAX, FLAGS }, + { "level", "set output level", OFFSET(level), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.0, 1.0, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(afreqshift); + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + }, + { NULL } +}; + +AVFilter ff_af_afreqshift = { + .name = "afreqshift", + .description = NULL_IF_CONFIG_SMALL("Apply frequency shifting to input audio."), + .query_formats = query_formats, + .priv_size = sizeof(AFreqShift), + .priv_class = &afreqshift_class, + .uninit = uninit, + .inputs = inputs, + .outputs = outputs, + .process_command = ff_filter_process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | + AVFILTER_FLAG_SLICE_THREADS, +}; + +static const AVOption aphaseshift_options[] = { + { "shift", "set phase shift", OFFSET(shift), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -1.0, 1.0, FLAGS }, + { "level", "set output level",OFFSET(level), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.0, 1.0, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(aphaseshift); + +AVFilter ff_af_aphaseshift = { + .name = "aphaseshift", + .description = NULL_IF_CONFIG_SMALL("Apply phase shifting to input audio."), + .query_formats = query_formats, + .priv_size = sizeof(AFreqShift), + .priv_class = &aphaseshift_class, + .uninit = uninit, + .inputs = inputs, + .outputs = outputs, + .process_command = ff_filter_process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | + AVFILTER_FLAG_SLICE_THREADS, +}; diff --git a/libavfilter/af_agate.c b/libavfilter/af_agate.c index 936caa0a4..5fcf6eceb 100644 --- a/libavfilter/af_agate.c +++ b/libavfilter/af_agate.c @@ -63,7 +63,7 @@ typedef struct AudioGateContext { } AudioGateContext; #define OFFSET(x) offsetof(AudioGateContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption options[] = { { "level_in", "set input level", OFFSET(level_in), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, @@ -268,6 +268,8 @@ AVFilter ff_af_agate = { .priv_class = &agate_class, .inputs = inputs, .outputs = outputs, + .process_command = ff_filter_process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; #endif /* CONFIG_AGATE_FILTER */ @@ -353,20 +355,20 @@ static int scquery_formats(AVFilterContext *ctx) }; int ret, i; - if (!ctx->inputs[0]->in_channel_layouts || - !ctx->inputs[0]->in_channel_layouts->nb_channel_layouts) { + if (!ctx->inputs[0]->incfg.channel_layouts || + !ctx->inputs[0]->incfg.channel_layouts->nb_channel_layouts) { av_log(ctx, AV_LOG_WARNING, "No channel layout for input 1\n"); return AVERROR(EAGAIN); } - if ((ret = ff_add_channel_layout(&layouts, ctx->inputs[0]->in_channel_layouts->channel_layouts[0])) < 0 || - (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0) + if ((ret = ff_add_channel_layout(&layouts, ctx->inputs[0]->incfg.channel_layouts->channel_layouts[0])) < 0 || + (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0) return ret; for (i = 0; i < 2; i++) { layouts = ff_all_channel_counts(); - if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0) return ret; } @@ -445,5 +447,7 @@ AVFilter ff_af_sidechaingate = { .uninit = uninit, .inputs = sidechaingate_inputs, .outputs = sidechaingate_outputs, + .process_command = ff_filter_process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; #endif /* CONFIG_SIDECHAINGATE_FILTER */ diff --git a/libavfilter/af_aiir.c b/libavfilter/af_aiir.c index bc31e5141..0f4129cfa 100644 --- a/libavfilter/af_aiir.c +++ b/libavfilter/af_aiir.c @@ -40,8 +40,7 @@ typedef struct Pair { typedef struct BiquadContext { double a[3]; double b[3]; - double i1, i2; - double o1, o2; + double w1, w2; } BiquadContext; typedef struct IIRChannel { @@ -49,6 +48,7 @@ typedef struct IIRChannel { double *ab[2]; double g; double *cache[2]; + double fir; BiquadContext *biquads; int clippings; } IIRChannel; @@ -95,7 +95,7 @@ static int query_formats(AVFilterContext *ctx) AVFilterLink *videolink = ctx->outputs[1]; formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &videolink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &videolink->incfg.formats)) < 0) return ret; } @@ -176,13 +176,15 @@ IIR_CH(s32p, int32_t, INT32_MIN, INT32_MAX, 1) IIR_CH(fltp, float, -1., 1., 0) IIR_CH(dblp, double, -1., 1., 0) -#define SERIAL_IIR_CH(name, type, min, max, need_clipping) \ -static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \ +#define SERIAL_IIR_CH(name, type, min, max, need_clipping) \ +static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, \ + int ch, int nb_jobs) \ { \ AudioIIRContext *s = ctx->priv; \ const double ig = s->dry_gain; \ const double og = s->wet_gain; \ const double mix = s->mix; \ + const double imix = 1. - mix; \ ThreadData *td = arg; \ AVFrame *in = td->in, *out = td->out; \ const type *src = (const type *)in->extended_data[ch]; \ @@ -193,28 +195,24 @@ static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, int ch, int nb int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \ int n, i; \ \ - for (i = 0; i < nb_biquads; i++) { \ + for (i = nb_biquads - 1; i >= 0; i--) { \ const double a1 = -iir->biquads[i].a[1]; \ const double a2 = -iir->biquads[i].a[2]; \ const double b0 = iir->biquads[i].b[0]; \ const double b1 = iir->biquads[i].b[1]; \ const double b2 = iir->biquads[i].b[2]; \ - double i1 = iir->biquads[i].i1; \ - double i2 = iir->biquads[i].i2; \ - double o1 = iir->biquads[i].o1; \ - double o2 = iir->biquads[i].o2; \ + double w1 = iir->biquads[i].w1; \ + double w2 = iir->biquads[i].w2; \ \ for (n = 0; n < in->nb_samples; n++) { \ - double sample = ig * (i ? dst[n] : src[n]); \ - double o0 = sample * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \ + double i0 = ig * (i ? dst[n] : src[n]); \ + double o0 = i0 * b0 + w1; \ \ - i2 = i1; \ - i1 = src[n]; \ - o2 = o1; \ - o1 = o0; \ + w1 = b1 * i0 + w2 + a1 * o0; \ + w2 = b2 * i0 + a2 * o0; \ o0 *= og * g; \ \ - o0 = o0 * mix + (1. - mix) * sample; \ + o0 = o0 * mix + imix * i0; \ if (need_clipping && o0 < min) { \ (*clippings)++; \ dst[n] = min; \ @@ -225,10 +223,8 @@ static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, int ch, int nb dst[n] = o0; \ } \ } \ - iir->biquads[i].i1 = i1; \ - iir->biquads[i].i2 = i2; \ - iir->biquads[i].o1 = o1; \ - iir->biquads[i].o2 = o2; \ + iir->biquads[i].w1 = w1; \ + iir->biquads[i].w2 = w2; \ } \ \ return 0; \ @@ -239,6 +235,127 @@ SERIAL_IIR_CH(s32p, int32_t, INT32_MIN, INT32_MAX, 1) SERIAL_IIR_CH(fltp, float, -1., 1., 0) SERIAL_IIR_CH(dblp, double, -1., 1., 0) +#define PARALLEL_IIR_CH(name, type, min, max, need_clipping) \ +static int iir_ch_parallel_## name(AVFilterContext *ctx, void *arg, \ + int ch, int nb_jobs) \ +{ \ + AudioIIRContext *s = ctx->priv; \ + const double ig = s->dry_gain; \ + const double og = s->wet_gain; \ + const double mix = s->mix; \ + const double imix = 1. - mix; \ + ThreadData *td = arg; \ + AVFrame *in = td->in, *out = td->out; \ + const type *src = (const type *)in->extended_data[ch]; \ + type *dst = (type *)out->extended_data[ch]; \ + IIRChannel *iir = &s->iir[ch]; \ + const double g = iir->g; \ + const double fir = iir->fir; \ + int *clippings = &iir->clippings; \ + int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \ + int n, i; \ + \ + for (i = 0; i < nb_biquads; i++) { \ + const double a1 = -iir->biquads[i].a[1]; \ + const double a2 = -iir->biquads[i].a[2]; \ + const double b1 = iir->biquads[i].b[1]; \ + const double b2 = iir->biquads[i].b[2]; \ + double w1 = iir->biquads[i].w1; \ + double w2 = iir->biquads[i].w2; \ + \ + for (n = 0; n < in->nb_samples; n++) { \ + double i0 = ig * src[n]; \ + double o0 = w1; \ + \ + w1 = b1 * i0 + w2 + a1 * o0; \ + w2 = b2 * i0 + a2 * o0; \ + o0 *= og * g; \ + o0 += dst[n]; \ + \ + if (need_clipping && o0 < min) { \ + (*clippings)++; \ + dst[n] = min; \ + } else if (need_clipping && o0 > max) { \ + (*clippings)++; \ + dst[n] = max; \ + } else { \ + dst[n] = o0; \ + } \ + } \ + iir->biquads[i].w1 = w1; \ + iir->biquads[i].w2 = w2; \ + } \ + \ + for (n = 0; n < in->nb_samples; n++) { \ + dst[n] += fir * src[n]; \ + dst[n] = dst[n] * mix + imix * src[n]; \ + } \ + \ + return 0; \ +} + +PARALLEL_IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1) +PARALLEL_IIR_CH(s32p, int32_t, INT32_MIN, INT32_MAX, 1) +PARALLEL_IIR_CH(fltp, float, -1., 1., 0) +PARALLEL_IIR_CH(dblp, double, -1., 1., 0) + +#define LATTICE_IIR_CH(name, type, min, max, need_clipping) \ +static int iir_ch_lattice_## name(AVFilterContext *ctx, void *arg, \ + int ch, int nb_jobs) \ +{ \ + AudioIIRContext *s = ctx->priv; \ + const double ig = s->dry_gain; \ + const double og = s->wet_gain; \ + const double mix = s->mix; \ + ThreadData *td = arg; \ + AVFrame *in = td->in, *out = td->out; \ + const type *src = (const type *)in->extended_data[ch]; \ + double n0, n1, p0, *x = (double *)s->iir[ch].cache[0]; \ + const int nb_stages = s->iir[ch].nb_ab[1]; \ + const double *v = s->iir[ch].ab[0]; \ + const double *k = s->iir[ch].ab[1]; \ + const double g = s->iir[ch].g; \ + int *clippings = &s->iir[ch].clippings; \ + type *dst = (type *)out->extended_data[ch]; \ + int n; \ + \ + for (n = 0; n < in->nb_samples; n++) { \ + const double in = src[n] * ig; \ + double out = 0.; \ + \ + n1 = in; \ + for (int i = nb_stages - 1; i >= 0; i--) { \ + n0 = n1 - k[i] * x[i]; \ + p0 = n0 * k[i] + x[i]; \ + out += p0 * v[i+1]; \ + x[i] = p0; \ + n1 = n0; \ + } \ + \ + out += n1 * v[0]; \ + memmove(&x[1], &x[0], nb_stages * sizeof(*x)); \ + x[0] = n1; \ + out *= og * g; \ + out = out * mix + in * (1. - mix); \ + if (need_clipping && out < min) { \ + (*clippings)++; \ + dst[n] = min; \ + } else if (need_clipping && out > max) { \ + (*clippings)++; \ + dst[n] = max; \ + } else { \ + dst[n] = out; \ + } \ + } \ + \ + return 0; \ +} + +LATTICE_IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1) +LATTICE_IIR_CH(s32p, int32_t, INT32_MIN, INT32_MAX, 1) +LATTICE_IIR_CH(fltp, float, -1., 1., 0) +LATTICE_IIR_CH(dblp, double, -1., 1., 0) + static void count_coefficients(char *item_str, int *nb_items) { char *p; @@ -272,7 +389,7 @@ static int read_gains(AVFilterContext *ctx, char *item_str, int nb_items) } p = NULL; - if (sscanf(arg, "%lf", &s->iir[i].g) != 1) { + if (av_sscanf(arg, "%lf", &s->iir[i].g) != 1) { av_log(ctx, AV_LOG_ERROR, "Invalid gains supplied: %s\n", arg); av_freep(&old_str); return AVERROR(EINVAL); @@ -299,7 +416,7 @@ static int read_tf_coefficients(AVFilterContext *ctx, char *item_str, int nb_ite break; p = NULL; - if (sscanf(arg, "%lf", &dst[i]) != 1) { + if (av_sscanf(arg, "%lf", &dst[i]) != 1) { av_log(ctx, AV_LOG_ERROR, "Invalid coefficients supplied: %s\n", arg); av_freep(&old_str); return AVERROR(EINVAL); @@ -324,7 +441,7 @@ static int read_zp_coefficients(AVFilterContext *ctx, char *item_str, int nb_ite break; p = NULL; - if (sscanf(arg, format, &dst[i*2], &dst[i*2+1]) != 2) { + if (av_sscanf(arg, format, &dst[i*2], &dst[i*2+1]) != 2) { av_log(ctx, AV_LOG_ERROR, "Invalid coefficients supplied: %s\n", arg); av_freep(&old_str); return AVERROR(EINVAL); @@ -336,7 +453,7 @@ static int read_zp_coefficients(AVFilterContext *ctx, char *item_str, int nb_ite return 0; } -static const char *format[] = { "%lf", "%lf %lfi", "%lf %lfr", "%lf %lfd", "%lf %lfi" }; +static const char *const format[] = { "%lf", "%lf %lfi", "%lf %lfr", "%lf %lfd", "%lf %lfi" }; static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, int ab) { @@ -368,7 +485,7 @@ static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, return AVERROR(ENOMEM); } - if (s->format) { + if (s->format > 0) { ret = read_zp_coefficients(ctx, arg, iir->nb_ab[ab], iir->ab[ab], format[s->format]); } else { ret = read_tf_coefficients(ctx, arg, iir->nb_ab[ab], iir->ab[ab]); @@ -656,6 +773,128 @@ static int decompose_zp2biquads(AVFilterContext *ctx, int channels) return 0; } +static void biquad_process(double *x, double *y, int length, + double b0, double b1, double b2, + double a1, double a2) +{ + double w1 = 0., w2 = 0.; + + a1 = -a1; + a2 = -a2; + + for (int n = 0; n < length; n++) { + double out, in = x[n]; + + y[n] = out = in * b0 + w1; + w1 = b1 * in + w2 + a1 * out; + w2 = b2 * in + a2 * out; + } +} + +static void solve(double *matrix, double *vector, int n, double *y, double *x, double *lu) +{ + double sum = 0.; + + for (int i = 0; i < n; i++) { + for (int j = i; j < n; j++) { + sum = 0.; + for (int k = 0; k < i; k++) + sum += lu[i * n + k] * lu[k * n + j]; + lu[i * n + j] = matrix[j * n + i] - sum; + } + for (int j = i + 1; j < n; j++) { + sum = 0.; + for (int k = 0; k < i; k++) + sum += lu[j * n + k] * lu[k * n + i]; + lu[j * n + i] = (1. / lu[i * n + i]) * (matrix[i * n + j] - sum); + } + } + + for (int i = 0; i < n; i++) { + sum = 0.; + for (int k = 0; k < i; k++) + sum += lu[i * n + k] * y[k]; + y[i] = vector[i] - sum; + } + + for (int i = n - 1; i >= 0; i--) { + sum = 0.; + for (int k = i + 1; k < n; k++) + sum += lu[i * n + k] * x[k]; + x[i] = (1 / lu[i * n + i]) * (y[i] - sum); + } +} + +static int convert_serial2parallel(AVFilterContext *ctx, int channels) +{ + AudioIIRContext *s = ctx->priv; + int ret = 0; + + for (int ch = 0; ch < channels; ch++) { + IIRChannel *iir = &s->iir[ch]; + int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; + int length = nb_biquads * 2 + 1; + double *impulse = av_calloc(length, sizeof(*impulse)); + double *y = av_calloc(length, sizeof(*y)); + double *resp = av_calloc(length, sizeof(*resp)); + double *M = av_calloc((length - 1) * 2 * nb_biquads, sizeof(*M)); + double *W = av_calloc((length - 1) * 2 * nb_biquads, sizeof(*W)); + + if (!impulse || !y || !resp || !M) { + av_free(impulse); + av_free(y); + av_free(resp); + av_free(M); + av_free(W); + return AVERROR(ENOMEM); + } + + impulse[0] = 1.; + + for (int n = 0; n < nb_biquads; n++) { + BiquadContext *biquad = &iir->biquads[n]; + + biquad_process(n ? y : impulse, y, length, + biquad->b[0], biquad->b[1], biquad->b[2], + biquad->a[1], biquad->a[2]); + } + + for (int n = 0; n < nb_biquads; n++) { + BiquadContext *biquad = &iir->biquads[n]; + + biquad_process(impulse, resp, length - 1, + 1., 0., 0., biquad->a[1], biquad->a[2]); + + memcpy(M + n * 2 * (length - 1), resp, sizeof(*resp) * (length - 1)); + memcpy(M + n * 2 * (length - 1) + length, resp, sizeof(*resp) * (length - 2)); + memset(resp, 0, length * sizeof(*resp)); + } + + solve(M, &y[1], length - 1, &impulse[1], resp, W); + + iir->fir = y[0]; + + for (int n = 0; n < nb_biquads; n++) { + BiquadContext *biquad = &iir->biquads[n]; + + biquad->b[0] = 0.; + biquad->b[1] = resp[n * 2 + 0]; + biquad->b[2] = resp[n * 2 + 1]; + } + + av_free(impulse); + av_free(y); + av_free(resp); + av_free(M); + av_free(W); + + if (ret < 0) + return ret; + } + + return 0; +} + static void convert_pr2zp(AVFilterContext *ctx, int channels) { AudioIIRContext *s = ctx->priv; @@ -695,27 +934,75 @@ static void convert_sp2zp(AVFilterContext *ctx, int channels) for (n = 0; n < iir->nb_ab[0]; n++) { double sr = iir->ab[0][2*n]; double si = iir->ab[0][2*n+1]; - double snr = 1. + sr; - double sdr = 1. - sr; - double div = sdr * sdr + si * si; - iir->ab[0][2*n] = (snr * sdr - si * si) / div; - iir->ab[0][2*n+1] = (sdr * si + snr * si) / div; + iir->ab[0][2*n] = exp(sr) * cos(si); + iir->ab[0][2*n+1] = exp(sr) * sin(si); } for (n = 0; n < iir->nb_ab[1]; n++) { double sr = iir->ab[1][2*n]; double si = iir->ab[1][2*n+1]; - double snr = 1. + sr; - double sdr = 1. - sr; - double div = sdr * sdr + si * si; - iir->ab[1][2*n] = (snr * sdr - si * si) / div; - iir->ab[1][2*n+1] = (sdr * si + snr * si) / div; + iir->ab[1][2*n] = exp(sr) * cos(si); + iir->ab[1][2*n+1] = exp(sr) * sin(si); } } } +static double fact(double i) +{ + if (i <= 0.) + return 1.; + return i * fact(i - 1.); +} + +static double coef_sf2zf(double *a, int N, int n) +{ + double z = 0.; + + for (int i = 0; i <= N; i++) { + double acc = 0.; + + for (int k = FFMAX(n - N + i, 0); k <= FFMIN(i, n); k++) { + acc += ((fact(i) * fact(N - i)) / + (fact(k) * fact(i - k) * fact(n - k) * fact(N - i - n + k))) * + ((k & 1) ? -1. : 1.); + } + + z += a[i] * pow(2., i) * acc; + } + + return z; +} + +static void convert_sf2tf(AVFilterContext *ctx, int channels) +{ + AudioIIRContext *s = ctx->priv; + int ch; + + for (ch = 0; ch < channels; ch++) { + IIRChannel *iir = &s->iir[ch]; + double *temp0 = av_calloc(iir->nb_ab[0], sizeof(*temp0)); + double *temp1 = av_calloc(iir->nb_ab[1], sizeof(*temp1)); + + if (!temp0 || !temp1) + goto next; + + memcpy(temp0, iir->ab[0], iir->nb_ab[0] * sizeof(*temp0)); + memcpy(temp1, iir->ab[1], iir->nb_ab[1] * sizeof(*temp1)); + + for (int n = 0; n < iir->nb_ab[0]; n++) + iir->ab[0][n] = coef_sf2zf(temp0, iir->nb_ab[0] - 1, n); + + for (int n = 0; n < iir->nb_ab[1]; n++) + iir->ab[1][n] = coef_sf2zf(temp1, iir->nb_ab[1] - 1, n); + +next: + av_free(temp0); + av_free(temp1); + } +} + static void convert_pd2zp(AVFilterContext *ctx, int channels) { AudioIIRContext *s = ctx->priv; @@ -1004,7 +1291,10 @@ static int config_output(AVFilterLink *outlink) if (ret < 0) return ret; - if (s->format == 2) { + if (s->format == -1) { + convert_sf2tf(ctx, inlink->channels); + s->format = 0; + } else if (s->format == 2) { convert_pr2zp(ctx, inlink->channels); } else if (s->format == 3) { convert_pd2zp(ctx, inlink->channels); @@ -1025,7 +1315,7 @@ static int config_output(AVFilterLink *outlink) } if (s->format == 0) - av_log(ctx, AV_LOG_WARNING, "tf coefficients format is not recommended for too high number of zeros/poles.\n"); + av_log(ctx, AV_LOG_WARNING, "transfer function coefficients format is not recommended for too high number of zeros/poles.\n"); if (s->format > 0 && s->process == 0) { av_log(ctx, AV_LOG_WARNING, "Direct processsing is not recommended for zp coefficients format.\n"); @@ -1033,16 +1323,37 @@ static int config_output(AVFilterLink *outlink) ret = convert_zp2tf(ctx, inlink->channels); if (ret < 0) return ret; - } else if (s->format == 0 && s->process == 1) { - av_log(ctx, AV_LOG_ERROR, "Serial cascading is not implemented for transfer function.\n"); + } else if (s->format == -2 && s->process > 0) { + av_log(ctx, AV_LOG_ERROR, "Only direct processing is implemented for lattice-ladder function.\n"); + return AVERROR_PATCHWELCOME; + } else if (s->format <= 0 && s->process == 1) { + av_log(ctx, AV_LOG_ERROR, "Serial processing is not implemented for transfer function.\n"); + return AVERROR_PATCHWELCOME; + } else if (s->format <= 0 && s->process == 2) { + av_log(ctx, AV_LOG_ERROR, "Parallel processing is not implemented for transfer function.\n"); return AVERROR_PATCHWELCOME; } else if (s->format > 0 && s->process == 1) { - if (inlink->format == AV_SAMPLE_FMT_S16P) - av_log(ctx, AV_LOG_WARNING, "Serial cascading is not recommended for i16 precision.\n"); - ret = decompose_zp2biquads(ctx, inlink->channels); if (ret < 0) return ret; + } else if (s->format > 0 && s->process == 2) { + if (s->precision > 1) + av_log(ctx, AV_LOG_WARNING, "Parallel processing is not recommended for fixed-point precisions.\n"); + ret = decompose_zp2biquads(ctx, inlink->channels); + if (ret < 0) + return ret; + ret = convert_serial2parallel(ctx, inlink->channels); + if (ret < 0) + return ret; + } + + for (ch = 0; s->format == -2 && ch < inlink->channels; ch++) { + IIRChannel *iir = &s->iir[ch]; + + if (iir->nb_ab[0] != iir->nb_ab[1] + 1) { + av_log(ctx, AV_LOG_ERROR, "Number of ladder coefficients must be one more than number of reflection coefficients.\n"); + return AVERROR(EINVAL); + } } for (ch = 0; s->format == 0 && ch < inlink->channels; ch++) { @@ -1061,10 +1372,19 @@ static int config_output(AVFilterLink *outlink) } switch (inlink->format) { - case AV_SAMPLE_FMT_DBLP: s->iir_channel = s->process == 1 ? iir_ch_serial_dblp : iir_ch_dblp; break; - case AV_SAMPLE_FMT_FLTP: s->iir_channel = s->process == 1 ? iir_ch_serial_fltp : iir_ch_fltp; break; - case AV_SAMPLE_FMT_S32P: s->iir_channel = s->process == 1 ? iir_ch_serial_s32p : iir_ch_s32p; break; - case AV_SAMPLE_FMT_S16P: s->iir_channel = s->process == 1 ? iir_ch_serial_s16p : iir_ch_s16p; break; + case AV_SAMPLE_FMT_DBLP: s->iir_channel = s->process == 2 ? iir_ch_parallel_dblp : s->process == 1 ? iir_ch_serial_dblp : iir_ch_dblp; break; + case AV_SAMPLE_FMT_FLTP: s->iir_channel = s->process == 2 ? iir_ch_parallel_fltp : s->process == 1 ? iir_ch_serial_fltp : iir_ch_fltp; break; + case AV_SAMPLE_FMT_S32P: s->iir_channel = s->process == 2 ? iir_ch_parallel_s32p : s->process == 1 ? iir_ch_serial_s32p : iir_ch_s32p; break; + case AV_SAMPLE_FMT_S16P: s->iir_channel = s->process == 2 ? iir_ch_parallel_s16p : s->process == 1 ? iir_ch_serial_s16p : iir_ch_s16p; break; + } + + if (s->format == -2) { + switch (inlink->format) { + case AV_SAMPLE_FMT_DBLP: s->iir_channel = iir_ch_lattice_dblp; break; + case AV_SAMPLE_FMT_FLTP: s->iir_channel = iir_ch_lattice_fltp; break; + case AV_SAMPLE_FMT_S32P: s->iir_channel = iir_ch_lattice_s32p; break; + case AV_SAMPLE_FMT_S16P: s->iir_channel = iir_ch_lattice_s16p; break; + } } return 0; @@ -1079,7 +1399,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFrame *out; int ch, ret; - if (av_frame_is_writable(in)) { + if (av_frame_is_writable(in) && s->process != 2) { out = in; } else { out = ff_get_audio_buffer(outlink, in->nb_samples); @@ -1159,26 +1479,21 @@ static av_cold int init(AVFilterContext *ctx) } pad = (AVFilterPad){ - .name = av_strdup("default"), + .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = config_output, }; - if (!pad.name) - return AVERROR(ENOMEM); - ret = ff_insert_outpad(ctx, 0, &pad); if (ret < 0) return ret; if (s->response) { vpad = (AVFilterPad){ - .name = av_strdup("filter_response"), + .name = "filter_response", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_video, }; - if (!vpad.name) - return AVERROR(ENOMEM); ret = ff_insert_outpad(ctx, 1, &vpad); if (ret < 0) @@ -1205,9 +1520,6 @@ static av_cold void uninit(AVFilterContext *ctx) } av_freep(&s->iir); - av_freep(&ctx->output_pads[0].name); - if (s->response) - av_freep(&ctx->output_pads[1].name); av_frame_free(&s->video); } @@ -1225,25 +1537,28 @@ static const AVFilterPad inputs[] = { #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM static const AVOption aiir_options[] = { - { "zeros", "set B/numerator/zeros coefficients", OFFSET(b_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF }, - { "z", "set B/numerator/zeros coefficients", OFFSET(b_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF }, - { "poles", "set A/denominator/poles coefficients", OFFSET(a_str),AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF }, - { "p", "set A/denominator/poles coefficients", OFFSET(a_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF }, + { "zeros", "set B/numerator/zeros/reflection coefficients", OFFSET(b_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF }, + { "z", "set B/numerator/zeros/reflection coefficients", OFFSET(b_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF }, + { "poles", "set A/denominator/poles/ladder coefficients", OFFSET(a_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF }, + { "p", "set A/denominator/poles/ladder coefficients", OFFSET(a_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF }, { "gains", "set channels gains", OFFSET(g_str), AV_OPT_TYPE_STRING, {.str="1|1"}, 0, 0, AF }, { "k", "set channels gains", OFFSET(g_str), AV_OPT_TYPE_STRING, {.str="1|1"}, 0, 0, AF }, { "dry", "set dry gain", OFFSET(dry_gain), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, AF }, { "wet", "set wet gain", OFFSET(wet_gain), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, AF }, - { "format", "set coefficients format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, AF, "format" }, - { "f", "set coefficients format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, AF, "format" }, + { "format", "set coefficients format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=1}, -2, 4, AF, "format" }, + { "f", "set coefficients format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=1}, -2, 4, AF, "format" }, + { "ll", "lattice-ladder function", 0, AV_OPT_TYPE_CONST, {.i64=-2}, 0, 0, AF, "format" }, + { "sf", "analog transfer function", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "format" }, { "tf", "digital transfer function", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "format" }, { "zp", "Z-plane zeros/poles", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "format" }, { "pr", "Z-plane zeros/poles (polar radians)", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "format" }, { "pd", "Z-plane zeros/poles (polar degrees)", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "format" }, { "sp", "S-plane zeros/poles", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF, "format" }, - { "process", "set kind of processing", OFFSET(process), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "process" }, - { "r", "set kind of processing", OFFSET(process), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "process" }, + { "process", "set kind of processing", OFFSET(process), AV_OPT_TYPE_INT, {.i64=1}, 0, 2, AF, "process" }, + { "r", "set kind of processing", OFFSET(process), AV_OPT_TYPE_INT, {.i64=1}, 0, 2, AF, "process" }, { "d", "direct", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "process" }, - { "s", "serial cascading", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "process" }, + { "s", "serial", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "process" }, + { "p", "parallel", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "process" }, { "precision", "set filtering precision", OFFSET(precision),AV_OPT_TYPE_INT, {.i64=0}, 0, 3, AF, "precision" }, { "e", "set precision", OFFSET(precision),AV_OPT_TYPE_INT, {.i64=0}, 0, 3, AF, "precision" }, { "dbl", "double-precision floating-point", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision" }, diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c index 567f25982..a914fd45c 100644 --- a/libavfilter/af_amerge.c +++ b/libavfilter/af_amerge.c @@ -58,17 +58,22 @@ AVFILTER_DEFINE_CLASS(amerge); static av_cold void uninit(AVFilterContext *ctx) { AMergeContext *s = ctx->priv; - int i; - for (i = 0; i < s->nb_inputs; i++) { - if (ctx->input_pads) - av_freep(&ctx->input_pads[i].name); - } av_freep(&s->in); + for (unsigned i = 0; i < ctx->nb_inputs; i++) + av_freep(&ctx->input_pads[i].name); } static int query_formats(AVFilterContext *ctx) { + static const enum AVSampleFormat packed_sample_fmts[] = { + AV_SAMPLE_FMT_U8, + AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_S32, + AV_SAMPLE_FMT_FLT, + AV_SAMPLE_FMT_DBL, + AV_SAMPLE_FMT_NONE + }; AMergeContext *s = ctx->priv; int64_t inlayout[SWR_CH_MAX], outlayout = 0; AVFilterFormats *formats; @@ -76,14 +81,14 @@ static int query_formats(AVFilterContext *ctx) int i, ret, overlap = 0, nb_ch = 0; for (i = 0; i < s->nb_inputs; i++) { - if (!ctx->inputs[i]->in_channel_layouts || - !ctx->inputs[i]->in_channel_layouts->nb_channel_layouts) { + if (!ctx->inputs[i]->incfg.channel_layouts || + !ctx->inputs[i]->incfg.channel_layouts->nb_channel_layouts) { av_log(ctx, AV_LOG_WARNING, "No channel layout for input %d\n", i + 1); return AVERROR(EAGAIN); } - inlayout[i] = ctx->inputs[i]->in_channel_layouts->channel_layouts[0]; - if (ctx->inputs[i]->in_channel_layouts->nb_channel_layouts > 1) { + inlayout[i] = ctx->inputs[i]->incfg.channel_layouts->channel_layouts[0]; + if (ctx->inputs[i]->incfg.channel_layouts->nb_channel_layouts > 1) { char buf[256]; av_get_channel_layout_string(buf, sizeof(buf), 0, inlayout[i]); av_log(ctx, AV_LOG_INFO, "Using \"%s\" for input %d\n", buf, i + 1); @@ -124,20 +129,20 @@ static int query_formats(AVFilterContext *ctx) if ((inlayout[i] >> c) & 1) *(route[i]++) = out_ch_number++; } - formats = ff_make_format_list(ff_packed_sample_fmts_array); + formats = ff_make_format_list(packed_sample_fmts); if ((ret = ff_set_common_formats(ctx, formats)) < 0) return ret; for (i = 0; i < s->nb_inputs; i++) { layouts = NULL; if ((ret = ff_add_channel_layout(&layouts, inlayout[i])) < 0) return ret; - if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0) return ret; } layouts = NULL; if ((ret = ff_add_channel_layout(&layouts, outlayout)) < 0) return ret; - if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0) return ret; return ff_set_common_samplerates(ctx, ff_all_samplerates()); diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 0826fc118..45a5dadf0 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -164,6 +164,7 @@ typedef struct MixContext { int duration_mode; /**< mode for determining duration */ float dropout_transition; /**< transition time when an input drops out */ char *weights_str; /**< string for custom weights for every input */ + int normalize; /**< if inputs are scaled */ int nb_channels; /**< number of channels */ int sample_rate; /**< sample rate */ @@ -195,6 +196,8 @@ static const AVOption amix_options[] = { OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A|F }, { "weights", "Set weight for each input.", OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, A|F|T }, + { "normalize", "Scale inputs", + OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, A|F|T }, { NULL } }; @@ -227,10 +230,14 @@ static void calculate_scales(MixContext *s, int nb_samples) } for (i = 0; i < s->nb_inputs; i++) { - if (s->input_state[i] & INPUT_ON) - s->input_scale[i] = 1.0f / s->scale_norm[i] * FFSIGN(s->weights[i]); - else + if (s->input_state[i] & INPUT_ON) { + if (!s->normalize) + s->input_scale[i] = FFABS(s->weights[i]); + else + s->input_scale[i] = 1.0f / s->scale_norm[i] * FFSIGN(s->weights[i]); + } else { s->input_scale[i] = 0.0f; + } } } @@ -309,6 +316,8 @@ static int output_frame(AVFilterLink *outlink) } } } + + s->next_pts = frame_list_next_pts(s->frame_list); } else { /* first input closed: use the available samples */ nb_samples = INT_MAX; @@ -324,7 +333,6 @@ static int output_frame(AVFilterLink *outlink) } } - s->next_pts = frame_list_next_pts(s->frame_list); frame_list_remove_samples(s->frame_list, nb_samples); calculate_scales(s, nb_samples); @@ -588,30 +596,18 @@ static av_cold void uninit(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { - AVFilterFormats *formats = NULL; - AVFilterChannelLayouts *layouts; + static const enum AVSampleFormat sample_fmts[] = { + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_NONE + }; int ret; - layouts = ff_all_channel_counts(); - if (!layouts) { - ret = AVERROR(ENOMEM); - goto fail; - } - - if ((ret = ff_add_format(&formats, AV_SAMPLE_FMT_FLT )) < 0 || - (ret = ff_add_format(&formats, AV_SAMPLE_FMT_FLTP)) < 0 || - (ret = ff_add_format(&formats, AV_SAMPLE_FMT_DBL )) < 0 || - (ret = ff_add_format(&formats, AV_SAMPLE_FMT_DBLP)) < 0 || - (ret = ff_set_common_formats (ctx, formats)) < 0 || - (ret = ff_set_common_channel_layouts(ctx, layouts)) < 0 || + if ((ret = ff_set_common_formats(ctx, ff_make_format_list(sample_fmts))) < 0 || (ret = ff_set_common_samplerates(ctx, ff_all_samplerates())) < 0) - goto fail; - return 0; -fail: - if (layouts) - av_freep(&layouts->channel_layouts); - av_freep(&layouts); - return ret; + return ret; + + return ff_set_common_channel_layouts(ctx, ff_all_channel_counts()); } static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, diff --git a/libavfilter/af_anequalizer.c b/libavfilter/af_anequalizer.c index 177e1c7b3..80e2c690f 100644 --- a/libavfilter/af_anequalizer.c +++ b/libavfilter/af_anequalizer.c @@ -192,37 +192,23 @@ static av_cold int init(AVFilterContext *ctx) int ret; pad = (AVFilterPad){ - .name = av_strdup("out0"), + .name = "out0", .type = AVMEDIA_TYPE_AUDIO, }; - if (!pad.name) - return AVERROR(ENOMEM); + ret = ff_insert_outpad(ctx, 0, &pad); + if (ret < 0) + return ret; if (s->draw_curves) { vpad = (AVFilterPad){ - .name = av_strdup("out1"), + .name = "out1", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_video, }; - if (!vpad.name) { - av_freep(&pad.name); - return AVERROR(ENOMEM); - } - } - - ret = ff_insert_outpad(ctx, 0, &pad); - if (ret < 0) { - av_freep(&pad.name); - return ret; - } - - if (s->draw_curves) { ret = ff_insert_outpad(ctx, 1, &vpad); - if (ret < 0) { - av_freep(&vpad.name); + if (ret < 0) return ret; - } } return 0; @@ -245,23 +231,23 @@ static int query_formats(AVFilterContext *ctx) if (s->draw_curves) { AVFilterLink *videolink = ctx->outputs[1]; formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &videolink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &videolink->incfg.formats)) < 0) return ret; } formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0 || - (ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0 || + (ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; layouts = ff_all_channel_counts(); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0 || - (ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0 || + (ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0 || - (ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0 || + (ret = ff_formats_ref(formats, &outlink->incfg.samplerates)) < 0) return ret; return 0; @@ -271,8 +257,6 @@ static av_cold void uninit(AVFilterContext *ctx) { AudioNEqualizerContext *s = ctx->priv; - for (int i = 0; i < ctx->nb_outputs; i++) - av_freep(&ctx->output_pads[i].name); av_frame_free(&s->video); av_freep(&s->filters); s->nb_filters = 0; @@ -709,22 +693,26 @@ static double process_sample(FoSection *s1, double in) return p1; } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int filter_channels(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs) { - AVFilterContext *ctx = inlink->dst; AudioNEqualizerContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - double *bptr; - int i, n; + AVFrame *buf = arg; + const int start = (buf->channels * jobnr) / nb_jobs; + const int end = (buf->channels * (jobnr+1)) / nb_jobs; - for (i = 0; i < s->nb_filters; i++) { + for (int i = 0; i < s->nb_filters; i++) { EqualizatorFilter *f = &s->filters[i]; + double *bptr; if (f->gain == 0. || f->ignore) continue; + if (f->channel < start || + f->channel >= end) + continue; bptr = (double *)buf->extended_data[f->channel]; - for (n = 0; n < buf->nb_samples; n++) { + for (int n = 0; n < buf->nb_samples; n++) { double sample = bptr[n]; sample = process_sample(f->section, sample); @@ -732,6 +720,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) } } + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +{ + AVFilterContext *ctx = inlink->dst; + AudioNEqualizerContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + + if (!ctx->is_disabled) + ctx->internal->execute(ctx, filter_channels, buf, NULL, FFMIN(inlink->channels, + ff_filter_get_nb_threads(ctx))); + if (s->draw_curves) { AVFrame *clone; @@ -773,6 +774,8 @@ AVFilter ff_af_anequalizer = { .query_formats = query_formats, .inputs = inputs, .outputs = NULL, - .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, .process_command = process_command, + .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS | + AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | + AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/af_anlmdn.c b/libavfilter/af_anlmdn.c index b8aef31c3..e2661e102 100644 --- a/libavfilter/af_anlmdn.c +++ b/libavfilter/af_anlmdn.c @@ -72,18 +72,17 @@ enum OutModes { }; #define OFFSET(x) offsetof(AudioNLMeansContext, x) -#define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM #define AFT AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption anlmdn_options[] = { { "s", "set denoising strength", OFFSET(a), AV_OPT_TYPE_FLOAT, {.dbl=0.00001},0.00001, 10, AFT }, - { "p", "set patch duration", OFFSET(pd), AV_OPT_TYPE_DURATION, {.i64=2000}, 1000, 100000, AF }, - { "r", "set research duration", OFFSET(rd), AV_OPT_TYPE_DURATION, {.i64=6000}, 2000, 300000, AF }, + { "p", "set patch duration", OFFSET(pd), AV_OPT_TYPE_DURATION, {.i64=2000}, 1000, 100000, AFT }, + { "r", "set research duration", OFFSET(rd), AV_OPT_TYPE_DURATION, {.i64=6000}, 2000, 300000, AFT }, { "o", "set output mode", OFFSET(om), AV_OPT_TYPE_INT, {.i64=OUT_MODE}, 0, NB_MODES-1, AFT, "mode" }, { "i", "input", 0, AV_OPT_TYPE_CONST, {.i64=IN_MODE}, 0, 0, AFT, "mode" }, { "o", "output", 0, AV_OPT_TYPE_CONST, {.i64=OUT_MODE}, 0, 0, AFT, "mode" }, { "n", "noise", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_MODE},0, 0, AFT, "mode" }, - { "m", "set smooth factor", OFFSET(m), AV_OPT_TYPE_FLOAT, {.dbl=11.}, 1, 15, AF }, + { "m", "set smooth factor", OFFSET(m), AV_OPT_TYPE_FLOAT, {.dbl=11.}, 1, 15, AFT }, { NULL } }; @@ -147,31 +146,72 @@ void ff_anlmdn_init(AudioNLMDNDSPContext *dsp) ff_anlmdn_init_x86(dsp); } +static int config_filter(AVFilterContext *ctx) +{ + AudioNLMeansContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + int newK, newS, newH, newN; + AVFrame *new_in, *new_cache; + + newK = av_rescale(s->pd, outlink->sample_rate, AV_TIME_BASE); + newS = av_rescale(s->rd, outlink->sample_rate, AV_TIME_BASE); + + newH = newK * 2 + 1; + newN = newH + (newK + newS) * 2; + + av_log(ctx, AV_LOG_DEBUG, "K:%d S:%d H:%d N:%d\n", newK, newS, newH, newN); + + if (!s->cache || s->cache->nb_samples < newS * 2) { + new_cache = ff_get_audio_buffer(outlink, newS * 2); + if (new_cache) { + av_frame_free(&s->cache); + s->cache = new_cache; + } else { + return AVERROR(ENOMEM); + } + } + if (!s->cache) + return AVERROR(ENOMEM); + + s->pdiff_lut_scale = 1.f / s->m * WEIGHT_LUT_SIZE; + for (int i = 0; i < WEIGHT_LUT_SIZE; i++) { + float w = -i / s->pdiff_lut_scale; + + s->weight_lut[i] = expf(w); + } + + if (!s->in || s->in->nb_samples < newN) { + new_in = ff_get_audio_buffer(outlink, newN); + if (new_in) { + av_frame_free(&s->in); + s->in = new_in; + } else { + return AVERROR(ENOMEM); + } + } + if (!s->in) + return AVERROR(ENOMEM); + + s->K = newK; + s->S = newS; + s->H = newH; + s->N = newN; + + return 0; +} + static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; AudioNLMeansContext *s = ctx->priv; int ret; - s->K = av_rescale(s->pd, outlink->sample_rate, AV_TIME_BASE); - s->S = av_rescale(s->rd, outlink->sample_rate, AV_TIME_BASE); - s->eof_left = -1; s->pts = AV_NOPTS_VALUE; - s->H = s->K * 2 + 1; - s->N = s->H + (s->K + s->S) * 2; - av_log(ctx, AV_LOG_DEBUG, "K:%d S:%d H:%d N:%d\n", s->K, s->S, s->H, s->N); - - av_frame_free(&s->in); - av_frame_free(&s->cache); - s->in = ff_get_audio_buffer(outlink, s->N); - if (!s->in) - return AVERROR(ENOMEM); - - s->cache = ff_get_audio_buffer(outlink, s->S * 2); - if (!s->cache) - return AVERROR(ENOMEM); + ret = config_filter(ctx); + if (ret < 0) + return ret; s->fifo = av_audio_fifo_alloc(outlink->format, outlink->channels, s->N); if (!s->fifo) @@ -181,13 +221,6 @@ static int config_output(AVFilterLink *outlink) if (ret < 0) return ret; - s->pdiff_lut_scale = 1.f / s->m * WEIGHT_LUT_SIZE; - for (int i = 0; i < WEIGHT_LUT_SIZE; i++) { - float w = -i / s->pdiff_lut_scale; - - s->weight_lut[i] = expf(w); - } - ff_anlmdn_init(&s->dsp); return 0; @@ -331,6 +364,22 @@ static int request_frame(AVFilterLink *outlink) return ret; } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + ret = config_filter(ctx); + if (ret < 0) + return ret; + + return 0; +} + static av_cold void uninit(AVFilterContext *ctx) { AudioNLMeansContext *s = ctx->priv; @@ -368,7 +417,7 @@ AVFilter ff_af_anlmdn = { .uninit = uninit, .inputs = inputs, .outputs = outputs, - .process_command = ff_filter_process_command, + .process_command = process_command, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c index ef10621c3..e54bd3eb4 100644 --- a/libavfilter/af_aresample.c +++ b/libavfilter/af_aresample.c @@ -95,15 +95,15 @@ static int query_formats(AVFilterContext *ctx) av_opt_get_int(aresample->swr, "ocl", 0, &out_layout); in_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); - if ((ret = ff_formats_ref(in_formats, &inlink->out_formats)) < 0) + if ((ret = ff_formats_ref(in_formats, &inlink->outcfg.formats)) < 0) return ret; in_samplerates = ff_all_samplerates(); - if ((ret = ff_formats_ref(in_samplerates, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(in_samplerates, &inlink->outcfg.samplerates)) < 0) return ret; in_layouts = ff_all_channel_counts(); - if ((ret = ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(in_layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; if(out_rate > 0) { @@ -113,7 +113,7 @@ static int query_formats(AVFilterContext *ctx) out_samplerates = ff_all_samplerates(); } - if ((ret = ff_formats_ref(out_samplerates, &outlink->in_samplerates)) < 0) + if ((ret = ff_formats_ref(out_samplerates, &outlink->incfg.samplerates)) < 0) return ret; if(out_format != AV_SAMPLE_FMT_NONE) { @@ -121,16 +121,16 @@ static int query_formats(AVFilterContext *ctx) out_formats = ff_make_format_list(formatlist); } else out_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); - if ((ret = ff_formats_ref(out_formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(out_formats, &outlink->incfg.formats)) < 0) return ret; if(out_layout) { int64_t layout_list[] = { out_layout, -1 }; - out_layouts = avfilter_make_format64_list(layout_list); + out_layouts = ff_make_format64_list(layout_list); } else out_layouts = ff_all_channel_counts(); - return ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); + return ff_channel_layouts_ref(out_layouts, &outlink->incfg.channel_layouts); } @@ -293,10 +293,19 @@ static int request_frame(AVFilterLink *outlink) return ret; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *resample_child_class_next(const AVClass *prev) { return prev ? NULL : swr_get_class(); } +#endif + +static const AVClass *resample_child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : swr_get_class(); + *iter = (void*)(uintptr_t)c; + return c; +} static void *resample_child_next(void *obj, void *prev) { @@ -317,7 +326,10 @@ static const AVClass aresample_class = { .item_name = av_default_item_name, .option = options, .version = LIBAVUTIL_VERSION_INT, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = resample_child_class_next, +#endif + .child_class_iterate = resample_child_class_iterate, .child_next = resample_child_next, }; diff --git a/libavfilter/af_arnndn.c b/libavfilter/af_arnndn.c index 7a26f8970..049865b58 100644 --- a/libavfilter/af_arnndn.c +++ b/libavfilter/af_arnndn.c @@ -36,6 +36,7 @@ #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/float_dsp.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/tx.h" #include "avfilter.h" @@ -127,7 +128,8 @@ typedef struct DenoiseState { int last_period; float mem_hp_x[2]; float lastg[NB_BANDS]; - RNNState rnn; + float history[FRAME_SIZE]; + RNNState rnn[2]; AVTXContext *tx, *txi; av_tx_fn tx_fn, txi_fn; } DenoiseState; @@ -136,14 +138,15 @@ typedef struct AudioRNNContext { const AVClass *class; char *model_name; + float mix; int channels; DenoiseState *st; DECLARE_ALIGNED(32, float, window)[WINDOW_SIZE]; - float dct_table[NB_BANDS*NB_BANDS]; + DECLARE_ALIGNED(32, float, dct_table)[FFALIGN(NB_BANDS, 4)][FFALIGN(NB_BANDS, 4)]; - RNNModel *model; + RNNModel *model[2]; AVFloatDSPContext *fdsp; } AudioRNNContext; @@ -182,9 +185,9 @@ static void rnnoise_model_free(RNNModel *model) av_free(model); } -static RNNModel *rnnoise_model_from_file(FILE *f) +static int rnnoise_model_from_file(FILE *f, RNNModel **rnn) { - RNNModel *ret; + RNNModel *ret = NULL; DenseLayer *input_dense; GRULayer *vad_gru; GRULayer *noise_gru; @@ -194,17 +197,17 @@ static RNNModel *rnnoise_model_from_file(FILE *f) int in; if (fscanf(f, "rnnoise-nu model file version %d\n", &in) != 1 || in != 1) - return NULL; + return AVERROR_INVALIDDATA; ret = av_calloc(1, sizeof(RNNModel)); if (!ret) - return NULL; + return AVERROR(ENOMEM); #define ALLOC_LAYER(type, name) \ name = av_calloc(1, sizeof(type)); \ if (!name) { \ rnnoise_model_free(ret); \ - return NULL; \ + return AVERROR(ENOMEM); \ } \ ret->name = name @@ -218,7 +221,7 @@ static RNNModel *rnnoise_model_from_file(FILE *f) #define INPUT_VAL(name) do { \ if (fscanf(f, "%d", &in) != 1 || in < 0 || in > 128) { \ rnnoise_model_free(ret); \ - return NULL; \ + return AVERROR(EINVAL); \ } \ name = in; \ } while (0) @@ -242,13 +245,13 @@ static RNNModel *rnnoise_model_from_file(FILE *f) float *values = av_calloc((len), sizeof(float)); \ if (!values) { \ rnnoise_model_free(ret); \ - return NULL; \ + return AVERROR(ENOMEM); \ } \ name = values; \ for (int i = 0; i < (len); i++) { \ if (fscanf(f, "%d", &in) != 1) { \ rnnoise_model_free(ret); \ - return NULL; \ + return AVERROR(EINVAL); \ } \ values[i] = in; \ } \ @@ -258,7 +261,7 @@ static RNNModel *rnnoise_model_from_file(FILE *f) float *values = av_calloc(FFALIGN((len0), 4) * FFALIGN((len1), 4) * (len2), sizeof(float)); \ if (!values) { \ rnnoise_model_free(ret); \ - return NULL; \ + return AVERROR(ENOMEM); \ } \ name = values; \ for (int k = 0; k < (len0); k++) { \ @@ -266,7 +269,7 @@ static RNNModel *rnnoise_model_from_file(FILE *f) for (int j = 0; j < (len1); j++) { \ if (fscanf(f, "%d", &in) != 1) { \ rnnoise_model_free(ret); \ - return NULL; \ + return AVERROR(EINVAL); \ } \ values[j * (len2) * FFALIGN((len0), 4) + i * FFALIGN((len0), 4) + k] = in; \ } \ @@ -274,13 +277,24 @@ static RNNModel *rnnoise_model_from_file(FILE *f) } \ } while (0) +#define NEW_LINE() do { \ + int c; \ + while ((c = fgetc(f)) != EOF) { \ + if (c == '\n') \ + break; \ + } \ + } while (0) + #define INPUT_DENSE(name) do { \ INPUT_VAL(name->nb_inputs); \ INPUT_VAL(name->nb_neurons); \ ret->name ## _size = name->nb_neurons; \ INPUT_ACTIVATION(name->activation); \ + NEW_LINE(); \ INPUT_ARRAY(name->input_weights, name->nb_inputs * name->nb_neurons); \ + NEW_LINE(); \ INPUT_ARRAY(name->bias, name->nb_neurons); \ + NEW_LINE(); \ } while (0) #define INPUT_GRU(name) do { \ @@ -288,9 +302,13 @@ static RNNModel *rnnoise_model_from_file(FILE *f) INPUT_VAL(name->nb_neurons); \ ret->name ## _size = name->nb_neurons; \ INPUT_ACTIVATION(name->activation); \ + NEW_LINE(); \ INPUT_ARRAY3(name->input_weights, name->nb_inputs, name->nb_neurons, 3); \ + NEW_LINE(); \ INPUT_ARRAY3(name->recurrent_weights, name->nb_neurons, name->nb_neurons, 3); \ + NEW_LINE(); \ INPUT_ARRAY(name->bias, name->nb_neurons * 3); \ + NEW_LINE(); \ } while (0) INPUT_DENSE(input_dense); @@ -302,10 +320,12 @@ static RNNModel *rnnoise_model_from_file(FILE *f) if (vad_output->nb_neurons != 1) { rnnoise_model_free(ret); - return NULL; + return AVERROR(EINVAL); } - return ret; + *rnn = ret; + + return 0; } static int query_formats(AVFilterContext *ctx) @@ -347,27 +367,34 @@ static int config_input(AVFilterLink *inlink) s->channels = inlink->channels; - s->st = av_calloc(s->channels, sizeof(DenoiseState)); + if (!s->st) + s->st = av_calloc(s->channels, sizeof(DenoiseState)); if (!s->st) return AVERROR(ENOMEM); for (int i = 0; i < s->channels; i++) { DenoiseState *st = &s->st[i]; - st->rnn.model = s->model; - st->rnn.vad_gru_state = av_calloc(sizeof(float), FFALIGN(s->model->vad_gru_size, 16)); - st->rnn.noise_gru_state = av_calloc(sizeof(float), FFALIGN(s->model->noise_gru_size, 16)); - st->rnn.denoise_gru_state = av_calloc(sizeof(float), FFALIGN(s->model->denoise_gru_size, 16)); - if (!st->rnn.vad_gru_state || - !st->rnn.noise_gru_state || - !st->rnn.denoise_gru_state) + st->rnn[0].model = s->model[0]; + st->rnn[0].vad_gru_state = av_calloc(sizeof(float), FFALIGN(s->model[0]->vad_gru_size, 16)); + st->rnn[0].noise_gru_state = av_calloc(sizeof(float), FFALIGN(s->model[0]->noise_gru_size, 16)); + st->rnn[0].denoise_gru_state = av_calloc(sizeof(float), FFALIGN(s->model[0]->denoise_gru_size, 16)); + if (!st->rnn[0].vad_gru_state || + !st->rnn[0].noise_gru_state || + !st->rnn[0].denoise_gru_state) return AVERROR(ENOMEM); + } - ret = av_tx_init(&st->tx, &st->tx_fn, AV_TX_FLOAT_FFT, 0, WINDOW_SIZE, NULL, 0); + for (int i = 0; i < s->channels; i++) { + DenoiseState *st = &s->st[i]; + + if (!st->tx) + ret = av_tx_init(&st->tx, &st->tx_fn, AV_TX_FLOAT_FFT, 0, WINDOW_SIZE, NULL, 0); if (ret < 0) return ret; - ret = av_tx_init(&st->txi, &st->txi_fn, AV_TX_FLOAT_FFT, 1, WINDOW_SIZE, NULL, 0); + if (!st->txi) + ret = av_tx_init(&st->txi, &st->txi_fn, AV_TX_FLOAT_FFT, 1, WINDOW_SIZE, NULL, 0); if (ret < 0) return ret; } @@ -413,8 +440,7 @@ static void inverse_transform(DenoiseState *st, float *out, const AVComplexFloat AVComplexFloat x[WINDOW_SIZE]; AVComplexFloat y[WINDOW_SIZE]; - for (int i = 0; i < FREQ_SIZE; i++) - x[i] = in[i]; + RNN_COPY(x, in, FREQ_SIZE); for (int i = FREQ_SIZE; i < WINDOW_SIZE; i++) { x[i].re = x[WINDOW_SIZE - i].re; @@ -497,12 +523,18 @@ static void frame_analysis(AudioRNNContext *s, DenoiseState *st, AVComplexFloat static void frame_synthesis(AudioRNNContext *s, DenoiseState *st, float *out, const AVComplexFloat *y) { LOCAL_ALIGNED_32(float, x, [WINDOW_SIZE]); + const float *src = st->history; + const float mix = s->mix; + const float imix = 1.f - FFMAX(mix, 0.f); inverse_transform(st, x, y); s->fdsp->vector_fmul(x, x, s->window, WINDOW_SIZE); s->fdsp->vector_fmac_scalar(x, st->synthesis_mem, 1.f, FRAME_SIZE); RNN_COPY(out, x, FRAME_SIZE); RNN_COPY(st->synthesis_mem, &x[FRAME_SIZE], FRAME_SIZE); + + for (int n = 0; n < FRAME_SIZE; n++) + out[n] = out[n] * mix + src[n] * imix; } static inline void xcorr_kernel(const float *x, const float *y, float sum[4], int len) @@ -781,7 +813,7 @@ static float compute_pitch_gain(float xy, float xx, float yy) return xy / sqrtf(1.f + xx * yy); } -static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2}; +static const uint8_t second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2}; static float remove_doubling(float *x, int maxperiod, int minperiod, int N, int *T0_, int prev_period, float prev_gain) { @@ -992,11 +1024,9 @@ static void pitch_search(const float *x_lp, float *y, static void dct(AudioRNNContext *s, float *out, const float *in) { for (int i = 0; i < NB_BANDS; i++) { - float sum = 0.f; + float sum; - for (int j = 0; j < NB_BANDS; j++) { - sum += in[j] * s->dct_table[j * NB_BANDS + i]; - } + sum = s->fdsp->scalarproduct_float(in, s->dct_table[i], FFALIGN(NB_BANDS, 4)); out[i] = sum * sqrtf(2.f / 22); } } @@ -1007,7 +1037,7 @@ static int compute_frame_features(AudioRNNContext *s, DenoiseState *st, AVComple float E = 0; float *ceps_0, *ceps_1, *ceps_2; float spec_variability = 0; - float Ly[NB_BANDS]; + LOCAL_ALIGNED_32(float, Ly, [NB_BANDS]); LOCAL_ALIGNED_32(float, p, [WINDOW_SIZE]); float pitch_buf[PITCH_BUF_SIZE>>1]; int pitch_index; @@ -1323,37 +1353,37 @@ static void compute_rnn(AudioRNNContext *s, RNNState *rnn, float *gains, float * compute_gru(s, rnn->model->vad_gru, rnn->vad_gru_state, dense_out); compute_dense(rnn->model->vad_output, vad, rnn->vad_gru_state); - for (int i = 0; i < rnn->model->input_dense_size; i++) - noise_input[i] = dense_out[i]; - for (int i = 0; i < rnn->model->vad_gru_size; i++) - noise_input[i + rnn->model->input_dense_size] = rnn->vad_gru_state[i]; - for (int i = 0; i < INPUT_SIZE; i++) - noise_input[i + rnn->model->input_dense_size + rnn->model->vad_gru_size] = input[i]; + memcpy(noise_input, dense_out, rnn->model->input_dense_size * sizeof(float)); + memcpy(noise_input + rnn->model->input_dense_size, + rnn->vad_gru_state, rnn->model->vad_gru_size * sizeof(float)); + memcpy(noise_input + rnn->model->input_dense_size + rnn->model->vad_gru_size, + input, INPUT_SIZE * sizeof(float)); compute_gru(s, rnn->model->noise_gru, rnn->noise_gru_state, noise_input); - for (int i = 0; i < rnn->model->vad_gru_size; i++) - denoise_input[i] = rnn->vad_gru_state[i]; - for (int i = 0; i < rnn->model->noise_gru_size; i++) - denoise_input[i + rnn->model->vad_gru_size] = rnn->noise_gru_state[i]; - for (int i = 0; i < INPUT_SIZE; i++) - denoise_input[i + rnn->model->vad_gru_size + rnn->model->noise_gru_size] = input[i]; + memcpy(denoise_input, rnn->vad_gru_state, rnn->model->vad_gru_size * sizeof(float)); + memcpy(denoise_input + rnn->model->vad_gru_size, + rnn->noise_gru_state, rnn->model->noise_gru_size * sizeof(float)); + memcpy(denoise_input + rnn->model->vad_gru_size + rnn->model->noise_gru_size, + input, INPUT_SIZE * sizeof(float)); compute_gru(s, rnn->model->denoise_gru, rnn->denoise_gru_state, denoise_input); compute_dense(rnn->model->denoise_output, gains, rnn->denoise_gru_state); } -static float rnnoise_channel(AudioRNNContext *s, DenoiseState *st, float *out, const float *in) +static float rnnoise_channel(AudioRNNContext *s, DenoiseState *st, float *out, const float *in, + int disabled) { AVComplexFloat X[FREQ_SIZE]; AVComplexFloat P[WINDOW_SIZE]; float x[FRAME_SIZE]; float Ex[NB_BANDS], Ep[NB_BANDS]; - float Exp[NB_BANDS]; + LOCAL_ALIGNED_32(float, Exp, [NB_BANDS]); float features[NB_FEATURES]; float g[NB_BANDS]; float gf[FREQ_SIZE]; float vad_prob = 0; + float *history = st->history; static const float a_hp[2] = {-1.99599, 0.99600}; static const float b_hp[2] = {-2, 1}; int silence; @@ -1361,8 +1391,8 @@ static float rnnoise_channel(AudioRNNContext *s, DenoiseState *st, float *out, c biquad(x, st->mem_hp_x, in, b_hp, a_hp, FRAME_SIZE); silence = compute_frame_features(s, st, X, P, Ex, Ep, Exp, features, x); - if (!silence) { - compute_rnn(s, &st->rnn, g, &vad_prob, features); + if (!silence && !disabled) { + compute_rnn(s, &st->rnn[0], g, &vad_prob, features); pitch_filter(X, P, Ex, Ep, Exp, g); for (int i = 0; i < NB_BANDS; i++) { float alpha = .6f; @@ -1380,6 +1410,7 @@ static float rnnoise_channel(AudioRNNContext *s, DenoiseState *st, float *out, c } frame_synthesis(s, st, out, X); + memcpy(history, in, FRAME_SIZE * sizeof(*history)); return vad_prob; } @@ -1400,7 +1431,8 @@ static int rnnoise_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_j for (int ch = start; ch < end; ch++) { rnnoise_channel(s, &s->st[ch], (float *)out->extended_data[ch], - (const float *)in->extended_data[ch]); + (const float *)in->extended_data[ch], + ctx->is_disabled); } return 0; @@ -1450,25 +1482,40 @@ static int activate(AVFilterContext *ctx) return FFERROR_NOT_READY; } +static int open_model(AVFilterContext *ctx, RNNModel **model) +{ + AudioRNNContext *s = ctx->priv; + int ret; + FILE *f; + + if (!s->model_name) + return AVERROR(EINVAL); + f = av_fopen_utf8(s->model_name, "r"); + if (!f) { + av_log(ctx, AV_LOG_ERROR, "Failed to open model file: %s\n", s->model_name); + return AVERROR(EINVAL); + } + + ret = rnnoise_model_from_file(f, model); + fclose(f); + if (!*model || ret < 0) + return ret; + + return 0; +} + static av_cold int init(AVFilterContext *ctx) { AudioRNNContext *s = ctx->priv; - FILE *f; + int ret; s->fdsp = avpriv_float_dsp_alloc(0); if (!s->fdsp) return AVERROR(ENOMEM); - if (!s->model_name) - return AVERROR(EINVAL); - f = av_fopen_utf8(s->model_name, "r"); - if (!f) - return AVERROR(EINVAL); - - s->model = rnnoise_model_from_file(f); - fclose(f); - if (!s->model) - return AVERROR(EINVAL); + ret = open_model(ctx, &s->model[0]); + if (ret < 0) + return ret; for (int i = 0; i < FRAME_SIZE; i++) { s->window[i] = sin(.5*M_PI*sin(.5*M_PI*(i+.5)/FRAME_SIZE) * sin(.5*M_PI*(i+.5)/FRAME_SIZE)); @@ -1477,31 +1524,68 @@ static av_cold int init(AVFilterContext *ctx) for (int i = 0; i < NB_BANDS; i++) { for (int j = 0; j < NB_BANDS; j++) { - s->dct_table[i*NB_BANDS + j] = cosf((i + .5f) * j * M_PI / NB_BANDS); + s->dct_table[j][i] = cosf((i + .5f) * j * M_PI / NB_BANDS); if (j == 0) - s->dct_table[i*NB_BANDS + j] *= sqrtf(.5); + s->dct_table[j][i] *= sqrtf(.5); } } return 0; } +static void free_model(AVFilterContext *ctx, int n) +{ + AudioRNNContext *s = ctx->priv; + + rnnoise_model_free(s->model[n]); + s->model[n] = NULL; + + for (int ch = 0; ch < s->channels && s->st; ch++) { + av_freep(&s->st[ch].rnn[n].vad_gru_state); + av_freep(&s->st[ch].rnn[n].noise_gru_state); + av_freep(&s->st[ch].rnn[n].denoise_gru_state); + } +} + +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + AudioRNNContext *s = ctx->priv; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + ret = open_model(ctx, &s->model[1]); + if (ret < 0) + return ret; + + FFSWAP(RNNModel *, s->model[0], s->model[1]); + for (int ch = 0; ch < s->channels; ch++) + FFSWAP(RNNState, s->st[ch].rnn[0], s->st[ch].rnn[1]); + + ret = config_input(ctx->inputs[0]); + if (ret < 0) { + for (int ch = 0; ch < s->channels; ch++) + FFSWAP(RNNState, s->st[ch].rnn[0], s->st[ch].rnn[1]); + FFSWAP(RNNModel *, s->model[0], s->model[1]); + return ret; + } + + free_model(ctx, 1); + return 0; +} + static av_cold void uninit(AVFilterContext *ctx) { AudioRNNContext *s = ctx->priv; av_freep(&s->fdsp); - rnnoise_model_free(s->model); - s->model = NULL; - - if (s->st) { - for (int ch = 0; ch < s->channels; ch++) { - av_freep(&s->st[ch].rnn.vad_gru_state); - av_freep(&s->st[ch].rnn.noise_gru_state); - av_freep(&s->st[ch].rnn.denoise_gru_state); - av_tx_uninit(&s->st[ch].tx); - av_tx_uninit(&s->st[ch].txi); - } + free_model(ctx, 0); + for (int ch = 0; ch < s->channels && s->st; ch++) { + av_tx_uninit(&s->st[ch].tx); + av_tx_uninit(&s->st[ch].txi); } av_freep(&s->st); } @@ -1524,11 +1608,12 @@ static const AVFilterPad outputs[] = { }; #define OFFSET(x) offsetof(AudioRNNContext, x) -#define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption arnndn_options[] = { { "model", "set model name", OFFSET(model_name), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, AF }, { "m", "set model name", OFFSET(model_name), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, AF }, + { "mix", "set output vs input mix", OFFSET(mix), AV_OPT_TYPE_FLOAT, {.dbl=1.0},-1, 1, AF }, { NULL } }; @@ -1545,5 +1630,7 @@ AVFilter ff_af_arnndn = { .uninit = uninit, .inputs = inputs, .outputs = outputs, - .flags = AVFILTER_FLAG_SLICE_THREADS, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | + AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; diff --git a/libavfilter/af_asetrate.c b/libavfilter/af_asetrate.c index 50a5f4374..2bb75e4a2 100644 --- a/libavfilter/af_asetrate.c +++ b/libavfilter/af_asetrate.c @@ -52,7 +52,7 @@ static av_cold int query_formats(AVFilterContext *ctx) int sample_rates[] = { sr->sample_rate, -1 }; return ff_formats_ref(ff_make_format_list(sample_rates), - &ctx->outputs[0]->in_samplerates); + &ctx->outputs[0]->incfg.samplerates); } static av_cold int config_props(AVFilterLink *outlink) diff --git a/libavfilter/af_asoftclip.c b/libavfilter/af_asoftclip.c index e9e3666ef..4900cb6dd 100644 --- a/libavfilter/af_asoftclip.c +++ b/libavfilter/af_asoftclip.c @@ -18,13 +18,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/opt.h" +#include "libswresample/swresample.h" #include "avfilter.h" #include "audio.h" #include "formats.h" enum ASoftClipTypes { + ASC_HARD = -1, ASC_TANH, ASC_ATAN, ASC_CUBIC, @@ -32,6 +35,7 @@ enum ASoftClipTypes { ASC_ALG, ASC_QUINTIC, ASC_SIN, + ASC_ERF, NB_TYPES, }; @@ -39,17 +43,28 @@ typedef struct ASoftClipContext { const AVClass *class; int type; + int oversample; + int64_t delay; + double threshold; + double output; double param; + SwrContext *up_ctx; + SwrContext *down_ctx; + + AVFrame *frame; + void (*filter)(struct ASoftClipContext *s, void **dst, const void **src, int nb_samples, int channels, int start, int end); } ASoftClipContext; #define OFFSET(x) offsetof(ASoftClipContext, x) #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM +#define F AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM static const AVOption asoftclip_options[] = { - { "type", "set softclip type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TYPES-1, A, "types" }, + { "type", "set softclip type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, -1, NB_TYPES-1, A, "types" }, + { "hard", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_HARD}, 0, 0, A, "types" }, { "tanh", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_TANH}, 0, 0, A, "types" }, { "atan", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_ATAN}, 0, 0, A, "types" }, { "cubic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_CUBIC}, 0, 0, A, "types" }, @@ -57,7 +72,11 @@ static const AVOption asoftclip_options[] = { { "alg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_ALG}, 0, 0, A, "types" }, { "quintic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_QUINTIC},0, 0, A, "types" }, { "sin", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_SIN}, 0, 0, A, "types" }, + { "erf", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_ERF}, 0, 0, A, "types" }, + { "threshold", "set softclip threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.000001, 1, A }, + { "output", "set softclip output gain", OFFSET(output), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.000001, 16, A }, { "param", "set softclip parameter", OFFSET(param), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.01, 3, A }, + { "oversample", "set oversample factor", OFFSET(oversample), AV_OPT_TYPE_INT, {.i64=1}, 1, 32, F }, { NULL } }; @@ -93,13 +112,14 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_samplerates(ctx, formats); } -#define SQR(x) ((x) * (x)) - static void filter_flt(ASoftClipContext *s, void **dptr, const void **sptr, int nb_samples, int channels, int start, int end) { + float threshold = s->threshold; + float gain = s->output * threshold; + float factor = 1.f / threshold; float param = s->param; for (int c = start; c < end; c++) { @@ -107,47 +127,79 @@ static void filter_flt(ASoftClipContext *s, float *dst = dptr[c]; switch (s->type) { + case ASC_HARD: + for (int n = 0; n < nb_samples; n++) { + dst[n] = av_clipf(src[n] * factor, -1.f, 1.f); + dst[n] *= gain; + } + break; case ASC_TANH: for (int n = 0; n < nb_samples; n++) { - dst[n] = tanhf(src[n] * param); + dst[n] = tanhf(src[n] * factor * param); + dst[n] *= gain; } break; case ASC_ATAN: - for (int n = 0; n < nb_samples; n++) - dst[n] = 2.f / M_PI * atanf(src[n] * param); + for (int n = 0; n < nb_samples; n++) { + dst[n] = 2.f / M_PI * atanf(src[n] * factor * param); + dst[n] *= gain; + } break; case ASC_CUBIC: for (int n = 0; n < nb_samples; n++) { - if (FFABS(src[n]) >= 1.5f) - dst[n] = FFSIGN(src[n]); + float sample = src[n] * factor; + + if (FFABS(sample) >= 1.5f) + dst[n] = FFSIGN(sample); else - dst[n] = src[n] - 0.1481f * powf(src[n], 3.f); + dst[n] = sample - 0.1481f * powf(sample, 3.f); + dst[n] *= gain; } break; case ASC_EXP: - for (int n = 0; n < nb_samples; n++) - dst[n] = 2.f / (1.f + expf(-2.f * src[n])) - 1.; + for (int n = 0; n < nb_samples; n++) { + dst[n] = 2.f / (1.f + expf(-2.f * src[n] * factor)) - 1.; + dst[n] *= gain; + } break; case ASC_ALG: - for (int n = 0; n < nb_samples; n++) - dst[n] = src[n] / (sqrtf(param + src[n] * src[n])); + for (int n = 0; n < nb_samples; n++) { + float sample = src[n] * factor; + + dst[n] = sample / (sqrtf(param + sample * sample)); + dst[n] *= gain; + } break; case ASC_QUINTIC: for (int n = 0; n < nb_samples; n++) { - if (FFABS(src[n]) >= 1.25) - dst[n] = FFSIGN(src[n]); + float sample = src[n] * factor; + + if (FFABS(sample) >= 1.25) + dst[n] = FFSIGN(sample); else - dst[n] = src[n] - 0.08192f * powf(src[n], 5.f); + dst[n] = sample - 0.08192f * powf(sample, 5.f); + dst[n] *= gain; } break; case ASC_SIN: for (int n = 0; n < nb_samples; n++) { - if (FFABS(src[n]) >= M_PI_2) - dst[n] = FFSIGN(src[n]); + float sample = src[n] * factor; + + if (FFABS(sample) >= M_PI_2) + dst[n] = FFSIGN(sample); else - dst[n] = sinf(src[n]); + dst[n] = sinf(sample); + dst[n] *= gain; } break; + case ASC_ERF: + for (int n = 0; n < nb_samples; n++) { + dst[n] = erff(src[n] * factor); + dst[n] *= gain; + } + break; + default: + av_assert0(0); } } } @@ -157,6 +209,9 @@ static void filter_dbl(ASoftClipContext *s, int nb_samples, int channels, int start, int end) { + double threshold = s->threshold; + double gain = s->output * threshold; + double factor = 1. / threshold; double param = s->param; for (int c = start; c < end; c++) { @@ -164,47 +219,79 @@ static void filter_dbl(ASoftClipContext *s, double *dst = dptr[c]; switch (s->type) { + case ASC_HARD: + for (int n = 0; n < nb_samples; n++) { + dst[n] = av_clipd(src[n] * factor, -1., 1.); + dst[n] *= gain; + } + break; case ASC_TANH: for (int n = 0; n < nb_samples; n++) { - dst[n] = tanh(src[n] * param); + dst[n] = tanh(src[n] * factor * param); + dst[n] *= gain; } break; case ASC_ATAN: - for (int n = 0; n < nb_samples; n++) - dst[n] = 2. / M_PI * atan(src[n] * param); + for (int n = 0; n < nb_samples; n++) { + dst[n] = 2. / M_PI * atan(src[n] * factor * param); + dst[n] *= gain; + } break; case ASC_CUBIC: for (int n = 0; n < nb_samples; n++) { - if (FFABS(src[n]) >= 1.5) - dst[n] = FFSIGN(src[n]); + double sample = src[n] * factor; + + if (FFABS(sample) >= 1.5) + dst[n] = FFSIGN(sample); else - dst[n] = src[n] - 0.1481 * pow(src[n], 3.); + dst[n] = sample - 0.1481 * pow(sample, 3.); + dst[n] *= gain; } break; case ASC_EXP: - for (int n = 0; n < nb_samples; n++) - dst[n] = 2. / (1. + exp(-2. * src[n])) - 1.; + for (int n = 0; n < nb_samples; n++) { + dst[n] = 2. / (1. + exp(-2. * src[n] * factor)) - 1.; + dst[n] *= gain; + } break; case ASC_ALG: - for (int n = 0; n < nb_samples; n++) - dst[n] = src[n] / (sqrt(param + src[n] * src[n])); + for (int n = 0; n < nb_samples; n++) { + double sample = src[n] * factor; + + dst[n] = sample / (sqrt(param + sample * sample)); + dst[n] *= gain; + } break; case ASC_QUINTIC: for (int n = 0; n < nb_samples; n++) { - if (FFABS(src[n]) >= 1.25) - dst[n] = FFSIGN(src[n]); + double sample = src[n] * factor; + + if (FFABS(sample) >= 1.25) + dst[n] = FFSIGN(sample); else - dst[n] = src[n] - 0.08192 * pow(src[n], 5.); + dst[n] = sample - 0.08192 * pow(sample, 5.); + dst[n] *= gain; } break; case ASC_SIN: for (int n = 0; n < nb_samples; n++) { - if (FFABS(src[n]) >= M_PI_2) - dst[n] = FFSIGN(src[n]); + double sample = src[n] * factor; + + if (FFABS(sample) >= M_PI_2) + dst[n] = FFSIGN(sample); else - dst[n] = sin(src[n]); + dst[n] = sin(sample); + dst[n] *= gain; } break; + case ASC_ERF: + for (int n = 0; n < nb_samples; n++) { + dst[n] = erf(src[n] * factor); + dst[n] *= gain; + } + break; + default: + av_assert0(0); } } } @@ -213,14 +300,48 @@ static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; ASoftClipContext *s = ctx->priv; + int ret; switch (inlink->format) { case AV_SAMPLE_FMT_FLT: case AV_SAMPLE_FMT_FLTP: s->filter = filter_flt; break; case AV_SAMPLE_FMT_DBL: case AV_SAMPLE_FMT_DBLP: s->filter = filter_dbl; break; + default: av_assert0(0); } + if (s->oversample <= 1) + return 0; + + s->up_ctx = swr_alloc(); + s->down_ctx = swr_alloc(); + if (!s->up_ctx || !s->down_ctx) + return AVERROR(ENOMEM); + + av_opt_set_int(s->up_ctx, "in_channel_layout", inlink->channel_layout, 0); + av_opt_set_int(s->up_ctx, "in_sample_rate", inlink->sample_rate, 0); + av_opt_set_sample_fmt(s->up_ctx, "in_sample_fmt", inlink->format, 0); + + av_opt_set_int(s->up_ctx, "out_channel_layout", inlink->channel_layout, 0); + av_opt_set_int(s->up_ctx, "out_sample_rate", inlink->sample_rate * s->oversample, 0); + av_opt_set_sample_fmt(s->up_ctx, "out_sample_fmt", inlink->format, 0); + + av_opt_set_int(s->down_ctx, "in_channel_layout", inlink->channel_layout, 0); + av_opt_set_int(s->down_ctx, "in_sample_rate", inlink->sample_rate * s->oversample, 0); + av_opt_set_sample_fmt(s->down_ctx, "in_sample_fmt", inlink->format, 0); + + av_opt_set_int(s->down_ctx, "out_channel_layout", inlink->channel_layout, 0); + av_opt_set_int(s->down_ctx, "out_sample_rate", inlink->sample_rate, 0); + av_opt_set_sample_fmt(s->down_ctx, "out_sample_fmt", inlink->format, 0); + + ret = swr_init(s->up_ctx); + if (ret < 0) + return ret; + + ret = swr_init(s->down_ctx); + if (ret < 0) + return ret; + return 0; } @@ -250,8 +371,9 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; + ASoftClipContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; - int nb_samples, channels; + int ret, nb_samples, channels; ThreadData td; AVFrame *out; @@ -274,17 +396,64 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) channels = 1; } - td.in = in; - td.out = out; - td.nb_samples = nb_samples; - td.channels = channels; - ctx->internal->execute(ctx, filter_channels, &td, NULL, FFMIN(channels, - ff_filter_get_nb_threads(ctx))); + if (s->oversample > 1) { + s->frame = ff_get_audio_buffer(outlink, in->nb_samples * s->oversample); + if (!s->frame) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = swr_convert(s->up_ctx, (uint8_t**)s->frame->extended_data, in->nb_samples * s->oversample, + (const uint8_t **)in->extended_data, in->nb_samples); + if (ret < 0) + goto fail; + + td.in = s->frame; + td.out = s->frame; + td.nb_samples = av_sample_fmt_is_planar(in->format) ? ret : ret * in->channels; + td.channels = channels; + ctx->internal->execute(ctx, filter_channels, &td, NULL, FFMIN(channels, + ff_filter_get_nb_threads(ctx))); + + ret = swr_convert(s->down_ctx, (uint8_t**)out->extended_data, out->nb_samples, + (const uint8_t **)s->frame->extended_data, ret); + if (ret < 0) + goto fail; + + if (out->pts) + out->pts -= s->delay; + s->delay += in->nb_samples - ret; + out->nb_samples = ret; + + av_frame_free(&s->frame); + } else { + td.in = in; + td.out = out; + td.nb_samples = nb_samples; + td.channels = channels; + ctx->internal->execute(ctx, filter_channels, &td, NULL, FFMIN(channels, + ff_filter_get_nb_threads(ctx))); + } if (out != in) av_frame_free(&in); return ff_filter_frame(outlink, out); +fail: + if (out != in) + av_frame_free(&out); + av_frame_free(&in); + av_frame_free(&s->frame); + + return ret; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + ASoftClipContext *s = ctx->priv; + + swr_free(&s->up_ctx); + swr_free(&s->down_ctx); } static const AVFilterPad inputs[] = { @@ -313,6 +482,7 @@ AVFilter ff_af_asoftclip = { .priv_class = &asoftclip_class, .inputs = inputs, .outputs = outputs, + .uninit = uninit, .process_command = ff_filter_process_command, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, diff --git a/libavfilter/af_astats.c b/libavfilter/af_astats.c index 27036385c..f50cbe199 100644 --- a/libavfilter/af_astats.c +++ b/libavfilter/af_astats.c @@ -329,11 +329,11 @@ static inline void update_stat(AudioStatsContext *s, ChannelStats *p, double d, drop = p->win_samples[p->win_pos]; p->win_samples[p->win_pos] = nd; - index = av_clip(FFABS(nd) * HISTOGRAM_MAX, 0, HISTOGRAM_MAX); + index = av_clip(lrint(av_clipd(FFABS(nd), 0.0, 1.0) * HISTOGRAM_MAX), 0, HISTOGRAM_MAX); p->max_index = FFMAX(p->max_index, index); p->histogram[index]++; if (!isnan(p->noise_floor)) - p->histogram[av_clip(FFABS(drop) * HISTOGRAM_MAX, 0, HISTOGRAM_MAX)]--; + p->histogram[av_clip(lrint(av_clipd(FFABS(drop), 0.0, 1.0) * HISTOGRAM_MAX), 0, HISTOGRAM_MAX)]--; p->win_pos++; while (p->histogram[p->max_index] == 0) diff --git a/libavfilter/af_asubboost.c b/libavfilter/af_asubboost.c index f8369fd81..4b30c6746 100644 --- a/libavfilter/af_asubboost.c +++ b/libavfilter/af_asubboost.c @@ -37,10 +37,10 @@ typedef struct ASubBoostContext { double a0, a1, a2; double b0, b1, b2; - int write_pos; + int *write_pos; int buffer_samples; - AVFrame *i, *o; + AVFrame *w; AVFrame *buffer; } ASubBoostContext; @@ -104,21 +104,69 @@ static int config_input(AVFilterLink *inlink) ASubBoostContext *s = ctx->priv; s->buffer = ff_get_audio_buffer(inlink, inlink->sample_rate / 10); - s->i = ff_get_audio_buffer(inlink, 2); - s->o = ff_get_audio_buffer(inlink, 2); - if (!s->buffer || !s->i || !s->o) + s->w = ff_get_audio_buffer(inlink, 2); + s->write_pos = av_calloc(inlink->channels, sizeof(*s->write_pos)); + if (!s->buffer || !s->w || !s->write_pos) return AVERROR(ENOMEM); return get_coeffs(ctx); } +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ASubBoostContext *s = ctx->priv; + ThreadData *td = arg; + AVFrame *out = td->out; + AVFrame *in = td->in; + const double mix = ctx->is_disabled ? 0. : 1.; + const double wet = ctx->is_disabled ? 1. : s->wet_gain; + const double dry = ctx->is_disabled ? 1. : s->dry_gain; + const double feedback = s->feedback, decay = s->decay; + const double b0 = s->b0; + const double b1 = s->b1; + const double b2 = s->b2; + const double a1 = -s->a1; + const double a2 = -s->a2; + const int start = (in->channels * jobnr) / nb_jobs; + const int end = (in->channels * (jobnr+1)) / nb_jobs; + const int buffer_samples = s->buffer_samples; + + for (int ch = start; ch < end; ch++) { + const double *src = (const double *)in->extended_data[ch]; + double *dst = (double *)out->extended_data[ch]; + double *buffer = (double *)s->buffer->extended_data[ch]; + double *w = (double *)s->w->extended_data[ch]; + int write_pos = s->write_pos[ch]; + + for (int n = 0; n < in->nb_samples; n++) { + double out_sample; + + out_sample = src[n] * b0 + w[0]; + w[0] = b1 * src[n] + w[1] + a1 * out_sample; + w[1] = b2 * src[n] + a2 * out_sample; + + buffer[write_pos] = buffer[write_pos] * decay + out_sample * feedback; + dst[n] = (src[n] * dry + buffer[write_pos] * mix) * wet; + + if (++write_pos >= buffer_samples) + write_pos = 0; + } + + s->write_pos[ch] = write_pos; + } + + return 0; +} + static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; - ASubBoostContext *s = ctx->priv; - const float wet = s->wet_gain, dry = s->dry_gain, feedback = s->feedback, decay = s->decay; - int write_pos; + ThreadData td; AVFrame *out; if (av_frame_is_writable(in)) { @@ -132,32 +180,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) av_frame_copy_props(out, in); } - for (int ch = 0; ch < in->channels; ch++) { - const double *src = (const double *)in->extended_data[ch]; - double *dst = (double *)out->extended_data[ch]; - double *buffer = (double *)s->buffer->extended_data[ch]; - double *ix = (double *)s->i->extended_data[ch]; - double *ox = (double *)s->o->extended_data[ch]; - - write_pos = s->write_pos; - for (int n = 0; n < in->nb_samples; n++) { - double out_sample; - - out_sample = src[n] * s->b0 + ix[0] * s->b1 + ix[1] * s->b2 - ox[0] * s->a1 - ox[1] * s->a2; - ix[1] = ix[0]; - ix[0] = src[n]; - ox[1] = ox[0]; - ox[0] = out_sample; - - buffer[write_pos] = buffer[write_pos] * decay + out_sample * feedback; - dst[n] = src[n] * dry + buffer[write_pos] * wet; - - if (++write_pos >= s->buffer_samples) - write_pos = 0; - } - } - - s->write_pos = write_pos; + td.in = in; td.out = out; + ctx->internal->execute(ctx, filter_channels, &td, NULL, FFMIN(inlink->channels, + ff_filter_get_nb_threads(ctx))); if (out != in) av_frame_free(&in); @@ -169,8 +194,8 @@ static av_cold void uninit(AVFilterContext *ctx) ASubBoostContext *s = ctx->priv; av_frame_free(&s->buffer); - av_frame_free(&s->i); - av_frame_free(&s->o); + av_frame_free(&s->w); + av_freep(&s->write_pos); } static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, @@ -189,10 +214,10 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption asubboost_options[] = { - { "dry", "set dry gain", OFFSET(dry_gain), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, FLAGS }, - { "wet", "set wet gain", OFFSET(wet_gain), AV_OPT_TYPE_DOUBLE, {.dbl=0.8}, 0, 1, FLAGS }, + { "dry", "set dry gain", OFFSET(dry_gain), AV_OPT_TYPE_DOUBLE, {.dbl=0.7}, 0, 1, FLAGS }, + { "wet", "set wet gain", OFFSET(wet_gain), AV_OPT_TYPE_DOUBLE, {.dbl=0.7}, 0, 1, FLAGS }, { "decay", "set decay", OFFSET(decay), AV_OPT_TYPE_DOUBLE, {.dbl=0.7}, 0, 1, FLAGS }, - { "feedback", "set feedback", OFFSET(feedback), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, FLAGS }, + { "feedback", "set feedback", OFFSET(feedback), AV_OPT_TYPE_DOUBLE, {.dbl=0.9}, 0, 1, FLAGS }, { "cutoff", "set cutoff", OFFSET(cutoff), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 50, 900, FLAGS }, { "slope", "set slope", OFFSET(slope), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0.0001, 1, FLAGS }, { "delay", "set delay", OFFSET(delay), AV_OPT_TYPE_DOUBLE, {.dbl=20}, 1, 100, FLAGS }, @@ -229,4 +254,6 @@ AVFilter ff_af_asubboost = { .inputs = inputs, .outputs = outputs, .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | + AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/af_asupercut.c b/libavfilter/af_asupercut.c new file mode 100644 index 000000000..d5c9a75d5 --- /dev/null +++ b/libavfilter/af_asupercut.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2005 Boðaç Topaktaþ + * Copyright (c) 2020 Paul B Mahol + * + * 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/channel_layout.h" +#include "libavutil/ffmath.h" +#include "libavutil/opt.h" +#include "avfilter.h" +#include "audio.h" +#include "formats.h" + +typedef struct BiquadCoeffs { + double a1, a2; + double b0, b1, b2; +} BiquadCoeffs; + +typedef struct ASuperCutContext { + const AVClass *class; + + double cutoff; + double level; + double qfactor; + int order; + + int filter_count; + int bypass; + + BiquadCoeffs coeffs[10]; + + AVFrame *w; + + int (*filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); +} ASuperCutContext; + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats = NULL; + AVFilterChannelLayouts *layouts = NULL; + static const enum AVSampleFormat sample_fmts[] = { + AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_NONE + }; + int ret; + + formats = ff_make_format_list(sample_fmts); + if (!formats) + return AVERROR(ENOMEM); + ret = ff_set_common_formats(ctx, formats); + if (ret < 0) + return ret; + + layouts = ff_all_channel_counts(); + if (!layouts) + return AVERROR(ENOMEM); + + ret = ff_set_common_channel_layouts(ctx, layouts); + if (ret < 0) + return ret; + + formats = ff_all_samplerates(); + return ff_set_common_samplerates(ctx, formats); +} + +static void calc_q_factors(int n, double *q) +{ + for (int i = 0; i < n / 2; i++) + q[i] = 1. / (-2. * cos(M_PI * (2. * (i + 1) + n - 1.) / (2. * n))); +} + +static int get_coeffs(AVFilterContext *ctx) +{ + ASuperCutContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + double w0 = s->cutoff / inlink->sample_rate; + double K = tan(M_PI * w0); + double q[10]; + + s->bypass = w0 >= 0.5; + if (s->bypass) + return 0; + + if (!strcmp(ctx->filter->name, "asubcut")) { + s->filter_count = s->order / 2 + (s->order & 1); + + calc_q_factors(s->order, q); + + if (s->order & 1) { + BiquadCoeffs *coeffs = &s->coeffs[0]; + double omega = 2. * tan(M_PI * w0); + + coeffs->b0 = 2. / (2. + omega); + coeffs->b1 = -coeffs->b0; + coeffs->b2 = 0.; + coeffs->a1 = -(omega - 2.) / (2. + omega); + coeffs->a2 = 0.; + } + + for (int b = (s->order & 1); b < s->filter_count; b++) { + BiquadCoeffs *coeffs = &s->coeffs[b]; + const int idx = b - (s->order & 1); + double norm = 1.0 / (1.0 + K / q[idx] + K * K); + + coeffs->b0 = norm; + coeffs->b1 = -2.0 * coeffs->b0; + coeffs->b2 = coeffs->b0; + coeffs->a1 = -2.0 * (K * K - 1.0) * norm; + coeffs->a2 = -(1.0 - K / q[idx] + K * K) * norm; + } + } else if (!strcmp(ctx->filter->name, "asupercut")) { + s->filter_count = s->order / 2 + (s->order & 1); + + calc_q_factors(s->order, q); + + if (s->order & 1) { + BiquadCoeffs *coeffs = &s->coeffs[0]; + double omega = 2. * tan(M_PI * w0); + + coeffs->b0 = omega / (2. + omega); + coeffs->b1 = coeffs->b0; + coeffs->b2 = 0.; + coeffs->a1 = -(omega - 2.) / (2. + omega); + coeffs->a2 = 0.; + } + + for (int b = (s->order & 1); b < s->filter_count; b++) { + BiquadCoeffs *coeffs = &s->coeffs[b]; + const int idx = b - (s->order & 1); + double norm = 1.0 / (1.0 + K / q[idx] + K * K); + + coeffs->b0 = K * K * norm; + coeffs->b1 = 2.0 * coeffs->b0; + coeffs->b2 = coeffs->b0; + coeffs->a1 = -2.0 * (K * K - 1.0) * norm; + coeffs->a2 = -(1.0 - K / q[idx] + K * K) * norm; + } + } else if (!strcmp(ctx->filter->name, "asuperpass")) { + double alpha, beta, gamma, theta; + double theta_0 = 2. * M_PI * (s->cutoff / inlink->sample_rate); + double d_E; + + s->filter_count = s->order / 2; + d_E = (2. * tan(theta_0 / (2. * s->qfactor))) / sin(theta_0); + + for (int b = 0; b < s->filter_count; b += 2) { + double D = 2. * sin(((b + 1) * M_PI) / (2. * s->filter_count)); + double A = (1. + pow((d_E / 2.), 2)) / (D * d_E / 2.); + double d = sqrt((d_E * D) / (A + sqrt(A * A - 1.))); + double B = D * (d_E / 2.) / d; + double W = B + sqrt(B * B - 1.); + + for (int j = 0; j < 2; j++) { + BiquadCoeffs *coeffs = &s->coeffs[b + j]; + + if (j == 1) + theta = 2. * atan(tan(theta_0 / 2.) / W); + else + theta = 2. * atan(W * tan(theta_0 / 2.)); + + beta = 0.5 * ((1. - (d / 2.) * sin(theta)) / (1. + (d / 2.) * sin(theta))); + gamma = (0.5 + beta) * cos(theta); + alpha = 0.5 * (0.5 - beta) * sqrt(1. + pow((W - (1. / W)) / d, 2.)); + + coeffs->a1 = 2. * gamma; + coeffs->a2 = -2. * beta; + coeffs->b0 = 2. * alpha; + coeffs->b1 = 0.; + coeffs->b2 = -2. * alpha; + } + } + } else if (!strcmp(ctx->filter->name, "asuperstop")) { + double alpha, beta, gamma, theta; + double theta_0 = 2. * M_PI * (s->cutoff / inlink->sample_rate); + double d_E; + + s->filter_count = s->order / 2; + d_E = (2. * tan(theta_0 / (2. * s->qfactor))) / sin(theta_0); + + for (int b = 0; b < s->filter_count; b += 2) { + double D = 2. * sin(((b + 1) * M_PI) / (2. * s->filter_count)); + double A = (1. + pow((d_E / 2.), 2)) / (D * d_E / 2.); + double d = sqrt((d_E * D) / (A + sqrt(A * A - 1.))); + double B = D * (d_E / 2.) / d; + double W = B + sqrt(B * B - 1.); + + for (int j = 0; j < 2; j++) { + BiquadCoeffs *coeffs = &s->coeffs[b + j]; + + if (j == 1) + theta = 2. * atan(tan(theta_0 / 2.) / W); + else + theta = 2. * atan(W * tan(theta_0 / 2.)); + + beta = 0.5 * ((1. - (d / 2.) * sin(theta)) / (1. + (d / 2.) * sin(theta))); + gamma = (0.5 + beta) * cos(theta); + alpha = 0.5 * (0.5 + beta) * ((1. - cos(theta)) / (1. - cos(theta_0))); + + coeffs->a1 = 2. * gamma; + coeffs->a2 = -2. * beta; + coeffs->b0 = 2. * alpha; + coeffs->b1 = -4. * alpha * cos(theta_0); + coeffs->b2 = 2. * alpha; + } + } + } + + return 0; +} + +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +#define FILTER(name, type) \ +static int filter_channels_## name(AVFilterContext *ctx, void *arg, \ + int jobnr, int nb_jobs) \ +{ \ + ASuperCutContext *s = ctx->priv; \ + ThreadData *td = arg; \ + AVFrame *out = td->out; \ + AVFrame *in = td->in; \ + const int start = (in->channels * jobnr) / nb_jobs; \ + const int end = (in->channels * (jobnr+1)) / nb_jobs; \ + const double level = s->level; \ + \ + for (int ch = start; ch < end; ch++) { \ + const type *src = (const type *)in->extended_data[ch]; \ + type *dst = (type *)out->extended_data[ch]; \ + \ + for (int b = 0; b < s->filter_count; b++) { \ + BiquadCoeffs *coeffs = &s->coeffs[b]; \ + const type a1 = coeffs->a1; \ + const type a2 = coeffs->a2; \ + const type b0 = coeffs->b0; \ + const type b1 = coeffs->b1; \ + const type b2 = coeffs->b2; \ + type *w = ((type *)s->w->extended_data[ch]) + b * 2; \ + \ + for (int n = 0; n < in->nb_samples; n++) { \ + type sin = b ? dst[n] : src[n] * level; \ + type sout = sin * b0 + w[0]; \ + \ + w[0] = b1 * sin + w[1] + a1 * sout; \ + w[1] = b2 * sin + a2 * sout; \ + \ + dst[n] = sout; \ + } \ + } \ + } \ + \ + return 0; \ +} + +FILTER(fltp, float) +FILTER(dblp, double) + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ASuperCutContext *s = ctx->priv; + + switch (inlink->format) { + case AV_SAMPLE_FMT_FLTP: s->filter_channels = filter_channels_fltp; break; + case AV_SAMPLE_FMT_DBLP: s->filter_channels = filter_channels_dblp; break; + } + + s->w = ff_get_audio_buffer(inlink, 2 * 10); + if (!s->w) + return AVERROR(ENOMEM); + + return get_coeffs(ctx); +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + ASuperCutContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + ThreadData td; + AVFrame *out; + + if (s->bypass) + return ff_filter_frame(outlink, in); + + if (av_frame_is_writable(in)) { + out = in; + } else { + out = ff_get_audio_buffer(outlink, in->nb_samples); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + } + + td.in = in; td.out = out; + ctx->internal->execute(ctx, s->filter_channels, &td, NULL, FFMIN(inlink->channels, + ff_filter_get_nb_threads(ctx))); + + if (out != in) + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return get_coeffs(ctx); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + ASuperCutContext *s = ctx->priv; + + av_frame_free(&s->w); +} + +#define OFFSET(x) offsetof(ASuperCutContext, x) +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption asupercut_options[] = { + { "cutoff", "set cutoff frequency", OFFSET(cutoff), AV_OPT_TYPE_DOUBLE, {.dbl=20000}, 20000, 192000, FLAGS }, + { "order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=10}, 3, 20, FLAGS }, + { "level", "set input level", OFFSET(level), AV_OPT_TYPE_DOUBLE, {.dbl=1.}, 0., 1., FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(asupercut); + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + }, + { NULL } +}; + +AVFilter ff_af_asupercut = { + .name = "asupercut", + .description = NULL_IF_CONFIG_SMALL("Cut super frequencies."), + .query_formats = query_formats, + .priv_size = sizeof(ASuperCutContext), + .priv_class = &asupercut_class, + .uninit = uninit, + .inputs = inputs, + .outputs = outputs, + .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | + AVFILTER_FLAG_SLICE_THREADS, +}; + +static const AVOption asubcut_options[] = { + { "cutoff", "set cutoff frequency", OFFSET(cutoff), AV_OPT_TYPE_DOUBLE, {.dbl=20}, 2, 200, FLAGS }, + { "order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=10}, 3, 20, FLAGS }, + { "level", "set input level", OFFSET(level), AV_OPT_TYPE_DOUBLE, {.dbl=1.}, 0., 1., FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(asubcut); + +AVFilter ff_af_asubcut = { + .name = "asubcut", + .description = NULL_IF_CONFIG_SMALL("Cut subwoofer frequencies."), + .query_formats = query_formats, + .priv_size = sizeof(ASuperCutContext), + .priv_class = &asubcut_class, + .uninit = uninit, + .inputs = inputs, + .outputs = outputs, + .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | + AVFILTER_FLAG_SLICE_THREADS, +}; + +static const AVOption asuperpass_asuperstop_options[] = { + { "centerf","set center frequency", OFFSET(cutoff), AV_OPT_TYPE_DOUBLE, {.dbl=1000}, 2, 999999, FLAGS }, + { "order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=4}, 4, 20, FLAGS }, + { "qfactor","set Q-factor", OFFSET(qfactor),AV_OPT_TYPE_DOUBLE, {.dbl=1.},0.01, 100., FLAGS }, + { "level", "set input level", OFFSET(level), AV_OPT_TYPE_DOUBLE, {.dbl=1.}, 0., 2., FLAGS }, + { NULL } +}; + +#define asuperpass_options asuperpass_asuperstop_options +AVFILTER_DEFINE_CLASS(asuperpass); + +AVFilter ff_af_asuperpass = { + .name = "asuperpass", + .description = NULL_IF_CONFIG_SMALL("Apply high order Butterworth band-pass filter."), + .query_formats = query_formats, + .priv_size = sizeof(ASuperCutContext), + .priv_class = &asuperpass_class, + .uninit = uninit, + .inputs = inputs, + .outputs = outputs, + .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | + AVFILTER_FLAG_SLICE_THREADS, +}; + +#define asuperstop_options asuperpass_asuperstop_options +AVFILTER_DEFINE_CLASS(asuperstop); + +AVFilter ff_af_asuperstop = { + .name = "asuperstop", + .description = NULL_IF_CONFIG_SMALL("Apply high order Butterworth band-stop filter."), + .query_formats = query_formats, + .priv_size = sizeof(ASuperCutContext), + .priv_class = &asuperstop_class, + .uninit = uninit, + .inputs = inputs, + .outputs = outputs, + .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | + AVFILTER_FLAG_SLICE_THREADS, +}; diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c index 81cdb0c10..4a09f8204 100644 --- a/libavfilter/af_biquads.c +++ b/libavfilter/af_biquads.c @@ -93,6 +93,14 @@ enum WidthType { NB_WTYPE, }; +enum TransformType { + DI, + DII, + TDII, + LATT, + NB_TTYPE, +}; + typedef struct ChanCache { double i1, i2; double o1, o2; @@ -106,6 +114,10 @@ typedef struct BiquadsContext { int width_type; int poles; int csg; + int transform_type; + int precision; + + int bypass; double gain; double frequency; @@ -118,6 +130,9 @@ typedef struct BiquadsContext { double a0, a1, a2; double b0, b1, b2; + double oa0, oa1, oa2; + double ob0, ob1, ob2; + ChanCache *cache; int block_align; @@ -127,32 +142,22 @@ typedef struct BiquadsContext { int disabled); } BiquadsContext; -static av_cold int init(AVFilterContext *ctx) -{ - BiquadsContext *s = ctx->priv; - - if (s->filter_type != biquad) { - if (s->frequency <= 0 || s->width <= 0) { - av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n", - s->frequency, s->width); - return AVERROR(EINVAL); - } - } - - return 0; -} - static int query_formats(AVFilterContext *ctx) { + BiquadsContext *s = ctx->priv; AVFilterFormats *formats; AVFilterChannelLayouts *layouts; - static const enum AVSampleFormat sample_fmts[] = { + static const enum AVSampleFormat auto_sample_fmts[] = { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE }; + enum AVSampleFormat sample_fmts[] = { + AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_NONE + }; int ret; layouts = ff_all_channel_counts(); @@ -162,7 +167,27 @@ static int query_formats(AVFilterContext *ctx) if (ret < 0) return ret; - formats = ff_make_format_list(sample_fmts); + switch (s->precision) { + case 0: + sample_fmts[0] = AV_SAMPLE_FMT_S16P; + formats = ff_make_format_list(sample_fmts); + break; + case 1: + sample_fmts[0] = AV_SAMPLE_FMT_S32P; + formats = ff_make_format_list(sample_fmts); + break; + case 2: + sample_fmts[0] = AV_SAMPLE_FMT_FLTP; + formats = ff_make_format_list(sample_fmts); + break; + case 3: + sample_fmts[0] = AV_SAMPLE_FMT_DBLP; + formats = ff_make_format_list(sample_fmts); + break; + default: + formats = ff_make_format_list(auto_sample_fmts); + break; + } if (!formats) return AVERROR(ENOMEM); ret = ff_set_common_formats(ctx, formats); @@ -258,6 +283,173 @@ BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) BIQUAD_FILTER(flt, float, -1., 1., 0) BIQUAD_FILTER(dbl, double, -1., 1., 0) +#define BIQUAD_DII_FILTER(name, type, min, max, need_clipping) \ +static void biquad_dii_## name (BiquadsContext *s, \ + const void *input, void *output, int len, \ + double *z1, double *z2, \ + double *unused1, double *unused2, \ + double b0, double b1, double b2, \ + double a1, double a2, int *clippings, \ + int disabled) \ +{ \ + const type *ibuf = input; \ + type *obuf = output; \ + double w1 = *z1; \ + double w2 = *z2; \ + double wet = s->mix; \ + double dry = 1. - wet; \ + double in, out, w0; \ + \ + a1 = -a1; \ + a2 = -a2; \ + \ + for (int i = 0; i < len; i++) { \ + in = ibuf[i]; \ + w0 = in + a1 * w1 + a2 * w2; \ + out = b0 * w0 + b1 * w1 + b2 * w2; \ + w2 = w1; \ + w1 = w0; \ + out = out * wet + in * dry; \ + if (disabled) { \ + obuf[i] = in; \ + } else if (need_clipping && out < min) { \ + (*clippings)++; \ + obuf[i] = min; \ + } else if (need_clipping && out > max) { \ + (*clippings)++; \ + obuf[i] = max; \ + } else { \ + obuf[i] = out; \ + } \ + } \ + *z1 = w1; \ + *z2 = w2; \ +} + +BIQUAD_DII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1) +BIQUAD_DII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) +BIQUAD_DII_FILTER(flt, float, -1., 1., 0) +BIQUAD_DII_FILTER(dbl, double, -1., 1., 0) + +#define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping) \ +static void biquad_tdii_## name (BiquadsContext *s, \ + const void *input, void *output, int len, \ + double *z1, double *z2, \ + double *unused1, double *unused2, \ + double b0, double b1, double b2, \ + double a1, double a2, int *clippings, \ + int disabled) \ +{ \ + const type *ibuf = input; \ + type *obuf = output; \ + double w1 = *z1; \ + double w2 = *z2; \ + double wet = s->mix; \ + double dry = 1. - wet; \ + double in, out; \ + \ + a1 = -a1; \ + a2 = -a2; \ + \ + for (int i = 0; i < len; i++) { \ + in = ibuf[i]; \ + out = b0 * in + w1; \ + w1 = b1 * in + w2 + a1 * out; \ + w2 = b2 * in + a2 * out; \ + out = out * wet + in * dry; \ + if (disabled) { \ + obuf[i] = in; \ + } else if (need_clipping && out < min) { \ + (*clippings)++; \ + obuf[i] = min; \ + } else if (need_clipping && out > max) { \ + (*clippings)++; \ + obuf[i] = max; \ + } else { \ + obuf[i] = out; \ + } \ + } \ + *z1 = w1; \ + *z2 = w2; \ +} + +BIQUAD_TDII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1) +BIQUAD_TDII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) +BIQUAD_TDII_FILTER(flt, float, -1., 1., 0) +BIQUAD_TDII_FILTER(dbl, double, -1., 1., 0) + +#define BIQUAD_LATT_FILTER(name, type, min, max, need_clipping) \ +static void biquad_latt_## name (BiquadsContext *s, \ + const void *input, void *output, int len, \ + double *z1, double *z2, \ + double *unused1, double *unused2, \ + double v0, double v1, double v2, \ + double k0, double k1, int *clippings, \ + int disabled) \ +{ \ + const type *ibuf = input; \ + type *obuf = output; \ + double s0 = *z1; \ + double s1 = *z2; \ + double wet = s->mix; \ + double dry = 1. - wet; \ + double in, out; \ + double t0, t1; \ + \ + for (int i = 0; i < len; i++) { \ + out = 0.; \ + in = ibuf[i]; \ + t0 = in - k1 * s0; \ + t1 = t0 * k1 + s0; \ + out += t1 * v2; \ + \ + t0 = t0 - k0 * s1; \ + t1 = t0 * k0 + s1; \ + out += t1 * v1; \ + \ + out += t0 * v0; \ + s0 = t1; \ + s1 = t0; \ + \ + out = out * wet + in * dry; \ + if (disabled) { \ + obuf[i] = in; \ + } else if (need_clipping && out < min) { \ + (*clippings)++; \ + obuf[i] = min; \ + } else if (need_clipping && out > max) { \ + (*clippings)++; \ + obuf[i] = max; \ + } else { \ + obuf[i] = out; \ + } \ + } \ + *z1 = s0; \ + *z2 = s1; \ +} + +BIQUAD_LATT_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1) +BIQUAD_LATT_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) +BIQUAD_LATT_FILTER(flt, float, -1., 1., 0) +BIQUAD_LATT_FILTER(dbl, double, -1., 1., 0) + +static void convert_dir2latt(BiquadsContext *s) +{ + double k0, k1, v0, v1, v2; + + k1 = s->a2; + k0 = s->a1 / (1. + k1); + v2 = s->b2; + v1 = s->b1 - v2 * s->a1; + v0 = s->b0 - v1 * k0 - v2 * k1; + + s->a1 = k0; + s->a2 = k1; + s->b0 = v0; + s->b1 = v1; + s->b2 = v2; +} + static int config_filter(AVFilterLink *outlink, int reset) { AVFilterContext *ctx = outlink->src; @@ -268,13 +460,15 @@ static int config_filter(AVFilterLink *outlink, int reset) double K = tan(w0 / 2.); double alpha, beta; - if (w0 > M_PI) { - av_log(ctx, AV_LOG_ERROR, - "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n", - s->frequency, inlink->sample_rate); - return AVERROR(EINVAL); + s->bypass = (((w0 > M_PI || w0 <= 0.) && reset) || (s->width <= 0.)) && (s->filter_type != biquad); + if (s->bypass) { + av_log(ctx, AV_LOG_WARNING, "Invalid frequency and/or width!\n"); + return 0; } + if ((w0 > M_PI || w0 <= 0.) && (s->filter_type != biquad)) + return AVERROR(EINVAL); + switch (s->width_type) { case NONE: alpha = 0.0; @@ -302,6 +496,12 @@ static int config_filter(AVFilterLink *outlink, int reset) switch (s->filter_type) { case biquad: + s->a0 = s->oa0; + s->a1 = s->oa1; + s->a2 = s->oa2; + s->b0 = s->ob0; + s->b1 = s->ob1; + s->b2 = s->ob2; break; case equalizer: s->a0 = 1 + alpha / A; @@ -314,22 +514,54 @@ static int config_filter(AVFilterLink *outlink, int reset) case bass: beta = sqrt((A * A + 1) - (A - 1) * (A - 1)); case lowshelf: - s->a0 = (A + 1) + (A - 1) * cos(w0) + beta * alpha; - s->a1 = -2 * ((A - 1) + (A + 1) * cos(w0)); - s->a2 = (A + 1) + (A - 1) * cos(w0) - beta * alpha; - s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha); - s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0)); - s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha); + if (s->poles == 1) { + double A = ff_exp10(s->gain / 20); + double ro = -sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4); + double n = (A + 1) / (A - 1); + double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1); + double beta0 = ((1 + A) + (1 - A) * alpha1) * 0.5; + double beta1 = ((1 - A) + (1 + A) * alpha1) * 0.5; + + s->a0 = 1 + ro * alpha1; + s->a1 = -ro - alpha1; + s->a2 = 0; + s->b0 = beta0 + ro * beta1; + s->b1 = -beta1 - ro * beta0; + s->b2 = 0; + } else { + s->a0 = (A + 1) + (A - 1) * cos(w0) + beta * alpha; + s->a1 = -2 * ((A - 1) + (A + 1) * cos(w0)); + s->a2 = (A + 1) + (A - 1) * cos(w0) - beta * alpha; + s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha); + s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0)); + s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha); + } break; case treble: beta = sqrt((A * A + 1) - (A - 1) * (A - 1)); case highshelf: - s->a0 = (A + 1) - (A - 1) * cos(w0) + beta * alpha; - s->a1 = 2 * ((A - 1) - (A + 1) * cos(w0)); - s->a2 = (A + 1) - (A - 1) * cos(w0) - beta * alpha; - s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha); - s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0)); - s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha); + if (s->poles == 1) { + double A = ff_exp10(s->gain / 20); + double ro = sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4); + double n = (A + 1) / (A - 1); + double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1); + double beta0 = ((1 + A) + (1 - A) * alpha1) * 0.5; + double beta1 = ((1 - A) + (1 + A) * alpha1) * 0.5; + + s->a0 = 1 + ro * alpha1; + s->a1 = ro + alpha1; + s->a2 = 0; + s->b0 = beta0 + ro * beta1; + s->b1 = beta1 + ro * beta0; + s->b2 = 0; + } else { + s->a0 = (A + 1) - (A - 1) * cos(w0) + beta * alpha; + s->a1 = 2 * ((A - 1) - (A + 1) * cos(w0)); + s->a2 = (A + 1) - (A - 1) * cos(w0) - beta * alpha; + s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha); + s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0)); + s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha); + } break; case bandpass: if (s->csg) { @@ -437,15 +669,83 @@ static int config_filter(AVFilterLink *outlink, int reset) if (reset) memset(s->cache, 0, sizeof(ChanCache) * inlink->channels); - switch (inlink->format) { - case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break; - case AV_SAMPLE_FMT_S32P: s->filter = biquad_s32; break; - case AV_SAMPLE_FMT_FLTP: s->filter = biquad_flt; break; - case AV_SAMPLE_FMT_DBLP: s->filter = biquad_dbl; break; - default: av_assert0(0); - } + switch (s->transform_type) { + case DI: + switch (inlink->format) { + case AV_SAMPLE_FMT_S16P: + s->filter = biquad_s16; + break; + case AV_SAMPLE_FMT_S32P: + s->filter = biquad_s32; + break; + case AV_SAMPLE_FMT_FLTP: + s->filter = biquad_flt; + break; + case AV_SAMPLE_FMT_DBLP: + s->filter = biquad_dbl; + break; + default: av_assert0(0); + } + break; + case DII: + switch (inlink->format) { + case AV_SAMPLE_FMT_S16P: + s->filter = biquad_dii_s16; + break; + case AV_SAMPLE_FMT_S32P: + s->filter = biquad_dii_s32; + break; + case AV_SAMPLE_FMT_FLTP: + s->filter = biquad_dii_flt; + break; + case AV_SAMPLE_FMT_DBLP: + s->filter = biquad_dii_dbl; + break; + default: av_assert0(0); + } + break; + case TDII: + switch (inlink->format) { + case AV_SAMPLE_FMT_S16P: + s->filter = biquad_tdii_s16; + break; + case AV_SAMPLE_FMT_S32P: + s->filter = biquad_tdii_s32; + break; + case AV_SAMPLE_FMT_FLTP: + s->filter = biquad_tdii_flt; + break; + case AV_SAMPLE_FMT_DBLP: + s->filter = biquad_tdii_dbl; + break; + default: av_assert0(0); + } + break; + case LATT: + switch (inlink->format) { + case AV_SAMPLE_FMT_S16P: + s->filter = biquad_latt_s16; + break; + case AV_SAMPLE_FMT_S32P: + s->filter = biquad_latt_s32; + break; + case AV_SAMPLE_FMT_FLTP: + s->filter = biquad_latt_flt; + break; + case AV_SAMPLE_FMT_DBLP: + s->filter = biquad_latt_dbl; + break; + default: av_assert0(0); + } + break; + default: + av_assert0(0); + } - s->block_align = av_get_bytes_per_sample(inlink->format); + s->block_align = av_get_bytes_per_sample(inlink->format); + + if (s->transform_type == LATT) + convert_dir2latt(s); return 0; } @@ -495,6 +795,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) ThreadData td; int ch; + if (s->bypass) + return ff_filter_frame(outlink, buf); + if (av_frame_is_writable(buf)) { out_buf = buf; } else { @@ -567,15 +870,14 @@ static const AVFilterPad outputs[] = { #define DEFINE_BIQUAD_FILTER(name_, description_) \ AVFILTER_DEFINE_CLASS(name_); \ -static av_cold int name_##_init(AVFilterContext *ctx) \ +static av_cold int name_##_init(AVFilterContext *ctx) \ { \ BiquadsContext *s = ctx->priv; \ - s->class = &name_##_class; \ s->filter_type = name_; \ - return init(ctx); \ + return 0; \ } \ \ -AVFilter ff_af_##name_ = { \ +AVFilter ff_af_##name_ = { \ .name = #name_, \ .description = NULL_IF_CONFIG_SMALL(description_), \ .priv_size = sizeof(BiquadsContext), \ @@ -610,13 +912,26 @@ static const AVOption equalizer_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, + {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, + {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, + {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, + {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, + {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, + {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, + {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}, {NULL} }; DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter."); #endif /* CONFIG_EQUALIZER_FILTER */ -#if CONFIG_BASS_FILTER -static const AVOption bass_options[] = { +#if CONFIG_BASS_FILTER || CONFIG_LOWSHELF_FILTER +static const AVOption bass_lowshelf_options[] = { {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS}, {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS}, {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, @@ -630,19 +945,42 @@ static const AVOption bass_options[] = { {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, + {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF}, + {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF}, {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, + {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, + {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, + {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, + {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, + {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, + {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, + {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}, {NULL} }; +#if CONFIG_BASS_FILTER +#define bass_options bass_lowshelf_options DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies."); #endif /* CONFIG_BASS_FILTER */ -#if CONFIG_TREBLE_FILTER -static const AVOption treble_options[] = { + +#if CONFIG_LOWSHELF_FILTER +#define lowshelf_options bass_lowshelf_options +DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter."); +#endif /* CONFIG_LOWSHELF_FILTER */ +#endif /* CONFIG_BASS_FILTER || CONFIG LOWSHELF_FILTER */ +#if CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER +static const AVOption treble_highshelf_options[] = { {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, @@ -656,17 +994,40 @@ static const AVOption treble_options[] = { {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, + {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF}, + {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF}, {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, + {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, + {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, + {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, + {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, + {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, + {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, + {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}, {NULL} }; +#if CONFIG_TREBLE_FILTER +#define treble_options treble_highshelf_options DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies."); #endif /* CONFIG_TREBLE_FILTER */ + +#if CONFIG_HIGHSHELF_FILTER +#define highshelf_options treble_highshelf_options +DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter."); +#endif /* CONFIG_HIGHSHELF_FILTER */ +#endif /* CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER */ #if CONFIG_BANDPASS_FILTER static const AVOption bandpass_options[] = { {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, @@ -687,6 +1048,19 @@ static const AVOption bandpass_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, + {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, + {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, + {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, + {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, + {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, + {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, + {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}, {NULL} }; @@ -711,6 +1085,19 @@ static const AVOption bandreject_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, + {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, + {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, + {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, + {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, + {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, + {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, + {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}, {NULL} }; @@ -737,6 +1124,19 @@ static const AVOption lowpass_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, + {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, + {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, + {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, + {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, + {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, + {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, + {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}, {NULL} }; @@ -763,6 +1163,19 @@ static const AVOption highpass_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, + {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, + {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, + {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, + {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, + {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, + {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, + {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}, {NULL} }; @@ -789,77 +1202,51 @@ static const AVOption allpass_options[] = { {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS}, {"o", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS}, + {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, + {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, + {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, + {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, + {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, + {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, + {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, + {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}, {NULL} }; DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter."); #endif /* CONFIG_ALLPASS_FILTER */ -#if CONFIG_LOWSHELF_FILTER -static const AVOption lowshelf_options[] = { - {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS}, - {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, - {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"}, - {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, - {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, - {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, - {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, - {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, - {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, - {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, - {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter."); -#endif /* CONFIG_LOWSHELF_FILTER */ -#if CONFIG_HIGHSHELF_FILTER -static const AVOption highshelf_options[] = { - {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, - {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"}, - {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, - {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, - {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, - {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, - {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, - {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, - {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, - {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter."); -#endif /* CONFIG_HIGHSHELF_FILTER */ #if CONFIG_BIQUAD_FILTER static const AVOption biquad_options[] = { - {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS}, - {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, - {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, - {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, - {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, - {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, + {"a0", NULL, OFFSET(oa0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS}, + {"a1", NULL, OFFSET(oa1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, + {"a2", NULL, OFFSET(oa2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, + {"b0", NULL, OFFSET(ob0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, + {"b1", NULL, OFFSET(ob1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, + {"b2", NULL, OFFSET(ob2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, + {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, + {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, + {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, + {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"}, + {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, + {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, + {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, + {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, + {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}, {NULL} }; diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c index 285d76a3e..c4b8dd547 100644 --- a/libavfilter/af_channelmap.c +++ b/libavfilter/af_channelmap.c @@ -280,28 +280,18 @@ static av_cold int channelmap_init(AVFilterContext *ctx) static int channelmap_query_formats(AVFilterContext *ctx) { ChannelMapContext *s = ctx->priv; - AVFilterChannelLayouts *layouts; AVFilterChannelLayouts *channel_layouts = NULL; int ret; - layouts = ff_all_channel_counts(); - if (!layouts) { - ret = AVERROR(ENOMEM); - goto fail; - } - if ((ret = ff_add_channel_layout (&channel_layouts, s->output_layout )) < 0 || - (ret = ff_set_common_formats (ctx , ff_planar_sample_fmts() )) < 0 || + if ((ret = ff_set_common_formats (ctx, ff_planar_sample_fmts())) < 0 || (ret = ff_set_common_samplerates (ctx , ff_all_samplerates() )) < 0 || - (ret = ff_channel_layouts_ref (layouts , &ctx->inputs[0]->out_channel_layouts)) < 0 || - (ret = ff_channel_layouts_ref (channel_layouts , &ctx->outputs[0]->in_channel_layouts)) < 0) - goto fail; + (ret = ff_add_channel_layout(&channel_layouts, s->output_layout)) < 0 || + (ret = ff_channel_layouts_ref(channel_layouts, + &ctx->outputs[0]->incfg.channel_layouts)) < 0) + return ret; - return 0; -fail: - if (layouts) - av_freep(&layouts->channel_layouts); - av_freep(&layouts); - return ret; + return ff_channel_layouts_ref(ff_all_channel_counts(), + &ctx->inputs[0]->outcfg.channel_layouts); } static int channelmap_filter_frame(AVFilterLink *inlink, AVFrame *buf) diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c index 821bb7380..ad00fe1ba 100644 --- a/libavfilter/af_channelsplit.c +++ b/libavfilter/af_channelsplit.c @@ -117,7 +117,7 @@ static int query_formats(AVFilterContext *ctx) return ret; if ((ret = ff_add_channel_layout(&in_layouts, s->channel_layout)) < 0 || - (ret = ff_channel_layouts_ref(in_layouts, &ctx->inputs[0]->out_channel_layouts)) < 0) + (ret = ff_channel_layouts_ref(in_layouts, &ctx->inputs[0]->outcfg.channel_layouts)) < 0) return ret; for (i = 0; i < ctx->nb_outputs; i++) { @@ -125,7 +125,7 @@ static int query_formats(AVFilterContext *ctx) uint64_t channel = av_channel_layout_extract_channel(s->channel_layout, s->map[i]); if ((ret = ff_add_channel_layout(&out_layouts, channel)) < 0 || - (ret = ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->in_channel_layouts)) < 0) + (ret = ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->incfg.channel_layouts)) < 0) return ret; } diff --git a/libavfilter/af_compensationdelay.c b/libavfilter/af_compensationdelay.c index 793332584..525b3d6f3 100644 --- a/libavfilter/af_compensationdelay.c +++ b/libavfilter/af_compensationdelay.c @@ -127,7 +127,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) const unsigned delay = s->delay; const double dry = s->dry; const double wet = s->wet; - unsigned r_ptr, w_ptr; + unsigned r_ptr, w_ptr = 0; AVFrame *out; int n, ch; diff --git a/libavfilter/af_crossfeed.c b/libavfilter/af_crossfeed.c index 70dd26eb2..fb0a49ec8 100644 --- a/libavfilter/af_crossfeed.c +++ b/libavfilter/af_crossfeed.c @@ -35,8 +35,7 @@ typedef struct CrossfeedContext { double a0, a1, a2; double b0, b1, b2; - double i1, i2; - double o1, o2; + double w1, w2; } CrossfeedContext; static int query_formats(AVFilterContext *ctx) @@ -92,8 +91,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) const double b0 = s->b0; const double b1 = s->b1; const double b2 = s->b2; - const double a1 = s->a1; - const double a2 = s->a2; + const double a1 = -s->a1; + const double a2 = -s->a2; AVFrame *out; double *dst; int n; @@ -113,12 +112,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) for (n = 0; n < out->nb_samples; n++, src += 2, dst += 2) { double mid = (src[0] + src[1]) * level_in * .5; double side = (src[0] - src[1]) * level_in * .5; - double oside = side * b0 + s->i1 * b1 + s->i2 * b2 - s->o1 * a1 - s->o2 * a2; + double oside = side * b0 + s->w1; - s->i2 = s->i1; - s->i1 = side; - s->o2 = s->o1; - s->o1 = oside; + s->w1 = b1 * side + s->w2 + a1 * oside; + s->w2 = b2 * side + a2 * oside; if (ctx->is_disabled) { dst[0] = src[0]; diff --git a/libavfilter/af_crystalizer.c b/libavfilter/af_crystalizer.c index f3d8ae699..d1f44984a 100644 --- a/libavfilter/af_crystalizer.c +++ b/libavfilter/af_crystalizer.c @@ -36,7 +36,7 @@ typedef struct CrystalizerContext { #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption crystalizer_options[] = { - { "i", "set intensity", OFFSET(mult), AV_OPT_TYPE_FLOAT, {.dbl=2.0}, 0, 10, A }, + { "i", "set intensity", OFFSET(mult), AV_OPT_TYPE_FLOAT, {.dbl=2.0},-10, 10, A }, { "c", "enable clipping", OFFSET(clip), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, A }, { NULL } }; @@ -91,7 +91,7 @@ static int filter_flt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const void **s = td->s; const int nb_samples = td->nb_samples; const int channels = td->channels; - float mult = td->mult; + const float mult = td->mult; const int clip = td->clip; const int start = (channels * jobnr) / nb_jobs; const int end = (channels * (jobnr+1)) / nb_jobs; @@ -126,7 +126,7 @@ static int filter_dbl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const void **s = td->s; const int nb_samples = td->nb_samples; const int channels = td->channels; - float mult = td->mult; + double mult = td->mult; const int clip = td->clip; const int start = (channels * jobnr) / nb_jobs; const int end = (channels * (jobnr+1)) / nb_jobs; @@ -195,7 +195,7 @@ static int filter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const void **s = td->s; const int nb_samples = td->nb_samples; const int channels = td->channels; - float mult = td->mult; + const double mult = td->mult; const int clip = td->clip; const int start = (channels * jobnr) / nb_jobs; const int end = (channels * (jobnr+1)) / nb_jobs; @@ -220,16 +220,157 @@ static int filter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) return 0; } +static int ifilter_flt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ThreadData *td = arg; + void **d = td->d; + void **p = td->p; + const void **s = td->s; + const int nb_samples = td->nb_samples; + const int channels = td->channels; + const float mult = -td->mult; + const float div = -td->mult + 1.f; + const int clip = td->clip; + const int start = (channels * jobnr) / nb_jobs; + const int end = (channels * (jobnr+1)) / nb_jobs; + float *prv = p[0]; + int n, c; + + for (c = start; c < end; c++) { + const float *src = s[0]; + float *dst = d[0]; + + for (n = 0; n < nb_samples; n++) { + float current = src[c]; + dst[c] = (current + prv[c] * mult) / div; + prv[c] = dst[c]; + if (clip) { + dst[c] = av_clipf(dst[c], -1, 1); + } + + dst += channels; + src += channels; + } + } + + return 0; +} + +static int ifilter_dbl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ThreadData *td = arg; + void **d = td->d; + void **p = td->p; + const void **s = td->s; + const int nb_samples = td->nb_samples; + const int channels = td->channels; + const double mult = -td->mult; + const double div = -td->mult + 1.f; + const int clip = td->clip; + const int start = (channels * jobnr) / nb_jobs; + const int end = (channels * (jobnr+1)) / nb_jobs; + double *prv = p[0]; + int n, c; + + for (c = start; c < end; c++) { + const double *src = s[0]; + double *dst = d[0]; + + for (n = 0; n < nb_samples; n++) { + double current = src[c]; + + dst[c] = (current + prv[c] * mult) / div; + prv[c] = dst[c]; + if (clip) { + dst[c] = av_clipd(dst[c], -1, 1); + } + + dst += channels; + src += channels; + } + } + + return 0; +} + +static int ifilter_fltp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ThreadData *td = arg; + void **d = td->d; + void **p = td->p; + const void **s = td->s; + const int nb_samples = td->nb_samples; + const int channels = td->channels; + const float mult = -td->mult; + const float div = -td->mult + 1.f; + const int clip = td->clip; + const int start = (channels * jobnr) / nb_jobs; + const int end = (channels * (jobnr+1)) / nb_jobs; + int n, c; + + for (c = start; c < end; c++) { + const float *src = s[c]; + float *dst = d[c]; + float *prv = p[c]; + + for (n = 0; n < nb_samples; n++) { + float current = src[n]; + + dst[n] = (current + prv[0] * mult) / div; + prv[0] = dst[n]; + if (clip) { + dst[n] = av_clipf(dst[n], -1, 1); + } + } + } + + return 0; +} + +static int ifilter_dblp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ThreadData *td = arg; + void **d = td->d; + void **p = td->p; + const void **s = td->s; + const int nb_samples = td->nb_samples; + const int channels = td->channels; + const double mult = -td->mult; + const double div = -td->mult + 1.f; + const int clip = td->clip; + const int start = (channels * jobnr) / nb_jobs; + const int end = (channels * (jobnr+1)) / nb_jobs; + int n, c; + + for (c = start; c < end; c++) { + const double *src = s[c]; + double *dst = d[c]; + double *prv = p[c]; + + for (n = 0; n < nb_samples; n++) { + double current = src[n]; + + dst[n] = (current + prv[0] * mult) / div; + prv[0] = dst[n]; + if (clip) { + dst[n] = av_clipd(dst[n], -1, 1); + } + } + } + + return 0; +} + static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; CrystalizerContext *s = ctx->priv; switch (inlink->format) { - case AV_SAMPLE_FMT_FLT: s->filter = filter_flt; break; - case AV_SAMPLE_FMT_DBL: s->filter = filter_dbl; break; - case AV_SAMPLE_FMT_FLTP: s->filter = filter_fltp; break; - case AV_SAMPLE_FMT_DBLP: s->filter = filter_dblp; break; + case AV_SAMPLE_FMT_FLT: s->filter = s->mult >= 0.f ? filter_flt : ifilter_flt; break; + case AV_SAMPLE_FMT_DBL: s->filter = s->mult >= 0.f ? filter_dbl : ifilter_dbl; break; + case AV_SAMPLE_FMT_FLTP: s->filter = s->mult >= 0.f ? filter_fltp : ifilter_fltp; break; + case AV_SAMPLE_FMT_DBLP: s->filter = s->mult >= 0.f ? filter_dblp : ifilter_dblp; break; } return 0; @@ -285,6 +426,18 @@ static av_cold void uninit(AVFilterContext *ctx) av_frame_free(&s->prev); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_input(ctx->inputs[0]); +} + static const AVFilterPad inputs[] = { { .name = "default", @@ -305,14 +458,14 @@ static const AVFilterPad outputs[] = { AVFilter ff_af_crystalizer = { .name = "crystalizer", - .description = NULL_IF_CONFIG_SMALL("Simple expand audio dynamic range filter."), + .description = NULL_IF_CONFIG_SMALL("Simple audio noise sharpening filter."), .query_formats = query_formats, .priv_size = sizeof(CrystalizerContext), .priv_class = &crystalizer_class, .uninit = uninit, .inputs = inputs, .outputs = outputs, - .process_command = ff_filter_process_command, + .process_command = process_command, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/af_dynaudnorm.c b/libavfilter/af_dynaudnorm.c index 365453d60..81fa62b69 100644 --- a/libavfilter/af_dynaudnorm.c +++ b/libavfilter/af_dynaudnorm.c @@ -719,6 +719,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) cqueue_dequeue(s->is_enabled, &is_enabled); amplify_frame(s, out, is_enabled > 0.); + s->pts = out->pts + out->nb_samples; ret = ff_filter_frame(outlink, out); } @@ -769,7 +770,7 @@ static int flush(AVFilterLink *outlink) } else if (s->queue.available) { AVFrame *out = ff_bufqueue_get(&s->queue); - s->pts = out->pts; + s->pts = out->pts + out->nb_samples; ret = ff_filter_frame(outlink, out); } @@ -797,7 +798,7 @@ static int activate(AVFilterContext *ctx) return ret; } - if (ff_inlink_queued_samples(inlink) >= s->frame_len) { + if (ff_inlink_check_available_samples(inlink, s->frame_len) > 0) { ff_filter_set_ready(ctx, 10); return 0; } diff --git a/libavfilter/af_earwax.c b/libavfilter/af_earwax.c index cdd2b4fc4..a4434290a 100644 --- a/libavfilter/af_earwax.c +++ b/libavfilter/af_earwax.c @@ -34,9 +34,9 @@ #include "audio.h" #include "formats.h" -#define NUMTAPS 64 +#define NUMTAPS 32 -static const int8_t filt[NUMTAPS] = { +static const int8_t filt[NUMTAPS * 2] = { /* 30° 330° */ 4, -6, /* 32 tap stereo FIR filter. */ 4, -11, /* One side filters as if the */ @@ -72,7 +72,10 @@ static const int8_t filt[NUMTAPS] = { 4, 0}; typedef struct EarwaxContext { - int16_t taps[NUMTAPS * 2]; + int16_t filter[2][NUMTAPS]; + int16_t taps[4][NUMTAPS * 2]; + + AVFrame *frame[2]; } EarwaxContext; static int query_formats(AVFilterContext *ctx) @@ -83,7 +86,7 @@ static int query_formats(AVFilterContext *ctx) AVFilterFormats *formats = NULL; AVFilterChannelLayouts *layout = NULL; - if ((ret = ff_add_format (&formats, AV_SAMPLE_FMT_S16 )) < 0 || + if ((ret = ff_add_format (&formats, AV_SAMPLE_FMT_S16P )) < 0 || (ret = ff_set_common_formats (ctx , formats )) < 0 || (ret = ff_add_channel_layout (&layout , AV_CH_LAYOUT_STEREO )) < 0 || (ret = ff_set_common_channel_layouts (ctx , layout )) < 0 || @@ -94,7 +97,8 @@ static int query_formats(AVFilterContext *ctx) } //FIXME: replace with DSPContext.scalarproduct_int16 -static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, int16_t *out) +static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, + const int16_t *filt, int16_t *out) { int32_t sample; int16_t j; @@ -103,7 +107,7 @@ static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, in sample = 0; for (j = 0; j < NUMTAPS; j++) sample += in[j] * filt[j]; - *out = av_clip_int16(sample >> 6); + *out = av_clip_int16(sample >> 7); out++; in++; } @@ -111,40 +115,102 @@ static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, in return out; } -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) +static int config_input(AVFilterLink *inlink) { - AVFilterLink *outlink = inlink->dst->outputs[0]; - int16_t *taps, *endin, *in, *out; - AVFrame *outsamples = ff_get_audio_buffer(outlink, insamples->nb_samples); + EarwaxContext *s = inlink->dst->priv; + + for (int i = 0; i < NUMTAPS; i++) { + s->filter[0][i] = filt[i * 2]; + s->filter[1][i] = filt[i * 2 + 1]; + } + + return 0; +} + +static void convolve(AVFilterContext *ctx, AVFrame *in, + int input_ch, int output_ch, + int filter_ch, int tap_ch) +{ + EarwaxContext *s = ctx->priv; + int16_t *taps, *endin, *dst, *src; int len; - if (!outsamples) { - av_frame_free(&insamples); - return AVERROR(ENOMEM); - } - av_frame_copy_props(outsamples, insamples); + taps = s->taps[tap_ch]; + dst = (int16_t *)s->frame[input_ch]->data[output_ch]; + src = (int16_t *)in->data[input_ch]; - taps = ((EarwaxContext *)inlink->dst->priv)->taps; - out = (int16_t *)outsamples->data[0]; - in = (int16_t *)insamples ->data[0]; - - len = FFMIN(NUMTAPS, 2*insamples->nb_samples); + len = FFMIN(NUMTAPS, in->nb_samples); // copy part of new input and process with saved input - memcpy(taps+NUMTAPS, in, len * sizeof(*taps)); - out = scalarproduct(taps, taps + len, out); + memcpy(taps+NUMTAPS, src, len * sizeof(*taps)); + dst = scalarproduct(taps, taps + len, s->filter[filter_ch], dst); // process current input - if (2*insamples->nb_samples >= NUMTAPS ){ - endin = in + insamples->nb_samples * 2 - NUMTAPS; - scalarproduct(in, endin, out); + if (in->nb_samples >= NUMTAPS) { + endin = src + in->nb_samples - NUMTAPS; + scalarproduct(src, endin, s->filter[filter_ch], dst); // save part of input for next round memcpy(taps, endin, NUMTAPS * sizeof(*taps)); - } else - memmove(taps, taps + 2*insamples->nb_samples, NUMTAPS * sizeof(*taps)); + } else { + memmove(taps, taps + in->nb_samples, NUMTAPS * sizeof(*taps)); + } +} - av_frame_free(&insamples); - return ff_filter_frame(outlink, outsamples); +static void mix(AVFilterContext *ctx, AVFrame *out, + int output_ch, int f0, int f1, int i0, int i1) +{ + EarwaxContext *s = ctx->priv; + const int16_t *srcl = (const int16_t *)s->frame[f0]->data[i0]; + const int16_t *srcr = (const int16_t *)s->frame[f1]->data[i1]; + int16_t *dst = (int16_t *)out->data[output_ch]; + + for (int n = 0; n < out->nb_samples; n++) + dst[n] = av_clip_int16(srcl[n] + srcr[n]); +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + EarwaxContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out = ff_get_audio_buffer(outlink, in->nb_samples); + + for (int ch = 0; ch < 2; ch++) { + if (!s->frame[ch] || s->frame[ch]->nb_samples < in->nb_samples) { + av_frame_free(&s->frame[ch]); + s->frame[ch] = ff_get_audio_buffer(outlink, in->nb_samples); + if (!s->frame[ch]) { + av_frame_free(&in); + av_frame_free(&out); + return AVERROR(ENOMEM); + } + } + } + + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + + convolve(ctx, in, 0, 0, 0, 0); + convolve(ctx, in, 0, 1, 1, 1); + convolve(ctx, in, 1, 0, 0, 2); + convolve(ctx, in, 1, 1, 1, 3); + + mix(ctx, out, 0, 0, 1, 1, 0); + mix(ctx, out, 1, 0, 1, 0, 1); + + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + EarwaxContext *s = ctx->priv; + + av_frame_free(&s->frame[0]); + av_frame_free(&s->frame[1]); } static const AVFilterPad earwax_inputs[] = { @@ -152,6 +218,7 @@ static const AVFilterPad earwax_inputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .filter_frame = filter_frame, + .config_props = config_input, }, { NULL } }; @@ -169,6 +236,7 @@ AVFilter ff_af_earwax = { .description = NULL_IF_CONFIG_SMALL("Widen the stereo image."), .query_formats = query_formats, .priv_size = sizeof(EarwaxContext), + .uninit = uninit, .inputs = earwax_inputs, .outputs = earwax_outputs, }; diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index fd17646f0..978f63599 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -1053,7 +1053,7 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state *states, int channels, in for (j = result - 1; j >= 0; j--) { for (i = 0; i < channels; i++) - bits[i] |= (*(samples++) & 1) << j; + bits[i] |= (*(samples++) & 1U) << j; samples += stride - channels; } @@ -1210,7 +1210,7 @@ static int hdcd_analyze(int32_t *samples, int count, int stride, int gain, int t int32_t *samples_end = samples + stride * count; for (i = 0; i < count; i++) { - samples[i * stride] <<= 15; + samples[i * stride] *= 1 << 15; if (mode == HDCD_ANA_PE) { int pel = (samples[i * stride] >> 16) & 1; int32_t sample = samples[i * stride]; @@ -1284,13 +1284,13 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int vbits, int av_assert0(asample <= max_asample); sample = sample >= 0 ? peaktab[asample] : -peaktab[asample]; } else - sample <<= shft; + sample *= (1 << shft); samples[i * stride] = sample; } } else { for (i = 0; i < count; i++) - samples[i * stride] <<= shft; + samples[i * stride] *= (1 << shft); } if (gain <= target_gain) { @@ -1638,12 +1638,12 @@ static int query_formats(AVFilterContext *ctx) return ret; in_formats = ff_make_format_list(sample_fmts_in); - ret = ff_formats_ref(in_formats, &inlink->out_formats); + ret = ff_formats_ref(in_formats, &inlink->outcfg.formats); if (ret < 0) return ret; out_formats = ff_make_format_list(sample_fmts_out); - ret = ff_formats_ref(out_formats, &outlink->in_formats); + ret = ff_formats_ref(out_formats, &outlink->incfg.formats); if (ret < 0) return ret; diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c index 552ad8483..edf8e773d 100644 --- a/libavfilter/af_headphone.c +++ b/libavfilter/af_headphone.c @@ -52,9 +52,7 @@ typedef struct HeadphoneContext { int ir_len; int air_len; - int mapping[64]; - - int nb_inputs; + int nb_hrir_inputs; int nb_irs; @@ -69,7 +67,6 @@ typedef struct HeadphoneContext { int size; int hrir_fmt; - int *delay[2]; float *data_ir[2]; float *temp_src[2]; FFTComplex *temp_fft[2]; @@ -78,82 +75,57 @@ typedef struct HeadphoneContext { FFTContext *fft[2], *ifft[2]; FFTComplex *data_hrtf[2]; - AVFloatDSPContext *fdsp; - struct headphone_inputs { - AVFrame *frame; + float (*scalarproduct_float)(const float *v1, const float *v2, int len); + struct hrir_inputs { int ir_len; - int delay_l; - int delay_r; int eof; - } *in; + } hrir_in[64]; + uint64_t mapping[64]; } HeadphoneContext; -static int parse_channel_name(HeadphoneContext *s, int x, char **arg, int *rchannel, char *buf) +static int parse_channel_name(const char *arg, uint64_t *rchannel) { - int len, i, channel_id = 0; - int64_t layout, layout0; + uint64_t layout = av_get_channel_layout(arg); - if (sscanf(*arg, "%7[A-Z]%n", buf, &len)) { - layout0 = layout = av_get_channel_layout(buf); - if (layout == AV_CH_LOW_FREQUENCY) - s->lfe_channel = x; - for (i = 32; i > 0; i >>= 1) { - if (layout >= 1LL << i) { - channel_id += i; - layout >>= i; - } - } - if (channel_id >= 64 || layout0 != 1LL << channel_id) - return AVERROR(EINVAL); - *rchannel = channel_id; - *arg += len; - return 0; - } - return AVERROR(EINVAL); + if (av_get_channel_layout_nb_channels(layout) != 1) + return AVERROR(EINVAL); + *rchannel = layout; + return 0; } static void parse_map(AVFilterContext *ctx) { HeadphoneContext *s = ctx->priv; - char *arg, *tokenizer, *p, *args = av_strdup(s->map); - int i; - - if (!args) - return; - p = args; - - s->lfe_channel = -1; - s->nb_inputs = 1; - - for (i = 0; i < 64; i++) { - s->mapping[i] = -1; - } + char *arg, *tokenizer, *p; + uint64_t used_channels = 0; + p = s->map; while ((arg = av_strtok(p, "|", &tokenizer))) { - int out_ch_id; - char buf[8]; + uint64_t out_channel; p = NULL; - if (parse_channel_name(s, s->nb_irs, &arg, &out_ch_id, buf)) { - av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", buf); + if (parse_channel_name(arg, &out_channel)) { + av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", arg); continue; } - s->mapping[s->nb_irs] = out_ch_id; + if (used_channels & out_channel) { + av_log(ctx, AV_LOG_WARNING, "Ignoring duplicate channel '%s'.\n", arg); + continue; + } + used_channels |= out_channel; + s->mapping[s->nb_irs] = out_channel; s->nb_irs++; } if (s->hrir_fmt == HRIR_MULTI) - s->nb_inputs = 2; + s->nb_hrir_inputs = 1; else - s->nb_inputs = s->nb_irs + 1; - - av_free(args); + s->nb_hrir_inputs = s->nb_irs; } typedef struct ThreadData { AVFrame *in, *out; int *write; - int **delay; float **ir; int *n_clippings; float **ringbuffer; @@ -169,7 +141,6 @@ static int headphone_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n AVFrame *in = td->in, *out = td->out; int offset = jobnr; int *write = &td->write[jobnr]; - const int *const delay = td->delay[jobnr]; const float *const ir = td->ir[jobnr]; int *n_clippings = &td->n_clippings[jobnr]; float *ringbuffer = td->ringbuffer[jobnr]; @@ -181,7 +152,7 @@ static int headphone_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n const int in_channels = in->channels; const int buffer_length = s->buffer_length; const uint32_t modulo = (uint32_t)buffer_length - 1; - float *buffer[16]; + float *buffer[64]; int wr = *write; int read; int i, l; @@ -192,23 +163,22 @@ static int headphone_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n } for (i = 0; i < in->nb_samples; i++) { - const float *temp_ir = ir; + const float *cur_ir = ir; *dst = 0; for (l = 0; l < in_channels; l++) { *(buffer[l] + wr) = src[l]; } - for (l = 0; l < in_channels; l++) { + for (l = 0; l < in_channels; cur_ir += air_len, l++) { const float *const bptr = buffer[l]; if (l == s->lfe_channel) { *dst += *(buffer[s->lfe_channel] + wr) * s->gain_lfe; - temp_ir += air_len; continue; } - read = (wr - *(delay + l) - (ir_len - 1) + buffer_length) & modulo; + read = (wr - (ir_len - 1)) & modulo; if (read + ir_len < buffer_length) { memcpy(temp_src, bptr + read, ir_len * sizeof(*temp_src)); @@ -219,8 +189,7 @@ static int headphone_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n memcpy(temp_src + len, bptr, (air_len - len) * sizeof(*temp_src)); } - dst[0] += s->fdsp->scalarproduct_float(temp_ir, temp_src, FFALIGN(ir_len, 32)); - temp_ir += air_len; + dst[0] += s->scalarproduct_float(cur_ir, temp_src, FFALIGN(ir_len, 32)); } if (fabsf(dst[0]) > 1) @@ -312,6 +281,8 @@ static int headphone_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr, for (j = 0; j < in->nb_samples; j++) { dst[2 * j] += fft_acc[j].re * fft_scale; + if (fabsf(dst[2 * j]) > 1) + n_clippings[0]++; } for (j = 0; j < ir_len - 1; j++) { @@ -320,14 +291,6 @@ static int headphone_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr, *(ringbuffer + write_pos) += fft_acc[in->nb_samples + j].re * fft_scale; } - for (i = 0; i < out->nb_samples; i++) { - if (fabsf(dst[0]) > 1) { - n_clippings[0]++; - } - - dst += 2; - } - *write = wr; return 0; @@ -345,7 +308,7 @@ static int check_ir(AVFilterLink *inlink, int input_number) av_log(ctx, AV_LOG_ERROR, "Too big length of IRs: %d > %d.\n", ir_len, max_ir_len); return AVERROR(EINVAL); } - s->in[input_number].ir_len = ir_len; + s->hrir_in[input_number].ir_len = ir_len; s->ir_len = FFMAX(ir_len, s->ir_len); return 0; @@ -366,7 +329,7 @@ static int headphone_frame(HeadphoneContext *s, AVFrame *in, AVFilterLink *outli out->pts = in->pts; td.in = in; td.out = out; td.write = s->write; - td.delay = s->delay; td.ir = s->data_ir; td.n_clippings = n_clippings; + td.ir = s->data_ir; td.n_clippings = n_clippings; td.ringbuffer = s->ringbuffer; td.temp_src = s->temp_src; td.temp_fft = s->temp_fft; td.temp_afft = s->temp_afft; @@ -391,37 +354,23 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) { struct HeadphoneContext *s = ctx->priv; const int ir_len = s->ir_len; - int nb_irs = s->nb_irs; int nb_input_channels = ctx->inputs[0]->channels; float gain_lin = expf((s->gain - 3 * nb_input_channels) / 20 * M_LN10); - FFTComplex *data_hrtf_l = NULL; - FFTComplex *data_hrtf_r = NULL; - FFTComplex *fft_in_l = NULL; - FFTComplex *fft_in_r = NULL; - float *data_ir_l = NULL; - float *data_ir_r = NULL; - int offset = 0, ret = 0; + AVFrame *frame; + int ret = 0; int n_fft; int i, j, k; s->air_len = 1 << (32 - ff_clz(ir_len)); + if (s->type == TIME_DOMAIN) { + s->air_len = FFALIGN(s->air_len, 32); + } s->buffer_length = 1 << (32 - ff_clz(s->air_len)); s->n_fft = n_fft = 1 << (32 - ff_clz(ir_len + s->size)); if (s->type == FREQUENCY_DOMAIN) { - fft_in_l = av_calloc(n_fft, sizeof(*fft_in_l)); - fft_in_r = av_calloc(n_fft, sizeof(*fft_in_r)); - if (!fft_in_l || !fft_in_r) { - ret = AVERROR(ENOMEM); - goto fail; - } - - av_fft_end(s->fft[0]); - av_fft_end(s->fft[1]); s->fft[0] = av_fft_init(av_log2(s->n_fft), 0); s->fft[1] = av_fft_init(av_log2(s->n_fft), 0); - av_fft_end(s->ifft[0]); - av_fft_end(s->ifft[1]); s->ifft[0] = av_fft_init(av_log2(s->n_fft), 1); s->ifft[1] = av_fft_init(av_log2(s->n_fft), 1); @@ -432,11 +381,6 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) } } - s->data_ir[0] = av_calloc(s->air_len, sizeof(float) * s->nb_irs); - s->data_ir[1] = av_calloc(s->air_len, sizeof(float) * s->nb_irs); - s->delay[0] = av_calloc(s->nb_irs, sizeof(float)); - s->delay[1] = av_calloc(s->nb_irs, sizeof(float)); - if (s->type == TIME_DOMAIN) { s->ringbuffer[0] = av_calloc(s->buffer_length, sizeof(float) * nb_input_channels); s->ringbuffer[1] = av_calloc(s->buffer_length, sizeof(float) * nb_input_channels); @@ -454,8 +398,7 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) } } - if (!s->data_ir[0] || !s->data_ir[1] || - !s->ringbuffer[0] || !s->ringbuffer[1]) { + if (!s->ringbuffer[0] || !s->ringbuffer[1]) { ret = AVERROR(ENOMEM); goto fail; } @@ -464,153 +407,96 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) s->temp_src[0] = av_calloc(s->air_len, sizeof(float)); s->temp_src[1] = av_calloc(s->air_len, sizeof(float)); - data_ir_l = av_calloc(nb_irs * s->air_len, sizeof(*data_ir_l)); - data_ir_r = av_calloc(nb_irs * s->air_len, sizeof(*data_ir_r)); - if (!data_ir_r || !data_ir_l || !s->temp_src[0] || !s->temp_src[1]) { + s->data_ir[0] = av_calloc(nb_input_channels * s->air_len, sizeof(*s->data_ir[0])); + s->data_ir[1] = av_calloc(nb_input_channels * s->air_len, sizeof(*s->data_ir[1])); + if (!s->data_ir[0] || !s->data_ir[1] || !s->temp_src[0] || !s->temp_src[1]) { ret = AVERROR(ENOMEM); goto fail; } } else { - data_hrtf_l = av_calloc(n_fft, sizeof(*data_hrtf_l) * nb_irs); - data_hrtf_r = av_calloc(n_fft, sizeof(*data_hrtf_r) * nb_irs); - if (!data_hrtf_r || !data_hrtf_l) { + s->data_hrtf[0] = av_calloc(n_fft, sizeof(*s->data_hrtf[0]) * nb_input_channels); + s->data_hrtf[1] = av_calloc(n_fft, sizeof(*s->data_hrtf[1]) * nb_input_channels); + if (!s->data_hrtf[0] || !s->data_hrtf[1]) { ret = AVERROR(ENOMEM); goto fail; } } - for (i = 0; i < s->nb_inputs - 1; i++) { - int len = s->in[i + 1].ir_len; - int delay_l = s->in[i + 1].delay_l; - int delay_r = s->in[i + 1].delay_r; + for (i = 0; i < s->nb_hrir_inputs; av_frame_free(&frame), i++) { + int len = s->hrir_in[i].ir_len; float *ptr; - ret = ff_inlink_consume_samples(ctx->inputs[i + 1], len, len, &s->in[i + 1].frame); + ret = ff_inlink_consume_samples(ctx->inputs[i + 1], len, len, &frame); if (ret < 0) goto fail; - ptr = (float *)s->in[i + 1].frame->extended_data[0]; + ptr = (float *)frame->extended_data[0]; if (s->hrir_fmt == HRIR_STEREO) { - int idx = -1; - - for (j = 0; j < inlink->channels; j++) { - if (s->mapping[i] < 0) { - continue; - } - - if ((av_channel_layout_extract_channel(inlink->channel_layout, j)) == (1LL << s->mapping[i])) { - idx = i; - break; - } - } - - if (idx == -1) + int idx = av_get_channel_layout_channel_index(inlink->channel_layout, + s->mapping[i]); + if (idx < 0) continue; if (s->type == TIME_DOMAIN) { - offset = idx * s->air_len; + float *data_ir_l = s->data_ir[0] + idx * s->air_len; + float *data_ir_r = s->data_ir[1] + idx * s->air_len; + for (j = 0; j < len; j++) { - data_ir_l[offset + j] = ptr[len * 2 - j * 2 - 2] * gain_lin; - data_ir_r[offset + j] = ptr[len * 2 - j * 2 - 1] * gain_lin; + data_ir_l[j] = ptr[len * 2 - j * 2 - 2] * gain_lin; + data_ir_r[j] = ptr[len * 2 - j * 2 - 1] * gain_lin; } } else { - memset(fft_in_l, 0, n_fft * sizeof(*fft_in_l)); - memset(fft_in_r, 0, n_fft * sizeof(*fft_in_r)); + FFTComplex *fft_in_l = s->data_hrtf[0] + idx * n_fft; + FFTComplex *fft_in_r = s->data_hrtf[1] + idx * n_fft; - offset = idx * n_fft; for (j = 0; j < len; j++) { - fft_in_l[delay_l + j].re = ptr[j * 2 ] * gain_lin; - fft_in_r[delay_r + j].re = ptr[j * 2 + 1] * gain_lin; + fft_in_l[j].re = ptr[j * 2 ] * gain_lin; + fft_in_r[j].re = ptr[j * 2 + 1] * gain_lin; } av_fft_permute(s->fft[0], fft_in_l); av_fft_calc(s->fft[0], fft_in_l); - memcpy(data_hrtf_l + offset, fft_in_l, n_fft * sizeof(*fft_in_l)); av_fft_permute(s->fft[0], fft_in_r); av_fft_calc(s->fft[0], fft_in_r); - memcpy(data_hrtf_r + offset, fft_in_r, n_fft * sizeof(*fft_in_r)); } } else { int I, N = ctx->inputs[1]->channels; for (k = 0; k < N / 2; k++) { - int idx = -1; - - for (j = 0; j < inlink->channels; j++) { - if (s->mapping[k] < 0) { - continue; - } - - if ((av_channel_layout_extract_channel(inlink->channel_layout, j)) == (1LL << s->mapping[k])) { - idx = k; - break; - } - } - if (idx == -1) + int idx = av_get_channel_layout_channel_index(inlink->channel_layout, + s->mapping[k]); + if (idx < 0) continue; - I = idx * 2; + I = k * 2; if (s->type == TIME_DOMAIN) { - offset = idx * s->air_len; + float *data_ir_l = s->data_ir[0] + idx * s->air_len; + float *data_ir_r = s->data_ir[1] + idx * s->air_len; + for (j = 0; j < len; j++) { - data_ir_l[offset + j] = ptr[len * N - j * N - N + I ] * gain_lin; - data_ir_r[offset + j] = ptr[len * N - j * N - N + I + 1] * gain_lin; + data_ir_l[j] = ptr[len * N - j * N - N + I ] * gain_lin; + data_ir_r[j] = ptr[len * N - j * N - N + I + 1] * gain_lin; } } else { - memset(fft_in_l, 0, n_fft * sizeof(*fft_in_l)); - memset(fft_in_r, 0, n_fft * sizeof(*fft_in_r)); + FFTComplex *fft_in_l = s->data_hrtf[0] + idx * n_fft; + FFTComplex *fft_in_r = s->data_hrtf[1] + idx * n_fft; - offset = idx * n_fft; for (j = 0; j < len; j++) { - fft_in_l[delay_l + j].re = ptr[j * N + I ] * gain_lin; - fft_in_r[delay_r + j].re = ptr[j * N + I + 1] * gain_lin; + fft_in_l[j].re = ptr[j * N + I ] * gain_lin; + fft_in_r[j].re = ptr[j * N + I + 1] * gain_lin; } av_fft_permute(s->fft[0], fft_in_l); av_fft_calc(s->fft[0], fft_in_l); - memcpy(data_hrtf_l + offset, fft_in_l, n_fft * sizeof(*fft_in_l)); av_fft_permute(s->fft[0], fft_in_r); av_fft_calc(s->fft[0], fft_in_r); - memcpy(data_hrtf_r + offset, fft_in_r, n_fft * sizeof(*fft_in_r)); } } } - - av_frame_free(&s->in[i + 1].frame); - } - - if (s->type == TIME_DOMAIN) { - memcpy(s->data_ir[0], data_ir_l, sizeof(float) * nb_irs * s->air_len); - memcpy(s->data_ir[1], data_ir_r, sizeof(float) * nb_irs * s->air_len); - } else { - s->data_hrtf[0] = av_calloc(n_fft * s->nb_irs, sizeof(FFTComplex)); - s->data_hrtf[1] = av_calloc(n_fft * s->nb_irs, sizeof(FFTComplex)); - if (!s->data_hrtf[0] || !s->data_hrtf[1]) { - ret = AVERROR(ENOMEM); - goto fail; - } - - memcpy(s->data_hrtf[0], data_hrtf_l, - sizeof(FFTComplex) * nb_irs * n_fft); - memcpy(s->data_hrtf[1], data_hrtf_r, - sizeof(FFTComplex) * nb_irs * n_fft); } s->have_hrirs = 1; fail: - - for (i = 0; i < s->nb_inputs - 1; i++) - av_frame_free(&s->in[i + 1].frame); - - av_freep(&data_ir_l); - av_freep(&data_ir_r); - - av_freep(&data_hrtf_l); - av_freep(&data_hrtf_r); - - av_freep(&fft_in_l); - av_freep(&fft_in_r); - return ret; } @@ -624,43 +510,38 @@ static int activate(AVFilterContext *ctx) FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[0], ctx); if (!s->eof_hrirs) { - for (i = 1; i < s->nb_inputs; i++) { - if (s->in[i].eof) + int eof = 1; + for (i = 0; i < s->nb_hrir_inputs; i++) { + AVFilterLink *input = ctx->inputs[i + 1]; + + if (s->hrir_in[i].eof) continue; - if ((ret = check_ir(ctx->inputs[i], i)) < 0) + if ((ret = check_ir(input, i)) < 0) return ret; - if (!s->in[i].eof) { - if (ff_outlink_get_status(ctx->inputs[i]) == AVERROR_EOF) - s->in[i].eof = 1; - } - } - - for (i = 1; i < s->nb_inputs; i++) { - if (!s->in[i].eof) - break; - } - - if (i != s->nb_inputs) { - if (ff_outlink_frame_wanted(ctx->outputs[0])) { - for (i = 1; i < s->nb_inputs; i++) { - if (!s->in[i].eof) - ff_inlink_request_frame(ctx->inputs[i]); + if (ff_outlink_get_status(input) == AVERROR_EOF) { + if (!ff_inlink_queued_samples(input)) { + av_log(ctx, AV_LOG_ERROR, "No samples provided for " + "HRIR stream %d.\n", i); + return AVERROR_INVALIDDATA; } + s->hrir_in[i].eof = 1; + } else { + if (ff_outlink_frame_wanted(ctx->outputs[0])) + ff_inlink_request_frame(input); + eof = 0; } - - return 0; - } else { - s->eof_hrirs = 1; } - } + if (!eof) + return 0; + s->eof_hrirs = 1; - if (!s->have_hrirs && s->eof_hrirs) { ret = convert_coeffs(ctx, inlink); if (ret < 0) return ret; - } + } else if (!s->have_hrirs) + return AVERROR_EOF; if ((ret = ff_inlink_consume_samples(ctx->inputs[0], s->size, s->size, &in)) > 0) { ret = headphone_frame(s, in, outlink); @@ -698,11 +579,14 @@ static int query_formats(AVFilterContext *ctx) if (!layouts) return AVERROR(ENOMEM); - ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts); if (ret) return ret; ret = ff_add_channel_layout(&stereo_layout, AV_CH_LAYOUT_STEREO); + if (ret) + return ret; + ret = ff_channel_layouts_ref(stereo_layout, &ctx->outputs[0]->incfg.channel_layouts); if (ret) return ret; @@ -710,21 +594,17 @@ static int query_formats(AVFilterContext *ctx) hrir_layouts = ff_all_channel_counts(); if (!hrir_layouts) return AVERROR(ENOMEM); - ret = ff_channel_layouts_ref(hrir_layouts, &ctx->inputs[1]->out_channel_layouts); + ret = ff_channel_layouts_ref(hrir_layouts, &ctx->inputs[1]->outcfg.channel_layouts); if (ret) return ret; } else { - for (i = 1; i < s->nb_inputs; i++) { - ret = ff_channel_layouts_ref(stereo_layout, &ctx->inputs[i]->out_channel_layouts); + for (i = 1; i <= s->nb_hrir_inputs; i++) { + ret = ff_channel_layouts_ref(stereo_layout, &ctx->inputs[i]->outcfg.channel_layouts); if (ret) return ret; } } - ret = ff_channel_layouts_ref(stereo_layout, &ctx->outputs[0]->in_channel_layouts); - if (ret) - return ret; - formats = ff_all_samplerates(); if (!formats) return AVERROR(ENOMEM); @@ -741,6 +621,8 @@ static int config_input(AVFilterLink *inlink) return AVERROR(EINVAL); } + s->lfe_channel = av_get_channel_layout_channel_index(inlink->channel_layout, + AV_CH_LOW_FREQUENCY); return 0; } @@ -764,27 +646,27 @@ static av_cold int init(AVFilterContext *ctx) parse_map(ctx); - s->in = av_calloc(s->nb_inputs, sizeof(*s->in)); - if (!s->in) - return AVERROR(ENOMEM); - - for (i = 1; i < s->nb_inputs; i++) { - char *name = av_asprintf("hrir%d", i - 1); + for (i = 0; i < s->nb_hrir_inputs; i++) { + char *name = av_asprintf("hrir%d", i); AVFilterPad pad = { .name = name, .type = AVMEDIA_TYPE_AUDIO, }; if (!name) return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { + if ((ret = ff_insert_inpad(ctx, i + 1, &pad)) < 0) { av_freep(&pad.name); return ret; } } - s->fdsp = avpriv_float_dsp_alloc(0); - if (!s->fdsp) - return AVERROR(ENOMEM); + if (s->type == TIME_DOMAIN) { + AVFloatDSPContext *fdsp = avpriv_float_dsp_alloc(0); + if (!fdsp) + return AVERROR(ENOMEM); + s->scalarproduct_float = fdsp->scalarproduct_float; + av_free(fdsp); + } return 0; } @@ -812,14 +694,11 @@ static int config_output(AVFilterLink *outlink) static av_cold void uninit(AVFilterContext *ctx) { HeadphoneContext *s = ctx->priv; - int i; av_fft_end(s->ifft[0]); av_fft_end(s->ifft[1]); av_fft_end(s->fft[0]); av_fft_end(s->fft[1]); - av_freep(&s->delay[0]); - av_freep(&s->delay[1]); av_freep(&s->data_ir[0]); av_freep(&s->data_ir[1]); av_freep(&s->ringbuffer[0]); @@ -832,13 +711,9 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&s->temp_afft[1]); av_freep(&s->data_hrtf[0]); av_freep(&s->data_hrtf[1]); - av_freep(&s->fdsp); - for (i = 0; i < s->nb_inputs; i++) { - if (ctx->input_pads && i) - av_freep(&ctx->input_pads[i].name); - } - av_freep(&s->in); + for (unsigned i = 1; i < ctx->nb_inputs; i++) + av_freep(&ctx->input_pads[i].name); } #define OFFSET(x) offsetof(HeadphoneContext, x) diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c index ea03b60d6..8f5df267d 100644 --- a/libavfilter/af_join.c +++ b/libavfilter/af_join.c @@ -227,12 +227,12 @@ static int join_query_formats(AVFilterContext *ctx) int i, ret; if ((ret = ff_add_channel_layout(&layouts, s->channel_layout)) < 0 || - (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0) + (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0) return ret; for (i = 0; i < ctx->nb_inputs; i++) { layouts = ff_all_channel_layouts(); - if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0) return ret; } diff --git a/libavfilter/af_ladspa.c b/libavfilter/af_ladspa.c index a8562fc07..31adc9c34 100644 --- a/libavfilter/af_ladspa.c +++ b/libavfilter/af_ladspa.c @@ -64,6 +64,9 @@ typedef struct LADSPAContext { int nb_samples; int64_t pts; int64_t duration; + int in_trim; + int out_pad; + int latency; } LADSPAContext; #define OFFSET(x) offsetof(LADSPAContext, x) @@ -81,11 +84,28 @@ static const AVOption ladspa_options[] = { { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS }, { "duration", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS }, { "d", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS }, + { "latency", "enable latency compensation", OFFSET(latency), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { "l", "enable latency compensation", OFFSET(latency), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { NULL } }; AVFILTER_DEFINE_CLASS(ladspa); +static int find_latency(AVFilterContext *ctx, LADSPAContext *s) +{ + int latency = 0; + + for (int ctl = 0; ctl < s->nb_outputcontrols; ctl++) { + if (av_strcasecmp("latency", s->desc->PortNames[s->ocmap[ctl]])) + continue; + + latency = lrintf(s->octlv[ctl]); + break; + } + + return latency; +} + static void print_ctl_info(AVFilterContext *ctx, int level, LADSPAContext *s, int ctl, unsigned long *map, LADSPA_Data *values, int print) @@ -143,12 +163,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterContext *ctx = inlink->dst; LADSPAContext *s = ctx->priv; AVFrame *out; - int i, h, p; + int i, h, p, new_out_samples; av_assert0(in->channels == (s->nb_inputs * s->nb_handles)); if (!s->nb_outputs || (av_frame_is_writable(in) && s->nb_inputs == s->nb_outputs && + s->in_trim == 0 && s->out_pad == 0 && !(s->desc->Properties & LADSPA_PROPERTY_INPLACE_BROKEN))) { out = in; } else { @@ -176,6 +197,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } s->desc->run(s->handles[h], in->nb_samples); + if (s->latency) + s->in_trim = s->out_pad = find_latency(ctx, s); + s->latency = 0; } for (i = 0; i < s->nb_outputcontrols; i++) @@ -184,6 +208,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if (out != in) av_frame_free(&in); + new_out_samples = out->nb_samples; + if (s->in_trim > 0) { + int trim = FFMIN(new_out_samples, s->in_trim); + + new_out_samples -= trim; + s->in_trim -= trim; + } + + if (new_out_samples <= 0) { + av_frame_free(&out); + return 0; + } else if (new_out_samples < out->nb_samples) { + int offset = out->nb_samples - new_out_samples; + for (int ch = 0; ch < out->channels; ch++) + memmove(out->extended_data[ch], out->extended_data[ch] + sizeof(float) * offset, + sizeof(float) * new_out_samples); + out->nb_samples = new_out_samples; + } + return ff_filter_frame(ctx->outputs[0], out); } @@ -195,8 +238,19 @@ static int request_frame(AVFilterLink *outlink) int64_t t; int i; - if (ctx->nb_inputs) - return ff_request_frame(ctx->inputs[0]); + if (ctx->nb_inputs) { + int ret = ff_request_frame(ctx->inputs[0]); + + if (ret == AVERROR_EOF && s->out_pad > 0) { + AVFrame *frame = ff_get_audio_buffer(outlink, FFMIN(2048, s->out_pad)); + if (!frame) + return AVERROR(ENOMEM); + + s->out_pad -= frame->nb_samples; + return filter_frame(ctx->inputs[0], frame); + } + return ret; + } t = av_rescale(s->pts, AV_TIME_BASE, s->sample_rate); if (s->duration >= 0 && t >= s->duration) @@ -415,6 +469,7 @@ static av_cold int init(AVFilterContext *ctx) } else { // argument is a shared object name char *paths = av_strdup(getenv("LADSPA_PATH")); + const char *home_path = getenv("HOME"); const char *separator = ":"; if (paths) { @@ -426,7 +481,12 @@ static av_cold int init(AVFilterContext *ctx) } av_free(paths); - if (!s->dl_handle && (paths = av_asprintf("%s/.ladspa/lib", getenv("HOME")))) { + if (!s->dl_handle && home_path && (paths = av_asprintf("%s/.ladspa", home_path))) { + s->dl_handle = try_load(paths, s->dl_name); + av_free(paths); + } + + if (!s->dl_handle && home_path && (paths = av_asprintf("%s/.ladspa/lib", home_path))) { s->dl_handle = try_load(paths, s->dl_name); av_free(paths); } @@ -654,12 +714,12 @@ static int query_formats(AVFilterContext *ctx) ret = ff_add_channel_layout(&layouts, inlayout); if (ret < 0) return ret; - ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts); if (ret < 0) return ret; if (!s->nb_outputs) { - ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts); if (ret < 0) return ret; } @@ -672,7 +732,7 @@ static int query_formats(AVFilterContext *ctx) ret = ff_add_channel_layout(&layouts, outlayout); if (ret < 0) return ret; - ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts); if (ret < 0) return ret; } diff --git a/libavfilter/af_loudnorm.c b/libavfilter/af_loudnorm.c index 8e3cdc36d..06aca8ef4 100644 --- a/libavfilter/af_loudnorm.c +++ b/libavfilter/af_loudnorm.c @@ -714,10 +714,10 @@ static int query_formats(AVFilterContext *ctx) formats = ff_make_format_list(input_srate); if (!formats) return AVERROR(ENOMEM); - ret = ff_formats_ref(formats, &inlink->out_samplerates); + ret = ff_formats_ref(formats, &inlink->outcfg.samplerates); if (ret < 0) return ret; - ret = ff_formats_ref(formats, &outlink->in_samplerates); + ret = ff_formats_ref(formats, &outlink->incfg.samplerates); if (ret < 0) return ret; } diff --git a/libavfilter/af_lv2.c b/libavfilter/af_lv2.c index 8a0a6fd88..3dabe566f 100644 --- a/libavfilter/af_lv2.c +++ b/libavfilter/af_lv2.c @@ -524,12 +524,12 @@ static int query_formats(AVFilterContext *ctx) ret = ff_add_channel_layout(&layouts, inlayout); if (ret < 0) return ret; - ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts); if (ret < 0) return ret; if (!s->nb_outputs) { - ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts); if (ret < 0) return ret; } @@ -542,7 +542,7 @@ static int query_formats(AVFilterContext *ctx) ret = ff_add_channel_layout(&layouts, outlayout); if (ret < 0) return ret; - ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts); if (ret < 0) return ret; } diff --git a/libavfilter/af_mcompand.c b/libavfilter/af_mcompand.c index f142573be..ce4f366ad 100644 --- a/libavfilter/af_mcompand.c +++ b/libavfilter/af_mcompand.c @@ -361,10 +361,8 @@ static int config_output(AVFilterLink *outlink) char *p2, *p3, *saveptr2 = NULL, *saveptr3 = NULL; double radius; - if (!tstr) { - uninit(ctx); + if (!tstr) return AVERROR(EINVAL); - } p = NULL; p2 = tstr; @@ -372,7 +370,6 @@ static int config_output(AVFilterLink *outlink) tstr2 = av_strtok(p2, " ", &saveptr2); if (!tstr2) { av_log(ctx, AV_LOG_ERROR, "at least one attacks/decays rate is mandatory\n"); - uninit(ctx); return AVERROR(EINVAL); } p2 = NULL; @@ -381,7 +378,6 @@ static int config_output(AVFilterLink *outlink) count_items(tstr2, &nb_attacks, ','); if (!nb_attacks || nb_attacks & 1) { av_log(ctx, AV_LOG_ERROR, "number of attacks rate plus decays rate must be even\n"); - uninit(ctx); return AVERROR(EINVAL); } @@ -417,7 +413,6 @@ static int config_output(AVFilterLink *outlink) tstr2 = av_strtok(p2, " ", &saveptr2); if (!tstr2) { av_log(ctx, AV_LOG_ERROR, "transfer function curve in dB must be set\n"); - uninit(ctx); return AVERROR(EINVAL); } sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.curve_dB); @@ -427,7 +422,6 @@ static int config_output(AVFilterLink *outlink) tstr2 = av_strtok(p2, " ", &saveptr2); if (!tstr2) { av_log(ctx, AV_LOG_ERROR, "transfer points missing\n"); - uninit(ctx); return AVERROR(EINVAL); } @@ -435,38 +429,31 @@ static int config_output(AVFilterLink *outlink) s->bands[i].transfer_fn.nb_segments = (nb_points + 4) * 2; s->bands[i].transfer_fn.segments = av_calloc(s->bands[i].transfer_fn.nb_segments, sizeof(CompandSegment)); - if (!s->bands[i].transfer_fn.segments) { - uninit(ctx); + if (!s->bands[i].transfer_fn.segments) return AVERROR(ENOMEM); - } ret = parse_points(tstr2, nb_points, radius, &s->bands[i].transfer_fn, ctx); if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "transfer points parsing failed\n"); - uninit(ctx); return ret; } tstr2 = av_strtok(p2, " ", &saveptr2); if (!tstr2) { av_log(ctx, AV_LOG_ERROR, "crossover_frequency is missing\n"); - uninit(ctx); return AVERROR(EINVAL); } new_nb_items += sscanf(tstr2, "%lf", &s->bands[i].topfreq) == 1; if (s->bands[i].topfreq < 0 || s->bands[i].topfreq >= outlink->sample_rate / 2) { av_log(ctx, AV_LOG_ERROR, "crossover_frequency: %f, should be >=0 and lower than half of sample rate: %d.\n", s->bands[i].topfreq, outlink->sample_rate / 2); - uninit(ctx); return AVERROR(EINVAL); } if (s->bands[i].topfreq != 0) { ret = crossover_setup(outlink, &s->bands[i].filter, s->bands[i].topfreq); - if (ret < 0) { - uninit(ctx); + if (ret < 0) return ret; - } } tstr2 = av_strtok(p2, " ", &saveptr2); diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c index 6924d1c72..b62817707 100644 --- a/libavfilter/af_pan.c +++ b/libavfilter/af_pan.c @@ -266,7 +266,7 @@ static int query_formats(AVFilterContext *ctx) // inlink supports any channel layout layouts = ff_all_channel_counts(); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; // outlink supports only requested output channel layout @@ -275,7 +275,7 @@ static int query_formats(AVFilterContext *ctx) pan->out_channel_layout ? pan->out_channel_layout : FF_COUNT2LAYOUT(pan->nb_output_channels))) < 0) return ret; - return ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); + return ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts); } static int config_props(AVFilterLink *link) diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c index e3c6a2069..caa97d8ab 100644 --- a/libavfilter/af_resample.c +++ b/libavfilter/af_resample.c @@ -102,12 +102,12 @@ static int query_formats(AVFilterContext *ctx) !(out_layouts = ff_all_channel_layouts ( ))) return AVERROR(ENOMEM); - if ((ret = ff_formats_ref (in_formats, &inlink->out_formats )) < 0 || - (ret = ff_formats_ref (out_formats, &outlink->in_formats )) < 0 || - (ret = ff_formats_ref (in_samplerates, &inlink->out_samplerates )) < 0 || - (ret = ff_formats_ref (out_samplerates, &outlink->in_samplerates )) < 0 || - (ret = ff_channel_layouts_ref (in_layouts, &inlink->out_channel_layouts)) < 0 || - (ret = ff_channel_layouts_ref (out_layouts, &outlink->in_channel_layouts)) < 0) + if ((ret = ff_formats_ref (in_formats, &inlink->outcfg.formats )) < 0 || + (ret = ff_formats_ref (out_formats, &outlink->incfg.formats )) < 0 || + (ret = ff_formats_ref (in_samplerates, &inlink->outcfg.samplerates )) < 0 || + (ret = ff_formats_ref (out_samplerates, &outlink->incfg.samplerates )) < 0 || + (ret = ff_channel_layouts_ref (in_layouts, &inlink->outcfg.channel_layouts)) < 0 || + (ret = ff_channel_layouts_ref (out_layouts, &outlink->incfg.channel_layouts)) < 0) return ret; return 0; @@ -306,10 +306,19 @@ fail: return ret; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *resample_child_class_next(const AVClass *prev) { return prev ? NULL : avresample_get_class(); } +#endif + +static const AVClass *resample_child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : avresample_get_class(); + *iter = (void*)(uintptr_t)c; + return c; +} static void *resample_child_next(void *obj, void *prev) { @@ -321,7 +330,10 @@ static const AVClass resample_class = { .class_name = "resample", .item_name = av_default_item_name, .version = LIBAVUTIL_VERSION_INT, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = resample_child_class_next, +#endif + .child_class_iterate = resample_child_class_iterate, .child_next = resample_child_next, }; diff --git a/libavfilter/af_rubberband.c b/libavfilter/af_rubberband.c index 1dfd74422..b42e67f09 100644 --- a/libavfilter/af_rubberband.c +++ b/libavfilter/af_rubberband.c @@ -212,6 +212,7 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar rubberband_set_time_ratio(s->rbs, 1. / s->tempo); rubberband_set_pitch_scale(s->rbs, s->pitch); + s->nb_samples = rubberband_get_samples_required(s->rbs); return 0; } diff --git a/libavfilter/af_sidechaincompress.c b/libavfilter/af_sidechaincompress.c index e79c04d40..80d1d8a10 100644 --- a/libavfilter/af_sidechaincompress.c +++ b/libavfilter/af_sidechaincompress.c @@ -306,20 +306,20 @@ static int query_formats(AVFilterContext *ctx) }; int ret, i; - if (!ctx->inputs[0]->in_channel_layouts || - !ctx->inputs[0]->in_channel_layouts->nb_channel_layouts) { + if (!ctx->inputs[0]->incfg.channel_layouts || + !ctx->inputs[0]->incfg.channel_layouts->nb_channel_layouts) { av_log(ctx, AV_LOG_WARNING, "No channel layout for input 1\n"); return AVERROR(EAGAIN); } - if ((ret = ff_add_channel_layout(&layouts, ctx->inputs[0]->in_channel_layouts->channel_layouts[0])) < 0 || - (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0) + if ((ret = ff_add_channel_layout(&layouts, ctx->inputs[0]->incfg.channel_layouts->channel_layouts[0])) < 0 || + (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0) return ret; for (i = 0; i < 2; i++) { layouts = ff_all_channel_counts(); - if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0) return ret; } diff --git a/libavfilter/af_sofalizer.c b/libavfilter/af_sofalizer.c index ccf3872e7..8a0397f54 100644 --- a/libavfilter/af_sofalizer.c +++ b/libavfilter/af_sofalizer.c @@ -183,10 +183,11 @@ static int preload_sofa(AVFilterContext *ctx, char *filename, int *samplingrate) return 0; } -static int parse_channel_name(char **arg, int *rchannel, char *buf) +static int parse_channel_name(AVFilterContext *ctx, char **arg, int *rchannel) { int len, i, channel_id = 0; int64_t layout, layout0; + char buf[8] = {0}; /* try to parse a channel name, e.g. "FL" */ if (av_sscanf(*arg, "%7[A-Z]%n", buf, &len)) { @@ -199,8 +200,18 @@ static int parse_channel_name(char **arg, int *rchannel, char *buf) } } /* reject layouts that are not a single channel */ - if (channel_id >= 64 || layout0 != 1LL << channel_id) + if (channel_id >= 64 || layout0 != 1LL << channel_id) { + av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", buf); return AVERROR(EINVAL); + } + *rchannel = channel_id; + *arg += len; + return 0; + } else if (av_sscanf(*arg, "%d%n", &channel_id, &len) == 1) { + if (channel_id < 0 || channel_id >= 64) { + av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%d\' as channel number.\n", channel_id); + return AVERROR(EINVAL); + } *rchannel = channel_id; *arg += len; return 0; @@ -218,13 +229,11 @@ static void parse_speaker_pos(AVFilterContext *ctx, int64_t in_channel_layout) p = args; while ((arg = av_strtok(p, "|", &tokenizer))) { - char buf[8]; float azim, elev; int out_ch_id; p = NULL; - if (parse_channel_name(&arg, &out_ch_id, buf)) { - av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", buf); + if (parse_channel_name(ctx, &arg, &out_ch_id)) { continue; } if (av_sscanf(arg, "%f %f", &azim, &elev) == 2) { @@ -246,11 +255,11 @@ static int get_speaker_pos(AVFilterContext *ctx, { struct SOFAlizerContext *s = ctx->priv; uint64_t channels_layout = ctx->inputs[0]->channel_layout; - float azim[16] = { 0 }; - float elev[16] = { 0 }; + float azim[64] = { 0 }; + float elev[64] = { 0 }; int m, ch, n_conv = ctx->inputs[0]->channels; /* get no. input channels */ - if (n_conv > 16) + if (n_conv < 0 || n_conv > 64) return AVERROR(EINVAL); s->lfe_channel = -1; @@ -351,7 +360,7 @@ static int sofalizer_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n const int buffer_length = s->buffer_length; /* -1 for AND instead of MODULO (applied to powers of 2): */ const uint32_t modulo = (uint32_t)buffer_length - 1; - float *buffer[16]; /* holds ringbuffer for each input channel */ + float *buffer[64]; /* holds ringbuffer for each input channel */ int wr = *write; int read; int i, l; @@ -652,7 +661,7 @@ static int query_formats(AVFilterContext *ctx) if (!layouts) return AVERROR(ENOMEM); - ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts); if (ret) return ret; @@ -661,7 +670,7 @@ static int query_formats(AVFilterContext *ctx) if (ret) return ret; - ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts); if (ret) return ret; diff --git a/libavfilter/af_speechnorm.c b/libavfilter/af_speechnorm.c new file mode 100644 index 000000000..eb46cf298 --- /dev/null +++ b/libavfilter/af_speechnorm.c @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2020 Paul B Mahol + * + * Speech Normalizer + * + * 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 + * Speech Normalizer + */ + +#include + +#include "libavutil/avassert.h" +#include "libavutil/opt.h" + +#define FF_BUFQUEUE_SIZE (1024) +#include "bufferqueue.h" + +#include "audio.h" +#include "avfilter.h" +#include "filters.h" +#include "internal.h" + +#define MAX_ITEMS 882000 +#define MIN_PEAK (1. / 32768.) + +typedef struct PeriodItem { + int size; + int type; + double max_peak; +} PeriodItem; + +typedef struct ChannelContext { + int state; + int bypass; + PeriodItem pi[MAX_ITEMS]; + double gain_state; + double pi_max_peak; + int pi_start; + int pi_end; + int pi_size; +} ChannelContext; + +typedef struct SpeechNormalizerContext { + const AVClass *class; + + double peak_value; + double max_expansion; + double max_compression; + double threshold_value; + double raise_amount; + double fall_amount; + uint64_t channels; + int invert; + int link; + + ChannelContext *cc; + double prev_gain; + + int max_period; + int eof; + int64_t pts; + + struct FFBufQueue queue; + + void (*analyze_channel)(AVFilterContext *ctx, ChannelContext *cc, + const uint8_t *srcp, int nb_samples); + void (*filter_channels[2])(AVFilterContext *ctx, + AVFrame *in, int nb_samples); +} SpeechNormalizerContext; + +#define OFFSET(x) offsetof(SpeechNormalizerContext, x) +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption speechnorm_options[] = { + { "peak", "set the peak value", OFFSET(peak_value), AV_OPT_TYPE_DOUBLE, {.dbl=0.95}, 0.0, 1.0, FLAGS }, + { "p", "set the peak value", OFFSET(peak_value), AV_OPT_TYPE_DOUBLE, {.dbl=0.95}, 0.0, 1.0, FLAGS }, + { "expansion", "set the max expansion factor", OFFSET(max_expansion), AV_OPT_TYPE_DOUBLE, {.dbl=2.0}, 1.0, 50.0, FLAGS }, + { "e", "set the max expansion factor", OFFSET(max_expansion), AV_OPT_TYPE_DOUBLE, {.dbl=2.0}, 1.0, 50.0, FLAGS }, + { "compression", "set the max compression factor", OFFSET(max_compression), AV_OPT_TYPE_DOUBLE, {.dbl=2.0}, 1.0, 50.0, FLAGS }, + { "c", "set the max compression factor", OFFSET(max_compression), AV_OPT_TYPE_DOUBLE, {.dbl=2.0}, 1.0, 50.0, FLAGS }, + { "threshold", "set the threshold value", OFFSET(threshold_value), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0.0, 1.0, FLAGS }, + { "t", "set the threshold value", OFFSET(threshold_value), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0.0, 1.0, FLAGS }, + { "raise", "set the expansion raising amount", OFFSET(raise_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0.0, 1.0, FLAGS }, + { "r", "set the expansion raising amount", OFFSET(raise_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0.0, 1.0, FLAGS }, + { "fall", "set the compression raising amount", OFFSET(fall_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0.0, 1.0, FLAGS }, + { "f", "set the compression raising amount", OFFSET(fall_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0.0, 1.0, FLAGS }, + { "channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS }, + { "h", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS }, + { "invert", "set inverted filtering", OFFSET(invert), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { "i", "set inverted filtering", OFFSET(invert), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { "link", "set linked channels filtering", OFFSET(link), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { "l", "set linked channels filtering", OFFSET(link), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(speechnorm); + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats; + AVFilterChannelLayouts *layouts; + static const enum AVSampleFormat sample_fmts[] = { + AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_NONE + }; + int ret; + + layouts = ff_all_channel_counts(); + if (!layouts) + return AVERROR(ENOMEM); + ret = ff_set_common_channel_layouts(ctx, layouts); + if (ret < 0) + return ret; + + formats = ff_make_format_list(sample_fmts); + if (!formats) + return AVERROR(ENOMEM); + ret = ff_set_common_formats(ctx, formats); + if (ret < 0) + return ret; + + formats = ff_all_samplerates(); + if (!formats) + return AVERROR(ENOMEM); + return ff_set_common_samplerates(ctx, formats); +} + +static int get_pi_samples(PeriodItem *pi, int start, int end, int remain) +{ + int sum; + + if (pi[start].type == 0) + return remain; + + sum = remain; + while (start != end) { + start++; + if (start >= MAX_ITEMS) + start = 0; + if (pi[start].type == 0) + break; + av_assert0(pi[start].size > 0); + sum += pi[start].size; + } + + return sum; +} + +static int available_samples(AVFilterContext *ctx) +{ + SpeechNormalizerContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + int min_pi_nb_samples; + + min_pi_nb_samples = get_pi_samples(s->cc[0].pi, s->cc[0].pi_start, s->cc[0].pi_end, s->cc[0].pi_size); + for (int ch = 1; ch < inlink->channels && min_pi_nb_samples > 0; ch++) { + ChannelContext *cc = &s->cc[ch]; + + min_pi_nb_samples = FFMIN(min_pi_nb_samples, get_pi_samples(cc->pi, cc->pi_start, cc->pi_end, cc->pi_size)); + } + + return min_pi_nb_samples; +} + +static void consume_pi(ChannelContext *cc, int nb_samples) +{ + if (cc->pi_size >= nb_samples) { + cc->pi_size -= nb_samples; + } else { + av_assert0(0); + } +} + +static double next_gain(AVFilterContext *ctx, double pi_max_peak, int bypass, double state) +{ + SpeechNormalizerContext *s = ctx->priv; + const double expansion = FFMIN(s->max_expansion, s->peak_value / pi_max_peak); + const double compression = 1. / s->max_compression; + const int type = s->invert ? pi_max_peak <= s->threshold_value : pi_max_peak >= s->threshold_value; + + if (bypass) { + return 1.; + } else if (type) { + return FFMIN(expansion, state + s->raise_amount); + } else { + return FFMIN(expansion, FFMAX(compression, state - s->fall_amount)); + } +} + +static void next_pi(AVFilterContext *ctx, ChannelContext *cc, int bypass) +{ + av_assert0(cc->pi_size >= 0); + if (cc->pi_size == 0) { + SpeechNormalizerContext *s = ctx->priv; + int start = cc->pi_start; + + av_assert0(cc->pi[start].size > 0); + av_assert0(cc->pi[start].type > 0 || s->eof); + cc->pi_size = cc->pi[start].size; + cc->pi_max_peak = cc->pi[start].max_peak; + av_assert0(cc->pi_start != cc->pi_end || s->eof); + start++; + if (start >= MAX_ITEMS) + start = 0; + cc->pi_start = start; + cc->gain_state = next_gain(ctx, cc->pi_max_peak, bypass, cc->gain_state); + } +} + +static double min_gain(AVFilterContext *ctx, ChannelContext *cc, int max_size) +{ + SpeechNormalizerContext *s = ctx->priv; + double min_gain = s->max_expansion; + double gain_state = cc->gain_state; + int size = cc->pi_size; + int idx = cc->pi_start; + + min_gain = FFMIN(min_gain, gain_state); + while (size <= max_size) { + if (idx == cc->pi_end) + break; + gain_state = next_gain(ctx, cc->pi[idx].max_peak, 0, gain_state); + min_gain = FFMIN(min_gain, gain_state); + size += cc->pi[idx].size; + idx++; + if (idx >= MAX_ITEMS) + idx = 0; + } + + return min_gain; +} + +#define ANALYZE_CHANNEL(name, ptype, zero) \ +static void analyze_channel_## name (AVFilterContext *ctx, ChannelContext *cc, \ + const uint8_t *srcp, int nb_samples) \ +{ \ + SpeechNormalizerContext *s = ctx->priv; \ + const ptype *src = (const ptype *)srcp; \ + int n = 0; \ + \ + if (cc->state < 0) \ + cc->state = src[0] >= zero; \ + \ + while (n < nb_samples) { \ + if ((cc->state != (src[n] >= zero)) || \ + (cc->pi[cc->pi_end].size > s->max_period)) { \ + double max_peak = cc->pi[cc->pi_end].max_peak; \ + int state = cc->state; \ + cc->state = src[n] >= zero; \ + av_assert0(cc->pi[cc->pi_end].size > 0); \ + if (cc->pi[cc->pi_end].max_peak >= MIN_PEAK || \ + cc->pi[cc->pi_end].size > s->max_period) { \ + cc->pi[cc->pi_end].type = 1; \ + cc->pi_end++; \ + if (cc->pi_end >= MAX_ITEMS) \ + cc->pi_end = 0; \ + if (cc->state != state) \ + cc->pi[cc->pi_end].max_peak = DBL_MIN; \ + else \ + cc->pi[cc->pi_end].max_peak = max_peak; \ + cc->pi[cc->pi_end].type = 0; \ + cc->pi[cc->pi_end].size = 0; \ + av_assert0(cc->pi_end != cc->pi_start); \ + } \ + } \ + \ + if (cc->state) { \ + while (src[n] >= zero) { \ + cc->pi[cc->pi_end].max_peak = FFMAX(cc->pi[cc->pi_end].max_peak, src[n]); \ + cc->pi[cc->pi_end].size++; \ + n++; \ + if (n >= nb_samples) \ + break; \ + } \ + } else { \ + while (src[n] < zero) { \ + cc->pi[cc->pi_end].max_peak = FFMAX(cc->pi[cc->pi_end].max_peak, -src[n]); \ + cc->pi[cc->pi_end].size++; \ + n++; \ + if (n >= nb_samples) \ + break; \ + } \ + } \ + } \ +} + +ANALYZE_CHANNEL(dbl, double, 0.0) +ANALYZE_CHANNEL(flt, float, 0.f) + +#define FILTER_CHANNELS(name, ptype) \ +static void filter_channels_## name (AVFilterContext *ctx, \ + AVFrame *in, int nb_samples) \ +{ \ + SpeechNormalizerContext *s = ctx->priv; \ + AVFilterLink *inlink = ctx->inputs[0]; \ + \ + for (int ch = 0; ch < inlink->channels; ch++) { \ + ChannelContext *cc = &s->cc[ch]; \ + ptype *dst = (ptype *)in->extended_data[ch]; \ + const int bypass = !(av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels); \ + int n = 0; \ + \ + while (n < nb_samples) { \ + ptype gain; \ + int size; \ + \ + next_pi(ctx, cc, bypass); \ + size = FFMIN(nb_samples - n, cc->pi_size); \ + av_assert0(size > 0); \ + gain = cc->gain_state; \ + consume_pi(cc, size); \ + for (int i = n; i < n + size; i++) \ + dst[i] *= gain; \ + n += size; \ + } \ + } \ +} + +FILTER_CHANNELS(dbl, double) +FILTER_CHANNELS(flt, float) + +static double lerp(double min, double max, double mix) +{ + return min + (max - min) * mix; +} + +#define FILTER_LINK_CHANNELS(name, ptype) \ +static void filter_link_channels_## name (AVFilterContext *ctx, \ + AVFrame *in, int nb_samples) \ +{ \ + SpeechNormalizerContext *s = ctx->priv; \ + AVFilterLink *inlink = ctx->inputs[0]; \ + int n = 0; \ + \ + while (n < nb_samples) { \ + int min_size = nb_samples - n; \ + int max_size = 1; \ + ptype gain = s->max_expansion; \ + \ + for (int ch = 0; ch < inlink->channels; ch++) { \ + ChannelContext *cc = &s->cc[ch]; \ + \ + cc->bypass = !(av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels); \ + \ + next_pi(ctx, cc, cc->bypass); \ + min_size = FFMIN(min_size, cc->pi_size); \ + max_size = FFMAX(max_size, cc->pi_size); \ + } \ + \ + av_assert0(min_size > 0); \ + for (int ch = 0; ch < inlink->channels; ch++) { \ + ChannelContext *cc = &s->cc[ch]; \ + \ + if (cc->bypass) \ + continue; \ + gain = FFMIN(gain, min_gain(ctx, cc, max_size)); \ + } \ + \ + for (int ch = 0; ch < inlink->channels; ch++) { \ + ChannelContext *cc = &s->cc[ch]; \ + ptype *dst = (ptype *)in->extended_data[ch]; \ + \ + consume_pi(cc, min_size); \ + if (cc->bypass) \ + continue; \ + \ + for (int i = n; i < n + min_size; i++) { \ + ptype g = lerp(s->prev_gain, gain, (i - n) / (double)min_size); \ + dst[i] *= g; \ + } \ + } \ + \ + s->prev_gain = gain; \ + n += min_size; \ + } \ +} + +FILTER_LINK_CHANNELS(dbl, double) +FILTER_LINK_CHANNELS(flt, float) + +static int filter_frame(AVFilterContext *ctx) +{ + SpeechNormalizerContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFilterLink *inlink = ctx->inputs[0]; + int ret; + + while (s->queue.available > 0) { + int min_pi_nb_samples; + AVFrame *in; + + in = ff_bufqueue_peek(&s->queue, 0); + if (!in) + break; + + min_pi_nb_samples = available_samples(ctx); + if (min_pi_nb_samples < in->nb_samples && !s->eof) + break; + + in = ff_bufqueue_get(&s->queue); + + av_frame_make_writable(in); + + s->filter_channels[s->link](ctx, in, in->nb_samples); + + s->pts = in->pts + in->nb_samples; + + return ff_filter_frame(outlink, in); + } + + for (int f = 0; f < ff_inlink_queued_frames(inlink); f++) { + AVFrame *in; + + ret = ff_inlink_consume_frame(inlink, &in); + if (ret < 0) + return ret; + if (ret == 0) + break; + + ff_bufqueue_add(ctx, &s->queue, in); + + for (int ch = 0; ch < inlink->channels; ch++) { + ChannelContext *cc = &s->cc[ch]; + + s->analyze_channel(ctx, cc, in->extended_data[ch], in->nb_samples); + } + } + + return 1; +} + +static int activate(AVFilterContext *ctx) +{ + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + SpeechNormalizerContext *s = ctx->priv; + int ret, status; + int64_t pts; + + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); + + ret = filter_frame(ctx); + if (ret <= 0) + return ret; + + if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) { + if (status == AVERROR_EOF) + s->eof = 1; + } + + if (s->eof && ff_inlink_queued_samples(inlink) == 0 && + s->queue.available == 0) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->pts); + return 0; + } + + if (s->queue.available > 0) { + AVFrame *in = ff_bufqueue_peek(&s->queue, 0); + const int nb_samples = available_samples(ctx); + + if (nb_samples >= in->nb_samples || s->eof) { + ff_filter_set_ready(ctx, 10); + return 0; + } + } + + FF_FILTER_FORWARD_WANTED(outlink, inlink); + + return FFERROR_NOT_READY; +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + SpeechNormalizerContext *s = ctx->priv; + + s->max_period = inlink->sample_rate / 10; + + s->prev_gain = 1.; + s->cc = av_calloc(inlink->channels, sizeof(*s->cc)); + if (!s->cc) + return AVERROR(ENOMEM); + + for (int ch = 0; ch < inlink->channels; ch++) { + ChannelContext *cc = &s->cc[ch]; + + cc->state = -1; + cc->gain_state = 1.; + } + + switch (inlink->format) { + case AV_SAMPLE_FMT_FLTP: + s->analyze_channel = analyze_channel_flt; + s->filter_channels[0] = filter_channels_flt; + s->filter_channels[1] = filter_link_channels_flt; + break; + case AV_SAMPLE_FMT_DBLP: + s->analyze_channel = analyze_channel_dbl; + s->filter_channels[0] = filter_channels_dbl; + s->filter_channels[1] = filter_link_channels_dbl; + break; + default: + av_assert0(0); + } + + return 0; +} + +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + SpeechNormalizerContext *s = ctx->priv; + int link = s->link; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + if (link != s->link) + s->prev_gain = 1.; + + return 0; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + SpeechNormalizerContext *s = ctx->priv; + + ff_bufqueue_discard_all(&s->queue); + av_freep(&s->cc); +} + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + }, + { NULL } +}; + +AVFilter ff_af_speechnorm = { + .name = "speechnorm", + .description = NULL_IF_CONFIG_SMALL("Speech Normalizer."), + .query_formats = query_formats, + .priv_size = sizeof(SpeechNormalizerContext), + .priv_class = &speechnorm_class, + .activate = activate, + .uninit = uninit, + .inputs = inputs, + .outputs = outputs, + .process_command = process_command, +}; diff --git a/libavfilter/af_stereotools.c b/libavfilter/af_stereotools.c index 7e529783d..2c636a27a 100644 --- a/libavfilter/af_stereotools.c +++ b/libavfilter/af_stereotools.c @@ -57,7 +57,7 @@ typedef struct StereoToolsContext { } StereoToolsContext; #define OFFSET(x) offsetof(StereoToolsContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption stereotools_options[] = { { "level_in", "set level in", OFFSET(level_in), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, @@ -69,7 +69,7 @@ static const AVOption stereotools_options[] = { { "muter", "mute R", OFFSET(mute_r), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A }, { "phasel", "phase L", OFFSET(phase_l), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A }, { "phaser", "phase R", OFFSET(phase_r), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A }, - { "mode", "set stereo mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 8, A, "mode" }, + { "mode", "set stereo mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 10, A, "mode" }, { "lr>lr", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, A, "mode" }, { "lr>ms", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, A, "mode" }, { "ms>lr", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, A, "mode" }, @@ -79,6 +79,8 @@ static const AVOption stereotools_options[] = { { "lr>rl", 0, 0, AV_OPT_TYPE_CONST, {.i64=6}, 0, 0, A, "mode" }, { "ms>ll", 0, 0, AV_OPT_TYPE_CONST, {.i64=7}, 0, 0, A, "mode" }, { "ms>rr", 0, 0, AV_OPT_TYPE_CONST, {.i64=8}, 0, 0, A, "mode" }, + { "ms>rl", 0, 0, AV_OPT_TYPE_CONST, {.i64=9}, 0, 0, A, "mode" }, + { "lr>l-r", 0, 0, AV_OPT_TYPE_CONST, {.i64=10}, 0, 0, A, "mode" }, { "slev", "set side level", OFFSET(slev), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, { "sbal", "set side balance", OFFSET(sbal), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -1, 1, A }, { "mlev", "set middle level", OFFSET(mlev), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, @@ -118,12 +120,9 @@ static int config_input(AVFilterLink *inlink) AVFilterContext *ctx = inlink->dst; StereoToolsContext *s = ctx->priv; - s->length = 2 * inlink->sample_rate * 0.05; - if (s->length <= 1 || s->length & 1) { - av_log(ctx, AV_LOG_ERROR, "sample rate is too small\n"); - return AVERROR(EINVAL); - } - s->buffer = av_calloc(s->length, sizeof(*s->buffer)); + s->length = FFALIGN(inlink->sample_rate / 10, 2); + if (!s->buffer) + s->buffer = av_calloc(s->length, sizeof(*s->buffer)); if (!s->buffer) return AVERROR(ENOMEM); @@ -235,7 +234,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) L = R; break; case 5: - L = (L + R) / 2; + L = (L + R) * 0.5; R = L; break; case 6: @@ -259,6 +258,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) L = r; R = r; break; + case 9: + l = L * mlev * FFMIN(1., 2. - mpan) + R * slev * FFMIN(1., 2. - sbal); + r = L * mlev * FFMIN(1., mpan) - R * slev * FFMIN(1., sbal); + L = r; + R = l; + break; + case 10: + L = (L - R) * 0.5; + R = L; + break; } L *= 1. - mute_l; @@ -315,8 +324,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) L *= level_out; R *= level_out; - dst[0] = L; - dst[1] = R; + if (ctx->is_disabled) { + dst[0] = src[0]; + dst[1] = src[1]; + } else { + dst[0] = L; + dst[1] = R; + } } if (out != in) @@ -324,6 +338,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_input(ctx->inputs[0]); +} + static av_cold void uninit(AVFilterContext *ctx) { StereoToolsContext *s = ctx->priv; @@ -358,4 +384,6 @@ AVFilter ff_af_stereotools = { .uninit = uninit, .inputs = inputs, .outputs = outputs, + .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, }; diff --git a/libavfilter/af_surround.c b/libavfilter/af_surround.c index 11406786e..d18b3146e 100644 --- a/libavfilter/af_surround.c +++ b/libavfilter/af_surround.c @@ -175,7 +175,7 @@ static int query_formats(AVFilterContext *ctx) if (ret) return ret; - ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts); if (ret) return ret; @@ -184,7 +184,7 @@ static int query_formats(AVFilterContext *ctx) if (ret) return ret; - ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts); + ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts); if (ret) return ret; diff --git a/libavfilter/af_tremolo.c b/libavfilter/af_tremolo.c index f55e8e2b0..6baeb7f11 100644 --- a/libavfilter/af_tremolo.c +++ b/libavfilter/af_tremolo.c @@ -126,7 +126,7 @@ static int config_input(AVFilterLink *inlink) const double offset = 1. - s->depth / 2.; int i; - s->table_size = inlink->sample_rate / s->freq; + s->table_size = lrint(inlink->sample_rate / s->freq + 0.5); s->table = av_malloc_array(s->table_size, sizeof(*s->table)); if (!s->table) return AVERROR(ENOMEM); diff --git a/libavfilter/af_vibrato.c b/libavfilter/af_vibrato.c index 22bbab623..5db1f0f6c 100644 --- a/libavfilter/af_vibrato.c +++ b/libavfilter/af_vibrato.c @@ -162,7 +162,7 @@ static int config_input(AVFilterLink *inlink) s->buf = av_calloc(inlink->channels, sizeof(*s->buf)); if (!s->buf) return AVERROR(ENOMEM); - s->buf_size = inlink->sample_rate * 0.005; + s->buf_size = lrint(inlink->sample_rate * 0.005 + 0.5); for (c = 0; c < s->channels; c++) { s->buf[c] = av_malloc_array(s->buf_size, sizeof(*s->buf[c])); if (!s->buf[c]) @@ -170,7 +170,7 @@ static int config_input(AVFilterLink *inlink) } s->buf_index = 0; - s->wave_table_size = inlink->sample_rate / s->freq; + s->wave_table_size = lrint(inlink->sample_rate / s->freq + 0.5); s->wave_table = av_malloc_array(s->wave_table_size, sizeof(*s->wave_table)); if (!s->wave_table) return AVERROR(ENOMEM); diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c index 213c57195..5fc00d82a 100644 --- a/libavfilter/af_volume.c +++ b/libavfilter/af_volume.c @@ -335,10 +335,6 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar return ret; } -#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *buf) { AVFilterContext *ctx = inlink->dst; diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 1183e4026..0872c6e0f 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -34,15 +34,18 @@ extern AVFilter ff_af_acrusher; extern AVFilter ff_af_adeclick; extern AVFilter ff_af_adeclip; extern AVFilter ff_af_adelay; +extern AVFilter ff_af_adenorm; extern AVFilter ff_af_aderivative; extern AVFilter ff_af_aecho; extern AVFilter ff_af_aemphasis; extern AVFilter ff_af_aeval; +extern AVFilter ff_af_aexciter; extern AVFilter ff_af_afade; extern AVFilter ff_af_afftdn; extern AVFilter ff_af_afftfilt; extern AVFilter ff_af_afir; extern AVFilter ff_af_aformat; +extern AVFilter ff_af_afreqshift; extern AVFilter ff_af_agate; extern AVFilter ff_af_aiir; extern AVFilter ff_af_aintegral; @@ -61,6 +64,7 @@ extern AVFilter ff_af_anull; extern AVFilter ff_af_apad; extern AVFilter ff_af_aperms; extern AVFilter ff_af_aphaser; +extern AVFilter ff_af_aphaseshift; extern AVFilter ff_af_apulsator; extern AVFilter ff_af_arealtime; extern AVFilter ff_af_aresample; @@ -80,6 +84,10 @@ extern AVFilter ff_af_asr; extern AVFilter ff_af_astats; extern AVFilter ff_af_astreamselect; extern AVFilter ff_af_asubboost; +extern AVFilter ff_af_asubcut; +extern AVFilter ff_af_asupercut; +extern AVFilter ff_af_asuperpass; +extern AVFilter ff_af_asuperstop; extern AVFilter ff_af_atempo; extern AVFilter ff_af_atrim; extern AVFilter ff_af_axcorrelate; @@ -128,6 +136,7 @@ extern AVFilter ff_af_sidechaingate; extern AVFilter ff_af_silencedetect; extern AVFilter ff_af_silenceremove; extern AVFilter ff_af_sofalizer; +extern AVFilter ff_af_speechnorm; extern AVFilter ff_af_stereotools; extern AVFilter ff_af_stereowiden; extern AVFilter ff_af_superequalizer; @@ -172,17 +181,22 @@ extern AVFilter ff_vf_bwdif; extern AVFilter ff_vf_cas; extern AVFilter ff_vf_chromahold; extern AVFilter ff_vf_chromakey; +extern AVFilter ff_vf_chromanr; extern AVFilter ff_vf_chromashift; extern AVFilter ff_vf_ciescope; extern AVFilter ff_vf_codecview; extern AVFilter ff_vf_colorbalance; extern AVFilter ff_vf_colorchannelmixer; +extern AVFilter ff_vf_colorcontrast; +extern AVFilter ff_vf_colorcorrect; +extern AVFilter ff_vf_colorize; extern AVFilter ff_vf_colorkey; extern AVFilter ff_vf_colorkey_opencl; extern AVFilter ff_vf_colorhold; extern AVFilter ff_vf_colorlevels; extern AVFilter ff_vf_colormatrix; extern AVFilter ff_vf_colorspace; +extern AVFilter ff_vf_colortemperature; extern AVFilter ff_vf_convolution; extern AVFilter ff_vf_convolution_opencl; extern AVFilter ff_vf_convolve; @@ -225,9 +239,12 @@ extern AVFilter ff_vf_drawtext; extern AVFilter ff_vf_edgedetect; extern AVFilter ff_vf_elbg; extern AVFilter ff_vf_entropy; +extern AVFilter ff_vf_epx; extern AVFilter ff_vf_eq; extern AVFilter ff_vf_erosion; extern AVFilter ff_vf_erosion_opencl; +extern AVFilter ff_vf_estdif; +extern AVFilter ff_vf_exposure; extern AVFilter ff_vf_extractplanes; extern AVFilter ff_vf_fade; extern AVFilter ff_vf_fftdnoiz; @@ -266,12 +283,14 @@ extern AVFilter ff_vf_hwmap; extern AVFilter ff_vf_hwupload; extern AVFilter ff_vf_hwupload_cuda; extern AVFilter ff_vf_hysteresis; +extern AVFilter ff_vf_identity; extern AVFilter ff_vf_idet; extern AVFilter ff_vf_il; extern AVFilter ff_vf_inflate; extern AVFilter ff_vf_interlace; extern AVFilter ff_vf_interleave; extern AVFilter ff_vf_kerndeint; +extern AVFilter ff_vf_kirsch; extern AVFilter ff_vf_lagfun; extern AVFilter ff_vf_lenscorrection; extern AVFilter ff_vf_lensfun; @@ -299,7 +318,9 @@ extern AVFilter ff_vf_metadata; extern AVFilter ff_vf_midequalizer; extern AVFilter ff_vf_minterpolate; extern AVFilter ff_vf_mix; +extern AVFilter ff_vf_monochrome; extern AVFilter ff_vf_mpdecimate; +extern AVFilter ff_vf_msad; extern AVFilter ff_vf_negate; extern AVFilter ff_vf_nlmeans; extern AVFilter ff_vf_nlmeans_opencl; @@ -373,9 +394,11 @@ extern AVFilter ff_vf_setrange; extern AVFilter ff_vf_setsar; extern AVFilter ff_vf_settb; extern AVFilter ff_vf_sharpness_vaapi; +extern AVFilter ff_vf_shear; extern AVFilter ff_vf_showinfo; extern AVFilter ff_vf_showpalette; extern AVFilter ff_vf_shuffleframes; +extern AVFilter ff_vf_shufflepixels; extern AVFilter ff_vf_shuffleplanes; extern AVFilter ff_vf_sidedata; extern AVFilter ff_vf_signalstats; @@ -403,6 +426,7 @@ extern AVFilter ff_vf_tile; extern AVFilter ff_vf_tinterlace; extern AVFilter ff_vf_tlut2; extern AVFilter ff_vf_tmedian; +extern AVFilter ff_vf_tmidequalizer; extern AVFilter ff_vf_tmix; extern AVFilter ff_vf_tonemap; extern AVFilter ff_vf_tonemap_opencl; @@ -426,6 +450,7 @@ extern AVFilter ff_vf_vfrdet; extern AVFilter ff_vf_vibrance; extern AVFilter ff_vf_vidstabdetect; extern AVFilter ff_vf_vidstabtransform; +extern AVFilter ff_vf_vif; extern AVFilter ff_vf_vignette; extern AVFilter ff_vf_vmafmotion; extern AVFilter ff_vf_vpp_qsv; @@ -527,7 +552,7 @@ const AVFilter *avfilter_get_by_name(const char *name) while ((f = av_filter_iterate(&opaque))) if (!strcmp(f->name, name)) - return (AVFilter *)f; + return f; return NULL; } diff --git a/libavfilter/asrc_afirsrc.c b/libavfilter/asrc_afirsrc.c index b90ffad57..d8ba8f6a5 100644 --- a/libavfilter/asrc_afirsrc.c +++ b/libavfilter/asrc_afirsrc.c @@ -145,7 +145,7 @@ static av_cold int query_formats(AVFilterContext *ctx) if (ret < 0) return ret; - layouts = avfilter_make_format64_list(chlayouts); + layouts = ff_make_format64_list(chlayouts); if (!layouts) return AVERROR(ENOMEM); ret = ff_set_common_channel_layouts(ctx, layouts); diff --git a/libavfilter/asrc_anoisesrc.c b/libavfilter/asrc_anoisesrc.c index 7aa878707..40ee07700 100644 --- a/libavfilter/asrc_anoisesrc.c +++ b/libavfilter/asrc_anoisesrc.c @@ -101,7 +101,7 @@ static av_cold int query_formats(AVFilterContext *ctx) if (ret < 0) return ret; - layouts = avfilter_make_format64_list(chlayouts); + layouts = ff_make_format64_list(chlayouts); if (!layouts) return AVERROR(ENOMEM); ret = ff_set_common_channel_layouts(ctx, layouts); diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c index 52db61685..f2c0799fa 100644 --- a/libavfilter/asrc_anullsrc.c +++ b/libavfilter/asrc_anullsrc.c @@ -32,6 +32,7 @@ #include "libavutil/opt.h" #include "audio.h" #include "avfilter.h" +#include "filters.h" #include "internal.h" typedef struct ANullContext { @@ -40,6 +41,7 @@ typedef struct ANullContext { uint64_t channel_layout; char *sample_rate_str; int sample_rate; + int64_t duration; int nb_samples; ///< number of samples per requested frame int64_t pts; } ANullContext; @@ -52,8 +54,10 @@ static const AVOption anullsrc_options[]= { { "cl", "set channel_layout", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, FLAGS }, { "sample_rate", "set sample rate", OFFSET(sample_rate_str) , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0, FLAGS }, { "r", "set sample rate", OFFSET(sample_rate_str) , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0, FLAGS }, - { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS }, - { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS }, + { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, UINT16_MAX, FLAGS }, + { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, UINT16_MAX, FLAGS }, + { "duration", "set the audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS }, + { "d", "set the audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS }, { NULL } }; @@ -83,44 +87,45 @@ static int query_formats(AVFilterContext *ctx) int ret; if ((ret = ff_set_common_formats (ctx, ff_all_formats (AVMEDIA_TYPE_AUDIO))) < 0 || - (ret = ff_set_common_channel_layouts (ctx, avfilter_make_format64_list (chlayouts ))) < 0 || (ret = ff_set_common_samplerates (ctx, ff_make_format_list (sample_rates ))) < 0) return ret; - return 0; + return ff_set_common_channel_layouts(ctx, ff_make_format64_list(chlayouts)); } -static int config_props(AVFilterLink *outlink) +static av_cold int config_props(AVFilterLink *outlink) { ANullContext *null = outlink->src->priv; - char buf[128]; - av_get_channel_layout_string(buf, sizeof(buf), 0, null->channel_layout); - av_log(outlink->src, AV_LOG_VERBOSE, - "sample_rate:%d channel_layout:'%s' nb_samples:%d\n", - null->sample_rate, buf, null->nb_samples); + if (null->duration >= 0) + null->duration = av_rescale(null->duration, null->sample_rate, AV_TIME_BASE); return 0; } -static int request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - int ret; - ANullContext *null = outlink->src->priv; - AVFrame *samplesref; + ANullContext *null = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; - samplesref = ff_get_audio_buffer(outlink, null->nb_samples); - if (!samplesref) - return AVERROR(ENOMEM); + if (null->duration >= 0 && null->pts >= null->duration) { + ff_outlink_set_status(outlink, AVERROR_EOF, null->pts); + return 0; + } - samplesref->pts = null->pts; + if (ff_outlink_frame_wanted(outlink)) { + AVFrame *samplesref = ff_get_audio_buffer(outlink, null->duration >= 0 ? FFMIN(null->nb_samples, null->duration - null->pts) : null->nb_samples); - ret = ff_filter_frame(outlink, samplesref); - if (ret < 0) - return ret; + if (!samplesref) + return AVERROR(ENOMEM); - null->pts += null->nb_samples; - return ret; + samplesref->pts = null->pts; + null->pts += samplesref->nb_samples; + + return ff_filter_frame(outlink, samplesref); + } + + return FFERROR_NOT_READY; } static const AVFilterPad avfilter_asrc_anullsrc_outputs[] = { @@ -128,7 +133,6 @@ static const AVFilterPad avfilter_asrc_anullsrc_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = config_props, - .request_frame = request_frame, }, { NULL } }; @@ -141,5 +145,6 @@ AVFilter ff_asrc_anullsrc = { .priv_size = sizeof(ANullContext), .inputs = NULL, .outputs = avfilter_asrc_anullsrc_outputs, + .activate = activate, .priv_class = &anullsrc_class, }; diff --git a/libavfilter/asrc_hilbert.c b/libavfilter/asrc_hilbert.c index a51c676c6..640dfe46f 100644 --- a/libavfilter/asrc_hilbert.c +++ b/libavfilter/asrc_hilbert.c @@ -113,7 +113,7 @@ static av_cold int query_formats(AVFilterContext *ctx) if (ret < 0) return ret; - layouts = avfilter_make_format64_list(chlayouts); + layouts = ff_make_format64_list(chlayouts); if (!layouts) return AVERROR(ENOMEM); ret = ff_set_common_channel_layouts(ctx, layouts); diff --git a/libavfilter/asrc_sinc.c b/libavfilter/asrc_sinc.c index 24aeab6e7..c3ecb864d 100644 --- a/libavfilter/asrc_sinc.c +++ b/libavfilter/asrc_sinc.c @@ -84,7 +84,7 @@ static int query_formats(AVFilterContext *ctx) if (ret < 0) return ret; - layouts = avfilter_make_format64_list(chlayouts); + layouts = ff_make_format64_list(chlayouts); if (!layouts) return AVERROR(ENOMEM); ret = ff_set_common_channel_layouts(ctx, layouts); diff --git a/libavfilter/asrc_sine.c b/libavfilter/asrc_sine.c index 3a87210b4..3b7d2e6d0 100644 --- a/libavfilter/asrc_sine.c +++ b/libavfilter/asrc_sine.c @@ -194,7 +194,7 @@ static av_cold int query_formats(AVFilterContext *ctx) if (ret < 0) return ret; - layouts = avfilter_make_format64_list(chlayouts); + layouts = ff_make_format64_list(chlayouts); if (!layouts) return AVERROR(ENOMEM); ret = ff_set_common_channel_layouts(ctx, layouts); @@ -247,7 +247,7 @@ static int request_frame(AVFilterLink *outlink) samples[i] = sine->sin[sine->phi >> (32 - LOG_PERIOD)]; sine->phi += sine->dphi; if (sine->beep_index < sine->beep_length) { - samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] << 1; + samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] * 2; sine->phi_beep += sine->dphi_beep; } if (++sine->beep_index == sine->beep_period) diff --git a/libavfilter/atadenoise.h b/libavfilter/atadenoise.h index 26cb20b9c..7d92ece0d 100644 --- a/libavfilter/atadenoise.h +++ b/libavfilter/atadenoise.h @@ -31,12 +31,12 @@ enum ATAAlgorithm { }; typedef struct ATADenoiseDSPContext { - void (*filter_row)(const uint8_t *src, uint8_t *dst, - const uint8_t **srcf, - int w, int mid, int size, - int thra, int thrb); + void (*filter_row[4])(const uint8_t *src, uint8_t *dst, + const uint8_t **srcf, + int w, int mid, int size, + int thra, int thrb, const float *weight); } ATADenoiseDSPContext; -void ff_atadenoise_init_x86(ATADenoiseDSPContext *dsp, int depth, int algorithm); +void ff_atadenoise_init_x86(ATADenoiseDSPContext *dsp, int depth, int algorithm, const float *sigma); #endif /* AVFILTER_ATADENOISE_H */ diff --git a/libavfilter/audio.h b/libavfilter/audio.h index 6adc82dc8..6bbe6ee9e 100644 --- a/libavfilter/audio.h +++ b/libavfilter/audio.h @@ -25,24 +25,6 @@ #include "avfilter.h" #include "internal.h" -static const enum AVSampleFormat ff_packed_sample_fmts_array[] = { - AV_SAMPLE_FMT_U8, - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_S32, - AV_SAMPLE_FMT_FLT, - AV_SAMPLE_FMT_DBL, - AV_SAMPLE_FMT_NONE -}; - -static const enum AVSampleFormat ff_planar_sample_fmts_array[] = { - AV_SAMPLE_FMT_U8P, - AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_S32P, - AV_SAMPLE_FMT_FLTP, - AV_SAMPLE_FMT_DBLP, - AV_SAMPLE_FMT_NONE -}; - /** default handler for get_audio_buffer() for audio inputs */ AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples); diff --git a/libavfilter/avf_abitscope.c b/libavfilter/avf_abitscope.c index 759f821e7..501194388 100644 --- a/libavfilter/avf_abitscope.c +++ b/libavfilter/avf_abitscope.c @@ -69,21 +69,21 @@ static int query_formats(AVFilterContext *ctx) int ret; formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0) return ret; layouts = ff_all_channel_counts(); if (!layouts) return AVERROR(ENOMEM); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0) return ret; formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/avf_ahistogram.c b/libavfilter/avf_ahistogram.c index 92cda4675..b37b4a66a 100644 --- a/libavfilter/avf_ahistogram.c +++ b/libavfilter/avf_ahistogram.c @@ -99,17 +99,17 @@ static int query_formats(AVFilterContext *ctx) int ret = AVERROR(EINVAL); formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref (formats, &inlink->out_formats )) < 0 || + if ((ret = ff_formats_ref (formats, &inlink->outcfg.formats )) < 0 || (layouts = ff_all_channel_counts()) == NULL || - (ret = ff_channel_layouts_ref (layouts, &inlink->out_channel_layouts)) < 0) + (ret = ff_channel_layouts_ref (layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0) return ret; formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/avf_aphasemeter.c b/libavfilter/avf_aphasemeter.c index be0b2fb70..61da9a90b 100644 --- a/libavfilter/avf_aphasemeter.c +++ b/libavfilter/avf_aphasemeter.c @@ -28,26 +28,43 @@ #include "libavutil/intreadwrite.h" #include "libavutil/opt.h" #include "libavutil/parseutils.h" +#include "libavutil/timestamp.h" #include "avfilter.h" #include "formats.h" #include "audio.h" #include "video.h" #include "internal.h" +#include "float.h" typedef struct AudioPhaseMeterContext { const AVClass *class; AVFrame *out; int do_video; + int do_phasing_detection; int w, h; AVRational frame_rate; int contrast[4]; uint8_t *mpc_str; uint8_t mpc[4]; int draw_median_phase; + int is_mono; + int is_out_phase; + int start_mono_presence; + int start_out_phase_presence; + float tolerance; + float angle; + float phase; + AVRational time_base; + int64_t duration; + int64_t frame_end; + int64_t mono_idx[2]; + int64_t out_phase_idx[2]; } AudioPhaseMeterContext; +#define MAX_DURATION (24*60*60*1000000LL) #define OFFSET(x) offsetof(AudioPhaseMeterContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define get_duration(index) (index[1] - index[0]) static const AVOption aphasemeter_options[] = { { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, INT_MAX, FLAGS }, @@ -59,6 +76,13 @@ static const AVOption aphasemeter_options[] = { { "bc", "set blue contrast", OFFSET(contrast[2]), AV_OPT_TYPE_INT, {.i64=1}, 0, 255, FLAGS }, { "mpc", "set median phase color", OFFSET(mpc_str), AV_OPT_TYPE_STRING, {.str = "none"}, 0, 0, FLAGS }, { "video", "set video output", OFFSET(do_video), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS }, + { "phasing", "set mono and out-of-phase detection output", OFFSET(do_phasing_detection), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS }, + { "tolerance", "set phase tolerance for mono detection", OFFSET(tolerance), AV_OPT_TYPE_FLOAT, {.dbl = 0.}, 0, 1, FLAGS }, + { "t", "set phase tolerance for mono detection", OFFSET(tolerance), AV_OPT_TYPE_FLOAT, {.dbl = 0.}, 0, 1, FLAGS }, + { "angle", "set angle threshold for out-of-phase detection", OFFSET(angle), AV_OPT_TYPE_FLOAT, {.dbl = 170.}, 90, 180, FLAGS }, + { "a", "set angle threshold for out-of-phase detection", OFFSET(angle), AV_OPT_TYPE_FLOAT, {.dbl = 170.}, 90, 180, FLAGS }, + { "duration", "set minimum mono or out-of-phase duration in seconds", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=2000000}, 0, MAX_DURATION, FLAGS }, + { "d", "set minimum mono or out-of-phase duration in seconds", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=2000000}, 0, MAX_DURATION, FLAGS }, { NULL } }; @@ -76,23 +100,23 @@ static int query_formats(AVFilterContext *ctx) int ret; formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref (formats, &inlink->out_formats )) < 0 || - (ret = ff_formats_ref (formats, &outlink->in_formats )) < 0 || + if ((ret = ff_formats_ref (formats, &inlink->outcfg.formats )) < 0 || + (ret = ff_formats_ref (formats, &outlink->incfg.formats )) < 0 || (ret = ff_add_channel_layout (&layout, AV_CH_LAYOUT_STEREO )) < 0 || - (ret = ff_channel_layouts_ref (layout , &inlink->out_channel_layouts)) < 0 || - (ret = ff_channel_layouts_ref (layout , &outlink->in_channel_layouts)) < 0) + (ret = ff_channel_layouts_ref (layout , &inlink->outcfg.channel_layouts)) < 0 || + (ret = ff_channel_layouts_ref (layout , &outlink->incfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0 || - (ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0 || + (ret = ff_formats_ref(formats, &outlink->incfg.samplerates)) < 0) return ret; if (s->do_video) { AVFilterLink *outlink = ctx->outputs[1]; formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; } @@ -104,6 +128,7 @@ static int config_input(AVFilterLink *inlink) AVFilterContext *ctx = inlink->dst; AudioPhaseMeterContext *s = ctx->priv; int nb_samples; + s->duration = av_rescale(s->duration, inlink->sample_rate, AV_TIME_BASE); if (s->do_video) { nb_samples = FFMAX(1, av_rescale(inlink->sample_rate, s->frame_rate.den, s->frame_rate.num)); @@ -140,6 +165,76 @@ static inline int get_x(float phase, int w) return (phase + 1.) / 2. * (w - 1); } +static inline void add_metadata(AVFrame *insamples, const char *key, char *value) +{ + char buf[128]; + + snprintf(buf, sizeof(buf), "lavfi.aphasemeter.%s", key); + av_dict_set(&insamples->metadata, buf, value, 0); +} + +static inline void update_mono_detection(AudioPhaseMeterContext *s, AVFrame *insamples, int mono_measurement) +{ + int64_t mono_duration; + if (!s->is_mono && mono_measurement) { + s->is_mono = 1; + s->start_mono_presence = 1; + s->mono_idx[0] = insamples->pts; + } + if (s->is_mono && mono_measurement && s->start_mono_presence) { + s->mono_idx[1] = s->frame_end; + mono_duration = get_duration(s->mono_idx); + if (mono_duration >= s->duration) { + add_metadata(insamples, "mono_start", av_ts2timestr(s->mono_idx[0], &s->time_base)); + av_log(s, AV_LOG_INFO, "mono_start: %s\n", av_ts2timestr(s->mono_idx[0], &s->time_base)); + s->start_mono_presence = 0; + } + } + if (s->is_mono && !mono_measurement) { + s->mono_idx[1] = insamples ? insamples->pts : s->frame_end; + mono_duration = get_duration(s->mono_idx); + if (mono_duration >= s->duration) { + if (insamples) { + add_metadata(insamples, "mono_end", av_ts2timestr(s->mono_idx[1], &s->time_base)); + add_metadata(insamples, "mono_duration", av_ts2timestr(mono_duration, &s->time_base)); + } + av_log(s, AV_LOG_INFO, "mono_end: %s | mono_duration: %s\n", av_ts2timestr(s->mono_idx[1], &s->time_base), av_ts2timestr(mono_duration, &s->time_base)); + } + s->is_mono = 0; + } +} + +static inline void update_out_phase_detection(AudioPhaseMeterContext *s, AVFrame *insamples, int out_phase_measurement) +{ + int64_t out_phase_duration; + if (!s->is_out_phase && out_phase_measurement) { + s->is_out_phase = 1; + s->start_out_phase_presence = 1; + s->out_phase_idx[0] = insamples->pts; + } + if (s->is_out_phase && out_phase_measurement && s->start_out_phase_presence) { + s->out_phase_idx[1] = s->frame_end; + out_phase_duration = get_duration(s->out_phase_idx); + if (out_phase_duration >= s->duration) { + add_metadata(insamples, "out_phase_start", av_ts2timestr(s->out_phase_idx[0], &s->time_base)); + av_log(s, AV_LOG_INFO, "out_phase_start: %s\n", av_ts2timestr(s->out_phase_idx[0], &s->time_base)); + s->start_out_phase_presence = 0; + } + } + if (s->is_out_phase && !out_phase_measurement) { + s->out_phase_idx[1] = insamples ? insamples->pts : s->frame_end; + out_phase_duration = get_duration(s->out_phase_idx); + if (out_phase_duration >= s->duration) { + if (insamples) { + add_metadata(insamples, "out_phase_end", av_ts2timestr(s->out_phase_idx[1], &s->time_base)); + add_metadata(insamples, "out_phase_duration", av_ts2timestr(out_phase_duration, &s->time_base)); + } + av_log(s, AV_LOG_INFO, "out_phase_end: %s | out_phase_duration: %s\n", av_ts2timestr(s->out_phase_idx[1], &s->time_base), av_ts2timestr(out_phase_duration, &s->time_base)); + } + s->is_out_phase = 0; + } +} + static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; @@ -154,6 +249,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFrame *out; uint8_t *dst; int i; + int mono_measurement; + int out_phase_measurement; + float tolerance = 1.0f - s->tolerance; + float angle = cosf(s->angle/180.0f*M_PI); if (s->do_video && (!s->out || s->out->width != outlink->w || s->out->height != outlink->h)) { @@ -193,6 +292,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) fphase += phase; } fphase /= in->nb_samples; + s->phase = fphase; if (s->do_video) { if (s->draw_median_phase) { @@ -209,7 +309,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) uint8_t value[128]; snprintf(value, sizeof(value), "%f", fphase); - av_dict_set(metadata, "lavfi.aphasemeter.phase", value, 0); + add_metadata(in, "phase", value); + } + + if (s->do_phasing_detection) { + s->time_base = inlink->time_base; + s->frame_end = in->pts + av_rescale_q(in->nb_samples, + (AVRational){ 1, in->sample_rate }, inlink->time_base); + + mono_measurement = (tolerance - fphase) < FLT_EPSILON; + out_phase_measurement = (angle - fphase) > FLT_EPSILON; + + update_mono_detection(s, in, mono_measurement); + update_out_phase_detection(s, in, out_phase_measurement); } if (s->do_video) { @@ -227,11 +339,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) static av_cold void uninit(AVFilterContext *ctx) { AudioPhaseMeterContext *s = ctx->priv; - int i; + if (s->do_phasing_detection) { + update_mono_detection(s, NULL, 0); + update_out_phase_detection(s, NULL, 0); + } av_frame_free(&s->out); - for (i = 0; i < ctx->nb_outputs; i++) - av_freep(&ctx->output_pads[i].name); } static av_cold int init(AVFilterContext *ctx) @@ -241,30 +354,22 @@ static av_cold int init(AVFilterContext *ctx) int ret; pad = (AVFilterPad){ - .name = av_strdup("out0"), + .name = "out0", .type = AVMEDIA_TYPE_AUDIO, }; - if (!pad.name) - return AVERROR(ENOMEM); ret = ff_insert_outpad(ctx, 0, &pad); - if (ret < 0) { - av_freep(&pad.name); + if (ret < 0) return ret; - } if (s->do_video) { pad = (AVFilterPad){ - .name = av_strdup("out1"), + .name = "out1", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_video_output, }; - if (!pad.name) - return AVERROR(ENOMEM); ret = ff_insert_outpad(ctx, 1, &pad); - if (ret < 0) { - av_freep(&pad.name); + if (ret < 0) return ret; - } } return 0; diff --git a/libavfilter/avf_avectorscope.c b/libavfilter/avf_avectorscope.c index b288ff63f..c44353c7f 100644 --- a/libavfilter/avf_avectorscope.c +++ b/libavfilter/avf_avectorscope.c @@ -190,17 +190,17 @@ static int query_formats(AVFilterContext *ctx) int ret; formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref (formats, &inlink->out_formats )) < 0 || + if ((ret = ff_formats_ref (formats, &inlink->outcfg.formats )) < 0 || (ret = ff_add_channel_layout (&layout, AV_CH_LAYOUT_STEREO )) < 0 || - (ret = ff_channel_layouts_ref (layout , &inlink->out_channel_layouts)) < 0) + (ret = ff_channel_layouts_ref (layout , &inlink->outcfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0) return ret; formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c index 28bd5407a..df6414704 100644 --- a/libavfilter/avf_concat.c +++ b/libavfilter/avf_concat.c @@ -87,25 +87,25 @@ static int query_formats(AVFilterContext *ctx) /* Set the output formats */ formats = ff_all_formats(type); - if ((ret = ff_formats_ref(formats, &ctx->outputs[idx]->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &ctx->outputs[idx]->incfg.formats)) < 0) return ret; if (type == AVMEDIA_TYPE_AUDIO) { rates = ff_all_samplerates(); - if ((ret = ff_formats_ref(rates, &ctx->outputs[idx]->in_samplerates)) < 0) + if ((ret = ff_formats_ref(rates, &ctx->outputs[idx]->incfg.samplerates)) < 0) return ret; layouts = ff_all_channel_layouts(); - if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[idx]->in_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[idx]->incfg.channel_layouts)) < 0) return ret; } /* Set the same formats for each corresponding input */ for (seg = 0; seg < cat->nb_segments; seg++) { - if ((ret = ff_formats_ref(formats, &ctx->inputs[idx]->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &ctx->inputs[idx]->outcfg.formats)) < 0) return ret; if (type == AVMEDIA_TYPE_AUDIO) { - if ((ret = ff_formats_ref(rates, &ctx->inputs[idx]->out_samplerates)) < 0 || - (ret = ff_channel_layouts_ref(layouts, &ctx->inputs[idx]->out_channel_layouts)) < 0) + if ((ret = ff_formats_ref(rates, &ctx->inputs[idx]->outcfg.samplerates)) < 0 || + (ret = ff_channel_layouts_ref(layouts, &ctx->inputs[idx]->outcfg.channel_layouts)) < 0) return ret; } idx += ctx->nb_outputs; @@ -251,6 +251,10 @@ static int send_silence(AVFilterContext *ctx, unsigned in_no, unsigned out_no, if (!rate_tb.den) return AVERROR_BUG; + if (cat->in[in_no].pts < INT64_MIN + seg_delta) + return AVERROR_INVALIDDATA; + if (seg_delta < cat->in[in_no].pts) + return AVERROR_INVALIDDATA; nb_samples = av_rescale_q(seg_delta - cat->in[in_no].pts, outlink->time_base, rate_tb); frame_nb_samples = FFMAX(9600, rate_tb.den / 5); /* arbitrary */ diff --git a/libavfilter/avf_showcqt.c b/libavfilter/avf_showcqt.c index cb0dca505..dba1f089e 100644 --- a/libavfilter/avf_showcqt.c +++ b/libavfilter/avf_showcqt.c @@ -1133,11 +1133,11 @@ static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout) int64_t last_time, cur_time; #define UPDATE_TIME(t) \ - cur_time = av_gettime(); \ + cur_time = av_gettime_relative(); \ t += cur_time - last_time; \ last_time = cur_time - last_time = av_gettime(); + last_time = av_gettime_relative(); memcpy(s->fft_result, s->fft_data, s->fft_len * sizeof(*s->fft_data)); if (s->attack_data) { @@ -1321,30 +1321,30 @@ static int query_formats(AVFilterContext *ctx) AVFilterChannelLayouts *layouts = NULL; AVFilterLink *inlink = ctx->inputs[0]; AVFilterLink *outlink = ctx->outputs[0]; - enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }; - enum AVPixelFormat pix_fmts[] = { + static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }; + static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE }; - int64_t channel_layouts[] = { AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO_DOWNMIX, -1 }; + static const int64_t channel_layouts[] = { AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO_DOWNMIX, -1 }; int ret; /* set input audio formats */ formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0) return ret; - layouts = avfilter_make_format64_list(channel_layouts); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0) + layouts = ff_make_format64_list(channel_layouts); + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0) return ret; /* set output video format */ formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/avf_showfreqs.c b/libavfilter/avf_showfreqs.c index 645754ded..6f286c03b 100644 --- a/libavfilter/avf_showfreqs.c +++ b/libavfilter/avf_showfreqs.c @@ -36,6 +36,7 @@ #include "internal.h" #include "window_func.h" +enum DataMode { MAGNITUDE, PHASE, DELAY, NB_DATA }; enum DisplayMode { LINE, BAR, DOT, NB_MODES }; enum ChannelMode { COMBINED, SEPARATE, NB_CMODES }; enum FrequencyScale { FS_LINEAR, FS_LOG, FS_RLOG, NB_FSCALES }; @@ -45,6 +46,7 @@ typedef struct ShowFreqsContext { const AVClass *class; int w, h; int mode; + int data_mode; int cmode; int fft_size; int fft_bits; @@ -115,6 +117,10 @@ static const AVOption showfreqs_options[] = { { "combined", "show all channels in same window", 0, AV_OPT_TYPE_CONST, {.i64=COMBINED}, 0, 0, FLAGS, "cmode" }, { "separate", "show each channel in own window", 0, AV_OPT_TYPE_CONST, {.i64=SEPARATE}, 0, 0, FLAGS, "cmode" }, { "minamp", "set minimum amplitude", OFFSET(minamp), AV_OPT_TYPE_FLOAT, {.dbl=1e-6}, FLT_MIN, 1e-6, FLAGS }, + { "data", "set data mode", OFFSET(data_mode), AV_OPT_TYPE_INT, {.i64=MAGNITUDE}, 0, NB_DATA-1, FLAGS, "data" }, + { "magnitude", "show magnitude", 0, AV_OPT_TYPE_CONST, {.i64=MAGNITUDE}, 0, 0, FLAGS, "data" }, + { "phase", "show phase", 0, AV_OPT_TYPE_CONST, {.i64=PHASE}, 0, 0, FLAGS, "data" }, + { "delay", "show group delay",0, AV_OPT_TYPE_CONST, {.i64=DELAY}, 0, 0, FLAGS, "data" }, { NULL } }; @@ -132,20 +138,20 @@ static int query_formats(AVFilterContext *ctx) /* set input audio formats */ formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0) return ret; layouts = ff_all_channel_layouts(); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0) return ret; /* set output video format */ formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; return 0; @@ -397,6 +403,7 @@ static int plot_freqs(AVFilterLink *inlink, AVFrame *in) #define RE(x, ch) s->fft_data[ch][x].re #define IM(x, ch) s->fft_data[ch][x].im #define M(a, b) (sqrt((a) * (a) + (b) * (b))) +#define P(a, b) (atan2((b), (a))) colors = av_strdup(s->colors); if (!colors) { @@ -413,13 +420,37 @@ static int plot_freqs(AVFilterLink *inlink, AVFrame *in) if (color) av_parse_color(fg, color, -1, ctx); - a = av_clipd(M(RE(0, ch), 0) / s->scale, 0, 1); - plot_freq(s, ch, a, 0, fg, &prev_y, out, outlink); + switch (s->data_mode) { + case MAGNITUDE: + a = av_clipd(M(RE(0, ch), 0) / s->scale, 0, 1); + plot_freq(s, ch, a, 0, fg, &prev_y, out, outlink); - for (f = 1; f < s->nb_freq; f++) { - a = av_clipd(M(RE(f, ch), IM(f, ch)) / s->scale, 0, 1); + for (f = 1; f < s->nb_freq; f++) { + a = av_clipd(M(RE(f, ch), IM(f, ch)) / s->scale, 0, 1); - plot_freq(s, ch, a, f, fg, &prev_y, out, outlink); + plot_freq(s, ch, a, f, fg, &prev_y, out, outlink); + } + break; + case PHASE: + a = av_clipd((M_PI + P(RE(0, ch), 0)) / (2. * M_PI), 0, 1); + plot_freq(s, ch, a, 0, fg, &prev_y, out, outlink); + + for (f = 1; f < s->nb_freq; f++) { + a = av_clipd((M_PI + P(RE(f, ch), IM(f, ch))) / (2. * M_PI), 0, 1); + + plot_freq(s, ch, a, f, fg, &prev_y, out, outlink); + } + break; + case DELAY: + plot_freq(s, ch, 0, 0, fg, &prev_y, out, outlink); + + for (f = 1; f < s->nb_freq; f++) { + a = av_clipd((M_PI - P(IM(f, ch) * RE(f-1, ch) - IM(f-1, ch) * RE(f, ch), + RE(f, ch) * RE(f-1, ch) + IM(f, ch) * IM(f-1, ch))) / (2. * M_PI), 0, 1); + + plot_freq(s, ch, a, f, fg, &prev_y, out, outlink); + } + break; } } diff --git a/libavfilter/avf_showspatial.c b/libavfilter/avf_showspatial.c index 80109a305..a2c8ac24b 100644 --- a/libavfilter/avf_showspatial.c +++ b/libavfilter/avf_showspatial.c @@ -114,17 +114,17 @@ static int query_formats(AVFilterContext *ctx) int ret; formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref (formats, &inlink->out_formats )) < 0 || + if ((ret = ff_formats_ref (formats, &inlink->outcfg.formats )) < 0 || (ret = ff_add_channel_layout (&layout, AV_CH_LAYOUT_STEREO )) < 0 || - (ret = ff_channel_layouts_ref (layout , &inlink->out_channel_layouts)) < 0) + (ret = ff_channel_layouts_ref (layout , &inlink->outcfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0) return ret; formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c index e99f377fb..c690665ba 100644 --- a/libavfilter/avf_showspectrum.c +++ b/libavfilter/avf_showspectrum.c @@ -355,20 +355,20 @@ static int query_formats(AVFilterContext *ctx) /* set input audio formats */ formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0) return ret; layouts = ff_all_channel_layouts(); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0) return ret; /* set output video format */ formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/avf_showvolume.c b/libavfilter/avf_showvolume.c index 7ab2fcfc4..466283a3e 100644 --- a/libavfilter/avf_showvolume.c +++ b/libavfilter/avf_showvolume.c @@ -125,19 +125,19 @@ static int query_formats(AVFilterContext *ctx) int ret; formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0) return ret; layouts = ff_all_channel_counts(); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0) return ret; formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c index afe05fb50..aabd79e23 100644 --- a/libavfilter/avf_showwaves.c +++ b/libavfilter/avf_showwaves.c @@ -57,6 +57,12 @@ enum ShowWavesDrawMode { DRAW_NB, }; +enum ShowWavesFilterMode { + FILTER_AVERAGE, + FILTER_PEAK, + FILTER_NB, +}; + struct frame_node { AVFrame *frame; struct frame_node *next; @@ -77,6 +83,7 @@ typedef struct ShowWavesContext { int scale; ///< ShowWavesScale int draw_mode; ///< ShowWavesDrawMode int split_channels; + int filter_mode; uint8_t *fg; int (*get_h)(int16_t sample, int height); @@ -154,20 +161,20 @@ static int query_formats(AVFilterContext *ctx) /* set input audio formats */ formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0) return ret; layouts = ff_all_channel_layouts(); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0) return ret; formats = ff_all_samplerates(); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0) return ret; /* set output video format */ formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; return 0; @@ -590,12 +597,21 @@ static int push_single_pic(AVFilterLink *outlink) int64_t max_samples = col == outlink->w - 1 ? last_column_samples: column_max_samples; int ch; - for (ch = 0; ch < nb_channels; ch++) - sum[ch] += abs(p[ch + i*nb_channels]) << 1; + switch (showwaves->filter_mode) { + case FILTER_AVERAGE: + for (ch = 0; ch < nb_channels; ch++) + sum[ch] += abs(p[ch + i*nb_channels]) << 1; + break; + case FILTER_PEAK: + for (ch = 0; ch < nb_channels; ch++) + sum[ch] = FFMAX(sum[ch], abs(p[ch + i*nb_channels])); + break; + } + n++; if (n == max_samples) { for (ch = 0; ch < nb_channels; ch++) { - int16_t sample = sum[ch] / max_samples; + int16_t sample = sum[ch] / (showwaves->filter_mode == FILTER_AVERAGE ? max_samples : 1); uint8_t *buf = out->data[0] + col * pixstep; int h; @@ -792,6 +808,9 @@ static const AVOption showwavespic_options[] = { { "draw", "set draw mode", OFFSET(draw_mode), AV_OPT_TYPE_INT, {.i64 = DRAW_SCALE}, 0, DRAW_NB-1, FLAGS, .unit="draw" }, { "scale", "scale pixel values for each drawn sample", 0, AV_OPT_TYPE_CONST, {.i64=DRAW_SCALE}, .flags=FLAGS, .unit="draw"}, { "full", "draw every pixel for sample directly", 0, AV_OPT_TYPE_CONST, {.i64=DRAW_FULL}, .flags=FLAGS, .unit="draw"}, + { "filter", "set filter mode", OFFSET(filter_mode), AV_OPT_TYPE_INT, {.i64 = FILTER_AVERAGE}, 0, FILTER_NB-1, FLAGS, .unit="filter" }, + { "average", "use average samples", 0, AV_OPT_TYPE_CONST, {.i64=FILTER_AVERAGE}, .flags=FLAGS, .unit="filter"}, + { "peak", "use peak samples", 0, AV_OPT_TYPE_CONST, {.i64=FILTER_PEAK}, .flags=FLAGS, .unit="filter"}, { NULL } }; diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 394811916..22ecad5f7 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -232,11 +232,12 @@ void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts ff_filter_set_ready(link->src, 200); } +#if FF_API_FILTER_LINK_SET_CLOSED void avfilter_link_set_closed(AVFilterLink *link, int closed) { ff_avfilter_link_set_out_status(link, closed ? AVERROR_EOF : 0, AV_NOPTS_VALUE); } - +#endif int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, unsigned filt_srcpad_idx, unsigned filt_dstpad_idx) { @@ -261,15 +262,15 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, /* if any information on supported media formats already exists on the * link, we need to preserve that */ - if (link->out_formats) - ff_formats_changeref(&link->out_formats, - &filt->outputs[filt_dstpad_idx]->out_formats); - if (link->out_samplerates) - ff_formats_changeref(&link->out_samplerates, - &filt->outputs[filt_dstpad_idx]->out_samplerates); - if (link->out_channel_layouts) - ff_channel_layouts_changeref(&link->out_channel_layouts, - &filt->outputs[filt_dstpad_idx]->out_channel_layouts); + if (link->outcfg.formats) + ff_formats_changeref(&link->outcfg.formats, + &filt->outputs[filt_dstpad_idx]->outcfg.formats); + if (link->outcfg.samplerates) + ff_formats_changeref(&link->outcfg.samplerates, + &filt->outputs[filt_dstpad_idx]->outcfg.samplerates); + if (link->outcfg.channel_layouts) + ff_channel_layouts_changeref(&link->outcfg.channel_layouts, + &filt->outputs[filt_dstpad_idx]->outcfg.channel_layouts); return 0; } @@ -583,6 +584,7 @@ static void *filter_child_next(void *obj, void *prev) return NULL; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *filter_child_class_next(const AVClass *prev) { void *opaque = NULL; @@ -604,14 +606,27 @@ static const AVClass *filter_child_class_next(const AVClass *prev) return NULL; } +#endif + +static const AVClass *filter_child_class_iterate(void **iter) +{ + const AVFilter *f; + + while ((f = av_filter_iterate(iter))) + if (f->priv_class) + return f->priv_class; + + return NULL; +} #define OFFSET(x) offsetof(AVFilterContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM +#define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption avfilter_options[] = { { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" }, { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" }, - { "enable", "set enable expression", OFFSET(enable_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, + { "enable", "set enable expression", OFFSET(enable_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = TFLAGS }, { "threads", "Allowed number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, { "extra_hw_frames", "Number of extra hardware frames to allocate for the user", @@ -625,7 +640,10 @@ static const AVClass avfilter_class = { .version = LIBAVUTIL_VERSION_INT, .category = AV_CLASS_CATEGORY_FILTER, .child_next = filter_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = filter_child_class_next, +#endif + .child_class_iterate = filter_child_class_iterate, .option = avfilter_options, }; @@ -730,12 +748,12 @@ static void free_link(AVFilterLink *link) av_buffer_unref(&link->hw_frames_ctx); - ff_formats_unref(&link->in_formats); - ff_formats_unref(&link->out_formats); - ff_formats_unref(&link->in_samplerates); - ff_formats_unref(&link->out_samplerates); - ff_channel_layouts_unref(&link->in_channel_layouts); - ff_channel_layouts_unref(&link->out_channel_layouts); + ff_formats_unref(&link->incfg.formats); + ff_formats_unref(&link->outcfg.formats); + ff_formats_unref(&link->incfg.samplerates); + ff_formats_unref(&link->outcfg.samplerates); + ff_channel_layouts_unref(&link->incfg.channel_layouts); + ff_channel_layouts_unref(&link->outcfg.channel_layouts); avfilter_link_free(&link); } @@ -841,28 +859,23 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options, return ret; } } else { - av_dict_set(options, key, value, 0); - if ((ret = av_opt_set(ctx->priv, key, value, AV_OPT_SEARCH_CHILDREN)) < 0) { - if (!av_opt_find(ctx->priv, key, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) { - if (ret == AVERROR_OPTION_NOT_FOUND) - av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); - av_free(value); - av_free(parsed_key); - return ret; + av_dict_set(options, key, value, 0); + if ((ret = av_opt_set(ctx->priv, key, value, AV_OPT_SEARCH_CHILDREN)) < 0) { + if (!av_opt_find(ctx->priv, key, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) { + if (ret == AVERROR_OPTION_NOT_FOUND) + av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); + av_free(value); + av_free(parsed_key); + return ret; + } } } - } av_free(value); av_free(parsed_key); count++; } - if (ctx->enable_str) { - ret = set_enable_expr(ctx, ctx->enable_str); - if (ret < 0) - return ret; - } return count; } @@ -913,6 +926,12 @@ int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options) else if (ctx->filter->init_dict) ret = ctx->filter->init_dict(ctx, options); + if (ctx->enable_str) { + ret = set_enable_expr(ctx, ctx->enable_str); + if (ret < 0) + return ret; + } + return ret; } @@ -1408,9 +1427,6 @@ static int ff_filter_activate_default(AVFilterContext *filter) Rationale: checking frame_blocked_in is necessary to avoid requesting repeatedly on a blocked input if another is not blocked (example: [buffersrc1][testsrc1][buffersrc2][testsrc2]concat=v=2). - - TODO: respect needs_fifo and remove auto-inserted fifos. - */ int ff_filter_activate(AVFilterContext *filter) diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 49b4f7a93..be1242436 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -68,6 +68,7 @@ typedef struct AVFilterContext AVFilterContext; typedef struct AVFilterLink AVFilterLink; typedef struct AVFilterPad AVFilterPad; typedef struct AVFilterFormats AVFilterFormats; +typedef struct AVFilterChannelLayouts AVFilterChannelLayouts; /** * Get the number of elements in a NULL-terminated array of AVFilterPads (e.g. @@ -264,13 +265,13 @@ typedef struct AVFilter { * and outputs are fixed), shortly before the format negotiation. This * callback may be called more than once. * - * This callback must set AVFilterLink.out_formats on every input link and - * AVFilterLink.in_formats on every output link to a list of pixel/sample + * This callback must set AVFilterLink.outcfg.formats on every input link and + * AVFilterLink.incfg.formats on every output link to a list of pixel/sample * formats that the filter supports on that link. For audio links, this - * filter must also set @ref AVFilterLink.in_samplerates "in_samplerates" / - * @ref AVFilterLink.out_samplerates "out_samplerates" and - * @ref AVFilterLink.in_channel_layouts "in_channel_layouts" / - * @ref AVFilterLink.out_channel_layouts "out_channel_layouts" analogously. + * filter must also set @ref AVFilterLink.incfg.samplerates "in_samplerates" / + * @ref AVFilterLink.outcfg.samplerates "out_samplerates" and + * @ref AVFilterLink.incfg.channel_layouts "in_channel_layouts" / + * @ref AVFilterLink.outcfg.channel_layouts "out_channel_layouts" analogously. * * This callback may be NULL for filters with one input, in which case * libavfilter assumes that it supports all input formats and preserves @@ -285,11 +286,13 @@ typedef struct AVFilter { int flags_internal; ///< Additional flags for avfilter internal use only. +#if FF_API_NEXT /** * Used by the filter registration system. Must not be touched by any other * code. */ struct AVFilter *next; +#endif /** * Make the filter instance process a command. @@ -424,6 +427,35 @@ struct AVFilterContext { int extra_hw_frames; }; +/** + * Lists of formats / etc. supported by an end of a link. + * + * This structure is directly part of AVFilterLink, in two copies: + * one for the source filter, one for the destination filter. + + * These lists are used for negotiating the format to actually be used, + * which will be loaded into the format and channel_layout members of + * AVFilterLink, when chosen. + */ +typedef struct AVFilterFormatsConfig { + + /** + * List of supported formats (pixel or sample). + */ + AVFilterFormats *formats; + + /** + * Lists of supported sample rates, only for audio. + */ + AVFilterFormats *samplerates; + + /** + * Lists of supported channel layouts, only for audio. + */ + AVFilterChannelLayouts *channel_layouts; + +} AVFilterFormatsConfig; + /** * A link between two filters. This contains pointers to the source and * destination filters between which this link exists, and the indexes of @@ -471,33 +503,16 @@ struct AVFilterLink { * New public fields should be added right above. ***************************************************************** */ - /** - * Lists of formats and channel layouts supported by the input and output - * filters respectively. These lists are used for negotiating the format - * to actually be used, which will be loaded into the format and - * channel_layout members, above, when chosen. - * - */ - AVFilterFormats *in_formats; - AVFilterFormats *out_formats; /** - * Lists of channel layouts and sample rates used for automatic - * negotiation. + * Lists of supported formats / etc. supported by the input filter. */ - AVFilterFormats *in_samplerates; - AVFilterFormats *out_samplerates; - struct AVFilterChannelLayouts *in_channel_layouts; - struct AVFilterChannelLayouts *out_channel_layouts; + AVFilterFormatsConfig incfg; /** - * Audio only, the destination filter sets this to a non-zero value to - * request that buffers with the given number of samples should be sent to - * it. AVFilterPad.needs_fifo must also be set on the corresponding input - * pad. - * Last buffer before EOF will be padded with silence. + * Lists of supported formats / etc. supported by the output filter. */ - int request_samples; + AVFilterFormatsConfig outcfg; /** stage of the initialization of the link properties (dimensions, etc) */ enum { @@ -572,11 +587,6 @@ struct AVFilterLink { */ int channels; - /** - * Link processing flags. - */ - unsigned flags; - /** * Number of past frames sent through the link. */ @@ -671,7 +681,7 @@ void avfilter_link_free(AVFilterLink **link); attribute_deprecated int avfilter_link_get_channels(AVFilterLink *link); #endif - +#if FF_API_FILTER_LINK_SET_CLOSED /** * Set the closed field of a link. * @deprecated applications are not supposed to mess with links, they should @@ -679,7 +689,7 @@ int avfilter_link_get_channels(AVFilterLink *link); */ attribute_deprecated void avfilter_link_set_closed(AVFilterLink *link, int closed); - +#endif /** * Negotiate the media format, dimensions, etc of all inputs to a filter. * diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 2fe4f0b0f..f6b572b3d 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -313,6 +313,53 @@ static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l) } } +static int filter_link_check_formats(void *log, AVFilterLink *link, AVFilterFormatsConfig *cfg) +{ + int ret; + + switch (link->type) { + + case AVMEDIA_TYPE_VIDEO: + if ((ret = ff_formats_check_pixel_formats(log, cfg->formats)) < 0) + return ret; + break; + + case AVMEDIA_TYPE_AUDIO: + if ((ret = ff_formats_check_sample_formats(log, cfg->formats)) < 0 || + (ret = ff_formats_check_sample_rates(log, cfg->samplerates)) < 0 || + (ret = ff_formats_check_channel_layouts(log, cfg->channel_layouts)) < 0) + return ret; + break; + + default: + av_assert0(!"reached"); + } + return 0; +} + +/** + * Check the validity of the formats / etc. lists set by query_formats(). + * + * In particular, check they do not contain any redundant element. + */ +static int filter_check_formats(AVFilterContext *ctx) +{ + unsigned i; + int ret; + + for (i = 0; i < ctx->nb_inputs; i++) { + ret = filter_link_check_formats(ctx, ctx->inputs[i], &ctx->inputs[i]->outcfg); + if (ret < 0) + return ret; + } + for (i = 0; i < ctx->nb_outputs; i++) { + ret = filter_link_check_formats(ctx, ctx->outputs[i], &ctx->outputs[i]->incfg); + if (ret < 0) + return ret; + } + return 0; +} + static int filter_query_formats(AVFilterContext *ctx) { int ret, i; @@ -329,11 +376,14 @@ static int filter_query_formats(AVFilterContext *ctx) ctx->name, av_err2str(ret)); return ret; } + ret = filter_check_formats(ctx); + if (ret < 0) + return ret; for (i = 0; i < ctx->nb_inputs; i++) - sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts); + sanitize_channel_layouts(ctx, ctx->inputs[i]->outcfg.channel_layouts); for (i = 0; i < ctx->nb_outputs; i++) - sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts); + sanitize_channel_layouts(ctx, ctx->outputs[i]->incfg.channel_layouts); formats = ff_all_formats(type); if ((ret = ff_set_common_formats(ctx, formats)) < 0) @@ -354,81 +404,24 @@ static int formats_declared(AVFilterContext *f) int i; for (i = 0; i < f->nb_inputs; i++) { - if (!f->inputs[i]->out_formats) + if (!f->inputs[i]->outcfg.formats) return 0; if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO && - !(f->inputs[i]->out_samplerates && - f->inputs[i]->out_channel_layouts)) + !(f->inputs[i]->outcfg.samplerates && + f->inputs[i]->outcfg.channel_layouts)) return 0; } for (i = 0; i < f->nb_outputs; i++) { - if (!f->outputs[i]->in_formats) + if (!f->outputs[i]->incfg.formats) return 0; if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO && - !(f->outputs[i]->in_samplerates && - f->outputs[i]->in_channel_layouts)) + !(f->outputs[i]->incfg.samplerates && + f->outputs[i]->incfg.channel_layouts)) return 0; } return 1; } -static AVFilterFormats *clone_filter_formats(AVFilterFormats *arg) -{ - AVFilterFormats *a = av_memdup(arg, sizeof(*arg)); - if (a) { - a->refcount = 0; - a->refs = NULL; - a->formats = av_memdup(a->formats, sizeof(*a->formats) * a->nb_formats); - if (!a->formats && arg->formats) - av_freep(&a); - } - return a; -} - -static int can_merge_formats(AVFilterFormats *a_arg, - AVFilterFormats *b_arg, - enum AVMediaType type, - int is_sample_rate) -{ - AVFilterFormats *a, *b, *ret; - if (a_arg == b_arg) - return 1; - a = clone_filter_formats(a_arg); - b = clone_filter_formats(b_arg); - - if (!a || !b) { - if (a) - av_freep(&a->formats); - if (b) - av_freep(&b->formats); - - av_freep(&a); - av_freep(&b); - - return 0; - } - - if (is_sample_rate) { - ret = ff_merge_samplerates(a, b); - } else { - ret = ff_merge_formats(a, b, type); - } - if (ret) { - av_freep(&ret->formats); - av_freep(&ret->refs); - av_freep(&ret); - return 1; - } else { - if (a) - av_freep(&a->formats); - if (b) - av_freep(&b->formats); - av_freep(&a); - av_freep(&b); - return 0; - } -} - /** * Perform one round of query_formats() and merging formats lists on the * filter graph. @@ -473,47 +466,42 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) if (!link) continue; - if (link->in_formats != link->out_formats - && link->in_formats && link->out_formats) - if (!can_merge_formats(link->in_formats, link->out_formats, - link->type, 0)) + if (link->incfg.formats != link->outcfg.formats + && link->incfg.formats && link->outcfg.formats) + if (!ff_can_merge_formats(link->incfg.formats, link->outcfg.formats, + link->type)) convert_needed = 1; if (link->type == AVMEDIA_TYPE_AUDIO) { - if (link->in_samplerates != link->out_samplerates - && link->in_samplerates && link->out_samplerates) - if (!can_merge_formats(link->in_samplerates, - link->out_samplerates, - 0, 1)) + if (link->incfg.samplerates != link->outcfg.samplerates + && link->incfg.samplerates && link->outcfg.samplerates) + if (!ff_can_merge_samplerates(link->incfg.samplerates, + link->outcfg.samplerates)) convert_needed = 1; } -#define MERGE_DISPATCH(field, statement) \ - if (!(link->in_ ## field && link->out_ ## field)) { \ +#define CHECKED_MERGE(field, ...) ((ret = ff_merge_ ## field(__VA_ARGS__)) <= 0) +#define MERGE_DISPATCH(field, ...) \ + if (!(link->incfg.field && link->outcfg.field)) { \ count_delayed++; \ - } else if (link->in_ ## field == link->out_ ## field) { \ + } else if (link->incfg.field == link->outcfg.field) { \ count_already_merged++; \ } else if (!convert_needed) { \ count_merged++; \ - statement \ + if (CHECKED_MERGE(field, __VA_ARGS__)) { \ + if (ret < 0) \ + return ret; \ + convert_needed = 1; \ + } \ } if (link->type == AVMEDIA_TYPE_AUDIO) { - MERGE_DISPATCH(channel_layouts, - if (!ff_merge_channel_layouts(link->in_channel_layouts, - link->out_channel_layouts)) - convert_needed = 1; - ) - MERGE_DISPATCH(samplerates, - if (!ff_merge_samplerates(link->in_samplerates, - link->out_samplerates)) - convert_needed = 1; - ) + MERGE_DISPATCH(channel_layouts, link->incfg.channel_layouts, + link->outcfg.channel_layouts) + MERGE_DISPATCH(samplerates, link->incfg.samplerates, + link->outcfg.samplerates) } - MERGE_DISPATCH(formats, - if (!ff_merge_formats(link->in_formats, link->out_formats, - link->type)) - convert_needed = 1; - ) + MERGE_DISPATCH(formats, link->incfg.formats, + link->outcfg.formats, link->type) #undef MERGE_DISPATCH if (convert_needed) { @@ -573,41 +561,40 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) inlink = convert->inputs[0]; outlink = convert->outputs[0]; - av_assert0( inlink-> in_formats->refcount > 0); - av_assert0( inlink->out_formats->refcount > 0); - av_assert0(outlink-> in_formats->refcount > 0); - av_assert0(outlink->out_formats->refcount > 0); + av_assert0( inlink->incfg.formats->refcount > 0); + av_assert0( inlink->outcfg.formats->refcount > 0); + av_assert0(outlink->incfg.formats->refcount > 0); + av_assert0(outlink->outcfg.formats->refcount > 0); if (outlink->type == AVMEDIA_TYPE_AUDIO) { - av_assert0( inlink-> in_samplerates->refcount > 0); - av_assert0( inlink->out_samplerates->refcount > 0); - av_assert0(outlink-> in_samplerates->refcount > 0); - av_assert0(outlink->out_samplerates->refcount > 0); - av_assert0( inlink-> in_channel_layouts->refcount > 0); - av_assert0( inlink->out_channel_layouts->refcount > 0); - av_assert0(outlink-> in_channel_layouts->refcount > 0); - av_assert0(outlink->out_channel_layouts->refcount > 0); + av_assert0( inlink-> incfg.samplerates->refcount > 0); + av_assert0( inlink->outcfg.samplerates->refcount > 0); + av_assert0(outlink-> incfg.samplerates->refcount > 0); + av_assert0(outlink->outcfg.samplerates->refcount > 0); + av_assert0( inlink-> incfg.channel_layouts->refcount > 0); + av_assert0( inlink->outcfg.channel_layouts->refcount > 0); + av_assert0(outlink-> incfg.channel_layouts->refcount > 0); + av_assert0(outlink->outcfg.channel_layouts->refcount > 0); } - if (!ff_merge_formats( inlink->in_formats, inlink->out_formats, inlink->type) || - !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type)) - ret = AVERROR(ENOSYS); - if (inlink->type == AVMEDIA_TYPE_AUDIO && - (!ff_merge_samplerates(inlink->in_samplerates, - inlink->out_samplerates) || - !ff_merge_channel_layouts(inlink->in_channel_layouts, - inlink->out_channel_layouts))) - ret = AVERROR(ENOSYS); - if (outlink->type == AVMEDIA_TYPE_AUDIO && - (!ff_merge_samplerates(outlink->in_samplerates, - outlink->out_samplerates) || - !ff_merge_channel_layouts(outlink->in_channel_layouts, - outlink->out_channel_layouts))) - ret = AVERROR(ENOSYS); - - if (ret < 0) { + if (CHECKED_MERGE(formats, inlink->incfg.formats, + inlink->outcfg.formats, inlink->type) || + CHECKED_MERGE(formats, outlink->incfg.formats, + outlink->outcfg.formats, outlink->type) || + inlink->type == AVMEDIA_TYPE_AUDIO && + (CHECKED_MERGE(samplerates, inlink->incfg.samplerates, + inlink->outcfg.samplerates) || + CHECKED_MERGE(channel_layouts, inlink->incfg.channel_layouts, + inlink->outcfg.channel_layouts)) || + outlink->type == AVMEDIA_TYPE_AUDIO && + (CHECKED_MERGE(samplerates, outlink->incfg.samplerates, + outlink->outcfg.samplerates) || + CHECKED_MERGE(channel_layouts, outlink->incfg.channel_layouts, + outlink->outcfg.channel_layouts))) { + if (ret < 0) + return ret; av_log(log_ctx, AV_LOG_ERROR, "Impossible to convert between the formats supported by the filter " "'%s' and the filter '%s'\n", link->src->name, link->dst->name); - return ret; + return AVERROR(ENOSYS); } } } @@ -676,7 +663,7 @@ static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt static int pick_format(AVFilterLink *link, AVFilterLink *ref) { - if (!link || !link->in_formats) + if (!link || !link->incfg.formats) return 0; if (link->type == AVMEDIA_TYPE_VIDEO) { @@ -685,98 +672,98 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0; enum AVPixelFormat best= AV_PIX_FMT_NONE; int i; - for (i=0; iin_formats->nb_formats; i++) { - enum AVPixelFormat p = link->in_formats->formats[i]; + for (i = 0; i < link->incfg.formats->nb_formats; i++) { + enum AVPixelFormat p = link->incfg.formats->formats[i]; best= av_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL); } av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n", - av_get_pix_fmt_name(best), link->in_formats->nb_formats, + av_get_pix_fmt_name(best), link->incfg.formats->nb_formats, av_get_pix_fmt_name(ref->format), has_alpha); - link->in_formats->formats[0] = best; + link->incfg.formats->formats[0] = best; } } else if (link->type == AVMEDIA_TYPE_AUDIO) { if(ref && ref->type == AVMEDIA_TYPE_AUDIO){ enum AVSampleFormat best= AV_SAMPLE_FMT_NONE; int i; - for (i=0; iin_formats->nb_formats; i++) { - enum AVSampleFormat p = link->in_formats->formats[i]; + for (i = 0; i < link->incfg.formats->nb_formats; i++) { + enum AVSampleFormat p = link->incfg.formats->formats[i]; best = find_best_sample_fmt_of_2(best, p, ref->format); } av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s\n", - av_get_sample_fmt_name(best), link->in_formats->nb_formats, + av_get_sample_fmt_name(best), link->incfg.formats->nb_formats, av_get_sample_fmt_name(ref->format)); - link->in_formats->formats[0] = best; + link->incfg.formats->formats[0] = best; } } - link->in_formats->nb_formats = 1; - link->format = link->in_formats->formats[0]; + link->incfg.formats->nb_formats = 1; + link->format = link->incfg.formats->formats[0]; if (link->type == AVMEDIA_TYPE_AUDIO) { - if (!link->in_samplerates->nb_formats) { + if (!link->incfg.samplerates->nb_formats) { av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for" " the link between filters %s and %s.\n", link->src->name, link->dst->name); return AVERROR(EINVAL); } - link->in_samplerates->nb_formats = 1; - link->sample_rate = link->in_samplerates->formats[0]; + link->incfg.samplerates->nb_formats = 1; + link->sample_rate = link->incfg.samplerates->formats[0]; - if (link->in_channel_layouts->all_layouts) { + if (link->incfg.channel_layouts->all_layouts) { av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for" " the link between filters %s and %s.\n", link->src->name, link->dst->name); - if (!link->in_channel_layouts->all_counts) + if (!link->incfg.channel_layouts->all_counts) av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not " "supported, try specifying a channel layout using " "'aformat=channel_layouts=something'.\n"); return AVERROR(EINVAL); } - link->in_channel_layouts->nb_channel_layouts = 1; - link->channel_layout = link->in_channel_layouts->channel_layouts[0]; + link->incfg.channel_layouts->nb_channel_layouts = 1; + link->channel_layout = link->incfg.channel_layouts->channel_layouts[0]; if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout))) link->channel_layout = 0; else link->channels = av_get_channel_layout_nb_channels(link->channel_layout); } - ff_formats_unref(&link->in_formats); - ff_formats_unref(&link->out_formats); - ff_formats_unref(&link->in_samplerates); - ff_formats_unref(&link->out_samplerates); - ff_channel_layouts_unref(&link->in_channel_layouts); - ff_channel_layouts_unref(&link->out_channel_layouts); + ff_formats_unref(&link->incfg.formats); + ff_formats_unref(&link->outcfg.formats); + ff_formats_unref(&link->incfg.samplerates); + ff_formats_unref(&link->outcfg.samplerates); + ff_channel_layouts_unref(&link->incfg.channel_layouts); + ff_channel_layouts_unref(&link->outcfg.channel_layouts); return 0; } -#define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format, unref_format) \ +#define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \ do { \ for (i = 0; i < filter->nb_inputs; i++) { \ AVFilterLink *link = filter->inputs[i]; \ fmt_type fmt; \ \ - if (!link->out_ ## list || link->out_ ## list->nb != 1) \ + if (!link->outcfg.list || link->outcfg.list->nb != 1) \ continue; \ - fmt = link->out_ ## list->var[0]; \ + fmt = link->outcfg.list->var[0]; \ \ for (j = 0; j < filter->nb_outputs; j++) { \ AVFilterLink *out_link = filter->outputs[j]; \ list_type *fmts; \ \ if (link->type != out_link->type || \ - out_link->in_ ## list->nb == 1) \ + out_link->incfg.list->nb == 1) \ continue; \ - fmts = out_link->in_ ## list; \ + fmts = out_link->incfg.list; \ \ - if (!out_link->in_ ## list->nb) { \ - if ((ret = add_format(&out_link->in_ ##list, fmt)) < 0)\ + if (!out_link->incfg.list->nb) { \ + if ((ret = add_format(&out_link->incfg.list, fmt)) < 0)\ return ret; \ ret = 1; \ break; \ } \ \ - for (k = 0; k < out_link->in_ ## list->nb; k++) \ + for (k = 0; k < out_link->incfg.list->nb; k++) \ if (fmts->var[k] == fmt) { \ fmts->var[0] = fmt; \ fmts->nb = 1; \ @@ -792,25 +779,25 @@ static int reduce_formats_on_filter(AVFilterContext *filter) int i, j, k, ret = 0; REDUCE_FORMATS(int, AVFilterFormats, formats, formats, - nb_formats, ff_add_format, ff_formats_unref); + nb_formats, ff_add_format); REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, - nb_formats, ff_add_format, ff_formats_unref); + nb_formats, ff_add_format); /* reduce channel layouts */ for (i = 0; i < filter->nb_inputs; i++) { AVFilterLink *inlink = filter->inputs[i]; uint64_t fmt; - if (!inlink->out_channel_layouts || - inlink->out_channel_layouts->nb_channel_layouts != 1) + if (!inlink->outcfg.channel_layouts || + inlink->outcfg.channel_layouts->nb_channel_layouts != 1) continue; - fmt = inlink->out_channel_layouts->channel_layouts[0]; + fmt = inlink->outcfg.channel_layouts->channel_layouts[0]; for (j = 0; j < filter->nb_outputs; j++) { AVFilterLink *outlink = filter->outputs[j]; AVFilterChannelLayouts *fmts; - fmts = outlink->in_channel_layouts; + fmts = outlink->incfg.channel_layouts; if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1) continue; @@ -818,12 +805,12 @@ static int reduce_formats_on_filter(AVFilterContext *filter) (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) { /* Turn the infinite list into a singleton */ fmts->all_layouts = fmts->all_counts = 0; - if (ff_add_channel_layout(&outlink->in_channel_layouts, fmt) < 0) + if (ff_add_channel_layout(&outlink->incfg.channel_layouts, fmt) < 0) ret = 1; break; } - for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) { + for (k = 0; k < outlink->incfg.channel_layouts->nb_channel_layouts; k++) { if (fmts->channel_layouts[k] == fmt) { fmts->channel_layouts[0] = fmt; fmts->nb_channel_layouts = 1; @@ -864,24 +851,24 @@ static void swap_samplerates_on_filter(AVFilterContext *filter) link = filter->inputs[i]; if (link->type == AVMEDIA_TYPE_AUDIO && - link->out_samplerates->nb_formats== 1) + link->outcfg.samplerates->nb_formats== 1) break; } if (i == filter->nb_inputs) return; - sample_rate = link->out_samplerates->formats[0]; + sample_rate = link->outcfg.samplerates->formats[0]; for (i = 0; i < filter->nb_outputs; i++) { AVFilterLink *outlink = filter->outputs[i]; int best_idx, best_diff = INT_MAX; if (outlink->type != AVMEDIA_TYPE_AUDIO || - outlink->in_samplerates->nb_formats < 2) + outlink->incfg.samplerates->nb_formats < 2) continue; - for (j = 0; j < outlink->in_samplerates->nb_formats; j++) { - int diff = abs(sample_rate - outlink->in_samplerates->formats[j]); + for (j = 0; j < outlink->incfg.samplerates->nb_formats; j++) { + int diff = abs(sample_rate - outlink->incfg.samplerates->formats[j]); av_assert0(diff < INT_MAX); // This would lead to the use of uninitialized best_diff but is only possible with invalid sample rates @@ -890,8 +877,8 @@ static void swap_samplerates_on_filter(AVFilterContext *filter) best_idx = j; } } - FFSWAP(int, outlink->in_samplerates->formats[0], - outlink->in_samplerates->formats[best_idx]); + FFSWAP(int, outlink->incfg.samplerates->formats[0], + outlink->incfg.samplerates->formats[best_idx]); } } @@ -946,7 +933,7 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) link = filter->inputs[i]; if (link->type == AVMEDIA_TYPE_AUDIO && - link->out_channel_layouts->nb_channel_layouts == 1) + link->outcfg.channel_layouts->nb_channel_layouts == 1) break; } if (i == filter->nb_inputs) @@ -957,12 +944,12 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX; if (outlink->type != AVMEDIA_TYPE_AUDIO || - outlink->in_channel_layouts->nb_channel_layouts < 2) + outlink->incfg.channel_layouts->nb_channel_layouts < 2) continue; - for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) { - uint64_t in_chlayout = link->out_channel_layouts->channel_layouts[0]; - uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j]; + for (j = 0; j < outlink->incfg.channel_layouts->nb_channel_layouts; j++) { + uint64_t in_chlayout = link->outcfg.channel_layouts->channel_layouts[0]; + uint64_t out_chlayout = outlink->incfg.channel_layouts->channel_layouts[j]; int in_channels = av_get_channel_layout_nb_channels(in_chlayout); int out_channels = av_get_channel_layout_nb_channels(out_chlayout); int count_diff = out_channels - in_channels; @@ -1020,8 +1007,8 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) } } av_assert0(best_idx >= 0); - FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0], - outlink->in_channel_layouts->channel_layouts[best_idx]); + FFSWAP(uint64_t, outlink->incfg.channel_layouts->channel_layouts[0], + outlink->incfg.channel_layouts->channel_layouts[best_idx]); } } @@ -1044,13 +1031,13 @@ static void swap_sample_fmts_on_filter(AVFilterContext *filter) link = filter->inputs[i]; if (link->type == AVMEDIA_TYPE_AUDIO && - link->out_formats->nb_formats == 1) + link->outcfg.formats->nb_formats == 1) break; } if (i == filter->nb_inputs) return; - format = link->out_formats->formats[0]; + format = link->outcfg.formats->formats[0]; bps = av_get_bytes_per_sample(format); for (i = 0; i < filter->nb_outputs; i++) { @@ -1058,11 +1045,11 @@ static void swap_sample_fmts_on_filter(AVFilterContext *filter) int best_idx = -1, best_score = INT_MIN; if (outlink->type != AVMEDIA_TYPE_AUDIO || - outlink->in_formats->nb_formats < 2) + outlink->incfg.formats->nb_formats < 2) continue; - for (j = 0; j < outlink->in_formats->nb_formats; j++) { - int out_format = outlink->in_formats->formats[j]; + for (j = 0; j < outlink->incfg.formats->nb_formats; j++) { + int out_format = outlink->incfg.formats->formats[j]; int out_bps = av_get_bytes_per_sample(out_format); int score; @@ -1089,8 +1076,8 @@ static void swap_sample_fmts_on_filter(AVFilterContext *filter) } } av_assert0(best_idx >= 0); - FFSWAP(int, outlink->in_formats->formats[0], - outlink->in_formats->formats[best_idx]); + FFSWAP(int, outlink->incfg.formats->formats[0], + outlink->incfg.formats->formats[best_idx]); } } @@ -1114,7 +1101,7 @@ static int pick_formats(AVFilterGraph *graph) AVFilterContext *filter = graph->filters[i]; if (filter->nb_inputs){ for (j = 0; j < filter->nb_inputs; j++){ - if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->nb_formats == 1) { + if (filter->inputs[j]->incfg.formats && filter->inputs[j]->incfg.formats->nb_formats == 1) { if ((ret = pick_format(filter->inputs[j], NULL)) < 0) return ret; change = 1; @@ -1123,7 +1110,7 @@ static int pick_formats(AVFilterGraph *graph) } if (filter->nb_outputs){ for (j = 0; j < filter->nb_outputs; j++){ - if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->nb_formats == 1) { + if (filter->outputs[j]->incfg.formats && filter->outputs[j]->incfg.formats->nb_formats == 1) { if ((ret = pick_format(filter->outputs[j], NULL)) < 0) return ret; change = 1; @@ -1132,7 +1119,7 @@ static int pick_formats(AVFilterGraph *graph) } if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) { for (j = 0; j < filter->nb_outputs; j++) { - if(filter->outputs[j]->format<0) { + if (filter->outputs[j]->format<0) { if ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0) return ret; change = 1; @@ -1228,52 +1215,12 @@ static int graph_config_pointers(AVFilterGraph *graph, return 0; } -static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx) -{ - AVFilterContext *f; - int i, j, ret; - int fifo_count = 0; - - for (i = 0; i < graph->nb_filters; i++) { - f = graph->filters[i]; - - for (j = 0; j < f->nb_inputs; j++) { - AVFilterLink *link = f->inputs[j]; - AVFilterContext *fifo_ctx; - const AVFilter *fifo; - char name[32]; - - if (!link->dstpad->needs_fifo) - continue; - - fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ? - avfilter_get_by_name("fifo") : - avfilter_get_by_name("afifo"); - - snprintf(name, sizeof(name), "auto_fifo_%d", fifo_count++); - - ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL, - NULL, graph); - if (ret < 0) - return ret; - - ret = avfilter_insert_filter(link, fifo_ctx, 0, 0); - if (ret < 0) - return ret; - } - } - - return 0; -} - int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx) { int ret; if ((ret = graph_check_validity(graphctx, log_ctx))) return ret; - if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0) - return ret; if ((ret = graph_config_formats(graphctx, log_ctx))) return ret; if ((ret = graph_config_links(graphctx, log_ctx))) diff --git a/libavfilter/bbox.c b/libavfilter/bbox.c index be9b2e6b7..3ed9045b0 100644 --- a/libavfilter/bbox.c +++ b/libavfilter/bbox.c @@ -20,56 +20,71 @@ #include "bbox.h" +#define BBOX(type, name) \ +static int bbox_##name(FFBoundingBox *bbox, \ + const type *data, int linesize, int w, int h, \ + int min_val) \ +{ \ + int x, y; \ + int start_x; \ + int start_y; \ + int end_x; \ + int end_y; \ + const type *line; \ + \ + /* left bound */ \ + for (start_x = 0; start_x < w; start_x++) \ + for (y = 0; y < h; y++) \ + if ((data[y * linesize + start_x] > min_val)) \ + goto outl; \ +outl: \ + if (start_x == w) /* no points found */ \ + return 0; \ + \ + /* right bound */ \ + for (end_x = w - 1; end_x >= start_x; end_x--) \ + for (y = 0; y < h; y++) \ + if ((data[y * linesize + end_x] > min_val)) \ + goto outr; \ +outr: \ + \ + /* top bound */ \ + line = data; \ + for (start_y = 0; start_y < h; start_y++) { \ + for (x = 0; x < w; x++) \ + if (line[x] > min_val) \ + goto outt; \ + line += linesize; \ + } \ +outt: \ + \ + /* bottom bound */ \ + line = data + (h-1)*linesize; \ + for (end_y = h - 1; end_y >= start_y; end_y--) { \ + for (x = 0; x < w; x++) \ + if (line[x] > min_val) \ + goto outb; \ + line -= linesize; \ + } \ +outb: \ + \ + bbox->x1 = start_x; \ + bbox->y1 = start_y; \ + bbox->x2 = end_x; \ + bbox->y2 = end_y; \ + return 1; \ +} + +BBOX(uint8_t, 8) +BBOX(uint16_t, 16) + int ff_calculate_bounding_box(FFBoundingBox *bbox, - const uint8_t *data, int linesize, int w, int h, - int min_val) + const uint8_t *data, int linesize, + int w, int h, + int min_val, int depth) { - int x, y; - int start_x; - int start_y; - int end_x; - int end_y; - const uint8_t *line; - - /* left bound */ - for (start_x = 0; start_x < w; start_x++) - for (y = 0; y < h; y++) - if ((data[y * linesize + start_x] > min_val)) - goto outl; -outl: - if (start_x == w) /* no points found */ - return 0; - - /* right bound */ - for (end_x = w - 1; end_x >= start_x; end_x--) - for (y = 0; y < h; y++) - if ((data[y * linesize + end_x] > min_val)) - goto outr; -outr: - - /* top bound */ - line = data; - for (start_y = 0; start_y < h; start_y++) { - for (x = 0; x < w; x++) - if (line[x] > min_val) - goto outt; - line += linesize; - } -outt: - - /* bottom bound */ - line = data + (h-1)*linesize; - for (end_y = h - 1; end_y >= start_y; end_y--) { - for (x = 0; x < w; x++) - if (line[x] > min_val) - goto outb; - line -= linesize; - } -outb: - - bbox->x1 = start_x; - bbox->y1 = start_y; - bbox->x2 = end_x; - bbox->y2 = end_y; - return 1; + if (depth <= 8) + return bbox_8(bbox, data, linesize, w, h, min_val); + else + return bbox_16(bbox, (const uint16_t *)data, linesize / 2, w, h, min_val); } diff --git a/libavfilter/bbox.h b/libavfilter/bbox.h index cf026b81f..116158d59 100644 --- a/libavfilter/bbox.h +++ b/libavfilter/bbox.h @@ -39,6 +39,6 @@ typedef struct FFBoundingBox { */ int ff_calculate_bounding_box(FFBoundingBox *bbox, const uint8_t *data, int linesize, - int w, int h, int min_val); + int w, int h, int min_val, int depth); #endif /* AVFILTER_BBOX_H */ diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index 76a46f667..15d897cff 100644 --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c @@ -62,6 +62,29 @@ typedef struct BufferSinkContext { #define NB_ITEMS(list) (list ## _size / sizeof(*list)) +static void cleanup_redundant_layouts(AVFilterContext *ctx) +{ + BufferSinkContext *buf = ctx->priv; + int nb_layouts = NB_ITEMS(buf->channel_layouts); + int nb_counts = NB_ITEMS(buf->channel_counts); + uint64_t counts = 0; + int i, lc, n; + + for (i = 0; i < nb_counts; i++) + if (buf->channel_counts[i] < 64) + counts |= (uint64_t)1 << buf->channel_counts[i]; + for (i = lc = 0; i < nb_layouts; i++) { + n = av_get_channel_layout_nb_channels(buf->channel_layouts[i]); + if (n < 64 && (counts & ((uint64_t)1 << n))) + av_log(ctx, AV_LOG_WARNING, + "Removing channel layout 0x%"PRIx64", redundant with %d channels\n", + buf->channel_layouts[i], n); + else + buf->channel_layouts[lc++] = buf->channel_layouts[i]; + } + buf->channel_layouts_size = lc * sizeof(*buf->channel_layouts); +} + int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame) { return av_buffersink_get_frame_flags(ctx, frame, 0); @@ -125,7 +148,7 @@ int attribute_align_arg av_buffersink_get_samples(AVFilterContext *ctx, return get_frame_internal(ctx, frame, 0, nb_samples); } -#if FF_API_NEXT +#if FF_API_BUFFERSINK_ALLOC AVBufferSinkParams *av_buffersink_params_alloc(void) { static const int pixel_fmts[] = { AV_PIX_FMT_NONE }; @@ -253,6 +276,7 @@ static int asink_query_formats(AVFilterContext *ctx) if (buf->channel_layouts_size || buf->channel_counts_size || buf->all_channel_counts) { + cleanup_redundant_layouts(ctx); for (i = 0; i < NB_ITEMS(buf->channel_layouts); i++) if ((ret = ff_add_channel_layout(&layouts, buf->channel_layouts[i])) < 0) return ret; diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h index 2ec821c68..69ed0f29a 100644 --- a/libavfilter/buffersink.h +++ b/libavfilter/buffersink.h @@ -31,6 +31,42 @@ * @defgroup lavfi_buffersink Buffer sink API * @ingroup lavfi * @{ + * + * The buffersink and abuffersink filters are there to connect filter graphs + * to applications. They have a single input, connected to the graph, and no + * output. Frames must be extracted using av_buffersink_get_frame() or + * av_buffersink_get_samples(). + * + * The format negotiated by the graph during configuration can be obtained + * using the accessor functions: + * - av_buffersink_get_time_base(), + * - av_buffersink_get_format(), + * - av_buffersink_get_frame_rate(), + * - av_buffersink_get_w(), + * - av_buffersink_get_h(), + * - av_buffersink_get_sample_aspect_ratio(), + * - av_buffersink_get_channels(), + * - av_buffersink_get_channel_layout(), + * - av_buffersink_get_sample_rate(). + * + * The format can be constrained by setting options, using av_opt_set() and + * related functions with the AV_OPT_SEARCH_CHILDREN flag. + * - pix_fmts (int list), + * - sample_fmts (int list), + * - sample_rates (int list), + * - channel_layouts (int64_t), + * - channel_counts (int list), + * - all_channel_counts (bool). + * Most of these options are of type binary, and should be set using + * av_opt_set_int_list() or av_opt_set_bin(). If they are not set, all + * corresponding formats are accepted. + * + * As a special case, if neither channel_layouts nor channel_counts is set, + * all valid channel layouts are accepted, but channel counts without a + * layout are not, unless all_channel_counts is set. + * Also, channel_layouts must not contain a channel layout already accepted + * by a value in channel_counts; for example, if channel_counts contains 2, + * then channel_layouts must not contain stereo. */ /** @@ -59,9 +95,9 @@ int av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flag */ #define AV_BUFFERSINK_FLAG_NO_REQUEST 2 -#if FF_API_NEXT +#if FF_API_BUFFERSINK_ALLOC /** - * Struct to use for initializing a buffersink context. + * Deprecated and unused struct to use for initializing a buffersink context. */ typedef struct AVBufferSinkParams { const enum AVPixelFormat *pixel_fmts; ///< list of allowed pixel formats, terminated by AV_PIX_FMT_NONE @@ -76,7 +112,7 @@ attribute_deprecated AVBufferSinkParams *av_buffersink_params_alloc(void); /** - * Struct to use for initializing an abuffersink context. + * Deprecated and unused struct to use for initializing an abuffersink context. */ typedef struct AVABufferSinkParams { const enum AVSampleFormat *sample_fmts; ///< list of allowed sample formats, terminated by AV_SAMPLE_FMT_NONE diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index bf30f5417..da1cf9941 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -149,33 +149,6 @@ int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *fr return av_buffersrc_add_frame_flags(ctx, frame, 0); } -static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, - AVFrame *frame, int flags); - -int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) -{ - AVFrame *copy = NULL; - int ret = 0; - - if (frame && frame->channel_layout && - av_get_channel_layout_nb_channels(frame->channel_layout) != frame->channels) { - av_log(ctx, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); - return AVERROR(EINVAL); - } - - if (!(flags & AV_BUFFERSRC_FLAG_KEEP_REF) || !frame) - return av_buffersrc_add_frame_internal(ctx, frame, flags); - - if (!(copy = av_frame_alloc())) - return AVERROR(ENOMEM); - ret = av_frame_ref(copy, frame); - if (ret >= 0) - ret = av_buffersrc_add_frame_internal(ctx, copy, flags); - - av_frame_free(©); - return ret; -} - static int push_frame(AVFilterGraph *graph) { int ret; @@ -190,13 +163,18 @@ static int push_frame(AVFilterGraph *graph) return 0; } -static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, - AVFrame *frame, int flags) +int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) { BufferSourceContext *s = ctx->priv; AVFrame *copy; int refcounted, ret; + if (frame && frame->channel_layout && + av_get_channel_layout_nb_channels(frame->channel_layout) != frame->channels) { + av_log(ctx, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); + return AVERROR(EINVAL); + } + s->nb_failed_requests = 0; if (!frame) @@ -229,7 +207,7 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, if (!(copy = av_frame_alloc())) return AVERROR(ENOMEM); - if (refcounted) { + if (refcounted && !(flags & AV_BUFFERSRC_FLAG_KEEP_REF)) { av_frame_move_ref(copy, frame); } else { ret = av_frame_ref(copy, frame); diff --git a/libavfilter/convolution.h b/libavfilter/convolution.h index fc6aad58f..88aabe9a2 100644 --- a/libavfilter/convolution.h +++ b/libavfilter/convolution.h @@ -57,7 +57,7 @@ typedef struct ConvolutionContext { void (*filter[4])(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride); + int dstride, int stride, int size); } ConvolutionContext; void ff_convolution_init_x86(ConvolutionContext *s); diff --git a/libavfilter/cuda/vector_helpers.cuh b/libavfilter/cuda/vector_helpers.cuh new file mode 100644 index 000000000..67332ef03 --- /dev/null +++ b/libavfilter/cuda/vector_helpers.cuh @@ -0,0 +1,112 @@ +/* + * This file is part of FFmpeg. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVFILTER_CUDA_VECTORHELPERS_H +#define AVFILTER_CUDA_VECTORHELPERS_H + +typedef unsigned char uchar; +typedef unsigned short ushort; + +template struct vector_helper { }; +template<> struct vector_helper { typedef float ftype; typedef int itype; }; +template<> struct vector_helper { typedef float2 ftype; typedef int2 itype; }; +template<> struct vector_helper { typedef float4 ftype; typedef int4 itype; }; +template<> struct vector_helper { typedef float ftype; typedef int itype; }; +template<> struct vector_helper { typedef float2 ftype; typedef int2 itype; }; +template<> struct vector_helper { typedef float4 ftype; typedef int4 itype; }; +template<> struct vector_helper { typedef float ftype; typedef int itype; }; +template<> struct vector_helper { typedef float2 ftype; typedef int2 itype; }; +template<> struct vector_helper { typedef float4 ftype; typedef int4 itype; }; + +#define floatT typename vector_helper::ftype +#define intT typename vector_helper::itype + +template inline __device__ V to_floatN(const T &a) { return (V)a; } +template inline __device__ T from_floatN(const V &a) { return (T)a; } + +#define OPERATORS2(T) \ + template inline __device__ T operator+(const T &a, const V &b) { return make_ ## T (a.x + b.x, a.y + b.y); } \ + template inline __device__ T operator-(const T &a, const V &b) { return make_ ## T (a.x - b.x, a.y - b.y); } \ + template inline __device__ T operator*(const T &a, V b) { return make_ ## T (a.x * b, a.y * b); } \ + template inline __device__ T operator/(const T &a, V b) { return make_ ## T (a.x / b, a.y / b); } \ + template inline __device__ T operator>>(const T &a, V b) { return make_ ## T (a.x >> b, a.y >> b); } \ + template inline __device__ T operator<<(const T &a, V b) { return make_ ## T (a.x << b, a.y << b); } \ + template inline __device__ T &operator+=(T &a, const V &b) { a.x += b.x; a.y += b.y; return a; } \ + template inline __device__ void vec_set(T &a, const V &b) { a.x = b.x; a.y = b.y; } \ + template inline __device__ void vec_set_scalar(T &a, V b) { a.x = b; a.y = b; } \ + template<> inline __device__ float2 to_floatN(const T &a) { return make_float2(a.x, a.y); } \ + template<> inline __device__ T from_floatN(const float2 &a) { return make_ ## T(a.x, a.y); } +#define OPERATORS4(T) \ + template inline __device__ T operator+(const T &a, const V &b) { return make_ ## T (a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); } \ + template inline __device__ T operator-(const T &a, const V &b) { return make_ ## T (a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); } \ + template inline __device__ T operator*(const T &a, V b) { return make_ ## T (a.x * b, a.y * b, a.z * b, a.w * b); } \ + template inline __device__ T operator/(const T &a, V b) { return make_ ## T (a.x / b, a.y / b, a.z / b, a.w / b); } \ + template inline __device__ T operator>>(const T &a, V b) { return make_ ## T (a.x >> b, a.y >> b, a.z >> b, a.w >> b); } \ + template inline __device__ T operator<<(const T &a, V b) { return make_ ## T (a.x << b, a.y << b, a.z << b, a.w << b); } \ + template inline __device__ T &operator+=(T &a, const V &b) { a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; return a; } \ + template inline __device__ void vec_set(T &a, const V &b) { a.x = b.x; a.y = b.y; a.z = b.z; a.w = b.w; } \ + template inline __device__ void vec_set_scalar(T &a, V b) { a.x = b; a.y = b; a.z = b; a.w = b; } \ + template<> inline __device__ float4 to_floatN(const T &a) { return make_float4(a.x, a.y, a.z, a.w); } \ + template<> inline __device__ T from_floatN(const float4 &a) { return make_ ## T(a.x, a.y, a.z, a.w); } + +OPERATORS2(int2) +OPERATORS2(uchar2) +OPERATORS2(ushort2) +OPERATORS2(float2) +OPERATORS4(int4) +OPERATORS4(uchar4) +OPERATORS4(ushort4) +OPERATORS4(float4) + +template inline __device__ void vec_set(int &a, V b) { a = b; } +template inline __device__ void vec_set(float &a, V b) { a = b; } +template inline __device__ void vec_set(uchar &a, V b) { a = b; } +template inline __device__ void vec_set(ushort &a, V b) { a = b; } +template inline __device__ void vec_set_scalar(int &a, V b) { a = b; } +template inline __device__ void vec_set_scalar(float &a, V b) { a = b; } +template inline __device__ void vec_set_scalar(uchar &a, V b) { a = b; } +template inline __device__ void vec_set_scalar(ushort &a, V b) { a = b; } + +template +inline __device__ T lerp_scalar(T v0, T v1, float t) { + return t*v1 + (1.0f - t)*v0; +} + +template<> +inline __device__ float2 lerp_scalar(float2 v0, float2 v1, float t) { + return make_float2( + lerp_scalar(v0.x, v1.x, t), + lerp_scalar(v0.y, v1.y, t) + ); +} + +template<> +inline __device__ float4 lerp_scalar(float4 v0, float4 v1, float t) { + return make_float4( + lerp_scalar(v0.x, v1.x, t), + lerp_scalar(v0.y, v1.y, t), + lerp_scalar(v0.z, v1.z, t), + lerp_scalar(v0.w, v1.w, t) + ); +} + +#endif diff --git a/libavfilter/dnn/Makefile b/libavfilter/dnn/Makefile index bb37298b5..d6d58f4b6 100644 --- a/libavfilter/dnn/Makefile +++ b/libavfilter/dnn/Makefile @@ -1,6 +1,11 @@ OBJS-$(CONFIG_DNN) += dnn/dnn_interface.o +OBJS-$(CONFIG_DNN) += dnn/dnn_io_proc.o +OBJS-$(CONFIG_DNN) += dnn/queue.o +OBJS-$(CONFIG_DNN) += dnn/safe_queue.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layers.o +OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_avgpool.o +OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_dense.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_pad.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_conv2d.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_depth2space.o @@ -9,5 +14,6 @@ OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_mat OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_mathunary.o DNN-OBJS-$(CONFIG_LIBTENSORFLOW) += dnn/dnn_backend_tf.o +DNN-OBJS-$(CONFIG_LIBOPENVINO) += dnn/dnn_backend_openvino.o OBJS-$(CONFIG_DNN) += $(DNN-OBJS-yes) diff --git a/libavfilter/dnn/dnn_backend_native.c b/libavfilter/dnn/dnn_backend_native.c index a685efb09..d8ae36c52 100644 --- a/libavfilter/dnn/dnn_backend_native.c +++ b/libavfilter/dnn/dnn_backend_native.c @@ -27,16 +27,39 @@ #include "libavutil/avassert.h" #include "dnn_backend_native_layer_conv2d.h" #include "dnn_backend_native_layers.h" +#include "dnn_io_proc.h" + +#define OFFSET(x) offsetof(NativeContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM +static const AVOption dnn_native_options[] = { + { "conv2d_threads", "threads num for conv2d layer", OFFSET(options.conv2d_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS }, + { NULL }, +}; + +static const AVClass dnn_native_class = { + .class_name = "dnn_native", + .item_name = av_default_item_name, + .option = dnn_native_options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_FILTER, +}; + +static DNNReturnType execute_model_native(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame, + int do_ioproc); static DNNReturnType get_input_native(void *model, DNNData *input, const char *input_name) { - ConvolutionalNetwork *network = (ConvolutionalNetwork *)model; + NativeModel *native_model = model; + NativeContext *ctx = &native_model->ctx; - for (int i = 0; i < network->operands_num; ++i) { - DnnOperand *oprd = &network->operands[i]; + for (int i = 0; i < native_model->operands_num; ++i) { + DnnOperand *oprd = &native_model->operands[i]; if (strcmp(oprd->name, input_name) == 0) { - if (oprd->type != DOT_INPUT) + if (oprd->type != DOT_INPUT) { + av_log(ctx, AV_LOG_ERROR, "Found \"%s\" in model, but it is not input node\n", input_name); return DNN_ERROR; + } input->dt = oprd->data_type; av_assert0(oprd->dims[0] == 1); input->height = oprd->dims[1]; @@ -47,82 +70,56 @@ static DNNReturnType get_input_native(void *model, DNNData *input, const char *i } // do not find the input operand + av_log(ctx, AV_LOG_ERROR, "Could not find \"%s\" in model\n", input_name); return DNN_ERROR; } -static DNNReturnType set_input_output_native(void *model, DNNData *input, const char *input_name, const char **output_names, uint32_t nb_output) +static DNNReturnType get_output_native(void *model, const char *input_name, int input_width, int input_height, + const char *output_name, int *output_width, int *output_height) { - ConvolutionalNetwork *network = (ConvolutionalNetwork *)model; - DnnOperand *oprd = NULL; + DNNReturnType ret; + NativeModel *native_model = model; + NativeContext *ctx = &native_model->ctx; + AVFrame *in_frame = av_frame_alloc(); + AVFrame *out_frame = NULL; - if (network->layers_num <= 0 || network->operands_num <= 0) + if (!in_frame) { + av_log(ctx, AV_LOG_ERROR, "Could not allocate memory for input frame\n"); return DNN_ERROR; - - /* inputs */ - for (int i = 0; i < network->operands_num; ++i) { - oprd = &network->operands[i]; - if (strcmp(oprd->name, input_name) == 0) { - if (oprd->type != DOT_INPUT) - return DNN_ERROR; - break; - } - oprd = NULL; } - if (!oprd) + out_frame = av_frame_alloc(); + + if (!out_frame) { + av_log(ctx, AV_LOG_ERROR, "Could not allocate memory for output frame\n"); + av_frame_free(&in_frame); return DNN_ERROR; - - oprd->dims[0] = 1; - oprd->dims[1] = input->height; - oprd->dims[2] = input->width; - oprd->dims[3] = input->channels; - - av_freep(&oprd->data); - oprd->length = calculate_operand_data_length(oprd); - if (oprd->length <= 0) - return DNN_ERROR; - oprd->data = av_malloc(oprd->length); - if (!oprd->data) - return DNN_ERROR; - - input->data = oprd->data; - - /* outputs */ - network->nb_output = 0; - av_freep(&network->output_indexes); - network->output_indexes = av_mallocz_array(nb_output, sizeof(*network->output_indexes)); - if (!network->output_indexes) - return DNN_ERROR; - - for (uint32_t i = 0; i < nb_output; ++i) { - const char *output_name = output_names[i]; - for (int j = 0; j < network->operands_num; ++j) { - oprd = &network->operands[j]; - if (strcmp(oprd->name, output_name) == 0) { - network->output_indexes[network->nb_output++] = j; - break; - } - } } - if (network->nb_output != nb_output) - return DNN_ERROR; + in_frame->width = input_width; + in_frame->height = input_height; - return DNN_SUCCESS; + ret = execute_model_native(native_model->model, input_name, in_frame, &output_name, 1, out_frame, 0); + *output_width = out_frame->width; + *output_height = out_frame->height; + + av_frame_free(&out_frame); + av_frame_free(&in_frame); + return ret; } // Loads model and its parameters that are stored in a binary file with following structure: // layers_num,layer_type,layer_parameterss,layer_type,layer_parameters... // For CONV layer: activation_function, input_num, output_num, kernel_size, kernel, biases // For DEPTH_TO_SPACE layer: block_size -DNNModel *ff_dnn_load_model_native(const char *model_filename) +DNNModel *ff_dnn_load_model_native(const char *model_filename, DNNFunctionType func_type, const char *options, AVFilterContext *filter_ctx) { +#define DNN_NATIVE_MAGIC "FFMPEGDNNNATIVE" DNNModel *model = NULL; - char header_expected[] = "FFMPEGDNNNATIVE"; - char *buf; - size_t size; + // sizeof - 1 to skip the terminating '\0' which is not written in the file + char buf[sizeof(DNN_NATIVE_MAGIC) - 1]; int version, header_size, major_version_expected = 1; - ConvolutionalNetwork *network = NULL; + NativeModel *native_model = NULL; AVIOContext *model_file_context; int file_size, dnn_size, parsed_size; int32_t layer; @@ -141,20 +138,10 @@ DNNModel *ff_dnn_load_model_native(const char *model_filename) /** * check file header with string and version */ - size = sizeof(header_expected); - buf = av_malloc(size); - if (!buf) { + if (avio_read(model_file_context, buf, sizeof(buf)) != sizeof(buf) || + memcmp(buf, DNN_NATIVE_MAGIC, sizeof(buf))) goto fail; - } - - // size - 1 to skip the ending '\0' which is not saved in file - avio_get_str(model_file_context, size - 1, buf, size); - dnn_size = size - 1; - if (strncmp(buf, header_expected, size) != 0) { - av_freep(&buf); - goto fail; - } - av_freep(&buf); + dnn_size = sizeof(buf); version = (int32_t)avio_rl32(model_file_context); dnn_size += 4; @@ -167,29 +154,42 @@ DNNModel *ff_dnn_load_model_native(const char *model_filename) dnn_size += 4; header_size = dnn_size; - network = av_mallocz(sizeof(ConvolutionalNetwork)); - if (!network){ + native_model = av_mallocz(sizeof(NativeModel)); + if (!native_model){ goto fail; } - model->model = (void *)network; + model->model = native_model; + + native_model->ctx.class = &dnn_native_class; + model->options = options; + if (av_opt_set_from_string(&native_model->ctx, model->options, NULL, "=", "&") < 0) + goto fail; + native_model->model = model; + +#if !HAVE_PTHREAD_CANCEL + if (native_model->ctx.options.conv2d_threads > 1){ + av_log(&native_model->ctx, AV_LOG_WARNING, "'conv2d_threads' option was set but it is not supported " + "on this build (pthread support is required)\n"); + } +#endif avio_seek(model_file_context, file_size - 8, SEEK_SET); - network->layers_num = (int32_t)avio_rl32(model_file_context); - network->operands_num = (int32_t)avio_rl32(model_file_context); + native_model->layers_num = (int32_t)avio_rl32(model_file_context); + native_model->operands_num = (int32_t)avio_rl32(model_file_context); dnn_size += 8; avio_seek(model_file_context, header_size, SEEK_SET); - network->layers = av_mallocz(network->layers_num * sizeof(Layer)); - if (!network->layers){ + native_model->layers = av_mallocz(native_model->layers_num * sizeof(Layer)); + if (!native_model->layers){ goto fail; } - network->operands = av_mallocz(network->operands_num * sizeof(DnnOperand)); - if (!network->operands){ + native_model->operands = av_mallocz(native_model->operands_num * sizeof(DnnOperand)); + if (!native_model->operands){ goto fail; } - for (layer = 0; layer < network->layers_num; ++layer){ + for (layer = 0; layer < native_model->layers_num; ++layer){ layer_type = (int32_t)avio_rl32(model_file_context); dnn_size += 4; @@ -197,25 +197,25 @@ DNNModel *ff_dnn_load_model_native(const char *model_filename) goto fail; } - network->layers[layer].type = layer_type; - parsed_size = layer_funcs[layer_type].pf_load(&network->layers[layer], model_file_context, file_size, network->operands_num); + native_model->layers[layer].type = layer_type; + parsed_size = ff_layer_funcs[layer_type].pf_load(&native_model->layers[layer], model_file_context, file_size, native_model->operands_num); if (!parsed_size) { goto fail; } dnn_size += parsed_size; } - for (int32_t i = 0; i < network->operands_num; ++i){ + for (int32_t i = 0; i < native_model->operands_num; ++i){ DnnOperand *oprd; int32_t name_len; int32_t operand_index = (int32_t)avio_rl32(model_file_context); dnn_size += 4; - if (operand_index >= network->operands_num) { + if (operand_index >= native_model->operands_num) { goto fail; } - oprd = &network->operands[operand_index]; + oprd = &native_model->operands[operand_index]; name_len = (int32_t)avio_rl32(model_file_context); dnn_size += 4; @@ -232,6 +232,8 @@ DNNModel *ff_dnn_load_model_native(const char *model_filename) oprd->dims[dim] = (int32_t)avio_rl32(model_file_context); dnn_size += 4; } + if (oprd->type == DOT_INPUT && oprd->dims[0] != 1) + goto fail; oprd->isNHWC = 1; } @@ -243,8 +245,10 @@ DNNModel *ff_dnn_load_model_native(const char *model_filename) return NULL; } - model->set_input_output = &set_input_output_native; model->get_input = &get_input_native; + model->get_output = &get_output_native; + model->filter_ctx = filter_ctx; + model->func_type = func_type; return model; @@ -254,38 +258,140 @@ fail: return NULL; } -DNNReturnType ff_dnn_execute_model_native(const DNNModel *model, DNNData *outputs, uint32_t nb_output) +static DNNReturnType execute_model_native(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame, + int do_ioproc) { - ConvolutionalNetwork *network = (ConvolutionalNetwork *)model->model; + NativeModel *native_model = model->model; + NativeContext *ctx = &native_model->ctx; int32_t layer; - uint32_t nb = FFMIN(nb_output, network->nb_output); + DNNData input, output; + DnnOperand *oprd = NULL; - if (network->layers_num <= 0 || network->operands_num <= 0) + if (native_model->layers_num <= 0 || native_model->operands_num <= 0) { + av_log(ctx, AV_LOG_ERROR, "No operands or layers in model\n"); return DNN_ERROR; - if (!network->operands[0].data) - return DNN_ERROR; - - for (layer = 0; layer < network->layers_num; ++layer){ - DNNLayerType layer_type = network->layers[layer].type; - layer_funcs[layer_type].pf_exec(network->operands, - network->layers[layer].input_operand_indexes, - network->layers[layer].output_operand_index, - network->layers[layer].params); } - for (uint32_t i = 0; i < nb; ++i) { - DnnOperand *oprd = &network->operands[network->output_indexes[i]]; - outputs[i].data = oprd->data; - outputs[i].height = oprd->dims[1]; - outputs[i].width = oprd->dims[2]; - outputs[i].channels = oprd->dims[3]; - outputs[i].dt = oprd->data_type; + for (int i = 0; i < native_model->operands_num; ++i) { + oprd = &native_model->operands[i]; + if (strcmp(oprd->name, input_name) == 0) { + if (oprd->type != DOT_INPUT) { + av_log(ctx, AV_LOG_ERROR, "Found \"%s\" in model, but it is not input node\n", input_name); + return DNN_ERROR; + } + break; + } + oprd = NULL; + } + if (!oprd) { + av_log(ctx, AV_LOG_ERROR, "Could not find \"%s\" in model\n", input_name); + return DNN_ERROR; + } + + oprd->dims[1] = in_frame->height; + oprd->dims[2] = in_frame->width; + + av_freep(&oprd->data); + oprd->length = ff_calculate_operand_data_length(oprd); + if (oprd->length <= 0) { + av_log(ctx, AV_LOG_ERROR, "The input data length overflow\n"); + return DNN_ERROR; + } + oprd->data = av_malloc(oprd->length); + if (!oprd->data) { + av_log(ctx, AV_LOG_ERROR, "Failed to malloc memory for input data\n"); + return DNN_ERROR; + } + + input.height = oprd->dims[1]; + input.width = oprd->dims[2]; + input.channels = oprd->dims[3]; + input.data = oprd->data; + input.dt = oprd->data_type; + if (do_ioproc) { + if (native_model->model->pre_proc != NULL) { + native_model->model->pre_proc(in_frame, &input, native_model->model->filter_ctx); + } else { + ff_proc_from_frame_to_dnn(in_frame, &input, native_model->model->func_type, ctx); + } + } + + if (nb_output != 1) { + // currently, the filter does not need multiple outputs, + // so we just pending the support until we really need it. + avpriv_report_missing_feature(ctx, "multiple outputs"); + return DNN_ERROR; + } + + for (layer = 0; layer < native_model->layers_num; ++layer){ + DNNLayerType layer_type = native_model->layers[layer].type; + if (ff_layer_funcs[layer_type].pf_exec(native_model->operands, + native_model->layers[layer].input_operand_indexes, + native_model->layers[layer].output_operand_index, + native_model->layers[layer].params, + &native_model->ctx) == DNN_ERROR) { + av_log(ctx, AV_LOG_ERROR, "Failed to execute model\n"); + return DNN_ERROR; + } + } + + for (uint32_t i = 0; i < nb_output; ++i) { + DnnOperand *oprd = NULL; + const char *output_name = output_names[i]; + for (int j = 0; j < native_model->operands_num; ++j) { + if (strcmp(native_model->operands[j].name, output_name) == 0) { + oprd = &native_model->operands[j]; + break; + } + } + + if (oprd == NULL) { + av_log(ctx, AV_LOG_ERROR, "Could not find output in model\n"); + return DNN_ERROR; + } + + output.data = oprd->data; + output.height = oprd->dims[1]; + output.width = oprd->dims[2]; + output.channels = oprd->dims[3]; + output.dt = oprd->data_type; + + if (do_ioproc) { + if (native_model->model->post_proc != NULL) { + native_model->model->post_proc(out_frame, &output, native_model->model->filter_ctx); + } else { + ff_proc_from_dnn_to_frame(out_frame, &output, ctx); + } + } else { + out_frame->width = output.width; + out_frame->height = output.height; + } } return DNN_SUCCESS; } -int32_t calculate_operand_dims_count(const DnnOperand *oprd) +DNNReturnType ff_dnn_execute_model_native(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame) +{ + NativeModel *native_model = model->model; + NativeContext *ctx = &native_model->ctx; + + if (!in_frame) { + av_log(ctx, AV_LOG_ERROR, "in frame is NULL when execute model.\n"); + return DNN_ERROR; + } + + if (!out_frame) { + av_log(ctx, AV_LOG_ERROR, "out frame is NULL when execute model.\n"); + return DNN_ERROR; + } + + return execute_model_native(model, input_name, in_frame, output_names, nb_output, out_frame, 1); +} + +int32_t ff_calculate_operand_dims_count(const DnnOperand *oprd) { int32_t result = 1; for (int i = 0; i < 4; ++i) @@ -294,7 +400,7 @@ int32_t calculate_operand_dims_count(const DnnOperand *oprd) return result; } -int32_t calculate_operand_data_length(const DnnOperand* oprd) +int32_t ff_calculate_operand_data_length(const DnnOperand* oprd) { // currently, we just support DNN_FLOAT uint64_t len = sizeof(float); @@ -308,34 +414,33 @@ int32_t calculate_operand_data_length(const DnnOperand* oprd) void ff_dnn_free_model_native(DNNModel **model) { - ConvolutionalNetwork *network; + NativeModel *native_model; ConvolutionalParams *conv_params; int32_t layer; if (*model) { if ((*model)->model) { - network = (ConvolutionalNetwork *)(*model)->model; - if (network->layers) { - for (layer = 0; layer < network->layers_num; ++layer){ - if (network->layers[layer].type == DLT_CONV2D){ - conv_params = (ConvolutionalParams *)network->layers[layer].params; + native_model = (*model)->model; + if (native_model->layers) { + for (layer = 0; layer < native_model->layers_num; ++layer){ + if (native_model->layers[layer].type == DLT_CONV2D){ + conv_params = (ConvolutionalParams *)native_model->layers[layer].params; av_freep(&conv_params->kernel); av_freep(&conv_params->biases); } - av_freep(&network->layers[layer].params); + av_freep(&native_model->layers[layer].params); } - av_freep(&network->layers); + av_freep(&native_model->layers); } - if (network->operands) { - for (uint32_t operand = 0; operand < network->operands_num; ++operand) - av_freep(&network->operands[operand].data); - av_freep(&network->operands); + if (native_model->operands) { + for (uint32_t operand = 0; operand < native_model->operands_num; ++operand) + av_freep(&native_model->operands[operand].data); + av_freep(&native_model->operands); } - av_freep(&network->output_indexes); - av_freep(&network); + av_freep(&native_model); } av_freep(model); } diff --git a/libavfilter/dnn/dnn_backend_native.h b/libavfilter/dnn/dnn_backend_native.h index 62191ffe8..d313c48f3 100644 --- a/libavfilter/dnn/dnn_backend_native.h +++ b/libavfilter/dnn/dnn_backend_native.h @@ -29,6 +29,7 @@ #include "../dnn_interface.h" #include "libavformat/avio.h" +#include "libavutil/opt.h" /** * the enum value of DNNLayerType should not be changed, @@ -43,10 +44,14 @@ typedef enum { DLT_MAXIMUM = 4, DLT_MATH_BINARY = 5, DLT_MATH_UNARY = 6, + DLT_AVG_POOL = 7, + DLT_DENSE = 8, DLT_COUNT } DNNLayerType; typedef enum {DOT_INPUT = 1, DOT_OUTPUT = 2, DOT_INTERMEDIATE = DOT_INPUT | DOT_OUTPUT} DNNOperandType; +typedef enum {VALID, SAME, SAME_CLAMP_TO_EDGE} DNNPaddingParam; +typedef enum {RELU, TANH, SIGMOID, NONE, LEAKY_RELU} DNNActivationFunc; typedef struct Layer{ DNNLayerType type; @@ -104,24 +109,34 @@ typedef struct InputParams{ int height, width, channels; } InputParams; +typedef struct NativeOptions{ + uint32_t conv2d_threads; +} NativeOptions; + +typedef struct NativeContext { + const AVClass *class; + NativeOptions options; +} NativeContext; + // Represents simple feed-forward convolutional network. -typedef struct ConvolutionalNetwork{ +typedef struct NativeModel{ + NativeContext ctx; + DNNModel *model; Layer *layers; int32_t layers_num; DnnOperand *operands; int32_t operands_num; - int32_t *output_indexes; - uint32_t nb_output; -} ConvolutionalNetwork; +} NativeModel; -DNNModel *ff_dnn_load_model_native(const char *model_filename); +DNNModel *ff_dnn_load_model_native(const char *model_filename, DNNFunctionType func_type, const char *options, AVFilterContext *filter_ctx); -DNNReturnType ff_dnn_execute_model_native(const DNNModel *model, DNNData *outputs, uint32_t nb_output); +DNNReturnType ff_dnn_execute_model_native(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame); void ff_dnn_free_model_native(DNNModel **model); // NOTE: User must check for error (return value <= 0) to handle // case like integer overflow. -int32_t calculate_operand_data_length(const DnnOperand *oprd); -int32_t calculate_operand_dims_count(const DnnOperand *oprd); +int32_t ff_calculate_operand_data_length(const DnnOperand *oprd); +int32_t ff_calculate_operand_dims_count(const DnnOperand *oprd); #endif diff --git a/libavfilter/dnn/dnn_backend_native_layer_avgpool.c b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c new file mode 100644 index 000000000..dcfb8c816 --- /dev/null +++ b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2020 + * + * 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 + * DNN native backend implementation. + */ + +#include "libavutil/avassert.h" +#include "dnn_backend_native_layer_avgpool.h" + +int ff_dnn_load_layer_avg_pool(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +{ + AvgPoolParams *avgpool_params; + int dnn_size = 0; + avgpool_params = av_malloc(sizeof(*avgpool_params)); + if(!avgpool_params) + return 0; + + avgpool_params->strides = (int32_t)avio_rl32(model_file_context); + avgpool_params->padding_method = (int32_t)avio_rl32(model_file_context); + avgpool_params->kernel_size = (int32_t)avio_rl32(model_file_context); + dnn_size += 12; + + if (dnn_size > file_size || avgpool_params->kernel_size <= 0 || avgpool_params->strides <=0){ + av_freep(&avgpool_params); + return 0; + } + + layer->params = avgpool_params; + layer->input_operand_indexes[0] = (int32_t)avio_rl32(model_file_context); + layer->output_operand_index = (int32_t)avio_rl32(model_file_context); + dnn_size += 8; + + if (layer->input_operand_indexes[0] >= operands_num || layer->output_operand_index >= operands_num) { + return 0; + } + return dnn_size; +} + +int ff_dnn_execute_layer_avg_pool(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx) +{ + float *output; + int height_end, width_end, height_radius, width_radius, output_height, output_width, kernel_area; + int32_t input_operand_index = input_operand_indexes[0]; + int number = operands[input_operand_index].dims[0]; + int height = operands[input_operand_index].dims[1]; + int width = operands[input_operand_index].dims[2]; + int channel = operands[input_operand_index].dims[3]; + const float *input = operands[input_operand_index].data; + const AvgPoolParams *avgpool_params = parameters; + + int kernel_strides = avgpool_params->strides; + int src_linesize = width * channel; + DnnOperand *output_operand = &operands[output_operand_index]; + + /** + * When padding_method = SAME, the tensorflow will only padding the hald number of 0 pxiels + * except the remainders. + * Eg: assuming the input height = 1080, the strides = 11, so the remainders = 1080 % 11 = 2 + * and if ksize = 5: it will fill (5 - 2) >> 1 = 1 line before the first line of input image, + * and 5 - 2 - 1 = 2 lines after the last line of input image. + * and if ksize = 7: it will fill (7 - 2) >> 1 = 2 lines before the first line of input image, + * and 7 - 2 - 2 = 3 lines after the last line of input image. + */ + if (avgpool_params->padding_method == SAME) { + height_end = height; + width_end = width; + height_radius = avgpool_params->kernel_size - ((height - 1) % kernel_strides + 1); + width_radius = avgpool_params->kernel_size - ((width - 1) % kernel_strides + 1); + height_radius = height_radius < 0 ? 0 : height_radius >> 1; + width_radius = width_radius < 0 ? 0 : width_radius >> 1; + output_height = ceil(height / (kernel_strides * 1.0)); + output_width = ceil(width / (kernel_strides * 1.0)); + } else { + av_assert0(avgpool_params->padding_method == VALID); + height_end = height - avgpool_params->kernel_size + 1; + width_end = width - avgpool_params->kernel_size + 1; + height_radius = 0; + width_radius = 0; + output_height = ceil((height - avgpool_params->kernel_size + 1) / (kernel_strides * 1.0)); + output_width = ceil((width - avgpool_params->kernel_size + 1) / (kernel_strides * 1.0)); + } + + output_operand->dims[0] = number; + output_operand->dims[1] = output_height; + output_operand->dims[2] = output_width; + // not support pooling in channel dimension now + output_operand->dims[3] = channel; + output_operand->data_type = operands[input_operand_index].data_type; + output_operand->length = ff_calculate_operand_data_length(output_operand); + if (output_operand->length <= 0) { + av_log(ctx, AV_LOG_ERROR, "The output data length overflow\n"); + return DNN_ERROR; + } + output_operand->data = av_realloc(output_operand->data, output_operand->length); + if (!output_operand->data) { + av_log(ctx, AV_LOG_ERROR, "Failed to reallocate memory for output\n"); + return DNN_ERROR; + } + output = output_operand->data; + + for (int y = 0; y < height_end; y += kernel_strides) { + for (int x = 0; x < width_end; x += kernel_strides) { + for (int n_channel = 0; n_channel < channel; ++n_channel) { + output[n_channel] = 0.0; + kernel_area = 0; + for (int kernel_y = 0; kernel_y < avgpool_params->kernel_size; ++kernel_y) { + for (int kernel_x = 0; kernel_x < avgpool_params->kernel_size; ++kernel_x) { + float input_pel; + int y_pos = y + (kernel_y - height_radius); + int x_pos = x + (kernel_x - width_radius); + if (x_pos < 0 || x_pos >= width || y_pos < 0 || y_pos >= height) { + input_pel = 0.0; + } else { + kernel_area++; + input_pel = input[y_pos * src_linesize + x_pos * channel + n_channel]; + } + output[n_channel] += input_pel; + } + } + output[n_channel] /= kernel_area; + } + output += channel; + } + } + + return 0; +} diff --git a/libavfilter/dnn/dnn_backend_native_layer_avgpool.h b/libavfilter/dnn/dnn_backend_native_layer_avgpool.h new file mode 100644 index 000000000..75d9eb187 --- /dev/null +++ b/libavfilter/dnn/dnn_backend_native_layer_avgpool.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 + * + * 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 + * DNN inference functions interface for native backend. + */ + +#ifndef AVFILTER_DNN_DNN_BACKEND_NATIVE_LAYER_AVGPOOL_H +#define AVFILTER_DNN_DNN_BACKEND_NATIVE_LAYER_AVGPOOL_H + +#include "dnn_backend_native.h" + +typedef struct AvgPoolParams{ + int32_t strides, kernel_size; + DNNPaddingParam padding_method; +} AvgPoolParams; + +int ff_dnn_load_layer_avg_pool(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); +int ff_dnn_execute_layer_avg_pool(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx); + +#endif diff --git a/libavfilter/dnn/dnn_backend_native_layer_conv2d.c b/libavfilter/dnn/dnn_backend_native_layer_conv2d.c index a2202e407..7a60aa6a4 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_conv2d.c +++ b/libavfilter/dnn/dnn_backend_native_layer_conv2d.c @@ -19,11 +19,31 @@ */ #include "libavutil/avassert.h" +#include "libavutil/thread.h" +#include "libavutil/cpu.h" #include "dnn_backend_native_layer_conv2d.h" #define CLAMP_TO_EDGE(x, w) ((x) < 0 ? 0 : ((x) >= (w) ? (w - 1) : (x))) -int dnn_load_layer_conv2d(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +//struct to pass parameters +typedef struct ThreadCommonParam{ + DnnOperand *operands; + const int32_t *input_operand_indexes; + int32_t output_operand_index; + const void *parameters; + NativeContext *ctx; + float *output_data; +} ThreadCommonParam; + +typedef struct ThreadParam{ + ThreadCommonParam *thread_common_param; + int thread_start, thread_end; +#if HAVE_PTHREAD_CANCEL + pthread_t thread; +#endif +} ThreadParam; + +int ff_dnn_load_layer_conv2d(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) { ConvolutionalParams *conv_params; int kernel_size; @@ -53,7 +73,7 @@ int dnn_load_layer_conv2d(Layer *layer, AVIOContext *model_file_context, int fil return 0; } - conv_params->kernel = av_malloc(kernel_size * sizeof(float)); + conv_params->kernel = av_malloc_array(kernel_size, sizeof(*conv_params->kernel)); if (!conv_params->kernel) { av_freep(&conv_params); return 0; @@ -64,7 +84,7 @@ int dnn_load_layer_conv2d(Layer *layer, AVIOContext *model_file_context, int fil conv_params->biases = NULL; if (conv_params->has_bias) { - conv_params->biases = av_malloc(conv_params->output_num * sizeof(float)); + conv_params->biases = av_malloc_array(conv_params->output_num, sizeof(*conv_params->biases)); if (!conv_params->biases){ av_freep(&conv_params->kernel); av_freep(&conv_params); @@ -88,17 +108,18 @@ int dnn_load_layer_conv2d(Layer *layer, AVIOContext *model_file_context, int fil return dnn_size; } -int dnn_execute_layer_conv2d(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters) +static void * dnn_execute_layer_conv2d_thread(void *threadarg) { - float *output; - int32_t input_operand_index = input_operand_indexes[0]; - int number = operands[input_operand_index].dims[0]; + //pass parameters + ThreadParam *thread_param = threadarg; + ThreadCommonParam *thread_common_param = thread_param->thread_common_param; + DnnOperand *operands = thread_common_param->operands; + int32_t input_operand_index = thread_common_param->input_operand_indexes[0]; int height = operands[input_operand_index].dims[1]; int width = operands[input_operand_index].dims[2]; int channel = operands[input_operand_index].dims[3]; const float *input = operands[input_operand_index].data; - const ConvolutionalParams *conv_params = (const ConvolutionalParams *)parameters; + const ConvolutionalParams *conv_params = thread_common_param->parameters; int radius = conv_params->kernel_size >> 1; int src_linesize = width * conv_params->input_num; @@ -106,23 +127,12 @@ int dnn_execute_layer_conv2d(DnnOperand *operands, const int32_t *input_operand_ int filter_size = conv_params->kernel_size * filter_linesize; int pad_size = (conv_params->padding_method == VALID) ? (conv_params->kernel_size - 1) / 2 * conv_params->dilation : 0; - DnnOperand *output_operand = &operands[output_operand_index]; - output_operand->dims[0] = number; - output_operand->dims[1] = height - pad_size * 2; - output_operand->dims[2] = width - pad_size * 2; - output_operand->dims[3] = conv_params->output_num; - output_operand->data_type = operands[input_operand_index].data_type; - output_operand->length = calculate_operand_data_length(output_operand); - if (output_operand->length <= 0) - return -1; - output_operand->data = av_realloc(output_operand->data, output_operand->length); - if (!output_operand->data) - return -1; - output = output_operand->data; + float *output = thread_common_param->output_data; + output += (conv_params->output_num) * (width - 2 * pad_size) * (thread_param->thread_start - pad_size); av_assert0(channel == conv_params->input_num); - for (int y = pad_size; y < height - pad_size; ++y) { + for (int y = thread_param->thread_start; y < thread_param->thread_end; ++y) { for (int x = pad_size; x < width - pad_size; ++x) { for (int n_filter = 0; n_filter < conv_params->output_num; ++n_filter) { if (conv_params->has_bias) @@ -170,5 +180,84 @@ int dnn_execute_layer_conv2d(DnnOperand *operands, const int32_t *input_operand_ output += conv_params->output_num; } } - return 0; + return NULL; +} + + +int ff_dnn_execute_layer_conv2d(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx) +{ +#if HAVE_PTHREAD_CANCEL + int thread_num = (ctx->options.conv2d_threads <= 0 || ctx->options.conv2d_threads > av_cpu_count()) + ? (av_cpu_count() + 1) : (ctx->options.conv2d_threads); + int ret = DNN_SUCCESS, thread_stride; + ThreadParam *thread_param; +#else + ThreadParam thread_param = { 0 }; +#endif + ThreadCommonParam thread_common_param; + const ConvolutionalParams *conv_params = parameters; + int height = operands[input_operand_indexes[0]].dims[1]; + int width = operands[input_operand_indexes[0]].dims[2]; + int pad_size = (conv_params->padding_method == VALID) ? (conv_params->kernel_size - 1) / 2 * conv_params->dilation : 0; + DnnOperand *output_operand = &operands[output_operand_index]; + void *tmp; + + output_operand->dims[0] = operands[input_operand_indexes[0]].dims[0]; + output_operand->dims[1] = height - pad_size * 2; + output_operand->dims[2] = width - pad_size * 2; + output_operand->dims[3] = conv_params->output_num; + output_operand->data_type = operands[input_operand_indexes[0]].data_type; + output_operand->length = ff_calculate_operand_data_length(output_operand); + if (output_operand->length <= 0) { + av_log(ctx, AV_LOG_ERROR, "The output data length overflow\n"); + return DNN_ERROR; + } + tmp = av_realloc(output_operand->data, output_operand->length); + if (!tmp) { + av_log(ctx, AV_LOG_ERROR, "Failed to reallocate memory for output\n"); + return DNN_ERROR; + } + output_operand->data = tmp; + thread_common_param.output_data = output_operand->data; + thread_common_param.operands = operands; + thread_common_param.input_operand_indexes = input_operand_indexes; + thread_common_param.output_operand_index = output_operand_index; + thread_common_param.parameters = parameters; + thread_common_param.ctx = ctx; + +#if HAVE_PTHREAD_CANCEL + thread_param = av_malloc_array(thread_num, sizeof(*thread_param)); + if (!thread_param) + return DNN_ERROR; + thread_stride = (height - pad_size * 2) / thread_num; + //create threads + for (int i = 0; i < thread_num; i++){ + thread_param[i].thread_common_param = &thread_common_param; + thread_param[i].thread_start = thread_stride * i + pad_size; + thread_param[i].thread_end = (i == thread_num - 1) ? (height - pad_size) : (thread_param[i].thread_start + thread_stride); + if (pthread_create(&thread_param[i].thread, NULL, + dnn_execute_layer_conv2d_thread, &thread_param[i])) { + thread_num = i; + ret = DNN_ERROR; + break; + } + } + + for (int i = 0; i < thread_num; i++){ + pthread_join(thread_param[i].thread, NULL); + } + + //release memory + av_freep(&thread_param); + + return ret; +#else + thread_param.thread_common_param = &thread_common_param; + thread_param.thread_start = pad_size; + thread_param.thread_end = height - pad_size; + dnn_execute_layer_conv2d_thread(&thread_param); + + return DNN_SUCCESS; +#endif } diff --git a/libavfilter/dnn/dnn_backend_native_layer_conv2d.h b/libavfilter/dnn/dnn_backend_native_layer_conv2d.h index eeb15fdf0..03ca795c6 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_conv2d.h +++ b/libavfilter/dnn/dnn_backend_native_layer_conv2d.h @@ -23,20 +23,18 @@ #include "dnn_backend_native.h" -typedef enum {RELU, TANH, SIGMOID, NONE, LEAKY_RELU} DNNActivationFunc; -typedef enum {VALID, SAME, SAME_CLAMP_TO_EDGE} DNNConvPaddingParam; typedef struct ConvolutionalParams{ int32_t input_num, output_num, kernel_size; DNNActivationFunc activation; - DNNConvPaddingParam padding_method; + DNNPaddingParam padding_method; int32_t dilation; int32_t has_bias; float *kernel; float *biases; } ConvolutionalParams; -int dnn_load_layer_conv2d(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); -int dnn_execute_layer_conv2d(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters); +int ff_dnn_load_layer_conv2d(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); +int ff_dnn_execute_layer_conv2d(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx); #endif diff --git a/libavfilter/dnn/dnn_backend_native_layer_dense.c b/libavfilter/dnn/dnn_backend_native_layer_dense.c new file mode 100644 index 000000000..117590d7b --- /dev/null +++ b/libavfilter/dnn/dnn_backend_native_layer_dense.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2020 + * + * 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/avassert.h" +#include "dnn_backend_native_layer_dense.h" + +int ff_dnn_load_layer_dense(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +{ + DenseParams *dense_params; + int kernel_size; + int dnn_size = 0; + dense_params = av_malloc(sizeof(*dense_params)); + if (!dense_params) + return 0; + + dense_params->activation = (int32_t)avio_rl32(model_file_context); + dense_params->input_num = (int32_t)avio_rl32(model_file_context); + dense_params->output_num = (int32_t)avio_rl32(model_file_context); + dense_params->has_bias = (int32_t)avio_rl32(model_file_context); + dnn_size += 16; + + kernel_size = dense_params->input_num * dense_params->output_num; + dnn_size += kernel_size * 4; + if (dense_params->has_bias) + dnn_size += dense_params->output_num * 4; + + if (dnn_size > file_size || dense_params->input_num <= 0 || + dense_params->output_num <= 0){ + av_freep(&dense_params); + return 0; + } + + dense_params->kernel = av_malloc(kernel_size * sizeof(float)); + if (!dense_params->kernel) { + av_freep(&dense_params); + return 0; + } + for (int i = 0; i < kernel_size; ++i) { + dense_params->kernel[i] = av_int2float(avio_rl32(model_file_context)); + } + + dense_params->biases = NULL; + if (dense_params->has_bias) { + dense_params->biases = av_malloc(dense_params->output_num * sizeof(float)); + if (!dense_params->biases){ + av_freep(&dense_params->kernel); + av_freep(&dense_params); + return 0; + } + for (int i = 0; i < dense_params->output_num; ++i){ + dense_params->biases[i] = av_int2float(avio_rl32(model_file_context)); + } + } + + layer->params = dense_params; + + layer->input_operand_indexes[0] = (int32_t)avio_rl32(model_file_context); + layer->output_operand_index = (int32_t)avio_rl32(model_file_context); + dnn_size += 8; + + if (layer->input_operand_indexes[0] >= operands_num || layer->output_operand_index >= operands_num) { + return 0; + } + + return dnn_size; +} + +int ff_dnn_execute_layer_dense(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx) +{ + float *output; + int32_t input_operand_index = input_operand_indexes[0]; + int number = operands[input_operand_index].dims[0]; + int height = operands[input_operand_index].dims[1]; + int width = operands[input_operand_index].dims[2]; + int channel = operands[input_operand_index].dims[3]; + const float *input = operands[input_operand_index].data; + const DenseParams *dense_params = parameters; + + int src_linesize = width * channel; + DnnOperand *output_operand = &operands[output_operand_index]; + output_operand->dims[0] = number; + output_operand->dims[1] = height; + output_operand->dims[2] = width; + output_operand->dims[3] = dense_params->output_num; + output_operand->data_type = operands[input_operand_index].data_type; + output_operand->length = ff_calculate_operand_data_length(output_operand); + if (output_operand->length <= 0) { + av_log(ctx, AV_LOG_ERROR, "The output data length overflow\n"); + return DNN_ERROR; + } + output_operand->data = av_realloc(output_operand->data, output_operand->length); + if (!output_operand->data) { + av_log(ctx, AV_LOG_ERROR, "Failed to reallocate memory for output\n"); + return DNN_ERROR; + } + output = output_operand->data; + + av_assert0(channel == dense_params->input_num); + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + for (int n_filter = 0; n_filter < dense_params->output_num; ++n_filter) { + if (dense_params->has_bias) + output[n_filter] = dense_params->biases[n_filter]; + else + output[n_filter] = 0.f; + + for (int ch = 0; ch < dense_params->input_num; ++ch) { + float input_pel; + input_pel = input[y * src_linesize + x * dense_params->input_num + ch]; + output[n_filter] += input_pel * dense_params->kernel[n_filter*dense_params->input_num + ch]; + } + switch (dense_params->activation){ + case RELU: + output[n_filter] = FFMAX(output[n_filter], 0.0); + break; + case TANH: + output[n_filter] = 2.0f / (1.0f + exp(-2.0f * output[n_filter])) - 1.0f; + break; + case SIGMOID: + output[n_filter] = 1.0f / (1.0f + exp(-output[n_filter])); + break; + case NONE: + break; + case LEAKY_RELU: + output[n_filter] = FFMAX(output[n_filter], 0.0) + 0.2 * FFMIN(output[n_filter], 0.0); + } + } + output += dense_params->output_num; + } + } + return 0; +} diff --git a/libavfilter/dnn/dnn_backend_native_layer_dense.h b/libavfilter/dnn/dnn_backend_native_layer_dense.h new file mode 100644 index 000000000..86248856a --- /dev/null +++ b/libavfilter/dnn/dnn_backend_native_layer_dense.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 + * + * 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 AVFILTER_DNN_DNN_BACKEND_NATIVE_LAYER_DENSE_H +#define AVFILTER_DNN_DNN_BACKEND_NATIVE_LAYER_DENSE_H + +#include "dnn_backend_native.h" + +typedef struct DenseParams{ + int32_t input_num, output_num; + DNNActivationFunc activation; + int32_t has_bias; + float *kernel; + float *biases; +} DenseParams; + +int ff_dnn_load_layer_dense(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); +int ff_dnn_execute_layer_dense(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx); +#endif diff --git a/libavfilter/dnn/dnn_backend_native_layer_depth2space.c b/libavfilter/dnn/dnn_backend_native_layer_depth2space.c index 2c8bddf23..2fde6d1ba 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_depth2space.c +++ b/libavfilter/dnn/dnn_backend_native_layer_depth2space.c @@ -27,7 +27,7 @@ #include "libavutil/avassert.h" #include "dnn_backend_native_layer_depth2space.h" -int dnn_load_layer_depth2space(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +int ff_dnn_load_layer_depth2space(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) { DepthToSpaceParams *params; int dnn_size = 0; @@ -49,11 +49,11 @@ int dnn_load_layer_depth2space(Layer *layer, AVIOContext *model_file_context, in return dnn_size; } -int dnn_execute_layer_depth2space(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters) +int ff_dnn_execute_layer_depth2space(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx) { float *output; - const DepthToSpaceParams *params = (const DepthToSpaceParams *)parameters; + const DepthToSpaceParams *params = parameters; int block_size = params->block_size; int32_t input_operand_index = input_operand_indexes[0]; int number = operands[input_operand_index].dims[0]; @@ -74,12 +74,16 @@ int dnn_execute_layer_depth2space(DnnOperand *operands, const int32_t *input_ope output_operand->dims[2] = width * block_size; output_operand->dims[3] = new_channels; output_operand->data_type = operands[input_operand_index].data_type; - output_operand->length = calculate_operand_data_length(output_operand); - if (output_operand->length <= 0) - return -1; + output_operand->length = ff_calculate_operand_data_length(output_operand); + if (output_operand->length <= 0) { + av_log(ctx, AV_LOG_ERROR, "The output data length overflow\n"); + return DNN_ERROR; + } output_operand->data = av_realloc(output_operand->data, output_operand->length); - if (!output_operand->data) - return -1; + if (!output_operand->data) { + av_log(ctx, AV_LOG_ERROR, "Failed to reallocate memory for output\n"); + return DNN_ERROR; + } output = output_operand->data; for (y = 0; y < height; ++y){ diff --git a/libavfilter/dnn/dnn_backend_native_layer_depth2space.h b/libavfilter/dnn/dnn_backend_native_layer_depth2space.h index b2901e014..ef5939444 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_depth2space.h +++ b/libavfilter/dnn/dnn_backend_native_layer_depth2space.h @@ -34,8 +34,8 @@ typedef struct DepthToSpaceParams{ int block_size; } DepthToSpaceParams; -int dnn_load_layer_depth2space(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); -int dnn_execute_layer_depth2space(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters); +int ff_dnn_load_layer_depth2space(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); +int ff_dnn_execute_layer_depth2space(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx); #endif diff --git a/libavfilter/dnn/dnn_backend_native_layer_mathbinary.c b/libavfilter/dnn/dnn_backend_native_layer_mathbinary.c index dd42c329a..1c33b4633 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_mathbinary.c +++ b/libavfilter/dnn/dnn_backend_native_layer_mathbinary.c @@ -27,22 +27,90 @@ #include "libavutil/avassert.h" #include "dnn_backend_native_layer_mathbinary.h" -int dnn_load_layer_math_binary(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +typedef float (*FunType)(float src0, float src1); + +static float sub(float src0, float src1) { - DnnLayerMathBinaryParams *params; + return src0 - src1; +} +static float add(float src0, float src1) +{ + return src0 + src1; +} +static float mul(float src0, float src1) +{ + return src0 * src1; +} +static float realdiv(float src0, float src1) +{ + return src0 / src1; +} +static float minimum(float src0, float src1) +{ + return FFMIN(src0, src1); +} +static float floormod(float src0, float src1) +{ + return (float)((int)(src0) % (int)(src1)); +} + +static void math_binary_commutative(FunType pfun, const DnnLayerMathBinaryParams *params, const DnnOperand *input, DnnOperand *output, DnnOperand *operands, const int32_t *input_operand_indexes) +{ + int dims_count; + const float *src; + float *dst; + dims_count = ff_calculate_operand_dims_count(output); + src = input->data; + dst = output->data; + if (params->input0_broadcast || params->input1_broadcast) { + for (int i = 0; i < dims_count; ++i) { + dst[i] = pfun(params->v, src[i]); + } + } else { + const DnnOperand *input1 = &operands[input_operand_indexes[1]]; + const float *src1 = input1->data; + for (int i = 0; i < dims_count; ++i) { + dst[i] = pfun(src[i], src1[i]); + } + } +} +static void math_binary_not_commutative(FunType pfun, const DnnLayerMathBinaryParams *params, const DnnOperand *input, DnnOperand *output, DnnOperand *operands, const int32_t *input_operand_indexes) +{ + int dims_count; + const float *src; + float *dst; + dims_count = ff_calculate_operand_dims_count(output); + src = input->data; + dst = output->data; + if (params->input0_broadcast) { + for (int i = 0; i < dims_count; ++i) { + dst[i] = pfun(params->v, src[i]); + } + } else if (params->input1_broadcast) { + for (int i = 0; i < dims_count; ++i) { + dst[i] = pfun(src[i], params->v); + } + } else { + const DnnOperand *input1 = &operands[input_operand_indexes[1]]; + const float *src1 = input1->data; + for (int i = 0; i < dims_count; ++i) { + dst[i] = pfun(src[i], src1[i]); + } + } +} +int ff_dnn_load_layer_math_binary(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +{ + DnnLayerMathBinaryParams params = { 0 }; int dnn_size = 0; int input_index = 0; - params = av_malloc(sizeof(*params)); - if (!params) - return 0; - params->bin_op = (int32_t)avio_rl32(model_file_context); + params.bin_op = (int32_t)avio_rl32(model_file_context); dnn_size += 4; - params->input0_broadcast = (int32_t)avio_rl32(model_file_context); + params.input0_broadcast = (int32_t)avio_rl32(model_file_context); dnn_size += 4; - if (params->input0_broadcast) { - params->v = av_int2float(avio_rl32(model_file_context)); + if (params.input0_broadcast) { + params.v = av_int2float(avio_rl32(model_file_context)); } else { layer->input_operand_indexes[input_index] = (int32_t)avio_rl32(model_file_context); if (layer->input_operand_indexes[input_index] >= operands_num) { @@ -52,10 +120,10 @@ int dnn_load_layer_math_binary(Layer *layer, AVIOContext *model_file_context, in } dnn_size += 4; - params->input1_broadcast = (int32_t)avio_rl32(model_file_context); + params.input1_broadcast = (int32_t)avio_rl32(model_file_context); dnn_size += 4; - if (params->input1_broadcast) { - params->v = av_int2float(avio_rl32(model_file_context)); + if (params.input1_broadcast) { + params.v = av_int2float(avio_rl32(model_file_context)); } else { layer->input_operand_indexes[input_index] = (int32_t)avio_rl32(model_file_context); if (layer->input_operand_indexes[input_index] >= operands_num) { @@ -67,115 +135,60 @@ int dnn_load_layer_math_binary(Layer *layer, AVIOContext *model_file_context, in layer->output_operand_index = (int32_t)avio_rl32(model_file_context); dnn_size += 4; - layer->params = params; if (layer->output_operand_index >= operands_num) { return 0; } + layer->params = av_memdup(¶ms, sizeof(params)); + if (!layer->params) + return 0; return dnn_size; } -int dnn_execute_layer_math_binary(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters) +int ff_dnn_execute_layer_math_binary(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx) { const DnnOperand *input = &operands[input_operand_indexes[0]]; DnnOperand *output = &operands[output_operand_index]; - const DnnLayerMathBinaryParams *params = (const DnnLayerMathBinaryParams *)parameters; - int dims_count; - const float *src; - float *dst; + const DnnLayerMathBinaryParams *params = parameters; for (int i = 0; i < 4; ++i) output->dims[i] = input->dims[i]; output->data_type = input->data_type; - output->length = calculate_operand_data_length(output); - if (output->length <= 0) + output->length = ff_calculate_operand_data_length(output); + if (output->length <= 0) { + av_log(ctx, AV_LOG_ERROR, "The output data length overflow\n"); return DNN_ERROR; + } output->data = av_realloc(output->data, output->length); - if (!output->data) + if (!output->data) { + av_log(ctx, AV_LOG_ERROR, "Failed to reallocate memory for output\n"); return DNN_ERROR; - - dims_count = calculate_operand_dims_count(output); - src = input->data; - dst = output->data; + } switch (params->bin_op) { case DMBO_SUB: - if (params->input0_broadcast) { - for (int i = 0; i < dims_count; ++i) { - dst[i] = params->v - src[i]; - } - } else if (params->input1_broadcast) { - for (int i = 0; i < dims_count; ++i) { - dst[i] = src[i] - params->v; - } - } else { - const DnnOperand *input1 = &operands[input_operand_indexes[1]]; - const float *src1 = input1->data; - for (int i = 0; i < dims_count; ++i) { - dst[i] = src[i] - src1[i]; - } - } + math_binary_not_commutative(sub, params, input, output, operands, input_operand_indexes); return 0; case DMBO_ADD: - if (params->input0_broadcast || params->input1_broadcast) { - for (int i = 0; i < dims_count; ++i) { - dst[i] = params->v + src[i]; - } - } else { - const DnnOperand *input1 = &operands[input_operand_indexes[1]]; - const float *src1 = input1->data; - for (int i = 0; i < dims_count; ++i) { - dst[i] = src[i] + src1[i]; - } - } + math_binary_commutative(add, params, input, output, operands, input_operand_indexes); return 0; case DMBO_MUL: - if (params->input0_broadcast || params->input1_broadcast) { - for (int i = 0; i < dims_count; ++i) { - dst[i] = params->v * src[i]; - } - } else { - const DnnOperand *input1 = &operands[input_operand_indexes[1]]; - const float *src1 = input1->data; - for (int i = 0; i < dims_count; ++i) { - dst[i] = src[i] * src1[i]; - } - } + math_binary_commutative(mul, params, input, output, operands, input_operand_indexes); return 0; case DMBO_REALDIV: - if (params->input0_broadcast) { - for (int i = 0; i < dims_count; ++i) { - dst[i] = params->v / src[i]; - } - } else if (params->input1_broadcast) { - for (int i = 0; i < dims_count; ++i) { - dst[i] = src[i] / params->v; - } - } else { - const DnnOperand *input1 = &operands[input_operand_indexes[1]]; - const float *src1 = input1->data; - for (int i = 0; i < dims_count; ++i) { - dst[i] = src[i] / src1[i]; - } - } + math_binary_not_commutative(realdiv, params, input, output, operands, input_operand_indexes); return 0; case DMBO_MINIMUM: - if (params->input0_broadcast || params->input1_broadcast) { - for (int i = 0; i < dims_count; ++i) { - dst[i] = FFMIN(params->v, src[i]); - } - } else { - const DnnOperand *input1 = &operands[input_operand_indexes[1]]; - const float *src1 = input1->data; - for (int i = 0; i < dims_count; ++i) { - dst[i] = FFMIN(src[i], src1[i]); - } - } + math_binary_commutative(minimum, params, input, output, operands, input_operand_indexes); + return 0; + case DMBO_FLOORMOD: + math_binary_not_commutative(floormod, params, input, output, operands, input_operand_indexes); return 0; default: - return -1; + av_log(ctx, AV_LOG_ERROR, "Unmatch math binary operator\n"); + return DNN_ERROR; } } diff --git a/libavfilter/dnn/dnn_backend_native_layer_mathbinary.h b/libavfilter/dnn/dnn_backend_native_layer_mathbinary.h index 0acf3b0ea..eee294b00 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_mathbinary.h +++ b/libavfilter/dnn/dnn_backend_native_layer_mathbinary.h @@ -36,6 +36,7 @@ typedef enum { DMBO_MUL = 2, DMBO_REALDIV = 3, DMBO_MINIMUM = 4, + DMBO_FLOORMOD = 5, DMBO_COUNT } DNNMathBinaryOperation; @@ -46,8 +47,8 @@ typedef struct DnnLayerMathBinaryParams{ float v; } DnnLayerMathBinaryParams; -int dnn_load_layer_math_binary(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); -int dnn_execute_layer_math_binary(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters); +int ff_dnn_load_layer_math_binary(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); +int ff_dnn_execute_layer_math_binary(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx); #endif diff --git a/libavfilter/dnn/dnn_backend_native_layer_mathunary.c b/libavfilter/dnn/dnn_backend_native_layer_mathunary.c index 6f02faef7..1bb05d02a 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_mathunary.c +++ b/libavfilter/dnn/dnn_backend_native_layer_mathunary.c @@ -23,11 +23,13 @@ * DNN native backend implementation. */ +#include + #include "dnn_backend_native.h" #include "libavutil/avassert.h" #include "dnn_backend_native_layer_mathunary.h" -int dnn_load_layer_math_unary(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +int ff_dnn_load_layer_math_unary(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) { DnnLayerMathUnaryParams *params; int dnn_size = 0; @@ -50,12 +52,12 @@ int dnn_load_layer_math_unary(Layer *layer, AVIOContext *model_file_context, int } -int dnn_execute_layer_math_unary(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters) +int ff_dnn_execute_layer_math_unary(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx) { const DnnOperand *input = &operands[input_operand_indexes[0]]; DnnOperand *output = &operands[output_operand_index]; - const DnnLayerMathUnaryParams *params = (const DnnLayerMathUnaryParams *)parameters; + const DnnLayerMathUnaryParams *params = parameters; int dims_count; const float *src; float *dst; @@ -64,14 +66,18 @@ int dnn_execute_layer_math_unary(DnnOperand *operands, const int32_t *input_oper output->dims[i] = input->dims[i]; output->data_type = input->data_type; - output->length = calculate_operand_data_length(output); - if (output->length <= 0) + output->length = ff_calculate_operand_data_length(output); + if (output->length <= 0) { + av_log(ctx, AV_LOG_ERROR, "The output data length overflow\n"); return DNN_ERROR; + } output->data = av_realloc(output->data, output->length); - if (!output->data) + if (!output->data) { + av_log(ctx, AV_LOG_ERROR, "Failed to reallocate memory for output\n"); return DNN_ERROR; + } - dims_count = calculate_operand_dims_count(output); + dims_count = ff_calculate_operand_dims_count(output); src = input->data; dst = output->data; @@ -80,7 +86,68 @@ int dnn_execute_layer_math_unary(DnnOperand *operands, const int32_t *input_oper for (int i = 0; i < dims_count; ++i) dst[i] = FFABS(src[i]); return 0; + case DMUO_SIN: + for (int i = 0; i < dims_count; ++i) + dst[i] = sin(src[i]); + return 0; + case DMUO_COS: + for (int i = 0; i < dims_count; ++i) + dst[i] = cos(src[i]); + return 0; + case DMUO_TAN: + for (int i = 0; i < dims_count; ++i) + dst[i] = tan(src[i]); + return 0; + case DMUO_ASIN: + for (int i = 0; i < dims_count; ++i) + dst[i] = asin(src[i]); + return 0; + case DMUO_ACOS: + for (int i = 0; i < dims_count; ++i) + dst[i] = acos(src[i]); + return 0; + case DMUO_ATAN: + for (int i = 0; i < dims_count; ++i) + dst[i] = atan(src[i]); + return 0; + case DMUO_SINH: + for (int i = 0; i < dims_count; ++i) + dst[i] = sinh(src[i]); + return 0; + case DMUO_COSH: + for (int i = 0; i < dims_count; ++i) + dst[i] = cosh(src[i]); + return 0; + case DMUO_TANH: + for (int i = 0; i < dims_count; ++i) + dst[i] = tanh(src[i]); + return 0; + case DMUO_ASINH: + for (int i = 0; i < dims_count; ++i) + dst[i] = asinh(src[i]); + return 0; + case DMUO_ACOSH: + for (int i = 0; i < dims_count; ++i) + dst[i] = acosh(src[i]); + return 0; + case DMUO_ATANH: + for (int i = 0; i < dims_count; ++i) + dst[i] = atanh(src[i]); + return 0; + case DMUO_CEIL: + for (int i = 0; i < dims_count; ++i) + dst[i] = ceil(src[i]); + return 0; + case DMUO_FLOOR: + for (int i = 0; i < dims_count; ++i) + dst[i] = floor(src[i]); + return 0; + case DMUO_ROUND: + for (int i = 0; i < dims_count; ++i) + dst[i] = round(src[i]); + return 0; default: - return -1; + av_log(ctx, AV_LOG_ERROR, "Unmatch math unary operator\n"); + return DNN_ERROR; } } diff --git a/libavfilter/dnn/dnn_backend_native_layer_mathunary.h b/libavfilter/dnn/dnn_backend_native_layer_mathunary.h index a9a8a0d30..2199931e6 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_mathunary.h +++ b/libavfilter/dnn/dnn_backend_native_layer_mathunary.h @@ -31,6 +31,21 @@ typedef enum { DMUO_ABS = 0, + DMUO_SIN = 1, + DMUO_COS = 2, + DMUO_TAN = 3, + DMUO_ASIN = 4, + DMUO_ACOS = 5, + DMUO_ATAN = 6, + DMUO_SINH = 7, + DMUO_COSH = 8, + DMUO_TANH = 9, + DMUO_ASINH = 10, + DMUO_ACOSH = 11, + DMUO_ATANH = 12, + DMUO_CEIL = 13, + DMUO_FLOOR = 14, + DMUO_ROUND = 15, DMUO_COUNT } DNNMathUnaryOperation; @@ -38,8 +53,8 @@ typedef struct DnnLayerMathUnaryParams{ DNNMathUnaryOperation un_op; } DnnLayerMathUnaryParams; -int dnn_load_layer_math_unary(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); -int dnn_execute_layer_math_unary(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters); +int ff_dnn_load_layer_math_unary(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); +int ff_dnn_execute_layer_math_unary(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx); #endif diff --git a/libavfilter/dnn/dnn_backend_native_layer_maximum.c b/libavfilter/dnn/dnn_backend_native_layer_maximum.c index cdddfdd87..65af55376 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_maximum.c +++ b/libavfilter/dnn/dnn_backend_native_layer_maximum.c @@ -27,7 +27,7 @@ #include "libavutil/avassert.h" #include "dnn_backend_native_layer_maximum.h" -int dnn_load_layer_maximum(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +int ff_dnn_load_layer_maximum(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) { DnnLayerMaximumParams *params; int dnn_size = 0; @@ -49,12 +49,12 @@ int dnn_load_layer_maximum(Layer *layer, AVIOContext *model_file_context, int fi return dnn_size; } -int dnn_execute_layer_maximum(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters) +int ff_dnn_execute_layer_maximum(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx) { const DnnOperand *input = &operands[input_operand_indexes[0]]; DnnOperand *output = &operands[output_operand_index]; - const DnnLayerMaximumParams *params = (const DnnLayerMaximumParams *)parameters; + const DnnLayerMaximumParams *params = parameters; int dims_count; const float *src; float *dst; @@ -63,14 +63,18 @@ int dnn_execute_layer_maximum(DnnOperand *operands, const int32_t *input_operand output->dims[i] = input->dims[i]; output->data_type = input->data_type; - output->length = calculate_operand_data_length(output); - if (output->length <= 0) + output->length = ff_calculate_operand_data_length(output); + if (output->length <= 0) { + av_log(ctx, AV_LOG_ERROR, "The output data length overflow\n"); return DNN_ERROR; + } output->data = av_realloc(output->data, output->length); - if (!output->data) + if (!output->data) { + av_log(ctx, AV_LOG_ERROR, "Failed to reallocate memory for output\n"); return DNN_ERROR; + } - dims_count = calculate_operand_dims_count(output); + dims_count = ff_calculate_operand_dims_count(output); src = input->data; dst = output->data; for (int i = 0; i < dims_count; ++i) diff --git a/libavfilter/dnn/dnn_backend_native_layer_maximum.h b/libavfilter/dnn/dnn_backend_native_layer_maximum.h index c049c63fd..523acbe05 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_maximum.h +++ b/libavfilter/dnn/dnn_backend_native_layer_maximum.h @@ -37,8 +37,8 @@ typedef struct DnnLayerMaximumParams{ }val; } DnnLayerMaximumParams; -int dnn_load_layer_maximum(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); -int dnn_execute_layer_maximum(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters); +int ff_dnn_load_layer_maximum(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); +int ff_dnn_execute_layer_maximum(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx); #endif diff --git a/libavfilter/dnn/dnn_backend_native_layer_pad.c b/libavfilter/dnn/dnn_backend_native_layer_pad.c index feaab001e..a60451a8d 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_pad.c +++ b/libavfilter/dnn/dnn_backend_native_layer_pad.c @@ -22,7 +22,7 @@ #include "libavutil/avassert.h" #include "dnn_backend_native_layer_pad.h" -int dnn_load_layer_pad(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +int ff_dnn_load_layer_pad(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) { LayerPadParams *params; int dnn_size = 0; @@ -75,13 +75,13 @@ static int after_get_buddy(int given, int border, LayerPadModeParam mode) } } -int dnn_execute_layer_pad(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters) +int ff_dnn_execute_layer_pad(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx) { int32_t before_paddings; int32_t after_paddings; float* output; - const LayerPadParams *params = (const LayerPadParams *)parameters; + const LayerPadParams *params = parameters; // suppose format is int32_t input_operand_index = input_operand_indexes[0]; @@ -110,12 +110,16 @@ int dnn_execute_layer_pad(DnnOperand *operands, const int32_t *input_operand_ind output_operand->dims[2] = new_width; output_operand->dims[3] = new_channel; output_operand->data_type = operands[input_operand_index].data_type; - output_operand->length = calculate_operand_data_length(output_operand); - if (output_operand->length <= 0) - return -1; + output_operand->length = ff_calculate_operand_data_length(output_operand); + if (output_operand->length <= 0) { + av_log(ctx, AV_LOG_ERROR, "The output data length overflow\n"); + return DNN_ERROR; + } output_operand->data = av_realloc(output_operand->data, output_operand->length); - if (!output_operand->data) - return -1; + if (!output_operand->data) { + av_log(ctx, AV_LOG_ERROR, "Failed to reallocate memory for output\n"); + return DNN_ERROR; + } output = output_operand->data; // copy the original data diff --git a/libavfilter/dnn/dnn_backend_native_layer_pad.h b/libavfilter/dnn/dnn_backend_native_layer_pad.h index 18e05bdd5..4f76c67c3 100644 --- a/libavfilter/dnn/dnn_backend_native_layer_pad.h +++ b/libavfilter/dnn/dnn_backend_native_layer_pad.h @@ -36,8 +36,8 @@ typedef struct LayerPadParams{ float constant_values; } LayerPadParams; -int dnn_load_layer_pad(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); -int dnn_execute_layer_pad(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters); +int ff_dnn_load_layer_pad(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); +int ff_dnn_execute_layer_pad(DnnOperand *operands, const int32_t *input_operand_indexes, + int32_t output_operand_index, const void *parameters, NativeContext *ctx); #endif diff --git a/libavfilter/dnn/dnn_backend_native_layers.c b/libavfilter/dnn/dnn_backend_native_layers.c index 70f9a5f95..492939fd3 100644 --- a/libavfilter/dnn/dnn_backend_native_layers.c +++ b/libavfilter/dnn/dnn_backend_native_layers.c @@ -26,13 +26,17 @@ #include "dnn_backend_native_layer_maximum.h" #include "dnn_backend_native_layer_mathbinary.h" #include "dnn_backend_native_layer_mathunary.h" +#include "dnn_backend_native_layer_avgpool.h" +#include "dnn_backend_native_layer_dense.h" -LayerFunc layer_funcs[DLT_COUNT] = { +const LayerFunc ff_layer_funcs[DLT_COUNT] = { {NULL, NULL}, - {dnn_execute_layer_conv2d, dnn_load_layer_conv2d}, - {dnn_execute_layer_depth2space, dnn_load_layer_depth2space}, - {dnn_execute_layer_pad, dnn_load_layer_pad}, - {dnn_execute_layer_maximum, dnn_load_layer_maximum}, - {dnn_execute_layer_math_binary, dnn_load_layer_math_binary}, - {dnn_execute_layer_math_unary, dnn_load_layer_math_unary}, + {ff_dnn_execute_layer_conv2d, ff_dnn_load_layer_conv2d}, + {ff_dnn_execute_layer_depth2space, ff_dnn_load_layer_depth2space}, + {ff_dnn_execute_layer_pad, ff_dnn_load_layer_pad}, + {ff_dnn_execute_layer_maximum, ff_dnn_load_layer_maximum}, + {ff_dnn_execute_layer_math_binary, ff_dnn_load_layer_math_binary}, + {ff_dnn_execute_layer_math_unary, ff_dnn_load_layer_math_unary}, + {ff_dnn_execute_layer_avg_pool, ff_dnn_load_layer_avg_pool}, + {ff_dnn_execute_layer_dense, ff_dnn_load_layer_dense}, }; diff --git a/libavfilter/dnn/dnn_backend_native_layers.h b/libavfilter/dnn/dnn_backend_native_layers.h index b696e9c6f..bbd02927c 100644 --- a/libavfilter/dnn/dnn_backend_native_layers.h +++ b/libavfilter/dnn/dnn_backend_native_layers.h @@ -25,7 +25,7 @@ #include "dnn_backend_native.h" typedef int (*LAYER_EXEC_FUNC)(DnnOperand *operands, const int32_t *input_operand_indexes, - int32_t output_operand_index, const void *parameters); + int32_t output_operand_index, const void *parameters, NativeContext *ctx); typedef int (*LAYER_LOAD_FUNC)(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num); typedef struct LayerFunc { @@ -33,6 +33,6 @@ typedef struct LayerFunc { LAYER_LOAD_FUNC pf_load; }LayerFunc; -extern LayerFunc layer_funcs[DLT_COUNT]; +extern const LayerFunc ff_layer_funcs[DLT_COUNT]; #endif diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c new file mode 100644 index 000000000..9a47d74c1 --- /dev/null +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -0,0 +1,814 @@ +/* + * Copyright (c) 2020 + * + * 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 + * DNN OpenVINO backend implementation. + */ + +#include "dnn_backend_openvino.h" +#include "dnn_io_proc.h" +#include "libavformat/avio.h" +#include "libavutil/avassert.h" +#include "libavutil/opt.h" +#include "libavutil/avstring.h" +#include "../internal.h" +#include "queue.h" +#include "safe_queue.h" +#include + +typedef struct OVOptions{ + char *device_type; + int nireq; + int batch_size; + int input_resizable; +} OVOptions; + +typedef struct OVContext { + const AVClass *class; + OVOptions options; +} OVContext; + +typedef struct OVModel{ + OVContext ctx; + DNNModel *model; + ie_core_t *core; + ie_network_t *network; + ie_executable_network_t *exe_network; + ie_infer_request_t *infer_request; + + /* for async execution */ + SafeQueue *request_queue; // holds RequestItem + Queue *task_queue; // holds TaskItem +} OVModel; + +typedef struct TaskItem { + OVModel *ov_model; + const char *input_name; + AVFrame *in_frame; + const char *output_name; + AVFrame *out_frame; + int do_ioproc; + int async; + int done; +} TaskItem; + +typedef struct RequestItem { + ie_infer_request_t *infer_request; + TaskItem **tasks; + int task_count; + ie_complete_call_back_t callback; +} RequestItem; + +#define APPEND_STRING(generated_string, iterate_string) \ + generated_string = generated_string ? av_asprintf("%s %s", generated_string, iterate_string) : \ + av_asprintf("%s", iterate_string); + +#define OFFSET(x) offsetof(OVContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM +static const AVOption dnn_openvino_options[] = { + { "device", "device to run model", OFFSET(options.device_type), AV_OPT_TYPE_STRING, { .str = "CPU" }, 0, 0, FLAGS }, + { "nireq", "number of request", OFFSET(options.nireq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, + { "batch_size", "batch size per request", OFFSET(options.batch_size), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 1000, FLAGS}, + { "input_resizable", "can input be resizable or not", OFFSET(options.input_resizable), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(dnn_openvino); + +static DNNDataType precision_to_datatype(precision_e precision) +{ + switch (precision) + { + case FP32: + return DNN_FLOAT; + case U8: + return DNN_UINT8; + default: + av_assert0(!"not supported yet."); + return DNN_FLOAT; + } +} + +static int get_datatype_size(DNNDataType dt) +{ + switch (dt) + { + case DNN_FLOAT: + return sizeof(float); + case DNN_UINT8: + return sizeof(uint8_t); + default: + av_assert0(!"not supported yet."); + return 1; + } +} + +static DNNReturnType fill_model_input_ov(OVModel *ov_model, RequestItem *request) +{ + dimensions_t dims; + precision_e precision; + ie_blob_buffer_t blob_buffer; + OVContext *ctx = &ov_model->ctx; + IEStatusCode status; + DNNData input; + ie_blob_t *input_blob = NULL; + TaskItem *task = request->tasks[0]; + + status = ie_infer_request_get_blob(request->infer_request, task->input_name, &input_blob); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to get input blob with name %s\n", task->input_name); + return DNN_ERROR; + } + + status |= ie_blob_get_dims(input_blob, &dims); + status |= ie_blob_get_precision(input_blob, &precision); + if (status != OK) { + ie_blob_free(&input_blob); + av_log(ctx, AV_LOG_ERROR, "Failed to get input blob dims/precision\n"); + return DNN_ERROR; + } + + status = ie_blob_get_buffer(input_blob, &blob_buffer); + if (status != OK) { + ie_blob_free(&input_blob); + av_log(ctx, AV_LOG_ERROR, "Failed to get input blob buffer\n"); + return DNN_ERROR; + } + + input.height = dims.dims[2]; + input.width = dims.dims[3]; + input.channels = dims.dims[1]; + input.data = blob_buffer.buffer; + input.dt = precision_to_datatype(precision); + // all models in openvino open model zoo use BGR as input, + // change to be an option when necessary. + input.order = DCO_BGR; + + av_assert0(request->task_count <= dims.dims[0]); + for (int i = 0; i < request->task_count; ++i) { + task = request->tasks[i]; + if (task->do_ioproc) { + if (ov_model->model->pre_proc != NULL) { + ov_model->model->pre_proc(task->in_frame, &input, ov_model->model->filter_ctx); + } else { + ff_proc_from_frame_to_dnn(task->in_frame, &input, ov_model->model->func_type, ctx); + } + } + input.data = (uint8_t *)input.data + + input.width * input.height * input.channels * get_datatype_size(input.dt); + } + ie_blob_free(&input_blob); + + return DNN_SUCCESS; +} + +static void infer_completion_callback(void *args) +{ + dimensions_t dims; + precision_e precision; + IEStatusCode status; + RequestItem *request = args; + TaskItem *task = request->tasks[0]; + SafeQueue *requestq = task->ov_model->request_queue; + ie_blob_t *output_blob = NULL; + ie_blob_buffer_t blob_buffer; + DNNData output; + OVContext *ctx = &task->ov_model->ctx; + + status = ie_infer_request_get_blob(request->infer_request, task->output_name, &output_blob); + if (status != OK) { + //incorrect output name + char *model_output_name = NULL; + char *all_output_names = NULL; + size_t model_output_count = 0; + av_log(ctx, AV_LOG_ERROR, "Failed to get model output data\n"); + status = ie_network_get_outputs_number(task->ov_model->network, &model_output_count); + for (size_t i = 0; i < model_output_count; i++) { + status = ie_network_get_output_name(task->ov_model->network, i, &model_output_name); + APPEND_STRING(all_output_names, model_output_name) + } + av_log(ctx, AV_LOG_ERROR, + "output \"%s\" may not correct, all output(s) are: \"%s\"\n", + task->output_name, all_output_names); + return; + } + + status = ie_blob_get_buffer(output_blob, &blob_buffer); + if (status != OK) { + ie_blob_free(&output_blob); + av_log(ctx, AV_LOG_ERROR, "Failed to access output memory\n"); + return; + } + + status |= ie_blob_get_dims(output_blob, &dims); + status |= ie_blob_get_precision(output_blob, &precision); + if (status != OK) { + ie_blob_free(&output_blob); + av_log(ctx, AV_LOG_ERROR, "Failed to get dims or precision of output\n"); + return; + } + + output.channels = dims.dims[1]; + output.height = dims.dims[2]; + output.width = dims.dims[3]; + output.dt = precision_to_datatype(precision); + output.data = blob_buffer.buffer; + + av_assert0(request->task_count <= dims.dims[0]); + av_assert0(request->task_count >= 1); + for (int i = 0; i < request->task_count; ++i) { + task = request->tasks[i]; + if (task->do_ioproc) { + if (task->ov_model->model->post_proc != NULL) { + task->ov_model->model->post_proc(task->out_frame, &output, task->ov_model->model->filter_ctx); + } else { + ff_proc_from_dnn_to_frame(task->out_frame, &output, ctx); + } + } else { + task->out_frame->width = output.width; + task->out_frame->height = output.height; + } + task->done = 1; + output.data = (uint8_t *)output.data + + output.width * output.height * output.channels * get_datatype_size(output.dt); + } + ie_blob_free(&output_blob); + + request->task_count = 0; + + if (task->async) { + if (ff_safe_queue_push_back(requestq, request) < 0) { + av_log(ctx, AV_LOG_ERROR, "Failed to push back request_queue.\n"); + return; + } + } +} + +static DNNReturnType init_model_ov(OVModel *ov_model, const char *input_name, const char *output_name) +{ + OVContext *ctx = &ov_model->ctx; + IEStatusCode status; + ie_available_devices_t a_dev; + ie_config_t config = {NULL, NULL, NULL}; + char *all_dev_names = NULL; + + // batch size + if (ctx->options.batch_size <= 0) { + ctx->options.batch_size = 1; + } + + if (ctx->options.batch_size > 1) { + input_shapes_t input_shapes; + status = ie_network_get_input_shapes(ov_model->network, &input_shapes); + if (status != OK) + goto err; + for (int i = 0; i < input_shapes.shape_num; i++) + input_shapes.shapes[i].shape.dims[0] = ctx->options.batch_size; + status = ie_network_reshape(ov_model->network, input_shapes); + ie_network_input_shapes_free(&input_shapes); + if (status != OK) + goto err; + } + + // The order of dims in the openvino is fixed and it is always NCHW for 4-D data. + // while we pass NHWC data from FFmpeg to openvino + status = ie_network_set_input_layout(ov_model->network, input_name, NHWC); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to set layout as NHWC for input %s\n", input_name); + goto err; + } + status = ie_network_set_output_layout(ov_model->network, output_name, NHWC); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to set layout as NHWC for output %s\n", output_name); + goto err; + } + + // all models in openvino open model zoo use BGR with range [0.0f, 255.0f] as input, + // we don't have a AVPixelFormat to descibe it, so we'll use AV_PIX_FMT_BGR24 and + // ask openvino to do the conversion internally. + // the current supported SR model (frame processing) is generated from tensorflow model, + // and its input is Y channel as float with range [0.0f, 1.0f], so do not set for this case. + // TODO: we need to get a final clear&general solution with all backends/formats considered. + if (ov_model->model->func_type != DFT_PROCESS_FRAME) { + status = ie_network_set_input_precision(ov_model->network, input_name, U8); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to set input precision as U8 for %s\n", input_name); + goto err; + } + } + + status = ie_core_load_network(ov_model->core, ov_model->network, ctx->options.device_type, &config, &ov_model->exe_network); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to load OpenVINO model network\n"); + status = ie_core_get_available_devices(ov_model->core, &a_dev); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to get available devices\n"); + goto err; + } + for (int i = 0; i < a_dev.num_devices; i++) { + APPEND_STRING(all_dev_names, a_dev.devices[i]) + } + av_log(ctx, AV_LOG_ERROR,"device %s may not be supported, all available devices are: \"%s\"\n", + ctx->options.device_type, all_dev_names); + goto err; + } + + // create infer_request for sync execution + status = ie_exec_network_create_infer_request(ov_model->exe_network, &ov_model->infer_request); + if (status != OK) + goto err; + + // create infer_requests for async execution + if (ctx->options.nireq <= 0) { + // the default value is a rough estimation + ctx->options.nireq = av_cpu_count() / 2 + 1; + } + + ov_model->request_queue = ff_safe_queue_create(); + if (!ov_model->request_queue) { + goto err; + } + + for (int i = 0; i < ctx->options.nireq; i++) { + RequestItem *item = av_mallocz(sizeof(*item)); + if (!item) { + goto err; + } + + item->callback.completeCallBackFunc = infer_completion_callback; + item->callback.args = item; + if (ff_safe_queue_push_back(ov_model->request_queue, item) < 0) { + av_freep(&item); + goto err; + } + + status = ie_exec_network_create_infer_request(ov_model->exe_network, &item->infer_request); + if (status != OK) { + goto err; + } + + item->tasks = av_malloc_array(ctx->options.batch_size, sizeof(*item->tasks)); + if (!item->tasks) { + goto err; + } + item->task_count = 0; + } + + ov_model->task_queue = ff_queue_create(); + if (!ov_model->task_queue) { + goto err; + } + + return DNN_SUCCESS; + +err: + ff_dnn_free_model_ov(&ov_model->model); + return DNN_ERROR; +} + +static DNNReturnType execute_model_ov(RequestItem *request) +{ + IEStatusCode status; + DNNReturnType ret; + TaskItem *task = request->tasks[0]; + OVContext *ctx = &task->ov_model->ctx; + + if (task->async) { + if (request->task_count < ctx->options.batch_size) { + if (ff_safe_queue_push_front(task->ov_model->request_queue, request) < 0) { + av_log(ctx, AV_LOG_ERROR, "Failed to push back request_queue.\n"); + return DNN_ERROR; + } + return DNN_SUCCESS; + } + ret = fill_model_input_ov(task->ov_model, request); + if (ret != DNN_SUCCESS) { + return ret; + } + status = ie_infer_set_completion_callback(request->infer_request, &request->callback); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to set completion callback for inference\n"); + return DNN_ERROR; + } + status = ie_infer_request_infer_async(request->infer_request); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to start async inference\n"); + return DNN_ERROR; + } + return DNN_SUCCESS; + } else { + ret = fill_model_input_ov(task->ov_model, request); + if (ret != DNN_SUCCESS) { + return ret; + } + status = ie_infer_request_infer(request->infer_request); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to start synchronous model inference\n"); + return DNN_ERROR; + } + infer_completion_callback(request); + return task->done ? DNN_SUCCESS : DNN_ERROR; + } +} + +static DNNReturnType get_input_ov(void *model, DNNData *input, const char *input_name) +{ + OVModel *ov_model = model; + OVContext *ctx = &ov_model->ctx; + char *model_input_name = NULL; + char *all_input_names = NULL; + IEStatusCode status; + size_t model_input_count = 0; + dimensions_t dims; + precision_e precision; + int input_resizable = ctx->options.input_resizable; + + status = ie_network_get_inputs_number(ov_model->network, &model_input_count); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to get input count\n"); + return DNN_ERROR; + } + + for (size_t i = 0; i < model_input_count; i++) { + status = ie_network_get_input_name(ov_model->network, i, &model_input_name); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to get No.%d input's name\n", (int)i); + return DNN_ERROR; + } + if (strcmp(model_input_name, input_name) == 0) { + ie_network_name_free(&model_input_name); + status |= ie_network_get_input_dims(ov_model->network, input_name, &dims); + status |= ie_network_get_input_precision(ov_model->network, input_name, &precision); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to get No.%d input's dims or precision\n", (int)i); + return DNN_ERROR; + } + + input->channels = dims.dims[1]; + input->height = input_resizable ? -1 : dims.dims[2]; + input->width = input_resizable ? -1 : dims.dims[3]; + input->dt = precision_to_datatype(precision); + return DNN_SUCCESS; + } else { + //incorrect input name + APPEND_STRING(all_input_names, model_input_name) + } + + ie_network_name_free(&model_input_name); + } + + av_log(ctx, AV_LOG_ERROR, "Could not find \"%s\" in model, all input(s) are: \"%s\"\n", input_name, all_input_names); + return DNN_ERROR; +} + +static DNNReturnType get_output_ov(void *model, const char *input_name, int input_width, int input_height, + const char *output_name, int *output_width, int *output_height) +{ + DNNReturnType ret; + OVModel *ov_model = model; + OVContext *ctx = &ov_model->ctx; + TaskItem task; + RequestItem request; + AVFrame *in_frame = NULL; + AVFrame *out_frame = NULL; + TaskItem *ptask = &task; + IEStatusCode status; + input_shapes_t input_shapes; + + if (ctx->options.input_resizable) { + status = ie_network_get_input_shapes(ov_model->network, &input_shapes); + input_shapes.shapes->shape.dims[2] = input_height; + input_shapes.shapes->shape.dims[3] = input_width; + status |= ie_network_reshape(ov_model->network, input_shapes); + ie_network_input_shapes_free(&input_shapes); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to reshape input size for %s\n", input_name); + return DNN_ERROR; + } + } + + if (!ov_model->exe_network) { + if (init_model_ov(ov_model, input_name, output_name) != DNN_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed init OpenVINO exectuable network or inference request\n"); + return DNN_ERROR; + } + } + + in_frame = av_frame_alloc(); + if (!in_frame) { + av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory for input frame\n"); + return DNN_ERROR; + } + in_frame->width = input_width; + in_frame->height = input_height; + + out_frame = av_frame_alloc(); + if (!out_frame) { + av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory for output frame\n"); + av_frame_free(&in_frame); + return DNN_ERROR; + } + + task.done = 0; + task.do_ioproc = 0; + task.async = 0; + task.input_name = input_name; + task.in_frame = in_frame; + task.output_name = output_name; + task.out_frame = out_frame; + task.ov_model = ov_model; + + request.infer_request = ov_model->infer_request; + request.task_count = 1; + request.tasks = &ptask; + + ret = execute_model_ov(&request); + *output_width = out_frame->width; + *output_height = out_frame->height; + + av_frame_free(&out_frame); + av_frame_free(&in_frame); + return ret; +} + +DNNModel *ff_dnn_load_model_ov(const char *model_filename, DNNFunctionType func_type, const char *options, AVFilterContext *filter_ctx) +{ + DNNModel *model = NULL; + OVModel *ov_model = NULL; + OVContext *ctx = NULL; + IEStatusCode status; + + model = av_mallocz(sizeof(DNNModel)); + if (!model){ + return NULL; + } + + ov_model = av_mallocz(sizeof(OVModel)); + if (!ov_model) { + av_freep(&model); + return NULL; + } + model->model = ov_model; + ov_model->model = model; + ov_model->ctx.class = &dnn_openvino_class; + ctx = &ov_model->ctx; + + //parse options + av_opt_set_defaults(ctx); + if (av_opt_set_from_string(ctx, options, NULL, "=", "&") < 0) { + av_log(ctx, AV_LOG_ERROR, "Failed to parse options \"%s\"\n", options); + goto err; + } + + status = ie_core_create("", &ov_model->core); + if (status != OK) + goto err; + + status = ie_core_read_network(ov_model->core, model_filename, NULL, &ov_model->network); + if (status != OK) { + ie_version_t ver; + ver = ie_c_api_version(); + av_log(ctx, AV_LOG_ERROR, "Failed to read the network from model file %s,\n" + "Please check if the model version matches the runtime OpenVINO %s\n", + model_filename, ver.api_version); + ie_version_free(&ver); + goto err; + } + + model->get_input = &get_input_ov; + model->get_output = &get_output_ov; + model->options = options; + model->filter_ctx = filter_ctx; + model->func_type = func_type; + + return model; + +err: + ff_dnn_free_model_ov(&model); + return NULL; +} + +DNNReturnType ff_dnn_execute_model_ov(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame) +{ + OVModel *ov_model = model->model; + OVContext *ctx = &ov_model->ctx; + TaskItem task; + RequestItem request; + TaskItem *ptask = &task; + + if (!in_frame) { + av_log(ctx, AV_LOG_ERROR, "in frame is NULL when execute model.\n"); + return DNN_ERROR; + } + + if (!out_frame && model->func_type == DFT_PROCESS_FRAME) { + av_log(ctx, AV_LOG_ERROR, "out frame is NULL when execute model.\n"); + return DNN_ERROR; + } + + if (nb_output != 1) { + // currently, the filter does not need multiple outputs, + // so we just pending the support until we really need it. + avpriv_report_missing_feature(ctx, "multiple outputs"); + return DNN_ERROR; + } + + if (ctx->options.batch_size > 1) { + avpriv_report_missing_feature(ctx, "batch mode for sync execution"); + return DNN_ERROR; + } + + if (!ov_model->exe_network) { + if (init_model_ov(ov_model, input_name, output_names[0]) != DNN_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed init OpenVINO exectuable network or inference request\n"); + return DNN_ERROR; + } + } + + task.done = 0; + task.do_ioproc = 1; + task.async = 0; + task.input_name = input_name; + task.in_frame = in_frame; + task.output_name = output_names[0]; + task.out_frame = out_frame; + task.ov_model = ov_model; + + request.infer_request = ov_model->infer_request; + request.task_count = 1; + request.tasks = &ptask; + + return execute_model_ov(&request); +} + +DNNReturnType ff_dnn_execute_model_async_ov(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame) +{ + OVModel *ov_model = model->model; + OVContext *ctx = &ov_model->ctx; + RequestItem *request; + TaskItem *task; + + if (!in_frame) { + av_log(ctx, AV_LOG_ERROR, "in frame is NULL when async execute model.\n"); + return DNN_ERROR; + } + + if (!out_frame && model->func_type == DFT_PROCESS_FRAME) { + av_log(ctx, AV_LOG_ERROR, "out frame is NULL when async execute model.\n"); + return DNN_ERROR; + } + + if (!ov_model->exe_network) { + if (init_model_ov(ov_model, input_name, output_names[0]) != DNN_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed init OpenVINO exectuable network or inference request\n"); + return DNN_ERROR; + } + } + + task = av_malloc(sizeof(*task)); + if (!task) { + av_log(ctx, AV_LOG_ERROR, "unable to alloc memory for task item.\n"); + return DNN_ERROR; + } + + task->done = 0; + task->do_ioproc = 1; + task->async = 1; + task->input_name = input_name; + task->in_frame = in_frame; + task->output_name = output_names[0]; + task->out_frame = out_frame; + task->ov_model = ov_model; + if (ff_queue_push_back(ov_model->task_queue, task) < 0) { + av_freep(&task); + av_log(ctx, AV_LOG_ERROR, "unable to push back task_queue.\n"); + return DNN_ERROR; + } + + request = ff_safe_queue_pop_front(ov_model->request_queue); + if (!request) { + av_log(ctx, AV_LOG_ERROR, "unable to get infer request.\n"); + return DNN_ERROR; + } + + request->tasks[request->task_count++] = task; + return execute_model_ov(request); +} + +DNNAsyncStatusType ff_dnn_get_async_result_ov(const DNNModel *model, AVFrame **in, AVFrame **out) +{ + OVModel *ov_model = model->model; + TaskItem *task = ff_queue_peek_front(ov_model->task_queue); + + if (!task) { + return DAST_EMPTY_QUEUE; + } + + if (!task->done) { + return DAST_NOT_READY; + } + + *in = task->in_frame; + *out = task->out_frame; + ff_queue_pop_front(ov_model->task_queue); + av_freep(&task); + + return DAST_SUCCESS; +} + +DNNReturnType ff_dnn_flush_ov(const DNNModel *model) +{ + OVModel *ov_model = model->model; + OVContext *ctx = &ov_model->ctx; + RequestItem *request; + IEStatusCode status; + DNNReturnType ret; + + request = ff_safe_queue_pop_front(ov_model->request_queue); + if (!request) { + av_log(ctx, AV_LOG_ERROR, "unable to get infer request.\n"); + return DNN_ERROR; + } + + if (request->task_count == 0) { + // no pending task need to flush + if (ff_safe_queue_push_back(ov_model->request_queue, request) < 0) { + av_log(ctx, AV_LOG_ERROR, "Failed to push back request_queue.\n"); + return DNN_ERROR; + } + return DNN_SUCCESS; + } + + ret = fill_model_input_ov(ov_model, request); + if (ret != DNN_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to fill model input.\n"); + return ret; + } + status = ie_infer_set_completion_callback(request->infer_request, &request->callback); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to set completion callback for inference\n"); + return DNN_ERROR; + } + status = ie_infer_request_infer_async(request->infer_request); + if (status != OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to start async inference\n"); + return DNN_ERROR; + } + + return DNN_SUCCESS; +} + +void ff_dnn_free_model_ov(DNNModel **model) +{ + if (*model){ + OVModel *ov_model = (*model)->model; + while (ff_safe_queue_size(ov_model->request_queue) != 0) { + RequestItem *item = ff_safe_queue_pop_front(ov_model->request_queue); + if (item && item->infer_request) { + ie_infer_request_free(&item->infer_request); + } + av_freep(&item->tasks); + av_freep(&item); + } + ff_safe_queue_destroy(ov_model->request_queue); + + while (ff_queue_size(ov_model->task_queue) != 0) { + TaskItem *item = ff_queue_pop_front(ov_model->task_queue); + av_frame_free(&item->in_frame); + av_frame_free(&item->out_frame); + av_freep(&item); + } + ff_queue_destroy(ov_model->task_queue); + + if (ov_model->infer_request) + ie_infer_request_free(&ov_model->infer_request); + if (ov_model->exe_network) + ie_exec_network_free(&ov_model->exe_network); + if (ov_model->network) + ie_network_free(&ov_model->network); + if (ov_model->core) + ie_core_free(&ov_model->core); + av_freep(&ov_model); + av_freep(model); + } +} diff --git a/libavfilter/dnn/dnn_backend_openvino.h b/libavfilter/dnn/dnn_backend_openvino.h new file mode 100644 index 000000000..a484a7be3 --- /dev/null +++ b/libavfilter/dnn/dnn_backend_openvino.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 + * + * 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 + * DNN inference functions interface for OpenVINO backend. + */ + + +#ifndef AVFILTER_DNN_DNN_BACKEND_OPENVINO_H +#define AVFILTER_DNN_DNN_BACKEND_OPENVINO_H + +#include "../dnn_interface.h" + +DNNModel *ff_dnn_load_model_ov(const char *model_filename, DNNFunctionType func_type, const char *options, AVFilterContext *filter_ctx); + +DNNReturnType ff_dnn_execute_model_ov(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame); +DNNReturnType ff_dnn_execute_model_async_ov(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame); +DNNAsyncStatusType ff_dnn_get_async_result_ov(const DNNModel *model, AVFrame **in, AVFrame **out); +DNNReturnType ff_dnn_flush_ov(const DNNModel *model); + +void ff_dnn_free_model_ov(DNNModel **model); + +#endif diff --git a/libavfilter/dnn/dnn_backend_tf.c b/libavfilter/dnn/dnn_backend_tf.c index 9ceca5cea..750a47672 100644 --- a/libavfilter/dnn/dnn_backend_tf.c +++ b/libavfilter/dnn/dnn_backend_tf.c @@ -29,22 +29,43 @@ #include "dnn_backend_native_layer_depth2space.h" #include "libavformat/avio.h" #include "libavutil/avassert.h" +#include "../internal.h" #include "dnn_backend_native_layer_pad.h" #include "dnn_backend_native_layer_maximum.h" +#include "dnn_io_proc.h" #include +typedef struct TFOptions{ + char *sess_config; +} TFOptions; + +typedef struct TFContext { + const AVClass *class; + TFOptions options; +} TFContext; + typedef struct TFModel{ + TFContext ctx; + DNNModel *model; TF_Graph *graph; TF_Session *session; TF_Status *status; - TF_Output input; - TF_Tensor *input_tensor; - TF_Output *outputs; - TF_Tensor **output_tensors; - uint32_t nb_output; } TFModel; +#define OFFSET(x) offsetof(TFContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM +static const AVOption dnn_tensorflow_options[] = { + { "sess_config", "config for SessionOptions", OFFSET(options.sess_config), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(dnn_tensorflow); + +static DNNReturnType execute_model_tf(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame, + int do_ioproc); + static void free_buffer(void *data, size_t length) { av_freep(&data); @@ -76,7 +97,7 @@ static TF_Buffer *read_graph(const char *model_filename) } graph_buf = TF_NewBuffer(); - graph_buf->data = (void *)graph_data; + graph_buf->data = graph_data; graph_buf->length = size; graph_buf->data_deallocator = free_buffer; @@ -107,14 +128,17 @@ static TF_Tensor *allocate_input_tensor(const DNNData *input) static DNNReturnType get_input_tf(void *model, DNNData *input, const char *input_name) { - TFModel *tf_model = (TFModel *)model; + TFModel *tf_model = model; + TFContext *ctx = &tf_model->ctx; TF_Status *status; int64_t dims[4]; TF_Output tf_output; tf_output.oper = TF_GraphOperationByName(tf_model->graph, input_name); - if (!tf_output.oper) + if (!tf_output.oper) { + av_log(ctx, AV_LOG_ERROR, "Could not find \"%s\" in model\n", input_name); return DNN_ERROR; + } tf_output.index = 0; input->dt = TF_OperationOutputType(tf_output); @@ -123,6 +147,7 @@ static DNNReturnType get_input_tf(void *model, DNNData *input, const char *input TF_GraphGetTensorShape(tf_model->graph, tf_output, dims, 4, status); if (TF_GetCode(status) != TF_OK){ TF_DeleteStatus(status); + av_log(ctx, AV_LOG_ERROR, "Failed to get input tensor shape: number of dimension incorrect\n"); return DNN_ERROR; } TF_DeleteStatus(status); @@ -136,96 +161,104 @@ static DNNReturnType get_input_tf(void *model, DNNData *input, const char *input return DNN_SUCCESS; } -static DNNReturnType set_input_output_tf(void *model, DNNData *input, const char *input_name, const char **output_names, uint32_t nb_output) +static DNNReturnType get_output_tf(void *model, const char *input_name, int input_width, int input_height, + const char *output_name, int *output_width, int *output_height) { - TFModel *tf_model = (TFModel *)model; - TF_SessionOptions *sess_opts; - const TF_Operation *init_op = TF_GraphOperationByName(tf_model->graph, "init"); + DNNReturnType ret; + TFModel *tf_model = model; + TFContext *ctx = &tf_model->ctx; + AVFrame *in_frame = av_frame_alloc(); + AVFrame *out_frame = NULL; - // Input operation - tf_model->input.oper = TF_GraphOperationByName(tf_model->graph, input_name); - if (!tf_model->input.oper){ - return DNN_ERROR; - } - tf_model->input.index = 0; - if (tf_model->input_tensor){ - TF_DeleteTensor(tf_model->input_tensor); - } - tf_model->input_tensor = allocate_input_tensor(input); - if (!tf_model->input_tensor){ - return DNN_ERROR; - } - input->data = (float *)TF_TensorData(tf_model->input_tensor); - - // Output operation - if (nb_output == 0) - return DNN_ERROR; - - av_freep(&tf_model->outputs); - tf_model->outputs = av_malloc_array(nb_output, sizeof(*tf_model->outputs)); - if (!tf_model->outputs) - return DNN_ERROR; - for (int i = 0; i < nb_output; ++i) { - tf_model->outputs[i].oper = TF_GraphOperationByName(tf_model->graph, output_names[i]); - if (!tf_model->outputs[i].oper){ - av_freep(&tf_model->outputs); - return DNN_ERROR; - } - tf_model->outputs[i].index = 0; - } - - if (tf_model->output_tensors) { - for (uint32_t i = 0; i < tf_model->nb_output; ++i) { - if (tf_model->output_tensors[i]) { - TF_DeleteTensor(tf_model->output_tensors[i]); - tf_model->output_tensors[i] = NULL; - } - } - } - av_freep(&tf_model->output_tensors); - tf_model->output_tensors = av_mallocz_array(nb_output, sizeof(*tf_model->output_tensors)); - if (!tf_model->output_tensors) { - av_freep(&tf_model->outputs); + if (!in_frame) { + av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory for input frame\n"); return DNN_ERROR; } - tf_model->nb_output = nb_output; - - if (tf_model->session){ - TF_CloseSession(tf_model->session, tf_model->status); - TF_DeleteSession(tf_model->session, tf_model->status); - } - - sess_opts = TF_NewSessionOptions(); - tf_model->session = TF_NewSession(tf_model->graph, sess_opts, tf_model->status); - TF_DeleteSessionOptions(sess_opts); - if (TF_GetCode(tf_model->status) != TF_OK) - { + out_frame = av_frame_alloc(); + if (!out_frame) { + av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory for output frame\n"); + av_frame_free(&in_frame); return DNN_ERROR; } - // Run initialization operation with name "init" if it is present in graph - if (init_op){ - TF_SessionRun(tf_model->session, NULL, - NULL, NULL, 0, - NULL, NULL, 0, - &init_op, 1, NULL, tf_model->status); - if (TF_GetCode(tf_model->status) != TF_OK) - { - return DNN_ERROR; - } - } + in_frame->width = input_width; + in_frame->height = input_height; - return DNN_SUCCESS; + ret = execute_model_tf(tf_model->model, input_name, in_frame, &output_name, 1, out_frame, 0); + *output_width = out_frame->width; + *output_height = out_frame->height; + + av_frame_free(&out_frame); + av_frame_free(&in_frame); + return ret; } static DNNReturnType load_tf_model(TFModel *tf_model, const char *model_filename) { + TFContext *ctx = &tf_model->ctx; TF_Buffer *graph_def; TF_ImportGraphDefOptions *graph_opts; + TF_SessionOptions *sess_opts; + const TF_Operation *init_op; + uint8_t *sess_config = NULL; + int sess_config_length = 0; + + // prepare the sess config data + if (tf_model->ctx.options.sess_config != NULL) { + /* + tf_model->ctx.options.sess_config is hex to present the serialized proto + required by TF_SetConfig below, so we need to first generate the serialized + proto in a python script, the following is a script example to generate + serialized proto which specifies one GPU, we can change the script to add + more options. + + import tensorflow as tf + gpu_options = tf.GPUOptions(visible_device_list='0') + config = tf.ConfigProto(gpu_options=gpu_options) + s = config.SerializeToString() + b = ''.join("%02x" % int(ord(b)) for b in s[::-1]) + print('0x%s' % b) + + the script output looks like: 0xab...cd, and then pass 0xab...cd to sess_config. + */ + char tmp[3]; + tmp[2] = '\0'; + + if (strncmp(tf_model->ctx.options.sess_config, "0x", 2) != 0) { + av_log(ctx, AV_LOG_ERROR, "sess_config should start with '0x'\n"); + return DNN_ERROR; + } + + sess_config_length = strlen(tf_model->ctx.options.sess_config); + if (sess_config_length % 2 != 0) { + av_log(ctx, AV_LOG_ERROR, "the length of sess_config is not even (%s), " + "please re-generate the config.\n", + tf_model->ctx.options.sess_config); + return DNN_ERROR; + } + + sess_config_length -= 2; //ignore the first '0x' + sess_config_length /= 2; //get the data length in byte + + sess_config = av_malloc(sess_config_length); + if (!sess_config) { + av_log(ctx, AV_LOG_ERROR, "failed to allocate memory\n"); + return DNN_ERROR; + } + + for (int i = 0; i < sess_config_length; i++) { + int index = 2 + (sess_config_length - 1 - i) * 2; + tmp[0] = tf_model->ctx.options.sess_config[index]; + tmp[1] = tf_model->ctx.options.sess_config[index + 1]; + sess_config[i] = strtol(tmp, NULL, 16); + } + } graph_def = read_graph(model_filename); if (!graph_def){ + av_log(ctx, AV_LOG_ERROR, "Failed to read model \"%s\" graph\n", model_filename); + av_freep(&sess_config); return DNN_ERROR; } tf_model->graph = TF_NewGraph(); @@ -237,9 +270,45 @@ static DNNReturnType load_tf_model(TFModel *tf_model, const char *model_filename if (TF_GetCode(tf_model->status) != TF_OK){ TF_DeleteGraph(tf_model->graph); TF_DeleteStatus(tf_model->status); + av_log(ctx, AV_LOG_ERROR, "Failed to import serialized graph to model graph\n"); + av_freep(&sess_config); return DNN_ERROR; } + init_op = TF_GraphOperationByName(tf_model->graph, "init"); + sess_opts = TF_NewSessionOptions(); + + if (sess_config) { + TF_SetConfig(sess_opts, sess_config, sess_config_length,tf_model->status); + av_freep(&sess_config); + if (TF_GetCode(tf_model->status) != TF_OK) { + av_log(ctx, AV_LOG_ERROR, "Failed to set config for sess options with %s\n", + tf_model->ctx.options.sess_config); + return DNN_ERROR; + } + } + + tf_model->session = TF_NewSession(tf_model->graph, sess_opts, tf_model->status); + TF_DeleteSessionOptions(sess_opts); + if (TF_GetCode(tf_model->status) != TF_OK) + { + av_log(ctx, AV_LOG_ERROR, "Failed to create new session with model graph\n"); + return DNN_ERROR; + } + + // Run initialization operation with name "init" if it is present in graph + if (init_op){ + TF_SessionRun(tf_model->session, NULL, + NULL, NULL, 0, + NULL, NULL, 0, + &init_op, 1, NULL, tf_model->status); + if (TF_GetCode(tf_model->status) != TF_OK) + { + av_log(ctx, AV_LOG_ERROR, "Failed to run session when initializing\n"); + return DNN_ERROR; + } + } + return DNN_SUCCESS; } @@ -248,6 +317,7 @@ static DNNReturnType load_tf_model(TFModel *tf_model, const char *model_filename static DNNReturnType add_conv_layer(TFModel *tf_model, TF_Operation *transpose_op, TF_Operation **cur_op, ConvolutionalParams* params, const int layer) { + TFContext *ctx = &tf_model->ctx; TF_Operation *op; TF_OperationDescription *op_desc; TF_Output input; @@ -273,10 +343,12 @@ static DNNReturnType add_conv_layer(TFModel *tf_model, TF_Operation *transpose_o memcpy(TF_TensorData(tensor), params->kernel, size * sizeof(float)); TF_SetAttrTensor(op_desc, "value", tensor, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to set value for kernel of conv layer %d\n", layer); return DNN_ERROR; } op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add kernel to conv layer %d\n", layer); return DNN_ERROR; } @@ -290,6 +362,7 @@ static DNNReturnType add_conv_layer(TFModel *tf_model, TF_Operation *transpose_o TF_SetAttrType(op_desc, "Tperm", TF_INT32); op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add transpose to conv layer %d\n", layer); return DNN_ERROR; } @@ -304,6 +377,7 @@ static DNNReturnType add_conv_layer(TFModel *tf_model, TF_Operation *transpose_o TF_SetAttrString(op_desc, "padding", "VALID", 5); *cur_op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add conv2d to conv layer %d\n", layer); return DNN_ERROR; } @@ -316,10 +390,12 @@ static DNNReturnType add_conv_layer(TFModel *tf_model, TF_Operation *transpose_o memcpy(TF_TensorData(tensor), params->biases, params->output_num * sizeof(float)); TF_SetAttrTensor(op_desc, "value", tensor, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to set value for conv_biases of conv layer %d\n", layer); return DNN_ERROR; } op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add conv_biases to conv layer %d\n", layer); return DNN_ERROR; } @@ -332,6 +408,7 @@ static DNNReturnType add_conv_layer(TFModel *tf_model, TF_Operation *transpose_o TF_SetAttrType(op_desc, "T", TF_FLOAT); *cur_op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add bias_add to conv layer %d\n", layer); return DNN_ERROR; } @@ -347,6 +424,7 @@ static DNNReturnType add_conv_layer(TFModel *tf_model, TF_Operation *transpose_o op_desc = TF_NewOperation(tf_model->graph, "Sigmoid", name_buffer); break; default: + avpriv_report_missing_feature(ctx, "convolutional activation function %d", params->activation); return DNN_ERROR; } input.oper = *cur_op; @@ -354,6 +432,7 @@ static DNNReturnType add_conv_layer(TFModel *tf_model, TF_Operation *transpose_o TF_SetAttrType(op_desc, "T", TF_FLOAT); *cur_op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add activation function to conv layer %d\n", layer); return DNN_ERROR; } @@ -363,6 +442,7 @@ static DNNReturnType add_conv_layer(TFModel *tf_model, TF_Operation *transpose_o static DNNReturnType add_depth_to_space_layer(TFModel *tf_model, TF_Operation **cur_op, DepthToSpaceParams *params, const int layer) { + TFContext *ctx = &tf_model->ctx; TF_OperationDescription *op_desc; TF_Output input; char name_buffer[NAME_BUFFER_SIZE]; @@ -376,6 +456,7 @@ static DNNReturnType add_depth_to_space_layer(TFModel *tf_model, TF_Operation ** TF_SetAttrInt(op_desc, "block_size", params->block_size); *cur_op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add depth_to_space to layer %d\n", layer); return DNN_ERROR; } @@ -385,6 +466,7 @@ static DNNReturnType add_depth_to_space_layer(TFModel *tf_model, TF_Operation ** static DNNReturnType add_pad_layer(TFModel *tf_model, TF_Operation **cur_op, LayerPadParams *params, const int layer) { + TFContext *ctx = &tf_model->ctx; TF_Operation *op; TF_Tensor *tensor; TF_OperationDescription *op_desc; @@ -409,10 +491,12 @@ static DNNReturnType add_pad_layer(TFModel *tf_model, TF_Operation **cur_op, pads[7] = params->paddings[3][1]; TF_SetAttrTensor(op_desc, "value", tensor, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to set value for pad of layer %d\n", layer); return DNN_ERROR; } op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add pad to layer %d\n", layer); return DNN_ERROR; } @@ -427,6 +511,7 @@ static DNNReturnType add_pad_layer(TFModel *tf_model, TF_Operation **cur_op, TF_SetAttrString(op_desc, "mode", "SYMMETRIC", 9); *cur_op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add mirror_pad to layer %d\n", layer); return DNN_ERROR; } @@ -436,6 +521,7 @@ static DNNReturnType add_pad_layer(TFModel *tf_model, TF_Operation **cur_op, static DNNReturnType add_maximum_layer(TFModel *tf_model, TF_Operation **cur_op, DnnLayerMaximumParams *params, const int layer) { + TFContext *ctx = &tf_model->ctx; TF_Operation *op; TF_Tensor *tensor; TF_OperationDescription *op_desc; @@ -452,10 +538,12 @@ static DNNReturnType add_maximum_layer(TFModel *tf_model, TF_Operation **cur_op, *y = params->val.y; TF_SetAttrTensor(op_desc, "value", tensor, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to set value for maximum/y of layer %d", layer); return DNN_ERROR; } op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add maximum/y to layer %d\n", layer); return DNN_ERROR; } @@ -469,6 +557,7 @@ static DNNReturnType add_maximum_layer(TFModel *tf_model, TF_Operation **cur_op, TF_SetAttrType(op_desc, "T", TF_FLOAT); *cur_op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ + av_log(ctx, AV_LOG_ERROR, "Failed to add maximum to layer %d\n", layer); return DNN_ERROR; } @@ -477,6 +566,7 @@ static DNNReturnType add_maximum_layer(TFModel *tf_model, TF_Operation **cur_op, static DNNReturnType load_native_model(TFModel *tf_model, const char *model_filename) { + TFContext *ctx = &tf_model->ctx; int32_t layer; TF_OperationDescription *op_desc; TF_Operation *op; @@ -487,15 +577,16 @@ static DNNReturnType load_native_model(TFModel *tf_model, const char *model_file int64_t transpose_perm_shape[] = {4}; int64_t input_shape[] = {1, -1, -1, -1}; DNNReturnType layer_add_res; - DNNModel *native_model = NULL; - ConvolutionalNetwork *conv_network; + DNNModel *model = NULL; + NativeModel *native_model; - native_model = ff_dnn_load_model_native(model_filename); - if (!native_model){ + model = ff_dnn_load_model_native(model_filename, DFT_PROCESS_FRAME, NULL, NULL); + if (!model){ + av_log(ctx, AV_LOG_ERROR, "Failed to load native model\n"); return DNN_ERROR; } - conv_network = (ConvolutionalNetwork *)native_model->model; + native_model = model->model; tf_model->graph = TF_NewGraph(); tf_model->status = TF_NewStatus(); @@ -503,6 +594,7 @@ static DNNReturnType load_native_model(TFModel *tf_model, const char *model_file { \ TF_DeleteGraph(tf_model->graph); \ TF_DeleteStatus(tf_model->status); \ + av_log(ctx, AV_LOG_ERROR, "Failed to set value or add operator to layer\n"); \ return DNN_ERROR; \ } @@ -528,26 +620,26 @@ static DNNReturnType load_native_model(TFModel *tf_model, const char *model_file } transpose_op = TF_FinishOperation(op_desc, tf_model->status); - for (layer = 0; layer < conv_network->layers_num; ++layer){ - switch (conv_network->layers[layer].type){ + for (layer = 0; layer < native_model->layers_num; ++layer){ + switch (native_model->layers[layer].type){ case DLT_INPUT: layer_add_res = DNN_SUCCESS; break; case DLT_CONV2D: layer_add_res = add_conv_layer(tf_model, transpose_op, &op, - (ConvolutionalParams *)conv_network->layers[layer].params, layer); + (ConvolutionalParams *)native_model->layers[layer].params, layer); break; case DLT_DEPTH_TO_SPACE: layer_add_res = add_depth_to_space_layer(tf_model, &op, - (DepthToSpaceParams *)conv_network->layers[layer].params, layer); + (DepthToSpaceParams *)native_model->layers[layer].params, layer); break; case DLT_MIRROR_PAD: layer_add_res = add_pad_layer(tf_model, &op, - (LayerPadParams *)conv_network->layers[layer].params, layer); + (LayerPadParams *)native_model->layers[layer].params, layer); break; case DLT_MAXIMUM: layer_add_res = add_maximum_layer(tf_model, &op, - (DnnLayerMaximumParams *)conv_network->layers[layer].params, layer); + (DnnLayerMaximumParams *)native_model->layers[layer].params, layer); break; default: CLEANUP_ON_ERROR(tf_model); @@ -567,17 +659,17 @@ static DNNReturnType load_native_model(TFModel *tf_model, const char *model_file CLEANUP_ON_ERROR(tf_model); } - ff_dnn_free_model_native(&native_model); + ff_dnn_free_model_native(&model); return DNN_SUCCESS; } -DNNModel *ff_dnn_load_model_tf(const char *model_filename) +DNNModel *ff_dnn_load_model_tf(const char *model_filename, DNNFunctionType func_type, const char *options, AVFilterContext *filter_ctx) { DNNModel *model = NULL; TFModel *tf_model = NULL; - model = av_malloc(sizeof(DNNModel)); + model = av_mallocz(sizeof(DNNModel)); if (!model){ return NULL; } @@ -587,6 +679,17 @@ DNNModel *ff_dnn_load_model_tf(const char *model_filename) av_freep(&model); return NULL; } + tf_model->ctx.class = &dnn_tensorflow_class; + tf_model->model = model; + + //parse options + av_opt_set_defaults(&tf_model->ctx); + if (av_opt_set_from_string(&tf_model->ctx, options, NULL, "=", "&") < 0) { + av_log(&tf_model->ctx, AV_LOG_ERROR, "Failed to parse options \"%s\"\n", options); + av_freep(&tf_model); + av_freep(&model); + return NULL; + } if (load_tf_model(tf_model, model_filename) != DNN_SUCCESS){ if (load_native_model(tf_model, model_filename) != DNN_SUCCESS){ @@ -597,56 +700,151 @@ DNNModel *ff_dnn_load_model_tf(const char *model_filename) } } - model->model = (void *)tf_model; - model->set_input_output = &set_input_output_tf; + model->model = tf_model; model->get_input = &get_input_tf; + model->get_output = &get_output_tf; + model->options = options; + model->filter_ctx = filter_ctx; + model->func_type = func_type; return model; } - - -DNNReturnType ff_dnn_execute_model_tf(const DNNModel *model, DNNData *outputs, uint32_t nb_output) +static DNNReturnType execute_model_tf(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame, + int do_ioproc) { - TFModel *tf_model = (TFModel *)model->model; - uint32_t nb = FFMIN(nb_output, tf_model->nb_output); - if (nb == 0) - return DNN_ERROR; + TF_Output *tf_outputs; + TFModel *tf_model = model->model; + TFContext *ctx = &tf_model->ctx; + DNNData input, output; + TF_Tensor **output_tensors; + TF_Output tf_input; + TF_Tensor *input_tensor; - av_assert0(tf_model->output_tensors); - for (uint32_t i = 0; i < tf_model->nb_output; ++i) { - if (tf_model->output_tensors[i]) { - TF_DeleteTensor(tf_model->output_tensors[i]); - tf_model->output_tensors[i] = NULL; + if (get_input_tf(tf_model, &input, input_name) != DNN_SUCCESS) + return DNN_ERROR; + input.height = in_frame->height; + input.width = in_frame->width; + + tf_input.oper = TF_GraphOperationByName(tf_model->graph, input_name); + if (!tf_input.oper){ + av_log(ctx, AV_LOG_ERROR, "Could not find \"%s\" in model\n", input_name); + return DNN_ERROR; + } + tf_input.index = 0; + input_tensor = allocate_input_tensor(&input); + if (!input_tensor){ + av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory for input tensor\n"); + return DNN_ERROR; + } + input.data = (float *)TF_TensorData(input_tensor); + + if (do_ioproc) { + if (tf_model->model->pre_proc != NULL) { + tf_model->model->pre_proc(in_frame, &input, tf_model->model->filter_ctx); + } else { + ff_proc_from_frame_to_dnn(in_frame, &input, tf_model->model->func_type, ctx); } } - TF_SessionRun(tf_model->session, NULL, - &tf_model->input, &tf_model->input_tensor, 1, - tf_model->outputs, tf_model->output_tensors, nb, - NULL, 0, NULL, tf_model->status); - - if (TF_GetCode(tf_model->status) != TF_OK){ + if (nb_output != 1) { + // currently, the filter does not need multiple outputs, + // so we just pending the support until we really need it. + avpriv_report_missing_feature(ctx, "multiple outputs"); return DNN_ERROR; } - for (uint32_t i = 0; i < nb; ++i) { - outputs[i].height = TF_Dim(tf_model->output_tensors[i], 1); - outputs[i].width = TF_Dim(tf_model->output_tensors[i], 2); - outputs[i].channels = TF_Dim(tf_model->output_tensors[i], 3); - outputs[i].data = TF_TensorData(tf_model->output_tensors[i]); - outputs[i].dt = TF_TensorType(tf_model->output_tensors[i]); + tf_outputs = av_malloc_array(nb_output, sizeof(*tf_outputs)); + if (tf_outputs == NULL) { + av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory for *tf_outputs\n"); \ + return DNN_ERROR; } + output_tensors = av_mallocz_array(nb_output, sizeof(*output_tensors)); + if (!output_tensors) { + av_freep(&tf_outputs); + av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory for output tensor\n"); \ + return DNN_ERROR; + } + + for (int i = 0; i < nb_output; ++i) { + tf_outputs[i].oper = TF_GraphOperationByName(tf_model->graph, output_names[i]); + if (!tf_outputs[i].oper) { + av_freep(&tf_outputs); + av_freep(&output_tensors); + av_log(ctx, AV_LOG_ERROR, "Could not find output \"%s\" in model\n", output_names[i]); \ + return DNN_ERROR; + } + tf_outputs[i].index = 0; + } + + TF_SessionRun(tf_model->session, NULL, + &tf_input, &input_tensor, 1, + tf_outputs, output_tensors, nb_output, + NULL, 0, NULL, tf_model->status); + if (TF_GetCode(tf_model->status) != TF_OK) { + av_freep(&tf_outputs); + av_freep(&output_tensors); + av_log(ctx, AV_LOG_ERROR, "Failed to run session when executing model\n"); + return DNN_ERROR; + } + + for (uint32_t i = 0; i < nb_output; ++i) { + output.height = TF_Dim(output_tensors[i], 1); + output.width = TF_Dim(output_tensors[i], 2); + output.channels = TF_Dim(output_tensors[i], 3); + output.data = TF_TensorData(output_tensors[i]); + output.dt = TF_TensorType(output_tensors[i]); + + if (do_ioproc) { + if (tf_model->model->post_proc != NULL) { + tf_model->model->post_proc(out_frame, &output, tf_model->model->filter_ctx); + } else { + ff_proc_from_dnn_to_frame(out_frame, &output, ctx); + } + } else { + out_frame->width = output.width; + out_frame->height = output.height; + } + } + + for (uint32_t i = 0; i < nb_output; ++i) { + if (output_tensors[i]) { + TF_DeleteTensor(output_tensors[i]); + } + } + TF_DeleteTensor(input_tensor); + av_freep(&output_tensors); + av_freep(&tf_outputs); return DNN_SUCCESS; } +DNNReturnType ff_dnn_execute_model_tf(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame) +{ + TFModel *tf_model = model->model; + TFContext *ctx = &tf_model->ctx; + + if (!in_frame) { + av_log(ctx, AV_LOG_ERROR, "in frame is NULL when execute model.\n"); + return DNN_ERROR; + } + + if (!out_frame) { + av_log(ctx, AV_LOG_ERROR, "out frame is NULL when execute model.\n"); + return DNN_ERROR; + } + + return execute_model_tf(model, input_name, in_frame, output_names, nb_output, out_frame, 1); +} + void ff_dnn_free_model_tf(DNNModel **model) { TFModel *tf_model; if (*model){ - tf_model = (TFModel *)(*model)->model; + tf_model = (*model)->model; if (tf_model->graph){ TF_DeleteGraph(tf_model->graph); } @@ -657,19 +855,6 @@ void ff_dnn_free_model_tf(DNNModel **model) if (tf_model->status){ TF_DeleteStatus(tf_model->status); } - if (tf_model->input_tensor){ - TF_DeleteTensor(tf_model->input_tensor); - } - if (tf_model->output_tensors) { - for (uint32_t i = 0; i < tf_model->nb_output; ++i) { - if (tf_model->output_tensors[i]) { - TF_DeleteTensor(tf_model->output_tensors[i]); - tf_model->output_tensors[i] = NULL; - } - } - } - av_freep(&tf_model->outputs); - av_freep(&tf_model->output_tensors); av_freep(&tf_model); av_freep(model); } diff --git a/libavfilter/dnn/dnn_backend_tf.h b/libavfilter/dnn/dnn_backend_tf.h index 3e4508912..8cec04748 100644 --- a/libavfilter/dnn/dnn_backend_tf.h +++ b/libavfilter/dnn/dnn_backend_tf.h @@ -29,9 +29,10 @@ #include "../dnn_interface.h" -DNNModel *ff_dnn_load_model_tf(const char *model_filename); +DNNModel *ff_dnn_load_model_tf(const char *model_filename, DNNFunctionType func_type, const char *options, AVFilterContext *filter_ctx); -DNNReturnType ff_dnn_execute_model_tf(const DNNModel *model, DNNData *outputs, uint32_t nb_output); +DNNReturnType ff_dnn_execute_model_tf(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame); void ff_dnn_free_model_tf(DNNModel **model); diff --git a/libavfilter/dnn/dnn_interface.c b/libavfilter/dnn/dnn_interface.c index 62da55f43..02e532fc1 100644 --- a/libavfilter/dnn/dnn_interface.c +++ b/libavfilter/dnn/dnn_interface.c @@ -26,13 +26,14 @@ #include "../dnn_interface.h" #include "dnn_backend_native.h" #include "dnn_backend_tf.h" +#include "dnn_backend_openvino.h" #include "libavutil/mem.h" DNNModule *ff_get_dnn_module(DNNBackendType backend_type) { DNNModule *dnn_module; - dnn_module = av_malloc(sizeof(DNNModule)); + dnn_module = av_mallocz(sizeof(DNNModule)); if(!dnn_module){ return NULL; } @@ -53,6 +54,19 @@ DNNModule *ff_get_dnn_module(DNNBackendType backend_type) return NULL; #endif break; + case DNN_OV: + #if (CONFIG_LIBOPENVINO == 1) + dnn_module->load_model = &ff_dnn_load_model_ov; + dnn_module->execute_model = &ff_dnn_execute_model_ov; + dnn_module->execute_model_async = &ff_dnn_execute_model_async_ov; + dnn_module->get_async_result = &ff_dnn_get_async_result_ov; + dnn_module->flush = &ff_dnn_flush_ov; + dnn_module->free_model = &ff_dnn_free_model_ov; + #else + av_freep(&dnn_module); + return NULL; + #endif + break; default: av_log(NULL, AV_LOG_ERROR, "Module backend_type is not native or tensorflow\n"); av_freep(&dnn_module); diff --git a/libavfilter/dnn/dnn_io_proc.c b/libavfilter/dnn/dnn_io_proc.c new file mode 100644 index 000000000..e104cc506 --- /dev/null +++ b/libavfilter/dnn/dnn_io_proc.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2020 + * + * 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 "dnn_io_proc.h" +#include "libavutil/imgutils.h" +#include "libswscale/swscale.h" +#include "libavutil/avassert.h" + +DNNReturnType ff_proc_from_dnn_to_frame(AVFrame *frame, DNNData *output, void *log_ctx) +{ + struct SwsContext *sws_ctx; + int bytewidth = av_image_get_linesize(frame->format, frame->width, 0); + if (output->dt != DNN_FLOAT) { + avpriv_report_missing_feature(log_ctx, "data type rather than DNN_FLOAT"); + return DNN_ERROR; + } + + switch (frame->format) { + case AV_PIX_FMT_RGB24: + case AV_PIX_FMT_BGR24: + sws_ctx = sws_getContext(frame->width * 3, + frame->height, + AV_PIX_FMT_GRAYF32, + frame->width * 3, + frame->height, + AV_PIX_FMT_GRAY8, + 0, NULL, NULL, NULL); + if (!sws_ctx) { + av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion " + "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n", + av_get_pix_fmt_name(AV_PIX_FMT_GRAYF32), frame->width * 3, frame->height, + av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width * 3, frame->height); + return DNN_ERROR; + } + sws_scale(sws_ctx, (const uint8_t *[4]){(const uint8_t *)output->data, 0, 0, 0}, + (const int[4]){frame->width * 3 * sizeof(float), 0, 0, 0}, 0, frame->height, + (uint8_t * const*)frame->data, frame->linesize); + sws_freeContext(sws_ctx); + return DNN_SUCCESS; + case AV_PIX_FMT_GRAYF32: + av_image_copy_plane(frame->data[0], frame->linesize[0], + output->data, bytewidth, + bytewidth, frame->height); + return DNN_SUCCESS; + case AV_PIX_FMT_YUV420P: + case AV_PIX_FMT_YUV422P: + case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUV410P: + case AV_PIX_FMT_YUV411P: + case AV_PIX_FMT_GRAY8: + case AV_PIX_FMT_NV12: + sws_ctx = sws_getContext(frame->width, + frame->height, + AV_PIX_FMT_GRAYF32, + frame->width, + frame->height, + AV_PIX_FMT_GRAY8, + 0, NULL, NULL, NULL); + if (!sws_ctx) { + av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion " + "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n", + av_get_pix_fmt_name(AV_PIX_FMT_GRAYF32), frame->width, frame->height, + av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width, frame->height); + return DNN_ERROR; + } + sws_scale(sws_ctx, (const uint8_t *[4]){(const uint8_t *)output->data, 0, 0, 0}, + (const int[4]){frame->width * sizeof(float), 0, 0, 0}, 0, frame->height, + (uint8_t * const*)frame->data, frame->linesize); + sws_freeContext(sws_ctx); + return DNN_SUCCESS; + default: + avpriv_report_missing_feature(log_ctx, "%s", av_get_pix_fmt_name(frame->format)); + return DNN_ERROR; + } + + return DNN_SUCCESS; +} + +static DNNReturnType proc_from_frame_to_dnn_frameprocessing(AVFrame *frame, DNNData *input, void *log_ctx) +{ + struct SwsContext *sws_ctx; + int bytewidth = av_image_get_linesize(frame->format, frame->width, 0); + if (input->dt != DNN_FLOAT) { + avpriv_report_missing_feature(log_ctx, "data type rather than DNN_FLOAT"); + return DNN_ERROR; + } + + switch (frame->format) { + case AV_PIX_FMT_RGB24: + case AV_PIX_FMT_BGR24: + sws_ctx = sws_getContext(frame->width * 3, + frame->height, + AV_PIX_FMT_GRAY8, + frame->width * 3, + frame->height, + AV_PIX_FMT_GRAYF32, + 0, NULL, NULL, NULL); + if (!sws_ctx) { + av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion " + "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n", + av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width * 3, frame->height, + av_get_pix_fmt_name(AV_PIX_FMT_GRAYF32),frame->width * 3, frame->height); + return DNN_ERROR; + } + sws_scale(sws_ctx, (const uint8_t **)frame->data, + frame->linesize, 0, frame->height, + (uint8_t * const*)(&input->data), + (const int [4]){frame->width * 3 * sizeof(float), 0, 0, 0}); + sws_freeContext(sws_ctx); + break; + case AV_PIX_FMT_GRAYF32: + av_image_copy_plane(input->data, bytewidth, + frame->data[0], frame->linesize[0], + bytewidth, frame->height); + break; + case AV_PIX_FMT_YUV420P: + case AV_PIX_FMT_YUV422P: + case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUV410P: + case AV_PIX_FMT_YUV411P: + case AV_PIX_FMT_GRAY8: + case AV_PIX_FMT_NV12: + sws_ctx = sws_getContext(frame->width, + frame->height, + AV_PIX_FMT_GRAY8, + frame->width, + frame->height, + AV_PIX_FMT_GRAYF32, + 0, NULL, NULL, NULL); + if (!sws_ctx) { + av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion " + "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n", + av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width, frame->height, + av_get_pix_fmt_name(AV_PIX_FMT_GRAYF32),frame->width, frame->height); + return DNN_ERROR; + } + sws_scale(sws_ctx, (const uint8_t **)frame->data, + frame->linesize, 0, frame->height, + (uint8_t * const*)(&input->data), + (const int [4]){frame->width * sizeof(float), 0, 0, 0}); + sws_freeContext(sws_ctx); + break; + default: + avpriv_report_missing_feature(log_ctx, "%s", av_get_pix_fmt_name(frame->format)); + return DNN_ERROR; + } + + return DNN_SUCCESS; +} + +static enum AVPixelFormat get_pixel_format(DNNData *data) +{ + if (data->dt == DNN_UINT8 && data->order == DCO_BGR) { + return AV_PIX_FMT_BGR24; + } + + av_assert0(!"not supported yet.\n"); + return AV_PIX_FMT_BGR24; +} + +static DNNReturnType proc_from_frame_to_dnn_analytics(AVFrame *frame, DNNData *input, void *log_ctx) +{ + struct SwsContext *sws_ctx; + int linesizes[4]; + enum AVPixelFormat fmt = get_pixel_format(input); + sws_ctx = sws_getContext(frame->width, frame->height, frame->format, + input->width, input->height, fmt, + SWS_FAST_BILINEAR, NULL, NULL, NULL); + if (!sws_ctx) { + av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion " + "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n", + av_get_pix_fmt_name(frame->format), frame->width, frame->height, + av_get_pix_fmt_name(fmt), input->width, input->height); + return DNN_ERROR; + } + + if (av_image_fill_linesizes(linesizes, fmt, input->width) < 0) { + av_log(log_ctx, AV_LOG_ERROR, "unable to get linesizes with av_image_fill_linesizes"); + sws_freeContext(sws_ctx); + return DNN_ERROR; + } + + sws_scale(sws_ctx, (const uint8_t *const *)frame->data, frame->linesize, 0, frame->height, + (uint8_t *const *)(&input->data), linesizes); + + sws_freeContext(sws_ctx); + return DNN_SUCCESS; +} + +DNNReturnType ff_proc_from_frame_to_dnn(AVFrame *frame, DNNData *input, DNNFunctionType func_type, void *log_ctx) +{ + switch (func_type) + { + case DFT_PROCESS_FRAME: + return proc_from_frame_to_dnn_frameprocessing(frame, input, log_ctx); + case DFT_ANALYTICS_DETECT: + return proc_from_frame_to_dnn_analytics(frame, input, log_ctx); + default: + avpriv_report_missing_feature(log_ctx, "model function type %d", func_type); + return DNN_ERROR; + } +} diff --git a/libavfilter/dnn/dnn_io_proc.h b/libavfilter/dnn/dnn_io_proc.h new file mode 100644 index 000000000..91ad3cb26 --- /dev/null +++ b/libavfilter/dnn/dnn_io_proc.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 + * + * 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 + * DNN input&output process between AVFrame and DNNData. + */ + + +#ifndef AVFILTER_DNN_DNN_IO_PROC_H +#define AVFILTER_DNN_DNN_IO_PROC_H + +#include "../dnn_interface.h" +#include "libavutil/frame.h" + +DNNReturnType ff_proc_from_frame_to_dnn(AVFrame *frame, DNNData *input, DNNFunctionType func_type, void *log_ctx); +DNNReturnType ff_proc_from_dnn_to_frame(AVFrame *frame, DNNData *output, void *log_ctx); + +#endif diff --git a/libavfilter/dnn/queue.c b/libavfilter/dnn/queue.c new file mode 100644 index 000000000..954437a8b --- /dev/null +++ b/libavfilter/dnn/queue.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2020 + * + * 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 "queue.h" +#include "libavutil/mem.h" +#include "libavutil/avassert.h" + +typedef struct QueueEntry QueueEntry; + +struct QueueEntry { + void *value; + QueueEntry *prev; + QueueEntry *next; +}; + +struct Queue { + QueueEntry *head; + QueueEntry *tail; + size_t length; +}; + +static inline QueueEntry *create_entry(void *val) +{ + QueueEntry *entry = av_malloc(sizeof(*entry)); + if (entry) + entry->value = val; + return entry; +} + +Queue* ff_queue_create(void) +{ + Queue *q = av_malloc(sizeof(*q)); + if (!q) + return NULL; + + q->head = create_entry(q); + q->tail = create_entry(q); + + if (!q->head || !q->tail) { + av_freep(&q->head); + av_freep(&q->tail); + av_freep(&q); + return NULL; + } + + q->head->next = q->tail; + q->tail->prev = q->head; + q->head->prev = NULL; + q->tail->next = NULL; + q->length = 0; + + return q; +} + +void ff_queue_destroy(Queue *q) +{ + QueueEntry *entry; + if (!q) + return; + + entry = q->head; + while (entry != NULL) { + QueueEntry *temp = entry; + entry = entry->next; + av_freep(&temp); + } + + av_freep(&q); +} + +size_t ff_queue_size(Queue *q) +{ + return q ? q->length : 0; +} + +void *ff_queue_peek_front(Queue *q) +{ + if (!q || q->length == 0) + return NULL; + + return q->head->next->value; +} + +void *ff_queue_peek_back(Queue *q) +{ + if (!q || q->length == 0) + return NULL; + + return q->tail->prev->value; +} + +int ff_queue_push_front(Queue *q, void *v) +{ + QueueEntry *new_entry; + QueueEntry *original_next; + if (!q) + return 0; + + new_entry = create_entry(v); + if (!new_entry) + return -1; + original_next = q->head->next; + + q->head->next = new_entry; + original_next->prev = new_entry; + new_entry->prev = q->head; + new_entry->next = original_next; + q->length++; + + return q->length; +} + +int ff_queue_push_back(Queue *q, void *v) +{ + QueueEntry *new_entry; + QueueEntry *original_prev; + if (!q) + return 0; + + new_entry = create_entry(v); + if (!new_entry) + return -1; + original_prev = q->tail->prev; + + q->tail->prev = new_entry; + original_prev->next = new_entry; + new_entry->next = q->tail; + new_entry->prev = original_prev; + q->length++; + + return q->length; +} + +void *ff_queue_pop_front(Queue *q) +{ + QueueEntry *front; + QueueEntry *new_head_next; + void *ret; + + if (!q || q->length == 0) + return NULL; + + front = q->head->next; + new_head_next = front->next; + ret = front->value; + + q->head->next = new_head_next; + new_head_next->prev = q->head; + + av_freep(&front); + q->length--; + return ret; +} + +void *ff_queue_pop_back(Queue *q) +{ + QueueEntry *back; + QueueEntry *new_tail_prev; + void *ret; + + if (!q || q->length == 0) + return NULL; + + back = q->tail->prev; + new_tail_prev = back->prev; + ret = back->value; + + q->tail->prev = new_tail_prev; + new_tail_prev->next = q->tail; + + av_freep(&back); + q->length--; + return ret; +} diff --git a/libavfilter/dnn/queue.h b/libavfilter/dnn/queue.h new file mode 100644 index 000000000..4d7121366 --- /dev/null +++ b/libavfilter/dnn/queue.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020 + * + * 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 AVFILTER_DNN_QUEUE_H +#define AVFILTER_DNN_QUEUE_H + +typedef struct Queue Queue; + +Queue *ff_queue_create(void); +void ff_queue_destroy(Queue *q); + +size_t ff_queue_size(Queue *q); + +void *ff_queue_peek_front(Queue *q); +void *ff_queue_peek_back(Queue *q); + +int ff_queue_push_front(Queue *q, void *v); +int ff_queue_push_back(Queue *q, void *v); + +void *ff_queue_pop_front(Queue *q); +void *ff_queue_pop_back(Queue *q); + +#endif diff --git a/libavfilter/dnn/safe_queue.c b/libavfilter/dnn/safe_queue.c new file mode 100644 index 000000000..e962d4cb7 --- /dev/null +++ b/libavfilter/dnn/safe_queue.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2020 + * + * 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 "queue.h" +#include "safe_queue.h" +#include "libavutil/mem.h" +#include "libavutil/avassert.h" +#include "libavutil/thread.h" + +#if HAVE_PTHREAD_CANCEL +#define DNNCond pthread_cond_t +#define dnn_cond_init pthread_cond_init +#define dnn_cond_destroy pthread_cond_destroy +#define dnn_cond_signal pthread_cond_signal +#define dnn_cond_wait pthread_cond_wait +#else +#define DNNCond char +static inline int dnn_cond_init(DNNCond *cond, const void *attr) { return 0; } +static inline int dnn_cond_destroy(DNNCond *cond) { return 0; } +static inline int dnn_cond_signal(DNNCond *cond) { return 0; } +static inline int dnn_cond_wait(DNNCond *cond, AVMutex *mutex) +{ + av_assert0(!"should not reach here"); + return 0; +} +#endif + +struct SafeQueue { + Queue *q; + AVMutex mutex; + DNNCond cond; +}; + +SafeQueue *ff_safe_queue_create(void) +{ + SafeQueue *sq = av_malloc(sizeof(*sq)); + if (!sq) + return NULL; + + sq->q = ff_queue_create(); + if (!sq->q) { + av_freep(&sq); + return NULL; + } + + ff_mutex_init(&sq->mutex, NULL); + dnn_cond_init(&sq->cond, NULL); + return sq; +} + +void ff_safe_queue_destroy(SafeQueue *sq) +{ + if (!sq) + return; + + ff_queue_destroy(sq->q); + ff_mutex_destroy(&sq->mutex); + dnn_cond_destroy(&sq->cond); + av_freep(&sq); +} + +size_t ff_safe_queue_size(SafeQueue *sq) +{ + return sq ? ff_queue_size(sq->q) : 0; +} + +int ff_safe_queue_push_front(SafeQueue *sq, void *v) +{ + int ret; + ff_mutex_lock(&sq->mutex); + ret = ff_queue_push_front(sq->q, v); + dnn_cond_signal(&sq->cond); + ff_mutex_unlock(&sq->mutex); + return ret; +} + +int ff_safe_queue_push_back(SafeQueue *sq, void *v) +{ + int ret; + ff_mutex_lock(&sq->mutex); + ret = ff_queue_push_back(sq->q, v); + dnn_cond_signal(&sq->cond); + ff_mutex_unlock(&sq->mutex); + return ret; +} + +void *ff_safe_queue_pop_front(SafeQueue *sq) +{ + void *value; + ff_mutex_lock(&sq->mutex); + while (ff_queue_size(sq->q) == 0) { + dnn_cond_wait(&sq->cond, &sq->mutex); + } + value = ff_queue_pop_front(sq->q); + dnn_cond_signal(&sq->cond); + ff_mutex_unlock(&sq->mutex); + return value; +} diff --git a/libavfilter/dnn/safe_queue.h b/libavfilter/dnn/safe_queue.h new file mode 100644 index 000000000..36d6daaba --- /dev/null +++ b/libavfilter/dnn/safe_queue.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 + * + * 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 AVFILTER_DNN_SAFE_QUEUE_H +#define AVFILTER_DNN_SAFE_QUEUE_H + +typedef struct SafeQueue SafeQueue; + +SafeQueue *ff_safe_queue_create(void); +void ff_safe_queue_destroy(SafeQueue *sq); + +size_t ff_safe_queue_size(SafeQueue *sq); + +int ff_safe_queue_push_front(SafeQueue *sq, void *v); +int ff_safe_queue_push_back(SafeQueue *sq, void *v); + +void *ff_safe_queue_pop_front(SafeQueue *sq); + +#endif diff --git a/libavfilter/dnn_filter_common.c b/libavfilter/dnn_filter_common.c new file mode 100644 index 000000000..413adba40 --- /dev/null +++ b/libavfilter/dnn_filter_common.c @@ -0,0 +1,106 @@ +/* + * 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 "dnn_filter_common.h" + +int ff_dnn_init(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *filter_ctx) +{ + if (!ctx->model_filename) { + av_log(filter_ctx, AV_LOG_ERROR, "model file for network is not specified\n"); + return AVERROR(EINVAL); + } + if (!ctx->model_inputname) { + av_log(filter_ctx, AV_LOG_ERROR, "input name of the model network is not specified\n"); + return AVERROR(EINVAL); + } + if (!ctx->model_outputname) { + av_log(filter_ctx, AV_LOG_ERROR, "output name of the model network is not specified\n"); + return AVERROR(EINVAL); + } + + ctx->dnn_module = ff_get_dnn_module(ctx->backend_type); + if (!ctx->dnn_module) { + av_log(filter_ctx, AV_LOG_ERROR, "could not create DNN module for requested backend\n"); + return AVERROR(ENOMEM); + } + if (!ctx->dnn_module->load_model) { + av_log(filter_ctx, AV_LOG_ERROR, "load_model for network is not specified\n"); + return AVERROR(EINVAL); + } + + ctx->model = (ctx->dnn_module->load_model)(ctx->model_filename, func_type, ctx->backend_options, filter_ctx); + if (!ctx->model) { + av_log(filter_ctx, AV_LOG_ERROR, "could not load DNN model\n"); + return AVERROR(EINVAL); + } + + if (!ctx->dnn_module->execute_model_async && ctx->async) { + ctx->async = 0; + av_log(filter_ctx, AV_LOG_WARNING, "this backend does not support async execution, roll back to sync.\n"); + } + +#if !HAVE_PTHREAD_CANCEL + if (ctx->async) { + ctx->async = 0; + av_log(filter_ctx, AV_LOG_WARNING, "pthread is not supported, roll back to sync.\n"); + } +#endif + + return 0; +} + +DNNReturnType ff_dnn_get_input(DnnContext *ctx, DNNData *input) +{ + return ctx->model->get_input(ctx->model->model, input, ctx->model_inputname); +} + +DNNReturnType ff_dnn_get_output(DnnContext *ctx, int input_width, int input_height, int *output_width, int *output_height) +{ + return ctx->model->get_output(ctx->model->model, ctx->model_inputname, input_width, input_height, + ctx->model_outputname, output_width, output_height); +} + +DNNReturnType ff_dnn_execute_model(DnnContext *ctx, AVFrame *in_frame, AVFrame *out_frame) +{ + return (ctx->dnn_module->execute_model)(ctx->model, ctx->model_inputname, in_frame, + (const char **)&ctx->model_outputname, 1, out_frame); +} + +DNNReturnType ff_dnn_execute_model_async(DnnContext *ctx, AVFrame *in_frame, AVFrame *out_frame) +{ + return (ctx->dnn_module->execute_model_async)(ctx->model, ctx->model_inputname, in_frame, + (const char **)&ctx->model_outputname, 1, out_frame); +} + +DNNAsyncStatusType ff_dnn_get_async_result(DnnContext *ctx, AVFrame **in_frame, AVFrame **out_frame) +{ + return (ctx->dnn_module->get_async_result)(ctx->model, in_frame, out_frame); +} + +DNNReturnType ff_dnn_flush(DnnContext *ctx) +{ + return (ctx->dnn_module->flush)(ctx->model); +} + +void ff_dnn_uninit(DnnContext *ctx) +{ + if (ctx->dnn_module) { + (ctx->dnn_module->free_model)(&ctx->model); + av_freep(&ctx->dnn_module); + } +} diff --git a/libavfilter/dnn_filter_common.h b/libavfilter/dnn_filter_common.h new file mode 100644 index 000000000..79c4d3efe --- /dev/null +++ b/libavfilter/dnn_filter_common.h @@ -0,0 +1,59 @@ +/* + * 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 + * common functions for the dnn based filters + */ + +#ifndef AVFILTER_DNN_FILTER_COMMON_H +#define AVFILTER_DNN_FILTER_COMMON_H + +#include "dnn_interface.h" + +typedef struct DnnContext { + char *model_filename; + DNNBackendType backend_type; + char *model_inputname; + char *model_outputname; + char *backend_options; + int async; + + DNNModule *dnn_module; + DNNModel *model; +} DnnContext; + +#define DNN_COMMON_OPTIONS \ + { "model", "path to model file", OFFSET(model_filename), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },\ + { "input", "input name of the model", OFFSET(model_inputname), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },\ + { "output", "output name of the model", OFFSET(model_outputname), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },\ + { "backend_configs", "backend configs", OFFSET(backend_options), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },\ + { "options", "backend configs", OFFSET(backend_options), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },\ + { "async", "use DNN async inference", OFFSET(async), AV_OPT_TYPE_BOOL, { .i64 = 1}, 0, 1, FLAGS}, + + +int ff_dnn_init(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *filter_ctx); +DNNReturnType ff_dnn_get_input(DnnContext *ctx, DNNData *input); +DNNReturnType ff_dnn_get_output(DnnContext *ctx, int input_width, int input_height, int *output_width, int *output_height); +DNNReturnType ff_dnn_execute_model(DnnContext *ctx, AVFrame *in_frame, AVFrame *out_frame); +DNNReturnType ff_dnn_execute_model_async(DnnContext *ctx, AVFrame *in_frame, AVFrame *out_frame); +DNNAsyncStatusType ff_dnn_get_async_result(DnnContext *ctx, AVFrame **in_frame, AVFrame **out_frame); +DNNReturnType ff_dnn_flush(DnnContext *ctx); +void ff_dnn_uninit(DnnContext *ctx); + +#endif diff --git a/libavfilter/dnn_interface.h b/libavfilter/dnn_interface.h index b20e5c8fa..d3a0c58a6 100644 --- a/libavfilter/dnn_interface.h +++ b/libavfilter/dnn_interface.h @@ -27,36 +27,79 @@ #define AVFILTER_DNN_INTERFACE_H #include +#include "libavutil/frame.h" +#include "avfilter.h" typedef enum {DNN_SUCCESS, DNN_ERROR} DNNReturnType; -typedef enum {DNN_NATIVE, DNN_TF} DNNBackendType; +typedef enum {DNN_NATIVE, DNN_TF, DNN_OV} DNNBackendType; typedef enum {DNN_FLOAT = 1, DNN_UINT8 = 4} DNNDataType; +typedef enum { + DCO_NONE, + DCO_BGR, +} DNNColorOrder; + +typedef enum { + DAST_FAIL, // something wrong + DAST_EMPTY_QUEUE, // no more inference result to get + DAST_NOT_READY, // all queued inferences are not finished + DAST_SUCCESS // got a result frame successfully +} DNNAsyncStatusType; + +typedef enum { + DFT_NONE, + DFT_PROCESS_FRAME, // process the whole frame + DFT_ANALYTICS_DETECT, // detect from the whole frame + // we can add more such as detect_from_crop, classify_from_bbox, etc. +}DNNFunctionType; + typedef struct DNNData{ void *data; - DNNDataType dt; int width, height, channels; + // dt and order together decide the color format + DNNDataType dt; + DNNColorOrder order; } DNNData; typedef struct DNNModel{ // Stores model that can be different for different backends. void *model; + // Stores options when the model is executed by the backend + const char *options; + // Stores FilterContext used for the interaction between AVFrame and DNNData + AVFilterContext *filter_ctx; + // Stores function type of the model + DNNFunctionType func_type; // Gets model input information // Just reuse struct DNNData here, actually the DNNData.data field is not needed. DNNReturnType (*get_input)(void *model, DNNData *input, const char *input_name); - // Sets model input and output. - // Should be called at least once before model execution. - DNNReturnType (*set_input_output)(void *model, DNNData *input, const char *input_name, const char **output_names, uint32_t nb_output); + // Gets model output width/height with given input w/h + DNNReturnType (*get_output)(void *model, const char *input_name, int input_width, int input_height, + const char *output_name, int *output_width, int *output_height); + // set the pre process to transfer data from AVFrame to DNNData + // the default implementation within DNN is used if it is not provided by the filter + int (*pre_proc)(AVFrame *frame_in, DNNData *model_input, AVFilterContext *filter_ctx); + // set the post process to transfer data from DNNData to AVFrame + // the default implementation within DNN is used if it is not provided by the filter + int (*post_proc)(AVFrame *frame_out, DNNData *model_output, AVFilterContext *filter_ctx); } DNNModel; // Stores pointers to functions for loading, executing, freeing DNN models for one of the backends. typedef struct DNNModule{ // Loads model and parameters from given file. Returns NULL if it is not possible. - DNNModel *(*load_model)(const char *model_filename); + DNNModel *(*load_model)(const char *model_filename, DNNFunctionType func_type, const char *options, AVFilterContext *filter_ctx); // Executes model with specified input and output. Returns DNN_ERROR otherwise. - DNNReturnType (*execute_model)(const DNNModel *model, DNNData *outputs, uint32_t nb_output); + DNNReturnType (*execute_model)(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame); + // Executes model with specified input and output asynchronously. Returns DNN_ERROR otherwise. + DNNReturnType (*execute_model_async)(const DNNModel *model, const char *input_name, AVFrame *in_frame, + const char **output_names, uint32_t nb_output, AVFrame *out_frame); + // Retrieve inference result. + DNNAsyncStatusType (*get_async_result)(const DNNModel *model, AVFrame **in, AVFrame **out); + // Flush all the pending tasks. + DNNReturnType (*flush)(const DNNModel *model); // Frees memory allocated for model. void (*free_model)(DNNModel **model); } DNNModule; diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c index 5f4cb548f..0a59ff998 100644 --- a/libavfilter/drawutils.c +++ b/libavfilter/drawutils.c @@ -70,6 +70,10 @@ int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt) case AV_PIX_FMT_GBRAP12BE: case AV_PIX_FMT_GBRAP16LE: case AV_PIX_FMT_GBRAP16BE: + case AV_PIX_FMT_GBRPF32LE: + case AV_PIX_FMT_GBRPF32BE: + case AV_PIX_FMT_GBRAPF32LE: + case AV_PIX_FMT_GBRAPF32BE: case AV_PIX_FMT_GBRP: rgba_map[GREEN] = 0; rgba_map[BLUE ] = 1; rgba_map[RED ] = 2; rgba_map[ALPHA] = 3; break; default: /* unsupported */ return AVERROR(EINVAL); @@ -77,104 +81,6 @@ int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt) return 0; } -int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, uint8_t dst_color[4], - enum AVPixelFormat pix_fmt, uint8_t rgba_color[4], - int *is_packed_rgba, uint8_t rgba_map_ptr[4]) -{ - uint8_t rgba_map[4] = {0}; - int i; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(pix_fmt); - int hsub; - - av_assert0(pix_desc); - - hsub = pix_desc->log2_chroma_w; - - *is_packed_rgba = ff_fill_rgba_map(rgba_map, pix_fmt) >= 0; - - if (*is_packed_rgba) { - pixel_step[0] = (av_get_bits_per_pixel(pix_desc))>>3; - for (i = 0; i < 4; i++) - dst_color[rgba_map[i]] = rgba_color[i]; - - line[0] = av_malloc_array(w, pixel_step[0]); - if (!line[0]) - return AVERROR(ENOMEM); - for (i = 0; i < w; i++) - memcpy(line[0] + i * pixel_step[0], dst_color, pixel_step[0]); - if (rgba_map_ptr) - memcpy(rgba_map_ptr, rgba_map, sizeof(rgba_map[0]) * 4); - } else { - int plane; - - dst_color[0] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]); - dst_color[1] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0); - dst_color[2] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0); - dst_color[3] = rgba_color[3]; - - for (plane = 0; plane < 4; plane++) { - int line_size; - int hsub1 = (plane == 1 || plane == 2) ? hsub : 0; - - pixel_step[plane] = 1; - line_size = AV_CEIL_RSHIFT(w, hsub1) * pixel_step[plane]; - line[plane] = av_malloc(line_size); - if (!line[plane]) { - while(plane && line[plane-1]) - av_freep(&line[--plane]); - return AVERROR(ENOMEM); - } - memset(line[plane], dst_color[plane], line_size); - } - } - - return 0; -} - -void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4], - uint8_t *src[4], int pixelstep[4], - int hsub, int vsub, int x, int y, int w, int h) -{ - int i, plane; - uint8_t *p; - - for (plane = 0; plane < 4 && dst[plane]; plane++) { - int hsub1 = plane == 1 || plane == 2 ? hsub : 0; - int vsub1 = plane == 1 || plane == 2 ? vsub : 0; - int width = AV_CEIL_RSHIFT(w, hsub1); - int height = AV_CEIL_RSHIFT(h, vsub1); - - p = dst[plane] + (y >> vsub1) * dst_linesize[plane]; - for (i = 0; i < height; i++) { - memcpy(p + (x >> hsub1) * pixelstep[plane], - src[plane], width * pixelstep[plane]); - p += dst_linesize[plane]; - } - } -} - -void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4], - uint8_t *src[4], int src_linesize[4], int pixelstep[4], - int hsub, int vsub, int x, int y, int y2, int w, int h) -{ - int i, plane; - uint8_t *p; - - for (plane = 0; plane < 4 && dst[plane]; plane++) { - int hsub1 = plane == 1 || plane == 2 ? hsub : 0; - int vsub1 = plane == 1 || plane == 2 ? vsub : 0; - int width = AV_CEIL_RSHIFT(w, hsub1); - int height = AV_CEIL_RSHIFT(h, vsub1); - - p = dst[plane] + (y >> vsub1) * dst_linesize[plane]; - for (i = 0; i < height; i++) { - memcpy(p + (x >> hsub1) * pixelstep[plane], - src[plane] + src_linesize[plane]*(i+(y2>>vsub1)), width * pixelstep[plane]); - p += dst_linesize[plane]; - } - } -} - int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); diff --git a/libavfilter/drawutils.h b/libavfilter/drawutils.h index b999d70e5..2ca247558 100644 --- a/libavfilter/drawutils.h +++ b/libavfilter/drawutils.h @@ -30,19 +30,6 @@ int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt); -int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, - uint8_t dst_color[4], - enum AVPixelFormat pix_fmt, uint8_t rgba_color[4], - int *is_packed_rgba, uint8_t rgba_map[4]); - -void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4], - uint8_t *src[4], int pixelstep[4], - int hsub, int vsub, int x, int y, int w, int h); - -void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4], - uint8_t *src[4], int src_linesize[4], int pixelstep[4], - int hsub, int vsub, int x, int y, int y2, int w, int h); - #define MAX_PLANES 4 typedef struct FFDrawContext { diff --git a/libavfilter/ebur128.c b/libavfilter/ebur128.c index ca2fca006..d93500ef3 100644 --- a/libavfilter/ebur128.c +++ b/libavfilter/ebur128.c @@ -49,6 +49,7 @@ #include "libavutil/common.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/thread.h" #define CHECK_ERROR(condition, errorcode, goto_point) \ @@ -361,9 +362,6 @@ static void ebur128_filter_##type(FFEBUR128State* st, const type** srcs, st->d->v[ci][1] = fabs(st->d->v[ci][1]) < DBL_MIN ? 0.0 : st->d->v[ci][1]; \ } \ } -EBUR128_FILTER(short, -((double)SHRT_MIN)) -EBUR128_FILTER(int, -((double)INT_MIN)) -EBUR128_FILTER(float, 1.0) EBUR128_FILTER(double, 1.0) static double ebur128_energy_to_loudness(double energy) @@ -458,8 +456,8 @@ int ff_ebur128_set_channel(FFEBUR128State * st, } static int ebur128_energy_shortterm(FFEBUR128State * st, double *out); -#define FF_EBUR128_ADD_FRAMES_PLANAR(type) \ -void ff_ebur128_add_frames_planar_##type(FFEBUR128State* st, const type** srcs, \ +#define EBUR128_ADD_FRAMES_PLANAR(type) \ +static void ebur128_add_frames_planar_##type(FFEBUR128State* st, const type** srcs, \ size_t frames, int stride) { \ size_t src_index = 0; \ while (frames > 0) { \ @@ -501,10 +499,7 @@ void ff_ebur128_add_frames_planar_##type(FFEBUR128State* st, const type** srcs, } \ } \ } -FF_EBUR128_ADD_FRAMES_PLANAR(short) -FF_EBUR128_ADD_FRAMES_PLANAR(int) -FF_EBUR128_ADD_FRAMES_PLANAR(float) -FF_EBUR128_ADD_FRAMES_PLANAR(double) +EBUR128_ADD_FRAMES_PLANAR(double) #define FF_EBUR128_ADD_FRAMES(type) \ void ff_ebur128_add_frames_##type(FFEBUR128State* st, const type* src, \ size_t frames) { \ @@ -512,11 +507,8 @@ void ff_ebur128_add_frames_##type(FFEBUR128State* st, const type* src, \ const type **buf = (const type**)st->d->data_ptrs; \ for (i = 0; i < st->channels; i++) \ buf[i] = src + i; \ - ff_ebur128_add_frames_planar_##type(st, buf, frames, st->channels); \ + ebur128_add_frames_planar_##type(st, buf, frames, st->channels); \ } -FF_EBUR128_ADD_FRAMES(short) -FF_EBUR128_ADD_FRAMES(int) -FF_EBUR128_ADD_FRAMES(float) FF_EBUR128_ADD_FRAMES(double) static int ebur128_calc_relative_threshold(FFEBUR128State **sts, size_t size, @@ -605,12 +597,6 @@ int ff_ebur128_loudness_global(FFEBUR128State * st, double *out) return ebur128_gated_loudness(&st, 1, out); } -int ff_ebur128_loudness_global_multiple(FFEBUR128State ** sts, size_t size, - double *out) -{ - return ebur128_gated_loudness(sts, size, out); -} - static int ebur128_energy_in_interval(FFEBUR128State * st, size_t interval_frames, double *out) { @@ -627,21 +613,6 @@ static int ebur128_energy_shortterm(FFEBUR128State * st, double *out) out); } -int ff_ebur128_loudness_momentary(FFEBUR128State * st, double *out) -{ - double energy; - int error = ebur128_energy_in_interval(st, st->d->samples_in_100ms * 4, - &energy); - if (error) { - return error; - } else if (energy <= 0.0) { - *out = -HUGE_VAL; - return 0; - } - *out = ebur128_energy_to_loudness(energy); - return 0; -} - int ff_ebur128_loudness_shortterm(FFEBUR128State * st, double *out) { double energy; @@ -656,22 +627,6 @@ int ff_ebur128_loudness_shortterm(FFEBUR128State * st, double *out) return 0; } -int ff_ebur128_loudness_window(FFEBUR128State * st, - unsigned long window, double *out) -{ - double energy; - size_t interval_frames = st->samplerate * window / 1000; - int error = ebur128_energy_in_interval(st, interval_frames, &energy); - if (error) { - return error; - } else if (energy <= 0.0) { - *out = -HUGE_VAL; - return 0; - } - *out = ebur128_energy_to_loudness(energy); - return 0; -} - /* EBU - TECH 3342 */ int ff_ebur128_loudness_range_multiple(FFEBUR128State ** sts, size_t size, double *out) diff --git a/libavfilter/ebur128.h b/libavfilter/ebur128.h index 74367545e..8e7385e04 100644 --- a/libavfilter/ebur128.h +++ b/libavfilter/ebur128.h @@ -81,7 +81,7 @@ enum channel { * modes that suit your needs, as performance will be better. */ enum mode { - /** can call ff_ebur128_loudness_momentary */ + /** can resurrrect and call ff_ebur128_loudness_momentary */ FF_EBUR128_MODE_M = (1 << 0), /** can call ff_ebur128_loudness_shortterm */ FF_EBUR128_MODE_S = (1 << 1) | FF_EBUR128_MODE_M, @@ -151,41 +151,9 @@ int ff_ebur128_set_channel(FFEBUR128State * st, * @param src array of source frames. Channels must be interleaved. * @param frames number of frames. Not number of samples! */ -void ff_ebur128_add_frames_short(FFEBUR128State * st, - const short *src, size_t frames); -/** \brief See \ref ebur128_add_frames_short */ -void ff_ebur128_add_frames_int(FFEBUR128State * st, - const int *src, size_t frames); -/** \brief See \ref ebur128_add_frames_short */ -void ff_ebur128_add_frames_float(FFEBUR128State * st, - const float *src, size_t frames); -/** \brief See \ref ebur128_add_frames_short */ void ff_ebur128_add_frames_double(FFEBUR128State * st, const double *src, size_t frames); -/** \brief Add frames to be processed. - * - * @param st library state. - * @param srcs array of source frame channel data pointers - * @param frames number of frames. Not number of samples! - * @param stride number of samples to skip to for the next sample of the same channel - */ -void ff_ebur128_add_frames_planar_short(FFEBUR128State * st, - const short **srcs, - size_t frames, int stride); -/** \brief See \ref ebur128_add_frames_planar_short */ -void ff_ebur128_add_frames_planar_int(FFEBUR128State * st, - const int **srcs, - size_t frames, int stride); -/** \brief See \ref ebur128_add_frames_planar_short */ -void ff_ebur128_add_frames_planar_float(FFEBUR128State * st, - const float **srcs, - size_t frames, int stride); -/** \brief See \ref ebur128_add_frames_planar_short */ -void ff_ebur128_add_frames_planar_double(FFEBUR128State * st, - const double **srcs, - size_t frames, int stride); - /** \brief Get global integrated loudness in LUFS. * * @param st library state. @@ -196,28 +164,7 @@ void ff_ebur128_add_frames_planar_double(FFEBUR128State * st, * - AVERROR(EINVAL) if mode "FF_EBUR128_MODE_I" has not been set. */ int ff_ebur128_loudness_global(FFEBUR128State * st, double *out); -/** \brief Get global integrated loudness in LUFS across multiple instances. - * - * @param sts array of library states. - * @param size length of sts - * @param out integrated loudness in LUFS. -HUGE_VAL if result is negative - * infinity. - * @return - * - 0 on success. - * - AVERROR(EINVAL) if mode "FF_EBUR128_MODE_I" has not been set. - */ -int ff_ebur128_loudness_global_multiple(FFEBUR128State ** sts, - size_t size, double *out); -/** \brief Get momentary loudness (last 400ms) in LUFS. - * - * @param st library state. - * @param out momentary loudness in LUFS. -HUGE_VAL if result is negative - * infinity. - * @return - * - 0 on success. - */ -int ff_ebur128_loudness_momentary(FFEBUR128State * st, double *out); /** \brief Get short-term loudness (last 3s) in LUFS. * * @param st library state. @@ -229,20 +176,6 @@ int ff_ebur128_loudness_momentary(FFEBUR128State * st, double *out); */ int ff_ebur128_loudness_shortterm(FFEBUR128State * st, double *out); -/** \brief Get loudness of the specified window in LUFS. - * - * window must not be larger than the current window set in st. - * - * @param st library state. - * @param window window in ms to calculate loudness. - * @param out loudness in LUFS. -HUGE_VAL if result is negative infinity. - * @return - * - 0 on success. - * - AVERROR(EINVAL) if window larger than current window in st. - */ -int ff_ebur128_loudness_window(FFEBUR128State * st, - unsigned long window, double *out); - /** \brief Get loudness range (LRA) of programme in LU. * * Calculates loudness range according to EBU 3342. diff --git a/libavfilter/f_drawgraph.c b/libavfilter/f_drawgraph.c index 030afb9b4..b9dd26d39 100644 --- a/libavfilter/f_drawgraph.c +++ b/libavfilter/f_drawgraph.c @@ -134,7 +134,7 @@ static int query_formats(AVFilterContext *ctx) int ret; AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(fmts_list, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(fmts_list, &outlink->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c index 31b75ab09..e81520838 100644 --- a/libavfilter/f_ebur128.c +++ b/libavfilter/f_ebur128.c @@ -527,30 +527,22 @@ static av_cold int init(AVFilterContext *ctx) /* insert output pads */ if (ebur128->do_video) { pad = (AVFilterPad){ - .name = av_strdup("out0"), + .name = "out0", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_video_output, }; - if (!pad.name) - return AVERROR(ENOMEM); ret = ff_insert_outpad(ctx, 0, &pad); - if (ret < 0) { - av_freep(&pad.name); + if (ret < 0) return ret; - } } pad = (AVFilterPad){ - .name = av_asprintf("out%d", ebur128->do_video), + .name = ebur128->do_video ? "out1" : "out0", .type = AVMEDIA_TYPE_AUDIO, .config_props = config_audio_output, }; - if (!pad.name) - return AVERROR(ENOMEM); ret = ff_insert_outpad(ctx, ebur128->do_video, &pad); - if (ret < 0) { - av_freep(&pad.name); + if (ret < 0) return ret; - } /* summary */ av_log(ctx, AV_LOG_VERBOSE, "EBU +%d scale\n", ebur128->meter); @@ -910,7 +902,7 @@ static int query_formats(AVFilterContext *ctx) /* set optional output video format */ if (ebur128->do_video) { formats = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; outlink = ctx->outputs[1]; } @@ -919,18 +911,18 @@ static int query_formats(AVFilterContext *ctx) * Note: ff_set_common_* functions are not used because they affect all the * links, and thus break the video format negotiation */ formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0 || - (ret = ff_formats_ref(formats, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0 || + (ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) return ret; layouts = ff_all_channel_layouts(); - if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0 || - (ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0 || + (ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts)) < 0) return ret; formats = ff_make_format_list(input_srate); - if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0 || - (ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0 || + (ret = ff_formats_ref(formats, &outlink->incfg.samplerates)) < 0) return ret; return 0; @@ -990,8 +982,6 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&ebur128->i400.cache[i]); av_freep(&ebur128->i3000.cache[i]); } - for (i = 0; i < ctx->nb_outputs; i++) - av_freep(&ctx->output_pads[i].name); av_frame_free(&ebur128->outpicref); #if CONFIG_SWRESAMPLE av_freep(&ebur128->swr_buf); diff --git a/libavfilter/f_graphmonitor.c b/libavfilter/f_graphmonitor.c index a9c4ba42f..74779965d 100644 --- a/libavfilter/f_graphmonitor.c +++ b/libavfilter/f_graphmonitor.c @@ -47,6 +47,7 @@ typedef struct GraphMonitorContext { uint8_t yellow[4]; uint8_t red[4]; uint8_t green[4]; + uint8_t blue[4]; uint8_t bg[4]; } GraphMonitorContext; @@ -60,6 +61,7 @@ enum { MODE_FMT = 1 << 6, MODE_SIZE = 1 << 7, MODE_RATE = 1 << 8, + MODE_EOF = 1 << 9, }; #define OFFSET(x) offsetof(GraphMonitorContext, x) @@ -85,6 +87,7 @@ static const AVOption graphmonitor_options[] = { { "format", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_FMT}, 0, 0, VF, "flags" }, { "size", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_SIZE}, 0, 0, VF, "flags" }, { "rate", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_RATE}, 0, 0, VF, "flags" }, + { "eof", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_EOF}, 0, 0, VF, "flags" }, { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, VF }, { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, VF }, { NULL } @@ -100,7 +103,7 @@ static int query_formats(AVFilterContext *ctx) int ret; AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); - if ((ret = ff_formats_ref(fmts_list, &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(fmts_list, &outlink->incfg.formats)) < 0) return ret; return 0; @@ -236,6 +239,11 @@ static void draw_items(AVFilterContext *ctx, AVFrame *out, drawtext(out, xpos, ypos, buffer, s->white); xpos += strlen(buffer) * 8; } + if (s->flags & MODE_EOF && ff_outlink_get_status(l)) { + snprintf(buffer, sizeof(buffer)-1, " | eof"); + drawtext(out, xpos, ypos, buffer, s->blue); + xpos += strlen(buffer) * 8; + } } static int create_frame(AVFilterContext *ctx, int64_t pts) @@ -352,6 +360,7 @@ static int config_output(AVFilterLink *outlink) s->yellow[0] = s->yellow[1] = 255; s->red[0] = 255; s->green[1] = 255; + s->blue[2] = 255; s->pts = AV_NOPTS_VALUE; s->next_pts = AV_NOPTS_VALUE; outlink->w = s->w; diff --git a/libavfilter/f_interleave.c b/libavfilter/f_interleave.c index a18bbe79b..024657c02 100644 --- a/libavfilter/f_interleave.c +++ b/libavfilter/f_interleave.c @@ -65,17 +65,35 @@ static int activate(AVFilterContext *ctx) InterleaveContext *s = ctx->priv; int64_t q_pts, pts = INT64_MAX; int i, nb_eofs = 0, input_idx = -1; + int first_eof = 0; + int64_t rpts; + int status; int nb_inputs_with_frames = 0; FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx); + for (i = 0; i < ctx->nb_inputs; i++) { + int is_eof = !!ff_inlink_acknowledge_status(ctx->inputs[i], &status, &rpts); + + nb_eofs += is_eof; + if (i == 0) + first_eof = is_eof; + } + + if ((nb_eofs > 0 && s->duration_mode == DURATION_SHORTEST) || + (nb_eofs == ctx->nb_inputs && s->duration_mode == DURATION_LONGEST) || + (first_eof && s->duration_mode == DURATION_FIRST)) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->pts); + return 0; + } + for (i = 0; i < ctx->nb_inputs; i++) { if (!ff_inlink_queued_frames(ctx->inputs[i])) continue; nb_inputs_with_frames++; } - if (nb_inputs_with_frames > 0) { + if (nb_inputs_with_frames >= ctx->nb_inputs - nb_eofs) { for (i = 0; i < ctx->nb_inputs; i++) { AVFrame *frame; @@ -115,16 +133,6 @@ static int activate(AVFilterContext *ctx) } } - for (i = 0; i < ctx->nb_inputs; i++) - nb_eofs += !!ff_outlink_get_status(ctx->inputs[i]); - - if ((nb_eofs > 0 && s->duration_mode == DURATION_SHORTEST) || - (nb_eofs == ctx->nb_inputs && s->duration_mode == DURATION_LONGEST) || - (ff_outlink_get_status(ctx->inputs[0]) && s->duration_mode == DURATION_FIRST)) { - ff_outlink_set_status(outlink, AVERROR_EOF, s->pts); - return 0; - } - for (i = 0; i < ctx->nb_inputs; i++) { if (ff_inlink_queued_frames(ctx->inputs[i])) continue; @@ -135,7 +143,7 @@ static int activate(AVFilterContext *ctx) } } - if (i) { + if (i == ctx->nb_inputs - nb_eofs && ff_outlink_frame_wanted(outlink)) { ff_filter_set_ready(ctx, 100); return 0; } diff --git a/libavfilter/f_perms.c b/libavfilter/f_perms.c index dc6ecbbb5..d984e5b15 100644 --- a/libavfilter/f_perms.c +++ b/libavfilter/f_perms.c @@ -141,6 +141,7 @@ AVFilter ff_af_aperms = { .inputs = aperms_inputs, .outputs = aperms_outputs, .priv_class = &aperms_class, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; #endif /* CONFIG_APERMS_FILTER */ @@ -174,5 +175,6 @@ AVFilter ff_vf_perms = { .inputs = perms_inputs, .outputs = perms_outputs, .priv_class = &perms_class, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; #endif /* CONFIG_PERMS_FILTER */ diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c index 755e10a39..92938c33a 100644 --- a/libavfilter/f_select.c +++ b/libavfilter/f_select.c @@ -325,9 +325,6 @@ static double get_concatdec_select(AVFrame *frame, int64_t pts) return NAN; } -#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) - static void select_frame(AVFilterContext *ctx, AVFrame *frame) { SelectContext *select = ctx->priv; diff --git a/libavfilter/f_sendcmd.c b/libavfilter/f_sendcmd.c index 0ac87e07e..6b02669af 100644 --- a/libavfilter/f_sendcmd.c +++ b/libavfilter/f_sendcmd.c @@ -475,9 +475,6 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&s->intervals); } -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *ref) { AVFilterContext *ctx = inlink->dst; diff --git a/libavfilter/f_sidedata.c b/libavfilter/f_sidedata.c index 4210dcac4..375772337 100644 --- a/libavfilter/f_sidedata.c +++ b/libavfilter/f_sidedata.c @@ -71,6 +71,7 @@ static const AVOption filt_name##_options[] = { \ { "S12M_TIMECOD", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_S12M_TIMECODE }, 0, 0, FLAGS, "type" }, \ { "DYNAMIC_HDR_PLUS", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_DYNAMIC_HDR_PLUS }, 0, 0, FLAGS, "type" }, \ { "REGIONS_OF_INTEREST", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_REGIONS_OF_INTEREST }, 0, 0, FLAGS, "type" }, \ + { "SEI_UNREGISTERED", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_SEI_UNREGISTERED }, 0, 0, FLAGS, "type" }, \ { NULL } \ } #else @@ -99,6 +100,7 @@ static const AVOption filt_name##_options[] = { \ { "S12M_TIMECOD", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_S12M_TIMECODE }, 0, 0, FLAGS, "type" }, \ { "DYNAMIC_HDR_PLUS", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_DYNAMIC_HDR_PLUS }, 0, 0, FLAGS, "type" }, \ { "REGIONS_OF_INTEREST", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_REGIONS_OF_INTEREST }, 0, 0, FLAGS, "type" }, \ + { "SEI_UNREGISTERED", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_SEI_UNREGISTERED }, 0, 0, FLAGS, "type" }, \ { NULL } \ } #endif diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index f5587df62..5b39e1afe 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -23,16 +23,12 @@ * FIFO buffering filter */ -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/mathematics.h" -#include "libavutil/samplefmt.h" #include "audio.h" #include "avfilter.h" #include "internal.h" -#include "video.h" typedef struct Buf { AVFrame *frame; @@ -98,157 +94,19 @@ static void queue_pop(FifoContext *s) s->root.next = tmp; } -/** - * Move data pointers and pts offset samples forward. - */ -static void buffer_offset(AVFilterLink *link, AVFrame *frame, - int offset) -{ - int nb_channels = link->channels; - int planar = av_sample_fmt_is_planar(link->format); - int planes = planar ? nb_channels : 1; - int block_align = av_get_bytes_per_sample(link->format) * (planar ? 1 : nb_channels); - int i; - - av_assert0(frame->nb_samples > offset); - - for (i = 0; i < planes; i++) - frame->extended_data[i] += block_align * offset; - if (frame->data != frame->extended_data) - memcpy(frame->data, frame->extended_data, - FFMIN(planes, FF_ARRAY_ELEMS(frame->data)) * sizeof(*frame->data)); - frame->linesize[0] -= block_align*offset; - frame->nb_samples -= offset; - - if (frame->pts != AV_NOPTS_VALUE) { - frame->pts += av_rescale_q(offset, (AVRational){1, link->sample_rate}, - link->time_base); - } -} - -static int calc_ptr_alignment(AVFrame *frame) -{ - int planes = av_sample_fmt_is_planar(frame->format) ? - frame->channels : 1; - int min_align = 128; - int p; - - for (p = 0; p < planes; p++) { - int cur_align = 128; - while ((intptr_t)frame->extended_data[p] % cur_align) - cur_align >>= 1; - if (cur_align < min_align) - min_align = cur_align; - } - return min_align; -} - -static int return_audio_frame(AVFilterContext *ctx) -{ - AVFilterLink *link = ctx->outputs[0]; - FifoContext *s = ctx->priv; - AVFrame *head = s->root.next ? s->root.next->frame : NULL; - AVFrame *out; - int ret; - - /* if head is NULL then we're flushing the remaining samples in out */ - if (!head && !s->out) - return AVERROR_EOF; - - if (!s->out && - head->nb_samples >= link->request_samples && - calc_ptr_alignment(head) >= 32) { - if (head->nb_samples == link->request_samples) { - out = head; - queue_pop(s); - } else { - out = av_frame_clone(head); - if (!out) - return AVERROR(ENOMEM); - - out->nb_samples = link->request_samples; - buffer_offset(link, head, link->request_samples); - } - } else { - int nb_channels = link->channels; - - if (!s->out) { - s->out = ff_get_audio_buffer(link, link->request_samples); - if (!s->out) - return AVERROR(ENOMEM); - - s->out->nb_samples = 0; - s->out->pts = head->pts; - s->allocated_samples = link->request_samples; - } else if (link->request_samples != s->allocated_samples) { - av_log(ctx, AV_LOG_ERROR, "request_samples changed before the " - "buffer was returned.\n"); - return AVERROR(EINVAL); - } - - while (s->out->nb_samples < s->allocated_samples) { - int len; - - if (!s->root.next) { - ret = ff_request_frame(ctx->inputs[0]); - if (ret == AVERROR_EOF) { - av_samples_set_silence(s->out->extended_data, - s->out->nb_samples, - s->allocated_samples - - s->out->nb_samples, - nb_channels, link->format); - s->out->nb_samples = s->allocated_samples; - break; - } else if (ret < 0) - return ret; - if (!s->root.next) - return 0; - } - head = s->root.next->frame; - - len = FFMIN(s->allocated_samples - s->out->nb_samples, - head->nb_samples); - - av_samples_copy(s->out->extended_data, head->extended_data, - s->out->nb_samples, 0, len, nb_channels, - link->format); - s->out->nb_samples += len; - - if (len == head->nb_samples) { - av_frame_free(&head); - queue_pop(s); - } else { - buffer_offset(link, head, len); - } - } - out = s->out; - s->out = NULL; - } - return ff_filter_frame(link, out); -} - static int request_frame(AVFilterLink *outlink) { FifoContext *s = outlink->src->priv; int ret = 0; if (!s->root.next) { - if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0) { - if (ret == AVERROR_EOF && outlink->request_samples) - return return_audio_frame(outlink->src); + if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0) return ret; - } if (!s->root.next) return 0; } - - if (outlink->request_samples) { - return return_audio_frame(outlink->src); - } else { - ret = ff_filter_frame(outlink, s->root.next->frame); - queue_pop(s); - } - + ret = ff_filter_frame(outlink, s->root.next->frame); + queue_pop(s); return ret; } diff --git a/libavfilter/formats.c b/libavfilter/formats.c index de4315369..713173e70 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -24,7 +24,6 @@ #include "libavutil/common.h" #include "libavutil/eval.h" #include "libavutil/pixdesc.h" -#include "libavutil/parseutils.h" #include "avfilter.h" #include "internal.h" #include "formats.h" @@ -34,14 +33,14 @@ /** * Add all refs from a to ret and destroy a. */ -#define MERGE_REF(ret, a, fmts, type, fail) \ +#define MERGE_REF(ret, a, fmts, type, fail_statement) \ do { \ type ***tmp; \ int i; \ \ if (!(tmp = av_realloc_array(ret->refs, ret->refcount + a->refcount, \ sizeof(*tmp)))) \ - goto fail; \ + { fail_statement } \ ret->refs = tmp; \ \ for (i = 0; i < a->refcount; i ++) { \ @@ -55,50 +54,54 @@ do { \ } while (0) /** - * Add all formats common for a and b to ret, copy the refs and destroy - * a and b. + * Add all formats common to a and b to a, add b's refs to a and destroy b. + * If check is set, nothing is modified and it is only checked whether + * the formats are compatible. + * If empty_allowed is set and one of a,b->nb is zero, the lists are + * merged; otherwise, it is treated as error. */ -#define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail) \ -do { \ - int i, j, k = 0, count = FFMIN(a->nb, b->nb); \ - \ - if (!(ret = av_mallocz(sizeof(*ret)))) \ - goto fail; \ - \ - if (count) { \ - if (!(ret->fmts = av_malloc_array(count, sizeof(*ret->fmts)))) \ - goto fail; \ - for (i = 0; i < a->nb; i++) \ - for (j = 0; j < b->nb; j++) \ - if (a->fmts[i] == b->fmts[j]) { \ - if(k >= FFMIN(a->nb, b->nb)){ \ - av_log(NULL, AV_LOG_ERROR, "Duplicate formats in %s detected\n", __FUNCTION__); \ - av_free(ret->fmts); \ - av_free(ret); \ - return NULL; \ - } \ - ret->fmts[k++] = a->fmts[i]; \ - } \ - } \ - ret->nb = k; \ - /* check that there was at least one common format */ \ - if (!ret->nb) \ - goto fail; \ - \ - MERGE_REF(ret, a, fmts, type, fail); \ - MERGE_REF(ret, b, fmts, type, fail); \ +#define MERGE_FORMATS(a, b, fmts, nb, type, check, empty_allowed) \ +do { \ + int i, j, k = 0, skip = 0; \ + \ + if (empty_allowed) { \ + if (!a->nb || !b->nb) { \ + if (check) \ + return 1; \ + if (!a->nb) \ + FFSWAP(type *, a, b); \ + skip = 1; \ + } \ + } \ + if (!skip) { \ + for (i = 0; i < a->nb; i++) \ + for (j = 0; j < b->nb; j++) \ + if (a->fmts[i] == b->fmts[j]) { \ + if (check) \ + return 1; \ + a->fmts[k++] = a->fmts[i]; \ + break; \ + } \ + /* Check that there was at least one common format. \ + * Notice that both a and b are unchanged if not. */ \ + if (!k) \ + return 0; \ + av_assert2(!check); \ + a->nb = k; \ + } \ + \ + MERGE_REF(a, b, fmts, type, return AVERROR(ENOMEM);); \ } while (0) -AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, - enum AVMediaType type) +static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b, + enum AVMediaType type, int check) { - AVFilterFormats *ret = NULL; int i, j; int alpha1=0, alpha2=0; int chroma1=0, chroma2=0; if (a == b) - return a; + return 1; /* Do not lose chroma or alpha in merging. It happens if both lists have formats with chroma (resp. alpha), but @@ -122,56 +125,58 @@ AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, // If chroma or alpha can be lost through merging then do not merge if (alpha2 > alpha1 || chroma2 > chroma1) - return NULL; + return 0; - MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail); + MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0); - return ret; -fail: - if (ret) { - av_freep(&ret->refs); - av_freep(&ret->formats); - } - av_freep(&ret); - return NULL; + return 1; } -AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a, - AVFilterFormats *b) +int ff_can_merge_formats(const AVFilterFormats *a, const AVFilterFormats *b, + enum AVMediaType type) { - AVFilterFormats *ret = NULL; - - if (a == b) return a; - - if (a->nb_formats && b->nb_formats) { - MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail); - } else if (a->nb_formats) { - MERGE_REF(a, b, formats, AVFilterFormats, fail); - ret = a; - } else { - MERGE_REF(b, a, formats, AVFilterFormats, fail); - ret = b; - } - - return ret; -fail: - if (ret) { - av_freep(&ret->refs); - av_freep(&ret->formats); - } - av_freep(&ret); - return NULL; + return merge_formats_internal((AVFilterFormats *)a, + (AVFilterFormats *)b, type, 1); } -AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, - AVFilterChannelLayouts *b) +int ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, + enum AVMediaType type) { - AVFilterChannelLayouts *ret = NULL; + av_assert2(a->refcount && b->refcount); + return merge_formats_internal(a, b, type, 0); +} + +static int merge_samplerates_internal(AVFilterFormats *a, + AVFilterFormats *b, int check) +{ + if (a == b) return 1; + + MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 1); + return 1; +} + +int ff_can_merge_samplerates(const AVFilterFormats *a, const AVFilterFormats *b) +{ + return merge_samplerates_internal((AVFilterFormats *)a, (AVFilterFormats *)b, 1); +} + +int ff_merge_samplerates(AVFilterFormats *a, AVFilterFormats *b) +{ + av_assert2(a->refcount && b->refcount); + return merge_samplerates_internal(a, b, 0); +} + +int ff_merge_channel_layouts(AVFilterChannelLayouts *a, + AVFilterChannelLayouts *b) +{ + uint64_t *channel_layouts; unsigned a_all = a->all_layouts + a->all_counts; unsigned b_all = b->all_layouts + b->all_counts; int ret_max, ret_nb = 0, i, j, round; - if (a == b) return a; + av_assert2(a->refcount && b->refcount); + + if (a == b) return 1; /* Put the most generic set in a, to avoid doing everything twice */ if (a_all < b_all) { @@ -187,18 +192,16 @@ AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, /* Not optimal: the unknown layouts of b may become known after another merge. */ if (!j) - return NULL; + return 0; b->nb_channel_layouts = j; } - MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail); - return b; + MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return AVERROR(ENOMEM);); + return 1; } ret_max = a->nb_channel_layouts + b->nb_channel_layouts; - if (!(ret = av_mallocz(sizeof(*ret))) || - !(ret->channel_layouts = av_malloc_array(ret_max, - sizeof(*ret->channel_layouts)))) - goto fail; + if (!(channel_layouts = av_malloc_array(ret_max, sizeof(*channel_layouts)))) + return AVERROR(ENOMEM); /* a[known] intersect b[known] */ for (i = 0; i < a->nb_channel_layouts; i++) { @@ -206,8 +209,9 @@ AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, continue; for (j = 0; j < b->nb_channel_layouts; j++) { if (a->channel_layouts[i] == b->channel_layouts[j]) { - ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; + channel_layouts[ret_nb++] = a->channel_layouts[i]; a->channel_layouts[i] = b->channel_layouts[j] = 0; + break; } } } @@ -221,7 +225,7 @@ AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt)); for (j = 0; j < b->nb_channel_layouts; j++) if (b->channel_layouts[j] == bfmt) - ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; + channel_layouts[ret_nb++] = a->channel_layouts[i]; } /* 1st round: swap to prepare 2nd round; 2nd round: put it back */ FFSWAP(AVFilterChannelLayouts *, a, b); @@ -232,23 +236,23 @@ AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, continue; for (j = 0; j < b->nb_channel_layouts; j++) if (a->channel_layouts[i] == b->channel_layouts[j]) - ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; + channel_layouts[ret_nb++] = a->channel_layouts[i]; } - ret->nb_channel_layouts = ret_nb; - if (!ret->nb_channel_layouts) - goto fail; - MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail); - MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail); - return ret; - -fail: - if (ret) { - av_freep(&ret->refs); - av_freep(&ret->channel_layouts); + if (!ret_nb) { + av_free(channel_layouts); + return 0; } - av_freep(&ret); - return NULL; + + if (a->refcount > b->refcount) + FFSWAP(AVFilterChannelLayouts *, a, b); + + MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, + { av_free(channel_layouts); return AVERROR(ENOMEM); }); + av_freep(&b->channel_layouts); + b->channel_layouts = channel_layouts; + b->nb_channel_layouts = ret_nb; + return 1; } int ff_fmt_is_in(int fmt, const int *fmts) @@ -289,7 +293,7 @@ AVFilterFormats *ff_make_format_list(const int *fmts) return formats; } -AVFilterChannelLayouts *ff_make_formatu64_list(const uint64_t *fmts) +AVFilterChannelLayouts *ff_make_format64_list(const int64_t *fmts) { MAKE_FORMAT_LIST(AVFilterChannelLayouts, channel_layouts, nb_channel_layouts); @@ -300,21 +304,16 @@ AVFilterChannelLayouts *ff_make_formatu64_list(const uint64_t *fmts) return formats; } +#if LIBAVFILTER_VERSION_MAJOR < 8 AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts) { - MAKE_FORMAT_LIST(AVFilterChannelLayouts, - channel_layouts, nb_channel_layouts); - if (count) - memcpy(formats->channel_layouts, fmts, - sizeof(*formats->channel_layouts) * count); - - return formats; + return ff_make_format64_list(fmts); } +#endif #define ADD_FORMAT(f, fmt, unref_fn, type, list, nb) \ do { \ type *fmts; \ - void *oldf = *f; \ \ if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) { \ return AVERROR(ENOMEM); \ @@ -324,8 +323,6 @@ do { \ sizeof(*(*f)->list)); \ if (!fmts) { \ unref_fn(f); \ - if (!oldf) \ - av_freep(f); \ return AVERROR(ENOMEM); \ } \ \ @@ -449,7 +446,7 @@ AVFilterChannelLayouts *ff_all_channel_counts(void) #define FORMATS_REF(f, ref, unref_fn) \ void *tmp; \ \ - if (!f || !ref) \ + if (!f) \ return AVERROR(ENOMEM); \ \ tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1); \ @@ -486,16 +483,17 @@ do { \ do { \ int idx = -1; \ \ - if (!ref || !*ref || !(*ref)->refs) \ + if (!*ref) \ return; \ \ FIND_REF_INDEX(ref, idx); \ \ - if (idx >= 0) \ + if (idx >= 0) { \ memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \ sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \ - \ - if(!--(*ref)->refcount) { \ + --(*ref)->refcount; \ + } \ + if (!(*ref)->refcount) { \ av_free((*ref)->list); \ av_free((*ref)->refs); \ av_free(*ref); \ @@ -537,33 +535,25 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref) FORMATS_CHANGEREF(oldref, newref); } -#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref_fn, unref_fn, list) \ +#define SET_COMMON_FORMATS(ctx, fmts, ref_fn, unref_fn) \ int count = 0, i; \ \ if (!fmts) \ return AVERROR(ENOMEM); \ \ for (i = 0; i < ctx->nb_inputs; i++) { \ - if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) { \ - int ret = ref_fn(fmts, &ctx->inputs[i]->out_fmts); \ + if (ctx->inputs[i] && !ctx->inputs[i]->outcfg.fmts) { \ + int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts); \ if (ret < 0) { \ - unref_fn(&fmts); \ - if (fmts) \ - av_freep(&fmts->list); \ - av_freep(&fmts); \ return ret; \ } \ count++; \ } \ } \ for (i = 0; i < ctx->nb_outputs; i++) { \ - if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) { \ - int ret = ref_fn(fmts, &ctx->outputs[i]->in_fmts); \ + if (ctx->outputs[i] && !ctx->outputs[i]->incfg.fmts) { \ + int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts); \ if (ret < 0) { \ - unref_fn(&fmts); \ - if (fmts) \ - av_freep(&fmts->list); \ - av_freep(&fmts); \ return ret; \ } \ count++; \ @@ -571,25 +561,23 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref) } \ \ if (!count) { \ - av_freep(&fmts->list); \ - av_freep(&fmts->refs); \ - av_freep(&fmts); \ + unref_fn(&fmts); \ } \ \ return 0; int ff_set_common_channel_layouts(AVFilterContext *ctx, - AVFilterChannelLayouts *layouts) + AVFilterChannelLayouts *channel_layouts) { - SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts, - ff_channel_layouts_ref, ff_channel_layouts_unref, channel_layouts); + SET_COMMON_FORMATS(ctx, channel_layouts, + ff_channel_layouts_ref, ff_channel_layouts_unref); } int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates) { - SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates, - ff_formats_ref, ff_formats_unref, formats); + SET_COMMON_FORMATS(ctx, samplerates, + ff_formats_ref, ff_formats_unref); } /** @@ -599,23 +587,22 @@ int ff_set_common_samplerates(AVFilterContext *ctx, */ int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats) { - SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats, - ff_formats_ref, ff_formats_unref, formats); + SET_COMMON_FORMATS(ctx, formats, + ff_formats_ref, ff_formats_unref); } -static int default_query_formats_common(AVFilterContext *ctx, - AVFilterChannelLayouts *(layouts)(void)) +int ff_default_query_formats(AVFilterContext *ctx) { int ret; - enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type : - ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type : + enum AVMediaType type = ctx->nb_inputs ? ctx->inputs [0]->type : + ctx->nb_outputs ? ctx->outputs[0]->type : AVMEDIA_TYPE_VIDEO; ret = ff_set_common_formats(ctx, ff_all_formats(type)); if (ret < 0) return ret; if (type == AVMEDIA_TYPE_AUDIO) { - ret = ff_set_common_channel_layouts(ctx, layouts()); + ret = ff_set_common_channel_layouts(ctx, ff_all_channel_counts()); if (ret < 0) return ret; ret = ff_set_common_samplerates(ctx, ff_all_samplerates()); @@ -626,16 +613,6 @@ static int default_query_formats_common(AVFilterContext *ctx, return 0; } -int ff_default_query_formats(AVFilterContext *ctx) -{ - return default_query_formats_common(ctx, ff_all_channel_counts); -} - -int ff_query_formats_all_layouts(AVFilterContext *ctx) -{ - return default_query_formats_common(ctx, ff_all_channel_layouts); -} - /* internal functions for parsing audio format arguments */ int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx) @@ -653,32 +630,6 @@ int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ct return 0; } -int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx) -{ - char *tail; - int sfmt = av_get_sample_fmt(arg); - if (sfmt == AV_SAMPLE_FMT_NONE) { - sfmt = strtol(arg, &tail, 0); - if (*tail || av_get_bytes_per_sample(sfmt)<=0) { - av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg); - return AVERROR(EINVAL); - } - } - *ret = sfmt; - return 0; -} - -int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx) -{ - AVRational r; - if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0 ||r.den<=0) { - av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg); - return AVERROR(EINVAL); - } - *ret = r; - return 0; -} - int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx) { char *tail; @@ -711,3 +662,73 @@ int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg, return 0; } + +static int check_list(void *log, const char *name, const AVFilterFormats *fmts) +{ + unsigned i, j; + + if (!fmts) + return 0; + if (!fmts->nb_formats) { + av_log(log, AV_LOG_ERROR, "Empty %s list\n", name); + return AVERROR(EINVAL); + } + for (i = 0; i < fmts->nb_formats; i++) { + for (j = i + 1; j < fmts->nb_formats; j++) { + if (fmts->formats[i] == fmts->formats[j]) { + av_log(log, AV_LOG_ERROR, "Duplicated %s\n", name); + return AVERROR(EINVAL); + } + } + } + return 0; +} + +int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts) +{ + return check_list(log, "pixel format", fmts); +} + +int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts) +{ + return check_list(log, "sample format", fmts); +} + +int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts) +{ + if (!fmts || !fmts->nb_formats) + return 0; + return check_list(log, "sample rate", fmts); +} + +static int layouts_compatible(uint64_t a, uint64_t b) +{ + return a == b || + (KNOWN(a) && !KNOWN(b) && av_get_channel_layout_nb_channels(a) == FF_LAYOUT2COUNT(b)) || + (KNOWN(b) && !KNOWN(a) && av_get_channel_layout_nb_channels(b) == FF_LAYOUT2COUNT(a)); +} + +int ff_formats_check_channel_layouts(void *log, const AVFilterChannelLayouts *fmts) +{ + unsigned i, j; + + if (!fmts) + return 0; + if (fmts->all_layouts < fmts->all_counts) { + av_log(log, AV_LOG_ERROR, "Inconsistent generic list\n"); + return AVERROR(EINVAL); + } + if (!fmts->all_layouts && !fmts->nb_channel_layouts) { + av_log(log, AV_LOG_ERROR, "Empty channel layout list\n"); + return AVERROR(EINVAL); + } + for (i = 0; i < fmts->nb_channel_layouts; i++) { + for (j = i + 1; j < fmts->nb_channel_layouts; j++) { + if (layouts_compatible(fmts->channel_layouts[i], fmts->channel_layouts[j])) { + av_log(log, AV_LOG_ERROR, "Duplicated or redundant channel layout\n"); + return AVERROR(EINVAL); + } + } + } + return 0; +} diff --git a/libavfilter/formats.h b/libavfilter/formats.h index cc588f30d..0520bf42a 100644 --- a/libavfilter/formats.h +++ b/libavfilter/formats.h @@ -20,6 +20,7 @@ #define AVFILTER_FORMATS_H #include "avfilter.h" +#include "version.h" /** * A list of supported formats for one end of a filter link. This is used @@ -82,7 +83,7 @@ struct AVFilterFormats { * channel count with unknown disposition with the same number of channels * (e.g. AV_CH_LAYOUT_STEREO and FF_COUNT2LAYOUT(2). */ -typedef struct AVFilterChannelLayouts { +struct AVFilterChannelLayouts { uint64_t *channel_layouts; ///< list of channel layouts int nb_channel_layouts; ///< number of channel layouts char all_layouts; ///< accept any known channel layout @@ -90,7 +91,7 @@ typedef struct AVFilterChannelLayouts { unsigned refcount; ///< number of references to this list struct AVFilterChannelLayouts ***refs; ///< references to this list -} AVFilterChannelLayouts; +}; /** * Encode a channel count as a channel layout. @@ -109,17 +110,32 @@ typedef struct AVFilterChannelLayouts { (int)((l) & 0x7FFFFFFF) : 0) /** - * Return a channel layouts/samplerates list which contains the intersection of - * the layouts/samplerates of a and b. Also, all the references of a, all the - * references of b, and a and b themselves will be deallocated. + * Check the formats/samplerates lists for compatibility for merging + * without actually merging. * - * If a and b do not share any common elements, neither is modified, and NULL - * is returned. + * @return 1 if they are compatible, 0 if not. */ -AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, - AVFilterChannelLayouts *b); -AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a, - AVFilterFormats *b); +int ff_can_merge_formats(const AVFilterFormats *a, const AVFilterFormats *b, + enum AVMediaType type); +int ff_can_merge_samplerates(const AVFilterFormats *a, const AVFilterFormats *b); + +/** + * Merge the formats/channel layouts/samplerates lists if they are compatible + * and update all the references of a and b to point to the combined list and + * free the old lists as needed. The combined list usually contains the + * intersection of the lists of a and b. + * + * Both a and b must have owners (i.e. refcount > 0) for these functions. + * + * @return 1 if merging succeeded, 0 if a and b are incompatible + * and negative AVERROR code on failure. + * a and b are unmodified if 0 is returned. + */ +int ff_merge_channel_layouts(AVFilterChannelLayouts *a, + AVFilterChannelLayouts *b); +int ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, + enum AVMediaType type); +int ff_merge_samplerates(AVFilterFormats *a, AVFilterFormats *b); /** * Construct an empty AVFilterChannelLayouts/AVFilterFormats struct -- @@ -139,11 +155,11 @@ av_warn_unused_result AVFilterChannelLayouts *ff_all_channel_counts(void); av_warn_unused_result +AVFilterChannelLayouts *ff_make_format64_list(const int64_t *fmts); + +#if LIBAVFILTER_VERSION_MAJOR < 8 AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts); - -av_warn_unused_result -AVFilterChannelLayouts *ff_make_formatu64_list(const uint64_t *fmts); - +#endif /** * A helper for query_formats() which sets all links to the same list of channel @@ -186,14 +202,6 @@ void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref, av_warn_unused_result int ff_default_query_formats(AVFilterContext *ctx); - /** - * Set the formats list to all known channel layouts. This function behaves - * like ff_default_query_formats(), except it only accepts known channel - * layouts. It should only be used with audio filters. - */ -av_warn_unused_result -int ff_query_formats_all_layouts(AVFilterContext *ctx); - /** * Create a list of supported formats. This is intended for use in * AVFilter->query_formats(). @@ -237,17 +245,6 @@ int ff_formats_pixdesc_filter(AVFilterFormats **rfmts, unsigned want, unsigned r av_warn_unused_result AVFilterFormats *ff_planar_sample_fmts(void); -/** - * Return a format list which contains the intersection of the formats of - * a and b. Also, all the references of a, all the references of b, and - * a and b themselves will be deallocated. - * - * If a and b do not share any common formats, neither is modified, and NULL - * is returned. - */ -AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, - enum AVMediaType type); - /** * Add *ref as a new reference to formats. * That is the pointers will point like in the ascii art below: @@ -294,4 +291,32 @@ void ff_formats_unref(AVFilterFormats **ref); */ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref); +/** + * Check that fmts is a valid pixel formats list. + * + * In particular, check for duplicates. + */ +int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts); + +/** + * Check that fmts is a valid sample formats list. + * + * In particular, check for duplicates. + */ +int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts); + +/** + * Check that fmts is a valid sample rates list. + * + * In particular, check for duplicates. + */ +int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts); + +/** + * Check that fmts is a valid channel layouts list. + * + * In particular, check for duplicates. + */ +int ff_formats_check_channel_layouts(void *log, const AVFilterChannelLayouts *fmts); + #endif /* AVFILTER_FORMATS_H */ diff --git a/libavfilter/framepool.c b/libavfilter/framepool.c index 3b178cebb..dab889152 100644 --- a/libavfilter/framepool.c +++ b/libavfilter/framepool.c @@ -48,7 +48,7 @@ struct FFFramePool { }; -FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size), +FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(buffer_size_t size), int width, int height, enum AVPixelFormat format, @@ -116,7 +116,7 @@ fail: return NULL; } -FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(int size), +FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(buffer_size_t size), int channels, int nb_samples, enum AVSampleFormat format, diff --git a/libavfilter/framepool.h b/libavfilter/framepool.h index e5560e4c6..28857a4a1 100644 --- a/libavfilter/framepool.h +++ b/libavfilter/framepool.h @@ -23,6 +23,7 @@ #include "libavutil/buffer.h" #include "libavutil/frame.h" +#include "libavutil/internal.h" /** * Frame pool. This structure is opaque and not meant to be accessed @@ -43,7 +44,7 @@ typedef struct FFFramePool FFFramePool; * @param align buffers alignement of each frame in this pool * @return newly created video frame pool on success, NULL on error. */ -FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size), +FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(buffer_size_t size), int width, int height, enum AVPixelFormat format, @@ -61,7 +62,7 @@ FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size), * @param align buffers alignement of each frame in this pool * @return newly created audio frame pool on success, NULL on error. */ -FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(int size), +FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(buffer_size_t size), int channels, int samples, enum AVSampleFormat format, diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c index b32a5cba6..bc6fce81f 100644 --- a/libavfilter/framesync.c +++ b/libavfilter/framesync.c @@ -53,6 +53,13 @@ static const AVClass framesync_class = { .parent_log_context_offset = OFFSET(parent), }; +const AVClass *ff_framesync_child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : &framesync_class; + *iter = (void *)(uintptr_t)c; + return c; +} + enum { STATE_BOF, STATE_RUN, diff --git a/libavfilter/framesync.h b/libavfilter/framesync.h index 37743cccb..51bab1628 100644 --- a/libavfilter/framesync.h +++ b/libavfilter/framesync.h @@ -297,6 +297,8 @@ int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); */ int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); +const AVClass *ff_framesync_child_class_iterate(void **iter); + #define FRAMESYNC_DEFINE_CLASS(name, context, field) \ static int name##_framesync_preinit(AVFilterContext *ctx) { \ context *s = ctx->priv; \ @@ -318,6 +320,7 @@ static const AVClass name##_class = { \ .version = LIBAVUTIL_VERSION_INT, \ .category = AV_CLASS_CATEGORY_FILTER, \ .child_class_next = name##_child_class_next, \ + .child_class_iterate = ff_framesync_child_class_iterate, \ .child_next = name##_child_next, \ } diff --git a/libavfilter/gblur.h b/libavfilter/gblur.h index 87129801d..dce50671f 100644 --- a/libavfilter/gblur.h +++ b/libavfilter/gblur.h @@ -37,6 +37,7 @@ typedef struct GBlurContext { int steps; int planes; + int flt; int depth; int planewidth[4]; int planeheight[4]; @@ -49,7 +50,9 @@ typedef struct GBlurContext { float nuV; int nb_planes; void (*horiz_slice)(float *buffer, int width, int height, int steps, float nu, float bscale); + void (*postscale_slice)(float *buffer, int length, float postscale, float min, float max); } GBlurContext; + void ff_gblur_init(GBlurContext *s); void ff_gblur_init_x86(GBlurContext *s); #endif diff --git a/libavfilter/glslang.cpp b/libavfilter/glslang.cpp index 497df6e24..986bddd78 100644 --- a/libavfilter/glslang.cpp +++ b/libavfilter/glslang.cpp @@ -24,7 +24,6 @@ extern "C" { } #include -#include #include #include @@ -236,8 +235,7 @@ int glslang_init(void) void glslang_uninit(void) { pthread_mutex_lock(&glslang_mutex); - av_assert0(glslang_refcount > 0); - if (--glslang_refcount == 0) + if (glslang_refcount && (--glslang_refcount == 0)) FinalizeProcess(); pthread_mutex_unlock(&glslang_mutex); } diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c index d92b5360a..1385c3ae7 100644 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@ -63,7 +63,7 @@ static char *parse_link_name(const char **buf, void *log_ctx) name = av_get_token(buf, "]"); if (!name) - goto fail; + return NULL; if (!name[0]) { av_log(log_ctx, AV_LOG_ERROR, @@ -71,12 +71,14 @@ static char *parse_link_name(const char **buf, void *log_ctx) goto fail; } - if (*(*buf)++ != ']') { + if (**buf != ']') { av_log(log_ctx, AV_LOG_ERROR, "Mismatched '[' found in the following: \"%s\".\n", start); fail: av_freep(&name); + return NULL; } + (*buf)++; return name; } @@ -184,9 +186,16 @@ static int parse_filter(AVFilterContext **filt_ctx, const char **buf, AVFilterGr char *name = av_get_token(buf, "=,;["); int ret; + if (!name) + return AVERROR(ENOMEM); + if (**buf == '=') { (*buf)++; opts = av_get_token(buf, "[],;"); + if (!opts) { + av_free(name); + return AVERROR(ENOMEM); + } } ret = create_filter(filt_ctx, graph, index, name, opts, log_ctx); @@ -303,8 +312,10 @@ static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs, char *name = parse_link_name(buf, log_ctx); AVFilterInOut *match; - if (!name) + if (!name) { + avfilter_inout_free(&parsed_inputs); return AVERROR(EINVAL); + } /* First check if the label is not in the open_outputs list */ match = extract_inout(name, open_outputs); @@ -314,6 +325,7 @@ static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs, } else { /* Not in the list, so add it as an input */ if (!(match = av_mallocz(sizeof(AVFilterInOut)))) { + avfilter_inout_free(&parsed_inputs); av_free(name); return AVERROR(ENOMEM); } @@ -360,15 +372,14 @@ static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, match = extract_inout(name, open_inputs); if (match) { - if ((ret = link_filter(input->filter_ctx, input->pad_idx, - match->filter_ctx, match->pad_idx, log_ctx)) < 0) { - av_free(name); - return ret; - } + ret = link_filter(input->filter_ctx, input->pad_idx, + match->filter_ctx, match->pad_idx, log_ctx); av_freep(&match->name); av_freep(&name); av_freep(&match); av_freep(&input); + if (ret < 0) + return ret; } else { /* Not in the list, so add the first input as an open_output */ input->name = name; diff --git a/libavfilter/hflip.h b/libavfilter/hflip.h index 204090dbb..a40b98470 100644 --- a/libavfilter/hflip.h +++ b/libavfilter/hflip.h @@ -27,6 +27,7 @@ typedef struct FlipContext { const AVClass *class; int max_step[4]; ///< max pixel step for each plane, expressed as a number of bytes + int bayer_plus1; ///< 1 .. not a Bayer input format, 2 .. Bayer input format int planewidth[4]; ///< width of each plane int planeheight[4]; ///< height of each plane diff --git a/libavfilter/internal.h b/libavfilter/internal.h index abe7537b5..f3b434dbe 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -117,14 +117,6 @@ struct AVFilterPad { */ int (*config_props)(AVFilterLink *link); - /** - * The filter expects a fifo to be inserted on its input link, - * typically because it has a delay. - * - * input pads only. - */ - int needs_fifo; - /** * The filter expects writable frames from its input link, * duplicating data buffers if needed. @@ -179,28 +171,6 @@ int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ct av_warn_unused_result int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx); -/** - * Parse a time base. - * - * @param ret unsigned AVRational pointer to where the value should be written - * @param arg string to parse - * @param log_ctx log context - * @return >= 0 in case of success, a negative AVERROR code on error - */ -av_warn_unused_result -int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx); - -/** - * Parse a sample format name or a corresponding integer representation. - * - * @param ret integer pointer to where the value should be written - * @param arg string to parse - * @param log_ctx log context - * @return >= 0 in case of success, a negative AVERROR code on error - */ -av_warn_unused_result -int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx); - /** * Parse a channel layout or a corresponding integer representation. * @@ -234,6 +204,10 @@ void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts void ff_command_queue_pop(AVFilterContext *filter); +#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) +#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) +#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) + /* misc trace functions */ #define FF_TPRINTF_START(ctx, func) ff_tlog(NULL, "%-16s: ", #func) @@ -394,6 +368,8 @@ int ff_filter_get_nb_threads(AVFilterContext *ctx); /** * Generic processing of user supplied commands that are set * in the same way as the filter options. + * NOTE: 'enable' option is handled separately, and not by + * this function. */ int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags); diff --git a/libavfilter/lavfutils.c b/libavfilter/lavfutils.c index db4b69b9f..34051ee61 100644 --- a/libavfilter/lavfutils.c +++ b/libavfilter/lavfutils.c @@ -19,6 +19,7 @@ */ #include "libavutil/imgutils.h" +#include "libavformat/avformat.h" #include "lavfutils.h" int ff_load_image(uint8_t *data[4], int linesize[4], @@ -27,16 +28,14 @@ int ff_load_image(uint8_t *data[4], int linesize[4], { AVInputFormat *iformat = NULL; AVFormatContext *format_ctx = NULL; - AVCodec *codec; - AVCodecContext *codec_ctx; + const AVCodec *codec; + AVCodecContext *codec_ctx = NULL; AVCodecParameters *par; - AVFrame *frame; - int frame_decoded, ret = 0; + AVFrame *frame = NULL; + int ret = 0; AVPacket pkt; AVDictionary *opt=NULL; - av_init_packet(&pkt); - iformat = av_find_input_format("image2pipe"); if ((ret = avformat_open_input(&format_ctx, filename, iformat, NULL)) < 0) { av_log(log_ctx, AV_LOG_ERROR, @@ -46,7 +45,7 @@ int ff_load_image(uint8_t *data[4], int linesize[4], if ((ret = avformat_find_stream_info(format_ctx, NULL)) < 0) { av_log(log_ctx, AV_LOG_ERROR, "Find stream info failed\n"); - return ret; + goto end; } par = format_ctx->streams[0]->codecpar; @@ -88,11 +87,16 @@ int ff_load_image(uint8_t *data[4], int linesize[4], goto end; } - ret = avcodec_decode_video2(codec_ctx, frame, &frame_decoded, &pkt); - if (ret < 0 || !frame_decoded) { + ret = avcodec_send_packet(codec_ctx, &pkt); + av_packet_unref(&pkt); + if (ret < 0) { + av_log(log_ctx, AV_LOG_ERROR, "Error submitting a packet to decoder\n"); + goto end; + } + + ret = avcodec_receive_frame(codec_ctx, frame); + if (ret < 0) { av_log(log_ctx, AV_LOG_ERROR, "Failed to decode image from file\n"); - if (ret >= 0) - ret = -1; goto end; } @@ -107,7 +111,6 @@ int ff_load_image(uint8_t *data[4], int linesize[4], av_image_copy(data, linesize, (const uint8_t **)frame->data, frame->linesize, *pix_fmt, *w, *h); end: - av_packet_unref(&pkt); avcodec_free_context(&codec_ctx); avformat_close_input(&format_ctx); av_frame_free(&frame); diff --git a/libavfilter/lavfutils.h b/libavfilter/lavfutils.h index 2d5308f79..96738cead 100644 --- a/libavfilter/lavfutils.h +++ b/libavfilter/lavfutils.h @@ -24,7 +24,8 @@ #ifndef AVFILTER_LAVFUTILS_H #define AVFILTER_LAVFUTILS_H -#include "libavformat/avformat.h" +#include +#include "libavutil/pixfmt.h" /** * Load image from filename and put the resulting image in data. diff --git a/libavfilter/qp_table.c b/libavfilter/qp_table.c new file mode 100644 index 000000000..33812b708 --- /dev/null +++ b/libavfilter/qp_table.c @@ -0,0 +1,72 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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 + +// for FF_QSCALE_TYPE_* +#include "libavcodec/internal.h" + +#include "libavutil/frame.h" +#include "libavutil/mem.h" +#include "libavutil/video_enc_params.h" + +#include "qp_table.h" + +int ff_qp_table_extract(AVFrame *frame, int8_t **table, int *table_w, int *table_h, + int *qscale_type) +{ + AVFrameSideData *sd; + AVVideoEncParams *par; + unsigned int mb_h = (frame->height + 15) / 16; + unsigned int mb_w = (frame->width + 15) / 16; + unsigned int nb_mb = mb_h * mb_w; + unsigned int block_idx; + + *table = NULL; + + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_VIDEO_ENC_PARAMS); + if (!sd) + return 0; + par = (AVVideoEncParams*)sd->data; + if (par->type != AV_VIDEO_ENC_PARAMS_MPEG2 || + (par->nb_blocks != 0 && par->nb_blocks != nb_mb)) + return AVERROR(ENOSYS); + + *table = av_malloc(nb_mb); + if (!*table) + return AVERROR(ENOMEM); + if (table_w) + *table_w = mb_w; + if (table_h) + *table_h = mb_h; + if (qscale_type) + *qscale_type = FF_QSCALE_TYPE_MPEG2; + + if (par->nb_blocks == 0) { + memset(*table, par->qp, nb_mb); + return 0; + } + + for (block_idx = 0; block_idx < nb_mb; block_idx++) { + AVVideoBlockParams *b = av_video_enc_params_block(par, block_idx); + (*table)[block_idx] = par->qp + b->delta_qp; + } + + return 0; +} + diff --git a/libavfilter/qp_table.h b/libavfilter/qp_table.h new file mode 100644 index 000000000..a552fe2e6 --- /dev/null +++ b/libavfilter/qp_table.h @@ -0,0 +1,33 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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 AVFILTER_QP_TABLE_H +#define AVFILTER_QP_TABLE_H + +#include + +#include "libavutil/frame.h" + +/** + * Extract a libpostproc-compatible QP table - an 8-bit QP value per 16x16 + * macroblock, stored in raster order - from AVVideoEncParams side data. + */ +int ff_qp_table_extract(AVFrame *frame, int8_t **table, int *table_w, int *table_h, + int *qscale_type); + +#endif // AVFILTER_QP_TABLE_H diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 8d5ff2eb6..f216b3f24 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -76,6 +76,110 @@ static const mfxHandleType handle_types[] = { static const AVRational default_tb = { 1, 90000 }; +static const struct { + int mfx_iopattern; + const char *desc; +} qsv_iopatterns[] = { + {MFX_IOPATTERN_IN_VIDEO_MEMORY, "input is video memory surface" }, + {MFX_IOPATTERN_IN_SYSTEM_MEMORY, "input is system memory surface" }, + {MFX_IOPATTERN_IN_OPAQUE_MEMORY, "input is opaque memory surface" }, + {MFX_IOPATTERN_OUT_VIDEO_MEMORY, "output is video memory surface" }, + {MFX_IOPATTERN_OUT_SYSTEM_MEMORY, "output is system memory surface" }, + {MFX_IOPATTERN_OUT_OPAQUE_MEMORY, "output is opaque memory surface" }, +}; + +int ff_qsvvpp_print_iopattern(void *log_ctx, int mfx_iopattern, + const char *extra_string) +{ + const char *desc = NULL; + + for (int i = 0; i < FF_ARRAY_ELEMS(qsv_iopatterns); i++) { + if (qsv_iopatterns[i].mfx_iopattern == mfx_iopattern) { + desc = qsv_iopatterns[i].desc; + } + } + if (!desc) + desc = "unknown iopattern"; + + av_log(log_ctx, AV_LOG_VERBOSE, "%s: %s\n", extra_string, desc); + return 0; +} + +static const struct { + mfxStatus mfxerr; + int averr; + const char *desc; +} qsv_errors[] = { + { MFX_ERR_NONE, 0, "success" }, + { MFX_ERR_UNKNOWN, AVERROR_UNKNOWN, "unknown error" }, + { MFX_ERR_NULL_PTR, AVERROR(EINVAL), "NULL pointer" }, + { MFX_ERR_UNSUPPORTED, AVERROR(ENOSYS), "unsupported" }, + { MFX_ERR_MEMORY_ALLOC, AVERROR(ENOMEM), "failed to allocate memory" }, + { MFX_ERR_NOT_ENOUGH_BUFFER, AVERROR(ENOMEM), "insufficient input/output buffer" }, + { MFX_ERR_INVALID_HANDLE, AVERROR(EINVAL), "invalid handle" }, + { MFX_ERR_LOCK_MEMORY, AVERROR(EIO), "failed to lock the memory block" }, + { MFX_ERR_NOT_INITIALIZED, AVERROR_BUG, "not initialized" }, + { MFX_ERR_NOT_FOUND, AVERROR(ENOSYS), "specified object was not found" }, + /* the following 3 errors should always be handled explicitly, so those "mappings" + * are for completeness only */ + { MFX_ERR_MORE_DATA, AVERROR_UNKNOWN, "expect more data at input" }, + { MFX_ERR_MORE_SURFACE, AVERROR_UNKNOWN, "expect more surface at output" }, + { MFX_ERR_MORE_BITSTREAM, AVERROR_UNKNOWN, "expect more bitstream at output" }, + { MFX_ERR_ABORTED, AVERROR_UNKNOWN, "operation aborted" }, + { MFX_ERR_DEVICE_LOST, AVERROR(EIO), "device lost" }, + { MFX_ERR_INCOMPATIBLE_VIDEO_PARAM, AVERROR(EINVAL), "incompatible video parameters" }, + { MFX_ERR_INVALID_VIDEO_PARAM, AVERROR(EINVAL), "invalid video parameters" }, + { MFX_ERR_UNDEFINED_BEHAVIOR, AVERROR_BUG, "undefined behavior" }, + { MFX_ERR_DEVICE_FAILED, AVERROR(EIO), "device failed" }, + { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM, AVERROR(EINVAL), "incompatible audio parameters" }, + { MFX_ERR_INVALID_AUDIO_PARAM, AVERROR(EINVAL), "invalid audio parameters" }, + + { MFX_WRN_IN_EXECUTION, 0, "operation in execution" }, + { MFX_WRN_DEVICE_BUSY, 0, "device busy" }, + { MFX_WRN_VIDEO_PARAM_CHANGED, 0, "video parameters changed" }, + { MFX_WRN_PARTIAL_ACCELERATION, 0, "partial acceleration" }, + { MFX_WRN_INCOMPATIBLE_VIDEO_PARAM, 0, "incompatible video parameters" }, + { MFX_WRN_VALUE_NOT_CHANGED, 0, "value is saturated" }, + { MFX_WRN_OUT_OF_RANGE, 0, "value out of range" }, + { MFX_WRN_FILTER_SKIPPED, 0, "filter skipped" }, + { MFX_WRN_INCOMPATIBLE_AUDIO_PARAM, 0, "incompatible audio parameters" }, +}; + +static int qsv_map_error(mfxStatus mfx_err, const char **desc) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(qsv_errors); i++) { + if (qsv_errors[i].mfxerr == mfx_err) { + if (desc) + *desc = qsv_errors[i].desc; + return qsv_errors[i].averr; + } + } + if (desc) + *desc = "unknown error"; + return AVERROR_UNKNOWN; +} + +int ff_qsvvpp_print_error(void *log_ctx, mfxStatus err, + const char *error_string) +{ + const char *desc; + int ret; + ret = qsv_map_error(err, &desc); + av_log(log_ctx, AV_LOG_ERROR, "%s: %s (%d)\n", error_string, desc, err); + return ret; +} + +int ff_qsvvpp_print_warning(void *log_ctx, mfxStatus err, + const char *warning_string) +{ + const char *desc; + int ret; + ret = qsv_map_error(err, &desc); + av_log(log_ctx, AV_LOG_WARNING, "%s: %s (%d)\n", warning_string, desc, err); + return ret; +} + /* functions for frameAlloc */ static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, mfxFrameAllocResponse *resp) @@ -505,15 +609,19 @@ static int init_vpp_session(AVFilterContext *avctx, QSVVPPContext *s) } } - if (ret != MFX_ERR_NONE) { - av_log(avctx, AV_LOG_ERROR, "Error getting the session handle\n"); + if (ret < 0) + return ff_qsvvpp_print_error(avctx, ret, "Error getting the session handle"); + else if (ret > 0) { + ff_qsvvpp_print_warning(avctx, ret, "Warning in getting the session handle"); return AVERROR_UNKNOWN; } /* create a "slave" session with those same properties, to be used for vpp */ ret = MFXInit(impl, &ver, &s->session); - if (ret != MFX_ERR_NONE) { - av_log(avctx, AV_LOG_ERROR, "Error initializing a session for scaling\n"); + if (ret < 0) + return ff_qsvvpp_print_error(avctx, ret, "Error initializing a session"); + else if (ret > 0) { + ff_qsvvpp_print_warning(avctx, ret, "Warning in session initialization"); return AVERROR_UNKNOWN; } @@ -646,11 +754,16 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p else if (IS_OPAQUE_MEMORY(s->out_mem_mode)) s->vpp_param.IOPattern |= MFX_IOPATTERN_OUT_OPAQUE_MEMORY; + /* Print input memory mode */ + ff_qsvvpp_print_iopattern(avctx, s->vpp_param.IOPattern & 0x0F, "VPP"); + /* Print output memory mode */ + ff_qsvvpp_print_iopattern(avctx, s->vpp_param.IOPattern & 0xF0, "VPP"); ret = MFXVideoVPP_Init(s->session, &s->vpp_param); if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Failed to create a qsvvpp, ret = %d.\n", ret); + ret = ff_qsvvpp_print_error(avctx, ret, "Failed to create a qsvvpp"); goto failed; - } + } else if (ret > 0) + ff_qsvvpp_print_warning(avctx, ret, "Warning When creating qsvvpp"); *vpp = s; return 0; diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index c2bcce754..b4baeedf9 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -71,4 +71,13 @@ int ff_qsvvpp_free(QSVVPPContext **vpp); /* vpp filter frame and call the cb if needed */ int ff_qsvvpp_filter_frame(QSVVPPContext *vpp, AVFilterLink *inlink, AVFrame *frame); +int ff_qsvvpp_print_iopattern(void *log_ctx, int mfx_iopattern, + const char *extra_string); + +int ff_qsvvpp_print_error(void *log_ctx, mfxStatus err, + const char *error_string); + +int ff_qsvvpp_print_warning(void *log_ctx, mfxStatus err, + const char *warning_string); + #endif /* AVFILTER_QSVVPP_H */ diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c index c7c383627..440a21892 100644 --- a/libavfilter/setpts.c +++ b/libavfilter/setpts.c @@ -142,10 +142,6 @@ static int config_input(AVFilterLink *inlink) return 0; } -#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - #define BUF_SIZE 64 static inline char *double2int64str(char *buf, double v) @@ -266,14 +262,15 @@ static av_cold void uninit(AVFilterContext *ctx) } #define OFFSET(x) offsetof(SetPTSContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM -static const AVOption options[] = { - { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = FLAGS }, - { NULL } -}; +#define V AV_OPT_FLAG_VIDEO_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM +#define F AV_OPT_FLAG_FILTERING_PARAM #if CONFIG_SETPTS_FILTER -#define setpts_options options +static const AVOption setpts_options[] = { + { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = V|F }, + { NULL } +}; AVFILTER_DEFINE_CLASS(setpts); static const AVFilterPad avfilter_vf_setpts_inputs[] = { @@ -310,7 +307,10 @@ AVFilter ff_vf_setpts = { #if CONFIG_ASETPTS_FILTER -#define asetpts_options options +static const AVOption asetpts_options[] = { + { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = A|F }, + { NULL } +}; AVFILTER_DEFINE_CLASS(asetpts); static const AVFilterPad asetpts_inputs[] = { diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c index 476b8d3d9..589250041 100644 --- a/libavfilter/src_movie.c +++ b/libavfilter/src_movie.c @@ -51,7 +51,6 @@ typedef struct MovieStream { AVStream *st; AVCodecContext *codec_ctx; - int done; int64_t discontinuity_threshold; int64_t last_pts; } MovieStream; @@ -70,8 +69,6 @@ typedef struct MovieContext { int64_t ts_offset; AVFormatContext *format_ctx; - int eof; - AVPacket pkt, pkt0; int max_stream_index; /**< max stream # actually used for output */ MovieStream *st; /**< array of all streams, one per output */ @@ -155,7 +152,7 @@ static AVStream *find_stream(void *log, AVFormatContext *avf, const char *spec) static int open_stream(AVFilterContext *ctx, MovieStream *st) { - AVCodec *codec; + const AVCodec *codec; int ret; codec = avcodec_find_decoder(st->st->codecpar->codec_id); @@ -172,7 +169,6 @@ static int open_stream(AVFilterContext *ctx, MovieStream *st) if (ret < 0) return ret; - st->codec_ctx->refcounted_frames = 1; st->codec_ctx->thread_count = ff_filter_get_nb_threads(ctx); if ((ret = avcodec_open2(st->codec_ctx, codec, NULL)) < 0) { @@ -213,7 +209,6 @@ static av_cold int movie_common_init(AVFilterContext *ctx) int64_t timestamp; int nb_streams = 1, ret, i; char default_streams[16], *stream_specs, *spec, *cursor; - char name[16]; AVStream *st; if (!movie->file_name) { @@ -305,9 +300,8 @@ static av_cold int movie_common_init(AVFilterContext *ctx) for (i = 0; i < nb_streams; i++) { AVFilterPad pad = { 0 }; movie->out_index[movie->st[i].st->index] = i; - snprintf(name, sizeof(name), "out%d", i); pad.type = movie->st[i].st->codecpar->codec_type; - pad.name = av_strdup(name); + pad.name = av_asprintf("out%d", i); if (!pad.name) return AVERROR(ENOMEM); pad.config_props = movie_config_output_props; @@ -365,19 +359,19 @@ static int movie_query_formats(AVFilterContext *ctx) switch (c->codec_type) { case AVMEDIA_TYPE_VIDEO: list[0] = c->format; - if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->incfg.formats)) < 0) return ret; break; case AVMEDIA_TYPE_AUDIO: list[0] = c->format; - if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->incfg.formats)) < 0) return ret; list[0] = c->sample_rate; - if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->in_samplerates)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->incfg.samplerates)) < 0) return ret; list64[0] = c->channel_layout; - if ((ret = ff_channel_layouts_ref(avfilter_make_format64_list(list64), - &outlink->in_channel_layouts)) < 0) + if ((ret = ff_channel_layouts_ref(ff_make_format64_list(list64), + &outlink->incfg.channel_layouts)) < 0) return ret; break; } @@ -452,113 +446,69 @@ static int rewind_file(AVFilterContext *ctx) for (i = 0; i < ctx->nb_outputs; i++) { avcodec_flush_buffers(movie->st[i].codec_ctx); - movie->st[i].done = 0; } - movie->eof = 0; return 0; } +static int movie_decode_packet(AVFilterContext *ctx) +{ + MovieContext *movie = ctx->priv; + AVPacket pkt = { 0 }; + int pkt_out_id, ret; + + /* read a new packet from input stream */ + ret = av_read_frame(movie->format_ctx, &pkt); + if (ret == AVERROR_EOF) { + /* EOF -> set all decoders for flushing */ + for (int i = 0; i < ctx->nb_outputs; i++) { + ret = avcodec_send_packet(movie->st[i].codec_ctx, NULL); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + return 0; + } else if (ret < 0) + return ret; + + /* send the packet to its decoder, if any */ + pkt_out_id = pkt.stream_index > movie->max_stream_index ? -1 : + movie->out_index[pkt.stream_index]; + if (pkt_out_id >= 0) + ret = avcodec_send_packet(movie->st[pkt_out_id].codec_ctx, &pkt); + av_packet_unref(&pkt); + + return ret; +} + /** * Try to push a frame to the requested output. * * @param ctx filter context * @param out_id number of output where a frame is wanted; - * if the frame is read from file, used to set the return value; - * if the codec is being flushed, flush the corresponding stream - * @return 1 if a frame was pushed on the requested output, - * 0 if another attempt is possible, - * <0 AVERROR code + * @return 0 if a frame was pushed on the requested output, + * AVERROR(EAGAIN) if the decoder requires more input + * AVERROR(EOF) if the decoder has been completely flushed + * <0 AVERROR code */ static int movie_push_frame(AVFilterContext *ctx, unsigned out_id) { - MovieContext *movie = ctx->priv; - AVPacket *pkt = &movie->pkt; - enum AVMediaType frame_type; - MovieStream *st; - int ret, got_frame = 0, pkt_out_id; - AVFilterLink *outlink; + MovieContext *movie = ctx->priv; + MovieStream *st = &movie->st[out_id]; + AVFilterLink *outlink = ctx->outputs[out_id]; AVFrame *frame; - - if (!pkt->size) { - if (movie->eof) { - if (movie->st[out_id].done) { - if (movie->loop_count != 1) { - ret = rewind_file(ctx); - if (ret < 0) - return ret; - movie->loop_count -= movie->loop_count > 1; - av_log(ctx, AV_LOG_VERBOSE, "Stream finished, looping.\n"); - return 0; /* retry */ - } - return AVERROR_EOF; - } - pkt->stream_index = movie->st[out_id].st->index; - /* packet is already ready for flushing */ - } else { - ret = av_read_frame(movie->format_ctx, &movie->pkt0); - if (ret < 0) { - av_init_packet(&movie->pkt0); /* ready for flushing */ - *pkt = movie->pkt0; - if (ret == AVERROR_EOF) { - movie->eof = 1; - return 0; /* start flushing */ - } - return ret; - } - *pkt = movie->pkt0; - } - } - - pkt_out_id = pkt->stream_index > movie->max_stream_index ? -1 : - movie->out_index[pkt->stream_index]; - if (pkt_out_id < 0) { - av_packet_unref(&movie->pkt0); - pkt->size = 0; /* ready for next run */ - pkt->data = NULL; - return 0; - } - st = &movie->st[pkt_out_id]; - outlink = ctx->outputs[pkt_out_id]; + int ret; frame = av_frame_alloc(); if (!frame) return AVERROR(ENOMEM); - frame_type = st->st->codecpar->codec_type; - switch (frame_type) { - case AVMEDIA_TYPE_VIDEO: - ret = avcodec_decode_video2(st->codec_ctx, frame, &got_frame, pkt); - break; - case AVMEDIA_TYPE_AUDIO: - ret = avcodec_decode_audio4(st->codec_ctx, frame, &got_frame, pkt); - break; - default: - ret = AVERROR(ENOSYS); - break; - } + ret = avcodec_receive_frame(st->codec_ctx, frame); if (ret < 0) { - av_log(ctx, AV_LOG_WARNING, "Decode error: %s\n", av_err2str(ret)); - av_frame_free(&frame); - av_packet_unref(&movie->pkt0); - movie->pkt.size = 0; - movie->pkt.data = NULL; - return 0; - } - if (!ret || st->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) - ret = pkt->size; + if (ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) + av_log(ctx, AV_LOG_WARNING, "Decode error: %s\n", av_err2str(ret)); - pkt->data += ret; - pkt->size -= ret; - if (pkt->size <= 0) { - av_packet_unref(&movie->pkt0); - pkt->size = 0; /* ready for next run */ - pkt->data = NULL; - } - if (!got_frame) { - if (!ret) - st->done = 1; av_frame_free(&frame); - return 0; + return ret; } frame->pts = frame->best_effort_timestamp; @@ -569,7 +519,7 @@ static int movie_push_frame(AVFilterContext *ctx, unsigned out_id) if (st->last_pts != AV_NOPTS_VALUE) { int64_t diff = frame->pts - st->last_pts; if (diff < 0 || diff > st->discontinuity_threshold) { - av_log(ctx, AV_LOG_VERBOSE, "Discontinuity in stream:%d diff:%"PRId64"\n", pkt_out_id, diff); + av_log(ctx, AV_LOG_VERBOSE, "Discontinuity in stream:%d diff:%"PRId64"\n", out_id, diff); movie->ts_offset += av_rescale_q_rnd(-diff, outlink->time_base, AV_TIME_BASE_Q, AV_ROUND_UP); frame->pts -= diff; } @@ -578,7 +528,8 @@ static int movie_push_frame(AVFilterContext *ctx, unsigned out_id) st->last_pts = frame->pts; } ff_dlog(ctx, "movie_push_frame(): file:'%s' %s\n", movie->file_name, - describe_frame_to_str((char[1024]){0}, 1024, frame, frame_type, outlink)); + describe_frame_to_str((char[1024]){0}, 1024, frame, + st->st->codecpar->codec_type, outlink)); if (st->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (frame->format != outlink->format) { @@ -594,19 +545,49 @@ static int movie_push_frame(AVFilterContext *ctx, unsigned out_id) if (ret < 0) return ret; - return pkt_out_id == out_id; + return 0; } static int movie_request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; + MovieContext *movie = ctx->priv; unsigned out_id = FF_OUTLINK_IDX(outlink); - int ret; while (1) { - ret = movie_push_frame(ctx, out_id); - if (ret) - return FFMIN(ret, 0); + int got_eagain = 0, got_eof = 0; + int ret = 0; + + /* check all decoders for available output */ + for (int i = 0; i < ctx->nb_outputs; i++) { + ret = movie_push_frame(ctx, i); + if (ret == AVERROR(EAGAIN)) + got_eagain++; + else if (ret == AVERROR_EOF) + got_eof++; + else if (ret < 0) + return ret; + else if (i == out_id) + return 0; + } + + if (got_eagain) { + /* all decoders require more input -> read a new packet */ + ret = movie_decode_packet(ctx); + if (ret < 0) + return ret; + } else if (got_eof) { + /* all decoders flushed */ + if (movie->loop_count != 1) { + ret = rewind_file(ctx); + if (ret < 0) + return ret; + movie->loop_count -= movie->loop_count > 1; + av_log(ctx, AV_LOG_VERBOSE, "Stream finished, looping.\n"); + continue; + } + return AVERROR_EOF; + } } } @@ -630,7 +611,6 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar for (i = 0; i < ctx->nb_outputs; i++) { avcodec_flush_buffers(movie->st[i].codec_ctx); - movie->st[i].done = 0; } return ret; } else if (!strcmp(cmd, "get_duration")) { diff --git a/libavfilter/tests/filtfmts.c b/libavfilter/tests/filtfmts.c index 317df86c5..356f46733 100644 --- a/libavfilter/tests/filtfmts.c +++ b/libavfilter/tests/filtfmts.c @@ -40,7 +40,7 @@ static void print_formats(AVFilterContext *filter_ctx) for (i = 0; i < filter_ctx->nb_##inout##puts; i++) { \ if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_VIDEO) { \ AVFilterFormats *fmts = \ - filter_ctx->inout##puts[i]->outin##_formats; \ + filter_ctx->inout##puts[i]->outin##cfg.formats; \ for (j = 0; j < fmts->nb_formats; j++) \ if(av_get_pix_fmt_name(fmts->formats[j])) \ printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ @@ -50,13 +50,13 @@ static void print_formats(AVFilterContext *filter_ctx) AVFilterFormats *fmts; \ AVFilterChannelLayouts *layouts; \ \ - fmts = filter_ctx->inout##puts[i]->outin##_formats; \ + fmts = filter_ctx->inout##puts[i]->outin##cfg.formats; \ for (j = 0; j < fmts->nb_formats; j++) \ printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ i, avfilter_pad_get_name(filter_ctx->inout##put_pads, i), \ av_get_sample_fmt_name(fmts->formats[j])); \ \ - layouts = filter_ctx->inout##puts[i]->outin##_channel_layouts; \ + layouts = filter_ctx->inout##puts[i]->outin##cfg.channel_layouts; \ for (j = 0; j < layouts->nb_channel_layouts; j++) { \ char buf[256]; \ av_get_channel_layout_string(buf, sizeof(buf), -1, \ diff --git a/libavfilter/tinterlace.h b/libavfilter/tinterlace.h index 020887ff3..4059ebf81 100644 --- a/libavfilter/tinterlace.h +++ b/libavfilter/tinterlace.h @@ -67,7 +67,6 @@ typedef struct TInterlaceContext { AVRational preout_time_base; int flags; ///< flags affecting interlacing algorithm int lowpass; ///< legacy interlace filter lowpass mode - int frame; ///< number of the output frame int vsub; ///< chroma vertical subsampling AVFrame *cur; AVFrame *next; diff --git a/libavfilter/unsharp.h b/libavfilter/unsharp.h index a60b30f31..253e32dd1 100644 --- a/libavfilter/unsharp.h +++ b/libavfilter/unsharp.h @@ -48,9 +48,12 @@ typedef struct UnsharpContext { UnsharpFilterParam luma; ///< luma parameters (width, height, amount) UnsharpFilterParam chroma; ///< chroma parameters (width, height, amount) int hsub, vsub; + int bitdepth; + int bps; int nb_threads; int opencl; int (* apply_unsharp)(AVFilterContext *ctx, AVFrame *in, AVFrame *out); + int (* unsharp_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); } UnsharpContext; #endif /* AVFILTER_UNSHARP_H */ diff --git a/libavfilter/v360.h b/libavfilter/v360.h index e9a47593c..87770664a 100644 --- a/libavfilter/v360.h +++ b/libavfilter/v360.h @@ -51,6 +51,9 @@ enum Projections { BARREL_SPLIT, TSPYRAMID, HEQUIRECTANGULAR, + EQUISOLID, + ORTHOGRAPHIC, + OCTAHEDRON, NB_PROJECTIONS, }; @@ -62,6 +65,7 @@ enum InterpMethod { LANCZOS, SPLINE16, GAUSSIAN, + MITCHELL, NB_INTERP_METHODS, }; @@ -106,6 +110,12 @@ typedef struct XYRemap { float ker[4][4]; } XYRemap; +typedef struct SliceXYRemap { + int16_t *u[2], *v[2]; + int16_t *ker[2]; + uint8_t *mask; +} SliceXYRemap; + typedef struct V360Context { const AVClass *class; int in, out; @@ -140,9 +150,8 @@ typedef struct V360Context { float flat_range[2]; float iflat_range[2]; - float rot_mat[3][3]; + float rot_quaternion[2][4]; - float input_mirror_modifier[2]; float output_mirror_modifier[3]; int in_width, in_height; @@ -161,10 +170,9 @@ typedef struct V360Context { int elements; int mask_size; int max_value; + int nb_threads; - int16_t *u[2], *v[2]; - int16_t *ker[2]; - uint8_t *mask; + SliceXYRemap *slice_remap; unsigned map[4]; int (*in_transform)(const struct V360Context *s, diff --git a/libavfilter/vaapi_vpp.c b/libavfilter/vaapi_vpp.c index b5b245c8a..1610df4c8 100644 --- a/libavfilter/vaapi_vpp.c +++ b/libavfilter/vaapi_vpp.c @@ -32,10 +32,10 @@ int ff_vaapi_vpp_query_formats(AVFilterContext *avctx) int err; if ((err = ff_formats_ref(ff_make_format_list(pix_fmts), - &avctx->inputs[0]->out_formats)) < 0) + &avctx->inputs[0]->outcfg.formats)) < 0) return err; if ((err = ff_formats_ref(ff_make_format_list(pix_fmts), - &avctx->outputs[0]->in_formats)) < 0) + &avctx->outputs[0]->incfg.formats)) < 0) return err; return 0; diff --git a/libavfilter/vaf_spectrumsynth.c b/libavfilter/vaf_spectrumsynth.c index fed2cbba0..7347f8435 100644 --- a/libavfilter/vaf_spectrumsynth.c +++ b/libavfilter/vaf_spectrumsynth.c @@ -34,6 +34,7 @@ #include "formats.h" #include "audio.h" #include "video.h" +#include "filters.h" #include "internal.h" #include "window_func.h" @@ -114,28 +115,28 @@ static int query_formats(AVFilterContext *ctx) int ret, sample_rates[] = { 48000, -1 }; formats = ff_make_format_list(sample_fmts); - if ((ret = ff_formats_ref (formats, &outlink->in_formats )) < 0 || + if ((ret = ff_formats_ref (formats, &outlink->incfg.formats )) < 0 || (ret = ff_add_channel_layout (&layout, FF_COUNT2LAYOUT(s->channels))) < 0 || - (ret = ff_channel_layouts_ref (layout , &outlink->in_channel_layouts)) < 0) + (ret = ff_channel_layouts_ref (layout , &outlink->incfg.channel_layouts)) < 0) return ret; sample_rates[0] = s->sample_rate; formats = ff_make_format_list(sample_rates); if (!formats) return AVERROR(ENOMEM); - if ((ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0) + if ((ret = ff_formats_ref(formats, &outlink->incfg.samplerates)) < 0) return ret; formats = ff_make_format_list(pix_fmts); if (!formats) return AVERROR(ENOMEM); - if ((ret = ff_formats_ref(formats, &magnitude->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &magnitude->outcfg.formats)) < 0) return ret; formats = ff_make_format_list(pix_fmts); if (!formats) return AVERROR(ENOMEM); - if ((ret = ff_formats_ref(formats, &phase->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &phase->outcfg.formats)) < 0) return ret; return 0; @@ -222,25 +223,6 @@ static int config_output(AVFilterLink *outlink) return 0; } -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - SpectrumSynthContext *s = ctx->priv; - int ret; - - if (!s->magnitude) { - ret = ff_request_frame(ctx->inputs[0]); - if (ret < 0) - return ret; - } - if (!s->phase) { - ret = ff_request_frame(ctx->inputs[1]); - if (ret < 0) - return ret; - } - return 0; -} - static void read16_fft_bin(SpectrumSynthContext *s, int x, int y, int f, int ch) { @@ -470,22 +452,43 @@ static int try_push_frames(AVFilterContext *ctx) return ret; } -static int filter_frame_magnitude(AVFilterLink *inlink, AVFrame *magnitude) +static int activate(AVFilterContext *ctx) { - AVFilterContext *ctx = inlink->dst; SpectrumSynthContext *s = ctx->priv; + AVFrame **staging[2] = { &s->magnitude, &s->phase }; + int64_t pts; + int i, ret; - s->magnitude = magnitude; - return try_push_frames(ctx); -} + FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[0], ctx); -static int filter_frame_phase(AVFilterLink *inlink, AVFrame *phase) -{ - AVFilterContext *ctx = inlink->dst; - SpectrumSynthContext *s = ctx->priv; + for (i = 0; i < 2; i++) { + if (*staging[i]) + continue; + ret = ff_inlink_consume_frame(ctx->inputs[i], staging[i]); + if (ret < 0) + return ret; + if (ret) { + ff_filter_set_ready(ctx, 10); + return try_push_frames(ctx); + } + } - s->phase = phase; - return try_push_frames(ctx); + for (i = 0; i < 2; i++) { + if (ff_inlink_acknowledge_status(ctx->inputs[i], &ret, &pts)) { + ff_outlink_set_status(ctx->outputs[0], ret, pts); + ff_inlink_set_status(ctx->inputs[1 - i], ret); + return 0; + } + } + + if (ff_outlink_frame_wanted(ctx->outputs[0])) { + for (i = 0; i < 2; i++) { + if (!*staging[i]) + ff_inlink_request_frame(ctx->inputs[i]); + } + } + + return FFERROR_NOT_READY; } static av_cold void uninit(AVFilterContext *ctx) @@ -509,14 +512,10 @@ static const AVFilterPad spectrumsynth_inputs[] = { { .name = "magnitude", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame_magnitude, - .needs_fifo = 1, }, { .name = "phase", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame_phase, - .needs_fifo = 1, }, { NULL } }; @@ -526,7 +525,6 @@ static const AVFilterPad spectrumsynth_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -536,6 +534,7 @@ AVFilter ff_vaf_spectrumsynth = { .description = NULL_IF_CONFIG_SMALL("Convert input spectrum videos to audio output."), .uninit = uninit, .query_formats = query_formats, + .activate = activate, .priv_size = sizeof(SpectrumSynthContext), .inputs = spectrumsynth_inputs, .outputs = spectrumsynth_outputs, diff --git a/libavfilter/version.h b/libavfilter/version.h index 96b14d679..33bb98e08 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 7 -#define LIBAVFILTER_VERSION_MINOR 85 +#define LIBAVFILTER_VERSION_MINOR 110 #define LIBAVFILTER_VERSION_MICRO 100 @@ -65,5 +65,11 @@ #ifndef FF_API_NEXT #define FF_API_NEXT (LIBAVFILTER_VERSION_MAJOR < 8) #endif +#ifndef FF_API_FILTER_LINK_SET_CLOSED +#define FF_API_FILTER_LINK_SET_CLOSED (LIBAVFILTER_VERSION_MAJOR < 8) +#endif +#ifndef FF_API_BUFFERSINK_ALLOC +#define FF_API_BUFFERSINK_ALLOC (LIBAVFILTER_VERSION_MAJOR < 9) +#endif #endif /* AVFILTER_VERSION_H */ diff --git a/libavfilter/vf_addroi.c b/libavfilter/vf_addroi.c index 489998ce7..d6b83ee85 100644 --- a/libavfilter/vf_addroi.c +++ b/libavfilter/vf_addroi.c @@ -26,8 +26,8 @@ enum { X, Y, W, H, NB_PARAMS, }; -static const char *addroi_param_names[] = { - "x", "y", "w", "h", +static const char addroi_param_names[] = { + 'x', 'y', 'w', 'h', }; enum { @@ -74,12 +74,12 @@ static int addroi_config_input(AVFilterLink *inlink) val = av_expr_eval(ctx->region_expr[i], vars, NULL); if (val < 0.0) { - av_log(avctx, AV_LOG_WARNING, "Calculated value %g for %s is " + av_log(avctx, AV_LOG_WARNING, "Calculated value %g for %c is " "less than zero - using zero instead.\n", val, addroi_param_names[i]); val = 0.0; } else if (val > max_value) { - av_log(avctx, AV_LOG_WARNING, "Calculated value %g for %s is " + av_log(avctx, AV_LOG_WARNING, "Calculated value %g for %c is " "greater than maximum allowed value %d - " "using %d instead.\n", val, addroi_param_names[i], max_value, max_value); @@ -194,7 +194,7 @@ static av_cold int addroi_init(AVFilterContext *avctx) 0, avctx); if (err < 0) { av_log(ctx, AV_LOG_ERROR, - "Error parsing %s expression '%s'.\n", + "Error parsing %c expression '%s'.\n", addroi_param_names[i], ctx->region_str[i]); return err; } diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c index 85b6d9b61..69532d61c 100644 --- a/libavfilter/vf_alphamerge.c +++ b/libavfilter/vf_alphamerge.c @@ -32,6 +32,7 @@ #include "drawutils.h" #include "formats.h" #include "filters.h" +#include "framesync.h" #include "internal.h" #include "video.h" @@ -42,83 +43,27 @@ typedef struct AlphaMergeContext { int is_packed_rgb; uint8_t rgba_map[4]; - AVFrame *main_frame; - AVFrame *alpha_frame; + + FFFrameSync fs; } AlphaMergeContext; -static int query_formats(AVFilterContext *ctx) +static int do_alphamerge(FFFrameSync *fs) { - static const enum AVPixelFormat main_fmts[] = { - AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_GBRAP, - AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, - AV_PIX_FMT_NONE - }; - static const enum AVPixelFormat alpha_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }; - AVFilterFormats *main_formats = NULL, *alpha_formats = NULL; + AVFilterContext *ctx = fs->parent; + AlphaMergeContext *s = ctx->priv; + AVFrame *main_buf, *alpha_buf; int ret; - if (!(main_formats = ff_make_format_list(main_fmts)) || - !(alpha_formats = ff_make_format_list(alpha_fmts))) { - ret = AVERROR(ENOMEM); - goto fail; - } - if ((ret = ff_formats_ref(main_formats , &ctx->inputs[0]->out_formats)) < 0 || - (ret = ff_formats_ref(alpha_formats, &ctx->inputs[1]->out_formats)) < 0 || - (ret = ff_formats_ref(main_formats , &ctx->outputs[0]->in_formats)) < 0) - goto fail; - return 0; -fail: - if (main_formats) - av_freep(&main_formats->formats); - av_freep(&main_formats); - if (alpha_formats) - av_freep(&alpha_formats->formats); - av_freep(&alpha_formats); - return ret; -} - -static int config_input_main(AVFilterLink *inlink) -{ - AlphaMergeContext *s = inlink->dst->priv; - s->is_packed_rgb = - ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0 && - inlink->format != AV_PIX_FMT_GBRAP; - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *mainlink = ctx->inputs[0]; - AVFilterLink *alphalink = ctx->inputs[1]; - if (mainlink->w != alphalink->w || mainlink->h != alphalink->h) { - av_log(ctx, AV_LOG_ERROR, - "Input frame sizes do not match (%dx%d vs %dx%d).\n", - mainlink->w, mainlink->h, - alphalink->w, alphalink->h); - return AVERROR(EINVAL); - } - - outlink->w = mainlink->w; - outlink->h = mainlink->h; - outlink->time_base = mainlink->time_base; - outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; - outlink->frame_rate = mainlink->frame_rate; - return 0; -} - -static void draw_frame(AVFilterContext *ctx, - AVFrame *main_buf, - AVFrame *alpha_buf) -{ - AlphaMergeContext *s = ctx->priv; - int h = main_buf->height; + ret = ff_framesync_dualinput_get_writable(fs, &main_buf, &alpha_buf); + if (ret < 0) + return ret; + if (!alpha_buf) + return ff_filter_frame(ctx->outputs[0], main_buf); if (s->is_packed_rgb) { int x, y; uint8_t *pin, *pout; - for (y = 0; y < h; y++) { + for (y = 0; y < main_buf->height; y++) { pin = alpha_buf->data[0] + y * alpha_buf->linesize[0]; pout = main_buf->data[0] + y * main_buf->linesize[0] + s->rgba_map[A]; for (x = 0; x < main_buf->width; x++) { @@ -134,55 +79,86 @@ static void draw_frame(AVFilterContext *ctx, alpha_buf->data[Y], alpha_linesize, FFMIN(main_linesize, alpha_linesize), alpha_buf->height); } + + return ff_filter_frame(ctx->outputs[0], main_buf); +} + +static av_cold int init(AVFilterContext *ctx) +{ + AlphaMergeContext *s = ctx->priv; + + s->fs.on_event = do_alphamerge; + return 0; +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat main_fmts[] = { + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, + AV_PIX_FMT_GBRAP, + AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, + AV_PIX_FMT_NONE + }; + static const enum AVPixelFormat alpha_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }; + AVFilterFormats *main_formats = ff_make_format_list(main_fmts); + int ret; + + if ((ret = ff_formats_ref(main_formats, &ctx->inputs[0]->outcfg.formats)) < 0 || + (ret = ff_formats_ref(main_formats, &ctx->outputs[0]->incfg.formats)) < 0) + return ret; + + return ff_formats_ref(ff_make_format_list(alpha_fmts), + &ctx->inputs[1]->outcfg.formats); +} + +static int config_input_main(AVFilterLink *inlink) +{ + AlphaMergeContext *s = inlink->dst->priv; + s->is_packed_rgb = + ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0 && + inlink->format != AV_PIX_FMT_GBRAP; + return 0; +} + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + AlphaMergeContext *s = ctx->priv; + AVFilterLink *mainlink = ctx->inputs[0]; + AVFilterLink *alphalink = ctx->inputs[1]; + int ret; + + if (mainlink->w != alphalink->w || mainlink->h != alphalink->h) { + av_log(ctx, AV_LOG_ERROR, + "Input frame sizes do not match (%dx%d vs %dx%d).\n", + mainlink->w, mainlink->h, + alphalink->w, alphalink->h); + return AVERROR(EINVAL); + } + + if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0) + return ret; + + outlink->w = mainlink->w; + outlink->h = mainlink->h; + outlink->time_base = mainlink->time_base; + outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; + outlink->frame_rate = mainlink->frame_rate; + + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) { - AVFilterLink *outlink = ctx->outputs[0]; AlphaMergeContext *s = ctx->priv; - int ret; + return ff_framesync_activate(&s->fs); +} - FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx); +static av_cold void uninit(AVFilterContext *ctx) +{ + AlphaMergeContext *s = ctx->priv; - if (!s->main_frame) { - ret = ff_inlink_consume_frame(ctx->inputs[0], &s->main_frame); - if (ret < 0) - return ret; - } - - if (!s->alpha_frame) { - ret = ff_inlink_consume_frame(ctx->inputs[1], &s->alpha_frame); - if (ret < 0) - return ret; - } - - if (s->main_frame && s->alpha_frame) { - if (!ctx->is_disabled) - draw_frame(ctx, s->main_frame, s->alpha_frame); - ret = ff_filter_frame(outlink, s->main_frame); - av_frame_free(&s->alpha_frame); - s->main_frame = NULL; - return ret; - } - - FF_FILTER_FORWARD_STATUS(ctx->inputs[0], outlink); - FF_FILTER_FORWARD_STATUS(ctx->inputs[1], outlink); - - if (ff_outlink_frame_wanted(ctx->outputs[0]) && - !ff_outlink_get_status(ctx->inputs[0]) && - !s->main_frame) { - ff_inlink_request_frame(ctx->inputs[0]); - return 0; - } - - if (ff_outlink_frame_wanted(ctx->outputs[0]) && - !ff_outlink_get_status(ctx->inputs[1]) && - !s->alpha_frame) { - ff_inlink_request_frame(ctx->inputs[1]); - return 0; - } - - return FFERROR_NOT_READY; + ff_framesync_uninit(&s->fs); } static const AVFilterPad alphamerge_inputs[] = { @@ -190,7 +166,6 @@ static const AVFilterPad alphamerge_inputs[] = { .name = "main", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_input_main, - .needs_writable = 1, },{ .name = "alpha", .type = AVMEDIA_TYPE_VIDEO, @@ -211,17 +186,20 @@ static const AVOption alphamerge_options[] = { { NULL } }; -AVFILTER_DEFINE_CLASS(alphamerge); +FRAMESYNC_DEFINE_CLASS(alphamerge, AlphaMergeContext, fs); AVFilter ff_vf_alphamerge = { .name = "alphamerge", .description = NULL_IF_CONFIG_SMALL("Copy the luma value of the second " "input into the alpha channel of the first input."), + .preinit = alphamerge_framesync_preinit, .priv_size = sizeof(AlphaMergeContext), .priv_class = &alphamerge_class, + .init = init, .query_formats = query_formats, .inputs = alphamerge_inputs, .outputs = alphamerge_outputs, + .uninit = uninit, .activate = activate, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, }; diff --git a/libavfilter/vf_atadenoise.c b/libavfilter/vf_atadenoise.c index e1a822045..ccbda723f 100644 --- a/libavfilter/vf_atadenoise.c +++ b/libavfilter/vf_atadenoise.c @@ -44,6 +44,7 @@ typedef struct ATADenoiseContext { const AVClass *class; float fthra[4], fthrb[4]; + float sigma[4]; int thra[4], thrb[4]; int algorithm; @@ -55,7 +56,8 @@ typedef struct ATADenoiseContext { struct FFBufQueue q; void *data[4][SIZE]; int linesize[4][SIZE]; - int size, mid; + float weights[4][SIZE]; + int size, mid, radius; int available; int (*filter_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); @@ -79,6 +81,9 @@ static const AVOption atadenoise_options[] = { { "a", "set variant of algorithm", OFFSET(algorithm),AV_OPT_TYPE_INT, {.i64=PARALLEL}, 0, NB_ATAA-1, FLAGS, "a" }, { "p", "parallel", 0, AV_OPT_TYPE_CONST, {.i64=PARALLEL}, 0, 0, FLAGS, "a" }, { "s", "serial", 0, AV_OPT_TYPE_CONST, {.i64=SERIAL}, 0, 0, FLAGS, "a" }, + { "0s", "set sigma for 1st plane", OFFSET(sigma[0]), AV_OPT_TYPE_FLOAT, {.dbl=INT16_MAX}, 0, INT16_MAX, FLAGS }, + { "1s", "set sigma for 2nd plane", OFFSET(sigma[1]), AV_OPT_TYPE_FLOAT, {.dbl=INT16_MAX}, 0, INT16_MAX, FLAGS }, + { "2s", "set sigma for 3rd plane", OFFSET(sigma[2]), AV_OPT_TYPE_FLOAT, {.dbl=INT16_MAX}, 0, INT16_MAX, FLAGS }, { NULL } }; @@ -129,7 +134,8 @@ static av_cold int init(AVFilterContext *ctx) av_log(ctx, AV_LOG_WARNING, "size %d is invalid. Must be an odd value, setting it to %d.\n", s->size, s->size|1); s->size |= 1; } - s->mid = s->size / 2 + 1; + s->radius = s->size / 2; + s->mid = s->radius; return 0; } @@ -138,11 +144,114 @@ typedef struct ThreadData { AVFrame *in, *out; } ThreadData; +#define WFILTER_ROW(type, name) \ +static void fweight_row##name(const uint8_t *ssrc, uint8_t *ddst, \ + const uint8_t *ssrcf[SIZE], \ + int w, int mid, int size, \ + int thra, int thrb, const float *weights) \ +{ \ + const type *src = (const type *)ssrc; \ + const type **srcf = (const type **)ssrcf; \ + type *dst = (type *)ddst; \ + \ + for (int x = 0; x < w; x++) { \ + const int srcx = src[x]; \ + unsigned lsumdiff = 0, rsumdiff = 0; \ + unsigned ldiff, rdiff; \ + float sum = srcx; \ + float wsum = 1.f; \ + int l = 0, r = 0; \ + int srcjx, srcix; \ + \ + for (int j = mid - 1, i = mid + 1; j >= 0 && i < size; j--, i++) { \ + srcjx = srcf[j][x]; \ + \ + ldiff = FFABS(srcx - srcjx); \ + lsumdiff += ldiff; \ + if (ldiff > thra || \ + lsumdiff > thrb) \ + break; \ + l++; \ + sum += srcjx * weights[j]; \ + wsum += weights[j]; \ + \ + srcix = srcf[i][x]; \ + \ + rdiff = FFABS(srcx - srcix); \ + rsumdiff += rdiff; \ + if (rdiff > thra || \ + rsumdiff > thrb) \ + break; \ + r++; \ + sum += srcix * weights[i]; \ + wsum += weights[i]; \ + } \ + \ + dst[x] = lrintf(sum / wsum); \ + } \ +} + +WFILTER_ROW(uint8_t, 8) +WFILTER_ROW(uint16_t, 16) + +#define WFILTER_ROW_SERIAL(type, name) \ +static void fweight_row##name##_serial(const uint8_t *ssrc, uint8_t *ddst, \ + const uint8_t *ssrcf[SIZE], \ + int w, int mid, int size, \ + int thra, int thrb, \ + const float *weights) \ +{ \ + const type *src = (const type *)ssrc; \ + const type **srcf = (const type **)ssrcf; \ + type *dst = (type *)ddst; \ + \ + for (int x = 0; x < w; x++) { \ + const int srcx = src[x]; \ + unsigned lsumdiff = 0, rsumdiff = 0; \ + unsigned ldiff, rdiff; \ + float sum = srcx; \ + float wsum = 1.f; \ + int l = 0, r = 0; \ + int srcjx, srcix; \ + \ + for (int j = mid - 1; j >= 0; j--) { \ + srcjx = srcf[j][x]; \ + \ + ldiff = FFABS(srcx - srcjx); \ + lsumdiff += ldiff; \ + if (ldiff > thra || \ + lsumdiff > thrb) \ + break; \ + l++; \ + sum += srcjx * weights[j]; \ + wsum += weights[j]; \ + } \ + \ + for (int i = mid + 1; i < size; i++) { \ + srcix = srcf[i][x]; \ + \ + rdiff = FFABS(srcx - srcix); \ + rsumdiff += rdiff; \ + if (rdiff > thra || \ + rsumdiff > thrb) \ + break; \ + r++; \ + sum += srcix * weights[i]; \ + wsum += weights[i]; \ + } \ + \ + dst[x] = lrintf(sum / wsum); \ + } \ +} + +WFILTER_ROW_SERIAL(uint8_t, 8) +WFILTER_ROW_SERIAL(uint16_t, 16) + #define FILTER_ROW(type, name) \ static void filter_row##name(const uint8_t *ssrc, uint8_t *ddst, \ const uint8_t *ssrcf[SIZE], \ int w, int mid, int size, \ - int thra, int thrb) \ + int thra, int thrb, const float *weights) \ { \ const type *src = (const type *)ssrc; \ const type **srcf = (const type **)ssrcf; \ @@ -189,7 +298,8 @@ FILTER_ROW(uint16_t, 16) static void filter_row##name##_serial(const uint8_t *ssrc, uint8_t *ddst, \ const uint8_t *ssrcf[SIZE], \ int w, int mid, int size, \ - int thra, int thrb) \ + int thra, int thrb, \ + const float *weights) \ { \ const type *src = (const type *)ssrc; \ const type **srcf = (const type **)ssrcf; \ @@ -245,6 +355,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) int p, y, i; for (p = 0; p < s->nb_planes; p++) { + const float *weights = s->weights[p]; const int h = s->planeheight[p]; const int w = s->planewidth[p]; const int slice_start = (h * jobnr) / nb_jobs; @@ -267,7 +378,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) srcf[i] = data[i] + slice_start * linesize[i]; for (y = slice_start; y < slice_end; y++) { - s->dsp.filter_row(src, dst, srcf, w, mid, size, thra, thrb); + s->dsp.filter_row[p](src, dst, srcf, w, mid, size, thra, thrb, weights); dst += out->linesize[p]; src += in->linesize[p]; @@ -296,10 +407,17 @@ static int config_input(AVFilterLink *inlink) depth = desc->comp[0].depth; s->filter_slice = filter_slice; - if (depth == 8) - s->dsp.filter_row = s->algorithm == PARALLEL ? filter_row8 : filter_row8_serial; - else - s->dsp.filter_row = s->algorithm == PARALLEL ? filter_row16 : filter_row16_serial; + + for (int p = 0; p < s->nb_planes; p++) { + if (depth == 8 && s->sigma[p] == INT16_MAX) + s->dsp.filter_row[p] = s->algorithm == PARALLEL ? filter_row8 : filter_row8_serial; + else if (s->sigma[p] == INT16_MAX) + s->dsp.filter_row[p] = s->algorithm == PARALLEL ? filter_row16 : filter_row16_serial; + else if (depth == 8 && s->sigma[p] < INT16_MAX) + s->dsp.filter_row[p] = s->algorithm == PARALLEL ? fweight_row8 : fweight_row8_serial; + else if (s->sigma[p] < INT16_MAX) + s->dsp.filter_row[p] = s->algorithm == PARALLEL ? fweight_row16 : fweight_row16_serial; + } s->thra[0] = s->fthra[0] * (1 << depth) - 1; s->thra[1] = s->fthra[1] * (1 << depth) - 1; @@ -308,8 +426,18 @@ static int config_input(AVFilterLink *inlink) s->thrb[1] = s->fthrb[1] * (1 << depth) - 1; s->thrb[2] = s->fthrb[2] * (1 << depth) - 1; + for (int p = 0; p < s->nb_planes; p++) { + float sigma = s->radius * s->sigma[p]; + + s->weights[p][s->radius] = 1.f; + for (int n = 1; n <= s->radius; n++) { + s->weights[p][s->radius + n] = + s->weights[p][s->radius - n] = expf(-0.5 * (n + 1) * (n + 1) / (sigma * sigma)); + } + } + if (ARCH_X86) - ff_atadenoise_init_x86(&s->dsp, depth, s->algorithm); + ff_atadenoise_init_x86(&s->dsp, depth, s->algorithm, s->sigma); return 0; } diff --git a/libavfilter/vf_bbox.c b/libavfilter/vf_bbox.c index 4ac2980a6..acbb4ea16 100644 --- a/libavfilter/vf_bbox.c +++ b/libavfilter/vf_bbox.c @@ -33,13 +33,14 @@ typedef struct BBoxContext { const AVClass *class; int min_val; + int depth; } BBoxContext; #define OFFSET(x) offsetof(BBoxContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption bbox_options[] = { - { "min_val", "set minimum luminance value for bounding box", OFFSET(min_val), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 254, FLAGS }, + { "min_val", "set minimum luminance value for bounding box", OFFSET(min_val), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, UINT16_MAX, FLAGS }, { NULL } }; @@ -48,11 +49,26 @@ AVFILTER_DEFINE_CLASS(bbox); static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV411P, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, + AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, + AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_NONE, }; @@ -75,7 +91,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) has_bbox = ff_calculate_bounding_box(&box, frame->data[0], frame->linesize[0], - inlink->w, inlink->h, bbox->min_val); + inlink->w, inlink->h, bbox->min_val, bbox->depth); w = box.x2 - box.x1 + 1; h = box.y2 - box.y1 + 1; @@ -105,6 +121,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) return ff_filter_frame(inlink->dst->outputs[0], frame); } +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + BBoxContext *s = ctx->priv; + const AVPixFmtDescriptor *desc; + + desc = av_pix_fmt_desc_get(outlink->format); + if (!desc) + return AVERROR_BUG; + s->depth = desc->comp[0].depth; + + return 0; +} + static const AVFilterPad bbox_inputs[] = { { .name = "default", @@ -118,6 +148,7 @@ static const AVFilterPad bbox_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, }, { NULL } }; @@ -131,4 +162,5 @@ AVFilter ff_vf_bbox = { .inputs = bbox_inputs, .outputs = bbox_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, + .process_command = ff_filter_process_command, }; diff --git a/libavfilter/vf_bilateral.c b/libavfilter/vf_bilateral.c index 3c9d8006d..3eaf8dd00 100644 --- a/libavfilter/vf_bilateral.c +++ b/libavfilter/vf_bilateral.c @@ -41,6 +41,7 @@ typedef struct BilateralContext { int planewidth[4]; int planeheight[4]; + float alpha; float range_table[65536]; float *img_out_f; @@ -54,10 +55,10 @@ typedef struct BilateralContext { } BilateralContext; #define OFFSET(x) offsetof(BilateralContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption bilateral_options[] = { - { "sigmaS", "set spatial sigma", OFFSET(sigmaS), AV_OPT_TYPE_FLOAT, {.dbl=0.1}, 0.0, 10, FLAGS }, + { "sigmaS", "set spatial sigma", OFFSET(sigmaS), AV_OPT_TYPE_FLOAT, {.dbl=0.1}, 0.0, 512, FLAGS }, { "sigmaR", "set range sigma", OFFSET(sigmaR), AV_OPT_TYPE_FLOAT, {.dbl=0.1}, 0.0, 1, FLAGS }, { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=1}, 0, 0xF, FLAGS }, { NULL } @@ -91,18 +92,30 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); } -static int config_input(AVFilterLink *inlink) +static int config_params(AVFilterContext *ctx) { - BilateralContext *s = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + BilateralContext *s = ctx->priv; float inv_sigma_range; - s->depth = desc->comp[0].depth; inv_sigma_range = 1.0f / (s->sigmaR * ((1 << s->depth) - 1)); + s->alpha = expf(-sqrtf(2.f) / s->sigmaS); //compute a lookup table for (int i = 0; i < (1 << s->depth); i++) - s->range_table[i] = expf(-i * inv_sigma_range); + s->range_table[i] = s->alpha * expf(-i * inv_sigma_range); + + return 0; +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + BilateralContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + + s->depth = desc->comp[0].depth; + + config_params(ctx); s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); s->planewidth[0] = s->planewidth[3] = inlink->w; @@ -144,10 +157,10 @@ static void bilateral_##name(BilateralContext *s, const uint8_t *ssrc, uint8_t * float *map_factor_a = s->map_factor_a, *map_factor_b = s->map_factor_b; \ float *slice_factor_a = s->slice_factor_a, *slice_factor_b = s->slice_factor_b; \ float *line_factor_a = s->line_factor_a, *line_factor_b = s->line_factor_b; \ - float *range_table = s->range_table; \ - float alpha = expf(-sqrtf(2.f) / (sigma_spatial * width)); \ + const float *range_table = s->range_table; \ + const float alpha = s->alpha; \ float ypr, ycr, *ycy, *ypy, *xcy, fp, fc; \ - float inv_alpha_ = 1 - alpha; \ + const float inv_alpha_ = 1.f - alpha; \ float *ycf, *ypf, *xcf, *in_factor; \ const type *tcy, *tpy; \ int h1; \ @@ -165,14 +178,13 @@ static void bilateral_##name(BilateralContext *s, const uint8_t *ssrc, uint8_t * *temp_factor_x++ = fp = 1; \ \ for (int x = 1; x < width; x++) { \ - float weight, alpha_; \ + float alpha_; \ int range_dist; \ type tcr = *texture_x++; \ type dr = abs(tcr - tpr); \ \ range_dist = dr; \ - weight = range_table[range_dist]; \ - alpha_ = weight*alpha; \ + alpha_ = range_table[range_dist]; \ *temp_x++ = ycr = inv_alpha_*(*in_x++) + alpha_*ypr; \ tpr = tcr; \ ypr = ycr; \ @@ -190,8 +202,7 @@ static void bilateral_##name(BilateralContext *s, const uint8_t *ssrc, uint8_t * type tcr = *--texture_x; \ type dr = abs(tcr - tpr); \ int range_dist = dr; \ - float weight = range_table[range_dist]; \ - float alpha_ = weight * alpha; \ + float alpha_ = range_table[range_dist]; \ \ ycr = inv_alpha_ * (*--in_x) + alpha_ * ypr; \ --temp_x; *temp_x = 0.5f*((*temp_x) + ycr); \ @@ -206,8 +217,6 @@ static void bilateral_##name(BilateralContext *s, const uint8_t *ssrc, uint8_t * } \ memcpy(img_out_f, img_temp, sizeof(float) * width); \ \ - alpha = expf(-sqrtf(2.f) / (sigma_spatial * height)); \ - inv_alpha_ = 1 - alpha; \ in_factor = map_factor_a; \ memcpy(map_factor_b, in_factor, sizeof(float) * width); \ for (int y = 1; y < height; y++) { \ @@ -223,8 +232,7 @@ static void bilateral_##name(BilateralContext *s, const uint8_t *ssrc, uint8_t * for (int x = 0; x < width; x++) { \ type dr = abs((*tcy++) - (*tpy++)); \ int range_dist = dr; \ - float weight = range_table[range_dist]; \ - float alpha_ = weight*alpha; \ + float alpha_ = range_table[range_dist]; \ \ *ycy++ = inv_alpha_*(*xcy++) + alpha_*(*ypy++); \ *ycf++ = inv_alpha_*(*xcf++) + alpha_*(*ypf++); \ @@ -263,8 +271,7 @@ static void bilateral_##name(BilateralContext *s, const uint8_t *ssrc, uint8_t * for (int x = 0; x < width; x++) { \ type dr = abs((*tcy++) - (*tpy++)); \ int range_dist = dr; \ - float weight = range_table[range_dist]; \ - float alpha_ = weight*alpha; \ + float alpha_ = range_table[range_dist]; \ float ycc, fcc = inv_alpha_*(*xcf++) + alpha_*(*ypf_++); \ \ *ycf_++ = fcc; \ @@ -277,8 +284,8 @@ static void bilateral_##name(BilateralContext *s, const uint8_t *ssrc, uint8_t * factor_++; \ } \ \ - memcpy(ypy, ycy, sizeof(float) * width); \ - memcpy(ypf, ycf, sizeof(float) * width); \ + ypy = ycy; \ + ypf = ycf; \ } \ \ for (int i = 0; i < height; i++) \ @@ -339,6 +346,21 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&s->line_factor_b); } +static int process_command(AVFilterContext *ctx, + const char *cmd, + const char *arg, + char *res, + int res_len, + int flags) +{ + int ret = ff_filter_process_command(ctx, cmd, arg, res, res_len, flags); + + if (ret < 0) + return ret; + + return config_params(ctx); +} + static const AVFilterPad bilateral_inputs[] = { { .name = "default", @@ -367,4 +389,5 @@ AVFilter ff_vf_bilateral = { .inputs = bilateral_inputs, .outputs = bilateral_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, + .process_command = process_command, }; diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c index 4b5d8ff56..565a7545e 100644 --- a/libavfilter/vf_blackdetect.c +++ b/libavfilter/vf_blackdetect.c @@ -26,6 +26,7 @@ #include #include "libavutil/opt.h" +#include "libavutil/pixdesc.h" #include "libavutil/timestamp.h" #include "avfilter.h" #include "internal.h" @@ -44,6 +45,10 @@ typedef struct BlackDetectContext { unsigned int pixel_black_th_i; unsigned int nb_black_pixels; ///< number of black pixels counted so far + AVRational time_base; + int depth; + int nb_threads; + unsigned int *counter; } BlackDetectContext; #define OFFSET(x) offsetof(BlackDetectContext, x) @@ -77,6 +82,19 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, YUVJ_FORMATS, + AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, + AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_NONE }; @@ -89,97 +107,139 @@ static int query_formats(AVFilterContext *ctx) static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; - BlackDetectContext *blackdetect = ctx->priv; + BlackDetectContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + const int depth = desc->comp[0].depth; + const int max = (1 << depth) - 1; + const int factor = (1 << (depth - 8)); - blackdetect->black_min_duration = - blackdetect->black_min_duration_time / av_q2d(inlink->time_base); + s->depth = depth; + s->nb_threads = ff_filter_get_nb_threads(ctx); + s->time_base = inlink->time_base; + s->black_min_duration = s->black_min_duration_time / av_q2d(s->time_base); + s->counter = av_calloc(s->nb_threads, sizeof(*s->counter)); + if (!s->counter) + return AVERROR(ENOMEM); - blackdetect->pixel_black_th_i = ff_fmt_is_in(inlink->format, yuvj_formats) ? + s->pixel_black_th_i = ff_fmt_is_in(inlink->format, yuvj_formats) ? // luminance_minimum_value + pixel_black_th * luminance_range_size - blackdetect->pixel_black_th * 255 : - 16 + blackdetect->pixel_black_th * (235 - 16); + s->pixel_black_th * max : + 16 * factor + s->pixel_black_th * (235 - 16) * factor; - av_log(blackdetect, AV_LOG_VERBOSE, + av_log(s, AV_LOG_VERBOSE, "black_min_duration:%s pixel_black_th:%f pixel_black_th_i:%d picture_black_ratio_th:%f\n", - av_ts2timestr(blackdetect->black_min_duration, &inlink->time_base), - blackdetect->pixel_black_th, blackdetect->pixel_black_th_i, - blackdetect->picture_black_ratio_th); + av_ts2timestr(s->black_min_duration, &s->time_base), + s->pixel_black_th, s->pixel_black_th_i, + s->picture_black_ratio_th); return 0; } static void check_black_end(AVFilterContext *ctx) { - BlackDetectContext *blackdetect = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; + BlackDetectContext *s = ctx->priv; - if ((blackdetect->black_end - blackdetect->black_start) >= blackdetect->black_min_duration) { - av_log(blackdetect, AV_LOG_INFO, + if ((s->black_end - s->black_start) >= s->black_min_duration) { + av_log(s, AV_LOG_INFO, "black_start:%s black_end:%s black_duration:%s\n", - av_ts2timestr(blackdetect->black_start, &inlink->time_base), - av_ts2timestr(blackdetect->black_end, &inlink->time_base), - av_ts2timestr(blackdetect->black_end - blackdetect->black_start, &inlink->time_base)); + av_ts2timestr(s->black_start, &s->time_base), + av_ts2timestr(s->black_end, &s->time_base), + av_ts2timestr(s->black_end - s->black_start, &s->time_base)); } } -static int request_frame(AVFilterLink *outlink) +static int black_counter(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs) { - AVFilterContext *ctx = outlink->src; - BlackDetectContext *blackdetect = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - int ret = ff_request_frame(inlink); + BlackDetectContext *s = ctx->priv; + const unsigned int threshold = s->pixel_black_th_i; + unsigned int *counterp = &s->counter[jobnr]; + AVFrame *in = arg; + const int linesize = in->linesize[0]; + const int w = in->width; + const int h = in->height; + const int start = (h * jobnr) / nb_jobs; + const int end = (h * (jobnr+1)) / nb_jobs; + const int size = end - start; + unsigned int counter = 0; - if (ret == AVERROR_EOF && blackdetect->black_started) { - // FIXME: black_end should be set to last_picref_pts + last_picref_duration - blackdetect->black_end = blackdetect->last_picref_pts; - check_black_end(ctx); + if (s->depth == 8) { + const uint8_t *p = in->data[0] + start * linesize; + + for (int i = 0; i < size; i++) { + for (int x = 0; x < w; x++) + counter += p[x] <= threshold; + p += linesize; + } + } else { + const uint16_t *p = (const uint16_t *)(in->data[0] + start * linesize); + + for (int i = 0; i < size; i++) { + for (int x = 0; x < w; x++) + counter += p[x] <= threshold; + p += linesize / 2; + } } - return ret; + + *counterp = counter; + + return 0; } static int filter_frame(AVFilterLink *inlink, AVFrame *picref) { AVFilterContext *ctx = inlink->dst; - BlackDetectContext *blackdetect = ctx->priv; + BlackDetectContext *s = ctx->priv; double picture_black_ratio = 0; - const uint8_t *p = picref->data[0]; - int x, i; - for (i = 0; i < inlink->h; i++) { - for (x = 0; x < inlink->w; x++) - blackdetect->nb_black_pixels += p[x] <= blackdetect->pixel_black_th_i; - p += picref->linesize[0]; - } + ctx->internal->execute(ctx, black_counter, picref, NULL, + FFMIN(inlink->h, s->nb_threads)); - picture_black_ratio = (double)blackdetect->nb_black_pixels / (inlink->w * inlink->h); + for (int i = 0; i < s->nb_threads; i++) + s->nb_black_pixels += s->counter[i]; + + picture_black_ratio = (double)s->nb_black_pixels / (inlink->w * inlink->h); av_log(ctx, AV_LOG_DEBUG, "frame:%"PRId64" picture_black_ratio:%f pts:%s t:%s type:%c\n", inlink->frame_count_out, picture_black_ratio, - av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base), + av_ts2str(picref->pts), av_ts2timestr(picref->pts, &s->time_base), av_get_picture_type_char(picref->pict_type)); - if (picture_black_ratio >= blackdetect->picture_black_ratio_th) { - if (!blackdetect->black_started) { + if (picture_black_ratio >= s->picture_black_ratio_th) { + if (!s->black_started) { /* black starts here */ - blackdetect->black_started = 1; - blackdetect->black_start = picref->pts; + s->black_started = 1; + s->black_start = picref->pts; av_dict_set(&picref->metadata, "lavfi.black_start", - av_ts2timestr(blackdetect->black_start, &inlink->time_base), 0); + av_ts2timestr(s->black_start, &s->time_base), 0); } - } else if (blackdetect->black_started) { + } else if (s->black_started) { /* black ends here */ - blackdetect->black_started = 0; - blackdetect->black_end = picref->pts; + s->black_started = 0; + s->black_end = picref->pts; check_black_end(ctx); av_dict_set(&picref->metadata, "lavfi.black_end", - av_ts2timestr(blackdetect->black_end, &inlink->time_base), 0); + av_ts2timestr(s->black_end, &s->time_base), 0); } - blackdetect->last_picref_pts = picref->pts; - blackdetect->nb_black_pixels = 0; + s->last_picref_pts = picref->pts; + s->nb_black_pixels = 0; return ff_filter_frame(inlink->dst->outputs[0], picref); } +static av_cold void uninit(AVFilterContext *ctx) +{ + BlackDetectContext *s = ctx->priv; + + av_freep(&s->counter); + + if (s->black_started) { + // FIXME: black_end should be set to last_picref_pts + last_picref_duration + s->black_end = s->last_picref_pts; + check_black_end(ctx); + } +} + static const AVFilterPad blackdetect_inputs[] = { { .name = "default", @@ -194,7 +254,6 @@ static const AVFilterPad blackdetect_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, }, { NULL } }; @@ -206,5 +265,7 @@ AVFilter ff_vf_blackdetect = { .query_formats = query_formats, .inputs = blackdetect_inputs, .outputs = blackdetect_outputs, + .uninit = uninit, .priv_class = &blackdetect_class, + .flags = AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c index d59bed823..d12bfffbe 100644 --- a/libavfilter/vf_blend.c +++ b/libavfilter/vf_blend.c @@ -60,63 +60,60 @@ typedef struct ThreadData { FilterParams *param; } ThreadData; -#define COMMON_OPTIONS \ - { "c0_mode", "set component #0 blend mode", OFFSET(params[0].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},\ - { "c1_mode", "set component #1 blend mode", OFFSET(params[1].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},\ - { "c2_mode", "set component #2 blend mode", OFFSET(params[2].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},\ - { "c3_mode", "set component #3 blend mode", OFFSET(params[3].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},\ - { "all_mode", "set blend mode for all components", OFFSET(all_mode), AV_OPT_TYPE_INT, {.i64=-1},-1, BLEND_NB-1, FLAGS, "mode"},\ - { "addition", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_ADDITION}, 0, 0, FLAGS, "mode" },\ - { "addition128","", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINMERGE}, 0, 0, FLAGS, "mode" },\ - { "grainmerge", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINMERGE}, 0, 0, FLAGS, "mode" },\ - { "and", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AND}, 0, 0, FLAGS, "mode" },\ - { "average", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AVERAGE}, 0, 0, FLAGS, "mode" },\ - { "burn", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_BURN}, 0, 0, FLAGS, "mode" },\ - { "darken", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DARKEN}, 0, 0, FLAGS, "mode" },\ - { "difference", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE}, 0, 0, FLAGS, "mode" },\ - { "difference128", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINEXTRACT}, 0, 0, FLAGS, "mode" },\ - { "grainextract", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINEXTRACT}, 0, 0, FLAGS, "mode" },\ - { "divide", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIVIDE}, 0, 0, FLAGS, "mode" },\ - { "dodge", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DODGE}, 0, 0, FLAGS, "mode" },\ - { "exclusion", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXCLUSION}, 0, 0, FLAGS, "mode" },\ - { "extremity", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXTREMITY}, 0, 0, FLAGS, "mode" },\ - { "freeze", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_FREEZE}, 0, 0, FLAGS, "mode" },\ - { "glow", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GLOW}, 0, 0, FLAGS, "mode" },\ - { "hardlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HARDLIGHT}, 0, 0, FLAGS, "mode" },\ - { "hardmix", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HARDMIX}, 0, 0, FLAGS, "mode" },\ - { "heat", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HEAT}, 0, 0, FLAGS, "mode" },\ - { "lighten", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_LIGHTEN}, 0, 0, FLAGS, "mode" },\ - { "linearlight","", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_LINEARLIGHT},0, 0, FLAGS, "mode" },\ - { "multiply", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_MULTIPLY}, 0, 0, FLAGS, "mode" },\ - { "multiply128","", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_MULTIPLY128},0, 0, FLAGS, "mode" },\ - { "negation", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NEGATION}, 0, 0, FLAGS, "mode" },\ - { "normal", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NORMAL}, 0, 0, FLAGS, "mode" },\ - { "or", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OR}, 0, 0, FLAGS, "mode" },\ - { "overlay", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OVERLAY}, 0, 0, FLAGS, "mode" },\ - { "phoenix", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PHOENIX}, 0, 0, FLAGS, "mode" },\ - { "pinlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PINLIGHT}, 0, 0, FLAGS, "mode" },\ - { "reflect", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_REFLECT}, 0, 0, FLAGS, "mode" },\ - { "screen", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SCREEN}, 0, 0, FLAGS, "mode" },\ - { "softlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SOFTLIGHT}, 0, 0, FLAGS, "mode" },\ - { "subtract", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SUBTRACT}, 0, 0, FLAGS, "mode" },\ - { "vividlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_VIVIDLIGHT}, 0, 0, FLAGS, "mode" },\ - { "xor", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_XOR}, 0, 0, FLAGS, "mode" },\ - { "c0_expr", "set color component #0 expression", OFFSET(params[0].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },\ - { "c1_expr", "set color component #1 expression", OFFSET(params[1].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },\ - { "c2_expr", "set color component #2 expression", OFFSET(params[2].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },\ - { "c3_expr", "set color component #3 expression", OFFSET(params[3].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },\ - { "all_expr", "set expression for all color components", OFFSET(all_expr), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },\ - { "c0_opacity", "set color component #0 opacity", OFFSET(params[0].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },\ - { "c1_opacity", "set color component #1 opacity", OFFSET(params[1].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },\ - { "c2_opacity", "set color component #2 opacity", OFFSET(params[2].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },\ - { "c3_opacity", "set color component #3 opacity", OFFSET(params[3].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },\ - { "all_opacity", "set opacity for all color components", OFFSET(all_opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS} - #define OFFSET(x) offsetof(BlendContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption blend_options[] = { - COMMON_OPTIONS, + { "c0_mode", "set component #0 blend mode", OFFSET(params[0].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode" }, + { "c1_mode", "set component #1 blend mode", OFFSET(params[1].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode" }, + { "c2_mode", "set component #2 blend mode", OFFSET(params[2].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode" }, + { "c3_mode", "set component #3 blend mode", OFFSET(params[3].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode" }, + { "all_mode", "set blend mode for all components", OFFSET(all_mode), AV_OPT_TYPE_INT, {.i64=-1},-1, BLEND_NB-1, FLAGS, "mode" }, + { "addition", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_ADDITION}, 0, 0, FLAGS, "mode" }, + { "addition128","", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINMERGE}, 0, 0, FLAGS, "mode" }, + { "grainmerge", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINMERGE}, 0, 0, FLAGS, "mode" }, + { "and", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AND}, 0, 0, FLAGS, "mode" }, + { "average", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AVERAGE}, 0, 0, FLAGS, "mode" }, + { "burn", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_BURN}, 0, 0, FLAGS, "mode" }, + { "darken", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DARKEN}, 0, 0, FLAGS, "mode" }, + { "difference", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE}, 0, 0, FLAGS, "mode" }, + { "difference128", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINEXTRACT}, 0, 0, FLAGS, "mode" }, + { "grainextract", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINEXTRACT}, 0, 0, FLAGS, "mode" }, + { "divide", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIVIDE}, 0, 0, FLAGS, "mode" }, + { "dodge", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DODGE}, 0, 0, FLAGS, "mode" }, + { "exclusion", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXCLUSION}, 0, 0, FLAGS, "mode" }, + { "extremity", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXTREMITY}, 0, 0, FLAGS, "mode" }, + { "freeze", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_FREEZE}, 0, 0, FLAGS, "mode" }, + { "glow", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GLOW}, 0, 0, FLAGS, "mode" }, + { "hardlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HARDLIGHT}, 0, 0, FLAGS, "mode" }, + { "hardmix", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HARDMIX}, 0, 0, FLAGS, "mode" }, + { "heat", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HEAT}, 0, 0, FLAGS, "mode" }, + { "lighten", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_LIGHTEN}, 0, 0, FLAGS, "mode" }, + { "linearlight","", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_LINEARLIGHT},0, 0, FLAGS, "mode" }, + { "multiply", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_MULTIPLY}, 0, 0, FLAGS, "mode" }, + { "multiply128","", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_MULTIPLY128},0, 0, FLAGS, "mode" }, + { "negation", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NEGATION}, 0, 0, FLAGS, "mode" }, + { "normal", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NORMAL}, 0, 0, FLAGS, "mode" }, + { "or", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OR}, 0, 0, FLAGS, "mode" }, + { "overlay", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OVERLAY}, 0, 0, FLAGS, "mode" }, + { "phoenix", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PHOENIX}, 0, 0, FLAGS, "mode" }, + { "pinlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PINLIGHT}, 0, 0, FLAGS, "mode" }, + { "reflect", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_REFLECT}, 0, 0, FLAGS, "mode" }, + { "screen", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SCREEN}, 0, 0, FLAGS, "mode" }, + { "softlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SOFTLIGHT}, 0, 0, FLAGS, "mode" }, + { "subtract", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SUBTRACT}, 0, 0, FLAGS, "mode" }, + { "vividlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_VIVIDLIGHT}, 0, 0, FLAGS, "mode" }, + { "xor", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_XOR}, 0, 0, FLAGS, "mode" }, + { "c0_expr", "set color component #0 expression", OFFSET(params[0].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { "c1_expr", "set color component #1 expression", OFFSET(params[1].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { "c2_expr", "set color component #2 expression", OFFSET(params[2].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { "c3_expr", "set color component #3 expression", OFFSET(params[3].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { "all_expr", "set expression for all color components", OFFSET(all_expr), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { "c0_opacity", "set color component #0 opacity", OFFSET(params[0].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS }, + { "c1_opacity", "set color component #1 opacity", OFFSET(params[1].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS }, + { "c2_opacity", "set color component #2 opacity", OFFSET(params[2].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS }, + { "c3_opacity", "set color component #3 opacity", OFFSET(params[3].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS }, + { "all_opacity", "set opacity for all color components", OFFSET(all_opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS }, { NULL } }; @@ -783,13 +780,45 @@ void ff_blend_init(FilterParams *param, int depth) ff_blend_init_x86(param, depth); } +static int config_params(AVFilterContext *ctx) +{ + BlendContext *s = ctx->priv; + int ret; + + for (int plane = 0; plane < FF_ARRAY_ELEMS(s->params); plane++) { + FilterParams *param = &s->params[plane]; + + if (s->all_mode >= 0) + param->mode = s->all_mode; + if (s->all_opacity < 1) + param->opacity = s->all_opacity; + + ff_blend_init(param, s->depth); + + if (s->all_expr && !param->expr_str) { + param->expr_str = av_strdup(s->all_expr); + if (!param->expr_str) + return AVERROR(ENOMEM); + } + if (param->expr_str) { + ret = av_expr_parse(¶m->e, param->expr_str, var_names, + NULL, NULL, NULL, NULL, 0, ctx); + if (ret < 0) + return ret; + param->blend = s->depth > 8 ? s->depth > 16 ? blend_expr_32bit : blend_expr_16bit : blend_expr_8bit; + } + } + + return 0; +} + static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; AVFilterLink *toplink = ctx->inputs[TOP]; BlendContext *s = ctx->priv; const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(toplink->format); - int ret, plane; + int ret; if (!s->tblend) { AVFilterLink *bottomlink = ctx->inputs[BOTTOM]; @@ -824,29 +853,9 @@ static int config_output(AVFilterLink *outlink) if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0) return ret; - for (plane = 0; plane < FF_ARRAY_ELEMS(s->params); plane++) { - FilterParams *param = &s->params[plane]; - - if (s->all_mode >= 0) - param->mode = s->all_mode; - if (s->all_opacity < 1) - param->opacity = s->all_opacity; - - ff_blend_init(param, s->depth); - - if (s->all_expr && !param->expr_str) { - param->expr_str = av_strdup(s->all_expr); - if (!param->expr_str) - return AVERROR(ENOMEM); - } - if (param->expr_str) { - ret = av_expr_parse(¶m->e, param->expr_str, var_names, - NULL, NULL, NULL, NULL, 0, ctx); - if (ret < 0) - return ret; - param->blend = s->depth > 8 ? s->depth > 16 ? blend_expr_32bit : blend_expr_16bit : blend_expr_8bit; - } - } + ret = config_params(ctx); + if (ret < 0) + return ret; if (s->tblend) return 0; @@ -857,6 +866,18 @@ static int config_output(AVFilterLink *outlink) return ret; } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_params(ctx); +} + #if CONFIG_BLEND_FILTER static int activate(AVFilterContext *ctx) @@ -898,6 +919,7 @@ AVFilter ff_vf_blend = { .outputs = blend_outputs, .priv_class = &blend_class, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif @@ -925,11 +947,7 @@ static int tblend_filter_frame(AVFilterLink *inlink, AVFrame *frame) return 0; } -static const AVOption tblend_options[] = { - COMMON_OPTIONS, - { NULL } -}; - +#define tblend_options blend_options AVFILTER_DEFINE_CLASS(tblend); static const AVFilterPad tblend_inputs[] = { @@ -961,6 +979,7 @@ AVFilter ff_vf_tblend = { .inputs = tblend_inputs, .outputs = tblend_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif diff --git a/libavfilter/vf_bm3d.c b/libavfilter/vf_bm3d.c index e5d2b8bc6..18d13b25f 100644 --- a/libavfilter/vf_bm3d.c +++ b/libavfilter/vf_bm3d.c @@ -942,27 +942,19 @@ static av_cold int init(AVFilterContext *ctx) } pad.type = AVMEDIA_TYPE_VIDEO; - pad.name = av_strdup("source"); + pad.name = "source"; pad.config_props = config_input; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) return ret; - } if (s->ref) { pad.type = AVMEDIA_TYPE_VIDEO; - pad.name = av_strdup("reference"); + pad.name = "reference"; pad.config_props = NULL; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) return ret; - } } return 0; @@ -1027,9 +1019,6 @@ static av_cold void uninit(AVFilterContext *ctx) BM3DContext *s = ctx->priv; int i; - for (i = 0; i < ctx->nb_inputs; i++) - av_freep(&ctx->input_pads[i].name); - if (s->ref) ff_framesync_uninit(&s->fs); diff --git a/libavfilter/vf_chromanr.c b/libavfilter/vf_chromanr.c new file mode 100644 index 000000000..06325309e --- /dev/null +++ b/libavfilter/vf_chromanr.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2020 Paul B Mahol + * + * 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/avstring.h" +#include "libavutil/imgutils.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" + +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct ChromaNRContext { + const AVClass *class; + + float threshold; + float threshold_y; + float threshold_u; + float threshold_v; + int thres; + int thres_y; + int thres_u; + int thres_v; + int sizew; + int sizeh; + int stepw; + int steph; + int depth; + int chroma_w; + int chroma_h; + int nb_planes; + int linesize[4]; + int planeheight[4]; + int planewidth[4]; + + AVFrame *out; + int (*filter_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); +} ChromaNRContext; + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9, + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, + AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA444P12, + AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +#define FILTER_FUNC(name, type) \ +static int filter_slice##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ +{ \ + ChromaNRContext *s = ctx->priv; \ + AVFrame *in = arg; \ + AVFrame *out = s->out; \ + const int in_ylinesize = in->linesize[0]; \ + const int in_ulinesize = in->linesize[1]; \ + const int in_vlinesize = in->linesize[2]; \ + const int out_ulinesize = out->linesize[1]; \ + const int out_vlinesize = out->linesize[2]; \ + const int chroma_w = s->chroma_w; \ + const int chroma_h = s->chroma_h; \ + const int stepw = s->stepw; \ + const int steph = s->steph; \ + const int sizew = s->sizew; \ + const int sizeh = s->sizeh; \ + const int thres = s->thres; \ + const int thres_y = s->thres_y; \ + const int thres_u = s->thres_u; \ + const int thres_v = s->thres_v; \ + const int h = s->planeheight[1]; \ + const int w = s->planewidth[1]; \ + const int slice_start = (h * jobnr) / nb_jobs; \ + const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + type *out_uptr = (type *)(out->data[1] + slice_start * out_ulinesize); \ + type *out_vptr = (type *)(out->data[2] + slice_start * out_vlinesize); \ + \ + { \ + const int h = s->planeheight[0]; \ + const int slice_start = (h * jobnr) / nb_jobs; \ + const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + \ + av_image_copy_plane(out->data[0] + slice_start * out->linesize[0], \ + out->linesize[0], \ + in->data[0] + slice_start * in->linesize[0], \ + in->linesize[0], \ + s->linesize[0], slice_end - slice_start); \ + \ + if (s->nb_planes == 4) { \ + av_image_copy_plane(out->data[3] + slice_start * out->linesize[3], \ + out->linesize[3], \ + in->data[3] + slice_start * in->linesize[3], \ + in->linesize[3], \ + s->linesize[3], slice_end - slice_start); \ + } \ + } \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + const type *in_yptr = (const type *)(in->data[0] + y * chroma_h * in_ylinesize); \ + const type *in_uptr = (const type *)(in->data[1] + y * in_ulinesize); \ + const type *in_vptr = (const type *)(in->data[2] + y * in_vlinesize); \ + \ + for (int x = 0; x < w; x++) { \ + const int cy = in_yptr[x * chroma_w]; \ + const int cu = in_uptr[x]; \ + const int cv = in_vptr[x]; \ + int su = cu; \ + int sv = cv; \ + int cn = 1; \ + \ + for (int yy = FFMAX(0, y - sizeh); yy < FFMIN(y + sizeh, h); yy += steph) { \ + const type *in_yptr = (const type *)(in->data[0] + yy * chroma_h * in_ylinesize); \ + const type *in_uptr = (const type *)(in->data[1] + yy * in_ulinesize); \ + const type *in_vptr = (const type *)(in->data[2] + yy * in_vlinesize); \ + \ + for (int xx = FFMAX(0, x - sizew); xx < FFMIN(x + sizew, w); xx += stepw) { \ + const int Y = in_yptr[xx * chroma_w]; \ + const int U = in_uptr[xx]; \ + const int V = in_vptr[xx]; \ + \ + if (FFABS(cu - U) + FFABS(cv - V) + FFABS(cy - Y) < thres && \ + FFABS(cu - U) < thres_u && FFABS(cv - V) < thres_v && \ + FFABS(cy - Y) < thres_y && \ + xx != x && yy != y) { \ + su += U; \ + sv += V; \ + cn++; \ + } \ + } \ + } \ + \ + out_uptr[x] = su / cn; \ + out_vptr[x] = sv / cn; \ + } \ + \ + out_uptr += out_ulinesize / sizeof(type); \ + out_vptr += out_vlinesize / sizeof(type); \ + } \ + \ + return 0; \ +} + +FILTER_FUNC(8, uint8_t) +FILTER_FUNC(16, uint16_t) + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + AVFilterLink *outlink = ctx->outputs[0]; + ChromaNRContext *s = ctx->priv; + AVFrame *out; + + s->thres = s->threshold * (1 << (s->depth - 8)); + s->thres_y = s->threshold_y * (1 << (s->depth - 8)); + s->thres_u = s->threshold_u * (1 << (s->depth - 8)); + s->thres_v = s->threshold_v * (1 << (s->depth - 8)); + + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + + av_frame_copy_props(out, in); + s->out = out; + ctx->internal->execute(ctx, s->filter_slice, in, NULL, + FFMIN3(s->planeheight[1], + s->planeheight[2], + ff_filter_get_nb_threads(ctx))); + + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ChromaNRContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int ret; + + s->nb_planes = desc->nb_components; + s->depth = desc->comp[0].depth; + s->filter_slice = s->depth <= 8 ? filter_slice8 : filter_slice16; + s->chroma_w = 1 << desc->log2_chroma_w; + s->chroma_h = 1 << desc->log2_chroma_h; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + + if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) + return ret; + + return 0; +} + +#define OFFSET(x) offsetof(ChromaNRContext, x) +#define VF AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption chromanr_options[] = { + { "thres", "set y+u+v threshold", OFFSET(threshold), AV_OPT_TYPE_FLOAT, {.dbl=30}, 1, 200, VF }, + { "sizew", "set horizontal size", OFFSET(sizew), AV_OPT_TYPE_INT, {.i64=5}, 1, 100, VF }, + { "sizeh", "set vertical size", OFFSET(sizeh), AV_OPT_TYPE_INT, {.i64=5}, 1, 100, VF }, + { "stepw", "set horizontal step", OFFSET(stepw), AV_OPT_TYPE_INT, {.i64=1}, 1, 50, VF }, + { "steph", "set vertical step", OFFSET(steph), AV_OPT_TYPE_INT, {.i64=1}, 1, 50, VF }, + { "threy", "set y threshold", OFFSET(threshold_y), AV_OPT_TYPE_FLOAT, {.dbl=200},1, 200, VF }, + { "threu", "set u threshold", OFFSET(threshold_u), AV_OPT_TYPE_FLOAT, {.dbl=200},1, 200, VF }, + { "threv", "set v threshold", OFFSET(threshold_v), AV_OPT_TYPE_FLOAT, {.dbl=200},1, 200, VF }, + { NULL } +}; + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(chromanr); + +AVFilter ff_vf_chromanr = { + .name = "chromanr", + .description = NULL_IF_CONFIG_SMALL("Reduce chrominance noise."), + .priv_size = sizeof(ChromaNRContext), + .priv_class = &chromanr_class, + .query_formats = query_formats, + .outputs = outputs, + .inputs = inputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; diff --git a/libavfilter/vf_ciescope.c b/libavfilter/vf_ciescope.c index d5a2c8c0a..719e66ad0 100644 --- a/libavfilter/vf_ciescope.c +++ b/libavfilter/vf_ciescope.c @@ -139,10 +139,10 @@ static int query_formats(AVFilterContext *ctx) { int ret; - if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0) return ret; - if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c index 331bfba77..28ac2df72 100644 --- a/libavfilter/vf_codecview.c +++ b/libavfilter/vf_codecview.c @@ -33,6 +33,7 @@ #include "libavutil/motion_vector.h" #include "libavutil/opt.h" #include "avfilter.h" +#include "qp_table.h" #include "internal.h" #define MV_P_FOR (1<<0) @@ -140,7 +141,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, } buf += sx + sy * stride; ex -= sx; - f = ((ey - sy) << 16) / ex; + f = ((ey - sy) * (1 << 16)) / ex; for (x = 0; x <= ex; x++) { y = (x * f) >> 16; fr = (x * f) & 0xFFFF; @@ -155,7 +156,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, buf += sx + sy * stride; ey -= sy; if (ey) - f = ((ex - sx) << 16) / ey; + f = ((ex - sx) * (1 << 16)) / ey; else f = 0; for(y= 0; y <= ey; y++){ @@ -198,8 +199,8 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int length = sqrt((rx * rx + ry * ry) << 8); // FIXME subpixel accuracy - rx = ROUNDED_DIV(rx * 3 << 4, length); - ry = ROUNDED_DIV(ry * 3 << 4, length); + rx = ROUNDED_DIV(rx * (3 << 4), length); + ry = ROUNDED_DIV(ry * (3 << 4), length); if (tail) { rx = -rx; @@ -219,8 +220,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) AVFilterLink *outlink = ctx->outputs[0]; if (s->qp) { - int qstride, qp_type; - int8_t *qp_table = av_frame_get_qp_table(frame, &qstride, &qp_type); + int qstride, qp_type, ret; + int8_t *qp_table; + + ret = ff_qp_table_extract(frame, &qp_table, &qstride, NULL, &qp_type); + if (ret < 0) { + av_frame_free(&frame); + return ret; + } if (qp_table) { int x, y; @@ -240,6 +247,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) pv += lzv; } } + av_freep(&qp_table); } if (s->mv || s->mv_type) { diff --git a/libavfilter/vf_colorbalance.c b/libavfilter/vf_colorbalance.c index 56f9d5c49..6dc1b2848 100644 --- a/libavfilter/vf_colorbalance.c +++ b/libavfilter/vf_colorbalance.c @@ -111,7 +111,7 @@ static float get_component(float v, float l, v += m; v += h; - return av_clipf(v + 0.5f, 0, 1); + return av_clipf(v, 0, 1); } static float hfun(float n, float h, float s, float l) @@ -188,9 +188,9 @@ static int color_balance8_p(AVFilterContext *ctx, void *arg, int jobnr, int nb_j if (s->preserve_lightness) preservel(&r, &g, &b, l); - dstr[j] = av_clip_uint8(r * max); - dstg[j] = av_clip_uint8(g * max); - dstb[j] = av_clip_uint8(b * max); + dstr[j] = av_clip_uint8(lrintf(r * max)); + dstg[j] = av_clip_uint8(lrintf(g * max)); + dstb[j] = av_clip_uint8(lrintf(b * max)); if (in != out && out->linesize[3]) dsta[j] = srca[j]; } @@ -242,9 +242,9 @@ static int color_balance16_p(AVFilterContext *ctx, void *arg, int jobnr, int nb_ if (s->preserve_lightness) preservel(&r, &g, &b, l); - dstr[j] = av_clip_uintp2_c(r * max, depth); - dstg[j] = av_clip_uintp2_c(g * max, depth); - dstb[j] = av_clip_uintp2_c(b * max, depth); + dstr[j] = av_clip_uintp2_c(lrintf(r * max), depth); + dstg[j] = av_clip_uintp2_c(lrintf(g * max), depth); + dstb[j] = av_clip_uintp2_c(lrintf(b * max), depth); if (in != out && out->linesize[3]) dsta[j] = srca[j]; } @@ -299,9 +299,9 @@ static int color_balance8(AVFilterContext *ctx, void *arg, int jobnr, int nb_job if (s->preserve_lightness) preservel(&r, &g, &b, l); - dst[j + roffset] = av_clip_uint8(r * max); - dst[j + goffset] = av_clip_uint8(g * max); - dst[j + boffset] = av_clip_uint8(b * max); + dst[j + roffset] = av_clip_uint8(lrintf(r * max)); + dst[j + goffset] = av_clip_uint8(lrintf(g * max)); + dst[j + boffset] = av_clip_uint8(lrintf(b * max)); if (in != out && step == 4) dst[j + aoffset] = src[j + aoffset]; } @@ -351,9 +351,9 @@ static int color_balance16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo if (s->preserve_lightness) preservel(&r, &g, &b, l); - dst[j + roffset] = av_clip_uintp2_c(r * max, depth); - dst[j + goffset] = av_clip_uintp2_c(g * max, depth); - dst[j + boffset] = av_clip_uintp2_c(b * max, depth); + dst[j + roffset] = av_clip_uintp2_c(lrintf(r * max), depth); + dst[j + goffset] = av_clip_uintp2_c(lrintf(g * max), depth); + dst[j + boffset] = av_clip_uintp2_c(lrintf(b * max), depth); if (in != out && step == 4) dst[j + aoffset] = src[j + aoffset]; } diff --git a/libavfilter/vf_colorchannelmixer.c b/libavfilter/vf_colorchannelmixer.c index 3bbe44d6e..9857a666f 100644 --- a/libavfilter/vf_colorchannelmixer.c +++ b/libavfilter/vf_colorchannelmixer.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" @@ -41,6 +43,8 @@ typedef struct ColorChannelMixerContext { double gr, gg, gb, ga; double br, bg, bb, ba; double ar, ag, ab, aa; + double sr, sg, sb; + double preserve_lightness; int *lut[4][4]; @@ -48,7 +52,7 @@ typedef struct ColorChannelMixerContext { uint8_t rgba_map[4]; - int (*filter_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); + int (*filter_slice[2])(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); } ColorChannelMixerContext; #define OFFSET(x) offsetof(ColorChannelMixerContext, x) @@ -71,6 +75,7 @@ static const AVOption colorchannelmixer_options[] = { { "ag", "set the green gain for the alpha channel", OFFSET(ag), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS }, { "ab", "set the blue gain for the alpha channel", OFFSET(ab), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS }, { "aa", "set the alpha gain for the alpha channel", OFFSET(aa), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -2, 2, FLAGS }, + { "pl", "preserve lightness", OFFSET(preserve_lightness), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 1, FLAGS }, { NULL } }; @@ -101,13 +106,29 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } +static float lerpf(float v0, float v1, float f) +{ + return v0 + (v1 - v0) * f; +} + +static void preservel(float *r, float *g, float *b, float lin, float lout) +{ + *r *= lout / lin; + *g *= lout / lin; + *b *= lout / lin; +} + static av_always_inline int filter_slice_rgba_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, - int have_alpha) + int have_alpha, int pl) { ColorChannelMixerContext *s = ctx->priv; ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; + const float l = s->preserve_lightness; + const float sr = s->sr; + const float sg = s->sg; + const float sb = s->sb; const int slice_start = (out->height * jobnr) / nb_jobs; const int slice_end = (out->height * (jobnr+1)) / nb_jobs; const uint8_t *srcg = in->data[0] + slice_start * in->linesize[0]; @@ -126,19 +147,42 @@ static av_always_inline int filter_slice_rgba_planar(AVFilterContext *ctx, void const uint8_t gin = srcg[j]; const uint8_t bin = srcb[j]; const uint8_t ain = have_alpha ? srca[j] : 0; + int rout, gout, bout; + float lin; + + if (pl) + lin = FFMAX3(rin, gin, bin) + FFMIN3(rin, gin, bin); + + rout = s->lut[R][R][rin] + + s->lut[R][G][gin] + + s->lut[R][B][bin] + + (have_alpha == 1 ? s->lut[R][A][ain] : 0); + gout = s->lut[G][R][rin] + + s->lut[G][G][gin] + + s->lut[G][B][bin] + + (have_alpha == 1 ? s->lut[G][A][ain] : 0); + bout = s->lut[B][R][rin] + + s->lut[B][G][gin] + + s->lut[B][B][bin] + + (have_alpha == 1 ? s->lut[B][A][ain] : 0); + + if (pl) { + float frout = rout / sr; + float fgout = gout / sg; + float fbout = bout / sb; + float lout = FFMAX3(frout, fgout, fbout) + FFMIN3(frout, fgout, fbout); + + preservel(&frout, &fgout, &fbout, lin, lout); + + rout = lrintf(lerpf(rout, frout, l)); + gout = lrintf(lerpf(gout, fgout, l)); + bout = lrintf(lerpf(bout, fbout, l)); + } + + dstr[j] = av_clip_uint8(rout); + dstg[j] = av_clip_uint8(gout); + dstb[j] = av_clip_uint8(bout); - dstr[j] = av_clip_uint8(s->lut[R][R][rin] + - s->lut[R][G][gin] + - s->lut[R][B][bin] + - (have_alpha == 1 ? s->lut[R][A][ain] : 0)); - dstg[j] = av_clip_uint8(s->lut[G][R][rin] + - s->lut[G][G][gin] + - s->lut[G][B][bin] + - (have_alpha == 1 ? s->lut[G][A][ain] : 0)); - dstb[j] = av_clip_uint8(s->lut[B][R][rin] + - s->lut[B][G][gin] + - s->lut[B][B][bin] + - (have_alpha == 1 ? s->lut[B][A][ain] : 0)); if (have_alpha == 1) { dsta[j] = av_clip_uint8(s->lut[A][R][rin] + s->lut[A][G][gin] + @@ -161,12 +205,16 @@ static av_always_inline int filter_slice_rgba_planar(AVFilterContext *ctx, void } static av_always_inline int filter_slice_rgba16_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, - int have_alpha, int depth) + int have_alpha, int depth, int pl) { ColorChannelMixerContext *s = ctx->priv; ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; + const float l = s->preserve_lightness; + const float sr = s->sr; + const float sg = s->sg; + const float sb = s->sb; const int slice_start = (out->height * jobnr) / nb_jobs; const int slice_end = (out->height * (jobnr+1)) / nb_jobs; const uint16_t *srcg = (const uint16_t *)(in->data[0] + slice_start * in->linesize[0]); @@ -185,19 +233,42 @@ static av_always_inline int filter_slice_rgba16_planar(AVFilterContext *ctx, voi const uint16_t gin = srcg[j]; const uint16_t bin = srcb[j]; const uint16_t ain = have_alpha ? srca[j] : 0; + int rout, gout, bout; + float lin; + + if (pl) + lin = FFMAX3(rin, gin, bin) + FFMIN3(rin, gin, bin); + + rout = s->lut[R][R][rin] + + s->lut[R][G][gin] + + s->lut[R][B][bin] + + (have_alpha == 1 ? s->lut[R][A][ain] : 0); + gout = s->lut[G][R][rin] + + s->lut[G][G][gin] + + s->lut[G][B][bin] + + (have_alpha == 1 ? s->lut[G][A][ain] : 0); + bout = s->lut[B][R][rin] + + s->lut[B][G][gin] + + s->lut[B][B][bin] + + (have_alpha == 1 ? s->lut[B][A][ain] : 0); + + if (pl) { + float frout = rout / sr; + float fgout = gout / sg; + float fbout = bout / sb; + float lout = FFMAX3(frout, fgout, fbout) + FFMIN3(frout, fgout, fbout); + + preservel(&frout, &fgout, &fbout, lin, lout); + + rout = lrintf(lerpf(rout, frout, l)); + gout = lrintf(lerpf(gout, fgout, l)); + bout = lrintf(lerpf(bout, fbout, l)); + } + + dstr[j] = av_clip_uintp2(rout, depth); + dstg[j] = av_clip_uintp2(gout, depth); + dstb[j] = av_clip_uintp2(bout, depth); - dstr[j] = av_clip_uintp2(s->lut[R][R][rin] + - s->lut[R][G][gin] + - s->lut[R][B][bin] + - (have_alpha == 1 ? s->lut[R][A][ain] : 0), depth); - dstg[j] = av_clip_uintp2(s->lut[G][R][rin] + - s->lut[G][G][gin] + - s->lut[G][B][bin] + - (have_alpha == 1 ? s->lut[G][A][ain] : 0), depth); - dstb[j] = av_clip_uintp2(s->lut[B][R][rin] + - s->lut[B][G][gin] + - s->lut[B][B][bin] + - (have_alpha == 1 ? s->lut[B][A][ain] : 0), depth); if (have_alpha == 1) { dsta[j] = av_clip_uintp2(s->lut[A][R][rin] + s->lut[A][G][gin] + @@ -221,61 +292,115 @@ static av_always_inline int filter_slice_rgba16_planar(AVFilterContext *ctx, voi static int filter_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba_planar(ctx, arg, jobnr, nb_jobs, 0); + return filter_slice_rgba_planar(ctx, arg, jobnr, nb_jobs, 0, 0); } static int filter_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba_planar(ctx, arg, jobnr, nb_jobs, 1); + return filter_slice_rgba_planar(ctx, arg, jobnr, nb_jobs, 1, 0); +} + +static int filter_slice_gbrp_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba_planar(ctx, arg, jobnr, nb_jobs, 0, 1); +} + +static int filter_slice_gbrap_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba_planar(ctx, arg, jobnr, nb_jobs, 1, 1); } static int filter_slice_gbrp9(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 9); + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 9, 0); } static int filter_slice_gbrp10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 10); + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 10, 0); } static int filter_slice_gbrap10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 1, 10); + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 1, 10, 0); } static int filter_slice_gbrp12(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 12); + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 12, 0); } static int filter_slice_gbrap12(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 1, 12); + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 1, 12, 0); } static int filter_slice_gbrp14(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 14); + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 14, 0); } static int filter_slice_gbrp16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 16); + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 16, 0); } static int filter_slice_gbrap16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 1, 16); + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 1, 16, 0); +} + +static int filter_slice_gbrp9_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 9, 1); +} + +static int filter_slice_gbrp10_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 10, 1); +} + +static int filter_slice_gbrap10_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 1, 10, 1); +} + +static int filter_slice_gbrp12_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 12, 1); +} + +static int filter_slice_gbrap12_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 1, 12, 1); +} + +static int filter_slice_gbrp14_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 14, 1); +} + +static int filter_slice_gbrp16_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 0, 16, 1); +} + +static int filter_slice_gbrap16_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_planar(ctx, arg, jobnr, nb_jobs, 1, 16, 1); } static av_always_inline int filter_slice_rgba_packed(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, - int have_alpha, int step) + int have_alpha, int step, int pl) { ColorChannelMixerContext *s = ctx->priv; ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; + const float l = s->preserve_lightness; + const float sr = s->sr; + const float sg = s->sg; + const float sb = s->sb; const int slice_start = (out->height * jobnr) / nb_jobs; const int slice_end = (out->height * (jobnr+1)) / nb_jobs; const uint8_t roffset = s->rgba_map[R]; @@ -295,19 +420,42 @@ static av_always_inline int filter_slice_rgba_packed(AVFilterContext *ctx, void const uint8_t gin = src[j + goffset]; const uint8_t bin = src[j + boffset]; const uint8_t ain = src[j + aoffset]; + int rout, gout, bout; + float lin; + + if (pl) + lin = FFMAX3(rin, gin, bin) + FFMIN3(rin, gin, bin); + + rout = s->lut[R][R][rin] + + s->lut[R][G][gin] + + s->lut[R][B][bin] + + (have_alpha == 1 ? s->lut[R][A][ain] : 0); + gout = s->lut[G][R][rin] + + s->lut[G][G][gin] + + s->lut[G][B][bin] + + (have_alpha == 1 ? s->lut[G][A][ain] : 0); + bout = s->lut[B][R][rin] + + s->lut[B][G][gin] + + s->lut[B][B][bin] + + (have_alpha == 1 ? s->lut[B][A][ain] : 0); + + if (pl) { + float frout = rout / sr; + float fgout = gout / sg; + float fbout = bout / sb; + float lout = FFMAX3(frout, fgout, fbout) + FFMIN3(frout, fgout, fbout); + + preservel(&frout, &fgout, &fbout, lin, lout); + + rout = lrintf(lerpf(rout, frout, l)); + gout = lrintf(lerpf(gout, fgout, l)); + bout = lrintf(lerpf(bout, fbout, l)); + } + + dst[j + roffset] = av_clip_uint8(rout); + dst[j + goffset] = av_clip_uint8(gout); + dst[j + boffset] = av_clip_uint8(bout); - dst[j + roffset] = av_clip_uint8(s->lut[R][R][rin] + - s->lut[R][G][gin] + - s->lut[R][B][bin] + - (have_alpha == 1 ? s->lut[R][A][ain] : 0)); - dst[j + goffset] = av_clip_uint8(s->lut[G][R][rin] + - s->lut[G][G][gin] + - s->lut[G][B][bin] + - (have_alpha == 1 ? s->lut[G][A][ain] : 0)); - dst[j + boffset] = av_clip_uint8(s->lut[B][R][rin] + - s->lut[B][G][gin] + - s->lut[B][B][bin] + - (have_alpha == 1 ? s->lut[B][A][ain] : 0)); if (have_alpha == 1) { dst[j + aoffset] = av_clip_uint8(s->lut[A][R][rin] + s->lut[A][G][gin] + @@ -325,12 +473,16 @@ static av_always_inline int filter_slice_rgba_packed(AVFilterContext *ctx, void } static av_always_inline int filter_slice_rgba16_packed(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, - int have_alpha, int step) + int have_alpha, int step, int pl) { ColorChannelMixerContext *s = ctx->priv; ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; + const float l = s->preserve_lightness; + const float sr = s->sr; + const float sg = s->sg; + const float sb = s->sb; const int slice_start = (out->height * jobnr) / nb_jobs; const int slice_end = (out->height * (jobnr+1)) / nb_jobs; const uint8_t roffset = s->rgba_map[R]; @@ -350,19 +502,42 @@ static av_always_inline int filter_slice_rgba16_packed(AVFilterContext *ctx, voi const uint16_t gin = src[j + goffset]; const uint16_t bin = src[j + boffset]; const uint16_t ain = src[j + aoffset]; + int rout, gout, bout; + float lin; + + if (pl) + lin = FFMAX3(rin, gin, bin) + FFMIN3(rin, gin, bin); + + rout = s->lut[R][R][rin] + + s->lut[R][G][gin] + + s->lut[R][B][bin] + + (have_alpha == 1 ? s->lut[R][A][ain] : 0); + gout = s->lut[G][R][rin] + + s->lut[G][G][gin] + + s->lut[G][B][bin] + + (have_alpha == 1 ? s->lut[G][A][ain] : 0); + bout = s->lut[B][R][rin] + + s->lut[B][G][gin] + + s->lut[B][B][bin] + + (have_alpha == 1 ? s->lut[B][A][ain] : 0); + + if (pl) { + float frout = rout / sr; + float fgout = gout / sg; + float fbout = bout / sb; + float lout = FFMAX3(frout, fgout, fbout) + FFMIN3(frout, fgout, fbout); + + preservel(&frout, &fgout, &fbout, lin, lout); + + rout = lrintf(lerpf(rout, frout, l)); + gout = lrintf(lerpf(gout, fgout, l)); + bout = lrintf(lerpf(bout, fbout, l)); + } + + dst[j + roffset] = av_clip_uint16(rout); + dst[j + goffset] = av_clip_uint16(gout); + dst[j + boffset] = av_clip_uint16(bout); - dst[j + roffset] = av_clip_uint16(s->lut[R][R][rin] + - s->lut[R][G][gin] + - s->lut[R][B][bin] + - (have_alpha == 1 ? s->lut[R][A][ain] : 0)); - dst[j + goffset] = av_clip_uint16(s->lut[G][R][rin] + - s->lut[G][G][gin] + - s->lut[G][B][bin] + - (have_alpha == 1 ? s->lut[G][A][ain] : 0)); - dst[j + boffset] = av_clip_uint16(s->lut[B][R][rin] + - s->lut[B][G][gin] + - s->lut[B][B][bin] + - (have_alpha == 1 ? s->lut[B][A][ain] : 0)); if (have_alpha == 1) { dst[j + aoffset] = av_clip_uint16(s->lut[A][R][rin] + s->lut[A][G][gin] + @@ -380,27 +555,52 @@ static av_always_inline int filter_slice_rgba16_packed(AVFilterContext *ctx, voi static int filter_slice_rgba64(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_packed(ctx, arg, jobnr, nb_jobs, 1, 4); + return filter_slice_rgba16_packed(ctx, arg, jobnr, nb_jobs, 1, 4, 0); } static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba16_packed(ctx, arg, jobnr, nb_jobs, 0, 3); + return filter_slice_rgba16_packed(ctx, arg, jobnr, nb_jobs, 0, 3, 0); +} + +static int filter_slice_rgba64_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_packed(ctx, arg, jobnr, nb_jobs, 1, 4, 1); +} + +static int filter_slice_rgb48_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba16_packed(ctx, arg, jobnr, nb_jobs, 0, 3, 1); } static int filter_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, 1, 4); + return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, 1, 4, 0); } static int filter_slice_rgb24(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, 0, 3); + return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, 0, 3, 0); } static int filter_slice_rgb0(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, -1, 4); + return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, -1, 4, 0); +} + +static int filter_slice_rgba_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, 1, 4, 1); +} + +static int filter_slice_rgb24_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, 0, 3, 1); +} + +static int filter_slice_rgb0_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, -1, 4, 1); } static int config_output(AVFilterLink *outlink) @@ -424,6 +624,19 @@ static int config_output(AVFilterLink *outlink) s->lut[i][j] = buffer; } + s->sr = s->rr + s->rg + s->rb + s->ra; + s->sg = s->gr + s->gg + s->gb + s->ga; + s->sb = s->br + s->bg + s->bb + s->ba; + + if (fabs(s->sr) <= DBL_EPSILON) + s->sr = 1.; + + if (fabs(s->sg) <= DBL_EPSILON) + s->sg = 1.; + + if (fabs(s->sb) <= DBL_EPSILON) + s->sb = 1.; + for (i = 0; i < size; i++) { s->lut[R][R][i] = lrint(i * s->rr); s->lut[R][G][i] = lrint(i * s->rg); @@ -449,57 +662,72 @@ static int config_output(AVFilterLink *outlink) switch (outlink->format) { case AV_PIX_FMT_BGR24: case AV_PIX_FMT_RGB24: - s->filter_slice = filter_slice_rgb24; + s->filter_slice[0] = filter_slice_rgb24; + s->filter_slice[1] = filter_slice_rgb24_pl; break; case AV_PIX_FMT_0BGR: case AV_PIX_FMT_0RGB: case AV_PIX_FMT_BGR0: case AV_PIX_FMT_RGB0: - s->filter_slice = filter_slice_rgb0; + s->filter_slice[0] = filter_slice_rgb0; + s->filter_slice[1] = filter_slice_rgb0_pl; break; case AV_PIX_FMT_ABGR: case AV_PIX_FMT_ARGB: case AV_PIX_FMT_BGRA: case AV_PIX_FMT_RGBA: - s->filter_slice = filter_slice_rgba; + s->filter_slice[0] = filter_slice_rgba; + s->filter_slice[1] = filter_slice_rgba_pl; break; case AV_PIX_FMT_BGR48: case AV_PIX_FMT_RGB48: - s->filter_slice = filter_slice_rgb48; + s->filter_slice[0] = filter_slice_rgb48; + s->filter_slice[1] = filter_slice_rgb48_pl; break; case AV_PIX_FMT_BGRA64: case AV_PIX_FMT_RGBA64: - s->filter_slice = filter_slice_rgba64; + s->filter_slice[0] = filter_slice_rgba64; + s->filter_slice[1] = filter_slice_rgba64_pl; break; case AV_PIX_FMT_GBRP: - s->filter_slice = filter_slice_gbrp; + s->filter_slice[0] = filter_slice_gbrp; + s->filter_slice[1] = filter_slice_gbrp_pl; break; case AV_PIX_FMT_GBRAP: - s->filter_slice = filter_slice_gbrap; + s->filter_slice[0] = filter_slice_gbrap; + s->filter_slice[1] = filter_slice_gbrap_pl; break; case AV_PIX_FMT_GBRP9: - s->filter_slice = filter_slice_gbrp9; + s->filter_slice[0] = filter_slice_gbrp9; + s->filter_slice[1] = filter_slice_gbrp9_pl; break; case AV_PIX_FMT_GBRP10: - s->filter_slice = filter_slice_gbrp10; + s->filter_slice[0] = filter_slice_gbrp10; + s->filter_slice[1] = filter_slice_gbrp10_pl; break; case AV_PIX_FMT_GBRAP10: - s->filter_slice = filter_slice_gbrap10; + s->filter_slice[0] = filter_slice_gbrap10; + s->filter_slice[1] = filter_slice_gbrap10_pl; break; case AV_PIX_FMT_GBRP12: - s->filter_slice = filter_slice_gbrp12; + s->filter_slice[0] = filter_slice_gbrp12; + s->filter_slice[1] = filter_slice_gbrp12_pl; break; case AV_PIX_FMT_GBRAP12: - s->filter_slice = filter_slice_gbrap12; + s->filter_slice[0] = filter_slice_gbrap12; + s->filter_slice[1] = filter_slice_gbrap12_pl; break; case AV_PIX_FMT_GBRP14: - s->filter_slice = filter_slice_gbrp14; + s->filter_slice[0] = filter_slice_gbrp14; + s->filter_slice[1] = filter_slice_gbrp14_pl; break; case AV_PIX_FMT_GBRP16: - s->filter_slice = filter_slice_gbrp16; + s->filter_slice[0] = filter_slice_gbrp16; + s->filter_slice[1] = filter_slice_gbrp16_pl; break; case AV_PIX_FMT_GBRAP16: - s->filter_slice = filter_slice_gbrap16; + s->filter_slice[0] = filter_slice_gbrap16; + s->filter_slice[1] = filter_slice_gbrap16_pl; break; } @@ -511,6 +739,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterContext *ctx = inlink->dst; ColorChannelMixerContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; + const int pl = s->preserve_lightness > 0.; ThreadData td; AVFrame *out; @@ -527,7 +756,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) td.in = in; td.out = out; - ctx->internal->execute(ctx, s->filter_slice, &td, NULL, FFMIN(outlink->h, ff_filter_get_nb_threads(ctx))); + ctx->internal->execute(ctx, s->filter_slice[pl], &td, NULL, FFMIN(outlink->h, ff_filter_get_nb_threads(ctx))); if (in != out) av_frame_free(&in); diff --git a/libavfilter/vf_colorcontrast.c b/libavfilter/vf_colorcontrast.c new file mode 100644 index 000000000..7206c954b --- /dev/null +++ b/libavfilter/vf_colorcontrast.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/opt.h" +#include "libavutil/imgutils.h" +#include "avfilter.h" +#include "drawutils.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +#define R 0 +#define G 1 +#define B 2 + +typedef struct ColorContrastContext { + const AVClass *class; + + float rc, gm, by; + float rcw, gmw, byw; + float preserve; + + int step; + int depth; + uint8_t rgba_map[4]; + + int (*do_slice)(AVFilterContext *s, void *arg, + int jobnr, int nb_jobs); +} ColorContrastContext; + +static inline float lerpf(float v0, float v1, float f) +{ + return v0 + (v1 - v0) * f; +} + +#define PROCESS(max) \ + br = (b + r) * 0.5f; \ + gb = (g + b) * 0.5f; \ + rg = (r + g) * 0.5f; \ + \ + gd = g - br; \ + bd = b - rg; \ + rd = r - gb; \ + \ + g0 = g + gd * gm; \ + b0 = b - gd * gm; \ + r0 = r - gd * gm; \ + \ + g1 = g - bd * by; \ + b1 = b + bd * by; \ + r1 = r - bd * by; \ + \ + g2 = g - rd * rc; \ + b2 = b - rd * rc; \ + r2 = r + rd * rc; \ + \ + ng = av_clipf((g0 * gmw + g1 * byw + g2 * rcw) * scale, 0.f, max); \ + nb = av_clipf((b0 * gmw + b1 * byw + b2 * rcw) * scale, 0.f, max); \ + nr = av_clipf((r0 * gmw + r1 * byw + r2 * rcw) * scale, 0.f, max); \ + \ + li = FFMAX3(r, g, b) + FFMIN3(r, g, b); \ + lo = FFMAX3(nr, ng, nb) + FFMIN3(nr, ng, nb) + FLT_EPSILON; \ + lf = li / lo; \ + \ + r = nr * lf; \ + g = ng * lf; \ + b = nb * lf; \ + \ + nr = lerpf(nr, r, preserve); \ + ng = lerpf(ng, g, preserve); \ + nb = lerpf(nb, b, preserve); + +static int colorcontrast_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorContrastContext *s = ctx->priv; + AVFrame *frame = arg; + const int width = frame->width; + const int height = frame->height; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int glinesize = frame->linesize[0]; + const int blinesize = frame->linesize[1]; + const int rlinesize = frame->linesize[2]; + uint8_t *gptr = frame->data[0] + slice_start * glinesize; + uint8_t *bptr = frame->data[1] + slice_start * blinesize; + uint8_t *rptr = frame->data[2] + slice_start * rlinesize; + const float preserve = s->preserve; + const float gm = s->gm * 0.5f; + const float by = s->by * 0.5f; + const float rc = s->rc * 0.5f; + const float gmw = s->gmw; + const float byw = s->byw; + const float rcw = s->rcw; + const float sum = gmw + byw + rcw; + const float scale = 1.f / sum; + + for (int y = slice_start; y < slice_end && sum > FLT_EPSILON; y++) { + for (int x = 0; x < width; x++) { + float g = gptr[x]; + float b = bptr[x]; + float r = rptr[x]; + float g0, g1, g2; + float b0, b1, b2; + float r0, r1, r2; + float gd, bd, rd; + float gb, br, rg; + float nr, ng, nb; + float li, lo, lf; + + PROCESS(255.f); + + gptr[x] = av_clip_uint8(ng); + bptr[x] = av_clip_uint8(nb); + rptr[x] = av_clip_uint8(nr); + } + + gptr += glinesize; + bptr += blinesize; + rptr += rlinesize; + } + + return 0; +} + +static int colorcontrast_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorContrastContext *s = ctx->priv; + AVFrame *frame = arg; + const int depth = s->depth; + const float max = (1 << depth) - 1; + const int width = frame->width; + const int height = frame->height; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int glinesize = frame->linesize[0] / 2; + const int blinesize = frame->linesize[1] / 2; + const int rlinesize = frame->linesize[2] / 2; + uint16_t *gptr = (uint16_t *)frame->data[0] + slice_start * glinesize; + uint16_t *bptr = (uint16_t *)frame->data[1] + slice_start * blinesize; + uint16_t *rptr = (uint16_t *)frame->data[2] + slice_start * rlinesize; + const float preserve = s->preserve; + const float gm = s->gm * 0.5f; + const float by = s->by * 0.5f; + const float rc = s->rc * 0.5f; + const float gmw = s->gmw; + const float byw = s->byw; + const float rcw = s->rcw; + const float sum = gmw + byw + rcw; + const float scale = 1.f / sum; + + for (int y = slice_start; y < slice_end && sum > FLT_EPSILON; y++) { + for (int x = 0; x < width; x++) { + float g = gptr[x]; + float b = bptr[x]; + float r = rptr[x]; + float g0, g1, g2; + float b0, b1, b2; + float r0, r1, r2; + float gd, bd, rd; + float gb, br, rg; + float nr, ng, nb; + float li, lo, lf; + + PROCESS(max); + + gptr[x] = av_clip_uintp2_c(ng, depth); + bptr[x] = av_clip_uintp2_c(nb, depth); + rptr[x] = av_clip_uintp2_c(nr, depth); + } + + gptr += glinesize; + bptr += blinesize; + rptr += rlinesize; + } + + return 0; +} + +static int colorcontrast_slice8p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorContrastContext *s = ctx->priv; + AVFrame *frame = arg; + const int step = s->step; + const int width = frame->width; + const int height = frame->height; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int linesize = frame->linesize[0]; + const uint8_t roffset = s->rgba_map[R]; + const uint8_t goffset = s->rgba_map[G]; + const uint8_t boffset = s->rgba_map[B]; + uint8_t *ptr = frame->data[0] + slice_start * linesize; + const float preserve = s->preserve; + const float gm = s->gm * 0.5f; + const float by = s->by * 0.5f; + const float rc = s->rc * 0.5f; + const float gmw = s->gmw; + const float byw = s->byw; + const float rcw = s->rcw; + const float sum = gmw + byw + rcw; + const float scale = 1.f / sum; + + for (int y = slice_start; y < slice_end && sum > FLT_EPSILON; y++) { + for (int x = 0; x < width; x++) { + float g = ptr[x * step + goffset]; + float b = ptr[x * step + boffset]; + float r = ptr[x * step + roffset]; + float g0, g1, g2; + float b0, b1, b2; + float r0, r1, r2; + float gd, bd, rd; + float gb, br, rg; + float nr, ng, nb; + float li, lo, lf; + + PROCESS(255.f); + + ptr[x * step + goffset] = av_clip_uint8(ng); + ptr[x * step + boffset] = av_clip_uint8(nb); + ptr[x * step + roffset] = av_clip_uint8(nr); + } + + ptr += linesize; + } + + return 0; +} + +static int colorcontrast_slice16p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorContrastContext *s = ctx->priv; + AVFrame *frame = arg; + const int step = s->step; + const int depth = s->depth; + const float max = (1 << depth) - 1; + const int width = frame->width; + const int height = frame->height; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int linesize = frame->linesize[0] / 2; + const uint8_t roffset = s->rgba_map[R]; + const uint8_t goffset = s->rgba_map[G]; + const uint8_t boffset = s->rgba_map[B]; + uint16_t *ptr = (uint16_t *)frame->data[0] + slice_start * linesize; + const float preserve = s->preserve; + const float gm = s->gm * 0.5f; + const float by = s->by * 0.5f; + const float rc = s->rc * 0.5f; + const float gmw = s->gmw; + const float byw = s->byw; + const float rcw = s->rcw; + const float sum = gmw + byw + rcw; + const float scale = 1.f / sum; + + for (int y = slice_start; y < slice_end && sum > FLT_EPSILON; y++) { + for (int x = 0; x < width; x++) { + float g = ptr[x * step + goffset]; + float b = ptr[x * step + boffset]; + float r = ptr[x * step + roffset]; + float g0, g1, g2; + float b0, b1, b2; + float r0, r1, r2; + float gd, bd, rd; + float gb, br, rg; + float nr, ng, nb; + float li, lo, lf; + + PROCESS(max); + + ptr[x * step + goffset] = av_clip_uintp2_c(ng, depth); + ptr[x * step + boffset] = av_clip_uintp2_c(nb, depth); + ptr[x * step + roffset] = av_clip_uintp2_c(nr, depth); + } + + ptr += linesize; + } + + return 0; +} + +static int filter_frame(AVFilterLink *link, AVFrame *frame) +{ + AVFilterContext *ctx = link->dst; + ColorContrastContext *s = ctx->priv; + int res; + + if (res = ctx->internal->execute(ctx, s->do_slice, frame, NULL, + FFMIN(frame->height, ff_filter_get_nb_threads(ctx)))) + return res; + + return ff_filter_frame(ctx->outputs[0], frame); +} + +static av_cold int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_fmts[] = { + AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, + AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, + AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, + AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, + AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, + AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48, + AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *formats = NULL; + + formats = ff_make_format_list(pixel_fmts); + if (!formats) + return AVERROR(ENOMEM); + + return ff_set_common_formats(ctx, formats); +} + +static av_cold int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ColorContrastContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR; + + s->step = desc->nb_components; + if (inlink->format == AV_PIX_FMT_RGB0 || + inlink->format == AV_PIX_FMT_0RGB || + inlink->format == AV_PIX_FMT_BGR0 || + inlink->format == AV_PIX_FMT_0BGR) + s->step = 4; + + s->depth = desc->comp[0].depth; + s->do_slice = s->depth <= 8 ? colorcontrast_slice8 : colorcontrast_slice16; + if (!planar) + s->do_slice = s->depth <= 8 ? colorcontrast_slice8p : colorcontrast_slice16p; + + ff_fill_rgba_map(s->rgba_map, inlink->format); + + return 0; +} + +static const AVFilterPad colorcontrast_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .needs_writable = 1, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad colorcontrast_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +#define OFFSET(x) offsetof(ColorContrastContext, x) +#define VF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption colorcontrast_options[] = { + { "rc", "set the red-cyan contrast", OFFSET(rc), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF }, + { "gm", "set the green-magenta contrast", OFFSET(gm), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF }, + { "by", "set the blue-yellow contrast", OFFSET(by), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF }, + { "rcw", "set the red-cyan weight", OFFSET(rcw), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF }, + { "gmw", "set the green-magenta weight", OFFSET(gmw), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF }, + { "byw", "set the blue-yellow weight", OFFSET(byw), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF }, + { "pl", "set the amount of preserving lightness", OFFSET(preserve), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(colorcontrast); + +AVFilter ff_vf_colorcontrast = { + .name = "colorcontrast", + .description = NULL_IF_CONFIG_SMALL("Adjust color contrast between RGB components."), + .priv_size = sizeof(ColorContrastContext), + .priv_class = &colorcontrast_class, + .query_formats = query_formats, + .inputs = colorcontrast_inputs, + .outputs = colorcontrast_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; diff --git a/libavfilter/vf_colorcorrect.c b/libavfilter/vf_colorcorrect.c new file mode 100644 index 000000000..f998f02e3 --- /dev/null +++ b/libavfilter/vf_colorcorrect.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/opt.h" +#include "libavutil/imgutils.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct ColorCorrectContext { + const AVClass *class; + + float rl, bl; + float rh, bh; + float saturation; + + int depth; + + int (*do_slice)(AVFilterContext *s, void *arg, + int jobnr, int nb_jobs); +} ColorCorrectContext; + +#define PROCESS() \ + float y = yptr[x] * imax; \ + float u = uptr[x] * imax - .5f; \ + float v = vptr[x] * imax - .5f; \ + float ny, nu, nv; \ + \ + ny = y; \ + nu = saturation * (u + y * bd + bl); \ + nv = saturation * (v + y * rd + rl); + +static int colorcorrect_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorCorrectContext *s = ctx->priv; + AVFrame *frame = arg; + const int depth = s->depth; + const float max = (1 << depth) - 1; + const float imax = 1.f / max; + const int width = frame->width; + const int height = frame->height; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ylinesize = frame->linesize[0]; + const int ulinesize = frame->linesize[1]; + const int vlinesize = frame->linesize[2]; + uint8_t *yptr = frame->data[0] + slice_start * ylinesize; + uint8_t *uptr = frame->data[1] + slice_start * ulinesize; + uint8_t *vptr = frame->data[2] + slice_start * vlinesize; + const float saturation = s->saturation; + const float bl = s->bl; + const float rl = s->rl; + const float bd = s->bh - bl; + const float rd = s->rh - rl; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + PROCESS() + + yptr[x] = av_clip_uint8( ny * max); + uptr[x] = av_clip_uint8((nu + 0.5f) * max); + vptr[x] = av_clip_uint8((nv + 0.5f) * max); + } + + yptr += ylinesize; + uptr += ulinesize; + vptr += vlinesize; + } + + return 0; +} + +static int colorcorrect_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorCorrectContext *s = ctx->priv; + AVFrame *frame = arg; + const int depth = s->depth; + const float max = (1 << depth) - 1; + const float imax = 1.f / max; + const int width = frame->width; + const int height = frame->height; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ylinesize = frame->linesize[0] / 2; + const int ulinesize = frame->linesize[1] / 2; + const int vlinesize = frame->linesize[2] / 2; + uint16_t *yptr = (uint16_t *)frame->data[0] + slice_start * ylinesize; + uint16_t *uptr = (uint16_t *)frame->data[1] + slice_start * ulinesize; + uint16_t *vptr = (uint16_t *)frame->data[2] + slice_start * vlinesize; + const float saturation = s->saturation; + const float bl = s->bl; + const float rl = s->rl; + const float bd = s->bh - bl; + const float rd = s->rh - rl; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + PROCESS() + + yptr[x] = av_clip_uintp2_c( ny * max, depth); + uptr[x] = av_clip_uintp2_c((nu + 0.5f) * max, depth); + vptr[x] = av_clip_uintp2_c((nv + 0.5f) * max, depth); + } + + yptr += ylinesize; + uptr += ulinesize; + vptr += vlinesize; + } + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *frame) +{ + AVFilterContext *ctx = inlink->dst; + ColorCorrectContext *s = ctx->priv; + + ctx->internal->execute(ctx, s->do_slice, frame, NULL, + FFMIN(frame->height, ff_filter_get_nb_threads(ctx))); + + return ff_filter_frame(ctx->outputs[0], frame); +} + +static av_cold int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_fmts[] = { + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *formats = NULL; + + formats = ff_make_format_list(pixel_fmts); + if (!formats) + return AVERROR(ENOMEM); + + return ff_set_common_formats(ctx, formats); +} + +static av_cold int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ColorCorrectContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + + s->depth = desc->comp[0].depth; + s->do_slice = s->depth <= 8 ? colorcorrect_slice8 : colorcorrect_slice16; + + return 0; +} + +static const AVFilterPad colorcorrect_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .needs_writable = 1, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad colorcorrect_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +#define OFFSET(x) offsetof(ColorCorrectContext, x) +#define VF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption colorcorrect_options[] = { + { "rl", "set the red shadow spot", OFFSET(rl), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF }, + { "bl", "set the blue shadow spot", OFFSET(bl), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF }, + { "rh", "set the red highlight spot", OFFSET(rh), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF }, + { "bh", "set the blue highlight spot", OFFSET(bh), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF }, + { "saturation", "set the amount of saturation", OFFSET(saturation), AV_OPT_TYPE_FLOAT, {.dbl=1}, -3, 3, VF }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(colorcorrect); + +AVFilter ff_vf_colorcorrect = { + .name = "colorcorrect", + .description = NULL_IF_CONFIG_SMALL("Adjust color white balance selectively for blacks and whites."), + .priv_size = sizeof(ColorCorrectContext), + .priv_class = &colorcorrect_class, + .query_formats = query_formats, + .inputs = colorcorrect_inputs, + .outputs = colorcorrect_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; diff --git a/libavfilter/vf_colorize.c b/libavfilter/vf_colorize.c new file mode 100644 index 000000000..e9d348201 --- /dev/null +++ b/libavfilter/vf_colorize.c @@ -0,0 +1,306 @@ +/* + * 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/opt.h" +#include "libavutil/imgutils.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct ColorizeContext { + const AVClass *class; + + float hue; + float saturation; + float lightness; + float mix; + + int depth; + int c[3]; + int planewidth[4]; + int planeheight[4]; + + int (*do_plane_slice[2])(AVFilterContext *s, void *arg, + int jobnr, int nb_jobs); +} ColorizeContext; + +static inline float lerpf(float v0, float v1, float f) +{ + return v0 + (v1 - v0) * f; +} + +static int colorizey_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorizeContext *s = ctx->priv; + AVFrame *frame = arg; + const int width = s->planewidth[0]; + const int height = s->planeheight[0]; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ylinesize = frame->linesize[0]; + uint8_t *yptr = frame->data[0] + slice_start * ylinesize; + const int yv = s->c[0]; + const float mix = s->mix; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) + yptr[x] = lerpf(yv, yptr[x], mix); + + yptr += ylinesize; + } + + return 0; +} + +static int colorizey_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorizeContext *s = ctx->priv; + AVFrame *frame = arg; + const int width = s->planewidth[0]; + const int height = s->planeheight[0]; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ylinesize = frame->linesize[0] / 2; + uint16_t *yptr = (uint16_t *)frame->data[0] + slice_start * ylinesize; + const int yv = s->c[0]; + const float mix = s->mix; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) + yptr[x] = lerpf(yv, yptr[x], mix); + + yptr += ylinesize; + } + + return 0; +} + +static int colorize_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorizeContext *s = ctx->priv; + AVFrame *frame = arg; + const int width = s->planewidth[1]; + const int height = s->planeheight[1]; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ulinesize = frame->linesize[1]; + const int vlinesize = frame->linesize[2]; + uint8_t *uptr = frame->data[1] + slice_start * ulinesize; + uint8_t *vptr = frame->data[2] + slice_start * vlinesize; + const int u = s->c[1]; + const int v = s->c[2]; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + uptr[x] = u; + vptr[x] = v; + } + + uptr += ulinesize; + vptr += vlinesize; + } + + return 0; +} + +static int colorize_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorizeContext *s = ctx->priv; + AVFrame *frame = arg; + const int width = s->planewidth[1]; + const int height = s->planeheight[1]; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ulinesize = frame->linesize[1] / 2; + const int vlinesize = frame->linesize[2] / 2; + uint16_t *uptr = (uint16_t *)frame->data[1] + slice_start * ulinesize; + uint16_t *vptr = (uint16_t *)frame->data[2] + slice_start * vlinesize; + const int u = s->c[1]; + const int v = s->c[2]; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + uptr[x] = u; + vptr[x] = v; + } + + uptr += ulinesize; + vptr += vlinesize; + } + + return 0; +} + +static int do_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorizeContext *s = ctx->priv; + + s->do_plane_slice[0](ctx, arg, jobnr, nb_jobs); + s->do_plane_slice[1](ctx, arg, jobnr, nb_jobs); + + return 0; +} + +static float hue2rgb(float p, float q, float t) +{ + if (t < 0.f) t += 1.f; + if (t > 1.f) t -= 1.f; + if (t < 1.f/6.f) return p + (q - p) * 6.f * t; + if (t < 1.f/2.f) return q; + if (t < 2.f/3.f) return p + (q - p) * (2.f/3.f - t) * 6.f; + + return p; +} + +static void hsl2rgb(float h, float s, float l, float *r, float *g, float *b) +{ + h /= 360.f; + + if (s == 0.f) { + *r = *g = *b = l; + } else { + const float q = l < 0.5f ? l * (1.f + s) : l + s - l * s; + const float p = 2.f * l - q; + + *r = hue2rgb(p, q, h + 1.f / 3.f); + *g = hue2rgb(p, q, h); + *b = hue2rgb(p, q, h - 1.f / 3.f); + } +} + +static void rgb2yuv(float r, float g, float b, int *y, int *u, int *v, int depth) +{ + *y = ((0.21260*219.0/255.0) * r + (0.71520*219.0/255.0) * g + + (0.07220*219.0/255.0) * b) * ((1 << depth) - 1); + *u = (-(0.11457*224.0/255.0) * r - (0.38543*224.0/255.0) * g + + (0.50000*224.0/255.0) * b + 0.5) * ((1 << depth) - 1); + *v = ((0.50000*224.0/255.0) * r - (0.45415*224.0/255.0) * g - + (0.04585*224.0/255.0) * b + 0.5) * ((1 << depth) - 1); +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *frame) +{ + AVFilterContext *ctx = inlink->dst; + ColorizeContext *s = ctx->priv; + float c[3]; + + hsl2rgb(s->hue, s->saturation, s->lightness, &c[0], &c[1], &c[2]); + rgb2yuv(c[0], c[1], c[2], &s->c[0], &s->c[1], &s->c[2], s->depth); + + ctx->internal->execute(ctx, do_slice, frame, NULL, + FFMIN(s->planeheight[1], ff_filter_get_nb_threads(ctx))); + + return ff_filter_frame(ctx->outputs[0], frame); +} + +static av_cold int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_fmts[] = { + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *formats = NULL; + + formats = ff_make_format_list(pixel_fmts); + if (!formats) + return AVERROR(ENOMEM); + + return ff_set_common_formats(ctx, formats); +} + +static av_cold int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ColorizeContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int depth; + + s->depth = depth = desc->comp[0].depth; + + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + + s->do_plane_slice[0] = depth <= 8 ? colorizey_slice8 : colorizey_slice16; + s->do_plane_slice[1] = depth <= 8 ? colorize_slice8 : colorize_slice16; + + return 0; +} + +static const AVFilterPad colorize_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .needs_writable = 1, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad colorize_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +#define OFFSET(x) offsetof(ColorizeContext, x) +#define VF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption colorize_options[] = { + { "hue", "set the hue", OFFSET(hue), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 360, VF }, + { "saturation", "set the saturation", OFFSET(saturation), AV_OPT_TYPE_FLOAT, {.dbl=0.5},0, 1, VF }, + { "lightness", "set the lightness", OFFSET(lightness), AV_OPT_TYPE_FLOAT, {.dbl=0.5},0, 1, VF }, + { "mix", "set the mix of source lightness", OFFSET(mix), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, VF }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(colorize); + +AVFilter ff_vf_colorize = { + .name = "colorize", + .description = NULL_IF_CONFIG_SMALL("Overlay a solid color on the video stream."), + .priv_size = sizeof(ColorizeContext), + .priv_class = &colorize_class, + .query_formats = query_formats, + .inputs = colorize_inputs, + .outputs = colorize_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; diff --git a/libavfilter/vf_colorlevels.c b/libavfilter/vf_colorlevels.c index c03e288e4..9085e4097 100644 --- a/libavfilter/vf_colorlevels.c +++ b/libavfilter/vf_colorlevels.c @@ -40,11 +40,14 @@ typedef struct Range { typedef struct ColorLevelsContext { const AVClass *class; Range range[4]; + int nb_comp; int bpp; int step; uint8_t rgba_map[4]; int linesize; + + int (*colorlevels_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); } ColorLevelsContext; #define OFFSET(x) offsetof(ColorLevelsContext, x) @@ -90,6 +93,74 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } +typedef struct ThreadData { + const uint8_t *srcrow; + uint8_t *dstrow; + int dst_linesize; + int src_linesize; + + float coeff[4]; + + int h; + + int imin[4]; + int omin[4]; +} ThreadData; + +#define LOAD_COMMON \ + ColorLevelsContext *s = ctx->priv; \ + const ThreadData *td = arg; \ + const int process_h = td->h; \ + const int slice_start = (process_h * jobnr ) / nb_jobs; \ + const int slice_end = (process_h * (jobnr+1)) / nb_jobs; \ + const uint8_t *srcrow = td->srcrow; \ + uint8_t *dstrow = td->dstrow; \ + const int step = s->step; + +static int colorlevels_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + LOAD_COMMON + + for (int comp = 0; comp < s->nb_comp; comp++) { + const uint8_t offset = s->rgba_map[comp]; + const int imin = td->imin[comp]; + const int omin = td->omin[comp]; + const float coeff = td->coeff[comp]; + + for (int y = slice_start; y < slice_end; y++) { + const uint8_t *src = srcrow + y * td->src_linesize; + uint8_t *dst = dstrow + y * td->dst_linesize; + + for (int x = 0; x < s->linesize; x += step) + dst[x + offset] = av_clip_uint8((src[x + offset] - imin) * coeff + omin); + } + } + + return 0; +} + +static int colorlevels_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + LOAD_COMMON + + for (int comp = 0; comp < s->nb_comp; comp++) { + const uint8_t offset = s->rgba_map[comp]; + const int imin = td->imin[comp]; + const int omin = td->omin[comp]; + const float coeff = td->coeff[comp]; + + for (int y = slice_start; y < slice_end; y++) { + const uint16_t *src = (const uint16_t *)(srcrow + y * td->src_linesize); + uint16_t *dst = (uint16_t *)(dstrow + y * td->dst_linesize); + + for (int x = 0; x < s->linesize; x += step) + dst[x + offset] = av_clip_uint16((src[x + offset] - imin) * coeff + omin); + } + } + + return 0; +} + static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; @@ -98,71 +169,13 @@ static int config_input(AVFilterLink *inlink) s->nb_comp = desc->nb_components; s->bpp = desc->comp[0].depth >> 3; - s->step = (av_get_padded_bits_per_pixel(desc) >> 3) / s->bpp; + s->step = av_get_padded_bits_per_pixel(desc) >> (3 + (s->bpp == 2)); s->linesize = inlink->w * s->step; ff_fill_rgba_map(s->rgba_map, inlink->format); - return 0; -} - -struct thread_data { - const uint8_t *srcrow; - uint8_t *dstrow; - int dst_linesize; - int src_linesize; - - double coeff; - uint8_t offset; - - int h; - - int imin; - int omin; -}; - -#define LOAD_COMMON\ - ColorLevelsContext *s = ctx->priv;\ - const struct thread_data *td = arg;\ -\ - int process_h = td->h;\ - const int slice_start = (process_h * jobnr ) / nb_jobs;\ - const int slice_end = (process_h * (jobnr+1)) / nb_jobs;\ - int x, y;\ - const uint8_t *srcrow = td->srcrow;\ - uint8_t *dstrow = td->dstrow;\ - const int step = s->step;\ - const uint8_t offset = td->offset;\ -\ - int imin = td->imin;\ - int omin = td->omin;\ - double coeff = td->coeff;\ - -static int colorlevel_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - LOAD_COMMON - - for (y = slice_start; y < slice_end; y++) { - const uint8_t *src = srcrow + y * td->src_linesize; - uint8_t *dst = dstrow + y * td->dst_linesize; - - for (x = 0; x < s->linesize; x += step) - dst[x + offset] = av_clip_uint8((src[x + offset] - imin) * coeff + omin); - } - - return 0; -} - -static int colorlevel_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - LOAD_COMMON - - for (y = slice_start; y < slice_end; y++) { - const uint16_t *src = (const uint16_t *)(srcrow + y * td->src_linesize); - uint16_t *dst = (uint16_t *)(dstrow + y * td->dst_linesize); - - for (x = 0; x < s->linesize; x += step) - dst[x + offset] = av_clip_uint16((src[x + offset] - imin) * coeff + omin); - } + s->colorlevels_slice = colorlevels_slice_8; + if (s->bpp == 2) + s->colorlevels_slice = colorlevels_slice_16; return 0; } @@ -173,8 +186,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ColorLevelsContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; const int step = s->step; + ThreadData td; AVFrame *out; - int x, y, i; if (av_frame_is_writable(in)) { out = in; @@ -187,26 +200,30 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) av_frame_copy_props(out, in); } + td.h = inlink->h; + td.dst_linesize = out->linesize[0]; + td.src_linesize = in->linesize[0]; + td.srcrow = in->data[0]; + td.dstrow = out->data[0]; + switch (s->bpp) { case 1: - for (i = 0; i < s->nb_comp; i++) { + for (int i = 0; i < s->nb_comp; i++) { Range *r = &s->range[i]; const uint8_t offset = s->rgba_map[i]; const uint8_t *srcrow = in->data[0]; - uint8_t *dstrow = out->data[0]; int imin = lrint(r->in_min * UINT8_MAX); int imax = lrint(r->in_max * UINT8_MAX); int omin = lrint(r->out_min * UINT8_MAX); int omax = lrint(r->out_max * UINT8_MAX); - double coeff; - struct thread_data td; + float coeff; if (imin < 0) { imin = UINT8_MAX; - for (y = 0; y < inlink->h; y++) { + for (int y = 0; y < inlink->h; y++) { const uint8_t *src = srcrow; - for (x = 0; x < s->linesize; x += step) + for (int x = 0; x < s->linesize; x += step) imin = FFMIN(imin, src[x + offset]); srcrow += in->linesize[0]; } @@ -214,51 +231,39 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if (imax < 0) { srcrow = in->data[0]; imax = 0; - for (y = 0; y < inlink->h; y++) { + for (int y = 0; y < inlink->h; y++) { const uint8_t *src = srcrow; - for (x = 0; x < s->linesize; x += step) + for (int x = 0; x < s->linesize; x += step) imax = FFMAX(imax, src[x + offset]); srcrow += in->linesize[0]; } } - srcrow = in->data[0]; coeff = (omax - omin) / (double)(imax - imin); - td.srcrow = srcrow; - td.dstrow = dstrow; - td.dst_linesize = out->linesize[0]; - td.src_linesize = in->linesize[0]; - td.coeff = coeff; - td.offset = offset; - td.h = inlink->h; - td.imin = imin; - td.omin = omin; - - ctx->internal->execute(ctx, colorlevel_slice_8, &td, NULL, - FFMIN(inlink->h, ff_filter_get_nb_threads(ctx))); + td.coeff[i] = coeff; + td.imin[i] = imin; + td.omin[i] = omin; } break; case 2: - for (i = 0; i < s->nb_comp; i++) { + for (int i = 0; i < s->nb_comp; i++) { Range *r = &s->range[i]; const uint8_t offset = s->rgba_map[i]; const uint8_t *srcrow = in->data[0]; - uint8_t *dstrow = out->data[0]; int imin = lrint(r->in_min * UINT16_MAX); int imax = lrint(r->in_max * UINT16_MAX); int omin = lrint(r->out_min * UINT16_MAX); int omax = lrint(r->out_max * UINT16_MAX); - double coeff; - struct thread_data td; + float coeff; if (imin < 0) { imin = UINT16_MAX; - for (y = 0; y < inlink->h; y++) { + for (int y = 0; y < inlink->h; y++) { const uint16_t *src = (const uint16_t *)srcrow; - for (x = 0; x < s->linesize; x += step) + for (int x = 0; x < s->linesize; x += step) imin = FFMIN(imin, src[x + offset]); srcrow += in->linesize[0]; } @@ -266,33 +271,27 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if (imax < 0) { srcrow = in->data[0]; imax = 0; - for (y = 0; y < inlink->h; y++) { + for (int y = 0; y < inlink->h; y++) { const uint16_t *src = (const uint16_t *)srcrow; - for (x = 0; x < s->linesize; x += step) + for (int x = 0; x < s->linesize; x += step) imax = FFMAX(imax, src[x + offset]); srcrow += in->linesize[0]; } } - srcrow = in->data[0]; coeff = (omax - omin) / (double)(imax - imin); - td.srcrow = srcrow; - td.dstrow = dstrow; - td.dst_linesize = out->linesize[0]; - td.src_linesize = in->linesize[0]; - td.coeff = coeff; - td.offset = offset; - td.h = inlink->h; - td.imin = imin; - td.omin = omin; - - ctx->internal->execute(ctx, colorlevel_slice_16, &td, NULL, - FFMIN(inlink->h, ff_filter_get_nb_threads(ctx))); + td.coeff[i] = coeff; + td.imin[i] = imin; + td.omin[i] = omin; } + break; } + ctx->internal->execute(ctx, s->colorlevels_slice, &td, NULL, + FFMIN(inlink->h, ff_filter_get_nb_threads(ctx))); + if (in != out) av_frame_free(&in); return ff_filter_frame(outlink, out); diff --git a/libavfilter/vf_colorspace.c b/libavfilter/vf_colorspace.c index 7098dd5be..471669500 100644 --- a/libavfilter/vf_colorspace.c +++ b/libavfilter/vf_colorspace.c @@ -24,6 +24,7 @@ */ #include "libavutil/avassert.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/pixfmt.h" @@ -179,6 +180,7 @@ static const struct TransferCharacteristics transfer_characteristics[AVCOL_TRC_N [AVCOL_TRC_GAMMA28] = { 1.0, 0.0, 1.0 / 2.8, 0.0 }, [AVCOL_TRC_SMPTE170M] = { 1.099, 0.018, 0.45, 4.5 }, [AVCOL_TRC_SMPTE240M] = { 1.1115, 0.0228, 0.45, 4.0 }, + [AVCOL_TRC_LINEAR] = { 1.0, 0.0, 1.0, 0.0 }, [AVCOL_TRC_IEC61966_2_1] = { 1.055, 0.0031308, 1.0 / 2.4, 12.92 }, [AVCOL_TRC_IEC61966_2_4] = { 1.099, 0.018, 0.45, 4.5 }, [AVCOL_TRC_BT2020_10] = { 1.099, 0.018, 0.45, 4.5 }, @@ -896,7 +898,7 @@ static int query_formats(AVFilterContext *ctx) return AVERROR(ENOMEM); if (s->user_format == AV_PIX_FMT_NONE) return ff_set_common_formats(ctx, formats); - res = ff_formats_ref(formats, &ctx->inputs[0]->out_formats); + res = ff_formats_ref(formats, &ctx->inputs[0]->outcfg.formats); if (res < 0) return res; formats = NULL; @@ -904,7 +906,7 @@ static int query_formats(AVFilterContext *ctx) if (res < 0) return res; - return ff_formats_ref(formats, &ctx->outputs[0]->in_formats); + return ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats); } static int config_props(AVFilterLink *outlink) @@ -990,6 +992,7 @@ static const AVOption colorspace_options[] = { ENUM("gamma28", AVCOL_TRC_GAMMA28, "trc"), ENUM("smpte170m", AVCOL_TRC_SMPTE170M, "trc"), ENUM("smpte240m", AVCOL_TRC_SMPTE240M, "trc"), + ENUM("linear", AVCOL_TRC_LINEAR, "trc"), ENUM("srgb", AVCOL_TRC_IEC61966_2_1, "trc"), ENUM("iec61966-2-1", AVCOL_TRC_IEC61966_2_1, "trc"), ENUM("xvycc", AVCOL_TRC_IEC61966_2_4, "trc"), diff --git a/libavfilter/vf_colortemperature.c b/libavfilter/vf_colortemperature.c new file mode 100644 index 000000000..7be5e796e --- /dev/null +++ b/libavfilter/vf_colortemperature.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/opt.h" +#include "libavutil/imgutils.h" +#include "avfilter.h" +#include "drawutils.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +#define R 0 +#define G 1 +#define B 2 + +typedef struct ColorTemperatureContext { + const AVClass *class; + + float temperature; + float mix; + float preserve; + + float color[3]; + + int step; + int depth; + uint8_t rgba_map[4]; + + int (*do_slice)(AVFilterContext *s, void *arg, + int jobnr, int nb_jobs); +} ColorTemperatureContext; + +static float saturate(float input) +{ + return av_clipf(input, 0.f, 1.f); +} + +static void kelvin2rgb(float k, float *rgb) +{ + float kelvin = k / 100.0f; + + if (kelvin <= 66.0f) { + rgb[0] = 1.0f; + rgb[1] = saturate(0.39008157876901960784f * logf(kelvin) - 0.63184144378862745098f); + } else { + const float t = fmaxf(kelvin - 60.0f, 0.0f); + rgb[0] = saturate(1.29293618606274509804f * powf(t, -0.1332047592f)); + rgb[1] = saturate(1.12989086089529411765f * powf(t, -0.0755148492f)); + } + + if (kelvin >= 66.0f) + rgb[2] = 1.0f; + else if (kelvin <= 19.0f) + rgb[2] = 0.0f; + else + rgb[2] = saturate(0.54320678911019607843f * logf(kelvin - 10.0f) - 1.19625408914f); +} + +static float lerpf(float v0, float v1, float f) +{ + return v0 + (v1 - v0) * f; +} + +#define PROCESS() \ + nr = r * color[0]; \ + ng = g * color[1]; \ + nb = b * color[2]; \ + \ + nr = lerpf(r, nr, mix); \ + ng = lerpf(g, ng, mix); \ + nb = lerpf(b, nb, mix); \ + \ + l0 = (FFMAX3(r, g, b) + FFMIN3(r, g, b)) + FLT_EPSILON; \ + l1 = (FFMAX3(nr, ng, nb) + FFMIN3(nr, ng, nb)) + FLT_EPSILON; \ + l = l0 / l1; \ + \ + r = nr * l; \ + g = ng * l; \ + b = nb * l; \ + \ + nr = lerpf(nr, r, preserve); \ + ng = lerpf(ng, g, preserve); \ + nb = lerpf(nb, b, preserve); + +static int temperature_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorTemperatureContext *s = ctx->priv; + AVFrame *frame = arg; + const int width = frame->width; + const int height = frame->height; + const float mix = s->mix; + const float preserve = s->preserve; + const float *color = s->color; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int glinesize = frame->linesize[0]; + const int blinesize = frame->linesize[1]; + const int rlinesize = frame->linesize[2]; + uint8_t *gptr = frame->data[0] + slice_start * glinesize; + uint8_t *bptr = frame->data[1] + slice_start * blinesize; + uint8_t *rptr = frame->data[2] + slice_start * rlinesize; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + float g = gptr[x]; + float b = bptr[x]; + float r = rptr[x]; + float nr, ng, nb; + float l0, l1, l; + + PROCESS() + + gptr[x] = av_clip_uint8(ng); + bptr[x] = av_clip_uint8(nb); + rptr[x] = av_clip_uint8(nr); + } + + gptr += glinesize; + bptr += blinesize; + rptr += rlinesize; + } + + return 0; +} + +static int temperature_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorTemperatureContext *s = ctx->priv; + AVFrame *frame = arg; + const int depth = s->depth; + const int width = frame->width; + const int height = frame->height; + const float preserve = s->preserve; + const float mix = s->mix; + const float *color = s->color; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int glinesize = frame->linesize[0] / sizeof(uint16_t); + const int blinesize = frame->linesize[1] / sizeof(uint16_t); + const int rlinesize = frame->linesize[2] / sizeof(uint16_t); + uint16_t *gptr = (uint16_t *)frame->data[0] + slice_start * glinesize; + uint16_t *bptr = (uint16_t *)frame->data[1] + slice_start * blinesize; + uint16_t *rptr = (uint16_t *)frame->data[2] + slice_start * rlinesize; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + float g = gptr[x]; + float b = bptr[x]; + float r = rptr[x]; + float nr, ng, nb; + float l0, l1, l; + + PROCESS() + + gptr[x] = av_clip_uintp2_c(ng, depth); + bptr[x] = av_clip_uintp2_c(nb, depth); + rptr[x] = av_clip_uintp2_c(nr, depth); + } + + gptr += glinesize; + bptr += blinesize; + rptr += rlinesize; + } + + return 0; +} + +static int temperature_slice8p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorTemperatureContext *s = ctx->priv; + AVFrame *frame = arg; + const int step = s->step; + const int width = frame->width; + const int height = frame->height; + const float mix = s->mix; + const float preserve = s->preserve; + const float *color = s->color; + const uint8_t roffset = s->rgba_map[R]; + const uint8_t goffset = s->rgba_map[G]; + const uint8_t boffset = s->rgba_map[B]; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int linesize = frame->linesize[0]; + uint8_t *ptr = frame->data[0] + slice_start * linesize; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + float g = ptr[x * step + goffset]; + float b = ptr[x * step + boffset]; + float r = ptr[x * step + roffset]; + float nr, ng, nb; + float l0, l1, l; + + PROCESS() + + ptr[x * step + goffset] = av_clip_uint8(ng); + ptr[x * step + boffset] = av_clip_uint8(nb); + ptr[x * step + roffset] = av_clip_uint8(nr); + } + + ptr += linesize; + } + + return 0; +} + +static int temperature_slice16p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ColorTemperatureContext *s = ctx->priv; + AVFrame *frame = arg; + const int step = s->step; + const int depth = s->depth; + const int width = frame->width; + const int height = frame->height; + const float preserve = s->preserve; + const float mix = s->mix; + const float *color = s->color; + const uint8_t roffset = s->rgba_map[R]; + const uint8_t goffset = s->rgba_map[G]; + const uint8_t boffset = s->rgba_map[B]; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int linesize = frame->linesize[0] / sizeof(uint16_t); + uint16_t *ptr = (uint16_t *)frame->data[0] + slice_start * linesize; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + float g = ptr[x * step + goffset]; + float b = ptr[x * step + boffset]; + float r = ptr[x * step + roffset]; + float nr, ng, nb; + float l0, l1, l; + + PROCESS() + + ptr[x * step + goffset] = av_clip_uintp2_c(ng, depth); + ptr[x * step + boffset] = av_clip_uintp2_c(nb, depth); + ptr[x * step + roffset] = av_clip_uintp2_c(nr, depth); + } + + ptr += linesize; + } + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *frame) +{ + AVFilterContext *ctx = inlink->dst; + ColorTemperatureContext *s = ctx->priv; + + kelvin2rgb(s->temperature, s->color); + + ctx->internal->execute(ctx, s->do_slice, frame, NULL, + FFMIN(frame->height, ff_filter_get_nb_threads(ctx))); + + return ff_filter_frame(ctx->outputs[0], frame); +} + +static av_cold int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_fmts[] = { + AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, + AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, + AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, + AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, + AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, + AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48, + AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *formats = NULL; + + formats = ff_make_format_list(pixel_fmts); + if (!formats) + return AVERROR(ENOMEM); + + return ff_set_common_formats(ctx, formats); +} + +static av_cold int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ColorTemperatureContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR; + + s->step = desc->nb_components; + if (inlink->format == AV_PIX_FMT_RGB0 || + inlink->format == AV_PIX_FMT_0RGB || + inlink->format == AV_PIX_FMT_BGR0 || + inlink->format == AV_PIX_FMT_0BGR) + s->step = 4; + + s->depth = desc->comp[0].depth; + s->do_slice = s->depth <= 8 ? temperature_slice8 : temperature_slice16; + if (!planar) + s->do_slice = s->depth <= 8 ? temperature_slice8p : temperature_slice16p; + + ff_fill_rgba_map(s->rgba_map, inlink->format); + + return 0; +} + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + .config_props = config_input, + .needs_writable = 1, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +#define OFFSET(x) offsetof(ColorTemperatureContext, x) +#define VF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption colortemperature_options[] = { + { "temperature", "set the temperature in Kelvin", OFFSET(temperature), AV_OPT_TYPE_FLOAT, {.dbl=6500}, 1000, 40000, VF }, + { "mix", "set the mix with filtered output", OFFSET(mix), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, VF }, + { "pl", "set the amount of preserving lightness", OFFSET(preserve), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(colortemperature); + +AVFilter ff_vf_colortemperature = { + .name = "colortemperature", + .description = NULL_IF_CONFIG_SMALL("Adjust color temperature of video."), + .priv_size = sizeof(ColorTemperatureContext), + .priv_class = &colortemperature_class, + .query_formats = query_formats, + .inputs = inputs, + .outputs = outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; diff --git a/libavfilter/vf_convolution.c b/libavfilter/vf_convolution.c index 5909feaad..0b7356b32 100644 --- a/libavfilter/vf_convolution.c +++ b/libavfilter/vf_convolution.c @@ -31,7 +31,7 @@ #include "video.h" #define OFFSET(x) offsetof(ConvolutionContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption convolution_options[] = { { "0m", "set matrix for 1st plane", OFFSET(matrix_str[0]), AV_OPT_TYPE_STRING, {.str="0 0 0 0 1 0 0 0 0"}, 0, 0, FLAGS }, @@ -110,7 +110,7 @@ typedef struct ThreadData { static void filter16_prewitt(uint8_t *dstp, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { uint16_t *dst = (uint16_t *)dstp; int x; @@ -128,7 +128,7 @@ static void filter16_prewitt(uint8_t *dstp, int width, static void filter16_roberts(uint8_t *dstp, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { uint16_t *dst = (uint16_t *)dstp; int x; @@ -144,7 +144,7 @@ static void filter16_roberts(uint8_t *dstp, int width, static void filter16_sobel(uint8_t *dstp, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { uint16_t *dst = (uint16_t *)dstp; int x; @@ -159,10 +159,59 @@ static void filter16_sobel(uint8_t *dstp, int width, } } +static void filter16_kirsch(uint8_t *dstp, int width, + float scale, float delta, const int *const matrix, + const uint8_t *c[], int peak, int radius, + int dstride, int stride, int size) +{ + uint16_t *dst = (uint16_t *)dstp; + const uint16_t *c0 = (const uint16_t *)c[0], *c1 = (const uint16_t *)c[1], *c2 = (const uint16_t *)c[2]; + const uint16_t *c3 = (const uint16_t *)c[3], *c5 = (const uint16_t *)c[5]; + const uint16_t *c6 = (const uint16_t *)c[6], *c7 = (const uint16_t *)c[7], *c8 = (const uint16_t *)c[8]; + int x; + + for (x = 0; x < width; x++) { + int sum0 = c0[x] * 5 + c1[x] * 5 + c2[x] * 5 + + c3[x] * -3 + c5[x] * -3 + + c6[x] * -3 + c7[x] * -3 + c8[x] * -3; + int sum1 = c0[x] * -3 + c1[x] * 5 + c2[x] * 5 + + c3[x] * 5 + c5[x] * -3 + + c6[x] * -3 + c7[x] * -3 + c8[x] * -3; + int sum2 = c0[x] * -3 + c1[x] * -3 + c2[x] * 5 + + c3[x] * 5 + c5[x] * 5 + + c6[x] * -3 + c7[x] * -3 + c8[x] * -3; + int sum3 = c0[x] * -3 + c1[x] * -3 + c2[x] * -3 + + c3[x] * 5 + c5[x] * 5 + + c6[x] * 5 + c7[x] * -3 + c8[x] * -3; + int sum4 = c0[x] * -3 + c1[x] * -3 + c2[x] * -3 + + c3[x] * -3 + c5[x] * 5 + + c6[x] * 5 + c7[x] * 5 + c8[x] * -3; + int sum5 = c0[x] * -3 + c1[x] * -3 + c2[x] * -3 + + c3[x] * -3 + c5[x] * -3 + + c6[x] * 5 + c7[x] * 5 + c8[x] * 5; + int sum6 = c0[x] * 5 + c1[x] * -3 + c2[x] * -3 + + c3[x] * -3 + c5[x] * -3 + + c6[x] * -3 + c7[x] * 5 + c8[x] * 5; + int sum7 = c0[x] * 5 + c1[x] * 5 + c2[x] * -3 + + c3[x] * -3 + c5[x] * -3 + + c6[x] * -3 + c7[x] * -3 + c8[x] * 5; + + sum0 = FFMAX(sum0, sum1); + sum2 = FFMAX(sum2, sum3); + sum4 = FFMAX(sum4, sum5); + sum6 = FFMAX(sum6, sum7); + sum0 = FFMAX(sum0, sum2); + sum4 = FFMAX(sum4, sum6); + sum0 = FFMAX(sum0, sum4); + + dst[x] = av_clip(FFABS(sum0) * scale + delta, 0, peak); + } +} + static void filter_prewitt(uint8_t *dst, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2]; const uint8_t *c3 = c[3], *c5 = c[5]; @@ -182,7 +231,7 @@ static void filter_prewitt(uint8_t *dst, int width, static void filter_roberts(uint8_t *dst, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { int x; @@ -197,7 +246,7 @@ static void filter_roberts(uint8_t *dst, int width, static void filter_sobel(uint8_t *dst, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2]; const uint8_t *c3 = c[3], *c5 = c[5]; @@ -214,10 +263,58 @@ static void filter_sobel(uint8_t *dst, int width, } } +static void filter_kirsch(uint8_t *dst, int width, + float scale, float delta, const int *const matrix, + const uint8_t *c[], int peak, int radius, + int dstride, int stride, int size) +{ + const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2]; + const uint8_t *c3 = c[3], *c5 = c[5]; + const uint8_t *c6 = c[6], *c7 = c[7], *c8 = c[8]; + int x; + + for (x = 0; x < width; x++) { + int sum0 = c0[x] * 5 + c1[x] * 5 + c2[x] * 5 + + c3[x] * -3 + c5[x] * -3 + + c6[x] * -3 + c7[x] * -3 + c8[x] * -3; + int sum1 = c0[x] * -3 + c1[x] * 5 + c2[x] * 5 + + c3[x] * 5 + c5[x] * -3 + + c6[x] * -3 + c7[x] * -3 + c8[x] * -3; + int sum2 = c0[x] * -3 + c1[x] * -3 + c2[x] * 5 + + c3[x] * 5 + c5[x] * 5 + + c6[x] * -3 + c7[x] * -3 + c8[x] * -3; + int sum3 = c0[x] * -3 + c1[x] * -3 + c2[x] * -3 + + c3[x] * 5 + c5[x] * 5 + + c6[x] * 5 + c7[x] * -3 + c8[x] * -3; + int sum4 = c0[x] * -3 + c1[x] * -3 + c2[x] * -3 + + c3[x] * -3 + c5[x] * 5 + + c6[x] * 5 + c7[x] * 5 + c8[x] * -3; + int sum5 = c0[x] * -3 + c1[x] * -3 + c2[x] * -3 + + c3[x] * -3 + c5[x] * -3 + + c6[x] * 5 + c7[x] * 5 + c8[x] * 5; + int sum6 = c0[x] * 5 + c1[x] * -3 + c2[x] * -3 + + c3[x] * -3 + c5[x] * -3 + + c6[x] * -3 + c7[x] * 5 + c8[x] * 5; + int sum7 = c0[x] * 5 + c1[x] * 5 + c2[x] * -3 + + c3[x] * -3 + c5[x] * -3 + + c6[x] * -3 + c7[x] * -3 + c8[x] * 5; + + sum0 = FFMAX(sum0, sum1); + sum2 = FFMAX(sum2, sum3); + sum4 = FFMAX(sum4, sum5); + sum6 = FFMAX(sum6, sum7); + sum0 = FFMAX(sum0, sum2); + sum4 = FFMAX(sum4, sum6); + sum0 = FFMAX(sum0, sum4); + + dst[x] = av_clip_uint8(FFABS(sum0) * scale + delta); + } +} + static void filter16_3x3(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { uint16_t *dst = (uint16_t *)dstp; int x; @@ -240,7 +337,7 @@ static void filter16_3x3(uint8_t *dstp, int width, static void filter16_5x5(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { uint16_t *dst = (uint16_t *)dstp; int x; @@ -259,7 +356,7 @@ static void filter16_5x5(uint8_t *dstp, int width, static void filter16_7x7(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { uint16_t *dst = (uint16_t *)dstp; int x; @@ -278,7 +375,7 @@ static void filter16_7x7(uint8_t *dstp, int width, static void filter16_row(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { uint16_t *dst = (uint16_t *)dstp; int x; @@ -297,19 +394,24 @@ static void filter16_row(uint8_t *dstp, int width, static void filter16_column(uint8_t *dstp, int height, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { + DECLARE_ALIGNED(64, int, sum)[16]; uint16_t *dst = (uint16_t *)dstp; - int y; + const int width = FFMIN(16, size); - for (y = 0; y < height; y++) { - int i, sum = 0; + for (int y = 0; y < height; y++) { - for (i = 0; i < 2 * radius + 1; i++) - sum += AV_RN16A(&c[i][0 + y * stride]) * matrix[i]; + memset(sum, 0, sizeof(sum)); + for (int i = 0; i < 2 * radius + 1; i++) { + for (int off16 = 0; off16 < width; off16++) + sum[off16] += AV_RN16A(&c[i][0 + y * stride + off16 * 2]) * matrix[i]; + } - sum = (int)(sum * rdiv + bias + 0.5f); - dst[0] = av_clip(sum, 0, peak); + for (int off16 = 0; off16 < width; off16++) { + sum[off16] = (int)(sum[off16] * rdiv + bias + 0.5f); + dst[off16] = av_clip(sum[off16], 0, peak); + } dst += dstride / 2; } } @@ -317,7 +419,7 @@ static void filter16_column(uint8_t *dstp, int height, static void filter_7x7(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { int x; @@ -335,7 +437,7 @@ static void filter_7x7(uint8_t *dst, int width, static void filter_5x5(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { int x; @@ -353,7 +455,7 @@ static void filter_5x5(uint8_t *dst, int width, static void filter_3x3(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2]; const uint8_t *c3 = c[3], *c4 = c[4], *c5 = c[5]; @@ -372,7 +474,7 @@ static void filter_3x3(uint8_t *dst, int width, static void filter_row(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { int x; @@ -390,18 +492,22 @@ static void filter_row(uint8_t *dst, int width, static void filter_column(uint8_t *dst, int height, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride) + int dstride, int stride, int size) { - int y; + DECLARE_ALIGNED(64, int, sum)[16]; - for (y = 0; y < height; y++) { - int i, sum = 0; + for (int y = 0; y < height; y++) { + memset(sum, 0, sizeof(sum)); - for (i = 0; i < 2 * radius + 1; i++) - sum += c[i][0 + y * stride] * matrix[i]; + for (int i = 0; i < 2 * radius + 1; i++) { + for (int off16 = 0; off16 < 16; off16++) + sum[off16] += c[i][0 + y * stride + off16] * matrix[i]; + } - sum = (int)(sum * rdiv + bias + 0.5f); - dst[0] = av_clip_uint8(sum); + for (int off16 = 0; off16 < 16; off16++) { + sum[off16] = (int)(sum[off16] * rdiv + bias + 0.5f); + dst[off16] = av_clip_uint8(sum[off16]); + } dst += dstride; } } @@ -508,6 +614,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int dst_pos = slice_start * (mode == MATRIX_COLUMN ? bpc : dstride); uint8_t *dst = out->data[plane] + dst_pos; const int *matrix = s->matrix[plane]; + const int step = mode == MATRIX_COLUMN ? 16 : 1; const uint8_t *c[49]; int y, x; @@ -520,32 +627,31 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) width * bpc, slice_end - slice_start); continue; } - - for (y = slice_start; y < slice_end; y++) { + for (y = slice_start; y < slice_end; y += step) { const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : radius * bpc; - const int yoff = mode == MATRIX_COLUMN ? radius * stride : 0; + const int yoff = mode == MATRIX_COLUMN ? radius * dstride : 0; for (x = 0; x < radius; x++) { const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc; - const int yoff = mode == MATRIX_COLUMN ? x * stride : 0; + const int yoff = mode == MATRIX_COLUMN ? x * dstride : 0; s->setup[plane](radius, c, src, stride, x, width, y, height, bpc); s->filter[plane](dst + yoff + xoff, 1, rdiv, bias, matrix, c, s->max, radius, - dstride, stride); + dstride, stride, slice_end - step); } s->setup[plane](radius, c, src, stride, radius, width, y, height, bpc); s->filter[plane](dst + yoff + xoff, sizew - 2 * radius, rdiv, bias, matrix, c, s->max, radius, - dstride, stride); + dstride, stride, slice_end - step); for (x = sizew - radius; x < sizew; x++) { const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc; - const int yoff = mode == MATRIX_COLUMN ? x * stride : 0; + const int yoff = mode == MATRIX_COLUMN ? x * dstride : 0; s->setup[plane](radius, c, src, stride, x, width, y, height, bpc); s->filter[plane](dst + yoff + xoff, 1, rdiv, bias, matrix, c, s->max, radius, - dstride, stride); + dstride, stride, slice_end - step); } if (mode != MATRIX_COLUMN) dst += dstride; @@ -604,6 +710,10 @@ static int config_input(AVFilterLink *inlink) if (s->depth > 8) for (p = 0; p < s->nb_planes; p++) s->filter[p] = filter16_sobel; + } else if (!strcmp(ctx->filter->name, "kirsch")) { + if (s->depth > 8) + for (p = 0; p < s->nb_planes; p++) + s->filter[p] = filter16_kirsch; } return 0; @@ -644,20 +754,25 @@ static av_cold int init(AVFilterContext *ctx) float sum = 0; p = s->matrix_str[i]; - while (s->matrix_length[i] < 49) { - if (!(arg = av_strtok(p, " ", &saveptr))) - break; + if (p) { + s->matrix_length[i] = 0; - p = NULL; - sscanf(arg, "%d", &matrix[s->matrix_length[i]]); - sum += matrix[s->matrix_length[i]]; - s->matrix_length[i]++; + while (s->matrix_length[i] < 49) { + if (!(arg = av_strtok(p, " |", &saveptr))) + break; + + p = NULL; + sscanf(arg, "%d", &matrix[s->matrix_length[i]]); + sum += matrix[s->matrix_length[i]]; + s->matrix_length[i]++; + } + + if (!(s->matrix_length[i] & 1)) { + av_log(ctx, AV_LOG_ERROR, "number of matrix elements must be odd\n"); + return AVERROR(EINVAL); + } } - if (!(s->matrix_length[i] & 1)) { - av_log(ctx, AV_LOG_ERROR, "number of matrix elements must be odd\n"); - return AVERROR(EINVAL); - } if (s->mode[i] == MATRIX_ROW) { s->filter[i] = filter_row; s->setup[i] = setup_row; @@ -668,24 +783,31 @@ static av_cold int init(AVFilterContext *ctx) s->size[i] = s->matrix_length[i]; } else if (s->matrix_length[i] == 9) { s->size[i] = 3; - if (!memcmp(matrix, same3x3, sizeof(same3x3))) + + if (!memcmp(matrix, same3x3, sizeof(same3x3))) { s->copy[i] = 1; - else + } else { s->filter[i] = filter_3x3; + s->copy[i] = 0; + } s->setup[i] = setup_3x3; } else if (s->matrix_length[i] == 25) { s->size[i] = 5; - if (!memcmp(matrix, same5x5, sizeof(same5x5))) + if (!memcmp(matrix, same5x5, sizeof(same5x5))) { s->copy[i] = 1; - else + } else { s->filter[i] = filter_5x5; + s->copy[i] = 0; + } s->setup[i] = setup_5x5; } else if (s->matrix_length[i] == 49) { s->size[i] = 7; - if (!memcmp(matrix, same7x7, sizeof(same7x7))) + if (!memcmp(matrix, same7x7, sizeof(same7x7))) { s->copy[i] = 1; - else + } else { s->filter[i] = filter_7x7; + s->copy[i] = 0; + } s->setup[i] = setup_7x7; } else { return AVERROR(EINVAL); @@ -732,11 +854,34 @@ static av_cold int init(AVFilterContext *ctx) s->rdiv[i] = s->scale; s->bias[i] = s->delta; } + } else if (!strcmp(ctx->filter->name, "kirsch")) { + for (i = 0; i < 4; i++) { + if ((1 << i) & s->planes) + s->filter[i] = filter_kirsch; + else + s->copy[i] = 1; + s->size[i] = 3; + s->setup[i] = setup_3x3; + s->rdiv[i] = s->scale; + s->bias[i] = s->delta; + } } return 0; } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return init(ctx); +} + static const AVFilterPad convolution_inputs[] = { { .name = "default", @@ -767,19 +912,23 @@ AVFilter ff_vf_convolution = { .inputs = convolution_inputs, .outputs = convolution_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif /* CONFIG_CONVOLUTION_FILTER */ -#if CONFIG_PREWITT_FILTER +#if CONFIG_PREWITT_FILTER || CONFIG_ROBERTS_FILTER || CONFIG_SOBEL_FILTER -static const AVOption prewitt_options[] = { +static const AVOption prewitt_roberts_sobel_options[] = { { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, FLAGS}, { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 65535, FLAGS}, { "delta", "set delta", OFFSET(delta), AV_OPT_TYPE_FLOAT, {.dbl=0}, -65535, 65535, FLAGS}, { NULL } }; +#if CONFIG_PREWITT_FILTER + +#define prewitt_options prewitt_roberts_sobel_options AVFILTER_DEFINE_CLASS(prewitt); AVFilter ff_vf_prewitt = { @@ -792,19 +941,14 @@ AVFilter ff_vf_prewitt = { .inputs = convolution_inputs, .outputs = convolution_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif /* CONFIG_PREWITT_FILTER */ #if CONFIG_SOBEL_FILTER -static const AVOption sobel_options[] = { - { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, FLAGS}, - { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 65535, FLAGS}, - { "delta", "set delta", OFFSET(delta), AV_OPT_TYPE_FLOAT, {.dbl=0}, -65535, 65535, FLAGS}, - { NULL } -}; - +#define sobel_options prewitt_roberts_sobel_options AVFILTER_DEFINE_CLASS(sobel); AVFilter ff_vf_sobel = { @@ -817,19 +961,14 @@ AVFilter ff_vf_sobel = { .inputs = convolution_inputs, .outputs = convolution_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif /* CONFIG_SOBEL_FILTER */ #if CONFIG_ROBERTS_FILTER -static const AVOption roberts_options[] = { - { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, FLAGS}, - { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 65535, FLAGS}, - { "delta", "set delta", OFFSET(delta), AV_OPT_TYPE_FLOAT, {.dbl=0}, -65535, 65535, FLAGS}, - { NULL } -}; - +#define roberts_options prewitt_roberts_sobel_options AVFILTER_DEFINE_CLASS(roberts); AVFilter ff_vf_roberts = { @@ -842,6 +981,29 @@ AVFilter ff_vf_roberts = { .inputs = convolution_inputs, .outputs = convolution_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif /* CONFIG_ROBERTS_FILTER */ + +#if CONFIG_KIRSCH_FILTER + +#define kirsch_options prewitt_roberts_sobel_options +AVFILTER_DEFINE_CLASS(kirsch); + +AVFilter ff_vf_kirsch = { + .name = "kirsch", + .description = NULL_IF_CONFIG_SMALL("Apply kirsch operator."), + .priv_size = sizeof(ConvolutionContext), + .priv_class = &kirsch_class, + .init = init, + .query_formats = query_formats, + .inputs = convolution_inputs, + .outputs = convolution_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, +}; + +#endif /* CONFIG_KIRSCH_FILTER */ + +#endif /* CONFIG_PREWITT_FILTER || CONFIG_ROBERTS_FILTER || CONFIG_SOBEL_FILTER */ diff --git a/libavfilter/vf_copy.c b/libavfilter/vf_copy.c index e82feb4f0..78bb5109e 100644 --- a/libavfilter/vf_copy.c +++ b/libavfilter/vf_copy.c @@ -30,17 +30,12 @@ static int query_formats(AVFilterContext *ctx) { AVFilterFormats *formats = NULL; - int fmt; - - for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - int ret; - if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) - continue; - if ((ret = ff_add_format(&formats, fmt)) < 0) - return ret; - } + int ret; + ret = ff_formats_pixdesc_filter(&formats, 0, + AV_PIX_FMT_FLAG_HWACCEL); + if (ret < 0) + return ret; return ff_set_common_formats(ctx, formats); } diff --git a/libavfilter/vf_coreimage.m b/libavfilter/vf_coreimage.m index 4ed5ba792..cbd67791b 100644 --- a/libavfilter/vf_coreimage.m +++ b/libavfilter/vf_coreimage.m @@ -149,8 +149,8 @@ static int query_formats(AVFilterContext *fctx) return AVERROR(ENOMEM); } - if ((ret = ff_formats_ref(inout_formats, &fctx->inputs[0]->out_formats)) < 0 || - (ret = ff_formats_ref(inout_formats, &fctx->outputs[0]->in_formats)) < 0) { + if ((ret = ff_formats_ref(inout_formats, &fctx->inputs[0]->outcfg.formats)) < 0 || + (ret = ff_formats_ref(inout_formats, &fctx->outputs[0]->incfg.formats)) < 0) { return ret; } @@ -171,7 +171,7 @@ static int query_formats_src(AVFilterContext *fctx) return AVERROR(ENOMEM); } - if ((ret = ff_formats_ref(inout_formats, &fctx->outputs[0]->in_formats)) < 0) { + if ((ret = ff_formats_ref(inout_formats, &fctx->outputs[0]->incfg.formats)) < 0) { return ret; } diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c index 7c7d0b953..5ae87cad2 100644 --- a/libavfilter/vf_cropdetect.c +++ b/libavfilter/vf_cropdetect.c @@ -37,6 +37,7 @@ typedef struct CropDetectContext { int x1, y1, x2, y2; float limit; int round; + int skip; int reset_count; int frame_nb; int max_pixsteps[4]; @@ -127,10 +128,10 @@ static av_cold int init(AVFilterContext *ctx) { CropDetectContext *s = ctx->priv; - s->frame_nb = -2; + s->frame_nb = -1 * s->skip; - av_log(ctx, AV_LOG_VERBOSE, "limit:%f round:%d reset_count:%d\n", - s->limit, s->round, s->reset_count); + av_log(ctx, AV_LOG_VERBOSE, "limit:%f round:%d skip:%d reset_count:%d\n", + s->limit, s->round, s->skip, s->reset_count); return 0; } @@ -167,7 +168,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) int outliers, last_y; int limit = lrint(s->limit); - // ignore first 2 frames - they may be empty + // ignore first s->skip frames if (++s->frame_nb > 0) { metadata = &frame->metadata; @@ -247,6 +248,7 @@ static const AVOption cropdetect_options[] = { { "limit", "Threshold below which the pixel is considered black", OFFSET(limit), AV_OPT_TYPE_FLOAT, { .dbl = 24.0/255 }, 0, 65535, FLAGS }, { "round", "Value by which the width/height should be divisible", OFFSET(round), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, INT_MAX, FLAGS }, { "reset", "Recalculate the crop area after this many frames", OFFSET(reset_count), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, + { "skip", "Number of initial frames to skip", OFFSET(skip), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, INT_MAX, FLAGS }, { "reset_count", "Recalculate the crop area after this many frames",OFFSET(reset_count),AV_OPT_TYPE_INT,{ .i64 = 0 }, 0, INT_MAX, FLAGS }, { "max_outliers", "Threshold count of outliers", OFFSET(max_outliers),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, { NULL } diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c index 883cc1c90..3524fef1a 100644 --- a/libavfilter/vf_curves.c +++ b/libavfilter/vf_curves.c @@ -69,8 +69,10 @@ typedef struct CurvesContext { uint8_t rgba_map[4]; int step; char *plot_filename; + int saved_plot; int is_16bit; int depth; + int parsed_psfile; int (*filter_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); } CurvesContext; @@ -80,20 +82,20 @@ typedef struct ThreadData { } ThreadData; #define OFFSET(x) offsetof(CurvesContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption curves_options[] = { { "preset", "select a color curves preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=PRESET_NONE}, PRESET_NONE, NB_PRESETS-1, FLAGS, "preset_name" }, - { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NONE}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "color_negative", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_COLOR_NEGATIVE}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "cross_process", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_CROSS_PROCESS}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "darker", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_DARKER}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "increase_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_INCREASE_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "lighter", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_LIGHTER}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "linear_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_LINEAR_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "medium_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_MEDIUM_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "negative", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NEGATIVE}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "strong_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_STRONG_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "vintage", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_VINTAGE}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, + { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NONE}, 0, 0, FLAGS, "preset_name" }, + { "color_negative", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_COLOR_NEGATIVE}, 0, 0, FLAGS, "preset_name" }, + { "cross_process", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_CROSS_PROCESS}, 0, 0, FLAGS, "preset_name" }, + { "darker", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_DARKER}, 0, 0, FLAGS, "preset_name" }, + { "increase_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_INCREASE_CONTRAST}, 0, 0, FLAGS, "preset_name" }, + { "lighter", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_LIGHTER}, 0, 0, FLAGS, "preset_name" }, + { "linear_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_LINEAR_CONTRAST}, 0, 0, FLAGS, "preset_name" }, + { "medium_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_MEDIUM_CONTRAST}, 0, 0, FLAGS, "preset_name" }, + { "negative", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NEGATIVE}, 0, 0, FLAGS, "preset_name" }, + { "strong_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_STRONG_CONTRAST}, 0, 0, FLAGS, "preset_name" }, + { "vintage", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_VINTAGE}, 0, 0, FLAGS, "preset_name" }, { "master","set master points coordinates",OFFSET(comp_points_str[NB_COMP]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, { "m", "set master points coordinates",OFFSET(comp_points_str[NB_COMP]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, { "red", "set red points coordinates", OFFSET(comp_points_str[0]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, @@ -486,10 +488,11 @@ static av_cold int curves_init(AVFilterContext *ctx) } } - if (curves->psfile) { + if (curves->psfile && !curves->parsed_psfile) { ret = parse_psfile(ctx, curves->psfile); if (ret < 0) return ret; + curves->parsed_psfile = 1; } if (curves->preset != PRESET_NONE) { @@ -504,6 +507,7 @@ static av_cold int curves_init(AVFilterContext *ctx) SET_COMP_IF_NOT_SET(1, g); SET_COMP_IF_NOT_SET(2, b); SET_COMP_IF_NOT_SET(3, master); + curves->preset = PRESET_NONE; } return 0; @@ -664,7 +668,8 @@ static int config_input(AVFilterLink *inlink) curves->filter_slice = desc->flags & AV_PIX_FMT_FLAG_PLANAR ? filter_slice_planar : filter_slice_packed; for (i = 0; i < NB_COMP + 1; i++) { - curves->graph[i] = av_mallocz_array(curves->lut_size, sizeof(*curves->graph[0])); + if (!curves->graph[i]) + curves->graph[i] = av_mallocz_array(curves->lut_size, sizeof(*curves->graph[0])); if (!curves->graph[i]) return AVERROR(ENOMEM); ret = parse_points_str(ctx, comp_points + i, curves->comp_points_str[i], curves->lut_size); @@ -699,8 +704,10 @@ static int config_input(AVFilterLink *inlink) } } - if (curves->plot_filename) + if (curves->plot_filename && !curves->saved_plot) { dump_curves(curves->plot_filename, curves->graph, comp_points, curves->lut_size); + curves->saved_plot = 1; + } for (i = 0; i < NB_COMP + 1; i++) { struct keypoint *point = comp_points[i]; @@ -743,6 +750,42 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + CurvesContext *curves = ctx->priv; + int ret; + + if (!strcmp(cmd, "plot")) { + curves->saved_plot = 0; + } else if (!strcmp(cmd, "all") || !strcmp(cmd, "preset") || !strcmp(cmd, "psfile")) { + if (!strcmp(cmd, "psfile")) + curves->parsed_psfile = 0; + av_freep(&curves->comp_points_str_all); + av_freep(&curves->comp_points_str[0]); + av_freep(&curves->comp_points_str[1]); + av_freep(&curves->comp_points_str[2]); + av_freep(&curves->comp_points_str[NB_COMP]); + } else if (!strcmp(cmd, "red") || !strcmp(cmd, "r")) { + av_freep(&curves->comp_points_str[0]); + } else if (!strcmp(cmd, "green") || !strcmp(cmd, "g")) { + av_freep(&curves->comp_points_str[1]); + } else if (!strcmp(cmd, "blue") || !strcmp(cmd, "b")) { + av_freep(&curves->comp_points_str[2]); + } else if (!strcmp(cmd, "master") || !strcmp(cmd, "m")) { + av_freep(&curves->comp_points_str[NB_COMP]); + } + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + ret = curves_init(ctx); + if (ret < 0) + return ret; + return config_input(ctx->inputs[0]); +} + static av_cold void curves_uninit(AVFilterContext *ctx) { int i; @@ -781,4 +824,5 @@ AVFilter ff_vf_curves = { .outputs = curves_outputs, .priv_class = &curves_class, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; diff --git a/libavfilter/vf_datascope.c b/libavfilter/vf_datascope.c index 35f60aa2f..88007c926 100644 --- a/libavfilter/vf_datascope.c +++ b/libavfilter/vf_datascope.c @@ -37,6 +37,7 @@ typedef struct DatascopeContext { int mode; int dformat; int axis; + int components; float opacity; int nb_planes; @@ -60,17 +61,18 @@ typedef struct DatascopeContext { static const AVOption datascope_options[] = { { "size", "set output size", OFFSET(ow), AV_OPT_TYPE_IMAGE_SIZE, {.str="hd720"}, 0, 0, FLAGS }, { "s", "set output size", OFFSET(ow), AV_OPT_TYPE_IMAGE_SIZE, {.str="hd720"}, 0, 0, FLAGS }, - { "x", "set x offset", OFFSET(x), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS }, - { "y", "set y offset", OFFSET(y), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS }, - { "mode", "set scope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "mode" }, - { "mono", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mode" }, - { "color", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mode" }, - { "color2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "mode" }, - { "axis", "draw column/row numbers", OFFSET(axis), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, - { "opacity", "set background opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS }, - { "format", "set display number format", OFFSET(dformat), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "format" }, - { "hex", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "format" }, - { "dec", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "format" }, + { "x", "set x offset", OFFSET(x), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGSR }, + { "y", "set y offset", OFFSET(y), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGSR }, + { "mode", "set scope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGSR, "mode" }, + { "mono", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGSR, "mode" }, + { "color", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGSR, "mode" }, + { "color2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGSR, "mode" }, + { "axis", "draw column/row numbers", OFFSET(axis), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGSR }, + { "opacity", "set background opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGSR }, + { "format", "set display number format", OFFSET(dformat), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGSR, "format" }, + { "hex", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGSR, "format" }, + { "dec", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGSR, "format" }, + { "components", "set components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=15}, 1, 15, FLAGSR }, { NULL } }; @@ -169,7 +171,7 @@ static void reverse_color16(FFDrawContext *draw, FFDrawColor *color, FFDrawColor typedef struct ThreadData { AVFrame *in, *out; - int xoff, yoff; + int xoff, yoff, PP; } ThreadData; static int filter_color2(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) @@ -180,13 +182,14 @@ static int filter_color2(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; + const int PP = td->PP; const int xoff = td->xoff; const int yoff = td->yoff; const int P = FFMAX(s->nb_planes, s->nb_comps); const int C = s->chars; const int D = ((s->chars - s->dformat) >> 2) + s->dformat * 2; const int W = (outlink->w - xoff) / (C * 10); - const int H = (outlink->h - yoff) / (P * 12); + const int H = (outlink->h - yoff) / (PP * 12); const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"}; const int slice_start = (W * jobnr) / nb_jobs; const int slice_end = (W * (jobnr+1)) / nb_jobs; @@ -196,18 +199,21 @@ static int filter_color2(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) { FFDrawColor color = { { 0 } }; FFDrawColor reverse = { { 0 } }; - int value[4] = { 0 }; + int value[4] = { 0 }, pp = 0; s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value); s->reverse_color(&s->draw, &color, &reverse); ff_fill_rectangle(&s->draw, &color, out->data, out->linesize, - xoff + x * C * 10, yoff + y * P * 12, C * 10, P * 12); + xoff + x * C * 10, yoff + y * PP * 12, C * 10, PP * 12); for (p = 0; p < P; p++) { char text[256]; + if (!(s->components & (1 << p))) + continue; snprintf(text, sizeof(text), format[D], value[p]); - draw_text(&s->draw, out, &reverse, xoff + x * C * 10 + 2, yoff + y * P * 12 + p * 10 + 2, text, 0); + draw_text(&s->draw, out, &reverse, xoff + x * C * 10 + 2, yoff + y * PP * 12 + pp * 10 + 2, text, 0); + pp++; } } } @@ -223,13 +229,14 @@ static int filter_color(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; + const int PP = td->PP; const int xoff = td->xoff; const int yoff = td->yoff; const int P = FFMAX(s->nb_planes, s->nb_comps); const int C = s->chars; const int D = ((s->chars - s->dformat) >> 2) + s->dformat * 2; const int W = (outlink->w - xoff) / (C * 10); - const int H = (outlink->h - yoff) / (P * 12); + const int H = (outlink->h - yoff) / (PP * 12); const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"}; const int slice_start = (W * jobnr) / nb_jobs; const int slice_end = (W * (jobnr+1)) / nb_jobs; @@ -238,15 +245,18 @@ static int filter_color(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (y = 0; y < H && (y + s->y < inlink->h); y++) { for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) { FFDrawColor color = { { 0 } }; - int value[4] = { 0 }; + int value[4] = { 0 }, pp = 0; s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value); for (p = 0; p < P; p++) { char text[256]; + if (!(s->components & (1 << p))) + continue; snprintf(text, sizeof(text), format[D], value[p]); - draw_text(&s->draw, out, &color, xoff + x * C * 10 + 2, yoff + y * P * 12 + p * 10 + 2, text, 0); + draw_text(&s->draw, out, &color, xoff + x * C * 10 + 2, yoff + y * PP * 12 + pp * 10 + 2, text, 0); + pp++; } } } @@ -262,13 +272,14 @@ static int filter_mono(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; + const int PP = td->PP; const int xoff = td->xoff; const int yoff = td->yoff; const int P = FFMAX(s->nb_planes, s->nb_comps); const int C = s->chars; const int D = ((s->chars - s->dformat) >> 2) + s->dformat * 2; const int W = (outlink->w - xoff) / (C * 10); - const int H = (outlink->h - yoff) / (P * 12); + const int H = (outlink->h - yoff) / (PP * 12); const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"}; const int slice_start = (W * jobnr) / nb_jobs; const int slice_end = (W * (jobnr+1)) / nb_jobs; @@ -277,14 +288,17 @@ static int filter_mono(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (y = 0; y < H && (y + s->y < inlink->h); y++) { for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) { FFDrawColor color = { { 0 } }; - int value[4] = { 0 }; + int value[4] = { 0 }, pp = 0; s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value); for (p = 0; p < P; p++) { char text[256]; + if (!(s->components & (1 << p))) + continue; snprintf(text, sizeof(text), format[D], value[p]); - draw_text(&s->draw, out, &s->white, xoff + x * C * 10 + 2, yoff + y * P * 12 + p * 10 + 2, text, 0); + draw_text(&s->draw, out, &s->white, xoff + x * C * 10 + 2, yoff + y * PP * 12 + pp * 10 + 2, text, 0); + pp++; } } } @@ -297,9 +311,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterContext *ctx = inlink->dst; DatascopeContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; + const int P = FFMAX(s->nb_planes, s->nb_comps); ThreadData td = { 0 }; int ymaxlen = 0; int xmaxlen = 0; + int PP = 0; AVFrame *out; out = ff_get_video_buffer(outlink, outlink->w, outlink->h); @@ -312,10 +328,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ff_fill_rectangle(&s->draw, &s->black, out->data, out->linesize, 0, 0, outlink->w, outlink->h); + for (int p = 0; p < P; p++) { + if (s->components & (1 << p)) + PP++; + } + PP = FFMAX(PP, 1); + if (s->axis) { - const int P = FFMAX(s->nb_planes, s->nb_comps); const int C = s->chars; - int Y = outlink->h / (P * 12); + int Y = outlink->h / (PP * 12); int X = outlink->w / (C * 10); char text[256] = { 0 }; int x, y; @@ -327,16 +348,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) xmaxlen = strlen(text); xmaxlen *= 10; - Y = (outlink->h - xmaxlen) / (P * 12); + Y = (outlink->h - xmaxlen) / (PP * 12); X = (outlink->w - ymaxlen) / (C * 10); for (y = 0; y < Y; y++) { snprintf(text, sizeof(text), "%d", s->y + y); ff_fill_rectangle(&s->draw, &s->gray, out->data, out->linesize, - 0, xmaxlen + y * P * 12 + (P + 1) * P - 2, ymaxlen, 10); + 0, xmaxlen + y * PP * 12 + (PP + 1) * PP - 2, ymaxlen, 10); - draw_text(&s->draw, out, &s->yellow, 2, xmaxlen + y * P * 12 + (P + 1) * P, text, 0); + draw_text(&s->draw, out, &s->yellow, 2, xmaxlen + y * PP * 12 + (PP + 1) * PP, text, 0); } for (x = 0; x < X; x++) { @@ -349,7 +370,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } } - td.in = in; td.out = out, td.yoff = xmaxlen, td.xoff = ymaxlen; + td.in = in; td.out = out, td.yoff = xmaxlen, td.xoff = ymaxlen, td.PP = PP; ctx->internal->execute(ctx, s->filter, &td, NULL, FFMIN(ff_filter_get_nb_threads(ctx), FFMAX(outlink->w / 20, 1))); av_frame_free(&in); @@ -398,6 +419,18 @@ static int config_output(AVFilterLink *outlink) return 0; } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_input(ctx->inputs[0]); +} + static const AVFilterPad inputs[] = { { .name = "default", @@ -426,6 +459,7 @@ AVFilter ff_vf_datascope = { .inputs = inputs, .outputs = outputs, .flags = AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; typedef struct PixscopeContext { @@ -460,13 +494,13 @@ typedef struct PixscopeContext { #define POFFSET(x) offsetof(PixscopeContext, x) static const AVOption pixscope_options[] = { - { "x", "set scope x offset", POFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, - { "y", "set scope y offset", POFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, - { "w", "set scope width", POFFSET(w), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS }, - { "h", "set scope height", POFFSET(h), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS }, - { "o", "set window opacity", POFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, - { "wx", "set window x offset", POFFSET(wx), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGS }, - { "wy", "set window y offset", POFFSET(wy), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGS }, + { "x", "set scope x offset", POFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR }, + { "y", "set scope y offset", POFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR }, + { "w", "set scope width", POFFSET(w), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGSR }, + { "h", "set scope height", POFFSET(h), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGSR }, + { "o", "set window opacity", POFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR }, + { "wx", "set window x offset", POFFSET(wx), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGSR }, + { "wy", "set window y offset", POFFSET(wy), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGSR }, { NULL } }; @@ -675,6 +709,18 @@ static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int pixscope_process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return pixscope_config_input(ctx->inputs[0]); +} + static const AVFilterPad pixscope_inputs[] = { { .name = "default", @@ -702,6 +748,7 @@ AVFilter ff_vf_pixscope = { .inputs = pixscope_inputs, .outputs = pixscope_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, + .process_command = pixscope_process_command, }; typedef struct PixelValues { @@ -791,7 +838,7 @@ static void draw_line(FFDrawContext *draw, int x0, int y0, int x1, int y1, for (p = 0; p < draw->nb_planes; p++) { if (draw->desc->comp[p].depth == 8) { if (draw->nb_planes == 1) { - for (i = 0; i < 4; i++) { + for (i = 0; i < draw->desc->nb_components; i++) { out->data[0][y0 * out->linesize[0] + x0 * draw->pixelstep[0] + i] = color->comp[0].u8[i]; } } else { @@ -799,8 +846,8 @@ static void draw_line(FFDrawContext *draw, int x0, int y0, int x1, int y1, } } else { if (draw->nb_planes == 1) { - for (i = 0; i < 4; i++) { - AV_WN16(out->data[0] + y0 * out->linesize[0] + 2 * (x0 * draw->pixelstep[0] + i), color->comp[0].u16[i]); + for (i = 0; i < draw->desc->nb_components; i++) { + AV_WN16(out->data[0] + y0 * out->linesize[0] + (x0 * draw->pixelstep[0] + i), color->comp[0].u16[i]); } } else { AV_WN16(out->data[p] + out->linesize[p] * (y0 >> draw->vsub[p]) + (x0 >> draw->hsub[p]) * 2, color->comp[p].u16[0]); @@ -965,7 +1012,7 @@ static void draw_scope(OscilloscopeContext *s, int x0, int y0, int x1, int y1, if (s->draw.nb_planes == 1) { int i; - for (i = 0; i < s->draw.pixelstep[0]; i++) + for (i = 0; i < s->nb_comps; i++) out->data[0][out->linesize[0] * y0 + x0 * s->draw.pixelstep[0] + i] = 255 * ((s->nb_values + state) & 1); } else { out->data[0][out->linesize[0] * y0 + x0] = 255 * ((s->nb_values + state) & 1); @@ -974,8 +1021,8 @@ static void draw_scope(OscilloscopeContext *s, int x0, int y0, int x1, int y1, if (s->draw.nb_planes == 1) { int i; - for (i = 0; i < s->draw.pixelstep[0]; i++) - AV_WN16(out->data[0] + out->linesize[0] * y0 + 2 * x0 * (s->draw.pixelstep[0] + i), (s->max - 1) * ((s->nb_values + state) & 1)); + for (i = 0; i < s->nb_comps; i++) + AV_WN16(out->data[0] + out->linesize[0] * y0 + x0 * s->draw.pixelstep[0] + i, (s->max - 1) * ((s->nb_values + state) & 1)); } else { AV_WN16(out->data[0] + out->linesize[0] * y0 + 2 * x0, (s->max - 1) * ((s->nb_values + state) & 1)); } diff --git a/libavfilter/vf_dblur.c b/libavfilter/vf_dblur.c index cc127da73..c4c37dec5 100644 --- a/libavfilter/vf_dblur.c +++ b/libavfilter/vf_dblur.c @@ -40,7 +40,6 @@ typedef struct DBlurContext { int planeheight[4]; float *buffer; int nb_planes; - void (*horiz_slice)(float *buffer, int width, int height, int steps, float nu, float bscale); } DBlurContext; #define OFFSET(x) offsetof(DBlurContext, x) diff --git a/libavfilter/vf_dctdnoiz.c b/libavfilter/vf_dctdnoiz.c index cdbe5f853..a89f2631c 100644 --- a/libavfilter/vf_dctdnoiz.c +++ b/libavfilter/vf_dctdnoiz.c @@ -30,6 +30,7 @@ #include "libavutil/avassert.h" #include "libavutil/eval.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "internal.h" diff --git a/libavfilter/vf_deband.c b/libavfilter/vf_deband.c index 330792f53..c05225d2b 100644 --- a/libavfilter/vf_deband.c +++ b/libavfilter/vf_deband.c @@ -49,7 +49,7 @@ typedef struct DebandContext { } DebandContext; #define OFFSET(x) offsetof(DebandContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption deband_options[] = { { "1thr", "set 1st plane threshold", OFFSET(threshold[0]), AV_OPT_TYPE_FLOAT, {.dbl=0.02}, 0.00003, 0.5, FLAGS }, @@ -117,7 +117,7 @@ static int query_formats(AVFilterContext *ctx) static float frand(int x, int y) { - const float r = sinf(x * 12.9898 + y * 78.233) * 43758.545; + const float r = sinf(x * 12.9898f + y * 78.233f) * 43758.545f; return r - floorf(r); } @@ -389,8 +389,10 @@ static int config_input(AVFilterLink *inlink) s->thr[2] = ((1 << desc->comp[2].depth) - 1) * s->threshold[2]; s->thr[3] = ((1 << desc->comp[3].depth) - 1) * s->threshold[3]; - s->x_pos = av_malloc(s->planewidth[0] * s->planeheight[0] * sizeof(*s->x_pos)); - s->y_pos = av_malloc(s->planewidth[0] * s->planeheight[0] * sizeof(*s->y_pos)); + if (!s->x_pos) + s->x_pos = av_malloc(s->planewidth[0] * s->planeheight[0] * sizeof(*s->x_pos)); + if (!s->y_pos) + s->y_pos = av_malloc(s->planewidth[0] * s->planeheight[0] * sizeof(*s->y_pos)); if (!s->x_pos || !s->y_pos) return AVERROR(ENOMEM); @@ -432,6 +434,17 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + + if (ret < 0) + return ret; + + return config_input(ctx->inputs[0]); +} + static av_cold void uninit(AVFilterContext *ctx) { DebandContext *s = ctx->priv; @@ -468,4 +481,5 @@ AVFilter ff_vf_deband = { .inputs = avfilter_vf_deband_inputs, .outputs = avfilter_vf_deband_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; diff --git a/libavfilter/vf_deblock.c b/libavfilter/vf_deblock.c index 77c681ecb..0671a6454 100644 --- a/libavfilter/vf_deblock.c +++ b/libavfilter/vf_deblock.c @@ -285,14 +285,14 @@ static int config_output(AVFilterLink *outlink) if (s->depth <= 8 && s->filter == WEAK) { s->deblockh = deblockh8_weak; s->deblockv = deblockv8_weak; - } else if (s->depth >= 8 && s->filter == WEAK) { + } else if (s->depth > 8 && s->filter == WEAK) { s->deblockh = deblockh16_weak; s->deblockv = deblockv16_weak; } if (s->depth <= 8 && s->filter == STRONG) { s->deblockh = deblockh8_strong; s->deblockv = deblockv8_strong; - } else if (s->depth >= 8 && s->filter == STRONG) { + } else if (s->depth > 8 && s->filter == STRONG) { s->deblockh = deblockh16_strong; s->deblockv = deblockv16_strong; } @@ -367,8 +367,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_output(ctx->outputs[0]); +} + #define OFFSET(x) offsetof(DeblockContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption deblock_options[] = { { "filter", "set type of filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=STRONG},0, 1, FLAGS, "filter" }, @@ -412,4 +424,5 @@ AVFilter ff_vf_deblock = { .inputs = inputs, .outputs = outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, + .process_command = process_command, }; diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c index 88a8b38a5..a76711f26 100644 --- a/libavfilter/vf_decimate.c +++ b/libavfilter/vf_decimate.c @@ -23,6 +23,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/timestamp.h" #include "avfilter.h" +#include "filters.h" #include "internal.h" #define INPUT_MAIN 0 @@ -43,6 +44,7 @@ typedef struct DecimateContext { AVFrame **clean_src; ///< frame queue for the clean source int got_frame[2]; ///< frame request flag for each input stream AVRational ts_unit; ///< timestamp units for the output frames + int64_t last_pts; ///< last output timestamp int64_t start_pts; ///< base for output timestamps uint32_t eof; ///< bitmask for end of stream int hsub, vsub; ///< chroma subsampling values @@ -165,11 +167,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) dm->got_frame[INPUT_MAIN] = dm->got_frame[INPUT_CLEANSRC] = 0; if (dm->ppsrc) - in = dm->clean_src[dm->fid]; + in = dm->queue[dm->fid].frame; if (in) { /* update frame metrics */ - prv = dm->fid ? (dm->ppsrc ? dm->clean_src[dm->fid - 1] : dm->queue[dm->fid - 1].frame) : dm->last; + prv = dm->fid ? dm->queue[dm->fid - 1].frame : dm->last; if (!prv) { dm->queue[dm->fid].maxbdiff = INT64_MAX; dm->queue[dm->fid].totdiff = INT64_MAX; @@ -223,10 +225,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if (dm->ppsrc) { av_frame_free(&frame); frame = dm->clean_src[i]; + if (!frame) + continue; dm->clean_src[i] = NULL; } frame->pts = av_rescale_q(outlink->frame_count_in, dm->ts_unit, (AVRational){1,1}) + (dm->start_pts == AV_NOPTS_VALUE ? 0 : dm->start_pts); + dm->last_pts = frame->pts; ret = ff_filter_frame(outlink, frame); if (ret < 0) break; @@ -236,36 +241,63 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ret; } -static int config_input(AVFilterLink *inlink) +static int activate(AVFilterContext *ctx) { - int max_value; - AVFilterContext *ctx = inlink->dst; DecimateContext *dm = ctx->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); - const int w = inlink->w; - const int h = inlink->h; + AVFrame *frame = NULL; + int ret = 0, status; + int64_t pts; - dm->hsub = pix_desc->log2_chroma_w; - dm->vsub = pix_desc->log2_chroma_h; - dm->depth = pix_desc->comp[0].depth; - max_value = (1 << dm->depth) - 1; - dm->scthresh = (int64_t)(((int64_t)max_value * w * h * dm->scthresh_flt) / 100); - dm->dupthresh = (int64_t)(((int64_t)max_value * dm->blockx * dm->blocky * dm->dupthresh_flt) / 100); - dm->nxblocks = (w + dm->blockx/2 - 1) / (dm->blockx/2); - dm->nyblocks = (h + dm->blocky/2 - 1) / (dm->blocky/2); - dm->bdiffsize = dm->nxblocks * dm->nyblocks; - dm->bdiffs = av_malloc_array(dm->bdiffsize, sizeof(*dm->bdiffs)); - dm->queue = av_calloc(dm->cycle, sizeof(*dm->queue)); + FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[0], ctx); - if (!dm->bdiffs || !dm->queue) - return AVERROR(ENOMEM); - - if (dm->ppsrc) { - dm->clean_src = av_calloc(dm->cycle, sizeof(*dm->clean_src)); - if (!dm->clean_src) - return AVERROR(ENOMEM); + if ((dm->got_frame[INPUT_MAIN] == 0) && !(dm->eof & (1 << INPUT_MAIN)) && + (ret = ff_inlink_consume_frame(ctx->inputs[INPUT_MAIN], &frame)) > 0) { + ret = filter_frame(ctx->inputs[INPUT_MAIN], frame); + if (ret < 0) + return ret; + } + if (ret < 0) + return ret; + if (dm->ppsrc && + (dm->got_frame[INPUT_CLEANSRC] == 0) && !(dm->eof & (1 << INPUT_CLEANSRC)) && + (ret = ff_inlink_consume_frame(ctx->inputs[INPUT_CLEANSRC], &frame)) > 0) { + ret = filter_frame(ctx->inputs[INPUT_CLEANSRC], frame); + if (ret < 0) + return ret; + } + if (ret < 0) { + return ret; + } else if (dm->eof == ((1 << INPUT_MAIN) | (dm->ppsrc << INPUT_CLEANSRC))) { + ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, dm->last_pts); + return 0; + } else if (!(dm->eof & (1 << INPUT_MAIN)) && ff_inlink_acknowledge_status(ctx->inputs[INPUT_MAIN], &status, &pts)) { + if (status == AVERROR_EOF) { // flushing + dm->eof |= 1 << INPUT_MAIN; + if (dm->ppsrc) + filter_frame(ctx->inputs[INPUT_CLEANSRC], NULL); + filter_frame(ctx->inputs[INPUT_MAIN], NULL); + ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, dm->last_pts); + return 0; + } + } else if (dm->ppsrc && !(dm->eof & (1 << INPUT_CLEANSRC)) && ff_inlink_acknowledge_status(ctx->inputs[INPUT_CLEANSRC], &status, &pts)) { + if (status == AVERROR_EOF) { // flushing + dm->eof |= 1 << INPUT_CLEANSRC; + filter_frame(ctx->inputs[INPUT_MAIN], NULL); + filter_frame(ctx->inputs[INPUT_CLEANSRC], NULL); + ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, dm->last_pts); + return 0; + } } + if (ff_inlink_queued_frames(ctx->inputs[INPUT_MAIN]) > 0 && + (dm->ppsrc && ff_inlink_queued_frames(ctx->inputs[INPUT_CLEANSRC]) > 0)) { + ff_filter_set_ready(ctx, 100); + } else if (ff_outlink_frame_wanted(ctx->outputs[0])) { + if (dm->got_frame[INPUT_MAIN] == 0) + ff_inlink_request_frame(ctx->inputs[INPUT_MAIN]); + if (dm->ppsrc && (dm->got_frame[INPUT_CLEANSRC] == 0)) + ff_inlink_request_frame(ctx->inputs[INPUT_CLEANSRC]); + } return 0; } @@ -273,29 +305,19 @@ static av_cold int decimate_init(AVFilterContext *ctx) { DecimateContext *dm = ctx->priv; AVFilterPad pad = { - .name = av_strdup("main"), + .name = "main", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_input, }; int ret; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, INPUT_MAIN, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, INPUT_MAIN, &pad)) < 0) return ret; - } if (dm->ppsrc) { - pad.name = av_strdup("clean_src"); + pad.name = "clean_src"; pad.config_props = NULL; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad)) < 0) return ret; - } } if ((dm->blockx & (dm->blockx - 1)) || @@ -326,40 +348,6 @@ static av_cold void decimate_uninit(AVFilterContext *ctx) av_frame_free(&dm->clean_src[i]); } av_freep(&dm->clean_src); - for (i = 0; i < ctx->nb_inputs; i++) - av_freep(&ctx->input_pads[i].name); -} - -static int request_inlink(AVFilterContext *ctx, int lid) -{ - int ret = 0; - DecimateContext *dm = ctx->priv; - - if (!dm->got_frame[lid]) { - AVFilterLink *inlink = ctx->inputs[lid]; - ret = ff_request_frame(inlink); - if (ret == AVERROR_EOF) { // flushing - dm->eof |= 1 << lid; - ret = filter_frame(inlink, NULL); - } - } - return ret; -} - -static int request_frame(AVFilterLink *outlink) -{ - int ret; - AVFilterContext *ctx = outlink->src; - DecimateContext *dm = ctx->priv; - const uint32_t eof_mask = 1<ppsrc<eof & eof_mask) == eof_mask) // flush done? - return AVERROR_EOF; - if ((ret = request_inlink(ctx, INPUT_MAIN)) < 0) - return ret; - if (dm->ppsrc && (ret = request_inlink(ctx, INPUT_CLEANSRC)) < 0) - return ret; - return 0; } static int query_formats(AVFilterContext *ctx) @@ -369,8 +357,12 @@ static int query_formats(AVFilterContext *ctx) #define PF_ALPHA(suf) AV_PIX_FMT_YUVA420##suf, AV_PIX_FMT_YUVA422##suf, AV_PIX_FMT_YUVA444##suf #define PF(suf) PF_NOALPHA(suf), PF_ALPHA(suf) PF(P), PF(P9), PF(P10), PF_NOALPHA(P12), PF_NOALPHA(P14), PF(P16), + AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, + AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, + AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); @@ -383,9 +375,33 @@ static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; DecimateContext *dm = ctx->priv; - const AVFilterLink *inlink = - ctx->inputs[dm->ppsrc ? INPUT_CLEANSRC : INPUT_MAIN]; + const AVFilterLink *inlink = ctx->inputs[INPUT_MAIN]; AVRational fps = inlink->frame_rate; + int max_value; + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); + const int w = inlink->w; + const int h = inlink->h; + + dm->hsub = pix_desc->log2_chroma_w; + dm->vsub = pix_desc->log2_chroma_h; + dm->depth = pix_desc->comp[0].depth; + max_value = (1 << dm->depth) - 1; + dm->scthresh = (int64_t)(((int64_t)max_value * w * h * dm->scthresh_flt) / 100); + dm->dupthresh = (int64_t)(((int64_t)max_value * dm->blockx * dm->blocky * dm->dupthresh_flt) / 100); + dm->nxblocks = (w + dm->blockx/2 - 1) / (dm->blockx/2); + dm->nyblocks = (h + dm->blocky/2 - 1) / (dm->blocky/2); + dm->bdiffsize = dm->nxblocks * dm->nyblocks; + dm->bdiffs = av_malloc_array(dm->bdiffsize, sizeof(*dm->bdiffs)); + dm->queue = av_calloc(dm->cycle, sizeof(*dm->queue)); + + if (!dm->bdiffs || !dm->queue) + return AVERROR(ENOMEM); + + if (dm->ppsrc) { + dm->clean_src = av_calloc(dm->cycle, sizeof(*dm->clean_src)); + if (!dm->clean_src) + return AVERROR(ENOMEM); + } if (!fps.num || !fps.den) { av_log(ctx, AV_LOG_ERROR, "The input needs a constant frame rate; " @@ -398,8 +414,13 @@ static int config_output(AVFilterLink *outlink) outlink->time_base = inlink->time_base; outlink->frame_rate = fps; outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; - outlink->w = inlink->w; - outlink->h = inlink->h; + if (dm->ppsrc) { + outlink->w = ctx->inputs[INPUT_CLEANSRC]->w; + outlink->h = ctx->inputs[INPUT_CLEANSRC]->h; + } else { + outlink->w = inlink->w; + outlink->h = inlink->h; + } dm->ts_unit = av_inv_q(av_mul_q(fps, outlink->time_base)); return 0; } @@ -408,7 +429,6 @@ static const AVFilterPad decimate_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = config_output, }, { NULL } @@ -418,6 +438,7 @@ AVFilter ff_vf_decimate = { .name = "decimate", .description = NULL_IF_CONFIG_SMALL("Decimate frames (post field matching filter)."), .init = decimate_init, + .activate = activate, .uninit = decimate_uninit, .priv_size = sizeof(DecimateContext), .query_formats = query_formats, diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c index 80217c841..89a282f99 100644 --- a/libavfilter/vf_deinterlace_qsv.c +++ b/libavfilter/vf_deinterlace_qsv.c @@ -202,16 +202,20 @@ static int init_out_session(AVFilterContext *ctx) } } - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error getting the session handle\n"); + if (err < 0) + return ff_qsvvpp_print_error(ctx, err, "Error getting the session handle"); + else if (err > 0) { + ff_qsvvpp_print_warning(ctx, err, "Warning in getting the session handle"); return AVERROR_UNKNOWN; } /* create a "slave" session with those same properties, to be used for * actual deinterlacing */ err = MFXInit(impl, &ver, &s->session); - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error initializing a session for deinterlacing\n"); + if (err < 0) + return ff_qsvvpp_print_error(ctx, err, "Error initializing a session for deinterlacing"); + else if (err > 0) { + ff_qsvvpp_print_warning(ctx, err, "Warning in session initialization"); return AVERROR_UNKNOWN; } @@ -309,9 +313,17 @@ static int init_out_session(AVFilterContext *ctx) par.vpp.Out.FrameRateExtD = ctx->outputs[0]->time_base.den; } + /* Print input memory mode */ + ff_qsvvpp_print_iopattern(ctx, par.IOPattern & 0x0F, "VPP"); + /* Print output memory mode */ + ff_qsvvpp_print_iopattern(ctx, par.IOPattern & 0xF0, "VPP"); err = MFXVideoVPP_Init(s->session, &par); - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error opening the VPP for deinterlacing: %d\n", err); + if (err < 0) + return ff_qsvvpp_print_error(ctx, err, + "Error opening the VPP for deinterlacing"); + else if (err > 0) { + ff_qsvvpp_print_warning(ctx, err, + "Warning in VPP initialization"); return AVERROR_UNKNOWN; } @@ -482,8 +494,13 @@ static int process_frame(AVFilterContext *ctx, const AVFrame *in, return QSVDEINT_MORE_INPUT; } - if ((err < 0 && err != MFX_ERR_MORE_SURFACE) || !sync) { - av_log(ctx, AV_LOG_ERROR, "Error during deinterlacing: %d\n", err); + if (err < 0 && err != MFX_ERR_MORE_SURFACE) { + ret = ff_qsvvpp_print_error(ctx, err, "Error during deinterlacing"); + goto fail; + } + + if (!sync) { + av_log(ctx, AV_LOG_ERROR, "No sync during deinterlacing\n"); ret = AVERROR_UNKNOWN; goto fail; } @@ -494,8 +511,7 @@ static int process_frame(AVFilterContext *ctx, const AVFrame *in, err = MFXVideoCORE_SyncOperation(s->session, sync, 1000); } while (err == MFX_WRN_IN_EXECUTION); if (err < 0) { - av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err); - ret = AVERROR_UNKNOWN; + ret = ff_qsvvpp_print_error(ctx, err, "Error synchronizing the operation"); goto fail; } diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index e55673d5a..6069c3016 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -55,7 +55,6 @@ enum var_name { VAR_T, VAR_VARS_NB }; -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx) { diff --git a/libavfilter/vf_derain.c b/libavfilter/vf_derain.c index 74322602b..7814fc1e0 100644 --- a/libavfilter/vf_derain.c +++ b/libavfilter/vf_derain.c @@ -27,35 +27,30 @@ #include "libavformat/avio.h" #include "libavutil/opt.h" #include "avfilter.h" -#include "dnn_interface.h" +#include "dnn_filter_common.h" #include "formats.h" #include "internal.h" typedef struct DRContext { const AVClass *class; - + DnnContext dnnctx; int filter_type; - char *model_filename; - DNNBackendType backend_type; - DNNModule *dnn_module; - DNNModel *model; - DNNData input; - DNNData output; } DRContext; -#define CLIP(x, min, max) (x < min ? min : (x > max ? max : x)) #define OFFSET(x) offsetof(DRContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM static const AVOption derain_options[] = { { "filter_type", "filter type(derain/dehaze)", OFFSET(filter_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, "type" }, { "derain", "derain filter flag", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "type" }, { "dehaze", "dehaze filter flag", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "type" }, - { "dnn_backend", "DNN backend", OFFSET(backend_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, "backend" }, + { "dnn_backend", "DNN backend", OFFSET(dnnctx.backend_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, "backend" }, { "native", "native backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "backend" }, #if (CONFIG_LIBTENSORFLOW == 1) { "tensorflow", "tensorflow backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "backend" }, #endif - { "model", "path to model file", OFFSET(model_filename), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, + { "model", "path to model file", OFFSET(dnnctx.model_filename), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, + { "input", "input name of the model", OFFSET(dnnctx.model_inputname), AV_OPT_TYPE_STRING, { .str = "x" }, 0, 0, FLAGS }, + { "output", "output name of the model", OFFSET(dnnctx.model_outputname), AV_OPT_TYPE_STRING, { .str = "y" }, 0, 0, FLAGS }, { NULL } }; @@ -74,69 +69,29 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, formats); } -static int config_inputs(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - DRContext *dr_context = ctx->priv; - const char *model_output_name = "y"; - DNNReturnType result; - - dr_context->input.width = inlink->w; - dr_context->input.height = inlink->h; - dr_context->input.channels = 3; - - result = (dr_context->model->set_input_output)(dr_context->model->model, &dr_context->input, "x", &model_output_name, 1); - if (result != DNN_SUCCESS) { - av_log(ctx, AV_LOG_ERROR, "could not set input and output for the model\n"); - return AVERROR(EIO); - } - - return 0; -} - static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; DRContext *dr_context = ctx->priv; DNNReturnType dnn_result; + AVFrame *out; - AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { av_log(ctx, AV_LOG_ERROR, "could not allocate memory for output frame\n"); av_frame_free(&in); return AVERROR(ENOMEM); } - av_frame_copy_props(out, in); - for (int i = 0; i < in->height; i++){ - for(int j = 0; j < in->width * 3; j++){ - int k = i * in->linesize[0] + j; - int t = i * in->width * 3 + j; - ((float *)dr_context->input.data)[t] = in->data[0][k] / 255.0; - } - } - - dnn_result = (dr_context->dnn_module->execute_model)(dr_context->model, &dr_context->output, 1); + dnn_result = ff_dnn_execute_model(&dr_context->dnnctx, in, out); if (dnn_result != DNN_SUCCESS){ av_log(ctx, AV_LOG_ERROR, "failed to execute model\n"); + av_frame_free(&in); return AVERROR(EIO); } - out->height = dr_context->output.height; - out->width = dr_context->output.width; - outlink->h = dr_context->output.height; - outlink->w = dr_context->output.width; - - for (int i = 0; i < out->height; i++){ - for(int j = 0; j < out->width * 3; j++){ - int k = i * out->linesize[0] + j; - int t = i * out->width * 3 + j; - out->data[0][k] = CLIP((int)((((float *)dr_context->output.data)[t]) * 255), 0, 255); - } - } - av_frame_free(&in); return ff_filter_frame(outlink, out); @@ -145,46 +100,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) static av_cold int init(AVFilterContext *ctx) { DRContext *dr_context = ctx->priv; - - dr_context->input.dt = DNN_FLOAT; - dr_context->dnn_module = ff_get_dnn_module(dr_context->backend_type); - if (!dr_context->dnn_module) { - av_log(ctx, AV_LOG_ERROR, "could not create DNN module for requested backend\n"); - return AVERROR(ENOMEM); - } - if (!dr_context->model_filename) { - av_log(ctx, AV_LOG_ERROR, "model file for network is not specified\n"); - return AVERROR(EINVAL); - } - if (!dr_context->dnn_module->load_model) { - av_log(ctx, AV_LOG_ERROR, "load_model for network is not specified\n"); - return AVERROR(EINVAL); - } - - dr_context->model = (dr_context->dnn_module->load_model)(dr_context->model_filename); - if (!dr_context->model) { - av_log(ctx, AV_LOG_ERROR, "could not load DNN model\n"); - return AVERROR(EINVAL); - } - - return 0; + return ff_dnn_init(&dr_context->dnnctx, DFT_PROCESS_FRAME, ctx); } static av_cold void uninit(AVFilterContext *ctx) { DRContext *dr_context = ctx->priv; - - if (dr_context->dnn_module) { - (dr_context->dnn_module->free_model)(&dr_context->model); - av_freep(&dr_context->dnn_module); - } + ff_dnn_uninit(&dr_context->dnnctx); } static const AVFilterPad derain_inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_inputs, .filter_frame = filter_frame, }, { NULL } diff --git a/libavfilter/vf_despill.c b/libavfilter/vf_despill.c index 64c27f406..bf6c7ca2c 100644 --- a/libavfilter/vf_despill.c +++ b/libavfilter/vf_despill.c @@ -153,7 +153,7 @@ static const AVFilterPad despill_outputs[] = { }; #define OFFSET(x) offsetof(DespillContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption despill_options[] = { { "type", "set the screen type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "type" }, @@ -179,5 +179,6 @@ AVFilter ff_vf_despill = { .query_formats = query_formats, .inputs = despill_inputs, .outputs = despill_outputs, + .process_command = ff_filter_process_command, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/vf_detelecine.c b/libavfilter/vf_detelecine.c index 0199214c3..f02f85d60 100644 --- a/libavfilter/vf_detelecine.c +++ b/libavfilter/vf_detelecine.c @@ -124,19 +124,16 @@ static av_cold int init(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { - AVFilterFormats *pix_fmts = NULL; - int fmt, ret; + AVFilterFormats *formats = NULL; + int ret; - for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL || - desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) && - (ret = ff_add_format(&pix_fmts, fmt)) < 0) - return ret; - } - - return ff_set_common_formats(ctx, pix_fmts); + ret = ff_formats_pixdesc_filter(&formats, 0, + AV_PIX_FMT_FLAG_BITSTREAM | + AV_PIX_FMT_FLAG_PAL | + AV_PIX_FMT_FLAG_HWACCEL); + if (ret < 0) + return ret; + return ff_set_common_formats(ctx, formats); } static int config_input(AVFilterLink *inlink) diff --git a/libavfilter/vf_dnn_processing.c b/libavfilter/vf_dnn_processing.c index cf589aced..88e95e8ae 100644 --- a/libavfilter/vf_dnn_processing.c +++ b/libavfilter/vf_dnn_processing.c @@ -28,44 +28,32 @@ #include "libavutil/pixdesc.h" #include "libavutil/avassert.h" #include "libavutil/imgutils.h" -#include "avfilter.h" -#include "dnn_interface.h" +#include "filters.h" +#include "dnn_filter_common.h" #include "formats.h" #include "internal.h" #include "libswscale/swscale.h" +#include "libavutil/time.h" typedef struct DnnProcessingContext { const AVClass *class; - - char *model_filename; - DNNBackendType backend_type; - char *model_inputname; - char *model_outputname; - - DNNModule *dnn_module; - DNNModel *model; - - // input & output of the model at execution time - DNNData input; - DNNData output; - - struct SwsContext *sws_gray8_to_grayf32; - struct SwsContext *sws_grayf32_to_gray8; + DnnContext dnnctx; struct SwsContext *sws_uv_scale; int sws_uv_height; } DnnProcessingContext; -#define OFFSET(x) offsetof(DnnProcessingContext, x) +#define OFFSET(x) offsetof(DnnProcessingContext, dnnctx.x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM static const AVOption dnn_processing_options[] = { - { "dnn_backend", "DNN backend", OFFSET(backend_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, "backend" }, + { "dnn_backend", "DNN backend", OFFSET(backend_type), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "backend" }, { "native", "native backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "backend" }, #if (CONFIG_LIBTENSORFLOW == 1) { "tensorflow", "tensorflow backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "backend" }, #endif - { "model", "path to model file", OFFSET(model_filename), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, - { "input", "input name of the model", OFFSET(model_inputname), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, - { "output", "output name of the model", OFFSET(model_outputname), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, +#if (CONFIG_LIBOPENVINO == 1) + { "openvino", "openvino backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, "backend" }, +#endif + DNN_COMMON_OPTIONS { NULL } }; @@ -74,37 +62,7 @@ AVFILTER_DEFINE_CLASS(dnn_processing); static av_cold int init(AVFilterContext *context) { DnnProcessingContext *ctx = context->priv; - - if (!ctx->model_filename) { - av_log(ctx, AV_LOG_ERROR, "model file for network is not specified\n"); - return AVERROR(EINVAL); - } - if (!ctx->model_inputname) { - av_log(ctx, AV_LOG_ERROR, "input name of the model network is not specified\n"); - return AVERROR(EINVAL); - } - if (!ctx->model_outputname) { - av_log(ctx, AV_LOG_ERROR, "output name of the model network is not specified\n"); - return AVERROR(EINVAL); - } - - ctx->dnn_module = ff_get_dnn_module(ctx->backend_type); - if (!ctx->dnn_module) { - av_log(ctx, AV_LOG_ERROR, "could not create DNN module for requested backend\n"); - return AVERROR(ENOMEM); - } - if (!ctx->dnn_module->load_model) { - av_log(ctx, AV_LOG_ERROR, "load_model for network is not specified\n"); - return AVERROR(EINVAL); - } - - ctx->model = (ctx->dnn_module->load_model)(ctx->model_filename); - if (!ctx->model) { - av_log(ctx, AV_LOG_ERROR, "could not load DNN model\n"); - return AVERROR(EINVAL); - } - - return 0; + return ff_dnn_init(&ctx->dnnctx, DFT_PROCESS_FRAME, context); } static int query_formats(AVFilterContext *context) @@ -114,6 +72,7 @@ static int query_formats(AVFilterContext *context) AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAYF32, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_NV12, AV_PIX_FMT_NONE }; AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); @@ -143,6 +102,10 @@ static int check_modelinput_inlink(const DNNData *model_input, const AVFilterLin model_input->width, inlink->w); return AVERROR(EIO); } + if (model_input->dt != DNN_FLOAT) { + avpriv_report_missing_feature(ctx, "data type rather than DNN_FLOAT"); + return AVERROR(EIO); + } switch (fmt) { case AV_PIX_FMT_RGB24: @@ -151,20 +114,6 @@ static int check_modelinput_inlink(const DNNData *model_input, const AVFilterLin LOG_FORMAT_CHANNEL_MISMATCH(); return AVERROR(EIO); } - if (model_input->dt != DNN_FLOAT && model_input->dt != DNN_UINT8) { - av_log(ctx, AV_LOG_ERROR, "only support dnn models with input data type as float32 and uint8.\n"); - return AVERROR(EIO); - } - return 0; - case AV_PIX_FMT_GRAY8: - if (model_input->channels != 1) { - LOG_FORMAT_CHANNEL_MISMATCH(); - return AVERROR(EIO); - } - if (model_input->dt != DNN_UINT8) { - av_log(ctx, AV_LOG_ERROR, "only support dnn models with input data type uint8.\n"); - return AVERROR(EIO); - } return 0; case AV_PIX_FMT_GRAYF32: case AV_PIX_FMT_YUV420P: @@ -172,17 +121,14 @@ static int check_modelinput_inlink(const DNNData *model_input, const AVFilterLin case AV_PIX_FMT_YUV444P: case AV_PIX_FMT_YUV410P: case AV_PIX_FMT_YUV411P: + case AV_PIX_FMT_NV12: if (model_input->channels != 1) { LOG_FORMAT_CHANNEL_MISMATCH(); return AVERROR(EIO); } - if (model_input->dt != DNN_FLOAT) { - av_log(ctx, AV_LOG_ERROR, "only support dnn models with input data type float32.\n"); - return AVERROR(EIO); - } return 0; default: - av_log(ctx, AV_LOG_ERROR, "%s not supported.\n", av_get_pix_fmt_name(fmt)); + avpriv_report_missing_feature(ctx, "%s", av_get_pix_fmt_name(fmt)); return AVERROR(EIO); } @@ -197,7 +143,7 @@ static int config_input(AVFilterLink *inlink) DNNData model_input; int check; - result = ctx->model->get_input(ctx->model->model, &model_input, ctx->model_inputname); + result = ff_dnn_get_input(&ctx->dnnctx, &model_input); if (result != DNN_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "could not get input from the model\n"); return AVERROR(EIO); @@ -208,90 +154,42 @@ static int config_input(AVFilterLink *inlink) return check; } - ctx->input.width = inlink->w; - ctx->input.height = inlink->h; - ctx->input.channels = model_input.channels; - ctx->input.dt = model_input.dt; - - result = (ctx->model->set_input_output)(ctx->model->model, - &ctx->input, ctx->model_inputname, - (const char **)&ctx->model_outputname, 1); - if (result != DNN_SUCCESS) { - av_log(ctx, AV_LOG_ERROR, "could not set input and output for the model\n"); - return AVERROR(EIO); - } - return 0; } -static int prepare_sws_context(AVFilterLink *outlink) +static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + av_assert0(desc); + return !(desc->flags & AV_PIX_FMT_FLAG_RGB) && desc->nb_components == 3; +} + +static int prepare_uv_scale(AVFilterLink *outlink) { AVFilterContext *context = outlink->src; DnnProcessingContext *ctx = context->priv; AVFilterLink *inlink = context->inputs[0]; enum AVPixelFormat fmt = inlink->format; - DNNDataType input_dt = ctx->input.dt; - DNNDataType output_dt = ctx->output.dt; - - switch (fmt) { - case AV_PIX_FMT_RGB24: - case AV_PIX_FMT_BGR24: - if (input_dt == DNN_FLOAT) { - ctx->sws_gray8_to_grayf32 = sws_getContext(inlink->w * 3, - inlink->h, - AV_PIX_FMT_GRAY8, - inlink->w * 3, - inlink->h, - AV_PIX_FMT_GRAYF32, - 0, NULL, NULL, NULL); - } - if (output_dt == DNN_FLOAT) { - ctx->sws_grayf32_to_gray8 = sws_getContext(outlink->w * 3, - outlink->h, - AV_PIX_FMT_GRAYF32, - outlink->w * 3, - outlink->h, - AV_PIX_FMT_GRAY8, - 0, NULL, NULL, NULL); - } - return 0; - case AV_PIX_FMT_YUV420P: - case AV_PIX_FMT_YUV422P: - case AV_PIX_FMT_YUV444P: - case AV_PIX_FMT_YUV410P: - case AV_PIX_FMT_YUV411P: - av_assert0(input_dt == DNN_FLOAT); - av_assert0(output_dt == DNN_FLOAT); - ctx->sws_gray8_to_grayf32 = sws_getContext(inlink->w, - inlink->h, - AV_PIX_FMT_GRAY8, - inlink->w, - inlink->h, - AV_PIX_FMT_GRAYF32, - 0, NULL, NULL, NULL); - ctx->sws_grayf32_to_gray8 = sws_getContext(outlink->w, - outlink->h, - AV_PIX_FMT_GRAYF32, - outlink->w, - outlink->h, - AV_PIX_FMT_GRAY8, - 0, NULL, NULL, NULL); + if (isPlanarYUV(fmt)) { if (inlink->w != outlink->w || inlink->h != outlink->h) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - int sws_src_h = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); - int sws_src_w = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); - int sws_dst_h = AV_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h); - int sws_dst_w = AV_CEIL_RSHIFT(outlink->w, desc->log2_chroma_w); - ctx->sws_uv_scale = sws_getContext(sws_src_w, sws_src_h, AV_PIX_FMT_GRAY8, - sws_dst_w, sws_dst_h, AV_PIX_FMT_GRAY8, - SWS_BICUBIC, NULL, NULL, NULL); - ctx->sws_uv_height = sws_src_h; + if (fmt == AV_PIX_FMT_NV12) { + ctx->sws_uv_scale = sws_getContext(inlink->w >> 1, inlink->h >> 1, AV_PIX_FMT_YA8, + outlink->w >> 1, outlink->h >> 1, AV_PIX_FMT_YA8, + SWS_BICUBIC, NULL, NULL, NULL); + ctx->sws_uv_height = inlink->h >> 1; + } else { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); + int sws_src_h = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + int sws_src_w = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + int sws_dst_h = AV_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h); + int sws_dst_w = AV_CEIL_RSHIFT(outlink->w, desc->log2_chroma_w); + ctx->sws_uv_scale = sws_getContext(sws_src_w, sws_src_h, AV_PIX_FMT_GRAY8, + sws_dst_w, sws_dst_h, AV_PIX_FMT_GRAY8, + SWS_BICUBIC, NULL, NULL, NULL); + ctx->sws_uv_height = sws_src_h; + } } - return 0; - default: - //do nothing - break; } return 0; @@ -302,120 +200,20 @@ static int config_output(AVFilterLink *outlink) AVFilterContext *context = outlink->src; DnnProcessingContext *ctx = context->priv; DNNReturnType result; + AVFilterLink *inlink = context->inputs[0]; // have a try run in case that the dnn model resize the frame - result = (ctx->dnn_module->execute_model)(ctx->model, &ctx->output, 1); - if (result != DNN_SUCCESS){ - av_log(ctx, AV_LOG_ERROR, "failed to execute model\n"); + result = ff_dnn_get_output(&ctx->dnnctx, inlink->w, inlink->h, &outlink->w, &outlink->h); + if (result != DNN_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "could not get output from the model\n"); return AVERROR(EIO); } - outlink->w = ctx->output.width; - outlink->h = ctx->output.height; - - prepare_sws_context(outlink); + prepare_uv_scale(outlink); return 0; } -static int copy_from_frame_to_dnn(DnnProcessingContext *ctx, const AVFrame *frame) -{ - int bytewidth = av_image_get_linesize(frame->format, frame->width, 0); - DNNData *dnn_input = &ctx->input; - - switch (frame->format) { - case AV_PIX_FMT_RGB24: - case AV_PIX_FMT_BGR24: - if (dnn_input->dt == DNN_FLOAT) { - sws_scale(ctx->sws_gray8_to_grayf32, (const uint8_t **)frame->data, frame->linesize, - 0, frame->height, (uint8_t * const*)(&dnn_input->data), - (const int [4]){frame->width * 3 * sizeof(float), 0, 0, 0}); - } else { - av_assert0(dnn_input->dt == DNN_UINT8); - av_image_copy_plane(dnn_input->data, bytewidth, - frame->data[0], frame->linesize[0], - bytewidth, frame->height); - } - return 0; - case AV_PIX_FMT_GRAY8: - case AV_PIX_FMT_GRAYF32: - av_image_copy_plane(dnn_input->data, bytewidth, - frame->data[0], frame->linesize[0], - bytewidth, frame->height); - return 0; - case AV_PIX_FMT_YUV420P: - case AV_PIX_FMT_YUV422P: - case AV_PIX_FMT_YUV444P: - case AV_PIX_FMT_YUV410P: - case AV_PIX_FMT_YUV411P: - sws_scale(ctx->sws_gray8_to_grayf32, (const uint8_t **)frame->data, frame->linesize, - 0, frame->height, (uint8_t * const*)(&dnn_input->data), - (const int [4]){frame->width * sizeof(float), 0, 0, 0}); - return 0; - default: - return AVERROR(EIO); - } - - return 0; -} - -static int copy_from_dnn_to_frame(DnnProcessingContext *ctx, AVFrame *frame) -{ - int bytewidth = av_image_get_linesize(frame->format, frame->width, 0); - DNNData *dnn_output = &ctx->output; - - switch (frame->format) { - case AV_PIX_FMT_RGB24: - case AV_PIX_FMT_BGR24: - if (dnn_output->dt == DNN_FLOAT) { - sws_scale(ctx->sws_grayf32_to_gray8, (const uint8_t *[4]){(const uint8_t *)dnn_output->data, 0, 0, 0}, - (const int[4]){frame->width * 3 * sizeof(float), 0, 0, 0}, - 0, frame->height, (uint8_t * const*)frame->data, frame->linesize); - - } else { - av_assert0(dnn_output->dt == DNN_UINT8); - av_image_copy_plane(frame->data[0], frame->linesize[0], - dnn_output->data, bytewidth, - bytewidth, frame->height); - } - return 0; - case AV_PIX_FMT_GRAY8: - // it is possible that data type of dnn output is float32, - // need to add support for such case when needed. - av_assert0(dnn_output->dt == DNN_UINT8); - av_image_copy_plane(frame->data[0], frame->linesize[0], - dnn_output->data, bytewidth, - bytewidth, frame->height); - return 0; - case AV_PIX_FMT_GRAYF32: - av_assert0(dnn_output->dt == DNN_FLOAT); - av_image_copy_plane(frame->data[0], frame->linesize[0], - dnn_output->data, bytewidth, - bytewidth, frame->height); - return 0; - case AV_PIX_FMT_YUV420P: - case AV_PIX_FMT_YUV422P: - case AV_PIX_FMT_YUV444P: - case AV_PIX_FMT_YUV410P: - case AV_PIX_FMT_YUV411P: - sws_scale(ctx->sws_grayf32_to_gray8, (const uint8_t *[4]){(const uint8_t *)dnn_output->data, 0, 0, 0}, - (const int[4]){frame->width * sizeof(float), 0, 0, 0}, - 0, frame->height, (uint8_t * const*)frame->data, frame->linesize); - return 0; - default: - return AVERROR(EIO); - } - - return 0; -} - -static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - av_assert0(desc); - return !(desc->flags & AV_PIX_FMT_FLAG_RGB) && desc->nb_components == 3; -} - static int copy_uv_planes(DnnProcessingContext *ctx, AVFrame *out, const AVFrame *in) { const AVPixFmtDescriptor *desc; @@ -431,6 +229,9 @@ static int copy_uv_planes(DnnProcessingContext *ctx, AVFrame *out, const AVFrame in->data[i], in->linesize[i], bytewidth, uv_height); } + } else if (in->format == AV_PIX_FMT_NV12) { + sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 1), in->linesize + 1, + 0, ctx->sws_uv_height, out->data + 1, out->linesize + 1); } else { sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 1), in->linesize + 1, 0, ctx->sws_uv_height, out->data + 1, out->linesize + 1); @@ -449,23 +250,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) DNNReturnType dnn_result; AVFrame *out; - copy_from_frame_to_dnn(ctx, in); - - dnn_result = (ctx->dnn_module->execute_model)(ctx->model, &ctx->output, 1); - if (dnn_result != DNN_SUCCESS){ - av_log(ctx, AV_LOG_ERROR, "failed to execute model\n"); - av_frame_free(&in); - return AVERROR(EIO); - } - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { av_frame_free(&in); return AVERROR(ENOMEM); } - av_frame_copy_props(out, in); - copy_from_dnn_to_frame(ctx, out); + + dnn_result = ff_dnn_execute_model(&ctx->dnnctx, in, out); + if (dnn_result != DNN_SUCCESS){ + av_log(ctx, AV_LOG_ERROR, "failed to execute model\n"); + av_frame_free(&in); + av_frame_free(&out); + return AVERROR(EIO); + } if (isPlanarYUV(in->format)) copy_uv_planes(ctx, out, in); @@ -474,18 +272,158 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int activate_sync(AVFilterContext *filter_ctx) +{ + AVFilterLink *inlink = filter_ctx->inputs[0]; + AVFilterLink *outlink = filter_ctx->outputs[0]; + AVFrame *in = NULL; + int64_t pts; + int ret, status; + int got_frame = 0; + + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); + + do { + // drain all input frames + ret = ff_inlink_consume_frame(inlink, &in); + if (ret < 0) + return ret; + if (ret > 0) { + ret = filter_frame(inlink, in); + if (ret < 0) + return ret; + got_frame = 1; + } + } while (ret > 0); + + // if frame got, schedule to next filter + if (got_frame) + return 0; + + if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { + if (status == AVERROR_EOF) { + ff_outlink_set_status(outlink, status, pts); + return ret; + } + } + + FF_FILTER_FORWARD_WANTED(outlink, inlink); + + return FFERROR_NOT_READY; +} + +static int flush_frame(AVFilterLink *outlink, int64_t pts, int64_t *out_pts) +{ + DnnProcessingContext *ctx = outlink->src->priv; + int ret; + DNNAsyncStatusType async_state; + + ret = ff_dnn_flush(&ctx->dnnctx); + if (ret != DNN_SUCCESS) { + return -1; + } + + do { + AVFrame *in_frame = NULL; + AVFrame *out_frame = NULL; + async_state = ff_dnn_get_async_result(&ctx->dnnctx, &in_frame, &out_frame); + if (out_frame) { + if (isPlanarYUV(in_frame->format)) + copy_uv_planes(ctx, out_frame, in_frame); + av_frame_free(&in_frame); + ret = ff_filter_frame(outlink, out_frame); + if (ret < 0) + return ret; + if (out_pts) + *out_pts = out_frame->pts + pts; + } + av_usleep(5000); + } while (async_state >= DAST_NOT_READY); + + return 0; +} + +static int activate_async(AVFilterContext *filter_ctx) +{ + AVFilterLink *inlink = filter_ctx->inputs[0]; + AVFilterLink *outlink = filter_ctx->outputs[0]; + DnnProcessingContext *ctx = filter_ctx->priv; + AVFrame *in = NULL, *out = NULL; + int64_t pts; + int ret, status; + int got_frame = 0; + int async_state; + + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); + + do { + // drain all input frames + ret = ff_inlink_consume_frame(inlink, &in); + if (ret < 0) + return ret; + if (ret > 0) { + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + if (ff_dnn_execute_model_async(&ctx->dnnctx, in, out) != DNN_SUCCESS) { + return AVERROR(EIO); + } + } + } while (ret > 0); + + // drain all processed frames + do { + AVFrame *in_frame = NULL; + AVFrame *out_frame = NULL; + async_state = ff_dnn_get_async_result(&ctx->dnnctx, &in_frame, &out_frame); + if (out_frame) { + if (isPlanarYUV(in_frame->format)) + copy_uv_planes(ctx, out_frame, in_frame); + av_frame_free(&in_frame); + ret = ff_filter_frame(outlink, out_frame); + if (ret < 0) + return ret; + got_frame = 1; + } + } while (async_state == DAST_SUCCESS); + + // if frame got, schedule to next filter + if (got_frame) + return 0; + + if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { + if (status == AVERROR_EOF) { + int64_t out_pts = pts; + ret = flush_frame(outlink, pts, &out_pts); + ff_outlink_set_status(outlink, status, out_pts); + return ret; + } + } + + FF_FILTER_FORWARD_WANTED(outlink, inlink); + + return 0; +} + +static int activate(AVFilterContext *filter_ctx) +{ + DnnProcessingContext *ctx = filter_ctx->priv; + + if (ctx->dnnctx.async) + return activate_async(filter_ctx); + else + return activate_sync(filter_ctx); +} + static av_cold void uninit(AVFilterContext *ctx) { DnnProcessingContext *context = ctx->priv; - sws_freeContext(context->sws_gray8_to_grayf32); - sws_freeContext(context->sws_grayf32_to_gray8); sws_freeContext(context->sws_uv_scale); - - if (context->dnn_module) - (context->dnn_module->free_model)(&context->model); - - av_freep(&context->dnn_module); + ff_dnn_uninit(&context->dnnctx); } static const AVFilterPad dnn_processing_inputs[] = { @@ -493,7 +431,6 @@ static const AVFilterPad dnn_processing_inputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_input, - .filter_frame = filter_frame, }, { NULL } }; @@ -517,4 +454,5 @@ AVFilter ff_vf_dnn_processing = { .inputs = dnn_processing_inputs, .outputs = dnn_processing_outputs, .priv_class = &dnn_processing_class, + .activate = activate, }; diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c index 21d520e52..6151db4d2 100644 --- a/libavfilter/vf_drawbox.c +++ b/libavfilter/vf_drawbox.c @@ -322,7 +322,7 @@ static const AVOption drawbox_options[] = { { "c", "set color of the box", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, 0, 0, FLAGS }, { "thickness", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, 0, 0, FLAGS }, { "t", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, 0, 0, FLAGS }, - { "replace", "replace color & alpha", OFFSET(replace), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, FLAGS }, + { "replace", "replace color & alpha", OFFSET(replace), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, FLAGS }, { NULL } }; diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index abe1ca6c3..7b1000e5b 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -568,6 +568,11 @@ static int load_font(AVFilterContext *ctx) return err; } +static inline int is_newline(uint32_t c) +{ + return c == '\n' || c == '\r' || c == '\f' || c == '\v'; +} + static int load_textfile(AVFilterContext *ctx) { DrawTextContext *s = ctx->priv; @@ -583,6 +588,8 @@ static int load_textfile(AVFilterContext *ctx) return err; } + if (textbuf_size > 0 && is_newline(textbuf[textbuf_size - 1])) + textbuf_size--; if (textbuf_size > SIZE_MAX - 1 || !(tmp = av_realloc(s->text, textbuf_size + 1))) { av_file_unmap(textbuf, textbuf_size); return AVERROR(ENOMEM); @@ -595,11 +602,6 @@ static int load_textfile(AVFilterContext *ctx) return 0; } -static inline int is_newline(uint32_t c) -{ - return c == '\n' || c == '\r' || c == '\f' || c == '\v'; -} - #if CONFIG_LIBFRIBIDI static int shape_text(AVFilterContext *ctx) { diff --git a/libavfilter/vf_edgedetect.c b/libavfilter/vf_edgedetect.c index a5614ea63..df8afbd53 100644 --- a/libavfilter/vf_edgedetect.c +++ b/libavfilter/vf_edgedetect.c @@ -294,7 +294,7 @@ static void double_threshold(int low, int high, int w, int h, continue; } - if ((!i || i == w - 1 || !j || j == h - 1) && + if (!(!i || i == w - 1 || !j || j == h - 1) && src[i] > low && (src[-src_linesize + i-1] > high || src[-src_linesize + i ] > high || diff --git a/libavfilter/vf_elbg.c b/libavfilter/vf_elbg.c index 5bccb5f58..835b1dfe3 100644 --- a/libavfilter/vf_elbg.c +++ b/libavfilter/vf_elbg.c @@ -100,8 +100,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE }; - if ((ret = ff_formats_ref(ff_make_format_list(pix_fmts), &ctx->inputs[0]->out_formats)) < 0 || - (ret = ff_formats_ref(ff_make_format_list(pal8_fmt), &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0 || + (ret = ff_formats_ref(ff_make_format_list(pal8_fmt), &ctx->outputs[0]->incfg.formats)) < 0) return ret; } return 0; diff --git a/libavfilter/vf_epx.c b/libavfilter/vf_epx.c new file mode 100644 index 000000000..65b8975c2 --- /dev/null +++ b/libavfilter/vf_epx.c @@ -0,0 +1,287 @@ +/* + * 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/opt.h" +#include "libavutil/avassert.h" +#include "libavutil/pixdesc.h" +#include "internal.h" + +typedef struct EPXContext { + const AVClass *class; + + int n; + + int (*epx_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); +} EPXContext; + +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +#define OFFSET(x) offsetof(EPXContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +static const AVOption epx_options[] = { + { "n", "set scale factor", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 3}, 2, 3, .flags = FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(epx); + +static int epx2_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ThreadData *td = arg; + const AVFrame *in = td->in; + AVFrame *out = td->out; + const int slice_start = (in->height * jobnr ) / nb_jobs; + const int slice_end = (in->height * (jobnr+1)) / nb_jobs; + + for (int p = 0; p < 1; p++) { + const int width = in->width; + const int height = in->height; + const int src_linesize = in->linesize[p] / 4; + const int dst_linesize = out->linesize[p] / 4; + const uint32_t *src = (const uint32_t *)in->data[p]; + uint32_t *dst = (uint32_t *)out->data[p]; + const uint32_t *src_line[3]; + + src_line[0] = src + src_linesize * FFMAX(slice_start - 1, 0); + src_line[1] = src + src_linesize * slice_start; + src_line[2] = src + src_linesize * FFMIN(slice_start + 1, height-1); + + for (int y = slice_start; y < slice_end; y++) { + uint32_t *dst_line[2]; + + dst_line[0] = dst + dst_linesize*2*y; + dst_line[1] = dst + dst_linesize*(2*y+1); + + for (int x = 0; x < width; x++) { + uint32_t E0, E1, E2, E3; + uint32_t B, D, E, F, H; + + B = src_line[0][x]; + D = src_line[1][FFMAX(x-1, 0)]; + E = src_line[1][x]; + F = src_line[1][FFMIN(x+1, width - 1)]; + H = src_line[2][x]; + + if (B != H && D != F) { + E0 = D == B ? D : E; + E1 = B == F ? F : E; + E2 = D == H ? D : E; + E3 = H == F ? F : E; + } else { + E0 = E; + E1 = E; + E2 = E; + E3 = E; + } + + dst_line[0][x*2] = E0; + dst_line[0][x*2+1] = E1; + dst_line[1][x*2] = E2; + dst_line[1][x*2+1] = E3; + } + + src_line[0] = src_line[1]; + src_line[1] = src_line[2]; + src_line[2] = src_line[1]; + + if (y < height - 1) + src_line[2] += src_linesize; + } + } + + return 0; +} + +static int epx3_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ThreadData *td = arg; + const AVFrame *in = td->in; + AVFrame *out = td->out; + const int slice_start = (in->height * jobnr ) / nb_jobs; + const int slice_end = (in->height * (jobnr+1)) / nb_jobs; + + for (int p = 0; p < 1; p++) { + const int width = in->width; + const int height = in->height; + const int src_linesize = in->linesize[p] / 4; + const int dst_linesize = out->linesize[p] / 4; + const uint32_t *src = (const uint32_t *)in->data[p]; + uint32_t *dst = (uint32_t *)out->data[p]; + const uint32_t *src_line[3]; + + src_line[0] = src + src_linesize * FFMAX(slice_start - 1, 0); + src_line[1] = src + src_linesize * slice_start; + src_line[2] = src + src_linesize * FFMIN(slice_start + 1, height-1); + + for (int y = slice_start; y < slice_end; y++) { + uint32_t *dst_line[3]; + + dst_line[0] = dst + dst_linesize*3*y; + dst_line[1] = dst + dst_linesize*(3*y+1); + dst_line[2] = dst + dst_linesize*(3*y+2); + + for (int x = 0; x < width; x++) { + uint32_t E0, E1, E2, E3, E4, E5, E6, E7, E8; + uint32_t A, B, C, D, E, F, G, H, I; + + A = src_line[0][FFMAX(x-1, 0)]; + B = src_line[0][x]; + C = src_line[0][FFMIN(x+1, width - 1)]; + D = src_line[1][FFMAX(x-1, 0)]; + E = src_line[1][x]; + F = src_line[1][FFMIN(x+1, width - 1)]; + G = src_line[2][FFMAX(x-1, 0)]; + H = src_line[2][x]; + I = src_line[2][FFMIN(x+1, width - 1)]; + + if (B != H && D != F) { + E0 = D == B ? D : E; + E1 = (D == B && E != C) || (B == F && E != A) ? B : E; + E2 = B == F ? F : E; + E3 = (D == B && E != G) || (D == H && E != A) ? D : E; + E4 = E; + E5 = (B == F && E != I) || (H == F && E != C) ? F : E; + E6 = D == H ? D : E; + E7 = (D == H && E != I) || (H == F && E != G) ? H : E; + E8 = H == F ? F : E; + } else { + E0 = E; + E1 = E; + E2 = E; + E3 = E; + E4 = E; + E5 = E; + E6 = E; + E7 = E; + E8 = E; + } + + dst_line[0][x*3] = E0; + dst_line[0][x*3+1] = E1; + dst_line[0][x*3+2] = E2; + dst_line[1][x*3] = E3; + dst_line[1][x*3+1] = E4; + dst_line[1][x*3+2] = E5; + dst_line[2][x*3] = E6; + dst_line[2][x*3+1] = E7; + dst_line[2][x*3+2] = E8; + } + + src_line[0] = src_line[1]; + src_line[1] = src_line[2]; + src_line[2] = src_line[1]; + + if (y < height - 1) + src_line[2] += src_linesize; + } + } + + return 0; +} + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + EPXContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + const AVPixFmtDescriptor *desc; + + desc = av_pix_fmt_desc_get(outlink->format); + if (!desc) + return AVERROR_BUG; + + outlink->w = inlink->w * s->n; + outlink->h = inlink->h * s->n; + + switch (s->n) { + case 2: + s->epx_slice = epx2_slice; + break; + case 3: + s->epx_slice = epx3_slice; + break; + } + + return 0; +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, + AV_PIX_FMT_NONE, + }; + + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + AVFilterLink *outlink = ctx->outputs[0]; + EPXContext *s = ctx->priv; + ThreadData td; + + AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + + av_frame_copy_props(out, in); + + td.in = in, td.out = out; + ctx->internal->execute(ctx, s->epx_slice, &td, NULL, FFMIN(inlink->h, ff_filter_get_nb_threads(ctx))); + + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL } +}; + +AVFilter ff_vf_epx = { + .name = "epx", + .description = NULL_IF_CONFIG_SMALL("Scale the input using EPX algorithm."), + .inputs = inputs, + .outputs = outputs, + .query_formats = query_formats, + .priv_size = sizeof(EPXContext), + .priv_class = &epx_class, + .flags = AVFILTER_FLAG_SLICE_THREADS, +}; diff --git a/libavfilter/vf_eq.c b/libavfilter/vf_eq.c index c8c3d5b34..114781fca 100644 --- a/libavfilter/vf_eq.c +++ b/libavfilter/vf_eq.c @@ -249,8 +249,6 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; diff --git a/libavfilter/vf_estdif.c b/libavfilter/vf_estdif.c new file mode 100644 index 000000000..abe90a125 --- /dev/null +++ b/libavfilter/vf_estdif.c @@ -0,0 +1,591 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/imgutils.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct ESTDIFContext { + const AVClass *class; + + int mode; ///< 0 is frame, 1 is field + int parity; ///< frame field parity + int deint; ///< which frames to deinterlace + int rslope; ///< best edge slope search radius + int redge; ///< best edge match search radius + int interp; ///< type of interpolation + int linesize[4]; ///< bytes of pixel data per line for each plane + int planewidth[4]; ///< width of each plane + int planeheight[4]; ///< height of each plane + int field; ///< which field are we on, 0 or 1 + int eof; + int depth; + int half; + int nb_planes; + int nb_threads; + int64_t pts; + AVFrame *prev; + + void (*interpolate)(struct ESTDIFContext *s, uint8_t *dst, + const uint8_t *prev_line, const uint8_t *next_line, + const uint8_t *prev2_line, const uint8_t *next2_line, + const uint8_t *prev3_line, const uint8_t *next3_line, + int x, int width, int rslope, int redge, unsigned half, + int depth, int *K); + + unsigned (*mid_8[3])(const uint8_t *const prev, + const uint8_t *const next, + const uint8_t *const prev2, + const uint8_t *const next2, + const uint8_t *const prev3, + const uint8_t *const next3, + int end, int x, int k, int depth); + + unsigned (*mid_16[3])(const uint16_t *const prev, + const uint16_t *const next, + const uint16_t *const prev2, + const uint16_t *const next2, + const uint16_t *const prev3, + const uint16_t *const next3, + int end, int x, int k, int depth); +} ESTDIFContext; + +#define MAX_R 15 +#define S (MAX_R * 2 + 1) + +#define OFFSET(x) offsetof(ESTDIFContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM +#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, 0, 0, FLAGS, unit } + +static const AVOption estdif_options[] = { + { "mode", "specify the mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "mode" }, + CONST("frame", "send one frame for each frame", 0, "mode"), + CONST("field", "send one frame for each field", 1, "mode"), + { "parity", "specify the assumed picture field parity", OFFSET(parity), AV_OPT_TYPE_INT, {.i64=-1}, -1, 1, FLAGS, "parity" }, + CONST("tff", "assume top field first", 0, "parity"), + CONST("bff", "assume bottom field first", 1, "parity"), + CONST("auto", "auto detect parity", -1, "parity"), + { "deint", "specify which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "deint" }, + CONST("all", "deinterlace all frames", 0, "deint"), + CONST("interlaced", "only deinterlace frames marked as interlaced", 1, "deint"), + { "rslope", "specify the search radius for edge slope tracing", OFFSET(rslope), AV_OPT_TYPE_INT, {.i64=1}, 1, MAX_R, FLAGS, }, + { "redge", "specify the search radius for best edge matching", OFFSET(redge), AV_OPT_TYPE_INT, {.i64=2}, 0, MAX_R, FLAGS, }, + { "interp", "specify the type of interpolation", OFFSET(interp), AV_OPT_TYPE_INT, {.i64=1}, 0, 2, FLAGS, "interp" }, + CONST("2p", "two-point interpolation", 0, "interp"), + CONST("4p", "four-point interpolation", 1, "interp"), + CONST("6p", "six-point interpolation", 2, "interp"), + { NULL } +}; + +AVFILTER_DEFINE_CLASS(estdif); + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, + AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, + AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_GRAY8, + AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_YUV440P12, + 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_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + AVFilterLink *inlink = ctx->inputs[0]; + + outlink->time_base.num = inlink->time_base.num; + outlink->time_base.den = inlink->time_base.den * 2; + outlink->frame_rate.num = inlink->frame_rate.num * 2; + outlink->frame_rate.den = inlink->frame_rate.den; + + return 0; +} + +typedef struct ThreadData { + AVFrame *out, *in; +} ThreadData; + +#define MIDL(type, ss) \ +static unsigned midl_##ss(const type *const prev, \ + const type *const next, \ + int end, int x, int k) \ +{ \ + return (prev[av_clip(x + k, 0, end)] + \ + next[av_clip(x - k, 0, end)] + 1) >> 1; \ +} + +MIDL(uint8_t, 8) +MIDL(uint16_t, 16) + +#define MID2(type, ss) \ +static unsigned mid2_##ss(const type *const prev, \ + const type *const next, \ + const type *const prev2, \ + const type *const next2, \ + const type *const prev3, \ + const type *const next3, \ + int end, int x, int k, int depth) \ +{ \ + return (prev[av_clip(x + k, 0, end)] + \ + next[av_clip(x - k, 0, end)] + 1) >> 1; \ +} + +MID2(uint8_t, 8) +MID2(uint16_t, 16) + +#define MID4(type, ss) \ +static unsigned mid4_##ss(const type *const prev, \ + const type *const next, \ + const type *const prev2, \ + const type *const next2, \ + const type *const prev3, \ + const type *const next3, \ + int end, int x, int k, int depth) \ +{ \ + return av_clip_uintp2_c(( \ + 9 * (prev[av_clip(x + k, 0, end)] + \ + next[av_clip(x - k, 0, end)]) - \ + 1 * (prev2[av_clip(x + k*3, 0, end)] + \ + next2[av_clip(x - k*3, 0, end)]) + 8) >> 4, \ + depth); \ +} + +MID4(uint8_t, 8) +MID4(uint16_t, 16) + +#define MID6(type, ss) \ +static unsigned mid6_##ss(const type *const prev, \ + const type *const next, \ + const type *const prev2, \ + const type *const next2, \ + const type *const prev3, \ + const type *const next3, \ + int end, int x, int k, int depth) \ +{ \ + return av_clip_uintp2_c(( \ + 20 * (prev[av_clip(x + k, 0, end)] + \ + next[av_clip(x - k, 0, end)]) - \ + 5 * (prev2[av_clip(x + k*3, 0, end)] + \ + next2[av_clip(x - k*3, 0, end)]) + \ + 1 * (prev3[av_clip(x + k*5, 0, end)] + \ + next3[av_clip(x - k*5, 0, end)]) + 16) >> 5, \ + depth); \ +} + +MID6(uint8_t, 8) +MID6(uint16_t, 16) + +#define DIFF(type, ss) \ +static unsigned diff_##ss(const type *const prev, \ + const type *const next, \ + int end, int x, int k, int j) \ +{ \ + return FFABS(prev[av_clip(x + k + j, 0, end)] - \ + next[av_clip(x - k + j, 0, end)]); \ +} + +DIFF(uint8_t, 8) +DIFF(uint16_t, 16) + +#define COST(type, ss) \ +static unsigned cost_##ss(const type *const prev, \ + const type *const next, \ + int end, int x, int k) \ +{ \ + const int m = midl_##ss(prev, next, end, x, k); \ + const int p = prev[x]; \ + const int n = next[x]; \ + \ + return FFABS(p - m) + FFABS(n - m); \ +} + +COST(uint8_t, 8) +COST(uint16_t, 16) + +#define INTERPOLATE(type, atype, max, ss) \ +static void interpolate_##ss(ESTDIFContext *s, uint8_t *ddst, \ + const uint8_t *const pprev_line, \ + const uint8_t *const nnext_line, \ + const uint8_t *const pprev2_line, \ + const uint8_t *const nnext2_line, \ + const uint8_t *const pprev3_line, \ + const uint8_t *const nnext3_line, \ + int x, int width, int rslope, \ + int redge, unsigned h, int depth, \ + int *K) \ +{ \ + type *dst = (type *)ddst; \ + const type *const prev_line = (const type *const)pprev_line; \ + const type *const prev2_line = (const type *const)pprev2_line; \ + const type *const prev3_line = (const type *const)pprev3_line; \ + const type *const next_line = (const type *const)nnext_line; \ + const type *const next2_line = (const type *const)nnext2_line; \ + const type *const next3_line = (const type *const)nnext3_line; \ + const int interp = s->interp; \ + const int end = width - 1; \ + const atype f = redge + 2; \ + atype sd[S], sD[S], di = 0; \ + atype dmin = max; \ + int k = *K; \ + \ + for (int i = -rslope; i <= rslope && abs(k) > rslope; i++) { \ + atype sum = 0; \ + \ + for (int j = -redge; j <= redge; j++) { \ + sum += diff_##ss(prev_line, next_line, end, x, i, j); \ + sum += diff_##ss(prev2_line, prev_line, end, x, i, j); \ + sum += diff_##ss(next_line, next2_line, end, x, i, j); \ + } \ + \ + sD[i + rslope] = sum; \ + sD[i + rslope] += f * cost_##ss(prev_line, next_line, end, x, i); \ + sD[i + rslope] += h * abs(i); \ + \ + dmin = FFMIN(sD[i + rslope], dmin); \ + } \ + \ + for (int i = -rslope; i <= rslope; i++) { \ + atype sum = 0; \ + \ + for (int j = -redge; j <= redge; j++) { \ + sum += diff_##ss(prev_line, next_line, end, x, k + i, j); \ + sum += diff_##ss(prev2_line, prev_line, end, x, k + i, j); \ + sum += diff_##ss(next_line, next2_line, end, x, k + i, j); \ + } \ + \ + sd[i + rslope] = sum; \ + sd[i + rslope] += f * cost_##ss(prev_line, next_line, end, x, k + i); \ + sd[i + rslope] += h * abs(k + i); \ + \ + dmin = FFMIN(sd[i + rslope], dmin); \ + } \ + \ + for (int i = -rslope; i <= rslope && abs(k) > rslope; i++) { \ + if (dmin == sD[i + rslope]) { \ + di = 1; \ + k = i; \ + break; \ + } \ + } \ + \ + for (int i = -rslope; i <= rslope && !di; i++) { \ + if (dmin == sd[i + rslope]) { \ + k += i; \ + break; \ + } \ + } \ + \ + dst[x] = s->mid_##ss[interp](prev_line, next_line, \ + prev2_line, next2_line, \ + prev3_line, next3_line, \ + end, x, k, depth); \ + \ + *K = k; \ +} + +INTERPOLATE(uint8_t, unsigned, UINT_MAX, 8) +INTERPOLATE(uint16_t, uint64_t, UINT64_MAX, 16) + +static int deinterlace_slice(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs) +{ + ESTDIFContext *s = ctx->priv; + ThreadData *td = arg; + AVFrame *out = td->out; + AVFrame *in = td->in; + const int rslope = s->rslope; + const int redge = s->redge; + const int half = s->half; + const int depth = s->depth; + const int interlaced = in->interlaced_frame; + const int tff = (s->field == (s->parity == -1 ? interlaced ? in->top_field_first : 1 : + s->parity ^ 1)); + + for (int plane = 0; plane < s->nb_planes; plane++) { + const uint8_t *src_data = in->data[plane]; + uint8_t *dst_data = out->data[plane]; + const int linesize = s->linesize[plane]; + const int width = s->planewidth[plane]; + const int height = s->planeheight[plane]; + const int src_linesize = in->linesize[plane]; + const int dst_linesize = out->linesize[plane]; + const int start = (height * jobnr) / nb_jobs; + const int end = (height * (jobnr+1)) / nb_jobs; + const uint8_t *prev_line, *prev2_line, *next_line, *next2_line, *in_line; + const uint8_t *prev3_line, *next3_line; + uint8_t *out_line; + int y_out; + + y_out = start + (tff ^ (start & 1)); + + in_line = src_data + (y_out * src_linesize); + out_line = dst_data + (y_out * dst_linesize); + + while (y_out < end) { + memcpy(out_line, in_line, linesize); + y_out += 2; + in_line += src_linesize * 2; + out_line += dst_linesize * 2; + } + + y_out = start + ((!tff) ^ (start & 1)); + out_line = dst_data + (y_out * dst_linesize); + + for (int y = y_out; y < end; y += 2) { + int y_prev3_in = y - 5; + int y_next3_in = y + 5; + int y_prev2_in = y - 3; + int y_next2_in = y + 3; + int y_prev_in = y - 1; + int y_next_in = y + 1; + int k; + + while (y_prev3_in < 0) + y_prev3_in += 2; + + while (y_next3_in >= height) + y_next3_in -= 2; + + while (y_prev2_in < 0) + y_prev2_in += 2; + + while (y_next2_in >= height) + y_next2_in -= 2; + + while (y_prev_in < 0) + y_prev_in += 2; + + while (y_next_in >= height) + y_next_in -= 2; + + prev3_line = src_data + (y_prev3_in * src_linesize); + next3_line = src_data + (y_next3_in * src_linesize); + + prev2_line = src_data + (y_prev2_in * src_linesize); + next2_line = src_data + (y_next2_in * src_linesize); + + prev_line = src_data + (y_prev_in * src_linesize); + next_line = src_data + (y_next_in * src_linesize); + + k = 0; + + for (int x = 0; x < width; x++) { + s->interpolate(s, out_line, + prev_line, next_line, + prev2_line, next2_line, + prev3_line, next3_line, + x, width, rslope, redge, half, depth, &k); + } + + out_line += 2 * dst_linesize; + } + } + + return 0; +} + +static int filter(AVFilterContext *ctx, int is_second, AVFrame *in) +{ + ESTDIFContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out; + ThreadData td; + + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) + return AVERROR(ENOMEM); + av_frame_copy_props(out, in); + out->interlaced_frame = 0; + out->pts = s->pts; + + td.out = out; td.in = in; + ctx->internal->execute(ctx, deinterlace_slice, &td, NULL, + FFMIN(s->planeheight[1] / 2, s->nb_threads)); + + if (s->mode) + s->field = !s->field; + + return ff_filter_frame(outlink, out); +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ESTDIFContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int ret; + + if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) + return ret; + + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + + if (inlink->h < 3) { + av_log(ctx, AV_LOG_ERROR, "Video of less than 3 lines is not supported\n"); + return AVERROR(EINVAL); + } + + s->nb_planes = av_pix_fmt_count_planes(inlink->format); + s->nb_threads = ff_filter_get_nb_threads(ctx); + s->depth = desc->comp[0].depth; + s->interpolate = s->depth <= 8 ? interpolate_8 : interpolate_16; + s->mid_8[0] = mid2_8; + s->mid_8[1] = mid4_8; + s->mid_8[2] = mid6_8; + s->mid_16[0] = mid2_16; + s->mid_16[1] = mid4_16; + s->mid_16[2] = mid6_16; + s->half = 1 << (s->depth - 1); + + return 0; +} + static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + ESTDIFContext *s = ctx->priv; + int ret; + + if (!s->prev) { + s->prev = in; + return 0; + } + + if ((s->deint && !in->interlaced_frame) || ctx->is_disabled) { + s->prev->pts *= 2; + ret = ff_filter_frame(ctx->outputs[0], s->prev); + s->prev = in; + return ret; + } + + s->pts = s->prev->pts * 2; + ret = filter(ctx, 0, s->prev); + if (ret < 0 || s->mode == 0) { + av_frame_free(&s->prev); + s->prev = in; + return ret; + } + + s->pts = s->prev->pts + in->pts; + ret = filter(ctx, 1, s->prev); + av_frame_free(&s->prev); + s->prev = in; + return ret; +} + +static int request_frame(AVFilterLink *link) +{ + AVFilterContext *ctx = link->src; + ESTDIFContext *s = ctx->priv; + int ret; + + if (s->eof) + return AVERROR_EOF; + + ret = ff_request_frame(ctx->inputs[0]); + + if (ret == AVERROR_EOF && s->prev) { + AVFrame *next = av_frame_clone(s->prev); + + if (!next) + return AVERROR(ENOMEM); + + next->pts = s->prev->pts + av_rescale_q(1, av_inv_q(ctx->outputs[0]->frame_rate), + ctx->outputs[0]->time_base); + s->eof = 1; + ret = filter_frame(ctx->inputs[0], next); + } else if (ret < 0) { + return ret; + } + + return ret; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + ESTDIFContext *s = ctx->priv; + + av_frame_free(&s->prev); +} + +static const AVFilterPad estdif_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad estdif_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + .request_frame = request_frame, + }, + { NULL } +}; + +AVFilter ff_vf_estdif = { + .name = "estdif", + .description = NULL_IF_CONFIG_SMALL("Apply Edge Slope Tracing deinterlace."), + .priv_size = sizeof(ESTDIFContext), + .priv_class = &estdif_class, + .uninit = uninit, + .query_formats = query_formats, + .inputs = estdif_inputs, + .outputs = estdif_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; diff --git a/libavfilter/vf_exposure.c b/libavfilter/vf_exposure.c new file mode 100644 index 000000000..b7ad07563 --- /dev/null +++ b/libavfilter/vf_exposure.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/opt.h" +#include "libavutil/imgutils.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct ExposureContext { + const AVClass *class; + + float exposure; + float black; + + float scale; + int (*do_slice)(AVFilterContext *s, void *arg, + int jobnr, int nb_jobs); +} ExposureContext; + +static int exposure_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ExposureContext *s = ctx->priv; + AVFrame *frame = arg; + const int width = frame->width; + const int height = frame->height; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const float black = s->black; + const float scale = s->scale; + + for (int p = 0; p < 3; p++) { + const int linesize = frame->linesize[p] / 4; + float *ptr = (float *)frame->data[p] + slice_start * linesize; + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) + ptr[x] = (ptr[x] - black) * scale; + + ptr += linesize; + } + } + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *frame) +{ + AVFilterContext *ctx = inlink->dst; + ExposureContext *s = ctx->priv; + + s->scale = 1.f / (exp2f(-s->exposure) - s->black); + ctx->internal->execute(ctx, s->do_slice, frame, NULL, + FFMIN(frame->height, ff_filter_get_nb_threads(ctx))); + + return ff_filter_frame(ctx->outputs[0], frame); +} + +static av_cold int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_fmts[] = { + AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *formats = NULL; + + formats = ff_make_format_list(pixel_fmts); + if (!formats) + return AVERROR(ENOMEM); + + return ff_set_common_formats(ctx, formats); +} + +static av_cold int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ExposureContext *s = ctx->priv; + + s->do_slice = exposure_slice; + + return 0; +} + +static const AVFilterPad exposure_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .needs_writable = 1, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad exposure_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +#define OFFSET(x) offsetof(ExposureContext, x) +#define VF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption exposure_options[] = { + { "exposure", "set the exposure correction", OFFSET(exposure), AV_OPT_TYPE_FLOAT, {.dbl=0}, -3, 3, VF }, + { "black", "set the black level correction", OFFSET(black), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(exposure); + +AVFilter ff_vf_exposure = { + .name = "exposure", + .description = NULL_IF_CONFIG_SMALL("Adjust exposure of the video stream."), + .priv_size = sizeof(ExposureContext), + .priv_class = &exposure_class, + .query_formats = query_formats, + .inputs = exposure_inputs, + .outputs = exposure_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c index 739c2420c..01ce4d1a3 100644 --- a/libavfilter/vf_extractplanes.c +++ b/libavfilter/vf_extractplanes.c @@ -115,16 +115,22 @@ AVFILTER_DEFINE_CLASS(extractplanes); AV_PIX_FMT_YUV422P14##suf, \ AV_PIX_FMT_YUV444P14##suf +#define FLOAT_FORMATS(suf) \ + AV_PIX_FMT_GRAYF32##suf, \ + AV_PIX_FMT_GBRPF32##suf, AV_PIX_FMT_GBRAPF32##suf \ + static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat in_pixfmts_le[] = { EIGHTBIT_FORMATS, HIGHDEPTH_FORMATS(LE), + FLOAT_FORMATS(LE), AV_PIX_FMT_NONE, }; static const enum AVPixelFormat in_pixfmts_be[] = { EIGHTBIT_FORMATS, HIGHDEPTH_FORMATS(BE), + FLOAT_FORMATS(BE), AV_PIX_FMT_NONE, }; static const enum AVPixelFormat out8_pixfmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }; @@ -138,17 +144,19 @@ static int query_formats(AVFilterContext *ctx) static const enum AVPixelFormat out14be_pixfmts[] = { AV_PIX_FMT_GRAY14BE, AV_PIX_FMT_NONE }; static const enum AVPixelFormat out16le_pixfmts[] = { AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_NONE }; static const enum AVPixelFormat out16be_pixfmts[] = { AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE }; + static const enum AVPixelFormat out32le_pixfmts[] = { AV_PIX_FMT_GRAYF32LE, AV_PIX_FMT_NONE }; + static const enum AVPixelFormat out32be_pixfmts[] = { AV_PIX_FMT_GRAYF32BE, AV_PIX_FMT_NONE }; const enum AVPixelFormat *out_pixfmts, *in_pixfmts; const AVPixFmtDescriptor *desc; AVFilterFormats *avff; int i, ret, depth = 0, be = 0; - if (!ctx->inputs[0]->in_formats || - !ctx->inputs[0]->in_formats->nb_formats) { + if (!ctx->inputs[0]->incfg.formats || + !ctx->inputs[0]->incfg.formats->nb_formats) { return AVERROR(EAGAIN); } - avff = ctx->inputs[0]->in_formats; + avff = ctx->inputs[0]->incfg.formats; desc = av_pix_fmt_desc_get(avff->formats[0]); depth = desc->comp[0].depth; be = desc->flags & AV_PIX_FMT_FLAG_BE; @@ -157,8 +165,8 @@ static int query_formats(AVFilterContext *ctx) } else { in_pixfmts = in_pixfmts_le; } - if (!ctx->inputs[0]->out_formats) - if ((ret = ff_formats_ref(ff_make_format_list(in_pixfmts), &ctx->inputs[0]->out_formats)) < 0) + if (!ctx->inputs[0]->outcfg.formats) + if ((ret = ff_formats_ref(ff_make_format_list(in_pixfmts), &ctx->inputs[0]->outcfg.formats)) < 0) return ret; for (i = 1; i < avff->nb_formats; i++) { @@ -187,13 +195,17 @@ static int query_formats(AVFilterContext *ctx) out_pixfmts = out14le_pixfmts; else if (be && depth == 14) out_pixfmts = out14be_pixfmts; - else if (be) + else if (be && depth == 16) out_pixfmts = out16be_pixfmts; - else + else if (!be && depth == 16) out_pixfmts = out16le_pixfmts; + else if (be && depth == 32) + out_pixfmts = out32be_pixfmts; + else + out_pixfmts = out32le_pixfmts; for (i = 0; i < ctx->nb_outputs; i++) - if ((ret = ff_formats_ref(ff_make_format_list(out_pixfmts), &ctx->outputs[i]->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(out_pixfmts), &ctx->outputs[i]->incfg.formats)) < 0) return ret; return 0; } diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 58d7f8cd4..10523fd18 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -62,6 +62,7 @@ typedef struct FadeContext { int alpha; int is_planar; uint64_t start_time, duration; + uint64_t start_time_pts, duration_pts; enum {VF_FADE_WAITING=0, VF_FADE_FADING, VF_FADE_DONE} fade_state; uint8_t color_rgba[4]; ///< fade color int black_fade; ///< if color_rgba is black @@ -403,7 +404,7 @@ static int filter_slice_alpha16(AVFilterContext *ctx, void *arg, int jobnr, return 0; } -static int config_props(AVFilterLink *inlink) +static int config_input(AVFilterLink *inlink) { FadeContext *s = inlink->dst->priv; const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(inlink->format); @@ -422,6 +423,11 @@ static int config_props(AVFilterLink *inlink) s->is_rgb = pixdesc->flags & AV_PIX_FMT_FLAG_RGB; s->is_packed_rgb = !s->is_planar && s->is_rgb; + if (s->duration) + s->duration_pts = av_rescale_q(s->duration, AV_TIME_BASE_Q, inlink->time_base); + if (s->start_time) + s->start_time_pts = av_rescale_q(s->start_time, AV_TIME_BASE_Q, inlink->time_base); + /* use CCIR601/709 black level for studio-level pixel non-alpha components */ s->black_level = ff_fmt_is_in(inlink->format, studio_level_pix_fmts) && !s->alpha ? 16 * (1 << (s->depth - 8)): 0; @@ -440,29 +446,28 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { AVFilterContext *ctx = inlink->dst; FadeContext *s = ctx->priv; - double frame_timestamp = frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base); // Calculate Fade assuming this is a Fade In if (s->fade_state == VF_FADE_WAITING) { s->factor=0; - if (frame_timestamp >= s->start_time/(double)AV_TIME_BASE + if (frame->pts >= s->start_time_pts && inlink->frame_count_out >= s->start_frame) { // Time to start fading s->fade_state = VF_FADE_FADING; // Save start time in case we are starting based on frames and fading based on time - if (s->start_time == 0 && s->start_frame != 0) { - s->start_time = frame_timestamp*(double)AV_TIME_BASE; + if (s->start_time_pts == 0 && s->start_frame != 0) { + s->start_time_pts = frame->pts; } // Save start frame in case we are starting based on time and fading based on frames - if (s->start_time != 0 && s->start_frame == 0) { + if (s->start_time_pts != 0 && s->start_frame == 0) { s->start_frame = inlink->frame_count_out; } } } if (s->fade_state == VF_FADE_FADING) { - if (s->duration == 0) { + if (s->duration_pts == 0) { // Fading based on frame count s->factor = (inlink->frame_count_out - s->start_frame) * s->fade_per_frame; if (inlink->frame_count_out > s->start_frame + s->nb_frames) { @@ -471,10 +476,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) } else { // Fading based on duration - s->factor = (frame_timestamp - s->start_time/(double)AV_TIME_BASE) - * (float) UINT16_MAX / (s->duration/(double)AV_TIME_BASE); - if (frame_timestamp > s->start_time/(double)AV_TIME_BASE - + s->duration/(double)AV_TIME_BASE) { + s->factor = (frame->pts - s->start_time_pts) * UINT16_MAX / s->duration_pts; + if (frame->pts > s->start_time_pts + s->duration_pts) { s->fade_state = VF_FADE_DONE; } } @@ -550,7 +553,7 @@ static const AVFilterPad avfilter_vf_fade_inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, + .config_props = config_input, .filter_frame = filter_frame, .needs_writable = 1, }, @@ -574,5 +577,6 @@ AVFilter ff_vf_fade = { .query_formats = query_formats, .inputs = avfilter_vf_fade_inputs, .outputs = avfilter_vf_fade_outputs, - .flags = AVFILTER_FLAG_SLICE_THREADS, + .flags = AVFILTER_FLAG_SLICE_THREADS | + AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; diff --git a/libavfilter/vf_fieldhint.c b/libavfilter/vf_fieldhint.c index c120bb01c..dcd08dabc 100644 --- a/libavfilter/vf_fieldhint.c +++ b/libavfilter/vf_fieldhint.c @@ -77,19 +77,16 @@ static av_cold int init(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { - AVFilterFormats *pix_fmts = NULL; - int fmt, ret; + AVFilterFormats *formats = NULL; + int ret; - for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL || - desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) && - (ret = ff_add_format(&pix_fmts, fmt)) < 0) - return ret; - } - - return ff_set_common_formats(ctx, pix_fmts); + ret = ff_formats_pixdesc_filter(&formats, 0, + AV_PIX_FMT_FLAG_HWACCEL | + AV_PIX_FMT_FLAG_BITSTREAM | + AV_PIX_FMT_FLAG_PAL); + if (ret < 0) + return ret; + return ff_set_common_formats(ctx, formats); } static int config_input(AVFilterLink *inlink) diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c index fa4aa8239..528f94317 100644 --- a/libavfilter/vf_fieldmatch.c +++ b/libavfilter/vf_fieldmatch.c @@ -917,14 +917,14 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } - if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_MAIN]->out_formats)) < 0) + if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_MAIN]->outcfg.formats)) < 0) return ret; fmts_list = ff_make_format_list(unproc_pix_fmts); if (!fmts_list) return AVERROR(ENOMEM); - if ((ret = ff_formats_ref(fmts_list, &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(fmts_list, &ctx->outputs[0]->incfg.formats)) < 0) return ret; - if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_CLEANSRC]->out_formats)) < 0) + if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_CLEANSRC]->outcfg.formats)) < 0) return ret; return 0; } @@ -951,8 +951,8 @@ static int config_input(AVFilterLink *inlink) fm->tpitchuv = FFALIGN(w >> 1, 16); fm->tbuffer = av_calloc((h/2 + 4) * fm->tpitchy, sizeof(*fm->tbuffer)); - fm->c_array = av_malloc((((w + fm->blockx/2)/fm->blockx)+1) * - (((h + fm->blocky/2)/fm->blocky)+1) * + fm->c_array = av_malloc_array((((w + fm->blockx/2)/fm->blockx)+1) * + (((h + fm->blocky/2)/fm->blocky)+1), 4 * sizeof(*fm->c_array)); if (!fm->tbuffer || !fm->c_array) return AVERROR(ENOMEM); @@ -964,28 +964,20 @@ static av_cold int fieldmatch_init(AVFilterContext *ctx) { const FieldMatchContext *fm = ctx->priv; AVFilterPad pad = { - .name = av_strdup("main"), + .name = "main", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_input, }; int ret; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, INPUT_MAIN, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, INPUT_MAIN, &pad)) < 0) return ret; - } if (fm->ppsrc) { - pad.name = av_strdup("clean_src"); + pad.name = "clean_src"; pad.config_props = NULL; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad)) < 0) return ret; - } } if ((fm->blockx & (fm->blockx - 1)) || @@ -1004,7 +996,6 @@ static av_cold int fieldmatch_init(AVFilterContext *ctx) static av_cold void fieldmatch_uninit(AVFilterContext *ctx) { - int i; FieldMatchContext *fm = ctx->priv; if (fm->prv != fm->src) @@ -1021,8 +1012,6 @@ static av_cold void fieldmatch_uninit(AVFilterContext *ctx) av_freep(&fm->cmask_data[0]); av_freep(&fm->tbuffer); av_freep(&fm->c_array); - for (i = 0; i < ctx->nb_inputs; i++) - av_freep(&ctx->input_pads[i].name); } static int config_output(AVFilterLink *outlink) diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c index 5707151f1..5d97dc58d 100644 --- a/libavfilter/vf_fieldorder.c +++ b/libavfilter/vf_fieldorder.c @@ -58,8 +58,8 @@ static int query_formats(AVFilterContext *ctx) (ret = ff_add_format(&formats, pix_fmt)) < 0) return ret; } - if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->out_formats)) < 0 || - (ret = ff_formats_ref(formats, &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->outcfg.formats)) < 0 || + (ret = ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats)) < 0) return ret; } diff --git a/libavfilter/vf_fillborders.c b/libavfilter/vf_fillborders.c index a5a0cb365..d703cbe4b 100644 --- a/libavfilter/vf_fillborders.c +++ b/libavfilter/vf_fillborders.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/colorspace.h" #include "libavutil/common.h" #include "libavutil/opt.h" @@ -31,7 +32,7 @@ enum { Y, U, V, A }; enum { R, G, B }; -enum FillMode { FM_SMEAR, FM_MIRROR, FM_FIXED, FM_NB_MODES }; +enum FillMode { FM_SMEAR, FM_MIRROR, FM_FIXED, FM_REFLECT, FM_WRAP, FM_FADE, FM_NB_MODES }; typedef struct Borders { int left, right, top, bottom; @@ -269,6 +270,231 @@ static void fixed_borders16(FillBordersContext *s, AVFrame *frame) } } +static void reflect_borders8(FillBordersContext *s, AVFrame *frame) +{ + int p, y, x; + + for (p = 0; p < s->nb_planes; p++) { + uint8_t *ptr = frame->data[p]; + int linesize = frame->linesize[p]; + + for (y = s->borders[p].top; y < s->planeheight[p] - s->borders[p].bottom; y++) { + for (x = 0; x < s->borders[p].left; x++) { + ptr[y * linesize + x] = ptr[y * linesize + s->borders[p].left * 2 - x]; + } + + for (x = 0; x < s->borders[p].right; x++) { + ptr[y * linesize + s->planewidth[p] - s->borders[p].right + x] = + ptr[y * linesize + s->planewidth[p] - s->borders[p].right - 2 - x]; + } + } + + for (y = 0; y < s->borders[p].top; y++) { + memcpy(ptr + y * linesize, + ptr + (s->borders[p].top * 2 - y) * linesize, + s->planewidth[p]); + } + + for (y = 0; y < s->borders[p].bottom; y++) { + memcpy(ptr + (s->planeheight[p] - s->borders[p].bottom + y) * linesize, + ptr + (s->planeheight[p] - s->borders[p].bottom - 2 - y) * linesize, + s->planewidth[p]); + } + } +} + +static void reflect_borders16(FillBordersContext *s, AVFrame *frame) +{ + int p, y, x; + + for (p = 0; p < s->nb_planes; p++) { + uint16_t *ptr = (uint16_t *)frame->data[p]; + int linesize = frame->linesize[p] / 2; + + for (y = s->borders[p].top; y < s->planeheight[p] - s->borders[p].bottom; y++) { + for (x = 0; x < s->borders[p].left; x++) { + ptr[y * linesize + x] = ptr[y * linesize + s->borders[p].left * 2 - x]; + } + + for (x = 0; x < s->borders[p].right; x++) { + ptr[y * linesize + s->planewidth[p] - s->borders[p].right + x] = + ptr[y * linesize + s->planewidth[p] - s->borders[p].right - 2 - x]; + } + } + + for (y = 0; y < s->borders[p].top; y++) { + memcpy(ptr + y * linesize, + ptr + (s->borders[p].top * 2 - y) * linesize, + s->planewidth[p] * 2); + } + + for (y = 0; y < s->borders[p].bottom; y++) { + memcpy(ptr + (s->planeheight[p] - s->borders[p].bottom + y) * linesize, + ptr + (s->planeheight[p] - s->borders[p].bottom - 2 - y) * linesize, + s->planewidth[p] * 2); + } + } +} + +static void wrap_borders8(FillBordersContext *s, AVFrame *frame) +{ + int p, y, x; + + for (p = 0; p < s->nb_planes; p++) { + uint8_t *ptr = frame->data[p]; + int linesize = frame->linesize[p]; + + for (y = s->borders[p].top; y < s->planeheight[p] - s->borders[p].bottom; y++) { + for (x = 0; x < s->borders[p].left; x++) { + ptr[y * linesize + x] = ptr[y * linesize + s->planewidth[p] - s->borders[p].right - s->borders[p].left + x]; + } + + for (x = 0; x < s->borders[p].right; x++) { + ptr[y * linesize + s->planewidth[p] - s->borders[p].right + x] = + ptr[y * linesize + s->borders[p].left + x]; + } + } + + for (y = 0; y < s->borders[p].top; y++) { + memcpy(ptr + y * linesize, + ptr + (s->planeheight[p] - s->borders[p].bottom - s->borders[p].top + y) * linesize, + s->planewidth[p]); + } + + for (y = 0; y < s->borders[p].bottom; y++) { + memcpy(ptr + (s->planeheight[p] - s->borders[p].bottom + y) * linesize, + ptr + (s->borders[p].top + y) * linesize, + s->planewidth[p]); + } + } +} + +static void wrap_borders16(FillBordersContext *s, AVFrame *frame) +{ + int p, y, x; + + for (p = 0; p < s->nb_planes; p++) { + uint16_t *ptr = (uint16_t *)frame->data[p]; + int linesize = frame->linesize[p] / 2; + + for (y = s->borders[p].top; y < s->planeheight[p] - s->borders[p].bottom; y++) { + for (x = 0; x < s->borders[p].left; x++) { + ptr[y * linesize + x] = ptr[y * linesize + s->planewidth[p] - s->borders[p].right - s->borders[p].left + x]; + } + + for (x = 0; x < s->borders[p].right; x++) { + ptr[y * linesize + s->planewidth[p] - s->borders[p].right + x] = + ptr[y * linesize + s->borders[p].left + x]; + } + } + + for (y = 0; y < s->borders[p].top; y++) { + memcpy(ptr + y * linesize, + ptr + (s->planeheight[p] - s->borders[p].bottom - s->borders[p].top + y) * linesize, + s->planewidth[p] * 2); + } + + for (y = 0; y < s->borders[p].bottom; y++) { + memcpy(ptr + (s->planeheight[p] - s->borders[p].bottom + y) * linesize, + ptr + (s->borders[p].top + y) * linesize, + s->planewidth[p] * 2); + } + } +} + +static int lerp8(int fill, int src, int pos, int size) +{ + return av_clip_uint8(((fill * 256 * pos / size) + (src * 256 * (size - pos) / size)) >> 8); +} + +static int lerp16(int fill, int src, int pos, int size, int depth) +{ + return av_clip_uintp2_c(((fill * (1LL << depth) * pos / size) + (src * (1LL << depth) * (size - pos) / size)) >> depth, depth); +} + +static void fade_borders8(FillBordersContext *s, AVFrame *frame) +{ + int p, y, x; + + for (p = 0; p < s->nb_planes; p++) { + uint8_t *ptr = frame->data[p]; + const uint8_t fill = s->fill[p]; + const int linesize = frame->linesize[p]; + const int start_left = s->borders[p].left; + const int start_right = s->planewidth[p] - s->borders[p].right; + const int start_top = s->borders[p].top; + const int start_bottom = s->planeheight[p] - s->borders[p].bottom; + + for (y = 0; y < start_top; y++) { + for (x = 0; x < s->planewidth[p]; x++) { + int src = ptr[y * linesize + x]; + ptr[y * linesize + x] = lerp8(fill, src, start_top - y, start_top); + } + } + + for (y = start_bottom; y < s->planeheight[p]; y++) { + for (x = 0; x < s->planewidth[p]; x++) { + int src = ptr[y * linesize + x]; + ptr[y * linesize + x] = lerp8(fill, src, y - start_bottom, s->borders[p].bottom); + } + } + + for (y = 0; y < s->planeheight[p]; y++) { + for (x = 0; x < start_left; x++) { + int src = ptr[y * linesize + x]; + ptr[y * linesize + x] = lerp8(fill, src, start_left - x, start_left); + } + + for (x = 0; x < s->borders[p].right; x++) { + int src = ptr[y * linesize + start_right + x]; + ptr[y * linesize + start_right + x] = lerp8(fill, src, x, s->borders[p].right); + } + } + } +} + +static void fade_borders16(FillBordersContext *s, AVFrame *frame) +{ + const int depth = s->depth; + int p, y, x; + + for (p = 0; p < s->nb_planes; p++) { + uint16_t *ptr = (uint16_t *)frame->data[p]; + const uint16_t fill = s->fill[p] << (depth - 8); + const int linesize = frame->linesize[p] / 2; + const int start_left = s->borders[p].left; + const int start_right = s->planewidth[p] - s->borders[p].right; + const int start_top = s->borders[p].top; + const int start_bottom = s->planeheight[p] - s->borders[p].bottom; + + for (y = 0; y < start_top; y++) { + for (x = 0; x < s->planewidth[p]; x++) { + int src = ptr[y * linesize + x]; + ptr[y * linesize + x] = lerp16(fill, src, start_top - y, start_top, depth); + } + } + + for (y = start_bottom; y < s->planeheight[p]; y++) { + for (x = 0; x < s->planewidth[p]; x++) { + int src = ptr[y * linesize + x]; + ptr[y * linesize + x] = lerp16(fill, src, y - start_bottom, s->borders[p].bottom, depth); + } + } + + for (y = 0; y < s->planeheight[p]; y++) { + for (x = 0; x < start_left; x++) { + int src = ptr[y * linesize + x]; + ptr[y * linesize + x] = lerp16(fill, src, start_left - x, start_left, depth); + } + + for (x = 0; x < s->borders[p].right; x++) { + int src = ptr[y * linesize + start_right + x]; + ptr[y * linesize + start_right + x] = lerp16(fill, src, x, s->borders[p].right, depth); + } + } + } +} + static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { FillBordersContext *s = inlink->dst->priv; @@ -325,6 +551,10 @@ static int config_input(AVFilterLink *inlink) case FM_SMEAR: s->fillborders = s->depth <= 8 ? smear_borders8 : smear_borders16; break; case FM_MIRROR: s->fillborders = s->depth <= 8 ? mirror_borders8 : mirror_borders16; break; case FM_FIXED: s->fillborders = s->depth <= 8 ? fixed_borders8 : fixed_borders16; break; + case FM_REFLECT:s->fillborders = s->depth <= 8 ? reflect_borders8: reflect_borders16;break; + case FM_WRAP: s->fillborders = s->depth <= 8 ? wrap_borders8 : wrap_borders16; break; + case FM_FADE: s->fillborders = s->depth <= 8 ? fade_borders8 : fade_borders16; break; + default: av_assert0(0); } s->yuv_color[Y] = RGB_TO_Y_CCIR(s->rgba_color[R], s->rgba_color[G], s->rgba_color[B]); @@ -370,7 +600,10 @@ static const AVOption fillborders_options[] = { { "smear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=FM_SMEAR}, 0, 0, FLAGS, "mode" }, { "mirror", NULL, 0, AV_OPT_TYPE_CONST, {.i64=FM_MIRROR}, 0, 0, FLAGS, "mode" }, { "fixed", NULL, 0, AV_OPT_TYPE_CONST, {.i64=FM_FIXED}, 0, 0, FLAGS, "mode" }, - { "color", "set the color for the fixed mode", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str = "black"}, .flags = FLAGS }, + { "reflect",NULL, 0, AV_OPT_TYPE_CONST, {.i64=FM_REFLECT},0, 0, FLAGS, "mode" }, + { "wrap", NULL, 0, AV_OPT_TYPE_CONST, {.i64=FM_WRAP}, 0, 0, FLAGS, "mode" }, + { "fade", NULL, 0, AV_OPT_TYPE_CONST, {.i64=FM_FADE}, 0, 0, FLAGS, "mode" }, + { "color", "set the color for the fixed/fade mode", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str = "black"}, .flags = FLAGS }, { NULL } }; diff --git a/libavfilter/vf_framepack.c b/libavfilter/vf_framepack.c index b5d877ca9..3da80cfee 100644 --- a/libavfilter/vf_framepack.c +++ b/libavfilter/vf_framepack.c @@ -44,6 +44,7 @@ typedef struct FramepackContext { const AVClass *class; + int depth; const AVPixFmtDescriptor *pix_desc; ///< agreed pixel format enum AVStereo3DType format; ///< frame pack type output @@ -52,9 +53,29 @@ typedef struct FramepackContext { } FramepackContext; static const enum AVPixelFormat formats_supported[] = { - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, + AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, + AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_NONE }; @@ -113,6 +134,7 @@ static int config_output(AVFilterLink *outlink) s->pix_desc = av_pix_fmt_desc_get(outlink->format); if (!s->pix_desc) return AVERROR_BUG; + s->depth = s->pix_desc->comp[0].depth; // modify output properties as needed switch (s->format) { @@ -149,7 +171,7 @@ static void horizontal_frame_pack(AVFilterLink *outlink, FramepackContext *s = ctx->priv; int i, plane; - if (interleaved) { + if (interleaved && s->depth <= 8) { const uint8_t *leftp = s->input_views[LEFT]->data[0]; const uint8_t *rightp = s->input_views[RIGHT]->data[0]; uint8_t *dstp = out->data[0]; @@ -184,17 +206,53 @@ static void horizontal_frame_pack(AVFilterLink *outlink, } } } + } else if (interleaved && s->depth > 8) { + const uint16_t *leftp = (const uint16_t *)s->input_views[LEFT]->data[0]; + const uint16_t *rightp = (const uint16_t *)s->input_views[RIGHT]->data[0]; + uint16_t *dstp = (uint16_t *)out->data[0]; + int length = out->width / 2; + int lines = out->height; + + for (plane = 0; plane < s->pix_desc->nb_components; plane++) { + if (plane == 1 || plane == 2) { + length = AV_CEIL_RSHIFT(out->width / 2, s->pix_desc->log2_chroma_w); + lines = AV_CEIL_RSHIFT(out->height, s->pix_desc->log2_chroma_h); + } + for (i = 0; i < lines; i++) { + int j; + leftp = (const uint16_t *)s->input_views[LEFT]->data[plane] + + s->input_views[LEFT]->linesize[plane] * i / 2; + rightp = (const uint16_t *)s->input_views[RIGHT]->data[plane] + + s->input_views[RIGHT]->linesize[plane] * i / 2; + dstp = (uint16_t *)out->data[plane] + out->linesize[plane] * i / 2; + for (j = 0; j < length; j++) { + // interpolate chroma as necessary + if ((s->pix_desc->log2_chroma_w || + s->pix_desc->log2_chroma_h) && + (plane == 1 || plane == 2)) { + *dstp++ = (*leftp + *rightp) / 2; + *dstp++ = (*leftp + *rightp) / 2; + } else { + *dstp++ = *leftp; + *dstp++ = *rightp; + } + leftp += 1; + rightp += 1; + } + } + } } else { for (i = 0; i < 2; i++) { + const int psize = 1 + (s->depth > 8); const uint8_t *src[4]; uint8_t *dst[4]; - int sub_w = s->input_views[i]->width >> s->pix_desc->log2_chroma_w; + int sub_w = psize * s->input_views[i]->width >> s->pix_desc->log2_chroma_w; src[0] = s->input_views[i]->data[0]; src[1] = s->input_views[i]->data[1]; src[2] = s->input_views[i]->data[2]; - dst[0] = out->data[0] + i * s->input_views[i]->width; + dst[0] = out->data[0] + i * s->input_views[i]->width * psize; dst[1] = out->data[1] + i * sub_w; dst[2] = out->data[2] + i * sub_w; diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 5d3840599..2ec4707d9 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -338,7 +338,7 @@ static int query_formats(AVFilterContext *ctx) return ret; } else { /* F0R_COLOR_MODEL_PACKED32 */ static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_ARGB, AV_PIX_FMT_NONE + AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_NONE }; formats = ff_make_format_list(pix_fmts); } @@ -371,11 +371,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + Frei0rContext *s = ctx->priv; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return set_params(ctx, s->params); +} + #define OFFSET(x) offsetof(Frei0rContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM +#define TFLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM static const AVOption frei0r_options[] = { { "filter_name", NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS }, + { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = TFLAGS }, { NULL } }; @@ -409,6 +423,8 @@ AVFilter ff_vf_frei0r = { .priv_class = &frei0r_class, .inputs = avfilter_vf_frei0r_inputs, .outputs = avfilter_vf_frei0r_outputs, + .process_command = process_command, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; static av_cold int source_init(AVFilterContext *ctx) diff --git a/libavfilter/vf_fspp.c b/libavfilter/vf_fspp.c index c6989046c..d70952a14 100644 --- a/libavfilter/vf_fspp.c +++ b/libavfilter/vf_fspp.c @@ -37,9 +37,11 @@ #include "libavutil/avassert.h" #include "libavutil/imgutils.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "internal.h" +#include "qp_table.h" #include "vf_fspp.h" #define OFFSET(x) offsetof(FSPPContext, x) @@ -525,13 +527,6 @@ static int config_input(AVFilterLink *inlink) if (!fspp->temp || !fspp->src) return AVERROR(ENOMEM); - if (!fspp->use_bframe_qp && !fspp->qp) { - fspp->non_b_qp_alloc_size = AV_CEIL_RSHIFT(inlink->w, 4) * AV_CEIL_RSHIFT(inlink->h, 4); - fspp->non_b_qp_table = av_calloc(fspp->non_b_qp_alloc_size, sizeof(*fspp->non_b_qp_table)); - if (!fspp->non_b_qp_table) - return AVERROR(ENOMEM); - } - fspp->store_slice = store_slice_c; fspp->store_slice2 = store_slice2_c; fspp->mul_thrmat = mul_thrmat_c; @@ -553,8 +548,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFrame *out = in; int qp_stride = 0; - uint8_t *qp_table = NULL; + int8_t *qp_table = NULL; int i, bias; + int ret = 0; int custom_threshold_m[64]; bias = (1 << 4) + fspp->strength; @@ -581,38 +577,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) * the quantizers from the B-frames (B-frames often have a higher QP), we * need to save the qp table from the last non B-frame; this is what the * following code block does */ - if (!fspp->qp) { - qp_table = av_frame_get_qp_table(in, &qp_stride, &fspp->qscale_type); + if (!fspp->qp && (fspp->use_bframe_qp || in->pict_type != AV_PICTURE_TYPE_B)) { + ret = ff_qp_table_extract(in, &qp_table, &qp_stride, NULL, &fspp->qscale_type); + if (ret < 0) { + av_frame_free(&in); + return ret; + } - if (qp_table && !fspp->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) { - int w, h; - - /* if the qp stride is not set, it means the QP are only defined on - * a line basis */ - if (!qp_stride) { - w = AV_CEIL_RSHIFT(inlink->w, 4); - h = 1; - } else { - w = qp_stride; - h = AV_CEIL_RSHIFT(inlink->h, 4); - } - if (w * h > fspp->non_b_qp_alloc_size) { - int ret = av_reallocp_array(&fspp->non_b_qp_table, w, h); - if (ret < 0) { - fspp->non_b_qp_alloc_size = 0; - return ret; - } - fspp->non_b_qp_alloc_size = w * h; - } - - av_assert0(w * h <= fspp->non_b_qp_alloc_size); - memcpy(fspp->non_b_qp_table, qp_table, w * h); + if (!fspp->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) { + av_freep(&fspp->non_b_qp_table); + fspp->non_b_qp_table = qp_table; + fspp->non_b_qp_stride = qp_stride; } } if (fspp->log2_count && !ctx->is_disabled) { - if (!fspp->use_bframe_qp && fspp->non_b_qp_table) + if (!fspp->use_bframe_qp && fspp->non_b_qp_table) { qp_table = fspp->non_b_qp_table; + qp_stride = fspp->non_b_qp_stride; + } if (qp_table || fspp->qp) { const int cw = AV_CEIL_RSHIFT(inlink->w, fspp->hsub); @@ -627,7 +610,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) out = ff_get_video_buffer(outlink, aligned_w, aligned_h); if (!out) { av_frame_free(&in); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto finish; } av_frame_copy_props(out, in); out->width = in->width; @@ -651,7 +635,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) inlink->w, inlink->h); av_frame_free(&in); } - return ff_filter_frame(outlink, out); + ret = ff_filter_frame(outlink, out); +finish: + if (qp_table != fspp->non_b_qp_table) + av_freep(&qp_table); + return ret; } static av_cold void uninit(AVFilterContext *ctx) diff --git a/libavfilter/vf_fspp.h b/libavfilter/vf_fspp.h index 73d8c7c77..6623af450 100644 --- a/libavfilter/vf_fspp.h +++ b/libavfilter/vf_fspp.h @@ -65,8 +65,8 @@ typedef struct FSPPContext { int prev_q; uint8_t *src; int16_t *temp; - uint8_t *non_b_qp_table; - int non_b_qp_alloc_size; + int8_t *non_b_qp_table; + int non_b_qp_stride; int use_bframe_qp; void (*store_slice)(uint8_t *dst, int16_t *src, diff --git a/libavfilter/vf_gblur.c b/libavfilter/vf_gblur.c index 2e587f6a0..86c765b59 100644 --- a/libavfilter/vf_gblur.c +++ b/libavfilter/vf_gblur.c @@ -25,6 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" @@ -52,6 +54,15 @@ typedef struct ThreadData { int width; } ThreadData; +static void postscale_c(float *buffer, int length, + float postscale, float min, float max) +{ + for (int i = 0; i < length; i++) { + buffer[i] *= postscale; + buffer[i] = av_clipf(buffer[i], min, max); + } +} + static void horiz_slice_c(float *buffer, int width, int height, int steps, float nu, float bscale) { @@ -152,25 +163,22 @@ static int filter_vertically(AVFilterContext *ctx, void *arg, int jobnr, int nb_ return 0; } - static int filter_postscale(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { GBlurContext *s = ctx->priv; ThreadData *td = arg; - const float max = (1 << s->depth) - 1; + const float max = s->flt ? FLT_MAX : (1 << s->depth) - 1; + const float min = s->flt ? -FLT_MAX : 0.f; const int height = td->height; const int width = td->width; - const int64_t numpixels = width * (int64_t)height; - const unsigned slice_start = (numpixels * jobnr ) / nb_jobs; - const unsigned slice_end = (numpixels * (jobnr+1)) / nb_jobs; + const int awidth = FFALIGN(width, 64); + const int slice_start = (height * jobnr ) / nb_jobs; + const int slice_end = (height * (jobnr+1)) / nb_jobs; const float postscale = s->postscale * s->postscaleV; - float *buffer = s->buffer; - unsigned i; + const int slice_size = slice_end - slice_start; - for (i = slice_start; i < slice_end; i++) { - buffer[i] *= postscale; - buffer[i] = av_clipf(buffer[i], 0.f, max); - } + s->postscale_slice(s->buffer + slice_start * awidth, + slice_size * awidth, postscale, min, max); return 0; } @@ -214,6 +222,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32, + AV_PIX_FMT_GRAYF32, AV_PIX_FMT_NONE }; @@ -223,7 +233,8 @@ static int query_formats(AVFilterContext *ctx) void ff_gblur_init(GBlurContext *s) { s->horiz_slice = horiz_slice_c; - if (ARCH_X86_64) + s->postscale_slice = postscale_c; + if (ARCH_X86) ff_gblur_init_x86(s); } @@ -233,6 +244,7 @@ static int config_input(AVFilterLink *inlink) GBlurContext *s = inlink->dst->priv; s->depth = desc->comp[0].depth; + s->flt = !!(desc->flags & AV_PIX_FMT_FLAG_FLOAT); s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); s->planewidth[0] = s->planewidth[3] = inlink->w; s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); @@ -240,7 +252,7 @@ static int config_input(AVFilterLink *inlink) s->nb_planes = av_pix_fmt_count_planes(inlink->format); - s->buffer = av_malloc_array(FFALIGN(inlink->w, 16), FFALIGN(inlink->h, 16) * sizeof(*s->buffer)); + s->buffer = av_malloc_array(FFALIGN(inlink->w, 64), FFALIGN(inlink->h, 64) * sizeof(*s->buffer)); if (!s->buffer) return AVERROR(ENOMEM); @@ -303,7 +315,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) continue; } - if (s->depth == 8) { + if (s->flt) { + av_image_copy_plane((uint8_t *)bptr, width * sizeof(float), + in->data[plane], in->linesize[plane], + width * sizeof(float), height); + } else if (s->depth == 8) { for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { bptr[x] = src[x]; @@ -324,7 +340,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) gaussianiir2d(ctx, plane); bptr = s->buffer; - if (s->depth == 8) { + if (s->flt) { + av_image_copy_plane(out->data[plane], out->linesize[plane], + (uint8_t *)bptr, width * sizeof(float), + width * sizeof(float), height); + } else if (s->depth == 8) { for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { dst[x] = bptr[x]; diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c index d7abf96a6..072cef3ca 100644 --- a/libavfilter/vf_geq.c +++ b/libavfilter/vf_geq.c @@ -270,7 +270,7 @@ static av_cold int geq_init(AVFilterContext *ctx) } for (plane = 0; plane < NB_PLANES; plane++) { - static double (*p[])(void *, double, double) = { + static double (*const p[])(void *, double, double) = { lum , cb , cr , alpha , lumsum, cbsum, crsub, alphasum, }; @@ -283,7 +283,7 @@ static av_cold int geq_init(AVFilterContext *ctx) "gsum", "bsum", "rsum", "alphasum", "psum", NULL }; const char *const *func2_names = geq->is_rgb ? func2_rgb_names : func2_yuv_names; - double (*func2[])(void *, double, double) = { + double (*const func2[])(void *, double, double) = { lum , cb , cr , alpha , p[plane], lumsum, cbsum, crsub, alphasum, p[plane + 4], NULL }; diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index f63128d72..28da37ff9 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -35,6 +35,7 @@ #include "libavutil/imgutils.h" #include "libavutil/common.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c index b77afc77f..8d7bd9b4d 100644 --- a/libavfilter/vf_hflip.c +++ b/libavfilter/vf_hflip.c @@ -138,6 +138,7 @@ static int config_props(AVFilterLink *inlink) s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, hsub); s->planeheight[0] = s->planeheight[3] = inlink->h; s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, vsub); + s->bayer_plus1 = !!(pix_desc->flags & AV_PIX_FMT_FLAG_BAYER) + 1; nb_planes = av_pix_fmt_count_planes(inlink->format); @@ -149,6 +150,7 @@ int ff_hflip_init(FlipContext *s, int step[4], int nb_planes) int i; for (i = 0; i < nb_planes; i++) { + step[i] *= s->bayer_plus1; switch (step[i]) { case 1: s->flip_line[i] = hflip_byte_c; break; case 2: s->flip_line[i] = hflip_short_c; break; @@ -180,7 +182,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) int i, plane, step; for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) { - const int width = s->planewidth[plane]; + const int width = s->planewidth[plane] / s->bayer_plus1; const int height = s->planeheight[plane]; const int start = (height * job ) / nb_jobs; const int end = (height * (job+1)) / nb_jobs; diff --git a/libavfilter/vf_histogram.c b/libavfilter/vf_histogram.c index db1962edc..ed6892bc8 100644 --- a/libavfilter/vf_histogram.c +++ b/libavfilter/vf_histogram.c @@ -34,6 +34,7 @@ typedef struct HistogramContext { const AVClass *class; ///< AVClass context for log and options purpose int thistogram; int envelope; + int slide; unsigned histogram[256*256]; int histogram_size; int width; @@ -155,15 +156,15 @@ static int query_formats(AVFilterContext *ctx) int rgb, i, bits; int ret; - if (!ctx->inputs[0]->in_formats || - !ctx->inputs[0]->in_formats->nb_formats) { + if (!ctx->inputs[0]->incfg.formats || + !ctx->inputs[0]->incfg.formats->nb_formats) { return AVERROR(EAGAIN); } - if (!ctx->inputs[0]->out_formats) - if ((ret = ff_formats_ref(ff_make_format_list(levels_in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0) + if (!ctx->inputs[0]->outcfg.formats) + if ((ret = ff_formats_ref(ff_make_format_list(levels_in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0) return ret; - avff = ctx->inputs[0]->in_formats; + avff = ctx->inputs[0]->incfg.formats; desc = av_pix_fmt_desc_get(avff->formats[0]); rgb = desc->flags & AV_PIX_FMT_FLAG_RGB; bits = desc->comp[0].depth; @@ -192,7 +193,7 @@ static int query_formats(AVFilterContext *ctx) out_pix_fmts = levels_out_yuv12_pix_fmts; else return AVERROR(EAGAIN); - if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0) return ret; return 0; @@ -354,8 +355,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) max_hval_log = log2(max_hval + 1); if (s->thistogram) { + const int bpp = 1 + (s->histogram_size > 256); int minh = s->histogram_size - 1, maxh = 0; + if (s->slide == 2) { + s->x_pos = out->width - 1; + for (j = 0; j < outlink->h; j++) { + memmove(out->data[p] + j * out->linesize[p] , + out->data[p] + j * out->linesize[p] + bpp, + (outlink->w - 1) * bpp); + } + } else if (s->slide == 3) { + s->x_pos = 0; + for (j = 0; j < outlink->h; j++) { + memmove(out->data[p] + j * out->linesize[p] + bpp, + out->data[p] + j * out->linesize[p], + (outlink->w - 1) * bpp); + } + } + for (int i = 0; i < s->histogram_size; i++) { int idx = s->histogram_size - i - 1; int value = s->start[p]; @@ -443,8 +461,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) out->pts = in->pts; av_frame_free(&in); s->x_pos++; - if (s->x_pos >= s->width) + if (s->x_pos >= s->width) { s->x_pos = 0; + if (s->thistogram && (s->slide == 4 || s->slide == 0)) { + s->out = NULL; + goto end; + } + } else if (s->thistogram && s->slide == 4) { + return 0; + } if (s->thistogram) { AVFrame *clone = av_frame_clone(out); @@ -453,6 +478,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return AVERROR(ENOMEM); return ff_filter_frame(outlink, clone); } +end: return ff_filter_frame(outlink, out); } @@ -491,6 +517,13 @@ AVFilter ff_vf_histogram = { #if CONFIG_THISTOGRAM_FILTER +static av_cold void uninit(AVFilterContext *ctx) +{ + HistogramContext *s = ctx->priv; + + av_frame_free(&s->out); +} + static const AVOption thistogram_options[] = { { "width", "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS}, { "w", "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS}, @@ -501,6 +534,12 @@ static const AVOption thistogram_options[] = { { "e", "display envelope", OFFSET(envelope), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { "ecolor", "set envelope color", OFFSET(envelope_rgba), AV_OPT_TYPE_COLOR, {.str="gold"}, 0, 0, FLAGS }, { "ec", "set envelope color", OFFSET(envelope_rgba), AV_OPT_TYPE_COLOR, {.str="gold"}, 0, 0, FLAGS }, + { "slide", "set slide mode", OFFSET(slide), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, FLAGS, "slide" }, + {"frame", "draw new frames", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "slide"}, + {"replace", "replace old columns with new", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "slide"}, + {"scroll", "scroll from right to left", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "slide"}, + {"rscroll", "scroll from left to right", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "slide"}, + {"picture", "display graph in single frame", OFFSET(slide), AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, FLAGS, "slide"}, { NULL } }; @@ -513,6 +552,7 @@ AVFilter ff_vf_thistogram = { .query_formats = query_formats, .inputs = inputs, .outputs = outputs, + .uninit = uninit, .priv_class = &thistogram_class, }; diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c index b75ef2105..1499c05cb 100644 --- a/libavfilter/vf_hue.c +++ b/libavfilter/vf_hue.c @@ -363,9 +363,6 @@ static void apply_lut10(HueContext *s, } } -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) { HueContext *hue = inlink->dst->priv; diff --git a/libavfilter/vf_hwdownload.c b/libavfilter/vf_hwdownload.c index 33af30cf4..c5c760afd 100644 --- a/libavfilter/vf_hwdownload.c +++ b/libavfilter/vf_hwdownload.c @@ -37,26 +37,13 @@ typedef struct HWDownloadContext { static int hwdownload_query_formats(AVFilterContext *avctx) { - AVFilterFormats *infmts = NULL; - AVFilterFormats *outfmts = NULL; - const AVPixFmtDescriptor *desc; + AVFilterFormats *fmts; int err; - for (desc = av_pix_fmt_desc_next(NULL); desc; - desc = av_pix_fmt_desc_next(desc)) { - if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) - err = ff_add_format(&infmts, av_pix_fmt_desc_get_id(desc)); - else - err = ff_add_format(&outfmts, av_pix_fmt_desc_get_id(desc)); - if (err) { - ff_formats_unref(&infmts); - ff_formats_unref(&outfmts); - return err; - } - } - - if ((err = ff_formats_ref(infmts, &avctx->inputs[0]->out_formats)) < 0 || - (err = ff_formats_ref(outfmts, &avctx->outputs[0]->in_formats)) < 0) + if ((err = ff_formats_pixdesc_filter(&fmts, AV_PIX_FMT_FLAG_HWACCEL, 0)) || + (err = ff_formats_ref(fmts, &avctx->inputs[0]->outcfg.formats)) || + (err = ff_formats_pixdesc_filter(&fmts, 0, AV_PIX_FMT_FLAG_HWACCEL)) || + (err = ff_formats_ref(fmts, &avctx->outputs[0]->incfg.formats))) return err; return 0; diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c index 290559a06..a89f69cbe 100644 --- a/libavfilter/vf_hwmap.c +++ b/libavfilter/vf_hwmap.c @@ -42,9 +42,9 @@ static int hwmap_query_formats(AVFilterContext *avctx) int ret; if ((ret = ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_VIDEO), - &avctx->inputs[0]->out_formats)) < 0 || + &avctx->inputs[0]->outcfg.formats)) < 0 || (ret = ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_VIDEO), - &avctx->outputs[0]->in_formats)) < 0) + &avctx->outputs[0]->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/vf_hwupload.c b/libavfilter/vf_hwupload.c index 7c5dd497b..7f2aa90af 100644 --- a/libavfilter/vf_hwupload.c +++ b/libavfilter/vf_hwupload.c @@ -90,9 +90,9 @@ static int hwupload_query_formats(AVFilterContext *avctx) } } - if ((err = ff_formats_ref(input_formats, &avctx->inputs[0]->out_formats)) < 0 || + if ((err = ff_formats_ref(input_formats, &avctx->inputs[0]->outcfg.formats)) < 0 || (err = ff_formats_ref(ff_make_format_list(output_pix_fmts), - &avctx->outputs[0]->in_formats)) < 0) + &avctx->outputs[0]->incfg.formats)) < 0) goto fail; av_hwframe_constraints_free(&constraints); diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c index 8ee082585..afc1b265e 100644 --- a/libavfilter/vf_hwupload_cuda.c +++ b/libavfilter/vf_hwupload_cuda.c @@ -57,7 +57,7 @@ static int cudaupload_query_formats(AVFilterContext *ctx) int ret; static const enum AVPixelFormat input_pix_fmts[] = { - AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_P010, AV_PIX_FMT_P016, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_0RGB32, AV_PIX_FMT_0BGR32, #if CONFIG_VULKAN @@ -71,13 +71,13 @@ static int cudaupload_query_formats(AVFilterContext *ctx) AVFilterFormats *in_fmts = ff_make_format_list(input_pix_fmts); AVFilterFormats *out_fmts; - ret = ff_formats_ref(in_fmts, &ctx->inputs[0]->out_formats); + ret = ff_formats_ref(in_fmts, &ctx->inputs[0]->outcfg.formats); if (ret < 0) return ret; out_fmts = ff_make_format_list(output_pix_fmts); - ret = ff_formats_ref(out_fmts, &ctx->outputs[0]->in_formats); + ret = ff_formats_ref(out_fmts, &ctx->outputs[0]->incfg.formats); if (ret < 0) return ret; diff --git a/libavfilter/vf_identity.c b/libavfilter/vf_identity.c new file mode 100644 index 000000000..60d02e328 --- /dev/null +++ b/libavfilter/vf_identity.c @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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 + * Caculate the Identity between two input videos. + */ + +#include "libavutil/avstring.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "avfilter.h" +#include "drawutils.h" +#include "formats.h" +#include "framesync.h" +#include "internal.h" +#include "video.h" +#include "scene_sad.h" + +typedef struct IdentityContext { + const AVClass *class; + FFFrameSync fs; + double score, min_score, max_score, score_comp[4]; + uint64_t nb_frames; + int is_rgb; + int is_msad; + uint8_t rgba_map[4]; + int max[4]; + char comps[4]; + int nb_components; + int nb_threads; + int planewidth[4]; + int planeheight[4]; + uint64_t **scores; + unsigned (*filter_line)(const uint8_t *buf, const uint8_t *ref, int w); + int (*filter_slice)(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs); + ff_scene_sad_fn sad; +} IdentityContext; + +#define OFFSET(x) offsetof(IdentityContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +static unsigned identity_line_8bit(const uint8_t *main_line, const uint8_t *ref_line, int outw) +{ + unsigned score = 0; + + for (int j = 0; j < outw; j++) + score += main_line[j] == ref_line[j]; + + return score; +} + +static unsigned identity_line_16bit(const uint8_t *mmain_line, const uint8_t *rref_line, int outw) +{ + const uint16_t *main_line = (const uint16_t *)mmain_line; + const uint16_t *ref_line = (const uint16_t *)rref_line; + unsigned score = 0; + + for (int j = 0; j < outw; j++) + score += main_line[j] == ref_line[j]; + + return score; +} + +typedef struct ThreadData { + const uint8_t *main_data[4]; + const uint8_t *ref_data[4]; + int main_linesize[4]; + int ref_linesize[4]; + int planewidth[4]; + int planeheight[4]; + uint64_t **score; + int nb_components; +} ThreadData; + +static +int compute_images_msad(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs) +{ + IdentityContext *s = ctx->priv; + ThreadData *td = arg; + uint64_t *score = td->score[jobnr]; + + for (int c = 0; c < td->nb_components; c++) { + const int outw = td->planewidth[c]; + const int outh = td->planeheight[c]; + const int slice_start = (outh * jobnr) / nb_jobs; + const int slice_end = (outh * (jobnr+1)) / nb_jobs; + const int ref_linesize = td->ref_linesize[c]; + const int main_linesize = td->main_linesize[c]; + const uint8_t *main_line = td->main_data[c] + main_linesize * slice_start; + const uint8_t *ref_line = td->ref_data[c] + ref_linesize * slice_start; + uint64_t m = 0; + + s->sad(main_line, main_linesize, ref_line, ref_linesize, + outw, slice_end - slice_start, &m); + + score[c] = m; + } + + return 0; +} + +static +int compute_images_identity(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs) +{ + IdentityContext *s = ctx->priv; + ThreadData *td = arg; + uint64_t *score = td->score[jobnr]; + + for (int c = 0; c < td->nb_components; c++) { + const int outw = td->planewidth[c]; + const int outh = td->planeheight[c]; + const int slice_start = (outh * jobnr) / nb_jobs; + const int slice_end = (outh * (jobnr+1)) / nb_jobs; + const int ref_linesize = td->ref_linesize[c]; + const int main_linesize = td->main_linesize[c]; + const uint8_t *main_line = td->main_data[c] + main_linesize * slice_start; + const uint8_t *ref_line = td->ref_data[c] + ref_linesize * slice_start; + uint64_t m = 0; + + for (int i = slice_start; i < slice_end; i++) { + m += s->filter_line(main_line, ref_line, outw); + ref_line += ref_linesize; + main_line += main_linesize; + } + score[c] = m; + } + + return 0; +} + +static void set_meta(AVFilterContext *ctx, + AVDictionary **metadata, const char *key, char comp, float d) +{ + char value[128]; + snprintf(value, sizeof(value), "%f", d); + if (comp) { + char key2[128]; + snprintf(key2, sizeof(key2), "lavfi.%s.%s%s%c", + ctx->filter->name, ctx->filter->name, key, comp); + av_dict_set(metadata, key2, value, 0); + } else { + char key2[128]; + snprintf(key2, sizeof(key2), "lavfi.%s.%s%s", + ctx->filter->name, ctx->filter->name, key); + av_dict_set(metadata, key2, value, 0); + } +} + +static int do_identity(FFFrameSync *fs) +{ + AVFilterContext *ctx = fs->parent; + IdentityContext *s = ctx->priv; + AVFrame *master, *ref; + double comp_score[4], score = 0.; + uint64_t comp_sum[4] = { 0 }; + AVDictionary **metadata; + ThreadData td; + int ret; + + ret = ff_framesync_dualinput_get(fs, &master, &ref); + if (ret < 0) + return ret; + if (ctx->is_disabled || !ref) + return ff_filter_frame(ctx->outputs[0], master); + metadata = &master->metadata; + + td.nb_components = s->nb_components; + td.score = s->scores; + for (int c = 0; c < s->nb_components; c++) { + td.main_data[c] = master->data[c]; + td.ref_data[c] = ref->data[c]; + td.main_linesize[c] = master->linesize[c]; + td.ref_linesize[c] = ref->linesize[c]; + td.planewidth[c] = s->planewidth[c]; + td.planeheight[c] = s->planeheight[c]; + } + + ctx->internal->execute(ctx, s->filter_slice, &td, NULL, FFMIN(s->planeheight[1], s->nb_threads)); + + for (int j = 0; j < s->nb_threads; j++) { + for (int c = 0; c < s->nb_components; c++) + comp_sum[c] += s->scores[j][c]; + } + + for (int c = 0; c < s->nb_components; c++) + comp_score[c] = comp_sum[c] / ((double)s->planewidth[c] * s->planeheight[c]); + + for (int c = 0; c < s->nb_components && s->is_msad; c++) + comp_score[c] /= (double)s->max[c]; + + for (int c = 0; c < s->nb_components; c++) + score += comp_score[c]; + score /= s->nb_components; + + s->min_score = FFMIN(s->min_score, score); + s->max_score = FFMAX(s->max_score, score); + + s->score += score; + + for (int j = 0; j < s->nb_components; j++) + s->score_comp[j] += comp_score[j]; + s->nb_frames++; + + for (int j = 0; j < s->nb_components; j++) { + int c = s->is_rgb ? s->rgba_map[j] : j; + set_meta(ctx, metadata, ".", s->comps[j], comp_score[c]); + } + set_meta(ctx, metadata, "_avg", 0, score); + + return ff_filter_frame(ctx->outputs[0], master); +} + +static av_cold int init(AVFilterContext *ctx) +{ + IdentityContext *s = ctx->priv; + + s->fs.on_event = do_identity; + + return 0; +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, +#define PF_NOALPHA(suf) AV_PIX_FMT_YUV420##suf, AV_PIX_FMT_YUV422##suf, AV_PIX_FMT_YUV444##suf +#define PF_ALPHA(suf) AV_PIX_FMT_YUVA420##suf, AV_PIX_FMT_YUVA422##suf, AV_PIX_FMT_YUVA444##suf +#define PF(suf) PF_NOALPHA(suf), PF_ALPHA(suf) + PF(P), PF(P9), PF(P10), PF_NOALPHA(P12), PF_NOALPHA(P14), PF(P16), + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, + AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +static int config_input_ref(AVFilterLink *inlink) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + AVFilterContext *ctx = inlink->dst; + IdentityContext *s = ctx->priv; + + s->nb_threads = ff_filter_get_nb_threads(ctx); + s->nb_components = desc->nb_components; + if (ctx->inputs[0]->w != ctx->inputs[1]->w || + ctx->inputs[0]->h != ctx->inputs[1]->h) { + av_log(ctx, AV_LOG_ERROR, "Width and height of input videos must be same.\n"); + return AVERROR(EINVAL); + } + if (ctx->inputs[0]->format != ctx->inputs[1]->format) { + av_log(ctx, AV_LOG_ERROR, "Inputs must be of same pixel format.\n"); + return AVERROR(EINVAL); + } + + s->is_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0; + s->comps[0] = s->is_rgb ? 'R' : 'Y' ; + s->comps[1] = s->is_rgb ? 'G' : 'U' ; + s->comps[2] = s->is_rgb ? 'B' : 'V' ; + s->comps[3] = 'A'; + + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + + s->scores = av_calloc(s->nb_threads, sizeof(*s->scores)); + if (!s->scores) + return AVERROR(ENOMEM); + + for (int t = 0; t < s->nb_threads && s->scores; t++) { + s->scores[t] = av_calloc(s->nb_components, sizeof(*s->scores[0])); + if (!s->scores[t]) + return AVERROR(ENOMEM); + } + + s->min_score = +INFINITY; + s->max_score = -INFINITY; + + s->max[0] = (1 << desc->comp[0].depth) - 1; + s->max[1] = (1 << desc->comp[1].depth) - 1; + s->max[2] = (1 << desc->comp[2].depth) - 1; + s->max[3] = (1 << desc->comp[3].depth) - 1; + + s->is_msad = !strcmp(ctx->filter->name, "msad"); + s->filter_slice = !s->is_msad ? compute_images_identity : compute_images_msad; + s->filter_line = desc->comp[0].depth > 8 ? identity_line_16bit : identity_line_8bit; + + s->sad = ff_scene_sad_get_fn(desc->comp[0].depth <= 8 ? 8 : 16); + if (!s->sad) + return AVERROR(EINVAL); + + return 0; +} + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + IdentityContext *s = ctx->priv; + AVFilterLink *mainlink = ctx->inputs[0]; + int ret; + + ret = ff_framesync_init_dualinput(&s->fs, ctx); + if (ret < 0) + return ret; + outlink->w = mainlink->w; + outlink->h = mainlink->h; + outlink->time_base = mainlink->time_base; + outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; + outlink->frame_rate = mainlink->frame_rate; + if ((ret = ff_framesync_configure(&s->fs)) < 0) + return ret; + + outlink->time_base = s->fs.time_base; + + if (av_cmp_q(mainlink->time_base, outlink->time_base) || + av_cmp_q(ctx->inputs[1]->time_base, outlink->time_base)) + av_log(ctx, AV_LOG_WARNING, "not matching timebases found between first input: %d/%d and second input %d/%d, results may be incorrect!\n", + mainlink->time_base.num, mainlink->time_base.den, + ctx->inputs[1]->time_base.num, ctx->inputs[1]->time_base.den); + + return 0; +} + +static int activate(AVFilterContext *ctx) +{ + IdentityContext *s = ctx->priv; + return ff_framesync_activate(&s->fs); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + IdentityContext *s = ctx->priv; + + if (s->nb_frames > 0) { + char buf[256]; + + buf[0] = 0; + for (int j = 0; j < s->nb_components; j++) { + int c = s->is_rgb ? s->rgba_map[j] : j; + av_strlcatf(buf, sizeof(buf), " %c:%f", s->comps[j], s->score_comp[c] / s->nb_frames); + } + + av_log(ctx, AV_LOG_INFO, "%s%s average:%f min:%f max:%f\n", + ctx->filter->name, + buf, + s->score / s->nb_frames, + s->min_score, + s->max_score); + } + + ff_framesync_uninit(&s->fs); + for (int t = 0; t < s->nb_threads && s->scores; t++) + av_freep(&s->scores[t]); + av_freep(&s->scores); +} + +static const AVFilterPad identity_inputs[] = { + { + .name = "main", + .type = AVMEDIA_TYPE_VIDEO, + },{ + .name = "reference", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_input_ref, + }, + { NULL } +}; + +static const AVFilterPad identity_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL } +}; + +static const AVOption options[] = { + { NULL } +}; + +#if CONFIG_IDENTITY_FILTER + +#define identity_options options +FRAMESYNC_DEFINE_CLASS(identity, IdentityContext, fs); + +AVFilter ff_vf_identity = { + .name = "identity", + .description = NULL_IF_CONFIG_SMALL("Calculate the Identity between two video streams."), + .preinit = identity_framesync_preinit, + .init = init, + .uninit = uninit, + .query_formats = query_formats, + .activate = activate, + .priv_size = sizeof(IdentityContext), + .priv_class = &identity_class, + .inputs = identity_inputs, + .outputs = identity_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, +}; + +#endif /* CONFIG_IDENTITY_FILTER */ + +#if CONFIG_MSAD_FILTER + +#define msad_options options +FRAMESYNC_DEFINE_CLASS(msad, IdentityContext, fs); + +AVFilter ff_vf_msad = { + .name = "msad", + .description = NULL_IF_CONFIG_SMALL("Calculate the MSAD between two video streams."), + .preinit = msad_framesync_preinit, + .init = init, + .uninit = uninit, + .query_formats = query_formats, + .activate = activate, + .priv_size = sizeof(IdentityContext), + .priv_class = &msad_class, + .inputs = identity_inputs, + .outputs = identity_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, +}; + +#endif /* CONFIG_MSAD_FILTER */ diff --git a/libavfilter/vf_il.c b/libavfilter/vf_il.c index 6cd5f89f7..46af57f96 100644 --- a/libavfilter/vf_il.c +++ b/libavfilter/vf_il.c @@ -84,16 +84,13 @@ AVFILTER_DEFINE_CLASS(il); static int query_formats(AVFilterContext *ctx) { AVFilterFormats *formats = NULL; - int fmt, ret; - - for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_PAL) && - !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) && - (ret = ff_add_format(&formats, fmt)) < 0) - return ret; - } + int ret; + ret = ff_formats_pixdesc_filter(&formats, 0, + AV_PIX_FMT_FLAG_PAL | + AV_PIX_FMT_FLAG_HWACCEL); + if (ret < 0) + return ret; return ff_set_common_formats(ctx, formats); } diff --git a/libavfilter/vf_lagfun.c b/libavfilter/vf_lagfun.c index 1fbc889e3..36b19b3f8 100644 --- a/libavfilter/vf_lagfun.c +++ b/libavfilter/vf_lagfun.c @@ -30,16 +30,16 @@ typedef struct LagfunContext { const AVClass *class; - const AVPixFmtDescriptor *desc; float decay; int planes; int depth; int nb_planes; int linesize[4]; - int height[4]; + int planewidth[4]; + int planeheight[4]; - AVFrame *old; + float *old[4]; int (*lagfun)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); } LagfunContext; @@ -74,100 +74,87 @@ static int query_formats(AVFilterContext *ctx) } typedef struct ThreadData { - AVFrame *in, *out, *old; + AVFrame *in, *out; } ThreadData; -static int lagfun_frame8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - LagfunContext *s = ctx->priv; - const float decay = s->decay; - ThreadData *td = arg; - AVFrame *in = td->in; - AVFrame *out = td->out; - AVFrame *old = td->old; - - for (int p = 0; p < s->nb_planes; p++) { - const int slice_start = (s->height[p] * jobnr) / nb_jobs; - const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; - const uint8_t *src = in->data[p] + slice_start * in->linesize[p]; - const uint8_t *osrc = old->data[p] + slice_start * old->linesize[p]; - uint8_t *dst = out->data[p] + slice_start * out->linesize[p]; - - if (!((1 << p) & s->planes)) { - av_image_copy_plane(dst, out->linesize[p], - src, in->linesize[p], - s->linesize[p], slice_end - slice_start); - continue; - } - - for (int y = slice_start; y < slice_end; y++) { - for (int x = 0; x < s->linesize[p]; x++) - dst[x] = FFMAX(src[x], osrc[x] * decay); - - src += in->linesize[p]; - osrc += old->linesize[p]; - dst += out->linesize[p]; - } - } - - return 0; +#define LAGFUN(name, type) \ +static int lagfun_frame##name(AVFilterContext *ctx, void *arg, \ + int jobnr, int nb_jobs) \ +{ \ + LagfunContext *s = ctx->priv; \ + const float decay = s->decay; \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; \ + const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; \ + const type *src = (const type *)in->data[p] + \ + slice_start * in->linesize[p] / sizeof(type); \ + float *osrc = s->old[p] + slice_start * s->planewidth[p]; \ + type *dst = (type *)out->data[p] + \ + slice_start * out->linesize[p] / sizeof(type); \ + \ + if (!((1 << p) & s->planes)) { \ + av_image_copy_plane((uint8_t *)dst, out->linesize[p], \ + (const uint8_t *)src, in->linesize[p], \ + s->linesize[p], slice_end - slice_start); \ + continue; \ + } \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + for (int x = 0; x < s->planewidth[p]; x++) { \ + float v = FFMAX(src[x], osrc[x] * decay); \ + \ + osrc[x] = v; \ + if (ctx->is_disabled) { \ + dst[x] = src[x]; \ + } else { \ + dst[x] = lrintf(v); \ + } \ + } \ + \ + src += in->linesize[p] / sizeof(type); \ + osrc += s->planewidth[p]; \ + dst += out->linesize[p] / sizeof(type); \ + } \ + } \ + \ + return 0; \ } -static int lagfun_frame16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - LagfunContext *s = ctx->priv; - const float decay = s->decay; - ThreadData *td = arg; - AVFrame *in = td->in; - AVFrame *out = td->out; - AVFrame *old = td->old; - - for (int p = 0; p < s->nb_planes; p++) { - const int slice_start = (s->height[p] * jobnr) / nb_jobs; - const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; - const uint16_t *src = (const uint16_t *)in->data[p] + slice_start * in->linesize[p] / 2; - const uint16_t *osrc = (const uint16_t *)old->data[p] + slice_start * old->linesize[p] / 2; - uint16_t *dst = (uint16_t *)out->data[p] + slice_start * out->linesize[p] / 2; - - if (!((1 << p) & s->planes)) { - av_image_copy_plane((uint8_t *)dst, out->linesize[p], - (uint8_t *)src, in->linesize[p], - s->linesize[p], slice_end - slice_start); - continue; - } - - for (int y = slice_start; y < slice_end; y++) { - for (int x = 0; x < s->linesize[p] / 2; x++) - dst[x] = FFMAX(src[x], osrc[x] * decay); - - src += in->linesize[p] / 2; - osrc += old->linesize[p] / 2; - dst += out->linesize[p] / 2; - } - } - - return 0; -} +LAGFUN(8, uint8_t) +LAGFUN(16, uint16_t) static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; LagfunContext *s = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; + const AVPixFmtDescriptor *desc; int ret; - s->desc = av_pix_fmt_desc_get(outlink->format); - if (!s->desc) + desc = av_pix_fmt_desc_get(outlink->format); + if (!desc) return AVERROR_BUG; s->nb_planes = av_pix_fmt_count_planes(outlink->format); - s->depth = s->desc->comp[0].depth; + s->depth = desc->comp[0].depth; s->lagfun = s->depth <= 8 ? lagfun_frame8 : lagfun_frame16; if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) return ret; - s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h); - s->height[0] = s->height[3] = inlink->h; + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + + for (int p = 0; p < s->nb_planes; p++) { + s->old[p] = av_calloc(s->planewidth[p] * s->planeheight[p], sizeof(*s->old[0])); + if (!s->old[p]) + return AVERROR(ENOMEM); + } return 0; } @@ -180,11 +167,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ThreadData td; AVFrame *out; - if (!s->old) { - s->old = av_frame_clone(in); - return ff_filter_frame(outlink, in); - } - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { av_frame_free(&in); @@ -194,12 +176,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) td.out = out; td.in = in; - td.old = s->old; - ctx->internal->execute(ctx, s->lagfun, &td, NULL, FFMIN(s->height[1], ff_filter_get_nb_threads(ctx))); + ctx->internal->execute(ctx, s->lagfun, &td, NULL, FFMIN(s->planeheight[1], ff_filter_get_nb_threads(ctx))); - av_frame_free(&s->old); av_frame_free(&in); - s->old = av_frame_clone(out); return ff_filter_frame(outlink, out); } @@ -207,11 +186,12 @@ static av_cold void uninit(AVFilterContext *ctx) { LagfunContext *s = ctx->priv; - av_frame_free(&s->old); + for (int p = 0; p < s->nb_planes; p++) + av_freep(&s->old[p]); } #define OFFSET(x) offsetof(LagfunContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM static const AVOption lagfun_options[] = { { "decay", "set decay", OFFSET(decay), AV_OPT_TYPE_FLOAT, {.dbl=.95}, 0, 1, FLAGS }, @@ -248,5 +228,6 @@ AVFilter ff_vf_lagfun = { .uninit = uninit, .outputs = outputs, .inputs = inputs, - .flags = AVFILTER_FLAG_SLICE_THREADS, + .flags = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, + .process_command = ff_filter_process_command, }; diff --git a/libavfilter/vf_lenscorrection.c b/libavfilter/vf_lenscorrection.c index bb8ea3734..9386f795d 100644 --- a/libavfilter/vf_lenscorrection.c +++ b/libavfilter/vf_lenscorrection.c @@ -26,30 +26,43 @@ #include #include +#include "libavutil/colorspace.h" #include "libavutil/opt.h" #include "libavutil/intreadwrite.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "drawutils.h" #include "internal.h" #include "video.h" typedef struct LenscorrectionCtx { const AVClass *av_class; - int width; - int height; - int hsub, vsub; + int planewidth[4]; + int planeheight[4]; + int depth; int nb_planes; double cx, cy, k1, k2; + int interpolation; + uint8_t fill_rgba[4]; + int fill_color[4]; + int32_t *correction[4]; + + int (*filter_slice)(AVFilterContext *ctx, void *arg, int job, int nb_jobs, int plane); } LenscorrectionCtx; -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define OFFSET(x) offsetof(LenscorrectionCtx, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption lenscorrection_options[] = { - { "cx", "set relative center x", offsetof(LenscorrectionCtx, cx), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, .flags=FLAGS }, - { "cy", "set relative center y", offsetof(LenscorrectionCtx, cy), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, .flags=FLAGS }, - { "k1", "set quadratic distortion factor", offsetof(LenscorrectionCtx, k1), AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -1, 1, .flags=FLAGS }, - { "k2", "set double quadratic distortion factor", offsetof(LenscorrectionCtx, k2), AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -1, 1, .flags=FLAGS }, + { "cx", "set relative center x", OFFSET(cx), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, .flags=FLAGS }, + { "cy", "set relative center y", OFFSET(cy), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, .flags=FLAGS }, + { "k1", "set quadratic distortion factor", OFFSET(k1), AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -1, 1, .flags=FLAGS }, + { "k2", "set double quadratic distortion factor", OFFSET(k2), AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -1, 1, .flags=FLAGS }, + { "i", "set interpolation type", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=0}, 0, 64, .flags=FLAGS, "i" }, + { "nearest", "nearest neighbour", 0, AV_OPT_TYPE_CONST, {.i64=0},0, 0, .flags=FLAGS, "i" }, + { "bilinear", "bilinear", 0, AV_OPT_TYPE_CONST, {.i64=1},0, 0, .flags=FLAGS, "i" }, + { "fc", "set the color of the unmapped pixels", OFFSET(fill_rgba), AV_OPT_TYPE_COLOR, {.str="black@0"}, .flags = FLAGS }, { NULL } }; @@ -57,54 +70,137 @@ AVFILTER_DEFINE_CLASS(lenscorrection); typedef struct ThreadData { AVFrame *in, *out; - int w, h; - int plane; - int xcenter, ycenter; - int32_t *correction; } ThreadData; -static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) -{ - ThreadData *td = arg; - AVFrame *in = td->in; - AVFrame *out = td->out; - - const int w = td->w, h = td->h; - const int xcenter = td->xcenter; - const int ycenter = td->ycenter; - const int start = (h * job ) / nb_jobs; - const int end = (h * (job+1)) / nb_jobs; - const int plane = td->plane; - const int inlinesize = in->linesize[plane]; - const int outlinesize = out->linesize[plane]; - const uint8_t *indata = in->data[plane]; - uint8_t *outrow = out->data[plane] + start * outlinesize; - int i; - for (i = start; i < end; i++, outrow += outlinesize) { - const int off_y = i - ycenter; - uint8_t *out = outrow; - int j; - for (j = 0; j < w; j++) { - const int off_x = j - xcenter; - const int64_t radius_mult = td->correction[j + i*w]; - const int x = xcenter + ((radius_mult * off_x + (1<<23))>>24); - const int y = ycenter + ((radius_mult * off_y + (1<<23))>>24); - const char isvalid = x > 0 && x < w - 1 && y > 0 && y < h - 1; - *out++ = isvalid ? indata[y * inlinesize + x] : 0; - } - } - return 0; +#define NEAREST(type, name) \ +static int filter##name##_slice(AVFilterContext *ctx, void *arg, int job, \ + int nb_jobs, int plane) \ +{ \ + LenscorrectionCtx *rect = ctx->priv; \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + \ + const int32_t *correction = rect->correction[plane]; \ + const int fill_color = rect->fill_color[plane]; \ + const int w = rect->planewidth[plane], h = rect->planeheight[plane]; \ + const int xcenter = rect->cx * w; \ + const int ycenter = rect->cy * h; \ + const int start = (h * job ) / nb_jobs; \ + const int end = (h * (job+1)) / nb_jobs; \ + const int inlinesize = in->linesize[plane] / sizeof(type); \ + const int outlinesize = out->linesize[plane] / sizeof(type); \ + const type *indata = (const type *)in->data[plane]; \ + type *outrow = (type *)out->data[plane] + start * outlinesize; \ + for (int i = start; i < end; i++, outrow += outlinesize) { \ + const int off_y = i - ycenter; \ + type *out = outrow; \ + for (int j = 0; j < w; j++) { \ + const int off_x = j - xcenter; \ + const int64_t radius_mult = correction[j + i*w]; \ + const int x = xcenter + ((radius_mult * off_x + (1<<23))>>24); \ + const int y = ycenter + ((radius_mult * off_y + (1<<23))>>24); \ + const char isvalid = x >= 0 && x < w && y >= 0 && y < h; \ + *out++ = isvalid ? indata[y * inlinesize + x] : fill_color; \ + } \ + } \ + return 0; \ } + +NEAREST(uint8_t, 8) +NEAREST(uint16_t, 16) + +#define BILINEAR(type, name) \ +static int filter##name##_slice_bilinear(AVFilterContext *ctx, void *arg, \ + int job, int nb_jobs, int plane) \ +{ \ + LenscorrectionCtx *rect = ctx->priv; \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + \ + const int32_t *correction = rect->correction[plane]; \ + const int fill_color = rect->fill_color[plane]; \ + const int depth = rect->depth; \ + const uint64_t max = (1 << 24) - 1; \ + const uint64_t add = (1 << 23); \ + const int w = rect->planewidth[plane], h = rect->planeheight[plane]; \ + const int xcenter = rect->cx * w; \ + const int ycenter = rect->cy * h; \ + const int start = (h * job ) / nb_jobs; \ + const int end = (h * (job+1)) / nb_jobs; \ + const int inlinesize = in->linesize[plane] / sizeof(type); \ + const int outlinesize = out->linesize[plane] / sizeof(type); \ + const type *indata = (const type *)in->data[plane]; \ + type *outrow = (type *)out->data[plane] + start * outlinesize; \ + \ + for (int i = start; i < end; i++, outrow += outlinesize) { \ + const int off_y = i - ycenter; \ + type *out = outrow; \ + \ + for (int j = 0; j < w; j++) { \ + const int off_x = j - xcenter; \ + const int64_t radius_mult = correction[j + i*w]; \ + const int x = xcenter + ((radius_mult * off_x + (1<<23)) >> 24); \ + const int y = ycenter + ((radius_mult * off_y + (1<<23)) >> 24); \ + const char isvalid = x >= 0 && x <= w - 1 && y >= 0 && y <= h - 1; \ + \ + if (isvalid) { \ + const int nx = FFMIN(x + 1, w - 1); \ + const int ny = FFMIN(y + 1, h - 1); \ + const uint64_t du = off_x >= 0 ? (radius_mult * off_x + add) & max : max - ((radius_mult * -off_x + add) & max); \ + const uint64_t dv = off_y >= 0 ? (radius_mult * off_y + add) & max : max - ((radius_mult * -off_y + add) & max); \ + const uint64_t p0 = indata[ y * inlinesize + x]; \ + const uint64_t p1 = indata[ y * inlinesize + nx]; \ + const uint64_t p2 = indata[ny * inlinesize + x]; \ + const uint64_t p3 = indata[ny * inlinesize + nx]; \ + uint64_t sum = 0; \ + \ + sum += (max - du) * (max - dv) * p0; \ + sum += ( du) * (max - dv) * p1; \ + sum += (max - du) * ( dv) * p2; \ + sum += ( du) * ( dv) * p3; \ + \ + out[j] = av_clip_uintp2_c((sum + (1ULL << 47)) >> 48, depth); \ + } else { \ + out[j] = fill_color; \ + } \ + } \ + } \ + \ + return 0; \ +} + +BILINEAR(uint8_t, 8) +BILINEAR(uint16_t, 16) + static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_YUV422P, - AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, + AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, + AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_NONE }; AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); @@ -123,17 +219,86 @@ static av_cold void uninit(AVFilterContext *ctx) } } -static int config_props(AVFilterLink *outlink) +static void calc_correction(AVFilterContext *ctx, int plane) +{ + LenscorrectionCtx *rect = ctx->priv; + int w = rect->planewidth[plane]; + int h = rect->planeheight[plane]; + int xcenter = rect->cx * w; + int ycenter = rect->cy * h; + int k1 = rect->k1 * (1<<24); + int k2 = rect->k2 * (1<<24); + const int64_t r2inv = (4LL<<60) / (w * w + h * h); + + for (int j = 0; j < h; j++) { + const int off_y = j - ycenter; + const int off_y2 = off_y * off_y; + for (int i = 0; i < w; i++) { + const int off_x = i - xcenter; + const int64_t r2 = ((off_x * off_x + off_y2) * r2inv + (1LL<<31)) >> 32; + const int64_t r4 = (r2 * r2 + (1<<27)) >> 28; + const int radius_mult = (r2 * k1 + r4 * k2 + (1LL<<27) + (1LL<<52))>>28; + rect->correction[plane][j * w + i] = radius_mult; + } + } +} + +static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; LenscorrectionCtx *rect = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(inlink->format); - rect->hsub = pixdesc->log2_chroma_w; - rect->vsub = pixdesc->log2_chroma_h; - outlink->w = rect->width = inlink->w; - outlink->h = rect->height = inlink->h; + int is_rgb = !!(pixdesc->flags & AV_PIX_FMT_FLAG_RGB); + uint8_t rgba_map[4]; + int factor; + + ff_fill_rgba_map(rgba_map, inlink->format); + rect->depth = pixdesc->comp[0].depth; + factor = 1 << (rect->depth - 8); + rect->planeheight[1] = rect->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, pixdesc->log2_chroma_h); + rect->planeheight[0] = rect->planeheight[3] = inlink->h; + rect->planewidth[1] = rect->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, pixdesc->log2_chroma_w); + rect->planewidth[0] = rect->planewidth[3] = inlink->w; rect->nb_planes = av_pix_fmt_count_planes(inlink->format); + rect->filter_slice = rect->depth <= 8 ? filter8_slice : filter16_slice; + if (rect->interpolation) + rect->filter_slice = rect->depth <= 8 ? filter8_slice_bilinear : filter16_slice_bilinear; + + if (is_rgb) { + rect->fill_color[rgba_map[0]] = rect->fill_rgba[0] * factor; + rect->fill_color[rgba_map[1]] = rect->fill_rgba[1] * factor; + rect->fill_color[rgba_map[2]] = rect->fill_rgba[2] * factor; + rect->fill_color[rgba_map[3]] = rect->fill_rgba[3] * factor; + } else { + rect->fill_color[0] = RGB_TO_Y_BT709(rect->fill_rgba[0], rect->fill_rgba[1], rect->fill_rgba[2]) * factor; + rect->fill_color[1] = RGB_TO_U_BT709(rect->fill_rgba[0], rect->fill_rgba[1], rect->fill_rgba[2], 0) * factor; + rect->fill_color[2] = RGB_TO_V_BT709(rect->fill_rgba[0], rect->fill_rgba[1], rect->fill_rgba[2], 0) * factor; + rect->fill_color[3] = rect->fill_rgba[3] * factor; + } + + for (int plane = 0; plane < rect->nb_planes; plane++) { + int w = rect->planewidth[plane]; + int h = rect->planeheight[plane]; + + if (!rect->correction[plane]) + rect->correction[plane] = av_malloc_array(w, h * sizeof(**rect->correction)); + if (!rect->correction[plane]) + return AVERROR(ENOMEM); + calc_correction(ctx, plane); + } + + return 0; +} + +static int filter_slice(AVFilterContext *ctx, void *arg, int job, + int nb_jobs) +{ + LenscorrectionCtx *rect = ctx->priv; + + for (int plane = 0; plane < rect->nb_planes; plane++) + rect->filter_slice(ctx, arg, job, nb_jobs, plane); + return 0; } @@ -141,9 +306,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; - LenscorrectionCtx *rect = (LenscorrectionCtx*)ctx->priv; + LenscorrectionCtx *rect = ctx->priv; AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - int plane; + ThreadData td; if (!out) { av_frame_free(&in); @@ -152,52 +317,28 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) av_frame_copy_props(out, in); - for (plane = 0; plane < rect->nb_planes; ++plane) { - int hsub = plane == 1 || plane == 2 ? rect->hsub : 0; - int vsub = plane == 1 || plane == 2 ? rect->vsub : 0; - int w = AV_CEIL_RSHIFT(rect->width, hsub); - int h = AV_CEIL_RSHIFT(rect->height, vsub); - int xcenter = rect->cx * w; - int ycenter = rect->cy * h; - int k1 = rect->k1 * (1<<24); - int k2 = rect->k2 * (1<<24); - ThreadData td = { - .in = in, - .out = out, - .w = w, - .h = h, - .xcenter = xcenter, - .ycenter = ycenter, - .plane = plane}; - - if (!rect->correction[plane]) { - int i,j; - const int64_t r2inv = (4LL<<60) / (w * w + h * h); - - rect->correction[plane] = av_malloc_array(w, h * sizeof(**rect->correction)); - if (!rect->correction[plane]) - return AVERROR(ENOMEM); - for (j = 0; j < h; j++) { - const int off_y = j - ycenter; - const int off_y2 = off_y * off_y; - for (i = 0; i < w; i++) { - const int off_x = i - xcenter; - const int64_t r2 = ((off_x * off_x + off_y2) * r2inv + (1LL<<31)) >> 32; - const int64_t r4 = (r2 * r2 + (1<<27)) >> 28; - const int radius_mult = (r2 * k1 + r4 * k2 + (1LL<<27) + (1LL<<52))>>28; - rect->correction[plane][j * w + i] = radius_mult; - } - } - } - - td.correction = rect->correction[plane]; - ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, ff_filter_get_nb_threads(ctx))); - } + td.in = in; td.out = out; + ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(rect->planeheight[1], ff_filter_get_nb_threads(ctx))); av_frame_free(&in); return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, + const char *cmd, + const char *arg, + char *res, + int res_len, + int flags) +{ + int ret = ff_filter_process_command(ctx, cmd, arg, res, res_len, flags); + + if (ret < 0) + return ret; + + return config_output(ctx->outputs[0]); +} + static const AVFilterPad lenscorrection_inputs[] = { { .name = "default", @@ -211,7 +352,7 @@ static const AVFilterPad lenscorrection_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, + .config_props = config_output, }, { NULL } }; @@ -225,5 +366,6 @@ AVFilter ff_vf_lenscorrection = { .outputs = lenscorrection_outputs, .priv_class = &lenscorrection_class, .uninit = uninit, - .flags = AVFILTER_FLAG_SLICE_THREADS, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; diff --git a/libavfilter/vf_lensfun.c b/libavfilter/vf_lensfun.c index 089121ed0..430daa941 100644 --- a/libavfilter/vf_lensfun.c +++ b/libavfilter/vf_lensfun.c @@ -136,27 +136,36 @@ static av_cold int init(AVFilterContext *ctx) const lfCamera **cameras; const lfLens **lenses; - if (!lensfun->make) { - av_log(ctx, AV_LOG_FATAL, "Option \"make\" not specified\n"); - return AVERROR(EINVAL); - } else if (!lensfun->model) { - av_log(ctx, AV_LOG_FATAL, "Option \"model\" not specified\n"); - return AVERROR(EINVAL); - } else if (!lensfun->lens_model) { - av_log(ctx, AV_LOG_FATAL, "Option \"lens_model\" not specified\n"); - return AVERROR(EINVAL); - } - - lensfun->lens = lf_lens_new(); - lensfun->camera = lf_camera_new(); - - db = lf_db_new(); + db = lf_db_create(); if (lf_db_load(db) != LF_NO_ERROR) { lf_db_destroy(db); av_log(ctx, AV_LOG_FATAL, "Failed to load lensfun database\n"); return AVERROR_INVALIDDATA; } + if (!lensfun->make || !lensfun->model) { + const lfCamera *const *cameras = lf_db_get_cameras(db); + + av_log(ctx, AV_LOG_FATAL, "Option \"make\" or option \"model\" not specified\n"); + av_log(ctx, AV_LOG_INFO, "Available values for \"make\" and \"model\":\n"); + for (int i = 0; cameras && cameras[i]; i++) + av_log(ctx, AV_LOG_INFO, "\t%s\t%s\n", cameras[i]->Maker, cameras[i]->Model); + lf_db_destroy(db); + return AVERROR(EINVAL); + } else if (!lensfun->lens_model) { + const lfLens *const *lenses = lf_db_get_lenses(db); + + av_log(ctx, AV_LOG_FATAL, "Option \"lens_model\" not specified\n"); + av_log(ctx, AV_LOG_INFO, "Available values for \"lens_model\":\n"); + for (int i = 0; lenses && lenses[i]; i++) + av_log(ctx, AV_LOG_INFO, "\t%s\t(make %s)\n", lenses[i]->Model, lenses[i]->Maker); + lf_db_destroy(db); + return AVERROR(EINVAL); + } + + lensfun->lens = lf_lens_create(); + lensfun->camera = lf_camera_create(); + cameras = lf_db_find_cameras(db, lensfun->make, lensfun->model); if (cameras && *cameras) { lf_camera_copy(lensfun->camera, *cameras); @@ -169,7 +178,7 @@ static av_cold int init(AVFilterContext *ctx) } lf_free(cameras); - lenses = lf_db_find_lenses_hd(db, lensfun->camera, NULL, lensfun->lens_model, 0); + lenses = lf_db_find_lenses(db, lensfun->camera, NULL, lensfun->lens_model, 0); if (lenses && *lenses) { lf_lens_copy(lensfun->lens, *lenses); av_log(ctx, AV_LOG_INFO, "Using lens %s\n", lensfun->lens->Model); @@ -210,30 +219,23 @@ static int config_props(AVFilterLink *inlink) LensfunContext *lensfun = ctx->priv; int index; float a; - int lensfun_mode = 0; if (!lensfun->modifier) { if (lensfun->camera && lensfun->lens) { - lensfun->modifier = lf_modifier_new(lensfun->lens, - lensfun->camera->CropFactor, - inlink->w, - inlink->h); + lensfun->modifier = lf_modifier_create(lensfun->lens, + lensfun->focal_length, + lensfun->camera->CropFactor, + inlink->w, + inlink->h, LF_PF_U8, lensfun->reverse); if (lensfun->mode & VIGNETTING) - lensfun_mode |= LF_MODIFY_VIGNETTING; - if (lensfun->mode & GEOMETRY_DISTORTION) - lensfun_mode |= LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE; + lf_modifier_enable_vignetting_correction(lensfun->modifier, lensfun->aperture, lensfun->focus_distance); + if (lensfun->mode & GEOMETRY_DISTORTION) { + lf_modifier_enable_distortion_correction(lensfun->modifier); + lf_modifier_enable_projection_transform(lensfun->modifier, lensfun->target_geometry); + lf_modifier_enable_scaling(lensfun->modifier, lensfun->scale); + } if (lensfun->mode & SUBPIXEL_DISTORTION) - lensfun_mode |= LF_MODIFY_TCA; - lf_modifier_initialize(lensfun->modifier, - lensfun->lens, - LF_PF_U8, - lensfun->focal_length, - lensfun->aperture, - lensfun->focus_distance, - lensfun->scale, - lensfun->target_geometry, - lensfun_mode, - lensfun->reverse); + lf_modifier_enable_tca_correction(lensfun->modifier); } else { // lensfun->camera and lensfun->lens should have been initialized return AVERROR_BUG; diff --git a/libavfilter/vf_libvmaf.c b/libavfilter/vf_libvmaf.c index 14c3216b3..4d49127ef 100644 --- a/libavfilter/vf_libvmaf.c +++ b/libavfilter/vf_libvmaf.c @@ -74,7 +74,7 @@ typedef struct LIBVMAFContext { static const AVOption libvmaf_options[] = { {"model_path", "Set the model to be used for computing vmaf.", OFFSET(model_path), AV_OPT_TYPE_STRING, {.str="/usr/local/share/model/vmaf_v0.6.1.pkl"}, 0, 1, FLAGS}, {"log_path", "Set the file path to be used to store logs.", OFFSET(log_path), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS}, - {"log_fmt", "Set the format of the log (xml or json).", OFFSET(log_fmt), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS}, + {"log_fmt", "Set the format of the log (csv, json or xml).", OFFSET(log_fmt), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS}, {"enable_transform", "Enables transform for computing vmaf.", OFFSET(enable_transform), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"phone_model", "Invokes the phone model that will generate higher VMAF scores.", OFFSET(phone_model), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"psnr", "Enables computing psnr along with vmaf.", OFFSET(psnr), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, diff --git a/libavfilter/vf_limiter.c b/libavfilter/vf_limiter.c index 8db28fee6..1779c6394 100644 --- a/libavfilter/vf_limiter.c +++ b/libavfilter/vf_limiter.c @@ -46,7 +46,7 @@ typedef struct LimiterContext { } LimiterContext; #define OFFSET(x) offsetof(LimiterContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption limiter_options[] = { { "min", "set min value", OFFSET(min), AV_OPT_TYPE_INT, {.i64=0}, 0, 65535, .flags = FLAGS }, @@ -133,7 +133,7 @@ static void limiter16(const uint8_t *ssrc, uint8_t *ddst, } } -static int config_props(AVFilterLink *inlink) +static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; LimiterContext *s = ctx->priv; @@ -230,12 +230,24 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_input(ctx->inputs[0]); +} + static const AVFilterPad inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .filter_frame = filter_frame, - .config_props = config_props, + .config_props = config_input, }, { NULL } }; @@ -258,4 +270,5 @@ AVFilter ff_vf_limiter = { .inputs = inputs, .outputs = outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index 1fdc5e181..1a94e1cf7 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -81,7 +81,7 @@ typedef struct LutContext { #define A 3 #define OFFSET(x) offsetof(LutContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption options[] = { { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS }, @@ -566,6 +566,17 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + + if (ret < 0) + return ret; + + return config_props(ctx->inputs[0]); +} + static const AVFilterPad inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, @@ -592,7 +603,9 @@ static const AVFilterPad outputs[] = { .query_formats = query_formats, \ .inputs = inputs, \ .outputs = outputs, \ - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, \ + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | \ + AVFILTER_FLAG_SLICE_THREADS, \ + .process_command = process_command, \ } #if CONFIG_LUT_FILTER @@ -654,17 +667,12 @@ AVFILTER_DEFINE_CLASS(negate); static av_cold int negate_init(AVFilterContext *ctx) { LutContext *s = ctx->priv; - int i; - av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", s->negate_alpha); - - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { s->comp_expr_str[i] = av_strdup((i == 3 && !s->negate_alpha) ? "val" : "negval"); - if (!s->comp_expr_str[i]) { - uninit(ctx); + if (!s->comp_expr_str[i]) return AVERROR(ENOMEM); - } } return 0; diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c index 7a204f5f1..8de8e11fc 100644 --- a/libavfilter/vf_lut2.c +++ b/libavfilter/vf_lut2.c @@ -79,12 +79,13 @@ typedef struct ThreadData { #define OFFSET(x) offsetof(LUT2Context, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption options[] = { - { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, - { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, - { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, - { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, + { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = TFLAGS }, + { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = TFLAGS }, + { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = TFLAGS }, + { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = TFLAGS }, { "d", "set output depth", OFFSET(odepth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 16, .flags = FLAGS }, { NULL } }; @@ -177,7 +178,7 @@ static int query_formats(AVFilterContext *ctx) if (s->tlut2 || !s->odepth) return ff_set_common_formats(ctx, ff_make_format_list(all_pix_fmts)); - ret = ff_formats_ref(ff_make_format_list(all_pix_fmts), &ctx->inputs[0]->out_formats); + ret = ff_formats_ref(ff_make_format_list(all_pix_fmts), &ctx->inputs[0]->outcfg.formats); if (ret < 0) return ret; @@ -192,7 +193,7 @@ static int query_formats(AVFilterContext *ctx) return AVERROR(EINVAL); } - return ff_formats_ref(ff_make_format_list(pix_fmts), &ctx->outputs[0]->in_formats); + return ff_formats_ref(ff_make_format_list(pix_fmts), &ctx->outputs[0]->incfg.formats); } static int config_inputx(AVFilterLink *inlink) @@ -353,7 +354,8 @@ static int config_output(AVFilterLink *outlink) } for (p = 0; p < s->nb_planes; p++) { - s->lut[p] = av_malloc_array(1 << s->depth, sizeof(uint16_t)); + if (!s->lut[p]) + s->lut[p] = av_malloc_array(1 << s->depth, sizeof(uint16_t)); if (!s->lut[p]) return AVERROR(ENOMEM); } @@ -543,6 +545,17 @@ static const AVFilterPad outputs[] = { { NULL } }; +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + + if (ret < 0) + return ret; + + return config_output(ctx->outputs[0]); +} + #define lut2_options options FRAMESYNC_DEFINE_CLASS(lut2, LUT2Context, fs); @@ -560,6 +573,7 @@ AVFilter ff_vf_lut2 = { .outputs = outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #if CONFIG_TLUT2_FILTER @@ -610,10 +624,10 @@ static int tlut2_filter_frame(AVFilterLink *inlink, AVFrame *frame) } static const AVOption tlut2_options[] = { - { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, - { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, - { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, - { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, + { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = TFLAGS }, + { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = TFLAGS }, + { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = TFLAGS }, + { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = TFLAGS }, { NULL } }; @@ -650,6 +664,7 @@ AVFilter ff_vf_tlut2 = { .outputs = tlut2_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c index 6730a424c..8b1aeb75e 100644 --- a/libavfilter/vf_lut3d.c +++ b/libavfilter/vf_lut3d.c @@ -49,6 +49,8 @@ enum interp_mode { INTERPOLATE_NEAREST, INTERPOLATE_TRILINEAR, INTERPOLATE_TETRAHEDRAL, + INTERPOLATE_PYRAMID, + INTERPOLATE_PRISM, NB_INTERP_MODE }; @@ -98,16 +100,19 @@ typedef struct ThreadData { #define OFFSET(x) offsetof(LUT3DContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM #define COMMON_OPTIONS \ - { "interp", "select interpolation mode", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=INTERPOLATE_TETRAHEDRAL}, 0, NB_INTERP_MODE-1, FLAGS, "interp_mode" }, \ - { "nearest", "use values from the nearest defined points", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_NEAREST}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \ - { "trilinear", "interpolate values using the 8 points defining a cube", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TRILINEAR}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \ - { "tetrahedral", "interpolate values using a tetrahedron", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TETRAHEDRAL}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \ + { "interp", "select interpolation mode", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=INTERPOLATE_TETRAHEDRAL}, 0, NB_INTERP_MODE-1, TFLAGS, "interp_mode" }, \ + { "nearest", "use values from the nearest defined points", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_NEAREST}, 0, 0, TFLAGS, "interp_mode" }, \ + { "trilinear", "interpolate values using the 8 points defining a cube", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TRILINEAR}, 0, 0, TFLAGS, "interp_mode" }, \ + { "tetrahedral", "interpolate values using a tetrahedron", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TETRAHEDRAL}, 0, 0, TFLAGS, "interp_mode" }, \ + { "pyramid", "interpolate values using a pyramid", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_PYRAMID}, 0, 0, TFLAGS, "interp_mode" }, \ + { "prism", "interpolate values using a prism", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_PRISM}, 0, 0, TFLAGS, "interp_mode" }, \ { NULL } #define EXPONENT_MASK 0x7F800000 #define MANTISSA_MASK 0x007FFFFF -#define SIGN_MASK 0x7FFFFFFF +#define SIGN_MASK 0x80000000 static inline float sanitizef(float f) { @@ -120,7 +125,7 @@ static inline float sanitizef(float f) return 0.0f; } else if (t.i & SIGN_MASK) { // -INF - return FLT_MIN; + return -FLT_MAX; } else { // +INF return FLT_MAX; @@ -185,6 +190,101 @@ static inline struct rgbvec interp_trilinear(const LUT3DContext *lut3d, return c; } +static inline struct rgbvec interp_pyramid(const LUT3DContext *lut3d, + const struct rgbvec *s) +{ + const int lutsize2 = lut3d->lutsize2; + const int lutsize = lut3d->lutsize; + const int prev[] = {PREV(s->r), PREV(s->g), PREV(s->b)}; + const int next[] = {NEXT(s->r), NEXT(s->g), NEXT(s->b)}; + const struct rgbvec d = {s->r - prev[0], s->g - prev[1], s->b - prev[2]}; + const struct rgbvec c000 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + prev[2]]; + const struct rgbvec c111 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + next[2]]; + struct rgbvec c; + + if (d.g > d.r && d.b > d.r) { + const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]]; + const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]]; + const struct rgbvec c011 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + next[2]]; + + c.r = c000.r + (c111.r - c011.r) * d.r + (c010.r - c000.r) * d.g + (c001.r - c000.r) * d.b + + (c011.r - c001.r - c010.r + c000.r) * d.g * d.b; + c.g = c000.g + (c111.g - c011.g) * d.r + (c010.g - c000.g) * d.g + (c001.g - c000.g) * d.b + + (c011.g - c001.g - c010.g + c000.g) * d.g * d.b; + c.b = c000.b + (c111.b - c011.b) * d.r + (c010.b - c000.b) * d.g + (c001.b - c000.b) * d.b + + (c011.b - c001.b - c010.b + c000.b) * d.g * d.b; + } else if (d.r > d.g && d.b > d.g) { + const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]]; + const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]]; + const struct rgbvec c101 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + next[2]]; + + c.r = c000.r + (c100.r - c000.r) * d.r + (c111.r - c101.r) * d.g + (c001.r - c000.r) * d.b + + (c101.r - c001.r - c100.r + c000.r) * d.r * d.b; + c.g = c000.g + (c100.g - c000.g) * d.r + (c111.g - c101.g) * d.g + (c001.g - c000.g) * d.b + + (c101.g - c001.g - c100.g + c000.g) * d.r * d.b; + c.b = c000.b + (c100.b - c000.b) * d.r + (c111.b - c101.b) * d.g + (c001.b - c000.b) * d.b + + (c101.b - c001.b - c100.b + c000.b) * d.r * d.b; + } else { + const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]]; + const struct rgbvec c110 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + prev[2]]; + const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]]; + + c.r = c000.r + (c100.r - c000.r) * d.r + (c010.r - c000.r) * d.g + (c111.r - c110.r) * d.b + + (c110.r - c100.r - c010.r + c000.r) * d.r * d.g; + c.g = c000.g + (c100.g - c000.g) * d.r + (c010.g - c000.g) * d.g + (c111.g - c110.g) * d.b + + (c110.g - c100.g - c010.g + c000.g) * d.r * d.g; + c.b = c000.b + (c100.b - c000.b) * d.r + (c010.b - c000.b) * d.g + (c111.b - c110.b) * d.b + + (c110.b - c100.b - c010.b + c000.b) * d.r * d.g; + } + + return c; +} + +static inline struct rgbvec interp_prism(const LUT3DContext *lut3d, + const struct rgbvec *s) +{ + const int lutsize2 = lut3d->lutsize2; + const int lutsize = lut3d->lutsize; + const int prev[] = {PREV(s->r), PREV(s->g), PREV(s->b)}; + const int next[] = {NEXT(s->r), NEXT(s->g), NEXT(s->b)}; + const struct rgbvec d = {s->r - prev[0], s->g - prev[1], s->b - prev[2]}; + const struct rgbvec c000 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + prev[2]]; + const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]]; + const struct rgbvec c101 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + next[2]]; + const struct rgbvec c111 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + next[2]]; + struct rgbvec c; + + if (d.b > d.r) { + const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]]; + const struct rgbvec c011 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + next[2]]; + + c.r = c000.r + (c001.r - c000.r) * d.b + (c101.r - c001.r) * d.r + (c010.r - c000.r) * d.g + + (c000.r - c010.r - c001.r + c011.r) * d.b * d.g + + (c001.r - c011.r - c101.r + c111.r) * d.r * d.g; + c.g = c000.g + (c001.g - c000.g) * d.b + (c101.g - c001.g) * d.r + (c010.g - c000.g) * d.g + + (c000.g - c010.g - c001.g + c011.g) * d.b * d.g + + (c001.g - c011.g - c101.g + c111.g) * d.r * d.g; + c.b = c000.b + (c001.b - c000.b) * d.b + (c101.b - c001.b) * d.r + (c010.b - c000.b) * d.g + + (c000.b - c010.b - c001.b + c011.b) * d.b * d.g + + (c001.b - c011.b - c101.b + c111.b) * d.r * d.g; + } else { + const struct rgbvec c110 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + prev[2]]; + const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]]; + + c.r = c000.r + (c101.r - c100.r) * d.b + (c100.r - c000.r) * d.r + (c010.r - c000.r) * d.g + + (c100.r - c110.r - c101.r + c111.r) * d.b * d.g + + (c000.r - c010.r - c100.r + c110.r) * d.r * d.g; + c.g = c000.g + (c101.g - c100.g) * d.b + (c100.g - c000.g) * d.r + (c010.g - c000.g) * d.g + + (c100.g - c110.g - c101.g + c111.g) * d.b * d.g + + (c000.g - c010.g - c100.g + c110.g) * d.r * d.g; + c.b = c000.b + (c101.b - c100.b) * d.b + (c100.b - c000.b) * d.r + (c010.b - c000.b) * d.g + + (c100.b - c110.b - c101.b + c111.b) * d.b * d.g + + (c000.b - c010.b - c100.b + c110.b) * d.r * d.g; + } + + return c; +} + /** * Tetrahedral interpolation. Based on code found in Truelight Software Library paper. * @see http://www.filmlight.ltd.uk/pdf/whitepapers/FL-TL-TN-0057-SoftwareLib.pdf @@ -337,26 +437,38 @@ static int interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, i DEFINE_INTERP_FUNC_PLANAR(nearest, 8, 8) DEFINE_INTERP_FUNC_PLANAR(trilinear, 8, 8) DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 8, 8) +DEFINE_INTERP_FUNC_PLANAR(pyramid, 8, 8) +DEFINE_INTERP_FUNC_PLANAR(prism, 8, 8) DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 9) DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 9) DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 9) +DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 9) +DEFINE_INTERP_FUNC_PLANAR(prism, 16, 9) DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 10) DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 10) DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 10) +DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 10) +DEFINE_INTERP_FUNC_PLANAR(prism, 16, 10) DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 12) DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 12) DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 12) +DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 12) +DEFINE_INTERP_FUNC_PLANAR(prism, 16, 12) DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 14) DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 14) DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 14) +DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 14) +DEFINE_INTERP_FUNC_PLANAR(prism, 16, 14) DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 16) DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 16) DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 16) +DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 16) +DEFINE_INTERP_FUNC_PLANAR(prism, 16, 16) #define DEFINE_INTERP_FUNC_PLANAR_FLOAT(name, depth) \ static int interp_##name##_pf##depth(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ @@ -422,6 +534,8 @@ static int interp_##name##_pf##depth(AVFilterContext *ctx, void *arg, int jobnr, DEFINE_INTERP_FUNC_PLANAR_FLOAT(nearest, 32) DEFINE_INTERP_FUNC_PLANAR_FLOAT(trilinear, 32) DEFINE_INTERP_FUNC_PLANAR_FLOAT(tetrahedral, 32) +DEFINE_INTERP_FUNC_PLANAR_FLOAT(pyramid, 32) +DEFINE_INTERP_FUNC_PLANAR_FLOAT(prism, 32) #define DEFINE_INTERP_FUNC(name, nbits) \ static int interp_##nbits##_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ @@ -475,10 +589,14 @@ static int interp_##nbits##_##name(AVFilterContext *ctx, void *arg, int jobnr, i DEFINE_INTERP_FUNC(nearest, 8) DEFINE_INTERP_FUNC(trilinear, 8) DEFINE_INTERP_FUNC(tetrahedral, 8) +DEFINE_INTERP_FUNC(pyramid, 8) +DEFINE_INTERP_FUNC(prism, 8) DEFINE_INTERP_FUNC(nearest, 16) DEFINE_INTERP_FUNC(trilinear, 16) DEFINE_INTERP_FUNC(tetrahedral, 16) +DEFINE_INTERP_FUNC(pyramid, 16) +DEFINE_INTERP_FUNC(prism, 16) #define MAX_LINE_SIZE 512 @@ -878,18 +996,16 @@ static int parse_cinespace(AVFilterContext *ctx, FILE *f) prelut_sizes[i] = npoints; in_min[i] = FLT_MAX; - in_max[i] = FLT_MIN; + in_max[i] = -FLT_MAX; out_min[i] = FLT_MAX; - out_max[i] = FLT_MIN; - - last = FLT_MIN; + out_max[i] = -FLT_MAX; for (int j = 0; j < npoints; j++) { NEXT_FLOAT_OR_GOTO(v, end) in_min[i] = FFMIN(in_min[i], v); in_max[i] = FFMAX(in_max[i], v); in_prelut[i][j] = v; - if (v < last) { + if (j > 0 && v < last) { av_log(ctx, AV_LOG_ERROR, "Invalid file, non increasing prelut.\n"); ret = AVERROR(ENOMEM); goto end; @@ -1088,6 +1204,8 @@ static int config_input(AVFilterLink *inlink) case INTERPOLATE_NEAREST: SET_FUNC(nearest); break; case INTERPOLATE_TRILINEAR: SET_FUNC(trilinear); break; case INTERPOLATE_TETRAHEDRAL: SET_FUNC(tetrahedral); break; + case INTERPOLATE_PYRAMID: SET_FUNC(pyramid); break; + case INTERPOLATE_PRISM: SET_FUNC(prism); break; default: av_assert0(0); } @@ -1133,6 +1251,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return config_input(ctx->inputs[0]); +} + #if CONFIG_LUT3D_FILTER static const AVOption lut3d_options[] = { { "file", "set 3D LUT file name", OFFSET(file), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, @@ -1234,6 +1364,7 @@ AVFilter ff_vf_lut3d = { .outputs = lut3d_outputs, .priv_class = &lut3d_class, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif @@ -1502,6 +1633,7 @@ AVFilter ff_vf_haldclut = { .outputs = haldclut_outputs, .priv_class = &haldclut_class, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif @@ -1681,13 +1813,13 @@ try_again: } static const AVOption lut1d_options[] = { - { "file", "set 1D LUT file name", OFFSET(file), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "interp", "select interpolation mode", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=INTERPOLATE_1D_LINEAR}, 0, NB_INTERP_1D_MODE-1, FLAGS, "interp_mode" }, - { "nearest", "use values from the nearest defined points", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_NEAREST}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, - { "linear", "use values from the linear interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_LINEAR}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, - { "cosine", "use values from the cosine interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_COSINE}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, - { "cubic", "use values from the cubic interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_CUBIC}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, - { "spline", "use values from the spline interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_SPLINE}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, + { "file", "set 1D LUT file name", OFFSET(file), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = TFLAGS }, + { "interp", "select interpolation mode", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=INTERPOLATE_1D_LINEAR}, 0, NB_INTERP_1D_MODE-1, TFLAGS, "interp_mode" }, + { "nearest", "use values from the nearest defined points", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_NEAREST}, 0, 0, TFLAGS, "interp_mode" }, + { "linear", "use values from the linear interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_LINEAR}, 0, 0, TFLAGS, "interp_mode" }, + { "cosine", "use values from the cosine interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_COSINE}, 0, 0, TFLAGS, "interp_mode" }, + { "cubic", "use values from the cubic interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_CUBIC}, 0, 0, TFLAGS, "interp_mode" }, + { "spline", "use values from the spline interpolation", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_SPLINE}, 0, 0, TFLAGS, "interp_mode" }, { NULL } }; @@ -2117,6 +2249,24 @@ static int filter_frame_1d(AVFilterLink *inlink, AVFrame *in) return ff_filter_frame(outlink, out); } +static int lut1d_process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + LUT1DContext *lut1d = ctx->priv; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + ret = lut1d_init(ctx); + if (ret < 0) { + set_identity_matrix_1d(lut1d, 32); + return ret; + } + return config_input_1d(ctx->inputs[0]); +} + static const AVFilterPad lut1d_inputs[] = { { .name = "default", @@ -2145,5 +2295,6 @@ AVFilter ff_vf_lut1d = { .outputs = lut1d_outputs, .priv_class = &lut1d_class, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = lut1d_process_command, }; #endif diff --git a/libavfilter/vf_maskedclamp.c b/libavfilter/vf_maskedclamp.c index 52392c4c8..af2793b55 100644 --- a/libavfilter/vf_maskedclamp.c +++ b/libavfilter/vf_maskedclamp.c @@ -29,7 +29,7 @@ #include "maskedclamp.h" #define OFFSET(x) offsetof(MaskedClampContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM typedef struct ThreadData { AVFrame *b, *o, *m, *d; @@ -327,4 +327,5 @@ AVFilter ff_vf_maskedclamp = { .outputs = maskedclamp_outputs, .priv_class = &maskedclamp_class, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, }; diff --git a/libavfilter/vf_maskedmerge.c b/libavfilter/vf_maskedmerge.c index 82f55e66a..2f83fb5dc 100644 --- a/libavfilter/vf_maskedmerge.c +++ b/libavfilter/vf_maskedmerge.c @@ -28,7 +28,7 @@ #include "maskedmerge.h" #define OFFSET(x) offsetof(MaskedMergeContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption maskedmerge_options[] = { { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF, FLAGS }, @@ -46,7 +46,7 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, - AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, @@ -328,4 +328,5 @@ AVFilter ff_vf_maskedmerge = { .outputs = maskedmerge_outputs, .priv_class = &maskedmerge_class, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, }; diff --git a/libavfilter/vf_maskedminmax.c b/libavfilter/vf_maskedminmax.c index 0685c8a16..90140827a 100644 --- a/libavfilter/vf_maskedminmax.c +++ b/libavfilter/vf_maskedminmax.c @@ -28,7 +28,7 @@ #include "framesync.h" #define OFFSET(x) offsetof(MaskedMinMaxContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM typedef struct ThreadData { AVFrame *src, *f1, *f2, *dst; @@ -50,7 +50,7 @@ typedef struct MaskedMinMaxContext { } MaskedMinMaxContext; static const AVOption maskedminmax_options[] = { - { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF, FLAGS }, + { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF, FLAGS }, { NULL } }; @@ -340,6 +340,7 @@ AVFilter ff_vf_maskedmin = { .inputs = maskedminmax_inputs, .outputs = maskedminmax_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, }; #define maskedmax_options maskedminmax_options @@ -357,4 +358,5 @@ AVFilter ff_vf_maskedmax = { .inputs = maskedminmax_inputs, .outputs = maskedminmax_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, }; diff --git a/libavfilter/vf_maskedthreshold.c b/libavfilter/vf_maskedthreshold.c index d925819f6..5a6ebb1a0 100644 --- a/libavfilter/vf_maskedthreshold.c +++ b/libavfilter/vf_maskedthreshold.c @@ -43,7 +43,7 @@ typedef struct MaskedThresholdContext { } MaskedThresholdContext; #define OFFSET(x) offsetof(MaskedThresholdContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM typedef struct ThreadData { AVFrame *src, *ref, *dst; @@ -295,4 +295,5 @@ AVFilter ff_vf_maskedthreshold = { .inputs = maskedthreshold_inputs, .outputs = maskedthreshold_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, }; diff --git a/libavfilter/vf_maskfun.c b/libavfilter/vf_maskfun.c index 4ceb21b94..55a4c57c9 100644 --- a/libavfilter/vf_maskfun.c +++ b/libavfilter/vf_maskfun.c @@ -47,14 +47,14 @@ typedef struct MaskFunContext { } MaskFunContext; #define OFFSET(x) offsetof(MaskFunContext, x) -#define VF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define VFT AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption maskfun_options[] = { - { "low", "set low threshold", OFFSET(low), AV_OPT_TYPE_INT, {.i64=10}, 0, UINT16_MAX, VF }, - { "high", "set high threshold", OFFSET(high), AV_OPT_TYPE_INT, {.i64=10}, 0, UINT16_MAX, VF }, - { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF, VF }, - { "fill", "set fill value", OFFSET(fill), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, VF }, - { "sum", "set sum value", OFFSET(sum), AV_OPT_TYPE_INT, {.i64=10}, 0, UINT16_MAX, VF }, + { "low", "set low threshold", OFFSET(low), AV_OPT_TYPE_INT, {.i64=10}, 0, UINT16_MAX, VFT }, + { "high", "set high threshold", OFFSET(high), AV_OPT_TYPE_INT, {.i64=10}, 0, UINT16_MAX, VFT }, + { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF, VFT }, + { "fill", "set fill value", OFFSET(fill), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, VFT }, + { "sum", "set sum value", OFFSET(sum), AV_OPT_TYPE_INT, {.i64=10}, 0, UINT16_MAX, VFT }, { NULL } }; @@ -182,6 +182,45 @@ static int maskfun##name(AVFilterContext *ctx, void *arg, \ MASKFUN(8, uint8_t, 1) MASKFUN(16, uint16_t, 2) +static void fill_frame(AVFilterContext *ctx) +{ + MaskFunContext *s = ctx->priv; + + s->fill = FFMIN(s->fill, s->max); + if (s->depth == 8) { + for (int p = 0; p < s->nb_planes; p++) { + uint8_t *dst = s->empty->data[p]; + + for (int y = 0; y < s->height[p]; y++) { + memset(dst, s->fill, s->width[p]); + dst += s->empty->linesize[p]; + } + } + } else { + for (int p = 0; p < s->nb_planes; p++) { + uint16_t *dst = (uint16_t *)s->empty->data[p]; + + for (int y = 0; y < s->height[p]; y++) { + for (int x = 0; x < s->width[p]; x++) + dst[x] = s->fill; + dst += s->empty->linesize[p] / 2; + } + } + } +} + +static void set_max_sum(AVFilterContext *ctx) +{ + MaskFunContext *s = ctx->priv; + + s->max_sum = 0; + for (int p = 0; p < s->nb_planes; p++) { + if (!((1 << p) & s->planes)) + continue; + s->max_sum += (uint64_t)s->sum * s->width[p] * s->height[p]; + } +} + static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; @@ -203,7 +242,6 @@ static int config_input(AVFilterLink *inlink) s->depth = desc->comp[0].depth; s->max = (1 << s->depth) - 1; - s->fill = FFMIN(s->fill, s->max); if (s->depth == 8) { s->maskfun = maskfun8; @@ -217,33 +255,30 @@ static int config_input(AVFilterLink *inlink) if (!s->empty) return AVERROR(ENOMEM); - if (s->depth == 8) { - for (int p = 0; p < s->nb_planes; p++) { - uint8_t *dst = s->empty->data[p]; + fill_frame(ctx); - for (int y = 0; y < s->height[p]; y++) { - memset(dst, s->fill, s->width[p]); - dst += s->empty->linesize[p]; - } - } - } else { - for (int p = 0; p < s->nb_planes; p++) { - uint16_t *dst = (uint16_t *)s->empty->data[p]; + set_max_sum(ctx); - for (int y = 0; y < s->height[p]; y++) { - for (int x = 0; x < s->width[p]; x++) - dst[x] = s->fill; - dst += s->empty->linesize[p] / 2; - } - } - } + return 0; +} - s->max_sum = 0; - for (int p = 0; p < s->nb_planes; p++) { - if (!((1 << p) & s->planes)) - continue; - s->max_sum += (uint64_t)s->sum * s->width[p] * s->height[p]; - } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + MaskFunContext *s = ctx->priv; + int fill = s->fill; + int sum = s->sum; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + if (sum != s->sum) + set_max_sum(ctx); + + if (fill != s->fill) + fill_frame(ctx); return 0; } @@ -284,4 +319,5 @@ AVFilter ff_vf_maskfun = { .outputs = maskfun_outputs, .priv_class = &maskfun_class, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; diff --git a/libavfilter/vf_mcdeint.c b/libavfilter/vf_mcdeint.c index 9cdec6308..1cad45cd4 100644 --- a/libavfilter/vf_mcdeint.c +++ b/libavfilter/vf_mcdeint.c @@ -74,6 +74,7 @@ typedef struct MCDeintContext { int mode; ///< MCDeintMode int parity; ///< MCDeintParity int qp; + AVPacket *pkt; AVCodecContext *enc_ctx; } MCDeintContext; @@ -102,7 +103,7 @@ static int config_props(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; MCDeintContext *mcdeint = ctx->priv; - AVCodec *enc; + const AVCodec *enc; AVCodecContext *enc_ctx; AVDictionary *opts = NULL; int ret; @@ -112,6 +113,9 @@ static int config_props(AVFilterLink *inlink) return AVERROR(EINVAL); } + mcdeint->pkt = av_packet_alloc(); + if (!mcdeint->pkt) + return AVERROR(ENOMEM); mcdeint->enc_ctx = avcodec_alloc_context3(enc); if (!mcdeint->enc_ctx) return AVERROR(ENOMEM); @@ -154,6 +158,7 @@ static av_cold void uninit(AVFilterContext *ctx) { MCDeintContext *mcdeint = ctx->priv; + av_packet_free(&mcdeint->pkt); avcodec_free_context(&mcdeint->enc_ctx); } @@ -173,7 +178,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) MCDeintContext *mcdeint = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; AVFrame *outpic, *frame_dec; - AVPacket pkt = {0}; + AVPacket *pkt = mcdeint->pkt; int x, y, i, ret, got_frame = 0; outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h); @@ -184,9 +189,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) av_frame_copy_props(outpic, inpic); inpic->quality = mcdeint->qp * FF_QP2LAMBDA; - av_init_packet(&pkt); - - ret = avcodec_encode_video2(mcdeint->enc_ctx, &pkt, inpic, &got_frame); + ret = avcodec_encode_video2(mcdeint->enc_ctx, pkt, inpic, &got_frame); if (ret < 0) goto end; @@ -274,7 +277,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) mcdeint->parity ^= 1; end: - av_packet_unref(&pkt); + av_packet_unref(pkt); av_frame_free(&inpic); if (ret < 0) { av_frame_free(&outpic); diff --git a/libavfilter/vf_mergeplanes.c b/libavfilter/vf_mergeplanes.c index 4b4f91be5..22eb36a2e 100644 --- a/libavfilter/vf_mergeplanes.c +++ b/libavfilter/vf_mergeplanes.c @@ -122,12 +122,12 @@ static int query_formats(AVFilterContext *ctx) } for (i = 0; i < s->nb_inputs; i++) - if ((ret = ff_formats_ref(formats, &ctx->inputs[i]->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &ctx->inputs[i]->outcfg.formats)) < 0) return ret; formats = NULL; if ((ret = ff_add_format(&formats, s->out_fmt)) < 0 || - (ret = ff_formats_ref(formats, &ctx->outputs[0]->in_formats)) < 0) + (ret = ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/vf_minterpolate.c b/libavfilter/vf_minterpolate.c index c9ce80420..969463f02 100644 --- a/libavfilter/vf_minterpolate.c +++ b/libavfilter/vf_minterpolate.c @@ -340,7 +340,7 @@ static int config_input(AVFilterLink *inlink) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); const int height = inlink->h; const int width = inlink->w; - int i, ret = 0; + int i; mi_ctx->log2_chroma_h = desc->log2_chroma_h; mi_ctx->log2_chroma_w = desc->log2_chroma_w; @@ -363,13 +363,25 @@ static int config_input(AVFilterLink *inlink) } if (mi_ctx->mi_mode == MI_MODE_MCI) { + if (mi_ctx->b_width < 2 || mi_ctx->b_height < 2) { + av_log(inlink->dst, AV_LOG_ERROR, "Height or width < %d\n", + 2 * mi_ctx->mb_size); + return AVERROR(EINVAL); + } + ff_me_init_context(me_ctx, mi_ctx->mb_size, mi_ctx->search_param, + width, height, 0, (mi_ctx->b_width - 1) << mi_ctx->log2_mb_size, + 0, (mi_ctx->b_height - 1) << mi_ctx->log2_mb_size); + + if (mi_ctx->me_mode == ME_MODE_BIDIR) + me_ctx->get_cost = &get_sad_ob; + else if (mi_ctx->me_mode == ME_MODE_BILAT) + me_ctx->get_cost = &get_sbad_ob; + mi_ctx->pixel_mvs = av_mallocz_array(width * height, sizeof(PixelMVS)); mi_ctx->pixel_weights = av_mallocz_array(width * height, sizeof(PixelWeights)); mi_ctx->pixel_refs = av_mallocz_array(width * height, sizeof(PixelRefs)); - if (!mi_ctx->pixel_mvs || !mi_ctx->pixel_weights || !mi_ctx->pixel_refs) { - ret = AVERROR(ENOMEM); - goto fail; - } + if (!mi_ctx->pixel_mvs || !mi_ctx->pixel_weights || !mi_ctx->pixel_refs) + return AVERROR(ENOMEM); if (mi_ctx->me_mode == ME_MODE_BILAT) if (!(mi_ctx->int_blocks = av_mallocz_array(mi_ctx->b_count, sizeof(Block)))) @@ -390,21 +402,7 @@ static int config_input(AVFilterLink *inlink) return AVERROR(EINVAL); } - ff_me_init_context(me_ctx, mi_ctx->mb_size, mi_ctx->search_param, width, height, 0, (mi_ctx->b_width - 1) << mi_ctx->log2_mb_size, 0, (mi_ctx->b_height - 1) << mi_ctx->log2_mb_size); - - if (mi_ctx->me_mode == ME_MODE_BIDIR) - me_ctx->get_cost = &get_sad_ob; - else if (mi_ctx->me_mode == ME_MODE_BILAT) - me_ctx->get_cost = &get_sbad_ob; - return 0; -fail: - for (i = 0; i < NB_FRAMES; i++) - av_freep(&mi_ctx->frames[i].blocks); - av_freep(&mi_ctx->pixel_mvs); - av_freep(&mi_ctx->pixel_weights); - av_freep(&mi_ctx->pixel_refs); - return ret; } static int config_output(AVFilterLink *outlink) @@ -825,9 +823,10 @@ static int inject_frame(AVFilterLink *inlink, AVFrame *avf_in) return 0; } -static int detect_scene_change(MIContext *mi_ctx) +static int detect_scene_change(AVFilterContext *ctx) { - AVMotionEstContext *me_ctx = &mi_ctx->me_ctx; + MIContext *mi_ctx = ctx->priv; + AVFilterLink *input = ctx->inputs[0]; uint8_t *p1 = mi_ctx->frames[1].avf->data[0]; ptrdiff_t linesize1 = mi_ctx->frames[1].avf->linesize[0]; uint8_t *p2 = mi_ctx->frames[2].avf->data[0]; @@ -836,9 +835,9 @@ static int detect_scene_change(MIContext *mi_ctx) if (mi_ctx->scd_method == SCD_METHOD_FDIFF) { double ret = 0, mafd, diff; uint64_t sad; - mi_ctx->sad(p1, linesize1, p2, linesize2, me_ctx->width, me_ctx->height, &sad); + mi_ctx->sad(p1, linesize1, p2, linesize2, input->w, input->h, &sad); emms_c(); - mafd = (double) sad * 100.0 / (me_ctx->height * me_ctx->width) / (1 << mi_ctx->bitdepth); + mafd = (double) sad * 100.0 / (input->h * input->w) / (1 << mi_ctx->bitdepth); diff = fabs(mafd - mi_ctx->prev_mafd); ret = av_clipf(FFMIN(mafd, diff), 0, 100.0); mi_ctx->prev_mafd = mafd; @@ -1186,7 +1185,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *avf_in) if (!mi_ctx->frames[0].avf) return 0; - mi_ctx->scene_changed = detect_scene_change(mi_ctx); + mi_ctx->scene_changed = detect_scene_change(ctx); for (;;) { AVFrame *avf_out; diff --git a/libavfilter/vf_mix.c b/libavfilter/vf_mix.c index bdb67d8e5..ee4d95791 100644 --- a/libavfilter/vf_mix.c +++ b/libavfilter/vf_mix.c @@ -55,26 +55,56 @@ typedef struct MixContext { static int query_formats(AVFilterContext *ctx) { - AVFilterFormats *pix_fmts = NULL; - int fmt, ret; + AVFilterFormats *formats = NULL; + int ret; - for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_HWACCEL || - desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) && - (ret = ff_add_format(&pix_fmts, fmt)) < 0) - return ret; + ret = ff_formats_pixdesc_filter(&formats, 0, + AV_PIX_FMT_FLAG_BITSTREAM | + AV_PIX_FMT_FLAG_PAL | + AV_PIX_FMT_FLAG_HWACCEL); + if (ret < 0) + return ret; + return ff_set_common_formats(ctx, formats); +} + +static int parse_weights(AVFilterContext *ctx) +{ + MixContext *s = ctx->priv; + char *p, *arg, *saveptr = NULL; + int i, last = 0; + + s->wfactor = 0.f; + p = s->weights_str; + for (i = 0; i < s->nb_inputs; i++) { + if (!(arg = av_strtok(p, " |", &saveptr))) + break; + + p = NULL; + if (av_sscanf(arg, "%f", &s->weights[i]) != 1) { + av_log(ctx, AV_LOG_ERROR, "Invalid syntax for weights[%d].\n", i); + return AVERROR(EINVAL); + } + s->wfactor += s->weights[i]; + last = i; } - return ff_set_common_formats(ctx, pix_fmts); + for (; i < s->nb_inputs; i++) { + s->weights[i] = s->weights[last]; + s->wfactor += s->weights[i]; + } + if (s->scale == 0) { + s->wfactor = 1 / s->wfactor; + } else { + s->wfactor = s->scale; + } + + return 0; } static av_cold int init(AVFilterContext *ctx) { MixContext *s = ctx->priv; - char *p, *arg, *saveptr = NULL; - int i, ret, last = 0; + int ret; s->tmix = !strcmp(ctx->filter->name, "tmix"); @@ -87,7 +117,7 @@ static av_cold int init(AVFilterContext *ctx) return AVERROR(ENOMEM); if (!s->tmix) { - for (i = 0; i < s->nb_inputs; i++) { + for (int i = 0; i < s->nb_inputs; i++) { AVFilterPad pad = { 0 }; pad.type = AVMEDIA_TYPE_VIDEO; @@ -102,30 +132,7 @@ static av_cold int init(AVFilterContext *ctx) } } - p = s->weights_str; - for (i = 0; i < s->nb_inputs; i++) { - if (!(arg = av_strtok(p, " ", &saveptr))) - break; - - p = NULL; - if (av_sscanf(arg, "%f", &s->weights[i]) != 1) { - av_log(ctx, AV_LOG_ERROR, "Invalid syntax for weights[%d].\n", i); - return AVERROR(EINVAL); - } - s->wfactor += s->weights[i]; - last = i; - } - for (; i < s->nb_inputs; i++) { - s->weights[i] = s->weights[last]; - s->wfactor += s->weights[i]; - } - if (s->scale == 0) { - s->wfactor = 1 / s->wfactor; - } else { - s->wfactor = s->scale; - } - - return 0; + return parse_weights(ctx); } typedef struct ThreadData { @@ -204,6 +211,14 @@ static int process_frame(FFFrameSync *fs) return ret; } + if (ctx->is_disabled) { + out = av_frame_clone(s->frames[0]); + if (!out) + return AVERROR(ENOMEM); + out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base); + return ff_filter_frame(outlink, out); + } + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) return AVERROR(ENOMEM); @@ -298,6 +313,18 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&s->frames); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + return parse_weights(ctx); +} + static int activate(AVFilterContext *ctx) { MixContext *s = ctx->priv; @@ -306,11 +333,12 @@ static int activate(AVFilterContext *ctx) #define OFFSET(x) offsetof(MixContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM +#define TFLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM static const AVOption mix_options[] = { { "inputs", "set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=2}, 2, INT16_MAX, .flags = FLAGS }, - { "weights", "set weight for each input", OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, .flags = FLAGS }, - { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT16_MAX, .flags = FLAGS }, + { "weights", "set weight for each input", OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, .flags = TFLAGS }, + { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT16_MAX, .flags = TFLAGS }, { "duration", "how to determine end of stream", OFFSET(duration), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, .flags = FLAGS, "duration" }, { "longest", "Duration of longest input", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "duration" }, { "shortest", "Duration of shortest input", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "duration" }, @@ -340,7 +368,9 @@ AVFilter ff_vf_mix = { .init = init, .uninit = uninit, .activate = activate, - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_SLICE_THREADS, + .flags = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_SLICE_THREADS | + AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, + .process_command = process_command, }; #endif /* CONFIG_MIX_FILTER */ @@ -389,8 +419,8 @@ static int tmix_filter_frame(AVFilterLink *inlink, AVFrame *in) static const AVOption tmix_options[] = { { "frames", "set number of successive frames to mix", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=3}, 1, 128, .flags = FLAGS }, - { "weights", "set weight for each frame", OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1 1"}, 0, 0, .flags = FLAGS }, - { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT16_MAX, .flags = FLAGS }, + { "weights", "set weight for each frame", OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1 1"}, 0, 0, .flags = TFLAGS }, + { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT16_MAX, .flags = TFLAGS }, { NULL }, }; @@ -416,6 +446,7 @@ AVFilter ff_vf_tmix = { .init = init, .uninit = uninit, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif /* CONFIG_TMIX_FILTER */ diff --git a/libavfilter/vf_monochrome.c b/libavfilter/vf_monochrome.c new file mode 100644 index 000000000..8faa068db --- /dev/null +++ b/libavfilter/vf_monochrome.c @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/opt.h" +#include "libavutil/imgutils.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct MonochromeContext { + const AVClass *class; + + float b, r; + float size; + float high; + + int depth; + int subw, subh; + + int (*do_slice)(AVFilterContext *s, void *arg, + int jobnr, int nb_jobs); + int (*clear_uv)(AVFilterContext *s, void *arg, + int jobnr, int nb_jobs); +} MonochromeContext; + +static float envelope(const float x) +{ + const float beta = 0.6f; + + if (x < beta) { + const float tmp = fabsf(x / beta - 1.f); + + return 1.f - tmp * tmp; + } else { + const float tmp = (1.f - x) / (1.f - beta); + + return tmp * tmp * (3.f - 2.f * tmp); + } +} + +static float filter(float b, float r, float u, float v, float size) +{ + return expf(-av_clipf(((b - u) * (b - u) + + (r - v) * (r - v)) * + size, 0.f, 1.f)); +} + +#define PROCESS() \ + const int cx = x >> subw; \ + float y = yptr[x] * imax; \ + float u = uptr[cx] * imax - .5f; \ + float v = vptr[cx] * imax - .5f; \ + float tt, t, ny; \ + \ + ny = filter(b, r, u, v, size); \ + tt = envelope(y); \ + t = tt + (1.f - tt) * ihigh; \ + ny = (1.f - t) * y + t * ny * y; + +static int monochrome_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + MonochromeContext *s = ctx->priv; + AVFrame *frame = arg; + const int depth = s->depth; + const int subw = s->subw; + const int subh = s->subh; + const float max = (1 << depth) - 1; + const float imax = 1.f / max; + const int width = frame->width; + const int height = frame->height; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ylinesize = frame->linesize[0]; + const int ulinesize = frame->linesize[1]; + const int vlinesize = frame->linesize[2]; + uint8_t *yptr = frame->data[0] + slice_start * ylinesize; + const float ihigh = 1.f - s->high; + const float size = 1.f / s->size; + const float b = s->b * .5f; + const float r = s->r * .5f; + + for (int y = slice_start; y < slice_end; y++) { + const int cy = y >> subh; + uint8_t *uptr = frame->data[1] + cy * ulinesize; + uint8_t *vptr = frame->data[2] + cy * vlinesize; + + for (int x = 0; x < width; x++) { + PROCESS() + + yptr[x] = av_clip_uint8(ny * max); + } + + yptr += ylinesize; + } + + return 0; +} + +static int monochrome_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + MonochromeContext *s = ctx->priv; + AVFrame *frame = arg; + const int depth = s->depth; + const int subw = s->subw; + const int subh = s->subh; + const float max = (1 << depth) - 1; + const float imax = 1.f / max; + const int width = frame->width; + const int height = frame->height; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ylinesize = frame->linesize[0] / 2; + const int ulinesize = frame->linesize[1] / 2; + const int vlinesize = frame->linesize[2] / 2; + uint16_t *yptr = (uint16_t *)frame->data[0] + slice_start * ylinesize; + const float ihigh = 1.f - s->high; + const float size = 1.f / s->size; + const float b = s->b * .5f; + const float r = s->r * .5f; + + for (int y = slice_start; y < slice_end; y++) { + const int cy = y >> subh; + uint16_t *uptr = (uint16_t *)frame->data[1] + cy * ulinesize; + uint16_t *vptr = (uint16_t *)frame->data[2] + cy * vlinesize; + + for (int x = 0; x < width; x++) { + PROCESS() + + yptr[x] = av_clip_uintp2_c(ny * max, depth); + } + + yptr += ylinesize; + } + + return 0; +} + +static int clear_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + MonochromeContext *s = ctx->priv; + AVFrame *frame = arg; + const int depth = s->depth; + const int half = 1 << (depth - 1); + const int subw = s->subw; + const int subh = s->subh; + const int width = AV_CEIL_RSHIFT(frame->width, subw); + const int height = AV_CEIL_RSHIFT(frame->height, subh); + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ulinesize = frame->linesize[1]; + const int vlinesize = frame->linesize[2]; + + for (int y = slice_start; y < slice_end; y++) { + uint8_t *uptr = frame->data[1] + y * ulinesize; + uint8_t *vptr = frame->data[2] + y * vlinesize; + + memset(uptr, half, width); + memset(vptr, half, width); + } + + return 0; +} + +static int clear_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + MonochromeContext *s = ctx->priv; + AVFrame *frame = arg; + const int depth = s->depth; + const int half = 1 << (depth - 1); + const int subw = s->subw; + const int subh = s->subh; + const int width = AV_CEIL_RSHIFT(frame->width, subw); + const int height = AV_CEIL_RSHIFT(frame->height, subh); + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int ulinesize = frame->linesize[1] / 2; + const int vlinesize = frame->linesize[2] / 2; + + for (int y = slice_start; y < slice_end; y++) { + uint16_t *uptr = (uint16_t *)frame->data[1] + y * ulinesize; + uint16_t *vptr = (uint16_t *)frame->data[2] + y * vlinesize; + + for (int x = 0; x < width; x++) { + uptr[x] = half; + vptr[x] = half; + } + } + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *frame) +{ + AVFilterContext *ctx = inlink->dst; + MonochromeContext *s = ctx->priv; + + ctx->internal->execute(ctx, s->do_slice, frame, NULL, + FFMIN(frame->height, ff_filter_get_nb_threads(ctx))); + ctx->internal->execute(ctx, s->clear_uv, frame, NULL, + FFMIN(frame->height >> s->subh, ff_filter_get_nb_threads(ctx))); + + return ff_filter_frame(ctx->outputs[0], frame); +} + +static av_cold int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_fmts[] = { + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *formats = NULL; + + formats = ff_make_format_list(pixel_fmts); + if (!formats) + return AVERROR(ENOMEM); + + return ff_set_common_formats(ctx, formats); +} + +static av_cold int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + MonochromeContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + + s->depth = desc->comp[0].depth; + s->do_slice = s->depth <= 8 ? monochrome_slice8 : monochrome_slice16; + s->clear_uv = s->depth <= 8 ? clear_slice8 : clear_slice16; + s->subw = desc->log2_chroma_w; + s->subh = desc->log2_chroma_h; + + return 0; +} + +static const AVFilterPad monochrome_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .needs_writable = 1, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad monochrome_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +#define OFFSET(x) offsetof(MonochromeContext, x) +#define VF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption monochrome_options[] = { + { "cb", "set the chroma blue spot", OFFSET(b), AV_OPT_TYPE_FLOAT, {.dbl=0},-1, 1, VF }, + { "cr", "set the chroma red spot", OFFSET(r), AV_OPT_TYPE_FLOAT, {.dbl=0},-1, 1, VF }, + { "size", "set the color filter size", OFFSET(size), AV_OPT_TYPE_FLOAT, {.dbl=1},.1,10, VF }, + { "high", "set the highlights strength", OFFSET(high), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(monochrome); + +AVFilter ff_vf_monochrome = { + .name = "monochrome", + .description = NULL_IF_CONFIG_SMALL("Convert video to gray using custom color filter."), + .priv_size = sizeof(MonochromeContext), + .priv_class = &monochrome_class, + .query_formats = query_formats, + .inputs = monochrome_inputs, + .outputs = monochrome_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; diff --git a/libavfilter/vf_neighbor.c b/libavfilter/vf_neighbor.c index 17a9b8826..9cd900132 100644 --- a/libavfilter/vf_neighbor.c +++ b/libavfilter/vf_neighbor.c @@ -371,60 +371,44 @@ AVFilter ff_vf_##name_ = { \ .process_command = ff_filter_process_command, \ } -#if CONFIG_EROSION_FILTER - -static const AVOption erosion_options[] = { +/* The following options are shared between all filters here; + * the de/inflate filters only use the threshold* options. */ +#define DEINFLATE_OPTIONS_OFFSET (CONFIG_EROSION_FILTER || CONFIG_DILATION_FILTER) +static const AVOption options[] = { +#if CONFIG_EROSION_FILTER || CONFIG_DILATION_FILTER + { "coordinates", "set coordinates", OFFSET(coordinates), AV_OPT_TYPE_INT, {.i64=255}, 0, 255, FLAGS }, +#endif { "threshold0", "set threshold for 1st plane", OFFSET(threshold[0]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, { "threshold1", "set threshold for 2nd plane", OFFSET(threshold[1]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, { "threshold2", "set threshold for 3rd plane", OFFSET(threshold[2]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, { "threshold3", "set threshold for 4th plane", OFFSET(threshold[3]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "coordinates", "set coordinates", OFFSET(coordinates), AV_OPT_TYPE_INT, {.i64=255}, 0, 255, FLAGS }, { NULL } }; +#if CONFIG_EROSION_FILTER + +#define erosion_options options DEFINE_NEIGHBOR_FILTER(erosion, "Apply erosion effect."); #endif /* CONFIG_EROSION_FILTER */ #if CONFIG_DILATION_FILTER -static const AVOption dilation_options[] = { - { "threshold0", "set threshold for 1st plane", OFFSET(threshold[0]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "threshold1", "set threshold for 2nd plane", OFFSET(threshold[1]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "threshold2", "set threshold for 3rd plane", OFFSET(threshold[2]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "threshold3", "set threshold for 4th plane", OFFSET(threshold[3]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "coordinates", "set coordinates", OFFSET(coordinates), AV_OPT_TYPE_INT, {.i64=255}, 0, 255, FLAGS }, - { NULL } -}; - +#define dilation_options options DEFINE_NEIGHBOR_FILTER(dilation, "Apply dilation effect."); #endif /* CONFIG_DILATION_FILTER */ #if CONFIG_DEFLATE_FILTER -static const AVOption deflate_options[] = { - { "threshold0", "set threshold for 1st plane", OFFSET(threshold[0]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "threshold1", "set threshold for 2nd plane", OFFSET(threshold[1]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "threshold2", "set threshold for 3rd plane", OFFSET(threshold[2]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "threshold3", "set threshold for 4th plane", OFFSET(threshold[3]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { NULL } -}; - +#define deflate_options &options[DEINFLATE_OPTIONS_OFFSET] DEFINE_NEIGHBOR_FILTER(deflate, "Apply deflate effect."); #endif /* CONFIG_DEFLATE_FILTER */ #if CONFIG_INFLATE_FILTER -static const AVOption inflate_options[] = { - { "threshold0", "set threshold for 1st plane", OFFSET(threshold[0]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "threshold1", "set threshold for 2nd plane", OFFSET(threshold[1]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "threshold2", "set threshold for 3rd plane", OFFSET(threshold[2]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { "threshold3", "set threshold for 4th plane", OFFSET(threshold[3]), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, FLAGS }, - { NULL } -}; - +#define inflate_options &options[DEINFLATE_OPTIONS_OFFSET] DEFINE_NEIGHBOR_FILTER(inflate, "Apply inflate effect."); #endif /* CONFIG_INFLATE_FILTER */ diff --git a/libavfilter/vf_nnedi.c b/libavfilter/vf_nnedi.c index 9bad99e98..b273c1394 100644 --- a/libavfilter/vf_nnedi.c +++ b/libavfilter/vf_nnedi.c @@ -21,9 +21,11 @@ #include +#include "libavutil/avassert.h" #include "libavutil/common.h" #include "libavutil/float_dsp.h" #include "libavutil/imgutils.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" @@ -31,44 +33,59 @@ #include "internal.h" #include "video.h" -typedef struct FrameData { - uint8_t *paddedp[3]; - int padded_stride[3]; - int padded_width[3]; - int padded_height[3]; +static const size_t NNEDI_WEIGHTS_SIZE = 13574928; +static const uint8_t NNEDI_XDIM[] = { 8, 16, 32, 48, 8, 16, 32 }; +static const uint8_t NNEDI_YDIM[] = { 6, 6, 6, 6, 4, 4, 4 }; +static const uint16_t NNEDI_NNS[] = { 16, 32, 64, 128, 256 }; - uint8_t *dstp[3]; - int dst_stride[3]; +typedef struct PrescreenerCoefficients { + DECLARE_ALIGNED(32, float, kernel_l0)[4][16 * 4]; + DECLARE_ALIGNED(32, float, bias_l0)[4]; - int field[3]; + DECLARE_ALIGNED(32, float, kernel_l1)[4][4]; + DECLARE_ALIGNED(32, float, bias_l1)[4]; - int32_t *lcount[3]; - float *input; - float *temp; -} FrameData; + DECLARE_ALIGNED(32, float, kernel_l2)[4][8]; + DECLARE_ALIGNED(32, float, bias_l2)[4]; +} PrescreenerCoefficients; + +typedef struct PredictorCoefficients { + int xdim, ydim, nns, nsize; + float *data; + float *softmax_q1; + float *elliott_q1; + float *softmax_bias_q1; + float *elliott_bias_q1; + float *softmax_q2; + float *elliott_q2; + float *softmax_bias_q2; + float *elliott_bias_q2; +} PredictorCoefficients; typedef struct NNEDIContext { const AVClass *class; char *weights_file; - AVFrame *src; - AVFrame *second; - AVFrame *dst; + AVFrame *prev; int eof; - int64_t cur_pts; + int64_t pts; AVFloatDSPContext *fdsp; + int depth; int nb_planes; + int nb_threads; int linesize[4]; + int planewidth[4]; int planeheight[4]; + int field_n; - float *weights0; - float *weights1[2]; - int asize; - int nns; - int xdia; - int ydia; + PrescreenerCoefficients prescreener[4]; + PredictorCoefficients coeffs[2][5][7]; + + float half; + float in_scale; + float out_scale; // Parameters int deint; @@ -79,104 +96,85 @@ typedef struct NNEDIContext { int qual; int etype; int pscrn; - int fapprox; - int max_value; + int input_size; + uint8_t **prescreen_buf; + float **input_buf; + float **output_buf; - void (*copy_pad)(const AVFrame *, FrameData *, struct NNEDIContext *, int); - void (*evalfunc_0)(struct NNEDIContext *, FrameData *); - void (*evalfunc_1)(struct NNEDIContext *, FrameData *); - - // Functions used in evalfunc_0 - void (*readpixels)(const uint8_t *, const int, float *); - void (*compute_network0)(struct NNEDIContext *s, const float *, const float *, uint8_t *); - int32_t (*process_line0)(const uint8_t *, int, uint8_t *, const uint8_t *, const int, const int, const int); - - // Functions used in evalfunc_1 - void (*extract)(const uint8_t *, const int, const int, const int, float *, float *); - void (*dot_prod)(struct NNEDIContext *, const float *, const float *, float *, const int, const int, const float *); - void (*expfunc)(float *, const int); - void (*wae5)(const float *, const int, float *); - - FrameData frame_data; + void (*read)(const uint8_t *src, float *dst, + int src_stride, int dst_stride, + int width, int height, float scale); + void (*write)(const float *src, uint8_t *dst, + int src_stride, int dst_stride, + int width, int height, int depth, float scale); + void (*prescreen[2])(AVFilterContext *ctx, + const void *src, ptrdiff_t src_stride, + uint8_t *prescreen, int N, + const PrescreenerCoefficients *const coeffs); } NNEDIContext; #define OFFSET(x) offsetof(NNEDIContext, x) +#define RFLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM static const AVOption nnedi_options[] = { {"weights", "set weights file", OFFSET(weights_file), AV_OPT_TYPE_STRING, {.str="nnedi3_weights.bin"}, 0, 0, FLAGS }, - {"deint", "set which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "deint" }, - {"all", "deinterlace all frames", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "deint" }, - {"interlaced", "only deinterlace frames marked as interlaced", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "deint" }, - {"field", "set mode of operation", OFFSET(field), AV_OPT_TYPE_INT, {.i64=-1}, -2, 3, FLAGS, "field" }, - {"af", "use frame flags, both fields", 0, AV_OPT_TYPE_CONST, {.i64=-2}, 0, 0, FLAGS, "field" }, - {"a", "use frame flags, single field", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, "field" }, - {"t", "use top field only", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "field" }, - {"b", "use bottom field only", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "field" }, - {"tf", "use both fields, top first", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "field" }, - {"bf", "use both fields, bottom first", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "field" }, - {"planes", "set which planes to process", OFFSET(process_plane), AV_OPT_TYPE_INT, {.i64=7}, 0, 7, FLAGS }, - {"nsize", "set size of local neighborhood around each pixel, used by the predictor neural network", OFFSET(nsize), AV_OPT_TYPE_INT, {.i64=6}, 0, 6, FLAGS, "nsize" }, - {"s8x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "nsize" }, - {"s16x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "nsize" }, - {"s32x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "nsize" }, - {"s48x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "nsize" }, - {"s8x4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, FLAGS, "nsize" }, - {"s16x4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=5}, 0, 0, FLAGS, "nsize" }, - {"s32x4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=6}, 0, 0, FLAGS, "nsize" }, - {"nns", "set number of neurons in predictor neural network", OFFSET(nnsparam), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, FLAGS, "nns" }, - {"n16", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "nns" }, - {"n32", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "nns" }, - {"n64", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "nns" }, - {"n128", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "nns" }, - {"n256", NULL, 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, FLAGS, "nns" }, - {"qual", "set quality", OFFSET(qual), AV_OPT_TYPE_INT, {.i64=1}, 1, 2, FLAGS, "qual" }, - {"fast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "qual" }, - {"slow", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "qual" }, - {"etype", "set which set of weights to use in the predictor", OFFSET(etype), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "etype" }, - {"a", "weights trained to minimize absolute error", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "etype" }, - {"s", "weights trained to minimize squared error", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "etype" }, - {"pscrn", "set prescreening", OFFSET(pscrn), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS, "pscrn" }, - {"none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "pscrn" }, - {"original", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "pscrn" }, - {"new", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "pscrn" }, - {"fapprox", NULL, OFFSET(fapprox), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS }, + {"deint", "set which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, RFLAGS, "deint" }, + {"all", "deinterlace all frames", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "deint" }, + {"interlaced", "only deinterlace frames marked as interlaced", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "deint" }, + {"field", "set mode of operation", OFFSET(field), AV_OPT_TYPE_INT, {.i64=-1}, -2, 3, RFLAGS, "field" }, + {"af", "use frame flags, both fields", 0, AV_OPT_TYPE_CONST, {.i64=-2}, 0, 0, RFLAGS, "field" }, + {"a", "use frame flags, single field", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, RFLAGS, "field" }, + {"t", "use top field only", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "field" }, + {"b", "use bottom field only", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "field" }, + {"tf", "use both fields, top first", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "field" }, + {"bf", "use both fields, bottom first", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, RFLAGS, "field" }, + {"planes", "set which planes to process", OFFSET(process_plane), AV_OPT_TYPE_INT, {.i64=7}, 0, 15, RFLAGS }, + {"nsize", "set size of local neighborhood around each pixel, used by the predictor neural network", OFFSET(nsize), AV_OPT_TYPE_INT, {.i64=6}, 0, 6, RFLAGS, "nsize" }, + {"s8x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "nsize" }, + {"s16x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "nsize" }, + {"s32x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "nsize" }, + {"s48x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, RFLAGS, "nsize" }, + {"s8x4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, RFLAGS, "nsize" }, + {"s16x4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=5}, 0, 0, RFLAGS, "nsize" }, + {"s32x4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=6}, 0, 0, RFLAGS, "nsize" }, + {"nns", "set number of neurons in predictor neural network", OFFSET(nnsparam), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, RFLAGS, "nns" }, + {"n16", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "nns" }, + {"n32", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "nns" }, + {"n64", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "nns" }, + {"n128", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, RFLAGS, "nns" }, + {"n256", NULL, 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, RFLAGS, "nns" }, + {"qual", "set quality", OFFSET(qual), AV_OPT_TYPE_INT, {.i64=1}, 1, 2, RFLAGS, "qual" }, + {"fast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "qual" }, + {"slow", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "qual" }, + {"etype", "set which set of weights to use in the predictor", OFFSET(etype), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, RFLAGS, "etype" }, + {"a", "weights trained to minimize absolute error", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "etype" }, + {"abs","weights trained to minimize absolute error", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "etype" }, + {"s", "weights trained to minimize squared error", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "etype" }, + {"mse","weights trained to minimize squared error", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "etype" }, + {"pscrn", "set prescreening", OFFSET(pscrn), AV_OPT_TYPE_INT, {.i64=2}, 0, 4, RFLAGS, "pscrn" }, + {"none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "pscrn" }, + {"original", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "pscrn" }, + {"new", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "pscrn" }, + {"new2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, RFLAGS, "pscrn" }, + {"new3", NULL, 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, RFLAGS, "pscrn" }, { NULL } }; AVFILTER_DEFINE_CLASS(nnedi); -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - NNEDIContext *s = ctx->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - int ret; - - s->nb_planes = av_pix_fmt_count_planes(inlink->format); - if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) - return ret; - - s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); - s->planeheight[0] = s->planeheight[3] = inlink->h; - - return 0; -} - static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; - NNEDIContext *s = ctx->priv; outlink->time_base.num = ctx->inputs[0]->time_base.num; outlink->time_base.den = ctx->inputs[0]->time_base.den * 2; outlink->w = ctx->inputs[0]->w; outlink->h = ctx->inputs[0]->h; - if (s->field > 1 || s->field == -2) - outlink->frame_rate = av_mul_q(ctx->inputs[0]->frame_rate, - (AVRational){2, 1}); + outlink->frame_rate = av_mul_q(ctx->inputs[0]->frame_rate, + (AVRational){2, 1}); return 0; } @@ -184,14 +182,28 @@ static int config_output(AVFilterLink *outlink) static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_GRAY8, + AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P, - AV_PIX_FMT_GBRP, - AV_PIX_FMT_GRAY8, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_YUV440P12, + 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_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_NONE }; @@ -201,679 +213,508 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } -static void copy_pad(const AVFrame *src, FrameData *frame_data, NNEDIContext *s, int fn) +static float dot_dsp(const NNEDIContext *const s, const float *kernel, const float *input, + int n, float scale, float bias) { - const int off = 1 - fn; - int plane, y, x; + float sum, y; - for (plane = 0; plane < s->nb_planes; plane++) { - const uint8_t *srcp = (const uint8_t *)src->data[plane]; - uint8_t *dstp = (uint8_t *)frame_data->paddedp[plane]; + sum = s->fdsp->scalarproduct_float(kernel, input, n); - const int src_stride = src->linesize[plane]; - const int dst_stride = frame_data->padded_stride[plane]; + y = sum * scale + bias + 1e-20f; - const int src_height = s->planeheight[plane]; - const int dst_height = frame_data->padded_height[plane]; + return y; +} - const int src_width = s->linesize[plane]; - const int dst_width = frame_data->padded_width[plane]; +static float elliott(float x) +{ + return x / (1.0f + fabsf(x)); +} - int c = 4; +static void transform_elliott(float *input, int size) +{ + for (int i = 0; i < size; i++) + input[i] = elliott(input[i]); +} - if (!(s->process_plane & (1 << plane))) - continue; +static void process_old(AVFilterContext *ctx, + const void *src, ptrdiff_t src_stride, + uint8_t *prescreen, int N, + const PrescreenerCoefficients *const m_data) +{ + NNEDIContext *s = ctx->priv; + const float *src_p = src; - // Copy. - for (y = off; y < src_height; y += 2) - memcpy(dstp + 32 + (6 + y) * dst_stride, - srcp + y * src_stride, - src_width * sizeof(uint8_t)); + // Adjust source pointer to point to top-left of filter window. + const float *window = src_p - 2 * src_stride - 5; - // And pad. - dstp += (6 + off) * dst_stride; - for (y = 6 + off; y < dst_height - 6; y += 2) { - int c = 2; + for (int j = 0; j < N; j++) { + LOCAL_ALIGNED_32(float, input, [48]); + float state[12]; - for (x = 0; x < 32; x++) - dstp[x] = dstp[64 - x]; + for (int i = 0; i < 4; i++) + memcpy(input + i * 12, window + i * src_stride + j, 12 * sizeof(float)); - for (x = dst_width - 32; x < dst_width; x++, c += 2) - dstp[x] = dstp[x - c]; + // Layer 0. + for (int n = 0; n < 4; n++) + state[n] = dot_dsp(s, m_data->kernel_l0[n], input, 48, 1.0f, m_data->bias_l0[n]); + transform_elliott(state + 1, 3); - dstp += dst_stride * 2; + // Layer 1. + for (int n = 0; n < 4; n++) + state[n + 4] = dot_dsp(s, m_data->kernel_l1[n], state, 4, 1.0f, m_data->bias_l1[n]); + transform_elliott(state + 4, 3); + + // Layer 2. + for (int n = 0; n < 4; n++) + state[n + 8] = dot_dsp(s, m_data->kernel_l2[n], state, 8, 1.0f, m_data->bias_l2[n]); + + prescreen[j] = FFMAX(state[10], state[11]) <= FFMAX(state[8], state[9]) ? 255 : 0; + } +} + +static void process_new(AVFilterContext *ctx, + const void *src, ptrdiff_t src_stride, + uint8_t *prescreen, int N, + const PrescreenerCoefficients *const m_data) +{ + NNEDIContext *s = ctx->priv; + const float *src_p = src; + + // Adjust source pointer to point to top-left of filter window. + const float *window = src_p - 2 * src_stride - 6; + + for (int j = 0; j < N; j += 4) { + LOCAL_ALIGNED_32(float, input, [64]); + float state[8]; + + for (int i = 0; i < 4; i++) + memcpy(input + i * 16, window + i * src_stride + j, 16 * sizeof(float)); + + for (int n = 0; n < 4; n++) + state[n] = dot_dsp(s, m_data->kernel_l0[n], input, 64, 1.0f, m_data->bias_l0[n]); + transform_elliott(state, 4); + + for (int n = 0; n < 4; n++) + state[n + 4] = dot_dsp(s, m_data->kernel_l1[n], state, 4, 1.0f, m_data->bias_l1[n]); + + for (int n = 0; n < 4; n++) + prescreen[j + n] = state[n + 4] > 0.f; + } +} + +static int filter_offset(int nn, const PredictorCoefficients *const model) +{ + return nn * model->nsize; +} + +static const float *softmax_q1_filter(int nn, + const PredictorCoefficients *const model) +{ + return model->softmax_q1 + filter_offset(nn, model); +} + +static const float *elliott_q1_filter(int nn, + const PredictorCoefficients *const model) +{ + return model->elliott_q1 + filter_offset(nn, model); +} + +static const float *softmax_q2_filter(int nn, + const PredictorCoefficients *const model) +{ + return model->softmax_q2 + filter_offset(nn, model); +} + +static const float *elliott_q2_filter(int nn, + const PredictorCoefficients *const model) +{ + return model->elliott_q2 + filter_offset(nn, model); +} + +static void gather_input(const float *src, ptrdiff_t src_stride, + float *buf, float mstd[4], + const PredictorCoefficients *const model) +{ + const float scale = 1.f / model->nsize; + float sum = 0.f; + float sum_sq = 0.f; + float tmp; + + for (int i = 0; i < model->ydim; i++) { + memcpy(buf, src, model->xdim * sizeof(float)); + + for (int j = 0; j < model->xdim; j++) { + const float val = src[j]; + + sum += val; + sum_sq += val * val; } - dstp = (uint8_t *)frame_data->paddedp[plane]; - for (y = off; y < 6; y += 2) - memcpy(dstp + y * dst_stride, - dstp + (12 + 2 * off - y) * dst_stride, - dst_width * sizeof(uint8_t)); - - for (y = dst_height - 6 + off; y < dst_height; y += 2, c += 4) - memcpy(dstp + y * dst_stride, - dstp + (y - c) * dst_stride, - dst_width * sizeof(uint8_t)); - } -} - -static void elliott(float *data, const int n) -{ - int i; - - for (i = 0; i < n; i++) - data[i] = data[i] / (1.0f + FFABS(data[i])); -} - -static void dot_prod(NNEDIContext *s, const float *data, const float *weights, float *vals, const int n, const int len, const float *scale) -{ - int i; - - for (i = 0; i < n; i++) { - float sum; - - sum = s->fdsp->scalarproduct_float(data, &weights[i * len], len); - - vals[i] = sum * scale[0] + weights[n * len + i]; - } -} - -static void dot_prods(NNEDIContext *s, const float *dataf, const float *weightsf, float *vals, const int n, const int len, const float *scale) -{ - const int16_t *data = (int16_t *)dataf; - const int16_t *weights = (int16_t *)weightsf; - const float *wf = (float *)&weights[n * len]; - int i, j; - - for (i = 0; i < n; i++) { - int sum = 0, off = ((i >> 2) << 3) + (i & 3); - for (j = 0; j < len; j++) - sum += data[j] * weights[i * len + j]; - - vals[i] = sum * wf[off] * scale[0] + wf[off + 4]; - } -} - -static void compute_network0(NNEDIContext *s, const float *input, const float *weights, uint8_t *d) -{ - float t, temp[12], scale = 1.0f; - - dot_prod(s, input, weights, temp, 4, 48, &scale); - t = temp[0]; - elliott(temp, 4); - temp[0] = t; - dot_prod(s, temp, weights + 4 * 49, temp + 4, 4, 4, &scale); - elliott(temp + 4, 4); - dot_prod(s, temp, weights + 4 * 49 + 4 * 5, temp + 8, 4, 8, &scale); - if (FFMAX(temp[10], temp[11]) <= FFMAX(temp[8], temp[9])) - d[0] = 1; - else - d[0] = 0; -} - -static void compute_network0_i16(NNEDIContext *s, const float *inputf, const float *weightsf, uint8_t *d) -{ - const float *wf = weightsf + 2 * 48; - float t, temp[12], scale = 1.0f; - - dot_prods(s, inputf, weightsf, temp, 4, 48, &scale); - t = temp[0]; - elliott(temp, 4); - temp[0] = t; - dot_prod(s, temp, wf + 8, temp + 4, 4, 4, &scale); - elliott(temp + 4, 4); - dot_prod(s, temp, wf + 8 + 4 * 5, temp + 8, 4, 8, &scale); - if (FFMAX(temp[10], temp[11]) <= FFMAX(temp[8], temp[9])) - d[0] = 1; - else - d[0] = 0; -} - -static void pixel2float48(const uint8_t *t8, const int pitch, float *p) -{ - const uint8_t *t = (const uint8_t *)t8; - int y, x; - - for (y = 0; y < 4; y++) - for (x = 0; x < 12; x++) - p[y * 12 + x] = t[y * pitch * 2 + x]; -} - -static void byte2word48(const uint8_t *t, const int pitch, float *pf) -{ - int16_t *p = (int16_t *)pf; - int y, x; - - for (y = 0; y < 4; y++) - for (x = 0; x < 12; x++) - p[y * 12 + x] = t[y * pitch * 2 + x]; -} - -static int32_t process_line0(const uint8_t *tempu, int width, uint8_t *dstp8, const uint8_t *src3p8, const int src_pitch, const int max_value, const int chroma) -{ - uint8_t *dstp = (uint8_t *)dstp8; - const uint8_t *src3p = (const uint8_t *)src3p8; - int minimum = 0; - int maximum = max_value - 1; // Technically the -1 is only needed for 8 and 16 bit input. - int count = 0, x; - for (x = 0; x < width; x++) { - if (tempu[x]) { - int tmp = 19 * (src3p[x + src_pitch * 2] + src3p[x + src_pitch * 4]) - 3 * (src3p[x] + src3p[x + src_pitch * 6]); - tmp /= 32; - dstp[x] = FFMAX(FFMIN(tmp, maximum), minimum); - } else { - dstp[x] = 255; - count++; - } - } - return count; -} - -// new prescreener functions -static void byte2word64(const uint8_t *t, const int pitch, float *p) -{ - int16_t *ps = (int16_t *)p; - int y, x; - - for (y = 0; y < 4; y++) - for (x = 0; x < 16; x++) - ps[y * 16 + x] = t[y * pitch * 2 + x]; -} - -static void compute_network0new(NNEDIContext *s, const float *datai, const float *weights, uint8_t *d) -{ - int16_t *data = (int16_t *)datai; - int16_t *ws = (int16_t *)weights; - float *wf = (float *)&ws[4 * 64]; - float vals[8]; - int mask, i, j; - - for (i = 0; i < 4; i++) { - int sum = 0; - float t; - - for (j = 0; j < 64; j++) - sum += data[j] * ws[(i << 3) + ((j >> 3) << 5) + (j & 7)]; - t = sum * wf[i] + wf[4 + i]; - vals[i] = t / (1.0f + FFABS(t)); + src += src_stride; + buf += model->xdim; } - for (i = 0; i < 4; i++) { - float sum = 0.0f; - - for (j = 0; j < 4; j++) - sum += vals[j] * wf[8 + i + (j << 2)]; - vals[4 + i] = sum + wf[8 + 16 + i]; - } - - mask = 0; - for (i = 0; i < 4; i++) { - if (vals[4 + i] > 0.0f) - mask |= (0x1 << (i << 3)); - } - - ((int *)d)[0] = mask; -} - -static void evalfunc_0(NNEDIContext *s, FrameData *frame_data) -{ - float *input = frame_data->input; - const float *weights0 = s->weights0; - float *temp = frame_data->temp; - uint8_t *tempu = (uint8_t *)temp; - int plane, x, y; - - // And now the actual work. - for (plane = 0; plane < s->nb_planes; plane++) { - const uint8_t *srcp = (const uint8_t *)frame_data->paddedp[plane]; - const int src_stride = frame_data->padded_stride[plane] / sizeof(uint8_t); - - const int width = frame_data->padded_width[plane]; - const int height = frame_data->padded_height[plane]; - - uint8_t *dstp = (uint8_t *)frame_data->dstp[plane]; - const int dst_stride = frame_data->dst_stride[plane] / sizeof(uint8_t); - const uint8_t *src3p; - int ystart, ystop; - int32_t *lcount; - - if (!(s->process_plane & (1 << plane))) - continue; - - for (y = 1 - frame_data->field[plane]; y < height - 12; y += 2) { - memcpy(dstp + y * dst_stride, - srcp + 32 + (6 + y) * src_stride, - (width - 64) * sizeof(uint8_t)); - - } - - ystart = 6 + frame_data->field[plane]; - ystop = height - 6; - srcp += ystart * src_stride; - dstp += (ystart - 6) * dst_stride - 32; - src3p = srcp - src_stride * 3; - lcount = frame_data->lcount[plane] - 6; - - if (s->pscrn == 1) { // original - for (y = ystart; y < ystop; y += 2) { - for (x = 32; x < width - 32; x++) { - s->readpixels((const uint8_t *)(src3p + x - 5), src_stride, input); - s->compute_network0(s, input, weights0, tempu+x); - } - lcount[y] += s->process_line0(tempu + 32, width - 64, (uint8_t *)(dstp + 32), (const uint8_t *)(src3p + 32), src_stride, s->max_value, plane); - src3p += src_stride * 2; - dstp += dst_stride * 2; - } - } else if (s->pscrn > 1) { // new - for (y = ystart; y < ystop; y += 2) { - for (x = 32; x < width - 32; x += 4) { - s->readpixels((const uint8_t *)(src3p + x - 6), src_stride, input); - s->compute_network0(s, input, weights0, tempu + x); - } - lcount[y] += s->process_line0(tempu + 32, width - 64, (uint8_t *)(dstp + 32), (const uint8_t *)(src3p + 32), src_stride, s->max_value, plane); - src3p += src_stride * 2; - dstp += dst_stride * 2; - } - } else { // no prescreening - for (y = ystart; y < ystop; y += 2) { - memset(dstp + 32, 255, (width - 64) * sizeof(uint8_t)); - lcount[y] += width - 64; - dstp += dst_stride * 2; - } - } - } -} - -static void extract_m8(const uint8_t *srcp8, const int stride, const int xdia, const int ydia, float *mstd, float *input) -{ - // uint8_t or uint16_t or float - const uint8_t *srcp = (const uint8_t *)srcp8; - float scale; - double tmp; - - // int32_t or int64_t or double - int64_t sum = 0, sumsq = 0; - int y, x; - - for (y = 0; y < ydia; y++) { - const uint8_t *srcpT = srcp + y * stride * 2; - - for (x = 0; x < xdia; x++) { - sum += srcpT[x]; - sumsq += (uint32_t)srcpT[x] * (uint32_t)srcpT[x]; - input[x] = srcpT[x]; - } - input += xdia; - } - scale = 1.0f / (xdia * ydia); mstd[0] = sum * scale; - tmp = (double)sumsq * scale - (double)mstd[0] * mstd[0]; - mstd[3] = 0.0f; - if (tmp <= FLT_EPSILON) - mstd[1] = mstd[2] = 0.0f; - else { - mstd[1] = sqrt(tmp); + mstd[3] = 0.f; + + tmp = sum_sq * scale - mstd[0] * mstd[0]; + if (tmp < FLT_EPSILON) { + mstd[1] = 0.0f; + mstd[2] = 0.0f; + } else { + mstd[1] = sqrtf(tmp); mstd[2] = 1.0f / mstd[1]; } } -static void extract_m8_i16(const uint8_t *srcp, const int stride, const int xdia, const int ydia, float *mstd, float *inputf) +static float softmax_exp(float x) { - int16_t *input = (int16_t *)inputf; - float scale; - int sum = 0, sumsq = 0; - int y, x; - - for (y = 0; y < ydia; y++) { - const uint8_t *srcpT = srcp + y * stride * 2; - for (x = 0; x < xdia; x++) { - sum += srcpT[x]; - sumsq += srcpT[x] * srcpT[x]; - input[x] = srcpT[x]; - } - input += xdia; - } - scale = 1.0f / (float)(xdia * ydia); - mstd[0] = sum * scale; - mstd[1] = sumsq * scale - mstd[0] * mstd[0]; - mstd[3] = 0.0f; - if (mstd[1] <= FLT_EPSILON) - mstd[1] = mstd[2] = 0.0f; - else { - mstd[1] = sqrt(mstd[1]); - mstd[2] = 1.0f / mstd[1]; - } + return expf(av_clipf(x, -80.f, 80.f)); } - -static const float exp_lo = -80.0f; -static const float exp_hi = +80.0f; - -static void e2_m16(float *s, const int n) +static void transform_softmax_exp(float *input, int size) { - int i; - - for (i = 0; i < n; i++) - s[i] = exp(av_clipf(s[i], exp_lo, exp_hi)); + for (int i = 0; i < size; i++) + input[i] = softmax_exp(input[i]); } -const float min_weight_sum = 1e-10f; - -static void weighted_avg_elliott_mul5_m16(const float *w, const int n, float *mstd) +static void wae5(const float *softmax, const float *el, + int n, float mstd[4]) { float vsum = 0.0f, wsum = 0.0f; - int i; - for (i = 0; i < n; i++) { - vsum += w[i] * (w[n + i] / (1.0f + FFABS(w[n + i]))); - wsum += w[i]; + for (int i = 0; i < n; i++) { + vsum += softmax[i] * elliott(el[i]); + wsum += softmax[i]; } - if (wsum > min_weight_sum) - mstd[3] += ((5.0f * vsum) / wsum) * mstd[1] + mstd[0]; + + if (wsum > 1e-10f) + mstd[3] += (5.0f * vsum) / wsum * mstd[1] + mstd[0]; else mstd[3] += mstd[0]; } - -static void evalfunc_1(NNEDIContext *s, FrameData *frame_data) +static void predictor(AVFilterContext *ctx, + const void *src, ptrdiff_t src_stride, void *dst, + const uint8_t *prescreen, int N, + const PredictorCoefficients *const model, int use_q2) { - float *input = frame_data->input; - float *temp = frame_data->temp; - float **weights1 = s->weights1; - const int qual = s->qual; - const int asize = s->asize; - const int nns = s->nns; - const int xdia = s->xdia; - const int xdiad2m1 = (xdia / 2) - 1; - const int ydia = s->ydia; - const float scale = 1.0f / (float)qual; - int plane, y, x, i; + const NNEDIContext *const s = ctx->priv; + const float *src_p = src; + float *dst_p = dst; - for (plane = 0; plane < s->nb_planes; plane++) { - const uint8_t *srcp = (const uint8_t *)frame_data->paddedp[plane]; - const int src_stride = frame_data->padded_stride[plane] / sizeof(uint8_t); + // Adjust source pointer to point to top-left of filter window. + const float *window = src_p - (model->ydim / 2) * src_stride - (model->xdim / 2 - 1); + const int filter_size = model->nsize; + const int nns = model->nns; - const int width = frame_data->padded_width[plane]; - const int height = frame_data->padded_height[plane]; + for (int i = 0; i < N; i++) { + LOCAL_ALIGNED_32(float, input, [48 * 6]); + float activation[256 * 2]; + float mstd[4]; + float scale; - uint8_t *dstp = (uint8_t *)frame_data->dstp[plane]; - const int dst_stride = frame_data->dst_stride[plane] / sizeof(uint8_t); - - const int ystart = frame_data->field[plane]; - const int ystop = height - 12; - const uint8_t *srcpp; - - if (!(s->process_plane & (1 << plane))) + if (prescreen[i]) continue; - srcp += (ystart + 6) * src_stride; - dstp += ystart * dst_stride - 32; - srcpp = srcp - (ydia - 1) * src_stride - xdiad2m1; + gather_input(window + i, src_stride, input, mstd, model); + scale = mstd[2]; - for (y = ystart; y < ystop; y += 2) { - for (x = 32; x < width - 32; x++) { - float mstd[4]; + for (int nn = 0; nn < nns; nn++) + activation[nn] = dot_dsp(s, softmax_q1_filter(nn, model), input, filter_size, scale, model->softmax_bias_q1[nn]); - if (dstp[x] != 255) - continue; + for (int nn = 0; nn < nns; nn++) + activation[nns + nn] = dot_dsp(s, elliott_q1_filter(nn, model), input, filter_size, scale, model->elliott_bias_q1[nn]); - s->extract((const uint8_t *)(srcpp + x), src_stride, xdia, ydia, mstd, input); - for (i = 0; i < qual; i++) { - s->dot_prod(s, input, weights1[i], temp, nns * 2, asize, mstd + 2); - s->expfunc(temp, nns); - s->wae5(temp, nns, mstd); - } + transform_softmax_exp(activation, nns); + wae5(activation, activation + nns, nns, mstd); - dstp[x] = FFMIN(FFMAX((int)(mstd[3] * scale + 0.5f), 0), s->max_value); - } - srcpp += src_stride * 2; - dstp += dst_stride * 2; + if (use_q2) { + for (int nn = 0; nn < nns; nn++) + activation[nn] = dot_dsp(s, softmax_q2_filter(nn, model), input, filter_size, scale, model->softmax_bias_q2[nn]); + + for (int nn = 0; nn < nns; nn++) + activation[nns + nn] = dot_dsp(s, elliott_q2_filter(nn, model), input, filter_size, scale, model->elliott_bias_q2[nn]); + + transform_softmax_exp(activation, nns); + wae5(activation, activation + nns, nns, mstd); } + + dst_p[i] = mstd[3] * (use_q2 ? 0.5f : 1.f); } } -#define NUM_NSIZE 7 -#define NUM_NNS 5 - -static int roundds(const double f) +static void read_bytes(const uint8_t *src, float *dst, + int src_stride, int dst_stride, + int width, int height, float scale) { - if (f - floor(f) >= 0.5) - return FFMIN((int)ceil(f), 32767); - return FFMAX((int)floor(f), -32768); + for (int y = 0; y < height; y++) { + for (int x = 0; x < 32; x++) + dst[-x - 1] = src[x]; + + for (int x = 0; x < width; x++) + dst[x] = src[x]; + + for (int x = 0; x < 32; x++) + dst[width + x] = src[width - x - 1]; + + dst += dst_stride; + src += src_stride; + } } -static void select_functions(NNEDIContext *s) +static void read_words(const uint8_t *srcp, float *dst, + int src_stride, int dst_stride, + int width, int height, float scale) { - s->copy_pad = copy_pad; - s->evalfunc_0 = evalfunc_0; - s->evalfunc_1 = evalfunc_1; + const uint16_t *src = (const uint16_t *)srcp; - // evalfunc_0 - s->process_line0 = process_line0; + src_stride /= 2; - if (s->pscrn < 2) { // original prescreener - if (s->fapprox & 1) { // int16 dot products - s->readpixels = byte2word48; - s->compute_network0 = compute_network0_i16; - } else { - s->readpixels = pixel2float48; - s->compute_network0 = compute_network0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < 32; x++) + dst[-x - 1] = src[x] * scale; + + for (int x = 0; x < width; x++) + dst[x] = src[x] * scale; + + for (int x = 0; x < 32; x++) + dst[width + x] = src[width - x - 1] * scale; + + dst += dst_stride; + src += src_stride; + } +} + +static void write_bytes(const float *src, uint8_t *dst, + int src_stride, int dst_stride, + int width, int height, int depth, + float scale) +{ + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) + dst[x] = av_clip_uint8(src[x]); + + dst += dst_stride; + src += src_stride; + } +} + +static void write_words(const float *src, uint8_t *dstp, + int src_stride, int dst_stride, + int width, int height, int depth, + float scale) +{ + uint16_t *dst = (uint16_t *)dstp; + + dst_stride /= 2; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) + dst[x] = av_clip_uintp2_c(src[x] * scale, depth); + + dst += dst_stride; + src += src_stride; + } +} + +static void interpolation(const void *src, ptrdiff_t src_stride, + void *dst, const uint8_t *prescreen, int n) +{ + const float *src_p = src; + float *dst_p = dst; + const float *window = src_p - 2 * src_stride; + + for (int i = 0; i < n; i++) { + float accum = 0.0f; + + if (!prescreen[i]) + continue; + + accum += (-3.0f / 32.0f) * window[0 * src_stride + i]; + accum += (19.0f / 32.0f) * window[1 * src_stride + i]; + accum += (19.0f / 32.0f) * window[2 * src_stride + i]; + accum += (-3.0f / 32.0f) * window[3 * src_stride + i]; + + dst_p[i] = accum; + } +} + +static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + const NNEDIContext *const s = ctx->priv; + AVFrame *out = arg; + AVFrame *in = s->prev; + const float in_scale = s->in_scale; + const float out_scale = s->out_scale; + const int depth = s->depth; + const int interlaced = in->interlaced_frame; + const int tff = s->field_n == (s->field < 0 ? interlaced ? in->top_field_first : 1 : + (s->field & 1) ^ 1); + + + for (int p = 0; p < s->nb_planes; p++) { + const int height = s->planeheight[p]; + const int width = s->planewidth[p]; + const int slice_start = 2 * ((height / 2 * jobnr) / nb_jobs); + const int slice_end = 2 * ((height / 2 * (jobnr+1)) / nb_jobs); + const uint8_t *src_data = in->data[p]; + uint8_t *dst_data = out->data[p]; + uint8_t *dst = out->data[p] + slice_start * out->linesize[p]; + const int src_linesize = in->linesize[p]; + const int dst_linesize = out->linesize[p]; + uint8_t *prescreen_buf = s->prescreen_buf[jobnr]; + float *srcbuf = s->input_buf[jobnr]; + const int srcbuf_stride = width + 64; + float *dstbuf = s->output_buf[jobnr]; + const int dstbuf_stride = width; + const int slice_height = (slice_end - slice_start) / 2; + const int last_slice = slice_end == height; + const uint8_t *in_line; + uint8_t *out_line; + int y_out; + + if (!(s->process_plane & (1 << p))) { + av_image_copy_plane(dst, out->linesize[p], + in->data[p] + slice_start * in->linesize[p], + in->linesize[p], + s->linesize[p], slice_end - slice_start); + continue; } - } else { // new prescreener - // only int16 dot products - s->readpixels = byte2word64; - s->compute_network0 = compute_network0new; + + y_out = slice_start + (tff ^ (slice_start & 1)); + in_line = src_data + (y_out * src_linesize); + out_line = dst_data + (y_out * dst_linesize); + + while (y_out < slice_end) { + memcpy(out_line, in_line, s->linesize[p]); + y_out += 2; + in_line += src_linesize * 2; + out_line += dst_linesize * 2; + } + + y_out = slice_start + ((!tff) ^ (slice_start & 1)); + + s->read(src_data + FFMAX(y_out - 5, tff) * src_linesize, + srcbuf + 32, + src_linesize * 2, srcbuf_stride, + width, 1, in_scale); + srcbuf += srcbuf_stride; + + s->read(src_data + FFMAX(y_out - 3, tff) * src_linesize, + srcbuf + 32, + src_linesize * 2, srcbuf_stride, + width, 1, in_scale); + srcbuf += srcbuf_stride; + + s->read(src_data + FFMAX(y_out - 1, tff) * src_linesize, + srcbuf + 32, + src_linesize * 2, srcbuf_stride, + width, 1, in_scale); + srcbuf += srcbuf_stride; + + in_line = src_data + FFMIN(y_out + 1, height - 1 - !tff) * src_linesize; + out_line = dst_data + (y_out * dst_linesize); + + s->read(in_line, srcbuf + 32, src_linesize * 2, srcbuf_stride, + width, slice_height - last_slice, in_scale); + + y_out += (slice_height - last_slice) * 2; + + s->read(src_data + FFMIN(y_out + 1, height - 1 - !tff) * src_linesize, + srcbuf + 32 + srcbuf_stride * (slice_height - last_slice), + src_linesize * 2, srcbuf_stride, + width, 1, in_scale); + + s->read(src_data + FFMIN(y_out + 3, height - 1 - !tff) * src_linesize, + srcbuf + 32 + srcbuf_stride * (slice_height + 1 - last_slice), + src_linesize * 2, srcbuf_stride, + width, 1, in_scale); + + s->read(src_data + FFMIN(y_out + 5, height - 1 - !tff) * src_linesize, + srcbuf + 32 + srcbuf_stride * (slice_height + 2 - last_slice), + src_linesize * 2, srcbuf_stride, + width, 1, in_scale); + + for (int y = 0; y < slice_end - slice_start; y += 2) { + if (s->pscrn > 0) + s->prescreen[s->pscrn > 1](ctx, srcbuf + (y / 2) * srcbuf_stride + 32, + srcbuf_stride, prescreen_buf, width, + &s->prescreener[s->pscrn - 1]); + + predictor(ctx, + srcbuf + (y / 2) * srcbuf_stride + 32, + srcbuf_stride, + dstbuf + (y / 2) * dstbuf_stride, + prescreen_buf, width, + &s->coeffs[s->etype][s->nnsparam][s->nsize], s->qual == 2); + + if (s->pscrn > 0) + interpolation(srcbuf + (y / 2) * srcbuf_stride + 32, + srcbuf_stride, + dstbuf + (y / 2) * dstbuf_stride, + prescreen_buf, width); + } + + s->write(dstbuf, out_line, dstbuf_stride, dst_linesize * 2, + width, slice_height, depth, out_scale); } - // evalfunc_1 - s->wae5 = weighted_avg_elliott_mul5_m16; - - if (s->fapprox & 2) { // use int16 dot products - s->extract = extract_m8_i16; - s->dot_prod = dot_prods; - } else { // use float dot products - s->extract = extract_m8; - s->dot_prod = dot_prod; - } - - s->expfunc = e2_m16; -} - -static int modnpf(const int m, const int n) -{ - if ((m % n) == 0) - return m; - return m + n - (m % n); + return 0; } static int get_frame(AVFilterContext *ctx, int is_second) { NNEDIContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *src = s->src; - FrameData *frame_data; - int effective_field = s->field; - size_t temp_size; - int field_n; - int plane; + AVFrame *dst; - if (effective_field > 1) - effective_field -= 2; - else if (effective_field < 0) - effective_field += 2; - - if (s->field < 0 && src->interlaced_frame && src->top_field_first == 0) - effective_field = 0; - else if (s->field < 0 && src->interlaced_frame && src->top_field_first == 1) - effective_field = 1; - else - effective_field = !effective_field; - - if (s->field > 1 || s->field == -2) { - if (is_second) { - field_n = (effective_field == 0); - } else { - field_n = (effective_field == 1); - } - } else { - field_n = effective_field; - } - - s->dst = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!s->dst) + dst = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!dst) return AVERROR(ENOMEM); - av_frame_copy_props(s->dst, src); - s->dst->interlaced_frame = 0; + av_frame_copy_props(dst, s->prev); + dst->interlaced_frame = 0; + dst->pts = s->pts; - frame_data = &s->frame_data; + ctx->internal->execute(ctx, filter_slice, dst, NULL, FFMIN(s->planeheight[1] / 2, s->nb_threads)); - for (plane = 0; plane < s->nb_planes; plane++) { - int dst_height = s->planeheight[plane]; - int dst_width = s->linesize[plane]; + if (s->field == -2 || s->field > 1) + s->field_n = !s->field_n; - const int min_alignment = 16; - const int min_pad = 10; - - if (!(s->process_plane & (1 << plane))) { - av_image_copy_plane(s->dst->data[plane], s->dst->linesize[plane], - src->data[plane], src->linesize[plane], - s->linesize[plane], - s->planeheight[plane]); - continue; - } - - frame_data->padded_width[plane] = dst_width + 64; - frame_data->padded_height[plane] = dst_height + 12; - frame_data->padded_stride[plane] = modnpf(frame_data->padded_width[plane] + min_pad, min_alignment); // TODO: maybe min_pad is in pixels too? - if (!frame_data->paddedp[plane]) { - frame_data->paddedp[plane] = av_malloc_array(frame_data->padded_stride[plane], frame_data->padded_height[plane]); - if (!frame_data->paddedp[plane]) - return AVERROR(ENOMEM); - } - - frame_data->dstp[plane] = s->dst->data[plane]; - frame_data->dst_stride[plane] = s->dst->linesize[plane]; - - if (!frame_data->lcount[plane]) { - frame_data->lcount[plane] = av_calloc(dst_height, sizeof(int32_t) * 16); - if (!frame_data->lcount[plane]) - return AVERROR(ENOMEM); - } else { - memset(frame_data->lcount[plane], 0, dst_height * sizeof(int32_t) * 16); - } - - frame_data->field[plane] = field_n; - } - - if (!frame_data->input) { - frame_data->input = av_malloc(512 * sizeof(float)); - if (!frame_data->input) - return AVERROR(ENOMEM); - } - // evalfunc_0 requires at least padded_width[0] bytes. - // evalfunc_1 requires at least 512 floats. - if (!frame_data->temp) { - temp_size = FFMAX(frame_data->padded_width[0], 512 * sizeof(float)); - frame_data->temp = av_malloc(temp_size); - if (!frame_data->temp) - return AVERROR(ENOMEM); - } - - // Copy src to a padded "frame" in frame_data and mirror the edges. - s->copy_pad(src, frame_data, s, field_n); - - // Handles prescreening and the cubic interpolation. - s->evalfunc_0(s, frame_data); - - // The rest. - s->evalfunc_1(s, frame_data); - - return 0; + return ff_filter_frame(outlink, dst); } -static int filter_frame(AVFilterLink *inlink, AVFrame *src) +static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; NNEDIContext *s = ctx->priv; int ret; - if ((s->field > 1 || - s->field == -2) && !s->second) { - goto second; - } else if (s->field > 1 || - s->field == -2) { - AVFrame *dst; - - s->src = s->second; - ret = get_frame(ctx, 1); - if (ret < 0) { - av_frame_free(&s->dst); - av_frame_free(&s->second); - s->src = NULL; - return ret; - } - dst = s->dst; - - if (src->pts != AV_NOPTS_VALUE && - dst->pts != AV_NOPTS_VALUE) - dst->pts += src->pts; - else - dst->pts = AV_NOPTS_VALUE; - - ret = ff_filter_frame(outlink, dst); - if (ret < 0) - return ret; - if (s->eof) - return 0; - s->cur_pts = s->second->pts; - av_frame_free(&s->second); -second: - if ((s->deint && src->interlaced_frame && - !ctx->is_disabled) || - (!s->deint && !ctx->is_disabled)) { - s->second = src; - } + if (!s->prev) { + s->prev = in; + return 0; } - if ((s->deint && !src->interlaced_frame) || ctx->is_disabled) { - AVFrame *dst = av_frame_clone(src); - if (!dst) { - av_frame_free(&src); - av_frame_free(&s->second); - return AVERROR(ENOMEM); - } - - if (s->field > 1 || s->field == -2) { - av_frame_free(&s->second); - if ((s->deint && src->interlaced_frame) || - (!s->deint)) - s->second = src; - } else { - av_frame_free(&src); - } - if (dst->pts != AV_NOPTS_VALUE) - dst->pts *= 2; - return ff_filter_frame(outlink, dst); - } - - s->src = src; - ret = get_frame(ctx, 0); - if (ret < 0) { - av_frame_free(&s->dst); - av_frame_free(&s->src); - av_frame_free(&s->second); + if ((s->deint && !in->interlaced_frame) || ctx->is_disabled) { + s->prev->pts *= 2; + ret = ff_filter_frame(ctx->outputs[0], s->prev); + s->prev = in; return ret; } - if (src->pts != AV_NOPTS_VALUE) - s->dst->pts = src->pts * 2; - if (s->field <= 1 && s->field > -2) { - av_frame_free(&src); - s->src = NULL; + s->pts = s->prev->pts * 2; + ret = get_frame(ctx, 0); + if (ret < 0 || (s->field > -2 && s->field < 2)) { + av_frame_free(&s->prev); + s->prev = in; + return ret; } - return ff_filter_frame(outlink, s->dst); + s->pts = s->prev->pts + in->pts; + ret = get_frame(ctx, 1); + av_frame_free(&s->prev); + s->prev = in; + return ret; } static int request_frame(AVFilterLink *link) @@ -887,42 +728,243 @@ static int request_frame(AVFilterLink *link) ret = ff_request_frame(ctx->inputs[0]); - if (ret == AVERROR_EOF && s->second) { - AVFrame *next = av_frame_clone(s->second); + if (ret == AVERROR_EOF && s->prev) { + AVFrame *next = av_frame_clone(s->prev); if (!next) return AVERROR(ENOMEM); - next->pts = s->second->pts * 2 - s->cur_pts; + next->pts = s->prev->pts + av_rescale_q(1, av_inv_q(ctx->outputs[0]->frame_rate), + ctx->outputs[0]->time_base); s->eof = 1; - filter_frame(ctx->inputs[0], next); + ret = filter_frame(ctx->inputs[0], next); } else if (ret < 0) { return ret; } + return ret; +} + +static void copy_weights(float *dst, int n, const float **data) +{ + memcpy(dst, *data, n * sizeof(float)); + *data += n; +} + +static float *allocate(float **ptr, int size) +{ + float *ret = *ptr; + + *ptr += size; + + return ret; +} + +static int allocate_model(PredictorCoefficients *coeffs, int xdim, int ydim, int nns) +{ + int filter_size = nns * xdim * ydim; + int bias_size = nns; + float *data; + + data = av_calloc(filter_size + bias_size, 4 * sizeof(float)); + if (!data) + return AVERROR(ENOMEM); + + coeffs->data = data; + coeffs->xdim = xdim; + coeffs->ydim = ydim; + coeffs->nsize = xdim * ydim; + coeffs->nns = nns; + + coeffs->softmax_q1 = allocate(&data, filter_size); + coeffs->elliott_q1 = allocate(&data, filter_size); + coeffs->softmax_bias_q1 = allocate(&data, bias_size); + coeffs->elliott_bias_q1 = allocate(&data, bias_size); + + coeffs->softmax_q2 = allocate(&data, filter_size); + coeffs->elliott_q2 = allocate(&data, filter_size); + coeffs->softmax_bias_q2 = allocate(&data, bias_size); + coeffs->elliott_bias_q2 = allocate(&data, bias_size); + return 0; } +static int read_weights(AVFilterContext *ctx, const float *bdata) +{ + NNEDIContext *s = ctx->priv; + int ret; + + copy_weights(&s->prescreener[0].kernel_l0[0][0], 4 * 48, &bdata); + copy_weights(s->prescreener[0].bias_l0, 4, &bdata); + + copy_weights(&s->prescreener[0].kernel_l1[0][0], 4 * 4, &bdata); + copy_weights(s->prescreener[0].bias_l1, 4, &bdata); + + copy_weights(&s->prescreener[0].kernel_l2[0][0], 4 * 8, &bdata); + copy_weights(s->prescreener[0].bias_l2, 4, &bdata); + + for (int i = 0; i < 3; i++) { + PrescreenerCoefficients *data = &s->prescreener[i + 1]; + float kernel_l0_shuffled[4 * 64]; + float kernel_l1_shuffled[4 * 4]; + + copy_weights(kernel_l0_shuffled, 4 * 64, &bdata); + copy_weights(data->bias_l0, 4, &bdata); + + copy_weights(kernel_l1_shuffled, 4 * 4, &bdata); + copy_weights(data->bias_l1, 4, &bdata); + + for (int n = 0; n < 4; n++) { + for (int k = 0; k < 64; k++) + data->kernel_l0[n][k] = kernel_l0_shuffled[(k / 8) * 32 + n * 8 + k % 8]; + for (int k = 0; k < 4; k++) + data->kernel_l1[n][k] = kernel_l1_shuffled[k * 4 + n]; + } + } + + for (int m = 0; m < 2; m++) { + // Grouping by neuron count. + for (int i = 0; i < 5; i++) { + const int nns = NNEDI_NNS[i]; + + // Grouping by window size. + for (int j = 0; j < 7; j++) { + PredictorCoefficients *model = &s->coeffs[m][i][j]; + const int xdim = NNEDI_XDIM[j]; + const int ydim = NNEDI_YDIM[j]; + const int filter_size = xdim * ydim; + + ret = allocate_model(model, xdim, ydim, nns); + if (ret < 0) + return ret; + + // Quality 1 model. NNS[i] * (XDIM[j] * YDIM[j]) * 2 coefficients. + copy_weights(model->softmax_q1, nns * filter_size, &bdata); + copy_weights(model->elliott_q1, nns * filter_size, &bdata); + + // Quality 1 model bias. NNS[i] * 2 coefficients. + copy_weights(model->softmax_bias_q1, nns, &bdata); + copy_weights(model->elliott_bias_q1, nns, &bdata); + + // Quality 2 model. NNS[i] * (XDIM[j] * YDIM[j]) * 2 coefficients. + copy_weights(model->softmax_q2, nns * filter_size, &bdata); + copy_weights(model->elliott_q2, nns * filter_size, &bdata); + + // Quality 2 model bias. NNS[i] * 2 coefficients. + copy_weights(model->softmax_bias_q2, nns, &bdata); + copy_weights(model->elliott_bias_q2, nns, &bdata); + } + } + } + + return 0; +} + +static float mean(const float *input, int size) +{ + float sum = 0.f; + + for (int i = 0; i < size; i++) + sum += input[i]; + + return sum / size; +} + +static void transform(float *input, int size, float mean, float half) +{ + for (int i = 0; i < size; i++) + input[i] = (input[i] - mean) / half; +} + +static void subtract_mean_old(PrescreenerCoefficients *coeffs, float half) +{ + for (int n = 0; n < 4; n++) { + float m = mean(coeffs->kernel_l0[n], 48); + + transform(coeffs->kernel_l0[n], 48, m, half); + } +} + +static void subtract_mean_new(PrescreenerCoefficients *coeffs, float half) +{ + for (int n = 0; n < 4; n++) { + float m = mean(coeffs->kernel_l0[n], 64); + + transform(coeffs->kernel_l0[n], 64, m, half); + } +} + +static void subtract_mean_predictor(PredictorCoefficients *model) +{ + const int filter_size = model->nsize; + const int nns = model->nns; + const float scale = 1.f / nns; + + double softmax_means[256]; // Average of individual softmax filters. + double elliott_means[256]; // Average of individual elliott filters. + double mean_filter[48 * 6] = { 0 }; // Pointwise average of all softmax filters. + double mean_bias; + + // Quality 1. + for (int nn = 0; nn < nns; nn++) { + softmax_means[nn] = mean(model->softmax_q1 + nn * filter_size, filter_size); + elliott_means[nn] = mean(model->elliott_q1 + nn * filter_size, filter_size); + + for (int k = 0; k < filter_size; k++) + mean_filter[k] += model->softmax_q1[nn * filter_size + k] - softmax_means[nn]; + } + + for (int k = 0; k < filter_size; k++) + mean_filter[k] *= scale; + + mean_bias = mean(model->softmax_bias_q1, nns); + + for (int nn = 0; nn < nns; nn++) { + for (int k = 0; k < filter_size; k++) { + model->softmax_q1[nn * filter_size + k] -= softmax_means[nn] + mean_filter[k]; + model->elliott_q1[nn * filter_size + k] -= elliott_means[nn]; + } + model->softmax_bias_q1[nn] -= mean_bias; + } + + // Quality 2. + memset(mean_filter, 0, sizeof(mean_filter)); + + for (int nn = 0; nn < nns; nn++) { + softmax_means[nn] = mean(model->softmax_q2 + nn * filter_size, filter_size); + elliott_means[nn] = mean(model->elliott_q2 + nn * filter_size, filter_size); + + for (int k = 0; k < filter_size; k++) { + mean_filter[k] += model->softmax_q2[nn * filter_size + k] - softmax_means[nn]; + } + } + + for (int k = 0; k < filter_size; k++) + mean_filter[k] *= scale; + + mean_bias = mean(model->softmax_bias_q2, nns); + + for (int nn = 0; nn < nns; nn++) { + for (int k = 0; k < filter_size; k++) { + model->softmax_q2[nn * filter_size + k] -= softmax_means[nn] + mean_filter[k]; + model->elliott_q2[nn * filter_size + k] -= elliott_means[nn]; + } + + model->softmax_bias_q2[nn] -= mean_bias; + } +} + static av_cold int init(AVFilterContext *ctx) { NNEDIContext *s = ctx->priv; FILE *weights_file = NULL; - int64_t expected_size = 13574928; int64_t weights_size; float *bdata; size_t bytes_read; - const int xdia_table[NUM_NSIZE] = { 8, 16, 32, 48, 8, 16, 32 }; - const int ydia_table[NUM_NSIZE] = { 6, 6, 6, 6, 4, 4, 4 }; - const int nns_table[NUM_NNS] = { 16, 32, 64, 128, 256 }; - const int dims0 = 49 * 4 + 5 * 4 + 9 * 4; - const int dims0new = 4 * 65 + 4 * 5; - const int dims1 = nns_table[s->nnsparam] * 2 * (xdia_table[s->nsize] * ydia_table[s->nsize] + 1); - int dims1tsize = 0; - int dims1offset = 0; - int ret = 0, i, j, k; + int ret = 0; - weights_file = fopen(s->weights_file, "rb"); + weights_file = av_fopen_utf8(s->weights_file, "rb"); if (!weights_file) { av_log(ctx, AV_LOG_ERROR, "No weights file provided, aborting!\n"); return AVERROR(EINVAL); @@ -940,7 +982,7 @@ static av_cold int init(AVFilterContext *ctx) fclose(weights_file); av_log(ctx, AV_LOG_ERROR, "Couldn't get size of weights file.\n"); return AVERROR(EINVAL); - } else if (weights_size != expected_size) { + } else if (weights_size != NNEDI_WEIGHTS_SIZE) { fclose(weights_file); av_log(ctx, AV_LOG_ERROR, "Unexpected weights file size.\n"); return AVERROR(EINVAL); @@ -952,15 +994,14 @@ static av_cold int init(AVFilterContext *ctx) return AVERROR(EINVAL); } - bdata = (float *)av_malloc(expected_size); + bdata = av_malloc(NNEDI_WEIGHTS_SIZE); if (!bdata) { fclose(weights_file); return AVERROR(ENOMEM); } - bytes_read = fread(bdata, 1, expected_size, weights_file); - - if (bytes_read != (size_t)expected_size) { + bytes_read = fread(bdata, 1, NNEDI_WEIGHTS_SIZE, weights_file); + if (bytes_read != NNEDI_WEIGHTS_SIZE) { fclose(weights_file); ret = AVERROR_INVALIDDATA; av_log(ctx, AV_LOG_ERROR, "Couldn't read weights file.\n"); @@ -969,212 +1010,132 @@ static av_cold int init(AVFilterContext *ctx) fclose(weights_file); - for (j = 0; j < NUM_NNS; j++) { - for (i = 0; i < NUM_NSIZE; i++) { - if (i == s->nsize && j == s->nnsparam) - dims1offset = dims1tsize; - dims1tsize += nns_table[j] * 2 * (xdia_table[i] * ydia_table[i] + 1) * 2; - } - } - - s->weights0 = av_malloc_array(FFMAX(dims0, dims0new), sizeof(float)); - if (!s->weights0) { + s->fdsp = avpriv_float_dsp_alloc(0); + if (!s->fdsp) { ret = AVERROR(ENOMEM); goto fail; } - for (i = 0; i < 2; i++) { - s->weights1[i] = av_malloc_array(dims1, sizeof(float)); - if (!s->weights1[i]) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - - // Adjust prescreener weights - if (s->pscrn >= 2) {// using new prescreener - const float *bdw; - int16_t *ws; - float *wf; - double mean[4] = { 0.0, 0.0, 0.0, 0.0 }; - int *offt = av_calloc(4 * 64, sizeof(int)); - - if (!offt) { - ret = AVERROR(ENOMEM); - goto fail; - } - - for (j = 0; j < 4; j++) - for (k = 0; k < 64; k++) - offt[j * 64 + k] = ((k >> 3) << 5) + ((j & 3) << 3) + (k & 7); - - bdw = bdata + dims0 + dims0new * (s->pscrn - 2); - ws = (int16_t *)s->weights0; - wf = (float *)&ws[4 * 64]; - // Calculate mean weight of each first layer neuron - for (j = 0; j < 4; j++) { - double cmean = 0.0; - for (k = 0; k < 64; k++) - cmean += bdw[offt[j * 64 + k]]; - mean[j] = cmean / 64.0; - } - // Factor mean removal and 1.0/127.5 scaling - // into first layer weights. scale to int16 range - for (j = 0; j < 4; j++) { - double scale, mval = 0.0; - - for (k = 0; k < 64; k++) - mval = FFMAX(mval, FFABS((bdw[offt[j * 64 + k]] - mean[j]) / 127.5)); - scale = 32767.0 / mval; - for (k = 0; k < 64; k++) - ws[offt[j * 64 + k]] = roundds(((bdw[offt[j * 64 + k]] - mean[j]) / 127.5) * scale); - wf[j] = (float)(mval / 32767.0); - } - memcpy(wf + 4, bdw + 4 * 64, (dims0new - 4 * 64) * sizeof(float)); - av_free(offt); - } else { // using old prescreener - double mean[4] = { 0.0, 0.0, 0.0, 0.0 }; - // Calculate mean weight of each first layer neuron - for (j = 0; j < 4; j++) { - double cmean = 0.0; - for (k = 0; k < 48; k++) - cmean += bdata[j * 48 + k]; - mean[j] = cmean / 48.0; - } - if (s->fapprox & 1) {// use int16 dot products in first layer - int16_t *ws = (int16_t *)s->weights0; - float *wf = (float *)&ws[4 * 48]; - // Factor mean removal and 1.0/127.5 scaling - // into first layer weights. scale to int16 range - for (j = 0; j < 4; j++) { - double scale, mval = 0.0; - for (k = 0; k < 48; k++) - mval = FFMAX(mval, FFABS((bdata[j * 48 + k] - mean[j]) / 127.5)); - scale = 32767.0 / mval; - for (k = 0; k < 48; k++) - ws[j * 48 + k] = roundds(((bdata[j * 48 + k] - mean[j]) / 127.5) * scale); - wf[j] = (float)(mval / 32767.0); - } - memcpy(wf + 4, bdata + 4 * 48, (dims0 - 4 * 48) * sizeof(float)); - } else {// use float dot products in first layer - double half = (1 << 8) - 1; - - half /= 2; - - // Factor mean removal and 1.0/half scaling - // into first layer weights. - for (j = 0; j < 4; j++) - for (k = 0; k < 48; k++) - s->weights0[j * 48 + k] = (float)((bdata[j * 48 + k] - mean[j]) / half); - memcpy(s->weights0 + 4 * 48, bdata + 4 * 48, (dims0 - 4 * 48) * sizeof(float)); - } - } - - // Adjust prediction weights - for (i = 0; i < 2; i++) { - const float *bdataT = bdata + dims0 + dims0new * 3 + dims1tsize * s->etype + dims1offset + i * dims1; - const int nnst = nns_table[s->nnsparam]; - const int asize = xdia_table[s->nsize] * ydia_table[s->nsize]; - const int boff = nnst * 2 * asize; - double *mean = (double *)av_calloc(asize + 1 + nnst * 2, sizeof(double)); - - if (!mean) { - ret = AVERROR(ENOMEM); - goto fail; - } - - // Calculate mean weight of each neuron (ignore bias) - for (j = 0; j < nnst * 2; j++) { - double cmean = 0.0; - for (k = 0; k < asize; k++) - cmean += bdataT[j * asize + k]; - mean[asize + 1 + j] = cmean / (double)asize; - } - // Calculate mean softmax neuron - for (j = 0; j < nnst; j++) { - for (k = 0; k < asize; k++) - mean[k] += bdataT[j * asize + k] - mean[asize + 1 + j]; - mean[asize] += bdataT[boff + j]; - } - for (j = 0; j < asize + 1; j++) - mean[j] /= (double)(nnst); - - if (s->fapprox & 2) { // use int16 dot products - int16_t *ws = (int16_t *)s->weights1[i]; - float *wf = (float *)&ws[nnst * 2 * asize]; - // Factor mean removal into weights, remove global offset from - // softmax neurons, and scale weights to int16 range. - for (j = 0; j < nnst; j++) { // softmax neurons - double scale, mval = 0.0; - for (k = 0; k < asize; k++) - mval = FFMAX(mval, FFABS(bdataT[j * asize + k] - mean[asize + 1 + j] - mean[k])); - scale = 32767.0 / mval; - for (k = 0; k < asize; k++) - ws[j * asize + k] = roundds((bdataT[j * asize + k] - mean[asize + 1 + j] - mean[k]) * scale); - wf[(j >> 2) * 8 + (j & 3)] = (float)(mval / 32767.0); - wf[(j >> 2) * 8 + (j & 3) + 4] = (float)(bdataT[boff + j] - mean[asize]); - } - for (j = nnst; j < nnst * 2; j++) { // elliott neurons - double scale, mval = 0.0; - for (k = 0; k < asize; k++) - mval = FFMAX(mval, FFABS(bdataT[j * asize + k] - mean[asize + 1 + j])); - scale = 32767.0 / mval; - for (k = 0; k < asize; k++) - ws[j * asize + k] = roundds((bdataT[j * asize + k] - mean[asize + 1 + j]) * scale); - wf[(j >> 2) * 8 + (j & 3)] = (float)(mval / 32767.0); - wf[(j >> 2) * 8 + (j & 3) + 4] = bdataT[boff + j]; - } - } else { // use float dot products - // Factor mean removal into weights, and remove global - // offset from softmax neurons. - for (j = 0; j < nnst * 2; j++) { - for (k = 0; k < asize; k++) { - const double q = j < nnst ? mean[k] : 0.0; - s->weights1[i][j * asize + k] = (float)(bdataT[j * asize + k] - mean[asize + 1 + j] - q); - } - s->weights1[i][boff + j] = (float)(bdataT[boff + j] - (j < nnst ? mean[asize] : 0.0)); - } - } - av_free(mean); - } - - s->nns = nns_table[s->nnsparam]; - s->xdia = xdia_table[s->nsize]; - s->ydia = ydia_table[s->nsize]; - s->asize = xdia_table[s->nsize] * ydia_table[s->nsize]; - - s->max_value = 65535 >> 8; - - select_functions(s); - - s->fdsp = avpriv_float_dsp_alloc(0); - if (!s->fdsp) - ret = AVERROR(ENOMEM); + ret = read_weights(ctx, bdata); + if (ret < 0) + goto fail; fail: av_free(bdata); return ret; } +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + NNEDIContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int ret; + + s->depth = desc->comp[0].depth; + s->nb_threads = ff_filter_get_nb_threads(ctx); + s->nb_planes = av_pix_fmt_count_planes(inlink->format); + if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) + return ret; + + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + + s->half = ((1 << 8) - 1) / 2.f; + s->out_scale = 1 << (s->depth - 8); + s->in_scale = 1.f / s->out_scale; + + switch (s->depth) { + case 8: + s->read = read_bytes; + s->write = write_bytes; + break; + default: + s->read = read_words; + s->write = write_words; + break; + } + + subtract_mean_old(&s->prescreener[0], s->half); + subtract_mean_new(&s->prescreener[1], s->half); + subtract_mean_new(&s->prescreener[2], s->half); + subtract_mean_new(&s->prescreener[3], s->half); + + s->prescreen[0] = process_old; + s->prescreen[1] = process_new; + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 5; j++) { + for (int k = 0; k < 7; k++) + subtract_mean_predictor(&s->coeffs[i][j][k]); + } + } + + s->input_size = (s->planewidth[0] + 64) * (s->planeheight[0] + 6); + s->input_buf = av_calloc(s->nb_threads, sizeof(*s->input_buf)); + if (!s->input_buf) + return AVERROR(ENOMEM); + + for (int i = 0; i < s->nb_threads; i++) { + s->input_buf[i] = av_calloc(s->input_size, sizeof(**s->input_buf)); + if (!s->input_buf[i]) + return AVERROR(ENOMEM); + } + + s->output_buf = av_calloc(s->nb_threads, sizeof(*s->output_buf)); + if (!s->output_buf) + return AVERROR(ENOMEM); + + for (int i = 0; i < s->nb_threads; i++) { + s->output_buf[i] = av_calloc(s->input_size, sizeof(**s->output_buf)); + if (!s->output_buf[i]) + return AVERROR(ENOMEM); + } + + s->prescreen_buf = av_calloc(s->nb_threads, sizeof(*s->prescreen_buf)); + if (!s->prescreen_buf) + return AVERROR(ENOMEM); + + for (int i = 0; i < s->nb_threads; i++) { + s->prescreen_buf[i] = av_calloc(s->planewidth[0], sizeof(**s->prescreen_buf)); + if (!s->prescreen_buf[i]) + return AVERROR(ENOMEM); + } + + return 0; +} + static av_cold void uninit(AVFilterContext *ctx) { NNEDIContext *s = ctx->priv; - int i; - av_freep(&s->weights0); + for (int i = 0; i < s->nb_threads && s->prescreen_buf; i++) + av_freep(&s->prescreen_buf[i]); - for (i = 0; i < 2; i++) - av_freep(&s->weights1[i]); + av_freep(&s->prescreen_buf); - for (i = 0; i < s->nb_planes; i++) { - av_freep(&s->frame_data.paddedp[i]); - av_freep(&s->frame_data.lcount[i]); + for (int i = 0; i < s->nb_threads && s->input_buf; i++) + av_freep(&s->input_buf[i]); + + av_freep(&s->input_buf); + + for (int i = 0; i < s->nb_threads && s->output_buf; i++) + av_freep(&s->output_buf[i]); + + av_freep(&s->output_buf); + av_freep(&s->fdsp); + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 5; j++) { + for (int k = 0; k < 7; k++) { + av_freep(&s->coeffs[i][j][k].data); + } + } } - av_freep(&s->frame_data.input); - av_freep(&s->frame_data.temp); - av_freep(&s->fdsp); - av_frame_free(&s->second); + av_frame_free(&s->prev); } static const AVFilterPad inputs[] = { @@ -1207,5 +1168,6 @@ AVFilter ff_vf_nnedi = { .query_formats = query_formats, .inputs = inputs, .outputs = outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, }; diff --git a/libavfilter/vf_normalize.c b/libavfilter/vf_normalize.c index e2e00b123..9675c8ac2 100644 --- a/libavfilter/vf_normalize.c +++ b/libavfilter/vf_normalize.c @@ -448,8 +448,8 @@ static int config_input(AVFilterLink *inlink) for (c = 0; c < 3; c++) { s->min[c].history = s->history_mem + (c*2) * s->history_len; s->max[c].history = s->history_mem + (c*2+1) * s->history_len; - s->sblackpt[c] = scale * s->blackpt[c] + (s->blackpt[c] >> (s->depth - 8)); - s->swhitept[c] = scale * s->whitept[c] + (s->whitept[c] >> (s->depth - 8)); + s->sblackpt[c] = scale * s->blackpt[c] + (s->blackpt[c] & (1 << (s->depth - 8))); + s->swhitept[c] = scale * s->whitept[c] + (s->whitept[c] & (1 << (s->depth - 8))); } planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR; diff --git a/libavfilter/vf_ocr.c b/libavfilter/vf_ocr.c index d5f76059b..c7ccb4a84 100644 --- a/libavfilter/vf_ocr.c +++ b/libavfilter/vf_ocr.c @@ -43,7 +43,7 @@ typedef struct OCRContext { static const AVOption ocr_options[] = { { "datapath", "set datapath", OFFSET(datapath), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, { "language", "set language", OFFSET(language), AV_OPT_TYPE_STRING, {.str="eng"}, 0, 0, FLAGS }, - { "whitelist", "set character whitelist", OFFSET(whitelist), AV_OPT_TYPE_STRING, {.str="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:;,-+_!?\"'[]{}()<>|/\\=*&%$#@!~"}, 0, 0, FLAGS }, + { "whitelist", "set character whitelist", OFFSET(whitelist), AV_OPT_TYPE_STRING, {.str="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:;,-+_!?\"'[]{}()<>|/\\=*&%$#@!~ "}, 0, 0, FLAGS }, { "blacklist", "set character blacklist", OFFSET(blacklist), AV_OPT_TYPE_STRING, {.str=""}, 0, 0, FLAGS }, { NULL } }; diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index b5ab5fba5..bda5970b8 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -154,6 +154,7 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar static const enum AVPixelFormat alpha_pix_fmts[] = { AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE }; @@ -172,6 +173,14 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE }; + static const enum AVPixelFormat main_pix_fmts_yuv420p10[] = { + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUVA420P10, + AV_PIX_FMT_NONE + }; + static const enum AVPixelFormat overlay_pix_fmts_yuv420p10[] = { + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_NONE + }; + static const enum AVPixelFormat main_pix_fmts_yuv422[] = { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_NONE }; @@ -179,6 +188,13 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA422P, AV_PIX_FMT_NONE }; + static const enum AVPixelFormat main_pix_fmts_yuv422p10[] = { + AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_NONE + }; + static const enum AVPixelFormat overlay_pix_fmts_yuv422p10[] = { + AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_NONE + }; + static const enum AVPixelFormat main_pix_fmts_yuv444[] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE }; @@ -205,76 +221,52 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_NONE }; - AVFilterFormats *main_formats = NULL; - AVFilterFormats *overlay_formats = NULL; + const enum AVPixelFormat *main_formats, *overlay_formats; + AVFilterFormats *formats; int ret; switch (s->format) { case OVERLAY_FORMAT_YUV420: - if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv420)) || - !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv420))) { - ret = AVERROR(ENOMEM); - goto fail; - } + main_formats = main_pix_fmts_yuv420; + overlay_formats = overlay_pix_fmts_yuv420; + break; + case OVERLAY_FORMAT_YUV420P10: + main_formats = main_pix_fmts_yuv420p10; + overlay_formats = overlay_pix_fmts_yuv420p10; break; case OVERLAY_FORMAT_YUV422: - if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv422)) || - !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv422))) { - ret = AVERROR(ENOMEM); - goto fail; - } + main_formats = main_pix_fmts_yuv422; + overlay_formats = overlay_pix_fmts_yuv422; + break; + case OVERLAY_FORMAT_YUV422P10: + main_formats = main_pix_fmts_yuv422p10; + overlay_formats = overlay_pix_fmts_yuv422p10; break; case OVERLAY_FORMAT_YUV444: - if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv444)) || - !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv444))) { - ret = AVERROR(ENOMEM); - goto fail; - } + main_formats = main_pix_fmts_yuv444; + overlay_formats = overlay_pix_fmts_yuv444; break; case OVERLAY_FORMAT_RGB: - if (!(main_formats = ff_make_format_list(main_pix_fmts_rgb)) || - !(overlay_formats = ff_make_format_list(overlay_pix_fmts_rgb))) { - ret = AVERROR(ENOMEM); - goto fail; - } + main_formats = main_pix_fmts_rgb; + overlay_formats = overlay_pix_fmts_rgb; break; case OVERLAY_FORMAT_GBRP: - if (!(main_formats = ff_make_format_list(main_pix_fmts_gbrp)) || - !(overlay_formats = ff_make_format_list(overlay_pix_fmts_gbrp))) { - ret = AVERROR(ENOMEM); - goto fail; - } + main_formats = main_pix_fmts_gbrp; + overlay_formats = overlay_pix_fmts_gbrp; break; case OVERLAY_FORMAT_AUTO: - if (!(main_formats = ff_make_format_list(alpha_pix_fmts))) { - ret = AVERROR(ENOMEM); - goto fail; - } - break; + return ff_set_common_formats(ctx, ff_make_format_list(alpha_pix_fmts)); default: av_assert0(0); } - if (s->format == OVERLAY_FORMAT_AUTO) { - ret = ff_set_common_formats(ctx, main_formats); - if (ret < 0) - goto fail; - } else { - if ((ret = ff_formats_ref(main_formats , &ctx->inputs[MAIN]->out_formats )) < 0 || - (ret = ff_formats_ref(overlay_formats, &ctx->inputs[OVERLAY]->out_formats)) < 0 || - (ret = ff_formats_ref(main_formats , &ctx->outputs[MAIN]->in_formats )) < 0) - goto fail; - } + formats = ff_make_format_list(main_formats); + if ((ret = ff_formats_ref(formats, &ctx->inputs[MAIN]->outcfg.formats)) < 0 || + (ret = ff_formats_ref(formats, &ctx->outputs[MAIN]->incfg.formats)) < 0) + return ret; - return 0; -fail: - if (main_formats) - av_freep(&main_formats->formats); - av_freep(&main_formats); - if (overlay_formats) - av_freep(&overlay_formats->formats); - av_freep(&overlay_formats); - return ret; + return ff_formats_ref(ff_make_format_list(overlay_formats), + &ctx->inputs[OVERLAY]->outcfg.formats); } static int config_input_overlay(AVFilterLink *inlink) @@ -441,190 +433,216 @@ static av_always_inline void blend_slice_packed_rgb(AVFilterContext *ctx, } } -static av_always_inline void blend_plane(AVFilterContext *ctx, - AVFrame *dst, const AVFrame *src, - int src_w, int src_h, - int dst_w, int dst_h, - int i, int hsub, int vsub, - int x, int y, - int main_has_alpha, - int dst_plane, - int dst_offset, - int dst_step, - int straight, - int yuv, - int jobnr, - int nb_jobs) -{ - OverlayContext *octx = ctx->priv; - int src_wp = AV_CEIL_RSHIFT(src_w, hsub); - int src_hp = AV_CEIL_RSHIFT(src_h, vsub); - int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub); - int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); - int yp = y>>vsub; - int xp = x>>hsub; - uint8_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; - int jmax, j, k, kmax; - int slice_start, slice_end; - - j = FFMAX(-yp, 0); - jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); - - slice_start = j + (jmax * jobnr) / nb_jobs; - slice_end = j + (jmax * (jobnr+1)) / nb_jobs; - - sp = src->data[i] + (slice_start) * src->linesize[i]; - dp = dst->data[dst_plane] - + (yp + slice_start) * dst->linesize[dst_plane] - + dst_offset; - ap = src->data[3] + (slice_start << vsub) * src->linesize[3]; - dap = dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]; - - for (j = slice_start; j < slice_end; j++) { - k = FFMAX(-xp, 0); - d = dp + (xp+k) * dst_step; - s = sp + k; - a = ap + (k<blend_row[i]) { - int c = octx->blend_row[i](d, da, s, a, kmax - k, src->linesize[3]); - - s += c; - d += dst_step * c; - da += (1 << hsub) * c; - a += (1 << hsub) * c; - k += c; - } - for (; k < kmax; k++) { - int alpha_v, alpha_h, alpha; - - // average alpha for color components, improve quality - if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { - alpha = (a[0] + a[src->linesize[3]] + - a[1] + a[src->linesize[3]+1]) >> 2; - } else if (hsub || vsub) { - alpha_h = hsub && k+1 < src_wp ? - (a[0] + a[1]) >> 1 : a[0]; - alpha_v = vsub && j+1 < src_hp ? - (a[0] + a[src->linesize[3]]) >> 1 : a[0]; - alpha = (alpha_v + alpha_h) >> 1; - } else - alpha = a[0]; - // if the main channel has an alpha channel, alpha has to be calculated - // to create an un-premultiplied (straight) alpha value - if (main_has_alpha && alpha != 0 && alpha != 255) { - // average alpha for color components, improve quality - uint8_t alpha_d; - if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { - alpha_d = (da[0] + da[dst->linesize[3]] + - da[1] + da[dst->linesize[3]+1]) >> 2; - } else if (hsub || vsub) { - alpha_h = hsub && k+1 < src_wp ? - (da[0] + da[1]) >> 1 : da[0]; - alpha_v = vsub && j+1 < src_hp ? - (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; - alpha_d = (alpha_v + alpha_h) >> 1; - } else - alpha_d = da[0]; - alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); - } - if (straight) { - *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); - } else { - if (i && yuv) - *d = av_clip(FAST_DIV255((*d - 128) * (255 - alpha)) + *s - 128, -128, 128) + 128; - else - *d = FFMIN(FAST_DIV255(*d * (255 - alpha)) + *s, 255); - } - s++; - d += dst_step; - da += 1 << hsub; - a += 1 << hsub; - } - dp += dst->linesize[dst_plane]; - sp += src->linesize[i]; - ap += (1 << vsub) * src->linesize[3]; - dap += (1 << vsub) * dst->linesize[3]; - } +#define DEFINE_BLEND_PLANE(depth, nbits) \ +static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext *ctx, \ + AVFrame *dst, const AVFrame *src, \ + int src_w, int src_h, \ + int dst_w, int dst_h, \ + int i, int hsub, int vsub, \ + int x, int y, \ + int main_has_alpha, \ + int dst_plane, \ + int dst_offset, \ + int dst_step, \ + int straight, \ + int yuv, \ + int jobnr, \ + int nb_jobs) \ +{ \ + OverlayContext *octx = ctx->priv; \ + int src_wp = AV_CEIL_RSHIFT(src_w, hsub); \ + int src_hp = AV_CEIL_RSHIFT(src_h, vsub); \ + int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub); \ + int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); \ + int yp = y>>vsub; \ + int xp = x>>hsub; \ + uint##depth##_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; \ + int jmax, j, k, kmax; \ + int slice_start, slice_end; \ + const uint##depth##_t max = (1 << nbits) - 1; \ + const uint##depth##_t mid = (1 << (nbits -1)) ; \ + int bytes = depth / 8; \ + \ + dst_step /= bytes; \ + j = FFMAX(-yp, 0); \ + jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); \ + \ + slice_start = j + (jmax * jobnr) / nb_jobs; \ + slice_end = j + (jmax * (jobnr+1)) / nb_jobs; \ + \ + sp = (uint##depth##_t *)(src->data[i] + (slice_start) * src->linesize[i]); \ + dp = (uint##depth##_t *)(dst->data[dst_plane] \ + + (yp + slice_start) * dst->linesize[dst_plane] \ + + dst_offset); \ + ap = (uint##depth##_t *)(src->data[3] + (slice_start << vsub) * src->linesize[3]); \ + dap = (uint##depth##_t *)(dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]); \ + \ + for (j = slice_start; j < slice_end; j++) { \ + k = FFMAX(-xp, 0); \ + d = dp + (xp+k) * dst_step; \ + s = sp + k; \ + a = ap + (k<blend_row[i]) { \ + int c = octx->blend_row[i]((uint8_t*)d, (uint8_t*)da, (uint8_t*)s, \ + (uint8_t*)a, kmax - k, src->linesize[3]); \ + \ + s += c; \ + d += dst_step * c; \ + da += (1 << hsub) * c; \ + a += (1 << hsub) * c; \ + k += c; \ + } \ + for (; k < kmax; k++) { \ + int alpha_v, alpha_h, alpha; \ + \ + /* average alpha for color components, improve quality */ \ + if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \ + alpha = (a[0] + a[src->linesize[3]] + \ + a[1] + a[src->linesize[3]+1]) >> 2; \ + } else if (hsub || vsub) { \ + alpha_h = hsub && k+1 < src_wp ? \ + (a[0] + a[1]) >> 1 : a[0]; \ + alpha_v = vsub && j+1 < src_hp ? \ + (a[0] + a[src->linesize[3]]) >> 1 : a[0]; \ + alpha = (alpha_v + alpha_h) >> 1; \ + } else \ + alpha = a[0]; \ + /* if the main channel has an alpha channel, alpha has to be calculated */ \ + /* to create an un-premultiplied (straight) alpha value */ \ + if (main_has_alpha && alpha != 0 && alpha != max) { \ + /* average alpha for color components, improve quality */ \ + uint8_t alpha_d; \ + if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \ + alpha_d = (da[0] + da[dst->linesize[3]] + \ + da[1] + da[dst->linesize[3]+1]) >> 2; \ + } else if (hsub || vsub) { \ + alpha_h = hsub && k+1 < src_wp ? \ + (da[0] + da[1]) >> 1 : da[0]; \ + alpha_v = vsub && j+1 < src_hp ? \ + (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; \ + alpha_d = (alpha_v + alpha_h) >> 1; \ + } else \ + alpha_d = da[0]; \ + alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \ + } \ + if (straight) { \ + if (nbits > 8) \ + *d = (*d * (max - alpha) + *s * alpha) / max; \ + else \ + *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); \ + } else { \ + if (nbits > 8) { \ + if (i && yuv) \ + *d = av_clip((*d * (max - alpha) + *s * alpha) / max + *s - mid, -mid, mid) + mid; \ + else \ + *d = FFMIN((*d * (max - alpha) + *s * alpha) / max + *s, max); \ + } else { \ + if (i && yuv) \ + *d = av_clip(FAST_DIV255((*d - mid) * (max - alpha)) + *s - mid, -mid, mid) + mid; \ + else \ + *d = FFMIN(FAST_DIV255(*d * (max - alpha)) + *s, max); \ + } \ + } \ + s++; \ + d += dst_step; \ + da += 1 << hsub; \ + a += 1 << hsub; \ + } \ + dp += dst->linesize[dst_plane] / bytes; \ + sp += src->linesize[i] / bytes; \ + ap += (1 << vsub) * src->linesize[3] / bytes; \ + dap += (1 << vsub) * dst->linesize[3] / bytes; \ + } \ } +DEFINE_BLEND_PLANE(8, 8) +DEFINE_BLEND_PLANE(16, 10) -static inline void alpha_composite(const AVFrame *src, const AVFrame *dst, - int src_w, int src_h, - int dst_w, int dst_h, - int x, int y, - int jobnr, int nb_jobs) -{ - uint8_t alpha; ///< the amount of overlay to blend on to main - uint8_t *s, *sa, *d, *da; - int i, imax, j, jmax; - int slice_start, slice_end; - - imax = FFMIN(-y + dst_h, src_h); - slice_start = (imax * jobnr) / nb_jobs; - slice_end = ((imax * (jobnr+1)) / nb_jobs); - - i = FFMAX(-y, 0); - sa = src->data[3] + (i + slice_start) * src->linesize[3]; - da = dst->data[3] + (y + i + slice_start) * dst->linesize[3]; - - for (i = i + slice_start; i < slice_end; i++) { - j = FFMAX(-x, 0); - s = sa + j; - d = da + x+j; - - for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { - alpha = *s; - if (alpha != 0 && alpha != 255) { - uint8_t alpha_d = *d; - alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); - } - switch (alpha) { - case 0: - break; - case 255: - *d = *s; - break; - default: - // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha - *d += FAST_DIV255((255 - *d) * *s); - } - d += 1; - s += 1; - } - da += dst->linesize[3]; - sa += src->linesize[3]; - } +#define DEFINE_ALPHA_COMPOSITE(depth, nbits) \ +static inline void alpha_composite_##depth##_##nbits##bits(const AVFrame *src, const AVFrame *dst, \ + int src_w, int src_h, \ + int dst_w, int dst_h, \ + int x, int y, \ + int jobnr, int nb_jobs) \ +{ \ + uint##depth##_t alpha; /* the amount of overlay to blend on to main */ \ + uint##depth##_t *s, *sa, *d, *da; \ + int i, imax, j, jmax; \ + int slice_start, slice_end; \ + const uint##depth##_t max = (1 << nbits) - 1; \ + int bytes = depth / 8; \ + \ + imax = FFMIN(-y + dst_h, src_h); \ + slice_start = (imax * jobnr) / nb_jobs; \ + slice_end = ((imax * (jobnr+1)) / nb_jobs); \ + \ + i = FFMAX(-y, 0); \ + sa = (uint##depth##_t *)(src->data[3] + (i + slice_start) * src->linesize[3]); \ + da = (uint##depth##_t *)(dst->data[3] + (y + i + slice_start) * dst->linesize[3]); \ + \ + for (i = i + slice_start; i < slice_end; i++) { \ + j = FFMAX(-x, 0); \ + s = sa + j; \ + d = da + x+j; \ + \ + for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { \ + alpha = *s; \ + if (alpha != 0 && alpha != max) { \ + uint8_t alpha_d = *d; \ + alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \ + } \ + if (alpha == max) \ + *d = *s; \ + else if (alpha > 0) { \ + /* apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha */ \ + if (nbits > 8) \ + *d += (max - *d) * *s / max; \ + else \ + *d += FAST_DIV255((max - *d) * *s); \ + } \ + d += 1; \ + s += 1; \ + } \ + da += dst->linesize[3] / bytes; \ + sa += src->linesize[3] / bytes; \ + } \ } +DEFINE_ALPHA_COMPOSITE(8, 8) +DEFINE_ALPHA_COMPOSITE(16, 10) -static av_always_inline void blend_slice_yuv(AVFilterContext *ctx, - AVFrame *dst, const AVFrame *src, - int hsub, int vsub, - int main_has_alpha, - int x, int y, - int is_straight, - int jobnr, int nb_jobs) -{ - OverlayContext *s = ctx->priv; - const int src_w = src->width; - const int src_h = src->height; - const int dst_w = dst->width; - const int dst_h = dst->height; - - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, - s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 1, - jobnr, nb_jobs); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, - s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 1, - jobnr, nb_jobs); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, - s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 1, - jobnr, nb_jobs); - - if (main_has_alpha) - alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs); +#define DEFINE_BLEND_SLICE_YUV(depth, nbits) \ +static av_always_inline void blend_slice_yuv_##depth##_##nbits##bits(AVFilterContext *ctx, \ + AVFrame *dst, const AVFrame *src, \ + int hsub, int vsub, \ + int main_has_alpha, \ + int x, int y, \ + int is_straight, \ + int jobnr, int nb_jobs) \ +{ \ + OverlayContext *s = ctx->priv; \ + const int src_w = src->width; \ + const int src_h = src->height; \ + const int dst_w = dst->width; \ + const int dst_h = dst->height; \ + \ + blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, \ + x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, \ + s->main_desc->comp[0].step, is_straight, 1, jobnr, nb_jobs); \ + blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, \ + x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, \ + s->main_desc->comp[1].step, is_straight, 1, jobnr, nb_jobs); \ + blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, \ + x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, \ + s->main_desc->comp[2].step, is_straight, 1, jobnr, nb_jobs); \ + \ + if (main_has_alpha) \ + alpha_composite_##depth##_##nbits##bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, \ + jobnr, nb_jobs); \ } +DEFINE_BLEND_SLICE_YUV(8, 8) +DEFINE_BLEND_SLICE_YUV(16, 10) static av_always_inline void blend_slice_planar_rgb(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, @@ -641,25 +659,25 @@ static av_always_inline void blend_slice_planar_rgb(AVFilterContext *ctx, const int dst_w = dst->width; const int dst_h = dst->height; - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, + blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 0, jobnr, nb_jobs); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, + blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 0, jobnr, nb_jobs); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, + blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 0, jobnr, nb_jobs); if (main_has_alpha) - alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs); + alpha_composite_8_8bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs); } static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -667,7 +685,39 @@ static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int n { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlayContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlayContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlayContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlayContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -675,7 +725,7 @@ static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -683,7 +733,7 @@ static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int n { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -691,7 +741,7 @@ static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -699,7 +749,7 @@ static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int n { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -723,7 +773,7 @@ static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -731,7 +781,7 @@ static int blend_slice_yuva420_pm(AVFilterContext *ctx, void *arg, int jobnr, in { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -739,7 +789,7 @@ static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -747,7 +797,7 @@ static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, in { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -755,7 +805,7 @@ static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -763,7 +813,7 @@ static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, in { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -834,9 +884,15 @@ static int config_input_main(AVFilterLink *inlink) case OVERLAY_FORMAT_YUV420: s->blend_slice = s->main_has_alpha ? blend_slice_yuva420 : blend_slice_yuv420; break; + case OVERLAY_FORMAT_YUV420P10: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva420p10 : blend_slice_yuv420p10; + break; case OVERLAY_FORMAT_YUV422: s->blend_slice = s->main_has_alpha ? blend_slice_yuva422 : blend_slice_yuv422; break; + case OVERLAY_FORMAT_YUV422P10: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva422p10 : blend_slice_yuv422p10; + break; case OVERLAY_FORMAT_YUV444: s->blend_slice = s->main_has_alpha ? blend_slice_yuva444 : blend_slice_yuv444; break; @@ -851,9 +907,15 @@ static int config_input_main(AVFilterLink *inlink) case AV_PIX_FMT_YUVA420P: s->blend_slice = blend_slice_yuva420; break; + case AV_PIX_FMT_YUVA420P10: + s->blend_slice = blend_slice_yuva420p10; + break; case AV_PIX_FMT_YUVA422P: s->blend_slice = blend_slice_yuva422; break; + case AV_PIX_FMT_YUVA422P10: + s->blend_slice = blend_slice_yuva422p10; + break; case AV_PIX_FMT_YUVA444P: s->blend_slice = blend_slice_yuva444; break; @@ -1005,7 +1067,9 @@ static const AVOption overlay_options[] = { { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" }, { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" }, + { "yuv420p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420P10}, .flags = FLAGS, .unit = "format" }, { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" }, + { "yuv422p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422P10}, .flags = FLAGS, .unit = "format" }, { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" }, { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" }, { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" }, diff --git a/libavfilter/vf_overlay.h b/libavfilter/vf_overlay.h index 98b06eaac..30a1a7371 100644 --- a/libavfilter/vf_overlay.h +++ b/libavfilter/vf_overlay.h @@ -41,7 +41,9 @@ enum var_name { enum OverlayFormat { OVERLAY_FORMAT_YUV420, + OVERLAY_FORMAT_YUV420P10, OVERLAY_FORMAT_YUV422, + OVERLAY_FORMAT_YUV422P10, OVERLAY_FORMAT_YUV444, OVERLAY_FORMAT_RGB, OVERLAY_FORMAT_GBRP, diff --git a/libavfilter/vf_overlay_cuda.c b/libavfilter/vf_overlay_cuda.c index 2f0f860e5..f6ee43e92 100644 --- a/libavfilter/vf_overlay_cuda.c +++ b/libavfilter/vf_overlay_cuda.c @@ -157,9 +157,12 @@ static int overlay_cuda_blend(FFFrameSync *fs) if (ret < 0) return ret; - if (!input_main || !input_overlay) + if (!input_main) return AVERROR_BUG; + if (!input_overlay) + return ff_filter_frame(outlink, input_main); + ret = av_frame_make_writable(input_main); if (ret < 0) { av_frame_free(&input_main); diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c index 2a4dc5cb5..dd6c30f2a 100644 --- a/libavfilter/vf_overlay_qsv.c +++ b/libavfilter/vf_overlay_qsv.c @@ -381,12 +381,12 @@ static int overlay_qsv_query_formats(AVFilterContext *ctx) }; for (i = 0; i < ctx->nb_inputs; i++) { - ret = ff_formats_ref(ff_make_format_list(main_in_fmts), &ctx->inputs[i]->out_formats); + ret = ff_formats_ref(ff_make_format_list(main_in_fmts), &ctx->inputs[i]->outcfg.formats); if (ret < 0) return ret; } - ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats); + ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats); if (ret < 0) return ret; @@ -398,13 +398,11 @@ static const AVFilterPad overlay_qsv_inputs[] = { .name = "main", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_main_input, - .needs_fifo = 1, }, { .name = "overlay", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_overlay_input, - .needs_fifo = 1, }, { NULL } }; diff --git a/libavfilter/vf_owdenoise.c b/libavfilter/vf_owdenoise.c index 6d6c2a3d5..7dfe10f2f 100644 --- a/libavfilter/vf_owdenoise.c +++ b/libavfilter/vf_owdenoise.c @@ -30,6 +30,7 @@ #include "libavutil/imgutils.h" #include "libavutil/opt.h" +#include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "avfilter.h" #include "internal.h" diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 9b0a0e1b8..c49a6f116 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -99,9 +99,9 @@ static int query_formats(AVFilterContext *ctx) static const enum AVPixelFormat out_fmts[] = {AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE}; int ret; - if ((ret = ff_formats_ref(ff_make_format_list(in_fmts) , &ctx->inputs[0]->out_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(in_fmts) , &ctx->inputs[0]->outcfg.formats)) < 0) return ret; - if ((ret = ff_formats_ref(ff_make_format_list(out_fmts), &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(out_fmts), &ctx->outputs[0]->incfg.formats)) < 0) return ret; return 0; } diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index b32ff817d..f4c7d6043 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -142,25 +142,20 @@ static int query_formats(AVFilterContext *ctx) static const enum AVPixelFormat inpal_fmts[] = {AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE}; static const enum AVPixelFormat out_fmts[] = {AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE}; int ret; - AVFilterFormats *in = ff_make_format_list(in_fmts); - AVFilterFormats *inpal = ff_make_format_list(inpal_fmts); - AVFilterFormats *out = ff_make_format_list(out_fmts); - if (!in || !inpal || !out) { - av_freep(&in); - av_freep(&inpal); - av_freep(&out); - return AVERROR(ENOMEM); - } - if ((ret = ff_formats_ref(in , &ctx->inputs[0]->out_formats)) < 0 || - (ret = ff_formats_ref(inpal, &ctx->inputs[1]->out_formats)) < 0 || - (ret = ff_formats_ref(out , &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(in_fmts), + &ctx->inputs[0]->outcfg.formats)) < 0 || + (ret = ff_formats_ref(ff_make_format_list(inpal_fmts), + &ctx->inputs[1]->outcfg.formats)) < 0 || + (ret = ff_formats_ref(ff_make_format_list(out_fmts), + &ctx->outputs[0]->incfg.formats)) < 0) return ret; return 0; } -static av_always_inline int dither_color(uint32_t px, int er, int eg, int eb, int scale, int shift) +static av_always_inline uint32_t dither_color(uint32_t px, int er, int eg, + int eb, int scale, int shift) { - return av_clip_uint8( px >> 24 ) << 24 + return px >> 24 << 24 | av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<> 8 & 0xff) + ((eg * scale) / (1<w, 8); const int aligned_h = FFALIGN(outlink->h, 8); AVFrame *outbuf; - int qstride, qp_type; - int8_t *qp_table ; + int qstride = 0; + int8_t *qp_table = NULL; + int ret; outbuf = ff_get_video_buffer(outlink, aligned_w, aligned_h); if (!outbuf) { @@ -137,7 +140,13 @@ static int pp_filter_frame(AVFilterLink *inlink, AVFrame *inbuf) av_frame_copy_props(outbuf, inbuf); outbuf->width = inbuf->width; outbuf->height = inbuf->height; - qp_table = av_frame_get_qp_table(inbuf, &qstride, &qp_type); + + ret = ff_qp_table_extract(inbuf, &qp_table, &qstride, NULL, NULL); + if (ret < 0) { + av_frame_free(&inbuf); + av_frame_free(&outbuf); + return ret; + } pp_postprocess((const uint8_t **)inbuf->data, inbuf->linesize, outbuf->data, outbuf->linesize, @@ -146,9 +155,10 @@ static int pp_filter_frame(AVFilterLink *inlink, AVFrame *inbuf) qstride, pp->modes[pp->mode_id], pp->pp_ctx, - outbuf->pict_type | (qp_type ? PP_PICT_TYPE_QP2 : 0)); + outbuf->pict_type | (qp_table ? PP_PICT_TYPE_QP2 : 0)); av_frame_free(&inbuf); + av_freep(&qp_table); return ff_filter_frame(outlink, outbuf); } diff --git a/libavfilter/vf_pp7.c b/libavfilter/vf_pp7.c index 570a1c90b..ade7feb0b 100644 --- a/libavfilter/vf_pp7.c +++ b/libavfilter/vf_pp7.c @@ -29,9 +29,11 @@ #include "libavutil/avassert.h" #include "libavutil/imgutils.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "internal.h" +#include "qp_table.h" #include "vf_pp7.h" enum mode { @@ -322,10 +324,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFrame *out = in; int qp_stride = 0; - uint8_t *qp_table = NULL; + int8_t *qp_table = NULL; - if (!pp7->qp) - qp_table = av_frame_get_qp_table(in, &qp_stride, &pp7->qscale_type); + if (!pp7->qp) { + int ret = ff_qp_table_extract(in, &qp_table, &qp_stride, NULL, &pp7->qscale_type); + if (ret < 0) { + av_frame_free(&in); + return ret; + } + } if (!ctx->is_disabled) { const int cw = AV_CEIL_RSHIFT(inlink->w, pp7->hsub); @@ -340,6 +347,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) out = ff_get_video_buffer(outlink, aligned_w, aligned_h); if (!out) { av_frame_free(&in); + av_freep(&qp_table); return AVERROR(ENOMEM); } av_frame_copy_props(out, in); @@ -366,6 +374,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) inlink->w, inlink->h); av_frame_free(&in); } + av_freep(&qp_table); return ff_filter_frame(outlink, out); } diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c index 1fef4777d..e051cadac 100644 --- a/libavfilter/vf_premultiply.c +++ b/libavfilter/vf_premultiply.c @@ -73,7 +73,7 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, - AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; @@ -82,7 +82,7 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRAP, - AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_GBRAPF32, AV_PIX_FMT_NONE }; @@ -218,6 +218,54 @@ static void premultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc, } } +static void premultiplyf32(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int shift, int offset) +{ + const float *msrc = (const float *)mmsrc; + const float *asrc = (const float *)aasrc; + float *dst = (float *)ddst; + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + dst[x] = msrc[x] * asrc[x]; + } + + dst += dlinesize / 4; + msrc += mlinesize / 4; + asrc += alinesize / 4; + } +} + +static void premultiplyf32offset(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int shift, int offset) +{ + const float *msrc = (const float *)mmsrc; + const float *asrc = (const float *)aasrc; + float *dst = (float *)ddst; + int x, y; + + float offsetf = offset / 65535.0f; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + dst[x] = ((msrc[x] - offsetf) * asrc[x]) + offsetf; + } + + dst += dlinesize / 4; + msrc += mlinesize / 4; + asrc += alinesize / 4; + } +} + static void unpremultiply8(const uint8_t *msrc, const uint8_t *asrc, uint8_t *dst, ptrdiff_t mlinesize, ptrdiff_t alinesize, @@ -365,6 +413,62 @@ static void unpremultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc, } } +static void unpremultiplyf32(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + const float *msrc = (const float *)mmsrc; + const float *asrc = (const float *)aasrc; + + float *dst = (float *)ddst; + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0.0f) + dst[x] = msrc[x] / asrc[x]; + else + dst[x] = msrc[x]; + } + + dst += dlinesize / 4; + msrc += mlinesize / 4; + asrc += alinesize / 4; + } +} + +static void unpremultiplyf32offset(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + const float *msrc = (const float *)mmsrc; + const float *asrc = (const float *)aasrc; + + float *dst = (float *)ddst; + int x, y; + + float offsetf = offset / 65535.0f; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0.0f) + dst[x] = (msrc[x] - offsetf) / asrc[x] + offsetf; + else + dst[x] = msrc[x]; + } + + dst += dlinesize / 4; + msrc += mlinesize / 4; + asrc += alinesize / 4; + } +} + static int premultiply_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { PreMultiplyContext *s = ctx->priv; @@ -442,6 +546,7 @@ static int filter_frame(AVFilterContext *ctx, case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUVA444P10: case AV_PIX_FMT_YUV444P12: + case AV_PIX_FMT_YUVA444P12: case AV_PIX_FMT_YUV444P14: case AV_PIX_FMT_YUV444P16: case AV_PIX_FMT_YUVA444P16: @@ -458,6 +563,10 @@ static int filter_frame(AVFilterContext *ctx, case AV_PIX_FMT_GBRAP16: s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply16offset : unpremultiply16; break; + case AV_PIX_FMT_GBRPF32: + case AV_PIX_FMT_GBRAPF32: + s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiplyf32offset : unpremultiplyf32; + break; case AV_PIX_FMT_GRAY8: s->premultiply[0] = limited ? unpremultiply8offset : unpremultiply8; break; @@ -489,6 +598,7 @@ static int filter_frame(AVFilterContext *ctx, case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUVA444P10: case AV_PIX_FMT_YUV444P12: + case AV_PIX_FMT_YUVA444P12: case AV_PIX_FMT_YUV444P14: case AV_PIX_FMT_YUV444P16: case AV_PIX_FMT_YUVA444P16: @@ -505,6 +615,10 @@ static int filter_frame(AVFilterContext *ctx, case AV_PIX_FMT_GBRAP16: s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply16offset : premultiply16; break; + case AV_PIX_FMT_GBRPF32: + case AV_PIX_FMT_GBRAPF32: + s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiplyf32offset: premultiplyf32; + break; case AV_PIX_FMT_GRAY8: s->premultiply[0] = limited ? premultiply8offset : premultiply8; break; @@ -567,7 +681,7 @@ static int config_input(AVFilterLink *inlink) s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub); s->width[0] = s->width[3] = inlink->w; - s->depth = desc->comp[0].depth; + s->depth = desc->flags & AV_PIX_FMT_FLAG_FLOAT ? 16 : desc->comp[0].depth; s->max = (1 << s->depth) - 1; s->half = (1 << s->depth) / 2; s->offset = 16 << (s->depth - 8); @@ -673,27 +787,19 @@ static av_cold int init(AVFilterContext *ctx) s->inverse = 1; pad.type = AVMEDIA_TYPE_VIDEO; - pad.name = av_strdup("main"); + pad.name = "main"; pad.config_props = config_input; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) return ret; - } if (!s->inplace) { pad.type = AVMEDIA_TYPE_VIDEO; - pad.name = av_strdup("alpha"); + pad.name = "alpha"; pad.config_props = NULL; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) return ret; - } } return 0; diff --git a/libavfilter/vf_pseudocolor.c b/libavfilter/vf_pseudocolor.c index e48b69c08..6f67c02eb 100644 --- a/libavfilter/vf_pseudocolor.c +++ b/libavfilter/vf_pseudocolor.c @@ -59,8 +59,112 @@ enum var_name { VAR_VARS_NB }; +enum Curves { + MAGMA, + INFERNO, + PLASMA, + VIRIDIS, + TURBO, + CIVIDIS, + NB_CURVES, +}; + +enum Presets { + PRESET_MAGMA, + PRESET_INFERNO, + PRESET_PLASMA, + PRESET_VIRIDIS, + PRESET_TURBO, + PRESET_CIVIDIS, + PRESET_RANGE1, + PRESET_RANGE2, + PRESET_SHADOWS, + PRESET_HIGHLIGHTS, + NB_PRESETS, +}; + +typedef struct Curve { + double coef[3][8]; +} Curve; + +typedef struct Fill { + float fill[4]; +} Fill; + +typedef struct Range { + int start, end; +} Range; + +typedef struct Preset { + int nb_segments; + const Range *ranges; + const Curve *curves; + const Fill *fills; +} Preset; + +static const Range full_range = {0, 256}; +static const Range spec1_range[] = {{0, 16}, {16, 236}, {236, 256}}; +static const Range spec2_range[] = {{0, 16}, {16, 22}, {22, 226}, {226, 236}, {236, 256}}; +static const Range shadows_range[] = {{0, 32}, {32, 256}}; +static const Range highlights_range[] = {{0, 214}, {214, 224}, {224, 256}}; + +static const Fill spec1_fills[] = {{{0.5f, 0.f, .5f, 1.f}}, {{-1.f, -1.f, -1.f, 1.f}}, {{1.f, 0.f, 0.f, 1.f}}}; +static const Fill spec2_fills[] = {{{0.5f, 0.f, .5f, 1.f}}, {{0.f, 1.f, 1.f, 1.f}}, {{-1.f, -1.f, -1.f, 1.f}}, {{1.f, 1.f, 0.f, 1.f}}, {{1.f, 0.f, 0.f, 1.f}}}; +static const Fill shadows_fills[] = {{{0.8f, 0.4f, .8f, 1.f}}, {{-1.f, -1.f, -1.f, 1.f}}}; +static const Fill highlights_fills[] = {{{-1.f, -1.f, -1.f, 1.f}}, {{1.f, 0.3f, 0.6f, 1.f}}, {{1.f, 0.2f, .5f, 1.f}}}; + +static const Curve curves[] = +{ + [MAGMA] = {{ + {-7.5631093e-16, 7.4289183e-13, -2.8525484e-10, 5.4446085e-08, -5.5596238e-06, 3.0569325e-04, -2.3137421e-03, 1.2152095e-02 }, + { 1.3217636e-15, -1.2214648e-12, 4.4319712e-10, -8.0197993e-08, 7.6598370e-06, -3.6523704e-04, 8.4836670e-03, -2.5536888e-02 }, + {-1.1446568e-15, 1.0013446e-12, -3.5651575e-10, 6.6775016e-08, -6.7120346e-06, 2.7346619e-04, 4.7969657e-03, 1.1971441e-02 }, + }}, + [INFERNO] = {{ + {-3.9848859e-18, 9.4821649e-14, -6.7371977e-11, 1.8469937e-08, -2.5359307e-06, 1.7959053e-04, 3.9782564e-04, 2.8845935e-04 }, + { 6.8408539e-16, -6.5499979e-13, 2.4562526e-10, -4.5989298e-08, 4.5723324e-06, -2.2111913e-04, 5.2023164e-03, -1.1226064e-02 }, + {-2.9921470e-15, 2.5864165e-12, -8.7403799e-10, 1.4713388e-07, -1.2701505e-05, 4.5159935e-04, 3.1087989e-03, 1.9122831e-02 }, + }}, + [PLASMA] = {{ + { 3.6196089e-16, -3.3623041e-13, 1.2324010e-10, -2.2769060e-08, 2.2297792e-06, -1.2567829e-04, 9.9791629e-03, 5.7247918e-02 }, + { 5.0262888e-16, -5.3193896e-13, 2.2451715e-10, -4.7529623e-08, 5.1374873e-06, -2.3260136e-04, 3.1502825e-03, 1.5362491e-02 }, + {-1.7782261e-16, 2.2487839e-13, -1.0610236e-10, 2.4112644e-08, -2.6331623e-06, 8.9499751e-05, 2.1386328e-03, 5.3824268e-01 }, + }}, + [VIRIDIS] = {{ + { 9.4850045e-16, -8.6629383e-13, 3.0310944e-10, -5.1340396e-08, 4.6024275e-06, -2.2744239e-04, 4.5559993e-03, 2.5662350e-01 }, + { 9.6461041e-17, -6.9209477e-14, 1.7625397e-11, -2.0229773e-09, 1.4900110e-07, -1.9315187e-05, 5.8967339e-03, 3.9544827e-03 }, + { 5.1785449e-16, -3.6663004e-13, 1.0249990e-10, -1.5431998e-08, 1.5007941e-06, -1.2001502e-04, 7.6951526e-03, 3.2292815e-01 }, + }}, + [TURBO] = {{ + {-4.3683890e-15, 3.7020347e-12, -1.1712592e-09, 1.6401790e-07, -8.6842919e-06, -1.8542465e-06, 8.4485325e-03, 1.6267077e-01 }, + {-4.0011069e-16, 2.7861423e-13, -6.3388921e-11, 5.8872238e-09, -5.4466522e-07, 1.8037114e-05, 1.0599869e-02, 7.6914696e-02 }, + {-2.8242609e-15, 2.9234108e-12, -1.1726546e-09, 2.2552115e-07, -2.0059387e-05, 5.0595552e-04, 1.7714932e-02, 2.7271836e-01 }, + }}, + [CIVIDIS] = {{ + {-9.5484131e-16, 9.6988184e-13, -4.0058766e-10, 8.5743924e-08, -9.9644797e-06, 5.9197908e-04, -1.0361579e-02, 3.3164429e-02 }, + { 1.2731941e-17, -9.4238449e-15, 2.2808841e-12, -1.1548296e-10, -2.3888913e-08, 3.8986680e-06, 2.5879330e-03, 1.2769733e-01 }, + { 4.6004608e-16, -5.0686849e-13, 2.2753449e-10, -5.3074099e-08, 6.7196096e-06, -4.4120020e-04, 1.3435551e-02, 2.8293355e-01 }, + }}, +}; + +static const Preset presets[] = +{ + [PRESET_MAGMA] = { 1, &full_range, &curves[MAGMA], NULL }, + [PRESET_INFERNO] = { 1, &full_range, &curves[INFERNO], NULL }, + [PRESET_PLASMA] = { 1, &full_range, &curves[PLASMA], NULL }, + [PRESET_VIRIDIS] = { 1, &full_range, &curves[VIRIDIS], NULL }, + [PRESET_TURBO] = { 1, &full_range, &curves[TURBO], NULL }, + [PRESET_CIVIDIS] = { 1, &full_range, &curves[CIVIDIS], NULL }, + [PRESET_RANGE1] = { 3, spec1_range, NULL, spec1_fills }, + [PRESET_RANGE2] = { 5, spec2_range, NULL, spec2_fills }, + [PRESET_SHADOWS] = { 2, shadows_range, NULL, shadows_fills }, + [PRESET_HIGHLIGHTS] = { 3, highlights_range, NULL, highlights_fills }, +}; + typedef struct PseudoColorContext { const AVClass *class; + int preset; + float opacity; int max; int index; int nb_planes; @@ -78,18 +182,34 @@ typedef struct PseudoColorContext { ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut); + float *lut, + float opacity); } PseudoColorContext; #define OFFSET(x) offsetof(PseudoColorContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption pseudocolor_options[] = { { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS }, { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS }, { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS }, { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS }, + { "index", "set component as base", OFFSET(index), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, .flags = FLAGS }, { "i", "set component as base", OFFSET(index), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, .flags = FLAGS }, + { "preset", "set preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=-1},-1, NB_PRESETS-1, .flags = FLAGS, "preset" }, + { "p", "set preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=-1},-1, NB_PRESETS-1, .flags = FLAGS, "preset" }, + { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=-1}, .flags = FLAGS, "preset" }, + { "magma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_MAGMA}, .flags = FLAGS, "preset" }, + { "inferno", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_INFERNO}, .flags = FLAGS, "preset" }, + { "plasma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_PLASMA}, .flags = FLAGS, "preset" }, + { "viridis", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_VIRIDIS}, .flags = FLAGS, "preset" }, + { "turbo", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_TURBO}, .flags = FLAGS, "preset" }, + { "cividis", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_CIVIDIS}, .flags = FLAGS, "preset" }, + { "range1", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_RANGE1}, .flags = FLAGS, "preset" }, + { "range2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_RANGE2}, .flags = FLAGS, "preset" }, + { "shadows", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_SHADOWS}, .flags = FLAGS, "preset" }, + { "highlights", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_HIGHLIGHTS},.flags=FLAGS, "preset" }, + { "opacity", "set pseudocolor opacity",OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, .flags = FLAGS }, { NULL } }; @@ -130,6 +250,18 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } +static inline float lerpf(float v0, float v1, float f) +{ + return v0 + (v1 - v0) * f; +} + +#define PCLIP(v, max, dst, src, x) \ + if (v >= 0 && v <= max) { \ + dst[x] = lerpf(src[x], v, opacity);\ + } else { \ + dst[x] = src[x]; \ + } + static void pseudocolor_filter(int max, int width, int height, const uint8_t *index, const uint8_t *src, @@ -137,7 +269,8 @@ static void pseudocolor_filter(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { int x, y; @@ -145,11 +278,7 @@ static void pseudocolor_filter(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[x]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } index += ilinesize; src += slinesize; @@ -164,7 +293,8 @@ static void pseudocolor_filter_11(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { int x, y; @@ -172,11 +302,7 @@ static void pseudocolor_filter_11(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[(y << 1) * ilinesize + (x << 1)]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } src += slinesize; dst += dlinesize; @@ -190,7 +316,8 @@ static void pseudocolor_filter_11d(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { int x, y; @@ -198,11 +325,7 @@ static void pseudocolor_filter_11d(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } src += slinesize; dst += dlinesize; @@ -216,7 +339,8 @@ static void pseudocolor_filter_10(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { int x, y; @@ -224,11 +348,7 @@ static void pseudocolor_filter_10(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[x << 1]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } index += ilinesize; src += slinesize; @@ -243,7 +363,8 @@ static void pseudocolor_filter_10d(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { int x, y; @@ -251,11 +372,7 @@ static void pseudocolor_filter_10d(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[x >> 1]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } index += ilinesize; src += slinesize; @@ -270,7 +387,8 @@ static void pseudocolor_filter_16(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { const uint16_t *index = (const uint16_t *)iindex; const uint16_t *src = (const uint16_t *)ssrc; @@ -281,11 +399,7 @@ static void pseudocolor_filter_16(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[x]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } index += ilinesize / 2; src += slinesize / 2; @@ -300,7 +414,8 @@ static void pseudocolor_filter_16_10(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { const uint16_t *index = (const uint16_t *)iindex; const uint16_t *src = (const uint16_t *)ssrc; @@ -311,11 +426,7 @@ static void pseudocolor_filter_16_10(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[x << 1]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } index += ilinesize / 2; src += slinesize / 2; @@ -330,7 +441,8 @@ static void pseudocolor_filter_16_10d(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { const uint16_t *index = (const uint16_t *)iindex; const uint16_t *src = (const uint16_t *)ssrc; @@ -341,11 +453,7 @@ static void pseudocolor_filter_16_10d(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[x >> 1]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } index += ilinesize / 2; src += slinesize / 2; @@ -360,7 +468,8 @@ static void pseudocolor_filter_16_11(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { const uint16_t *index = (const uint16_t *)iindex; const uint16_t *src = (const uint16_t *)ssrc; @@ -375,11 +484,7 @@ static void pseudocolor_filter_16_11(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[(y << 1) * ilinesize + (x << 1)]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } src += slinesize; dst += dlinesize; @@ -393,7 +498,8 @@ static void pseudocolor_filter_16_11d(int max, int width, int height, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, - float *lut) + float *lut, + float opacity) { const uint16_t *index = (const uint16_t *)iindex; const uint16_t *src = (const uint16_t *)ssrc; @@ -408,25 +514,46 @@ static void pseudocolor_filter_16_11d(int max, int width, int height, for (x = 0; x < width; x++) { int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]]; - if (v >= 0 && v <= max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } + PCLIP(v, max, dst, src, x); } src += slinesize; dst += dlinesize; } } +#define RGB_TO_Y_BT709(r, g, b) \ +((0.21260*219.0/255.0) * (r) + (0.71520*219.0/255.0) * (g) + \ + (0.07220*219.0/255.0) * (b)) + +#define RGB_TO_U_BT709(r1, g1, b1, max) \ +(-(0.11457*224.0/255.0) * r1 - (0.38543*224.0/255.0) * g1 + \ + (0.50000*224.0/255.0) * b1 + max * 0.5) + +#define RGB_TO_V_BT709(r1, g1, b1, max) \ +((0.50000*224.0/255.0) * r1 - (0.45415*224.0/255.0) * g1 - \ + (0.04585*224.0/255.0) * b1 + max * 0.5) + +static double poly_eval(const double *const poly, double x) +{ + double res = 0.; + + for (int i = 0; i < 8; i++) { + res += pow(x, i) * poly[7-i]; + } + + return av_clipd(res, 0., 1.); +} + static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; PseudoColorContext *s = ctx->priv; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - int depth, ret, hsub, vsub, color; + int depth, ret, hsub, vsub, color, factor, rgb; + rgb = desc->flags & AV_PIX_FMT_FLAG_RGB; depth = desc->comp[0].depth; + factor = 1 << (depth - 8); s->max = (1 << depth) - 1; s->nb_planes = av_pix_fmt_count_planes(inlink->format); @@ -457,7 +584,7 @@ static int config_input(AVFilterLink *inlink) s->var_values[VAR_VMAX] = 240 * (1 << (depth - 8)); s->var_values[VAR_AMAX] = s->max; - for (color = 0; color < s->nb_planes; color++) { + for (color = 0; color < s->nb_planes && s->preset < 0; color++) { double res; int val; @@ -488,6 +615,77 @@ static int config_input(AVFilterLink *inlink) } } + if (s->preset >= 0) { + int nb_segments = presets[s->preset].nb_segments; + + for (int seg = 0; seg < nb_segments; seg++) { + int start = presets[s->preset].ranges[seg].start; + int end = presets[s->preset].ranges[seg].end; + + for (int i = start; i < end; i++) { + if (!presets[s->preset].curves) { + const Fill fill = presets[s->preset].fills[seg]; + + for (int j = 0; j < factor; j++) { + double r, g, b, a; + + g = fill.fill[1]; + b = fill.fill[2]; + r = fill.fill[0]; + a = fill.fill[3]; + + if (g >= 0.f && b >= 0.f && r >= 0.f) { + g *= s->max; + b *= s->max; + r *= s->max; + + if (!rgb) { + double y = RGB_TO_Y_BT709(r, g, b); + double u = RGB_TO_U_BT709(r, g, b, s->max); + double v = RGB_TO_V_BT709(r, g, b, s->max); + + r = v; + g = y; + b = u; + } + } + + s->lut[0][i*factor+j] = g; + s->lut[1][i*factor+j] = b; + s->lut[2][i*factor+j] = r; + s->lut[3][i*factor+j] = a * s->max; + } + } else { + const Curve curve = presets[s->preset].curves[seg]; + + for (int j = 0; j < factor; j++) { + const double lf = j / (double)factor; + double r, g, b; + + g = poly_eval(curve.coef[1], i + lf) * s->max; + b = poly_eval(curve.coef[2], i + lf) * s->max; + r = poly_eval(curve.coef[0], i + lf) * s->max; + + if (!rgb) { + double y = RGB_TO_Y_BT709(r, g, b); + double u = RGB_TO_U_BT709(r, g, b, s->max); + double v = RGB_TO_V_BT709(r, g, b, s->max); + + r = v; + g = y; + b = u; + } + + s->lut[0][i*factor+j] = g; + s->lut[1][i*factor+j] = b; + s->lut[2][i*factor+j] = r; + s->lut[3][i*factor+j] = 1.f * s->max; + } + } + } + } + } + switch (inlink->format) { case AV_PIX_FMT_YUV444P: case AV_PIX_FMT_YUVA444P: @@ -596,13 +794,43 @@ static int config_input(AVFilterLink *inlink) return 0; } +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + PseudoColorContext *s = ctx->priv; + ThreadData *td = arg; + AVFrame *in = td->in; + AVFrame *out = td->out; + + for (int plane = 0; plane < s->nb_planes; plane++) { + const int slice_start = (s->height[plane] * jobnr) / nb_jobs; + const int slice_end = (s->height[plane] * (jobnr+1)) / nb_jobs; + const int islice_start = (s->height[s->index] * jobnr) / nb_jobs; + ptrdiff_t ilinesize = in->linesize[s->index]; + ptrdiff_t slinesize = in->linesize[plane]; + ptrdiff_t dlinesize = out->linesize[plane]; + const uint8_t *index = in->data[s->index] + islice_start * ilinesize; + const uint8_t *src = in->data[plane] + slice_start * slinesize; + uint8_t *dst = out->data[plane] + slice_start * dlinesize; + + s->filter[plane](s->max, s->width[plane], slice_end - slice_start, + index, src, dst, ilinesize, slinesize, + dlinesize, s->lut[plane], s->opacity); + } + + return 0; +} + static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; PseudoColorContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; + ThreadData td; AVFrame *out; - int plane; out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { @@ -611,23 +839,24 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } av_frame_copy_props(out, in); - for (plane = 0; plane < s->nb_planes; plane++) { - const uint8_t *index = in->data[s->index]; - const uint8_t *src = in->data[plane]; - uint8_t *dst = out->data[plane]; - ptrdiff_t ilinesize = in->linesize[s->index]; - ptrdiff_t slinesize = in->linesize[plane]; - ptrdiff_t dlinesize = out->linesize[plane]; - - s->filter[plane](s->max, s->width[plane], s->height[plane], - index, src, dst, ilinesize, slinesize, - dlinesize, s->lut[plane]); - } + td.out = out, td.in = in; + ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(s->height[1], ff_filter_get_nb_threads(ctx))); av_frame_free(&in); return ff_filter_frame(outlink, out); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + int ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + + if (ret < 0) + return ret; + + return config_input(ctx->inputs[0]); +} + static const AVFilterPad inputs[] = { { .name = "default", @@ -668,5 +897,6 @@ AVFilter ff_vf_pseudocolor = { .query_formats = query_formats, .inputs = inputs, .outputs = outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c index c9a673dcd..0d0c0f35a 100644 --- a/libavfilter/vf_psnr.c +++ b/libavfilter/vf_psnr.c @@ -51,9 +51,11 @@ typedef struct PSNRContext { uint8_t rgba_map[4]; char comps[4]; int nb_components; + int nb_threads; int planewidth[4]; int planeheight[4]; double planeweight[4]; + uint64_t **score; PSNRDSPContext dsp; } PSNRContext; @@ -104,35 +106,50 @@ static uint64_t sse_line_16bit(const uint8_t *_main_line, const uint8_t *_ref_li return m2; } -static inline -void compute_images_mse(PSNRContext *s, - const uint8_t *main_data[4], const int main_linesizes[4], - const uint8_t *ref_data[4], const int ref_linesizes[4], - int w, int h, double mse[4]) -{ - int i, c; +typedef struct ThreadData { + const uint8_t *main_data[4]; + const uint8_t *ref_data[4]; + int main_linesize[4]; + int ref_linesize[4]; + int planewidth[4]; + int planeheight[4]; + uint64_t **score; + int nb_components; + PSNRDSPContext *dsp; +} ThreadData; - for (c = 0; c < s->nb_components; c++) { - const int outw = s->planewidth[c]; - const int outh = s->planeheight[c]; - const uint8_t *main_line = main_data[c]; - const uint8_t *ref_line = ref_data[c]; - const int ref_linesize = ref_linesizes[c]; - const int main_linesize = main_linesizes[c]; +static +int compute_images_mse(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs) +{ + ThreadData *td = arg; + uint64_t *score = td->score[jobnr]; + + for (int c = 0; c < td->nb_components; c++) { + const int outw = td->planewidth[c]; + const int outh = td->planeheight[c]; + const int slice_start = (outh * jobnr) / nb_jobs; + const int slice_end = (outh * (jobnr+1)) / nb_jobs; + const int ref_linesize = td->ref_linesize[c]; + const int main_linesize = td->main_linesize[c]; + const uint8_t *main_line = td->main_data[c] + main_linesize * slice_start; + const uint8_t *ref_line = td->ref_data[c] + ref_linesize * slice_start; uint64_t m = 0; - for (i = 0; i < outh; i++) { - m += s->dsp.sse_line(main_line, ref_line, outw); + for (int i = slice_start; i < slice_end; i++) { + m += td->dsp->sse_line(main_line, ref_line, outw); ref_line += ref_linesize; main_line += main_linesize; } - mse[c] = m / (double)(outw * outh); + score[c] = m; } + + return 0; } static void set_meta(AVDictionary **metadata, const char *key, char comp, float d) { char value[128]; - snprintf(value, sizeof(value), "%0.2f", d); + snprintf(value, sizeof(value), "%f", d); if (comp) { char key2[128]; snprintf(key2, sizeof(key2), "%s%c", key, comp); @@ -147,34 +164,55 @@ static int do_psnr(FFFrameSync *fs) AVFilterContext *ctx = fs->parent; PSNRContext *s = ctx->priv; AVFrame *master, *ref; - double comp_mse[4], mse = 0; - int ret, j, c; + double comp_mse[4], mse = 0.; + uint64_t comp_sum[4] = { 0 }; AVDictionary **metadata; + ThreadData td; + int ret; ret = ff_framesync_dualinput_get(fs, &master, &ref); if (ret < 0) return ret; - if (!ref) + if (ctx->is_disabled || !ref) return ff_filter_frame(ctx->outputs[0], master); metadata = &master->metadata; - compute_images_mse(s, (const uint8_t **)master->data, master->linesize, - (const uint8_t **)ref->data, ref->linesize, - master->width, master->height, comp_mse); + td.nb_components = s->nb_components; + td.dsp = &s->dsp; + td.score = s->score; + for (int c = 0; c < s->nb_components; c++) { + td.main_data[c] = master->data[c]; + td.ref_data[c] = ref->data[c]; + td.main_linesize[c] = master->linesize[c]; + td.ref_linesize[c] = ref->linesize[c]; + td.planewidth[c] = s->planewidth[c]; + td.planeheight[c] = s->planeheight[c]; + } - for (j = 0; j < s->nb_components; j++) - mse += comp_mse[j] * s->planeweight[j]; + ctx->internal->execute(ctx, compute_images_mse, &td, NULL, FFMIN(s->planeheight[1], s->nb_threads)); + + for (int j = 0; j < s->nb_threads; j++) { + for (int c = 0; c < s->nb_components; c++) + comp_sum[c] += s->score[j][c]; + } + + for (int c = 0; c < s->nb_components; c++) + comp_mse[c] = comp_sum[c] / ((double)s->planewidth[c] * s->planeheight[c]); + + for (int c = 0; c < s->nb_components; c++) + mse += comp_mse[c] * s->planeweight[c]; s->min_mse = FFMIN(s->min_mse, mse); s->max_mse = FFMAX(s->max_mse, mse); s->mse += mse; - for (j = 0; j < s->nb_components; j++) + + for (int j = 0; j < s->nb_components; j++) s->mse_comp[j] += comp_mse[j]; s->nb_frames++; - for (j = 0; j < s->nb_components; j++) { - c = s->is_rgb ? s->rgba_map[j] : j; + for (int j = 0; j < s->nb_components; j++) { + int c = s->is_rgb ? s->rgba_map[j] : j; set_meta(metadata, "lavfi.psnr.mse.", s->comps[j], comp_mse[c]); set_meta(metadata, "lavfi.psnr.psnr.", s->comps[j], get_psnr(comp_mse[c], 1, s->max[c])); } @@ -185,16 +223,16 @@ static int do_psnr(FFFrameSync *fs) if (s->stats_version == 2 && !s->stats_header_written) { fprintf(s->stats_file, "psnr_log_version:2 fields:n"); fprintf(s->stats_file, ",mse_avg"); - for (j = 0; j < s->nb_components; j++) { + for (int j = 0; j < s->nb_components; j++) { fprintf(s->stats_file, ",mse_%c", s->comps[j]); } fprintf(s->stats_file, ",psnr_avg"); - for (j = 0; j < s->nb_components; j++) { + for (int j = 0; j < s->nb_components; j++) { fprintf(s->stats_file, ",psnr_%c", s->comps[j]); } if (s->stats_add_max) { fprintf(s->stats_file, ",max_avg"); - for (j = 0; j < s->nb_components; j++) { + for (int j = 0; j < s->nb_components; j++) { fprintf(s->stats_file, ",max_%c", s->comps[j]); } } @@ -202,20 +240,20 @@ static int do_psnr(FFFrameSync *fs) s->stats_header_written = 1; } fprintf(s->stats_file, "n:%"PRId64" mse_avg:%0.2f ", s->nb_frames, mse); - for (j = 0; j < s->nb_components; j++) { - c = s->is_rgb ? s->rgba_map[j] : j; + for (int j = 0; j < s->nb_components; j++) { + int c = s->is_rgb ? s->rgba_map[j] : j; fprintf(s->stats_file, "mse_%c:%0.2f ", s->comps[j], comp_mse[c]); } fprintf(s->stats_file, "psnr_avg:%0.2f ", get_psnr(mse, 1, s->average_max)); - for (j = 0; j < s->nb_components; j++) { - c = s->is_rgb ? s->rgba_map[j] : j; + for (int j = 0; j < s->nb_components; j++) { + int c = s->is_rgb ? s->rgba_map[j] : j; fprintf(s->stats_file, "psnr_%c:%0.2f ", s->comps[j], get_psnr(comp_mse[c], 1, s->max[c])); } if (s->stats_version == 2 && s->stats_add_max) { fprintf(s->stats_file, "max_avg:%d ", s->average_max); - for (j = 0; j < s->nb_components; j++) { - c = s->is_rgb ? s->rgba_map[j] : j; + for (int j = 0; j < s->nb_components; j++) { + int c = s->is_rgb ? s->rgba_map[j] : j; fprintf(s->stats_file, "max_%c:%d ", s->comps[j], s->max[c]); } } @@ -289,6 +327,7 @@ static int config_input_ref(AVFilterLink *inlink) unsigned sum; int j; + s->nb_threads = ff_filter_get_nb_threads(ctx); s->nb_components = desc->nb_components; if (ctx->inputs[0]->w != ctx->inputs[1]->w || ctx->inputs[0]->h != ctx->inputs[1]->h) { @@ -329,6 +368,16 @@ static int config_input_ref(AVFilterLink *inlink) if (ARCH_X86) ff_psnr_init_x86(&s->dsp, desc->comp[0].depth); + s->score = av_calloc(s->nb_threads, sizeof(*s->score)); + if (!s->score) + return AVERROR(ENOMEM); + + for (int t = 0; t < s->nb_threads && s->score; t++) { + s->score[t] = av_calloc(s->nb_components, sizeof(*s->score[0])); + if (!s->score[t]) + return AVERROR(ENOMEM); + } + return 0; } @@ -389,6 +438,9 @@ static av_cold void uninit(AVFilterContext *ctx) } ff_framesync_uninit(&s->fs); + for (int t = 0; t < s->nb_threads && s->score; t++) + av_freep(&s->score[t]); + av_freep(&s->score); if (s->stats_file && s->stats_file != stdout) fclose(s->stats_file); @@ -427,4 +479,5 @@ AVFilter ff_vf_psnr = { .priv_class = &psnr_class, .inputs = psnr_inputs, .outputs = psnr_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/vf_qp.c b/libavfilter/vf_qp.c index 33d39493b..e2d60fdbb 100644 --- a/libavfilter/vf_qp.c +++ b/libavfilter/vf_qp.c @@ -23,6 +23,8 @@ #include "libavutil/imgutils.h" #include "libavutil/pixdesc.h" #include "libavutil/opt.h" +#include "libavutil/video_enc_params.h" + #include "avfilter.h" #include "formats.h" #include "internal.h" @@ -36,6 +38,8 @@ typedef struct QPContext { int evaluate_per_mb; } QPContext; +static const char *const var_names[] = { "known", "qp", "x", "y", "w", "h", NULL }; + #define OFFSET(x) offsetof(QPContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM @@ -53,7 +57,6 @@ static int config_input(AVFilterLink *inlink) int i; int ret; AVExpr *e = NULL; - static const char *var_names[] = { "known", "qp", "x", "y", "w", "h", NULL }; if (!s->qp_expr_str) return 0; @@ -89,39 +92,59 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; QPContext *s = ctx->priv; - AVBufferRef *out_qp_table_buf; AVFrame *out = NULL; - const int8_t *in_qp_table; - int type, stride, ret; + int ret; + + AVFrameSideData *sd_in; + AVVideoEncParams *par_in = NULL; + int8_t in_qp_global = 0; + + AVVideoEncParams *par_out; if (!s->qp_expr_str || ctx->is_disabled) return ff_filter_frame(outlink, in); - out_qp_table_buf = av_buffer_alloc(s->h * s->qstride); - if (!out_qp_table_buf) { - ret = AVERROR(ENOMEM); - goto fail; + sd_in = av_frame_get_side_data(in, AV_FRAME_DATA_VIDEO_ENC_PARAMS); + if (sd_in && sd_in->size >= sizeof(AVVideoEncParams)) { + par_in = (AVVideoEncParams*)sd_in->data; + + // we accept the input QP table only if it is of the MPEG2 type + // and contains either no blocks at all or 16x16 macroblocks + if (par_in->type == AV_VIDEO_ENC_PARAMS_MPEG2 && + (par_in->nb_blocks == s->h * s->qstride || !par_in->nb_blocks)) { + in_qp_global = par_in->qp; + if (!par_in->nb_blocks) + par_in = NULL; + } else + par_in = NULL; } out = av_frame_clone(in); if (!out) { - av_buffer_unref(&out_qp_table_buf); ret = AVERROR(ENOMEM); goto fail; } - in_qp_table = av_frame_get_qp_table(in, &stride, &type); - av_frame_set_qp_table(out, out_qp_table_buf, s->qstride, type); + par_out = av_video_enc_params_create_side_data(out, AV_VIDEO_ENC_PARAMS_MPEG2, + (s->evaluate_per_mb || sd_in) ? + s->h * s->qstride : 0); + if (!par_out) { + ret = AVERROR(ENOMEM); + goto fail; + } +#define BLOCK_QP_DELTA(block_idx) \ + (par_in ? av_video_enc_params_block(par_in, block_idx)->delta_qp : 0) if (s->evaluate_per_mb) { int y, x; for (y = 0; y < s->h; y++) for (x = 0; x < s->qstride; x++) { - int qp = in_qp_table ? in_qp_table[x + stride * y] : NAN; - double var_values[] = { !!in_qp_table, qp, x, y, s->qstride, s->h, 0}; - static const char *var_names[] = { "known", "qp", "x", "y", "w", "h", NULL }; + unsigned int block_idx = y * s->qstride + x; + AVVideoBlockParams *b = av_video_enc_params_block(par_out, block_idx); + int qp = sd_in ? in_qp_global + BLOCK_QP_DELTA(block_idx) : NAN; + double var_values[] = { !!sd_in, qp, x, y, s->qstride, s->h, 0}; double temp_val; ret = av_expr_parse_and_eval(&temp_val, s->qp_expr_str, @@ -129,21 +152,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) NULL, NULL, NULL, NULL, 0, 0, ctx); if (ret < 0) goto fail; - out_qp_table_buf->data[x + s->qstride * y] = lrintf(temp_val); + b->delta_qp = lrintf(temp_val); } - } else if (in_qp_table) { + } else if (sd_in) { int y, x; for (y = 0; y < s->h; y++) - for (x = 0; x < s->qstride; x++) - out_qp_table_buf->data[x + s->qstride * y] = s->lut[129 + - ((int8_t)in_qp_table[x + stride * y])]; + for (x = 0; x < s->qstride; x++) { + unsigned int block_idx = y * s->qstride + x; + AVVideoBlockParams *b = av_video_enc_params_block(par_out, block_idx); + b->delta_qp = s->lut[129 + (int8_t)(in_qp_global + BLOCK_QP_DELTA(block_idx))]; + } } else { - int y, x, qp = s->lut[0]; - - for (y = 0; y < s->h; y++) - for (x = 0; x < s->qstride; x++) - out_qp_table_buf->data[x + s->qstride * y] = qp; + par_out->qp = s->lut[0]; } ret = ff_filter_frame(outlink, out); diff --git a/libavfilter/vf_readeia608.c b/libavfilter/vf_readeia608.c index 2973847d4..d4c3ca6e5 100644 --- a/libavfilter/vf_readeia608.c +++ b/libavfilter/vf_readeia608.c @@ -57,24 +57,37 @@ typedef struct CodeItem { int size; } CodeItem; -typedef struct ReadEIA608Context { - const AVClass *class; - int start, end; - int nb_found; +typedef struct ScanItem { + int nb_line; + int found; int white; int black; + uint64_t *histogram; + uint8_t byte[2]; + + CodeItem *code; + LineItem *line; +} ScanItem; + +typedef struct ReadEIA608Context { + const AVClass *class; + + int start, end; float spw; int chp; int lp; - uint64_t histogram[256]; + int depth; + int max; + int nb_allocated; + ScanItem *scan; - CodeItem *code; - LineItem *line; + void (*read_line[2])(AVFrame *in, int nb_line, + LineItem *line, int lp, int w); } ReadEIA608Context; #define OFFSET(x) offsetof(ReadEIA608Context, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption readeia608_options[] = { { "scan_min", "set from which line to scan for codes", OFFSET(start), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS }, @@ -90,13 +103,26 @@ AVFILTER_DEFINE_CLASS(readeia608); static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pixel_fmts[] = { - AV_PIX_FMT_GRAY8, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, + AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, + AV_PIX_FMT_GRAY16, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_NONE }; AVFilterFormats *formats = ff_make_format_list(pixel_fmts); @@ -105,53 +131,75 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, formats); } -static int config_input(AVFilterLink *inlink) +static int config_filter(AVFilterContext *ctx, int start, int end) { - AVFilterContext *ctx = inlink->dst; ReadEIA608Context *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; int size = inlink->w + LAG; - if (s->end >= inlink->h) { + if (end >= inlink->h) { av_log(ctx, AV_LOG_WARNING, "Last line to scan too large, clipping.\n"); - s->end = inlink->h - 1; + end = inlink->h - 1; } - if (s->start > s->end) { + if (start > end) { av_log(ctx, AV_LOG_ERROR, "Invalid range.\n"); return AVERROR(EINVAL); } - s->line = av_calloc(size, sizeof(*s->line)); - s->code = av_calloc(size, sizeof(*s->code)); - if (!s->line || !s->code) - return AVERROR(ENOMEM); + if (s->nb_allocated < end - start + 1) { + const int diff = end - start + 1 - s->nb_allocated; + + s->scan = av_realloc_f(s->scan, end - start + 1, sizeof(*s->scan)); + if (!s->scan) + return AVERROR(ENOMEM); + memset(&s->scan[s->nb_allocated], 0, diff * sizeof(*s->scan)); + s->nb_allocated = end - start + 1; + } + + for (int i = 0; i < s->nb_allocated; i++) { + ScanItem *scan = &s->scan[i]; + + if (!scan->histogram) + scan->histogram = av_calloc(s->max + 1, sizeof(*scan->histogram)); + if (!scan->line) + scan->line = av_calloc(size, sizeof(*scan->line)); + if (!scan->code) + scan->code = av_calloc(size, sizeof(*scan->code)); + if (!scan->line || !scan->code || !scan->histogram) + return AVERROR(ENOMEM); + } + + s->start = start; + s->end = end; return 0; } -static void build_histogram(ReadEIA608Context *s, const LineItem *line, int len) +static void build_histogram(ReadEIA608Context *s, ScanItem *scan, const LineItem *line, int len) { - memset(s->histogram, 0, sizeof(s->histogram)); + memset(scan->histogram, 0, (s->max + 1) * sizeof(*scan->histogram)); for (int i = LAG; i < len + LAG; i++) - s->histogram[line[i].input]++; + scan->histogram[line[i].input]++; } -static void find_black_and_white(ReadEIA608Context *s) +static void find_black_and_white(ReadEIA608Context *s, ScanItem *scan) { + const int max = s->max; int start = 0, end = 0, middle; int black = 0, white = 0; int cnt; - for (int i = 0; i < 256; i++) { - if (s->histogram[i]) { + for (int i = 0; i <= max; i++) { + if (scan->histogram[i]) { start = i; break; } } - for (int i = 255; i >= 0; i--) { - if (s->histogram[i]) { + for (int i = max; i >= 0; i--) { + if (scan->histogram[i]) { end = i; break; } @@ -161,22 +209,22 @@ static void find_black_and_white(ReadEIA608Context *s) cnt = 0; for (int i = start; i <= middle; i++) { - if (s->histogram[i] > cnt) { - cnt = s->histogram[i]; + if (scan->histogram[i] > cnt) { + cnt = scan->histogram[i]; black = i; } } cnt = 0; for (int i = end; i >= middle; i--) { - if (s->histogram[i] > cnt) { - cnt = s->histogram[i]; + if (scan->histogram[i] > cnt) { + cnt = scan->histogram[i]; white = i; } } - s->black = black; - s->white = white; + scan->black = black; + scan->white = white; } static float meanf(const LineItem *line, int len) @@ -202,7 +250,7 @@ static float stddevf(const LineItem *line, int len) return sqrtf(standard_deviation / (len - 1)); } -static void thresholding(ReadEIA608Context *s, LineItem *line, +static void thresholding(ReadEIA608Context *s, ScanItem *scan, LineItem *line, int lag, float threshold, float influence, int len) { for (int i = lag; i < len + lag; i++) { @@ -230,8 +278,8 @@ static void thresholding(ReadEIA608Context *s, LineItem *line, } else { int distance_from_black, distance_from_white; - distance_from_black = FFABS(line[i].input - s->black); - distance_from_white = FFABS(line[i].input - s->white); + distance_from_black = FFABS(line[i].input - scan->black); + distance_from_white = FFABS(line[i].input - scan->white); line[i].output = distance_from_black <= distance_from_white ? 0 : 255; } @@ -264,84 +312,109 @@ static int periods(const LineItem *line, CodeItem *code, int len) return cnt + 1; } -static void dump_code(AVFilterContext *ctx, int len, int item) +static void dump_code(AVFilterContext *ctx, ScanItem *scan, int len, int item) { - ReadEIA608Context *s = ctx->priv; - av_log(ctx, AV_LOG_DEBUG, "%d:", item); for (int i = 0; i < len; i++) { - av_log(ctx, AV_LOG_DEBUG, " %03d", s->code[i].size); + av_log(ctx, AV_LOG_DEBUG, " %03d", scan->code[i].size); } av_log(ctx, AV_LOG_DEBUG, "\n"); } -static void extract_line(AVFilterContext *ctx, AVFrame *in, int w, int nb_line) +#define READ_LINE(type, name) \ +static void read_##name(AVFrame *in, int nb_line, LineItem *line, int lp, int w) \ +{ \ + const type *src = (const type *)(&in->data[0][nb_line * in->linesize[0]]);\ + \ + if (lp) { \ + for (int i = 0; i < w; i++) { \ + int a = FFMAX(i - 3, 0); \ + int b = FFMAX(i - 2, 0); \ + int c = FFMAX(i - 1, 0); \ + int d = FFMIN(i + 3, w-1); \ + int e = FFMIN(i + 2, w-1); \ + int f = FFMIN(i + 1, w-1); \ + \ + line[LAG + i].input = (src[a] + src[b] + src[c] + src[i] + \ + src[d] + src[e] + src[f] + 6) / 7; \ + } \ + } else { \ + for (int i = 0; i < w; i++) { \ + line[LAG + i].input = src[i]; \ + } \ + } \ +} + +READ_LINE(uint8_t, byte) +READ_LINE(uint16_t, word) + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ReadEIA608Context *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + + if (!desc) + return AVERROR_BUG; + s->depth = desc->comp[0].depth; + s->max = (1 << desc->comp[0].depth) - 1; + s->read_line[0] = read_byte; + s->read_line[1] = read_word; + + return config_filter(ctx, s->start, s->end); +} + +static void extract_line(AVFilterContext *ctx, AVFrame *in, ScanItem *scan, int w, int nb_line) { ReadEIA608Context *s = ctx->priv; - LineItem *line = s->line; + LineItem *line = scan->line; int i, j, ch, len; - const uint8_t *src; - uint8_t byte[2] = { 0 }; uint8_t codes[19] = { 0 }; float bit_size = 0.f; int parity; memset(line, 0, (w + LAG) * sizeof(*line)); + scan->byte[0] = scan->byte[1] = 0; + scan->found = 0; - src = &in->data[0][nb_line * in->linesize[0]]; - if (s->lp) { - for (i = 0; i < w; i++) { - int a = FFMAX(i - 3, 0); - int b = FFMAX(i - 2, 0); - int c = FFMAX(i - 1, 0); - int d = FFMIN(i + 3, w-1); - int e = FFMIN(i + 2, w-1); - int f = FFMIN(i + 1, w-1); + s->read_line[s->depth > 8](in, nb_line, line, s->lp, w); - line[LAG + i].input = (src[a] + src[b] + src[c] + src[i] + src[d] + src[e] + src[f] + 6) / 7; - } - } else { - for (i = 0; i < w; i++) { - line[LAG + i].input = src[i]; - } - } - - build_histogram(s, line, w); - find_black_and_white(s); - if (s->white - s->black < 5) + build_histogram(s, scan, line, w); + find_black_and_white(s, scan); + if (scan->white - scan->black < 5) return; - thresholding(s, line, LAG, 1, 0, w); - len = periods(line, s->code, w); - dump_code(ctx, len, nb_line); + thresholding(s, scan, line, LAG, 1, 0, w); + len = periods(line, scan->code, w); + dump_code(ctx, scan, len, nb_line); if (len < 15 || - s->code[14].bit != 0 || - w / (float)s->code[14].size < SYNC_BITSIZE_MIN || - w / (float)s->code[14].size > SYNC_BITSIZE_MAX) { + scan->code[14].bit != 0 || + w / (float)scan->code[14].size < SYNC_BITSIZE_MIN || + w / (float)scan->code[14].size > SYNC_BITSIZE_MAX) { return; } for (i = 14; i < len; i++) { - bit_size += s->code[i].size; + bit_size += scan->code[i].size; } bit_size /= 19.f; for (i = 1; i < 14; i++) { - if (s->code[i].size / bit_size > CLOCK_BITSIZE_MAX || - s->code[i].size / bit_size < CLOCK_BITSIZE_MIN) { + if (scan->code[i].size / bit_size > CLOCK_BITSIZE_MAX || + scan->code[i].size / bit_size < CLOCK_BITSIZE_MIN) { return; } } - if (s->code[15].size / bit_size < 0.45f) { + if (scan->code[15].size / bit_size < 0.45f) { return; } for (j = 0, i = 14; i < len; i++) { int run, bit; - run = lrintf(s->code[i].size / bit_size); - bit = s->code[i].bit; + run = lrintf(scan->code[i].size / bit_size); + bit = scan->code[i].bit; for (int k = 0; j < 19 && k < run; k++) { codes[j++] = bit; @@ -361,33 +434,37 @@ static void extract_line(AVFilterContext *ctx, AVFrame *in, int w, int nb_line) } else { b = 0; } - byte[ch] |= b << i; + scan->byte[ch] |= b << i; } if (s->chp) { if (!(parity & 1)) { - byte[ch] = 0x7F; + scan->byte[ch] = 0x7F; } } } - { - uint8_t key[128], value[128]; + scan->nb_line = nb_line; + scan->found = 1; +} - //snprintf(key, sizeof(key), "lavfi.readeia608.%d.bits", s->nb_found); - //snprintf(value, sizeof(value), "0b%d%d%d%d%d%d%d%d 0b%d%d%d%d%d%d%d%d", codes[3]==255,codes[4]==255,codes[5]==255,codes[6]==255,codes[7]==255,codes[8]==255,codes[9]==255,codes[10]==255,codes[11]==255,codes[12]==255,codes[13]==255,codes[14]==255,codes[15]==255,codes[16]==255,codes[17]==255,codes[18]==255); - //av_dict_set(&in->metadata, key, value, 0); +static int extract_lines(AVFilterContext *ctx, void *arg, + int job, int nb_jobs) +{ + ReadEIA608Context *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + const int h = s->end - s->start + 1; + const int start = (h * job) / nb_jobs; + const int end = (h * (job+1)) / nb_jobs; + AVFrame *in = arg; - snprintf(key, sizeof(key), "lavfi.readeia608.%d.cc", s->nb_found); - snprintf(value, sizeof(value), "0x%02X%02X", byte[0], byte[1]); - av_dict_set(&in->metadata, key, value, 0); + for (int i = start; i < end; i++) { + ScanItem *scan = &s->scan[i]; - snprintf(key, sizeof(key), "lavfi.readeia608.%d.line", s->nb_found); - snprintf(value, sizeof(value), "%d", nb_line); - av_dict_set(&in->metadata, key, value, 0); + extract_line(ctx, in, scan, inlink->w, i); } - s->nb_found++; + return 0; } static int filter_frame(AVFilterLink *inlink, AVFrame *in) @@ -395,11 +472,33 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; ReadEIA608Context *s = ctx->priv; - int i; + int nb_found; - s->nb_found = 0; - for (i = s->start; i <= s->end; i++) - extract_line(ctx, in, inlink->w, i); + ctx->internal->execute(ctx, extract_lines, in, NULL, FFMIN(FFMAX(s->end - s->start + 1, 1), + ff_filter_get_nb_threads(ctx))); + + nb_found = 0; + for (int i = 0; i < s->end - s->start + 1; i++) { + ScanItem *scan = &s->scan[i]; + uint8_t key[128], value[128]; + + if (!scan->found) + continue; + + //snprintf(key, sizeof(key), "lavfi.readeia608.%d.bits", nb_found); + //snprintf(value, sizeof(value), "0b%d%d%d%d%d%d%d%d 0b%d%d%d%d%d%d%d%d", codes[3]==255,codes[4]==255,codes[5]==255,codes[6]==255,codes[7]==255,codes[8]==255,codes[9]==255,codes[10]==255,codes[11]==255,codes[12]==255,codes[13]==255,codes[14]==255,codes[15]==255,codes[16]==255,codes[17]==255,codes[18]==255); + //av_dict_set(&in->metadata, key, value, 0); + + snprintf(key, sizeof(key), "lavfi.readeia608.%d.cc", nb_found); + snprintf(value, sizeof(value), "0x%02X%02X", scan->byte[0], scan->byte[1]); + av_dict_set(&in->metadata, key, value, 0); + + snprintf(key, sizeof(key), "lavfi.readeia608.%d.line", nb_found); + snprintf(value, sizeof(value), "%d", scan->nb_line); + av_dict_set(&in->metadata, key, value, 0); + + nb_found++; + } return ff_filter_frame(outlink, in); } @@ -408,8 +507,35 @@ static av_cold void uninit(AVFilterContext *ctx) { ReadEIA608Context *s = ctx->priv; - av_freep(&s->code); - av_freep(&s->line); + for (int i = 0; i < s->nb_allocated; i++) { + ScanItem *scan = &s->scan[i]; + + av_freep(&scan->histogram); + av_freep(&scan->code); + av_freep(&scan->line); + } + + s->nb_allocated = 0; + av_freep(&s->scan); +} + +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + ReadEIA608Context *s = ctx->priv; + int ret, start = s->start, end = s->end; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + ret = config_filter(ctx, s->start, s->end); + if (ret < 0) { + s->start = start; + s->end = end; + } + + return 0; } static const AVFilterPad readeia608_inputs[] = { @@ -439,5 +565,6 @@ AVFilter ff_vf_readeia608 = { .inputs = readeia608_inputs, .outputs = readeia608_outputs, .uninit = uninit, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; diff --git a/libavfilter/vf_remap.c b/libavfilter/vf_remap.c index 6d5d75225..1896a268c 100644 --- a/libavfilter/vf_remap.c +++ b/libavfilter/vf_remap.c @@ -115,25 +115,15 @@ static int query_formats(AVFilterContext *ctx) AVFilterFormats *pix_formats = NULL, *map_formats = NULL; int ret; - if (!(pix_formats = ff_make_format_list(s->format ? gray_pix_fmts : pix_fmts)) || - !(map_formats = ff_make_format_list(map_fmts))) { - ret = AVERROR(ENOMEM); - goto fail; - } - if ((ret = ff_formats_ref(pix_formats, &ctx->inputs[0]->out_formats)) < 0 || - (ret = ff_formats_ref(map_formats, &ctx->inputs[1]->out_formats)) < 0 || - (ret = ff_formats_ref(map_formats, &ctx->inputs[2]->out_formats)) < 0 || - (ret = ff_formats_ref(pix_formats, &ctx->outputs[0]->in_formats)) < 0) - goto fail; - return 0; -fail: - if (pix_formats) - av_freep(&pix_formats->formats); - av_freep(&pix_formats); - if (map_formats) - av_freep(&map_formats->formats); - av_freep(&map_formats); - return ret; + pix_formats = ff_make_format_list(s->format ? gray_pix_fmts : pix_fmts); + if ((ret = ff_formats_ref(pix_formats, &ctx->inputs[0]->outcfg.formats)) < 0 || + (ret = ff_formats_ref(pix_formats, &ctx->outputs[0]->incfg.formats)) < 0) + return ret; + + map_formats = ff_make_format_list(map_fmts); + if ((ret = ff_formats_ref(map_formats, &ctx->inputs[1]->outcfg.formats)) < 0) + return ret; + return ff_formats_ref(map_formats, &ctx->inputs[2]->outcfg.formats); } /** diff --git a/libavfilter/vf_removelogo.c b/libavfilter/vf_removelogo.c index aff2d12a1..4026bdd09 100644 --- a/libavfilter/vf_removelogo.c +++ b/libavfilter/vf_removelogo.c @@ -342,8 +342,8 @@ static av_cold int init(AVFilterContext *ctx) /* Calculate our bounding rectangles, which determine in what * region the logo resides for faster processing. */ - ff_calculate_bounding_box(&s->full_mask_bbox, s->full_mask_data, w, w, h, 0); - ff_calculate_bounding_box(&s->half_mask_bbox, s->half_mask_data, w/2, w/2, h/2, 0); + ff_calculate_bounding_box(&s->full_mask_bbox, s->full_mask_data, w, w, h, 0, 8); + ff_calculate_bounding_box(&s->half_mask_bbox, s->half_mask_data, w/2, w/2, h/2, 0, 8); #define SHOW_LOGO_INFO(mask_type) \ av_log(ctx, AV_LOG_VERBOSE, #mask_type " x1:%d x2:%d y1:%d y2:%d max_mask_size:%d\n", \ diff --git a/libavfilter/vf_rotate.c b/libavfilter/vf_rotate.c index 02f56c6eb..65c6cc411 100644 --- a/libavfilter/vf_rotate.c +++ b/libavfilter/vf_rotate.c @@ -415,8 +415,6 @@ static av_always_inline void simple_rotate(uint8_t *dst, const uint8_t *src, int } } -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) { ThreadData *td = arg; diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 0348f19d3..5ad9334d0 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -358,7 +358,7 @@ static int query_formats(AVFilterContext *ctx) return ret; } } - if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->out_formats)) < 0) + if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->outcfg.formats)) < 0) return ret; } if (ctx->outputs[0]) { @@ -372,7 +372,7 @@ static int query_formats(AVFilterContext *ctx) return ret; } } - if ((ret = ff_formats_ref(formats, &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats)) < 0) return ret; } @@ -635,8 +635,8 @@ static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, s int vsub= ((i+1)&2) ? scale->vsub : 0; in_stride[i] = cur_pic->linesize[i] * mul; out_stride[i] = out_buf->linesize[i] * mul; - in[i] = cur_pic->data[i] + ((y>>vsub)+field) * cur_pic->linesize[i]; - out[i] = out_buf->data[i] + field * out_buf->linesize[i]; + in[i] = FF_PTR_ADD(cur_pic->data[i], ((y>>vsub)+field) * cur_pic->linesize[i]); + out[i] = FF_PTR_ADD(out_buf->data[i], field * out_buf->linesize[i]); } if (scale->input_is_pal) in[1] = cur_pic->data[1]; @@ -647,8 +647,6 @@ static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, s out,out_stride); } -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) - static int scale_frame(AVFilterLink *link, AVFrame *in, AVFrame **frame_out) { AVFilterContext *ctx = link->dst; @@ -882,10 +880,19 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar return ret; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *child_class_next(const AVClass *prev) { return prev ? NULL : sws_get_class(); } +#endif + +static const AVClass *child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : sws_get_class(); + *iter = (void*)(uintptr_t)c; + return c; +} #define OFFSET(x) offsetof(ScaleContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM @@ -944,7 +951,10 @@ static const AVClass scale_class = { .option = scale_options, .version = LIBAVUTIL_VERSION_INT, .category = AV_CLASS_CATEGORY_FILTER, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = child_class_next, +#endif + .child_class_iterate = child_class_iterate, }; static const AVFilterPad avfilter_vf_scale_inputs[] = { @@ -984,7 +994,10 @@ static const AVClass scale2ref_class = { .option = scale_options, .version = LIBAVUTIL_VERSION_INT, .category = AV_CLASS_CATEGORY_FILTER, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = child_class_next, +#endif + .child_class_iterate = child_class_iterate, }; static const AVFilterPad avfilter_vf_scale2ref_inputs[] = { diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c index 1ffb73f83..99fef6b22 100644 --- a/libavfilter/vf_scale_cuda.c +++ b/libavfilter/vf_scale_cuda.c @@ -20,6 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include #include #include @@ -38,6 +39,8 @@ #include "scale_eval.h" #include "video.h" +#include "vf_scale_cuda.h" + static const enum AVPixelFormat supported_formats[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12, @@ -45,16 +48,27 @@ static const enum AVPixelFormat supported_formats[] = { AV_PIX_FMT_P010, AV_PIX_FMT_P016, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_0RGB32, + AV_PIX_FMT_0BGR32, }; #define DIV_UP(a, b) ( ((a) + (b) - 1) / (b) ) -#define ALIGN_UP(a, b) (((a) + (b) - 1) & ~((b) - 1)) -#define NUM_BUFFERS 2 #define BLOCKX 32 #define BLOCKY 16 #define CHECK_CU(x) FF_CUDA_CHECK_DL(ctx, s->hwctx->internal->cuda_dl, x) +enum { + INTERP_ALGO_DEFAULT, + + INTERP_ALGO_NEAREST, + INTERP_ALGO_BILINEAR, + INTERP_ALGO_BICUBIC, + INTERP_ALGO_LANCZOS, + + INTERP_ALGO_COUNT +}; + typedef struct CUDAScaleContext { const AVClass *class; @@ -63,11 +77,6 @@ typedef struct CUDAScaleContext { enum AVPixelFormat in_fmt; enum AVPixelFormat out_fmt; - struct { - int width; - int height; - } planes_in[3], planes_out[3]; - AVBufferRef *frames_ctx; AVFrame *frame; @@ -98,6 +107,12 @@ typedef struct CUDAScaleContext { CUdeviceptr srcBuffer; CUdeviceptr dstBuffer; int tex_alignment; + + int interp_algo; + int interp_use_linear; + int interp_as_integer; + + float param; } CUDAScaleContext; static av_cold int cudascale_init(AVFilterContext *ctx) @@ -120,6 +135,16 @@ static av_cold void cudascale_uninit(AVFilterContext *ctx) { CUDAScaleContext *s = ctx->priv; + if (s->hwctx && s->cu_module) { + CudaFunctions *cu = s->hwctx->internal->cuda_dl; + CUcontext dummy; + + CHECK_CU(cu->cuCtxPushCurrent(s->hwctx->cuda_ctx)); + CHECK_CU(cu->cuModuleUnload(s->cu_module)); + s->cu_module = NULL; + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + } + av_frame_free(&s->frame); av_buffer_unref(&s->frames_ctx); av_frame_free(&s->tmp_frame); @@ -131,30 +156,17 @@ static int cudascale_query_formats(AVFilterContext *ctx) AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE, }; AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); + if (!pix_fmts) + return AVERROR(ENOMEM); return ff_set_common_formats(ctx, pix_fmts); } -static av_cold int init_stage(CUDAScaleContext *s, AVBufferRef *device_ctx) +static av_cold int init_hwframe_ctx(CUDAScaleContext *s, AVBufferRef *device_ctx, int width, int height) { AVBufferRef *out_ref = NULL; AVHWFramesContext *out_ctx; - int in_sw, in_sh, out_sw, out_sh; - int ret, i; - - av_pix_fmt_get_chroma_sub_sample(s->in_fmt, &in_sw, &in_sh); - av_pix_fmt_get_chroma_sub_sample(s->out_fmt, &out_sw, &out_sh); - if (!s->planes_out[0].width) { - s->planes_out[0].width = s->planes_in[0].width; - s->planes_out[0].height = s->planes_in[0].height; - } - - for (i = 1; i < FF_ARRAY_ELEMS(s->planes_in); i++) { - s->planes_in[i].width = s->planes_in[0].width >> in_sw; - s->planes_in[i].height = s->planes_in[0].height >> in_sh; - s->planes_out[i].width = s->planes_out[0].width >> out_sw; - s->planes_out[i].height = s->planes_out[0].height >> out_sh; - } + int ret; out_ref = av_hwframe_ctx_alloc(device_ctx); if (!out_ref) @@ -163,8 +175,8 @@ static av_cold int init_stage(CUDAScaleContext *s, AVBufferRef *device_ctx) out_ctx->format = AV_PIX_FMT_CUDA; out_ctx->sw_format = s->out_fmt; - out_ctx->width = FFALIGN(s->planes_out[0].width, 32); - out_ctx->height = FFALIGN(s->planes_out[0].height, 32); + out_ctx->width = FFALIGN(width, 32); + out_ctx->height = FFALIGN(height, 32); ret = av_hwframe_ctx_init(out_ref); if (ret < 0) @@ -175,8 +187,8 @@ static av_cold int init_stage(CUDAScaleContext *s, AVBufferRef *device_ctx) if (ret < 0) goto fail; - s->frame->width = s->planes_out[0].width; - s->frame->height = s->planes_out[0].height; + s->frame->width = width; + s->frame->height = height; av_buffer_unref(&s->frames_ctx); s->frames_ctx = out_ref; @@ -228,20 +240,20 @@ static av_cold int init_processing_chain(AVFilterContext *ctx, int in_width, int return AVERROR(ENOSYS); } - if (in_width == out_width && in_height == out_height) - s->passthrough = 1; - s->in_fmt = in_format; s->out_fmt = out_format; - s->planes_in[0].width = in_width; - s->planes_in[0].height = in_height; - s->planes_out[0].width = out_width; - s->planes_out[0].height = out_height; + if (s->passthrough && in_width == out_width && in_height == out_height && in_format == out_format) { + s->frames_ctx = av_buffer_ref(ctx->inputs[0]->hw_frames_ctx); + if (!s->frames_ctx) + return AVERROR(ENOMEM); + } else { + s->passthrough = 0; - ret = init_stage(s, in_frames_ctx->device_ref); - if (ret < 0) - return ret; + ret = init_hwframe_ctx(s, in_frames_ctx->device_ref, out_width, out_height); + if (ret < 0) + return ret; + } ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->frames_ctx); if (!ctx->outputs[0]->hw_frames_ctx) @@ -259,10 +271,46 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink) AVCUDADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx; CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx; CudaFunctions *cu = device_hwctx->internal->cuda_dl; + char buf[64]; int w, h; int ret; + char *scaler_ptx; + const char *function_infix = ""; + extern char vf_scale_cuda_ptx[]; + extern char vf_scale_cuda_bicubic_ptx[]; + + switch(s->interp_algo) { + case INTERP_ALGO_NEAREST: + scaler_ptx = vf_scale_cuda_ptx; + function_infix = "_Nearest"; + s->interp_use_linear = 0; + s->interp_as_integer = 1; + break; + case INTERP_ALGO_BILINEAR: + scaler_ptx = vf_scale_cuda_ptx; + function_infix = "_Bilinear"; + s->interp_use_linear = 1; + s->interp_as_integer = 1; + break; + case INTERP_ALGO_DEFAULT: + case INTERP_ALGO_BICUBIC: + scaler_ptx = vf_scale_cuda_bicubic_ptx; + function_infix = "_Bicubic"; + s->interp_use_linear = 0; + s->interp_as_integer = 0; + break; + case INTERP_ALGO_LANCZOS: + scaler_ptx = vf_scale_cuda_bicubic_ptx; + function_infix = "_Lanczos"; + s->interp_use_linear = 0; + s->interp_as_integer = 0; + break; + default: + av_log(ctx, AV_LOG_ERROR, "Unknown interpolation algorithm\n"); + return AVERROR_BUG; + } s->hwctx = device_hwctx; s->cu_stream = s->hwctx->stream; @@ -271,31 +319,37 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink) if (ret < 0) goto fail; - ret = CHECK_CU(cu->cuModuleLoadData(&s->cu_module, vf_scale_cuda_ptx)); + ret = CHECK_CU(cu->cuModuleLoadData(&s->cu_module, scaler_ptx)); if (ret < 0) goto fail; - CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_uchar, s->cu_module, "Subsample_Bilinear_uchar")); + snprintf(buf, sizeof(buf), "Subsample%s_uchar", function_infix); + CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_uchar, s->cu_module, buf)); if (ret < 0) goto fail; - CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_uchar2, s->cu_module, "Subsample_Bilinear_uchar2")); + snprintf(buf, sizeof(buf), "Subsample%s_uchar2", function_infix); + CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_uchar2, s->cu_module, buf)); if (ret < 0) goto fail; - CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_uchar4, s->cu_module, "Subsample_Bilinear_uchar4")); + snprintf(buf, sizeof(buf), "Subsample%s_uchar4", function_infix); + CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_uchar4, s->cu_module, buf)); if (ret < 0) goto fail; - CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_ushort, s->cu_module, "Subsample_Bilinear_ushort")); + snprintf(buf, sizeof(buf), "Subsample%s_ushort", function_infix); + CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_ushort, s->cu_module, buf)); if (ret < 0) goto fail; - CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_ushort2, s->cu_module, "Subsample_Bilinear_ushort2")); + snprintf(buf, sizeof(buf), "Subsample%s_ushort2", function_infix); + CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_ushort2, s->cu_module, buf)); if (ret < 0) goto fail; - CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_ushort4, s->cu_module, "Subsample_Bilinear_ushort4")); + snprintf(buf, sizeof(buf), "Subsample%s_ushort4", function_infix); + CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_ushort4, s->cu_module, buf)); if (ret < 0) goto fail; @@ -322,8 +376,8 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink) if (ret < 0) return ret; - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n", - inlink->w, inlink->h, outlink->w, outlink->h); + av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d%s\n", + inlink->w, inlink->h, outlink->w, outlink->h, s->passthrough ? " (passthrough)" : ""); if (inlink->sample_aspect_ratio.num) { outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w, @@ -342,18 +396,21 @@ fail: static int call_resize_kernel(AVFilterContext *ctx, CUfunction func, int channels, uint8_t *src_dptr, int src_width, int src_height, int src_pitch, uint8_t *dst_dptr, int dst_width, int dst_height, int dst_pitch, - int pixel_size) + int pixel_size, int bit_depth) { CUDAScaleContext *s = ctx->priv; CudaFunctions *cu = s->hwctx->internal->cuda_dl; CUdeviceptr dst_devptr = (CUdeviceptr)dst_dptr; CUtexObject tex = 0; - void *args_uchar[] = { &tex, &dst_devptr, &dst_width, &dst_height, &dst_pitch, &src_width, &src_height }; + void *args_uchar[] = { &tex, &dst_devptr, &dst_width, &dst_height, &dst_pitch, + &src_width, &src_height, &bit_depth, &s->param }; int ret; CUDA_TEXTURE_DESC tex_desc = { - .filterMode = CU_TR_FILTER_MODE_LINEAR, - .flags = CU_TRSF_READ_AS_INTEGER, + .filterMode = s->interp_use_linear ? + CU_TR_FILTER_MODE_LINEAR : + CU_TR_FILTER_MODE_POINT, + .flags = s->interp_as_integer ? CU_TRSF_READ_AS_INTEGER : 0, }; CUDA_RESOURCE_DESC res_desc = { @@ -364,10 +421,14 @@ static int call_resize_kernel(AVFilterContext *ctx, CUfunction func, int channel .res.pitch2D.numChannels = channels, .res.pitch2D.width = src_width, .res.pitch2D.height = src_height, - .res.pitch2D.pitchInBytes = src_pitch * pixel_size, + .res.pitch2D.pitchInBytes = src_pitch, .res.pitch2D.devPtr = (CUdeviceptr)src_dptr, }; + // Handling of channels is done via vector-types in cuda, so their size is implicitly part of the pitch + // Same for pixel_size, which is represented via datatypes on the cuda side of things. + dst_pitch /= channels * pixel_size; + ret = CHECK_CU(cu->cuTexObjectCreate(&tex, &res_desc, &tex_desc, NULL)); if (ret < 0) goto exit; @@ -394,73 +455,80 @@ static int scalecuda_resize(AVFilterContext *ctx, call_resize_kernel(ctx, s->cu_func_uchar, 1, in->data[0], in->width, in->height, in->linesize[0], out->data[0], out->width, out->height, out->linesize[0], - 1); + 1, 8); call_resize_kernel(ctx, s->cu_func_uchar, 1, - in->data[1], in->width/2, in->height/2, in->linesize[0]/2, - out->data[1], out->width/2, out->height/2, out->linesize[0]/2, - 1); + in->data[1], in->width / 2, in->height / 2, in->linesize[1], + out->data[1], out->width / 2, out->height / 2, out->linesize[1], + 1, 8); call_resize_kernel(ctx, s->cu_func_uchar, 1, - in->data[2], in->width/2, in->height/2, in->linesize[0]/2, - out->data[2], out->width/2, out->height/2, out->linesize[0]/2, - 1); + in->data[2], in->width / 2, in->height / 2, in->linesize[2], + out->data[2], out->width / 2, out->height / 2, out->linesize[2], + 1, 8); break; case AV_PIX_FMT_YUV444P: call_resize_kernel(ctx, s->cu_func_uchar, 1, in->data[0], in->width, in->height, in->linesize[0], out->data[0], out->width, out->height, out->linesize[0], - 1); + 1, 8); call_resize_kernel(ctx, s->cu_func_uchar, 1, - in->data[1], in->width, in->height, in->linesize[0], - out->data[1], out->width, out->height, out->linesize[0], - 1); + in->data[1], in->width, in->height, in->linesize[1], + out->data[1], out->width, out->height, out->linesize[1], + 1, 8); call_resize_kernel(ctx, s->cu_func_uchar, 1, - in->data[2], in->width, in->height, in->linesize[0], - out->data[2], out->width, out->height, out->linesize[0], - 1); + in->data[2], in->width, in->height, in->linesize[2], + out->data[2], out->width, out->height, out->linesize[2], + 1, 8); break; case AV_PIX_FMT_YUV444P16: call_resize_kernel(ctx, s->cu_func_ushort, 1, - in->data[0], in->width, in->height, in->linesize[0] / 2, - out->data[0], out->width, out->height, out->linesize[0] / 2, - 2); + in->data[0], in->width, in->height, in->linesize[0], + out->data[0], out->width, out->height, out->linesize[0], + 2, 16); call_resize_kernel(ctx, s->cu_func_ushort, 1, - in->data[1], in->width, in->height, in->linesize[1] / 2, - out->data[1], out->width, out->height, out->linesize[1] / 2, - 2); + in->data[1], in->width, in->height, in->linesize[1], + out->data[1], out->width, out->height, out->linesize[1], + 2, 16); call_resize_kernel(ctx, s->cu_func_ushort, 1, - in->data[2], in->width, in->height, in->linesize[2] / 2, - out->data[2], out->width, out->height, out->linesize[2] / 2, - 2); + in->data[2], in->width, in->height, in->linesize[2], + out->data[2], out->width, out->height, out->linesize[2], + 2, 16); break; case AV_PIX_FMT_NV12: call_resize_kernel(ctx, s->cu_func_uchar, 1, in->data[0], in->width, in->height, in->linesize[0], out->data[0], out->width, out->height, out->linesize[0], - 1); + 1, 8); call_resize_kernel(ctx, s->cu_func_uchar2, 2, - in->data[1], in->width/2, in->height/2, in->linesize[1], - out->data[1], out->width/2, out->height/2, out->linesize[1]/2, - 1); + in->data[1], in->width / 2, in->height / 2, in->linesize[1], + out->data[1], out->width / 2, out->height / 2, out->linesize[1], + 1, 8); break; case AV_PIX_FMT_P010LE: call_resize_kernel(ctx, s->cu_func_ushort, 1, - in->data[0], in->width, in->height, in->linesize[0]/2, - out->data[0], out->width, out->height, out->linesize[0]/2, - 2); + in->data[0], in->width, in->height, in->linesize[0], + out->data[0], out->width, out->height, out->linesize[0], + 2, 10); call_resize_kernel(ctx, s->cu_func_ushort2, 2, - in->data[1], in->width / 2, in->height / 2, in->linesize[1]/2, - out->data[1], out->width / 2, out->height / 2, out->linesize[1] / 4, - 2); + in->data[1], in->width / 2, in->height / 2, in->linesize[1], + out->data[1], out->width / 2, out->height / 2, out->linesize[1], + 2, 10); break; case AV_PIX_FMT_P016LE: call_resize_kernel(ctx, s->cu_func_ushort, 1, - in->data[0], in->width, in->height, in->linesize[0] / 2, - out->data[0], out->width, out->height, out->linesize[0] / 2, - 2); + in->data[0], in->width, in->height, in->linesize[0], + out->data[0], out->width, out->height, out->linesize[0], + 2, 16); call_resize_kernel(ctx, s->cu_func_ushort2, 2, - in->data[1], in->width / 2, in->height / 2, in->linesize[1] / 2, - out->data[1], out->width / 2, out->height / 2, out->linesize[1] / 4, - 2); + in->data[1], in->width / 2, in->height / 2, in->linesize[1], + out->data[1], out->width / 2, out->height / 2, out->linesize[1], + 2, 16); + break; + case AV_PIX_FMT_0RGB32: + case AV_PIX_FMT_0BGR32: + call_resize_kernel(ctx, s->cu_func_uchar4, 4, + in->data[0], in->width, in->height, in->linesize[0], + out->data[0], out->width, out->height, out->linesize[0], + 1, 8); break; default: return AVERROR_BUG; @@ -472,6 +540,7 @@ static int scalecuda_resize(AVFilterContext *ctx, static int cudascale_scale(AVFilterContext *ctx, AVFrame *out, AVFrame *in) { CUDAScaleContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; AVFrame *src = in; int ret; @@ -487,8 +556,8 @@ static int cudascale_scale(AVFilterContext *ctx, AVFrame *out, AVFrame *in) av_frame_move_ref(out, s->frame); av_frame_move_ref(s->frame, s->tmp_frame); - s->frame->width = s->planes_out[0].width; - s->frame->height = s->planes_out[0].height; + s->frame->width = outlink->w; + s->frame->height = outlink->h; ret = av_frame_copy_props(out, in); if (ret < 0) @@ -508,6 +577,9 @@ static int cudascale_filter_frame(AVFilterLink *link, AVFrame *in) CUcontext dummy; int ret = 0; + if (s->passthrough) + return ff_filter_frame(outlink, in); + out = av_frame_alloc(); if (!out) { ret = AVERROR(ENOMEM); @@ -537,16 +609,32 @@ fail: return ret; } +static AVFrame *cudascale_get_video_buffer(AVFilterLink *inlink, int w, int h) +{ + CUDAScaleContext *s = inlink->dst->priv; + + return s->passthrough ? + ff_null_get_video_buffer (inlink, w, h) : + ff_default_get_video_buffer(inlink, w, h); +} + #define OFFSET(x) offsetof(CUDAScaleContext, x) #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM) static const AVOption options[] = { - { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, - { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, - { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, "force_oar" }, - { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" }, - { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" }, - { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" }, - { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS }, + { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, + { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, + { "interp_algo", "Interpolation algorithm used for resizing", OFFSET(interp_algo), AV_OPT_TYPE_INT, { .i64 = INTERP_ALGO_DEFAULT }, 0, INTERP_ALGO_COUNT - 1, FLAGS, "interp_algo" }, + { "nearest", "nearest neighbour", 0, AV_OPT_TYPE_CONST, { .i64 = INTERP_ALGO_NEAREST }, 0, 0, FLAGS, "interp_algo" }, + { "bilinear", "bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = INTERP_ALGO_BILINEAR }, 0, 0, FLAGS, "interp_algo" }, + { "bicubic", "bicubic", 0, AV_OPT_TYPE_CONST, { .i64 = INTERP_ALGO_BICUBIC }, 0, 0, FLAGS, "interp_algo" }, + { "lanczos", "lanczos", 0, AV_OPT_TYPE_CONST, { .i64 = INTERP_ALGO_LANCZOS }, 0, 0, FLAGS, "interp_algo" }, + { "passthrough", "Do not process frames at all if parameters match", OFFSET(passthrough), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, + { "param", "Algorithm-Specific parameter", OFFSET(param), AV_OPT_TYPE_FLOAT, { .dbl = SCALE_CUDA_PARAM_DEFAULT }, -FLT_MAX, FLT_MAX, FLAGS }, + { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, FLAGS, "force_oar" }, + { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" }, + { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" }, + { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" }, + { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256, FLAGS }, { NULL }, }; @@ -562,6 +650,7 @@ static const AVFilterPad cudascale_inputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .filter_frame = cudascale_filter_frame, + .get_video_buffer = cudascale_get_video_buffer, }, { NULL } }; diff --git a/libavfilter/vf_scale_cuda.cu b/libavfilter/vf_scale_cuda.cu index 3f3f40546..44eef535f 100644 --- a/libavfilter/vf_scale_cuda.cu +++ b/libavfilter/vf_scale_cuda.cu @@ -20,192 +20,104 @@ * DEALINGS IN THE SOFTWARE. */ +#include "cuda/vector_helpers.cuh" + +template +__device__ inline void Subsample_Nearest(cudaTextureObject_t tex, + T *dst, + int dst_width, int dst_height, int dst_pitch, + int src_width, int src_height, + int bit_depth) +{ + int xo = blockIdx.x * blockDim.x + threadIdx.x; + int yo = blockIdx.y * blockDim.y + threadIdx.y; + + if (yo < dst_height && xo < dst_width) + { + float hscale = (float)src_width / (float)dst_width; + float vscale = (float)src_height / (float)dst_height; + float xi = (xo + 0.5f) * hscale; + float yi = (yo + 0.5f) * vscale; + + dst[yo*dst_pitch+xo] = tex2D(tex, xi, yi); + } +} + +template +__device__ inline void Subsample_Bilinear(cudaTextureObject_t tex, + T *dst, + int dst_width, int dst_height, int dst_pitch, + int src_width, int src_height, + int bit_depth) +{ + int xo = blockIdx.x * blockDim.x + threadIdx.x; + int yo = blockIdx.y * blockDim.y + threadIdx.y; + + if (yo < dst_height && xo < dst_width) + { + float hscale = (float)src_width / (float)dst_width; + float vscale = (float)src_height / (float)dst_height; + float xi = (xo + 0.5f) * hscale; + float yi = (yo + 0.5f) * vscale; + // 3-tap filter weights are {wh,1.0,wh} and {wv,1.0,wv} + float wh = min(max(0.5f * (hscale - 1.0f), 0.0f), 1.0f); + float wv = min(max(0.5f * (vscale - 1.0f), 0.0f), 1.0f); + // Convert weights to two bilinear weights -> {wh,1.0,wh} -> {wh,0.5,0} + {0,0.5,wh} + float dx = wh / (0.5f + wh); + float dy = wv / (0.5f + wv); + + intT r = { 0 }; + vec_set_scalar(r, 2); + r += tex2D(tex, xi - dx, yi - dy); + r += tex2D(tex, xi + dx, yi - dy); + r += tex2D(tex, xi - dx, yi + dy); + r += tex2D(tex, xi + dx, yi + dy); + vec_set(dst[yo*dst_pitch+xo], r >> 2); + } +} + extern "C" { -__global__ void Subsample_Bilinear_uchar(cudaTextureObject_t uchar_tex, - unsigned char *dst, - int dst_width, int dst_height, int dst_pitch, - int src_width, int src_height) -{ - int xo = blockIdx.x * blockDim.x + threadIdx.x; - int yo = blockIdx.y * blockDim.y + threadIdx.y; - - if (yo < dst_height && xo < dst_width) - { - float hscale = (float)src_width / (float)dst_width; - float vscale = (float)src_height / (float)dst_height; - float xi = (xo + 0.5f) * hscale; - float yi = (yo + 0.5f) * vscale; - // 3-tap filter weights are {wh,1.0,wh} and {wv,1.0,wv} - float wh = min(max(0.5f * (hscale - 1.0f), 0.0f), 1.0f); - float wv = min(max(0.5f * (vscale - 1.0f), 0.0f), 1.0f); - // Convert weights to two bilinear weights -> {wh,1.0,wh} -> {wh,0.5,0} + {0,0.5,wh} - float dx = wh / (0.5f + wh); - float dy = wv / (0.5f + wv); - int y0 = tex2D(uchar_tex, xi-dx, yi-dy); - int y1 = tex2D(uchar_tex, xi+dx, yi-dy); - int y2 = tex2D(uchar_tex, xi-dx, yi+dy); - int y3 = tex2D(uchar_tex, xi+dx, yi+dy); - dst[yo*dst_pitch+xo] = (unsigned char)((y0+y1+y2+y3+2) >> 2); +#define NEAREST_KERNEL(T) \ + __global__ void Subsample_Nearest_ ## T(cudaTextureObject_t src_tex, \ + T *dst, \ + int dst_width, int dst_height, int dst_pitch, \ + int src_width, int src_height, \ + int bit_depth) \ + { \ + Subsample_Nearest(src_tex, dst, \ + dst_width, dst_height, dst_pitch, \ + src_width, src_height, \ + bit_depth); \ } -} -__global__ void Subsample_Bilinear_uchar2(cudaTextureObject_t uchar2_tex, - uchar2 *dst, - int dst_width, int dst_height, int dst_pitch2, - int src_width, int src_height) -{ - int xo = blockIdx.x * blockDim.x + threadIdx.x; - int yo = blockIdx.y * blockDim.y + threadIdx.y; +NEAREST_KERNEL(uchar) +NEAREST_KERNEL(uchar2) +NEAREST_KERNEL(uchar4) - if (yo < dst_height && xo < dst_width) - { - float hscale = (float)src_width / (float)dst_width; - float vscale = (float)src_height / (float)dst_height; - float xi = (xo + 0.5f) * hscale; - float yi = (yo + 0.5f) * vscale; - // 3-tap filter weights are {wh,1.0,wh} and {wv,1.0,wv} - float wh = min(max(0.5f * (hscale - 1.0f), 0.0f), 1.0f); - float wv = min(max(0.5f * (vscale - 1.0f), 0.0f), 1.0f); - // Convert weights to two bilinear weights -> {wh,1.0,wh} -> {wh,0.5,0} + {0,0.5,wh} - float dx = wh / (0.5f + wh); - float dy = wv / (0.5f + wv); - uchar2 c0 = tex2D(uchar2_tex, xi-dx, yi-dy); - uchar2 c1 = tex2D(uchar2_tex, xi+dx, yi-dy); - uchar2 c2 = tex2D(uchar2_tex, xi-dx, yi+dy); - uchar2 c3 = tex2D(uchar2_tex, xi+dx, yi+dy); - int2 uv; - uv.x = ((int)c0.x+(int)c1.x+(int)c2.x+(int)c3.x+2) >> 2; - uv.y = ((int)c0.y+(int)c1.y+(int)c2.y+(int)c3.y+2) >> 2; - dst[yo*dst_pitch2+xo] = make_uchar2((unsigned char)uv.x, (unsigned char)uv.y); +NEAREST_KERNEL(ushort) +NEAREST_KERNEL(ushort2) +NEAREST_KERNEL(ushort4) + +#define BILINEAR_KERNEL(T) \ + __global__ void Subsample_Bilinear_ ## T(cudaTextureObject_t src_tex, \ + T *dst, \ + int dst_width, int dst_height, int dst_pitch, \ + int src_width, int src_height, \ + int bit_depth) \ + { \ + Subsample_Bilinear(src_tex, dst, \ + dst_width, dst_height, dst_pitch, \ + src_width, src_height, \ + bit_depth); \ } -} -__global__ void Subsample_Bilinear_uchar4(cudaTextureObject_t uchar4_tex, - uchar4 *dst, - int dst_width, int dst_height, int dst_pitch, - int src_width, int src_height) -{ - int xo = blockIdx.x * blockDim.x + threadIdx.x; - int yo = blockIdx.y * blockDim.y + threadIdx.y; +BILINEAR_KERNEL(uchar) +BILINEAR_KERNEL(uchar2) +BILINEAR_KERNEL(uchar4) - if (yo < dst_height && xo < dst_width) - { - float hscale = (float)src_width / (float)dst_width; - float vscale = (float)src_height / (float)dst_height; - float xi = (xo + 0.5f) * hscale; - float yi = (yo + 0.5f) * vscale; - // 3-tap filter weights are {wh,1.0,wh} and {wv,1.0,wv} - float wh = min(max(0.5f * (hscale - 1.0f), 0.0f), 1.0f); - float wv = min(max(0.5f * (vscale - 1.0f), 0.0f), 1.0f); - // Convert weights to two bilinear weights -> {wh,1.0,wh} -> {wh,0.5,0} + {0,0.5,wh} - float dx = wh / (0.5f + wh); - float dy = wv / (0.5f + wv); - uchar4 c0 = tex2D(uchar4_tex, xi-dx, yi-dy); - uchar4 c1 = tex2D(uchar4_tex, xi+dx, yi-dy); - uchar4 c2 = tex2D(uchar4_tex, xi-dx, yi+dy); - uchar4 c3 = tex2D(uchar4_tex, xi+dx, yi+dy); - int4 res; - res.x = ((int)c0.x+(int)c1.x+(int)c2.x+(int)c3.x+2) >> 2; - res.y = ((int)c0.y+(int)c1.y+(int)c2.y+(int)c3.y+2) >> 2; - res.z = ((int)c0.z+(int)c1.z+(int)c2.z+(int)c3.z+2) >> 2; - res.w = ((int)c0.w+(int)c1.w+(int)c2.w+(int)c3.w+2) >> 2; - dst[yo*dst_pitch+xo] = make_uchar4( - (unsigned char)res.x, (unsigned char)res.y, (unsigned char)res.z, (unsigned char)res.w); - } -} - -__global__ void Subsample_Bilinear_ushort(cudaTextureObject_t ushort_tex, - unsigned short *dst, - int dst_width, int dst_height, int dst_pitch, - int src_width, int src_height) -{ - int xo = blockIdx.x * blockDim.x + threadIdx.x; - int yo = blockIdx.y * blockDim.y + threadIdx.y; - - if (yo < dst_height && xo < dst_width) - { - float hscale = (float)src_width / (float)dst_width; - float vscale = (float)src_height / (float)dst_height; - float xi = (xo + 0.5f) * hscale; - float yi = (yo + 0.5f) * vscale; - // 3-tap filter weights are {wh,1.0,wh} and {wv,1.0,wv} - float wh = min(max(0.5f * (hscale - 1.0f), 0.0f), 1.0f); - float wv = min(max(0.5f * (vscale - 1.0f), 0.0f), 1.0f); - // Convert weights to two bilinear weights -> {wh,1.0,wh} -> {wh,0.5,0} + {0,0.5,wh} - float dx = wh / (0.5f + wh); - float dy = wv / (0.5f + wv); - int y0 = tex2D(ushort_tex, xi-dx, yi-dy); - int y1 = tex2D(ushort_tex, xi+dx, yi-dy); - int y2 = tex2D(ushort_tex, xi-dx, yi+dy); - int y3 = tex2D(ushort_tex, xi+dx, yi+dy); - dst[yo*dst_pitch+xo] = (unsigned short)((y0+y1+y2+y3+2) >> 2); - } -} - -__global__ void Subsample_Bilinear_ushort2(cudaTextureObject_t ushort2_tex, - ushort2 *dst, - int dst_width, int dst_height, int dst_pitch2, - int src_width, int src_height) -{ - int xo = blockIdx.x * blockDim.x + threadIdx.x; - int yo = blockIdx.y * blockDim.y + threadIdx.y; - - if (yo < dst_height && xo < dst_width) - { - float hscale = (float)src_width / (float)dst_width; - float vscale = (float)src_height / (float)dst_height; - float xi = (xo + 0.5f) * hscale; - float yi = (yo + 0.5f) * vscale; - // 3-tap filter weights are {wh,1.0,wh} and {wv,1.0,wv} - float wh = min(max(0.5f * (hscale - 1.0f), 0.0f), 1.0f); - float wv = min(max(0.5f * (vscale - 1.0f), 0.0f), 1.0f); - // Convert weights to two bilinear weights -> {wh,1.0,wh} -> {wh,0.5,0} + {0,0.5,wh} - float dx = wh / (0.5f + wh); - float dy = wv / (0.5f + wv); - ushort2 c0 = tex2D(ushort2_tex, xi-dx, yi-dy); - ushort2 c1 = tex2D(ushort2_tex, xi+dx, yi-dy); - ushort2 c2 = tex2D(ushort2_tex, xi-dx, yi+dy); - ushort2 c3 = tex2D(ushort2_tex, xi+dx, yi+dy); - int2 uv; - uv.x = ((int)c0.x+(int)c1.x+(int)c2.x+(int)c3.x+2) >> 2; - uv.y = ((int)c0.y+(int)c1.y+(int)c2.y+(int)c3.y+2) >> 2; - dst[yo*dst_pitch2+xo] = make_ushort2((unsigned short)uv.x, (unsigned short)uv.y); - } -} - -__global__ void Subsample_Bilinear_ushort4(cudaTextureObject_t ushort4_tex, - ushort4 *dst, - int dst_width, int dst_height, int dst_pitch, - int src_width, int src_height) -{ - int xo = blockIdx.x * blockDim.x + threadIdx.x; - int yo = blockIdx.y * blockDim.y + threadIdx.y; - - if (yo < dst_height && xo < dst_width) - { - float hscale = (float)src_width / (float)dst_width; - float vscale = (float)src_height / (float)dst_height; - float xi = (xo + 0.5f) * hscale; - float yi = (yo + 0.5f) * vscale; - // 3-tap filter weights are {wh,1.0,wh} and {wv,1.0,wv} - float wh = min(max(0.5f * (hscale - 1.0f), 0.0f), 1.0f); - float wv = min(max(0.5f * (vscale - 1.0f), 0.0f), 1.0f); - // Convert weights to two bilinear weights -> {wh,1.0,wh} -> {wh,0.5,0} + {0,0.5,wh} - float dx = wh / (0.5f + wh); - float dy = wv / (0.5f + wv); - ushort4 c0 = tex2D(ushort4_tex, xi-dx, yi-dy); - ushort4 c1 = tex2D(ushort4_tex, xi+dx, yi-dy); - ushort4 c2 = tex2D(ushort4_tex, xi-dx, yi+dy); - ushort4 c3 = tex2D(ushort4_tex, xi+dx, yi+dy); - int4 res; - res.x = ((int)c0.x+(int)c1.x+(int)c2.x+(int)c3.x+2) >> 2; - res.y = ((int)c0.y+(int)c1.y+(int)c2.y+(int)c3.y+2) >> 2; - res.z = ((int)c0.z+(int)c1.z+(int)c2.z+(int)c3.z+2) >> 2; - res.w = ((int)c0.w+(int)c1.w+(int)c2.w+(int)c3.w+2) >> 2; - dst[yo*dst_pitch+xo] = make_ushort4( - (unsigned short)res.x, (unsigned short)res.y, (unsigned short)res.z, (unsigned short)res.w); - } -} +BILINEAR_KERNEL(ushort) +BILINEAR_KERNEL(ushort2) +BILINEAR_KERNEL(ushort4) } diff --git a/libavfilter/vf_scale_cuda.h b/libavfilter/vf_scale_cuda.h new file mode 100644 index 000000000..40d5b9cfa --- /dev/null +++ b/libavfilter/vf_scale_cuda.h @@ -0,0 +1,28 @@ +/* + * This file is part of FFmpeg. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVFILTER_SCALE_CUDA_H +#define AVFILTER_SCALE_CUDA_H + +#define SCALE_CUDA_PARAM_DEFAULT 999999.0f + +#endif diff --git a/libavfilter/vf_scale_cuda_bicubic.cu b/libavfilter/vf_scale_cuda_bicubic.cu new file mode 100644 index 000000000..554667383 --- /dev/null +++ b/libavfilter/vf_scale_cuda_bicubic.cu @@ -0,0 +1,224 @@ +/* + * This file is part of FFmpeg. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "cuda/vector_helpers.cuh" +#include "vf_scale_cuda.h" + +typedef float4 (*coeffs_function_t)(float, float); + +__device__ inline float4 lanczos_coeffs(float x, float param) +{ + const float pi = 3.141592654f; + + float4 res = make_float4( + pi * (x + 1), + pi * x, + pi * (x - 1), + pi * (x - 2)); + + res.x = res.x == 0.0f ? 1.0f : + __sinf(res.x) * __sinf(res.x / 2.0f) / (res.x * res.x / 2.0f); + res.y = res.y == 0.0f ? 1.0f : + __sinf(res.y) * __sinf(res.y / 2.0f) / (res.y * res.y / 2.0f); + res.z = res.z == 0.0f ? 1.0f : + __sinf(res.z) * __sinf(res.z / 2.0f) / (res.z * res.z / 2.0f); + res.w = res.w == 0.0f ? 1.0f : + __sinf(res.w) * __sinf(res.w / 2.0f) / (res.w * res.w / 2.0f); + + return res / (res.x + res.y + res.z + res.w); +} + +__device__ inline float4 bicubic_coeffs(float x, float param) +{ + const float A = param == SCALE_CUDA_PARAM_DEFAULT ? 0.0f : -param; + + float4 res; + res.x = ((A * (x + 1) - 5 * A) * (x + 1) + 8 * A) * (x + 1) - 4 * A; + res.y = ((A + 2) * x - (A + 3)) * x * x + 1; + res.z = ((A + 2) * (1 - x) - (A + 3)) * (1 - x) * (1 - x) + 1; + res.w = 1.0f - res.x - res.y - res.z; + + return res; +} + +__device__ inline void derived_fast_coeffs(float4 coeffs, float x, float *h0, float *h1, float *s) +{ + float g0 = coeffs.x + coeffs.y; + float g1 = coeffs.z + coeffs.w; + + *h0 = coeffs.y / g0 - 0.5f; + *h1 = coeffs.w / g1 + 1.5f; + *s = g0 / (g0 + g1); +} + +template +__device__ inline V apply_coeffs(float4 coeffs, V c0, V c1, V c2, V c3) +{ + V res = c0 * coeffs.x; + res += c1 * coeffs.y; + res += c2 * coeffs.z; + res += c3 * coeffs.w; + + return res; +} + +template +__device__ inline void Subsample_Bicubic(coeffs_function_t coeffs_function, + cudaTextureObject_t src_tex, + T *dst, + int dst_width, int dst_height, int dst_pitch, + int src_width, int src_height, + int bit_depth, float param) +{ + int xo = blockIdx.x * blockDim.x + threadIdx.x; + int yo = blockIdx.y * blockDim.y + threadIdx.y; + + if (yo < dst_height && xo < dst_width) + { + float hscale = (float)src_width / (float)dst_width; + float vscale = (float)src_height / (float)dst_height; + float xi = (xo + 0.5f) * hscale - 0.5f; + float yi = (yo + 0.5f) * vscale - 0.5f; + float px = floor(xi); + float py = floor(yi); + float fx = xi - px; + float fy = yi - py; + + float factor = bit_depth > 8 ? 0xFFFF : 0xFF; + + float4 coeffsX = coeffs_function(fx, param); + float4 coeffsY = coeffs_function(fy, param); + +#define PIX(x, y) tex2D(src_tex, (x), (y)) + + dst[yo * dst_pitch + xo] = from_floatN( + apply_coeffs(coeffsY, + apply_coeffs(coeffsX, PIX(px - 1, py - 1), PIX(px, py - 1), PIX(px + 1, py - 1), PIX(px + 2, py - 1)), + apply_coeffs(coeffsX, PIX(px - 1, py ), PIX(px, py ), PIX(px + 1, py ), PIX(px + 2, py )), + apply_coeffs(coeffsX, PIX(px - 1, py + 1), PIX(px, py + 1), PIX(px + 1, py + 1), PIX(px + 2, py + 1)), + apply_coeffs(coeffsX, PIX(px - 1, py + 2), PIX(px, py + 2), PIX(px + 1, py + 2), PIX(px + 2, py + 2)) + ) * factor + ); + +#undef PIX + } +} + +/* This does not yield correct results. Most likely because of low internal precision in tex2D linear interpolation */ +template +__device__ inline void Subsample_FastBicubic(coeffs_function_t coeffs_function, + cudaTextureObject_t src_tex, + T *dst, + int dst_width, int dst_height, int dst_pitch, + int src_width, int src_height, + int bit_depth, float param) +{ + int xo = blockIdx.x * blockDim.x + threadIdx.x; + int yo = blockIdx.y * blockDim.y + threadIdx.y; + + if (yo < dst_height && xo < dst_width) + { + float hscale = (float)src_width / (float)dst_width; + float vscale = (float)src_height / (float)dst_height; + float xi = (xo + 0.5f) * hscale - 0.5f; + float yi = (yo + 0.5f) * vscale - 0.5f; + float px = floor(xi); + float py = floor(yi); + float fx = xi - px; + float fy = yi - py; + + float factor = bit_depth > 8 ? 0xFFFF : 0xFF; + + float4 coeffsX = coeffs_function(fx, param); + float4 coeffsY = coeffs_function(fy, param); + + float h0x, h1x, sx; + float h0y, h1y, sy; + derived_fast_coeffs(coeffsX, fx, &h0x, &h1x, &sx); + derived_fast_coeffs(coeffsY, fy, &h0y, &h1y, &sy); + +#define PIX(x, y) tex2D(src_tex, (x), (y)) + + floatT pix[4] = { + PIX(px + h0x, py + h0y), + PIX(px + h1x, py + h0y), + PIX(px + h0x, py + h1y), + PIX(px + h1x, py + h1y) + }; + +#undef PIX + + dst[yo * dst_pitch + xo] = from_floatN( + lerp_scalar( + lerp_scalar(pix[3], pix[2], sx), + lerp_scalar(pix[1], pix[0], sx), + sy) * factor + ); + } +} + +extern "C" { + +#define BICUBIC_KERNEL(T) \ + __global__ void Subsample_Bicubic_ ## T(cudaTextureObject_t src_tex, \ + T *dst, \ + int dst_width, int dst_height, int dst_pitch, \ + int src_width, int src_height, \ + int bit_depth, float param) \ + { \ + Subsample_Bicubic(&bicubic_coeffs, src_tex, dst, \ + dst_width, dst_height, dst_pitch, \ + src_width, src_height, \ + bit_depth, param); \ + } + +BICUBIC_KERNEL(uchar) +BICUBIC_KERNEL(uchar2) +BICUBIC_KERNEL(uchar4) + +BICUBIC_KERNEL(ushort) +BICUBIC_KERNEL(ushort2) +BICUBIC_KERNEL(ushort4) + + +#define LANCZOS_KERNEL(T) \ + __global__ void Subsample_Lanczos_ ## T(cudaTextureObject_t src_tex, \ + T *dst, \ + int dst_width, int dst_height, int dst_pitch, \ + int src_width, int src_height, \ + int bit_depth, float param) \ + { \ + Subsample_Bicubic(&lanczos_coeffs, src_tex, dst, \ + dst_width, dst_height, dst_pitch, \ + src_width, src_height, \ + bit_depth, param); \ + } + +LANCZOS_KERNEL(uchar) +LANCZOS_KERNEL(uchar2) +LANCZOS_KERNEL(uchar4) + +LANCZOS_KERNEL(ushort) +LANCZOS_KERNEL(ushort2) +LANCZOS_KERNEL(ushort4) + +} diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index 5064dcbb6..2ac237395 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -313,8 +313,10 @@ static int init_out_session(AVFilterContext *ctx) } } - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error getting the session handle\n"); + if (err < 0) + return ff_qsvvpp_print_error(ctx, err, "Error getting the session handle"); + else if (err > 0) { + ff_qsvvpp_print_warning(ctx, err, "Warning in getting the session handle"); return AVERROR_UNKNOWN; } @@ -430,9 +432,17 @@ static int init_out_session(AVFilterContext *ctx) par.vpp.Out.FrameRateExtN = 25; par.vpp.Out.FrameRateExtD = 1; + /* Print input memory mode */ + ff_qsvvpp_print_iopattern(ctx, par.IOPattern & 0x0F, "VPP"); + /* Print output memory mode */ + ff_qsvvpp_print_iopattern(ctx, par.IOPattern & 0xF0, "VPP"); err = MFXVideoVPP_Init(s->session, &par); - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error opening the VPP for scaling\n"); + if (err < 0) + return ff_qsvvpp_print_error(ctx, err, + "Error opening the VPP for scaling"); + else if (err > 0) { + ff_qsvvpp_print_warning(ctx, err, + "Warning in VPP initialization"); return AVERROR_UNKNOWN; } @@ -573,8 +583,13 @@ static int qsvscale_filter_frame(AVFilterLink *link, AVFrame *in) av_usleep(1); } while (err == MFX_WRN_DEVICE_BUSY); - if (err < 0 || !sync) { - av_log(ctx, AV_LOG_ERROR, "Error during scaling\n"); + if (err < 0) { + ret = ff_qsvvpp_print_error(ctx, err, "Error during scaling"); + goto fail; + } + + if (!sync) { + av_log(ctx, AV_LOG_ERROR, "No sync during scaling\n"); ret = AVERROR_UNKNOWN; goto fail; } @@ -583,8 +598,7 @@ static int qsvscale_filter_frame(AVFilterLink *link, AVFrame *in) err = MFXVideoCORE_SyncOperation(s->session, sync, 1000); } while (err == MFX_WRN_IN_EXECUTION); if (err < 0) { - av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err); - ret = AVERROR_UNKNOWN; + ret = ff_qsvvpp_print_error(ctx, err, "Error synchronizing the operation"); goto fail; } diff --git a/libavfilter/vf_selectivecolor.c b/libavfilter/vf_selectivecolor.c index d8f339d54..9bd79a3e6 100644 --- a/libavfilter/vf_selectivecolor.c +++ b/libavfilter/vf_selectivecolor.c @@ -61,7 +61,7 @@ enum correction_method { NB_CORRECTION_METHODS, }; -static const char *color_names[NB_RANGES] = { +static const char *const color_names[NB_RANGES] = { "red", "yellow", "green", "cyan", "blue", "magenta", "white", "neutral", "black" }; diff --git a/libavfilter/vf_shear.c b/libavfilter/vf_shear.c new file mode 100644 index 000000000..de298af94 --- /dev/null +++ b/libavfilter/vf_shear.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/avstring.h" +#include "libavutil/opt.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/parseutils.h" +#include "libavutil/pixdesc.h" + +#include "avfilter.h" +#include "drawutils.h" +#include "internal.h" +#include "video.h" + +#include + +typedef struct ShearContext { + const AVClass *class; + + float shx, shy; + int interp; + + uint8_t fillcolor[4]; ///< color expressed either in YUVA or RGBA colorspace for the padding area + char *fillcolor_str; + int fillcolor_enable; + int nb_planes; + int depth; + FFDrawContext draw; + FFDrawColor color; + + int hsub, vsub; + int planewidth[4]; + int planeheight[4]; + + int (*filter_slice[2])(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); +} ShearContext; + +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +#define OFFSET(x) offsetof(ShearContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption shear_options[] = { + { "shx", "set x shear factor", OFFSET(shx), AV_OPT_TYPE_FLOAT, {.dbl=0.}, -2, 2, .flags=FLAGS }, + { "shy", "set y shear factor", OFFSET(shy), AV_OPT_TYPE_FLOAT, {.dbl=0.}, -2, 2, .flags=FLAGS }, + { "fillcolor", "set background fill color", OFFSET(fillcolor_str), AV_OPT_TYPE_STRING, {.str="black"}, 0, 0, .flags=FLAGS }, + { "c", "set background fill color", OFFSET(fillcolor_str), AV_OPT_TYPE_STRING, {.str="black"}, 0, 0, .flags=FLAGS }, + { "interp", "set interpolation", OFFSET(interp), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, .flags=FLAGS, "interp" }, + { "nearest", "nearest neighbour", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, .flags=FLAGS, "interp" }, + { "bilinear", "bilinear", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, .flags=FLAGS, "interp" }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(shear); + +static av_cold int init(AVFilterContext *ctx) +{ + ShearContext *s = ctx->priv; + + if (!strcmp(s->fillcolor_str, "none")) + s->fillcolor_enable = 0; + else if (av_parse_color(s->fillcolor, s->fillcolor_str, -1, ctx) >= 0) + s->fillcolor_enable = 1; + else + return AVERROR(EINVAL); + return 0; +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, + AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, + AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +#define NN(type, name) \ +static int filter_slice_nn##name(AVFilterContext *ctx, void *arg, int jobnr, \ + int nb_jobs) \ +{ \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + ShearContext *s = ctx->priv; \ + const float shx = s->shx; \ + const float shy = s->shy; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const int hsub = (p == 1 || p == 2) ? s->hsub: 1; \ + const int vsub = (p == 1 || p == 2) ? s->vsub: 1; \ + const int width = s->planewidth[p]; \ + const int height = s->planeheight[p]; \ + const int wx = vsub * shx * height * 0.5f / hsub; \ + const int wy = hsub * shy * width * 0.5f / vsub; \ + const int slice_start = (height * jobnr) / nb_jobs; \ + const int slice_end = (height * (jobnr+1)) / nb_jobs; \ + const int src_linesize = in->linesize[p] / sizeof(type); \ + const int dst_linesize = out->linesize[p] / sizeof(type); \ + const type *src = (const type *)in->data[p]; \ + type *dst = (type *)out->data[p] + slice_start * dst_linesize; \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + for (int x = 0; x < width; x++) { \ + int sx = x + vsub * shx * y / hsub - wx; \ + int sy = y + hsub * shy * x / vsub - wy; \ + \ + if (sx >= 0 && sx < width - 1 && \ + sy >= 0 && sy < height - 1) { \ + dst[x] = src[sy * src_linesize + sx]; \ + } \ + } \ + \ + dst += dst_linesize; \ + } \ + } \ + \ + return 0; \ +} + +NN(uint8_t, 8) +NN(uint16_t, 16) + +#define BL(type, name) \ +static int filter_slice_bl##name(AVFilterContext *ctx, void *arg, int jobnr, \ + int nb_jobs) \ +{ \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + ShearContext *s = ctx->priv; \ + const int depth = s->depth; \ + const float shx = s->shx; \ + const float shy = s->shy; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const int hsub = (p == 1 || p == 2) ? s->hsub: 1; \ + const int vsub = (p == 1 || p == 2) ? s->vsub: 1; \ + const int width = s->planewidth[p]; \ + const int height = s->planeheight[p]; \ + const float wx = vsub * shx * height * 0.5f / hsub; \ + const float wy = hsub * shy * width * 0.5f / vsub; \ + const int slice_start = (height * jobnr) / nb_jobs; \ + const int slice_end = (height * (jobnr+1)) / nb_jobs; \ + const int src_linesize = in->linesize[p] / sizeof(type); \ + const int dst_linesize = out->linesize[p] / sizeof(type); \ + const type *src = (const type *)in->data[p]; \ + type *dst = (type *)out->data[p] + slice_start * dst_linesize; \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + for (int x = 0; x < width; x++) { \ + const float sx = x + vsub * shx * y / hsub - wx; \ + const float sy = y + hsub * shy * x / vsub - wy; \ + \ + if (sx >= 0 && sx < width - 1 && \ + sy >= 0 && sy < height - 1) { \ + float sum = 0.f; \ + int ax = floorf(sx); \ + int ay = floorf(sy); \ + float du = sx - ax; \ + float dv = sy - ay; \ + int bx = FFMIN(ax + 1, width - 1); \ + int by = FFMIN(ay + 1, height - 1); \ + \ + sum += (1.f - du) * (1.f - dv) * src[ay * src_linesize + ax];\ + sum += ( du) * (1.f - dv) * src[ay * src_linesize + bx];\ + sum += (1.f - du) * ( dv) * src[by * src_linesize + ax];\ + sum += ( du) * ( dv) * src[by * src_linesize + bx];\ + dst[x] = av_clip_uintp2_c(lrintf(sum), depth); \ + } \ + } \ + \ + dst += dst_linesize; \ + } \ + } \ + \ + return 0; \ +} + +BL(uint8_t, 8) +BL(uint16_t, 16) + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + ShearContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + ThreadData td; + AVFrame *out; + + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + + /* fill background */ + if (s->fillcolor_enable) + ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize, + 0, 0, outlink->w, outlink->h); + + td.in = in, td.out = out; + ctx->internal->execute(ctx, s->filter_slice[s->interp], &td, NULL, FFMIN(s->planeheight[1], ff_filter_get_nb_threads(ctx))); + + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + ShearContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); + + s->nb_planes = av_pix_fmt_count_planes(outlink->format); + s->depth = desc->comp[0].depth; + s->hsub = 1 << desc->log2_chroma_w; + s->vsub = 1 << desc->log2_chroma_h; + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(ctx->inputs[0]->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = ctx->inputs[0]->w; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(ctx->inputs[0]->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = ctx->inputs[0]->h; + + ff_draw_init(&s->draw, outlink->format, 0); + ff_draw_color(&s->draw, &s->color, s->fillcolor); + + s->filter_slice[0] = s->depth <= 8 ? filter_slice_nn8 : filter_slice_nn16; + s->filter_slice[1] = s->depth <= 8 ? filter_slice_bl8 : filter_slice_bl16; + + return 0; +} + +static int process_command(AVFilterContext *ctx, + const char *cmd, + const char *arg, + char *res, + int res_len, + int flags) +{ + ShearContext *s = ctx->priv; + int ret; + + ret = ff_filter_process_command(ctx, cmd, arg, res, res_len, flags); + if (ret < 0) + return ret; + + ret = init(ctx); + if (ret < 0) + return ret; + ff_draw_color(&s->draw, &s->color, s->fillcolor); + + return 0; +} + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL } +}; + +AVFilter ff_vf_shear = { + .name = "shear", + .description = NULL_IF_CONFIG_SMALL("Shear transform the input image."), + .priv_size = sizeof(ShearContext), + .init = init, + .query_formats = query_formats, + .inputs = inputs, + .outputs = outputs, + .priv_class = &shear_class, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, +}; diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index 5d4aee416..620889200 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -29,6 +29,7 @@ #include "libavutil/display.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" +#include "libavutil/hdr_dynamic_metadata.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/spherical.h" @@ -57,14 +58,14 @@ static const AVOption showinfo_options[] = { AVFILTER_DEFINE_CLASS(showinfo); -static void dump_spherical(AVFilterContext *ctx, AVFrame *frame, AVFrameSideData *sd) +static void dump_spherical(AVFilterContext *ctx, AVFrame *frame, const AVFrameSideData *sd) { - AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; + const AVSphericalMapping *spherical = (const AVSphericalMapping *)sd->data; double yaw, pitch, roll; av_log(ctx, AV_LOG_INFO, "spherical information: "); if (sd->size < sizeof(*spherical)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -75,7 +76,7 @@ static void dump_spherical(AVFilterContext *ctx, AVFrame *frame, AVFrameSideData else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) av_log(ctx, AV_LOG_INFO, "tiled equirectangular "); else { - av_log(ctx, AV_LOG_WARNING, "unknown"); + av_log(ctx, AV_LOG_WARNING, "unknown\n"); return; } @@ -96,17 +97,17 @@ static void dump_spherical(AVFilterContext *ctx, AVFrame *frame, AVFrameSideData } } -static void dump_stereo3d(AVFilterContext *ctx, AVFrameSideData *sd) +static void dump_stereo3d(AVFilterContext *ctx, const AVFrameSideData *sd) { - AVStereo3D *stereo; + const AVStereo3D *stereo; av_log(ctx, AV_LOG_INFO, "stereoscopic information: "); if (sd->size < sizeof(*stereo)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } - stereo = (AVStereo3D *)sd->data; + stereo = (const AVStereo3D *)sd->data; av_log(ctx, AV_LOG_INFO, "type - %s", av_stereo3d_type_name(stereo->type)); @@ -114,7 +115,23 @@ static void dump_stereo3d(AVFilterContext *ctx, AVFrameSideData *sd) av_log(ctx, AV_LOG_INFO, " (inverted)"); } -static void dump_roi(AVFilterContext *ctx, AVFrameSideData *sd) +static void dump_s12m_timecode(AVFilterContext *ctx, AVRational frame_rate, const AVFrameSideData *sd) +{ + const uint32_t *tc = (const uint32_t *)sd->data; + + if ((sd->size != sizeof(uint32_t) * 4) || (tc[0] > 3)) { + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); + return; + } + + for (int j = 1; j <= tc[0]; j++) { + char tcbuf[AV_TIMECODE_STR_SIZE]; + av_timecode_make_smpte_tc_string2(tcbuf, frame_rate, tc[j], 0, 0); + av_log(ctx, AV_LOG_INFO, "timecode - %s%s", tcbuf, j != tc[0] ? ", " : ""); + } +} + +static void dump_roi(AVFilterContext *ctx, const AVFrameSideData *sd) { int nb_rois; const AVRegionOfInterest *roi; @@ -123,7 +140,7 @@ static void dump_roi(AVFilterContext *ctx, AVFrameSideData *sd) roi = (const AVRegionOfInterest *)sd->data; roi_size = roi->self_size; if (!roi_size || sd->size % roi_size != 0) { - av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size."); + av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n"); return; } nb_rois = sd->size / roi_size; @@ -136,17 +153,17 @@ static void dump_roi(AVFilterContext *ctx, AVFrameSideData *sd) } } -static void dump_mastering_display(AVFilterContext *ctx, AVFrameSideData *sd) +static void dump_mastering_display(AVFilterContext *ctx, const AVFrameSideData *sd) { - AVMasteringDisplayMetadata *mastering_display; + const AVMasteringDisplayMetadata *mastering_display; av_log(ctx, AV_LOG_INFO, "mastering display: "); if (sd->size < sizeof(*mastering_display)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } - mastering_display = (AVMasteringDisplayMetadata *)sd->data; + mastering_display = (const AVMasteringDisplayMetadata *)sd->data; av_log(ctx, AV_LOG_INFO, "has_primaries:%d has_luminance:%d " "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) " @@ -162,18 +179,118 @@ static void dump_mastering_display(AVFilterContext *ctx, AVFrameSideData *sd) av_q2d(mastering_display->min_luminance), av_q2d(mastering_display->max_luminance)); } +static void dump_dynamic_hdr_plus(AVFilterContext *ctx, AVFrameSideData *sd) +{ + AVDynamicHDRPlus *hdr_plus; + + av_log(ctx, AV_LOG_INFO, "HDR10+ metadata: "); + if (sd->size < sizeof(*hdr_plus)) { + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); + return; + } + + hdr_plus = (AVDynamicHDRPlus *)sd->data; + av_log(ctx, AV_LOG_INFO, "application version: %d, ", hdr_plus->application_version); + av_log(ctx, AV_LOG_INFO, "num_windows: %d, ", hdr_plus->num_windows); + for (int w = 1; w < hdr_plus->num_windows; w++) { + AVHDRPlusColorTransformParams *params = &hdr_plus->params[w]; + av_log(ctx, AV_LOG_INFO, "window %d { ", w); + av_log(ctx, AV_LOG_INFO, "window_upper_left_corner: (%5.4f,%5.4f),", + av_q2d(params->window_upper_left_corner_x), + av_q2d(params->window_upper_left_corner_y)); + av_log(ctx, AV_LOG_INFO, "window_lower_right_corner: (%5.4f,%5.4f), ", + av_q2d(params->window_lower_right_corner_x), + av_q2d(params->window_lower_right_corner_y)); + av_log(ctx, AV_LOG_INFO, "window_upper_left_corner: (%5.4f, %5.4f), ", + av_q2d(params->window_upper_left_corner_x), + av_q2d(params->window_upper_left_corner_y)); + av_log(ctx, AV_LOG_INFO, "center_of_ellipse_x: (%d,%d), ", + params->center_of_ellipse_x, + params->center_of_ellipse_y); + av_log(ctx, AV_LOG_INFO, "rotation_angle: %d, ", + params->rotation_angle); + av_log(ctx, AV_LOG_INFO, "semimajor_axis_internal_ellipse: %d, ", + params->semimajor_axis_internal_ellipse); + av_log(ctx, AV_LOG_INFO, "semimajor_axis_external_ellipse: %d, ", + params->semimajor_axis_external_ellipse); + av_log(ctx, AV_LOG_INFO, "semiminor_axis_external_ellipse: %d, ", + params->semiminor_axis_external_ellipse); + av_log(ctx, AV_LOG_INFO, "overlap_process_option: %d}, ", + params->overlap_process_option); + } + av_log(ctx, AV_LOG_INFO, "targeted_system_display_maximum_luminance: %9.4f, ", + av_q2d(hdr_plus->targeted_system_display_maximum_luminance)); + if (hdr_plus->targeted_system_display_actual_peak_luminance_flag) { + av_log(ctx, AV_LOG_INFO, "targeted_system_display_actual_peak_luminance: {"); + for (int i = 0; i < hdr_plus->num_rows_targeted_system_display_actual_peak_luminance; i++) { + av_log(ctx, AV_LOG_INFO, "("); + for (int j = 0; j < hdr_plus->num_cols_targeted_system_display_actual_peak_luminance; j++) { + av_log(ctx, AV_LOG_INFO, "%5.4f,", + av_q2d(hdr_plus->targeted_system_display_actual_peak_luminance[i][j])); + } + av_log(ctx, AV_LOG_INFO, ")"); + } + av_log(ctx, AV_LOG_INFO, "}, "); + } + + for (int w = 0; w < hdr_plus->num_windows; w++) { + AVHDRPlusColorTransformParams *params = &hdr_plus->params[w]; + av_log(ctx, AV_LOG_INFO, "window %d {maxscl: {", w); + for (int i = 0; i < 3; i++) { + av_log(ctx, AV_LOG_INFO, "%5.4f,",av_q2d(params->maxscl[i])); + } + av_log(ctx, AV_LOG_INFO, "} average_maxrgb: %5.4f, ", + av_q2d(params->average_maxrgb)); + av_log(ctx, AV_LOG_INFO, "distribution_maxrgb: {"); + for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) { + av_log(ctx, AV_LOG_INFO, "(%d,%5.4f)", + params->distribution_maxrgb[i].percentage, + av_q2d(params->distribution_maxrgb[i].percentile)); + } + av_log(ctx, AV_LOG_INFO, "} fraction_bright_pixels: %5.4f, ", + av_q2d(params->fraction_bright_pixels)); + if (params->tone_mapping_flag) { + av_log(ctx, AV_LOG_INFO, "knee_point: (%5.4f,%5.4f), ", av_q2d(params->knee_point_x), av_q2d(params->knee_point_y)); + av_log(ctx, AV_LOG_INFO, "bezier_curve_anchors: {"); + for (int i = 0; i < params->num_bezier_curve_anchors; i++) { + av_log(ctx, AV_LOG_INFO, "%5.4f,", + av_q2d(params->bezier_curve_anchors[i])); + } + av_log(ctx, AV_LOG_INFO, "} "); + } + if (params->color_saturation_mapping_flag) { + av_log(ctx, AV_LOG_INFO, "color_saturation_weight: %5.4f", + av_q2d(params->color_saturation_weight)); + } + av_log(ctx, AV_LOG_INFO, "} "); + } + + if (hdr_plus->mastering_display_actual_peak_luminance_flag) { + av_log(ctx, AV_LOG_INFO, "mastering_display_actual_peak_luminance: {"); + for (int i = 0; i < hdr_plus->num_rows_mastering_display_actual_peak_luminance; i++) { + av_log(ctx, AV_LOG_INFO, "("); + for (int j = 0; j < hdr_plus->num_cols_mastering_display_actual_peak_luminance; j++) { + av_log(ctx, AV_LOG_INFO, " %5.4f,", + av_q2d(hdr_plus->mastering_display_actual_peak_luminance[i][j])); + } + av_log(ctx, AV_LOG_INFO, ")"); + } + av_log(ctx, AV_LOG_INFO, "} "); + } +} + static void dump_content_light_metadata(AVFilterContext *ctx, AVFrameSideData *sd) { - AVContentLightMetadata* metadata = (AVContentLightMetadata*)sd->data; + const AVContentLightMetadata *metadata = (const AVContentLightMetadata *)sd->data; av_log(ctx, AV_LOG_INFO, "Content Light Level information: " "MaxCLL=%d, MaxFALL=%d", metadata->MaxCLL, metadata->MaxFALL); } -static void dump_video_enc_params(AVFilterContext *ctx, AVFrameSideData *sd) +static void dump_video_enc_params(AVFilterContext *ctx, const AVFrameSideData *sd) { - AVVideoEncParams *par = (AVVideoEncParams*)sd->data; + const AVVideoEncParams *par = (const AVVideoEncParams *)sd->data; int plane, acdc; av_log(ctx, AV_LOG_INFO, "video encoding parameters: type %d; ", par->type); @@ -190,6 +307,33 @@ static void dump_video_enc_params(AVFilterContext *ctx, AVFrameSideData *sd) av_log(ctx, AV_LOG_INFO, "%u blocks; ", par->nb_blocks); } +static void dump_sei_unregistered_metadata(AVFilterContext *ctx, const AVFrameSideData *sd) +{ + const int uuid_size = 16; + const uint8_t *user_data = sd->data; + int i; + + if (sd->size < uuid_size) { + av_log(ctx, AV_LOG_ERROR, "invalid data(%d < UUID(%d-bytes))\n", sd->size, uuid_size); + return; + } + + av_log(ctx, AV_LOG_INFO, "User Data Unregistered:\n"); + av_log(ctx, AV_LOG_INFO, "UUID="); + for (i = 0; i < uuid_size; i++) { + av_log(ctx, AV_LOG_INFO, "%02x", user_data[i]); + if (i == 3 || i == 5 || i == 7 || i == 9) + av_log(ctx, AV_LOG_INFO, "-"); + } + av_log(ctx, AV_LOG_INFO, "\n"); + + av_log(ctx, AV_LOG_INFO, "User Data="); + for (; i < sd->size; i++) { + av_log(ctx, AV_LOG_INFO, "%02x", user_data[i]); + } + av_log(ctx, AV_LOG_INFO, "\n"); +} + static void dump_color_property(AVFilterContext *ctx, AVFrame *frame) { const char *color_range_str = av_color_range_name(frame->color_range); @@ -337,17 +481,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) dump_stereo3d(ctx, sd); break; case AV_FRAME_DATA_S12M_TIMECODE: { - uint32_t *tc = (uint32_t*)sd->data; - int m = FFMIN(tc[0],3); - if (sd->size != 16) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); - break; - } - for (int j = 1; j <= m; j++) { - char tcbuf[AV_TIMECODE_STR_SIZE]; - av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); - av_log(ctx, AV_LOG_INFO, "timecode - %s%s", tcbuf, j != m ? ", " : ""); - } + dump_s12m_timecode(ctx, inlink->frame_rate, sd); break; } case AV_FRAME_DATA_DISPLAYMATRIX: @@ -363,6 +497,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: dump_mastering_display(ctx, sd); break; + case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: + dump_dynamic_hdr_plus(ctx, sd); + break; case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: dump_content_light_metadata(ctx, sd); break; @@ -375,8 +512,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) case AV_FRAME_DATA_VIDEO_ENC_PARAMS: dump_video_enc_params(ctx, sd); break; + case AV_FRAME_DATA_SEI_UNREGISTERED: + dump_sei_unregistered_metadata(ctx, sd); + break; default: - av_log(ctx, AV_LOG_WARNING, "unknown side data type %d (%d bytes)", + av_log(ctx, AV_LOG_WARNING, "unknown side data type %d (%d bytes)\n", sd->type, sd->size); break; } diff --git a/libavfilter/vf_showpalette.c b/libavfilter/vf_showpalette.c index 5b0772bc0..c0327acf5 100644 --- a/libavfilter/vf_showpalette.c +++ b/libavfilter/vf_showpalette.c @@ -46,26 +46,13 @@ static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat in_fmts[] = {AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE}; static const enum AVPixelFormat out_fmts[] = {AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE}; - int ret; - AVFilterFormats *in = ff_make_format_list(in_fmts); - AVFilterFormats *out = ff_make_format_list(out_fmts); - if (!in || !out) { - ret = AVERROR(ENOMEM); - goto fail; - } + int ret = ff_formats_ref(ff_make_format_list(in_fmts), + &ctx->inputs[0]->outcfg.formats); + if (ret < 0) + return ret; - if ((ret = ff_formats_ref(in , &ctx->inputs[0]->out_formats)) < 0 || - (ret = ff_formats_ref(out, &ctx->outputs[0]->in_formats)) < 0) - goto fail; - return 0; -fail: - if (in) - av_freep(&in->formats); - av_freep(&in); - if (out) - av_freep(&out->formats); - av_freep(&out); - return ret; + return ff_formats_ref(ff_make_format_list(out_fmts), + &ctx->outputs[0]->incfg.formats); } static int config_output(AVFilterLink *outlink) @@ -76,7 +63,7 @@ static int config_output(AVFilterLink *outlink) return 0; } -static int disp_palette(AVFrame *out, const AVFrame *in, int size) +static void disp_palette(AVFrame *out, const AVFrame *in, int size) { int x, y, i, j; uint32_t *dst = (uint32_t *)out->data[0]; @@ -88,12 +75,10 @@ static int disp_palette(AVFrame *out, const AVFrame *in, int size) for (j = 0; j < size; j++) for (i = 0; i < size; i++) dst[(y*dst_linesize + x) * size + j*dst_linesize + i] = pal[y*16 + x]; - return 0; } static int filter_frame(AVFilterLink *inlink, AVFrame *in) { - int ret; AVFrame *out; AVFilterContext *ctx = inlink->dst; const ShowPaletteContext *s = ctx->priv; @@ -105,9 +90,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return AVERROR(ENOMEM); } av_frame_copy_props(out, in); - ret = disp_palette(out, in, s->size); + disp_palette(out, in, s->size); av_frame_free(&in); - return ret < 0 ? ret : ff_filter_frame(outlink, out); + return ff_filter_frame(outlink, out); } static const AVFilterPad showpalette_inputs[] = { diff --git a/libavfilter/vf_shufflepixels.c b/libavfilter/vf_shufflepixels.c new file mode 100644 index 000000000..463bb66bc --- /dev/null +++ b/libavfilter/vf_shufflepixels.c @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2020 Paul B Mahol + * + * 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/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/common.h" +#include "libavutil/internal.h" +#include "libavutil/imgutils.h" +#include "libavutil/lfg.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "libavutil/random_seed.h" + +#include "avfilter.h" +#include "internal.h" +#include "video.h" + +typedef struct ShufflePixelsContext { + const AVClass *class; + + int block_w, block_h; + int mode; + int direction; + int64_t seed; + + int depth; + int nb_planes; + int linesize[4]; + int planewidth[4]; + int planeheight[4]; + + int nb_blocks; + + uint8_t *used; + int32_t *map; + + AVLFG c; + + int (*shuffle_pixels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); +} ShufflePixelsContext; + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_GBRAP16, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_NONE + }; + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +static void make_horizontal_map(AVFilterContext *ctx) +{ + ShufflePixelsContext *s = ctx->priv; + const int nb_blocks = s->nb_blocks; + AVLFG *c = &s->c; + uint8_t *used = s->used; + int32_t *map = s->map; + + for (int x = 0; x < s->planewidth[0];) { + int rand = av_lfg_get(c) % nb_blocks; + + if (used[rand] == 0) { + int width; + + if (s->direction) { + width = FFMIN(s->block_w, s->planewidth[0] - x); + map[rand * s->block_w] = x; + } else { + width = FFMIN(s->block_w, s->planewidth[0] - rand * s->block_w); + map[x] = rand * s->block_w; + } + used[rand] = 1; + + if (s->direction) { + for (int i = 1; i < width; i++) { + map[rand * s->block_w + i] = map[rand * s->block_w] + i; + } + } else { + for (int i = 1; i < width; i++) { + map[x + i] = map[x] + i; + } + } + + x += width; + } + } +} + +static void make_vertical_map(AVFilterContext *ctx) +{ + ShufflePixelsContext *s = ctx->priv; + const int nb_blocks = s->nb_blocks; + AVLFG *c = &s->c; + uint8_t *used = s->used; + int32_t *map = s->map; + + for (int y = 0; y < s->planeheight[0];) { + int rand = av_lfg_get(c) % nb_blocks; + + if (used[rand] == 0) { + int height; + + if (s->direction) { + height = FFMIN(s->block_h, s->planeheight[0] - y); + map[rand * s->block_h] = y; + } else { + height = FFMIN(s->block_h, s->planeheight[0] - rand * s->block_h); + map[y] = rand * s->block_h; + } + used[rand] = 1; + + if (s->direction) { + for (int i = 1; i < height; i++) { + map[rand * s->block_h + i] = map[rand * s->block_h] + i; + } + } else { + for (int i = 1; i < height; i++) { + map[y + i] = map[y] + i; + } + } + + y += height; + } + } +} + +static void make_block_map(AVFilterContext *ctx) +{ + ShufflePixelsContext *s = ctx->priv; + const int nb_blocks = s->nb_blocks; + int nb_blocks_w = s->planewidth[0] / s->block_w; + AVLFG *c = &s->c; + uint8_t *used = s->used; + int32_t *map = s->map; + + for (int i = 0; i < nb_blocks;) { + int rand = av_lfg_get(c) % nb_blocks; + + if (used[rand] == 0) { + int yin = i / nb_blocks_w; + int xin = i % nb_blocks_w; + int in = yin * s->block_h * s->planewidth[0] + xin * s->block_w; + int yout = rand / nb_blocks_w; + int xout = rand % nb_blocks_w; + int out = yout * s->block_h * s->planewidth[0] + xout * s->block_w; + + if (s->direction) { + map[out] = in; + } else { + map[in] = out; + } + used[rand] = 1; + + if (s->direction) { + for (int y = 0; y < s->block_h; y++) { + for (int x = 0; x < s->block_w; x++) { + map[out + y * s->planewidth[0] + x] = map[out] + x + y * s->planewidth[0]; + } + } + } else { + for (int y = 0; y < s->block_h; y++) { + for (int x = 0; x < s->block_w; x++) { + map[in + y * s->planewidth[0] + x] = map[in] + x + y * s->planewidth[0]; + } + } + } + + i++; + } + } +} + +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + + +#define SHUFFLE_HORIZONTAL(name, type) \ +static int shuffle_horizontal## name(AVFilterContext *ctx, void *arg, \ + int jobnr, int nb_jobs) \ +{ \ + ShufflePixelsContext *s = ctx->priv; \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; \ + const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; \ + type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ + const type *src = (const type *)(in->data[p] + \ + slice_start * in->linesize[p]); \ + const int32_t *map = s->map; \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + for (int x = 0; x < s->planewidth[p]; x++) { \ + dst[x] = src[map[x]]; \ + } \ + \ + dst += out->linesize[p] / sizeof(type); \ + src += in->linesize[p] / sizeof(type); \ + } \ + } \ + \ + return 0; \ +} + +SHUFFLE_HORIZONTAL(8, uint8_t) +SHUFFLE_HORIZONTAL(16, uint16_t) + +#define SHUFFLE_VERTICAL(name, type) \ +static int shuffle_vertical## name(AVFilterContext *ctx, void *arg, \ + int jobnr, int nb_jobs) \ +{ \ + ShufflePixelsContext *s = ctx->priv; \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; \ + const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; \ + type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ + const int32_t *map = s->map; \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + const type *src = (const type *)(in->data[p] + \ + map[y] * in->linesize[p]); \ + \ + memcpy(dst, src, s->linesize[p]); \ + dst += out->linesize[p] / sizeof(type); \ + } \ + } \ + \ + return 0; \ +} + +SHUFFLE_VERTICAL(8, uint8_t) +SHUFFLE_VERTICAL(16, uint16_t) + +#define SHUFFLE_BLOCK(name, type) \ +static int shuffle_block## name(AVFilterContext *ctx, void *arg, \ + int jobnr, int nb_jobs) \ +{ \ + ShufflePixelsContext *s = ctx->priv; \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; \ + const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; \ + type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ + const type *src = (const type *)in->data[p]; \ + const int32_t *map = s->map + slice_start * s->planewidth[p]; \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + for (int x = 0; x < s->planewidth[p]; x++) { \ + int ymap = map[x] / s->planewidth[p]; \ + int xmap = map[x] % s->planewidth[p]; \ + \ + dst[x] = src[xmap + ymap * in->linesize[p] / sizeof(type)]; \ + } \ + \ + dst += out->linesize[p] / sizeof(type); \ + map += s->planewidth[p]; \ + } \ + } \ + \ + return 0; \ +} + +SHUFFLE_BLOCK(8, uint8_t) +SHUFFLE_BLOCK(16, uint16_t) + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + ShufflePixelsContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + const AVPixFmtDescriptor *desc; + int ret; + + if (s->seed == -1) + s->seed = av_get_random_seed(); + av_lfg_init(&s->c, s->seed); + + desc = av_pix_fmt_desc_get(outlink->format); + if (!desc) + return AVERROR_BUG; + s->nb_planes = av_pix_fmt_count_planes(outlink->format); + s->depth = desc->comp[0].depth; + + if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) + return ret; + + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + + s->map = av_calloc(inlink->w * inlink->h, sizeof(*s->map)); + if (!s->map) + return AVERROR(ENOMEM); + + switch (s->mode) { + case 0: + s->shuffle_pixels = s->depth <= 8 ? shuffle_horizontal8 : shuffle_horizontal16; + s->nb_blocks = (s->planewidth[0] + s->block_w - 1) / s->block_w; + break; + case 1: + s->shuffle_pixels = s->depth <= 8 ? shuffle_vertical8 : shuffle_vertical16; + s->nb_blocks = (s->planeheight[0] + s->block_h - 1) / s->block_h; + break; + case 2: + s->shuffle_pixels = s->depth <= 8 ? shuffle_block8 : shuffle_block16; + s->nb_blocks = (s->planeheight[0] / s->block_h) * + (s->planewidth[0] / s->block_w); + break; + default: + av_assert0(0); + } + + s->used = av_calloc(s->nb_blocks, sizeof(*s->used)); + if (!s->used) + return AVERROR(ENOMEM); + + switch (s->mode) { + case 0: + make_horizontal_map(ctx); + break; + case 1: + make_vertical_map(ctx); + break; + case 2: + make_block_map(ctx); + break; + default: + av_assert0(0); + } + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + ShufflePixelsContext *s = ctx->priv; + AVFrame *out = ff_get_video_buffer(ctx->outputs[0], in->width, in->height); + ThreadData td; + int ret; + + ret = av_frame_copy_props(out, in); + if (ret < 0) { + av_frame_free(&out); + goto fail; + } + + td.out = out; + td.in = in; + ctx->internal->execute(ctx, s->shuffle_pixels, &td, NULL, FFMIN(s->planeheight[1], ff_filter_get_nb_threads(ctx))); + + av_frame_free(&in); + return ff_filter_frame(ctx->outputs[0], out); +fail: + av_frame_free(&in); + return ret; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + ShufflePixelsContext *s = ctx->priv; + + av_freep(&s->map); + av_freep(&s->used); +} + +#define OFFSET(x) offsetof(ShufflePixelsContext, x) +#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) +static const AVOption shufflepixels_options[] = { + { "direction", "set shuffle direction", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "dir" }, + { "d", "set shuffle direction", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "dir" }, + { "forward", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "dir" }, + { "inverse", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "dir" }, + { "mode", "set shuffle mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "mode" }, + { "m", "set shuffle mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "mode" }, + { "horizontal", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mode" }, + { "vertical", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mode" }, + { "block", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "mode" }, + { "width", "set block width", OFFSET(block_w), AV_OPT_TYPE_INT, {.i64=10}, 1, 8000, FLAGS }, + { "w", "set block width", OFFSET(block_w), AV_OPT_TYPE_INT, {.i64=10}, 1, 8000, FLAGS }, + { "height", "set block height", OFFSET(block_h), AV_OPT_TYPE_INT, {.i64=10}, 1, 8000, FLAGS }, + { "h", "set block height", OFFSET(block_h), AV_OPT_TYPE_INT, {.i64=10}, 1, 8000, FLAGS }, + { "seed", "set random seed", OFFSET(seed), AV_OPT_TYPE_INT64, {.i64=-1}, -1, UINT_MAX, FLAGS }, + { "s", "set random seed", OFFSET(seed), AV_OPT_TYPE_INT64, {.i64=-1}, -1, UINT_MAX, FLAGS }, + { NULL }, +}; + +AVFILTER_DEFINE_CLASS(shufflepixels); + +static const AVFilterPad shufflepixels_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + }, + { NULL }, +}; + +static const AVFilterPad shufflepixels_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL }, +}; + +AVFilter ff_vf_shufflepixels = { + .name = "shufflepixels", + .description = NULL_IF_CONFIG_SMALL("Shuffle video pixels."), + .priv_size = sizeof(ShufflePixelsContext), + .priv_class = &shufflepixels_class, + .query_formats = query_formats, + .uninit = uninit, + .inputs = shufflepixels_inputs, + .outputs = shufflepixels_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, +}; diff --git a/libavfilter/vf_shuffleplanes.c b/libavfilter/vf_shuffleplanes.c index 6c718893c..c5a376d50 100644 --- a/libavfilter/vf_shuffleplanes.c +++ b/libavfilter/vf_shuffleplanes.c @@ -64,7 +64,6 @@ static int query_formats(AVFilterContext *ctx) if (i != 4) continue; if ((ret = ff_add_format(&formats, fmt)) < 0) { - ff_formats_unref(&formats); return ret; } } diff --git a/libavfilter/vf_signature.c b/libavfilter/vf_signature.c index d07b213f3..32a6405e1 100644 --- a/libavfilter/vf_signature.c +++ b/libavfilter/vf_signature.c @@ -132,8 +132,9 @@ static uint64_t get_block_sum(StreamContext *sc, uint64_t intpic[32][32], const return sum; } -static int cmp(const uint64_t *a, const uint64_t *b) +static int cmp(const void *x, const void *y) { + const uint64_t *a = x, *b = y; return *a < *b ? -1 : ( *a > *b ? 1 : 0 ); } @@ -291,7 +292,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) } /* get threshold */ - qsort(sortsignature, elemcat->elem_count, sizeof(uint64_t), (void*) cmp); + qsort(sortsignature, elemcat->elem_count, sizeof(uint64_t), cmp); th = sortsignature[(int) (elemcat->elem_count*0.333)]; /* ternarize */ @@ -317,7 +318,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) } /* confidence */ - qsort(conflist, DIFFELEM_SIZE, sizeof(uint64_t), (void*) cmp); + qsort(conflist, DIFFELEM_SIZE, sizeof(uint64_t), cmp); fs->confidence = FFMIN(conflist[DIFFELEM_SIZE/2], 255); /* coarsesignature */ @@ -559,7 +560,6 @@ static int binary_export(AVFilterContext *ctx, StreamContext *sc, const char* fi } } - avpriv_align_put_bits(&buf); flush_put_bits(&buf); fwrite(buffer, 1, put_bits_count(&buf)/8, f); fclose(f); @@ -664,6 +664,10 @@ static av_cold int init(AVFilterContext *ctx) if (!pad.name) return AVERROR(ENOMEM); + if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } sc = &(sic->streamcontexts[i]); @@ -680,11 +684,6 @@ static av_cold int init(AVFilterContext *ctx) sc->coarseend = sc->coarsesiglist; sc->coarsecount = 0; sc->midcoarse = 0; - - if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { - av_freep(&pad.name); - return ret; - } } /* check filename */ @@ -731,6 +730,8 @@ static av_cold void uninit(AVFilterContext *ctx) } av_freep(&sic->streamcontexts); } + for (unsigned i = 0; i < ctx->nb_inputs; i++) + av_freep(&ctx->input_pads[i].name); } static int config_output(AVFilterLink *outlink) diff --git a/libavfilter/vf_spp.c b/libavfilter/vf_spp.c index a83b1195c..6ea7e7458 100644 --- a/libavfilter/vf_spp.c +++ b/libavfilter/vf_spp.c @@ -33,9 +33,11 @@ #include "libavutil/avassert.h" #include "libavutil/imgutils.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "internal.h" +#include "qp_table.h" #include "vf_spp.h" enum mode { @@ -44,10 +46,19 @@ enum mode { NB_MODES }; +#if FF_API_CHILD_CLASS_NEXT static const AVClass *child_class_next(const AVClass *prev) { return prev ? NULL : avcodec_dct_get_class(); } +#endif + +static const AVClass *child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : avcodec_dct_get_class(); + *iter = (void*)(uintptr_t)c; + return c; +} static void *child_next(void *obj, void *prev) { @@ -74,7 +85,10 @@ static const AVClass spp_class = { .option = spp_options, .version = LIBAVUTIL_VERSION_INT, .category = AV_CLASS_CATEGORY_FILTER, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = child_class_next, +#endif + .child_class_iterate = child_class_iterate, .child_next = child_next, }; @@ -362,47 +376,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterLink *outlink = ctx->outputs[0]; AVFrame *out = in; int qp_stride = 0; - const int8_t *qp_table = NULL; + int8_t *qp_table = NULL; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); const int depth = desc->comp[0].depth; + int ret = 0; /* if we are not in a constant user quantizer mode and we don't want to use * the quantizers from the B-frames (B-frames often have a higher QP), we * need to save the qp table from the last non B-frame; this is what the * following code block does */ - if (!s->qp) { - qp_table = av_frame_get_qp_table(in, &qp_stride, &s->qscale_type); + if (!s->qp && (s->use_bframe_qp || in->pict_type != AV_PICTURE_TYPE_B)) { + ret = ff_qp_table_extract(in, &qp_table, &qp_stride, NULL, &s->qscale_type); + if (ret < 0) { + av_frame_free(&in); + return ret; + } - if (qp_table && !s->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) { - int w, h; - - /* if the qp stride is not set, it means the QP are only defined on - * a line basis */ - if (!qp_stride) { - w = AV_CEIL_RSHIFT(inlink->w, 4); - h = 1; - } else { - w = qp_stride; - h = AV_CEIL_RSHIFT(inlink->h, 4); - } - - if (w * h > s->non_b_qp_alloc_size) { - int ret = av_reallocp_array(&s->non_b_qp_table, w, h); - if (ret < 0) { - s->non_b_qp_alloc_size = 0; - return ret; - } - s->non_b_qp_alloc_size = w * h; - } - - av_assert0(w * h <= s->non_b_qp_alloc_size); - memcpy(s->non_b_qp_table, qp_table, w * h); + if (!s->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) { + av_freep(&s->non_b_qp_table); + s->non_b_qp_table = qp_table; + s->non_b_qp_stride = qp_stride; } } if (s->log2_count && !ctx->is_disabled) { - if (!s->use_bframe_qp && s->non_b_qp_table) - qp_table = s->non_b_qp_table; + if (!s->use_bframe_qp && s->non_b_qp_table) { + qp_table = s->non_b_qp_table; + qp_stride = s->non_b_qp_stride; + } if (qp_table || s->qp) { const int cw = AV_CEIL_RSHIFT(inlink->w, s->hsub); @@ -417,7 +418,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) out = ff_get_video_buffer(outlink, aligned_w, aligned_h); if (!out) { av_frame_free(&in); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto finish; } av_frame_copy_props(out, in); out->width = in->width; @@ -441,7 +443,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) inlink->w, inlink->h); av_frame_free(&in); } - return ff_filter_frame(outlink, out); + ret = ff_filter_frame(outlink, out); +finish: + if (qp_table != s->non_b_qp_table) + av_freep(&qp_table); + return ret; } static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, diff --git a/libavfilter/vf_spp.h b/libavfilter/vf_spp.h index 879ed40f0..76c0c34ab 100644 --- a/libavfilter/vf_spp.h +++ b/libavfilter/vf_spp.h @@ -39,7 +39,7 @@ typedef struct SPPContext { uint16_t *temp; AVDCT *dct; int8_t *non_b_qp_table; - int non_b_qp_alloc_size; + int non_b_qp_stride; int use_bframe_qp; int hsub, vsub; diff --git a/libavfilter/vf_sr.c b/libavfilter/vf_sr.c index f000eda18..45f941acd 100644 --- a/libavfilter/vf_sr.c +++ b/libavfilter/vf_sr.c @@ -32,32 +32,29 @@ #include "libavutil/pixdesc.h" #include "libavformat/avio.h" #include "libswscale/swscale.h" -#include "dnn_interface.h" +#include "dnn_filter_common.h" typedef struct SRContext { const AVClass *class; - - char *model_filename; - DNNBackendType backend_type; - DNNModule *dnn_module; - DNNModel *model; - DNNData input; - DNNData output; + DnnContext dnnctx; int scale_factor; - struct SwsContext *sws_contexts[3]; - int sws_slice_h, sws_input_linesize, sws_output_linesize; + struct SwsContext *sws_uv_scale; + int sws_uv_height; + struct SwsContext *sws_pre_scale; } SRContext; #define OFFSET(x) offsetof(SRContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM static const AVOption sr_options[] = { - { "dnn_backend", "DNN backend used for model execution", OFFSET(backend_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, "backend" }, + { "dnn_backend", "DNN backend used for model execution", OFFSET(dnnctx.backend_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, "backend" }, { "native", "native backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "backend" }, #if (CONFIG_LIBTENSORFLOW == 1) { "tensorflow", "tensorflow backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "backend" }, #endif { "scale_factor", "scale factor for SRCNN model", OFFSET(scale_factor), AV_OPT_TYPE_INT, { .i64 = 2 }, 2, 4, FLAGS }, - { "model", "path to model file specifying network architecture and its parameters", OFFSET(model_filename), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { "model", "path to model file specifying network architecture and its parameters", OFFSET(dnnctx.model_filename), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { "input", "input name of the model", OFFSET(dnnctx.model_inputname), AV_OPT_TYPE_STRING, { .str = "x" }, 0, 0, FLAGS }, + { "output", "output name of the model", OFFSET(dnnctx.model_outputname), AV_OPT_TYPE_STRING, { .str = "y" }, 0, 0, FLAGS }, { NULL } }; @@ -66,33 +63,7 @@ AVFILTER_DEFINE_CLASS(sr); static av_cold int init(AVFilterContext *context) { SRContext *sr_context = context->priv; - - sr_context->dnn_module = ff_get_dnn_module(sr_context->backend_type); - if (!sr_context->dnn_module){ - av_log(context, AV_LOG_ERROR, "could not create DNN module for requested backend\n"); - return AVERROR(ENOMEM); - } - - if (!sr_context->model_filename){ - av_log(context, AV_LOG_ERROR, "model file for network was not specified\n"); - return AVERROR(EIO); - } - if (!sr_context->dnn_module->load_model) { - av_log(context, AV_LOG_ERROR, "load_model for network was not specified\n"); - return AVERROR(EIO); - } - sr_context->model = (sr_context->dnn_module->load_model)(sr_context->model_filename); - if (!sr_context->model){ - av_log(context, AV_LOG_ERROR, "could not load DNN model\n"); - return AVERROR(EIO); - } - - sr_context->input.dt = DNN_FLOAT; - sr_context->sws_contexts[0] = NULL; - sr_context->sws_contexts[1] = NULL; - sr_context->sws_contexts[2] = NULL; - - return 0; + return ff_dnn_init(&sr_context->dnnctx, DFT_PROCESS_FRAME, context); } static int query_formats(AVFilterContext *context) @@ -111,86 +82,43 @@ static int query_formats(AVFilterContext *context) return ff_set_common_formats(context, formats_list); } -static int config_props(AVFilterLink *inlink) +static int config_output(AVFilterLink *outlink) { - AVFilterContext *context = inlink->dst; - SRContext *sr_context = context->priv; - AVFilterLink *outlink = context->outputs[0]; + AVFilterContext *context = outlink->src; + SRContext *ctx = context->priv; DNNReturnType result; - int sws_src_h, sws_src_w, sws_dst_h, sws_dst_w; - const char *model_output_name = "y"; + AVFilterLink *inlink = context->inputs[0]; + int out_width, out_height; - sr_context->input.width = inlink->w * sr_context->scale_factor; - sr_context->input.height = inlink->h * sr_context->scale_factor; - sr_context->input.channels = 1; - - result = (sr_context->model->set_input_output)(sr_context->model->model, &sr_context->input, "x", &model_output_name, 1); - if (result != DNN_SUCCESS){ - av_log(context, AV_LOG_ERROR, "could not set input and output for the model\n"); + // have a try run in case that the dnn model resize the frame + result = ff_dnn_get_output(&ctx->dnnctx, inlink->w, inlink->h, &out_width, &out_height); + if (result != DNN_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "could not get output from the model\n"); return AVERROR(EIO); } - result = (sr_context->dnn_module->execute_model)(sr_context->model, &sr_context->output, 1); - if (result != DNN_SUCCESS){ - av_log(context, AV_LOG_ERROR, "failed to execute loaded model\n"); - return AVERROR(EIO); - } - - if (sr_context->input.height != sr_context->output.height || sr_context->input.width != sr_context->output.width){ - sr_context->input.width = inlink->w; - sr_context->input.height = inlink->h; - result = (sr_context->model->set_input_output)(sr_context->model->model, &sr_context->input, "x", &model_output_name, 1); - if (result != DNN_SUCCESS){ - av_log(context, AV_LOG_ERROR, "could not set input and output for the model\n"); - return AVERROR(EIO); - } - result = (sr_context->dnn_module->execute_model)(sr_context->model, &sr_context->output, 1); - if (result != DNN_SUCCESS){ - av_log(context, AV_LOG_ERROR, "failed to execute loaded model\n"); - return AVERROR(EIO); - } - sr_context->scale_factor = 0; - } - outlink->h = sr_context->output.height; - outlink->w = sr_context->output.width; - sr_context->sws_contexts[1] = sws_getContext(sr_context->input.width, sr_context->input.height, AV_PIX_FMT_GRAY8, - sr_context->input.width, sr_context->input.height, AV_PIX_FMT_GRAYF32, - 0, NULL, NULL, NULL); - sr_context->sws_input_linesize = sr_context->input.width << 2; - sr_context->sws_contexts[2] = sws_getContext(sr_context->output.width, sr_context->output.height, AV_PIX_FMT_GRAYF32, - sr_context->output.width, sr_context->output.height, AV_PIX_FMT_GRAY8, - 0, NULL, NULL, NULL); - sr_context->sws_output_linesize = sr_context->output.width << 2; - if (!sr_context->sws_contexts[1] || !sr_context->sws_contexts[2]){ - av_log(context, AV_LOG_ERROR, "could not create SwsContext for conversions\n"); - return AVERROR(ENOMEM); - } - if (sr_context->scale_factor){ - sr_context->sws_contexts[0] = sws_getContext(inlink->w, inlink->h, inlink->format, - outlink->w, outlink->h, outlink->format, - SWS_BICUBIC, NULL, NULL, NULL); - if (!sr_context->sws_contexts[0]){ - av_log(context, AV_LOG_ERROR, "could not create SwsContext for scaling\n"); - return AVERROR(ENOMEM); - } - sr_context->sws_slice_h = inlink->h; - } else { + if (inlink->w != out_width || inlink->h != out_height) { + //espcn + outlink->w = out_width; + outlink->h = out_height; if (inlink->format != AV_PIX_FMT_GRAY8){ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - sws_src_h = AV_CEIL_RSHIFT(sr_context->input.height, desc->log2_chroma_h); - sws_src_w = AV_CEIL_RSHIFT(sr_context->input.width, desc->log2_chroma_w); - sws_dst_h = AV_CEIL_RSHIFT(sr_context->output.height, desc->log2_chroma_h); - sws_dst_w = AV_CEIL_RSHIFT(sr_context->output.width, desc->log2_chroma_w); - - sr_context->sws_contexts[0] = sws_getContext(sws_src_w, sws_src_h, AV_PIX_FMT_GRAY8, - sws_dst_w, sws_dst_h, AV_PIX_FMT_GRAY8, - SWS_BICUBIC, NULL, NULL, NULL); - if (!sr_context->sws_contexts[0]){ - av_log(context, AV_LOG_ERROR, "could not create SwsContext for scaling\n"); - return AVERROR(ENOMEM); - } - sr_context->sws_slice_h = sws_src_h; + int sws_src_h = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + int sws_src_w = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + int sws_dst_h = AV_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h); + int sws_dst_w = AV_CEIL_RSHIFT(outlink->w, desc->log2_chroma_w); + ctx->sws_uv_scale = sws_getContext(sws_src_w, sws_src_h, AV_PIX_FMT_GRAY8, + sws_dst_w, sws_dst_h, AV_PIX_FMT_GRAY8, + SWS_BICUBIC, NULL, NULL, NULL); + ctx->sws_uv_height = sws_src_h; } + } else { + //srcnn + outlink->w = out_width * ctx->scale_factor; + outlink->h = out_height * ctx->scale_factor; + ctx->sws_pre_scale = sws_getContext(inlink->w, inlink->h, inlink->format, + outlink->w, outlink->h, outlink->format, + SWS_BICUBIC, NULL, NULL, NULL); } return 0; @@ -199,7 +127,7 @@ static int config_props(AVFilterLink *inlink) static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *context = inlink->dst; - SRContext *sr_context = context->priv; + SRContext *ctx = context->priv; AVFilterLink *outlink = context->outputs[0]; AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h); DNNReturnType dnn_result; @@ -210,62 +138,47 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return AVERROR(ENOMEM); } av_frame_copy_props(out, in); - out->height = sr_context->output.height; - out->width = sr_context->output.width; - if (sr_context->scale_factor){ - sws_scale(sr_context->sws_contexts[0], (const uint8_t **)in->data, in->linesize, - 0, sr_context->sws_slice_h, out->data, out->linesize); - sws_scale(sr_context->sws_contexts[1], (const uint8_t **)out->data, out->linesize, - 0, out->height, (uint8_t * const*)(&sr_context->input.data), - (const int [4]){sr_context->sws_input_linesize, 0, 0, 0}); + if (ctx->sws_pre_scale) { + sws_scale(ctx->sws_pre_scale, + (const uint8_t **)in->data, in->linesize, 0, in->height, + out->data, out->linesize); + dnn_result = ff_dnn_execute_model(&ctx->dnnctx, out, out); } else { - if (sr_context->sws_contexts[0]){ - sws_scale(sr_context->sws_contexts[0], (const uint8_t **)(in->data + 1), in->linesize + 1, - 0, sr_context->sws_slice_h, out->data + 1, out->linesize + 1); - sws_scale(sr_context->sws_contexts[0], (const uint8_t **)(in->data + 2), in->linesize + 2, - 0, sr_context->sws_slice_h, out->data + 2, out->linesize + 2); - } - - sws_scale(sr_context->sws_contexts[1], (const uint8_t **)in->data, in->linesize, - 0, in->height, (uint8_t * const*)(&sr_context->input.data), - (const int [4]){sr_context->sws_input_linesize, 0, 0, 0}); + dnn_result = ff_dnn_execute_model(&ctx->dnnctx, in, out); } - av_frame_free(&in); - dnn_result = (sr_context->dnn_module->execute_model)(sr_context->model, &sr_context->output, 1); if (dnn_result != DNN_SUCCESS){ - av_log(context, AV_LOG_ERROR, "failed to execute loaded model\n"); + av_log(ctx, AV_LOG_ERROR, "failed to execute loaded model\n"); + av_frame_free(&in); + av_frame_free(&out); return AVERROR(EIO); } - sws_scale(sr_context->sws_contexts[2], (const uint8_t *[4]){(const uint8_t *)sr_context->output.data, 0, 0, 0}, - (const int[4]){sr_context->sws_output_linesize, 0, 0, 0}, - 0, out->height, (uint8_t * const*)out->data, out->linesize); + if (ctx->sws_uv_scale) { + sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 1), in->linesize + 1, + 0, ctx->sws_uv_height, out->data + 1, out->linesize + 1); + sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 2), in->linesize + 2, + 0, ctx->sws_uv_height, out->data + 2, out->linesize + 2); + } + av_frame_free(&in); return ff_filter_frame(outlink, out); } static av_cold void uninit(AVFilterContext *context) { - int i; SRContext *sr_context = context->priv; - if (sr_context->dnn_module){ - (sr_context->dnn_module->free_model)(&sr_context->model); - av_freep(&sr_context->dnn_module); - } - - for (i = 0; i < 3; ++i){ - sws_freeContext(sr_context->sws_contexts[i]); - } + ff_dnn_uninit(&sr_context->dnnctx); + sws_freeContext(sr_context->sws_uv_scale); + sws_freeContext(sr_context->sws_pre_scale); } static const AVFilterPad sr_inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, .filter_frame = filter_frame, }, { NULL } @@ -274,6 +187,7 @@ static const AVFilterPad sr_inputs[] = { static const AVFilterPad sr_outputs[] = { { .name = "default", + .config_props = config_output, .type = AVMEDIA_TYPE_VIDEO, }, { NULL } diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c index a32fada22..ebb314c69 100644 --- a/libavfilter/vf_ssim.c +++ b/libavfilter/vf_ssim.c @@ -51,6 +51,7 @@ typedef struct SSIMContext { FILE *stats_file; char *stats_file_str; int nb_components; + int nb_threads; int max; uint64_t nb_frames; double ssim[4], ssim_total; @@ -59,13 +60,11 @@ typedef struct SSIMContext { uint8_t rgba_map[4]; int planewidth[4]; int planeheight[4]; - int *temp; + int **temp; int is_rgb; - double (*ssim_plane)(SSIMDSPContext *dsp, - uint8_t *main, int main_stride, - uint8_t *ref, int ref_stride, - int width, int height, void *temp, - int max); + double **score; + int (*ssim_plane)(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs); SSIMDSPContext dsp; } SSIMContext; @@ -83,7 +82,7 @@ FRAMESYNC_DEFINE_CLASS(ssim, SSIMContext, fs); static void set_meta(AVDictionary **metadata, const char *key, char comp, float d) { char value[128]; - snprintf(value, sizeof(value), "%0.2f", d); + snprintf(value, sizeof(value), "%f", d); if (comp) { char key2[128]; snprintf(key2, sizeof(key2), "%s%c", key, comp); @@ -221,60 +220,104 @@ static double ssim_endn_8bit(const int (*sum0)[4], const int (*sum1)[4], int wid #define SUM_LEN(w) (((w) >> 2) + 3) -static double ssim_plane_16bit(SSIMDSPContext *dsp, - uint8_t *main, int main_stride, - uint8_t *ref, int ref_stride, - int width, int height, void *temp, - int max) +typedef struct ThreadData { + const uint8_t *main_data[4]; + const uint8_t *ref_data[4]; + int main_linesize[4]; + int ref_linesize[4]; + int planewidth[4]; + int planeheight[4]; + double **score; + int **temp; + int nb_components; + int max; + SSIMDSPContext *dsp; +} ThreadData; + +static int ssim_plane_16bit(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs) { - int z = 0, y; - double ssim = 0.0; - int64_t (*sum0)[4] = temp; - int64_t (*sum1)[4] = sum0 + SUM_LEN(width); + ThreadData *td = arg; + double *score = td->score[jobnr]; + void *temp = td->temp[jobnr]; + const int max = td->max; - width >>= 2; - height >>= 2; + for (int c = 0; c < td->nb_components; c++) { + const uint8_t *main_data = td->main_data[c]; + const uint8_t *ref_data = td->ref_data[c]; + const int main_stride = td->main_linesize[c]; + const int ref_stride = td->ref_linesize[c]; + int width = td->planewidth[c]; + int height = td->planeheight[c]; + const int slice_start = ((height >> 2) * jobnr) / nb_jobs; + const int slice_end = ((height >> 2) * (jobnr+1)) / nb_jobs; + const int ystart = FFMAX(1, slice_start); + int z = ystart - 1; + double ssim = 0.0; + int64_t (*sum0)[4] = temp; + int64_t (*sum1)[4] = sum0 + SUM_LEN(width); - for (y = 1; y < height; y++) { - for (; z <= y; z++) { - FFSWAP(void*, sum0, sum1); - ssim_4x4xn_16bit(&main[4 * z * main_stride], main_stride, - &ref[4 * z * ref_stride], ref_stride, - sum0, width); + width >>= 2; + height >>= 2; + + for (int y = ystart; y < slice_end; y++) { + for (; z <= y; z++) { + FFSWAP(void*, sum0, sum1); + ssim_4x4xn_16bit(&main_data[4 * z * main_stride], main_stride, + &ref_data[4 * z * ref_stride], ref_stride, + sum0, width); + } + + ssim += ssim_endn_16bit((const int64_t (*)[4])sum0, (const int64_t (*)[4])sum1, width - 1, max); } - ssim += ssim_endn_16bit((const int64_t (*)[4])sum0, (const int64_t (*)[4])sum1, width - 1, max); + score[c] = ssim; } - return ssim / ((height - 1) * (width - 1)); + return 0; } -static double ssim_plane(SSIMDSPContext *dsp, - uint8_t *main, int main_stride, - uint8_t *ref, int ref_stride, - int width, int height, void *temp, - int max) +static int ssim_plane(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs) { - int z = 0, y; - double ssim = 0.0; - int (*sum0)[4] = temp; - int (*sum1)[4] = sum0 + SUM_LEN(width); + ThreadData *td = arg; + double *score = td->score[jobnr]; + void *temp = td->temp[jobnr]; + SSIMDSPContext *dsp = td->dsp; - width >>= 2; - height >>= 2; + for (int c = 0; c < td->nb_components; c++) { + const uint8_t *main_data = td->main_data[c]; + const uint8_t *ref_data = td->ref_data[c]; + const int main_stride = td->main_linesize[c]; + const int ref_stride = td->ref_linesize[c]; + int width = td->planewidth[c]; + int height = td->planeheight[c]; + const int slice_start = ((height >> 2) * jobnr) / nb_jobs; + const int slice_end = ((height >> 2) * (jobnr+1)) / nb_jobs; + const int ystart = FFMAX(1, slice_start); + int z = ystart - 1; + double ssim = 0.0; + int (*sum0)[4] = temp; + int (*sum1)[4] = sum0 + SUM_LEN(width); - for (y = 1; y < height; y++) { - for (; z <= y; z++) { - FFSWAP(void*, sum0, sum1); - dsp->ssim_4x4_line(&main[4 * z * main_stride], main_stride, - &ref[4 * z * ref_stride], ref_stride, - sum0, width); + width >>= 2; + height >>= 2; + + for (int y = ystart; y < slice_end; y++) { + for (; z <= y; z++) { + FFSWAP(void*, sum0, sum1); + dsp->ssim_4x4_line(&main_data[4 * z * main_stride], main_stride, + &ref_data[4 * z * ref_stride], ref_stride, + sum0, width); + } + + ssim += dsp->ssim_end_line((const int (*)[4])sum0, (const int (*)[4])sum1, width - 1); } - ssim += dsp->ssim_end_line((const int (*)[4])sum0, (const int (*)[4])sum1, width - 1); + score[c] = ssim; } - return ssim / ((height - 1) * (width - 1)); + return 0; } static double ssim_db(double ssim, double weight) @@ -288,26 +331,47 @@ static int do_ssim(FFFrameSync *fs) SSIMContext *s = ctx->priv; AVFrame *master, *ref; AVDictionary **metadata; - double c[4] = { 0 }, ssimv = 0.0; + double c[4] = {0}, ssimv = 0.0; + ThreadData td; int ret, i; ret = ff_framesync_dualinput_get(fs, &master, &ref); if (ret < 0) return ret; - if (!ref) + if (ctx->is_disabled || !ref) return ff_filter_frame(ctx->outputs[0], master); metadata = &master->metadata; s->nb_frames++; + td.nb_components = s->nb_components; + td.dsp = &s->dsp; + td.score = s->score; + td.temp = s->temp; + td.max = s->max; + + for (int n = 0; n < s->nb_components; n++) { + td.main_data[n] = master->data[n]; + td.ref_data[n] = ref->data[n]; + td.main_linesize[n] = master->linesize[n]; + td.ref_linesize[n] = ref->linesize[n]; + td.planewidth[n] = s->planewidth[n]; + td.planeheight[n] = s->planeheight[n]; + } + + ctx->internal->execute(ctx, s->ssim_plane, &td, NULL, FFMIN((s->planeheight[1] + 3) >> 2, s->nb_threads)); + + for (i = 0; i < s->nb_components; i++) { + for (int j = 0; j < s->nb_threads; j++) + c[i] += s->score[j][i]; + c[i] = c[i] / (((s->planewidth[i] >> 2) - 1) * ((s->planeheight[i] >> 2) - 1)); + } + for (i = 0; i < s->nb_components; i++) { - c[i] = s->ssim_plane(&s->dsp, master->data[i], master->linesize[i], - ref->data[i], ref->linesize[i], - s->planewidth[i], s->planeheight[i], s->temp, - s->max); ssimv += s->coefs[i] * c[i]; s->ssim[i] += c[i]; } + for (i = 0; i < s->nb_components; i++) { int cidx = s->is_rgb ? s->rgba_map[i] : i; set_meta(metadata, "lavfi.ssim.", s->comps[i], c[cidx]); @@ -383,6 +447,7 @@ static int config_input_ref(AVFilterLink *inlink) SSIMContext *s = ctx->priv; int sum = 0, i; + s->nb_threads = ff_filter_get_nb_threads(ctx); s->nb_components = desc->nb_components; if (ctx->inputs[0]->w != ctx->inputs[1]->w || @@ -410,9 +475,15 @@ static int config_input_ref(AVFilterLink *inlink) for (i = 0; i < s->nb_components; i++) s->coefs[i] = (double) s->planeheight[i] * s->planewidth[i] / sum; - s->temp = av_mallocz_array(2 * SUM_LEN(inlink->w), (desc->comp[0].depth > 8) ? sizeof(int64_t[4]) : sizeof(int[4])); + s->temp = av_calloc(s->nb_threads, sizeof(*s->temp)); if (!s->temp) return AVERROR(ENOMEM); + + for (int t = 0; t < s->nb_threads; t++) { + s->temp[t] = av_mallocz_array(2 * SUM_LEN(inlink->w), (desc->comp[0].depth > 8) ? sizeof(int64_t[4]) : sizeof(int[4])); + if (!s->temp[t]) + return AVERROR(ENOMEM); + } s->max = (1 << desc->comp[0].depth) - 1; s->ssim_plane = desc->comp[0].depth > 8 ? ssim_plane_16bit : ssim_plane; @@ -421,6 +492,16 @@ static int config_input_ref(AVFilterLink *inlink) if (ARCH_X86) ff_ssim_init_x86(&s->dsp); + s->score = av_calloc(s->nb_threads, sizeof(*s->score)); + if (!s->score) + return AVERROR(ENOMEM); + + for (int t = 0; t < s->nb_threads && s->score; t++) { + s->score[t] = av_calloc(s->nb_components, sizeof(*s->score[0])); + if (!s->score[t]) + return AVERROR(ENOMEM); + } + return 0; } @@ -482,6 +563,12 @@ static av_cold void uninit(AVFilterContext *ctx) if (s->stats_file && s->stats_file != stdout) fclose(s->stats_file); + for (int t = 0; t < s->nb_threads && s->score; t++) + av_freep(&s->score[t]); + av_freep(&s->score); + + for (int t = 0; t < s->nb_threads && s->temp; t++) + av_freep(&s->temp[t]); av_freep(&s->temp); } @@ -518,4 +605,5 @@ AVFilter ff_vf_ssim = { .priv_class = &ssim_class, .inputs = ssim_inputs, .outputs = ssim_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c index 35b7177e8..3d2b19a31 100644 --- a/libavfilter/vf_stack.c +++ b/libavfilter/vf_stack.c @@ -60,24 +60,21 @@ typedef struct StackContext { static int query_formats(AVFilterContext *ctx) { - AVFilterFormats *pix_fmts = NULL; + AVFilterFormats *formats = NULL; StackContext *s = ctx->priv; - int fmt, ret; + int ret; if (s->fillcolor_enable) { return ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); } - for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_HWACCEL || - desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) && - (ret = ff_add_format(&pix_fmts, fmt)) < 0) - return ret; - } - - return ff_set_common_formats(ctx, pix_fmts); + ret = ff_formats_pixdesc_filter(&formats, 0, + AV_PIX_FMT_FLAG_HWACCEL | + AV_PIX_FMT_FLAG_BITSTREAM | + AV_PIX_FMT_FLAG_PAL); + if (ret < 0) + return ret; + return ff_set_common_formats(ctx, formats); } static av_cold int init(AVFilterContext *ctx) diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c index a3b4029af..de74afa2b 100644 --- a/libavfilter/vf_subtitles.c +++ b/libavfilter/vf_subtitles.c @@ -302,7 +302,7 @@ static av_cold int init_subtitles(AVFilterContext *ctx) AVDictionary *codec_opts = NULL; AVFormatContext *fmt = NULL; AVCodecContext *dec_ctx = NULL; - AVCodec *dec = NULL; + const AVCodec *dec; const AVCodecDescriptor *dec_desc; AVStream *st; AVPacket pkt; @@ -384,22 +384,25 @@ static av_cold int init_subtitles(AVFilterContext *ctx) if (!dec) { av_log(ctx, AV_LOG_ERROR, "Failed to find subtitle codec %s\n", avcodec_get_name(st->codecpar->codec_id)); - return AVERROR(EINVAL); + ret = AVERROR_DECODER_NOT_FOUND; + goto end; } dec_desc = avcodec_descriptor_get(st->codecpar->codec_id); if (dec_desc && !(dec_desc->props & AV_CODEC_PROP_TEXT_SUB)) { av_log(ctx, AV_LOG_ERROR, "Only text based subtitles are currently supported\n"); - return AVERROR_PATCHWELCOME; + ret = AVERROR_PATCHWELCOME; + goto end; } if (ass->charenc) av_dict_set(&codec_opts, "sub_charenc", ass->charenc, 0); - if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57,26,100)) - av_dict_set(&codec_opts, "sub_text_format", "ass", 0); + av_dict_set(&codec_opts, "sub_text_format", "ass", 0); dec_ctx = avcodec_alloc_context3(dec); - if (!dec_ctx) - return AVERROR(ENOMEM); + if (!dec_ctx) { + ret = AVERROR(ENOMEM); + goto end; + } ret = avcodec_parameters_to_context(dec_ctx, st->codecpar); if (ret < 0) @@ -445,9 +448,6 @@ static av_cold int init_subtitles(AVFilterContext *ctx) ass_process_codec_private(ass->track, dec_ctx->subtitle_header, dec_ctx->subtitle_header_size); - av_init_packet(&pkt); - pkt.data = NULL; - pkt.size = 0; while (av_read_frame(fmt, &pkt) >= 0) { int i, got_subtitle; AVSubtitle sub = {0}; @@ -464,11 +464,8 @@ static av_cold int init_subtitles(AVFilterContext *ctx) char *ass_line = sub.rects[i]->ass; if (!ass_line) break; - if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57,25,100)) - ass_process_data(ass->track, ass_line, strlen(ass_line)); - else - ass_process_chunk(ass->track, ass_line, strlen(ass_line), - start_time, duration); + ass_process_chunk(ass->track, ass_line, strlen(ass_line), + start_time, duration); } } } @@ -478,7 +475,6 @@ static av_cold int init_subtitles(AVFilterContext *ctx) end: av_dict_free(&codec_opts); - avcodec_close(dec_ctx); avcodec_free_context(&dec_ctx); avformat_close_input(&fmt); return ret; diff --git a/libavfilter/vf_super2xsai.c b/libavfilter/vf_super2xsai.c index 87eec04da..d6c5f44c1 100644 --- a/libavfilter/vf_super2xsai.c +++ b/libavfilter/vf_super2xsai.c @@ -46,6 +46,10 @@ typedef struct Super2xSaIContext { int is_be; } Super2xSaIContext; +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D)) #define INTERPOLATE(A, B) (((A & hi_pixel_mask) >> 1) + ((B & hi_pixel_mask) >> 1) + (A & B & lo_pixel_mask)) @@ -53,32 +57,40 @@ typedef struct Super2xSaIContext { #define Q_INTERPOLATE(A, B, C, D) ((A & q_hi_pixel_mask) >> 2) + ((B & q_hi_pixel_mask) >> 2) + ((C & q_hi_pixel_mask) >> 2) + ((D & q_hi_pixel_mask) >> 2) \ + ((((A & q_lo_pixel_mask) + (B & q_lo_pixel_mask) + (C & q_lo_pixel_mask) + (D & q_lo_pixel_mask)) >> 2) & q_lo_pixel_mask) -static void super2xsai(AVFilterContext *ctx, - uint8_t *src, int src_linesize, - uint8_t *dst, int dst_linesize, - int width, int height) +static int super2xsai(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { Super2xSaIContext *s = ctx->priv; + ThreadData *td = arg; + AVFrame *in = td->in; + AVFrame *out = td->out; + const uint8_t *src = in->data[0]; + uint8_t *dst = out->data[0]; + const int src_linesize = in->linesize[0]; + const int dst_linesize = out->linesize[0]; + const int width = in->width; + const int height = in->height; unsigned int x, y; uint32_t color[4][4]; - unsigned char *src_line[4]; + const uint8_t *src_line[4]; const int bpp = s->bpp; const uint32_t hi_pixel_mask = s->hi_pixel_mask; const uint32_t lo_pixel_mask = s->lo_pixel_mask; const uint32_t q_hi_pixel_mask = s->q_hi_pixel_mask; const uint32_t q_lo_pixel_mask = s->q_lo_pixel_mask; + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr+1)) / nb_jobs; /* Point to the first 4 lines, first line is duplicated */ - src_line[0] = src; - src_line[1] = src; - src_line[2] = src + src_linesize*FFMIN(1, height-1); - src_line[3] = src + src_linesize*FFMIN(2, height-1); + src_line[0] = src + src_linesize*FFMAX(slice_start - 1, 0); + src_line[1] = src + src_linesize*slice_start; + src_line[2] = src + src_linesize*FFMIN(slice_start + 1, height-1); + src_line[3] = src + src_linesize*FFMIN(slice_start + 2, height-1); #define READ_COLOR4(dst, src_line, off) dst = *((const uint32_t *)src_line + off) #define READ_COLOR3(dst, src_line, off) dst = AV_RL24 (src_line + 3*off) #define READ_COLOR2(dst, src_line, off) dst = s->is_be ? AV_RB16(src_line + 2 * off) : AV_RL16(src_line + 2 * off) - for (y = 0; y < height; y++) { + for (y = slice_start; y < slice_end; y++) { uint8_t *dst_line[2]; dst_line[0] = dst + dst_linesize*2*y; @@ -229,6 +241,8 @@ static void super2xsai(AVFilterContext *ctx, if (y < height - 3) src_line[3] += src_linesize; } // y loop + + return 0; } static int query_formats(AVFilterContext *ctx) @@ -305,24 +319,25 @@ static int config_output(AVFilterLink *outlink) return 0; } -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) +static int filter_frame(AVFilterLink *inlink, AVFrame *in) { - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpicref) { - av_frame_free(&inpicref); + AVFilterContext *ctx = inlink->dst; + AVFilterLink *outlink = ctx->outputs[0]; + ThreadData td; + AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); return AVERROR(ENOMEM); } - av_frame_copy_props(outpicref, inpicref); - outpicref->width = outlink->w; - outpicref->height = outlink->h; + av_frame_copy_props(out, in); + out->width = outlink->w; + out->height = outlink->h; - super2xsai(inlink->dst, inpicref->data[0], inpicref->linesize[0], - outpicref->data[0], outpicref->linesize[0], - inlink->w, inlink->h); + td.in = in, td.out = out; + ctx->internal->execute(ctx, super2xsai, &td, NULL, FFMIN(in->height, ff_filter_get_nb_threads(ctx))); - av_frame_free(&inpicref); - return ff_filter_frame(outlink, outpicref); + av_frame_free(&in); + return ff_filter_frame(outlink, out); } static const AVFilterPad super2xsai_inputs[] = { @@ -351,4 +366,5 @@ AVFilter ff_vf_super2xsai = { .query_formats = query_formats, .inputs = super2xsai_inputs, .outputs = super2xsai_outputs, + .flags = AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/vf_swaprect.c b/libavfilter/vf_swaprect.c index cf9c298f2..66bed161f 100644 --- a/libavfilter/vf_swaprect.c +++ b/libavfilter/vf_swaprect.c @@ -43,7 +43,7 @@ typedef struct SwapRectContext { } SwapRectContext; #define OFFSET(x) offsetof(SwapRectContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM static const AVOption swaprect_options[] = { { "w", "set rect width", OFFSET(w), AV_OPT_TYPE_STRING, {.str="w/2"}, 0, 0, .flags = FLAGS }, { "h", "set rect height", OFFSET(h), AV_OPT_TYPE_STRING, {.str="h/2"}, 0, 0, .flags = FLAGS }, @@ -253,4 +253,5 @@ AVFilter ff_vf_swaprect = { .inputs = inputs, .outputs = outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, + .process_command = ff_filter_process_command, }; diff --git a/libavfilter/vf_telecine.c b/libavfilter/vf_telecine.c index 741b19a4f..6563b4972 100644 --- a/libavfilter/vf_telecine.c +++ b/libavfilter/vf_telecine.c @@ -101,19 +101,16 @@ static av_cold int init(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { - AVFilterFormats *pix_fmts = NULL; - int fmt, ret; + AVFilterFormats *formats = NULL; + int ret; - for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL || - desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) && - (ret = ff_add_format(&pix_fmts, fmt)) < 0) - return ret; - } - - return ff_set_common_formats(ctx, pix_fmts); + ret = ff_formats_pixdesc_filter(&formats, 0, + AV_PIX_FMT_FLAG_BITSTREAM | + AV_PIX_FMT_FLAG_PAL | + AV_PIX_FMT_FLAG_HWACCEL); + if (ret < 0) + return ret; + return ff_set_common_formats(ctx, formats); } static int config_input(AVFilterLink *inlink) diff --git a/libavfilter/vf_threshold.c b/libavfilter/vf_threshold.c index ee29c88ef..11623d394 100644 --- a/libavfilter/vf_threshold.c +++ b/libavfilter/vf_threshold.c @@ -52,10 +52,12 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, - AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, + AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, diff --git a/libavfilter/vf_thumbnail.c b/libavfilter/vf_thumbnail.c index ac04615bd..e49b70c3b 100644 --- a/libavfilter/vf_thumbnail.c +++ b/libavfilter/vf_thumbnail.c @@ -28,6 +28,7 @@ */ #include "libavutil/opt.h" +#include "libavutil/pixdesc.h" #include "avfilter.h" #include "internal.h" @@ -44,6 +45,9 @@ typedef struct ThumbContext { int n_frames; ///< number of frames for analysis struct thumb_frame *frames; ///< the n_frames frames AVRational tb; ///< copy of the input timebase to ease access + + int planewidth[4]; + int planeheight[4]; } ThumbContext; #define OFFSET(x) offsetof(ThumbContext, x) @@ -140,14 +144,55 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) // keep a reference of each frame s->frames[s->n].buf = frame; - // update current frame RGB histogram - for (j = 0; j < inlink->h; j++) { - for (i = 0; i < inlink->w; i++) { - hist[0*256 + p[i*3 ]]++; - hist[1*256 + p[i*3 + 1]]++; - hist[2*256 + p[i*3 + 2]]++; + // update current frame histogram + switch (inlink->format) { + case AV_PIX_FMT_RGB24: + case AV_PIX_FMT_BGR24: + for (j = 0; j < inlink->h; j++) { + for (i = 0; i < inlink->w; i++) { + hist[0*256 + p[i*3 ]]++; + hist[1*256 + p[i*3 + 1]]++; + hist[2*256 + p[i*3 + 2]]++; + } + p += frame->linesize[0]; } - p += frame->linesize[0]; + break; + case AV_PIX_FMT_RGB0: + case AV_PIX_FMT_BGR0: + case AV_PIX_FMT_RGBA: + case AV_PIX_FMT_BGRA: + for (j = 0; j < inlink->h; j++) { + for (i = 0; i < inlink->w; i++) { + hist[0*256 + p[i*4 ]]++; + hist[1*256 + p[i*4 + 1]]++; + hist[2*256 + p[i*4 + 2]]++; + } + p += frame->linesize[0]; + } + break; + case AV_PIX_FMT_0RGB: + case AV_PIX_FMT_0BGR: + case AV_PIX_FMT_ARGB: + case AV_PIX_FMT_ABGR: + for (j = 0; j < inlink->h; j++) { + for (i = 0; i < inlink->w; i++) { + hist[0*256 + p[i*4 + 1]]++; + hist[1*256 + p[i*4 + 2]]++; + hist[2*256 + p[i*4 + 3]]++; + } + p += frame->linesize[0]; + } + break; + default: + for (int plane = 0; plane < 3; plane++) { + const uint8_t *p = frame->data[plane]; + for (j = 0; j < s->planeheight[plane]; j++) { + for (i = 0; i < s->planewidth[plane]; i++) + hist[256*plane + p[i]]++; + p += frame->linesize[plane]; + } + } + break; } // no selection until the buffer of N frames is filled up @@ -188,8 +233,14 @@ static int config_props(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; ThumbContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); s->tb = inlink->time_base; + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + return 0; } @@ -197,6 +248,18 @@ static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, + AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, + AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, + AV_PIX_FMT_ABGR, AV_PIX_FMT_ARGB, + AV_PIX_FMT_0BGR, AV_PIX_FMT_0RGB, + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE }; AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); diff --git a/libavfilter/vf_tile.c b/libavfilter/vf_tile.c index 6278f72ab..7e421a972 100644 --- a/libavfilter/vf_tile.c +++ b/libavfilter/vf_tile.c @@ -63,7 +63,7 @@ static const AVOption tile_options[] = { { "color", "set the color of the unused area", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str = "black"}, .flags = FLAGS }, { "overlap", "set how many frames to overlap for each render", OFFSET(overlap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, - { "init_padding", " set how many frames to initially pad", OFFSET(init_padding), + { "init_padding", "set how many frames to initially pad", OFFSET(init_padding), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, { NULL } }; diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c index a77753775..542b66898 100644 --- a/libavfilter/vf_tinterlace.c +++ b/libavfilter/vf_tinterlace.c @@ -396,12 +396,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) copy_picture_field(tinterlace, out->data, out->linesize, (const uint8_t **)cur->data, cur->linesize, inlink->format, inlink->w, inlink->h, - FIELD_UPPER_AND_LOWER, 1, tinterlace->mode == MODE_MERGEX2 ? inlink->frame_count_out & 1 ? FIELD_LOWER : FIELD_UPPER : FIELD_UPPER, tinterlace->flags); + FIELD_UPPER_AND_LOWER, 1, tinterlace->mode == MODE_MERGEX2 ? (1 + inlink->frame_count_out) & 1 ? FIELD_LOWER : FIELD_UPPER : FIELD_UPPER, tinterlace->flags); /* write even frame lines into the lower field of the new frame */ copy_picture_field(tinterlace, out->data, out->linesize, (const uint8_t **)next->data, next->linesize, inlink->format, inlink->w, inlink->h, - FIELD_UPPER_AND_LOWER, 1, tinterlace->mode == MODE_MERGEX2 ? inlink->frame_count_out & 1 ? FIELD_UPPER : FIELD_LOWER : FIELD_LOWER, tinterlace->flags); + FIELD_UPPER_AND_LOWER, 1, tinterlace->mode == MODE_MERGEX2 ? (1 + inlink->frame_count_out) & 1 ? FIELD_UPPER : FIELD_LOWER : FIELD_LOWER, tinterlace->flags); if (tinterlace->mode != MODE_MERGEX2) av_frame_free(&tinterlace->next); break; @@ -423,7 +423,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) out->height = outlink->h; out->sample_aspect_ratio = av_mul_q(cur->sample_aspect_ratio, av_make_q(2, 1)); - field = (1 + tinterlace->frame) & 1 ? FIELD_UPPER : FIELD_LOWER; + field = (1 + outlink->frame_count_in) & 1 ? FIELD_UPPER : FIELD_LOWER; /* copy upper and lower fields */ copy_picture_field(tinterlace, out->data, out->linesize, (const uint8_t **)cur->data, cur->linesize, @@ -517,7 +517,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) out->pts = av_rescale_q(out->pts, tinterlace->preout_time_base, outlink->time_base); ret = ff_filter_frame(outlink, out); - tinterlace->frame++; return ret; } diff --git a/libavfilter/vf_tmidequalizer.c b/libavfilter/vf_tmidequalizer.c new file mode 100644 index 000000000..6e3f3ccce --- /dev/null +++ b/libavfilter/vf_tmidequalizer.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2020 Paul B Mahol + * + * 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/imgutils.h" +#include "libavutil/pixdesc.h" +#include "libavutil/opt.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct TMidEqualizerContext { + const AVClass *class; + + int planes; + int radius; + float sigma; + + int plane_width[4], plane_height[4]; + int nb_frames; + int depth; + int f_frames; + int l_frames; + int del_frame; + int cur_frame; + int nb_planes; + int histogram_size; + float kernel[127]; + float *histogram[4][256]; + float *change[4]; + + AVFrame **frames; + + void (*compute_histogram)(const uint8_t *ssrc, ptrdiff_t linesize, + int w, int h, float *histogram, size_t hsize); + void (*apply_contrast_change)(const uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize, + int w, int h, float *change, float *orig); +} TMidEqualizerContext; + +#define OFFSET(x) offsetof(TMidEqualizerContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +static const AVOption tmidequalizer_options[] = { + { "radius", "set radius", OFFSET(radius), AV_OPT_TYPE_INT, {.i64=5}, 1, 127, FLAGS }, + { "sigma", "set sigma", OFFSET(sigma), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, + { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(tmidequalizer); + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, + AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, + AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, + AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, + AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9, + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, + AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA444P12, + AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, + 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_GBRP16, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY16, + AV_PIX_FMT_NONE + }; + + return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); +} + +static void compute_contrast_function(const float *const histograms[256], + const float *const kernel, + int nb_frames, int radius, int hsize, + float *f, int idx) +{ + const float *const h1 = histograms[idx]; + int p2[256] = { 0 }; + + for (int p1 = 0; p1 < hsize; p1++) { + float weight = 1.f; + float sum = p1 * weight; + + for (int j = 0; j < radius; j++) { + const int nidx = ((idx - radius + j) % nb_frames); + const float *const h2 = histograms[nidx < 0 ? nidx + nb_frames: nidx]; + int k = j; + + for (; p2[k] < hsize && h2[p2[k]] < h1[p1]; p2[k]++); + if (p2[k] == hsize) + p2[k]--; + + weight += kernel[j]; + sum += kernel[j] * p2[k]; + } + + for (int j = radius + 1; j < nb_frames; j++) { + const int nidx = (idx - radius + j) % nb_frames; + const float *const h2 = histograms[nidx < 0 ? nidx + nb_frames: nidx]; + int k = j; + + for (; p2[k] < hsize && h2[p2[k]] < h1[p1]; p2[k]++); + if (p2[k] == hsize) + p2[k]--; + + weight += kernel[j - radius - 1]; + sum += kernel[j - radius - 1] * p2[k]; + } + + f[p1] = sum / weight; + } +} + +static void apply_contrast_change8(const uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize, + int w, int h, float *change, float *orig) +{ + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) + dst[x] = lrintf(change[src[x]]); + + dst += dst_linesize; + src += src_linesize; + } +} + +static void apply_contrast_change16(const uint8_t *ssrc, ptrdiff_t src_linesize, + uint8_t *ddst, ptrdiff_t dst_linesize, + int w, int h, float *change, float *orig) +{ + const uint16_t *src = (const uint16_t *)ssrc; + uint16_t *dst = (uint16_t *)ddst; + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) + dst[x] = lrintf(change[src[x]]); + + dst += dst_linesize / 2; + src += src_linesize / 2; + } +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + TMidEqualizerContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out; + int eof = 0; + + if (!in) { + int idx = s->f_frames < s->nb_frames ? s->radius : s->del_frame ? s->del_frame - 1 : s->nb_frames - 1; + + if (s->f_frames < s->nb_frames) { + s->l_frames = s->nb_frames - s->f_frames; + } else { + s->l_frames++; + } + in = av_frame_clone(s->frames[idx]); + if (!in) + return AVERROR(ENOMEM); + eof = 1; + } + + if (s->f_frames < s->nb_frames) { + s->frames[s->f_frames] = in; + + for (int p = 0; p < s->nb_planes; p++) { + s->compute_histogram(in->data[p], in->linesize[p], + s->plane_width[p], s->plane_height[p], + s->histogram[p][s->f_frames], + s->histogram_size); + } + + s->f_frames++; + + while (s->f_frames <= s->radius) { + s->frames[s->f_frames] = av_frame_clone(in); + if (!s->frames[s->f_frames]) + return AVERROR(ENOMEM); + for (int p = 0; p < s->nb_planes; p++) { + memcpy(s->histogram[p][s->f_frames], + s->histogram[p][s->f_frames - 1], + s->histogram_size * sizeof(float)); + } + s->f_frames++; + } + + if (!eof && s->f_frames < s->nb_frames) { + return 0; + } else { + while (s->f_frames < s->nb_frames) { + s->frames[s->f_frames] = av_frame_clone(in); + if (!s->frames[s->f_frames]) + return AVERROR(ENOMEM); + for (int p = 0; p < s->nb_planes; p++) { + memcpy(s->histogram[p][s->f_frames], + s->histogram[p][s->f_frames - 1], + s->histogram_size * sizeof(float)); + } + s->f_frames++; + } + } + s->cur_frame = s->radius; + s->del_frame = 0; + } else { + av_frame_free(&s->frames[s->del_frame]); + s->frames[s->del_frame] = in; + + for (int p = 0; p < s->nb_planes; p++) { + s->compute_histogram(in->data[p], in->linesize[p], + s->plane_width[p], s->plane_height[p], + s->histogram[p][s->del_frame], + s->histogram_size); + } + + s->del_frame++; + if (s->del_frame >= s->nb_frames) + s->del_frame = 0; + } + + if (ctx->is_disabled) { + const int idx = s->cur_frame; + + out = av_frame_clone(s->frames[idx]); + if (!out) + return AVERROR(ENOMEM); + } else { + const int idx = s->cur_frame; + + in = s->frames[idx]; + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) + return AVERROR(ENOMEM); + av_frame_copy_props(out, in); + + for (int p = 0; p < s->nb_planes; p++) { + if (!((1 << p) & s->planes)) { + av_image_copy_plane(out->data[p], out->linesize[p], in->data[p], in->linesize[p], + s->plane_width[p] * (1 + (s->depth > 8)), s->plane_height[p]); + continue; + } + + compute_contrast_function((const float *const *)s->histogram[p], s->kernel, + s->nb_frames, s->radius, s->histogram_size, s->change[p], idx); + + s->apply_contrast_change(in->data[p], in->linesize[p], + out->data[p], out->linesize[p], + s->plane_width[p], s->plane_height[p], + s->change[p], s->histogram[p][idx]); + } + } + + s->cur_frame++; + if (s->cur_frame >= s->nb_frames) + s->cur_frame = 0; + + return ff_filter_frame(outlink, out); +} + +static void compute_histogram8(const uint8_t *src, ptrdiff_t linesize, + int w, int h, float *histogram, size_t hsize) +{ + memset(histogram, 0, hsize * sizeof(*histogram)); + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) + histogram[src[x]] += 1; + src += linesize; + } + + for (int x = 0; x < hsize; x++) + histogram[x] /= hsize; + + for (int x = 1; x < hsize; x++) + histogram[x] += histogram[x-1]; +} + +static void compute_histogram16(const uint8_t *ssrc, ptrdiff_t linesize, + int w, int h, float *histogram, size_t hsize) +{ + const uint16_t *src = (const uint16_t *)ssrc; + + memset(histogram, 0, hsize * sizeof(*histogram)); + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) + histogram[src[x]] += 1; + src += linesize / 2; + } + + for (int x = 0; x < hsize; x++) + histogram[x] /= hsize; + + for (int x = 1; x < hsize; x++) + histogram[x] += histogram[x-1]; +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + TMidEqualizerContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + float sigma = s->radius * s->sigma; + int vsub, hsub; + + s->depth = desc->comp[0].depth; + s->nb_frames = s->radius * 2 + 1; + s->nb_planes = av_pix_fmt_count_planes(inlink->format); + + hsub = desc->log2_chroma_w; + vsub = desc->log2_chroma_h; + + s->plane_height[0] = s->plane_height[3] = inlink->h; + s->plane_width[0] = s->plane_width[3] = inlink->w; + s->plane_height[1] = s->plane_height[2] = AV_CEIL_RSHIFT(inlink->h, vsub); + s->plane_width[1] = s->plane_width[2] = AV_CEIL_RSHIFT(inlink->w, hsub); + + s->histogram_size = 1 << s->depth; + + for (int n = 0; n < s->radius; n++) + s->kernel[n] = expf(-0.5 * (n + 1) * (n + 1) / (sigma * sigma)); + + for (int p = 0; p < s->nb_planes; p++) { + for (int n = 0; n < s->nb_frames; n++) { + s->histogram[p][n] = av_calloc(s->histogram_size, sizeof(float)); + if (!s->histogram[p][n]) + return AVERROR(ENOMEM); + } + + s->change[p] = av_calloc(s->histogram_size, sizeof(float)); + if (!s->change[p]) + return AVERROR(ENOMEM); + } + + if (!s->frames) + s->frames = av_calloc(s->nb_frames, sizeof(*s->frames)); + if (!s->frames) + return AVERROR(ENOMEM); + + s->compute_histogram = s->depth <= 8 ? compute_histogram8 : compute_histogram16; + s->apply_contrast_change = s->depth <= 8 ? apply_contrast_change8 : apply_contrast_change16; + + return 0; +} + +static int request_frame(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + TMidEqualizerContext *s = ctx->priv; + int ret; + + ret = ff_request_frame(ctx->inputs[0]); + if (ret == AVERROR_EOF && s->l_frames < s->radius) { + ret = filter_frame(ctx->inputs[0], NULL); + } + + return ret; +} + +static void free_histograms(AVFilterContext *ctx, int x, int nb_frames) +{ + TMidEqualizerContext *s = ctx->priv; + + for (int n = 0; n < nb_frames; n++) + av_freep(&s->histogram[x][n]); + av_freep(&s->change[x]); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + TMidEqualizerContext *s = ctx->priv; + + free_histograms(ctx, 0, s->nb_frames); + free_histograms(ctx, 1, s->nb_frames); + free_histograms(ctx, 2, s->nb_frames); + free_histograms(ctx, 3, s->nb_frames); + + for (int i = 0; i < s->nb_frames && s->frames; i++) + av_frame_free(&s->frames[i]); + av_freep(&s->frames); +} + +static const AVFilterPad tmidequalizer_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_input, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad tmidequalizer_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .request_frame = request_frame, + }, + { NULL } +}; + +AVFilter ff_vf_tmidequalizer = { + .name = "tmidequalizer", + .description = NULL_IF_CONFIG_SMALL("Apply Temporal Midway Equalization."), + .priv_size = sizeof(TMidEqualizerContext), + .uninit = uninit, + .query_formats = query_formats, + .inputs = tmidequalizer_inputs, + .outputs = tmidequalizer_outputs, + .priv_class = &tmidequalizer_class, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, +}; diff --git a/libavfilter/vf_tonemap_opencl.c b/libavfilter/vf_tonemap_opencl.c index b88022872..2681ebd1b 100644 --- a/libavfilter/vf_tonemap_opencl.c +++ b/libavfilter/vf_tonemap_opencl.c @@ -71,12 +71,12 @@ typedef struct TonemapOpenCLContext { cl_mem util_mem; } TonemapOpenCLContext; -static const char *linearize_funcs[AVCOL_TRC_NB] = { +static const char *const linearize_funcs[AVCOL_TRC_NB] = { [AVCOL_TRC_SMPTE2084] = "eotf_st2084", [AVCOL_TRC_ARIB_STD_B67] = "inverse_oetf_hlg", }; -static const char *delinearize_funcs[AVCOL_TRC_NB] = { +static const char *const delinearize_funcs[AVCOL_TRC_NB] = { [AVCOL_TRC_BT709] = "inverse_eotf_bt1886", [AVCOL_TRC_BT2020_10] = "inverse_eotf_bt1886", }; @@ -91,7 +91,7 @@ static const struct WhitepointCoefficients whitepoint_table[AVCOL_PRI_NB] = { [AVCOL_PRI_BT2020] = { 0.3127, 0.3290 }, }; -static const char *tonemap_func[TONEMAP_MAX] = { +static const char *const tonemap_func[TONEMAP_MAX] = { [TONEMAP_NONE] = "direct", [TONEMAP_LINEAR] = "linear", [TONEMAP_GAMMA] = "gamma", diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index 7b430b650..198dbbaa5 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -57,81 +57,90 @@ typedef struct TheadData { int height; } ThreadData; -static int unsharp_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - ThreadData *td = arg; - UnsharpFilterParam *fp = td->fp; - uint32_t **sc = fp->sc; - uint32_t *sr = fp->sr; - const uint8_t *src2 = NULL; //silence a warning - const int amount = fp->amount; - const int steps_x = fp->steps_x; - const int steps_y = fp->steps_y; - const int scalebits = fp->scalebits; - const int32_t halfscale = fp->halfscale; - - uint8_t *dst = td->dst; - const uint8_t *src = td->src; - const int dst_stride = td->dst_stride; - const int src_stride = td->src_stride; - const int width = td->width; - const int height = td->height; - const int sc_offset = jobnr * 2 * steps_y; - const int sr_offset = jobnr * (MAX_MATRIX_SIZE - 1); - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; - - int32_t res; - int x, y, z; - uint32_t tmp1, tmp2; - - if (!amount) { - av_image_copy_plane(dst + slice_start * dst_stride, dst_stride, - src + slice_start * src_stride, src_stride, - width, slice_end - slice_start); - return 0; - } - - for (y = 0; y < 2 * steps_y; y++) - memset(sc[sc_offset + y], 0, sizeof(sc[y][0]) * (width + 2 * steps_x)); - - // if this is not the first tile, we start from (slice_start - steps_y), - // so we can get smooth result at slice boundary - if (slice_start > steps_y) { - src += (slice_start - steps_y) * src_stride; - dst += (slice_start - steps_y) * dst_stride; - } - - for (y = -steps_y + slice_start; y < steps_y + slice_end; y++) { - if (y < height) - src2 = src; - - memset(sr + sr_offset, 0, sizeof(sr[0]) * (2 * steps_x - 1)); - for (x = -steps_x; x < width + steps_x; x++) { - tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width-1] : src2[x]; - for (z = 0; z < steps_x * 2; z += 2) { - tmp2 = sr[sr_offset + z + 0] + tmp1; sr[sr_offset + z + 0] = tmp1; - tmp1 = sr[sr_offset + z + 1] + tmp2; sr[sr_offset + z + 1] = tmp2; - } - for (z = 0; z < steps_y * 2; z += 2) { - tmp2 = sc[sc_offset + z + 0][x + steps_x] + tmp1; sc[sc_offset + z + 0][x + steps_x] = tmp1; - tmp1 = sc[sc_offset + z + 1][x + steps_x] + tmp2; sc[sc_offset + z + 1][x + steps_x] = tmp2; - } - if (x >= steps_x && y >= (steps_y + slice_start)) { - const uint8_t *srx = src - steps_y * src_stride + x - steps_x; - uint8_t *dsx = dst - steps_y * dst_stride + x - steps_x; - - res = (int32_t)*srx + ((((int32_t) * srx - (int32_t)((tmp1 + halfscale) >> scalebits)) * amount) >> 16); - *dsx = av_clip_uint8(res); - } - } - if (y >= 0) { - dst += dst_stride; - src += src_stride; - } - } - return 0; +#define DEF_UNSHARP_SLICE_FUNC(name, nbits) \ +static int name##_##nbits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ +{ \ + ThreadData *td = arg; \ + UnsharpFilterParam *fp = td->fp; \ + UnsharpContext *s = ctx->priv; \ + uint32_t **sc = fp->sc; \ + uint32_t *sr = fp->sr; \ + const uint##nbits##_t *src2 = NULL; \ + const int amount = fp->amount; \ + const int steps_x = fp->steps_x; \ + const int steps_y = fp->steps_y; \ + const int scalebits = fp->scalebits; \ + const int32_t halfscale = fp->halfscale; \ + \ + uint##nbits##_t *dst = (uint##nbits##_t*)td->dst; \ + const uint##nbits##_t *src = (const uint##nbits##_t *)td->src; \ + int dst_stride = td->dst_stride; \ + int src_stride = td->src_stride; \ + const int width = td->width; \ + const int height = td->height; \ + const int sc_offset = jobnr * 2 * steps_y; \ + const int sr_offset = jobnr * (MAX_MATRIX_SIZE - 1); \ + const int slice_start = (height * jobnr) / nb_jobs; \ + const int slice_end = (height * (jobnr+1)) / nb_jobs; \ + \ + int32_t res; \ + int x, y, z; \ + uint32_t tmp1, tmp2; \ + \ + if (!amount) { \ + av_image_copy_plane(td->dst + slice_start * dst_stride, dst_stride, \ + td->src + slice_start * src_stride, src_stride, \ + width * s->bps, slice_end - slice_start); \ + return 0; \ + } \ + \ + for (y = 0; y < 2 * steps_y; y++) \ + memset(sc[sc_offset + y], 0, sizeof(sc[y][0]) * (width + 2 * steps_x)); \ + \ + dst_stride = dst_stride / s->bps; \ + src_stride = src_stride / s->bps; \ + /* if this is not the first tile, we start from (slice_start - steps_y) */ \ + /* so we can get smooth result at slice boundary */ \ + if (slice_start > steps_y) { \ + src += (slice_start - steps_y) * src_stride; \ + dst += (slice_start - steps_y) * dst_stride; \ + } \ + \ + for (y = -steps_y + slice_start; y < steps_y + slice_end; y++) { \ + if (y < height) \ + src2 = src; \ + \ + memset(sr + sr_offset, 0, sizeof(sr[0]) * (2 * steps_x - 1)); \ + for (x = -steps_x; x < width + steps_x; x++) { \ + tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width-1] : src2[x]; \ + for (z = 0; z < steps_x * 2; z += 2) { \ + tmp2 = sr[sr_offset + z + 0] + tmp1; sr[sr_offset + z + 0] = tmp1; \ + tmp1 = sr[sr_offset + z + 1] + tmp2; sr[sr_offset + z + 1] = tmp2; \ + } \ + for (z = 0; z < steps_y * 2; z += 2) { \ + tmp2 = sc[sc_offset + z + 0][x + steps_x] + tmp1; \ + sc[sc_offset + z + 0][x + steps_x] = tmp1; \ + tmp1 = sc[sc_offset + z + 1][x + steps_x] + tmp2; \ + sc[sc_offset + z + 1][x + steps_x] = tmp2; \ + } \ + if (x >= steps_x && y >= (steps_y + slice_start)) { \ + const uint##nbits##_t *srx = src - steps_y * src_stride + x - steps_x; \ + uint##nbits##_t *dsx = dst - steps_y * dst_stride + x - steps_x; \ + \ + res = (int32_t)*srx + ((((int32_t) * srx - \ + (int32_t)((tmp1 + halfscale) >> scalebits)) * amount) >> (8+nbits)); \ + *dsx = av_clip_uint##nbits(res); \ + } \ + } \ + if (y >= 0) { \ + dst += dst_stride; \ + src += src_stride; \ + } \ + } \ + return 0; \ } +DEF_UNSHARP_SLICE_FUNC(unsharp_slice, 16) +DEF_UNSHARP_SLICE_FUNC(unsharp_slice, 8) static int apply_unsharp_c(AVFilterContext *ctx, AVFrame *in, AVFrame *out) { @@ -155,7 +164,7 @@ static int apply_unsharp_c(AVFilterContext *ctx, AVFrame *in, AVFrame *out) td.height = plane_h[i]; td.dst_stride = out->linesize[i]; td.src_stride = in->linesize[i]; - ctx->internal->execute(ctx, unsharp_slice, &td, NULL, FFMIN(plane_h[i], s->nb_threads)); + ctx->internal->execute(ctx, s->unsharp_slice, &td, NULL, FFMIN(plane_h[i], s->nb_threads)); } return 0; } @@ -192,6 +201,10 @@ static int query_formats(AVFilterContext *ctx) static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_NONE }; @@ -238,6 +251,9 @@ static int config_input(AVFilterLink *inlink) s->hsub = desc->log2_chroma_w; s->vsub = desc->log2_chroma_h; + s->bitdepth = desc->comp[0].depth; + s->bps = s->bitdepth > 8 ? 2 : 1; + s->unsharp_slice = s->bitdepth > 8 ? unsharp_slice_16 : unsharp_slice_8; // ensure (height / nb_threads) > 4 * steps_y, // so that we don't have too much overlap between two threads diff --git a/libavfilter/vf_uspp.c b/libavfilter/vf_uspp.c index da4029f4b..ba07181e7 100644 --- a/libavfilter/vf_uspp.c +++ b/libavfilter/vf_uspp.c @@ -29,9 +29,11 @@ #include "libavutil/avassert.h" #include "libavutil/imgutils.h" +#include "libavutil/mem_internal.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "internal.h" +#include "qp_table.h" #include "avfilter.h" #define MAX_LEVEL 8 /* quality levels */ @@ -49,10 +51,11 @@ typedef struct USPPContext { int outbuf_size; uint8_t *outbuf; AVCodecContext *avctx_enc[BLOCK*BLOCK]; + AVPacket *pkt; AVFrame *frame; AVFrame *frame_dec; - uint8_t *non_b_qp_table; - int non_b_qp_alloc_size; + int8_t *non_b_qp_table; + int non_b_qp_stride; int use_bframe_qp; } USPPContext; @@ -238,23 +241,24 @@ static void filter(USPPContext *p, uint8_t *dst[3], uint8_t *src[3], const int y1c = y1 >> p->vsub; const int BLOCKc = BLOCK >> p->hsub; int offset; - AVPacket pkt = {0}; + AVPacket *pkt = p->pkt; int got_pkt_ptr; - av_init_packet(&pkt); - pkt.data = p->outbuf; - pkt.size = p->outbuf_size; + av_packet_unref(pkt); + pkt->data = p->outbuf; + pkt->size = p->outbuf_size; p->frame->data[0] = p->src[0] + x1 + y1 * p->frame->linesize[0]; p->frame->data[1] = p->src[1] + x1c + y1c * p->frame->linesize[1]; p->frame->data[2] = p->src[2] + x1c + y1c * p->frame->linesize[2]; p->frame->format = p->avctx_enc[i]->pix_fmt; - ret = avcodec_encode_video2(p->avctx_enc[i], &pkt, p->frame, &got_pkt_ptr); + ret = avcodec_encode_video2(p->avctx_enc[i], pkt, p->frame, &got_pkt_ptr); if (ret < 0) { av_log(p->avctx_enc[i], AV_LOG_ERROR, "Encoding failed\n"); continue; } + av_packet_unref(pkt); p->frame_dec = p->avctx_enc[i]->coded_frame; @@ -316,7 +320,7 @@ static int config_input(AVFilterLink *inlink) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); int i; - AVCodec *enc = avcodec_find_encoder(AV_CODEC_ID_SNOW); + const AVCodec *enc = avcodec_find_encoder(AV_CODEC_ID_SNOW); if (!enc) { av_log(ctx, AV_LOG_ERROR, "SNOW encoder not found.\n"); return AVERROR(EINVAL); @@ -362,15 +366,17 @@ static int config_input(AVFilterLink *inlink) avctx_enc->global_quality = 123; av_dict_set(&opts, "no_bitstream", "1", 0); ret = avcodec_open2(avctx_enc, enc, &opts); + av_dict_free(&opts); if (ret < 0) return ret; - av_dict_free(&opts); av_assert0(avctx_enc->codec); } uspp->outbuf_size = (width + BLOCK) * (height + BLOCK) * 10; if (!(uspp->frame = av_frame_alloc())) return AVERROR(ENOMEM); + if (!(uspp->pkt = av_packet_alloc())) + return AVERROR(ENOMEM); if (!(uspp->outbuf = av_malloc(uspp->outbuf_size))) return AVERROR(ENOMEM); @@ -385,45 +391,32 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFrame *out = in; int qp_stride = 0; - uint8_t *qp_table = NULL; + int8_t *qp_table = NULL; + int ret = 0; /* if we are not in a constant user quantizer mode and we don't want to use * the quantizers from the B-frames (B-frames often have a higher QP), we * need to save the qp table from the last non B-frame; this is what the * following code block does */ - if (!uspp->qp) { - qp_table = av_frame_get_qp_table(in, &qp_stride, &uspp->qscale_type); + if (!uspp->qp && (uspp->use_bframe_qp || in->pict_type != AV_PICTURE_TYPE_B)) { + ret = ff_qp_table_extract(in, &qp_table, &qp_stride, NULL, &uspp->qscale_type); + if (ret < 0) { + av_frame_free(&in); + return ret; + } - if (qp_table && !uspp->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) { - int w, h; - - /* if the qp stride is not set, it means the QP are only defined on - * a line basis */ - if (!qp_stride) { - w = AV_CEIL_RSHIFT(inlink->w, 4); - h = 1; - } else { - w = qp_stride; - h = AV_CEIL_RSHIFT(inlink->h, 4); - } - - if (w * h > uspp->non_b_qp_alloc_size) { - int ret = av_reallocp_array(&uspp->non_b_qp_table, w, h); - if (ret < 0) { - uspp->non_b_qp_alloc_size = 0; - return ret; - } - uspp->non_b_qp_alloc_size = w * h; - } - - av_assert0(w * h <= uspp->non_b_qp_alloc_size); - memcpy(uspp->non_b_qp_table, qp_table, w * h); + if (!uspp->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) { + av_freep(&uspp->non_b_qp_table); + uspp->non_b_qp_table = qp_table; + uspp->non_b_qp_stride = qp_stride; } } if (uspp->log2_count && !ctx->is_disabled) { - if (!uspp->use_bframe_qp && uspp->non_b_qp_table) + if (!uspp->use_bframe_qp && uspp->non_b_qp_table) { qp_table = uspp->non_b_qp_table; + qp_stride = uspp->non_b_qp_stride; + } if (qp_table || uspp->qp) { @@ -436,6 +429,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) out = ff_get_video_buffer(outlink, aligned_w, aligned_h); if (!out) { av_frame_free(&in); + if (qp_table != uspp->non_b_qp_table) + av_free(qp_table); return AVERROR(ENOMEM); } av_frame_copy_props(out, in); @@ -455,7 +450,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) inlink->w, inlink->h); av_frame_free(&in); } - return ff_filter_frame(outlink, out); + ret = ff_filter_frame(outlink, out); + if (qp_table != uspp->non_b_qp_table) + av_freep(&qp_table); + return ret; } static av_cold void uninit(AVFilterContext *ctx) @@ -468,13 +466,12 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&uspp->src[i]); } - for (i = 0; i < (1 << uspp->log2_count); i++) { - avcodec_close(uspp->avctx_enc[i]); - av_freep(&uspp->avctx_enc[i]); - } + for (i = 0; i < (1 << uspp->log2_count); i++) + avcodec_free_context(&uspp->avctx_enc[i]); av_freep(&uspp->non_b_qp_table); av_freep(&uspp->outbuf); + av_packet_free(&uspp->pkt); av_frame_free(&uspp->frame); } diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c index e9457d940..94473cd5b 100644 --- a/libavfilter/vf_v360.c +++ b/libavfilter/vf_v360.c @@ -81,6 +81,9 @@ static const AVOption v360_options[] = { { "tsp", "truncated square pyramid", 0, AV_OPT_TYPE_CONST, {.i64=TSPYRAMID}, 0, 0, FLAGS, "in" }, { "hequirect", "half equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=HEQUIRECTANGULAR},0, 0, FLAGS, "in" }, { "he", "half equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=HEQUIRECTANGULAR},0, 0, FLAGS, "in" }, + { "equisolid", "equisolid", 0, AV_OPT_TYPE_CONST, {.i64=EQUISOLID}, 0, 0, FLAGS, "in" }, + { "og", "orthographic", 0, AV_OPT_TYPE_CONST, {.i64=ORTHOGRAPHIC}, 0, 0, FLAGS, "in" }, + {"octahedron", "octahedron", 0, AV_OPT_TYPE_CONST, {.i64=OCTAHEDRON}, 0, 0, FLAGS, "in" }, { "output", "set output projection", OFFSET(out), AV_OPT_TYPE_INT, {.i64=CUBEMAP_3_2}, 0, NB_PROJECTIONS-1, FLAGS, "out" }, { "e", "equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=EQUIRECTANGULAR}, 0, 0, FLAGS, "out" }, { "equirect", "equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=EQUIRECTANGULAR}, 0, 0, FLAGS, "out" }, @@ -108,6 +111,9 @@ static const AVOption v360_options[] = { { "tsp", "truncated square pyramid", 0, AV_OPT_TYPE_CONST, {.i64=TSPYRAMID}, 0, 0, FLAGS, "out" }, { "hequirect", "half equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=HEQUIRECTANGULAR},0, 0, FLAGS, "out" }, { "he", "half equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=HEQUIRECTANGULAR},0, 0, FLAGS, "out" }, + { "equisolid", "equisolid", 0, AV_OPT_TYPE_CONST, {.i64=EQUISOLID}, 0, 0, FLAGS, "out" }, + { "og", "orthographic", 0, AV_OPT_TYPE_CONST, {.i64=ORTHOGRAPHIC}, 0, 0, FLAGS, "out" }, + {"octahedron", "octahedron", 0, AV_OPT_TYPE_CONST, {.i64=OCTAHEDRON}, 0, 0, FLAGS, "out" }, { "interp", "set interpolation method", OFFSET(interp), AV_OPT_TYPE_INT, {.i64=BILINEAR}, 0, NB_INTERP_METHODS-1, FLAGS, "interp" }, { "near", "nearest neighbour", 0, AV_OPT_TYPE_CONST, {.i64=NEAREST}, 0, 0, FLAGS, "interp" }, { "nearest", "nearest neighbour", 0, AV_OPT_TYPE_CONST, {.i64=NEAREST}, 0, 0, FLAGS, "interp" }, @@ -122,6 +128,7 @@ static const AVOption v360_options[] = { { "spline16", "spline16 interpolation", 0, AV_OPT_TYPE_CONST, {.i64=SPLINE16}, 0, 0, FLAGS, "interp" }, { "gauss", "gaussian interpolation", 0, AV_OPT_TYPE_CONST, {.i64=GAUSSIAN}, 0, 0, FLAGS, "interp" }, { "gaussian", "gaussian interpolation", 0, AV_OPT_TYPE_CONST, {.i64=GAUSSIAN}, 0, 0, FLAGS, "interp" }, + { "mitchell", "mitchell interpolation", 0, AV_OPT_TYPE_CONST, {.i64=MITCHELL}, 0, 0, FLAGS, "interp" }, { "w", "output width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, INT16_MAX, FLAGS, "w"}, { "h", "output height", OFFSET(height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT16_MAX, FLAGS, "h"}, { "in_stereo", "input stereo format", OFFSET(in_stereo), AV_OPT_TYPE_INT, {.i64=STEREO_2D}, 0, NB_STEREO_FMTS-1, FLAGS, "stereo" }, @@ -273,6 +280,7 @@ static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jo { \ ThreadData *td = arg; \ const V360Context *s = ctx->priv; \ + const SliceXYRemap *r = &s->slice_remap[jobnr]; \ const AVFrame *in = td->in; \ AVFrame *out = td->out; \ \ @@ -289,7 +297,7 @@ static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jo const uint8_t *const src = in->data[plane] + \ in_offset_h * in_linesize + in_offset_w * (bits >> 3); \ uint8_t *dst = out->data[plane] + out_offset_h * out_linesize + out_offset_w * (bits >> 3); \ - const uint8_t *mask = plane == 3 ? s->mask : NULL; \ + const uint8_t *mask = plane == 3 ? r->mask : NULL; \ const int width = s->pr_width[plane]; \ const int height = s->pr_height[plane]; \ \ @@ -297,15 +305,16 @@ static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jo const int slice_end = (height * (jobnr + 1)) / nb_jobs; \ \ for (int y = slice_start; y < slice_end && !mask; y++) { \ - const int16_t *const u = s->u[map] + y * uv_linesize * ws * ws; \ - const int16_t *const v = s->v[map] + y * uv_linesize * ws * ws; \ - const int16_t *const ker = s->ker[map] + y * uv_linesize * ws * ws; \ + const int16_t *const u = r->u[map] + (y - slice_start) * uv_linesize * ws * ws; \ + const int16_t *const v = r->v[map] + (y - slice_start) * uv_linesize * ws * ws; \ + const int16_t *const ker = r->ker[map] + (y - slice_start) * uv_linesize * ws * ws; \ \ s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \ } \ \ for (int y = slice_start; y < slice_end && mask; y++) { \ - memcpy(dst + y * out_linesize, mask + y * width * (bits >> 3), width * (bits >> 3)); \ + memcpy(dst + y * out_linesize, mask + \ + (y - slice_start) * width * (bits >> 3), width * (bits >> 3)); \ } \ } \ } \ @@ -340,8 +349,9 @@ static void remap##ws##_##bits##bit_line_c(uint8_t *dst, int width, const uint8_ int tmp = 0; \ \ for (int i = 0; i < ws; i++) { \ + const int iws = i * ws; \ for (int j = 0; j < ws; j++) { \ - tmp += kker[i * ws + j] * s[vv[i * ws + j] * in_linesize + uu[i * ws + j]]; \ + tmp += kker[iws + j] * s[vv[iws + j] * in_linesize + uu[iws + j]]; \ } \ } \ \ @@ -372,6 +382,7 @@ void ff_v360_init(V360Context *s, int depth) case LANCZOS: case SPLINE16: case GAUSSIAN: + case MITCHELL: s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c; break; } @@ -660,6 +671,71 @@ static void gaussian_kernel(float du, float dv, const XYRemap *rmap, } } +/** + * Calculate 1-dimensional cubic_bc_spline coefficients. + * + * @param t relative coordinate + * @param coeffs coefficients + */ +static void calculate_cubic_bc_coeffs(float t, float *coeffs, + float b, float c) +{ + float sum = 0.f; + float p0 = (6.f - 2.f * b) / 6.f, + p2 = (-18.f + 12.f * b + 6.f * c) / 6.f, + p3 = (12.f - 9.f * b - 6.f * c) / 6.f, + q0 = (8.f * b + 24.f * c) / 6.f, + q1 = (-12.f * b - 48.f * c) / 6.f, + q2 = (6.f * b + 30.f * c) / 6.f, + q3 = (-b - 6.f * c) / 6.f; + + for (int i = 0; i < 4; i++) { + const float x = fabsf(t - i + 1.f); + if (x < 1.f) { + coeffs[i] = (p0 + x * x * (p2 + x * p3)) * + (p0 + x * x * (p2 + x * p3 / 2.f) / 4.f); + } else if (x < 2.f) { + coeffs[i] = (q0 + x * (q1 + x * (q2 + x * q3))) * + (q0 + x * (q1 + x * (q2 + x / 2.f * q3) / 2.f) / 2.f); + } else { + coeffs[i] = 0.f; + } + sum += coeffs[i]; + } + + for (int i = 0; i < 4; i++) { + coeffs[i] /= sum; + } +} + +/** + * Calculate kernel for mitchell interpolation. + * + * @param du horizontal relative coordinate + * @param dv vertical relative coordinate + * @param rmap calculated 4x4 window + * @param u u remap data + * @param v v remap data + * @param ker ker remap data + */ +static void mitchell_kernel(float du, float dv, const XYRemap *rmap, + int16_t *u, int16_t *v, int16_t *ker) +{ + float du_coeffs[4]; + float dv_coeffs[4]; + + calculate_cubic_bc_coeffs(du, du_coeffs, 1.f / 3.f, 1.f / 3.f); + calculate_cubic_bc_coeffs(dv, dv_coeffs, 1.f / 3.f, 1.f / 3.f); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + u[i * 4 + j] = rmap->u[i][j]; + v[i * 4 + j] = rmap->v[i][j]; + ker[i * 4 + j] = lrintf(du_coeffs[j] * dv_coeffs[i] * 16385.f); + } + } +} + /** * Modulo operation with only positive remainders. * @@ -687,12 +763,12 @@ static inline int mod(int a, int b) static inline int reflecty(int y, int h) { if (y < 0) { - return -y; + y = -y; } else if (y >= h) { - return 2 * h - 1 - y; + y = 2 * h - 1 - y; } - return y; + return av_clip(y, 0, h - 1); } /** @@ -1102,9 +1178,6 @@ static void xyz_to_cube(const V360Context *s, face = s->in_cubemap_face_order[*direction]; rotate_cube_face(uf, vf, s->in_cubemap_face_rotation[face]); - - (*uf) *= s->input_mirror_modifier[0]; - (*vf) *= s->input_mirror_modifier[1]; } /** @@ -1795,8 +1868,8 @@ static int xyz_to_stereographic(const V360Context *s, const float theta = acosf(vec[2]); const float r = tanf(theta * 0.5f); const float c = r / hypotf(vec[0], vec[1]); - const float x = vec[0] * c / s->iflat_range[0] * s->input_mirror_modifier[0]; - const float y = vec[1] * c / s->iflat_range[1] * s->input_mirror_modifier[1]; + const float x = vec[0] * c / s->iflat_range[0]; + const float y = vec[1] * c / s->iflat_range[1]; const float uf = (x + 1.f) * width / 2.f; const float vf = (y + 1.f) * height / 2.f; @@ -1819,6 +1892,217 @@ static int xyz_to_stereographic(const V360Context *s, return visible; } +/** + * Prepare data for processing equisolid output format. + * + * @param ctx filter context + * + * @return error code + */ +static int prepare_equisolid_out(AVFilterContext *ctx) +{ + V360Context *s = ctx->priv; + + s->flat_range[0] = sinf(s->h_fov * M_PI / 720.f); + s->flat_range[1] = sinf(s->v_fov * M_PI / 720.f); + + return 0; +} + +/** + * Calculate 3D coordinates on sphere for corresponding frame position in equisolid format. + * + * @param s filter private context + * @param i horizontal position on frame [0, width) + * @param j vertical position on frame [0, height) + * @param width frame width + * @param height frame height + * @param vec coordinates on sphere + */ +static int equisolid_to_xyz(const V360Context *s, + int i, int j, int width, int height, + float *vec) +{ + const float x = ((2.f * i + 1.f) / width - 1.f) * s->flat_range[0]; + const float y = ((2.f * j + 1.f) / height - 1.f) * s->flat_range[1]; + const float r = hypotf(x, y); + const float theta = asinf(r) * 2.f; + const float sin_theta = sinf(theta); + + vec[0] = x / r * sin_theta; + vec[1] = y / r * sin_theta; + vec[2] = cosf(theta); + + normalize_vector(vec); + + return 1; +} + +/** + * Prepare data for processing equisolid input format. + * + * @param ctx filter context + * + * @return error code + */ +static int prepare_equisolid_in(AVFilterContext *ctx) +{ + V360Context *s = ctx->priv; + + s->iflat_range[0] = sinf(FFMIN(s->ih_fov, 359.f) * M_PI / 720.f); + s->iflat_range[1] = sinf(FFMIN(s->iv_fov, 359.f) * M_PI / 720.f); + + return 0; +} + +/** + * Calculate frame position in equisolid format for corresponding 3D coordinates on sphere. + * + * @param s filter private context + * @param vec coordinates on sphere + * @param width frame width + * @param height frame height + * @param us horizontal coordinates for interpolation window + * @param vs vertical coordinates for interpolation window + * @param du horizontal relative coordinate + * @param dv vertical relative coordinate + */ +static int xyz_to_equisolid(const V360Context *s, + const float *vec, int width, int height, + int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) +{ + const float theta = acosf(vec[2]); + const float r = sinf(theta * 0.5f); + const float c = r / hypotf(vec[0], vec[1]); + const float x = vec[0] * c / s->iflat_range[0]; + const float y = vec[1] * c / s->iflat_range[1]; + + const float uf = (x + 1.f) * width / 2.f; + const float vf = (y + 1.f) * height / 2.f; + + const int ui = floorf(uf); + const int vi = floorf(vf); + + const int visible = isfinite(x) && isfinite(y) && vi >= 0 && vi < height && ui >= 0 && ui < width; + + *du = visible ? uf - ui : 0.f; + *dv = visible ? vf - vi : 0.f; + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + us[i][j] = visible ? av_clip(ui + j - 1, 0, width - 1) : 0; + vs[i][j] = visible ? av_clip(vi + i - 1, 0, height - 1) : 0; + } + } + + return visible; +} + +/** + * Prepare data for processing orthographic output format. + * + * @param ctx filter context + * + * @return error code + */ +static int prepare_orthographic_out(AVFilterContext *ctx) +{ + V360Context *s = ctx->priv; + + s->flat_range[0] = sinf(FFMIN(s->h_fov, 180.f) * M_PI / 360.f); + s->flat_range[1] = sinf(FFMIN(s->v_fov, 180.f) * M_PI / 360.f); + + return 0; +} + +/** + * Calculate 3D coordinates on sphere for corresponding frame position in orthographic format. + * + * @param s filter private context + * @param i horizontal position on frame [0, width) + * @param j vertical position on frame [0, height) + * @param width frame width + * @param height frame height + * @param vec coordinates on sphere + */ +static int orthographic_to_xyz(const V360Context *s, + int i, int j, int width, int height, + float *vec) +{ + const float x = ((2.f * i + 1.f) / width - 1.f) * s->flat_range[0]; + const float y = ((2.f * j + 1.f) / height - 1.f) * s->flat_range[1]; + const float r = hypotf(x, y); + const float theta = asinf(r); + + vec[0] = x; + vec[1] = y; + vec[2] = cosf(theta); + + normalize_vector(vec); + + return 1; +} + +/** + * Prepare data for processing orthographic input format. + * + * @param ctx filter context + * + * @return error code + */ +static int prepare_orthographic_in(AVFilterContext *ctx) +{ + V360Context *s = ctx->priv; + + s->iflat_range[0] = sinf(FFMIN(s->ih_fov, 180.f) * M_PI / 360.f); + s->iflat_range[1] = sinf(FFMIN(s->iv_fov, 180.f) * M_PI / 360.f); + + return 0; +} + +/** + * Calculate frame position in orthographic format for corresponding 3D coordinates on sphere. + * + * @param s filter private context + * @param vec coordinates on sphere + * @param width frame width + * @param height frame height + * @param us horizontal coordinates for interpolation window + * @param vs vertical coordinates for interpolation window + * @param du horizontal relative coordinate + * @param dv vertical relative coordinate + */ +static int xyz_to_orthographic(const V360Context *s, + const float *vec, int width, int height, + int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) +{ + const float theta = acosf(vec[2]); + const float r = sinf(theta); + const float c = r / hypotf(vec[0], vec[1]); + const float x = vec[0] * c / s->iflat_range[0]; + const float y = vec[1] * c / s->iflat_range[1]; + + const float uf = (x + 1.f) * width / 2.f; + const float vf = (y + 1.f) * height / 2.f; + + const int ui = floorf(uf); + const int vi = floorf(vf); + + const int visible = vec[2] >= 0.f && isfinite(x) && isfinite(y) && vi >= 0 && vi < height && ui >= 0 && ui < width; + + *du = visible ? uf - ui : 0.f; + *dv = visible ? vf - vi : 0.f; + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + us[i][j] = visible ? av_clip(ui + j - 1, 0, width - 1) : 0; + vs[i][j] = visible ? av_clip(vi + i - 1, 0, height - 1) : 0; + } + } + + return visible; +} + /** * Calculate frame position in equirectangular format for corresponding 3D coordinates on sphere. * @@ -1835,8 +2119,8 @@ static int xyz_to_equirect(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) { - const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0]; - const float theta = asinf(vec[1]) * s->input_mirror_modifier[1]; + const float phi = atan2f(vec[0], vec[2]); + const float theta = asinf(vec[1]); const float uf = (phi / M_PI + 1.f) * width / 2.f; const float vf = (theta / M_PI_2 + 1.f) * height / 2.f; @@ -1873,8 +2157,8 @@ static int xyz_to_hequirect(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) { - const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0]; - const float theta = asinf(vec[1]) * s->input_mirror_modifier[1]; + const float phi = atan2f(vec[0], vec[2]); + const float theta = asinf(vec[1]); const float uf = (phi / M_PI_2 + 1.f) * width / 2.f; const float vf = (theta / M_PI_2 + 1.f) * height / 2.f; @@ -1936,8 +2220,8 @@ static int xyz_to_flat(const V360Context *s, const float zf = vec[2]; const float h = hypotf(vec[0], vec[1]); const float c = h <= 1e-6f ? 1.f : rr / h; - float uf = vec[0] * c / s->iflat_range[0] * s->input_mirror_modifier[0]; - float vf = vec[1] * c / s->iflat_range[1] * s->input_mirror_modifier[1]; + float uf = vec[0] * c / s->iflat_range[0]; + float vf = vec[1] * c / s->iflat_range[1]; int visible, ui, vi; uf = zf >= 0.f ? (uf + 1.f) * width / 2.f : 0.f; @@ -1977,8 +2261,8 @@ static int xyz_to_mercator(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) { - const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0]; - const float theta = vec[1] * s->input_mirror_modifier[1]; + const float phi = atan2f(vec[0], vec[2]); + const float theta = vec[1]; const float uf = (phi / M_PI + 1.f) * width / 2.f; const float vf = (av_clipf(logf((1.f + theta) / (1.f - theta)) / (2.f * M_PI), -1.f, 1.f) + 1.f) * height / 2.f; @@ -2048,8 +2332,8 @@ static int xyz_to_ball(const V360Context *s, const float l = hypotf(vec[0], vec[1]); const float r = sqrtf(1.f - vec[2]) / M_SQRT2; - const float uf = (1.f + r * vec[0] * s->input_mirror_modifier[0] / (l > 0.f ? l : 1.f)) * width * 0.5f; - const float vf = (1.f + r * vec[1] * s->input_mirror_modifier[1] / (l > 0.f ? l : 1.f)) * height * 0.5f; + const float uf = (1.f + r * vec[0] / (l > 0.f ? l : 1.f)) * width * 0.5f; + const float vf = (1.f + r * vec[1] / (l > 0.f ? l : 1.f)) * height * 0.5f; const int ui = floorf(uf); const int vi = floorf(vf); @@ -2156,11 +2440,11 @@ static int xyz_to_hammer(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) { - const float theta = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0]; + const float theta = atan2f(vec[0], vec[2]); const float z = sqrtf(1.f + sqrtf(1.f - vec[1] * vec[1]) * cosf(theta * 0.5f)); const float x = sqrtf(1.f - vec[1] * vec[1]) * sinf(theta * 0.5f) / z; - const float y = vec[1] / z * s->input_mirror_modifier[1]; + const float y = vec[1] / z; const float uf = (x + 1.f) * width / 2.f; const float vf = (y + 1.f) * height / 2.f; @@ -2228,8 +2512,8 @@ static int xyz_to_sinusoidal(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) { - const float theta = asinf(vec[1]) * s->input_mirror_modifier[1]; - const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0] * cosf(theta); + const float theta = asinf(vec[1]); + const float phi = atan2f(vec[0], vec[2]) * cosf(theta); const float uf = (phi / M_PI + 1.f) * width / 2.f; const float vf = (theta / M_PI_2 + 1.f) * height / 2.f; @@ -2261,51 +2545,19 @@ static int prepare_eac_in(AVFilterContext *ctx) { V360Context *s = ctx->priv; - if (s->ih_flip && s->iv_flip) { - s->in_cubemap_face_order[RIGHT] = BOTTOM_LEFT; - s->in_cubemap_face_order[LEFT] = BOTTOM_RIGHT; - s->in_cubemap_face_order[UP] = TOP_LEFT; - s->in_cubemap_face_order[DOWN] = TOP_RIGHT; - s->in_cubemap_face_order[FRONT] = BOTTOM_MIDDLE; - s->in_cubemap_face_order[BACK] = TOP_MIDDLE; - } else if (s->ih_flip) { - s->in_cubemap_face_order[RIGHT] = TOP_LEFT; - s->in_cubemap_face_order[LEFT] = TOP_RIGHT; - s->in_cubemap_face_order[UP] = BOTTOM_LEFT; - s->in_cubemap_face_order[DOWN] = BOTTOM_RIGHT; - s->in_cubemap_face_order[FRONT] = TOP_MIDDLE; - s->in_cubemap_face_order[BACK] = BOTTOM_MIDDLE; - } else if (s->iv_flip) { - s->in_cubemap_face_order[RIGHT] = BOTTOM_RIGHT; - s->in_cubemap_face_order[LEFT] = BOTTOM_LEFT; - s->in_cubemap_face_order[UP] = TOP_RIGHT; - s->in_cubemap_face_order[DOWN] = TOP_LEFT; - s->in_cubemap_face_order[FRONT] = BOTTOM_MIDDLE; - s->in_cubemap_face_order[BACK] = TOP_MIDDLE; - } else { - s->in_cubemap_face_order[RIGHT] = TOP_RIGHT; - s->in_cubemap_face_order[LEFT] = TOP_LEFT; - s->in_cubemap_face_order[UP] = BOTTOM_RIGHT; - s->in_cubemap_face_order[DOWN] = BOTTOM_LEFT; - s->in_cubemap_face_order[FRONT] = TOP_MIDDLE; - s->in_cubemap_face_order[BACK] = BOTTOM_MIDDLE; - } + s->in_cubemap_face_order[RIGHT] = TOP_RIGHT; + s->in_cubemap_face_order[LEFT] = TOP_LEFT; + s->in_cubemap_face_order[UP] = BOTTOM_RIGHT; + s->in_cubemap_face_order[DOWN] = BOTTOM_LEFT; + s->in_cubemap_face_order[FRONT] = TOP_MIDDLE; + s->in_cubemap_face_order[BACK] = BOTTOM_MIDDLE; - if (s->iv_flip) { - s->in_cubemap_face_rotation[TOP_LEFT] = ROT_270; - s->in_cubemap_face_rotation[TOP_MIDDLE] = ROT_90; - s->in_cubemap_face_rotation[TOP_RIGHT] = ROT_270; - s->in_cubemap_face_rotation[BOTTOM_LEFT] = ROT_0; - s->in_cubemap_face_rotation[BOTTOM_MIDDLE] = ROT_0; - s->in_cubemap_face_rotation[BOTTOM_RIGHT] = ROT_0; - } else { - s->in_cubemap_face_rotation[TOP_LEFT] = ROT_0; - s->in_cubemap_face_rotation[TOP_MIDDLE] = ROT_0; - s->in_cubemap_face_rotation[TOP_RIGHT] = ROT_0; - s->in_cubemap_face_rotation[BOTTOM_LEFT] = ROT_270; - s->in_cubemap_face_rotation[BOTTOM_MIDDLE] = ROT_90; - s->in_cubemap_face_rotation[BOTTOM_RIGHT] = ROT_270; - } + s->in_cubemap_face_rotation[TOP_LEFT] = ROT_0; + s->in_cubemap_face_rotation[TOP_MIDDLE] = ROT_0; + s->in_cubemap_face_rotation[TOP_RIGHT] = ROT_0; + s->in_cubemap_face_rotation[BOTTOM_LEFT] = ROT_270; + s->in_cubemap_face_rotation[BOTTOM_MIDDLE] = ROT_90; + s->in_cubemap_face_rotation[BOTTOM_RIGHT] = ROT_270; return 0; } @@ -2632,8 +2884,8 @@ static int xyz_to_fisheye(const V360Context *s, const float lh = h > 0.f ? h : 1.f; const float phi = atan2f(h, vec[2]) / M_PI; - float uf = vec[0] / lh * phi * s->input_mirror_modifier[0] / s->iflat_range[0]; - float vf = vec[1] / lh * phi * s->input_mirror_modifier[1] / s->iflat_range[1]; + float uf = vec[0] / lh * phi / s->iflat_range[0]; + float vf = vec[1] / lh * phi / s->iflat_range[1]; const int visible = hypotf(uf, vf) <= 0.5f; int ui, vi; @@ -2707,8 +2959,8 @@ static int xyz_to_pannini(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) { - const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0]; - const float theta = asinf(vec[1]) * s->input_mirror_modifier[1]; + const float phi = atan2f(vec[0], vec[2]); + const float theta = asinf(vec[1]); const float d = s->ih_fov; const float S = (d + 1.f) / (d + cosf(phi)); @@ -2821,8 +3073,8 @@ static int xyz_to_cylindrical(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) { - const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0] / s->iflat_range[0]; - const float theta = asinf(vec[1]) * s->input_mirror_modifier[1]; + const float phi = atan2f(vec[0], vec[2]) / s->iflat_range[0]; + const float theta = asinf(vec[1]); const float uf = (phi + 1.f) * (width - 1) / 2.f; const float vf = (tanf(theta) / s->iflat_range[1] + 1.f) * height / 2.f; @@ -2881,8 +3133,8 @@ static int perspective_to_xyz(const V360Context *s, const float cos_theta = cosf(theta); vec[0] = cos_theta * sin_phi; - vec[1] = sin_theta; - vec[2] = cos_theta * cos_phi; + vec[1] = cos_theta * cos_phi; + vec[2] = sin_theta; } else { vec[0] = 0.f; vec[1] = 1.f; @@ -2890,7 +3142,6 @@ static int perspective_to_xyz(const V360Context *s, return 0; } - normalize_vector(vec); return 1; } @@ -2949,13 +3200,13 @@ static int xyz_to_tetrahedron(const V360Context *s, y = vec[1] / d; z = -vec[2] / d; - vf = 0.5f - y * 0.5f * s->input_mirror_modifier[1]; + vf = 0.5f - y * 0.5f; if ((x + y >= 0.f && y + z >= 0.f && -z - x <= 0.f) || (x + y <= 0.f && -y + z >= 0.f && z - x >= 0.f)) { - uf = 0.25f * x * s->input_mirror_modifier[0] + 0.25f; + uf = 0.25f * x + 0.25f; } else { - uf = 0.75f - 0.25f * x * s->input_mirror_modifier[0]; + uf = 0.75f - 0.25f * x; } uf *= width; @@ -3039,8 +3290,8 @@ static int xyz_to_dfisheye(const V360Context *s, const float lh = h > 0.f ? h : 1.f; const float theta = acosf(fabsf(vec[2])) / M_PI; - float uf = (theta * (vec[0] / lh) * s->input_mirror_modifier[0] / s->iflat_range[0] + 0.5f) * ew; - float vf = (theta * (vec[1] / lh) * s->input_mirror_modifier[1] / s->iflat_range[1] + 0.5f) * eh; + float uf = (theta * (vec[0] / lh) / s->iflat_range[0] + 0.5f) * ew; + float vf = (theta * (vec[1] / lh) / s->iflat_range[1] + 0.5f) * eh; int ui, vi; int u_shift; @@ -3158,8 +3409,8 @@ static int xyz_to_barrel(const V360Context *s, { const float scale = 0.99f; - const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0]; - const float theta = asinf(vec[1]) * s->input_mirror_modifier[1]; + const float phi = atan2f(vec[0], vec[2]); + const float theta = asinf(vec[1]); const float theta_range = M_PI_4; int ew, eh; @@ -3171,7 +3422,7 @@ static int xyz_to_barrel(const V360Context *s, ew = 4 * width / 5; eh = height; - u_shift = s->ih_flip ? width / 5 : 0; + u_shift = 0; v_shift = 0; uf = (phi / M_PI * scale + 1.f) * ew / 2.f; @@ -3180,7 +3431,7 @@ static int xyz_to_barrel(const V360Context *s, ew = width / 5; eh = height / 2; - u_shift = s->ih_flip ? 0 : 4 * ew; + u_shift = 4 * ew; if (theta < 0.f) { // UP uf = -vec[0] / vec[1]; @@ -3192,9 +3443,6 @@ static int xyz_to_barrel(const V360Context *s, v_shift = eh; } - uf *= s->input_mirror_modifier[0] * s->input_mirror_modifier[1]; - vf *= s->input_mirror_modifier[1]; - uf = 0.5f * ew * (uf * scale + 1.f); vf = 0.5f * eh * (vf * scale + 1.f); } @@ -3231,8 +3479,8 @@ static int xyz_to_barrelsplit(const V360Context *s, const float *vec, int width, int height, int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) { - const float phi = atan2f(vec[0], vec[2]) * s->input_mirror_modifier[0]; - const float theta = asinf(vec[1]) * s->input_mirror_modifier[1]; + const float phi = atan2f(vec[0], vec[2]); + const float theta = asinf(vec[1]); const float theta_range = M_PI_4; @@ -3248,7 +3496,7 @@ static int xyz_to_barrelsplit(const V360Context *s, ew = width / 3 * 2; eh = height / 2; - u_shift = s->ih_flip ? width / 3 : 0; + u_shift = 0; v_shift = phi >= M_PI_2 || phi < -M_PI_2 ? eh : 0; uf = fmodf(phi, M_PI_2) / M_PI_2; @@ -3267,7 +3515,7 @@ static int xyz_to_barrelsplit(const V360Context *s, ew = width / 3; eh = height / 4; - u_shift = s->ih_flip ? 0 : 2 * ew; + u_shift = 2 * ew; if (theta <= 0.f && theta >= -M_PI_2 && phi <= M_PI_2 && phi >= -M_PI_2) { @@ -3291,9 +3539,6 @@ static int xyz_to_barrelsplit(const V360Context *s, v_shift = height * 0.75f; } - uf *= s->input_mirror_modifier[0] * s->input_mirror_modifier[1]; - vf *= s->input_mirror_modifier[1]; - uf = 0.5f * width / 3.f * (uf * scalew + 1.f); vf = height * 0.25f * (vf * scaleh + 1.f) + v_offset; } @@ -3532,73 +3777,161 @@ static int xyz_to_tspyramid(const V360Context *s, return 1; } -static void multiply_matrix(float c[3][3], const float a[3][3], const float b[3][3]) +/** + * Calculate 3D coordinates on sphere for corresponding frame position in octahedron format. + * + * @param s filter private context + * @param i horizontal position on frame [0, width) + * @param j vertical position on frame [0, height) + * @param width frame width + * @param height frame height + * @param vec coordinates on sphere + */ +static int octahedron_to_xyz(const V360Context *s, + int i, int j, int width, int height, + float *vec) { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - float sum = 0.f; + const float x = ((i + 0.5f) / width) * 2.f - 1.f; + const float y = ((j + 0.5f) / height) * 2.f - 1.f; + const float ax = fabsf(x); + const float ay = fabsf(y); - for (int k = 0; k < 3; k++) - sum += a[i][k] * b[k][j]; - - c[i][j] = sum; - } + vec[2] = 1.f - (ax + ay); + if (ax + ay > 1.f) { + vec[0] = (1.f - ay) * FFSIGN(x); + vec[1] = (1.f - ax) * FFSIGN(y); + } else { + vec[0] = x; + vec[1] = y; } + + normalize_vector(vec); + + return 1; } /** - * Calculate rotation matrix for yaw/pitch/roll angles. + * Calculate frame position in octahedron format for corresponding 3D coordinates on sphere. + * + * @param s filter private context + * @param vec coordinates on sphere + * @param width frame width + * @param height frame height + * @param us horizontal coordinates for interpolation window + * @param vs vertical coordinates for interpolation window + * @param du horizontal relative coordinate + * @param dv vertical relative coordinate */ -static inline void calculate_rotation_matrix(float yaw, float pitch, float roll, - float rot_mat[3][3], - const int rotation_order[3]) +static int xyz_to_octahedron(const V360Context *s, + const float *vec, int width, int height, + int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) +{ + float uf, vf, zf; + int ui, vi; + float div = fabsf(vec[0]) + fabsf(vec[1]) + fabsf(vec[2]); + + uf = vec[0] / div; + vf = vec[1] / div; + zf = vec[2]; + + if (zf < 0.f) { + zf = vf; + vf = (1.f - fabsf(uf)) * FFSIGN(zf); + uf = (1.f - fabsf(zf)) * FFSIGN(uf); + } + + uf = uf * 0.5f + 0.5f; + vf = vf * 0.5f + 0.5f; + + uf *= width; + vf *= height; + + ui = floorf(uf); + vi = floorf(vf); + + *du = uf - ui; + *dv = vf - vi; + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + us[i][j] = av_clip(ui + j - 1, 0, width - 1); + vs[i][j] = av_clip(vi + i - 1, 0, height - 1); + } + } + + return 1; +} + +static void multiply_quaternion(float c[4], const float a[4], const float b[4]) +{ + c[0] = a[0] * b[0] - a[1] * b[1] - a[2] * b[2] - a[3] * b[3]; + c[1] = a[1] * b[0] + a[0] * b[1] + a[2] * b[3] - a[3] * b[2]; + c[2] = a[2] * b[0] + a[0] * b[2] + a[3] * b[1] - a[1] * b[3]; + c[3] = a[3] * b[0] + a[0] * b[3] + a[1] * b[2] - a[2] * b[1]; +} + +static void conjugate_quaternion(float d[4], const float q[4]) +{ + d[0] = q[0]; + d[1] = -q[1]; + d[2] = -q[2]; + d[3] = -q[3]; +} + +/** + * Calculate rotation quaternion for yaw/pitch/roll angles. + */ +static inline void calculate_rotation(float yaw, float pitch, float roll, + float rot_quaternion[2][4], + const int rotation_order[3]) { const float yaw_rad = yaw * M_PI / 180.f; const float pitch_rad = pitch * M_PI / 180.f; const float roll_rad = roll * M_PI / 180.f; - const float sin_yaw = sinf(yaw_rad); - const float cos_yaw = cosf(yaw_rad); - const float sin_pitch = sinf(pitch_rad); - const float cos_pitch = cosf(pitch_rad); - const float sin_roll = sinf(roll_rad); - const float cos_roll = cosf(roll_rad); + const float sin_yaw = sinf(yaw_rad * 0.5f); + const float cos_yaw = cosf(yaw_rad * 0.5f); + const float sin_pitch = sinf(pitch_rad * 0.5f); + const float cos_pitch = cosf(pitch_rad * 0.5f); + const float sin_roll = sinf(roll_rad * 0.5f); + const float cos_roll = cosf(roll_rad * 0.5f); - float m[3][3][3]; - float temp[3][3]; + float m[3][4]; + float tmp[2][4]; - m[0][0][0] = cos_yaw; m[0][0][1] = 0; m[0][0][2] = sin_yaw; - m[0][1][0] = 0; m[0][1][1] = 1; m[0][1][2] = 0; - m[0][2][0] = -sin_yaw; m[0][2][1] = 0; m[0][2][2] = cos_yaw; + m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f; + m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f; + m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll; - m[1][0][0] = 1; m[1][0][1] = 0; m[1][0][2] = 0; - m[1][1][0] = 0; m[1][1][1] = cos_pitch; m[1][1][2] = -sin_pitch; - m[1][2][0] = 0; m[1][2][1] = sin_pitch; m[1][2][2] = cos_pitch; + multiply_quaternion(tmp[0], rot_quaternion[0], m[rotation_order[0]]); + multiply_quaternion(tmp[1], tmp[0], m[rotation_order[1]]); + multiply_quaternion(rot_quaternion[0], tmp[1], m[rotation_order[2]]); - m[2][0][0] = cos_roll; m[2][0][1] = -sin_roll; m[2][0][2] = 0; - m[2][1][0] = sin_roll; m[2][1][1] = cos_roll; m[2][1][2] = 0; - m[2][2][0] = 0; m[2][2][1] = 0; m[2][2][2] = 1; - - multiply_matrix(temp, m[rotation_order[0]], m[rotation_order[1]]); - multiply_matrix(rot_mat, temp, m[rotation_order[2]]); + conjugate_quaternion(rot_quaternion[1], rot_quaternion[0]); } /** - * Rotate vector with given rotation matrix. + * Rotate vector with given rotation quaternion. * - * @param rot_mat rotation matrix + * @param rot_quaternion rotation quaternion * @param vec vector */ -static inline void rotate(const float rot_mat[3][3], +static inline void rotate(const float rot_quaternion[2][4], float *vec) { - const float x_tmp = vec[0] * rot_mat[0][0] + vec[1] * rot_mat[0][1] + vec[2] * rot_mat[0][2]; - const float y_tmp = vec[0] * rot_mat[1][0] + vec[1] * rot_mat[1][1] + vec[2] * rot_mat[1][2]; - const float z_tmp = vec[0] * rot_mat[2][0] + vec[1] * rot_mat[2][1] + vec[2] * rot_mat[2][2]; + float qv[4], temp[4], rqv[4]; - vec[0] = x_tmp; - vec[1] = y_tmp; - vec[2] = z_tmp; + qv[0] = 0.f; + qv[1] = vec[0]; + qv[2] = vec[1]; + qv[3] = vec[2]; + + multiply_quaternion(temp, rot_quaternion[0], qv); + multiply_quaternion(rqv, temp, rot_quaternion[1]); + + vec[0] = rqv[1]; + vec[1] = rqv[2]; + vec[2] = rqv[3]; } static inline void set_mirror_modifier(int h_flip, int v_flip, int d_flip, @@ -3616,26 +3949,52 @@ static inline void mirror(const float *modifier, float *vec) vec[2] *= modifier[2]; } -static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int sizeof_mask, int p) +static inline void input_flip(int16_t u[4][4], int16_t v[4][4], int w, int h, int hflip, int vflip) { - if (!s->u[p]) - s->u[p] = av_calloc(s->uv_linesize[p] * s->pr_height[p], sizeof_uv); - if (!s->v[p]) - s->v[p] = av_calloc(s->uv_linesize[p] * s->pr_height[p], sizeof_uv); - if (!s->u[p] || !s->v[p]) - return AVERROR(ENOMEM); - if (sizeof_ker) { - if (!s->ker[p]) - s->ker[p] = av_calloc(s->uv_linesize[p] * s->pr_height[p], sizeof_ker); - if (!s->ker[p]) - return AVERROR(ENOMEM); + if (hflip) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) + u[i][j] = w - 1 - u[i][j]; + } } - if (sizeof_mask && !p) { - if (!s->mask) - s->mask = av_calloc(s->pr_width[p] * s->pr_height[p], sizeof_mask); - if (!s->mask) + if (vflip) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) + v[i][j] = h - 1 - v[i][j]; + } + } +} + +static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int sizeof_mask, int p) +{ + const int pr_height = s->pr_height[p]; + + for (int n = 0; n < s->nb_threads; n++) { + SliceXYRemap *r = &s->slice_remap[n]; + const int slice_start = (pr_height * n ) / s->nb_threads; + const int slice_end = (pr_height * (n + 1)) / s->nb_threads; + const int height = slice_end - slice_start; + + if (!r->u[p]) + r->u[p] = av_calloc(s->uv_linesize[p] * height, sizeof_uv); + if (!r->v[p]) + r->v[p] = av_calloc(s->uv_linesize[p] * height, sizeof_uv); + if (!r->u[p] || !r->v[p]) return AVERROR(ENOMEM); + if (sizeof_ker) { + if (!r->ker[p]) + r->ker[p] = av_calloc(s->uv_linesize[p] * height, sizeof_ker); + if (!r->ker[p]) + return AVERROR(ENOMEM); + } + + if (sizeof_mask && !p) { + if (!r->mask) + r->mask = av_calloc(s->pr_width[p] * height, sizeof_mask); + if (!r->mask) + return AVERROR(ENOMEM); + } } return 0; @@ -3644,6 +4003,29 @@ static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int siz static void fov_from_dfov(int format, float d_fov, float w, float h, float *h_fov, float *v_fov) { switch (format) { + case ORTHOGRAPHIC: + { + const float d = 0.5f * hypotf(w, h); + const float l = sinf(d_fov * M_PI / 360.f) / d; + + *h_fov = asinf(w * 0.5 * l) * 360.f / M_PI; + *v_fov = asinf(h * 0.5 * l) * 360.f / M_PI; + + if (d_fov > 180.f) { + *h_fov = 180.f - *h_fov; + *v_fov = 180.f - *v_fov; + } + } + break; + case EQUISOLID: + { + const float d = 0.5f * hypotf(w, h); + const float l = d / (sinf(d_fov * M_PI / 720.f)); + + *h_fov = 2.f * asinf(w * 0.5f / l) * 360.f / M_PI; + *v_fov = 2.f * asinf(h * 0.5f / l) * 360.f / M_PI; + } + break; case STEREOGRAPHIC: { const float d = 0.5f * hypotf(w, h); @@ -3699,6 +4081,7 @@ static void set_dimensions(int *outw, int *outh, int w, int h, const AVPixFmtDes static av_always_inline int v360_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { V360Context *s = ctx->priv; + SliceXYRemap *r = &s->slice_remap[jobnr]; for (int p = 0; p < s->nb_allocated; p++) { const int max_value = s->max_value; @@ -3709,17 +4092,18 @@ static av_always_inline int v360_slice(AVFilterContext *ctx, void *arg, int jobn const int in_height = s->inplaneheight[p]; const int slice_start = (height * jobnr ) / nb_jobs; const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int elements = s->elements; float du, dv; float vec[3]; XYRemap rmap; for (int j = slice_start; j < slice_end; j++) { for (int i = 0; i < width; i++) { - int16_t *u = s->u[p] + (j * uv_linesize + i) * s->elements; - int16_t *v = s->v[p] + (j * uv_linesize + i) * s->elements; - int16_t *ker = s->ker[p] + (j * uv_linesize + i) * s->elements; - uint8_t *mask8 = p ? NULL : s->mask + (j * s->pr_width[0] + i); - uint16_t *mask16 = p ? NULL : (uint16_t *)s->mask + (j * s->pr_width[0] + i); + int16_t *u = r->u[p] + ((j - slice_start) * uv_linesize + i) * elements; + int16_t *v = r->v[p] + ((j - slice_start) * uv_linesize + i) * elements; + int16_t *ker = r->ker[p] + ((j - slice_start) * uv_linesize + i) * elements; + uint8_t *mask8 = p ? NULL : r->mask + ((j - slice_start) * s->pr_width[0] + i); + uint16_t *mask16 = p ? NULL : (uint16_t *)r->mask + ((j - slice_start) * s->pr_width[0] + i); int in_mask, out_mask; if (s->out_transpose) @@ -3727,7 +4111,7 @@ static av_always_inline int v360_slice(AVFilterContext *ctx, void *arg, int jobn else out_mask = s->out_transform(s, i, j, width, height, vec); av_assert1(!isnan(vec[0]) && !isnan(vec[1]) && !isnan(vec[2])); - rotate(s->rot_mat, vec); + rotate(s->rot_quaternion, vec); av_assert1(!isnan(vec[0]) && !isnan(vec[1]) && !isnan(vec[2])); normalize_vector(vec); mirror(s->output_mirror_modifier, vec); @@ -3735,10 +4119,11 @@ static av_always_inline int v360_slice(AVFilterContext *ctx, void *arg, int jobn in_mask = s->in_transform(s, vec, in_height, in_width, rmap.v, rmap.u, &du, &dv); else in_mask = s->in_transform(s, vec, in_width, in_height, rmap.u, rmap.v, &du, &dv); + input_flip(rmap.u, rmap.v, in_width, in_height, s->ih_flip, s->iv_flip); av_assert1(!isnan(du) && !isnan(dv)); s->calculate_kernel(du, dv, &rmap, u, v, ker); - if (!p && s->mask) { + if (!p && r->mask) { if (s->mask_size == 1) { mask8[0] = 255 * (out_mask & in_mask); } else { @@ -3771,8 +4156,6 @@ static int config_output(AVFilterLink *outlink) int have_alpha; s->max_value = (1 << depth) - 1; - s->input_mirror_modifier[0] = s->ih_flip ? -1.f : 1.f; - s->input_mirror_modifier[1] = s->iv_flip ? -1.f : 1.f; switch (s->interp) { case NEAREST: @@ -3824,6 +4207,13 @@ static int config_output(AVFilterLink *outlink) sizeof_uv = sizeof(int16_t) * s->elements; sizeof_ker = sizeof(int16_t) * s->elements; break; + case MITCHELL: + s->calculate_kernel = mitchell_kernel; + s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice; + s->elements = 4 * 4; + sizeof_uv = sizeof(int16_t) * s->elements; + sizeof_ker = sizeof(int16_t) * s->elements; + break; default: av_assert0(0); } @@ -4014,6 +4404,24 @@ static int config_output(AVFilterLink *outlink) wf = w * 2.f; hf = h; break; + case EQUISOLID: + s->in_transform = xyz_to_equisolid; + err = prepare_equisolid_in(ctx); + wf = w; + hf = h / 2.f; + break; + case ORTHOGRAPHIC: + s->in_transform = xyz_to_orthographic; + err = prepare_orthographic_in(ctx); + wf = w; + hf = h / 2.f; + break; + case OCTAHEDRON: + s->in_transform = xyz_to_octahedron; + err = 0; + wf = w; + hf = h / 2.f; + break; default: av_log(ctx, AV_LOG_ERROR, "Specified input format is not handled.\n"); return AVERROR_BUG; @@ -4150,6 +4558,24 @@ static int config_output(AVFilterLink *outlink) w = lrintf(wf / 2.f); h = lrintf(hf); break; + case EQUISOLID: + s->out_transform = equisolid_to_xyz; + prepare_out = prepare_equisolid_out; + w = lrintf(wf); + h = lrintf(hf * 2.f); + break; + case ORTHOGRAPHIC: + s->out_transform = orthographic_to_xyz; + prepare_out = prepare_orthographic_out; + w = lrintf(wf); + h = lrintf(hf * 2.f); + break; + case OCTAHEDRON: + s->out_transform = octahedron_to_xyz; + prepare_out = NULL; + w = lrintf(wf); + h = lrintf(hf * 2.f); + break; default: av_log(ctx, AV_LOG_ERROR, "Specified output format is not handled.\n"); return AVERROR_BUG; @@ -4219,6 +4645,7 @@ static int config_output(AVFilterLink *outlink) outlink->h = h; outlink->w = w; + s->nb_threads = FFMIN(outlink->h, ff_filter_get_nb_threads(ctx)); s->nb_planes = av_pix_fmt_count_planes(inlink->format); have_alpha = !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA); @@ -4231,13 +4658,23 @@ static int config_output(AVFilterLink *outlink) s->map[1] = s->map[2] = 1; } - for (int i = 0; i < s->nb_allocated; i++) - allocate_plane(s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha * s->alpha, i); + if (!s->slice_remap) + s->slice_remap = av_calloc(s->nb_threads, sizeof(*s->slice_remap)); + if (!s->slice_remap) + return AVERROR(ENOMEM); + + for (int i = 0; i < s->nb_allocated; i++) { + err = allocate_plane(s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha * s->alpha, i); + if (err < 0) + return err; + } + + calculate_rotation(s->yaw, s->pitch, s->roll, + s->rot_quaternion, s->rotation_order); - calculate_rotation_matrix(s->yaw, s->pitch, s->roll, s->rot_mat, s->rotation_order); set_mirror_modifier(s->h_flip, s->v_flip, s->d_flip, s->output_mirror_modifier); - ctx->internal->execute(ctx, v360_slice, NULL, NULL, FFMIN(outlink->h, ff_filter_get_nb_threads(ctx))); + ctx->internal->execute(ctx, v360_slice, NULL, NULL, s->nb_threads); return 0; } @@ -4260,7 +4697,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) td.in = in; td.out = out; - ctx->internal->execute(ctx, s->remap_slice, &td, NULL, FFMIN(outlink->h, ff_filter_get_nb_threads(ctx))); + ctx->internal->execute(ctx, s->remap_slice, &td, NULL, s->nb_threads); av_frame_free(&in); return ff_filter_frame(outlink, out); @@ -4269,8 +4706,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags) { + V360Context *s = ctx->priv; int ret; + s->yaw = s->pitch = s->roll = 0.f; + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); if (ret < 0) return ret; @@ -4278,16 +4718,33 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar return config_output(ctx->outputs[0]); } +static av_cold int init(AVFilterContext *ctx) +{ + V360Context *s = ctx->priv; + + s->rot_quaternion[0][0] = 1.f; + s->rot_quaternion[0][1] = s->rot_quaternion[0][2] = s->rot_quaternion[0][3] = 0.f; + + return 0; +} + static av_cold void uninit(AVFilterContext *ctx) { V360Context *s = ctx->priv; - for (int p = 0; p < s->nb_allocated; p++) { - av_freep(&s->u[p]); - av_freep(&s->v[p]); - av_freep(&s->ker[p]); + for (int n = 0; n < s->nb_threads && s->slice_remap; n++) { + SliceXYRemap *r = &s->slice_remap[n]; + + for (int p = 0; p < s->nb_allocated; p++) { + av_freep(&r->u[p]); + av_freep(&r->v[p]); + av_freep(&r->ker[p]); + } + + av_freep(&r->mask); } - av_freep(&s->mask); + + av_freep(&s->slice_remap); } static const AVFilterPad inputs[] = { @@ -4312,6 +4769,7 @@ AVFilter ff_vf_v360 = { .name = "v360", .description = NULL_IF_CONFIG_SMALL("Convert 360 projection of video."), .priv_size = sizeof(V360Context), + .init = init, .uninit = uninit, .query_formats = query_formats, .inputs = inputs, diff --git a/libavfilter/vf_vaguedenoiser.c b/libavfilter/vf_vaguedenoiser.c index 49b338ff9..b510cdd62 100644 --- a/libavfilter/vf_vaguedenoiser.c +++ b/libavfilter/vf_vaguedenoiser.c @@ -71,7 +71,7 @@ static const AVOption vaguedenoiser_options[] = { { "method", "set filtering method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=2 }, 0, 2, FLAGS, "method" }, { "hard", "hard thresholding", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "method" }, { "soft", "soft thresholding", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "method" }, - { "garrote", "garotte thresholding", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "method" }, + { "garrote", "garrote thresholding", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "method" }, { "nsteps", "set number of steps", OFFSET(nsteps), AV_OPT_TYPE_INT, {.i64=6 }, 1, 32, FLAGS }, { "percent", "set percent of full denoising", OFFSET(percent),AV_OPT_TYPE_FLOAT, {.dbl=85}, 0,100, FLAGS }, { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15 }, 0, 15, FLAGS }, diff --git a/libavfilter/vf_vectorscope.c b/libavfilter/vf_vectorscope.c index 38af87804..e51f8191f 100644 --- a/libavfilter/vf_vectorscope.c +++ b/libavfilter/vf_vectorscope.c @@ -216,23 +216,23 @@ static int query_formats(AVFilterContext *ctx) AVFilterFormats *avff; int depth, rgb, i, ret; - if (!ctx->inputs[0]->in_formats || - !ctx->inputs[0]->in_formats->nb_formats) { + if (!ctx->inputs[0]->incfg.formats || + !ctx->inputs[0]->incfg.formats->nb_formats) { return AVERROR(EAGAIN); } - if (!ctx->inputs[0]->out_formats) { + if (!ctx->inputs[0]->outcfg.formats) { const enum AVPixelFormat *in_pix_fmts; if ((s->x == 1 && s->y == 2) || (s->x == 2 && s->y == 1)) in_pix_fmts = in2_pix_fmts; else in_pix_fmts = in1_pix_fmts; - if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0) return ret; } - avff = ctx->inputs[0]->in_formats; + avff = ctx->inputs[0]->incfg.formats; desc = av_pix_fmt_desc_get(avff->formats[0]); rgb = desc->flags & AV_PIX_FMT_FLAG_RGB; depth = desc->comp[0].depth; @@ -261,7 +261,7 @@ static int query_formats(AVFilterContext *ctx) out_pix_fmts = out_yuv12_pix_fmts; else return AVERROR(EAGAIN); - if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c index c7c39d334..1de3dc5da 100644 --- a/libavfilter/vf_vflip.c +++ b/libavfilter/vf_vflip.c @@ -33,6 +33,7 @@ typedef struct FlipContext { const AVClass *class; int vsub; ///< vertical chroma subsampling + int bayer; } FlipContext; static const AVOption vflip_options[] = { @@ -47,6 +48,7 @@ static int config_input(AVFilterLink *link) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); flip->vsub = desc->log2_chroma_h; + flip->bayer = !!(desc->flags & AV_PIX_FMT_FLAG_BAYER); return 0; } @@ -74,11 +76,43 @@ static AVFrame *get_video_buffer(AVFilterLink *link, int w, int h) return frame; } +static int flip_bayer(AVFilterLink *link, AVFrame *in) +{ + AVFilterContext *ctx = link->dst; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out; + uint8_t *inrow = in->data[0], *outrow; + int i, width = outlink->w << (av_pix_fmt_desc_get(link->format)->comp[0].step > 1); + if (outlink->h & 1) { + av_log(ctx, AV_LOG_ERROR, "Bayer vertical flip needs even height\n"); + return AVERROR_INVALIDDATA; + } + + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + outrow = out->data[0] + out->linesize[0] * (outlink->h - 2); + for (i = 0; i < outlink->h >> 1; i++) { + memcpy(outrow, inrow, width); + memcpy(outrow + out->linesize[0], inrow + in->linesize[0], width); + inrow += 2 * in->linesize[0]; + outrow -= 2 * out->linesize[0]; + } + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + static int filter_frame(AVFilterLink *link, AVFrame *frame) { FlipContext *flip = link->dst->priv; int i; + if (flip->bayer) + return flip_bayer(link, frame); + for (i = 0; i < 4; i ++) { int vsub = i == 1 || i == 2 ? flip->vsub : 0; int height = AV_CEIL_RSHIFT(link->h, vsub); diff --git a/libavfilter/vf_vibrance.c b/libavfilter/vf_vibrance.c index 8e1a55cac..edea521b1 100644 --- a/libavfilter/vf_vibrance.c +++ b/libavfilter/vf_vibrance.c @@ -21,10 +21,15 @@ #include "libavutil/opt.h" #include "libavutil/imgutils.h" #include "avfilter.h" +#include "drawutils.h" #include "formats.h" #include "internal.h" #include "video.h" +#define R 0 +#define G 1 +#define B 2 + typedef struct VibranceContext { const AVClass *class; @@ -33,7 +38,9 @@ typedef struct VibranceContext { float lcoeffs[3]; int alternate; + int step; int depth; + uint8_t rgba_map[4]; int (*do_slice)(AVFilterContext *s, void *arg, int jobnr, int nb_jobs); @@ -160,6 +167,118 @@ static int vibrance_slice16(AVFilterContext *avctx, void *arg, int jobnr, int nb return 0; } +static int vibrance_slice8p(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs) +{ + VibranceContext *s = avctx->priv; + AVFrame *frame = arg; + const int step = s->step; + const int width = frame->width; + const int height = frame->height; + const float scale = 1.f / 255.f; + const float gc = s->lcoeffs[0]; + const float bc = s->lcoeffs[1]; + const float rc = s->lcoeffs[2]; + const uint8_t roffset = s->rgba_map[R]; + const uint8_t goffset = s->rgba_map[G]; + const uint8_t boffset = s->rgba_map[B]; + const float intensity = s->intensity; + const float alternate = s->alternate ? 1.f : -1.f; + const float gintensity = intensity * s->balance[0]; + const float bintensity = intensity * s->balance[1]; + const float rintensity = intensity * s->balance[2]; + const float sgintensity = alternate * FFSIGN(gintensity); + const float sbintensity = alternate * FFSIGN(bintensity); + const float srintensity = alternate * FFSIGN(rintensity); + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int linesize = frame->linesize[0]; + uint8_t *ptr = frame->data[0] + slice_start * linesize; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + float g = ptr[x * step + goffset] * scale; + float b = ptr[x * step + boffset] * scale; + float r = ptr[x * step + roffset] * scale; + float max_color = FFMAX3(r, g, b); + float min_color = FFMIN3(r, g, b); + float color_saturation = max_color - min_color; + float luma = g * gc + r * rc + b * bc; + const float cg = 1.f + gintensity * (1.f - sgintensity * color_saturation); + const float cb = 1.f + bintensity * (1.f - sbintensity * color_saturation); + const float cr = 1.f + rintensity * (1.f - srintensity * color_saturation); + + g = lerpf(luma, g, cg); + b = lerpf(luma, b, cb); + r = lerpf(luma, r, cr); + + ptr[x * step + goffset] = av_clip_uint8(g * 255.f); + ptr[x * step + boffset] = av_clip_uint8(b * 255.f); + ptr[x * step + roffset] = av_clip_uint8(r * 255.f); + } + + ptr += linesize; + } + + return 0; +} + +static int vibrance_slice16p(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs) +{ + VibranceContext *s = avctx->priv; + AVFrame *frame = arg; + const int step = s->step; + const int depth = s->depth; + const float max = (1 << depth) - 1; + const float scale = 1.f / max; + const float gc = s->lcoeffs[0]; + const float bc = s->lcoeffs[1]; + const float rc = s->lcoeffs[2]; + const uint8_t roffset = s->rgba_map[R]; + const uint8_t goffset = s->rgba_map[G]; + const uint8_t boffset = s->rgba_map[B]; + const int width = frame->width; + const int height = frame->height; + const float intensity = s->intensity; + const float alternate = s->alternate ? 1.f : -1.f; + const float gintensity = intensity * s->balance[0]; + const float bintensity = intensity * s->balance[1]; + const float rintensity = intensity * s->balance[2]; + const float sgintensity = alternate * FFSIGN(gintensity); + const float sbintensity = alternate * FFSIGN(bintensity); + const float srintensity = alternate * FFSIGN(rintensity); + const int slice_start = (height * jobnr) / nb_jobs; + const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int linesize = frame->linesize[0] / 2; + uint16_t *ptr = (uint16_t *)frame->data[0] + slice_start * linesize; + + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + float g = ptr[x * step + goffset] * scale; + float b = ptr[x * step + boffset] * scale; + float r = ptr[x * step + roffset] * scale; + float max_color = FFMAX3(r, g, b); + float min_color = FFMIN3(r, g, b); + float color_saturation = max_color - min_color; + float luma = g * gc + r * rc + b * bc; + const float cg = 1.f + gintensity * (1.f - sgintensity * color_saturation); + const float cb = 1.f + bintensity * (1.f - sbintensity * color_saturation); + const float cr = 1.f + rintensity * (1.f - srintensity * color_saturation); + + g = lerpf(luma, g, cg); + b = lerpf(luma, b, cb); + r = lerpf(luma, r, cr); + + ptr[x * step + goffset] = av_clip_uintp2_c(g * max, depth); + ptr[x * step + boffset] = av_clip_uintp2_c(b * max, depth); + ptr[x * step + roffset] = av_clip_uintp2_c(r * max, depth); + } + + ptr += linesize; + } + + return 0; +} + static int filter_frame(AVFilterLink *link, AVFrame *frame) { AVFilterContext *avctx = link->dst; @@ -176,10 +295,17 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) static av_cold int query_formats(AVFilterContext *avctx) { static const enum AVPixelFormat pixel_fmts[] = { + AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, + AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, + AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, + AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, + AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48, + AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64, AV_PIX_FMT_NONE }; @@ -197,9 +323,21 @@ static av_cold int config_input(AVFilterLink *inlink) AVFilterContext *avctx = inlink->dst; VibranceContext *s = avctx->priv; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR; + + s->step = desc->nb_components; + if (inlink->format == AV_PIX_FMT_RGB0 || + inlink->format == AV_PIX_FMT_0RGB || + inlink->format == AV_PIX_FMT_BGR0 || + inlink->format == AV_PIX_FMT_0BGR) + s->step = 4; s->depth = desc->comp[0].depth; s->do_slice = s->depth <= 8 ? vibrance_slice8 : vibrance_slice16; + if (!planar) + s->do_slice = s->depth <= 8 ? vibrance_slice8p : vibrance_slice16p; + + ff_fill_rgba_map(s->rgba_map, inlink->format); return 0; } diff --git a/libavfilter/vf_vif.c b/libavfilter/vf_vif.c new file mode 100644 index 000000000..024821064 --- /dev/null +++ b/libavfilter/vf_vif.c @@ -0,0 +1,657 @@ +/* + * Copyright (c) 2017 Ronald S. Bultje + * Copyright (c) 2017 Ashish Pratap Singh + * Copyright (c) 2021 Paul B Mahol + * + * 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 + * Calculate VIF between two input videos. + */ + +#include + +#include "libavutil/avstring.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "avfilter.h" +#include "framesync.h" +#include "drawutils.h" +#include "formats.h" +#include "internal.h" +#include "vif.h" +#include "video.h" + +typedef struct VIFContext { + const AVClass *class; + FFFrameSync fs; + const AVPixFmtDescriptor *desc; + int width; + int height; + int nb_threads; + float factor; + float *data_buf[13]; + float **temp; + float *ref_data; + float *main_data; + double vif_sum[4]; + double vif_min[4]; + double vif_max[4]; + uint64_t nb_frames; +} VIFContext; + +#define OFFSET(x) offsetof(VIFContext, x) + +static const AVOption vif_options[] = { + { NULL } +}; + +AVFILTER_DEFINE_CLASS(vif); + +static const uint8_t vif_filter1d_width1[4] = { 17, 9, 5, 3 }; + +static const float vif_filter1d_table[4][17] = +{ + { + 0.00745626912, 0.0142655009, 0.0250313189, 0.0402820669, 0.0594526194, + 0.0804751068, 0.0999041125, 0.113746084, 0.118773937, 0.113746084, + 0.0999041125, 0.0804751068, 0.0594526194, 0.0402820669, 0.0250313189, + 0.0142655009, 0.00745626912 + }, + { + 0.0189780835, 0.0558981746, 0.120920904, 0.192116052, 0.224173605, + 0.192116052, 0.120920904, 0.0558981746, 0.0189780835 + }, + { + 0.054488685, 0.244201347, 0.402619958, 0.244201347, 0.054488685 + }, + { + 0.166378498, 0.667243004, 0.166378498 + } +}; + +typedef struct ThreadData { + const float *filter; + const float *src; + float *dst; + int w, h; + int src_stride; + int dst_stride; + int filter_width; + float **temp; +} ThreadData; + +static void vif_dec2(const float *src, float *dst, int w, int h, + int src_stride, int dst_stride) +{ + const int dst_px_stride = dst_stride / 2; + + for (int i = 0; i < h / 2; i++) { + for (int j = 0; j < w / 2; j++) + dst[i * dst_px_stride + j] = src[(i * 2) * src_stride + (j * 2)]; + } +} + +static void vif_statistic(const float *mu1_sq, const float *mu2_sq, + const float *mu1_mu2, const float *xx_filt, + const float *yy_filt, const float *xy_filt, + float *num, float *den, int w, int h) +{ + static const float sigma_nsq = 2; + float mu1_sq_val, mu2_sq_val, mu1_mu2_val, xx_filt_val, yy_filt_val, xy_filt_val; + float sigma1_sq, sigma2_sq, sigma12, g, sv_sq, eps = 1.0e-10f; + float gain_limit = 100.f; + float num_val, den_val; + float accum_num = 0.0f; + float accum_den = 0.0f; + + for (int i = 0; i < h; i++) { + float accum_inner_num = 0.f; + float accum_inner_den = 0.f; + + for (int j = 0; j < w; j++) { + mu1_sq_val = mu1_sq[i * w + j]; + mu2_sq_val = mu2_sq[i * w + j]; + mu1_mu2_val = mu1_mu2[i * w + j]; + xx_filt_val = xx_filt[i * w + j]; + yy_filt_val = yy_filt[i * w + j]; + xy_filt_val = xy_filt[i * w + j]; + + sigma1_sq = xx_filt_val - mu1_sq_val; + sigma2_sq = yy_filt_val - mu2_sq_val; + sigma12 = xy_filt_val - mu1_mu2_val; + + sigma1_sq = FFMAX(sigma1_sq, 0.0f); + sigma2_sq = FFMAX(sigma2_sq, 0.0f); + sigma12 = FFMAX(sigma12, 0.0f); + + g = sigma12 / (sigma1_sq + eps); + sv_sq = sigma2_sq - g * sigma12; + + if (sigma1_sq < eps) { + g = 0.0f; + sv_sq = sigma2_sq; + sigma1_sq = 0.0f; + } + + if (sigma2_sq < eps) { + g = 0.0f; + sv_sq = 0.0f; + } + + if (g < 0.0f) { + sv_sq = sigma2_sq; + g = 0.0f; + } + sv_sq = FFMAX(sv_sq, eps); + + g = FFMIN(g, gain_limit); + + num_val = log2f(1.0f + g * g * sigma1_sq / (sv_sq + sigma_nsq)); + den_val = log2f(1.0f + sigma1_sq / sigma_nsq); + + if (isnan(den_val)) + num_val = den_val = 1.f; + + accum_inner_num += num_val; + accum_inner_den += den_val; + } + + accum_num += accum_inner_num; + accum_den += accum_inner_den; + } + + num[0] = accum_num; + den[0] = accum_den; +} + +static void vif_xx_yy_xy(const float *x, const float *y, float *xx, float *yy, + float *xy, int w, int h) +{ + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + float xval = x[j]; + float yval = y[j]; + float xxval = xval * xval; + float yyval = yval * yval; + float xyval = xval * yval; + + xx[j] = xxval; + yy[j] = yyval; + xy[j] = xyval; + } + + xx += w; + yy += w; + xy += w; + x += w; + y += w; + } +} + +static int vif_filter1d(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ThreadData *td = arg; + const float *filter = td->filter; + const float *src = td->src; + float *dst = td->dst; + int w = td->w; + int h = td->h; + int src_stride = td->src_stride; + int dst_stride = td->dst_stride; + int filt_w = td->filter_width; + float *temp = td->temp[jobnr]; + const int slice_start = (h * jobnr) / nb_jobs; + const int slice_end = (h * (jobnr+1)) / nb_jobs; + + for (int i = slice_start; i < slice_end; i++) { + /** Vertical pass. */ + for (int j = 0; j < w; j++) { + float sum = 0.f; + + if (i >= filt_w / 2 && i < h - filt_w / 2 - 1) { + for (int filt_i = 0; filt_i < filt_w; filt_i++) { + const float filt_coeff = filter[filt_i]; + float img_coeff; + int ii = i - filt_w / 2 + filt_i; + + img_coeff = src[ii * src_stride + j]; + sum += filt_coeff * img_coeff; + } + } else { + for (int filt_i = 0; filt_i < filt_w; filt_i++) { + const float filt_coeff = filter[filt_i]; + int ii = i - filt_w / 2 + filt_i; + float img_coeff; + + ii = ii < 0 ? -ii : (ii >= h ? 2 * h - ii - 1 : ii); + + img_coeff = src[ii * src_stride + j]; + sum += filt_coeff * img_coeff; + } + } + + temp[j] = sum; + } + + /** Horizontal pass. */ + for (int j = 0; j < w; j++) { + float sum = 0.f; + + if (j >= filt_w / 2 && j < w - filt_w / 2 - 1) { + for (int filt_j = 0; filt_j < filt_w; filt_j++) { + const float filt_coeff = filter[filt_j]; + int jj = j - filt_w / 2 + filt_j; + float img_coeff; + + img_coeff = temp[jj]; + sum += filt_coeff * img_coeff; + } + } else { + for (int filt_j = 0; filt_j < filt_w; filt_j++) { + const float filt_coeff = filter[filt_j]; + int jj = j - filt_w / 2 + filt_j; + float img_coeff; + + jj = jj < 0 ? -jj : (jj >= w ? 2 * w - jj - 1 : jj); + + img_coeff = temp[jj]; + sum += filt_coeff * img_coeff; + } + } + + dst[i * dst_stride + j] = sum; + } + } + + return 0; +} + +int ff_compute_vif2(AVFilterContext *ctx, + const float *ref, const float *main, int w, int h, + int ref_stride, int main_stride, float *score, + float *data_buf[14], float **temp, + int gnb_threads) +{ + ThreadData td; + float *ref_scale = data_buf[0]; + float *main_scale = data_buf[1]; + float *ref_sq = data_buf[2]; + float *main_sq = data_buf[3]; + float *ref_main = data_buf[4]; + float *mu1 = data_buf[5]; + float *mu2 = data_buf[6]; + float *mu1_sq = data_buf[7]; + float *mu2_sq = data_buf[8]; + float *mu1_mu2 = data_buf[9]; + float *ref_sq_filt = data_buf[10]; + float *main_sq_filt = data_buf[11]; + float *ref_main_filt = data_buf[12]; + + float *curr_ref_scale = (float *)ref; + float *curr_main_scale = (float *)main; + int curr_ref_stride = ref_stride; + int curr_main_stride = main_stride; + + float num = 0.f; + float den = 0.f; + + for (int scale = 0; scale < 4; scale++) { + const float *filter = vif_filter1d_table[scale]; + int filter_width = vif_filter1d_width1[scale]; + const int nb_threads = FFMIN(h, gnb_threads); + int buf_valid_w = w; + int buf_valid_h = h; + + td.filter = filter; + td.filter_width = filter_width; + + if (scale > 0) { + td.src = curr_ref_scale; + td.dst = mu1; + td.w = w; + td.h = h; + td.src_stride = curr_ref_stride; + td.dst_stride = w; + td.temp = temp; + ctx->internal->execute(ctx, vif_filter1d, &td, NULL, nb_threads); + + td.src = curr_main_scale; + td.dst = mu2; + td.src_stride = curr_main_stride; + ctx->internal->execute(ctx, vif_filter1d, &td, NULL, nb_threads); + + vif_dec2(mu1, ref_scale, buf_valid_w, buf_valid_h, w, w); + vif_dec2(mu2, main_scale, buf_valid_w, buf_valid_h, w, w); + + w = buf_valid_w / 2; + h = buf_valid_h / 2; + + buf_valid_w = w; + buf_valid_h = h; + + curr_ref_scale = ref_scale; + curr_main_scale = main_scale; + + curr_ref_stride = w; + curr_main_stride = w; + } + + td.src = curr_ref_scale; + td.dst = mu1; + td.w = w; + td.h = h; + td.src_stride = curr_ref_stride; + td.dst_stride = w; + td.temp = temp; + ctx->internal->execute(ctx, vif_filter1d, &td, NULL, nb_threads); + + td.src = curr_main_scale; + td.dst = mu2; + td.src_stride = curr_main_stride; + ctx->internal->execute(ctx, vif_filter1d, &td, NULL, nb_threads); + + vif_xx_yy_xy(mu1, mu2, mu1_sq, mu2_sq, mu1_mu2, w, h); + + vif_xx_yy_xy(curr_ref_scale, curr_main_scale, ref_sq, main_sq, ref_main, w, h); + + td.src = ref_sq; + td.dst = ref_sq_filt; + td.src_stride = w; + ctx->internal->execute(ctx, vif_filter1d, &td, NULL, nb_threads); + + td.src = main_sq; + td.dst = main_sq_filt; + td.src_stride = w; + ctx->internal->execute(ctx, vif_filter1d, &td, NULL, nb_threads); + + td.src = ref_main; + td.dst = ref_main_filt; + ctx->internal->execute(ctx, vif_filter1d, &td, NULL, nb_threads); + + vif_statistic(mu1_sq, mu2_sq, mu1_mu2, ref_sq_filt, main_sq_filt, + ref_main_filt, &num, &den, w, h); + + score[scale] = den <= FLT_EPSILON ? 1.f : num / den; + } + + return 0; +} + +#define offset_fn(type, bits) \ +static void offset_##bits##bit(VIFContext *s, \ + const AVFrame *ref, \ + AVFrame *main, int stride)\ +{ \ + int w = s->width; \ + int h = s->height; \ + \ + int ref_stride = ref->linesize[0]; \ + int main_stride = main->linesize[0]; \ + \ + const type *ref_ptr = (const type *) ref->data[0]; \ + const type *main_ptr = (const type *) main->data[0]; \ + \ + const float factor = s->factor; \ + \ + float *ref_ptr_data = s->ref_data; \ + float *main_ptr_data = s->main_data; \ + \ + for (int i = 0; i < h; i++) { \ + for (int j = 0; j < w; j++) { \ + ref_ptr_data[j] = ref_ptr[j] * factor - 128.f; \ + main_ptr_data[j] = main_ptr[j] * factor - 128.f; \ + } \ + ref_ptr += ref_stride / sizeof(type); \ + ref_ptr_data += w; \ + main_ptr += main_stride / sizeof(type); \ + main_ptr_data += w; \ + } \ +} + +offset_fn(uint8_t, 8) +offset_fn(uint16_t, 16) + +static void set_meta(AVDictionary **metadata, const char *key, float d) +{ + char value[257]; + snprintf(value, sizeof(value), "%f", d); + av_dict_set(metadata, key, value, 0); +} + +static AVFrame *do_vif(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref) +{ + VIFContext *s = ctx->priv; + AVDictionary **metadata = &main->metadata; + float score[4]; + + s->factor = 1.f / (1 << (s->desc->comp[0].depth - 8)); + if (s->desc->comp[0].depth <= 8) { + offset_8bit(s, ref, main, s->width); + } else { + offset_16bit(s, ref, main, s->width); + } + + ff_compute_vif2(ctx, + s->ref_data, s->main_data, s->width, + s->height, s->width, s->width, + score, s->data_buf, s->temp, + s->nb_threads); + + set_meta(metadata, "lavfi.vif.scale.0", score[0]); + set_meta(metadata, "lavfi.vif.scale.1", score[1]); + set_meta(metadata, "lavfi.vif.scale.2", score[2]); + set_meta(metadata, "lavfi.vif.scale.3", score[3]); + + for (int i = 0; i < 4; i++) { + s->vif_min[i] = FFMIN(s->vif_min[i], score[i]); + s->vif_max[i] = FFMAX(s->vif_max[i], score[i]); + s->vif_sum[i] += score[i]; + } + + s->nb_frames++; + + return main; +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, + AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, + AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P, +#define PF(suf) AV_PIX_FMT_YUV420##suf, AV_PIX_FMT_YUV422##suf, AV_PIX_FMT_YUV444##suf + PF(P9), PF(P10), PF(P12), PF(P14), PF(P16), + AV_PIX_FMT_NONE + }; + + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +static int config_input_ref(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + VIFContext *s = ctx->priv; + + if (ctx->inputs[0]->w != ctx->inputs[1]->w || + ctx->inputs[0]->h != ctx->inputs[1]->h) { + av_log(ctx, AV_LOG_ERROR, "Width and height of input videos must be same.\n"); + return AVERROR(EINVAL); + } + if (ctx->inputs[0]->format != ctx->inputs[1]->format) { + av_log(ctx, AV_LOG_ERROR, "Inputs must be of same pixel format.\n"); + return AVERROR(EINVAL); + } + + s->desc = av_pix_fmt_desc_get(inlink->format); + s->width = ctx->inputs[0]->w; + s->height = ctx->inputs[0]->h; + s->nb_threads = ff_filter_get_nb_threads(ctx); + + for (int i = 0; i < 4; i++) { + s->vif_min[i] = DBL_MAX; + s->vif_max[i] = -DBL_MAX; + } + + for (int i = 0; i < 13; i++) { + if (!(s->data_buf[i] = av_calloc(s->width, s->height * sizeof(float)))) + return AVERROR(ENOMEM); + } + + if (!(s->ref_data = av_calloc(s->width, s->height * sizeof(float)))) + return AVERROR(ENOMEM); + + if (!(s->main_data = av_calloc(s->width, s->height * sizeof(float)))) + return AVERROR(ENOMEM); + + if (!(s->temp = av_calloc(s->nb_threads, sizeof(s->temp[0])))) + return AVERROR(ENOMEM); + + for (int i = 0; i < s->nb_threads; i++) { + if (!(s->temp[i] = av_calloc(s->width, sizeof(float)))) + return AVERROR(ENOMEM); + } + + return 0; +} + +static int process_frame(FFFrameSync *fs) +{ + AVFilterContext *ctx = fs->parent; + VIFContext *s = fs->opaque; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out_frame, *main_frame = NULL, *ref_frame = NULL; + int ret; + + ret = ff_framesync_dualinput_get(fs, &main_frame, &ref_frame); + if (ret < 0) + return ret; + + if (ctx->is_disabled || !ref_frame) { + out_frame = main_frame; + } else { + out_frame = do_vif(ctx, main_frame, ref_frame); + } + + out_frame->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base); + + return ff_filter_frame(outlink, out_frame); +} + + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + VIFContext *s = ctx->priv; + AVFilterLink *mainlink = ctx->inputs[0]; + FFFrameSyncIn *in; + int ret; + + outlink->w = mainlink->w; + outlink->h = mainlink->h; + outlink->time_base = mainlink->time_base; + outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; + outlink->frame_rate = mainlink->frame_rate; + if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) + return ret; + + in = s->fs.in; + in[0].time_base = mainlink->time_base; + in[1].time_base = ctx->inputs[1]->time_base; + in[0].sync = 2; + in[0].before = EXT_STOP; + in[0].after = EXT_STOP; + in[1].sync = 1; + in[1].before = EXT_STOP; + in[1].after = EXT_STOP; + s->fs.opaque = s; + s->fs.on_event = process_frame; + + return ff_framesync_configure(&s->fs); +} + +static int activate(AVFilterContext *ctx) +{ + VIFContext *s = ctx->priv; + return ff_framesync_activate(&s->fs); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + VIFContext *s = ctx->priv; + + if (s->nb_frames > 0) { + for (int i = 0; i < 4; i++) + av_log(ctx, AV_LOG_INFO, "VIF scale=%d average:%f min:%f: max:%f\n", + i, s->vif_sum[i] / s->nb_frames, s->vif_min[i], s->vif_max[i]); + } + + for (int i = 0; i < 13; i++) + av_freep(&s->data_buf[i]); + + av_freep(&s->ref_data); + av_freep(&s->main_data); + + for (int i = 0; i < s->nb_threads && s->temp; i++) + av_freep(&s->temp[i]); + + av_freep(&s->temp); + + ff_framesync_uninit(&s->fs); +} + +static const AVFilterPad vif_inputs[] = { + { + .name = "main", + .type = AVMEDIA_TYPE_VIDEO, + },{ + .name = "reference", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_input_ref, + }, + { NULL } +}; + +static const AVFilterPad vif_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL } +}; + +AVFilter ff_vf_vif = { + .name = "vif", + .description = NULL_IF_CONFIG_SMALL("Calculate the VIF between two video streams."), + .uninit = uninit, + .query_formats = query_formats, + .priv_size = sizeof(VIFContext), + .priv_class = &vif_class, + .activate = activate, + .inputs = vif_inputs, + .outputs = vif_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, +}; diff --git a/libavfilter/vf_vignette.c b/libavfilter/vf_vignette.c index 47b59e5ba..ecb04a964 100644 --- a/libavfilter/vf_vignette.c +++ b/libavfilter/vf_vignette.c @@ -155,9 +155,6 @@ static double get_natural_factor(const VignetteContext *s, int x, int y) } } -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) - static void update_context(VignetteContext *s, AVFilterLink *inlink, AVFrame *frame) { int x, y; diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 3194295f5..5d5770745 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -489,7 +489,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) static int query_formats(AVFilterContext *ctx) { int ret; - AVFilterFormats *in_fmts, *out_fmts; static const enum AVPixelFormat in_pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12, @@ -505,16 +504,12 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_NONE }; - in_fmts = ff_make_format_list(in_pix_fmts); - out_fmts = ff_make_format_list(out_pix_fmts); - ret = ff_formats_ref(in_fmts, &ctx->inputs[0]->out_formats); + ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), + &ctx->inputs[0]->outcfg.formats); if (ret < 0) return ret; - ret = ff_formats_ref(out_fmts, &ctx->outputs[0]->in_formats); - if (ret < 0) - return ret; - - return 0; + return ff_formats_ref(ff_make_format_list(out_pix_fmts), + &ctx->outputs[0]->incfg.formats); } static av_cold void vpp_uninit(AVFilterContext *ctx) diff --git a/libavfilter/vf_w3fdif.c b/libavfilter/vf_w3fdif.c index 5d64dbd95..1a64b2b95 100644 --- a/libavfilter/vf_w3fdif.c +++ b/libavfilter/vf_w3fdif.c @@ -34,6 +34,8 @@ typedef struct W3FDIFContext { const AVClass *class; int filter; ///< 0 is simple, 1 is more complex + int mode; ///< 0 is frame, 1 is field + int parity; ///< frame field parity int deint; ///< which frames to deinterlace int linesize[4]; ///< bytes of pixel data per line for each plane int planeheight[4]; ///< height of each plane @@ -49,13 +51,20 @@ typedef struct W3FDIFContext { } W3FDIFContext; #define OFFSET(x) offsetof(W3FDIFContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM #define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, 0, 0, FLAGS, unit } static const AVOption w3fdif_options[] = { { "filter", "specify the filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "filter" }, CONST("simple", NULL, 0, "filter"), CONST("complex", NULL, 1, "filter"), + { "mode", "specify the interlacing mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "mode"}, + CONST("frame", "send one frame for each frame", 0, "mode"), + CONST("field", "send one frame for each field", 1, "mode"), + { "parity", "specify the assumed picture field parity", OFFSET(parity), AV_OPT_TYPE_INT, {.i64=-1}, -1, 1, FLAGS, "parity" }, + CONST("tff", "assume top field first", 0, "parity"), + CONST("bff", "assume bottom field first", 1, "parity"), + CONST("auto", "auto detect parity", -1, "parity"), { "deint", "specify which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "deint" }, CONST("all", "deinterlace all frames", 0, "deint"), CONST("interlaced", "only deinterlace frames marked as interlaced", 1, "deint"), @@ -76,11 +85,15 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GRAY8, + AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, - AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, @@ -346,17 +359,16 @@ static const int16_t coef_hf[2][5] = {{ -2048, 4096, -2048, 0, 0}, typedef struct ThreadData { AVFrame *out, *cur, *adj; - int plane; } ThreadData; -static int deinterlace_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +static int deinterlace_plane_slice(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs, int plane) { W3FDIFContext *s = ctx->priv; ThreadData *td = arg; AVFrame *out = td->out; AVFrame *cur = td->cur; AVFrame *adj = td->adj; - const int plane = td->plane; const int filter = s->filter; uint8_t *in_line, *in_lines_cur[5], *in_lines_adj[5]; uint8_t *out_line, *out_pixel; @@ -372,10 +384,13 @@ static int deinterlace_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_ const int start = (height * jobnr) / nb_jobs; const int end = (height * (jobnr+1)) / nb_jobs; const int max = s->max; + const int interlaced = cur->interlaced_frame; + const int tff = s->field == (s->parity == -1 ? interlaced ? cur->top_field_first : 1 : + s->parity ^ 1); int j, y_in, y_out; /* copy unchanged the lines of the field */ - y_out = start + ((s->field == cur->top_field_first) ^ (start & 1)); + y_out = start + (tff ^ (start & 1)); in_line = cur_data + (y_out * cur_line_stride); out_line = dst_data + (y_out * dst_line_stride); @@ -388,7 +403,7 @@ static int deinterlace_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_ } /* interpolate other lines of the field */ - y_out = start + ((s->field != cur->top_field_first) ^ (start & 1)); + y_out = start + ((!tff) ^ (start & 1)); out_line = dst_data + (y_out * dst_line_stride); @@ -454,13 +469,23 @@ static int deinterlace_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_ return 0; } +static int deinterlace_slice(AVFilterContext *ctx, void *arg, + int jobnr, int nb_jobs) +{ + W3FDIFContext *s = ctx->priv; + + for (int p = 0; p < s->nb_planes; p++) + deinterlace_plane_slice(ctx, arg, jobnr, nb_jobs, p); + + return 0; +} + static int filter(AVFilterContext *ctx, int is_second) { W3FDIFContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; AVFrame *out, *adj; ThreadData td; - int plane; out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) @@ -484,12 +509,10 @@ static int filter(AVFilterContext *ctx, int is_second) adj = s->field ? s->next : s->prev; td.out = out; td.cur = s->cur; td.adj = adj; - for (plane = 0; plane < s->nb_planes; plane++) { - td.plane = plane; - ctx->internal->execute(ctx, deinterlace_slice, &td, NULL, FFMIN(s->planeheight[plane], s->nb_threads)); - } + ctx->internal->execute(ctx, deinterlace_slice, &td, NULL, FFMIN(s->planeheight[1], s->nb_threads)); - s->field = !s->field; + if (s->mode) + s->field = !s->field; return ff_filter_frame(outlink, out); } @@ -526,7 +549,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) return 0; ret = filter(ctx, 0); - if (ret < 0) + if (ret < 0 || s->mode == 0) return ret; return filter(ctx, 1); @@ -602,4 +625,5 @@ AVFilter ff_vf_w3fdif = { .inputs = w3fdif_inputs, .outputs = w3fdif_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, }; diff --git a/libavfilter/vf_waveform.c b/libavfilter/vf_waveform.c index b2c5b46d8..8191da279 100644 --- a/libavfilter/vf_waveform.c +++ b/libavfilter/vf_waveform.c @@ -303,13 +303,6 @@ static const enum AVPixelFormat out_gray12_lowpass_pix_fmts[] = { AV_PIX_FMT_NONE }; -static const enum AVPixelFormat flat_pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10, - AV_PIX_FMT_YUV444P12, - AV_PIX_FMT_NONE -}; - static int query_formats(AVFilterContext *ctx) { WaveformContext *s = ctx->priv; @@ -319,8 +312,8 @@ static int query_formats(AVFilterContext *ctx) AVFilterFormats *avff, *avff2; int depth, depth2, rgb, i, ret, ncomp, ncomp2; - if (!ctx->inputs[0]->in_formats || - !ctx->inputs[0]->in_formats->nb_formats) { + if (!ctx->inputs[0]->incfg.formats || + !ctx->inputs[0]->incfg.formats->nb_formats) { return AVERROR(EAGAIN); } @@ -336,13 +329,13 @@ static int query_formats(AVFilterContext *ctx) default: return AVERROR_BUG; } - if (!ctx->inputs[0]->out_formats) { - if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0) + if (!ctx->inputs[0]->outcfg.formats) { + if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0) return ret; } - avff = ctx->inputs[0]->in_formats; - avff2 = ctx->inputs[0]->out_formats; + avff = ctx->inputs[0]->incfg.formats; + avff2 = ctx->inputs[0]->outcfg.formats; desc = av_pix_fmt_desc_get(avff->formats[0]); desc2 = av_pix_fmt_desc_get(avff2->formats[0]); ncomp = desc->nb_components; @@ -385,7 +378,7 @@ static int query_formats(AVFilterContext *ctx) out_pix_fmts = out_yuv12_lowpass_pix_fmts; else return AVERROR(EAGAIN); - if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0) + if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/vf_weave.c b/libavfilter/vf_weave.c index 8951b0909..6139844b2 100644 --- a/libavfilter/vf_weave.c +++ b/libavfilter/vf_weave.c @@ -54,18 +54,11 @@ static int query_formats(AVFilterContext *ctx) AVFilterFormats *formats = NULL; int ret; - for (int fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - - if (!(desc->flags & AV_PIX_FMT_FLAG_PAL) && - !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { - if ((ret = ff_add_format(&formats, fmt)) < 0) { - ff_formats_unref(&formats); - return ret; - } - } - } - + ret = ff_formats_pixdesc_filter(&formats, 0, + AV_PIX_FMT_FLAG_PAL | + AV_PIX_FMT_FLAG_HWACCEL); + if (ret < 0) + return ret; return ff_set_common_formats(ctx, formats); } @@ -97,15 +90,51 @@ static int config_props_output(AVFilterLink *outlink) return 0; } +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +static int weave_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + AVFilterLink *inlink = ctx->inputs[0]; + WeaveContext *s = ctx->priv; + ThreadData *td = arg; + AVFrame *in = td->in; + AVFrame *out = td->out; + + const int weave = (s->double_weave && !(inlink->frame_count_out & 1)); + const int field1 = weave ? s->first_field : (!s->first_field); + const int field2 = weave ? (!s->first_field) : s->first_field; + + for (int i = 0; i < s->nb_planes; i++) { + const int height = s->planeheight[i]; + const int start = (height * jobnr) / nb_jobs; + const int end = (height * (jobnr+1)) / nb_jobs; + + av_image_copy_plane(out->data[i] + out->linesize[i] * field1 + + out->linesize[i] * start * 2, + out->linesize[i] * 2, + in->data[i] + start * in->linesize[i], + in->linesize[i], + s->linesize[i], end - start); + av_image_copy_plane(out->data[i] + out->linesize[i] * field2 + + out->linesize[i] * start * 2, + out->linesize[i] * 2, + s->prev->data[i] + start * s->prev->linesize[i], + s->prev->linesize[i], + s->linesize[i], end - start); + } + + return 0; +} + static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; WeaveContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; + ThreadData td; AVFrame *out; - int i; - int weave; - int field1, field2; if (!s->prev) { s->prev = in; @@ -120,19 +149,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } av_frame_copy_props(out, in); - weave = (s->double_weave && !(inlink->frame_count_out & 1)); - field1 = weave ? s->first_field : (!s->first_field); - field2 = weave ? (!s->first_field) : s->first_field; - for (i = 0; i < s->nb_planes; i++) { - av_image_copy_plane(out->data[i] + out->linesize[i] * field1, - out->linesize[i] * 2, - in->data[i], in->linesize[i], - s->linesize[i], s->planeheight[i]); - av_image_copy_plane(out->data[i] + out->linesize[i] * field2, - out->linesize[i] * 2, - s->prev->data[i], s->prev->linesize[i], - s->linesize[i], s->planeheight[i]); - } + td.out = out, td.in = in; + ctx->internal->execute(ctx, weave_slice, &td, NULL, FFMIN(s->planeheight[1], + ff_filter_get_nb_threads(ctx))); out->pts = s->double_weave ? s->prev->pts : in->pts / 2; out->interlaced_frame = 1; @@ -180,6 +199,7 @@ AVFilter ff_vf_weave = { .uninit = uninit, .inputs = weave_inputs, .outputs = weave_outputs, + .flags = AVFILTER_FLAG_SLICE_THREADS, }; static av_cold int init(AVFilterContext *ctx) @@ -205,4 +225,5 @@ AVFilter ff_vf_doubleweave = { .uninit = uninit, .inputs = weave_inputs, .outputs = weave_outputs, + .flags = AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/vf_xfade.c b/libavfilter/vf_xfade.c index 1b5ebef9e..cb4fae21d 100644 --- a/libavfilter/vf_xfade.c +++ b/libavfilter/vf_xfade.c @@ -65,6 +65,14 @@ enum XFadeTransitions { HRSLICE, VUSLICE, VDSLICE, + HBLUR, + FADEGRAYS, + WIPETL, + WIPETR, + WIPEBL, + WIPEBR, + SQUEEZEH, + SQUEEZEV, NB_TRANSITIONS, }; @@ -78,6 +86,7 @@ typedef struct XFadeContext { int nb_planes; int depth; + int is_rgb; int64_t duration_pts; int64_t offset_pts; @@ -182,6 +191,14 @@ static const AVOption xfade_options[] = { { "hrslice", "hr slice transition", 0, AV_OPT_TYPE_CONST, {.i64=HRSLICE}, 0, 0, FLAGS, "transition" }, { "vuslice", "vu slice transition", 0, AV_OPT_TYPE_CONST, {.i64=VUSLICE}, 0, 0, FLAGS, "transition" }, { "vdslice", "vd slice transition", 0, AV_OPT_TYPE_CONST, {.i64=VDSLICE}, 0, 0, FLAGS, "transition" }, + { "hblur", "hblur transition", 0, AV_OPT_TYPE_CONST, {.i64=HBLUR}, 0, 0, FLAGS, "transition" }, + { "fadegrays", "fadegrays transition", 0, AV_OPT_TYPE_CONST, {.i64=FADEGRAYS}, 0, 0, FLAGS, "transition" }, + { "wipetl", "wipe tl transition", 0, AV_OPT_TYPE_CONST, {.i64=WIPETL}, 0, 0, FLAGS, "transition" }, + { "wipetr", "wipe tr transition", 0, AV_OPT_TYPE_CONST, {.i64=WIPETR}, 0, 0, FLAGS, "transition" }, + { "wipebl", "wipe bl transition", 0, AV_OPT_TYPE_CONST, {.i64=WIPEBL}, 0, 0, FLAGS, "transition" }, + { "wipebr", "wipe br transition", 0, AV_OPT_TYPE_CONST, {.i64=WIPEBR}, 0, 0, FLAGS, "transition" }, + { "squeezeh", "squeeze h transition", 0, AV_OPT_TYPE_CONST, {.i64=SQUEEZEH}, 0, 0, FLAGS, "transition" }, + { "squeezev", "squeeze v transition", 0, AV_OPT_TYPE_CONST, {.i64=SQUEEZEV}, 0, 0, FLAGS, "transition" }, { "duration", "set cross fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=1000000}, 0, 60000000, FLAGS }, { "offset", "set cross fade start relative to first input stream", OFFSET(offset), AV_OPT_TYPE_DURATION, {.i64=0}, INT64_MIN, INT64_MAX, FLAGS }, { "expr", "set expression for custom transition", OFFSET(custom_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, @@ -1299,6 +1316,322 @@ static void vdslice##name##_transition(AVFilterContext *ctx, VDSLICE_TRANSITION(8, uint8_t, 1) VDSLICE_TRANSITION(16, uint16_t, 2) +#define HBLUR_TRANSITION(name, type, div) \ +static void hblur##name##_transition(AVFilterContext *ctx, \ + const AVFrame *a, const AVFrame *b, AVFrame *out, \ + float progress, \ + int slice_start, int slice_end, int jobnr) \ +{ \ + XFadeContext *s = ctx->priv; \ + const int width = out->width; \ + const float prog = progress <= 0.5f ? progress * 2.f : (1.f - progress) * 2.f; \ + const int size = 1 + (width / 2) * prog; \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + for (int p = 0; p < s->nb_planes; p++) { \ + const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ + const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ + type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ + float sum0 = 0.f; \ + float sum1 = 0.f; \ + float cnt = size; \ + \ + for (int x = 0; x < size; x++) { \ + sum0 += xf0[x]; \ + sum1 += xf1[x]; \ + } \ + \ + for (int x = 0; x < width; x++) { \ + dst[x] = mix(sum0 / cnt, sum1 / cnt, progress); \ + \ + if (x + size < width) { \ + sum0 += xf0[x + size] - xf0[x]; \ + sum1 += xf1[x + size] - xf1[x]; \ + } else { \ + sum0 -= xf0[x]; \ + sum1 -= xf1[x]; \ + cnt--; \ + } \ + } \ + } \ + } \ +} + +HBLUR_TRANSITION(8, uint8_t, 1) +HBLUR_TRANSITION(16, uint16_t, 2) + +#define FADEGRAYS_TRANSITION(name, type, div) \ +static void fadegrays##name##_transition(AVFilterContext *ctx, \ + const AVFrame *a, const AVFrame *b, AVFrame *out, \ + float progress, \ + int slice_start, int slice_end, int jobnr) \ +{ \ + XFadeContext *s = ctx->priv; \ + const int width = out->width; \ + const int is_rgb = s->is_rgb; \ + const int mid = (s->max_value + 1) / 2; \ + const float phase = 0.2f; \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + for (int x = 0; x < width; x++) { \ + int bg[2][4]; \ + if (is_rgb) { \ + for (int p = 0; p < s->nb_planes; p++) { \ + const type *xf0 = (const type *)(a->data[p] + \ + y * a->linesize[p]); \ + const type *xf1 = (const type *)(b->data[p] + \ + y * b->linesize[p]); \ + if (p == 3) { \ + bg[0][3] = xf0[x]; \ + bg[1][3] = xf1[x]; \ + } else { \ + bg[0][0] += xf0[x]; \ + bg[1][0] += xf1[x]; \ + } \ + } \ + bg[0][0] = bg[0][0] / 3; \ + bg[1][0] = bg[1][0] / 3; \ + bg[0][1] = bg[0][2] = bg[0][0]; \ + bg[1][1] = bg[1][2] = bg[1][0]; \ + } else { \ + const type *yf0 = (const type *)(a->data[0] + \ + y * a->linesize[0]); \ + const type *yf1 = (const type *)(b->data[0] + \ + y * a->linesize[0]); \ + bg[0][0] = yf0[x]; \ + bg[1][0] = yf1[x]; \ + if (s->nb_planes == 4) { \ + const type *af0 = (const type *)(a->data[3] + \ + y * a->linesize[3]); \ + const type *af1 = (const type *)(b->data[3] + \ + y * a->linesize[3]); \ + bg[0][3] = af0[x]; \ + bg[1][3] = af1[x]; \ + } \ + bg[0][1] = bg[1][1] = mid; \ + bg[0][2] = bg[1][2] = mid; \ + } \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ + const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ + type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ + \ + dst[x] = mix(mix(xf0[x], bg[0][p], \ + smoothstep(1.f-phase, 1.f, progress)), \ + mix(bg[1][p], xf1[x], smoothstep(phase, 1.f, progress)), \ + progress); \ + } \ + } \ + } \ +} + +FADEGRAYS_TRANSITION(8, uint8_t, 1) +FADEGRAYS_TRANSITION(16, uint16_t, 2) + +#define WIPETL_TRANSITION(name, type, div) \ +static void wipetl##name##_transition(AVFilterContext *ctx, \ + const AVFrame *a, const AVFrame *b, AVFrame *out, \ + float progress, \ + int slice_start, int slice_end, int jobnr) \ +{ \ + XFadeContext *s = ctx->priv; \ + const int height = slice_end - slice_start; \ + const int zw = out->width * progress; \ + const int zh = out->height * progress; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ + const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ + type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ + \ + for (int y = 0; y < height; y++) { \ + for (int x = 0; x < out->width; x++) { \ + dst[x] = slice_start + y <= zh && \ + x <= zw ? xf0[x] : xf1[x]; \ + } \ + \ + dst += out->linesize[p] / div; \ + xf0 += a->linesize[p] / div; \ + xf1 += b->linesize[p] / div; \ + } \ + } \ +} + +WIPETL_TRANSITION(8, uint8_t, 1) +WIPETL_TRANSITION(16, uint16_t, 2) + +#define WIPETR_TRANSITION(name, type, div) \ +static void wipetr##name##_transition(AVFilterContext *ctx, \ + const AVFrame *a, const AVFrame *b, AVFrame *out, \ + float progress, \ + int slice_start, int slice_end, int jobnr) \ +{ \ + XFadeContext *s = ctx->priv; \ + const int height = slice_end - slice_start; \ + const int zw = out->width * (1.f - progress); \ + const int zh = out->height * progress; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ + const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ + type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ + \ + for (int y = 0; y < height; y++) { \ + for (int x = 0; x < out->width; x++) { \ + dst[x] = slice_start + y <= zh && \ + x > zw ? xf0[x] : xf1[x]; \ + } \ + \ + dst += out->linesize[p] / div; \ + xf0 += a->linesize[p] / div; \ + xf1 += b->linesize[p] / div; \ + } \ + } \ +} + +WIPETR_TRANSITION(8, uint8_t, 1) +WIPETR_TRANSITION(16, uint16_t, 2) + +#define WIPEBL_TRANSITION(name, type, div) \ +static void wipebl##name##_transition(AVFilterContext *ctx, \ + const AVFrame *a, const AVFrame *b, AVFrame *out, \ + float progress, \ + int slice_start, int slice_end, int jobnr) \ +{ \ + XFadeContext *s = ctx->priv; \ + const int height = slice_end - slice_start; \ + const int zw = out->width * progress; \ + const int zh = out->height * (1.f - progress); \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ + const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ + type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ + \ + for (int y = 0; y < height; y++) { \ + for (int x = 0; x < out->width; x++) { \ + dst[x] = slice_start + y > zh && \ + x <= zw ? xf0[x] : xf1[x]; \ + } \ + \ + dst += out->linesize[p] / div; \ + xf0 += a->linesize[p] / div; \ + xf1 += b->linesize[p] / div; \ + } \ + } \ +} + +WIPEBL_TRANSITION(8, uint8_t, 1) +WIPEBL_TRANSITION(16, uint16_t, 2) + +#define WIPEBR_TRANSITION(name, type, div) \ +static void wipebr##name##_transition(AVFilterContext *ctx, \ + const AVFrame *a, const AVFrame *b, AVFrame *out, \ + float progress, \ + int slice_start, int slice_end, int jobnr) \ +{ \ + XFadeContext *s = ctx->priv; \ + const int height = slice_end - slice_start; \ + const int zh = out->height * (1.f - progress); \ + const int zw = out->width * (1.f - progress); \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ + const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ + type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ + \ + for (int y = 0; y < height; y++) { \ + for (int x = 0; x < out->width; x++) { \ + dst[x] = slice_start + y > zh && \ + x > zw ? xf0[x] : xf1[x]; \ + } \ + \ + dst += out->linesize[p] / div; \ + xf0 += a->linesize[p] / div; \ + xf1 += b->linesize[p] / div; \ + } \ + } \ +} + +WIPEBR_TRANSITION(8, uint8_t, 1) +WIPEBR_TRANSITION(16, uint16_t, 2) + +#define SQUEEZEH_TRANSITION(name, type, div) \ +static void squeezeh##name##_transition(AVFilterContext *ctx, \ + const AVFrame *a, const AVFrame *b, AVFrame *out, \ + float progress, \ + int slice_start, int slice_end, int jobnr) \ +{ \ + XFadeContext *s = ctx->priv; \ + const float h = out->height; \ + const int height = slice_end - slice_start; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ + type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ + \ + for (int y = 0; y < height; y++) { \ + const float z = .5f + ((slice_start + y) / h - .5f) / progress; \ + \ + if (z < 0.f || z > 1.f) { \ + for (int x = 0; x < out->width; x++) \ + dst[x] = xf1[x]; \ + } else { \ + const int yy = lrintf(z * (h - 1.f)); \ + const type *xf0 = (const type *)(a->data[p] + yy * a->linesize[p]); \ + \ + for (int x = 0; x < out->width; x++) \ + dst[x] = xf0[x]; \ + } \ + \ + dst += out->linesize[p] / div; \ + xf1 += b->linesize[p] / div; \ + } \ + } \ +} + +SQUEEZEH_TRANSITION(8, uint8_t, 1) +SQUEEZEH_TRANSITION(16, uint16_t, 2) + +#define SQUEEZEV_TRANSITION(name, type, div) \ +static void squeezev##name##_transition(AVFilterContext *ctx, \ + const AVFrame *a, const AVFrame *b, AVFrame *out, \ + float progress, \ + int slice_start, int slice_end, int jobnr) \ +{ \ + XFadeContext *s = ctx->priv; \ + const float w = out->width; \ + const int height = slice_end - slice_start; \ + \ + for (int p = 0; p < s->nb_planes; p++) { \ + const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ + const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ + type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ + \ + for (int y = 0; y < height; y++) { \ + for (int x = 0; x < out->width; x++) { \ + const float z = .5f + (x / w - .5f) / progress; \ + \ + if (z < 0.f || z > 1.f) { \ + dst[x] = xf1[x]; \ + } else { \ + const int xx = lrintf(z * (w - 1.f)); \ + \ + dst[x] = xf0[xx]; \ + } \ + } \ + \ + dst += out->linesize[p] / div; \ + xf0 += a->linesize[p] / div; \ + xf1 += b->linesize[p] / div; \ + } \ + } \ +} + +SQUEEZEV_TRANSITION(8, uint8_t, 1) +SQUEEZEV_TRANSITION(16, uint16_t, 2) + static inline double getpix(void *priv, double x, double y, int plane, int nb) { XFadeContext *s = priv; @@ -1340,7 +1673,6 @@ static int config_output(AVFilterLink *outlink) AVFilterLink *inlink1 = ctx->inputs[1]; XFadeContext *s = ctx->priv; const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink0->format); - int is_rgb; if (inlink0->format != inlink1->format) { av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n"); @@ -1365,6 +1697,22 @@ static int config_output(AVFilterLink *outlink) return AVERROR(EINVAL); } + if (!inlink0->frame_rate.num || !inlink0->frame_rate.den) { + av_log(ctx, AV_LOG_ERROR, "The inputs needs to be a constant frame rate; " + "current rate of %d/%d is invalid\n", inlink0->frame_rate.num, inlink0->frame_rate.den); + return AVERROR(EINVAL); + } + + if (inlink0->frame_rate.num != inlink1->frame_rate.num || + inlink0->frame_rate.den != inlink1->frame_rate.den) { + av_log(ctx, AV_LOG_ERROR, "First input link %s frame rate " + "(%d/%d) do not match the corresponding " + "second input link %s frame rate (%d/%d)\n", + ctx->input_pads[0].name, inlink0->frame_rate.num, inlink0->frame_rate.den, + ctx->input_pads[1].name, inlink1->frame_rate.num, inlink1->frame_rate.den); + return AVERROR(EINVAL); + } + outlink->w = inlink0->w; outlink->h = inlink0->h; outlink->time_base = inlink0->time_base; @@ -1372,14 +1720,14 @@ static int config_output(AVFilterLink *outlink) outlink->frame_rate = inlink0->frame_rate; s->depth = pix_desc->comp[0].depth; - is_rgb = !!(pix_desc->flags & AV_PIX_FMT_FLAG_RGB); + s->is_rgb = !!(pix_desc->flags & AV_PIX_FMT_FLAG_RGB); s->nb_planes = av_pix_fmt_count_planes(inlink0->format); s->max_value = (1 << s->depth) - 1; s->black[0] = 0; - s->black[1] = s->black[2] = is_rgb ? 0 : s->max_value / 2; + s->black[1] = s->black[2] = s->is_rgb ? 0 : s->max_value / 2; s->black[3] = s->max_value; s->white[0] = s->white[3] = s->max_value; - s->white[1] = s->white[2] = is_rgb ? s->max_value : s->max_value / 2; + s->white[1] = s->white[2] = s->is_rgb ? s->max_value : s->max_value / 2; s->first_pts = s->last_pts = s->pts = AV_NOPTS_VALUE; @@ -1425,6 +1773,14 @@ static int config_output(AVFilterLink *outlink) case HRSLICE: s->transitionf = s->depth <= 8 ? hrslice8_transition : hrslice16_transition; break; case VUSLICE: s->transitionf = s->depth <= 8 ? vuslice8_transition : vuslice16_transition; break; case VDSLICE: s->transitionf = s->depth <= 8 ? vdslice8_transition : vdslice16_transition; break; + case HBLUR: s->transitionf = s->depth <= 8 ? hblur8_transition : hblur16_transition; break; + case FADEGRAYS: s->transitionf = s->depth <= 8 ? fadegrays8_transition : fadegrays16_transition; break; + case WIPETL: s->transitionf = s->depth <= 8 ? wipetl8_transition : wipetl16_transition; break; + case WIPETR: s->transitionf = s->depth <= 8 ? wipetr8_transition : wipetr16_transition; break; + case WIPEBL: s->transitionf = s->depth <= 8 ? wipebl8_transition : wipebl16_transition; break; + case WIPEBR: s->transitionf = s->depth <= 8 ? wipebr8_transition : wipebr16_transition; break; + case SQUEEZEH: s->transitionf = s->depth <= 8 ? squeezeh8_transition : squeezeh16_transition; break; + case SQUEEZEV: s->transitionf = s->depth <= 8 ? squeezev8_transition : squeezev16_transition; break; } if (s->transition == CUSTOM) { @@ -1474,6 +1830,7 @@ static int xfade_frame(AVFilterContext *ctx, AVFrame *a, AVFrame *b) out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) return AVERROR(ENOMEM); + av_frame_copy_props(out, a); td.xf[0] = a, td.xf[1] = b, td.out = out, td.progress = progress; ctx->internal->execute(ctx, xfade_slice, &td, NULL, FFMIN(outlink->h, ff_filter_get_nb_threads(ctx))); @@ -1494,6 +1851,11 @@ static int xfade_activate(AVFilterContext *ctx) FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx); if (s->xfade_is_over) { + if (!s->eof[0]) { + ret = ff_inlink_consume_frame(ctx->inputs[0], &in); + if (ret > 0) + av_frame_free(&in); + } ret = ff_inlink_consume_frame(ctx->inputs[1], &in); if (ret < 0) { return ret; @@ -1504,10 +1866,9 @@ static int xfade_activate(AVFilterContext *ctx) ff_outlink_set_status(outlink, status, s->pts); return 0; } else if (!ret) { - if (ff_outlink_frame_wanted(outlink)) { + if (ff_outlink_frame_wanted(outlink)) ff_inlink_request_frame(ctx->inputs[1]); - return 0; - } + return 0; } } @@ -1557,14 +1918,17 @@ static int xfade_activate(AVFilterContext *ctx) if (!s->eof[1] && ff_outlink_get_status(ctx->inputs[1])) { s->eof[1] = 1; } - if (!s->eof[0] && !s->xf[0]) + if (!s->eof[0] && !s->xf[0] && ff_inlink_queued_frames(ctx->inputs[0]) == 0) ff_inlink_request_frame(ctx->inputs[0]); - if (!s->eof[1] && (s->need_second || s->eof[0])) + if (!s->eof[1] && (s->need_second || s->eof[0]) && ff_inlink_queued_frames(ctx->inputs[1]) == 0) ff_inlink_request_frame(ctx->inputs[1]); if (s->eof[0] && s->eof[1] && ( - ff_inlink_queued_frames(ctx->inputs[0]) <= 0 || - ff_inlink_queued_frames(ctx->inputs[1]) <= 0)) + ff_inlink_queued_frames(ctx->inputs[0]) <= 0 && + ff_inlink_queued_frames(ctx->inputs[1]) <= 0)) { ff_outlink_set_status(outlink, AVERROR_EOF, AV_NOPTS_VALUE); + } else if (s->xfade_is_over) { + ff_filter_set_ready(ctx, 100); + } return 0; } diff --git a/libavfilter/vf_xmedian.c b/libavfilter/vf_xmedian.c index 15857d6f1..8b6dd6970 100644 --- a/libavfilter/vf_xmedian.c +++ b/libavfilter/vf_xmedian.c @@ -244,14 +244,20 @@ static int process_frame(FFFrameSync *fs) return ret; } - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (ctx->is_disabled) { + out = av_frame_clone(in[0]); + } else { + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + } if (!out) return AVERROR(ENOMEM); out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base); - td.in = in; - td.out = out; - ctx->internal->execute(ctx, s->median_frames, &td, NULL, FFMIN(s->height[1], ff_filter_get_nb_threads(ctx))); + if (!ctx->is_disabled) { + td.in = in; + td.out = out; + ctx->internal->execute(ctx, s->median_frames, &td, NULL, FFMIN(s->height[1], ff_filter_get_nb_threads(ctx))); + } return ff_filter_frame(outlink, out); } @@ -316,7 +322,7 @@ static int config_output(AVFilterLink *outlink) in[i].time_base = inlink->time_base; in[i].sync = 1; in[i].before = EXT_STOP; - in[i].after = EXT_STOP; + in[i].after = EXT_INFINITY; } ret = ff_framesync_configure(&s->fs); @@ -344,13 +350,32 @@ static int activate(AVFilterContext *ctx) return ff_framesync_activate(&s->fs); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + XMedianContext *s = ctx->priv; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + if (s->nb_inputs & 1) + s->index = s->radius * 2.f * s->percentile; + else + s->index = av_clip(s->radius * 2.f * s->percentile, 1, s->nb_inputs - 1); + + return 0; +} + #define OFFSET(x) offsetof(XMedianContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM +#define TFLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM static const AVOption xmedian_options[] = { { "inputs", "set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=3}, 3, 255, .flags = FLAGS }, - { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, .flags = FLAGS }, - { "percentile", "set percentile", OFFSET(percentile),AV_OPT_TYPE_FLOAT,{.dbl=0.5}, 0, 1, .flags = FLAGS }, + { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, .flags =TFLAGS }, + { "percentile", "set percentile", OFFSET(percentile),AV_OPT_TYPE_FLOAT,{.dbl=0.5}, 0, 1, .flags =TFLAGS }, { NULL }, }; @@ -364,7 +389,7 @@ static const AVFilterPad outputs[] = { }; #if CONFIG_XMEDIAN_FILTER -AVFILTER_DEFINE_CLASS(xmedian); +FRAMESYNC_DEFINE_CLASS(xmedian, XMedianContext, fs); AVFilter ff_vf_xmedian = { .name = "xmedian", @@ -373,10 +398,13 @@ AVFilter ff_vf_xmedian = { .priv_class = &xmedian_class, .query_formats = query_formats, .outputs = outputs, + .preinit = xmedian_framesync_preinit, .init = init, .uninit = uninit, .activate = activate, - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_SLICE_THREADS, + .flags = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_SLICE_THREADS | + AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, + .process_command = process_command, }; #endif /* CONFIG_XMEDIAN_FILTER */ @@ -422,8 +450,8 @@ static int tmedian_filter_frame(AVFilterLink *inlink, AVFrame *in) static const AVOption tmedian_options[] = { { "radius", "set median filter radius", OFFSET(radius), AV_OPT_TYPE_INT, {.i64=1}, 1, 127, .flags = FLAGS }, - { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, .flags = FLAGS }, - { "percentile", "set percentile", OFFSET(percentile), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, .flags = FLAGS }, + { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, .flags =TFLAGS }, + { "percentile", "set percentile", OFFSET(percentile), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, .flags =TFLAGS }, { NULL }, }; @@ -458,6 +486,7 @@ AVFilter ff_vf_tmedian = { .init = init, .uninit = uninit, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, + .process_command = process_command, }; #endif /* CONFIG_TMEDIAN_FILTER */ diff --git a/libavfilter/vf_yadif_cuda.c b/libavfilter/vf_yadif_cuda.c index c9eb1a229..3841c5f0d 100644 --- a/libavfilter/vf_yadif_cuda.c +++ b/libavfilter/vf_yadif_cuda.c @@ -216,10 +216,10 @@ static int deint_cuda_query_formats(AVFilterContext *ctx) int ret; if ((ret = ff_formats_ref(ff_make_format_list(pix_fmts), - &ctx->inputs[0]->out_formats)) < 0) + &ctx->inputs[0]->outcfg.formats)) < 0) return ret; if ((ret = ff_formats_ref(ff_make_format_list(pix_fmts), - &ctx->outputs[0]->in_formats)) < 0) + &ctx->outputs[0]->incfg.formats)) < 0) return ret; return 0; diff --git a/libavfilter/vf_yaepblur.c b/libavfilter/vf_yaepblur.c index 0fb7b84af..7c9aa7a1f 100644 --- a/libavfilter/vf_yaepblur.c +++ b/libavfilter/vf_yaepblur.c @@ -323,7 +323,7 @@ static const AVFilterPad yaep_outputs[] = { #define OFFSET(x) offsetof(YAEPContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM -static const AVOption yaep_options[] = { +static const AVOption yaepblur_options[] = { { "radius", "set window radius", OFFSET(radius), AV_OPT_TYPE_INT, {.i64=3}, 0, INT_MAX, .flags=FLAGS }, { "r" , "set window radius", OFFSET(radius), AV_OPT_TYPE_INT, {.i64=3}, 0, INT_MAX, .flags=FLAGS }, { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=1}, 0, 0xF, .flags=FLAGS }, @@ -333,13 +333,13 @@ static const AVOption yaep_options[] = { { NULL } }; -AVFILTER_DEFINE_CLASS(yaep); +AVFILTER_DEFINE_CLASS(yaepblur); AVFilter ff_vf_yaepblur = { .name = "yaepblur", .description = NULL_IF_CONFIG_SMALL("Yet another edge preserving blur filter."), .priv_size = sizeof(YAEPContext), - .priv_class = &yaep_class, + .priv_class = &yaepblur_class, .uninit = uninit, .query_formats = query_formats, .inputs = yaep_inputs, diff --git a/libavfilter/vf_zoompan.c b/libavfilter/vf_zoompan.c index 59c9b19ec..d9d53decf 100644 --- a/libavfilter/vf_zoompan.c +++ b/libavfilter/vf_zoompan.c @@ -38,7 +38,8 @@ static const char *const var_names[] = { "on", "duration", "pduration", - "time", + "in_time", "it", + "out_time", "time", "ot", "frame", "zoom", "pzoom", @@ -61,7 +62,8 @@ enum var_name { VAR_ON, VAR_DURATION, VAR_PDURATION, - VAR_TIME, + VAR_IN_TIME, VAR_IT, + VAR_TIME, VAR_OUT_TIME, VAR_OT, VAR_FRAME, VAR_ZOOM, VAR_PZOOM, @@ -155,6 +157,7 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va { ZPContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; + AVFilterLink *inlink = ctx->inputs[0]; int64_t pts = s->frame_count; int k, x, y, w, h, ret = 0; uint8_t *input[4]; @@ -165,7 +168,10 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va var_values[VAR_PY] = s->y; var_values[VAR_PZOOM] = s->prev_zoom; var_values[VAR_PDURATION] = s->prev_nb_frames; - var_values[VAR_TIME] = pts * av_q2d(outlink->time_base); + var_values[VAR_IN_TIME] = var_values[VAR_IT] = in->pts == AV_NOPTS_VALUE ? + NAN : in->pts * av_q2d(inlink->time_base); + var_values[VAR_OUT_TIME] = pts * av_q2d(outlink->time_base); + var_values[VAR_TIME] = var_values[VAR_OT] = var_values[VAR_OUT_TIME]; var_values[VAR_FRAME] = i; var_values[VAR_ON] = outlink->frame_count_in; diff --git a/libavfilter/vf_zscale.c b/libavfilter/vf_zscale.c index 023a5d10e..c18a161ab 100644 --- a/libavfilter/vf_zscale.c +++ b/libavfilter/vf_zscale.c @@ -101,6 +101,8 @@ typedef struct ZScaleContext { char *size_str; double nominal_peak_luminance; int approximate_gamma; + double param_a; + double param_b; char *w_expr; ///< width expression string char *h_expr; ///< height expression string @@ -187,10 +189,10 @@ static int query_formats(AVFilterContext *ctx) }; int ret; - ret = ff_formats_ref(ff_make_format_list(pixel_fmts), &ctx->inputs[0]->out_formats); + ret = ff_formats_ref(ff_make_format_list(pixel_fmts), &ctx->inputs[0]->outcfg.formats); if (ret < 0) return ret; - return ff_formats_ref(ff_make_format_list(pixel_fmts), &ctx->outputs[0]->in_formats); + return ff_formats_ref(ff_make_format_list(pixel_fmts), &ctx->outputs[0]->incfg.formats); } static int config_props(AVFilterLink *outlink) @@ -301,7 +303,7 @@ static int config_props(AVFilterLink *outlink) } else outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s sar:%d/%d -> w:%d h:%d fmt:%s sar:%d/%d\n", + av_log(ctx, AV_LOG_TRACE, "w:%d h:%d fmt:%s sar:%d/%d -> w:%d h:%d fmt:%s sar:%d/%d\n", inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format), inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den, outlink->w, outlink->h, av_get_pix_fmt_name(outlink->format), @@ -601,6 +603,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) s->params.resample_filter_uv = s->filter; s->params.nominal_peak_luminance = s->nominal_peak_luminance; s->params.allow_approximate_gamma = s->approximate_gamma; + s->params.filter_param_a = s->params.filter_param_a_uv = s->param_a; + s->params.filter_param_b = s->params.filter_param_b_uv = s->param_b; format_init(&s->src_format, in, desc, s->colorspace_in, s->primaries_in, s->trc_in, s->range_in, s->chromal_in); @@ -897,6 +901,9 @@ static const AVOption zscale_options[] = { { "cin", "set input chroma location", OFFSET(chromal_in), AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM, FLAGS, "chroma" }, { "npl", "set nominal peak luminance", OFFSET(nominal_peak_luminance), AV_OPT_TYPE_DOUBLE, {.dbl = NAN}, 0, DBL_MAX, FLAGS }, { "agamma", "allow approximate gamma", OFFSET(approximate_gamma), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS }, + { "param_a", "parameter A, which is parameter \"b\" for bicubic, " + "and the number of filter taps for lanczos", OFFSET(param_a), AV_OPT_TYPE_DOUBLE, {.dbl = NAN}, -DBL_MAX, DBL_MAX, FLAGS }, + { "param_b", "parameter B, which is parameter \"c\" for bicubic", OFFSET(param_b), AV_OPT_TYPE_DOUBLE, {.dbl = NAN}, -DBL_MAX, DBL_MAX, FLAGS }, { NULL } }; diff --git a/libavfilter/vif.h b/libavfilter/vif.h new file mode 100644 index 000000000..5b0d86da0 --- /dev/null +++ b/libavfilter/vif.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 Ronald S. Bultje + * Copyright (c) 2017 Ashish Pratap Singh + * + * 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 AVFILTER_VIF_H +#define AVFILTER_VIF_H + +#include "avfilter.h" + +int ff_compute_vif2(AVFilterContext *ctx, + const float *ref, const float *main, int w, int h, + int ref_stride, int main_stride, float *score, + float *data_buf[13], float **temp, int nb_threads); + +#endif /* AVFILTER_VIF_H */ diff --git a/libavfilter/vsrc_gradients.c b/libavfilter/vsrc_gradients.c index 984227017..b05ad5bf9 100644 --- a/libavfilter/vsrc_gradients.c +++ b/libavfilter/vsrc_gradients.c @@ -19,6 +19,7 @@ */ #include "avfilter.h" +#include "filters.h" #include "formats.h" #include "video.h" #include "internal.h" @@ -36,7 +37,9 @@ typedef struct GradientsContext { int w, h; int type; AVRational frame_rate; - uint64_t pts; + int64_t pts; + int64_t duration; ///< duration expressed in microseconds + float speed; uint8_t color_rgba[8][4]; int nb_colors; @@ -72,6 +75,9 @@ static const AVOption gradients_options[] = { {"nb_colors", "set the number of colors", OFFSET(nb_colors), AV_OPT_TYPE_INT, {.i64=2}, 2, 8, FLAGS }, {"n", "set the number of colors", OFFSET(nb_colors), AV_OPT_TYPE_INT, {.i64=2}, 2, 8, FLAGS }, {"seed", "set the seed", OFFSET(seed), AV_OPT_TYPE_INT64, {.i64=-1}, -1, UINT32_MAX, FLAGS }, + {"duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS },\ + {"d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS },\ + {"speed", "set gradients rotation speed", OFFSET(speed), AV_OPT_TYPE_FLOAT,{.dbl=0.01}, 0.00001, 1, FLAGS },\ {NULL}, }; @@ -95,20 +101,20 @@ static uint32_t lerp_color(uint8_t c0[4], uint8_t c1[4], float x) { const float y = 1.f - x; - return (lrint(c0[0] * y + c1[0] * x)) << 0 | - (lrint(c0[1] * y + c1[1] * x)) << 8 | - (lrint(c0[2] * y + c1[2] * x)) << 16 | - (lrint(c0[3] * y + c1[3] * x)) << 24; + return (lrintf(c0[0] * y + c1[0] * x)) << 0 | + (lrintf(c0[1] * y + c1[1] * x)) << 8 | + (lrintf(c0[2] * y + c1[2] * x)) << 16 | + (lrintf(c0[3] * y + c1[3] * x)) << 24; } static uint64_t lerp_color16(uint8_t c0[4], uint8_t c1[4], float x) { const float y = 1.f - x; - return (llrint((c0[0] * y + c1[0] * x) * 256)) << 0 | - (llrint((c0[1] * y + c1[1] * x) * 256)) << 16 | - (llrint((c0[2] * y + c1[2] * x) * 256)) << 32 | - (llrint((c0[3] * y + c1[3] * x) * 256)) << 48; + return (llrintf((c0[0] * y + c1[0] * x) * 256)) << 0 | + (llrintf((c0[1] * y + c1[1] * x) * 256)) << 16 | + (llrintf((c0[2] * y + c1[2] * x) * 256)) << 32 | + (llrintf((c0[3] * y + c1[3] * x) * 256)) << 48; } static uint32_t lerp_colors(uint8_t arr[3][4], int nb_colors, float step) @@ -181,7 +187,7 @@ static int draw_gradients_slice(AVFilterContext *ctx, void *arg, int job, int nb for (int y = start; y < end; y++) { for (int x = 0; x < width; x++) { float factor = project(s->fx0, s->fy0, s->fx1, s->fy1, x, y); - dst[x] = lerp_colors(s->color_rgba, s->nb_colors, factor);; + dst[x] = lerp_colors(s->color_rgba, s->nb_colors, factor); } dst += linesize; @@ -204,7 +210,7 @@ static int draw_gradients_slice16(AVFilterContext *ctx, void *arg, int job, int for (int y = start; y < end; y++) { for (int x = 0; x < width; x++) { float factor = project(s->fx0, s->fy0, s->fx1, s->fy1, x, y); - dst[x] = lerp_colors16(s->color_rgba, s->nb_colors, factor);; + dst[x] = lerp_colors16(s->color_rgba, s->nb_colors, factor); } dst += linesize; @@ -242,37 +248,51 @@ static int draw_gradients_slice16(AVFilterContext *ctx, void *arg, int job, int return 0; } -static int gradients_request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - AVFilterContext *ctx = outlink->src; GradientsContext *s = ctx->priv; - AVFrame *frame = ff_get_video_buffer(outlink, s->w, s->h); - float angle = fmodf(s->pts / 100.f, 2.f * M_PI); - const float w2 = s->w / 2.f; - const float h2 = s->h / 2.f; + AVFilterLink *outlink = ctx->outputs[0]; - s->fx0 = (s->x0 - w2) * cosf(angle) - (s->y0 - h2) * sinf(angle) + w2; - s->fy0 = (s->x0 - w2) * sinf(angle) + (s->y0 - h2) * cosf(angle) + h2; + if (s->duration >= 0 && + av_rescale_q(s->pts, outlink->time_base, AV_TIME_BASE_Q) >= s->duration) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->pts); + return 0; + } - s->fx1 = (s->x1 - w2) * cosf(angle) - (s->y1 - h2) * sinf(angle) + w2; - s->fy1 = (s->x1 - w2) * sinf(angle) + (s->y1 - h2) * cosf(angle) + h2; + if (ff_outlink_frame_wanted(outlink)) { + AVFrame *frame = ff_get_video_buffer(outlink, s->w, s->h); + float angle = fmodf(s->pts * s->speed, 2.f * M_PI); + const float w2 = s->w / 2.f; + const float h2 = s->h / 2.f; - if (!frame) - return AVERROR(ENOMEM); + s->fx0 = (s->x0 - w2) * cosf(angle) - (s->y0 - h2) * sinf(angle) + w2; + s->fy0 = (s->x0 - w2) * sinf(angle) + (s->y0 - h2) * cosf(angle) + h2; - frame->sample_aspect_ratio = (AVRational) {1, 1}; - frame->pts = s->pts++; + s->fx1 = (s->x1 - w2) * cosf(angle) - (s->y1 - h2) * sinf(angle) + w2; + s->fy1 = (s->x1 - w2) * sinf(angle) + (s->y1 - h2) * cosf(angle) + h2; - ctx->internal->execute(ctx, s->draw_slice, frame, NULL, FFMIN(outlink->h, ff_filter_get_nb_threads(ctx))); + if (!frame) + return AVERROR(ENOMEM); - return ff_filter_frame(outlink, frame); + frame->key_frame = 1; + frame->interlaced_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_I; + frame->sample_aspect_ratio = (AVRational) {1, 1}; + frame->pts = s->pts++; + + ctx->internal->execute(ctx, s->draw_slice, frame, NULL, + FFMIN(outlink->h, ff_filter_get_nb_threads(ctx))); + + return ff_filter_frame(outlink, frame); + } + + return FFERROR_NOT_READY; } static const AVFilterPad gradients_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = gradients_request_frame, .config_props = config_output, }, { NULL } @@ -286,5 +306,6 @@ AVFilter ff_vsrc_gradients = { .query_formats = query_formats, .inputs = NULL, .outputs = gradients_outputs, + .activate = activate, .flags = AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index e8c33b00a..7899c843c 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -45,6 +45,7 @@ #include "libavutil/xga_font_data.h" #include "avfilter.h" #include "drawutils.h" +#include "filters.h" #include "formats.h" #include "internal.h" #include "video.h" @@ -76,6 +77,8 @@ typedef struct TestSourceContext { /* only used by rgbtest */ uint8_t rgba_map[4]; + int complement; + int depth; /* only used by haldclut */ int level; @@ -98,6 +101,9 @@ typedef struct TestSourceContext { #define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE +#define NOSIZE_OPTIONS_OFFSET 2 +/* Filters using COMMON_OPTIONS_NOSIZE also use the following options + * via &options[NOSIZE_OPTIONS_OFFSET]. So don't break it. */ static const AVOption options[] = { COMMON_OPTIONS { NULL } @@ -138,14 +144,19 @@ static int config_props(AVFilterLink *outlink) return 0; } -static int request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - TestSourceContext *test = outlink->src->priv; + AVFilterLink *outlink = ctx->outputs[0]; + TestSourceContext *test = ctx->priv; AVFrame *frame; + if (!ff_outlink_frame_wanted(outlink)) + return FFERROR_NOT_READY; if (test->duration >= 0 && - av_rescale_q(test->pts, test->time_base, AV_TIME_BASE_Q) >= test->duration) - return AVERROR_EOF; + av_rescale_q(test->pts, test->time_base, AV_TIME_BASE_Q) >= test->duration) { + ff_outlink_set_status(outlink, AVERROR_EOF, test->pts); + return 0; + } if (test->draw_once) { if (test->draw_once_reset) { @@ -250,7 +261,6 @@ static const AVFilterPad color_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = color_config_props, }, { NULL } @@ -263,6 +273,7 @@ AVFilter ff_vsrc_color = { .priv_size = sizeof(TestSourceContext), .init = color_init, .uninit = uninit, + .activate = activate, .query_formats = color_query_formats, .inputs = NULL, .outputs = color_outputs, @@ -384,7 +395,6 @@ static const AVFilterPad haldclutsrc_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = haldclutsrc_config_props, }, { NULL } @@ -398,6 +408,7 @@ AVFilter ff_vsrc_haldclutsrc = { .init = haldclutsrc_init, .uninit = uninit, .query_formats = haldclutsrc_query_formats, + .activate = activate, .inputs = NULL, .outputs = haldclutsrc_outputs, }; @@ -422,7 +433,6 @@ static const AVFilterPad nullsrc_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = config_props, }, { NULL }, @@ -433,6 +443,7 @@ AVFilter ff_vsrc_nullsrc = { .description = NULL_IF_CONFIG_SMALL("Null video source, return unprocessed video frames."), .init = nullsrc_init, .uninit = uninit, + .activate = activate, .priv_size = sizeof(TestSourceContext), .priv_class = &nullsrc_class, .inputs = NULL, @@ -658,7 +669,6 @@ static const AVFilterPad avfilter_vsrc_testsrc_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = config_props, }, { NULL } @@ -672,6 +682,7 @@ AVFilter ff_vsrc_testsrc = { .init = test_init, .uninit = uninit, .query_formats = test_query_formats, + .activate = activate, .inputs = NULL, .outputs = avfilter_vsrc_testsrc_outputs, }; @@ -931,7 +942,6 @@ static const AVFilterPad avfilter_vsrc_testsrc2_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = test2_config_props, }, { NULL } @@ -945,6 +955,7 @@ AVFilter ff_vsrc_testsrc2 = { .init = test2_init, .uninit = uninit, .query_formats = test2_query_formats, + .activate = activate, .inputs = NULL, .outputs = avfilter_vsrc_testsrc2_outputs, }; @@ -953,7 +964,13 @@ AVFilter ff_vsrc_testsrc2 = { #if CONFIG_RGBTESTSRC_FILTER -#define rgbtestsrc_options options +static const AVOption rgbtestsrc_options[] = { + COMMON_OPTIONS + { "complement", "set complement colors", OFFSET(complement), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { "co", "set complement colors", OFFSET(complement), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { NULL } +}; + AVFILTER_DEFINE_CLASS(rgbtestsrc); #define R 0 @@ -961,12 +978,15 @@ AVFILTER_DEFINE_CLASS(rgbtestsrc); #define B 2 #define A 3 -static void rgbtest_put_pixel(uint8_t *dst, int dst_linesize, +static void rgbtest_put_pixel(uint8_t *dstp[4], int dst_linesizep[4], int x, int y, unsigned r, unsigned g, unsigned b, enum AVPixelFormat fmt, uint8_t rgba_map[4]) { + uint8_t *dst = dstp[0]; + int dst_linesize = dst_linesizep[0]; uint32_t v; uint8_t *p; + uint16_t *p16; switch (fmt) { case AV_PIX_FMT_BGR444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4); break; @@ -989,9 +1009,52 @@ static void rgbtest_put_pixel(uint8_t *dst, int dst_linesize, p = dst + 4*x + y*dst_linesize; AV_WL32(p, v); break; + case AV_PIX_FMT_GBRP: + p = dstp[0] + x + y * dst_linesizep[0]; + p[0] = g; + p = dstp[1] + x + y * dst_linesizep[1]; + p[0] = b; + p = dstp[2] + x + y * dst_linesizep[2]; + p[0] = r; + break; + case AV_PIX_FMT_GBRP9: + case AV_PIX_FMT_GBRP10: + case AV_PIX_FMT_GBRP12: + case AV_PIX_FMT_GBRP14: + case AV_PIX_FMT_GBRP16: + p16 = (uint16_t *)(dstp[0] + x*2 + y * dst_linesizep[0]); + p16[0] = g; + p16 = (uint16_t *)(dstp[1] + x*2 + y * dst_linesizep[1]); + p16[0] = b; + p16 = (uint16_t *)(dstp[2] + x*2 + y * dst_linesizep[2]); + p16[0] = r; + break; } } +static void rgbtest_fill_picture_complement(AVFilterContext *ctx, AVFrame *frame) +{ + TestSourceContext *test = ctx->priv; + int x, y, w = frame->width, h = frame->height; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + int c = (1 << FFMAX(test->depth, 8))*x/w; + int r = 0, g = 0, b = 0; + + if (6*y < h ) r = c; + else if (6*y < 2*h) g = c, b = c; + else if (6*y < 3*h) g = c; + else if (6*y < 4*h) r = c, b = c; + else if (6*y < 5*h) b = c; + else r = c, g = c; + + rgbtest_put_pixel(frame->data, frame->linesize, x, y, r, g, b, + ctx->outputs[0]->format, test->rgba_map); + } + } +} + static void rgbtest_fill_picture(AVFilterContext *ctx, AVFrame *frame) { TestSourceContext *test = ctx->priv; @@ -999,14 +1062,14 @@ static void rgbtest_fill_picture(AVFilterContext *ctx, AVFrame *frame) for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { - int c = 256*x/w; + int c = (1 << FFMAX(test->depth, 8))*x/w; int r = 0, g = 0, b = 0; if (3*y < h ) r = c; else if (3*y < 2*h) g = c; else b = c; - rgbtest_put_pixel(frame->data[0], frame->linesize[0], x, y, r, g, b, + rgbtest_put_pixel(frame->data, frame->linesize, x, y, r, g, b, ctx->outputs[0]->format, test->rgba_map); } } @@ -1017,7 +1080,7 @@ static av_cold int rgbtest_init(AVFilterContext *ctx) TestSourceContext *test = ctx->priv; test->draw_once = 1; - test->fill_picture_fn = rgbtest_fill_picture; + test->fill_picture_fn = test->complement ? rgbtest_fill_picture_complement : rgbtest_fill_picture; return init(ctx); } @@ -1029,6 +1092,8 @@ static int rgbtest_query_formats(AVFilterContext *ctx) AV_PIX_FMT_RGB444, AV_PIX_FMT_BGR444, AV_PIX_FMT_RGB565, AV_PIX_FMT_BGR565, AV_PIX_FMT_RGB555, AV_PIX_FMT_BGR555, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_NONE }; @@ -1041,7 +1106,9 @@ static int rgbtest_query_formats(AVFilterContext *ctx) static int rgbtest_config_props(AVFilterLink *outlink) { TestSourceContext *test = outlink->src->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); + test->depth = desc->comp[0].depth; ff_fill_rgba_map(test->rgba_map, outlink->format); return config_props(outlink); } @@ -1050,7 +1117,6 @@ static const AVFilterPad avfilter_vsrc_rgbtestsrc_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = rgbtest_config_props, }, { NULL } @@ -1064,6 +1130,7 @@ AVFilter ff_vsrc_rgbtestsrc = { .init = rgbtest_init, .uninit = uninit, .query_formats = rgbtest_query_formats, + .activate = activate, .inputs = NULL, .outputs = avfilter_vsrc_rgbtestsrc_outputs, }; @@ -1226,7 +1293,6 @@ static const AVFilterPad avfilter_vsrc_yuvtestsrc_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = yuvtest_config_props, }, { NULL } @@ -1240,6 +1306,7 @@ AVFilter ff_vsrc_yuvtestsrc = { .init = yuvtest_init, .uninit = uninit, .query_formats = yuvtest_query_formats, + .activate = activate, .inputs = NULL, .outputs = avfilter_vsrc_yuvtestsrc_outputs, }; @@ -1369,7 +1436,6 @@ static const AVFilterPad smptebars_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = config_props, }, { NULL } @@ -1417,6 +1483,7 @@ AVFilter ff_vsrc_pal75bars = { .init = pal75bars_init, .uninit = uninit, .query_formats = smptebars_query_formats, + .activate = activate, .inputs = NULL, .outputs = smptebars_outputs, }; @@ -1463,6 +1530,7 @@ AVFilter ff_vsrc_pal100bars = { .init = pal100bars_init, .uninit = uninit, .query_formats = smptebars_query_formats, + .activate = activate, .inputs = NULL, .outputs = smptebars_outputs, }; @@ -1530,6 +1598,7 @@ AVFilter ff_vsrc_smptebars = { .init = smptebars_init, .uninit = uninit, .query_formats = smptebars_query_formats, + .activate = activate, .inputs = NULL, .outputs = smptebars_outputs, }; @@ -1635,6 +1704,7 @@ AVFilter ff_vsrc_smptehdbars = { .init = smptehdbars_init, .uninit = uninit, .query_formats = smptebars_query_formats, + .activate = activate, .inputs = NULL, .outputs = smptebars_outputs, }; @@ -1644,11 +1714,7 @@ AVFilter ff_vsrc_smptehdbars = { #if CONFIG_ALLYUV_FILTER -static const AVOption allyuv_options[] = { - COMMON_OPTIONS_NOSIZE - { NULL } -}; - +#define allyuv_options &options[NOSIZE_OPTIONS_OFFSET] AVFILTER_DEFINE_CLASS(allyuv); static void allyuv_fill_picture(AVFilterContext *ctx, AVFrame *frame) @@ -1703,7 +1769,6 @@ static const AVFilterPad avfilter_vsrc_allyuv_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = config_props, }, { NULL } @@ -1717,6 +1782,7 @@ AVFilter ff_vsrc_allyuv = { .init = allyuv_init, .uninit = uninit, .query_formats = allyuv_query_formats, + .activate = activate, .inputs = NULL, .outputs = avfilter_vsrc_allyuv_outputs, }; @@ -1725,11 +1791,7 @@ AVFilter ff_vsrc_allyuv = { #if CONFIG_ALLRGB_FILTER -static const AVOption allrgb_options[] = { - COMMON_OPTIONS_NOSIZE - { NULL } -}; - +#define allrgb_options &options[NOSIZE_OPTIONS_OFFSET] AVFILTER_DEFINE_CLASS(allrgb); static void allrgb_fill_picture(AVFilterContext *ctx, AVFrame *frame) @@ -1784,7 +1846,6 @@ static const AVFilterPad avfilter_vsrc_allrgb_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = allrgb_config_props, }, { NULL } @@ -1798,6 +1859,7 @@ AVFilter ff_vsrc_allrgb = { .init = allrgb_init, .uninit = uninit, .query_formats = allrgb_query_formats, + .activate = activate, .inputs = NULL, .outputs = avfilter_vsrc_allrgb_outputs, }; diff --git a/libavfilter/x86/vf_atadenoise_init.c b/libavfilter/x86/vf_atadenoise_init.c index 1f69b1af3..3f87f3c44 100644 --- a/libavfilter/x86/vf_atadenoise_init.c +++ b/libavfilter/x86/vf_atadenoise_init.c @@ -28,22 +28,24 @@ void ff_atadenoise_filter_row8_sse4(const uint8_t *src, uint8_t *dst, const uint8_t **srcf, int w, int mid, int size, - int thra, int thrb); + int thra, int thrb, const float *weights); void ff_atadenoise_filter_row8_serial_sse4(const uint8_t *src, uint8_t *dst, const uint8_t **srcf, int w, int mid, int size, - int thra, int thrb); + int thra, int thrb, const float *weights); -av_cold void ff_atadenoise_init_x86(ATADenoiseDSPContext *dsp, int depth, int algorithm) +av_cold void ff_atadenoise_init_x86(ATADenoiseDSPContext *dsp, int depth, int algorithm, const float *sigma) { int cpu_flags = av_get_cpu_flags(); - if (ARCH_X86_64 && EXTERNAL_SSE4(cpu_flags) && depth <= 8 && algorithm == PARALLEL) { - dsp->filter_row = ff_atadenoise_filter_row8_sse4; - } + for (int p = 0; p < 4; p++) { + if (ARCH_X86_64 && EXTERNAL_SSE4(cpu_flags) && depth <= 8 && algorithm == PARALLEL && sigma[p] == INT16_MAX) { + dsp->filter_row[p] = ff_atadenoise_filter_row8_sse4; + } - if (ARCH_X86_64 && EXTERNAL_SSE4(cpu_flags) && depth <= 8 && algorithm == SERIAL) { - dsp->filter_row = ff_atadenoise_filter_row8_serial_sse4; + if (ARCH_X86_64 && EXTERNAL_SSE4(cpu_flags) && depth <= 8 && algorithm == SERIAL && sigma[p] == INT16_MAX) { + dsp->filter_row[p] = ff_atadenoise_filter_row8_serial_sse4; + } } } diff --git a/libavfilter/x86/vf_convolution_init.c b/libavfilter/x86/vf_convolution_init.c index 51432406e..b78a47d02 100644 --- a/libavfilter/x86/vf_convolution_init.c +++ b/libavfilter/x86/vf_convolution_init.c @@ -27,7 +27,7 @@ void ff_filter_3x3_sse4(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, - int dstride, int stride); + int dstride, int stride, int size); av_cold void ff_convolution_init_x86(ConvolutionContext *s) { @@ -36,7 +36,7 @@ av_cold void ff_convolution_init_x86(ConvolutionContext *s) int cpu_flags = av_get_cpu_flags(); for (i = 0; i < 4; i++) { if (s->mode[i] == MATRIX_SQUARE) { - if (s->matrix_length[i] == 9) { + if (s->matrix_length[i] == 9 && s->depth == 8) { if (EXTERNAL_SSE4(cpu_flags)) s->filter[i] = ff_filter_3x3_sse4; } diff --git a/libavfilter/x86/vf_gblur.asm b/libavfilter/x86/vf_gblur.asm index a25b1659f..4d84e6d01 100644 --- a/libavfilter/x86/vf_gblur.asm +++ b/libavfilter/x86/vf_gblur.asm @@ -183,3 +183,49 @@ HORIZ_SLICE INIT_XMM avx2 HORIZ_SLICE %endif + +%macro POSTSCALE_SLICE 0 +cglobal postscale_slice, 2, 2, 4, ptr, length, postscale, min, max + shl lengthd, 2 + add ptrq, lengthq + neg lengthq +%if ARCH_X86_32 + VBROADCASTSS m0, postscalem + VBROADCASTSS m1, minm + VBROADCASTSS m2, maxm +%elif WIN64 + SWAP 0, 2 + SWAP 1, 3 + VBROADCASTSS m0, xm0 + VBROADCASTSS m1, xm1 + VBROADCASTSS m2, maxm +%else ; UNIX64 + VBROADCASTSS m0, xm0 + VBROADCASTSS m1, xm1 + VBROADCASTSS m2, xm2 +%endif + + .loop: +%if cpuflag(avx2) + mulps m3, m0, [ptrq + lengthq] +%else + movu m3, [ptrq + lengthq] + mulps m3, m0 +%endif + maxps m3, m1 + minps m3, m2 + movu [ptrq+lengthq], m3 + + add lengthq, mmsize + jl .loop + + RET +%endmacro + +INIT_XMM sse +POSTSCALE_SLICE + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +POSTSCALE_SLICE +%endif diff --git a/libavfilter/x86/vf_gblur_init.c b/libavfilter/x86/vf_gblur_init.c index e63e59fe2..d80fb46fe 100644 --- a/libavfilter/x86/vf_gblur_init.c +++ b/libavfilter/x86/vf_gblur_init.c @@ -27,14 +27,25 @@ void ff_horiz_slice_sse4(float *ptr, int width, int height, int steps, float nu, float bscale); void ff_horiz_slice_avx2(float *ptr, int width, int height, int steps, float nu, float bscale); +void ff_postscale_slice_sse(float *ptr, int length, float postscale, float min, float max); +void ff_postscale_slice_avx2(float *ptr, int length, float postscale, float min, float max); + av_cold void ff_gblur_init_x86(GBlurContext *s) { -#if ARCH_X86_64 int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_SSE4(cpu_flags)) + if (EXTERNAL_SSE(cpu_flags)) { + s->postscale_slice = ff_postscale_slice_sse; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + s->postscale_slice = ff_postscale_slice_avx2; + } +#if ARCH_X86_64 + if (EXTERNAL_SSE4(cpu_flags)) { s->horiz_slice = ff_horiz_slice_sse4; - if (EXTERNAL_AVX2(cpu_flags)) + } + if (EXTERNAL_AVX2(cpu_flags)) { s->horiz_slice = ff_horiz_slice_avx2; + } #endif } diff --git a/libavfilter/x86/vf_v360_init.c b/libavfilter/x86/vf_v360_init.c index 7d001a694..2b2b06dd4 100644 --- a/libavfilter/x86/vf_v360_init.c +++ b/libavfilter/x86/vf_v360_init.c @@ -64,7 +64,8 @@ av_cold void ff_v360_init_x86(V360Context *s, int depth) if (EXTERNAL_AVX2_FAST(cpu_flags) && (s->interp == BICUBIC || s->interp == LANCZOS || s->interp == SPLINE16 || - s->interp == GAUSSIAN) && depth <= 8) + s->interp == GAUSSIAN || + s->interp == MITCHELL) && depth <= 8) s->remap_line = ff_remap4_8bit_line_avx2; #endif } diff --git a/libavformat/3dostr.c b/libavformat/3dostr.c index e77df9e5c..534f205fc 100644 --- a/libavformat/3dostr.c +++ b/libavformat/3dostr.c @@ -19,17 +19,56 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/intreadwrite.h" #include "avformat.h" #include "internal.h" static int threedostr_probe(const AVProbeData *p) { - if (memcmp(p->buf, "CTRL", 4) && - memcmp(p->buf, "SHDR", 4) && - memcmp(p->buf, "SNDS", 4)) - return 0; + for (int i = 0; i < p->buf_size;) { + unsigned chunk = AV_RL32(p->buf + i); + unsigned size = AV_RB32(p->buf + i + 4); - return AVPROBE_SCORE_MAX / 3 * 2; + if (size < 8 || p->buf_size - i < size) + return 0; + i += 8; + size -= 8; + switch (chunk) { + case MKTAG('C','T','R','L'): + break; + case MKTAG('S','N','D','S'): + if (size < 56) + return 0; + i += 8; + if (AV_RL32(p->buf + i) != MKTAG('S','H','D','R')) + return 0; + i += 28; + + if (AV_RB32(p->buf + i) <= 0) + return 0; + i += 4; + if (AV_RB32(p->buf + i) <= 0) + return 0; + i += 4; + if (AV_RL32(p->buf + i) == MKTAG('S','D','X','2')) + return AVPROBE_SCORE_MAX; + else + return 0; + break; + case MKTAG('S','H','D','R'): + if (size > 0x78) { + i += 0x78; + size -= 0x78; + } + break; + default: + break; + } + + i += size; + } + + return 0; } static int threedostr_read_header(AVFormatContext *s) @@ -110,15 +149,12 @@ static int threedostr_read_header(AVFormatContext *s) static int threedostr_read_packet(AVFormatContext *s, AVPacket *pkt) { - unsigned chunk, size, found_ssmp = 0; + unsigned chunk, size; AVStream *st = s->streams[0]; int64_t pos; int ret = 0; - while (!found_ssmp) { - if (avio_feof(s->pb)) - return AVERROR_EOF; - + while (!avio_feof(s->pb)) { pos = avio_tell(s->pb); chunk = avio_rl32(s->pb); size = avio_rb32(s->pb); @@ -143,9 +179,7 @@ static int threedostr_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->pos = pos; pkt->stream_index = 0; pkt->duration = size / st->codecpar->channels; - size = 0; - found_ssmp = 1; - break; + return ret; default: av_log(s, AV_LOG_DEBUG, "skipping unknown chunk: %X\n", chunk); break; @@ -154,7 +188,7 @@ static int threedostr_read_packet(AVFormatContext *s, AVPacket *pkt) avio_skip(s->pb, size); } - return ret; + return AVERROR_EOF; } AVInputFormat ff_threedostr_demuxer = { diff --git a/libavformat/Makefile b/libavformat/Makefile index 0658fa371..0f340f74a 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -8,7 +8,6 @@ HEADERS = avformat.h \ OBJS = allformats.o \ avio.o \ aviobuf.o \ - cutils.o \ dump.o \ format.o \ id3v1.o \ @@ -17,7 +16,6 @@ OBJS = allformats.o \ mux.o \ options.o \ os_support.o \ - qtpalette.o \ protocols.o \ riff.o \ sdp.o \ @@ -27,7 +25,7 @@ OBJS = allformats.o \ OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o # subsystems -OBJS-$(CONFIG_ISO_MEDIA) += isom.o +OBJS-$(CONFIG_ISO_MEDIA) += isom.o isom_tags.o OBJS-$(CONFIG_NETWORK) += network.o OBJS-$(CONFIG_RIFFDEC) += riffdec.o OBJS-$(CONFIG_RIFFENC) += riffenc.o @@ -68,8 +66,10 @@ OBJS-$(CONFIG_SRTP) += srtp.o OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o OBJS-$(CONFIG_AA_DEMUXER) += aadec.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o +OBJS-$(CONFIG_AAX_DEMUXER) += aaxdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o +OBJS-$(CONFIG_ACE_DEMUXER) += acedec.o OBJS-$(CONFIG_ACM_DEMUXER) += acm.o rawdec.o OBJS-$(CONFIG_ACT_DEMUXER) += act.o OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o @@ -81,19 +81,22 @@ OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o OBJS-$(CONFIG_ADX_MUXER) += rawenc.o OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o OBJS-$(CONFIG_AFC_DEMUXER) += afc.o -OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o pcm.o isom.o \ +OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o aiff.o pcm.o \ mov_chan.o replaygain.o -OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o id3v2enc.o +OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o aiff.o id3v2enc.o OBJS-$(CONFIG_AIX_DEMUXER) += aixdec.o OBJS-$(CONFIG_ALP_DEMUXER) += alp.o +OBJS-$(CONFIG_ALP_MUXER) += alp.o OBJS-$(CONFIG_AMR_DEMUXER) += amr.o OBJS-$(CONFIG_AMR_MUXER) += amr.o rawenc.o OBJS-$(CONFIG_AMRNB_DEMUXER) += amr.o OBJS-$(CONFIG_AMRWB_DEMUXER) += amr.o +OBJS-$(CONFIG_AMV_MUXER) += amvenc.o OBJS-$(CONFIG_ANM_DEMUXER) += anm.o OBJS-$(CONFIG_APC_DEMUXER) += apc.o OBJS-$(CONFIG_APE_DEMUXER) += ape.o apetag.o img2.o -OBJS-$(CONFIG_APM_DEMUXER) += apm.o riffdec.o +OBJS-$(CONFIG_APM_DEMUXER) += apm.o +OBJS-$(CONFIG_APM_MUXER) += apm.o rawenc.o OBJS-$(CONFIG_APNG_DEMUXER) += apngdec.o OBJS-$(CONFIG_APNG_MUXER) += apngenc.o OBJS-$(CONFIG_APTX_DEMUXER) += aptxdec.o rawdec.o @@ -102,6 +105,8 @@ OBJS-$(CONFIG_APTX_HD_DEMUXER) += aptxdec.o rawdec.o OBJS-$(CONFIG_APTX_HD_MUXER) += rawenc.o OBJS-$(CONFIG_AQTITLE_DEMUXER) += aqtitledec.o subtitles.o OBJS-$(CONFIG_ARGO_ASF_DEMUXER) += argo_asf.o +OBJS-$(CONFIG_ARGO_ASF_MUXER) += argo_asf.o +OBJS-$(CONFIG_ARGO_BRP_DEMUXER) += argo_brp.o argo_asf.o OBJS-$(CONFIG_ASF_DEMUXER) += asfdec_f.o asf.o asfcrypt.o \ avlanguage.o OBJS-$(CONFIG_ASF_O_DEMUXER) += asfdec_o.o asf.o asfcrypt.o \ @@ -113,16 +118,18 @@ OBJS-$(CONFIG_AST_DEMUXER) += ast.o astdec.o OBJS-$(CONFIG_AST_MUXER) += ast.o astenc.o OBJS-$(CONFIG_AU_DEMUXER) += au.o pcm.o OBJS-$(CONFIG_AU_MUXER) += au.o rawenc.o -OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o +OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o isom_tags.o OBJS-$(CONFIG_AVI_MUXER) += avienc.o mpegtsenc.o avlanguage.o rawutils.o OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o swf.o OBJS-$(CONFIG_AVR_DEMUXER) += avr.o pcm.o -OBJS-$(CONFIG_AVS_DEMUXER) += avs.o voc_packet.o vocdec.o voc.o -OBJS-$(CONFIG_AVS2_DEMUXER) += davs2.o rawdec.o +OBJS-$(CONFIG_AVS_DEMUXER) += avs.o voc_packet.o voc.o +OBJS-$(CONFIG_AVS2_DEMUXER) += avs2dec.o rawdec.o OBJS-$(CONFIG_AVS2_MUXER) += rawenc.o +OBJS-$(CONFIG_AVS3_DEMUXER) += avs3dec.o rawdec.o OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o OBJS-$(CONFIG_BINK_DEMUXER) += bink.o +OBJS-$(CONFIG_BINKA_DEMUXER) += binka.o OBJS-$(CONFIG_BINTEXT_DEMUXER) += bintext.o sauce.o OBJS-$(CONFIG_BIT_DEMUXER) += bit.o OBJS-$(CONFIG_BIT_MUXER) += bit.o @@ -130,7 +137,7 @@ OBJS-$(CONFIG_BMV_DEMUXER) += bmv.o OBJS-$(CONFIG_BOA_DEMUXER) += boadec.o OBJS-$(CONFIG_BFSTM_DEMUXER) += brstm.o OBJS-$(CONFIG_BRSTM_DEMUXER) += brstm.o -OBJS-$(CONFIG_C93_DEMUXER) += c93.o voc_packet.o vocdec.o voc.o +OBJS-$(CONFIG_C93_DEMUXER) += c93.o voc_packet.o voc.o OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov_chan.o mov_esds.o OBJS-$(CONFIG_CAF_MUXER) += cafenc.o caf.o riff.o OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += cavsvideodec.o rawdec.o @@ -230,7 +237,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER) += rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o @@ -259,6 +266,7 @@ OBJS-$(CONFIG_IMAGE_PBM_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_PCX_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_PGMYUV_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_PGM_PIPE_DEMUXER) += img2dec.o img2.o +OBJS-$(CONFIG_IMAGE_PHOTOCD_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_PICTOR_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_PNG_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_PPM_PIPE_DEMUXER) += img2dec.o img2.o @@ -269,10 +277,12 @@ OBJS-$(CONFIG_IMAGE_SVG_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_SUNRAST_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_TIFF_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_WEBP_PIPE_DEMUXER) += img2dec.o img2.o +OBJS-$(CONFIG_IMAGE_XBM_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_XPM_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_XWD_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_INGENIENT_DEMUXER) += ingenientdec.o rawdec.o OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o +OBJS-$(CONFIG_IPU_DEMUXER) += ipudec.o OBJS-$(CONFIG_IRCAM_DEMUXER) += ircamdec.o ircam.o pcm.o OBJS-$(CONFIG_IRCAM_MUXER) += ircamenc.o ircam.o rawenc.o OBJS-$(CONFIG_ISS_DEMUXER) += iss.o @@ -289,6 +299,7 @@ OBJS-$(CONFIG_KVAG_MUXER) += kvag.o rawenc.o OBJS-$(CONFIG_LATM_MUXER) += latmenc.o rawenc.o OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o OBJS-$(CONFIG_LOAS_DEMUXER) += loasdec.o rawdec.o +OBJS-$(CONFIG_LUODAT_DEMUXER) += luodatdec.o OBJS-$(CONFIG_LRC_DEMUXER) += lrcdec.o lrc.o subtitles.o OBJS-$(CONFIG_LRC_MUXER) += lrcenc.o lrc.o OBJS-$(CONFIG_LVF_DEMUXER) += lvfdec.o @@ -296,13 +307,15 @@ OBJS-$(CONFIG_LXF_DEMUXER) += lxfdec.o OBJS-$(CONFIG_M4V_DEMUXER) += m4vdec.o rawdec.o OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ - rmsipr.o flac_picture.o \ + flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ - replaygain.o + qtpalette.o replaygain.o OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ - av1.o avc.o hevc.o \ + av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ vorbiscomment.o wv.o +OBJS-$(CONFIG_MCA_DEMUXER) += mca.o +OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o OBJS-$(CONFIG_MGSTS_DEMUXER) += mgsts.o OBJS-$(CONFIG_MICRODVD_DEMUXER) += microdvddec.o subtitles.o @@ -316,7 +329,10 @@ OBJS-$(CONFIG_MLV_DEMUXER) += mlvdec.o riffdec.o OBJS-$(CONFIG_MM_DEMUXER) += mm.o OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o OBJS-$(CONFIG_MMF_MUXER) += mmf.o rawenc.o -OBJS-$(CONFIG_MOV_DEMUXER) += mov.o mov_chan.o mov_esds.o replaygain.o +OBJS-$(CONFIG_MODS_DEMUXER) += mods.o +OBJS-$(CONFIG_MOFLEX_DEMUXER) += moflex.o +OBJS-$(CONFIG_MOV_DEMUXER) += mov.o mov_chan.o mov_esds.o \ + qtpalette.o replaygain.o OBJS-$(CONFIG_MOV_MUXER) += movenc.o av1.o avc.o hevc.o vpcc.o \ movenchint.o mov_chan.o rtp.o \ movenccenc.o rawutils.o @@ -342,6 +358,7 @@ OBJS-$(CONFIG_MPL2_DEMUXER) += mpl2dec.o subtitles.o OBJS-$(CONFIG_MSF_DEMUXER) += msf.o OBJS-$(CONFIG_MPSUB_DEMUXER) += mpsubdec.o subtitles.o OBJS-$(CONFIG_MSNWC_TCP_DEMUXER) += msnwc_tcp.o +OBJS-$(CONFIG_MSP_DEMUXER) += mspdec.o OBJS-$(CONFIG_MTAF_DEMUXER) += mtaf.o OBJS-$(CONFIG_MTV_DEMUXER) += mtv.o OBJS-$(CONFIG_MUSX_DEMUXER) += musx.o @@ -355,10 +372,11 @@ OBJS-$(CONFIG_NISTSPHERE_DEMUXER) += nistspheredec.o pcm.o OBJS-$(CONFIG_NSP_DEMUXER) += nspdec.o pcm.o OBJS-$(CONFIG_NSV_DEMUXER) += nsvdec.o OBJS-$(CONFIG_NULL_MUXER) += nullenc.o -OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o isom.o +OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o isom_tags.o OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o OBJS-$(CONFIG_AV1_DEMUXER) += av1dec.o +OBJS-$(CONFIG_OBU_DEMUXER) += av1dec.o OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ oggparsecelt.o \ oggparsedirac.o \ @@ -484,8 +502,10 @@ OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o OBJS-$(CONFIG_SEGAFILM_MUXER) += segafilmenc.o OBJS-$(CONFIG_SEGMENT_MUXER) += segment.o OBJS-$(CONFIG_SER_DEMUXER) += serdec.o +OBJS-$(CONFIG_SGA_DEMUXER) += sga.o OBJS-$(CONFIG_SHORTEN_DEMUXER) += shortendec.o rawdec.o OBJS-$(CONFIG_SIFF_DEMUXER) += siff.o +OBJS-$(CONFIG_SIMBIOSIS_IMX_DEMUXER) += imx.o OBJS-$(CONFIG_SINGLEJPEG_MUXER) += rawenc.o OBJS-$(CONFIG_SLN_DEMUXER) += pcmdec.o pcm.o OBJS-$(CONFIG_SMACKER_DEMUXER) += smacker.o @@ -511,6 +531,7 @@ OBJS-$(CONFIG_SUBVIEWER_DEMUXER) += subviewerdec.o subtitles.o OBJS-$(CONFIG_SUP_DEMUXER) += supdec.o OBJS-$(CONFIG_SUP_MUXER) += supenc.o OBJS-$(CONFIG_SVAG_DEMUXER) += svag.o +OBJS-$(CONFIG_SVS_DEMUXER) += svs.o OBJS-$(CONFIG_SWF_DEMUXER) += swfdec.o swf.o OBJS-$(CONFIG_SWF_MUXER) += swfenc.o swf.o OBJS-$(CONFIG_TAK_DEMUXER) += takdec.o apetag.o img2.o rawdec.o @@ -525,6 +546,7 @@ OBJS-$(CONFIG_TRUEHD_DEMUXER) += rawdec.o mlpdec.o OBJS-$(CONFIG_TRUEHD_MUXER) += rawenc.o OBJS-$(CONFIG_TTA_DEMUXER) += tta.o apetag.o img2.o OBJS-$(CONFIG_TTA_MUXER) += ttaenc.o apetag.o img2.o +OBJS-$(CONFIG_TTML_MUXER) += ttmlenc.o OBJS-$(CONFIG_TTY_DEMUXER) += tty.o sauce.o OBJS-$(CONFIG_TY_DEMUXER) += ty.o OBJS-$(CONFIG_TXD_DEMUXER) += txd.o @@ -551,7 +573,7 @@ OBJS-$(CONFIG_WAV_DEMUXER) += wavdec.o pcm.o OBJS-$(CONFIG_WAV_MUXER) += wavenc.o OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \ - av1.o avc.o hevc.o \ + av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ wv.o vorbiscomment.o OBJS-$(CONFIG_WEBM_DASH_MANIFEST_MUXER) += webmdashenc.o @@ -599,6 +621,7 @@ OBJS-$(CONFIG_FFRTMPHTTP_PROTOCOL) += rtmphttp.o OBJS-$(CONFIG_FILE_PROTOCOL) += file.o OBJS-$(CONFIG_FTP_PROTOCOL) += ftp.o urldecode.o OBJS-$(CONFIG_GOPHER_PROTOCOL) += gopher.o +OBJS-$(CONFIG_GOPHERS_PROTOCOL) += gopher.o OBJS-$(CONFIG_HLS_PROTOCOL) += hlsproto.o OBJS-$(CONFIG_HTTP_PROTOCOL) += http.o httpauth.o urldecode.o OBJS-$(CONFIG_HTTPPROXY_PROTOCOL) += http.o httpauth.o urldecode.o @@ -634,6 +657,7 @@ OBJS-$(CONFIG_UNIX_PROTOCOL) += unix.o # external library protocols OBJS-$(CONFIG_LIBAMQP_PROTOCOL) += libamqp.o +OBJS-$(CONFIG_LIBRIST_PROTOCOL) += librist.o OBJS-$(CONFIG_LIBRTMP_PROTOCOL) += librtmp.o OBJS-$(CONFIG_LIBRTMPE_PROTOCOL) += librtmp.o OBJS-$(CONFIG_LIBRTMPS_PROTOCOL) += librtmp.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c index 63f8176a5..2575e9815 100644 --- a/libavformat/aadec.c +++ b/libavformat/aadec.c @@ -72,8 +72,8 @@ static int get_second_size(char *codec_name) static int aa_read_header(AVFormatContext *s) { int i, j, idx, largest_idx = -1; - uint32_t nkey, nval, toc_size, npairs, header_seed = 0, start; - char key[128], val[128], codec_name[64] = {0}; + uint32_t toc_size, npairs, header_seed = 0, start; + char codec_name[64] = {0}; uint8_t output[24], dst[8], src[8]; int64_t largest_size = -1, current_size = -1, chapter_pos; struct toc_entry { @@ -104,8 +104,9 @@ static int aa_read_header(AVFormatContext *s) if (npairs > MAX_DICTIONARY_ENTRIES) return AVERROR_INVALIDDATA; for (i = 0; i < npairs; i++) { - memset(val, 0, sizeof(val)); - memset(key, 0, sizeof(key)); + char key[128], val[128]; + uint32_t nkey, nval; + avio_skip(pb, 1); // unidentified integer nkey = avio_rb32(pb); // key string length nval = avio_rb32(pb); // value string length @@ -113,7 +114,7 @@ static int aa_read_header(AVFormatContext *s) avio_get_str(pb, nval, val, sizeof(val)); if (!strcmp(key, "codec")) { av_log(s, AV_LOG_DEBUG, "Codec is <%s>\n", val); - strncpy(codec_name, val, sizeof(codec_name) - 1); + av_strlcpy(codec_name, val, sizeof(codec_name)); } else if (!strcmp(key, "HeaderSeed")) { av_log(s, AV_LOG_DEBUG, "HeaderSeed is <%s>\n", val); header_seed = atoi(val); @@ -221,14 +222,18 @@ static int aa_read_header(AVFormatContext *s) c->content_end = start + largest_size; while ((chapter_pos = avio_tell(pb)) >= 0 && chapter_pos < c->content_end) { - int chapter_idx = s->nb_chapters; + unsigned chapter_idx = s->nb_chapters; uint32_t chapter_size = avio_rb32(pb); - if (chapter_size == 0) break; + if (chapter_size == 0 || avio_feof(pb)) + break; chapter_pos -= start + CHAPTER_HEADER_SIZE * chapter_idx; avio_skip(pb, 4 + chapter_size); if (!avpriv_new_chapter(s, chapter_idx, st->time_base, - chapter_pos * TIMEPREC, (chapter_pos + chapter_size) * TIMEPREC, NULL)) - return AVERROR(ENOMEM); + chapter_pos * TIMEPREC, + (chapter_pos + chapter_size) * TIMEPREC, NULL)) { + av_freep(&c->tea_ctx); + return AVERROR(ENOMEM); + } } st->duration = (largest_size - CHAPTER_HEADER_SIZE * s->nb_chapters) * TIMEPREC; diff --git a/libavformat/aaxdec.c b/libavformat/aaxdec.c new file mode 100644 index 000000000..c6d2d1c8d --- /dev/null +++ b/libavformat/aaxdec.c @@ -0,0 +1,415 @@ +/* + * AAX demuxer + * Copyright (c) 2020 Paul B Mahol + * + * 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/avassert.h" +#include "libavutil/intreadwrite.h" +#include "avformat.h" +#include "internal.h" + +typedef struct AAXColumn { + uint8_t flag; + uint8_t type; + const char *name; + uint32_t offset; + int size; +} AAXColumn; + +typedef struct AAXSegment { + int64_t start; + int64_t end; +} AAXSegment; + +typedef struct AAXContext { + int64_t table_size; + uint16_t version; + int64_t rows_offset; + int64_t strings_offset; + int64_t data_offset; + int64_t name_offset; + uint16_t columns; + uint16_t row_width; + uint32_t nb_segments; + int64_t schema_offset; + int64_t strings_size; + char *string_table; + + uint32_t current_segment; + + AAXColumn *xcolumns; + AAXSegment *segments; +} AAXContext; + +static int aax_probe(const AVProbeData *p) +{ + if (AV_RB32(p->buf) != MKBETAG('@','U','T','F')) + return 0; + if (AV_RB32(p->buf + 4) == 0) + return 0; + if (AV_RB16(p->buf + 8) > 1) + return 0; + if (AV_RB32(p->buf + 28) < 1) + return 0; + + return AVPROBE_SCORE_MAX; +} + +enum ColumnFlag { + COLUMN_FLAG_NAME = 0x1, + COLUMN_FLAG_DEFAULT = 0x2, + COLUMN_FLAG_ROW = 0x4, + COLUMN_FLAG_UNDEFINED = 0x8 /* shouldn't exist */ +}; + +enum ColumnType { + COLUMN_TYPE_UINT8 = 0x00, + COLUMN_TYPE_SINT8 = 0x01, + COLUMN_TYPE_UINT16 = 0x02, + COLUMN_TYPE_SINT16 = 0x03, + COLUMN_TYPE_UINT32 = 0x04, + COLUMN_TYPE_SINT32 = 0x05, + COLUMN_TYPE_UINT64 = 0x06, + COLUMN_TYPE_SINT64 = 0x07, + COLUMN_TYPE_FLOAT = 0x08, + COLUMN_TYPE_DOUBLE = 0x09, + COLUMN_TYPE_STRING = 0x0a, + COLUMN_TYPE_VLDATA = 0x0b, + COLUMN_TYPE_UINT128 = 0x0c, /* for GUIDs */ + COLUMN_TYPE_UNDEFINED = -1 +}; + +static int64_t get_pts(AVFormatContext *s, int64_t pos, int size) +{ + AAXContext *a = s->priv_data; + int64_t pts = 0; + + for (int seg = 0; seg < a->current_segment; seg++) + pts += (a->segments[seg].end - a->segments[seg].start) / size; + + pts += ((pos - a->segments[a->current_segment].start) / size); + + return pts; +} + +static int aax_read_header(AVFormatContext *s) +{ + AAXContext *a = s->priv_data; + AVIOContext *pb = s->pb; + AVCodecParameters *par; + AVStream *st; + int64_t column_offset = 0; + int ret, extradata_size; + char *codec; + + avio_skip(pb, 4); + a->table_size = avio_rb32(pb) + 8LL; + a->version = avio_rb16(pb); + a->rows_offset = avio_rb16(pb) + 8LL; + a->strings_offset = avio_rb32(pb) + 8LL; + a->data_offset = avio_rb32(pb) + 8LL; + a->name_offset = avio_rb32(pb); + a->columns = avio_rb16(pb); + a->row_width = avio_rb16(pb); + a->nb_segments = avio_rb32(pb); + + if (a->nb_segments < 1) + return AVERROR_INVALIDDATA; + + a->schema_offset = 0x20; + a->strings_size = a->data_offset - a->strings_offset; + + if (a->rows_offset > a->table_size || + a->strings_offset > a->table_size || + a->data_offset > a->table_size) + return AVERROR_INVALIDDATA; + if (a->strings_size <= 0 || a->name_offset >= a->strings_size || + a->strings_size > UINT16_MAX) + return AVERROR_INVALIDDATA; + if (a->columns <= 0) + return AVERROR_INVALIDDATA; + + a->segments = av_calloc(a->nb_segments, sizeof(*a->segments)); + if (!a->segments) + return AVERROR(ENOMEM); + + a->xcolumns = av_calloc(a->columns, sizeof(*a->xcolumns)); + if (!a->xcolumns) { + ret = AVERROR(ENOMEM); + goto fail; + } + + a->string_table = av_calloc(a->strings_size + 1, sizeof(*a->string_table)); + if (!a->string_table) { + ret = AVERROR(ENOMEM); + goto fail; + } + + for (int c = 0; c < a->columns; c++) { + uint8_t info = avio_r8(pb); + uint32_t offset = avio_rb32(pb); + int value_size; + + if (offset >= a->strings_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + a->xcolumns[c].flag = info >> 4; + a->xcolumns[c].type = info & 0x0F; + + switch (a->xcolumns[c].type) { + case COLUMN_TYPE_UINT8: + case COLUMN_TYPE_SINT8: + value_size = 0x01; + break; + case COLUMN_TYPE_UINT16: + case COLUMN_TYPE_SINT16: + value_size = 0x02; + break; + case COLUMN_TYPE_UINT32: + case COLUMN_TYPE_SINT32: + case COLUMN_TYPE_FLOAT: + case COLUMN_TYPE_STRING: + value_size = 0x04; + break; + case COLUMN_TYPE_VLDATA: + value_size = 0x08; + break; + case COLUMN_TYPE_UINT128: + value_size = 0x10; + break; + default: + ret = AVERROR_INVALIDDATA; + goto fail; + } + + a->xcolumns[c].size = value_size; + + if (a->xcolumns[c].flag & COLUMN_FLAG_NAME) + a->xcolumns[c].name = a->string_table + offset; + + if (a->xcolumns[c].flag & COLUMN_FLAG_DEFAULT) { + /* data is found relative to columns start */ + a->xcolumns[c].offset = avio_tell(pb) - a->schema_offset; + avio_skip(pb, value_size); + } + + if (a->xcolumns[c].flag & COLUMN_FLAG_ROW) { + /* data is found relative to row start */ + a->xcolumns[c].offset = column_offset; + column_offset += value_size; + } + } + + avio_seek(pb, a->strings_offset, SEEK_SET); + ret = avio_read(pb, a->string_table, a->strings_size); + if (ret != a->strings_size) { + if (ret < 0) + goto fail; + ret = AVERROR(EIO); + goto fail; + } + + for (int c = 0; c < a->columns; c++) { + int64_t data_offset = 0; + int64_t col_offset; + int flag, type; + + if (!a->xcolumns[c].name || strcmp(a->xcolumns[c].name, "data")) + continue; + + type = a->xcolumns[c].type; + flag = a->xcolumns[c].flag; + col_offset = a->xcolumns[c].offset; + + for (uint64_t r = 0; r < a->nb_segments; r++) { + if (flag & COLUMN_FLAG_DEFAULT) { + data_offset = a->schema_offset + col_offset; + } else if (flag & COLUMN_FLAG_ROW) { + data_offset = a->rows_offset + r * a->row_width + col_offset; + } else { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + avio_seek(pb, data_offset, SEEK_SET); + if (type == COLUMN_TYPE_VLDATA) { + int64_t start, size; + + start = avio_rb32(pb); + size = avio_rb32(pb); + a->segments[r].start = start + a->data_offset; + a->segments[r].end = a->segments[r].start + size; + } else { + ret = AVERROR_INVALIDDATA; + goto fail; + } + } + } + + if (!a->segments[0].end) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + st = avformat_new_stream(s, NULL); + if (!st) { + ret = AVERROR(ENOMEM); + goto fail; + } + st->start_time = 0; + par = s->streams[0]->codecpar; + par->codec_type = AVMEDIA_TYPE_AUDIO; + + codec = a->string_table + a->name_offset; + if (!strcmp(codec, "AAX")) { + par->codec_id = AV_CODEC_ID_ADPCM_ADX; + avio_seek(pb, a->segments[0].start, SEEK_SET); + if (avio_rb16(pb) != 0x8000) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + extradata_size = avio_rb16(pb) + 4; + if (extradata_size < 12) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + avio_seek(pb, -4, SEEK_CUR); + ret = ff_get_extradata(s, par, pb, extradata_size); + if (ret < 0) { + goto fail; + } + par->channels = AV_RB8 (par->extradata + 7); + par->sample_rate = AV_RB32(par->extradata + 8); + if (!par->channels || !par->sample_rate) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + avpriv_set_pts_info(st, 64, 32, par->sample_rate); + /*} else if (!strcmp(codec, "HCA") ){ + par->codec_id = AV_CODEC_ID_HCA;*/ + } else { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + return 0; +fail: + av_freep(&a->string_table); + av_freep(&a->xcolumns); + av_freep(&a->segments); + + return ret; +} + +static int aax_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AAXContext *a = s->priv_data; + AVCodecParameters *par = s->streams[0]->codecpar; + AVIOContext *pb = s->pb; + const int size = 18 * par->channels; + int ret, extradata_size = 0; + uint8_t *extradata = NULL; + int skip = 0; + + if (avio_feof(pb)) + return AVERROR_EOF; + + pkt->pos = avio_tell(pb); + + for (uint32_t seg = 0; seg < a->nb_segments; seg++) { + int64_t start = a->segments[seg].start; + int64_t end = a->segments[seg].end; + + if (pkt->pos >= start && pkt->pos <= end) { + a->current_segment = seg; + if (par->codec_id == AV_CODEC_ID_ADPCM_ADX) + skip = (end - start) - ((end - start) / size) * size; + break; + } + } + + if (pkt->pos >= a->segments[a->current_segment].end - skip) { + if (a->current_segment + 1 == a->nb_segments) + return AVERROR_EOF; + a->current_segment++; + avio_seek(pb, a->segments[a->current_segment].start, SEEK_SET); + + if (par->codec_id == AV_CODEC_ID_ADPCM_ADX) { + if (avio_rb16(pb) != 0x8000) + return AVERROR_INVALIDDATA; + extradata_size = avio_rb16(pb) + 4; + avio_seek(pb, -4, SEEK_CUR); + if (extradata_size < 12) + return AVERROR_INVALIDDATA; + extradata = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!extradata) + return AVERROR(ENOMEM); + if (avio_read(pb, extradata, extradata_size) != extradata_size) { + av_free(extradata); + return AVERROR(EIO); + } + memset(extradata + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + } + } + + ret = av_get_packet(pb, pkt, size); + if (ret != size) { + av_free(extradata); + return ret < 0 ? ret : AVERROR(EIO); + } + pkt->duration = 1; + pkt->stream_index = 0; + pkt->pts = get_pts(s, pkt->pos, size); + + if (extradata) { + ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, extradata, extradata_size); + if (ret < 0) { + av_free(extradata); + return ret; + } + } + + return ret; +} + +static int aax_read_close(AVFormatContext *s) +{ + AAXContext *a = s->priv_data; + + av_freep(&a->segments); + av_freep(&a->xcolumns); + av_freep(&a->string_table); + + return 0; +} + +AVInputFormat ff_aax_demuxer = { + .name = "aax", + .long_name = NULL_IF_CONFIG_SMALL("CRI AAX"), + .priv_data_size = sizeof(AAXContext), + .read_probe = aax_probe, + .read_header = aax_read_header, + .read_packet = aax_read_packet, + .read_close = aax_read_close, + .extensions = "aax", + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/acedec.c b/libavformat/acedec.c new file mode 100644 index 000000000..f1bc512d5 --- /dev/null +++ b/libavformat/acedec.c @@ -0,0 +1,114 @@ +/* + * ACE demuxer + * Copyright (c) 2020 Paul B Mahol + * + * 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/intreadwrite.h" +#include "avformat.h" +#include "internal.h" + +static int ace_probe(const AVProbeData *p) +{ + uint32_t asc; + + if (AV_RB32(p->buf) != MKBETAG('A','A','C',' ')) + return 0; + if (p->buf_size < 0x44) + return 0; + asc = AV_RB32(p->buf + 0x40); + if (asc < 0x44 || asc > p->buf_size - 4) + return 0; + if (AV_RB32(p->buf + asc) != MKBETAG('A','S','C',' ')) + return 0; + + return AVPROBE_SCORE_MAX / 2 + 1; +} + +static int ace_read_header(AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + AVCodecParameters *par; + int ret, codec, rate, nb_channels; + uint32_t asc_pos, size; + AVStream *st; + + avio_skip(pb, 0x40); + asc_pos = avio_rb32(pb); + if (asc_pos < 0x44) + return AVERROR_INVALIDDATA; + avio_skip(pb, asc_pos - 0x44); + if (avio_rb32(pb) != MKBETAG('A','S','C',' ')) + return AVERROR_INVALIDDATA; + avio_skip(pb, 0xec); + codec = avio_rb32(pb); + nb_channels = avio_rb32(pb); + if (nb_channels <= 0 || nb_channels > 8) + return AVERROR_INVALIDDATA; + size = avio_rb32(pb); + if (size == 0) + return AVERROR_INVALIDDATA; + rate = avio_rb32(pb); + if (rate <= 0) + return AVERROR_INVALIDDATA; + avio_skip(pb, 16); + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + st->start_time = 0; + par = st->codecpar; + par->codec_type = AVMEDIA_TYPE_AUDIO; + par->channels = nb_channels; + par->sample_rate = rate; + par->block_align = (codec == 4 ? 0x60 : codec == 5 ? 0x98 : 0xC0) * nb_channels; + st->duration = (size / par->block_align) * 1024LL; + par->codec_id = AV_CODEC_ID_ATRAC3; + + ret = ff_alloc_extradata(par, 14); + if (ret < 0) + return ret; + + AV_WL16(st->codecpar->extradata, 1); + AV_WL16(st->codecpar->extradata+2, 2048 * par->channels); + AV_WL16(st->codecpar->extradata+4, 0); + AV_WL16(st->codecpar->extradata+6, codec == 4 ? 1 : 0); + AV_WL16(st->codecpar->extradata+8, codec == 4 ? 1 : 0); + AV_WL16(st->codecpar->extradata+10, 1); + AV_WL16(st->codecpar->extradata+12, 0); + + avpriv_set_pts_info(st, 64, 1, par->sample_rate); + + return 0; +} + +static int ace_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVCodecParameters *par = s->streams[0]->codecpar; + + return av_get_packet(s->pb, pkt, par->block_align); +} + +AVInputFormat ff_ace_demuxer = { + .name = "ace", + .long_name = NULL_IF_CONFIG_SMALL("tri-Ace Audio Container"), + .read_probe = ace_probe, + .read_header = ace_read_header, + .read_packet = ace_read_packet, + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/adp.c b/libavformat/adp.c index 8668c78fe..b0ee09753 100644 --- a/libavformat/adp.c +++ b/libavformat/adp.c @@ -75,13 +75,9 @@ static int adp_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR_EOF; ret = av_get_packet(s->pb, pkt, size); + if (ret < 0) + return ret; - if (ret != size) { - if (ret < 0) { - return ret; - } - av_shrink_packet(pkt, ret); - } pkt->stream_index = 0; return ret; diff --git a/libavformat/adtsenc.c b/libavformat/adtsenc.c index d937e2bea..3595cb3bb 100644 --- a/libavformat/adtsenc.c +++ b/libavformat/adtsenc.c @@ -40,6 +40,7 @@ typedef struct ADTSContext { int pce_size; int apetag; int id3v2tag; + int mpeg_id; uint8_t pce_data[MAX_PCE_SIZE]; } ADTSContext; @@ -136,7 +137,7 @@ static int adts_write_frame_header(ADTSContext *ctx, /* adts_fixed_header */ put_bits(&pb, 12, 0xfff); /* syncword */ - put_bits(&pb, 1, 0); /* ID */ + put_bits(&pb, 1, ctx->mpeg_id); /* ID */ put_bits(&pb, 2, 0); /* layer */ put_bits(&pb, 1, 1); /* protection_absent */ put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */ @@ -169,7 +170,8 @@ static int adts_write_packet(AVFormatContext *s, AVPacket *pkt) return 0; if (!par->extradata_size) { uint8_t *side_data; - int side_data_size = 0, ret; + buffer_size_t side_data_size; + int ret; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size); @@ -214,6 +216,7 @@ static int adts_write_trailer(AVFormatContext *s) static const AVOption options[] = { { "write_id3v2", "Enable ID3v2 tag writing", OFFSET(id3v2tag), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, ENC}, { "write_apetag", "Enable APE tag writing", OFFSET(apetag), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, ENC}, + { "write_mpeg2", "Use MPE2 ID when writing", OFFSET(mpeg_id), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, ENC, "mpeg_id"}, { NULL }, }; diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c index ccd5049ac..a265c87de 100644 --- a/libavformat/adxdec.c +++ b/libavformat/adxdec.c @@ -53,6 +53,9 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt) AVCodecParameters *par = s->streams[0]->codecpar; int ret, size; + if (avio_feof(s->pb)) + return AVERROR_EOF; + if (par->channels <= 0) { av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n", par->channels); return AVERROR_INVALIDDATA; @@ -63,16 +66,21 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->pos = avio_tell(s->pb); pkt->stream_index = 0; - ret = av_get_packet(s->pb, pkt, size); - if (ret != size) { - return ret < 0 ? ret : AVERROR(EIO); + ret = av_get_packet(s->pb, pkt, size * 128); + if (ret < 0) + return ret; + if ((ret % size) && ret >= size) { + size = ret - (ret % size); + av_shrink_packet(pkt, size); + pkt->flags &= ~AV_PKT_FLAG_CORRUPT; + } else if (ret < size) { + return AVERROR(EIO); + } else { + size = ret; } - if (AV_RB16(pkt->data) & 0x8000) { - return AVERROR_EOF; - } - pkt->size = size; - pkt->duration = 1; - pkt->pts = (pkt->pos - c->header_size) / size; + + pkt->duration = size / (BLOCK_SIZE * par->channels); + pkt->pts = (pkt->pos - c->header_size) / (BLOCK_SIZE * par->channels); return 0; } diff --git a/libavformat/aiff.c b/libavformat/aiff.c new file mode 100644 index 000000000..0f25b436b --- /dev/null +++ b/libavformat/aiff.c @@ -0,0 +1,54 @@ +/* + * AIFF/AIFF-C muxer/demuxer common data + * Copyright (c) 2006 Patrick Guimond + * + * 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 "libavcodec/codec_id.h" +#include "internal.h" + +const AVCodecTag ff_codec_aiff_tags[] = { + { AV_CODEC_ID_PCM_S16BE, MKTAG('N','O','N','E') }, + { AV_CODEC_ID_PCM_S8, MKTAG('N','O','N','E') }, + { AV_CODEC_ID_PCM_U8, MKTAG('r','a','w',' ') }, + { AV_CODEC_ID_PCM_S24BE, MKTAG('N','O','N','E') }, + { AV_CODEC_ID_PCM_S32BE, MKTAG('N','O','N','E') }, + { AV_CODEC_ID_PCM_F32BE, MKTAG('f','l','3','2') }, + { AV_CODEC_ID_PCM_F64BE, MKTAG('f','l','6','4') }, + { AV_CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') }, + { AV_CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') }, + { AV_CODEC_ID_PCM_S24BE, MKTAG('i','n','2','4') }, + { AV_CODEC_ID_PCM_S32BE, MKTAG('i','n','3','2') }, + { AV_CODEC_ID_MACE3, MKTAG('M','A','C','3') }, + { AV_CODEC_ID_MACE6, MKTAG('M','A','C','6') }, + { AV_CODEC_ID_GSM, MKTAG('G','S','M',' ') }, + { AV_CODEC_ID_ADPCM_G722, MKTAG('G','7','2','2') }, + { AV_CODEC_ID_ADPCM_G726LE, MKTAG('G','7','2','6') }, + { AV_CODEC_ID_PCM_S16BE, MKTAG('t','w','o','s') }, + { AV_CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') }, + { AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') }, + { AV_CODEC_ID_QDMC, MKTAG('Q','D','M','C') }, + { AV_CODEC_ID_QDM2, MKTAG('Q','D','M','2') }, + { AV_CODEC_ID_QCELP, MKTAG('Q','c','l','p') }, + { AV_CODEC_ID_SDX2_DPCM, MKTAG('S','D','X','2') }, + { AV_CODEC_ID_ADPCM_IMA_WS, MKTAG('A','D','P','4') }, + { AV_CODEC_ID_NONE, 0 }, +}; + +const AVCodecTag *const ff_aiff_codec_tags_list[] = { ff_codec_aiff_tags, NULL }; diff --git a/libavformat/aiff.h b/libavformat/aiff.h index 0ed10a241..7c7c55cb5 100644 --- a/libavformat/aiff.h +++ b/libavformat/aiff.h @@ -27,35 +27,9 @@ #ifndef AVFORMAT_AIFF_H #define AVFORMAT_AIFF_H -#include "avformat.h" #include "internal.h" -static const AVCodecTag ff_codec_aiff_tags[] = { - { AV_CODEC_ID_PCM_S16BE, MKTAG('N','O','N','E') }, - { AV_CODEC_ID_PCM_S8, MKTAG('N','O','N','E') }, - { AV_CODEC_ID_PCM_U8, MKTAG('r','a','w',' ') }, - { AV_CODEC_ID_PCM_S24BE, MKTAG('N','O','N','E') }, - { AV_CODEC_ID_PCM_S32BE, MKTAG('N','O','N','E') }, - { AV_CODEC_ID_PCM_F32BE, MKTAG('f','l','3','2') }, - { AV_CODEC_ID_PCM_F64BE, MKTAG('f','l','6','4') }, - { AV_CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') }, - { AV_CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') }, - { AV_CODEC_ID_PCM_S24BE, MKTAG('i','n','2','4') }, - { AV_CODEC_ID_PCM_S32BE, MKTAG('i','n','3','2') }, - { AV_CODEC_ID_MACE3, MKTAG('M','A','C','3') }, - { AV_CODEC_ID_MACE6, MKTAG('M','A','C','6') }, - { AV_CODEC_ID_GSM, MKTAG('G','S','M',' ') }, - { AV_CODEC_ID_ADPCM_G722, MKTAG('G','7','2','2') }, - { AV_CODEC_ID_ADPCM_G726LE, MKTAG('G','7','2','6') }, - { AV_CODEC_ID_PCM_S16BE, MKTAG('t','w','o','s') }, - { AV_CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') }, - { AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') }, - { AV_CODEC_ID_QDMC, MKTAG('Q','D','M','C') }, - { AV_CODEC_ID_QDM2, MKTAG('Q','D','M','2') }, - { AV_CODEC_ID_QCELP, MKTAG('Q','c','l','p') }, - { AV_CODEC_ID_SDX2_DPCM, MKTAG('S','D','X','2') }, - { AV_CODEC_ID_ADPCM_IMA_WS, MKTAG('A','D','P','4') }, - { AV_CODEC_ID_NONE, 0 }, -}; +extern const AVCodecTag ff_codec_aiff_tags[]; +extern const AVCodecTag *const ff_aiff_codec_tags_list[]; #endif /* AVFORMAT_AIFF_H */ diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index 4d1c9bbb5..dcaf1560b 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -20,13 +20,11 @@ */ #include "libavutil/intreadwrite.h" -#include "libavutil/mathematics.h" #include "libavutil/dict.h" #include "avformat.h" #include "internal.h" #include "pcm.h" #include "aiff.h" -#include "isom.h" #include "id3v2.h" #include "mov_chan.h" #include "replaygain.h" @@ -288,6 +286,8 @@ static int aiff_read_header(AVFormatContext *s) get_meta(s, "comment" , size); break; case MKTAG('S', 'S', 'N', 'D'): /* Sampled sound chunk */ + if (size < 8) + return AVERROR_INVALIDDATA; aiff->data_end = avio_tell(pb) + size; offset = avio_rb32(pb); /* Offset of sound data */ avio_rb32(pb); /* BlockSize... don't care */ @@ -432,5 +432,5 @@ AVInputFormat ff_aiff_demuxer = { .read_header = aiff_read_header, .read_packet = aiff_read_packet, .read_seek = ff_pcm_read_seek, - .codec_tag = (const AVCodecTag* const []){ ff_codec_aiff_tags, 0 }, + .codec_tag = ff_aiff_codec_tags_list, }; diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c index 88c45df33..06e475cdd 100644 --- a/libavformat/aiffenc.c +++ b/libavformat/aiffenc.c @@ -23,6 +23,7 @@ #include "libavutil/intfloat.h" #include "libavutil/opt.h" +#include "libavcodec/packet_internal.h" #include "avformat.h" #include "internal.h" #include "aiff.h" @@ -36,7 +37,7 @@ typedef struct AIFFOutputContext { int64_t frames; int64_t ssnd; int audio_stream_idx; - AVPacketList *pict_list, *pict_list_end; + PacketList *pict_list, *pict_list_end; int write_id3v2; int id3v2_version; } AIFFOutputContext; @@ -47,7 +48,7 @@ static int put_id3v2_tags(AVFormatContext *s, AIFFOutputContext *aiff) uint64_t pos, end, size; ID3v2EncContext id3v2 = { 0 }; AVIOContext *pb = s->pb; - AVPacketList *pict_list = aiff->pict_list; + PacketList *pict_list = aiff->pict_list; if (!s->metadata && !s->nb_chapters && !aiff->pict_list) return 0; @@ -220,8 +221,8 @@ static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt) if (s->streams[pkt->stream_index]->nb_frames >= 1) return 0; - return ff_packet_list_put(&aiff->pict_list, &aiff->pict_list_end, - pkt, FF_PACKETLIST_FLAG_REF_PACKET); + return avpriv_packet_list_put(&aiff->pict_list, &aiff->pict_list_end, + pkt, av_packet_ref, 0); } return 0; @@ -272,7 +273,7 @@ static void aiff_deinit(AVFormatContext *s) { AIFFOutputContext *aiff = s->priv_data; - ff_packet_list_free(&aiff->pict_list, &aiff->pict_list_end); + avpriv_packet_list_free(&aiff->pict_list, &aiff->pict_list_end); } #define OFFSET(x) offsetof(AIFFOutputContext, x) @@ -304,6 +305,6 @@ AVOutputFormat ff_aiff_muxer = { .write_packet = aiff_write_packet, .write_trailer = aiff_write_trailer, .deinit = aiff_deinit, - .codec_tag = (const AVCodecTag* const []){ ff_codec_aiff_tags, 0 }, + .codec_tag = ff_aiff_codec_tags_list, .priv_class = &aiff_muxer_class, }; diff --git a/libavformat/allformats.c b/libavformat/allformats.c index a7c5c9db8..a38fd1f58 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -31,8 +31,10 @@ extern AVOutputFormat ff_a64_muxer; extern AVInputFormat ff_aa_demuxer; extern AVInputFormat ff_aac_demuxer; +extern AVInputFormat ff_aax_demuxer; extern AVInputFormat ff_ac3_demuxer; extern AVOutputFormat ff_ac3_muxer; +extern AVInputFormat ff_ace_demuxer; extern AVInputFormat ff_acm_demuxer; extern AVInputFormat ff_act_demuxer; extern AVInputFormat ff_adf_demuxer; @@ -47,14 +49,17 @@ extern AVInputFormat ff_aiff_demuxer; extern AVOutputFormat ff_aiff_muxer; extern AVInputFormat ff_aix_demuxer; extern AVInputFormat ff_alp_demuxer; +extern AVOutputFormat ff_alp_muxer; extern AVInputFormat ff_amr_demuxer; extern AVOutputFormat ff_amr_muxer; extern AVInputFormat ff_amrnb_demuxer; extern AVInputFormat ff_amrwb_demuxer; +extern AVOutputFormat ff_amv_muxer; extern AVInputFormat ff_anm_demuxer; extern AVInputFormat ff_apc_demuxer; extern AVInputFormat ff_ape_demuxer; extern AVInputFormat ff_apm_demuxer; +extern AVOutputFormat ff_apm_muxer; extern AVInputFormat ff_apng_demuxer; extern AVOutputFormat ff_apng_muxer; extern AVInputFormat ff_aptx_demuxer; @@ -63,6 +68,8 @@ extern AVInputFormat ff_aptx_hd_demuxer; extern AVOutputFormat ff_aptx_hd_muxer; extern AVInputFormat ff_aqtitle_demuxer; extern AVInputFormat ff_argo_asf_demuxer; +extern AVOutputFormat ff_argo_asf_muxer; +extern AVInputFormat ff_argo_brp_demuxer; extern AVInputFormat ff_asf_demuxer; extern AVOutputFormat ff_asf_muxer; extern AVInputFormat ff_asf_o_demuxer; @@ -82,10 +89,12 @@ extern AVInputFormat ff_avr_demuxer; extern AVInputFormat ff_avs_demuxer; extern AVInputFormat ff_avs2_demuxer; extern AVOutputFormat ff_avs2_muxer; +extern AVInputFormat ff_avs3_demuxer; extern AVInputFormat ff_bethsoftvid_demuxer; extern AVInputFormat ff_bfi_demuxer; extern AVInputFormat ff_bintext_demuxer; extern AVInputFormat ff_bink_demuxer; +extern AVInputFormat ff_binka_demuxer; extern AVInputFormat ff_bit_demuxer; extern AVOutputFormat ff_bit_muxer; extern AVInputFormat ff_bmv_demuxer; @@ -207,6 +216,7 @@ extern AVInputFormat ff_image2_brender_pix_demuxer; extern AVInputFormat ff_ingenient_demuxer; extern AVInputFormat ff_ipmovie_demuxer; extern AVOutputFormat ff_ipod_muxer; +extern AVInputFormat ff_ipu_demuxer; extern AVInputFormat ff_ircam_demuxer; extern AVOutputFormat ff_ircam_muxer; extern AVOutputFormat ff_ismv_muxer; @@ -224,12 +234,15 @@ extern AVOutputFormat ff_kvag_muxer; extern AVOutputFormat ff_latm_muxer; extern AVInputFormat ff_lmlm4_demuxer; extern AVInputFormat ff_loas_demuxer; +extern AVInputFormat ff_luodat_demuxer; extern AVInputFormat ff_lrc_demuxer; extern AVOutputFormat ff_lrc_muxer; extern AVInputFormat ff_lvf_demuxer; extern AVInputFormat ff_lxf_demuxer; extern AVInputFormat ff_m4v_demuxer; extern AVOutputFormat ff_m4v_muxer; +extern AVInputFormat ff_mca_demuxer; +extern AVInputFormat ff_mcc_demuxer; extern AVOutputFormat ff_md5_muxer; extern AVInputFormat ff_matroska_demuxer; extern AVOutputFormat ff_matroska_muxer; @@ -246,6 +259,8 @@ extern AVInputFormat ff_mlv_demuxer; extern AVInputFormat ff_mm_demuxer; extern AVInputFormat ff_mmf_demuxer; extern AVOutputFormat ff_mmf_muxer; +extern AVInputFormat ff_mods_demuxer; +extern AVInputFormat ff_moflex_demuxer; extern AVInputFormat ff_mov_demuxer; extern AVOutputFormat ff_mov_muxer; extern AVOutputFormat ff_mp2_muxer; @@ -272,6 +287,7 @@ extern AVInputFormat ff_mpl2_demuxer; extern AVInputFormat ff_mpsub_demuxer; extern AVInputFormat ff_msf_demuxer; extern AVInputFormat ff_msnwc_tcp_demuxer; +extern AVInputFormat ff_msp_demuxer; extern AVInputFormat ff_mtaf_demuxer; extern AVInputFormat ff_mtv_demuxer; extern AVInputFormat ff_musx_demuxer; @@ -290,6 +306,7 @@ extern AVOutputFormat ff_null_muxer; extern AVInputFormat ff_nut_demuxer; extern AVOutputFormat ff_nut_muxer; extern AVInputFormat ff_nuv_demuxer; +extern AVInputFormat ff_obu_demuxer; extern AVOutputFormat ff_oga_muxer; extern AVInputFormat ff_ogg_demuxer; extern AVOutputFormat ff_ogg_muxer; @@ -384,8 +401,10 @@ extern AVOutputFormat ff_segafilm_muxer; extern AVOutputFormat ff_segment_muxer; extern AVOutputFormat ff_stream_segment_muxer; extern AVInputFormat ff_ser_demuxer; +extern AVInputFormat ff_sga_demuxer; extern AVInputFormat ff_shorten_demuxer; extern AVInputFormat ff_siff_demuxer; +extern AVInputFormat ff_simbiosis_imx_demuxer; extern AVOutputFormat ff_singlejpeg_muxer; extern AVInputFormat ff_sln_demuxer; extern AVInputFormat ff_smacker_demuxer; @@ -409,6 +428,7 @@ extern AVInputFormat ff_subviewer_demuxer; extern AVInputFormat ff_sup_demuxer; extern AVOutputFormat ff_sup_muxer; extern AVInputFormat ff_svag_demuxer; +extern AVInputFormat ff_svs_demuxer; extern AVInputFormat ff_swf_demuxer; extern AVOutputFormat ff_swf_muxer; extern AVInputFormat ff_tak_demuxer; @@ -425,6 +445,7 @@ extern AVInputFormat ff_truehd_demuxer; extern AVOutputFormat ff_truehd_muxer; extern AVInputFormat ff_tta_demuxer; extern AVOutputFormat ff_tta_muxer; +extern AVOutputFormat ff_ttml_muxer; extern AVInputFormat ff_txd_demuxer; extern AVInputFormat ff_tty_demuxer; extern AVInputFormat ff_ty_demuxer; @@ -475,6 +496,7 @@ extern AVInputFormat ff_yuv4mpegpipe_demuxer; extern AVOutputFormat ff_yuv4mpegpipe_muxer; /* image demuxers */ extern AVInputFormat ff_image_bmp_pipe_demuxer; +extern AVInputFormat ff_image_cri_pipe_demuxer; extern AVInputFormat ff_image_dds_pipe_demuxer; extern AVInputFormat ff_image_dpx_pipe_demuxer; extern AVInputFormat ff_image_exr_pipe_demuxer; @@ -487,6 +509,8 @@ extern AVInputFormat ff_image_pbm_pipe_demuxer; extern AVInputFormat ff_image_pcx_pipe_demuxer; extern AVInputFormat ff_image_pgmyuv_pipe_demuxer; extern AVInputFormat ff_image_pgm_pipe_demuxer; +extern AVInputFormat ff_image_pgx_pipe_demuxer; +extern AVInputFormat ff_image_photocd_pipe_demuxer; extern AVInputFormat ff_image_pictor_pipe_demuxer; extern AVInputFormat ff_image_png_pipe_demuxer; extern AVInputFormat ff_image_ppm_pipe_demuxer; @@ -497,6 +521,7 @@ extern AVInputFormat ff_image_svg_pipe_demuxer; extern AVInputFormat ff_image_sunrast_pipe_demuxer; extern AVInputFormat ff_image_tiff_pipe_demuxer; extern AVInputFormat ff_image_webp_pipe_demuxer; +extern AVInputFormat ff_image_xbm_pipe_demuxer; extern AVInputFormat ff_image_xpm_pipe_demuxer; extern AVInputFormat ff_image_xwd_pipe_demuxer; @@ -521,7 +546,7 @@ const AVOutputFormat *av_muxer_iterate(void **opaque) if (i < size) { f = muxer_list[i]; - } else if (indev_list) { + } else if (outdev_list) { f = outdev_list[i - size]; } @@ -538,7 +563,7 @@ const AVInputFormat *av_demuxer_iterate(void **opaque) if (i < size) { f = demuxer_list[i]; - } else if (outdev_list) { + } else if (indev_list) { f = indev_list[i - size]; } diff --git a/libavformat/alp.c b/libavformat/alp.c index e1da312b8..222cc246a 100644 --- a/libavformat/alp.c +++ b/libavformat/alp.c @@ -1,5 +1,5 @@ /* - * LEGO Racers ALP (.tun & .pcm) demuxer + * LEGO Racers ALP (.tun & .pcm) (de)muxer * * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com) * @@ -21,8 +21,10 @@ */ #include "avformat.h" #include "internal.h" +#include "rawenc.h" #include "libavutil/intreadwrite.h" #include "libavutil/internal.h" +#include "libavutil/opt.h" #define ALP_TAG MKTAG('A', 'L', 'P', ' ') #define ALP_MAX_READ_SIZE 4096 @@ -36,6 +38,18 @@ typedef struct ALPHeader { uint32_t sample_rate; /*< Sample rate, only if header_size >= 12. */ } ALPHeader; +typedef enum ALPType { + ALP_TYPE_AUTO = 0, /*< Autodetect based on file extension. */ + ALP_TYPE_TUN = 1, /*< Force a .TUN file. */ + ALP_TYPE_PCM = 2, /*< Force a .PCM file. */ +} ALPType; + +typedef struct ALPMuxContext { + const AVClass *class; + ALPType type; +} ALPMuxContext; + +#if CONFIG_ALP_DEMUXER static int alp_probe(const AVProbeData *p) { uint32_t i; @@ -58,38 +72,39 @@ static int alp_read_header(AVFormatContext *s) { int ret; AVStream *st; - ALPHeader hdr; + ALPHeader *hdr = s->priv_data; AVCodecParameters *par; - if ((hdr.magic = avio_rl32(s->pb)) != ALP_TAG) + if ((hdr->magic = avio_rl32(s->pb)) != ALP_TAG) return AVERROR_INVALIDDATA; - hdr.header_size = avio_rl32(s->pb); + hdr->header_size = avio_rl32(s->pb); - if (hdr.header_size != 8 && hdr.header_size != 12) { + if (hdr->header_size != 8 && hdr->header_size != 12) { return AVERROR_INVALIDDATA; } - if ((ret = avio_read(s->pb, hdr.adpcm, sizeof(hdr.adpcm))) < 0) + if ((ret = avio_read(s->pb, hdr->adpcm, sizeof(hdr->adpcm))) < 0) return ret; - else if (ret != sizeof(hdr.adpcm)) + else if (ret != sizeof(hdr->adpcm)) return AVERROR(EIO); - if (strncmp("ADPCM", hdr.adpcm, sizeof(hdr.adpcm)) != 0) + if (strncmp("ADPCM", hdr->adpcm, sizeof(hdr->adpcm)) != 0) return AVERROR_INVALIDDATA; - hdr.unk1 = avio_r8(s->pb); - hdr.num_channels = avio_r8(s->pb); + hdr->unk1 = avio_r8(s->pb); + hdr->num_channels = avio_r8(s->pb); - if (hdr.header_size == 8) { + if (hdr->header_size == 8) { /* .TUN music file */ - hdr.sample_rate = 22050; + hdr->sample_rate = 22050; + } else { /* .PCM sound file */ - hdr.sample_rate = avio_rl32(s->pb); + hdr->sample_rate = avio_rl32(s->pb); } - if (hdr.sample_rate > 44100) { + if (hdr->sample_rate > 44100) { avpriv_request_sample(s, "Sample Rate > 44100"); return AVERROR_PATCHWELCOME; } @@ -101,12 +116,12 @@ static int alp_read_header(AVFormatContext *s) par->codec_type = AVMEDIA_TYPE_AUDIO; par->codec_id = AV_CODEC_ID_ADPCM_IMA_ALP; par->format = AV_SAMPLE_FMT_S16; - par->sample_rate = hdr.sample_rate; - par->channels = hdr.num_channels; + par->sample_rate = hdr->sample_rate; + par->channels = hdr->num_channels; - if (hdr.num_channels == 1) + if (hdr->num_channels == 1) par->channel_layout = AV_CH_LAYOUT_MONO; - else if (hdr.num_channels == 2) + else if (hdr->num_channels == 2) par->channel_layout = AV_CH_LAYOUT_STEREO; else return AVERROR_INVALIDDATA; @@ -137,10 +152,155 @@ static int alp_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; } +static int alp_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + const ALPHeader *hdr = s->priv_data; + + if (pts != 0) + return AVERROR(EINVAL); + + return avio_seek(s->pb, hdr->header_size + 8, SEEK_SET); +} + AVInputFormat ff_alp_demuxer = { .name = "alp", .long_name = NULL_IF_CONFIG_SMALL("LEGO Racers ALP"), + .priv_data_size = sizeof(ALPHeader), .read_probe = alp_probe, .read_header = alp_read_header, - .read_packet = alp_read_packet + .read_packet = alp_read_packet, + .read_seek = alp_seek, }; +#endif + +#if CONFIG_ALP_MUXER + +static int alp_write_init(AVFormatContext *s) +{ + ALPMuxContext *alp = s->priv_data; + AVCodecParameters *par; + + if (alp->type == ALP_TYPE_AUTO) { + if (av_match_ext(s->url, "pcm")) + alp->type = ALP_TYPE_PCM; + else + alp->type = ALP_TYPE_TUN; + } + + if (s->nb_streams != 1) { + av_log(s, AV_LOG_ERROR, "Too many streams\n"); + return AVERROR(EINVAL); + } + + par = s->streams[0]->codecpar; + + if (par->codec_id != AV_CODEC_ID_ADPCM_IMA_ALP) { + av_log(s, AV_LOG_ERROR, "%s codec not supported\n", + avcodec_get_name(par->codec_id)); + return AVERROR(EINVAL); + } + + if (par->channels > 2) { + av_log(s, AV_LOG_ERROR, "A maximum of 2 channels are supported\n"); + return AVERROR(EINVAL); + } + + if (par->sample_rate > 44100) { + av_log(s, AV_LOG_ERROR, "Sample rate too large\n"); + return AVERROR(EINVAL); + } + + if (alp->type == ALP_TYPE_TUN && par->sample_rate != 22050) { + av_log(s, AV_LOG_ERROR, "Sample rate must be 22050 for TUN files\n"); + return AVERROR(EINVAL); + } + return 0; +} + +static int alp_write_header(AVFormatContext *s) +{ + ALPMuxContext *alp = s->priv_data; + AVCodecParameters *par = s->streams[0]->codecpar; + + avio_wl32(s->pb, ALP_TAG); + avio_wl32(s->pb, alp->type == ALP_TYPE_PCM ? 12 : 8); + avio_write(s->pb, "ADPCM", 6); + avio_w8(s->pb, 0); + avio_w8(s->pb, par->channels); + if (alp->type == ALP_TYPE_PCM) + avio_wl32(s->pb, par->sample_rate); + + return 0; +} + +enum { AE = AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }; + +static const AVOption alp_options[] = { + { + .name = "type", + .help = "set file type", + .offset = offsetof(ALPMuxContext, type), + .type = AV_OPT_TYPE_INT, + .default_val = {.i64 = ALP_TYPE_AUTO}, + .min = ALP_TYPE_AUTO, + .max = ALP_TYPE_PCM, + .flags = AE, + .unit = "type", + }, + { + .name = "auto", + .help = "autodetect based on file extension", + .offset = 0, + .type = AV_OPT_TYPE_CONST, + .default_val = {.i64 = ALP_TYPE_AUTO}, + .min = 0, + .max = 0, + .flags = AE, + .unit = "type" + }, + { + .name = "tun", + .help = "force .tun, used for music", + .offset = 0, + .type = AV_OPT_TYPE_CONST, + .default_val = {.i64 = ALP_TYPE_TUN}, + .min = 0, + .max = 0, + .flags = AE, + .unit = "type" + }, + { + .name = "pcm", + .help = "force .pcm, used for sfx", + .offset = 0, + .type = AV_OPT_TYPE_CONST, + .default_val = {.i64 = ALP_TYPE_PCM}, + .min = 0, + .max = 0, + .flags = AE, + .unit = "type" + }, + { NULL } +}; + +static const AVClass alp_muxer_class = { + .class_name = "alp", + .item_name = av_default_item_name, + .option = alp_options, + .version = LIBAVUTIL_VERSION_INT +}; + +AVOutputFormat ff_alp_muxer = { + .name = "alp", + .long_name = NULL_IF_CONFIG_SMALL("LEGO Racers ALP"), + .extensions = "tun,pcm", + .audio_codec = AV_CODEC_ID_ADPCM_IMA_ALP, + .video_codec = AV_CODEC_ID_NONE, + .init = alp_write_init, + .write_header = alp_write_header, + .write_packet = ff_raw_write_packet, + .priv_class = &alp_muxer_class, + .priv_data_size = sizeof(ALPMuxContext) +}; +#endif diff --git a/libavformat/amvenc.c b/libavformat/amvenc.c new file mode 100644 index 000000000..5d13b618f --- /dev/null +++ b/libavformat/amvenc.c @@ -0,0 +1,422 @@ +/* + * AMV muxer + * + * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.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 + */ +#include "avformat.h" +#include "riff.h" +#include "internal.h" +#include "avio_internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/avassert.h" + +/* + * Things to note: + * - AMV is a hard-coded (and broken) subset of AVI. It's not worth sullying the + * existing AVI muxer with its filth. + * - No separate demuxer as the existing AVI demuxer can handle these. + * - The sizes of certain tags are deliberately set to 0 as some players break + * when they're set correctly. Ditto with some header fields. + * - There is no index. + * - Players are **very** sensitive to the frame order and sizes. + * - Frames must be strictly interleaved as V-A, any V-V or A-A will + * cause crashes. + * - Variable video frame sizes seem to be handled fine. + * - Variable audio frame sizes cause crashes. + * - If audio is shorter than video, it's padded with silence. + * - If video is shorter than audio, the most recent frame is repeated. + */ + +#define AMV_STREAM_COUNT 2 +#define AMV_STREAM_VIDEO 0 +#define AMV_STREAM_AUDIO 1 +#define AMV_VIDEO_STRH_SIZE 56 +#define AMV_VIDEO_STRF_SIZE 36 +#define AMV_AUDIO_STRH_SIZE 48 +#define AMV_AUDIO_STRF_SIZE 20 /* sizeof(WAVEFORMATEX) + 2 */ + +typedef struct AMVContext +{ + int64_t riff_start; + int64_t movi_list; + int64_t offset_duration; + int last_stream; + + int32_t us_per_frame; /* Microseconds per frame. */ + + int32_t aframe_size; /* Expected audio frame size. */ + int32_t ablock_align; /* Expected audio block align. */ + AVPacket *apad; /* Dummy audio packet for padding. */ + AVPacket *vpad; /* Most recent video frame, for padding. */ + + /* + * Cumulative PTS values for each stream, used for the final + * duration calculcation. + */ + int64_t lastpts[AMV_STREAM_COUNT]; +} AMVContext; + +/* ff_{start,end}_tag(), but sets the size to 0. */ +static int64_t amv_start_tag(AVIOContext *pb, const char *tag) +{ + ffio_wfourcc(pb, tag); + avio_wl32(pb, 0); + return avio_tell(pb); +} + +static void amv_end_tag(AVIOContext *pb, int64_t start) +{ + int64_t pos; + av_assert0((start&1) == 0); + + pos = avio_tell(pb); + if (pos & 1) + avio_w8(pb, 0); +} + +static av_cold int amv_init(AVFormatContext *s) +{ + AMVContext *amv = s->priv_data; + AVStream *vst, *ast; + int ret; + + amv->last_stream = -1; + + if (s->nb_streams != AMV_STREAM_COUNT) { + av_log(s, AV_LOG_ERROR, "AMV files only support 2 streams\n"); + return AVERROR(EINVAL); + } + + vst = s->streams[AMV_STREAM_VIDEO]; + ast = s->streams[AMV_STREAM_AUDIO]; + + if (vst->codecpar->codec_id != AV_CODEC_ID_AMV) { + av_log(s, AV_LOG_ERROR, "First AMV stream must be %s\n", + avcodec_get_name(AV_CODEC_ID_AMV)); + return AVERROR(EINVAL); + } + + if (ast->codecpar->codec_id != AV_CODEC_ID_ADPCM_IMA_AMV) { + av_log(s, AV_LOG_ERROR, "Second AMV stream must be %s\n", + avcodec_get_name(AV_CODEC_ID_ADPCM_IMA_AMV)); + return AVERROR(EINVAL); + } + + /* These files are broken-enough as they are. They shouldn't be streamed. */ + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { + av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n"); + return AVERROR(EINVAL); + } + + amv->us_per_frame = av_rescale(AV_TIME_BASE, vst->time_base.num, vst->time_base.den); + amv->aframe_size = av_rescale(ast->codecpar->sample_rate, amv->us_per_frame, AV_TIME_BASE); + amv->ablock_align = 8 + (FFALIGN(amv->aframe_size, 2) / 2); + + av_log(s, AV_LOG_TRACE, "us_per_frame = %d\n", amv->us_per_frame); + av_log(s, AV_LOG_TRACE, "aframe_size = %d\n", amv->aframe_size); + av_log(s, AV_LOG_TRACE, "ablock_align = %d\n", amv->ablock_align); + + /* + * Bail if the framerate's too high. Prevents the audio frame size from + * getting too small. 63fps is the closest value to 60fps that divides + * cleanly, so cap it there. + */ + if (amv->us_per_frame < 15873) { + av_log(s, AV_LOG_ERROR, "Refusing to mux >63fps video\n"); + return AVERROR(EINVAL); + } + + /* + * frame_size will be set if coming from the encoder. + * Make sure the its been configured correctly. The audio frame duration + * needs to match that of the video. + */ + if (ast->codecpar->frame_size) { + AVCodecParameters *par = ast->codecpar; + int bad = 0; + + if (par->frame_size != amv->aframe_size) { + av_log(s, AV_LOG_ERROR, "Invalid audio frame size. Got %d, wanted %d\n", + par->frame_size, amv->aframe_size); + bad = 1; + } + + if (par->block_align != amv->ablock_align) { + av_log(s, AV_LOG_ERROR, "Invalid audio block align. Got %d, wanted %d\n", + par->block_align, amv->ablock_align); + bad = 1; + } + + if (bad) { + av_log(s, AV_LOG_ERROR, "Try -block_size %d\n", amv->aframe_size); + return AVERROR(EINVAL); + } + + if (ast->codecpar->sample_rate % amv->aframe_size) { + av_log(s, AV_LOG_ERROR, "Audio sample rate not a multiple of the frame size.\n" + "Please change video frame rate. Suggested rates: 10,14,15,18,21,25,30\n"); + return AVERROR(EINVAL); + } + } else { + /* If remuxing from the same source, then this will match the video. */ + int32_t aus = av_rescale(AV_TIME_BASE, ast->time_base.num, ast->time_base.den); + if (aus != amv->us_per_frame) { + av_log(s, AV_LOG_ERROR, "Cannot remux streams with a different time base\n"); + return AVERROR(EINVAL); + } + } + + /* Allocate and fill dummy packet so we can pad the audio. */ + amv->apad = av_packet_alloc(); + if (!amv->apad) + return AVERROR(ENOMEM); + if ((ret = av_new_packet(amv->apad, amv->ablock_align)) < 0) { + av_packet_free(&amv->apad); + return ret; + } + + amv->apad->stream_index = AMV_STREAM_AUDIO; + memset(amv->apad->data, 0, amv->ablock_align); + AV_WL32(amv->apad->data + 4, amv->aframe_size); + + amv->vpad = av_packet_alloc(); + if (!amv->vpad) { + av_packet_free(&amv->apad); + return AVERROR(ENOMEM); + } + amv->vpad->stream_index = AMV_STREAM_VIDEO; + amv->vpad->duration = 1; + return 0; +} + +static void amv_deinit(AVFormatContext *s) +{ + AMVContext *amv = s->priv_data; + + av_packet_free(&amv->apad); + av_packet_free(&amv->vpad); +} + +static void amv_write_vlist(AVFormatContext *s, AVCodecParameters *par) +{ + int64_t tag_list, tag_str; + + av_assert0(par->codec_id == AV_CODEC_ID_AMV); + + tag_list = amv_start_tag(s->pb, "LIST"); + ffio_wfourcc(s->pb, "strl"); + tag_str = ff_start_tag(s->pb, "strh"); + ffio_fill(s->pb, 0, AMV_VIDEO_STRH_SIZE); + ff_end_tag(s->pb, tag_str); + + tag_str = ff_start_tag(s->pb, "strf"); + ffio_fill(s->pb, 0, AMV_VIDEO_STRF_SIZE); + ff_end_tag(s->pb, tag_str); + + amv_end_tag(s->pb, tag_list); +} + +static void amv_write_alist(AVFormatContext *s, AVCodecParameters *par) +{ + uint8_t buf[AMV_AUDIO_STRF_SIZE]; + AVIOContext *pb = s->pb; + int64_t tag_list, tag_str; + + av_assert0(par->codec_id == AV_CODEC_ID_ADPCM_IMA_AMV); + + tag_list = amv_start_tag(pb, "LIST"); + ffio_wfourcc(pb, "strl"); + tag_str = ff_start_tag(pb, "strh"); + ffio_fill(s->pb, 0, AMV_AUDIO_STRH_SIZE); + ff_end_tag(pb, tag_str); + + /* Bodge an (incorrect) WAVEFORMATEX (+2 pad bytes) */ + tag_str = ff_start_tag(pb, "strf"); + AV_WL16(buf + 0, 1); + AV_WL16(buf + 2, par->channels); + AV_WL32(buf + 4, par->sample_rate); + AV_WL32(buf + 8, par->sample_rate * par->channels * 2); + AV_WL16(buf + 12, 2); + AV_WL16(buf + 14, 16); + AV_WL16(buf + 16, 0); + AV_WL16(buf + 18, 0); + avio_write(pb, buf, AMV_AUDIO_STRF_SIZE); + ff_end_tag(pb, tag_str); + + amv_end_tag(pb, tag_list); +} + +static int amv_write_header(AVFormatContext *s) +{ + AMVContext *amv = s->priv_data; + AVIOContext *pb = s->pb; + AVStream *vst = s->streams[AMV_STREAM_VIDEO]; + AVStream *ast = s->streams[AMV_STREAM_AUDIO]; + uint8_t amvh[56] = {0}; + int64_t list1; + + amv->riff_start = amv_start_tag(pb, "RIFF"); + ffio_wfourcc(pb, "AMV "); + list1 = amv_start_tag(pb, "LIST"); + ffio_wfourcc(pb, "hdrl"); + + ffio_wfourcc(pb, "amvh"); + avio_wl32(pb, 56); + + AV_WL32(amvh + 0, amv->us_per_frame); + AV_WL32(amvh + 32, vst->codecpar->width); + AV_WL32(amvh + 36, vst->codecpar->height); + AV_WL32(amvh + 40, vst->time_base.den); + AV_WL32(amvh + 44, vst->time_base.num); + AV_WL32(amvh + 48, 0); + AV_WL32(amvh + 52, 0); /* duration, filled in later. */ + + avio_write(pb, amvh, sizeof(amvh)); + amv->offset_duration = avio_tell(pb) - 4; + + amv_write_vlist(s, vst->codecpar); + amv_write_alist(s, ast->codecpar); + amv_end_tag(pb, list1); + + amv->movi_list = amv_start_tag(pb, "LIST"); + ffio_wfourcc(pb, "movi"); + return 0; +} + +static int amv_write_packet_internal(AVFormatContext *s, AVPacket *pkt) +{ + AMVContext *amv = s->priv_data; + + if (pkt->stream_index == AMV_STREAM_VIDEO) + ffio_wfourcc(s->pb, "00dc"); + else if (pkt->stream_index == AMV_STREAM_AUDIO) + ffio_wfourcc(s->pb, "01wb"); + else + av_assert0(0); + + if (pkt->stream_index == AMV_STREAM_AUDIO && pkt->size != amv->ablock_align) { + /* Can happen when remuxing files produced by another encoder. */ + av_log(s, AV_LOG_WARNING, "Invalid audio packet size (%d != %d)\n", + pkt->size, amv->ablock_align); + } + + avio_wl32(s->pb, pkt->size); + avio_write(s->pb, pkt->data, pkt->size); + + amv->lastpts[pkt->stream_index] += pkt->duration; + amv->last_stream = pkt->stream_index; + return 0; +} + +static int amv_pad(AVFormatContext *s, AVPacket *pkt) +{ + AMVContext *amv = s->priv_data; + int stream_index = pkt->stream_index; + + if (stream_index != amv->last_stream) + return 0; + + stream_index = (stream_index + 1) % s->nb_streams; + if (stream_index == AMV_STREAM_VIDEO) + return amv_write_packet_internal(s, amv->vpad); + else if (stream_index == AMV_STREAM_AUDIO) + return amv_write_packet_internal(s, amv->apad); + else + av_assert0(0); + + return AVERROR(EINVAL); +} + +static int amv_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + AMVContext *amv = s->priv_data; + int ret; + + /* Add a dummy frame if we've received two of the same index. */ + if ((ret = amv_pad(s, pkt)) < 0) + return ret; + + if ((ret = amv_write_packet_internal(s, pkt)) < 0) + return ret; + + if (pkt->stream_index == AMV_STREAM_VIDEO) { + /* Save the last packet for padding. */ + av_packet_unref(amv->vpad); + if ((ret = av_packet_ref(amv->vpad, pkt)) < 0) + return ret; + } + + return 0; +} + +static int amv_write_trailer(AVFormatContext *s) +{ + AMVContext *amv = s->priv_data; + AVStream *vst = s->streams[AMV_STREAM_VIDEO]; + AVStream *ast = s->streams[AMV_STREAM_AUDIO]; + int64_t maxpts, ret; + int hh, mm, ss; + + /* Pad-out one last audio frame if needed. */ + if (amv->last_stream == AMV_STREAM_VIDEO) { + if ((ret = amv_write_packet_internal(s, amv->apad)) < 0) + return ret; + } + + amv_end_tag(s->pb, amv->movi_list); + amv_end_tag(s->pb, amv->riff_start); + + ffio_wfourcc(s->pb, "AMV_"); + ffio_wfourcc(s->pb, "END_"); + + if ((ret = avio_seek(s->pb, amv->offset_duration, SEEK_SET)) < 0) + return ret; + + /* Go back and write the duration. */ + maxpts = FFMAX( + av_rescale_q(amv->lastpts[AMV_STREAM_VIDEO], vst->time_base, AV_TIME_BASE_Q), + av_rescale_q(amv->lastpts[AMV_STREAM_AUDIO], ast->time_base, AV_TIME_BASE_Q) + ); + + ss = maxpts / AV_TIME_BASE; + mm = ss / 60; + hh = mm / 60; + ss %= 60; + mm %= 60; + + avio_w8(s->pb, ss); + avio_w8(s->pb, mm); + avio_wl16(s->pb, hh); + return 0; +} + +AVOutputFormat ff_amv_muxer = { + .name = "amv", + .long_name = NULL_IF_CONFIG_SMALL("AMV"), + .mime_type = "video/amv", + .extensions = "amv", + .priv_data_size = sizeof(AMVContext), + .audio_codec = AV_CODEC_ID_ADPCM_IMA_AMV, + .video_codec = AV_CODEC_ID_AMV, + .init = amv_init, + .deinit = amv_deinit, + .write_header = amv_write_header, + .write_packet = amv_write_packet, + .write_trailer = amv_write_trailer, +}; diff --git a/libavformat/ape.c b/libavformat/ape.c index d92cb2867..2698c770e 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -77,10 +77,6 @@ typedef struct APEContext { uint16_t bps; uint16_t channels; uint32_t samplerate; - - /* Seektable */ - uint32_t *seektable; - uint8_t *bittable; } APEContext; static int ape_read_close(AVFormatContext * s); @@ -130,20 +126,6 @@ static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx) av_log(s, AV_LOG_DEBUG, "\nSeektable\n\n"); if ((ape_ctx->seektablelength / sizeof(uint32_t)) != ape_ctx->totalframes) { av_log(s, AV_LOG_DEBUG, "No seektable\n"); - } else { - for (i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++) { - if (i < ape_ctx->totalframes - 1) { - av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32" (%"PRIu32" bytes)", - i, ape_ctx->seektable[i], - ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]); - if (ape_ctx->bittable) - av_log(s, AV_LOG_DEBUG, " + %2d bits\n", - ape_ctx->bittable[i]); - av_log(s, AV_LOG_DEBUG, "\n"); - } else { - av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32"\n", i, ape_ctx->seektable[i]); - } - } } av_log(s, AV_LOG_DEBUG, "\nFrames\n\n"); @@ -262,10 +244,10 @@ static int ape_read_header(AVFormatContext * s) ape->totalframes); return AVERROR_INVALIDDATA; } - if (ape->seektablelength / sizeof(*ape->seektable) < ape->totalframes) { + if (ape->seektablelength / sizeof(uint32_t) < ape->totalframes) { av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %"SIZE_SPECIFIER" vs. %"PRIu32"\n", - ape->seektablelength / sizeof(*ape->seektable), ape->totalframes); + ape->seektablelength / sizeof(uint32_t), ape->totalframes); return AVERROR_INVALIDDATA; } ape->frames = av_malloc_array(ape->totalframes, sizeof(APEFrame)); @@ -281,39 +263,26 @@ static int ape_read_header(AVFormatContext * s) if (ape->totalframes > 1) ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1); - if (ape->seektablelength > 0) { - ape->seektable = av_mallocz(ape->seektablelength); - if (!ape->seektable) { - ret = AVERROR(ENOMEM); - goto fail; - } - for (i = 0; i < ape->seektablelength / sizeof(uint32_t) && !pb->eof_reached; i++) - ape->seektable[i] = avio_rl32(pb); - if (ape->fileversion < 3810) { - ape->bittable = av_mallocz(ape->totalframes); - if (!ape->bittable) { - ret = AVERROR(ENOMEM); - goto fail; - } - for (i = 0; i < ape->totalframes && !pb->eof_reached; i++) - ape->bittable[i] = avio_r8(pb); - } - if (pb->eof_reached) { - av_log(s, AV_LOG_ERROR, "File truncated\n"); - ret = AVERROR_INVALIDDATA; - goto fail; - } - } - ape->frames[0].pos = ape->firstframe; ape->frames[0].nblocks = ape->blocksperframe; ape->frames[0].skip = 0; + avio_rl32(pb); // seektable[0] for (i = 1; i < ape->totalframes; i++) { - ape->frames[i].pos = ape->seektable[i] + ape->junklength; + uint32_t seektable_entry = avio_rl32(pb); + ape->frames[i].pos = seektable_entry + ape->junklength; ape->frames[i].nblocks = ape->blocksperframe; ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; + + if (pb->eof_reached) { + av_log(s, AV_LOG_ERROR, "seektable truncated\n"); + ret = AVERROR_INVALIDDATA; + goto fail; + } + ff_dlog(s, "seektable: %8d %"PRIu32"\n", i, seektable_entry); } + avio_skip(pb, ape->seektablelength / sizeof(uint32_t) - ape->totalframes); + ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks; /* calculate final packet size from total file size, if available */ file_size = avio_size(pb); @@ -335,10 +304,18 @@ static int ape_read_header(AVFormatContext * s) } if (ape->fileversion < 3810) { for (i = 0; i < ape->totalframes; i++) { - if (i < ape->totalframes - 1 && ape->bittable[i + 1]) - ape->frames[i].size += 4; + int bits = avio_r8(pb); + if (i && bits) + ape->frames[i - 1].size += 4; + ape->frames[i].skip <<= 3; - ape->frames[i].skip += ape->bittable[i]; + ape->frames[i].skip += bits; + ff_dlog(s, "bittable: %2d\n", bits); + if (pb->eof_reached) { + av_log(s, AV_LOG_ERROR, "bittable truncated\n"); + ret = AVERROR_INVALIDDATA; + goto fail; + } } } @@ -454,8 +431,6 @@ static int ape_read_close(AVFormatContext * s) APEContext *ape = s->priv_data; av_freep(&ape->frames); - av_freep(&ape->seektable); - av_freep(&ape->bittable); return 0; } diff --git a/libavformat/apm.c b/libavformat/apm.c index 9d2a856cc..38a0f6382 100644 --- a/libavformat/apm.c +++ b/libavformat/apm.c @@ -1,5 +1,5 @@ /* - * Rayman 2 APM Demuxer + * Rayman 2 APM (De)muxer * * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com) * @@ -21,14 +21,18 @@ */ #include "avformat.h" #include "internal.h" -#include "riff.h" +#include "rawenc.h" +#include "libavutil/avassert.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #define APM_FILE_HEADER_SIZE 20 -#define APM_VS12_CHUNK_SIZE 76 +#define APM_FILE_EXTRADATA_SIZE 80 +#define APM_EXTRADATA_SIZE 28 + #define APM_MAX_READ_SIZE 4096 +#define APM_TAG_CODEC 0x2000 #define APM_TAG_VS12 MKTAG('v', 's', '1', '2') #define APM_TAG_DATA MKTAG('D', 'A', 'T', 'A') @@ -42,38 +46,45 @@ typedef struct APMState { int32_t saved_l; } APMState; -typedef struct APMVS12Chunk { +typedef struct APMExtraData { uint32_t magic; uint32_t file_size; uint32_t data_size; uint32_t unk1; uint32_t unk2; APMState state; - uint32_t pad[7]; -} APMVS12Chunk; + uint32_t unk3[7]; + uint32_t data; +} APMExtraData; -static void apm_parse_vs12(APMVS12Chunk *vs12, const uint8_t *buf) +#if CONFIG_APM_DEMUXER +static void apm_parse_extradata(APMExtraData *ext, const uint8_t *buf) { - vs12->magic = AV_RL32(buf + 0); - vs12->file_size = AV_RL32(buf + 4); - vs12->data_size = AV_RL32(buf + 8); - vs12->unk1 = AV_RL32(buf + 12); - vs12->unk2 = AV_RL32(buf + 16); + ext->magic = AV_RL32(buf + 0); + ext->file_size = AV_RL32(buf + 4); + ext->data_size = AV_RL32(buf + 8); + ext->unk1 = AV_RL32(buf + 12); + ext->unk2 = AV_RL32(buf + 16); - vs12->state.has_saved = AV_RL32(buf + 20); - vs12->state.predictor_r = AV_RL32(buf + 24); - vs12->state.step_index_r = AV_RL32(buf + 28); - vs12->state.saved_r = AV_RL32(buf + 32); - vs12->state.predictor_l = AV_RL32(buf + 36); - vs12->state.step_index_l = AV_RL32(buf + 40); - vs12->state.saved_l = AV_RL32(buf + 44); + ext->state.has_saved = AV_RL32(buf + 20); + ext->state.predictor_r = AV_RL32(buf + 24); + ext->state.step_index_r = AV_RL32(buf + 28); + ext->state.saved_r = AV_RL32(buf + 32); + ext->state.predictor_l = AV_RL32(buf + 36); + ext->state.step_index_l = AV_RL32(buf + 40); + ext->state.saved_l = AV_RL32(buf + 44); - for (int i = 0; i < FF_ARRAY_ELEMS(vs12->pad); i++) - vs12->pad[i] = AV_RL32(buf + 48 + (i * 4)); + for (int i = 0; i < FF_ARRAY_ELEMS(ext->unk3); i++) + ext->unk3[i] = AV_RL32(buf + 48 + (i * 4)); + + ext->data = AV_RL32(buf + 76); } static int apm_probe(const AVProbeData *p) { + if (AV_RL16(p->buf) != APM_TAG_CODEC) + return 0; + if (p->buf_size < 100) return 0; @@ -90,71 +101,82 @@ static int apm_read_header(AVFormatContext *s) { int64_t ret; AVStream *st; - APMVS12Chunk vs12; - uint8_t buf[APM_VS12_CHUNK_SIZE]; + APMExtraData extradata; + AVCodecParameters *par; + uint8_t buf[APM_FILE_EXTRADATA_SIZE]; if (!(st = avformat_new_stream(s, NULL))) return AVERROR(ENOMEM); - /* The header starts with a WAVEFORMATEX */ - if ((ret = ff_get_wav_header(s, s->pb, st->codecpar, APM_FILE_HEADER_SIZE, 0)) < 0) + /* + * This is 98% a WAVEFORMATEX, but there's something screwy with the extradata + * that ff_get_wav_header() can't (and shouldn't) handle properly. + */ + if (avio_rl16(s->pb) != APM_TAG_CODEC) + return AVERROR_INVALIDDATA; + + par = st->codecpar; + par->channels = avio_rl16(s->pb); + par->sample_rate = avio_rl32(s->pb); + + /* Skip the bitrate, it's usually wrong anyway. */ + if ((ret = avio_skip(s->pb, 4)) < 0) return ret; - if (st->codecpar->bits_per_coded_sample != 4) + par->block_align = avio_rl16(s->pb); + par->bits_per_coded_sample = avio_rl16(s->pb); + + if (avio_rl32(s->pb) != APM_FILE_EXTRADATA_SIZE) return AVERROR_INVALIDDATA; - if (st->codecpar->codec_tag != 0x2000) + /* 8 = bits per sample * max channels */ + if (par->sample_rate > (INT_MAX / 8)) return AVERROR_INVALIDDATA; - /* ff_get_wav_header() does most of the work, but we need to fix a few things. */ - st->codecpar->codec_id = AV_CODEC_ID_ADPCM_IMA_APM; - st->codecpar->codec_tag = 0; + if (par->bits_per_coded_sample != 4) + return AVERROR_INVALIDDATA; - if (st->codecpar->channels == 2) - st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; - else if (st->codecpar->channels == 1) - st->codecpar->channel_layout = AV_CH_LAYOUT_MONO; + if (par->channels == 2) + par->channel_layout = AV_CH_LAYOUT_STEREO; + else if (par->channels == 1) + par->channel_layout = AV_CH_LAYOUT_MONO; else return AVERROR_INVALIDDATA; - st->codecpar->format = AV_SAMPLE_FMT_S16; - st->codecpar->bits_per_raw_sample = 16; - st->codecpar->bit_rate = st->codecpar->channels * - st->codecpar->sample_rate * - st->codecpar->bits_per_coded_sample; + par->codec_type = AVMEDIA_TYPE_AUDIO; + par->codec_id = AV_CODEC_ID_ADPCM_IMA_APM; + par->format = AV_SAMPLE_FMT_S16; + par->bits_per_raw_sample = 16; + par->bit_rate = par->channels * + par->sample_rate * + par->bits_per_coded_sample; - if ((ret = avio_read(s->pb, buf, APM_VS12_CHUNK_SIZE)) < 0) + if ((ret = avio_read(s->pb, buf, APM_FILE_EXTRADATA_SIZE)) < 0) return ret; - else if (ret != APM_VS12_CHUNK_SIZE) + else if (ret != APM_FILE_EXTRADATA_SIZE) return AVERROR(EIO); - apm_parse_vs12(&vs12, buf); + apm_parse_extradata(&extradata, buf); - if (vs12.magic != APM_TAG_VS12) { + if (extradata.magic != APM_TAG_VS12 || extradata.data != APM_TAG_DATA) return AVERROR_INVALIDDATA; - } - if (vs12.state.has_saved) { + if (extradata.state.has_saved) { avpriv_request_sample(s, "Saved Samples"); return AVERROR_PATCHWELCOME; } - if (avio_rl32(s->pb) != APM_TAG_DATA) - return AVERROR_INVALIDDATA; - - if ((ret = ff_alloc_extradata(st->codecpar, 16)) < 0) + if ((ret = ff_alloc_extradata(par, APM_EXTRADATA_SIZE)) < 0) return ret; - AV_WL32(st->codecpar->extradata + 0, vs12.state.predictor_l); - AV_WL32(st->codecpar->extradata + 4, vs12.state.step_index_l); - AV_WL32(st->codecpar->extradata + 8, vs12.state.predictor_r); - AV_WL32(st->codecpar->extradata + 12, vs12.state.step_index_r); + /* Use the entire state as extradata. */ + memcpy(par->extradata, buf + 20, APM_EXTRADATA_SIZE); - avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); + avpriv_set_pts_info(st, 64, 1, par->sample_rate); st->start_time = 0; - st->duration = vs12.data_size * - (8 / st->codecpar->bits_per_coded_sample) / - st->codecpar->channels; + st->duration = extradata.data_size * + (8 / par->bits_per_coded_sample) / + par->channels; return 0; } @@ -186,3 +208,110 @@ AVInputFormat ff_apm_demuxer = { .read_header = apm_read_header, .read_packet = apm_read_packet }; +#endif + +#if CONFIG_APM_MUXER +static int apm_write_init(AVFormatContext *s) +{ + AVCodecParameters *par; + + if (s->nb_streams != 1) { + av_log(s, AV_LOG_ERROR, "APM files have exactly one stream\n"); + return AVERROR(EINVAL); + } + + par = s->streams[0]->codecpar; + + if (par->codec_id != AV_CODEC_ID_ADPCM_IMA_APM) { + av_log(s, AV_LOG_ERROR, "%s codec not supported\n", + avcodec_get_name(par->codec_id)); + return AVERROR(EINVAL); + } + + if (par->channels > 2) { + av_log(s, AV_LOG_ERROR, "APM files only support up to 2 channels\n"); + return AVERROR(EINVAL); + } + + if (par->sample_rate > (INT_MAX / 8)) { + av_log(s, AV_LOG_ERROR, "Sample rate too large\n"); + return AVERROR(EINVAL); + } + + if (par->extradata_size != APM_EXTRADATA_SIZE) { + av_log(s, AV_LOG_ERROR, "Invalid/missing extradata\n"); + return AVERROR(EINVAL); + } + + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { + av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n"); + return AVERROR(EINVAL); + } + + return 0; +} + +static int apm_write_header(AVFormatContext *s) +{ + uint8_t buf[APM_FILE_EXTRADATA_SIZE] = { 0 }; + AVCodecParameters *par = s->streams[0]->codecpar; + + /* + * Bodge a WAVEFORMATEX manually, ff_put_wav_header() can't + * be used because of the extra 2 bytes. + */ + avio_wl16(s->pb, APM_TAG_CODEC); + avio_wl16(s->pb, par->channels); + avio_wl32(s->pb, par->sample_rate); + /* This is the wrong calculation, but it's what the orginal files have. */ + avio_wl32(s->pb, par->sample_rate * par->channels * 2); + avio_wl16(s->pb, par->block_align); + avio_wl16(s->pb, par->bits_per_coded_sample); + avio_wl32(s->pb, APM_FILE_EXTRADATA_SIZE); + + /* + * Build the extradata. Assume the codec's given us correct data. + * File and data sizes are fixed later. + */ + AV_WL32(buf + 0, APM_TAG_VS12); /* magic */ + AV_WL32(buf + 12, 0xFFFFFFFF); /* unk1 */ + memcpy( buf + 20, par->extradata, APM_EXTRADATA_SIZE); + AV_WL32(buf + 76, APM_TAG_DATA); /* data */ + + avio_write(s->pb, buf, APM_FILE_EXTRADATA_SIZE); + return 0; +} + +static int apm_write_trailer(AVFormatContext *s) +{ + int64_t file_size, data_size; + + file_size = avio_tell(s->pb); + data_size = file_size - (APM_FILE_HEADER_SIZE + APM_FILE_EXTRADATA_SIZE); + + if (file_size >= UINT32_MAX) { + av_log(s, AV_LOG_ERROR, + "Filesize %"PRId64" invalid for APM, output file will be broken\n", + file_size); + return AVERROR(ERANGE); + } + + avio_seek(s->pb, 24, SEEK_SET); + avio_wl32(s->pb, (uint32_t)file_size); + avio_wl32(s->pb, (uint32_t)data_size); + + return 0; +} + +AVOutputFormat ff_apm_muxer = { + .name = "apm", + .long_name = NULL_IF_CONFIG_SMALL("Ubisoft Rayman 2 APM"), + .extensions = "apm", + .audio_codec = AV_CODEC_ID_ADPCM_IMA_APM, + .video_codec = AV_CODEC_ID_NONE, + .init = apm_write_init, + .write_header = apm_write_header, + .write_packet = ff_raw_write_packet, + .write_trailer = apm_write_trailer +}; +#endif diff --git a/libavformat/apngdec.c b/libavformat/apngdec.c index 0f1d04a36..bf8343faf 100644 --- a/libavformat/apngdec.c +++ b/libavformat/apngdec.c @@ -127,7 +127,7 @@ static int append_extradata(AVCodecParameters *par, AVIOContext *pb, int len) int new_size, ret; uint8_t *new_extradata; - if (previous_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - len) + if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - previous_size) return AVERROR_INVALIDDATA; new_size = previous_size + len; @@ -138,7 +138,7 @@ static int append_extradata(AVCodecParameters *par, AVIOContext *pb, int len) par->extradata = new_extradata; par->extradata_size = new_size; - if ((ret = avio_read(pb, par->extradata + previous_size, len)) < 0) + if ((ret = ffio_read_size(pb, par->extradata + previous_size, len)) < 0) return ret; return previous_size; @@ -151,17 +151,17 @@ static int apng_read_header(AVFormatContext *s) uint32_t len, tag; AVStream *st; int acTL_found = 0; - int64_t ret = AVERROR_INVALIDDATA; + int64_t ret; /* verify PNGSIG */ if (avio_rb64(pb) != PNGSIG) - return ret; + return AVERROR_INVALIDDATA; /* parse IHDR (must be first chunk) */ len = avio_rb32(pb); tag = avio_rl32(pb); if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R')) - return ret; + return AVERROR_INVALIDDATA; st = avformat_new_stream(s, NULL); if (!st) @@ -185,19 +185,17 @@ static int apng_read_header(AVFormatContext *s) AV_WL32(st->codecpar->extradata+4, tag); AV_WB32(st->codecpar->extradata+8, st->codecpar->width); AV_WB32(st->codecpar->extradata+12, st->codecpar->height); - if ((ret = avio_read(pb, st->codecpar->extradata+16, 9)) < 0) - goto fail; + if ((ret = ffio_read_size(pb, st->codecpar->extradata + 16, 9)) < 0) + return ret; - while (!avio_feof(pb)) { + while (1) { if (acTL_found && ctx->num_play != 1) { int64_t size = avio_size(pb); int64_t offset = avio_tell(pb); if (size < 0) { - ret = size; - goto fail; + return size; } else if (offset < 0) { - ret = offset; - goto fail; + return offset; } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) { av_log(s, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n"); ctx->num_play = 1; @@ -205,20 +203,18 @@ static int apng_read_header(AVFormatContext *s) } if ((ctx->num_play == 1 || !acTL_found) && ((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0)) - goto fail; + return ret; len = avio_rb32(pb); - if (len > 0x7fffffff) { - ret = AVERROR_INVALIDDATA; - goto fail; - } + if (len > INT_MAX - 12) + return AVERROR_INVALIDDATA; tag = avio_rl32(pb); switch (tag) { case MKTAG('a', 'c', 'T', 'L'): if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || (ret = append_extradata(st->codecpar, pb, len + 12)) < 0) - goto fail; + return ret; acTL_found = 1; ctx->num_frames = AV_RB32(st->codecpar->extradata + ret + 8); ctx->num_play = AV_RB32(st->codecpar->extradata + ret + 12); @@ -226,22 +222,18 @@ static int apng_read_header(AVFormatContext *s) ctx->num_frames, ctx->num_play); break; case MKTAG('f', 'c', 'T', 'L'): - if (!acTL_found) { - ret = AVERROR_INVALIDDATA; - goto fail; + if (!acTL_found || len != 26) { + return AVERROR_INVALIDDATA; } if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0) - goto fail; + return ret; return 0; default: if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || (ret = append_extradata(st->codecpar, pb, len + 12)) < 0) - goto fail; + return ret; } } - -fail: - return ret; } static int decode_fctl_chunk(AVFormatContext *s, APNGDemuxContext *ctx, AVPacket *pkt) diff --git a/libavformat/apngenc.c b/libavformat/apngenc.c index 88cd8054d..7e86f4514 100644 --- a/libavformat/apngenc.c +++ b/libavformat/apngenc.c @@ -119,7 +119,7 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) AVIOContext *io_context = format_context->pb; AVStream *codec_stream = format_context->streams[0]; uint8_t *side_data = NULL; - int side_data_size = 0; + buffer_size_t side_data_size; av_assert0(apng->prev_packet); diff --git a/libavformat/argo_asf.c b/libavformat/argo_asf.c index abc6e51ba..8e2bf21c7 100644 --- a/libavformat/argo_asf.c +++ b/libavformat/argo_asf.c @@ -1,5 +1,5 @@ /* - * Argonaut Games ASF demuxer + * Argonaut Games ASF (de)muxer * * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com) * @@ -23,38 +23,11 @@ #include "internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/avassert.h" +#include "libavutil/opt.h" +#include "argo_asf.h" -#define ASF_TAG MKTAG('A', 'S', 'F', '\0') -#define ASF_FILE_HEADER_SIZE 24 -#define ASF_CHUNK_HEADER_SIZE 20 - -typedef struct ArgoASFFileHeader { - uint32_t magic; /*< Magic Number, {'A', 'S', 'F', '\0'} */ - uint16_t version_major; /*< File Major Version. */ - uint16_t version_minor; /*< File Minor Version. */ - uint32_t num_chunks; /*< No. chunks in the file. */ - uint32_t chunk_offset; /*< Offset to the first chunk from the start of the file. */ - int8_t name[8]; /*< Name. */ -} ArgoASFFileHeader; - -typedef struct ArgoASFChunkHeader { - uint32_t num_blocks; /*< No. blocks in the chunk. */ - uint32_t num_samples; /*< No. samples per channel in a block. */ - uint32_t unk1; /*< Unknown */ - uint16_t sample_rate; /*< Sample rate. */ - uint16_t unk2; /*< Unknown. */ - uint32_t flags; /*< Stream flags. */ -} ArgoASFChunkHeader; - -enum { - ASF_CF_BITS_PER_SAMPLE = (1 << 0), /*< 16-bit if set, 8 otherwise. */ - ASF_CF_STEREO = (1 << 1), /*< Stereo if set, mono otherwise. */ - ASF_CF_ALWAYS1_1 = (1 << 2), /*< Unknown, always seems to be set. */ - ASF_CF_ALWAYS1_2 = (1 << 3), /*< Unknown, always seems to be set. */ - - ASF_CF_ALWAYS1 = ASF_CF_ALWAYS1_1 | ASF_CF_ALWAYS1_2, - ASF_CF_ALWAYS0 = ~(ASF_CF_BITS_PER_SAMPLE | ASF_CF_STEREO | ASF_CF_ALWAYS1) -}; +/* Maximum number of blocks to read at once. */ +#define ASF_NB_BLOCKS 32 typedef struct ArgoASFDemuxContext { ArgoASFFileHeader fhdr; @@ -62,7 +35,15 @@ typedef struct ArgoASFDemuxContext { uint32_t blocks_read; } ArgoASFDemuxContext; -static void argo_asf_parse_file_header(ArgoASFFileHeader *hdr, const uint8_t *buf) +typedef struct ArgoASFMuxContext { + const AVClass *class; + int version_major; + int version_minor; + const char *name; + int64_t nb_blocks; +} ArgoASFMuxContext; + +void ff_argo_asf_parse_file_header(ArgoASFFileHeader *hdr, const uint8_t *buf) { hdr->magic = AV_RL32(buf + 0); hdr->version_major = AV_RL16(buf + 4); @@ -73,7 +54,18 @@ static void argo_asf_parse_file_header(ArgoASFFileHeader *hdr, const uint8_t *bu hdr->name[i] = AV_RL8(buf + 16 + i); } -static void argo_asf_parse_chunk_header(ArgoASFChunkHeader *hdr, const uint8_t *buf) +int ff_argo_asf_validate_file_header(AVFormatContext *s, const ArgoASFFileHeader *hdr) +{ + if (hdr->magic != ASF_TAG || hdr->num_chunks == 0) + return AVERROR_INVALIDDATA; + + if (hdr->chunk_offset < ASF_FILE_HEADER_SIZE) + return AVERROR_INVALIDDATA; + + return 0; +} + +void ff_argo_asf_parse_chunk_header(ArgoASFChunkHeader *hdr, const uint8_t *buf) { hdr->num_blocks = AV_RL32(buf + 0); hdr->num_samples = AV_RL32(buf + 4); @@ -83,11 +75,83 @@ static void argo_asf_parse_chunk_header(ArgoASFChunkHeader *hdr, const uint8_t * hdr->flags = AV_RL32(buf + 16); } +int ff_argo_asf_fill_stream(AVFormatContext *s, AVStream *st, const ArgoASFFileHeader *fhdr, + const ArgoASFChunkHeader *ckhdr) +{ + if (ckhdr->num_samples != ASF_SAMPLE_COUNT) { + av_log(s, AV_LOG_ERROR, "Invalid sample count. Got %u, expected %d\n", + ckhdr->num_samples, ASF_SAMPLE_COUNT); + return AVERROR_INVALIDDATA; + } + + if ((ckhdr->flags & ASF_CF_ALWAYS1) != ASF_CF_ALWAYS1 || (ckhdr->flags & ASF_CF_ALWAYS0) != 0) { + avpriv_request_sample(s, "Nonstandard flags (0x%08X)", ckhdr->flags); + return AVERROR_PATCHWELCOME; + } + + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + st->codecpar->codec_id = AV_CODEC_ID_ADPCM_ARGO; + st->codecpar->format = AV_SAMPLE_FMT_S16P; + + if (ckhdr->flags & ASF_CF_STEREO) { + st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; + st->codecpar->channels = 2; + } else { + st->codecpar->channel_layout = AV_CH_LAYOUT_MONO; + st->codecpar->channels = 1; + } + + /* v1.1 files (FX Fighter) are all marked as 44100, but are actually 22050. */ + if (fhdr->version_major == 1 && fhdr->version_minor == 1) + st->codecpar->sample_rate = 22050; + else + st->codecpar->sample_rate = ckhdr->sample_rate; + + st->codecpar->bits_per_coded_sample = 4; + + if (ckhdr->flags & ASF_CF_BITS_PER_SAMPLE) + st->codecpar->bits_per_raw_sample = 16; + else + st->codecpar->bits_per_raw_sample = 8; + + if (st->codecpar->bits_per_raw_sample != 16) { + /* The header allows for these, but I've never seen any files with them. */ + avpriv_request_sample(s, "Non 16-bit samples"); + return AVERROR_PATCHWELCOME; + } + + /* + * (nchannel control bytes) + ((bytes_per_channel) * nchannel) + * For mono, this is 17. For stereo, this is 34. + */ + st->codecpar->block_align = st->codecpar->channels + + (ckhdr->num_samples / 2) * + st->codecpar->channels; + + st->codecpar->bit_rate = st->codecpar->channels * + st->codecpar->sample_rate * + st->codecpar->bits_per_coded_sample; + + avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); + st->start_time = 0; + + if (fhdr->num_chunks == 1) { + st->duration = ckhdr->num_blocks * ckhdr->num_samples; + st->nb_frames = ckhdr->num_blocks; + } + + return 0; +} + +#if CONFIG_ARGO_ASF_DEMUXER /* * Known versions: - * 1.1: The sample files in /game-formats/brender/part2.zip + * 1.1: https://samples.ffmpeg.org/game-formats/brender/part2.zip + * FX Fighter * 1.2: Croc! Legend of the Gobbos * 2.1: Croc 2 + * The Emperor's New Groove + * Disney's Aladdin in Nasira's Revenge */ static int argo_asf_is_known_version(const ArgoASFFileHeader *hdr) { @@ -102,7 +166,7 @@ static int argo_asf_probe(const AVProbeData *p) av_assert0(AVPROBE_PADDING_SIZE >= ASF_FILE_HEADER_SIZE); - argo_asf_parse_file_header(&hdr, p->buf); + ff_argo_asf_parse_file_header(&hdr, p->buf); if (hdr.magic != ASF_TAG) return 0; @@ -119,7 +183,7 @@ static int argo_asf_read_header(AVFormatContext *s) AVIOContext *pb = s->pb; AVStream *st; ArgoASFDemuxContext *asf = s->priv_data; - uint8_t buf[FFMAX(ASF_FILE_HEADER_SIZE, ASF_CHUNK_HEADER_SIZE)]; + uint8_t buf[ASF_MIN_BUFFER_SIZE]; if (!(st = avformat_new_stream(s, NULL))) return AVERROR(ENOMEM); @@ -129,23 +193,13 @@ static int argo_asf_read_header(AVFormatContext *s) else if (ret != ASF_FILE_HEADER_SIZE) return AVERROR(EIO); - argo_asf_parse_file_header(&asf->fhdr, buf); + ff_argo_asf_parse_file_header(&asf->fhdr, buf); - if (!argo_asf_is_known_version(&asf->fhdr)) { - avpriv_request_sample(s, "Version %hu.%hu", - asf->fhdr.version_major, asf->fhdr.version_minor - ); - return AVERROR_PATCHWELCOME; - } + if ((ret = ff_argo_asf_validate_file_header(s, &asf->fhdr)) < 0) + return ret; - if (asf->fhdr.num_chunks == 0) { - return AVERROR_INVALIDDATA; - } else if (asf->fhdr.num_chunks > 1) { - avpriv_request_sample(s, ">1 chunk"); - return AVERROR_PATCHWELCOME; - } - - if (asf->fhdr.chunk_offset < ASF_FILE_HEADER_SIZE) + /* This should only be 1 in ASF files. >1 is fine if in BRP. */ + if (asf->fhdr.num_chunks != 1) return AVERROR_INVALIDDATA; if ((ret = avio_skip(pb, asf->fhdr.chunk_offset - ASF_FILE_HEADER_SIZE)) < 0) @@ -156,63 +210,9 @@ static int argo_asf_read_header(AVFormatContext *s) else if (ret != ASF_CHUNK_HEADER_SIZE) return AVERROR(EIO); - argo_asf_parse_chunk_header(&asf->ckhdr, buf); + ff_argo_asf_parse_chunk_header(&asf->ckhdr, buf); - if ((asf->ckhdr.flags & ASF_CF_ALWAYS1) != ASF_CF_ALWAYS1 || (asf->ckhdr.flags & ASF_CF_ALWAYS0) != 0) { - avpriv_request_sample(s, "Nonstandard flags (0x%08X)", asf->ckhdr.flags); - return AVERROR_PATCHWELCOME; - } - - st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; - st->codecpar->codec_id = AV_CODEC_ID_ADPCM_ARGO; - st->codecpar->format = AV_SAMPLE_FMT_S16P; - - if (asf->ckhdr.flags & ASF_CF_STEREO) { - st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; - st->codecpar->channels = 2; - } else { - st->codecpar->channel_layout = AV_CH_LAYOUT_MONO; - st->codecpar->channels = 1; - } - - /* v1.1 files (FX Fighter) are all marked as 44100, but are actually 22050. */ - if (asf->fhdr.version_major == 1 && asf->fhdr.version_minor == 1) - st->codecpar->sample_rate = 22050; - else - st->codecpar->sample_rate = asf->ckhdr.sample_rate; - - st->codecpar->bits_per_coded_sample = 4; - - if (asf->ckhdr.flags & ASF_CF_BITS_PER_SAMPLE) - st->codecpar->bits_per_raw_sample = 16; - else - st->codecpar->bits_per_raw_sample = 8; - - if (st->codecpar->bits_per_raw_sample != 16) { - /* The header allows for these, but I've never seen any files with them. */ - avpriv_request_sample(s, "Non 16-bit samples"); - return AVERROR_PATCHWELCOME; - } - - /* - * (nchannel control bytes) + ((bytes_per_channel) * nchannel) - * For mono, this is 17. For stereo, this is 34. - */ - st->codecpar->frame_size = st->codecpar->channels + - (asf->ckhdr.num_samples / 2) * - st->codecpar->channels; - - st->codecpar->block_align = st->codecpar->frame_size; - - st->codecpar->bit_rate = st->codecpar->channels * - st->codecpar->sample_rate * - st->codecpar->bits_per_coded_sample; - - avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); - st->start_time = 0; - st->duration = asf->ckhdr.num_blocks * asf->ckhdr.num_samples; - st->nb_frames = asf->ckhdr.num_blocks; - return 0; + return ff_argo_asf_fill_stream(s, st, &asf->fhdr, &asf->ckhdr); } static int argo_asf_read_packet(AVFormatContext *s, AVPacket *pkt) @@ -226,15 +226,43 @@ static int argo_asf_read_packet(AVFormatContext *s, AVPacket *pkt) if (asf->blocks_read >= asf->ckhdr.num_blocks) return AVERROR_EOF; - if ((ret = av_get_packet(pb, pkt, st->codecpar->frame_size)) < 0) + ret = av_get_packet(pb, pkt, st->codecpar->block_align * + FFMIN(ASF_NB_BLOCKS, asf->ckhdr.num_blocks - asf->blocks_read)); + if (ret < 0) return ret; - else if (ret != st->codecpar->frame_size) + + /* Something real screwy is going on. */ + if (ret % st->codecpar->block_align != 0) return AVERROR_INVALIDDATA; - pkt->stream_index = st->index; - pkt->duration = asf->ckhdr.num_samples; - ++asf->blocks_read; + pkt->stream_index = st->index; + pkt->duration = asf->ckhdr.num_samples * (ret / st->codecpar->block_align); + pkt->pts = asf->blocks_read * asf->ckhdr.num_samples; + asf->blocks_read += (ret / st->codecpar->block_align); + + pkt->flags &= ~AV_PKT_FLAG_CORRUPT; + return 0; +} + +static int argo_asf_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + ArgoASFDemuxContext *asf = s->priv_data; + AVStream *st = s->streams[stream_index]; + int64_t offset; + uint32_t block = pts / asf->ckhdr.num_samples; + + if (block >= asf->ckhdr.num_blocks) + return -1; + + offset = asf->fhdr.chunk_offset + ASF_CHUNK_HEADER_SIZE + + (block * st->codecpar->block_align); + + if ((offset = avio_seek(s->pb, offset, SEEK_SET)) < 0) + return offset; + + asf->blocks_read = block; return 0; } @@ -249,5 +277,211 @@ AVInputFormat ff_argo_asf_demuxer = { .priv_data_size = sizeof(ArgoASFDemuxContext), .read_probe = argo_asf_probe, .read_header = argo_asf_read_header, - .read_packet = argo_asf_read_packet + .read_packet = argo_asf_read_packet, + .read_seek = argo_asf_seek, }; +#endif + +#if CONFIG_ARGO_ASF_MUXER +static int argo_asf_write_init(AVFormatContext *s) +{ + ArgoASFMuxContext *ctx = s->priv_data; + const AVCodecParameters *par; + + if (s->nb_streams != 1) { + av_log(s, AV_LOG_ERROR, "ASF files have exactly one stream\n"); + return AVERROR(EINVAL); + } + + par = s->streams[0]->codecpar; + + if (par->codec_id != AV_CODEC_ID_ADPCM_ARGO) { + av_log(s, AV_LOG_ERROR, "%s codec not supported\n", + avcodec_get_name(par->codec_id)); + return AVERROR(EINVAL); + } + + if (ctx->version_major == 1 && ctx->version_minor == 1 && par->sample_rate != 22050) { + av_log(s, AV_LOG_ERROR, "ASF v1.1 files only support a sample rate of 22050\n"); + return AVERROR(EINVAL); + } + + if (par->channels > 2) { + av_log(s, AV_LOG_ERROR, "ASF files only support up to 2 channels\n"); + return AVERROR(EINVAL); + } + + if (par->block_align != 17 * par->channels) + return AVERROR(EINVAL); + + if (par->sample_rate > UINT16_MAX) { + av_log(s, AV_LOG_ERROR, "Sample rate too large\n"); + return AVERROR(EINVAL); + } + + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { + av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n"); + return AVERROR(EINVAL); + } + + return 0; +} + +static void argo_asf_write_file_header(const ArgoASFFileHeader *fhdr, AVIOContext *pb) +{ + avio_wl32( pb, fhdr->magic); + avio_wl16( pb, fhdr->version_major); + avio_wl16( pb, fhdr->version_minor); + avio_wl32( pb, fhdr->num_chunks); + avio_wl32( pb, fhdr->chunk_offset); + avio_write(pb, fhdr->name, sizeof(fhdr->name)); +} + +static void argo_asf_write_chunk_header(const ArgoASFChunkHeader *ckhdr, AVIOContext *pb) +{ + avio_wl32(pb, ckhdr->num_blocks); + avio_wl32(pb, ckhdr->num_samples); + avio_wl32(pb, ckhdr->unk1); + avio_wl16(pb, ckhdr->sample_rate); + avio_wl16(pb, ckhdr->unk2); + avio_wl32(pb, ckhdr->flags); +} + +static int argo_asf_write_header(AVFormatContext *s) +{ + const AVCodecParameters *par = s->streams[0]->codecpar; + ArgoASFMuxContext *ctx = s->priv_data; + ArgoASFChunkHeader chdr; + ArgoASFFileHeader fhdr = { + .magic = ASF_TAG, + .version_major = (uint16_t)ctx->version_major, + .version_minor = (uint16_t)ctx->version_minor, + .num_chunks = 1, + .chunk_offset = ASF_FILE_HEADER_SIZE + }; + + /* + * If the user specified a name, use it as is. Otherwise take the + * basename and lop off the extension (if any). + */ + if (ctx->name) { + strncpy(fhdr.name, ctx->name, sizeof(fhdr.name)); + } else { + const char *start = av_basename(s->url); + const char *end = strrchr(start, '.'); + size_t len; + + if (end) + len = end - start; + else + len = strlen(start); + + memcpy(fhdr.name, start, FFMIN(len, sizeof(fhdr.name))); + } + + chdr.num_blocks = 0; + chdr.num_samples = ASF_SAMPLE_COUNT; + chdr.unk1 = 0; + + if (ctx->version_major == 1 && ctx->version_minor == 1) + chdr.sample_rate = 44100; + else + chdr.sample_rate = par->sample_rate; + + chdr.unk2 = ~0; + chdr.flags = ASF_CF_BITS_PER_SAMPLE | ASF_CF_ALWAYS1; + + if (par->channels == 2) + chdr.flags |= ASF_CF_STEREO; + + argo_asf_write_file_header(&fhdr, s->pb); + argo_asf_write_chunk_header(&chdr, s->pb); + return 0; +} + +static int argo_asf_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + ArgoASFMuxContext *ctx = s->priv_data; + AVCodecParameters *par = s->streams[0]->codecpar; + int nb_blocks = pkt->size / par->block_align; + + if (pkt->size % par->block_align != 0) + return AVERROR_INVALIDDATA; + + if (ctx->nb_blocks + nb_blocks > UINT32_MAX) + return AVERROR_INVALIDDATA; + + avio_write(s->pb, pkt->data, pkt->size); + + ctx->nb_blocks += nb_blocks; + return 0; +} + +static int argo_asf_write_trailer(AVFormatContext *s) +{ + ArgoASFMuxContext *ctx = s->priv_data; + int64_t ret; + + if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET) < 0)) + return ret; + + avio_wl32(s->pb, (uint32_t)ctx->nb_blocks); + return 0; +} + +static const AVOption argo_asf_options[] = { + { + .name = "version_major", + .help = "override file major version", + .offset = offsetof(ArgoASFMuxContext, version_major), + .type = AV_OPT_TYPE_INT, + .default_val = {.i64 = 2}, + .min = 0, + .max = UINT16_MAX, + .flags = AV_OPT_FLAG_ENCODING_PARAM + }, + { + .name = "version_minor", + .help = "override file minor version", + .offset = offsetof(ArgoASFMuxContext, version_minor), + .type = AV_OPT_TYPE_INT, + .default_val = {.i64 = 1}, + .min = 0, + .max = UINT16_MAX, + .flags = AV_OPT_FLAG_ENCODING_PARAM + }, + { + .name = "name", + .help = "embedded file name (max 8 characters)", + .offset = offsetof(ArgoASFMuxContext, name), + .type = AV_OPT_TYPE_STRING, + .default_val = {.str = NULL}, + .flags = AV_OPT_FLAG_ENCODING_PARAM + }, + { NULL } +}; + +static const AVClass argo_asf_muxer_class = { + .class_name = "argo_asf_muxer", + .item_name = av_default_item_name, + .option = argo_asf_options, + .version = LIBAVUTIL_VERSION_INT +}; + +AVOutputFormat ff_argo_asf_muxer = { + .name = "argo_asf", + .long_name = NULL_IF_CONFIG_SMALL("Argonaut Games ASF"), + /* + * NB: Can't do this as it conflicts with the actual ASF format. + * .extensions = "asf", + */ + .audio_codec = AV_CODEC_ID_ADPCM_ARGO, + .video_codec = AV_CODEC_ID_NONE, + .init = argo_asf_write_init, + .write_header = argo_asf_write_header, + .write_packet = argo_asf_write_packet, + .write_trailer = argo_asf_write_trailer, + .priv_class = &argo_asf_muxer_class, + .priv_data_size = sizeof(ArgoASFMuxContext) +}; +#endif diff --git a/libavformat/argo_asf.h b/libavformat/argo_asf.h new file mode 100644 index 000000000..e65125fb7 --- /dev/null +++ b/libavformat/argo_asf.h @@ -0,0 +1,71 @@ +/* + * Argonaut Games ASF (de)muxer + * + * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.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 + */ + +#ifndef AVFORMAT_ARGO_ASF_H +#define AVFORMAT_ARGO_ASF_H + +#include +#include "libavutil/common.h" + +#include "avformat.h" + +#define ASF_TAG MKTAG('A', 'S', 'F', '\0') +#define ASF_FILE_HEADER_SIZE 24 +#define ASF_CHUNK_HEADER_SIZE 20 +#define ASF_SAMPLE_COUNT 32 +#define ASF_MIN_BUFFER_SIZE FFMAX(ASF_FILE_HEADER_SIZE, ASF_CHUNK_HEADER_SIZE) + +typedef struct ArgoASFFileHeader { + uint32_t magic; /*< Magic Number, {'A', 'S', 'F', '\0'} */ + uint16_t version_major; /*< File Major Version. */ + uint16_t version_minor; /*< File Minor Version. */ + uint32_t num_chunks; /*< No. chunks in the file. */ + uint32_t chunk_offset; /*< Offset to the first chunk from the start of the file. */ + int8_t name[8]; /*< Name. */ +} ArgoASFFileHeader; + +typedef struct ArgoASFChunkHeader { + uint32_t num_blocks; /*< No. blocks in the chunk. */ + uint32_t num_samples; /*< No. samples per channel in a block. Always 32. */ + uint32_t unk1; /*< Unknown */ + uint16_t sample_rate; /*< Sample rate. */ + uint16_t unk2; /*< Unknown. */ + uint32_t flags; /*< Stream flags. */ +} ArgoASFChunkHeader; + +enum { + ASF_CF_BITS_PER_SAMPLE = (1 << 0), /*< 16-bit if set, 8 otherwise. */ + ASF_CF_STEREO = (1 << 1), /*< Stereo if set, mono otherwise. */ + ASF_CF_ALWAYS1_1 = (1 << 2), /*< Unknown, always seems to be set. */ + ASF_CF_ALWAYS1_2 = (1 << 3), /*< Unknown, always seems to be set. */ + + ASF_CF_ALWAYS1 = ASF_CF_ALWAYS1_1 | ASF_CF_ALWAYS1_2, + ASF_CF_ALWAYS0 = ~(ASF_CF_BITS_PER_SAMPLE | ASF_CF_STEREO | ASF_CF_ALWAYS1) +}; + +void ff_argo_asf_parse_file_header(ArgoASFFileHeader *hdr, const uint8_t *buf); +int ff_argo_asf_validate_file_header(AVFormatContext *s, const ArgoASFFileHeader *hdr); +void ff_argo_asf_parse_chunk_header(ArgoASFChunkHeader *hdr, const uint8_t *buf); +int ff_argo_asf_fill_stream(AVFormatContext *s, AVStream *st, const ArgoASFFileHeader *fhdr, + const ArgoASFChunkHeader *ckhdr); + +#endif /* AVFORMAT_ARGO_ASF_H */ diff --git a/libavformat/argo_brp.c b/libavformat/argo_brp.c new file mode 100644 index 000000000..6d6da851e --- /dev/null +++ b/libavformat/argo_brp.c @@ -0,0 +1,423 @@ +/* + * Argonaut Games BRP Demuxer + * + * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.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 + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/avassert.h" +#include "libavutil/internal.h" +#include "argo_asf.h" + +#define BRP_TAG MKTAG('B', 'R', 'P', 'P') +#define BRP_FILE_HEADER_SIZE 12 +#define BRP_BLOCK_HEADER_SIZE 12 +#define BRP_STREAM_HEADER_SIZE 20 +#define BRP_MAX_STREAMS 32 /* Soft cap, but even this is overkill. */ +#define BRP_BASF_LOOKAHEAD 10 /* How many blocks to search for the first BASF one. */ +#define BVID_HEADER_SIZE 16 +#define MASK_HEADER_SIZE 12 +#define BRP_MIN_BUFFER_SIZE FFMAX3(FFMAX3(BRP_FILE_HEADER_SIZE, \ + BRP_BLOCK_HEADER_SIZE, \ + BRP_STREAM_HEADER_SIZE), \ + BVID_HEADER_SIZE, \ + MASK_HEADER_SIZE) + +#define BRP_CODEC_ID_BVID MKTAG('B', 'V', 'I', 'D') +#define BRP_CODEC_ID_BASF MKTAG('B', 'A', 'S', 'F') +#define BRP_CODEC_ID_MASK MKTAG('M', 'A', 'S', 'K') + +typedef struct ArgoBRPFileHeader { + uint32_t magic; + uint32_t num_streams; + uint32_t byte_rate; +} ArgoBRPFileHeader; + +typedef struct ArgoBRPBlockHeader { + int32_t stream_id; + uint32_t start_ms; + uint32_t size; +} ArgoBRPBlockHeader; + +typedef struct ArgoBVIDHeader { + uint32_t num_frames; + uint32_t width; + uint32_t height; + uint32_t depth; +} ArgoBVIDHeader; + +typedef struct ArgoMASKHeader { + uint32_t num_frames; + uint32_t width; + uint32_t height; +} ArgoMASKHeader; + +typedef struct ArgoBRPStreamHeader { + uint32_t codec_id; + uint32_t id; + uint32_t duration_ms; + uint32_t byte_rate; + uint32_t extradata_size; + union + { + /* If codec_id == BRP_CODEC_ID_BVID */ + ArgoBVIDHeader bvid; + /* If codec_id == BRP_CODEC_ID_BASF */ + ArgoASFFileHeader basf; + /* If codec_id == BRP_CODEC_ID_MASK */ + ArgoMASKHeader mask; + } extradata; +} ArgoBRPStreamHeader; + +typedef struct ArgoBRPDemuxContext { + ArgoBRPFileHeader fhdr; + ArgoBRPStreamHeader streams[BRP_MAX_STREAMS]; + + struct { + int index; + ArgoASFChunkHeader ckhdr; + } basf; +} ArgoBRPDemuxContext; + +static int argo_brp_probe(const AVProbeData *p) +{ + if (AV_RL32(p->buf) != BRP_TAG) + return 0; + + return AVPROBE_SCORE_EXTENSION + 1; +} + +static int read_extradata(AVFormatContext *s, const ArgoBRPStreamHeader *hdr, + void *buf, size_t bufsz) +{ + const char *name; + uint32_t size; + int64_t ret; + + if (hdr->codec_id == BRP_CODEC_ID_BVID) { + name = "BVID"; + size = BVID_HEADER_SIZE; + } else if (hdr->codec_id == BRP_CODEC_ID_BASF) { + name = "BASF"; + size = ASF_FILE_HEADER_SIZE; + } else if (hdr->codec_id == BRP_CODEC_ID_MASK) { + name = "MASK"; + size = MASK_HEADER_SIZE; + } else { + avpriv_request_sample(s, "BRP codec id 0x%x", hdr->codec_id); + + if ((ret = avio_skip(s->pb, hdr->extradata_size)) < 0) + return ret; + + return 1; + } + + if (hdr->extradata_size != size) { + av_log(s, AV_LOG_ERROR, "Invalid %s extradata size %u, expected %u\n", + name, hdr->extradata_size, size); + return AVERROR_INVALIDDATA; + } + + av_assert0(bufsz >= size); + + if ((ret = avio_read(s->pb, buf, size)) < 0) + return ret; + + if (ret != size) + return AVERROR(EIO); + + return 0; +} + +static int argo_brp_read_header(AVFormatContext *s) +{ + int64_t ret; + AVIOContext *pb = s->pb; + ArgoBRPDemuxContext *brp = s->priv_data; + uint8_t buf[FFMAX(BRP_MIN_BUFFER_SIZE, ASF_MIN_BUFFER_SIZE)]; + + if ((ret = avio_read(pb, buf, BRP_FILE_HEADER_SIZE)) < 0) + return ret; + else if (ret != BRP_FILE_HEADER_SIZE) + return AVERROR(EIO); + + brp->fhdr.magic = AV_RL32(buf + 0); + brp->fhdr.num_streams = AV_RL32(buf + 4); + brp->fhdr.byte_rate = AV_RL32(buf + 8); + + if (brp->fhdr.magic != BRP_TAG) + return AVERROR_INVALIDDATA; + + if (brp->fhdr.num_streams > BRP_MAX_STREAMS) { + avpriv_request_sample(s, ">%d streams", BRP_MAX_STREAMS); + return AVERROR_PATCHWELCOME; + } + + /* Build the stream info. */ + brp->basf.index = -1; + for (uint32_t i = 0; i < brp->fhdr.num_streams; i++) { + ArgoBRPStreamHeader *hdr = brp->streams + i; + AVStream *st; + + if (!(st = avformat_new_stream(s, NULL))) + return AVERROR(ENOMEM); + + if ((ret = avio_read(pb, buf, BRP_STREAM_HEADER_SIZE)) < 0) + return ret; + else if (ret != BRP_STREAM_HEADER_SIZE) + return AVERROR(EIO); + + hdr->codec_id = AV_RL32(buf + 0); + hdr->id = AV_RL32(buf + 4); + hdr->duration_ms = AV_RL32(buf + 8); + hdr->byte_rate = AV_RL32(buf + 12); + hdr->extradata_size = AV_RL32(buf + 16); + + /* This should always be the case. */ + if (hdr->id != i) + return AVERROR_INVALIDDATA; + + /* Timestamps are in milliseconds. */ + avpriv_set_pts_info(st, 64, 1, 1000); + st->duration = hdr->duration_ms; + st->codecpar->bit_rate = hdr->byte_rate * 8; + + if ((ret = read_extradata(s, hdr, buf, sizeof(buf))) < 0) { + return ret; + } else if (ret > 0) { + st->codecpar->codec_type = AVMEDIA_TYPE_UNKNOWN; + continue; + } + + if (hdr->codec_id == BRP_CODEC_ID_BVID) { + ArgoBVIDHeader *bvid = &hdr->extradata.bvid; + + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = AV_CODEC_ID_ARGO; + + bvid->num_frames = AV_RL32(buf + 0); + bvid->width = AV_RL32(buf + 4); + bvid->height = AV_RL32(buf + 8); + bvid->depth = AV_RL32(buf + 12); + + if (bvid->num_frames == 0) + return AVERROR_INVALIDDATA; + + /* These are from 1990's games, sanity check this. */ + if (bvid->width >= 65536 || bvid->height >= 65536 || + bvid->depth > 24 || bvid->depth % 8 != 0) { + return AVERROR_INVALIDDATA; + } + + st->codecpar->width = bvid->width; + st->codecpar->height = bvid->height; + st->nb_frames = bvid->num_frames; + st->codecpar->bits_per_raw_sample = bvid->depth; + } else if (hdr->codec_id == BRP_CODEC_ID_BASF) { + /* + * It would make the demuxer significantly more complicated + * to support multiple BASF streams. I've never seen a file + * with more than one. + */ + if (brp->basf.index >= 0) { + avpriv_request_sample(s, "Multiple BASF streams"); + return AVERROR_PATCHWELCOME; + } + + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + st->codecpar->codec_id = AV_CODEC_ID_ADPCM_ARGO; + brp->basf.index = i; + ff_argo_asf_parse_file_header(&hdr->extradata.basf, buf); + + if ((ret = ff_argo_asf_validate_file_header(s, &hdr->extradata.basf)) < 0) + return ret; + + st->nb_frames = hdr->extradata.basf.num_chunks; + } else if (hdr->codec_id == BRP_CODEC_ID_MASK) { + ArgoMASKHeader *mask = &hdr->extradata.mask; + + st->codecpar->codec_type = AVMEDIA_TYPE_DATA; + + mask->num_frames = AV_RL32(buf + 0); + mask->width = AV_RL32(buf + 4); + mask->height = AV_RL32(buf + 8); + + st->nb_frames = mask->num_frames; + } else { + av_assert0(0); /* Caught above, should never happen. */ + } + } + + /* Try to find the first BASF chunk. */ + if (brp->basf.index >= 0) { + AVStream *st = s->streams[brp->basf.index]; + ArgoBRPStreamHeader *hdr = brp->streams + brp->basf.index; + ArgoBRPBlockHeader blk; + int64_t offset; + int i; + + av_assert0(st->codecpar->codec_id == AV_CODEC_ID_ADPCM_ARGO); + av_assert0(brp->streams[brp->basf.index].extradata_size == ASF_FILE_HEADER_SIZE); + + if ((ret = avio_tell(s->pb)) < 0) + return ret; + + offset = ret; + + av_log(s, AV_LOG_TRACE, "Searching %d blocks for BASF...", BRP_BASF_LOOKAHEAD); + + for (i = 0; i < BRP_BASF_LOOKAHEAD; i++) { + if ((ret = avio_read(pb, buf, BRP_BLOCK_HEADER_SIZE)) < 0) + return ret; + else if (ret != BRP_BLOCK_HEADER_SIZE) + return AVERROR(EIO); + + blk.stream_id = AV_RL32(buf + 0); + blk.start_ms = AV_RL32(buf + 4); + blk.size = AV_RL32(buf + 8); + + if (blk.stream_id == brp->basf.index || blk.stream_id == -1) + break; + + if ((ret = avio_skip(pb, blk.size)) < 0) + return ret; + } + + if (i == BRP_BASF_LOOKAHEAD || blk.stream_id == -1) { + /* Don't error here, as there may still be a valid video stream. */ + av_log(s, AV_LOG_TRACE, "not found\n"); + goto done; + } + + av_log(s, AV_LOG_TRACE, "found at index %d\n", i); + + if (blk.size < ASF_CHUNK_HEADER_SIZE) + return AVERROR_INVALIDDATA; + + if ((ret = avio_read(pb, buf, ASF_CHUNK_HEADER_SIZE)) < 0) + return ret; + else if (ret != ASF_CHUNK_HEADER_SIZE) + return AVERROR(EIO); + + ff_argo_asf_parse_chunk_header(&brp->basf.ckhdr, buf); + + /* + * Special Case Hack. It seems that in files where the BASF block isn't first, + * v1.1 streams are allowed to be non-22050... + * Bump the version to 1.2 so ff_argo_asf_fill_stream() doesn't "correct" it. + * + * Found in Alien Odyssey games files in: + * ./GRAPHICS/COMMBUNK/{{COMADD1,COMM2_{1,2,3E},COMM3_{2,3,4,5,6}},FADE{1,2}}.BRP + * + * Either this format really inconsistent, or FX Fighter and Croc just ignored the + * sample rate field... + */ + if (i != 0 && hdr->extradata.basf.version_major == 1 && hdr->extradata.basf.version_minor == 1) + hdr->extradata.basf.version_minor = 2; + + if ((ret = ff_argo_asf_fill_stream(s, st, &hdr->extradata.basf, &brp->basf.ckhdr)) < 0) + return ret; + + /* Convert ms to samples. */ + st->start_time = av_rescale_rnd(blk.start_ms, st->codecpar->sample_rate, 1000, AV_ROUND_UP); + st->duration = av_rescale_rnd(hdr->duration_ms, st->codecpar->sample_rate, 1000, AV_ROUND_UP); + +done: + if ((ret = avio_seek(s->pb, offset, SEEK_SET)) < 0) + return ret; + } + return 0; +} + +static int argo_brp_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + ArgoBRPDemuxContext *brp = s->priv_data; + ArgoBRPBlockHeader blk; + const ArgoBRPStreamHeader *shdr; + AVStream *st; + uint8_t buf[BRP_MIN_BUFFER_SIZE]; + ArgoASFChunkHeader ckhdr; + int ret; + + if ((ret = avio_read(s->pb, buf, BRP_BLOCK_HEADER_SIZE)) < 0) + return ret; + else if (ret != BRP_BLOCK_HEADER_SIZE) + return AVERROR(EIO); + + blk.stream_id = AV_RL32(buf + 0); + blk.start_ms = AV_RL32(buf + 4); + blk.size = AV_RL32(buf + 8); + + if (blk.stream_id == -1) + return AVERROR_EOF; + + if (blk.stream_id < -1 || blk.stream_id >= s->nb_streams) + return AVERROR_INVALIDDATA; + + st = s->streams[blk.stream_id]; + shdr = brp->streams + blk.stream_id; + + if (blk.stream_id == brp->basf.index) { + if (blk.size < ASF_CHUNK_HEADER_SIZE) + return AVERROR_INVALIDDATA; + + if ((ret = avio_read(s->pb, buf, ASF_CHUNK_HEADER_SIZE)) < 0) + return ret; + + ff_argo_asf_parse_chunk_header(&ckhdr, buf); + + /* Ensure the chunk attributes are the same. */ + if (ckhdr.sample_rate != brp->basf.ckhdr.sample_rate || + ckhdr.flags != brp->basf.ckhdr.flags || + ckhdr.unk1 != brp->basf.ckhdr.unk1 || + ckhdr.unk2 != brp->basf.ckhdr.unk2) + return AVERROR_INVALIDDATA; + + blk.size -= ASF_CHUNK_HEADER_SIZE; + } + + if ((ret = av_get_packet(s->pb, pkt, blk.size)) < 0) + return ret; + else if (ret != blk.size) + return AVERROR_INVALIDDATA; + + if (blk.stream_id == brp->basf.index) { + pkt->duration = ckhdr.num_samples * ckhdr.num_blocks; + pkt->pts = av_rescale_rnd(blk.start_ms, ckhdr.sample_rate, 1000, AV_ROUND_UP); + } else if (shdr->codec_id == BRP_CODEC_ID_BVID) { + pkt->duration = av_rescale_rnd(1, st->duration, shdr->extradata.bvid.num_frames, AV_ROUND_UP); + pkt->pts = blk.start_ms; + } else { + pkt->pts = blk.start_ms; + } + + pkt->stream_index = blk.stream_id; + return 0; +} + +AVInputFormat ff_argo_brp_demuxer = { + .name = "argo_brp", + .long_name = NULL_IF_CONFIG_SMALL("Argonaut Games BRP"), + .priv_data_size = sizeof(ArgoBRPDemuxContext), + .read_probe = argo_brp_probe, + .read_header = argo_brp_read_header, + .read_packet = argo_brp_read_packet, +}; diff --git a/libavformat/asf.c b/libavformat/asf.c index 719cae9da..f1f171e6f 100644 --- a/libavformat/asf.c +++ b/libavformat/asf.c @@ -40,12 +40,6 @@ const ff_asf_guid ff_asf_audio_stream = { 0x40, 0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B }; -const ff_asf_guid ff_asf_audio_conceal_none = { - // 0x40, 0xa4, 0xf1, 0x49, 0x4ece, 0x11d0, 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 - // New value lifted from avifile - 0x00, 0x57, 0xfb, 0x20, 0x55, 0x5B, 0xCF, 0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b -}; - const ff_asf_guid ff_asf_audio_conceal_spread = { 0x50, 0xCD, 0xC3, 0xBF, 0x8F, 0x61, 0xCF, 0x11, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20 }; diff --git a/libavformat/asf.h b/libavformat/asf.h index a30d3bb23..bce820efa 100644 --- a/libavformat/asf.h +++ b/libavformat/asf.h @@ -74,7 +74,6 @@ extern const ff_asf_guid ff_asf_file_header; extern const ff_asf_guid ff_asf_stream_header; extern const ff_asf_guid ff_asf_ext_stream_header; extern const ff_asf_guid ff_asf_audio_stream; -extern const ff_asf_guid ff_asf_audio_conceal_none; extern const ff_asf_guid ff_asf_audio_conceal_spread; extern const ff_asf_guid ff_asf_video_stream; extern const ff_asf_guid ff_asf_jfif_media; diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c index 0aab7c230..f784e6299 100644 --- a/libavformat/asfdec_f.c +++ b/libavformat/asfdec_f.c @@ -143,6 +143,12 @@ static const ff_asf_guid stream_bitrate_guid = { /* (http://get.to/sdp) */ 0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2 }; +static const ff_asf_guid asf_audio_conceal_none = { + // 0x40, 0xa4, 0xf1, 0x49, 0x4ece, 0x11d0, 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 + // New value lifted from avifile + 0x00, 0x57, 0xfb, 0x20, 0x55, 0x5B, 0xCF, 0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b +}; + #define PRINT_IF_GUID(g, cmp) \ if (!ff_guidcmp(g, &cmp)) \ av_log(NULL, AV_LOG_TRACE, "(GUID: %s) ", # cmp) @@ -154,7 +160,7 @@ static void print_guid(ff_asf_guid *g) else PRINT_IF_GUID(g, ff_asf_file_header); else PRINT_IF_GUID(g, ff_asf_stream_header); else PRINT_IF_GUID(g, ff_asf_audio_stream); - else PRINT_IF_GUID(g, ff_asf_audio_conceal_none); + else PRINT_IF_GUID(g, asf_audio_conceal_none); else PRINT_IF_GUID(g, ff_asf_video_stream); else PRINT_IF_GUID(g, ff_asf_video_conceal_none); else PRINT_IF_GUID(g, ff_asf_command_stream); @@ -479,7 +485,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) if (is_dvr_ms_audio) { // codec_id and codec_tag are unreliable in dvr_ms // files. Set them later by probing stream. - st->request_probe = 1; + st->internal->request_probe = 1; st->codecpar->codec_tag = 0; } if (st->codecpar->codec_id == AV_CODEC_ID_AAC) diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c index 893368702..7c0856518 100644 --- a/libavformat/asfdec_o.c +++ b/libavformat/asfdec_o.c @@ -63,7 +63,7 @@ typedef struct GUIDParseTable { } GUIDParseTable; typedef struct ASFPacket { - AVPacket avpkt; + AVPacket *avpkt; int64_t dts; uint32_t frame_num; // ASF payloads with the same number are parts of the same frame int flags; @@ -360,7 +360,6 @@ static int asf_set_metadata(AVFormatContext *s, const uint8_t *name, * but in reality this is only loosely similar */ static int asf_read_picture(AVFormatContext *s, int len) { - ASFContext *asf = s->priv_data; AVPacket pkt = { 0 }; const CodecMime *mime = ff_id3v2_mime_tags; enum AVCodecID id = AV_CODEC_ID_NONE; @@ -368,7 +367,6 @@ static int asf_read_picture(AVFormatContext *s, int len) uint8_t *desc = NULL; AVStream *st = NULL; int ret, type, picsize, desc_len; - ASFStream *asf_st; /* type + picsize + mime + desc */ if (len < 1 + 4 + 2 + 2) { @@ -425,22 +423,14 @@ static int asf_read_picture(AVFormatContext *s, int len) ret = AVERROR(ENOMEM); goto fail; } - asf->asf_st[asf->nb_streams] = av_mallocz(sizeof(*asf_st)); - asf_st = asf->asf_st[asf->nb_streams]; - if (!asf_st) { - ret = AVERROR(ENOMEM); - goto fail; - } st->disposition |= AV_DISPOSITION_ATTACHED_PIC; - st->codecpar->codec_type = asf_st->type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = id; st->attached_pic = pkt; - st->attached_pic.stream_index = asf_st->index = st->index; + st->attached_pic.stream_index = st->index; st->attached_pic.flags |= AV_PKT_FLAG_KEY; - asf->nb_streams++; - if (*desc) { if (av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL) < 0) av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n"); @@ -609,7 +599,8 @@ static int asf_read_metadata_obj(AVFormatContext *s, const GUIDParseTable *g) } else { if (st_num < ASF_MAX_STREAMS) { if ((ret = process_metadata(s, name, name_len, val_len, type, - &asf->asf_sd[st_num].asf_met)) < 0) { + st_num ? &asf->asf_sd[st_num].asf_met + : &s->metadata)) < 0) { av_freep(&name); break; } @@ -790,8 +781,10 @@ static int asf_read_stream_properties(AVFormatContext *s, const GUIDParseTable * asf_st->index = st->index; asf_st->indexed = 0; st->id = flags & ASF_STREAM_NUM; - av_init_packet(&asf_st->pkt.avpkt); asf_st->pkt.data_size = 0; + asf_st->pkt.avpkt = av_packet_alloc(); + if (!asf_st->pkt.avpkt) + return AVERROR(ENOMEM); avio_skip(pb, 4); // skip reserved field switch (type) { @@ -863,6 +856,8 @@ static int asf_read_ext_stream_properties(AVFormatContext *s, const GUIDParseTab st_num = avio_rl16(pb); st_num &= ASF_STREAM_NUM; lang_idx = avio_rl16(pb); // Stream Language ID Index + if (lang_idx >= ASF_MAX_STREAMS) + return AVERROR_INVALIDDATA; for (i = 0; i < asf->nb_streams; i++) { if (st_num == asf->asf_st[i]->stream_index) { st = s->streams[asf->asf_st[i]->index]; @@ -1147,9 +1142,7 @@ static void reset_packet(ASFPacket *asf_pkt) asf_pkt->duration = 0; asf_pkt->flags = 0; asf_pkt->dts = 0; - asf_pkt->duration = 0; - av_packet_unref(&asf_pkt->avpkt); - av_init_packet(&asf_pkt->avpkt); + av_packet_unref(asf_pkt->avpkt); } static int asf_read_replicated_data(AVFormatContext *s, ASFPacket *asf_pkt) @@ -1162,7 +1155,7 @@ static int asf_read_replicated_data(AVFormatContext *s, ASFPacket *asf_pkt) data_size = avio_rl32(pb); // read media object size if (data_size <= 0) return AVERROR_INVALIDDATA; - if ((ret = av_new_packet(&asf_pkt->avpkt, data_size)) < 0) + if ((ret = av_new_packet(asf_pkt->avpkt, data_size)) < 0) return ret; asf_pkt->data_size = asf_pkt->size_left = data_size; } else @@ -1203,7 +1196,7 @@ static int asf_read_multiple_payload(AVFormatContext *s, AVPacket *pkt, pay_len, asf->packet_size, avio_tell(pb)); return AVERROR_INVALIDDATA; } - p = asf_pkt->avpkt.data + asf_pkt->data_size - asf_pkt->size_left; + p = asf_pkt->avpkt->data + asf_pkt->data_size - asf_pkt->size_left; if (pay_len > asf_pkt->size_left) { av_log(s, AV_LOG_ERROR, "Error: invalid buffer size, pay_len %d, data size left %d.\n", @@ -1238,7 +1231,7 @@ static int asf_read_single_payload(AVFormatContext *s, ASFPacket *asf_pkt) data_size = avio_rl32(pb); // read media object size if (data_size <= 0) return AVERROR_EOF; - if ((ret = av_new_packet(&asf_pkt->avpkt, data_size)) < 0) + if ((ret = av_new_packet(asf_pkt->avpkt, data_size)) < 0) return ret; asf_pkt->data_size = asf_pkt->size_left = data_size; } else @@ -1259,7 +1252,7 @@ static int asf_read_single_payload(AVFormatContext *s, ASFPacket *asf_pkt) avio_tell(pb)); return AVERROR_INVALIDDATA; } - p = asf_pkt->avpkt.data + asf_pkt->data_size - asf_pkt->size_left; + p = asf_pkt->avpkt->data + asf_pkt->data_size - asf_pkt->size_left; if (size > asf_pkt->size_left || asf_pkt->size_left <= 0) return AVERROR_INVALIDDATA; if (asf_pkt->size_left > size) @@ -1396,16 +1389,18 @@ static int asf_deinterleave(AVFormatContext *s, ASFPacket *asf_pkt, int st_num) { ASFContext *asf = s->priv_data; ASFStream *asf_st = asf->asf_st[st_num]; - unsigned char *p = asf_pkt->avpkt.data; + unsigned char *p = asf_pkt->avpkt->data; uint16_t pkt_len = asf->asf_st[st_num]->virtual_pkt_len; uint16_t chunk_len = asf->asf_st[st_num]->virtual_chunk_len; int nchunks = pkt_len / chunk_len; - AVPacket pkt; + uint8_t *data; int pos = 0, j, l, ret; - if ((ret = av_new_packet(&pkt, asf_pkt->data_size)) < 0) - return ret; + data = av_malloc(asf_pkt->data_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!data) + return AVERROR(ENOMEM); + memset(data + asf_pkt->data_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); while (asf_pkt->data_size >= asf_st->span * pkt_len + pos) { if (pos >= asf_pkt->data_size) { @@ -1418,20 +1413,22 @@ static int asf_deinterleave(AVFormatContext *s, ASFPacket *asf_pkt, int st_num) for (j = 0; j < asf_st->span; j++) { if ((pos + chunk_len) >= asf_pkt->data_size) break; - memcpy(pkt.data + pos, + memcpy(data + pos, p + (j * nchunks + l) * chunk_len, chunk_len); pos += chunk_len; } } p += asf_st->span * pkt_len; - if (p > asf_pkt->avpkt.data + asf_pkt->data_size) + if (p > asf_pkt->avpkt->data + asf_pkt->data_size) break; } - av_packet_unref(&asf_pkt->avpkt); - asf_pkt->avpkt = pkt; + av_packet_unref(asf_pkt->avpkt); + ret = av_packet_from_data(asf_pkt->avpkt, data, asf_pkt->data_size); + if (ret < 0) + av_free(data); - return 0; + return ret; } static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) @@ -1501,7 +1498,7 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) asf->asf_st[i]->type == AVMEDIA_TYPE_AUDIO) if ((ret = asf_deinterleave(s, asf_pkt, i)) < 0) return ret; - av_packet_move_ref(pkt, &asf_pkt->avpkt); + av_packet_move_ref(pkt, asf_pkt->avpkt); pkt->stream_index = asf->asf_st[i]->index; pkt->flags = asf_pkt->flags; pkt->dts = asf_pkt->dts - asf->preroll; @@ -1526,7 +1523,7 @@ static int asf_read_close(AVFormatContext *s) for (i = 0; i < ASF_MAX_STREAMS; i++) { av_dict_free(&asf->asf_sd[i].asf_met); if (i < asf->nb_streams) { - av_packet_unref(&asf->asf_st[i]->pkt.avpkt); + av_packet_free(&asf->asf_st[i]->pkt.avpkt); av_freep(&asf->asf_st[i]); } } @@ -1556,14 +1553,7 @@ static void reset_packet_state(AVFormatContext *s) asf->sub_dts = 0; for (i = 0; i < asf->nb_streams; i++) { ASFPacket *pkt = &asf->asf_st[i]->pkt; - pkt->size_left = 0; - pkt->data_size = 0; - pkt->duration = 0; - pkt->flags = 0; - pkt->dts = 0; - pkt->duration = 0; - av_packet_unref(&pkt->avpkt); - av_init_packet(&pkt->avpkt); + reset_packet(pkt); } } @@ -1583,9 +1573,12 @@ static int64_t asf_read_timestamp(AVFormatContext *s, int stream_index, { ASFContext *asf = s->priv_data; int64_t pkt_pos = *pos, pkt_offset, dts = AV_NOPTS_VALUE, data_end; - AVPacket pkt; + AVPacket *pkt = av_packet_alloc(); int n; + if (!pkt) + return AVERROR(ENOMEM); + data_end = asf->data_offset + asf->data_size; n = (pkt_pos - asf->first_packet_offset + asf->packet_size - 1) / @@ -1601,9 +1594,9 @@ static int64_t asf_read_timestamp(AVFormatContext *s, int stream_index, int i, ret, st_found; - av_init_packet(&pkt); pkt_offset = avio_tell(s->pb); - if ((ret = asf_read_packet(s, &pkt)) < 0) { + if ((ret = asf_read_packet(s, pkt)) < 0) { + av_packet_free(&pkt); dts = AV_NOPTS_VALUE; return ret; } @@ -1615,11 +1608,11 @@ static int64_t asf_read_timestamp(AVFormatContext *s, int stream_index, ASFStream *st = asf->asf_st[i]; st_found = 0; - if (pkt.flags & AV_PKT_FLAG_KEY) { - dts = pkt.dts; + if (pkt->flags & AV_PKT_FLAG_KEY) { + dts = pkt->dts; if (dts) { - av_add_index_entry(s->streams[pkt.stream_index], pkt_pos, - dts, pkt.size, 0, AVINDEX_KEYFRAME); + av_add_index_entry(s->streams[pkt->stream_index], pkt_pos, + dts, pkt->size, 0, AVINDEX_KEYFRAME); if (stream_index == st->index) { st_found = 1; break; @@ -1629,11 +1622,11 @@ static int64_t asf_read_timestamp(AVFormatContext *s, int stream_index, } if (st_found) break; - av_packet_unref(&pkt); + av_packet_unref(pkt); } *pos = pkt_pos; - av_packet_unref(&pkt); + av_packet_free(&pkt); return dts; } diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index 73afb1320..23a09efe0 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -258,6 +258,10 @@ static const AVCodecTag codec_asf_bmp_tags[] = { { AV_CODEC_ID_NONE, 0 }, }; +static const AVCodecTag *const asf_codec_tags[] = { + codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, NULL +}; + #define PREROLL_TIME 3100 static void put_str16(AVIOContext *s, const char *tag) @@ -682,7 +686,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, avio_wl16(pb, 40 + par->extradata_size); /* size */ /* BITMAPINFOHEADER header */ - ff_put_bmp_header(pb, par, 1, 0); + ff_put_bmp_header(pb, par, 1, 0, 0); } end_header(pb, hpos); } @@ -1170,9 +1174,7 @@ AVOutputFormat ff_asf_muxer = { .write_packet = asf_write_packet, .write_trailer = asf_write_trailer, .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag * const []) { - codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0 - }, + .codec_tag = asf_codec_tags, .priv_class = &asf_muxer_class, }; #endif /* CONFIG_ASF_MUXER */ @@ -1197,9 +1199,7 @@ AVOutputFormat ff_asf_stream_muxer = { .write_packet = asf_write_packet, .write_trailer = asf_write_trailer, .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag * const []) { - codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0 - }, + .codec_tag = asf_codec_tags, .priv_class = &asf_stream_muxer_class, }; #endif /* CONFIG_ASF_STREAM_MUXER */ diff --git a/libavformat/ast.c b/libavformat/ast.c index 9de74aae6..856d36f08 100644 --- a/libavformat/ast.c +++ b/libavformat/ast.c @@ -19,7 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "avformat.h" +#include +#include "libavcodec/codec_id.h" #include "internal.h" const AVCodecTag ff_codec_ast_tags[] = { @@ -27,3 +28,5 @@ const AVCodecTag ff_codec_ast_tags[] = { { AV_CODEC_ID_PCM_S16BE_PLANAR, 1 }, { AV_CODEC_ID_NONE, 0 }, }; + +const AVCodecTag *const ff_ast_codec_tags_list[] = { ff_codec_ast_tags, NULL }; diff --git a/libavformat/ast.h b/libavformat/ast.h index 4a399ea41..b629f7ed4 100644 --- a/libavformat/ast.h +++ b/libavformat/ast.h @@ -26,5 +26,6 @@ #include "internal.h" extern const AVCodecTag ff_codec_ast_tags[]; +extern const AVCodecTag *const ff_ast_codec_tags_list[]; #endif /* AVFORMAT_AST_H */ diff --git a/libavformat/astdec.c b/libavformat/astdec.c index 9d2174f70..610c9385a 100644 --- a/libavformat/astdec.c +++ b/libavformat/astdec.c @@ -118,5 +118,5 @@ AVInputFormat ff_ast_demuxer = { .read_packet = ast_read_packet, .extensions = "ast", .flags = AVFMT_GENERIC_INDEX, - .codec_tag = (const AVCodecTag* const []){ff_codec_ast_tags, 0}, + .codec_tag = ff_ast_codec_tags_list, }; diff --git a/libavformat/astenc.c b/libavformat/astenc.c index e0b94b8b6..69541bc0c 100644 --- a/libavformat/astenc.c +++ b/libavformat/astenc.c @@ -207,5 +207,5 @@ AVOutputFormat ff_ast_muxer = { .write_packet = ast_write_packet, .write_trailer = ast_write_trailer, .priv_class = &ast_muxer_class, - .codec_tag = (const AVCodecTag* const []){ff_codec_ast_tags, 0}, + .codec_tag = ff_ast_codec_tags_list, }; diff --git a/libavformat/async.c b/libavformat/async.c index a0bdfa2ee..5a81507ef 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -262,24 +262,28 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** ret = pthread_mutex_init(&c->mutex, NULL); if (ret != 0) { + ret = AVERROR(ret); av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", av_err2str(ret)); goto mutex_fail; } ret = pthread_cond_init(&c->cond_wakeup_main, NULL); if (ret != 0) { + ret = AVERROR(ret); av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret)); goto cond_wakeup_main_fail; } ret = pthread_cond_init(&c->cond_wakeup_background, NULL); if (ret != 0) { + ret = AVERROR(ret); av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret)); goto cond_wakeup_background_fail; } ret = pthread_create(&c->async_buffer_thread, NULL, async_buffer_task, h); if (ret) { + ret = AVERROR(ret); av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", av_err2str(ret)); goto thread_fail; } @@ -608,7 +612,8 @@ int main(void) /* * test normal read */ - ret = ffurl_open(&h, "async:async-test:", AVIO_FLAG_READ, NULL, NULL); + ret = ffurl_open_whitelist(&h, "async:async-test:", AVIO_FLAG_READ, + NULL, NULL, NULL, NULL, NULL); printf("open: %d\n", ret); size = ffurl_size(h); @@ -684,7 +689,8 @@ int main(void) */ ffurl_close(h); av_dict_set_int(&opts, "async-test-read-error", -10000, 0); - ret = ffurl_open(&h, "async:async-test:", AVIO_FLAG_READ, NULL, &opts); + ret = ffurl_open_whitelist(&h, "async:async-test:", AVIO_FLAG_READ, + NULL, &opts, NULL, NULL, NULL); printf("open: %d\n", ret); ret = ffurl_read(h, buf, 1); diff --git a/libavformat/au.c b/libavformat/au.c index 1e77dc3cb..c2c1b7a3a 100644 --- a/libavformat/au.c +++ b/libavformat/au.c @@ -35,8 +35,6 @@ /* if we don't know the size in advance */ #define AU_UNKNOWN_SIZE ((uint32_t)(~0)) -/* the specification requires an annotation field of at least eight bytes */ -#define AU_DEFAULT_HEADER_SIZE (24+8) static const AVCodecTag codec_au_tags[] = { { AV_CODEC_ID_PCM_MULAW, 1 }, @@ -55,6 +53,8 @@ static const AVCodecTag codec_au_tags[] = { { AV_CODEC_ID_NONE, 0 }, }; +static const AVCodecTag *const au_codec_tags[] = { codec_au_tags, NULL }; + #if CONFIG_AU_DEMUXER static int au_probe(const AVProbeData *p) @@ -68,20 +68,20 @@ static int au_probe(const AVProbeData *p) static int au_read_annotation(AVFormatContext *s, int size) { - static const char * keys[] = { + static const char keys[][7] = { "title", "artist", "album", "track", "genre", - NULL }; + }; AVIOContext *pb = s->pb; enum { PARSE_KEY, PARSE_VALUE, PARSE_FINISHED } state = PARSE_KEY; char c; AVBPrint bprint; char * key = NULL; char * value = NULL; - int i; + int ret, i; av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); @@ -97,7 +97,9 @@ static int au_read_annotation(AVFormatContext *s, int size) if (c == '\0') { state = PARSE_FINISHED; } else if (c == '=') { - av_bprint_finalize(&bprint, &key); + ret = av_bprint_finalize(&bprint, &key); + if (ret < 0) + return ret; av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); state = PARSE_VALUE; } else { @@ -110,11 +112,11 @@ static int au_read_annotation(AVFormatContext *s, int size) av_log(s, AV_LOG_ERROR, "Memory error while parsing AU metadata.\n"); } else { av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); - for (i = 0; keys[i] != NULL && key != NULL; i++) { + for (i = 0; i < FF_ARRAY_ELEMS(keys); i++) { if (av_strcasecmp(keys[i], key) == 0) { av_dict_set(&(s->metadata), keys[i], value, AV_DICT_DONT_STRDUP_VAL); - av_freep(&key); value = NULL; + break; } } } @@ -148,6 +150,7 @@ static int au_read_header(AVFormatContext *s) int bps, ba = 0; enum AVCodecID codec; AVStream *st; + int ret; tag = avio_rl32(pb); if (tag != MKTAG('.', 's', 'n', 'd')) @@ -166,7 +169,9 @@ static int au_read_header(AVFormatContext *s) if (size > 24) { /* parse annotation field to get metadata */ - au_read_annotation(s, size - 24); + ret = au_read_annotation(s, size - 24); + if (ret < 0) + return ret; } codec = ff_codec_get_id(codec_au_tags, id); @@ -228,7 +233,7 @@ AVInputFormat ff_au_demuxer = { .read_header = au_read_header, .read_packet = ff_pcm_read_packet, .read_seek = ff_pcm_read_seek, - .codec_tag = (const AVCodecTag* const []) { codec_au_tags, 0 }, + .codec_tag = au_codec_tags, }; #endif /* CONFIG_AU_DEMUXER */ @@ -241,36 +246,31 @@ typedef struct AUContext { #include "rawenc.h" -static int au_get_annotations(AVFormatContext *s, char **buffer) +static int au_get_annotations(AVFormatContext *s, AVBPrint *annotations) { - static const char * keys[] = { + static const char keys[][7] = { "Title", "Artist", "Album", "Track", "Genre", - NULL }; - int i; + }; int cnt = 0; AVDictionary *m = s->metadata; AVDictionaryEntry *t = NULL; - AVBPrint bprint; - av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); - - for (i = 0; keys[i] != NULL; i++) { + for (int i = 0; i < FF_ARRAY_ELEMS(keys); i++) { t = av_dict_get(m, keys[i], NULL, 0); if (t != NULL) { if (cnt++) - av_bprint_chars(&bprint, '\n', 1); - av_bprint_append_data(&bprint, keys[i], strlen(keys[i])); - av_bprint_chars(&bprint, '=', 1); - av_bprint_append_data(&bprint, t->value, strlen(t->value)); + av_bprint_chars(annotations, '\n', 1); + av_bprintf(annotations, "%s=%s", keys[i], t->value); } } - /* pad with 0's */ - av_bprint_append_data(&bprint, "\0\0\0\0\0\0\0\0", 8); - return av_bprint_finalize(&bprint, buffer); + /* The specification requires the annotation field to be zero-terminated + * and its length to be a multiple of eight, so pad with 0's */ + av_bprint_chars(annotations, '\0', 8); + return av_bprint_is_complete(annotations) ? 0 : AVERROR(ENOMEM); } static int au_write_header(AVFormatContext *s) @@ -279,9 +279,7 @@ static int au_write_header(AVFormatContext *s) AUContext *au = s->priv_data; AVIOContext *pb = s->pb; AVCodecParameters *par = s->streams[0]->codecpar; - char *annotations = NULL; - - au->header_size = AU_DEFAULT_HEADER_SIZE; + AVBPrint annotations; if (s->nb_streams != 1) { av_log(s, AV_LOG_ERROR, "only one stream is supported\n"); @@ -294,30 +292,24 @@ static int au_write_header(AVFormatContext *s) return AVERROR(EINVAL); } - if (av_dict_count(s->metadata) > 0) { - ret = au_get_annotations(s, &annotations); - if (ret < 0) - return ret; - if (annotations != NULL) { - au->header_size = (24 + strlen(annotations) + 8) & ~7; - if (au->header_size < AU_DEFAULT_HEADER_SIZE) - au->header_size = AU_DEFAULT_HEADER_SIZE; - } - } + av_bprint_init(&annotations, 0, INT_MAX - 24); + ret = au_get_annotations(s, &annotations); + if (ret < 0) + goto fail; + au->header_size = 24 + annotations.len & ~7; + ffio_wfourcc(pb, ".snd"); /* magic number */ avio_wb32(pb, au->header_size); /* header size */ avio_wb32(pb, AU_UNKNOWN_SIZE); /* data size */ avio_wb32(pb, par->codec_tag); /* codec ID */ avio_wb32(pb, par->sample_rate); avio_wb32(pb, par->channels); - if (annotations != NULL) { - avio_write(pb, annotations, au->header_size - 24); - av_freep(&annotations); - } else { - avio_wb64(pb, 0); /* annotation field */ - } + avio_write(pb, annotations.str, annotations.len & ~7); - return 0; +fail: + av_bprint_finalize(&annotations, NULL); + + return ret; } static int au_write_trailer(AVFormatContext *s) @@ -347,7 +339,7 @@ AVOutputFormat ff_au_muxer = { .write_header = au_write_header, .write_packet = ff_raw_write_packet, .write_trailer = au_write_trailer, - .codec_tag = (const AVCodecTag* const []) { codec_au_tags, 0 }, + .codec_tag = au_codec_tags, .flags = AVFMT_NOTIMESTAMPS, }; diff --git a/libavformat/av1.c b/libavformat/av1.c index 1e7a67d2f..5512c4e0f 100644 --- a/libavformat/av1.c +++ b/libavformat/av1.c @@ -363,11 +363,11 @@ int ff_av1_parse_seq_header(AV1SequenceParameters *seq, const uint8_t *buf, int int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) { - AVIOContext *seq_pb = NULL, *meta_pb = NULL; + AVIOContext *meta_pb; AV1SequenceParameters seq_params; PutBitContext pbc; - uint8_t header[4]; - uint8_t *seq, *meta; + uint8_t header[4], *meta; + const uint8_t *seq; int64_t obu_size; int start_pos, type, temporal_id, spatial_id; int ret, nb_seq = 0, seq_size, meta_size; @@ -375,12 +375,23 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) if (size <= 0) return AVERROR_INVALIDDATA; - ret = avio_open_dyn_buf(&seq_pb); - if (ret < 0) - return ret; + if (buf[0] & 0x80) { + // first bit is nonzero, the passed data does not consist purely of + // OBUs. Expect that the data is already in AV1CodecConfigurationRecord + // format. + int config_record_version = buf[0] & 0x7f; + if (config_record_version != 1 || size < 4) { + return AVERROR_INVALIDDATA; + } + + avio_write(pb, buf, size); + + return 0; + } + ret = avio_open_dyn_buf(&meta_pb); if (ret < 0) - goto fail; + return ret; while (size > 0) { int len = parse_obu_header(buf, size, &obu_size, &start_pos, @@ -401,7 +412,8 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) if (ret < 0) goto fail; - avio_write(seq_pb, buf, len); + seq = buf; + seq_size = len; break; case AV1_OBU_METADATA: if (!obu_size) { @@ -417,8 +429,7 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) buf += len; } - seq_size = avio_get_dyn_buf(seq_pb, &seq); - if (!seq_size) { + if (!nb_seq) { ret = AVERROR_INVALIDDATA; goto fail; } @@ -447,7 +458,6 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) avio_write(pb, meta, meta_size); fail: - ffio_free_dyn_buf(&seq_pb); ffio_free_dyn_buf(&meta_pb); return ret; diff --git a/libavformat/av1dec.c b/libavformat/av1dec.c index 1be2fac1c..5ae81b34d 100644 --- a/libavformat/av1dec.c +++ b/libavformat/av1dec.c @@ -22,12 +22,77 @@ #include "config.h" #include "libavutil/common.h" +#include "libavutil/fifo.h" #include "libavutil/opt.h" #include "libavcodec/av1_parse.h" #include "avformat.h" #include "avio_internal.h" #include "internal.h" +//return < 0 if we need more data +static int get_score(int type, int *seq) +{ + switch (type) { + case AV1_OBU_SEQUENCE_HEADER: + *seq = 1; + return -1; + case AV1_OBU_FRAME: + case AV1_OBU_FRAME_HEADER: + return *seq ? AVPROBE_SCORE_EXTENSION + 1 : 0; + case AV1_OBU_METADATA: + case AV1_OBU_PADDING: + return -1; + default: + break; + } + return 0; +} + +static int read_header(AVFormatContext *s, const AVRational *framerate, AVBSFContext **bsf, void *logctx) +{ + const AVBitStreamFilter *filter = av_bsf_get_by_name("av1_frame_merge"); + AVStream *st; + int ret; + + if (!filter) { + av_log(logctx, AV_LOG_ERROR, "av1_frame_merge bitstream filter " + "not found. This is a bug, please report it.\n"); + return AVERROR_BUG; + } + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = AV_CODEC_ID_AV1; + st->need_parsing = AVSTREAM_PARSE_HEADERS; + + st->internal->avctx->framerate = *framerate; + // taken from rawvideo demuxers + avpriv_set_pts_info(st, 64, 1, 1200000); + + ret = av_bsf_alloc(filter, bsf); + if (ret < 0) + return ret; + + ret = avcodec_parameters_copy((*bsf)->par_in, st->codecpar); + if (ret < 0) { + av_bsf_free(bsf); + return ret; + } + + ret = av_bsf_init(*bsf); + if (ret < 0) + av_bsf_free(bsf); + + return ret; + +} + +#define DEC AV_OPT_FLAG_DECODING_PARAM + +#if CONFIG_AV1_DEMUXER typedef struct AnnexBContext { const AVClass *class; AVBSFContext *bsf; @@ -89,13 +154,11 @@ static int annexb_probe(const AVProbeData *p) if (ret < 0 || ((int64_t)frame_unit_size + ret) > temporal_unit_size) return 0; cnt += ret; - temporal_unit_size -= ret; ret = leb(&pb, &obu_unit_size); if (ret < 0 || ((int64_t)obu_unit_size + ret) >= frame_unit_size) return 0; cnt += ret; - temporal_unit_size -= obu_unit_size + ret; frame_unit_size -= obu_unit_size + ret; avio_skip(&pb, obu_unit_size); @@ -123,21 +186,10 @@ static int annexb_probe(const AVProbeData *p) return 0; cnt += obu_unit_size; - switch (type) { - case AV1_OBU_SEQUENCE_HEADER: - seq = 1; - break; - case AV1_OBU_FRAME: - case AV1_OBU_FRAME_HEADER: - return seq ? AVPROBE_SCORE_EXTENSION + 1 : 0; - case AV1_OBU_TILE_GROUP: - case AV1_OBU_TEMPORAL_DELIMITER: - return 0; - default: - break; - } + ret = get_score(type, &seq); + if (ret >= 0) + return ret; - temporal_unit_size -= obu_unit_size + ret; frame_unit_size -= obu_unit_size + ret; } while (frame_unit_size); @@ -147,43 +199,7 @@ static int annexb_probe(const AVProbeData *p) static int annexb_read_header(AVFormatContext *s) { AnnexBContext *c = s->priv_data; - const AVBitStreamFilter *filter = av_bsf_get_by_name("av1_frame_merge"); - AVStream *st; - int ret; - - if (!filter) { - av_log(c, AV_LOG_ERROR, "av1_frame_merge bitstream filter " - "not found. This is a bug, please report it.\n"); - return AVERROR_BUG; - } - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; - st->codecpar->codec_id = AV_CODEC_ID_AV1; - st->need_parsing = AVSTREAM_PARSE_HEADERS; - - st->internal->avctx->framerate = c->framerate; - // taken from rawvideo demuxers - avpriv_set_pts_info(st, 64, 1, 1200000); - - ret = av_bsf_alloc(filter, &c->bsf); - if (ret < 0) - return ret; - - ret = avcodec_parameters_copy(c->bsf->par_in, st->codecpar); - if (ret < 0) { - av_bsf_free(&c->bsf); - return ret; - } - - ret = av_bsf_init(c->bsf); - if (ret < 0) - av_bsf_free(&c->bsf); - - return ret; + return read_header(s, &c->framerate, &c->bsf, c); } static int annexb_read_packet(AVFormatContext *s, AVPacket *pkt) @@ -252,11 +268,11 @@ static int annexb_read_close(AVFormatContext *s) } #define OFFSET(x) offsetof(AnnexBContext, x) -#define DEC AV_OPT_FLAG_DECODING_PARAM static const AVOption annexb_options[] = { { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC}, { NULL }, }; +#undef OFFSET static const AVClass annexb_demuxer_class = { .class_name = "AV1 Annex B demuxer", @@ -277,3 +293,191 @@ AVInputFormat ff_av1_demuxer = { .flags = AVFMT_GENERIC_INDEX, .priv_class = &annexb_demuxer_class, }; +#endif + +#if CONFIG_OBU_DEMUXER +typedef struct ObuContext { + const AVClass *class; + AVBSFContext *bsf; + AVRational framerate; + AVFifoBuffer *fifo; +} ObuContext; + +//For low overhead obu, we can't foresee the obu size before we parsed the header. +//So, we can't use parse_obu_header here, since it will check size <= buf_size +//see c27c7b49dc for more details +static int read_obu_with_size(const uint8_t *buf, int buf_size, int64_t *obu_size, int *type) +{ + GetBitContext gb; + int ret, extension_flag, start_pos; + int64_t size; + + ret = init_get_bits8(&gb, buf, FFMIN(buf_size, MAX_OBU_HEADER_SIZE)); + if (ret < 0) + return ret; + + if (get_bits1(&gb) != 0) // obu_forbidden_bit + return AVERROR_INVALIDDATA; + + *type = get_bits(&gb, 4); + extension_flag = get_bits1(&gb); + if (!get_bits1(&gb)) // has_size_flag + return AVERROR_INVALIDDATA; + skip_bits1(&gb); // obu_reserved_1bit + + if (extension_flag) { + get_bits(&gb, 3); // temporal_id + get_bits(&gb, 2); // spatial_id + skip_bits(&gb, 3); // extension_header_reserved_3bits + } + + *obu_size = leb128(&gb); + if (*obu_size > INT_MAX) + return AVERROR_INVALIDDATA; + + if (get_bits_left(&gb) < 0) + return AVERROR_INVALIDDATA; + + start_pos = get_bits_count(&gb) / 8; + + size = *obu_size + start_pos; + if (size > INT_MAX) + return AVERROR_INVALIDDATA; + return size; +} + +static int obu_probe(const AVProbeData *p) +{ + int64_t obu_size; + int seq = 0; + int ret, type, cnt; + + // Check that the first OBU is a Temporal Delimiter. + cnt = read_obu_with_size(p->buf, p->buf_size, &obu_size, &type); + if (cnt < 0 || type != AV1_OBU_TEMPORAL_DELIMITER || obu_size != 0) + return 0; + + while (1) { + ret = read_obu_with_size(p->buf + cnt, p->buf_size - cnt, &obu_size, &type); + if (ret < 0 || obu_size <= 0) + return 0; + cnt += FFMIN(ret, p->buf_size - cnt); + + ret = get_score(type, &seq); + if (ret >= 0) + return ret; + } + return 0; +} + +static int obu_read_header(AVFormatContext *s) +{ + ObuContext *c = s->priv_data; + c->fifo = av_fifo_alloc(MAX_OBU_HEADER_SIZE); + if (!c->fifo) + return AVERROR(ENOMEM); + return read_header(s, &c->framerate, &c->bsf, c); +} + +static int obu_get_packet(AVFormatContext *s, AVPacket *pkt) +{ + ObuContext *c = s->priv_data; + uint8_t header[MAX_OBU_HEADER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; + int64_t obu_size; + int size = av_fifo_space(c->fifo); + int ret, len, type; + + av_fifo_generic_write(c->fifo, s->pb, size, + (int (*)(void*, void*, int))avio_read); + size = av_fifo_size(c->fifo); + if (!size) + return 0; + + av_fifo_generic_peek(c->fifo, header, size, NULL); + + len = read_obu_with_size(header, size, &obu_size, &type); + if (len < 0) { + av_log(c, AV_LOG_ERROR, "Failed to read obu\n"); + return len; + } + + ret = av_new_packet(pkt, len); + if (ret < 0) { + av_log(c, AV_LOG_ERROR, "Failed to allocate packet for obu\n"); + return ret; + } + size = FFMIN(size, len); + av_fifo_generic_read(c->fifo, pkt->data, size, NULL); + len -= size; + if (len > 0) { + ret = avio_read(s->pb, pkt->data + size, len); + if (ret != len) { + av_log(c, AV_LOG_ERROR, "Failed to read %d frome file\n", len); + return ret < 0 ? ret : AVERROR_INVALIDDATA; + } + } + return 0; +} + +static int obu_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + ObuContext *c = s->priv_data; + int ret; + + while (1) { + ret = obu_get_packet(s, pkt); + if (ret < 0) + return ret; + ret = av_bsf_send_packet(c->bsf, pkt); + if (ret < 0) { + av_log(s, AV_LOG_ERROR, "Failed to send packet to " + "av1_frame_merge filter\n"); + return ret; + } + ret = av_bsf_receive_packet(c->bsf, pkt); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + av_log(s, AV_LOG_ERROR, "av1_frame_merge filter failed to " + "send output packet\n"); + if (ret != AVERROR(EAGAIN)) + break; + } + + return ret; +} + +static int obu_read_close(AVFormatContext *s) +{ + ObuContext *c = s->priv_data; + + av_fifo_freep(&c->fifo); + av_bsf_free(&c->bsf); + return 0; +} + +#define OFFSET(x) offsetof(ObuContext, x) +static const AVOption obu_options[] = { + { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC}, + { NULL }, +}; +#undef OFFSET + +static const AVClass obu_demuxer_class = { + .class_name = "AV1 low overhead OBU demuxer", + .item_name = av_default_item_name, + .option = obu_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVInputFormat ff_obu_demuxer = { + .name = "obu", + .long_name = NULL_IF_CONFIG_SMALL("AV1 low overhead OBU"), + .priv_data_size = sizeof(ObuContext), + .read_probe = obu_probe, + .read_header = obu_read_header, + .read_packet = obu_read_packet, + .read_close = obu_read_close, + .extensions = "obu", + .flags = AVFMT_GENERIC_INDEX, + .priv_class = &obu_demuxer_class, +}; +#endif diff --git a/libavformat/avc.c b/libavformat/avc.c index cc452d71a..b5e292138 100644 --- a/libavformat/avc.c +++ b/libavformat/avc.c @@ -27,7 +27,7 @@ #include "avc.h" #include "avio_internal.h" -static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uint8_t *end) +static const uint8_t *avc_find_startcode_internal(const uint8_t *p, const uint8_t *end) { const uint8_t *a = p + 4 - ((intptr_t)p & 3); @@ -65,7 +65,7 @@ static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uin } const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){ - const uint8_t *out= ff_avc_find_startcode_internal(p, end); + const uint8_t *out = avc_find_startcode_internal(p, end); if(p decoder has not been searched for yet. - * >0 -> decoder found - * <0 -> decoder with codec_id == -found_decoder has not been found - */ - int found_decoder; - - int64_t last_duration; - - /** - * Those are used for average framerate estimation. - */ - int64_t fps_first_dts; - int fps_first_dts_idx; - int64_t fps_last_dts; - int fps_last_dts_idx; - - } *info; +#if LIBAVFORMAT_VERSION_MAJOR < 59 + // kept for ABI compatibility only, do not access in any way + void *unused; +#endif int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ @@ -1085,14 +1083,12 @@ typedef struct AVStream { enum AVStreamParseType need_parsing; struct AVCodecParserContext *parser; - /** - * last packet in packet_buffer for this stream when muxing. - */ - struct AVPacketList *last_in_packet_buffer; - AVProbeData probe_data; -#define MAX_REORDER_DELAY 16 - int64_t pts_buffer[MAX_REORDER_DELAY+1]; - +#if LIBAVFORMAT_VERSION_MAJOR < 59 + // kept for ABI compatibility only, do not access in any way + void *unused7; + AVProbeData unused6; + int64_t unused5[16+1]; +#endif AVIndexEntry *index_entries; /**< Only used if the format does not support seeking natively. */ int nb_index_entries; @@ -1105,115 +1101,12 @@ typedef struct AVStream { */ int stream_identifier; - /** - * Details of the MPEG-TS program which created this stream. - */ - int program_num; - int pmt_version; - int pmt_stream_idx; - - int64_t interleaver_chunk_size; - int64_t interleaver_chunk_duration; - - /** - * stream probing state - * -1 -> probing finished - * 0 -> no probing requested - * rest -> perform probing with request_probe being the minimum score to accept. - */ - int request_probe; - /** - * Indicates that everything up to the next keyframe - * should be discarded. - */ - int skip_to_keyframe; - - /** - * Number of samples to skip at the start of the frame decoded from the next packet. - */ - int skip_samples; - - /** - * If not 0, the number of samples that should be skipped from the start of - * the stream (the samples are removed from packets with pts==0, which also - * assumes negative timestamps do not happen). - * Intended for use with formats such as mp3 with ad-hoc gapless audio - * support. - */ - int64_t start_skip_samples; - - /** - * If not 0, the first audio sample that should be discarded from the stream. - * This is broken by design (needs global sample count), but can't be - * avoided for broken by design formats such as mp3 with ad-hoc gapless - * audio support. - */ - int64_t first_discard_sample; - - /** - * The sample after last sample that is intended to be discarded after - * first_discard_sample. Works on frame boundaries only. Used to prevent - * early EOF if the gapless info is broken (considered concatenated mp3s). - */ - int64_t last_discard_sample; - - /** - * Number of internally decoded frames, used internally in libavformat, do not access - * its lifetime differs from info which is why it is not in that structure. - */ - int nb_decoded_frames; - - /** - * Timestamp offset added to timestamps before muxing - */ - int64_t mux_ts_offset; - - /** - * Internal data to check for wrapping of the time stamp - */ - int64_t pts_wrap_reference; - - /** - * Options for behavior, when a wrap is detected. - * - * Defined by AV_PTS_WRAP_ values. - * - * If correction is enabled, there are two possibilities: - * If the first time stamp is near the wrap point, the wrap offset - * will be subtracted, which will create negative time stamps. - * Otherwise the offset will be added. - */ - int pts_wrap_behavior; - - /** - * Internal data to prevent doing update_initial_durations() twice - */ - int update_initial_durations_done; - - /** - * Internal data to generate dts from pts - */ - int64_t pts_reorder_error[MAX_REORDER_DELAY+1]; - uint8_t pts_reorder_error_count[MAX_REORDER_DELAY+1]; - - /** - * Internal data to analyze DTS and detect faulty mpeg streams - */ - int64_t last_dts_for_order_check; - uint8_t dts_ordered; - uint8_t dts_misordered; - - /** - * Internal data to inject global side data - */ - int inject_global_side_data; - - /** - * display aspect ratio (0 if unknown) - * - encoding: unused - * - decoding: Set by libavformat to calculate sample_aspect_ratio internally - */ - AVRational display_aspect_ratio; +#if LIBAVFORMAT_VERSION_MAJOR < 59 + // kept for ABI compatibility only, do not access in any way + int unused8; + int unused9; + int unused10; +#endif /** * An opaque field for libavformat internal usage. @@ -1292,7 +1185,11 @@ typedef struct AVProgram { change dynamically at runtime. */ typedef struct AVChapter { +#if FF_API_CHAPTER_ID_INT int id; ///< unique ID to identify the chapter +#else + int64_t id; ///< unique ID to identify the chapter +#endif AVRational time_base; ///< time base in which the start/end timestamps are specified int64_t start, end; ///< chapter start/end time in time_base units AVDictionary *metadata; @@ -1487,7 +1384,9 @@ typedef struct AVFormatContext { #define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Deprecated, does nothing. #endif #define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down) -#define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted) +#if FF_API_LAVF_PRIV_OPT +#define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (deprecated, will do nothing once av_demuxer_open() is removed) +#endif #if FF_API_LAVF_KEEPSIDE_FLAG #define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Deprecated, does nothing. #endif @@ -1645,12 +1544,24 @@ typedef struct AVFormatContext { int strict_std_compliance; /** - * Flags for the user to detect events happening on the file. Flags must - * be cleared by the user once the event has been handled. - * A combination of AVFMT_EVENT_FLAG_*. + * Flags indicating events happening on the file, a combination of + * AVFMT_EVENT_FLAG_*. + * + * - demuxing: may be set by the demuxer in avformat_open_input(), + * avformat_find_stream_info() and av_read_frame(). Flags must be cleared + * by the user once the event has been handled. + * - muxing: may be set by the user after avformat_write_header() to + * indicate a user-triggered event. The muxer will clear the flags for + * events it has handled in av_[interleaved]_write_frame(). */ int event_flags; -#define AVFMT_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in updated metadata. +/** + * - demuxing: the demuxer read new metadata from the file and updated + * AVFormatContext.metadata accordingly + * - muxing: the user updated AVFormatContext.metadata and wishes the muxer to + * write it into the file + */ +#define AVFMT_EVENT_FLAG_METADATA_UPDATED 0x0001 /** * Maximum number of packets to read while waiting for the first timestamp. @@ -2007,12 +1918,6 @@ void av_format_inject_global_side_data(AVFormatContext *s); */ enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx); -typedef struct AVPacketList { - AVPacket pkt; - struct AVPacketList *next; -} AVPacketList; - - /** * @defgroup lavf_core Core functions * @ingroup libavf @@ -2183,17 +2088,26 @@ int av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type, * @return pointer to fresh allocated data or NULL otherwise */ uint8_t *av_stream_new_side_data(AVStream *stream, +#if FF_API_BUFFER_SIZE_T enum AVPacketSideDataType type, int size); +#else + enum AVPacketSideDataType type, size_t size); +#endif /** * Get side information from stream. * * @param stream stream * @param type desired side information type - * @param size pointer for side information size to store (optional) + * @param size If supplied, *size will be set to the size of the side data + * or to zero if the desired side data is not present. * @return pointer to data if present or NULL otherwise */ uint8_t *av_stream_get_side_data(const AVStream *stream, +#if FF_API_BUFFER_SIZE_T enum AVPacketSideDataType type, int *size); +#else + enum AVPacketSideDataType type, size_t *size); +#endif AVProgram *av_new_program(AVFormatContext *s, int id); @@ -2311,8 +2225,13 @@ int av_probe_input_buffer(AVIOContext *pb, ff_const59 AVInputFormat **fmt, */ int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options); +#if FF_API_DEMUXER_OPEN +/** + * @deprecated Use an AVDictionary to pass options to a demuxer. + */ attribute_deprecated int av_demuxer_open(AVFormatContext *ic); +#endif /** * Read packets of a media file to get stream information. This diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 0d66ad231..59929afd4 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -59,7 +59,7 @@ typedef struct AVIStream { * the MS dshow demuxer */ AVFormatContext *sub_ctx; - AVPacket sub_pkt; + AVPacket *sub_pkt; AVBufferRef *sub_buffer; int64_t seek_pos; @@ -110,9 +110,19 @@ static const char avi_headers[][8] = { static const AVMetadataConv avi_metadata_conv[] = { { "strn", "title" }, + { "isbj", "subject" }, + { "inam", "title" }, + { "iart", "artist" }, + { "icop", "copyright" }, + { "icmt", "comment" }, + { "ignr", "genre" }, + { "iprd", "product" }, + { "isft", "software" }, + { 0 }, }; +static int avi_read_close(AVFormatContext *s); static int avi_load_index(AVFormatContext *s); static int guess_ni_flag(AVFormatContext *s); @@ -464,6 +474,7 @@ static int calculate_bitrate(AVFormatContext *s) return 1; } +#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0) static int avi_read_header(AVFormatContext *s) { AVIContext *avi = s->priv_data; @@ -499,7 +510,7 @@ static int avi_read_header(AVFormatContext *s) frame_period = 0; for (;;) { if (avio_feof(pb)) - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); tag = avio_rl32(pb); size = avio_rl32(pb); @@ -571,12 +582,12 @@ static int avi_read_header(AVFormatContext *s) stream_index++; st = avformat_new_stream(s, NULL); if (!st) - goto fail; + RETURN_ERROR(AVERROR(ENOMEM)); st->id = stream_index; ast = av_mallocz(sizeof(AVIStream)); if (!ast) - goto fail; + RETURN_ERROR(AVERROR(ENOMEM)); st->priv_data = ast; } if (amv_file_format) @@ -592,12 +603,12 @@ static int avi_read_header(AVFormatContext *s) /* After some consideration -- I don't think we * have to support anything but DV in type1 AVIs. */ if (s->nb_streams != 1) - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); if (handler != MKTAG('d', 'v', 's', 'd') && handler != MKTAG('d', 'v', 'h', 'd') && handler != MKTAG('d', 'v', 's', 'l')) - goto fail; + return AVERROR_INVALIDDATA; if (!CONFIG_DV_DEMUXER) return AVERROR_DEMUXER_NOT_FOUND; @@ -697,7 +708,7 @@ static int avi_read_header(AVFormatContext *s) "Invalid sample_size %d at stream %d\n", ast->sample_size, stream_index); - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); } av_log(s, AV_LOG_WARNING, "Invalid sample_size %d at stream %d " @@ -827,6 +838,12 @@ static int avi_read_header(AVFormatContext *s) st->codecpar->codec_tag == MKTAG('H', '2', '6', '5')) st->need_parsing = AVSTREAM_PARSE_FULL; + if (st->codecpar->codec_id == AV_CODEC_ID_AVRN && + st->codecpar->codec_tag == MKTAG('A', 'V', 'R', 'n') && + (st->codecpar->extradata_size < 31 || + memcmp(&st->codecpar->extradata[28], "1:1", 3))) + st->codecpar->codec_id = AV_CODEC_ID_MJPEG; + if (st->codecpar->codec_tag == 0 && st->codecpar->height > 0 && st->codecpar->extradata_size < 1U << 30) { st->codecpar->extradata_size += 9; @@ -899,7 +916,7 @@ static int avi_read_header(AVFormatContext *s) break; case AVMEDIA_TYPE_SUBTITLE: st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->request_probe= 1; + st->internal->request_probe= 1; avio_skip(pb, size); break; default: @@ -927,7 +944,7 @@ static int avi_read_header(AVFormatContext *s) av_log(s, AV_LOG_WARNING, "New extradata in strd chunk, freeing previous one.\n"); } if ((ret = ff_get_extradata(s, st->codecpar, pb, size)) < 0) - return ret; + goto fail; } if (st->codecpar->extradata_size & 1) //FIXME check if the encoder really did this correctly @@ -945,7 +962,7 @@ static int avi_read_header(AVFormatContext *s) avi->use_odml && read_odml_index(s, 0) < 0 && (s->error_recognition & AV_EF_EXPLODE)) - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); avio_seek(pb, pos + size, SEEK_SET); break; case MKTAG('v', 'p', 'r', 'p'): @@ -977,10 +994,18 @@ static int avi_read_header(AVFormatContext *s) avio_skip(pb, size); break; case MKTAG('s', 't', 'r', 'n'): + case MKTAG('i', 's', 'b', 'j'): + case MKTAG('i', 'n', 'a', 'm'): + case MKTAG('i', 'a', 'r', 't'): + case MKTAG('i', 'c', 'o', 'p'): + case MKTAG('i', 'c', 'm', 't'): + case MKTAG('i', 'g', 'n', 'r'): + case MKTAG('i', 'p', 'o', 'd'): + case MKTAG('i', 's', 'o', 'f'): if (s->nb_streams) { ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size); if (ret < 0) - return ret; + goto fail; break; } default: @@ -991,7 +1016,7 @@ static int avi_read_header(AVFormatContext *s) "I will ignore it and try to continue anyway.\n", av_fourcc2str(tag), size); if (s->error_recognition & AV_EF_EXPLODE) - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); avi->movi_list = avio_tell(pb) - 4; avi->movi_end = avi->fsize; goto end_of_header; @@ -1008,9 +1033,7 @@ static int avi_read_header(AVFormatContext *s) end_of_header: /* check stream number */ if (stream_index != s->nb_streams - 1) { - -fail: - return AVERROR_INVALIDDATA; + RETURN_ERROR(AVERROR_INVALIDDATA); } if (!avi->index_loaded && (pb->seekable & AVIO_SEEKABLE_NORMAL)) @@ -1019,7 +1042,7 @@ fail: avi->index_loaded |= 1; if ((ret = guess_ni_flag(s)) < 0) - return ret; + goto fail; avi->non_interleaved |= ret | (s->flags & AVFMT_FLAG_SORT_DTS); @@ -1056,6 +1079,9 @@ fail: ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); return 0; +fail: + avi_read_close(s); + return ret; } static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) @@ -1069,11 +1095,15 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) ff_const59 AVInputFormat *sub_demuxer; AVRational time_base; int size; + AVProbeData pd; + unsigned int desc_len; AVIOContext *pb = avio_alloc_context(pkt->data + 7, pkt->size - 7, 0, NULL, NULL, NULL, NULL); - AVProbeData pd; - unsigned int desc_len = avio_rl32(pb); + if (!pb) + goto error; + + desc_len = avio_rl32(pb); if (desc_len > pb->buf_end - pb->buf_ptr) goto error; @@ -1100,6 +1130,9 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) if (strcmp(sub_demuxer->name, "srt") && strcmp(sub_demuxer->name, "ass")) goto error; + if (!(ast->sub_pkt = av_packet_alloc())) + goto error; + if (!(ast->sub_ctx = avformat_alloc_context())) goto error; @@ -1111,7 +1144,7 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) { if (ast->sub_ctx->nb_streams != 1) goto error; - ff_read_packet(ast->sub_ctx, &ast->sub_pkt); + ff_read_packet(ast->sub_ctx, ast->sub_pkt); avcodec_parameters_copy(st->codecpar, ast->sub_ctx->streams[0]->codecpar); time_base = ast->sub_ctx->streams[0]->time_base; avpriv_set_pts_info(st, 64, time_base.num, time_base.den); @@ -1122,6 +1155,7 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) return 1; error: + av_packet_free(&ast->sub_pkt); av_freep(&ast->sub_ctx); avio_context_free(&pb); } @@ -1142,8 +1176,8 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st, for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; ast = st->priv_data; - if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) { - ts = av_rescale_q(ast->sub_pkt.dts, st->time_base, AV_TIME_BASE_Q); + if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt && ast->sub_pkt->data) { + ts = av_rescale_q(ast->sub_pkt->dts, st->time_base, AV_TIME_BASE_Q); if (ts <= next_ts && ts < ts_min) { ts_min = ts; sub_st = st; @@ -1153,11 +1187,11 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st, if (sub_st) { ast = sub_st->priv_data; - *pkt = ast->sub_pkt; + av_packet_move_ref(pkt, ast->sub_pkt); pkt->stream_index = sub_st->index; - if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0) - ast->sub_pkt.data = NULL; + if (ff_read_packet(ast->sub_ctx, ast->sub_pkt) < 0) + ast->sub_pkt->data = NULL; } return sub_st; } @@ -1254,7 +1288,7 @@ start_sync: AVStream *st1 = s->streams[1]; AVIStream *ast1 = st1->priv_data; // workaround for broken small-file-bug402.avi - if ( d[2] == 'w' && d[3] == 'b' + if (ast1 && d[2] == 'w' && d[3] == 'b' && n == 0 && st ->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st1->codecpar->codec_type == AVMEDIA_TYPE_AUDIO @@ -1459,7 +1493,7 @@ resync: } } - if (dv_demux) { + if (CONFIG_DV_DEMUXER && dv_demux) { AVBufferRef *avbuf = pkt->buf; size = avpriv_dv_produce_packet(avi->dv_demux, pkt, pkt->data, pkt->size, pkt->pos); @@ -1668,18 +1702,19 @@ static int check_stream_max_drift(AVFormatContext *s) AVIStream *ast = st->priv_data; if (idx[i] && min_dts != INT64_MAX / 2) { - int64_t dts; + int64_t dts, delta_dts; dts = av_rescale_q(st->index_entries[idx[i] - 1].timestamp / FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q); + delta_dts = av_sat_sub64(dts, min_dts); max_dts = FFMAX(max_dts, dts); max_buffer = FFMAX(max_buffer, - av_rescale(dts - min_dts, + av_rescale(delta_dts, st->codecpar->bit_rate, AV_TIME_BASE)); } } - if (max_dts - min_dts > 2 * AV_TIME_BASE || + if (av_sat_sub64(max_dts, min_dts) > 2 * AV_TIME_BASE || max_buffer > 1024 * 1024 * 8 * 8) { av_free(idx); return 1; @@ -1775,10 +1810,10 @@ static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp) { AVIStream *ast2 = st2->priv_data; int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base); - av_packet_unref(&ast2->sub_pkt); + av_packet_unref(ast2->sub_pkt); if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 || avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0) - ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt); + ff_read_packet(ast2->sub_ctx, ast2->sub_pkt); } static int avi_read_seek(AVFormatContext *s, int stream_index, @@ -1912,7 +1947,7 @@ static int avi_read_close(AVFormatContext *s) avformat_close_input(&ast->sub_ctx); } av_buffer_unref(&ast->sub_buffer); - av_packet_unref(&ast->sub_pkt); + av_packet_free(&ast->sub_pkt); } } diff --git a/libavformat/avienc.c b/libavformat/avienc.c index 297d5b896..ac11dd9cb 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -66,12 +66,14 @@ typedef struct AVIIndex { typedef struct AVIContext { const AVClass *class; + AVPacket *empty_packet; int64_t riff_start, movi_list, odml_list; int64_t frames_hdr_all; int riff_id; int reserve_index_space; int master_index_max_size; int write_channel_mask; + int flipped_raw_rgb; } AVIContext; typedef struct AVIStream { @@ -273,6 +275,10 @@ static int avi_write_header(AVFormatContext *s) return AVERROR(EINVAL); } + avi->empty_packet = av_packet_alloc(); + if (!avi->empty_packet) + return AVERROR(ENOMEM); + for (n = 0; n < s->nb_streams; n++) { s->streams[n]->priv_data = av_mallocz(sizeof(AVIStream)); if (!s->streams[n]->priv_data) @@ -449,7 +455,7 @@ static int avi_write_header(AVFormatContext *s) && par->bits_per_coded_sample == 15) par->bits_per_coded_sample = 16; avist->pal_offset = avio_tell(pb) + 40; - ff_put_bmp_header(pb, par, 0, 0); + ff_put_bmp_header(pb, par, 0, 0, avi->flipped_raw_rgb); pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi, par->bits_per_coded_sample); if ( !par->codec_tag @@ -738,24 +744,21 @@ static int avi_write_idx1(AVFormatContext *s) static int write_skip_frames(AVFormatContext *s, int stream_index, int64_t dts) { + AVIContext *avi = s->priv_data; AVIStream *avist = s->streams[stream_index]->priv_data; AVCodecParameters *par = s->streams[stream_index]->codecpar; ff_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(dts), avist->packet_count, stream_index); while (par->block_align == 0 && dts != AV_NOPTS_VALUE && dts > avist->packet_count && par->codec_id != AV_CODEC_ID_XSUB && avist->packet_count) { - AVPacket empty_packet; if (dts - avist->packet_count > 60000) { av_log(s, AV_LOG_ERROR, "Too large number of skipped frames %"PRId64" > 60000\n", dts - avist->packet_count); return AVERROR(EINVAL); } - av_init_packet(&empty_packet); - empty_packet.size = 0; - empty_packet.data = NULL; - empty_packet.stream_index = stream_index; - avi_write_packet_internal(s, &empty_packet); + avi->empty_packet->stream_index = stream_index; + avi_write_packet_internal(s, avi->empty_packet); ff_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(dts), avist->packet_count); } @@ -977,6 +980,10 @@ static int avi_write_trailer(AVFormatContext *s) static void avi_deinit(AVFormatContext *s) { + AVIContext *avi = s->priv_data; + + av_packet_free(&avi->empty_packet); + for (int i = 0; i < s->nb_streams; i++) { AVIStream *avist = s->streams[i]->priv_data; if (!avist) @@ -993,6 +1000,7 @@ static void avi_deinit(AVFormatContext *s) static const AVOption options[] = { { "reserve_index_space", "reserve space (in bytes) at the beginning of the file for each stream index", OFFSET(reserve_index_space), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, ENC }, { "write_channel_mask", "write channel mask into wave format header", OFFSET(write_channel_mask), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC }, + { "flipped_raw_rgb", "Raw RGB bitmaps are stored bottom-up", OFFSET(flipped_raw_rgb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC }, { NULL }, }; @@ -1016,8 +1024,6 @@ AVOutputFormat ff_avi_muxer = { .write_header = avi_write_header, .write_packet = avi_write_packet, .write_trailer = avi_write_trailer, - .codec_tag = (const AVCodecTag * const []) { - ff_codec_bmp_tags, ff_codec_wav_tags, 0 - }, + .codec_tag = ff_riff_codec_tags_list, .priv_class = &avi_muxer_class, }; diff --git a/libavformat/avio.c b/libavformat/avio.c index 237966c30..8011482e7 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -67,7 +67,10 @@ const AVClass ffurl_context_class = { .option = options, .version = LIBAVUTIL_VERSION_INT, .child_next = urlcontext_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = ff_urlcontext_child_class_next, +#endif + .child_class_iterate = ff_urlcontext_child_class_iterate, }; /*@}*/ @@ -111,11 +114,10 @@ static int url_alloc_for_protocol(URLContext **puc, const URLProtocol *up, goto fail; } if (up->priv_data_class) { - int proto_len= strlen(up->name); - char *start = strchr(uc->filename, ','); + char *start; *(const AVClass **)uc->priv_data = up->priv_data_class; av_opt_set_defaults(uc->priv_data); - if(!strncmp(up->name, uc->filename, proto_len) && uc->filename + proto_len == start){ + if (av_strstart(uc->filename, up->name, (const char**)&start) && *start == ',') { int ret= 0; char *p= start; char sep= *++p; @@ -351,13 +353,6 @@ fail: return ret; } -int ffurl_open(URLContext **puc, const char *filename, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options) -{ - return ffurl_open_whitelist(puc, filename, flags, - int_cb, options, NULL, NULL, NULL); -} - static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf, int size, int size_min, int (*transfer_func)(URLContext *h, diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h index c575df803..fe87f2a28 100644 --- a/libavformat/avio_internal.h +++ b/libavformat/avio_internal.h @@ -100,7 +100,9 @@ int ffio_realloc_buf(AVIOContext *s, int buf_size); * * Will ensure that when reading sequentially up to buf_size, seeking * within the current pos and pos+buf_size is possible. - * Once the stream position moves outside this window this guarantee is lost. + * Once the stream position moves outside this window or another + * ffio_ensure_seekback call requests a buffer outside this window this + * guarantee is lost. */ int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size); diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index a48ceebae..518cb1112 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -40,7 +40,7 @@ * data instead of calling the protocol seek function, for seekable * protocols. */ -#define SHORT_SEEK_THRESHOLD 4096 +#define SHORT_SEEK_THRESHOLD 32768 static void *ff_avio_child_next(void *obj, void *prev) { @@ -48,10 +48,19 @@ static void *ff_avio_child_next(void *obj, void *prev) return prev ? NULL : s->opaque; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *ff_avio_child_class_next(const AVClass *prev) { return prev ? NULL : &ffurl_context_class; } +#endif + +static const AVClass *child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : &ffurl_context_class; + *iter = (void*)(uintptr_t)c; + return c; +} #define OFFSET(x) offsetof(AVIOContext,x) #define E AV_OPT_FLAG_ENCODING_PARAM @@ -67,7 +76,10 @@ const AVClass ff_avio_class = { .version = LIBAVUTIL_VERSION_INT, .option = ff_avio_options, .child_next = ff_avio_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = ff_avio_child_class_next, +#endif + .child_class_iterate = child_class_iterate, }; static void fill_buffer(AVIOContext *s); @@ -271,13 +283,9 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) if (offset < 0) return AVERROR(EINVAL); - if (s->short_seek_get) { - short_seek = s->short_seek_get(s->opaque); - /* fallback to default short seek */ - if (short_seek <= 0) - short_seek = s->short_seek_threshold; - } else - short_seek = s->short_seek_threshold; + short_seek = s->short_seek_threshold; + if (s->short_seek_get) + short_seek = FFMAX(s->short_seek_get(s->opaque), short_seek); offset1 = offset - pos; // "offset1" is the relative offset from the beginning of s->buffer s->buf_ptr_max = FFMAX(s->buf_ptr_max, s->buf_ptr); @@ -528,7 +536,7 @@ static void fill_buffer(AVIOContext *s) { int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE; - uint8_t *dst = s->buf_end - s->buffer + max_buffer_size < s->buffer_size ? + uint8_t *dst = s->buf_end - s->buffer + max_buffer_size <= s->buffer_size ? s->buf_end : s->buffer; int len = s->buffer_size - (dst - s->buffer); @@ -674,9 +682,11 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size) int ffio_read_size(AVIOContext *s, unsigned char *buf, int size) { int ret = avio_read(s, buf, size); - if (ret != size) - return AVERROR_INVALIDDATA; - return ret; + if (ret == size) + return ret; + if (ret < 0 && ret != AVERROR_EOF) + return ret; + return AVERROR_INVALIDDATA; } int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data) @@ -696,7 +706,7 @@ int avio_read_partial(AVIOContext *s, unsigned char *buf, int size) int len; if (size < 0) - return -1; + return AVERROR(EINVAL); if (s->read_packet && s->write_flag) { len = read_packet_wrapper(s, buf, size); @@ -707,13 +717,6 @@ int avio_read_partial(AVIOContext *s, unsigned char *buf, int size) len = s->buf_end - s->buf_ptr; if (len == 0) { - /* Reset the buf_end pointer to the start of the buffer, to make sure - * the fill_buffer call tries to read as much data as fits into the - * full buffer, instead of just what space is left after buf_end. - * This avoids returning partial packets at the end of the buffer, - * for packet based inputs. - */ - s->buf_end = s->buf_ptr = s->buffer; fill_buffer(s); len = s->buf_end - s->buf_ptr; } @@ -926,6 +929,11 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) } else { buffer_size = IO_BUFFER_SIZE; } + if (!(h->flags & AVIO_FLAG_WRITE) && h->is_streamed) { + if (buffer_size > INT_MAX/2) + return AVERROR(EINVAL); + buffer_size *= 2; + } buffer = av_malloc(buffer_size); if (!buffer) return AVERROR(ENOMEM); @@ -979,32 +987,46 @@ URLContext* ffio_geturlcontext(AVIOContext *s) return NULL; } +static void update_checksum(AVIOContext *s) +{ + if (s->update_checksum && s->buf_ptr > s->checksum_ptr) { + s->checksum = s->update_checksum(s->checksum, s->checksum_ptr, + s->buf_ptr - s->checksum_ptr); + } +} + int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size) { uint8_t *buffer; int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE; - int filled = s->buf_end - s->buffer; - ptrdiff_t checksum_ptr_offset = s->checksum_ptr ? s->checksum_ptr - s->buffer : -1; + ptrdiff_t filled = s->buf_end - s->buf_ptr; - buf_size += s->buf_ptr - s->buffer + max_buffer_size; + if (buf_size <= s->buf_end - s->buf_ptr) + return 0; - if (buf_size < filled || s->seekable || !s->read_packet) + buf_size += max_buffer_size - 1; + + if (buf_size + s->buf_ptr - s->buffer <= s->buffer_size || s->seekable || !s->read_packet) return 0; av_assert0(!s->write_flag); - buffer = av_malloc(buf_size); - if (!buffer) - return AVERROR(ENOMEM); - - memcpy(buffer, s->buffer, filled); - av_free(s->buffer); - s->buf_ptr = buffer + (s->buf_ptr - s->buffer); - s->buf_end = buffer + (s->buf_end - s->buffer); - s->buffer = buffer; - s->buffer_size = buf_size; - if (checksum_ptr_offset >= 0) - s->checksum_ptr = s->buffer + checksum_ptr_offset; + if (buf_size <= s->buffer_size) { + update_checksum(s); + memmove(s->buffer, s->buf_ptr, filled); + } else { + buffer = av_malloc(buf_size); + if (!buffer) + return AVERROR(ENOMEM); + update_checksum(s); + memcpy(buffer, s->buf_ptr, filled); + av_free(s->buffer); + s->buffer = buffer; + s->buffer_size = buf_size; + } + s->buf_ptr = s->buffer; + s->buf_end = s->buffer + filled; + s->checksum_ptr = s->buffer; return 0; } @@ -1272,22 +1294,21 @@ typedef struct DynBuffer { static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) { DynBuffer *d = opaque; - unsigned new_size, new_allocated_size; + unsigned new_size; /* reallocate buffer if needed */ new_size = (unsigned)d->pos + buf_size; - new_allocated_size = d->allocated_size; - if (new_size < d->pos || new_size > INT_MAX/2) - return -1; - while (new_size > new_allocated_size) { - if (!new_allocated_size) - new_allocated_size = new_size; - else - new_allocated_size += new_allocated_size / 2 + 1; - } - - if (new_allocated_size > d->allocated_size) { + if (new_size < d->pos || new_size > INT_MAX) + return AVERROR(ERANGE); + if (new_size > d->allocated_size) { + unsigned new_allocated_size = d->allocated_size ? d->allocated_size + : new_size; int err; + while (new_size > new_allocated_size) + new_allocated_size += new_allocated_size / 2 + 1; + + new_allocated_size = FFMIN(new_allocated_size, INT_MAX); + if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) { d->allocated_size = 0; d->size = 0; @@ -1325,8 +1346,10 @@ static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence) offset += d->pos; else if (whence == SEEK_END) offset += d->size; - if (offset < 0 || offset > 0x7fffffffLL) - return -1; + if (offset < 0) + return AVERROR(EINVAL); + if (offset > INT_MAX) + return AVERROR(ERANGE); d->pos = offset; return 0; } @@ -1337,7 +1360,7 @@ static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size) unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024; if (sizeof(DynBuffer) + io_buffer_size < io_buffer_size) - return -1; + return AVERROR(ERANGE); d = av_mallocz(sizeof(DynBuffer) + io_buffer_size); if (!d) return AVERROR(ENOMEM); @@ -1361,7 +1384,7 @@ int avio_open_dyn_buf(AVIOContext **s) int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) { if (max_packet_size <= 0) - return -1; + return AVERROR(EINVAL); return url_open_dyn_buf_internal(s, max_packet_size); } diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index 2c08ace8d..21ae8c183 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -42,6 +42,13 @@ #define AVISYNTH_LIB AVISYNTH_NAME SLIBSUF #endif +/* Endianness guards for audio */ +#if HAVE_BIGENDIAN + #define PCM(format) (AV_CODEC_ID_PCM_ ## format ## BE) +#else + #define PCM(format) (AV_CODEC_ID_PCM_ ## format ## LE) +#endif + #include typedef struct AviSynthLibrary { @@ -57,6 +64,7 @@ typedef struct AviSynthLibrary { AVSC_DECLARE_FUNC(avs_get_version); AVSC_DECLARE_FUNC(avs_get_video_info); AVSC_DECLARE_FUNC(avs_invoke); + AVSC_DECLARE_FUNC(avs_is_color_space); AVSC_DECLARE_FUNC(avs_release_clip); AVSC_DECLARE_FUNC(avs_release_value); AVSC_DECLARE_FUNC(avs_release_video_frame); @@ -133,6 +141,7 @@ static av_cold int avisynth_load_library(void) LOAD_AVS_FUNC(avs_get_version, 0); LOAD_AVS_FUNC(avs_get_video_info, 0); LOAD_AVS_FUNC(avs_invoke, 0); + LOAD_AVS_FUNC(avs_is_color_space, 1); LOAD_AVS_FUNC(avs_release_clip, 0); LOAD_AVS_FUNC(avs_release_value, 0); LOAD_AVS_FUNC(avs_release_video_frame, 0); @@ -241,6 +250,23 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) st->nb_frames = avs->vi->num_frames; avpriv_set_pts_info(st, 32, avs->vi->fps_denominator, avs->vi->fps_numerator); + av_log(s, AV_LOG_TRACE, "avs_is_field_based: %d\n", avs_is_field_based(avs->vi)); + av_log(s, AV_LOG_TRACE, "avs_is_parity_known: %d\n", avs_is_parity_known(avs->vi)); + + /* The following typically only works when assumetff (-bff) and + * assumefieldbased is used in-script. Additional + * logic using GetParity() could deliver more accurate results + * but also decodes a frame which we want to avoid. */ + st->codecpar->field_order = AV_FIELD_UNKNOWN; + if (avs_is_field_based(avs->vi)) { + if (avs_is_tff(avs->vi)) { + st->codecpar->field_order = AV_FIELD_TT; + } + else if (avs_is_bff(avs->vi)) { + st->codecpar->field_order = AV_FIELD_BB; + } + } + switch (avs->vi->pixel_type) { /* 10~16-bit YUV pix_fmts (AviSynth+) */ case AVS_CS_YUV444P10: @@ -494,16 +520,16 @@ static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st) st->codecpar->codec_id = AV_CODEC_ID_PCM_U8; break; case AVS_SAMPLE_INT16: - st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; + st->codecpar->codec_id = PCM(S16); break; case AVS_SAMPLE_INT24: - st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE; + st->codecpar->codec_id = PCM(S24); break; case AVS_SAMPLE_INT32: - st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE; + st->codecpar->codec_id = PCM(S32); break; case AVS_SAMPLE_FLOAT: - st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE; + st->codecpar->codec_id = PCM(F32); break; default: av_log(s, AV_LOG_ERROR, @@ -628,7 +654,6 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, const unsigned char *src_p; int n, i, plane, rowsize, planeheight, pitch, bits, ret; const char *error; - int avsplus av_unused; if (avs->curr_frame >= avs->vi->num_frames) return AVERROR_EOF; @@ -638,19 +663,6 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, if (discard) return 0; -#ifdef _WIN32 - /* Detect whether we're using AviSynth 2.6 or AviSynth+ by - * looking for whether avs_is_planar_rgb exists. */ - if (GetProcAddress(avs_library.library, "avs_is_planar_rgb") == NULL) - avsplus = 0; - else - avsplus = 1; -#else - /* AviSynth+ is now the only variant of AviSynth we support - * on Linux and macOS. */ - avsplus = 1; -#endif - bits = avs_library.avs_bits_per_pixel(avs->vi); /* Without the cast to int64_t, calculation overflows at about 9k x 9k @@ -687,14 +699,9 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, planeheight = avs_library.avs_get_height_p(frame, plane); /* Flip RGB video. */ - if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) { - src_p = src_p + (planeheight - 1) * pitch; - pitch = -pitch; - } - - /* Flip Planar RGB video */ - if (avsplus && (avs_library.avs_is_planar_rgb(avs->vi) || - avs_library.avs_is_planar_rgba(avs->vi))) { + if (avs_library.avs_is_color_space(avs->vi, AVS_CS_BGR) || + avs_library.avs_is_color_space(avs->vi, AVS_CS_BGR48) || + avs_library.avs_is_color_space(avs->vi, AVS_CS_BGR64)) { src_p = src_p + (planeheight - 1) * pitch; pitch = -pitch; } diff --git a/libavformat/avlanguage.c b/libavformat/avlanguage.c index f5d2ddf30..c36893c99 100644 --- a/libavformat/avlanguage.c +++ b/libavformat/avlanguage.c @@ -763,10 +763,3 @@ const char *ff_convert_lang_to(const char *lang, enum AVLangCodespace target_cod return NULL; } - -#if LIBAVFORMAT_VERSION_MAJOR < 58 -const char *av_convert_lang_to(const char *lang, enum AVLangCodespace target_codespace) -{ - return ff_convert_lang_to(lang, target_codespace); -} -#endif diff --git a/libavformat/avlanguage.h b/libavformat/avlanguage.h index 1d72dcb3c..1901e7840 100644 --- a/libavformat/avlanguage.h +++ b/libavformat/avlanguage.h @@ -21,9 +21,6 @@ #ifndef AVFORMAT_AVLANGUAGE_H #define AVFORMAT_AVLANGUAGE_H -#include "libavutil/attributes.h" -#include "libavformat/version.h" - /** * Known language codespaces */ @@ -38,9 +35,5 @@ enum AVLangCodespace { * @return NULL if the provided lang is null or invalid. */ const char *ff_convert_lang_to(const char *lang, enum AVLangCodespace target_codespace); -#if LIBAVFORMAT_VERSION_MAJOR < 58 -attribute_deprecated -const char *av_convert_lang_to(const char *lang, enum AVLangCodespace target_codespace); -#endif #endif /* AVFORMAT_AVLANGUAGE_H */ diff --git a/libavformat/avs2dec.c b/libavformat/avs2dec.c new file mode 100644 index 000000000..51908d2b6 --- /dev/null +++ b/libavformat/avs2dec.c @@ -0,0 +1,71 @@ +/* + * AVS2 video stream probe. + * + * Copyright (C) 2018 Huiwen Ren, + * + * 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 "avformat.h" +#include "rawdec.h" +#include "libavcodec/internal.h" +#include "libavutil/intreadwrite.h" + +#define AVS2_ISSQH(x) ((x) == 0xB0) +#define AVS2_ISEND(x) ((x) == 0xB1) +#define AVS2_ISPIC(x) ((x) == 0xB3 || (x) == 0xB6) +#define AVS2_ISUNIT(x) (AVS2_ISSQH(x) || AVS2_ISEND(x) || (x) == 0xB2 || AVS2_ISPIC(x) || (x) == 0xB5 || (x) == 0xB7) +#define AVS2_ISPROFILE(x) ((x) == 0x20 || (x) == 0x22 || (x) == 0x30 || (x) == 0x32) + +static int avs2_probe(const AVProbeData *p) +{ + uint32_t code = -1, hds = 0, pic = 0, seq = 0; + uint8_t state = 0; + const uint8_t *ptr = p->buf, *end = p->buf + p->buf_size, *sqb = 0; + if (AV_RB32(p->buf) != 0x1B0){ + return 0; + } + + while (ptr < end) { + ptr = avpriv_find_start_code(ptr, end, &code); + state = code & 0xFF; + if ((code & 0xffffff00) == 0x100) { + if (AVS2_ISUNIT(state)) { + if (sqb && !hds) { + hds = ptr - sqb; + } + if (AVS2_ISSQH(state)) { + if (!AVS2_ISPROFILE(*ptr)) + return 0; + sqb = ptr; + seq++; + } else if (AVS2_ISPIC(state)) { + pic++; + } else if (AVS2_ISEND(state)) { + break; + } + } + } + } + if (seq && hds >= 21 && pic){ + return AVPROBE_SCORE_EXTENSION + 2; // more than cavs + } + + return 0; +} + +FF_DEF_RAWVIDEO_DEMUXER(avs2, "raw AVS2-P2/IEEE1857.4", avs2_probe, "avs,avs2", AV_CODEC_ID_AVS2) diff --git a/libavformat/avs3dec.c b/libavformat/avs3dec.c new file mode 100644 index 000000000..253caa7c1 --- /dev/null +++ b/libavformat/avs3dec.c @@ -0,0 +1,68 @@ +/* + * RAW AVS3-P2/IEEE1857.10 video demuxer + * Copyright (c) 2020 Zhenyu Wang + * Bingjie Han + * Huiwen Ren + * + * 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/avs3.h" +#include "libavcodec/internal.h" +#include "avformat.h" +#include "rawdec.h" + +static int avs3video_probe(const AVProbeData *p) +{ + const uint8_t *ptr = p->buf, *end = p->buf + p->buf_size; + uint32_t code = -1; + uint8_t state = 0; + int pic = 0, seq = 0, slice_pos = 0; + int ret = 0; + + while (ptr < end) { + ptr = avpriv_find_start_code(ptr, end, &code); + state = code & 0xFF; + if ((code & 0xFFFFFF00) == 0x100) { + if (state < AVS3_SEQ_START_CODE) { + if (code < slice_pos) + return 0; + slice_pos = code; + } else { + slice_pos = 0; + } + if (state == AVS3_SEQ_START_CODE) { + seq++; + if (*ptr != AVS3_PROFILE_BASELINE_MAIN && *ptr != AVS3_PROFILE_BASELINE_MAIN10) + return 0; + } else if (AVS3_ISPIC(state)) { + pic++; + } else if ((state == AVS3_UNDEF_START_CODE) || + (state > AVS3_VIDEO_EDIT_CODE)) { + return 0; + } + } + } + + if (seq && pic && av_match_ext(p->filename, "avs3")) { + ret = AVPROBE_SCORE_MAX; + } + + return ret; +} + +FF_DEF_RAWVIDEO_DEMUXER(avs3, "raw AVS3-P2/IEEE1857.10", avs3video_probe, "avs3", AV_CODEC_ID_AVS3) diff --git a/libavformat/binka.c b/libavformat/binka.c new file mode 100644 index 000000000..13ca9ca4b --- /dev/null +++ b/libavformat/binka.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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/intreadwrite.h" +#include "avformat.h" +#include "internal.h" + +static int binka_probe(const AVProbeData *p) +{ + if (AV_RB32(p->buf) == MKBETAG('1', 'F', 'C', 'B') && + (p->buf[4] == 1 || p->buf[4] == 2)) + return AVPROBE_SCORE_MAX; + return 0; +} + +static int binka_read_header(AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + AVStream *st; + int entries, offset; + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + avio_skip(pb, 5); + + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + st->codecpar->codec_id = AV_CODEC_ID_BINKAUDIO_DCT; + st->codecpar->channels = avio_r8(pb); + st->codecpar->sample_rate = avio_rl16(pb); + st->duration = avio_rl32(pb); + + avio_skip(pb, 8); + entries = avio_rl16(pb); + + offset = entries * 2 + 2; + avio_skip(pb, offset); + + avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); + + return 0; +} + +static int binka_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVIOContext *pb = s->pb; + AVStream *st = s->streams[0]; + int64_t pos; + int pkt_size; + int ret; + + if (avio_feof(pb)) + return AVERROR_EOF; + + pos = avio_tell(pb); + avio_skip(pb, 2); + pkt_size = avio_rl16(pb) + 4; + if (pkt_size <= 4) + return AVERROR(EIO); + ret = av_new_packet(pkt, pkt_size); + if (ret < 0) + return ret; + + avio_read(pb, pkt->data + 4, pkt_size - 4); + AV_WL32(pkt->data, pkt_size); + + pkt->pos = pos; + pkt->stream_index = 0; + pkt->duration = av_get_audio_frame_duration2(st->codecpar, 0); + + return 0; +} + +AVInputFormat ff_binka_demuxer = { + .name = "binka", + .long_name = NULL_IF_CONFIG_SMALL("Bink Audio"), + .read_probe = binka_probe, + .read_header = binka_read_header, + .read_packet = binka_read_packet, + .flags = AVFMT_GENERIC_INDEX, + .extensions = "binka", +}; diff --git a/libavformat/brstm.c b/libavformat/brstm.c index ca965ed7e..6754c1712 100644 --- a/libavformat/brstm.c +++ b/libavformat/brstm.c @@ -24,6 +24,11 @@ #include "avformat.h" #include "internal.h" +typedef struct BRSTMCoeffOffset { + uint8_t channel; + uint32_t offset; +} BRSTMCoeffOffset; + typedef struct BRSTMDemuxContext { uint32_t block_size; uint32_t block_count; @@ -33,8 +38,9 @@ typedef struct BRSTMDemuxContext { uint32_t last_block_size; uint32_t last_block_samples; uint32_t data_start; - uint8_t *table; + uint8_t table[256 * 32]; uint8_t *adpc; + BRSTMCoeffOffset offsets[256]; int little_endian; } BRSTMDemuxContext; @@ -61,12 +67,18 @@ static int read_close(AVFormatContext *s) { BRSTMDemuxContext *b = s->priv_data; - av_freep(&b->table); av_freep(&b->adpc); return 0; } +static int sort_offsets(const void *a, const void *b) +{ + const BRSTMCoeffOffset *s1 = a; + const BRSTMCoeffOffset *s2 = b; + return FFDIFFSIGN(s1->offset, s2->offset); +} + static av_always_inline unsigned int read16(AVFormatContext *s) { BRSTMDemuxContext *b = s->priv_data; @@ -259,17 +271,30 @@ static int read_header(AVFormatContext *s) if (toffset > size) return AVERROR_INVALIDDATA; + if (!bfstm) { + avio_skip(s->pb, pos + toffset - avio_tell(s->pb) - 8LL * (st->codecpar->channels + 1)); + for (ch = 0; ch < st->codecpar->channels; ch++) { + avio_skip(s->pb, 4); + b->offsets[ch].channel = ch; + b->offsets[ch].offset = read32(s); + } + + qsort(b->offsets, st->codecpar->channels, sizeof(*b->offsets), sort_offsets); + } + avio_skip(s->pb, pos + toffset - avio_tell(s->pb)); - b->table = av_mallocz(32 * st->codecpar->channels); - if (!b->table) - return AVERROR(ENOMEM); for (ch = 0; ch < st->codecpar->channels; ch++) { + if (!bfstm) + avio_skip(s->pb, pos + 16LL + b->offsets[ch].offset - avio_tell(s->pb)); + if (avio_read(s->pb, b->table + ch * 32, 32) != 32) { ret = AVERROR_INVALIDDATA; goto fail; } - avio_skip(s->pb, bfstm ? 14 : 24); + + if (bfstm) + avio_skip(s->pb, 14); } } @@ -393,11 +418,6 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) av_log(s, AV_LOG_ERROR, "adpcm_thp requires ADPC chunk, but none was found.\n"); return AVERROR_INVALIDDATA; } - if (!b->table) { - b->table = av_mallocz(32 * par->channels); - if (!b->table) - return AVERROR(ENOMEM); - } if (size > (INT_MAX - 32 - 4) || (32 + 4 + size) > (INT_MAX / par->channels) || @@ -446,7 +466,11 @@ static int read_seek(AVFormatContext *s, int stream_index, BRSTMDemuxContext *b = s->priv_data; int64_t ret = 0; + if (timestamp < 0) + timestamp = 0; timestamp /= b->samples_per_block; + if (timestamp >= b->block_count) + timestamp = b->block_count - 1; ret = avio_seek(s->pb, b->data_start + timestamp * b->block_size * st->codecpar->channels, SEEK_SET); if (ret < 0) diff --git a/libavformat/caf.c b/libavformat/caf.c index fe242ff03..a700e4055 100644 --- a/libavformat/caf.c +++ b/libavformat/caf.c @@ -78,3 +78,4 @@ const AVCodecTag ff_codec_caf_tags[] = { { AV_CODEC_ID_NONE, 0 }, }; +const AVCodecTag *const ff_caf_codec_tags_list[] = { ff_codec_caf_tags, NULL }; diff --git a/libavformat/caf.h b/libavformat/caf.h index 9c25f2c68..ed0392b1f 100644 --- a/libavformat/caf.h +++ b/libavformat/caf.h @@ -30,5 +30,6 @@ #include "internal.h" extern const AVCodecTag ff_codec_caf_tags[]; +extern const AVCodecTag *const ff_caf_codec_tags_list[]; #endif /* AVFORMAT_CAF_H */ diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index c2ac1369f..76bc4a465 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -204,15 +204,20 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size) st->nb_frames += avio_rb32(pb); /* priming frames */ st->nb_frames += avio_rb32(pb); /* remainder frames */ - st->duration = 0; - for (i = 0; i < num_packets; i++) { - if (avio_feof(pb)) - return AVERROR_INVALIDDATA; - ret = av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME); - if (ret < 0) - return ret; - pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb); - st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb); + if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) { + st->duration = caf->frames_per_packet * num_packets; + pos = caf-> bytes_per_packet * num_packets; + } else { + st->duration = 0; + for (i = 0; i < num_packets; i++) { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; + ret = av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME); + if (ret < 0) + return ret; + pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb); + st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb); + } } if (avio_tell(pb) - ccount > size) { @@ -460,5 +465,5 @@ AVInputFormat ff_caf_demuxer = { .read_header = read_header, .read_packet = read_packet, .read_seek = read_seek, - .codec_tag = (const AVCodecTag* const []){ ff_codec_caf_tags, 0 }, + .codec_tag = ff_caf_codec_tags_list, }; diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c index 98d4d9212..7e44797a5 100644 --- a/libavformat/cafenc.c +++ b/libavformat/cafenc.c @@ -274,5 +274,5 @@ AVOutputFormat ff_caf_muxer = { .write_header = caf_write_header, .write_packet = caf_write_packet, .write_trailer = caf_write_trailer, - .codec_tag = (const AVCodecTag* const []){ff_codec_caf_tags, 0}, + .codec_tag = ff_caf_codec_tags_list, }; diff --git a/libavformat/cdg.c b/libavformat/cdg.c index f933819d5..8fb287a99 100644 --- a/libavformat/cdg.c +++ b/libavformat/cdg.c @@ -26,10 +26,6 @@ #define CDG_COMMAND 0x09 #define CDG_MASK 0x3F -typedef struct CDGContext { - int got_first_packet; -} CDGContext; - static int read_header(AVFormatContext *s) { AVStream *vst; @@ -56,26 +52,16 @@ static int read_header(AVFormatContext *s) static int read_packet(AVFormatContext *s, AVPacket *pkt) { - CDGContext *priv = s->priv_data; int ret; - while (1) { - ret = av_get_packet(s->pb, pkt, CDG_PACKET_SIZE); - if (ret < 1 || (pkt->data[0] & CDG_MASK) == CDG_COMMAND) - break; - av_packet_unref(pkt); - } - - if (!priv->got_first_packet) { - pkt->flags |= AV_PKT_FLAG_KEY; - priv->got_first_packet = 1; - } - + ret = av_get_packet(s->pb, pkt, CDG_PACKET_SIZE); pkt->stream_index = 0; pkt->dts= pkt->pts= pkt->pos / CDG_PACKET_SIZE; - if(ret>5 && (pkt->data[0]&0x3F) == 9 && (pkt->data[1]&0x3F)==1 && !(pkt->data[2+2+1] & 0x0F)){ + if (!pkt->pos || (ret > 5 && + (pkt->data[0] & CDG_MASK) == CDG_COMMAND && + (pkt->data[1] & CDG_MASK) == 1 && !(pkt->data[2+2+1] & 0x0F))) { pkt->flags = AV_PKT_FLAG_KEY; } return ret; @@ -84,7 +70,6 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) AVInputFormat ff_cdg_demuxer = { .name = "cdg", .long_name = NULL_IF_CONFIG_SMALL("CD Graphics"), - .priv_data_size = sizeof(CDGContext), .read_header = read_header, .read_packet = read_packet, .flags = AVFMT_GENERIC_INDEX, diff --git a/libavformat/cdxl.c b/libavformat/cdxl.c index 5718fc3e2..33b6d5cba 100644 --- a/libavformat/cdxl.c +++ b/libavformat/cdxl.c @@ -30,53 +30,70 @@ typedef struct CDXLDemuxContext { AVClass *class; - int sample_rate; - char *framerate; - AVRational fps; int read_chunk; + AVRational frate; + int srate; + AVRational frame_rate; + int sample_rate; uint8_t header[CDXL_HEADER_SIZE]; int video_stream_index; int audio_stream_index; int64_t filesize; + int64_t pos; } CDXLDemuxContext; static int cdxl_read_probe(const AVProbeData *p) { int score = AVPROBE_SCORE_EXTENSION + 10; + const uint8_t *buf = p->buf; if (p->buf_size < CDXL_HEADER_SIZE) return 0; - /* reserved bytes should always be set to 0 */ - if (AV_RN64(&p->buf[24]) || AV_RN16(&p->buf[10])) + /* check type */ + if (buf[0] > 1) return 0; - /* check type */ - if (p->buf[0] != 1) + /* reserved bytes should always be set to 0 */ + if (AV_RL24(&buf[29])) return 0; /* check palette size */ - if (AV_RB16(&p->buf[20]) > 512) + if (!AV_RN16(&buf[20])) + return 0; + if (buf[0] == 1 && AV_RB16(&buf[20]) > 512) + return 0; + if (buf[0] == 0 && AV_RB16(&buf[20]) > 768) + return 0; + + if (!AV_RN16(&buf[22]) && AV_RN16(&buf[24])) + return 0; + + if (buf[0] == 0 && (!buf[26] || !AV_RB16(&buf[24]))) return 0; /* check number of planes */ - if (p->buf[18] || !p->buf[19]) + if (buf[19] != 6 && buf[19] != 8 && buf[19] != 24) + return 0; + + if (buf[18]) return 0; /* check widh and height */ - if (!AV_RN16(&p->buf[14]) || !AV_RN16(&p->buf[16])) + if (AV_RB16(&buf[14]) > 640 || AV_RB16(&buf[16]) > 480 || + AV_RB16(&buf[14]) == 0 || AV_RB16(&buf[16]) == 0) return 0; /* chunk size */ - if (AV_RB32(&p->buf[2]) < AV_RB16(&p->buf[22]) + AV_RB16(&p->buf[20]) + CDXL_HEADER_SIZE) + if (AV_RB32(&buf[2]) <= AV_RB16(&buf[20]) + AV_RB16(&buf[22]) * (1 + !!(buf[1] & 0x10)) + CDXL_HEADER_SIZE) return 0; /* previous chunk size */ - if (AV_RN32(&p->buf[6])) + if (AV_RN32(&buf[6])) score /= 2; /* current frame number, usually starts from 1 */ - if (AV_RB16(&p->buf[12]) != 1) + if (AV_RB32(&buf[10]) != 1) score /= 2; return score; @@ -85,13 +102,6 @@ static int cdxl_read_probe(const AVProbeData *p) static int cdxl_read_header(AVFormatContext *s) { CDXLDemuxContext *cdxl = s->priv_data; - int ret; - - if (cdxl->framerate && (ret = av_parse_video_rate(&cdxl->fps, cdxl->framerate)) < 0) { - av_log(s, AV_LOG_ERROR, - "Could not parse framerate: %s.\n", cdxl->framerate); - return ret; - } cdxl->read_chunk = 0; cdxl->video_stream_index = -1; @@ -110,27 +120,34 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt) AVIOContext *pb = s->pb; uint32_t current_size, video_size, image_size; uint16_t audio_size, palette_size, width, height; - int64_t pos; - int format, frames, ret; + int channels, type, format, ret; if (avio_feof(pb)) return AVERROR_EOF; - pos = avio_tell(pb); - if (!cdxl->read_chunk && - avio_read(pb, cdxl->header, CDXL_HEADER_SIZE) != CDXL_HEADER_SIZE) - return AVERROR_EOF; - if (cdxl->header[0] != 1) { - av_log(s, AV_LOG_ERROR, "non-standard cdxl file\n"); + if (!cdxl->read_chunk) { + cdxl->pos = avio_tell(pb); + if (avio_read(pb, cdxl->header, CDXL_HEADER_SIZE) != CDXL_HEADER_SIZE) + return AVERROR_EOF; + } + if (cdxl->header[0] > 1) { + av_log(s, AV_LOG_ERROR, "unsupported cdxl file\n"); return AVERROR_INVALIDDATA; } + type = cdxl->header[0]; + channels = 1 + !!(cdxl->header[1] & 0x10); format = cdxl->header[1] & 0xE0; current_size = AV_RB32(&cdxl->header[2]); width = AV_RB16(&cdxl->header[14]); height = AV_RB16(&cdxl->header[16]); palette_size = AV_RB16(&cdxl->header[20]); - audio_size = AV_RB16(&cdxl->header[22]); + audio_size = AV_RB16(&cdxl->header[22]) * channels; + cdxl->srate = AV_RB16(&cdxl->header[24]); + if (!cdxl->srate && audio_size) + cdxl->srate = cdxl->sample_rate; + cdxl->frate.num = cdxl->header[26]; + cdxl->frate.den = 1; if (cdxl->header[19] == 0 || FFALIGN(width, 16) * (uint64_t)height * cdxl->header[19] > INT_MAX) return AVERROR_INVALIDDATA; @@ -140,11 +157,18 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt) image_size = FFALIGN(width, 16) * height * cdxl->header[19] / 8; video_size = palette_size + image_size; - if (palette_size > 512) + if ((type == 1 && palette_size > 512) || + (type == 0 && palette_size > 768)) return AVERROR_INVALIDDATA; if (current_size < (uint64_t)audio_size + video_size + CDXL_HEADER_SIZE) return AVERROR_INVALIDDATA; + if (!cdxl->frate.num && audio_size && cdxl->srate > 0) { + cdxl->frate = (AVRational){ cdxl->srate, audio_size }; + } else if (!cdxl->frate.num) { + cdxl->frate = cdxl->frame_rate; + } + if (cdxl->read_chunk && audio_size) { if (cdxl->audio_stream_index == -1) { AVStream *st = avformat_new_stream(s, NULL); @@ -153,26 +177,23 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt) st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_tag = 0; - st->codecpar->codec_id = AV_CODEC_ID_PCM_S8; - if (cdxl->header[1] & 0x10) { - st->codecpar->channels = 2; - st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; - } else { - st->codecpar->channels = 1; - st->codecpar->channel_layout = AV_CH_LAYOUT_MONO; - } - st->codecpar->sample_rate = cdxl->sample_rate; + st->codecpar->codec_id = AV_CODEC_ID_PCM_S8_PLANAR; + st->codecpar->channels = channels; + st->codecpar->channel_layout = channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; + st->codecpar->sample_rate= cdxl->srate; st->start_time = 0; cdxl->audio_stream_index = st->index; - avpriv_set_pts_info(st, 64, 1, cdxl->sample_rate); + avpriv_set_pts_info(st, 64, 1, cdxl->srate); + if (current_size && cdxl->filesize > 0 && audio_size > 0) + st->duration = (cdxl->filesize / current_size) * audio_size / channels; } ret = av_get_packet(pb, pkt, audio_size); if (ret < 0) return ret; pkt->stream_index = cdxl->audio_stream_index; - pkt->pos = pos; - pkt->duration = audio_size; + pkt->pos = cdxl->pos; + pkt->duration = audio_size / channels; cdxl->read_chunk = 0; } else { if (cdxl->video_stream_index == -1) { @@ -186,20 +207,11 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt) st->codecpar->width = width; st->codecpar->height = height; - if (audio_size + video_size && cdxl->filesize > 0) { - frames = cdxl->filesize / (audio_size + video_size); - - if(cdxl->framerate) - st->duration = frames; - else - st->duration = frames * (int64_t)audio_size; - } + if (current_size && cdxl->filesize > 0) + st->nb_frames = cdxl->filesize / current_size; st->start_time = 0; cdxl->video_stream_index = st->index; - if (cdxl->framerate) - avpriv_set_pts_info(st, 64, cdxl->fps.den, cdxl->fps.num); - else - avpriv_set_pts_info(st, 64, 1, cdxl->sample_rate); + avpriv_set_pts_info(st, 64, cdxl->frate.den, cdxl->frate.num); } if ((ret = av_new_packet(pkt, video_size + CDXL_HEADER_SIZE)) < 0) @@ -212,8 +224,8 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt) av_shrink_packet(pkt, CDXL_HEADER_SIZE + ret); pkt->stream_index = cdxl->video_stream_index; pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pos = pos; - pkt->duration = cdxl->framerate ? 1 : audio_size ? audio_size : 220; + pkt->pos = cdxl->pos; + pkt->duration = 1; cdxl->read_chunk = audio_size; } @@ -222,10 +234,20 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt) return ret; } +static int read_seek(AVFormatContext *s, int stream_index, + int64_t timestamp, int flags) +{ + CDXLDemuxContext *cdxl = s->priv_data; + + cdxl->read_chunk = 0; + + return -1; +} + #define OFFSET(x) offsetof(CDXLDemuxContext, x) static const AVOption cdxl_options[] = { - { "sample_rate", "", OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 11025 }, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, - { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, + { "sample_rate", "", OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64=11025 }, 8000, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, + { "frame_rate", "", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, { .str="15" }, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, { NULL }, }; @@ -240,10 +262,11 @@ AVInputFormat ff_cdxl_demuxer = { .name = "cdxl", .long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"), .priv_data_size = sizeof(CDXLDemuxContext), + .priv_class = &cdxl_demuxer_class, .read_probe = cdxl_read_probe, .read_header = cdxl_read_header, .read_packet = cdxl_read_packet, + .read_seek = read_seek, .extensions = "cdxl,xl", .flags = AVFMT_GENERIC_INDEX, - .priv_class = &cdxl_demuxer_class, }; diff --git a/libavformat/chromaprint.c b/libavformat/chromaprint.c index 0cd7cdeb2..423f5b7d6 100644 --- a/libavformat/chromaprint.c +++ b/libavformat/chromaprint.c @@ -1,6 +1,6 @@ /* * Chromaprint fingerprinting muxer - * Copyright (c) 2015 Rodger Combs + * Copyright (c) 2015 rcombs * * This file is part of FFmpeg. * diff --git a/libavformat/cinedec.c b/libavformat/cinedec.c index 0f2453cdf..88f5e5690 100644 --- a/libavformat/cinedec.c +++ b/libavformat/cinedec.c @@ -288,7 +288,7 @@ static int cine_read_packet(AVFormatContext *avctx, AVPacket *pkt) AVIOContext *pb = avctx->pb; int n, size, ret; - if (cine->pts >= st->duration) + if (cine->pts >= st->nb_index_entries) return AVERROR_EOF; avio_seek(pb, st->index_entries[cine->pts].pos, SEEK_SET); diff --git a/libavformat/codec2.c b/libavformat/codec2.c index 0d7c48858..0c2ad3aa0 100644 --- a/libavformat/codec2.c +++ b/libavformat/codec2.c @@ -29,8 +29,8 @@ #include "rawenc.h" #include "pcm.h" -#define AVPRIV_CODEC2_HEADER_SIZE 7 -#define AVPRIV_CODEC2_MAGIC 0xC0DEC2 +#define CODEC2_HEADER_SIZE 7 +#define CODEC2_MAGIC 0xC0DEC2 //the lowest version we should ever run across is 0.8 //we may run across later versions as the format evolves @@ -46,7 +46,7 @@ typedef struct { static int codec2_probe(const AVProbeData *p) { //must start wih C0 DE C2 - if (AV_RB24(p->buf) != AVPRIV_CODEC2_MAGIC) { + if (AV_RB24(p->buf) != CODEC2_MAGIC) { return 0; } @@ -61,9 +61,69 @@ static int codec2_probe(const AVProbeData *p) return AVPROBE_SCORE_EXTENSION + 1; } +//Mimics codec2_samples_per_frame() +static int codec2_mode_frame_size(AVFormatContext *s, int mode) +{ + int frame_size_table[CODEC2_MODE_MAX+1] = { + 160, // 3200 + 160, // 2400 + 320, // 1600 + 320, // 1400 + 320, // 1300 + 320, // 1200 + 320, // 700 + 320, // 700B + 320, // 700C + }; + + if (mode < 0 || mode > CODEC2_MODE_MAX) { + av_log(s, AV_LOG_ERROR, "unknown codec2 mode %i, can't find frame_size\n", mode); + return 0; + } else { + return frame_size_table[mode]; + } +} + +//Mimics (codec2_bits_per_frame()+7)/8 +static int codec2_mode_block_align(AVFormatContext *s, int mode) +{ + int block_align_table[CODEC2_MODE_MAX+1] = { + 8, // 3200 + 6, // 2400 + 8, // 1600 + 7, // 1400 + 7, // 1300 + 6, // 1200 + 4, // 700 + 4, // 700B + 4, // 700C + }; + + if (mode < 0 || mode > CODEC2_MODE_MAX) { + av_log(s, AV_LOG_ERROR, "unknown codec2 mode %i, can't find block_align\n", mode); + return 0; + } else { + return block_align_table[mode]; + } +} + +//Computes bitrate from mode, with frames rounded up to the nearest octet. +//So 700 bit/s (28 bits/frame) becomes 800 bits/s (32 bits/frame). +static int codec2_mode_bit_rate(AVFormatContext *s, int mode) +{ + int frame_size = codec2_mode_frame_size(s, mode); + int block_align = codec2_mode_block_align(s, mode); + + if (frame_size <= 0 || block_align <= 0) { + return 0; + } + + return 8 * 8000 * block_align / frame_size; +} + static int codec2_read_header_common(AVFormatContext *s, AVStream *st) { - int mode = avpriv_codec2_mode_from_extradata(st->codecpar->extradata); + int mode = codec2_mode_from_extradata(st->codecpar->extradata); st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = AV_CODEC_ID_CODEC2; @@ -71,9 +131,9 @@ static int codec2_read_header_common(AVFormatContext *s, AVStream *st) st->codecpar->channels = 1; st->codecpar->format = AV_SAMPLE_FMT_S16; st->codecpar->channel_layout = AV_CH_LAYOUT_MONO; - st->codecpar->bit_rate = avpriv_codec2_mode_bit_rate(s, mode); - st->codecpar->frame_size = avpriv_codec2_mode_frame_size(s, mode); - st->codecpar->block_align = avpriv_codec2_mode_block_align(s, mode); + st->codecpar->bit_rate = codec2_mode_bit_rate(s, mode); + st->codecpar->frame_size = codec2_mode_frame_size(s, mode); + st->codecpar->block_align = codec2_mode_block_align(s, mode); if (st->codecpar->bit_rate <= 0 || st->codecpar->frame_size <= 0 || @@ -95,28 +155,28 @@ static int codec2_read_header(AVFormatContext *s) return AVERROR(ENOMEM); } - if (avio_rb24(s->pb) != AVPRIV_CODEC2_MAGIC) { + if (avio_rb24(s->pb) != CODEC2_MAGIC) { av_log(s, AV_LOG_ERROR, "not a .c2 file\n"); return AVERROR_INVALIDDATA; } - ret = ff_alloc_extradata(st->codecpar, AVPRIV_CODEC2_EXTRADATA_SIZE); + ret = ff_alloc_extradata(st->codecpar, CODEC2_EXTRADATA_SIZE); if (ret) { return ret; } - ret = ffio_read_size(s->pb, st->codecpar->extradata, AVPRIV_CODEC2_EXTRADATA_SIZE); + ret = ffio_read_size(s->pb, st->codecpar->extradata, CODEC2_EXTRADATA_SIZE); if (ret < 0) { return ret; } - version = avpriv_codec2_version_from_extradata(st->codecpar->extradata); + version = AV_RB16(st->codecpar->extradata); if ((version >> 8) != EXPECTED_CODEC2_MAJOR_VERSION) { avpriv_report_missing_feature(s, "Major version %i", version >> 8); return AVERROR_PATCHWELCOME; } - s->internal->data_offset = AVPRIV_CODEC2_HEADER_SIZE; + s->internal->data_offset = CODEC2_HEADER_SIZE; return codec2_read_header_common(s, st); } @@ -160,14 +220,14 @@ static int codec2_write_header(AVFormatContext *s) st = s->streams[0]; - if (st->codecpar->extradata_size != AVPRIV_CODEC2_EXTRADATA_SIZE) { + if (st->codecpar->extradata_size != CODEC2_EXTRADATA_SIZE) { av_log(s, AV_LOG_ERROR, ".c2 files require exactly %i bytes of extradata (got %i)\n", - AVPRIV_CODEC2_EXTRADATA_SIZE, st->codecpar->extradata_size); + CODEC2_EXTRADATA_SIZE, st->codecpar->extradata_size); return AVERROR(EINVAL); } - avio_wb24(s->pb, AVPRIV_CODEC2_MAGIC); - avio_write(s->pb, st->codecpar->extradata, AVPRIV_CODEC2_EXTRADATA_SIZE); + avio_wb24(s->pb, CODEC2_MAGIC); + avio_write(s->pb, st->codecpar->extradata, CODEC2_EXTRADATA_SIZE); return 0; } @@ -189,13 +249,13 @@ static int codec2raw_read_header(AVFormatContext *s) return AVERROR(ENOMEM); } - ret = ff_alloc_extradata(st->codecpar, AVPRIV_CODEC2_EXTRADATA_SIZE); + ret = ff_alloc_extradata(st->codecpar, CODEC2_EXTRADATA_SIZE); if (ret) { return ret; } s->internal->data_offset = 0; - avpriv_codec2_make_extradata(st->codecpar->extradata, c2->mode); + codec2_make_extradata(st->codecpar->extradata, c2->mode); return codec2_read_header_common(s, st); } @@ -211,7 +271,7 @@ static const AVOption codec2_options[] = { }; static const AVOption codec2raw_options[] = { - AVPRIV_CODEC2_AVOPTIONS("codec2 mode [mandatory]", Codec2Context, -1, -1, AV_OPT_FLAG_DECODING_PARAM), + CODEC2_AVOPTIONS("codec2 mode [mandatory]", Codec2Context, -1, -1, AV_OPT_FLAG_DECODING_PARAM), FRAMES_PER_PACKET, { NULL }, }; diff --git a/libavformat/concat.c b/libavformat/concat.c index 418405dd5..278afd997 100644 --- a/libavformat/concat.c +++ b/libavformat/concat.c @@ -73,14 +73,11 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) for (i = 0, len = 1; uri[i]; i++) { if (uri[i] == *AV_CAT_SEPARATOR) { - /* integer overflow */ - if (++len == UINT_MAX / sizeof(*nodes)) { - return AVERROR(ENAMETOOLONG); - } + len++; } } - if (!(nodes = av_realloc(NULL, sizeof(*nodes) * len))) + if (!(nodes = av_realloc_array(NULL, len, sizeof(*nodes)))) return AVERROR(ENOMEM); else data->nodes = nodes; diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 6d5b9914f..32d4a9901 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -626,7 +626,7 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base), av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base)); if (cat->cur_file->metadata) { - int metadata_len; + buffer_size_t metadata_len; char* packed_metadata = av_packet_pack_dictionary(cat->cur_file->metadata, &metadata_len); if (!packed_metadata) return AVERROR(ENOMEM); diff --git a/libavformat/crypto.c b/libavformat/crypto.c index 31f9ac0ab..1d4514e0f 100644 --- a/libavformat/crypto.c +++ b/libavformat/crypto.c @@ -252,21 +252,17 @@ static int64_t crypto_seek(URLContext *h, int64_t pos, int whence) case SEEK_CUR: pos = pos + c->position; break; - case SEEK_END: { - int64_t newpos = ffurl_seek( c->hd, pos, AVSEEK_SIZE ); + case SEEK_END: + newpos = ffurl_seek( c->hd, pos, AVSEEK_SIZE ); if (newpos < 0) { av_log(h, AV_LOG_ERROR, "Crypto: seek_end - can't get file size (pos=%lld)\r\n", (long long int)pos); return newpos; } pos = newpos - pos; - } - break; - case AVSEEK_SIZE: { - int64_t newpos = ffurl_seek( c->hd, pos, AVSEEK_SIZE ); - return newpos; - } break; + case AVSEEK_SIZE: + return ffurl_seek( c->hd, pos, AVSEEK_SIZE ); default: av_log(h, AV_LOG_ERROR, "Crypto: no support for seek where 'whence' is %d\r\n", whence); diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index ec2aadcee..6f3f28dcc 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -29,7 +29,7 @@ #include "dash.h" #define INITIAL_BUFFER_SIZE 32768 -#define MAX_MANIFEST_SIZE 50 * 1024 +#define MAX_BPRINT_READ_SIZE (UINT_MAX - 1) #define DEFAULT_MANIFEST_SIZE 8 * 1024 struct fragment { @@ -80,13 +80,9 @@ struct representation { AVIOContext *input; AVFormatContext *parent; AVFormatContext *ctx; - AVPacket pkt; - int rep_idx; - int rep_count; int stream_index; - enum AVMediaType type; - char id[20]; + char *id; char *lang; int bandwidth; AVRational framerate; @@ -159,13 +155,14 @@ typedef struct DASHContext { /* Flags for init section*/ int is_init_section_common_video; int is_init_section_common_audio; + int is_init_section_common_subtitle; } DASHContext; static int ishttp(char *url) { const char *proto_name = avio_find_protocol_name(url); - return av_strstart(proto_name, "http", NULL); + return proto_name && av_strstart(proto_name, "http", NULL); } static int aligned(int val) @@ -231,21 +228,21 @@ static uint32_t get_duration_insec(AVFormatContext *s, const char *duration) return 0; /* parser error */ } switch (type) { - case 'D': - days = (uint32_t)value; - break; - case 'H': - hours = (uint32_t)value; - break; - case 'M': - mins = (uint32_t)value; - break; - case 'S': - secs = (uint32_t)value; - break; - default: - // handle invalid type - break; + case 'D': + days = (uint32_t)value; + break; + case 'H': + hours = (uint32_t)value; + break; + case 'M': + mins = (uint32_t)value; + break; + case 'S': + secs = (uint32_t)value; + break; + default: + // handle invalid type + break; } ptr += size; } @@ -363,6 +360,8 @@ static void free_representation(struct representation *pls) } av_freep(&pls->url_template); + av_freep(&pls->lang); + av_freep(&pls->id); av_freep(&pls); } @@ -400,16 +399,13 @@ static void free_subtitle_list(DASHContext *c) } static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, - AVDictionary *opts, AVDictionary *opts2, int *is_http) + AVDictionary **opts, AVDictionary *opts2, int *is_http) { DASHContext *c = s->priv_data; AVDictionary *tmp = NULL; const char *proto_name = NULL; int ret; - av_dict_copy(&tmp, opts, 0); - av_dict_copy(&tmp, opts2, 0); - if (av_strstart(url, "crypto", NULL)) { if (url[6] == '+' || url[6] == ':') proto_name = avio_find_protocol_name(url + 7); @@ -443,6 +439,8 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, return AVERROR_INVALIDDATA; av_freep(pb); + av_dict_copy(&tmp, *opts, 0); + av_dict_copy(&tmp, opts2, 0); ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); if (ret >= 0) { // update cookies on http response with setcookies. @@ -452,7 +450,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, av_opt_get(*pb, "cookies", AV_OPT_SEARCH_CHILDREN, (uint8_t**)&new_cookies); if (new_cookies) { - av_dict_set(&opts, "cookies", new_cookies, AV_DICT_DONT_STRDUP_VAL); + av_dict_set(opts, "cookies", new_cookies, AV_DICT_DONT_STRDUP_VAL); } } @@ -476,11 +474,9 @@ static char *get_content_url(xmlNodePtr *baseurl_nodes, char *text; char *url = NULL; char *tmp_str = av_mallocz(max_url_size); - char *tmp_str_2 = av_mallocz(max_url_size); - if (!tmp_str || !tmp_str_2) { + if (!tmp_str) return NULL; - } for (i = 0; i < n_baseurl_nodes; ++i) { if (baseurl_nodes[i] && @@ -489,9 +485,7 @@ static char *get_content_url(xmlNodePtr *baseurl_nodes, text = xmlNodeGetContent(baseurl_nodes[i]->children); if (text) { memset(tmp_str, 0, max_url_size); - memset(tmp_str_2, 0, max_url_size); - ff_make_absolute_url(tmp_str_2, max_url_size, tmp_str, text); - av_strlcpy(tmp_str, tmp_str_2, max_url_size); + ff_make_absolute_url(tmp_str, max_url_size, "", text); xmlFree(text); } } @@ -501,7 +495,7 @@ static char *get_content_url(xmlNodePtr *baseurl_nodes, ff_make_absolute_url(tmp_str, max_url_size, tmp_str, val); if (rep_id_val) { - url = av_strireplace(tmp_str, "$RepresentationID$", (const char*)rep_id_val); + url = av_strireplace(tmp_str, "$RepresentationID$", rep_id_val); if (!url) { goto end; } @@ -510,14 +504,13 @@ static char *get_content_url(xmlNodePtr *baseurl_nodes, if (rep_bandwidth_val && tmp_str[0] != '\0') { // free any previously assigned url before reassigning av_free(url); - url = av_strireplace(tmp_str, "$Bandwidth$", (const char*)rep_bandwidth_val); + url = av_strireplace(tmp_str, "$Bandwidth$", rep_bandwidth_val); if (!url) { goto end; } } end: av_free(tmp_str); - av_free(tmp_str_2); return url; } @@ -566,11 +559,11 @@ static enum AVMediaType get_content_type(xmlNodePtr node) attr = i ? "mimeType" : "contentType"; val = xmlGetProp(node, attr); if (val) { - if (av_stristr((const char *)val, "video")) { + if (av_stristr(val, "video")) { type = AVMEDIA_TYPE_VIDEO; - } else if (av_stristr((const char *)val, "audio")) { + } else if (av_stristr(val, "audio")) { type = AVMEDIA_TYPE_AUDIO; - } else if (av_stristr((const char *)val, "text")) { + } else if (av_stristr(val, "text")) { type = AVMEDIA_TYPE_SUBTITLE; } xmlFree(val); @@ -609,15 +602,17 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati char *media_val = NULL; char *range_val = NULL; int max_url_size = c ? c->max_url_size: MAX_URL_SIZE; + int err; - if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { + if (!av_strcasecmp(fragmenturl_node->name, "Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); range_val = xmlGetProp(fragmenturl_node, "range"); if (initialization_val || range_val) { + free_fragment(&rep->init_section); rep->init_section = get_Fragment(range_val); + xmlFree(range_val); if (!rep->init_section) { xmlFree(initialization_val); - xmlFree(range_val); return AVERROR(ENOMEM); } rep->init_section->url = get_content_url(baseurl_nodes, 4, @@ -625,24 +620,20 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati rep_id_val, rep_bandwidth_val, initialization_val); - + xmlFree(initialization_val); if (!rep->init_section->url) { - av_free(rep->init_section); - xmlFree(initialization_val); - xmlFree(range_val); + av_freep(&rep->init_section); return AVERROR(ENOMEM); } - xmlFree(initialization_val); - xmlFree(range_val); } - } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { + } else if (!av_strcasecmp(fragmenturl_node->name, "SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); range_val = xmlGetProp(fragmenturl_node, "mediaRange"); if (media_val || range_val) { struct fragment *seg = get_Fragment(range_val); + xmlFree(range_val); if (!seg) { xmlFree(media_val); - xmlFree(range_val); return AVERROR(ENOMEM); } seg->url = get_content_url(baseurl_nodes, 4, @@ -650,15 +641,16 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati rep_id_val, rep_bandwidth_val, media_val); + xmlFree(media_val); if (!seg->url) { av_free(seg); - xmlFree(media_val); - xmlFree(range_val); return AVERROR(ENOMEM); } - dynarray_add(&rep->fragments, &rep->n_fragments, seg); - xmlFree(media_val); - xmlFree(range_val); + err = av_dynarray_add_nofree(&rep->fragments, &rep->n_fragments, seg); + if (err < 0) { + free_fragment(&seg); + return err; + } } } @@ -670,8 +662,9 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat { xmlAttrPtr attr = NULL; char *val = NULL; + int err; - if (!av_strcasecmp(fragment_timeline_node->name, (const char *)"S")) { + if (!av_strcasecmp(fragment_timeline_node->name, "S")) { struct timeline *tml = av_mallocz(sizeof(struct timeline)); if (!tml) { return AVERROR(ENOMEM); @@ -685,17 +678,21 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat continue; } - if (!av_strcasecmp(attr->name, (const char *)"t")) { + if (!av_strcasecmp(attr->name, "t")) { tml->starttime = (int64_t)strtoll(val, NULL, 10); - } else if (!av_strcasecmp(attr->name, (const char *)"r")) { + } else if (!av_strcasecmp(attr->name, "r")) { tml->repeat =(int64_t) strtoll(val, NULL, 10); - } else if (!av_strcasecmp(attr->name, (const char *)"d")) { + } else if (!av_strcasecmp(attr->name, "d")) { tml->duration = (int64_t)strtoll(val, NULL, 10); } attr = attr->next; xmlFree(val); } - dynarray_add(&rep->timelines, &rep->n_timelines, tml); + err = av_dynarray_add_nofree(&rep->timelines, &rep->n_timelines, tml); + if (err < 0) { + av_free(tml); + return err; + } } return 0; @@ -776,7 +773,7 @@ static int resolve_content_path(AVFormatContext *s, const char *url, int *max_ur size = strlen(root_url); isRootHttp = ishttp(root_url); - if (root_url[size - 1] != token) { + if (size > 0 && root_url[size - 1] != token) { av_strlcat(root_url, "/", size + 2); size += 2; } @@ -834,9 +831,6 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr adaptionset_supplementalproperty_node) { int32_t ret = 0; - int32_t subtitle_rep_idx = 0; - int32_t audio_rep_idx = 0; - int32_t video_rep_idx = 0; DASHContext *c = s->priv_data; struct representation *rep = NULL; struct fragment *seg = NULL; @@ -846,18 +840,10 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr segmentlists_tab[3]; xmlNodePtr fragment_timeline_node = NULL; xmlNodePtr fragment_templates_tab[5]; - char *duration_val = NULL; - char *presentation_timeoffset_val = NULL; - char *startnumber_val = NULL; - char *timescale_val = NULL; - char *initialization_val = NULL; - char *media_val = NULL; char *val = NULL; xmlNodePtr baseurl_nodes[4]; xmlNodePtr representation_node = node; - char *rep_id_val = xmlGetProp(representation_node, "id"); - char *rep_bandwidth_val = xmlGetProp(representation_node, "bandwidth"); - char *rep_framerate_val = xmlGetProp(representation_node, "frameRate"); + char *rep_bandwidth_val; enum AVMediaType type = AVMEDIA_TYPE_UNKNOWN; // try get information from representation @@ -869,253 +855,240 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, // try get information from adaption set if (type == AVMEDIA_TYPE_UNKNOWN) type = get_content_type(adaptionset_node); - if (type == AVMEDIA_TYPE_UNKNOWN) { + if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO && + type != AVMEDIA_TYPE_SUBTITLE) { av_log(s, AV_LOG_VERBOSE, "Parsing '%s' - skipp not supported representation type\n", url); - } else if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) { - // convert selected representation to our internal struct - rep = av_mallocz(sizeof(struct representation)); - if (!rep) { - ret = AVERROR(ENOMEM); - goto end; + return 0; + } + + // convert selected representation to our internal struct + rep = av_mallocz(sizeof(struct representation)); + if (!rep) + return AVERROR(ENOMEM); + if (c->adaptionset_lang) { + rep->lang = av_strdup(c->adaptionset_lang); + if (!rep->lang) { + av_log(s, AV_LOG_ERROR, "alloc language memory failure\n"); + av_freep(&rep); + return AVERROR(ENOMEM); } - if (c->adaptionset_lang) { - rep->lang = av_strdup(c->adaptionset_lang); - if (!rep->lang) { - av_log(s, AV_LOG_ERROR, "alloc language memory failure\n"); - av_freep(&rep); - ret = AVERROR(ENOMEM); - goto end; + } + rep->parent = s; + representation_segmenttemplate_node = find_child_node_by_name(representation_node, "SegmentTemplate"); + representation_baseurl_node = find_child_node_by_name(representation_node, "BaseURL"); + representation_segmentlist_node = find_child_node_by_name(representation_node, "SegmentList"); + rep_bandwidth_val = xmlGetProp(representation_node, "bandwidth"); + val = xmlGetProp(representation_node, "id"); + if (val) { + rep->id = av_strdup(val); + xmlFree(val); + if (!rep->id) + goto enomem; + } + + baseurl_nodes[0] = mpd_baseurl_node; + baseurl_nodes[1] = period_baseurl_node; + baseurl_nodes[2] = adaptionset_baseurl_node; + baseurl_nodes[3] = representation_baseurl_node; + + ret = resolve_content_path(s, url, &c->max_url_size, baseurl_nodes, 4); + c->max_url_size = aligned(c->max_url_size + + (rep->id ? strlen(rep->id) : 0) + + (rep_bandwidth_val ? strlen(rep_bandwidth_val) : 0)); + if (ret == AVERROR(ENOMEM) || ret == 0) + goto free; + if (representation_segmenttemplate_node || fragment_template_node || period_segmenttemplate_node) { + fragment_timeline_node = NULL; + fragment_templates_tab[0] = representation_segmenttemplate_node; + fragment_templates_tab[1] = adaptionset_segmentlist_node; + fragment_templates_tab[2] = fragment_template_node; + fragment_templates_tab[3] = period_segmenttemplate_node; + fragment_templates_tab[4] = period_segmentlist_node; + + val = get_val_from_nodes_tab(fragment_templates_tab, 4, "initialization"); + if (val) { + rep->init_section = av_mallocz(sizeof(struct fragment)); + if (!rep->init_section) { + xmlFree(val); + goto enomem; + } + c->max_url_size = aligned(c->max_url_size + strlen(val)); + rep->init_section->url = get_content_url(baseurl_nodes, 4, + c->max_url_size, rep->id, + rep_bandwidth_val, val); + xmlFree(val); + if (!rep->init_section->url) + goto enomem; + rep->init_section->size = -1; + } + val = get_val_from_nodes_tab(fragment_templates_tab, 4, "media"); + if (val) { + c->max_url_size = aligned(c->max_url_size + strlen(val)); + rep->url_template = get_content_url(baseurl_nodes, 4, + c->max_url_size, rep->id, + rep_bandwidth_val, val); + xmlFree(val); + } + val = get_val_from_nodes_tab(fragment_templates_tab, 4, "presentationTimeOffset"); + if (val) { + rep->presentation_timeoffset = (int64_t) strtoll(val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->presentation_timeoffset = [%"PRId64"]\n", rep->presentation_timeoffset); + xmlFree(val); + } + val = get_val_from_nodes_tab(fragment_templates_tab, 4, "duration"); + if (val) { + rep->fragment_duration = (int64_t) strtoll(val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); + xmlFree(val); + } + val = get_val_from_nodes_tab(fragment_templates_tab, 4, "timescale"); + if (val) { + rep->fragment_timescale = (int64_t) strtoll(val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); + xmlFree(val); + } + val = get_val_from_nodes_tab(fragment_templates_tab, 4, "startNumber"); + if (val) { + rep->start_number = rep->first_seq_no = (int64_t) strtoll(val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); + xmlFree(val); + } + if (adaptionset_supplementalproperty_node) { + if (!av_strcasecmp(xmlGetProp(adaptionset_supplementalproperty_node,"schemeIdUri"), "http://dashif.org/guidelines/last-segment-number")) { + val = xmlGetProp(adaptionset_supplementalproperty_node,"value"); + if (!val) { + av_log(s, AV_LOG_ERROR, "Missing value attribute in adaptionset_supplementalproperty_node\n"); + } else { + rep->last_seq_no =(int64_t) strtoll(val, NULL, 10) - 1; + xmlFree(val); + } } } - rep->parent = s; - representation_segmenttemplate_node = find_child_node_by_name(representation_node, "SegmentTemplate"); - representation_baseurl_node = find_child_node_by_name(representation_node, "BaseURL"); - representation_segmentlist_node = find_child_node_by_name(representation_node, "SegmentList"); - baseurl_nodes[0] = mpd_baseurl_node; - baseurl_nodes[1] = period_baseurl_node; - baseurl_nodes[2] = adaptionset_baseurl_node; - baseurl_nodes[3] = representation_baseurl_node; + fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline"); - ret = resolve_content_path(s, url, &c->max_url_size, baseurl_nodes, 4); - c->max_url_size = aligned(c->max_url_size - + (rep_id_val ? strlen(rep_id_val) : 0) - + (rep_bandwidth_val ? strlen(rep_bandwidth_val) : 0)); - if (ret == AVERROR(ENOMEM) || ret == 0) { - goto end; - } - if (representation_segmenttemplate_node || fragment_template_node || period_segmenttemplate_node) { - fragment_timeline_node = NULL; - fragment_templates_tab[0] = representation_segmenttemplate_node; - fragment_templates_tab[1] = adaptionset_segmentlist_node; - fragment_templates_tab[2] = fragment_template_node; - fragment_templates_tab[3] = period_segmenttemplate_node; - fragment_templates_tab[4] = period_segmentlist_node; - - presentation_timeoffset_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "presentationTimeOffset"); - duration_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "duration"); - startnumber_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "startNumber"); - timescale_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "timescale"); - initialization_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "initialization"); - media_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "media"); - - if (initialization_val) { - rep->init_section = av_mallocz(sizeof(struct fragment)); - if (!rep->init_section) { - av_free(rep); - ret = AVERROR(ENOMEM); - goto end; - } - c->max_url_size = aligned(c->max_url_size + strlen(initialization_val)); - rep->init_section->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, initialization_val); - if (!rep->init_section->url) { - av_free(rep->init_section); - av_free(rep); - ret = AVERROR(ENOMEM); - goto end; - } - rep->init_section->size = -1; - xmlFree(initialization_val); - } - - if (media_val) { - c->max_url_size = aligned(c->max_url_size + strlen(media_val)); - rep->url_template = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, media_val); - xmlFree(media_val); - } - - if (presentation_timeoffset_val) { - rep->presentation_timeoffset = (int64_t) strtoll(presentation_timeoffset_val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->presentation_timeoffset = [%"PRId64"]\n", rep->presentation_timeoffset); - xmlFree(presentation_timeoffset_val); - } - if (duration_val) { - rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); - xmlFree(duration_val); - } - if (timescale_val) { - rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); - xmlFree(timescale_val); - } - if (startnumber_val) { - rep->start_number = rep->first_seq_no = (int64_t) strtoll(startnumber_val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); - xmlFree(startnumber_val); - } - if (adaptionset_supplementalproperty_node) { - if (!av_strcasecmp(xmlGetProp(adaptionset_supplementalproperty_node,"schemeIdUri"), "http://dashif.org/guidelines/last-segment-number")) { - val = xmlGetProp(adaptionset_supplementalproperty_node,"value"); - if (!val) { - av_log(s, AV_LOG_ERROR, "Missing value attribute in adaptionset_supplementalproperty_node\n"); - } else { - rep->last_seq_no =(int64_t) strtoll(val, NULL, 10) - 1; - xmlFree(val); - } - } - } - - fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline"); - - if (!fragment_timeline_node) - fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline"); - if (!fragment_timeline_node) - fragment_timeline_node = find_child_node_by_name(adaptionset_segmentlist_node, "SegmentTimeline"); - if (!fragment_timeline_node) - fragment_timeline_node = find_child_node_by_name(period_segmentlist_node, "SegmentTimeline"); - if (fragment_timeline_node) { - fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node); - while (fragment_timeline_node) { - ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node); - if (ret < 0) { - return ret; - } - fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node); - } - } - } else if (representation_baseurl_node && !representation_segmentlist_node) { - seg = av_mallocz(sizeof(struct fragment)); - if (!seg) { - ret = AVERROR(ENOMEM); - goto end; - } - seg->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, NULL); - if (!seg->url) { - av_free(seg); - ret = AVERROR(ENOMEM); - goto end; - } - seg->size = -1; - dynarray_add(&rep->fragments, &rep->n_fragments, seg); - } else if (representation_segmentlist_node) { - // TODO: https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html - // http://www-itec.uni-klu.ac.at/dash/ddash/mpdGenerator.php?fragmentlength=15&type=full - xmlNodePtr fragmenturl_node = NULL; - segmentlists_tab[0] = representation_segmentlist_node; - segmentlists_tab[1] = adaptionset_segmentlist_node; - segmentlists_tab[2] = period_segmentlist_node; - - duration_val = get_val_from_nodes_tab(segmentlists_tab, 3, "duration"); - timescale_val = get_val_from_nodes_tab(segmentlists_tab, 3, "timescale"); - startnumber_val = get_val_from_nodes_tab(segmentlists_tab, 3, "startNumber"); - if (duration_val) { - rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); - xmlFree(duration_val); - } - if (timescale_val) { - rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); - xmlFree(timescale_val); - } - if (startnumber_val) { - rep->start_number = rep->first_seq_no = (int64_t) strtoll(startnumber_val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); - xmlFree(startnumber_val); - } - - fragmenturl_node = xmlFirstElementChild(representation_segmentlist_node); - while (fragmenturl_node) { - ret = parse_manifest_segmenturlnode(s, rep, fragmenturl_node, - baseurl_nodes, - rep_id_val, - rep_bandwidth_val); - if (ret < 0) { - return ret; - } - fragmenturl_node = xmlNextElementSibling(fragmenturl_node); - } - - fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline"); - - if (!fragment_timeline_node) - fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline"); - if (!fragment_timeline_node) - fragment_timeline_node = find_child_node_by_name(adaptionset_segmentlist_node, "SegmentTimeline"); - if (!fragment_timeline_node) - fragment_timeline_node = find_child_node_by_name(period_segmentlist_node, "SegmentTimeline"); - if (fragment_timeline_node) { - fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node); - while (fragment_timeline_node) { - ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node); - if (ret < 0) { - return ret; - } - fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node); - } - } - } else { - free_representation(rep); - rep = NULL; - av_log(s, AV_LOG_ERROR, "Unknown format of Representation node id[%s] \n", (const char *)rep_id_val); - } - - if (rep) { - if (rep->fragment_duration > 0 && !rep->fragment_timescale) - rep->fragment_timescale = 1; - rep->bandwidth = rep_bandwidth_val ? atoi(rep_bandwidth_val) : 0; - strncpy(rep->id, rep_id_val ? rep_id_val : "", sizeof(rep->id)); - rep->framerate = av_make_q(0, 0); - if (type == AVMEDIA_TYPE_VIDEO && rep_framerate_val) { - ret = av_parse_video_rate(&rep->framerate, rep_framerate_val); + if (!fragment_timeline_node) + fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline"); + if (!fragment_timeline_node) + fragment_timeline_node = find_child_node_by_name(adaptionset_segmentlist_node, "SegmentTimeline"); + if (!fragment_timeline_node) + fragment_timeline_node = find_child_node_by_name(period_segmentlist_node, "SegmentTimeline"); + if (fragment_timeline_node) { + fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node); + while (fragment_timeline_node) { + ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node); if (ret < 0) - av_log(s, AV_LOG_VERBOSE, "Ignoring invalid frame rate '%s'\n", rep_framerate_val); + goto free; + fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node); } + } + } else if (representation_baseurl_node && !representation_segmentlist_node) { + seg = av_mallocz(sizeof(struct fragment)); + if (!seg) + goto enomem; + ret = av_dynarray_add_nofree(&rep->fragments, &rep->n_fragments, seg); + if (ret < 0) { + av_free(seg); + goto free; + } + seg->url = get_content_url(baseurl_nodes, 4, c->max_url_size, + rep->id, rep_bandwidth_val, NULL); + if (!seg->url) + goto enomem; + seg->size = -1; + } else if (representation_segmentlist_node) { + // TODO: https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html + // http://www-itec.uni-klu.ac.at/dash/ddash/mpdGenerator.php?fragmentlength=15&type=full + xmlNodePtr fragmenturl_node = NULL; + segmentlists_tab[0] = representation_segmentlist_node; + segmentlists_tab[1] = adaptionset_segmentlist_node; + segmentlists_tab[2] = period_segmentlist_node; - switch (type) { - case AVMEDIA_TYPE_VIDEO: - rep->rep_idx = video_rep_idx; - dynarray_add(&c->videos, &c->n_videos, rep); - break; - case AVMEDIA_TYPE_AUDIO: - rep->rep_idx = audio_rep_idx; - dynarray_add(&c->audios, &c->n_audios, rep); - break; - case AVMEDIA_TYPE_SUBTITLE: - rep->rep_idx = subtitle_rep_idx; - dynarray_add(&c->subtitles, &c->n_subtitles, rep); - break; - default: - av_log(s, AV_LOG_WARNING, "Unsupported the stream type %d\n", type); - break; + val = get_val_from_nodes_tab(segmentlists_tab, 3, "duration"); + if (val) { + rep->fragment_duration = (int64_t) strtoll(val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); + xmlFree(val); + } + val = get_val_from_nodes_tab(segmentlists_tab, 3, "timescale"); + if (val) { + rep->fragment_timescale = (int64_t) strtoll(val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); + xmlFree(val); + } + val = get_val_from_nodes_tab(segmentlists_tab, 3, "startNumber"); + if (val) { + rep->start_number = rep->first_seq_no = (int64_t) strtoll(val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); + xmlFree(val); + } + + fragmenturl_node = xmlFirstElementChild(representation_segmentlist_node); + while (fragmenturl_node) { + ret = parse_manifest_segmenturlnode(s, rep, fragmenturl_node, + baseurl_nodes, rep->id, + rep_bandwidth_val); + if (ret < 0) + goto free; + fragmenturl_node = xmlNextElementSibling(fragmenturl_node); + } + + fragment_timeline_node = find_child_node_by_name(adaptionset_segmentlist_node, "SegmentTimeline"); + if (!fragment_timeline_node) + fragment_timeline_node = find_child_node_by_name(period_segmentlist_node, "SegmentTimeline"); + if (fragment_timeline_node) { + fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node); + while (fragment_timeline_node) { + ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node); + if (ret < 0) + goto free; + fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node); } } + } else { + av_log(s, AV_LOG_ERROR, "Unknown format of Representation node id '%s' \n", + rep->id ? rep->id : ""); + goto free; + } + + if (rep->fragment_duration > 0 && !rep->fragment_timescale) + rep->fragment_timescale = 1; + rep->bandwidth = rep_bandwidth_val ? atoi(rep_bandwidth_val) : 0; + rep->framerate = av_make_q(0, 0); + if (type == AVMEDIA_TYPE_VIDEO) { + char *rep_framerate_val = xmlGetProp(representation_node, "frameRate"); + if (rep_framerate_val) { + ret = av_parse_video_rate(&rep->framerate, rep_framerate_val); + if (ret < 0) + av_log(s, AV_LOG_VERBOSE, "Ignoring invalid frame rate '%s'\n", rep_framerate_val); + xmlFree(rep_framerate_val); + } } - video_rep_idx += type == AVMEDIA_TYPE_VIDEO; - audio_rep_idx += type == AVMEDIA_TYPE_AUDIO; - subtitle_rep_idx += type == AVMEDIA_TYPE_SUBTITLE; + switch (type) { + case AVMEDIA_TYPE_VIDEO: + ret = av_dynarray_add_nofree(&c->videos, &c->n_videos, rep); + break; + case AVMEDIA_TYPE_AUDIO: + ret = av_dynarray_add_nofree(&c->audios, &c->n_audios, rep); + break; + case AVMEDIA_TYPE_SUBTITLE: + ret = av_dynarray_add_nofree(&c->subtitles, &c->n_subtitles, rep); + break; + } + if (ret < 0) + goto free; end: - if (rep_id_val) - xmlFree(rep_id_val); if (rep_bandwidth_val) xmlFree(rep_bandwidth_val); - if (rep_framerate_val) - xmlFree(rep_framerate_val); return ret; +enomem: + ret = AVERROR(ENOMEM); +free: + free_representation(rep); + goto end; } static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptionset_node) @@ -1153,17 +1126,17 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, node = xmlFirstElementChild(adaptionset_node); while (node) { - if (!av_strcasecmp(node->name, (const char *)"SegmentTemplate")) { + if (!av_strcasecmp(node->name, "SegmentTemplate")) { fragment_template_node = node; - } else if (!av_strcasecmp(node->name, (const char *)"ContentComponent")) { + } else if (!av_strcasecmp(node->name, "ContentComponent")) { content_component_node = node; - } else if (!av_strcasecmp(node->name, (const char *)"BaseURL")) { + } else if (!av_strcasecmp(node->name, "BaseURL")) { adaptionset_baseurl_node = node; - } else if (!av_strcasecmp(node->name, (const char *)"SegmentList")) { + } else if (!av_strcasecmp(node->name, "SegmentList")) { adaptionset_segmentlist_node = node; - } else if (!av_strcasecmp(node->name, (const char *)"SupplementalProperty")) { + } else if (!av_strcasecmp(node->name, "SupplementalProperty")) { adaptionset_supplementalproperty_node = node; - } else if (!av_strcasecmp(node->name, (const char *)"Representation")) { + } else if (!av_strcasecmp(node->name, "Representation")) { ret = parse_manifest_representation(s, url, node, adaptionset_node, mpd_baseurl_node, @@ -1182,7 +1155,8 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, } err: - av_freep(&c->adaptionset_lang); + xmlFree(c->adaptionset_lang); + c->adaptionset_lang = NULL; return ret; } @@ -1220,7 +1194,6 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) DASHContext *c = s->priv_data; int ret = 0; int close_in = 0; - uint8_t *new_url = NULL; int64_t filesize = 0; AVBPrint buf; AVDictionary *opts = NULL; @@ -1249,21 +1222,20 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) return ret; } - if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0) { - c->base_url = av_strdup(new_url); - } else { + if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, (uint8_t**)&c->base_url) < 0) c->base_url = av_strdup(url); - } filesize = avio_size(in); - if (filesize > MAX_MANIFEST_SIZE) { + filesize = filesize > 0 ? filesize : DEFAULT_MANIFEST_SIZE; + + if (filesize > MAX_BPRINT_READ_SIZE) { av_log(s, AV_LOG_ERROR, "Manifest too large: %"PRId64"\n", filesize); return AVERROR_INVALIDDATA; } - av_bprint_init(&buf, (filesize > 0) ? filesize + 1 : DEFAULT_MANIFEST_SIZE, AV_BPRINT_SIZE_UNLIMITED); + av_bprint_init(&buf, filesize + 1, AV_BPRINT_SIZE_UNLIMITED); - if ((ret = avio_read_to_bprint(in, &buf, MAX_MANIFEST_SIZE)) < 0 || + if ((ret = avio_read_to_bprint(in, &buf, MAX_BPRINT_READ_SIZE)) < 0 || !avio_feof(in) || (filesize = buf.len) == 0) { av_log(s, AV_LOG_ERROR, "Unable to read to manifest '%s'\n", url); @@ -1283,7 +1255,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } if (node->type != XML_ELEMENT_NODE || - av_strcasecmp(node->name, (const char *)"MPD")) { + av_strcasecmp(node->name, "MPD")) { ret = AVERROR_INVALIDDATA; av_log(s, AV_LOG_ERROR, "Unable to parse '%s' - wrong root node name[%s] type[%d]\n", url, node->name, (int)node->type); goto cleanup; @@ -1295,7 +1267,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) ret = AVERROR_INVALIDDATA; goto cleanup; } - if (!av_strcasecmp(val, (const char *)"dynamic")) + if (!av_strcasecmp(val, "dynamic")) c->is_live = 1; xmlFree(val); @@ -1303,29 +1275,29 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) while (attr) { val = xmlGetProp(node, attr->name); - if (!av_strcasecmp(attr->name, (const char *)"availabilityStartTime")) { - c->availability_start_time = get_utc_date_time_insec(s, (const char *)val); + if (!av_strcasecmp(attr->name, "availabilityStartTime")) { + c->availability_start_time = get_utc_date_time_insec(s, val); av_log(s, AV_LOG_TRACE, "c->availability_start_time = [%"PRId64"]\n", c->availability_start_time); - } else if (!av_strcasecmp(attr->name, (const char *)"availabilityEndTime")) { - c->availability_end_time = get_utc_date_time_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, "availabilityEndTime")) { + c->availability_end_time = get_utc_date_time_insec(s, val); av_log(s, AV_LOG_TRACE, "c->availability_end_time = [%"PRId64"]\n", c->availability_end_time); - } else if (!av_strcasecmp(attr->name, (const char *)"publishTime")) { - c->publish_time = get_utc_date_time_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, "publishTime")) { + c->publish_time = get_utc_date_time_insec(s, val); av_log(s, AV_LOG_TRACE, "c->publish_time = [%"PRId64"]\n", c->publish_time); - } else if (!av_strcasecmp(attr->name, (const char *)"minimumUpdatePeriod")) { - c->minimum_update_period = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, "minimumUpdatePeriod")) { + c->minimum_update_period = get_duration_insec(s, val); av_log(s, AV_LOG_TRACE, "c->minimum_update_period = [%"PRId64"]\n", c->minimum_update_period); - } else if (!av_strcasecmp(attr->name, (const char *)"timeShiftBufferDepth")) { - c->time_shift_buffer_depth = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, "timeShiftBufferDepth")) { + c->time_shift_buffer_depth = get_duration_insec(s, val); av_log(s, AV_LOG_TRACE, "c->time_shift_buffer_depth = [%"PRId64"]\n", c->time_shift_buffer_depth); - } else if (!av_strcasecmp(attr->name, (const char *)"minBufferTime")) { - c->min_buffer_time = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, "minBufferTime")) { + c->min_buffer_time = get_duration_insec(s, val); av_log(s, AV_LOG_TRACE, "c->min_buffer_time = [%"PRId64"]\n", c->min_buffer_time); - } else if (!av_strcasecmp(attr->name, (const char *)"suggestedPresentationDelay")) { - c->suggested_presentation_delay = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, "suggestedPresentationDelay")) { + c->suggested_presentation_delay = get_duration_insec(s, val); av_log(s, AV_LOG_TRACE, "c->suggested_presentation_delay = [%"PRId64"]\n", c->suggested_presentation_delay); - } else if (!av_strcasecmp(attr->name, (const char *)"mediaPresentationDuration")) { - c->media_presentation_duration = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, "mediaPresentationDuration")) { + c->media_presentation_duration = get_duration_insec(s, val); av_log(s, AV_LOG_TRACE, "c->media_presentation_duration = [%"PRId64"]\n", c->media_presentation_duration); } attr = attr->next; @@ -1342,16 +1314,16 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) // at now we can handle only one period, with the longest duration node = xmlFirstElementChild(node); while (node) { - if (!av_strcasecmp(node->name, (const char *)"Period")) { + if (!av_strcasecmp(node->name, "Period")) { period_duration_sec = 0; period_start_sec = 0; attr = node->properties; while (attr) { val = xmlGetProp(node, attr->name); - if (!av_strcasecmp(attr->name, (const char *)"duration")) { - period_duration_sec = get_duration_insec(s, (const char *)val); - } else if (!av_strcasecmp(attr->name, (const char *)"start")) { - period_start_sec = get_duration_insec(s, (const char *)val); + if (!av_strcasecmp(attr->name, "duration")) { + period_duration_sec = get_duration_insec(s, val); + } else if (!av_strcasecmp(attr->name, "start")) { + period_start_sec = get_duration_insec(s, val); } attr = attr->next; xmlFree(val); @@ -1376,13 +1348,13 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) adaptionset_node = xmlFirstElementChild(period_node); while (adaptionset_node) { - if (!av_strcasecmp(adaptionset_node->name, (const char *)"BaseURL")) { + if (!av_strcasecmp(adaptionset_node->name, "BaseURL")) { period_baseurl_node = adaptionset_node; - } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"SegmentTemplate")) { + } else if (!av_strcasecmp(adaptionset_node->name, "SegmentTemplate")) { period_segmenttemplate_node = adaptionset_node; - } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"SegmentList")) { + } else if (!av_strcasecmp(adaptionset_node->name, "SegmentList")) { period_segmentlist_node = adaptionset_node; - } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"AdaptationSet")) { + } else if (!av_strcasecmp(adaptionset_node->name, "AdaptationSet")) { parse_manifest_adaptationset(s, url, adaptionset_node, mpd_baseurl_node, period_baseurl_node, period_segmenttemplate_node, period_segmentlist_node); } adaptionset_node = xmlNextElementSibling(adaptionset_node); @@ -1394,7 +1366,6 @@ cleanup: xmlFreeNode(mpd_baseurl_node); } - av_free(new_url); av_bprint_finalize(&buf, NULL); if (close_in) { avio_close(in); @@ -1648,10 +1619,10 @@ static struct fragment *get_current_fragment(struct representation *pls) refresh_manifest(pls->parent); } if (pls->cur_seq_no <= min_seq_no) { - av_log(pls->parent, AV_LOG_VERBOSE, "old fragment: cur[%"PRId64"] min[%"PRId64"] max[%"PRId64"], playlist %d\n", (int64_t)pls->cur_seq_no, min_seq_no, max_seq_no, (int)pls->rep_idx); + av_log(pls->parent, AV_LOG_VERBOSE, "old fragment: cur[%"PRId64"] min[%"PRId64"] max[%"PRId64"]\n", (int64_t)pls->cur_seq_no, min_seq_no, max_seq_no); pls->cur_seq_no = calc_cur_seg_no(pls->parent, pls); } else if (pls->cur_seq_no > max_seq_no) { - av_log(pls->parent, AV_LOG_VERBOSE, "new fragment: min[%"PRId64"] max[%"PRId64"], playlist %d\n", min_seq_no, max_seq_no, (int)pls->rep_idx); + av_log(pls->parent, AV_LOG_VERBOSE, "new fragment: min[%"PRId64"] max[%"PRId64"]\n", min_seq_no, max_seq_no); } seg = av_mallocz(sizeof(struct fragment)); if (!seg) { @@ -1664,8 +1635,15 @@ static struct fragment *get_current_fragment(struct representation *pls) } } if (seg) { - char *tmpfilename= av_mallocz(c->max_url_size); + char *tmpfilename; + if (!pls->url_template) { + av_log(pls->parent, AV_LOG_ERROR, "Cannot get fragment, missing template URL\n"); + av_free(seg); + return NULL; + } + tmpfilename = av_mallocz(c->max_url_size); if (!tmpfilename) { + av_free(seg); return NULL; } ff_dash_fill_tmpl_params(tmpfilename, c->max_url_size, pls->url_template, 0, pls->cur_seq_no, 0, get_segment_start_time_based_on_timeline(pls, pls->cur_seq_no)); @@ -1676,6 +1654,7 @@ static struct fragment *get_current_fragment(struct representation *pls) if (!seg->url) { av_log(pls->parent, AV_LOG_ERROR, "Cannot resolve template url '%s'\n", pls->url_template); av_free(tmpfilename); + av_free(seg); return NULL; } } @@ -1722,9 +1701,9 @@ static int open_input(DASHContext *c, struct representation *pls, struct fragmen } ff_make_absolute_url(url, c->max_url_size, c->base_url, seg->url); - av_log(pls->parent, AV_LOG_VERBOSE, "DASH request for url '%s', offset %"PRId64", playlist %d\n", - url, seg->url_offset, pls->rep_idx); - ret = open_url(pls->parent, &pls->input, url, c->avio_opts, opts, NULL); + av_log(pls->parent, AV_LOG_VERBOSE, "DASH request for url '%s', offset %"PRId64"\n", + url, seg->url_offset); + ret = open_url(pls->parent, &pls->input, url, &c->avio_opts, opts, NULL); cleanup: av_free(url); @@ -1748,8 +1727,7 @@ static int update_init_section(struct representation *pls) ret = open_input(c, pls, pls->init_section); if (ret < 0) { av_log(pls->parent, AV_LOG_WARNING, - "Failed to open an initialization section in playlist %d\n", - pls->rep_idx); + "Failed to open an initialization section\n"); return ret; } @@ -1817,7 +1795,7 @@ restart: ret = AVERROR_EXIT; goto end; } - av_log(v->parent, AV_LOG_WARNING, "Failed to open fragment of playlist %d\n", v->rep_idx); + av_log(v->parent, AV_LOG_WARNING, "Failed to open fragment of playlist\n"); v->cur_seq_no++; goto restart; } @@ -1867,10 +1845,8 @@ static int save_avio_options(AVFormatContext *s) if (av_opt_get(s->pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) { if (buf[0] != '\0') { ret = av_dict_set(&c->avio_opts, *opt, buf, AV_DICT_DONT_STRDUP_VAL); - if (ret < 0) { - av_freep(&buf); + if (ret < 0) return ret; - } } else { av_freep(&buf); } @@ -1898,7 +1874,6 @@ static void close_demux_for_component(struct representation *pls) memset(&pls->pb, 0x00, sizeof(AVIOContext)); pls->ctx->pb = NULL; avformat_close_input(&pls->ctx); - pls->ctx = NULL; } static int reopen_demux_for_component(AVFormatContext *s, struct representation *pls) @@ -1930,11 +1905,8 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation pls->ctx = NULL; goto fail; } - if (c->is_live) { - ffio_init_context(&pls->pb, avio_ctx_buffer , INITIAL_BUFFER_SIZE, 0, pls, read_data, NULL, NULL); - } else { - ffio_init_context(&pls->pb, avio_ctx_buffer , INITIAL_BUFFER_SIZE, 0, pls, read_data, NULL, seek_data); - } + ffio_init_context(&pls->pb, avio_ctx_buffer, INITIAL_BUFFER_SIZE, 0, + pls, read_data, NULL, c->is_live ? NULL : seek_data); pls->pb.seekable = 0; if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0) @@ -1943,9 +1915,10 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO; pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; + pls->ctx->interrupt_callback = s->interrupt_callback; ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0); if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx); + av_log(s, AV_LOG_ERROR, "Error when loading first fragment of playlist\n"); avformat_free_context(pls->ctx); pls->ctx = NULL; goto fail; @@ -2001,6 +1974,20 @@ static int open_demux_for_component(AVFormatContext *s, struct representation *p st->id = i; avcodec_parameters_copy(st->codecpar, ist->codecpar); avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); + + // copy disposition + st->disposition = ist->disposition; + + // copy side data + for (int i = 0; i < ist->nb_side_data; i++) { + const AVPacketSideData *sd_src = &ist->side_data[i]; + uint8_t *dst_data; + + dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size); + if (!dst_data) + return AVERROR(ENOMEM); + memcpy(dst_data, sd_src->data, sd_src->size); + } } return 0; @@ -2023,7 +2010,12 @@ static int is_common_init_section_exist(struct representation **pls, int n_pls) url_offset = first_init_section->url_offset; size = pls[0]->init_section->size; for (i=0;iinit_section->url,url) || pls[i]->init_section->url_offset != url_offset || pls[i]->init_section->size != size) { + if (!pls[i]->init_section) + continue; + + if (av_strcasecmp(pls[i]->init_section->url, url) || + pls[i]->init_section->url_offset != url_offset || + pls[i]->init_section->size != size) { return 0; } } @@ -2045,11 +2037,21 @@ static int copy_init_section(struct representation *rep_dest, struct representat return 0; } +static int dash_close(AVFormatContext *s); + +static void move_metadata(AVStream *st, const char *key, char **value) +{ + if (*value) { + av_dict_set(&st->metadata, key, *value, AV_DICT_DONT_STRDUP_VAL); + *value = NULL; + } +} static int dash_read_header(AVFormatContext *s) { DASHContext *c = s->priv_data; struct representation *rep; + AVProgram *program; int ret = 0; int stream_index = 0; int i; @@ -2108,11 +2110,11 @@ static int dash_read_header(AVFormatContext *s) } if (c->n_subtitles) - c->is_init_section_common_audio = is_common_init_section_exist(c->subtitles, c->n_subtitles); + c->is_init_section_common_subtitle = is_common_init_section_exist(c->subtitles, c->n_subtitles); for (i = 0; i < c->n_subtitles; i++) { rep = c->subtitles[i]; - if (i > 0 && c->is_init_section_common_audio) { + if (i > 0 && c->is_init_section_common_subtitle) { ret = copy_init_section(rep, c->subtitles[0]); if (ret < 0) goto fail; @@ -2131,50 +2133,40 @@ static int dash_read_header(AVFormatContext *s) } /* Create a program */ - if (!ret) { - AVProgram *program; - program = av_new_program(s, 0); - if (!program) { - goto fail; - } + program = av_new_program(s, 0); + if (!program) { + ret = AVERROR(ENOMEM); + goto fail; + } - for (i = 0; i < c->n_videos; i++) { - rep = c->videos[i]; - av_program_add_stream_index(s, 0, rep->stream_index); - rep->assoc_stream = s->streams[rep->stream_index]; - if (rep->bandwidth > 0) - av_dict_set_int(&rep->assoc_stream->metadata, "variant_bitrate", rep->bandwidth, 0); - if (rep->id[0]) - av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0); - } - for (i = 0; i < c->n_audios; i++) { - rep = c->audios[i]; - av_program_add_stream_index(s, 0, rep->stream_index); - rep->assoc_stream = s->streams[rep->stream_index]; - if (rep->bandwidth > 0) - av_dict_set_int(&rep->assoc_stream->metadata, "variant_bitrate", rep->bandwidth, 0); - if (rep->id[0]) - av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0); - if (rep->lang) { - av_dict_set(&rep->assoc_stream->metadata, "language", rep->lang, 0); - av_freep(&rep->lang); - } - } - for (i = 0; i < c->n_subtitles; i++) { - rep = c->subtitles[i]; - av_program_add_stream_index(s, 0, rep->stream_index); - rep->assoc_stream = s->streams[rep->stream_index]; - if (rep->id[0]) - av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0); - if (rep->lang) { - av_dict_set(&rep->assoc_stream->metadata, "language", rep->lang, 0); - av_freep(&rep->lang); - } - } + for (i = 0; i < c->n_videos; i++) { + rep = c->videos[i]; + av_program_add_stream_index(s, 0, rep->stream_index); + rep->assoc_stream = s->streams[rep->stream_index]; + if (rep->bandwidth > 0) + av_dict_set_int(&rep->assoc_stream->metadata, "variant_bitrate", rep->bandwidth, 0); + move_metadata(rep->assoc_stream, "id", &rep->id); + } + for (i = 0; i < c->n_audios; i++) { + rep = c->audios[i]; + av_program_add_stream_index(s, 0, rep->stream_index); + rep->assoc_stream = s->streams[rep->stream_index]; + if (rep->bandwidth > 0) + av_dict_set_int(&rep->assoc_stream->metadata, "variant_bitrate", rep->bandwidth, 0); + move_metadata(rep->assoc_stream, "id", &rep->id); + move_metadata(rep->assoc_stream, "language", &rep->lang); + } + for (i = 0; i < c->n_subtitles; i++) { + rep = c->subtitles[i]; + av_program_add_stream_index(s, 0, rep->stream_index); + rep->assoc_stream = s->streams[rep->stream_index]; + move_metadata(rep->assoc_stream, "id", &rep->id); + move_metadata(rep->assoc_stream, "language", &rep->lang); } return 0; fail: + dash_close(s); return ret; } @@ -2271,6 +2263,7 @@ static int dash_close(AVFormatContext *s) DASHContext *c = s->priv_data; free_audio_list(c); free_video_list(c); + free_subtitle_list(c); av_dict_free(&c->avio_opts); av_freep(&c->base_url); return 0; @@ -2283,8 +2276,8 @@ static int dash_seek(AVFormatContext *s, struct representation *pls, int64_t see int j = 0; int64_t duration = 0; - av_log(pls->parent, AV_LOG_VERBOSE, "DASH seek pos[%"PRId64"ms], playlist %d%s\n", - seek_pos_msec, pls->rep_idx, dry_run ? " (dry)" : ""); + av_log(pls->parent, AV_LOG_VERBOSE, "DASH seek pos[%"PRId64"ms] %s\n", + seek_pos_msec, dry_run ? " (dry)" : ""); // single fragment mode if (pls->n_fragments == 1) { @@ -2302,8 +2295,8 @@ static int dash_seek(AVFormatContext *s, struct representation *pls, int64_t see if (pls->n_timelines > 0 && pls->fragment_timescale > 0) { int64_t num = pls->first_seq_no; av_log(pls->parent, AV_LOG_VERBOSE, "dash_seek with SegmentTimeline start n_timelines[%d] " - "last_seq_no[%"PRId64"], playlist %d.\n", - (int)pls->n_timelines, (int64_t)pls->last_seq_no, (int)pls->rep_idx); + "last_seq_no[%"PRId64"].\n", + (int)pls->n_timelines, (int64_t)pls->last_seq_no); for (i = 0; i < pls->n_timelines; i++) { if (pls->timelines[i]->starttime > 0) { duration = pls->timelines[i]->starttime; @@ -2324,8 +2317,8 @@ static int dash_seek(AVFormatContext *s, struct representation *pls, int64_t see set_seq_num: pls->cur_seq_no = num > pls->last_seq_no ? pls->last_seq_no : num; - av_log(pls->parent, AV_LOG_VERBOSE, "dash_seek with SegmentTimeline end cur_seq_no[%"PRId64"], playlist %d.\n", - (int64_t)pls->cur_seq_no, (int)pls->rep_idx); + av_log(pls->parent, AV_LOG_VERBOSE, "dash_seek with SegmentTimeline end cur_seq_no[%"PRId64"].\n", + (int64_t)pls->cur_seq_no); } else if (pls->fragment_duration > 0) { pls->cur_seq_no = pls->first_seq_no + ((seek_pos_msec * pls->fragment_timescale) / pls->fragment_duration) / 1000; } else { diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 00a37b175..81a5c2b45 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -115,6 +115,7 @@ typedef struct OutputStream { int64_t last_dts, last_pts; int last_flags; int bit_rate; + int first_segment_bit_rate; SegmentType segment_type; /* segment type selected for this particular stream */ const char *format_name; const char *extension_name; @@ -171,6 +172,7 @@ typedef struct DASHContext { const char *user_agent; AVDictionary *http_opts; int hls_playlist; + const char *hls_master_name; int http_persistent; int master_playlist_created; AVIOContext *mpd_out; @@ -196,6 +198,7 @@ typedef struct DASHContext { int target_latency_refid; AVRational min_playback_rate; AVRational max_playback_rate; + int64_t update_period; } DASHContext; static struct codec_string { @@ -839,8 +842,12 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind continue; if (os->bit_rate > 0) - snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", - os->bit_rate); + snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->bit_rate); + else if (final) { + int average_bit_rate = os->pos * 8 * AV_TIME_BASE / c->total_duration; + snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", average_bit_rate); + } else if (os->first_segment_bit_rate > 0) + snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->first_segment_bit_rate); if (as->media_type == AVMEDIA_TYPE_VIDEO) { avio_printf(out, "\t\t\tuse_template && !c->use_timeline) update_period = 500; + if (c->update_period) + update_period = c->update_period; avio_printf(out, "\tminimumUpdatePeriod=\"PT%"PRId64"S\"\n", update_period); if (!c->ldash) avio_printf(out, "\tsuggestedPresentationDelay=\"PT%"PRId64"S\"\n", c->last_duration / AV_TIME_BASE); @@ -1261,9 +1270,9 @@ static int write_manifest(AVFormatContext *s, int final) return 0; if (*c->dirname) - snprintf(filename_hls, sizeof(filename_hls), "%smaster.m3u8", c->dirname); + snprintf(filename_hls, sizeof(filename_hls), "%s%s", c->dirname, c->hls_master_name); else - snprintf(filename_hls, sizeof(filename_hls), "master.m3u8"); + snprintf(filename_hls, sizeof(filename_hls), "%s", c->hls_master_name); snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", filename_hls); @@ -1304,7 +1313,13 @@ static int write_manifest(AVFormatContext *s, int final) OutputStream *os = &c->streams[i]; char *agroup = NULL; char *codec_str_ptr = NULL; - int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead; + int stream_bitrate = os->muxer_overhead; + if (os->bit_rate > 0) + stream_bitrate += os->bit_rate; + else if (final) + stream_bitrate += os->pos * 8 * AV_TIME_BASE / c->total_duration; + else if (os->first_segment_bit_rate > 0) + stream_bitrate += os->first_segment_bit_rate; if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) continue; if (os->segment_type != SEGMENT_TYPE_MP4) @@ -1671,7 +1686,7 @@ static int dash_init(AVFormatContext *s) 1024 * 1024); if (as->par.num && av_cmp_q(par, as->par)) { - av_log(s, AV_LOG_ERROR, "Conflicting stream par values in Adaptation Set %d\n", os->as_idx); + av_log(s, AV_LOG_ERROR, "Conflicting stream aspect ratios values in Adaptation Set %d. Please ensure all adaptation sets have the same aspect ratio\n", os->as_idx); return AVERROR(EINVAL); } as->par = par; @@ -1800,7 +1815,8 @@ static int update_stream_extradata(AVFormatContext *s, OutputStream *os, { AVCodecParameters *par = os->ctx->streams[0]->codecpar; uint8_t *extradata; - int ret, extradata_size; + buffer_size_t extradata_size; + int ret; if (par->extradata_size) return 0; @@ -1957,11 +1973,8 @@ static int dash_flush(AVFormatContext *s, int final, int stream) os->total_pkt_size = 0; os->total_pkt_duration = 0; - if (!os->bit_rate) { - // calculate average bitrate of first segment - int64_t bitrate = (int64_t) range_length * 8 * (c->use_timeline ? os->ctx->streams[0]->time_base.den : AV_TIME_BASE) / duration; - if (bitrate >= 0) - os->bit_rate = bitrate; + if (!os->bit_rate && !os->first_segment_bit_rate) { + os->first_segment_bit_rate = (int64_t) range_length * 8 * AV_TIME_BASE / duration; } add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_pts, os->pos, range_length, index_length, next_exp_index); av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, os->full_path); @@ -2018,7 +2031,7 @@ static int dash_parse_prft(DASHContext *c, AVPacket *pkt) { OutputStream *os = &c->streams[pkt->stream_index]; AVProducerReferenceTime *prft; - int side_data_size; + buffer_size_t side_data_size; prft = (AVProducerReferenceTime *)av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &side_data_size); if (!prft || side_data_size != sizeof(AVProducerReferenceTime) || (prft->flags && prft->flags != 24)) { @@ -2292,7 +2305,7 @@ static int dash_write_trailer(AVFormatContext *s) if (c->hls_playlist && c->master_playlist_created) { char filename[1024]; - snprintf(filename, sizeof(filename), "%smaster.m3u8", c->dirname); + snprintf(filename, sizeof(filename), "%s%s", c->dirname, c->hls_master_name); dashenc_delete_file(s, filename); } } @@ -2349,6 +2362,7 @@ static const AVOption options[] = { { "http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E}, { "http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, { "hls_playlist", "Generate HLS playlist files(master.m3u8, media_%d.m3u8)", OFFSET(hls_playlist), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, + { "hls_master_name", "HLS master playlist name", OFFSET(hls_master_name), AV_OPT_TYPE_STRING, {.str = "master.m3u8"}, 0, 0, E }, { "streaming", "Enable/Disable streaming mode of output. Each frame will be moof fragment", OFFSET(streaming), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, { "timeout", "set timeout for socket I/O operations", OFFSET(timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E }, { "index_correction", "Enable/Disable segment index correction logic", OFFSET(index_correction), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, @@ -2370,6 +2384,7 @@ static const AVOption options[] = { { "target_latency", "Set desired target latency for Low-latency dash", OFFSET(target_latency), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT_MAX, E }, { "min_playback_rate", "Set desired minimum playback rate", OFFSET(min_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E }, { "max_playback_rate", "Set desired maximum playback rate", OFFSET(max_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E }, + { "update_period", "Set the mpd update interval", OFFSET(update_period), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E}, { NULL }, }; diff --git a/libavformat/daudenc.c b/libavformat/daudenc.c index 15a5afdfc..b489659a8 100644 --- a/libavformat/daudenc.c +++ b/libavformat/daudenc.c @@ -21,11 +21,11 @@ #include "avformat.h" -static int daud_write_header(struct AVFormatContext *s) +static int daud_init(struct AVFormatContext *s) { AVCodecParameters *par = s->streams[0]->codecpar; if (par->channels!=6 || par->sample_rate!=96000) - return -1; + return AVERROR(EINVAL); return 0; } @@ -34,7 +34,7 @@ static int daud_write_packet(struct AVFormatContext *s, AVPacket *pkt) if (pkt->size > 65535) { av_log(s, AV_LOG_ERROR, "Packet size too large for s302m. (%d > 65535)\n", pkt->size); - return -1; + return AVERROR_INVALIDDATA; } avio_wb16(s->pb, pkt->size); avio_wb16(s->pb, 0x8010); // unknown @@ -48,7 +48,7 @@ AVOutputFormat ff_daud_muxer = { .extensions = "302", .audio_codec = AV_CODEC_ID_PCM_S24DAUD, .video_codec = AV_CODEC_ID_NONE, - .write_header = daud_write_header, + .init = daud_init, .write_packet = daud_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; diff --git a/libavformat/dcstr.c b/libavformat/dcstr.c index 9041a8653..9ddccc7f2 100644 --- a/libavformat/dcstr.c +++ b/libavformat/dcstr.c @@ -43,6 +43,8 @@ static int dcstr_read_header(AVFormatContext *s) st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->channels = avio_rl32(s->pb); st->codecpar->sample_rate = avio_rl32(s->pb); + if (st->codecpar->sample_rate <= 0) + return AVERROR_INVALIDDATA; codec = avio_rl32(s->pb); align = avio_rl32(s->pb); avio_skip(s->pb, 4); diff --git a/libavformat/dhav.c b/libavformat/dhav.c index 91c175498..d5d25801c 100644 --- a/libavformat/dhav.c +++ b/libavformat/dhav.c @@ -173,18 +173,9 @@ static int read_chunk(AVFormatContext *s) if (avio_feof(s->pb)) return AVERROR_EOF; - if (avio_rl32(s->pb) != MKTAG('D','H','A','V') && dhav->last_good_pos < INT64_MAX - 0x8000) { - dhav->last_good_pos += 0x8000; - avio_seek(s->pb, dhav->last_good_pos, SEEK_SET); - - while (avio_rl32(s->pb) != MKTAG('D','H','A','V')) { - if (avio_feof(s->pb) || dhav->last_good_pos >= INT64_MAX - 0x8000) - return AVERROR_EOF; - dhav->last_good_pos += 0x8000; - ret = avio_skip(s->pb, 0x8000 - 4); - if (ret < 0) - return ret; - } + while (avio_r8(s->pb) != 'D' || avio_r8(s->pb) != 'H' || avio_r8(s->pb) != 'A' || avio_r8(s->pb) != 'V') { + if (avio_feof(s->pb)) + return AVERROR_EOF; } start = avio_tell(s->pb) - 4; @@ -361,7 +352,7 @@ retry: case 0x4: case 0x8: st->codecpar->codec_id = AV_CODEC_ID_H264; break; case 0xc: st->codecpar->codec_id = AV_CODEC_ID_HEVC; break; - default: avpriv_request_sample(s, "Unknown video codec %X\n", dhav->video_codec); + default: avpriv_request_sample(s, "Unknown video codec %X", dhav->video_codec); } st->duration = dhav->duration; st->codecpar->width = dhav->width; @@ -394,7 +385,7 @@ retry: case 0x1f: st->codecpar->codec_id = AV_CODEC_ID_MP2; break; case 0x21: st->codecpar->codec_id = AV_CODEC_ID_MP3; break; case 0x0d: st->codecpar->codec_id = AV_CODEC_ID_ADPCM_MS; break; - default: avpriv_request_sample(s, "Unknown audio codec %X\n", dhav->audio_codec); + default: avpriv_request_sample(s, "Unknown audio codec %X", dhav->audio_codec); } st->duration = dhav->duration; st->codecpar->channels = dhav->audio_channels; diff --git a/libavformat/dss.c b/libavformat/dss.c index 058504913..468de3fe8 100644 --- a/libavformat/dss.c +++ b/libavformat/dss.c @@ -219,7 +219,6 @@ static int dss_sp_read_packet(AVFormatContext *s, AVPacket *pkt) } else read_size = DSS_FRAME_SIZE; - ctx->counter -= read_size; ctx->packet_size = DSS_FRAME_SIZE - 1; ret = av_new_packet(pkt, DSS_FRAME_SIZE); @@ -231,17 +230,16 @@ static int dss_sp_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->stream_index = 0; s->bit_rate = 8LL * ctx->packet_size * st->codecpar->sample_rate * 512 / (506 * pkt->duration); - if (ctx->counter < 0) { - int size2 = ctx->counter + read_size; - - ret = avio_read(s->pb, ctx->dss_sp_buf + offset + buff_offset, - size2 - offset); - if (ret < size2 - offset) + if (ctx->counter < read_size) { + ret = avio_read(s->pb, ctx->dss_sp_buf + buff_offset, + ctx->counter); + if (ret < ctx->counter) goto error_eof; + offset = ctx->counter; dss_skip_audio_header(s, pkt); - offset = size2; } + ctx->counter -= read_size; ret = avio_read(s->pb, ctx->dss_sp_buf + offset + buff_offset, read_size - offset); @@ -278,7 +276,7 @@ static int dss_723_1_read_packet(AVFormatContext *s, AVPacket *pkt) size = frame_size[byte & 3]; ctx->packet_size = size; - ctx->counter -= size; + ctx->counter--; ret = av_new_packet(pkt, size); if (ret < 0) @@ -288,27 +286,26 @@ static int dss_723_1_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->data[0] = byte; offset = 1; pkt->duration = 240; - s->bit_rate = 8LL * size * st->codecpar->sample_rate * 512 / (506 * pkt->duration); + s->bit_rate = 8LL * size-- * st->codecpar->sample_rate * 512 / (506 * pkt->duration); pkt->stream_index = 0; - if (ctx->counter < 0) { - int size2 = ctx->counter + size; - + if (ctx->counter < size) { ret = avio_read(s->pb, pkt->data + offset, - size2 - offset); - if (ret < size2 - offset) { + ctx->counter); + if (ret < ctx->counter) return ret < 0 ? ret : AVERROR_EOF; - } + offset += ctx->counter; + size -= ctx->counter; + ctx->counter = 0; dss_skip_audio_header(s, pkt); - offset = size2; } + ctx->counter -= size; - ret = avio_read(s->pb, pkt->data + offset, size - offset); - if (ret < size - offset) { + ret = avio_read(s->pb, pkt->data + offset, size); + if (ret < size) return ret < 0 ? ret : AVERROR_EOF; - } return pkt->size; } diff --git a/libavformat/dump.c b/libavformat/dump.c index 06bafc272..62ef5e985 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -34,6 +34,7 @@ #include "libavutil/replaygain.h" #include "libavutil/spherical.h" #include "libavutil/stereo3d.h" +#include "libavutil/timecode.h" #include "avformat.h" @@ -131,10 +132,10 @@ static void print_fps(double d, const char *postfix) av_log(NULL, AV_LOG_INFO, "%1.0fk %s", d / 1000, postfix); } -static void dump_metadata(void *ctx, AVDictionary *m, const char *indent) +static void dump_metadata(void *ctx, const AVDictionary *m, const char *indent) { if (m && !(av_dict_count(m) == 1 && av_dict_get(m, "language", NULL, 0))) { - AVDictionaryEntry *tag = NULL; + const AVDictionaryEntry *tag = NULL; av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent); while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) @@ -158,7 +159,7 @@ static void dump_metadata(void *ctx, AVDictionary *m, const char *indent) } /* param change side data*/ -static void dump_paramchange(void *ctx, AVPacketSideData *sd) +static void dump_paramchange(void *ctx, const AVPacketSideData *sd) { int size = sd->size; const uint8_t *data = sd->data; @@ -211,7 +212,7 @@ static void dump_paramchange(void *ctx, AVPacketSideData *sd) return; fail: - av_log(ctx, AV_LOG_ERROR, "unknown param"); + av_log(ctx, AV_LOG_ERROR, "unknown param\n"); } /* replaygain side data*/ @@ -235,15 +236,15 @@ static void print_peak(void *ctx, const char *str, uint32_t peak) av_log(ctx, AV_LOG_INFO, ", "); } -static void dump_replaygain(void *ctx, AVPacketSideData *sd) +static void dump_replaygain(void *ctx, const AVPacketSideData *sd) { - AVReplayGain *rg; + const AVReplayGain *rg; if (sd->size < sizeof(*rg)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } - rg = (AVReplayGain*)sd->data; + rg = (const AVReplayGain *)sd->data; print_gain(ctx, "track gain", rg->track_gain); print_peak(ctx, "track peak", rg->track_peak); @@ -251,16 +252,16 @@ static void dump_replaygain(void *ctx, AVPacketSideData *sd) print_peak(ctx, "album peak", rg->album_peak); } -static void dump_stereo3d(void *ctx, AVPacketSideData *sd) +static void dump_stereo3d(void *ctx, const AVPacketSideData *sd) { - AVStereo3D *stereo; + const AVStereo3D *stereo; if (sd->size < sizeof(*stereo)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } - stereo = (AVStereo3D *)sd->data; + stereo = (const AVStereo3D *)sd->data; av_log(ctx, AV_LOG_INFO, "%s", av_stereo3d_type_name(stereo->type)); @@ -268,12 +269,12 @@ static void dump_stereo3d(void *ctx, AVPacketSideData *sd) av_log(ctx, AV_LOG_INFO, " (inverted)"); } -static void dump_audioservicetype(void *ctx, AVPacketSideData *sd) +static void dump_audioservicetype(void *ctx, const AVPacketSideData *sd) { - enum AVAudioServiceType *ast = (enum AVAudioServiceType *)sd->data; + const enum AVAudioServiceType *ast = (const enum AVAudioServiceType *)sd->data; if (sd->size < sizeof(*ast)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -311,12 +312,12 @@ static void dump_audioservicetype(void *ctx, AVPacketSideData *sd) } } -static void dump_cpb(void *ctx, AVPacketSideData *sd) +static void dump_cpb(void *ctx, const AVPacketSideData *sd) { - AVCPBProperties *cpb = (AVCPBProperties *)sd->data; + const AVCPBProperties *cpb = (const AVCPBProperties *)sd->data; if (sd->size < sizeof(*cpb)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -334,8 +335,10 @@ static void dump_cpb(void *ctx, AVPacketSideData *sd) av_log(ctx, AV_LOG_INFO, "vbv_delay: %"PRIu64"", cpb->vbv_delay); } -static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) { - AVMasteringDisplayMetadata* metadata = (AVMasteringDisplayMetadata*)sd->data; +static void dump_mastering_display_metadata(void *ctx, const AVPacketSideData *sd) +{ + const AVMasteringDisplayMetadata *metadata = + (const AVMasteringDisplayMetadata *)sd->data; av_log(ctx, AV_LOG_INFO, "Mastering Display Metadata, " "has_primaries:%d has_luminance:%d " "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) " @@ -351,21 +354,23 @@ static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) { av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); } -static void dump_content_light_metadata(void *ctx, AVPacketSideData* sd) +static void dump_content_light_metadata(void *ctx, const AVPacketSideData *sd) { - AVContentLightMetadata* metadata = (AVContentLightMetadata*)sd->data; + const AVContentLightMetadata *metadata = + (const AVContentLightMetadata *)sd->data; av_log(ctx, AV_LOG_INFO, "Content Light Level Metadata, " "MaxCLL=%d, MaxFALL=%d", metadata->MaxCLL, metadata->MaxFALL); } -static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData *sd) +static void dump_spherical(void *ctx, const AVCodecParameters *par, + const AVPacketSideData *sd) { - AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; + const AVSphericalMapping *spherical = (const AVSphericalMapping *)sd->data; double yaw, pitch, roll; if (sd->size < sizeof(*spherical)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -388,9 +393,10 @@ static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData * } } -static void dump_dovi_conf(void *ctx, AVPacketSideData* sd) +static void dump_dovi_conf(void *ctx, const AVPacketSideData *sd) { - AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data; + const AVDOVIDecoderConfigurationRecord *dovi = + (const AVDOVIDecoderConfigurationRecord *)sd->data; av_log(ctx, AV_LOG_INFO, "version: %d.%d, profile: %d, level: %d, " "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d", @@ -402,7 +408,23 @@ static void dump_dovi_conf(void *ctx, AVPacketSideData* sd) dovi->dv_bl_signal_compatibility_id); } -static void dump_sidedata(void *ctx, AVStream *st, const char *indent) +static void dump_s12m_timecode(void *ctx, const AVStream *st, const AVPacketSideData *sd) +{ + const uint32_t *tc = (const uint32_t *)sd->data; + + if ((sd->size != sizeof(uint32_t) * 4) || (tc[0] > 3)) { + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); + return; + } + + for (int j = 1; j <= tc[0]; j++) { + char tcbuf[AV_TIMECODE_STR_SIZE]; + av_timecode_make_smpte_tc_string2(tcbuf, st->avg_frame_rate, tc[j], 0, 0); + av_log(ctx, AV_LOG_INFO, "timecode - %s%s", tcbuf, j != tc[0] ? ", " : ""); + } +} + +static void dump_sidedata(void *ctx, const AVStream *st, const char *indent) { int i; @@ -410,10 +432,10 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent) av_log(ctx, AV_LOG_INFO, "%sSide data:\n", indent); for (i = 0; i < st->nb_side_data; i++) { - AVPacketSideData sd = st->side_data[i]; + const AVPacketSideData *sd = &st->side_data[i]; av_log(ctx, AV_LOG_INFO, "%s ", indent); - switch (sd.type) { + switch (sd->type) { case AV_PKT_DATA_PALETTE: av_log(ctx, AV_LOG_INFO, "palette"); break; @@ -422,55 +444,59 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent) break; case AV_PKT_DATA_PARAM_CHANGE: av_log(ctx, AV_LOG_INFO, "paramchange: "); - dump_paramchange(ctx, &sd); + dump_paramchange(ctx, sd); break; case AV_PKT_DATA_H263_MB_INFO: av_log(ctx, AV_LOG_INFO, "H.263 macroblock info"); break; case AV_PKT_DATA_REPLAYGAIN: av_log(ctx, AV_LOG_INFO, "replaygain: "); - dump_replaygain(ctx, &sd); + dump_replaygain(ctx, sd); break; case AV_PKT_DATA_DISPLAYMATRIX: av_log(ctx, AV_LOG_INFO, "displaymatrix: rotation of %.2f degrees", - av_display_rotation_get((int32_t *)sd.data)); + av_display_rotation_get((const int32_t *)sd->data)); break; case AV_PKT_DATA_STEREO3D: av_log(ctx, AV_LOG_INFO, "stereo3d: "); - dump_stereo3d(ctx, &sd); + dump_stereo3d(ctx, sd); break; case AV_PKT_DATA_AUDIO_SERVICE_TYPE: av_log(ctx, AV_LOG_INFO, "audio service type: "); - dump_audioservicetype(ctx, &sd); + dump_audioservicetype(ctx, sd); break; case AV_PKT_DATA_QUALITY_STATS: av_log(ctx, AV_LOG_INFO, "quality factor: %"PRId32", pict_type: %c", - AV_RL32(sd.data), av_get_picture_type_char(sd.data[4])); + AV_RL32(sd->data), av_get_picture_type_char(sd->data[4])); break; case AV_PKT_DATA_CPB_PROPERTIES: av_log(ctx, AV_LOG_INFO, "cpb: "); - dump_cpb(ctx, &sd); + dump_cpb(ctx, sd); break; case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: - dump_mastering_display_metadata(ctx, &sd); + dump_mastering_display_metadata(ctx, sd); break; case AV_PKT_DATA_SPHERICAL: av_log(ctx, AV_LOG_INFO, "spherical: "); - dump_spherical(ctx, st->codecpar, &sd); + dump_spherical(ctx, st->codecpar, sd); break; case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: - dump_content_light_metadata(ctx, &sd); + dump_content_light_metadata(ctx, sd); break; case AV_PKT_DATA_ICC_PROFILE: av_log(ctx, AV_LOG_INFO, "ICC Profile"); break; case AV_PKT_DATA_DOVI_CONF: av_log(ctx, AV_LOG_INFO, "DOVI configuration record: "); - dump_dovi_conf(ctx, &sd); + dump_dovi_conf(ctx, sd); + break; + case AV_PKT_DATA_S12M_TIMECODE: + av_log(ctx, AV_LOG_INFO, "SMPTE ST 12-1:2014: "); + dump_s12m_timecode(ctx, st, sd); break; default: av_log(ctx, AV_LOG_INFO, - "unknown side data type %d (%d bytes)", sd.type, sd.size); + "unknown side data type %d (%d bytes)", sd->type, sd->size); break; } @@ -479,14 +505,14 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent) } /* "user interface" functions */ -static void dump_stream_format(AVFormatContext *ic, int i, +static void dump_stream_format(const AVFormatContext *ic, int i, int index, int is_output) { char buf[256]; int flags = (is_output ? ic->oformat->flags : ic->iformat->flags); - AVStream *st = ic->streams[i]; - AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); - char *separator = ic->dump_separator; + const AVStream *st = ic->streams[i]; + const AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); + const char *separator = ic->dump_separator; AVCodecContext *avctx; int ret; @@ -500,6 +526,8 @@ static void dump_stream_format(AVFormatContext *ic, int i, return; } +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS // Fields which are missing from AVCodecParameters need to be taken from the AVCodecContext avctx->properties = st->codec->properties; avctx->codec = st->codec->codec; @@ -507,13 +535,15 @@ static void dump_stream_format(AVFormatContext *ic, int i, avctx->qmax = st->codec->qmax; avctx->coded_width = st->codec->coded_width; avctx->coded_height = st->codec->coded_height; +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (separator) av_opt_set(avctx, "dump_separator", separator, 0); avcodec_string(buf, sizeof(buf), avctx, is_output); avcodec_free_context(&avctx); - av_log(NULL, AV_LOG_INFO, " Stream #%d:%d", index, i); + av_log(NULL, AV_LOG_INFO, " Stream #%d:%d", index, i); /* the pid is an important information, so we display it */ /* XXX: add a generic system */ @@ -541,7 +571,13 @@ static void dump_stream_format(AVFormatContext *ic, int i, int fps = st->avg_frame_rate.den && st->avg_frame_rate.num; int tbr = st->r_frame_rate.den && st->r_frame_rate.num; int tbn = st->time_base.den && st->time_base.num; +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS int tbc = st->codec->time_base.den && st->codec->time_base.num; +FF_ENABLE_DEPRECATION_WARNINGS +#else + int tbc = 0; +#endif if (fps || tbr || tbn || tbc) av_log(NULL, AV_LOG_INFO, "%s", separator); @@ -552,8 +588,12 @@ static void dump_stream_format(AVFormatContext *ic, int i, print_fps(av_q2d(st->r_frame_rate), tbn || tbc ? "tbr, " : "tbr"); if (tbn) print_fps(1 / av_q2d(st->time_base), tbc ? "tbn, " : "tbn"); +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS if (tbc) print_fps(1 / av_q2d(st->codec->time_base), "tbc"); +FF_ENABLE_DEPRECATION_WARNINGS +#endif } if (st->disposition & AV_DISPOSITION_DEFAULT) @@ -646,31 +686,34 @@ void av_dump_format(AVFormatContext *ic, int index, av_log(NULL, AV_LOG_INFO, "\n"); } + if (ic->nb_chapters) + av_log(NULL, AV_LOG_INFO, " Chapters:\n"); for (i = 0; i < ic->nb_chapters; i++) { - AVChapter *ch = ic->chapters[i]; + const AVChapter *ch = ic->chapters[i]; av_log(NULL, AV_LOG_INFO, " Chapter #%d:%d: ", index, i); av_log(NULL, AV_LOG_INFO, "start %f, ", ch->start * av_q2d(ch->time_base)); av_log(NULL, AV_LOG_INFO, "end %f\n", ch->end * av_q2d(ch->time_base)); - dump_metadata(NULL, ch->metadata, " "); + dump_metadata(NULL, ch->metadata, " "); } if (ic->nb_programs) { int j, k, total = 0; for (j = 0; j < ic->nb_programs; j++) { - AVDictionaryEntry *name = av_dict_get(ic->programs[j]->metadata, - "name", NULL, 0); - av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id, + const AVProgram *program = ic->programs[j]; + const AVDictionaryEntry *name = av_dict_get(program->metadata, + "name", NULL, 0); + av_log(NULL, AV_LOG_INFO, " Program %d %s\n", program->id, name ? name->value : ""); - dump_metadata(NULL, ic->programs[j]->metadata, " "); - for (k = 0; k < ic->programs[j]->nb_stream_indexes; k++) { - dump_stream_format(ic, ic->programs[j]->stream_index[k], + dump_metadata(NULL, program->metadata, " "); + for (k = 0; k < program->nb_stream_indexes; k++) { + dump_stream_format(ic, program->stream_index[k], index, is_output); - printed[ic->programs[j]->stream_index[k]] = 1; + printed[program->stream_index[k]] = 1; } - total += ic->programs[j]->nb_stream_indexes; + total += program->nb_stream_indexes; } if (total < ic->nb_streams) av_log(NULL, AV_LOG_INFO, " No Program\n"); diff --git a/libavformat/dv.c b/libavformat/dv.c index e99422d4b..26a78139f 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -49,7 +49,6 @@ struct DVDemuxContext { uint8_t audio_buf[4][8192]; int ach; int frames; - uint64_t abytes; }; static inline uint16_t dv_audio_12to16(uint16_t sample) @@ -258,7 +257,7 @@ static int dv_extract_audio_info(DVDemuxContext *c, const uint8_t *frame) c->ast[i] = avformat_new_stream(c->fctx, NULL); if (!c->ast[i]) break; - avpriv_set_pts_info(c->ast[i], 64, 1, 30000); + avpriv_set_pts_info(c->ast[i], 64, c->sys->time_base.num, c->sys->time_base.den); c->ast[i]->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; c->ast[i]->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; @@ -315,12 +314,27 @@ static int dv_extract_timecode(DVDemuxContext* c, const uint8_t* frame, char *tc tc_pack = dv_extract_pack(frame, dv_timecode); if (!tc_pack) return 0; - av_timecode_make_smpte_tc_string(tc, AV_RB32(tc_pack + 1), prevent_df); + av_timecode_make_smpte_tc_string2(tc, av_inv_q(c->sys->time_base), AV_RB32(tc_pack + 1), prevent_df, 1); return 1; } /* The following 3 functions constitute our interface to the world */ +static int dv_init_demux(AVFormatContext *s, DVDemuxContext *c) +{ + c->vst = avformat_new_stream(s, NULL); + if (!c->vst) + return AVERROR(ENOMEM); + + c->fctx = s; + c->vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + c->vst->codecpar->codec_id = AV_CODEC_ID_DVVIDEO; + c->vst->codecpar->bit_rate = 25000000; + c->vst->start_time = 0; + + return 0; +} + DVDemuxContext *avpriv_dv_init_demux(AVFormatContext *s) { DVDemuxContext *c; @@ -329,18 +343,11 @@ DVDemuxContext *avpriv_dv_init_demux(AVFormatContext *s) if (!c) return NULL; - c->vst = avformat_new_stream(s, NULL); - if (!c->vst) { + if (dv_init_demux(s, c)) { av_free(c); return NULL; } - c->fctx = s; - c->vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; - c->vst->codecpar->codec_id = AV_CODEC_ID_DVVIDEO; - c->vst->codecpar->bit_rate = 25000000; - c->vst->start_time = 0; - return c; } @@ -379,8 +386,7 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, for (i = 0; i < c->ach; i++) { c->audio_pkt[i].pos = pos; c->audio_pkt[i].size = size; - c->audio_pkt[i].pts = c->abytes * 30000 * 8 / - c->ast[i]->codecpar->bit_rate; + c->audio_pkt[i].pts = (c->sys->height == 720) ? (c->frames & ~1) : c->frames; ppcm[i] = c->audio_buf[i]; } if (c->ach) @@ -393,10 +399,7 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, c->audio_pkt[2].size = c->audio_pkt[3].size = 0; } else { c->audio_pkt[0].size = c->audio_pkt[1].size = 0; - c->abytes += size; } - } else { - c->abytes += size; } /* Now it's time to return video packet */ @@ -436,13 +439,6 @@ static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c, void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset) { c->frames = frame_offset; - if (c->ach) { - if (c->sys) { - c->abytes = av_rescale_q(c->frames, c->sys->time_base, - (AVRational) { 8, c->ast[0]->codecpar->bit_rate }); - } else - av_log(c->fctx, AV_LOG_ERROR, "cannot adjust audio bytes\n"); - } c->audio_pkt[0].size = c->audio_pkt[1].size = 0; c->audio_pkt[2].size = c->audio_pkt[3].size = 0; } @@ -452,7 +448,7 @@ void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset) ************************************************************/ typedef struct RawDVContext { - DVDemuxContext *dv_demux; + DVDemuxContext dv_demux; uint8_t buf[DV_MAX_FRAME_SIZE]; } RawDVContext; @@ -462,31 +458,26 @@ static int dv_read_timecode(AVFormatContext *s) { int64_t pos = avio_tell(s->pb); // Read 3 DIF blocks: Header block and 2 Subcode blocks. - int partial_frame_size = 3 * 80; - uint8_t *partial_frame = av_mallocz(sizeof(*partial_frame) * - partial_frame_size); - +#define PARTIAL_FRAME_SIZE (3 * 80) + uint8_t partial_frame[PARTIAL_FRAME_SIZE]; RawDVContext *c = s->priv_data; - if (!partial_frame) - return AVERROR(ENOMEM); - ret = avio_read(s->pb, partial_frame, partial_frame_size); + ret = avio_read(s->pb, partial_frame, PARTIAL_FRAME_SIZE); if (ret < 0) goto finish; - if (ret < partial_frame_size) { + if (ret < PARTIAL_FRAME_SIZE) { ret = -1; goto finish; } - ret = dv_extract_timecode(c->dv_demux, partial_frame, timecode); + ret = dv_extract_timecode(&c->dv_demux, partial_frame, timecode); if (ret) av_dict_set(&s->metadata, "timecode", timecode, 0); else av_log(s, AV_LOG_ERROR, "Detected timecode is invalid\n"); finish: - av_free(partial_frame); avio_seek(s->pb, pos, SEEK_SET); return ret; } @@ -497,16 +488,14 @@ static int dv_read_header(AVFormatContext *s) RawDVContext *c = s->priv_data; int ret; - c->dv_demux = avpriv_dv_init_demux(s); - if (!c->dv_demux) - return AVERROR(ENOMEM); + if ((ret = dv_init_demux(s, &c->dv_demux)) < 0) + return ret; state = avio_rb32(s->pb); while ((state & 0xffffff7f) != 0x1f07003f) { if (avio_feof(s->pb)) { av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n"); - ret = AVERROR_INVALIDDATA; - goto fail; + return AVERROR_INVALIDDATA; } if (state == 0x003f0700 || state == 0xff3f0700) marker_pos = avio_tell(s->pb); @@ -521,33 +510,26 @@ static int dv_read_header(AVFormatContext *s) if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) != DV_PROFILE_BYTES - 4 || avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0) { - ret = AVERROR(EIO); - goto fail; + return AVERROR(EIO); } - c->dv_demux->sys = av_dv_frame_profile(c->dv_demux->sys, + c->dv_demux.sys = av_dv_frame_profile(c->dv_demux.sys, c->buf, DV_PROFILE_BYTES); - if (!c->dv_demux->sys) { + if (!c->dv_demux.sys) { av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n"); - ret = AVERROR_INVALIDDATA; - goto fail; + return AVERROR_INVALIDDATA; } - s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, + s->bit_rate = av_rescale_q(c->dv_demux.sys->frame_size, (AVRational) { 8, 1 }, - c->dv_demux->sys->time_base); + c->dv_demux.sys->time_base); if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) dv_read_timecode(s); return 0; - -fail: - av_freep(&c->dv_demux); - - return ret; } static int dv_read_packet(AVFormatContext *s, AVPacket *pkt) @@ -555,14 +537,14 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt) int size; RawDVContext *c = s->priv_data; - size = avpriv_dv_get_packet(c->dv_demux, pkt); + size = avpriv_dv_get_packet(&c->dv_demux, pkt); if (size < 0) { int ret; int64_t pos = avio_tell(s->pb); - if (!c->dv_demux->sys) + if (!c->dv_demux.sys) return AVERROR(EIO); - size = c->dv_demux->sys->frame_size; + size = c->dv_demux.sys->frame_size; ret = avio_read(s->pb, c->buf, size); if (ret < 0) { return ret; @@ -570,7 +552,7 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EIO); } - size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos); + size = avpriv_dv_produce_packet(&c->dv_demux, pkt, c->buf, size, pos); } return size; @@ -580,7 +562,7 @@ static int dv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { RawDVContext *r = s->priv_data; - DVDemuxContext *c = r->dv_demux; + DVDemuxContext *c = &r->dv_demux; int64_t offset = dv_frame_offset(s, c, timestamp, flags); if (avio_seek(s->pb, offset, SEEK_SET) < 0) @@ -590,13 +572,6 @@ static int dv_read_seek(AVFormatContext *s, int stream_index, return 0; } -static int dv_read_close(AVFormatContext *s) -{ - RawDVContext *c = s->priv_data; - av_freep(&c->dv_demux); - return 0; -} - static int dv_probe(const AVProbeData *p) { unsigned marker_pos = 0; @@ -646,7 +621,6 @@ AVInputFormat ff_dv_demuxer = { .read_probe = dv_probe, .read_header = dv_read_header, .read_packet = dv_read_packet, - .read_close = dv_read_close, .read_seek = dv_read_seek, .extensions = "dv,dif", }; diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c index c71e53277..320f8479f 100644 --- a/libavformat/dvenc.c +++ b/libavformat/dvenc.c @@ -29,6 +29,7 @@ */ #include +#include "libavutil/time_internal.h" #include "avformat.h" #include "internal.h" #include "libavcodec/dv_profile.h" @@ -72,6 +73,14 @@ static const int dv_aaux_packs_dist[12][9] = { { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, }; +static void brktimegm(time_t secs, struct tm *tm) +{ + tm = gmtime_r(&secs, tm); + + tm->tm_year += 1900; /* unlike gmtime_r we store complete year here */ + tm->tm_mon += 1; /* unlike gmtime_r tm_mon is from 1 to 12 */ +} + static int dv_audio_frame_size(const AVDVProfile* sys, int frame, int sample_rate) { if ((sys->time_base.den == 25 || sys->time_base.den == 50) && sys->time_base.num == 1) { @@ -143,7 +152,7 @@ static int dv_write_pack(enum dv_pack_type pack_id, DVMuxContext *c, uint8_t* bu case dv_video_recdate: /* VAUX recording date */ ct = c->start_time + av_rescale_rnd(c->frames, c->sys->time_base.num, c->sys->time_base.den, AV_ROUND_DOWN); - ff_brktimegm(ct, &tc); + brktimegm(ct, &tc); buf[1] = 0xff; /* ds, tm, tens of time zone, units of time zone */ /* 0xff is very likely to be "unknown" */ buf[2] = (3 << 6) | /* reserved -- always 1 */ @@ -159,7 +168,7 @@ static int dv_write_pack(enum dv_pack_type pack_id, DVMuxContext *c, uint8_t* bu case dv_video_rectime: /* VAUX recording time */ ct = c->start_time + av_rescale_rnd(c->frames, c->sys->time_base.num, c->sys->time_base.den, AV_ROUND_DOWN); - ff_brktimegm(ct, &tc); + brktimegm(ct, &tc); buf[1] = (3 << 6) | /* reserved -- always 1 */ 0x3f; /* tens of frame, units of frame: 0x3f - "unknown" ? */ buf[2] = (1 << 7) | /* reserved -- always 1 */ @@ -307,34 +316,34 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s) /* We have to sort out where audio and where video stream is */ for (i=0; inb_streams; i++) { - switch (s->streams[i]->codecpar->codec_type) { + AVStream *st = s->streams[i]; + switch (st->codecpar->codec_type) { case AVMEDIA_TYPE_VIDEO: if (vst) return NULL; - vst = s->streams[i]; + if (st->codecpar->codec_id != AV_CODEC_ID_DVVIDEO) + goto bail_out; + vst = st; break; case AVMEDIA_TYPE_AUDIO: if (c->n_ast > 1) return NULL; - c->ast[c->n_ast++] = s->streams[i]; + /* Some checks -- DV format is very picky about its incoming streams */ + if(st->codecpar->codec_id != AV_CODEC_ID_PCM_S16LE || + st->codecpar->channels != 2) + goto bail_out; + if (st->codecpar->sample_rate != 48000 && + st->codecpar->sample_rate != 44100 && + st->codecpar->sample_rate != 32000 ) + goto bail_out; + c->ast[c->n_ast++] = st; break; default: goto bail_out; } } - /* Some checks -- DV format is very picky about its incoming streams */ - if (!vst || vst->codecpar->codec_id != AV_CODEC_ID_DVVIDEO) + if (!vst) goto bail_out; - for (i=0; in_ast; i++) { - if (c->ast[i]) { - if(c->ast[i]->codecpar->codec_id != AV_CODEC_ID_PCM_S16LE || - c->ast[i]->codecpar->channels != 2) - goto bail_out; - if (c->ast[i]->codecpar->sample_rate != 48000 && - c->ast[i]->codecpar->sample_rate != 44100 && - c->ast[i]->codecpar->sample_rate != 32000 ) - goto bail_out; - } - } + c->sys = av_dv_codec_profile2(vst->codecpar->width, vst->codecpar->height, vst->codecpar->format, vst->time_base); if (!c->sys) @@ -406,9 +415,10 @@ static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt) fsize = dv_assemble_frame(s, s->priv_data, s->streams[pkt->stream_index], pkt->data, pkt->size, &frame); - if (fsize > 0) { - avio_write(s->pb, frame, fsize); + if (fsize < 0) { + return fsize; } + avio_write(s->pb, frame, fsize); return 0; } diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index 5ad7e821d..7c0d6a2e3 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -561,14 +561,14 @@ static int ea_read_header(AVFormatContext *s) st->codecpar->bits_per_coded_sample; ea->audio_stream_index = st->index; st->start_time = 0; - return 1; + return 0; } no_audio: ea->audio_codec = AV_CODEC_ID_NONE; if (!ea->video.codec) return AVERROR_INVALIDDATA; - return 1; + return 0; } static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) diff --git a/libavformat/ffmetadec.c b/libavformat/ffmetadec.c index 6a30b58c4..9fcba0849 100644 --- a/libavformat/ffmetadec.c +++ b/libavformat/ffmetadec.c @@ -101,19 +101,22 @@ static AVChapter *read_chapter(AVFormatContext *s) uint8_t line[256]; int64_t start, end; AVRational tb = {1, 1e9}; + int ret; get_line(s->pb, line, sizeof(line)); if (sscanf(line, "TIMEBASE=%d/%d", &tb.num, &tb.den)) get_line(s->pb, line, sizeof(line)); - if (!sscanf(line, "START=%"SCNd64, &start)) { + ret = sscanf(line, "START=%"SCNd64, &start); + if (ret <= 0) { av_log(s, AV_LOG_ERROR, "Expected chapter start timestamp, found %s.\n", line); start = (s->nb_chapters && s->chapters[s->nb_chapters - 1]->end != AV_NOPTS_VALUE) ? s->chapters[s->nb_chapters - 1]->end : 0; } else get_line(s->pb, line, sizeof(line)); - if (!sscanf(line, "END=%"SCNd64, &end)) { + ret = sscanf(line, "END=%"SCNd64, &end); + if (ret <= 0) { av_log(s, AV_LOG_ERROR, "Expected chapter end timestamp, found %s.\n", line); end = AV_NOPTS_VALUE; } diff --git a/libavformat/fifo.c b/libavformat/fifo.c index d11dc6626..17748e94c 100644 --- a/libavformat/fifo.c +++ b/libavformat/fifo.c @@ -19,6 +19,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "libavutil/avassert.h" #include "libavutil/opt.h" #include "libavutil/time.h" @@ -77,6 +79,9 @@ typedef struct FifoContext { /* Value > 0 signals queue overflow */ volatile uint8_t overflow_flag; + atomic_int_least64_t queue_duration; + int64_t last_sent_dts; + int64_t timeshift; } FifoContext; typedef struct FifoThreadContext { @@ -98,9 +103,12 @@ typedef struct FifoThreadContext { * so finalization by calling write_trailer and ff_io_close must be done * before exiting / reinitialization of underlying muxer */ uint8_t header_written; + + int64_t last_received_dts; } FifoThreadContext; typedef enum FifoMessageType { + FIFO_NOOP, FIFO_WRITE_HEADER, FIFO_WRITE_PACKET, FIFO_FLUSH_OUTPUT @@ -159,6 +167,15 @@ static int fifo_thread_flush_output(FifoThreadContext *ctx) return av_write_frame(avf2, NULL); } +static int64_t next_duration(AVFormatContext *avf, AVPacket *pkt, int64_t *last_dts) +{ + AVStream *st = avf->streams[pkt->stream_index]; + int64_t dts = av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q); + int64_t duration = (*last_dts == AV_NOPTS_VALUE ? 0 : dts - *last_dts); + *last_dts = dts; + return duration; +} + static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt) { AVFormatContext *avf = ctx->avf; @@ -167,6 +184,9 @@ static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt) AVRational src_tb, dst_tb; int ret, s_idx; + if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE) + atomic_fetch_sub_explicit(&fifo->queue_duration, next_duration(avf, pkt, &ctx->last_received_dts), memory_order_relaxed); + if (ctx->drop_until_keyframe) { if (pkt->flags & AV_PKT_FLAG_KEY) { ctx->drop_until_keyframe = 0; @@ -209,6 +229,9 @@ static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg { int ret = AVERROR(EINVAL); + if (msg->type == FIFO_NOOP) + return 0; + if (!ctx->header_written) { ret = fifo_thread_write_header(ctx); if (ret < 0) @@ -390,12 +413,13 @@ static void *fifo_consumer_thread(void *data) AVFormatContext *avf = data; FifoContext *fifo = avf->priv_data; AVThreadMessageQueue *queue = fifo->queue; - FifoMessage msg = {FIFO_WRITE_HEADER, {0}}; + FifoMessage msg = {fifo->timeshift ? FIFO_NOOP : FIFO_WRITE_HEADER, {0}}; int ret; FifoThreadContext fifo_thread_ctx; memset(&fifo_thread_ctx, 0, sizeof(FifoThreadContext)); fifo_thread_ctx.avf = avf; + fifo_thread_ctx.last_received_dts = AV_NOPTS_VALUE; while (1) { uint8_t just_flushed = 0; @@ -429,6 +453,10 @@ static void *fifo_consumer_thread(void *data) if (just_flushed) av_log(avf, AV_LOG_INFO, "FIFO queue flushed\n"); + if (fifo->timeshift) + while (atomic_load_explicit(&fifo->queue_duration, memory_order_relaxed) < fifo->timeshift) + av_usleep(10000); + ret = av_thread_message_queue_recv(queue, &msg, 0); if (ret < 0) { av_thread_message_queue_set_err_send(queue, ret); @@ -488,6 +516,8 @@ static int fifo_init(AVFormatContext *avf) " only when drop_pkts_on_overflow is also turned on\n"); return AVERROR(EINVAL); } + atomic_init(&fifo->queue_duration, 0); + fifo->last_sent_dts = AV_NOPTS_VALUE; oformat = av_guess_format(fifo->format, avf->url, NULL); if (!oformat) { @@ -563,6 +593,9 @@ static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt) goto fail; } + if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE) + atomic_fetch_add_explicit(&fifo->queue_duration, next_duration(avf, pkt, &fifo->last_sent_dts), memory_order_relaxed); + return ret; fail: if (pkt) @@ -576,6 +609,27 @@ static int fifo_write_trailer(AVFormatContext *avf) int ret; av_thread_message_queue_set_err_recv(fifo->queue, AVERROR_EOF); + if (fifo->timeshift) { + int64_t now = av_gettime_relative(); + int64_t elapsed = 0; + FifoMessage msg = {FIFO_NOOP}; + do { + int64_t delay = av_gettime_relative() - now; + if (delay < 0) { // Discontinuity? + delay = 10000; + now = av_gettime_relative(); + } else { + now += delay; + } + atomic_fetch_add_explicit(&fifo->queue_duration, delay, memory_order_relaxed); + elapsed += delay; + if (elapsed > fifo->timeshift) + break; + av_usleep(10000); + ret = av_thread_message_queue_send(fifo->queue, &msg, AV_THREAD_MESSAGE_NONBLOCK); + } while (ret >= 0 || ret == AVERROR(EAGAIN)); + atomic_store(&fifo->queue_duration, INT64_MAX); + } ret = pthread_join(fifo->writer_thread, NULL); if (ret < 0) { @@ -630,6 +684,9 @@ static const AVOption options[] = { {"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM}, + {"timeshift", "Delay fifo output", OFFSET(timeshift), + AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM}, + {NULL}, }; diff --git a/libavformat/fitsenc.c b/libavformat/fitsenc.c index cc3999aa8..212c769df 100644 --- a/libavformat/fitsenc.c +++ b/libavformat/fitsenc.c @@ -45,7 +45,8 @@ static int fits_write_header(AVFormatContext *s) * @param lines_written to keep track of lines written so far * @return 0 */ -static int write_keyword_value(AVFormatContext *s, const char *keyword, int value, int *lines_written) +static int write_keyword_value(AVFormatContext *s, const char *fmt, + const char *keyword, void *value, int *lines_written) { int len, ret; uint8_t header[80]; @@ -57,7 +58,12 @@ static int write_keyword_value(AVFormatContext *s, const char *keyword, int valu header[8] = '='; header[9] = ' '; - ret = snprintf(header + 10, 70, "%d", value); + if (!strcmp(fmt, "%d")) { + ret = snprintf(header + 10, 70, fmt, *(int *)value); + } else { + ret = snprintf(header + 10, 70, fmt, *(float *)value); + } + memset(&header[ret + 10], ' ', sizeof(header) - (ret + 10)); avio_write(s->pb, header, sizeof(header)); @@ -72,16 +78,22 @@ static int write_image_header(AVFormatContext *s) FITSContext *fitsctx = s->priv_data; uint8_t buffer[80]; int bitpix, naxis, naxis3 = 1, bzero = 0, rgb = 0, lines_written = 0, lines_left; + int pcount = 0, gcount = 1; + float datamax, datamin; switch (encctx->format) { case AV_PIX_FMT_GRAY8: bitpix = 8; naxis = 2; + datamin = 0; + datamax = 255; break; case AV_PIX_FMT_GRAY16BE: bitpix = 16; naxis = 2; bzero = 32768; + datamin = 0; + datamax = 65535; break; case AV_PIX_FMT_GBRP: case AV_PIX_FMT_GBRAP: @@ -93,6 +105,8 @@ static int write_image_header(AVFormatContext *s) } else { naxis3 = 4; } + datamin = 0; + datamax = 255; break; case AV_PIX_FMT_GBRP16BE: case AV_PIX_FMT_GBRAP16BE: @@ -105,6 +119,8 @@ static int write_image_header(AVFormatContext *s) naxis3 = 4; } bzero = 32768; + datamin = 0; + datamax = 65535; break; default: return AVERROR(EINVAL); @@ -122,28 +138,31 @@ static int write_image_header(AVFormatContext *s) } lines_written++; - write_keyword_value(s, "BITPIX", bitpix, &lines_written); // no of bits per pixel - write_keyword_value(s, "NAXIS", naxis, &lines_written); // no of dimensions of image - write_keyword_value(s, "NAXIS1", encctx->width, &lines_written); // first dimension i.e. width - write_keyword_value(s, "NAXIS2", encctx->height, &lines_written); // second dimension i.e. height + write_keyword_value(s, "%d", "BITPIX", &bitpix, &lines_written); // no of bits per pixel + write_keyword_value(s, "%d", "NAXIS", &naxis, &lines_written); // no of dimensions of image + write_keyword_value(s, "%d", "NAXIS1", &encctx->width, &lines_written); // first dimension i.e. width + write_keyword_value(s, "%d", "NAXIS2", &encctx->height, &lines_written); // second dimension i.e. height if (rgb) - write_keyword_value(s, "NAXIS3", naxis3, &lines_written); // third dimension to store RGBA planes + write_keyword_value(s, "%d", "NAXIS3", &naxis3, &lines_written); // third dimension to store RGBA planes if (!fitsctx->first_image) { - write_keyword_value(s, "PCOUNT", 0, &lines_written); - write_keyword_value(s, "GCOUNT", 1, &lines_written); + write_keyword_value(s, "%d", "PCOUNT", &pcount, &lines_written); + write_keyword_value(s, "%d", "GCOUNT", &gcount, &lines_written); } else { fitsctx->first_image = 0; } + write_keyword_value(s, "%g", "DATAMIN", &datamin, &lines_written); + write_keyword_value(s, "%g", "DATAMAX", &datamax, &lines_written); + /* * Since FITS does not support unsigned 16 bit integers, * BZERO = 32768 is used to store unsigned 16 bit integers as * signed integers so that it can be read properly. */ if (bitpix == 16) - write_keyword_value(s, "BZERO", bzero, &lines_written); + write_keyword_value(s, "%d", "BZERO", &bzero, &lines_written); if (rgb) { memcpy(buffer, "CTYPE3 = 'RGB '", 20); diff --git a/libavformat/flac_picture.c b/libavformat/flac_picture.c index 53e24b28b..f15cfa877 100644 --- a/libavformat/flac_picture.c +++ b/libavformat/flac_picture.c @@ -165,7 +165,7 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size, int tr RETURN_ERROR(AVERROR(ENOMEM)); } - av_init_packet(&st->attached_pic); + av_packet_unref(&st->attached_pic); st->attached_pic.buf = data; st->attached_pic.data = data->data; st->attached_pic.size = len; diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 79c05f14b..1463e1caa 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -259,7 +259,7 @@ static int flac_probe(const AVProbeData *p) static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit) { - AVPacket pkt; + AVPacket *pkt = s->internal->parse_pkt; AVStream *st = s->streams[stream_index]; AVCodecParserContext *parser; int ret; @@ -268,7 +268,6 @@ static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_inde if (avio_seek(s->pb, *ppos, SEEK_SET) < 0) return AV_NOPTS_VALUE; - av_init_packet(&pkt); parser = av_parser_init(st->codecpar->codec_id); if (!parser){ return AV_NOPTS_VALUE; @@ -279,20 +278,20 @@ static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_inde uint8_t *data; int size; - ret = ff_raw_read_partial_packet(s, &pkt); + ret = ff_raw_read_partial_packet(s, pkt); if (ret < 0){ if (ret == AVERROR(EAGAIN)) continue; else { - av_packet_unref(&pkt); - av_assert1(!pkt.size); + av_packet_unref(pkt); + av_assert1(!pkt->size); } } av_parser_parse2(parser, st->internal->avctx, - &data, &size, pkt.data, pkt.size, - pkt.pts, pkt.dts, *ppos); + &data, &size, pkt->data, pkt->size, + pkt->pts, pkt->dts, *ppos); - av_packet_unref(&pkt); + av_packet_unref(pkt); if (size) { if (parser->pts != AV_NOPTS_VALUE){ // seeking may not have started from beginning of a frame diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c index b947a3b06..57f5c012f 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -23,6 +23,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavcodec/flac.h" +#include "libavcodec/packet_internal.h" #include "avformat.h" #include "avio_internal.h" #include "flacenc.h" @@ -38,7 +39,7 @@ typedef struct FlacMuxerContext { int audio_stream_idx; int waiting_pics; /* audio packets are queued here until we get all the attached pictures */ - AVPacketList *queue, *queue_end; + PacketList *queue, *queue_end; /* updated streaminfo sent by the encoder at the end */ uint8_t streaminfo[FLAC_STREAMINFO_SIZE]; @@ -279,7 +280,7 @@ static int flac_write_audio_packet(struct AVFormatContext *s, AVPacket *pkt) { FlacMuxerContext *c = s->priv_data; uint8_t *streaminfo; - int streaminfo_size; + buffer_size_t streaminfo_size; /* check for updated streaminfo */ streaminfo = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, @@ -305,7 +306,7 @@ static int flac_queue_flush(AVFormatContext *s) write = 0; while (c->queue) { - ff_packet_list_get(&c->queue, &c->queue_end, &pkt); + avpriv_packet_list_get(&c->queue, &c->queue_end, &pkt); if (write && (ret = flac_write_audio_packet(s, &pkt)) < 0) write = 0; av_packet_unref(&pkt); @@ -345,7 +346,9 @@ static void flac_deinit(struct AVFormatContext *s) { FlacMuxerContext *c = s->priv_data; - ff_packet_list_free(&c->queue, &c->queue_end); + avpriv_packet_list_free(&c->queue, &c->queue_end); + for (unsigned i = 0; i < s->nb_streams; i++) + av_packet_free((AVPacket **)&s->streams[i]->priv_data); } static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt) @@ -356,7 +359,7 @@ static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt) if (pkt->stream_index == c->audio_stream_idx) { if (c->waiting_pics) { /* buffer audio packets until we get all the pictures */ - ret = ff_packet_list_put(&c->queue, &c->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET); + ret = avpriv_packet_list_put(&c->queue, &c->queue_end, pkt, av_packet_ref, 0); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Out of memory in packet queue; skipping attached pictures\n"); c->waiting_pics = 0; diff --git a/libavformat/flic.c b/libavformat/flic.c index e65c15777..4552bff69 100644 --- a/libavformat/flic.c +++ b/libavformat/flic.c @@ -202,6 +202,7 @@ static int flic_read_packet(AVFormatContext *s, int magic; int ret = 0; unsigned char preamble[FLIC_PREAMBLE_SIZE]; + int64_t pos = avio_tell(pb); while (!packet_read && !avio_feof(pb)) { @@ -219,15 +220,19 @@ static int flic_read_packet(AVFormatContext *s, return ret; pkt->stream_index = flic->video_stream_index; - pkt->pts = flic->frame_number++; - pkt->pos = avio_tell(pb); + pkt->pos = pos; memcpy(pkt->data, preamble, FLIC_PREAMBLE_SIZE); ret = avio_read(pb, pkt->data + FLIC_PREAMBLE_SIZE, size - FLIC_PREAMBLE_SIZE); if (ret != size - FLIC_PREAMBLE_SIZE) { ret = AVERROR(EIO); } + pkt->flags = flic->frame_number == 0 ? AV_PKT_FLAG_KEY : 0; + pkt->pts = flic->frame_number; + if (flic->frame_number == 0) + av_add_index_entry(s->streams[flic->video_stream_index], pkt->pos, pkt->pts, pkt->size, 0, AVINDEX_KEYFRAME); packet_read = 1; + flic->frame_number++; } else if (magic == FLIC_TFTD_CHUNK_AUDIO) { if ((ret = av_new_packet(pkt, size)) < 0) return ret; @@ -236,7 +241,8 @@ static int flic_read_packet(AVFormatContext *s, avio_skip(pb, 10); pkt->stream_index = flic->audio_stream_index; - pkt->pos = avio_tell(pb); + pkt->pos = pos; + pkt->flags = AV_PKT_FLAG_KEY; ret = avio_read(pb, pkt->data, size); if (ret != size) { @@ -254,6 +260,31 @@ static int flic_read_packet(AVFormatContext *s, return avio_feof(pb) ? AVERROR_EOF : ret; } +static int flic_read_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + FlicDemuxContext *flic = s->priv_data; + AVStream *st = s->streams[stream_index]; + int64_t pos, ts; + int index; + + if (!st->index_entries || stream_index != flic->video_stream_index) + return -1; + + index = av_index_search_timestamp(st, pts, flags); + + if (index < 0) + index = av_index_search_timestamp(st, pts, flags ^ AVSEEK_FLAG_BACKWARD); + if (index < 0) + return -1; + + pos = st->index_entries[index].pos; + ts = st->index_entries[index].timestamp; + flic->frame_number = ts; + avio_seek(s->pb, pos, SEEK_SET); + return 0; +} + AVInputFormat ff_flic_demuxer = { .name = "flic", .long_name = NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation"), @@ -261,4 +292,5 @@ AVInputFormat ff_flic_demuxer = { .read_probe = flic_probe, .read_header = flic_read_header, .read_packet = flic_read_packet, + .read_seek = flic_read_seek, }; diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 334a5f4a7..79c810f96 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -453,9 +453,13 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t m } for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) { + double d; if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER) goto invalid; - current_array[0][i] = av_int2double(avio_rb64(ioc)); + d = av_int2double(avio_rb64(ioc)); + if (isnan(d) || d < INT64_MIN || d > INT64_MAX) + goto invalid; + current_array[0][i] = d; } if (times && filepositions) { // All done, exiting at a position allowing amf_parse_object @@ -526,8 +530,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, if (key && (ioc->seekable & AVIO_SEEKABLE_NORMAL) && !strcmp(KEYFRAMES_TAG, key) && depth == 1) - if (parse_keyframes_index(s, ioc, - max_pos) < 0) + if (parse_keyframes_index(s, ioc, max_pos) < 0) av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n"); else add_keyframes_index(s); @@ -728,7 +731,7 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) if (!strcmp(buffer, "onCaptionInfo")) return TYPE_ONCAPTIONINFO; - if (strcmp(buffer, "onMetaData") && strcmp(buffer, "onCuePoint")) { + if (strcmp(buffer, "onMetaData") && strcmp(buffer, "onCuePoint") && strcmp(buffer, "|RtmpSampleAccess")) { av_log(s, AV_LOG_DEBUG, "Unknown type %s\n", buffer); return TYPE_UNKNOWN; } @@ -744,8 +747,7 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) astream = stream; if (flv->last_keyframe_stream_index == -1) flv->last_keyframe_stream_index = i; - } - else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) + } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) dstream = stream; } @@ -873,6 +875,8 @@ static int amf_skip_tag(AVIOContext *pb, AMFDataType type, int depth) parse_name = 0; case AMF_DATA_TYPE_MIXEDARRAY: nb = avio_rb32(pb); + if (nb < 0) + return AVERROR_INVALIDDATA; case AMF_DATA_TYPE_OBJECT: while(!pb->eof_reached && (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY)) { if (parse_name) { @@ -1076,8 +1080,7 @@ retry: if (type == 0 && dts == 0 || type < 0) { if (type < 0 && flv->validate_count && flv->validate_index[0].pos > next && - flv->validate_index[0].pos - 4 < next - ) { + flv->validate_index[0].pos - 4 < next) { av_log(s, AV_LOG_WARNING, "Adjusting next position due to index mismatch\n"); next = flv->validate_index[0].pos - 4; } @@ -1138,7 +1141,6 @@ skip: st = create_stream(s, stream_types[stream_type]); if (!st) return AVERROR(ENOMEM); - } av_log(s, AV_LOG_TRACE, "%d %X %d \n", stream_type, flags, st->discard); @@ -1151,10 +1153,9 @@ skip: stream_type == FLV_STREAM_TYPE_AUDIO)) av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); - if ( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO))) - ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO))) - || st->discard >= AVDISCARD_ALL - ) { + if ((st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)) || + (st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && stream_type == FLV_STREAM_TYPE_VIDEO)) || + st->discard >= AVDISCARD_ALL) { avio_seek(s->pb, next, SEEK_SET); ret = FFERROR_REDO; goto leave; @@ -1317,10 +1318,10 @@ retry_duration: ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0); } - if ( stream_type == FLV_STREAM_TYPE_AUDIO || - ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) || - stream_type == FLV_STREAM_TYPE_SUBTITLE || - stream_type == FLV_STREAM_TYPE_DATA) + if (stream_type == FLV_STREAM_TYPE_AUDIO || + (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || + stream_type == FLV_STREAM_TYPE_SUBTITLE || + stream_type == FLV_STREAM_TYPE_DATA) pkt->flags |= AV_PKT_FLAG_KEY; leave: diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index 5cf3ce8a1..35bf7ace5 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -902,7 +902,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) { - int side_size = 0; + buffer_size_t side_size; uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) { ret = ff_alloc_extradata(par, side_size); diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c index a567b5299..1fbe4aa4e 100644 --- a/libavformat/framecrcenc.c +++ b/libavformat/framecrcenc.c @@ -21,8 +21,11 @@ #include +#include "config.h" #include "libavutil/adler32.h" #include "libavutil/avstring.h" +#include "libavutil/intreadwrite.h" +#include "libavcodec/avcodec.h" #include "avformat.h" #include "internal.h" @@ -42,6 +45,17 @@ static int framecrc_write_header(struct AVFormatContext *s) return ff_framehash_write_header(s); } +static av_unused void inline bswap(char *buf, int offset, int size) +{ + if (size == 8) { + uint64_t val = AV_RN64(buf + offset); + AV_WN64(buf + offset, av_bswap64(val)); + } else if (size == 4) { + uint32_t val = AV_RN32(buf + offset); + AV_WN32(buf + offset, av_bswap32(val)); + } +} + static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt) { uint32_t crc = av_adler32_update(0, pkt->data, pkt->size); @@ -52,21 +66,58 @@ static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt) if (pkt->flags != AV_PKT_FLAG_KEY) av_strlcatf(buf, sizeof(buf), ", F=0x%0X", pkt->flags); if (pkt->side_data_elems) { - int i, j; + int i; av_strlcatf(buf, sizeof(buf), ", S=%d", pkt->side_data_elems); for (i=0; iside_data_elems; i++) { + const AVPacketSideData *const sd = &pkt->side_data[i]; + const uint8_t *data = sd->data; uint32_t side_data_crc = 0; - if (HAVE_BIGENDIAN && AV_PKT_DATA_PALETTE == pkt->side_data[i].type) { - for (j=0; jside_data[i].size; j++) { - side_data_crc = av_adler32_update(side_data_crc, - pkt->side_data[i].data + (j^3), - 1); + + switch (sd->type) { +#if HAVE_BIGENDIAN + uint8_t bswap_buf[FFMAX(sizeof(AVCPBProperties), + sizeof(AVProducerReferenceTime))]; + case AV_PKT_DATA_PALETTE: + case AV_PKT_DATA_REPLAYGAIN: + case AV_PKT_DATA_DISPLAYMATRIX: + case AV_PKT_DATA_STEREO3D: + case AV_PKT_DATA_AUDIO_SERVICE_TYPE: + case AV_PKT_DATA_FALLBACK_TRACK: + case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: + case AV_PKT_DATA_SPHERICAL: + case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: + case AV_PKT_DATA_S12M_TIMECODE: + for (int j = 0; j < sd->size / 4; j++) { + uint8_t buf[4]; + AV_WL32(buf, AV_RB32(sd->data + 4 * j)); + side_data_crc = av_adler32_update(side_data_crc, buf, 4); } - } else { - side_data_crc = av_adler32_update(0, - pkt->side_data[i].data, - pkt->side_data[i].size); + break; + case AV_PKT_DATA_CPB_PROPERTIES: +#define BSWAP(struct, field) bswap(bswap_buf, offsetof(struct, field), sizeof(((struct){0}).field)) + if (sd->size == sizeof(AVCPBProperties)) { + memcpy(bswap_buf, sd->data, sizeof(AVCPBProperties)); + data = bswap_buf; + BSWAP(AVCPBProperties, max_bitrate); + BSWAP(AVCPBProperties, min_bitrate); + BSWAP(AVCPBProperties, avg_bitrate); + BSWAP(AVCPBProperties, buffer_size); + BSWAP(AVCPBProperties, vbv_delay); + } + goto pod; + case AV_PKT_DATA_PRFT: + if (sd->size == sizeof(AVProducerReferenceTime)) { + memcpy(bswap_buf, sd->data, sizeof(AVProducerReferenceTime)); + data = bswap_buf; + BSWAP(AVProducerReferenceTime, wallclock); + BSWAP(AVProducerReferenceTime, flags); + } + goto pod; + pod: +#endif + default: + side_data_crc = av_adler32_update(0, data, sd->size); } av_strlcatf(buf, sizeof(buf), ", %8d, 0x%08"PRIx32, pkt->side_data[i].size, side_data_crc); } diff --git a/libavformat/frmdec.c b/libavformat/frmdec.c index 9a962f37f..1bc3a83e1 100644 --- a/libavformat/frmdec.c +++ b/libavformat/frmdec.c @@ -29,13 +29,12 @@ #include "libavutil/intreadwrite.h" #include "avformat.h" -static const PixelFormatTag frm_pix_fmt_tags[] = { - { AV_PIX_FMT_RGB555, 1 }, - { AV_PIX_FMT_RGB0, 2 }, - { AV_PIX_FMT_RGB24, 3 }, - { AV_PIX_FMT_BGR0, 4 }, - { AV_PIX_FMT_BGRA, 5 }, - { AV_PIX_FMT_NONE, 0 }, +static const enum AVPixelFormat frm_pix_fmt_tags[] = { + AV_PIX_FMT_RGB555, + AV_PIX_FMT_RGB0, + AV_PIX_FMT_RGB24, + AV_PIX_FMT_BGR0, + AV_PIX_FMT_BGRA, }; typedef struct { @@ -55,6 +54,8 @@ static int frm_read_header(AVFormatContext *avctx) { AVIOContext *pb = avctx->pb; AVStream *st = avformat_new_stream(avctx, 0); + unsigned idx; + if (!st) return AVERROR(ENOMEM); @@ -62,9 +63,10 @@ static int frm_read_header(AVFormatContext *avctx) st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; avio_skip(pb, 3); - st->codecpar->format = avpriv_find_pix_fmt(frm_pix_fmt_tags, avio_r8(pb)); - if (!st->codecpar->format) + idx = avio_r8(pb) - 1; + if (idx >= FF_ARRAY_ELEMS(frm_pix_fmt_tags)) return AVERROR_INVALIDDATA; + st->codecpar->format = frm_pix_fmt_tags[idx]; st->codecpar->codec_tag = 0; st->codecpar->width = avio_rl16(pb); diff --git a/libavformat/gifdec.c b/libavformat/gifdec.c index a31644c2a..d617de5f4 100644 --- a/libavformat/gifdec.c +++ b/libavformat/gifdec.c @@ -144,7 +144,7 @@ static int gif_read_header(AVFormatContext *s) AVBPrint bp; int block_size; - av_bprint_init(&bp, 0, -1); + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); while ((block_size = avio_r8(pb)) != 0) { avio_read_to_bprint(pb, &bp, block_size); } diff --git a/libavformat/gopher.c b/libavformat/gopher.c index 8b6d14a1f..9bbe17164 100644 --- a/libavformat/gopher.c +++ b/libavformat/gopher.c @@ -2,6 +2,7 @@ * Gopher protocol * * Copyright (c) 2009 Toshimitsu Kimura + * Copyright (c) 2021 parazyd * * based on libavformat/http.c, Copyright (c) 2000, 2001 Fabrice Bellard * @@ -22,6 +23,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #include "libavutil/avstring.h" #include "avformat.h" #include "internal.h" @@ -75,19 +78,23 @@ static int gopher_close(URLContext *h) static int gopher_open(URLContext *h, const char *uri, int flags) { GopherContext *s = h->priv_data; - char hostname[1024], auth[1024], path[1024], buf[1024]; + char proto[10], hostname[1024], auth[1024], path[1024], buf[1024]; int port, err; + const char *lower_proto = "tcp"; h->is_streamed = 1; /* needed in any case to build the host string */ - av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, - path, sizeof(path), uri); + av_url_split(proto, sizeof(proto), auth, sizeof(auth), + hostname, sizeof(hostname), &port, path, sizeof(path), uri); if (port < 0) port = 70; - ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); + if (!strcmp(proto, "gophers")) + lower_proto = "tls"; + + ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL); s->hd = NULL; err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, @@ -110,13 +117,28 @@ static int gopher_read(URLContext *h, uint8_t *buf, int size) return len; } - +#if CONFIG_GOPHER_PROTOCOL const URLProtocol ff_gopher_protocol = { - .name = "gopher", - .url_open = gopher_open, - .url_read = gopher_read, - .url_write = gopher_write, - .url_close = gopher_close, - .priv_data_size = sizeof(GopherContext), - .flags = URL_PROTOCOL_FLAG_NETWORK, + .name = "gopher", + .url_open = gopher_open, + .url_read = gopher_read, + .url_write = gopher_write, + .url_close = gopher_close, + .priv_data_size = sizeof(GopherContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, + .default_whitelist = "gopher,tcp" }; +#endif /* CONFIG_GOPHER_PROTOCOL */ + +#if CONFIG_GOPHERS_PROTOCOL +const URLProtocol ff_gophers_protocol = { + .name = "gophers", + .url_open = gopher_open, + .url_read = gopher_read, + .url_write = gopher_write, + .url_close = gopher_close, + .priv_data_size = sizeof(GopherContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, + .default_whitelist = "gopher,gophers,tcp,tls" +}; +#endif /* CONFIG_GOPHERS_PROTOCOL */ diff --git a/libavformat/hashenc.c b/libavformat/hashenc.c index ce609f6ef..1e9faf372 100644 --- a/libavformat/hashenc.c +++ b/libavformat/hashenc.c @@ -42,8 +42,8 @@ struct HashContext { #define FORMAT_VERSION_OPT \ { "format_version", "file format version", OFFSET(format_version), AV_OPT_TYPE_INT, {.i64 = 2}, 1, 2, ENC } -#if CONFIG_HASH_MUXER -static const AVOption hash_options[] = { +#if CONFIG_HASH_MUXER || CONFIG_STREAMHASH_MUXER +static const AVOption hash_streamhash_options[] = { HASH_OPT("sha256"), { NULL }, }; @@ -57,13 +57,6 @@ static const AVOption framehash_options[] = { }; #endif -#if CONFIG_STREAMHASH_MUXER -static const AVOption streamhash_options[] = { - HASH_OPT("sha256"), - { NULL }, -}; -#endif - #if CONFIG_MD5_MUXER static const AVOption md5_options[] = { HASH_OPT("md5"), @@ -156,6 +149,7 @@ static int hash_write_trailer(struct AVFormatContext *s) return 0; } +#endif static void hash_free(struct AVFormatContext *s) { @@ -168,13 +162,12 @@ static void hash_free(struct AVFormatContext *s) } av_freep(&c->hashes); } -#endif #if CONFIG_HASH_MUXER static const AVClass hashenc_class = { .class_name = "hash muxer", .item_name = av_default_item_name, - .option = hash_options, + .option = hash_streamhash_options, .version = LIBAVUTIL_VERSION_INT, }; @@ -222,7 +215,7 @@ AVOutputFormat ff_md5_muxer = { static const AVClass streamhashenc_class = { .class_name = "stream hash muxer", .item_name = av_default_item_name, - .option = streamhash_options, + .option = hash_streamhash_options, .version = LIBAVUTIL_VERSION_INT, }; @@ -326,14 +319,6 @@ static int framehash_write_packet(struct AVFormatContext *s, AVPacket *pkt) avio_printf(s->pb, "\n"); return 0; } - -static void framehash_free(struct AVFormatContext *s) -{ - struct HashContext *c = s->priv_data; - if (c->hashes) - av_hash_freep(&c->hashes[0]); - av_freep(&c->hashes); -} #endif #if CONFIG_FRAMEHASH_MUXER @@ -353,7 +338,7 @@ AVOutputFormat ff_framehash_muxer = { .init = framehash_init, .write_header = framehash_write_header, .write_packet = framehash_write_packet, - .deinit = framehash_free, + .deinit = hash_free, .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT | AVFMT_TS_NEGATIVE, .priv_class = &framehash_class, @@ -377,7 +362,7 @@ AVOutputFormat ff_framemd5_muxer = { .init = framehash_init, .write_header = framehash_write_header, .write_packet = framehash_write_packet, - .deinit = framehash_free, + .deinit = hash_free, .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT | AVFMT_TS_NEGATIVE, .priv_class = &framemd5_class, diff --git a/libavformat/hevc.c b/libavformat/hevc.c index f621cb2f1..94eb3a9cb 100644 --- a/libavformat/hevc.c +++ b/libavformat/hevc.c @@ -1068,29 +1068,27 @@ int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness) { - int ret = 0; - uint8_t *buf, *end, *start = NULL; HEVCDecoderConfigurationRecord hvcc; - - hvcc_init(&hvcc); + uint8_t *buf, *end, *start; + int ret; if (size < 6) { /* We can't write a valid hvcC from the provided data */ - ret = AVERROR_INVALIDDATA; - goto end; + return AVERROR_INVALIDDATA; } else if (*data == 1) { /* Data is already hvcC-formatted */ avio_write(pb, data, size); - goto end; + return 0; } else if (!(AV_RB24(data) == 1 || AV_RB32(data) == 1)) { /* Not a valid Annex B start code prefix */ - ret = AVERROR_INVALIDDATA; - goto end; + return AVERROR_INVALIDDATA; } ret = ff_avc_parse_nal_units_buf(data, &start, &size); if (ret < 0) - goto end; + return ret; + + hvcc_init(&hvcc); buf = start; end = start + size; diff --git a/libavformat/hls.c b/libavformat/hls.c index 3c7e197ce..597bea7f2 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -23,7 +23,7 @@ /** * @file * Apple HTTP Live Streaming demuxer - * http://tools.ietf.org/html/draft-pantos-http-live-streaming + * https://www.rfc-editor.org/rfc/rfc8216.txt */ #include "libavformat/http.h" @@ -101,7 +101,7 @@ struct playlist { AVFormatContext *parent; int index; AVFormatContext *ctx; - AVPacket pkt; + AVPacket *pkt; int has_noheader_flag; /* main demuxer streams associated with this playlist @@ -112,13 +112,13 @@ struct playlist { int finished; enum PlaylistType type; int64_t target_duration; - int start_seq_no; + int64_t start_seq_no; int n_segments; struct segment **segments; int needed; int broken; - int cur_seq_no; - int last_seq_no; + int64_t cur_seq_no; + int64_t last_seq_no; int m3u8_hold_counters; int64_t cur_seg_offset; int64_t last_load_time; @@ -199,7 +199,7 @@ typedef struct HLSContext { int n_renditions; struct rendition **renditions; - int cur_seq_no; + int64_t cur_seq_no; int m3u8_hold_counters; int live_start_index; int first_packet; @@ -256,7 +256,7 @@ static void free_playlist_list(HLSContext *c) av_dict_free(&pls->id3_initial); ff_id3v2_free_extra_meta(&pls->id3_deferred_extra); av_freep(&pls->init_sec_buf); - av_packet_unref(&pls->pkt); + av_packet_free(&pls->pkt); av_freep(&pls->pb.buffer); ff_format_io_close(c->ctx, &pls->input); pls->input_read_done = 0; @@ -293,26 +293,23 @@ static void free_rendition_list(HLSContext *c) c->n_renditions = 0; } -/* - * Used to reset a statically allocated AVPacket to a clean state, - * containing no data. - */ -static void reset_packet(AVPacket *pkt) -{ - av_init_packet(pkt); - pkt->data = NULL; -} - static struct playlist *new_playlist(HLSContext *c, const char *url, const char *base) { struct playlist *pls = av_mallocz(sizeof(struct playlist)); if (!pls) return NULL; - reset_packet(&pls->pkt); - ff_make_absolute_url(pls->url, sizeof(pls->url), base, url); - if (!pls->url[0]) + pls->pkt = av_packet_alloc(); + if (!pls->pkt) { + av_free(pls); return NULL; + } + ff_make_absolute_url(pls->url, sizeof(pls->url), base, url); + if (!pls->url[0]) { + av_packet_free(&pls->pkt); + av_free(pls); + return NULL; + } pls->seek_timestamp = AV_NOPTS_VALUE; pls->is_id3_timestamped = -1; @@ -625,7 +622,7 @@ static int open_url_keepalive(AVFormatContext *s, AVIOContext **pb, } static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, - AVDictionary *opts, AVDictionary *opts2, int *is_http_out) + AVDictionary **opts, AVDictionary *opts2, int *is_http_out) { HLSContext *c = s->priv_data; AVDictionary *tmp = NULL; @@ -672,7 +669,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; - av_dict_copy(&tmp, opts, 0); + av_dict_copy(&tmp, *opts, 0); av_dict_copy(&tmp, opts2, 0); if (is_http && c->http_persistent && *pb) { @@ -685,6 +682,8 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, av_log(s, AV_LOG_WARNING, "keepalive request failed for '%s' with error: '%s' when opening url, retrying with new connection\n", url, av_err2str(ret)); + av_dict_copy(&tmp, *opts, 0); + av_dict_copy(&tmp, opts2, 0); ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); } } else { @@ -698,7 +697,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, av_opt_get(*pb, "cookies", AV_OPT_SEARCH_CHILDREN, (uint8_t**)&new_cookies); if (new_cookies) - av_dict_set(&opts, "cookies", new_cookies, AV_DICT_DONT_STRDUP_VAL); + av_dict_set(opts, "cookies", new_cookies, AV_DICT_DONT_STRDUP_VAL); } av_dict_free(&tmp); @@ -730,7 +729,7 @@ static int parse_playlist(HLSContext *c, const char *url, int is_http = av_strstart(url, "http", NULL); struct segment **prev_segments = NULL; int prev_n_segments = 0; - int prev_start_seq_no = -1; + int64_t prev_start_seq_no = -1; if (is_http && !in && c->http_persistent && c->playlist_pb) { in = c->playlist_pb; @@ -816,10 +815,17 @@ static int parse_playlist(HLSContext *c, const char *url, goto fail; pls->target_duration = strtoll(ptr, NULL, 10) * AV_TIME_BASE; } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) { + uint64_t seq_no; ret = ensure_playlist(c, &pls, url); if (ret < 0) goto fail; - pls->start_seq_no = atoi(ptr); + seq_no = strtoull(ptr, NULL, 10); + if (seq_no > INT64_MAX) { + av_log(c->ctx, AV_LOG_DEBUG, "MEDIA-SEQUENCE higher than " + "INT64_MAX, mask out the highest bit\n"); + seq_no &= INT64_MAX; + } + pls->start_seq_no = seq_no; } else if (av_strstart(line, "#EXT-X-PLAYLIST-TYPE:", &ptr)) { ret = ensure_playlist(c, &pls, url); if (ret < 0) @@ -840,9 +846,9 @@ static int parse_playlist(HLSContext *c, const char *url, if (has_iv) { memcpy(cur_init_section->iv, iv, sizeof(iv)); } else { - int seq = pls->start_seq_no + pls->n_segments; + int64_t seq = pls->start_seq_no + pls->n_segments; memset(cur_init_section->iv, 0, sizeof(cur_init_section->iv)); - AV_WB32(cur_init_section->iv + 12, seq); + AV_WB64(cur_init_section->iv + 8, seq); } if (key_type != KEY_NONE) { @@ -897,9 +903,9 @@ static int parse_playlist(HLSContext *c, const char *url, if (has_iv) { memcpy(seg->iv, iv, sizeof(iv)); } else { - int seq = pls->start_seq_no + pls->n_segments; + int64_t seq = pls->start_seq_no + pls->n_segments; memset(seg->iv, 0, sizeof(seg->iv)); - AV_WB32(seg->iv + 12, seq); + AV_WB64(seg->iv + 8, seq); } if (key_type != KEY_NONE) { @@ -962,16 +968,17 @@ static int parse_playlist(HLSContext *c, const char *url, if (prev_segments) { if (pls->start_seq_no > prev_start_seq_no && c->first_timestamp != AV_NOPTS_VALUE) { int64_t prev_timestamp = c->first_timestamp; - int i, diff = pls->start_seq_no - prev_start_seq_no; + int i; + int64_t diff = pls->start_seq_no - prev_start_seq_no; for (i = 0; i < prev_n_segments && i < diff; i++) { c->first_timestamp += prev_segments[i]->duration; } - av_log(c->ctx, AV_LOG_DEBUG, "Media sequence change (%d -> %d)" + av_log(c->ctx, AV_LOG_DEBUG, "Media sequence change (%"PRId64" -> %"PRId64")" " reflected in first_timestamp: %"PRId64" -> %"PRId64"\n", prev_start_seq_no, pls->start_seq_no, prev_timestamp, c->first_timestamp); } else if (pls->start_seq_no < prev_start_seq_no) { - av_log(c->ctx, AV_LOG_WARNING, "Media sequence changed unexpectedly: %d -> %d\n", + av_log(c->ctx, AV_LOG_WARNING, "Media sequence changed unexpectedly: %"PRId64" -> %"PRId64"\n", prev_start_seq_no, pls->start_seq_no); } free_segment_dynarray(prev_segments, prev_n_segments); @@ -999,7 +1006,7 @@ static struct segment *current_segment(struct playlist *pls) static struct segment *next_segment(struct playlist *pls) { - int n = pls->cur_seq_no - pls->start_seq_no + 1; + int64_t n = pls->cur_seq_no - pls->start_seq_no + 1; if (n >= pls->n_segments) return NULL; return pls->segments[n]; @@ -1239,12 +1246,12 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, seg->url, seg->url_offset, pls->index); if (seg->key_type == KEY_NONE) { - ret = open_url(pls->parent, in, seg->url, c->avio_opts, opts, &is_http); + ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http); } else if (seg->key_type == KEY_AES_128) { char iv[33], key[33], url[MAX_URL_SIZE]; if (strcmp(seg->key, pls->key_url)) { AVIOContext *pb = NULL; - if (open_url(pls->parent, &pb, seg->key, c->avio_opts, opts, NULL) == 0) { + if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) { ret = avio_read(pb, pls->key, sizeof(pls->key)); if (ret != sizeof(pls->key)) { av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s\n", @@ -1268,7 +1275,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_dict_set(&opts, "key", key, 0); av_dict_set(&opts, "iv", iv, 0); - ret = open_url(pls->parent, in, url, c->avio_opts, opts, &is_http); + ret = open_url(pls->parent, in, url, &c->avio_opts, opts, &is_http); if (ret < 0) { goto cleanup; } @@ -1291,7 +1298,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, * as would be expected. Wrong offset received from the server will not be * noticed without the call, though. */ - if (ret == 0 && !is_http && seg->key_type == KEY_NONE && seg->url_offset) { + if (ret == 0 && !is_http && seg->url_offset) { int64_t seekret = avio_seek(*in, seg->url_offset, SEEK_SET); if (seekret < 0) { av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url); @@ -1465,7 +1472,7 @@ reload: } if (v->cur_seq_no < v->start_seq_no) { av_log(v->parent, AV_LOG_WARNING, - "skipping %d segments ahead, expired from playlists\n", + "skipping %"PRId64" segments ahead, expired from playlists\n", v->start_seq_no - v->cur_seq_no); v->cur_seq_no = v->start_seq_no; } @@ -1511,7 +1518,7 @@ reload: if (ret < 0) { if (ff_check_interrupt(c->interrupt_callback)) return AVERROR_EXIT; - av_log(v->parent, AV_LOG_WARNING, "Failed to open segment %d of playlist %d\n", + av_log(v->parent, AV_LOG_WARNING, "Failed to open segment %"PRId64" of playlist %d\n", v->cur_seq_no, v->index); v->cur_seq_no += 1; @@ -1536,7 +1543,7 @@ reload: if (ret < 0) { if (ff_check_interrupt(c->interrupt_callback)) return AVERROR_EXIT; - av_log(v->parent, AV_LOG_WARNING, "Failed to open next segment %d of playlist %d\n", + av_log(v->parent, AV_LOG_WARNING, "Failed to open segment %"PRId64" of playlist %d\n", v->cur_seq_no + 1, v->index); } else { @@ -1633,7 +1640,7 @@ static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pl /* if timestamp was in valid range: returns 1 and sets seq_no * if not: returns 0 and sets seq_no to closest segment */ static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls, - int64_t timestamp, int *seq_no) + int64_t timestamp, int64_t *seq_no) { int i; int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? @@ -1658,9 +1665,9 @@ static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls, return 0; } -static int select_cur_seq_no(HLSContext *c, struct playlist *pls) +static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls) { - int seq_no; + int64_t seq_no; if (!pls->finished && !c->first_packet && av_gettime_relative() - pls->last_load_time >= default_reload_interval(pls)) @@ -1768,6 +1775,20 @@ static int set_stream_info_from_input_stream(AVStream *st, struct playlist *pls, else avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); + // copy disposition + st->disposition = ist->disposition; + + // copy side data + for (int i = 0; i < ist->nb_side_data; i++) { + const AVPacketSideData *sd_src = &ist->side_data[i]; + uint8_t *dst_data; + + dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size); + if (!dst_data) + return AVERROR(ENOMEM); + memcpy(dst_data, sd_src->data, sd_src->size); + } + st->internal->need_context_update = 1; return 0; @@ -1838,7 +1859,7 @@ static int hls_read_header(AVFormatContext *s) { HLSContext *c = s->priv_data; int ret = 0, i; - int highest_cur_seq_no = 0; + int64_t highest_cur_seq_no = 0; c->ctx = s; c->interrupt_callback = &s->interrupt_callback; @@ -1970,19 +1991,21 @@ static int hls_read_header(AVFormatContext *s) read_data, NULL, NULL); pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; + pls->ctx->interrupt_callback = s->interrupt_callback; url = av_strdup(pls->segments[0]->url); ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); - av_free(url); if (ret < 0) { /* Free the ctx - it isn't initialized properly at this point, * so avformat_close_input shouldn't be called. If * avformat_open_input fails below, it frees and zeros the * context, so it doesn't need any special treatment like this. */ - av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", pls->segments[0]->url); + av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); avformat_free_context(pls->ctx); pls->ctx = NULL; + av_free(url); goto fail; } + av_free(url); pls->ctx->pb = &pls->pb; pls->ctx->io_open = nested_io_open; pls->ctx->flags |= s->flags & ~AVFMT_FLAG_CUSTOM_IO; @@ -2069,7 +2092,7 @@ static int recheck_discard_flags(AVFormatContext *s, int first) pls->seek_flags = AVSEEK_FLAG_ANY; pls->seek_stream_index = -1; } - av_log(s, AV_LOG_INFO, "Now receiving playlist %d, segment %d\n", i, pls->cur_seq_no); + av_log(s, AV_LOG_INFO, "Now receiving playlist %d, segment %"PRId64"\n", i, pls->cur_seq_no); } else if (first && !cur_needed && pls->needed) { ff_format_io_close(pls->parent, &pls->input); pls->input_read_done = 0; @@ -2086,26 +2109,26 @@ static int recheck_discard_flags(AVFormatContext *s, int first) static void fill_timing_for_id3_timestamped_stream(struct playlist *pls) { if (pls->id3_offset >= 0) { - pls->pkt.dts = pls->id3_mpegts_timestamp + + pls->pkt->dts = pls->id3_mpegts_timestamp + av_rescale_q(pls->id3_offset, - pls->ctx->streams[pls->pkt.stream_index]->time_base, + pls->ctx->streams[pls->pkt->stream_index]->time_base, MPEG_TIME_BASE_Q); - if (pls->pkt.duration) - pls->id3_offset += pls->pkt.duration; + if (pls->pkt->duration) + pls->id3_offset += pls->pkt->duration; else pls->id3_offset = -1; } else { /* there have been packets with unknown duration * since the last id3 tag, should not normally happen */ - pls->pkt.dts = AV_NOPTS_VALUE; + pls->pkt->dts = AV_NOPTS_VALUE; } - if (pls->pkt.duration) - pls->pkt.duration = av_rescale_q(pls->pkt.duration, - pls->ctx->streams[pls->pkt.stream_index]->time_base, + if (pls->pkt->duration) + pls->pkt->duration = av_rescale_q(pls->pkt->duration, + pls->ctx->streams[pls->pkt->stream_index]->time_base, MPEG_TIME_BASE_Q); - pls->pkt.pts = AV_NOPTS_VALUE; + pls->pkt->pts = AV_NOPTS_VALUE; } static AVRational get_timebase(struct playlist *pls) @@ -2113,7 +2136,7 @@ static AVRational get_timebase(struct playlist *pls) if (pls->is_id3_timestamped) return MPEG_TIME_BASE_Q; - return pls->ctx->streams[pls->pkt.stream_index]->time_base; + return pls->ctx->streams[pls->pkt->stream_index]->time_base; } static int compare_ts_with_wrapdetect(int64_t ts_a, struct playlist *pls_a, @@ -2137,26 +2160,25 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) struct playlist *pls = c->playlists[i]; /* Make sure we've got one buffered packet from each open playlist * stream */ - if (pls->needed && !pls->pkt.data) { + if (pls->needed && !pls->pkt->data) { while (1) { int64_t ts_diff; AVRational tb; - ret = av_read_frame(pls->ctx, &pls->pkt); + ret = av_read_frame(pls->ctx, pls->pkt); if (ret < 0) { if (!avio_feof(&pls->pb) && ret != AVERROR_EOF) return ret; - reset_packet(&pls->pkt); break; } else { /* stream_index check prevents matching picture attachments etc. */ - if (pls->is_id3_timestamped && pls->pkt.stream_index == 0) { + if (pls->is_id3_timestamped && pls->pkt->stream_index == 0) { /* audio elementary streams are id3 timestamped */ fill_timing_for_id3_timestamped_stream(pls); } if (c->first_timestamp == AV_NOPTS_VALUE && - pls->pkt.dts != AV_NOPTS_VALUE) - c->first_timestamp = av_rescale_q(pls->pkt.dts, + pls->pkt->dts != AV_NOPTS_VALUE) + c->first_timestamp = av_rescale_q(pls->pkt->dts, get_timebase(pls), AV_TIME_BASE_Q); } @@ -2164,35 +2186,35 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) break; if (pls->seek_stream_index < 0 || - pls->seek_stream_index == pls->pkt.stream_index) { + pls->seek_stream_index == pls->pkt->stream_index) { - if (pls->pkt.dts == AV_NOPTS_VALUE) { + if (pls->pkt->dts == AV_NOPTS_VALUE) { pls->seek_timestamp = AV_NOPTS_VALUE; break; } tb = get_timebase(pls); - ts_diff = av_rescale_rnd(pls->pkt.dts, AV_TIME_BASE, + ts_diff = av_rescale_rnd(pls->pkt->dts, AV_TIME_BASE, tb.den, AV_ROUND_DOWN) - pls->seek_timestamp; if (ts_diff >= 0 && (pls->seek_flags & AVSEEK_FLAG_ANY || - pls->pkt.flags & AV_PKT_FLAG_KEY)) { + pls->pkt->flags & AV_PKT_FLAG_KEY)) { pls->seek_timestamp = AV_NOPTS_VALUE; break; } } - av_packet_unref(&pls->pkt); + av_packet_unref(pls->pkt); } } /* Check if this stream has the packet with the lowest dts */ - if (pls->pkt.data) { + if (pls->pkt->data) { struct playlist *minpls = minplaylist < 0 ? NULL : c->playlists[minplaylist]; if (minplaylist < 0) { minplaylist = i; } else { - int64_t dts = pls->pkt.dts; - int64_t mindts = minpls->pkt.dts; + int64_t dts = pls->pkt->dts; + int64_t mindts = minpls->pkt->dts; if (dts == AV_NOPTS_VALUE || (mindts != AV_NOPTS_VALUE && compare_ts_with_wrapdetect(dts, pls, mindts, minpls) < 0)) @@ -2209,7 +2231,7 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) ret = update_streams_from_subdemuxer(s, pls); if (ret < 0) { - av_packet_unref(&pls->pkt); + av_packet_unref(pls->pkt); return ret; } @@ -2230,17 +2252,17 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) update_noheader_flag(s); } - if (pls->pkt.stream_index >= pls->n_main_streams) { + if (pls->pkt->stream_index >= pls->n_main_streams) { av_log(s, AV_LOG_ERROR, "stream index inconsistency: index %d, %d main streams, %d subdemuxer streams\n", - pls->pkt.stream_index, pls->n_main_streams, pls->ctx->nb_streams); - av_packet_unref(&pls->pkt); + pls->pkt->stream_index, pls->n_main_streams, pls->ctx->nb_streams); + av_packet_unref(pls->pkt); return AVERROR_BUG; } - ist = pls->ctx->streams[pls->pkt.stream_index]; - st = pls->main_streams[pls->pkt.stream_index]; + ist = pls->ctx->streams[pls->pkt->stream_index]; + st = pls->main_streams[pls->pkt->stream_index]; - av_packet_move_ref(pkt, &pls->pkt); + av_packet_move_ref(pkt, pls->pkt); pkt->stream_index = st->index; if (pkt->dts != AV_NOPTS_VALUE) @@ -2267,10 +2289,10 @@ static int hls_read_seek(AVFormatContext *s, int stream_index, { HLSContext *c = s->priv_data; struct playlist *seek_pls = NULL; - int i, seq_no; - int j; + int i, j; int stream_subdemuxer_index; int64_t first_timestamp, seek_timestamp, duration; + int64_t seq_no; if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags & AVFMTCTX_UNSEEKABLE)) return AVERROR(ENOSYS); @@ -2316,7 +2338,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index, pls->input_read_done = 0; ff_format_io_close(pls->parent, &pls->input_next); pls->input_next_requested = 0; - av_packet_unref(&pls->pkt); + av_packet_unref(pls->pkt); pls->pb.eof_reached = 0; /* Clear any buffered data */ pls->pb.buf_end = pls->pb.buf_ptr = pls->pb.buffer; @@ -2365,7 +2387,7 @@ static const AVOption hls_options[] = { OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS}, {"allowed_extensions", "List of file extensions that hls is allowed to access", OFFSET(allowed_extensions), AV_OPT_TYPE_STRING, - {.str = "3gp,aac,avi,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"}, + {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"}, INT_MIN, INT_MAX, FLAGS}, {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded", OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS}, diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 71fa3db06..7d97ce178 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -46,6 +46,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "avc.h" #if CONFIG_HTTP_PROTOCOL #include "http.h" #endif @@ -69,6 +70,7 @@ typedef enum { #define KEYSIZE 16 #define LINE_BUFFER_SIZE MAX_URL_SIZE #define HLS_MICROSECOND_UNIT 1000000 +#define BUFSIZE (16 * 1024) #define POSTFIX_PATTERN "_%d" typedef struct HLSSegment { @@ -86,6 +88,7 @@ typedef struct HLSSegment { char iv_string[KEYSIZE*2 + 1]; struct HLSSegment *next; + double discont_program_date_time; } HLSSegment; typedef enum HLSFlags { @@ -119,6 +122,7 @@ typedef struct VariantStream { ff_const59 AVOutputFormat *oformat; ff_const59 AVOutputFormat *vtt_oformat; AVIOContext *out; + AVIOContext *out_single_file; int packets_written; int init_range_length; uint8_t *temp_buffer; @@ -149,6 +153,7 @@ typedef struct VariantStream { HLSSegment *last_segment; HLSSegment *old_segments; + char *basename_tmp; char *basename; char *vtt_basename; char *vtt_m3u8_name; @@ -191,8 +196,8 @@ typedef struct HLSContext { int64_t start_sequence; uint32_t start_sequence_source_type; // enum StartSequenceSourceType - float time; // Set by a private option. - float init_time; // Set by a private option. + int64_t time; // Set by a private option. + int64_t init_time; // Set by a private option. int max_nb_segments; // Set by a private option. int hls_delete_threshold; // Set by a private option. #if FF_API_HLS_WRAP @@ -255,6 +260,29 @@ typedef struct HLSContext { int has_video_m3u8; /* has video stream m3u8 list */ } HLSContext; +static int strftime_expand(const char *fmt, char **dest) +{ + int r = 1; + time_t now0; + struct tm *tm, tmpbuf; + char *buf; + + buf = av_mallocz(MAX_URL_SIZE); + if (!buf) + return AVERROR(ENOMEM); + + time(&now0); + tm = localtime_r(&now0, &tmpbuf); + r = strftime(buf, MAX_URL_SIZE, fmt, tm); + if (!r) { + av_free(buf); + return AVERROR(EINVAL); + } + *dest = buf; + + return r; +} + static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, AVDictionary **options) { @@ -334,6 +362,51 @@ static void write_codec_attr(AVStream *st, VariantStream *vs) } else { goto fail; } + } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) { + uint8_t *data = st->codecpar->extradata; + int profile = FF_PROFILE_UNKNOWN; + int level = FF_LEVEL_UNKNOWN; + + if (st->codecpar->profile != FF_PROFILE_UNKNOWN) + profile = st->codecpar->profile; + if (st->codecpar->level != FF_LEVEL_UNKNOWN) + level = st->codecpar->level; + + /* check the boundary of data which from current position is small than extradata_size */ + while (data && (data - st->codecpar->extradata + 19) < st->codecpar->extradata_size) { + /* get HEVC SPS NAL and seek to profile_tier_level */ + if (!(data[0] | data[1] | data[2]) && data[3] == 1 && ((data[4] & 0x7E) == 0x42)) { + uint8_t *rbsp_buf; + int remain_size = 0; + int rbsp_size = 0; + /* skip start code + nalu header */ + data += 6; + /* process by reference General NAL unit syntax */ + remain_size = st->codecpar->extradata_size - (data - st->codecpar->extradata); + rbsp_buf = ff_nal_unit_extract_rbsp(data, remain_size, &rbsp_size, 0); + if (!rbsp_buf) + return; + if (rbsp_size < 13) { + av_freep(&rbsp_buf); + break; + } + /* skip sps_video_parameter_set_id u(4), + * sps_max_sub_layers_minus1 u(3), + * and sps_temporal_id_nesting_flag u(1) */ + profile = rbsp_buf[1] & 0x1f; + /* skip 8 + 8 + 32 + 4 + 43 + 1 bit */ + level = rbsp_buf[12]; + av_freep(&rbsp_buf); + break; + } + data++; + } + if (st->codecpar->codec_tag == MKTAG('h','v','c','1') && + profile != FF_PROFILE_UNKNOWN && + level != FF_LEVEL_UNKNOWN) { + snprintf(attr, sizeof(attr), "%s.%d.4.L%d.B01", av_fourcc2str(st->codecpar->codec_tag), profile, level); + } else + goto fail; } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) { snprintf(attr, sizeof(attr), "mp4a.40.33"); } else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) { @@ -365,11 +438,11 @@ fail: static int replace_str_data_in_filename(char **s, const char *filename, char placeholder, const char *datastring) { const char *p; - char *new_filename; char c; int addchar_count; int found_count = 0; AVBPrint buf; + int ret; av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); @@ -395,22 +468,21 @@ static int replace_str_data_in_filename(char **s, const char *filename, char pla } if (!av_bprint_is_complete(&buf)) { av_bprint_finalize(&buf, NULL); - return -1; + return AVERROR(ENOMEM); } - if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename) - return -1; - *s = new_filename; + if ((ret = av_bprint_finalize(&buf, s)) < 0) + return ret; return found_count; } static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number) { const char *p; - char *new_filename; char c; int nd, addchar_count; int found_count = 0; AVBPrint buf; + int ret; av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); @@ -444,11 +516,10 @@ static int replace_int_data_in_filename(char **s, const char *filename, char pla } if (!av_bprint_is_complete(&buf)) { av_bprint_finalize(&buf, NULL); - return -1; + return AVERROR(ENOMEM); } - if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename) - return -1; - *s = new_filename; + if ((ret = av_bprint_finalize(&buf, s)) < 0) + return ret; return found_count; } @@ -1077,6 +1148,7 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, en->keyframe_size = vs->video_keyframe_size; en->next = NULL; en->discont = 0; + en->discont_program_date_time = 0; if (vs->discontinuity) { en->discont = 1; @@ -1101,7 +1173,8 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, if (hls->max_nb_segments && vs->nb_entries >= hls->max_nb_segments) { en = vs->segments; - vs->initial_prog_date_time += en->duration; + if (!en->next->discont_program_date_time && !en->discont_program_date_time) + vs->initial_prog_date_time += en->duration; vs->segments = en->next; if (en && hls->flags & HLS_DELETE_SEGMENTS && #if FF_API_HLS_WRAP @@ -1135,6 +1208,7 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs char line[MAX_URL_SIZE]; const char *ptr; const char *end; + double discont_program_date_time = 0; if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, &s->interrupt_callback, NULL, @@ -1189,7 +1263,25 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs av_strlcpy(vs->iv_string, ptr, sizeof(vs->iv_string)); } } + } else if (av_strstart(line, "#EXT-X-PROGRAM-DATE-TIME:", &ptr)) { + struct tm program_date_time; + int y,M,d,h,m,s; + double ms; + if (sscanf(ptr, "%d-%d-%dT%d:%d:%d.%lf", &y, &M, &d, &h, &m, &s, &ms) != 7) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + program_date_time.tm_year = y - 1900; + program_date_time.tm_mon = M - 1; + program_date_time.tm_mday = d; + program_date_time.tm_hour = h; + program_date_time.tm_min = m; + program_date_time.tm_sec = s; + program_date_time.tm_isdst = -1; + + discont_program_date_time = mktime(&program_date_time); + discont_program_date_time += (double)(ms / 1000); } else if (av_strstart(line, "#", NULL)) { continue; } else if (line[0]) { @@ -1203,8 +1295,9 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs is_segment = 0; new_start_pos = avio_tell(vs->avf->pb); vs->size = new_start_pos - vs->start_pos; - vs->initial_prog_date_time -= vs->duration; // this is a previously existing segment ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size); + vs->last_segment->discont_program_date_time = discont_program_date_time; + discont_program_date_time += vs->duration; if (ret < 0) goto fail; vs->start_pos = new_start_pos; @@ -1471,6 +1564,10 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) sequence = 0; } + if (hls->flags & HLS_I_FRAMES_ONLY) { + hls->version = 4; + } + if (hls->flags & HLS_INDEPENDENT_SEGMENTS) { hls->version = 6; } @@ -1525,7 +1622,11 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) ret = ff_hls_write_file_entry(byterange_mode ? hls->m3u8_out : vs->out, en->discont, byterange_mode, en->duration, hls->flags & HLS_ROUND_DURATIONS, en->size, en->pos, hls->baseurl, - en->filename, prog_date_time_p, en->keyframe_size, en->keyframe_pos, hls->flags & HLS_I_FRAMES_ONLY); + en->filename, + en->discont_program_date_time ? &en->discont_program_date_time : prog_date_time_p, + en->keyframe_size, en->keyframe_pos, hls->flags & HLS_I_FRAMES_ONLY); + if (en->discont_program_date_time) + en->discont_program_date_time -= en->duration; if (ret < 0) { av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n"); } @@ -1613,19 +1714,15 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) ff_format_set_url(oc, filename); } else { if (c->use_localtime) { - time_t now0; - struct tm *tm, tmpbuf; - int bufsize = strlen(vs->basename) + MAX_URL_SIZE; - char *buf = av_mallocz(bufsize); - if (!buf) - return AVERROR(ENOMEM); - time(&now0); - tm = localtime_r(&now0, &tmpbuf); - ff_format_set_url(oc, buf); - if (!strftime(oc->url, bufsize, vs->basename, tm)) { + int r; + char *expanded = NULL; + + r = strftime_expand(vs->basename, &expanded); + if (r < 0) { av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); - return AVERROR(EINVAL); + return r; } + ff_format_set_url(oc, expanded); err = sls_flag_use_localtime_filename(oc, c, vs); if (err < 0) { @@ -1724,12 +1821,34 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0); } if (c->flags & HLS_SINGLE_FILE) { + if (c->key_info_file || c->encrypt) { + av_dict_set(&options, "encryption_key", vs->key_string, 0); + av_dict_set(&options, "encryption_iv", vs->iv_string, 0); + + /* Write temp file with cryption content */ + av_freep(&vs->basename_tmp); + vs->basename_tmp = av_asprintf("crypto:%s.tmp", oc->url); + + /* append temp file content into single file */ + av_freep(&vs->basename); + vs->basename = av_asprintf("%s", oc->url); + } else { + vs->basename_tmp = vs->basename; + } set_http_options(s, &options, c); - if ((err = hlsenc_io_open(s, &vs->out, oc->url, &options)) < 0) { + if (!vs->out_single_file) + if ((err = hlsenc_io_open(s, &vs->out_single_file, vs->basename, &options)) < 0) { + if (c->ignore_io_errors) + err = 0; + goto fail; + } + + if ((err = hlsenc_io_open(s, &vs->out, vs->basename_tmp, &options)) < 0) { if (c->ignore_io_errors) err = 0; goto fail; } + } } if (vs->vtt_basename) { @@ -2224,6 +2343,10 @@ static int hls_write_header(AVFormatContext *s) continue; } avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den); + if (outer_st->codecpar->codec_id == AV_CODEC_ID_HEVC && + outer_st->codecpar->codec_tag != MKTAG('h','v','c','1')) { + av_log(s, AV_LOG_WARNING, "Stream HEVC is not hvc1, you should use tag:v hvc1 to set it.\n"); + } write_codec_attr(outer_st, vs); } @@ -2260,6 +2383,38 @@ static int hls_init_file_resend(AVFormatContext *s, VariantStream *vs) return ret; } +static int64_t append_single_file(AVFormatContext *s, VariantStream *vs) +{ + int ret = 0; + int64_t read_byte = 0; + int64_t total_size = 0; + char *filename = NULL; + char buf[BUFSIZE]; + AVFormatContext *oc = vs->avf; + + hlsenc_io_close(s, &vs->out, vs->basename_tmp); + filename = av_asprintf("%s.tmp", oc->url); + ret = s->io_open(s, &vs->out, filename, AVIO_FLAG_READ, NULL); + if (ret < 0) { + av_free(filename); + return ret; + } + + do { + memset(buf, 0, sizeof(BUFSIZE)); + read_byte = avio_read(vs->out, buf, BUFSIZE); + avio_write(vs->out_single_file, buf, read_byte); + if (read_byte > 0) { + total_size += read_byte; + ret = total_size; + } + } while (read_byte > 0); + + hlsenc_io_close(s, &vs->out, filename); + av_free(filename); + + return ret; +} static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) { HLSContext *hls = s->priv_data; @@ -2303,9 +2458,9 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) if (vs->sequence - vs->nb_entries > hls->start_sequence && hls->init_time > 0) { /* reset end_pts, hls->recording_time at end of the init hls list */ - int64_t init_list_dur = hls->init_time * vs->nb_entries * AV_TIME_BASE; - int64_t after_init_list_dur = (vs->sequence - hls->start_sequence - vs->nb_entries) * (hls->time * AV_TIME_BASE); - hls->recording_time = hls->time * AV_TIME_BASE; + int64_t init_list_dur = hls->init_time * vs->nb_entries; + int64_t after_init_list_dur = (vs->sequence - hls->start_sequence - vs->nb_entries) * hls->time; + hls->recording_time = hls->time; end_pts = init_list_dur + after_init_list_dur ; } @@ -2343,9 +2498,9 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) vs->duration = (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den; } } - } + can_split = can_split && (pkt->pts - vs->end_pts > 0); if (vs->packets_written && can_split && av_compare_ts(pkt->pts - vs->start_pts, st->time_base, end_pts, AV_TIME_BASE_Q) >= 0) { int64_t new_start_pos; @@ -2385,6 +2540,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } vs->size = range_length; + if (hls->key_info_file || hls->encrypt) + vs->size = append_single_file(s, vs); } else { if (oc->url[0]) { proto = avio_find_protocol_name(oc->url); @@ -2392,7 +2549,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) && (hls->flags & HLS_TEMP_FILE); } - if ((hls->max_seg_size > 0 && (vs->size >= hls->max_seg_size)) || !byterange_mode) { + if ((hls->max_seg_size > 0 && (vs->size + vs->start_pos >= hls->max_seg_size)) || !byterange_mode) { AVDictionary *options = NULL; char *filename = NULL; if (hls->key_info_file || hls->encrypt) { @@ -2486,15 +2643,18 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) if (hls->flags & HLS_SINGLE_FILE) { vs->start_pos += vs->size; + if (hls->key_info_file || hls->encrypt) + ret = hls_start(s, vs); } else if (hls->max_seg_size > 0) { - vs->start_pos = new_start_pos; - if (vs->size >= hls->max_seg_size) { + if (vs->size + vs->start_pos >= hls->max_seg_size) { vs->sequence++; sls_flag_file_rename(hls, vs, old_filename); ret = hls_start(s, vs); vs->start_pos = 0; /* When split segment by byte, the duration is short than hls_time, * so it is not enough one segment duration as hls_time, */ + } else { + vs->start_pos = new_start_pos; } } else { vs->start_pos = new_start_pos; @@ -2512,13 +2672,14 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) vs->packets_written++; if (oc->pb) { + int64_t keyframe_pre_pos = avio_tell(oc->pb); ret = ff_write_chained(oc, stream_index, pkt, s, 0); - vs->video_keyframe_size += pkt->size; - if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->flags & AV_PKT_FLAG_KEY)) { - vs->video_keyframe_size = avio_tell(oc->pb); - } else { - vs->video_keyframe_pos = avio_tell(vs->out); + if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && + (pkt->flags & AV_PKT_FLAG_KEY) && !keyframe_pre_pos) { + av_write_frame(oc, NULL); /* Flush any buffered data */ + vs->video_keyframe_size = avio_tell(oc->pb) - keyframe_pre_pos; } + vs->video_keyframe_pos = vs->start_pos; if (hls->ignore_io_errors) ret = 0; } @@ -2631,7 +2792,6 @@ static int hls_write_trailer(struct AVFormatContext *s) goto failed; vs->size = range_length; - hlsenc_io_close(s, &vs->out, filename); ret = hlsenc_io_close(s, &vs->out, filename); if (ret < 0) { av_log(s, AV_LOG_WARNING, "upload segment failed, will retry with a new http session.\n"); @@ -2646,7 +2806,12 @@ static int hls_write_trailer(struct AVFormatContext *s) if (ret < 0) av_log(s, AV_LOG_WARNING, "Failed to upload file '%s' at the end.\n", oc->url); } - + if (hls->flags & HLS_SINGLE_FILE) { + if (hls->key_info_file || hls->encrypt) { + vs->size = append_single_file(s, vs); + } + hlsenc_io_close(s, &vs->out_single_file, vs->basename); + } failed: av_freep(&vs->temp_buffer); av_dict_free(&options); @@ -2706,6 +2871,7 @@ static int hls_init(AVFormatContext *s) char *p = NULL; int http_base_proto = ff_is_http_proto(s->url); int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1; + double initial_program_date_time = av_gettime() / 1000000.0; if (hls->use_localtime) { pattern = get_default_pattern_localtime_fmt(s); @@ -2779,7 +2945,7 @@ static int hls_init(AVFormatContext *s) av_log(hls, AV_LOG_DEBUG, "start_number evaluated to %"PRId64"\n", hls->start_sequence); } - hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE; + hls->recording_time = hls->init_time ? hls->init_time : hls->time; if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) { // Independent segments cannot be guaranteed when splitting by time @@ -2800,12 +2966,7 @@ static int hls_init(AVFormatContext *s) vs->start_pts = AV_NOPTS_VALUE; vs->end_pts = AV_NOPTS_VALUE; vs->current_segment_final_filename_fmt[0] = '\0'; - - if (hls->flags & HLS_PROGRAM_DATE_TIME) { - time_t now0; - time(&now0); - vs->initial_prog_date_time = now0; - } + vs->initial_prog_date_time = initial_program_date_time; for (j = 0; j < vs->nb_streams; j++) { vs->has_video += vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO; @@ -2869,6 +3030,19 @@ static int hls_init(AVFormatContext *s) return ret; } + if (hls->use_localtime) { + int r; + char *expanded = NULL; + + r = strftime_expand(vs->fmp4_init_filename, &expanded); + if (r < 0) { + av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); + return r; + } + av_free(vs->fmp4_init_filename); + vs->fmp4_init_filename = expanded; + } + p = strrchr(vs->m3u8_name, '/'); if (p) { char tmp = *(++p); @@ -2924,7 +3098,7 @@ static int hls_init(AVFormatContext *s) av_log(s, AV_LOG_WARNING, "append_list mode does not support hls_init_time," " hls_init_time value will have no effect\n"); hls->init_time = 0; - hls->recording_time = hls->time * AV_TIME_BASE; + hls->recording_time = hls->time; } } @@ -2940,8 +3114,8 @@ static int hls_init(AVFormatContext *s) #define E AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { {"start_number", "set first number in the sequence", OFFSET(start_sequence),AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E}, - {"hls_time", "set segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E}, - {"hls_init_time", "set segment length in seconds at init list", OFFSET(init_time), AV_OPT_TYPE_FLOAT, {.dbl = 0}, 0, FLT_MAX, E}, + {"hls_time", "set segment length", OFFSET(time), AV_OPT_TYPE_DURATION, {.i64 = 2000000}, 0, INT64_MAX, E}, + {"hls_init_time", "set segment length at init list", OFFSET(init_time), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E}, {"hls_list_size", "set maximum number of playlist entries", OFFSET(max_nb_segments), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E}, {"hls_delete_threshold", "set number of unreferenced segments to keep before deleting", OFFSET(hls_delete_threshold), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, E}, {"hls_ts_options","set hls mpegts list of options for the container format used for hls", OFFSET(format_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E}, diff --git a/libavformat/hlsproto.c b/libavformat/hlsproto.c index de45f771d..9e78f931e 100644 --- a/libavformat/hlsproto.c +++ b/libavformat/hlsproto.c @@ -22,7 +22,7 @@ /** * @file * Apple HTTP Live Streaming Protocol Handler - * http://tools.ietf.org/html/draft-pantos-http-live-streaming + * https://www.rfc-editor.org/rfc/rfc8216.txt */ #include "libavutil/avstring.h" diff --git a/libavformat/http.c b/libavformat/http.c index 6c39da1a8..fb2d9306b 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -78,9 +78,6 @@ typedef struct HTTPContext { char *http_version; char *user_agent; char *referer; -#if FF_API_HTTP_USER_AGENT - char *user_agent_deprecated; -#endif char *content_type; /* Set if the server correctly handles Connection: close and will close * the connection after feeding us the content. */ @@ -119,8 +116,10 @@ typedef struct HTTPContext { char *method; int reconnect; int reconnect_at_eof; + int reconnect_on_network_error; int reconnect_streamed; int reconnect_delay_max; + char *reconnect_on_http_error; int listen; char *resource; int reply_code; @@ -143,7 +142,7 @@ static const AVOption options[] = { { "user_agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, { .str = DEFAULT_USER_AGENT }, 0, 0, D }, { "referer", "override referer header", OFFSET(referer), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D }, #if FF_API_HTTP_USER_AGENT - { "user-agent", "use the \"user_agent\" option instead", OFFSET(user_agent_deprecated), AV_OPT_TYPE_STRING, { .str = DEFAULT_USER_AGENT }, 0, 0, D|AV_OPT_FLAG_DEPRECATED }, + { "user-agent", "use the \"user_agent\" option instead", OFFSET(user_agent), AV_OPT_TYPE_STRING, { .str = DEFAULT_USER_AGENT }, 0, 0, D|AV_OPT_FLAG_DEPRECATED }, #endif { "multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D | E }, { "post_data", "set custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D | E }, @@ -164,6 +163,8 @@ static const AVOption options[] = { { "method", "Override the HTTP method or set the expected HTTP method from a client", OFFSET(method), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D | E }, { "reconnect", "auto reconnect after disconnect before EOF", OFFSET(reconnect), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, { "reconnect_at_eof", "auto reconnect at EOF", OFFSET(reconnect_at_eof), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, + { "reconnect_on_network_error", "auto reconnect in case of tcp/tls error during connect", OFFSET(reconnect_on_network_error), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, + { "reconnect_on_http_error", "list of http status codes to reconnect on", OFFSET(reconnect_on_http_error), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D }, { "reconnect_streamed", "auto reconnect streamed / non seekable streams", OFFSET(reconnect_streamed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, { "reconnect_delay_max", "max reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_max), AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, D }, { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, @@ -213,6 +214,12 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) use_proxy = 0; if (port < 0) port = 443; + /* pass http_proxy to underlying protocol */ + if (s->http_proxy) { + err = av_dict_set(options, "http_proxy", s->http_proxy, 0); + if (err < 0) + return err; + } } if (port < 0) port = 80; @@ -258,21 +265,73 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) return location_changed; } +static int http_should_reconnect(HTTPContext *s, int err) +{ + const char *status_group; + char http_code[4]; + + switch (err) { + case AVERROR_HTTP_BAD_REQUEST: + case AVERROR_HTTP_UNAUTHORIZED: + case AVERROR_HTTP_FORBIDDEN: + case AVERROR_HTTP_NOT_FOUND: + case AVERROR_HTTP_OTHER_4XX: + status_group = "4xx"; + break; + + case AVERROR_HTTP_SERVER_ERROR: + status_group = "5xx"; + break; + + default: + return s->reconnect_on_network_error; + } + + if (!s->reconnect_on_http_error) + return 0; + + if (av_match_list(status_group, s->reconnect_on_http_error, ',') > 0) + return 1; + + snprintf(http_code, sizeof(http_code), "%d", s->http_code); + + return av_match_list(http_code, s->reconnect_on_http_error, ',') > 0; +} + /* return non zero if error */ static int http_open_cnx(URLContext *h, AVDictionary **options) { HTTPAuthType cur_auth_type, cur_proxy_auth_type; HTTPContext *s = h->priv_data; int location_changed, attempts = 0, redirects = 0; + int reconnect_delay = 0; + uint64_t off; + redo: av_dict_copy(options, s->chained_options, 0); cur_auth_type = s->auth_state.auth_type; cur_proxy_auth_type = s->auth_state.auth_type; + off = s->off; location_changed = http_open_cnx_internal(h, options); - if (location_changed < 0) - goto fail; + if (location_changed < 0) { + if (!http_should_reconnect(s, location_changed) || + reconnect_delay > s->reconnect_delay_max) + goto fail; + + av_log(h, AV_LOG_WARNING, "Will reconnect at %"PRIu64" in %d second(s).\n", off, reconnect_delay); + location_changed = ff_network_sleep_interruptible(1000U * 1000 * reconnect_delay, &h->interrupt_callback); + if (location_changed != AVERROR(ETIMEDOUT)) + goto fail; + reconnect_delay = 1 + 2 * reconnect_delay; + + /* restore the offset (http_connect resets it) */ + s->off = off; + + ffurl_closep(&s->hd); + goto redo; + } attempts++; if (s->http_code == 401) { @@ -292,7 +351,7 @@ redo: goto fail; } if ((s->http_code == 301 || s->http_code == 302 || - s->http_code == 303 || s->http_code == 307) && + s->http_code == 303 || s->http_code == 307 || s->http_code == 308) && location_changed == 1) { /* url moved, get next */ ffurl_closep(&s->hd); @@ -577,7 +636,7 @@ static int http_open(URLContext *h, const char *uri, int flags, "No trailing CRLF found in HTTP header. Adding it.\n"); ret = av_reallocp(&s->headers, len + 3); if (ret < 0) - return ret; + goto bail_out; s->headers[len] = '\r'; s->headers[len + 1] = '\n'; s->headers[len + 2] = '\0'; @@ -588,6 +647,7 @@ static int http_open(URLContext *h, const char *uri, int flags, return http_listen(h, uri, flags, options); } ret = http_open_cnx(h, options); +bail_out: if (ret < 0) av_dict_free(&s->chained_options); return ret; @@ -1264,12 +1324,6 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, } } -#if FF_API_HTTP_USER_AGENT - if (strcmp(s->user_agent_deprecated, DEFAULT_USER_AGENT)) { - s->user_agent = av_strdup(s->user_agent_deprecated); - } -#endif - av_bprintf(&request, "%s ", method); bprint_escaped_path(&request, path); av_bprintf(&request, " HTTP/1.1\r\n"); @@ -1435,7 +1489,8 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size) if ((!s->willclose || s->chunksize == UINT64_MAX) && s->off >= target_end) return AVERROR_EOF; len = ffurl_read(s->hd, buf, size); - if (!len && (!s->willclose || s->chunksize == UINT64_MAX) && s->off < target_end) { + if ((!len || len == AVERROR_EOF) && + (!s->willclose || s->chunksize == UINT64_MAX) && s->off < target_end) { av_log(h, AV_LOG_ERROR, "Stream ends prematurely at %"PRIu64", should be %"PRIu64"\n", s->off, target_end diff --git a/libavformat/icecast.c b/libavformat/icecast.c index 38af16b99..b06c53cab 100644 --- a/libavformat/icecast.c +++ b/libavformat/icecast.c @@ -43,6 +43,7 @@ typedef struct IcecastContext { int public; char *url; char *user_agent; + int tls; } IcecastContext; #define DEFAULT_ICE_USER "source" @@ -62,6 +63,7 @@ static const AVOption options[] = { { "password", "set password", OFFSET(pass), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "content_type", "set content-type, MUST be set if not audio/mpeg", OFFSET(content_type), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "legacy_icecast", "use legacy SOURCE method, for Icecast < v2.4", OFFSET(legacy_icecast), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, + { "tls", "use a TLS connection", OFFSET(tls), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, { NULL } }; @@ -162,7 +164,9 @@ static int icecast_open(URLContext *h, const char *uri, int flags) } // Build new URI for passing to http protocol - ff_url_join(h_url, sizeof(h_url), "http", auth, host, port, "%s", path); + ff_url_join(h_url, sizeof(h_url), + s->tls ? "https" : "http", + auth, host, port, "%s", path); // Finally open http proto handler ret = ffurl_open_whitelist(&s->hd, h_url, AVIO_FLAG_READ_WRITE, NULL, &opt_dict, h->protocol_whitelist, h->protocol_blacklist, h); diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 775fc0d51..f33b7ba93 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -998,6 +998,8 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, if (tlen <= 0) goto seek; + if (dlen / 32768 > tlen) + goto seek; av_fast_malloc(&uncompressed_buffer, &uncompressed_buffer_size, dlen); if (!uncompressed_buffer) { @@ -1160,7 +1162,7 @@ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta *extra_meta) av_dict_set(&st->metadata, "comment", apic->type, 0); - av_init_packet(&st->attached_pic); + av_packet_unref(&st->attached_pic); st->attached_pic.buf = apic->buf; st->attached_pic.data = apic->buf->data; st->attached_pic.size = apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE; diff --git a/libavformat/img2.c b/libavformat/img2.c index d243d6c12..6bdd7efe2 100644 --- a/libavformat/img2.c +++ b/libavformat/img2.c @@ -41,6 +41,7 @@ const IdStrMap ff_img_tags[] = { { AV_CODEC_ID_PBM, "pbm" }, { AV_CODEC_ID_PAM, "pam" }, { AV_CODEC_ID_PFM, "pfm" }, + { AV_CODEC_ID_CRI, "cri" }, { AV_CODEC_ID_ALIAS_PIX, "pix" }, { AV_CODEC_ID_DDS, "dds" }, { AV_CODEC_ID_MPEG1VIDEO, "mpg1-img" }, @@ -55,6 +56,7 @@ const IdStrMap ff_img_tags[] = { { AV_CODEC_ID_TIFF, "dng" }, { AV_CODEC_ID_SGI, "sgi" }, { AV_CODEC_ID_PTX, "ptx" }, + { AV_CODEC_ID_PHOTOCD, "pcd" }, { AV_CODEC_ID_PCX, "pcx" }, { AV_CODEC_ID_QDRAW, "pic" }, { AV_CODEC_ID_QDRAW, "pct" }, diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index ee7ceed08..65e3c9b1a 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -220,8 +220,10 @@ int ff_img_read_header(AVFormatContext *s1) avpriv_set_pts_info(st, 64, 1, 1000000000); } else if (s->ts_from_file) avpriv_set_pts_info(st, 64, 1, 1); - else + else { avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num); + st->avg_frame_rate = s->framerate; + } if (s->width && s->height) { st->codecpar->width = s->width; @@ -379,9 +381,10 @@ int ff_img_read_header(AVFormatContext *s1) * as a dictionary, so it can be used by filters like 'drawtext'. */ static int add_filename_as_pkt_side_data(char *filename, AVPacket *pkt) { - int metadata_len, ret; AVDictionary *d = NULL; char *packed_metadata = NULL; + buffer_size_t metadata_len; + int ret; av_dict_set(&d, "lavf.image2dec.source_path", filename, 0); av_dict_set(&d, "lavf.image2dec.source_basename", av_basename(filename), 0); @@ -684,6 +687,17 @@ static int bmp_probe(const AVProbeData *p) return AVPROBE_SCORE_EXTENSION / 4; } +static int cri_probe(const AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if ( AV_RL32(b) == 1 + && AV_RL32(b + 4) == 4 + && AV_RN32(b + 8) == AV_RN32("DVCC")) + return AVPROBE_SCORE_MAX - 1; + return 0; +} + static int dds_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -804,7 +818,7 @@ static int jpeg_probe(const AVProbeData *p) return AVPROBE_SCORE_EXTENSION + 1; if (state == SOS) return AVPROBE_SCORE_EXTENSION / 2; - return AVPROBE_SCORE_EXTENSION / 8; + return AVPROBE_SCORE_EXTENSION / 8 + 1; } static int jpegls_probe(const AVProbeData *p) @@ -980,7 +994,7 @@ static inline int pnm_probe(const AVProbeData *p) static int pbm_probe(const AVProbeData *p) { - return pnm_magic_check(p, 1) || pnm_magic_check(p, 4) ? pnm_probe(p) : 0; + return pnm_magic_check(p, 1) || pnm_magic_check(p, 4) || pnm_magic_check(p, 22) || pnm_magic_check(p, 54) ? pnm_probe(p) : 0; } static inline int pgmx_probe(const AVProbeData *p) @@ -1000,6 +1014,14 @@ static int pgmyuv_probe(const AVProbeData *p) // custom FFmpeg format recognized return ret && av_match_ext(p->filename, "pgmyuv") ? ret : 0; } +static int pgx_probe(const AVProbeData *p) +{ + const uint8_t *b = p->buf; + if (!memcmp(b, "PG ML ", 6)) + return AVPROBE_SCORE_EXTENSION + 1; + return 0; +} + static int ppm_probe(const AVProbeData *p) { return pnm_magic_check(p, 3) || pnm_magic_check(p, 6) ? pnm_probe(p) : 0; @@ -1010,6 +1032,16 @@ static int pam_probe(const AVProbeData *p) return pnm_magic_check(p, 7) ? pnm_probe(p) : 0; } +static int xbm_probe(const AVProbeData *p) +{ + if (!memcmp(p->buf, "/* XBM X10 format */", 20)) + return AVPROBE_SCORE_MAX; + + if (!memcmp(p->buf, "#define", 7)) + return AVPROBE_SCORE_MAX - 1; + return 0; +} + static int xpm_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -1062,6 +1094,17 @@ static int gif_probe(const AVProbeData *p) return AVPROBE_SCORE_MAX - 1; } +static int photocd_probe(const AVProbeData *p) +{ + if (!memcmp(p->buf, "PCD_OPA", 7)) + return AVPROBE_SCORE_MAX - 1; + + if (p->buf_size < 0x807 || memcmp(p->buf + 0x800, "PCD_IPI", 7)) + return 0; + + return AVPROBE_SCORE_MAX - 1; +} + #define IMAGEAUTO_DEMUXER(imgname, codecid)\ static const AVClass imgname ## _class = {\ .class_name = AV_STRINGIFY(imgname) " demuxer",\ @@ -1082,6 +1125,7 @@ AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\ }; IMAGEAUTO_DEMUXER(bmp, AV_CODEC_ID_BMP) +IMAGEAUTO_DEMUXER(cri, AV_CODEC_ID_CRI) IMAGEAUTO_DEMUXER(dds, AV_CODEC_ID_DDS) IMAGEAUTO_DEMUXER(dpx, AV_CODEC_ID_DPX) IMAGEAUTO_DEMUXER(exr, AV_CODEC_ID_EXR) @@ -1094,6 +1138,8 @@ IMAGEAUTO_DEMUXER(pbm, AV_CODEC_ID_PBM) IMAGEAUTO_DEMUXER(pcx, AV_CODEC_ID_PCX) IMAGEAUTO_DEMUXER(pgm, AV_CODEC_ID_PGM) IMAGEAUTO_DEMUXER(pgmyuv, AV_CODEC_ID_PGMYUV) +IMAGEAUTO_DEMUXER(pgx, AV_CODEC_ID_PGX) +IMAGEAUTO_DEMUXER(photocd, AV_CODEC_ID_PHOTOCD) IMAGEAUTO_DEMUXER(pictor, AV_CODEC_ID_PICTOR) IMAGEAUTO_DEMUXER(png, AV_CODEC_ID_PNG) IMAGEAUTO_DEMUXER(ppm, AV_CODEC_ID_PPM) @@ -1104,5 +1150,6 @@ IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST) IMAGEAUTO_DEMUXER(svg, AV_CODEC_ID_SVG) IMAGEAUTO_DEMUXER(tiff, AV_CODEC_ID_TIFF) IMAGEAUTO_DEMUXER(webp, AV_CODEC_ID_WEBP) +IMAGEAUTO_DEMUXER(xbm, AV_CODEC_ID_XBM) IMAGEAUTO_DEMUXER(xpm, AV_CODEC_ID_XPM) IMAGEAUTO_DEMUXER(xwd, AV_CODEC_ID_XWD) diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c index b303d3823..0f7a21ffa 100644 --- a/libavformat/img2enc.c +++ b/libavformat/img2enc.c @@ -260,7 +260,7 @@ static const AVClass img2mux_class = { AVOutputFormat ff_image2_muxer = { .name = "image2", .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"), - .extensions = "bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png," + .extensions = "bmp,dpx,exr,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pfm,pgm,pgmyuv,png," "ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,im24," "sunras,xbm,xface,pix,y", .priv_data_size = sizeof(VideoMuxData), diff --git a/libavformat/imx.c b/libavformat/imx.c new file mode 100644 index 000000000..22fca0bdc --- /dev/null +++ b/libavformat/imx.c @@ -0,0 +1,168 @@ +/* + * Simbiosis game demuxer + * + * Copyright (C) 2021 Paul B Mahol + * + * 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 "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/avassert.h" +#include "libavutil/internal.h" + +#define IMX_TAG MKTAG('I', 'M', 'A', 'X') + +typedef struct SimbiosisIMXDemuxContext { + uint8_t pal[AVPALETTE_SIZE]; + int pal_changed; + int64_t first_video_packet_pos; +} SimbiosisIMXDemuxContext; + +static int simbiosis_imx_probe(const AVProbeData *p) +{ + if (AV_RL32(p->buf) != IMX_TAG) + return 0; + if (AV_RN32(p->buf+4) == 0) + return 0; + if (AV_RN16(p->buf+8) == 0) + return 0; + if (AV_RL16(p->buf+10) != 0x102) + return 0; + + return AVPROBE_SCORE_EXTENSION + 10; +} + +static int simbiosis_imx_read_header(AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + AVStream *vst, *ast; + int rate; + + vst = avformat_new_stream(s, NULL); + ast = avformat_new_stream(s, NULL); + if (!vst || !ast) + return AVERROR(ENOMEM); + + avio_skip(pb, 4); + + vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + vst->codecpar->codec_tag = 0; + vst->codecpar->format = AV_PIX_FMT_PAL8; + vst->codecpar->codec_id = AV_CODEC_ID_SIMBIOSIS_IMX; + vst->start_time = 0; + vst->duration = + vst->nb_frames = avio_rl32(pb); + rate = avio_rl16(pb); + avio_skip(pb, 12); + + avpriv_set_pts_info(vst, 64, 1, rate); + + ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + ast->codecpar->codec_tag = 0; + ast->codecpar->codec_id = AV_CODEC_ID_PCM_U8; + ast->codecpar->channels = 1; + ast->codecpar->channel_layout = AV_CH_LAYOUT_MONO; + ast->codecpar->sample_rate = 22050; + ast->start_time = 0; + + avpriv_set_pts_info(ast, 64, 1, 22050); + + return 0; +} + +static int simbiosis_imx_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVIOContext *pb = s->pb; + SimbiosisIMXDemuxContext *imx = s->priv_data; + uint32_t chunk_size, chunk_type; + int64_t pos = avio_tell(pb); + int ret, idx = -1; + +retry: + if (avio_feof(pb)) + return AVERROR_EOF; + + chunk_size = avio_rl32(pb); + chunk_type = avio_rl32(pb); + + switch (chunk_type) { + case 0xAAFF: + return AVERROR_EOF; + case 0xAA99: + idx = 1; + break; + case 0xAA97: + idx = 0; + if (!imx->first_video_packet_pos) + imx->first_video_packet_pos = pos; + break; + case 0xAA98: + if (chunk_size > 256 * 3) + return AVERROR_INVALIDDATA; + for (int i = 0; i < chunk_size / 3; i++) { + unsigned r = avio_r8(pb) << 18; + unsigned g = avio_r8(pb) << 10; + unsigned b = avio_r8(pb) << 2; + + AV_WL32(imx->pal + i * 4, (0xFFU << 24) | r | g | b); + } + imx->pal_changed = 1; + idx = -1; + break; + default: + return AVERROR_INVALIDDATA; + } + + if (idx == -1) + goto retry; + + ret = av_get_packet(pb, pkt, chunk_size); + if (ret < 0) + return ret; + + if (imx->pal_changed && idx == 0) { + uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, + AVPALETTE_SIZE); + if (!pal) + return AVERROR(ENOMEM); + memcpy(pal, imx->pal, AVPALETTE_SIZE); + imx->pal_changed = 0; + if (pos <= imx->first_video_packet_pos) + pkt->flags |= AV_PKT_FLAG_KEY; + } else if (idx == 1) { + pkt->flags |= AV_PKT_FLAG_KEY; + } + + pkt->pos = pos; + pkt->stream_index = idx; + pkt->duration = idx ? chunk_size : 1; + + return ret; +} + +AVInputFormat ff_simbiosis_imx_demuxer = { + .name = "simbiosis_imx", + .long_name = NULL_IF_CONFIG_SMALL("Simbiosis Interactive IMX"), + .priv_data_size = sizeof(SimbiosisIMXDemuxContext), + .read_probe = simbiosis_imx_probe, + .read_header = simbiosis_imx_read_header, + .read_packet = simbiosis_imx_read_packet, + .extensions = "imx", + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/internal.h b/libavformat/internal.h index 17a6ab07d..8ed4ee1c9 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -73,8 +73,8 @@ struct AVFormatInternal { * not decoded, for example to get the codec parameters in MPEG * streams. */ - struct AVPacketList *packet_buffer; - struct AVPacketList *packet_buffer_end; + struct PacketList *packet_buffer; + struct PacketList *packet_buffer_end; /* av_seek_frame() support */ int64_t data_offset; /**< offset of the first packet */ @@ -85,13 +85,19 @@ struct AVFormatInternal { * be identified, as parsing cannot be done without knowing the * codec. */ - struct AVPacketList *raw_packet_buffer; - struct AVPacketList *raw_packet_buffer_end; + struct PacketList *raw_packet_buffer; + struct PacketList *raw_packet_buffer_end; /** * Packets split by the parser get queued here. */ - struct AVPacketList *parse_queue; - struct AVPacketList *parse_queue_end; + AVPacket *parse_pkt; + struct PacketList *parse_queue; + struct PacketList *parse_queue_end; + + /** + * Used to hold temporary packets. + */ + AVPacket *pkt; /** * Remaining size available for raw_packet_buffer, in bytes. */ @@ -142,6 +148,11 @@ struct AVFormatInternal { * Prefer the codec framerate for avg_frame_rate computation. */ int prefer_codec_framerate; + + /** + * Set if chapter ids are strictly monotonic. + */ + int chapter_ids_monotonic; }; struct AVStreamInternal { @@ -191,6 +202,153 @@ struct AVStreamInternal { int is_intra_only; FFFrac *priv_pts; + +#define MAX_STD_TIMEBASES (30*12+30+3+6) + /** + * Stream information used internally by avformat_find_stream_info() + */ + struct { + int64_t last_dts; + int64_t duration_gcd; + int duration_count; + int64_t rfps_duration_sum; + double (*duration_error)[2][MAX_STD_TIMEBASES]; + int64_t codec_info_duration; + int64_t codec_info_duration_fields; + int frame_delay_evidence; + + /** + * 0 -> decoder has not been searched for yet. + * >0 -> decoder found + * <0 -> decoder with codec_id == -found_decoder has not been found + */ + int found_decoder; + + int64_t last_duration; + + /** + * Those are used for average framerate estimation. + */ + int64_t fps_first_dts; + int fps_first_dts_idx; + int64_t fps_last_dts; + int fps_last_dts_idx; + + } *info; + + int64_t interleaver_chunk_size; + int64_t interleaver_chunk_duration; + + /** + * stream probing state + * -1 -> probing finished + * 0 -> no probing requested + * rest -> perform probing with request_probe being the minimum score to accept. + */ + int request_probe; + /** + * Indicates that everything up to the next keyframe + * should be discarded. + */ + int skip_to_keyframe; + + /** + * Number of samples to skip at the start of the frame decoded from the next packet. + */ + int skip_samples; + + /** + * If not 0, the number of samples that should be skipped from the start of + * the stream (the samples are removed from packets with pts==0, which also + * assumes negative timestamps do not happen). + * Intended for use with formats such as mp3 with ad-hoc gapless audio + * support. + */ + int64_t start_skip_samples; + + /** + * If not 0, the first audio sample that should be discarded from the stream. + * This is broken by design (needs global sample count), but can't be + * avoided for broken by design formats such as mp3 with ad-hoc gapless + * audio support. + */ + int64_t first_discard_sample; + + /** + * The sample after last sample that is intended to be discarded after + * first_discard_sample. Works on frame boundaries only. Used to prevent + * early EOF if the gapless info is broken (considered concatenated mp3s). + */ + int64_t last_discard_sample; + + /** + * Number of internally decoded frames, used internally in libavformat, do not access + * its lifetime differs from info which is why it is not in that structure. + */ + int nb_decoded_frames; + + /** + * Timestamp offset added to timestamps before muxing + */ + int64_t mux_ts_offset; + + /** + * Internal data to check for wrapping of the time stamp + */ + int64_t pts_wrap_reference; + + /** + * Options for behavior, when a wrap is detected. + * + * Defined by AV_PTS_WRAP_ values. + * + * If correction is enabled, there are two possibilities: + * If the first time stamp is near the wrap point, the wrap offset + * will be subtracted, which will create negative time stamps. + * Otherwise the offset will be added. + */ + int pts_wrap_behavior; + + /** + * Internal data to prevent doing update_initial_durations() twice + */ + int update_initial_durations_done; + +#define MAX_REORDER_DELAY 16 + + /** + * Internal data to generate dts from pts + */ + int64_t pts_reorder_error[MAX_REORDER_DELAY+1]; + uint8_t pts_reorder_error_count[MAX_REORDER_DELAY+1]; + + int64_t pts_buffer[MAX_REORDER_DELAY+1]; + + /** + * Internal data to analyze DTS and detect faulty mpeg streams + */ + int64_t last_dts_for_order_check; + uint8_t dts_ordered; + uint8_t dts_misordered; + + /** + * Internal data to inject global side data + */ + int inject_global_side_data; + + /** + * display aspect ratio (0 if unknown) + * - encoding: unused + * - decoding: Set by libavformat to calculate sample_aspect_ratio internally + */ + AVRational display_aspect_ratio; + + AVProbeData probe_data; + + /** + * last packet in packet_buffer for this stream when muxing. + */ + struct PacketList *last_in_packet_buffer; }; #ifdef __GNUC__ @@ -208,8 +366,6 @@ do {\ } while(0) #endif -struct tm *ff_brktimegm(time_t secs, struct tm *tm); - /** * Automatically create sub-directories * @@ -399,7 +555,11 @@ void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance); * * @return AVChapter or NULL on error */ +#if FF_API_CHAPTER_ID_INT AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, +#else +AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, +#endif int64_t start, int64_t end, const char *title); /** @@ -710,15 +870,12 @@ int ff_bprint_to_codecpar_extradata(AVCodecParameters *par, struct AVBPrint *buf /** * Find the next packet in the interleaving queue for the given stream. - * The pkt parameter is filled in with the queued packet, including - * references to the data (which the caller is not allowed to keep or - * modify). * - * @return 0 if a packet was found, a negative value if no packet was found + * @return a pointer to a packet if one was found, NULL otherwise. */ -int ff_interleaved_peek(AVFormatContext *s, int stream, - AVPacket *pkt, int add_offset); +const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream); +int ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset); int ff_lock_avformat(void); int ff_unlock_avformat(void); @@ -730,48 +887,6 @@ int ff_unlock_avformat(void); */ void ff_format_set_url(AVFormatContext *s, char *url); -#define FF_PACKETLIST_FLAG_REF_PACKET (1 << 0) /**< Create a new reference for the packet instead of - transferring the ownership of the existing one to the - list. */ - -/** - * Append an AVPacket to the list. - * - * @param head List head element - * @param tail List tail element - * @param pkt The packet being appended. The data described in it will - * be made reference counted if it isn't already. - * @param flags Any combination of FF_PACKETLIST_FLAG_* flags - * @return 0 on success, negative AVERROR value on failure. On failure, - the list is unchanged - */ -int ff_packet_list_put(AVPacketList **head, AVPacketList **tail, - AVPacket *pkt, int flags); - -/** - * Remove the oldest AVPacket in the list and return it. - * The behaviour is undefined if the packet list is empty. - * - * @note The pkt will be overwritten completely. The caller owns the - * packet and must unref it by itself. - * - * @param head List head element - * @param tail List tail element - * @param pkt Pointer to an AVPacket struct - * @return 0 on success. Success is guaranteed - * if the packet list is not empty. - */ -int ff_packet_list_get(AVPacketList **head, AVPacketList **tail, - AVPacket *pkt); - -/** - * Wipe the list and unref all the packets in it. - * - * @param head List head element - * @param tail List tail element - */ -void ff_packet_list_free(AVPacketList **head, AVPacketList **tail); - void avpriv_register_devices(const AVOutputFormat * const o[], const AVInputFormat * const i[]); #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index 137c85770..3234d591d 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -661,8 +661,10 @@ static int ipmovie_read_header(AVFormatContext *s) ipmovie->palette[i] = 0xFFU << 24; /* process the first chunk which should be CHUNK_INIT_VIDEO */ - if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO) + if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO) { + av_packet_unref(&pkt); return AVERROR_INVALIDDATA; + } /* peek ahead to the next chunk-- if it is an init audio chunk, process * it; if it is the first video chunk, this is a silent file */ @@ -674,8 +676,10 @@ static int ipmovie_read_header(AVFormatContext *s) if (chunk_type == CHUNK_VIDEO) ipmovie->audio_type = AV_CODEC_ID_NONE; /* no audio */ - else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO) + else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO) { + av_packet_unref(&pkt); return AVERROR_INVALIDDATA; + } /* initialize the stream decoders */ st = avformat_new_stream(s, NULL); diff --git a/libavformat/ipudec.c b/libavformat/ipudec.c new file mode 100644 index 000000000..df53df00d --- /dev/null +++ b/libavformat/ipudec.c @@ -0,0 +1,89 @@ +/* + * IPU video demuxer + * Copyright (c) 2020 Paul B Mahol + * + * 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 "avformat.h" +#include "internal.h" +#include "avio_internal.h" +#include "rawdec.h" + +#include "libavutil/intreadwrite.h" +#include "libavcodec/internal.h" + +static int ipu_read_probe(const AVProbeData *p) +{ + if (AV_RB32(p->buf) != MKBETAG('i', 'p', 'u', 'm')) + return 0; + + if (AV_RL32(p->buf + 4) == 0) + return 0; + + if (AV_RL16(p->buf + 8) == 0) + return 0; + + if (AV_RL16(p->buf + 10) == 0) + return 0; + + if (AV_RL32(p->buf + 12) == 0) + return 0; + + return AVPROBE_SCORE_MAX; +} + +static int ipu_read_header(AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + AVStream *st = avformat_new_stream(s, NULL); + + if (!st) + return AVERROR(ENOMEM); + avio_skip(pb, 8); + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = AV_CODEC_ID_IPU; + st->codecpar->width = avio_rl16(pb); + st->codecpar->height = avio_rl16(pb); + st->start_time = 0; + st->duration = + st->nb_frames = avio_rl32(pb); + st->need_parsing = AVSTREAM_PARSE_FULL_RAW; + avpriv_set_pts_info(st, 64, 1, 25); + + return 0; +} + +static const AVClass ipu_demuxer_class = { + .class_name = "ipu demuxer", + .item_name = av_default_item_name, + .option = ff_raw_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVInputFormat ff_ipu_demuxer = { + .name = "ipu", + .long_name = NULL_IF_CONFIG_SMALL("raw IPU Video"), + .read_probe = ipu_read_probe, + .read_header = ipu_read_header, + .read_packet = ff_raw_read_partial_packet, + .extensions = "ipu", + .flags = AVFMT_GENERIC_INDEX, + .raw_codec_id = AV_CODEC_ID_IPU, + .priv_data_size = sizeof(FFRawDemuxerContext), + .priv_class = &ipu_demuxer_class, +}; diff --git a/libavformat/ircamdec.c b/libavformat/ircamdec.c index 17bfb4ed1..db09f606c 100644 --- a/libavformat/ircamdec.c +++ b/libavformat/ircamdec.c @@ -66,12 +66,12 @@ static int ircam_read_header(AVFormatContext *s) } if (le == 1) { - sample_rate = av_int2float(avio_rl32(s->pb)); + sample_rate = lrintf(av_int2float(avio_rl32(s->pb))); channels = avio_rl32(s->pb); tag = avio_rl32(s->pb); tags = ff_codec_ircam_le_tags; } else if (le == 0) { - sample_rate = av_int2float(avio_rb32(s->pb)); + sample_rate = lrintf(av_int2float(avio_rb32(s->pb))); channels = avio_rb32(s->pb); tag = avio_rb32(s->pb); tags = ff_codec_ircam_be_tags; diff --git a/libavformat/isom.c b/libavformat/isom.c index 44c7b1303..df9877914 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -72,312 +72,6 @@ const AVCodecTag ff_mp4_obj_type[] = { { AV_CODEC_ID_NONE , 0 }, }; -const AVCodecTag ff_codec_movvideo_tags[] = { -/* { AV_CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */ - - { AV_CODEC_ID_RAWVIDEO, MKTAG('r', 'a', 'w', ' ') }, /* uncompressed RGB */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', '2') }, /* uncompressed YUV422 */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') }, /* uncompressed 8-bit 4:2:2 */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') }, /* same as 2VUY but byte-swapped */ - - { AV_CODEC_ID_RAWVIDEO, MKTAG('L', '5', '5', '5') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('L', '5', '6', '5') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '5', '6', '5') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('2', '4', 'B', 'G') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '1', '6', 'g') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '4', '8', 'r') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '6', '4', 'a') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'b', 'g') }, /* BOXX */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'r', 'g') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'y', 'v') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('N', 'O', '1', '6') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('D', 'V', 'O', 'O') }, /* Digital Voodoo SD 8 Bit */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', '2', '0') }, /* Radius DV YUV PAL */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', '1', '1') }, /* Radius DV YUV NTSC */ - - { AV_CODEC_ID_R10K, MKTAG('R', '1', '0', 'k') }, /* uncompressed 10-bit RGB */ - { AV_CODEC_ID_R10K, MKTAG('R', '1', '0', 'g') }, /* uncompressed 10-bit RGB */ - { AV_CODEC_ID_R210, MKTAG('r', '2', '1', '0') }, /* uncompressed 10-bit RGB */ - { AV_CODEC_ID_AVUI, MKTAG('A', 'V', 'U', 'I') }, /* AVID Uncompressed deinterleaved UYVY422 */ - { AV_CODEC_ID_AVRP, MKTAG('A', 'V', 'r', 'p') }, /* Avid 1:1 10-bit RGB Packer */ - { AV_CODEC_ID_AVRP, MKTAG('S', 'U', 'D', 'S') }, /* Avid DS Uncompressed */ - { AV_CODEC_ID_V210, MKTAG('v', '2', '1', '0') }, /* uncompressed 10-bit 4:2:2 */ - { AV_CODEC_ID_V210, MKTAG('b', 'x', 'y', '2') }, /* BOXX 10-bit 4:2:2 */ - { AV_CODEC_ID_V308, MKTAG('v', '3', '0', '8') }, /* uncompressed 8-bit 4:4:4 */ - { AV_CODEC_ID_V408, MKTAG('v', '4', '0', '8') }, /* uncompressed 8-bit 4:4:4:4 */ - { AV_CODEC_ID_V410, MKTAG('v', '4', '1', '0') }, /* uncompressed 10-bit 4:4:4 */ - { AV_CODEC_ID_Y41P, MKTAG('Y', '4', '1', 'P') }, /* uncompressed 12-bit 4:1:1 */ - { AV_CODEC_ID_YUV4, MKTAG('y', 'u', 'v', '4') }, /* libquicktime packed yuv420p */ - { AV_CODEC_ID_TARGA_Y216, MKTAG('Y', '2', '1', '6') }, - - { AV_CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */ - { AV_CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */ - { AV_CODEC_ID_AVRN , MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */ -/* { AV_CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, *//* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */ - { AV_CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') }, /* Motion JPEG OpenDML */ - { AV_CODEC_ID_MJPEGB, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */ - - { AV_CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */ - { AV_CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */ - { AV_CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/ - { AV_CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, /* Sorenson Video v3 */ - - { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, - { AV_CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */ - { AV_CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, - { AV_CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') }, /* experimental: 3IVX files before ivx D4 4.5.1 */ - - { AV_CODEC_ID_H263, MKTAG('h', '2', '6', '3') }, /* H.263 */ - { AV_CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, /* H.263 ?? works */ - - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') }, /* DVCPRO PAL produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') }, /* DVCPRO50 PAL produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') }, /* DVCPRO50 NTSC produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, /* AVID DV */ - { AV_CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', '1') }, /* AVID DV100 */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'q') }, /* DVCPRO HD 720p50 */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'p') }, /* DVCPRO HD 720p60 */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '1') }, - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '2') }, - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '4') }, - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '5') }, /* DVCPRO HD 50i produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '6') }, /* DVCPRO HD 60i produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '3') }, /* DVCPRO HD 30p produced by FCP */ - - { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */ - { AV_CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */ - { AV_CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */ - { AV_CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') }, /* Planar RGB (8BPS) */ - { AV_CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') }, /* Apple Graphics (SMC) */ - { AV_CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') }, /* Apple Animation (RLE) */ - { AV_CODEC_ID_SGIRLE, MKTAG('r', 'l', 'e', '1') }, /* SGI RLE 8-bit */ - { AV_CODEC_ID_MSRLE, MKTAG('W', 'R', 'L', 'E') }, - { AV_CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') }, /* QuickDraw */ - { AV_CODEC_ID_CDTOONS, MKTAG('Q', 'k', 'B', 'k') }, /* CDToons */ - - { AV_CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') }, - - { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') }, /* HEVC/H.265 which indicates parameter sets may be in ES */ - { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') }, /* HEVC/H.265 which indicates parameter sets shall not be in ES */ - { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', 'e') }, /* HEVC-based Dolby Vision derived from hev1 */ - /* dvh1 is handled within mov.c */ - - { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */ - { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '2') }, - { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') }, - { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '4') }, - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'p') }, /* AVC-Intra 50M 720p24/30/60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') }, /* AVC-Intra 50M 720p25/50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '2') }, /* AVC-Intra 50M 1080p25/50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '3') }, /* AVC-Intra 50M 1080p24/30/60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '5') }, /* AVC-Intra 50M 1080i50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '6') }, /* AVC-Intra 50M 1080i60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', 'p') }, /* AVC-Intra 100M 720p24/30/60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', 'q') }, /* AVC-Intra 100M 720p25/50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '2') }, /* AVC-Intra 100M 1080p25/50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '3') }, /* AVC-Intra 100M 1080p24/30/60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC-Intra 100M 1080i50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '6') }, /* AVC-Intra 100M 1080i60 */ - { AV_CODEC_ID_H264, MKTAG('A', 'V', 'i', 'n') }, /* AVC-Intra with implicit SPS/PPS */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', 'v', 'x') }, /* XAVC 10-bit 4:2:2 */ - { AV_CODEC_ID_H264, MKTAG('r', 'v', '6', '4') }, /* X-Com Radvision */ - { AV_CODEC_ID_H264, MKTAG('x', 'a', 'l', 'g') }, /* XAVC-L HD422 produced by FCP */ - { AV_CODEC_ID_H264, MKTAG('a', 'v', 'l', 'g') }, /* Panasonic P2 AVC-LongG */ - { AV_CODEC_ID_H264, MKTAG('d', 'v', 'a', '1') }, /* AVC-based Dolby Vision derived from avc1 */ - { AV_CODEC_ID_H264, MKTAG('d', 'v', 'a', 'v') }, /* AVC-based Dolby Vision derived from avc3 */ - - { AV_CODEC_ID_VP8, MKTAG('v', 'p', '0', '8') }, /* VP8 */ - { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') }, /* VP9 */ - { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') }, /* AV1 */ - - { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', ' ') }, - { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, /* Apple MPEG-1 Camcorder */ - { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */ - { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '1', 'v') }, /* CoreMedia CMVideoCodecType */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', '2', 'v', '1') }, /* Apple MPEG-2 Camcorder */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') }, /* MPEG-2 HDV 720p30 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG-2 HDV 1080i60 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* MPEG-2 HDV 1080i50 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '4') }, /* MPEG-2 HDV 720p24 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') }, /* MPEG-2 HDV 720p25 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') }, /* MPEG-2 HDV 1080p24 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') }, /* MPEG-2 HDV 1080p25 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') }, /* MPEG-2 HDV 1080p30 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '9') }, /* MPEG-2 HDV 720p60 JVC */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', 'a') }, /* MPEG-2 HDV 720p50 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG-2 IMX NTSC 525/60 50mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG-2 IMX PAL 625/50 50mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') }, /* MPEG-2 IMX NTSC 525/60 40mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'p') }, /* MPEG-2 IMX PAL 625/50 40mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') }, /* MPEG-2 IMX NTSC 525/60 30mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') }, /* MPEG-2 IMX PAL 625/50 30mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '1') }, /* XDCAM HD422 720p30 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '4') }, /* XDCAM HD422 720p24 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '5') }, /* XDCAM HD422 720p25 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '9') }, /* XDCAM HD422 720p60 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'a') }, /* XDCAM HD422 720p50 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'b') }, /* XDCAM HD422 1080i60 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'c') }, /* XDCAM HD422 1080i50 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'd') }, /* XDCAM HD422 1080p24 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'e') }, /* XDCAM HD422 1080p25 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'f') }, /* XDCAM HD422 1080p30 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '1') }, /* XDCAM EX 720p30 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '2') }, /* XDCAM HD 1080i60 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '3') }, /* XDCAM HD 1080i50 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '4') }, /* XDCAM EX 720p24 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '5') }, /* XDCAM EX 720p25 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '6') }, /* XDCAM HD 1080p24 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '7') }, /* XDCAM HD 1080p25 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '8') }, /* XDCAM HD 1080p30 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '9') }, /* XDCAM EX 720p60 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'a') }, /* XDCAM EX 720p50 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'b') }, /* XDCAM EX 1080i60 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'c') }, /* XDCAM EX 1080i50 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') }, /* XDCAM EX 1080p24 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') }, /* XDCAM EX 1080p25 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') }, /* XDCAM EX 1080p30 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', 'd') }, /* XDCAM HD 540p */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', '2') }, /* XDCAM HD422 540p */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') }, /* AVID IMX PAL */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '2', 'v') }, /* FCP5 */ - - { AV_CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */ - - { AV_CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') }, /* Truevision Targa */ - { AV_CODEC_ID_TIFF, MKTAG('t', 'i', 'f', 'f') }, /* TIFF embedded in MOV */ - { AV_CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, /* embedded gif files as frames (usually one "click to play movie" frame) */ - { AV_CODEC_ID_PNG, MKTAG('p', 'n', 'g', ' ') }, - { AV_CODEC_ID_PNG, MKTAG('M', 'N', 'G', ' ') }, - - { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') }, /* SMPTE RP 2025 */ - { AV_CODEC_ID_CAVS, MKTAG('a', 'v', 's', '2') }, - - { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, - { AV_CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') }, /* AVID DNxHD */ - { AV_CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'h') }, /* AVID DNxHR */ - { AV_CODEC_ID_H263, MKTAG('H', '2', '6', '3') }, - { AV_CODEC_ID_MSMPEG4V3, MKTAG('3', 'I', 'V', 'D') }, /* 3ivx DivX Doctor */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'V', '1', 'x') }, /* AVID 1:1x */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'u', 'p') }, - { AV_CODEC_ID_SGI, MKTAG('s', 'g', 'i', ' ') }, /* SGI */ - { AV_CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') }, /* DPX */ - { AV_CODEC_ID_EXR, MKTAG('e', 'x', 'r', ' ') }, /* OpenEXR */ - - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'h') }, /* Apple ProRes 422 High Quality */ - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'n') }, /* Apple ProRes 422 Standard Definition */ - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 's') }, /* Apple ProRes 422 LT */ - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'o') }, /* Apple ProRes 422 Proxy */ - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'h') }, /* Apple ProRes 4444 */ - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'x') }, /* Apple ProRes 4444 XQ */ - { AV_CODEC_ID_FLIC, MKTAG('f', 'l', 'i', 'c') }, - - { AV_CODEC_ID_AIC, MKTAG('i', 'c', 'o', 'd') }, - - { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', '1') }, - { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', '5') }, - { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'Y') }, - { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'A') }, - { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'M') }, - - { AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', '3') }, - { AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', 'I') }, - - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'R', '0') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'R', 'A') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'R', 'G') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'Y', '2') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'Y', '4') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'R', 'G') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'R', 'A') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'G', '0') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', '0') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', '2') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', '4') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', 'A') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '2', 'R', 'A') }, - { AV_CODEC_ID_MAGICYUV, MKTAG('M', '2', 'R', 'G') }, - - { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '0') }, - { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '1') }, - { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '2') }, - { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '3') }, - { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '4') }, - { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '5') }, - { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '6') }, - { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '7') }, - - { AV_CODEC_ID_PIXLET, MKTAG('p', 'x', 'l', 't') }, - - { AV_CODEC_ID_NOTCHLC, MKTAG('n', 'c', 'l', 'c') }, - - { AV_CODEC_ID_NONE, 0 }, -}; - -const AVCodecTag ff_codec_movaudio_tags[] = { - { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, - { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F */ - { AV_CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') }, /* Nero Recode */ - { AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, - { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') }, - { AV_CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */ - { AV_CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */ - { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'c') }, /* DTS formats prior to DTS-HD */ - { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'h') }, /* DTS-HD audio formats */ - { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'l') }, /* DTS-HD Lossless formats */ - { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'e') }, /* DTS Express */ - { AV_CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non-standard */ - { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F (only valid in ISOBMFF) */ - { AV_CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') }, - { AV_CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') }, - { AV_CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') }, - { AV_CODEC_ID_ILBC, MKTAG('i', 'l', 'b', 'c') }, - { AV_CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, - { AV_CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, - { AV_CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') }, - { AV_CODEC_ID_MP2, MKTAG('.', 'm', 'p', '2') }, - { AV_CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') }, - { AV_CODEC_ID_MP3, MKTAG('m', 'p', '3', ' ') }, /* vlc */ - { AV_CODEC_ID_MP3, 0x6D730055 }, - { AV_CODEC_ID_NELLYMOSER, MKTAG('n', 'm', 'o', 's') }, /* Flash Media Server */ - { AV_CODEC_ID_NELLYMOSER, MKTAG('N', 'E', 'L', 'L') }, /* Perian */ - { AV_CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, - { AV_CODEC_ID_PCM_F32BE, MKTAG('f', 'l', '3', '2') }, - { AV_CODEC_ID_PCM_F32LE, MKTAG('f', 'l', '3', '2') }, - { AV_CODEC_ID_PCM_F64BE, MKTAG('f', 'l', '6', '4') }, - { AV_CODEC_ID_PCM_F64LE, MKTAG('f', 'l', '6', '4') }, - { AV_CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, - { AV_CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, - { AV_CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, - { AV_CODEC_ID_PCM_S16BE, MKTAG('l', 'p', 'c', 'm') }, - { AV_CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') }, - { AV_CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') }, - { AV_CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') }, - { AV_CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') }, - { AV_CODEC_ID_PCM_S32LE, MKTAG('i', 'n', '3', '2') }, - { AV_CODEC_ID_PCM_S8, MKTAG('s', 'o', 'w', 't') }, - { AV_CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, - { AV_CODEC_ID_PCM_U8, MKTAG('N', 'O', 'N', 'E') }, - { AV_CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'p') }, - { AV_CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'q') }, - { AV_CODEC_ID_QCELP, MKTAG('s', 'q', 'c', 'p') }, /* ISO Media fourcc */ - { AV_CODEC_ID_QDM2, MKTAG('Q', 'D', 'M', '2') }, - { AV_CODEC_ID_QDMC, MKTAG('Q', 'D', 'M', 'C') }, - { AV_CODEC_ID_SPEEX, MKTAG('s', 'p', 'e', 'x') }, /* Flash Media Server */ - { AV_CODEC_ID_SPEEX, MKTAG('S', 'P', 'X', 'N') }, /* ZygoAudio (quality 10 mode) */ - { AV_CODEC_ID_EVRC, MKTAG('s', 'e', 'v', 'c') }, /* 3GPP2 */ - { AV_CODEC_ID_SMV, MKTAG('s', 's', 'm', 'v') }, /* 3GPP2 */ - { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') }, /* nonstandard */ - { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') }, /* mp4ra.org */ - { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') }, /* mp4ra.org */ - { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') }, /* MPEG-H 3D Audio bitstream */ - { AV_CODEC_ID_NONE, 0 }, -}; - const AVCodecTag ff_codec_movsubtitle_tags[] = { { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'e', 'x', 't') }, { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') }, @@ -395,25 +89,145 @@ const AVCodecTag ff_codec_movdata_tags[] = { /* http://developer.apple.com/documentation/mac/Text/Text-368.html */ /* deprecated by putting the code as 3*5 bits ASCII */ static const char mov_mdhd_language_map[][4] = { - /* 0-9 */ - "eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor", - "heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/, - "urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav", "", - "fo ", "", "rus", "chi", "", "iri", "alb", "ron", "ces", "slk", - "slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze", - /*?*/ - "aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon", "", "pus", - "kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj", - "pa ", "ori", "mal", "kan", "tam", "tel", "", "bur", "khm", "lao", - /* roman? arabic? */ - "vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa", - /*==rundi?*/ - "", "run", "", "mlg", "epo", "", "", "", "", "", - /* 100 */ - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "wel", "baq", - "cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav" + "eng", /* 0 English */ + "fra", /* 1 French */ + "ger", /* 2 German */ + "ita", /* 3 Italian */ + "dut", /* 4 Dutch */ + "sve", /* 5 Swedish */ + "spa", /* 6 Spanish */ + "dan", /* 7 Danish */ + "por", /* 8 Portuguese */ + "nor", /* 9 Norwegian */ + "heb", /* 10 Hebrew */ + "jpn", /* 11 Japanese */ + "ara", /* 12 Arabic */ + "fin", /* 13 Finnish */ + "gre", /* 14 Greek */ + "ice", /* 15 Icelandic */ + "mlt", /* 16 Maltese */ + "tur", /* 17 Turkish */ + "hr ", /* 18 Croatian */ + "chi", /* 19 Traditional Chinese */ + "urd", /* 20 Urdu */ + "hin", /* 21 Hindi */ + "tha", /* 22 Thai */ + "kor", /* 23 Korean */ + "lit", /* 24 Lithuanian */ + "pol", /* 25 Polish */ + "hun", /* 26 Hungarian */ + "est", /* 27 Estonian */ + "lav", /* 28 Latvian */ + "", /* 29 Sami */ + "fo ", /* 30 Faroese */ + "", /* 31 Farsi */ + "rus", /* 32 Russian */ + "chi", /* 33 Simplified Chinese */ + "", /* 34 Flemish */ + "iri", /* 35 Irish */ + "alb", /* 36 Albanian */ + "ron", /* 37 Romanian */ + "ces", /* 38 Czech */ + "slk", /* 39 Slovak */ + "slv", /* 40 Slovenian */ + "yid", /* 41 Yiddish */ + "sr ", /* 42 Serbian */ + "mac", /* 43 Macedonian */ + "bul", /* 44 Bulgarian */ + "ukr", /* 45 Ukrainian */ + "bel", /* 46 Belarusian */ + "uzb", /* 47 Uzbek */ + "kaz", /* 48 Kazakh */ + "aze", /* 49 Azerbaijani */ + "aze", /* 50 AzerbaijanAr */ + "arm", /* 51 Armenian */ + "geo", /* 52 Georgian */ + "mol", /* 53 Moldavian */ + "kir", /* 54 Kirghiz */ + "tgk", /* 55 Tajiki */ + "tuk", /* 56 Turkmen */ + "mon", /* 57 Mongolian */ + "", /* 58 MongolianCyr */ + "pus", /* 59 Pashto */ + "kur", /* 60 Kurdish */ + "kas", /* 61 Kashmiri */ + "snd", /* 62 Sindhi */ + "tib", /* 63 Tibetan */ + "nep", /* 64 Nepali */ + "san", /* 65 Sanskrit */ + "mar", /* 66 Marathi */ + "ben", /* 67 Bengali */ + "asm", /* 68 Assamese */ + "guj", /* 69 Gujarati */ + "pa ", /* 70 Punjabi */ + "ori", /* 71 Oriya */ + "mal", /* 72 Malayalam */ + "kan", /* 73 Kannada */ + "tam", /* 74 Tamil */ + "tel", /* 75 Telugu */ + "", /* 76 Sinhala */ + "bur", /* 77 Burmese */ + "khm", /* 78 Khmer */ + "lao", /* 79 Lao */ + "vie", /* 80 Vietnamese */ + "ind", /* 81 Indonesian */ + "tgl", /* 82 Tagalog */ + "may", /* 83 MalayRoman */ + "may", /* 84 MalayArabic */ + "amh", /* 85 Amharic */ + "tir", /* 86 Galla */ + "orm", /* 87 Oromo */ + "som", /* 88 Somali */ + "swa", /* 89 Swahili */ + "", /* 90 Kinyarwanda */ + "run", /* 91 Rundi */ + "", /* 92 Nyanja */ + "mlg", /* 93 Malagasy */ + "epo", /* 94 Esperanto */ + "", /* 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 */ + "wel", /* 128 Welsh */ + "baq", /* 129 Basque */ + "cat", /* 130 Catalan */ + "lat", /* 131 Latin */ + "que", /* 132 Quechua */ + "grn", /* 133 Guarani */ + "aym", /* 134 Aymara */ + "tat", /* 135 Tatar */ + "uig", /* 136 Uighur */ + "dzo", /* 137 Dzongkha */ + "jav", /* 138 JavaneseRom */ }; int ff_mov_iso639_to_lang(const char lang[4], int mp4) @@ -604,45 +418,6 @@ static const MovChannelLayout mov_channel_layout[] = { { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, (137<<16) | 5}, // kCAFChannelLayoutTag_DVD_11 { 0, 0}, }; -#if 0 -int ff_mov_read_chan(AVFormatContext *s, AVStream *st, int64_t size) -{ - AVCodecContext *codec= st->codec; - uint32_t layout_tag; - AVIOContext *pb = s->pb; - const MovChannelLayout *layouts = mov_channel_layout; - - if (size < 12) - return AVERROR_INVALIDDATA; - - layout_tag = avio_rb32(pb); - size -= 4; - if (layout_tag == 0) { // kCAFChannelLayoutTag_UseChannelDescriptions - // Channel descriptions not implemented - av_log_ask_for_sample(s, "Unimplemented container channel layout.\n"); - avio_skip(pb, size); - return 0; - } - if (layout_tag == 0x10000) { // kCAFChannelLayoutTag_UseChannelBitmap - codec->channel_layout = avio_rb32(pb); - size -= 4; - avio_skip(pb, size); - return 0; - } - while (layouts->channel_layout) { - if (layout_tag == layouts->layout_tag) { - codec->channel_layout = layouts->channel_layout; - break; - } - layouts++; - } - if (!codec->channel_layout) - av_log(s, AV_LOG_WARNING, "Unknown container channel layout.\n"); - avio_skip(pb, size); - - return 0; -} -#endif void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout) { @@ -664,13 +439,3 @@ void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout) } avio_wb32(pb, 0); // mNumberChannelDescriptions } - -const struct AVCodecTag *avformat_get_mov_video_tags(void) -{ - return ff_codec_movvideo_tags; -} - -const struct AVCodecTag *avformat_get_mov_audio_tags(void) -{ - return ff_codec_movaudio_tags; -} diff --git a/libavformat/isom.h b/libavformat/isom.h index 41a9c64c1..5a6d50409 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -286,11 +286,17 @@ typedef struct MOVContext { int activation_bytes_size; void *audible_fixed_key; int audible_fixed_key_size; + void *audible_key; + int audible_key_size; + void *audible_iv; + int audible_iv_size; struct AVAES *aes_decrypt; uint8_t *decryption_key; int decryption_key_len; int enable_drefs; int32_t movie_display_matrix[3][3]; ///< display matrix from mvhd + int have_read_mfra_size; + uint32_t mfra_size; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/isom_tags.c b/libavformat/isom_tags.c new file mode 100644 index 000000000..1666b9d4a --- /dev/null +++ b/libavformat/isom_tags.c @@ -0,0 +1,346 @@ +/* + * ISO Media codec tags + * Copyright (c) 2001 Fabrice Bellard + * Copyright (c) 2002 Francois Revol + * Copyright (c) 2006 Baptiste Coudurier + * + * 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/codec_id.h" +#include "avformat.h" +#include "internal.h" +#include "isom.h" + +const AVCodecTag ff_codec_movvideo_tags[] = { +/* { AV_CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */ + + { AV_CODEC_ID_RAWVIDEO, MKTAG('r', 'a', 'w', ' ') }, /* uncompressed RGB */ + { AV_CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', '2') }, /* uncompressed YUV422 */ + { AV_CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') }, /* uncompressed 8-bit 4:2:2 */ + { AV_CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') }, /* same as 2VUY but byte-swapped */ + + { AV_CODEC_ID_RAWVIDEO, MKTAG('L', '5', '5', '5') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('L', '5', '6', '5') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '5', '6', '5') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('2', '4', 'B', 'G') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '1', '6', 'g') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '4', '8', 'r') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '6', '4', 'a') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'b', 'g') }, /* BOXX */ + { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'r', 'g') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'y', 'v') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('N', 'O', '1', '6') }, + { AV_CODEC_ID_RAWVIDEO, MKTAG('D', 'V', 'O', 'O') }, /* Digital Voodoo SD 8 Bit */ + { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', '2', '0') }, /* Radius DV YUV PAL */ + { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', '1', '1') }, /* Radius DV YUV NTSC */ + + { AV_CODEC_ID_R10K, MKTAG('R', '1', '0', 'k') }, /* uncompressed 10-bit RGB */ + { AV_CODEC_ID_R10K, MKTAG('R', '1', '0', 'g') }, /* uncompressed 10-bit RGB */ + { AV_CODEC_ID_R210, MKTAG('r', '2', '1', '0') }, /* uncompressed 10-bit RGB */ + { AV_CODEC_ID_AVUI, MKTAG('A', 'V', 'U', 'I') }, /* AVID Uncompressed deinterleaved UYVY422 */ + { AV_CODEC_ID_AVRP, MKTAG('A', 'V', 'r', 'p') }, /* Avid 1:1 10-bit RGB Packer */ + { AV_CODEC_ID_AVRP, MKTAG('S', 'U', 'D', 'S') }, /* Avid DS Uncompressed */ + { AV_CODEC_ID_V210, MKTAG('v', '2', '1', '0') }, /* uncompressed 10-bit 4:2:2 */ + { AV_CODEC_ID_V210, MKTAG('b', 'x', 'y', '2') }, /* BOXX 10-bit 4:2:2 */ + { AV_CODEC_ID_V308, MKTAG('v', '3', '0', '8') }, /* uncompressed 8-bit 4:4:4 */ + { AV_CODEC_ID_V408, MKTAG('v', '4', '0', '8') }, /* uncompressed 8-bit 4:4:4:4 */ + { AV_CODEC_ID_V410, MKTAG('v', '4', '1', '0') }, /* uncompressed 10-bit 4:4:4 */ + { AV_CODEC_ID_Y41P, MKTAG('Y', '4', '1', 'P') }, /* uncompressed 12-bit 4:1:1 */ + { AV_CODEC_ID_YUV4, MKTAG('y', 'u', 'v', '4') }, /* libquicktime packed yuv420p */ + { AV_CODEC_ID_TARGA_Y216, MKTAG('Y', '2', '1', '6') }, + + { AV_CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */ + { AV_CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */ + { AV_CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */ + { AV_CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, /* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */ + { AV_CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') }, /* Motion JPEG OpenDML */ + { AV_CODEC_ID_MJPEGB, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */ + + { AV_CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */ + { AV_CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */ + { AV_CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/ + { AV_CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, /* Sorenson Video v3 */ + + { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, + { AV_CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */ + { AV_CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, + { AV_CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') }, /* experimental: 3IVX files before ivx D4 4.5.1 */ + + { AV_CODEC_ID_H263, MKTAG('h', '2', '6', '3') }, /* H.263 */ + { AV_CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, /* H.263 ?? works */ + + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */ + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */ + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') }, /* DVCPRO PAL produced by FCP */ + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') }, /* DVCPRO50 PAL produced by FCP */ + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') }, /* DVCPRO50 NTSC produced by FCP */ + { AV_CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, /* AVID DV */ + { AV_CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', '1') }, /* AVID DV100 */ + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'q') }, /* DVCPRO HD 720p50 */ + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'p') }, /* DVCPRO HD 720p60 */ + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '1') }, + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '2') }, + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '4') }, + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '5') }, /* DVCPRO HD 50i produced by FCP */ + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '6') }, /* DVCPRO HD 60i produced by FCP */ + { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '3') }, /* DVCPRO HD 30p produced by FCP */ + + { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */ + { AV_CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */ + { AV_CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */ + { AV_CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') }, /* Planar RGB (8BPS) */ + { AV_CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') }, /* Apple Graphics (SMC) */ + { AV_CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') }, /* Apple Animation (RLE) */ + { AV_CODEC_ID_SGIRLE, MKTAG('r', 'l', 'e', '1') }, /* SGI RLE 8-bit */ + { AV_CODEC_ID_MSRLE, MKTAG('W', 'R', 'L', 'E') }, + { AV_CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') }, /* QuickDraw */ + { AV_CODEC_ID_CDTOONS, MKTAG('Q', 'k', 'B', 'k') }, /* CDToons */ + + { AV_CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') }, + + { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') }, /* HEVC/H.265 which indicates parameter sets may be in ES */ + { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') }, /* HEVC/H.265 which indicates parameter sets shall not be in ES */ + { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', 'e') }, /* HEVC-based Dolby Vision derived from hev1 */ + /* dvh1 is handled within mov.c */ + + { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */ + { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '2') }, + { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') }, + { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '4') }, + { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'p') }, /* AVC-Intra 50M 720p24/30/60 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') }, /* AVC-Intra 50M 720p25/50 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '2') }, /* AVC-Intra 50M 1080p25/50 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '3') }, /* AVC-Intra 50M 1080p24/30/60 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '5') }, /* AVC-Intra 50M 1080i50 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '6') }, /* AVC-Intra 50M 1080i60 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', 'p') }, /* AVC-Intra 100M 720p24/30/60 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', 'q') }, /* AVC-Intra 100M 720p25/50 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '2') }, /* AVC-Intra 100M 1080p25/50 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '3') }, /* AVC-Intra 100M 1080p24/30/60 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC-Intra 100M 1080i50 */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '6') }, /* AVC-Intra 100M 1080i60 */ + { AV_CODEC_ID_H264, MKTAG('A', 'V', 'i', 'n') }, /* AVC-Intra with implicit SPS/PPS */ + { AV_CODEC_ID_H264, MKTAG('a', 'i', 'v', 'x') }, /* XAVC 10-bit 4:2:2 */ + { AV_CODEC_ID_H264, MKTAG('r', 'v', '6', '4') }, /* X-Com Radvision */ + { AV_CODEC_ID_H264, MKTAG('x', 'a', 'l', 'g') }, /* XAVC-L HD422 produced by FCP */ + { AV_CODEC_ID_H264, MKTAG('a', 'v', 'l', 'g') }, /* Panasonic P2 AVC-LongG */ + { AV_CODEC_ID_H264, MKTAG('d', 'v', 'a', '1') }, /* AVC-based Dolby Vision derived from avc1 */ + { AV_CODEC_ID_H264, MKTAG('d', 'v', 'a', 'v') }, /* AVC-based Dolby Vision derived from avc3 */ + + { AV_CODEC_ID_VP8, MKTAG('v', 'p', '0', '8') }, /* VP8 */ + { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') }, /* VP9 */ + { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') }, /* AV1 */ + + { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', ' ') }, + { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, /* Apple MPEG-1 Camcorder */ + { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */ + { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '1', 'v') }, /* CoreMedia CMVideoCodecType */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', '2', 'v', '1') }, /* Apple MPEG-2 Camcorder */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') }, /* MPEG-2 HDV 720p30 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG-2 HDV 1080i60 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* MPEG-2 HDV 1080i50 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '4') }, /* MPEG-2 HDV 720p24 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') }, /* MPEG-2 HDV 720p25 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') }, /* MPEG-2 HDV 1080p24 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') }, /* MPEG-2 HDV 1080p25 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') }, /* MPEG-2 HDV 1080p30 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '9') }, /* MPEG-2 HDV 720p60 JVC */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', 'a') }, /* MPEG-2 HDV 720p50 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG-2 IMX NTSC 525/60 50mb/s produced by FCP */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG-2 IMX PAL 625/50 50mb/s produced by FCP */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') }, /* MPEG-2 IMX NTSC 525/60 40mb/s produced by FCP */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'p') }, /* MPEG-2 IMX PAL 625/50 40mb/s produced by FCP */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') }, /* MPEG-2 IMX NTSC 525/60 30mb/s produced by FCP */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') }, /* MPEG-2 IMX PAL 625/50 30mb/s produced by FCP */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '1') }, /* XDCAM HD422 720p30 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '4') }, /* XDCAM HD422 720p24 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '5') }, /* XDCAM HD422 720p25 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '9') }, /* XDCAM HD422 720p60 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'a') }, /* XDCAM HD422 720p50 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'b') }, /* XDCAM HD422 1080i60 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'c') }, /* XDCAM HD422 1080i50 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'd') }, /* XDCAM HD422 1080p24 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'e') }, /* XDCAM HD422 1080p25 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'f') }, /* XDCAM HD422 1080p30 CBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '1') }, /* XDCAM EX 720p30 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '2') }, /* XDCAM HD 1080i60 */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '3') }, /* XDCAM HD 1080i50 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '4') }, /* XDCAM EX 720p24 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '5') }, /* XDCAM EX 720p25 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '6') }, /* XDCAM HD 1080p24 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '7') }, /* XDCAM HD 1080p25 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '8') }, /* XDCAM HD 1080p30 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '9') }, /* XDCAM EX 720p60 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'a') }, /* XDCAM EX 720p50 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'b') }, /* XDCAM EX 1080i60 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'c') }, /* XDCAM EX 1080i50 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') }, /* XDCAM EX 1080p24 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') }, /* XDCAM EX 1080p25 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') }, /* XDCAM EX 1080p30 VBR */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', 'd') }, /* XDCAM HD 540p */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', '2') }, /* XDCAM HD422 540p */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') }, /* AVID IMX PAL */ + { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '2', 'v') }, /* FCP5 */ + + { AV_CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */ + + { AV_CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') }, /* Truevision Targa */ + { AV_CODEC_ID_TIFF, MKTAG('t', 'i', 'f', 'f') }, /* TIFF embedded in MOV */ + { AV_CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, /* embedded gif files as frames (usually one "click to play movie" frame) */ + { AV_CODEC_ID_PNG, MKTAG('p', 'n', 'g', ' ') }, + { AV_CODEC_ID_PNG, MKTAG('M', 'N', 'G', ' ') }, + + { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') }, /* SMPTE RP 2025 */ + { AV_CODEC_ID_CAVS, MKTAG('a', 'v', 's', '2') }, + + { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, + { AV_CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') }, /* AVID DNxHD */ + { AV_CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'h') }, /* AVID DNxHR */ + { AV_CODEC_ID_H263, MKTAG('H', '2', '6', '3') }, + { AV_CODEC_ID_MSMPEG4V3, MKTAG('3', 'I', 'V', 'D') }, /* 3ivx DivX Doctor */ + { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'V', '1', 'x') }, /* AVID 1:1x */ + { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'u', 'p') }, + { AV_CODEC_ID_SGI, MKTAG('s', 'g', 'i', ' ') }, /* SGI */ + { AV_CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') }, /* DPX */ + { AV_CODEC_ID_EXR, MKTAG('e', 'x', 'r', ' ') }, /* OpenEXR */ + + { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'h') }, /* Apple ProRes 422 High Quality */ + { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'n') }, /* Apple ProRes 422 Standard Definition */ + { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 's') }, /* Apple ProRes 422 LT */ + { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'o') }, /* Apple ProRes 422 Proxy */ + { AV_CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'h') }, /* Apple ProRes 4444 */ + { AV_CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'x') }, /* Apple ProRes 4444 XQ */ + { AV_CODEC_ID_FLIC, MKTAG('f', 'l', 'i', 'c') }, + + { AV_CODEC_ID_AIC, MKTAG('i', 'c', 'o', 'd') }, + + { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', '1') }, + { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', '5') }, + { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'Y') }, + { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'A') }, + { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'M') }, + + { AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', '3') }, + { AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', 'I') }, + + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'R', '0') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'R', 'A') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'R', 'G') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'Y', '0') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'Y', '2') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'Y', '4') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'R', 'G') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'R', 'A') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'G', '0') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', '0') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', '2') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', '4') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '8', 'Y', 'A') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '2', 'R', 'A') }, + { AV_CODEC_ID_MAGICYUV, MKTAG('M', '2', 'R', 'G') }, + + { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '0') }, + { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '1') }, + { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '2') }, + { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '3') }, + { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '4') }, + { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '5') }, + { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '6') }, + { AV_CODEC_ID_SHEERVIDEO, MKTAG('S', 'h', 'r', '7') }, + + { AV_CODEC_ID_PIXLET, MKTAG('p', 'x', 'l', 't') }, + + { AV_CODEC_ID_NOTCHLC, MKTAG('n', 'c', 'l', 'c') }, + + { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'G', 'R') }, /* ASC Bayer BGGR */ + + { AV_CODEC_ID_NONE, 0 }, +}; + +const AVCodecTag ff_codec_movaudio_tags[] = { + { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, + { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F */ + { AV_CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') }, /* Nero Recode */ + { AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, + { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') }, + { AV_CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */ + { AV_CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */ + { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'c') }, /* DTS formats prior to DTS-HD */ + { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'h') }, /* DTS-HD audio formats */ + { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'l') }, /* DTS-HD Lossless formats */ + { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'e') }, /* DTS Express */ + { AV_CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non-standard */ + { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F (only valid in ISOBMFF) */ + { AV_CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') }, + { AV_CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') }, + { AV_CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') }, + { AV_CODEC_ID_ILBC, MKTAG('i', 'l', 'b', 'c') }, + { AV_CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, + { AV_CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, + { AV_CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') }, + { AV_CODEC_ID_MP2, MKTAG('.', 'm', 'p', '2') }, + { AV_CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') }, + { AV_CODEC_ID_MP3, MKTAG('m', 'p', '3', ' ') }, /* vlc */ + { AV_CODEC_ID_MP3, 0x6D730055 }, + { AV_CODEC_ID_NELLYMOSER, MKTAG('n', 'm', 'o', 's') }, /* Flash Media Server */ + { AV_CODEC_ID_NELLYMOSER, MKTAG('N', 'E', 'L', 'L') }, /* Perian */ + { AV_CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, + { AV_CODEC_ID_PCM_F32BE, MKTAG('f', 'l', '3', '2') }, + { AV_CODEC_ID_PCM_F32LE, MKTAG('f', 'l', '3', '2') }, + { AV_CODEC_ID_PCM_F64BE, MKTAG('f', 'l', '6', '4') }, + { AV_CODEC_ID_PCM_F64LE, MKTAG('f', 'l', '6', '4') }, + { AV_CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, + { AV_CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, + { AV_CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, + { AV_CODEC_ID_PCM_S16BE, MKTAG('l', 'p', 'c', 'm') }, + { AV_CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') }, + { AV_CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') }, + { AV_CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') }, + { AV_CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') }, + { AV_CODEC_ID_PCM_S32LE, MKTAG('i', 'n', '3', '2') }, + { AV_CODEC_ID_PCM_S8, MKTAG('s', 'o', 'w', 't') }, + { AV_CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, + { AV_CODEC_ID_PCM_U8, MKTAG('N', 'O', 'N', 'E') }, + { AV_CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'p') }, + { AV_CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'q') }, + { AV_CODEC_ID_QCELP, MKTAG('s', 'q', 'c', 'p') }, /* ISO Media fourcc */ + { AV_CODEC_ID_QDM2, MKTAG('Q', 'D', 'M', '2') }, + { AV_CODEC_ID_QDMC, MKTAG('Q', 'D', 'M', 'C') }, + { AV_CODEC_ID_SPEEX, MKTAG('s', 'p', 'e', 'x') }, /* Flash Media Server */ + { AV_CODEC_ID_SPEEX, MKTAG('S', 'P', 'X', 'N') }, /* ZygoAudio (quality 10 mode) */ + { AV_CODEC_ID_EVRC, MKTAG('s', 'e', 'v', 'c') }, /* 3GPP2 */ + { AV_CODEC_ID_SMV, MKTAG('s', 's', 'm', 'v') }, /* 3GPP2 */ + { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') }, /* nonstandard */ + { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') }, /* mp4ra.org */ + { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') }, /* mp4ra.org */ + { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') }, /* MPEG-H 3D Audio bitstream */ + { AV_CODEC_ID_NONE, 0 }, +}; + +const struct AVCodecTag *avformat_get_mov_video_tags(void) +{ + return ff_codec_movvideo_tags; +} + +const struct AVCodecTag *avformat_get_mov_audio_tags(void) +{ + return ff_codec_movaudio_tags; +} diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c index 0951f56c9..889c00438 100644 --- a/libavformat/ivfenc.c +++ b/libavformat/ivfenc.c @@ -23,7 +23,7 @@ typedef struct IVFEncContext { unsigned frame_cnt; - uint64_t last_pts, sum_delta_pts; + uint64_t last_pts, sum_delta_pts, last_pkt_duration; } IVFEncContext; static int ivf_init(AVFormatContext *s) @@ -86,6 +86,7 @@ static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt) avio_write(pb, pkt->data, pkt->size); if (ctx->frame_cnt) ctx->sum_delta_pts += pkt->pts - ctx->last_pts; + ctx->last_pkt_duration = pkt->duration; ctx->frame_cnt++; ctx->last_pts = pkt->pts; @@ -97,12 +98,15 @@ static int ivf_write_trailer(AVFormatContext *s) AVIOContext *pb = s->pb; IVFEncContext *ctx = s->priv_data; - if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && ctx->frame_cnt > 1) { + if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && + (ctx->frame_cnt > 1 || (ctx->frame_cnt == 1 && ctx->last_pkt_duration))) { int64_t end = avio_tell(pb); avio_seek(pb, 24, SEEK_SET); // overwrite the "length" field (duration) - avio_wl32(pb, ctx->frame_cnt * ctx->sum_delta_pts / (ctx->frame_cnt - 1)); + avio_wl32(pb, ctx->last_pkt_duration ? + ctx->sum_delta_pts + ctx->last_pkt_duration : + ctx->frame_cnt * ctx->sum_delta_pts / (ctx->frame_cnt - 1)); avio_wl32(pb, 0); // zero out unused bytes avio_seek(pb, end, SEEK_SET); } diff --git a/libavformat/jacosubdec.c b/libavformat/jacosubdec.c index e70ceeaaf..9c6640eef 100644 --- a/libavformat/jacosubdec.c +++ b/libavformat/jacosubdec.c @@ -125,8 +125,8 @@ static const char *read_ts(JACOsubContext *jacosub, const char *buf, return NULL; shift_and_ret: - ts_start64 = (ts_start + jacosub->shift) * 100LL / jacosub->timeres; - ts_end64 = (ts_end + jacosub->shift) * 100LL / jacosub->timeres; + ts_start64 = (ts_start + (int64_t)jacosub->shift) * 100LL / jacosub->timeres; + ts_end64 = (ts_end + (int64_t)jacosub->shift) * 100LL / jacosub->timeres; *start = ts_start64; *duration = ts_end64 - ts_start64; return buf + len; @@ -148,9 +148,15 @@ static int get_shift(int timeres, const char *buf) ret = 0; switch (n) { - case 4: ret = sign * (((int64_t)a*3600 + b*60 + c) * timeres + d); - case 3: ret = sign * (( (int64_t)a*60 + b) * timeres + c); - case 2: ret = sign * (( (int64_t)a) * timeres + b); + case 4: + ret = sign * (((int64_t)a*3600 + b*60 + c) * timeres + d); + break; + case 3: + ret = sign * (( (int64_t)a*60 + b) * timeres + c); + break; + case 2: + ret = sign * (( (int64_t)a) * timeres + b); + break; } if ((int)ret != ret) ret = 0; @@ -193,6 +199,7 @@ static int jacosub_read_header(AVFormatContext *s) sub = ff_subtitles_queue_insert(&jacosub->q, line, len, merge_line); if (!sub) { + av_bprint_finalize(&header, NULL); ret = AVERROR(ENOMEM); goto fail; } @@ -244,7 +251,7 @@ static int jacosub_read_header(AVFormatContext *s) /* SHIFT and TIMERES affect the whole script so packet timing can only be * done in a second pass */ for (i = 0; i < jacosub->q.nb_subs; i++) { - AVPacket *sub = &jacosub->q.subs[i]; + AVPacket *sub = jacosub->q.subs[i]; read_ts(jacosub, sub->data, &sub->pts, &sub->duration); } ff_subtitles_queue_finalize(s, &jacosub->q); diff --git a/libavformat/kvag.c b/libavformat/kvag.c index 8f641873b..91d1d8a51 100644 --- a/libavformat/kvag.c +++ b/libavformat/kvag.c @@ -110,12 +110,22 @@ static int kvag_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; } +static int kvag_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + if (pts != 0) + return AVERROR(EINVAL); + + return avio_seek(s->pb, KVAG_HEADER_SIZE, SEEK_SET); +} + AVInputFormat ff_kvag_demuxer = { .name = "kvag", .long_name = NULL_IF_CONFIG_SMALL("Simon & Schuster Interactive VAG"), .read_probe = kvag_probe, .read_header = kvag_read_header, - .read_packet = kvag_read_packet + .read_packet = kvag_read_packet, + .read_seek = kvag_seek, }; #endif diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c index 5ae677f5d..91e96e90b 100644 --- a/libavformat/latmenc.c +++ b/libavformat/latmenc.c @@ -101,6 +101,17 @@ static int latm_write_header(AVFormatContext *s) return 0; } +static void copy_bits(PutBitContext *pb, const uint8_t *src, int length) +{ + int words = length >> 4; + int bits = length & 15; + int i; + for (i = 0; i < words; i++) + put_bits(pb, 16, AV_RB16(src + 2 * i)); + if (bits) + put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits)); +} + static void latm_write_frame_header(AVFormatContext *s, PutBitContext *bs) { LATMContext *ctx = s->priv_data; @@ -120,12 +131,12 @@ static void latm_write_frame_header(AVFormatContext *s, PutBitContext *bs) /* AudioSpecificConfig */ if (ctx->object_type == AOT_ALS) { - header_size = par->extradata_size-(ctx->off >> 3); - avpriv_copy_bits(bs, &par->extradata[ctx->off >> 3], header_size); + header_size = (par->extradata_size - (ctx->off >> 3)) * 8; + copy_bits(bs, &par->extradata[ctx->off >> 3], header_size); } else { // + 3 assumes not scalable and dependsOnCoreCoder == 0, // see decode_ga_specific_config in libavcodec/aacdec.c - avpriv_copy_bits(bs, par->extradata, ctx->off + 3); + copy_bits(bs, par->extradata, ctx->off + 3); if (!ctx->channel_conf) { GetBitContext gb; @@ -165,7 +176,8 @@ static int latm_write_packet(AVFormatContext *s, AVPacket *pkt) return ff_raw_write_packet(s, pkt); else { uint8_t *side_data; - int side_data_size = 0, ret; + buffer_size_t side_data_size; + int ret; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size); @@ -207,11 +219,10 @@ static int latm_write_packet(AVFormatContext *s, AVPacket *pkt) // This allows us to remux our FATE AAC samples into latm // files that are still playable with minimal effort. put_bits(&bs, 8, pkt->data[0] & 0xfe); - avpriv_copy_bits(&bs, pkt->data + 1, 8*pkt->size - 8); + copy_bits(&bs, pkt->data + 1, 8*pkt->size - 8); } else - avpriv_copy_bits(&bs, pkt->data, 8*pkt->size); + copy_bits(&bs, pkt->data, 8*pkt->size); - avpriv_align_put_bits(&bs); flush_put_bits(&bs); len = put_bits_count(&bs) >> 3; diff --git a/libavformat/libamqp.c b/libavformat/libamqp.c index aaf0e5115..c3b9c484e 100644 --- a/libavformat/libamqp.c +++ b/libavformat/libamqp.c @@ -39,6 +39,7 @@ typedef struct AMQPContext { int pkt_size; int64_t connection_timeout; int pkt_size_overflow; + int delivery_mode; } AMQPContext; #define STR_LEN 1024 @@ -52,16 +53,19 @@ static const AVOption options[] = { { "exchange", "Exchange to send/read packets", OFFSET(exchange), AV_OPT_TYPE_STRING, { .str = "amq.direct" }, 0, 0, .flags = D | E }, { "routing_key", "Key to filter streams", OFFSET(routing_key), AV_OPT_TYPE_STRING, { .str = "amqp" }, 0, 0, .flags = D | E }, { "connection_timeout", "Initial connection timeout", OFFSET(connection_timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT64_MAX, .flags = D | E}, + { "delivery_mode", "Delivery mode", OFFSET(delivery_mode), AV_OPT_TYPE_INT, { .i64 = AMQP_DELIVERY_PERSISTENT }, 1, 2, .flags = E, "delivery_mode"}, + { "persistent", "Persistent delivery mode", 0, AV_OPT_TYPE_CONST, { .i64 = AMQP_DELIVERY_PERSISTENT }, 0, 0, E, "delivery_mode" }, + { "non-persistent", "Non-persistent delivery mode", 0, AV_OPT_TYPE_CONST, { .i64 = AMQP_DELIVERY_NONPERSISTENT }, 0, 0, E, "delivery_mode" }, { NULL } }; static int amqp_proto_open(URLContext *h, const char *uri, int flags) { int ret, server_msg; - char hostname[STR_LEN], credentials[STR_LEN]; + char hostname[STR_LEN], credentials[STR_LEN], path[STR_LEN]; int port; - const char *user, *password = NULL; - const char *user_decoded, *password_decoded; + const char *user, *password = NULL, *vhost; + const char *user_decoded, *password_decoded, *vhost_decoded; char *p; amqp_rpc_reply_t broker_reply; struct timeval tval = { 0 }; @@ -72,7 +76,7 @@ static int amqp_proto_open(URLContext *h, const char *uri, int flags) h->max_packet_size = s->pkt_size; av_url_split(NULL, 0, credentials, sizeof(credentials), - hostname, sizeof(hostname), &port, NULL, 0, uri); + hostname, sizeof(hostname), &port, path, sizeof(path), uri); if (port < 0) port = 5672; @@ -105,8 +109,27 @@ static int amqp_proto_open(URLContext *h, const char *uri, int flags) return AVERROR(ENOMEM); } + /* skip query for now */ + p = strchr(path, '?'); + if (p) + *p = '\0'; + + vhost = path; + if (*vhost == '\0') + vhost = "/"; + else + vhost++; /* skip leading '/' */ + + vhost_decoded = ff_urldecode(vhost, 0); + if (!vhost_decoded) { + av_freep(&user_decoded); + av_freep(&password_decoded); + return AVERROR(ENOMEM); + } + s->conn = amqp_new_connection(); if (!s->conn) { + av_freep(&vhost_decoded); av_freep(&user_decoded); av_freep(&password_decoded); av_log(h, AV_LOG_ERROR, "Error creating connection\n"); @@ -132,7 +155,7 @@ static int amqp_proto_open(URLContext *h, const char *uri, int flags) goto destroy_connection; } - broker_reply = amqp_login(s->conn, "/", 0, s->pkt_size, 0, + broker_reply = amqp_login(s->conn, vhost_decoded, 0, s->pkt_size, 0, AMQP_SASL_METHOD_PLAIN, user_decoded, password_decoded); if (broker_reply.reply_type != AMQP_RESPONSE_NORMAL) { @@ -191,6 +214,7 @@ static int amqp_proto_open(URLContext *h, const char *uri, int flags) } } + av_freep(&vhost_decoded); av_freep(&user_decoded); av_freep(&password_decoded); return 0; @@ -202,6 +226,7 @@ close_connection: destroy_connection: amqp_destroy_connection(s->conn); + av_freep(&vhost_decoded); av_freep(&user_decoded); av_freep(&password_decoded); return AVERROR_EXTERNAL; @@ -222,7 +247,7 @@ static int amqp_proto_write(URLContext *h, const unsigned char *buf, int size) props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG; props.content_type = amqp_cstring_bytes("octet/stream"); - props.delivery_mode = 2; /* persistent delivery mode */ + props.delivery_mode = s->delivery_mode; ret = amqp_basic_publish(s->conn, DEFAULT_CHANNEL, amqp_cstring_bytes(s->exchange), amqp_cstring_bytes(s->routing_key), 0, 0, diff --git a/libavformat/libgme.c b/libavformat/libgme.c index e6c56c487..f9d9abaad 100644 --- a/libavformat/libgme.c +++ b/libavformat/libgme.c @@ -31,7 +31,6 @@ typedef struct GMEContext { const AVClass *class; Music_Emu *music_emu; - gme_info_t *info; ///< selected track /* options */ int track_index; @@ -55,12 +54,16 @@ static void add_meta(AVFormatContext *s, const char *name, const char *value) av_dict_set(&s->metadata, name, value, 0); } -static int load_metadata(AVFormatContext *s) +static int load_metadata(AVFormatContext *s, int64_t *duration) { GMEContext *gme = s->priv_data; - gme_info_t *info = gme->info; + gme_info_t *info = NULL; char buf[30]; + if (gme_track_info(gme->music_emu, &info, gme->track_index)) + return AVERROR_STREAM_NOT_FOUND; + + *duration = info->length; add_meta(s, "system", info->system); add_meta(s, "game", info->game); add_meta(s, "song", info->song); @@ -71,20 +74,30 @@ static int load_metadata(AVFormatContext *s) snprintf(buf, sizeof(buf), "%d", (int)gme_track_count(gme->music_emu)); add_meta(s, "tracks", buf); + gme_free_info(info); return 0; } #define AUDIO_PKT_SIZE 512 +static int read_close_gme(AVFormatContext *s) +{ + GMEContext *gme = s->priv_data; + gme_delete(gme->music_emu); + return 0; +} + static int read_header_gme(AVFormatContext *s) { AVStream *st; AVIOContext *pb = s->pb; GMEContext *gme = s->priv_data; int64_t sz = avio_size(pb); + int64_t duration; char *buf; char dummy; + int ret; if (sz < 0) { av_log(s, AV_LOG_WARNING, "Could not determine file size\n"); @@ -103,6 +116,7 @@ static int read_header_gme(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "File size is larger than max_size option " "value %"PRIi64", consider increasing the max_size option\n", gme->max_size); + av_freep(&buf); return AVERROR_BUFFER_TOO_SMALL; } @@ -112,20 +126,24 @@ static int read_header_gme(AVFormatContext *s) } av_freep(&buf); - if (gme_track_info(gme->music_emu, &gme->info, gme->track_index)) - return AVERROR_STREAM_NOT_FOUND; - - if (gme_start_track(gme->music_emu, gme->track_index)) + ret = load_metadata(s, &duration); + if (ret < 0) { + read_close_gme(s); + return ret; + } + if (gme_start_track(gme->music_emu, gme->track_index)) { + read_close_gme(s); return AVERROR_UNKNOWN; - - load_metadata(s); + } st = avformat_new_stream(s, NULL); - if (!st) + if (!st) { + read_close_gme(s); return AVERROR(ENOMEM); + } avpriv_set_pts_info(st, 64, 1, 1000); if (st->duration > 0) - st->duration = gme->info->length; + st->duration = duration; st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE); st->codecpar->channels = 2; @@ -153,14 +171,6 @@ static int read_packet_gme(AVFormatContext *s, AVPacket *pkt) return 0; } -static int read_close_gme(AVFormatContext *s) -{ - GMEContext *gme = s->priv_data; - gme_free_info(gme->info); - gme_delete(gme->music_emu); - return 0; -} - static int read_seek_gme(AVFormatContext *s, int stream_idx, int64_t ts, int flags) { GMEContext *gme = s->priv_data; diff --git a/libavformat/libmodplug.c b/libavformat/libmodplug.c index 6e567f5f9..b85269341 100644 --- a/libavformat/libmodplug.c +++ b/libavformat/libmodplug.c @@ -99,6 +99,14 @@ static const AVOption options[] = { {NULL}, }; +static int modplug_read_close(AVFormatContext *s) +{ + ModPlugContext *modplug = s->priv_data; + ModPlug_Unload(modplug->f); + av_freep(&modplug->buf); + return 0; +} + #define SET_OPT_IF_REQUESTED(libopt, opt, flag) do { \ if (modplug->opt) { \ settings.libopt = modplug->opt; \ @@ -168,6 +176,7 @@ static int modplug_read_header(AVFormatContext *s) ModPlug_Settings settings; ModPlugContext *modplug = s->priv_data; int64_t sz = avio_size(pb); + int ret; if (sz < 0) { av_log(s, AV_LOG_WARNING, "Could not determine file size\n"); @@ -221,8 +230,10 @@ static int modplug_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); + if (!st) { + ret = AVERROR(ENOMEM); + goto fail; + } avpriv_set_pts_info(st, 64, 1, 1000); st->duration = ModPlug_GetLength(modplug->f); st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; @@ -235,8 +246,10 @@ static int modplug_read_header(AVFormatContext *s) if (modplug->video_stream) { AVStream *vst = avformat_new_stream(s, NULL); - if (!vst) - return AVERROR(ENOMEM); + if (!vst) { + ret = AVERROR(ENOMEM); + goto fail; + } avpriv_set_pts_info(vst, 64, 1, 1000); vst->duration = st->duration; vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; @@ -247,7 +260,13 @@ static int modplug_read_header(AVFormatContext *s) modplug->fsize = modplug->linesize * modplug->h; } - return modplug_load_metadata(s); + ret = modplug_load_metadata(s); + if (ret < 0) + goto fail; + return 0; +fail: + modplug_read_close(s); + return ret; } static void write_text(uint8_t *dst, const char *s, int linesize, int x, int y) @@ -332,14 +351,6 @@ static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; } -static int modplug_read_close(AVFormatContext *s) -{ - ModPlugContext *modplug = s->priv_data; - ModPlug_Unload(modplug->f); - av_freep(&modplug->buf); - return 0; -} - static int modplug_read_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags) { ModPlugContext *modplug = s->priv_data; diff --git a/libavformat/libopenmpt.c b/libavformat/libopenmpt.c index 52511aba5..b07da5f07 100644 --- a/libavformat/libopenmpt.c +++ b/libavformat/libopenmpt.c @@ -218,7 +218,7 @@ static int read_seek_openmpt(AVFormatContext *s, int stream_idx, int64_t ts, int return 0; } -static int probe_openmpt_extension(AVProbeData *p) +static int probe_openmpt_extension(const AVProbeData *p) { const char *ext; if (p->filename) { diff --git a/libavformat/librist.c b/libavformat/librist.c new file mode 100644 index 000000000..01a3f9c12 --- /dev/null +++ b/libavformat/librist.c @@ -0,0 +1,244 @@ +/* + * 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 + * Reliable Internet Streaming Transport protocol + */ + +#include "libavutil/avassert.h" +#include "libavutil/opt.h" +#include "libavutil/parseutils.h" +#include "libavutil/time.h" + +#include "avformat.h" +#include "internal.h" +#include "network.h" +#include "os_support.h" +#include "url.h" + +#include + +// RIST_MAX_PACKET_SIZE - 28 minimum protocol overhead +#define MAX_PAYLOAD_SIZE (10000-28) + +typedef struct RISTContext { + const AVClass *class; + + int profile; + int buffer_size; + int packet_size; + int log_level; + int encryption; + char *secret; + + struct rist_logging_settings logging_settings; + struct rist_peer_config peer_config; + + struct rist_peer *peer; + struct rist_ctx *ctx; +} RISTContext; + +#define D AV_OPT_FLAG_DECODING_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM +#define OFFSET(x) offsetof(RISTContext, x) +static const AVOption librist_options[] = { + { "rist_profile","set profile", OFFSET(profile), AV_OPT_TYPE_INT, {.i64=RIST_PROFILE_MAIN}, 0, 2, .flags = D|E, "profile" }, + { "simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64=RIST_PROFILE_SIMPLE}, 0, 0, .flags = D|E, "profile" }, + { "main", NULL, 0, AV_OPT_TYPE_CONST, {.i64=RIST_PROFILE_MAIN}, 0, 0, .flags = D|E, "profile" }, + { "advanced", NULL, 0, AV_OPT_TYPE_CONST, {.i64=RIST_PROFILE_ADVANCED}, 0, 0, .flags = D|E, "profile" }, + { "buffer_size", "set buffer_size in ms", OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64=0}, 0, 30000, .flags = D|E }, + { "pkt_size", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64=1316}, 1, MAX_PAYLOAD_SIZE, .flags = D|E }, + { "log_level", "set loglevel", OFFSET(log_level), AV_OPT_TYPE_INT, {.i64=RIST_LOG_INFO}, -1, INT_MAX, .flags = D|E }, + { "secret", "set encryption secret",OFFSET(secret), AV_OPT_TYPE_STRING,{.str=NULL}, 0, 0, .flags = D|E }, + { "encryption","set encryption type",OFFSET(encryption), AV_OPT_TYPE_INT ,{.i64=0}, 0, INT_MAX, .flags = D|E }, + { NULL } +}; + +static int risterr2ret(int err) +{ + switch (err) { + case RIST_ERR_MALLOC: + return AVERROR(ENOMEM); + default: + return AVERROR_EXTERNAL; + } +} + +static int log_cb(void *arg, enum rist_log_level log_level, const char *msg) +{ + int level; + + switch (log_level) { + case RIST_LOG_ERROR: level = AV_LOG_ERROR; break; + case RIST_LOG_WARN: level = AV_LOG_WARNING; break; + case RIST_LOG_NOTICE: level = AV_LOG_INFO; break; + case RIST_LOG_INFO: level = AV_LOG_VERBOSE; break; + case RIST_LOG_DEBUG: level = AV_LOG_DEBUG; break; + case RIST_LOG_DISABLE: level = AV_LOG_QUIET; break; + default: level = AV_LOG_WARNING; + } + + av_log(arg, level, "%s", msg); + + return 0; +} + +static int librist_close(URLContext *h) +{ + RISTContext *s = h->priv_data; + int ret = 0; + + s->peer = NULL; + + if (s->ctx) + ret = rist_destroy(s->ctx); + s->ctx = NULL; + + return risterr2ret(ret); +} + +static int librist_open(URLContext *h, const char *uri, int flags) +{ + RISTContext *s = h->priv_data; + struct rist_logging_settings *logging_settings = &s->logging_settings; + struct rist_peer_config *peer_config = &s->peer_config; + int ret; + + if ((flags & AVIO_FLAG_READ_WRITE) == AVIO_FLAG_READ_WRITE) + return AVERROR(EINVAL); + + ret = rist_logging_set(&logging_settings, s->log_level, log_cb, h, NULL, NULL); + if (ret < 0) + return risterr2ret(ret); + + if (flags & AVIO_FLAG_WRITE) { + h->max_packet_size = s->packet_size; + ret = rist_sender_create(&s->ctx, s->profile, 0, logging_settings); + } + if (ret < 0) + goto err; + + if (flags & AVIO_FLAG_READ) { + h->max_packet_size = MAX_PAYLOAD_SIZE; + ret = rist_receiver_create(&s->ctx, s->profile, logging_settings); + } + if (ret < 0) + goto err; + + ret = rist_peer_config_defaults_set(peer_config); + if (ret < 0) + goto err; + + ret = rist_parse_address(uri, (const struct rist_peer_config **)&peer_config); + if (ret < 0) + goto err; + + if (((s->encryption == 128 || s->encryption == 256) && !s->secret) || + ((peer_config->key_size == 128 || peer_config->key_size == 256) && !peer_config->secret[0])) { + av_log(h, AV_LOG_ERROR, "secret is mandatory if encryption is enabled\n"); + librist_close(h); + return AVERROR(EINVAL); + } + + if (s->secret && peer_config->secret[0] == 0) + av_strlcpy(peer_config->secret, s->secret, RIST_MAX_STRING_SHORT); + + if (s->secret && (s->encryption == 128 || s->encryption == 256)) + peer_config->key_size = s->encryption; + + if (s->buffer_size) { + peer_config->recovery_length_min = s->buffer_size; + peer_config->recovery_length_max = s->buffer_size; + } + + ret = rist_peer_create(s->ctx, &s->peer, &s->peer_config); + if (ret < 0) + goto err; + + ret = rist_start(s->ctx); + if (ret < 0) + goto err; + + return 0; + +err: + librist_close(h); + + return risterr2ret(ret); +} + +static int librist_read(URLContext *h, uint8_t *buf, int size) +{ + RISTContext *s = h->priv_data; + const struct rist_data_block *data_block; + int ret; + + ret = rist_receiver_data_read(s->ctx, &data_block, POLLING_TIME); + if (ret < 0) + return risterr2ret(ret); + + if (ret == 0) + return AVERROR(EAGAIN); + + if (data_block->payload_len > MAX_PAYLOAD_SIZE) { + rist_receiver_data_block_free((struct rist_data_block**)&data_block); + return AVERROR_EXTERNAL; + } + + size = data_block->payload_len; + memcpy(buf, data_block->payload, size); + rist_receiver_data_block_free((struct rist_data_block**)&data_block); + + return size; +} + +static int librist_write(URLContext *h, const uint8_t *buf, int size) +{ + RISTContext *s = h->priv_data; + struct rist_data_block data_block = { 0 }; + int ret; + + data_block.ts_ntp = 0; + data_block.payload = buf; + data_block.payload_len = size; + + ret = rist_sender_data_write(s->ctx, &data_block); + if (ret < 0) + return risterr2ret(ret); + + return ret; +} + +static const AVClass librist_class = { + .class_name = "librist", + .item_name = av_default_item_name, + .option = librist_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const URLProtocol ff_librist_protocol = { + .name = "rist", + .url_open = librist_open, + .url_read = librist_read, + .url_write = librist_write, + .url_close = librist_close, + .priv_data_size = sizeof(RISTContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, + .priv_data_class = &librist_class, +}; diff --git a/libavformat/libsrt.c b/libavformat/libsrt.c index f73e7dbfa..c1e96f700 100644 --- a/libavformat/libsrt.c +++ b/libavformat/libsrt.c @@ -53,7 +53,6 @@ enum SRTMode { typedef struct SRTContext { const AVClass *class; int fd; - int listen_fd; int eid; int64_t rw_timeout; int64_t listen_timeout; @@ -123,7 +122,7 @@ static const AVOption libsrt_options[] = { { "tsbpddelay", "deprecated, same effect as latency option", OFFSET(latency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "rcvlatency", "receive latency (in microseconds)", OFFSET(rcvlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "peerlatency", "peer latency (in microseconds)", OFFSET(peerlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, - { "tlpktdrop", "Enable receiver pkt drop", OFFSET(tlpktdrop), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E }, + { "tlpktdrop", "Enable too-late pkt drop", OFFSET(tlpktdrop), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E }, { "nakreport", "Enable receiver to send periodic NAK reports", OFFSET(nakreport), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E }, { "connect_timeout", "Connect timeout(in milliseconds). Caller default: 3000, rendezvous (x 10)", OFFSET(connect_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "mode", "Connection mode (caller, listener, rendezvous)", OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = SRT_MODE_CALLER }, SRT_MODE_CALLER, SRT_MODE_RENDEZVOUS, .flags = D|E, "mode" }, @@ -164,15 +163,25 @@ static int libsrt_socket_nonblock(int socket, int enable) return srt_setsockopt(socket, 0, SRTO_RCVSYN, &blocking, sizeof(blocking)); } -static int libsrt_network_wait_fd(URLContext *h, int eid, int fd, int write) +static int libsrt_epoll_create(URLContext *h, int fd, int write) +{ + int modes = SRT_EPOLL_ERR | (write ? SRT_EPOLL_OUT : SRT_EPOLL_IN); + int eid = srt_epoll_create(); + if (eid < 0) + return libsrt_neterrno(h); + if (srt_epoll_add_usock(eid, fd, &modes) < 0) { + srt_epoll_release(eid); + return libsrt_neterrno(h); + } + return eid; +} + +static int libsrt_network_wait_fd(URLContext *h, int eid, int write) { int ret, len = 1, errlen = 1; - int modes = SRT_EPOLL_ERR | (write ? SRT_EPOLL_OUT : SRT_EPOLL_IN); SRTSOCKET ready[1]; SRTSOCKET error[1]; - if (srt_epoll_add_usock(eid, fd, &modes) < 0) - return libsrt_neterrno(h); if (write) { ret = srt_epoll_wait(eid, error, &errlen, ready, &len, POLLING_TIME, 0, 0, 0, 0); } else { @@ -186,14 +195,12 @@ static int libsrt_network_wait_fd(URLContext *h, int eid, int fd, int write) } else { ret = errlen ? AVERROR(EIO) : 0; } - if (srt_epoll_remove_usock(eid, fd) < 0) - return libsrt_neterrno(h); return ret; } /* TODO de-duplicate code from ff_network_wait_fd_timeout() */ -static int libsrt_network_wait_fd_timeout(URLContext *h, int eid, int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb) +static int libsrt_network_wait_fd_timeout(URLContext *h, int eid, int write, int64_t timeout, AVIOInterruptCB *int_cb) { int ret; int64_t wait_start = 0; @@ -201,7 +208,7 @@ static int libsrt_network_wait_fd_timeout(URLContext *h, int eid, int fd, int wr while (1) { if (ff_check_interrupt(int_cb)) return AVERROR_EXIT; - ret = libsrt_network_wait_fd(h, eid, fd, write); + ret = libsrt_network_wait_fd(h, eid, write); if (ret != AVERROR(EAGAIN)) return ret; if (timeout > 0) { @@ -220,15 +227,13 @@ static int libsrt_listen(int eid, int fd, const struct sockaddr *addr, socklen_t if (srt_setsockopt(fd, SOL_SOCKET, SRTO_REUSEADDR, &reuse, sizeof(reuse))) { av_log(h, AV_LOG_WARNING, "setsockopt(SRTO_REUSEADDR) failed\n"); } - ret = srt_bind(fd, addr, addrlen); - if (ret) + if (srt_bind(fd, addr, addrlen)) return libsrt_neterrno(h); - ret = srt_listen(fd, 1); - if (ret) + if (srt_listen(fd, 1)) return libsrt_neterrno(h); - ret = libsrt_network_wait_fd_timeout(h, eid, fd, 1, timeout, &h->interrupt_callback); + ret = libsrt_network_wait_fd_timeout(h, eid, 1, timeout, &h->interrupt_callback); if (ret < 0) return ret; @@ -245,11 +250,10 @@ static int libsrt_listen_connect(int eid, int fd, const struct sockaddr *addr, s { int ret; - ret = srt_connect(fd, addr, addrlen); - if (ret < 0) + if (srt_connect(fd, addr, addrlen) < 0) return libsrt_neterrno(h); - ret = libsrt_network_wait_fd_timeout(h, eid, fd, 1, timeout, &h->interrupt_callback); + ret = libsrt_network_wait_fd_timeout(h, eid, 1, timeout, &h->interrupt_callback); if (ret < 0) { if (will_try_next) { av_log(h, AV_LOG_WARNING, @@ -330,7 +334,7 @@ static int libsrt_set_options_pre(URLContext *h, int fd) (s->latency >= 0 && libsrt_setsockopt(h, fd, SRTO_LATENCY, "SRTO_LATENCY", &latency, sizeof(latency)) < 0) || (s->rcvlatency >= 0 && libsrt_setsockopt(h, fd, SRTO_RCVLATENCY, "SRTO_RCVLATENCY", &rcvlatency, sizeof(rcvlatency)) < 0) || (s->peerlatency >= 0 && libsrt_setsockopt(h, fd, SRTO_PEERLATENCY, "SRTO_PEERLATENCY", &peerlatency, sizeof(peerlatency)) < 0) || - (s->tlpktdrop >= 0 && libsrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) || + (s->tlpktdrop >= 0 && libsrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKTDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) || (s->nakreport >= 0 && libsrt_setsockopt(h, fd, SRTO_NAKREPORT, "SRTO_NAKREPORT", &s->nakreport, sizeof(s->nakreport)) < 0) || (connect_timeout >= 0 && libsrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) <0 ) || (s->sndbuf >= 0 && libsrt_setsockopt(h, fd, SRTO_SNDBUF, "SRTO_SNDBUF", &s->sndbuf, sizeof(s->sndbuf)) < 0) || @@ -363,7 +367,7 @@ static int libsrt_set_options_pre(URLContext *h, int fd) static int libsrt_setup(URLContext *h, const char *uri, int flags) { struct addrinfo hints = { 0 }, *ai, *cur_ai; - int port, fd = -1, listen_fd = -1; + int port, fd; SRTContext *s = h->priv_data; const char *p; char buf[256]; @@ -371,7 +375,7 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) char hostname[1024],proto[1024],path[1024]; char portstr[10]; int64_t open_timeout = 0; - int eid; + int eid, write_eid; av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); @@ -408,11 +412,6 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) cur_ai = ai; - eid = srt_epoll_create(); - if (eid < 0) - return libsrt_neterrno(h); - s->eid = eid; - restart: fd = srt_socket(cur_ai->ai_family, cur_ai->ai_socktype, 0); @@ -436,21 +435,30 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) if (libsrt_socket_nonblock(fd, 1) < 0) av_log(h, AV_LOG_DEBUG, "libsrt_socket_nonblock failed\n"); + ret = write_eid = libsrt_epoll_create(h, fd, 1); + if (ret < 0) + goto fail1; if (s->mode == SRT_MODE_LISTENER) { // multi-client - if ((ret = libsrt_listen(s->eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, h, s->listen_timeout)) < 0) + ret = libsrt_listen(write_eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, h, s->listen_timeout); + srt_epoll_release(write_eid); + if (ret < 0) goto fail1; - listen_fd = fd; + srt_close(fd); fd = ret; } else { if (s->mode == SRT_MODE_RENDEZVOUS) { - ret = srt_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen); - if (ret) + if (srt_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) { + ret = libsrt_neterrno(h); + srt_epoll_release(write_eid); goto fail1; + } } - if ((ret = libsrt_listen_connect(s->eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, - open_timeout, h, !!cur_ai->ai_next)) < 0) { + ret = libsrt_listen_connect(write_eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, + open_timeout, h, !!cur_ai->ai_next); + srt_epoll_release(write_eid); + if (ret < 0) { if (ret == AVERROR_EXIT) goto fail1; else @@ -471,9 +479,13 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) h->max_packet_size = packet_size; } + ret = eid = libsrt_epoll_create(h, fd, flags & AVIO_FLAG_WRITE); + if (eid < 0) + goto fail1; + h->is_streamed = 1; s->fd = fd; - s->listen_fd = listen_fd; + s->eid = eid; freeaddrinfo(ai); return 0; @@ -484,18 +496,13 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) cur_ai = cur_ai->ai_next; if (fd >= 0) srt_close(fd); - if (listen_fd >= 0) - srt_close(listen_fd); ret = 0; goto restart; } fail1: if (fd >= 0) srt_close(fd); - if (listen_fd >= 0) - srt_close(listen_fd); freeaddrinfo(ai); - srt_epoll_release(s->eid); return ret; } @@ -652,7 +659,7 @@ static int libsrt_read(URLContext *h, uint8_t *buf, int size) int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { - ret = libsrt_network_wait_fd_timeout(h, s->eid, s->fd, 0, h->rw_timeout, &h->interrupt_callback); + ret = libsrt_network_wait_fd_timeout(h, s->eid, 0, h->rw_timeout, &h->interrupt_callback); if (ret) return ret; } @@ -671,7 +678,7 @@ static int libsrt_write(URLContext *h, const uint8_t *buf, int size) int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { - ret = libsrt_network_wait_fd_timeout(h, s->eid, s->fd, 1, h->rw_timeout, &h->interrupt_callback); + ret = libsrt_network_wait_fd_timeout(h, s->eid, 1, h->rw_timeout, &h->interrupt_callback); if (ret) return ret; } @@ -688,12 +695,8 @@ static int libsrt_close(URLContext *h) { SRTContext *s = h->priv_data; - srt_close(s->fd); - - if (s->listen_fd >= 0) - srt_close(s->listen_fd); - srt_epoll_release(s->eid); + srt_close(s->fd); srt_cleanup(); diff --git a/libavformat/luodatdec.c b/libavformat/luodatdec.c new file mode 100644 index 000000000..3ec494a91 --- /dev/null +++ b/libavformat/luodatdec.c @@ -0,0 +1,126 @@ +/* + * CCTV DAT demuxer + * + * Copyright (c) 2020 Paul B Mahol + * + * 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/intreadwrite.h" +#include "avio_internal.h" +#include "avformat.h" +#include "internal.h" + +static int dat_probe(const AVProbeData *p) +{ + if (p->buf_size < 0x2080) + return 0; + + if (memcmp(p->buf, "luo ", 4)) + return 0; + + if (memcmp(p->buf + 0x1ffc, " oulliu ", 8)) + return 0; + + if (!AV_RL32(p->buf + 0x2004)) + return 0; + + if (memcmp(p->buf + 0x207c, " uil", 4)) + return 0; + + return AVPROBE_SCORE_MAX; +} + +static int dat_read_header(AVFormatContext *s) +{ + s->ctx_flags |= AVFMTCTX_NOHEADER; + + avio_seek(s->pb, 0x2000, SEEK_SET); + + return 0; +} + +static int dat_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVIOContext *pb = s->pb; + int index, ret, key, stream_id, stream_index, width, height, fps, pkt_size; + int64_t pts, pos = avio_tell(pb); + + if (avio_feof(pb)) + return AVERROR_EOF; + + if (avio_rb32(pb) != MKBETAG('l', 'i', 'u', ' ')) + return AVERROR_INVALIDDATA; + stream_id = avio_rl32(pb); + width = avio_rl32(pb); + height = avio_rl32(pb); + fps = avio_rl32(pb); + avio_skip(pb, 16); + key = avio_rl32(pb) == 1; + avio_skip(pb, 4); + index = avio_rl32(pb); + avio_skip(pb, 4); + pts = avio_rl64(pb); + pkt_size = avio_rl32(pb); + avio_skip(pb, 64); + + if (pkt_size == 0) + return AVERROR_EOF; + + for (stream_index = 0; stream_index < s->nb_streams; stream_index++) { + if (s->streams[stream_index]->id == stream_id) + break; + } + + if (stream_index == s->nb_streams) { + AVStream *st = avformat_new_stream(s, NULL); + + if (!st) + return AVERROR(ENOMEM); + + st->id = stream_id; + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = AV_CODEC_ID_H264; + st->codecpar->width = width; + st->codecpar->height = height; + avpriv_set_pts_info(st, 64, 1, fps); + } + + if (index >= s->nb_streams) + av_log(s, AV_LOG_WARNING, "Stream index out of range.\n"); + + ret = av_get_packet(pb, pkt, pkt_size); + if (ret < 0) + return ret; + pkt->pos = pos; + pkt->pts = pts; + pkt->stream_index = stream_index; + if (key) + pkt->flags |= AV_PKT_FLAG_KEY; + + return ret; +} + +AVInputFormat ff_luodat_demuxer = { + .name = "luodat", + .long_name = NULL_IF_CONFIG_SMALL("Video CCTV DAT"), + .read_probe = dat_probe, + .read_header = dat_read_header, + .read_packet = dat_read_packet, + .extensions = "dat", + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/lxfdec.c b/libavformat/lxfdec.c index fa84ceea7..509d19fe7 100644 --- a/libavformat/lxfdec.c +++ b/libavformat/lxfdec.c @@ -195,7 +195,7 @@ static int get_packet_header(AVFormatContext *s) return AVERROR_PATCHWELCOME; } - samples = track_size * 8 / st->codecpar->bits_per_coded_sample; + samples = track_size * 8LL / st->codecpar->bits_per_coded_sample; //use audio packet size to determine video standard //for NTSC we have one 8008-sample audio frame per five video frames @@ -210,6 +210,8 @@ static int get_packet_header(AVFormatContext *s) avpriv_set_pts_info(s->streams[0], 64, 1, 25); } + if (av_popcount(channels) * (uint64_t)track_size > INT_MAX) + return AVERROR_INVALIDDATA; //TODO: warning if track mask != (1 << channels) - 1? ret = av_popcount(channels) * track_size; diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 6f198f06e..30cbe18a8 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -98,6 +98,11 @@ #define MATROSKA_ID_TRACKFLAGENABLED 0xB9 #define MATROSKA_ID_TRACKFLAGDEFAULT 0x88 #define MATROSKA_ID_TRACKFLAGFORCED 0x55AA +#define MATROSKA_ID_TRACKFLAGHEARINGIMPAIRED 0x55AB +#define MATROSKA_ID_TRACKFLAGVISUALIMPAIRED 0x55AC +#define MATROSKA_ID_TRACKFLAGTEXTDESCRIPTIONS 0x55AD +#define MATROSKA_ID_TRACKFLAGORIGINAL 0x55AE +#define MATROSKA_ID_TRACKFLAGCOMMENTARY 0x55AF #define MATROSKA_ID_TRACKFLAGLACING 0x9C #define MATROSKA_ID_TRACKMINCACHE 0x6DE7 #define MATROSKA_ID_TRACKMAXCACHE 0x6DF8 diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 22d1ca575..65756ae06 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -48,6 +48,7 @@ #include "libavcodec/bytestream.h" #include "libavcodec/flac.h" #include "libavcodec/mpeg4audio.h" +#include "libavcodec/packet_internal.h" #include "avformat.h" #include "avio_internal.h" @@ -94,9 +95,20 @@ typedef enum { EBML_TYPE_COUNT } EbmlType; +typedef struct CountedElement { + union { + uint64_t u; + int64_t i; + double f; + char *s; + } el; + unsigned count; +} CountedElement; + typedef const struct EbmlSyntax { uint32_t id; - EbmlType type; + uint8_t type; + uint8_t is_counted; size_t list_elem_size; size_t data_offset; union { @@ -156,7 +168,7 @@ typedef struct MatroskaMasteringMeta { double white_x; double white_y; double max_luminance; - double min_luminance; + CountedElement min_luminance; } MatroskaMasteringMeta; typedef struct MatroskaTrackVideoColor { @@ -238,6 +250,11 @@ typedef struct MatroskaTrack { uint64_t default_duration; uint64_t flag_default; uint64_t flag_forced; + uint64_t flag_comment; + uint64_t flag_hearingimpaired; + uint64_t flag_visualimpaired; + uint64_t flag_textdescriptions; + CountedElement flag_original; uint64_t seek_preroll; MatroskaTrackVideo video; MatroskaTrackAudio audio; @@ -318,7 +335,7 @@ typedef struct MatroskaLevel { typedef struct MatroskaBlock { uint64_t duration; - int64_t reference; + CountedElement reference; uint64_t non_simple; EbmlBin bin; uint64_t additional_id; @@ -364,9 +381,11 @@ typedef struct MatroskaDemuxContext { /* byte position of the segment inside the stream */ int64_t segment_start; + AVPacket *pkt; + /* the packet queue */ - AVPacketList *queue; - AVPacketList *queue_end; + PacketList *queue; + PacketList *queue_end; int done; @@ -397,120 +416,120 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[27], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; static EbmlSyntax ebml_header[] = { - { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml, version), { .u = EBML_VERSION } }, - { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml, max_size), { .u = 8 } }, - { EBML_ID_EBMLMAXIDLENGTH, EBML_UINT, 0, offsetof(Ebml, id_length), { .u = 4 } }, - { EBML_ID_DOCTYPE, EBML_STR, 0, offsetof(Ebml, doctype), { .s = "(none)" } }, - { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml, doctype_version), { .u = 1 } }, + { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, 0, offsetof(Ebml, version), { .u = EBML_VERSION } }, + { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, 0, offsetof(Ebml, max_size), { .u = 8 } }, + { EBML_ID_EBMLMAXIDLENGTH, EBML_UINT, 0, 0, offsetof(Ebml, id_length), { .u = 4 } }, + { EBML_ID_DOCTYPE, EBML_STR, 0, 0, offsetof(Ebml, doctype), { .s = "(none)" } }, + { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, 0, offsetof(Ebml, doctype_version), { .u = 1 } }, { EBML_ID_EBMLVERSION, EBML_NONE }, { EBML_ID_DOCTYPEVERSION, EBML_NONE }, CHILD_OF(ebml_syntax) }; static EbmlSyntax ebml_syntax[] = { - { EBML_ID_HEADER, EBML_NEST, 0, 0, { .n = ebml_header } }, + { EBML_ID_HEADER, EBML_NEST, 0, 0, 0, { .n = ebml_header } }, { MATROSKA_ID_SEGMENT, EBML_STOP }, { 0 } }; static EbmlSyntax matroska_info[] = { - { MATROSKA_ID_TIMECODESCALE, EBML_UINT, 0, offsetof(MatroskaDemuxContext, time_scale), { .u = 1000000 } }, - { MATROSKA_ID_DURATION, EBML_FLOAT, 0, offsetof(MatroskaDemuxContext, duration) }, - { MATROSKA_ID_TITLE, EBML_UTF8, 0, offsetof(MatroskaDemuxContext, title) }, + { MATROSKA_ID_TIMECODESCALE, EBML_UINT, 0, 0, offsetof(MatroskaDemuxContext, time_scale), { .u = 1000000 } }, + { MATROSKA_ID_DURATION, EBML_FLOAT, 0, 0, offsetof(MatroskaDemuxContext, duration) }, + { MATROSKA_ID_TITLE, EBML_UTF8, 0, 0, offsetof(MatroskaDemuxContext, title) }, { MATROSKA_ID_WRITINGAPP, EBML_NONE }, - { MATROSKA_ID_MUXINGAPP, EBML_UTF8, 0, offsetof(MatroskaDemuxContext, muxingapp) }, - { MATROSKA_ID_DATEUTC, EBML_BIN, 0, offsetof(MatroskaDemuxContext, date_utc) }, + { MATROSKA_ID_MUXINGAPP, EBML_UTF8, 0, 0, offsetof(MatroskaDemuxContext, muxingapp) }, + { MATROSKA_ID_DATEUTC, EBML_BIN, 0, 0, offsetof(MatroskaDemuxContext, date_utc) }, { MATROSKA_ID_SEGMENTUID, EBML_NONE }, CHILD_OF(matroska_segment) }; static EbmlSyntax matroska_mastering_meta[] = { - { MATROSKA_ID_VIDEOCOLOR_RX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, r_x), { .f=-1 } }, - { MATROSKA_ID_VIDEOCOLOR_RY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, r_y), { .f=-1 } }, - { MATROSKA_ID_VIDEOCOLOR_GX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, g_x), { .f=-1 } }, - { MATROSKA_ID_VIDEOCOLOR_GY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, g_y), { .f=-1 } }, - { MATROSKA_ID_VIDEOCOLOR_BX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, b_x), { .f=-1 } }, - { MATROSKA_ID_VIDEOCOLOR_BY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, b_y), { .f=-1 } }, - { MATROSKA_ID_VIDEOCOLOR_WHITEX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, white_x), { .f=-1 } }, - { MATROSKA_ID_VIDEOCOLOR_WHITEY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, white_y), { .f=-1 } }, - { MATROSKA_ID_VIDEOCOLOR_LUMINANCEMIN, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, min_luminance), { .f=-1 } }, - { MATROSKA_ID_VIDEOCOLOR_LUMINANCEMAX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, max_luminance), { .f=-1 } }, + { MATROSKA_ID_VIDEOCOLOR_RX, EBML_FLOAT, 0, 0, offsetof(MatroskaMasteringMeta, r_x) }, + { MATROSKA_ID_VIDEOCOLOR_RY, EBML_FLOAT, 0, 0, offsetof(MatroskaMasteringMeta, r_y) }, + { MATROSKA_ID_VIDEOCOLOR_GX, EBML_FLOAT, 0, 0, offsetof(MatroskaMasteringMeta, g_x) }, + { MATROSKA_ID_VIDEOCOLOR_GY, EBML_FLOAT, 0, 0, offsetof(MatroskaMasteringMeta, g_y) }, + { MATROSKA_ID_VIDEOCOLOR_BX, EBML_FLOAT, 0, 0, offsetof(MatroskaMasteringMeta, b_x) }, + { MATROSKA_ID_VIDEOCOLOR_BY, EBML_FLOAT, 0, 0, offsetof(MatroskaMasteringMeta, b_y) }, + { MATROSKA_ID_VIDEOCOLOR_WHITEX, EBML_FLOAT, 0, 0, offsetof(MatroskaMasteringMeta, white_x) }, + { MATROSKA_ID_VIDEOCOLOR_WHITEY, EBML_FLOAT, 0, 0, offsetof(MatroskaMasteringMeta, white_y) }, + { MATROSKA_ID_VIDEOCOLOR_LUMINANCEMIN, EBML_FLOAT, 1, 0, offsetof(MatroskaMasteringMeta, min_luminance) }, + { MATROSKA_ID_VIDEOCOLOR_LUMINANCEMAX, EBML_FLOAT, 0, 0, offsetof(MatroskaMasteringMeta, max_luminance) }, CHILD_OF(matroska_track_video_color) }; static EbmlSyntax matroska_track_video_color[] = { - { MATROSKA_ID_VIDEOCOLORMATRIXCOEFF, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, matrix_coefficients), { .u = AVCOL_SPC_UNSPECIFIED } }, - { MATROSKA_ID_VIDEOCOLORBITSPERCHANNEL, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, bits_per_channel), { .u=0 } }, - { MATROSKA_ID_VIDEOCOLORCHROMASUBHORZ, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_horz), { .u=0 } }, - { MATROSKA_ID_VIDEOCOLORCHROMASUBVERT, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_vert), { .u=0 } }, - { MATROSKA_ID_VIDEOCOLORCBSUBHORZ, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, cb_sub_horz), { .u=0 } }, - { MATROSKA_ID_VIDEOCOLORCBSUBVERT, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, cb_sub_vert), { .u=0 } }, - { MATROSKA_ID_VIDEOCOLORCHROMASITINGHORZ, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_horz), { .u = MATROSKA_COLOUR_CHROMASITINGHORZ_UNDETERMINED } }, - { MATROSKA_ID_VIDEOCOLORCHROMASITINGVERT, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_vert), { .u = MATROSKA_COLOUR_CHROMASITINGVERT_UNDETERMINED } }, - { MATROSKA_ID_VIDEOCOLORRANGE, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, range), { .u = AVCOL_RANGE_UNSPECIFIED } }, - { MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, transfer_characteristics), { .u = AVCOL_TRC_UNSPECIFIED } }, - { MATROSKA_ID_VIDEOCOLORPRIMARIES, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, primaries), { .u = AVCOL_PRI_UNSPECIFIED } }, - { MATROSKA_ID_VIDEOCOLORMAXCLL, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_cll), { .u=0 } }, - { MATROSKA_ID_VIDEOCOLORMAXFALL, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_fall), { .u=0 } }, - { MATROSKA_ID_VIDEOCOLORMASTERINGMETA, EBML_NEST, 0, offsetof(MatroskaTrackVideoColor, mastering_meta), { .n = matroska_mastering_meta } }, + { MATROSKA_ID_VIDEOCOLORMATRIXCOEFF, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, matrix_coefficients), { .u = AVCOL_SPC_UNSPECIFIED } }, + { MATROSKA_ID_VIDEOCOLORBITSPERCHANNEL, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, bits_per_channel), { .u = 0 } }, + { MATROSKA_ID_VIDEOCOLORCHROMASUBHORZ, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_horz) }, + { MATROSKA_ID_VIDEOCOLORCHROMASUBVERT, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_vert) }, + { MATROSKA_ID_VIDEOCOLORCBSUBHORZ, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, cb_sub_horz) }, + { MATROSKA_ID_VIDEOCOLORCBSUBVERT, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, cb_sub_vert) }, + { MATROSKA_ID_VIDEOCOLORCHROMASITINGHORZ, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_horz), { .u = MATROSKA_COLOUR_CHROMASITINGHORZ_UNDETERMINED } }, + { MATROSKA_ID_VIDEOCOLORCHROMASITINGVERT, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_vert), { .u = MATROSKA_COLOUR_CHROMASITINGVERT_UNDETERMINED } }, + { MATROSKA_ID_VIDEOCOLORRANGE, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, range), { .u = AVCOL_RANGE_UNSPECIFIED } }, + { MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, transfer_characteristics), { .u = AVCOL_TRC_UNSPECIFIED } }, + { MATROSKA_ID_VIDEOCOLORPRIMARIES, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, primaries), { .u = AVCOL_PRI_UNSPECIFIED } }, + { MATROSKA_ID_VIDEOCOLORMAXCLL, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, max_cll) }, + { MATROSKA_ID_VIDEOCOLORMAXFALL, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoColor, max_fall) }, + { MATROSKA_ID_VIDEOCOLORMASTERINGMETA, EBML_NEST, 0, 0, offsetof(MatroskaTrackVideoColor, mastering_meta), { .n = matroska_mastering_meta } }, CHILD_OF(matroska_track_video) }; static EbmlSyntax matroska_track_video_projection[] = { - { MATROSKA_ID_VIDEOPROJECTIONTYPE, EBML_UINT, 0, offsetof(MatroskaTrackVideoProjection, type), { .u = MATROSKA_VIDEO_PROJECTION_TYPE_RECTANGULAR } }, - { MATROSKA_ID_VIDEOPROJECTIONPRIVATE, EBML_BIN, 0, offsetof(MatroskaTrackVideoProjection, private) }, - { MATROSKA_ID_VIDEOPROJECTIONPOSEYAW, EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, yaw), { .f=0.0 } }, - { MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH, EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, pitch), { .f=0.0 } }, - { MATROSKA_ID_VIDEOPROJECTIONPOSEROLL, EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, roll), { .f=0.0 } }, + { MATROSKA_ID_VIDEOPROJECTIONTYPE, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideoProjection, type), { .u = MATROSKA_VIDEO_PROJECTION_TYPE_RECTANGULAR } }, + { MATROSKA_ID_VIDEOPROJECTIONPRIVATE, EBML_BIN, 0, 0, offsetof(MatroskaTrackVideoProjection, private) }, + { MATROSKA_ID_VIDEOPROJECTIONPOSEYAW, EBML_FLOAT, 0, 0, offsetof(MatroskaTrackVideoProjection, yaw), { .f = 0.0 } }, + { MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH, EBML_FLOAT, 0, 0, offsetof(MatroskaTrackVideoProjection, pitch), { .f = 0.0 } }, + { MATROSKA_ID_VIDEOPROJECTIONPOSEROLL, EBML_FLOAT, 0, 0, offsetof(MatroskaTrackVideoProjection, roll), { .f = 0.0 } }, CHILD_OF(matroska_track_video) }; static EbmlSyntax matroska_track_video[] = { - { MATROSKA_ID_VIDEOFRAMERATE, EBML_FLOAT, 0, offsetof(MatroskaTrackVideo, frame_rate) }, - { MATROSKA_ID_VIDEODISPLAYWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo, display_width), { .u=-1 } }, - { MATROSKA_ID_VIDEODISPLAYHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo, display_height), { .u=-1 } }, - { MATROSKA_ID_VIDEOPIXELWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo, pixel_width) }, - { MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo, pixel_height) }, - { MATROSKA_ID_VIDEOCOLORSPACE, EBML_BIN, 0, offsetof(MatroskaTrackVideo, color_space) }, - { MATROSKA_ID_VIDEOALPHAMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo, alpha_mode) }, - { MATROSKA_ID_VIDEOCOLOR, EBML_NEST, sizeof(MatroskaTrackVideoColor), offsetof(MatroskaTrackVideo, color), { .n = matroska_track_video_color } }, - { MATROSKA_ID_VIDEOPROJECTION, EBML_NEST, 0, offsetof(MatroskaTrackVideo, projection), { .n = matroska_track_video_projection } }, + { MATROSKA_ID_VIDEOFRAMERATE, EBML_FLOAT, 0, 0, offsetof(MatroskaTrackVideo, frame_rate) }, + { MATROSKA_ID_VIDEODISPLAYWIDTH, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideo, display_width), { .u=-1 } }, + { MATROSKA_ID_VIDEODISPLAYHEIGHT, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideo, display_height), { .u=-1 } }, + { MATROSKA_ID_VIDEOPIXELWIDTH, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideo, pixel_width) }, + { MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideo, pixel_height) }, + { MATROSKA_ID_VIDEOCOLORSPACE, EBML_BIN, 0, 0, offsetof(MatroskaTrackVideo, color_space) }, + { MATROSKA_ID_VIDEOALPHAMODE, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideo, alpha_mode), { .u = 0 } }, + { MATROSKA_ID_VIDEOCOLOR, EBML_NEST, 0, sizeof(MatroskaTrackVideoColor), offsetof(MatroskaTrackVideo, color), { .n = matroska_track_video_color } }, + { MATROSKA_ID_VIDEOPROJECTION, EBML_NEST, 0, 0, offsetof(MatroskaTrackVideo, projection), { .n = matroska_track_video_projection } }, { MATROSKA_ID_VIDEOPIXELCROPB, EBML_NONE }, { MATROSKA_ID_VIDEOPIXELCROPT, EBML_NONE }, { MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE }, { MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE }, - { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_UINT, 0, offsetof(MatroskaTrackVideo, display_unit), { .u= MATROSKA_VIDEO_DISPLAYUNIT_PIXELS } }, - { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_UINT, 0, offsetof(MatroskaTrackVideo, interlaced), { .u = MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED } }, - { MATROSKA_ID_VIDEOFIELDORDER, EBML_UINT, 0, offsetof(MatroskaTrackVideo, field_order), { .u = MATROSKA_VIDEO_FIELDORDER_UNDETERMINED } }, - { MATROSKA_ID_VIDEOSTEREOMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo, stereo_mode), { .u = MATROSKA_VIDEO_STEREOMODE_TYPE_NB } }, + { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideo, display_unit), { .u= MATROSKA_VIDEO_DISPLAYUNIT_PIXELS } }, + { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideo, interlaced), { .u = MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED } }, + { MATROSKA_ID_VIDEOFIELDORDER, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideo, field_order), { .u = MATROSKA_VIDEO_FIELDORDER_UNDETERMINED } }, + { MATROSKA_ID_VIDEOSTEREOMODE, EBML_UINT, 0, 0, offsetof(MatroskaTrackVideo, stereo_mode), { .u = MATROSKA_VIDEO_STEREOMODE_TYPE_NB } }, { MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE }, CHILD_OF(matroska_track) }; static EbmlSyntax matroska_track_audio[] = { - { MATROSKA_ID_AUDIOSAMPLINGFREQ, EBML_FLOAT, 0, offsetof(MatroskaTrackAudio, samplerate), { .f = 8000.0 } }, - { MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, EBML_FLOAT, 0, offsetof(MatroskaTrackAudio, out_samplerate) }, - { MATROSKA_ID_AUDIOBITDEPTH, EBML_UINT, 0, offsetof(MatroskaTrackAudio, bitdepth) }, - { MATROSKA_ID_AUDIOCHANNELS, EBML_UINT, 0, offsetof(MatroskaTrackAudio, channels), { .u = 1 } }, + { MATROSKA_ID_AUDIOSAMPLINGFREQ, EBML_FLOAT, 0, 0, offsetof(MatroskaTrackAudio, samplerate), { .f = 8000.0 } }, + { MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, EBML_FLOAT, 0, 0, offsetof(MatroskaTrackAudio, out_samplerate) }, + { MATROSKA_ID_AUDIOBITDEPTH, EBML_UINT, 0, 0, offsetof(MatroskaTrackAudio, bitdepth) }, + { MATROSKA_ID_AUDIOCHANNELS, EBML_UINT, 0, 0, offsetof(MatroskaTrackAudio, channels), { .u = 1 } }, CHILD_OF(matroska_track) }; static EbmlSyntax matroska_track_encoding_compression[] = { - { MATROSKA_ID_ENCODINGCOMPALGO, EBML_UINT, 0, offsetof(MatroskaTrackCompression, algo), { .u = 0 } }, - { MATROSKA_ID_ENCODINGCOMPSETTINGS, EBML_BIN, 0, offsetof(MatroskaTrackCompression, settings) }, + { MATROSKA_ID_ENCODINGCOMPALGO, EBML_UINT, 0, 0, offsetof(MatroskaTrackCompression, algo), { .u = MATROSKA_TRACK_ENCODING_COMP_ZLIB } }, + { MATROSKA_ID_ENCODINGCOMPSETTINGS, EBML_BIN, 0, 0, offsetof(MatroskaTrackCompression, settings) }, CHILD_OF(matroska_track_encoding) }; static EbmlSyntax matroska_track_encoding_encryption[] = { - { MATROSKA_ID_ENCODINGENCALGO, EBML_UINT, 0, offsetof(MatroskaTrackEncryption,algo), {.u = 0} }, - { MATROSKA_ID_ENCODINGENCKEYID, EBML_BIN, 0, offsetof(MatroskaTrackEncryption,key_id) }, + { MATROSKA_ID_ENCODINGENCALGO, EBML_UINT, 0, 0, offsetof(MatroskaTrackEncryption,algo), {.u = 0} }, + { MATROSKA_ID_ENCODINGENCKEYID, EBML_BIN, 0, 0, offsetof(MatroskaTrackEncryption,key_id) }, { MATROSKA_ID_ENCODINGENCAESSETTINGS, EBML_NONE }, { MATROSKA_ID_ENCODINGSIGALGO, EBML_NONE }, { MATROSKA_ID_ENCODINGSIGHASHALGO, EBML_NONE }, @@ -519,54 +538,59 @@ static EbmlSyntax matroska_track_encoding_encryption[] = { CHILD_OF(matroska_track_encoding) }; static EbmlSyntax matroska_track_encoding[] = { - { MATROSKA_ID_ENCODINGSCOPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding, scope), { .u = 1 } }, - { MATROSKA_ID_ENCODINGTYPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding, type), { .u = 0 } }, - { MATROSKA_ID_ENCODINGCOMPRESSION, EBML_NEST, 0, offsetof(MatroskaTrackEncoding, compression), { .n = matroska_track_encoding_compression } }, - { MATROSKA_ID_ENCODINGENCRYPTION, EBML_NEST, 0, offsetof(MatroskaTrackEncoding, encryption), { .n = matroska_track_encoding_encryption } }, + { MATROSKA_ID_ENCODINGSCOPE, EBML_UINT, 0, 0, offsetof(MatroskaTrackEncoding, scope), { .u = 1 } }, + { MATROSKA_ID_ENCODINGTYPE, EBML_UINT, 0, 0, offsetof(MatroskaTrackEncoding, type), { .u = 0 } }, + { MATROSKA_ID_ENCODINGCOMPRESSION, EBML_NEST, 0, 0, offsetof(MatroskaTrackEncoding, compression), { .n = matroska_track_encoding_compression } }, + { MATROSKA_ID_ENCODINGENCRYPTION, EBML_NEST, 0, 0, offsetof(MatroskaTrackEncoding, encryption), { .n = matroska_track_encoding_encryption } }, { MATROSKA_ID_ENCODINGORDER, EBML_NONE }, CHILD_OF(matroska_track_encodings) }; static EbmlSyntax matroska_track_encodings[] = { - { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack, encodings), { .n = matroska_track_encoding } }, + { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, 0, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack, encodings), { .n = matroska_track_encoding } }, CHILD_OF(matroska_track) }; static EbmlSyntax matroska_track_plane[] = { - { MATROSKA_ID_TRACKPLANEUID, EBML_UINT, 0, offsetof(MatroskaTrackPlane,uid) }, - { MATROSKA_ID_TRACKPLANETYPE, EBML_UINT, 0, offsetof(MatroskaTrackPlane,type) }, + { MATROSKA_ID_TRACKPLANEUID, EBML_UINT, 0, 0, offsetof(MatroskaTrackPlane,uid) }, + { MATROSKA_ID_TRACKPLANETYPE, EBML_UINT, 0, 0, offsetof(MatroskaTrackPlane,type) }, CHILD_OF(matroska_track_combine_planes) }; static EbmlSyntax matroska_track_combine_planes[] = { - { MATROSKA_ID_TRACKPLANE, EBML_NEST, sizeof(MatroskaTrackPlane), offsetof(MatroskaTrackOperation,combine_planes), {.n = matroska_track_plane} }, + { MATROSKA_ID_TRACKPLANE, EBML_NEST, 0, sizeof(MatroskaTrackPlane), offsetof(MatroskaTrackOperation,combine_planes), {.n = matroska_track_plane} }, CHILD_OF(matroska_track_operation) }; static EbmlSyntax matroska_track_operation[] = { - { MATROSKA_ID_TRACKCOMBINEPLANES, EBML_NEST, 0, 0, {.n = matroska_track_combine_planes} }, + { MATROSKA_ID_TRACKCOMBINEPLANES, EBML_NEST, 0, 0, 0, {.n = matroska_track_combine_planes} }, CHILD_OF(matroska_track) }; static EbmlSyntax matroska_track[] = { - { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, offsetof(MatroskaTrack, num) }, - { MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, offsetof(MatroskaTrack, name) }, - { MATROSKA_ID_TRACKUID, EBML_UINT, 0, offsetof(MatroskaTrack, uid) }, - { MATROSKA_ID_TRACKTYPE, EBML_UINT, 0, offsetof(MatroskaTrack, type) }, - { MATROSKA_ID_CODECID, EBML_STR, 0, offsetof(MatroskaTrack, codec_id) }, - { MATROSKA_ID_CODECPRIVATE, EBML_BIN, 0, offsetof(MatroskaTrack, codec_priv) }, - { MATROSKA_ID_CODECDELAY, EBML_UINT, 0, offsetof(MatroskaTrack, codec_delay) }, - { MATROSKA_ID_TRACKLANGUAGE, EBML_STR, 0, offsetof(MatroskaTrack, language), { .s = "eng" } }, - { MATROSKA_ID_TRACKDEFAULTDURATION, EBML_UINT, 0, offsetof(MatroskaTrack, default_duration) }, - { MATROSKA_ID_TRACKTIMECODESCALE, EBML_FLOAT, 0, offsetof(MatroskaTrack, time_scale), { .f = 1.0 } }, - { MATROSKA_ID_TRACKFLAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTrack, flag_default), { .u = 1 } }, - { MATROSKA_ID_TRACKFLAGFORCED, EBML_UINT, 0, offsetof(MatroskaTrack, flag_forced), { .u = 0 } }, - { MATROSKA_ID_TRACKVIDEO, EBML_NEST, 0, offsetof(MatroskaTrack, video), { .n = matroska_track_video } }, - { MATROSKA_ID_TRACKAUDIO, EBML_NEST, 0, offsetof(MatroskaTrack, audio), { .n = matroska_track_audio } }, - { MATROSKA_ID_TRACKOPERATION, EBML_NEST, 0, offsetof(MatroskaTrack, operation), { .n = matroska_track_operation } }, - { MATROSKA_ID_TRACKCONTENTENCODINGS, EBML_NEST, 0, 0, { .n = matroska_track_encodings } }, - { MATROSKA_ID_TRACKMAXBLKADDID, EBML_UINT, 0, offsetof(MatroskaTrack, max_block_additional_id) }, - { MATROSKA_ID_SEEKPREROLL, EBML_UINT, 0, offsetof(MatroskaTrack, seek_preroll) }, + { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, 0, offsetof(MatroskaTrack, num) }, + { MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, 0, offsetof(MatroskaTrack, name) }, + { MATROSKA_ID_TRACKUID, EBML_UINT, 0, 0, offsetof(MatroskaTrack, uid) }, + { MATROSKA_ID_TRACKTYPE, EBML_UINT, 0, 0, offsetof(MatroskaTrack, type) }, + { MATROSKA_ID_CODECID, EBML_STR, 0, 0, offsetof(MatroskaTrack, codec_id) }, + { MATROSKA_ID_CODECPRIVATE, EBML_BIN, 0, 0, offsetof(MatroskaTrack, codec_priv) }, + { MATROSKA_ID_CODECDELAY, EBML_UINT, 0, 0, offsetof(MatroskaTrack, codec_delay), { .u = 0 } }, + { MATROSKA_ID_TRACKLANGUAGE, EBML_STR, 0, 0, offsetof(MatroskaTrack, language), { .s = "eng" } }, + { MATROSKA_ID_TRACKDEFAULTDURATION, EBML_UINT, 0, 0, offsetof(MatroskaTrack, default_duration) }, + { MATROSKA_ID_TRACKTIMECODESCALE, EBML_FLOAT, 0, 0, offsetof(MatroskaTrack, time_scale), { .f = 1.0 } }, + { MATROSKA_ID_TRACKFLAGCOMMENTARY, EBML_UINT, 0, 0, offsetof(MatroskaTrack, flag_comment), { .u = 0 } }, + { MATROSKA_ID_TRACKFLAGDEFAULT, EBML_UINT, 0, 0, offsetof(MatroskaTrack, flag_default), { .u = 1 } }, + { MATROSKA_ID_TRACKFLAGFORCED, EBML_UINT, 0, 0, offsetof(MatroskaTrack, flag_forced), { .u = 0 } }, + { MATROSKA_ID_TRACKFLAGHEARINGIMPAIRED, EBML_UINT, 0, 0, offsetof(MatroskaTrack, flag_hearingimpaired), { .u = 0 } }, + { MATROSKA_ID_TRACKFLAGVISUALIMPAIRED, EBML_UINT, 0, 0, offsetof(MatroskaTrack, flag_visualimpaired), { .u = 0 } }, + { MATROSKA_ID_TRACKFLAGTEXTDESCRIPTIONS, EBML_UINT, 0, 0, offsetof(MatroskaTrack, flag_textdescriptions), { .u = 0 } }, + { MATROSKA_ID_TRACKFLAGORIGINAL, EBML_UINT, 1, 0, offsetof(MatroskaTrack, flag_original), {.u = 0 } }, + { MATROSKA_ID_TRACKVIDEO, EBML_NEST, 0, 0, offsetof(MatroskaTrack, video), { .n = matroska_track_video } }, + { MATROSKA_ID_TRACKAUDIO, EBML_NEST, 0, 0, offsetof(MatroskaTrack, audio), { .n = matroska_track_audio } }, + { MATROSKA_ID_TRACKOPERATION, EBML_NEST, 0, 0, offsetof(MatroskaTrack, operation), { .n = matroska_track_operation } }, + { MATROSKA_ID_TRACKCONTENTENCODINGS, EBML_NEST, 0, 0, 0, { .n = matroska_track_encodings } }, + { MATROSKA_ID_TRACKMAXBLKADDID, EBML_UINT, 0, 0, offsetof(MatroskaTrack, max_block_additional_id), { .u = 0 } }, + { MATROSKA_ID_SEEKPREROLL, EBML_UINT, 0, 0, offsetof(MatroskaTrack, seek_preroll), { .u = 0 } }, { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE }, { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE }, { MATROSKA_ID_CODECNAME, EBML_NONE }, @@ -579,36 +603,36 @@ static EbmlSyntax matroska_track[] = { }; static EbmlSyntax matroska_tracks[] = { - { MATROSKA_ID_TRACKENTRY, EBML_NEST, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext, tracks), { .n = matroska_track } }, + { MATROSKA_ID_TRACKENTRY, EBML_NEST, 0, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext, tracks), { .n = matroska_track } }, CHILD_OF(matroska_segment) }; static EbmlSyntax matroska_attachment[] = { - { MATROSKA_ID_FILEUID, EBML_UINT, 0, offsetof(MatroskaAttachment, uid) }, - { MATROSKA_ID_FILENAME, EBML_UTF8, 0, offsetof(MatroskaAttachment, filename) }, - { MATROSKA_ID_FILEMIMETYPE, EBML_STR, 0, offsetof(MatroskaAttachment, mime) }, - { MATROSKA_ID_FILEDATA, EBML_BIN, 0, offsetof(MatroskaAttachment, bin) }, - { MATROSKA_ID_FILEDESC, EBML_UTF8, 0, offsetof(MatroskaAttachment, description) }, + { MATROSKA_ID_FILEUID, EBML_UINT, 0, 0, offsetof(MatroskaAttachment, uid) }, + { MATROSKA_ID_FILENAME, EBML_UTF8, 0, 0, offsetof(MatroskaAttachment, filename) }, + { MATROSKA_ID_FILEMIMETYPE, EBML_STR, 0, 0, offsetof(MatroskaAttachment, mime) }, + { MATROSKA_ID_FILEDATA, EBML_BIN, 0, 0, offsetof(MatroskaAttachment, bin) }, + { MATROSKA_ID_FILEDESC, EBML_UTF8, 0, 0, offsetof(MatroskaAttachment, description) }, CHILD_OF(matroska_attachments) }; static EbmlSyntax matroska_attachments[] = { - { MATROSKA_ID_ATTACHEDFILE, EBML_NEST, sizeof(MatroskaAttachment), offsetof(MatroskaDemuxContext, attachments), { .n = matroska_attachment } }, + { MATROSKA_ID_ATTACHEDFILE, EBML_NEST, 0, sizeof(MatroskaAttachment), offsetof(MatroskaDemuxContext, attachments), { .n = matroska_attachment } }, CHILD_OF(matroska_segment) }; static EbmlSyntax matroska_chapter_display[] = { - { MATROSKA_ID_CHAPSTRING, EBML_UTF8, 0, offsetof(MatroskaChapter, title) }, + { MATROSKA_ID_CHAPSTRING, EBML_UTF8, 0, 0, offsetof(MatroskaChapter, title) }, { MATROSKA_ID_CHAPLANG, EBML_NONE }, { MATROSKA_ID_CHAPCOUNTRY, EBML_NONE }, CHILD_OF(matroska_chapter_entry) }; static EbmlSyntax matroska_chapter_entry[] = { - { MATROSKA_ID_CHAPTERTIMESTART, EBML_UINT, 0, offsetof(MatroskaChapter, start), { .u = AV_NOPTS_VALUE } }, - { MATROSKA_ID_CHAPTERTIMEEND, EBML_UINT, 0, offsetof(MatroskaChapter, end), { .u = AV_NOPTS_VALUE } }, - { MATROSKA_ID_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaChapter, uid) }, - { MATROSKA_ID_CHAPTERDISPLAY, EBML_NEST, 0, 0, { .n = matroska_chapter_display } }, + { MATROSKA_ID_CHAPTERTIMESTART, EBML_UINT, 0, 0, offsetof(MatroskaChapter, start), { .u = AV_NOPTS_VALUE } }, + { MATROSKA_ID_CHAPTERTIMEEND, EBML_UINT, 0, 0, offsetof(MatroskaChapter, end), { .u = AV_NOPTS_VALUE } }, + { MATROSKA_ID_CHAPTERUID, EBML_UINT, 0, 0, offsetof(MatroskaChapter, uid) }, + { MATROSKA_ID_CHAPTERDISPLAY, EBML_NEST, 0, 0, 0, { .n = matroska_chapter_display } }, { MATROSKA_ID_CHAPTERFLAGHIDDEN, EBML_NONE }, { MATROSKA_ID_CHAPTERFLAGENABLED, EBML_NONE }, { MATROSKA_ID_CHAPTERPHYSEQUIV, EBML_NONE }, @@ -617,7 +641,7 @@ static EbmlSyntax matroska_chapter_entry[] = { }; static EbmlSyntax matroska_chapter[] = { - { MATROSKA_ID_CHAPTERATOM, EBML_NEST, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext, chapters), { .n = matroska_chapter_entry } }, + { MATROSKA_ID_CHAPTERATOM, EBML_NEST, 0, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext, chapters), { .n = matroska_chapter_entry } }, { MATROSKA_ID_EDITIONUID, EBML_NONE }, { MATROSKA_ID_EDITIONFLAGHIDDEN, EBML_NONE }, { MATROSKA_ID_EDITIONFLAGDEFAULT, EBML_NONE }, @@ -626,13 +650,13 @@ static EbmlSyntax matroska_chapter[] = { }; static EbmlSyntax matroska_chapters[] = { - { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, { .n = matroska_chapter } }, + { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, 0, { .n = matroska_chapter } }, CHILD_OF(matroska_segment) }; static EbmlSyntax matroska_index_pos[] = { - { MATROSKA_ID_CUETRACK, EBML_UINT, 0, offsetof(MatroskaIndexPos, track) }, - { MATROSKA_ID_CUECLUSTERPOSITION, EBML_UINT, 0, offsetof(MatroskaIndexPos, pos) }, + { MATROSKA_ID_CUETRACK, EBML_UINT, 0, 0, offsetof(MatroskaIndexPos, track) }, + { MATROSKA_ID_CUECLUSTERPOSITION, EBML_UINT, 0, 0, offsetof(MatroskaIndexPos, pos) }, { MATROSKA_ID_CUERELATIVEPOSITION,EBML_NONE }, { MATROSKA_ID_CUEDURATION, EBML_NONE }, { MATROSKA_ID_CUEBLOCKNUMBER, EBML_NONE }, @@ -640,102 +664,102 @@ static EbmlSyntax matroska_index_pos[] = { }; static EbmlSyntax matroska_index_entry[] = { - { MATROSKA_ID_CUETIME, EBML_UINT, 0, offsetof(MatroskaIndex, time) }, - { MATROSKA_ID_CUETRACKPOSITION, EBML_NEST, sizeof(MatroskaIndexPos), offsetof(MatroskaIndex, pos), { .n = matroska_index_pos } }, + { MATROSKA_ID_CUETIME, EBML_UINT, 0, 0, offsetof(MatroskaIndex, time) }, + { MATROSKA_ID_CUETRACKPOSITION, EBML_NEST, 0, sizeof(MatroskaIndexPos), offsetof(MatroskaIndex, pos), { .n = matroska_index_pos } }, CHILD_OF(matroska_index) }; static EbmlSyntax matroska_index[] = { - { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext, index), { .n = matroska_index_entry } }, + { MATROSKA_ID_POINTENTRY, EBML_NEST, 0, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext, index), { .n = matroska_index_entry } }, CHILD_OF(matroska_segment) }; static EbmlSyntax matroska_simpletag[] = { - { MATROSKA_ID_TAGNAME, EBML_UTF8, 0, offsetof(MatroskaTag, name) }, - { MATROSKA_ID_TAGSTRING, EBML_UTF8, 0, offsetof(MatroskaTag, string) }, - { MATROSKA_ID_TAGLANG, EBML_STR, 0, offsetof(MatroskaTag, lang), { .s = "und" } }, - { MATROSKA_ID_TAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTag, def) }, - { MATROSKA_ID_TAGDEFAULT_BUG, EBML_UINT, 0, offsetof(MatroskaTag, def) }, - { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag, sub), { .n = matroska_simpletag } }, + { MATROSKA_ID_TAGNAME, EBML_UTF8, 0, 0, offsetof(MatroskaTag, name) }, + { MATROSKA_ID_TAGSTRING, EBML_UTF8, 0, 0, offsetof(MatroskaTag, string) }, + { MATROSKA_ID_TAGLANG, EBML_STR, 0, 0, offsetof(MatroskaTag, lang), { .s = "und" } }, + { MATROSKA_ID_TAGDEFAULT, EBML_UINT, 0, 0, offsetof(MatroskaTag, def) }, + { MATROSKA_ID_TAGDEFAULT_BUG, EBML_UINT, 0, 0, offsetof(MatroskaTag, def) }, + { MATROSKA_ID_SIMPLETAG, EBML_NEST, 0, sizeof(MatroskaTag), offsetof(MatroskaTag, sub), { .n = matroska_simpletag } }, CHILD_OF(matroska_tag) }; static EbmlSyntax matroska_tagtargets[] = { - { MATROSKA_ID_TAGTARGETS_TYPE, EBML_STR, 0, offsetof(MatroskaTagTarget, type) }, - { MATROSKA_ID_TAGTARGETS_TYPEVALUE, EBML_UINT, 0, offsetof(MatroskaTagTarget, typevalue), { .u = 50 } }, - { MATROSKA_ID_TAGTARGETS_TRACKUID, EBML_UINT, 0, offsetof(MatroskaTagTarget, trackuid) }, - { MATROSKA_ID_TAGTARGETS_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaTagTarget, chapteruid) }, - { MATROSKA_ID_TAGTARGETS_ATTACHUID, EBML_UINT, 0, offsetof(MatroskaTagTarget, attachuid) }, + { MATROSKA_ID_TAGTARGETS_TYPE, EBML_STR, 0, 0, offsetof(MatroskaTagTarget, type) }, + { MATROSKA_ID_TAGTARGETS_TYPEVALUE, EBML_UINT, 0, 0, offsetof(MatroskaTagTarget, typevalue), { .u = 50 } }, + { MATROSKA_ID_TAGTARGETS_TRACKUID, EBML_UINT, 0, 0, offsetof(MatroskaTagTarget, trackuid), { .u = 0 } }, + { MATROSKA_ID_TAGTARGETS_CHAPTERUID, EBML_UINT, 0, 0, offsetof(MatroskaTagTarget, chapteruid), { .u = 0 } }, + { MATROSKA_ID_TAGTARGETS_ATTACHUID, EBML_UINT, 0, 0, offsetof(MatroskaTagTarget, attachuid), { .u = 0 } }, CHILD_OF(matroska_tag) }; static EbmlSyntax matroska_tag[] = { - { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTags, tag), { .n = matroska_simpletag } }, - { MATROSKA_ID_TAGTARGETS, EBML_NEST, 0, offsetof(MatroskaTags, target), { .n = matroska_tagtargets } }, + { MATROSKA_ID_SIMPLETAG, EBML_NEST, 0, sizeof(MatroskaTag), offsetof(MatroskaTags, tag), { .n = matroska_simpletag } }, + { MATROSKA_ID_TAGTARGETS, EBML_NEST, 0, 0, offsetof(MatroskaTags, target), { .n = matroska_tagtargets } }, CHILD_OF(matroska_tags) }; static EbmlSyntax matroska_tags[] = { - { MATROSKA_ID_TAG, EBML_NEST, sizeof(MatroskaTags), offsetof(MatroskaDemuxContext, tags), { .n = matroska_tag } }, + { MATROSKA_ID_TAG, EBML_NEST, 0, sizeof(MatroskaTags), offsetof(MatroskaDemuxContext, tags), { .n = matroska_tag } }, CHILD_OF(matroska_segment) }; static EbmlSyntax matroska_seekhead_entry[] = { - { MATROSKA_ID_SEEKID, EBML_UINT, 0, offsetof(MatroskaSeekhead, id) }, - { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, offsetof(MatroskaSeekhead, pos), { .u = -1 } }, + { MATROSKA_ID_SEEKID, EBML_UINT, 0, 0, offsetof(MatroskaSeekhead, id) }, + { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, 0, offsetof(MatroskaSeekhead, pos), { .u = -1 } }, CHILD_OF(matroska_seekhead) }; static EbmlSyntax matroska_seekhead[] = { - { MATROSKA_ID_SEEKENTRY, EBML_NEST, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext, seekhead), { .n = matroska_seekhead_entry } }, + { MATROSKA_ID_SEEKENTRY, EBML_NEST, 0, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext, seekhead), { .n = matroska_seekhead_entry } }, CHILD_OF(matroska_segment) }; static EbmlSyntax matroska_segment[] = { { MATROSKA_ID_CLUSTER, EBML_STOP }, - { MATROSKA_ID_INFO, EBML_LEVEL1, 0, 0, { .n = matroska_info } }, - { MATROSKA_ID_TRACKS, EBML_LEVEL1, 0, 0, { .n = matroska_tracks } }, - { MATROSKA_ID_ATTACHMENTS, EBML_LEVEL1, 0, 0, { .n = matroska_attachments } }, - { MATROSKA_ID_CHAPTERS, EBML_LEVEL1, 0, 0, { .n = matroska_chapters } }, - { MATROSKA_ID_CUES, EBML_LEVEL1, 0, 0, { .n = matroska_index } }, - { MATROSKA_ID_TAGS, EBML_LEVEL1, 0, 0, { .n = matroska_tags } }, - { MATROSKA_ID_SEEKHEAD, EBML_LEVEL1, 0, 0, { .n = matroska_seekhead } }, + { MATROSKA_ID_INFO, EBML_LEVEL1, 0, 0, 0, { .n = matroska_info } }, + { MATROSKA_ID_TRACKS, EBML_LEVEL1, 0, 0, 0, { .n = matroska_tracks } }, + { MATROSKA_ID_ATTACHMENTS, EBML_LEVEL1, 0, 0, 0, { .n = matroska_attachments } }, + { MATROSKA_ID_CHAPTERS, EBML_LEVEL1, 0, 0, 0, { .n = matroska_chapters } }, + { MATROSKA_ID_CUES, EBML_LEVEL1, 0, 0, 0, { .n = matroska_index } }, + { MATROSKA_ID_TAGS, EBML_LEVEL1, 0, 0, 0, { .n = matroska_tags } }, + { MATROSKA_ID_SEEKHEAD, EBML_LEVEL1, 0, 0, 0, { .n = matroska_seekhead } }, { 0 } /* We don't want to go back to level 0, so don't add the parent. */ }; static EbmlSyntax matroska_segments[] = { - { MATROSKA_ID_SEGMENT, EBML_NEST, 0, 0, { .n = matroska_segment } }, + { MATROSKA_ID_SEGMENT, EBML_NEST, 0, 0, 0, { .n = matroska_segment } }, { 0 } }; static EbmlSyntax matroska_blockmore[] = { - { MATROSKA_ID_BLOCKADDID, EBML_UINT, 0, offsetof(MatroskaBlock,additional_id), { .u = 1 } }, - { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN, 0, offsetof(MatroskaBlock,additional) }, + { MATROSKA_ID_BLOCKADDID, EBML_UINT, 0, 0, offsetof(MatroskaBlock,additional_id), { .u = 1 } }, + { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN, 0, 0, offsetof(MatroskaBlock,additional) }, CHILD_OF(matroska_blockadditions) }; static EbmlSyntax matroska_blockadditions[] = { - { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, 0, {.n = matroska_blockmore} }, + { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, 0, 0, {.n = matroska_blockmore} }, CHILD_OF(matroska_blockgroup) }; static EbmlSyntax matroska_blockgroup[] = { - { MATROSKA_ID_BLOCK, EBML_BIN, 0, offsetof(MatroskaBlock, bin) }, - { MATROSKA_ID_BLOCKADDITIONS, EBML_NEST, 0, 0, { .n = matroska_blockadditions} }, - { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock, duration) }, - { MATROSKA_ID_DISCARDPADDING, EBML_SINT, 0, offsetof(MatroskaBlock, discard_padding) }, - { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock, reference), { .i = INT64_MIN } }, + { MATROSKA_ID_BLOCK, EBML_BIN, 0, 0, offsetof(MatroskaBlock, bin) }, + { MATROSKA_ID_BLOCKADDITIONS, EBML_NEST, 0, 0, 0, { .n = matroska_blockadditions} }, + { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, 0, offsetof(MatroskaBlock, duration) }, + { MATROSKA_ID_DISCARDPADDING, EBML_SINT, 0, 0, offsetof(MatroskaBlock, discard_padding) }, + { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 1, 0, offsetof(MatroskaBlock, reference) }, { MATROSKA_ID_CODECSTATE, EBML_NONE }, - { 1, EBML_UINT, 0, offsetof(MatroskaBlock, non_simple), { .u = 1 } }, + { 1, EBML_UINT, 0, 0, offsetof(MatroskaBlock, non_simple), { .u = 1 } }, CHILD_OF(matroska_cluster_parsing) }; // The following array contains SimpleBlock and BlockGroup twice // in order to reuse the other values for matroska_cluster_enter. static EbmlSyntax matroska_cluster_parsing[] = { - { MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock, bin) }, - { MATROSKA_ID_BLOCKGROUP, EBML_NEST, 0, 0, { .n = matroska_blockgroup } }, - { MATROSKA_ID_CLUSTERTIMECODE, EBML_UINT, 0, offsetof(MatroskaCluster, timecode) }, + { MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, 0, offsetof(MatroskaBlock, bin) }, + { MATROSKA_ID_BLOCKGROUP, EBML_NEST, 0, 0, 0, { .n = matroska_blockgroup } }, + { MATROSKA_ID_CLUSTERTIMECODE, EBML_UINT, 0, 0, offsetof(MatroskaCluster, timecode) }, { MATROSKA_ID_SIMPLEBLOCK, EBML_STOP }, { MATROSKA_ID_BLOCKGROUP, EBML_STOP }, { MATROSKA_ID_CLUSTERPOSITION, EBML_NONE }, @@ -744,7 +768,7 @@ static EbmlSyntax matroska_cluster_parsing[] = { }; static EbmlSyntax matroska_cluster_enter[] = { - { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, { .n = &matroska_cluster_parsing[2] } }, + { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, 0, { .n = &matroska_cluster_parsing[2] } }, { 0 } }; #undef CHILD_OF @@ -917,12 +941,17 @@ static int ebml_read_length(MatroskaDemuxContext *matroska, AVIOContext *pb, /* * Read the next element as an unsigned int. - * Returns NEEDS_CHECKING. + * Returns NEEDS_CHECKING unless size == 0. */ -static int ebml_read_uint(AVIOContext *pb, int size, uint64_t *num) +static int ebml_read_uint(AVIOContext *pb, int size, + uint64_t default_value, uint64_t *num) { int n = 0; + if (size == 0) { + *num = default_value; + return 0; + } /* big-endian ordering; build up number */ *num = 0; while (n++ < size) @@ -933,14 +962,16 @@ static int ebml_read_uint(AVIOContext *pb, int size, uint64_t *num) /* * Read the next element as a signed int. - * Returns NEEDS_CHECKING. + * Returns NEEDS_CHECKING unless size == 0. */ -static int ebml_read_sint(AVIOContext *pb, int size, int64_t *num) +static int ebml_read_sint(AVIOContext *pb, int size, + int64_t default_value, int64_t *num) { int n = 1; if (size == 0) { - *num = 0; + *num = default_value; + return 0; } else { *num = sign_extend(avio_r8(pb), 8); @@ -954,17 +985,19 @@ static int ebml_read_sint(AVIOContext *pb, int size, int64_t *num) /* * Read the next element as a float. - * Returns NEEDS_CHECKING or < 0 on obvious failure. + * Returns 0 if size == 0, NEEDS_CHECKING or < 0 on obvious failure. */ -static int ebml_read_float(AVIOContext *pb, int size, double *num) +static int ebml_read_float(AVIOContext *pb, int size, + double default_value, double *num) { - if (size == 0) - *num = 0; - else if (size == 4) + if (size == 0) { + *num = default_value; + return 0; + } else if (size == 4) { *num = av_int2float(avio_rb32(pb)); - else if (size == 8) + } else if (size == 8) { *num = av_int2double(avio_rb64(pb)); - else + } else return AVERROR_INVALIDDATA; return NEEDS_CHECKING; @@ -974,20 +1007,27 @@ static int ebml_read_float(AVIOContext *pb, int size, double *num) * Read the next element as an ASCII string. * 0 is success, < 0 or NEEDS_CHECKING is failure. */ -static int ebml_read_ascii(AVIOContext *pb, int size, char **str) +static int ebml_read_ascii(AVIOContext *pb, int size, + const char *default_value, char **str) { char *res; int ret; - /* EBML strings are usually not 0-terminated, so we allocate one - * byte more, read the string and NULL-terminate it ourselves. */ - if (!(res = av_malloc(size + 1))) - return AVERROR(ENOMEM); - if ((ret = avio_read(pb, (uint8_t *) res, size)) != size) { - av_free(res); - return ret < 0 ? ret : NEEDS_CHECKING; + if (size == 0 && default_value) { + res = av_strdup(default_value); + if (!res) + return AVERROR(ENOMEM); + } else { + /* EBML strings are usually not 0-terminated, so we allocate one + * byte more, read the string and NUL-terminate it ourselves. */ + if (!(res = av_malloc(size + 1))) + return AVERROR(ENOMEM); + if ((ret = avio_read(pb, (uint8_t *) res, size)) != size) { + av_free(res); + return ret < 0 ? ret : NEEDS_CHECKING; + } + (res)[size] = '\0'; } - (res)[size] = '\0'; av_free(*str); *str = res; @@ -1086,28 +1126,29 @@ static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, int res; if (data) { - for (int i = 0; syntax[i].id; i++) + for (int i = 0; syntax[i].id; i++) { + void *dst = (char *)data + syntax[i].data_offset; switch (syntax[i].type) { case EBML_UINT: - *(uint64_t *) ((char *) data + syntax[i].data_offset) = syntax[i].def.u; + *(uint64_t *)dst = syntax[i].def.u; break; case EBML_SINT: - *(int64_t *) ((char *) data + syntax[i].data_offset) = syntax[i].def.i; + *(int64_t *) dst = syntax[i].def.i; break; case EBML_FLOAT: - *(double *) ((char *) data + syntax[i].data_offset) = syntax[i].def.f; + *(double *) dst = syntax[i].def.f; break; case EBML_STR: case EBML_UTF8: // the default may be NULL if (syntax[i].def.s) { - uint8_t **dst = (uint8_t **) ((uint8_t *) data + syntax[i].data_offset); - *dst = av_strdup(syntax[i].def.s); - if (!*dst) + *(char**)dst = av_strdup(syntax[i].def.s); + if (!*(char**)dst) return AVERROR(ENOMEM); } break; } + } if (!matroska->levels[matroska->num_levels - 1].length) { matroska->num_levels--; @@ -1384,17 +1425,17 @@ static int ebml_parse(MatroskaDemuxContext *matroska, switch (syntax->type) { case EBML_UINT: - res = ebml_read_uint(pb, length, data); + res = ebml_read_uint(pb, length, syntax->def.u, data); break; case EBML_SINT: - res = ebml_read_sint(pb, length, data); + res = ebml_read_sint(pb, length, syntax->def.i, data); break; case EBML_FLOAT: - res = ebml_read_float(pb, length, data); + res = ebml_read_float(pb, length, syntax->def.f, data); break; case EBML_STR: case EBML_UTF8: - res = ebml_read_ascii(pb, length, data); + res = ebml_read_ascii(pb, length, syntax->def.s, data); break; case EBML_BIN: res = ebml_read_binary(pb, length, pos_alt, data); @@ -1467,6 +1508,12 @@ static int ebml_parse(MatroskaDemuxContext *matroska, } level_check: + if (syntax->is_counted && data) { + CountedElement *elem = data; + if (elem->count != UINT_MAX) + elem->count++; + } + if (level_check == LEVEL_ENDED && matroska->num_levels) { level = &matroska->levels[matroska->num_levels - 1]; pos = avio_tell(pb); @@ -2027,12 +2074,12 @@ static int matroska_parse_flac(AVFormatContext *s, static int mkv_field_order(MatroskaDemuxContext *matroska, int64_t field_order) { - int major, minor, micro, bttb = 0; + int minor, micro, bttb = 0; /* workaround a bug in our Matroska muxer, introduced in version 57.36 alongside * this function, and fixed in 57.52 */ - if (matroska->muxingapp && sscanf(matroska->muxingapp, "Lavf%d.%d.%d", &major, &minor, µ) == 3) - bttb = (major == 57 && minor >= 36 && minor <= 51 && micro >= 100); + if (matroska->muxingapp && sscanf(matroska->muxingapp, "Lavf57.%d.%d", &minor, µ) == 2) + bttb = (minor >= 36 && minor <= 51 && micro >= 100); switch (field_order) { case MATROSKA_VIDEO_FIELDORDER_PROGRESSIVE: @@ -2092,7 +2139,10 @@ static int mkv_parse_video_color(AVStream *st, const MatroskaTrack *track) { mastering_meta->g_x > 0 && mastering_meta->g_y > 0 && mastering_meta->b_x > 0 && mastering_meta->b_y > 0 && mastering_meta->white_x > 0 && mastering_meta->white_y > 0; - has_mastering_luminance = mastering_meta->max_luminance > 0; + has_mastering_luminance = mastering_meta->max_luminance > + mastering_meta->min_luminance.el.f && + mastering_meta->min_luminance.el.f >= 0 && + mastering_meta->min_luminance.count; if (color->matrix_coefficients != AVCOL_SPC_RESERVED) st->codecpar->color_space = color->matrix_coefficients; @@ -2151,7 +2201,7 @@ static int mkv_parse_video_color(AVStream *st, const MatroskaTrack *track) { } if (has_mastering_luminance) { metadata->max_luminance = av_d2q(mastering_meta->max_luminance, INT_MAX); - metadata->min_luminance = av_d2q(mastering_meta->min_luminance, INT_MAX); + metadata->min_luminance = av_d2q(mastering_meta->min_luminance.el.f, INT_MAX); metadata->has_luminance = 1; } } @@ -2162,30 +2212,26 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track, void *logctx) { AVSphericalMapping *spherical; + const MatroskaTrackVideoProjection *mkv_projection = &track->video.projection; + const uint8_t *priv_data = mkv_projection->private.data; enum AVSphericalProjection projection; size_t spherical_size; uint32_t l = 0, t = 0, r = 0, b = 0; uint32_t padding = 0; int ret; - GetByteContext gb; - bytestream2_init(&gb, track->video.projection.private.data, - track->video.projection.private.size); - - if (bytestream2_get_byte(&gb) != 0) { + if (mkv_projection->private.size && priv_data[0] != 0) { av_log(logctx, AV_LOG_WARNING, "Unknown spherical metadata\n"); return 0; } - bytestream2_skip(&gb, 3); // flags - switch (track->video.projection.type) { case MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR: if (track->video.projection.private.size == 20) { - t = bytestream2_get_be32(&gb); - b = bytestream2_get_be32(&gb); - l = bytestream2_get_be32(&gb); - r = bytestream2_get_be32(&gb); + t = AV_RB32(priv_data + 4); + b = AV_RB32(priv_data + 8); + l = AV_RB32(priv_data + 12); + r = AV_RB32(priv_data + 16); if (b >= UINT_MAX - t || r >= UINT_MAX - l) { av_log(logctx, AV_LOG_ERROR, @@ -2209,14 +2255,14 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track, av_log(logctx, AV_LOG_ERROR, "Missing projection private properties\n"); return AVERROR_INVALIDDATA; } else if (track->video.projection.private.size == 12) { - uint32_t layout = bytestream2_get_be32(&gb); + uint32_t layout = AV_RB32(priv_data + 4); if (layout) { av_log(logctx, AV_LOG_WARNING, "Unknown spherical cubemap layout %"PRIu32"\n", layout); return 0; } projection = AV_SPHERICAL_CUBEMAP; - padding = bytestream2_get_be32(&gb); + padding = AV_RB32(priv_data + 8); } else { av_log(logctx, AV_LOG_ERROR, "Unknown spherical metadata\n"); return AVERROR_INVALIDDATA; @@ -2428,8 +2474,7 @@ static int matroska_parse_tracks(AVFormatContext *s) encodings[0].compression.settings.size); for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) { - if (!strncmp(ff_mkv_codec_tags[j].str, track->codec_id, - strlen(ff_mkv_codec_tags[j].str))) { + if (av_strstart(track->codec_id, ff_mkv_codec_tags[j].str, NULL)) { codec_id = ff_mkv_codec_tags[j].id; break; } @@ -2684,8 +2729,12 @@ static int matroska_parse_tracks(AVFormatContext *s) av_log(matroska->ctx, AV_LOG_INFO, "Unknown/unsupported AVCodecID %s.\n", track->codec_id); - if (track->time_scale < 0.01) + if (track->time_scale < 0.01) { + av_log(matroska->ctx, AV_LOG_WARNING, + "Track TimestampScale too small %f, assuming 1.0.\n", + track->time_scale); track->time_scale = 1.0; + } avpriv_set_pts_info(st, 64, matroska->time_scale * track->time_scale, 1000 * 1000 * 1000); /* 64 bit pts in ns */ @@ -2704,6 +2753,15 @@ static int matroska_parse_tracks(AVFormatContext *s) st->disposition |= AV_DISPOSITION_DEFAULT; if (track->flag_forced) st->disposition |= AV_DISPOSITION_FORCED; + if (track->flag_comment) + st->disposition |= AV_DISPOSITION_COMMENT; + if (track->flag_hearingimpaired) + st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; + if (track->flag_visualimpaired) + st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED; + if (track->flag_original.count > 0) + st->disposition |= track->flag_original.el.u ? AV_DISPOSITION_ORIGINAL + : AV_DISPOSITION_DUB; if (!st->codecpar->extradata) { if (extradata) { @@ -2830,6 +2888,9 @@ static int matroska_parse_tracks(AVFormatContext *s) } } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) { st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; + + if (track->flag_textdescriptions) + st->disposition |= AV_DISPOSITION_DESCRIPTIONS; } } @@ -2884,6 +2945,10 @@ static int matroska_read_header(AVFormatContext *s) } ebml_free(ebml_syntax, &ebml); + matroska->pkt = av_packet_alloc(); + if (!matroska->pkt) + return AVERROR(ENOMEM); + /* The next thing is a segment. */ pos = avio_tell(matroska->ctx->pb); res = ebml_parse(matroska, matroska_segments, matroska); @@ -2894,6 +2959,8 @@ static int matroska_read_header(AVFormatContext *s) goto fail; pos = avio_tell(matroska->ctx->pb); res = ebml_parse(matroska, matroska_segment, matroska); + if (res == AVERROR(EIO)) // EOF is translated to EIO, this exists the loop on EOF + goto fail; } /* Set data_offset as it might be needed later by seek_frame_generic. */ if (matroska->current_id == MATROSKA_ID_CLUSTER) @@ -2931,8 +2998,7 @@ static int matroska_read_header(AVFormatContext *s) st->codecpar->codec_id = AV_CODEC_ID_NONE; for (i = 0; mkv_image_mime_tags[i].id != AV_CODEC_ID_NONE; i++) { - if (!strncmp(mkv_image_mime_tags[i].str, attachments[j].mime, - strlen(mkv_image_mime_tags[i].str))) { + if (av_strstart(attachments[j].mime, mkv_image_mime_tags[i].str, NULL)) { st->codecpar->codec_id = mkv_image_mime_tags[i].id; break; } @@ -2946,7 +3012,7 @@ static int matroska_read_header(AVFormatContext *s) st->disposition |= AV_DISPOSITION_ATTACHED_PIC; st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; - av_init_packet(pkt); + av_packet_unref(pkt); pkt->buf = attachments[j].bin.buf; attachments[j].bin.buf = NULL; pkt->data = attachments[j].bin.data; @@ -2961,8 +3027,7 @@ static int matroska_read_header(AVFormatContext *s) attachments[j].bin.size); for (i = 0; mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) { - if (!strncmp(mkv_mime_tags[i].str, attachments[j].mime, - strlen(mkv_mime_tags[i].str))) { + if (av_strstart(attachments[j].mime, mkv_mime_tags[i].str, NULL)) { st->codecpar->codec_id = mkv_mime_tags[i].id; break; } @@ -3004,7 +3069,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, MatroskaTrack *tracks = matroska->tracks.elem; MatroskaTrack *track; - ff_packet_list_get(&matroska->queue, &matroska->queue_end, pkt); + avpriv_packet_list_get(&matroska->queue, &matroska->queue_end, pkt); track = &tracks[pkt->stream_index]; if (track->has_palette) { uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); @@ -3026,7 +3091,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, */ static void matroska_clear_queue(MatroskaDemuxContext *matroska) { - ff_packet_list_free(&matroska->queue, &matroska->queue_end); + avpriv_packet_list_free(&matroska->queue, &matroska->queue_end); } static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf, @@ -3179,7 +3244,7 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, while (track->audio.pkt_cnt) { int ret; - AVPacket pktl, *pkt = &pktl; + AVPacket *pkt = matroska->pkt; ret = av_new_packet(pkt, a); if (ret < 0) { @@ -3192,7 +3257,7 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, track->audio.buf_timecode = AV_NOPTS_VALUE; pkt->pos = pos; pkt->stream_index = st->index; - ret = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0); + ret = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, NULL, 0); if (ret < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); @@ -3316,7 +3381,7 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, uint64_t duration, int64_t pos) { - AVPacket pktl, *pkt = &pktl; + AVPacket *pkt = matroska->pkt; uint8_t *id, *settings, *text, *buf; int id_len, settings_len, text_len; uint8_t *p, *q; @@ -3414,7 +3479,7 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, pkt->duration = duration; pkt->pos = pos; - err = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0); + err = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, NULL, 0); if (err < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); @@ -3433,7 +3498,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, { uint8_t *pkt_data = data; int res = 0; - AVPacket pktl, *pkt = &pktl; + AVPacket *pkt = matroska->pkt; if (st->codecpar->codec_id == AV_CODEC_ID_WAVPACK) { res = matroska_parse_wavpack(track, &pkt_data, &pkt_size); @@ -3463,7 +3528,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, if (!pkt_size && !additional_size) goto no_output; - av_init_packet(pkt); + av_packet_unref(pkt); if (!buf) pkt->buf = av_buffer_create(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE, NULL, NULL, 0); @@ -3525,7 +3590,7 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif - res = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0); + res = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, NULL, 0); if (res < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); @@ -3555,7 +3620,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf uint32_t lace_size[256]; int n, flags, laces = 0; uint64_t num; - int trust_default_duration = 1; + int trust_default_duration; ffio_init_context(&pb, data, size, 0, NULL, NULL, NULL, NULL); @@ -3589,7 +3654,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf if (cluster_time != (uint64_t) -1 && (block_time >= 0 || cluster_time >= -block_time)) { - timecode = cluster_time + block_time - track->codec_delay_in_track_tb; + uint64_t timecode_cluster_in_track_tb = (double) cluster_time / track->time_scale; + timecode = timecode_cluster_in_track_tb + block_time - track->codec_delay_in_track_tb; if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE && timecode < track->end_timecode) is_keyframe = 0; /* overlapping subtitles are not key frame */ @@ -3609,7 +3675,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf return res; if (is_keyframe) matroska->skip_to_keyframe = 0; - else if (!st->skip_to_keyframe) { + else if (!st->internal->skip_to_keyframe) { av_log(matroska->ctx, AV_LOG_ERROR, "File is broken, keyframes not correctly marked!\n"); matroska->skip_to_keyframe = 0; } @@ -3622,7 +3688,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf return res; } - if (track->audio.samplerate == 8000) { + trust_default_duration = track->default_duration != 0; + if (track->audio.samplerate == 8000 && trust_default_duration) { // If this is needed for more codecs, then add them here if (st->codecpar->codec_id == AV_CODEC_ID_AC3) { if (track->audio.samplerate != st->codecpar->sample_rate || !st->codecpar->frame_size) @@ -3714,7 +3781,7 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska) res = ebml_parse(matroska, matroska_cluster_parsing, cluster); if (res >= 0 && block->bin.size > 0) { - int is_keyframe = block->non_simple ? block->reference == INT64_MIN : -1; + int is_keyframe = block->non_simple ? block->reference.count == 0 : -1; uint8_t* additional = block->additional.size > 0 ? block->additional.data : NULL; @@ -3806,10 +3873,10 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, /* We seek to a level 1 element, so set the appropriate status. */ matroska_reset_status(matroska, 0, st->index_entries[index].pos); if (flags & AVSEEK_FLAG_ANY) { - st->skip_to_keyframe = 0; + st->internal->skip_to_keyframe = 0; matroska->skip_to_timecode = timestamp; } else { - st->skip_to_keyframe = 1; + st->internal->skip_to_keyframe = 1; matroska->skip_to_timecode = st->index_entries[index].timestamp; } matroska->skip_to_keyframe = 1; @@ -3822,7 +3889,7 @@ err: matroska_reset_status(matroska, 0, -1); matroska->resync_pos = -1; matroska_clear_queue(matroska); - st->skip_to_keyframe = + st->internal->skip_to_keyframe = matroska->skip_to_keyframe = 0; matroska->done = 0; return -1; @@ -3835,6 +3902,7 @@ static int matroska_read_close(AVFormatContext *s) int n; matroska_clear_queue(matroska); + av_packet_free(&matroska->pkt); for (n = 0; n < matroska->tracks.nb_elem; n++) if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) @@ -4260,7 +4328,7 @@ static const AVClass webm_dash_class = { AVInputFormat ff_matroska_demuxer = { .name = "matroska,webm", .long_name = NULL_IF_CONFIG_SMALL("Matroska / WebM"), - .extensions = "mkv,mk3d,mka,mks", + .extensions = "mkv,mk3d,mka,mks,webm", .priv_data_size = sizeof(MatroskaDemuxContext), .read_probe = matroska_probe, .read_header = matroska_read_header, diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index eaed02bc9..bbf231f2a 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -137,7 +137,7 @@ typedef struct MatroskaMuxContext { mkv_cues cues; int64_t cues_pos; - AVPacket cur_audio_pkt; + AVPacket *cur_audio_pkt; unsigned nb_attachments; int have_video; @@ -154,6 +154,7 @@ typedef struct MatroskaMuxContext { int is_dash; int dash_track_number; int allow_raw_vfw; + int flipped_raw_rgb; int default_mode; uint32_t segment_uid[4]; @@ -450,7 +451,7 @@ static void mkv_deinit(AVFormatContext *s) { MatroskaMuxContext *mkv = s->priv_data; - av_packet_unref(&mkv->cur_audio_pkt); + av_packet_free(&mkv->cur_audio_pkt); ffio_free_dyn_buf(&mkv->cluster_bc); ffio_free_dyn_buf(&mkv->info.bc); @@ -764,6 +765,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, int native_id, int qt_id) { AVIOContext *dyn_cp; + MatroskaMuxContext *mkv = s->priv_data; uint8_t *codecpriv; int ret, codecpriv_size; @@ -802,7 +804,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, ret = AVERROR(EINVAL); } - ff_put_bmp_header(dyn_cp, par, 0, 0); + ff_put_bmp_header(dyn_cp, par, 0, 0, mkv->flipped_raw_rgb); } } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) { unsigned int tag; @@ -1145,7 +1147,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value); tag = av_dict_get(st->metadata, "language", NULL, 0); put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, - tag && tag->value ? tag->value : "und"); + tag && tag->value[0] ? tag->value : "und"); // The default value for TRACKFLAGDEFAULT is 1, so add element // if we need to clear it. @@ -1189,6 +1191,18 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, put_ebml_string(pb, MATROSKA_ID_CODECID, codec_id); } else { + if (st->disposition & AV_DISPOSITION_COMMENT) + put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGCOMMENTARY, 1); + if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED) + put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGHEARINGIMPAIRED, 1); + if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED) + put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGVISUALIMPAIRED, 1); + if (st->disposition & (AV_DISPOSITION_ORIGINAL | AV_DISPOSITION_DUB) && + (st->disposition & (AV_DISPOSITION_ORIGINAL | AV_DISPOSITION_DUB)) + != (AV_DISPOSITION_ORIGINAL | AV_DISPOSITION_DUB)) + put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGORIGINAL, + !!(st->disposition & AV_DISPOSITION_ORIGINAL)); + // look for a codec ID string specific to mkv to use, // if none are found, use AVI codes if (par->codec_id != AV_CODEC_ID_RAWVIDEO || par->codec_tag) { @@ -1350,6 +1364,8 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, av_log(s, AV_LOG_ERROR, "Subtitle codec %d is not supported.\n", par->codec_id); return AVERROR(ENOSYS); } + if (mkv->mode != MODE_WEBM && st->disposition & AV_DISPOSITION_DESCRIPTIONS) + put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGTEXTDESCRIPTIONS, 1); if (mkv->mode != MODE_WEBM || par->codec_id != AV_CODEC_ID_WEBVTT) native_id = MATROSKA_TRACK_TYPE_SUBTITLE; @@ -1609,24 +1625,29 @@ static int mkv_write_tags(AVFormatContext *s) return 0; } +static int mkv_new_chapter_ids_needed(const AVFormatContext *s) +{ + for (unsigned i = 0; i < s->nb_chapters; i++) { + if (!s->chapters[i]->id) + return 1; + for (unsigned j = 0; j < i; j++) + if (s->chapters[j]->id == s->chapters[i]->id) + return 1; + } + return 0; +} + static int mkv_write_chapters(AVFormatContext *s) { MatroskaMuxContext *mkv = s->priv_data; AVIOContext *dyn_cp = NULL, *dyn_tags = NULL, **tags, *pb = s->pb; ebml_master editionentry; - uint64_t chapter_id_offset = 0; AVRational scale = {1, 1E9}; - int i, ret; + int ret, create_new_ids; if (!s->nb_chapters || mkv->wrote_chapters) return 0; - for (i = 0; i < s->nb_chapters; i++) - if (!s->chapters[i]->id) { - chapter_id_offset = 1; - break; - } - ret = start_ebml_master_crc32(&dyn_cp, mkv); if (ret < 0) return ret; @@ -1640,12 +1661,19 @@ static int mkv_write_chapters(AVFormatContext *s) } else tags = NULL; - for (i = 0; i < s->nb_chapters; i++) { + create_new_ids = mkv_new_chapter_ids_needed(s); + + for (unsigned i = 0; i < s->nb_chapters; i++) { ebml_master chapteratom, chapterdisplay; const AVChapter *c = s->chapters[i]; int64_t chapterstart = av_rescale_q(c->start, c->time_base, scale); int64_t chapterend = av_rescale_q(c->end, c->time_base, scale); const AVDictionaryEntry *t; +#if FF_API_CHAPTER_ID_INT + uint64_t uid = create_new_ids ? i + 1ULL : (uint32_t)c->id; +#else + uint64_t uid = create_new_ids ? i + 1ULL : c->id; +#endif if (chapterstart < 0 || chapterstart > chapterend || chapterend < 0) { av_log(s, AV_LOG_ERROR, "Invalid chapter start (%"PRId64") or end (%"PRId64").\n", @@ -1655,8 +1683,7 @@ static int mkv_write_chapters(AVFormatContext *s) } chapteratom = start_ebml_master(dyn_cp, MATROSKA_ID_CHAPTERATOM, 0); - put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERUID, - (uint32_t)c->id + chapter_id_offset); + put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERUID, uid); put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERTIMESTART, chapterstart); put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERTIMEEND, chapterend); if ((t = av_dict_get(c->metadata, "title", NULL, 0))) { @@ -1669,8 +1696,7 @@ static int mkv_write_chapters(AVFormatContext *s) if (tags && mkv_check_tag(c->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID)) { ret = mkv_write_tag(mkv, c->metadata, tags, NULL, - MATROSKA_ID_TAGTARGETS_CHAPTERUID, - (uint32_t)c->id + chapter_id_offset); + MATROSKA_ID_TAGTARGETS_CHAPTERUID, uid); if (ret < 0) goto fail; } @@ -1917,8 +1943,6 @@ static int mkv_write_header(AVFormatContext *s) mkv->reserve_cues_space = -1; } - av_init_packet(&mkv->cur_audio_pkt); - mkv->cur_audio_pkt.size = 0; mkv->cluster_pos = -1; // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or @@ -2007,7 +2031,8 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; mkv_track *track = &mkv->tracks[pkt->stream_index]; uint8_t *data = NULL, *side_data = NULL; - int err = 0, offset = 0, size = pkt->size, side_data_size = 0; + buffer_size_t side_data_size; + int err = 0, offset = 0, size = pkt->size; int64_t ts = track->write_dts ? pkt->dts : pkt->pts; uint64_t additional_id; int64_t discard_padding = 0; @@ -2117,17 +2142,16 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac MatroskaMuxContext *mkv = s->priv_data; mkv_track *track = &mkv->tracks[pkt->stream_index]; ebml_master blockgroup; - int id_size, settings_size, size; + buffer_size_t id_size, settings_size; + int size; const char *id, *settings; int64_t ts = track->write_dts ? pkt->dts : pkt->pts; const int flags = 0; - id_size = 0; id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size); id = id ? id : ""; - settings_size = 0; settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size); settings = settings ? settings : ""; @@ -2184,7 +2208,8 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) mkv_track *track = &mkv->tracks[pkt->stream_index]; AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; uint8_t *side_data; - int side_data_size = 0, ret; + buffer_size_t side_data_size; + int ret; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size); @@ -2414,9 +2439,9 @@ static int mkv_write_packet(AVFormatContext *s, const AVPacket *pkt) keyframe && (mkv->have_video ? codec_type == AVMEDIA_TYPE_VIDEO : 1) ? AVIO_DATA_MARKER_SYNC_POINT : AVIO_DATA_MARKER_BOUNDARY_POINT); // check if we have an audio packet cached - if (mkv->cur_audio_pkt.size > 0) { - ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt); - av_packet_unref(&mkv->cur_audio_pkt); + if (mkv->cur_audio_pkt->size > 0) { + ret = mkv_write_packet_internal(s, mkv->cur_audio_pkt); + av_packet_unref(mkv->cur_audio_pkt); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret); @@ -2428,7 +2453,7 @@ static int mkv_write_packet(AVFormatContext *s, const AVPacket *pkt) // keyframe's timecode is contained in the same cluster for WebM if (codec_type == AVMEDIA_TYPE_AUDIO) { if (pkt->size > 0) - ret = av_packet_ref(&mkv->cur_audio_pkt, pkt); + ret = av_packet_ref(mkv->cur_audio_pkt, pkt); } else ret = mkv_write_packet_internal(s, pkt); return ret; @@ -2460,8 +2485,8 @@ static int mkv_write_trailer(AVFormatContext *s) int ret, ret2 = 0; // check if we have an audio packet cached - if (mkv->cur_audio_pkt.size > 0) { - ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt); + if (mkv->cur_audio_pkt->size > 0) { + ret = mkv_write_packet_internal(s, mkv->cur_audio_pkt); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret); @@ -2685,6 +2710,9 @@ static int mkv_init(struct AVFormatContext *s) } else mkv->mode = MODE_MATROSKAv2; + mkv->cur_audio_pkt = av_packet_alloc(); + if (!mkv->cur_audio_pkt) + return AVERROR(ENOMEM); mkv->tracks = av_mallocz_array(s->nb_streams, sizeof(*mkv->tracks)); if (!mkv->tracks) return AVERROR(ENOMEM); @@ -2789,6 +2817,7 @@ static const AVOption options[] = { { "dash_track_number", "Track number for the DASH stream", OFFSET(dash_track_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, FLAGS }, { "live", "Write files assuming it is a live stream.", OFFSET(is_live), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "allow_raw_vfw", "allow RAW VFW mode", OFFSET(allow_raw_vfw), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { "flipped_raw_rgb", "Raw RGB bitmaps in VFW mode are stored bottom-up", OFFSET(flipped_raw_rgb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "write_crc32", "write a CRC32 element inside every Level 1 element", OFFSET(write_crc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, { "default_mode", "Controls how a track's FlagDefault is inferred", OFFSET(default_mode), AV_OPT_TYPE_INT, { .i64 = DEFAULT_MODE_INFER }, DEFAULT_MODE_INFER, DEFAULT_MODE_PASSTHROUGH, FLAGS, "default_mode" }, { "infer", "For each track type, mark the first track of disposition default as default; if none exists, mark the first track as default.", 0, AV_OPT_TYPE_CONST, { .i64 = DEFAULT_MODE_INFER }, 0, 0, FLAGS, "default_mode" }, diff --git a/libavformat/mca.c b/libavformat/mca.c new file mode 100644 index 000000000..27cfb1c77 --- /dev/null +++ b/libavformat/mca.c @@ -0,0 +1,229 @@ +/* + * MCA demuxer + * Copyright (c) 2020 Zixing Liu + * + * 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/intreadwrite.h" +#include "avformat.h" +#include "avio_internal.h" +#include "internal.h" + +typedef struct MCADemuxContext { + uint32_t block_count; + uint16_t block_size; + uint32_t current_block; + uint32_t data_start; + uint32_t samples_per_block; +} MCADemuxContext; + +static int probe(const AVProbeData *p) +{ + if (AV_RL32(p->buf) == MKTAG('M', 'A', 'D', 'P') && + AV_RL16(p->buf + 4) <= 0x5) + return AVPROBE_SCORE_MAX / 3 * 2; + return 0; +} + +static int read_header(AVFormatContext *s) +{ + AVStream *st; + MCADemuxContext *m = s->priv_data; + AVCodecParameters *par; + int64_t file_size = avio_size(s->pb); + uint16_t version = 0; + uint32_t header_size, data_size, data_offset, loop_start, loop_end, + nb_samples, nb_metadata, coef_offset = 0; + int ch, ret; + int64_t ret_size; + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + par = st->codecpar; + par->codec_type = AVMEDIA_TYPE_AUDIO; + + // parse file headers + avio_skip(s->pb, 0x4); // skip the file magic + version = avio_rl16(s->pb); + avio_skip(s->pb, 0x2); // padding + par->channels = avio_r8(s->pb); + avio_skip(s->pb, 0x1); // padding + m->block_size = avio_rl16(s->pb); + nb_samples = avio_rl32(s->pb); + par->sample_rate = avio_rl32(s->pb); + loop_start = avio_rl32(s->pb); + loop_end = avio_rl32(s->pb); + header_size = avio_rl32(s->pb); + data_size = avio_rl32(s->pb); + avio_skip(s->pb, 0x4); + nb_metadata = avio_rl16(s->pb); + avio_skip(s->pb, 0x2); // unknown u16 field + + // samples per frame = 14; frame size = 8 (2^3) + m->samples_per_block = (m->block_size * 14) >> 3; + + if (m->samples_per_block < 1) + return AVERROR_INVALIDDATA; + + m->block_count = nb_samples / m->samples_per_block; + st->duration = nb_samples; + + // sanity checks + if (!par->channels || par->sample_rate <= 0 + || loop_start > loop_end || m->block_count < 1) + return AVERROR_INVALIDDATA; + if ((ret = av_dict_set_int(&s->metadata, "loop_start", + av_rescale(loop_start, AV_TIME_BASE, + par->sample_rate), 0)) < 0) + return ret; + if ((ret = av_dict_set_int(&s->metadata, "loop_end", + av_rescale(loop_end, AV_TIME_BASE, + par->sample_rate), 0)) < 0) + return ret; + if ((32 + 4 + m->block_size) > (INT_MAX / par->channels) || + (32 + 4 + m->block_size) * par->channels > INT_MAX - 8) + return AVERROR_INVALIDDATA; + avpriv_set_pts_info(st, 64, 1, par->sample_rate); + + if (version <= 4) { + // version <= 4 needs to use the file size to calculate the offsets + if (file_size < 0) { + return AVERROR(EIO); + } + if (file_size - data_size > UINT32_MAX) + return AVERROR_INVALIDDATA; + m->data_start = file_size - data_size; + if (version <= 3) { + nb_metadata = 0; + // header_size is not available or incorrect in older versions + header_size = m->data_start; + } + } else if (version == 5) { + // read data_start location from the header + if (0x30 * par->channels + 0x4 > header_size) + return AVERROR_INVALIDDATA; + data_offset = header_size - 0x30 * par->channels - 0x4; + if ((ret_size = avio_seek(s->pb, data_offset, SEEK_SET)) < 0) + return ret_size; + m->data_start = avio_rl32(s->pb); + // check if the metadata is reasonable + if (file_size > 0 && (int64_t)m->data_start + data_size > file_size) { + // the header is broken beyond repair + if ((int64_t)header_size + data_size > file_size) { + av_log(s, AV_LOG_ERROR, + "MCA metadata corrupted, unable to determine the data offset.\n"); + return AVERROR_INVALIDDATA; + } + // recover the data_start information from the data size + av_log(s, AV_LOG_WARNING, + "Incorrect header size found in metadata, " + "header size approximated from the data size\n"); + if (file_size - data_offset > UINT32_MAX) + return AVERROR_INVALIDDATA; + m->data_start = file_size - data_size; + } + } else { + avpriv_request_sample(s, "version %d", version); + return AVERROR_PATCHWELCOME; + } + + // coefficient alignment = 0x30; metadata size = 0x14 + if (0x30 * par->channels + nb_metadata * 0x14 > header_size) + return AVERROR_INVALIDDATA; + coef_offset = + header_size - 0x30 * par->channels + nb_metadata * 0x14; + + st->start_time = 0; + par->codec_id = AV_CODEC_ID_ADPCM_THP_LE; + + ret = ff_alloc_extradata(st->codecpar, 32 * par->channels); + if (ret < 0) + return ret; + + if ((ret_size = avio_seek(s->pb, coef_offset, SEEK_SET)) < 0) + return ret_size; + for (ch = 0; ch < par->channels; ch++) { + if ((ret = ffio_read_size(s->pb, par->extradata + ch * 32, 32)) < 0) + return ret; + // 0x30 (alignment) - 0x20 (actual size, 32) = 0x10 (padding) + avio_skip(s->pb, 0x10); + } + + // seek to the beginning of the adpcm data + // there are some files where the adpcm audio data is not immediately after the header + if ((ret_size = avio_seek(s->pb, m->data_start, SEEK_SET)) < 0) + return ret_size; + + return 0; +} + +static int read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVCodecParameters *par = s->streams[0]->codecpar; + MCADemuxContext *m = s->priv_data; + uint16_t size = m->block_size; + uint32_t samples = m->samples_per_block; + int ret = 0; + + if (avio_feof(s->pb)) + return AVERROR_EOF; + m->current_block++; + if (m->current_block > m->block_count) + return AVERROR_EOF; + + if ((ret = av_get_packet(s->pb, pkt, size * par->channels)) < 0) + return ret; + pkt->duration = samples; + pkt->stream_index = 0; + + return 0; +} + +static int read_seek(AVFormatContext *s, int stream_index, + int64_t timestamp, int flags) +{ + AVStream *st = s->streams[stream_index]; + MCADemuxContext *m = s->priv_data; + int64_t ret = 0; + + if (timestamp < 0) + timestamp = 0; + timestamp /= m->samples_per_block; + if (timestamp >= m->block_count) + timestamp = m->block_count - 1; + ret = avio_seek(s->pb, m->data_start + timestamp * m->block_size * + st->codecpar->channels, SEEK_SET); + if (ret < 0) + return ret; + + m->current_block = timestamp; + ff_update_cur_dts(s, st, timestamp * m->samples_per_block); + return 0; +} + +AVInputFormat ff_mca_demuxer = { + .name = "mca", + .long_name = NULL_IF_CONFIG_SMALL("MCA Audio Format"), + .priv_data_size = sizeof(MCADemuxContext), + .read_probe = probe, + .read_header = read_header, + .read_packet = read_packet, + .read_seek = read_seek, + .extensions = "mca", +}; diff --git a/libavformat/mccdec.c b/libavformat/mccdec.c new file mode 100644 index 000000000..2a0b7905a --- /dev/null +++ b/libavformat/mccdec.c @@ -0,0 +1,238 @@ +/* + * MCC subtitle demuxer + * Copyright (c) 2020 Paul B Mahol + * + * 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 "avformat.h" +#include "internal.h" +#include "subtitles.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" +#include "libavutil/intreadwrite.h" + +typedef struct MCCContext { + FFDemuxSubtitlesQueue q; +} MCCContext; + +static int mcc_probe(const AVProbeData *p) +{ + char buf[28]; + FFTextReader tr; + + ff_text_init_buf(&tr, p->buf, p->buf_size); + + while (ff_text_peek_r8(&tr) == '\r' || ff_text_peek_r8(&tr) == '\n') + ff_text_r8(&tr); + + ff_text_read(&tr, buf, sizeof(buf)); + + if (!memcmp(buf, "File Format=MacCaption_MCC V", 28)) + return AVPROBE_SCORE_MAX; + + return 0; +} + +static int convert(uint8_t x) +{ + if (x >= 'a') + x -= 87; + else if (x >= 'A') + x -= 55; + else + x -= '0'; + return x; +} + +typedef struct alias { + uint8_t key; + int len; + const char *value; +} alias; + +static const alias aliases[20] = { + { .key = 16, .len = 3, .value = "\xFA\x0\x0", }, + { .key = 17, .len = 6, .value = "\xFA\x0\x0\xFA\x0\x0", }, + { .key = 18, .len = 9, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 19, .len = 12, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 20, .len = 15, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 21, .len = 18, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 22, .len = 21, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 23, .len = 24, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 24, .len = 27, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 25, .len = 3, .value = "\xFB\x80\x80", }, + { .key = 26, .len = 3, .value = "\xFC\x80\x80", }, + { .key = 27, .len = 3, .value = "\xFD\x80\x80", }, + { .key = 28, .len = 2, .value = "\x96\x69", }, + { .key = 29, .len = 2, .value = "\x61\x01", }, + { .key = 30, .len = 3, .value = "\xFC\x80\x80", }, + { .key = 31, .len = 3, .value = "\xFC\x80\x80", }, + { .key = 32, .len = 4, .value = "\xE1\x00\x00\x00", }, + { .key = 33, .len = 0, .value = NULL, }, + { .key = 34, .len = 0, .value = NULL, }, + { .key = 35, .len = 1, .value = "\x0", }, +}; + +static int mcc_read_header(AVFormatContext *s) +{ + MCCContext *mcc = s->priv_data; + AVStream *st = avformat_new_stream(s, NULL); + AVRational rate; + int64_t ts, pos; + uint8_t out[4096]; + char line[4096]; + FFTextReader tr; + int ret = 0; + + ff_text_init_avio(s, &tr, s->pb); + + if (!st) + return AVERROR(ENOMEM); + st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; + st->codecpar->codec_id = AV_CODEC_ID_EIA_608; + avpriv_set_pts_info(st, 64, 1, 30); + + while (!ff_text_eof(&tr)) { + int hh, mm, ss, fs, i = 0, j = 0; + int start = 12, count = 0; + AVPacket *sub; + char *lline; + + ff_subtitles_read_line(&tr, line, sizeof(line)); + if (!strncmp(line, "File Format=MacCaption_MCC V", 28)) + continue; + if (!strncmp(line, "//", 2)) + continue; + if (!strncmp(line, "Time Code Rate=", 15)) { + char *rate_str = line + 15; + char *df = NULL; + int num = -1, den = -1; + + if (rate_str[0]) { + num = strtol(rate_str, &df, 10); + den = 1; + if (df && !av_strncasecmp(df, "DF", 2)) { + num *= 1000; + den = 1001; + } + } + + if (num > 0 && den > 0) { + rate = av_make_q(num, den); + avpriv_set_pts_info(st, 64, rate.den, rate.num); + } + continue; + } + + if (av_sscanf(line, "%d:%d:%d:%d", &hh, &mm, &ss, &fs) != 4) + continue; + + ts = av_sat_add64(av_rescale(hh * 3600LL + mm * 60LL + ss, rate.num, rate.den), fs); + + lline = (char *)&line; + lline += 12; + pos = ff_text_pos(&tr); + + while (lline[i]) { + uint8_t v = convert(lline[i]); + + if (v >= 16 && v <= 35) { + int idx = v - 16; + if (aliases[idx].len) { + if (j >= sizeof(out) - 1 - aliases[idx].len) { + j = 0; + break; + } + memcpy(out + j, aliases[idx].value, aliases[idx].len); + j += aliases[idx].len; + } + } else { + uint8_t vv; + + if (i + 13 >= sizeof(line) - 1) + break; + vv = convert(lline[i + 1]); + if (j >= sizeof(out) - 1) { + j = 0; + break; + } + out[j++] = vv | (v << 4); + i++; + } + + i++; + } + out[j] = 0; + + if (out[7] & 0x80) + start += 4; + count = (out[11] & 0x1f) * 3; + if (j < start + count + 1) + continue; + + if (!count) + continue; + sub = ff_subtitles_queue_insert(&mcc->q, out + start, count, 0); + if (!sub) + goto fail; + + sub->pos = pos; + sub->pts = ts; + sub->duration = 1; + } + + ff_subtitles_queue_finalize(s, &mcc->q); + + return ret; +fail: + ff_subtitles_queue_clean(&mcc->q); + return AVERROR(ENOMEM); +} + +static int mcc_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + MCCContext *mcc = s->priv_data; + return ff_subtitles_queue_read_packet(&mcc->q, pkt); +} + +static int mcc_read_seek(AVFormatContext *s, int stream_index, + int64_t min_ts, int64_t ts, int64_t max_ts, int flags) +{ + MCCContext *mcc = s->priv_data; + return ff_subtitles_queue_seek(&mcc->q, s, stream_index, + min_ts, ts, max_ts, flags); +} + +static int mcc_read_close(AVFormatContext *s) +{ + MCCContext *mcc = s->priv_data; + ff_subtitles_queue_clean(&mcc->q); + return 0; +} + +AVInputFormat ff_mcc_demuxer = { + .name = "mcc", + .long_name = NULL_IF_CONFIG_SMALL("MacCaption"), + .priv_data_size = sizeof(MCCContext), + .read_probe = mcc_probe, + .read_header = mcc_read_header, + .read_packet = mcc_read_packet, + .read_seek2 = mcc_read_seek, + .read_close = mcc_read_close, + .extensions = "mcc", +}; diff --git a/libavformat/microdvddec.c b/libavformat/microdvddec.c index 1f871b251..ecebff101 100644 --- a/libavformat/microdvddec.c +++ b/libavformat/microdvddec.c @@ -65,12 +65,12 @@ static int64_t get_pts(const char *buf) return AV_NOPTS_VALUE; } -static int get_duration(const char *buf) +static int64_t get_duration(const char *buf) { int frame_start, frame_end; if (sscanf(buf, "{%d}{%d}", &frame_start, &frame_end) == 2) - return frame_end - frame_start; + return frame_end - (int64_t)frame_start; return -1; } diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c index 03aed7102..f08aabf4e 100644 --- a/libavformat/mlvdec.c +++ b/libavformat/mlvdec.c @@ -52,6 +52,8 @@ typedef struct { uint64_t pts; } MlvContext; +static int read_close(AVFormatContext *s); + static int probe(const AVProbeData *p) { if (AV_RL32(p->buf) == MKTAG('M','L','V','I') && @@ -130,23 +132,25 @@ static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f break; size -= 16; if (vst && type == MKTAG('R','A','W','I') && size >= 164) { - vst->codecpar->width = avio_rl16(pb); - vst->codecpar->height = avio_rl16(pb); - ret = av_image_check_size(vst->codecpar->width, vst->codecpar->height, 0, avctx); + unsigned width = avio_rl16(pb); + unsigned height = avio_rl16(pb); + unsigned bits_per_coded_sample; + ret = av_image_check_size(width, height, 0, avctx); if (ret < 0) return ret; if (avio_rl32(pb) != 1) avpriv_request_sample(avctx, "raw api version"); avio_skip(pb, 20); // pointer, width, height, pitch, frame_size - vst->codecpar->bits_per_coded_sample = avio_rl32(pb); - if (vst->codecpar->bits_per_coded_sample < 0 || - vst->codecpar->bits_per_coded_sample > (INT_MAX - 7) / (vst->codecpar->width * vst->codecpar->height)) { + bits_per_coded_sample = avio_rl32(pb); + if (bits_per_coded_sample > (INT_MAX - 7) / (width * height)) { av_log(avctx, AV_LOG_ERROR, - "invalid bits_per_coded_sample %d (size: %dx%d)\n", - vst->codecpar->bits_per_coded_sample, - vst->codecpar->width, vst->codecpar->height); + "invalid bits_per_coded_sample %u (size: %ux%u)\n", + bits_per_coded_sample, width, height); return AVERROR_INVALIDDATA; } + vst->codecpar->width = width; + vst->codecpar->height = height; + vst->codecpar->bits_per_coded_sample = bits_per_coded_sample; avio_skip(pb, 8 + 16 + 24); // black_level, white_level, xywh, active_area, exposure_bias if (avio_rl32(pb) != 0x2010100) /* RGGB */ avpriv_request_sample(avctx, "cfa_pattern"); @@ -376,6 +380,7 @@ static int read_header(AVFormatContext *avctx) if ((vst && !vst->nb_index_entries) || (ast && !ast->nb_index_entries)) { av_log(avctx, AV_LOG_ERROR, "no index entries found\n"); + read_close(avctx); return AVERROR_INVALIDDATA; } @@ -411,6 +416,10 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt) } pb = mlv->pb[st->index_entries[index].size]; + if (!pb) { + ret = FFERROR_REDO; + goto next_packet; + } avio_seek(pb, st->index_entries[index].pos, SEEK_SET); avio_skip(pb, 4); // blockType @@ -439,12 +448,14 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt) pkt->stream_index = mlv->stream_index; pkt->pts = mlv->pts; + ret = 0; +next_packet: mlv->stream_index++; if (mlv->stream_index == avctx->nb_streams) { mlv->stream_index = 0; mlv->pts++; } - return 0; + return ret; } static int read_seek(AVFormatContext *avctx, int stream_index, int64_t timestamp, int flags) diff --git a/libavformat/mods.c b/libavformat/mods.c new file mode 100644 index 000000000..a26db87e6 --- /dev/null +++ b/libavformat/mods.c @@ -0,0 +1,102 @@ +/* + * MODS demuxer + * Copyright (c) 2015-2016 Florian Nouwt + * Copyright (c) 2017 Adib Surani + * Copyright (c) 2020 Paul B Mahol + * + * 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/intreadwrite.h" + +#include "avformat.h" +#include "internal.h" + +static int mods_probe(const AVProbeData *p) +{ + if (memcmp(p->buf, "MODSN3\x0a\x00", 8)) + return 0; + if (AV_RB32(p->buf + 8) == 0) + return 0; + if (AV_RB32(p->buf + 12) == 0) + return 0; + if (AV_RB32(p->buf + 16) == 0) + return 0; + return AVPROBE_SCORE_MAX; +} + +static int mods_read_header(AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + AVRational fps; + int64_t pos; + + AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + avio_skip(pb, 8); + + st->nb_frames = avio_rl32(pb); + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = AV_CODEC_ID_MOBICLIP; + st->codecpar->width = avio_rl32(pb); + st->codecpar->height = avio_rl32(pb); + + fps.num = avio_rl32(pb); + fps.den = 0x1000000; + avpriv_set_pts_info(st, 64, fps.den, fps.num); + + avio_skip(pb, 16); + + pos = avio_rl32(pb) + 4; + avio_seek(pb, pos, SEEK_SET); + pos = avio_rl32(pb); + avio_seek(pb, pos, SEEK_SET); + + return 0; +} + +static int mods_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVIOContext *pb = s->pb; + unsigned size; + int64_t pos; + int ret; + + if (avio_feof(pb)) + return AVERROR_EOF; + + pos = avio_tell(pb); + size = avio_rl32(pb) >> 14; + ret = av_get_packet(pb, pkt, size); + pkt->pos = pos; + pkt->stream_index = 0; + pkt->flags |= AV_PKT_FLAG_KEY; + + return ret; +} + +AVInputFormat ff_mods_demuxer = { + .name = "mods", + .long_name = NULL_IF_CONFIG_SMALL("MobiClip MODS"), + .read_probe = mods_probe, + .read_header = mods_read_header, + .read_packet = mods_read_packet, + .extensions = "mods", + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/moflex.c b/libavformat/moflex.c new file mode 100644 index 000000000..41335ada7 --- /dev/null +++ b/libavformat/moflex.c @@ -0,0 +1,392 @@ +/* + * MOFLEX demuxer + * Copyright (c) 2015-2016 Florian Nouwt + * Copyright (c) 2017 Adib Surani + * Copyright (c) 2020 Paul B Mahol + * + * 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/bytestream.h" + +#include "avformat.h" +#include "internal.h" + +typedef struct BitReader { + unsigned last; + unsigned pos; +} BitReader; + +typedef struct MOFLEXDemuxContext { + unsigned size; + int64_t pos; + int64_t ts; + int flags; + int in_block; + + BitReader br; +} MOFLEXDemuxContext; + +static int pop(BitReader *br, AVIOContext *pb) +{ + if (avio_feof(pb)) + return AVERROR_EOF; + + if ((br->pos & 7) == 0) + br->last = (unsigned)avio_r8(pb) << 24U; + else + br->last <<= 1; + + br->pos++; + return !!(br->last & 0x80000000); +} + +static int pop_int(BitReader *br, AVIOContext *pb, int n) +{ + int value = 0; + + for (int i = 0; i < n; i++) { + int ret = pop(br, pb); + + if (ret < 0) + return ret; + if (ret > INT_MAX - value - value) + return AVERROR_INVALIDDATA; + value = 2 * value + ret; + } + + return value; +} + +static int pop_length(BitReader *br, AVIOContext *pb) +{ + int ret, n = 1; + + while ((ret = pop(br, pb)) == 0) + n++; + + if (ret < 0) + return ret; + return n; +} + +static int read_var_byte(AVFormatContext *s, unsigned *out) +{ + AVIOContext *pb = s->pb; + unsigned value = 0, data; + + data = avio_r8(pb); + if (!(data & 0x80)) { + *out = data; + return 0; + } + + value = (data & 0x7F) << 7; + data = avio_r8(pb); + if (!(data & 0x80)) { + value |= data; + *out = value; + return 0; + } + + value = ((data & 0x7F) | value) << 7; + data = avio_r8(pb); + if (!(data & 0x80)) { + value |= data; + *out = value; + return 0; + } + + value = (((data & 0x7F) | value) << 7) | avio_r8(pb); + *out = value; + + return 0; +} + +static int moflex_probe(const AVProbeData *p) +{ + GetByteContext gb; + int score = 0; + + bytestream2_init(&gb, p->buf, p->buf_size); + + if (bytestream2_get_be16(&gb) != 0x4C32) + return 0; + score += 10; + + bytestream2_skip(&gb, 10); + if (bytestream2_get_be16(&gb) == 0) + return 0; + score += 5; + + while (bytestream2_get_bytes_left(&gb) > 0) { + int type = bytestream2_get_byte(&gb); + int size = bytestream2_get_byte(&gb); + + if (type == 0) { + score += 5 * (size == 0); + break; + } + if ((type == 1 && size == 12) || + (type == 2 && size == 6) || + (type == 3 && size == 13) || + (type == 4 && size == 2)) + score += 20; + bytestream2_skip(&gb, size); + } + + return FFMIN(AVPROBE_SCORE_MAX, score); +} + +static int moflex_read_sync(AVFormatContext *s) +{ + MOFLEXDemuxContext *m = s->priv_data; + AVIOContext *pb = s->pb; + + if (avio_rb16(pb) != 0x4C32) { + if (avio_feof(pb)) + return AVERROR_EOF; + avio_seek(pb, -2, SEEK_CUR); + return 1; + } + + avio_skip(pb, 2); + m->ts = avio_rb64(pb); + m->size = avio_rb16(pb) + 1; + + while (!avio_feof(pb)) { + unsigned type, ssize, codec_id = 0; + unsigned codec_type, width = 0, height = 0, sample_rate = 0, channels = 0; + int stream_index = -1; + int format; + AVRational fps; + + read_var_byte(s, &type); + read_var_byte(s, &ssize); + + switch (type) { + case 0: + if (ssize > 0) + avio_skip(pb, ssize); + return 0; + case 2: + codec_type = AVMEDIA_TYPE_AUDIO; + stream_index = avio_r8(pb); + codec_id = avio_r8(pb); + switch (codec_id) { + case 0: codec_id = AV_CODEC_ID_FASTAUDIO; break; + case 1: codec_id = AV_CODEC_ID_ADPCM_IMA_MOFLEX; break; + case 2: codec_id = AV_CODEC_ID_PCM_S16LE; break; + default: + av_log(s, AV_LOG_ERROR, "Unsupported audio codec: %d\n", codec_id); + return AVERROR_PATCHWELCOME; + } + sample_rate = avio_rb24(pb) + 1; + channels = avio_r8(pb) + 1; + break; + case 1: + case 3: + codec_type = AVMEDIA_TYPE_VIDEO; + stream_index = avio_r8(pb); + codec_id = avio_r8(pb); + switch (codec_id) { + case 0: codec_id = AV_CODEC_ID_MOBICLIP; break; + default: + av_log(s, AV_LOG_ERROR, "Unsupported video codec: %d\n", codec_id); + return AVERROR_PATCHWELCOME; + } + fps.num = avio_rb16(pb); + fps.den = avio_rb16(pb); + width = avio_rb16(pb); + height = avio_rb16(pb); + format = AV_PIX_FMT_YUV420P; + avio_skip(pb, type == 3 ? 3 : 2); + break; + case 4: + codec_type = AVMEDIA_TYPE_DATA; + stream_index = avio_r8(pb); + avio_skip(pb, 1); + break; + } + + if (stream_index == s->nb_streams) { + AVStream *st = avformat_new_stream(s, NULL); + + if (!st) + return AVERROR(ENOMEM); + + st->codecpar->codec_type = codec_type; + st->codecpar->codec_id = codec_id; + st->codecpar->width = width; + st->codecpar->height = height; + st->codecpar->sample_rate= sample_rate; + st->codecpar->channels = channels; + st->codecpar->format = format; + st->priv_data = av_packet_alloc(); + if (!st->priv_data) + return AVERROR(ENOMEM); + + if (sample_rate) + avpriv_set_pts_info(st, 63, 1, sample_rate); + else + avpriv_set_pts_info(st, 63, fps.den, fps.num); + } + } + + return 0; +} + +static int moflex_read_header(AVFormatContext *s) +{ + int ret; + + ret = moflex_read_sync(s); + if (ret < 0) + return ret; + + s->ctx_flags |= AVFMTCTX_NOHEADER; + avio_seek(s->pb, 0, SEEK_SET); + + return 0; +} + +static int moflex_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + MOFLEXDemuxContext *m = s->priv_data; + AVIOContext *pb = s->pb; + BitReader *br = &m->br; + int ret; + + while (!avio_feof(pb)) { + if (!m->in_block) { + m->pos = avio_tell(pb); + + ret = moflex_read_sync(s); + if (ret < 0) + return ret; + + m->flags = avio_r8(pb); + if (m->flags & 2) + avio_skip(pb, 2); + } + + while ((avio_tell(pb) < m->pos + m->size) && !avio_feof(pb) && avio_r8(pb)) { + int stream_index, bits, pkt_size, endframe; + AVPacket *packet; + + m->in_block = 1; + + avio_seek(pb, -1, SEEK_CUR); + br->pos = br->last = 0; + + bits = pop_length(br, pb); + if (bits < 0) + return bits; + stream_index = pop_int(br, pb, bits); + if (stream_index < 0) + return stream_index; + if (stream_index >= s->nb_streams) + return AVERROR_INVALIDDATA; + + endframe = pop(br, pb); + if (endframe < 0) + return endframe; + if (endframe) { + bits = pop_length(br, pb); + if (bits < 0) + return bits; + pop_int(br, pb, bits); + pop(br, pb); + bits = pop_length(br, pb); + if (bits < 0) + return bits; + pop_int(br, pb, bits * 2 + 26); + } + + pkt_size = pop_int(br, pb, 13) + 1; + if (pkt_size > m->size) + return AVERROR_INVALIDDATA; + packet = s->streams[stream_index]->priv_data; + if (!packet) { + avio_skip(pb, pkt_size); + continue; + } + + ret = av_append_packet(pb, packet, pkt_size); + if (ret < 0) + return ret; + if (endframe && packet->size > 0) { + av_packet_move_ref(pkt, packet); + pkt->pos = m->pos; + pkt->stream_index = stream_index; + if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + pkt->duration = 1; + if (pkt->data[0] & 0x80) + pkt->flags |= AV_PKT_FLAG_KEY; + } else { + pkt->flags |= AV_PKT_FLAG_KEY; + } + return ret; + } + } + + m->in_block = 0; + + if (m->flags % 2 == 0) { + if (m->size <= 0) + return AVERROR_INVALIDDATA; + avio_seek(pb, m->pos + m->size, SEEK_SET); + } + } + + return AVERROR_EOF; +} + +static int moflex_read_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + MOFLEXDemuxContext *m = s->priv_data; + + m->in_block = 0; + + return -1; +} + +static int moflex_read_close(AVFormatContext *s) +{ + for (int i = 0; i < s->nb_streams; i++) { + AVPacket *packet = s->streams[i]->priv_data; + + av_packet_free(&packet); + s->streams[i]->priv_data = 0; + } + + return 0; +} + +AVInputFormat ff_moflex_demuxer = { + .name = "moflex", + .long_name = NULL_IF_CONFIG_SMALL("MobiClip MOFLEX"), + .priv_data_size = sizeof(MOFLEXDemuxContext), + .read_probe = moflex_probe, + .read_header = moflex_read_header, + .read_packet = moflex_read_packet, + .read_seek = moflex_read_seek, + .read_close = moflex_read_close, + .extensions = "moflex", + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/mov.c b/libavformat/mov.c index 702fc7fac..38a70589b 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -181,7 +181,6 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) { - AVPacket pkt; AVStream *st; MOVStreamContext *sc; enum AVCodecID id; @@ -205,12 +204,12 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) return AVERROR(ENOMEM); st->priv_data = sc; - ret = av_get_packet(pb, &pkt, len); + ret = av_get_packet(pb, &st->attached_pic, len); if (ret < 0) return ret; - if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) { - if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) { + if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) { + if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) { id = AV_CODEC_ID_PNG; } else { id = AV_CODEC_ID_MJPEG; @@ -219,7 +218,6 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) st->disposition |= AV_DISPOSITION_ATTACHED_PIC; - st->attached_pic = pkt; st->attached_pic.stream_index = st->index; st->attached_pic.flags |= AV_PKT_FLAG_KEY; @@ -301,7 +299,7 @@ static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len) static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) { - char tmp_key[5]; + char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0}; char key2[32], language[4] = {0}; char *str = NULL; const char *key = NULL; @@ -406,7 +404,7 @@ retry: if (c->itunes_metadata && atom.size > 8) { int data_size = avio_rb32(pb); int tag = avio_rl32(pb); - if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) { + if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) { data_type = avio_rb32(pb); // type avio_rb32(pb); // unknown str_size = data_size - 16; @@ -448,8 +446,7 @@ retry: str_size = atom.size; if (c->export_all && !key) { - snprintf(tmp_key, 5, "%.4s", (char*)&atom.type); - key = tmp_key; + key = av_fourcc_make_string(tmp_key, atom.type); } if (!key) @@ -592,7 +589,12 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 || entries >= UINT_MAX / sizeof(*sc->drefs)) return AVERROR_INVALIDDATA; - sc->drefs_count = 0; + + for (i = 0; i < sc->drefs_count; i++) { + MOVDref *dref = &sc->drefs[i]; + av_freep(&dref->path); + av_freep(&dref->dir); + } av_free(sc->drefs); sc->drefs_count = 0; sc->drefs = av_mallocz(entries * sizeof(*sc->drefs)); @@ -648,7 +650,7 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_skip(pb, 16); for (type = 0; type != -1 && avio_tell(pb) < next; ) { - if(avio_feof(pb)) + if (avio_feof(pb)) return AVERROR_EOF; type = avio_rb16(pb); len = avio_rb16(pb); @@ -861,26 +863,20 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) { - const uint32_t ddts_size = 20; +#define DDTS_SIZE 20 + uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; AVStream *st = NULL; - uint8_t *buf = NULL; uint32_t frame_duration_code = 0; uint32_t channel_layout_code = 0; GetBitContext gb; + int ret; - buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!buf) { - return AVERROR(ENOMEM); - } - if (avio_read(pb, buf, ddts_size) < ddts_size) { - av_free(buf); - return AVERROR_INVALIDDATA; - } + if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0) + return ret; - init_get_bits(&gb, buf, 8*ddts_size); + init_get_bits(&gb, buf, 8 * DDTS_SIZE); if (c->fc->nb_streams < 1) { - av_free(buf); return 0; } st = c->fc->streams[c->fc->nb_streams-1]; @@ -888,7 +884,6 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) st->codecpar->sample_rate = get_bits_long(&gb, 32); if (st->codecpar->sample_rate <= 0) { av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate); - av_free(buf); return AVERROR_INVALIDDATA; } skip_bits_long(&gb, 32); /* max bitrate */ @@ -905,7 +900,7 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) (frame_duration_code == 3) ? 4096 : 0; if (channel_layout_code > 0xff) { - av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout"); + av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n"); } st->codecpar->channel_layout = ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) | @@ -916,7 +911,6 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0); st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout); - av_free(buf); return 0; } @@ -1088,6 +1082,30 @@ fail: return ret; } +static int mov_aaxc_crypto(MOVContext *c) +{ + if (c->audible_key_size != 16) { + av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n"); + return AVERROR(EINVAL); + } + + if (c->audible_iv_size != 16) { + av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n"); + return AVERROR(EINVAL); + } + + c->aes_decrypt = av_aes_alloc(); + if (!c->aes_decrypt) { + return AVERROR(ENOMEM); + } + + memcpy(c->file_key, c->audible_key, 16); + memcpy(c->file_iv, c->audible_iv, 16); + c->aax_mode = 1; + + return 0; +} + // Audible AAX (and AAX+) bytestream decryption static int aax_filter(uint8_t *input, int size, MOVContext *c) { @@ -1136,6 +1154,11 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, AV_DICT_DONT_STRDUP_VAL); + // Logic for handling Audible's .aaxc files + if (!strcmp(type, "aaxc")) { + mov_aaxc_crypto(c); + } + return 0; } @@ -1256,6 +1279,10 @@ static int64_t get_frag_time(MOVFragmentIndex *frag_index, if (track_id >= 0) { frag_stream_info = get_frag_stream_info(frag_index, index, track_id); + if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) + return frag_stream_info->sidx_pts; + if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE) + return frag_stream_info->first_tfra_pts; return frag_stream_info->sidx_pts; } @@ -1320,7 +1347,7 @@ static int update_frag_index(MOVContext *c, int64_t offset) &c->frag_index.allocated_size, (c->frag_index.nb_items + 1) * sizeof(*c->frag_index.item)); - if(!item) + if (!item) return -1; c->frag_index.item = item; @@ -1404,7 +1431,7 @@ static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom) static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx) { if (time) { - if(time >= 2082844800) + if (time >= 2082844800) time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ if ((int64_t)(time * 1000000ULL) / 1000000 != time) { @@ -1488,9 +1515,9 @@ static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale); c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */ - // set the AVCodecContext duration because the duration of individual tracks + // set the AVFormatContext duration because the duration of individual tracks // may be inaccurate - if (c->time_scale > 0 && !c->trex_data) + if (!c->trex_data) c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale); avio_rb32(pb); /* preferred scale */ @@ -1578,8 +1605,7 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom) ret = ffio_read_size(pb, icc_profile, atom.size - 4); if (ret < 0) return ret; - } - else { + } else { color_primaries = avio_rb16(pb); color_trc = avio_rb16(pb); color_matrix = avio_rb16(pb); @@ -1732,7 +1758,7 @@ static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom) { int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI); - if(ret == 0) + if (!ret) ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD); return ret; } @@ -1781,8 +1807,8 @@ static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; den *= 2; case 1: - c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num; - c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den; + c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num; + c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den; default: return 0; } @@ -2011,8 +2037,10 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!entries) return 0; - if (sc->chunk_offsets) - av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n"); + if (sc->chunk_offsets) { + av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n"); + return 0; + } av_free(sc->chunk_offsets); sc->chunk_count = 0; sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets)); @@ -2080,6 +2108,7 @@ static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, uint8_t codec_name[32] = { 0 }; int64_t stsd_start; unsigned int len; + uint32_t id = 0; /* The first 16 bytes of the video sample description are already * read in ff_mov_read_stsd_entries() */ @@ -2087,7 +2116,8 @@ static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, avio_rb16(pb); /* version */ avio_rb16(pb); /* revision level */ - avio_rb32(pb); /* vendor */ + id = avio_rl32(pb); /* vendor */ + av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0); avio_rb32(pb); /* temporal quality */ avio_rb32(pb); /* spatial quality */ @@ -2135,10 +2165,12 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, { int bits_per_sample, flags; uint16_t version = avio_rb16(pb); + uint32_t id = 0; AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE); avio_rb16(pb); /* revision level */ - avio_rb32(pb); /* vendor */ + id = avio_rl32(pb); /* vendor */ + av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0); st->codecpar->channels = avio_rb16(pb); /* channel count */ st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */ @@ -2233,7 +2265,7 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, } bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id); - if (bits_per_sample) { + if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) { st->codecpar->bits_per_coded_sample = bits_per_sample; sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels; } @@ -2326,34 +2358,20 @@ FF_DISABLE_DEPRECATION_WARNINGS st->codec->time_base = av_inv_q(st->avg_frame_rate); FF_ENABLE_DEPRECATION_WARNINGS #endif - /* adjust for per frame dur in counter mode */ - if (tmcd_ctx->tmcd_flags & 0x0008) { - int timescale = AV_RB32(st->codecpar->extradata + 8); - int framedur = AV_RB32(st->codecpar->extradata + 12); - st->avg_frame_rate = av_mul_q(st->avg_frame_rate, (AVRational){timescale, framedur}); -#if FF_API_LAVF_AVCTX -FF_DISABLE_DEPRECATION_WARNINGS - st->codec->time_base = av_mul_q(st->codec->time_base , (AVRational){framedur, timescale}); -FF_ENABLE_DEPRECATION_WARNINGS -#endif - } if (size > 30) { uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */ uint32_t format = AV_RB32(st->codecpar->extradata + 22); if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) { uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */ - if (str_size > 0 && size >= (int)str_size + 30) { + if (str_size > 0 && size >= (int)str_size + 30 && + st->codecpar->extradata[30] /* Don't add empty string */) { char *reel_name = av_malloc(str_size + 1); if (!reel_name) return AVERROR(ENOMEM); memcpy(reel_name, st->codecpar->extradata + 30, str_size); reel_name[str_size] = 0; /* Add null terminator */ - /* don't add reel_name if emtpy string */ - if (*reel_name == 0) { - av_free(reel_name); - } else { - av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL); - } + av_dict_set(&st->metadata, "reel_name", reel_name, + AV_DICT_DONT_STRDUP_VAL); } } } @@ -2438,6 +2456,9 @@ static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, case AV_CODEC_ID_VP9: st->need_parsing = AVSTREAM_PARSE_FULL; break; + case AV_CODEC_ID_AV1: + st->need_parsing = AVSTREAM_PARSE_HEADERS; + break; default: break; } @@ -2550,11 +2571,8 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) /* Move the current stream extradata to the stream context one. */ sc->extradata_size[pseudo_stream_id] = extra_size; - sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!sc->extradata[pseudo_stream_id]) - return AVERROR(ENOMEM); - memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size); - av_freep(&st->codecpar->extradata); + sc->extradata[pseudo_stream_id] = st->codecpar->extradata; + st->codecpar->extradata = NULL; st->codecpar->extradata_size = 0; } sc->stsd_count++; @@ -2584,7 +2602,7 @@ static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom) entries = avio_rb32(pb); /* Each entry contains a size (4 bytes) and format (4 bytes). */ - if (entries <= 0 || entries > atom.size / 8) { + if (entries <= 0 || entries > atom.size / 8 || entries > 1024) { av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries); return AVERROR_INVALIDDATA; } @@ -2655,8 +2673,10 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!entries) return 0; - if (sc->stsc_data) - av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n"); + if (sc->stsc_data) { + av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n"); + return 0; + } av_free(sc->stsc_data); sc->stsc_count = 0; sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data)); @@ -2781,8 +2801,7 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries); - if (!entries) - { + if (!entries) { sc->keyframe_absent = 1; if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) st->need_parsing = AVSTREAM_PARSE_HEADERS; @@ -2910,8 +2929,8 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) AVStream *st; MOVStreamContext *sc; unsigned int i, entries, alloc_size = 0; - int64_t duration=0; - int64_t total_sample_count=0; + int64_t duration = 0; + int64_t total_sample_count = 0; if (c->fc->nb_streams < 1) return 0; @@ -2946,7 +2965,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->stts_count = min_entries; sc->stts_data = stts_data; - sample_count=avio_rb32(pb); + sample_count = avio_rb32(pb); sample_duration = avio_rb32(pb); sc->stts_data[i].count= sample_count; @@ -2963,8 +2982,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (duration > 0 && duration <= INT64_MAX - sc->duration_for_fps && - total_sample_count <= INT_MAX - sc->nb_frames_for_fps - ) { + total_sample_count <= INT_MAX - sc->nb_frames_for_fps) { sc->duration_for_fps += duration; sc->nb_frames_for_fps += total_sample_count; } @@ -3004,7 +3022,7 @@ static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_freep(&sc->sdtp_data); sc->sdtp_count = 0; - sc->sdtp_data = av_mallocz(entries); + sc->sdtp_data = av_malloc(entries); if (!sc->sdtp_data) return AVERROR(ENOMEM); @@ -3053,8 +3071,8 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR(ENOMEM); for (i = 0; i < entries && !pb->eof_reached; i++) { - int count =avio_rb32(pb); - int duration =avio_rb32(pb); + int count = avio_rb32(pb); + int duration = avio_rb32(pb); if (count <= 0) { av_log(c->fc, AV_LOG_TRACE, @@ -3294,13 +3312,13 @@ static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) : min_size_needed; - if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry)) + if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry)) return -1; entries = av_fast_realloc(st->index_entries, &st->index_entries_allocated_size, requested_size); - if(!entries) + if (!entries) return -1; st->index_entries= entries; @@ -3345,12 +3363,12 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns FFMAX(min_size_needed, 2 * (*allocated_size)) : min_size_needed; - if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1) + if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1) return -1; ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size); - if(!ctts_buf_new) + if (!ctts_buf_new) return -1; *ctts_data = ctts_buf_new; @@ -3363,7 +3381,8 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns } #define MAX_REORDER_DELAY 16 -static void mov_estimate_video_delay(MOVContext *c, AVStream* st) { +static void mov_estimate_video_delay(MOVContext *c, AVStream* st) +{ MOVStreamContext *msc = st->priv_data; int ind; int ctts_ind = 0; @@ -3378,7 +3397,7 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st) { if (st->codecpar->video_delay <= 0 && msc->ctts_data && st->codecpar->codec_id == AV_CODEC_ID_H264) { st->codecpar->video_delay = 0; - for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) { + for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) { // Point j to the last elem of the buffer and insert the current pts there. j = buf_start; buf_start = (buf_start + 1); @@ -3566,7 +3585,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) } if (first_non_zero_audio_edit > 0) - st->skip_samples = msc->start_pad = 0; + st->internal->skip_samples = msc->start_pad = 0; } // While reordering frame index according to edit list we must handle properly @@ -3641,7 +3660,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time && first_non_zero_audio_edit > 0) { packet_skip_samples = edit_list_media_time - curr_cts; - st->skip_samples += packet_skip_samples; + st->internal->skip_samples += packet_skip_samples; // Shift the index entry timestamp by packet_skip_samples to be correct. edit_list_dts_counter -= packet_skip_samples; @@ -3674,7 +3693,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) // Increment skip_samples for the first non-zero audio edit list if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) { - st->skip_samples += frame_duration; + st->internal->skip_samples += frame_duration; } } } @@ -3760,7 +3779,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) // Update av stream length, if it ends up shorter than the track's media duration st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts); - msc->start_pad = st->skip_samples; + msc->start_pad = st->internal->skip_samples; // Free the old index and the old CTTS structures av_free(e_old); @@ -4176,10 +4195,10 @@ static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDr return AVERROR(ENOENT); } - if(strstr(ref->path + l + 1, "..") || - strstr(ref->path + l + 1, ":") || - (ref->nlvl_from > 1 && same_origin < 0) || - (filename[0] == '/' && src_path == src)) + if (strstr(ref->path + l + 1, "..") || + strstr(ref->path + l + 1, ":") || + (ref->nlvl_from > 1 && same_origin < 0) || + (filename[0] == '/' && src_path == src)) return AVERROR(ENOENT); } @@ -4813,8 +4832,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb); frag_stream_info = get_current_frag_stream_info(&c->frag_index); - if (frag_stream_info) - { + if (frag_stream_info) { if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) { dts = frag_stream_info->next_trun_dts - sc->time_offset; } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE && @@ -4863,7 +4881,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) new_entries = av_fast_realloc(st->index_entries, &st->index_entries_allocated_size, requested_size); - if(!new_entries) + if (!new_entries) return AVERROR(ENOMEM); st->index_entries= new_entries; @@ -5034,8 +5052,10 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) { - int64_t offset = avio_tell(pb) + atom.size, pts, timestamp; - uint8_t version; + int64_t stream_size = avio_size(pb); + int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp; + uint8_t version, is_complete; + int64_t offadd; unsigned i, j, track_id, item_count; AVStream *st = NULL; AVStream *ref_st = NULL; @@ -5073,11 +5093,15 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (version == 0) { pts = avio_rb32(pb); - offset += avio_rb32(pb); + offadd= avio_rb32(pb); } else { pts = avio_rb64(pb); - offset += avio_rb64(pb); + offadd= avio_rb64(pb); } + if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd) + return AVERROR_INVALIDDATA; + + offset += (uint64_t)offadd; avio_rb16(pb); // reserved @@ -5100,6 +5124,8 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (frag_stream_info) frag_stream_info->sidx_pts = timestamp; + if (av_sat_add64(offset, size) != offset + size) + return AVERROR_INVALIDDATA; offset += size; pts += duration; } @@ -5108,7 +5134,24 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->has_sidx = 1; - if (offset == avio_size(pb)) { + // See if the remaining bytes are just an mfra which we can ignore. + is_complete = offset == stream_size; + if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) { + int64_t ret; + int64_t original_pos = avio_tell(pb); + if (!c->have_read_mfra_size) { + if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0) + return ret; + c->mfra_size = avio_rb32(pb); + c->have_read_mfra_size = 1; + if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0) + return ret; + } + if (offset + c->mfra_size == stream_size) + is_complete = 1; + } + + if (is_complete) { // Find first entry in fragment index that came from an sidx. // This will pretty much always be the first entry. for (i = 0; i < c->frag_index.nb_items; i++) { @@ -5238,7 +5281,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) } else { edit_count = atom.size / elst_entry_size; if (edit_count * elst_entry_size != atom.size) { - av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count); + av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count); } } } @@ -5777,12 +5820,9 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) st = c->fc->streams[c->fc->nb_streams - 1]; sc = st->priv_data; - ret = avio_read(pb, uuid, sizeof(uuid)); - if (ret < 0) { + ret = ffio_read_size(pb, uuid, sizeof(uuid)); + if (ret < 0) return ret; - } else if (ret != sizeof(uuid)) { - return AVERROR_INVALIDDATA; - } if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) { uint8_t *buffer, *ptr; char *endptr; @@ -5798,13 +5838,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!buffer) { return AVERROR(ENOMEM); } - ret = avio_read(pb, buffer, len); + ret = ffio_read_size(pb, buffer, len); if (ret < 0) { av_free(buffer); return ret; - } else if (ret != len) { - av_free(buffer); - return AVERROR_INVALIDDATA; } ptr = buffer; @@ -5835,13 +5872,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!buffer) { return AVERROR(ENOMEM); } - ret = avio_read(pb, buffer, len); + ret = ffio_read_size(pb, buffer, len); if (ret < 0) { av_free(buffer); return ret; - } else if (ret != len) { - av_free(buffer); - return AVERROR_INVALIDDATA; } buffer[len] = '\0'; av_dict_set(&c->fc->metadata, "xmp", @@ -5985,7 +6019,7 @@ static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples) { - int i; + int i, ret; unsigned int subsample_count; AVSubsampleEncryptionInfo *subsamples; @@ -5999,11 +6033,11 @@ static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVSt return AVERROR(ENOMEM); if (sc->cenc.per_sample_iv_size != 0) { - if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) { + if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) { av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n"); av_encryption_info_free(*sample); *sample = NULL; - return AVERROR_INVALIDDATA; + return ret; } } @@ -6356,7 +6390,8 @@ static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom) AVStream *st; uint8_t *side_data, *extra_data, *old_side_data; size_t side_data_size; - int ret = 0, old_side_data_size; + buffer_size_t old_side_data_size; + int ret = 0; unsigned int version, kid_count, extra_data_size, alloc_size = 0; if (c->fc->nb_streams < 1) @@ -6371,9 +6406,8 @@ static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!info) return AVERROR(ENOMEM); - if (avio_read(pb, info->system_id, 16) != 16) { + if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) { av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n"); - ret = AVERROR_INVALIDDATA; goto finish; } @@ -6401,9 +6435,8 @@ static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom) } info->num_key_ids = i + 1; - if (avio_read(pb, info->key_ids[i], 16) != 16) { + if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) { av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n"); - ret = AVERROR_INVALIDDATA; goto finish; } } @@ -6622,15 +6655,13 @@ static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *s av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv); - if (!sample->subsample_count) - { + if (!sample->subsample_count) { /* decrypt the whole packet */ av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size); return 0; } - for (i = 0; i < sample->subsample_count; i++) - { + for (i = 0; i < sample->subsample_count; i++) { if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); return AVERROR_INVALIDDATA; @@ -6994,10 +7025,9 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) } } if (atom.type != MKTAG('r','o','o','t') && - atom.type != MKTAG('m','o','o','v')) - { - if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t')) - { + atom.type != MKTAG('m','o','o','v')) { + if (a.type == MKTAG('t','r','a','k') || + a.type == MKTAG('m','d','a','t')) { av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n"); avio_skip(pb, -8); c->atom_depth --; @@ -7063,8 +7093,8 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_skip(pb, left); else if (left < 0) { av_log(c->fc, AV_LOG_WARNING, - "overread end of atom '%.4s' by %"PRId64" bytes\n", - (char*)&a.type, -left); + "overread end of atom '%s' by %"PRId64" bytes\n", + av_fourcc2str(a.type), -left); avio_seek(pb, left, SEEK_CUR); } } @@ -7089,9 +7119,22 @@ static int mov_probe(const AVProbeData *p) /* check file header */ offset = 0; for (;;) { + int64_t size; + int minsize = 8; /* ignore invalid offset */ - if ((offset + 8) > (unsigned int)p->buf_size) + if ((offset + 8ULL) > (unsigned int)p->buf_size) break; + size = AV_RB32(p->buf + offset); + if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) { + size = AV_RB64(p->buf+offset + 8); + minsize = 16; + } else if (size == 0) { + size = p->buf_size - offset; + } + if (size < minsize) { + offset += 4; + continue; + } tag = AV_RL32(p->buf + offset + 4); switch(tag) { /* check for obvious tags */ @@ -7101,12 +7144,7 @@ static int mov_probe(const AVProbeData *p) case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */ case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */ case MKTAG('f','t','y','p'): - if (AV_RB32(p->buf+offset) < 8 && - (AV_RB32(p->buf+offset) != 1 || - offset + 12 > (unsigned int)p->buf_size || - AV_RB64(p->buf+offset + 8) == 0)) { - score = FFMAX(score, AVPROBE_SCORE_EXTENSION); - } else if (tag == MKTAG('f','t','y','p') && + if (tag == MKTAG('f','t','y','p') && ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ') || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ') )) { @@ -7114,7 +7152,6 @@ static int mov_probe(const AVProbeData *p) } else { score = AVPROBE_SCORE_MAX; } - offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; break; /* those are more common words, so rate then a bit less */ case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */ @@ -7123,7 +7160,6 @@ static int mov_probe(const AVProbeData *p) case MKTAG('j','u','n','k'): case MKTAG('p','i','c','t'): score = FFMAX(score, AVPROBE_SCORE_MAX - 5); - offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; break; case MKTAG(0x82,0x82,0x7f,0x7d): case MKTAG('s','k','i','p'): @@ -7131,31 +7167,32 @@ static int mov_probe(const AVProbeData *p) case MKTAG('p','r','f','l'): /* if we only find those cause probedata is too small at least rate them */ score = FFMAX(score, AVPROBE_SCORE_EXTENSION); - offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; break; - default: - offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; } + if (size > INT64_MAX - offset) + break; + offset += size; } - if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) { + if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) { /* moov atom in the header - we should make sure that this is not a * MOV-packed MPEG-PS */ offset = moov_offset; - while(offset < (p->buf_size - 16)){ /* Sufficient space */ + while (offset < (p->buf_size - 16)) { /* Sufficient space */ /* We found an actual hdlr atom */ - if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') && - AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') && - AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){ + if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') && + AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') && + AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) { av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n"); /* We found a media handler reference atom describing an * MPEG-PS-in-MOV, return a * low score to force expanding the probe window until * mpegps_probe finds what it needs */ return 5; - }else + } else { /* Keep looking */ - offset+=2; + offset += 2; + } } } @@ -7192,17 +7229,15 @@ static void mov_read_chapters(AVFormatContext *s) st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS; if (st->nb_index_entries) { // Retrieve the first frame, if possible - AVPacket pkt; AVIndexEntry *sample = &st->index_entries[0]; if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n"); goto finish; } - if (av_get_packet(sc->pb, &pkt, sample->size) < 0) + if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0) goto finish; - st->attached_pic = pkt; st->attached_pic.stream_index = st->index; st->attached_pic.flags |= AV_PKT_FLAG_KEY; } @@ -7519,22 +7554,22 @@ static int mov_read_mfra(MOVContext *c, AVIOContext *f) int64_t stream_size = avio_size(f); int64_t original_pos = avio_tell(f); int64_t seek_ret; - int32_t mfra_size; int ret = -1; if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) { ret = seek_ret; goto fail; } - mfra_size = avio_rb32(f); - if (mfra_size < 0 || mfra_size > stream_size) { + c->mfra_size = avio_rb32(f); + c->have_read_mfra_size = 1; + if (!c->mfra_size || c->mfra_size > stream_size) { av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n"); goto fail; } - if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) { + if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) { ret = seek_ret; goto fail; } - if (avio_rb32(f) != mfra_size) { + if (avio_rb32(f) != c->mfra_size) { av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n"); goto fail; } @@ -7549,6 +7584,7 @@ static int mov_read_mfra(MOVContext *c, AVIOContext *f) goto fail; } while (!ret); ret = 0; + c->frag_index.complete = 1; fail: seek_ret = avio_seek(f, original_pos, SEEK_SET); if (seek_ret < 0) { @@ -7633,8 +7669,9 @@ static int mov_read_header(AVFormatContext *s) AVStream *st = s->streams[i]; MOVStreamContext *sc = st->priv_data; fix_timescale(mov, sc); - if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) { - st->skip_samples = sc->start_pad; + if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && + st->codecpar->codec_id == AV_CODEC_ID_AAC) { + st->internal->skip_samples = sc->start_pad; } if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0) av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, @@ -7651,8 +7688,7 @@ static int mov_read_header(AVFormatContext *s) } if (mov->handbrake_version && mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2 - st->codecpar->codec_id == AV_CODEC_ID_MP3 - ) { + st->codecpar->codec_id == AV_CODEC_ID_MP3) { av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n"); st->need_parsing = AVSTREAM_PARSE_FULL; } @@ -7706,9 +7742,8 @@ static int mov_read_header(AVFormatContext *s) switch (st->codecpar->codec_type) { case AVMEDIA_TYPE_AUDIO: err = ff_replaygain_export(st, s->metadata); - if (err < 0) { + if (err < 0) goto fail; - } break; case AVMEDIA_TYPE_VIDEO: if (sc->display_matrix) { @@ -7862,6 +7897,27 @@ static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt) return 0; } +static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size) +{ + int new_size, ret; + + if (size <= 8) + return AVERROR_INVALIDDATA; + new_size = ((size - 8) / 2) * 3; + ret = av_new_packet(pkt, new_size); + if (ret < 0) + return ret; + + avio_skip(pb, 8); + for (int j = 0; j < new_size; j += 3) { + pkt->data[j] = 0xFC; + pkt->data[j+1] = avio_r8(pb); + pkt->data[j+2] = avio_r8(pb); + } + + return 0; +} + static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) { MOVContext *mov = s->priv_data; @@ -7901,12 +7957,15 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR_INVALIDDATA; } - if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) { + if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) { av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex); goto retry; } - ret = av_get_packet(sc->pb, pkt, sample->size); + if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8) + ret = get_eia608_packet(sc->pb, pkt, sample->size); + else + ret = av_get_packet(sc->pb, pkt, sample->size); if (ret < 0) { if (should_retry(sc->pb, ret)) { mov_current_sample_dec(sc); @@ -8062,22 +8121,38 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, /* adjust stsd index */ if (sc->chunk_count) { - time_sample = 0; - for (i = 0; i < sc->stsc_count; i++) { - int64_t next = time_sample + mov_get_stsc_samples(sc, i); - if (next > sc->current_sample) { - sc->stsc_index = i; - sc->stsc_sample = sc->current_sample - time_sample; - break; + time_sample = 0; + for (i = 0; i < sc->stsc_count; i++) { + int64_t next = time_sample + mov_get_stsc_samples(sc, i); + if (next > sc->current_sample) { + sc->stsc_index = i; + sc->stsc_sample = sc->current_sample - time_sample; + break; + } + av_assert0(next == (int)next); + time_sample = next; } - av_assert0(next == (int)next); - time_sample = next; - } } return sample; } +static int64_t mov_get_skip_samples(AVStream *st, int sample) +{ + MOVStreamContext *sc = st->priv_data; + int64_t first_ts = st->index_entries[0].timestamp; + int64_t ts = st->index_entries[sample].timestamp; + int64_t off; + + if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) + return 0; + + /* compute skip samples according to stream start_pad, seek ts and first ts */ + off = av_rescale_q(ts - first_ts, st->time_base, + (AVRational){1, st->codecpar->sample_rate}); + return FFMAX(sc->start_pad - off, 0); +} + static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) { MOVContext *mc = s->priv_data; @@ -8096,18 +8171,19 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti if (mc->seek_individually) { /* adjust seek timestamp to found sample timestamp */ int64_t seek_timestamp = st->index_entries[sample].timestamp; + st->internal->skip_samples = mov_get_skip_samples(st, sample); for (i = 0; i < s->nb_streams; i++) { int64_t timestamp; - MOVStreamContext *sc = s->streams[i]->priv_data; st = s->streams[i]; - st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0; if (stream_index == i) continue; timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base); - mov_seek_stream(s, st, timestamp, flags); + sample = mov_seek_stream(s, st, timestamp, flags); + if (sample >= 0) + st->internal->skip_samples = mov_get_skip_samples(st, sample); } } else { for (i = 0; i < s->nb_streams; i++) { @@ -8166,6 +8242,10 @@ static const AVOption mov_options[] = { AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS }, { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, + { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key), + AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, + { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv), + AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files! "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key), AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"}, diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 5d8dc4fd5..bade57dce 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -78,7 +78,7 @@ static const AVOption options[] = { { "delay_moov", "Delay writing the initial moov until the first fragment is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "global_sidx", "Write a global sidx index at the start of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "skip_sidx", "Skip writing of sidx atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - { "write_colr", "Write colr atom (Experimental, may be renamed or changed, do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, + { "write_colr", "Write colr atom even if the color info is unspecified (Experimental, may be renamed or changed, do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "prefer_icc", "If writing colr atom prioritise usage of ICC profile if it exists in stream packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_PREFER_ICC}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "use_metadata_tags", "Use mdta atom for metadata.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, @@ -365,7 +365,7 @@ static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *trac } struct eac3_info { - AVPacket pkt; + AVPacket *pkt; uint8_t ec3_done; uint8_t num_blocks; @@ -407,6 +407,9 @@ static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track) return AVERROR(ENOMEM); info = track->eac3_priv; + if (!info->pkt && !(info->pkt = av_packet_alloc())) + return AVERROR(ENOMEM); + if (avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size) < 0) { /* drop the packets until we see a good one */ if (!track->entry) { @@ -511,20 +514,20 @@ concatenate: } if (!info->num_blocks) { - ret = av_packet_ref(&info->pkt, pkt); + ret = av_packet_ref(info->pkt, pkt); if (!ret) info->num_blocks = num_blocks; goto end; } else { - if ((ret = av_grow_packet(&info->pkt, pkt->size)) < 0) + if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0) goto end; - memcpy(info->pkt.data + info->pkt.size - pkt->size, pkt->data, pkt->size); + memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size); info->num_blocks += num_blocks; - info->pkt.duration += pkt->duration; + info->pkt->duration += pkt->duration; if (info->num_blocks != 6) goto end; av_packet_unref(pkt); - av_packet_move_ref(pkt, &info->pkt); + av_packet_move_ref(pkt, info->pkt); info->num_blocks = 0; } ret = pkt->size; @@ -633,12 +636,59 @@ static unsigned compute_avg_bitrate(MOVTrack *track) return size * 8 * track->timescale / track->track_duration; } +struct mpeg4_bit_rate_values { + uint32_t buffer_size; ///< Size of the decoding buffer for the elementary stream in bytes. + uint32_t max_bit_rate; ///< Maximum rate in bits/second over any window of one second. + uint32_t avg_bit_rate; ///< Average rate in bits/second over the entire presentation. +}; + +static struct mpeg4_bit_rate_values calculate_mpeg4_bit_rates(MOVTrack *track) +{ + AVCPBProperties *props = track->st ? + (AVCPBProperties*)av_stream_get_side_data(track->st, + AV_PKT_DATA_CPB_PROPERTIES, + NULL) : + NULL; + struct mpeg4_bit_rate_values bit_rates = { 0 }; + + bit_rates.avg_bit_rate = compute_avg_bitrate(track); + if (!bit_rates.avg_bit_rate) { + // if the average bit rate cannot be calculated at this point, such as + // in the case of fragmented MP4, utilize the following values as + // fall-back in priority order: + // + // 1. average bit rate property + // 2. bit rate (usually average over the whole clip) + // 3. maximum bit rate property + + if (props && props->avg_bitrate) { + bit_rates.avg_bit_rate = props->avg_bitrate; + } else if (track->par->bit_rate) { + bit_rates.avg_bit_rate = track->par->bit_rate; + } else if (props && props->max_bitrate) { + bit_rates.avg_bit_rate = props->max_bitrate; + } + } + + // (FIXME should be max rate in any 1 sec window) + bit_rates.max_bit_rate = FFMAX(track->par->bit_rate, + bit_rates.avg_bit_rate); + + // utilize values from properties if we have them available + if (props) { + bit_rates.max_bit_rate = FFMAX(bit_rates.max_bit_rate, + props->max_bitrate); + bit_rates.buffer_size = props->buffer_size / 8; + } + + return bit_rates; +} + static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic { - AVCPBProperties *props; + struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track); int64_t pos = avio_tell(pb); int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0; - unsigned avg_bitrate; avio_wb32(pb, 0); // size ffio_wfourcc(pb, "esds"); @@ -669,14 +719,9 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic else avio_w8(pb, 0x11); // flags (= Visualstream) - props = (AVCPBProperties*)av_stream_get_side_data(track->st, AV_PKT_DATA_CPB_PROPERTIES, - NULL); - - avio_wb24(pb, props ? props->buffer_size / 8 : 0); // Buffersize DB - - avg_bitrate = compute_avg_bitrate(track); - avio_wb32(pb, props ? FFMAX3(props->max_bitrate, props->avg_bitrate, avg_bitrate) : FFMAX(track->par->bit_rate, avg_bitrate)); // maxbitrate (FIXME should be max rate in any 1 sec window) - avio_wb32(pb, avg_bitrate); + avio_wb24(pb, bit_rates.buffer_size); // Buffersize DB + avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate + avio_wb32(pb, bit_rates.avg_bit_rate); if (track->vos_len) { // DecoderSpecific info descriptor @@ -1049,6 +1094,25 @@ static int get_samples_per_packet(MOVTrack *track) return first_duration; } +static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track) +{ + int64_t pos = avio_tell(pb); + struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track); + if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate && + !bit_rates.buffer_size) + // no useful data to be written, skip + return 0; + + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "btrt"); + + avio_wb32(pb, bit_rates.buffer_size); + avio_wb32(pb, bit_rates.max_bit_rate); + avio_wb32(pb, bit_rates.avg_bit_rate); + + return update_size(pb, pos); +} + static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) { int64_t pos = avio_tell(pb); @@ -1197,6 +1261,10 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex return ret; } + if (track->mode == MODE_MP4 && + ((ret = mov_write_btrt_tag(pb, track)) < 0)) + return ret; + ret = update_size(pb, pos); return ret; } @@ -1588,6 +1656,10 @@ static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) { unsigned int tag = track->par->codec_tag; + // "rtp " is used to distinguish internally created RTP-hint tracks + // (with rtp_ctx) from other tracks. + if (tag == MKTAG('r','t','p',' ')) + tag = 0; if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL && (track->par->codec_id == AV_CODEC_ID_DVVIDEO || track->par->codec_id == AV_CODEC_ID_RAWVIDEO || @@ -1712,6 +1784,7 @@ static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order) static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track) { + int ret = AVERROR_BUG; int64_t pos = avio_tell(pb); avio_wb32(pb, 0); /* size */ avio_wl32(pb, track->tag); // store it byteswapped @@ -1724,6 +1797,10 @@ static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track) else if (track->par->extradata_size) avio_write(pb, track->par->extradata, track->par->extradata_size); + if (track->mode == MODE_MP4 && + ((ret = mov_write_btrt_tag(pb, track)) < 0)) + return ret; + return update_size(pb, pos); } @@ -1904,7 +1981,7 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc) // Ref (MP4): ISO/IEC 14496-12:2012 const uint8_t *icc_profile; - int icc_profile_size; + buffer_size_t icc_profile_size; if (prefer_icc) { icc_profile = av_stream_get_side_data(track->st, AV_PKT_DATA_ICC_PROFILE, &icc_profile_size); @@ -1951,7 +2028,6 @@ static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track) side_data = av_stream_get_side_data(track->st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL, NULL); if (!side_data) { - av_log(NULL, AV_LOG_VERBOSE, "Not writing 'clli' atom. No content light level info.\n"); return 0; } content_light_metadata = (const AVContentLightMetadata*)side_data; @@ -1978,7 +2054,6 @@ static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track) side_data = av_stream_get_side_data(track->st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, NULL); metadata = (const AVMasteringDisplayMetadata*)side_data; if (!metadata || !metadata->has_primaries || !metadata->has_luminance) { - av_log(NULL, AV_LOG_VERBOSE, "Not writing 'mdcv' atom. Missing mastering metadata.\n"); return 0; } @@ -2027,6 +2102,7 @@ static void find_compressor(char * compressor_name, int len, MOVTrack *track) static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) { + int ret = AVERROR_BUG; int64_t pos = avio_tell(pb); char compressor_name[32] = { 0 }; int avid = 0; @@ -2164,11 +2240,17 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex else av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n"); } - if (mov->flags & FF_MOV_FLAG_WRITE_COLR) { - if (track->mode == MODE_MOV || track->mode == MODE_MP4) - mov_write_colr_tag(pb, track, mov->flags & FF_MOV_FLAG_PREFER_ICC); - else - av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4.\n"); + if (track->mode == MODE_MOV || track->mode == MODE_MP4) { + int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED && + track->par->color_trc != AVCOL_TRC_UNSPECIFIED && + track->par->color_space != AVCOL_SPC_UNSPECIFIED; + if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR || + av_stream_get_side_data(track->st, AV_PKT_DATA_ICC_PROFILE, NULL)) { + int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info; + mov_write_colr_tag(pb, track, prefer_icc); + } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) { + av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4.\n"); + } } if (track->mode == MODE_MOV || track->mode == MODE_MP4) { mov_write_clli_tag(pb, track); @@ -2179,7 +2261,7 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex AVStereo3D* stereo_3d = (AVStereo3D*) av_stream_get_side_data(track->st, AV_PKT_DATA_STEREO3D, NULL); AVSphericalMapping* spherical_mapping = (AVSphericalMapping*)av_stream_get_side_data(track->st, AV_PKT_DATA_SPHERICAL, NULL); AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *) - av_stream_get_side_data(track->st, AV_PKT_DATA_DOVI_CONF, NULL);; + av_stream_get_side_data(track->st, AV_PKT_DATA_DOVI_CONF, NULL); if (stereo_3d) mov_write_st3d_tag(s, pb, stereo_3d); @@ -2201,6 +2283,10 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid); } + if (track->mode == MODE_MP4 && + ((ret = mov_write_btrt_tag(pb, track)) < 0)) + return ret; + /* extra padding for avid stsd */ /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */ if (avid) @@ -2819,21 +2905,50 @@ static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext return update_size(pb, pos); } -static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track) +static void get_pts_range(MOVMuxContext *mov, MOVTrack *track, + int64_t *start, int64_t *end) { - if (track->tag == MKTAG('t','m','c','d')) { + if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) { // tmcd tracks gets track_duration set in mov_write_moov_tag from // another track's duration, while the end_pts may be left at zero. // Calculate the pts duration for that track instead. - return av_rescale(calc_pts_duration(mov, &mov->tracks[track->src_track]), - track->timescale, mov->tracks[track->src_track].timescale); + get_pts_range(mov, &mov->tracks[track->src_track], start, end); + *start = av_rescale(*start, track->timescale, + mov->tracks[track->src_track].timescale); + *end = av_rescale(*end, track->timescale, + mov->tracks[track->src_track].timescale); + return; } if (track->end_pts != AV_NOPTS_VALUE && track->start_dts != AV_NOPTS_VALUE && track->start_cts != AV_NOPTS_VALUE) { - return track->end_pts - (track->start_dts + track->start_cts); + *start = track->start_dts + track->start_cts; + *end = track->end_pts; + return; } - return track->track_duration; + *start = 0; + *end = track->track_duration; +} + +static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track) +{ + int64_t start, end; + get_pts_range(mov, track, &start, &end); + return end - start; +} + +// Calculate the actual duration of the track, after edits. +// If it starts with a pts < 0, that is removed by the edit list. +// If it starts with a pts > 0, the edit list adds a delay before that. +// Thus, with edit lists enabled, the post-edit output of the file is +// starting with pts=0. +static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track) +{ + int64_t start, end; + get_pts_range(mov, track, &start, &end); + if (mov->use_editlist != 0) + start = 0; + return end - start; } static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov, @@ -2921,7 +3036,8 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, int group = 0; uint32_t *display_matrix = NULL; - int display_matrix_size, i; + buffer_size_t display_matrix_size; + int i; if (st) { if (mov->per_stream_grouping) @@ -3060,7 +3176,7 @@ static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track) static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) { - int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track), + int64_t duration = av_rescale_rnd(calc_samples_pts_duration(mov, track), MOV_TIMESCALE, track->timescale, AV_ROUND_UP); int version = duration < INT32_MAX ? 0 : 1; @@ -3620,7 +3736,7 @@ static int mov_write_covr(AVIOContext *pb, AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { MOVTrack *trk = &mov->tracks[i]; - if (!is_cover_image(trk->st) || trk->cover_image.size <= 0) + if (!is_cover_image(trk->st) || trk->cover_image->size <= 0) continue; if (!pos) { @@ -3628,11 +3744,11 @@ static int mov_write_covr(AVIOContext *pb, AVFormatContext *s) avio_wb32(pb, 0); ffio_wfourcc(pb, "covr"); } - avio_wb32(pb, 16 + trk->cover_image.size); + avio_wb32(pb, 16 + trk->cover_image->size); ffio_wfourcc(pb, "data"); avio_wb32(pb, trk->tag); avio_wb32(pb , 0); - avio_write(pb, trk->cover_image.data, trk->cover_image.size); + avio_write(pb, trk->cover_image->data, trk->cover_image->size); } return pos ? update_size(pb, pos) : 0; @@ -4061,7 +4177,8 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov, track->tref_tag = MKTAG('h','i','n','t'); track->tref_id = mov->tracks[track->src_track].track_id; } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) { - int * fallback, size; + buffer_size_t size; + int *fallback; fallback = (int*)av_stream_get_side_data(track->st, AV_PKT_DATA_FALLBACK_TRACK, &size); @@ -4129,8 +4246,6 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormat { int64_t pos = avio_tell(pb); int i; - int64_t manifest_bit_rate = 0; - AVCPBProperties *props = NULL; static const uint8_t uuid[] = { 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd, @@ -4156,6 +4271,8 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormat for (i = 0; i < mov->nb_streams; i++) { MOVTrack *track = &mov->tracks[i]; + struct mpeg4_bit_rate_values bit_rates = + calculate_mpeg4_bit_rates(track); const char *type; int track_id = track->track_id; char track_name_buf[32] = { 0 }; @@ -4171,17 +4288,9 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormat continue; } - props = (AVCPBProperties*)av_stream_get_side_data(track->st, AV_PKT_DATA_CPB_PROPERTIES, NULL); - - if (track->par->bit_rate) { - manifest_bit_rate = track->par->bit_rate; - } else if (props) { - manifest_bit_rate = props->max_bitrate; - } - - avio_printf(pb, "<%s systemBitrate=\"%"PRId64"\">\n", type, - manifest_bit_rate); - param_write_int(pb, "systemBitrate", manifest_bit_rate); + avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type, + bit_rates.avg_bit_rate); + param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate); param_write_int(pb, "trackID", track_id); param_write_string(pb, "systemLanguage", lang ? lang->value : "und"); @@ -4798,28 +4907,40 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track) static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov) { - int64_t pos = avio_tell(pb); - int i; + AVIOContext *mfra_pb; + int i, ret, sz; + uint8_t *buf; - avio_wb32(pb, 0); /* size placeholder */ - ffio_wfourcc(pb, "mfra"); + ret = avio_open_dyn_buf(&mfra_pb); + if (ret < 0) + return ret; + + avio_wb32(mfra_pb, 0); /* size placeholder */ + ffio_wfourcc(mfra_pb, "mfra"); /* An empty mfra atom is enough to indicate to the publishing point that * the stream has ended. */ if (mov->flags & FF_MOV_FLAG_ISML) - return update_size(pb, pos); + goto done_mfra; for (i = 0; i < mov->nb_streams; i++) { MOVTrack *track = &mov->tracks[i]; if (track->nb_frag_info) - mov_write_tfra_tag(pb, track); + mov_write_tfra_tag(mfra_pb, track); } - avio_wb32(pb, 16); - ffio_wfourcc(pb, "mfro"); - avio_wb32(pb, 0); /* version + flags */ - avio_wb32(pb, avio_tell(pb) + 4 - pos); + avio_wb32(mfra_pb, 16); + ffio_wfourcc(mfra_pb, "mfro"); + avio_wb32(mfra_pb, 0); /* version + flags */ + avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4); - return update_size(pb, pos); +done_mfra: + + sz = update_size(mfra_pb, 0); + ret = avio_get_dyn_buf(mfra_pb, &buf); + avio_write(pb, buf, ret); + ffio_free_dyn_buf(&mfra_pb); + + return sz; } static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov) @@ -4875,7 +4996,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) { MOVMuxContext *mov = s->priv_data; int64_t pos = avio_tell(pb); - int has_h264 = 0, has_video = 0; + int has_h264 = 0, has_av1 = 0, has_video = 0; int i; for (i = 0; i < s->nb_streams; i++) { @@ -4886,6 +5007,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) has_video = 1; if (st->codecpar->codec_id == AV_CODEC_ID_H264) has_h264 = 1; + if (st->codecpar->codec_id == AV_CODEC_ID_AV1) + has_av1 = 1; } avio_wb32(pb, 0); /* size */ @@ -4909,6 +5032,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) ffio_wfourcc(pb, "cmfc"); if (mov->flags & FF_MOV_FLAG_FRAGMENT && !(mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)) ffio_wfourcc(pb, "iso6"); + if (has_av1) + ffio_wfourcc(pb, "av01"); } else { if (mov->flags & FF_MOV_FLAG_FRAGMENT) ffio_wfourcc(pb, "iso6"); @@ -5181,15 +5306,19 @@ static int mov_flush_fragment(AVFormatContext *s, int force) for (i = 0; i < s->nb_streams; i++) { MOVTrack *track = &mov->tracks[i]; if (!track->end_reliable) { - AVPacket pkt; - if (!ff_interleaved_peek(s, i, &pkt, 1)) { + const AVPacket *pkt = ff_interleaved_peek(s, i); + if (pkt) { + int64_t offset, dts, pts; + ff_get_muxer_ts_offset(s, i, &offset); + pts = pkt->pts + offset; + dts = pkt->dts + offset; if (track->dts_shift != AV_NOPTS_VALUE) - pkt.dts += track->dts_shift; - track->track_duration = pkt.dts - track->start_dts; - if (pkt.pts != AV_NOPTS_VALUE) - track->end_pts = pkt.pts; + dts += track->dts_shift; + track->track_duration = dts - track->start_dts; + if (pts != AV_NOPTS_VALUE) + track->end_pts = pts; else - track->end_pts = pkt.dts; + track->end_pts = dts; } } } @@ -5432,7 +5561,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) AVProducerReferenceTime *prft; unsigned int samples_in_chunk = 0; int size = pkt->size, ret = 0, offset = 0; - int prft_size; + buffer_size_t prft_size; uint8_t *reformatted_data = NULL; ret = check_pkt(s, pkt); @@ -5582,6 +5711,22 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) goto end; avio_write(pb, pkt->data, size); #endif + } else if (par->codec_id == AV_CODEC_ID_EIA_608) { + size = 8; + + for (int i = 0; i < pkt->size; i += 3) { + if (pkt->data[i] == 0xFC) { + size += 2; + } + } + avio_wb32(pb, size); + ffio_wfourcc(pb, "cdat"); + for (int i = 0; i < pkt->size; i += 3) { + if (pkt->data[i] == 0xFC) { + avio_w8(pb, pkt->data[i + 1]); + avio_w8(pb, pkt->data[i + 2]); + } + } } else { if (trk->cenc.aes_ctr) { if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) { @@ -5601,11 +5746,12 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) if (trk->entry >= trk->cluster_capacity) { unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE; - if (av_reallocp_array(&trk->cluster, new_capacity, - sizeof(*trk->cluster))) { + void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster)); + if (!cluster) { ret = AVERROR(ENOMEM); goto err; } + trk->cluster = cluster; trk->cluster_capacity = new_capacity; } @@ -5768,7 +5914,7 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) trk->par->codec_id == AV_CODEC_ID_AAC || trk->par->codec_id == AV_CODEC_ID_AV1 || trk->par->codec_id == AV_CODEC_ID_FLAC) { - int side_size = 0; + buffer_size_t side_size; uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) { void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE); @@ -5827,20 +5973,20 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) static int mov_write_subtitle_end_packet(AVFormatContext *s, int stream_index, int64_t dts) { - AVPacket end; + MOVMuxContext *mov = s->priv_data; + AVPacket *end = mov->pkt; uint8_t data[2] = {0}; int ret; - av_init_packet(&end); - end.size = sizeof(data); - end.data = data; - end.pts = dts; - end.dts = dts; - end.duration = 0; - end.stream_index = stream_index; + end->size = sizeof(data); + end->data = data; + end->pts = dts; + end->dts = dts; + end->duration = 0; + end->stream_index = stream_index; - ret = mov_write_single_packet(s, &end); - av_packet_unref(&end); + ret = mov_write_single_packet(s, end); + av_packet_unref(end); return ret; } @@ -5867,7 +6013,7 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) return 0; } - if ((ret = av_packet_ref(&trk->cover_image, pkt)) < 0) + if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0) return ret; return 0; @@ -5953,7 +6099,7 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum) MOVMuxContext *mov = s->priv_data; MOVTrack *track = &mov->tracks[tracknum]; - AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY }; + AVPacket *pkt = mov->pkt; int i, len; track->mode = mov->mode; @@ -6015,13 +6161,16 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum) } #endif + pkt->stream_index = tracknum; + pkt->flags = AV_PKT_FLAG_KEY; + for (i = 0; i < s->nb_chapters; i++) { AVChapter *c = s->chapters[i]; AVDictionaryEntry *t; int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE}); - pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE}); - pkt.duration = end - pkt.dts; + pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE}); + pkt->duration = end - pkt->dts; if ((t = av_dict_get(c->metadata, "title", NULL, 0))) { static const char encd[12] = { @@ -6029,18 +6178,22 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum) 'e', 'n', 'c', 'd', 0x00, 0x00, 0x01, 0x00 }; len = strlen(t->value); - pkt.size = len + 2 + 12; - pkt.data = av_malloc(pkt.size); - if (!pkt.data) + pkt->size = len + 2 + 12; + pkt->data = av_malloc(pkt->size); + if (!pkt->data) { + av_packet_unref(pkt); return AVERROR(ENOMEM); - AV_WB16(pkt.data, len); - memcpy(pkt.data + 2, t->value, len); - memcpy(pkt.data + len + 2, encd, sizeof(encd)); - ff_mov_write_packet(s, &pkt); - av_freep(&pkt.data); + } + AV_WB16(pkt->data, len); + memcpy(pkt->data + 2, t->value, len); + memcpy(pkt->data + len + 2, encd, sizeof(encd)); + ff_mov_write_packet(s, pkt); + av_freep(&pkt->data); } } + av_packet_unref(mov->pkt); + return 0; } @@ -6056,12 +6209,13 @@ static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, int src_ static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc) { - int ret; MOVMuxContext *mov = s->priv_data; MOVTrack *track = &mov->tracks[index]; AVStream *src_st = s->streams[src_index]; - AVPacket pkt = {.stream_index = index, .flags = AV_PKT_FLAG_KEY, .size = 4}; + uint8_t data[4]; + AVPacket *pkt = mov->pkt; AVRational rate = find_fps(s, src_st); + int ret; /* tmcd track based on video stream */ track->mode = mov->mode; @@ -6083,12 +6237,13 @@ static int mov_create_timecode_track(AVFormatContext *s, int index, int src_inde track->st->avg_frame_rate = av_inv_q(rate); /* the tmcd track just contains one packet with the frame number */ - pkt.data = av_malloc(pkt.size); - if (!pkt.data) - return AVERROR(ENOMEM); - AV_WB32(pkt.data, tc.start); - ret = ff_mov_write_packet(s, &pkt); - av_free(pkt.data); + pkt->data = data; + pkt->stream_index = index; + pkt->flags = AV_PKT_FLAG_KEY; + pkt->size = 4; + AV_WB32(pkt->data, tc.start); + ret = ff_mov_write_packet(s, pkt); + av_packet_unref(pkt); return ret; } @@ -6150,10 +6305,13 @@ static void mov_free(AVFormatContext *s) MOVMuxContext *mov = s->priv_data; int i; + av_packet_free(&mov->pkt); + + if (!mov->tracks) + return; + if (mov->chapter_track) { - if (mov->tracks[mov->chapter_track].par) - av_freep(&mov->tracks[mov->chapter_track].par->extradata); - av_freep(&mov->tracks[mov->chapter_track].par); + avcodec_parameters_free(&mov->tracks[mov->chapter_track].par); } for (i = 0; i < mov->nb_streams; i++) { @@ -6163,20 +6321,22 @@ static void mov_free(AVFormatContext *s) av_freep(&mov->tracks[i].par); av_freep(&mov->tracks[i].cluster); av_freep(&mov->tracks[i].frag_info); - av_packet_unref(&mov->tracks[i].cover_image); + av_packet_free(&mov->tracks[i].cover_image); if (mov->tracks[i].eac3_priv) { struct eac3_info *info = mov->tracks[i].eac3_priv; - av_packet_unref(&info->pkt); + av_packet_free(&info->pkt); av_freep(&mov->tracks[i].eac3_priv); } if (mov->tracks[i].vos_len) av_freep(&mov->tracks[i].vos_data); ff_mov_cenc_free(&mov->tracks[i].cenc); + ffio_free_dyn_buf(&mov->tracks[i].mdat_buf); } av_freep(&mov->tracks); + ffio_free_dyn_buf(&mov->mdat_buf); } static uint32_t rgb_to_yuv(uint32_t rgb) @@ -6248,7 +6408,6 @@ static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, static int mov_init(AVFormatContext *s) { MOVMuxContext *mov = s->priv_data; - AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0); int i, ret; mov->fc = s; @@ -6256,15 +6415,15 @@ static int mov_init(AVFormatContext *s) /* Default mode == MP4 */ mov->mode = MODE_MP4; - if (s->oformat) { - if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP; - else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2; - else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV; - else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP; - else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD; - else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM; - else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V; - } +#define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name)) + if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP; + else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2; + else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV; + else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP; + else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD; + else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM; + else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V; +#undef IS_MODE if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) mov->flags |= FF_MOV_FLAG_EMPTY_MOOV; @@ -6366,6 +6525,9 @@ static int mov_init(AVFormatContext *s) if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4) || mov->write_tmcd == 1) { + AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode", + NULL, 0); + /* +1 tmcd track for each video stream with a timecode */ for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; @@ -6394,6 +6556,10 @@ static int mov_init(AVFormatContext *s) mov->nb_streams += mov->nb_meta_tmcd; } + mov->pkt = av_packet_alloc(); + if (!mov->pkt) + return AVERROR(ENOMEM); + // Reserve an extra stream for chapters for the case where chapters // are written in the trailer mov->tracks = av_mallocz_array((mov->nb_streams + 1), sizeof(*mov->tracks)); @@ -6501,6 +6667,11 @@ static int mov_init(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n"); return AVERROR_PATCHWELCOME; } + if (is_cover_image(st)) { + track->cover_image = av_packet_alloc(); + if (!track->cover_image) + return AVERROR(ENOMEM); + } } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { track->timescale = st->codecpar->sample_rate; if (!st->codecpar->frame_size && !av_get_bits_per_sample(st->codecpar->codec_id)) { @@ -6586,7 +6757,6 @@ static int mov_write_header(AVFormatContext *s) { AVIOContext *pb = s->pb; MOVMuxContext *mov = s->priv_data; - AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0); int i, ret, hint_track = 0, tmcd_track = 0, nb_tracks = s->nb_streams; if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) @@ -6685,6 +6855,8 @@ static int mov_write_header(AVFormatContext *s) } if (mov->nb_meta_tmcd) { + const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata, + "timecode", NULL, 0); /* Initialize the tmcd tracks */ for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; @@ -6873,6 +7045,7 @@ static int mov_write_trailer(AVFormatContext *s) AVCodecParameters *par = track->par; track->vos_len = par->extradata_size; + av_freep(&track->vos_data); track->vos_data = av_malloc(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE); if (!track->vos_data) return AVERROR(ENOMEM); @@ -6967,7 +7140,9 @@ static int mov_write_trailer(AVFormatContext *s) } if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) { avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER); - mov_write_mfra_tag(pb, mov); + res = mov_write_mfra_tag(pb, mov); + if (res < 0) + return res; } } @@ -6989,6 +7164,7 @@ static int mov_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt) return ret; } +#if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER static const AVCodecTag codec_3gp_tags[] = { { AV_CODEC_ID_H263, MKTAG('s','2','6','3') }, { AV_CODEC_ID_H264, MKTAG('a','v','c','1') }, @@ -6999,8 +7175,10 @@ static const AVCodecTag codec_3gp_tags[] = { { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') }, { AV_CODEC_ID_NONE, 0 }, }; +static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL }; +#endif -const AVCodecTag codec_mp4_tags[] = { +static const AVCodecTag codec_mp4_tags[] = { { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') }, @@ -7017,6 +7195,7 @@ const AVCodecTag codec_mp4_tags[] = { { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') }, { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') }, { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, + { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') }, { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') }, { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') }, { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') }, @@ -7035,8 +7214,11 @@ const AVCodecTag codec_mp4_tags[] = { { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') }, { AV_CODEC_ID_NONE, 0 }, }; +#if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER +static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL }; +#endif -const AVCodecTag codec_ism_tags[] = { +static const AVCodecTag codec_ism_tags[] = { { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') }, { AV_CODEC_ID_NONE , 0 }, }; @@ -7099,7 +7281,7 @@ AVOutputFormat ff_tgp_muxer = { .write_trailer = mov_write_trailer, .deinit = mov_free, .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE, - .codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 }, + .codec_tag = codec_3gp_tags_list, .check_bitstream = mov_check_bitstream, .priv_class = &tgp_muxer_class, }; @@ -7121,7 +7303,7 @@ AVOutputFormat ff_mp4_muxer = { .write_trailer = mov_write_trailer, .deinit = mov_free, .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE, - .codec_tag = (const AVCodecTag* const []){ codec_mp4_tags, 0 }, + .codec_tag = mp4_codec_tags_list, .check_bitstream = mov_check_bitstream, .priv_class = &mp4_muxer_class, }; @@ -7142,7 +7324,7 @@ AVOutputFormat ff_psp_muxer = { .write_trailer = mov_write_trailer, .deinit = mov_free, .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE, - .codec_tag = (const AVCodecTag* const []){ codec_mp4_tags, 0 }, + .codec_tag = mp4_codec_tags_list, .check_bitstream = mov_check_bitstream, .priv_class = &psp_muxer_class, }; @@ -7162,7 +7344,7 @@ AVOutputFormat ff_tg2_muxer = { .write_trailer = mov_write_trailer, .deinit = mov_free, .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE, - .codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 }, + .codec_tag = codec_3gp_tags_list, .check_bitstream = mov_check_bitstream, .priv_class = &tg2_muxer_class, }; diff --git a/libavformat/movenc.h b/libavformat/movenc.h index 997b2d61c..cdbc4074c 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -134,7 +134,7 @@ typedef struct MOVTrack { uint32_t default_size; HintSampleQueue sample_queue; - AVPacket cover_image; + AVPacket *cover_image; AVIOContext *mdat_buf; int64_t data_offset; @@ -215,6 +215,8 @@ typedef struct MOVMuxContext { int per_stream_grouping; AVFormatContext *fc; + AVPacket *pkt; + int use_editlist; float gamma; diff --git a/libavformat/movenccenc.c b/libavformat/movenccenc.c index b91294f70..74f3c4ccf 100644 --- a/libavformat/movenccenc.c +++ b/libavformat/movenccenc.c @@ -412,4 +412,6 @@ int ff_mov_cenc_init(MOVMuxCencContext* ctx, uint8_t* encryption_key, void ff_mov_cenc_free(MOVMuxCencContext* ctx) { av_aes_ctr_free(ctx->aes_ctr); + av_freep(&ctx->auxiliary_info); + av_freep(&ctx->auxiliary_info_sizes); } diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c index 964026ec7..47276091f 100644 --- a/libavformat/movenchint.c +++ b/libavformat/movenchint.c @@ -408,7 +408,7 @@ int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, uint8_t *buf = NULL; int size; AVIOContext *hintbuf = NULL; - AVPacket hint_pkt; + AVPacket *hint_pkt = mov->pkt; int ret = 0, count; if (!rtp_ctx) @@ -437,21 +437,22 @@ int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, /* Open a buffer for writing the hint */ if ((ret = avio_open_dyn_buf(&hintbuf)) < 0) goto done; - av_init_packet(&hint_pkt); - count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt.dts); + av_packet_unref(hint_pkt); + count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt->dts); av_freep(&buf); /* Write the hint data into the hint track */ - hint_pkt.size = size = avio_close_dyn_buf(hintbuf, &buf); - hint_pkt.data = buf; - hint_pkt.pts = hint_pkt.dts; - hint_pkt.stream_index = track_index; + hint_pkt->size = size = avio_close_dyn_buf(hintbuf, &buf); + hint_pkt->data = buf; + hint_pkt->pts = hint_pkt->dts; + hint_pkt->stream_index = track_index; if (pkt->flags & AV_PKT_FLAG_KEY) - hint_pkt.flags |= AV_PKT_FLAG_KEY; + hint_pkt->flags |= AV_PKT_FLAG_KEY; if (count > 0) - ff_mov_write_packet(s, &hint_pkt); + ff_mov_write_packet(s, hint_pkt); done: av_free(buf); + av_packet_unref(hint_pkt); sample_queue_retain(&trk->sample_queue); return ret; } diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index b044679c0..5e7f273c6 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -255,13 +255,13 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, mp3->start_pad = v>>12; mp3-> end_pad = v&4095; - st->start_skip_samples = mp3->start_pad + 528 + 1; + st->internal->start_skip_samples = mp3->start_pad + 528 + 1; if (mp3->frames) { - st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; - st->last_discard_sample = mp3->frames * (int64_t)spf; + st->internal->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; + st->internal->last_discard_sample = mp3->frames * (int64_t)spf; } if (!st->start_time) - st->start_time = av_rescale_q(st->start_skip_samples, + st->start_time = av_rescale_q(st->internal->start_skip_samples, (AVRational){1, c->sample_rate}, st->time_base); av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index 14d4b6e0a..803148f0c 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -28,6 +28,7 @@ #include "libavcodec/mpegaudio.h" #include "libavcodec/mpegaudiodata.h" #include "libavcodec/mpegaudiodecheader.h" +#include "libavcodec/packet_internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/opt.h" #include "libavutil/dict.h" @@ -131,7 +132,7 @@ typedef struct MP3Context { int pics_to_write; /* audio packets are queued here until we get all the attached pictures */ - AVPacketList *queue, *queue_end; + PacketList *queue, *queue_end; } MP3Context; static const uint8_t xing_offtbl[2][2] = {{32, 17}, {17, 9}}; @@ -354,7 +355,7 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) if (mp3->xing_offset) { uint8_t *side_data = NULL; - int side_data_size = 0; + buffer_size_t side_data_size; mp3_xing_add_frame(mp3, pkt); mp3->audio_size += pkt->size; @@ -387,7 +388,7 @@ static int mp3_queue_flush(AVFormatContext *s) mp3_write_xing(s); while (mp3->queue) { - ff_packet_list_get(&mp3->queue, &mp3->queue_end, &pkt); + avpriv_packet_list_get(&mp3->queue, &mp3->queue_end, &pkt); if (write && (ret = mp3_write_audio_packet(s, &pkt)) < 0) write = 0; av_packet_unref(&pkt); @@ -401,7 +402,8 @@ static void mp3_update_xing(AVFormatContext *s) AVReplayGain *rg; uint16_t tag_crc; uint8_t *toc; - int i, rg_size; + buffer_size_t rg_size; + int i; int64_t old_pos = avio_tell(s->pb); /* replace "Xing" identification string with "Info" for CBR files. */ @@ -522,7 +524,7 @@ static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt) if (pkt->stream_index == mp3->audio_stream_idx) { if (mp3->pics_to_write) { /* buffer audio packets until we get all the pictures */ - int ret = ff_packet_list_put(&mp3->queue, &mp3->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET); + int ret = avpriv_packet_list_put(&mp3->queue, &mp3->queue_end, pkt, av_packet_ref, 0); if (ret < 0) { av_log(s, AV_LOG_WARNING, "Not enough memory to buffer audio. Skipping picture streams\n"); @@ -630,7 +632,7 @@ static void mp3_deinit(struct AVFormatContext *s) { MP3Context *mp3 = s->priv_data; - ff_packet_list_free(&mp3->queue, &mp3->queue_end); + avpriv_packet_list_free(&mp3->queue, &mp3->queue_end); av_freep(&mp3->xing_frame); } diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index f33323a59..88c55e3d2 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -127,7 +127,11 @@ static void mpc8_get_chunk_header(AVIOContext *pb, int *tag, int64_t *size) pos = avio_tell(pb); *tag = avio_rl16(pb); *size = ffio_read_varlen(pb); - *size -= avio_tell(pb) - pos; + pos -= avio_tell(pb); + if (av_sat_add64(*size, pos) != (uint64_t)*size + pos) { + *size = -1; + } else + *size += pos; } static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index a5e17925c..79610ec60 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -622,7 +622,7 @@ skip: st->codecpar->channel_layout = AV_CH_LAYOUT_MONO; st->codecpar->sample_rate = 8000; } - st->request_probe = request_probe; + st->internal->request_probe = request_probe; st->need_parsing = AVSTREAM_PARSE_FULL; found: @@ -934,7 +934,7 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) if (tmpq->current_sub_idx >= tmpq->nb_subs) continue; - ts = tmpq->subs[tmpq->current_sub_idx].pts; + ts = tmpq->subs[tmpq->current_sub_idx]->pts; if (ts < min_ts) { min_ts = ts; sid = i; @@ -950,7 +950,7 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) /* compute maximum packet size using the next packet position. This is * useful when the len in the header is non-sense */ if (q->current_sub_idx < q->nb_subs) { - psize = q->subs[q->current_sub_idx].pos - pkt->pos; + psize = q->subs[q->current_sub_idx]->pos - pkt->pos; } else { int64_t fsize = avio_size(pb); psize = fsize < 0 ? 0xffff : fsize - pkt->pos; diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c index 9bd0a555d..d37f181ea 100644 --- a/libavformat/mpegenc.c +++ b/libavformat/mpegenc.c @@ -48,9 +48,9 @@ typedef struct StreamInfo { uint8_t id; int max_buffer_size; /* in bytes */ int buffer_index; - PacketDesc *predecode_packet; + PacketDesc *predecode_packet; /* start of packet queue */ + PacketDesc *last_packet; /* end of packet queue */ PacketDesc *premux_packet; - PacketDesc **next_packet; int packet_number; uint8_t lpcm_header[3]; int lpcm_align; @@ -986,6 +986,8 @@ static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr) } stream->buffer_index -= pkt_desc->size; stream->predecode_packet = pkt_desc->next; + if (!stream->predecode_packet) + stream->last_packet = NULL; av_freep(&pkt_desc); } } @@ -1149,7 +1151,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) StreamInfo *stream = st->priv_data; int64_t pts, dts; PacketDesc *pkt_desc; - int preload; + int preload, ret; const int is_iframe = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY); @@ -1177,14 +1179,6 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) av_log(ctx, AV_LOG_TRACE, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n", dts / 90000.0, pts / 90000.0, pkt->flags, pkt->stream_index, pts != AV_NOPTS_VALUE); - if (!stream->premux_packet) - stream->next_packet = &stream->premux_packet; - *stream->next_packet = - pkt_desc = av_mallocz(sizeof(PacketDesc)); - if (!pkt_desc) - return AVERROR(ENOMEM); - pkt_desc->pts = pts; - pkt_desc->dts = dts; if (st->codecpar->codec_id == AV_CODEC_ID_PCM_DVD) { if (size < 3) { @@ -1198,14 +1192,24 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) size -= 3; } + pkt_desc = av_mallocz(sizeof(PacketDesc)); + if (!pkt_desc) + return AVERROR(ENOMEM); + if (!stream->predecode_packet) { + stream->predecode_packet = pkt_desc; + } else + stream->last_packet->next = pkt_desc; + stream->last_packet = pkt_desc; + if (!stream->premux_packet) + stream->premux_packet = pkt_desc; + pkt_desc->pts = pts; + pkt_desc->dts = dts; pkt_desc->unwritten_size = pkt_desc->size = size; - if (!stream->predecode_packet) - stream->predecode_packet = pkt_desc; - stream->next_packet = &pkt_desc->next; - if (av_fifo_realloc2(stream->fifo, av_fifo_size(stream->fifo) + size) < 0) - return -1; + ret = av_fifo_realloc2(stream->fifo, av_fifo_size(stream->fifo) + size); + if (ret < 0) + return ret; if (s->is_dvd) { // min VOBU length 0.4 seconds (mpucoder) @@ -1259,6 +1263,11 @@ static void mpeg_mux_deinit(AVFormatContext *ctx) StreamInfo *stream = ctx->streams[i]->priv_data; if (!stream) continue; + for (PacketDesc *pkt = stream->predecode_packet; pkt; ) { + PacketDesc *tmp = pkt->next; + av_free(pkt); + pkt = tmp; + } av_fifo_freep(&stream->fifo); } } diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index bc24d89cd..6e0d9d749 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -20,6 +20,7 @@ */ #include "libavutil/buffer.h" +#include "libavutil/common.h" #include "libavutil/crc.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" @@ -106,11 +107,19 @@ struct MpegTSFilter { } u; }; -#define MAX_PIDS_PER_PROGRAM 64 +struct Stream { + int idx; + int stream_identifier; +}; + +#define MAX_STREAMS_PER_PROGRAM 128 +#define MAX_PIDS_PER_PROGRAM (MAX_STREAMS_PER_PROGRAM + 2) struct Program { unsigned int id; // program id/service id unsigned int nb_pids; unsigned int pids[MAX_PIDS_PER_PROGRAM]; + unsigned int nb_streams; + struct Stream streams[MAX_STREAMS_PER_PROGRAM]; /** have we found pmt for this program */ int pmt_found; @@ -285,16 +294,13 @@ static void clear_avprogram(MpegTSContext *ts, unsigned int programid) prg->nb_stream_indexes = 0; } -static void clear_program(MpegTSContext *ts, unsigned int programid) +static void clear_program(struct Program *p) { - int i; - - clear_avprogram(ts, programid); - for (i = 0; i < ts->nb_prg; i++) - if (ts->prg[i].id == programid) { - ts->prg[i].nb_pids = 0; - ts->prg[i].pmt_found = 0; - } + if (!p) + return; + p->nb_pids = 0; + p->nb_streams = 0; + p->pmt_found = 0; } static void clear_programs(MpegTSContext *ts) @@ -303,24 +309,24 @@ static void clear_programs(MpegTSContext *ts) ts->nb_prg = 0; } -static void add_pat_entry(MpegTSContext *ts, unsigned int programid) +static struct Program * add_program(MpegTSContext *ts, unsigned int programid) { - struct Program *p; + struct Program *p = get_program(ts, programid); + if (p) + return p; if (av_reallocp_array(&ts->prg, ts->nb_prg + 1, sizeof(*ts->prg)) < 0) { ts->nb_prg = 0; - return; + return NULL; } p = &ts->prg[ts->nb_prg]; p->id = programid; - p->nb_pids = 0; - p->pmt_found = 0; + clear_program(p); ts->nb_prg++; + return p; } -static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, - unsigned int pid) +static void add_pid_to_program(struct Program *p, unsigned int pid) { - struct Program *p = get_program(ts, programid); int i; if (!p) return; @@ -335,15 +341,6 @@ static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, p->pids[p->nb_pids++] = pid; } -static void set_pmt_found(MpegTSContext *ts, unsigned int programid) -{ - struct Program *p = get_program(ts, programid); - if (!p) - return; - - p->pmt_found = 1; -} - static void update_av_program_info(AVFormatContext *s, unsigned int programid, unsigned int pid, int version) { @@ -380,6 +377,9 @@ static int discard_pid(MpegTSContext *ts, unsigned int pid) int used = 0, discarded = 0; struct Program *p; + if (pid == PAT_PID) + return 0; + /* If none of the programs have .discard=AVDISCARD_ALL then there's * no way we have to discard this packet */ for (k = 0; k < ts->stream->nb_programs; k++) @@ -510,20 +510,22 @@ static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, { MpegTSFilter *filter; MpegTSSectionFilter *sec; + uint8_t *section_buf = av_mallocz(MAX_SECTION_SIZE); - if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_SECTION))) + if (!section_buf) return NULL; + + if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_SECTION))) { + av_free(section_buf); + return NULL; + } sec = &filter->u.section_filter; sec->section_cb = section_cb; sec->opaque = opaque; - sec->section_buf = av_mallocz(MAX_SECTION_SIZE); + sec->section_buf = section_buf; sec->check_crc = check_crc; sec->last_ver = -1; - if (!sec->section_buf) { - av_free(filter); - return NULL; - } return filter; } @@ -607,8 +609,9 @@ static int get_packet_size(AVFormatContext* s) /*init buffer to store stream for probing */ uint8_t buf[PROBE_PACKET_MAX_BUF] = {0}; int buf_size = 0; + int max_iterations = 16; - while (buf_size < PROBE_PACKET_MAX_BUF) { + while (buf_size < PROBE_PACKET_MAX_BUF && max_iterations--) { ret = avio_read_partial(s->pb, buf + buf_size, PROBE_PACKET_MAX_BUF - buf_size); if (ret < 0) return AVERROR_INVALIDDATA; @@ -880,7 +883,7 @@ static void mpegts_find_stream_type(AVStream *st, st->codecpar->codec_id = types->codec_id; st->internal->need_context_update = 1; } - st->request_probe = 0; + st->internal->request_probe = 0; return; } } @@ -913,7 +916,7 @@ static int mpegts_set_stream_info(AVStream *st, PESContext *pes, mpegts_find_stream_type(st, pes->stream_type, ISO_types); if (pes->stream_type == 4 || pes->stream_type == 0x0f) - st->request_probe = 50; + st->internal->request_probe = 50; if ((prog_reg_desc == AV_RL32("HDMV") || prog_reg_desc == AV_RL32("HDPR")) && st->codecpar->codec_id == AV_CODEC_ID_NONE) { @@ -950,12 +953,12 @@ static int mpegts_set_stream_info(AVStream *st, PESContext *pes, st->codecpar->codec_type = old_codec_type; } if ((st->codecpar->codec_id == AV_CODEC_ID_NONE || - (st->request_probe > 0 && st->request_probe < AVPROBE_SCORE_STREAM_RETRY / 5)) && + (st->internal->request_probe > 0 && st->internal->request_probe < AVPROBE_SCORE_STREAM_RETRY / 5)) && st->probe_packets > 0 && stream_type == STREAM_TYPE_PRIVATE_DATA) { st->codecpar->codec_type = AVMEDIA_TYPE_DATA; st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA; - st->request_probe = AVPROBE_SCORE_STREAM_RETRY / 5; + st->internal->request_probe = AVPROBE_SCORE_STREAM_RETRY / 5; } /* queue a context update if properties changed */ @@ -978,7 +981,7 @@ static void reset_pes_packet_state(PESContext *pes) static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) { - av_init_packet(pkt); + av_packet_unref(pkt); pkt->data = (uint8_t *)buffer; pkt->size = len; } @@ -987,7 +990,7 @@ static int new_pes_packet(PESContext *pes, AVPacket *pkt) { uint8_t *sd; - av_init_packet(pkt); + av_packet_unref(pkt); pkt->buf = pes->buffer; pkt->data = pes->buffer->data; @@ -1196,12 +1199,12 @@ static int mpegts_push_data(MpegTSFilter *filter, code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */ code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */ pes->state = MPEGTS_PESHEADER; - if (pes->st->codecpar->codec_id == AV_CODEC_ID_NONE && !pes->st->request_probe) { + if (pes->st->codecpar->codec_id == AV_CODEC_ID_NONE && !pes->st->internal->request_probe) { av_log(pes->stream, AV_LOG_TRACE, "pid=%x stream_type=%x probing\n", pes->pid, pes->stream_type); - pes->st->request_probe = 1; + pes->st->internal->request_probe = 1; } } else { pes->pes_header_size = 6; @@ -1323,8 +1326,8 @@ skip: int64_t pcr = f->last_pcr / 300; pcr_found = 1; if (st) { - pes->st->pts_wrap_reference = st->pts_wrap_reference; - pes->st->pts_wrap_behavior = st->pts_wrap_behavior; + pes->st->internal->pts_wrap_reference = st->internal->pts_wrap_reference; + pes->st->internal->pts_wrap_behavior = st->internal->pts_wrap_behavior; } if (pes->dts == AV_NOPTS_VALUE || pes->dts < pcr) { pes->pts = pes->dts = pcr; @@ -1341,7 +1344,8 @@ skip: } } - if (!pcr_found) { + if (pes->st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT && + !pcr_found) { av_log(pes->stream, AV_LOG_VERBOSE, "Forcing DTS/PTS to be unset for a " "non-trustworthy PES packet for PID %d as " @@ -1796,17 +1800,17 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type av_log(fc, AV_LOG_TRACE, "tag: 0x%02x len=%d\n", desc_tag, desc_len); - if ((st->codecpar->codec_id == AV_CODEC_ID_NONE || st->request_probe > 0) && + if ((st->codecpar->codec_id == AV_CODEC_ID_NONE || st->internal->request_probe > 0) && stream_type == STREAM_TYPE_PRIVATE_DATA) mpegts_find_stream_type(st, desc_tag, DESC_types); switch (desc_tag) { - case 0x02: /* video stream descriptor */ + case VIDEO_STREAM_DESCRIPTOR: if (get8(pp, desc_end) & 0x1) { st->disposition |= AV_DISPOSITION_STILL_IMAGE; } break; - case 0x1E: /* SL descriptor */ + case SL_DESCRIPTOR: desc_es_id = get16(pp, desc_end); if (desc_es_id < 0) break; @@ -1829,13 +1833,13 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type mpegts_open_section_filter(ts, pid, m4sl_cb, ts, 1); } break; - case 0x1F: /* FMC descriptor */ + case FMC_DESCRIPTOR: if (get16(pp, desc_end) < 0) break; if (mp4_descr_count > 0 && (st->codecpar->codec_id == AV_CODEC_ID_AAC_LATM || - (st->request_probe == 0 && st->codecpar->codec_id == AV_CODEC_ID_NONE) || - st->request_probe > 0) && + (st->internal->request_probe == 0 && st->codecpar->codec_id == AV_CODEC_ID_NONE) || + st->internal->request_probe > 0) && mp4_descr->dec_config_descr_len && mp4_descr->es_id == pid) { AVIOContext pb; ffio_init_context(&pb, mp4_descr->dec_config_descr, @@ -1844,7 +1848,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type ff_mp4_read_dec_config_descr(fc, st, &pb); if (st->codecpar->codec_id == AV_CODEC_ID_AAC && st->codecpar->extradata_size > 0) { - st->request_probe = st->need_parsing = 0; + st->internal->request_probe = st->need_parsing = 0; st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->internal->need_context_update = 1; } @@ -1955,7 +1959,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type } } break; - case 0x0a: /* ISO 639 language descriptor */ + case ISO_639_LANGUAGE_DESCRIPTOR: for (i = 0; i + 4 <= desc_len; i += 4) { language[i + 0] = get8(pp, desc_end); language[i + 1] = get8(pp, desc_end); @@ -1981,19 +1985,19 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type av_dict_set(&st->metadata, "language", language, AV_DICT_DONT_OVERWRITE); } break; - case 0x05: /* registration descriptor */ + case REGISTRATION_DESCRIPTOR: st->codecpar->codec_tag = bytestream_get_le32(pp); av_log(fc, AV_LOG_TRACE, "reg_desc=%.4s\n", (char *)&st->codecpar->codec_tag); - if (st->codecpar->codec_id == AV_CODEC_ID_NONE || st->request_probe > 0) { + if (st->codecpar->codec_id == AV_CODEC_ID_NONE || st->internal->request_probe > 0) { mpegts_find_stream_type(st, st->codecpar->codec_tag, REGD_types); if (st->codecpar->codec_tag == MKTAG('B', 'S', 'S', 'D')) - st->request_probe = 50; + st->internal->request_probe = 50; } break; case 0x52: /* stream identifier descriptor */ st->stream_identifier = 1 + get8(pp, desc_end); break; - case 0x26: /* metadata descriptor */ + case METADATA_DESCRIPTOR: if (get16(pp, desc_end) == 0xFFFF) *pp += 4; if (get8(pp, desc_end) == 0xFF) { @@ -2140,7 +2144,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_ARIB_CAPTION; st->codecpar->profile = picked_profile; - st->request_probe = 0; + st->internal->request_probe = 0; } break; case 0xb0: /* DOVI video stream descriptor */ @@ -2198,25 +2202,20 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type } static AVStream *find_matching_stream(MpegTSContext *ts, int pid, unsigned int programid, - int stream_identifier, int pmt_stream_idx) + int stream_identifier, int pmt_stream_idx, struct Program *p) { AVFormatContext *s = ts->stream; int i; AVStream *found = NULL; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->program_num != programid) - continue; - if (stream_identifier != -1) { /* match based on "stream identifier descriptor" if present */ - if (st->stream_identifier == stream_identifier+1) { - found = st; - break; - } - } else if (st->pmt_stream_idx == pmt_stream_idx) { /* match based on position within the PMT */ - found = st; - break; + if (stream_identifier) { /* match based on "stream identifier descriptor" if present */ + for (i = 0; i < p->nb_streams; i++) { + if (p->streams[i].stream_identifier == stream_identifier) + if (!found || pmt_stream_idx == i) /* fallback to idx based guess if multiple streams have the same identifier */ + found = s->streams[p->streams[i].idx]; } + } else if (pmt_stream_idx < p->nb_streams) { /* match based on position within the PMT */ + found = s->streams[p->streams[pmt_stream_idx].idx]; } if (found) { @@ -2275,6 +2274,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len { MpegTSContext *ts = filter->u.section_filter.opaque; MpegTSSectionFilter *tssf = &filter->u.section_filter; + struct Program old_program; SectionHeader h1, *h = &h1; PESContext *pes; AVStream *st; @@ -2283,6 +2283,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len int desc_list_len; uint32_t prog_reg_desc = 0; /* registration descriptor */ int stream_identifier = -1; + struct Program *prg; int mp4_descr_count = 0; Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = { { 0 } }; @@ -2306,16 +2307,26 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (!ts->scan_all_pmts && ts->skip_changes) return; - if (ts->skip_unknown_pmt && !get_program(ts, h->id)) + prg = get_program(ts, h->id); + if (prg) + old_program = *prg; + else + clear_program(&old_program); + + if (ts->skip_unknown_pmt && !prg) + return; + if (prg && prg->nb_pids && prg->pids[0] != ts->current_pid) return; if (!ts->skip_clear) - clear_program(ts, h->id); + clear_avprogram(ts, h->id); + clear_program(prg); + add_pid_to_program(prg, ts->current_pid); pcr_pid = get16(&p, p_end); if (pcr_pid < 0) return; pcr_pid &= 0x1fff; - add_pid_to_pmt(ts, h->id, pcr_pid); + add_pid_to_program(prg, pcr_pid); update_av_program_info(ts->stream, h->id, pcr_pid, h->version); av_log(ts->stream, AV_LOG_TRACE, "pcr_pid=0x%x\n", pcr_pid); @@ -2335,13 +2346,13 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len // something else is broken, exit the program_descriptors_loop break; program_info_length -= len + 2; - if (tag == 0x1d) { // IOD descriptor + if (tag == IOD_DESCRIPTOR) { get8(&p, p_end); // scope get8(&p, p_end); // label len -= 2; mp4_read_iods(ts->stream, p, len, mp4_descr + mp4_descr_count, &mp4_descr_count, MAX_MP4_DESCR_COUNT); - } else if (tag == 0x05 && len >= 4) { // registration descriptor + } else if (tag == REGISTRATION_DESCRIPTOR && len >= 4) { prog_reg_desc = bytestream_get_le32(&p); len -= 4; } @@ -2355,10 +2366,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (!ts->pkt) ts->stop_parse = 2; - set_pmt_found(ts, h->id); + if (prg) + prg->pmt_found = 1; - - for (i = 0; ; i++) { + for (i = 0; i < MAX_STREAMS_PER_PROGRAM; i++) { st = 0; pes = NULL; stream_type = get8(&p, p_end); @@ -2371,14 +2382,13 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (pid == ts->current_pid) goto out; - if (ts->merge_pmt_versions) - stream_identifier = parse_stream_identifier_desc(p, p_end); + stream_identifier = parse_stream_identifier_desc(p, p_end) + 1; /* now create stream */ if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) { pes = ts->pids[pid]->u.pes_filter.opaque; if (ts->merge_pmt_versions && !pes->st) { - st = find_matching_stream(ts, pid, h->id, stream_identifier, i); + st = find_matching_stream(ts, pid, h->id, stream_identifier, i, &old_program); if (st) { pes->st = st; pes->stream_type = stream_type; @@ -2390,9 +2400,6 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (!pes->st) goto out; pes->st->id = pes->pid; - pes->st->program_num = h->id; - pes->st->pmt_version = h->version; - pes->st->pmt_stream_idx = i; } st = pes->st; } else if (is_pes_stream(stream_type, prog_reg_desc)) { @@ -2400,7 +2407,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably pes = add_pes_stream(ts, pid, pcr_pid); if (ts->merge_pmt_versions && pes && !pes->st) { - st = find_matching_stream(ts, pid, h->id, stream_identifier, i); + st = find_matching_stream(ts, pid, h->id, stream_identifier, i, &old_program); if (st) { pes->st = st; pes->stream_type = stream_type; @@ -2412,9 +2419,6 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (!st) goto out; st->id = pes->pid; - st->program_num = h->id; - st->pmt_version = h->version; - st->pmt_stream_idx = i; } } else { int idx = ff_find_stream_index(ts->stream, pid); @@ -2422,16 +2426,13 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len st = ts->stream->streams[idx]; } if (ts->merge_pmt_versions && !st) { - st = find_matching_stream(ts, pid, h->id, stream_identifier, i); + st = find_matching_stream(ts, pid, h->id, stream_identifier, i, &old_program); } if (!st) { st = avformat_new_stream(ts->stream, NULL); if (!st) goto out; st->id = pid; - st->program_num = h->id; - st->pmt_version = h->version; - st->pmt_stream_idx = i; st->codecpar->codec_type = AVMEDIA_TYPE_DATA; if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { mpegts_find_stream_type(st, stream_type, SCTE_types); @@ -2446,7 +2447,12 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (pes && !pes->stream_type) mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc); - add_pid_to_pmt(ts, h->id, pid); + add_pid_to_program(prg, pid); + if (prg) { + prg->streams[i].idx = st->index; + prg->streams[i].stream_identifier = stream_identifier; + prg->nb_streams++; + } av_program_add_stream_index(ts->stream, h->id, st->index); @@ -2488,6 +2494,7 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len SectionHeader h1, *h = &h1; const uint8_t *p, *p_end; int sid, pmt_pid; + int nb_prg = 0; AVProgram *program; av_log(ts->stream, AV_LOG_TRACE, "PAT:\n"); @@ -2506,7 +2513,6 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len return; ts->stream->ts_id = h->id; - clear_programs(ts); for (;;) { sid = get16(&p, p_end); if (sid < 0) @@ -2525,6 +2531,7 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len /* NIT info */ } else { MpegTSFilter *fil = ts->pids[pmt_pid]; + struct Program *prg; program = av_new_program(ts->stream, sid); if (program) { program->program_num = sid; @@ -2538,11 +2545,20 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (!ts->pids[pmt_pid]) mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1); - add_pat_entry(ts, sid); - add_pid_to_pmt(ts, sid, 0); // add pat pid to program - add_pid_to_pmt(ts, sid, pmt_pid); + prg = add_program(ts, sid); + if (prg) { + unsigned prg_idx = prg - ts->prg; + if (prg->nb_pids && prg->pids[0] != pmt_pid) + clear_program(prg); + add_pid_to_program(prg, pmt_pid); + if (prg_idx > nb_prg) + FFSWAP(struct Program, ts->prg[nb_prg], ts->prg[prg_idx]); + if (prg_idx >= nb_prg) + nb_prg++; + } } } + ts->nb_prg = nb_prg; if (sid < 0) { int i,j; @@ -3048,10 +3064,11 @@ static int mpegts_read_header(AVFormatContext *s) MpegTSContext *ts = s->priv_data; AVIOContext *pb = s->pb; int64_t pos, probesize = s->probesize; + int64_t seekback = FFMAX(s->probesize, (int64_t)ts->resync_size + PROBE_PACKET_MAX_BUF); s->internal->prefer_codec_framerate = 1; - if (ffio_ensure_seekback(pb, probesize) < 0) + if (ffio_ensure_seekback(pb, seekback) < 0) av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n"); pos = avio_tell(pb); @@ -3085,7 +3102,6 @@ static int mpegts_read_header(AVFormatContext *s) AVStream *st; int pcr_pid, pid, nb_packets, nb_pcrs, ret, pcr_l; int64_t pcrs[2], pcr_h; - int packet_count[2]; uint8_t packet[TS_PACKET_SIZE]; const uint8_t *data; @@ -3111,7 +3127,6 @@ static int mpegts_read_header(AVFormatContext *s) parse_pcr(&pcr_h, &pcr_l, data) == 0) { finished_reading_packet(s, ts->raw_packet_size); pcr_pid = pid; - packet_count[nb_pcrs] = nb_packets; pcrs[nb_pcrs] = pcr_h * 300 + pcr_l; nb_pcrs++; if (nb_pcrs >= 2) { @@ -3121,7 +3136,6 @@ static int mpegts_read_header(AVFormatContext *s) } else { av_log(ts->stream, AV_LOG_WARNING, "invalid pcr pair %"PRId64" >= %"PRId64"\n", pcrs[0], pcrs[1]); pcrs[0] = pcrs[1]; - packet_count[0] = packet_count[1]; nb_pcrs--; } } @@ -3133,8 +3147,8 @@ static int mpegts_read_header(AVFormatContext *s) /* NOTE1: the bitrate is computed without the FEC */ /* NOTE2: it is only the bitrate of the start of the stream */ - ts->pcr_incr = (pcrs[1] - pcrs[0]) / (packet_count[1] - packet_count[0]); - ts->cur_pcr = pcrs[0] - ts->pcr_incr * packet_count[0]; + ts->pcr_incr = pcrs[1] - pcrs[0]; + ts->cur_pcr = pcrs[0] - ts->pcr_incr * (nb_packets - 1); s->bit_rate = TS_PACKET_SIZE * 8 * 27000000LL / ts->pcr_incr; st->codecpar->bit_rate = s->bit_rate; st->start_time = ts->cur_pcr; @@ -3284,33 +3298,37 @@ static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit) { MpegTSContext *ts = s->priv_data; + AVPacket *pkt; int64_t pos; int pos47 = ts->pos47_full % ts->raw_packet_size; pos = ((*ppos + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * ts->raw_packet_size + pos47; ff_read_frame_flush(s); if (avio_seek(s->pb, pos, SEEK_SET) < 0) return AV_NOPTS_VALUE; + pkt = av_packet_alloc(); + if (!pkt) + return AV_NOPTS_VALUE; while(pos < pos_limit) { - int ret; - AVPacket pkt; - av_init_packet(&pkt); - ret = av_read_frame(s, &pkt); - if (ret < 0) + int ret = av_read_frame(s, pkt); + if (ret < 0) { + av_packet_free(&pkt); return AV_NOPTS_VALUE; - if (pkt.dts != AV_NOPTS_VALUE && pkt.pos >= 0) { - ff_reduce_index(s, pkt.stream_index); - av_add_index_entry(s->streams[pkt.stream_index], pkt.pos, pkt.dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); - if (pkt.stream_index == stream_index && pkt.pos >= *ppos) { - int64_t dts = pkt.dts; - *ppos = pkt.pos; - av_packet_unref(&pkt); + } + if (pkt->dts != AV_NOPTS_VALUE && pkt->pos >= 0) { + ff_reduce_index(s, pkt->stream_index); + av_add_index_entry(s->streams[pkt->stream_index], pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); + if (pkt->stream_index == stream_index && pkt->pos >= *ppos) { + int64_t dts = pkt->dts; + *ppos = pkt->pos; + av_packet_free(&pkt); return dts; } } - pos = pkt.pos; - av_packet_unref(&pkt); + pos = pkt->pos; + av_packet_unref(pkt); } + av_packet_free(&pkt); return AV_NOPTS_VALUE; } diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h index 059b693f0..04874e0f4 100644 --- a/libavformat/mpegts.h +++ b/libavformat/mpegts.h @@ -137,6 +137,23 @@ #define STREAM_TYPE_AUDIO_TRUEHD 0x83 #define STREAM_TYPE_AUDIO_EAC3 0x87 +/* ISO/IEC 13818-1 Table 2-22 */ +#define STREAM_ID_PRIVATE_STREAM_1 0xbd +#define STREAM_ID_AUDIO_STREAM_0 0xc0 +#define STREAM_ID_VIDEO_STREAM_0 0xe0 +#define STREAM_ID_METADATA_STREAM 0xfc +#define STREAM_ID_EXTENDED_STREAM_ID 0xfd + +/* ISO/IEC 13818-1 Table 2-45 */ +#define VIDEO_STREAM_DESCRIPTOR 0x02 +#define REGISTRATION_DESCRIPTOR 0x05 +#define ISO_639_LANGUAGE_DESCRIPTOR 0x0a +#define IOD_DESCRIPTOR 0x1d +#define SL_DESCRIPTOR 0x1e +#define FMC_DESCRIPTOR 0x1f +#define METADATA_DESCRIPTOR 0x26 +#define METADATA_STD_DESCRIPTOR 0x27 + typedef struct MpegTSContext MpegTSContext; MpegTSContext *avpriv_mpegts_parse_open(AVFormatContext *s); @@ -168,6 +185,22 @@ typedef struct Mp4Descr { SLConfigDescr sl; } Mp4Descr; +/* + * ETSI 300 468 descriptor 0x6A(AC-3) + * Refer to: ETSI EN 300 468 V1.11.1 (2010-04) (SI in DVB systems) + */ +typedef struct DVBAC3Descriptor { + uint8_t component_type_flag; + uint8_t bsid_flag; + uint8_t mainid_flag; + uint8_t asvc_flag; + uint8_t reserved_flags; + uint8_t component_type; + uint8_t bsid; + uint8_t mainid; + uint8_t asvc; +} DVBAC3Descriptor; + /** * Parse an MPEG-2 descriptor * @param[in] fc Format context (used for logging only) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index b5ee48d01..35c835c48 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -27,6 +27,7 @@ #include "libavutil/mathematics.h" #include "libavutil/opt.h" +#include "libavcodec/ac3_parser_internal.h" #include "libavcodec/internal.h" #include "avformat.h" @@ -76,13 +77,16 @@ typedef struct MpegTSWrite { MpegTSSection pat; /* MPEG-2 PAT table */ MpegTSSection sdt; /* MPEG-2 SDT table context */ MpegTSService **services; + AVPacket *pkt; int64_t sdt_period; /* SDT period in PCR time base */ int64_t pat_period; /* PAT/PMT period in PCR time base */ int nb_services; int64_t first_pcr; + int first_dts_checked; int64_t next_pcr; int mux_rate; ///< set to 1 when VBR int pes_payload_size; + int64_t total_size; int transport_stream_id; int original_network_id; @@ -229,7 +233,7 @@ typedef struct MpegTSWriteStream { int cc; int discontinuity; int payload_size; - int first_pts_check; ///< first pts check needed + int first_timestamp_checked; ///< first pts/dts check needed int prev_payload_key; int64_t payload_pts; int64_t payload_dts; @@ -244,6 +248,8 @@ typedef struct MpegTSWriteStream { /* For Opus */ int opus_queued_samples; int opus_pending_trim_start; + + DVBAC3Descriptor *dvb_ac3_desc; } MpegTSWriteStream; static void mpegts_write_pat(AVFormatContext *s) @@ -272,7 +278,7 @@ static void putbuf(uint8_t **q_ptr, const uint8_t *buf, size_t len) static void put_registration_descriptor(uint8_t **q_ptr, uint32_t tag) { uint8_t *q = *q_ptr; - *q++ = 0x05; /* MPEG-2 registration descriptor*/ + *q++ = REGISTRATION_DESCRIPTOR; *q++ = 4; *q++ = tag; *q++ = tag >> 8; @@ -453,6 +459,7 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) AVStream *st = s->streams[i]; MpegTSWriteStream *ts_st = st->priv_data; AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); + enum AVCodecID codec_id = st->codecpar->codec_id; if (s->nb_programs) { int k, found = 0; @@ -483,19 +490,43 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) /* write optional descriptors here */ switch (st->codecpar->codec_type) { case AVMEDIA_TYPE_AUDIO: - if (st->codecpar->codec_id==AV_CODEC_ID_AC3 && (ts->flags & MPEGTS_FLAG_SYSTEM_B)) { - *q++=0x6a; // AC3 descriptor see A038 DVB SI - *q++=1; // 1 byte, all flags sets to 0 - *q++=0; // omit all fields... + if (codec_id == AV_CODEC_ID_AC3) + put_registration_descriptor(&q, MKTAG('A', 'C', '-', '3')); + if (codec_id == AV_CODEC_ID_EAC3) + put_registration_descriptor(&q, MKTAG('E', 'A', 'C', '3')); + if (ts->flags & MPEGTS_FLAG_SYSTEM_B) { + if (codec_id == AV_CODEC_ID_AC3) { + DVBAC3Descriptor *dvb_ac3_desc = ts_st->dvb_ac3_desc; + + *q++=0x6a; // AC3 descriptor see A038 DVB SI + if (dvb_ac3_desc) { + int len = 1 + + !!(dvb_ac3_desc->component_type_flag) + + !!(dvb_ac3_desc->bsid_flag) + + !!(dvb_ac3_desc->mainid_flag) + + !!(dvb_ac3_desc->asvc_flag); + + *q++ = len; + *q++ = dvb_ac3_desc->component_type_flag << 7 | dvb_ac3_desc->bsid_flag << 6 | + dvb_ac3_desc->mainid_flag << 5 | dvb_ac3_desc->asvc_flag << 4; + + if (dvb_ac3_desc->component_type_flag) *q++ = dvb_ac3_desc->component_type; + if (dvb_ac3_desc->bsid_flag) *q++ = dvb_ac3_desc->bsid; + if (dvb_ac3_desc->mainid_flag) *q++ = dvb_ac3_desc->mainid; + if (dvb_ac3_desc->asvc_flag) *q++ = dvb_ac3_desc->asvc; + } else { + *q++=1; // 1 byte, all flags sets to 0 + *q++=0; // omit all fields... + } + } else if (codec_id == AV_CODEC_ID_EAC3) { + *q++=0x7a; // EAC3 descriptor see A038 DVB SI + *q++=1; // 1 byte, all flags sets to 0 + *q++=0; // omit all fields... + } } - if (st->codecpar->codec_id==AV_CODEC_ID_EAC3 && (ts->flags & MPEGTS_FLAG_SYSTEM_B)) { - *q++=0x7a; // EAC3 descriptor see A038 DVB SI - *q++=1; // 1 byte, all flags sets to 0 - *q++=0; // omit all fields... - } - if (st->codecpar->codec_id==AV_CODEC_ID_S302M) + if (codec_id == AV_CODEC_ID_S302M) put_registration_descriptor(&q, MKTAG('B', 'S', 'S', 'D')); - if (st->codecpar->codec_id==AV_CODEC_ID_OPUS) { + if (codec_id == AV_CODEC_ID_OPUS) { /* 6 bytes registration descriptor, 4 bytes Opus audio descriptor */ if (q - data > SECTION_LENGTH - 6 - 4) { err = 1; @@ -572,7 +603,7 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) char *next = lang->value; uint8_t *len_ptr; - *q++ = 0x0a; /* ISO 639 language descriptor */ + *q++ = ISO_639_LANGUAGE_DESCRIPTOR; len_ptr = q++; *len_ptr = 0; @@ -610,7 +641,7 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) const char default_language[] = "und"; const char *language = lang && strlen(lang->value) >= 3 ? lang->value : default_language; - if (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { + if (codec_id == AV_CODEC_ID_DVB_SUBTITLE) { uint8_t *len_ptr; int extradata_copied = 0; @@ -652,7 +683,7 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) } *len_ptr = q - len_ptr - 1; - } else if (st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT) { + } else if (codec_id == AV_CODEC_ID_DVB_TELETEXT) { uint8_t *len_ptr = NULL; int extradata_copied = 0; @@ -696,11 +727,11 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) } break; case AVMEDIA_TYPE_DATA: - if (st->codecpar->codec_id == AV_CODEC_ID_SMPTE_KLV) { + if (codec_id == AV_CODEC_ID_SMPTE_KLV) { put_registration_descriptor(&q, MKTAG('K', 'L', 'V', 'A')); - } else if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) { + } else if (codec_id == AV_CODEC_ID_TIMED_ID3) { const char *tag = "ID3 "; - *q++ = 0x26; /* metadata descriptor */ + *q++ = METADATA_DESCRIPTOR; *q++ = 13; put16(&q, 0xffff); /* metadata application format */ putbuf(&q, tag, strlen(tag)); @@ -802,9 +833,9 @@ invalid: return 0; } -static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) +static int64_t get_pcr(const MpegTSWrite *ts) { - return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + + return av_rescale(ts->total_size + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + ts->first_pcr; } @@ -812,13 +843,14 @@ static void write_packet(AVFormatContext *s, const uint8_t *packet) { MpegTSWrite *ts = s->priv_data; if (ts->m2ts_mode) { - int64_t pcr = get_pcr(s->priv_data, s->pb); + int64_t pcr = get_pcr(s->priv_data); uint32_t tp_extra_header = pcr % 0x3fffffff; tp_extra_header = AV_RB32(&tp_extra_header); avio_write(s->pb, (unsigned char *) &tp_extra_header, sizeof(tp_extra_header)); } avio_write(s->pb, packet, TS_PACKET_SIZE); + ts->total_size += TS_PACKET_SIZE; } static void section_write_packet(MpegTSSection *s, const uint8_t *packet) @@ -991,6 +1023,10 @@ static int mpegts_init(AVFormatContext *s) ts->sdt.write_packet = section_write_packet; ts->sdt.opaque = s; + ts->pkt = av_packet_alloc(); + if (!ts->pkt) + return AVERROR(ENOMEM); + /* assign pids to each stream */ for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; @@ -1070,7 +1106,6 @@ static int mpegts_init(AVFormatContext *s) } ts_st->payload_pts = AV_NOPTS_VALUE; ts_st->payload_dts = AV_NOPTS_VALUE; - ts_st->first_pts_check = 1; ts_st->cc = 15; ts_st->discontinuity = ts->flags & MPEGTS_FLAG_DISCONT; if (st->codecpar->codec_id == AV_CODEC_ID_AAC && @@ -1200,7 +1235,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) } /* PCR coded into 6 bytes */ - q += write_pcr_bits(q, get_pcr(ts, s->pb)); + q += write_pcr_bits(q, get_pcr(ts)); /* stuffing bytes */ memset(q, 0xFF, TS_PACKET_SIZE - (q - buf)); @@ -1287,7 +1322,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, while (payload_size > 0) { int64_t pcr = AV_NOPTS_VALUE; if (ts->mux_rate > 1) - pcr = get_pcr(ts, s->pb); + pcr = get_pcr(ts); else if (dts != AV_NOPTS_VALUE) pcr = (dts - delay) * 300; @@ -1298,7 +1333,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, write_pcr = 0; if (ts->mux_rate > 1) { /* Send PCR packets for all PCR streams if needed */ - pcr = get_pcr(ts, s->pb); + pcr = get_pcr(ts); if (pcr >= ts->next_pcr) { int64_t next_pcr = INT64_MAX; for (int i = 0; i < s->nb_streams; i++) { @@ -1312,7 +1347,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, ts_st2->last_pcr = FFMAX(pcr - ts_st2->pcr_period, ts_st2->last_pcr + ts_st2->pcr_period); if (st2 != st) { mpegts_insert_pcr_only(s, st2); - pcr = get_pcr(ts, s->pb); + pcr = get_pcr(ts); } else { write_pcr = 1; } @@ -1382,28 +1417,28 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, is_dvb_teletext = 0; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (st->codecpar->codec_id == AV_CODEC_ID_DIRAC) - *q++ = 0xfd; + *q++ = STREAM_ID_EXTENDED_STREAM_ID; else - *q++ = 0xe0; + *q++ = STREAM_ID_VIDEO_STREAM_0; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && (st->codecpar->codec_id == AV_CODEC_ID_MP2 || st->codecpar->codec_id == AV_CODEC_ID_MP3 || st->codecpar->codec_id == AV_CODEC_ID_AAC)) { - *q++ = 0xc0; + *q++ = STREAM_ID_AUDIO_STREAM_0; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AC3 && ts->m2ts_mode) { - *q++ = 0xfd; + *q++ = STREAM_ID_EXTENDED_STREAM_ID; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA && st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) { - *q++ = 0xbd; + *q++ = STREAM_ID_PRIVATE_STREAM_1; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { - *q++ = stream_id != -1 ? stream_id : 0xfc; + *q++ = stream_id != -1 ? stream_id : STREAM_ID_METADATA_STREAM; - if (stream_id == 0xbd) /* asynchronous KLV */ + if (stream_id == STREAM_ID_PRIVATE_STREAM_1) /* asynchronous KLV */ pts = dts = AV_NOPTS_VALUE; } else { - *q++ = 0xbd; + *q++ = STREAM_ID_PRIVATE_STREAM_1; if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) { if (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { is_dvb_subtitle = 1; @@ -1647,7 +1682,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) const int64_t max_audio_delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) / 2; int64_t dts = pkt->dts, pts = pkt->pts; int opus_samples = 0; - int side_data_size; + buffer_size_t side_data_size; uint8_t *side_data = NULL; int stream_id = -1; @@ -1658,17 +1693,22 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) stream_id = side_data[0]; if (ts->copyts < 1) { + if (!ts->first_dts_checked && dts != AV_NOPTS_VALUE) { + ts->first_pcr += dts * 300; + ts->first_dts_checked = 1; + } + if (pts != AV_NOPTS_VALUE) pts += delay; if (dts != AV_NOPTS_VALUE) dts += delay; } - if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) { - av_log(s, AV_LOG_ERROR, "first pts value must be set\n"); + if (!ts_st->first_timestamp_checked && (pts == AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE)) { + av_log(s, AV_LOG_ERROR, "first pts and dts value must be set\n"); return AVERROR_INVALIDDATA; } - ts_st->first_pts_check = 0; + ts_st->first_timestamp_checked = 1; if (st->codecpar->codec_id == AV_CODEC_ID_H264) { const uint8_t *p = buf, *buf_end = p + size; @@ -1710,30 +1750,30 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) } if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) { int ret; - AVPacket pkt2; + AVPacket *pkt2 = ts->pkt; if (!ts_st->amux) { av_log(s, AV_LOG_ERROR, "AAC bitstream not in ADTS format " "and extradata missing\n"); } else { - av_init_packet(&pkt2); - pkt2.data = pkt->data; - pkt2.size = pkt->size; - av_assert0(pkt->dts != AV_NOPTS_VALUE); - pkt2.dts = av_rescale_q(pkt->dts, st->time_base, ts_st->amux->streams[0]->time_base); + av_packet_unref(pkt2); + pkt2->data = pkt->data; + pkt2->size = pkt->size; + av_assert0(pkt->dts != AV_NOPTS_VALUE); + pkt2->dts = av_rescale_q(pkt->dts, st->time_base, ts_st->amux->streams[0]->time_base); - ret = avio_open_dyn_buf(&ts_st->amux->pb); - if (ret < 0) - return ret; + ret = avio_open_dyn_buf(&ts_st->amux->pb); + if (ret < 0) + return ret; - ret = av_write_frame(ts_st->amux, &pkt2); - if (ret < 0) { - ffio_free_dyn_buf(&ts_st->amux->pb); - return ret; - } - size = avio_close_dyn_buf(ts_st->amux->pb, &data); - ts_st->amux->pb = NULL; - buf = data; + ret = av_write_frame(ts_st->amux, pkt2); + if (ret < 0) { + ffio_free_dyn_buf(&ts_st->amux->pb); + return ret; + } + size = avio_close_dyn_buf(ts_st->amux->pb, &data); + ts_st->amux->pb = NULL; + buf = data; } } } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) { @@ -1779,7 +1819,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) /* Add Opus control header */ if ((AV_RB16(pkt->data) >> 5) != 0x3ff) { uint8_t *side_data; - int side_data_size; + buffer_size_t side_data_size; int i, n; int ctrl_header_size; int trim_start = 0, trim_end = 0; @@ -1841,6 +1881,63 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) * need to count the samples of that too! */ av_log(s, AV_LOG_WARNING, "Got MPEG-TS formatted Opus data, unhandled"); } + } else if (st->codecpar->codec_id == AV_CODEC_ID_AC3 && !ts_st->dvb_ac3_desc) { + AC3HeaderInfo *hdr = NULL; + + if (avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size) >= 0) { + uint8_t number_of_channels_flag; + uint8_t service_type_flag; + uint8_t full_service_flag = 1; + DVBAC3Descriptor *dvb_ac3_desc; + + dvb_ac3_desc = av_mallocz(sizeof(*dvb_ac3_desc)); + if (!dvb_ac3_desc) { + av_free(hdr); + return AVERROR(ENOMEM); + } + + service_type_flag = hdr->bitstream_mode; + switch (hdr->channel_mode) { + case AC3_CHMODE_DUALMONO: + number_of_channels_flag = 1; + break; + case AC3_CHMODE_MONO: + number_of_channels_flag = 0; + break; + case AC3_CHMODE_STEREO: + if (hdr->dolby_surround_mode == AC3_DSURMOD_ON) + number_of_channels_flag = 3; + else + number_of_channels_flag = 2; + break; + case AC3_CHMODE_3F: + case AC3_CHMODE_2F1R: + case AC3_CHMODE_3F1R: + case AC3_CHMODE_2F2R: + case AC3_CHMODE_3F2R: + number_of_channels_flag = 4; + break; + default: /* reserved */ + number_of_channels_flag = 7; + break; + } + + if (service_type_flag == 1 || service_type_flag == 4 || + (service_type_flag == 7 && !number_of_channels_flag)) + full_service_flag = 0; + + dvb_ac3_desc->component_type_flag = 1; + dvb_ac3_desc->component_type = (full_service_flag << 6) | + ((service_type_flag & 0x7) << 3) | + (number_of_channels_flag & 0x7); + dvb_ac3_desc->bsid_flag = 1; + dvb_ac3_desc->bsid = hdr->bitstream_id; + dvb_ac3_desc->mainid_flag = 0; + dvb_ac3_desc->asvc_flag = 0; + + ts_st->dvb_ac3_desc = dvb_ac3_desc; + } + av_free(hdr); } if (ts_st->payload_size && (ts_st->payload_size + size > ts->pes_payload_size || @@ -1928,10 +2025,13 @@ static void mpegts_deinit(AVFormatContext *s) MpegTSService *service; int i; + av_packet_free(&ts->pkt); + for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; MpegTSWriteStream *ts_st = st->priv_data; if (ts_st) { + av_freep(&ts_st->dvb_ac3_desc); av_freep(&ts_st->payload); if (ts_st->amux) { avformat_free_context(ts_st->amux); diff --git a/libavformat/mpjpegdec.c b/libavformat/mpjpegdec.c index df2880412..5fe00fd16 100644 --- a/libavformat/mpjpegdec.c +++ b/libavformat/mpjpegdec.c @@ -328,18 +328,18 @@ static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt) ret = av_get_packet(s->pb, pkt, size); } else { /* no size was given -- we read until the next boundary or end-of-file */ - int remaining = 0, len; + int len; const int read_chunk = 2048; pkt->pos = avio_tell(s->pb); - while ((ret = ffio_ensure_seekback(s->pb, read_chunk - remaining)) >= 0 && /* we may need to return as much as all we've read back to the buffer */ - (ret = av_append_packet(s->pb, pkt, read_chunk - remaining)) >= 0) { + while ((ret = ffio_ensure_seekback(s->pb, read_chunk)) >= 0 && /* we may need to return as much as all we've read back to the buffer */ + (ret = av_append_packet(s->pb, pkt, read_chunk)) >= 0) { /* scan the new data */ char *start; - len = ret + remaining; + len = ret; start = pkt->data + pkt->size - len; do { if (!memcmp(start, mpjpeg->searchstr, mpjpeg->searchstr_len)) { @@ -351,7 +351,8 @@ static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt) len--; start++; } while (len >= mpjpeg->searchstr_len); - remaining = len; + avio_seek(s->pb, -len, SEEK_CUR); + pkt->size -= len; } /* error or EOF occurred */ diff --git a/libavformat/mpl2dec.c b/libavformat/mpl2dec.c index bea258d9e..38445c7aa 100644 --- a/libavformat/mpl2dec.c +++ b/libavformat/mpl2dec.c @@ -83,7 +83,6 @@ static int mpl2_read_header(AVFormatContext *s) { MPL2Context *mpl2 = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - int res = 0; if (!st) return AVERROR(ENOMEM); @@ -122,7 +121,7 @@ static int mpl2_read_header(AVFormatContext *s) } ff_subtitles_queue_finalize(s, &mpl2->q); - return res; + return 0; } static int mpl2_read_packet(AVFormatContext *s, AVPacket *pkt) diff --git a/libavformat/mpsubdec.c b/libavformat/mpsubdec.c index 2e6dc883e..c113be5eb 100644 --- a/libavformat/mpsubdec.c +++ b/libavformat/mpsubdec.c @@ -147,8 +147,8 @@ static int mpsub_read_header(AVFormatContext *s) if (common_factor > 1) { common_factor = av_gcd(pts_info.num, common_factor); for (i = 0; i < mpsub->q.nb_subs; i++) { - mpsub->q.subs[i].pts /= common_factor; - mpsub->q.subs[i].duration /= common_factor; + mpsub->q.subs[i]->pts /= common_factor; + mpsub->q.subs[i]->duration /= common_factor; } pts_info.num /= common_factor; } diff --git a/libavformat/mspdec.c b/libavformat/mspdec.c new file mode 100644 index 000000000..4845eb372 --- /dev/null +++ b/libavformat/mspdec.c @@ -0,0 +1,117 @@ +/* + * Microsoft Paint (MSP) demuxer + * Copyright (c) 2020 Peter Ross (pross@xvid.org) + * + * 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 + * Microsoft Paint (MSP) demuxer + */ + +#include "libavutil/intreadwrite.h" +#include "libavutil/imgutils.h" +#include "avformat.h" +#include "internal.h" + +typedef struct { + int packet_size; +} MSPContext; + +static int msp_probe(const AVProbeData *p) +{ + unsigned int i, sum; + + if (p->buf_size <= 32 || (memcmp(p->buf, "DanM", 4) && memcmp(p->buf, "LinS", 4))) + return 0; + + sum = 0; + for (i = 0; i < 24; i += 2) + sum ^= AV_RL16(p->buf + i); + + return AV_RL16(p->buf + 24) == sum ? AVPROBE_SCORE_MAX : 0; +} + +static int msp_read_header(AVFormatContext *s) +{ + MSPContext * cntx = s->priv_data; + AVIOContext *pb = s->pb; + AVStream *st; + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = avio_rl32(pb) == MKTAG('D', 'a', 'n', 'M') ? AV_CODEC_ID_RAWVIDEO : AV_CODEC_ID_MSP2; + + st->codecpar->width = avio_rl16(pb); + st->codecpar->height = avio_rl16(pb); + st->codecpar->format = AV_PIX_FMT_MONOBLACK; + + st->sample_aspect_ratio.num = avio_rl16(pb); + st->sample_aspect_ratio.den = avio_rl16(pb); + avio_skip(pb, 20); + + if (st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) { + cntx->packet_size = av_image_get_buffer_size(st->codecpar->format, st->codecpar->width, st->codecpar->height, 1); + } else + cntx->packet_size = 2 * st->codecpar->height; + + if (cntx->packet_size <= 0) + return cntx->packet_size < 0 ? cntx->packet_size : AVERROR_INVALIDDATA; + + return 0; +} + +static int msp_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVStream *st = s->streams[0]; + MSPContext *cntx = s->priv_data; + int ret; + + ret = av_get_packet(s->pb, pkt, cntx->packet_size); + if (ret < 0) + return ret; + + if (st->codecpar->codec_id == AV_CODEC_ID_MSP2) { + unsigned int size, i; + if (pkt->size != 2 * st->codecpar->height) + return AVERROR_INVALIDDATA; + size = 0; + for (i = 0; i < st->codecpar->height; i++) + size += AV_RL16(&pkt->data[i * 2]); + ret = av_append_packet(s->pb, pkt, size); + if (ret < 0) + return ret; + } + + pkt->stream_index = 0; + pkt->flags |= AV_PKT_FLAG_KEY; + return 0; +} + +AVInputFormat ff_msp_demuxer = { + .name = "msp", + .long_name = NULL_IF_CONFIG_SMALL("Microsoft Paint (MSP))"), + .read_probe = msp_probe, + .read_header = msp_read_header, + .read_packet = msp_read_packet, + .flags = AVFMT_NOTIMESTAMPS, + .priv_data_size = sizeof(MSPContext), +}; diff --git a/libavformat/musx.c b/libavformat/musx.c index 8537eb7e7..9dd721182 100644 --- a/libavformat/musx.c +++ b/libavformat/musx.c @@ -20,12 +20,23 @@ */ #include "libavutil/avassert.h" +#include "libavutil/intreadwrite.h" #include "avformat.h" #include "internal.h" static int musx_probe(const AVProbeData *p) { - if (memcmp(p->buf, "MUSX", 4)) + unsigned version; + + if (AV_RB32(p->buf) != MKBETAG('M','U','S','X')) + return 0; + + version = AV_RL32(p->buf + 8); + if (version != 10 && + version != 6 && + version != 5 && + version != 4 && + version != 201) return 0; return AVPROBE_SCORE_MAX / 5 * 2; diff --git a/libavformat/mux.c b/libavformat/mux.c index 44d5e5d1c..6a557d294 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -22,6 +22,7 @@ #include "avformat.h" #include "internal.h" #include "libavcodec/internal.h" +#include "libavcodec/packet_internal.h" #include "libavutil/opt.h" #include "libavutil/dict.h" #include "libavutil/pixdesc.h" @@ -546,7 +547,7 @@ FF_DISABLE_DEPRECATION_WARNINGS static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *pkt) { int delay = FFMAX(st->codecpar->video_delay, st->internal->avctx->max_b_frames > 0); - int num, den, i; + int i; int frame_size; if (!s->internal->missing_ts_warning && @@ -564,20 +565,6 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket * av_log(s, AV_LOG_DEBUG, "compute_muxer_pkt_fields: pts:%s dts:%s cur_dts:%s b:%d size:%d st:%d\n", av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), delay, pkt->size, pkt->stream_index); - if (pkt->duration < 0 && st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) { - av_log(s, AV_LOG_WARNING, "Packet with invalid duration %"PRId64" in stream %d\n", - pkt->duration, pkt->stream_index); - pkt->duration = 0; - } - - /* duration field */ - if (pkt->duration == 0) { - ff_compute_frame_duration(s, &num, &den, st, NULL, pkt); - if (den && num) { - pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num); - } - } - if (pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && delay == 0) pkt->pts = pkt->dts; @@ -595,13 +582,13 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket * //calculate dts from pts if (pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY) { - st->pts_buffer[0] = pkt->pts; - for (i = 1; i < delay + 1 && st->pts_buffer[i] == AV_NOPTS_VALUE; i++) - st->pts_buffer[i] = pkt->pts + (i - delay - 1) * pkt->duration; - for (i = 0; ipts_buffer[i] > st->pts_buffer[i + 1]; i++) - FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]); + st->internal->pts_buffer[0] = pkt->pts; + for (i = 1; i < delay + 1 && st->internal->pts_buffer[i] == AV_NOPTS_VALUE; i++) + st->internal->pts_buffer[i] = pkt->pts + (i - delay - 1) * pkt->duration; + for (i = 0; iinternal->pts_buffer[i] > st->internal->pts_buffer[i + 1]; i++) + FFSWAP(int64_t, st->internal->pts_buffer[i], st->internal->pts_buffer[i + 1]); - pkt->dts = st->pts_buffer[0]; + pkt->dts = st->internal->pts_buffer[0]; } if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && @@ -652,6 +639,37 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket * FF_ENABLE_DEPRECATION_WARNINGS #endif +static void guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt) +{ + if (pkt->duration < 0 && st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) { + av_log(s, AV_LOG_WARNING, "Packet with invalid duration %"PRId64" in stream %d\n", + pkt->duration, pkt->stream_index); + pkt->duration = 0; + } + + if (pkt->duration) + return; + + switch (st->codecpar->codec_type) { + case AVMEDIA_TYPE_VIDEO: + if (st->avg_frame_rate.num > 0 && st->avg_frame_rate.den > 0) { + pkt->duration = av_rescale_q(1, av_inv_q(st->avg_frame_rate), + st->time_base); + } else if (st->time_base.num * 1000LL > st->time_base.den) + pkt->duration = 1; + break; + case AVMEDIA_TYPE_AUDIO: { + int frame_size = av_get_audio_frame_duration2(st->codecpar, pkt->size); + if (frame_size && st->codecpar->sample_rate) { + pkt->duration = av_rescale_q(frame_size, + (AVRational){1, st->codecpar->sample_rate}, + st->time_base); + } + break; + } + } +} + /** * Shift timestamps and call muxer; the original pts/dts are not kept. * @@ -678,7 +696,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) if (s->avoid_negative_ts > 0) { AVStream *st = s->streams[pkt->stream_index]; - int64_t offset = st->mux_ts_offset; + int64_t offset = st->internal->mux_ts_offset; int64_t ts = s->internal->avoid_negative_ts_use_pts ? pkt->pts : pkt->dts; if (s->internal->offset == AV_NOPTS_VALUE && ts != AV_NOPTS_VALUE && @@ -688,7 +706,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) } if (s->internal->offset != AV_NOPTS_VALUE && !offset) { - offset = st->mux_ts_offset = + offset = st->internal->mux_ts_offset = av_rescale_q_rnd(s->internal->offset, s->internal->offset_timebase, st->time_base, @@ -813,11 +831,11 @@ int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, int (*compare)(AVFormatContext *, const AVPacket *, const AVPacket *)) { int ret; - AVPacketList **next_point, *this_pktl; + PacketList **next_point, *this_pktl; AVStream *st = s->streams[pkt->stream_index]; int chunked = s->max_chunk_size || s->max_chunk_duration; - this_pktl = av_malloc(sizeof(AVPacketList)); + this_pktl = av_malloc(sizeof(PacketList)); if (!this_pktl) { av_packet_unref(pkt); return AVERROR(ENOMEM); @@ -831,27 +849,27 @@ int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, av_packet_move_ref(&this_pktl->pkt, pkt); pkt = &this_pktl->pkt; - if (st->last_in_packet_buffer) { - next_point = &(st->last_in_packet_buffer->next); + if (st->internal->last_in_packet_buffer) { + next_point = &(st->internal->last_in_packet_buffer->next); } else { next_point = &s->internal->packet_buffer; } if (chunked) { uint64_t max= av_rescale_q_rnd(s->max_chunk_duration, AV_TIME_BASE_Q, st->time_base, AV_ROUND_UP); - st->interleaver_chunk_size += pkt->size; - st->interleaver_chunk_duration += pkt->duration; - if ( (s->max_chunk_size && st->interleaver_chunk_size > s->max_chunk_size) - || (max && st->interleaver_chunk_duration > max)) { - st->interleaver_chunk_size = 0; + st->internal->interleaver_chunk_size += pkt->size; + st->internal->interleaver_chunk_duration += pkt->duration; + if ( (s->max_chunk_size && st->internal->interleaver_chunk_size > s->max_chunk_size) + || (max && st->internal->interleaver_chunk_duration > max)) { + st->internal->interleaver_chunk_size = 0; pkt->flags |= CHUNK_START; - if (max && st->interleaver_chunk_duration > max) { + if (max && st->internal->interleaver_chunk_duration > max) { int64_t syncoffset = (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)*max/2; int64_t syncto = av_rescale(pkt->dts + syncoffset, 1, max)*max - syncoffset; - st->interleaver_chunk_duration += (pkt->dts - syncto)/8 - max; + st->internal->interleaver_chunk_duration += (pkt->dts - syncto)/8 - max; } else - st->interleaver_chunk_duration = 0; + st->internal->interleaver_chunk_duration = 0; } } if (*next_point) { @@ -876,7 +894,7 @@ next_non_null: this_pktl->next = *next_point; - st->last_in_packet_buffer = *next_point = this_pktl; + st->internal->last_in_packet_buffer = *next_point = this_pktl; return 0; } @@ -914,7 +932,7 @@ static int interleave_compare_dts(AVFormatContext *s, const AVPacket *next, int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) { - AVPacketList *pktl; + PacketList *pktl; int stream_count = 0; int noninterleaved_count = 0; int i, ret; @@ -926,7 +944,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, } for (i = 0; i < s->nb_streams; i++) { - if (s->streams[i]->last_in_packet_buffer) { + if (s->streams[i]->internal->last_in_packet_buffer) { ++stream_count; } else if (s->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_ATTACHMENT && s->streams[i]->codecpar->codec_id != AV_CODEC_ID_VP8 && @@ -951,7 +969,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, for (i = 0; i < s->nb_streams; i++) { int64_t last_dts; - const AVPacketList *last = s->streams[i]->last_in_packet_buffer; + const PacketList *last = s->streams[i]->internal->last_in_packet_buffer; if (!last) continue; @@ -1000,8 +1018,8 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, if (!s->internal->packet_buffer) s->internal->packet_buffer_end = NULL; - if (st->last_in_packet_buffer == pktl) - st->last_in_packet_buffer = NULL; + if (st->internal->last_in_packet_buffer == pktl) + st->internal->last_in_packet_buffer = NULL; av_packet_unref(&pktl->pkt); av_freep(&pktl); @@ -1019,8 +1037,8 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, if (!s->internal->packet_buffer) s->internal->packet_buffer_end = NULL; - if (st->last_in_packet_buffer == pktl) - st->last_in_packet_buffer = NULL; + if (st->internal->last_in_packet_buffer == pktl) + st->internal->last_in_packet_buffer = NULL; av_freep(&pktl); return 1; @@ -1029,30 +1047,32 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, } } -int ff_interleaved_peek(AVFormatContext *s, int stream, - AVPacket *pkt, int add_offset) +int ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset) { - AVPacketList *pktl = s->internal->packet_buffer; + AVStream *st; + + if (stream_index < 0 || stream_index >= s->nb_streams) + return AVERROR(EINVAL); + + st = s->streams[stream_index]; + *offset = st->internal->mux_ts_offset; + + if (s->output_ts_offset) + *offset += av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, st->time_base); + + return 0; +} + +const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream) +{ + PacketList *pktl = s->internal->packet_buffer; while (pktl) { if (pktl->pkt.stream_index == stream) { - *pkt = pktl->pkt; - if (add_offset) { - AVStream *st = s->streams[pkt->stream_index]; - int64_t offset = st->mux_ts_offset; - - if (s->output_ts_offset) - offset += av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, st->time_base); - - if (pkt->dts != AV_NOPTS_VALUE) - pkt->dts += offset; - if (pkt->pts != AV_NOPTS_VALUE) - pkt->pts += offset; - } - return 0; + return &pktl->pkt; } pktl = pktl->next; } - return AVERROR(ENOENT); + return NULL; } /** @@ -1118,6 +1138,8 @@ static int write_packet_common(AVFormatContext *s, AVStream *st, AVPacket *pkt, av_log(s, AV_LOG_DEBUG, "%s size:%d dts:%s pts:%s\n", __FUNCTION__, pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts)); + guess_pkt_duration(s, st, pkt); + #if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX if ((ret = compute_muxer_pkt_fields(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) return ret; @@ -1189,7 +1211,7 @@ static int write_packets_common(AVFormatContext *s, AVPacket *pkt, int interleav int av_write_frame(AVFormatContext *s, AVPacket *in) { - AVPacket local_pkt, *pkt = &local_pkt; + AVPacket *pkt = s->internal->pkt; int ret; if (!in) { @@ -1210,6 +1232,7 @@ int av_write_frame(AVFormatContext *s, AVPacket *in) * The following avoids copying in's data unnecessarily. * Copying side data is unavoidable as a bitstream filter * may change it, e.g. free it on errors. */ + av_packet_unref(pkt); pkt->buf = NULL; pkt->data = in->data; pkt->size = in->size; @@ -1251,14 +1274,14 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) int av_write_trailer(AVFormatContext *s) { int i, ret1, ret = 0; - AVPacket pkt = {0}; - av_init_packet(&pkt); + AVPacket *pkt = s->internal->pkt; + av_packet_unref(pkt); for (i = 0; i < s->nb_streams; i++) { if (s->streams[i]->internal->bsfc) { - ret1 = write_packets_from_bsfs(s, s->streams[i], &pkt, 1/*interleaved*/); + ret1 = write_packets_from_bsfs(s, s->streams[i], pkt, 1/*interleaved*/); if (ret1 < 0) - av_packet_unref(&pkt); + av_packet_unref(pkt); if (ret >= 0) ret = ret1; } @@ -1332,7 +1355,7 @@ static void uncoded_frame_free(void *unused, uint8_t *data) static int write_uncoded_frame_internal(AVFormatContext *s, int stream_index, AVFrame *frame, int interleaved) { - AVPacket pkt, *pktp; + AVPacket *pkt = s->internal->pkt; av_assert0(s->oformat); if (!s->oformat->write_uncoded_frame) { @@ -1341,18 +1364,17 @@ static int write_uncoded_frame_internal(AVFormatContext *s, int stream_index, } if (!frame) { - pktp = NULL; + pkt = NULL; } else { size_t bufsize = sizeof(frame) + AV_INPUT_BUFFER_PADDING_SIZE; AVFrame **framep = av_mallocz(bufsize); if (!framep) goto fail; - pktp = &pkt; - av_init_packet(&pkt); - pkt.buf = av_buffer_create((void *)framep, bufsize, + av_packet_unref(pkt); + pkt->buf = av_buffer_create((void *)framep, bufsize, uncoded_frame_free, NULL, 0); - if (!pkt.buf) { + if (!pkt->buf) { av_free(framep); fail: av_frame_free(&frame); @@ -1360,17 +1382,17 @@ static int write_uncoded_frame_internal(AVFormatContext *s, int stream_index, } *framep = frame; - pkt.data = (void *)framep; - pkt.size = sizeof(frame); - pkt.pts = - pkt.dts = frame->pts; - pkt.duration = frame->pkt_duration; - pkt.stream_index = stream_index; - pkt.flags |= AV_PKT_FLAG_UNCODED_FRAME; + pkt->data = (void *)framep; + pkt->size = sizeof(frame); + pkt->pts = + pkt->dts = frame->pts; + pkt->duration = frame->pkt_duration; + pkt->stream_index = stream_index; + pkt->flags |= AV_PKT_FLAG_UNCODED_FRAME; } - return interleaved ? av_interleaved_write_frame(s, pktp) : - av_write_frame(s, pktp); + return interleaved ? av_interleaved_write_frame(s, pkt) : + av_write_frame(s, pkt); } int av_write_uncoded_frame(AVFormatContext *s, int stream_index, diff --git a/libavformat/mvdec.c b/libavformat/mvdec.c index 7d59d82b1..045c66ac3 100644 --- a/libavformat/mvdec.c +++ b/libavformat/mvdec.c @@ -213,10 +213,12 @@ static int parse_video_var(AVFormatContext *avctx, AVStream *st, st->codecpar->width = var_read_int(pb, size); } else if (!strcmp(name, "ORIENTATION")) { if (var_read_int(pb, size) == 1101) { - st->codecpar->extradata = av_strdup("BottomUp"); - if (!st->codecpar->extradata) - return AVERROR(ENOMEM); - st->codecpar->extradata_size = 9; + if (!st->codecpar->extradata) { + st->codecpar->extradata = av_strdup("BottomUp"); + if (!st->codecpar->extradata) + return AVERROR(ENOMEM); + st->codecpar->extradata_size = 9; + } } } else if (!strcmp(name, "Q_SPATIAL") || !strcmp(name, "Q_TEMPORAL")) { var_read_metadata(avctx, name, size); diff --git a/libavformat/mvi.c b/libavformat/mvi.c index 2d4b11aa3..cfdbe5d27 100644 --- a/libavformat/mvi.c +++ b/libavformat/mvi.c @@ -120,6 +120,10 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) mvi->video_frame_size = (mvi->get_int)(pb); if (mvi->audio_size_left == 0) return AVERROR(EIO); + if (mvi->audio_size_counter + 512 > UINT64_MAX - mvi->audio_frame_size || + mvi->audio_size_counter + 512 + mvi->audio_frame_size >= ((uint64_t)INT32_MAX) << MVI_FRAC_BITS) + return AVERROR_INVALIDDATA; + count = (mvi->audio_size_counter + mvi->audio_frame_size + 512) >> MVI_FRAC_BITS; if (count > mvi->audio_size_left) count = mvi->audio_size_left; diff --git a/libavformat/mxf.c b/libavformat/mxf.c index 7d154ca9d..85a65f871 100644 --- a/libavformat/mxf.c +++ b/libavformat/mxf.c @@ -22,6 +22,8 @@ #include "libavutil/common.h" #include "mxf.h" +const uint8_t ff_mxf_random_index_pack_key[16] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x11,0x01,0x00 }; + /** * SMPTE RP224 http://www.smpte-ra.org/mdd/index.html */ @@ -86,6 +88,55 @@ const MXFCodecUL ff_mxf_codec_tag_uls[] = { { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 0 }, }; +const MXFCodecUL ff_mxf_color_primaries_uls[] = { + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x01,0x00,0x00 }, 14, AVCOL_PRI_SMPTE170M }, /* SMPTE 170M */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x02,0x00,0x00 }, 14, AVCOL_PRI_BT470BG }, /* ITU-R BT.470 PAL */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x03,0x00,0x00 }, 14, AVCOL_PRI_BT709 }, /* ITU-R BT.709 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x04,0x00,0x00 }, 14, AVCOL_PRI_BT2020 }, /* ITU-R BT.2020 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x05,0x00,0x00 }, 14, AVCOL_PRI_SMPTE428 }, /* SMPTE-DC28 DCDM */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x06,0x00,0x00 }, 14, AVCOL_PRI_SMPTE432 }, /* P3D65 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x08,0x00,0x00 }, 14, AVCOL_PRI_SMPTE428 }, /* Cinema Mezzanine */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x0a,0x00,0x00 }, 14, AVCOL_PRI_SMPTE431 }, /* P3DCI */ + /* alternate mappings for encoding */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x01,0x00,0x00 }, 14, AVCOL_PRI_SMPTE240M }, /* = AVCOL_PRI_SMPTE170M */ + + { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVCOL_PRI_UNSPECIFIED }, +}; + +const MXFCodecUL ff_mxf_color_trc_uls[] = { + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x01,0x00,0x00 }, 14, AVCOL_TRC_GAMMA22 }, /* ITU-R BT.470 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00 }, 14, AVCOL_TRC_BT709 }, /* ITU-R BT.709 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x03,0x00,0x00 }, 14, AVCOL_TRC_SMPTE240M }, /* SMPTE 240M */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x04,0x00,0x00 }, 14, AVCOL_TRC_BT709 }, /* SMPTE 274/296M (must appear after ITU-R BT.709) */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x05,0x00,0x00 }, 14, AVCOL_TRC_BT1361_ECG }, /* ITU-R BT.1361 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x06,0x00,0x00 }, 14, AVCOL_TRC_LINEAR }, /* Linear */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x08,0x04,0x01,0x01,0x01,0x01,0x07,0x00,0x00 }, 14, AVCOL_TRC_SMPTE428 }, /* SMPTE-DC28 DCDM */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x08,0x00,0x00 }, 14, AVCOL_TRC_IEC61966_2_4 }, /* IEC 61966-2-4 xvYCC */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0E,0x04,0x01,0x01,0x01,0x01,0x09,0x00,0x00 }, 14, AVCOL_TRC_BT2020_10 }, /* ITU-R BT.2020 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x0A,0x00,0x00 }, 14, AVCOL_TRC_SMPTE2084 }, /* SMPTE ST 2084 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x0B,0x00,0x00 }, 14, AVCOL_TRC_ARIB_STD_B67 }, /* Hybrid Log-Gamma OETF */ + /* alternate mappings for encoding */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x01,0x00,0x00 }, 14, AVCOL_TRC_GAMMA28 }, /* = AVCOL_TRC_GAMMA22 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00 }, 14, AVCOL_TRC_SMPTE170M }, /* = AVCOL_TRC_BT709 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0E,0x04,0x01,0x01,0x01,0x01,0x09,0x00,0x00 }, 14, AVCOL_TRC_BT2020_12 }, /* = AVCOL_TRC_BT2020_10 */ + + { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVCOL_TRC_UNSPECIFIED }, +}; + +/* aka Coding Equations */ +const MXFCodecUL ff_mxf_color_space_uls[] = { + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x02,0x01,0x00,0x00 }, 14, AVCOL_SPC_BT470BG }, /* ITU-R BT.601 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x02,0x02,0x00,0x00 }, 14, AVCOL_SPC_BT709 }, /* ITU-R BT.709 */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x02,0x03,0x00,0x00 }, 14, AVCOL_SPC_SMPTE240M }, /* SMPTE 240M */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x02,0x04,0x00,0x00 }, 14, AVCOL_SPC_YCGCO }, /* YCgCo */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x02,0x05,0x00,0x00 }, 14, AVCOL_SPC_RGB }, /* GBR */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x02,0x06,0x00,0x00 }, 14, AVCOL_SPC_BT2020_NCL }, /* ITU-R BT.2020 Non-Constant Luminance */ + /* alternate mappings for encoding */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x02,0x03,0x00,0x00 }, 14, AVCOL_SPC_SMPTE170M }, /* = AVCOL_SPC_SMPTE240M */ + + { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVCOL_SPC_UNSPECIFIED }, +}; + static const struct { enum AVPixelFormat pix_fmt; const char data[16]; diff --git a/libavformat/mxf.h b/libavformat/mxf.h index f2fff2781..b1b1fedac 100644 --- a/libavformat/mxf.h +++ b/libavformat/mxf.h @@ -78,6 +78,22 @@ typedef enum { RawVWrap } MXFWrappingIndicatorType; +typedef struct MXFLocalTagPair { + int local_tag; + UID uid; +} MXFLocalTagPair; + +extern const uint8_t ff_mxf_random_index_pack_key[16]; + +#define FF_MXF_MasteringDisplay_PREFIX 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01 +#define FF_MXF_MasteringDisplayPrimaries { FF_MXF_MasteringDisplay_PREFIX,0x01,0x00,0x00 } +#define FF_MXF_MasteringDisplayWhitePointChromaticity { FF_MXF_MasteringDisplay_PREFIX,0x02,0x00,0x00 } +#define FF_MXF_MasteringDisplayMaximumLuminance { FF_MXF_MasteringDisplay_PREFIX,0x03,0x00,0x00 } +#define FF_MXF_MasteringDisplayMinimumLuminance { FF_MXF_MasteringDisplay_PREFIX,0x04,0x00,0x00 } + +#define FF_MXF_MASTERING_CHROMA_DEN 50000 +#define FF_MXF_MASTERING_LUMA_DEN 10000 + typedef struct MXFCodecUL { UID uid; unsigned matching_len; @@ -91,6 +107,9 @@ extern const MXFCodecUL ff_mxf_data_definition_uls[]; extern const MXFCodecUL ff_mxf_codec_uls[]; extern const MXFCodecUL ff_mxf_pixel_format_uls[]; extern const MXFCodecUL ff_mxf_codec_tag_uls[]; +extern const MXFCodecUL ff_mxf_color_primaries_uls[]; +extern const MXFCodecUL ff_mxf_color_trc_uls[]; +extern const MXFCodecUL ff_mxf_color_space_uls[]; int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt); int ff_mxf_get_content_package_rate(AVRational time_base); diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index ebbbbea2f..1f372affc 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -28,6 +28,7 @@ * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container + * SMPTE 2067-21 Interoperable Master Format — Application #2E * * Principle * Search for Track numbers which will identify essence element KLV packets. @@ -47,6 +48,7 @@ #include "libavutil/aes.h" #include "libavutil/avassert.h" +#include "libavutil/mastering_display_metadata.h" #include "libavutil/mathematics.h" #include "libavcodec/bytestream.h" #include "libavutil/intreadwrite.h" @@ -199,6 +201,9 @@ typedef struct MXFDescriptor { int bits_per_sample; int64_t duration; /* ContainerDuration optional property */ unsigned int component_depth; + unsigned int black_ref_level; + unsigned int white_ref_level; + unsigned int color_range; unsigned int horiz_subsampling; unsigned int vert_subsampling; UID *sub_descriptors_refs; @@ -207,6 +212,12 @@ typedef struct MXFDescriptor { uint8_t *extradata; int extradata_size; enum AVPixelFormat pix_fmt; + UID color_primaries_ul; + UID color_trc_ul; + UID color_space_ul; + AVMasteringDisplayMetadata *mastering; + AVContentLightMetadata *coll; + size_t coll_size; } MXFDescriptor; typedef struct MXFIndexTableSegment { @@ -312,16 +323,26 @@ static const uint8_t mxf_canopus_essence_element_key[] = { 0x06,0x0e,0x2b,0x static const uint8_t mxf_system_item_key_cp[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x03,0x01,0x04 }; static const uint8_t mxf_system_item_key_gc[] = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 }; static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 }; +static const uint8_t mxf_apple_coll_prefix[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01 }; /* complete keys to match */ static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 }; static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 }; -static const uint8_t mxf_random_index_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x11,0x01,0x00 }; static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 }; static const uint8_t mxf_avid_project_name[] = { 0xa5,0xfb,0x7b,0x25,0xf6,0x15,0x94,0xb9,0x62,0xfc,0x37,0x17,0x49,0x2d,0x42,0xbf }; static const uint8_t mxf_jp2k_rsiz[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; static const uint8_t mxf_indirect_value_utf16le[] = { 0x4c,0x00,0x02,0x10,0x01,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 }; static const uint8_t mxf_indirect_value_utf16be[] = { 0x42,0x01,0x10,0x02,0x00,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 }; +static const uint8_t mxf_apple_coll_max_cll[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x01 }; +static const uint8_t mxf_apple_coll_max_fall[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x02 }; + +static const uint8_t mxf_mastering_display_prefix[13] = { FF_MXF_MasteringDisplay_PREFIX }; +static const uint8_t mxf_mastering_display_uls[4][16] = { + FF_MXF_MasteringDisplayPrimaries, + FF_MXF_MasteringDisplayWhitePointChromaticity, + FF_MXF_MasteringDisplayMaximumLuminance, + FF_MXF_MasteringDisplayMinimumLuminance, +}; #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) @@ -332,6 +353,8 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx) case Descriptor: case MultipleDescriptor: av_freep(&((MXFDescriptor *)*ctx)->extradata); + av_freep(&((MXFDescriptor *)*ctx)->mastering); + av_freep(&((MXFDescriptor *)*ctx)->coll); av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs); break; case Sequence: @@ -821,15 +844,17 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size return 0; } -static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set) +static int mxf_add_metadata_set(MXFContext *mxf, MXFMetadataSet **metadata_set) { MXFMetadataSet **tmp; tmp = av_realloc_array(mxf->metadata_sets, mxf->metadata_sets_count + 1, sizeof(*mxf->metadata_sets)); - if (!tmp) + if (!tmp) { + mxf_free_metadataset(metadata_set, 1); return AVERROR(ENOMEM); + } mxf->metadata_sets = tmp; - mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set; + mxf->metadata_sets[mxf->metadata_sets_count] = *metadata_set; mxf->metadata_sets_count++; return 0; } @@ -847,6 +872,7 @@ static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, i static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count) { *count = avio_rb32(pb); + av_free(*refs); *refs = av_calloc(*count, sizeof(UID)); if (!*refs) { *count = 0; @@ -900,10 +926,8 @@ static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int siz case 0x1901: if (mxf->packages_refs) av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple packages_refs\n"); - av_free(mxf->packages_refs); return mxf_read_strong_ref_array(pb, &mxf->packages_refs, &mxf->packages_count); case 0x1902: - av_free(mxf->essence_container_data_refs); return mxf_read_strong_ref_array(pb, &mxf->essence_container_data_refs, &mxf->essence_container_data_count); } return 0; @@ -1070,9 +1094,9 @@ static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *seg if(segment->nb_index_entries && length < 11) return AVERROR_INVALIDDATA; - if (!(segment->temporal_offset_entries=av_calloc(segment->nb_index_entries, sizeof(*segment->temporal_offset_entries))) || - !(segment->flag_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->flag_entries))) || - !(segment->stream_offset_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->stream_offset_entries)))) { + if (!FF_ALLOC_TYPED_ARRAY(segment->temporal_offset_entries, segment->nb_index_entries) || + !FF_ALLOC_TYPED_ARRAY(segment->flag_entries , segment->nb_index_entries) || + !FF_ALLOC_TYPED_ARRAY(segment->stream_offset_entries , segment->nb_index_entries)) { av_freep(&segment->temporal_offset_entries); av_freep(&segment->flag_entries); return AVERROR(ENOMEM); @@ -1199,15 +1223,33 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int descriptor->aspect_ratio.num = avio_rb32(pb); descriptor->aspect_ratio.den = avio_rb32(pb); break; + case 0x3210: + avio_read(pb, descriptor->color_trc_ul, 16); + break; case 0x3212: descriptor->field_dominance = avio_r8(pb); break; + case 0x3219: + avio_read(pb, descriptor->color_primaries_ul, 16); + break; + case 0x321A: + avio_read(pb, descriptor->color_space_ul, 16); + break; case 0x3301: descriptor->component_depth = avio_rb32(pb); break; case 0x3302: descriptor->horiz_subsampling = avio_rb32(pb); break; + case 0x3304: + descriptor->black_ref_level = avio_rb32(pb); + break; + case 0x3305: + descriptor->white_ref_level = avio_rb32(pb); + break; + case 0x3306: + descriptor->color_range = avio_rb32(pb); + break; case 0x3308: descriptor->vert_subsampling = avio_rb32(pb); break; @@ -1246,6 +1288,55 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int rsiz == FF_PROFILE_JPEG2000_DCINEMA_4K) descriptor->pix_fmt = AV_PIX_FMT_XYZ12; } + if (IS_KLV_KEY(uid, mxf_mastering_display_prefix)) { + if (!descriptor->mastering) { + descriptor->mastering = av_mastering_display_metadata_alloc(); + if (!descriptor->mastering) + return AVERROR(ENOMEM); + } + if (IS_KLV_KEY(uid, mxf_mastering_display_uls[0])) { + for (int i = 0; i < 3; i++) { + /* Order: large x, large y, other (i.e. RGB) */ + descriptor->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN); + descriptor->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN); + } + /* Check we have seen mxf_mastering_display_white_point_chromaticity */ + if (descriptor->mastering->white_point[0].den != 0) + descriptor->mastering->has_primaries = 1; + } + if (IS_KLV_KEY(uid, mxf_mastering_display_uls[1])) { + descriptor->mastering->white_point[0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN); + descriptor->mastering->white_point[1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN); + /* Check we have seen mxf_mastering_display_primaries */ + if (descriptor->mastering->display_primaries[0][0].den != 0) + descriptor->mastering->has_primaries = 1; + } + if (IS_KLV_KEY(uid, mxf_mastering_display_uls[2])) { + descriptor->mastering->max_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN); + /* Check we have seen mxf_mastering_display_minimum_luminance */ + if (descriptor->mastering->min_luminance.den != 0) + descriptor->mastering->has_luminance = 1; + } + if (IS_KLV_KEY(uid, mxf_mastering_display_uls[3])) { + descriptor->mastering->min_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN); + /* Check we have seen mxf_mastering_display_maximum_luminance */ + if (descriptor->mastering->max_luminance.den != 0) + descriptor->mastering->has_luminance = 1; + } + } + if (IS_KLV_KEY(uid, mxf_apple_coll_prefix)) { + if (!descriptor->coll) { + descriptor->coll = av_content_light_metadata_alloc(&descriptor->coll_size); + if (!descriptor->coll) + return AVERROR(ENOMEM); + } + if (IS_KLV_KEY(uid, mxf_apple_coll_max_cll)) { + descriptor->coll->MaxCLL = avio_rb16(pb); + } + if (IS_KLV_KEY(uid, mxf_apple_coll_max_fall)) { + descriptor->coll->MaxFALL = avio_rb16(pb); + } + } break; } return 0; @@ -1887,6 +1978,15 @@ static int mxf_umid_to_str(UID ul, UID uid, char **str) return 0; } +static int mxf_version_to_str(uint16_t major, uint16_t minor, uint16_t tertiary, + uint16_t patch, uint16_t release, char **str) +{ + *str = av_asprintf("%d.%d.%d.%d.%d", major, minor, tertiary, patch, release); + if (!*str) + return AVERROR(ENOMEM); + return 0; +} + static int mxf_add_umid_metadata(AVDictionary **pm, const char *key, MXFPackage* package) { char *str; @@ -2143,6 +2243,30 @@ static int mxf_add_metadata_stream(MXFContext *mxf, MXFTrack *track) return 0; } +static enum AVColorRange mxf_get_color_range(MXFContext *mxf, MXFDescriptor *descriptor) +{ + if (descriptor->black_ref_level || descriptor->white_ref_level || descriptor->color_range) { + /* CDCI range metadata */ + if (!descriptor->component_depth) + return AVCOL_RANGE_UNSPECIFIED; + if (descriptor->black_ref_level == 0 && + descriptor->white_ref_level == ((1<component_depth) - 1) && + (descriptor->color_range == (1<component_depth) || + descriptor->color_range == ((1<component_depth) - 1))) + return AVCOL_RANGE_JPEG; + if (descriptor->component_depth >= 8 && + descriptor->black_ref_level == (1 <<(descriptor->component_depth - 4)) && + descriptor->white_ref_level == (235<<(descriptor->component_depth - 8)) && + descriptor->color_range == ((14<<(descriptor->component_depth - 4)) + 1)) + return AVCOL_RANGE_MPEG; + avpriv_request_sample(mxf->fc, "Unrecognized CDCI color range (color diff range %d, b %d, w %d, depth %d)", + descriptor->color_range, descriptor->black_ref_level, + descriptor->white_ref_level, descriptor->component_depth); + } + + return AVCOL_RANGE_UNSPECIFIED; +} + static int mxf_parse_structural_metadata(MXFContext *mxf) { MXFPackage *material_package = NULL; @@ -2477,7 +2601,27 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) av_dict_set_int(&st->metadata, "source_track_origin", source_track->sequence->origin, 0); } if (descriptor->aspect_ratio.num && descriptor->aspect_ratio.den) - st->display_aspect_ratio = descriptor->aspect_ratio; + st->internal->display_aspect_ratio = descriptor->aspect_ratio; + st->codecpar->color_range = mxf_get_color_range(mxf, descriptor); + st->codecpar->color_primaries = mxf_get_codec_ul(ff_mxf_color_primaries_uls, &descriptor->color_primaries_ul)->id; + st->codecpar->color_trc = mxf_get_codec_ul(ff_mxf_color_trc_uls, &descriptor->color_trc_ul)->id; + st->codecpar->color_space = mxf_get_codec_ul(ff_mxf_color_space_uls, &descriptor->color_space_ul)->id; + if (descriptor->mastering) { + ret = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, + (uint8_t *)descriptor->mastering, + sizeof(*descriptor->mastering)); + if (ret < 0) + goto fail_and_free; + descriptor->mastering = NULL; + } + if (descriptor->coll) { + ret = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL, + (uint8_t *)descriptor->coll, + descriptor->coll_size); + if (ret < 0) + goto fail_and_free; + descriptor->coll = NULL; + } } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul); /* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */ @@ -2604,6 +2748,17 @@ static int64_t mxf_timestamp_to_int64(uint64_t timestamp) av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \ } while (0) +#define SET_VERSION_METADATA(pb, name, major, minor, tertiary, patch, release, str) do { \ + major = avio_rb16(pb); \ + minor = avio_rb16(pb); \ + tertiary = avio_rb16(pb); \ + patch = avio_rb16(pb); \ + release = avio_rb16(pb); \ + if ((ret = mxf_version_to_str(major, minor, tertiary, patch, release, &str)) < 0) \ + return ret; \ + av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \ +} while (0) + #define SET_UID_METADATA(pb, name, var, str) do { \ avio_read(pb, var, 16); \ if ((ret = mxf_uid_to_str(var, &str)) < 0) \ @@ -2625,6 +2780,7 @@ static int mxf_read_identification_metadata(void *arg, AVIOContext *pb, int tag, UID uid = { 0 }; char *str = NULL; uint64_t ts; + uint16_t major, minor, tertiary, patch, release; switch (tag) { case 0x3C01: SET_STR_METADATA(pb, "company_name", str); @@ -2632,6 +2788,9 @@ static int mxf_read_identification_metadata(void *arg, AVIOContext *pb, int tag, case 0x3C02: SET_STR_METADATA(pb, "product_name", str); break; + case 0x3C03: + SET_VERSION_METADATA(pb, "product_version_num", major, minor, tertiary, patch, release, str); + break; case 0x3C04: SET_STR_METADATA(pb, "product_version", str); break; @@ -2641,6 +2800,9 @@ static int mxf_read_identification_metadata(void *arg, AVIOContext *pb, int tag, case 0x3C06: SET_TS_METADATA(pb, "modification_date", ts, str); break; + case 0x3C07: + SET_VERSION_METADATA(pb, "toolkit_version_num", major, minor, tertiary, patch, release, str); + break; case 0x3C08: SET_STR_METADATA(pb, "application_platform", str); break; @@ -2711,6 +2873,7 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType type) { + ctx->type = type; switch (type){ case MultipleDescriptor: case Descriptor: @@ -2726,20 +2889,32 @@ static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType typ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadFunc *read_child, int ctx_size, enum MXFMetadataSetType type) { AVIOContext *pb = mxf->fc->pb; - MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf; uint64_t klv_end = avio_tell(pb) + klv->length; + MXFMetadataSet *meta; + void *ctx; - if (!ctx) - return AVERROR(ENOMEM); - mxf_metadataset_init(ctx, type); + if (ctx_size) { + meta = av_mallocz(ctx_size); + if (!meta) + return AVERROR(ENOMEM); + ctx = meta; + mxf_metadataset_init(meta, type); + } else { + meta = NULL; + ctx = mxf; + } while (avio_tell(pb) + 4 < klv_end && !avio_feof(pb)) { int ret; int tag = avio_rb16(pb); int size = avio_rb16(pb); /* KLV specified by 0x53 */ int64_t next = avio_tell(pb); UID uid = {0}; - if (next < 0 || next > INT64_MAX - size) + if (next < 0 || next > INT64_MAX - size) { + if (meta) { + mxf_free_metadataset(&meta, 1); + } return next < 0 ? next : AVERROR_INVALIDDATA; + } next += size; av_log(mxf->fc, AV_LOG_TRACE, "local tag %#04x size %d\n", tag, size); @@ -2758,20 +2933,20 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF } } } - if (ctx_size && tag == 0x3C0A) { - avio_read(pb, ctx->uid, 16); + if (meta && tag == 0x3C0A) { + avio_read(pb, meta->uid, 16); } else if ((ret = read_child(ctx, pb, tag, size, uid, -1)) < 0) { - if (ctx_size) - mxf_free_metadataset(&ctx, 1); + if (meta) { + mxf_free_metadataset(&meta, 1); + } return ret; } /* Accept the 64k local set limit being exceeded (Avid). Don't accept * it extending past the end of the KLV though (zzuf5.mxf). */ if (avio_tell(pb) > klv_end) { - if (ctx_size) { - ctx->type = type; - mxf_free_metadataset(&ctx, 1); + if (meta) { + mxf_free_metadataset(&meta, 1); } av_log(mxf->fc, AV_LOG_ERROR, @@ -2781,8 +2956,7 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF } else if (avio_tell(pb) <= next) /* only seek forward, else this can loop for a long time */ avio_seek(pb, next, SEEK_SET); } - if (ctx_size) ctx->type = type; - return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0; + return meta ? mxf_add_metadata_set(mxf, &meta) : 0; } /** @@ -3085,10 +3259,8 @@ static int mxf_handle_missing_index_segment(MXFContext *mxf, AVStream *st) if (!(segment = av_mallocz(sizeof(*segment)))) return AVERROR(ENOMEM); - if ((ret = mxf_add_metadata_set(mxf, segment))) { - mxf_free_metadataset((MXFMetadataSet**)&segment, 1); + if ((ret = mxf_add_metadata_set(mxf, (MXFMetadataSet**)&segment))) return ret; - } /* Make sure we have nonzero unique index_sid, body_sid will be ok, because * using the same SID for index is forbidden in MXF. */ @@ -3140,7 +3312,7 @@ static void mxf_read_random_index_pack(AVFormatContext *s) goto end; avio_seek(s->pb, file_size - length, SEEK_SET); if (klv_read_packet(&klv, s->pb) < 0 || - !IS_KLV_KEY(klv.key, mxf_random_index_pack_key)) + !IS_KLV_KEY(klv.key, ff_mxf_random_index_pack_key)) goto end; if (klv.next_klv != file_size || klv.length <= 4 || (klv.length - 4) % 12) { av_log(s, AV_LOG_WARNING, "Invalid RIP KLV length\n"); @@ -3603,7 +3775,7 @@ static int mxf_probe(const AVProbeData *p) { AV_RN32(bufp+ 4) == AV_RN32(mxf_header_partition_pack_key+ 4) && AV_RN32(bufp+ 8) == AV_RN32(mxf_header_partition_pack_key+ 8) && AV_RN16(bufp+12) == AV_RN16(mxf_header_partition_pack_key+12)) - return AVPROBE_SCORE_MAX; + return bufp == p->buf ? AVPROBE_SCORE_MAX : AVPROBE_SCORE_MAX - 1; bufp ++; } else bufp += 10; diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 5a3a609bf..7a16bf915 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -44,6 +44,7 @@ #include "libavutil/random_seed.h" #include "libavutil/timecode.h" #include "libavutil/avassert.h" +#include "libavutil/mastering_display_metadata.h" #include "libavutil/pixdesc.h" #include "libavutil/time_internal.h" #include "libavcodec/bytestream.h" @@ -52,6 +53,7 @@ #include "libavcodec/h264_ps.h" #include "libavcodec/golomb.h" #include "libavcodec/internal.h" +#include "libavcodec/packet_internal.h" #include "avformat.h" #include "avio_internal.h" #include "internal.h" @@ -65,11 +67,6 @@ extern AVOutputFormat ff_mxf_opatom_muxer; #define EDIT_UNITS_PER_BODY 250 #define KAG_SIZE 512 -typedef struct MXFLocalTagPair { - int local_tag; - UID uid; -} MXFLocalTagPair; - typedef struct MXFIndexEntry { uint64_t offset; unsigned slice_offset; ///< offset of audio slice @@ -232,38 +229,6 @@ static const UID mxf_d10_container_uls[] = { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 }, // D-10 525/50 NTSC 30mb/s }; -typedef struct MXFContext { - AVClass *av_class; - int64_t footer_partition_offset; - int essence_container_count; - AVRational time_base; - int header_written; - MXFIndexEntry *index_entries; - unsigned edit_units_count; - uint64_t timestamp; ///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8) - uint8_t slice_count; ///< index slice count minus 1 (1 if no audio, 0 otherwise) - int last_indexed_edit_unit; - uint64_t *body_partition_offset; - unsigned body_partitions_count; - int last_key_index; ///< index of last key frame - uint64_t duration; - AVTimecode tc; ///< timecode context - AVStream *timecode_track; - int timecode_base; ///< rounded time code base (25 or 30) - int edit_unit_byte_count; ///< fixed edit unit byte count - int content_package_rate; ///< content package rate in system element, see SMPTE 326M - uint64_t body_offset; - uint32_t instance_number; - uint8_t umid[16]; ///< unique material identifier - int channel_count; - int signal_standard; - uint32_t tagged_value_count; - AVRational audio_edit_rate; - int store_user_comments; - int track_instance_count; // used to generate MXFTrack uuids - int cbr_index; ///< use a constant bitrate index -} MXFContext; - static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd }; static const uint8_t umid_ul[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 }; @@ -275,7 +240,6 @@ static const uint8_t opatom_ul[] = { 0x06,0x0E,0x2B,0x34,0x04, static const uint8_t footer_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete static const uint8_t primer_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }; static const uint8_t index_table_segment_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 }; -static const uint8_t random_index_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x11,0x01,0x00 }; static const uint8_t header_open_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; // OpenIncomplete static const uint8_t header_closed_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; // ClosedComplete static const uint8_t klv_fill_key[] = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 }; @@ -366,6 +330,8 @@ static const MXFLocalTagPair mxf_local_tag_batch[] = { { 0x3217, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x03,0x02,0x07,0x00,0x00,0x00}}, /* Display F2 offset */ { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */ { 0x3210, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x02,0x01,0x01,0x01,0x02,0x00}}, /* Transfer characteristic */ + { 0x321A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x02,0x01,0x01,0x03,0x01,0x00}}, /* Coding Equations (color space) */ + { 0x3219, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x09,0x04,0x01,0x02,0x01,0x01,0x06,0x01,0x00}}, /* Color Primaries */ { 0x3213, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x02,0x00,0x00,0x00,0x00}}, /* Image Start Offset */ { 0x3214, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Image End Offset */ { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */ @@ -406,20 +372,56 @@ static const MXFLocalTagPair mxf_local_tag_batch[] = { // Wave Audio Essence Descriptor { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, /* Average Bytes Per Second */ { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Block Align */ -}; - -static const MXFLocalTagPair mxf_avc_subdescriptor_local_tags[] = { + // mxf_user_comments_local_tag + { 0x4406, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0C,0x00,0x00,0x00}}, /* User Comments */ + { 0x5001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x09,0x01,0x00,0x00}}, /* Name */ + { 0x5003, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0A,0x01,0x00,0x00}}, /* Value */ + // mxf_avc_subdescriptor_local_tags { 0x8100, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00}}, /* SubDescriptors */ { 0x8200, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x06,0x01,0x0E,0x00,0x00}}, /* AVC Decoding Delay */ { 0x8201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x06,0x01,0x0A,0x00,0x00}}, /* AVC Profile */ { 0x8202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x06,0x01,0x0D,0x00,0x00}}, /* AVC Level */ + // ff_mxf_mastering_display_local_tags + { 0x8301, FF_MXF_MasteringDisplayPrimaries }, + { 0x8302, FF_MXF_MasteringDisplayWhitePointChromaticity }, + { 0x8303, FF_MXF_MasteringDisplayMaximumLuminance }, + { 0x8304, FF_MXF_MasteringDisplayMinimumLuminance }, }; -static const MXFLocalTagPair mxf_user_comments_local_tag[] = { - { 0x4406, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0C,0x00,0x00,0x00}}, /* User Comments */ - { 0x5001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x09,0x01,0x00,0x00}}, /* Name */ - { 0x5003, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0A,0x01,0x00,0x00}}, /* Value */ -}; +#define MXF_NUM_TAGS FF_ARRAY_ELEMS(mxf_local_tag_batch) + +typedef struct MXFContext { + AVClass *av_class; + int64_t footer_partition_offset; + int essence_container_count; + AVRational time_base; + int header_written; + MXFIndexEntry *index_entries; + unsigned edit_units_count; + uint64_t timestamp; ///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8) + uint8_t slice_count; ///< index slice count minus 1 (1 if no audio, 0 otherwise) + int last_indexed_edit_unit; + uint64_t *body_partition_offset; + unsigned body_partitions_count; + int last_key_index; ///< index of last key frame + uint64_t duration; + AVTimecode tc; ///< timecode context + AVStream *timecode_track; + int timecode_base; ///< rounded time code base (25 or 30) + int edit_unit_byte_count; ///< fixed edit unit byte count + int content_package_rate; ///< content package rate in system element, see SMPTE 326M + uint64_t body_offset; + uint32_t instance_number; + uint8_t umid[16]; ///< unique material identifier + int channel_count; + int signal_standard; + uint32_t tagged_value_count; + AVRational audio_edit_rate; + int store_user_comments; + int track_instance_count; // used to generate MXFTrack uuids + int cbr_index; ///< use a constant bitrate index + uint8_t unused_tags[MXF_NUM_TAGS]; ///< local tags that we know will not be used +} MXFContext; static void mxf_write_uuid(AVIOContext *pb, enum MXFMetadataSetType type, int value) { @@ -495,30 +497,64 @@ static int mxf_get_essence_container_ul_index(enum AVCodecID id) return -1; } -static void mxf_write_local_tags(AVIOContext *pb, const MXFLocalTagPair *local_tags, int count) +static const MXFLocalTagPair* mxf_lookup_local_tag(int tag) { - int i; - for (i = 0; i < count; i++) { - avio_wb16(pb, local_tags[i].local_tag); - avio_write(pb, local_tags[i].uid, 16); + for (int i = 0; i < MXF_NUM_TAGS; i++) { + if (mxf_local_tag_batch[i].local_tag == tag) { + return &mxf_local_tag_batch[i]; + } } + + // this assert can only be hit during development + av_assert0(0 && "you forgot to add your new tag to mxf_local_tag_batch"); +} + +static void mxf_mark_tag_unused(MXFContext *mxf, int tag) +{ + const MXFLocalTagPair *pair = mxf_lookup_local_tag(tag); + mxf->unused_tags[pair - mxf_local_tag_batch] = 1; } static void mxf_write_primer_pack(AVFormatContext *s) { MXFContext *mxf = s->priv_data; AVIOContext *pb = s->pb; - int local_tag_number, i = 0; - int avc_tags_count = 0; - - local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch); - local_tag_number += mxf->store_user_comments * FF_ARRAY_ELEMS(mxf_user_comments_local_tag); + int local_tag_number = MXF_NUM_TAGS, i; + int will_have_avc_tags = 0, will_have_mastering_tags = 0; for (i = 0; i < s->nb_streams; i++) { MXFStreamContext *sc = s->streams[i]->priv_data; if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_H264 && !sc->avc_intra) { - avc_tags_count = FF_ARRAY_ELEMS(mxf_avc_subdescriptor_local_tags); - local_tag_number += avc_tags_count; + will_have_avc_tags = 1; + } + if (av_stream_get_side_data(s->streams[i], AV_PKT_DATA_MASTERING_DISPLAY_METADATA, NULL)) { + will_have_mastering_tags = 1; + } + } + + if (!mxf->store_user_comments) { + mxf_mark_tag_unused(mxf, 0x4406); + mxf_mark_tag_unused(mxf, 0x5001); + mxf_mark_tag_unused(mxf, 0x5003); + } + + if (!will_have_avc_tags) { + mxf_mark_tag_unused(mxf, 0x8100); + mxf_mark_tag_unused(mxf, 0x8200); + mxf_mark_tag_unused(mxf, 0x8201); + mxf_mark_tag_unused(mxf, 0x8202); + } + + if (!will_have_mastering_tags) { + mxf_mark_tag_unused(mxf, 0x8301); + mxf_mark_tag_unused(mxf, 0x8302); + mxf_mark_tag_unused(mxf, 0x8303); + mxf_mark_tag_unused(mxf, 0x8304); + } + + for (i = 0; i < MXF_NUM_TAGS; i++) { + if (mxf->unused_tags[i]) { + local_tag_number--; } } @@ -528,21 +564,23 @@ static void mxf_write_primer_pack(AVFormatContext *s) avio_wb32(pb, local_tag_number); // local_tag num avio_wb32(pb, 18); // item size, always 18 according to the specs - for (i = 0; i < FF_ARRAY_ELEMS(mxf_local_tag_batch); i++) { - avio_wb16(pb, mxf_local_tag_batch[i].local_tag); - avio_write(pb, mxf_local_tag_batch[i].uid, 16); - } - if (mxf->store_user_comments) - for (i = 0; i < FF_ARRAY_ELEMS(mxf_user_comments_local_tag); i++) { - avio_wb16(pb, mxf_user_comments_local_tag[i].local_tag); - avio_write(pb, mxf_user_comments_local_tag[i].uid, 16); + for (i = 0; i < MXF_NUM_TAGS; i++) { + if (mxf->unused_tags[i] == 0) { + avio_wb16(pb, mxf_local_tag_batch[i].local_tag); + avio_write(pb, mxf_local_tag_batch[i].uid, 16); } - if (avc_tags_count > 0) - mxf_write_local_tags(pb, mxf_avc_subdescriptor_local_tags, avc_tags_count); + } } -static void mxf_write_local_tag(AVIOContext *pb, int size, int tag) +static void mxf_write_local_tag(AVFormatContext *s, int size, int tag) { + MXFContext *mxf = s->priv_data; + AVIOContext *pb = s->pb; + const MXFLocalTagPair *pair = mxf_lookup_local_tag(tag); + + // make sure the tag was not declared unnecessary upfront + av_assert0(mxf->unused_tags[pair - mxf_local_tag_batch] == 0); + avio_wb16(pb, tag); avio_wb16(pb, size); } @@ -553,11 +591,10 @@ static void mxf_write_metadata_key(AVIOContext *pb, unsigned int value) avio_wb24(pb, value); } -static const MXFCodecUL *mxf_get_data_definition_ul(int type) +static const MXFCodecUL *mxf_get_codec_ul_by_id(const MXFCodecUL *uls, int id) { - const MXFCodecUL *uls = ff_mxf_data_definition_uls; while (uls->uid[0]) { - if (type == uls->id) + if (id == uls->id) break; uls++; } @@ -600,44 +637,44 @@ static void mxf_write_preface(AVFormatContext *s) klv_encode_ber_length(pb, 138 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count)); // write preface set uid - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, Preface, 0); PRINT_KEY(s, "preface uid", pb->buf_ptr - 16); // last modified date - mxf_write_local_tag(pb, 8, 0x3B02); + mxf_write_local_tag(s, 8, 0x3B02); avio_wb64(pb, mxf->timestamp); // write version - mxf_write_local_tag(pb, 2, 0x3B05); + mxf_write_local_tag(s, 2, 0x3B05); avio_wb16(pb, 259); // v1.3 // Object Model Version - mxf_write_local_tag(pb, 4, 0x3B07); + mxf_write_local_tag(s, 4, 0x3B07); avio_wb32(pb, 1); // write identification_refs - mxf_write_local_tag(pb, 16 + 8, 0x3B06); + mxf_write_local_tag(s, 16 + 8, 0x3B06); mxf_write_refs_count(pb, 1); mxf_write_uuid(pb, Identification, 0); // write content_storage_refs - mxf_write_local_tag(pb, 16, 0x3B03); + mxf_write_local_tag(s, 16, 0x3B03); mxf_write_uuid(pb, ContentStorage, 0); // operational pattern - mxf_write_local_tag(pb, 16, 0x3B09); + mxf_write_local_tag(s, 16, 0x3B09); if (s->oformat == &ff_mxf_opatom_muxer) avio_write(pb, opatom_ul, 16); else avio_write(pb, op1a_ul, 16); // write essence_container_refs - mxf_write_local_tag(pb, 8 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count), 0x3B0A); + mxf_write_local_tag(s, 8 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count), 0x3B0A); mxf_write_essence_container_refs(s); // write dm_scheme_refs - mxf_write_local_tag(pb, 8, 0x3B0B); + mxf_write_local_tag(s, 8, 0x3B0B); avio_wb64(pb, 0); } @@ -686,8 +723,9 @@ static int mxf_utf16_local_tag_length(const char *utf8_str) /* * Write a local tag containing an utf-8 string as utf-16 */ -static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *value) +static void mxf_write_local_tag_utf16(AVFormatContext *s, int tag, const char *value) { + AVIOContext *pb = s->pb; uint64_t size = mxf_utf16len(value); if (size >= UINT16_MAX/2) { @@ -695,7 +733,7 @@ static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *valu return; } - mxf_write_local_tag(pb, size*2, tag); + mxf_write_local_tag(s, size*2, tag); avio_put_str16be(pb, value); } @@ -715,50 +753,57 @@ static void store_version(AVFormatContext *s){ avio_wb16(pb, 0); // release } +#define PLATFORM_IDENT "Lavf " AV_STRINGIFY((OS_NAME)) static void mxf_write_identification(AVFormatContext *s) { MXFContext *mxf = s->priv_data; AVIOContext *pb = s->pb; - const char *company = "FFmpeg"; - const char *product = s->oformat != &ff_mxf_opatom_muxer ? "OP1a Muxer" : "OPAtom Muxer"; - const char *version; + AVDictionaryEntry *com_entry = av_dict_get(s->metadata, "company_name", NULL, 0); + AVDictionaryEntry *product_entry = av_dict_get(s->metadata, "product_name", NULL, 0); + AVDictionaryEntry *version_entry = av_dict_get(s->metadata, "product_version", NULL, 0); + const char *company = com_entry ? com_entry->value : "FFmpeg"; + const char *product = product_entry ? product_entry->value : s->oformat != &ff_mxf_opatom_muxer ? "OP1a Muxer" : "OPAtom Muxer"; + const char *platform = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : PLATFORM_IDENT; + const char *version = version_entry ? version_entry->value : + s->flags & AVFMT_FLAG_BITEXACT ? "0.0.0" : + AV_STRINGIFY(LIBAVFORMAT_VERSION); int length; mxf_write_metadata_key(pb, 0x013000); PRINT_KEY(s, "identification key", pb->buf_ptr - 16); - version = s->flags & AVFMT_FLAG_BITEXACT ? - "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION); length = 100 +mxf_utf16_local_tag_length(company) + mxf_utf16_local_tag_length(product) + + mxf_utf16_local_tag_length(platform) + mxf_utf16_local_tag_length(version); klv_encode_ber_length(pb, length); // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, Identification, 0); PRINT_KEY(s, "identification uid", pb->buf_ptr - 16); // write generation uid - mxf_write_local_tag(pb, 16, 0x3C09); + mxf_write_local_tag(s, 16, 0x3C09); mxf_write_uuid(pb, Identification, 1); - mxf_write_local_tag_utf16(pb, 0x3C01, company); // Company Name - mxf_write_local_tag_utf16(pb, 0x3C02, product); // Product Name + mxf_write_local_tag_utf16(s, 0x3C01, company); // Company Name + mxf_write_local_tag_utf16(s, 0x3C02, product); // Product Name - mxf_write_local_tag(pb, 10, 0x3C03); // Product Version + mxf_write_local_tag(s, 10, 0x3C03); // Product Version store_version(s); - mxf_write_local_tag_utf16(pb, 0x3C04, version); // Version String + mxf_write_local_tag_utf16(s, 0x3C04, version); // Version String + mxf_write_local_tag_utf16(s, 0x3C08, platform); // Platform // write product uid - mxf_write_local_tag(pb, 16, 0x3C05); + mxf_write_local_tag(s, 16, 0x3C05); mxf_write_uuid(pb, Identification, 2); // modification date - mxf_write_local_tag(pb, 8, 0x3C06); + mxf_write_local_tag(s, 8, 0x3C06); avio_wb64(pb, mxf->timestamp); - mxf_write_local_tag(pb, 10, 0x3C07); // Toolkit Version + mxf_write_local_tag(s, 10, 0x3C07); // Toolkit Version store_version(s); } @@ -772,19 +817,19 @@ static void mxf_write_content_storage(AVFormatContext *s, MXFPackage *packages, klv_encode_ber_length(pb, 60 + (16 * package_count)); // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, ContentStorage, 0); PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16); // write package reference - mxf_write_local_tag(pb, 16 * package_count + 8, 0x1901); + mxf_write_local_tag(s, 16 * package_count + 8, 0x1901); mxf_write_refs_count(pb, package_count); for (i = 0; i < package_count; i++) { mxf_write_uuid(pb, packages[i].type, packages[i].instance); } // write essence container data - mxf_write_local_tag(pb, 8 + 16, 0x1902); + mxf_write_local_tag(s, 8 + 16, 0x1902); mxf_write_refs_count(pb, 1); mxf_write_uuid(pb, EssenceContainerData, 0); } @@ -800,23 +845,23 @@ static void mxf_write_track(AVFormatContext *s, AVStream *st, MXFPackage *packag klv_encode_ber_length(pb, 80); // write track uid - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, Track, mxf->track_instance_count); PRINT_KEY(s, "track uid", pb->buf_ptr - 16); // write track id - mxf_write_local_tag(pb, 4, 0x4801); + mxf_write_local_tag(s, 4, 0x4801); avio_wb32(pb, st->index+2); // write track number - mxf_write_local_tag(pb, 4, 0x4804); + mxf_write_local_tag(s, 4, 0x4804); if (package->type == MaterialPackage) avio_wb32(pb, 0); // track number of material package is 0 else avio_write(pb, sc->track_essence_element_key + 12, 4); // write edit rate - mxf_write_local_tag(pb, 8, 0x4B01); + mxf_write_local_tag(s, 8, 0x4B01); if (st == mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer) { avio_wb32(pb, mxf->tc.rate.num); @@ -827,11 +872,11 @@ static void mxf_write_track(AVFormatContext *s, AVStream *st, MXFPackage *packag } // write origin - mxf_write_local_tag(pb, 8, 0x4B02); + mxf_write_local_tag(s, 8, 0x4B02); avio_wb64(pb, 0); // write sequence refs - mxf_write_local_tag(pb, 16, 0x4803); + mxf_write_local_tag(s, 16, 0x4803); mxf_write_uuid(pb, Sequence, mxf->track_instance_count); } @@ -843,16 +888,16 @@ static void mxf_write_common_fields(AVFormatContext *s, AVStream *st) AVIOContext *pb = s->pb; // find data define uls - mxf_write_local_tag(pb, 16, 0x0201); + mxf_write_local_tag(s, 16, 0x0201); if (st == mxf->timecode_track) avio_write(pb, smpte_12m_timecode_track_data_ul, 16); else { - const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codecpar->codec_type); + const MXFCodecUL *data_def_ul = mxf_get_codec_ul_by_id(ff_mxf_data_definition_uls, st->codecpar->codec_type); avio_write(pb, data_def_ul->uid, 16); } // write duration - mxf_write_local_tag(pb, 8, 0x0202); + mxf_write_local_tag(s, 8, 0x0202); if (st != mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { avio_wb64(pb, mxf->body_offset / mxf->edit_unit_byte_count); @@ -871,14 +916,14 @@ static void mxf_write_sequence(AVFormatContext *s, AVStream *st, MXFPackage *pac PRINT_KEY(s, "sequence key", pb->buf_ptr - 16); klv_encode_ber_length(pb, 80); - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, Sequence, mxf->track_instance_count); PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16); mxf_write_common_fields(s, st); // write structural component - mxf_write_local_tag(pb, 16 + 8, 0x1001); + mxf_write_local_tag(s, 16 + 8, 0x1001); mxf_write_refs_count(pb, 1); if (st == mxf->timecode_track) component = TimecodeComponent; @@ -897,21 +942,21 @@ static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, MXFPa klv_encode_ber_length(pb, 75); // UID - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, TimecodeComponent, mxf->track_instance_count); mxf_write_common_fields(s, st); // Start Time Code - mxf_write_local_tag(pb, 8, 0x1501); + mxf_write_local_tag(s, 8, 0x1501); avio_wb64(pb, mxf->tc.start); // Rounded Time Code Base - mxf_write_local_tag(pb, 2, 0x1502); + mxf_write_local_tag(s, 2, 0x1502); avio_wb16(pb, mxf->timecode_base); // Drop Frame - mxf_write_local_tag(pb, 1, 0x1503); + mxf_write_local_tag(s, 1, 0x1503); avio_w8(pb, !!(mxf->tc.flags & AV_TIMECODE_FLAG_DROPFRAME)); } @@ -926,18 +971,18 @@ static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, MXF klv_encode_ber_length(pb, 108); // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, SourceClip, mxf->track_instance_count); PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16); mxf_write_common_fields(s, st); // write start_position - mxf_write_local_tag(pb, 8, 0x1201); + mxf_write_local_tag(s, 8, 0x1201); avio_wb64(pb, 0); // write source package uid, end of the reference - mxf_write_local_tag(pb, 32, 0x1101); + mxf_write_local_tag(s, 32, 0x1101); if (!package->ref) { for (i = 0; i < 4; i++) avio_wb64(pb, 0); @@ -945,7 +990,7 @@ static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, MXF mxf_write_umid(s, package->ref->instance); // write source track id - mxf_write_local_tag(pb, 4, 0x1102); + mxf_write_local_tag(s, 4, 0x1102); if (package->type == SourcePackage && !package->ref) avio_wb32(pb, 0); else @@ -959,7 +1004,7 @@ static void mxf_write_tape_descriptor(AVFormatContext *s) mxf_write_metadata_key(pb, 0x012e00); PRINT_KEY(s, "tape descriptor key", pb->buf_ptr - 16); klv_encode_ber_length(pb, 20); - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, TapeDescriptor, 0); PRINT_KEY(s, "tape_desc uid", pb->buf_ptr - 16); } @@ -976,17 +1021,17 @@ static void mxf_write_multi_descriptor(AVFormatContext *s) PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16); klv_encode_ber_length(pb, 64 + 16LL * s->nb_streams); - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, MultipleDescriptor, 0); PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16); // write sample rate - mxf_write_local_tag(pb, 8, 0x3001); + mxf_write_local_tag(s, 8, 0x3001); avio_wb32(pb, mxf->time_base.den); avio_wb32(pb, mxf->time_base.num); // write essence container ul - mxf_write_local_tag(pb, 16, 0x3004); + mxf_write_local_tag(s, 16, 0x3004); if (mxf->essence_container_count > 1) ul = multiple_desc_ul; else { @@ -996,7 +1041,7 @@ static void mxf_write_multi_descriptor(AVFormatContext *s) avio_write(pb, ul, 16); // write sub descriptor refs - mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01); + mxf_write_local_tag(s, s->nb_streams * 16 + 8, 0x3F01); mxf_write_refs_count(pb, s->nb_streams); for (i = 0; i < s->nb_streams; i++) mxf_write_uuid(pb, SubDescriptor, i); @@ -1013,13 +1058,13 @@ static int64_t mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UI klv_encode_ber4_length(pb, 0); pos = avio_tell(pb); - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, SubDescriptor, st->index); - mxf_write_local_tag(pb, 4, 0x3006); + mxf_write_local_tag(s, 4, 0x3006); avio_wb32(pb, st->index+2); - mxf_write_local_tag(pb, 8, 0x3001); + mxf_write_local_tag(s, 8, 0x3001); if (s->oformat == &ff_mxf_d10_muxer) { avio_wb32(pb, mxf->time_base.den); avio_wb32(pb, mxf->time_base.num); @@ -1034,7 +1079,7 @@ static int64_t mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UI } } - mxf_write_local_tag(pb, 16, 0x3004); + mxf_write_local_tag(s, 16, 0x3004); avio_write(pb, *sc->container_ul, 16); return pos; @@ -1049,32 +1094,14 @@ static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0 static const UID mxf_avc_subdescriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6E,0x00 }; -static int get_trc(UID ul, enum AVColorTransferCharacteristic trc) +static inline uint16_t rescale_mastering_chroma(AVRational q) { - switch (trc){ - case AVCOL_TRC_GAMMA28 : - case AVCOL_TRC_GAMMA22 : - memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x01,0x00,0x00}), 16); - return 0; - case AVCOL_TRC_BT709 : - case AVCOL_TRC_SMPTE170M : - memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00}), 16); - return 0; - case AVCOL_TRC_SMPTE240M : - memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x03,0x00,0x00}), 16); - return 0; - case AVCOL_TRC_BT1361_ECG: - memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x05,0x00,0x00}), 16); - return 0; - case AVCOL_TRC_LINEAR : - memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x06,0x00,0x00}), 16); - return 0; - case AVCOL_TRC_SMPTE428 : - memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x08,0x04,0x01,0x01,0x01,0x01,0x07,0x00,0x00}), 16); - return 0; - default: - return -1; - } + return av_clip_uint16(av_rescale(q.num, FF_MXF_MASTERING_CHROMA_DEN, q.den)); +} + +static inline uint32_t rescale_mastering_luma(AVRational q) +{ + return av_rescale(q.num, FF_MXF_MASTERING_LUMA_DEN, q.den); } static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key) @@ -1085,10 +1112,15 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID int stored_height = (st->codecpar->height+15)/16*16; int display_height; int f1, f2; - UID transfer_ul = {0}; + const MXFCodecUL *color_primaries_ul; + const MXFCodecUL *color_trc_ul; + const MXFCodecUL *color_space_ul; int64_t pos = mxf_write_generic_desc(s, st, key); + uint8_t *side_data; - get_trc(transfer_ul, st->codecpar->color_trc); + color_primaries_ul = mxf_get_codec_ul_by_id(ff_mxf_color_primaries_uls, st->codecpar->color_primaries); + color_trc_ul = mxf_get_codec_ul_by_id(ff_mxf_color_trc_uls, st->codecpar->color_trc); + color_space_ul = mxf_get_codec_ul_by_id(ff_mxf_color_space_uls, st->codecpar->color_space); if (st->codecpar->codec_id == AV_CODEC_ID_DVVIDEO) { if (st->codecpar->height == 1080) @@ -1099,43 +1131,43 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID if (!stored_width) stored_width = (st->codecpar->width+15)/16*16; - mxf_write_local_tag(pb, 4, 0x3203); + mxf_write_local_tag(s, 4, 0x3203); avio_wb32(pb, stored_width); - mxf_write_local_tag(pb, 4, 0x3202); + mxf_write_local_tag(s, 4, 0x3202); avio_wb32(pb, stored_height>>sc->interlaced); if (s->oformat == &ff_mxf_d10_muxer) { //Stored F2 Offset - mxf_write_local_tag(pb, 4, 0x3216); + mxf_write_local_tag(s, 4, 0x3216); avio_wb32(pb, 0); //Image Start Offset - mxf_write_local_tag(pb, 4, 0x3213); + mxf_write_local_tag(s, 4, 0x3213); avio_wb32(pb, 0); //Image End Offset - mxf_write_local_tag(pb, 4, 0x3214); + mxf_write_local_tag(s, 4, 0x3214); avio_wb32(pb, 0); } //Sampled width - mxf_write_local_tag(pb, 4, 0x3205); + mxf_write_local_tag(s, 4, 0x3205); avio_wb32(pb, stored_width); //Samples height - mxf_write_local_tag(pb, 4, 0x3204); + mxf_write_local_tag(s, 4, 0x3204); avio_wb32(pb, st->codecpar->height>>sc->interlaced); //Sampled X Offset - mxf_write_local_tag(pb, 4, 0x3206); + mxf_write_local_tag(s, 4, 0x3206); avio_wb32(pb, 0); //Sampled Y Offset - mxf_write_local_tag(pb, 4, 0x3207); + mxf_write_local_tag(s, 4, 0x3207); avio_wb32(pb, 0); - mxf_write_local_tag(pb, 4, 0x3209); + mxf_write_local_tag(s, 4, 0x3209); avio_wb32(pb, stored_width); if (st->codecpar->height == 608) // PAL + VBI @@ -1145,67 +1177,67 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID else display_height = st->codecpar->height; - mxf_write_local_tag(pb, 4, 0x3208); + mxf_write_local_tag(s, 4, 0x3208); avio_wb32(pb, display_height>>sc->interlaced); // display X offset - mxf_write_local_tag(pb, 4, 0x320A); + mxf_write_local_tag(s, 4, 0x320A); avio_wb32(pb, 0); // display Y offset - mxf_write_local_tag(pb, 4, 0x320B); + mxf_write_local_tag(s, 4, 0x320B); avio_wb32(pb, (st->codecpar->height - display_height)>>sc->interlaced); if (sc->interlaced) { //Display F2 Offset - mxf_write_local_tag(pb, 4, 0x3217); + mxf_write_local_tag(s, 4, 0x3217); avio_wb32(pb, -((st->codecpar->height - display_height)&1)); } // component depth - mxf_write_local_tag(pb, 4, 0x3301); + mxf_write_local_tag(s, 4, 0x3301); avio_wb32(pb, sc->component_depth); // horizontal subsampling - mxf_write_local_tag(pb, 4, 0x3302); + mxf_write_local_tag(s, 4, 0x3302); avio_wb32(pb, sc->h_chroma_sub_sample); // vertical subsampling - mxf_write_local_tag(pb, 4, 0x3308); + mxf_write_local_tag(s, 4, 0x3308); avio_wb32(pb, sc->v_chroma_sub_sample); // color siting - mxf_write_local_tag(pb, 1, 0x3303); + mxf_write_local_tag(s, 1, 0x3303); avio_w8(pb, sc->color_siting); // Padding Bits - mxf_write_local_tag(pb, 2, 0x3307); + mxf_write_local_tag(s, 2, 0x3307); avio_wb16(pb, 0); if (st->codecpar->color_range != AVCOL_RANGE_UNSPECIFIED) { int black = 0, white = (1<component_depth) - 1, - color = (1<component_depth) - 1; + color = (1<component_depth); if (st->codecpar->color_range == AVCOL_RANGE_MPEG) { black = 1 << (sc->component_depth - 4); white = 235 << (sc->component_depth - 8); color = (14 << (sc->component_depth - 4)) + 1; } - mxf_write_local_tag(pb, 4, 0x3304); + mxf_write_local_tag(s, 4, 0x3304); avio_wb32(pb, black); - mxf_write_local_tag(pb, 4, 0x3305); + mxf_write_local_tag(s, 4, 0x3305); avio_wb32(pb, white); - mxf_write_local_tag(pb, 4, 0x3306); + mxf_write_local_tag(s, 4, 0x3306); avio_wb32(pb, color); } if (sc->signal_standard) { - mxf_write_local_tag(pb, 1, 0x3215); + mxf_write_local_tag(s, 1, 0x3215); avio_w8(pb, sc->signal_standard); } // frame layout - mxf_write_local_tag(pb, 1, 0x320C); + mxf_write_local_tag(s, 1, 0x320C); avio_w8(pb, sc->interlaced); // video line map @@ -1225,33 +1257,70 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID } - mxf_write_local_tag(pb, 16, 0x320D); + mxf_write_local_tag(s, 16, 0x320D); avio_wb32(pb, 2); avio_wb32(pb, 4); avio_wb32(pb, f1); avio_wb32(pb, f2); - mxf_write_local_tag(pb, 8, 0x320E); + mxf_write_local_tag(s, 8, 0x320E); avio_wb32(pb, sc->aspect_ratio.num); avio_wb32(pb, sc->aspect_ratio.den); - //Transfer characteristic - if (transfer_ul[0]) { - mxf_write_local_tag(pb, 16, 0x3210); - avio_write(pb, transfer_ul, 16); + if (color_primaries_ul->uid[0]) { + mxf_write_local_tag(s, 16, 0x3219); + avio_write(pb, color_primaries_ul->uid, 16); }; - mxf_write_local_tag(pb, 16, 0x3201); + if (color_trc_ul->uid[0]) { + mxf_write_local_tag(s, 16, 0x3210); + avio_write(pb, color_trc_ul->uid, 16); + }; + + if (color_space_ul->uid[0]) { + mxf_write_local_tag(s, 16, 0x321A); + avio_write(pb, color_space_ul->uid, 16); + }; + + mxf_write_local_tag(s, 16, 0x3201); avio_write(pb, *sc->codec_ul, 16); + // Mastering Display metadata + side_data = av_stream_get_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, NULL); + if (side_data) { + const AVMasteringDisplayMetadata *metadata = (const AVMasteringDisplayMetadata*)side_data; + if (metadata->has_primaries) { + mxf_write_local_tag(s, 12, 0x8301); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[0][0])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[0][1])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[1][0])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[1][1])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[2][0])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[2][1])); + mxf_write_local_tag(s, 4, 0x8302); + avio_wb16(pb, rescale_mastering_chroma(metadata->white_point[0])); + avio_wb16(pb, rescale_mastering_chroma(metadata->white_point[1])); + } else { + av_log(NULL, AV_LOG_VERBOSE, "Not writing mastering display primaries. Missing data.\n"); + } + if (metadata->has_luminance) { + mxf_write_local_tag(s, 4, 0x8303); + avio_wb32(pb, rescale_mastering_luma(metadata->max_luminance)); + mxf_write_local_tag(s, 4, 0x8304); + avio_wb32(pb, rescale_mastering_luma(metadata->min_luminance)); + } else { + av_log(NULL, AV_LOG_VERBOSE, "Not writing mastering display luminances. Missing data.\n"); + } + } + if (sc->interlaced && sc->field_dominance) { - mxf_write_local_tag(pb, 1, 0x3212); + mxf_write_local_tag(s, 1, 0x3212); avio_w8(pb, sc->field_dominance); } if (st->codecpar->codec_id == AV_CODEC_ID_H264 && !sc->avc_intra) { // write avc sub descriptor ref - mxf_write_local_tag(pb, 8 + 16, 0x8100); + mxf_write_local_tag(s, 8 + 16, 0x8100); mxf_write_refs_count(pb, 1); mxf_write_uuid(pb, AVCSubDescriptor, 0); } @@ -1277,16 +1346,16 @@ static void mxf_write_avc_subdesc(AVFormatContext *s, AVStream *st) klv_encode_ber4_length(pb, 0); pos = avio_tell(pb); - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, AVCSubDescriptor, 0); - mxf_write_local_tag(pb, 1, 0x8200); + mxf_write_local_tag(s, 1, 0x8200); avio_w8(pb, 0xFF); // AVC Decoding Delay, unknown - mxf_write_local_tag(pb, 1, 0x8201); + mxf_write_local_tag(s, 1, 0x8201); avio_w8(pb, st->codecpar->profile); // AVC Profile - mxf_write_local_tag(pb, 1, 0x8202); + mxf_write_local_tag(s, 1, 0x8202); avio_w8(pb, st->codecpar->level); // AVC Level mxf_update_klv_size(s->pb, pos); @@ -1329,29 +1398,29 @@ static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st) if (st->codecpar->codec_id != AV_CODEC_ID_H264) { // bit rate - mxf_write_local_tag(pb, 4, 0x8000); + mxf_write_local_tag(s, 4, 0x8000); avio_wb32(pb, sc->video_bit_rate); // profile and level - mxf_write_local_tag(pb, 1, 0x8007); + mxf_write_local_tag(s, 1, 0x8007); if (!st->codecpar->profile) profile_and_level |= 0x80; // escape bit avio_w8(pb, profile_and_level); // low delay - mxf_write_local_tag(pb, 1, 0x8003); + mxf_write_local_tag(s, 1, 0x8003); avio_w8(pb, sc->low_delay); // closed gop - mxf_write_local_tag(pb, 1, 0x8004); + mxf_write_local_tag(s, 1, 0x8004); avio_w8(pb, sc->seq_closed_gop); // max gop - mxf_write_local_tag(pb, 2, 0x8006); + mxf_write_local_tag(s, 2, 0x8006); avio_wb16(pb, sc->max_gop); // b picture count - mxf_write_local_tag(pb, 2, 0x8008); + mxf_write_local_tag(s, 2, 0x8008); avio_wb16(pb, sc->b_picture_count); } @@ -1366,25 +1435,25 @@ static int64_t mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, int64_t pos = mxf_write_generic_desc(s, st, key); if (s->oformat == &ff_mxf_opatom_muxer) { - mxf_write_local_tag(pb, 8, 0x3002); + mxf_write_local_tag(s, 8, 0x3002); avio_wb64(pb, mxf->body_offset / mxf->edit_unit_byte_count); } // audio locked - mxf_write_local_tag(pb, 1, 0x3D02); + mxf_write_local_tag(s, 1, 0x3D02); avio_w8(pb, 1); // write audio sampling rate - mxf_write_local_tag(pb, 8, 0x3D03); + mxf_write_local_tag(s, 8, 0x3D03); avio_wb32(pb, st->codecpar->sample_rate); avio_wb32(pb, 1); if (s->oformat == &ff_mxf_d10_muxer) { - mxf_write_local_tag(pb, 1, 0x3D04); + mxf_write_local_tag(s, 1, 0x3D04); avio_w8(pb, 0); } - mxf_write_local_tag(pb, 4, 0x3D07); + mxf_write_local_tag(s, 4, 0x3D07); if (mxf->channel_count == -1) { if (show_warnings && (s->oformat == &ff_mxf_d10_muxer) && (st->codecpar->channels != 4) && (st->codecpar->channels != 8)) av_log(s, AV_LOG_WARNING, "the number of audio channels shall be 4 or 8 : the output will not comply to MXF D-10 specs, use -d10_channelcount to fix this\n"); @@ -1399,7 +1468,7 @@ static int64_t mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, avio_wb32(pb, st->codecpar->channels); } - mxf_write_local_tag(pb, 4, 0x3D01); + mxf_write_local_tag(s, 4, 0x3D01); avio_wb32(pb, av_get_bits_per_sample(st->codecpar->codec_id)); return pos; @@ -1410,11 +1479,11 @@ static int64_t mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID AVIOContext *pb = s->pb; int64_t pos = mxf_write_generic_sound_common(s, st, key); - mxf_write_local_tag(pb, 2, 0x3D0A); + mxf_write_local_tag(s, 2, 0x3D0A); avio_wb16(pb, st->codecpar->block_align); // avg bytes per sec - mxf_write_local_tag(pb, 4, 0x3D09); + mxf_write_local_tag(s, 4, 0x3D09); avio_wb32(pb, st->codecpar->block_align*st->codecpar->sample_rate); return pos; @@ -1454,14 +1523,14 @@ static int mxf_write_tagged_value(AVFormatContext *s, const char* name, const ch klv_encode_ber_length(pb, 24 + name_size + indirect_value_size); // write instance UID - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, TaggedValue, mxf->tagged_value_count); // write name - mxf_write_local_tag_utf16(pb, 0x5001, name); // Name + mxf_write_local_tag_utf16(s, 0x5001, name); // Name // write indirect value - mxf_write_local_tag(pb, indirect_value_size, 0x5003); + mxf_write_local_tag(s, indirect_value_size, 0x5003); avio_write(pb, mxf_indirect_value_utf16le, 17); avio_put_str16le(pb, value); @@ -1508,30 +1577,30 @@ static void mxf_write_package(AVFormatContext *s, MXFPackage *package) } // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, package->type, package->instance); av_log(s, AV_LOG_DEBUG, "package type:%d\n", package->type); PRINT_KEY(s, "package uid", pb->buf_ptr - 16); // write package umid - mxf_write_local_tag(pb, 32, 0x4401); + mxf_write_local_tag(s, 32, 0x4401); mxf_write_umid(s, package->instance); PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16); // package name if (name_size) - mxf_write_local_tag_utf16(pb, 0x4402, package->name); + mxf_write_local_tag_utf16(s, 0x4402, package->name); // package creation date - mxf_write_local_tag(pb, 8, 0x4405); + mxf_write_local_tag(s, 8, 0x4405); avio_wb64(pb, mxf->timestamp); // package modified date - mxf_write_local_tag(pb, 8, 0x4404); + mxf_write_local_tag(s, 8, 0x4404); avio_wb64(pb, mxf->timestamp); // write track refs - mxf_write_local_tag(pb, track_count*16 + 8, 0x4403); + mxf_write_local_tag(s, track_count*16 + 8, 0x4403); mxf_write_refs_count(pb, track_count); // these are the uuids of the tracks the will be written in mxf_write_track for (i = 0; i < track_count; i++) @@ -1539,7 +1608,7 @@ static void mxf_write_package(AVFormatContext *s, MXFPackage *package) // write user comment refs if (mxf->store_user_comments) { - mxf_write_local_tag(pb, user_comment_count*16 + 8, 0x4406); + mxf_write_local_tag(s, user_comment_count*16 + 8, 0x4406); mxf_write_refs_count(pb, user_comment_count); for (i = 0; i < user_comment_count; i++) mxf_write_uuid(pb, TaggedValue, mxf->tagged_value_count - user_comment_count + i); @@ -1547,14 +1616,14 @@ static void mxf_write_package(AVFormatContext *s, MXFPackage *package) // write multiple descriptor reference if (package->type == SourcePackage && package->instance == 1) { - mxf_write_local_tag(pb, 16, 0x4701); + mxf_write_local_tag(s, 16, 0x4701); if (s->nb_streams > 1) { mxf_write_uuid(pb, MultipleDescriptor, 0); mxf_write_multi_descriptor(s); } else mxf_write_uuid(pb, SubDescriptor, 0); } else if (package->type == SourcePackage && package->instance == 2) { - mxf_write_local_tag(pb, 16, 0x4701); + mxf_write_local_tag(s, 16, 0x4701); mxf_write_uuid(pb, TapeDescriptor, 0); mxf_write_tape_descriptor(s); } @@ -1594,16 +1663,16 @@ static int mxf_write_essence_container_data(AVFormatContext *s) mxf_write_metadata_key(pb, 0x012300); klv_encode_ber_length(pb, 72); - mxf_write_local_tag(pb, 16, 0x3C0A); // Instance UID + mxf_write_local_tag(s, 16, 0x3C0A); // Instance UID mxf_write_uuid(pb, EssenceContainerData, 0); - mxf_write_local_tag(pb, 32, 0x2701); // Linked Package UID + mxf_write_local_tag(s, 32, 0x2701); // Linked Package UID mxf_write_umid(s, 1); - mxf_write_local_tag(pb, 4, 0x3F07); // BodySID + mxf_write_local_tag(s, 4, 0x3F07); // BodySID avio_wb32(pb, 1); - mxf_write_local_tag(pb, 4, 0x3F06); // IndexSID + mxf_write_local_tag(s, 4, 0x3F06); // IndexSID avio_wb32(pb, 2); return 0; @@ -1688,43 +1757,43 @@ static void mxf_write_index_table_segment(AVFormatContext *s) pos = avio_tell(pb); // instance id - mxf_write_local_tag(pb, 16, 0x3C0A); + mxf_write_local_tag(s, 16, 0x3C0A); mxf_write_uuid(pb, IndexTableSegment, 0); // index edit rate - mxf_write_local_tag(pb, 8, 0x3F0B); + mxf_write_local_tag(s, 8, 0x3F0B); avio_wb32(pb, mxf->time_base.den); avio_wb32(pb, mxf->time_base.num); // index start position - mxf_write_local_tag(pb, 8, 0x3F0C); + mxf_write_local_tag(s, 8, 0x3F0C); avio_wb64(pb, mxf->last_indexed_edit_unit); // index duration - mxf_write_local_tag(pb, 8, 0x3F0D); + mxf_write_local_tag(s, 8, 0x3F0D); if (mxf->edit_unit_byte_count) avio_wb64(pb, 0); // index table covers whole container else avio_wb64(pb, mxf->edit_units_count); // edit unit byte count - mxf_write_local_tag(pb, 4, 0x3F05); + mxf_write_local_tag(s, 4, 0x3F05); avio_wb32(pb, mxf->edit_unit_byte_count); // index sid - mxf_write_local_tag(pb, 4, 0x3F06); + mxf_write_local_tag(s, 4, 0x3F06); avio_wb32(pb, 2); // body sid - mxf_write_local_tag(pb, 4, 0x3F07); + mxf_write_local_tag(s, 4, 0x3F07); avio_wb32(pb, 1); // real slice count - 1 - mxf_write_local_tag(pb, 1, 0x3F08); + mxf_write_local_tag(s, 1, 0x3F08); avio_w8(pb, !mxf->edit_unit_byte_count); // only one slice for CBR // delta entry array - mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09); + mxf_write_local_tag(s, 8 + (s->nb_streams+1)*6, 0x3F09); avio_wb32(pb, s->nb_streams+1); // num of entries avio_wb32(pb, 6); // size of one entry // write system item delta entry @@ -1756,7 +1825,7 @@ static void mxf_write_index_table_segment(AVFormatContext *s) if (!mxf->edit_unit_byte_count) { MXFStreamContext *sc = s->streams[0]->priv_data; - mxf_write_local_tag(pb, 8 + mxf->edit_units_count*15, 0x3F0A); + mxf_write_local_tag(s, 8 + mxf->edit_units_count*15, 0x3F0A); avio_wb32(pb, mxf->edit_units_count); // num of entries avio_wb32(pb, 15); // size of one entry @@ -1951,7 +2020,6 @@ static int mxf_parse_prores_frame(AVFormatContext *s, AVStream *st, AVPacket *pk if (mxf->header_written) return 1; - sc->codec_ul = NULL; profile = st->codecpar->profile; for (i = 0; i < FF_ARRAY_ELEMS(mxf_prores_codec_uls); i++) { if (profile == mxf_prores_codec_uls[i].profile) { @@ -1959,7 +2027,7 @@ static int mxf_parse_prores_frame(AVFormatContext *s, AVStream *st, AVPacket *pk break; } } - if (!sc->codec_ul) + if (i == FF_ARRAY_ELEMS(mxf_prores_codec_uls)) return 0; sc->frame_size = pkt->size; @@ -2005,7 +2073,6 @@ static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt if (pkt->size < 43) return 0; - sc->codec_ul = NULL; cid = AV_RB32(pkt->data + 0x28); for (i = 0; i < FF_ARRAY_ELEMS(mxf_dnxhd_codec_uls); i++) { if (cid == mxf_dnxhd_codec_uls[i].cid) { @@ -2013,7 +2080,7 @@ static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt break; } } - if (!sc->codec_ul) + if (i == FF_ARRAY_ELEMS(mxf_dnxhd_codec_uls)) return 0; sc->component_depth = 0; @@ -2176,6 +2243,7 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st, const uint8_t *buf = pkt->data; const uint8_t *buf_end = pkt->data + pkt->size; const uint8_t *nal_end; + const UID *codec_ul = NULL; uint32_t state = -1; int extra_size = 512; // support AVC Intra files without SPS/PPS header int i, frame_size, slice_type, has_sps = 0, intra_only = 0, ret; @@ -2246,12 +2314,11 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st, if (!has_sps) sc->interlaced = st->codecpar->field_order != AV_FIELD_PROGRESSIVE ? 1 : 0; - sc->codec_ul = NULL; frame_size = pkt->size + extra_size; for (i = 0; i < FF_ARRAY_ELEMS(mxf_h264_codec_uls); i++) { if (frame_size == mxf_h264_codec_uls[i].frame_size && sc->interlaced == mxf_h264_codec_uls[i].interlaced) { - sc->codec_ul = &mxf_h264_codec_uls[i].uid; + codec_ul = &mxf_h264_codec_uls[i].uid; sc->component_depth = 10; // AVC Intra is always 10 Bit sc->aspect_ratio = (AVRational){ 16, 9 }; // 16:9 is mandatory for broadcast HD st->codecpar->profile = mxf_h264_codec_uls[i].profile; @@ -2265,17 +2332,18 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st, mxf_h264_codec_uls[i].profile == sps->profile_idc && (mxf_h264_codec_uls[i].intra_only < 0 || mxf_h264_codec_uls[i].intra_only == intra_only)) { - sc->codec_ul = &mxf_h264_codec_uls[i].uid; + codec_ul = &mxf_h264_codec_uls[i].uid; st->codecpar->profile = sps->profile_idc; st->codecpar->level = sps->level_idc; // continue to check for avc intra } } - if (!sc->codec_ul) { + if (!codec_ul) { av_log(s, AV_LOG_ERROR, "h264 profile not supported\n"); return 0; } + sc->codec_ul = codec_ul; return 1; } @@ -2372,9 +2440,13 @@ static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, } } } - if (s->oformat != &ff_mxf_d10_muxer) - sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codecpar); - return !!sc->codec_ul; + if (s->oformat != &ff_mxf_d10_muxer) { + const UID *codec_ul = mxf_get_mpeg2_codec_ul(st->codecpar); + if (!codec_ul) + return 0; + sc->codec_ul = codec_ul; + } + return 1; } static uint64_t mxf_parse_timestamp(int64_t timestamp64) @@ -2816,6 +2888,13 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt) MXFIndexEntry ie = {0}; int err; + if (!mxf->header_written && pkt->stream_index != 0 && + s->oformat != &ff_mxf_opatom_muxer) { + av_log(s, AV_LOG_ERROR, "Received non-video packet before " + "header has been written\n"); + return AVERROR_INVALIDDATA; + } + if (!mxf->cbr_index && !mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) { if ((err = av_reallocp_array(&mxf->index_entries, mxf->edit_units_count + EDIT_UNITS_PER_BODY, sizeof(*mxf->index_entries))) < 0) { @@ -2929,7 +3008,7 @@ static void mxf_write_random_index_pack(AVFormatContext *s) uint64_t pos = avio_tell(pb); int i; - avio_write(pb, random_index_pack_key, 16); + avio_write(pb, ff_mxf_random_index_pack_key, 16); klv_encode_ber_length(pb, 28 + 12LL*mxf->body_partitions_count); if (mxf->edit_unit_byte_count && s->oformat != &ff_mxf_opatom_muxer) @@ -3023,26 +3102,26 @@ static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket int i, stream_count = 0; for (i = 0; i < s->nb_streams; i++) - stream_count += !!s->streams[i]->last_in_packet_buffer; + stream_count += !!s->streams[i]->internal->last_in_packet_buffer; if (stream_count && (s->nb_streams == stream_count || flush)) { - AVPacketList *pktl = s->internal->packet_buffer; + PacketList *pktl = s->internal->packet_buffer; if (s->nb_streams != stream_count) { - AVPacketList *last = NULL; + PacketList *last = NULL; // find last packet in edit unit while (pktl) { if (!stream_count || pktl->pkt.stream_index == 0) break; // update last packet in packet buffer - if (s->streams[pktl->pkt.stream_index]->last_in_packet_buffer != pktl) - s->streams[pktl->pkt.stream_index]->last_in_packet_buffer = pktl; + if (s->streams[pktl->pkt.stream_index]->internal->last_in_packet_buffer != pktl) + s->streams[pktl->pkt.stream_index]->internal->last_in_packet_buffer = pktl; last = pktl; pktl = pktl->next; stream_count--; } // purge packet queue while (pktl) { - AVPacketList *next = pktl->next; + PacketList *next = pktl->next; av_packet_unref(&pktl->pkt); av_freep(&pktl); pktl = next; @@ -3060,8 +3139,8 @@ static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *out = pktl->pkt; av_log(s, AV_LOG_TRACE, "out st:%d dts:%"PRId64"\n", (*out).stream_index, (*out).dts); s->internal->packet_buffer = pktl->next; - if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl) - s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL; + if(s->streams[pktl->pkt.stream_index]->internal->last_in_packet_buffer == pktl) + s->streams[pktl->pkt.stream_index]->internal->last_in_packet_buffer= NULL; if(!s->internal->packet_buffer) s->internal->packet_buffer_end= NULL; av_freep(&pktl); diff --git a/libavformat/nut.c b/libavformat/nut.c index d6993239a..47ed15252 100644 --- a/libavformat/nut.c +++ b/libavformat/nut.c @@ -27,6 +27,8 @@ const AVCodecTag ff_nut_subtitle_tags[] = { { AV_CODEC_ID_TEXT, MKTAG('U', 'T', 'F', '8') }, + { AV_CODEC_ID_ASS, MKTAG('S', 'S', 'A', 0 ) }, + { AV_CODEC_ID_ASS, MKTAG('A', 'S', 'S', 0 ) }, { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('D', 'V', 'D', 'S') }, { AV_CODEC_ID_DVB_SUBTITLE, MKTAG('D', 'V', 'B', 'S') }, { AV_CODEC_ID_DVB_TELETEXT, MKTAG('D', 'V', 'B', 'T') }, diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index 8b0ccf4aa..fbecf7132 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -489,8 +489,8 @@ static int decode_info_header(NUTContext *nut) AVIOContext *bc = s->pb; uint64_t tmp, chapter_start, chapter_len; unsigned int stream_id_plus1, count; - int chapter_id, i, ret = 0; - int64_t value, end; + int i, ret = 0; + int64_t chapter_id, value, end; char name[256], str_value[1024], type_str[256]; const char *type; int *event_flags = NULL; diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h index 629a1d626..bf982bfe1 100644 --- a/libavformat/oggdec.h +++ b/libavformat/oggdec.h @@ -87,7 +87,7 @@ struct ogg_stream { int start_trimming; ///< set the number of packets to drop from the start int end_trimming; ///< set the number of packets to drop from the end uint8_t *new_metadata; - unsigned int new_metadata_size; + buffer_size_t new_metadata_size; void *private; }; diff --git a/libavformat/oma.c b/libavformat/oma.c index f7ae3c994..7282d464a 100644 --- a/libavformat/oma.c +++ b/libavformat/oma.c @@ -18,10 +18,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include "libavcodec/codec_id.h" #include "internal.h" #include "oma.h" -#include "libavcodec/avcodec.h" -#include "libavutil/channel_layout.h" const uint16_t ff_oma_srate_tab[8] = { 320, 441, 480, 882, 960, 0 }; @@ -35,16 +35,4 @@ const AVCodecTag ff_oma_codec_tags[] = { { 0 }, }; -/** map ATRAC-X channel id to internal channel layout */ -const uint64_t ff_oma_chid_to_native_layout[7] = { - AV_CH_LAYOUT_MONO, - AV_CH_LAYOUT_STEREO, - AV_CH_LAYOUT_SURROUND, - AV_CH_LAYOUT_4POINT0, - AV_CH_LAYOUT_5POINT1_BACK, - AV_CH_LAYOUT_6POINT1_BACK, - AV_CH_LAYOUT_7POINT1 -}; - -/** map ATRAC-X channel id to total number of channels */ -const int ff_oma_chid_to_num_channels[7] = {1, 2, 3, 4, 6, 7, 8}; +const AVCodecTag *const ff_oma_codec_tags_list[] = { ff_oma_codec_tags, NULL }; diff --git a/libavformat/oma.h b/libavformat/oma.h index 36fd0125e..85d5932f1 100644 --- a/libavformat/oma.h +++ b/libavformat/oma.h @@ -42,8 +42,6 @@ enum { extern const uint16_t ff_oma_srate_tab[8]; extern const AVCodecTag ff_oma_codec_tags[]; - -extern const uint64_t ff_oma_chid_to_native_layout[7]; -extern const int ff_oma_chid_to_num_channels[7]; +extern const AVCodecTag *const ff_oma_codec_tags_list[]; #endif /* AVFORMAT_OMA_H */ diff --git a/libavformat/omadec.c b/libavformat/omadec.c index 5675d86e7..d31b475fd 100644 --- a/libavformat/omadec.c +++ b/libavformat/omadec.c @@ -59,6 +59,20 @@ static const uint64_t leaf_table[] = { 0x1573cd93da7df623, 0x47f98d79620dd535 }; +/** map ATRAC-X channel id to internal channel layout */ +static const uint64_t oma_chid_to_native_layout[7] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_6POINT1_BACK, + AV_CH_LAYOUT_7POINT1 +}; + +/** map ATRAC-X channel id to total number of channels */ +static const int oma_chid_to_num_channels[7] = { 1, 2, 3, 4, 6, 7, 8 }; + typedef struct OMAContext { uint64_t content_start; int encrypted; @@ -492,8 +506,8 @@ static int oma_read_header(AVFormatContext *s) ret = AVERROR_INVALIDDATA; goto fail; } - st->codecpar->channel_layout = ff_oma_chid_to_native_layout[channel_id - 1]; - st->codecpar->channels = ff_oma_chid_to_num_channels[channel_id - 1]; + st->codecpar->channel_layout = oma_chid_to_native_layout[channel_id - 1]; + st->codecpar->channels = oma_chid_to_num_channels[channel_id - 1]; framesize = ((codec_params & 0x3FF) * 8) + 8; samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100; if (!samplerate) { @@ -621,5 +635,5 @@ AVInputFormat ff_oma_demuxer = { .read_close = oma_read_close, .flags = AVFMT_GENERIC_INDEX, .extensions = "oma,omg,aa3", - .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0}, + .codec_tag = ff_oma_codec_tags_list, }; diff --git a/libavformat/omaenc.c b/libavformat/omaenc.c index 7952808bf..d3c4f6202 100644 --- a/libavformat/omaenc.c +++ b/libavformat/omaenc.c @@ -102,6 +102,6 @@ AVOutputFormat ff_oma_muxer = { .audio_codec = AV_CODEC_ID_ATRAC3, .write_header = oma_write_header, .write_packet = ff_raw_write_packet, - .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0}, + .codec_tag = ff_oma_codec_tags_list, .flags = AVFMT_NOTIMESTAMPS, }; diff --git a/libavformat/options.c b/libavformat/options.c index e14510504..07403b533 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -21,6 +21,7 @@ #include "avio_internal.h" #include "internal.h" +#include "libavutil/avassert.h" #include "libavutil/internal.h" #include "libavutil/opt.h" @@ -53,33 +54,96 @@ static void *format_child_next(void *obj, void *prev) return NULL; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *format_child_class_next(const AVClass *prev) { - AVInputFormat *ifmt = NULL; - AVOutputFormat *ofmt = NULL; + const AVInputFormat *ifmt = NULL; + const AVOutputFormat *ofmt = NULL; + void *ifmt_iter = NULL, *ofmt_iter = NULL; if (!prev) return &ff_avio_class; - while ((ifmt = av_iformat_next(ifmt))) + while ((ifmt = av_demuxer_iterate(&ifmt_iter))) if (ifmt->priv_class == prev) break; - if (!ifmt) - while ((ofmt = av_oformat_next(ofmt))) + if (!ifmt) { + ifmt_iter = NULL; + while ((ofmt = av_muxer_iterate(&ofmt_iter))) if (ofmt->priv_class == prev) break; - if (!ofmt) - while (ifmt = av_iformat_next(ifmt)) + } + if (!ofmt) { + ofmt_iter = NULL; + while ((ifmt = av_demuxer_iterate(&ifmt_iter))) if (ifmt->priv_class) return ifmt->priv_class; + } - while (ofmt = av_oformat_next(ofmt)) + while ((ofmt = av_muxer_iterate(&ofmt_iter))) if (ofmt->priv_class) return ofmt->priv_class; return NULL; } +#endif + +enum { + CHILD_CLASS_ITER_AVIO = 0, + CHILD_CLASS_ITER_MUX, + CHILD_CLASS_ITER_DEMUX, + CHILD_CLASS_ITER_DONE, + +}; + +#define ITER_STATE_SHIFT 16 + +static const AVClass *format_child_class_iterate(void **iter) +{ + // we use the low 16 bits of iter as the value to be passed to + // av_(de)muxer_iterate() + void *val = (void*)(((uintptr_t)*iter) & ((1 << ITER_STATE_SHIFT) - 1)); + unsigned int state = ((uintptr_t)*iter) >> ITER_STATE_SHIFT; + const AVClass *ret = NULL; + + if (state == CHILD_CLASS_ITER_AVIO) { + ret = &ff_avio_class; + state++; + goto finish; + } + + if (state == CHILD_CLASS_ITER_MUX) { + const AVOutputFormat *ofmt; + + while ((ofmt = av_muxer_iterate(&val))) { + ret = ofmt->priv_class; + if (ret) + goto finish; + } + + val = NULL; + state++; + } + + if (state == CHILD_CLASS_ITER_DEMUX) { + const AVInputFormat *ifmt; + + while ((ifmt = av_demuxer_iterate(&val))) { + ret = ifmt->priv_class; + if (ret) + goto finish; + } + val = NULL; + state++; + } + +finish: + // make sure none av_(de)muxer_iterate does not set the high bits of val + av_assert0(!((uintptr_t)val >> ITER_STATE_SHIFT)); + *iter = (void*)((uintptr_t)val | (state << ITER_STATE_SHIFT)); + return ret; +} static AVClassCategory get_category(void *ptr) { @@ -94,7 +158,10 @@ static const AVClass av_format_context_class = { .option = avformat_options, .version = LIBAVUTIL_VERSION_INT, .child_next = format_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = format_child_class_next, +#endif + .child_class_iterate = format_child_class_iterate, .category = AV_CLASS_CATEGORY_MUXER, .get_category = get_category, }; @@ -153,6 +220,15 @@ AVFormatContext *avformat_alloc_context(void) av_free(ic); return NULL; } + internal->pkt = av_packet_alloc(); + internal->parse_pkt = av_packet_alloc(); + if (!internal->pkt || !internal->parse_pkt) { + av_packet_free(&internal->pkt); + av_packet_free(&internal->parse_pkt); + av_free(internal); + av_free(ic); + return NULL; + } avformat_get_context_defaults(ic); ic->internal = internal; ic->internal->offset = AV_NOPTS_VALUE; diff --git a/libavformat/paf.c b/libavformat/paf.c index 958711164..dbc50100f 100644 --- a/libavformat/paf.c +++ b/libavformat/paf.c @@ -136,6 +136,10 @@ static int read_header(AVFormatContext *s) p->start_offset = avio_rl32(pb); p->max_video_blks = avio_rl32(pb); p->max_audio_blks = avio_rl32(pb); + + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; + if (p->buffer_size < 175 || p->max_audio_blks < 2 || p->max_video_blks < 1 || @@ -149,11 +153,11 @@ static int read_header(AVFormatContext *s) p->frame_blks > INT_MAX / sizeof(uint32_t)) return AVERROR_INVALIDDATA; - p->blocks_count_table = av_mallocz(p->nb_frames * + p->blocks_count_table = av_malloc_array(p->nb_frames, sizeof(*p->blocks_count_table)); - p->frames_offset_table = av_mallocz(p->nb_frames * + p->frames_offset_table = av_malloc_array(p->nb_frames, sizeof(*p->frames_offset_table)); - p->blocks_offset_table = av_mallocz(p->frame_blks * + p->blocks_offset_table = av_malloc_array(p->frame_blks, sizeof(*p->blocks_offset_table)); p->video_size = p->max_video_blks * p->buffer_size; diff --git a/libavformat/pcmdec.c b/libavformat/pcmdec.c index 9895af03a..9b552936a 100644 --- a/libavformat/pcmdec.c +++ b/libavformat/pcmdec.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avstring.h" #include "avformat.h" #include "internal.h" #include "pcm.h" @@ -35,36 +36,33 @@ typedef struct PCMAudioDemuxerContext { static int pcm_read_header(AVFormatContext *s) { PCMAudioDemuxerContext *s1 = s->priv_data; + AVCodecParameters *par; AVStream *st; uint8_t *mime_type = NULL; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); + par = st->codecpar; - - st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; - st->codecpar->codec_id = s->iformat->raw_codec_id; - st->codecpar->sample_rate = s1->sample_rate; - st->codecpar->channels = s1->channels; + par->codec_type = AVMEDIA_TYPE_AUDIO; + par->codec_id = s->iformat->raw_codec_id; + par->sample_rate = s1->sample_rate; + par->channels = s1->channels; av_opt_get(s->pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type); if (mime_type && s->iformat->mime_type) { int rate = 0, channels = 0, little_endian = 0; - size_t len = strlen(s->iformat->mime_type); - if (!av_strncasecmp(s->iformat->mime_type, mime_type, len)) { /* audio/L16 */ - uint8_t *options = mime_type + len; - len = strlen(mime_type); - while (options < mime_type + len) { - options = strstr(options, ";"); - if (!options++) - break; + const char *options; + if (av_stristart(mime_type, s->iformat->mime_type, &options)) { /* audio/L16 */ + while (options = strchr(options, ';')) { + options++; if (!rate) sscanf(options, " rate=%d", &rate); if (!channels) sscanf(options, " channels=%d", &channels); if (!little_endian) { - char val[14]; /* sizeof("little-endian") == 14 */ + char val[sizeof("little-endian")]; if (sscanf(options, " endianness=%13s", val) == 1) { little_endian = strcmp(val, "little-endian") == 0; } @@ -77,24 +75,22 @@ static int pcm_read_header(AVFormatContext *s) av_freep(&mime_type); return AVERROR_INVALIDDATA; } - st->codecpar->sample_rate = rate; + par->sample_rate = rate; if (channels > 0) - st->codecpar->channels = channels; + par->channels = channels; if (little_endian) - st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; + par->codec_id = AV_CODEC_ID_PCM_S16LE; } } av_freep(&mime_type); - st->codecpar->bits_per_coded_sample = - av_get_bits_per_sample(st->codecpar->codec_id); + par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id); - av_assert0(st->codecpar->bits_per_coded_sample > 0); + av_assert0(par->bits_per_coded_sample > 0); - st->codecpar->block_align = - st->codecpar->bits_per_coded_sample * st->codecpar->channels / 8; + par->block_align = par->bits_per_coded_sample * par->channels / 8; - avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); + avpriv_set_pts_info(st, 64, 1, par->sample_rate); return 0; } @@ -104,7 +100,8 @@ static const AVOption pcm_options[] = { { NULL }, }; -#define PCMDEF(name_, long_name_, ext, codec, ...) \ +#define PCMDEF_0(name_, long_name_, ext, codec, ...) +#define PCMDEF_1(name_, long_name_, ext, codec, ...) \ static const AVClass name_ ## _demuxer_class = { \ .class_name = #name_ " demuxer", \ .item_name = av_default_item_name, \ @@ -124,70 +121,40 @@ AVInputFormat ff_pcm_ ## name_ ## _demuxer = { \ .priv_class = &name_ ## _demuxer_class, \ __VA_ARGS__ \ }; +#define PCMDEF_2(name, long_name, ext, codec, enabled, ...) \ + PCMDEF_ ## enabled(name, long_name, ext, codec, __VA_ARGS__) +#define PCMDEF_3(name, long_name, ext, codec, config, ...) \ + PCMDEF_2(name, long_name, ext, codec, config, __VA_ARGS__) +#define PCMDEF_EXT(name, long_name, ext, uppercase, ...) \ + PCMDEF_3(name, long_name, ext, AV_CODEC_ID_PCM_ ## uppercase, \ + CONFIG_PCM_ ## uppercase ## _DEMUXER, __VA_ARGS__) +#define PCMDEF(name, long_name, ext, uppercase) \ + PCMDEF_EXT(name, long_name, ext, uppercase, ) -PCMDEF(f64be, "PCM 64-bit floating-point big-endian", - NULL, AV_CODEC_ID_PCM_F64BE) - -PCMDEF(f64le, "PCM 64-bit floating-point little-endian", - NULL, AV_CODEC_ID_PCM_F64LE) - -PCMDEF(f32be, "PCM 32-bit floating-point big-endian", - NULL, AV_CODEC_ID_PCM_F32BE) - -PCMDEF(f32le, "PCM 32-bit floating-point little-endian", - NULL, AV_CODEC_ID_PCM_F32LE) - -PCMDEF(s32be, "PCM signed 32-bit big-endian", - NULL, AV_CODEC_ID_PCM_S32BE) - -PCMDEF(s32le, "PCM signed 32-bit little-endian", - NULL, AV_CODEC_ID_PCM_S32LE) - -PCMDEF(s24be, "PCM signed 24-bit big-endian", - NULL, AV_CODEC_ID_PCM_S24BE) - -PCMDEF(s24le, "PCM signed 24-bit little-endian", - NULL, AV_CODEC_ID_PCM_S24LE) - -PCMDEF(s16be, "PCM signed 16-bit big-endian", - AV_NE("sw", NULL), AV_CODEC_ID_PCM_S16BE, .mime_type = "audio/L16") - -PCMDEF(s16le, "PCM signed 16-bit little-endian", - AV_NE(NULL, "sw"), AV_CODEC_ID_PCM_S16LE) - -PCMDEF(s8, "PCM signed 8-bit", - "sb", AV_CODEC_ID_PCM_S8) - -PCMDEF(u32be, "PCM unsigned 32-bit big-endian", - NULL, AV_CODEC_ID_PCM_U32BE) - -PCMDEF(u32le, "PCM unsigned 32-bit little-endian", - NULL, AV_CODEC_ID_PCM_U32LE) - -PCMDEF(u24be, "PCM unsigned 24-bit big-endian", - NULL, AV_CODEC_ID_PCM_U24BE) - -PCMDEF(u24le, "PCM unsigned 24-bit little-endian", - NULL, AV_CODEC_ID_PCM_U24LE) - -PCMDEF(u16be, "PCM unsigned 16-bit big-endian", - AV_NE("uw", NULL), AV_CODEC_ID_PCM_U16BE) - -PCMDEF(u16le, "PCM unsigned 16-bit little-endian", - AV_NE(NULL, "uw"), AV_CODEC_ID_PCM_U16LE) - -PCMDEF(u8, "PCM unsigned 8-bit", - "ub", AV_CODEC_ID_PCM_U8) - -PCMDEF(alaw, "PCM A-law", - "al", AV_CODEC_ID_PCM_ALAW) - -PCMDEF(mulaw, "PCM mu-law", - "ul", AV_CODEC_ID_PCM_MULAW) - -PCMDEF(vidc, "PCM Archimedes VIDC", - NULL, AV_CODEC_ID_PCM_VIDC) +PCMDEF(f64be, "PCM 64-bit floating-point big-endian", NULL, F64BE) +PCMDEF(f64le, "PCM 64-bit floating-point little-endian", NULL, F64LE) +PCMDEF(f32be, "PCM 32-bit floating-point big-endian", NULL, F32BE) +PCMDEF(f32le, "PCM 32-bit floating-point little-endian", NULL, F32LE) +PCMDEF(s32be, "PCM signed 32-bit big-endian", NULL, S32BE) +PCMDEF(s32le, "PCM signed 32-bit little-endian", NULL, S32LE) +PCMDEF(s24be, "PCM signed 24-bit big-endian", NULL, S24BE) +PCMDEF(s24le, "PCM signed 24-bit little-endian", NULL, S24LE) +PCMDEF_EXT(s16be, "PCM signed 16-bit big-endian", + AV_NE("sw", NULL), S16BE, .mime_type = "audio/L16") +PCMDEF(s16le, "PCM signed 16-bit little-endian", AV_NE(NULL, "sw"), S16LE) +PCMDEF(s8, "PCM signed 8-bit", "sb", S8) +PCMDEF(u32be, "PCM unsigned 32-bit big-endian", NULL, U32BE) +PCMDEF(u32le, "PCM unsigned 32-bit little-endian", NULL, U32LE) +PCMDEF(u24be, "PCM unsigned 24-bit big-endian", NULL, U24BE) +PCMDEF(u24le, "PCM unsigned 24-bit little-endian", NULL, U24LE) +PCMDEF(u16be, "PCM unsigned 16-bit big-endian", AV_NE("uw", NULL), U16BE) +PCMDEF(u16le, "PCM unsigned 16-bit little-endian", AV_NE(NULL, "uw"), U16LE) +PCMDEF(u8, "PCM unsigned 8-bit", "ub", U8) +PCMDEF(alaw, "PCM A-law", "al", ALAW) +PCMDEF(mulaw, "PCM mu-law", "ul", MULAW) +PCMDEF(vidc, "PCM Archimedes VIDC", NULL, VIDC) +#if CONFIG_SLN_DEMUXER static const AVOption sln_options[] = { { "sample_rate", "", offsetof(PCMAudioDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.i64 = 8000}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, { "channels", "", offsetof(PCMAudioDemuxerContext, channels), AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, @@ -213,3 +180,4 @@ AVInputFormat ff_sln_demuxer = { .raw_codec_id = AV_CODEC_ID_PCM_S16LE, .priv_class = &sln_demuxer_class, }; +#endif diff --git a/libavformat/pcmenc.c b/libavformat/pcmenc.c index 1760b3bef..050b9c4aa 100644 --- a/libavformat/pcmenc.c +++ b/libavformat/pcmenc.c @@ -22,7 +22,8 @@ #include "avformat.h" #include "rawenc.h" -#define PCMDEF(name_, long_name_, ext, codec) \ +#define PCMDEF_0(name_, long_name_, ext, codec) +#define PCMDEF_1(name_, long_name_, ext, codec) \ AVOutputFormat ff_pcm_ ## name_ ## _muxer = { \ .name = #name_, \ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ @@ -32,66 +33,32 @@ AVOutputFormat ff_pcm_ ## name_ ## _muxer = { \ .write_packet = ff_raw_write_packet, \ .flags = AVFMT_NOTIMESTAMPS, \ }; +#define PCMDEF_2(name, long_name, ext, codec, enabled) \ + PCMDEF_ ## enabled(name, long_name, ext, codec) +#define PCMDEF_3(name, long_name, ext, codec, config) \ + PCMDEF_2(name, long_name, ext, codec, config) +#define PCMDEF(name, long_name, ext, uppercase) \ + PCMDEF_3(name, long_name, ext, AV_CODEC_ID_PCM_ ## uppercase, \ + CONFIG_PCM_ ## uppercase ## _MUXER) -PCMDEF(f64be, "PCM 64-bit floating-point big-endian", - NULL, AV_CODEC_ID_PCM_F64BE) - -PCMDEF(f64le, "PCM 64-bit floating-point little-endian", - NULL, AV_CODEC_ID_PCM_F64LE) - -PCMDEF(f32be, "PCM 32-bit floating-point big-endian", - NULL, AV_CODEC_ID_PCM_F32BE) - -PCMDEF(f32le, "PCM 32-bit floating-point little-endian", - NULL, AV_CODEC_ID_PCM_F32LE) - -PCMDEF(s32be, "PCM signed 32-bit big-endian", - NULL, AV_CODEC_ID_PCM_S32BE) - -PCMDEF(s32le, "PCM signed 32-bit little-endian", - NULL, AV_CODEC_ID_PCM_S32LE) - -PCMDEF(s24be, "PCM signed 24-bit big-endian", - NULL, AV_CODEC_ID_PCM_S24BE) - -PCMDEF(s24le, "PCM signed 24-bit little-endian", - NULL, AV_CODEC_ID_PCM_S24LE) - -PCMDEF(s16be, "PCM signed 16-bit big-endian", - AV_NE("sw", NULL), AV_CODEC_ID_PCM_S16BE) - -PCMDEF(s16le, "PCM signed 16-bit little-endian", - AV_NE(NULL, "sw"), AV_CODEC_ID_PCM_S16LE) - -PCMDEF(s8, "PCM signed 8-bit", - "sb", AV_CODEC_ID_PCM_S8) - -PCMDEF(u32be, "PCM unsigned 32-bit big-endian", - NULL, AV_CODEC_ID_PCM_U32BE) - -PCMDEF(u32le, "PCM unsigned 32-bit little-endian", - NULL, AV_CODEC_ID_PCM_U32LE) - -PCMDEF(u24be, "PCM unsigned 24-bit big-endian", - NULL, AV_CODEC_ID_PCM_U24BE) - -PCMDEF(u24le, "PCM unsigned 24-bit little-endian", - NULL, AV_CODEC_ID_PCM_U24LE) - -PCMDEF(u16be, "PCM unsigned 16-bit big-endian", - AV_NE("uw", NULL), AV_CODEC_ID_PCM_U16BE) - -PCMDEF(u16le, "PCM unsigned 16-bit little-endian", - AV_NE(NULL, "uw"), AV_CODEC_ID_PCM_U16LE) - -PCMDEF(u8, "PCM unsigned 8-bit", - "ub", AV_CODEC_ID_PCM_U8) - -PCMDEF(alaw, "PCM A-law", - "al", AV_CODEC_ID_PCM_ALAW) - -PCMDEF(mulaw, "PCM mu-law", - "ul", AV_CODEC_ID_PCM_MULAW) - -PCMDEF(vidc, "PCM Archimedes VIDC", - NULL, AV_CODEC_ID_PCM_VIDC) +PCMDEF(f64be, "PCM 64-bit floating-point big-endian", NULL, F64BE) +PCMDEF(f64le, "PCM 64-bit floating-point little-endian", NULL, F64LE) +PCMDEF(f32be, "PCM 32-bit floating-point big-endian", NULL, F32BE) +PCMDEF(f32le, "PCM 32-bit floating-point little-endian", NULL, F32LE) +PCMDEF(s32be, "PCM signed 32-bit big-endian", NULL, S32BE) +PCMDEF(s32le, "PCM signed 32-bit little-endian", NULL, S32LE) +PCMDEF(s24be, "PCM signed 24-bit big-endian", NULL, S24BE) +PCMDEF(s24le, "PCM signed 24-bit little-endian", NULL, S24LE) +PCMDEF(s16be, "PCM signed 16-bit big-endian", AV_NE("sw", NULL), S16BE) +PCMDEF(s16le, "PCM signed 16-bit little-endian", AV_NE(NULL, "sw"), S16LE) +PCMDEF(s8, "PCM signed 8-bit", "sb", S8) +PCMDEF(u32be, "PCM unsigned 32-bit big-endian", NULL, U32BE) +PCMDEF(u32le, "PCM unsigned 32-bit little-endian", NULL, U32LE) +PCMDEF(u24be, "PCM unsigned 24-bit big-endian", NULL, U24BE) +PCMDEF(u24le, "PCM unsigned 24-bit little-endian", NULL, U24LE) +PCMDEF(u16be, "PCM unsigned 16-bit big-endian", AV_NE("uw", NULL), U16BE) +PCMDEF(u16le, "PCM unsigned 16-bit little-endian", AV_NE(NULL, "uw"), U16LE) +PCMDEF(u8, "PCM unsigned 8-bit", "ub", U8) +PCMDEF(alaw, "PCM A-law", "al", ALAW) +PCMDEF(mulaw, "PCM mu-law", "ul", MULAW) +PCMDEF(vidc, "PCM Archimedes VIDC", NULL, VIDC) diff --git a/libavformat/pjsdec.c b/libavformat/pjsdec.c index e30c23d83..1f1d51c40 100644 --- a/libavformat/pjsdec.c +++ b/libavformat/pjsdec.c @@ -67,7 +67,6 @@ static int pjs_read_header(AVFormatContext *s) { PJSContext *pjs = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - int res = 0; if (!st) return AVERROR(ENOMEM); @@ -105,7 +104,7 @@ static int pjs_read_header(AVFormatContext *s) } ff_subtitles_queue_finalize(s, &pjs->q); - return res; + return 0; } static int pjs_read_packet(AVFormatContext *s, AVPacket *pkt) diff --git a/libavformat/pp_bnk.c b/libavformat/pp_bnk.c index 8364de1fd..07eeca3cd 100644 --- a/libavformat/pp_bnk.c +++ b/libavformat/pp_bnk.c @@ -55,6 +55,7 @@ typedef struct PPBnkCtx { int track_count; PPBnkCtxTrack *tracks; uint32_t current_track; + int is_music; } PPBnkCtx; enum { @@ -194,8 +195,12 @@ static int pp_bnk_read_header(AVFormatContext *s) goto fail; } + ctx->is_music = (hdr.flags & PP_BNK_FLAG_MUSIC) && + (ctx->track_count == 2) && + (ctx->tracks[0].data_size == ctx->tracks[1].data_size); + /* Build the streams. */ - for (int i = 0; i < ctx->track_count; i++) { + for (int i = 0; i < (ctx->is_music ? 1 : ctx->track_count); i++) { if (!(st = avformat_new_stream(s, NULL))) { ret = AVERROR(ENOMEM); goto fail; @@ -204,14 +209,21 @@ static int pp_bnk_read_header(AVFormatContext *s) par = st->codecpar; par->codec_type = AVMEDIA_TYPE_AUDIO; par->codec_id = AV_CODEC_ID_ADPCM_IMA_CUNNING; - par->format = AV_SAMPLE_FMT_S16; - par->channel_layout = AV_CH_LAYOUT_MONO; - par->channels = 1; + par->format = AV_SAMPLE_FMT_S16P; + + if (ctx->is_music) { + par->channel_layout = AV_CH_LAYOUT_STEREO; + par->channels = 2; + } else { + par->channel_layout = AV_CH_LAYOUT_MONO; + par->channels = 1; + } + par->sample_rate = hdr.sample_rate; par->bits_per_coded_sample = 4; par->bits_per_raw_sample = 16; par->block_align = 1; - par->bit_rate = par->sample_rate * par->bits_per_coded_sample; + par->bit_rate = par->sample_rate * par->bits_per_coded_sample * par->channels; avpriv_set_pts_info(st, 64, 1, par->sample_rate); st->start_time = 0; @@ -253,18 +265,38 @@ static int pp_bnk_read_packet(AVFormatContext *s, AVPacket *pkt) size = FFMIN(trk->data_size - trk->bytes_read, PP_BNK_MAX_READ_SIZE); - if ((ret = av_get_packet(s->pb, pkt, size)) == AVERROR_EOF) { - /* If we've hit EOF, don't attempt this track again. */ - trk->data_size = trk->bytes_read; - continue; - } else if (ret < 0) { - return ret; + if (!ctx->is_music) { + ret = av_get_packet(s->pb, pkt, size); + if (ret == AVERROR_EOF) { + /* If we've hit EOF, don't attempt this track again. */ + trk->data_size = trk->bytes_read; + continue; + } + } else { + if (!pkt->data && (ret = av_new_packet(pkt, size * 2)) < 0) + return ret; + ret = avio_read(s->pb, pkt->data + size * ctx->current_track, size); + if (ret >= 0 && ret != size) { + /* Only return stereo packets if both tracks could be read. */ + ret = AVERROR_EOF; + } } + if (ret < 0) + return ret; trk->bytes_read += ret; pkt->flags &= ~AV_PKT_FLAG_CORRUPT; - pkt->stream_index = ctx->current_track++; + pkt->stream_index = ctx->current_track; pkt->duration = ret * 2; + + if (ctx->is_music) { + if (pkt->stream_index == 0) + continue; + + pkt->stream_index = 0; + } + + ctx->current_track++; return 0; } @@ -281,6 +313,25 @@ static int pp_bnk_read_close(AVFormatContext *s) return 0; } +static int pp_bnk_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + PPBnkCtx *ctx = s->priv_data; + + if (pts != 0) + return AVERROR(EINVAL); + + if (ctx->is_music) { + av_assert0(stream_index == 0); + ctx->tracks[0].bytes_read = 0; + ctx->tracks[1].bytes_read = 0; + } else { + ctx->tracks[stream_index].bytes_read = 0; + } + + return 0; +} + AVInputFormat ff_pp_bnk_demuxer = { .name = "pp_bnk", .long_name = NULL_IF_CONFIG_SMALL("Pro Pinball Series Soundbank"), @@ -288,5 +339,6 @@ AVInputFormat ff_pp_bnk_demuxer = { .read_probe = pp_bnk_probe, .read_header = pp_bnk_read_header, .read_packet = pp_bnk_read_packet, - .read_close = pp_bnk_read_close + .read_close = pp_bnk_read_close, + .read_seek = pp_bnk_seek, }; diff --git a/libavformat/protocols.c b/libavformat/protocols.c index f1b8eab0f..fb6fabdce 100644 --- a/libavformat/protocols.c +++ b/libavformat/protocols.c @@ -34,6 +34,7 @@ extern const URLProtocol ff_ffrtmphttp_protocol; extern const URLProtocol ff_file_protocol; extern const URLProtocol ff_ftp_protocol; extern const URLProtocol ff_gopher_protocol; +extern const URLProtocol ff_gophers_protocol; extern const URLProtocol ff_hls_protocol; extern const URLProtocol ff_http_protocol; extern const URLProtocol ff_httpproxy_protocol; @@ -61,6 +62,7 @@ extern const URLProtocol ff_udp_protocol; extern const URLProtocol ff_udplite_protocol; extern const URLProtocol ff_unix_protocol; extern const URLProtocol ff_libamqp_protocol; +extern const URLProtocol ff_librist_protocol; extern const URLProtocol ff_librtmp_protocol; extern const URLProtocol ff_librtmpe_protocol; extern const URLProtocol ff_librtmps_protocol; @@ -73,6 +75,7 @@ extern const URLProtocol ff_libzmq_protocol; #include "libavformat/protocol_list.c" +#if FF_API_CHILD_CLASS_NEXT const AVClass *ff_urlcontext_child_class_next(const AVClass *prev) { int i; @@ -91,7 +94,22 @@ const AVClass *ff_urlcontext_child_class_next(const AVClass *prev) return url_protocols[i]->priv_data_class; return NULL; } +#endif +const AVClass *ff_urlcontext_child_class_iterate(void **iter) +{ + const AVClass *ret = NULL; + uintptr_t i; + + for (i = (uintptr_t)*iter; url_protocols[i]; i++) { + ret = url_protocols[i]->priv_data_class; + if (ret) + break; + } + + *iter = (void*)(uintptr_t)(url_protocols[i] ? i + 1 : i); + return ret; +} const char *avio_enum_protocols(void **opaque, int output) { diff --git a/libavformat/qtpalette.c b/libavformat/qtpalette.c index 6833f0cea..046daf0ac 100644 --- a/libavformat/qtpalette.c +++ b/libavformat/qtpalette.c @@ -24,10 +24,302 @@ #include #include -#include "avformat.h" -#include "libavutil/intreadwrite.h" +#include "libavcodec/codec_id.h" +#include "avio.h" #include "qtpalette.h" +static const uint8_t qt_default_palette_2[2 * 3] = { + 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00 +}; + +/* From a screenshot of the "Monitors & Sound" control panel in Mac OS 7.5.5 */ +static const uint8_t qt_default_palette_4[4 * 3] = { + 0xFF, 0xFF, 0xFF, + 0xAC, 0xAC, 0xAC, + 0x55, 0x55, 0x55, + 0x00, 0x00, 0x00 +}; + +/* From a screenshot of the "Monitors & Sound" control panel in Mac OS 7.5.5 */ +static const uint8_t qt_default_palette_16[16 * 3] = { + 0xFF, 0xFF, 0xFF, + 0xFC, 0xF3, 0x05, + 0xFF, 0x64, 0x02, + 0xDD, 0x08, 0x06, + 0xF2, 0x08, 0x84, + 0x46, 0x00, 0xA5, + 0x00, 0x00, 0xD4, + 0x02, 0xAB, 0xEA, + 0x1F, 0xB7, 0x14, + 0x00, 0x64, 0x11, + 0x56, 0x2C, 0x05, + 0x90, 0x71, 0x3A, + 0xC0, 0xC0, 0xC0, + 0x80, 0x80, 0x80, + 0x40, 0x40, 0x40, + 0x00, 0x00, 0x00 +}; + +static const uint8_t qt_default_palette_256[256 * 3] = { + /* 0, 0x00 */ 0xFF, 0xFF, 0xFF, + /* 1, 0x01 */ 0xFF, 0xFF, 0xCC, + /* 2, 0x02 */ 0xFF, 0xFF, 0x99, + /* 3, 0x03 */ 0xFF, 0xFF, 0x66, + /* 4, 0x04 */ 0xFF, 0xFF, 0x33, + /* 5, 0x05 */ 0xFF, 0xFF, 0x00, + /* 6, 0x06 */ 0xFF, 0xCC, 0xFF, + /* 7, 0x07 */ 0xFF, 0xCC, 0xCC, + /* 8, 0x08 */ 0xFF, 0xCC, 0x99, + /* 9, 0x09 */ 0xFF, 0xCC, 0x66, + /* 10, 0x0A */ 0xFF, 0xCC, 0x33, + /* 11, 0x0B */ 0xFF, 0xCC, 0x00, + /* 12, 0x0C */ 0xFF, 0x99, 0xFF, + /* 13, 0x0D */ 0xFF, 0x99, 0xCC, + /* 14, 0x0E */ 0xFF, 0x99, 0x99, + /* 15, 0x0F */ 0xFF, 0x99, 0x66, + /* 16, 0x10 */ 0xFF, 0x99, 0x33, + /* 17, 0x11 */ 0xFF, 0x99, 0x00, + /* 18, 0x12 */ 0xFF, 0x66, 0xFF, + /* 19, 0x13 */ 0xFF, 0x66, 0xCC, + /* 20, 0x14 */ 0xFF, 0x66, 0x99, + /* 21, 0x15 */ 0xFF, 0x66, 0x66, + /* 22, 0x16 */ 0xFF, 0x66, 0x33, + /* 23, 0x17 */ 0xFF, 0x66, 0x00, + /* 24, 0x18 */ 0xFF, 0x33, 0xFF, + /* 25, 0x19 */ 0xFF, 0x33, 0xCC, + /* 26, 0x1A */ 0xFF, 0x33, 0x99, + /* 27, 0x1B */ 0xFF, 0x33, 0x66, + /* 28, 0x1C */ 0xFF, 0x33, 0x33, + /* 29, 0x1D */ 0xFF, 0x33, 0x00, + /* 30, 0x1E */ 0xFF, 0x00, 0xFF, + /* 31, 0x1F */ 0xFF, 0x00, 0xCC, + /* 32, 0x20 */ 0xFF, 0x00, 0x99, + /* 33, 0x21 */ 0xFF, 0x00, 0x66, + /* 34, 0x22 */ 0xFF, 0x00, 0x33, + /* 35, 0x23 */ 0xFF, 0x00, 0x00, + /* 36, 0x24 */ 0xCC, 0xFF, 0xFF, + /* 37, 0x25 */ 0xCC, 0xFF, 0xCC, + /* 38, 0x26 */ 0xCC, 0xFF, 0x99, + /* 39, 0x27 */ 0xCC, 0xFF, 0x66, + /* 40, 0x28 */ 0xCC, 0xFF, 0x33, + /* 41, 0x29 */ 0xCC, 0xFF, 0x00, + /* 42, 0x2A */ 0xCC, 0xCC, 0xFF, + /* 43, 0x2B */ 0xCC, 0xCC, 0xCC, + /* 44, 0x2C */ 0xCC, 0xCC, 0x99, + /* 45, 0x2D */ 0xCC, 0xCC, 0x66, + /* 46, 0x2E */ 0xCC, 0xCC, 0x33, + /* 47, 0x2F */ 0xCC, 0xCC, 0x00, + /* 48, 0x30 */ 0xCC, 0x99, 0xFF, + /* 49, 0x31 */ 0xCC, 0x99, 0xCC, + /* 50, 0x32 */ 0xCC, 0x99, 0x99, + /* 51, 0x33 */ 0xCC, 0x99, 0x66, + /* 52, 0x34 */ 0xCC, 0x99, 0x33, + /* 53, 0x35 */ 0xCC, 0x99, 0x00, + /* 54, 0x36 */ 0xCC, 0x66, 0xFF, + /* 55, 0x37 */ 0xCC, 0x66, 0xCC, + /* 56, 0x38 */ 0xCC, 0x66, 0x99, + /* 57, 0x39 */ 0xCC, 0x66, 0x66, + /* 58, 0x3A */ 0xCC, 0x66, 0x33, + /* 59, 0x3B */ 0xCC, 0x66, 0x00, + /* 60, 0x3C */ 0xCC, 0x33, 0xFF, + /* 61, 0x3D */ 0xCC, 0x33, 0xCC, + /* 62, 0x3E */ 0xCC, 0x33, 0x99, + /* 63, 0x3F */ 0xCC, 0x33, 0x66, + /* 64, 0x40 */ 0xCC, 0x33, 0x33, + /* 65, 0x41 */ 0xCC, 0x33, 0x00, + /* 66, 0x42 */ 0xCC, 0x00, 0xFF, + /* 67, 0x43 */ 0xCC, 0x00, 0xCC, + /* 68, 0x44 */ 0xCC, 0x00, 0x99, + /* 69, 0x45 */ 0xCC, 0x00, 0x66, + /* 70, 0x46 */ 0xCC, 0x00, 0x33, + /* 71, 0x47 */ 0xCC, 0x00, 0x00, + /* 72, 0x48 */ 0x99, 0xFF, 0xFF, + /* 73, 0x49 */ 0x99, 0xFF, 0xCC, + /* 74, 0x4A */ 0x99, 0xFF, 0x99, + /* 75, 0x4B */ 0x99, 0xFF, 0x66, + /* 76, 0x4C */ 0x99, 0xFF, 0x33, + /* 77, 0x4D */ 0x99, 0xFF, 0x00, + /* 78, 0x4E */ 0x99, 0xCC, 0xFF, + /* 79, 0x4F */ 0x99, 0xCC, 0xCC, + /* 80, 0x50 */ 0x99, 0xCC, 0x99, + /* 81, 0x51 */ 0x99, 0xCC, 0x66, + /* 82, 0x52 */ 0x99, 0xCC, 0x33, + /* 83, 0x53 */ 0x99, 0xCC, 0x00, + /* 84, 0x54 */ 0x99, 0x99, 0xFF, + /* 85, 0x55 */ 0x99, 0x99, 0xCC, + /* 86, 0x56 */ 0x99, 0x99, 0x99, + /* 87, 0x57 */ 0x99, 0x99, 0x66, + /* 88, 0x58 */ 0x99, 0x99, 0x33, + /* 89, 0x59 */ 0x99, 0x99, 0x00, + /* 90, 0x5A */ 0x99, 0x66, 0xFF, + /* 91, 0x5B */ 0x99, 0x66, 0xCC, + /* 92, 0x5C */ 0x99, 0x66, 0x99, + /* 93, 0x5D */ 0x99, 0x66, 0x66, + /* 94, 0x5E */ 0x99, 0x66, 0x33, + /* 95, 0x5F */ 0x99, 0x66, 0x00, + /* 96, 0x60 */ 0x99, 0x33, 0xFF, + /* 97, 0x61 */ 0x99, 0x33, 0xCC, + /* 98, 0x62 */ 0x99, 0x33, 0x99, + /* 99, 0x63 */ 0x99, 0x33, 0x66, + /* 100, 0x64 */ 0x99, 0x33, 0x33, + /* 101, 0x65 */ 0x99, 0x33, 0x00, + /* 102, 0x66 */ 0x99, 0x00, 0xFF, + /* 103, 0x67 */ 0x99, 0x00, 0xCC, + /* 104, 0x68 */ 0x99, 0x00, 0x99, + /* 105, 0x69 */ 0x99, 0x00, 0x66, + /* 106, 0x6A */ 0x99, 0x00, 0x33, + /* 107, 0x6B */ 0x99, 0x00, 0x00, + /* 108, 0x6C */ 0x66, 0xFF, 0xFF, + /* 109, 0x6D */ 0x66, 0xFF, 0xCC, + /* 110, 0x6E */ 0x66, 0xFF, 0x99, + /* 111, 0x6F */ 0x66, 0xFF, 0x66, + /* 112, 0x70 */ 0x66, 0xFF, 0x33, + /* 113, 0x71 */ 0x66, 0xFF, 0x00, + /* 114, 0x72 */ 0x66, 0xCC, 0xFF, + /* 115, 0x73 */ 0x66, 0xCC, 0xCC, + /* 116, 0x74 */ 0x66, 0xCC, 0x99, + /* 117, 0x75 */ 0x66, 0xCC, 0x66, + /* 118, 0x76 */ 0x66, 0xCC, 0x33, + /* 119, 0x77 */ 0x66, 0xCC, 0x00, + /* 120, 0x78 */ 0x66, 0x99, 0xFF, + /* 121, 0x79 */ 0x66, 0x99, 0xCC, + /* 122, 0x7A */ 0x66, 0x99, 0x99, + /* 123, 0x7B */ 0x66, 0x99, 0x66, + /* 124, 0x7C */ 0x66, 0x99, 0x33, + /* 125, 0x7D */ 0x66, 0x99, 0x00, + /* 126, 0x7E */ 0x66, 0x66, 0xFF, + /* 127, 0x7F */ 0x66, 0x66, 0xCC, + /* 128, 0x80 */ 0x66, 0x66, 0x99, + /* 129, 0x81 */ 0x66, 0x66, 0x66, + /* 130, 0x82 */ 0x66, 0x66, 0x33, + /* 131, 0x83 */ 0x66, 0x66, 0x00, + /* 132, 0x84 */ 0x66, 0x33, 0xFF, + /* 133, 0x85 */ 0x66, 0x33, 0xCC, + /* 134, 0x86 */ 0x66, 0x33, 0x99, + /* 135, 0x87 */ 0x66, 0x33, 0x66, + /* 136, 0x88 */ 0x66, 0x33, 0x33, + /* 137, 0x89 */ 0x66, 0x33, 0x00, + /* 138, 0x8A */ 0x66, 0x00, 0xFF, + /* 139, 0x8B */ 0x66, 0x00, 0xCC, + /* 140, 0x8C */ 0x66, 0x00, 0x99, + /* 141, 0x8D */ 0x66, 0x00, 0x66, + /* 142, 0x8E */ 0x66, 0x00, 0x33, + /* 143, 0x8F */ 0x66, 0x00, 0x00, + /* 144, 0x90 */ 0x33, 0xFF, 0xFF, + /* 145, 0x91 */ 0x33, 0xFF, 0xCC, + /* 146, 0x92 */ 0x33, 0xFF, 0x99, + /* 147, 0x93 */ 0x33, 0xFF, 0x66, + /* 148, 0x94 */ 0x33, 0xFF, 0x33, + /* 149, 0x95 */ 0x33, 0xFF, 0x00, + /* 150, 0x96 */ 0x33, 0xCC, 0xFF, + /* 151, 0x97 */ 0x33, 0xCC, 0xCC, + /* 152, 0x98 */ 0x33, 0xCC, 0x99, + /* 153, 0x99 */ 0x33, 0xCC, 0x66, + /* 154, 0x9A */ 0x33, 0xCC, 0x33, + /* 155, 0x9B */ 0x33, 0xCC, 0x00, + /* 156, 0x9C */ 0x33, 0x99, 0xFF, + /* 157, 0x9D */ 0x33, 0x99, 0xCC, + /* 158, 0x9E */ 0x33, 0x99, 0x99, + /* 159, 0x9F */ 0x33, 0x99, 0x66, + /* 160, 0xA0 */ 0x33, 0x99, 0x33, + /* 161, 0xA1 */ 0x33, 0x99, 0x00, + /* 162, 0xA2 */ 0x33, 0x66, 0xFF, + /* 163, 0xA3 */ 0x33, 0x66, 0xCC, + /* 164, 0xA4 */ 0x33, 0x66, 0x99, + /* 165, 0xA5 */ 0x33, 0x66, 0x66, + /* 166, 0xA6 */ 0x33, 0x66, 0x33, + /* 167, 0xA7 */ 0x33, 0x66, 0x00, + /* 168, 0xA8 */ 0x33, 0x33, 0xFF, + /* 169, 0xA9 */ 0x33, 0x33, 0xCC, + /* 170, 0xAA */ 0x33, 0x33, 0x99, + /* 171, 0xAB */ 0x33, 0x33, 0x66, + /* 172, 0xAC */ 0x33, 0x33, 0x33, + /* 173, 0xAD */ 0x33, 0x33, 0x00, + /* 174, 0xAE */ 0x33, 0x00, 0xFF, + /* 175, 0xAF */ 0x33, 0x00, 0xCC, + /* 176, 0xB0 */ 0x33, 0x00, 0x99, + /* 177, 0xB1 */ 0x33, 0x00, 0x66, + /* 178, 0xB2 */ 0x33, 0x00, 0x33, + /* 179, 0xB3 */ 0x33, 0x00, 0x00, + /* 180, 0xB4 */ 0x00, 0xFF, 0xFF, + /* 181, 0xB5 */ 0x00, 0xFF, 0xCC, + /* 182, 0xB6 */ 0x00, 0xFF, 0x99, + /* 183, 0xB7 */ 0x00, 0xFF, 0x66, + /* 184, 0xB8 */ 0x00, 0xFF, 0x33, + /* 185, 0xB9 */ 0x00, 0xFF, 0x00, + /* 186, 0xBA */ 0x00, 0xCC, 0xFF, + /* 187, 0xBB */ 0x00, 0xCC, 0xCC, + /* 188, 0xBC */ 0x00, 0xCC, 0x99, + /* 189, 0xBD */ 0x00, 0xCC, 0x66, + /* 190, 0xBE */ 0x00, 0xCC, 0x33, + /* 191, 0xBF */ 0x00, 0xCC, 0x00, + /* 192, 0xC0 */ 0x00, 0x99, 0xFF, + /* 193, 0xC1 */ 0x00, 0x99, 0xCC, + /* 194, 0xC2 */ 0x00, 0x99, 0x99, + /* 195, 0xC3 */ 0x00, 0x99, 0x66, + /* 196, 0xC4 */ 0x00, 0x99, 0x33, + /* 197, 0xC5 */ 0x00, 0x99, 0x00, + /* 198, 0xC6 */ 0x00, 0x66, 0xFF, + /* 199, 0xC7 */ 0x00, 0x66, 0xCC, + /* 200, 0xC8 */ 0x00, 0x66, 0x99, + /* 201, 0xC9 */ 0x00, 0x66, 0x66, + /* 202, 0xCA */ 0x00, 0x66, 0x33, + /* 203, 0xCB */ 0x00, 0x66, 0x00, + /* 204, 0xCC */ 0x00, 0x33, 0xFF, + /* 205, 0xCD */ 0x00, 0x33, 0xCC, + /* 206, 0xCE */ 0x00, 0x33, 0x99, + /* 207, 0xCF */ 0x00, 0x33, 0x66, + /* 208, 0xD0 */ 0x00, 0x33, 0x33, + /* 209, 0xD1 */ 0x00, 0x33, 0x00, + /* 210, 0xD2 */ 0x00, 0x00, 0xFF, + /* 211, 0xD3 */ 0x00, 0x00, 0xCC, + /* 212, 0xD4 */ 0x00, 0x00, 0x99, + /* 213, 0xD5 */ 0x00, 0x00, 0x66, + /* 214, 0xD6 */ 0x00, 0x00, 0x33, + /* 215, 0xD7 */ 0xEE, 0x00, 0x00, + /* 216, 0xD8 */ 0xDD, 0x00, 0x00, + /* 217, 0xD9 */ 0xBB, 0x00, 0x00, + /* 218, 0xDA */ 0xAA, 0x00, 0x00, + /* 219, 0xDB */ 0x88, 0x00, 0x00, + /* 220, 0xDC */ 0x77, 0x00, 0x00, + /* 221, 0xDD */ 0x55, 0x00, 0x00, + /* 222, 0xDE */ 0x44, 0x00, 0x00, + /* 223, 0xDF */ 0x22, 0x00, 0x00, + /* 224, 0xE0 */ 0x11, 0x00, 0x00, + /* 225, 0xE1 */ 0x00, 0xEE, 0x00, + /* 226, 0xE2 */ 0x00, 0xDD, 0x00, + /* 227, 0xE3 */ 0x00, 0xBB, 0x00, + /* 228, 0xE4 */ 0x00, 0xAA, 0x00, + /* 229, 0xE5 */ 0x00, 0x88, 0x00, + /* 230, 0xE6 */ 0x00, 0x77, 0x00, + /* 231, 0xE7 */ 0x00, 0x55, 0x00, + /* 232, 0xE8 */ 0x00, 0x44, 0x00, + /* 233, 0xE9 */ 0x00, 0x22, 0x00, + /* 234, 0xEA */ 0x00, 0x11, 0x00, + /* 235, 0xEB */ 0x00, 0x00, 0xEE, + /* 236, 0xEC */ 0x00, 0x00, 0xDD, + /* 237, 0xED */ 0x00, 0x00, 0xBB, + /* 238, 0xEE */ 0x00, 0x00, 0xAA, + /* 239, 0xEF */ 0x00, 0x00, 0x88, + /* 240, 0xF0 */ 0x00, 0x00, 0x77, + /* 241, 0xF1 */ 0x00, 0x00, 0x55, + /* 242, 0xF2 */ 0x00, 0x00, 0x44, + /* 243, 0xF3 */ 0x00, 0x00, 0x22, + /* 244, 0xF4 */ 0x00, 0x00, 0x11, + /* 245, 0xF5 */ 0xEE, 0xEE, 0xEE, + /* 246, 0xF6 */ 0xDD, 0xDD, 0xDD, + /* 247, 0xF7 */ 0xBB, 0xBB, 0xBB, + /* 248, 0xF8 */ 0xAA, 0xAA, 0xAA, + /* 249, 0xF9 */ 0x88, 0x88, 0x88, + /* 250, 0xFA */ 0x77, 0x77, 0x77, + /* 251, 0xFB */ 0x55, 0x55, 0x55, + /* 252, 0xFC */ 0x44, 0x44, 0x44, + /* 253, 0xFD */ 0x22, 0x22, 0x22, + /* 254, 0xFE */ 0x11, 0x11, 0x11, + /* 255, 0xFF */ 0x00, 0x00, 0x00 +}; + int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette) { int tmp, bit_depth, color_table_id, greyscale, i; @@ -73,13 +365,13 @@ int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette) const uint8_t *color_table; color_count = 1 << bit_depth; if (bit_depth == 1) - color_table = ff_qt_default_palette_2; + color_table = qt_default_palette_2; else if (bit_depth == 2) - color_table = ff_qt_default_palette_4; + color_table = qt_default_palette_4; else if (bit_depth == 4) - color_table = ff_qt_default_palette_16; + color_table = qt_default_palette_16; else - color_table = ff_qt_default_palette_256; + color_table = qt_default_palette_256; for (i = 0; i < color_count; i++) { r = color_table[i * 3 + 0]; g = color_table[i * 3 + 1]; diff --git a/libavformat/qtpalette.h b/libavformat/qtpalette.h index 016e91f1b..18a108eba 100644 --- a/libavformat/qtpalette.h +++ b/libavformat/qtpalette.h @@ -24,299 +24,7 @@ #define AVFORMAT_QTPALETTE_H #include -#include "avformat.h" - -static const uint8_t ff_qt_default_palette_2[2 * 3] = { - 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00 -}; - -/* From a screenshot of the "Monitors & Sound" control panel in Mac OS 7.5.5 */ -static const uint8_t ff_qt_default_palette_4[4 * 3] = { - 0xFF, 0xFF, 0xFF, - 0xAC, 0xAC, 0xAC, - 0x55, 0x55, 0x55, - 0x00, 0x00, 0x00 -}; - -/* From a screenshot of the "Monitors & Sound" control panel in Mac OS 7.5.5 */ -static const uint8_t ff_qt_default_palette_16[16 * 3] = { - 0xFF, 0xFF, 0xFF, - 0xFC, 0xF3, 0x05, - 0xFF, 0x64, 0x02, - 0xDD, 0x08, 0x06, - 0xF2, 0x08, 0x84, - 0x46, 0x00, 0xA5, - 0x00, 0x00, 0xD4, - 0x02, 0xAB, 0xEA, - 0x1F, 0xB7, 0x14, - 0x00, 0x64, 0x11, - 0x56, 0x2C, 0x05, - 0x90, 0x71, 0x3A, - 0xC0, 0xC0, 0xC0, - 0x80, 0x80, 0x80, - 0x40, 0x40, 0x40, - 0x00, 0x00, 0x00 -}; - -static const uint8_t ff_qt_default_palette_256[256 * 3] = { - /* 0, 0x00 */ 0xFF, 0xFF, 0xFF, - /* 1, 0x01 */ 0xFF, 0xFF, 0xCC, - /* 2, 0x02 */ 0xFF, 0xFF, 0x99, - /* 3, 0x03 */ 0xFF, 0xFF, 0x66, - /* 4, 0x04 */ 0xFF, 0xFF, 0x33, - /* 5, 0x05 */ 0xFF, 0xFF, 0x00, - /* 6, 0x06 */ 0xFF, 0xCC, 0xFF, - /* 7, 0x07 */ 0xFF, 0xCC, 0xCC, - /* 8, 0x08 */ 0xFF, 0xCC, 0x99, - /* 9, 0x09 */ 0xFF, 0xCC, 0x66, - /* 10, 0x0A */ 0xFF, 0xCC, 0x33, - /* 11, 0x0B */ 0xFF, 0xCC, 0x00, - /* 12, 0x0C */ 0xFF, 0x99, 0xFF, - /* 13, 0x0D */ 0xFF, 0x99, 0xCC, - /* 14, 0x0E */ 0xFF, 0x99, 0x99, - /* 15, 0x0F */ 0xFF, 0x99, 0x66, - /* 16, 0x10 */ 0xFF, 0x99, 0x33, - /* 17, 0x11 */ 0xFF, 0x99, 0x00, - /* 18, 0x12 */ 0xFF, 0x66, 0xFF, - /* 19, 0x13 */ 0xFF, 0x66, 0xCC, - /* 20, 0x14 */ 0xFF, 0x66, 0x99, - /* 21, 0x15 */ 0xFF, 0x66, 0x66, - /* 22, 0x16 */ 0xFF, 0x66, 0x33, - /* 23, 0x17 */ 0xFF, 0x66, 0x00, - /* 24, 0x18 */ 0xFF, 0x33, 0xFF, - /* 25, 0x19 */ 0xFF, 0x33, 0xCC, - /* 26, 0x1A */ 0xFF, 0x33, 0x99, - /* 27, 0x1B */ 0xFF, 0x33, 0x66, - /* 28, 0x1C */ 0xFF, 0x33, 0x33, - /* 29, 0x1D */ 0xFF, 0x33, 0x00, - /* 30, 0x1E */ 0xFF, 0x00, 0xFF, - /* 31, 0x1F */ 0xFF, 0x00, 0xCC, - /* 32, 0x20 */ 0xFF, 0x00, 0x99, - /* 33, 0x21 */ 0xFF, 0x00, 0x66, - /* 34, 0x22 */ 0xFF, 0x00, 0x33, - /* 35, 0x23 */ 0xFF, 0x00, 0x00, - /* 36, 0x24 */ 0xCC, 0xFF, 0xFF, - /* 37, 0x25 */ 0xCC, 0xFF, 0xCC, - /* 38, 0x26 */ 0xCC, 0xFF, 0x99, - /* 39, 0x27 */ 0xCC, 0xFF, 0x66, - /* 40, 0x28 */ 0xCC, 0xFF, 0x33, - /* 41, 0x29 */ 0xCC, 0xFF, 0x00, - /* 42, 0x2A */ 0xCC, 0xCC, 0xFF, - /* 43, 0x2B */ 0xCC, 0xCC, 0xCC, - /* 44, 0x2C */ 0xCC, 0xCC, 0x99, - /* 45, 0x2D */ 0xCC, 0xCC, 0x66, - /* 46, 0x2E */ 0xCC, 0xCC, 0x33, - /* 47, 0x2F */ 0xCC, 0xCC, 0x00, - /* 48, 0x30 */ 0xCC, 0x99, 0xFF, - /* 49, 0x31 */ 0xCC, 0x99, 0xCC, - /* 50, 0x32 */ 0xCC, 0x99, 0x99, - /* 51, 0x33 */ 0xCC, 0x99, 0x66, - /* 52, 0x34 */ 0xCC, 0x99, 0x33, - /* 53, 0x35 */ 0xCC, 0x99, 0x00, - /* 54, 0x36 */ 0xCC, 0x66, 0xFF, - /* 55, 0x37 */ 0xCC, 0x66, 0xCC, - /* 56, 0x38 */ 0xCC, 0x66, 0x99, - /* 57, 0x39 */ 0xCC, 0x66, 0x66, - /* 58, 0x3A */ 0xCC, 0x66, 0x33, - /* 59, 0x3B */ 0xCC, 0x66, 0x00, - /* 60, 0x3C */ 0xCC, 0x33, 0xFF, - /* 61, 0x3D */ 0xCC, 0x33, 0xCC, - /* 62, 0x3E */ 0xCC, 0x33, 0x99, - /* 63, 0x3F */ 0xCC, 0x33, 0x66, - /* 64, 0x40 */ 0xCC, 0x33, 0x33, - /* 65, 0x41 */ 0xCC, 0x33, 0x00, - /* 66, 0x42 */ 0xCC, 0x00, 0xFF, - /* 67, 0x43 */ 0xCC, 0x00, 0xCC, - /* 68, 0x44 */ 0xCC, 0x00, 0x99, - /* 69, 0x45 */ 0xCC, 0x00, 0x66, - /* 70, 0x46 */ 0xCC, 0x00, 0x33, - /* 71, 0x47 */ 0xCC, 0x00, 0x00, - /* 72, 0x48 */ 0x99, 0xFF, 0xFF, - /* 73, 0x49 */ 0x99, 0xFF, 0xCC, - /* 74, 0x4A */ 0x99, 0xFF, 0x99, - /* 75, 0x4B */ 0x99, 0xFF, 0x66, - /* 76, 0x4C */ 0x99, 0xFF, 0x33, - /* 77, 0x4D */ 0x99, 0xFF, 0x00, - /* 78, 0x4E */ 0x99, 0xCC, 0xFF, - /* 79, 0x4F */ 0x99, 0xCC, 0xCC, - /* 80, 0x50 */ 0x99, 0xCC, 0x99, - /* 81, 0x51 */ 0x99, 0xCC, 0x66, - /* 82, 0x52 */ 0x99, 0xCC, 0x33, - /* 83, 0x53 */ 0x99, 0xCC, 0x00, - /* 84, 0x54 */ 0x99, 0x99, 0xFF, - /* 85, 0x55 */ 0x99, 0x99, 0xCC, - /* 86, 0x56 */ 0x99, 0x99, 0x99, - /* 87, 0x57 */ 0x99, 0x99, 0x66, - /* 88, 0x58 */ 0x99, 0x99, 0x33, - /* 89, 0x59 */ 0x99, 0x99, 0x00, - /* 90, 0x5A */ 0x99, 0x66, 0xFF, - /* 91, 0x5B */ 0x99, 0x66, 0xCC, - /* 92, 0x5C */ 0x99, 0x66, 0x99, - /* 93, 0x5D */ 0x99, 0x66, 0x66, - /* 94, 0x5E */ 0x99, 0x66, 0x33, - /* 95, 0x5F */ 0x99, 0x66, 0x00, - /* 96, 0x60 */ 0x99, 0x33, 0xFF, - /* 97, 0x61 */ 0x99, 0x33, 0xCC, - /* 98, 0x62 */ 0x99, 0x33, 0x99, - /* 99, 0x63 */ 0x99, 0x33, 0x66, - /* 100, 0x64 */ 0x99, 0x33, 0x33, - /* 101, 0x65 */ 0x99, 0x33, 0x00, - /* 102, 0x66 */ 0x99, 0x00, 0xFF, - /* 103, 0x67 */ 0x99, 0x00, 0xCC, - /* 104, 0x68 */ 0x99, 0x00, 0x99, - /* 105, 0x69 */ 0x99, 0x00, 0x66, - /* 106, 0x6A */ 0x99, 0x00, 0x33, - /* 107, 0x6B */ 0x99, 0x00, 0x00, - /* 108, 0x6C */ 0x66, 0xFF, 0xFF, - /* 109, 0x6D */ 0x66, 0xFF, 0xCC, - /* 110, 0x6E */ 0x66, 0xFF, 0x99, - /* 111, 0x6F */ 0x66, 0xFF, 0x66, - /* 112, 0x70 */ 0x66, 0xFF, 0x33, - /* 113, 0x71 */ 0x66, 0xFF, 0x00, - /* 114, 0x72 */ 0x66, 0xCC, 0xFF, - /* 115, 0x73 */ 0x66, 0xCC, 0xCC, - /* 116, 0x74 */ 0x66, 0xCC, 0x99, - /* 117, 0x75 */ 0x66, 0xCC, 0x66, - /* 118, 0x76 */ 0x66, 0xCC, 0x33, - /* 119, 0x77 */ 0x66, 0xCC, 0x00, - /* 120, 0x78 */ 0x66, 0x99, 0xFF, - /* 121, 0x79 */ 0x66, 0x99, 0xCC, - /* 122, 0x7A */ 0x66, 0x99, 0x99, - /* 123, 0x7B */ 0x66, 0x99, 0x66, - /* 124, 0x7C */ 0x66, 0x99, 0x33, - /* 125, 0x7D */ 0x66, 0x99, 0x00, - /* 126, 0x7E */ 0x66, 0x66, 0xFF, - /* 127, 0x7F */ 0x66, 0x66, 0xCC, - /* 128, 0x80 */ 0x66, 0x66, 0x99, - /* 129, 0x81 */ 0x66, 0x66, 0x66, - /* 130, 0x82 */ 0x66, 0x66, 0x33, - /* 131, 0x83 */ 0x66, 0x66, 0x00, - /* 132, 0x84 */ 0x66, 0x33, 0xFF, - /* 133, 0x85 */ 0x66, 0x33, 0xCC, - /* 134, 0x86 */ 0x66, 0x33, 0x99, - /* 135, 0x87 */ 0x66, 0x33, 0x66, - /* 136, 0x88 */ 0x66, 0x33, 0x33, - /* 137, 0x89 */ 0x66, 0x33, 0x00, - /* 138, 0x8A */ 0x66, 0x00, 0xFF, - /* 139, 0x8B */ 0x66, 0x00, 0xCC, - /* 140, 0x8C */ 0x66, 0x00, 0x99, - /* 141, 0x8D */ 0x66, 0x00, 0x66, - /* 142, 0x8E */ 0x66, 0x00, 0x33, - /* 143, 0x8F */ 0x66, 0x00, 0x00, - /* 144, 0x90 */ 0x33, 0xFF, 0xFF, - /* 145, 0x91 */ 0x33, 0xFF, 0xCC, - /* 146, 0x92 */ 0x33, 0xFF, 0x99, - /* 147, 0x93 */ 0x33, 0xFF, 0x66, - /* 148, 0x94 */ 0x33, 0xFF, 0x33, - /* 149, 0x95 */ 0x33, 0xFF, 0x00, - /* 150, 0x96 */ 0x33, 0xCC, 0xFF, - /* 151, 0x97 */ 0x33, 0xCC, 0xCC, - /* 152, 0x98 */ 0x33, 0xCC, 0x99, - /* 153, 0x99 */ 0x33, 0xCC, 0x66, - /* 154, 0x9A */ 0x33, 0xCC, 0x33, - /* 155, 0x9B */ 0x33, 0xCC, 0x00, - /* 156, 0x9C */ 0x33, 0x99, 0xFF, - /* 157, 0x9D */ 0x33, 0x99, 0xCC, - /* 158, 0x9E */ 0x33, 0x99, 0x99, - /* 159, 0x9F */ 0x33, 0x99, 0x66, - /* 160, 0xA0 */ 0x33, 0x99, 0x33, - /* 161, 0xA1 */ 0x33, 0x99, 0x00, - /* 162, 0xA2 */ 0x33, 0x66, 0xFF, - /* 163, 0xA3 */ 0x33, 0x66, 0xCC, - /* 164, 0xA4 */ 0x33, 0x66, 0x99, - /* 165, 0xA5 */ 0x33, 0x66, 0x66, - /* 166, 0xA6 */ 0x33, 0x66, 0x33, - /* 167, 0xA7 */ 0x33, 0x66, 0x00, - /* 168, 0xA8 */ 0x33, 0x33, 0xFF, - /* 169, 0xA9 */ 0x33, 0x33, 0xCC, - /* 170, 0xAA */ 0x33, 0x33, 0x99, - /* 171, 0xAB */ 0x33, 0x33, 0x66, - /* 172, 0xAC */ 0x33, 0x33, 0x33, - /* 173, 0xAD */ 0x33, 0x33, 0x00, - /* 174, 0xAE */ 0x33, 0x00, 0xFF, - /* 175, 0xAF */ 0x33, 0x00, 0xCC, - /* 176, 0xB0 */ 0x33, 0x00, 0x99, - /* 177, 0xB1 */ 0x33, 0x00, 0x66, - /* 178, 0xB2 */ 0x33, 0x00, 0x33, - /* 179, 0xB3 */ 0x33, 0x00, 0x00, - /* 180, 0xB4 */ 0x00, 0xFF, 0xFF, - /* 181, 0xB5 */ 0x00, 0xFF, 0xCC, - /* 182, 0xB6 */ 0x00, 0xFF, 0x99, - /* 183, 0xB7 */ 0x00, 0xFF, 0x66, - /* 184, 0xB8 */ 0x00, 0xFF, 0x33, - /* 185, 0xB9 */ 0x00, 0xFF, 0x00, - /* 186, 0xBA */ 0x00, 0xCC, 0xFF, - /* 187, 0xBB */ 0x00, 0xCC, 0xCC, - /* 188, 0xBC */ 0x00, 0xCC, 0x99, - /* 189, 0xBD */ 0x00, 0xCC, 0x66, - /* 190, 0xBE */ 0x00, 0xCC, 0x33, - /* 191, 0xBF */ 0x00, 0xCC, 0x00, - /* 192, 0xC0 */ 0x00, 0x99, 0xFF, - /* 193, 0xC1 */ 0x00, 0x99, 0xCC, - /* 194, 0xC2 */ 0x00, 0x99, 0x99, - /* 195, 0xC3 */ 0x00, 0x99, 0x66, - /* 196, 0xC4 */ 0x00, 0x99, 0x33, - /* 197, 0xC5 */ 0x00, 0x99, 0x00, - /* 198, 0xC6 */ 0x00, 0x66, 0xFF, - /* 199, 0xC7 */ 0x00, 0x66, 0xCC, - /* 200, 0xC8 */ 0x00, 0x66, 0x99, - /* 201, 0xC9 */ 0x00, 0x66, 0x66, - /* 202, 0xCA */ 0x00, 0x66, 0x33, - /* 203, 0xCB */ 0x00, 0x66, 0x00, - /* 204, 0xCC */ 0x00, 0x33, 0xFF, - /* 205, 0xCD */ 0x00, 0x33, 0xCC, - /* 206, 0xCE */ 0x00, 0x33, 0x99, - /* 207, 0xCF */ 0x00, 0x33, 0x66, - /* 208, 0xD0 */ 0x00, 0x33, 0x33, - /* 209, 0xD1 */ 0x00, 0x33, 0x00, - /* 210, 0xD2 */ 0x00, 0x00, 0xFF, - /* 211, 0xD3 */ 0x00, 0x00, 0xCC, - /* 212, 0xD4 */ 0x00, 0x00, 0x99, - /* 213, 0xD5 */ 0x00, 0x00, 0x66, - /* 214, 0xD6 */ 0x00, 0x00, 0x33, - /* 215, 0xD7 */ 0xEE, 0x00, 0x00, - /* 216, 0xD8 */ 0xDD, 0x00, 0x00, - /* 217, 0xD9 */ 0xBB, 0x00, 0x00, - /* 218, 0xDA */ 0xAA, 0x00, 0x00, - /* 219, 0xDB */ 0x88, 0x00, 0x00, - /* 220, 0xDC */ 0x77, 0x00, 0x00, - /* 221, 0xDD */ 0x55, 0x00, 0x00, - /* 222, 0xDE */ 0x44, 0x00, 0x00, - /* 223, 0xDF */ 0x22, 0x00, 0x00, - /* 224, 0xE0 */ 0x11, 0x00, 0x00, - /* 225, 0xE1 */ 0x00, 0xEE, 0x00, - /* 226, 0xE2 */ 0x00, 0xDD, 0x00, - /* 227, 0xE3 */ 0x00, 0xBB, 0x00, - /* 228, 0xE4 */ 0x00, 0xAA, 0x00, - /* 229, 0xE5 */ 0x00, 0x88, 0x00, - /* 230, 0xE6 */ 0x00, 0x77, 0x00, - /* 231, 0xE7 */ 0x00, 0x55, 0x00, - /* 232, 0xE8 */ 0x00, 0x44, 0x00, - /* 233, 0xE9 */ 0x00, 0x22, 0x00, - /* 234, 0xEA */ 0x00, 0x11, 0x00, - /* 235, 0xEB */ 0x00, 0x00, 0xEE, - /* 236, 0xEC */ 0x00, 0x00, 0xDD, - /* 237, 0xED */ 0x00, 0x00, 0xBB, - /* 238, 0xEE */ 0x00, 0x00, 0xAA, - /* 239, 0xEF */ 0x00, 0x00, 0x88, - /* 240, 0xF0 */ 0x00, 0x00, 0x77, - /* 241, 0xF1 */ 0x00, 0x00, 0x55, - /* 242, 0xF2 */ 0x00, 0x00, 0x44, - /* 243, 0xF3 */ 0x00, 0x00, 0x22, - /* 244, 0xF4 */ 0x00, 0x00, 0x11, - /* 245, 0xF5 */ 0xEE, 0xEE, 0xEE, - /* 246, 0xF6 */ 0xDD, 0xDD, 0xDD, - /* 247, 0xF7 */ 0xBB, 0xBB, 0xBB, - /* 248, 0xF8 */ 0xAA, 0xAA, 0xAA, - /* 249, 0xF9 */ 0x88, 0x88, 0x88, - /* 250, 0xFA */ 0x77, 0x77, 0x77, - /* 251, 0xFB */ 0x55, 0x55, 0x55, - /* 252, 0xFC */ 0x44, 0x44, 0x44, - /* 253, 0xFD */ 0x22, 0x22, 0x22, - /* 254, 0xFE */ 0x11, 0x11, 0x11, - /* 255, 0xFF */ 0x00, 0x00, 0x00 -}; +#include "avio.h" /** * Retrieve the palette (or "color table" in QuickTime terms), either diff --git a/libavformat/r3d.c b/libavformat/r3d.c index edd80ab4f..9de0fb52c 100644 --- a/libavformat/r3d.c +++ b/libavformat/r3d.c @@ -56,6 +56,7 @@ static int r3d_read_red1(AVFormatContext *s) R3DContext *r3d = s->priv_data; char filename[258]; int tmp; + int ret; int av_unused tmp2; AVRational framerate; @@ -97,7 +98,9 @@ static int r3d_read_red1(AVFormatContext *s) r3d->audio_channels = avio_r8(s->pb); // audio channels av_log(s, AV_LOG_TRACE, "audio channels %d\n", tmp); - avio_read(s->pb, filename, 257); + ret = avio_read(s->pb, filename, 257); + if (ret < 257) + return ret < 0 ? ret : AVERROR_EOF; filename[sizeof(filename)-1] = 0; av_dict_set(&st->metadata, "filename", filename, 0); diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c index 10c37c5cb..122afca1b 100644 --- a/libavformat/rawdec.c +++ b/libavformat/rawdec.c @@ -208,6 +208,8 @@ static int mjpeg_probe(const AVProbeData *p) return AVPROBE_SCORE_EXTENSION / 2; return AVPROBE_SCORE_EXTENSION / 4; } + if (!nb_invalid && nb_frames) + return AVPROBE_SCORE_EXTENSION / 4; return 0; } diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c index 32704f9bf..caec297f4 100644 --- a/libavformat/rawenc.c +++ b/libavformat/rawenc.c @@ -64,7 +64,7 @@ AVOutputFormat ff_ac3_muxer = { .extensions = "ac3", .audio_codec = AV_CODEC_ID_AC3, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -96,7 +96,7 @@ AVOutputFormat ff_adx_muxer = { .extensions = "adx", .audio_codec = AV_CODEC_ID_ADPCM_ADX, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .write_trailer = adx_write_trailer, .flags = AVFMT_NOTIMESTAMPS, @@ -110,7 +110,7 @@ AVOutputFormat ff_aptx_muxer = { .extensions = "aptx", .audio_codec = AV_CODEC_ID_APTX, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -123,7 +123,7 @@ AVOutputFormat ff_aptx_hd_muxer = { .extensions = "aptxhd", .audio_codec = AV_CODEC_ID_APTX_HD, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -136,7 +136,7 @@ AVOutputFormat ff_avs2_muxer = { .extensions = "avs,avs2", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_AVS2, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -149,7 +149,7 @@ AVOutputFormat ff_cavsvideo_muxer = { .extensions = "cavs", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_CAVS, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -161,7 +161,7 @@ AVOutputFormat ff_codec2raw_muxer = { .long_name = NULL_IF_CONFIG_SMALL("raw codec2 muxer"), .audio_codec = AV_CODEC_ID_CODEC2, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -172,7 +172,7 @@ AVOutputFormat ff_codec2raw_muxer = { AVOutputFormat ff_data_muxer = { .name = "data", .long_name = NULL_IF_CONFIG_SMALL("raw data"), - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -185,7 +185,7 @@ AVOutputFormat ff_dirac_muxer = { .extensions = "drc,vc2", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_DIRAC, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -198,7 +198,7 @@ AVOutputFormat ff_dnxhd_muxer = { .extensions = "dnxhd,dnxhr", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_DNXHD, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -212,7 +212,7 @@ AVOutputFormat ff_dts_muxer = { .extensions = "dts", .audio_codec = AV_CODEC_ID_DTS, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -226,7 +226,7 @@ AVOutputFormat ff_eac3_muxer = { .extensions = "eac3", .audio_codec = AV_CODEC_ID_EAC3, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -240,7 +240,7 @@ AVOutputFormat ff_g722_muxer = { .extensions = "g722", .audio_codec = AV_CODEC_ID_ADPCM_G722, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -254,7 +254,7 @@ AVOutputFormat ff_g723_1_muxer = { .extensions = "tco,rco", .audio_codec = AV_CODEC_ID_G723_1, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -266,7 +266,7 @@ AVOutputFormat ff_g726_muxer = { .long_name = NULL_IF_CONFIG_SMALL("raw big-endian G.726 (\"left-justified\")"), .audio_codec = AV_CODEC_ID_ADPCM_G726, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -278,7 +278,7 @@ AVOutputFormat ff_g726le_muxer = { .long_name = NULL_IF_CONFIG_SMALL("raw little-endian G.726 (\"right-justified\")"), .audio_codec = AV_CODEC_ID_ADPCM_G726LE, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -292,7 +292,7 @@ AVOutputFormat ff_gsm_muxer = { .extensions = "gsm", .audio_codec = AV_CODEC_ID_GSM, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -306,7 +306,7 @@ AVOutputFormat ff_h261_muxer = { .extensions = "h261", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_H261, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -320,7 +320,7 @@ AVOutputFormat ff_h263_muxer = { .extensions = "h263", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_H263, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -342,7 +342,7 @@ AVOutputFormat ff_h264_muxer = { .extensions = "h264,264", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_H264, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .check_bitstream = h264_check_bitstream, .flags = AVFMT_NOTIMESTAMPS, @@ -365,7 +365,7 @@ AVOutputFormat ff_hevc_muxer = { .extensions = "hevc,h265,265", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_HEVC, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .check_bitstream = hevc_check_bitstream, .flags = AVFMT_NOTIMESTAMPS, @@ -379,7 +379,7 @@ AVOutputFormat ff_m4v_muxer = { .extensions = "m4v", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_MPEG4, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -393,7 +393,7 @@ AVOutputFormat ff_mjpeg_muxer = { .extensions = "mjpg,mjpeg", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_MJPEG, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -406,9 +406,9 @@ AVOutputFormat ff_singlejpeg_muxer = { .mime_type = "image/jpeg", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_MJPEG, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, - .write_header = force_one_stream, }; #endif @@ -419,7 +419,7 @@ AVOutputFormat ff_mlp_muxer = { .extensions = "mlp", .audio_codec = AV_CODEC_ID_MLP, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -446,7 +446,7 @@ AVOutputFormat ff_mpeg1video_muxer = { .extensions = "mpg,mpeg,m1v", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_MPEG1VIDEO, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -459,7 +459,7 @@ AVOutputFormat ff_mpeg2video_muxer = { .extensions = "m2v", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -484,7 +484,7 @@ AVOutputFormat ff_sbc_muxer = { .mime_type = "audio/x-sbc", .extensions = "sbc,msbc", .audio_codec = AV_CODEC_ID_SBC, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -497,7 +497,7 @@ AVOutputFormat ff_truehd_muxer = { .extensions = "thd", .audio_codec = AV_CODEC_ID_TRUEHD, .video_codec = AV_CODEC_ID_NONE, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; @@ -510,7 +510,7 @@ AVOutputFormat ff_vc1_muxer = { .extensions = "vc1", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_VC1, - .write_header = force_one_stream, + .init = force_one_stream, .write_packet = ff_raw_write_packet, .flags = AVFMT_NOTIMESTAMPS, }; diff --git a/libavformat/rdt.c b/libavformat/rdt.c index 60c36f09e..e5824f6a4 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -554,7 +554,7 @@ rdt_close_context (PayloadContext *rdt) } #define RDT_HANDLER(n, s, t) \ -RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \ +const RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \ .enc_name = s, \ .codec_type = t, \ .codec_id = AV_CODEC_ID_NONE, \ diff --git a/libavformat/realtextdec.c b/libavformat/realtextdec.c index c2316da0e..f53477442 100644 --- a/libavformat/realtextdec.c +++ b/libavformat/realtextdec.c @@ -45,16 +45,16 @@ static int realtext_probe(const AVProbeData *p) return !av_strncasecmp(buf, "codec_tag || par->codec_tag > 0xffff) return -1; + if (par->codec_id == AV_CODEC_ID_ADPCM_SWF && par->block_align == 0) { + av_log(s, AV_LOG_ERROR, "%s can only be written to WAVE with a constant frame size\n", + avcodec_get_name(par->codec_id)); + return AVERROR(EINVAL); + } + /* We use the known constant frame size for the codec if known, otherwise * fall back on using AVCodecContext.frame_size, which is not as reliable * for indicating packet duration. */ @@ -207,11 +213,12 @@ int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, /* BITMAPINFOHEADER header */ void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, - int for_asf, int ignore_extradata) + int for_asf, int ignore_extradata, int rgb_frame_is_flipped) { - int keep_height = par->extradata_size >= 9 && - !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9); - int extradata_size = par->extradata_size - 9*keep_height; + int flipped_extradata = (par->extradata_size >= 9 && + !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9)); + int keep_height = flipped_extradata || rgb_frame_is_flipped; + int extradata_size = par->extradata_size - 9*flipped_extradata; enum AVPixelFormat pix_fmt = par->format; int pal_avi; diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 49048ac4e..fc3bff485 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -115,6 +115,9 @@ RMStream *ff_rm_alloc_rmstream (void) void ff_rm_free_rmstream (RMStream *rms) { + if (!rms) + return; + av_packet_unref(&rms->pkt); } @@ -293,7 +296,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, ast->deint_id == DEINT_ID_GENR || ast->deint_id == DEINT_ID_SIPR) { if (st->codecpar->block_align <= 0 || - ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX || + ast->audio_framesize * (uint64_t)sub_packet_h > (unsigned)INT_MAX || ast->audio_framesize * sub_packet_h < st->codecpar->block_align) return AVERROR_INVALIDDATA; if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0) @@ -544,7 +547,7 @@ static int rm_read_header(AVFormatContext *s) unsigned int data_off = 0, indx_off = 0; char buf[128], mime[128]; int flags = 0; - int ret = -1; + int ret; unsigned size, v; int64_t codec_pos; @@ -560,6 +563,7 @@ static int rm_read_header(AVFormatContext *s) avio_skip(pb, tag_size - 8); for(;;) { + ret = AVERROR_INVALIDDATA; if (avio_feof(pb)) goto fail; tag = avio_rl32(pb); @@ -610,8 +614,10 @@ static int rm_read_header(AVFormatContext *s) get_str8(pb, mime, sizeof(mime)); /* mimetype */ st->codecpar->codec_type = AVMEDIA_TYPE_DATA; st->priv_data = ff_rm_alloc_rmstream(); - if (!st->priv_data) - return AVERROR(ENOMEM); + if (!st->priv_data) { + ret = AVERROR(ENOMEM); + goto fail; + } size = avio_rb32(pb); codec_pos = avio_tell(pb); @@ -625,8 +631,9 @@ static int rm_read_header(AVFormatContext *s) avio_seek(pb, codec_pos + size, SEEK_SET); } else { avio_skip(pb, -4); - if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data, - size, mime) < 0) + ret = ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data, + size, mime); + if (ret < 0) goto fail; } @@ -814,7 +821,6 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb, av_packet_unref(&vst->pkt); //FIXME this should be output. if ((ret = av_new_packet(&vst->pkt, vst->videobufsize)) < 0) return ret; - memset(vst->pkt.data, 0, vst->pkt.size); vst->videobufpos = 8*vst->slices + 1; vst->cur_slice = 0; vst->curpic_num = pic_num; @@ -846,7 +852,7 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb, if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, vst->videobufpos - 1 - 8*vst->slices); - pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices); + av_shrink_packet(pkt, vst->videobufpos + 8*(vst->cur_slice - vst->slices)); pkt->pts = AV_NOPTS_VALUE; pkt->pos = vst->pktpos; vst->slices = 0; @@ -1245,20 +1251,19 @@ static int ivr_read_header(AVFormatContext *s) } for (n = 0; n < nb_streams; n++) { - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->priv_data = ff_rm_alloc_rmstream(); - if (!st->priv_data) - return AVERROR(ENOMEM); + if (!(st = avformat_new_stream(s, NULL)) || + !(st->priv_data = ff_rm_alloc_rmstream())) { + ret = AVERROR(ENOMEM); + goto fail; + } if (avio_r8(pb) != 1) - return AVERROR_INVALIDDATA; + goto invalid_data; count = avio_rb32(pb); for (i = 0; i < count; i++) { if (avio_feof(pb)) - return AVERROR_INVALIDDATA; + goto invalid_data; type = avio_r8(pb); tlen = avio_rb32(pb); @@ -1270,25 +1275,25 @@ static int ivr_read_header(AVFormatContext *s) } else if (type == 4 && !strncmp(key, "OpaqueData", tlen)) { ret = ffio_ensure_seekback(pb, 4); if (ret < 0) - return ret; + goto fail; if (avio_rb32(pb) == MKBETAG('M', 'L', 'T', 'I')) { ret = rm_read_multi(s, pb, st, NULL); } else { if (avio_feof(pb)) - return AVERROR_INVALIDDATA; + goto invalid_data; avio_seek(pb, -4, SEEK_CUR); ret = ff_rm_read_mdpr_codecdata(s, pb, st, st->priv_data, len, NULL); } if (ret < 0) - return ret; + goto fail; } else if (type == 4) { int j; av_log(s, AV_LOG_DEBUG, "%s = '0x", key); for (j = 0; j < len; j++) { if (avio_feof(pb)) - return AVERROR_INVALIDDATA; + goto invalid_data; av_log(s, AV_LOG_DEBUG, "%X", avio_r8(pb)); } av_log(s, AV_LOG_DEBUG, "'\n"); @@ -1305,14 +1310,19 @@ static int ivr_read_header(AVFormatContext *s) } if (avio_r8(pb) != 6) - return AVERROR_INVALIDDATA; + goto invalid_data; avio_skip(pb, 12); - avio_skip(pb, avio_rb64(pb) + pos - avio_tell(s->pb)); + avio_seek(pb, avio_rb64(pb) + pos, SEEK_SET); if (avio_r8(pb) != 8) - return AVERROR_INVALIDDATA; + goto invalid_data; avio_skip(pb, 8); return 0; +invalid_data: + ret = AVERROR_INVALIDDATA; +fail: + rm_read_close(s); + return ret; } static int ivr_read_packet(AVFormatContext *s, AVPacket *pkt) diff --git a/libavformat/rso.c b/libavformat/rso.c index 7d88f0f5b..765c0d0d6 100644 --- a/libavformat/rso.c +++ b/libavformat/rso.c @@ -28,3 +28,5 @@ const AVCodecTag ff_codec_rso_tags[] = { { AV_CODEC_ID_ADPCM_IMA_WAV, 0x0101 }, { AV_CODEC_ID_NONE, 0 }, }; + +const AVCodecTag *const ff_rso_codec_tags_list[] = { ff_codec_rso_tags, NULL }; diff --git a/libavformat/rso.h b/libavformat/rso.h index 1f65dd90c..4f78b4018 100644 --- a/libavformat/rso.h +++ b/libavformat/rso.h @@ -28,5 +28,6 @@ /* The libavcodec codecs we support, and the IDs they have in the file */ extern const AVCodecTag ff_codec_rso_tags[]; +extern const AVCodecTag *const ff_rso_codec_tags_list[]; #endif /* AVFORMAT_RSO_H */ diff --git a/libavformat/rsodec.c b/libavformat/rsodec.c index b2d9a7c40..91b86bf00 100644 --- a/libavformat/rsodec.c +++ b/libavformat/rsodec.c @@ -79,5 +79,5 @@ AVInputFormat ff_rso_demuxer = { .read_header = rso_read_header, .read_packet = ff_pcm_read_packet, .read_seek = ff_pcm_read_seek, - .codec_tag = (const AVCodecTag* const []){ff_codec_rso_tags, 0}, + .codec_tag = ff_rso_codec_tags_list, }; diff --git a/libavformat/rsoenc.c b/libavformat/rsoenc.c index beba94b2a..780538a54 100644 --- a/libavformat/rsoenc.c +++ b/libavformat/rsoenc.c @@ -100,6 +100,6 @@ AVOutputFormat ff_rso_muxer = { .write_header = rso_write_header, .write_packet = ff_raw_write_packet, .write_trailer = rso_write_trailer, - .codec_tag = (const AVCodecTag* const []){ff_codec_rso_tags, 0}, + .codec_tag = ff_rso_codec_tags_list, .flags = AVFMT_NOTIMESTAMPS, }; diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index 1eeae1733..00eb0873b 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -84,14 +84,6 @@ void ff_amf_write_object_end(uint8_t **dst) bytestream_put_be24(dst, AMF_DATA_TYPE_OBJECT_END); } -int ff_amf_read_bool(GetByteContext *bc, int *val) -{ - if (bytestream2_get_byte(bc) != AMF_DATA_TYPE_BOOL) - return AVERROR_INVALIDDATA; - *val = bytestream2_get_byte(bc); - return 0; -} - int ff_amf_read_number(GetByteContext *bc, double *val) { uint64_t read; @@ -569,6 +561,7 @@ int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end, return amf_get_field_value2(&gb, name, dst, dst_size); } +#ifdef DEBUG static const char* rtmp_packet_type(int type) { switch (type) { @@ -685,6 +678,7 @@ void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p) av_log(ctx, AV_LOG_DEBUG, "\n"); } } +#endif int ff_amf_match_string(const uint8_t *data, int size, const char *str) { diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h index eb68f1d3e..a15d2a577 100644 --- a/libavformat/rtmppkt.h +++ b/libavformat/rtmppkt.h @@ -259,15 +259,6 @@ void ff_amf_write_field_name(uint8_t **dst, const char *str); */ void ff_amf_write_object_end(uint8_t **dst); -/** - * Read AMF boolean value. - * - *@param[in,out] gbc GetByteContext initialized with AMF-formatted data - *@param[out] val 0 or 1 - *@return 0 on success or an AVERROR code on failure -*/ -int ff_amf_read_bool(GetByteContext *gbc, int *val); - /** * Read AMF number value. * diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index d9741bc62..5a540e324 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -3119,7 +3119,8 @@ static const AVOption rtmp_options[] = { { NULL }, }; -#define RTMP_PROTOCOL(flavor) \ +#define RTMP_PROTOCOL_0(flavor) +#define RTMP_PROTOCOL_1(flavor) \ static const AVClass flavor##_class = { \ .class_name = #flavor, \ .item_name = av_default_item_name, \ @@ -3139,11 +3140,16 @@ const URLProtocol ff_##flavor##_protocol = { \ .flags = URL_PROTOCOL_FLAG_NETWORK, \ .priv_data_class= &flavor##_class, \ }; +#define RTMP_PROTOCOL_2(flavor, enabled) \ + RTMP_PROTOCOL_ ## enabled(flavor) +#define RTMP_PROTOCOL_3(flavor, config) \ + RTMP_PROTOCOL_2(flavor, config) +#define RTMP_PROTOCOL(flavor, uppercase) \ + RTMP_PROTOCOL_3(flavor, CONFIG_ ## uppercase ## _PROTOCOL) - -RTMP_PROTOCOL(rtmp) -RTMP_PROTOCOL(rtmpe) -RTMP_PROTOCOL(rtmps) -RTMP_PROTOCOL(rtmpt) -RTMP_PROTOCOL(rtmpte) -RTMP_PROTOCOL(rtmpts) +RTMP_PROTOCOL(rtmp, RTMP) +RTMP_PROTOCOL(rtmpe, RTMPE) +RTMP_PROTOCOL(rtmps, RTMPS) +RTMP_PROTOCOL(rtmpt, RTMPT) +RTMP_PROTOCOL(rtmpte, RTMPTE) +RTMP_PROTOCOL(rtmpts, RTMPTS) diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index 3d5b20009..fd4601e65 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -24,57 +24,60 @@ #include "libavutil/intreadwrite.h" #include "libavutil/time.h" +#include "libavcodec/bytestream.h" + #include "avformat.h" #include "network.h" #include "srtp.h" #include "url.h" #include "rtpdec.h" #include "rtpdec_formats.h" +#include "internal.h" #define MIN_FEEDBACK_INTERVAL 200000 /* 200 ms in us */ -static RTPDynamicProtocolHandler l24_dynamic_handler = { +static const RTPDynamicProtocolHandler l24_dynamic_handler = { .enc_name = "L24", .codec_type = AVMEDIA_TYPE_AUDIO, .codec_id = AV_CODEC_ID_PCM_S24BE, }; -static RTPDynamicProtocolHandler gsm_dynamic_handler = { +static const RTPDynamicProtocolHandler gsm_dynamic_handler = { .enc_name = "GSM", .codec_type = AVMEDIA_TYPE_AUDIO, .codec_id = AV_CODEC_ID_GSM, }; -static RTPDynamicProtocolHandler realmedia_mp3_dynamic_handler = { +static const RTPDynamicProtocolHandler realmedia_mp3_dynamic_handler = { .enc_name = "X-MP3-draft-00", .codec_type = AVMEDIA_TYPE_AUDIO, .codec_id = AV_CODEC_ID_MP3ADU, }; -static RTPDynamicProtocolHandler speex_dynamic_handler = { +static const RTPDynamicProtocolHandler speex_dynamic_handler = { .enc_name = "speex", .codec_type = AVMEDIA_TYPE_AUDIO, .codec_id = AV_CODEC_ID_SPEEX, }; -static RTPDynamicProtocolHandler opus_dynamic_handler = { +static const RTPDynamicProtocolHandler opus_dynamic_handler = { .enc_name = "opus", .codec_type = AVMEDIA_TYPE_AUDIO, .codec_id = AV_CODEC_ID_OPUS, }; -static RTPDynamicProtocolHandler t140_dynamic_handler = { /* RFC 4103 */ +static const RTPDynamicProtocolHandler t140_dynamic_handler = { /* RFC 4103 */ .enc_name = "t140", .codec_type = AVMEDIA_TYPE_SUBTITLE, .codec_id = AV_CODEC_ID_TEXT, }; -extern RTPDynamicProtocolHandler ff_rdt_video_handler; -extern RTPDynamicProtocolHandler ff_rdt_audio_handler; -extern RTPDynamicProtocolHandler ff_rdt_live_video_handler; -extern RTPDynamicProtocolHandler ff_rdt_live_audio_handler; +extern const RTPDynamicProtocolHandler ff_rdt_video_handler; +extern const RTPDynamicProtocolHandler ff_rdt_audio_handler; +extern const RTPDynamicProtocolHandler ff_rdt_live_video_handler; +extern const RTPDynamicProtocolHandler ff_rdt_live_audio_handler; -static const RTPDynamicProtocolHandler *rtp_dynamic_protocol_handler_list[] = { +static const RTPDynamicProtocolHandler *const rtp_dynamic_protocol_handler_list[] = { /* rtp */ &ff_ac3_dynamic_handler, &ff_amr_nb_dynamic_handler, @@ -401,38 +404,26 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd, void ff_rtp_send_punch_packets(URLContext *rtp_handle) { - AVIOContext *pb; - uint8_t *buf; - int len; + uint8_t buf[RTP_MIN_PACKET_LENGTH], *ptr = buf; /* Send a small RTP packet */ - if (avio_open_dyn_buf(&pb) < 0) - return; - avio_w8(pb, (RTP_VERSION << 6)); - avio_w8(pb, 0); /* Payload type */ - avio_wb16(pb, 0); /* Seq */ - avio_wb32(pb, 0); /* Timestamp */ - avio_wb32(pb, 0); /* SSRC */ + bytestream_put_byte(&ptr, (RTP_VERSION << 6)); + bytestream_put_byte(&ptr, 0); /* Payload type */ + bytestream_put_be16(&ptr, 0); /* Seq */ + bytestream_put_be32(&ptr, 0); /* Timestamp */ + bytestream_put_be32(&ptr, 0); /* SSRC */ - len = avio_close_dyn_buf(pb, &buf); - if ((len > 0) && buf) - ffurl_write(rtp_handle, buf, len); - av_free(buf); + ffurl_write(rtp_handle, buf, ptr - buf); /* Send a minimal RTCP RR */ - if (avio_open_dyn_buf(&pb) < 0) - return; + ptr = buf; + bytestream_put_byte(&ptr, (RTP_VERSION << 6)); + bytestream_put_byte(&ptr, RTCP_RR); /* receiver report */ + bytestream_put_be16(&ptr, 1); /* length in words - 1 */ + bytestream_put_be32(&ptr, 0); /* our own SSRC */ - avio_w8(pb, (RTP_VERSION << 6)); - avio_w8(pb, RTCP_RR); /* receiver report */ - avio_wb16(pb, 1); /* length in words - 1 */ - avio_wb32(pb, 0); /* our own SSRC */ - - len = avio_close_dyn_buf(pb, &buf); - if ((len > 0) && buf) - ffurl_write(rtp_handle, buf, len); - av_free(buf); + ffurl_write(rtp_handle, buf, ptr - buf); } static int find_missing_packets(RTPDemuxContext *s, uint16_t *first_missing, @@ -529,6 +520,43 @@ int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd, return 0; } +static int opus_write_extradata(AVCodecParameters *codecpar) +{ + uint8_t *bs; + int ret; + + /* This function writes an extradata with a channel mapping family of 0. + * This mapping family only supports mono and stereo layouts. And RFC7587 + * specifies that the number of channels in the SDP must be 2. + */ + if (codecpar->channels > 2) { + return AVERROR_INVALIDDATA; + } + + ret = ff_alloc_extradata(codecpar, 19); + if (ret < 0) + return ret; + + bs = (uint8_t *)codecpar->extradata; + + /* Opus magic */ + bytestream_put_buffer(&bs, "OpusHead", 8); + /* Version */ + bytestream_put_byte (&bs, 0x1); + /* Channel count */ + bytestream_put_byte (&bs, codecpar->channels); + /* Pre skip */ + bytestream_put_le16 (&bs, 0); + /* Input sample rate */ + bytestream_put_le32 (&bs, 48000); + /* Output gain */ + bytestream_put_le16 (&bs, 0x0); + /* Mapping family */ + bytestream_put_byte (&bs, 0x0); + + return 0; +} + /** * open a new RTP parse context for stream 'st'. 'st' can be NULL for * MPEG-2 TS streams. @@ -537,6 +565,7 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, int payload_type, int queue_size) { RTPDemuxContext *s; + int ret; s = av_mallocz(sizeof(RTPDemuxContext)); if (!s) @@ -560,6 +589,16 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, if (st->codecpar->sample_rate == 8000) st->codecpar->sample_rate = 16000; break; + case AV_CODEC_ID_OPUS: + ret = opus_write_extradata(st->codecpar); + if (ret < 0) { + av_log(s1, AV_LOG_ERROR, + "Error creating opus extradata: %s\n", + av_err2str(ret)); + av_free(s); + return NULL; + } + break; default: break; } @@ -925,7 +964,7 @@ int ff_parse_fmtp(AVFormatContext *s, int ff_rtp_finalize_packet(AVPacket *pkt, AVIOContext **dyn_buf, int stream_idx) { int ret; - av_init_packet(pkt); + av_packet_unref(pkt); pkt->size = avio_close_dyn_buf(*dyn_buf, &pkt->data); pkt->stream_index = stream_idx; diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h index 9144edbe8..701ce072b 100644 --- a/libavformat/rtpdec.h +++ b/libavformat/rtpdec.h @@ -134,8 +134,6 @@ struct RTPDynamicProtocolHandler { /** Parse handler for this dynamic packet */ DynamicPayloadPacketHandlerProc parse_packet; int (*need_keyframe)(PayloadContext *context); - - struct RTPDynamicProtocolHandler *next; }; typedef struct RTPPacket { diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 931463cec..b32d07413 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -112,7 +112,7 @@ static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, jpeg_put_marker(&pbc, APP0); bytestream2_put_be16(&pbc, 16); bytestream2_put_buffer(&pbc, "JFIF", 5); - bytestream2_put_be16(&pbc, 0x0201); + bytestream2_put_be16(&pbc, 0x0102); bytestream2_put_byte(&pbc, 0); bytestream2_put_be16(&pbc, 1); bytestream2_put_be16(&pbc, 1); diff --git a/libavformat/rtpdec_qt.c b/libavformat/rtpdec_qt.c index 740c382d0..492a1b671 100644 --- a/libavformat/rtpdec_qt.c +++ b/libavformat/rtpdec_qt.c @@ -34,11 +34,21 @@ #include "libavcodec/get_bits.h" struct PayloadContext { - AVPacket pkt; + AVPacket *pkt; int bytes_per_frame, remaining; uint32_t timestamp; }; +static av_cold int qt_rtp_init(AVFormatContext *ctx, int st_index, + PayloadContext *qt) +{ + qt->pkt = av_packet_alloc(); + if (!qt->pkt) + return AVERROR(ENOMEM); + + return 0; +} + static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, @@ -51,18 +61,18 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt, keyframe, ret; if (qt->remaining) { - int num = qt->pkt.size / qt->bytes_per_frame; + int num = qt->pkt->size / qt->bytes_per_frame; if ((ret = av_new_packet(pkt, qt->bytes_per_frame)) < 0) return ret; pkt->stream_index = st->index; - pkt->flags = qt->pkt.flags; + pkt->flags = qt->pkt->flags; memcpy(pkt->data, - &qt->pkt.data[(num - qt->remaining) * qt->bytes_per_frame], + &qt->pkt->data[(num - qt->remaining) * qt->bytes_per_frame], qt->bytes_per_frame); if (--qt->remaining == 0) { - av_freep(&qt->pkt.data); - qt->pkt.size = 0; + av_freep(&qt->pkt->data); + qt->pkt->size = 0; } return qt->remaining > 0; } @@ -171,31 +181,31 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt, switch (packing_scheme) { case 3: /* one data packet spread over 1 or multiple RTP packets */ - if (qt->pkt.size > 0 && qt->timestamp == *timestamp) { + if (qt->pkt->size > 0 && qt->timestamp == *timestamp) { int err; - if ((err = av_reallocp(&qt->pkt.data, qt->pkt.size + alen + + if ((err = av_reallocp(&qt->pkt->data, qt->pkt->size + alen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) { - qt->pkt.size = 0; + qt->pkt->size = 0; return err; } } else { - av_freep(&qt->pkt.data); - av_init_packet(&qt->pkt); - qt->pkt.data = av_realloc(NULL, alen + AV_INPUT_BUFFER_PADDING_SIZE); - if (!qt->pkt.data) + av_freep(&qt->pkt->data); + av_packet_unref(qt->pkt); + qt->pkt->data = av_realloc(NULL, alen + AV_INPUT_BUFFER_PADDING_SIZE); + if (!qt->pkt->data) return AVERROR(ENOMEM); - qt->pkt.size = 0; + qt->pkt->size = 0; qt->timestamp = *timestamp; } - memcpy(qt->pkt.data + qt->pkt.size, buf + avio_tell(&pb), alen); - qt->pkt.size += alen; + memcpy(qt->pkt->data + qt->pkt->size, buf + avio_tell(&pb), alen); + qt->pkt->size += alen; if (has_marker_bit) { - int ret = av_packet_from_data(pkt, qt->pkt.data, qt->pkt.size); + int ret = av_packet_from_data(pkt, qt->pkt->data, qt->pkt->size); if (ret < 0) return ret; - qt->pkt.size = 0; - qt->pkt.data = NULL; + qt->pkt->size = 0; + qt->pkt->data = NULL; pkt->flags = keyframe ? AV_PKT_FLAG_KEY : 0; pkt->stream_index = st->index; memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); @@ -214,17 +224,17 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt, pkt->flags = keyframe ? AV_PKT_FLAG_KEY : 0; pkt->stream_index = st->index; if (qt->remaining > 0) { - av_freep(&qt->pkt.data); - qt->pkt.data = av_realloc(NULL, qt->remaining * qt->bytes_per_frame); - if (!qt->pkt.data) { + av_freep(&qt->pkt->data); + qt->pkt->data = av_realloc(NULL, qt->remaining * qt->bytes_per_frame); + if (!qt->pkt->data) { av_packet_unref(pkt); return AVERROR(ENOMEM); } - qt->pkt.size = qt->remaining * qt->bytes_per_frame; - memcpy(qt->pkt.data, + qt->pkt->size = qt->remaining * qt->bytes_per_frame; + memcpy(qt->pkt->data, buf + avio_tell(&pb) + qt->bytes_per_frame, qt->remaining * qt->bytes_per_frame); - qt->pkt.flags = pkt->flags; + qt->pkt->flags = pkt->flags; return 1; } return 0; @@ -237,15 +247,17 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt, static void qt_rtp_close(PayloadContext *qt) { - av_freep(&qt->pkt.data); + av_freep(&qt->pkt->data); + av_packet_free(&qt->pkt); } #define RTP_QT_HANDLER(m, n, s, t) \ -RTPDynamicProtocolHandler ff_ ## m ## _rtp_ ## n ## _handler = { \ +const RTPDynamicProtocolHandler ff_ ## m ## _rtp_ ## n ## _handler = { \ .enc_name = s, \ .codec_type = t, \ .codec_id = AV_CODEC_ID_NONE, \ .priv_data_size = sizeof(PayloadContext), \ + .init = qt_rtp_init, \ .close = qt_rtp_close, \ .parse_packet = qt_rtp_parse_packet, \ } diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 63047becc..38e4c65c4 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -589,7 +589,7 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) break; case AV_CODEC_ID_H263: if (s->flags & FF_RTP_FLAG_RFC2190) { - int mb_info_size = 0; + buffer_size_t mb_info_size; const uint8_t *mb_info = av_packet_get_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, &mb_info_size); diff --git a/libavformat/rtpenc_mpegts.c b/libavformat/rtpenc_mpegts.c index 7d7377db7..da17b1d77 100644 --- a/libavformat/rtpenc_mpegts.c +++ b/libavformat/rtpenc_mpegts.c @@ -20,17 +20,22 @@ */ #include "libavutil/mathematics.h" +#include "libavutil/opt.h" #include "avformat.h" #include "avio_internal.h" -struct MuxChain { +typedef struct MuxChain { + const AVClass *class; AVFormatContext *mpegts_ctx; AVFormatContext *rtp_ctx; -}; + AVPacket *pkt; + AVDictionary* mpegts_muxer_options; + AVDictionary* rtp_muxer_options; +} MuxChain; static int rtp_mpegts_write_close(AVFormatContext *s) { - struct MuxChain *chain = s->priv_data; + MuxChain *chain = s->priv_data; if (chain->mpegts_ctx) { av_write_trailer(chain->mpegts_ctx); @@ -41,23 +46,31 @@ static int rtp_mpegts_write_close(AVFormatContext *s) av_write_trailer(chain->rtp_ctx); avformat_free_context(chain->rtp_ctx); } + + av_packet_free(&chain->pkt); + return 0; } static int rtp_mpegts_write_header(AVFormatContext *s) { - struct MuxChain *chain = s->priv_data; + MuxChain *chain = s->priv_data; AVFormatContext *mpegts_ctx = NULL, *rtp_ctx = NULL; ff_const59 AVOutputFormat *mpegts_format = av_guess_format("mpegts", NULL, NULL); ff_const59 AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); int i, ret = AVERROR(ENOMEM); AVStream *st; + AVDictionary *mpegts_muxer_options = NULL; + AVDictionary *rtp_muxer_options = NULL; if (!mpegts_format || !rtp_format) return AVERROR(ENOSYS); mpegts_ctx = avformat_alloc_context(); if (!mpegts_ctx) return AVERROR(ENOMEM); + chain->pkt = av_packet_alloc(); + if (!chain->pkt) + goto fail; mpegts_ctx->oformat = mpegts_format; mpegts_ctx->max_delay = s->max_delay; av_dict_copy(&mpegts_ctx->metadata, s->metadata, 0); @@ -67,12 +80,19 @@ static int rtp_mpegts_write_header(AVFormatContext *s) goto fail; st->time_base = s->streams[i]->time_base; st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio; + st->id = s->streams[i]->id; avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar); } if ((ret = avio_open_dyn_buf(&mpegts_ctx->pb)) < 0) goto fail; - if ((ret = avformat_write_header(mpegts_ctx, NULL)) < 0) + + av_dict_copy(&mpegts_muxer_options, chain->mpegts_muxer_options, 0); + + ret = avformat_write_header(mpegts_ctx, &mpegts_muxer_options); + av_dict_free(&mpegts_muxer_options); + if (ret < 0) goto fail; + for (i = 0; i < s->nb_streams; i++) s->streams[i]->time_base = mpegts_ctx->streams[i]->time_base; @@ -94,8 +114,12 @@ static int rtp_mpegts_write_header(AVFormatContext *s) st->time_base.den = 90000; st->codecpar->codec_id = AV_CODEC_ID_MPEG2TS; rtp_ctx->pb = s->pb; - if ((ret = avformat_write_header(rtp_ctx, NULL)) < 0) + av_dict_copy(&rtp_muxer_options, chain->rtp_muxer_options, 0); + ret = avformat_write_header(rtp_ctx, &rtp_muxer_options); + av_dict_free(&rtp_muxer_options); + if (ret < 0) goto fail; + chain->rtp_ctx = rtp_ctx; return 0; @@ -113,10 +137,10 @@ fail: static int rtp_mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) { - struct MuxChain *chain = s->priv_data; + MuxChain *chain = s->priv_data; int ret = 0, size; uint8_t *buf; - AVPacket local_pkt; + AVPacket *local_pkt = chain->pkt; if (!chain->mpegts_ctx->pb) { if ((ret = avio_open_dyn_buf(&chain->mpegts_ctx->pb)) < 0) @@ -130,31 +154,47 @@ static int rtp_mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) av_free(buf); return 0; } - av_init_packet(&local_pkt); - local_pkt.data = buf; - local_pkt.size = size; - local_pkt.stream_index = 0; + av_packet_unref(local_pkt); + local_pkt->data = buf; + local_pkt->size = size; + local_pkt->stream_index = 0; if (pkt->pts != AV_NOPTS_VALUE) - local_pkt.pts = av_rescale_q(pkt->pts, + local_pkt->pts = av_rescale_q(pkt->pts, s->streams[pkt->stream_index]->time_base, chain->rtp_ctx->streams[0]->time_base); if (pkt->dts != AV_NOPTS_VALUE) - local_pkt.dts = av_rescale_q(pkt->dts, + local_pkt->dts = av_rescale_q(pkt->dts, s->streams[pkt->stream_index]->time_base, chain->rtp_ctx->streams[0]->time_base); - ret = av_write_frame(chain->rtp_ctx, &local_pkt); + ret = av_write_frame(chain->rtp_ctx, local_pkt); av_free(buf); return ret; } +#define OFFSET(x) offsetof(MuxChain, x) +#define E AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "mpegts_muxer_options", "set list of options for the MPEG-TS muxer", OFFSET(mpegts_muxer_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E }, + { "rtp_muxer_options", "set list of options for the RTP muxer", OFFSET(rtp_muxer_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E }, + { NULL }, +}; + +static const AVClass rtp_mpegts_class = { + .class_name = "rtp_mpegts muxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVOutputFormat ff_rtp_mpegts_muxer = { .name = "rtp_mpegts", .long_name = NULL_IF_CONFIG_SMALL("RTP/mpegts output format"), - .priv_data_size = sizeof(struct MuxChain), + .priv_data_size = sizeof(MuxChain), .audio_codec = AV_CODEC_ID_AAC, .video_codec = AV_CODEC_ID_MPEG4, .write_header = rtp_mpegts_write_header, .write_packet = rtp_mpegts_write_packet, .write_trailer = rtp_mpegts_write_close, + .priv_class = &rtp_mpegts_class, }; diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index 19e940d01..7dd604215 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -60,6 +60,7 @@ typedef struct RTPContext { char *sources; char *block; char *fec_options_str; + int64_t rw_timeout; } RTPContext; #define OFFSET(x) offsetof(RTPContext, x) @@ -75,6 +76,7 @@ static const AVOption options[] = { { "write_to_source", "Send packets to the source address of the latest received packet", OFFSET(write_to_source), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, { "pkt_size", "Maximum packet size", OFFSET(pkt_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { "dscp", "DSCP class", OFFSET(dscp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, + { "timeout", "set timeout (in microseconds) of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "sources", "Source list", OFFSET(sources), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, { "block", "Block list", OFFSET(block), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, { "fec", "FEC", OFFSET(fec_options_str), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = E }, @@ -265,6 +267,9 @@ static int rtp_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "dscp", p)) { s->dscp = strtol(buf, NULL, 10); } + if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) { + s->rw_timeout = strtol(buf, NULL, 10); + } if (av_find_info_tag(buf, sizeof(buf), "sources", p)) { av_strlcpy(include_sources, buf, sizeof(include_sources)); ff_ip_parse_sources(h, buf, &s->filters); @@ -280,6 +285,8 @@ static int rtp_open(URLContext *h, const char *uri, int flags) block = s->block; } } + if (s->rw_timeout >= 0) + h->rw_timeout = s->rw_timeout; if (s->fec_options_str) { p = s->fec_options_str; @@ -375,9 +382,10 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) RTPContext *s = h->priv_data; int len, n, i; struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}}; - int poll_delay = h->flags & AVIO_FLAG_NONBLOCK ? 0 : 100; + int poll_delay = h->flags & AVIO_FLAG_NONBLOCK ? 0 : POLLING_TIME; struct sockaddr_storage *addrs[2] = { &s->last_rtp_source, &s->last_rtcp_source }; socklen_t *addr_lens[2] = { &s->last_rtp_source_len, &s->last_rtcp_source_len }; + int runs = h->rw_timeout / 1000 / POLLING_TIME; for(;;) { if (ff_check_interrupt(&h->interrupt_callback)) @@ -401,6 +409,8 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) continue; return len; } + } else if (n == 0 && h->rw_timeout > 0 && --runs <= 0) { + return AVERROR(ETIMEDOUT); } else if (n < 0) { if (ff_neterrno() == AVERROR(EINTR)) continue; diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 5d8491b74..25bdf475b 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -51,12 +51,8 @@ #include "rtpenc.h" #include "mpegts.h" -/* Timeout values for socket poll, in ms, - * and read_packet(), in seconds */ -#define POLL_TIMEOUT_MS 100 +/* Default timeout values for read packet in seconds */ #define READ_PACKET_TIMEOUT_S 10 -#define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / POLL_TIMEOUT_MS -#define SDP_MAX_SIZE 16384 #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH #define DEFAULT_REORDERING_DELAY 100000 @@ -93,12 +89,13 @@ const AVOption ff_rtsp_options[] = { RTSP_FLAG_OPTS("rtsp_flags", "set RTSP flags"), { "listen", "wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" }, { "prefer_tcp", "try RTP via TCP first, if available", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_PREFER_TCP}, 0, 0, DEC|ENC, "rtsp_flags" }, + { "satip_raw", "export raw MPEG-TS stream instead of demuxing", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_SATIP_RAW}, 0, 0, DEC, "rtsp_flags" }, RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"), { "min_port", "set minimum local UDP port", OFFSET(rtp_port_min), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MIN}, 0, 65535, DEC|ENC }, { "max_port", "set maximum local UDP port", OFFSET(rtp_port_max), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MAX}, 0, 65535, DEC|ENC }, { "listen_timeout", "set maximum timeout (in seconds) to wait for incoming connections (-1 is infinite, imply flag listen)", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC }, #if FF_API_OLD_RTSP_OPTIONS - { "timeout", "set maximum timeout (in seconds) to wait for incoming connections (-1 is infinite, imply flag listen) (deprecated, use listen_timeout)", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC }, + { "timeout", "set maximum timeout (in seconds) to wait for incoming connections (-1 is infinite, imply flag listen) (deprecated, use listen_timeout)", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC|AV_OPT_FLAG_DEPRECATED }, { "stimeout", "set timeout (in microseconds) of socket TCP I/O operations", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC }, #else { "timeout", "set timeout (in microseconds) of socket TCP I/O operations", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC }, @@ -106,7 +103,7 @@ const AVOption ff_rtsp_options[] = { COMMON_OPTS(), { "user_agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC }, #if FF_API_OLD_RTSP_OPTIONS - { "user-agent", "override User-Agent header (deprecated, use user_agent)", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC }, + { "user-agent", "override User-Agent header (deprecated, use user_agent)", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC|AV_OPT_FLAG_DEPRECATED }, #endif { NULL }, }; @@ -115,6 +112,7 @@ static const AVOption sdp_options[] = { RTSP_FLAG_OPTS("sdp_flags", "SDP flags"), { "custom_io", "use custom I/O", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_CUSTOM_IO}, 0, 0, DEC, "rtsp_flags" }, { "rtcp_to_source", "send RTCP packets to the source address of received packets", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_RTCP_TO_SOURCE}, 0, 0, DEC, "rtsp_flags" }, + { "listen_timeout", "set maximum timeout (in seconds) to wait for incoming connections", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = READ_PACKET_TIMEOUT_S}, INT_MIN, INT_MAX, DEC }, RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"), COMMON_OPTS(), { NULL }, @@ -122,6 +120,8 @@ static const AVOption sdp_options[] = { static const AVOption rtp_options[] = { RTSP_FLAG_OPTS("rtp_flags", "set RTP flags"), + { "listen_timeout", "set maximum timeout (in seconds) to wait for incoming connections", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = READ_PACKET_TIMEOUT_S}, INT_MIN, INT_MAX, DEC }, + RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"), COMMON_OPTS(), { NULL }, }; @@ -253,6 +253,35 @@ static void finalize_rtp_handler_init(AVFormatContext *s, RTSPStream *rtsp_st, } } +static int init_satip_stream(AVFormatContext *s) +{ + RTSPState *rt = s->priv_data; + RTSPStream *rtsp_st = av_mallocz(sizeof(RTSPStream)); + if (!rtsp_st) + return AVERROR(ENOMEM); + dynarray_add(&rt->rtsp_streams, + &rt->nb_rtsp_streams, rtsp_st); + + rtsp_st->sdp_payload_type = 33; // MP2T + av_strlcpy(rtsp_st->control_url, + rt->control_uri, sizeof(rtsp_st->control_url)); + + if (rt->rtsp_flags & RTSP_FLAG_SATIP_RAW) { + AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + st->id = rt->nb_rtsp_streams - 1; + rtsp_st->stream_index = st->index; + st->codecpar->codec_type = AVMEDIA_TYPE_DATA; + st->codecpar->codec_id = AV_CODEC_ID_MPEG2TS; + } else { + rtsp_st->stream_index = -1; + init_rtp_handler(&ff_mpegts_dynamic_handler, rtsp_st, NULL); + finalize_rtp_handler_init(s, rtsp_st, NULL); + } + return 0; +} + /* parse the rtpmap description: /[/] */ static int sdp_parse_rtpmap(AVFormatContext *s, AVStream *st, RTSPStream *rtsp_st, @@ -542,7 +571,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, break; case 'a': if (av_strstart(p, "control:", &p)) { - if (s->nb_streams == 0) { + if (rt->nb_rtsp_streams == 0) { if (!strncmp(p, "rtsp://", 7)) av_strlcpy(rt->control_uri, p, sizeof(rt->control_uri)); @@ -688,15 +717,7 @@ int ff_sdp_parse(AVFormatContext *s, const char *content) { const char *p; int letter, i; - /* Some SDP lines, particularly for Realmedia or ASF RTSP streams, - * contain long SDP lines containing complete ASF Headers (several - * kB) or arrays of MDPR (RM stream descriptor) headers plus - * "rulebooks" describing their properties. Therefore, the SDP line - * buffer is large. - * - * The Vorbis FMTP line can be up to 16KB - see xiph_parse_sdp_line - * in rtpdec_xiph.c. */ - char buf[16384], *q; + char buf[SDP_MAX_SIZE], *q; SDPParseState sdp_parse_state = { { 0 } }, *s1 = &sdp_parse_state; p = content; @@ -1034,7 +1055,7 @@ static void handle_rtp_info(RTSPState *rt, const char *url, static void rtsp_parse_rtp_info(RTSPState *rt, const char *p) { int read = 0; - char key[20], value[1024], url[1024] = ""; + char key[20], value[MAX_URL_SIZE], url[MAX_URL_SIZE] = ""; uint32_t seq = 0, rtptime = 0; for (;;) { @@ -1125,6 +1146,9 @@ void ff_rtsp_parse_line(AVFormatContext *s, } else if (av_stristart(p, "Content-Type:", &p)) { p += strspn(p, SPACE_CHARS); av_strlcpy(reply->content_type, p, sizeof(reply->content_type)); + } else if (av_stristart(p, "com.ses.streamID:", &p)) { + p += strspn(p, SPACE_CHARS); + av_strlcpy(reply->stream_id, p, sizeof(reply->stream_id)); } } @@ -1133,7 +1157,7 @@ void ff_rtsp_skip_packet(AVFormatContext *s) { RTSPState *rt = s->priv_data; int ret, len, len1; - uint8_t buf[1024]; + uint8_t buf[MAX_URL_SIZE]; ret = ffurl_read_complete(rt->rtsp_hd, buf, 3); if (ret != 3) @@ -1159,7 +1183,7 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply, int return_on_interleaved_data, const char *method) { RTSPState *rt = s->priv_data; - char buf[4096], buf1[1024], *q; + char buf[MAX_URL_SIZE], buf1[MAX_URL_SIZE], *q; unsigned char ch; const char *p; int ret, content_length, line_count = 0, request = 0; @@ -1229,7 +1253,8 @@ start: content = av_malloc(content_length + 1); if (!content) return AVERROR(ENOMEM); - ffurl_read_complete(rt->rtsp_hd, content, content_length); + if (ffurl_read_complete(rt->rtsp_hd, content, content_length) != content_length) + return AVERROR(EIO); content[content_length] = '\0'; } if (content_ptr) @@ -1238,7 +1263,7 @@ start: av_freep(&content); if (request) { - char buf[1024]; + char buf[MAX_URL_SIZE]; char base64buf[AV_BASE64_SIZE(sizeof(buf))]; const char* ptr = buf; @@ -1314,7 +1339,7 @@ static int rtsp_send_cmd_with_content_async(AVFormatContext *s, int send_content_length) { RTSPState *rt = s->priv_data; - char buf[4096], *out_buf; + char buf[MAX_URL_SIZE], *out_buf; char base64buf[AV_BASE64_SIZE(sizeof(buf))]; if (!rt->rtsp_hd_out) @@ -1424,7 +1449,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, int rtx = 0, j, i, err, interleave = 0, port_off; RTSPStream *rtsp_st; RTSPMessageHeader reply1, *reply = &reply1; - char cmd[2048]; + char cmd[MAX_URL_SIZE]; const char *trans_pref; if (rt->transport == RTSP_TRANSPORT_RDT) @@ -1445,7 +1470,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, port_off -= port_off & 0x01; for (j = rt->rtp_port_min + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) { - char transport[2048]; + char transport[MAX_URL_SIZE]; /* * WMS serves all UDP data over a single connection, the RTX, which @@ -1503,8 +1528,10 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, rtp_opened: port = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle); have_port: - snprintf(transport, sizeof(transport) - 1, - "%s/UDP;", trans_pref); + av_strlcpy(transport, trans_pref, sizeof(transport)); + av_strlcat(transport, + rt->server_type == RTSP_SERVER_SATIP ? ";" : "/UDP;", + sizeof(transport)); if (rt->server_type != RTSP_SERVER_REAL) av_strlcat(transport, "unicast;", sizeof(transport)); av_strlcatf(transport, sizeof(transport), @@ -1567,6 +1594,15 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, goto fail; } + if (rt->server_type == RTSP_SERVER_SATIP && reply->stream_id[0]) { + char proto[128], host[128], path[512], auth[128]; + int port; + av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host), + &port, path, sizeof(path), rt->control_uri); + ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host, + port, "/stream=%s", reply->stream_id); + } + /* XXX: same protocol for all streams is required */ if (i > 0) { if (reply->transports[0].lower_transport != rt->lower_transport || @@ -1594,7 +1630,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, break; case RTSP_LOWER_TRANSPORT_UDP: { - char url[1024], options[30] = ""; + char url[MAX_URL_SIZE], options[30] = ""; const char *peer = host; if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC) @@ -1612,7 +1648,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, break; } case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: { - char url[1024], namebuf[50], optbuf[20] = ""; + char url[MAX_URL_SIZE], namebuf[50], optbuf[20] = ""; struct sockaddr_storage addr; int port, ttl; AVDictionary *opts = map_to_opts(rt); @@ -1674,7 +1710,7 @@ int ff_rtsp_connect(AVFormatContext *s) { RTSPState *rt = s->priv_data; char proto[128], host[1024], path[1024]; - char tcpname[1024], cmd[2048], auth[128]; + char tcpname[1024], cmd[MAX_URL_SIZE], auth[128]; const char *lower_rtsp_proto = "tcp"; int port, err, tcp_fd; RTSPMessageHeader reply1, *reply = &reply1; @@ -1718,6 +1754,9 @@ redirect: lower_rtsp_proto = "tls"; default_port = RTSPS_DEFAULT_PORT; rt->lower_transport_mask = 1 << RTSP_LOWER_TRANSPORT_TCP; + } else if (!strcmp(proto, "satip")) { + av_strlcpy(proto, "rtsp", sizeof(proto)); + rt->server_type = RTSP_SERVER_SATIP; } if (*auth) { @@ -1865,7 +1904,9 @@ redirect: /* request options supported by the server; this also detects server * type */ - for (rt->server_type = RTSP_SERVER_RTP;;) { + if (rt->server_type != RTSP_SERVER_SATIP) + rt->server_type = RTSP_SERVER_RTP; + for (;;) { cmd[0] = 0; if (rt->server_type == RTSP_SERVER_REAL) av_strlcat(cmd, @@ -1900,9 +1941,15 @@ redirect: break; } - if (CONFIG_RTSP_DEMUXER && s->iformat) - err = ff_rtsp_setup_input_streams(s, reply); - else if (CONFIG_RTSP_MUXER) +#if CONFIG_RTSP_DEMUXER + if (s->iformat) { + if (rt->server_type == RTSP_SERVER_SATIP) + err = init_satip_stream(s); + else + err = ff_rtsp_setup_input_streams(s, reply); + } else +#endif + if (CONFIG_RTSP_MUXER) err = ff_rtsp_setup_output_streams(s, host); else av_assert0(0); @@ -1964,13 +2011,9 @@ static int parse_rtsp_message(AVFormatContext *s) if (rt->rtsp_flags & RTSP_FLAG_LISTEN) { if (rt->state == RTSP_STATE_STREAMING) { - if (!ff_rtsp_parse_streaming_commands(s)) - return AVERROR_EOF; - else - av_log(s, AV_LOG_WARNING, - "Unable to answer to TEARDOWN\n"); + return ff_rtsp_parse_streaming_commands(s); } else - return 0; + return AVERROR_EOF; } else { RTSPMessageHeader reply; ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL); @@ -1989,12 +2032,13 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, { RTSPState *rt = s->priv_data; RTSPStream *rtsp_st; - int n, i, ret, timeout_cnt = 0; + int n, i, ret; struct pollfd *p = rt->p; int *fds = NULL, fdsnum, fdsidx; + int runs = rt->initial_timeout * 1000LL / POLLING_TIME; if (!p) { - p = rt->p = av_malloc_array(2 * (rt->nb_rtsp_streams + 1), sizeof(struct pollfd)); + p = rt->p = av_malloc_array(2 * rt->nb_rtsp_streams + 1, sizeof(*p)); if (!p) return AVERROR(ENOMEM); @@ -2029,10 +2073,9 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, return AVERROR_EXIT; if (wait_end && wait_end - av_gettime_relative() < 0) return AVERROR(EAGAIN); - n = poll(p, rt->max_p, POLL_TIMEOUT_MS); + n = poll(p, rt->max_p, POLLING_TIME); if (n > 0) { int j = rt->rtsp_hd ? 1 : 0; - timeout_cnt = 0; for (i = 0; i < rt->nb_rtsp_streams; i++) { rtsp_st = rt->rtsp_streams[i]; if (rtsp_st->rtp_handle) { @@ -2053,7 +2096,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, } } #endif - } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) { + } else if (n == 0 && rt->initial_timeout > 0 && --runs <= 0) { return AVERROR(ETIMEDOUT); } else if (n < 0 && errno != EINTR) return AVERROR(errno); @@ -2259,9 +2302,7 @@ redo: s->start_time_realtime = av_rescale (rtpctx->first_rtcp_ntp_time - (NTP_OFFSET << 32), 1000000, 1LL << 32); if (rtpctx->st) { s->start_time_realtime -= - av_rescale (rtpctx->rtcp_ts_offset, - (uint64_t) rtpctx->st->time_base.num * 1000000, - rtpctx->st->time_base.den); + av_rescale_q (rtpctx->rtcp_ts_offset, rtpctx->st->time_base, AV_TIME_BASE_Q); } } } @@ -2338,7 +2379,7 @@ static int sdp_read_header(AVFormatContext *s) RTSPStream *rtsp_st; int size, i, err; char *content; - char url[1024]; + char url[MAX_URL_SIZE]; if (!ff_network_init()) return AVERROR(EIO); @@ -2351,11 +2392,14 @@ static int sdp_read_header(AVFormatContext *s) /* read the whole sdp file */ /* XXX: better loading */ content = av_malloc(SDP_MAX_SIZE); - if (!content) + if (!content) { + ff_network_close(); return AVERROR(ENOMEM); + } size = avio_read(s->pb, content, SDP_MAX_SIZE - 1); if (size <= 0) { av_free(content); + ff_network_close(); return AVERROR_INVALIDDATA; } content[size] ='\0'; @@ -2462,12 +2506,15 @@ static int rtp_read_header(AVFormatContext *s) RTSPState *rt = s->priv_data; const char *p; AVBPrint sdp; + AVDictionary *opts = NULL; if (!ff_network_init()) return AVERROR(EIO); + opts = map_to_opts(rt); ret = ffurl_open_whitelist(&in, s->url, AVIO_FLAG_READ, - &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist, NULL); + &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL); + av_dict_free(&opts); if (ret) goto fail; @@ -2507,6 +2554,7 @@ static int rtp_read_header(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d " "without an SDP file describing it\n", payload_type); + ret = AVERROR_INVALIDDATA; goto fail; } if (par->codec_type != AVMEDIA_TYPE_DATA) { @@ -2553,7 +2601,9 @@ static int rtp_read_header(AVFormatContext *s) ffio_init_context(&pb, sdp.str, sdp.len, 0, NULL, NULL, NULL, NULL); s->pb = &pb; - /* sdp_read_header initializes this again */ + /* if sdp_read_header() fails then following ff_network_close() cancels out */ + /* ff_network_init() at the start of this function. Otherwise it cancels out */ + /* ff_network_init() inside sdp_read_header() */ ff_network_close(); rt->media_type_mask = (1 << (AVMEDIA_TYPE_SUBTITLE+1)) - 1; diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h index 54a9a30c1..1310dd9c0 100644 --- a/libavformat/rtsp.h +++ b/libavformat/rtsp.h @@ -27,6 +27,7 @@ #include "rtpdec.h" #include "network.h" #include "httpauth.h" +#include "internal.h" #include "libavutil/log.h" #include "libavutil/opt.h" @@ -78,6 +79,7 @@ enum RTSPControlTransport { #define RTSP_DEFAULT_AUDIO_SAMPLERATE 44100 #define RTSP_RTP_PORT_MIN 5000 #define RTSP_RTP_PORT_MAX 65000 +#define SDP_MAX_SIZE 16384 /** * This describes a single item in the "Transport:" line of one stream as @@ -186,6 +188,11 @@ typedef struct RTSPMessageHeader { * Content type header */ char content_type[64]; + + /** + * SAT>IP com.ses.streamID header + */ + char stream_id[64]; } RTSPMessageHeader; /** @@ -208,6 +215,7 @@ enum RTSPServerType { RTSP_SERVER_RTP, /**< Standards-compliant RTP-server */ RTSP_SERVER_REAL, /**< Realmedia-style server */ RTSP_SERVER_WMS, /**< Windows Media server */ + RTSP_SERVER_SATIP,/**< SAT>IP server */ RTSP_SERVER_NB }; @@ -315,7 +323,7 @@ typedef struct RTSPState { /** some MS RTSP streams contain a URL in the SDP that we need to use * for all subsequent RTSP requests, rather than the input URI; in * other cases, this is a copy of AVFormatContext->filename. */ - char control_uri[1024]; + char control_uri[MAX_URL_SIZE]; /** The following are used for parsing raw mpegts in udp */ //@{ @@ -421,6 +429,7 @@ typedef struct RTSPState { #define RTSP_FLAG_RTCP_TO_SOURCE 0x8 /**< Send RTCP packets to the source address of received packets. */ #define RTSP_FLAG_PREFER_TCP 0x10 /**< Try RTP via TCP first if possible. */ +#define RTSP_FLAG_SATIP_RAW 0x20 /**< Export SAT>IP stream as raw MPEG-TS */ typedef struct RTSPSource { char addr[128]; /**< Source-specific multicast include source IP address (from SDP content) */ @@ -443,7 +452,7 @@ typedef struct RTSPStream { * for the selected transport. Only used for TCP. */ int interleaved_min, interleaved_max; - char control_url[1024]; /**< url for this stream (from SDP) */ + char control_url[MAX_URL_SIZE]; /**< url for this stream (from SDP) */ /** The following are used only in SDP, not RTSP */ //@{ diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c index dfa29913b..113da975e 100644 --- a/libavformat/rtspdec.c +++ b/libavformat/rtspdec.c @@ -97,7 +97,7 @@ static int rtsp_send_reply(AVFormatContext *s, enum RTSPStatusCode code, const char *extracontent, uint16_t seq) { RTSPState *rt = s->priv_data; - char message[4096]; + char message[MAX_URL_SIZE]; int index = 0; while (status_messages[index].code) { if (status_messages[index].code == code) { @@ -143,7 +143,7 @@ static inline int rtsp_read_request(AVFormatContext *s, const char *method) { RTSPState *rt = s->priv_data; - char rbuf[1024]; + char rbuf[MAX_URL_SIZE]; int rbuflen, ret; do { ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen); @@ -172,7 +172,7 @@ static int rtsp_read_announce(AVFormatContext *s) { RTSPState *rt = s->priv_data; RTSPMessageHeader request = { 0 }; - char sdp[4096]; + char sdp[SDP_MAX_SIZE]; int ret; ret = rtsp_read_request(s, &request, "ANNOUNCE"); @@ -232,9 +232,9 @@ static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl) RTSPState *rt = s->priv_data; RTSPMessageHeader request = { 0 }; int ret = 0; - char url[1024]; + char url[MAX_URL_SIZE]; RTSPStream *rtsp_st; - char responseheaders[1024]; + char responseheaders[MAX_URL_SIZE]; int localport = -1; int transportidx = 0; int streamid = 0; @@ -274,6 +274,17 @@ static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl) rtsp_st = rt->rtsp_streams[streamid]; localport = rt->rtp_port_min; + /* check if the stream has already been setup */ + if (rtsp_st->transport_priv) { + if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT) + ff_rdt_parse_close(rtsp_st->transport_priv); + else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP) + ff_rtp_parse_close(rtsp_st->transport_priv); + rtsp_st->transport_priv = NULL; + } + if (rtsp_st->rtp_handle) + ffurl_closep(&rtsp_st->rtp_handle); + if (request.transports[0].lower_transport == RTSP_LOWER_TRANSPORT_TCP) { rt->lower_transport = RTSP_LOWER_TRANSPORT_TCP; if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) { @@ -291,7 +302,7 @@ static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl) AVDictionary *opts = NULL; av_dict_set_int(&opts, "buffer_size", rt->buffer_size, 0); ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL); - av_log(s, AV_LOG_TRACE, "Opening: %s", url); + av_log(s, AV_LOG_TRACE, "Opening: %s\n", url); ret = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL); @@ -304,7 +315,7 @@ static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl) return ret; } - av_log(s, AV_LOG_TRACE, "Listening on: %d", + av_log(s, AV_LOG_TRACE, "Listening on: %d\n", ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle)); if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) { rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq); @@ -340,7 +351,7 @@ static int rtsp_read_record(AVFormatContext *s) RTSPState *rt = s->priv_data; RTSPMessageHeader request = { 0 }; int ret = 0; - char responseheaders[1024]; + char responseheaders[MAX_URL_SIZE]; ret = rtsp_read_request(s, &request, "RECORD"); if (ret) @@ -463,7 +474,7 @@ static inline int parse_command_line(AVFormatContext *s, const char *line, int ff_rtsp_parse_streaming_commands(AVFormatContext *s) { RTSPState *rt = s->priv_data; - unsigned char rbuf[4096]; + unsigned char rbuf[MAX_URL_SIZE]; unsigned char method[10]; char uri[500]; int ret; @@ -474,6 +485,7 @@ int ff_rtsp_parse_streaming_commands(AVFormatContext *s) ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen); if (ret < 0) return ret; + av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf); ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method, sizeof(method), &methodcode); if (ret) { @@ -505,7 +517,7 @@ static int rtsp_read_play(AVFormatContext *s) RTSPState *rt = s->priv_data; RTSPMessageHeader reply1, *reply = &reply1; int i; - char cmd[1024]; + char cmd[MAX_URL_SIZE]; av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state); rt->nb_byes = 0; @@ -591,7 +603,7 @@ static int rtsp_read_pause(AVFormatContext *s) int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply) { RTSPState *rt = s->priv_data; - char cmd[1024]; + char cmd[MAX_URL_SIZE]; unsigned char *content = NULL; int ret; @@ -634,12 +646,15 @@ static int rtsp_listen(AVFormatContext *s) int default_port = RTSP_DEFAULT_PORT; char tcpname[500]; const char *lower_proto = "tcp"; - unsigned char rbuf[4096]; + unsigned char rbuf[MAX_URL_SIZE]; unsigned char method[10]; int rbuflen = 0; int ret; enum RTSPMethod methodcode; + if (!ff_network_init()) + return AVERROR(EIO); + /* extract hostname and port */ av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host), &port, path, sizeof(path), s->url); @@ -664,19 +679,20 @@ static int rtsp_listen(AVFormatContext *s) &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist, NULL)) { av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n"); - return ret; + goto fail; } rt->state = RTSP_STATE_IDLE; rt->rtsp_hd_out = rt->rtsp_hd; for (;;) { /* Wait for incoming RTSP messages */ ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen); if (ret < 0) - return ret; + goto fail; + av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf); ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method, sizeof(method), &methodcode); if (ret) { av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n"); - return ret; + goto fail; } if (methodcode == ANNOUNCE) { @@ -691,10 +707,15 @@ static int rtsp_listen(AVFormatContext *s) } else if (methodcode == SETUP) ret = rtsp_read_setup(s, host, uri); if (ret) { - ffurl_close(rt->rtsp_hd); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } } +fail: + ff_rtsp_close_streams(s); + ff_rtsp_close_connections(s); + ff_network_close(); + return ret; } static int rtsp_probe(const AVProbeData *p) @@ -703,6 +724,7 @@ static int rtsp_probe(const AVProbeData *p) #if CONFIG_TLS_PROTOCOL av_strstart(p->filename, "rtsps:", NULL) || #endif + av_strstart(p->filename, "satip:", NULL) || av_strstart(p->filename, "rtsp:", NULL)) return AVPROBE_SCORE_MAX; return 0; @@ -727,22 +749,26 @@ static int rtsp_read_header(AVFormatContext *s) rt->real_setup_cache = !s->nb_streams ? NULL : av_mallocz_array(s->nb_streams, 2 * sizeof(*rt->real_setup_cache)); - if (!rt->real_setup_cache && s->nb_streams) - return AVERROR(ENOMEM); + if (!rt->real_setup_cache && s->nb_streams) { + ret = AVERROR(ENOMEM); + goto fail; + } rt->real_setup = rt->real_setup_cache + s->nb_streams; if (rt->initial_pause) { /* do not start immediately */ } else { - if ((ret = rtsp_read_play(s)) < 0) { - ff_rtsp_close_streams(s); - ff_rtsp_close_connections(s); - return ret; - } + ret = rtsp_read_play(s); + if (ret < 0) + goto fail; } } return 0; + +fail: + rtsp_read_close(s); + return ret; } int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, @@ -768,7 +794,7 @@ redo: } ret = ffurl_read_complete(rt->rtsp_hd, buf, 3); if (ret != 3) - return -1; + return AVERROR(EIO); id = buf[0]; len = AV_RB16(buf + 1); av_log(s, AV_LOG_TRACE, "id=%d len=%d\n", id, len); @@ -777,10 +803,10 @@ redo: /* get the data */ ret = ffurl_read_complete(rt->rtsp_hd, buf, len); if (ret != len) - return -1; + return AVERROR(EIO); if (rt->transport == RTSP_TRANSPORT_RDT && - ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0) - return -1; + (ret = ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL)) < 0) + return ret; /* find the matching stream */ for (i = 0; i < rt->nb_rtsp_streams; i++) { @@ -813,7 +839,7 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) RTSPState *rt = s->priv_data; int ret; RTSPMessageHeader reply1, *reply = &reply1; - char cmd[1024]; + char cmd[MAX_URL_SIZE]; retry: if (rt->server_type == RTSP_SERVER_REAL) { diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c index 97e3ef6da..c32022743 100644 --- a/libavformat/rtspenc.c +++ b/libavformat/rtspenc.c @@ -34,7 +34,6 @@ #include "libavutil/time.h" #include "url.h" -#define SDP_MAX_SIZE 16384 static const AVClass rtsp_muxer_class = { .class_name = "RTSP muxer", @@ -50,7 +49,7 @@ int ff_rtsp_setup_output_streams(AVFormatContext *s, const char *addr) int i; char *sdp; AVFormatContext sdp_ctx, *ctx_array[1]; - char url[1024]; + char url[MAX_URL_SIZE]; if (s->start_time_realtime == 0 || s->start_time_realtime == AV_NOPTS_VALUE) s->start_time_realtime = av_gettime(); @@ -112,7 +111,7 @@ static int rtsp_write_record(AVFormatContext *s) { RTSPState *rt = s->priv_data; RTSPMessageHeader reply1, *reply = &reply1; - char cmd[1024]; + char cmd[MAX_URL_SIZE]; snprintf(cmd, sizeof(cmd), "Range: npt=0.000-\r\n"); diff --git a/libavformat/samidec.c b/libavformat/samidec.c index cf5076c7b..d84f56ce6 100644 --- a/libavformat/samidec.c +++ b/libavformat/samidec.c @@ -89,6 +89,7 @@ static int sami_read_header(AVFormatContext *s) sub = ff_subtitles_queue_insert(&sami->q, buf.str, buf.len, !is_sync); if (!sub) { res = AVERROR(ENOMEM); + av_bprint_finalize(&hdr_buf, NULL); goto end; } if (is_sync) { @@ -97,6 +98,7 @@ static int sami_read_header(AVFormatContext *s) sub->pts = p ? strtol(p, NULL, 10) : 0; if (sub->pts <= INT64_MIN/2 || sub->pts >= INT64_MAX/2) { res = AVERROR_PATCHWELCOME; + av_bprint_finalize(&hdr_buf, NULL); goto end; } diff --git a/libavformat/sbgdec.c b/libavformat/sbgdec.c index d2a5a82c2..83016d0c1 100644 --- a/libavformat/sbgdec.c +++ b/libavformat/sbgdec.c @@ -476,6 +476,8 @@ static int parse_timestamp(struct sbg_parser *p, while (lex_char(p, '+')) { if (!lex_time(p, &dt)) return AVERROR_INVALIDDATA; + if (av_sat_add64(rel, dt) - dt != rel) + return AVERROR_INVALIDDATA; rel += dt; r = 1; } @@ -889,7 +891,7 @@ fail: return size; } -static void expand_timestamps(void *log, struct sbg_script *s) +static int expand_timestamps(void *log, struct sbg_script *s) { int i, nb_rel = 0; int64_t now, cur_ts, delta = 0; @@ -937,10 +939,13 @@ static void expand_timestamps(void *log, struct sbg_script *s) AV_NOPTS_VALUE; /* may be overridden later by -E option */ cur_ts = now; for (i = 0; i < s->nb_tseq; i++) { + if (av_sat_add64(s->tseq[i].ts.t, delta) != s->tseq[i].ts.t + (uint64_t)delta) + return AVERROR_INVALIDDATA; if (s->tseq[i].ts.t + delta < cur_ts) delta += DAY_TS; cur_ts = s->tseq[i].ts.t += delta; } + return 0; } static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max, @@ -993,7 +998,9 @@ static int expand_script(void *log, struct sbg_script *s) { int i, r, nb_events_max = 0; - expand_timestamps(log, s); + r = expand_timestamps(log, s); + if (r < 0) + return r; for (i = 0; i < s->nb_tseq; i++) { r = expand_tseq(log, s, &nb_events_max, 0, &s->tseq[i]); if (r < 0) diff --git a/libavformat/sccdec.c b/libavformat/sccdec.c index df4c94a6e..178652094 100644 --- a/libavformat/sccdec.c +++ b/libavformat/sccdec.c @@ -63,10 +63,9 @@ static int scc_read_header(AVFormatContext *s) { SCCContext *scc = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - char line[4096], line2[4096]; - int64_t ts_start, ts_end; - int count = 0, ret = 0; - ptrdiff_t len2, len; + char line2[4096], line[4096]; + int64_t pos, ts, next_ts = AV_NOPTS_VALUE; + ptrdiff_t len; uint8_t out[4096]; FFTextReader tr; @@ -78,83 +77,104 @@ static int scc_read_header(AVFormatContext *s) st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_EIA_608; - while (!ff_text_eof(&tr)) { - int64_t current_pos, next_pos; + while (!ff_text_eof(&tr) || next_ts == AV_NOPTS_VALUE || line2[0]) { char *saveptr = NULL, *lline; - int hh1, mm1, ss1, fs1, i; - int hh2, mm2, ss2, fs2; + int hh, mm, ss, fs, i; AVPacket *sub; - if (count == 0) { - current_pos = ff_text_pos(&tr); + if (next_ts == AV_NOPTS_VALUE) { while (!ff_text_eof(&tr)) { len = ff_subtitles_read_line(&tr, line, sizeof(line)); - if (len > 13) + if (len <= 13) + continue; + if (!strncmp(line, "Scenarist_SCC V1.0", 18)) + continue; + if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) + break; + } + + ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33LL; + + while (!ff_text_eof(&tr)) { + len = ff_subtitles_read_line(&tr, line2, sizeof(line2)); + if (len <= 13) + continue; + + if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) + break; + } + } else { + memmove(line, line2, sizeof(line)); + line2[0] = 0; + + while (!ff_text_eof(&tr)) { + len = ff_subtitles_read_line(&tr, line2, sizeof(line2)); + if (len <= 13) + continue; + + if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) break; } } - if (!strncmp(line, "Scenarist_SCC V1.0", 18)) - continue; - if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh1, &mm1, &ss1, &fs1) != 4) - continue; + next_ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33LL; - ts_start = (hh1 * 3600LL + mm1 * 60LL + ss1) * 1000LL + fs1 * 33; - - next_pos = ff_text_pos(&tr); - while (!ff_text_eof(&tr)) { - len2 = ff_subtitles_read_line(&tr, line2, sizeof(line2)); - if (len2 > 13) - break; - } - if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh2, &mm2, &ss2, &fs2) != 4) - continue; - - ts_end = (hh2 * 3600LL + mm2 * 60LL + ss2) * 1000LL + fs2 * 33; - count++; - -try_again: + pos = ff_text_pos(&tr); lline = (char *)&line; lline += 12; for (i = 0; i < 4095; i += 3) { char *ptr = av_strtok(lline, " ", &saveptr); char c1, c2, c3, c4; + uint8_t o1, o2; if (!ptr) break; if (av_sscanf(ptr, "%c%c%c%c", &c1, &c2, &c3, &c4) != 4) break; + o1 = convert(c2) | (convert(c1) << 4); + o2 = convert(c4) | (convert(c3) << 4); lline = NULL; + + if (i > 12 && o1 == 0x94 && o2 == 0x20 && saveptr && + (av_strncasecmp(saveptr, "942f", 4) && !av_strncasecmp(saveptr, "942c", 4))) { + + out[i] = 0; + + sub = ff_subtitles_queue_insert(&scc->q, out, i, 0); + if (!sub) + goto fail; + + sub->pos = pos; + pos += i; + sub->pts = ts; + sub->duration = i * 11; + ts += sub->duration; + i = 0; + } + out[i+0] = 0xfc; - out[i+1] = convert(c2) | (convert(c1) << 4); - out[i+2] = convert(c4) | (convert(c3) << 4); + out[i+1] = o1; + out[i+2] = o2; } + out[i] = 0; sub = ff_subtitles_queue_insert(&scc->q, out, i, 0); if (!sub) goto fail; - sub->pos = current_pos; - sub->pts = ts_start; - sub->duration = ts_end - ts_start; - memmove(line, line2, sizeof(line)); - current_pos = next_pos; - line2[0] = 0; - } - - if (line[0]) { - ts_start = ts_end; - ts_end += 1200; - goto try_again; + sub->pos = pos; + sub->pts = ts; + sub->duration = next_ts - ts; + ts = next_ts; } ff_subtitles_queue_finalize(s, &scc->q); - return ret; + return 0; fail: ff_subtitles_queue_clean(&scc->q); return AVERROR(ENOMEM); diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 2ce1a6226..95f3fbb87 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -704,6 +704,8 @@ static char *sdp_write_media_attributes(char *buff, int size, AVStream *st, int case AV_CODEC_ID_SPEEX: av_strlcatf(buff, size, "a=rtpmap:%d speex/%d\r\n", payload_type, p->sample_rate); +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS if (st->codec) { const char *mode; uint64_t vad_option; @@ -718,6 +720,8 @@ static char *sdp_write_media_attributes(char *buff, int size, AVStream *st, int av_strlcatf(buff, size, "a=fmtp:%d vbr=%s\r\n", payload_type, mode); } +FF_ENABLE_DEPRECATION_WARNINGS +#endif break; case AV_CODEC_ID_OPUS: /* The opus RTP draft says that all opus streams MUST be declared diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index 01422bdee..91cd7b7c2 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -40,8 +40,8 @@ typedef struct film_sample { int stream; - int64_t sample_offset; unsigned int sample_size; + int64_t sample_offset; int64_t pts; int keyframe; } film_sample; diff --git a/libavformat/segafilmenc.c b/libavformat/segafilmenc.c index 93c482ef7..42249d4ef 100644 --- a/libavformat/segafilmenc.c +++ b/libavformat/segafilmenc.c @@ -29,87 +29,28 @@ * http://wiki.multimedia.cx/index.php?title=Sega_FILM */ +#include "libavutil/avassert.h" #include "libavutil/intreadwrite.h" +#include "libavcodec/bytestream.h" #include "avformat.h" #include "internal.h" #include "avio_internal.h" -typedef struct FILMPacket { - int audio; - int keyframe; - int32_t pts; - int32_t duration; - int32_t size; - int32_t index; - struct FILMPacket *next; -} FILMPacket; - typedef struct FILMOutputContext { + AVIOContext *header; + unsigned index; int audio_index; int video_index; - int64_t stab_pos; - FILMPacket *start; - FILMPacket *last; - int64_t packet_count; } FILMOutputContext; -static int film_write_packet_to_header(AVFormatContext *format_context, FILMPacket *pkt) -{ - AVIOContext *pb = format_context->pb; - /* The bits in these two 32-bit integers contain info about the contents of this sample */ - int32_t info1 = 0; - int32_t info2 = 0; - - if (pkt->audio) { - /* Always the same, carries no more information than "this is audio" */ - info1 = 0xFFFFFFFF; - info2 = 1; - } else { - info1 = pkt->pts; - info2 = pkt->duration; - /* The top bit being set indicates a key frame */ - if (!pkt->keyframe) - info1 |= 1U << 31; - } - - /* Write the 16-byte sample info packet to the STAB chunk in the header */ - avio_wb32(pb, pkt->index); - avio_wb32(pb, pkt->size); - avio_wb32(pb, info1); - avio_wb32(pb, info2); - - return 0; -} - static int film_write_packet(AVFormatContext *format_context, AVPacket *pkt) { - FILMPacket *metadata; AVIOContext *pb = format_context->pb; FILMOutputContext *film = format_context->priv_data; - int encoded_buf_size = 0; + int encoded_buf_size, size = pkt->size; + uint32_t info1, info2; enum AVCodecID codec_id; - /* Track the metadata used to write the header and add it to the linked list */ - metadata = av_mallocz(sizeof(FILMPacket)); - if (!metadata) - return AVERROR(ENOMEM); - metadata->audio = pkt->stream_index == film->audio_index; - metadata->keyframe = pkt->flags & AV_PKT_FLAG_KEY; - metadata->pts = pkt->pts; - metadata->duration = pkt->duration; - metadata->size = pkt->size; - if (film->last == NULL) { - metadata->index = 0; - } else { - metadata->index = film->last->index + film->last->size; - film->last->next = metadata; - } - metadata->next = NULL; - if (film->start == NULL) - film->start = metadata; - film->packet_count++; - film->last = metadata; - codec_id = format_context->streams[pkt->stream_index]->codecpar->codec_id; /* Sega Cinepak has an extra two-byte header; write dummy data there, @@ -120,15 +61,14 @@ static int film_write_packet(AVFormatContext *format_context, AVPacket *pkt) if (encoded_buf_size != pkt->size && (pkt->size % encoded_buf_size) != 0) { avio_write(pb, pkt->data, pkt->size); } else { - uint8_t padding[2] = {0, 0}; /* In Sega Cinepak, the reported size in the Cinepak header is * 8 bytes too short. However, the size in the STAB section of the header * is correct, taking into account the extra two bytes. */ AV_WB24(&pkt->data[1], pkt->size - 8 + 2); - metadata->size += 2; + size += 2; avio_write(pb, pkt->data, 10); - avio_write(pb, padding, 2); + avio_wb16(pb, 0); avio_write(pb, &pkt->data[10], pkt->size - 10); } } else { @@ -136,7 +76,27 @@ static int film_write_packet(AVFormatContext *format_context, AVPacket *pkt) avio_write(pb, pkt->data, pkt->size); } - return 0; + /* Add the 16-byte sample info entry to the dynamic buffer + * for the STAB chunk in the header */ + pb = film->header; + avio_wb32(pb, film->index); + film->index += size; + avio_wb32(pb, size); + if (film->audio_index == pkt->stream_index) { + /* Always the same, carries no more information than "this is audio" */ + info1 = 0xFFFFFFFF; + info2 = 1; + } else { + info1 = pkt->pts; + info2 = pkt->duration; + /* The top bit being set indicates a key frame */ + if (!(pkt->flags & AV_PKT_FLAG_KEY)) + info1 |= 1U << 31; + } + avio_wb32(pb, info1); + avio_wb32(pb, info2); + + return pb->error; } static int get_audio_codec_id(enum AVCodecID codec_id) @@ -156,12 +116,10 @@ static int get_audio_codec_id(enum AVCodecID codec_id) static int film_init(AVFormatContext *format_context) { FILMOutputContext *film = format_context->priv_data; + int ret; + film->audio_index = -1; film->video_index = -1; - film->stab_pos = 0; - film->packet_count = 0; - film->start = NULL; - film->last = NULL; for (int i = 0; i < format_context->nb_streams; i++) { AVStream *st = format_context->streams[i]; @@ -202,11 +160,15 @@ static int film_init(AVFormatContext *format_context) av_log(format_context, AV_LOG_ERROR, "No video stream present.\n"); return AVERROR(EINVAL); } + if ((ret = avio_open_dyn_buf(&film->header)) < 0) + return ret; + ffio_fill(film->header, 0, 16 + 32 + 16); return 0; } -static int shift_data(AVFormatContext *format_context, int64_t shift_size) +static int write_header(AVFormatContext *format_context, uint8_t *header, + unsigned header_size) { int ret = 0; int64_t pos, pos_end; @@ -215,11 +177,12 @@ static int shift_data(AVFormatContext *format_context, int64_t shift_size) int read_size[2]; AVIOContext *read_pb; - buf = av_malloc(shift_size * 2); + buf = av_malloc(header_size); if (!buf) return AVERROR(ENOMEM); read_buf[0] = buf; - read_buf[1] = buf + shift_size; + read_buf[1] = header; + read_size[1] = header_size; /* Write the header at the beginning of the file, shifting all content as necessary; * based on the approach used by MOV faststart. */ @@ -232,25 +195,20 @@ static int shift_data(AVFormatContext *format_context, int64_t shift_size) return ret; } - /* mark the end of the shift to up to the last data we wrote, and get ready - * for writing */ - pos_end = avio_tell(format_context->pb); - avio_seek(format_context->pb, shift_size, SEEK_SET); + /* Mark the end of the shift to up to the last data we are going to write, + * and get ready for writing */ + pos_end = avio_tell(format_context->pb) + header_size; + pos = avio_seek(format_context->pb, 0, SEEK_SET); /* start reading at where the new header will be placed */ avio_seek(read_pb, 0, SEEK_SET); - pos = avio_tell(read_pb); -#define READ_BLOCK do { \ - read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], shift_size); \ - read_buf_id ^= 1; \ -} while (0) - - /* shift data by chunk of at most shift_size */ - READ_BLOCK; + /* shift data by chunk of at most header_size */ do { int n; - READ_BLOCK; + read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], + header_size); + read_buf_id ^= 1; n = read_size[read_buf_id]; if (n <= 0) break; @@ -266,79 +224,75 @@ static int shift_data(AVFormatContext *format_context, int64_t shift_size) static int film_write_header(AVFormatContext *format_context) { int ret = 0; - int64_t sample_table_size, stabsize, headersize; - AVIOContext *pb = format_context->pb; + unsigned stabsize, headersize, packet_count; FILMOutputContext *film = format_context->priv_data; - FILMPacket *prev, *packet; AVStream *video = NULL; + uint8_t *header, *ptr; /* Calculate how much we need to reserve for the header; * this is the amount the rest of the data will be shifted up by. */ - sample_table_size = film->packet_count * 16; - stabsize = 16 + sample_table_size; + headersize = avio_get_dyn_buf(film->header, &header); + if (headersize < 64) { + av_assert1(film->header->error < 0); + return film->header->error; + } + packet_count = (headersize - 64) / 16; + stabsize = 16 + 16 * packet_count; headersize = 16 + /* FILM header base */ 32 + /* FDSC chunk */ stabsize; - ret = shift_data(format_context, headersize); - if (ret < 0) - return ret; - /* Seek back to the beginning to start writing the header now */ - avio_seek(pb, 0, SEEK_SET); - - /* First, write the FILM header; this is very simple */ - - ffio_wfourcc(pb, "FILM"); - avio_wb32(pb, 48 + stabsize); + /* Write the header at the position in the buffer reserved for it. + * First, write the FILM header; this is very simple */ + ptr = header; + bytestream_put_be32(&ptr, MKBETAG('F', 'I', 'L', 'M')); + bytestream_put_be32(&ptr, headersize); /* This seems to be okay to hardcode, since this muxer targets 1.09 features; * videos produced by this muxer are readable by 1.08 and lower players. */ - ffio_wfourcc(pb, "1.09"); - /* I have no idea what this field does, might be reserved */ - avio_wb32(pb, 0); + bytestream_put_be32(&ptr, MKBETAG('1', '.', '0', '9')); + /* I have no idea what the next four bytes do, might be reserved */ + ptr += 4; /* Next write the FDSC (file description) chunk */ - ffio_wfourcc(pb, "FDSC"); - avio_wb32(pb, 0x20); /* Size of FDSC chunk */ + bytestream_put_be32(&ptr, MKBETAG('F', 'D', 'S', 'C')); + bytestream_put_be32(&ptr, 0x20); /* Size of FDSC chunk */ video = format_context->streams[film->video_index]; /* The only two supported codecs; raw video is rare */ switch (video->codecpar->codec_id) { case AV_CODEC_ID_CINEPAK: - ffio_wfourcc(pb, "cvid"); + bytestream_put_be32(&ptr, MKBETAG('c', 'v', 'i', 'd')); break; case AV_CODEC_ID_RAWVIDEO: - ffio_wfourcc(pb, "raw "); + bytestream_put_be32(&ptr, MKBETAG('r', 'a', 'w', ' ')); break; } - avio_wb32(pb, video->codecpar->height); - avio_wb32(pb, video->codecpar->width); - avio_w8(pb, 24); /* Bits per pixel - observed to always be 24 */ + bytestream_put_be32(&ptr, video->codecpar->height); + bytestream_put_be32(&ptr, video->codecpar->width); + bytestream_put_byte(&ptr, 24); /* Bits per pixel - observed to always be 24 */ if (film->audio_index > -1) { AVStream *audio = format_context->streams[film->audio_index]; int audio_codec = get_audio_codec_id(audio->codecpar->codec_id); - avio_w8(pb, audio->codecpar->channels); /* Audio channels */ - avio_w8(pb, audio->codecpar->bits_per_coded_sample); /* Audio bit depth */ - avio_w8(pb, audio_codec); /* Compression - 0 is PCM, 2 is ADX */ - avio_wb16(pb, audio->codecpar->sample_rate); /* Audio sampling rate */ + bytestream_put_byte(&ptr, audio->codecpar->channels); /* Audio channels */ + bytestream_put_byte(&ptr, audio->codecpar->bits_per_coded_sample); /* Audio bit depth */ + bytestream_put_byte(&ptr, audio_codec); /* Compression - 0 is PCM, 2 is ADX */ + bytestream_put_be16(&ptr, audio->codecpar->sample_rate); /* Audio sampling rate */ } else { - /* Set all these fields to 0 if there's no audio */ - avio_w8(pb, 0); - avio_w8(pb, 0); - avio_w8(pb, 0); - avio_wb16(pb, 0); + /* If there is no audio, all the audio fields should be set to zero. + * ffio_fill() already did this for us. */ + ptr += 1 + 1 + 1 + 2; } /* I have no idea what this pair of fields does either, might be reserved */ - avio_wb32(pb, 0); - avio_wb16(pb, 0); + ptr += 4 + 2; /* Finally, write the STAB (sample table) chunk */ - ffio_wfourcc(pb, "STAB"); - avio_wb32(pb, 16 + (film->packet_count * 16)); + bytestream_put_be32(&ptr, MKBETAG('S', 'T', 'A', 'B')); + bytestream_put_be32(&ptr, stabsize); /* Framerate base frequency. Here we're assuming that the frame rate is even. * In real world Sega FILM files, there are usually a couple of approaches: * a) framerate base frequency is the same as the framerate, and ticks @@ -348,19 +302,14 @@ static int film_write_header(AVFormatContext *format_context) * The latter occurs even in cases where the frame rate is even; for example, in * Lunar: Silver Star Story, the base frequency is 600 and each frame, the ticks * are incremented by 25 for an evenly spaced framerate of 24fps. */ - avio_wb32(pb, av_q2d(av_inv_q(video->time_base))); + bytestream_put_be32(&ptr, av_q2d(av_inv_q(video->time_base))); - avio_wb32(pb, film->packet_count); + bytestream_put_be32(&ptr, packet_count); - /* Finally, write out each packet's data to the header */ - packet = film->start; - while (packet != NULL) { - film_write_packet_to_header(format_context, packet); - prev = packet; - packet = packet->next; - av_freep(&prev); - } - film->start = film->last = NULL; + /* Finally, shift the data and write out the header. */ + ret = write_header(format_context, header, headersize); + if (ret < 0) + return ret; return 0; } @@ -368,13 +317,8 @@ static int film_write_header(AVFormatContext *format_context) static void film_deinit(AVFormatContext *format_context) { FILMOutputContext *film = format_context->priv_data; - FILMPacket *packet = film->start; - while (packet != NULL) { - FILMPacket *next = packet->next; - av_free(packet); - packet = next; - } - film->start = film->last = NULL; + + ffio_free_dyn_buf(&film->header); } AVOutputFormat ff_segafilm_muxer = { diff --git a/libavformat/segment.c b/libavformat/segment.c index 2ff2b5372..5265ecaeb 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -80,6 +80,7 @@ typedef struct SegmentContext { int list_flags; ///< flags affecting list generation int list_size; ///< number of entries for the segment list file + int is_nullctx; ///< whether avf->pb is a nullctx int use_clocktime; ///< flag to cut segments at regular clock time int64_t clocktime_offset; //< clock offset for cutting the segments at regular clock time int64_t clocktime_wrap_duration; //< wrapping duration considered for starting a new segment @@ -90,7 +91,6 @@ typedef struct SegmentContext { char *entry_prefix; ///< prefix to add to list entry filenames int list_type; ///< set the list type AVIOContext *list_pb; ///< list file put-byte context - char *time_str; ///< segment duration specification string int64_t time; ///< segment duration int use_strftime; ///< flag to expand filename with strftime int increment_tc; ///< flag to increment timecode if found @@ -510,7 +510,7 @@ static int parse_times(void *log_ctx, int64_t **times, int *nb_times, /* check on monotonicity */ if (i && (*times)[i-1] > (*times)[i]) { av_log(log_ctx, AV_LOG_ERROR, - "Specified time %f is greater than the following time %f\n", + "Specified time %f is smaller than the last time %f\n", (float)((*times)[i])/1000000, (float)((*times)[i-1])/1000000); FAIL(AVERROR(EINVAL)); } @@ -524,60 +524,52 @@ end: static int parse_frames(void *log_ctx, int **frames, int *nb_frames, const char *frames_str) { - char *p; - int i, ret = 0; - char *frames_str1 = av_strdup(frames_str); - char *saveptr = NULL; - - if (!frames_str1) - return AVERROR(ENOMEM); - -#define FAIL(err) ret = err; goto end + const char *p; + int i; *nb_frames = 1; - for (p = frames_str1; *p; p++) + for (p = frames_str; *p; p++) if (*p == ',') (*nb_frames)++; *frames = av_malloc_array(*nb_frames, sizeof(**frames)); if (!*frames) { av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced frames array\n"); - FAIL(AVERROR(ENOMEM)); + return AVERROR(ENOMEM); } - p = frames_str1; + p = frames_str; for (i = 0; i < *nb_frames; i++) { long int f; char *tailptr; - char *fstr = av_strtok(p, ",", &saveptr); - p = NULL; - if (!fstr) { + if (*p == '\0' || *p == ',') { av_log(log_ctx, AV_LOG_ERROR, "Empty frame specification in frame list %s\n", frames_str); - FAIL(AVERROR(EINVAL)); + return AVERROR(EINVAL); } - f = strtol(fstr, &tailptr, 10); - if (*tailptr || f <= 0 || f >= INT_MAX) { + f = strtol(p, &tailptr, 10); + if (*tailptr != '\0' && *tailptr != ',' || f <= 0 || f >= INT_MAX) { av_log(log_ctx, AV_LOG_ERROR, - "Invalid argument '%s', must be a positive integer <= INT64_MAX\n", - fstr); - FAIL(AVERROR(EINVAL)); + "Invalid argument '%s', must be a positive integer < INT_MAX\n", + p); + return AVERROR(EINVAL); } + if (*tailptr == ',') + tailptr++; + p = tailptr; (*frames)[i] = f; /* check on monotonicity */ if (i && (*frames)[i-1] > (*frames)[i]) { av_log(log_ctx, AV_LOG_ERROR, - "Specified frame %d is greater than the following frame %d\n", + "Specified frame %d is smaller than the last frame %d\n", (*frames)[i], (*frames)[i-1]); - FAIL(AVERROR(EINVAL)); + return AVERROR(EINVAL); } } -end: - av_free(frames_str1); - return ret; + return 0; } static int open_null_ctx(AVIOContext **ctx) @@ -660,9 +652,28 @@ static int select_reference_stream(AVFormatContext *s) static void seg_free(AVFormatContext *s) { SegmentContext *seg = s->priv_data; - ff_format_io_close(seg->avf, &seg->list_pb); - avformat_free_context(seg->avf); - seg->avf = NULL; + SegmentListEntry *cur; + + ff_format_io_close(s, &seg->list_pb); + if (seg->avf) { + if (seg->is_nullctx) + close_null_ctxp(&seg->avf->pb); + else + ff_format_io_close(s, &seg->avf->pb); + avformat_free_context(seg->avf); + seg->avf = NULL; + } + av_freep(&seg->times); + av_freep(&seg->frames); + av_freep(&seg->cur_entry.filename); + + cur = seg->segment_list_entries; + while (cur) { + SegmentListEntry *next = cur->next; + av_freep(&cur->filename); + av_free(cur); + cur = next; + } } static int seg_init(AVFormatContext *s) @@ -687,7 +698,7 @@ static int seg_init(AVFormatContext *s) "you can use output_ts_offset instead of it\n"); } - if (!!seg->time_str + !!seg->times_str + !!seg->frames_str > 1) { + if ((seg->time != 2000000) + !!seg->times_str + !!seg->frames_str > 1) { av_log(s, AV_LOG_ERROR, "segment_time, segment_times, and segment_frames options " "are mutually exclusive, select just one of them\n"); @@ -701,15 +712,6 @@ static int seg_init(AVFormatContext *s) if ((ret = parse_frames(s, &seg->frames, &seg->nb_frames, seg->frames_str)) < 0) return ret; } else { - /* set default value if not specified */ - if (!seg->time_str) - seg->time_str = av_strdup("2"); - if ((ret = av_parse_time(&seg->time, seg->time_str, 1)) < 0) { - av_log(s, AV_LOG_ERROR, - "Invalid time duration specification '%s' for segment_time option\n", - seg->time_str); - return ret; - } if (seg->use_clocktime) { if (seg->time <= 0) { av_log(s, AV_LOG_ERROR, "Invalid negative segment_time with segment_atclocktime option set\n"); @@ -774,6 +776,7 @@ static int seg_init(AVFormatContext *s) } else { if ((ret = open_null_ctx(&oc->pb)) < 0) return ret; + seg->is_nullctx = 1; } av_dict_copy(&options, seg->format_options, 0); @@ -788,7 +791,6 @@ static int seg_init(AVFormatContext *s) av_dict_free(&options); if (ret < 0) { - ff_format_io_close(oc, &oc->pb); return ret; } seg->segment_frame_count = 0; @@ -817,26 +819,9 @@ static int seg_write_header(AVFormatContext *s) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; - int ret, i; + int ret; if (!seg->header_written) { - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = oc->streams[i]; - AVCodecParameters *ipar, *opar; - - ipar = s->streams[i]->codecpar; - opar = oc->streams[i]->codecpar; - avcodec_parameters_copy(opar, ipar); - if (!oc->oformat->codec_tag || - av_codec_get_id (oc->oformat->codec_tag, ipar->codec_tag) == opar->codec_id || - av_codec_get_tag(oc->oformat->codec_tag, ipar->codec_id) <= 0) { - opar->codec_tag = ipar->codec_tag; - } else { - opar->codec_tag = 0; - } - st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio; - st->time_base = s->streams[i]->time_base; - } ret = avformat_write_header(oc, NULL); if (ret < 0) return ret; @@ -848,6 +833,7 @@ static int seg_write_header(AVFormatContext *s) ff_format_io_close(oc, &oc->pb); } else { close_null_ctxp(&oc->pb); + seg->is_nullctx = 0; } if ((ret = oc->io_open(oc, &oc->pb, oc->url, AVIO_FLAG_WRITE, NULL)) < 0) return ret; @@ -873,7 +859,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EINVAL); if (!st->codecpar->extradata_size) { - int pkt_extradata_size = 0; + buffer_size_t pkt_extradata_size; uint8_t *pkt_extradata = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &pkt_extradata_size); if (pkt_extradata && pkt_extradata_size > 0) { ret = ff_alloc_extradata(st->codecpar, pkt_extradata_size); @@ -987,41 +973,21 @@ static int seg_write_trailer(struct AVFormatContext *s) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; - SegmentListEntry *cur, *next; - int ret = 0; + int ret; if (!oc) - goto fail; + return 0; if (!seg->write_header_trailer) { if ((ret = segment_end(s, 0, 1)) < 0) - goto fail; + return ret; if ((ret = open_null_ctx(&oc->pb)) < 0) - goto fail; + return ret; + seg->is_nullctx = 1; ret = av_write_trailer(oc); - close_null_ctxp(&oc->pb); } else { ret = segment_end(s, 1, 1); } -fail: - if (seg->list) - ff_format_io_close(s, &seg->list_pb); - - av_opt_free(seg); - av_freep(&seg->times); - av_freep(&seg->frames); - av_freep(&seg->cur_entry.filename); - - cur = seg->segment_list_entries; - while (cur) { - next = cur->next; - av_freep(&cur->filename); - av_free(cur); - cur = next; - } - - avformat_free_context(oc); - seg->avf = NULL; return ret; } @@ -1068,7 +1034,7 @@ static const AVOption options[] = { { "segment_atclocktime", "set segment to be cut at clocktime", OFFSET(use_clocktime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E}, { "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E}, { "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT64_MAX}, 0, INT64_MAX, E}, - { "segment_time", "set segment duration", OFFSET(time_str),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, + { "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, INT64_MIN, INT64_MAX, E }, { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E }, { "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E }, { "segment_frames", "set segment split frame numbers", OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E }, diff --git a/libavformat/sga.c b/libavformat/sga.c new file mode 100644 index 000000000..e7a41e91e --- /dev/null +++ b/libavformat/sga.c @@ -0,0 +1,479 @@ +/* + * Digital Pictures SGA game demuxer + * + * Copyright (C) 2021 Paul B Mahol + * + * 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/intreadwrite.h" +#include "libavutil/avassert.h" +#include "libavutil/internal.h" +#include "avformat.h" +#include "internal.h" +#include "avio_internal.h" + +#define SEGA_CD_PCM_NUM 12500000 +#define SEGA_CD_PCM_DEN 786432 + +typedef struct SGADemuxContext { + int video_stream_index; + int audio_stream_index; + + uint8_t sector[65536 * 2]; + int sector_headers; + int sample_rate; + int first_audio_size; + int payload_size; + int packet_type; + int flags; + int idx; + int left; + int64_t pkt_pos; +} SGADemuxContext; + +static int sga_probe(const AVProbeData *p) +{ + const uint8_t *src = p->buf; + int score = 0, sectors = 1; + int last_left = 0; + int sample_rate = -1; + + if (p->buf_size < 2048) + return 0; + + for (int i = 0; i + 2 < p->buf_size; i += 2048) { + int header = AV_RB16(src + i); + + if ((header > 0x07FE && header < 0x8100) || + (header > 0x8200 && header < 0xA100) || + (header > 0xA200 && header < 0xC100)) { + sectors = 0; + break; + } + } + + for (int i = 0; i + 4 < p->buf_size;) { + int header = AV_RB16(src + i); + int left = AV_RB16(src + i + 2); + int offset, type, size; + + if (last_left < 0) + return 0; + if (sectors && header && last_left == 0) { + if (header >> 12) { + last_left = left; + } else { + last_left = left = header; + } + } else if (sectors && header) { + left = header; + last_left -= left; + if (header != 0x7FE && left < 7) + return 0; + } else if (sectors) { + if (left <= 8) + return 0; + i += sectors ? 2048 : left + 4; + last_left = 0; + continue; + } + + if (sectors && (i > 0 && left < 0x7fe) && + (i + left + 14 < p->buf_size)) { + offset = i + left + 2; + } else if (sectors && i > 0) { + i += 2048; + last_left -= FFMIN(last_left, 2046); + continue; + } else { + offset = 0; + last_left = left; + } + + header = AV_RB16(src + offset); + size = AV_RB16(src + offset + 2) + 4; + + while ((header & 0xFF00) == 0) { + offset++; + if (offset + 4 >= p->buf_size) + break; + header = AV_RB16(src + offset); + size = AV_RB16(src + offset + 2) + 4; + } + + if (offset + 12 >= p->buf_size) + break; + if ((header & 0xFF) > 1) + return 0; + type = header >> 8; + + if (type == 0xAA || + type == 0xA1 || + type == 0xA2 || + type == 0xA3) { + int new_rate; + + if (size <= 12) + return 0; + new_rate = AV_RB16(src + offset + 8); + if (sample_rate < 0) + sample_rate = new_rate; + if (sample_rate == 0 || new_rate != sample_rate) + return 0; + if (src[offset + 10] != 1) + return 0; + + score += 10; + } else if (type == 0xC1 || + type == 0xC6 || + type == 0xC7 || + type == 0xC8 || + type == 0xC9 || + type == 0xCB || + type == 0xCD || + type == 0xE7) { + int nb_pals = src[offset + 9]; + int tiles_w = src[offset + 10]; + int tiles_h = src[offset + 11]; + + if (size <= 12) + return 0; + if (nb_pals == 0 || nb_pals > 4) + return 0; + if (tiles_w == 0 || tiles_w > 80) + return 0; + if (tiles_h == 0 || tiles_h > 60) + return 0; + + score += 10; + } else if (header == 0x7FE) { + ; + } else { + return 0; + } + + i += sectors ? 2048 : size + 4; + last_left -= FFMIN(last_left, 2046); + + if (score < 0) + break; + } + + return av_clip(score, 0, AVPROBE_SCORE_MAX); +} + +static int sga_read_header(AVFormatContext *s) +{ + SGADemuxContext *sga = s->priv_data; + AVIOContext *pb = s->pb; + + sga->sector_headers = 1; + sga->first_audio_size = 0; + sga->video_stream_index = -1; + sga->audio_stream_index = -1; + sga->left = 2048; + sga->idx = 0; + + s->ctx_flags |= AVFMTCTX_NOHEADER; + + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { + while (!avio_feof(pb)) { + int header = avio_rb16(pb); + int type = header >> 8; + int skip = 2046; + int clock; + + if (!sga->first_audio_size && + (type == 0xAA || + type == 0xA1 || + type == 0xA2 || + type == 0xA3)) { + sga->first_audio_size = avio_rb16(pb); + avio_skip(pb, 4); + clock = avio_rb16(pb); + sga->sample_rate = av_rescale(clock, + SEGA_CD_PCM_NUM, + SEGA_CD_PCM_DEN); + skip -= 8; + } + if ((header > 0x07FE && header < 0x8100) || + (header > 0x8200 && header < 0xA100) || + (header > 0xA200 && header < 0xC100)) { + sga->sector_headers = 0; + break; + } + + avio_skip(pb, skip); + } + + avio_seek(pb, 0, SEEK_SET); + } + + return 0; +} + +static void print_stats(AVFormatContext *s, const char *where) +{ + SGADemuxContext *sga = s->priv_data; + + av_log(s, AV_LOG_DEBUG, "START %s\n", where); + av_log(s, AV_LOG_DEBUG, "pos: %"PRIX64"\n", avio_tell(s->pb)); + av_log(s, AV_LOG_DEBUG, "idx: %X\n", sga->idx); + av_log(s, AV_LOG_DEBUG, "packet_type: %X\n", sga->packet_type); + av_log(s, AV_LOG_DEBUG, "payload_size: %X\n", sga->payload_size); + av_log(s, AV_LOG_DEBUG, "SECTOR: %016"PRIX64"\n", AV_RB64(sga->sector)); + av_log(s, AV_LOG_DEBUG, "stream: %X\n", sga->sector[1]); + av_log(s, AV_LOG_DEBUG, "END %s\n", where); +} + +static void update_type_size(AVFormatContext *s) +{ + SGADemuxContext *sga = s->priv_data; + + if (sga->idx >= 4) { + sga->packet_type = sga->sector[0]; + sga->payload_size = AV_RB16(sga->sector + 2); + } else { + sga->packet_type = 0; + sga->payload_size = 0; + } +} + +static int sga_video_packet(AVFormatContext *s, AVPacket *pkt) +{ + SGADemuxContext *sga = s->priv_data; + int ret; + + if (sga->payload_size <= 8) + return AVERROR_INVALIDDATA; + + if (sga->video_stream_index == -1) { + AVRational frame_rate; + + AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + st->start_time = 0; + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_tag = 0; + st->codecpar->codec_id = AV_CODEC_ID_SGA_VIDEO; + sga->video_stream_index = st->index; + + if (sga->first_audio_size > 0 && sga->sample_rate > 0) { + frame_rate.num = sga->sample_rate; + frame_rate.den = sga->first_audio_size; + } else { + frame_rate.num = 15; + frame_rate.den = 1; + } + avpriv_set_pts_info(st, 64, frame_rate.den, frame_rate.num); + } + + ret = av_new_packet(pkt, sga->payload_size + 4); + if (ret < 0) + return AVERROR(ENOMEM); + memcpy(pkt->data, sga->sector, sga->payload_size + 4); + av_assert0(sga->idx >= sga->payload_size + 4); + memmove(sga->sector, sga->sector + sga->payload_size + 4, sga->idx - sga->payload_size - 4); + + pkt->stream_index = sga->video_stream_index; + pkt->duration = 1; + pkt->pos = sga->pkt_pos; + pkt->flags |= sga->flags; + sga->idx -= sga->payload_size + 4; + sga->flags = 0; + update_type_size(s); + + av_log(s, AV_LOG_DEBUG, "VIDEO PACKET: %d:%016"PRIX64" i:%X\n", pkt->size, AV_RB64(sga->sector), sga->idx); + + return 0; +} + +static int sga_audio_packet(AVFormatContext *s, AVPacket *pkt) +{ + SGADemuxContext *sga = s->priv_data; + int ret; + + if (sga->payload_size <= 8) + return AVERROR_INVALIDDATA; + + if (sga->audio_stream_index == -1) { + AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + st->start_time = 0; + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + st->codecpar->codec_tag = 0; + st->codecpar->codec_id = AV_CODEC_ID_PCM_SGA; + st->codecpar->channels = 1; + st->codecpar->channel_layout= AV_CH_LAYOUT_MONO; + st->codecpar->sample_rate = av_rescale(AV_RB16(sga->sector + 8), + SEGA_CD_PCM_NUM, + SEGA_CD_PCM_DEN); + sga->audio_stream_index = st->index; + + avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); + } + + ret = av_new_packet(pkt, sga->payload_size - 8); + if (ret < 0) + return AVERROR(ENOMEM); + memcpy(pkt->data, sga->sector + 12, sga->payload_size - 8); + av_assert0(sga->idx >= sga->payload_size + 4); + memmove(sga->sector, sga->sector + sga->payload_size + 4, sga->idx - sga->payload_size - 4); + + pkt->stream_index = sga->audio_stream_index; + pkt->duration = pkt->size; + pkt->pos = sga->pkt_pos; + pkt->flags |= sga->flags; + sga->idx -= sga->payload_size + 4; + sga->flags = 0; + update_type_size(s); + + av_log(s, AV_LOG_DEBUG, "AUDIO PACKET: %d:%016"PRIX64" i:%X\n", pkt->size, AV_RB64(sga->sector), sga->idx); + + return 0; +} + +static int sga_packet(AVFormatContext *s, AVPacket *pkt) +{ + SGADemuxContext *sga = s->priv_data; + int ret = 0; + + if (sga->packet_type == 0xCD || + sga->packet_type == 0xCB || + sga->packet_type == 0xC9 || + sga->packet_type == 0xC8 || + sga->packet_type == 0xC7 || + sga->packet_type == 0xC6 || + sga->packet_type == 0xC1 || + sga->packet_type == 0xE7) { + ret = sga_video_packet(s, pkt); + } else if (sga->packet_type == 0xA1 || + sga->packet_type == 0xA2 || + sga->packet_type == 0xA3 || + sga->packet_type == 0xAA) { + ret = sga_audio_packet(s, pkt); + } else { + if (sga->idx == 0) + return AVERROR_EOF; + if (sga->sector[0]) + return AVERROR_INVALIDDATA; + memmove(sga->sector, sga->sector + 1, sga->idx - 1); + sga->idx--; + return AVERROR(EAGAIN); + } + + return ret; +} + +static int try_packet(AVFormatContext *s, AVPacket *pkt) +{ + SGADemuxContext *sga = s->priv_data; + int ret = AVERROR(EAGAIN); + + update_type_size(s); + if (sga->idx >= sga->payload_size + 4) { + print_stats(s, "before sga_packet"); + ret = sga_packet(s, pkt); + print_stats(s, "after sga_packet"); + if (ret != AVERROR(EAGAIN)) + return ret; + } + + return sga->idx < sga->payload_size + 4 ? AVERROR(EAGAIN) : ret; +} + +static int sga_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + SGADemuxContext *sga = s->priv_data; + AVIOContext *pb = s->pb; + int header, ret = 0; + + sga->pkt_pos = avio_tell(pb); + +retry: + update_type_size(s); + + print_stats(s, "start"); + if (avio_feof(pb) && + (!sga->payload_size || sga->idx < sga->payload_size + 4)) + return AVERROR_EOF; + + if (sga->idx < sga->payload_size + 4) { + ret = ffio_ensure_seekback(pb, 2); + if (ret < 0) + return ret; + + print_stats(s, "before read header"); + header = avio_rb16(pb); + if (!header) { + avio_skip(pb, 2046); + sga->left = 0; + } else if (!avio_feof(pb) && + ((header >> 15) || + !sga->sector_headers)) { + avio_seek(pb, -2, SEEK_CUR); + sga->flags = AV_PKT_FLAG_KEY; + sga->left = 2048; + } else { + sga->left = 2046; + } + + av_assert0(sga->idx + sga->left < sizeof(sga->sector)); + ret = avio_read(pb, sga->sector + sga->idx, sga->left); + if (ret > 0) + sga->idx += ret; + else if (ret != AVERROR_EOF && ret) + return ret; + print_stats(s, "after read header"); + + update_type_size(s); + } + + ret = try_packet(s, pkt); + if (ret == AVERROR(EAGAIN)) + goto retry; + + return ret; +} + +static int sga_seek(AVFormatContext *s, int stream_index, + int64_t timestamp, int flags) +{ + SGADemuxContext *sga = s->priv_data; + + sga->packet_type = sga->payload_size = sga->idx = 0; + memset(sga->sector, 0, sizeof(sga->sector)); + + return -1; +} + +AVInputFormat ff_sga_demuxer = { + .name = "sga", + .long_name = NULL_IF_CONFIG_SMALL("Digital Pictures SGA"), + .priv_data_size = sizeof(SGADemuxContext), + .read_probe = sga_probe, + .read_header = sga_read_header, + .read_packet = sga_read_packet, + .read_seek = sga_seek, + .extensions = "sga", + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c index 531fc4153..40bcb7798 100644 --- a/libavformat/sierravmd.c +++ b/libavformat/sierravmd.c @@ -174,6 +174,8 @@ static int vmd_read_header(AVFormatContext *s) avpriv_set_pts_info(vst, 33, num, den); avpriv_set_pts_info(st, 33, num, den); } + if (!s->nb_streams) + return AVERROR_INVALIDDATA; toc_offset = AV_RL32(&vmd->vmd_header[812]); vmd->frame_count = AV_RL16(&vmd->vmd_header[6]); @@ -241,6 +243,8 @@ static int vmd_read_header(AVFormatContext *s) current_audio_pts++; break; case 2: /* Video Chunk */ + if (!vst) + break; vmd->frame_table[total_frames].frame_offset = current_offset; vmd->frame_table[total_frames].stream_index = vmd->video_stream_index; vmd->frame_table[total_frames].frame_size = size; diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 14c5e3c1c..61209e703 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -48,16 +48,17 @@ typedef struct SmackerContext { uint32_t *frm_size; uint8_t *frm_flags; /* internal variables */ + int64_t next_frame_pos; int cur_frame; - /* current frame for demuxing */ - uint8_t pal[768]; - int indexes[7]; int videoindex; - uint8_t *bufs[7]; - int buf_sizes[7]; - int stream_id[7]; - int curstream; - int64_t nextpos; + int indexes[7]; + int duration_size[7]; + /* current frame for demuxing */ + uint32_t frame_size; + int flags; + int next_audio_index; + int new_palette; + uint8_t pal[768]; int64_t aud_pts[7]; } SmackerContext; @@ -197,6 +198,8 @@ static int smacker_read_header(AVFormatContext *s) if (par->bits_per_coded_sample == 16 && par->codec_id == AV_CODEC_ID_PCM_U8) par->codec_id = AV_CODEC_ID_PCM_S16LE; + else + smk->duration_size[i] = 4; avpriv_set_pts_info(ast, 64, 1, par->sample_rate * par->channels * par->bits_per_coded_sample / 8); } @@ -205,85 +208,75 @@ static int smacker_read_header(AVFormatContext *s) avio_rl32(pb); /* padding */ /* setup data */ - smk->frm_size = av_malloc_array(smk->frames, sizeof(*smk->frm_size)); - smk->frm_flags = av_malloc(smk->frames); - if (!smk->frm_size || !smk->frm_flags) { - av_freep(&smk->frm_size); - av_freep(&smk->frm_flags); + st->priv_data = av_malloc_array(smk->frames, sizeof(*smk->frm_size) + + sizeof(*smk->frm_flags)); + if (!st->priv_data) return AVERROR(ENOMEM); - } + smk->frm_size = st->priv_data; + smk->frm_flags = (void*)(smk->frm_size + smk->frames); /* read frame info */ for (i = 0; i < smk->frames; i++) { smk->frm_size[i] = avio_rl32(pb); } - for (i = 0; i < smk->frames; i++) { - smk->frm_flags[i] = avio_r8(pb); + if ((ret = ffio_read_size(pb, smk->frm_flags, smk->frames)) < 0 || + /* load trees to extradata, they will be unpacked by decoder */ + (ret = ffio_read_size(pb, par->extradata + 16, + par->extradata_size - 16)) < 0) { + return ret; } - /* load trees to extradata, they will be unpacked by decoder */ - ret = avio_read(pb, par->extradata + 16, par->extradata_size - 16); - if (ret != par->extradata_size - 16) { - av_freep(&smk->frm_size); - av_freep(&smk->frm_flags); - return AVERROR(EIO); - } - - smk->curstream = -1; - smk->nextpos = avio_tell(pb); - return 0; } - static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) { SmackerContext *smk = s->priv_data; int flags; int ret; - int i; - int frame_size = 0; - int palchange = 0; if (avio_feof(s->pb) || smk->cur_frame >= smk->frames) return AVERROR_EOF; /* if we demuxed all streams, pass another frame */ - if(smk->curstream < 0) { - avio_seek(s->pb, smk->nextpos, 0); - frame_size = smk->frm_size[smk->cur_frame] & (~3); + if (!smk->next_audio_index) { + smk->frame_size = smk->frm_size[smk->cur_frame] & (~3); + smk->next_frame_pos = avio_tell(s->pb) + smk->frame_size; flags = smk->frm_flags[smk->cur_frame]; + smk->flags = flags >> 1; /* handle palette change event */ - if(flags & SMACKER_PAL){ + if (flags & SMACKER_PAL) { int size, sz, t, off, j, pos; uint8_t *pal = smk->pal; uint8_t oldpal[768]; memcpy(oldpal, pal, 768); size = avio_r8(s->pb); - size = size * 4 - 1; - if(size + 1 > frame_size) - return AVERROR_INVALIDDATA; - frame_size -= size; - frame_size--; + size = size * 4; + if (size > smk->frame_size) { + ret = AVERROR_INVALIDDATA; + goto next_frame; + } + smk->frame_size -= size--; sz = 0; pos = avio_tell(s->pb) + size; - while(sz < 256){ + while (sz < 256) { t = avio_r8(s->pb); - if(t & 0x80){ /* skip palette entries */ - sz += (t & 0x7F) + 1; + if (t & 0x80) { /* skip palette entries */ + sz += (t & 0x7F) + 1; pal += ((t & 0x7F) + 1) * 3; - } else if(t & 0x40){ /* copy with offset */ + } else if (t & 0x40) { /* copy with offset */ off = avio_r8(s->pb); j = (t & 0x3F) + 1; if (off + j > 0x100) { av_log(s, AV_LOG_ERROR, "Invalid palette update, offset=%d length=%d extends beyond palette size\n", off, j); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto next_frame; } off *= 3; - while(j-- && sz < 256) { + while (j-- && sz < 256) { *pal++ = oldpal[off + 0]; *pal++ = oldpal[off + 1]; *pal++ = oldpal[off + 2]; @@ -298,77 +291,97 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) } } avio_seek(s->pb, pos, 0); - palchange |= 1; + smk->new_palette = 1; } - flags >>= 1; - smk->curstream = -1; - /* if audio chunks are present, put them to stack and retrieve later */ - for(i = 0; i < 7; i++) { - if(flags & 1) { - uint32_t size; - int err; - - size = avio_rl32(s->pb) - 4; - if (!size || size + 4LL > frame_size) { - av_log(s, AV_LOG_ERROR, "Invalid audio part size\n"); - return AVERROR_INVALIDDATA; - } - frame_size -= size; - frame_size -= 4; - smk->curstream++; - if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) { - smk->buf_sizes[smk->curstream] = 0; - return err; - } - smk->buf_sizes[smk->curstream] = size; - ret = avio_read(s->pb, smk->bufs[smk->curstream], size); - if(ret != size) - return AVERROR(EIO); - smk->stream_id[smk->curstream] = smk->indexes[i]; - } - flags >>= 1; - } - if (frame_size < 0 || frame_size >= INT_MAX/2) - return AVERROR_INVALIDDATA; - if ((ret = av_new_packet(pkt, frame_size + 769)) < 0) - return ret; - if(smk->frm_size[smk->cur_frame] & 1) - palchange |= 2; - pkt->data[0] = palchange; - memcpy(pkt->data + 1, smk->pal, 768); - ret = avio_read(s->pb, pkt->data + 769, frame_size); - if(ret != frame_size) - return AVERROR(EIO); - pkt->stream_index = smk->videoindex; - pkt->pts = smk->cur_frame; - pkt->size = ret + 769; - smk->cur_frame++; - smk->nextpos = avio_tell(s->pb); - } else { - if (smk->stream_id[smk->curstream] < 0 || !smk->bufs[smk->curstream]) - return AVERROR_INVALIDDATA; - if ((ret = av_new_packet(pkt, smk->buf_sizes[smk->curstream])) < 0) - return ret; - memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]); - pkt->size = smk->buf_sizes[smk->curstream]; - pkt->stream_index = smk->stream_id[smk->curstream]; - pkt->pts = smk->aud_pts[smk->curstream]; - smk->aud_pts[smk->curstream] += AV_RL32(pkt->data); - smk->curstream--; } + for (int i = smk->next_audio_index; i < 7; i++) { + if (smk->flags & (1 << i)) { + uint32_t size; + + size = avio_rl32(s->pb); + if ((int)size < 4 + smk->duration_size[i] || size > smk->frame_size) { + av_log(s, AV_LOG_ERROR, "Invalid audio part size\n"); + ret = AVERROR_INVALIDDATA; + goto next_frame; + } + smk->frame_size -= size; + size -= 4; + + if (smk->indexes[i] < 0 || + s->streams[smk->indexes[i]]->discard >= AVDISCARD_ALL) { + smk->aud_pts[i] += smk->duration_size[i] ? avio_rl32(s->pb) + : size; + avio_skip(s->pb, size - smk->duration_size[i]); + continue; + } + if ((ret = av_get_packet(s->pb, pkt, size)) != size) { + ret = ret < 0 ? ret : AVERROR_INVALIDDATA; + goto next_frame; + } + pkt->stream_index = smk->indexes[i]; + pkt->pts = smk->aud_pts[i]; + pkt->duration = smk->duration_size[i] ? AV_RL32(pkt->data) + : size; + smk->aud_pts[i] += pkt->duration; + smk->next_audio_index = i + 1; + return 0; + } + } + + if (s->streams[smk->videoindex]->discard >= AVDISCARD_ALL) { + ret = FFERROR_REDO; + goto next_frame; + } + if (smk->frame_size >= INT_MAX/2) { + ret = AVERROR_INVALIDDATA; + goto next_frame; + } + if ((ret = av_new_packet(pkt, smk->frame_size + 769)) < 0) + goto next_frame; + flags = smk->new_palette; + if (smk->frm_size[smk->cur_frame] & 1) + flags |= 2; + pkt->data[0] = flags; + memcpy(pkt->data + 1, smk->pal, 768); + ret = ffio_read_size(s->pb, pkt->data + 769, smk->frame_size); + if (ret < 0) + goto next_frame; + pkt->stream_index = smk->videoindex; + pkt->pts = smk->cur_frame; + smk->next_audio_index = 0; + smk->new_palette = 0; + smk->cur_frame++; + return 0; +next_frame: + avio_seek(s->pb, smk->next_frame_pos, SEEK_SET); + smk->next_audio_index = 0; + smk->cur_frame++; + return ret; } -static int smacker_read_close(AVFormatContext *s) +static int smacker_read_seek(AVFormatContext *s, int stream_index, + int64_t timestamp, int flags) { SmackerContext *smk = s->priv_data; - int i; + int64_t ret; - for(i = 0; i < 7; i++) - av_freep(&smk->bufs[i]); - av_freep(&smk->frm_size); - av_freep(&smk->frm_flags); + /* only rewinding to start is supported */ + if (timestamp != 0) { + av_log(s, AV_LOG_ERROR, + "Random seeks are not supported (can only seek to start).\n"); + return AVERROR(EINVAL); + } + + if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0) + return ret; + + smk->cur_frame = 0; + smk->next_audio_index = 0; + smk->new_palette = 0; + memset(smk->pal, 0, sizeof(smk->pal)); + memset(smk->aud_pts, 0, sizeof(smk->aud_pts)); return 0; } @@ -380,5 +393,5 @@ AVInputFormat ff_smacker_demuxer = { .read_probe = smacker_probe, .read_header = smacker_read_header, .read_packet = smacker_read_packet, - .read_close = smacker_read_close, + .read_seek = smacker_read_seek, }; diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index 33bb404f4..ba5cc27ca 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -49,7 +49,6 @@ typedef struct Fragment { typedef struct OutputStream { AVFormatContext *ctx; - int ctx_inited; char dirname[1024]; uint8_t iobuf[32768]; URLContext *out; // Current output stream where all output is written @@ -173,8 +172,6 @@ static void ism_free(AVFormatContext *s) ffurl_closep(&os->out); ffurl_closep(&os->out2); ffurl_closep(&os->tail_out); - if (os->ctx && os->ctx_inited) - av_write_trailer(os->ctx); if (os->ctx && os->ctx->pb) avio_context_free(&os->ctx->pb); avformat_free_context(os->ctx); @@ -289,21 +286,18 @@ static int ism_write_header(AVFormatContext *s) ff_const59 AVOutputFormat *oformat; if (mkdir(s->url, 0777) == -1 && errno != EEXIST) { - ret = AVERROR(errno); av_log(s, AV_LOG_ERROR, "mkdir failed\n"); - goto fail; + return AVERROR(errno); } oformat = av_guess_format("ismv", NULL, NULL); if (!oformat) { - ret = AVERROR_MUXER_NOT_FOUND; - goto fail; + return AVERROR_MUXER_NOT_FOUND; } c->streams = av_mallocz_array(s->nb_streams, sizeof(*c->streams)); if (!c->streams) { - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } for (i = 0; i < s->nb_streams; i++) { @@ -321,22 +315,21 @@ static int ism_write_header(AVFormatContext *s) } if (mkdir(os->dirname, 0777) == -1 && errno != EEXIST) { - ret = AVERROR(errno); av_log(s, AV_LOG_ERROR, "mkdir failed\n"); - goto fail; + return AVERROR(errno); } os->ctx = ctx = avformat_alloc_context(); - if (!ctx || ff_copy_whiteblacklists(ctx, s) < 0) { - ret = AVERROR(ENOMEM); - goto fail; + if (!ctx) { + return AVERROR(ENOMEM); } + if ((ret = ff_copy_whiteblacklists(ctx, s)) < 0) + return ret; ctx->oformat = oformat; ctx->interrupt_callback = s->interrupt_callback; if (!(st = avformat_new_stream(ctx, NULL))) { - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar); st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio; @@ -344,8 +337,7 @@ static int ism_write_header(AVFormatContext *s) ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf), AVIO_FLAG_WRITE, os, NULL, ism_write, ism_seek); if (!ctx->pb) { - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } av_dict_set_int(&opts, "ism_lookahead", c->lookahead_count, 0); @@ -353,9 +345,8 @@ static int ism_write_header(AVFormatContext *s) ret = avformat_write_header(ctx, &opts); av_dict_free(&opts); if (ret < 0) { - goto fail; + return ret; } - os->ctx_inited = 1; avio_flush(ctx->pb); s->streams[i]->time_base = st->time_base; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { @@ -367,8 +358,7 @@ static int ism_write_header(AVFormatContext *s) os->fourcc = "WVC1"; } else { av_log(s, AV_LOG_ERROR, "Unsupported video codec\n"); - ret = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } } else { c->has_audio = 1; @@ -381,8 +371,7 @@ static int ism_write_header(AVFormatContext *s) os->audio_tag = 0x0162; } else { av_log(s, AV_LOG_ERROR, "Unsupported audio codec\n"); - ret = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } os->packet_size = st->codecpar->block_align ? st->codecpar->block_align : 4; } @@ -391,15 +380,13 @@ static int ism_write_header(AVFormatContext *s) if (!c->has_video && c->min_frag_duration <= 0) { av_log(s, AV_LOG_WARNING, "no video stream and no min frag duration set\n"); - ret = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } ret = write_manifest(s, 0); + if (ret < 0) + return ret; -fail: - if (ret) - ism_free(s); - return ret; + return 0; } static int parse_fragment(AVFormatContext *s, const char *filename, int64_t *start_ts, int64_t *duration, int64_t *moof_size, int64_t size) @@ -628,7 +615,6 @@ static int ism_write_trailer(AVFormatContext *s) rmdir(s->url); } - ism_free(s); return 0; } @@ -661,5 +647,6 @@ AVOutputFormat ff_smoothstreaming_muxer = { .write_header = ism_write_header, .write_packet = ism_write_packet, .write_trailer = ism_write_trailer, + .deinit = ism_free, .priv_class = &ism_class, }; diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c index 0288872fd..c3ba3a1a1 100644 --- a/libavformat/spdifenc.c +++ b/libavformat/spdifenc.c @@ -122,14 +122,16 @@ static int spdif_header_eac3(AVFormatContext *s, AVPacket *pkt) IEC61937Context *ctx = s->priv_data; static const uint8_t eac3_repeat[4] = {6, 3, 2, 1}; int repeat = 1; + uint8_t *tmp; int bsid = pkt->data[5] >> 3; if (bsid > 10 && (pkt->data[4] & 0xc0) != 0xc0) /* fscod */ repeat = eac3_repeat[(pkt->data[4] & 0x30) >> 4]; /* numblkscod */ - ctx->hd_buf[0] = av_fast_realloc(ctx->hd_buf[0], &ctx->hd_buf_size, ctx->hd_buf_filled + pkt->size); - if (!ctx->hd_buf[0]) + tmp = av_fast_realloc(ctx->hd_buf[0], &ctx->hd_buf_size, ctx->hd_buf_filled + pkt->size); + if (!tmp) return AVERROR(ENOMEM); + ctx->hd_buf[0] = tmp; memcpy(&ctx->hd_buf[0][ctx->hd_buf_filled], pkt->data, pkt->size); diff --git a/libavformat/srtenc.c b/libavformat/srtenc.c index d811a4da0..484dd4d23 100644 --- a/libavformat/srtenc.c +++ b/libavformat/srtenc.c @@ -61,7 +61,8 @@ static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt) SRTContext *srt = avf->priv_data; int64_t s = pkt->pts, e, d = pkt->duration; - int size, x1 = -1, y1 = -1, x2 = -1, y2 = -1; + buffer_size_t size; + int x1 = -1, y1 = -1, x2 = -1, y2 = -1; const uint8_t *p; p = av_packet_get_side_data(pkt, AV_PKT_DATA_SUBTITLE_POSITION, &size); diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c index ad7f68938..05c07cd85 100644 --- a/libavformat/subtitles.c +++ b/libavformat/subtitles.c @@ -111,13 +111,13 @@ int ff_text_peek_r8(FFTextReader *r) AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, const uint8_t *event, size_t len, int merge) { - AVPacket *subs, *sub; + AVPacket **subs, *sub; if (merge && q->nb_subs > 0) { /* merge with previous event */ int old_len; - sub = &q->subs[q->nb_subs - 1]; + sub = q->subs[q->nb_subs - 1]; old_len = sub->size; if (av_grow_packet(sub, len) < 0) return NULL; @@ -132,10 +132,14 @@ AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, if (!subs) return NULL; q->subs = subs; - sub = &subs[q->nb_subs]; - if (av_new_packet(sub, len) < 0) + sub = av_packet_alloc(); + if (!sub) return NULL; - q->nb_subs++; + if (av_new_packet(sub, len) < 0) { + av_packet_free(&sub); + return NULL; + } + subs[q->nb_subs++] = sub; sub->flags |= AV_PKT_FLAG_KEY; sub->pts = sub->dts = 0; memcpy(sub->data, event, len); @@ -145,8 +149,8 @@ AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, static int cmp_pkt_sub_ts_pos(const void *a, const void *b) { - const AVPacket *s1 = a; - const AVPacket *s2 = b; + const AVPacket *s1 = *(const AVPacket **)a; + const AVPacket *s2 = *(const AVPacket **)b; if (s1->pts == s2->pts) return FFDIFFSIGN(s1->pos, s2->pos); return FFDIFFSIGN(s1->pts , s2->pts); @@ -154,8 +158,8 @@ static int cmp_pkt_sub_ts_pos(const void *a, const void *b) static int cmp_pkt_sub_pos_ts(const void *a, const void *b) { - const AVPacket *s1 = a; - const AVPacket *s2 = b; + const AVPacket *s1 = *(const AVPacket **)a; + const AVPacket *s2 = *(const AVPacket **)b; if (s1->pos == s2->pos) { if (s1->pts == s2->pts) return 0; @@ -170,18 +174,18 @@ static void drop_dups(void *log_ctx, FFDemuxSubtitlesQueue *q) for (i = 1; i < q->nb_subs; i++) { const int last_id = i - 1 - drop; - const AVPacket *last = &q->subs[last_id]; + const AVPacket *last = q->subs[last_id]; - if (q->subs[i].pts == last->pts && - q->subs[i].duration == last->duration && - q->subs[i].stream_index == last->stream_index && - !strcmp(q->subs[i].data, last->data)) { + if (q->subs[i]->pts == last->pts && + q->subs[i]->duration == last->duration && + q->subs[i]->stream_index == last->stream_index && + !strcmp(q->subs[i]->data, last->data)) { - av_packet_unref(&q->subs[i]); + av_packet_free(&q->subs[i]); drop++; } else if (drop) { q->subs[last_id + 1] = q->subs[i]; - memset(&q->subs[i], 0, sizeof(q->subs[i])); // for safety + q->subs[i] = NULL; } } @@ -202,8 +206,8 @@ void ff_subtitles_queue_finalize(void *log_ctx, FFDemuxSubtitlesQueue *q) q->sort == SUB_SORT_TS_POS ? cmp_pkt_sub_ts_pos : cmp_pkt_sub_pos_ts); for (i = 0; i < q->nb_subs; i++) - if (q->subs[i].duration < 0 && i < q->nb_subs - 1) - q->subs[i].duration = q->subs[i + 1].pts - q->subs[i].pts; + if (q->subs[i]->duration < 0 && i < q->nb_subs - 1) + q->subs[i]->duration = q->subs[i + 1]->pts - q->subs[i]->pts; if (!q->keep_duplicates) drop_dups(log_ctx, q); @@ -211,11 +215,12 @@ void ff_subtitles_queue_finalize(void *log_ctx, FFDemuxSubtitlesQueue *q) int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt) { - AVPacket *sub = q->subs + q->current_sub_idx; + AVPacket *sub; int ret; if (q->current_sub_idx == q->nb_subs) return AVERROR_EOF; + sub = q->subs[q->current_sub_idx]; if ((ret = av_packet_ref(pkt, sub)) < 0) { return ret; } @@ -238,9 +243,9 @@ static int search_sub_ts(const FFDemuxSubtitlesQueue *q, int64_t ts) if (s1 == s2) return s1; if (s1 == s2 - 1) - return q->subs[s1].pts <= q->subs[s2].pts ? s1 : s2; + return q->subs[s1]->pts <= q->subs[s2]->pts ? s1 : s2; mid = (s1 + s2) / 2; - if (q->subs[mid].pts <= ts) + if (q->subs[mid]->pts <= ts) s1 = mid; else s2 = mid; @@ -262,24 +267,24 @@ int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int st if (idx < 0) return idx; - for (i = idx; i < q->nb_subs && q->subs[i].pts < min_ts; i++) - if (stream_index == -1 || q->subs[i].stream_index == stream_index) + for (i = idx; i < q->nb_subs && q->subs[i]->pts < min_ts; i++) + if (stream_index == -1 || q->subs[i]->stream_index == stream_index) idx = i; - for (i = idx; i > 0 && q->subs[i].pts > max_ts; i--) - if (stream_index == -1 || q->subs[i].stream_index == stream_index) + for (i = idx; i > 0 && q->subs[i]->pts > max_ts; i--) + if (stream_index == -1 || q->subs[i]->stream_index == stream_index) idx = i; - ts_selected = q->subs[idx].pts; + ts_selected = q->subs[idx]->pts; if (ts_selected < min_ts || ts_selected > max_ts) return AVERROR(ERANGE); /* look back in the latest subtitles for overlapping subtitles */ for (i = idx - 1; i >= 0; i--) { - int64_t pts = q->subs[i].pts; - if (q->subs[i].duration <= 0 || - (stream_index != -1 && q->subs[i].stream_index != stream_index)) + int64_t pts = q->subs[i]->pts; + if (q->subs[i]->duration <= 0 || + (stream_index != -1 && q->subs[i]->stream_index != stream_index)) continue; - if (pts >= min_ts && pts > ts_selected - q->subs[i].duration) + if (pts >= min_ts && pts > ts_selected - q->subs[i]->duration) idx = i; else break; @@ -291,7 +296,7 @@ int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int st * queue is ordered by pts and then filepos, so we can take the first * entry for a given timestamp. */ if (stream_index == -1) - while (idx > 0 && q->subs[idx - 1].pts == q->subs[idx].pts) + while (idx > 0 && q->subs[idx - 1]->pts == q->subs[idx]->pts) idx--; q->current_sub_idx = idx; @@ -304,7 +309,7 @@ void ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q) int i; for (i = 0; i < q->nb_subs; i++) - av_packet_unref(&q->subs[i]); + av_packet_free(&q->subs[i]); av_freep(&q->subs); q->nb_subs = q->allocated_size = q->current_sub_idx = 0; } diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h index 6b418e362..ca769639b 100644 --- a/libavformat/subtitles.h +++ b/libavformat/subtitles.h @@ -100,7 +100,7 @@ int ff_text_peek_r8(FFTextReader *r); void ff_text_read(FFTextReader *r, char *buf, size_t size); typedef struct { - AVPacket *subs; ///< array of subtitles packets + AVPacket **subs; ///< array of subtitles packets int nb_subs; ///< number of subtitles packets int allocated_size; ///< allocated size for subs int current_sub_idx; ///< current position for the read packet callback diff --git a/libavformat/svs.c b/libavformat/svs.c new file mode 100644 index 000000000..8be26c5bc --- /dev/null +++ b/libavformat/svs.c @@ -0,0 +1,96 @@ +/* + * SVS demuxer + * Copyright (c) 2020 Paul B Mahol + * + * 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/channel_layout.h" +#include "libavutil/intreadwrite.h" +#include "avformat.h" +#include "internal.h" + +static int svs_probe(const AVProbeData *p) +{ + if (p->buf_size < 32) + return 0; + + if (memcmp(p->buf, "SVS\00", 4)) + return 0; + + if (AV_RL32(p->buf + 16) == 0) + return 0; + + return AVPROBE_SCORE_MAX / 3; +} + +static int svs_read_header(AVFormatContext *s) +{ + AVStream *st; + uint32_t pitch; + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + avio_skip(s->pb, 16); + pitch = avio_rl32(s->pb); + avio_skip(s->pb, 12); + + s->internal->data_offset = avio_tell(s->pb); + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + st->codecpar->codec_id = AV_CODEC_ID_ADPCM_PSX; + st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; + st->codecpar->channels = 2; + st->codecpar->sample_rate = av_rescale_rnd(pitch, 48000, 4096, AV_ROUND_INF); + st->codecpar->block_align = 32; + st->start_time = 0; + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) + st->duration = av_get_audio_frame_duration2(st->codecpar, + avio_size(s->pb) - 32); + + avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); + + return 0; +} + +static int svs_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + int ret; + + if (avio_feof(s->pb)) + return AVERROR_EOF; + + ret = av_get_packet(s->pb, pkt, 32 * 256); + if (ret != 32 * 256) { + if (ret < 0) + return ret; + pkt->flags &= ~AV_PKT_FLAG_CORRUPT; + } + pkt->stream_index = 0; + + return ret; +} + +AVInputFormat ff_svs_demuxer = { + .name = "svs", + .long_name = NULL_IF_CONFIG_SMALL("Square SVS"), + .read_probe = svs_probe, + .read_header = svs_read_header, + .read_packet = svs_read_packet, + .extensions = "svs", +}; diff --git a/libavformat/swf.c b/libavformat/swf.c index 1aa434a0e..a3471d917 100644 --- a/libavformat/swf.c +++ b/libavformat/swf.c @@ -23,7 +23,9 @@ #include "internal.h" const AVCodecTag ff_swf_codec_tags[] = { - { AV_CODEC_ID_FLV1, 0x02 }, - { AV_CODEC_ID_VP6F, 0x04 }, - { AV_CODEC_ID_NONE, 0 }, + { AV_CODEC_ID_FLV1, 0x02 }, + { AV_CODEC_ID_FLASHSV, 0x03 }, + { AV_CODEC_ID_VP6F, 0x04 }, + { AV_CODEC_ID_VP6A, 0x05 }, + { AV_CODEC_ID_NONE, 0 }, }; diff --git a/libavformat/swf.h b/libavformat/swf.h index d0f0194c3..b66420c60 100644 --- a/libavformat/swf.h +++ b/libavformat/swf.h @@ -23,15 +23,6 @@ #ifndef AVFORMAT_SWF_H #define AVFORMAT_SWF_H -#include "config.h" - -#if CONFIG_ZLIB -#include -#endif - -#include "libavutil/fifo.h" -#include "avformat.h" -#include "avio.h" #include "internal.h" /* should have a generic way to indicate probable size */ @@ -113,35 +104,11 @@ enum { #define FLAG_SETFILL0 0x02 #define FLAG_SETFILL1 0x04 -#define AUDIO_FIFO_SIZE 65536 - /* character id used */ #define BITMAP_ID 0 #define VIDEO_ID 0 #define SHAPE_ID 1 -typedef struct SWFContext { - int64_t duration_pos; - int64_t tag_pos; - int64_t vframes_pos; - int samples_per_frame; - int sound_samples; - int swf_frame_number; - int video_frame_number; - int frame_rate; - int tag; - AVFifoBuffer *audio_fifo; - AVCodecParameters *audio_par, *video_par; - AVStream *video_st; -#if CONFIG_ZLIB -#define ZBUF_SIZE 4096 - AVIOContext *zpb; - uint8_t *zbuf_in; - uint8_t *zbuf_out; - z_stream zstream; -#endif -} SWFContext; - extern const AVCodecTag ff_swf_codec_tags[]; #endif /* AVFORMAT_SWF_H */ diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index 9a0b27bd8..f9a164b33 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -33,6 +33,19 @@ #include "libavutil/intreadwrite.h" #include "libavcodec/get_bits.h" #include "swf.h" +#include "flv.h" + +typedef struct SWFDecContext { + int samples_per_frame; + int frame_rate; +#if CONFIG_ZLIB +#define ZBUF_SIZE 4096 + AVIOContext *zpb; + uint8_t *zbuf_in; + uint8_t *zbuf_out; + z_stream zstream; +#endif +} SWFDecContext; static const AVCodecTag swf_audio_codec_tags[] = { { AV_CODEC_ID_PCM_S16LE, 0x00 }, @@ -78,10 +91,9 @@ static int swf_probe(const AVProbeData *p) && p->buf[3] <= 20) return AVPROBE_SCORE_MAX / 4 + 1; - if (init_get_bits8(&gb, p->buf + 3, p->buf_size - 3) < 0) + if (init_get_bits8(&gb, p->buf + 8, p->buf_size - 8) < 0) return 0; - skip_bits(&gb, 40); len = get_bits(&gb, 5); if (!len) return 0; @@ -102,7 +114,7 @@ static int swf_probe(const AVProbeData *p) static int zlib_refill(void *opaque, uint8_t *buf, int buf_size) { AVFormatContext *s = opaque; - SWFContext *swf = s->priv_data; + SWFDecContext *swf = s->priv_data; z_stream *z = &swf->zstream; int ret; @@ -129,11 +141,13 @@ retry: return buf_size - z->avail_out; } + +static av_cold int swf_read_close(AVFormatContext *avctx); #endif static int swf_read_header(AVFormatContext *s) { - SWFContext *swf = s->priv_data; + SWFDecContext *swf = s->priv_data; AVIOContext *pb = s->pb; int nbits, len, tag; @@ -143,19 +157,18 @@ static int swf_read_header(AVFormatContext *s) if (tag == MKBETAG('C', 'W', 'S', 0)) { av_log(s, AV_LOG_INFO, "SWF compressed file detected\n"); #if CONFIG_ZLIB - swf->zbuf_in = av_malloc(ZBUF_SIZE); - swf->zbuf_out = av_malloc(ZBUF_SIZE); - swf->zpb = avio_alloc_context(swf->zbuf_out, ZBUF_SIZE, 0, s, - zlib_refill, NULL, NULL); - if (!swf->zbuf_in || !swf->zbuf_out || !swf->zpb) - return AVERROR(ENOMEM); - swf->zpb->seekable = 0; if (inflateInit(&swf->zstream) != Z_OK) { av_log(s, AV_LOG_ERROR, "Unable to init zlib context\n"); - av_freep(&swf->zbuf_in); - av_freep(&swf->zbuf_out); return AVERROR(EINVAL); } + if (!(swf->zbuf_in = av_malloc(ZBUF_SIZE)) || + !(swf->zbuf_out = av_malloc(ZBUF_SIZE)) || + !(swf->zpb = avio_alloc_context(swf->zbuf_out, ZBUF_SIZE, 0, + s, zlib_refill, NULL, NULL))) { + swf_read_close(s); + return AVERROR(ENOMEM); + } + swf->zpb->seekable = 0; pb = swf->zpb; #else av_log(s, AV_LOG_ERROR, "zlib support is required to read SWF compressed files\n"); @@ -203,7 +216,7 @@ static AVStream *create_new_audio_stream(AVFormatContext *s, int id, int info) static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) { - SWFContext *swf = s->priv_data; + SWFDecContext *swf = s->priv_data; AVIOContext *pb = s->pb; AVStream *vst = NULL, *ast = NULL, *st = 0; int tag, len, i, frame, v, res; @@ -280,7 +293,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(ENOMEM); ast->duration = avio_rl32(pb); // number of samples if (((v>>4) & 15) == 2) { // MP3 sound data record - ast->skip_samples = avio_rl16(pb); + ast->internal->skip_samples = avio_rl16(pb); len -= 2; } len -= 7; @@ -295,15 +308,24 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) for(i=0; inb_streams; i++) { st = s->streams[i]; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) { + int pkt_flags = 0; frame = avio_rl16(pb); len -= 2; if (len <= 0) goto skip; + if (st->codecpar->codec_id == AV_CODEC_ID_FLASHSV) { + unsigned flags = avio_r8(pb); + len--; + if (len <= 0) + goto skip; + pkt_flags |= (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ? AV_PKT_FLAG_KEY : 0; + } if ((res = av_get_packet(pb, pkt, len)) < 0) return res; pkt->pos = pos; pkt->pts = frame; pkt->stream_index = st->index; + pkt->flags |= pkt_flags; return pkt->size; } } @@ -355,15 +377,25 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) ff_dlog(s, "bitmap: ch=%d fmt=%d %dx%d (linesize=%d) len=%d->%ld pal=%d\n", ch_id, bmp_fmt, width, height, linesize, len, out_len, colormapsize); + if (len * 17373LL < out_len) + goto bitmap_end_skip; + zbuf = av_malloc(len); - buf = av_malloc(out_len); - if (!zbuf || !buf) { + if (!zbuf) { res = AVERROR(ENOMEM); goto bitmap_end; } len = avio_read(pb, zbuf, len); - if (len < 0 || (res = uncompress(buf, &out_len, zbuf, len)) != Z_OK) { + if (len < 0) + goto bitmap_end_skip; + + buf = av_malloc(out_len); + if (!buf) { + res = AVERROR(ENOMEM); + goto bitmap_end; + } + if ((res = uncompress(buf, &out_len, zbuf, len)) != Z_OK) { av_log(s, AV_LOG_WARNING, "Failed to uncompress one bitmap\n"); goto bitmap_end_skip; } @@ -526,7 +558,7 @@ bitmap_end_skip: #if CONFIG_ZLIB static av_cold int swf_read_close(AVFormatContext *avctx) { - SWFContext *s = avctx->priv_data; + SWFDecContext *s = avctx->priv_data; inflateEnd(&s->zstream); av_freep(&s->zbuf_in); av_freep(&s->zbuf_out); @@ -538,7 +570,7 @@ static av_cold int swf_read_close(AVFormatContext *avctx) AVInputFormat ff_swf_demuxer = { .name = "swf", .long_name = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"), - .priv_data_size = sizeof(SWFContext), + .priv_data_size = sizeof(SWFDecContext), .read_probe = swf_probe, .read_header = swf_read_header, .read_packet = swf_read_packet, diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c index 9da4aad95..7e4e21401 100644 --- a/libavformat/swfenc.c +++ b/libavformat/swfenc.c @@ -22,12 +22,30 @@ #include "libavcodec/put_bits.h" #include "libavutil/avassert.h" +#include "libavutil/fifo.h" #include "avformat.h" +#include "flv.h" #include "swf.h" +#define AUDIO_FIFO_SIZE 65536 + +typedef struct SWFEncContext { + int64_t duration_pos; + int64_t tag_pos; + int64_t vframes_pos; + int samples_per_frame; + int sound_samples; + int swf_frame_number; + int video_frame_number; + int tag; + AVFifoBuffer *audio_fifo; + AVCodecParameters *audio_par, *video_par; + AVStream *video_st; +} SWFEncContext; + static void put_swf_tag(AVFormatContext *s, int tag) { - SWFContext *swf = s->priv_data; + SWFEncContext *swf = s->priv_data; AVIOContext *pb = s->pb; swf->tag_pos = avio_tell(pb); @@ -43,7 +61,7 @@ static void put_swf_tag(AVFormatContext *s, int tag) static void put_swf_end_tag(AVFormatContext *s) { - SWFContext *swf = s->priv_data; + SWFEncContext *swf = s->priv_data; AVIOContext *pb = s->pb; int64_t pos; int tag_len, tag; @@ -173,7 +191,7 @@ static void put_swf_matrix(AVIOContext *pb, static int swf_write_header(AVFormatContext *s) { - SWFContext *swf = s->priv_data; + SWFEncContext *swf = s->priv_data; AVIOContext *pb = s->pb; PutBitContext p; uint8_t buf1[256]; @@ -205,13 +223,13 @@ static int swf_write_header(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "SWF muxer only supports 1 video stream\n"); return AVERROR_INVALIDDATA; } - if (par->codec_id == AV_CODEC_ID_VP6F || - par->codec_id == AV_CODEC_ID_FLV1 || + if (ff_codec_get_tag(ff_swf_codec_tags, par->codec_id) || + par->codec_id == AV_CODEC_ID_PNG || par->codec_id == AV_CODEC_ID_MJPEG) { swf->video_st = s->streams[i]; swf->video_par = par; } else { - av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n"); + av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV, Flash Screen Video, PNG and MJPEG\n"); return -1; } } @@ -240,8 +258,12 @@ static int swf_write_header(AVFormatContext *s) if (!strcmp("avm2", s->oformat->name)) version = 9; - else if (swf->video_par && swf->video_par->codec_id == AV_CODEC_ID_VP6F) - version = 8; /* version 8 and above support VP6 codec */ + else if (swf->video_par && (swf->video_par->codec_id == AV_CODEC_ID_VP6A || + swf->video_par->codec_id == AV_CODEC_ID_VP6F || + swf->video_par->codec_id == AV_CODEC_ID_PNG)) + version = 8; /* version 8 and above support VP6 and PNG codec */ + else if (swf->video_par && swf->video_par->codec_id == AV_CODEC_ID_FLASHSV) + version = 7; /* version 7 and above support Flash Screen Video codec */ else if (swf->video_par && swf->video_par->codec_id == AV_CODEC_ID_FLV1) version = 6; /* version 6 and above support FLV1 codec */ else @@ -260,15 +282,15 @@ static int swf_write_header(AVFormatContext *s) swf->duration_pos = avio_tell(pb); avio_wl16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */ - /* avm2/swf v9 (also v8?) files require a file attribute tag */ - if (version == 9) { + /* swf v8 and later files require a file attribute tag */ + if (version >= 8) { put_swf_tag(s, TAG_FILEATTRIBUTES); - avio_wl32(pb, 1<<3); /* set ActionScript v3/AVM2 flag */ + avio_wl32(pb, (version >= 9) << 3); /* set ActionScript v3/AVM2 flag */ put_swf_end_tag(s); } /* define a shape with the jpeg inside */ - if (swf->video_par && swf->video_par->codec_id == AV_CODEC_ID_MJPEG) { + if (swf->video_par && (swf->video_par->codec_id == AV_CODEC_ID_MJPEG || swf->video_par->codec_id == AV_CODEC_ID_PNG)) { put_swf_tag(s, TAG_DEFINESHAPE); avio_wl16(pb, SHAPE_ID); /* ID of shape */ @@ -341,17 +363,17 @@ static int swf_write_header(AVFormatContext *s) } static int swf_write_video(AVFormatContext *s, - AVCodecParameters *par, const uint8_t *buf, int size) + AVCodecParameters *par, const uint8_t *buf, int size, unsigned pkt_flags) { - SWFContext *swf = s->priv_data; + SWFEncContext *swf = s->priv_data; AVIOContext *pb = s->pb; + unsigned codec_tag = ff_codec_get_tag(ff_swf_codec_tags, par->codec_id); /* Flash Player limit */ if (swf->swf_frame_number == 16000) av_log(s, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n"); - if (par->codec_id == AV_CODEC_ID_VP6F || - par->codec_id == AV_CODEC_ID_FLV1) { + if (codec_tag) { if (swf->video_frame_number == 0) { /* create a new video object */ put_swf_tag(s, TAG_VIDEOSTREAM); @@ -361,7 +383,7 @@ static int swf_write_video(AVFormatContext *s, avio_wl16(pb, par->width); avio_wl16(pb, par->height); avio_w8(pb, 0); - avio_w8(pb,ff_codec_get_tag(ff_swf_codec_tags, par->codec_id)); + avio_w8(pb, codec_tag); put_swf_end_tag(s); /* place the video object for the first time */ @@ -387,9 +409,14 @@ static int swf_write_video(AVFormatContext *s, put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG); avio_wl16(pb, VIDEO_ID); avio_wl16(pb, swf->video_frame_number++); + if (par->codec_id == AV_CODEC_ID_FLASHSV) { + /* FrameType and CodecId is needed here even if it is not documented correctly in the SWF specs */ + int flags = codec_tag | (pkt_flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER); + avio_w8(pb, flags); + } avio_write(pb, buf, size); put_swf_end_tag(s); - } else if (par->codec_id == AV_CODEC_ID_MJPEG) { + } else if (par->codec_id == AV_CODEC_ID_MJPEG || par->codec_id == AV_CODEC_ID_PNG) { if (swf->swf_frame_number > 0) { /* remove the shape */ put_swf_tag(s, TAG_REMOVEOBJECT); @@ -408,8 +435,9 @@ static int swf_write_video(AVFormatContext *s, avio_wl16(pb, BITMAP_ID); /* ID of the image */ /* a dummy jpeg header seems to be required */ - avio_wb32(pb, 0xffd8ffd9); - /* write the jpeg image */ + if (par->codec_id == AV_CODEC_ID_MJPEG) + avio_wb32(pb, 0xffd8ffd9); + /* write the jpeg/png image */ avio_write(pb, buf, size); put_swf_end_tag(s); @@ -448,7 +476,7 @@ static int swf_write_video(AVFormatContext *s, static int swf_write_audio(AVFormatContext *s, AVCodecParameters *par, uint8_t *buf, int size) { - SWFContext *swf = s->priv_data; + SWFEncContext *swf = s->priv_data; /* Flash Player limit */ if (swf->swf_frame_number == 16000) @@ -464,7 +492,7 @@ static int swf_write_audio(AVFormatContext *s, /* if audio only stream make sure we add swf frames */ if (!swf->video_par) - swf_write_video(s, par, 0, 0); + swf_write_video(s, par, 0, 0, 0); return 0; } @@ -475,31 +503,20 @@ static int swf_write_packet(AVFormatContext *s, AVPacket *pkt) if (par->codec_type == AVMEDIA_TYPE_AUDIO) return swf_write_audio(s, par, pkt->data, pkt->size); else - return swf_write_video(s, par, pkt->data, pkt->size); + return swf_write_video(s, par, pkt->data, pkt->size, pkt->flags); } static int swf_write_trailer(AVFormatContext *s) { - SWFContext *swf = s->priv_data; + SWFEncContext *swf = s->priv_data; AVIOContext *pb = s->pb; - AVCodecParameters *par, *video_par; - int file_size, i; - - video_par = NULL; - for(i=0;inb_streams;i++) { - par = s->streams[i]->codecpar; - if (par->codec_type == AVMEDIA_TYPE_VIDEO) - video_par = par; - else { - av_fifo_freep(&swf->audio_fifo); - } - } + int file_size; put_swf_tag(s, TAG_END); put_swf_end_tag(s); /* patch file size and number of frames if not streamed */ - if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && video_par) { + if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && swf->video_par) { file_size = avio_tell(pb); avio_seek(pb, 4, SEEK_SET); avio_wl32(pb, file_size); @@ -514,18 +531,26 @@ static int swf_write_trailer(AVFormatContext *s) return 0; } +static void swf_deinit(AVFormatContext *s) +{ + SWFEncContext *swf = s->priv_data; + + av_fifo_freep(&swf->audio_fifo); +} + #if CONFIG_SWF_MUXER AVOutputFormat ff_swf_muxer = { .name = "swf", .long_name = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"), .mime_type = "application/x-shockwave-flash", .extensions = "swf", - .priv_data_size = sizeof(SWFContext), + .priv_data_size = sizeof(SWFEncContext), .audio_codec = AV_CODEC_ID_MP3, .video_codec = AV_CODEC_ID_FLV1, .write_header = swf_write_header, .write_packet = swf_write_packet, .write_trailer = swf_write_trailer, + .deinit = swf_deinit, .flags = AVFMT_TS_NONSTRICT, }; #endif @@ -534,12 +559,13 @@ AVOutputFormat ff_avm2_muxer = { .name = "avm2", .long_name = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash) (AVM2)"), .mime_type = "application/x-shockwave-flash", - .priv_data_size = sizeof(SWFContext), + .priv_data_size = sizeof(SWFEncContext), .audio_codec = AV_CODEC_ID_MP3, .video_codec = AV_CODEC_ID_FLV1, .write_header = swf_write_header, .write_packet = swf_write_packet, .write_trailer = swf_write_trailer, + .deinit = swf_deinit, .flags = AVFMT_TS_NONSTRICT, }; #endif diff --git a/libavformat/tedcaptionsdec.c b/libavformat/tedcaptionsdec.c index 8b4452898..9a882c4d7 100644 --- a/libavformat/tedcaptionsdec.c +++ b/libavformat/tedcaptionsdec.c @@ -94,25 +94,20 @@ static int parse_string(AVIOContext *pb, int *cur_byte, AVBPrint *bp, int full) { int ret; - av_bprint_init(bp, 0, full ? AV_BPRINT_SIZE_UNLIMITED : AV_BPRINT_SIZE_AUTOMATIC); ret = expect_byte(pb, cur_byte, '"'); if (ret < 0) - goto fail; + return ret; while (*cur_byte > 0 && *cur_byte != '"') { if (*cur_byte == '\\') { next_byte(pb, cur_byte); - if (*cur_byte < 0) { - ret = AVERROR_INVALIDDATA; - goto fail; - } + if (*cur_byte < 0) + return AVERROR_INVALIDDATA; if ((*cur_byte | 32) == 'u') { unsigned chr = 0, i; for (i = 0; i < 4; i++) { next_byte(pb, cur_byte); - if (!HEX_DIGIT_TEST(*cur_byte)) { - ret = ERR_CODE(*cur_byte); - goto fail; - } + if (!HEX_DIGIT_TEST(*cur_byte)) + return ERR_CODE(*cur_byte); chr = chr * 16 + HEX_DIGIT_VAL(*cur_byte); } av_bprint_utf8(bp, chr); @@ -126,22 +121,18 @@ static int parse_string(AVIOContext *pb, int *cur_byte, AVBPrint *bp, int full) } ret = expect_byte(pb, cur_byte, '"'); if (ret < 0) - goto fail; - if (full && !av_bprint_is_complete(bp)) { - ret = AVERROR(ENOMEM); - goto fail; - } - return 0; + return ret; + if (full && !av_bprint_is_complete(bp)) + return AVERROR(ENOMEM); -fail: - av_bprint_finalize(bp, NULL); - return ret; + return 0; } static int parse_label(AVIOContext *pb, int *cur_byte, AVBPrint *bp) { int ret; + av_bprint_init(bp, 0, AV_BPRINT_SIZE_AUTOMATIC); ret = parse_string(pb, cur_byte, bp, 0); if (ret < 0) return ret; @@ -197,6 +188,8 @@ static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs) int64_t pos, start, duration; AVPacket *pkt; + av_bprint_init(&content, 0, AV_BPRINT_SIZE_UNLIMITED); + next_byte(pb, &cur_byte); ret = expect_byte(pb, &cur_byte, '{'); if (ret < 0) @@ -208,34 +201,34 @@ static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs) if (ret < 0) return AVERROR_INVALIDDATA; while (1) { - content.size = 0; start = duration = AV_NOPTS_VALUE; ret = expect_byte(pb, &cur_byte, '{'); if (ret < 0) - return ret; + goto fail; pos = avio_tell(pb) - 1; while (1) { ret = parse_label(pb, &cur_byte, &label); if (ret < 0) - return ret; + goto fail; if (!strcmp(label.str, "startOfParagraph")) { ret = parse_boolean(pb, &cur_byte, &start_of_par); if (ret < 0) - return ret; + goto fail; } else if (!strcmp(label.str, "content")) { ret = parse_string(pb, &cur_byte, &content, 1); if (ret < 0) - return ret; + goto fail; } else if (!strcmp(label.str, "startTime")) { ret = parse_int(pb, &cur_byte, &start); if (ret < 0) - return ret; + goto fail; } else if (!strcmp(label.str, "duration")) { ret = parse_int(pb, &cur_byte, &duration); if (ret < 0) - return ret; + goto fail; } else { - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } skip_spaces(pb, &cur_byte); if (cur_byte != ',') @@ -244,18 +237,22 @@ static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs) } ret = expect_byte(pb, &cur_byte, '}'); if (ret < 0) - return ret; + goto fail; if (!content.size || start == AV_NOPTS_VALUE || - duration == AV_NOPTS_VALUE) - return AVERROR_INVALIDDATA; + duration == AV_NOPTS_VALUE) { + ret = AVERROR_INVALIDDATA; + goto fail; + } pkt = ff_subtitles_queue_insert(subs, content.str, content.len, 0); - if (!pkt) - return AVERROR(ENOMEM); + if (!pkt) { + ret = AVERROR(ENOMEM); + goto fail; + } pkt->pos = pos; pkt->pts = start; pkt->duration = duration; - av_bprint_finalize(&content, NULL); + av_bprint_clear(&content); skip_spaces(pb, &cur_byte); if (cur_byte != ',') @@ -264,14 +261,16 @@ static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs) } ret = expect_byte(pb, &cur_byte, ']'); if (ret < 0) - return ret; + goto fail; ret = expect_byte(pb, &cur_byte, '}'); if (ret < 0) - return ret; + goto fail; skip_spaces(pb, &cur_byte); if (cur_byte != AVERROR_EOF) - return ERR_CODE(cur_byte); - return 0; + ret = ERR_CODE(cur_byte); +fail: + av_bprint_finalize(&content, NULL); + return ret; } static av_cold int tedcaptions_read_header(AVFormatContext *avf) @@ -294,9 +293,9 @@ static av_cold int tedcaptions_read_header(AVFormatContext *avf) } ff_subtitles_queue_finalize(avf, &tc->subs); for (i = 0; i < tc->subs.nb_subs; i++) - tc->subs.subs[i].pts += tc->start_time; + tc->subs.subs[i]->pts += tc->start_time; - last = &tc->subs.subs[tc->subs.nb_subs - 1]; + last = tc->subs.subs[tc->subs.nb_subs - 1]; st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_TEXT; avpriv_set_pts_info(st, 64, 1, 1000); diff --git a/libavformat/tee.c b/libavformat/tee.c index c5c59975e..c0b69a386 100644 --- a/libavformat/tee.c +++ b/libavformat/tee.c @@ -614,5 +614,5 @@ AVOutputFormat ff_tee_muxer = { .write_trailer = tee_write_trailer, .write_packet = tee_write_packet, .priv_class = &tee_muxer_class, - .flags = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH, + .flags = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE, }; diff --git a/libavformat/tests/fifo_muxer.c b/libavformat/tests/fifo_muxer.c index 5127a8aad..227c3d021 100644 --- a/libavformat/tests/fifo_muxer.c +++ b/libavformat/tests/fifo_muxer.c @@ -41,21 +41,18 @@ typedef struct FailingMuxerPacketData { static int prepare_packet(AVPacket *pkt, const FailingMuxerPacketData *pkt_data, int64_t pts) { - int ret; - FailingMuxerPacketData *data = av_malloc(sizeof(*data)); - if (!data) { - return AVERROR(ENOMEM); - } - memcpy(data, pkt_data, sizeof(FailingMuxerPacketData)); - ret = av_packet_from_data(pkt, (uint8_t*) data, sizeof(*data)); + int ret = av_new_packet(pkt, sizeof(*pkt_data)); + if (ret < 0) + return ret; + memcpy(pkt->data, pkt_data, sizeof(*pkt_data)); pkt->pts = pkt->dts = pts; pkt->duration = 1; - return ret; + return 0; } -static int initialize_fifo_tst_muxer_chain(AVFormatContext **oc) +static int initialize_fifo_tst_muxer_chain(AVFormatContext **oc, AVPacket **pkt) { int ret = 0; AVStream *s; @@ -71,20 +68,20 @@ static int initialize_fifo_tst_muxer_chain(AVFormatContext **oc) if (!s) { fprintf(stderr, "Failed to create stream: %s\n", av_err2str(ret)); - ret = AVERROR(ENOMEM); + return AVERROR(ENOMEM); } - return ret; + *pkt = av_packet_alloc(); + if (!*pkt) + return AVERROR(ENOMEM); + + return 0; } static int fifo_basic_test(AVFormatContext *oc, AVDictionary **opts, - const FailingMuxerPacketData *pkt_data) + AVPacket *pkt, const FailingMuxerPacketData *pkt_data) { int ret = 0, i; - AVPacket pkt; - - av_init_packet(&pkt); - ret = avformat_write_header(oc, opts); if (ret) { @@ -94,14 +91,14 @@ static int fifo_basic_test(AVFormatContext *oc, AVDictionary **opts, } for (i = 0; i < 15; i++ ) { - ret = prepare_packet(&pkt, pkt_data, i); + ret = prepare_packet(pkt, pkt_data, i); if (ret < 0) { fprintf(stderr, "Failed to prepare test packet: %s\n", av_err2str(ret)); goto write_trailer_and_fail; } - ret = av_write_frame(oc, &pkt); - av_packet_unref(&pkt); + ret = av_write_frame(oc, pkt); + av_packet_unref(pkt); if (ret < 0) { fprintf(stderr, "Unexpected write_frame error: %s\n", av_err2str(ret)); @@ -131,13 +128,10 @@ fail: } static int fifo_overflow_drop_test(AVFormatContext *oc, AVDictionary **opts, - const FailingMuxerPacketData *data) + AVPacket *pkt, const FailingMuxerPacketData *data) { int ret = 0, i; int64_t write_pkt_start, write_pkt_end, duration; - AVPacket pkt; - - av_init_packet(&pkt); ret = avformat_write_header(oc, opts); if (ret) { @@ -148,18 +142,19 @@ static int fifo_overflow_drop_test(AVFormatContext *oc, AVDictionary **opts, write_pkt_start = av_gettime_relative(); for (i = 0; i < 6; i++ ) { - ret = prepare_packet(&pkt, data, i); + ret = prepare_packet(pkt, data, i); if (ret < 0) { fprintf(stderr, "Failed to prepare test packet: %s\n", av_err2str(ret)); goto fail; } - ret = av_write_frame(oc, &pkt); - av_packet_unref(&pkt); + ret = av_write_frame(oc, pkt); + av_packet_unref(pkt); if (ret < 0) { break; } } + write_pkt_end = av_gettime_relative(); duration = write_pkt_end - write_pkt_start; if (duration > (SLEEPTIME_50_MS*6)/2) { @@ -185,7 +180,8 @@ fail: } typedef struct TestCase { - int (*test_func)(AVFormatContext *, AVDictionary **,const FailingMuxerPacketData *pkt_data); + int (*test_func)(AVFormatContext *, AVDictionary **, + AVPacket *, const FailingMuxerPacketData *pkt_data); const char *test_name; const char *options; @@ -203,10 +199,11 @@ static int run_test(const TestCase *test) { AVDictionary *opts = NULL; AVFormatContext *oc = NULL; + AVPacket *pkt = NULL; char buffer[BUFFER_SIZE]; int ret, ret1; - ret = initialize_fifo_tst_muxer_chain(&oc); + ret = initialize_fifo_tst_muxer_chain(&oc, &pkt); if (ret < 0) { fprintf(stderr, "Muxer initialization failed: %s\n", av_err2str(ret)); goto end; @@ -232,11 +229,12 @@ static int run_test(const TestCase *test) goto end; } - ret = test->test_func(oc, &opts, &test->pkt_data); + ret = test->test_func(oc, &opts, pkt, &test->pkt_data); end: printf("%s: %s\n", test->test_name, ret < 0 ? "fail" : "ok"); avformat_free_context(oc); + av_packet_free(&pkt); av_dict_free(&opts); return ret; } diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c index 1d15d97ad..04155dde7 100644 --- a/libavformat/tests/movenc.c +++ b/libavformat/tests/movenc.c @@ -56,6 +56,7 @@ int out_size; struct AVMD5* md5; uint8_t hash[HASH_SIZE]; +AVPacket *pkt; AVStream *video_st, *audio_st; int64_t audio_dts, video_dts; @@ -248,68 +249,67 @@ static void mux_frames(int n, int c) { int end_frames = frames + n; while (1) { - AVPacket pkt; uint8_t pktdata[8] = { 0 }; - av_init_packet(&pkt); + av_packet_unref(pkt); if (av_compare_ts(audio_dts, audio_st->time_base, video_dts, video_st->time_base) < 0) { - pkt.dts = pkt.pts = audio_dts; - pkt.stream_index = 1; - pkt.duration = audio_duration; + pkt->dts = pkt->pts = audio_dts; + pkt->stream_index = 1; + pkt->duration = audio_duration; audio_dts += audio_duration; } else { if (frames == end_frames) break; - pkt.dts = video_dts; - pkt.stream_index = 0; - pkt.duration = duration; + pkt->dts = video_dts; + pkt->stream_index = 0; + pkt->duration = duration; if ((frames % gop_size) == 0) { - pkt.flags |= AV_PKT_FLAG_KEY; + pkt->flags |= AV_PKT_FLAG_KEY; last_picture = AV_PICTURE_TYPE_I; - pkt.pts = pkt.dts + duration; - video_dts = pkt.pts; + pkt->pts = pkt->dts + duration; + video_dts = pkt->pts; } else { if (last_picture == AV_PICTURE_TYPE_P) { last_picture = AV_PICTURE_TYPE_B; - pkt.pts = pkt.dts; + pkt->pts = pkt->dts; video_dts = next_p_pts; } else { last_picture = AV_PICTURE_TYPE_P; if (((frames + 1) % gop_size) == 0) { - pkt.pts = pkt.dts + duration; - video_dts = pkt.pts; + pkt->pts = pkt->dts + duration; + video_dts = pkt->pts; } else { - next_p_pts = pkt.pts = pkt.dts + 2 * duration; + next_p_pts = pkt->pts = pkt->dts + 2 * duration; video_dts += duration; } } } if (!bframes) - pkt.pts = pkt.dts; + pkt->pts = pkt->dts; if (fake_pkt_duration) - pkt.duration = fake_pkt_duration; + pkt->duration = fake_pkt_duration; frames++; } if (clear_duration) - pkt.duration = 0; - AV_WB32(pktdata + 4, pkt.pts); - pkt.data = pktdata; - pkt.size = 8; + pkt->duration = 0; + AV_WB32(pktdata + 4, pkt->pts); + pkt->data = pktdata; + pkt->size = 8; if (skip_write) continue; - if (skip_write_audio && pkt.stream_index == 1) + if (skip_write_audio && pkt->stream_index == 1) continue; if (c) { - pkt.pts += (1LL<<32); - pkt.dts += (1LL<<32); + pkt->pts += (1LL<<32); + pkt->dts += (1LL<<32); } if (do_interleave) - av_interleaved_write_frame(ctx, &pkt); + av_interleaved_write_frame(ctx, pkt); else - av_write_frame(ctx, &pkt); + av_write_frame(ctx, pkt); } } @@ -327,19 +327,16 @@ static void skip_gops(int n) static void signal_init_ts(void) { - AVPacket pkt; - av_init_packet(&pkt); - pkt.size = 0; - pkt.data = NULL; + av_packet_unref(pkt); - pkt.stream_index = 0; - pkt.dts = video_dts; - pkt.pts = 0; - av_write_frame(ctx, &pkt); + pkt->stream_index = 0; + pkt->dts = video_dts; + pkt->pts = 0; + av_write_frame(ctx, pkt); - pkt.stream_index = 1; - pkt.dts = pkt.pts = audio_dts; - av_write_frame(ctx, &pkt); + pkt->stream_index = 1; + pkt->dts = pkt->pts = audio_dts; + av_write_frame(ctx, pkt); } static void finish(void) @@ -382,6 +379,11 @@ int main(int argc, char **argv) md5 = av_md5_alloc(); if (!md5) return 1; + pkt = av_packet_alloc(); + if (!pkt) { + av_free(md5); + return 1; + } // Write a fragmented file with an initial moov that actually contains some // samples. One moov+mdat with 1 second of data and one moof+mdat with 1 @@ -786,6 +788,7 @@ int main(int argc, char **argv) close_out(); av_free(md5); + av_packet_free(&pkt); return check_faults > 0 ? 1 : 0; } diff --git a/libavformat/tests/url.c b/libavformat/tests/url.c index 2eb597bb5..8644a3e82 100644 --- a/libavformat/tests/url.c +++ b/libavformat/tests/url.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include "libavformat/url.h" #include "libavformat/avformat.h" @@ -48,19 +49,30 @@ static void test_decompose(const char *url) static void test(const char *base, const char *rel) { - char buf[200], buf2[200]; + char buf[200], buf2[200], buf_dos[200], buf_native[200]; int ret; - ret = ff_make_absolute_url(buf, sizeof(buf), base, rel); + ret = ff_make_absolute_url2(buf, sizeof(buf), base, rel, 0); if (ret < 0) { printf("%50s %-20s => error %s\n", base, rel, av_err2str(ret)); return; } printf("%50s %-20s => %s\n", base, rel, buf); + ret = ff_make_absolute_url2(buf_dos, sizeof(buf_dos), base, rel, 1); + if (ret < 0) + snprintf(buf_dos, sizeof(buf_dos), "error %s", av_err2str(ret)); + ret = ff_make_absolute_url(buf_native, sizeof(buf_native), base, rel); + if (ret < 0) + snprintf(buf_native, sizeof(buf_native), "error %s", av_err2str(ret)); + if (strcmp(buf, buf_dos)) + printf("%50s %-20sDOS %s\n", base, rel, buf_dos); + if (HAVE_DOS_PATHS && strcmp(buf_dos, buf_native) || + !HAVE_DOS_PATHS && strcmp(buf, buf_native)) + printf("Native mismatch\n"); if (base) { /* Test in-buffer replacement */ snprintf(buf2, sizeof(buf2), "%s", base); - ff_make_absolute_url(buf2, sizeof(buf2), buf2, rel); + ff_make_absolute_url2(buf2, sizeof(buf2), buf2, rel, 0); if (strcmp(buf, buf2)) { printf("In-place handling of %s + %s failed\n", base, rel); exit(1); @@ -121,6 +133,21 @@ int main(void) test("http://server/foo/bar", "..doubledotfile"); test("http://server/foo/bar", "double..dotfile"); test("http://server/foo/bar", "doubledotfile.."); + test("file1", "file2"); + test("dir/file1", "file2"); + test("dir/file1", "../file2"); + test("dir\\file1", "file2"); + test("\\\\srv\\shr\\file", "..\\..\\dummy"); + test("\\\\srv\\shr\\file", "dummy"); + test("\\\\srv\\shr\\file", "\\\\srv2\\shr2\\file2"); + test("\\\\srv\\shr\\file", "d:/file"); + test("C:\\dir\\a", "..\\file"); + test("C:\\dir\\a", "\\\\srv\\shr\\file"); + test("C:\\dir\\a", "d:\\file"); + test("http://a/b", "\\\\srv\\shr\\file"); + test("http://a/b", "//srv/shr/file"); + test("http://a/b", "d:\\file"); + test("http://a/b", "C:/file"); /* From https://tools.ietf.org/html/rfc3986#section-5.4 */ test("http://a/b/c/d;p?q", "g:h"); // g:h diff --git a/libavformat/tls.c b/libavformat/tls.c index 10e0792e2..302c0f8d5 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -89,7 +89,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV if (!c->host && !(c->host = av_strdup(c->underlying_host))) return AVERROR(ENOMEM); - proxy_path = getenv("http_proxy"); + proxy_path = c->http_proxy ? c->http_proxy : getenv("http_proxy"); use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), c->underlying_host) && proxy_path && av_strstart(proxy_path, "http://", NULL); diff --git a/libavformat/tls.h b/libavformat/tls.h index beb19d6d5..6c6aa01a9 100644 --- a/libavformat/tls.h +++ b/libavformat/tls.h @@ -34,6 +34,7 @@ typedef struct TLSShared { int listen; char *host; + char *http_proxy; char underlying_host[200]; int numerichost; @@ -49,7 +50,8 @@ typedef struct TLSShared { {"cert_file", "Certificate file", offsetof(pstruct, options_field . cert_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ {"key_file", "Private key file", offsetof(pstruct, options_field . key_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ {"listen", "Listen for incoming connections", offsetof(pstruct, options_field . listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \ - {"verifyhost", "Verify against a specific hostname", offsetof(pstruct, options_field . host), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL } + {"verifyhost", "Verify against a specific hostname", offsetof(pstruct, options_field . host), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ + {"http_proxy", "Set proxy to tunnel through", offsetof(pstruct, options_field . http_proxy), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL } int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options); diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c index 0c4ef34f5..f9d5af709 100644 --- a/libavformat/tls_gnutls.c +++ b/libavformat/tls_gnutls.c @@ -269,6 +269,12 @@ static int tls_get_file_handle(URLContext *h) return ffurl_get_file_handle(c->tls_shared.tcp); } +static int tls_get_short_seek(URLContext *h) +{ + TLSContext *s = h->priv_data; + return ffurl_get_short_seek(s->tls_shared.tcp); +} + static const AVOption options[] = { TLS_COMMON_OPTIONS(TLSContext, tls_shared), { NULL } @@ -288,6 +294,7 @@ const URLProtocol ff_tls_protocol = { .url_write = tls_write, .url_close = tls_close, .url_get_file_handle = tls_get_file_handle, + .url_get_short_seek = tls_get_short_seek, .priv_data_size = sizeof(TLSContext), .flags = URL_PROTOCOL_FLAG_NETWORK, .priv_data_class = &tls_class, diff --git a/libavformat/tls_libtls.c b/libavformat/tls_libtls.c index dff7f2d9f..911c8094b 100644 --- a/libavformat/tls_libtls.c +++ b/libavformat/tls_libtls.c @@ -181,6 +181,12 @@ static int tls_get_file_handle(URLContext *h) return ffurl_get_file_handle(c->tls_shared.tcp); } +static int tls_get_short_seek(URLContext *h) +{ + TLSContext *s = h->priv_data; + return ffurl_get_short_seek(s->tls_shared.tcp); +} + static const AVOption options[] = { TLS_COMMON_OPTIONS(TLSContext, tls_shared), { NULL } @@ -200,6 +206,7 @@ const URLProtocol ff_tls_protocol = { .url_write = ff_tls_write, .url_close = ff_tls_close, .url_get_file_handle = tls_get_file_handle, + .url_get_short_seek = tls_get_short_seek, .priv_data_size = sizeof(TLSContext), .flags = URL_PROTOCOL_FLAG_NETWORK, .priv_data_class = &tls_class, diff --git a/libavformat/tls_mbedtls.c b/libavformat/tls_mbedtls.c index 965adf1be..aadf17760 100644 --- a/libavformat/tls_mbedtls.c +++ b/libavformat/tls_mbedtls.c @@ -326,6 +326,12 @@ static int tls_get_file_handle(URLContext *h) return ffurl_get_file_handle(c->tls_shared.tcp); } +static int tls_get_short_seek(URLContext *h) +{ + TLSContext *s = h->priv_data; + return ffurl_get_short_seek(s->tls_shared.tcp); +} + static const AVOption options[] = { TLS_COMMON_OPTIONS(TLSContext, tls_shared), \ {"key_password", "Password for the private key file", OFFSET(priv_key_pw), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ @@ -346,6 +352,7 @@ const URLProtocol ff_tls_protocol = { .url_write = tls_write, .url_close = tls_close, .url_get_file_handle = tls_get_file_handle, + .url_get_short_seek = tls_get_short_seek, .priv_data_size = sizeof(TLSContext), .flags = URL_PROTOCOL_FLAG_NETWORK, .priv_data_class = &tls_class, diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c index 002197fa7..e0616acbc 100644 --- a/libavformat/tls_openssl.c +++ b/libavformat/tls_openssl.c @@ -351,6 +351,12 @@ static int tls_get_file_handle(URLContext *h) return ffurl_get_file_handle(c->tls_shared.tcp); } +static int tls_get_short_seek(URLContext *h) +{ + TLSContext *s = h->priv_data; + return ffurl_get_short_seek(s->tls_shared.tcp); +} + static const AVOption options[] = { TLS_COMMON_OPTIONS(TLSContext, tls_shared), { NULL } @@ -370,6 +376,7 @@ const URLProtocol ff_tls_protocol = { .url_write = tls_write, .url_close = tls_close, .url_get_file_handle = tls_get_file_handle, + .url_get_short_seek = tls_get_short_seek, .priv_data_size = sizeof(TLSContext), .flags = URL_PROTOCOL_FLAG_NETWORK, .priv_data_class = &tls_class, diff --git a/libavformat/tls_schannel.c b/libavformat/tls_schannel.c index 4bfaa8522..d4959f75f 100644 --- a/libavformat/tls_schannel.c +++ b/libavformat/tls_schannel.c @@ -589,6 +589,12 @@ static int tls_get_file_handle(URLContext *h) return ffurl_get_file_handle(c->tls_shared.tcp); } +static int tls_get_short_seek(URLContext *h) +{ + TLSContext *s = h->priv_data; + return ffurl_get_short_seek(s->tls_shared.tcp); +} + static const AVOption options[] = { TLS_COMMON_OPTIONS(TLSContext, tls_shared), { NULL } @@ -608,6 +614,7 @@ const URLProtocol ff_tls_protocol = { .url_write = tls_write, .url_close = tls_close, .url_get_file_handle = tls_get_file_handle, + .url_get_short_seek = tls_get_short_seek, .priv_data_size = sizeof(TLSContext), .flags = URL_PROTOCOL_FLAG_NETWORK, .priv_data_class = &tls_class, diff --git a/libavformat/tls_securetransport.c b/libavformat/tls_securetransport.c index 3250b2305..f6a1a5e7b 100644 --- a/libavformat/tls_securetransport.c +++ b/libavformat/tls_securetransport.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Rodger Combs + * Copyright (c) 2015 rcombs * * This file is part of FFmpeg. * @@ -396,6 +396,12 @@ static int tls_get_file_handle(URLContext *h) return ffurl_get_file_handle(c->tls_shared.tcp); } +static int tls_get_short_seek(URLContext *h) +{ + TLSContext *s = h->priv_data; + return ffurl_get_short_seek(s->tls_shared.tcp); +} + static const AVOption options[] = { TLS_COMMON_OPTIONS(TLSContext, tls_shared), { NULL } @@ -415,6 +421,7 @@ const URLProtocol ff_tls_protocol = { .url_write = tls_write, .url_close = tls_close, .url_get_file_handle = tls_get_file_handle, + .url_get_short_seek = tls_get_short_seek, .priv_data_size = sizeof(TLSContext), .flags = URL_PROTOCOL_FLAG_NETWORK, .priv_data_class = &tls_class, diff --git a/libavformat/ttaenc.c b/libavformat/ttaenc.c index becd3e715..32eb26904 100644 --- a/libavformat/ttaenc.c +++ b/libavformat/ttaenc.c @@ -22,6 +22,7 @@ #include "libavutil/crc.h" #include "libavutil/intreadwrite.h" +#include "libavcodec/packet_internal.h" #include "apetag.h" #include "avformat.h" #include "avio_internal.h" @@ -29,7 +30,7 @@ typedef struct TTAMuxContext { AVIOContext *seek_table; - AVPacketList *queue, *queue_end; + PacketList *queue, *queue_end; uint32_t nb_samples; int frame_size; int last_frame; @@ -93,8 +94,8 @@ static int tta_write_packet(AVFormatContext *s, AVPacket *pkt) TTAMuxContext *tta = s->priv_data; int ret; - ret = ff_packet_list_put(&tta->queue, &tta->queue_end, pkt, - FF_PACKETLIST_FLAG_REF_PACKET); + ret = avpriv_packet_list_put(&tta->queue, &tta->queue_end, pkt, + av_packet_ref, 0); if (ret < 0) { return ret; } @@ -125,7 +126,7 @@ static void tta_queue_flush(AVFormatContext *s) AVPacket pkt; while (tta->queue) { - ff_packet_list_get(&tta->queue, &tta->queue_end, &pkt); + avpriv_packet_list_get(&tta->queue, &tta->queue_end, &pkt); avio_write(s->pb, pkt.data, pkt.size); av_packet_unref(&pkt); } @@ -161,7 +162,7 @@ static void tta_deinit(AVFormatContext *s) TTAMuxContext *tta = s->priv_data; ffio_free_dyn_buf(&tta->seek_table); - ff_packet_list_free(&tta->queue, &tta->queue_end); + avpriv_packet_list_free(&tta->queue, &tta->queue_end); } AVOutputFormat ff_tta_muxer = { diff --git a/libavformat/ttmlenc.c b/libavformat/ttmlenc.c new file mode 100644 index 000000000..940f8bbd4 --- /dev/null +++ b/libavformat/ttmlenc.c @@ -0,0 +1,174 @@ +/* + * TTML subtitle muxer + * Copyright (c) 2020 24i + * + * 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 + * TTML subtitle muxer + * @see https://www.w3.org/TR/ttml1/ + * @see https://www.w3.org/TR/ttml2/ + * @see https://www.w3.org/TR/ttml-imsc/rec + */ + +#include "avformat.h" +#include "internal.h" +#include "libavcodec/ttmlenc.h" +#include "libavutil/internal.h" + +enum TTMLPacketType { + PACKET_TYPE_PARAGRAPH, + PACKET_TYPE_DOCUMENT, +}; + +typedef struct TTMLMuxContext { + enum TTMLPacketType input_type; + unsigned int document_written; +} TTMLMuxContext; + +static const char ttml_header_text[] = +"\n" +"\n" +" \n" +"
\n"; + +static const char ttml_footer_text[] = +"
\n" +" \n" +"\n"; + +static void ttml_write_time(AVIOContext *pb, const char tag[], + int64_t millisec) +{ + int64_t sec, min, hour; + sec = millisec / 1000; + millisec -= 1000 * sec; + min = sec / 60; + sec -= 60 * min; + hour = min / 60; + min -= 60 * hour; + + avio_printf(pb, "%s=\"%02"PRId64":%02"PRId64":%02"PRId64".%03"PRId64"\"", + tag, hour, min, sec, millisec); +} + +static int ttml_write_header(AVFormatContext *ctx) +{ + TTMLMuxContext *ttml_ctx = ctx->priv_data; + ttml_ctx->document_written = 0; + + if (ctx->nb_streams != 1 || + ctx->streams[0]->codecpar->codec_id != AV_CODEC_ID_TTML) { + av_log(ctx, AV_LOG_ERROR, "Exactly one TTML stream is required!\n"); + return AVERROR(EINVAL); + } + + { + AVStream *st = ctx->streams[0]; + AVIOContext *pb = ctx->pb; + + AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, + 0); + const char *printed_lang = (lang && lang->value) ? lang->value : ""; + + // Not perfect, but decide whether the packet is a document or not + // by the existence of the lavc ttmlenc extradata. + ttml_ctx->input_type = (st->codecpar->extradata && + st->codecpar->extradata_size >= TTMLENC_EXTRADATA_SIGNATURE_SIZE && + !memcmp(st->codecpar->extradata, + TTMLENC_EXTRADATA_SIGNATURE, + TTMLENC_EXTRADATA_SIGNATURE_SIZE)) ? + PACKET_TYPE_PARAGRAPH : + PACKET_TYPE_DOCUMENT; + + avpriv_set_pts_info(st, 64, 1, 1000); + + if (ttml_ctx->input_type == PACKET_TYPE_PARAGRAPH) + avio_printf(pb, ttml_header_text, printed_lang); + } + + return 0; +} + +static int ttml_write_packet(AVFormatContext *ctx, AVPacket *pkt) +{ + TTMLMuxContext *ttml_ctx = ctx->priv_data; + AVIOContext *pb = ctx->pb; + + switch (ttml_ctx->input_type) { + case PACKET_TYPE_PARAGRAPH: + // write out a paragraph element with the given contents. + avio_printf(pb, " pts); + avio_w8(pb, '\n'); + ttml_write_time(pb, " end", pkt->pts + pkt->duration); + avio_printf(pb, ">"); + avio_write(pb, pkt->data, pkt->size); + avio_printf(pb, "

\n"); + break; + case PACKET_TYPE_DOCUMENT: + // dump the given document out as-is. + if (ttml_ctx->document_written) { + av_log(ctx, AV_LOG_ERROR, + "Attempting to write multiple TTML documents into a " + "single document! The XML specification forbids this " + "as there has to be a single root tag.\n"); + return AVERROR(EINVAL); + } + avio_write(pb, pkt->data, pkt->size); + ttml_ctx->document_written = 1; + break; + default: + av_log(ctx, AV_LOG_ERROR, + "Internal error: invalid TTML input packet type: %d!\n", + ttml_ctx->input_type); + return AVERROR_BUG; + } + + return 0; +} + +static int ttml_write_trailer(AVFormatContext *ctx) +{ + TTMLMuxContext *ttml_ctx = ctx->priv_data; + AVIOContext *pb = ctx->pb; + + if (ttml_ctx->input_type == PACKET_TYPE_PARAGRAPH) + avio_printf(pb, ttml_footer_text); + + return 0; +} + +AVOutputFormat ff_ttml_muxer = { + .name = "ttml", + .long_name = NULL_IF_CONFIG_SMALL("TTML subtitle"), + .extensions = "ttml", + .mime_type = "text/ttml", + .priv_data_size = sizeof(TTMLMuxContext), + .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | + AVFMT_TS_NONSTRICT, + .subtitle_codec = AV_CODEC_ID_TTML, + .write_header = ttml_write_header, + .write_packet = ttml_write_packet, + .write_trailer = ttml_write_trailer, +}; diff --git a/libavformat/ty.c b/libavformat/ty.c index 738a22e7d..c8e1067c0 100644 --- a/libavformat/ty.c +++ b/libavformat/ty.c @@ -72,11 +72,6 @@ typedef enum { TIVO_AUDIO_MPEG } TiVo_audio; -typedef struct TySeqTable { - uint64_t timestamp; - uint8_t chunk_bitmask[8]; -} TySeqTable; - typedef struct TYDemuxContext { unsigned cur_chunk; unsigned cur_chunk_pos; @@ -90,7 +85,6 @@ typedef struct TYDemuxContext { int pes_buf_cnt; /* how many bytes in our buffer */ size_t ac3_pkt_size; /* length of ac3 pkt we've seen so far */ uint64_t last_ty_pts; /* last TY timestamp we've seen */ - unsigned seq_table_size; /* number of entries in SEQ table */ int64_t first_audio_pts; int64_t last_audio_pts; @@ -99,8 +93,6 @@ typedef struct TYDemuxContext { TyRecHdr *rec_hdrs; /* record headers array */ int cur_rec; /* current record in this chunk */ int num_recs; /* number of recs in this chunk */ - int seq_rec; /* record number where seq start is */ - TySeqTable *seq_table; /* table of SEQ entries from mstr chk */ int first_chunk; uint8_t chunk[CHUNK_SIZE]; @@ -339,58 +331,6 @@ static int ty_read_header(AVFormatContext *s) return 0; } -/* parse a master chunk, filling the SEQ table and other variables. - * We assume the stream is currently pointing to it. - */ -static void parse_master(AVFormatContext *s) -{ - TYDemuxContext *ty = s->priv_data; - unsigned map_size; /* size of bitmask, in bytes */ - unsigned i, j; - - /* Note that the entries in the SEQ table in the stream may have - different sizes depending on the bits per entry. We store them - all in the same size structure, so we have to parse them out one - by one. If we had a dynamic structure, we could simply read the - entire table directly from the stream into memory in place. */ - - /* clear the SEQ table */ - av_freep(&ty->seq_table); - - /* parse header info */ - - map_size = AV_RB32(ty->chunk + 20); /* size of bitmask, in bytes */ - i = AV_RB32(ty->chunk + 28); /* size of SEQ table, in bytes */ - - ty->seq_table_size = i / (8LL + map_size); - - if (ty->seq_table_size == 0) { - ty->seq_table = NULL; - return; - } - - /* parse all the entries */ - ty->seq_table = av_calloc(ty->seq_table_size, sizeof(TySeqTable)); - if (ty->seq_table == NULL) { - ty->seq_table_size = 0; - return; - } - - ty->cur_chunk_pos = 32; - for (j = 0; j < ty->seq_table_size; j++) { - if (ty->cur_chunk_pos >= CHUNK_SIZE - 8) - return; - ty->seq_table[j].timestamp = AV_RB64(ty->chunk + ty->cur_chunk_pos); - ty->cur_chunk_pos += 8; - if (map_size > 8) { - av_log(s, AV_LOG_ERROR, "Unsupported SEQ bitmap size in master chunk.\n"); - ty->cur_chunk_pos += map_size; - } else { - memcpy(ty->seq_table[j].chunk_bitmask, ty->chunk + ty->cur_chunk_pos, map_size); - } - } -} - static int get_chunk(AVFormatContext *s) { TYDemuxContext *ty = s->priv_data; @@ -413,7 +353,7 @@ static int get_chunk(AVFormatContext *s) /* check if it's a PART Header */ if (AV_RB32(ty->chunk) == TIVO_PES_FILEID) { - parse_master(s); /* parse master chunk */ + /* skip master chunk and read new chunk */ return get_chunk(s); } @@ -421,14 +361,9 @@ static int get_chunk(AVFormatContext *s) if (ty->chunk[3] & 0x80) { /* 16 bit rec cnt */ ty->num_recs = num_recs = (ty->chunk[1] << 8) + ty->chunk[0]; - ty->seq_rec = (ty->chunk[3] << 8) + ty->chunk[2]; - if (ty->seq_rec != 0xffff) { - ty->seq_rec &= ~0x8000; - } } else { /* 8 bit reclen - TiVo 1.3 format */ ty->num_recs = num_recs = ty->chunk[0]; - ty->seq_rec = ty->chunk[1]; } ty->cur_rec = 0; ty->first_chunk = 0; @@ -770,7 +705,6 @@ static int ty_read_close(AVFormatContext *s) { TYDemuxContext *ty = s->priv_data; - av_freep(&ty->seq_table); av_freep(&ty->rec_hdrs); return 0; diff --git a/libavformat/udp.c b/libavformat/udp.c index ad6992c57..9b9d3de19 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -138,7 +138,7 @@ static const AVOption options[] = { { "connect", "set if connect() should be called on socket", OFFSET(is_connected), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, { "fifo_size", "set the UDP receiving circular buffer size, expressed as a number of packets with size of 188 bytes", OFFSET(circular_buffer_size), AV_OPT_TYPE_INT, {.i64 = 7*4096}, 0, INT_MAX, D }, { "overrun_nonfatal", "survive in case of UDP receiving circular buffer overrun", OFFSET(overrun_nonfatal), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, D }, - { "timeout", "set raise error timeout (only in read mode)", OFFSET(timeout), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D }, + { "timeout", "set raise error timeout, in microseconds (only in read mode)",OFFSET(timeout), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D }, { "sources", "Source list", OFFSET(sources), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, { "block", "Block list", OFFSET(block), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, { NULL } @@ -165,7 +165,7 @@ static int udp_set_multicast_ttl(int sockfd, int mcastTTL, if (addr->sa_family == AF_INET) { if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) { ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL)"); - return -1; + return ff_neterrno(); } } #endif @@ -173,7 +173,7 @@ static int udp_set_multicast_ttl(int sockfd, int mcastTTL, if (addr->sa_family == AF_INET6) { if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) { ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS)"); - return -1; + return ff_neterrno(); } } #endif @@ -190,10 +190,10 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr,struct soc if (local_addr) mreq.imr_interface= ((struct sockaddr_in *)local_addr)->sin_addr; else - mreq.imr_interface.s_addr= INADDR_ANY; + mreq.imr_interface.s_addr = INADDR_ANY; if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP)"); - return -1; + return ff_neterrno(); } } #endif @@ -203,10 +203,10 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr,struct soc memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); //TODO: Interface index should be looked up from local_addr - mreq6.ipv6mr_interface= 0; + mreq6.ipv6mr_interface = 0; if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)"); - return -1; + return ff_neterrno(); } } #endif @@ -221,9 +221,9 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr,struct so mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; if (local_addr) - mreq.imr_interface= ((struct sockaddr_in *)local_addr)->sin_addr; + mreq.imr_interface = ((struct sockaddr_in *)local_addr)->sin_addr; else - mreq.imr_interface.s_addr= INADDR_ANY; + mreq.imr_interface.s_addr = INADDR_ANY; if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP)"); return -1; @@ -236,7 +236,7 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr,struct so memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); //TODO: Interface index should be looked up from local_addr - mreq6.ipv6mr_interface= 0; + mreq6.ipv6mr_interface = 0; if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP)"); return -1; @@ -295,9 +295,9 @@ static int udp_set_multicast_sources(URLContext *h, mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; if (local_addr) - mreqs.imr_interface= ((struct sockaddr_in *)local_addr)->sin_addr; + mreqs.imr_interface = ((struct sockaddr_in *)local_addr)->sin_addr; else - mreqs.imr_interface.s_addr= INADDR_ANY; + mreqs.imr_interface.s_addr = INADDR_ANY; mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)&sources[i])->sin_addr.s_addr; if (setsockopt(sockfd, IPPROTO_IP, @@ -545,7 +545,7 @@ static void *circular_buffer_task_tx( void *_URLContext) uint8_t tmp[4]; int64_t timestamp; - len=av_fifo_size(s->fifo); + len = av_fifo_size(s->fifo); while (len<4) { if (s->close_req) @@ -553,11 +553,11 @@ static void *circular_buffer_task_tx( void *_URLContext) if (pthread_cond_wait(&s->cond, &s->mutex) < 0) { goto end; } - len=av_fifo_size(s->fifo); + len = av_fifo_size(s->fifo); } av_fifo_generic_read(s->fifo, tmp, 4, NULL); - len=AV_RL32(tmp); + len = AV_RL32(tmp); av_assert0(len >= 0); av_assert0(len <= sizeof(s->tmp)); @@ -633,6 +633,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) char buf[256]; struct sockaddr_storage my_addr; socklen_t len; + int ret; h->is_streamed = 1; @@ -641,18 +642,15 @@ static int udp_open(URLContext *h, const char *uri, int flags) s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_RX_BUF_SIZE; if (s->sources) { - if (ff_ip_parse_sources(h, s->sources, &s->filters) < 0) + if ((ret = ff_ip_parse_sources(h, s->sources, &s->filters)) < 0) goto fail; } if (s->block) { - if (ff_ip_parse_blocks(h, s->block, &s->filters) < 0) + if ((ret = ff_ip_parse_blocks(h, s->block, &s->filters)) < 0) goto fail; } - if (s->pkt_size > 0) - h->max_packet_size = s->pkt_size; - p = strchr(uri, '?'); if (p) { if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) { @@ -715,11 +713,11 @@ static int udp_open(URLContext *h, const char *uri, int flags) av_strlcpy(localaddr, buf, sizeof(localaddr)); } if (av_find_info_tag(buf, sizeof(buf), "sources", p)) { - if (ff_ip_parse_sources(h, buf, &s->filters) < 0) + if ((ret = ff_ip_parse_sources(h, buf, &s->filters)) < 0) goto fail; } if (av_find_info_tag(buf, sizeof(buf), "block", p)) { - if (ff_ip_parse_blocks(h, buf, &s->filters) < 0) + if ((ret = ff_ip_parse_blocks(h, buf, &s->filters)) < 0) goto fail; } if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p)) @@ -745,7 +743,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (!(flags & AVIO_FLAG_READ)) goto fail; } else { - if (ff_udp_set_remote_url(h, uri) < 0) + if ((ret = ff_udp_set_remote_url(h, uri)) < 0) goto fail; } @@ -766,15 +764,22 @@ static int udp_open(URLContext *h, const char *uri, int flags) */ if (s->reuse_socket > 0 || (s->is_multicast && s->reuse_socket < 0)) { s->reuse_socket = 1; - if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0) + if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0) { + ret = ff_neterrno(); goto fail; + } } if (s->is_broadcast) { #ifdef SO_BROADCAST - if (setsockopt (udp_fd, SOL_SOCKET, SO_BROADCAST, &(s->is_broadcast), sizeof(s->is_broadcast)) != 0) + if (setsockopt (udp_fd, SOL_SOCKET, SO_BROADCAST, &(s->is_broadcast), sizeof(s->is_broadcast)) != 0) { + ret = ff_neterrno(); + goto fail; + } +#else + ret = AVERROR(ENOSYS); + goto fail; #endif - goto fail; } /* Set the checksum coverage for UDP-Lite (RFC 3828) for sending and receiving. @@ -791,8 +796,10 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (dscp >= 0) { dscp <<= 2; - if (setsockopt (udp_fd, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) != 0) + if (setsockopt (udp_fd, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) != 0) { + ret = ff_neterrno(); goto fail; + } } /* If multicast, try binding the multicast address first, to avoid @@ -807,6 +814,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) /* the bind is needed to give a port to the socket now */ if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) { ff_log_net_error(h, AV_LOG_ERROR, "bind failed"); + ret = ff_neterrno(); goto fail; } @@ -817,28 +825,28 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (s->is_multicast) { if (h->flags & AVIO_FLAG_WRITE) { /* output */ - if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0) + if ((ret = udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr)) < 0) goto fail; } if (h->flags & AVIO_FLAG_READ) { /* input */ if (s->filters.nb_include_addrs) { - if (udp_set_multicast_sources(h, udp_fd, + if ((ret = udp_set_multicast_sources(h, udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, &s->local_addr_storage, s->filters.include_addrs, - s->filters.nb_include_addrs, 1) < 0) + s->filters.nb_include_addrs, 1)) < 0) goto fail; } else { - if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr,(struct sockaddr *)&s->local_addr_storage) < 0) + if ((ret = udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr,(struct sockaddr *)&s->local_addr_storage)) < 0) goto fail; } if (s->filters.nb_exclude_addrs) { - if (udp_set_multicast_sources(h, udp_fd, + if ((ret = udp_set_multicast_sources(h, udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, &s->local_addr_storage, s->filters.exclude_addrs, - s->filters.nb_exclude_addrs, 0) < 0) + s->filters.nb_exclude_addrs, 0)) < 0) goto fail; } } @@ -849,10 +857,11 @@ static int udp_open(URLContext *h, const char *uri, int flags) tmp = s->buffer_size; if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { ff_log_net_error(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF)"); + ret = ff_neterrno(); goto fail; } } else { - /* set udp recv buffer size to the requested value (default 64K) */ + /* set udp recv buffer size to the requested value (default UDP_RX_BUF_SIZE) */ tmp = s->buffer_size; if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) { ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF)"); @@ -872,6 +881,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (s->is_connected) { if (connect(udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) { ff_log_net_error(h, AV_LOG_ERROR, "connect"); + ret = ff_neterrno(); goto fail; } } @@ -891,23 +901,28 @@ static int udp_open(URLContext *h, const char *uri, int flags) } if ((!is_output && s->circular_buffer_size) || (is_output && s->bitrate && s->circular_buffer_size)) { - int ret; - /* start the task going */ s->fifo = av_fifo_alloc(s->circular_buffer_size); + if (!s->fifo) { + ret = AVERROR(ENOMEM); + goto fail; + } ret = pthread_mutex_init(&s->mutex, NULL); if (ret != 0) { av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", strerror(ret)); + ret = AVERROR(ret); goto fail; } ret = pthread_cond_init(&s->cond, NULL); if (ret != 0) { av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", strerror(ret)); + ret = AVERROR(ret); goto cond_fail; } ret = pthread_create(&s->circular_buffer_thread, NULL, is_output?circular_buffer_task_tx:circular_buffer_task_rx, h); if (ret != 0) { av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", strerror(ret)); + ret = AVERROR(ret); goto thread_fail; } s->thread_started = 1; @@ -926,7 +941,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) closesocket(udp_fd); av_fifo_freep(&s->fifo); ff_ip_reset_filters(&s->filters); - return AVERROR(EIO); + return ret; } static int udplite_open(URLContext *h, const char *uri, int flags) @@ -956,10 +971,10 @@ static int udp_read(URLContext *h, uint8_t *buf, int size) uint8_t tmp[4]; av_fifo_generic_read(s->fifo, tmp, 4, NULL); - avail= AV_RL32(tmp); + avail = AV_RL32(tmp); if(avail > size){ av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n"); - avail= size; + avail = size; } av_fifo_generic_read(s->fifo, buf, avail, NULL); @@ -973,8 +988,7 @@ static int udp_read(URLContext *h, uint8_t *buf, int size) } else if(nonblock) { pthread_mutex_unlock(&s->mutex); return AVERROR(EAGAIN); - } - else { + } else { /* FIXME: using the monotonic clock would be better, but it does not exist on all supported platforms. */ int64_t t = av_gettime() + 100000; @@ -987,7 +1001,7 @@ static int udp_read(URLContext *h, uint8_t *buf, int size) } nonblock = 1; } - } while( 1); + } while(1); } #endif @@ -1020,7 +1034,7 @@ static int udp_write(URLContext *h, const uint8_t *buf, int size) Here we can't know on which packet error was, but it needs to know that error exists. */ if (s->circular_buffer_error<0) { - int err=s->circular_buffer_error; + int err = s->circular_buffer_error; pthread_mutex_unlock(&s->mutex); return err; } diff --git a/libavformat/url.c b/libavformat/url.c index 77d610d95..f53fdf59d 100644 --- a/libavformat/url.c +++ b/libavformat/url.c @@ -149,6 +149,18 @@ int ff_url_decompose(URLComponents *uc, const char *url, const char *end) return 0; } +static int is_fq_dos_path(const char *path) +{ + if ((path[0] >= 'a' && path[0] <= 'z' || path[0] >= 'A' && path[0] <= 'Z') && + path[1] == ':' && + (path[2] == '/' || path[2] == '\\')) + return 1; + if ((path[0] == '/' || path[0] == '\\') && + (path[1] == '/' || path[1] == '\\')) + return 1; + return 0; +} + static int append_path(char *root, char *out_end, char **rout, const char *in, const char *in_end) { @@ -178,13 +190,14 @@ static int append_path(char *root, char *out_end, char **rout, return 0; } -int ff_make_absolute_url(char *buf, int size, const char *base, - const char *rel) +int ff_make_absolute_url2(char *buf, int size, const char *base, + const char *rel, int handle_dos_paths) { URLComponents ub, uc; char *out, *out_end, *path; const char *keep, *base_path_end; int use_base_path, simplify_path = 0, ret; + const char *base_separators = "/"; /* This is tricky. For HTTP, http://server/site/page + ../media/file @@ -211,6 +224,15 @@ int ff_make_absolute_url(char *buf, int size, const char *base, if (!base) base = ""; + if (handle_dos_paths) { + if ((ret = ff_url_decompose(&ub, base, NULL)) < 0) + goto error; + if (is_fq_dos_path(base) || av_strstart(base, "file:", NULL) || ub.path == ub.url) { + base_separators = "/\\"; + if (is_fq_dos_path(rel)) + base = ""; + } + } if ((ret = ff_url_decompose(&ub, base, NULL)) < 0 || (ret = ff_url_decompose(&uc, rel, NULL)) < 0) goto error; @@ -249,7 +271,7 @@ int ff_make_absolute_url(char *buf, int size, const char *base, if (use_base_path) { base_path_end = ub.url_component_end_path; if (URL_COMPONENT_HAVE(uc, path)) - while (base_path_end > ub.path && base_path_end[-1] != '/') + while (base_path_end > ub.path && !strchr(base_separators, base_path_end[-1])) base_path_end--; } if (keep > ub.path) @@ -294,6 +316,12 @@ error: return ret; } +int ff_make_absolute_url(char *buf, int size, const char *base, + const char *rel) +{ + return ff_make_absolute_url2(buf, size, base, rel, HAVE_DOS_PATHS); +} + AVIODirEntry *ff_alloc_dir_entry(void) { AVIODirEntry *entry = av_mallocz(sizeof(AVIODirEntry)); diff --git a/libavformat/url.h b/libavformat/url.h index 728a861bd..3bb1cf89f 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -56,8 +56,8 @@ typedef struct URLProtocol { int (*url_open)( URLContext *h, const char *url, int flags); /** * This callback is to be used by protocols which open further nested - * protocols. options are then to be passed to ffurl_open()/ffurl_connect() - * for those nested protocols. + * protocols. options are then to be passed to ffurl_open_whitelist() + * or ffurl_connect() for those nested protocols. */ int (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options); int (*url_accept)(URLContext *s, URLContext **c); @@ -87,8 +87,8 @@ typedef struct URLProtocol { int *numhandles); int (*url_get_short_seek)(URLContext *h); int (*url_shutdown)(URLContext *h, int flags); - int priv_data_size; const AVClass *priv_data_class; + int priv_data_size; int flags; int (*url_check)(URLContext *h, int mask); int (*url_open_dir)(URLContext *h); @@ -148,9 +148,6 @@ int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const char *whitelist, const char* blacklist, URLContext *parent); -int ffurl_open(URLContext **puc, const char *filename, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options); - /** * Accept an URLContext c on an URLContext s * @@ -311,6 +308,16 @@ int ff_url_join(char *str, int size, const char *proto, * @param size the size of buf * @param base the base url, may be equal to buf. * @param rel the new url, which is interpreted relative to base + * @param handle_dos_paths handle DOS paths for file or unspecified protocol + */ +int ff_make_absolute_url2(char *buf, int size, const char *base, + const char *rel, int handle_dos_paths); + +/** + * Convert a relative url into an absolute url, given a base url. + * + * Same as ff_make_absolute_url2 with handle_dos_paths being equal to + * HAVE_DOS_PATHS config variable. */ int ff_make_absolute_url(char *buf, int size, const char *base, const char *rel); @@ -322,7 +329,11 @@ int ff_make_absolute_url(char *buf, int size, const char *base, */ AVIODirEntry *ff_alloc_dir_entry(void); +#if FF_API_CHILD_CLASS_NEXT const AVClass *ff_urlcontext_child_class_next(const AVClass *prev); +#endif + +const AVClass *ff_urlcontext_child_class_iterate(void **iter); /** * Construct a list of protocols matching a given whitelist and/or blacklist. diff --git a/libavformat/utils.c b/libavformat/utils.c index 7185fbfd7..1384b5677 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -37,6 +37,7 @@ #include "libavcodec/bytestream.h" #include "libavcodec/internal.h" +#include "libavcodec/packet_internal.h" #include "libavcodec/raw.h" #include "avformat.h" @@ -100,13 +101,13 @@ static int is_relative(int64_t ts) { */ static int64_t wrap_timestamp(const AVStream *st, int64_t timestamp) { - if (st->pts_wrap_behavior != AV_PTS_WRAP_IGNORE && - st->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) { - if (st->pts_wrap_behavior == AV_PTS_WRAP_ADD_OFFSET && - timestamp < st->pts_wrap_reference) + if (st->internal->pts_wrap_behavior != AV_PTS_WRAP_IGNORE && st->pts_wrap_bits < 64 && + st->internal->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) { + if (st->internal->pts_wrap_behavior == AV_PTS_WRAP_ADD_OFFSET && + timestamp < st->internal->pts_wrap_reference) return timestamp + (1ULL << st->pts_wrap_bits); - else if (st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET && - timestamp >= st->pts_wrap_reference) + else if (st->internal->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET && + timestamp >= st->internal->pts_wrap_reference) return timestamp - (1ULL << st->pts_wrap_bits); } return timestamp; @@ -152,7 +153,7 @@ void av_format_inject_global_side_data(AVFormatContext *s) s->internal->inject_global_side_data = 1; for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - st->inject_global_side_data = 1; + st->internal->inject_global_side_data = 1; } } @@ -255,9 +256,11 @@ int ffio_limit(AVIOContext *s, int size) remaining = s->maxsize - pos; } - if (s->maxsize>= 0 && remaining+1 < size) { - av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG, "Truncating packet of size %d to %"PRId64"\n", size, remaining+1); - size = remaining+1; + if (s->maxsize >= 0 && remaining < size && size > 1) { + av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG, + "Truncating packet of size %d to %"PRId64"\n", + size, remaining + !remaining); + size = remaining + !remaining; } } return size; @@ -306,9 +309,15 @@ static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size) int av_get_packet(AVIOContext *s, AVPacket *pkt, int size) { +#if FF_API_INIT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS av_init_packet(pkt); pkt->data = NULL; pkt->size = 0; +FF_ENABLE_DEPRECATION_WARNINGS +#else + av_packet_unref(pkt); +#endif pkt->pos = avio_tell(s); return append_packet_chunked(s, pkt, size); @@ -367,7 +376,7 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, if (fmt_id_type[i].type != AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate) continue; - if (st->request_probe > score && + if (st->internal->request_probe > score && st->codecpar->codec_id != fmt_id_type[i].id) continue; st->codecpar->codec_id = fmt_id_type[i].id; @@ -389,6 +398,7 @@ FF_ENABLE_DEPRECATION_WARNINGS /************************************************************/ /* input media file */ +#if FF_API_DEMUXER_OPEN int av_demuxer_open(AVFormatContext *ic) { int err; @@ -408,7 +418,7 @@ int av_demuxer_open(AVFormatContext *ic) { return 0; } - +#endif /* Open input file and probe the format if necessary. */ static int init_input(AVFormatContext *s, const char *filename, AVDictionary **options) @@ -441,40 +451,6 @@ static int init_input(AVFormatContext *s, const char *filename, s, 0, s->format_probesize); } -int ff_packet_list_put(AVPacketList **packet_buffer, - AVPacketList **plast_pktl, - AVPacket *pkt, int flags) -{ - AVPacketList *pktl = av_mallocz(sizeof(AVPacketList)); - int ret; - - if (!pktl) - return AVERROR(ENOMEM); - - if (flags & FF_PACKETLIST_FLAG_REF_PACKET) { - if ((ret = av_packet_ref(&pktl->pkt, pkt)) < 0) { - av_free(pktl); - return ret; - } - } else { - ret = av_packet_make_refcounted(pkt); - if (ret < 0) { - av_free(pktl); - return ret; - } - av_packet_move_ref(&pktl->pkt, pkt); - } - - if (*packet_buffer) - (*plast_pktl)->next = pktl; - else - *packet_buffer = pktl; - - /* Add the packet in the buffered packet list. */ - *plast_pktl = pktl; - return 0; -} - int avformat_queue_attached_pictures(AVFormatContext *s) { int i, ret; @@ -488,10 +464,10 @@ int avformat_queue_attached_pictures(AVFormatContext *s) continue; } - ret = ff_packet_list_put(&s->internal->raw_packet_buffer, + ret = avpriv_packet_list_put(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end, &s->streams[i]->attached_pic, - FF_PACKETLIST_FLAG_REF_PACKET); + av_packet_ref, 0); if (ret < 0) return ret; } @@ -625,8 +601,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if (s->pb) ff_id3v2_read_dict(s->pb, &s->internal->id3v2_meta, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); - +#if FF_API_DEMUXER_OPEN if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header) +#else + if (s->iformat->read_header) +#endif if ((ret = s->iformat->read_header(s)) < 0) goto fail; @@ -655,7 +634,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if ((ret = avformat_queue_attached_pictures(s)) < 0) goto close; +#if FF_API_DEMUXER_OPEN if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->internal->data_offset) +#else + if (s->pb && !s->internal->data_offset) +#endif s->internal->data_offset = avio_tell(s->pb); s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; @@ -711,8 +694,8 @@ static void force_codec_ids(AVFormatContext *s, AVStream *st) static int probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt) { - if (st->request_probe>0) { - AVProbeData *pd = &st->probe_data; + if (st->internal->request_probe>0) { + AVProbeData *pd = &st->internal->probe_data; int end; av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets); --st->probe_packets; @@ -747,7 +730,7 @@ no_packet: || end) { pd->buf_size = 0; av_freep(&pd->buf); - st->request_probe = -1; + st->internal->request_probe = -1; if (st->codecpar->codec_id != AV_CODEC_ID_NONE) { av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index); } else @@ -768,7 +751,7 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in if (ref == AV_NOPTS_VALUE) ref = pkt->pts; - if (st->pts_wrap_reference != AV_NOPTS_VALUE || st->pts_wrap_bits >= 63 || ref == AV_NOPTS_VALUE || !s->correct_ts_overflow) + if (st->internal->pts_wrap_reference != AV_NOPTS_VALUE || st->pts_wrap_bits >= 63 || ref == AV_NOPTS_VALUE || !s->correct_ts_overflow) return 0; ref &= (1LL << st->pts_wrap_bits)-1; @@ -783,17 +766,17 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in if (!first_program) { int default_stream_index = av_find_default_stream_index(s); - if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) { + if (s->streams[default_stream_index]->internal->pts_wrap_reference == AV_NOPTS_VALUE) { for (i = 0; i < s->nb_streams; i++) { if (av_find_program_from_stream(s, NULL, i)) continue; - s->streams[i]->pts_wrap_reference = pts_wrap_reference; - s->streams[i]->pts_wrap_behavior = pts_wrap_behavior; + s->streams[i]->internal->pts_wrap_reference = pts_wrap_reference; + s->streams[i]->internal->pts_wrap_behavior = pts_wrap_behavior; } } else { - st->pts_wrap_reference = s->streams[default_stream_index]->pts_wrap_reference; - st->pts_wrap_behavior = s->streams[default_stream_index]->pts_wrap_behavior; + st->internal->pts_wrap_reference = s->streams[default_stream_index]->internal->pts_wrap_reference; + st->internal->pts_wrap_behavior = s->streams[default_stream_index]->internal->pts_wrap_behavior; } } else { @@ -812,8 +795,8 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in while (program) { if (program->pts_wrap_reference != pts_wrap_reference) { for (i = 0; inb_stream_indexes; i++) { - s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; - s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; + s->streams[program->stream_index[i]]->internal->pts_wrap_reference = pts_wrap_reference; + s->streams[program->stream_index[i]]->internal->pts_wrap_behavior = pts_wrap_behavior; } program->pts_wrap_reference = pts_wrap_reference; @@ -830,12 +813,18 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) int ret, i, err; AVStream *st; +#if FF_API_INIT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS pkt->data = NULL; pkt->size = 0; av_init_packet(pkt); +FF_ENABLE_DEPRECATION_WARNINGS +#else + av_packet_unref(pkt); +#endif for (;;) { - AVPacketList *pktl = s->internal->raw_packet_buffer; + PacketList *pktl = s->internal->raw_packet_buffer; const AVPacket *pkt1; if (pktl) { @@ -843,8 +832,8 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) if (s->internal->raw_packet_buffer_remaining_size <= 0) if ((err = probe_codec(s, st, NULL)) < 0) return err; - if (st->request_probe <= 0) { - ff_packet_list_get(&s->internal->raw_packet_buffer, + if (st->internal->request_probe <= 0) { + avpriv_packet_list_get(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end, pkt); s->internal->raw_packet_buffer_remaining_size += pkt->size; return 0; @@ -864,10 +853,10 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) return ret; for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; - if (st->probe_packets || st->request_probe > 0) + if (st->probe_packets || st->internal->request_probe > 0) if ((err = probe_codec(s, st, NULL)) < 0) return err; - av_assert0(st->request_probe <= 0); + av_assert0(st->internal->request_probe <= 0); } continue; } @@ -895,7 +884,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) st = s->streams[pkt->stream_index]; - if (update_wrap_reference(s, st, pkt->stream_index, pkt) && st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) { + if (update_wrap_reference(s, st, pkt->stream_index, pkt) && st->internal->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) { // correct first time stamps to negative values if (!is_relative(st->first_dts)) st->first_dts = wrap_timestamp(st, st->first_dts); @@ -914,12 +903,12 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) if (s->use_wallclock_as_timestamps) pkt->dts = pkt->pts = av_rescale_q(av_gettime(), AV_TIME_BASE_Q, st->time_base); - if (!pktl && st->request_probe <= 0) + if (!pktl && st->internal->request_probe <= 0) return ret; - err = ff_packet_list_put(&s->internal->raw_packet_buffer, + err = avpriv_packet_list_put(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end, - pkt, 0); + pkt, NULL, 0); if (err < 0) { av_packet_unref(pkt); return err; @@ -1028,7 +1017,7 @@ int ff_is_intra_only(enum AVCodecID id) static int has_decode_delay_been_guessed(AVStream *st) { if (st->codecpar->codec_id != AV_CODEC_ID_H264) return 1; - if (!st->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy + if (!st->internal->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy return 1; #if CONFIG_H264_DECODER if (st->internal->avctx->has_b_frames && @@ -1036,14 +1025,14 @@ static int has_decode_delay_been_guessed(AVStream *st) return 1; #endif if (st->internal->avctx->has_b_frames<3) - return st->nb_decoded_frames >= 7; + return st->internal->nb_decoded_frames >= 7; else if (st->internal->avctx->has_b_frames<4) - return st->nb_decoded_frames >= 18; + return st->internal->nb_decoded_frames >= 18; else - return st->nb_decoded_frames >= 20; + return st->internal->nb_decoded_frames >= 20; } -static AVPacketList *get_next_pkt(AVFormatContext *s, AVStream *st, AVPacketList *pktl) +static PacketList *get_next_pkt(AVFormatContext *s, AVStream *st, PacketList *pktl) { if (pktl->next) return pktl->next; @@ -1063,8 +1052,8 @@ static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t if (dts == AV_NOPTS_VALUE) { int64_t best_score = INT64_MAX; for (i = 0; ipts_reorder_error_count[i]) { - int64_t score = st->pts_reorder_error[i] / st->pts_reorder_error_count[i]; + if (st->internal->pts_reorder_error_count[i]) { + int64_t score = st->internal->pts_reorder_error[i] / st->internal->pts_reorder_error_count[i]; if (score < best_score) { best_score = score; dts = pts_buffer[i]; @@ -1075,13 +1064,13 @@ static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t for (i = 0; ipts_reorder_error[i]; - diff = FFMAX(diff, st->pts_reorder_error[i]); - st->pts_reorder_error[i] = diff; - st->pts_reorder_error_count[i]++; - if (st->pts_reorder_error_count[i] > 250) { - st->pts_reorder_error[i] >>= 1; - st->pts_reorder_error_count[i] >>= 1; + + (uint64_t)st->internal->pts_reorder_error[i]; + diff = FFMAX(diff, st->internal->pts_reorder_error[i]); + st->internal->pts_reorder_error[i] = diff; + st->internal->pts_reorder_error_count[i]++; + if (st->internal->pts_reorder_error_count[i] > 250) { + st->internal->pts_reorder_error[i] >>= 1; + st->internal->pts_reorder_error_count[i] >>= 1; } } } @@ -1099,7 +1088,7 @@ static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t * of the packets in a window. */ static void update_dts_from_pts(AVFormatContext *s, int stream_index, - AVPacketList *pkt_buffer) + PacketList *pkt_buffer) { AVStream *st = s->streams[stream_index]; int delay = st->internal->avctx->has_b_frames; @@ -1128,8 +1117,8 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, int64_t dts, int64_t pts, AVPacket *pkt) { AVStream *st = s->streams[stream_index]; - AVPacketList *pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue; - AVPacketList *pktl_it; + PacketList *pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue; + PacketList *pktl_it; uint64_t shift; @@ -1160,7 +1149,7 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, if (st->start_time == AV_NOPTS_VALUE && pktl_it->pkt.pts != AV_NOPTS_VALUE) { st->start_time = pktl_it->pkt.pts; if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate) - st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base)); + st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->internal->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base)); } } @@ -1173,20 +1162,20 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, st->start_time = pts; } if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate) - st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base)); + st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->internal->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base)); } } static void update_initial_durations(AVFormatContext *s, AVStream *st, int stream_index, int64_t duration) { - AVPacketList *pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue; + PacketList *pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue; int64_t cur_dts = RELATIVE_TS_BASE; if (st->first_dts != AV_NOPTS_VALUE) { - if (st->update_initial_durations_done) + if (st->internal->update_initial_durations_done) return; - st->update_initial_durations_done = 1; + st->internal->update_initial_durations_done = 1; cur_dts = st->first_dts; for (; pktl; pktl = get_next_pkt(s, st, pktl)) { if (pktl->pkt.stream_index == stream_index) { @@ -1223,8 +1212,7 @@ static void update_initial_durations(AVFormatContext *s, AVStream *st, pktl->pkt.dts = cur_dts; if (!st->internal->avctx->has_b_frames) pktl->pkt.pts = cur_dts; -// if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) - pktl->pkt.duration = duration; + pktl->pkt.duration = duration; } else break; cur_dts = pktl->pkt.dts + pktl->pkt.duration; @@ -1247,24 +1235,24 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, return; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && pkt->dts != AV_NOPTS_VALUE) { - if (pkt->dts == pkt->pts && st->last_dts_for_order_check != AV_NOPTS_VALUE) { - if (st->last_dts_for_order_check <= pkt->dts) { - st->dts_ordered++; + if (pkt->dts == pkt->pts && st->internal->last_dts_for_order_check != AV_NOPTS_VALUE) { + if (st->internal->last_dts_for_order_check <= pkt->dts) { + st->internal->dts_ordered++; } else { - av_log(s, st->dts_misordered ? AV_LOG_DEBUG : AV_LOG_WARNING, + av_log(s, st->internal->dts_misordered ? AV_LOG_DEBUG : AV_LOG_WARNING, "DTS %"PRIi64" < %"PRIi64" out of order\n", pkt->dts, - st->last_dts_for_order_check); - st->dts_misordered++; + st->internal->last_dts_for_order_check); + st->internal->dts_misordered++; } - if (st->dts_ordered + st->dts_misordered > 250) { - st->dts_ordered >>= 1; - st->dts_misordered >>= 1; + if (st->internal->dts_ordered + st->internal->dts_misordered > 250) { + st->internal->dts_ordered >>= 1; + st->internal->dts_misordered >>= 1; } } - st->last_dts_for_order_check = pkt->dts; - if (st->dts_ordered < 8*st->dts_misordered && pkt->dts == pkt->pts) + st->internal->last_dts_for_order_check = pkt->dts; + if (st->internal->dts_ordered < 8*st->internal->dts_misordered && pkt->dts == pkt->pts) pkt->dts = AV_NOPTS_VALUE; } @@ -1287,7 +1275,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, presentation_delayed = 1; if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && - st->pts_wrap_bits < 63 && pkt->dts > INT64_MIN + (1LL << (st->pts_wrap_bits - 1)) && + st->pts_wrap_bits < 63 && pkt->dts > INT64_MIN + (1LL << st->pts_wrap_bits) && pkt->dts - (1LL << (st->pts_wrap_bits - 1)) > pkt->pts) { if (is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits - 1)) > st->cur_dts) { pkt->dts -= 1LL << st->pts_wrap_bits; @@ -1395,12 +1383,12 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, } if (pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY) { - st->pts_buffer[0] = pkt->pts; - for (i = 0; ipts_buffer[i] > st->pts_buffer[i + 1]; i++) - FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]); + st->internal->pts_buffer[0] = pkt->pts; + for (i = 0; iinternal->pts_buffer[i] > st->internal->pts_buffer[i + 1]; i++) + FFSWAP(int64_t, st->internal->pts_buffer[i], st->internal->pts_buffer[i + 1]); if(has_decode_delay_been_guessed(st)) - pkt->dts = select_from_pts_buffer(st, st->pts_buffer, pkt->dts); + pkt->dts = select_from_pts_buffer(st, st->internal->pts_buffer, pkt->dts); } // We skipped it above so we try here. if (!onein_oneout) @@ -1424,20 +1412,6 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif } -void ff_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end) -{ - AVPacketList *tmp = *pkt_buf; - - while (tmp) { - AVPacketList *pktl = tmp; - tmp = pktl->next; - av_packet_unref(&pktl->pkt); - av_freep(&pktl); - } - *pkt_buf = NULL; - *pkt_buf_end = NULL; -} - /** * Parse a packet, add all split parts to parse_queue. * @@ -1447,14 +1421,14 @@ void ff_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end) static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index, int flush) { - AVPacket out_pkt; + AVPacket *out_pkt = s->internal->parse_pkt; AVStream *st = s->streams[stream_index]; uint8_t *data = pkt->data; int size = pkt->size; int ret = 0, got_output = flush; if (size || flush) { - av_init_packet(&out_pkt); + av_packet_unref(out_pkt); } else if (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) { // preserve 0-size sync packets compute_pkt_fields(s, st, st->parser, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE); @@ -1466,48 +1440,49 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int64_t next_dts = pkt->dts; len = av_parser_parse2(st->parser, st->internal->avctx, - &out_pkt.data, &out_pkt.size, data, size, + &out_pkt->data, &out_pkt->size, data, size, pkt->pts, pkt->dts, pkt->pos); pkt->pts = pkt->dts = AV_NOPTS_VALUE; pkt->pos = -1; /* increment read pointer */ - data += len; + av_assert1(data || !len); + data = len ? data + len : data; size -= len; - got_output = !!out_pkt.size; + got_output = !!out_pkt->size; - if (!out_pkt.size) + if (!out_pkt->size) continue; - if (pkt->buf && out_pkt.data == pkt->data) { - /* reference pkt->buf only when out_pkt.data is guaranteed to point + if (pkt->buf && out_pkt->data == pkt->data) { + /* reference pkt->buf only when out_pkt->data is guaranteed to point * to data in it and not in the parser's internal buffer. */ /* XXX: Ensure this is the case with all parsers when st->parser->flags * is PARSER_FLAG_COMPLETE_FRAMES and check for that instead? */ - out_pkt.buf = av_buffer_ref(pkt->buf); - if (!out_pkt.buf) { + out_pkt->buf = av_buffer_ref(pkt->buf); + if (!out_pkt->buf) { ret = AVERROR(ENOMEM); goto fail; } } else { - ret = av_packet_make_refcounted(&out_pkt); + ret = av_packet_make_refcounted(out_pkt); if (ret < 0) goto fail; } if (pkt->side_data) { - out_pkt.side_data = pkt->side_data; - out_pkt.side_data_elems = pkt->side_data_elems; + out_pkt->side_data = pkt->side_data; + out_pkt->side_data_elems = pkt->side_data_elems; pkt->side_data = NULL; pkt->side_data_elems = 0; } /* set the duration */ - out_pkt.duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0; + out_pkt->duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0; if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { if (st->internal->avctx->sample_rate > 0) { - out_pkt.duration = + out_pkt->duration = av_rescale_q_rnd(st->parser->duration, (AVRational) { 1, st->internal->avctx->sample_rate }, st->time_base, @@ -1515,30 +1490,30 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, } } - out_pkt.stream_index = st->index; - out_pkt.pts = st->parser->pts; - out_pkt.dts = st->parser->dts; - out_pkt.pos = st->parser->pos; - out_pkt.flags |= pkt->flags & AV_PKT_FLAG_DISCARD; + out_pkt->stream_index = st->index; + out_pkt->pts = st->parser->pts; + out_pkt->dts = st->parser->dts; + out_pkt->pos = st->parser->pos; + out_pkt->flags |= pkt->flags & AV_PKT_FLAG_DISCARD; if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) - out_pkt.pos = st->parser->frame_offset; + out_pkt->pos = st->parser->frame_offset; if (st->parser->key_frame == 1 || (st->parser->key_frame == -1 && st->parser->pict_type == AV_PICTURE_TYPE_I)) - out_pkt.flags |= AV_PKT_FLAG_KEY; + out_pkt->flags |= AV_PKT_FLAG_KEY; if (st->parser->key_frame == -1 && st->parser->pict_type ==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY)) - out_pkt.flags |= AV_PKT_FLAG_KEY; + out_pkt->flags |= AV_PKT_FLAG_KEY; - compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts); + compute_pkt_fields(s, st, st->parser, out_pkt, next_dts, next_pts); - ret = ff_packet_list_put(&s->internal->parse_queue, + ret = avpriv_packet_list_put(&s->internal->parse_queue, &s->internal->parse_queue_end, - &out_pkt, 0); + out_pkt, NULL, 0); if (ret < 0) { - av_packet_unref(&out_pkt); + av_packet_unref(out_pkt); goto fail; } } @@ -1554,21 +1529,6 @@ fail: return ret; } -int ff_packet_list_get(AVPacketList **pkt_buffer, - AVPacketList **pkt_buffer_end, - AVPacket *pkt) -{ - AVPacketList *pktl; - av_assert0(*pkt_buffer); - pktl = *pkt_buffer; - *pkt = pktl->pkt; - *pkt_buffer = pktl->next; - if (!pktl->next) - *pkt_buffer_end = NULL; - av_freep(&pktl); - return 0; -} - static int64_t ts_to_samples(AVStream *st, int64_t ts) { return av_rescale(ts, st->time_base.num * st->codecpar->sample_rate, st->time_base.den); @@ -1600,12 +1560,14 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) ret = 0; st = s->streams[pkt->stream_index]; + st->event_flags |= AVSTREAM_EVENT_FLAG_NEW_PACKETS; + /* update context if required */ if (st->internal->need_context_update) { if (avcodec_is_open(st->internal->avctx)) { av_log(s, AV_LOG_DEBUG, "Demuxer context update while decoder is open, closing and trying to re-open\n"); avcodec_close(st->internal->avctx); - st->info->found_decoder = 0; + st->internal->info->found_decoder = 0; } /* close parser, because it depends on the codec */ @@ -1691,41 +1653,41 @@ FF_ENABLE_DEPRECATION_WARNINGS av_packet_unref(pkt); } if (pkt->flags & AV_PKT_FLAG_KEY) - st->skip_to_keyframe = 0; - if (st->skip_to_keyframe) { + st->internal->skip_to_keyframe = 0; + if (st->internal->skip_to_keyframe) { av_packet_unref(pkt); got_packet = 0; } } if (!got_packet && s->internal->parse_queue) - ret = ff_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt); + ret = avpriv_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt); if (ret >= 0) { AVStream *st = s->streams[pkt->stream_index]; int discard_padding = 0; - if (st->first_discard_sample && pkt->pts != AV_NOPTS_VALUE) { + if (st->internal->first_discard_sample && pkt->pts != AV_NOPTS_VALUE) { int64_t pts = pkt->pts - (is_relative(pkt->pts) ? RELATIVE_TS_BASE : 0); int64_t sample = ts_to_samples(st, pts); int duration = ts_to_samples(st, pkt->duration); int64_t end_sample = sample + duration; - if (duration > 0 && end_sample >= st->first_discard_sample && - sample < st->last_discard_sample) - discard_padding = FFMIN(end_sample - st->first_discard_sample, duration); + if (duration > 0 && end_sample >= st->internal->first_discard_sample && + sample < st->internal->last_discard_sample) + discard_padding = FFMIN(end_sample - st->internal->first_discard_sample, duration); } - if (st->start_skip_samples && (pkt->pts == 0 || pkt->pts == RELATIVE_TS_BASE)) - st->skip_samples = st->start_skip_samples; - if (st->skip_samples || discard_padding) { + if (st->internal->start_skip_samples && (pkt->pts == 0 || pkt->pts == RELATIVE_TS_BASE)) + st->internal->skip_samples = st->internal->start_skip_samples; + if (st->internal->skip_samples || discard_padding) { uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10); if (p) { - AV_WL32(p, st->skip_samples); + AV_WL32(p, st->internal->skip_samples); AV_WL32(p + 4, discard_padding); - av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d / discard %d\n", st->skip_samples, discard_padding); + av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d / discard %d\n", st->internal->skip_samples, discard_padding); } - st->skip_samples = 0; + st->internal->skip_samples = 0; } - if (st->inject_global_side_data) { + if (st->internal->inject_global_side_data) { for (i = 0; i < st->nb_side_data; i++) { AVPacketSideData *src_sd = &st->side_data[i]; uint8_t *dst_data; @@ -1741,7 +1703,7 @@ FF_ENABLE_DEPRECATION_WARNINGS memcpy(dst_data, src_sd->data, src_sd->size); } - st->inject_global_side_data = 0; + st->internal->inject_global_side_data = 0; } } @@ -1783,7 +1745,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) if (!genpts) { ret = s->internal->packet_buffer - ? ff_packet_list_get(&s->internal->packet_buffer, + ? avpriv_packet_list_get(&s->internal->packet_buffer, &s->internal->packet_buffer_end, pkt) : read_frame_internal(s, pkt); if (ret < 0) @@ -1792,7 +1754,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) } for (;;) { - AVPacketList *pktl = s->internal->packet_buffer; + PacketList *pktl = s->internal->packet_buffer; if (pktl) { AVPacket *next_pkt = &pktl->pkt; @@ -1832,7 +1794,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) st = s->streams[next_pkt->stream_index]; if (!(next_pkt->pts == AV_NOPTS_VALUE && st->discard < AVDISCARD_ALL && next_pkt->dts != AV_NOPTS_VALUE && !eof)) { - ret = ff_packet_list_get(&s->internal->packet_buffer, + ret = avpriv_packet_list_get(&s->internal->packet_buffer, &s->internal->packet_buffer_end, pkt); goto return_packet; } @@ -1847,9 +1809,9 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) return ret; } - ret = ff_packet_list_put(&s->internal->packet_buffer, + ret = avpriv_packet_list_put(&s->internal->packet_buffer, &s->internal->packet_buffer_end, - pkt, 0); + pkt, NULL, 0); if (ret < 0) { av_packet_unref(pkt); return ret; @@ -1877,9 +1839,9 @@ static void flush_packet_queue(AVFormatContext *s) { if (!s->internal) return; - ff_packet_list_free(&s->internal->parse_queue, &s->internal->parse_queue_end); - ff_packet_list_free(&s->internal->packet_buffer, &s->internal->packet_buffer_end); - ff_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end); + avpriv_packet_list_free(&s->internal->parse_queue, &s->internal->parse_queue_end); + avpriv_packet_list_free(&s->internal->packet_buffer, &s->internal->packet_buffer_end); + avpriv_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end); s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; } @@ -1941,7 +1903,7 @@ void ff_read_frame_flush(AVFormatContext *s) st->parser = NULL; } st->last_IP_pts = AV_NOPTS_VALUE; - st->last_dts_for_order_check = AV_NOPTS_VALUE; + st->internal->last_dts_for_order_check = AV_NOPTS_VALUE; if (st->first_dts == AV_NOPTS_VALUE) st->cur_dts = RELATIVE_TS_BASE; else @@ -1951,12 +1913,12 @@ void ff_read_frame_flush(AVFormatContext *s) st->probe_packets = s->max_probe_packets; for (j = 0; j < MAX_REORDER_DELAY + 1; j++) - st->pts_buffer[j] = AV_NOPTS_VALUE; + st->internal->pts_buffer[j] = AV_NOPTS_VALUE; if (s->internal->inject_global_side_data) - st->inject_global_side_data = 1; + st->internal->inject_global_side_data = 1; - st->skip_samples = 0; + st->internal->skip_samples = 0; } } @@ -2427,7 +2389,7 @@ static int seek_frame_generic(AVFormatContext *s, int stream_index, return -1; if (index < 0 || index == st->nb_index_entries - 1) { - AVPacket pkt; + AVPacket *pkt = s->internal->pkt; int nonkey = 0; if (st->nb_index_entries) { @@ -2440,25 +2402,26 @@ static int seek_frame_generic(AVFormatContext *s, int stream_index, if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0) return ret; } + av_packet_unref(pkt); for (;;) { int read_status; do { - read_status = av_read_frame(s, &pkt); + read_status = av_read_frame(s, pkt); } while (read_status == AVERROR(EAGAIN)); if (read_status < 0) break; - if (stream_index == pkt.stream_index && pkt.dts > timestamp) { - if (pkt.flags & AV_PKT_FLAG_KEY) { - av_packet_unref(&pkt); + if (stream_index == pkt->stream_index && pkt->dts > timestamp) { + if (pkt->flags & AV_PKT_FLAG_KEY) { + av_packet_unref(pkt); break; } if (nonkey++ > 1000 && st->codecpar->codec_id != AV_CODEC_ID_CDGRAPHICS) { av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey); - av_packet_unref(&pkt); + av_packet_unref(pkt); break; } } - av_packet_unref(&pkt); + av_packet_unref(pkt); } index = av_index_search_timestamp(st, timestamp, flags); } @@ -2806,7 +2769,7 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) /* only usable for MPEG-PS streams */ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) { - AVPacket pkt1, *pkt = &pkt1; + AVPacket *pkt = ic->internal->pkt; AVStream *st; int num, den, read_size, i, ret; int found_duration = 0; @@ -2878,10 +2841,10 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) else duration -= st->first_dts; if (duration > 0) { - if (st->duration == AV_NOPTS_VALUE || st->info->last_duration<= 0 || - (st->duration < duration && FFABS(duration - st->info->last_duration) < 60LL*st->time_base.den / st->time_base.num)) + if (st->duration == AV_NOPTS_VALUE || st->internal->info->last_duration<= 0 || + (st->duration < duration && FFABS(duration - st->internal->info->last_duration) < 60LL*st->time_base.den / st->time_base.num)) st->duration = duration; - st->info->last_duration = duration; + st->internal->info->last_duration = duration; } } av_packet_unref(pkt); @@ -2930,14 +2893,14 @@ skip_duration_calc: st = ic->streams[i]; st->cur_dts = st->first_dts; st->last_IP_pts = AV_NOPTS_VALUE; - st->last_dts_for_order_check = AV_NOPTS_VALUE; + st->internal->last_dts_for_order_check = AV_NOPTS_VALUE; for (j = 0; j < MAX_REORDER_DELAY + 1; j++) - st->pts_buffer[j] = AV_NOPTS_VALUE; + st->internal->pts_buffer[j] = AV_NOPTS_VALUE; } } /* 1:1 map to AVDurationEstimationMethod */ -static const char *duration_name[] = { +static const char *const duration_name[] = { [AVFMT_DURATION_FROM_PTS] = "pts", [AVFMT_DURATION_FROM_STREAM] = "stream", [AVFMT_DURATION_FROM_BITRATE] = "bit rate", @@ -3018,20 +2981,20 @@ static int has_codec_parameters(AVStream *st, const char **errmsg_ptr) case AVMEDIA_TYPE_AUDIO: if (!avctx->frame_size && determinable_frame_size(avctx)) FAIL("unspecified frame size"); - if (st->info->found_decoder >= 0 && + if (st->internal->info->found_decoder >= 0 && avctx->sample_fmt == AV_SAMPLE_FMT_NONE) FAIL("unspecified sample format"); if (!avctx->sample_rate) FAIL("unspecified sample rate"); if (!avctx->channels) FAIL("unspecified number of channels"); - if (st->info->found_decoder >= 0 && !st->nb_decoded_frames && avctx->codec_id == AV_CODEC_ID_DTS) + if (st->internal->info->found_decoder >= 0 && !st->internal->nb_decoded_frames && avctx->codec_id == AV_CODEC_ID_DTS) FAIL("no decodable DTS frames"); break; case AVMEDIA_TYPE_VIDEO: if (!avctx->width) FAIL("unspecified size"); - if (st->info->found_decoder >= 0 && avctx->pix_fmt == AV_PIX_FMT_NONE) + if (st->internal->info->found_decoder >= 0 && avctx->pix_fmt == AV_PIX_FMT_NONE) FAIL("unspecified pixel format"); if (st->codecpar->codec_id == AV_CODEC_ID_RV30 || st->codecpar->codec_id == AV_CODEC_ID_RV40) if (!st->sample_aspect_ratio.num && !st->codecpar->sample_aspect_ratio.num && !st->codec_info_nb_frames) @@ -3065,14 +3028,14 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, return AVERROR(ENOMEM); if (!avcodec_is_open(avctx) && - st->info->found_decoder <= 0 && - (st->codecpar->codec_id != -st->info->found_decoder || !st->codecpar->codec_id)) { + st->internal->info->found_decoder <= 0 && + (st->codecpar->codec_id != -st->internal->info->found_decoder || !st->codecpar->codec_id)) { AVDictionary *thread_opt = NULL; codec = find_probe_decoder(s, st, st->codecpar->codec_id); if (!codec) { - st->info->found_decoder = -st->codecpar->codec_id; + st->internal->info->found_decoder = -st->codecpar->codec_id; ret = -1; goto fail; } @@ -3080,20 +3043,24 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, /* Force thread count to 1 since the H.264 decoder will not extract * SPS and PPS to extradata during multi-threaded decoding. */ av_dict_set(options ? options : &thread_opt, "threads", "1", 0); + /* Force lowres to 0. The decoder might reduce the video size by the + * lowres factor, and we don't want that propagated to the stream's + * codecpar */ + av_dict_set(options ? options : &thread_opt, "lowres", "0", 0); if (s->codec_whitelist) av_dict_set(options ? options : &thread_opt, "codec_whitelist", s->codec_whitelist, 0); ret = avcodec_open2(avctx, codec, options ? options : &thread_opt); if (!options) av_dict_free(&thread_opt); if (ret < 0) { - st->info->found_decoder = -avctx->codec_id; + st->internal->info->found_decoder = -avctx->codec_id; goto fail; } - st->info->found_decoder = 1; - } else if (!st->info->found_decoder) - st->info->found_decoder = 1; + st->internal->info->found_decoder = 1; + } else if (!st->internal->info->found_decoder) + st->internal->info->found_decoder = 1; - if (st->info->found_decoder < 0) { + if (st->internal->info->found_decoder < 0) { ret = -1; goto fail; } @@ -3132,7 +3099,7 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, } if (ret >= 0) { if (got_picture) - st->nb_decoded_frames++; + st->internal->nb_decoded_frames++; ret = got_picture; } } @@ -3256,31 +3223,51 @@ enum AVCodecID av_codec_get_id(const AVCodecTag *const *tags, unsigned int tag) return AV_CODEC_ID_NONE; } -static void compute_chapters_end(AVFormatContext *s) +static int chapter_start_cmp(const void *p1, const void *p2) { - unsigned int i, j; + AVChapter *ch1 = *(AVChapter**)p1; + AVChapter *ch2 = *(AVChapter**)p2; + int delta = av_compare_ts(ch1->start, ch1->time_base, ch2->start, ch2->time_base); + if (delta) + return delta; + return (ch1 > ch2) - (ch1 < ch2); +} + +static int compute_chapters_end(AVFormatContext *s) +{ + unsigned int i; int64_t max_time = 0; + AVChapter **timetable = av_malloc(s->nb_chapters * sizeof(*timetable)); + + if (!timetable) + return AVERROR(ENOMEM); if (s->duration > 0 && s->start_time < INT64_MAX - s->duration) max_time = s->duration + ((s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time); for (i = 0; i < s->nb_chapters; i++) - if (s->chapters[i]->end == AV_NOPTS_VALUE) { - AVChapter *ch = s->chapters[i]; - int64_t end = max_time ? av_rescale_q(max_time, AV_TIME_BASE_Q, - ch->time_base) - : INT64_MAX; + timetable[i] = s->chapters[i]; + qsort(timetable, s->nb_chapters, sizeof(*timetable), chapter_start_cmp); - for (j = 0; j < s->nb_chapters; j++) { - AVChapter *ch1 = s->chapters[j]; + for (i = 0; i < s->nb_chapters; i++) + if (timetable[i]->end == AV_NOPTS_VALUE) { + AVChapter *ch = timetable[i]; + int64_t end = max_time ? av_rescale_q(max_time, AV_TIME_BASE_Q, + ch->time_base) + : INT64_MAX; + + if (i + 1 < s->nb_chapters) { + AVChapter *ch1 = timetable[i + 1]; int64_t next_start = av_rescale_q(ch1->start, ch1->time_base, - ch->time_base); - if (j != i && next_start > ch->start && next_start < end) + ch->time_base); + if (next_start > ch->start && next_start < end) end = next_start; } ch->end = (end == INT64_MAX || end < ch->start) ? ch->start : end; } + av_free(timetable); + return 0; } static int get_std_framerate(int i) @@ -3359,59 +3346,59 @@ int ff_get_extradata(AVFormatContext *s, AVCodecParameters *par, AVIOContext *pb int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts) { int i, j; - int64_t last = st->info->last_dts; + int64_t last = st->internal->info->last_dts; if ( ts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && ts > last && ts - (uint64_t)last < INT64_MAX) { double dts = (is_relative(ts) ? ts - RELATIVE_TS_BASE : ts) * av_q2d(st->time_base); int64_t duration = ts - last; - if (!st->info->duration_error) - st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2); - if (!st->info->duration_error) + if (!st->internal->info->duration_error) + st->internal->info->duration_error = av_mallocz(sizeof(st->internal->info->duration_error[0])*2); + if (!st->internal->info->duration_error) return AVERROR(ENOMEM); // if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) // av_log(NULL, AV_LOG_ERROR, "%f\n", dts); for (i = 0; iinfo->duration_error[0][1][i] < 1e10) { + if (st->internal->info->duration_error[0][1][i] < 1e10) { int framerate = get_std_framerate(i); double sdts = dts*framerate/(1001*12); for (j= 0; j<2; j++) { int64_t ticks = llrint(sdts+j*0.5); double error= sdts - ticks + j*0.5; - st->info->duration_error[j][0][i] += error; - st->info->duration_error[j][1][i] += error*error; + st->internal->info->duration_error[j][0][i] += error; + st->internal->info->duration_error[j][1][i] += error*error; } } } - if (st->info->rfps_duration_sum <= INT64_MAX - duration) { - st->info->duration_count++; - st->info->rfps_duration_sum += duration; + if (st->internal->info->rfps_duration_sum <= INT64_MAX - duration) { + st->internal->info->duration_count++; + st->internal->info->rfps_duration_sum += duration; } - if (st->info->duration_count % 10 == 0) { - int n = st->info->duration_count; + if (st->internal->info->duration_count % 10 == 0) { + int n = st->internal->info->duration_count; for (i = 0; iinfo->duration_error[0][1][i] < 1e10) { - double a0 = st->info->duration_error[0][0][i] / n; - double error0 = st->info->duration_error[0][1][i] / n - a0*a0; - double a1 = st->info->duration_error[1][0][i] / n; - double error1 = st->info->duration_error[1][1][i] / n - a1*a1; + if (st->internal->info->duration_error[0][1][i] < 1e10) { + double a0 = st->internal->info->duration_error[0][0][i] / n; + double error0 = st->internal->info->duration_error[0][1][i] / n - a0*a0; + double a1 = st->internal->info->duration_error[1][0][i] / n; + double error1 = st->internal->info->duration_error[1][1][i] / n - a1*a1; if (error0 > 0.04 && error1 > 0.04) { - st->info->duration_error[0][1][i] = 2e10; - st->info->duration_error[1][1][i] = 2e10; + st->internal->info->duration_error[0][1][i] = 2e10; + st->internal->info->duration_error[1][1][i] = 2e10; } } } } // ignore the first 4 values, they might have some random jitter - if (st->info->duration_count > 3 && is_relative(ts) == is_relative(last)) - st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration); + if (st->internal->info->duration_count > 3 && is_relative(ts) == is_relative(last)) + st->internal->info->duration_gcd = av_gcd(st->internal->info->duration_gcd, duration); } if (ts != AV_NOPTS_VALUE) - st->info->last_dts = ts; + st->internal->info->last_dts = ts; return 0; } @@ -3428,9 +3415,10 @@ void ff_rfps_calculate(AVFormatContext *ic) // the check for tb_unreliable() is not completely correct, since this is not about handling // an unreliable/inexact time base, but a time base that is finer than necessary, as e.g. // ipmovie.c produces. - if (tb_unreliable(st->internal->avctx) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num) - av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX); - if (st->info->duration_count>1 && !st->r_frame_rate.num + if (tb_unreliable(st->internal->avctx) && st->internal->info->duration_count > 15 && st->internal->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num && + st->internal->info->duration_gcd < INT64_MAX / st->time_base.num) + av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->internal->info->duration_gcd, INT_MAX); + if (st->internal->info->duration_count>1 && !st->r_frame_rate.num && tb_unreliable(st->internal->avctx)) { int num = 0; double best_error= 0.01; @@ -3439,19 +3427,19 @@ void ff_rfps_calculate(AVFormatContext *ic) for (j= 0; jinfo->codec_info_duration && - st->info->codec_info_duration*av_q2d(st->time_base) < (1001*11.5)/get_std_framerate(j)) + if (st->internal->info->codec_info_duration && + st->internal->info->codec_info_duration*av_q2d(st->time_base) < (1001*11.5)/get_std_framerate(j)) continue; - if (!st->info->codec_info_duration && get_std_framerate(j) < 1001*12) + if (!st->internal->info->codec_info_duration && get_std_framerate(j) < 1001*12) continue; - if (av_q2d(st->time_base) * st->info->rfps_duration_sum / st->info->duration_count < (1001*12.0 * 0.8)/get_std_framerate(j)) + if (av_q2d(st->time_base) * st->internal->info->rfps_duration_sum / st->internal->info->duration_count < (1001*12.0 * 0.8)/get_std_framerate(j)) continue; for (k= 0; k<2; k++) { - int n = st->info->duration_count; - double a= st->info->duration_error[k][0][j] / n; - double error= st->info->duration_error[k][1][j]/n - a*a; + int n = st->internal->info->duration_count; + double a= st->internal->info->duration_error[k][0][j] / n; + double error= st->internal->info->duration_error[k][1][j]/n - a*a; if (error < best_error && best_error> 0.000000001) { best_error= error; @@ -3466,19 +3454,19 @@ void ff_rfps_calculate(AVFormatContext *ic) av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX); } if ( !st->avg_frame_rate.num - && st->r_frame_rate.num && st->info->rfps_duration_sum - && st->info->codec_info_duration <= 0 - && st->info->duration_count > 2 - && fabs(1.0 / (av_q2d(st->r_frame_rate) * av_q2d(st->time_base)) - st->info->rfps_duration_sum / (double)st->info->duration_count) <= 1.0 + && st->r_frame_rate.num && st->internal->info->rfps_duration_sum + && st->internal->info->codec_info_duration <= 0 + && st->internal->info->duration_count > 2 + && fabs(1.0 / (av_q2d(st->r_frame_rate) * av_q2d(st->time_base)) - st->internal->info->rfps_duration_sum / (double)st->internal->info->duration_count) <= 1.0 ) { av_log(ic, AV_LOG_DEBUG, "Setting avg frame rate based on r frame rate\n"); st->avg_frame_rate = st->r_frame_rate; } - av_freep(&st->info->duration_error); - st->info->last_dts = AV_NOPTS_VALUE; - st->info->duration_count = 0; - st->info->rfps_duration_sum = 0; + av_freep(&st->internal->info->duration_error); + st->internal->info->last_dts = AV_NOPTS_VALUE; + st->internal->info->duration_count = 0; + st->internal->info->rfps_duration_sum = 0; } } @@ -3571,9 +3559,6 @@ static int extract_extradata(AVStream *st, const AVPacket *pkt) } while (ret >= 0 && !sti->avctx->extradata) { - int extradata_size; - uint8_t *extradata; - ret = av_bsf_receive_packet(sti->extract_extradata.bsf, pkt_ref); if (ret < 0) { if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) @@ -3581,19 +3566,15 @@ static int extract_extradata(AVStream *st, const AVPacket *pkt) continue; } - extradata = av_packet_get_side_data(pkt_ref, AV_PKT_DATA_NEW_EXTRADATA, - &extradata_size); - - if (extradata) { - av_assert0(!sti->avctx->extradata); - if ((unsigned)extradata_size < FF_MAX_EXTRADATA_SIZE) - sti->avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!sti->avctx->extradata) { - av_packet_unref(pkt_ref); - return AVERROR(ENOMEM); + for (int i = 0; i < pkt_ref->side_data_elems; i++) { + AVPacketSideData *side_data = &pkt_ref->side_data[i]; + if (side_data->type == AV_PKT_DATA_NEW_EXTRADATA) { + sti->avctx->extradata = side_data->data; + sti->avctx->extradata_size = side_data->size; + side_data->data = NULL; + side_data->size = 0; + break; } - memcpy(sti->avctx->extradata, extradata, extradata_size); - sti->avctx->extradata_size = extradata_size; } av_packet_unref(pkt_ref); } @@ -3622,7 +3603,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) int64_t read_size; AVStream *st; AVCodecContext *avctx; - AVPacket pkt1; + AVPacket *pkt1 = ic->internal->pkt; int64_t old_offset = avio_tell(ic->pb); // new streams might appear, no options for those int orig_nb_streams = ic->nb_streams; @@ -3679,7 +3660,7 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif // only for the split stuff - if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->request_probe <= 0) { + if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->internal->request_probe <= 0) { st->parser = av_parser_init(st->codecpar->codec_id); if (st->parser) { if (st->need_parsing == AVSTREAM_PARSE_HEADERS) { @@ -3700,7 +3681,7 @@ FF_ENABLE_DEPRECATION_WARNINGS ret = avcodec_parameters_to_context(avctx, st->codecpar); if (ret < 0) goto find_stream_info_err; - if (st->request_probe <= 0) + if (st->internal->request_probe <= 0) st->internal->avctx_inited = 1; codec = find_probe_decoder(ic, st, st->codecpar->codec_id); @@ -3708,6 +3689,10 @@ FF_ENABLE_DEPRECATION_WARNINGS /* Force thread count to 1 since the H.264 decoder will not extract * SPS and PPS to extradata during multi-threaded decoding. */ av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 0); + /* Force lowres to 0. The decoder might reduce the video size by the + * lowres factor, and we don't want that propagated to the stream's + * codecpar */ + av_dict_set(options ? &options[i] : &thread_opt, "lowres", "0", 0); if (ic->codec_whitelist) av_dict_set(options ? &options[i] : &thread_opt, "codec_whitelist", ic->codec_whitelist, 0); @@ -3721,7 +3706,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } // Try to just open decoders, in case this is enough to get parameters. - if (!has_codec_parameters(st, NULL) && st->request_probe <= 0) { + if (!has_codec_parameters(st, NULL) && st->internal->request_probe <= 0) { if (codec && !avctx->codec) if (avcodec_open2(avctx, codec, options ? &options[i] : &thread_opt) < 0) av_log(ic, AV_LOG_WARNING, @@ -3733,10 +3718,10 @@ FF_ENABLE_DEPRECATION_WARNINGS for (i = 0; i < ic->nb_streams; i++) { #if FF_API_R_FRAME_RATE - ic->streams[i]->info->last_dts = AV_NOPTS_VALUE; + ic->streams[i]->internal->info->last_dts = AV_NOPTS_VALUE; #endif - ic->streams[i]->info->fps_first_dts = AV_NOPTS_VALUE; - ic->streams[i]->info->fps_last_dts = AV_NOPTS_VALUE; + ic->streams[i]->internal->info->fps_first_dts = AV_NOPTS_VALUE; + ic->streams[i]->internal->info->fps_last_dts = AV_NOPTS_VALUE; } read_size = 0; @@ -3770,8 +3755,8 @@ FF_ENABLE_DEPRECATION_WARNINGS fps_analyze_framecount = 0; /* variable fps and no guess at the real fps */ count = (ic->iformat->flags & AVFMT_NOTIMESTAMPS) ? - st->info->codec_info_duration_fields/2 : - st->info->duration_count; + st->internal->info->codec_info_duration_fields/2 : + st->internal->info->duration_count; if (!(st->r_frame_rate.num && st->avg_frame_rate.num) && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (count < fps_analyze_framecount) @@ -3779,7 +3764,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } // Look at the first 3 frames if there is evidence of frame delay // but the decoder delay is not set. - if (st->info->frame_delay_evidence && count < 2 && st->internal->avctx->has_b_frames == 0) + if (st->internal->info->frame_delay_evidence && count < 2 && st->internal->avctx->has_b_frames == 0) break; if (!st->internal->avctx->extradata && (!st->internal->extract_extradata.inited || @@ -3814,7 +3799,7 @@ FF_ENABLE_DEPRECATION_WARNINGS "Probe buffer size limit of %"PRId64" bytes reached\n", probesize); for (i = 0; i < ic->nb_streams; i++) if (!ic->streams[i]->r_frame_rate.num && - ic->streams[i]->info->duration_count <= 1 && + ic->streams[i]->internal->info->duration_count <= 1 && ic->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && strcmp(ic->iformat->name, "image2")) av_log(ic, AV_LOG_WARNING, @@ -3825,7 +3810,7 @@ FF_ENABLE_DEPRECATION_WARNINGS /* NOTE: A new stream can be added there if no header in file * (AVFMTCTX_NOHEADER). */ - ret = read_frame_internal(ic, &pkt1); + ret = read_frame_internal(ic, pkt1); if (ret == AVERROR(EAGAIN)) continue; @@ -3836,15 +3821,15 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) { - ret = ff_packet_list_put(&ic->internal->packet_buffer, + ret = avpriv_packet_list_put(&ic->internal->packet_buffer, &ic->internal->packet_buffer_end, - &pkt1, 0); + pkt1, NULL, 0); if (ret < 0) goto unref_then_goto_end; pkt = &ic->internal->packet_buffer_end->pkt; } else { - pkt = &pkt1; + pkt = pkt1; } st = ic->streams[pkt->stream_index]; @@ -3861,57 +3846,59 @@ FF_ENABLE_DEPRECATION_WARNINGS if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) { /* check for non-increasing dts */ - if (st->info->fps_last_dts != AV_NOPTS_VALUE && - st->info->fps_last_dts >= pkt->dts) { + if (st->internal->info->fps_last_dts != AV_NOPTS_VALUE && + st->internal->info->fps_last_dts >= pkt->dts) { av_log(ic, AV_LOG_DEBUG, "Non-increasing DTS in stream %d: packet %d with DTS " "%"PRId64", packet %d with DTS %"PRId64"\n", - st->index, st->info->fps_last_dts_idx, - st->info->fps_last_dts, st->codec_info_nb_frames, + st->index, st->internal->info->fps_last_dts_idx, + st->internal->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts); - st->info->fps_first_dts = - st->info->fps_last_dts = AV_NOPTS_VALUE; + st->internal->info->fps_first_dts = + st->internal->info->fps_last_dts = AV_NOPTS_VALUE; } /* Check for a discontinuity in dts. If the difference in dts * is more than 1000 times the average packet duration in the * sequence, we treat it as a discontinuity. */ - if (st->info->fps_last_dts != AV_NOPTS_VALUE && - st->info->fps_last_dts_idx > st->info->fps_first_dts_idx && - (pkt->dts - (uint64_t)st->info->fps_last_dts) / 1000 > - (st->info->fps_last_dts - (uint64_t)st->info->fps_first_dts) / - (st->info->fps_last_dts_idx - st->info->fps_first_dts_idx)) { + if (st->internal->info->fps_last_dts != AV_NOPTS_VALUE && + st->internal->info->fps_last_dts_idx > st->internal->info->fps_first_dts_idx && + (pkt->dts - (uint64_t)st->internal->info->fps_last_dts) / 1000 > + (st->internal->info->fps_last_dts - (uint64_t)st->internal->info->fps_first_dts) / + (st->internal->info->fps_last_dts_idx - st->internal->info->fps_first_dts_idx)) { av_log(ic, AV_LOG_WARNING, "DTS discontinuity in stream %d: packet %d with DTS " "%"PRId64", packet %d with DTS %"PRId64"\n", - st->index, st->info->fps_last_dts_idx, - st->info->fps_last_dts, st->codec_info_nb_frames, + st->index, st->internal->info->fps_last_dts_idx, + st->internal->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts); - st->info->fps_first_dts = - st->info->fps_last_dts = AV_NOPTS_VALUE; + st->internal->info->fps_first_dts = + st->internal->info->fps_last_dts = AV_NOPTS_VALUE; } /* update stored dts values */ - if (st->info->fps_first_dts == AV_NOPTS_VALUE) { - st->info->fps_first_dts = pkt->dts; - st->info->fps_first_dts_idx = st->codec_info_nb_frames; + if (st->internal->info->fps_first_dts == AV_NOPTS_VALUE) { + st->internal->info->fps_first_dts = pkt->dts; + st->internal->info->fps_first_dts_idx = st->codec_info_nb_frames; } - st->info->fps_last_dts = pkt->dts; - st->info->fps_last_dts_idx = st->codec_info_nb_frames; + st->internal->info->fps_last_dts = pkt->dts; + st->internal->info->fps_last_dts_idx = st->codec_info_nb_frames; } if (st->codec_info_nb_frames>1) { int64_t t = 0; int64_t limit; if (st->time_base.den > 0) - t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q); + t = av_rescale_q(st->internal->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q); if (st->avg_frame_rate.num > 0) t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, av_inv_q(st->avg_frame_rate), AV_TIME_BASE_Q)); if ( t == 0 && st->codec_info_nb_frames>30 - && st->info->fps_first_dts != AV_NOPTS_VALUE - && st->info->fps_last_dts != AV_NOPTS_VALUE) - t = FFMAX(t, av_rescale_q(st->info->fps_last_dts - st->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q)); + && st->internal->info->fps_first_dts != AV_NOPTS_VALUE + && st->internal->info->fps_last_dts != AV_NOPTS_VALUE) { + int64_t dur = av_sat_sub64(st->internal->info->fps_last_dts, st->internal->info->fps_first_dts); + t = FFMAX(t, av_rescale_q(dur, st->time_base, AV_TIME_BASE_Q)); + } if (analyzed_all_streams) limit = max_analyze_duration; else if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) limit = max_subtitle_analyze_duration; @@ -3922,15 +3909,15 @@ FF_ENABLE_DEPRECATION_WARNINGS limit, t, pkt->stream_index); if (ic->flags & AVFMT_FLAG_NOBUFFER) - av_packet_unref(&pkt1); + av_packet_unref(pkt1); break; } if (pkt->duration) { if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && st->start_time != AV_NOPTS_VALUE && pkt->pts >= st->start_time) { - st->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->info->codec_info_duration + pkt->duration); + st->internal->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->internal->info->codec_info_duration + pkt->duration); } else - st->info->codec_info_duration += pkt->duration; - st->info->codec_info_duration_fields += st->parser && st->need_parsing && avctx->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2; + st->internal->info->codec_info_duration += pkt->duration; + st->internal->info->codec_info_duration_fields += st->parser && st->need_parsing && avctx->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2; } } if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { @@ -3938,7 +3925,7 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_rfps_add_frame(ic, st, pkt->dts); #endif if (pkt->dts != pkt->pts && pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE) - st->info->frame_delay_evidence = 1; + st->internal->info->frame_delay_evidence = 1; } if (!st->internal->avctx->extradata) { ret = extract_extradata(st, pkt); @@ -3959,7 +3946,7 @@ FF_ENABLE_DEPRECATION_WARNINGS (options && i < orig_nb_streams) ? &options[i] : NULL); if (ic->flags & AVFMT_FLAG_NOBUFFER) - av_packet_unref(&pkt1); + av_packet_unref(pkt1); st->codec_info_nb_frames++; count++; @@ -3992,18 +3979,18 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (flush_codecs) { - AVPacket empty_pkt = { 0 }; + AVPacket *empty_pkt = ic->internal->pkt; int err = 0; - av_init_packet(&empty_pkt); + av_packet_unref(empty_pkt); for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; /* flush the decoders */ - if (st->info->found_decoder == 1) { + if (st->internal->info->found_decoder == 1) { do { - err = try_decode_frame(ic, st, &empty_pkt, + err = try_decode_frame(ic, st, empty_pkt, (options && i < orig_nb_streams) ? &options[i] : NULL); } while (err > 0 && !has_codec_parameters(st, NULL)); @@ -4029,20 +4016,20 @@ FF_ENABLE_DEPRECATION_WARNINGS } /* estimate average framerate if not set by demuxer */ - if (st->info->codec_info_duration_fields && + if (st->internal->info->codec_info_duration_fields && !st->avg_frame_rate.num && - st->info->codec_info_duration) { + st->internal->info->codec_info_duration) { int best_fps = 0; double best_error = 0.01; AVRational codec_frame_rate = avctx->framerate; - if (st->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| - st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den || - st->info->codec_info_duration < 0) + if (st->internal->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| + st->internal->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den || + st->internal->info->codec_info_duration < 0) continue; av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - st->info->codec_info_duration_fields * (int64_t) st->time_base.den, - st->info->codec_info_duration * 2 * (int64_t) st->time_base.num, 60000); + st->internal->info->codec_info_duration_fields * (int64_t) st->time_base.den, + st->internal->info->codec_info_duration * 2 * (int64_t) st->time_base.num, 60000); /* Round guessed framerate to a "standard" framerate if it's * within 1% of the original estimate. */ @@ -4080,9 +4067,9 @@ FF_ENABLE_DEPRECATION_WARNINGS st->r_frame_rate.den = st->time_base.num; } } - if (st->display_aspect_ratio.num && st->display_aspect_ratio.den) { + if (st->internal->display_aspect_ratio.num && st->internal->display_aspect_ratio.den) { AVRational hw_ratio = { avctx->height, avctx->width }; - st->sample_aspect_ratio = av_mul_q(st->display_aspect_ratio, + st->sample_aspect_ratio = av_mul_q(st->internal->display_aspect_ratio, hw_ratio); } } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -4136,35 +4123,28 @@ FF_ENABLE_DEPRECATION_WARNINGS avcodec_string(buf, sizeof(buf), st->internal->avctx, 0); av_log(ic, AV_LOG_WARNING, "Could not find codec parameters for stream %d (%s): %s\n" - "Consider increasing the value for the 'analyzeduration' and 'probesize' options\n", - i, buf, errmsg); + "Consider increasing the value for the 'analyzeduration' (%"PRId64") and 'probesize' (%"PRId64") options\n", + i, buf, errmsg, ic->max_analyze_duration, ic->probesize); } else { ret = 0; } } - compute_chapters_end(ic); + ret = compute_chapters_end(ic); + if (ret < 0) + goto find_stream_info_err; /* update the stream parameters from the internal codec contexts */ for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->internal->avctx_inited) { - int orig_w = st->codecpar->width; - int orig_h = st->codecpar->height; ret = avcodec_parameters_from_context(st->codecpar, st->internal->avctx); if (ret < 0) goto find_stream_info_err; ret = add_coded_side_data(st, st->internal->avctx); if (ret < 0) goto find_stream_info_err; -#if FF_API_LOWRES - // The decoder might reduce the video size by the lowres factor. - if (st->internal->avctx->lowres && orig_w) { - st->codecpar->width = orig_w; - st->codecpar->height = orig_h; - } -#endif } #if FF_API_LAVF_AVCTX @@ -4173,7 +4153,6 @@ FF_DISABLE_DEPRECATION_WARNINGS if (ret < 0) goto find_stream_info_err; -#if FF_API_LOWRES // The old API (AVStream.codec) "requires" the resolution to be adjusted // by the lowres factor. if (st->internal->avctx->lowres && st->internal->avctx->width) { @@ -4181,7 +4160,6 @@ FF_DISABLE_DEPRECATION_WARNINGS st->codec->width = st->internal->avctx->width; st->codec->height = st->internal->avctx->height; } -#endif if (st->codec->codec_tag != MKTAG('t','m','c','d')) { st->codec->time_base = st->internal->avctx->time_base; @@ -4211,10 +4189,10 @@ FF_ENABLE_DEPRECATION_WARNINGS find_stream_info_err: for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; - if (st->info) - av_freep(&st->info->duration_error); + if (st->internal->info) + av_freep(&st->internal->info->duration_error); avcodec_close(ic->streams[i]->internal->avctx); - av_freep(&ic->streams[i]->info); + av_freep(&ic->streams[i]->internal->info); av_bsf_free(&ic->streams[i]->internal->extract_extradata.bsf); av_packet_free(&ic->streams[i]->internal->extract_extradata.pkt); } @@ -4224,7 +4202,7 @@ find_stream_info_err: return ret; unref_then_goto_end: - av_packet_unref(&pkt1); + av_packet_unref(pkt1); goto find_stream_info_err; } @@ -4414,24 +4392,26 @@ static void free_stream(AVStream **pst) avcodec_free_context(&st->internal->avctx); av_bsf_free(&st->internal->bsfc); av_freep(&st->internal->priv_pts); + av_freep(&st->index_entries); + av_freep(&st->internal->probe_data.buf); + av_bsf_free(&st->internal->extract_extradata.bsf); av_packet_free(&st->internal->extract_extradata.pkt); + + if (st->internal->info) + av_freep(&st->internal->info->duration_error); + av_freep(&st->internal->info); } av_freep(&st->internal); av_dict_free(&st->metadata); avcodec_parameters_free(&st->codecpar); - av_freep(&st->probe_data.buf); - av_freep(&st->index_entries); #if FF_API_LAVF_AVCTX FF_DISABLE_DEPRECATION_WARNINGS avcodec_free_context(&st->codec); FF_ENABLE_DEPRECATION_WARNINGS #endif av_freep(&st->priv_data); - if (st->info) - av_freep(&st->info->duration_error); - av_freep(&st->info); #if FF_API_LAVF_FFSERVER FF_DISABLE_DEPRECATION_WARNINGS av_freep(&st->recommended_encoder_configuration); @@ -4485,6 +4465,8 @@ void avformat_free_context(AVFormatContext *s) av_freep(&s->chapters); av_dict_free(&s->metadata); av_dict_free(&s->internal->id3v2_meta); + av_packet_free(&s->internal->pkt); + av_packet_free(&s->internal->parse_pkt); av_freep(&s->streams); flush_packet_queue(s); av_freep(&s->internal); @@ -4539,17 +4521,11 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) st = av_mallocz(sizeof(AVStream)); if (!st) return NULL; - if (!(st->info = av_mallocz(sizeof(*st->info)))) { - av_free(st); - return NULL; - } - st->info->last_dts = AV_NOPTS_VALUE; #if FF_API_LAVF_AVCTX FF_DISABLE_DEPRECATION_WARNINGS st->codec = avcodec_alloc_context3(c); if (!st->codec) { - av_free(st->info); av_free(st); return NULL; } @@ -4560,6 +4536,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!st->internal) goto fail; + st->internal->info = av_mallocz(sizeof(*st->internal->info)); + if (!st->internal->info) + goto fail; + st->internal->info->last_dts = AV_NOPTS_VALUE; + st->codecpar = avcodec_parameters_alloc(); if (!st->codecpar) goto fail; @@ -4592,23 +4573,23 @@ FF_ENABLE_DEPRECATION_WARNINGS st->duration = AV_NOPTS_VALUE; st->first_dts = AV_NOPTS_VALUE; st->probe_packets = s->max_probe_packets; - st->pts_wrap_reference = AV_NOPTS_VALUE; - st->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; + st->internal->pts_wrap_reference = AV_NOPTS_VALUE; + st->internal->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; st->last_IP_pts = AV_NOPTS_VALUE; - st->last_dts_for_order_check = AV_NOPTS_VALUE; + st->internal->last_dts_for_order_check = AV_NOPTS_VALUE; for (i = 0; i < MAX_REORDER_DELAY + 1; i++) - st->pts_buffer[i] = AV_NOPTS_VALUE; + st->internal->pts_buffer[i] = AV_NOPTS_VALUE; st->sample_aspect_ratio = (AVRational) { 0, 1 }; #if FF_API_R_FRAME_RATE - st->info->last_dts = AV_NOPTS_VALUE; + st->internal->info->last_dts = AV_NOPTS_VALUE; #endif - st->info->fps_first_dts = AV_NOPTS_VALUE; - st->info->fps_last_dts = AV_NOPTS_VALUE; + st->internal->info->fps_first_dts = AV_NOPTS_VALUE; + st->internal->info->fps_last_dts = AV_NOPTS_VALUE; - st->inject_global_side_data = s->internal->inject_global_side_data; + st->internal->inject_global_side_data = s->internal->inject_global_side_data; st->internal->need_context_update = 1; @@ -4622,7 +4603,7 @@ fail: AVProgram *av_new_program(AVFormatContext *ac, int id) { AVProgram *program = NULL; - int i; + int i, ret; av_log(ac, AV_LOG_TRACE, "new_program: id=0x%04x\n", id); @@ -4634,40 +4615,55 @@ AVProgram *av_new_program(AVFormatContext *ac, int id) program = av_mallocz(sizeof(AVProgram)); if (!program) return NULL; - dynarray_add(&ac->programs, &ac->nb_programs, program); + ret = av_dynarray_add_nofree(&ac->programs, &ac->nb_programs, program); + if (ret < 0) { + av_free(program); + return NULL; + } program->discard = AVDISCARD_NONE; program->pmt_version = -1; + program->id = id; + program->pts_wrap_reference = AV_NOPTS_VALUE; + program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; + program->start_time = + program->end_time = AV_NOPTS_VALUE; } - program->id = id; - program->pts_wrap_reference = AV_NOPTS_VALUE; - program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; - - program->start_time = - program->end_time = AV_NOPTS_VALUE; - return program; } +#if FF_API_CHAPTER_ID_INT AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, +#else +AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, +#endif int64_t start, int64_t end, const char *title) { AVChapter *chapter = NULL; - int i; + int i, ret; if (end != AV_NOPTS_VALUE && start > end) { av_log(s, AV_LOG_ERROR, "Chapter end time %"PRId64" before start %"PRId64"\n", end, start); return NULL; } - for (i = 0; i < s->nb_chapters; i++) - if (s->chapters[i]->id == id) - chapter = s->chapters[i]; + if (!s->nb_chapters) { + s->internal->chapter_ids_monotonic = 1; + } else if (!s->internal->chapter_ids_monotonic || s->chapters[s->nb_chapters-1]->id >= id) { + s->internal->chapter_ids_monotonic = 0; + for (i = 0; i < s->nb_chapters; i++) + if (s->chapters[i]->id == id) + chapter = s->chapters[i]; + } if (!chapter) { chapter = av_mallocz(sizeof(AVChapter)); if (!chapter) return NULL; - dynarray_add(&s->chapters, &s->nb_chapters, chapter); + ret = av_dynarray_add_nofree(&s->chapters, &s->nb_chapters, chapter); + if (ret < 0) { + av_free(chapter); + return NULL; + } } av_dict_set(&chapter->metadata, "title", title, 0); chapter->id = id; @@ -5503,7 +5499,7 @@ int ff_generate_avci_extradata(AVStream *st) } uint8_t *av_stream_get_side_data(const AVStream *st, - enum AVPacketSideDataType type, int *size) + enum AVPacketSideDataType type, buffer_size_t *size) { int i; @@ -5556,7 +5552,7 @@ int av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type, } uint8_t *av_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type, - int size) + buffer_size_t size) { int ret; uint8_t *data = av_malloc(size); @@ -5730,7 +5726,7 @@ int ff_standardize_creation_time(AVFormatContext *s) int ff_get_packet_palette(AVFormatContext *s, AVPacket *pkt, int ret, uint32_t *palette) { uint8_t *side_data; - int size; + buffer_size_t size; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_PALETTE, &size); if (side_data) { @@ -5780,8 +5776,18 @@ int avformat_transfer_internal_stream_timing_info(const AVOutputFormat *ofmt, enum AVTimebaseSource copy_tb) { //TODO: use [io]st->internal->avctx - const AVCodecContext *dec_ctx = ist->codec; - AVCodecContext *enc_ctx = ost->codec; + const AVCodecContext *dec_ctx; + AVCodecContext *enc_ctx; + +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS + dec_ctx = ist->codec; + enc_ctx = ost->codec; +FF_ENABLE_DEPRECATION_WARNINGS +#else + dec_ctx = ist->internal->avctx; + enc_ctx = ost->internal->avctx; +#endif enc_ctx->time_base = ist->time_base; /* diff --git a/libavformat/version.h b/libavformat/version.h index 13c8a615a..46dc51a22 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 45 +#define LIBAVFORMAT_VERSION_MINOR 76 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ @@ -106,6 +106,15 @@ #ifndef FF_API_AVIOFORMAT #define FF_API_AVIOFORMAT (LIBAVFORMAT_VERSION_MAJOR < 59) #endif +#ifndef FF_API_DEMUXER_OPEN +#define FF_API_DEMUXER_OPEN (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_CHAPTER_ID_INT +#define FF_API_CHAPTER_ID_INT (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LAVF_PRIV_OPT +#define FF_API_LAVF_PRIV_OPT (LIBAVFORMAT_VERSION_MAJOR < 60) +#endif #ifndef FF_API_R_FRAME_RATE diff --git a/libavformat/vividas.c b/libavformat/vividas.c index 12554f46c..d35a646bd 100644 --- a/libavformat/vividas.c +++ b/libavformat/vividas.c @@ -157,7 +157,7 @@ static void decode_block(uint8_t *src, uint8_t *dest, unsigned size, uint32_t tmpkey = *key_ptr - key; if (a2 > s) { a2 = s; - avpriv_request_sample(NULL, "tiny aligned block\n"); + avpriv_request_sample(NULL, "tiny aligned block"); } memcpy(tmp + align, src, a2); xor_block(tmp, tmp, 4, key, &tmpkey); @@ -267,7 +267,7 @@ static uint8_t *read_sb_block(AVIOContext *src, unsigned *size, *size = n; n -= 8; - if (avio_read(src, buf+8, n) < n) { + if (avio_read(src, buf+8, n) != n) { av_free(buf); return NULL; } @@ -439,19 +439,20 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu AVIOContext pb0, *pb = &pb0; int i; int64_t filesize = avio_size(s->pb); + uint64_t n_sb_blocks_tmp; ffio_init_context(pb, buf, size, 0, NULL, NULL, NULL, NULL); ffio_read_varlen(pb); // track_index_len avio_r8(pb); // 'c' - viv->n_sb_blocks = ffio_read_varlen(pb); - if (viv->n_sb_blocks < 0 || viv->n_sb_blocks > size / 2) - goto error; - viv->sb_blocks = av_calloc(viv->n_sb_blocks, sizeof(VIV_SB_block)); + n_sb_blocks_tmp = ffio_read_varlen(pb); + if (n_sb_blocks_tmp > size / 2) + return AVERROR_INVALIDDATA; + viv->sb_blocks = av_calloc(n_sb_blocks_tmp, sizeof(*viv->sb_blocks)); if (!viv->sb_blocks) { - viv->n_sb_blocks = 0; return AVERROR(ENOMEM); } + viv->n_sb_blocks = n_sb_blocks_tmp; off = 0; poff = 0; @@ -461,7 +462,7 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu uint64_t n_packets_tmp = ffio_read_varlen(pb); if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX) - goto error; + return AVERROR_INVALIDDATA; viv->sb_blocks[i].byte_offset = off; viv->sb_blocks[i].packet_offset = poff; @@ -477,15 +478,13 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu } if (filesize > 0 && poff > filesize) - goto error; + return AVERROR_INVALIDDATA; viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry)); + if (!viv->sb_entries) + return AVERROR(ENOMEM); return 0; -error: - viv->n_sb_blocks = 0; - av_freep(&viv->sb_blocks); - return AVERROR_INVALIDDATA; } static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size) @@ -614,7 +613,7 @@ static int viv_read_header(AVFormatContext *s) ret = track_index(viv, s, buf, v); av_free(buf); if (ret < 0) - return ret; + goto fail; viv->sb_offset = avio_tell(pb); if (viv->n_sb_blocks > 0) { @@ -625,6 +624,9 @@ static int viv_read_header(AVFormatContext *s) } return 0; +fail: + av_freep(&viv->sb_blocks); + return ret; } static int viv_read_packet(AVFormatContext *s, @@ -755,18 +757,23 @@ static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp for (int i = 0; i < viv->n_sb_blocks; i++) { if (frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) { - // flush audio packet queue - viv->current_audio_subpacket = 0; - viv->n_audio_subpackets = 0; viv->current_sb = i; // seek to ith sb block avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET); // load the block load_sb_block(s, viv, 0); - // most problematic part: guess audio offset - viv->audio_sample = av_rescale_q(viv->sb_blocks[i].packet_offset, av_make_q(s->streams[1]->codecpar->sample_rate, 1), av_inv_q(s->streams[0]->time_base)); - // hand-tuned 1.s a/v offset - viv->audio_sample += s->streams[1]->codecpar->sample_rate; + if (viv->num_audio) { + const AVCodecParameters *par = s->streams[1]->codecpar; + // flush audio packet queue + viv->current_audio_subpacket = 0; + viv->n_audio_subpackets = 0; + // most problematic part: guess audio offset + viv->audio_sample = av_rescale_q(viv->sb_blocks[i].packet_offset, + av_make_q(par->sample_rate, 1), + av_inv_q(s->streams[0]->time_base)); + // hand-tuned 1.s a/v offset + viv->audio_sample += par->sample_rate; + } viv->current_sb_entry = 0; return 1; } diff --git a/libavformat/voc.c b/libavformat/voc.c index 2a972344d..04ec0da9b 100644 --- a/libavformat/voc.c +++ b/libavformat/voc.c @@ -19,10 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include "voc.h" #include "internal.h" -const unsigned char ff_voc_magic[21] = "Creative Voice File\x1A"; const AVCodecTag ff_voc_codec_tags[] = { {AV_CODEC_ID_PCM_U8, 0x00}, @@ -35,3 +35,8 @@ const AVCodecTag ff_voc_codec_tags[] = { {AV_CODEC_ID_ADPCM_CT, 0x0200}, {AV_CODEC_ID_NONE, 0}, }; + +#if CONFIG_VOC_DEMUXER || CONFIG_VOC_MUXER +const unsigned char ff_voc_magic[21] = "Creative Voice File\x1A"; +const AVCodecTag *const ff_voc_codec_tags_list[] = { ff_voc_codec_tags, NULL }; +#endif diff --git a/libavformat/voc.h b/libavformat/voc.h index 1f9a8be00..1fc6bb422 100644 --- a/libavformat/voc.h +++ b/libavformat/voc.h @@ -45,6 +45,7 @@ typedef enum voc_type { extern const unsigned char ff_voc_magic[21]; extern const AVCodecTag ff_voc_codec_tags[]; +extern const AVCodecTag *const ff_voc_codec_tags_list[]; int ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size); diff --git a/libavformat/voc_packet.c b/libavformat/voc_packet.c index 1e2e19e1c..e5ae0be1d 100644 --- a/libavformat/voc_packet.c +++ b/libavformat/voc_packet.c @@ -44,19 +44,29 @@ ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) AVINDEX_KEYFRAME); while (!voc->remaining_size) { + if (max_size < 4) + max_size = 0; type = avio_r8(pb); if (type == VOC_TYPE_EOF) return AVERROR_EOF; voc->remaining_size = avio_rl24(pb); if (!voc->remaining_size) { + int64_t filesize; if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) return AVERROR(EIO); - voc->remaining_size = avio_size(pb) - avio_tell(pb); + filesize = avio_size(pb); + if (filesize - avio_tell(pb) > INT_MAX) + return AVERROR_INVALIDDATA; + voc->remaining_size = filesize - avio_tell(pb); } max_size -= 4; switch (type) { case VOC_TYPE_VOICE_DATA: + if (voc->remaining_size < 2) { + voc->remaining_size = 0; + return AVERROR_INVALIDDATA; + } if (!par->sample_rate) { par->sample_rate = 1000000 / (256 - avio_r8(pb)); if (sample_rate) @@ -85,6 +95,10 @@ ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) break; case VOC_TYPE_NEW_VOICE_DATA: + if (voc->remaining_size < 12) { + voc->remaining_size = 0; + return AVERROR_INVALIDDATA; + } if (!par->sample_rate) { par->sample_rate = avio_rl32(pb); avpriv_set_pts_info(st, 64, 1, par->sample_rate); diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c index fd1ca20c9..2ccabf0fa 100644 --- a/libavformat/vocdec.c +++ b/libavformat/vocdec.c @@ -106,5 +106,5 @@ AVInputFormat ff_voc_demuxer = { .read_header = voc_read_header, .read_packet = voc_read_packet, .read_seek = voc_read_seek, - .codec_tag = (const AVCodecTag* const []){ ff_voc_codec_tags, 0 }, + .codec_tag = ff_voc_codec_tags_list, }; diff --git a/libavformat/vocenc.c b/libavformat/vocenc.c index 321b11303..bdc63843c 100644 --- a/libavformat/vocenc.c +++ b/libavformat/vocenc.c @@ -106,6 +106,6 @@ AVOutputFormat ff_voc_muxer = { .write_header = voc_write_header, .write_packet = voc_write_packet, .write_trailer = voc_write_trailer, - .codec_tag = (const AVCodecTag* const []){ ff_voc_codec_tags, 0 }, + .codec_tag = ff_voc_codec_tags_list, .flags = AVFMT_NOTIMESTAMPS, }; diff --git a/libavformat/vpk.c b/libavformat/vpk.c index b1df4e0df..f7f20548d 100644 --- a/libavformat/vpk.c +++ b/libavformat/vpk.c @@ -121,7 +121,10 @@ static int vpk_read_seek(AVFormatContext *s, int stream_index, int64_t ret = 0; samples_per_block = av_get_audio_frame_duration2(par, par->block_align); - timestamp /= samples_per_block; + if (samples_per_block > 0) + timestamp /= samples_per_block; + else + return -1; ret = avio_seek(s->pb, vpk->data_start + timestamp * par->block_align, SEEK_SET); if (ret < 0) return ret; diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index 309bb6573..8214ab849 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -6,6 +6,8 @@ * RF64 demuxer * Copyright (c) 2009 Daniel Verkamp * + * BW64 demuxer + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -25,6 +27,7 @@ #include +#include "config.h" #include "libavutil/avassert.h" #include "libavutil/dict.h" #include "libavutil/intreadwrite.h" @@ -54,13 +57,24 @@ typedef struct WAVDemuxContext { int smv_eof; int audio_eof; int ignore_length; + int max_size; int spdif; - int smv_cur_pt; int smv_given_first; int unaligned; // e.g. if an odd number of bytes ID3 tag was prepended int rifx; // RIFX: integer byte order for parameters is big endian } WAVDemuxContext; +#define OFFSET(x) offsetof(WAVDemuxContext, x) +#define DEC AV_OPT_FLAG_DECODING_PARAM +static const AVOption demux_options[] = { +#define W64_DEMUXER_OPTIONS_OFFSET (1 * CONFIG_WAV_DEMUXER) +#if CONFIG_WAV_DEMUXER + { "ignore_length", "Ignore length", OFFSET(ignore_length), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC }, +#endif + { "max_size", "max size of single packet", OFFSET(max_size), AV_OPT_TYPE_INT, { .i64 = 4096 }, 1024, 1 << 22, DEC }, + { NULL }, +}; + static void set_spdif(AVFormatContext *s, WAVDemuxContext *wav) { if (CONFIG_SPDIF_DEMUXER && s->streams[0]->codecpar->codec_tag == 1) { @@ -140,7 +154,8 @@ static int wav_probe(const AVProbeData *p) * its own, the returned score is decreased to avoid a probe * conflict between ACT and WAV. */ return AVPROBE_SCORE_MAX - 1; - else if (!memcmp(p->buf, "RF64", 4) && + else if ((!memcmp(p->buf, "RF64", 4) || + !memcmp(p->buf, "BW64", 4)) && !memcmp(p->buf + 12, "ds64", 4)) return AVPROBE_SCORE_MAX; } @@ -150,7 +165,7 @@ static int wav_probe(const AVProbeData *p) static void handle_stream_probing(AVStream *st) { if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE) { - st->request_probe = AVPROBE_SCORE_EXTENSION; + st->internal->request_probe = AVPROBE_SCORE_EXTENSION; st->probe_packets = FFMIN(st->probe_packets, 32); } } @@ -330,7 +345,7 @@ static int wav_read_header(AVFormatContext *s) { int64_t size, av_uninit(data_size); int64_t sample_count = 0; - int rf64 = 0; + int rf64 = 0, bw64 = 0; uint32_t tag; AVIOContext *pb = s->pb; AVStream *st = NULL; @@ -353,6 +368,9 @@ static int wav_read_header(AVFormatContext *s) case MKTAG('R', 'F', '6', '4'): rf64 = 1; break; + case MKTAG('B', 'W', '6', '4'): + bw64 = 1; + break; default: av_log(s, AV_LOG_ERROR, "invalid start code %s in RIFF header\n", av_fourcc2str(tag)); @@ -368,7 +386,7 @@ static int wav_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } - if (rf64) { + if (rf64 || bw64) { if (avio_rl32(pb) != MKTAG('d', 's', '6', '4')) return AVERROR_INVALIDDATA; size = avio_rl32(pb); @@ -423,7 +441,7 @@ static int wav_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } - if (rf64) { + if (rf64 || bw64) { next_tag_ofs = wav->data_end = avio_tell(pb) + data_size; } else if (size != 0xFFFFFFFF) { data_size = size; @@ -440,7 +458,7 @@ static int wav_read_header(AVFormatContext *s) /* don't look for footer metadata if we can't seek or if we don't * know where the data tag ends */ - if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || (!rf64 && !size)) + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || (!(rf64 && !bw64) && !size)) goto break_loop; break; case MKTAG('f', 'a', 'c', 't'): @@ -490,9 +508,9 @@ static int wav_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } AV_WL32(vst->codecpar->extradata, wav->smv_frames_per_jpeg); - wav->smv_cur_pt = 0; goto break_loop; case MKTAG('L', 'I', 'S', 'T'): + case MKTAG('l', 'i', 's', 't'): if (size < 4) { av_log(s, AV_LOG_ERROR, "too short LIST tag\n"); return AVERROR_INVALIDDATA; @@ -500,6 +518,33 @@ static int wav_read_header(AVFormatContext *s) switch (avio_rl32(pb)) { case MKTAG('I', 'N', 'F', 'O'): ff_read_riff_info(s, size - 4); + break; + case MKTAG('a', 'd', 't', 'l'): + if (s->nb_chapters > 0) { + while (avio_tell(pb) < next_tag_ofs && + !avio_feof(pb)) { + char cue_label[512]; + unsigned id, sub_size; + + if (avio_rl32(pb) != MKTAG('l', 'a', 'b', 'l')) + break; + + sub_size = avio_rl32(pb); + if (sub_size < 5) + break; + id = avio_rl32(pb); + avio_get_str(pb, sub_size - 4, cue_label, sizeof(cue_label)); + avio_skip(pb, avio_tell(pb) & 1); + + for (int i = 0; i < s->nb_chapters; i++) { + if (s->chapters[i]->id == id) { + av_dict_set(&s->chapters[i]->metadata, "title", cue_label, 0); + break; + } + } + } + } + break; } break; case MKTAG('I', 'D', '3', ' '): @@ -514,6 +559,27 @@ static int wav_read_header(AVFormatContext *s) ff_id3v2_free_extra_meta(&id3v2_extra_meta); } break; + case MKTAG('c', 'u', 'e', ' '): + if (size >= 4 && got_fmt && st->codecpar->sample_rate > 0) { + AVRational tb = {1, st->codecpar->sample_rate}; + unsigned nb_cues = avio_rl32(pb); + + if (size >= nb_cues * 24LL + 4LL) { + for (int i = 0; i < nb_cues; i++) { + unsigned offset, id = avio_rl32(pb); + + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; + + avio_skip(pb, 16); + offset = avio_rl32(pb); + + if (!avpriv_new_chapter(s, id, tb, offset, AV_NOPTS_VALUE, NULL)) + return AVERROR(ENOMEM); + } + } + } + break; } /* seek to next tag unless we know that we'll run into EOF */ @@ -623,8 +689,6 @@ static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16]) return AVERROR_EOF; } -#define MAX_SIZE 4096 - static int wav_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret, size; @@ -664,12 +728,9 @@ smv_retry: if (ret < 0) goto smv_out; pkt->pos -= 3; - pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg + wav->smv_cur_pt; - wav->smv_cur_pt++; - if (wav->smv_frames_per_jpeg > 0) - wav->smv_cur_pt %= wav->smv_frames_per_jpeg; - if (!wav->smv_cur_pt) - wav->smv_block++; + pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg; + pkt->duration = wav->smv_frames_per_jpeg; + wav->smv_block++; pkt->stream_index = 1; smv_out: @@ -701,7 +762,7 @@ smv_out: wav->data_end = avio_tell(s->pb) + left; } - size = MAX_SIZE; + size = wav->max_size; if (st->codecpar->block_align > 1) { if (size < st->codecpar->block_align) size = st->codecpar->block_align; @@ -731,7 +792,6 @@ static int wav_read_seek(AVFormatContext *s, timestamp = av_rescale_q(smv_timestamp, s->streams[1]->time_base, s->streams[0]->time_base); if (wav->smv_frames_per_jpeg > 0) { wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg; - wav->smv_cur_pt = smv_timestamp % wav->smv_frames_per_jpeg; } } @@ -750,13 +810,6 @@ static int wav_read_seek(AVFormatContext *s, return ff_pcm_read_seek(s, stream_index, timestamp, flags); } -#define OFFSET(x) offsetof(WAVDemuxContext, x) -#define DEC AV_OPT_FLAG_DECODING_PARAM -static const AVOption demux_options[] = { - { "ignore_length", "Ignore length", OFFSET(ignore_length), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC }, - { NULL }, -}; - static const AVClass wav_demuxer_class = { .class_name = "WAV demuxer", .item_name = av_default_item_name, @@ -772,7 +825,7 @@ AVInputFormat ff_wav_demuxer = { .read_packet = wav_read_packet, .read_seek = wav_read_seek, .flags = AVFMT_GENERIC_INDEX, - .codec_tag = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 }, + .codec_tag = ff_wav_codec_tags_list, .priv_class = &wav_demuxer_class, }; #endif /* CONFIG_WAV_DEMUXER */ @@ -869,7 +922,7 @@ static int w64_read_header(AVFormatContext *s) if (chunk_size == UINT32_MAX || (filesize >= 0 && chunk_size > filesize)) return AVERROR_INVALIDDATA; - value = av_mallocz(chunk_size + 1); + value = av_malloc(chunk_size + 1); if (!value) return AVERROR(ENOMEM); @@ -906,6 +959,13 @@ static int w64_read_header(AVFormatContext *s) return 0; } +static const AVClass w64_demuxer_class = { + .class_name = "W64 demuxer", + .item_name = av_default_item_name, + .option = &demux_options[W64_DEMUXER_OPTIONS_OFFSET], + .version = LIBAVUTIL_VERSION_INT, +}; + AVInputFormat ff_w64_demuxer = { .name = "w64", .long_name = NULL_IF_CONFIG_SMALL("Sony Wave64"), @@ -915,6 +975,7 @@ AVInputFormat ff_w64_demuxer = { .read_packet = wav_read_packet, .read_seek = wav_read_seek, .flags = AVFMT_GENERIC_INDEX, - .codec_tag = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 }, + .codec_tag = ff_wav_codec_tags_list, + .priv_class = &w64_demuxer_class, }; #endif /* CONFIG_W64_DEMUXER */ diff --git a/libavformat/wavenc.c b/libavformat/wavenc.c index 1027f107e..563a30d00 100644 --- a/libavformat/wavenc.c +++ b/libavformat/wavenc.c @@ -50,8 +50,6 @@ #define RF64_NEVER 0 #define RF64_ALWAYS 1 -#define PEAK_BUFFER_SIZE 1024 - typedef enum { PEAK_OFF = 0, PEAK_ON, @@ -72,8 +70,9 @@ typedef struct WAVMuxContext { int64_t maxpts; int16_t *peak_maxpos, *peak_maxneg; uint32_t peak_num_frames; - uint32_t peak_outbuf_size; + unsigned peak_outbuf_size; uint32_t peak_outbuf_bytes; + unsigned size_increment; uint8_t *peak_output; int last_duration; int write_bext; @@ -159,9 +158,8 @@ static av_cold int peak_init_writer(AVFormatContext *s) par->codec_id != AV_CODEC_ID_PCM_S16LE && par->codec_id != AV_CODEC_ID_PCM_U8 && par->codec_id != AV_CODEC_ID_PCM_U16LE) { - AVCodec *codec = avcodec_find_decoder(s->streams[0]->codecpar->codec_id); - av_log(s, AV_LOG_ERROR, "%s codec not supported for Peak Chunk\n", - codec ? codec->name : "NONE"); + av_log(s, AV_LOG_ERROR, "Codec %s not supported for Peak Chunk\n", + avcodec_get_name(par->codec_id)); return -1; } @@ -172,15 +170,15 @@ static av_cold int peak_init_writer(AVFormatContext *s) "Writing 16 bit peak for 8 bit audio does not make sense\n"); return AVERROR(EINVAL); } + if (par->channels > INT_MAX / (wav->peak_bps * wav->peak_ppv)) + return AVERROR(ERANGE); + wav->size_increment = par->channels * wav->peak_bps * wav->peak_ppv; wav->peak_maxpos = av_mallocz_array(par->channels, sizeof(*wav->peak_maxpos)); wav->peak_maxneg = av_mallocz_array(par->channels, sizeof(*wav->peak_maxneg)); - wav->peak_output = av_malloc(PEAK_BUFFER_SIZE); - if (!wav->peak_maxpos || !wav->peak_maxneg || !wav->peak_output) + if (!wav->peak_maxpos || !wav->peak_maxneg) goto nomem; - wav->peak_outbuf_size = PEAK_BUFFER_SIZE; - return 0; nomem: @@ -188,14 +186,24 @@ nomem: return AVERROR(ENOMEM); } -static void peak_write_frame(AVFormatContext *s) +static int peak_write_frame(AVFormatContext *s) { WAVMuxContext *wav = s->priv_data; AVCodecParameters *par = s->streams[0]->codecpar; + unsigned new_size = wav->peak_outbuf_bytes + wav->size_increment; + uint8_t *tmp; int c; - if (!wav->peak_output) - return; + if (new_size > INT_MAX) { + wav->write_peak = PEAK_OFF; + return AVERROR(ERANGE); + } + tmp = av_fast_realloc(wav->peak_output, &wav->peak_outbuf_size, new_size); + if (!tmp) { + wav->write_peak = PEAK_OFF; + return AVERROR(ENOMEM); + } + wav->peak_output = tmp; for (c = 0; c < par->channels; c++) { wav->peak_maxneg[c] = -wav->peak_maxneg[c]; @@ -209,17 +217,6 @@ static void peak_write_frame(AVFormatContext *s) wav->peak_maxpos[c] = FFMAX(wav->peak_maxpos[c], wav->peak_maxneg[c]); - if (wav->peak_outbuf_size - wav->peak_outbuf_bytes < - wav->peak_format * wav->peak_ppv) { - wav->peak_outbuf_size += PEAK_BUFFER_SIZE; - wav->peak_output = av_realloc(wav->peak_output, - wav->peak_outbuf_size); - if (!wav->peak_output) { - av_log(s, AV_LOG_ERROR, "No memory for peak data\n"); - return; - } - } - if (wav->peak_format == PEAK_FORMAT_UINT8) { wav->peak_output[wav->peak_outbuf_bytes++] = wav->peak_maxpos[c]; @@ -241,6 +238,8 @@ static void peak_write_frame(AVFormatContext *s) wav->peak_maxneg[c] = 0; } wav->peak_num_frames++; + + return 0; } static int peak_write_chunk(AVFormatContext *s) @@ -254,8 +253,11 @@ static int peak_write_chunk(AVFormatContext *s) char timestamp[28]; /* Peak frame of incomplete block at end */ - if (wav->peak_block_pos) - peak_write_frame(s); + if (wav->peak_block_pos) { + int ret = peak_write_frame(s); + if (ret < 0) + return ret; + } memset(timestamp, 0, sizeof(timestamp)); if (!(s->flags & AVFMT_FLAG_BITEXACT)) { @@ -325,9 +327,8 @@ static int wav_write_header(AVFormatContext *s) /* format header */ fmt = ff_start_tag(pb, "fmt "); if (ff_put_wav_header(s, pb, s->streams[0]->codecpar, 0) < 0) { - const AVCodecDescriptor *desc = avcodec_descriptor_get(s->streams[0]->codecpar->codec_id); - av_log(s, AV_LOG_ERROR, "%s codec not supported in WAVE format\n", - desc ? desc->name : "unknown"); + av_log(s, AV_LOG_ERROR, "Codec %s not supported in WAVE format\n", + avcodec_get_name(s->streams[0]->codecpar->codec_id)); return AVERROR(ENOSYS); } ff_end_tag(pb, fmt); @@ -386,7 +387,9 @@ static int wav_write_packet(AVFormatContext *s, AVPacket *pkt) if (++c == s->streams[0]->codecpar->channels) { c = 0; if (++wav->peak_block_pos == wav->peak_block_size) { - peak_write_frame(s); + int ret = peak_write_frame(s); + if (ret < 0) + return ret; wav->peak_block_pos = 0; } } @@ -514,7 +517,7 @@ AVOutputFormat ff_wav_muxer = { .write_trailer = wav_write_trailer, .deinit = wav_deinit, .flags = AVFMT_TS_NONSTRICT, - .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 }, + .codec_tag = ff_wav_codec_tags_list, .priv_class = &wav_muxer_class, }; #endif /* CONFIG_WAV_MUXER */ @@ -553,9 +556,8 @@ static int w64_write_header(AVFormatContext *s) avio_write(pb, ff_w64_guid_wave, sizeof(ff_w64_guid_wave)); start_guid(pb, ff_w64_guid_fmt, &start); if ((ret = ff_put_wav_header(s, pb, s->streams[0]->codecpar, 0)) < 0) { - AVCodec *codec = avcodec_find_decoder(s->streams[0]->codecpar->codec_id); - av_log(s, AV_LOG_ERROR, "%s codec not supported\n", - codec ? codec->name : "NONE"); + av_log(s, AV_LOG_ERROR, "Codec %s not supported\n", + avcodec_get_name(s->streams[0]->codecpar->codec_id)); return ret; } end_guid(pb, start); @@ -612,6 +614,6 @@ AVOutputFormat ff_w64_muxer = { .write_packet = wav_write_packet, .write_trailer = w64_write_trailer, .flags = AVFMT_TS_NONSTRICT, - .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 }, + .codec_tag = ff_wav_codec_tags_list, }; #endif /* CONFIG_W64_MUXER */ diff --git a/libavformat/wc3movie.c b/libavformat/wc3movie.c index 76e945d26..cd69931a4 100644 --- a/libavformat/wc3movie.c +++ b/libavformat/wc3movie.c @@ -69,7 +69,7 @@ typedef struct Wc3DemuxContext { int video_stream_index; int audio_stream_index; - AVPacket vpkt; + AVPacket *vpkt; } Wc3DemuxContext; @@ -77,8 +77,7 @@ static int wc3_read_close(AVFormatContext *s) { Wc3DemuxContext *wc3 = s->priv_data; - if (wc3->vpkt.size > 0) - av_packet_unref(&wc3->vpkt); + av_packet_free(&wc3->vpkt); return 0; } @@ -110,8 +109,9 @@ static int wc3_read_header(AVFormatContext *s) wc3->height = WC3_DEFAULT_HEIGHT; wc3->pts = 0; wc3->video_stream_index = wc3->audio_stream_index = 0; - av_init_packet(&wc3->vpkt); - wc3->vpkt.data = NULL; wc3->vpkt.size = 0; + wc3->vpkt = av_packet_alloc(); + if (!wc3->vpkt) + return AVERROR(ENOMEM); /* skip the first 3 32-bit numbers */ avio_skip(pb, 12); @@ -162,7 +162,7 @@ static int wc3_read_header(AVFormatContext *s) case PALT_TAG: /* one of several palettes */ avio_seek(pb, -8, SEEK_CUR); - av_append_packet(pb, &wc3->vpkt, 8 + PALETTE_SIZE); + av_append_packet(pb, wc3->vpkt, 8 + PALETTE_SIZE); break; default: @@ -248,18 +248,17 @@ static int wc3_read_packet(AVFormatContext *s, case SHOT_TAG: /* load up new palette */ avio_seek(pb, -8, SEEK_CUR); - av_append_packet(pb, &wc3->vpkt, 8 + 4); + av_append_packet(pb, wc3->vpkt, 8 + 4); break; case VGA__TAG: /* send out video chunk */ avio_seek(pb, -8, SEEK_CUR); - ret= av_append_packet(pb, &wc3->vpkt, 8 + size); + ret= av_append_packet(pb, wc3->vpkt, 8 + size); // ignore error if we have some data - if (wc3->vpkt.size > 0) + if (wc3->vpkt->size > 0) ret = 0; - *pkt = wc3->vpkt; - wc3->vpkt.data = NULL; wc3->vpkt.size = 0; + av_packet_move_ref(pkt, wc3->vpkt); pkt->stream_index = wc3->video_stream_index; pkt->pts = wc3->pts; packet_read = 1; diff --git a/libavformat/webmdashenc.c b/libavformat/webmdashenc.c index eb286cab9..1304c1a8c 100644 --- a/libavformat/webmdashenc.c +++ b/libavformat/webmdashenc.c @@ -79,19 +79,20 @@ static double get_duration(AVFormatContext *s) static int write_header(AVFormatContext *s) { WebMDashMuxContext *w = s->priv_data; + AVIOContext *pb = s->pb; double min_buffer_time = 1.0; - avio_printf(s->pb, "\n"); - avio_printf(s->pb, "pb, " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"); - avio_printf(s->pb, " xmlns=\"urn:mpeg:DASH:schema:MPD:2011\"\n"); - avio_printf(s->pb, " xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011\"\n"); - avio_printf(s->pb, " type=\"%s\"\n", w->is_live ? "dynamic" : "static"); + avio_printf(pb, "\n"); + avio_printf(pb, "is_live ? "dynamic" : "static"); if (!w->is_live) { - avio_printf(s->pb, " mediaPresentationDuration=\"PT%gS\"\n", + avio_printf(pb, " mediaPresentationDuration=\"PT%gS\"\n", get_duration(s)); } - avio_printf(s->pb, " minBufferTime=\"PT%gS\"\n", min_buffer_time); - avio_printf(s->pb, " profiles=\"%s\"%s", + avio_printf(pb, " minBufferTime=\"PT%gS\"\n", min_buffer_time); + avio_printf(pb, " profiles=\"%s\"%s", w->is_live ? "urn:mpeg:dash:profile:isoff-live:2011" : "urn:webm:dash:profile:webm-on-demand:2012", w->is_live ? "\n" : ">\n"); if (w->is_live) { @@ -105,14 +106,14 @@ static int write_header(AVFormatContext *s) if (s->flags & AVFMT_FLAG_BITEXACT) { av_strlcpy(gmt_iso, "", 1); } - avio_printf(s->pb, " availabilityStartTime=\"%s\"\n", gmt_iso); - avio_printf(s->pb, " timeShiftBufferDepth=\"PT%gS\"\n", w->time_shift_buffer_depth); - avio_printf(s->pb, " minimumUpdatePeriod=\"PT%dS\"", w->minimum_update_period); - avio_printf(s->pb, ">\n"); + avio_printf(pb, " availabilityStartTime=\"%s\"\n", gmt_iso); + avio_printf(pb, " timeShiftBufferDepth=\"PT%gS\"\n", w->time_shift_buffer_depth); + avio_printf(pb, " minimumUpdatePeriod=\"PT%dS\"", w->minimum_update_period); + avio_printf(pb, ">\n"); if (w->utc_timing_url) { - avio_printf(s->pb, "pb, " schemeIdUri=\"urn:mpeg:dash:utc:http-iso:2014\"\n"); - avio_printf(s->pb, " value=\"%s\"/>\n", w->utc_timing_url); + avio_printf(pb, "\n", w->utc_timing_url); } } return 0; @@ -123,7 +124,8 @@ static void write_footer(AVFormatContext *s) avio_printf(s->pb, "\n"); } -static int subsegment_alignment(AVFormatContext *s, AdaptationSet *as) { +static int subsegment_alignment(AVFormatContext *s, const AdaptationSet *as) +{ int i; AVDictionaryEntry *gold = av_dict_get(s->streams[as->streams[0]]->metadata, CUE_TIMESTAMPS, NULL, 0); @@ -131,26 +133,30 @@ static int subsegment_alignment(AVFormatContext *s, AdaptationSet *as) { for (i = 1; i < as->nb_streams; i++) { AVDictionaryEntry *ts = av_dict_get(s->streams[as->streams[i]]->metadata, CUE_TIMESTAMPS, NULL, 0); - if (!ts || strncmp(gold->value, ts->value, strlen(gold->value))) return 0; + if (!ts || !av_strstart(ts->value, gold->value, NULL)) return 0; } return 1; } -static int bitstream_switching(AVFormatContext *s, AdaptationSet *as) { +static int bitstream_switching(AVFormatContext *s, const AdaptationSet *as) +{ int i; - AVDictionaryEntry *gold_track_num = av_dict_get(s->streams[as->streams[0]]->metadata, + const AVStream *gold_st = s->streams[as->streams[0]]; + AVDictionaryEntry *gold_track_num = av_dict_get(gold_st->metadata, TRACK_NUMBER, NULL, 0); - AVCodecParameters *gold_par = s->streams[as->streams[0]]->codecpar; + AVCodecParameters *gold_par = gold_st->codecpar; if (!gold_track_num) return 0; for (i = 1; i < as->nb_streams; i++) { - AVDictionaryEntry *track_num = av_dict_get(s->streams[as->streams[i]]->metadata, + const AVStream *st = s->streams[as->streams[i]]; + AVDictionaryEntry *track_num = av_dict_get(st->metadata, TRACK_NUMBER, NULL, 0); - AVCodecParameters *par = s->streams[as->streams[i]]->codecpar; + AVCodecParameters *par = st->codecpar; if (!track_num || - strncmp(gold_track_num->value, track_num->value, strlen(gold_track_num->value)) || + !av_strstart(track_num->value, gold_track_num->value, NULL) || gold_par->codec_id != par->codec_id || gold_par->extradata_size != par->extradata_size || - memcmp(gold_par->extradata, par->extradata, par->extradata_size)) { + (par->extradata_size > 0 && + memcmp(gold_par->extradata, par->extradata, par->extradata_size))) { return 0; } } @@ -161,60 +167,65 @@ static int bitstream_switching(AVFormatContext *s, AdaptationSet *as) { * Writes a Representation within an Adaptation Set. Returns 0 on success and * < 0 on failure. */ -static int write_representation(AVFormatContext *s, AVStream *stream, char *id, +static int write_representation(AVFormatContext *s, AVStream *st, char *id, int output_width, int output_height, - int output_sample_rate) { + int output_sample_rate) +{ WebMDashMuxContext *w = s->priv_data; - AVDictionaryEntry *irange = av_dict_get(stream->metadata, INITIALIZATION_RANGE, NULL, 0); - AVDictionaryEntry *cues_start = av_dict_get(stream->metadata, CUES_START, NULL, 0); - AVDictionaryEntry *cues_end = av_dict_get(stream->metadata, CUES_END, NULL, 0); - AVDictionaryEntry *filename = av_dict_get(stream->metadata, FILENAME, NULL, 0); - AVDictionaryEntry *bandwidth = av_dict_get(stream->metadata, BANDWIDTH, NULL, 0); + AVIOContext *pb = s->pb; + const AVCodecParameters *par = st->codecpar; + AVDictionaryEntry *bandwidth = av_dict_get(st->metadata, BANDWIDTH, NULL, 0); const char *bandwidth_str; - if ((w->is_live && (!filename)) || - (!w->is_live && (!irange || !cues_start || !cues_end || !filename || !bandwidth))) { - return AVERROR_INVALIDDATA; - } - avio_printf(s->pb, "is_live && !bandwidth) { - bandwidth_str = (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ? "128000" : "1000000"; - } else { + avio_printf(pb, "value; + } else if (w->is_live) { + // if bandwidth for live was not provided, use a default + bandwidth_str = (par->codec_type == AVMEDIA_TYPE_AUDIO) ? "128000" : "1000000"; + } else { + return AVERROR(EINVAL); } - avio_printf(s->pb, " bandwidth=\"%s\"", bandwidth_str); - if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && output_width) - avio_printf(s->pb, " width=\"%d\"", stream->codecpar->width); - if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && output_height) - avio_printf(s->pb, " height=\"%d\"", stream->codecpar->height); - if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && output_sample_rate) - avio_printf(s->pb, " audioSamplingRate=\"%d\"", stream->codecpar->sample_rate); + avio_printf(pb, " bandwidth=\"%s\"", bandwidth_str); + if (par->codec_type == AVMEDIA_TYPE_VIDEO && output_width) + avio_printf(pb, " width=\"%d\"", par->width); + if (par->codec_type == AVMEDIA_TYPE_VIDEO && output_height) + avio_printf(pb, " height=\"%d\"", par->height); + if (par->codec_type == AVMEDIA_TYPE_AUDIO && output_sample_rate) + avio_printf(pb, " audioSamplingRate=\"%d\"", par->sample_rate); if (w->is_live) { // For live streams, Codec and Mime Type always go in the Representation tag. - avio_printf(s->pb, " codecs=\"%s\"", get_codec_name(stream->codecpar->codec_id)); - avio_printf(s->pb, " mimeType=\"%s/webm\"", - stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio"); + avio_printf(pb, " codecs=\"%s\"", get_codec_name(par->codec_id)); + avio_printf(pb, " mimeType=\"%s/webm\"", + par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio"); // For live streams, subsegments always start with key frames. So this // is always 1. - avio_printf(s->pb, " startsWithSAP=\"1\""); - avio_printf(s->pb, ">"); + avio_printf(pb, " startsWithSAP=\"1\""); + avio_printf(pb, ">"); } else { - avio_printf(s->pb, ">\n"); - avio_printf(s->pb, "%s\n", filename->value); - avio_printf(s->pb, "pb, " indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value); - avio_printf(s->pb, "pb, " range=\"0-%s\" />\n", irange->value); - avio_printf(s->pb, "\n"); + AVDictionaryEntry *irange = av_dict_get(st->metadata, INITIALIZATION_RANGE, NULL, 0); + AVDictionaryEntry *cues_start = av_dict_get(st->metadata, CUES_START, NULL, 0); + AVDictionaryEntry *cues_end = av_dict_get(st->metadata, CUES_END, NULL, 0); + AVDictionaryEntry *filename = av_dict_get(st->metadata, FILENAME, NULL, 0); + if (!irange || !cues_start || !cues_end || !filename) + return AVERROR(EINVAL); + + avio_printf(pb, ">\n"); + avio_printf(pb, "%s\n", filename->value); + avio_printf(pb, "\n", cues_start->value, cues_end->value); + avio_printf(pb, "\n", irange->value); + avio_printf(pb, "\n"); } - avio_printf(s->pb, "\n"); + avio_printf(pb, "\n"); return 0; } /* * Checks if width of all streams are the same. Returns 1 if true, 0 otherwise. */ -static int check_matching_width(AVFormatContext *s, AdaptationSet *as) { +static int check_matching_width(AVFormatContext *s, const AdaptationSet *as) +{ int first_width, i; if (as->nb_streams < 2) return 1; first_width = s->streams[as->streams[0]]->codecpar->width; @@ -227,7 +238,8 @@ static int check_matching_width(AVFormatContext *s, AdaptationSet *as) { /* * Checks if height of all streams are the same. Returns 1 if true, 0 otherwise. */ -static int check_matching_height(AVFormatContext *s, AdaptationSet *as) { +static int check_matching_height(AVFormatContext *s, const AdaptationSet *as) +{ int first_height, i; if (as->nb_streams < 2) return 1; first_height = s->streams[as->streams[0]]->codecpar->height; @@ -240,7 +252,8 @@ static int check_matching_height(AVFormatContext *s, AdaptationSet *as) { /* * Checks if sample rate of all streams are the same. Returns 1 if true, 0 otherwise. */ -static int check_matching_sample_rate(AVFormatContext *s, AdaptationSet *as) { +static int check_matching_sample_rate(AVFormatContext *s, const AdaptationSet *as) +{ int first_sample_rate, i; if (as->nb_streams < 2) return 1; first_sample_rate = s->streams[as->streams[0]]->codecpar->sample_rate; @@ -250,7 +263,8 @@ static int check_matching_sample_rate(AVFormatContext *s, AdaptationSet *as) { return 1; } -static void free_adaptation_sets(AVFormatContext *s) { +static void free_adaptation_sets(AVFormatContext *s) +{ WebMDashMuxContext *w = s->priv_data; int i; for (i = 0; i < w->nb_as; i++) { @@ -261,65 +275,24 @@ static void free_adaptation_sets(AVFormatContext *s) { } /* - * Parses a live header filename and computes the representation id, - * initialization pattern and the media pattern. Pass NULL if you don't want to - * compute any of those 3. Returns 0 on success and non-zero on failure. + * Parses a live header filename and returns the position of the '_' and '.' + * delimiting and . * * Name of the header file should conform to the following pattern: * _.hdr where can be * anything. The chunks should be named according to the following pattern: * __.chk */ -static int parse_filename(char *filename, char **representation_id, - char **initialization_pattern, char **media_pattern) { - char *underscore_pos = NULL; - char *period_pos = NULL; - char *filename_str = av_strdup(filename); - int ret = 0; - - if (!filename_str) { - ret = AVERROR(ENOMEM); - goto end; - } - underscore_pos = strrchr(filename_str, '_'); - if (!underscore_pos) { - ret = AVERROR_INVALIDDATA; - goto end; - } - period_pos = strchr(++underscore_pos, '.'); - if (!period_pos) { - ret = AVERROR_INVALIDDATA; - goto end; - } - *(underscore_pos - 1) = 0; - if (representation_id) { - *representation_id = av_malloc(period_pos - underscore_pos + 1); - if (!(*representation_id)) { - ret = AVERROR(ENOMEM); - goto end; - } - av_strlcpy(*representation_id, underscore_pos, period_pos - underscore_pos + 1); - } - if (initialization_pattern) { - *initialization_pattern = av_asprintf("%s_$RepresentationID$.hdr", - filename_str); - if (!(*initialization_pattern)) { - ret = AVERROR(ENOMEM); - goto end; - } - } - if (media_pattern) { - *media_pattern = av_asprintf("%s_$RepresentationID$_$Number$.chk", - filename_str); - if (!(*media_pattern)) { - ret = AVERROR(ENOMEM); - goto end; - } - } - -end: - av_freep(&filename_str); - return ret; +static int split_filename(char *filename, char **underscore_pos, + char **period_pos) +{ + *underscore_pos = strrchr(filename, '_'); + if (!*underscore_pos) + return AVERROR(EINVAL); + *period_pos = strchr(*underscore_pos, '.'); + if (!*period_pos) + return AVERROR(EINVAL); + return 0; } /* @@ -329,8 +302,10 @@ static int write_adaptation_set(AVFormatContext *s, int as_index) { WebMDashMuxContext *w = s->priv_data; AdaptationSet *as = &w->as[as_index]; - AVCodecParameters *par = s->streams[as->streams[0]]->codecpar; + const AVStream *st = s->streams[as->streams[0]]; + AVCodecParameters *par = st->codecpar; AVDictionaryEntry *lang; + AVIOContext *pb = s->pb; int i; static const char boolean[2][6] = { "false", "true" }; int subsegmentStartsWithSAP = 1; @@ -341,30 +316,31 @@ static int write_adaptation_set(AVFormatContext *s, int as_index) // in the Representation tag. int width_in_as = 1, height_in_as = 1, sample_rate_in_as = 1; if (par->codec_type == AVMEDIA_TYPE_VIDEO) { - width_in_as = !w->is_live && check_matching_width(s, as); + width_in_as = !w->is_live && check_matching_width (s, as); height_in_as = !w->is_live && check_matching_height(s, as); } else { sample_rate_in_as = !w->is_live && check_matching_sample_rate(s, as); } - avio_printf(s->pb, "id); - avio_printf(s->pb, " mimeType=\"%s/webm\"", + avio_printf(pb, "id); + avio_printf(pb, " mimeType=\"%s/webm\"", par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio"); - avio_printf(s->pb, " codecs=\"%s\"", get_codec_name(par->codec_id)); + avio_printf(pb, " codecs=\"%s\"", get_codec_name(par->codec_id)); - lang = av_dict_get(s->streams[as->streams[0]]->metadata, "language", NULL, 0); - if (lang) avio_printf(s->pb, " lang=\"%s\"", lang->value); + lang = av_dict_get(st->metadata, "language", NULL, 0); + if (lang) + avio_printf(pb, " lang=\"%s\"", lang->value); if (par->codec_type == AVMEDIA_TYPE_VIDEO && width_in_as) - avio_printf(s->pb, " width=\"%d\"", par->width); + avio_printf(pb, " width=\"%d\"", par->width); if (par->codec_type == AVMEDIA_TYPE_VIDEO && height_in_as) - avio_printf(s->pb, " height=\"%d\"", par->height); + avio_printf(pb, " height=\"%d\"", par->height); if (par->codec_type == AVMEDIA_TYPE_AUDIO && sample_rate_in_as) - avio_printf(s->pb, " audioSamplingRate=\"%d\"", par->sample_rate); + avio_printf(pb, " audioSamplingRate=\"%d\"", par->sample_rate); - avio_printf(s->pb, " bitstreamSwitching=\"%s\"", + avio_printf(pb, " bitstreamSwitching=\"%s\"", boolean[bitstream_switching(s, as)]); - avio_printf(s->pb, " subsegmentAlignment=\"%s\"", + avio_printf(pb, " subsegmentAlignment=\"%s\"", boolean[w->is_live || subsegment_alignment(s, as)]); for (i = 0; i < as->nb_streams; i++) { @@ -372,49 +348,55 @@ static int write_adaptation_set(AVFormatContext *s, int as_index) CLUSTER_KEYFRAME, NULL, 0); if (!w->is_live && (!kf || !strncmp(kf->value, "0", 1))) subsegmentStartsWithSAP = 0; } - avio_printf(s->pb, " subsegmentStartsWithSAP=\"%d\"", subsegmentStartsWithSAP); - avio_printf(s->pb, ">\n"); + avio_printf(pb, " subsegmentStartsWithSAP=\"%d\"", subsegmentStartsWithSAP); + avio_printf(pb, ">\n"); if (w->is_live) { AVDictionaryEntry *filename = - av_dict_get(s->streams[as->streams[0]]->metadata, FILENAME, NULL, 0); - char *initialization_pattern = NULL; - char *media_pattern = NULL; - int ret = parse_filename(filename->value, NULL, &initialization_pattern, - &media_pattern); + av_dict_get(st->metadata, FILENAME, NULL, 0); + char *underscore_pos, *period_pos; + int ret; + if (!filename) + return AVERROR(EINVAL); + ret = split_filename(filename->value, &underscore_pos, &period_pos); if (ret) return ret; - avio_printf(s->pb, "\n", + *underscore_pos = '\0'; + avio_printf(pb, "\n", par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio"); - avio_printf(s->pb, "pb, " timescale=\"1000\""); - avio_printf(s->pb, " duration=\"%d\"", w->chunk_duration); - avio_printf(s->pb, " media=\"%s\"", media_pattern); - avio_printf(s->pb, " startNumber=\"%d\"", w->chunk_start_index); - avio_printf(s->pb, " initialization=\"%s\"", initialization_pattern); - avio_printf(s->pb, "/>\n"); - av_free(initialization_pattern); - av_free(media_pattern); + avio_printf(pb, "chunk_duration); + avio_printf(pb, " media=\"%s_$RepresentationID$_$Number$.chk\"", + filename->value); + avio_printf(pb, " startNumber=\"%d\"", w->chunk_start_index); + avio_printf(pb, " initialization=\"%s_$RepresentationID$.hdr\"", + filename->value); + avio_printf(pb, "/>\n"); + *underscore_pos = '_'; } for (i = 0; i < as->nb_streams; i++) { - char *representation_id = NULL; + char buf[25], *representation_id = buf, *underscore_pos, *period_pos; + AVStream *st = s->streams[as->streams[i]]; int ret; if (w->is_live) { AVDictionaryEntry *filename = - av_dict_get(s->streams[as->streams[i]]->metadata, FILENAME, NULL, 0); + av_dict_get(st->metadata, FILENAME, NULL, 0); if (!filename) return AVERROR(EINVAL); - if (ret = parse_filename(filename->value, &representation_id, NULL, NULL)) + ret = split_filename(filename->value, &underscore_pos, &period_pos); + if (ret < 0) return ret; + representation_id = underscore_pos + 1; + *period_pos = '\0'; } else { - representation_id = av_asprintf("%d", w->representation_id++); - if (!representation_id) return AVERROR(ENOMEM); + snprintf(buf, sizeof(buf), "%d", w->representation_id++); } - ret = write_representation(s, s->streams[as->streams[i]], - representation_id, !width_in_as, + ret = write_representation(s, st, representation_id, !width_in_as, !height_in_as, !sample_rate_in_as); - av_free(representation_id); if (ret) return ret; + if (w->is_live) + *period_pos = '.'; } avio_printf(s->pb, "\n"); return 0; diff --git a/libavformat/webpenc.c b/libavformat/webpenc.c index 9fb472257..99aa23bad 100644 --- a/libavformat/webpenc.c +++ b/libavformat/webpenc.c @@ -53,24 +53,22 @@ static int webp_write_header(AVFormatContext *s) static int is_animated_webp_packet(AVPacket *pkt) { - if (pkt->size) { int skip = 0; unsigned flags = 0; if (pkt->size < 4) - return 0; + return AVERROR_INVALIDDATA; if (AV_RL32(pkt->data) == AV_RL32("RIFF")) skip = 12; - + // Safe to do this as a valid WebP bitstream is >=30 bytes. if (pkt->size < skip + 4) - return 0; + return AVERROR_INVALIDDATA; if (AV_RL32(pkt->data + skip) == AV_RL32("VP8X")) { flags |= pkt->data[skip + 4 + 4]; } if (flags & 2) // ANIMATION_FLAG is on return 1; - } return 0; } @@ -84,13 +82,9 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) unsigned flags = 0; int vp8x = 0; - if (w->last_pkt.size < 4) - return 0; if (AV_RL32(w->last_pkt.data) == AV_RL32("RIFF")) skip = 12; - if (w->last_pkt.size < skip + 4) - return 0; // Safe to do this as a valid WebP bitstream is >=30 bytes. if (AV_RL32(w->last_pkt.data + skip) == AV_RL32("VP8X")) { flags |= w->last_pkt.data[skip + 4 + 4]; vp8x = 1; @@ -149,7 +143,14 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) static int webp_write_packet(AVFormatContext *s, AVPacket *pkt) { WebpContext *w = s->priv_data; - w->using_webp_anim_encoder |= is_animated_webp_packet(pkt); + int ret; + + if (!pkt->size) + return 0; + ret = is_animated_webp_packet(pkt); + if (ret < 0) + return ret; + w->using_webp_anim_encoder |= ret; if (w->using_webp_anim_encoder) { avio_write(s->pb, pkt->data, pkt->size); @@ -190,6 +191,13 @@ static int webp_write_trailer(AVFormatContext *s) return 0; } +static void webp_deinit(AVFormatContext *s) +{ + WebpContext *w = s->priv_data; + + av_packet_unref(&w->last_pkt); +} + #define OFFSET(x) offsetof(WebpContext, x) #define ENC AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { @@ -213,6 +221,7 @@ AVOutputFormat ff_webp_muxer = { .write_header = webp_write_header, .write_packet = webp_write_packet, .write_trailer = webp_write_trailer, + .deinit = webp_deinit, .priv_class = &webp_muxer_class, .flags = AVFMT_VARIABLE_FPS, }; diff --git a/libavformat/webvttdec.c b/libavformat/webvttdec.c index bd3d45b38..8d2fdfed3 100644 --- a/libavformat/webvttdec.c +++ b/libavformat/webvttdec.c @@ -125,7 +125,7 @@ static int webvtt_read_header(AVFormatContext *s) break; /* optional cue settings */ - p += strcspn(p, "\n\t "); + p += strcspn(p, "\n\r\t "); while (*p == '\t' || *p == ' ') p++; settings = p; diff --git a/libavformat/webvttenc.c b/libavformat/webvttenc.c index cbd989dcb..552bc38b6 100644 --- a/libavformat/webvttenc.c +++ b/libavformat/webvttenc.c @@ -64,7 +64,7 @@ static int webvtt_write_header(AVFormatContext *ctx) static int webvtt_write_packet(AVFormatContext *ctx, AVPacket *pkt) { AVIOContext *pb = ctx->pb; - int id_size, settings_size; + buffer_size_t id_size, settings_size; uint8_t *id, *settings; avio_printf(pb, "\n"); diff --git a/libavformat/wsddec.c b/libavformat/wsddec.c index 2313b0ec4..74db6acda 100644 --- a/libavformat/wsddec.c +++ b/libavformat/wsddec.c @@ -120,7 +120,7 @@ static int wsd_read_header(AVFormatContext *s) } avio_skip(pb, 4); - av_timecode_make_smpte_tc_string(playback_time, avio_rb32(pb), 0); + av_timecode_make_smpte_tc_string2(playback_time, (AVRational){1,1}, avio_rb32(pb) & 0x00ffffffU, 1, 1); av_dict_set(&s->metadata, "playback_time", playback_time, 0); st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c index aa6ff78c4..4b3b7fb40 100644 --- a/libavformat/wtvdec.c +++ b/libavformat/wtvdec.c @@ -817,6 +817,8 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p avio_skip(pb, 12); ff_get_guid(pb, &formattype); size = avio_rl32(pb); + if (size < 0 || size > INT_MAX - 92) + return AVERROR_INVALIDDATA; parse_media_type(s, 0, sid, mediatype, subtype, formattype, size); consumed += 92 + size; } @@ -831,6 +833,8 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p avio_skip(pb, 12); ff_get_guid(pb, &formattype); size = avio_rl32(pb); + if (size < 0 || size > INT_MAX - 76) + return AVERROR_INVALIDDATA; parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size); consumed += 76 + size; } @@ -953,6 +957,9 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p } else av_log(s, AV_LOG_WARNING, "unsupported chunk:"FF_PRI_GUID"\n", FF_ARG_GUID(g)); + if (avio_feof(pb)) + break; + avio_skip(pb, WTV_PAD8(len) - consumed); } return AVERROR_EOF; diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c index 498bc6401..24fdbe109 100644 --- a/libavformat/wtvenc.c +++ b/libavformat/wtvenc.c @@ -241,7 +241,7 @@ static void put_videoinfoheader2(AVIOContext *pb, AVStream *st) avio_wl32(pb, 0); avio_wl32(pb, 0); - ff_put_bmp_header(pb, st->codecpar, 0, 1); + ff_put_bmp_header(pb, st->codecpar, 0, 1, 0); if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO) { int padding = (st->codecpar->extradata_size & 3) ? 4 - (st->codecpar->extradata_size & 3) : 0; @@ -839,6 +839,5 @@ AVOutputFormat ff_wtv_muxer = { .write_header = write_header, .write_packet = write_packet, .write_trailer = write_trailer, - .codec_tag = (const AVCodecTag* const []){ ff_codec_bmp_tags, - ff_codec_wav_tags, 0 }, + .codec_tag = ff_riff_codec_tags_list, }; diff --git a/libavformat/yuv4mpegenc.c b/libavformat/yuv4mpegenc.c index e84dbf956..6b53780ba 100644 --- a/libavformat/yuv4mpegenc.c +++ b/libavformat/yuv4mpegenc.c @@ -24,13 +24,12 @@ #include "internal.h" #include "yuv4mpeg.h" -#define Y4M_LINE_MAX 256 - -static int yuv4_generate_header(AVFormatContext *s, char* buf) +static int yuv4_write_header(AVFormatContext *s) { AVStream *st; + AVIOContext *pb = s->pb; int width, height; - int raten, rated, aspectn, aspectd, n; + int raten, rated, aspectn, aspectd, ret; char inter; const char *colorspace = ""; const char *colorrange = ""; @@ -168,12 +167,16 @@ static int yuv4_generate_header(AVFormatContext *s, char* buf) break; } - /* construct stream header, if this is the first frame */ - n = snprintf(buf, Y4M_LINE_MAX, "%s W%d H%d F%d:%d I%c A%d:%d%s%s\n", - Y4M_MAGIC, width, height, raten, rated, inter, - aspectn, aspectd, colorspace, colorrange); + ret = avio_printf(pb, Y4M_MAGIC " W%d H%d F%d:%d I%c A%d:%d%s%s\n", + width, height, raten, rated, inter, + aspectn, aspectd, colorspace, colorrange); + if (ret < 0) { + av_log(s, AV_LOG_ERROR, + "Error. YUV4MPEG stream header write failed.\n"); + return ret; + } - return n; + return 0; } @@ -181,30 +184,14 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt) { AVStream *st = s->streams[pkt->stream_index]; AVIOContext *pb = s->pb; - AVFrame *frame; - int* first_pkt = s->priv_data; + const AVFrame *frame = (const AVFrame *)pkt->data; int width, height, h_chroma_shift, v_chroma_shift; int i; - char buf2[Y4M_LINE_MAX + 1]; - uint8_t *ptr, *ptr1, *ptr2; - - frame = (AVFrame *)pkt->data; - - /* for the first packet we have to output the header as well */ - if (*first_pkt) { - *first_pkt = 0; - if (yuv4_generate_header(s, buf2) < 0) { - av_log(s, AV_LOG_ERROR, - "Error. YUV4MPEG stream header write failed.\n"); - return AVERROR(EIO); - } else { - avio_write(pb, buf2, strlen(buf2)); - } - } + const uint8_t *ptr, *ptr1, *ptr2; /* construct frame header */ - avio_printf(s->pb, "%s\n", Y4M_FRAME_MAGIC); + avio_printf(s->pb, Y4M_FRAME_MAGIC "\n"); width = st->codecpar->width; height = st->codecpar->height; @@ -279,10 +266,8 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt) return 0; } -static int yuv4_write_header(AVFormatContext *s) +static int yuv4_init(AVFormatContext *s) { - int *first_pkt = s->priv_data; - if (s->nb_streams != 1) return AVERROR(EIO); @@ -347,7 +332,6 @@ static int yuv4_write_header(AVFormatContext *s) return AVERROR(EIO); } - *first_pkt = 1; return 0; } @@ -355,9 +339,9 @@ AVOutputFormat ff_yuv4mpegpipe_muxer = { .name = "yuv4mpegpipe", .long_name = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"), .extensions = "y4m", - .priv_data_size = sizeof(int), .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, + .init = yuv4_init, .write_header = yuv4_write_header, .write_packet = yuv4_write_packet, }; diff --git a/libavutil/Makefile b/libavutil/Makefile index 9b08372eb..27bafe9e1 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -84,6 +84,7 @@ HEADERS = adler32.h \ xtea.h \ tea.h \ tx.h \ + film_grain_params.h \ HEADERS-$(CONFIG_LZO) += lzo.h @@ -170,6 +171,7 @@ OBJS = adler32.o \ tx_double.o \ tx_int32.o \ video_enc_params.o \ + film_grain_params.o \ OBJS-$(CONFIG_CUDA) += hwcontext_cuda.o diff --git a/libavutil/aarch64/timer.h b/libavutil/aarch64/timer.h index b57003941..8b28fd354 100644 --- a/libavutil/aarch64/timer.h +++ b/libavutil/aarch64/timer.h @@ -24,7 +24,13 @@ #include #include "config.h" -#if HAVE_INLINE_ASM +#if defined(__APPLE__) + +#include + +#define AV_READ_TIME mach_absolute_time + +#elif HAVE_INLINE_ASM #define AV_READ_TIME read_time diff --git a/libavutil/adler32.c b/libavutil/adler32.c index c87d5e261..5ed5ff55a 100644 --- a/libavutil/adler32.c +++ b/libavutil/adler32.c @@ -41,8 +41,12 @@ #define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(buf); #define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf); +#if FF_API_CRYPTO_SIZE_T unsigned long av_adler32_update(unsigned long adler, const uint8_t * buf, unsigned int len) +#else +AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, size_t len) +#endif { unsigned long s1 = adler & 0xffff; unsigned long s2 = adler >> 16; diff --git a/libavutil/adler32.h b/libavutil/adler32.h index a1f035b73..e7a8f8372 100644 --- a/libavutil/adler32.h +++ b/libavutil/adler32.h @@ -27,8 +27,10 @@ #ifndef AVUTIL_ADLER32_H #define AVUTIL_ADLER32_H +#include #include #include "attributes.h" +#include "version.h" /** * @defgroup lavu_adler32 Adler-32 @@ -38,6 +40,12 @@ * @{ */ +#if FF_API_CRYPTO_SIZE_T +typedef unsigned long AVAdler; +#else +typedef uint32_t AVAdler; +#endif + /** * Calculate the Adler32 checksum of a buffer. * @@ -50,8 +58,12 @@ * @param len size of input buffer * @return updated checksum */ -unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, - unsigned int len) av_pure; +AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, +#if FF_API_CRYPTO_SIZE_T + unsigned int len) av_pure; +#else + size_t len) av_pure; +#endif /** * @} diff --git a/libavutil/aes_internal.h b/libavutil/aes_internal.h index 494425878..c9d6c2485 100644 --- a/libavutil/aes_internal.h +++ b/libavutil/aes_internal.h @@ -1,5 +1,5 @@ /* - * copyright (c) 2015 Rodger Combs + * copyright (c) 2015 rcombs * * This file is part of FFmpeg. * @@ -21,7 +21,7 @@ #ifndef AVUTIL_AES_INTERNAL_H #define AVUTIL_AES_INTERNAL_H -#include "mem.h" +#include "mem_internal.h" #include typedef union { diff --git a/libavutil/arm/timer.h b/libavutil/arm/timer.h index 5e8bc8edd..caf23e2a5 100644 --- a/libavutil/arm/timer.h +++ b/libavutil/arm/timer.h @@ -24,7 +24,13 @@ #include #include "config.h" -#if HAVE_INLINE_ASM && defined(__ARM_ARCH_7A__) +#if defined(__APPLE__) + +#include + +#define AV_READ_TIME mach_absolute_time + +#elif HAVE_INLINE_ASM && defined(__ARM_ARCH_7A__) #define AV_READ_TIME read_time diff --git a/libavutil/avsscanf.c b/libavutil/avsscanf.c index 850c11794..b7f0f71c2 100644 --- a/libavutil/avsscanf.c +++ b/libavutil/avsscanf.c @@ -113,7 +113,7 @@ static int ffshgetc(FFFILE *f) } #define shlim(f, lim) ffshlim((f), (lim)) -#define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : ffshgetc(f)) +#define shgetc(f) (((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc(f)) #define shunget(f) ((f)->shend ? (void)(f)->rpos-- : (void)0) static const unsigned char table[] = { -1, diff --git a/libavutil/avstring.c b/libavutil/avstring.c index f4b8ed2b4..49e8df55a 100644 --- a/libavutil/avstring.c +++ b/libavutil/avstring.c @@ -136,6 +136,7 @@ end: return p; } +#if FF_API_D2STR char *av_d2str(double d) { char *str = av_malloc(16); @@ -143,6 +144,7 @@ char *av_d2str(double d) snprintf(str, 16, "%f", d); return str; } +#endif #define WHITESPACES " \n\t\r" @@ -334,17 +336,18 @@ int av_escape(char **dst, const char *src, const char *special_chars, enum AVEscapeMode mode, int flags) { AVBPrint dstbuf; + int ret; - av_bprint_init(&dstbuf, 1, AV_BPRINT_SIZE_UNLIMITED); + av_bprint_init(&dstbuf, 1, INT_MAX); /* (int)dstbuf.len must be >= 0 */ av_bprint_escape(&dstbuf, src, special_chars, mode, flags); if (!av_bprint_is_complete(&dstbuf)) { av_bprint_finalize(&dstbuf, NULL); return AVERROR(ENOMEM); - } else { - av_bprint_finalize(&dstbuf, dst); - return dstbuf.len; } + if ((ret = av_bprint_finalize(&dstbuf, dst)) < 0) + return ret; + return dstbuf.len; } int av_match_name(const char *name, const char *names) diff --git a/libavutil/avstring.h b/libavutil/avstring.h index 274335cfb..fae446c30 100644 --- a/libavutil/avstring.h +++ b/libavutil/avstring.h @@ -24,6 +24,7 @@ #include #include #include "attributes.h" +#include "version.h" /** * @addtogroup lavu_string @@ -155,10 +156,14 @@ static inline size_t av_strnlen(const char *s, size_t len) */ char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2); +#if FF_API_D2STR /** * Convert a number to an av_malloced string. + * @deprecated use av_asprintf() with "%f" or a more specific format */ +attribute_deprecated char *av_d2str(double d); +#endif /** * Unescape the given string until a non escaped terminating char, @@ -319,6 +324,7 @@ enum AVEscapeMode { AV_ESCAPE_MODE_AUTO, ///< Use auto-selected escaping mode. AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping. AV_ESCAPE_MODE_QUOTE, ///< Use single-quote escaping. + AV_ESCAPE_MODE_XML, ///< Use XML non-markup character data escaping. }; /** @@ -338,6 +344,19 @@ enum AVEscapeMode { */ #define AV_ESCAPE_FLAG_STRICT (1 << 1) +/** + * Within AV_ESCAPE_MODE_XML, additionally escape single quotes for single + * quoted attributes. + */ +#define AV_ESCAPE_FLAG_XML_SINGLE_QUOTES (1 << 2) + +/** + * Within AV_ESCAPE_MODE_XML, additionally escape double quotes for double + * quoted attributes. + */ +#define AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES (1 << 3) + + /** * Escape string in src, and put the escaped string in an allocated * string in *dst, which must be freed with av_free(). diff --git a/libavutil/base64.c b/libavutil/base64.c index 25ae8c411..a1316b943 100644 --- a/libavutil/base64.c +++ b/libavutil/base64.c @@ -79,12 +79,16 @@ static const uint8_t map2[256] = int av_base64_decode(uint8_t *out, const char *in_str, int out_size) { uint8_t *dst = out; - uint8_t *end = out + out_size; + uint8_t *end; // no sign extension const uint8_t *in = in_str; unsigned bits = 0xff; unsigned v; + if (!out) + goto validity_check; + + end = out + out_size; while (end - dst > 3) { BASE64_DEC_STEP(0); BASE64_DEC_STEP(1); @@ -108,6 +112,7 @@ int av_base64_decode(uint8_t *out, const char *in_str, int out_size) *dst++ = v; in += 4; } +validity_check: while (1) { BASE64_DEC_STEP(0); in++; @@ -126,7 +131,7 @@ out2: *dst++ = v >> 4; out1: out0: - return bits & 1 ? AVERROR_INVALIDDATA : dst - out; + return bits & 1 ? AVERROR_INVALIDDATA : out ? dst - out : 0; } /***************************************************************************** diff --git a/libavutil/bprint.c b/libavutil/bprint.c index 2f059c5ba..e12fb263f 100644 --- a/libavutil/bprint.c +++ b/libavutil/bprint.c @@ -283,6 +283,35 @@ void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_cha av_bprint_chars(dstbuf, '\'', 1); break; + case AV_ESCAPE_MODE_XML: + /* escape XML non-markup character data as per 2.4 by default: */ + /* [^<&]* - ([^<&]* ']]>' [^<&]*) */ + + /* additionally, given one of the AV_ESCAPE_FLAG_XML_* flags, */ + /* escape those specific characters as required. */ + for (; *src; src++) { + switch (*src) { + case '&' : av_bprintf(dstbuf, "%s", "&"); break; + case '<' : av_bprintf(dstbuf, "%s", "<"); break; + case '>' : av_bprintf(dstbuf, "%s", ">"); break; + case '\'': + if (!(flags & AV_ESCAPE_FLAG_XML_SINGLE_QUOTES)) + goto XML_DEFAULT_HANDLING; + + av_bprintf(dstbuf, "%s", "'"); + break; + case '"' : + if (!(flags & AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES)) + goto XML_DEFAULT_HANDLING; + + av_bprintf(dstbuf, "%s", """); + break; +XML_DEFAULT_HANDLING: + default: av_bprint_chars(dstbuf, *src, 1); + } + } + break; + /* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */ default: /* \-escape characters */ diff --git a/libavutil/buffer.c b/libavutil/buffer.c index 38a554208..858633e8c 100644 --- a/libavutil/buffer.c +++ b/libavutil/buffer.c @@ -26,7 +26,7 @@ #include "mem.h" #include "thread.h" -AVBufferRef *av_buffer_create(uint8_t *data, int size, +AVBufferRef *av_buffer_create(uint8_t *data, buffer_size_t size, void (*free)(void *opaque, uint8_t *data), void *opaque, int flags) { @@ -64,7 +64,7 @@ void av_buffer_default_free(void *opaque, uint8_t *data) av_free(data); } -AVBufferRef *av_buffer_alloc(int size) +AVBufferRef *av_buffer_alloc(buffer_size_t size) { AVBufferRef *ret = NULL; uint8_t *data = NULL; @@ -80,7 +80,7 @@ AVBufferRef *av_buffer_alloc(int size) return ret; } -AVBufferRef *av_buffer_allocz(int size) +AVBufferRef *av_buffer_allocz(buffer_size_t size) { AVBufferRef *ret = av_buffer_alloc(size); if (!ret) @@ -166,10 +166,11 @@ int av_buffer_make_writable(AVBufferRef **pbuf) return 0; } -int av_buffer_realloc(AVBufferRef **pbuf, int size) +int av_buffer_realloc(AVBufferRef **pbuf, buffer_size_t size) { AVBufferRef *buf = *pbuf; uint8_t *tmp; + int ret; if (!buf) { /* allocate a new buffer with av_realloc(), so it will be reallocatable @@ -196,9 +197,9 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size) /* cannot realloc, allocate a new reallocable buffer and copy data */ AVBufferRef *new = NULL; - av_buffer_realloc(&new, size); - if (!new) - return AVERROR(ENOMEM); + ret = av_buffer_realloc(&new, size); + if (ret < 0) + return ret; memcpy(new->data, buf->data, FFMIN(size, buf->size)); @@ -215,8 +216,34 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size) return 0; } -AVBufferPool *av_buffer_pool_init2(int size, void *opaque, - AVBufferRef* (*alloc)(void *opaque, int size), +int av_buffer_replace(AVBufferRef **pdst, AVBufferRef *src) +{ + AVBufferRef *dst = *pdst; + AVBufferRef *tmp; + + if (!src) { + av_buffer_unref(pdst); + return 0; + } + + if (dst && dst->buffer == src->buffer) { + /* make sure the data pointers match */ + dst->data = src->data; + dst->size = src->size; + return 0; + } + + tmp = av_buffer_ref(src); + if (!tmp) + return AVERROR(ENOMEM); + + av_buffer_unref(pdst); + *pdst = tmp; + return 0; +} + +AVBufferPool *av_buffer_pool_init2(buffer_size_t size, void *opaque, + AVBufferRef* (*alloc)(void *opaque, buffer_size_t size), void (*pool_free)(void *opaque)) { AVBufferPool *pool = av_mallocz(sizeof(*pool)); @@ -236,7 +263,7 @@ AVBufferPool *av_buffer_pool_init2(int size, void *opaque, return pool; } -AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)) +AVBufferPool *av_buffer_pool_init(buffer_size_t size, AVBufferRef* (*alloc)(buffer_size_t size)) { AVBufferPool *pool = av_mallocz(sizeof(*pool)); if (!pool) @@ -252,11 +279,7 @@ AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)) return pool; } -/* - * This function gets called when the pool has been uninited and - * all the buffers returned to it. - */ -static void buffer_pool_free(AVBufferPool *pool) +static void buffer_pool_flush(AVBufferPool *pool) { while (pool->pool) { BufferPoolEntry *buf = pool->pool; @@ -265,6 +288,15 @@ static void buffer_pool_free(AVBufferPool *pool) buf->free(buf->opaque, buf->data); av_freep(&buf); } +} + +/* + * This function gets called when the pool has been uninited and + * all the buffers returned to it. + */ +static void buffer_pool_free(AVBufferPool *pool) +{ + buffer_pool_flush(pool); ff_mutex_destroy(&pool->mutex); if (pool->pool_free) @@ -282,6 +314,10 @@ void av_buffer_pool_uninit(AVBufferPool **ppool) pool = *ppool; *ppool = NULL; + ff_mutex_lock(&pool->mutex); + buffer_pool_flush(pool); + ff_mutex_unlock(&pool->mutex); + if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1) buffer_pool_free(pool); } diff --git a/libavutil/buffer.h b/libavutil/buffer.h index c0f3f6cc9..241a80ed6 100644 --- a/libavutil/buffer.h +++ b/libavutil/buffer.h @@ -25,8 +25,11 @@ #ifndef AVUTIL_BUFFER_H #define AVUTIL_BUFFER_H +#include #include +#include "version.h" + /** * @defgroup lavu_buffer AVBuffer * @ingroup lavu_data @@ -90,7 +93,11 @@ typedef struct AVBufferRef { /** * Size of data in bytes. */ +#if FF_API_BUFFER_SIZE_T int size; +#else + size_t size; +#endif } AVBufferRef; /** @@ -98,13 +105,21 @@ typedef struct AVBufferRef { * * @return an AVBufferRef of given size or NULL when out of memory */ +#if FF_API_BUFFER_SIZE_T AVBufferRef *av_buffer_alloc(int size); +#else +AVBufferRef *av_buffer_alloc(size_t size); +#endif /** * Same as av_buffer_alloc(), except the returned buffer will be initialized * to zero. */ +#if FF_API_BUFFER_SIZE_T AVBufferRef *av_buffer_allocz(int size); +#else +AVBufferRef *av_buffer_allocz(size_t size); +#endif /** * Always treat the buffer as read-only, even when it has only one @@ -127,7 +142,11 @@ AVBufferRef *av_buffer_allocz(int size); * * @return an AVBufferRef referring to data on success, NULL on failure. */ +#if FF_API_BUFFER_SIZE_T AVBufferRef *av_buffer_create(uint8_t *data, int size, +#else +AVBufferRef *av_buffer_create(uint8_t *data, size_t size, +#endif void (*free)(void *opaque, uint8_t *data), void *opaque, int flags); @@ -195,7 +214,27 @@ int av_buffer_make_writable(AVBufferRef **buf); * reference to it (i.e. the one passed to this function). In all other cases * a new buffer is allocated and the data is copied. */ +#if FF_API_BUFFER_SIZE_T int av_buffer_realloc(AVBufferRef **buf, int size); +#else +int av_buffer_realloc(AVBufferRef **buf, size_t size); +#endif + +/** + * Ensure dst refers to the same data as src. + * + * When *dst is already equivalent to src, do nothing. Otherwise unreference dst + * and replace it with a new reference to src. + * + * @param dst Pointer to either a valid buffer reference or NULL. On success, + * this will point to a buffer reference equivalent to src. On + * failure, dst will be left untouched. + * @param src A buffer reference to replace dst with. May be NULL, then this + * function is equivalent to av_buffer_unref(dst). + * @return 0 on success + * AVERROR(ENOMEM) on memory allocation failure. + */ +int av_buffer_replace(AVBufferRef **dst, AVBufferRef *src); /** * @} @@ -246,7 +285,11 @@ typedef struct AVBufferPool AVBufferPool; * (av_buffer_alloc()). * @return newly created buffer pool on success, NULL on error. */ +#if FF_API_BUFFER_SIZE_T AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)); +#else +AVBufferPool *av_buffer_pool_init(size_t size, AVBufferRef* (*alloc)(size_t size)); +#endif /** * Allocate and initialize a buffer pool with a more complex allocator. @@ -263,8 +306,13 @@ AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)); * data. May be NULL. * @return newly created buffer pool on success, NULL on error. */ +#if FF_API_BUFFER_SIZE_T AVBufferPool *av_buffer_pool_init2(int size, void *opaque, AVBufferRef* (*alloc)(void *opaque, int size), +#else +AVBufferPool *av_buffer_pool_init2(size_t size, void *opaque, + AVBufferRef* (*alloc)(void *opaque, size_t size), +#endif void (*pool_free)(void *opaque)); /** diff --git a/libavutil/buffer_internal.h b/libavutil/buffer_internal.h index 70d2615a0..d902772ed 100644 --- a/libavutil/buffer_internal.h +++ b/libavutil/buffer_internal.h @@ -22,6 +22,7 @@ #include #include +#include "internal.h" #include "buffer.h" #include "thread.h" @@ -32,7 +33,7 @@ struct AVBuffer { uint8_t *data; /**< data described by this buffer */ - int size; /**< size of data in bytes */ + buffer_size_t size; /**< size of data in bytes */ /** * number of existing AVBufferRef instances referring to this buffer @@ -89,10 +90,10 @@ struct AVBufferPool { */ atomic_uint refcount; - int size; + buffer_size_t size; void *opaque; - AVBufferRef* (*alloc)(int size); - AVBufferRef* (*alloc2)(void *opaque, int size); + AVBufferRef* (*alloc)(buffer_size_t size); + AVBufferRef* (*alloc2)(void *opaque, buffer_size_t size); void (*pool_free)(void *opaque); }; diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c index 3bd5ee29b..ac773a9e6 100644 --- a/libavutil/channel_layout.c +++ b/libavutil/channel_layout.c @@ -62,6 +62,11 @@ static const struct channel_name channel_names[] = { [33] = { "SDL", "surround direct left" }, [34] = { "SDR", "surround direct right" }, [35] = { "LFE2", "low frequency 2" }, + [36] = { "TSL", "top side left" }, + [37] = { "TSR", "top side right" }, + [38] = { "BFC", "bottom front center" }, + [39] = { "BFL", "bottom front left" }, + [40] = { "BFR", "bottom front right" }, }; static const char *get_channel_name(int channel_id) @@ -104,6 +109,7 @@ static const struct { { "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL }, { "hexadecagonal", 16, AV_CH_LAYOUT_HEXADECAGONAL }, { "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, }, + { "22.2", 24, AV_CH_LAYOUT_22POINT2, }, }; static uint64_t get_channel_layout_single(const char *name, int name_len) diff --git a/libavutil/channel_layout.h b/libavutil/channel_layout.h index 50bb8f03c..d39ae1177 100644 --- a/libavutil/channel_layout.h +++ b/libavutil/channel_layout.h @@ -71,6 +71,11 @@ #define AV_CH_SURROUND_DIRECT_LEFT 0x0000000200000000ULL #define AV_CH_SURROUND_DIRECT_RIGHT 0x0000000400000000ULL #define AV_CH_LOW_FREQUENCY_2 0x0000000800000000ULL +#define AV_CH_TOP_SIDE_LEFT 0x0000001000000000ULL +#define AV_CH_TOP_SIDE_RIGHT 0x0000002000000000ULL +#define AV_CH_BOTTOM_FRONT_CENTER 0x0000004000000000ULL +#define AV_CH_BOTTOM_FRONT_LEFT 0x0000008000000000ULL +#define AV_CH_BOTTOM_FRONT_RIGHT 0x0000010000000000ULL /** Channel mask value used for AVCodecContext.request_channel_layout to indicate that the user requests the channel order of the decoder output @@ -110,6 +115,7 @@ #define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT) #define AV_CH_LAYOUT_HEXADECAGONAL (AV_CH_LAYOUT_OCTAGONAL|AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) #define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT) +#define AV_CH_LAYOUT_22POINT2 (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER|AV_CH_BACK_CENTER|AV_CH_LOW_FREQUENCY_2|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_CENTER|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_SIDE_LEFT|AV_CH_TOP_SIDE_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_BOTTOM_FRONT_CENTER|AV_CH_BOTTOM_FRONT_LEFT|AV_CH_BOTTOM_FRONT_RIGHT) enum AVMatrixEncoding { AV_MATRIX_ENCODING_NONE, diff --git a/libavutil/common.h b/libavutil/common.h index 92b721a59..aee353d39 100644 --- a/libavutil/common.h +++ b/libavutil/common.h @@ -80,6 +80,15 @@ */ #define FFNABS(a) ((a) <= 0 ? (a) : (-(a))) +/** + * Unsigned Absolute value. + * This takes the absolute value of a signed int and returns it as a unsigned. + * This also works with INT_MIN which would otherwise not be representable + * As with many macros, this evaluates its argument twice. + */ +#define FFABSU(a) ((a) <= 0 ? -(unsigned)(a) : (unsigned)(a)) +#define FFABS64U(a) ((a) <= 0 ? -(uint64_t)(a) : (uint64_t)(a)) + /** * Comparator. * For two numerical expressions x and y, gives 1 if x > y, -1 if x < y, and 0 @@ -106,8 +115,72 @@ # include "intmath.h" #endif -/* Pull in unguarded fallback defines at the end of this file. */ -#include "common.h" +#ifndef av_ceil_log2 +# define av_ceil_log2 av_ceil_log2_c +#endif +#ifndef av_clip +# define av_clip av_clip_c +#endif +#ifndef av_clip64 +# define av_clip64 av_clip64_c +#endif +#ifndef av_clip_uint8 +# define av_clip_uint8 av_clip_uint8_c +#endif +#ifndef av_clip_int8 +# define av_clip_int8 av_clip_int8_c +#endif +#ifndef av_clip_uint16 +# define av_clip_uint16 av_clip_uint16_c +#endif +#ifndef av_clip_int16 +# define av_clip_int16 av_clip_int16_c +#endif +#ifndef av_clipl_int32 +# define av_clipl_int32 av_clipl_int32_c +#endif +#ifndef av_clip_intp2 +# define av_clip_intp2 av_clip_intp2_c +#endif +#ifndef av_clip_uintp2 +# define av_clip_uintp2 av_clip_uintp2_c +#endif +#ifndef av_mod_uintp2 +# define av_mod_uintp2 av_mod_uintp2_c +#endif +#ifndef av_sat_add32 +# define av_sat_add32 av_sat_add32_c +#endif +#ifndef av_sat_dadd32 +# define av_sat_dadd32 av_sat_dadd32_c +#endif +#ifndef av_sat_sub32 +# define av_sat_sub32 av_sat_sub32_c +#endif +#ifndef av_sat_dsub32 +# define av_sat_dsub32 av_sat_dsub32_c +#endif +#ifndef av_sat_add64 +# define av_sat_add64 av_sat_add64_c +#endif +#ifndef av_sat_sub64 +# define av_sat_sub64 av_sat_sub64_c +#endif +#ifndef av_clipf +# define av_clipf av_clipf_c +#endif +#ifndef av_clipd +# define av_clipd av_clipd_c +#endif +#ifndef av_popcount +# define av_popcount av_popcount_c +#endif +#ifndef av_popcount64 +# define av_popcount64 av_popcount64_c +#endif +#ifndef av_parity +# define av_parity av_parity_c +#endif #ifndef av_log2 av_const int av_log2(unsigned v); @@ -303,11 +376,10 @@ static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) { int64_t tmp; return !__builtin_add_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN); #else - if (b >= 0 && a >= INT64_MAX - b) - return INT64_MAX; - if (b <= 0 && a <= INT64_MIN - b) - return INT64_MIN; - return a + b; + int64_t s = a+(uint64_t)b; + if ((int64_t)(a^b | ~s^b) >= 0) + return INT64_MAX ^ (b >> 63); + return s; #endif } @@ -534,75 +606,3 @@ static av_always_inline av_const int av_parity_c(uint32_t v) #endif /* HAVE_AV_CONFIG_H */ #endif /* AVUTIL_COMMON_H */ - -/* - * The following definitions are outside the multiple inclusion guard - * to ensure they are immediately available in intmath.h. - */ - -#ifndef av_ceil_log2 -# define av_ceil_log2 av_ceil_log2_c -#endif -#ifndef av_clip -# define av_clip av_clip_c -#endif -#ifndef av_clip64 -# define av_clip64 av_clip64_c -#endif -#ifndef av_clip_uint8 -# define av_clip_uint8 av_clip_uint8_c -#endif -#ifndef av_clip_int8 -# define av_clip_int8 av_clip_int8_c -#endif -#ifndef av_clip_uint16 -# define av_clip_uint16 av_clip_uint16_c -#endif -#ifndef av_clip_int16 -# define av_clip_int16 av_clip_int16_c -#endif -#ifndef av_clipl_int32 -# define av_clipl_int32 av_clipl_int32_c -#endif -#ifndef av_clip_intp2 -# define av_clip_intp2 av_clip_intp2_c -#endif -#ifndef av_clip_uintp2 -# define av_clip_uintp2 av_clip_uintp2_c -#endif -#ifndef av_mod_uintp2 -# define av_mod_uintp2 av_mod_uintp2_c -#endif -#ifndef av_sat_add32 -# define av_sat_add32 av_sat_add32_c -#endif -#ifndef av_sat_dadd32 -# define av_sat_dadd32 av_sat_dadd32_c -#endif -#ifndef av_sat_sub32 -# define av_sat_sub32 av_sat_sub32_c -#endif -#ifndef av_sat_dsub32 -# define av_sat_dsub32 av_sat_dsub32_c -#endif -#ifndef av_sat_add64 -# define av_sat_add64 av_sat_add64_c -#endif -#ifndef av_sat_sub64 -# define av_sat_sub64 av_sat_sub64_c -#endif -#ifndef av_clipf -# define av_clipf av_clipf_c -#endif -#ifndef av_clipd -# define av_clipd av_clipd_c -#endif -#ifndef av_popcount -# define av_popcount av_popcount_c -#endif -#ifndef av_popcount64 -# define av_popcount64 av_popcount64_c -#endif -#ifndef av_parity -# define av_parity av_parity_c -#endif diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 6548cc304..52f6b9a3b 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -51,6 +51,8 @@ static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1); static int get_cpu_flags(void) { + if (ARCH_MIPS) + return ff_get_cpu_flags_mips(); if (ARCH_AARCH64) return ff_get_cpu_flags_aarch64(); if (ARCH_ARM) @@ -169,6 +171,9 @@ int av_parse_cpu_flags(const char *s) { "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, +#elif ARCH_MIPS + { "mmi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMI }, .unit = "flags" }, + { "msa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MSA }, .unit = "flags" }, #endif { NULL }, }; @@ -250,6 +255,9 @@ int av_parse_cpu_caps(unsigned *flags, const char *s) { "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, +#elif ARCH_MIPS + { "mmi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMI }, .unit = "flags" }, + { "msa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MSA }, .unit = "flags" }, #endif { NULL }, }; @@ -308,6 +316,8 @@ int av_cpu_count(void) size_t av_cpu_max_align(void) { + if (ARCH_MIPS) + return ff_get_cpu_max_align_mips(); if (ARCH_AARCH64) return ff_get_cpu_max_align_aarch64(); if (ARCH_ARM) diff --git a/libavutil/cpu.h b/libavutil/cpu.h index 8bb9eb606..83099dd96 100644 --- a/libavutil/cpu.h +++ b/libavutil/cpu.h @@ -71,6 +71,9 @@ #define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations #define AV_CPU_FLAG_SETEND (1 <<16) +#define AV_CPU_FLAG_MMI (1 << 0) +#define AV_CPU_FLAG_MSA (1 << 1) + /** * Return the flags which specify extensions supported by the CPU. * The returned value is affected by av_force_cpu_flags() if that was used diff --git a/libavutil/cpu_internal.h b/libavutil/cpu_internal.h index 37122d1c5..889764320 100644 --- a/libavutil/cpu_internal.h +++ b/libavutil/cpu_internal.h @@ -41,11 +41,13 @@ #define CPUEXT_FAST(flags, cpuext) CPUEXT_SUFFIX_FAST(flags, , cpuext) #define CPUEXT_SLOW(flags, cpuext) CPUEXT_SUFFIX_SLOW(flags, , cpuext) +int ff_get_cpu_flags_mips(void); int ff_get_cpu_flags_aarch64(void); int ff_get_cpu_flags_arm(void); int ff_get_cpu_flags_ppc(void); int ff_get_cpu_flags_x86(void); +size_t ff_get_cpu_max_align_mips(void); size_t ff_get_cpu_max_align_aarch64(void); size_t ff_get_cpu_max_align_arm(void); size_t ff_get_cpu_max_align_ppc(void); diff --git a/libavutil/cuda_check.h b/libavutil/cuda_check.h index d02ea7eec..3aea085c0 100644 --- a/libavutil/cuda_check.h +++ b/libavutil/cuda_check.h @@ -20,6 +20,8 @@ #ifndef AVUTIL_CUDA_CHECK_H #define AVUTIL_CUDA_CHECK_H +#include "compat/cuda/dynlink_loader.h" + typedef CUresult CUDAAPI cuda_check_GetErrorName(CUresult error, const char** pstr); typedef CUresult CUDAAPI cuda_check_GetErrorString(CUresult error, const char** pstr); diff --git a/libavutil/eval.c b/libavutil/eval.c index c743ee3df..d0bada9b3 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -317,7 +317,7 @@ static double eval_expr(Parser *p, AVExpr *e) case e_lte: return e->value * (d <= d2 ? 1.0 : 0.0); case e_pow: return e->value * pow(d, d2); case e_mul: return e->value * (d * d2); - case e_div: return e->value * ((!CONFIG_FTRAPV || d2 ) ? (d / d2) : d * INFINITY); + case e_div: return e->value * (d2 ? (d / d2) : d * INFINITY); case e_add: return e->value * (d + d2); case e_last:return e->value * d2; case e_st : return e->value * (p->var[av_clip(d, 0, VARS-1)]= d2); diff --git a/libavutil/film_grain_params.c b/libavutil/film_grain_params.c new file mode 100644 index 000000000..930d23c7f --- /dev/null +++ b/libavutil/film_grain_params.c @@ -0,0 +1,42 @@ +/** + * 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 "film_grain_params.h" + +AVFilmGrainParams *av_film_grain_params_alloc(size_t *size) +{ + AVFilmGrainParams *params = av_mallocz(sizeof(AVFilmGrainParams)); + + if (size) + *size = sizeof(*params); + + return params; +} + +AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_FILM_GRAIN_PARAMS, + sizeof(AVFilmGrainParams)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVFilmGrainParams)); + + return (AVFilmGrainParams *)side_data->data; +} diff --git a/libavutil/film_grain_params.h b/libavutil/film_grain_params.h new file mode 100644 index 000000000..7629e3a04 --- /dev/null +++ b/libavutil/film_grain_params.h @@ -0,0 +1,168 @@ +/* + * 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 AVUTIL_FILM_GRAIN_PARAMS_H +#define AVUTIL_FILM_GRAIN_PARAMS_H + +#include "frame.h" + +enum AVFilmGrainParamsType { + AV_FILM_GRAIN_PARAMS_NONE = 0, + + /** + * The union is valid when interpreted as AVFilmGrainAOMParams (codec.aom) + */ + AV_FILM_GRAIN_PARAMS_AV1, +}; + +/** + * This structure describes how to handle film grain synthesis for AOM codecs. + * + * @note The struct must be allocated as part of AVFilmGrainParams using + * av_film_grain_params_alloc(). Its size is not a part of the public ABI. + */ +typedef struct AVFilmGrainAOMParams { + /** + * Number of points, and the scale and value for each point of the + * piecewise linear scaling function for the uma plane. + */ + int num_y_points; + uint8_t y_points[14][2 /* value, scaling */]; + + /** + * Signals whether to derive the chroma scaling function from the luma. + * Not equivalent to copying the luma values and scales. + */ + int chroma_scaling_from_luma; + + /** + * If chroma_scaling_from_luma is set to 0, signals the chroma scaling + * function parameters. + */ + int num_uv_points[2 /* cb, cr */]; + uint8_t uv_points[2 /* cb, cr */][10][2 /* value, scaling */]; + + /** + * Specifies the shift applied to the chroma components. For AV1, its within + * [8; 11] and determines the range and quantization of the film grain. + */ + int scaling_shift; + + /** + * Specifies the auto-regression lag. + */ + int ar_coeff_lag; + + /** + * Luma auto-regression coefficients. The number of coefficients is given by + * 2 * ar_coeff_lag * (ar_coeff_lag + 1). + */ + int8_t ar_coeffs_y[24]; + + /** + * Chroma auto-regression coefficients. The number of coefficients is given by + * 2 * ar_coeff_lag * (ar_coeff_lag + 1) + !!num_y_points. + */ + int8_t ar_coeffs_uv[2 /* cb, cr */][25]; + + /** + * Specifies the range of the auto-regressive coefficients. Values of 6, + * 7, 8 and so on represent a range of [-2, 2), [-1, 1), [-0.5, 0.5) and + * so on. For AV1 must be between 6 and 9. + */ + int ar_coeff_shift; + + /** + * Signals the down shift applied to the generated gaussian numbers during + * synthesis. + */ + int grain_scale_shift; + + /** + * Specifies the luma/chroma multipliers for the index to the component + * scaling function. + */ + int uv_mult[2 /* cb, cr */]; + int uv_mult_luma[2 /* cb, cr */]; + + /** + * Offset used for component scaling function. For AV1 its a 9-bit value + * with a range [-256, 255] + */ + int uv_offset[2 /* cb, cr */]; + + /** + * Signals whether to overlap film grain blocks. + */ + int overlap_flag; + + /** + * Signals to clip to limited color levels after film grain application. + */ + int limit_output_range; +} AVFilmGrainAOMParams; + +/** + * This structure describes how to handle film grain synthesis in video + * for specific codecs. Must be present on every frame where film grain is + * meant to be synthesised for correct presentation. + * + * @note The struct must be allocated with av_film_grain_params_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVFilmGrainParams { + /** + * Specifies the codec for which this structure is valid. + */ + enum AVFilmGrainParamsType type; + + /** + * Seed to use for the synthesis process, if the codec allows for it. + */ + uint64_t seed; + + /** + * Additional fields may be added both here and in any structure included. + * If a codec's film grain structure differs slightly over another + * codec's, fields within may change meaning depending on the type. + */ + union { + AVFilmGrainAOMParams aom; + } codec; +} AVFilmGrainParams; + +/** + * Allocate an AVFilmGrainParams structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * If size is not NULL it will be set to the number of bytes allocated. + * + * @return An AVFilmGrainParams filled with default values or NULL + * on failure. + */ +AVFilmGrainParams *av_film_grain_params_alloc(size_t *size); + +/** + * Allocate a complete AVFilmGrainParams and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVFilmGrainParams structure to be filled by caller. + */ +AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_FILM_GRAIN_PARAMS_H */ diff --git a/libavutil/frame.c b/libavutil/frame.c index 2e952edd2..75e347bf2 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -212,8 +212,10 @@ void av_frame_free(AVFrame **frame) static int get_video_buffer(AVFrame *frame, int align) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); - int ret, i, padded_height; + int ret, i, padded_height, total_size; int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align); + ptrdiff_t linesizes[4]; + size_t sizes[4]; if (!desc) return AVERROR(EINVAL); @@ -238,12 +240,22 @@ static int get_video_buffer(AVFrame *frame, int align) frame->linesize[i] = FFALIGN(frame->linesize[i], align); } + for (i = 0; i < 4; i++) + linesizes[i] = frame->linesize[i]; + padded_height = FFALIGN(frame->height, 32); - if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, - NULL, frame->linesize)) < 0) + if ((ret = av_image_fill_plane_sizes(sizes, frame->format, + padded_height, linesizes)) < 0) return ret; - frame->buf[0] = av_buffer_alloc(ret + 4*plane_padding); + total_size = 4*plane_padding; + for (i = 0; i < 4; i++) { + if (sizes[i] > INT_MAX - total_size) + return AVERROR(EINVAL); + total_size += sizes[i]; + } + + frame->buf[0] = av_buffer_alloc(total_size); if (!frame->buf[0]) { ret = AVERROR(ENOMEM); goto fail; @@ -337,7 +349,7 @@ int av_frame_get_buffer(AVFrame *frame, int align) static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) { - int i; + int ret, i; dst->key_frame = src->key_frame; dst->pict_type = src->pict_type; @@ -414,31 +426,18 @@ FF_DISABLE_DEPRECATION_WARNINGS dst->qscale_table = NULL; dst->qstride = 0; dst->qscale_type = 0; - av_buffer_unref(&dst->qp_table_buf); - if (src->qp_table_buf) { - dst->qp_table_buf = av_buffer_ref(src->qp_table_buf); - if (dst->qp_table_buf) { - dst->qscale_table = dst->qp_table_buf->data; - dst->qstride = src->qstride; - dst->qscale_type = src->qscale_type; - } + av_buffer_replace(&dst->qp_table_buf, src->qp_table_buf); + if (dst->qp_table_buf) { + dst->qscale_table = dst->qp_table_buf->data; + dst->qstride = src->qstride; + dst->qscale_type = src->qscale_type; } FF_ENABLE_DEPRECATION_WARNINGS #endif - av_buffer_unref(&dst->opaque_ref); - av_buffer_unref(&dst->private_ref); - if (src->opaque_ref) { - dst->opaque_ref = av_buffer_ref(src->opaque_ref); - if (!dst->opaque_ref) - return AVERROR(ENOMEM); - } - if (src->private_ref) { - dst->private_ref = av_buffer_ref(src->private_ref); - if (!dst->private_ref) - return AVERROR(ENOMEM); - } - return 0; + ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref); + ret |= av_buffer_replace(&dst->private_ref, src->private_ref); + return ret; } int av_frame_ref(AVFrame *dst, const AVFrame *src) @@ -457,17 +456,17 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) ret = frame_copy_props(dst, src, 0); if (ret < 0) - return ret; + goto fail; /* duplicate the frame data if it's not refcounted */ if (!src->buf[0]) { ret = av_frame_get_buffer(dst, 0); if (ret < 0) - return ret; + goto fail; ret = av_frame_copy(dst, src); if (ret < 0) - av_frame_unref(dst); + goto fail; return ret; } @@ -726,7 +725,7 @@ AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, AVFrameSideData *av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, - int size) + buffer_size_t size) { AVFrameSideData *ret; AVBufferRef *buf = av_buffer_alloc(size); @@ -851,6 +850,8 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type) case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)"; case AV_FRAME_DATA_REGIONS_OF_INTEREST: return "Regions Of Interest"; case AV_FRAME_DATA_VIDEO_ENC_PARAMS: return "Video encoding parameters"; + case AV_FRAME_DATA_SEI_UNREGISTERED: return "H.26[45] User Data Unregistered SEI message"; + case AV_FRAME_DATA_FILM_GRAIN_PARAMS: return "Film grain parameters"; } return NULL; } diff --git a/libavutil/frame.h b/libavutil/frame.h index fc67db0f6..7d1f8e293 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -162,8 +162,8 @@ enum AVFrameSideDataType { /** * Timecode which conforms to SMPTE ST 12-1. The data is an array of 4 uint32_t * where the first uint32_t describes how many (1-3) of the other timecodes are used. - * The timecode format is described in the av_timecode_get_smpte_from_framenum() - * function in libavutil/timecode.c. + * The timecode format is described in the documentation of av_timecode_get_smpte_from_framenum() + * function in libavutil/timecode.h. */ AV_FRAME_DATA_S12M_TIMECODE, @@ -184,6 +184,20 @@ enum AVFrameSideDataType { * Encoding parameters for a video frame, as described by AVVideoEncParams. */ AV_FRAME_DATA_VIDEO_ENC_PARAMS, + + /** + * User data unregistered metadata associated with a video frame. + * This is the H.26[45] UDU SEI message, and shouldn't be used for any other purpose + * The data is stored as uint8_t in AVFrameSideData.data which is 16 bytes of + * uuid_iso_iec_11578 followed by AVFrameSideData.size - 16 bytes of user_data_payload_byte. + */ + AV_FRAME_DATA_SEI_UNREGISTERED, + + /** + * Film grain parameters for a frame, described by AVFilmGrainParams. + * Must be present for every frame which should have film grain applied. + */ + AV_FRAME_DATA_FILM_GRAIN_PARAMS, }; enum AVActiveFormatDescription { @@ -206,7 +220,11 @@ enum AVActiveFormatDescription { typedef struct AVFrameSideData { enum AVFrameSideDataType type; uint8_t *data; +#if FF_API_BUFFER_SIZE_T int size; +#else + size_t size; +#endif AVDictionary *metadata; AVBufferRef *buf; } AVFrameSideData; @@ -899,7 +917,11 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane); */ AVFrameSideData *av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, +#if FF_API_BUFFER_SIZE_T int size); +#else + size_t size); +#endif /** * Add a new side data to a frame from an existing AVBufferRef diff --git a/libavutil/hash.c b/libavutil/hash.c index 75edb6db7..d626c3118 100644 --- a/libavutil/hash.c +++ b/libavutil/hash.c @@ -17,6 +17,8 @@ * 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 "hash.h" diff --git a/libavutil/hash.h b/libavutil/hash.h index 7693e6bf0..af4719e42 100644 --- a/libavutil/hash.h +++ b/libavutil/hash.h @@ -27,6 +27,7 @@ #ifndef AVUTIL_HASH_H #define AVUTIL_HASH_H +#include #include #include "version.h" diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c index 718a449b6..3773cd9eb 100644 --- a/libavutil/hwcontext_cuda.c +++ b/libavutil/hwcontext_cuda.c @@ -30,10 +30,9 @@ #include "pixfmt.h" #include "imgutils.h" -#define CUDA_FRAME_ALIGNMENT 256 - typedef struct CUDAFramesContext { int shift_width, shift_height; + int tex_alignment; } CUDAFramesContext; static const enum AVPixelFormat supported_formats[] = { @@ -94,7 +93,7 @@ static void cuda_buffer_free(void *opaque, uint8_t *data) CHECK_CU(cu->cuCtxPopCurrent(&dummy)); } -static AVBufferRef *cuda_pool_alloc(void *opaque, int size) +static AVBufferRef *cuda_pool_alloc(void *opaque, buffer_size_t size) { AVHWFramesContext *ctx = opaque; AVHWDeviceContext *device_ctx = ctx->device_ctx; @@ -127,8 +126,11 @@ fail: static int cuda_frames_init(AVHWFramesContext *ctx) { - CUDAFramesContext *priv = ctx->internal->priv; - int i; + AVHWDeviceContext *device_ctx = ctx->device_ctx; + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CUDAFramesContext *priv = ctx->internal->priv; + CudaFunctions *cu = hwctx->internal->cuda_dl; + int err, i; for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { if (ctx->sw_format == supported_formats[i]) @@ -140,10 +142,24 @@ static int cuda_frames_init(AVHWFramesContext *ctx) return AVERROR(ENOSYS); } + err = CHECK_CU(cu->cuDeviceGetAttribute(&priv->tex_alignment, + 14 /* CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT */, + hwctx->internal->cuda_device)); + if (err < 0) + return err; + + av_log(ctx, AV_LOG_DEBUG, "CUDA texture alignment: %d\n", priv->tex_alignment); + + // YUV420P is a special case. + // Since nvenc expects the U/V planes to have half the linesize of the Y plane + // alignment has to be doubled to ensure the U/V planes still end up aligned. + if (ctx->sw_format == AV_PIX_FMT_YUV420P) + priv->tex_alignment *= 2; + av_pix_fmt_get_chroma_sub_sample(ctx->sw_format, &priv->shift_width, &priv->shift_height); if (!ctx->pool) { - int size = av_image_get_buffer_size(ctx->sw_format, ctx->width, ctx->height, CUDA_FRAME_ALIGNMENT); + int size = av_image_get_buffer_size(ctx->sw_format, ctx->width, ctx->height, priv->tex_alignment); if (size < 0) return size; @@ -157,6 +173,7 @@ static int cuda_frames_init(AVHWFramesContext *ctx) static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) { + CUDAFramesContext *priv = ctx->internal->priv; int res; frame->buf[0] = av_buffer_pool_get(ctx->pool); @@ -164,7 +181,7 @@ static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) return AVERROR(ENOMEM); res = av_image_fill_arrays(frame->data, frame->linesize, frame->buf[0]->data, - ctx->sw_format, ctx->width, ctx->height, CUDA_FRAME_ALIGNMENT); + ctx->sw_format, ctx->width, ctx->height, priv->tex_alignment); if (res < 0) return res; @@ -173,7 +190,7 @@ static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) if (ctx->sw_format == AV_PIX_FMT_YUV420P) { frame->linesize[1] = frame->linesize[2] = frame->linesize[0] / 2; frame->data[2] = frame->data[1]; - frame->data[1] = frame->data[2] + frame->linesize[2] * ctx->height / 2; + frame->data[1] = frame->data[2] + frame->linesize[2] * (ctx->height / 2); } frame->format = AV_PIX_FMT_CUDA; diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index c8ae58f90..2a3549ebd 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -202,7 +202,7 @@ static AVBufferRef *d3d11va_alloc_single(AVHWFramesContext *ctx) return wrap_texture_buf(tex, 0); } -static AVBufferRef *d3d11va_pool_alloc(void *opaque, int size) +static AVBufferRef *d3d11va_pool_alloc(void *opaque, buffer_size_t size) { AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; D3D11VAFramesContext *s = ctx->internal->priv; diff --git a/libavutil/hwcontext_drm.c b/libavutil/hwcontext_drm.c index 32cbde82e..7a9fdbd26 100644 --- a/libavutil/hwcontext_drm.c +++ b/libavutil/hwcontext_drm.c @@ -16,10 +16,20 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #include #include #include +/* This was introduced in version 4.6. And may not exist all without an + * optional package. So to prevent a hard dependency on needing the Linux + * kernel headers to compile, make this optional. */ +#if HAVE_LINUX_DMA_BUF_H +#include +#include +#endif + #include #include @@ -85,6 +95,8 @@ static int drm_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) typedef struct DRMMapping { // Address and length of each mmap()ed region. int nb_regions; + int sync_flags; + int object[AV_DRM_MAX_PLANES]; void *address[AV_DRM_MAX_PLANES]; size_t length[AV_DRM_MAX_PLANES]; } DRMMapping; @@ -93,10 +105,14 @@ static void drm_unmap_frame(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap) { DRMMapping *map = hwmap->priv; - int i; - for (i = 0; i < map->nb_regions; i++) + for (int i = 0; i < map->nb_regions; i++) { +#if HAVE_LINUX_DMA_BUF_H + struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_END | map->sync_flags }; + ioctl(map->object[i], DMA_BUF_IOCTL_SYNC, &sync); +#endif munmap(map->address[i], map->length[i]); + } av_free(map); } @@ -105,6 +121,9 @@ static int drm_map_frame(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src, int flags) { const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)src->data[0]; +#if HAVE_LINUX_DMA_BUF_H + struct dma_buf_sync sync_start = { 0 }; +#endif DRMMapping *map; int err, i, p, plane; int mmap_prot; @@ -120,6 +139,14 @@ static int drm_map_frame(AVHWFramesContext *hwfc, if (flags & AV_HWFRAME_MAP_WRITE) mmap_prot |= PROT_WRITE; +#if HAVE_LINUX_DMA_BUF_H + if (flags & AV_HWFRAME_MAP_READ) + map->sync_flags |= DMA_BUF_SYNC_READ; + if (flags & AV_HWFRAME_MAP_WRITE) + map->sync_flags |= DMA_BUF_SYNC_WRITE; + sync_start.flags = DMA_BUF_SYNC_START | map->sync_flags; +#endif + av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES); for (i = 0; i < desc->nb_objects; i++) { addr = mmap(NULL, desc->objects[i].size, mmap_prot, MAP_SHARED, @@ -133,6 +160,13 @@ static int drm_map_frame(AVHWFramesContext *hwfc, map->address[i] = addr; map->length[i] = desc->objects[i].size; + map->object[i] = desc->objects[i].fd; + +#if HAVE_LINUX_DMA_BUF_H + /* We're not checking for errors here because the kernel may not + * support the ioctl, in which case its okay to carry on */ + ioctl(desc->objects[i].fd, DMA_BUF_IOCTL_SYNC, &sync_start); +#endif } map->nb_regions = i; diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index 64366cea8..33b3dc80f 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -124,7 +124,7 @@ static void dxva2_pool_release_dummy(void *opaque, uint8_t *data) // released in dxva2_frames_uninit() } -static AVBufferRef *dxva2_pool_alloc(void *opaque, int size) +static AVBufferRef *dxva2_pool_alloc(void *opaque, buffer_size_t size) { AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; DXVA2FramesContext *s = ctx->internal->priv; diff --git a/libavutil/hwcontext_opencl.c b/libavutil/hwcontext_opencl.c index cd8638abb..ee814602b 100644 --- a/libavutil/hwcontext_opencl.c +++ b/libavutil/hwcontext_opencl.c @@ -1617,7 +1617,7 @@ static void opencl_pool_free(void *opaque, uint8_t *data) av_free(desc); } -static AVBufferRef *opencl_pool_alloc(void *opaque, int size) +static AVBufferRef *opencl_pool_alloc(void *opaque, buffer_size_t size) { AVHWFramesContext *hwfc = opaque; AVOpenCLDeviceContext *hwctx = hwfc->device_ctx->hwctx; diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 35a944f8f..30b0d81f8 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -194,7 +194,7 @@ static void qsv_pool_release_dummy(void *opaque, uint8_t *data) { } -static AVBufferRef *qsv_pool_alloc(void *opaque, int size) +static AVBufferRef *qsv_pool_alloc(void *opaque, buffer_size_t size) { AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; QSVFramesContext *s = ctx->internal->priv; diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 5c4f5de04..4b81bd1f6 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -136,6 +136,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = { #endif MAP(ARGB, RGB32, ARGB, 0), MAP(XRGB, RGB32, 0RGB, 0), +#ifdef VA_FOURCC_X2R10G10B10 + MAP(X2R10G10B10, RGB32_10, X2RGB10, 0), +#endif }; #undef MAP @@ -265,14 +268,24 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev, } for (i = j = 0; i < attr_count; i++) { + int k; + if (attr_list[i].type != VASurfaceAttribPixelFormat) continue; fourcc = attr_list[i].value.value.i; pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); - if (pix_fmt != AV_PIX_FMT_NONE) + + if (pix_fmt == AV_PIX_FMT_NONE) + continue; + + for (k = 0; k < j; k++) { + if (constraints->valid_sw_formats[k] == pix_fmt) + break; + } + + if (k == j) constraints->valid_sw_formats[j++] = pix_fmt; } - av_assert0(j == pix_fmt_count); constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE; } } else { @@ -284,9 +297,19 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev, err = AVERROR(ENOMEM); goto fail; } - for (i = 0; i < ctx->nb_formats; i++) - constraints->valid_sw_formats[i] = ctx->formats[i].pix_fmt; - constraints->valid_sw_formats[i] = AV_PIX_FMT_NONE; + for (i = j = 0; i < ctx->nb_formats; i++) { + int k; + + for (k = 0; k < j; k++) { + if (constraints->valid_sw_formats[k] == ctx->formats[i].pix_fmt) + break; + } + + if (k == j) + constraints->valid_sw_formats[j++] = ctx->formats[i].pix_fmt; + } + + constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE; } constraints->valid_hw_formats = av_malloc_array(2, sizeof(pix_fmt)); @@ -441,7 +464,7 @@ static void vaapi_buffer_free(void *opaque, uint8_t *data) } } -static AVBufferRef *vaapi_pool_alloc(void *opaque, int size) +static AVBufferRef *vaapi_pool_alloc(void *opaque, buffer_size_t size) { AVHWFramesContext *hwfc = opaque; VAAPIFramesContext *ctx = hwfc->internal->priv; @@ -1654,20 +1677,24 @@ static int vaapi_device_derive(AVHWDeviceContext *ctx, } else { render_node = drmGetRenderDeviceNameFromFd(src_hwctx->fd); if (!render_node) { - av_log(ctx, AV_LOG_ERROR, "Failed to find a render node " - "matching the DRM device.\n"); - return AVERROR(ENODEV); - } - fd = open(render_node, O_RDWR); - if (fd < 0) { - av_log(ctx, AV_LOG_ERROR, "Failed to open render node %s" - "matching the DRM device.\n", render_node); + av_log(ctx, AV_LOG_VERBOSE, "Using non-render node " + "because the device does not have an " + "associated render node.\n"); + fd = src_hwctx->fd; + } else { + fd = open(render_node, O_RDWR); + if (fd < 0) { + av_log(ctx, AV_LOG_VERBOSE, "Using non-render node " + "because the associated render node " + "could not be opened.\n"); + fd = src_hwctx->fd; + } else { + av_log(ctx, AV_LOG_VERBOSE, "Using render node %s " + "in place of non-render DRM device.\n", + render_node); + } free(render_node); - return AVERROR(errno); } - av_log(ctx, AV_LOG_VERBOSE, "Using render node %s in place " - "of non-render DRM device.\n", render_node); - free(render_node); } } #else @@ -1675,8 +1702,13 @@ static int vaapi_device_derive(AVHWDeviceContext *ctx, #endif priv = av_mallocz(sizeof(*priv)); - if (!priv) + if (!priv) { + if (fd != src_hwctx->fd) { + // The fd was opened in this function. + close(fd); + } return AVERROR(ENOMEM); + } if (fd == src_hwctx->fd) { // The fd is inherited from the source context and we are holding diff --git a/libavutil/hwcontext_vdpau.c b/libavutil/hwcontext_vdpau.c index 6b8c1d5f7..a6fd7126f 100644 --- a/libavutil/hwcontext_vdpau.c +++ b/libavutil/hwcontext_vdpau.c @@ -32,27 +32,6 @@ #include "pixfmt.h" #include "pixdesc.h" -typedef struct VDPAUDeviceContext { - VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *get_transfer_caps; - VdpVideoSurfaceGetBitsYCbCr *get_data; - VdpVideoSurfacePutBitsYCbCr *put_data; - VdpVideoSurfaceCreate *surf_create; - VdpVideoSurfaceDestroy *surf_destroy; - - enum AVPixelFormat *pix_fmts[3]; - int nb_pix_fmts[3]; -} VDPAUDeviceContext; - -typedef struct VDPAUFramesContext { - VdpVideoSurfaceGetBitsYCbCr *get_data; - VdpVideoSurfacePutBitsYCbCr *put_data; - VdpChromaType chroma_type; - int chroma_idx; - - const enum AVPixelFormat *pix_fmts; - int nb_pix_fmts; -} VDPAUFramesContext; - typedef struct VDPAUPixFmtMap { VdpYCbCrFormat vdpau_fmt; enum AVPixelFormat pix_fmt; @@ -61,6 +40,10 @@ typedef struct VDPAUPixFmtMap { static const VDPAUPixFmtMap pix_fmts_420[] = { { VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV12 }, { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV420P }, +#ifdef VDP_YCBCR_FORMAT_P016 + { VDP_YCBCR_FORMAT_P016, AV_PIX_FMT_P016 }, + { VDP_YCBCR_FORMAT_P010, AV_PIX_FMT_P010 }, +#endif { 0, AV_PIX_FMT_NONE, }, }; @@ -75,6 +58,9 @@ static const VDPAUPixFmtMap pix_fmts_422[] = { static const VDPAUPixFmtMap pix_fmts_444[] = { #ifdef VDP_YCBCR_FORMAT_Y_U_V_444 { VDP_YCBCR_FORMAT_Y_U_V_444, AV_PIX_FMT_YUV444P }, +#endif +#ifdef VDP_YCBCR_FORMAT_P016 + {VDP_YCBCR_FORMAT_Y_U_V_444_16, AV_PIX_FMT_YUV444P16}, #endif { 0, AV_PIX_FMT_NONE, }, }; @@ -87,8 +73,36 @@ static const struct { { VDP_CHROMA_TYPE_420, AV_PIX_FMT_YUV420P, pix_fmts_420 }, { VDP_CHROMA_TYPE_422, AV_PIX_FMT_YUV422P, pix_fmts_422 }, { VDP_CHROMA_TYPE_444, AV_PIX_FMT_YUV444P, pix_fmts_444 }, +#ifdef VDP_YCBCR_FORMAT_P016 + { VDP_CHROMA_TYPE_420_16, AV_PIX_FMT_YUV420P10, pix_fmts_420 }, + { VDP_CHROMA_TYPE_420_16, AV_PIX_FMT_YUV420P12, pix_fmts_420 }, + { VDP_CHROMA_TYPE_422_16, AV_PIX_FMT_YUV422P10, pix_fmts_422 }, + { VDP_CHROMA_TYPE_444_16, AV_PIX_FMT_YUV444P10, pix_fmts_444 }, + { VDP_CHROMA_TYPE_444_16, AV_PIX_FMT_YUV444P12, pix_fmts_444 }, +#endif }; +typedef struct VDPAUDeviceContext { + VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *get_transfer_caps; + VdpVideoSurfaceGetBitsYCbCr *get_data; + VdpVideoSurfacePutBitsYCbCr *put_data; + VdpVideoSurfaceCreate *surf_create; + VdpVideoSurfaceDestroy *surf_destroy; + + enum AVPixelFormat *pix_fmts[FF_ARRAY_ELEMS(vdpau_pix_fmts)]; + int nb_pix_fmts[FF_ARRAY_ELEMS(vdpau_pix_fmts)]; +} VDPAUDeviceContext; + +typedef struct VDPAUFramesContext { + VdpVideoSurfaceGetBitsYCbCr *get_data; + VdpVideoSurfacePutBitsYCbCr *put_data; + VdpChromaType chroma_type; + int chroma_idx; + + const enum AVPixelFormat *pix_fmts; + int nb_pix_fmts; +} VDPAUFramesContext; + static int count_pixfmts(const VDPAUPixFmtMap *map) { int count = 0; @@ -211,7 +225,7 @@ static void vdpau_buffer_free(void *opaque, uint8_t *data) device_priv->surf_destroy(surf); } -static AVBufferRef *vdpau_pool_alloc(void *opaque, int size) +static AVBufferRef *vdpau_pool_alloc(void *opaque, buffer_size_t size) { AVHWFramesContext *ctx = opaque; VDPAUFramesContext *priv = ctx->internal->priv; @@ -354,6 +368,9 @@ static int vdpau_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, if ((vdpau_format == VDP_YCBCR_FORMAT_YV12) #ifdef VDP_YCBCR_FORMAT_Y_U_V_444 || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444) +#endif +#ifdef VDP_YCBCR_FORMAT_P016 + || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444_16) #endif ) FFSWAP(void*, data[1], data[2]); diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index 5e51d0390..2e3faaaa1 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -138,38 +138,75 @@ typedef struct AVVkFrameInternal { static const struct { enum AVPixelFormat pixfmt; - const VkFormat vkfmts[3]; + const VkFormat vkfmts[4]; } vk_pixfmt_map[] = { { AV_PIX_FMT_GRAY8, { VK_FORMAT_R8_UNORM } }, { AV_PIX_FMT_GRAY16, { VK_FORMAT_R16_UNORM } }, { AV_PIX_FMT_GRAYF32, { VK_FORMAT_R32_SFLOAT } }, { AV_PIX_FMT_NV12, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, + { AV_PIX_FMT_NV21, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, { AV_PIX_FMT_P010, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } }, { AV_PIX_FMT_P016, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } }, - { AV_PIX_FMT_YUV420P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, - { AV_PIX_FMT_YUV422P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, - { AV_PIX_FMT_YUV444P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_NV16, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, + { AV_PIX_FMT_NV24, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, + { AV_PIX_FMT_NV42, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, + + { AV_PIX_FMT_YUV420P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUV420P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUV420P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, { AV_PIX_FMT_YUV420P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_YUV422P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUV422P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUV422P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, { AV_PIX_FMT_YUV422P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_YUV444P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUV444P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUV444P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, { AV_PIX_FMT_YUV444P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, - { AV_PIX_FMT_ABGR, { VK_FORMAT_A8B8G8R8_UNORM_PACK32 } }, + { AV_PIX_FMT_YUVA420P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUVA420P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + /* There is no AV_PIX_FMT_YUVA420P12 */ + { AV_PIX_FMT_YUVA420P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_YUVA422P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUVA422P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUVA422P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUVA422P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_YUVA444P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUVA444P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUVA444P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUVA444P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_BGRA, { VK_FORMAT_B8G8R8A8_UNORM } }, { AV_PIX_FMT_RGBA, { VK_FORMAT_R8G8B8A8_UNORM } }, { AV_PIX_FMT_RGB24, { VK_FORMAT_R8G8B8_UNORM } }, { AV_PIX_FMT_BGR24, { VK_FORMAT_B8G8R8_UNORM } }, { AV_PIX_FMT_RGB48, { VK_FORMAT_R16G16B16_UNORM } }, { AV_PIX_FMT_RGBA64, { VK_FORMAT_R16G16B16A16_UNORM } }, + { AV_PIX_FMT_RGBA64, { VK_FORMAT_R16G16B16A16_UNORM } }, { AV_PIX_FMT_RGB565, { VK_FORMAT_R5G6B5_UNORM_PACK16 } }, { AV_PIX_FMT_BGR565, { VK_FORMAT_B5G6R5_UNORM_PACK16 } }, { AV_PIX_FMT_BGR0, { VK_FORMAT_B8G8R8A8_UNORM } }, - { AV_PIX_FMT_0BGR, { VK_FORMAT_A8B8G8R8_UNORM_PACK32 } }, { AV_PIX_FMT_RGB0, { VK_FORMAT_R8G8B8A8_UNORM } }, + /* Lower priority as there's an endianess-dependent overlap between these + * and rgba/bgr0, and PACK32 formats are more limited */ + { AV_PIX_FMT_BGR32, { VK_FORMAT_A8B8G8R8_UNORM_PACK32 } }, + { AV_PIX_FMT_0BGR32, { VK_FORMAT_A8B8G8R8_UNORM_PACK32 } }, + + { AV_PIX_FMT_X2RGB10, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } }, + + { AV_PIX_FMT_GBRAP, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_GBRAP16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, { AV_PIX_FMT_GBRPF32, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } }, + { AV_PIX_FMT_GBRAPF32, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } }, }; const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p) @@ -210,6 +247,8 @@ enum VulkanExtensions { EXT_EXTERNAL_FD_MEMORY = 1ULL << 2, /* VK_KHR_external_memory_fd */ EXT_EXTERNAL_FD_SEM = 1ULL << 3, /* VK_KHR_external_semaphore_fd */ EXT_EXTERNAL_HOST_MEMORY = 1ULL << 4, /* VK_EXT_external_memory_host */ + EXT_PUSH_DESCRIPTORS = 1ULL << 5, /* VK_KHR_push_descriptor */ + EXT_HOST_QUERY_RESET = 1ULL << 6, /* VK_EXT_host_query_reset */ EXT_NO_FLAG = 1ULL << 63, }; @@ -229,6 +268,8 @@ static const VulkanOptExtension optional_device_exts[] = { { VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, EXT_DRM_MODIFIER_FLAGS, }, { VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, EXT_EXTERNAL_FD_SEM, }, { VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, EXT_EXTERNAL_HOST_MEMORY, }, + { VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, EXT_PUSH_DESCRIPTORS, }, + { VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, EXT_HOST_QUERY_RESET, }, }; /* Converts return values to strings */ @@ -752,14 +793,6 @@ static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd, cmd->nb_queues = num_queues; - cmd->queues = av_mallocz(num_queues * sizeof(*cmd->queues)); - if (!cmd->queues) - return AVERROR(ENOMEM); - - cmd->bufs = av_mallocz(num_queues * sizeof(*cmd->bufs)); - if (!cmd->bufs) - return AVERROR(ENOMEM); - /* Create command pool */ ret = vkCreateCommandPool(hwctx->act_dev, &cqueue_create, hwctx->alloc, &cmd->pool); @@ -769,6 +802,10 @@ static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd, return AVERROR_EXTERNAL; } + cmd->bufs = av_mallocz(num_queues * sizeof(*cmd->bufs)); + if (!cmd->bufs) + return AVERROR(ENOMEM); + cbuf_create.commandPool = cmd->pool; /* Allocate command buffer */ @@ -776,9 +813,14 @@ static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd, if (ret != VK_SUCCESS) { av_log(hwfc, AV_LOG_ERROR, "Command buffer alloc failure: %s\n", vk_ret2str(ret)); + av_freep(&cmd->bufs); return AVERROR_EXTERNAL; } + cmd->queues = av_mallocz(num_queues * sizeof(*cmd->queues)); + if (!cmd->queues) + return AVERROR(ENOMEM); + for (int i = 0; i < num_queues; i++) { VulkanQueueCtx *q = &cmd->queues[i]; vkGetDeviceQueue(hwctx->act_dev, queue_family_index, i, &q->queue); @@ -792,23 +834,25 @@ static void free_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd) { AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; - /* Make sure all queues have finished executing */ - for (int i = 0; i < cmd->nb_queues; i++) { - VulkanQueueCtx *q = &cmd->queues[i]; + if (cmd->queues) { + for (int i = 0; i < cmd->nb_queues; i++) { + VulkanQueueCtx *q = &cmd->queues[i]; - if (q->fence && !q->was_synchronous) { - vkWaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX); - vkResetFences(hwctx->act_dev, 1, &q->fence); + /* Make sure all queues have finished executing */ + if (q->fence && !q->was_synchronous) { + vkWaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX); + vkResetFences(hwctx->act_dev, 1, &q->fence); + } + + /* Free the fence */ + if (q->fence) + vkDestroyFence(hwctx->act_dev, q->fence, hwctx->alloc); + + /* Free buffer dependencies */ + for (int j = 0; j < q->nb_buf_deps; j++) + av_buffer_unref(&q->buf_deps[j]); + av_free(q->buf_deps); } - - /* Free the fence */ - if (q->fence) - vkDestroyFence(hwctx->act_dev, q->fence, hwctx->alloc); - - /* Free buffer dependencies */ - for (int j = 0; j < q->nb_buf_deps; j++) - av_buffer_unref(&q->buf_deps[j]); - av_free(q->buf_deps); } if (cmd->bufs) @@ -816,8 +860,9 @@ static void free_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd) if (cmd->pool) vkDestroyCommandPool(hwctx->act_dev, cmd->pool, hwctx->alloc); - av_freep(&cmd->bufs); av_freep(&cmd->queues); + av_freep(&cmd->bufs); + cmd->pool = NULL; } static VkCommandBuffer get_buf_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd) @@ -1003,6 +1048,8 @@ static int vulkan_device_create_internal(AVHWDeviceContext *ctx, vkGetPhysicalDeviceFeatures(hwctx->phys_dev, &dev_features); #define COPY_FEATURE(DST, NAME) (DST).features.NAME = dev_features.NAME; COPY_FEATURE(hwctx->device_features, shaderImageGatherExtended) + COPY_FEATURE(hwctx->device_features, shaderStorageImageReadWithoutFormat) + COPY_FEATURE(hwctx->device_features, shaderStorageImageWriteWithoutFormat) COPY_FEATURE(hwctx->device_features, fragmentStoresAndAtomics) COPY_FEATURE(hwctx->device_features, vertexPipelineStoresAndAtomics) COPY_FEATURE(hwctx->device_features, shaderInt64) @@ -1270,12 +1317,18 @@ static int alloc_mem(AVHWDeviceContext *ctx, VkMemoryRequirements *req, /* The vulkan spec requires memory types to be sorted in the "optimal" * order, so the first matching type we find will be the best/fastest one */ for (int i = 0; i < p->mprops.memoryTypeCount; i++) { + const VkMemoryType *type = &p->mprops.memoryTypes[i]; + /* The memory type must be supported by the requirements (bitfield) */ if (!(req->memoryTypeBits & (1 << i))) continue; /* The memory type flags must include our properties */ - if ((p->mprops.memoryTypes[i].propertyFlags & req_flags) != req_flags) + if ((type->propertyFlags & req_flags) != req_flags) + continue; + + /* The memory type must be large enough */ + if (req->size > p->mprops.memoryHeaps[type->heapIndex].size) continue; /* Found a suitable memory type */ @@ -1499,6 +1552,23 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx, return submit_exec_ctx(hwfc, ectx, &s_info, 0); } +static inline void get_plane_wh(int *w, int *h, enum AVPixelFormat format, + int frame_w, int frame_h, int plane) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); + + /* Currently always true unless gray + alpha support is added */ + if (!plane || (plane == 3) || desc->flags & AV_PIX_FMT_FLAG_RGB || + !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) { + *w = frame_w; + *h = frame_h; + return; + } + + *w = AV_CEIL_RSHIFT(frame_w, desc->log2_chroma_w); + *h = AV_CEIL_RSHIFT(frame_h, desc->log2_chroma_h); +} + static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame, VkImageTiling tiling, VkImageUsageFlagBits usage, void *create_pnext) @@ -1530,19 +1600,11 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame, /* Create the images */ for (int i = 0; i < planes; i++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); - int w = hwfc->width; - int h = hwfc->height; - const int p_w = i > 0 ? AV_CEIL_RSHIFT(w, desc->log2_chroma_w) : w; - const int p_h = i > 0 ? AV_CEIL_RSHIFT(h, desc->log2_chroma_h) : h; - - VkImageCreateInfo image_create_info = { + VkImageCreateInfo create_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .pNext = create_pnext, .imageType = VK_IMAGE_TYPE_2D, .format = img_fmts[i], - .extent.width = p_w, - .extent.height = p_h, .extent.depth = 1, .mipLevels = 1, .arrayLayers = 1, @@ -1557,7 +1619,10 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame, VK_SHARING_MODE_EXCLUSIVE, }; - ret = vkCreateImage(hwctx->act_dev, &image_create_info, + get_plane_wh(&create_info.extent.width, &create_info.extent.height, + format, hwfc->width, hwfc->height, i); + + ret = vkCreateImage(hwctx->act_dev, &create_info, hwctx->alloc, &f->img[i]); if (ret != VK_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Image creation failure: %s\n", @@ -1575,7 +1640,7 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame, return AVERROR_EXTERNAL; } - f->layout[i] = image_create_info.initialLayout; + f->layout[i] = create_info.initialLayout; f->access[i] = 0x0; } @@ -1628,7 +1693,7 @@ static void try_export_flags(AVHWFramesContext *hwfc, } } -static AVBufferRef *vulkan_pool_alloc(void *opaque, int size) +static AVBufferRef *vulkan_pool_alloc(void *opaque, buffer_size_t size) { int err; AVVkFrame *f; @@ -1713,24 +1778,24 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) dev_hwctx->queue_family_comp_index, GET_QUEUE_COUNT(dev_hwctx, 0, 1, 0)); if (err) - goto fail; + return err; err = create_exec_ctx(hwfc, &fp->upload_ctx, dev_hwctx->queue_family_tx_index, GET_QUEUE_COUNT(dev_hwctx, 0, 0, 1)); if (err) - goto fail; + return err; err = create_exec_ctx(hwfc, &fp->download_ctx, dev_hwctx->queue_family_tx_index, 1); if (err) - goto fail; + return err; /* Test to see if allocation will fail */ err = create_frame(hwfc, &f, hwctx->tiling, hwctx->usage, hwctx->create_pnext); if (err) - goto fail; + return err; vulkan_frame_free(hwfc, (uint8_t *)f); @@ -1740,20 +1805,11 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) hwfc->internal->pool_internal = av_buffer_pool_init2(sizeof(AVVkFrame), hwfc, vulkan_pool_alloc, NULL); - if (!hwfc->internal->pool_internal) { - err = AVERROR(ENOMEM); - goto fail; - } + if (!hwfc->internal->pool_internal) + return AVERROR(ENOMEM); } return 0; - -fail: - free_exec_ctx(hwfc, &fp->conv_ctx); - free_exec_ctx(hwfc, &fp->upload_ctx); - free_exec_ctx(hwfc, &fp->download_ctx); - - return err; } static int vulkan_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) @@ -1953,7 +2009,7 @@ static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc) } static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **frame, - AVDRMFrameDescriptor *desc) + const AVFrame *src) { int err = 0; VkResult ret; @@ -1964,8 +2020,8 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f VulkanDevicePriv *p = ctx->internal->priv; VulkanFramesPriv *fp = hwfc->internal->priv; AVVulkanFramesContext *frames_hwctx = hwfc->hwctx; - const AVPixFmtDescriptor *fmt_desc = av_pix_fmt_desc_get(hwfc->sw_format); - const int has_modifiers = p->extensions & EXT_DRM_MODIFIER_FLAGS; + const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->data[0]; + const int has_modifiers = !!(p->extensions & EXT_DRM_MODIFIER_FLAGS); VkSubresourceLayout plane_data[AV_NUM_DATA_POINTERS] = { 0 }; VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { 0 }; VkBindImagePlaneMemoryInfo plane_info[AV_NUM_DATA_POINTERS] = { 0 }; @@ -2010,16 +2066,11 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, }; - const int p_w = i > 0 ? AV_CEIL_RSHIFT(hwfc->width, fmt_desc->log2_chroma_w) : hwfc->width; - const int p_h = i > 0 ? AV_CEIL_RSHIFT(hwfc->height, fmt_desc->log2_chroma_h) : hwfc->height; - - VkImageCreateInfo image_create_info = { + VkImageCreateInfo create_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .pNext = &einfo, .imageType = VK_IMAGE_TYPE_2D, .format = drm_to_vulkan_fmt(desc->layers[i].format), - .extent.width = p_w, - .extent.height = p_h, .extent.depth = 1, .mipLevels = 1, .arrayLayers = 1, @@ -2034,6 +2085,9 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f VK_SHARING_MODE_EXCLUSIVE, }; + get_plane_wh(&create_info.extent.width, &create_info.extent.height, + hwfc->sw_format, src->width, src->height, i); + for (int j = 0; j < planes; j++) { plane_data[j].offset = desc->layers[i].planes[j].offset; plane_data[j].rowPitch = desc->layers[i].planes[j].pitch; @@ -2043,7 +2097,7 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f } /* Create image */ - ret = vkCreateImage(hwctx->act_dev, &image_create_info, + ret = vkCreateImage(hwctx->act_dev, &create_info, hwctx->alloc, &f->img[i]); if (ret != VK_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Image creation failure: %s\n", @@ -2065,7 +2119,7 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f * offer us anything we could import and sync with, so instead * just signal the semaphore we created. */ - f->layout[i] = image_create_info.initialLayout; + f->layout[i] = create_info.initialLayout; f->access[i] = 0x0; } @@ -2193,9 +2247,7 @@ static int vulkan_map_from_drm(AVHWFramesContext *hwfc, AVFrame *dst, AVVkFrame *f; VulkanMapping *map = NULL; - err = vulkan_map_from_drm_frame_desc(hwfc, &f, - (AVDRMFrameDescriptor *)src->data[0]); - if (err) + if ((err = vulkan_map_from_drm_frame_desc(hwfc, &f, src))) return err; /* The unmapping function will free this */ @@ -2307,10 +2359,6 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc, CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = { .offset = 0, .arrayDesc = { - .Width = i > 0 ? AV_CEIL_RSHIFT(hwfc->width, desc->log2_chroma_w) - : hwfc->width, - .Height = i > 0 ? AV_CEIL_RSHIFT(hwfc->height, desc->log2_chroma_h) - : hwfc->height, .Depth = 0, .Format = cufmt, .NumChannels = 1 + ((planes == 2) && i), @@ -2336,6 +2384,12 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc, .type = CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD, }; + int p_w, p_h; + get_plane_wh(&p_w, &p_h, hwfc->sw_format, hwfc->width, hwfc->height, i); + + tex_desc.arrayDesc.Width = p_w; + tex_desc.arrayDesc.Height = p_h; + ret = pfn_vkGetMemoryFdKHR(hwctx->act_dev, &export_info, &ext_desc.handle.fd); if (ret != VK_SUCCESS) { @@ -2409,17 +2463,17 @@ static int vulkan_transfer_data_from_cuda(AVHWFramesContext *hwfc, CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS s_s_par[AV_NUM_DATA_POINTERS] = { 0 }; ret = CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx)); - if (ret < 0) { - err = AVERROR_EXTERNAL; - goto fail; - } + if (ret < 0) + return AVERROR_EXTERNAL; dst_f = (AVVkFrame *)dst->data[0]; ret = vulkan_export_to_cuda(hwfc, src->hw_frames_ctx, dst); if (ret < 0) { - goto fail; + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + return ret; } + dst_int = dst_f->internal; ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par, @@ -2438,12 +2492,14 @@ static int vulkan_transfer_data_from_cuda(AVHWFramesContext *hwfc, .dstMemoryType = CU_MEMORYTYPE_ARRAY, .dstArray = dst_int->cu_array[i], - .WidthInBytes = (i > 0 ? AV_CEIL_RSHIFT(hwfc->width, desc->log2_chroma_w) - : hwfc->width) * desc->comp[i].step, - .Height = i > 0 ? AV_CEIL_RSHIFT(hwfc->height, desc->log2_chroma_h) - : hwfc->height, }; + int p_w, p_h; + get_plane_wh(&p_w, &p_h, hwfc->sw_format, hwfc->width, hwfc->height, i); + + cpy.WidthInBytes = p_w * desc->comp[i].step; + cpy.Height = p_h; + ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream)); if (ret < 0) { err = AVERROR_EXTERNAL; @@ -2688,21 +2744,30 @@ static void free_buf(void *opaque, uint8_t *data) av_free(data); } -static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf, size_t imp_size, - int height, int *stride, VkBufferUsageFlags usage, - VkMemoryPropertyFlagBits flags, void *create_pnext, - void *alloc_pnext) +static size_t get_req_buffer_size(VulkanDevicePriv *p, int *stride, int height) +{ + size_t size; + *stride = FFALIGN(*stride, p->props.properties.limits.optimalBufferCopyRowPitchAlignment); + size = height*(*stride); + size = FFALIGN(size, p->props.properties.limits.minMemoryMapAlignment); + return size; +} + +static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf, + VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags, + size_t size, uint32_t req_memory_bits, int host_mapped, + void *create_pnext, void *alloc_pnext) { int err; VkResult ret; int use_ded_mem; AVVulkanDeviceContext *hwctx = ctx->hwctx; - VulkanDevicePriv *p = ctx->internal->priv; VkBufferCreateInfo buf_spawn = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = create_pnext, .usage = usage, + .size = size, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, }; @@ -2725,21 +2790,14 @@ static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf, size_t imp_size if (!vkbuf) return AVERROR(ENOMEM); - vkbuf->mapped_mem = !!imp_size; - - if (!vkbuf->mapped_mem) { - *stride = FFALIGN(*stride, p->props.properties.limits.optimalBufferCopyRowPitchAlignment); - buf_spawn.size = height*(*stride); - buf_spawn.size = FFALIGN(buf_spawn.size, p->props.properties.limits.minMemoryMapAlignment); - } else { - buf_spawn.size = imp_size; - } + vkbuf->mapped_mem = host_mapped; ret = vkCreateBuffer(hwctx->act_dev, &buf_spawn, NULL, &vkbuf->buf); if (ret != VK_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Failed to create buffer: %s\n", vk_ret2str(ret)); - return AVERROR_EXTERNAL; + err = AVERROR_EXTERNAL; + goto fail; } req_desc.buffer = vkbuf->buf; @@ -2752,27 +2810,35 @@ static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf, size_t imp_size if (use_ded_mem) ded_alloc.buffer = vkbuf->buf; + /* Additional requirements imposed on us */ + if (req_memory_bits) + req.memoryRequirements.memoryTypeBits &= req_memory_bits; + err = alloc_mem(ctx, &req.memoryRequirements, flags, use_ded_mem ? &ded_alloc : (void *)ded_alloc.pNext, &vkbuf->flags, &vkbuf->mem); if (err) - return err; + goto fail; ret = vkBindBufferMemory(hwctx->act_dev, vkbuf->buf, vkbuf->mem, 0); if (ret != VK_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Failed to bind memory to buffer: %s\n", vk_ret2str(ret)); - free_buf(ctx, (uint8_t *)vkbuf); - return AVERROR_EXTERNAL; + err = AVERROR_EXTERNAL; + goto fail; } *buf = av_buffer_create((uint8_t *)vkbuf, sizeof(*vkbuf), free_buf, ctx, 0); if (!(*buf)) { - free_buf(ctx, (uint8_t *)vkbuf); - return AVERROR(ENOMEM); + err = AVERROR(ENOMEM); + goto fail; } return 0; + +fail: + free_buf(ctx, (uint8_t *)vkbuf); + return err; } /* Skips mapping of host mapped buffers but still invalidates them */ @@ -2808,8 +2874,16 @@ static int map_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs, uint8_t *mem[ .memory = vkbuf->mem, .size = VK_WHOLE_SIZE, }; + + /* For host imported memory Vulkan says to use platform-defined + * sync methods, but doesn't really say not to call flush or invalidate + * on original host pointers. It does explicitly allow to do that on + * host-mapped pointers which are then mapped again using vkMapMemory, + * but known implementations return the original pointers when mapped + * again. */ if (vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) continue; + invalidate_ctx[invalidate_count++] = ival_buf; } @@ -2841,8 +2915,10 @@ static int unmap_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs, .memory = vkbuf->mem, .size = VK_WHOLE_SIZE, }; + if (vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) continue; + flush_ctx[flush_count++] = flush_buf; } } @@ -2868,7 +2944,8 @@ static int unmap_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs, } static int transfer_image_buf(AVHWFramesContext *hwfc, const AVFrame *f, - AVBufferRef **bufs, const int *buf_stride, int w, + AVBufferRef **bufs, size_t *buf_offsets, + const int *buf_stride, int w, int h, enum AVPixelFormat pix_fmt, int to_buf) { int err; @@ -2936,22 +3013,20 @@ static int transfer_image_buf(AVHWFramesContext *hwfc, const AVFrame *f, /* Schedule a copy for each plane */ for (int i = 0; i < planes; i++) { ImageBuffer *vkbuf = (ImageBuffer *)bufs[i]->data; - const int p_w = i > 0 ? AV_CEIL_RSHIFT(w, desc->log2_chroma_w) : w; - const int p_h = i > 0 ? AV_CEIL_RSHIFT(h, desc->log2_chroma_h) : h; VkBufferImageCopy buf_reg = { - .bufferOffset = 0, - /* Buffer stride isn't in bytes, it's in samples, the implementation - * uses the image's VkFormat to know how many bytes per sample - * the buffer has. So we have to convert by dividing. Stupid. - * Won't work with YUVA or other planar formats with alpha. */ + .bufferOffset = buf_offsets[i], .bufferRowLength = buf_stride[i] / desc->comp[i].step, - .bufferImageHeight = p_h, .imageSubresource.layerCount = 1, .imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .imageOffset = { 0, 0, 0, }, - .imageExtent = { p_w, p_h, 1, }, }; + int p_w, p_h; + get_plane_wh(&p_w, &p_h, pix_fmt, w, h, i); + + buf_reg.bufferImageHeight = p_h; + buf_reg.imageExtent = (VkExtent3D){ p_w, p_h, 1, }; + if (to_buf) vkCmdCopyImageToBuffer(cmd_buf, frame->img[i], frame->layout[i], vkbuf->buf, 1, &buf_reg); @@ -2982,26 +3057,34 @@ static int transfer_image_buf(AVHWFramesContext *hwfc, const AVFrame *f, } } -static int vulkan_transfer_data_from_mem(AVHWFramesContext *hwfc, AVFrame *dst, - const AVFrame *src) +static int vulkan_transfer_data(AVHWFramesContext *hwfc, const AVFrame *vkf, + const AVFrame *swf, int from) { int err = 0; - AVFrame tmp; - AVVkFrame *f = (AVVkFrame *)dst->data[0]; + VkResult ret; + AVVkFrame *f = (AVVkFrame *)vkf->data[0]; AVHWDeviceContext *dev_ctx = hwfc->device_ctx; - AVBufferRef *bufs[AV_NUM_DATA_POINTERS] = { 0 }; - const int planes = av_pix_fmt_count_planes(src->format); - int log2_chroma = av_pix_fmt_desc_get(src->format)->log2_chroma_h; + AVVulkanDeviceContext *hwctx = dev_ctx->hwctx; VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; - int host_mapped[AV_NUM_DATA_POINTERS] = { 0 }; - int map_host = p->extensions & EXT_EXTERNAL_HOST_MEMORY; - if ((src->format != AV_PIX_FMT_NONE && !av_vkfmt_from_pixfmt(src->format))) { - av_log(hwfc, AV_LOG_ERROR, "Unsupported source pixel format!\n"); + AVFrame tmp; + AVBufferRef *bufs[AV_NUM_DATA_POINTERS] = { 0 }; + size_t buf_offsets[AV_NUM_DATA_POINTERS] = { 0 }; + + int p_w, p_h; + const int planes = av_pix_fmt_count_planes(swf->format); + + int host_mapped[AV_NUM_DATA_POINTERS] = { 0 }; + const int map_host = !!(p->extensions & EXT_EXTERNAL_HOST_MEMORY); + + VK_LOAD_PFN(hwctx->inst, vkGetMemoryHostPointerPropertiesEXT); + + if ((swf->format != AV_PIX_FMT_NONE && !av_vkfmt_from_pixfmt(swf->format))) { + av_log(hwfc, AV_LOG_ERROR, "Unsupported software frame pixel format!\n"); return AVERROR(EINVAL); } - if (src->width > hwfc->width || src->height > hwfc->height) + if (swf->width > hwfc->width || swf->height > hwfc->height) return AVERROR(EINVAL); /* For linear, host visiable images */ @@ -3010,69 +3093,120 @@ static int vulkan_transfer_data_from_mem(AVHWFramesContext *hwfc, AVFrame *dst, AVFrame *map = av_frame_alloc(); if (!map) return AVERROR(ENOMEM); - map->format = src->format; + map->format = swf->format; - err = vulkan_map_frame_to_mem(hwfc, map, dst, AV_HWFRAME_MAP_WRITE); + err = vulkan_map_frame_to_mem(hwfc, map, vkf, AV_HWFRAME_MAP_WRITE); if (err) return err; - err = av_frame_copy(map, src); + err = av_frame_copy((AVFrame *)(from ? swf : map), from ? map : swf); av_frame_free(&map); return err; } /* Create buffers */ for (int i = 0; i < planes; i++) { - int h = src->height; - int p_height = i > 0 ? AV_CEIL_RSHIFT(h, log2_chroma) : h; - size_t p_size = FFABS(src->linesize[i]) * p_height; + size_t req_size; + + VkExternalMemoryBufferCreateInfo create_desc = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, + }; VkImportMemoryHostPointerInfoEXT import_desc = { .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT, .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, - .pHostPointer = src->data[i], }; - /* We can only map images with positive stride and alignment appropriate - * for the device. */ - host_mapped[i] = map_host && src->linesize[i] > 0 && - !(p_size % p->hprops.minImportedHostPointerAlignment) && - !(((uintptr_t)import_desc.pHostPointer) % - p->hprops.minImportedHostPointerAlignment); - p_size = host_mapped[i] ? p_size : 0; + VkMemoryHostPointerPropertiesEXT p_props = { + .sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT, + }; - tmp.linesize[i] = FFABS(src->linesize[i]); - err = create_buf(dev_ctx, &bufs[i], p_size, p_height, &tmp.linesize[i], - VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, NULL, + get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); + + tmp.linesize[i] = FFABS(swf->linesize[i]); + + /* Do not map images with a negative stride */ + if (map_host && swf->linesize[i] > 0) { + size_t offs; + offs = (uintptr_t)swf->data[i] % p->hprops.minImportedHostPointerAlignment; + import_desc.pHostPointer = swf->data[i] - offs; + + /* We have to compensate for the few extra bytes of padding we + * completely ignore at the start */ + req_size = FFALIGN(offs + tmp.linesize[i] * p_h, + p->hprops.minImportedHostPointerAlignment); + + ret = pfn_vkGetMemoryHostPointerPropertiesEXT(hwctx->act_dev, + import_desc.handleType, + import_desc.pHostPointer, + &p_props); + + if (ret == VK_SUCCESS) { + host_mapped[i] = 1; + buf_offsets[i] = offs; + } + } + + if (!host_mapped[i]) + req_size = get_req_buffer_size(p, &tmp.linesize[i], p_h); + + err = create_buf(dev_ctx, &bufs[i], + from ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + req_size, p_props.memoryTypeBits, host_mapped[i], + host_mapped[i] ? &create_desc : NULL, host_mapped[i] ? &import_desc : NULL); if (err) goto end; } - /* Map, copy image to buffer, unmap */ - if ((err = map_buffers(dev_ctx, bufs, tmp.data, planes, 0))) - goto end; + if (!from) { + /* Map, copy image to buffer, unmap */ + if ((err = map_buffers(dev_ctx, bufs, tmp.data, planes, 0))) + goto end; - for (int i = 0; i < planes; i++) { - int h = src->height; - int p_height = i > 0 ? AV_CEIL_RSHIFT(h, log2_chroma) : h; + for (int i = 0; i < planes; i++) { + if (host_mapped[i]) + continue; - if (host_mapped[i]) - continue; + get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); - av_image_copy_plane(tmp.data[i], tmp.linesize[i], - (const uint8_t *)src->data[i], src->linesize[i], - FFMIN(tmp.linesize[i], FFABS(src->linesize[i])), - p_height); + av_image_copy_plane(tmp.data[i], tmp.linesize[i], + (const uint8_t *)swf->data[i], swf->linesize[i], + FFMIN(tmp.linesize[i], FFABS(swf->linesize[i])), + p_h); + } + + if ((err = unmap_buffers(dev_ctx, bufs, planes, 1))) + goto end; } - if ((err = unmap_buffers(dev_ctx, bufs, planes, 1))) - goto end; + /* Copy buffers into/from image */ + err = transfer_image_buf(hwfc, vkf, bufs, buf_offsets, tmp.linesize, + swf->width, swf->height, swf->format, from); - /* Copy buffers to image */ - err = transfer_image_buf(hwfc, dst, bufs, tmp.linesize, - src->width, src->height, src->format, 0); + if (from) { + /* Map, copy image to buffer, unmap */ + if ((err = map_buffers(dev_ctx, bufs, tmp.data, planes, 0))) + goto end; + + for (int i = 0; i < planes; i++) { + if (host_mapped[i]) + continue; + + get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); + + av_image_copy_plane(swf->data[i], swf->linesize[i], + (const uint8_t *)tmp.data[i], tmp.linesize[i], + FFMIN(tmp.linesize[i], FFABS(swf->linesize[i])), + p_h); + } + + if ((err = unmap_buffers(dev_ctx, bufs, planes, 1))) + goto end; + } end: for (int i = 0; i < planes; i++) @@ -3082,7 +3216,7 @@ end: } static int vulkan_transfer_data_to(AVHWFramesContext *hwfc, AVFrame *dst, - const AVFrame *src) + const AVFrame *src) { av_unused VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; @@ -3097,13 +3231,13 @@ static int vulkan_transfer_data_to(AVHWFramesContext *hwfc, AVFrame *dst, if (src->hw_frames_ctx) return AVERROR(ENOSYS); else - return vulkan_transfer_data_from_mem(hwfc, dst, src); + return vulkan_transfer_data(hwfc, dst, src, 0); } } #if CONFIG_CUDA static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst, - const AVFrame *src) + const AVFrame *src) { int err; VkResult ret; @@ -3118,22 +3252,30 @@ static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst, AVCUDADeviceContext *cuda_dev = cuda_cu->hwctx; AVCUDADeviceContextInternal *cu_internal = cuda_dev->internal; CudaFunctions *cu = cu_internal->cuda_dl; + CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS s_w_par[AV_NUM_DATA_POINTERS] = { 0 }; + CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS s_s_par[AV_NUM_DATA_POINTERS] = { 0 }; ret = CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx)); - if (ret < 0) { - err = AVERROR_EXTERNAL; - goto fail; - } + if (ret < 0) + return AVERROR_EXTERNAL; dst_f = (AVVkFrame *)src->data[0]; err = vulkan_export_to_cuda(hwfc, dst->hw_frames_ctx, src); if (err < 0) { - goto fail; + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + return err; } dst_int = dst_f->internal; + ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par, + planes, cuda_dev->stream)); + if (ret < 0) { + err = AVERROR_EXTERNAL; + goto fail; + } + for (int i = 0; i < planes; i++) { CUDA_MEMCPY2D cpy = { .dstMemoryType = CU_MEMORYTYPE_DEVICE, @@ -3143,12 +3285,14 @@ static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst, .srcMemoryType = CU_MEMORYTYPE_ARRAY, .srcArray = dst_int->cu_array[i], - .WidthInBytes = (i > 0 ? AV_CEIL_RSHIFT(hwfc->width, desc->log2_chroma_w) - : hwfc->width) * desc->comp[i].step, - .Height = i > 0 ? AV_CEIL_RSHIFT(hwfc->height, desc->log2_chroma_h) - : hwfc->height, }; + int w, h; + get_plane_wh(&w, &h, hwfc->sw_format, hwfc->width, hwfc->height, i); + + cpy.WidthInBytes = w * desc->comp[i].step; + cpy.Height = h; + ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream)); if (ret < 0) { err = AVERROR_EXTERNAL; @@ -3156,6 +3300,13 @@ static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst, } } + ret = CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par, + planes, cuda_dev->stream)); + if (ret < 0) { + err = AVERROR_EXTERNAL; + goto fail; + } + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); av_log(hwfc, AV_LOG_VERBOSE, "Transfered Vulkan image to CUDA!\n"); @@ -3171,100 +3322,6 @@ fail: } #endif -static int vulkan_transfer_data_to_mem(AVHWFramesContext *hwfc, AVFrame *dst, - const AVFrame *src) -{ - int err = 0; - AVFrame tmp; - AVVkFrame *f = (AVVkFrame *)src->data[0]; - AVHWDeviceContext *dev_ctx = hwfc->device_ctx; - AVBufferRef *bufs[AV_NUM_DATA_POINTERS] = { 0 }; - const int planes = av_pix_fmt_count_planes(dst->format); - int log2_chroma = av_pix_fmt_desc_get(dst->format)->log2_chroma_h; - VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; - int host_mapped[AV_NUM_DATA_POINTERS] = { 0 }; - int map_host = p->extensions & EXT_EXTERNAL_HOST_MEMORY; - - if (dst->width > hwfc->width || dst->height > hwfc->height) - return AVERROR(EINVAL); - - /* For linear, host visiable images */ - if (f->tiling == VK_IMAGE_TILING_LINEAR && - f->flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - AVFrame *map = av_frame_alloc(); - if (!map) - return AVERROR(ENOMEM); - map->format = dst->format; - - err = vulkan_map_frame_to_mem(hwfc, map, src, AV_HWFRAME_MAP_READ); - if (err) - return err; - - err = av_frame_copy(dst, map); - av_frame_free(&map); - return err; - } - - /* Create buffers */ - for (int i = 0; i < planes; i++) { - int h = dst->height; - int p_height = i > 0 ? AV_CEIL_RSHIFT(h, log2_chroma) : h; - size_t p_size = FFABS(dst->linesize[i]) * p_height; - - VkImportMemoryHostPointerInfoEXT import_desc = { - .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT, - .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, - .pHostPointer = dst->data[i], - }; - - /* We can only map images with positive stride and alignment appropriate - * for the device. */ - host_mapped[i] = map_host && dst->linesize[i] > 0 && - !(p_size % p->hprops.minImportedHostPointerAlignment) && - !(((uintptr_t)import_desc.pHostPointer) % - p->hprops.minImportedHostPointerAlignment); - p_size = host_mapped[i] ? p_size : 0; - - tmp.linesize[i] = FFABS(dst->linesize[i]); - err = create_buf(dev_ctx, &bufs[i], p_size, p_height, - &tmp.linesize[i], VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, NULL, - host_mapped[i] ? &import_desc : NULL); - if (err) - goto end; - } - - /* Copy image to buffer */ - if ((err = transfer_image_buf(hwfc, src, bufs, tmp.linesize, - dst->width, dst->height, dst->format, 1))) - goto end; - - /* Map, copy buffer to frame, unmap */ - if ((err = map_buffers(dev_ctx, bufs, tmp.data, planes, 1))) - goto end; - - for (int i = 0; i < planes; i++) { - int h = dst->height; - int p_height = i > 0 ? AV_CEIL_RSHIFT(h, log2_chroma) : h; - - if (host_mapped[i]) - continue; - - av_image_copy_plane(dst->data[i], dst->linesize[i], - (const uint8_t *)tmp.data[i], tmp.linesize[i], - FFMIN(tmp.linesize[i], FFABS(dst->linesize[i])), - p_height); - } - - err = unmap_buffers(dev_ctx, bufs, planes, 0); - -end: - for (int i = 0; i < planes; i++) - av_buffer_unref(&bufs[i]); - - return err; -} - static int vulkan_transfer_data_from(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src) { @@ -3281,7 +3338,7 @@ static int vulkan_transfer_data_from(AVHWFramesContext *hwfc, AVFrame *dst, if (dst->hw_frames_ctx) return AVERROR(ENOSYS); else - return vulkan_transfer_data_to_mem(hwfc, dst, src); + return vulkan_transfer_data(hwfc, src, dst, 1); } } diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index 7f9c1b632..bd1333170 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -108,45 +108,69 @@ int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int wi return 0; } -int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, - uint8_t *ptr, const int linesizes[4]) +int av_image_fill_plane_sizes(size_t sizes[4], enum AVPixelFormat pix_fmt, + int height, const ptrdiff_t linesizes[4]) { - int i, total_size, size[4] = { 0 }, has_plane[4] = { 0 }; + int i, has_plane[4] = { 0 }; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - memset(data , 0, sizeof(data[0])*4); + memset(sizes , 0, sizeof(sizes[0])*4); if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) return AVERROR(EINVAL); - data[0] = ptr; - if (linesizes[0] > (INT_MAX - 1024) / height) + if (linesizes[0] > SIZE_MAX / height) return AVERROR(EINVAL); - size[0] = linesizes[0] * height; + sizes[0] = linesizes[0] * (size_t)height; if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & FF_PSEUDOPAL) { - data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */ - return size[0] + 256 * 4; + sizes[1] = 256 * 4; /* palette is stored here as 256 32 bits words */ + return 0; } for (i = 0; i < 4; i++) has_plane[desc->comp[i].plane] = 1; - total_size = size[0]; for (i = 1; i < 4 && has_plane[i]; i++) { int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; - data[i] = data[i-1] + size[i-1]; h = (height + (1 << s) - 1) >> s; - if (linesizes[i] > INT_MAX / h) + if (linesizes[i] > SIZE_MAX / h) return AVERROR(EINVAL); - size[i] = h * linesizes[i]; - if (total_size > INT_MAX - size[i]) - return AVERROR(EINVAL); - total_size += size[i]; + sizes[i] = (size_t)h * linesizes[i]; } - return total_size; + return 0; +} + +int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, + uint8_t *ptr, const int linesizes[4]) +{ + int i, ret; + ptrdiff_t linesizes1[4]; + size_t sizes[4]; + + memset(data , 0, sizeof(data[0])*4); + + for (i = 0; i < 4; i++) + linesizes1[i] = linesizes[i]; + + ret = av_image_fill_plane_sizes(sizes, pix_fmt, height, linesizes1); + if (ret < 0) + return ret; + + ret = 0; + for (i = 0; i < 4; i++) { + if (sizes[i] > INT_MAX - ret) + return AVERROR(EINVAL); + ret += sizes[i]; + } + + data[0] = ptr; + for (i = 1; i < 4 && sizes[i]; i++) + data[i] = data[i - 1] + sizes[i - 1]; + + return ret; } int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt) @@ -194,6 +218,8 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4], { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); int i, ret; + ptrdiff_t linesizes1[4]; + size_t total_size, sizes[4]; uint8_t *buf; if (!desc) @@ -204,12 +230,20 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4], if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, align>7 ? FFALIGN(w, 8) : w)) < 0) return ret; - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { linesizes[i] = FFALIGN(linesizes[i], align); + linesizes1[i] = linesizes[i]; + } - if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, NULL, linesizes)) < 0) + if ((ret = av_image_fill_plane_sizes(sizes, pix_fmt, h, linesizes1)) < 0) return ret; - buf = av_malloc(ret + align); + total_size = align; + for (i = 0; i < 4; i++) { + if (total_size > SIZE_MAX - sizes[i]) + return AVERROR(EINVAL); + total_size += sizes[i]; + } + buf = av_malloc(total_size); if (!buf) return AVERROR(ENOMEM); if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, buf, linesizes)) < 0) { @@ -220,6 +254,7 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4], avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt); if (align < 4) { av_log(NULL, AV_LOG_ERROR, "Formats with a palette require a minimum alignment of 4\n"); + av_free(buf); return AVERROR(EINVAL); } } @@ -431,9 +466,10 @@ int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align) { - uint8_t *data[4]; + int ret, i; int linesize[4]; - int ret; + ptrdiff_t aligned_linesize[4]; + size_t sizes[4]; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); if (!desc) return AVERROR(EINVAL); @@ -446,8 +482,24 @@ int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, if (desc->flags & FF_PSEUDOPAL) return FFALIGN(width, align) * height; - return av_image_fill_arrays(data, linesize, NULL, pix_fmt, - width, height, align); + ret = av_image_fill_linesizes(linesize, pix_fmt, width); + if (ret < 0) + return ret; + + for (i = 0; i < 4; i++) + aligned_linesize[i] = FFALIGN(linesize[i], align); + + ret = av_image_fill_plane_sizes(sizes, pix_fmt, height, aligned_linesize); + if (ret < 0) + return ret; + + ret = 0; + for (i = 0; i < 4; i++) { + if (sizes[i] > INT_MAX - ret) + return AVERROR(EINVAL); + ret += sizes[i]; + } + return ret; } int av_image_copy_to_buffer(uint8_t *dst, int dst_size, diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h index 5b790ecf0..5eccbf0bf 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -67,6 +67,20 @@ int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane); */ int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width); +/** + * Fill plane sizes for an image with pixel format pix_fmt and height height. + * + * @param size the array to be filled with the size of each image plane + * @param linesizes the array containing the linesize for each + * plane, should be filled by av_image_fill_linesizes() + * @return >= 0 in case of success, a negative error code otherwise + * + * @note The linesize parameters have the type ptrdiff_t here, while they are + * int for av_image_fill_linesizes(). + */ +int av_image_fill_plane_sizes(size_t size[4], enum AVPixelFormat pix_fmt, + int height, const ptrdiff_t linesizes[4]); + /** * Fill plane data pointers for an image with pixel format pix_fmt and * height height. diff --git a/libavutil/internal.h b/libavutil/internal.h index 4acbcf56c..2ed1c2abb 100644 --- a/libavutil/internal.h +++ b/libavutil/internal.h @@ -43,7 +43,6 @@ #include "cpu.h" #include "dict.h" #include "macros.h" -#include "mem.h" #include "pixfmt.h" #include "version.h" @@ -92,10 +91,6 @@ type av_##name##_get_##field(const str *s) { return s->field; } \ void av_##name##_set_##field(str *s, type v) { s->field = v; } -// Some broken preprocessors need a second expansion -// to be forced to tokenize __VA_ARGS__ -#define E1(x) x - /* Check if the hard coded offset of a struct member still matches reality. * Induce a compilation failure if not. */ @@ -103,75 +98,11 @@ int x_##o[offsetof(s, m) == o? 1: -1]; \ } -#define LOCAL_ALIGNED_A(a, t, v, s, o, ...) \ - uint8_t la_##v[sizeof(t s o) + (a)]; \ - t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a) -#define LOCAL_ALIGNED_D(a, t, v, s, o, ...) \ - DECLARE_ALIGNED(a, t, la_##v) s o; \ - t (*v) o = la_##v +#define FF_ALLOC_TYPED_ARRAY(p, nelem) (p = av_malloc_array(nelem, sizeof(*p))) +#define FF_ALLOCZ_TYPED_ARRAY(p, nelem) (p = av_mallocz_array(nelem, sizeof(*p))) -#define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_##a(t, v, __VA_ARGS__) - -#if HAVE_LOCAL_ALIGNED -# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_D(4, t, v, __VA_ARGS__,,)) -#else -# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_A(4, t, v, __VA_ARGS__,,)) -#endif - -#if HAVE_LOCAL_ALIGNED -# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,)) -#else -# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_A(8, t, v, __VA_ARGS__,,)) -#endif - -#if HAVE_LOCAL_ALIGNED -# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,)) -#else -# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_A(16, t, v, __VA_ARGS__,,)) -#endif - -#if HAVE_LOCAL_ALIGNED -# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,)) -#else -# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,)) -#endif - -#define FF_ALLOC_OR_GOTO(ctx, p, size, label)\ -{\ - p = av_malloc(size);\ - if (!(p) && (size) != 0) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} - -#define FF_ALLOCZ_OR_GOTO(ctx, p, size, label)\ -{\ - p = av_mallocz(size);\ - if (!(p) && (size) != 0) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} - -#define FF_ALLOC_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\ -{\ - p = av_malloc_array(nelem, elsize);\ - if (!p) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} - -#define FF_ALLOCZ_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\ -{\ - p = av_mallocz_array(nelem, elsize);\ - if (!p) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} +#define FF_PTR_ADD(ptr, off) ((off) ? (ptr) + (off) : (ptr)) #include "libm.h" @@ -353,7 +284,8 @@ void ff_check_pixfmt_descriptors(void); /** * Set a dictionary value to an ISO-8601 compliant timestamp string. * - * @param s AVFormatContext + * @param dict pointer to a pointer to a dictionary struct. If *dict is NULL + * a dictionary struct is allocated and put in *dict. * @param key metadata key * @param timestamp unix timestamp in microseconds * @return <0 on error @@ -369,4 +301,11 @@ int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t time #define FF_PSEUDOPAL 0 #endif +// Temporary typedef to simplify porting all AVBufferRef users to size_t +#if FF_API_BUFFER_SIZE_T +typedef int buffer_size_t; +#else +typedef size_t buffer_size_t; +#endif + #endif /* AVUTIL_INTERNAL_H */ diff --git a/libavutil/lls.h b/libavutil/lls.h index 1a276d537..5f849206f 100644 --- a/libavutil/lls.h +++ b/libavutil/lls.h @@ -24,7 +24,7 @@ #define AVUTIL_LLS_H #include "macros.h" -#include "mem.h" +#include "mem_internal.h" #include "version.h" #define MAX_VARS 32 diff --git a/libavutil/log.h b/libavutil/log.h index 9c14188a9..8edd6bbf2 100644 --- a/libavutil/log.h +++ b/libavutil/log.h @@ -112,6 +112,7 @@ typedef struct AVClass { */ void* (*child_next)(void *obj, void *prev); +#if FF_API_CHILD_CLASS_NEXT /** * Return an AVClass corresponding to the next potential * AVOptions-enabled child. @@ -120,7 +121,9 @@ typedef struct AVClass { * child_next iterates over _already existing_ objects, while * child_class_next iterates over _all possible_ children. */ + attribute_deprecated const struct AVClass* (*child_class_next)(const struct AVClass *prev); +#endif /** * Category used for visualization (like color) @@ -140,6 +143,21 @@ typedef struct AVClass { * available since version (52.12) */ int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); + + /** + * Iterate over the AVClasses corresponding to potential AVOptions-enabled + * children. + * + * @param iter pointer to opaque iteration state. The caller must initialize + * *iter to NULL before the first call. + * @return AVClass for the next AVOptions-enabled child or NULL if there are + * no more such children. + * + * @note The difference between child_next and this is that child_next + * iterates over _already existing_ objects, while child_class_iterate + * iterates over _all possible_ children. + */ + const struct AVClass* (*child_class_iterate)(void **iter); } AVClass; /** diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index da0fc17b2..2de2b39da 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -148,7 +148,7 @@ int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b) { int64_t a = tb_a.num * (int64_t)tb_b.den; int64_t b = tb_b.num * (int64_t)tb_a.den; - if ((FFABS(ts_a)|a|FFABS(ts_b)|b) <= INT_MAX) + if ((FFABS64U(ts_a)|a|FFABS64U(ts_b)|b) <= INT_MAX) return (ts_a*a > ts_b*b) - (ts_a*a < ts_b*b); if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b) return -1; diff --git a/libavutil/mem.h b/libavutil/mem.h index 5fb1a02dd..e21a1feaa 100644 --- a/libavutil/mem.h +++ b/libavutil/mem.h @@ -33,6 +33,7 @@ #include "attributes.h" #include "error.h" #include "avutil.h" +#include "version.h" /** * @addtogroup lavu_mem @@ -49,6 +50,10 @@ * dealing with memory consistently possible on all platforms. * * @{ + */ + +#if FF_API_DECLARE_ALIGNED +/** * * @defgroup lavu_mem_macros Alignment Macros * Helper macros for declaring aligned variables. @@ -125,6 +130,7 @@ /** * @} */ +#endif /** * @defgroup lavu_mem_attrs Function Attributes diff --git a/libavutil/mem_internal.h b/libavutil/mem_internal.h index 6fdbcb016..ee2575c85 100644 --- a/libavutil/mem_internal.h +++ b/libavutil/mem_internal.h @@ -21,8 +21,120 @@ #ifndef AVUTIL_MEM_INTERNAL_H #define AVUTIL_MEM_INTERNAL_H +#include "config.h" + +#include + #include "avassert.h" #include "mem.h" +#include "version.h" + +#if !FF_API_DECLARE_ALIGNED +/** + * @def DECLARE_ALIGNED(n,t,v) + * Declare a variable that is aligned in memory. + * + * @code{.c} + * DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42; + * DECLARE_ALIGNED(32, uint8_t, aligned_array)[128]; + * + * // The default-alignment equivalent would be + * uint16_t aligned_int = 42; + * uint8_t aligned_array[128]; + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_ALIGNED(n,t,v) + * Declare an aligned variable appropriate for use in inline assembly code. + * + * @code{.c} + * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_CONST(n,t,v) + * Declare a static constant aligned variable appropriate for use in inline + * assembly code. + * + * @code{.c} + * DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__DJGPP__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v +#elif defined(__GNUC__) || defined(__clang__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif +#endif + +// Some broken preprocessors need a second expansion +// to be forced to tokenize __VA_ARGS__ +#define E1(x) x + +#define LOCAL_ALIGNED_A(a, t, v, s, o, ...) \ + uint8_t la_##v[sizeof(t s o) + (a)]; \ + t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a) + +#define LOCAL_ALIGNED_D(a, t, v, s, o, ...) \ + DECLARE_ALIGNED(a, t, la_##v) s o; \ + t (*v) o = la_##v + +#define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_##a(t, v, __VA_ARGS__) + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_D(4, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_A(4, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_A(8, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_A(16, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,)) +#endif static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc) { diff --git a/libavutil/mips/Makefile b/libavutil/mips/Makefile index dbfa5aa34..5f8c9b64e 100644 --- a/libavutil/mips/Makefile +++ b/libavutil/mips/Makefile @@ -1 +1 @@ -OBJS += mips/float_dsp_mips.o +OBJS += mips/float_dsp_mips.o mips/cpu.o diff --git a/libavutil/mips/asmdefs.h b/libavutil/mips/asmdefs.h index 748119918..76bb2b93f 100644 --- a/libavutil/mips/asmdefs.h +++ b/libavutil/mips/asmdefs.h @@ -55,4 +55,46 @@ # define PTR_SLL "sll " #endif +/* + * parse_r var, r - Helper assembler macro for parsing register names. + * + * This converts the register name in $n form provided in \r to the + * corresponding register number, which is assigned to the variable \var. It is + * needed to allow explicit encoding of instructions in inline assembly where + * registers are chosen by the compiler in $n form, allowing us to avoid using + * fixed register numbers. + * + * It also allows newer instructions (not implemented by the assembler) to be + * transparently implemented using assembler macros, instead of needing separate + * cases depending on toolchain support. + * + * Simple usage example: + * __asm__ __volatile__("parse_r __rt, %0\n\t" + * ".insn\n\t" + * "# di %0\n\t" + * ".word (0x41606000 | (__rt << 16))" + * : "=r" (status); + */ + +/* Match an individual register number and assign to \var */ +#define _IFC_REG(n) \ + ".ifc \\r, $" #n "\n\t" \ + "\\var = " #n "\n\t" \ + ".endif\n\t" + +__asm__(".macro parse_r var r\n\t" + "\\var = -1\n\t" + _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) + _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) + _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) + _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) + _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) + _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) + _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) + _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) + ".iflt \\var\n\t" + ".error \"Unable to parse register name \\r\"\n\t" + ".endif\n\t" + ".endm"); + #endif /* AVCODEC_MIPS_ASMDEFS_H */ diff --git a/libavutil/mips/cpu.c b/libavutil/mips/cpu.c new file mode 100644 index 000000000..59619d54d --- /dev/null +++ b/libavutil/mips/cpu.c @@ -0,0 +1,134 @@ +/* + * 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/cpu_internal.h" +#include "config.h" +#if defined __linux__ || defined __ANDROID__ +#include +#include +#include +#include +#include "asmdefs.h" +#include "libavutil/avstring.h" +#endif + +#if defined __linux__ || defined __ANDROID__ + +#define HWCAP_LOONGSON_CPUCFG (1 << 14) + +static int cpucfg_available(void) +{ + return getauxval(AT_HWCAP) & HWCAP_LOONGSON_CPUCFG; +} + +/* Most toolchains have no CPUCFG support yet */ +static uint32_t read_cpucfg(uint32_t reg) +{ + uint32_t __res; + + __asm__ __volatile__( + "parse_r __res,%0\n\t" + "parse_r reg,%1\n\t" + ".insn \n\t" + ".word (0xc8080118 | (reg << 21) | (__res << 11))\n\t" + :"=r"(__res) + :"r"(reg) + : + ); + return __res; +} + +#define LOONGSON_CFG1 0x1 + +#define LOONGSON_CFG1_MMI (1 << 4) +#define LOONGSON_CFG1_MSA1 (1 << 5) + +static int cpu_flags_cpucfg(void) +{ + int flags = 0; + uint32_t cfg1 = read_cpucfg(LOONGSON_CFG1); + + if (cfg1 & LOONGSON_CFG1_MMI) + flags |= AV_CPU_FLAG_MMI; + + if (cfg1 & LOONGSON_CFG1_MSA1) + flags |= AV_CPU_FLAG_MSA; + + return flags; +} + +static int cpu_flags_cpuinfo(void) +{ + FILE *f = fopen("/proc/cpuinfo", "r"); + char buf[200]; + int flags = 0; + + if (!f) + return -1; + + while (fgets(buf, sizeof(buf), f)) { + /* Legacy kernel may not export MMI in ASEs implemented */ + if (av_strstart(buf, "cpu model", NULL)) { + if (strstr(buf, "Loongson-3 ")) + flags |= AV_CPU_FLAG_MMI; + } + + if (av_strstart(buf, "ASEs implemented", NULL)) { + if (strstr(buf, " loongson-mmi")) + flags |= AV_CPU_FLAG_MMI; + if (strstr(buf, " msa")) + flags |= AV_CPU_FLAG_MSA; + + break; + } + } + fclose(f); + return flags; +} +#endif + +int ff_get_cpu_flags_mips(void) +{ +#if defined __linux__ || defined __ANDROID__ + if (cpucfg_available()) + return cpu_flags_cpucfg(); + else + return cpu_flags_cpuinfo(); +#else + /* Assume no SIMD ASE supported */ + return 0; +#endif +} + +size_t ff_get_cpu_max_align_mips(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_MSA) + return 16; + + /* + * MMI itself is 64-bit but quad word load & store + * needs 128-bit align. + */ + if (flags & AV_CPU_FLAG_MMI) + return 16; + + return 8; +} diff --git a/libavutil/mips/cpu.h b/libavutil/mips/cpu.h new file mode 100644 index 000000000..615dc4975 --- /dev/null +++ b/libavutil/mips/cpu.h @@ -0,0 +1,28 @@ +/* + * 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 AVUTIL_MIPS_CPU_H +#define AVUTIL_MIPS_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define have_mmi(flags) CPUEXT(flags, MMI) +#define have_msa(flags) CPUEXT(flags, MSA) + +#endif /* AVUTIL_MIPS_CPU_H */ diff --git a/libavutil/mips/generic_macros_msa.h b/libavutil/mips/generic_macros_msa.h index 267d4e6ca..bb25e9fd7 100644 --- a/libavutil/mips/generic_macros_msa.h +++ b/libavutil/mips/generic_macros_msa.h @@ -111,10 +111,11 @@ uint32_t val_lw_m; \ \ __asm__ volatile ( \ - "ulw %[val_lw_m], %[psrc_lw_m] \n\t" \ + "lwr %[val_lw_m], 0(%[psrc_lw_m]) \n\t" \ + "lwl %[val_lw_m], 3(%[psrc_lw_m]) \n\t" \ \ - : [val_lw_m] "=r" (val_lw_m) \ - : [psrc_lw_m] "m" (*psrc_lw_m) \ + : [val_lw_m] "=&r"(val_lw_m) \ + : [psrc_lw_m] "r"(psrc_lw_m) \ ); \ \ val_lw_m; \ @@ -127,10 +128,11 @@ uint64_t val_ld_m = 0; \ \ __asm__ volatile ( \ - "uld %[val_ld_m], %[psrc_ld_m] \n\t" \ + "ldr %[val_ld_m], 0(%[psrc_ld_m]) \n\t" \ + "ldl %[val_ld_m], 7(%[psrc_ld_m]) \n\t" \ \ - : [val_ld_m] "=r" (val_ld_m) \ - : [psrc_ld_m] "m" (*psrc_ld_m) \ + : [val_ld_m] "=&r" (val_ld_m) \ + : [psrc_ld_m] "r" (psrc_ld_m) \ ); \ \ val_ld_m; \ diff --git a/libavutil/mips/mmiutils.h b/libavutil/mips/mmiutils.h index 8f692e86c..6a82caa90 100644 --- a/libavutil/mips/mmiutils.h +++ b/libavutil/mips/mmiutils.h @@ -25,6 +25,8 @@ #define AVUTIL_MIPS_MMIUTILS_H #include "config.h" + +#include "libavutil/mem_internal.h" #include "libavutil/mips/asmdefs.h" #if HAVE_LOONGSON2 diff --git a/libavutil/murmur3.c b/libavutil/murmur3.c index 796175251..3e85c3c94 100644 --- a/libavutil/murmur3.c +++ b/libavutil/murmur3.c @@ -17,6 +17,8 @@ * 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 "mem.h" #include "intreadwrite.h" diff --git a/libavutil/murmur3.h b/libavutil/murmur3.h index 1b09175c1..b3b3a07de 100644 --- a/libavutil/murmur3.h +++ b/libavutil/murmur3.h @@ -27,6 +27,7 @@ #ifndef AVUTIL_MURMUR3_H #define AVUTIL_MURMUR3_H +#include #include #include "version.h" diff --git a/libavutil/opt.c b/libavutil/opt.c index 423313bce..590146b5f 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -1245,6 +1245,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.'); av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.'); av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_RUNTIME_PARAM) ? 'T' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DEPRECATED) ? 'P' : '.'); if (opt->help) av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); @@ -1679,8 +1680,9 @@ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, if (search_flags & AV_OPT_SEARCH_CHILDREN) { if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { - const AVClass *child = NULL; - while (child = av_opt_child_class_next(c, child)) + void *iter = NULL; + const AVClass *child; + while (child = av_opt_child_class_iterate(c, &iter)) if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) return o; } else { @@ -1715,12 +1717,31 @@ void *av_opt_child_next(void *obj, void *prev) return NULL; } +#if FF_API_CHILD_CLASS_NEXT +FF_DISABLE_DEPRECATION_WARNINGS const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev) { if (parent->child_class_next) return parent->child_class_next(prev); return NULL; } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter) +{ + if (parent->child_class_iterate) + return parent->child_class_iterate(iter); +#if FF_API_CHILD_CLASS_NEXT +FF_DISABLE_DEPRECATION_WARNINGS + if (parent->child_class_next) { + *iter = parent->child_class_next(*iter); + return *iter; + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + return NULL; +} void *av_opt_ptr(const AVClass *class, void *obj, const char *name) { @@ -2100,6 +2121,8 @@ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, av_freep(&buf); } } - av_bprint_finalize(&bprint, buffer); + ret = av_bprint_finalize(&bprint, buffer); + if (ret < 0) + return ret; return 0; } diff --git a/libavutil/opt.h b/libavutil/opt.h index e46119572..8dc020a82 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -114,7 +114,7 @@ * libavcodec exports generic options, while its priv_data field exports * codec-specific options). In such a case, it is possible to set up the * parent struct to export a child's options. To do that, simply - * implement AVClass.child_next() and AVClass.child_class_next() in the + * implement AVClass.child_next() and AVClass.child_class_iterate() in the * parent struct's AVClass. * Assuming that the test_struct from above now also contains a * child_struct field: @@ -143,23 +143,25 @@ * return t->child_struct; * return NULL * } - * const AVClass child_class_next(const AVClass *prev) + * const AVClass child_class_iterate(void **iter) * { - * return prev ? NULL : &child_class; + * const AVClass *c = *iter ? NULL : &child_class; + * *iter = (void*)(uintptr_t)c; + * return c; * } * @endcode - * Putting child_next() and child_class_next() as defined above into + * Putting child_next() and child_class_iterate() as defined above into * test_class will now make child_struct's options accessible through * test_struct (again, proper setup as described above needs to be done on * child_struct right after it is created). * * From the above example it might not be clear why both child_next() - * and child_class_next() are needed. The distinction is that child_next() - * iterates over actually existing objects, while child_class_next() + * and child_class_iterate() are needed. The distinction is that child_next() + * iterates over actually existing objects, while child_class_iterate() * iterates over all possible child classes. E.g. if an AVCodecContext * was initialized to use a codec which has private options, then its * child_next() will return AVCodecContext.priv_data and finish - * iterating. OTOH child_class_next() on AVCodecContext.av_class will + * iterating. OTOH child_class_iterate() on AVCodecContext.av_class will * iterate over all available codecs with private options. * * @subsection avoptions_implement_named_constants Named constants @@ -194,7 +196,7 @@ * For enumerating there are basically two cases. The first is when you want to * get all options that may potentially exist on the struct and its children * (e.g. when constructing documentation). In that case you should call - * av_opt_child_class_next() recursively on the parent struct's AVClass. The + * av_opt_child_class_iterate() recursively on the parent struct's AVClass. The * second case is when you have an already initialized struct with all its * children and you want to get all options that can be actually written or read * from it. In that case you should call av_opt_child_next() recursively (and @@ -646,13 +648,26 @@ const AVOption *av_opt_next(const void *obj, const AVOption *prev); */ void *av_opt_child_next(void *obj, void *prev); +#if FF_API_CHILD_CLASS_NEXT /** * Iterate over potential AVOptions-enabled children of parent. * * @param prev result of a previous call to this function or NULL * @return AVClass corresponding to next potential child or NULL + * + * @deprecated use av_opt_child_class_iterate */ +attribute_deprecated const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev); +#endif + +/** + * Iterate over potential AVOptions-enabled children of parent. + * + * @param iter a pointer where iteration state is stored. + * @return AVClass corresponding to next potential child or NULL + */ +const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter); /** * @defgroup opt_set_funcs Option setting functions diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c index 167e82264..7f678cd85 100644 --- a/libavutil/parseutils.c +++ b/libavutil/parseutils.c @@ -736,12 +736,14 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) if (*q) return AVERROR(EINVAL); - if (INT64_MAX / suffix < t) + if (INT64_MAX / suffix < t || t < INT64_MIN / suffix) return AVERROR(ERANGE); t *= suffix; if (INT64_MAX - microseconds < t) return AVERROR(ERANGE); t += microseconds; + if (t == INT64_MIN && negative) + return AVERROR(ERANGE); *timeval = negative ? -t : t; return 0; } diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 9d61c5256..18c7a0efc 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -252,6 +252,30 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_RGB, }, + [AV_PIX_FMT_X2RGB10LE] = { + .name = "x2rgb10le", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 2, 4, 10, 3, 9, 2 }, /* R */ + { 0, 4, 1, 2, 10, 3, 9, 3 }, /* G */ + { 0, 4, 0, 0, 10, 3, 9, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_X2RGB10BE] = { + .name = "x2rgb10be", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 0, 4, 10, 3, 9, 2 }, /* R */ + { 0, 4, 1, 2, 10, 3, 9, 3 }, /* G */ + { 0, 4, 2, 0, 10, 3, 9, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE, + }, [AV_PIX_FMT_YUV422P] = { .name = "yuv422p", .nb_components = 3, @@ -2635,7 +2659,7 @@ void ff_check_pixfmt_descriptors(void){ continue; av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 0); av_assert0(tmp[0] == 0 && tmp[1] == 0); - tmp[0] = tmp[1] = (1<depth) - 1; + tmp[0] = tmp[1] = (1ULL << c->depth) - 1; av_write_image_line(tmp, data, linesize, d, 0, 0, j, 2); } } @@ -2678,11 +2702,13 @@ static int get_color_type(const AVPixFmtDescriptor *desc) { 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->name) { + if (av_strstart(desc->name, "yuvj", NULL)) + return FF_COLOR_YUV_JPEG; - if(desc->name && !strncmp(desc->name, "xyz", 3)) - return FF_COLOR_XYZ; + if (av_strstart(desc->name, "xyz", NULL)) + return FF_COLOR_XYZ; + } if(desc->flags & AV_PIX_FMT_FLAG_RGB) return FF_COLOR_RGB; @@ -2883,8 +2909,7 @@ int av_color_range_from_name(const char *name) int i; for (i = 0; i < FF_ARRAY_ELEMS(color_range_names); i++) { - size_t len = strlen(color_range_names[i]); - if (!strncmp(color_range_names[i], name, len)) + if (av_strstart(name, color_range_names[i], NULL)) return i; } @@ -2902,13 +2927,10 @@ int av_color_primaries_from_name(const char *name) int i; for (i = 0; i < FF_ARRAY_ELEMS(color_primaries_names); i++) { - size_t len; - if (!color_primaries_names[i]) continue; - len = strlen(color_primaries_names[i]); - if (!strncmp(color_primaries_names[i], name, len)) + if (av_strstart(name, color_primaries_names[i], NULL)) return i; } @@ -2926,13 +2948,10 @@ int av_color_transfer_from_name(const char *name) int i; for (i = 0; i < FF_ARRAY_ELEMS(color_transfer_names); i++) { - size_t len; - if (!color_transfer_names[i]) continue; - len = strlen(color_transfer_names[i]); - if (!strncmp(color_transfer_names[i], name, len)) + if (av_strstart(name, color_transfer_names[i], NULL)) return i; } @@ -2950,13 +2969,10 @@ int av_color_space_from_name(const char *name) int i; for (i = 0; i < FF_ARRAY_ELEMS(color_space_names); i++) { - size_t len; - if (!color_space_names[i]) continue; - len = strlen(color_space_names[i]); - if (!strncmp(color_space_names[i], name, len)) + if (av_strstart(name, color_space_names[i], NULL)) return i; } @@ -2974,13 +2990,10 @@ int av_chroma_location_from_name(const char *name) int i; for (i = 0; i < FF_ARRAY_ELEMS(chroma_location_names); i++) { - size_t len; - if (!chroma_location_names[i]) continue; - len = strlen(chroma_location_names[i]); - if (!strncmp(chroma_location_names[i], name, len)) + if (av_strstart(name, chroma_location_names[i], NULL)) return i; } diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h index c055810ae..9b9d386ae 100644 --- a/libavutil/pixdesc.h +++ b/libavutil/pixdesc.h @@ -147,6 +147,7 @@ typedef struct AVPixFmtDescriptor { */ #define AV_PIX_FMT_FLAG_RGB (1 << 5) +#if FF_API_PSEUDOPAL /** * The pixel format is "pseudo-paletted". This means that it contains a * fixed palette in the 2nd plane but the palette is fixed/constant for each @@ -164,6 +165,7 @@ typedef struct AVPixFmtDescriptor { * before the deprecation, though). */ #define AV_PIX_FMT_FLAG_PSEUDOPAL (1 << 6) +#endif /** * The pixel format has an alpha channel. This is set on all formats that diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 1c625cfc8..46ef211ad 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -358,6 +358,8 @@ enum AVPixelFormat { AV_PIX_FMT_Y210BE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, big-endian AV_PIX_FMT_Y210LE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, little-endian + AV_PIX_FMT_X2RGB10LE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), little-endian, X=unused/undefined + AV_PIX_FMT_X2RGB10BE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), big-endian, X=unused/undefined AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -447,6 +449,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE) #define AV_PIX_FMT_Y210 AV_PIX_FMT_NE(Y210BE, Y210LE) +#define AV_PIX_FMT_X2RGB10 AV_PIX_FMT_NE(X2RGB10BE, X2RGB10LE) /** * Chromaticity coordinates of the source primaries. @@ -527,12 +530,60 @@ enum AVColorSpace { }; /** - * MPEG vs JPEG YUV range. + * Visual content value range. + * + * These values are based on definitions that can be found in multiple + * specifications, such as ITU-T BT.709 (3.4 - Quantization of RGB, luminance + * and colour-difference signals), ITU-T BT.2020 (Table 5 - Digital + * Representation) as well as ITU-T BT.2100 (Table 9 - Digital 10- and 12-bit + * integer representation). At the time of writing, the BT.2100 one is + * recommended, as it also defines the full range representation. + * + * Common definitions: + * - For RGB and luminance planes such as Y in YCbCr and I in ICtCp, + * 'E' is the original value in range of 0.0 to 1.0. + * - For chrominance planes such as Cb,Cr and Ct,Cp, 'E' is the original + * value in range of -0.5 to 0.5. + * - 'n' is the output bit depth. + * - For additional definitions such as rounding and clipping to valid n + * bit unsigned integer range, please refer to BT.2100 (Table 9). */ 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 + + /** + * Narrow or limited range content. + * + * - For luminance planes: + * + * (219 * E + 16) * 2^(n-8) + * + * F.ex. the range of 16-235 for 8 bits + * + * - For chrominance planes: + * + * (224 * E + 128) * 2^(n-8) + * + * F.ex. the range of 16-240 for 8 bits + */ + AVCOL_RANGE_MPEG = 1, + + /** + * Full range content. + * + * - For RGB and luminance planes: + * + * (2^n - 1) * E + * + * F.ex. the range of 0-255 for 8 bits + * + * - For chrominance planes: + * + * (2^n - 1) * E + 2^(n - 1) + * + * F.ex. the range of 1-255 for 8 bits + */ + AVCOL_RANGE_JPEG = 2, AVCOL_RANGE_NB ///< Not part of ABI }; diff --git a/libavutil/ripemd.c b/libavutil/ripemd.c index 4f1c4ea89..89d69cc23 100644 --- a/libavutil/ripemd.c +++ b/libavutil/ripemd.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include "attributes.h" diff --git a/libavutil/ripemd.h b/libavutil/ripemd.h index 0db6858ff..921aa6668 100644 --- a/libavutil/ripemd.h +++ b/libavutil/ripemd.h @@ -28,6 +28,7 @@ #ifndef AVUTIL_RIPEMD_H #define AVUTIL_RIPEMD_H +#include #include #include "attributes.h" diff --git a/libavutil/spherical.c b/libavutil/spherical.c index 4be55f36c..ed66344a2 100644 --- a/libavutil/spherical.c +++ b/libavutil/spherical.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "avstring.h" #include "mem.h" #include "spherical.h" @@ -51,7 +52,7 @@ void av_spherical_tile_bounds(const AVSphericalMapping *map, *bottom = orig_height - height - *top; } -static const char *spherical_projection_names[] = { +static const char *const spherical_projection_names[] = { [AV_SPHERICAL_EQUIRECTANGULAR] = "equirectangular", [AV_SPHERICAL_CUBEMAP] = "cubemap", [AV_SPHERICAL_EQUIRECTANGULAR_TILE] = "tiled equirectangular", @@ -70,8 +71,7 @@ int av_spherical_from_name(const char *name) int i; for (i = 0; i < FF_ARRAY_ELEMS(spherical_projection_names); i++) { - size_t len = strlen(spherical_projection_names[i]); - if (!strncmp(spherical_projection_names[i], name, len)) + if (av_strstart(name, spherical_projection_names[i], NULL)) return i; } diff --git a/libavutil/stereo3d.c b/libavutil/stereo3d.c index 6edcdb179..279fcc1ff 100644 --- a/libavutil/stereo3d.c +++ b/libavutil/stereo3d.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include +#include "avstring.h" #include "common.h" #include "mem.h" #include "stereo3d.h" @@ -67,8 +67,7 @@ int av_stereo3d_from_name(const char *name) int i; for (i = 0; i < FF_ARRAY_ELEMS(stereo3d_type_names); i++) { - size_t len = strlen(stereo3d_type_names[i]); - if (!strncmp(stereo3d_type_names[i], name, len)) + if (av_strstart(name, stereo3d_type_names[i], NULL)) return i; } diff --git a/libavutil/tests/aes_ctr.c b/libavutil/tests/aes_ctr.c index 00fdb05d1..53d0e4a24 100644 --- a/libavutil/tests/aes_ctr.c +++ b/libavutil/tests/aes_ctr.c @@ -18,6 +18,7 @@ #include "libavutil/log.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavutil/aes_ctr.h" static const DECLARE_ALIGNED(8, uint8_t, plain)[] = { diff --git a/libavutil/tests/avstring.c b/libavutil/tests/avstring.c index 887bd25a1..37a2cf183 100644 --- a/libavutil/tests/avstring.c +++ b/libavutil/tests/avstring.c @@ -109,6 +109,8 @@ int main(void) TEST_STRIREPLACE(haystack, needle [2], "Education consists mainly in what we have instead."); TEST_STRIREPLACE(haystack, needle [1], "Education consists mainly in what we have instead"); +#if FF_API_D2STR +FF_DISABLE_DEPRECATION_WARNINGS /*Testing av_d2str()*/ #define TEST_D2STR(value, expected) \ if((ptr = av_d2str(value)) == NULL){ \ @@ -121,5 +123,7 @@ int main(void) TEST_D2STR(0 , "0.000000"); TEST_D2STR(-1.2333234, "-1.233323"); TEST_D2STR(-1.2333237, "-1.233324"); +FF_ENABLE_DEPRECATION_WARNINGS +#endif return 0; } diff --git a/libavutil/tests/cpu.c b/libavutil/tests/cpu.c index ce45b715a..c853371fb 100644 --- a/libavutil/tests/cpu.c +++ b/libavutil/tests/cpu.c @@ -49,6 +49,9 @@ static const struct { { AV_CPU_FLAG_SETEND, "setend" }, #elif ARCH_PPC { AV_CPU_FLAG_ALTIVEC, "altivec" }, +#elif ARCH_MIPS + { AV_CPU_FLAG_MMI, "mmi" }, + { AV_CPU_FLAG_MSA, "msa" }, #elif ARCH_X86 { AV_CPU_FLAG_MMX, "mmx" }, { AV_CPU_FLAG_MMXEXT, "mmxext" }, diff --git a/libavutil/tests/des.c b/libavutil/tests/des.c index f2a5c34f1..8fa88df68 100644 --- a/libavutil/tests/des.c +++ b/libavutil/tests/des.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mem_internal.h" #include "libavutil/timer.h" #include "libavutil/des.c" diff --git a/libavutil/tests/imgutils.c b/libavutil/tests/imgutils.c index 571045c85..748bd6c9d 100644 --- a/libavutil/tests/imgutils.c +++ b/libavutil/tests/imgutils.c @@ -22,6 +22,7 @@ int main(void) { + const AVPixFmtDescriptor *desc = NULL; int64_t x, y; for (y = -1; yname); + for (i = 0; i < 4 && data[i]; i++); + printf("planes: %d", i); + // Test the output of av_image_fill_linesizes() + printf(", linesizes:"); + for (i = 0; i < 4; i++) + printf(" %3d", linesizes[i]); + // Test the output of av_image_fill_plane_sizes() + printf(", plane_sizes:"); + for (i = 0; i < 4; i++) + printf(" %5"SIZE_SPECIFIER, sizes[i]); + // Test the output of av_image_fill_pointers() + for (i = 0; i < 3 && data[i + 1]; i++) + offsets[i] = data[i + 1] - data[i]; + printf(", plane_offsets:"); + for (i = 0; i < 3; i++) + printf(" %5"PTRDIFF_SPECIFIER, offsets[i]); + printf(", total_size: %d\n", total_size); + } return 0; } diff --git a/libavutil/tests/lls.c b/libavutil/tests/lls.c index 965b0f458..4c14c0c4b 100644 --- a/libavutil/tests/lls.c +++ b/libavutil/tests/lls.c @@ -22,6 +22,7 @@ #include "libavutil/internal.h" #include "libavutil/lfg.h" #include "libavutil/lls.h" +#include "libavutil/mem_internal.h" int main(void) { diff --git a/libavutil/time.c b/libavutil/time.c index afa6658aa..740afc478 100644 --- a/libavutil/time.c +++ b/libavutil/time.c @@ -57,7 +57,7 @@ int64_t av_gettime_relative(void) { #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) #ifdef __APPLE__ - if (clock_gettime) + if (&clock_gettime) #endif { struct timespec ts; @@ -72,7 +72,7 @@ int av_gettime_relative_is_monotonic(void) { #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) #ifdef __APPLE__ - if (!clock_gettime) + if (!&clock_gettime) return 0; #endif return 1; diff --git a/libavutil/timecode.c b/libavutil/timecode.c index 76163d555..2fc3295e2 100644 --- a/libavutil/timecode.c +++ b/libavutil/timecode.c @@ -33,16 +33,13 @@ int av_timecode_adjust_ntsc_framenum2(int framenum, int fps) { - /* only works for NTSC 29.97 and 59.94 */ + /* only works for multiples of NTSC 29.97 */ int drop_frames = 0; int d, m, frames_per_10mins; - if (fps == 30) { - drop_frames = 2; - frames_per_10mins = 17982; - } else if (fps == 60) { - drop_frames = 4; - frames_per_10mins = 35964; + if (fps && fps % 30 == 0) { + drop_frames = fps / 30 * 2; + frames_per_10mins = fps / 30 * 17982; } else return framenum; @@ -65,20 +62,41 @@ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) ss = framenum / fps % 60; mm = framenum / (fps*60) % 60; hh = framenum / (fps*3600) % 24; - return 0 << 31 | // color frame flag (0: unsync mode, 1: sync mode) - drop << 30 | // drop frame flag (0: non drop, 1: drop) - (ff / 10) << 28 | // tens of frames - (ff % 10) << 24 | // units of frames - 0 << 23 | // PC (NTSC) or BGF0 (PAL) - (ss / 10) << 20 | // tens of seconds - (ss % 10) << 16 | // units of seconds - 0 << 15 | // BGF0 (NTSC) or BGF2 (PAL) - (mm / 10) << 12 | // tens of minutes - (mm % 10) << 8 | // units of minutes - 0 << 7 | // BGF2 (NTSC) or PC (PAL) - 0 << 6 | // BGF1 - (hh / 10) << 4 | // tens of hours - (hh % 10); // units of hours + return av_timecode_get_smpte(tc->rate, drop, hh, mm, ss, ff); +} + +uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss, int ff) +{ + uint32_t tc = 0; + + /* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS. + See SMPTE ST 12-1:2014 Sec 12.1 for more info. */ + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { + if (ff % 2 == 1) { + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) + tc |= (1 << 7); + else + tc |= (1 << 23); + } + ff /= 2; + } + + hh = hh % 24; + mm = av_clip(mm, 0, 59); + ss = av_clip(ss, 0, 59); + ff = ff % 40; + + tc |= drop << 30; + tc |= (ff / 10) << 28; + tc |= (ff % 10) << 24; + tc |= (ss / 10) << 20; + tc |= (ss % 10) << 16; + tc |= (mm / 10) << 12; + tc |= (mm % 10) << 8; + tc |= (hh / 10) << 4; + tc |= (hh % 10); + + return tc; } char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum) @@ -96,8 +114,8 @@ char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum) } ff = framenum % fps; ss = framenum / fps % 60; - mm = framenum / (fps*60) % 60; - hh = framenum / (fps*3600); + mm = framenum / (fps*60LL) % 60; + hh = framenum / (fps*3600LL); if (tc->flags & AV_TIMECODE_FLAG_24HOURSMAX) hh = hh % 24; snprintf(buf, AV_TIMECODE_STR_SIZE, "%s%02d:%02d:%02d%c%02d", @@ -115,16 +133,33 @@ static unsigned bcd2uint(uint8_t bcd) return low + 10*high; } -char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df) +char *av_timecode_make_smpte_tc_string2(char *buf, AVRational rate, uint32_t tcsmpte, int prevent_df, int skip_field) { unsigned hh = bcd2uint(tcsmpte & 0x3f); // 6-bit hours unsigned mm = bcd2uint(tcsmpte>>8 & 0x7f); // 7-bit minutes unsigned ss = bcd2uint(tcsmpte>>16 & 0x7f); // 7-bit seconds unsigned ff = bcd2uint(tcsmpte>>24 & 0x3f); // 6-bit frames unsigned drop = tcsmpte & 1<<30 && !prevent_df; // 1-bit drop if not arbitrary bit + + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { + ff <<= 1; + if (!skip_field) { + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) + ff += !!(tcsmpte & 1 << 7); + else + ff += !!(tcsmpte & 1 << 23); + } + } + snprintf(buf, AV_TIMECODE_STR_SIZE, "%02u:%02u:%02u%c%02u", hh, mm, ss, drop ? ';' : ':', ff); return buf; + +} + +char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df) +{ + return av_timecode_make_smpte_tc_string2(buf, (AVRational){30, 1}, tcsmpte, prevent_df, 1); } char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit) @@ -158,8 +193,8 @@ static int check_timecode(void *log_ctx, AVTimecode *tc) av_log(log_ctx, AV_LOG_ERROR, "Valid timecode frame rate must be specified. Minimum value is 1\n"); return AVERROR(EINVAL); } - if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps != 30 && tc->fps != 60) { - av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 or 60000/1001 FPS\n"); + if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps % 30 != 0) { + av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with multiples of 30000/1001 FPS\n"); return AVERROR(EINVAL); } if (check_fps(tc->fps) < 0) { @@ -191,19 +226,12 @@ int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start return check_timecode(log_ctx, tc); } -int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx) +int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, int hh, int mm, int ss, int ff, void *log_ctx) { - char c; - int hh, mm, ss, ff, ret; - - if (sscanf(str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) { - av_log(log_ctx, AV_LOG_ERROR, "Unable to parse timecode, " - "syntax: hh:mm:ss[:;.]ff\n"); - return AVERROR_INVALIDDATA; - } + int ret; memset(tc, 0, sizeof(*tc)); - tc->flags = c != ':' ? AV_TIMECODE_FLAG_DROPFRAME : 0; // drop if ';', '.', ... + tc->flags = flags; tc->rate = rate; tc->fps = fps_from_frame_rate(rate); @@ -214,7 +242,22 @@ int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *st tc->start = (hh*3600 + mm*60 + ss) * tc->fps + ff; if (tc->flags & AV_TIMECODE_FLAG_DROPFRAME) { /* adjust frame number */ int tmins = 60*hh + mm; - tc->start -= (tc->fps == 30 ? 2 : 4) * (tmins - tmins/10); + tc->start -= (tc->fps / 30 * 2) * (tmins - tmins/10); } return 0; } + +int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx) +{ + char c; + int hh, mm, ss, ff, flags; + + if (sscanf(str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) { + av_log(log_ctx, AV_LOG_ERROR, "Unable to parse timecode, " + "syntax: hh:mm:ss[:;.]ff\n"); + return AVERROR_INVALIDDATA; + } + flags = c != ':' ? AV_TIMECODE_FLAG_DROPFRAME : 0; // drop if ';', '.', ... + + return av_timecode_init_from_components(tc, rate, flags, hh, mm, ss, ff, log_ctx); +} diff --git a/libavutil/timecode.h b/libavutil/timecode.h index 37c1361bc..060574a17 100644 --- a/libavutil/timecode.h +++ b/libavutil/timecode.h @@ -49,9 +49,9 @@ typedef struct { * Adjust frame number for NTSC drop frame time code. * * @param framenum frame number to adjust - * @param fps frame per second, 30 or 60 + * @param fps frame per second, multiples of 30 * @return adjusted frame number - * @warning adjustment is only valid in NTSC 29.97 and 59.94 + * @warning adjustment is only valid for multiples of NTSC 29.97 */ int av_timecode_adjust_ntsc_framenum2(int framenum, int fps); @@ -62,14 +62,39 @@ int av_timecode_adjust_ntsc_framenum2(int framenum, int fps); * @param framenum frame number * @return the SMPTE binary representation * + * See SMPTE ST 314M-2005 Sec 4.4.2.2.1 "Time code pack (TC)" + * the format description as follows: + * bits 0-5: hours, in BCD(6bits) + * bits 6: BGF1 + * bits 7: BGF2 (NTSC) or FIELD (PAL) + * bits 8-14: minutes, in BCD(7bits) + * bits 15: BGF0 (NTSC) or BGF2 (PAL) + * bits 16-22: seconds, in BCD(7bits) + * bits 23: FIELD (NTSC) or BGF0 (PAL) + * bits 24-29: frames, in BCD(6bits) + * bits 30: drop frame flag (0: non drop, 1: drop) + * bits 31: color frame flag (0: unsync mode, 1: sync mode) + * @note BCD numbers (6 or 7 bits): 4 or 5 lower bits for units, 2 higher bits for tens. * @note Frame number adjustment is automatically done in case of drop timecode, * you do NOT have to call av_timecode_adjust_ntsc_framenum2(). * @note The frame number is relative to tc->start. - * @note Color frame (CF), binary group flags (BGF) and biphase mark polarity - * correction (PC) bits are set to zero. + * @note Color frame (CF) and binary group flags (BGF) bits are set to zero. */ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum); +/** + * Convert sei info to SMPTE 12M binary representation. + * + * @param rate frame rate in rational form + * @param drop drop flag + * @param hh hour + * @param mm minute + * @param ss second + * @param ff frame number + * @return the SMPTE binary representation + */ +uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss, int ff); + /** * Load timecode string in buf. * @@ -84,6 +109,23 @@ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) */ char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum); +/** + * Get the timecode string from the SMPTE timecode format. + * + * In contrast to av_timecode_make_smpte_tc_string this function supports 50/60 + * fps timecodes by using the field bit. + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param rate frame rate of the timecode + * @param tcsmpte the 32-bit SMPTE timecode + * @param prevent_df prevent the use of a drop flag when it is known the DF bit + * is arbitrary + * @param skip_field prevent the use of a field flag when it is known the field + * bit is arbitrary (e.g. because it is used as PC flag) + * @return the buf parameter + */ +char *av_timecode_make_smpte_tc_string2(char *buf, AVRational rate, uint32_t tcsmpte, int prevent_df, int skip_field); + /** * Get the timecode string from the SMPTE timecode format. * @@ -118,6 +160,23 @@ char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit); */ int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx); +/** + * Init a timecode struct from the passed timecode components. + * + * @param log_ctx a pointer to an arbitrary struct of which the first field + * is a pointer to an AVClass struct (used for av_log) + * @param tc pointer to an allocated AVTimecode + * @param rate frame rate in rational form + * @param flags miscellaneous flags such as drop frame, +24 hours, ... + * (see AVTimecodeFlag) + * @param hh hours + * @param mm minutes + * @param ss seconds + * @param ff frames + * @return 0 on success, AVERROR otherwise + */ +int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, int hh, int mm, int ss, int ff, void *log_ctx); + /** * Parse timecode representation (hh:mm:ss[:;.]ff). * diff --git a/libavutil/timer.h b/libavutil/timer.h index 0bb353cfc..36f920e96 100644 --- a/libavutil/timer.h +++ b/libavutil/timer.h @@ -87,7 +87,7 @@ if (((tcount + tskip_count) & (tcount + tskip_count - 1)) == 0) { \ int i; \ av_log(NULL, AV_LOG_ERROR, \ - "%7"PRIu64" " FF_TIMER_UNITS " in %s,%8d runs,%7d skips", \ + "%7" PRIu64 " " FF_TIMER_UNITS " in %s,%8d runs,%7d skips",\ tsum * 10 / tcount, id, tcount, tskip_count); \ for (i = 0; i < 32; i++) \ av_log(NULL, AV_LOG_VERBOSE, " %2d", av_log2(2*thistogram[i]));\ diff --git a/libavutil/tx.c b/libavutil/tx.c index 3b0568a5e..1161df328 100644 --- a/libavutil/tx.c +++ b/libavutil/tx.c @@ -91,7 +91,7 @@ int ff_tx_gen_compound_mapping(AVTXContext *s) return 0; } -int ff_tx_gen_ptwo_revtab(AVTXContext *s) +int ff_tx_gen_ptwo_revtab(AVTXContext *s, int invert_lookup) { const int m = s->m, inv = s->inv; @@ -101,12 +101,48 @@ int ff_tx_gen_ptwo_revtab(AVTXContext *s) /* Default */ for (int i = 0; i < m; i++) { int k = -split_radix_permutation(i, m, inv) & (m - 1); - s->revtab[k] = i; + if (invert_lookup) + s->revtab[i] = k; + else + s->revtab[k] = i; } return 0; } +int ff_tx_gen_ptwo_inplace_revtab_idx(AVTXContext *s) +{ + int nb_inplace_idx = 0; + + if (!(s->inplace_idx = av_malloc(s->m*sizeof(*s->inplace_idx)))) + return AVERROR(ENOMEM); + + for (int src = 1; src < s->m; src++) { + int dst = s->revtab[src]; + int found = 0; + + if (dst <= src) + continue; + + do { + for (int j = 0; j < nb_inplace_idx; j++) { + if (dst == s->inplace_idx[j]) { + found = 1; + break; + } + } + dst = s->revtab[dst]; + } while (dst != src && !found); + + if (!found) + s->inplace_idx[nb_inplace_idx++] = src; + } + + s->inplace_idx[nb_inplace_idx++] = 0; + + return 0; +} + av_cold void av_tx_uninit(AVTXContext **ctx) { if (!(*ctx)) @@ -115,6 +151,7 @@ av_cold void av_tx_uninit(AVTXContext **ctx) av_free((*ctx)->pfatab); av_free((*ctx)->exptab); av_free((*ctx)->revtab); + av_free((*ctx)->inplace_idx); av_free((*ctx)->tmp); av_freep(ctx); diff --git a/libavutil/tx.h b/libavutil/tx.h index 418e8ec1e..bfc0c7f2a 100644 --- a/libavutil/tx.h +++ b/libavutil/tx.h @@ -43,6 +43,7 @@ enum AVTXType { * The stride parameter is ignored. */ AV_TX_FLOAT_FFT = 0, + /** * Standard MDCT with sample data type of float and a scale type of * float. Length is the frame size, not the window size (which is 2x frame) @@ -51,21 +52,27 @@ enum AVTXType { * For inverse transforms, the stride specifies the spacing between each * sample in the input array in bytes. The output will be a flat array. * Stride must be a non-zero multiple of sizeof(float). + * NOTE: the inverse transform is half-length, meaning the output will not + * contain redundant data. This is what most codecs work with. */ AV_TX_FLOAT_MDCT = 1, + /** * Same as AV_TX_FLOAT_FFT with a data type of AVComplexDouble. */ AV_TX_DOUBLE_FFT = 2, + /** * Same as AV_TX_FLOAT_MDCT with data and scale type of double. * Stride must be a non-zero multiple of sizeof(double). */ AV_TX_DOUBLE_MDCT = 3, + /** * Same as AV_TX_FLOAT_FFT with a data type of AVComplexInt32. */ AV_TX_INT32_FFT = 4, + /** * Same as AV_TX_FLOAT_MDCT with data type of int32_t and scale type of float. * Only scale values less than or equal to 1.0 are supported. @@ -91,10 +98,21 @@ enum AVTXType { */ typedef void (*av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride); +/** + * Flags for av_tx_init() + */ +enum AVTXFlags { + /** + * Performs an in-place transformation on the input. The output argument + * of av_tn_fn() MUST match the input. May be unsupported or slower for some + * transform types. + */ + AV_TX_INPLACE = 1ULL << 0, +}; + /** * Initialize a transform context with the given configuration - * Currently power of two lengths from 2 to 131072 are supported, along with - * any length decomposable to a power of two and either 3, 5 or 15. + * (i)MDCTs with an odd length are currently not supported. * * @param ctx the context to allocate, will be NULL on error * @param tx pointer to the transform function pointer to set @@ -102,7 +120,7 @@ typedef void (*av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride); * @param inv whether to do an inverse or a forward transform * @param len the size of the transform in samples * @param scale pointer to the value to scale the output if supported by type - * @param flags currently unused + * @param flags a bitmask of AVTXFlags or 0 * * @return 0 on success, negative error code on failure */ diff --git a/libavutil/tx_priv.h b/libavutil/tx_priv.h index e0d980abf..e2f4314a4 100644 --- a/libavutil/tx_priv.h +++ b/libavutil/tx_priv.h @@ -23,6 +23,7 @@ #include #include "thread.h" #include "mem.h" +#include "mem_internal.h" #include "avassert.h" #include "attributes.h" @@ -57,6 +58,7 @@ typedef void FFTComplex; (dim) = (are) * (bim) - (aim) * (bre); \ } while (0) +#define UNSCALE(x) (x) #define RESCALE(x) (x) #define FOLD(a, b) ((a) + (b)) @@ -84,7 +86,8 @@ typedef void FFTComplex; (dim) = (int)(((accu) + 0x40000000) >> 31); \ } while (0) -#define RESCALE(x) (lrintf((x) * 2147483648.0)) +#define UNSCALE(x) ((double)x/2147483648.0) +#define RESCALE(x) (av_clip64(lrintf((x) * 2147483648.0), INT32_MIN, INT32_MAX)) #define FOLD(x, y) ((int)((x) + (unsigned)(y) + 32) >> 6) @@ -103,21 +106,25 @@ typedef void FFTComplex; /* Used by asm, reorder with care */ struct AVTXContext { - int n; /* Nptwo part */ - int m; /* Ptwo part */ - int inv; /* Is inverted */ + int n; /* Non-power-of-two part */ + int m; /* Power-of-two part */ + int inv; /* Is inverse */ int type; /* Type */ + uint64_t flags; /* Flags */ + double scale; /* Scale */ FFTComplex *exptab; /* MDCT exptab */ FFTComplex *tmp; /* Temporary buffer needed for all compound transforms */ int *pfatab; /* Input/Output mapping for compound transforms */ int *revtab; /* Input mapping for power of two transforms */ + int *inplace_idx; /* Required indices to revtab for in-place transforms */ }; /* Shared functions */ int ff_tx_type_is_mdct(enum AVTXType type); int ff_tx_gen_compound_mapping(AVTXContext *s); -int ff_tx_gen_ptwo_revtab(AVTXContext *s); +int ff_tx_gen_ptwo_revtab(AVTXContext *s, int invert_lookup); +int ff_tx_gen_ptwo_inplace_revtab_idx(AVTXContext *s); /* Also used by SIMD init */ static inline int split_radix_permutation(int i, int n, int inverse) diff --git a/libavutil/tx_template.c b/libavutil/tx_template.c index 7f4ca2f31..a436f426d 100644 --- a/libavutil/tx_template.c +++ b/libavutil/tx_template.c @@ -392,11 +392,55 @@ static void monolithic_fft(AVTXContext *s, void *_out, void *_in, FFTComplex *in = _in; FFTComplex *out = _out; int m = s->m, mb = av_log2(m); - for (int i = 0; i < m; i++) - out[s->revtab[i]] = in[i]; + + if (s->flags & AV_TX_INPLACE) { + FFTComplex tmp; + int src, dst, *inplace_idx = s->inplace_idx; + + src = *inplace_idx++; + + do { + tmp = out[src]; + dst = s->revtab[src]; + do { + FFSWAP(FFTComplex, tmp, out[dst]); + dst = s->revtab[dst]; + } while (dst != src); /* Can be > as well, but is less predictable */ + out[dst] = tmp; + } while ((src = *inplace_idx++)); + } else { + for (int i = 0; i < m; i++) + out[i] = in[s->revtab[i]]; + } + fft_dispatch[mb](out); } +static void naive_fft(AVTXContext *s, void *_out, void *_in, + ptrdiff_t stride) +{ + FFTComplex *in = _in; + FFTComplex *out = _out; + const int n = s->n; + double phase = s->inv ? 2.0*M_PI/n : -2.0*M_PI/n; + + for(int i = 0; i < n; i++) { + FFTComplex tmp = { 0 }; + for(int j = 0; j < n; j++) { + const double factor = phase*i*j; + const FFTComplex mult = { + RESCALE(cos(factor)), + RESCALE(sin(factor)), + }; + FFTComplex res; + CMUL3(res, in[j], mult); + tmp.re += res.re; + tmp.im += res.im; + } + out[i] = tmp; + } +} + #define DECL_COMP_IMDCT(N) \ static void compound_imdct_##N##xM(AVTXContext *s, void *_dst, void *_src, \ ptrdiff_t stride) \ @@ -553,6 +597,57 @@ static void monolithic_mdct(AVTXContext *s, void *_dst, void *_src, } } +static void naive_imdct(AVTXContext *s, void *_dst, void *_src, + ptrdiff_t stride) +{ + int len = s->n; + int len2 = len*2; + FFTSample *src = _src; + FFTSample *dst = _dst; + double scale = s->scale; + const double phase = M_PI/(4.0*len2); + + stride /= sizeof(*src); + + for (int i = 0; i < len; i++) { + double sum_d = 0.0; + double sum_u = 0.0; + double i_d = phase * (4*len - 2*i - 1); + double i_u = phase * (3*len2 + 2*i + 1); + for (int j = 0; j < len2; j++) { + double a = (2 * j + 1); + double a_d = cos(a * i_d); + double a_u = cos(a * i_u); + double val = UNSCALE(src[j*stride]); + sum_d += a_d * val; + sum_u += a_u * val; + } + dst[i + 0] = RESCALE( sum_d*scale); + dst[i + len] = RESCALE(-sum_u*scale); + } +} + +static void naive_mdct(AVTXContext *s, void *_dst, void *_src, + ptrdiff_t stride) +{ + int len = s->n*2; + FFTSample *src = _src; + FFTSample *dst = _dst; + double scale = s->scale; + const double phase = M_PI/(4.0*len); + + stride /= sizeof(*dst); + + for (int i = 0; i < len; i++) { + double sum = 0.0; + for (int j = 0; j < len*2; j++) { + int a = (2*j + 1 + len) * (2*i + 1); + sum += UNSCALE(src[j]) * cos(a * phase); + } + dst[i*stride] = RESCALE(sum*scale); + } +} + static int gen_mdct_exptab(AVTXContext *s, int len4, double scale) { const double theta = (scale < 0 ? len4 : 0) + 1.0/8.0; @@ -575,11 +670,13 @@ int TX_NAME(ff_tx_init_mdct_fft)(AVTXContext *s, av_tx_fn *tx, const void *scale, uint64_t flags) { const int is_mdct = ff_tx_type_is_mdct(type); - int err, n = 1, m = 1, max_ptwo = 1 << (FF_ARRAY_ELEMS(fft_dispatch) - 1); + int err, l, n = 1, m = 1, max_ptwo = 1 << (FF_ARRAY_ELEMS(fft_dispatch) - 1); if (is_mdct) len >>= 1; + l = len; + #define CHECK_FACTOR(DST, FACTOR, SRC) \ if (DST == 1 && !(SRC % FACTOR)) { \ DST = FACTOR; \ @@ -600,13 +697,27 @@ int TX_NAME(ff_tx_init_mdct_fft)(AVTXContext *s, av_tx_fn *tx, s->m = m; s->inv = inv; s->type = type; + s->flags = flags; - /* Filter out direct 3, 5 and 15 transforms, too niche */ + /* If we weren't able to split the length into factors we can handle, + * resort to using the naive and slow FT. This also filters out + * direct 3, 5 and 15 transforms as they're too niche. */ if (len > 1 || m == 1) { - av_log(NULL, AV_LOG_ERROR, "Unsupported transform size: n = %i, " - "m = %i, residual = %i!\n", n, m, len); - return AVERROR(EINVAL); - } else if (n > 1 && m > 1) { /* 2D transform case */ + if (is_mdct && (l & 1)) /* Odd (i)MDCTs are not supported yet */ + return AVERROR(ENOSYS); + if (flags & AV_TX_INPLACE) /* Neither are in-place naive transforms */ + return AVERROR(ENOSYS); + s->n = l; + s->m = 1; + *tx = naive_fft; + if (is_mdct) { + s->scale = *((SCALE_TYPE *)scale); + *tx = inv ? naive_imdct : naive_mdct; + } + return 0; + } + + if (n > 1 && m > 1) { /* 2D transform case */ if ((err = ff_tx_gen_compound_mapping(s))) return err; if (!(s->tmp = av_malloc(n*m*sizeof(*s->tmp)))) @@ -627,7 +738,14 @@ int TX_NAME(ff_tx_init_mdct_fft)(AVTXContext *s, av_tx_fn *tx, if (n != 1) init_cos_tabs(0); if (m != 1) { - ff_tx_gen_ptwo_revtab(s); + if ((err = ff_tx_gen_ptwo_revtab(s, n == 1 && !is_mdct && !(flags & AV_TX_INPLACE)))) + return err; + if (flags & AV_TX_INPLACE) { + if (is_mdct) /* In-place MDCTs are not supported yet */ + return AVERROR(ENOSYS); + if ((err = ff_tx_gen_ptwo_inplace_revtab_idx(s))) + return err; + } for (int i = 4; i <= av_log2(m); i++) init_cos_tabs(i); } diff --git a/libavutil/version.h b/libavutil/version.h index 0ff722fbf..f888dbb2d 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 51 +#define LIBAVUTIL_VERSION_MINOR 70 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ @@ -129,7 +129,18 @@ #ifndef FF_API_PSEUDOPAL #define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) #endif - +#ifndef FF_API_CHILD_CLASS_NEXT +#define FF_API_CHILD_CLASS_NEXT (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_BUFFER_SIZE_T +#define FF_API_BUFFER_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_D2STR +#define FF_API_D2STR (LIBAVUTIL_VERSION_MAJOR < 58) +#endif +#ifndef FF_API_DECLARE_ALIGNED +#define FF_API_DECLARE_ALIGNED (LIBAVUTIL_VERSION_MAJOR < 58) +#endif /** * @} diff --git a/libavutil/video_enc_params.c b/libavutil/video_enc_params.c index c46c0f1dc..635176ab9 100644 --- a/libavutil/video_enc_params.c +++ b/libavutil/video_enc_params.c @@ -33,8 +33,7 @@ AVVideoEncParams *av_video_enc_params_alloc(enum AVVideoEncParamsType type, size_t size; size = sizeof(*par); - if (nb_blocks > SIZE_MAX / sizeof(AVVideoBlockParams) || - nb_blocks * sizeof(AVVideoBlockParams) > SIZE_MAX - size) + if (nb_blocks > (SIZE_MAX - size) / sizeof(AVVideoBlockParams)) return NULL; size += sizeof(AVVideoBlockParams) * nb_blocks; @@ -64,6 +63,10 @@ av_video_enc_params_create_side_data(AVFrame *frame, enum AVVideoEncParamsType t par = av_video_enc_params_alloc(type, nb_blocks, &size); if (!par) return NULL; + if (size > INT_MAX) { + av_free(par); + return NULL; + } buf = av_buffer_create((uint8_t *)par, size, NULL, NULL, 0); if (!buf) { av_freep(&par); diff --git a/libavutil/video_enc_params.h b/libavutil/video_enc_params.h index 43fa44315..fc0c3bc1a 100644 --- a/libavutil/video_enc_params.h +++ b/libavutil/video_enc_params.h @@ -55,6 +55,14 @@ enum AVVideoEncParamsType { * as AVVideoBlockParams.qp_delta. */ AV_VIDEO_ENC_PARAMS_H264, + + /* + * MPEG-2-compatible quantizer. + * + * Summing the frame-level qp with the per-block delta_qp gives the + * resulting quantizer for the block. + */ + AV_VIDEO_ENC_PARAMS_MPEG2, }; /** @@ -153,7 +161,7 @@ AVVideoEncParams *av_video_enc_params_alloc(enum AVVideoEncParamsType type, /** * Allocates memory for AVEncodeInfoFrame plus an array of * {@code nb_blocks} AVEncodeInfoBlock in the given AVFrame {@code frame} - * as AVFrameSideData of type AV_FRAME_DATA_ENCODE_INFO + * as AVFrameSideData of type AV_FRAME_DATA_VIDEO_ENC_PARAMS * and initializes the variables. */ AVVideoEncParams* diff --git a/libpostproc/postprocess_altivec_template.c b/libpostproc/postprocess_altivec_template.c index fa6ebe279..a9d4cd29a 100644 --- a/libpostproc/postprocess_altivec_template.c +++ b/libpostproc/postprocess_altivec_template.c @@ -21,6 +21,7 @@ */ #include "libavutil/avutil.h" +#include "libavutil/mem_internal.h" #define ALTIVEC_TRANSPOSE_8x8_SHORT(src_a,src_b,src_c,src_d,src_e,src_f,src_g,src_h) \ do { \ diff --git a/libpostproc/postprocess_internal.h b/libpostproc/postprocess_internal.h index 765fdeb14..5d1aee362 100644 --- a/libpostproc/postprocess_internal.h +++ b/libpostproc/postprocess_internal.h @@ -30,6 +30,7 @@ #include "libavutil/avutil.h" #include "libavutil/intmath.h" #include "libavutil/log.h" +#include "libavutil/mem_internal.h" #include "postprocess.h" #define V_DEBLOCK 0x01 diff --git a/libpostproc/postprocess_template.c b/libpostproc/postprocess_template.c index df1684d1e..411fc4191 100644 --- a/libpostproc/postprocess_template.c +++ b/libpostproc/postprocess_template.c @@ -23,6 +23,7 @@ * mmx/mmx2/3dnow postprocess code. */ +#include "libavutil/mem_internal.h" #include "libavutil/x86/asm.h" /* A single TEMPLATE_PP_* should be defined (to 1) when this template is diff --git a/libpostproc/version.h b/libpostproc/version.h index e5de9aefb..812f8e0dc 100644 --- a/libpostproc/version.h +++ b/libpostproc/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBPOSTPROC_VERSION_MAJOR 55 -#define LIBPOSTPROC_VERSION_MINOR 7 +#define LIBPOSTPROC_VERSION_MINOR 9 #define LIBPOSTPROC_VERSION_MICRO 100 #define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \ diff --git a/libswresample/audioconvert.c b/libswresample/audioconvert.c index d21fc8ef4..500aa0e5c 100644 --- a/libswresample/audioconvert.c +++ b/libswresample/audioconvert.c @@ -59,7 +59,7 @@ CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi) -CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16) +CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi * (1 << 16)) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16, (uint64_t)(*(const int16_t*)pi)<<48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0f/ (1<<15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) @@ -237,10 +237,10 @@ int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch; const int is= ich < 0 ? 0 : (in->planar ? 1 : in->ch_count) * in->bps; const uint8_t *pi= ich < 0 ? ctx->silence : in->ch[ich]; - uint8_t *po= out->ch[ch]; - uint8_t *end= po + os*len; + uint8_t *end, *po = out->ch[ch]; if(!po) continue; + end = po + os * len; ctx->conv_f(po+off*os, pi+off*is, is, os, end); } return 0; diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c index 6b5feaa07..94b3de88f 100644 --- a/libswresample/rematrix.c +++ b/libswresample/rematrix.c @@ -88,7 +88,7 @@ static int even(int64_t layout){ return 0; } -static int clean_layout(void *s, int64_t layout){ +static int64_t clean_layout(void *s, int64_t layout){ if(layout && layout != AV_CH_FRONT_CENTER && !(layout&(layout-1))) { char buf[128]; av_get_channel_layout_string(buf, sizeof(buf), -1, layout); @@ -141,6 +141,16 @@ av_cold int swr_build_matrix(uint64_t in_ch_layout_param, uint64_t out_ch_layout ) in_ch_layout = AV_CH_LAYOUT_STEREO; + if (in_ch_layout == AV_CH_LAYOUT_22POINT2 && + out_ch_layout != AV_CH_LAYOUT_22POINT2) { + in_ch_layout = (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER); + av_get_channel_layout_string(buf, sizeof(buf), -1, in_ch_layout); + av_log(log_context, AV_LOG_WARNING, + "Full-on remixing from 22.2 has not yet been implemented! " + "Processing the input as '%s'\n", + buf); + } + if(!sane_layout(in_ch_layout)){ av_get_channel_layout_string(buf, sizeof(buf), -1, in_ch_layout_param); av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf); diff --git a/libswresample/version.h b/libswresample/version.h index 257739195..0a99e0f13 100644 --- a/libswresample/version.h +++ b/libswresample/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBSWRESAMPLE_VERSION_MAJOR 3 -#define LIBSWRESAMPLE_VERSION_MINOR 7 +#define LIBSWRESAMPLE_VERSION_MINOR 9 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/libswscale/Makefile b/libswscale/Makefile index 5e03e6fa0..4b8f9de42 100644 --- a/libswscale/Makefile +++ b/libswscale/Makefile @@ -25,5 +25,6 @@ OBJS-$(CONFIG_SHARED) += log2_tab.o SLIBOBJS-$(HAVE_GNU_WINDRES) += swscaleres.o TESTPROGS = colorspace \ + floatimg_cmp \ pixdesc_query \ swscale \ diff --git a/libswscale/aarch64/swscale_unscaled.c b/libswscale/aarch64/swscale_unscaled.c index 551daad9e..c7a2a1037 100644 --- a/libswscale/aarch64/swscale_unscaled.c +++ b/libswscale/aarch64/swscale_unscaled.c @@ -42,15 +42,14 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsContext *c, const uint8_t *src[], uint8_t *dst[], int dstStride[]) { \ const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE }; \ \ - ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH, \ - dst[0] + srcSliceY * dstStride[0], dstStride[0], \ - src[0], srcStride[0], \ - src[1], srcStride[1], \ - src[2], srcStride[2], \ - yuv2rgb_table, \ - c->yuv2rgb_y_offset >> 6, \ - c->yuv2rgb_y_coeff); \ - return 0; \ + return ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH, \ + dst[0] + srcSliceY * dstStride[0], dstStride[0], \ + src[0], srcStride[0], \ + src[1], srcStride[1], \ + src[2], srcStride[2], \ + yuv2rgb_table, \ + c->yuv2rgb_y_offset >> 6, \ + c->yuv2rgb_y_coeff); \ } \ #define DECLARE_FF_YUVX_TO_ALL_RGBX_FUNCS(yuvx) \ @@ -76,14 +75,12 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsContext *c, const uint8_t *src[], uint8_t *dst[], int dstStride[]) { \ const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE }; \ \ - ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH, \ - dst[0] + srcSliceY * dstStride[0], dstStride[0], \ - src[0], srcStride[0], src[1], srcStride[1], \ - yuv2rgb_table, \ - c->yuv2rgb_y_offset >> 6, \ - c->yuv2rgb_y_coeff); \ - \ - return 0; \ + return ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH, \ + dst[0] + srcSliceY * dstStride[0], dstStride[0], \ + src[0], srcStride[0], src[1], srcStride[1], \ + yuv2rgb_table, \ + c->yuv2rgb_y_offset >> 6, \ + c->yuv2rgb_y_coeff); \ } \ #define DECLARE_FF_NVX_TO_ALL_RGBX_FUNCS(nvx) \ diff --git a/libswscale/aarch64/yuv2rgb_neon.S b/libswscale/aarch64/yuv2rgb_neon.S index b7446aa10..f4b220fb6 100644 --- a/libswscale/aarch64/yuv2rgb_neon.S +++ b/libswscale/aarch64/yuv2rgb_neon.S @@ -142,6 +142,7 @@ .macro declare_func ifmt ofmt function ff_\ifmt\()_to_\ofmt\()_neon, export=1 load_args_\ifmt + mov w9, w1 1: mov w8, w0 // w8 = width 2: @@ -193,6 +194,7 @@ function ff_\ifmt\()_to_\ofmt\()_neon, export=1 increment_\ifmt subs w1, w1, #1 // height -= 1 b.gt 1b + mov w0, w9 ret endfunc .endm diff --git a/libswscale/bayer_template.c b/libswscale/bayer_template.c index 1af1b6056..46b5a4984 100644 --- a/libswscale/bayer_template.c +++ b/libswscale/bayer_template.c @@ -118,6 +118,72 @@ B(1, 1) = (T(0, 1) + T(2, 1)) >> (1 + BAYER_SHIFT); #endif +#if defined(BAYER_BGGR) || defined(BAYER_RGGB) +#define BAYER_TO_RGB48_COPY \ + R(0, 0) = \ + R(0, 1) = \ + R(1, 1) = \ + R(1, 0) = S(1, 1); \ + \ + G(0, 1) = S(0, 1); \ + G(0, 0) = \ + G(1, 1) = (T(0, 1) + T(1, 0)) >> 1; \ + G(1, 0) = S(1, 0); \ + \ + B(1, 1) = \ + B(0, 0) = \ + B(0, 1) = \ + B(1, 0) = S(0, 0); +#define BAYER_TO_RGB48_INTERPOLATE \ + R(0, 0) = (T(-1, -1) + T(-1, 1) + T(1, -1) + T(1, 1)) >> 2; \ + G(0, 0) = (T(-1, 0) + T( 0, -1) + T(0, 1) + T(1, 0)) >> 2; \ + B(0, 0) = S(0, 0); \ + \ + R(0, 1) = (T(-1, 1) + T(1, 1)) >> 1; \ + G(0, 1) = S(0, 1); \ + B(0, 1) = (T(0, 0) + T(0, 2)) >> 1; \ + \ + R(1, 0) = (T(1, -1) + T(1, 1)) >> 1; \ + G(1, 0) = S(1, 0); \ + B(1, 0) = (T(0, 0) + T(2, 0)) >> 1; \ + \ + R(1, 1) = S(1, 1); \ + G(1, 1) = (T(0, 1) + T(1, 0) + T(1, 2) + T(2, 1)) >> 2; \ + B(1, 1) = (T(0, 0) + T(0, 2) + T(2, 0) + T(2, 2)) >> 2; +#else +#define BAYER_TO_RGB48_COPY \ + R(0, 0) = \ + R(0, 1) = \ + R(1, 1) = \ + R(1, 0) = S(1, 0); \ + \ + G(0, 0) = S(0, 0); \ + G(1, 1) = S(1, 1); \ + G(0, 1) = \ + G(1, 0) = (T(0, 0) + T(1, 1)) >> 1; \ + \ + B(1, 1) = \ + B(0, 0) = \ + B(0, 1) = \ + B(1, 0) = S(0, 1); +#define BAYER_TO_RGB48_INTERPOLATE \ + R(0, 0) = (T(-1, 0) + T(1, 0)) >> 1; \ + G(0, 0) = S(0, 0); \ + B(0, 0) = (T(0, -1) + T(0, 1)) >> 1; \ + \ + R(0, 1) = (T(-1, 0) + T(-1, 2) + T(1, 0) + T(1, 2)) >> 2; \ + G(0, 1) = (T(-1, 1) + T(0, 0) + T(0, 2) + T(1, 1)) >> 2; \ + B(0, 1) = S(0, 1); \ + \ + R(1, 0) = S(1, 0); \ + G(1, 0) = (T(0, 0) + T(1, -1) + T(1, 1) + T(2, 0)) >> 2; \ + B(1, 0) = (T(0, -1) + T(0, 1) + T(2, -1) + T(2, 1)) >> 2; \ + \ + R(1, 1) = (T(1, 0) + T(1, 2)) >> 1; \ + G(1, 1) = S(1, 1); \ + B(1, 1) = (T(0, 1) + T(2, 1)) >> 1; +#endif + /** * invoke ff_rgb24toyv12 for 2x2 pixels */ @@ -153,6 +219,40 @@ static void BAYER_RENAME(rgb24_interpolate)(const uint8_t *src, int src_stride, } } +static void BAYER_RENAME(rgb48_copy)(const uint8_t *src, int src_stride, uint8_t *ddst, int dst_stride, int width) +{ + uint16_t *dst = (uint16_t *)ddst; + int i; + + dst_stride /= 2; + for (i = 0 ; i < width; i+= 2) { + BAYER_TO_RGB48_COPY + src += 2 * BAYER_SIZEOF; + dst += 6; + } +} + +static void BAYER_RENAME(rgb48_interpolate)(const uint8_t *src, int src_stride, uint8_t *ddst, int dst_stride, int width) +{ + uint16_t *dst = (uint16_t *)ddst; + int i; + + dst_stride /= 2; + BAYER_TO_RGB48_COPY + src += 2 * BAYER_SIZEOF; + dst += 6; + + for (i = 2 ; i < width - 2; i+= 2) { + BAYER_TO_RGB48_INTERPOLATE + src += 2 * BAYER_SIZEOF; + dst += 6; + } + + if (width > 2) { + BAYER_TO_RGB48_COPY + } +} + static void BAYER_RENAME(yv12_copy)(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv) { uint8_t dst[12]; @@ -203,6 +303,8 @@ static void BAYER_RENAME(yv12_interpolate)(const uint8_t *src, int src_stride, u #undef B #undef BAYER_TO_RGB24_COPY #undef BAYER_TO_RGB24_INTERPOLATE +#undef BAYER_TO_RGB48_COPY +#undef BAYER_TO_RGB48_INTERPOLATE #undef BAYER_RENAME diff --git a/libswscale/input.c b/libswscale/input.c index e74cf0413..6850801a4 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -245,9 +245,11 @@ rgb48funcs(bgr, BE, AV_PIX_FMT_BGR48BE) origin == AV_PIX_FMT_BGRA || \ origin == AV_PIX_FMT_ARGB || \ origin == AV_PIX_FMT_ABGR) \ - ? AV_RN32A(&src[(i) * 4]) \ - : (isBE(origin) ? AV_RB16(&src[(i) * 2]) \ - : AV_RL16(&src[(i) * 2]))) + ? AV_RN32A(&src[(i) * 4]) \ + : ((origin == AV_PIX_FMT_X2RGB10LE) \ + ? AV_RL32(&src[(i) * 4]) \ + : (isBE(origin) ? AV_RB16(&src[(i) * 2]) \ + : AV_RL16(&src[(i) * 2])))) static av_always_inline void rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src, @@ -391,6 +393,7 @@ rgb16_32_wrapper(AV_PIX_FMT_BGR444BE, bgr12be, 0, 0, 0, 0, 0x000F, 0x00F0, rgb16_32_wrapper(AV_PIX_FMT_RGB565BE, rgb16be, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT + 8) rgb16_32_wrapper(AV_PIX_FMT_RGB555BE, rgb15be, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT + 7) rgb16_32_wrapper(AV_PIX_FMT_RGB444BE, rgb12be, 0, 0, 0, 0, 0x0F00, 0x00F0, 0x000F, 0, 4, 8, RGB2YUV_SHIFT + 4) +rgb16_32_wrapper(AV_PIX_FMT_X2RGB10LE, rgb30le, 16, 6, 0, 0, 0x3FF00000, 0xFFC00, 0x3FF, 0, 0, 4, RGB2YUV_SHIFT + 6) static void gbr24pToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *gsrc, const uint8_t *bsrc, const uint8_t *rsrc, @@ -921,7 +924,7 @@ static av_always_inline void planar_rgb16_to_y(uint8_t *_dst, const uint8_t *_sr int b = rdpx(src[1] + i); int r = rdpx(src[2] + i); - dst[i] = ((ry*r + gy*g + by*b + (33 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + shift - 14)); + dst[i] = (ry*r + gy*g + by*b + (16 << (RGB2YUV_SHIFT + bpc - 8)) + (1 << (RGB2YUV_SHIFT + shift - 15))) >> (RGB2YUV_SHIFT + shift - 14); } } @@ -954,8 +957,8 @@ static av_always_inline void planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV, int b = rdpx(src[1] + i); int r = rdpx(src[2] + i); - dstU[i] = (ru*r + gu*g + bu*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + shift - 14); - dstV[i] = (rv*r + gv*g + bv*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + shift - 14); + dstU[i] = (ru*r + gu*g + bu*b + (128 << (RGB2YUV_SHIFT + bpc - 8)) + (1 << (RGB2YUV_SHIFT + shift - 15))) >> (RGB2YUV_SHIFT + shift - 14); + dstV[i] = (rv*r + gv*g + bv*b + (128 << (RGB2YUV_SHIFT + bpc - 8)) + (1 << (RGB2YUV_SHIFT + shift - 15))) >> (RGB2YUV_SHIFT + shift - 14); } } #undef rdpx @@ -981,15 +984,14 @@ static av_always_inline void planar_rgbf32_to_uv(uint8_t *_dstU, uint8_t *_dstV, uint16_t *dstV = (uint16_t *)_dstV; int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX]; int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX]; - int bpc = 16; - int shift = 14; + for (i = 0; i < width; i++) { int g = av_clip_uint16(lrintf(65535.0f * rdpx(src[0] + i))); int b = av_clip_uint16(lrintf(65535.0f * rdpx(src[1] + i))); int r = av_clip_uint16(lrintf(65535.0f * rdpx(src[2] + i))); - dstU[i] = (ru*r + gu*g + bu*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + shift - 14); - dstV[i] = (rv*r + gv*g + bv*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + shift - 14); + dstU[i] = (ru*r + gu*g + bu*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT; + dstV[i] = (rv*r + gv*g + bv*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT; } } @@ -1000,14 +1002,13 @@ static av_always_inline void planar_rgbf32_to_y(uint8_t *_dst, const uint8_t *_s uint16_t *dst = (uint16_t *)_dst; int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX]; - int bpc = 16; - int shift = 14; + for (i = 0; i < width; i++) { int g = av_clip_uint16(lrintf(65535.0f * rdpx(src[0] + i))); int b = av_clip_uint16(lrintf(65535.0f * rdpx(src[1] + i))); int r = av_clip_uint16(lrintf(65535.0f * rdpx(src[2] + i))); - dst[i] = ((ry*r + gy*g + by*b + (33 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + shift - 14)); + dst[i] = (ry*r + gy*g + by*b + (0x2001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT; } } @@ -1341,6 +1342,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_RGB444BE: c->chrToYV12 = rgb12beToUV_half_c; break; + case AV_PIX_FMT_X2RGB10LE: + c->chrToYV12 = rgb30leToUV_half_c; + break; } } else { switch (srcFormat) { @@ -1422,6 +1426,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_RGB444BE: c->chrToYV12 = rgb12beToUV_c; break; + case AV_PIX_FMT_X2RGB10LE: + c->chrToYV12 = rgb30leToUV_c; + break; } } @@ -1701,6 +1708,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_Y210LE: c->lumToYV12 = y210le_Y_c; break; + case AV_PIX_FMT_X2RGB10LE: + c->lumToYV12 =rgb30leToY_c; + break; } if (c->needAlpha) { if (is16BPS(srcFormat) || isNBPS(srcFormat)) { diff --git a/libswscale/output.c b/libswscale/output.c index e864e515d..e855ad606 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -30,6 +30,7 @@ #include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" +#include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "config.h" #include "rgb2rgb.h" @@ -180,7 +181,8 @@ yuv2planeX_16_c_template(const int16_t *filter, int filterSize, } } -static void yuv2p016cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize, +static void yuv2p016cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, + const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, const int16_t **chrVSrc, uint8_t *dest8, int chrDstW) { @@ -188,7 +190,7 @@ static void yuv2p016cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterS const int32_t **uSrc = (const int32_t **)chrUSrc; const int32_t **vSrc = (const int32_t **)chrVSrc; int shift = 15; - int big_endian = c->dstFormat == AV_PIX_FMT_P016BE; + int big_endian = dstFormat == AV_PIX_FMT_P016BE; int i, j; for (i = 0; i < chrDstW; i++) { @@ -402,12 +404,11 @@ static void yuv2plane1_8_c(const int16_t *src, uint8_t *dest, int dstW, } } -static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize, - const int16_t **chrUSrc, const int16_t **chrVSrc, - uint8_t *dest, int chrDstW) +static void yuv2nv12cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, + const int16_t *chrFilter, int chrFilterSize, + const int16_t **chrUSrc, const int16_t **chrVSrc, + uint8_t *dest, int chrDstW) { - enum AVPixelFormat dstFormat = c->dstFormat; - const uint8_t *chrDither = c->chrDither8; int i; if (dstFormat == AV_PIX_FMT_NV12 || @@ -477,13 +478,14 @@ static void yuv2p010lX_c(const int16_t *filter, int filterSize, } } -static void yuv2p010cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize, +static void yuv2p010cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, + const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, const int16_t **chrVSrc, uint8_t *dest8, int chrDstW) { uint16_t *dest = (uint16_t*)dest8; int shift = 17; - int big_endian = c->dstFormat == AV_PIX_FMT_P010BE; + int big_endian = dstFormat == AV_PIX_FMT_P010BE; int i, j; for (i = 0; i < chrDstW; i++) { @@ -1602,6 +1604,13 @@ yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2, dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1]; dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]; + } else if (target == AV_PIX_FMT_X2RGB10) { + uint32_t *dest = (uint32_t *) _dest; + const uint32_t *r = (const uint32_t *) _r; + const uint32_t *g = (const uint32_t *) _g; + const uint32_t *b = (const uint32_t *) _b; + dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1]; + dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2]; } else /* 8/4 bits */ { uint8_t *dest = (uint8_t *) _dest; const uint8_t *r = (const uint8_t *) _r; @@ -1839,6 +1848,7 @@ YUV2RGBWRAPPER(yuv2rgb,, 12, AV_PIX_FMT_RGB444, 0) YUV2RGBWRAPPER(yuv2rgb,, 8, AV_PIX_FMT_RGB8, 0) YUV2RGBWRAPPER(yuv2rgb,, 4, AV_PIX_FMT_RGB4, 0) YUV2RGBWRAPPER(yuv2rgb,, 4b, AV_PIX_FMT_RGB4_BYTE, 0) +YUV2RGBWRAPPER(yuv2, rgb, x2rgb10, AV_PIX_FMT_X2RGB10, 0) static av_always_inline void yuv2rgb_write_full(SwsContext *c, uint8_t *dest, int i, int Y, int A, int U, int V, @@ -2974,6 +2984,12 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, *yuv2packed2 = yuv2rgb4b_2_c; *yuv2packedX = yuv2rgb4b_X_c; break; + case AV_PIX_FMT_X2RGB10LE: + case AV_PIX_FMT_X2RGB10BE: + *yuv2packed1 = yuv2x2rgb10_1_c; + *yuv2packed2 = yuv2x2rgb10_2_c; + *yuv2packedX = yuv2x2rgb10_X_c; + break; } } switch (dstFormat) { diff --git a/libswscale/ppc/swscale_ppc_template.c b/libswscale/ppc/swscale_ppc_template.c index aff2dd79f..0ffa92725 100644 --- a/libswscale/ppc/swscale_ppc_template.c +++ b/libswscale/ppc/swscale_ppc_template.c @@ -21,6 +21,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mem_internal.h" + static void FUNC(yuv2planeX_8_16)(const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, const uint8_t *dither, int offset, int x) diff --git a/libswscale/ppc/swscale_vsx.c b/libswscale/ppc/swscale_vsx.c index af8b0e1fa..8152ce7f1 100644 --- a/libswscale/ppc/swscale_vsx.c +++ b/libswscale/ppc/swscale_vsx.c @@ -28,6 +28,7 @@ #include "libswscale/swscale_internal.h" #include "libavutil/attributes.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "yuv2rgb_altivec.h" #include "libavutil/ppc/util_altivec.h" diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c index 536545293..5e1033a97 100644 --- a/libswscale/ppc/yuv2rgb_altivec.c +++ b/libswscale/ppc/yuv2rgb_altivec.c @@ -96,6 +96,7 @@ #include "libswscale/swscale_internal.h" #include "libavutil/attributes.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "yuv2rgb_altivec.h" @@ -283,6 +284,16 @@ static inline void cvtyuvtoRGB(SwsContext *c, vector signed short Y, * ------------------------------------------------------------------------------ */ +#if !HAVE_VSX +static inline vector unsigned char vec_xl(signed long long offset, const ubyte *addr) +{ + const vector unsigned char *v_addr = (const vector unsigned char *) (addr + offset); + vector unsigned char align_perm = vec_lvsl(offset, addr); + + return (vector unsigned char) vec_perm(v_addr[0], v_addr[1], align_perm); +} +#endif /* !HAVE_VSX */ + #define DEFCSP420_CVT(name, out_pixels) \ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \ int *instrides, int srcSliceY, int srcSliceH, \ @@ -424,13 +435,13 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \ } #define out_abgr(a, b, c, ptr) \ - vec_mstrgb32(__typeof__(a), ((__typeof__(a)) { 255 }), c, b, a, ptr) + vec_mstrgb32(__typeof__(a), ((__typeof__(a)) vec_splat((__typeof__(a)){ 255 }, 0)), c, b, a, ptr) #define out_bgra(a, b, c, ptr) \ - vec_mstrgb32(__typeof__(a), c, b, a, ((__typeof__(a)) { 255 }), ptr) + vec_mstrgb32(__typeof__(a), c, b, a, ((__typeof__(a)) vec_splat((__typeof__(a)){ 255 }, 0)), ptr) #define out_rgba(a, b, c, ptr) \ - vec_mstrgb32(__typeof__(a), a, b, c, ((__typeof__(a)) { 255 }), ptr) + vec_mstrgb32(__typeof__(a), a, b, c, ((__typeof__(a)) vec_splat((__typeof__(a)){ 255 }, 0)), ptr) #define out_argb(a, b, c, ptr) \ - vec_mstrgb32(__typeof__(a), ((__typeof__(a)) { 255 }), a, b, c, ptr) + vec_mstrgb32(__typeof__(a), ((__typeof__(a)) vec_splat((__typeof__(a)){ 255 }, 0)), a, b, c, ptr) #define out_rgb24(a, b, c, ptr) vec_mstrgb24(a, b, c, ptr) #define out_bgr24(a, b, c, ptr) vec_mstbgr24(a, b, c, ptr) diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c index f7385e372..42c69801b 100644 --- a/libswscale/rgb2rgb_template.c +++ b/libswscale/rgb2rgb_template.c @@ -342,7 +342,6 @@ static inline void shuffle_bytes_0321_c(const uint8_t *src, uint8_t *dst, } } -#if !HAVE_BIGENDIAN #define DEFINE_SHUFFLE_BYTES(name, a, b, c, d) \ static void shuffle_bytes_##name (const uint8_t *src, \ uint8_t *dst, int src_size) \ @@ -360,7 +359,6 @@ static void shuffle_bytes_##name (const uint8_t *src, \ DEFINE_SHUFFLE_BYTES(1230_c, 1, 2, 3, 0) DEFINE_SHUFFLE_BYTES(3012_c, 3, 0, 1, 2) DEFINE_SHUFFLE_BYTES(3210_c, 3, 2, 1, 0) -#endif static inline void rgb24tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size) { @@ -969,10 +967,10 @@ static av_cold void rgb2rgb_init_c(void) #else shuffle_bytes_0321 = shuffle_bytes_0321_c; shuffle_bytes_2103 = shuffle_bytes_2103_c; +#endif shuffle_bytes_1230 = shuffle_bytes_1230_c; shuffle_bytes_3012 = shuffle_bytes_3012_c; shuffle_bytes_3210 = shuffle_bytes_3210_c; -#endif rgb32tobgr16 = rgb32tobgr16_c; rgb32tobgr15 = rgb32tobgr15_c; yv12toyuy2 = yv12toyuy2_c; diff --git a/libswscale/slice.c b/libswscale/slice.c index 7849b70f4..d96db1336 100644 --- a/libswscale/slice.c +++ b/libswscale/slice.c @@ -158,14 +158,10 @@ int ff_init_slice_from_src(SwsSlice * s, uint8_t *src[4], int stride[4], int src chrY + chrH, lumY + lumH}; - uint8_t *const src_[4] = {src[0] + (relative ? 0 : start[0]) * stride[0], - src[1] + (relative ? 0 : start[1]) * stride[1], - src[2] + (relative ? 0 : start[2]) * stride[2], - src[3] + (relative ? 0 : start[3]) * stride[3]}; - s->width = srcW; - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4 && src[i] != NULL; ++i) { + uint8_t *const src_i = src[i] + (relative ? 0 : start[i]) * stride[i]; int j; int first = s->plane[i].sliceY; int n = s->plane[i].available_lines; @@ -175,13 +171,13 @@ int ff_init_slice_from_src(SwsSlice * s, uint8_t *src[4], int stride[4], int src if (start[i] >= first && n >= tot_lines) { s->plane[i].sliceH = FFMAX(tot_lines, s->plane[i].sliceH); for (j = 0; j < lines; j+= 1) - s->plane[i].line[start[i] - first + j] = src_[i] + j * stride[i]; + s->plane[i].line[start[i] - first + j] = src_i + j * stride[i]; } else { s->plane[i].sliceY = start[i]; lines = lines > n ? n : lines; s->plane[i].sliceH = lines; for (j = 0; j < lines; j+= 1) - s->plane[i].line[j] = src_[i] + j * stride[i]; + s->plane[i].line[j] = src_i + j * stride[i]; } } diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 9cb7e8f6a..12160a169 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -30,6 +30,7 @@ #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" +#include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "config.h" #include "rgb2rgb.h" diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index ee46092ff..a1de95cee 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -29,6 +29,7 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "libavutil/log.h" +#include "libavutil/mem_internal.h" #include "libavutil/pixfmt.h" #include "libavutil/pixdesc.h" #include "libavutil/ppc/util_altivec.h" @@ -119,7 +120,8 @@ typedef void (*yuv2planarX_fn)(const int16_t *filter, int filterSize, * Write one line of horizontally scaled chroma to interleaved output * with multi-point vertical scaling between input pixels. * - * @param c SWS scaling context + * @param dstFormat destination pixel format + * @param chrDither ordered dither array of type uint8_t and size 8 * @param chrFilter vertical chroma scaling coefficients, 12 bits [0,4096] * @param chrUSrc scaled chroma (U) source data, 15 bits for 8-10-bit * output, 19 bits for 16-bit output (in int32_t) @@ -130,7 +132,8 @@ typedef void (*yuv2planarX_fn)(const int16_t *filter, int filterSize, * output, this is in uint16_t * @param dstW width of chroma planes */ -typedef void (*yuv2interleavedX_fn)(struct SwsContext *c, +typedef void (*yuv2interleavedX_fn)(enum AVPixelFormat dstFormat, + const uint8_t *chrDither, const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, @@ -762,6 +765,13 @@ static av_always_inline int isBayer(enum AVPixelFormat pix_fmt) return !!(desc->flags & AV_PIX_FMT_FLAG_BAYER); } +static av_always_inline int isBayer16BPS(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + av_assert0(desc); + return desc->comp[1].depth == 8; +} + static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 5fb572b51..c4dd8a4d8 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -30,6 +30,7 @@ #include "libavutil/cpu.h" #include "libavutil/avutil.h" #include "libavutil/mathematics.h" +#include "libavutil/mem_internal.h" #include "libavutil/bswap.h" #include "libavutil/pixdesc.h" #include "libavutil/avassert.h" @@ -1326,6 +1327,55 @@ static int bayer_to_rgb24_wrapper(SwsContext *c, const uint8_t* src[], int srcSt return srcSliceH; } +static int bayer_to_rgb48_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]) +{ + uint8_t *dstPtr= dst[0] + srcSliceY * dstStride[0]; + const uint8_t *srcPtr= src[0]; + int i; + void (*copy) (const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width); + void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width); + + switch(c->srcFormat) { +#define CASE(pixfmt, prefix) \ + case pixfmt: copy = bayer_##prefix##_to_rgb48_copy; \ + interpolate = bayer_##prefix##_to_rgb48_interpolate; \ + break; + CASE(AV_PIX_FMT_BAYER_BGGR8, bggr8) + CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le) + CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be) + CASE(AV_PIX_FMT_BAYER_RGGB8, rggb8) + CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le) + CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be) + CASE(AV_PIX_FMT_BAYER_GBRG8, gbrg8) + CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le) + CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be) + CASE(AV_PIX_FMT_BAYER_GRBG8, grbg8) + CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le) + CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be) +#undef CASE + default: return 0; + } + + av_assert0(srcSliceH > 1); + + copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW); + srcPtr += 2 * srcStride[0]; + dstPtr += 2 * dstStride[0]; + + for (i = 2; i < srcSliceH - 2; i += 2) { + interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW); + srcPtr += 2 * srcStride[0]; + dstPtr += 2 * dstStride[0]; + } + + if (i + 1 == srcSliceH) { + copy(srcPtr, -srcStride[0], dstPtr, -dstStride[0], c->srcW); + } else if (i < srcSliceH) + copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW); + return srcSliceH; +} + static int bayer_to_yv12_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]) { @@ -1756,7 +1806,7 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat); const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat); int plane, i, j; - for (plane = 0; plane < 4; plane++) { + for (plane = 0; plane < 4 && dst[plane] != NULL; plane++) { int length = (plane == 0 || plane == 3) ? c->srcW : AV_CEIL_RSHIFT(c->srcW, c->chrDstHSubSample); int y = (plane == 0 || plane == 3) ? srcSliceY: AV_CEIL_RSHIFT(srcSliceY, c->chrDstVSubSample); int height = (plane == 0 || plane == 3) ? srcSliceH: AV_CEIL_RSHIFT(srcSliceH, c->chrDstVSubSample); @@ -1764,8 +1814,6 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], uint8_t *dstPtr = dst[plane] + dstStride[plane] * y; int shiftonly = plane == 1 || plane == 2 || (!c->srcRange && plane == 0); - if (!dst[plane]) - continue; // ignore palette for GRAY8 if (plane == 1 && !dst[2]) continue; if (!src[plane] || (plane == 1 && !src[2])) { @@ -2047,6 +2095,8 @@ void ff_get_unscaled_swscale(SwsContext *c) if (isBayer(srcFormat)) { if (dstFormat == AV_PIX_FMT_RGB24) c->swscale = bayer_to_rgb24_wrapper; + else if (dstFormat == AV_PIX_FMT_RGB48) + c->swscale = bayer_to_rgb48_wrapper; else if (dstFormat == AV_PIX_FMT_YUV420P) c->swscale = bayer_to_yv12_wrapper; else if (!isBayer(dstFormat)) { diff --git a/libswscale/tests/floatimg_cmp.c b/libswscale/tests/floatimg_cmp.c new file mode 100644 index 000000000..5c67594fb --- /dev/null +++ b/libswscale/tests/floatimg_cmp.c @@ -0,0 +1,296 @@ +/* + * 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 +#include +#include +#include + +#include "libavutil/avutil.h" +#include "libavutil/imgutils.h" +#include "libavutil/intfloat.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/lfg.h" +#include "libavutil/mem.h" +#include "libavutil/parseutils.h" +#include "libavutil/pixdesc.h" + +#include "libswscale/swscale.h" + +#define DEFAULT_W 96 +#define DEFAULT_H 96 + +static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUV444P16LE, + AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUV444P9LE, AV_PIX_FMT_YUV444P10LE, + AV_PIX_FMT_YUV444P12LE, AV_PIX_FMT_YUV444P14LE, + AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, + AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, + AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, + AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, + AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, + AV_PIX_FMT_RGB48LE, AV_PIX_FMT_BGR48LE, + AV_PIX_FMT_RGBA64LE, AV_PIX_FMT_BGRA64LE, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_GBRP9LE, + AV_PIX_FMT_GBRP10LE, AV_PIX_FMT_GBRAP10LE, + AV_PIX_FMT_GBRP12LE, AV_PIX_FMT_GBRAP12LE, + AV_PIX_FMT_GBRP14LE, + AV_PIX_FMT_GBRP16LE, AV_PIX_FMT_GBRAP16LE +}; + +const char *usage = "floatimg_cmp -pixel_format -size -ref \n"; + +int main(int argc, char **argv) +{ + enum AVPixelFormat inFormat = AV_PIX_FMT_NONE; + enum AVPixelFormat dstFormat = AV_PIX_FMT_NONE; + const AVPixFmtDescriptor *desc; + uint8_t *ptr; + uint32_t *in, *out; + + uint8_t *rgbIn[4] = {NULL, NULL, NULL, NULL}; + uint8_t *rgbOut[4] = {NULL, NULL, NULL, NULL}; + int rgbStride[4]; + + uint8_t *dst[4] = {NULL, NULL, NULL, NULL}; + int dstStride[4]; + + int i, x, y, p, size, count; + int res = -1; + int w = -1; + int h = -1; + union av_intfloat32 v0, v1; + + double sum; + float minimum, maximum, diff; + + struct SwsContext *sws = NULL; + AVLFG rand; + FILE *fp = NULL; + + for (i = 1; i < argc; i += 2) { + if (argv[i][0] != '-' || i + 1 == argc) + goto bad_option; + if (!strcmp(argv[i], "-ref")) { + fp = fopen(argv[i + 1], "rb"); + if (!fp) { + fprintf(stderr, "could not open '%s'\n", argv[i + 1]); + goto end; + } + } else if (!strcmp(argv[i], "-size")) { + res = av_parse_video_size(&w, &h, argv[i + 1]); + if (res < 0) { + fprintf(stderr, "invalid video size %s\n", argv[i + 1]); + goto end; + } + } else if (!strcmp(argv[i], "-pixel_format")) { + inFormat = av_get_pix_fmt(argv[i + 1]); + if (inFormat == AV_PIX_FMT_NONE) { + fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]); + goto end; + } + } else { +bad_option: + fprintf(stderr, "%s", usage); + fprintf(stderr, "bad option or argument missing (%s)\n", argv[i]); + goto end; + }; + } + + if (!fp) { + inFormat = AV_PIX_FMT_GBRPF32LE; + w = DEFAULT_W; + h = DEFAULT_H; + } + + if (w <= 0 || h <= 0) { + fprintf(stderr, "%s", usage); + fprintf(stderr, "invalid -video_size\n"); + goto end; + } + + if (inFormat == AV_PIX_FMT_NONE) { + fprintf(stderr, "%s", usage); + fprintf(stderr, "invalid input pixel format\n"); + goto end; + } + + desc = av_pix_fmt_desc_get(inFormat); + if (!(desc->flags & AV_PIX_FMT_FLAG_FLOAT)) { + fprintf(stderr, "input pixel format not floating point.\n"); + goto end; + } + + res = av_image_fill_linesizes(rgbStride, inFormat, w); + if (res < 0) { + fprintf(stderr, "av_image_fill_linesizes failed\n"); + goto end; + } + for (p = 0; p < 4; p++) { + rgbStride[p] = FFALIGN(rgbStride[p], 16); + if (rgbStride[p]) { + rgbIn[p] = av_mallocz(rgbStride[p] * h + 16); + rgbOut[p] = av_mallocz(rgbStride[p] * h + 16); + } + if (rgbStride[p] && (!rgbIn[p] || !rgbOut[p])) { + goto end; + } + } + + for (i = 0; i < FF_ARRAY_ELEMS(pix_fmts); i++) { + dstFormat = pix_fmts[i]; + if (fp) { + fseek(fp, 0, SEEK_SET); + for (p = 0; p < 4; p++) { + if (!rgbStride[p]) + continue; + + ptr = rgbIn[p]; + for (y = 0; y < h; y++) { + size = fread(ptr, 1, w*4, fp); + if (size != w*4) { + fprintf(stderr, "read error: %d\n", size); + goto end; + } + ptr += rgbStride[p]; + } + } + } else { + // fill src with random values between 0.0 - 1.0 + av_lfg_init(&rand, 1); + for (p = 0; p < 4; p++) { + if (!rgbStride[p]) + continue; + + for (y = 0; y < h; y++) { + in = (uint32_t*)(rgbIn[p] + y * rgbStride[p]); + for (x = 0; x < w; x++) { + v0.f = (float)av_lfg_get(&rand)/(float)(UINT32_MAX); + *in++ = AV_RL32(&v0.i); + } + } + } + } + + // setup intermediate image + for (p = 0; p < 4; p++) { + av_freep(&dst[p]); + } + + res = av_image_fill_linesizes(dstStride, dstFormat, w); + if (res < 0) { + fprintf(stderr, "av_image_fill_linesizes failed\n"); + goto end; + } + for (p = 0; p < 4; p++) { + dstStride[p] = FFALIGN(dstStride[p], 16); + if (dstStride[p]) { + dst[p] = av_mallocz(dstStride[p] * h + 16); + } + if (dstStride[p] && !dst[p]) { + goto end; + } + } + + // srcFormat -> dstFormat + sws = sws_getContext(w, h, inFormat, w, h, + dstFormat, SWS_BILINEAR, NULL, NULL, NULL); + if (!sws) { + fprintf(stderr, "Failed to get %s -> %s\n", av_get_pix_fmt_name(inFormat), av_get_pix_fmt_name(dstFormat) ); + goto end; + } + + res = sws_scale(sws, (const uint8_t *const *)rgbIn, rgbStride, 0, h, dst, dstStride); + if (res < 0 || res != h) { + fprintf(stderr, "sws_scale failed\n"); + res = -1; + goto end; + } + sws_freeContext(sws); + + // dstFormat -> srcFormat + sws = sws_getContext(w, h, dstFormat, w, h, + inFormat, SWS_BILINEAR, NULL, NULL, NULL); + if(!sws) { + fprintf(stderr, "Failed to get %s -> %s\n", av_get_pix_fmt_name(dstFormat), av_get_pix_fmt_name(inFormat) ); + goto end; + } + + res = sws_scale(sws, (const uint8_t *const *)dst, dstStride, 0, h, rgbOut, rgbStride); + if (res < 0 || res != h) { + fprintf(stderr, "sws_scale failed\n"); + res = -1; + goto end; + } + sws_freeContext(sws); + sws = NULL; + + minimum = FLT_MAX; + maximum = -FLT_MAX; + count = 0; + sum = 0.0; + + for (p = 0; p < 4; p++) { + if (!rgbStride[p]) + continue; + + for (y = 0; y < h; y++) { + in = (uint32_t*)(rgbIn[p] + y * rgbStride[p]); + out = (uint32_t*)(rgbOut[p] + y * rgbStride[p]); + for (x = 0; x < w; x++) { + if (desc->flags & AV_PIX_FMT_FLAG_BE) { + v0.i = AV_RB32(in); + v1.i = AV_RB32(out); + } else { + v0.i = AV_RL32(in); + v1.i = AV_RL32(out); + } + + diff = fabsf(v0.f - v1.f); + sum += diff; + minimum = FFMIN(minimum, diff); + maximum = FFMAX(maximum, diff); + + count++; + in++; + out++; + } + } + } + + fprintf(stdout, "%s -> %s -> %s\n", av_get_pix_fmt_name(inFormat), av_get_pix_fmt_name(dstFormat), av_get_pix_fmt_name(inFormat) ); + fprintf(stdout, "avg diff: %f\nmin diff: %f\nmax diff: %f\n", sum / count, minimum, maximum); + res = 0; + } + +end: + sws_freeContext(sws); + for (p = 0; p < 4; p++) { + av_freep(&rgbIn[p]); + av_freep(&rgbOut[p]); + av_freep(&dst[p]); + } + if (fp) + fclose(fp); + + return res; +} diff --git a/libswscale/tests/swscale.c b/libswscale/tests/swscale.c index 19878a787..6c38041dd 100644 --- a/libswscale/tests/swscale.c +++ b/libswscale/tests/swscale.c @@ -248,7 +248,7 @@ end: if (dstStride[i]) av_free(dst[i]); - return res; + return !!res; } static void selfTest(const uint8_t * const ref[4], int refStride[4], @@ -422,7 +422,11 @@ bad_option: for (y = 0; y < H; y++) for (x = 0; x < W * 4; x++) rgb_data[ x + y * 4 * W] = av_lfg_get(&rand); - sws_scale(sws, rgb_src, rgb_stride, 0, H / 12, (uint8_t * const *) src, stride); + res = sws_scale(sws, rgb_src, rgb_stride, 0, H / 12, (uint8_t * const *) src, stride); + if (res < 0 || res != H) { + res = -1; + goto error; + } sws_freeContext(sws); av_free(rgb_data); diff --git a/libswscale/utils.c b/libswscale/utils.c index 111062e91..352a8ed11 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -271,6 +271,7 @@ static const FormatEntry format_entries[] = { [AV_PIX_FMT_NV24] = { 1, 1 }, [AV_PIX_FMT_NV42] = { 1, 1 }, [AV_PIX_FMT_Y210LE] = { 1, 0 }, + [AV_PIX_FMT_X2RGB10LE] = { 1, 1 }, }; int sws_isSupportedInput(enum AVPixelFormat pix_fmt) @@ -352,13 +353,14 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, emms_c(); // FIXME should not be required but IS (even for non-MMX versions) // NOTE: the +3 is for the MMX(+1) / SSE(+3) scaler which reads over the end - FF_ALLOC_ARRAY_OR_GOTO(NULL, *filterPos, (dstW + 3), sizeof(**filterPos), fail); + if (!FF_ALLOC_TYPED_ARRAY(*filterPos, dstW + 3)) + goto nomem; if (FFABS(xInc - 0x10000) < 10 && srcPos == dstPos) { // unscaled int i; filterSize = 1; - FF_ALLOCZ_ARRAY_OR_GOTO(NULL, filter, - dstW, sizeof(*filter) * filterSize, fail); + if (!FF_ALLOCZ_TYPED_ARRAY(filter, dstW * filterSize)) + goto nomem; for (i = 0; i < dstW; i++) { filter[i * filterSize] = fone; @@ -368,8 +370,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, int i; int64_t xDstInSrc; filterSize = 1; - FF_ALLOC_ARRAY_OR_GOTO(NULL, filter, - dstW, sizeof(*filter) * filterSize, fail); + if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize)) + goto nomem; xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7); for (i = 0; i < dstW; i++) { @@ -384,8 +386,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, int i; int64_t xDstInSrc; filterSize = 2; - FF_ALLOC_ARRAY_OR_GOTO(NULL, filter, - dstW, sizeof(*filter) * filterSize, fail); + if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize)) + goto nomem; xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7); for (i = 0; i < dstW; i++) { @@ -425,9 +427,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, filterSize = FFMIN(filterSize, srcW - 2); filterSize = FFMAX(filterSize, 1); - FF_ALLOC_ARRAY_OR_GOTO(NULL, filter, - dstW, sizeof(*filter) * filterSize, fail); - + if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize)) + goto nomem; xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7); for (i = 0; i < dstW; i++) { int xx = (xDstInSrc - (filterSize - 2) * (1LL<<16)) / (1 << 17); @@ -525,8 +526,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, if (dstFilter) filter2Size += dstFilter->length - 1; av_assert0(filter2Size > 0); - FF_ALLOCZ_ARRAY_OR_GOTO(NULL, filter2, dstW, filter2Size * sizeof(*filter2), fail); - + if (!FF_ALLOCZ_TYPED_ARRAY(filter2, dstW * filter2Size)) + goto nomem; for (i = 0; i < dstW; i++) { int j, k; @@ -611,7 +612,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, av_assert0(filterSize > 0); filter = av_malloc_array(dstW, filterSize * sizeof(*filter)); if (!filter) - goto fail; + goto nomem; if (filterSize >= MAX_FILTER_SIZE * 16 / ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16)) { ret = RETCODE_USE_CASCADE; @@ -684,8 +685,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, // Note the +1 is for the MMX scaler which reads over the end /* align at 16 for AltiVec (needed by hScale_altivec_real) */ - FF_ALLOCZ_ARRAY_OR_GOTO(NULL, *outFilter, - (dstW + 3), *outFilterSize * sizeof(int16_t), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(*outFilter, *outFilterSize * (dstW + 3))) + goto nomem; /* normalize & store in outFilter */ for (i = 0; i < dstW; i++) { @@ -721,10 +722,13 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, } ret = 0; - + goto done; +nomem: + ret = AVERROR(ENOMEM); fail: if(ret < 0) av_log(NULL, ret == RETCODE_USE_CASCADE ? AV_LOG_DEBUG : AV_LOG_ERROR, "sws: initFilter failed\n"); +done: av_free(filter); av_free(filter2); return ret; @@ -860,6 +864,11 @@ static void fill_xyztables(struct SwsContext *c) } } +static int range_override_needed(enum AVPixelFormat format) +{ + return !isYUV(format) && !isGray(format); +} + int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation) @@ -872,9 +881,9 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], desc_dst = av_pix_fmt_desc_get(c->dstFormat); desc_src = av_pix_fmt_desc_get(c->srcFormat); - if(!isYUV(c->dstFormat) && !isGray(c->dstFormat)) + if(range_override_needed(c->dstFormat)) dstRange = 0; - if(!isYUV(c->srcFormat) && !isGray(c->srcFormat)) + if(range_override_needed(c->srcFormat)) srcRange = 0; if (c->srcRange != srcRange || @@ -1004,8 +1013,8 @@ int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, *inv_table = c->srcColorspaceTable; *table = c->dstColorspaceTable; - *srcRange = c->srcRange; - *dstRange = c->dstRange; + *srcRange = range_override_needed(c->srcFormat) ? 1 : c->srcRange; + *dstRange = range_override_needed(c->dstFormat) ? 1 : c->dstRange; *brightness = c->brightness; *contrast = c->contrast; *saturation = c->saturation; @@ -1417,7 +1426,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, c->chrDstW = AV_CEIL_RSHIFT(dstW, c->chrDstHSubSample); c->chrDstH = AV_CEIL_RSHIFT(dstH, c->chrDstVSubSample); - FF_ALLOCZ_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail); + if (!FF_ALLOCZ_TYPED_ARRAY(c->formatConvBuffer, FFALIGN(srcW * 2 + 78, 16) * 2)) + goto nomem; c->srcBpc = desc_src->comp[0].depth; if (c->srcBpc < 8) @@ -1486,7 +1496,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, srcW, srcH, tmpFmt, flags, NULL, NULL, c->param); if (!c->cascaded_context[0]) { - return -1; + return AVERROR(ENOMEM); } c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFmt, @@ -1494,7 +1504,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, flags, srcFilter, dstFilter, c->param); if (!c->cascaded_context[1]) - return -1; + return AVERROR(ENOMEM); c2 = c->cascaded_context[1]; c2->is_internal_gamma = 1; @@ -1507,10 +1517,10 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, // to properly create the gamma convert FilterDescriptor // we have to re-initialize it ff_free_filters(c2); - if (ff_init_filters(c2) < 0) { + if ((ret = ff_init_filters(c2)) < 0) { sws_freeContext(c2); c->cascaded_context[1] = NULL; - return -1; + return ret; } c->cascaded_context[2] = NULL; @@ -1524,15 +1534,16 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, dstW, dstH, dstFormat, flags, NULL, NULL, c->param); if (!c->cascaded_context[2]) - return -1; + return AVERROR(ENOMEM); } return 0; } if (isBayer(srcFormat)) { if (!unscaled || - (dstFormat != AV_PIX_FMT_RGB24 && dstFormat != AV_PIX_FMT_YUV420P)) { - enum AVPixelFormat tmpFormat = AV_PIX_FMT_RGB24; + (dstFormat != AV_PIX_FMT_RGB24 && dstFormat != AV_PIX_FMT_YUV420P && + dstFormat != AV_PIX_FMT_RGB48)) { + enum AVPixelFormat tmpFormat = isBayer16BPS(srcFormat) ? AV_PIX_FMT_RGB48 : AV_PIX_FMT_RGB24; ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride, srcW, srcH, tmpFormat, 64); @@ -1543,13 +1554,13 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, srcW, srcH, tmpFormat, flags, srcFilter, NULL, c->param); if (!c->cascaded_context[0]) - return -1; + return AVERROR(ENOMEM); c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFormat, dstW, dstH, dstFormat, flags, NULL, dstFilter, c->param); if (!c->cascaded_context[1]) - return -1; + return AVERROR(ENOMEM); return 0; } } @@ -1570,41 +1581,42 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, if (CONFIG_SWSCALE_ALPHA && isALPHA(srcFormat) && !isALPHA(dstFormat)) { enum AVPixelFormat tmpFormat = alphaless_fmt(srcFormat); - if (tmpFormat != AV_PIX_FMT_NONE && c->alphablend != SWS_ALPHA_BLEND_NONE) - if (!unscaled || - dstFormat != tmpFormat || - usesHFilter || usesVFilter || - c->srcRange != c->dstRange - ) { - c->cascaded_mainindex = 1; - ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride, - srcW, srcH, tmpFormat, 64); - if (ret < 0) - return ret; + if (tmpFormat != AV_PIX_FMT_NONE && c->alphablend != SWS_ALPHA_BLEND_NONE) { + if (!unscaled || + dstFormat != tmpFormat || + usesHFilter || usesVFilter || + c->srcRange != c->dstRange + ) { + c->cascaded_mainindex = 1; + ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride, + srcW, srcH, tmpFormat, 64); + if (ret < 0) + return ret; - c->cascaded_context[0] = sws_alloc_set_opts(srcW, srcH, srcFormat, - srcW, srcH, tmpFormat, - flags, c->param); - if (!c->cascaded_context[0]) - return -1; - c->cascaded_context[0]->alphablend = c->alphablend; - ret = sws_init_context(c->cascaded_context[0], NULL , NULL); - if (ret < 0) - return ret; + c->cascaded_context[0] = sws_alloc_set_opts(srcW, srcH, srcFormat, + srcW, srcH, tmpFormat, + flags, c->param); + if (!c->cascaded_context[0]) + return AVERROR(EINVAL); + c->cascaded_context[0]->alphablend = c->alphablend; + ret = sws_init_context(c->cascaded_context[0], NULL , NULL); + if (ret < 0) + return ret; - c->cascaded_context[1] = sws_alloc_set_opts(srcW, srcH, tmpFormat, - dstW, dstH, dstFormat, - flags, c->param); - if (!c->cascaded_context[1]) - return -1; + c->cascaded_context[1] = sws_alloc_set_opts(srcW, srcH, tmpFormat, + dstW, dstH, dstFormat, + flags, c->param); + if (!c->cascaded_context[1]) + return AVERROR(EINVAL); - c->cascaded_context[1]->srcRange = c->srcRange; - c->cascaded_context[1]->dstRange = c->dstRange; - ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter); - if (ret < 0) - return ret; + c->cascaded_context[1]->srcRange = c->srcRange; + c->cascaded_context[1]->dstRange = c->dstRange; + ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter); + if (ret < 0) + return ret; - return 0; + return 0; + } } } @@ -1657,10 +1669,11 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, return AVERROR(ENOMEM); } - FF_ALLOCZ_OR_GOTO(c, c->hLumFilter, (dstW / 8 + 8) * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(c, c->hChrFilter, (c->chrDstW / 4 + 8) * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(c, c->hLumFilterPos, (dstW / 2 / 8 + 8) * sizeof(int32_t), fail); - FF_ALLOCZ_OR_GOTO(c, c->hChrFilterPos, (c->chrDstW / 2 / 4 + 8) * sizeof(int32_t), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(c->hLumFilter, dstW / 8 + 8) || + !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilter, c->chrDstW / 4 + 8) || + !FF_ALLOCZ_TYPED_ARRAY(c->hLumFilterPos, dstW / 2 / 8 + 8) || + !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilterPos, c->chrDstW / 2 / 4 + 8)) + goto nomem; ff_init_hscaler_mmxext( dstW, c->lumXInc, c->lumMmxextFilterCode, c->hLumFilter, (uint32_t*)c->hLumFilterPos, 8); @@ -1671,6 +1684,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, if ( mprotect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1 || mprotect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1) { av_log(c, AV_LOG_ERROR, "mprotect failed, cannot use fast bilinear scaler\n"); + ret = AVERROR(EINVAL); goto fail; } #endif @@ -1728,8 +1742,9 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, goto fail; #if HAVE_ALTIVEC - FF_ALLOC_OR_GOTO(c, c->vYCoeffsBank, sizeof(vector signed short) * c->vLumFilterSize * c->dstH, fail); - FF_ALLOC_OR_GOTO(c, c->vCCoeffsBank, sizeof(vector signed short) * c->vChrFilterSize * c->chrDstH, fail); + if (!FF_ALLOC_TYPED_ARRAY(c->vYCoeffsBank, c->vLumFilterSize * c->dstH) || + !FF_ALLOC_TYPED_ARRAY(c->vCCoeffsBank, c->vChrFilterSize * c->chrDstH)) + goto nomem; for (i = 0; i < c->vLumFilterSize * c->dstH; i++) { int j; @@ -1748,7 +1763,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, } for (i = 0; i < 4; i++) - FF_ALLOCZ_OR_GOTO(c, c->dither_error[i], (c->dstW+2) * sizeof(int), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], c->dstW + 2)) + goto nomem; c->needAlpha = (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) ? 1 : 0; @@ -1838,6 +1854,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, c->swscale = ff_getSwsFunc(c); return ff_init_filters(c); +nomem: + ret = AVERROR(ENOMEM); fail: // FIXME replace things by appropriate error codes if (ret == RETCODE_USE_CASCADE) { int tmpW = sqrt(srcW * (int64_t)dstW); @@ -1859,16 +1877,16 @@ fail: // FIXME replace things by appropriate error codes tmpW, tmpH, tmpFormat, flags, srcFilter, NULL, c->param); if (!c->cascaded_context[0]) - return -1; + return AVERROR(ENOMEM); c->cascaded_context[1] = sws_getContext(tmpW, tmpH, tmpFormat, dstW, dstH, dstFormat, flags, NULL, dstFilter, c->param); if (!c->cascaded_context[1]) - return -1; + return AVERROR(ENOMEM); return 0; } - return -1; + return ret; } SwsContext *sws_alloc_set_opts(int srcW, int srcH, enum AVPixelFormat srcFormat, diff --git a/libswscale/version.h b/libswscale/version.h index 3aec51f1b..bc61201a8 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -27,7 +27,7 @@ #include "libavutil/version.h" #define LIBSWSCALE_VERSION_MAJOR 5 -#define LIBSWSCALE_VERSION_MINOR 7 +#define LIBSWSCALE_VERSION_MINOR 9 #define LIBSWSCALE_VERSION_MICRO 100 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ diff --git a/libswscale/vscale.c b/libswscale/vscale.c index 9ed227e90..500217239 100644 --- a/libswscale/vscale.c +++ b/libswscale/vscale.c @@ -92,7 +92,7 @@ static int chr_planar_vscale(SwsContext *c, SwsFilterDescriptor *desc, int slice uint16_t *filter = inst->filter[0] + (inst->isMMX ? 0 : chrSliceY * inst->filter_size); if (c->yuv2nv12cX) { - inst->pfn.yuv2interleavedX(c, filter, inst->filter_size, (const int16_t**)src1, (const int16_t**)src2, dst1[0], dstW); + inst->pfn.yuv2interleavedX(c->dstFormat, c->chrDither8, filter, inst->filter_size, (const int16_t**)src1, (const int16_t**)src2, dst1[0], dstW); } else if (inst->filter_size == 1) { inst->pfn.yuv2planar1((const int16_t*)src1[0], dst1[0], dstW, c->chrDither8, 0); inst->pfn.yuv2planar1((const int16_t*)src2[0], dst2[0], dstW, c->chrDither8, 3); diff --git a/libswscale/x86/Makefile b/libswscale/x86/Makefile index 831d5359a..bfe383364 100644 --- a/libswscale/x86/Makefile +++ b/libswscale/x86/Makefile @@ -13,3 +13,4 @@ X86ASM-OBJS += x86/input.o \ x86/scale.o \ x86/rgb_2_rgb.o \ x86/yuv_2_rgb.o \ + x86/yuv2yuvX.o \ diff --git a/libswscale/x86/hscale_fast_bilinear_simd.c b/libswscale/x86/hscale_fast_bilinear_simd.c index 60a2cbfc5..850f0add3 100644 --- a/libswscale/x86/hscale_fast_bilinear_simd.c +++ b/libswscale/x86/hscale_fast_bilinear_simd.c @@ -21,6 +21,7 @@ #include "../swscale_internal.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" +#include "libavutil/mem_internal.h" #define RET 0xC3 // near return opcode for x86 #define PREFETCH "prefetchnta" diff --git a/libswscale/x86/output.asm b/libswscale/x86/output.asm index db3e9934f..52cf9f2c2 100644 --- a/libswscale/x86/output.asm +++ b/libswscale/x86/output.asm @@ -2,6 +2,7 @@ ;* x86-optimized vertical line scaling functions ;* Copyright (c) 2011 Ronald S. Bultje ;* Kieran Kunhya +;* (c) 2020 Nelson Gomez ;* ;* This file is part of FFmpeg. ;* @@ -22,7 +23,7 @@ %include "libavutil/x86/x86util.asm" -SECTION_RODATA +SECTION_RODATA 32 minshort: times 8 dw 0x8000 yuv2yuvX_16_start: times 4 dd 0x4000 - 0x40000000 @@ -34,9 +35,20 @@ pd_4: times 4 dd 4 pd_4min0x40000:times 4 dd 4 - (0x40000) pw_16: times 8 dw 16 pw_32: times 8 dw 32 +pd_255: times 8 dd 255 pw_512: times 8 dw 512 pw_1024: times 8 dw 1024 +yuv2nv12_shuffle_mask: times 2 db 0, 4, 8, 12, \ + -1, -1, -1, -1, \ + -1, -1, -1, -1, \ + -1, -1, -1, -1 +yuv2nv21_shuffle_mask: times 2 db 4, 0, 12, 8, \ + -1, -1, -1, -1, \ + -1, -1, -1, -1, \ + -1, -1, -1, -1 +yuv2nv12_permute_mask: dd 0, 4, 1, 2, 3, 5, 6, 7 + SECTION .text ;----------------------------------------------------------------------------- @@ -423,3 +435,117 @@ yuv2plane1_fn 9, 5, 3 yuv2plane1_fn 10, 5, 3 yuv2plane1_fn 16, 5, 3 %endif + +%undef movsx + +;----------------------------------------------------------------------------- +; AVX2 yuv2nv12cX implementation +; +; void ff_yuv2nv12cX_avx2(enum AVPixelFormat format, const uint8_t *dither, +; const int16_t *filter, int filterSize, +; const int16_t **u, const int16_t **v, +; uint8_t *dst, int dstWidth) +; +; void ff_yuv2nv21cX_avx2(enum AVPixelFormat format, const uint8_t *dither, +; const int16_t *filter, int filterSize, +; const int16_t **u, const int16_t **v, +; uint8_t *dst, int dstWidth) +;----------------------------------------------------------------------------- + +%if ARCH_X86_64 +%macro yuv2nv12cX_fn 1 +cglobal %1cX, 8, 11, 13, tmp1, dither, filter, filterSize, u, v, dst, dstWidth + + mov tmp1q, qword [ditherq] + movq xm0, tmp1q + ror tmp1q, 24 + movq xm1, tmp1q + + pmovzxbd m0, xm0 + pslld m0, m0, 12 ; ditherLo + pmovzxbd m1, xm1 + pslld m1, m1, 12 ; ditherHi + + pxor m9, m9 ; uint8_min dwords + mova m10, [pd_255] ; uint8_max dwords + mova m11, [%1_shuffle_mask] ; shuffle_mask + mova m12, [yuv2nv12_permute_mask] ; permute mask + + DEFINE_ARGS tmp1, tmp2, filter, filterSize, u, v, dst, dstWidth + + xor r8q, r8q + +nv12_outer_%1: + mova m2, m0 ; resultLo + mova m3, m1 ; resultHi + xor r9q, r9q + +nv12_inner_%1: + movsx r10d, word [filterq + (2 * r9q)] + movd xm4, r10d + vpbroadcastd m4, xm4 ; filter + + mov tmp1q, [uq + (gprsize * r9q)] + mova xm7, oword [tmp1q + 2 * r8q] + + mov tmp2q, [vq + (gprsize * r9q)] + mova xm8, oword [tmp2q + 2 * r8q] + + punpcklwd xm5, xm7, xm8 + pmovsxwd m5, xm5 ; multiplicandsLo + punpckhwd xm6, xm7, xm8 + pmovsxwd m6, xm6 ; multiplicandsHi + + pmulld m7, m5, m4 ; mulResultLo + pmulld m8, m6, m4 ; mulResultHi + paddd m2, m2, m7 ; resultLo += mulResultLo + paddd m3, m3, m8 ; resultHi += mulResultHi + + inc r9d + cmp r9d, filterSized + jl nv12_inner_%1 + ; end of inner loop + + psrad m2, m2, 19 + psrad m3, m3, 19 + + ; Vectorized av_clip_uint8 + pmaxsd m2, m2, m9 + pmaxsd m3, m3, m9 + pminsd m2, m2, m10 + pminsd m3, m3, m10 + + ; At this point we have clamped uint8s arranged in this order: + ; m2: u1 0 0 0 v1 0 0 0 [...] + ; m3: u5 0 0 0 v5 0 0 0 [...] + ; + ; First, we shuffle the bytes to make the bytes semi-contiguous. + ; AVX-2 doesn't have cross-lane shuffling, so we'll end up with: + ; m2: u1 v1 u2 v2 0 0 0 0 0 0 0 0 u3 v3 u4 v4 + ; m3: u5 v5 u6 v6 0 0 0 0 0 0 0 0 u7 v7 u8 v8 + pshufb m2, m2, m11 + pshufb m3, m3, m11 + + ; To fix the cross-lane shuffling issue, we'll then use cross-lane + ; permutation to combine the two segments + vpermd m2, m12, m2 + vpermd m3, m12, m3 + + ; Now we have the final results in the lower 8 bytes of each register + movq [dstq], xm2 + movq [dstq + 8], xm3 + + add r8d, 8 + add dstq, 16 + + cmp r8d, dstWidthd + jl nv12_outer_%1 + RET +%endmacro + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +yuv2nv12cX_fn yuv2nv12 +yuv2nv12cX_fn yuv2nv21 +%endif +%endif ; ARCH_X86_64 diff --git a/libswscale/x86/rgb2rgb.c b/libswscale/x86/rgb2rgb.c index 2d6fc2ad2..c38a95327 100644 --- a/libswscale/x86/rgb2rgb.c +++ b/libswscale/x86/rgb2rgb.c @@ -30,6 +30,8 @@ #include "libavutil/x86/cpu.h" #include "libavutil/cpu.h" #include "libavutil/bswap.h" +#include "libavutil/mem_internal.h" + #include "libswscale/rgb2rgb.h" #include "libswscale/swscale.h" #include "libswscale/swscale_internal.h" @@ -38,12 +40,7 @@ DECLARE_ASM_CONST(8, uint64_t, mmx_ff) = 0x00000000000000FFULL; DECLARE_ASM_CONST(8, uint64_t, mmx_null) = 0x0000000000000000ULL; -DECLARE_ASM_CONST(8, uint64_t, mmx_one) = 0xFFFFFFFFFFFFFFFFULL; -DECLARE_ASM_CONST(8, uint64_t, mask32b) = 0x000000FF000000FFULL; -DECLARE_ASM_CONST(8, uint64_t, mask32g) = 0x0000FF000000FF00ULL; -DECLARE_ASM_CONST(8, uint64_t, mask32r) = 0x00FF000000FF0000ULL; DECLARE_ASM_CONST(8, uint64_t, mask32a) = 0xFF000000FF000000ULL; -DECLARE_ASM_CONST(8, uint64_t, mask32) = 0x00FFFFFF00FFFFFFULL; DECLARE_ASM_CONST(8, uint64_t, mask3216br) = 0x00F800F800F800F8ULL; DECLARE_ASM_CONST(8, uint64_t, mask3216g) = 0x0000FC000000FC00ULL; DECLARE_ASM_CONST(8, uint64_t, mask3215g) = 0x0000F8000000F800ULL; @@ -54,9 +51,6 @@ DECLARE_ASM_CONST(8, uint64_t, mask24g) = 0xFF0000FF0000FF00ULL; DECLARE_ASM_CONST(8, uint64_t, mask24r) = 0x0000FF0000FF0000ULL; DECLARE_ASM_CONST(8, uint64_t, mask24l) = 0x0000000000FFFFFFULL; DECLARE_ASM_CONST(8, uint64_t, mask24h) = 0x0000FFFFFF000000ULL; -DECLARE_ASM_CONST(8, uint64_t, mask24hh) = 0xffff000000000000ULL; -DECLARE_ASM_CONST(8, uint64_t, mask24hhh) = 0xffffffff00000000ULL; -DECLARE_ASM_CONST(8, uint64_t, mask24hhhh) = 0xffffffffffff0000ULL; DECLARE_ASM_CONST(8, uint64_t, mask15b) = 0x001F001F001F001FULL; /* 00000000 00011111 xxB */ DECLARE_ASM_CONST(8, uint64_t, mask15rg) = 0x7FE07FE07FE07FE0ULL; /* 01111111 11100000 RGx */ DECLARE_ASM_CONST(8, uint64_t, mask15s) = 0xFFE0FFE0FFE0FFE0ULL; diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c index 61110839e..0848a3146 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -27,6 +27,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/x86/cpu.h" #include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" const DECLARE_ALIGNED(8, uint64_t, ff_dither4)[2] = { @@ -43,15 +44,6 @@ const DECLARE_ALIGNED(8, uint64_t, ff_dither8)[2] = { DECLARE_ASM_CONST(8, uint64_t, bF8)= 0xF8F8F8F8F8F8F8F8LL; DECLARE_ASM_CONST(8, uint64_t, bFC)= 0xFCFCFCFCFCFCFCFCLL; -DECLARE_ASM_CONST(8, uint64_t, w10)= 0x0010001000100010LL; -DECLARE_ASM_CONST(8, uint64_t, w02)= 0x0002000200020002LL; - -DECLARE_ASM_CONST(8, uint64_t, b16Mask)= 0x001F001F001F001FLL; -DECLARE_ASM_CONST(8, uint64_t, g16Mask)= 0x07E007E007E007E0LL; -DECLARE_ASM_CONST(8, uint64_t, r16Mask)= 0xF800F800F800F800LL; -DECLARE_ASM_CONST(8, uint64_t, b15Mask)= 0x001F001F001F001FLL; -DECLARE_ASM_CONST(8, uint64_t, g15Mask)= 0x03E003E003E003E0LL; -DECLARE_ASM_CONST(8, uint64_t, r15Mask)= 0x7C007C007C007C00LL; DECLARE_ASM_ALIGNED(8, const uint64_t, ff_M24A) = 0x00FF0000FF0000FFLL; DECLARE_ASM_ALIGNED(8, const uint64_t, ff_M24B) = 0xFF0000FF0000FF00LL; @@ -195,87 +187,56 @@ void ff_updateMMXDitherTables(SwsContext *c, int dstY) } } } - -#if HAVE_MMXEXT -static void yuv2yuvX_sse3(const int16_t *filter, int filterSize, - const int16_t **src, uint8_t *dest, int dstW, - const uint8_t *dither, int offset) -{ - if(((uintptr_t)dest) & 15){ - yuv2yuvX_mmxext(filter, filterSize, src, dest, dstW, dither, offset); - return; - } - filterSize--; -#define MAIN_FUNCTION \ - "pxor %%xmm0, %%xmm0 \n\t" \ - "punpcklbw %%xmm0, %%xmm3 \n\t" \ - "movd %4, %%xmm1 \n\t" \ - "punpcklwd %%xmm1, %%xmm1 \n\t" \ - "punpckldq %%xmm1, %%xmm1 \n\t" \ - "punpcklqdq %%xmm1, %%xmm1 \n\t" \ - "psllw $3, %%xmm1 \n\t" \ - "paddw %%xmm1, %%xmm3 \n\t" \ - "psraw $4, %%xmm3 \n\t" \ - "movdqa %%xmm3, %%xmm4 \n\t" \ - "movdqa %%xmm3, %%xmm7 \n\t" \ - "movl %3, %%ecx \n\t" \ - "mov %0, %%"FF_REG_d" \n\t"\ - "mov (%%"FF_REG_d"), %%"FF_REG_S" \n\t"\ - ".p2align 4 \n\t" /* FIXME Unroll? */\ - "1: \n\t"\ - "movddup 8(%%"FF_REG_d"), %%xmm0 \n\t" /* filterCoeff */\ - "movdqa (%%"FF_REG_S", %%"FF_REG_c", 2), %%xmm2 \n\t" /* srcData */\ - "movdqa 16(%%"FF_REG_S", %%"FF_REG_c", 2), %%xmm5 \n\t" /* srcData */\ - "add $16, %%"FF_REG_d" \n\t"\ - "mov (%%"FF_REG_d"), %%"FF_REG_S" \n\t"\ - "test %%"FF_REG_S", %%"FF_REG_S" \n\t"\ - "pmulhw %%xmm0, %%xmm2 \n\t"\ - "pmulhw %%xmm0, %%xmm5 \n\t"\ - "paddw %%xmm2, %%xmm3 \n\t"\ - "paddw %%xmm5, %%xmm4 \n\t"\ - " jnz 1b \n\t"\ - "psraw $3, %%xmm3 \n\t"\ - "psraw $3, %%xmm4 \n\t"\ - "packuswb %%xmm4, %%xmm3 \n\t"\ - "movntdq %%xmm3, (%1, %%"FF_REG_c") \n\t"\ - "add $16, %%"FF_REG_c" \n\t"\ - "cmp %2, %%"FF_REG_c" \n\t"\ - "movdqa %%xmm7, %%xmm3 \n\t" \ - "movdqa %%xmm7, %%xmm4 \n\t" \ - "mov %0, %%"FF_REG_d" \n\t"\ - "mov (%%"FF_REG_d"), %%"FF_REG_S" \n\t"\ - "jb 1b \n\t" - - if (offset) { - __asm__ volatile( - "movq %5, %%xmm3 \n\t" - "movdqa %%xmm3, %%xmm4 \n\t" - "psrlq $24, %%xmm3 \n\t" - "psllq $40, %%xmm4 \n\t" - "por %%xmm4, %%xmm3 \n\t" - MAIN_FUNCTION - :: "g" (filter), - "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset), - "m"(filterSize), "m"(((uint64_t *) dither)[0]) - : XMM_CLOBBERS("%xmm0" , "%xmm1" , "%xmm2" , "%xmm3" , "%xmm4" , "%xmm5" , "%xmm7" ,) - "%"FF_REG_d, "%"FF_REG_S, "%"FF_REG_c - ); - } else { - __asm__ volatile( - "movq %5, %%xmm3 \n\t" - MAIN_FUNCTION - :: "g" (filter), - "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset), - "m"(filterSize), "m"(((uint64_t *) dither)[0]) - : XMM_CLOBBERS("%xmm0" , "%xmm1" , "%xmm2" , "%xmm3" , "%xmm4" , "%xmm5" , "%xmm7" ,) - "%"FF_REG_d, "%"FF_REG_S, "%"FF_REG_c - ); - } -} -#endif - #endif /* HAVE_INLINE_ASM */ +#define YUV2YUVX_FUNC_MMX(opt, step) \ +void ff_yuv2yuvX_ ##opt(const int16_t *filter, int filterSize, int srcOffset, \ + uint8_t *dest, int dstW, \ + const uint8_t *dither, int offset); \ +static void yuv2yuvX_ ##opt(const int16_t *filter, int filterSize, \ + const int16_t **src, uint8_t *dest, int dstW, \ + const uint8_t *dither, int offset) \ +{ \ + if(dstW > 0) \ + ff_yuv2yuvX_ ##opt(filter, filterSize - 1, 0, dest - offset, dstW + offset, dither, offset); \ + return; \ +} + +#define YUV2YUVX_FUNC(opt, step) \ +void ff_yuv2yuvX_ ##opt(const int16_t *filter, int filterSize, int srcOffset, \ + uint8_t *dest, int dstW, \ + const uint8_t *dither, int offset); \ +static void yuv2yuvX_ ##opt(const int16_t *filter, int filterSize, \ + const int16_t **src, uint8_t *dest, int dstW, \ + const uint8_t *dither, int offset) \ +{ \ + int remainder = (dstW % step); \ + int pixelsProcessed = dstW - remainder; \ + if(((uintptr_t)dest) & 15){ \ + yuv2yuvX_mmx(filter, filterSize, src, dest, dstW, dither, offset); \ + return; \ + } \ + if(pixelsProcessed > 0) \ + ff_yuv2yuvX_ ##opt(filter, filterSize - 1, 0, dest - offset, pixelsProcessed + offset, dither, offset); \ + if(remainder > 0){ \ + ff_yuv2yuvX_mmx(filter, filterSize - 1, pixelsProcessed, dest - offset, pixelsProcessed + remainder + offset, dither, offset); \ + } \ + return; \ +} + +#if HAVE_MMX_EXTERNAL +YUV2YUVX_FUNC_MMX(mmx, 16) +#endif +#if HAVE_MMXEXT_EXTERNAL +YUV2YUVX_FUNC_MMX(mmxext, 16) +#endif +#if HAVE_SSE3_EXTERNAL +YUV2YUVX_FUNC(sse3, 32) +#endif +#if HAVE_AVX2_EXTERNAL +YUV2YUVX_FUNC(avx2, 64) +#endif + #define SCALE_FUNC(filter_n, from_bpc, to_bpc, opt) \ void ff_hscale ## from_bpc ## to ## to_bpc ## _ ## filter_n ## _ ## opt( \ SwsContext *c, int16_t *data, \ @@ -380,6 +341,17 @@ INPUT_FUNCS(sse2); INPUT_FUNCS(ssse3); INPUT_FUNCS(avx); +#if ARCH_X86_64 +#define YUV2NV_DECL(fmt, opt) \ +void ff_yuv2 ## fmt ## cX_ ## opt(enum AVPixelFormat format, const uint8_t *dither, \ + const int16_t *filter, int filterSize, \ + const int16_t **u, const int16_t **v, \ + uint8_t *dst, int dstWidth) + +YUV2NV_DECL(nv12, avx2); +YUV2NV_DECL(nv21, avx2); +#endif + av_cold void ff_sws_init_swscale_x86(SwsContext *c) { int cpu_flags = av_get_cpu_flags(); @@ -391,11 +363,25 @@ av_cold void ff_sws_init_swscale_x86(SwsContext *c) #if HAVE_MMXEXT_INLINE if (INLINE_MMXEXT(cpu_flags)) sws_init_swscale_mmxext(c); - if (cpu_flags & AV_CPU_FLAG_SSE3){ - if(c->use_mmx_vfilter && !(c->flags & SWS_ACCURATE_RND)) - c->yuv2planeX = yuv2yuvX_sse3; - } #endif + if(c->use_mmx_vfilter && !(c->flags & SWS_ACCURATE_RND)) { +#if HAVE_MMX_EXTERNAL + if (EXTERNAL_MMX(cpu_flags)) + c->yuv2planeX = yuv2yuvX_mmx; +#endif +#if HAVE_MMXEXT_EXTERNAL + if (EXTERNAL_MMXEXT(cpu_flags)) + c->yuv2planeX = yuv2yuvX_mmxext; +#endif +#if HAVE_SSE3_EXTERNAL + if (EXTERNAL_SSE3(cpu_flags)) + c->yuv2planeX = yuv2yuvX_sse3; +#endif +#if HAVE_AVX2_EXTERNAL + if (EXTERNAL_AVX2_FAST(cpu_flags)) + c->yuv2planeX = yuv2yuvX_avx2; +#endif + } #define ASSIGN_SCALE_FUNC2(hscalefn, filtersize, opt1, opt2) do { \ if (c->srcBpc == 8) { \ @@ -580,4 +566,21 @@ switch(c->dstBpc){ \ break; } } + +#if ARCH_X86_64 + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + switch (c->dstFormat) { + case AV_PIX_FMT_NV12: + case AV_PIX_FMT_NV24: + c->yuv2nv12cX = ff_yuv2nv12cX_avx2; + break; + case AV_PIX_FMT_NV21: + case AV_PIX_FMT_NV42: + c->yuv2nv12cX = ff_yuv2nv21cX_avx2; + break; + default: + break; + } + } +#endif } diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c index 823056c2e..97d8cae61 100644 --- a/libswscale/x86/swscale_template.c +++ b/libswscale/x86/swscale_template.c @@ -38,88 +38,6 @@ #endif #define MOVNTQ(a,b) REAL_MOVNTQ(a,b) -#if !COMPILE_TEMPLATE_MMXEXT -static av_always_inline void -dither_8to16(const uint8_t *srcDither, int rot) -{ - if (rot) { - __asm__ volatile("pxor %%mm0, %%mm0\n\t" - "movq (%0), %%mm3\n\t" - "movq %%mm3, %%mm4\n\t" - "psrlq $24, %%mm3\n\t" - "psllq $40, %%mm4\n\t" - "por %%mm4, %%mm3\n\t" - "movq %%mm3, %%mm4\n\t" - "punpcklbw %%mm0, %%mm3\n\t" - "punpckhbw %%mm0, %%mm4\n\t" - :: "r"(srcDither) - ); - } else { - __asm__ volatile("pxor %%mm0, %%mm0\n\t" - "movq (%0), %%mm3\n\t" - "movq %%mm3, %%mm4\n\t" - "punpcklbw %%mm0, %%mm3\n\t" - "punpckhbw %%mm0, %%mm4\n\t" - :: "r"(srcDither) - ); - } -} -#endif - -static void RENAME(yuv2yuvX)(const int16_t *filter, int filterSize, - const int16_t **src, uint8_t *dest, int dstW, - const uint8_t *dither, int offset) -{ - dither_8to16(dither, offset); - filterSize--; - __asm__ volatile( - "movd %0, %%mm1\n\t" - "punpcklwd %%mm1, %%mm1\n\t" - "punpckldq %%mm1, %%mm1\n\t" - "psllw $3, %%mm1\n\t" - "paddw %%mm1, %%mm3\n\t" - "paddw %%mm1, %%mm4\n\t" - "psraw $4, %%mm3\n\t" - "psraw $4, %%mm4\n\t" - ::"m"(filterSize) - ); - - __asm__ volatile(\ - "movq %%mm3, %%mm6\n\t" - "movq %%mm4, %%mm7\n\t" - "movl %3, %%ecx\n\t" - "mov %0, %%"FF_REG_d" \n\t"\ - "mov (%%"FF_REG_d"), %%"FF_REG_S" \n\t"\ - ".p2align 4 \n\t" /* FIXME Unroll? */\ - "1: \n\t"\ - "movq 8(%%"FF_REG_d"), %%mm0 \n\t" /* filterCoeff */\ - "movq (%%"FF_REG_S", %%"FF_REG_c", 2), %%mm2 \n\t" /* srcData */\ - "movq 8(%%"FF_REG_S", %%"FF_REG_c", 2), %%mm5 \n\t" /* srcData */\ - "add $16, %%"FF_REG_d" \n\t"\ - "mov (%%"FF_REG_d"), %%"FF_REG_S" \n\t"\ - "test %%"FF_REG_S", %%"FF_REG_S" \n\t"\ - "pmulhw %%mm0, %%mm2 \n\t"\ - "pmulhw %%mm0, %%mm5 \n\t"\ - "paddw %%mm2, %%mm3 \n\t"\ - "paddw %%mm5, %%mm4 \n\t"\ - " jnz 1b \n\t"\ - "psraw $3, %%mm3 \n\t"\ - "psraw $3, %%mm4 \n\t"\ - "packuswb %%mm4, %%mm3 \n\t" - MOVNTQ2 " %%mm3, (%1, %%"FF_REG_c")\n\t" - "add $8, %%"FF_REG_c" \n\t"\ - "cmp %2, %%"FF_REG_c" \n\t"\ - "movq %%mm6, %%mm3\n\t" - "movq %%mm7, %%mm4\n\t" - "mov %0, %%"FF_REG_d" \n\t"\ - "mov (%%"FF_REG_d"), %%"FF_REG_S" \n\t"\ - "jb 1b \n\t"\ - :: "g" (filter), - "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset) - : "%"FF_REG_d, "%"FF_REG_S, "%"FF_REG_c - ); -} - #define YSCALEYUV2PACKEDX_UV \ __asm__ volatile(\ "xor %%"FF_REG_a", %%"FF_REG_a" \n\t"\ @@ -1517,7 +1435,6 @@ static av_cold void RENAME(sws_init_swscale)(SwsContext *c) } } else { c->use_mmx_vfilter= 1; - c->yuv2planeX = RENAME(yuv2yuvX ); if (!(c->flags & SWS_FULL_CHR_H_INT)) { switch (c->dstFormat) { case AV_PIX_FMT_RGB32: c->yuv2packedX = RENAME(yuv2rgb32_X); break; diff --git a/libswscale/x86/yuv2rgb.c b/libswscale/x86/yuv2rgb.c index c12e88cbb..47f45bd7c 100644 --- a/libswscale/x86/yuv2rgb.c +++ b/libswscale/x86/yuv2rgb.c @@ -41,14 +41,6 @@ #define DITHER1XBPP // only for MMX -/* hope these constant values are cache line aligned */ -DECLARE_ASM_CONST(8, uint64_t, mmx_00ffw) = 0x00ff00ff00ff00ffULL; -DECLARE_ASM_CONST(8, uint64_t, mmx_redmask) = 0xf8f8f8f8f8f8f8f8ULL; -DECLARE_ASM_CONST(8, uint64_t, mmx_grnmask) = 0xfcfcfcfcfcfcfcfcULL; -DECLARE_ASM_CONST(8, uint64_t, pb_e0) = 0xe0e0e0e0e0e0e0e0ULL; -DECLARE_ASM_CONST(8, uint64_t, pb_03) = 0x0303030303030303ULL; -DECLARE_ASM_CONST(8, uint64_t, pb_07) = 0x0707070707070707ULL; - //MMX versions #if HAVE_MMX #undef RENAME @@ -59,22 +51,18 @@ DECLARE_ASM_CONST(8, uint64_t, pb_07) = 0x0707070707070707ULL; #endif /* HAVE_MMX */ // MMXEXT versions -#if HAVE_MMXEXT #undef RENAME #undef COMPILE_TEMPLATE_MMXEXT #define COMPILE_TEMPLATE_MMXEXT 1 #define RENAME(a) a ## _mmxext #include "yuv2rgb_template.c" -#endif /* HAVE_MMXEXT */ //SSSE3 versions -#if HAVE_SSSE3 #undef RENAME #undef COMPILE_TEMPLATE_MMXEXT #define COMPILE_TEMPLATE_MMXEXT 0 #define RENAME(a) a ## _ssse3 #include "yuv2rgb_template.c" -#endif #endif /* HAVE_X86ASM */ diff --git a/libswscale/x86/yuv2yuvX.asm b/libswscale/x86/yuv2yuvX.asm new file mode 100644 index 000000000..b6294cb91 --- /dev/null +++ b/libswscale/x86/yuv2yuvX.asm @@ -0,0 +1,136 @@ +;****************************************************************************** +;* x86-optimized yuv2yuvX +;* Copyright 2020 Google LLC +;* Copyright (C) 2001-2011 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/x86/x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; yuv2yuvX +; +; void ff_yuv2yuvX_(const int16_t *filter, int filterSize, +; int srcOffset, uint8_t *dest, int dstW, +; const uint8_t *dither, int offset); +; +;----------------------------------------------------------------------------- + +%macro YUV2YUVX_FUNC 0 +cglobal yuv2yuvX, 7, 7, 8, filter, filterSize, src, dest, dstW, dither, offset +%if notcpuflag(sse3) +%define movr mova +%define unroll 1 +%else +%define movr movdqu +%define unroll 2 +%endif + movsxdifnidn dstWq, dstWd + movsxdifnidn offsetq, offsetd + movsxdifnidn srcq, srcd +%if cpuflag(avx2) + vpbroadcastq m3, [ditherq] +%else + movq xm3, [ditherq] +%endif ; avx2 + cmp offsetd, 0 + jz .offset + + ; offset != 0 path. + psrlq m5, m3, $18 + psllq m3, m3, $28 + por m3, m3, m5 + +.offset: + add offsetq, srcq + movd xm1, filterSized + SPLATW m1, xm1, 0 + pxor m0, m0, m0 + mov filterSizeq, filterq + mov srcq, [filterSizeq] + punpcklbw m3, m0 + psllw m1, m1, 3 + paddw m3, m3, m1 + psraw m7, m3, 4 +.outerloop: + mova m4, m7 + mova m3, m7 +%if cpuflag(sse3) + mova m6, m7 + mova m1, m7 +%endif +.loop: +%if cpuflag(avx2) + vpbroadcastq m0, [filterSizeq + 8] +%elif cpuflag(sse3) + movddup m0, [filterSizeq + 8] +%else + mova m0, [filterSizeq + 8] +%endif + pmulhw m2, m0, [srcq + offsetq * 2] + pmulhw m5, m0, [srcq + offsetq * 2 + mmsize] + paddw m3, m3, m2 + paddw m4, m4, m5 +%if cpuflag(sse3) + pmulhw m2, m0, [srcq + offsetq * 2 + 2 * mmsize] + pmulhw m5, m0, [srcq + offsetq * 2 + 3 * mmsize] + paddw m6, m6, m2 + paddw m1, m1, m5 +%endif + add filterSizeq, $10 + mov srcq, [filterSizeq] + test srcq, srcq + jnz .loop + psraw m3, m3, 3 + psraw m4, m4, 3 +%if cpuflag(sse3) + psraw m6, m6, 3 + psraw m1, m1, 3 +%endif + packuswb m3, m3, m4 +%if cpuflag(sse3) + packuswb m6, m6, m1 +%endif + mov srcq, [filterq] +%if cpuflag(avx2) + vpermq m3, m3, 216 + vpermq m6, m6, 216 +%endif + movr [destq + offsetq], m3 +%if cpuflag(sse3) + movr [destq + offsetq + mmsize], m6 +%endif + add offsetq, mmsize * unroll + mov filterSizeq, filterq + cmp offsetq, dstWq + jb .outerloop + REP_RET +%endmacro + +INIT_MMX mmx +YUV2YUVX_FUNC +INIT_MMX mmxext +YUV2YUVX_FUNC +INIT_XMM sse3 +YUV2YUVX_FUNC +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +YUV2YUVX_FUNC +%endif diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c index 588462504..6a3956e8e 100644 --- a/libswscale/yuv2rgb.c +++ b/libswscale/yuv2rgb.c @@ -793,7 +793,8 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], c->dstFormat == AV_PIX_FMT_NE(RGB444LE, RGB444BE) || c->dstFormat == AV_PIX_FMT_NE(BGR565LE, BGR565BE) || c->dstFormat == AV_PIX_FMT_NE(BGR555LE, BGR555BE) || - c->dstFormat == AV_PIX_FMT_NE(BGR444LE, BGR444BE); + c->dstFormat == AV_PIX_FMT_NE(BGR444LE, BGR444BE) || + c->dstFormat == AV_PIX_FMT_NE(X2RGB10LE, X2RGB10BE); const int bpp = c->dstFormatBpp; uint8_t *y_table; uint16_t *y_table16; @@ -965,6 +966,32 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], fill_table(c->table_bU, 1, cbu, y_table + yoffs); fill_gv_table(c->table_gV, 1, cgv); break; + case 30: + rbase = 20; + gbase = 10; + bbase = 0; + needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat); + if (!needAlpha) + abase = 30; + ALLOC_YUV_TABLE(table_plane_size * 3 * 4); + y_table32 = c->yuvTable; + yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy; + for (i = 0; i < table_plane_size; i++) { + unsigned yval = av_clip_uint8((yb + 0x8000) >> 16); + y_table32[i]= (yval << rbase) + (needAlpha ? 0 : (255u << abase)); + y_table32[i + table_plane_size] = yval << gbase; + y_table32[i + 2 * table_plane_size] = yval << bbase; + yb += cy; + } + if (isNotNe) { + for (i = 0; i < table_plane_size * 3; i++) + y_table32[i] = av_bswap32(y_table32[i]); + } + fill_table(c->table_rV, 4, crv, y_table32 + yoffs); + fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + table_plane_size); + fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2 * table_plane_size); + fill_gv_table(c->table_gV, 4, cgv); + break; case 32: case 64: base = (c->dstFormat == AV_PIX_FMT_RGB32_1 || diff --git a/tests/api/Makefile b/tests/api/Makefile index b5c4ccae2..c96e63675 100644 --- a/tests/api/Makefile +++ b/tests/api/Makefile @@ -2,7 +2,6 @@ APITESTPROGS-$(call ENCDEC, FLAC, FLAC) += api-flac APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264 APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264-slice APITESTPROGS-yes += api-seek -APITESTPROGS-yes += api-codec-param APITESTPROGS-$(call DEMDEC, H263, H263) += api-band APITESTPROGS-$(HAVE_THREADS) += api-threadmessage APITESTPROGS += $(APITESTPROGS-yes) diff --git a/tests/api/api-band-test.c b/tests/api/api-band-test.c index a84f6b7e5..717c9441a 100644 --- a/tests/api/api-band-test.c +++ b/tests/api/api-band-test.c @@ -71,14 +71,12 @@ static int video_decode(const char *input_filename) AVCodecParameters *origin_par = NULL; uint8_t *byte_buffer = NULL; AVFrame *fr = NULL; - AVPacket pkt; + AVPacket *pkt; AVFormatContext *fmt_ctx = NULL; int number_of_written_bytes; int video_stream; - int got_frame = 0; int byte_buffer_size; int result; - int end_of_stream = 0; draw_horiz_band_called = 0; @@ -135,6 +133,12 @@ static int video_decode(const char *input_filename) return AVERROR(ENOMEM); } + pkt = av_packet_alloc(); + if (!pkt) { + av_log(NULL, AV_LOG_ERROR, "Cannot allocate packet\n"); + return AVERROR(ENOMEM); + } + if (strcmp(codec->name, "flv") && strcmp(codec->name, "mpeg4") && strcmp(codec->name, "huffyuv")) { av_log(NULL, AV_LOG_ERROR, "Wrong codec\n"); return -1; @@ -155,50 +159,59 @@ static int video_decode(const char *input_filename) memset(slice_byte_buffer, 0, byte_buffer_size); slice_byte_buffer_size = byte_buffer_size; - av_init_packet(&pkt); - do { - if (!end_of_stream) { - if (av_read_frame(fmt_ctx, &pkt) < 0) { - end_of_stream = 1; - } + result = 0; + while (result >= 0) { + result = av_read_frame(fmt_ctx, pkt); + if (result >= 0 && pkt->stream_index != video_stream) { + av_packet_unref(pkt); + continue; } - if (end_of_stream) { - pkt.data = NULL; - pkt.size = 0; + + // pkt will be empty on read error/EOF + result = avcodec_send_packet(ctx, pkt); + + av_packet_unref(pkt); + + if (result < 0) { + av_log(NULL, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); + return result; } - if (pkt.stream_index == video_stream || end_of_stream) { - got_frame = 0; - result = avcodec_decode_video2(ctx, fr, &got_frame, &pkt); - if (result < 0) { + + while (result >= 0) { + result = avcodec_receive_frame(ctx, fr); + if (result == AVERROR_EOF) + goto finish; + else if (result == AVERROR(EAGAIN)) { + result = 0; + break; + } else if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n"); return result; } - if (got_frame) { - number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size, - (const uint8_t* const *)fr->data, (const int*) fr->linesize, - ctx->pix_fmt, ctx->width, ctx->height, 1); - if (number_of_written_bytes < 0) { - av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n"); - return number_of_written_bytes; - } - if (draw_horiz_band_called == 0) { - av_log(NULL, AV_LOG_ERROR, "draw_horiz_band haven't been called!\n"); - return -1; - } - if (av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes) != - av_adler32_update(0, (const uint8_t*)slice_byte_buffer, number_of_written_bytes)) { - av_log(NULL, AV_LOG_ERROR, "Decoded frames with and without draw_horiz_band are not the same!\n"); - return -1; - } - } - av_packet_unref(&pkt); - av_init_packet(&pkt); - } - } while (!end_of_stream || got_frame); - av_packet_unref(&pkt); + number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size, + (const uint8_t* const *)fr->data, (const int*) fr->linesize, + ctx->pix_fmt, ctx->width, ctx->height, 1); + if (number_of_written_bytes < 0) { + av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n"); + return number_of_written_bytes; + } + if (draw_horiz_band_called == 0) { + av_log(NULL, AV_LOG_ERROR, "draw_horiz_band haven't been called!\n"); + return -1; + } + if (av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes) != + av_adler32_update(0, (const uint8_t*)slice_byte_buffer, number_of_written_bytes)) { + av_log(NULL, AV_LOG_ERROR, "Decoded frames with and without draw_horiz_band are not the same!\n"); + return -1; + } + av_frame_unref(fr); + } + } + +finish: + av_packet_free(&pkt); av_frame_free(&fr); - avcodec_close(ctx); avformat_close_input(&fmt_ctx); avcodec_free_context(&ctx); av_freep(&byte_buffer); diff --git a/tests/api/api-flac-test.c b/tests/api/api-flac-test.c index ae6a9316d..f3bfbc95b 100644 --- a/tests/api/api-flac-test.c +++ b/tests/api/api-flac-test.c @@ -108,15 +108,20 @@ static int init_decoder(AVCodec *dec, AVCodecContext **dec_ctx, static int run_test(AVCodec *enc, AVCodec *dec, AVCodecContext *enc_ctx, AVCodecContext *dec_ctx) { - AVPacket enc_pkt; + AVPacket *enc_pkt; AVFrame *in_frame, *out_frame; uint8_t *raw_in = NULL, *raw_out = NULL; int in_offset = 0, out_offset = 0; int result = 0; - int got_output = 0; int i = 0; int in_frame_bytes, out_frame_bytes; + enc_pkt = av_packet_alloc(); + if (!enc_pkt) { + av_log(NULL, AV_LOG_ERROR, "Can't allocate output packet\n"); + return AVERROR(ENOMEM); + } + in_frame = av_frame_alloc(); if (!in_frame) { av_log(NULL, AV_LOG_ERROR, "Can't allocate input frame\n"); @@ -150,9 +155,9 @@ static int run_test(AVCodec *enc, AVCodec *dec, AVCodecContext *enc_ctx, } for (i = 0; i < NUMBER_OF_AUDIO_FRAMES; i++) { - av_init_packet(&enc_pkt); - enc_pkt.data = NULL; - enc_pkt.size = 0; + result = av_frame_make_writable(in_frame); + if (result < 0) + return result; generate_raw_frame((uint16_t*)(in_frame->data[0]), i, enc_ctx->sample_rate, enc_ctx->channels, enc_ctx->frame_size); @@ -163,50 +168,63 @@ static int run_test(AVCodec *enc, AVCodec *dec, AVCodecContext *enc_ctx, } memcpy(raw_in + in_offset, in_frame->data[0], in_frame_bytes); in_offset += in_frame_bytes; - result = avcodec_encode_audio2(enc_ctx, &enc_pkt, in_frame, &got_output); + result = avcodec_send_frame(enc_ctx, in_frame); if (result < 0) { - av_log(NULL, AV_LOG_ERROR, "Error encoding audio frame\n"); + av_log(NULL, AV_LOG_ERROR, "Error submitting a frame for encoding\n"); return result; } - /* if we get an encoded packet, feed it straight to the decoder */ - if (got_output) { - result = avcodec_decode_audio4(dec_ctx, out_frame, &got_output, &enc_pkt); + while (result >= 0) { + result = avcodec_receive_packet(enc_ctx, enc_pkt); + if (result == AVERROR(EAGAIN)) + break; + else if (result < 0 && result != AVERROR_EOF) { + av_log(NULL, AV_LOG_ERROR, "Error encoding audio frame\n"); + return result; + } + + /* if we get an encoded packet, feed it straight to the decoder */ + result = avcodec_send_packet(dec_ctx, enc_pkt); + av_packet_unref(enc_pkt); if (result < 0) { + av_log(NULL, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); + return result; + } + + result = avcodec_receive_frame(dec_ctx, out_frame); + if (result == AVERROR(EAGAIN)) { + result = 0; + continue; + } else if (result == AVERROR(EOF)) { + result = 0; + break; + } else if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Error decoding audio packet\n"); return result; } - if (got_output) { - if (result != enc_pkt.size) { - av_log(NULL, AV_LOG_INFO, "Decoder consumed only part of a packet, it is allowed to do so -- need to update this test\n"); - return AVERROR_UNKNOWN; - } - - if (in_frame->nb_samples != out_frame->nb_samples) { - av_log(NULL, AV_LOG_ERROR, "Error frames before and after decoding has different number of samples\n"); - return AVERROR_UNKNOWN; - } - - if (in_frame->channel_layout != out_frame->channel_layout) { - av_log(NULL, AV_LOG_ERROR, "Error frames before and after decoding has different channel layout\n"); - return AVERROR_UNKNOWN; - } - - if (in_frame->format != out_frame->format) { - av_log(NULL, AV_LOG_ERROR, "Error frames before and after decoding has different sample format\n"); - return AVERROR_UNKNOWN; - } - out_frame_bytes = out_frame->nb_samples * out_frame->channels * sizeof(uint16_t); - if (out_frame_bytes > out_frame->linesize[0]) { - av_log(NULL, AV_LOG_ERROR, "Incorrect value of output frame linesize\n"); - return 1; - } - memcpy(raw_out + out_offset, out_frame->data[0], out_frame_bytes); - out_offset += out_frame_bytes; + if (in_frame->nb_samples != out_frame->nb_samples) { + av_log(NULL, AV_LOG_ERROR, "Error frames before and after decoding has different number of samples\n"); + return AVERROR_UNKNOWN; } + + if (in_frame->channel_layout != out_frame->channel_layout) { + av_log(NULL, AV_LOG_ERROR, "Error frames before and after decoding has different channel layout\n"); + return AVERROR_UNKNOWN; + } + + if (in_frame->format != out_frame->format) { + av_log(NULL, AV_LOG_ERROR, "Error frames before and after decoding has different sample format\n"); + return AVERROR_UNKNOWN; + } + out_frame_bytes = out_frame->nb_samples * out_frame->channels * sizeof(uint16_t); + if (out_frame_bytes > out_frame->linesize[0]) { + av_log(NULL, AV_LOG_ERROR, "Incorrect value of output frame linesize\n"); + return 1; + } + memcpy(raw_out + out_offset, out_frame->data[0], out_frame_bytes); + out_offset += out_frame_bytes; } - av_packet_unref(&enc_pkt); } if (memcmp(raw_in, raw_out, out_frame_bytes * NUMBER_OF_AUDIO_FRAMES) != 0) { @@ -218,25 +236,12 @@ static int run_test(AVCodec *enc, AVCodec *dec, AVCodecContext *enc_ctx, av_freep(&raw_in); av_freep(&raw_out); + av_packet_free(&enc_pkt); av_frame_free(&in_frame); av_frame_free(&out_frame); return 0; } -static int close_encoder(AVCodecContext **enc_ctx) -{ - avcodec_close(*enc_ctx); - av_freep(enc_ctx); - return 0; -} - -static int close_decoder(AVCodecContext **dec_ctx) -{ - avcodec_close(*dec_ctx); - av_freep(dec_ctx); - return 0; -} - int main(void) { AVCodec *enc = NULL, *dec = NULL; @@ -265,8 +270,8 @@ int main(void) return 1; if (run_test(enc, dec, enc_ctx, dec_ctx) != 0) return 1; - close_encoder(&enc_ctx); - close_decoder(&dec_ctx); + avcodec_free_context(&enc_ctx); + avcodec_free_context(&dec_ctx); } } diff --git a/tests/api/api-h264-test.c b/tests/api/api-h264-test.c index 60a3ae5ef..04bdfbc9d 100644 --- a/tests/api/api-h264-test.c +++ b/tests/api/api-h264-test.c @@ -37,15 +37,13 @@ static int video_decode_example(const char *input_filename) AVCodecParameters *origin_par = NULL; AVFrame *fr = NULL; uint8_t *byte_buffer = NULL; - AVPacket pkt; + AVPacket *pkt; AVFormatContext *fmt_ctx = NULL; int number_of_written_bytes; int video_stream; - int got_frame = 0; int byte_buffer_size; int i = 0; int result; - int end_of_stream = 0; result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL); if (result < 0) { @@ -97,6 +95,12 @@ static int video_decode_example(const char *input_filename) return AVERROR(ENOMEM); } + pkt = av_packet_alloc(); + if (!pkt) { + av_log(NULL, AV_LOG_ERROR, "Cannot allocate packet\n"); + return AVERROR(ENOMEM); + } + byte_buffer_size = av_image_get_buffer_size(ctx->pix_fmt, ctx->width, ctx->height, 16); byte_buffer = av_malloc(byte_buffer_size); if (!byte_buffer) { @@ -106,45 +110,61 @@ static int video_decode_example(const char *input_filename) printf("#tb %d: %d/%d\n", video_stream, fmt_ctx->streams[video_stream]->time_base.num, fmt_ctx->streams[video_stream]->time_base.den); i = 0; - av_init_packet(&pkt); - do { - if (!end_of_stream) - if (av_read_frame(fmt_ctx, &pkt) < 0) - end_of_stream = 1; - if (end_of_stream) { - pkt.data = NULL; - pkt.size = 0; + + result = 0; + while (result >= 0) { + result = av_read_frame(fmt_ctx, pkt); + if (result >= 0 && pkt->stream_index != video_stream) { + av_packet_unref(pkt); + continue; } - if (pkt.stream_index == video_stream || end_of_stream) { - got_frame = 0; - if (pkt.pts == AV_NOPTS_VALUE) - pkt.pts = pkt.dts = i; - result = avcodec_decode_video2(ctx, fr, &got_frame, &pkt); - if (result < 0) { + + if (result < 0) + result = avcodec_send_packet(ctx, NULL); + else { + if (pkt->pts == AV_NOPTS_VALUE) + pkt->pts = pkt->dts = i; + result = avcodec_send_packet(ctx, pkt); + } + av_packet_unref(pkt); + + if (result < 0) { + av_log(NULL, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); + return result; + } + + while (result >= 0) { + result = avcodec_receive_frame(ctx, fr); + if (result == AVERROR_EOF) + goto finish; + else if (result == AVERROR(EAGAIN)) { + result = 0; + break; + } else if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n"); return result; } - if (got_frame) { - number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size, - (const uint8_t* const *)fr->data, (const int*) fr->linesize, - ctx->pix_fmt, ctx->width, ctx->height, 1); - if (number_of_written_bytes < 0) { - av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n"); - return number_of_written_bytes; - } - printf("%d, %s, %s, %8"PRId64", %8d, 0x%08lx\n", video_stream, - av_ts2str(fr->pts), av_ts2str(fr->pkt_dts), fr->pkt_duration, - number_of_written_bytes, av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes)); + + number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size, + (const uint8_t* const *)fr->data, (const int*) fr->linesize, + ctx->pix_fmt, ctx->width, ctx->height, 1); + if (number_of_written_bytes < 0) { + av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n"); + av_frame_unref(fr); + return number_of_written_bytes; } - av_packet_unref(&pkt); - av_init_packet(&pkt); + printf("%d, %s, %s, %8"PRId64", %8d, 0x%08lx\n", video_stream, + av_ts2str(fr->pts), av_ts2str(fr->pkt_dts), fr->pkt_duration, + number_of_written_bytes, av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes)); + + av_frame_unref(fr); } i++; - } while (!end_of_stream || got_frame); + } - av_packet_unref(&pkt); +finish: + av_packet_free(&pkt); av_frame_free(&fr); - avcodec_close(ctx); avformat_close_input(&fmt_ctx); avcodec_free_context(&ctx); av_freep(&byte_buffer); diff --git a/tests/api/api-seek-test.c b/tests/api/api-seek-test.c index d0531a2f7..bb9f5c89b 100644 --- a/tests/api/api-seek-test.c +++ b/tests/api/api-seek-test.c @@ -73,16 +73,14 @@ static int compare_crc_in_array(uint32_t crc, int64_t pts) } static int compute_crc_of_packets(AVFormatContext *fmt_ctx, int video_stream, - AVCodecContext *ctx, AVFrame *fr, uint64_t ts_start, uint64_t ts_end, int no_seeking) + AVCodecContext *ctx, AVPacket *pkt, AVFrame *fr, + uint64_t ts_start, uint64_t ts_end, int no_seeking) { int number_of_written_bytes; - int got_frame = 0; int result; - int end_of_stream = 0; int byte_buffer_size; uint8_t *byte_buffer; uint32_t crc; - AVPacket pkt; byte_buffer_size = av_image_get_buffer_size(ctx->pix_fmt, ctx->width, ctx->height, 16); byte_buffer = av_malloc(byte_buffer_size); @@ -101,53 +99,66 @@ static int compute_crc_of_packets(AVFormatContext *fmt_ctx, int video_stream, avcodec_flush_buffers(ctx); } - av_init_packet(&pkt); do { - if (!end_of_stream) - if (av_read_frame(fmt_ctx, &pkt) < 0) - end_of_stream = 1; - if (end_of_stream) { - pkt.data = NULL; - pkt.size = 0; + result = av_read_frame(fmt_ctx, pkt); + if (result >= 0 && pkt->stream_index != video_stream) { + av_packet_unref(pkt); + continue; } - if (pkt.stream_index == video_stream || end_of_stream) { - got_frame = 0; - if ((pkt.pts == AV_NOPTS_VALUE) && (!end_of_stream)) { + + if (result < 0) + result = avcodec_send_packet(ctx, NULL); + else { + if (pkt->pts == AV_NOPTS_VALUE) { av_log(NULL, AV_LOG_ERROR, "Error: frames doesn't have pts values\n"); return -1; } - result = avcodec_decode_video2(ctx, fr, &got_frame, &pkt); - if (result < 0) { + result = avcodec_send_packet(ctx, pkt); + } + + av_packet_unref(pkt); + + if (result < 0) { + av_log(NULL, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); + return result; + } + + while (result >= 0) { + result = avcodec_receive_frame(ctx, fr); + if (result == AVERROR_EOF) + goto finish; + else if (result == AVERROR(EAGAIN)) { + result = 0; + break; + } else if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n"); return result; } - if (got_frame) { - number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size, - (const uint8_t* const *)fr->data, (const int*) fr->linesize, - ctx->pix_fmt, ctx->width, ctx->height, 1); - if (number_of_written_bytes < 0) { - av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n"); - return number_of_written_bytes; - } - if ((!no_seeking) && (fr->pts > ts_end)) - break; - crc = av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes); - printf("%10"PRId64", 0x%08"PRIx32"\n", fr->pts, crc); - if (no_seeking) { - if (add_crc_to_array(crc, fr->pts) < 0) - return -1; - } - else { - if (compare_crc_in_array(crc, fr->pts) < 0) - return -1; - } - } - } - av_packet_unref(&pkt); - av_init_packet(&pkt); - } while ((!end_of_stream || got_frame) && (no_seeking || (fr->pts + fr->pkt_duration <= ts_end))); - av_packet_unref(&pkt); + number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size, + (const uint8_t* const *)fr->data, (const int*) fr->linesize, + ctx->pix_fmt, ctx->width, ctx->height, 1); + if (number_of_written_bytes < 0) { + av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n"); + return number_of_written_bytes; + } + if ((!no_seeking) && (fr->pts > ts_end)) + break; + crc = av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes); + printf("%10"PRId64", 0x%08"PRIx32"\n", fr->pts, crc); + if (no_seeking) { + if (add_crc_to_array(crc, fr->pts) < 0) + return -1; + } + else { + if (compare_crc_in_array(crc, fr->pts) < 0) + return -1; + } + av_frame_unref(fr); + } + } while (result >= 0 && (no_seeking || (fr->pts + fr->pkt_duration <= ts_end))); + +finish: av_freep(&byte_buffer); return 0; @@ -176,6 +187,7 @@ static int seek_test(const char *input_filename, const char *start, const char * AVCodec *codec = NULL; AVCodecContext *ctx= NULL; AVCodecParameters *origin_par = NULL; + AVPacket *pkt = NULL; AVFrame *fr = NULL; AVFormatContext *fmt_ctx = NULL; int video_stream; @@ -250,13 +262,20 @@ static int seek_test(const char *input_filename, const char *start, const char * goto end; } - result = compute_crc_of_packets(fmt_ctx, video_stream, ctx, fr, 0, 0, 1); + pkt = av_packet_alloc(); + if (!pkt) { + av_log(NULL, AV_LOG_ERROR, "Cannot allocate packet\n"); + result = AVERROR(ENOMEM); + goto end; + } + + result = compute_crc_of_packets(fmt_ctx, video_stream, ctx, pkt, fr, 0, 0, 1); if (result != 0) goto end; for (i = start_ts; i < end_ts; i += 100) { for (j = i + 100; j < end_ts; j += 100) { - result = compute_crc_of_packets(fmt_ctx, video_stream, ctx, fr, i, j, 0); + result = compute_crc_of_packets(fmt_ctx, video_stream, ctx, pkt, fr, i, j, 0); if (result != 0) break; } @@ -265,8 +284,8 @@ static int seek_test(const char *input_filename, const char *start, const char * end: av_freep(&crc_array); av_freep(&pts_array); + av_packet_free(&pkt); av_frame_free(&fr); - avcodec_close(ctx); avformat_close_input(&fmt_ctx); avcodec_free_context(&ctx); return result; diff --git a/tests/audiomatch.c b/tests/audiomatch.c index d44c4070e..56a60bdec 100644 --- a/tests/audiomatch.c +++ b/tests/audiomatch.c @@ -24,6 +24,7 @@ #define FFMIN(a,b) ((a) > (b) ? (b) : (a)) #define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) static int64_t fsize(FILE *f) { int64_t end, pos = ftell(f); @@ -81,9 +82,9 @@ int main(int argc, char **argv) { signal = malloc(siglen * sizeof(*signal)); if (fread(data , 1, datlen, f[0]) != datlen) - return 1; + goto read_fail; if (fread(signal, 1, siglen, f[1]) != siglen) - return 1; + goto read_fail; datlen /= 2; siglen /= 2; @@ -101,14 +102,21 @@ int main(int argc, char **argv) { int j = pos + i; c += signal[i] * data[j]; } - if (fabs(c) > sigamp * 0.94) - maxshift = FFMIN(maxshift, fabs(pos)+32); - if (fabs(c) > fabs(bestc)) { + if (FFABS(c) > sigamp * 0.94) + maxshift = FFMIN(maxshift, FFABS(pos)+32); + if (FFABS(c) > FFABS(bestc)) { bestc = c; bestpos = pos; } } printf("presig: %d postsig:%d c:%7.4f lenerr:%d\n", bestpos, datlen - siglen - bestpos, bestc / sigamp, datlen - siglen); + free(data); + free(signal); return 0; + +read_fail: + free(data); + free(signal); + return 1; } diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 9e9569777..1827a4e13 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -24,7 +24,7 @@ AVCODECOBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuvdsp.o AVCODECOBJS-$(CONFIG_JPEG2000_DECODER) += jpeg2000dsp.o AVCODECOBJS-$(CONFIG_OPUS_DECODER) += opusdsp.o AVCODECOBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o -AVCODECOBJS-$(CONFIG_HEVC_DECODER) += hevc_add_res.o hevc_idct.o hevc_sao.o +AVCODECOBJS-$(CONFIG_HEVC_DECODER) += hevc_add_res.o hevc_idct.o hevc_sao.o hevc_pel.o AVCODECOBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodsp.o AVCODECOBJS-$(CONFIG_V210_DECODER) += v210dec.o AVCODECOBJS-$(CONFIG_V210_ENCODER) += v210enc.o diff --git a/tests/checkasm/aacpsdsp.c b/tests/checkasm/aacpsdsp.c index 2ceef4341..359b1e9a0 100644 --- a/tests/checkasm/aacpsdsp.c +++ b/tests/checkasm/aacpsdsp.c @@ -18,6 +18,7 @@ #include "libavcodec/aacpsdsp.h" #include "libavutil/intfloat.h" +#include "libavutil/mem_internal.h" #include "checkasm.h" diff --git a/tests/checkasm/af_afir.c b/tests/checkasm/af_afir.c index 8d1f81546..b8a845db8 100644 --- a/tests/checkasm/af_afir.c +++ b/tests/checkasm/af_afir.c @@ -23,6 +23,7 @@ #include "libavfilter/af_afir.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #include "checkasm.h" #define LEN 256 diff --git a/tests/checkasm/alacdsp.c b/tests/checkasm/alacdsp.c index cbf03f82e..b822c725c 100644 --- a/tests/checkasm/alacdsp.c +++ b/tests/checkasm/alacdsp.c @@ -24,6 +24,7 @@ #include "libavcodec/mathops.h" #include "libavutil/common.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" #define BUF_SIZE 256 #define MAX_CHANNELS 2 diff --git a/tests/checkasm/audiodsp.c b/tests/checkasm/audiodsp.c index 7c4e16e40..d3a560429 100644 --- a/tests/checkasm/audiodsp.c +++ b/tests/checkasm/audiodsp.c @@ -25,6 +25,7 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "checkasm.h" diff --git a/tests/checkasm/blockdsp.c b/tests/checkasm/blockdsp.c index c753506b3..9e6ce9d7d 100644 --- a/tests/checkasm/blockdsp.c +++ b/tests/checkasm/blockdsp.c @@ -27,6 +27,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define randomize_buffers(size) \ do { \ diff --git a/tests/checkasm/bswapdsp.c b/tests/checkasm/bswapdsp.c index 5f7555037..d789e90de 100644 --- a/tests/checkasm/bswapdsp.c +++ b/tests/checkasm/bswapdsp.c @@ -24,6 +24,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define BUF_SIZE 512 diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 899f68bb3..8338e8ff5 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -116,6 +116,16 @@ static const struct { #if CONFIG_HEVC_DECODER { "hevc_add_res", checkasm_check_hevc_add_res }, { "hevc_idct", checkasm_check_hevc_idct }, + { "hevc_qpel", checkasm_check_hevc_qpel }, + { "hevc_qpel_uni", checkasm_check_hevc_qpel_uni }, + { "hevc_qpel_uni_w", checkasm_check_hevc_qpel_uni_w }, + { "hevc_qpel_bi", checkasm_check_hevc_qpel_bi }, + { "hevc_qpel_bi_w", checkasm_check_hevc_qpel_bi_w }, + { "hevc_epel", checkasm_check_hevc_epel }, + { "hevc_epel_uni", checkasm_check_hevc_epel_uni }, + { "hevc_epel_uni_w", checkasm_check_hevc_epel_uni_w }, + { "hevc_epel_bi", checkasm_check_hevc_epel_bi }, + { "hevc_epel_bi_w", checkasm_check_hevc_epel_bi_w }, { "hevc_sao", checkasm_check_hevc_sao }, #endif #if CONFIG_HUFFYUV_DECODER @@ -213,6 +223,9 @@ static const struct { { "ALTIVEC", "altivec", AV_CPU_FLAG_ALTIVEC }, { "VSX", "vsx", AV_CPU_FLAG_VSX }, { "POWER8", "power8", AV_CPU_FLAG_POWER8 }, +#elif ARCH_MIPS + { "MMI", "mmi", AV_CPU_FLAG_MMI }, + { "MSA", "msa", AV_CPU_FLAG_MSA }, #elif ARCH_X86 { "MMX", "mmx", AV_CPU_FLAG_MMX|AV_CPU_FLAG_CMOV }, { "MMXEXT", "mmxext", AV_CPU_FLAG_MMXEXT }, diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 0190bc912..ef6645e3a 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -58,6 +58,16 @@ void checkasm_check_h264pred(void); void checkasm_check_h264qpel(void); void checkasm_check_hevc_add_res(void); void checkasm_check_hevc_idct(void); +void checkasm_check_hevc_qpel(void); +void checkasm_check_hevc_qpel_uni(void); +void checkasm_check_hevc_qpel_uni_w(void); +void checkasm_check_hevc_qpel_bi(void); +void checkasm_check_hevc_qpel_bi_w(void); +void checkasm_check_hevc_epel(void); +void checkasm_check_hevc_epel_uni(void); +void checkasm_check_hevc_epel_uni_w(void); +void checkasm_check_hevc_epel_bi(void); +void checkasm_check_hevc_epel_bi_w(void); void checkasm_check_hevc_sao(void); void checkasm_check_huffyuvdsp(void); void checkasm_check_jpeg2000dsp(void); diff --git a/tests/checkasm/exrdsp.c b/tests/checkasm/exrdsp.c index 754a079f8..2a5febb9d 100644 --- a/tests/checkasm/exrdsp.c +++ b/tests/checkasm/exrdsp.c @@ -24,6 +24,7 @@ #include "libavcodec/avcodec.h" #include "libavcodec/exrdsp.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define BUF_SIZE 5120 #define PADDED_BUF_SIZE BUF_SIZE+AV_INPUT_BUFFER_PADDING_SIZE*2 diff --git a/tests/checkasm/fixed_dsp.c b/tests/checkasm/fixed_dsp.c index fa11f2e23..4e610a148 100644 --- a/tests/checkasm/fixed_dsp.c +++ b/tests/checkasm/fixed_dsp.c @@ -23,6 +23,7 @@ #include "libavutil/fixed_dsp.h" #include "libavutil/internal.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #define BUF_SIZE 256 diff --git a/tests/checkasm/flacdsp.c b/tests/checkasm/flacdsp.c index dccb54d67..6cd8ac50e 100644 --- a/tests/checkasm/flacdsp.c +++ b/tests/checkasm/flacdsp.c @@ -24,6 +24,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define BUF_SIZE 256 #define MAX_CHANNELS 8 diff --git a/tests/checkasm/float_dsp.c b/tests/checkasm/float_dsp.c index a1616a61a..1437d8ee9 100644 --- a/tests/checkasm/float_dsp.c +++ b/tests/checkasm/float_dsp.c @@ -23,6 +23,8 @@ #include "libavutil/float_dsp.h" #include "libavutil/internal.h" +#include "libavutil/mem_internal.h" + #include "checkasm.h" #define LEN 256 diff --git a/tests/checkasm/fmtconvert.c b/tests/checkasm/fmtconvert.c index 50ad3ca2e..aef74479f 100644 --- a/tests/checkasm/fmtconvert.c +++ b/tests/checkasm/fmtconvert.c @@ -24,6 +24,8 @@ #include "libavutil/internal.h" #include "libavutil/common.h" +#include "libavutil/mem_internal.h" + #include "libavcodec/fmtconvert.h" #include "checkasm.h" diff --git a/tests/checkasm/h264dsp.c b/tests/checkasm/h264dsp.c index 697520574..739245295 100644 --- a/tests/checkasm/h264dsp.c +++ b/tests/checkasm/h264dsp.c @@ -26,6 +26,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" static const uint32_t pixel_mask[3] = { 0xffffffff, 0x01ff01ff, 0x03ff03ff }; static const uint32_t pixel_mask_lf[3] = { 0xff0fff0f, 0x01ff000f, 0x03ff000f }; diff --git a/tests/checkasm/h264pred.c b/tests/checkasm/h264pred.c index 59dcb2f42..a3077f694 100644 --- a/tests/checkasm/h264pred.c +++ b/tests/checkasm/h264pred.c @@ -25,6 +25,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" static const int codec_ids[4] = { AV_CODEC_ID_H264, AV_CODEC_ID_VP8, AV_CODEC_ID_RV40, AV_CODEC_ID_SVQ3 }; diff --git a/tests/checkasm/h264qpel.c b/tests/checkasm/h264qpel.c index ba069f125..e47d65992 100644 --- a/tests/checkasm/h264qpel.c +++ b/tests/checkasm/h264qpel.c @@ -24,6 +24,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" static const uint32_t pixel_mask[3] = { 0xffffffff, 0x01ff01ff, 0x03ff03ff }; diff --git a/tests/checkasm/hevc_add_res.c b/tests/checkasm/hevc_add_res.c index 0a3bcbb70..0c896adac 100644 --- a/tests/checkasm/hevc_add_res.c +++ b/tests/checkasm/hevc_add_res.c @@ -21,6 +21,7 @@ #include #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "libavcodec/hevcdsp.h" diff --git a/tests/checkasm/hevc_idct.c b/tests/checkasm/hevc_idct.c index c20111c2d..338b8a23e 100644 --- a/tests/checkasm/hevc_idct.c +++ b/tests/checkasm/hevc_idct.c @@ -21,6 +21,7 @@ #include #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "libavcodec/hevcdsp.h" diff --git a/tests/checkasm/hevc_pel.c b/tests/checkasm/hevc_pel.c new file mode 100644 index 000000000..4d1545e46 --- /dev/null +++ b/tests/checkasm/hevc_pel.c @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2015 Henrik Gramner + * Copyright (c) 2021 Josh Dekker + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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 "checkasm.h" +#include "libavcodec/hevcdsp.h" +#include "libavutil/common.h" +#include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" + +static const uint32_t pixel_mask[] = { 0xffffffff, 0x01ff01ff, 0x03ff03ff, 0x07ff07ff, 0x0fff0fff }; +static const uint32_t pixel_mask16[] = { 0x00ff00ff, 0x01ff01ff, 0x03ff03ff, 0x07ff07ff, 0x0fff0fff }; +static const int sizes[] = { -1, 4, 6, 8, 12, 16, 24, 32, 48, 64 }; +static const int weights[] = { 0, 128, 255, -1 }; +static const int denoms[] = {0, 7, 12, -1 }; +static const int offsets[] = {0, 255, -1 }; + +#define SIZEOF_PIXEL ((bit_depth + 7) / 8) +#define BUF_SIZE (2 * MAX_PB_SIZE * (2 * 4 + MAX_PB_SIZE)) + +#define randomize_buffers() \ + do { \ + uint32_t mask = pixel_mask[bit_depth - 8]; \ + int k; \ + for (k = 0; k < BUF_SIZE; k += 4) { \ + uint32_t r = rnd() & mask; \ + AV_WN32A(buf0 + k, r); \ + AV_WN32A(buf1 + k, r); \ + r = rnd(); \ + AV_WN32A(dst0 + k, r); \ + AV_WN32A(dst1 + k, r); \ + } \ + } while (0) + +#define randomize_buffers_ref() \ + randomize_buffers(); \ + do { \ + uint32_t mask = pixel_mask16[bit_depth - 8]; \ + int k; \ + for (k = 0; k < BUF_SIZE; k += 2) { \ + uint32_t r = rnd() & mask; \ + AV_WN32A(ref0 + k, r); \ + AV_WN32A(ref1 + k, r); \ + } \ + } while (0) + +#define src0 (buf0 + 2 * 4 * MAX_PB_SIZE) /* hevc qpel functions read data from negative src pointer offsets */ +#define src1 (buf1 + 2 * 4 * MAX_PB_SIZE) + +void checkasm_check_hevc_qpel(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j, row; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, int16_t *dst, uint8_t *src, ptrdiff_t srcstride, + int height, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_pixels"; break; // 0 0 + case 1: type = "qpel_h"; break; // 0 1 + case 2: type = "qpel_v"; break; // 1 0 + case 3: type = "qpel_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_qpel[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + int16_t *dstw0 = (int16_t *) dst0, *dstw1 = (int16_t *) dst1; + randomize_buffers(); + call_ref(dstw0, src0, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + call_new(dstw1, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + for (row = 0; row < size[sizes]; row++) { + if (memcmp(dstw0 + row * MAX_PB_SIZE, dstw1 + row * MAX_PB_SIZE, sizes[size] * SIZEOF_PIXEL)) + fail(); + } + bench_new(dstw1, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + } + } + } + } + } + report("qpel"); +} + +void checkasm_check_hevc_qpel_uni(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int height, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_uni_pixels"; break; // 0 0 + case 1: type = "qpel_uni_h"; break; // 0 1 + case 2: type = "qpel_uni_v"; break; // 1 0 + case 3: type = "qpel_uni_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_qpel_uni[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + randomize_buffers(); + call_ref(dst0, sizes[size] * SIZEOF_PIXEL, src0, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + call_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + if (memcmp(dst0, dst1, sizes[size] * sizes[size] * SIZEOF_PIXEL)) + fail(); + bench_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + } + } + } + } + } + report("qpel_uni"); +} + +void checkasm_check_hevc_qpel_uni_w(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j; + const int *denom, *wx, *ox; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_uni_w_pixels"; break; // 0 0 + case 1: type = "qpel_uni_w_h"; break; // 0 1 + case 2: type = "qpel_uni_w_v"; break; // 1 0 + case 3: type = "qpel_uni_w_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_qpel_uni_w[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + for (denom = denoms; *denom >= 0; denom++) { + for (wx = weights; *wx >= 0; wx++) { + for (ox = offsets; *ox >= 0; ox++) { + randomize_buffers(); + call_ref(dst0, sizes[size] * SIZEOF_PIXEL, src0, sizes[size] * SIZEOF_PIXEL, sizes[size], *denom, *wx, *ox, i, j, sizes[size]); + call_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], *denom, *wx, *ox, i, j, sizes[size]); + if (memcmp(dst0, dst1, sizes[size] * sizes[size] * SIZEOF_PIXEL)) + fail(); + bench_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], *denom, *wx, *ox, i, j, sizes[size]); + } + } + } + } + } + } + } + } + report("qpel_uni_w"); +} + +void checkasm_check_hevc_qpel_bi(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + LOCAL_ALIGNED_32(int16_t, ref0, [BUF_SIZE]); + LOCAL_ALIGNED_32(int16_t, ref1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int16_t *src2, + int height, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_bi_pixels"; break; // 0 0 + case 1: type = "qpel_bi_h"; break; // 0 1 + case 2: type = "qpel_bi_v"; break; // 1 0 + case 3: type = "qpel_bi_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_qpel_bi[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + randomize_buffers_ref(); + call_ref(dst0, sizes[size] * SIZEOF_PIXEL, src0, sizes[size] * SIZEOF_PIXEL, ref0, sizes[size], i, j, sizes[size]); + call_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, ref1, sizes[size], i, j, sizes[size]); + if (memcmp(dst0, dst1, sizes[size] * sizes[size] * SIZEOF_PIXEL)) + fail(); + bench_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, ref1, sizes[size], i, j, sizes[size]); + } + } + } + } + } + report("qpel_bi"); +} + +void checkasm_check_hevc_qpel_bi_w(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + LOCAL_ALIGNED_32(int16_t, ref0, [BUF_SIZE]); + LOCAL_ALIGNED_32(int16_t, ref1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j; + const int *denom, *wx, *ox; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int16_t *src2, + int height, int denom, int wx0, int wx1, + int ox0, int ox1, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_bi_w_pixels"; break; // 0 0 + case 1: type = "qpel_bi_w_h"; break; // 0 1 + case 2: type = "qpel_bi_w_v"; break; // 1 0 + case 3: type = "qpel_bi_w_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_qpel_bi_w[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + for (denom = denoms; *denom >= 0; denom++) { + for (wx = weights; *wx >= 0; wx++) { + for (ox = offsets; *ox >= 0; ox++) { + randomize_buffers_ref(); + call_ref(dst0, sizes[size] * SIZEOF_PIXEL, src0, sizes[size] * SIZEOF_PIXEL, ref0, sizes[size], *denom, *wx, *wx, *ox, *ox, i, j, sizes[size]); + call_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, ref1, sizes[size], *denom, *wx, *wx, *ox, *ox, i, j, sizes[size]); + if (memcmp(dst0, dst1, sizes[size] * sizes[size] * SIZEOF_PIXEL)) + fail(); + bench_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, ref1, sizes[size], *denom, *wx, *wx, *ox, *ox, i, j, sizes[size]); + } + } + } + } + } + } + } + } + report("qpel_bi_w"); +} + +void checkasm_check_hevc_epel(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j, row; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, int16_t *dst, uint8_t *src, ptrdiff_t srcstride, + int height, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_pixels"; break; // 0 0 + case 1: type = "epel_h"; break; // 0 1 + case 2: type = "epel_v"; break; // 1 0 + case 3: type = "epel_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_epel[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + int16_t *dstw0 = (int16_t *) dst0, *dstw1 = (int16_t *) dst1; + randomize_buffers(); + call_ref(dstw0, src0, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + call_new(dstw1, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + for (row = 0; row < size[sizes]; row++) { + if (memcmp(dstw0 + row * MAX_PB_SIZE, dstw1 + row * MAX_PB_SIZE, sizes[size] * SIZEOF_PIXEL)) + fail(); + } + bench_new(dstw1, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + } + } + } + } + } + report("epel"); +} + +void checkasm_check_hevc_epel_uni(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int height, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_uni_pixels"; break; // 0 0 + case 1: type = "epel_uni_h"; break; // 0 1 + case 2: type = "epel_uni_v"; break; // 1 0 + case 3: type = "epel_uni_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_epel_uni[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + randomize_buffers(); + call_ref(dst0, sizes[size] * SIZEOF_PIXEL, src0, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + call_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + if (memcmp(dst0, dst1, sizes[size] * sizes[size] * SIZEOF_PIXEL)) + fail(); + bench_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], i, j, sizes[size]); + } + } + } + } + } + report("epel_uni"); +} + +void checkasm_check_hevc_epel_uni_w(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j; + const int *denom, *wx, *ox; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_uni_w_pixels"; break; // 0 0 + case 1: type = "epel_uni_w_h"; break; // 0 1 + case 2: type = "epel_uni_w_v"; break; // 1 0 + case 3: type = "epel_uni_w_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_epel_uni_w[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + for (denom = denoms; *denom >= 0; denom++) { + for (wx = weights; *wx >= 0; wx++) { + for (ox = offsets; *ox >= 0; ox++) { + randomize_buffers(); + call_ref(dst0, sizes[size] * SIZEOF_PIXEL, src0, sizes[size] * SIZEOF_PIXEL, sizes[size], *denom, *wx, *ox, i, j, sizes[size]); + call_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], *denom, *wx, *ox, i, j, sizes[size]); + if (memcmp(dst0, dst1, sizes[size] * sizes[size] * SIZEOF_PIXEL)) + fail(); + bench_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, sizes[size], *denom, *wx, *ox, i, j, sizes[size]); + } + } + } + } + } + } + } + } + report("epel_uni_w"); +} + +void checkasm_check_hevc_epel_bi(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + LOCAL_ALIGNED_32(int16_t, ref0, [BUF_SIZE]); + LOCAL_ALIGNED_32(int16_t, ref1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int16_t *src2, + int height, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_bi_pixels"; break; // 0 0 + case 1: type = "epel_bi_h"; break; // 0 1 + case 2: type = "epel_bi_v"; break; // 1 0 + case 3: type = "epel_bi_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_epel_bi[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + randomize_buffers_ref(); + call_ref(dst0, sizes[size] * SIZEOF_PIXEL, src0, sizes[size] * SIZEOF_PIXEL, ref0, sizes[size], i, j, sizes[size]); + call_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, ref1, sizes[size], i, j, sizes[size]); + if (memcmp(dst0, dst1, sizes[size] * sizes[size] * SIZEOF_PIXEL)) + fail(); + bench_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, ref1, sizes[size], i, j, sizes[size]); + } + } + } + } + } + report("epel_bi"); +} + +void checkasm_check_hevc_epel_bi_w(void) +{ + LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst0, [BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst1, [BUF_SIZE]); + LOCAL_ALIGNED_32(int16_t, ref0, [BUF_SIZE]); + LOCAL_ALIGNED_32(int16_t, ref1, [BUF_SIZE]); + + HEVCDSPContext h; + int size, bit_depth, i, j; + const int *denom, *wx, *ox; + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int16_t *src2, + int height, int denom, int wx0, int wx1, + int ox0, int ox1, intptr_t mx, intptr_t my, int width); + + for (bit_depth = 8; bit_depth <= 12; bit_depth++) { + ff_hevc_dsp_init(&h, bit_depth); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (size = 1; size < 10; size++) { + const char *type; + switch ((j << 1) | i) { + case 0: type = "pel_bi_w_pixels"; break; // 0 0 + case 1: type = "epel_bi_w_h"; break; // 0 1 + case 2: type = "epel_bi_w_v"; break; // 1 0 + case 3: type = "epel_bi_w_hv"; break; // 1 1 + } + + if (check_func(h.put_hevc_epel_bi_w[size][j][i], "put_hevc_%s%d_%d", type, sizes[size], bit_depth)) { + for (denom = denoms; *denom >= 0; denom++) { + for (wx = weights; *wx >= 0; wx++) { + for (ox = offsets; *ox >= 0; ox++) { + randomize_buffers_ref(); + call_ref(dst0, sizes[size] * SIZEOF_PIXEL, src0, sizes[size] * SIZEOF_PIXEL, ref0, sizes[size], *denom, *wx, *wx, *ox, *ox, i, j, sizes[size]); + call_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, ref1, sizes[size], *denom, *wx, *wx, *ox, *ox, i, j, sizes[size]); + if (memcmp(dst0, dst1, sizes[size] * sizes[size] * SIZEOF_PIXEL)) + fail(); + bench_new(dst1, sizes[size] * SIZEOF_PIXEL, src1, sizes[size] * SIZEOF_PIXEL, ref1, sizes[size], *denom, *wx, *wx, *ox, *ox, i, j, sizes[size]); + } + } + } + } + } + } + } + } + report("epel_bi_w"); +} diff --git a/tests/checkasm/hevc_sao.c b/tests/checkasm/hevc_sao.c index 8d0cf8077..6b750758e 100644 --- a/tests/checkasm/hevc_sao.c +++ b/tests/checkasm/hevc_sao.c @@ -21,6 +21,7 @@ #include #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "libavcodec/avcodec.h" diff --git a/tests/checkasm/jpeg2000dsp.c b/tests/checkasm/jpeg2000dsp.c index bce534dba..c9158ab3d 100644 --- a/tests/checkasm/jpeg2000dsp.c +++ b/tests/checkasm/jpeg2000dsp.c @@ -23,6 +23,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define BUF_SIZE 512 diff --git a/tests/checkasm/llviddspenc.c b/tests/checkasm/llviddspenc.c index 31eafd552..132f6d277 100644 --- a/tests/checkasm/llviddspenc.c +++ b/tests/checkasm/llviddspenc.c @@ -23,6 +23,7 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libavcodec/lossless_videoencdsp.h" diff --git a/tests/checkasm/opusdsp.c b/tests/checkasm/opusdsp.c index 828ecf9ce..34ee5a4ed 100644 --- a/tests/checkasm/opusdsp.c +++ b/tests/checkasm/opusdsp.c @@ -16,6 +16,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "libavutil/mem_internal.h" + #include "libavcodec/opusdsp.h" #include "checkasm.h" diff --git a/tests/checkasm/pixblockdsp.c b/tests/checkasm/pixblockdsp.c index 79ab156d4..9a7865aa5 100644 --- a/tests/checkasm/pixblockdsp.c +++ b/tests/checkasm/pixblockdsp.c @@ -24,6 +24,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define BUF_UNITS 8 #define BUF_SIZE (BUF_UNITS * 128 + 8 * BUF_UNITS) diff --git a/tests/checkasm/sbrdsp.c b/tests/checkasm/sbrdsp.c index 516b9f0ec..2fb14d5bf 100644 --- a/tests/checkasm/sbrdsp.c +++ b/tests/checkasm/sbrdsp.c @@ -16,6 +16,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "libavutil/mem_internal.h" + #include "libavcodec/sbrdsp.h" #include diff --git a/tests/checkasm/sw_rgb.c b/tests/checkasm/sw_rgb.c index e5aad20c6..c29b75d09 100644 --- a/tests/checkasm/sw_rgb.c +++ b/tests/checkasm/sw_rgb.c @@ -22,6 +22,7 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libswscale/rgb2rgb.h" diff --git a/tests/checkasm/sw_scale.c b/tests/checkasm/sw_scale.c index 9efa2b4de..3ac0f9082 100644 --- a/tests/checkasm/sw_scale.c +++ b/tests/checkasm/sw_scale.c @@ -22,6 +22,7 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "libavutil/mem.h" +#include "libavutil/mem_internal.h" #include "libswscale/swscale.h" #include "libswscale/swscale_internal.h" @@ -35,6 +36,105 @@ AV_WN32(buf + j, rnd()); \ } while (0) +// This reference function is the same approximate algorithm employed by the +// SIMD functions +static void ref_function(const int16_t *filter, int filterSize, + const int16_t **src, uint8_t *dest, int dstW, + const uint8_t *dither, int offset) +{ + int i, d; + d = ((filterSize - 1) * 8 + dither[0]) >> 4; + for ( i = 0; i < dstW; i++) { + int16_t val = d; + int j; + union { + int val; + int16_t v[2]; + } t; + for (j = 0; j < filterSize; j++){ + t.val = (int)src[j][i + offset] * (int)filter[j]; + val += t.v[1]; + } + dest[i]= av_clip_uint8(val>>3); + } +} + +static void check_yuv2yuvX(void) +{ + struct SwsContext *ctx; + int fsi, osi, isi, i, j; + int dstW; +#define LARGEST_FILTER 16 +#define FILTER_SIZES 4 + static const int filter_sizes[FILTER_SIZES] = {1, 4, 8, 16}; +#define LARGEST_INPUT_SIZE 512 +#define INPUT_SIZES 6 + static const int input_sizes[INPUT_SIZES] = {8, 24, 128, 144, 256, 512}; + + declare_func_emms(AV_CPU_FLAG_MMX, void, const int16_t *filter, + int filterSize, const int16_t **src, uint8_t *dest, + int dstW, const uint8_t *dither, int offset); + + const int16_t **src; + LOCAL_ALIGNED_8(int16_t, src_pixels, [LARGEST_FILTER * LARGEST_INPUT_SIZE]); + LOCAL_ALIGNED_8(int16_t, filter_coeff, [LARGEST_FILTER]); + LOCAL_ALIGNED_8(uint8_t, dst0, [LARGEST_INPUT_SIZE]); + LOCAL_ALIGNED_8(uint8_t, dst1, [LARGEST_INPUT_SIZE]); + LOCAL_ALIGNED_8(uint8_t, dither, [LARGEST_INPUT_SIZE]); + union VFilterData{ + const int16_t *src; + uint16_t coeff[8]; + } *vFilterData; + uint8_t d_val = rnd(); + memset(dither, d_val, LARGEST_INPUT_SIZE); + randomize_buffers((uint8_t*)src_pixels, LARGEST_FILTER * LARGEST_INPUT_SIZE * sizeof(int16_t)); + randomize_buffers((uint8_t*)filter_coeff, LARGEST_FILTER * sizeof(int16_t)); + ctx = sws_alloc_context(); + if (sws_init_context(ctx, NULL, NULL) < 0) + fail(); + + ff_getSwsFunc(ctx); + for(isi = 0; isi < INPUT_SIZES; ++isi){ + dstW = input_sizes[isi]; + for(osi = 0; osi < 64; osi += 16){ + for(fsi = 0; fsi < FILTER_SIZES; ++fsi){ + src = av_malloc(sizeof(int16_t*) * filter_sizes[fsi]); + vFilterData = av_malloc((filter_sizes[fsi] + 2) * sizeof(union VFilterData)); + memset(vFilterData, 0, (filter_sizes[fsi] + 2) * sizeof(union VFilterData)); + for(i = 0; i < filter_sizes[fsi]; ++i){ + src[i] = &src_pixels[i * LARGEST_INPUT_SIZE]; + vFilterData[i].src = src[i]; + for(j = 0; j < 4; ++j) + vFilterData[i].coeff[j + 4] = filter_coeff[i]; + } + if (check_func(ctx->yuv2planeX, "yuv2yuvX_%d_%d_%d", filter_sizes[fsi], osi, dstW)){ + memset(dst0, 0, LARGEST_INPUT_SIZE * sizeof(dst0[0])); + memset(dst1, 0, LARGEST_INPUT_SIZE * sizeof(dst1[0])); + + // The reference function is not the scalar function selected when mmx + // is deactivated as the SIMD functions do not give the same result as + // the scalar ones due to rounding. The SIMD functions are activated by + // the flag SWS_ACCURATE_RND + ref_function(&filter_coeff[0], filter_sizes[fsi], src, dst0, dstW - osi, dither, osi); + // There's no point in calling new for the reference function + if(ctx->use_mmx_vfilter){ + call_new((const int16_t*)vFilterData, filter_sizes[fsi], src, dst1, dstW - osi, dither, osi); + if (memcmp(dst0, dst1, LARGEST_INPUT_SIZE * sizeof(dst0[0]))) + fail(); + if(dstW == LARGEST_INPUT_SIZE) + bench_new((const int16_t*)vFilterData, filter_sizes[fsi], src, dst1, dstW - osi, dither, osi); + } + } + av_freep(&src); + av_freep(&vFilterData); + } + } + } + sws_freeContext(ctx); +#undef FILTER_SIZES +} + +#undef SRC_PIXELS #define SRC_PIXELS 128 static void check_hscale(void) @@ -131,4 +231,6 @@ void checkasm_check_sw_scale(void) { check_hscale(); report("hscale"); + check_yuv2yuvX(); + report("yuv2yuvX"); } diff --git a/tests/checkasm/synth_filter.c b/tests/checkasm/synth_filter.c index 87e32ebc0..9a0d746c9 100644 --- a/tests/checkasm/synth_filter.c +++ b/tests/checkasm/synth_filter.c @@ -25,6 +25,8 @@ #include "libavutil/internal.h" #include "libavutil/intfloat.h" +#include "libavutil/mem_internal.h" + #include "libavcodec/dcadata.h" #include "libavcodec/synth_filter.h" diff --git a/tests/checkasm/utvideodsp.c b/tests/checkasm/utvideodsp.c index 080b4287d..bdede6107 100644 --- a/tests/checkasm/utvideodsp.c +++ b/tests/checkasm/utvideodsp.c @@ -24,6 +24,7 @@ #include "libavcodec/avcodec.h" #include "libavcodec/utvideodsp.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define WIDTH 240 #define HEIGHT 120 diff --git a/tests/checkasm/v210enc.c b/tests/checkasm/v210enc.c index ed3677659..c3d5cc514 100644 --- a/tests/checkasm/v210enc.c +++ b/tests/checkasm/v210enc.c @@ -24,6 +24,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define BUF_SIZE 512 diff --git a/tests/checkasm/vf_colorspace.c b/tests/checkasm/vf_colorspace.c index 10b7b8392..31efa671f 100644 --- a/tests/checkasm/vf_colorspace.c +++ b/tests/checkasm/vf_colorspace.c @@ -24,6 +24,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define W 64 #define H 64 diff --git a/tests/checkasm/vf_eq.c b/tests/checkasm/vf_eq.c index 48dccddf7..1315b08f0 100644 --- a/tests/checkasm/vf_eq.c +++ b/tests/checkasm/vf_eq.c @@ -21,6 +21,7 @@ #include "libavfilter/avfilter.h" #include "libavfilter/vf_eq.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define WIDTH 256 #define HEIGHT 256 diff --git a/tests/checkasm/vf_gblur.c b/tests/checkasm/vf_gblur.c index 1d63fc22a..b9fe2f9a3 100644 --- a/tests/checkasm/vf_gblur.c +++ b/tests/checkasm/vf_gblur.c @@ -16,6 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include "checkasm.h" #include "libavfilter/gblur.h" @@ -33,34 +34,57 @@ tmp_buf[j] = (float)(rnd() & 0xFF); \ } while (0) +static void check_horiz_slice(float *dst_ref, float *dst_new) +{ + int steps = 2; + float nu = 0.101f; + float bscale = 1.112f; + + declare_func(void, float *dst, int w, int h, int steps, float nu, float bscale); + call_ref(dst_ref, WIDTH, HEIGHT, steps, nu, bscale); + call_new(dst_new, WIDTH, HEIGHT, steps, nu, bscale); + if (!float_near_abs_eps_array(dst_ref, dst_new, 0.01f, PIXELS)) { + fail(); + } + bench_new(dst_new, WIDTH, HEIGHT, 1, nu, bscale); +} + +static void check_postscale_slice(float *dst_ref, float *dst_new) +{ + float postscale = 0.0603f; + + declare_func(void, float *dst, int len, float postscale, float min, float max); + call_ref(dst_ref, PIXELS, postscale, -FLT_MAX, FLT_MAX); + call_new(dst_new, PIXELS, postscale, -FLT_MAX, FLT_MAX); + if (!float_near_abs_eps_array(dst_ref, dst_new, FLT_EPSILON, PIXELS)) { + fail(); + } + bench_new(dst_new, PIXELS, postscale, -FLT_MAX, FLT_MAX); +} + void checkasm_check_vf_gblur(void) { float *dst_ref = av_malloc(BUF_SIZE); float *dst_new = av_malloc(BUF_SIZE); - int w = WIDTH; - int h = HEIGHT; - int steps = 2; - float nu = 0.101f; - float bscale = 1.112f; GBlurContext s; - declare_func(void, float *dst, int w, int h, int steps, float nu, float bscale); - randomize_buffers(dst_ref, PIXELS); memcpy(dst_new, dst_ref, BUF_SIZE); ff_gblur_init(&s); if (check_func(s.horiz_slice, "horiz_slice")) { - call_ref(dst_ref, w, h, steps, nu, bscale); - call_new(dst_new, w, h, steps, nu, bscale); - - if (!float_near_abs_eps_array(dst_ref, dst_new, 0.01f, PIXELS)) { - fail(); - } - bench_new(dst_new, w, h, 1, nu, bscale); + check_horiz_slice(dst_ref, dst_new); } report("horiz_slice"); + + randomize_buffers(dst_ref, PIXELS); + memcpy(dst_new, dst_ref, BUF_SIZE); + if (check_func(s.postscale_slice, "postscale_slice")) { + check_postscale_slice(dst_ref, dst_new); + } + report("postscale_slice"); + av_freep(&dst_ref); av_freep(&dst_new); } diff --git a/tests/checkasm/vf_hflip.c b/tests/checkasm/vf_hflip.c index 6bb4d09d6..a3b6e613d 100644 --- a/tests/checkasm/vf_hflip.c +++ b/tests/checkasm/vf_hflip.c @@ -20,6 +20,7 @@ #include "checkasm.h" #include "libavfilter/hflip.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define WIDTH 256 #define WIDTH_PADDED 256 + 32 @@ -43,6 +44,7 @@ static void check_hflip(int step, const char * report_name){ declare_func(void, const uint8_t *src, uint8_t *dst, int w); + s.bayer_plus1 = 1; memset(src, 0, WIDTH_PADDED); memset(dst_ref, 0, WIDTH_PADDED); memset(dst_new, 0, WIDTH_PADDED); diff --git a/tests/checkasm/vf_threshold.c b/tests/checkasm/vf_threshold.c index 5a2fc0e4e..2c5cc807e 100644 --- a/tests/checkasm/vf_threshold.c +++ b/tests/checkasm/vf_threshold.c @@ -20,6 +20,7 @@ #include "checkasm.h" #include "libavfilter/threshold.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define WIDTH 256 #define WIDTH_PADDED 256 + 32 diff --git a/tests/checkasm/videodsp.c b/tests/checkasm/videodsp.c index 0a4424a28..eb2845a7d 100644 --- a/tests/checkasm/videodsp.c +++ b/tests/checkasm/videodsp.c @@ -23,6 +23,7 @@ #include "libavcodec/videodsp.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #define randomize_buffers(w, h) \ do { \ diff --git a/tests/checkasm/vp8dsp.c b/tests/checkasm/vp8dsp.c index d93f73087..c3af54fbf 100644 --- a/tests/checkasm/vp8dsp.c +++ b/tests/checkasm/vp8dsp.c @@ -25,6 +25,7 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" #include "checkasm.h" diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c index a91577b94..99c023899 100644 --- a/tests/checkasm/vp9dsp.c +++ b/tests/checkasm/vp9dsp.c @@ -27,6 +27,7 @@ #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" +#include "libavutil/mem_internal.h" static const uint32_t pixel_mask[3] = { 0xffffffff, 0x03ff03ff, 0x0fff0fff }; #define SIZEOF_PIXEL ((bit_depth + 7) / 8) diff --git a/tests/dnn/Makefile b/tests/dnn/Makefile index 64591b785..ef827520d 100644 --- a/tests/dnn/Makefile +++ b/tests/dnn/Makefile @@ -1,9 +1,11 @@ DNNTESTPROGS += dnn-layer-pad DNNTESTPROGS += dnn-layer-conv2d DNNTESTPROGS += dnn-layer-depth2space +DNNTESTPROGS += dnn-layer-dense DNNTESTPROGS += dnn-layer-mathbinary DNNTESTPROGS += dnn-layer-maximum DNNTESTPROGS += dnn-layer-mathunary +DNNTESTPROGS += dnn-layer-avgpool DNNTESTOBJS := $(DNNTESTOBJS:%=$(DNNTESTSDIR)%) $(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test.o) DNNTESTPROGS := $(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test$(EXESUF)) diff --git a/tests/dnn/dnn-layer-avgpool-test.c b/tests/dnn/dnn-layer-avgpool-test.c new file mode 100644 index 000000000..4a925ea22 --- /dev/null +++ b/tests/dnn/dnn-layer-avgpool-test.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2020 + * + * 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 "libavfilter/dnn/dnn_backend_native_layer_avgpool.h" + +#define EPSON 0.00001 + +static int test_with_same(void) +{ + // the input data and expected data are generated with below python code. + /* + import tensorflow as tf + import numpy as np + + x = tf.placeholder(tf.float32, shape=[1, None, None, 3]) + y = tf.layers.average_pooling2d(x, pool_size=[2,2], strides=[1,1], padding='VALID') + data = np.random.rand(1, 5, 6, 3); + + sess=tf.Session() + sess.run(tf.global_variables_initializer()) + + output = sess.run(y, feed_dict={x: data}) + + print("input:") + print(data.shape) + print(list(data.flatten())) + + print("output:") + print(output.shape) + print(list(output.flatten())) + */ + + AvgPoolParams params; + DnnOperand operands[2]; + int32_t input_indexes[1]; + float input[1*5*6*3] = { + 0.7461309859908424, 0.7567538372797069, 0.07662743569678687, 0.8882112610336333, 0.9720443314026668, 0.3337200343220823, 0.4421032129780248, + 0.14940809044964876, 0.6773177061961277, 0.9778844630669781, 0.6522650522626998, 0.0317651530878591, 0.31259897552911364, 0.6235936821891896, + 0.40016094349542775, 0.4599222930032276, 0.7893807222960093, 0.8475986363538283, 0.5058802717647394, 0.7827005363222633, 0.3032188123727916, + 0.8983728631302361, 0.20622408444965523, 0.22966072303869878, 0.09535751273161308, 0.8760709100995375, 0.9982324154558745, 0.7904595468621013, + 0.13883671508879347, 0.9332751439533138, 0.0010861680752152214, 0.3607210449251048, 0.6600652759586171, 0.7629572058138805, 0.29441975810476106, + 0.2683471432889405, 0.22574580829831536, 0.8893251976212904, 0.3907737043801005, 0.6421829842863968, 0.6670373870457297, 0.9383850793160277, + 0.4120458907436003, 0.3589847212711481, 0.48047736550128983, 0.6428192648418949, 0.0313661686292348, 0.429357100401472, 0.5123413386514056, + 0.8492446404097114, 0.9045286128486804, 0.8123708563814285, 0.3943245008451698, 0.9576713003177785, 0.5985610965938726, 0.9350833279543561, + 0.8010079897491659, 0.45882114217642866, 0.35275037908941487, 0.4555844661432271, 0.12352455940255314, 0.37801756635035544, 0.2824056214573083, + 0.6229462823245029, 0.7235305681391472, 0.5408259266122064, 0.12142224381781208, 0.34431198802873686, 0.7112823816321276, 0.6307144385115417, + 0.8136734589018082, 0.842095618140585, 0.8602767724004784, 0.6649236853766185, 0.5184782829419623, 0.9119607270982825, 0.3084111974561645, + 0.39460705638161364, 0.17710447526170836, 0.1715485945814199, 0.17277563576521882, 0.40188232428735704, 0.22847985411491878, 0.4135361701550696, + 0.24621846601980057, 0.6576588108454774, 0.6063336087333997, 0.6452342242996931, 0.7071689702737508, 0.1973416063225648 + }; + float expected_output[] = { + 0.75964886, 0.6794307, 0.23580676, 0.5810112, 0.5509369, 0.55973274, 0.5764512, 0.45414522, 0.6601476, 0.52050734, 0.44385415, + 0.50631666, 0.38414115, 0.5170288, 0.544043, 0.61143976, 0.5419003, 0.5579729, 0.5680455, 0.6363218, 0.4655096, 0.51198983, + 0.5270792, 0.66168886, 0.48517057, 0.3513146, 0.7103355, 0.48667657, 0.34504217, 0.7318065, 0.5221889, 0.4746775, 0.69765306, + 0.78766406, 0.34437215, 0.6130092, 0.48132777, 0.7110491, 0.6464378, 0.40914366, 0.4391975, 0.5392131, 0.45033398, 0.37297475, + 0.43326652, 0.4748823, 0.48711336, 0.64649844, 0.51921225, 0.60038865, 0.8538945, 0.7215426, 0.60399896, 0.89988345, 0.707405, + 0.5652921, 0.54241943, 0.41785273, 0.30268195, 0.3263432, 0.3313644, 0.37539417, 0.35238582, 0.34811732, 0.48849532, 0.56799453, + 0.41089734, 0.63070333, 0.5892633, 0.6379743, 0.7604212, 0.5197186, 0.88611877, 0.48666745, 0.45654267, 0.5445326, 0.2399799, + 0.28369135, 0.28949338, 0.20001422, 0.2931559, 0.3240504, 0.44306934, 0.5099349, 0.44572634, 0.68241394, 0.40183762, 0.6452342, + 0.707169, 0.1973416 + }; + float *output; + + params.strides = 1; + params.kernel_size = 2; + params.padding_method = SAME; + + operands[0].data = input; + operands[0].dims[0] = 1; + operands[0].dims[1] = 5; + operands[0].dims[2] = 6; + operands[0].dims[3] = 3; + operands[1].data = NULL; + + input_indexes[0] = 0; + ff_dnn_execute_layer_avg_pool(operands, input_indexes, 1, ¶ms, NULL); + + output = operands[1].data; + for (int i = 0; i < sizeof(expected_output) / sizeof(float); ++i) { + if (fabs(output[i] - expected_output[i]) > EPSON) { + printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]); + av_freep(&output); + return 1; + } + } + + av_freep(&output); + return 0; +} + +static int test_with_valid(void) +{ + // the input data and expected data are generated with below python code. + /* + import tensorflow as tf + import numpy as np + + x = tf.placeholder(tf.float32, shape=[1, None, None, 3]) + y = tf.layers.average_pooling2d(x, pool_size=[2,2], strides=[1,1], padding='VALID') + data = np.random.rand(1, 5, 6, 3); + + sess=tf.Session() + sess.run(tf.global_variables_initializer()) + + output = sess.run(y, feed_dict={x: data}) + + print("input:") + print(data.shape) + print(list(data.flatten())) + + print("output:") + print(output.shape) + print(list(output.flatten())) + */ + + AvgPoolParams params; + DnnOperand operands[2]; + int32_t input_indexes[1]; + float input[1*5*6*3] = { + 0.5046741692941682, 0.9273653202485155, 0.8193878359859937, 0.1904059431360905, 0.8664919633253656, 0.7484625128286059, 0.984534184632278, + 0.31900804890072254, 0.3259426099940872, 0.05388974903570376, 0.7356610151331133, 0.46710858713311965, 0.718553768817036, 0.062478421853278676, + 0.7813224786584609, 0.4826837517658389, 0.9748095400220147, 0.8078547703898341, 0.11976750668368585, 0.8713586777195065, 0.41447321551284355, + 0.9818788239089807, 0.4335715767584073, 0.4059793452147419, 0.3677205907204525, 0.47919995923571, 0.8341395256258882, 0.7059726374074609, + 0.5478504551919791, 0.8622900484790175, 0.8343709722511167, 0.05089827275068537, 0.6465283980840416, 0.544539116066677, 0.39812057257884337, + 0.9578115576866337, 0.25012888117580145, 0.579333516024662, 0.5556732133051457, 0.6119862111181243, 0.0018736758772316398, 0.9795490254040474, + 0.4488085008883018, 0.28947489777011737, 0.4834108668633247, 0.9280490084385024, 0.9895821458049648, 0.31777618554697606, 0.42679693258977847, + 0.74447844466923, 0.9752225305081498, 0.17564130841849335, 0.22382692067314292, 0.009602884447469373, 0.5144884415025782, 0.031622570708844555, + 0.8277532752502512, 0.4111593210409763, 0.5272084646575664, 0.28856508082905297, 0.11317726946036655, 0.7203328275540273, 0.8310055019972384, + 0.8535951508685228, 0.40230347305233227, 0.2819703265132867, 0.6243143957791139, 0.7512463693822311, 0.7523056340495644, 0.8838077258040928, + 0.5472240664033092, 0.2550538284454935, 0.5560317774456567, 0.8966847087518931, 0.6728358284165321, 0.30361297147530875, 0.464343925441822, + 0.34507695659461224, 0.6333175615390685, 0.26661369038523497, 0.9926748632253231, 0.9994267301382666, 0.8684917986974414, 0.3598754806113009, + 0.49550268625464666, 0.03652458679973214, 0.13469081713137177, 0.4579424049273835, 0.48641107969110353, 0.9670250266945365 + }; + float expected_output[1*4*5*3] = { + 0.44918162, 0.7746969, 0.5970757, 0.63113487, 0.5245679, 0.578631, 0.52802926, 0.52042985, 0.6223702, 0.57819676, 0.34922206, + 0.6893124, 0.64503694, 0.37157673, 0.7983793, 0.49094033, 0.47153437, 0.5889187, 0.6025985, 0.30103004, 0.6757697, 0.6126377, + 0.5765268, 0.62440413, 0.7237974, 0.5832023, 0.7004543, 0.49533707, 0.35433105, 0.6472913, 0.44694072, 0.28500956, 0.6628852, + 0.39628282, 0.38472247, 0.6456326, 0.58590746, 0.60042334, 0.47854072, 0.7081889, 0.7219026, 0.5818187, 0.5276401, 0.56669396, + 0.49804622, 0.4463231, 0.4799649, 0.5335578, 0.36531678, 0.4946247, 0.6143306, 0.6498792, 0.5644355, 0.6163815, 0.7432098, + 0.5146416, 0.38221055, 0.6153918, 0.45535153, 0.5272688 + }; + float *output; + + params.strides = 1; + params.kernel_size = 2; + params.padding_method = VALID; + + operands[0].data = input; + operands[0].dims[0] = 1; + operands[0].dims[1] = 5; + operands[0].dims[2] = 6; + operands[0].dims[3] = 3; + operands[1].data = NULL; + + input_indexes[0] = 0; + ff_dnn_execute_layer_avg_pool(operands, input_indexes, 1, ¶ms, NULL); + + output = operands[1].data; + for (int i = 0; i < sizeof(expected_output) / sizeof(float); ++i) { + if (fabs(output[i] - expected_output[i]) > EPSON) { + printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]); + av_freep(&output); + return 1; + } + } + + av_freep(&output); + return 0; +} + +int main(int argc, char **argv) +{ + if (test_with_same()) + return 1; + if (test_with_valid()) + return 1; + + return 0; +} diff --git a/tests/dnn/dnn-layer-conv2d-test.c b/tests/dnn/dnn-layer-conv2d-test.c index 2da01e537..5ee60eeaf 100644 --- a/tests/dnn/dnn-layer-conv2d-test.c +++ b/tests/dnn/dnn-layer-conv2d-test.c @@ -96,6 +96,10 @@ static int test_with_same_dilate(void) }; float bias[2] = { -1.6574852, -0.72915393 }; + NativeContext ctx; + ctx.class = NULL; + ctx.options.conv2d_threads = 1; + params.activation = TANH; params.has_bias = 1; params.biases = bias; @@ -114,7 +118,7 @@ static int test_with_same_dilate(void) operands[1].data = NULL; input_indexes[0] = 0; - dnn_execute_layer_conv2d(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_conv2d(operands, input_indexes, 1, ¶ms, &ctx); output = operands[1].data; for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { @@ -196,6 +200,10 @@ static int test_with_valid(void) }; float bias[2] = { -0.4773722, -0.19620377 }; + NativeContext ctx; + ctx.class = NULL; + ctx.options.conv2d_threads = 1; + params.activation = TANH; params.has_bias = 1; params.biases = bias; @@ -214,7 +222,7 @@ static int test_with_valid(void) operands[1].data = NULL; input_indexes[0] = 0; - dnn_execute_layer_conv2d(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_conv2d(operands, input_indexes, 1, ¶ms, &ctx); output = operands[1].data; for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { diff --git a/tests/dnn/dnn-layer-dense-test.c b/tests/dnn/dnn-layer-dense-test.c new file mode 100644 index 000000000..696f7505e --- /dev/null +++ b/tests/dnn/dnn-layer-dense-test.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2020 + * + * 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 +#include "libavfilter/dnn/dnn_backend_native_layer_dense.h" + +#define EPSON 0.00001 + +static int test(void) +{ + // the input data and expected data are generated with below python code. + /* + x = tf.placeholder(tf.float32, shape=[1, None, None, 3]) + y = tf.layers.dense(input_x, 3, activation=tf.nn.sigmoid, bias_initializer=tf.keras.initializers.he_normal()) + data = np.random.rand(1, 5, 6, 3); + + sess=tf.Session() + sess.run(tf.global_variables_initializer()) + + weights = dict([(var.name, sess.run(var)) for var in tf.trainable_variables()]) + kernel = weights['dense/kernel:0'] + kernel = np.transpose(kernel, [1, 0]) + print("kernel:") + print(kernel.shape) + print(list(kernel.flatten())) + + bias = weights['dense/bias:0'] + print("bias:") + print(bias.shape) + print(list(bias.flatten())) + + output = sess.run(y, feed_dict={x: data}) + + print("input:") + print(data.shape) + print(list(data.flatten())) + + print("output:") + print(output.shape) + print(list(output.flatten())) + */ + + DenseParams params; + DnnOperand operands[2]; + int32_t input_indexes[1]; + float input[1*5*6*3] = { + 0.5552418686576308, 0.20653189262022464, 0.31115120939398877, 0.5897014433221428, 0.37340078861060655, 0.6470921693941893, 0.8039950367872679, 0.8762700891949274, + 0.6556655583829558, 0.5911096107039339, 0.18640250865290997, 0.2803248779238966, 0.31586613136402053, 0.9447300740056483, 0.9443980824873418, 0.8158851991115941, + 0.5631010340387631, 0.9407402251929046, 0.6485434876551682, 0.5631376966470001, 0.17581924875609634, 0.7033802439103178, 0.04802402495561675, 0.9183681450194972, + 0.46059317944364, 0.07964160481596883, 0.871787076270302, 0.973743142324361, 0.15923146943258415, 0.8212946080584571, 0.5415954459227064, 0.9552813822803975, + 0.4908552668172057, 0.33723691635292274, 0.46588057864910026, 0.8994239961321776, 0.09845220457674186, 0.1713400292123486, 0.39570294912818826, 0.08018956486392803, + 0.5290478278169032, 0.7141906125920976, 0.0320878067840098, 0.6412406575332606, 0.0075712007102423096, 0.7150828462386156, 0.1311989216968138, 0.4706847944253756, + 0.5447610794883336, 0.3430923933318001, 0.536082357943209, 0.4371629342483694, 0.40227962985019927, 0.3553806249465469, 0.031806622424259245, 0.7053916426174, + 0.3261570237309813, 0.419500213292063, 0.3155691223480851, 0.05664028113178088, 0.3636491555914486, 0.8502419746667123, 0.9836596530684955, 0.1628681802975801, + 0.09410832912479894, 0.28407218939480294, 0.7983417928813697, 0.24132158596506748, 0.8154729498062224, 0.29173768373895637, 0.13407102008052096, 0.18705786678800385, + 0.7167943621295573, 0.09222004247174376, 0.2319220738766018, 0.17708964382285064, 0.1391440370249517, 0.3254088083499256, 0.4013916894718289, 0.4819742663322323, + 0.15080103744648077, 0.9302407847555013, 0.9397597961319524, 0.5719200825550793, 0.9538938024682824, 0.9583882089203861, 0.5168861091262276, 0.1926396841842669, + 0.6781176744337578, 0.719366447288566 + }; + float expected_output[1*5*6*3] = { + -0.3921688, -0.9243112, -0.29659146, -0.64000785, -0.9466343, -0.62125254, -0.71759033, -0.9171336, -0.735589, -0.34365994, + -0.92100817, -0.23903961, -0.8962277, -0.9521279, -0.90962386, -0.7488303, -0.9563761, -0.7701762, -0.40800542, -0.87684774, + -0.3339763, -0.6354543, -0.97068924, -0.6246325, -0.6992075, -0.9706726, -0.6818918, -0.51864433, -0.9592881, -0.51187396, + -0.7423632, -0.89911884, -0.7457824, -0.82009757, -0.96402895, -0.8235518, -0.61980766, -0.94494647, -0.5410502, -0.8281218, + -0.95508635, -0.8201453, -0.5937325, -0.8679507, -0.500767, -0.39430764, -0.93967676, -0.32183182, -0.58913624, -0.939717, + -0.55179894, -0.55004454, -0.9214453, -0.4889004, -0.75294703, -0.9118363, -0.7200309, -0.3248641, -0.8878874, -0.18977344, + -0.8873837, -0.9571257, -0.90145934, -0.50521654, -0.93739635, -0.39051685, -0.61143184, -0.9591179, -0.605999, -0.40008977, + -0.92219675, -0.26732883, -0.19607787, -0.9172511, -0.07068595, -0.5409857, -0.9387041, -0.44181606, -0.4705004, -0.8899935, + -0.37997037, -0.66105115, -0.89754754, -0.68141997, -0.6324047, -0.886776, -0.65066385, -0.8334821, -0.94801456, -0.83297 + }; + float *output; + float kernel[3*3] = { + 0.56611896, -0.5144603, -0.82600045, 0.19219112, 0.3835776, -0.7475352, 0.5209291, -0.6301091, -0.99442935}; + float bias[3] = {-0.3654299, -1.5711838, -0.15546428}; + + params.activation = TANH; + params.has_bias = 1; + params.biases = bias; + params.input_num = 3; + params.kernel = kernel; + params.output_num = 3; + + operands[0].data = input; + operands[0].dims[0] = 1; + operands[0].dims[1] = 5; + operands[0].dims[2] = 6; + operands[0].dims[3] = 3; + operands[1].data = NULL; + + input_indexes[0] = 0; + ff_dnn_execute_layer_dense(operands, input_indexes, 1, ¶ms, NULL); + + output = operands[1].data; + for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { + if (fabs(output[i] - expected_output[i]) > EPSON) { + printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]); + av_freep(&output); + return 1; + } + } + + av_freep(&output); + return 0; +} + +int main(int argc, char **argv) +{ + if (test()) + return 1; + + return 0; +} diff --git a/tests/dnn/dnn-layer-depth2space-test.c b/tests/dnn/dnn-layer-depth2space-test.c index 5225ec7b7..958247e67 100644 --- a/tests/dnn/dnn-layer-depth2space-test.c +++ b/tests/dnn/dnn-layer-depth2space-test.c @@ -81,7 +81,7 @@ static int test(void) input_indexes[0] = 0; params.block_size = 2; - dnn_execute_layer_depth2space(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_depth2space(operands, input_indexes, 1, ¶ms, NULL); output = operands[1].data; for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { diff --git a/tests/dnn/dnn-layer-mathbinary-test.c b/tests/dnn/dnn-layer-mathbinary-test.c index e7f8f8557..2e41dc1ae 100644 --- a/tests/dnn/dnn-layer-mathbinary-test.c +++ b/tests/dnn/dnn-layer-mathbinary-test.c @@ -40,6 +40,8 @@ static float get_expected(float f1, float f2, DNNMathBinaryOperation op) return f1 / f2; case DMBO_MINIMUM: return (f1 < f2) ? f1 : f2; + case DMBO_FLOORMOD: + return (float)((int)(f1) % (int)(f2)); default: av_assert0(!"not supported yet"); return 0.f; @@ -69,7 +71,7 @@ static int test_broadcast_input0(DNNMathBinaryOperation op) operands[1].data = NULL; input_indexes[0] = 0; - dnn_execute_layer_math_binary(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_math_binary(operands, input_indexes, 1, ¶ms, NULL); output = operands[1].data; for (int i = 0; i < sizeof(input) / sizeof(float); i++) { @@ -109,7 +111,7 @@ static int test_broadcast_input1(DNNMathBinaryOperation op) operands[1].data = NULL; input_indexes[0] = 0; - dnn_execute_layer_math_binary(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_math_binary(operands, input_indexes, 1, ¶ms, NULL); output = operands[1].data; for (int i = 0; i < sizeof(input) / sizeof(float); i++) { @@ -157,7 +159,7 @@ static int test_no_broadcast(DNNMathBinaryOperation op) input_indexes[0] = 0; input_indexes[1] = 1; - dnn_execute_layer_math_binary(operands, input_indexes, 2, ¶ms); + ff_dnn_execute_layer_math_binary(operands, input_indexes, 2, ¶ms, NULL); output = operands[2].data; for (int i = 0; i < sizeof(input0) / sizeof(float); i++) { @@ -205,5 +207,8 @@ int main(int argc, char **argv) if (test(DMBO_MINIMUM)) return 1; + if (test(DMBO_FLOORMOD)) + return 1; + return 0; } diff --git a/tests/dnn/dnn-layer-mathunary-test.c b/tests/dnn/dnn-layer-mathunary-test.c index f032ca068..a8c5ab022 100644 --- a/tests/dnn/dnn-layer-mathunary-test.c +++ b/tests/dnn/dnn-layer-mathunary-test.c @@ -32,6 +32,36 @@ static float get_expected(float f, DNNMathUnaryOperation op) { case DMUO_ABS: return (f >= 0) ? f : -f; + case DMUO_SIN: + return sin(f); + case DMUO_COS: + return cos(f); + case DMUO_TAN: + return tan(f); + case DMUO_ASIN: + return asin(f); + case DMUO_ACOS: + return acos(f); + case DMUO_ATAN: + return atan(f); + case DMUO_SINH: + return sinh(f); + case DMUO_COSH: + return cosh(f); + case DMUO_TANH: + return tanh(f); + case DMUO_ASINH: + return asinh(f); + case DMUO_ACOSH: + return acosh(f); + case DMUO_ATANH: + return atanh(f); + case DMUO_CEIL: + return ceil(f); + case DMUO_FLOOR: + return floor(f); + case DMUO_ROUND: + return round(f); default: av_assert0(!"not supported yet"); return 0.f; @@ -43,8 +73,8 @@ static int test(DNNMathUnaryOperation op) DnnLayerMathUnaryParams params; DnnOperand operands[2]; int32_t input_indexes[1]; - float input[1*1*2*3] = { - -3, 2.5, 2, -2.1, 7.8, 100}; + float input[1*1*3*3] = { + 0.1, 0.5, 0.75, -3, 2.5, 2, -2.1, 7.8, 100}; float *output; params.un_op = op; @@ -52,17 +82,20 @@ static int test(DNNMathUnaryOperation op) operands[0].data = input; operands[0].dims[0] = 1; operands[0].dims[1] = 1; - operands[0].dims[2] = 2; + operands[0].dims[2] = 3; operands[0].dims[3] = 3; operands[1].data = NULL; input_indexes[0] = 0; - dnn_execute_layer_math_unary(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_math_unary(operands, input_indexes, 1, ¶ms, NULL); output = operands[1].data; for (int i = 0; i < sizeof(input) / sizeof(float); ++i) { float expected_output = get_expected(input[i], op); - if(fabs(output[i] - expected_output) > EPS) { + int output_nan = isnan(output[i]); + int expected_nan = isnan(expected_output); + if ((!output_nan && !expected_nan && fabs(output[i] - expected_output) > EPS) || + (output_nan && !expected_nan) || (!output_nan && expected_nan)) { printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output); av_freep(&output); return 1; @@ -77,5 +110,35 @@ int main(int agrc, char **argv) { if (test(DMUO_ABS)) return 1; + if (test(DMUO_SIN)) + return 1; + if (test(DMUO_COS)) + return 1; + if (test(DMUO_TAN)) + return 1; + if (test(DMUO_ASIN)) + return 1; + if (test(DMUO_ACOS)) + return 1; + if (test(DMUO_ATAN)) + return 1; + if (test(DMUO_SINH)) + return 1; + if (test(DMUO_COSH)) + return 1; + if (test(DMUO_TANH)) + return 1; + if (test(DMUO_ASINH)) + return 1; + if (test(DMUO_ACOSH)) + return 1; + if (test(DMUO_ATANH)) + return 1; + if (test(DMUO_CEIL)) + return 1; + if (test(DMUO_FLOOR)) + return 1; + if (test(DMUO_ROUND)) + return 1; return 0; } diff --git a/tests/dnn/dnn-layer-maximum-test.c b/tests/dnn/dnn-layer-maximum-test.c index 06daf6448..bf22f3719 100644 --- a/tests/dnn/dnn-layer-maximum-test.c +++ b/tests/dnn/dnn-layer-maximum-test.c @@ -45,7 +45,7 @@ static int test(void) operands[1].data = NULL; input_indexes[0] = 0; - dnn_execute_layer_maximum(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_maximum(operands, input_indexes, 1, ¶ms, NULL); output = operands[1].data; for (int i = 0; i < sizeof(input) / sizeof(float); i++) { diff --git a/tests/dnn/dnn-layer-pad-test.c b/tests/dnn/dnn-layer-pad-test.c index ea8c824d1..a8443ce3b 100644 --- a/tests/dnn/dnn-layer-pad-test.c +++ b/tests/dnn/dnn-layer-pad-test.c @@ -79,7 +79,7 @@ static int test_with_mode_symmetric(void) operands[1].data = NULL; input_indexes[0] = 0; - dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms, NULL); output = operands[1].data; for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { @@ -144,7 +144,7 @@ static int test_with_mode_reflect(void) operands[1].data = NULL; input_indexes[0] = 0; - dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms, NULL); output = operands[1].data; for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { @@ -210,7 +210,7 @@ static int test_with_mode_constant(void) operands[1].data = NULL; input_indexes[0] = 0; - dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms); + ff_dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms, NULL); output = operands[1].data; for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { diff --git a/tests/fate-run.sh b/tests/fate-run.sh index 002944b01..b69176f7c 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -86,11 +86,15 @@ runecho(){ } probefmt(){ - run ffprobe${PROGSUF}${EXECSUF} -show_entries format=format_name -print_format default=nw=1:nk=1 -v 0 "$@" + run ffprobe${PROGSUF}${EXECSUF} -show_entries format=format_name -print_format default=nw=1:nk=1 "$@" +} + +probeaudiostream(){ + run ffprobe${PROGSUF}${EXECSUF} -show_entries stream=codec_name,codec_time_base,sample_fmt,channels,channel_layout "$@" } probetags(){ - run ffprobe${PROGSUF}${EXECSUF} -show_entries format_tags -v 0 "$@" + run ffprobe${PROGSUF}${EXECSUF} -show_entries format_tags "$@" } runlocal(){ @@ -99,31 +103,31 @@ runlocal(){ } probeframes(){ - run ffprobe${PROGSUF}${EXECSUF} -show_frames -v 0 "$@" + run ffprobe${PROGSUF}${EXECSUF} -show_frames "$@" } probechapters(){ - run ffprobe${PROGSUF}${EXECSUF} -show_chapters -v 0 "$@" + run ffprobe${PROGSUF}${EXECSUF} -show_chapters "$@" } probegaplessinfo(){ filename="$1" shift - run ffprobe${PROGSUF}${EXECSUF} -bitexact -select_streams a -show_entries format=start_time,duration:stream=index,start_pts,duration_ts -v 0 "$filename" "$@" + run ffprobe${PROGSUF}${EXECSUF} -bitexact -select_streams a -show_entries format=start_time,duration:stream=index,start_pts,duration_ts "$filename" "$@" pktfile1="${outdir}/${test}.pkts" framefile1="${outdir}/${test}.frames" cleanfiles="$cleanfiles $pktfile1 $framefile1" - run ffprobe${PROGSUF}${EXECSUF} -bitexact -select_streams a -of compact -count_packets -show_entries packet=pts,dts,duration,flags:stream=nb_read_packets -v 0 "$filename" "$@" > "$pktfile1" + run ffprobe${PROGSUF}${EXECSUF} -bitexact -select_streams a -of compact -count_packets -show_entries packet=pts,dts,duration,flags:stream=nb_read_packets "$filename" "$@" > "$pktfile1" head -n 8 "$pktfile1" tail -n 9 "$pktfile1" - run ffprobe${PROGSUF}${EXECSUF} -bitexact -select_streams a -of compact -count_frames -show_entries frame=pkt_pts,pkt_dts,best_effort_timestamp,pkt_duration,nb_samples:stream=nb_read_frames -v 0 "$filename" "$@" > "$framefile1" + run ffprobe${PROGSUF}${EXECSUF} -bitexact -select_streams a -of compact -count_frames -show_entries frame=pkt_pts,pkt_dts,best_effort_timestamp,pkt_duration,nb_samples:stream=nb_read_frames "$filename" "$@" > "$framefile1" head -n 8 "$framefile1" tail -n 9 "$framefile1" } ffmpeg(){ dec_opts="-hwaccel $hwaccel -threads $threads -thread_type $thread_type" - ffmpeg_args="-nostdin -nostats -cpuflags $cpuflags" + ffmpeg_args="-nostdin -nostats -noauto_conversion_filters -cpuflags $cpuflags" for arg in $@; do [ x${arg} = x-i ] && ffmpeg_args="${ffmpeg_args} ${dec_opts}" ffmpeg_args="${ffmpeg_args} ${arg}" @@ -154,12 +158,12 @@ md5pipe(){ md5(){ encfile="${outdir}/${test}.out" cleanfiles="$cleanfiles $encfile" - ffmpeg "$@" $(target_path $encfile) + ffmpeg -y "$@" $(target_path $encfile) || return do_md5sum $encfile | awk '{print $1}' } pcm(){ - ffmpeg "$@" -vn -f s16le - + ffmpeg -auto_conversion_filters "$@" -vn -f s16le - } fmtstdout(){ @@ -177,8 +181,8 @@ enc_dec_pcm(){ encfile="${outdir}/${test}.${out_fmt}" cleanfiles=$encfile encfile=$(target_path ${encfile}) - ffmpeg -i $src_file "$@" -f $out_fmt -y ${encfile} || return - ffmpeg -bitexact -i ${encfile} -c:a pcm_${pcm_fmt} -fflags +bitexact -f ${dec_fmt} - + ffmpeg -auto_conversion_filters -i $src_file "$@" -f $out_fmt -y ${encfile} || return + ffmpeg -auto_conversion_filters -bitexact -i ${encfile} -c:a pcm_${pcm_fmt} -fflags +bitexact -f ${dec_fmt} - } FLAGS="-flags +bitexact -sws_flags +accurate_rnd+bitexact -fflags +bitexact" @@ -200,16 +204,16 @@ enc_dec(){ tsrcfile=$(target_path $srcfile) tencfile=$(target_path $encfile) tdecfile=$(target_path $decfile) - ffmpeg -f $src_fmt $DEC_OPTS -i $tsrcfile $ENC_OPTS $enc_opt $FLAGS \ + ffmpeg -auto_conversion_filters -f $src_fmt $DEC_OPTS -i $tsrcfile $ENC_OPTS $enc_opt $FLAGS \ -f $enc_fmt -y $tencfile || return do_md5sum $encfile echo $(wc -c $encfile) - ffmpeg $8 $DEC_OPTS -i $tencfile $ENC_OPTS $dec_opt $FLAGS \ + ffmpeg -auto_conversion_filters $8 $DEC_OPTS -i $tencfile $ENC_OPTS $dec_opt $FLAGS \ -f $dec_fmt -y $tdecfile || return do_md5sum $decfile tests/tiny_psnr${HOSTEXECSUF} $srcfile $decfile $cmp_unit $cmp_shift test -z $ffprobe_opts || \ - run ffprobe${PROGSUF}${EXECSUF} $ffprobe_opts -v 0 $tencfile || return + run ffprobe${PROGSUF}${EXECSUF} $ffprobe_opts $tencfile || return } transcode(){ @@ -230,7 +234,7 @@ transcode(){ ffmpeg $DEC_OPTS -i $tencfile $ENC_OPTS $FLAGS $final_decode \ -f framecrc - || return test -z $ffprobe_opts || \ - run ffprobe${PROGSUF}${EXECSUF} $ffprobe_opts -v 0 $tencfile || return + run ffprobe${PROGSUF}${EXECSUF} $ffprobe_opts $tencfile || return } stream_remux(){ @@ -249,7 +253,7 @@ stream_remux(){ ffmpeg $DEC_OPTS -i $tencfile $ENC_OPTS $FLAGS $final_decode \ -f framecrc - || return test -z $ffprobe_opts || \ - run ffprobe${PROGSUF}${EXECSUF} $ffprobe_opts -v 0 $tencfile || return + run ffprobe${PROGSUF}${EXECSUF} $ffprobe_opts $tencfile || return } # FIXME: There is a certain duplication between the avconv-related helper @@ -266,7 +270,7 @@ echov(){ echo "$@" >&3 } -AVCONV_OPTS="-nostdin -nostats -y -cpuflags $cpuflags" +AVCONV_OPTS="-nostdin -nostats -noauto_conversion_filters -y -cpuflags $cpuflags" COMMON_OPTS="-flags +bitexact -idct simple -sws_flags +accurate_rnd+bitexact -fflags +bitexact" DEC_OPTS="$COMMON_OPTS -threads $threads" ENC_OPTS="$COMMON_OPTS -threads 1 -dct fastint" @@ -296,17 +300,17 @@ lavf_audio(){ t="${test#lavf-}" outdir="tests/data/lavf" file=${outdir}/lavf.$t - do_avconv $file $DEC_OPTS $1 -ar 44100 -f s16le -i $pcm_src "$ENC_OPTS -metadata title=lavftest" -t 1 -qscale 10 $2 - do_avconv_crc $file $DEC_OPTS $3 -i $target_path/$file + do_avconv $file -auto_conversion_filters $DEC_OPTS $1 -ar 44100 -f s16le -i $pcm_src "$ENC_OPTS -metadata title=lavftest" -t 1 -qscale 10 $2 + do_avconv_crc $file -auto_conversion_filters $DEC_OPTS $3 -i $target_path/$file } lavf_container(){ t="${test#lavf-}" outdir="tests/data/lavf" file=${outdir}/lavf.$t - do_avconv $file $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le $1 -i $pcm_src "$ENC_OPTS -metadata title=lavftest" -b:a 64k -t 1 -qscale:v 10 $2 + do_avconv $file -auto_conversion_filters $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le $1 -i $pcm_src "$ENC_OPTS -metadata title=lavftest" -b:a 64k -t 1 -qscale:v 10 $2 test "$3" = "disable_crc" || - do_avconv_crc $file $DEC_OPTS -i $target_path/$file $3 + do_avconv_crc $file -auto_conversion_filters $DEC_OPTS -i $target_path/$file $3 } lavf_container_attach() { lavf_container "" "$1 -attach ${raw_src%/*}/00.pgm -metadata:s:t mimetype=image/x-portable-greymap"; } @@ -326,8 +330,8 @@ lavf_container_fate() outdir="tests/data/lavf-fate" file=${outdir}/lavf.$t input="${target_samples}/$1" - do_avconv $file $DEC_OPTS $2 -i "$input" "$ENC_OPTS -metadata title=lavftest" -vcodec copy -acodec copy - do_avconv_crc $file $DEC_OPTS -i $target_path/$file $3 + do_avconv $file -auto_conversion_filters $DEC_OPTS $2 -i "$input" "$ENC_OPTS -metadata title=lavftest" -vcodec copy -acodec copy + do_avconv_crc $file -auto_conversion_filters $DEC_OPTS -i $target_path/$file $3 } lavf_image(){ @@ -335,9 +339,9 @@ lavf_image(){ outdir="tests/data/images/$t" mkdir -p "$outdir" file=${outdir}/%02d.$t - run_avconv $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $1 "$ENC_OPTS -metadata title=lavftest" -frames 13 -y -qscale 10 $target_path/$file + run_avconv $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $1 "$ENC_OPTS -metadata title=lavftest" -vf scale -frames 13 -y -qscale 10 $target_path/$file do_md5sum ${outdir}/02.$t - do_avconv_crc $file $DEC_OPTS $2 -i $target_path/$file $2 + do_avconv_crc $file -auto_conversion_filters $DEC_OPTS $2 -i $target_path/$file $2 echo $(wc -c ${outdir}/02.$t) } @@ -346,16 +350,16 @@ lavf_image2pipe(){ t="${t%pipe}" outdir="tests/data/lavf" file=${outdir}/${t}pipe.$t - do_avconv $file $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src -f image2pipe "$ENC_OPTS -metadata title=lavftest" -t 1 -qscale 10 - do_avconv_crc $file $DEC_OPTS -f image2pipe -i $target_path/$file + do_avconv $file -auto_conversion_filters $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src -f image2pipe "$ENC_OPTS -metadata title=lavftest" -t 1 -qscale 10 + do_avconv_crc $file -auto_conversion_filters $DEC_OPTS -f image2pipe -i $target_path/$file } lavf_video(){ t="${test#lavf-}" outdir="tests/data/lavf" file=${outdir}/lavf.$t - do_avconv $file $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src "$ENC_OPTS -metadata title=lavftest" -t 1 -qscale 10 $1 $2 - do_avconv_crc $file $DEC_OPTS -i $target_path/$file $1 + do_avconv $file -auto_conversion_filters $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src "$ENC_OPTS -metadata title=lavftest" -t 1 -qscale 10 $1 $2 + do_avconv_crc $file -auto_conversion_filters $DEC_OPTS -i $target_path/$file $1 } refcmp_metadata(){ @@ -412,7 +416,7 @@ pixfmts(){ outertest=$test for pix_fmt in $pix_fmts; do test=$pix_fmt - video_filter "${prefilter_chain}format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt -frames:v $nframes + video_filter "${prefilter_chain}scale,format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt -frames:v $nframes done rm $in_fmts $scale_in_fmts $scale_out_fmts $scale_exclude_fmts @@ -429,16 +433,16 @@ gapless(){ cleanfiles="$cleanfiles $decfile1 $decfile2 $decfile3" # test packet data - ffmpeg $extra_args -i "$sample" -bitexact -c:a copy -f framecrc -y $(target_path $decfile1) + ffmpeg -auto_conversion_filters $extra_args -i "$sample" -bitexact -c:a copy -f framecrc -y $(target_path $decfile1) do_md5sum $decfile1 # test decoded (and cut) data - ffmpeg $extra_args -i "$sample" -bitexact -f wav md5: + ffmpeg -auto_conversion_filters $extra_args -i "$sample" -bitexact -f wav md5: # the same as above again, with seeking to the start - ffmpeg $extra_args -ss 0 -seek_timestamp 1 -i "$sample" -bitexact -c:a copy -f framecrc -y $(target_path $decfile2) + ffmpeg -auto_conversion_filters $extra_args -ss 0 -seek_timestamp 1 -i "$sample" -bitexact -c:a copy -f framecrc -y $(target_path $decfile2) do_md5sum $decfile2 - ffmpeg $extra_args -ss 0 -seek_timestamp 1 -i "$sample" -bitexact -f wav md5: + ffmpeg -auto_conversion_filters $extra_args -ss 0 -seek_timestamp 1 -i "$sample" -bitexact -f wav md5: # test packet data, with seeking to a specific position - ffmpeg $extra_args -ss 5 -seek_timestamp 1 -i "$sample" -bitexact -c:a copy -f framecrc -y $(target_path $decfile3) + ffmpeg -auto_conversion_filters $extra_args -ss 5 -seek_timestamp 1 -i "$sample" -bitexact -c:a copy -f framecrc -y $(target_path $decfile3) do_md5sum $decfile3 } @@ -451,7 +455,7 @@ gaplessenc(){ cleanfiles="$cleanfiles $file1" # test data after reencoding - ffmpeg -i "$sample" -bitexact -map 0:a -c:a $codec -f $format -y "$(target_path "$file1")" + ffmpeg -i "$sample" -bitexact -map 0:a -c:a $codec -af aresample -f $format -y "$(target_path "$file1")" probegaplessinfo "$(target_path "$file1")" } @@ -463,7 +467,7 @@ audio_match(){ decfile="${outdir}/${test}.wav" cleanfiles="$cleanfiles $decfile" - ffmpeg -i "$sample" -bitexact $extra_args -y $(target_path $decfile) + ffmpeg -auto_conversion_filters -i "$sample" -bitexact $extra_args -y $(target_path $decfile) tests/audiomatch${HOSTEXECSUF} $decfile $trefile } @@ -480,10 +484,10 @@ concat(){ awk "{gsub(/%SRCFILE%/, \"$sample\"); print}" $template > $concatfile if [ "$mode" = "md5" ]; then - run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_streams -show_packets -v 0 -safe 0 $extra_args $(target_path $concatfile) | tr -d '\r' > $packetfile + run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_streams -show_packets -safe 0 $extra_args $(target_path $concatfile) | tr -d '\r' > $packetfile do_md5sum $packetfile else - run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_streams -show_packets -v 0 -of compact=p=0:nk=1 -safe 0 $extra_args $(target_path $concatfile) + run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_streams -show_packets -of compact=p=0:nk=1 -safe 0 $extra_args $(target_path $concatfile) fi } diff --git a/tests/fate/aac.mak b/tests/fate/aac.mak index bd283225c..4b38d3648 100644 --- a/tests/fate/aac.mak +++ b/tests/fate/aac.mak @@ -150,7 +150,7 @@ FATE_AAC += $(FATE_AAC_CT:%=fate-aac-ct-%) FATE_AAC_ENCODE += fate-aac-aref-encode fate-aac-aref-encode: ./tests/data/asynth-44100-2.wav -fate-aac-aref-encode: CMD = enc_dec_pcm adts wav s16le $(REF) -c:a aac -aac_is 0 -aac_pns 0 -aac_ms 0 -aac_tns 0 -b:a 512k +fate-aac-aref-encode: CMD = enc_dec_pcm adts wav s16le $(REF) -c:a aac -aac_is 0 -aac_pns 0 -aac_ms 0 -aac_tns 0 -b:a 512k -fflags +bitexact -flags +bitexact fate-aac-aref-encode: CMP = stddev fate-aac-aref-encode: REF = ./tests/data/asynth-44100-2.wav fate-aac-aref-encode: CMP_SHIFT = -4096 @@ -159,7 +159,7 @@ fate-aac-aref-encode: SIZE_TOLERANCE = 2464 fate-aac-aref-encode: FUZZ = 89 FATE_AAC_ENCODE += fate-aac-ln-encode -fate-aac-ln-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -c:a aac -aac_is 0 -aac_pns 0 -aac_ms 0 -aac_tns 0 -b:a 512k +fate-aac-ln-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -c:a aac -aac_is 0 -aac_pns 0 -aac_ms 0 -aac_tns 0 -b:a 512k -fflags +bitexact -flags +bitexact fate-aac-ln-encode: CMP = stddev fate-aac-ln-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav fate-aac-ln-encode: CMP_SHIFT = -4096 @@ -168,7 +168,7 @@ fate-aac-ln-encode: SIZE_TOLERANCE = 3560 fate-aac-ln-encode: FUZZ = 30 FATE_AAC_ENCODE += fate-aac-ln-encode-128k -fate-aac-ln-encode-128k: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -c:a aac -aac_is 0 -aac_pns 0 -aac_ms 0 -aac_tns 0 -b:a 128k -cutoff 22050 +fate-aac-ln-encode-128k: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -c:a aac -aac_is 0 -aac_pns 0 -aac_ms 0 -aac_tns 0 -b:a 128k -cutoff 22050 -fflags +bitexact -flags +bitexact fate-aac-ln-encode-128k: CMP = stddev fate-aac-ln-encode-128k: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav fate-aac-ln-encode-128k: CMP_SHIFT = -4096 @@ -195,7 +195,7 @@ fate-aac-tns-encode: FUZZ = 7 fate-aac-tns-encode: SIZE_TOLERANCE = 3560 FATE_AAC_ENCODE += fate-aac-is-encode -fate-aac-is-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -c:a aac -aac_pns 0 -aac_is 1 -aac_ms 0 -b:a 128k -aac_tns 0 -cutoff 22050 +fate-aac-is-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -c:a aac -aac_pns 0 -aac_is 1 -aac_ms 0 -b:a 128k -aac_tns 0 -cutoff 22050 -fflags +bitexact -flags +bitexact fate-aac-is-encode: CMP = stddev fate-aac-is-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav fate-aac-is-encode: CMP_SHIFT = -4096 @@ -204,7 +204,7 @@ fate-aac-is-encode: SIZE_TOLERANCE = 3560 fate-aac-is-encode: FUZZ = 10 FATE_AAC_ENCODE += fate-aac-ms-encode -fate-aac-ms-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -c:a aac -aac_pns 0 -aac_is 0 -aac_ms 1 -aac_tns 0 -b:a 128k -cutoff 22050 +fate-aac-ms-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -c:a aac -aac_pns 0 -aac_is 0 -aac_ms 1 -aac_tns 0 -b:a 128k -cutoff 22050 -fflags +bitexact -flags +bitexact fate-aac-ms-encode: CMP = stddev fate-aac-ms-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav fate-aac-ms-encode: CMP_SHIFT = -4096 @@ -224,7 +224,7 @@ fate-aac-yoraw-encode: FUZZ = 17 FATE_AAC_ENCODE += fate-aac-pred-encode -fate-aac-pred-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -profile:a aac_main -c:a aac -aac_is 0 -aac_pns 0 -aac_ms 0 -aac_tns 0 -b:a 128k -cutoff 22050 +fate-aac-pred-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -profile:a aac_main -c:a aac -aac_is 0 -aac_pns 0 -aac_ms 0 -aac_tns 0 -b:a 128k -cutoff 22050 -fflags +bitexact -flags +bitexact fate-aac-pred-encode: CMP = stddev fate-aac-pred-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav fate-aac-pred-encode: CMP_SHIFT = -4096 diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak index bb02d3829..d76e22bad 100644 --- a/tests/fate/ac3.mak +++ b/tests/fate/ac3.mak @@ -88,9 +88,9 @@ fate-ac3-encode fate-eac3-encode: REF = $(SAMPLES)/audio-reference/luckynight_2c FATE_AC3-$(call ENCMUX, AC3_FIXED, AC3) += fate-ac3-fixed-encode fate-ac3-fixed-encode: tests/data/asynth-44100-2.wav fate-ac3-fixed-encode: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-ac3-fixed-encode: CMD = md5 -i $(SRC) -c ac3_fixed -ab 128k -f ac3 -flags +bitexact +fate-ac3-fixed-encode: CMD = md5 -i $(SRC) -c ac3_fixed -ab 128k -f ac3 -flags +bitexact -af aresample fate-ac3-fixed-encode: CMP = oneline -fate-ac3-fixed-encode: REF = a1d1fc116463b771abf5aef7ed37d7b1 +fate-ac3-fixed-encode: REF = 1f548175e11a95e62ce20e442fcc8d08 FATE_EAC3-$(call ALLYES, EAC3_DEMUXER EAC3_MUXER EAC3_CORE_BSF) += fate-eac3-core-bsf fate-eac3-core-bsf: CMD = md5pipe -i $(TARGET_SAMPLES)/eac3/the_great_wall_7.1.eac3 -c:a copy -bsf:a eac3_core -fflags +bitexact -f eac3 diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak index bb6bfe5ad..1b8c32b16 100644 --- a/tests/fate/acodec.mak +++ b/tests/fate/acodec.mak @@ -1,6 +1,6 @@ fate-acodec-%: CODEC = $(@:fate-acodec-%=%) fate-acodec-%: SRC = tests/data/asynth-44100-2.wav -fate-acodec-%: CMD = enc_dec wav $(SRC) $(FMT) "-b:a 128k -c $(CODEC) $(ENCOPTS)" wav "-c pcm_s16le $(DECOPTS)" -keep +fate-acodec-%: CMD = enc_dec wav $(SRC) $(FMT) "-b:a 128k -c $(CODEC) $(ENCOPTS)" wav "-c pcm_s16le $(DECOPTS)" "$(KEEP_OVERRIDE)" fate-acodec-%: CMP_UNIT = 2 fate-acodec-%: REF = $(SRC_PATH)/tests/ref/acodec/$(@:fate-acodec-%=%) @@ -44,13 +44,17 @@ fate-acodec-pcm-u%be: FMT = nut fate-acodec-pcm-u%le: FMT = nut fate-acodec-pcm-f%be: FMT = au -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ADX, ADX) += adx -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_SSI, KVAG) += ima_ssi -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_WAV, WAV) += ima_wav -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_MS, WAV) += ms -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_SWF, FLV) += swf -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_YAMAHA, WAV) += yamaha +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ADX, ADX) += adx +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ARGO, ARGO_ASF) += argo +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APM, APM) += ima_apm +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_ALP, ALP) += ima_alp +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_SSI, KVAG) += ima_ssi +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_WAV, WAV) += ima_wav +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_MS, WAV) += ms +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_SWF, FLV) += swf +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_SWF, WAV) += swf-wav +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_YAMAHA, WAV) += yamaha FATE_ACODEC_ADPCM := $(FATE_ACODEC_ADPCM-yes:%=fate-acodec-adpcm-%) FATE_ACODEC += $(FATE_ACODEC_ADPCM) @@ -59,6 +63,8 @@ fate-acodec-adpcm: $(FATE_ACODEC_ADPCM) fate-acodec-adpcm-%: CODEC = adpcm_$(@:fate-acodec-adpcm-%=%) fate-acodec-adpcm-adx: FMT = adx +fate-acodec-adpcm-argo: FMT = argo_asf +fate-acodec-adpcm-ima_apm: FMT = apm fate-acodec-adpcm-ima_qt: FMT = aiff fate-acodec-adpcm-ima_ssi: FMT = kvag fate-acodec-adpcm-ima_wav: FMT = wav @@ -66,6 +72,12 @@ fate-acodec-adpcm-ms: FMT = wav fate-acodec-adpcm-swf: FMT = flv fate-acodec-adpcm-yamaha: FMT = wav +fate-acodec-adpcm-swf-wav: FMT = wav +fate-acodec-adpcm-swf-wav: CODEC = adpcm_swf + +fate-acodec-adpcm-ima_alp: FMT = alp +fate-acodec-adpcm-ima_alp: ENCOPTS = -type pcm + FATE_ACODEC_ADPCM_TRELLIS-$(call ENCDEC, ADPCM_ADX, ADX) += adx FATE_ACODEC_ADPCM_TRELLIS-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt FATE_ACODEC_ADPCM_TRELLIS-$(call ENCDEC, ADPCM_IMA_WAV, WAV) += ima_wav @@ -104,12 +116,12 @@ fate-acodec-alac: CODEC = alac -compression_level 1 FATE_ACODEC-$(call ENCDEC, DCA, DTS) += fate-acodec-dca fate-acodec-dca: tests/data/asynth-44100-2.wav fate-acodec-dca: SRC = tests/data/asynth-44100-2.wav -fate-acodec-dca: CMD = md5 -i $(TARGET_PATH)/$(SRC) -c:a dca -strict -2 -f dts -flags +bitexact +fate-acodec-dca: CMD = md5 -i $(TARGET_PATH)/$(SRC) -c:a dca -strict -2 -f dts -flags +bitexact -af aresample fate-acodec-dca: CMP = oneline fate-acodec-dca: REF = 2aa580ac67820fce4f581b96ebb34acc FATE_ACODEC-$(call ENCDEC, DCA, WAV) += fate-acodec-dca2 -fate-acodec-dca2: CMD = enc_dec_pcm dts wav s16le $(SRC) -c:a dca -strict -2 -flags +bitexact +fate-acodec-dca2: CMD = enc_dec_pcm dts wav s16le $(SRC) -c:a dca -strict -2 -flags +bitexact -af aresample fate-acodec-dca2: REF = $(SRC) fate-acodec-dca2: CMP = stddev fate-acodec-dca2: CMP_SHIFT = -2048 diff --git a/tests/fate/adpcm.mak b/tests/fate/adpcm.mak index bc2804477..f858a808c 100644 --- a/tests/fate/adpcm.mak +++ b/tests/fate/adpcm.mak @@ -1,8 +1,8 @@ FATE_ADPCM-$(call DEMDEC, FOURXM, ADPCM_4XM) += fate-adpcm-4xm -fate-adpcm-4xm: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/dracula.4xm -vn -map 0:6 +fate-adpcm-4xm: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/dracula.4xm -vn -map 0:6 -af aresample FATE_ADPCM-$(call DEMDEC, AST, ADPCM_AFC) += fate-adpcm-afc -fate-adpcm-afc: CMD = framecrc -i $(TARGET_SAMPLES)/ast/demo11_02_partial.ast +fate-adpcm-afc: CMD = framecrc -i $(TARGET_SAMPLES)/ast/demo11_02_partial.ast -af aresample FATE_ADPCM-$(call DEMDEC, WAV, ADPCM_CT) += fate-adpcm-creative fate-adpcm-creative: CMD = md5 -i $(TARGET_SAMPLES)/creative/intro-partial.wav -f s16le @@ -17,7 +17,7 @@ FATE_ADPCM-$(call DEMDEC, VOC, ADPCM_SBPRO_4) += fate-adpcm-creative-8-4bit fate-adpcm-creative-8-4bit: CMD = md5 -i $(TARGET_SAMPLES)/creative/BBC_4BIT.VOC -f s16le FATE_ADPCM-$(call DEMDEC, ADP, ADPCM_DTK) += fate-adpcm-dtk -fate-adpcm-dtk: CMD = framecrc -i $(TARGET_SAMPLES)/adp/shakespr_partial.adp -f s16le +fate-adpcm-dtk: CMD = framecrc -i $(TARGET_SAMPLES)/adp/shakespr_partial.adp -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA) += fate-adpcm-ea-1 fate-adpcm-ea-1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:a 26 -vn @@ -29,13 +29,13 @@ FATE_ADPCM-$(call DEMDEC, XA, ADPCM_EA_MAXIS_XA) += fate-adpcm-ea-maxis-xa fate-adpcm-ea-maxis-xa: CMD = framecrc -i $(TARGET_SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA_R1) += fate-adpcm-ea-r1 -fate-adpcm-ea-r1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/NFS6LogoE.mad -vn +fate-adpcm-ea-r1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/NFS6LogoE.mad -vn -af aresample FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA_R2) += fate-adpcm-ea-r2 -fate-adpcm-ea-r2: CMD = crc -i $(TARGET_SAMPLES)/ea-mpc/THX_logo.mpc -vn +fate-adpcm-ea-r2: CMD = crc -i $(TARGET_SAMPLES)/ea-mpc/THX_logo.mpc -vn -af aresample FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA_R3) += fate-adpcm-ea-r3 -fate-adpcm-ea-r3: CMD = crc -i $(TARGET_SAMPLES)/ea-vp6/THX_logo.vp6 -vn +fate-adpcm-ea-r3: CMD = crc -i $(TARGET_SAMPLES)/ea-vp6/THX_logo.vp6 -vn -af aresample FATE_ADPCM-$(call DEMDEC, AVI, ADPCM_IMA_AMV) += fate-adpcm-ima-amv fate-adpcm-ima-amv: CMD = framecrc -i $(TARGET_SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -vn @@ -68,7 +68,7 @@ FATE_ADPCM-$(call DEMDEC, SMJPEG, ADPCM_IMA_SMJPEG) += fate-adpcm-ima-smjpeg fate-adpcm-ima-smjpeg: CMD = framecrc -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -vn FATE_ADPCM-$(call DEMDEC, MOV, ADPCM_IMA_WAV) += fate-adpcm-ima_wav-stereo -fate-adpcm-ima_wav-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le +fate-adpcm-ima_wav-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, WSVQA, ADPCM_IMA_WS) += fate-adpcm-ima-ws fate-adpcm-ima-ws: CMD = framecrc -i $(TARGET_SAMPLES)/vqa/cc-demo1-partial.vqa -vn @@ -80,19 +80,19 @@ FATE_ADPCM-$(call DEMDEC, MOV, ADPCM_MS) += fate-adpcm_ms-stereo fate-adpcm_ms-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-ms02.mov -f s16le FATE_ADPCM-$(call DEMDEC, THP, ADPCM_THP) += fate-adpcm-thp -fate-adpcm-thp: CMD = framecrc -i $(TARGET_SAMPLES)/thp/pikmin2-opening1-partial.thp -vn +fate-adpcm-thp: CMD = framecrc -i $(TARGET_SAMPLES)/thp/pikmin2-opening1-partial.thp -vn -af aresample FATE_ADPCM-$(call DEMDEC, SMUSH, ADPCM_VIMA) += fate-adpcm-vima fate-adpcm-vima: CMD = framecrc -i $(TARGET_SAMPLES)/smush/ronin_part.znm -vn FATE_ADPCM-$(call DEMDEC, STR, ADPCM_XA) += fate-adpcm-xa -fate-adpcm-xa: CMD = framecrc -i $(TARGET_SAMPLES)/psx-str/abc000_cut.str -vn +fate-adpcm-xa: CMD = framecrc -i $(TARGET_SAMPLES)/psx-str/abc000_cut.str -vn -af aresample FATE_ADPCM-$(call DEMDEC, ARGO_ASF, ADPCM_ARGO) += fate-adpcm-argo-mono -fate-adpcm-argo-mono: CMD = md5 -i $(TARGET_SAMPLES)/argo-asf/PWIN22M.ASF -f s16le +fate-adpcm-argo-mono: CMD = md5 -i $(TARGET_SAMPLES)/argo-asf/PWIN22M.ASF -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, ARGO_ASF, ADPCM_ARGO) += fate-adpcm-argo-stereo -fate-adpcm-argo-stereo: CMD = md5 -i $(TARGET_SAMPLES)/argo-asf/CBK2_cut.asf -f s16le +fate-adpcm-argo-stereo: CMD = md5 -i $(TARGET_SAMPLES)/argo-asf/CBK2_cut.asf -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, KVAG, ADPCM_IMA_SSI) += fate-adpcm-ima-ssi-mono fate-adpcm-ima-ssi-mono: CMD = md5 -i $(TARGET_SAMPLES)/kvag/mull1_cut.vag -f s16le @@ -113,31 +113,34 @@ FATE_ADPCM-$(call DEMDEC, ALP, ADPCM_IMA_ALP) += fate-adpcm-ima-alp-stereo fate-adpcm-ima-alp-stereo: CMD = md5 -i $(TARGET_SAMPLES)/alp/theme-cut.tun -f s16le FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-single -fate-adpcm-ima-cunning-single: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/GD-cut.5c -f s16le +fate-adpcm-ima-cunning-single: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/GD-cut.5c -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-track0 -fate-adpcm-ima-cunning-track0: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-cut.11c -map 0:a:0 -f s16le +fate-adpcm-ima-cunning-track0: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-cut.11c -map 0:a:0 -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-track1 -fate-adpcm-ima-cunning-track1: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-cut.11c -map 0:a:1 -f s16le +fate-adpcm-ima-cunning-track1: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-cut.11c -map 0:a:1 -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-trunc-t1 -fate-adpcm-ima-cunning-trunc-t1: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t1.11c -map 0:a:0 -f s16le +fate-adpcm-ima-cunning-trunc-t1: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t1.11c -map 0:a:0 -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-trunc-t2-track0 -fate-adpcm-ima-cunning-trunc-t2-track0: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t2.11c -map 0:a:0 -f s16le +fate-adpcm-ima-cunning-trunc-t2-track0: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t2.11c -map 0:a:0 -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-trunc-t2-track1 -fate-adpcm-ima-cunning-trunc-t2-track1: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t2.11c -map 0:a:1 -f s16le +fate-adpcm-ima-cunning-trunc-t2-track1: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t2.11c -map 0:a:1 -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-trunc-t2a-track0 -fate-adpcm-ima-cunning-trunc-t2a-track0: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t2a.11c -map 0:a:0 -f s16le +fate-adpcm-ima-cunning-trunc-t2a-track0: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t2a.11c -map 0:a:0 -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-trunc-t2a-track1 -fate-adpcm-ima-cunning-trunc-t2a-track1: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t2a.11c -map 0:a:1 -f s16le +fate-adpcm-ima-cunning-trunc-t2a-track1: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-t2a.11c -map 0:a:1 -f s16le -af aresample FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-trunc-h2 -fate-adpcm-ima-cunning-trunc-h2: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-h2.11c -map 0:a:0 -f s16le +fate-adpcm-ima-cunning-trunc-h2: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/VIDEOMOD-trunc-h2.11c -map 0:a:0 -f s16le -af aresample + +FATE_ADPCM-$(call DEMDEC, PP_BNK, ADPCM_IMA_CUNNING) += fate-adpcm-ima-cunning-stereo +fate-adpcm-ima-cunning-stereo: CMD = md5 -y -i $(TARGET_SAMPLES)/pp_bnk/MOGODON2-cut.44c -f s16le -af aresample FATE_SAMPLES_AVCONV += $(FATE_ADPCM-yes) fate-adpcm: $(FATE_ADPCM-yes) diff --git a/tests/fate/api.mak b/tests/fate/api.mak index 3e1cc992e..10288f5ab 100644 --- a/tests/fate/api.mak +++ b/tests/fate/api.mak @@ -21,14 +21,6 @@ fate-api-seek: $(APITESTSDIR)/api-seek-test$(EXESUF) fate-lavf-flv fate-api-seek: CMD = run $(APITESTSDIR)/api-seek-test$(EXESUF) $(TARGET_PATH)/tests/data/lavf/lavf.flv 0 720 fate-api-seek: CMP = null -FATE_API_SAMPLES_LIBAVFORMAT-$(call DEMDEC, IMAGE2, PNG) += fate-api-png-codec-param -fate-api-png-codec-param: $(APITESTSDIR)/api-codec-param-test$(EXESUF) -fate-api-png-codec-param: CMD = run $(APITESTSDIR)/api-codec-param-test$(EXESUF) $(TARGET_SAMPLES)/png1/lena-rgba.png - -FATE_API_SAMPLES_LIBAVFORMAT-$(call DEMDEC, IMAGE2, MJPEG) += fate-api-mjpeg-codec-param -fate-api-mjpeg-codec-param: $(APITESTSDIR)/api-codec-param-test$(EXESUF) -fate-api-mjpeg-codec-param: CMD = run $(APITESTSDIR)/api-codec-param-test$(EXESUF) $(TARGET_SAMPLES)/exif/image_small.jpg - FATE_API-$(HAVE_THREADS) += fate-api-threadmessage fate-api-threadmessage: $(APITESTSDIR)/api-threadmessage-test$(EXESUF) fate-api-threadmessage: CMD = run $(APITESTSDIR)/api-threadmessage-test$(EXESUF) 3 10 30 50 2 20 40 diff --git a/tests/fate/apng.mak b/tests/fate/apng.mak index bc138b42d..0a5f542f1 100644 --- a/tests/fate/apng.mak +++ b/tests/fate/apng.mak @@ -4,6 +4,9 @@ fate-apng-clock: CMD = framecrc -i $(TARGET_SAMPLES)/apng/clock.png FATE_APNG += fate-apng-osample fate-apng-osample: CMD = framecrc -i $(TARGET_SAMPLES)/apng/o_sample.png +FATE_APNG += fate-apng-dispose-previous +fate-apng-dispose-previous: CMD = framecrc -i $(TARGET_SAMPLES)/apng/apng_out_of_order_frames.png + FATE_APNG-$(call DEMDEC, APNG, APNG) += $(FATE_APNG) FATE_SAMPLES_FFMPEG += $(FATE_APNG-yes) diff --git a/tests/fate/audio.mak b/tests/fate/audio.mak index c41958ea2..fd9905ca0 100644 --- a/tests/fate/audio.mak +++ b/tests/fate/audio.mak @@ -25,7 +25,7 @@ fate-dolby-e: CMP = oneoff fate-dolby-e: REF = $(SAMPLES)/dolby_e/16-11.pcm FATE_SAMPLES_AUDIO-$(call DEMDEC, DSS, DSS_SP) += fate-dss-lp fate-dss-sp -fate-dss-lp: CMD = framecrc -i $(TARGET_SAMPLES)/dss/lp.dss -frames 30 +fate-dss-lp: CMD = framecrc -i $(TARGET_SAMPLES)/dss/lp.dss -frames 30 -af aresample fate-dss-sp: CMD = framecrc -i $(TARGET_SAMPLES)/dss/sp.dss -frames 30 FATE_SAMPLES_AUDIO-$(call DEMDEC, DSF, DST) += fate-dsf-dst @@ -53,19 +53,19 @@ fate-nellymoser-aref-encode: CMP_TARGET = 3863 fate-nellymoser-aref-encode: SIZE_TOLERANCE = 268 FATE_SAMPLES_AUDIO-$(call DEMDEC, AVI, ON2AVC) += fate-on2avc -fate-on2avc: CMD = framecrc -i $(TARGET_SAMPLES)/vp7/potter-40.vp7 -frames 30 -vn +fate-on2avc: CMD = framecrc -i $(TARGET_SAMPLES)/vp7/potter-40.vp7 -frames 30 -vn -af aresample FATE_SAMPLES_AUDIO-$(call DEMDEC, PAF, PAF_AUDIO) += fate-paf-audio fate-paf-audio: CMD = framecrc -i $(TARGET_SAMPLES)/paf/hod1-partial.paf -vn FATE_SAMPLES_AUDIO-$(call DEMDEC, VMD, VMDAUDIO) += fate-sierra-vmd-audio -fate-sierra-vmd-audio: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -vn +fate-sierra-vmd-audio: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -vn -af aresample FATE_SAMPLES_AUDIO-$(call DEMDEC, SMACKER, SMACKAUD) += fate-smacker-audio -fate-smacker-audio: CMD = framecrc -i $(TARGET_SAMPLES)/smacker/wetlogo.smk -vn +fate-smacker-audio: CMD = framecrc -i $(TARGET_SAMPLES)/smacker/wetlogo.smk -vn -af aresample FATE_SAMPLES_AUDIO-$(call DEMDEC, WSVQA, WS_SND1) += fate-ws_snd -fate-ws_snd: CMD = md5 -i $(TARGET_SAMPLES)/vqa/ws_snd.vqa -f s16le +fate-ws_snd: CMD = md5 -i $(TARGET_SAMPLES)/vqa/ws_snd.vqa -f s16le -af aresample fate-flcl1905: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_frames -show_packets -print_format compact $(TARGET_SAMPLES)/wav/FLCL_Ending_My-short.wav diff --git a/tests/fate/bmp.mak b/tests/fate/bmp.mak index 923c70dac..de27f19b1 100644 --- a/tests/fate/bmp.mak +++ b/tests/fate/bmp.mak @@ -1,41 +1,41 @@ FATE_BMP += fate-bmp-1bit -fate-bmp-1bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test1.bmp -pix_fmt rgb24 +fate-bmp-1bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test1.bmp -pix_fmt rgb24 -vf scale FATE_BMP += fate-bmp-4bit -fate-bmp-4bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test4.bmp -pix_fmt rgb24 +fate-bmp-4bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test4.bmp -pix_fmt rgb24 -vf scale FATE_BMP += fate-bmp-4bit-os2 -fate-bmp-4bit-os2: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test4os2v2.bmp -pix_fmt rgb24 +fate-bmp-4bit-os2: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test4os2v2.bmp -pix_fmt rgb24 -vf scale FATE_BMP += fate-bmp-8bit -fate-bmp-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test8.bmp -pix_fmt rgb24 +fate-bmp-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test8.bmp -pix_fmt rgb24 -vf scale FATE_BMP += fate-bmp-8bit-os2 -fate-bmp-8bit-os2: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test8os2.bmp -pix_fmt rgb24 +fate-bmp-8bit-os2: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test8os2.bmp -pix_fmt rgb24 -vf scale FATE_BMP += fate-bmp-15bit -fate-bmp-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16.bmp -pix_fmt rgb555le +fate-bmp-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16.bmp -pix_fmt rgb555le -vf scale FATE_BMP += fate-bmp-15bit-mask -fate-bmp-15bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16bf555.bmp -pix_fmt rgb555le +fate-bmp-15bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16bf555.bmp -pix_fmt rgb555le -vf scale FATE_BMP += fate-bmp-16bit-mask -fate-bmp-16bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16bf565.bmp -pix_fmt rgb565le +fate-bmp-16bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16bf565.bmp -pix_fmt rgb565le -vf scale FATE_BMP += fate-bmp-24bit fate-bmp-24bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test24.bmp FATE_BMP += fate-bmp-32bit -fate-bmp-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test32.bmp -pix_fmt bgr24 +fate-bmp-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test32.bmp -pix_fmt bgr24 -vf scale FATE_BMP += fate-bmp-32bit-mask -fate-bmp-32bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test32bf.bmp -pix_fmt bgr24 +fate-bmp-32bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test32bf.bmp -pix_fmt bgr24 -vf scale FATE_BMP += fate-bmp-rle4 -fate-bmp-rle4: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/testcompress4.bmp -pix_fmt rgb24 +fate-bmp-rle4: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/testcompress4.bmp -pix_fmt rgb24 -vf scale FATE_BMP += fate-bmp-rle8 -fate-bmp-rle8: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/testcompress8.bmp -pix_fmt rgb24 +fate-bmp-rle8: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/testcompress8.bmp -pix_fmt rgb24 -vf scale FATE_BMP-$(call DEMDEC, IMAGE2, BMP) += $(FATE_BMP) diff --git a/tests/fate/canopus.mak b/tests/fate/canopus.mak index d41921130..3d664ff91 100644 --- a/tests/fate/canopus.mak +++ b/tests/fate/canopus.mak @@ -25,10 +25,10 @@ FATE_SAMPLES_FFMPEG-$(call DEMDEC, AVI, HQ_HQA) += $(FATE_CANOPUS_HQ_HQA) fate-canopus-hq_hqa: $(FATE_CANOPUS_HQ_HQA) FATE_CANOPUS_HQX += fate-canopus-hqx422 -fate-canopus-hqx422: CMD = framecrc -i $(TARGET_SAMPLES)/canopus/hqx422.avi -pix_fmt yuv422p16be -an +fate-canopus-hqx422: CMD = framecrc -i $(TARGET_SAMPLES)/canopus/hqx422.avi -pix_fmt yuv422p16be -an -vf scale FATE_CANOPUS_HQX += fate-canopus-hqx422a -fate-canopus-hqx422a: CMD = framecrc -i $(TARGET_SAMPLES)/canopus/hqx422a.avi -pix_fmt yuv422p16be -an +fate-canopus-hqx422a: CMD = framecrc -i $(TARGET_SAMPLES)/canopus/hqx422a.avi -pix_fmt yuv422p16be -an -vf scale FATE_SAMPLES_FFMPEG-$(call DEMDEC, AVI, HQX) += $(FATE_CANOPUS_HQX) fate-canopus-hqx: $(FATE_CANOPUS_HQX) diff --git a/tests/fate/cbs.mak b/tests/fate/cbs.mak index ad9c85863..18efa96a6 100644 --- a/tests/fate/cbs.mak +++ b/tests/fate/cbs.mak @@ -9,7 +9,7 @@ FATE_CBS_DEPS = $(call ALLYES, $(1)_DEMUXER $(2)_PARSER $(3)_METADATA_BSF $(4)_D define FATE_CBS_TEST # (codec, test_name, sample_file, output_format) FATE_CBS_$(1) += fate-cbs-$(1)-$(2) -fate-cbs-$(1)-$(2): CMD = md5 -i $(TARGET_SAMPLES)/$(3) -c:v copy -y -bsf:v $(1)_metadata -f $(4) +fate-cbs-$(1)-$(2): CMD = md5 -c:v $(3) -i $(TARGET_SAMPLES)/$(4) -c:v copy -y -bsf:v $(1)_metadata -f $(5) endef # AV1 read/write @@ -34,10 +34,10 @@ FATE_CBS_AV1_SAMPLES = \ seq_hdr_op_param_info.ivf \ switch_frame.ivf -$(foreach N,$(FATE_CBS_AV1_CONFORMANCE_SAMPLES),$(eval $(call FATE_CBS_TEST,av1,$(basename $(N)),av1-test-vectors/$(N),rawvideo))) -$(foreach N,$(FATE_CBS_AV1_SAMPLES),$(eval $(call FATE_CBS_TEST,av1,$(basename $(N)),av1/$(N),rawvideo))) +$(foreach N,$(FATE_CBS_AV1_CONFORMANCE_SAMPLES),$(eval $(call FATE_CBS_TEST,av1,$(basename $(N)),av1,av1-test-vectors/$(N),rawvideo))) +$(foreach N,$(FATE_CBS_AV1_SAMPLES),$(eval $(call FATE_CBS_TEST,av1,$(basename $(N)),av1,av1/$(N),rawvideo))) -FATE_CBS_AV1-$(call ALLYES, IVF_DEMUXER AV1_PARSER AV1_METADATA_BSF RAWVIDEO_MUXER) = $(FATE_CBS_av1) +FATE_CBS_AV1-$(call FATE_CBS_DEPS, IVF, AV1, AV1, AV1, RAWVIDEO) = $(FATE_CBS_av1) FATE_SAMPLES_AVCONV += $(FATE_CBS_AV1-yes) fate-cbs-av1: $(FATE_CBS_AV1-yes) @@ -62,8 +62,8 @@ FATE_CBS_H264_CONFORMANCE_SAMPLES = \ FATE_CBS_H264_SAMPLES = \ sei-1.h264 -$(foreach N,$(FATE_CBS_H264_CONFORMANCE_SAMPLES),$(eval $(call FATE_CBS_TEST,h264,$(basename $(N)),h264-conformance/$(N),h264))) -$(foreach N,$(FATE_CBS_H264_SAMPLES),$(eval $(call FATE_CBS_TEST,h264,$(basename $(N)),h264/$(N),h264))) +$(foreach N,$(FATE_CBS_H264_CONFORMANCE_SAMPLES),$(eval $(call FATE_CBS_TEST,h264,$(basename $(N)),h264,h264-conformance/$(N),h264))) +$(foreach N,$(FATE_CBS_H264_SAMPLES),$(eval $(call FATE_CBS_TEST,h264,$(basename $(N)),h264,h264/$(N),h264))) FATE_CBS_H264-$(call FATE_CBS_DEPS, H264, H264, H264, H264, H264) = $(FATE_CBS_h264) FATE_SAMPLES_AVCONV += $(FATE_CBS_H264-yes) @@ -93,7 +93,7 @@ FATE_CBS_HEVC_SAMPLES = \ HRD_A_Fujitsu_2.bit \ SLPPLP_A_VIDYO_2.bit -$(foreach N,$(FATE_CBS_HEVC_SAMPLES),$(eval $(call FATE_CBS_TEST,hevc,$(basename $(N)),hevc-conformance/$(N),hevc))) +$(foreach N,$(FATE_CBS_HEVC_SAMPLES),$(eval $(call FATE_CBS_TEST,hevc,$(basename $(N)),hevc,hevc-conformance/$(N),hevc))) FATE_CBS_HEVC-$(call FATE_CBS_DEPS, HEVC, HEVC, HEVC, HEVC, HEVC) = $(FATE_CBS_hevc) FATE_SAMPLES_AVCONV += $(FATE_CBS_HEVC-yes) @@ -106,7 +106,7 @@ FATE_CBS_MPEG2_SAMPLES = \ sony-ct3.bs \ tcela-6.bits -$(foreach N,$(FATE_CBS_MPEG2_SAMPLES),$(eval $(call FATE_CBS_TEST,mpeg2,$(basename $(N)),mpeg2/$(N),mpeg2video))) +$(foreach N,$(FATE_CBS_MPEG2_SAMPLES),$(eval $(call FATE_CBS_TEST,mpeg2,$(basename $(N)),mpeg2video,mpeg2/$(N),mpeg2video))) FATE_CBS_MPEG2-$(call FATE_CBS_DEPS, MPEGVIDEO, MPEGVIDEO, MPEG2, MPEG2VIDEO, MPEG2VIDEO) = $(FATE_CBS_mpeg2) FATE_SAMPLES_AVCONV += $(FATE_CBS_MPEG2-yes) @@ -130,7 +130,7 @@ FATE_CBS_VP9_SAMPLES = \ vp93-2-20-10bit-yuv422.webm \ vp93-2-20-12bit-yuv444.webm -$(foreach N,$(FATE_CBS_VP9_SAMPLES),$(eval $(call FATE_CBS_TEST,vp9,$(basename $(N)),vp9-test-vectors/$(N),ivf))) +$(foreach N,$(FATE_CBS_VP9_SAMPLES),$(eval $(call FATE_CBS_TEST,vp9,$(basename $(N)),vp9,vp9-test-vectors/$(N),ivf))) FATE_CBS_VP9-$(call FATE_CBS_DEPS, IVF, VP9, VP9, VP9, IVF) = $(FATE_CBS_vp9) FATE_SAMPLES_AVCONV += $(FATE_CBS_VP9-yes) diff --git a/tests/fate/cdxl.mak b/tests/fate/cdxl.mak index 8144f96d9..2a4e2dd51 100644 --- a/tests/fate/cdxl.mak +++ b/tests/fate/cdxl.mak @@ -8,10 +8,10 @@ FATE_CDXL += fate-cdxl-ham8 fate-cdxl-ham8: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/mirage.cdxl -an -frames:v 1 FATE_CDXL += fate-cdxl-pal8 -fate-cdxl-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/maku.cdxl -pix_fmt rgb24 -frames:v 11 +fate-cdxl-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/maku.cdxl -pix_fmt rgb24 -frames:v 11 -vf scale FATE_CDXL += fate-cdxl-pal8-small -fate-cdxl-pal8-small: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/fruit.cdxl -an -pix_fmt rgb24 -frames:v 46 +fate-cdxl-pal8-small: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/fruit.cdxl -an -pix_fmt rgb24 -frames:v 46 -vf scale FATE_CDXL-$(call DEMDEC, CDXL, CDXL) += $(FATE_CDXL) diff --git a/tests/fate/dca.mak b/tests/fate/dca.mak index fad3a7529..d6e4df9e7 100644 --- a/tests/fate/dca.mak +++ b/tests/fate/dca.mak @@ -23,14 +23,14 @@ DCADEC_SUITE_LOSSY = core_51_24_48_768_0 \ define FATE_DCADEC_LOSSLESS_SUITE FATE_DCADEC_LOSSLESS += fate-dca-$(1) fate-dca-$(1)-dmix_2 fate-dca-$(1)-dmix_6 -fate-dca-$(1): CMD = framemd5 -i $(TARGET_SAMPLES)/dts/dcadec-suite/$(1).dtshd -c:a pcm_$(2) -fate-dca-$(1)-dmix_2: CMD = framemd5 -request_channel_layout 0x3 -i $(TARGET_SAMPLES)/dts/dcadec-suite/$(1).dtshd -c:a pcm_$(2) -fate-dca-$(1)-dmix_6: CMD = framemd5 -request_channel_layout 0x60f -i $(TARGET_SAMPLES)/dts/dcadec-suite/$(1).dtshd -c:a pcm_$(2) +fate-dca-$(1): CMD = framemd5 -i $(TARGET_SAMPLES)/dts/dcadec-suite/$(1).dtshd -c:a pcm_$(2) -af aresample +fate-dca-$(1)-dmix_2: CMD = framemd5 -request_channel_layout 0x3 -i $(TARGET_SAMPLES)/dts/dcadec-suite/$(1).dtshd -c:a pcm_$(2) -af aresample +fate-dca-$(1)-dmix_6: CMD = framemd5 -request_channel_layout 0x60f -i $(TARGET_SAMPLES)/dts/dcadec-suite/$(1).dtshd -c:a pcm_$(2) -af aresample endef define FATE_DCADEC_LOSSY_SUITE FATE_DCADEC_LOSSY += fate-dca-$(1) -fate-dca-$(1): CMD = ffmpeg -i $(TARGET_SAMPLES)/dts/dcadec-suite/$(1).dtshd -f f32le - +fate-dca-$(1): CMD = ffmpeg -i $(TARGET_SAMPLES)/dts/dcadec-suite/$(1).dtshd -f f32le -af aresample - fate-dca-$(1): REF = $(SAMPLES)/dts/dcadec-suite/$(1).f32 endef @@ -40,20 +40,20 @@ $(foreach N,$(DCADEC_SUITE_LOSSY),$(eval $(call FATE_DCADEC_LOSSY_SUITE,$(N)))) # lossy downmix tests FATE_DCADEC_LOSSY += fate-dca-core_51_24_48_768_1-dmix_2 -fate-dca-core_51_24_48_768_1-dmix_2: CMD = ffmpeg -request_channel_layout 0x3 -i $(TARGET_SAMPLES)/dts/dcadec-suite/core_51_24_48_768_1.dtshd -f f32le - +fate-dca-core_51_24_48_768_1-dmix_2: CMD = ffmpeg -request_channel_layout 0x3 -i $(TARGET_SAMPLES)/dts/dcadec-suite/core_51_24_48_768_1.dtshd -f f32le -af aresample - fate-dca-core_51_24_48_768_1-dmix_2: REF = $(SAMPLES)/dts/dcadec-suite/core_51_24_48_768_1-dmix_2.f32 FATE_DCADEC_LOSSY += fate-dca-x96_xxch_71_24_96_3840-dmix_2 -fate-dca-x96_xxch_71_24_96_3840-dmix_2: CMD = ffmpeg -request_channel_layout 0x3 -i $(TARGET_SAMPLES)/dts/dcadec-suite/x96_xxch_71_24_96_3840.dtshd -f f32le - +fate-dca-x96_xxch_71_24_96_3840-dmix_2: CMD = ffmpeg -request_channel_layout 0x3 -i $(TARGET_SAMPLES)/dts/dcadec-suite/x96_xxch_71_24_96_3840.dtshd -f f32le -af aresample - # intentionally uses the dmix_6 reference because the sample does not contain stereo downmix coefficients fate-dca-x96_xxch_71_24_96_3840-dmix_2: REF = $(SAMPLES)/dts/dcadec-suite/x96_xxch_71_24_96_3840-dmix_6.f32 FATE_DCADEC_LOSSY += fate-dca-x96_xxch_71_24_96_3840-dmix_6 -fate-dca-x96_xxch_71_24_96_3840-dmix_6: CMD = ffmpeg -request_channel_layout 0x60f -i $(TARGET_SAMPLES)/dts/dcadec-suite/x96_xxch_71_24_96_3840.dtshd -f f32le - +fate-dca-x96_xxch_71_24_96_3840-dmix_6: CMD = ffmpeg -request_channel_layout 0x60f -i $(TARGET_SAMPLES)/dts/dcadec-suite/x96_xxch_71_24_96_3840.dtshd -f f32le -af aresample - fate-dca-x96_xxch_71_24_96_3840-dmix_6: REF = $(SAMPLES)/dts/dcadec-suite/x96_xxch_71_24_96_3840-dmix_6.f32 FATE_DCADEC_LOSSY += fate-dca-xch_61_24_48_768-dmix_6 -fate-dca-xch_61_24_48_768-dmix_6: CMD = ffmpeg -request_channel_layout 0x60f -i $(TARGET_SAMPLES)/dts/dcadec-suite/xch_61_24_48_768.dtshd -f f32le - +fate-dca-xch_61_24_48_768-dmix_6: CMD = ffmpeg -request_channel_layout 0x60f -i $(TARGET_SAMPLES)/dts/dcadec-suite/xch_61_24_48_768.dtshd -f f32le -af aresample - fate-dca-xch_61_24_48_768-dmix_6: REF = $(SAMPLES)/dts/dcadec-suite/xch_61_24_48_768-dmix_6.f32 $(FATE_DCADEC_LOSSY): CMP = oneoff @@ -68,7 +68,7 @@ fate-dca-core: CMP = oneoff fate-dca-core: REF = $(SAMPLES)/dts/dts.pcm FATE_DCA-$(call DEMDEC, DTS, DCA) += fate-dca-xll -fate-dca-xll: CMD = md5 -i $(TARGET_SAMPLES)/dts/master_audio_7.1_24bit.dts -f s24le +fate-dca-xll: CMD = md5 -i $(TARGET_SAMPLES)/dts/master_audio_7.1_24bit.dts -f s24le -af aresample FATE_DCA-$(call DEMDEC, DTS, DCA) += fate-dts_es fate-dts_es: CMD = pcm -i $(TARGET_SAMPLES)/dts/dts_es.dts diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak index 9f3a6be27..e5809bedd 100644 --- a/tests/fate/demux.mak +++ b/tests/fate/demux.mak @@ -7,11 +7,14 @@ fate-adts-id3v1-demux: CMD = framecrc -f aac -i $(TARGET_SAMPLES)/aac/id3v1.aac fate-adts-id3v2-demux: CMD = framecrc -f aac -i $(TARGET_SAMPLES)/aac/id3v2.aac -c:a copy fate-adts-id3v2-two-tags-demux: CMD = framecrc -i $(TARGET_SAMPLES)/aac/id3v2_two_tags.aac -c:a copy +FATE_SAMPLES_DEMUX-$(CONFIG_AA_DEMUXER) += fate-aa-demux +fate-aa-demux: CMD = framecrc -i $(TARGET_SAMPLES)/aa/bush.aa -c:a copy + FATE_SAMPLES_DEMUX-$(CONFIG_AEA_DEMUXER) += fate-aea-demux fate-aea-demux: CMD = crc -i $(TARGET_SAMPLES)/aea/chirp.aea -c:a copy -FATE_SAMPLES_DEMUX-$(CONFIG_AV1_DEMUXER) += fate-av1-annexb-demux -fate-av1-annexb-demux: CMD = framecrc -i $(TARGET_SAMPLES)/av1/annexb.obu -c:v copy +FATE_SAMPLES_DEMUX-$(call DEMDEC, AV1, AV1) += fate-av1-annexb-demux +fate-av1-annexb-demux: CMD = framecrc -c:v av1 -i $(TARGET_SAMPLES)/av1/annexb.obu -c:v copy FATE_SAMPLES_DEMUX-$(CONFIG_AST_DEMUXER) += fate-ast fate-ast: CMD = crc -i $(TARGET_SAMPLES)/ast/demo11_02_partial.ast -c copy diff --git a/tests/fate/dfa.mak b/tests/fate/dfa.mak index f4b605747..5b725e3a9 100644 --- a/tests/fate/dfa.mak +++ b/tests/fate/dfa.mak @@ -1,35 +1,35 @@ FATE_DFA += fate-dfa1 -fate-dfa1: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0000.dfa -pix_fmt rgb24 +fate-dfa1: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0000.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa2 -fate-dfa2: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0001.dfa -pix_fmt rgb24 +fate-dfa2: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0001.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa3 -fate-dfa3: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0002.dfa -pix_fmt rgb24 +fate-dfa3: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0002.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa4 -fate-dfa4: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0003.dfa -pix_fmt rgb24 +fate-dfa4: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0003.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa5 -fate-dfa5: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0004.dfa -pix_fmt rgb24 +fate-dfa5: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0004.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa6 -fate-dfa6: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0005.dfa -pix_fmt rgb24 +fate-dfa6: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0005.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa7 -fate-dfa7: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0006.dfa -pix_fmt rgb24 +fate-dfa7: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0006.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa8 -fate-dfa8: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0007.dfa -pix_fmt rgb24 +fate-dfa8: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0007.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa9 -fate-dfa9: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0008.dfa -pix_fmt rgb24 +fate-dfa9: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0008.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa10 -fate-dfa10: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0009.dfa -pix_fmt rgb24 +fate-dfa10: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0009.dfa -pix_fmt rgb24 -vf scale FATE_DFA += fate-dfa11 -fate-dfa11: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0010.dfa -pix_fmt rgb24 +fate-dfa11: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0010.dfa -pix_fmt rgb24 -vf scale FATE_DFA-$(call DEMDEC, DFA, DFA) += $(FATE_DFA) diff --git a/tests/fate/dnn.mak b/tests/fate/dnn.mak index 4a50b1638..ef07ee45f 100644 --- a/tests/fate/dnn.mak +++ b/tests/fate/dnn.mak @@ -8,6 +8,11 @@ fate-dnn-layer-conv2d: $(DNNTESTSDIR)/dnn-layer-conv2d-test$(EXESUF) fate-dnn-layer-conv2d: CMD = run $(DNNTESTSDIR)/dnn-layer-conv2d-test$(EXESUF) fate-dnn-layer-conv2d: CMP = null +FATE_DNN += fate-dnn-layer-dense +fate-dnn-layer-dense: $(DNNTESTSDIR)/dnn-layer-dense-test$(EXESUF) +fate-dnn-layer-dense: CMD = run $(DNNTESTSDIR)/dnn-layer-dense-test$(EXESUF) +fate-dnn-layer-dense: CMP = null + FATE_DNN += fate-dnn-layer-depth2space fate-dnn-layer-depth2space: $(DNNTESTSDIR)/dnn-layer-depth2space-test$(EXESUF) fate-dnn-layer-depth2space: CMD = run $(DNNTESTSDIR)/dnn-layer-depth2space-test$(EXESUF) @@ -28,6 +33,11 @@ fate-dnn-layer-mathunary: $(DNNTESTSDIR)/dnn-layer-mathunary-test$(EXESUF) fate-dnn-layer-mathunary: CMD = run $(DNNTESTSDIR)/dnn-layer-mathunary-test$(EXESUF) fate-dnn-layer-mathunary: CMP = null -FATE-yes += $(FATE_DNN) +FATE_DNN += fate-dnn-layer-avgpool +fate-dnn-layer-avgpool: $(DNNTESTSDIR)/dnn-layer-avgpool-test$(EXESUF) +fate-dnn-layer-avgpool: CMD = run $(DNNTESTSDIR)/dnn-layer-avgpool-test$(EXESUF) +fate-dnn-layer-avgpool: CMP = null + +FATE-$(CONFIG_DNN) += $(FATE_DNN) fate-dnn: $(FATE_DNN) diff --git a/tests/fate/dnxhd.mak b/tests/fate/dnxhd.mak index 60bfd34ba..59f3f90e9 100644 --- a/tests/fate/dnxhd.mak +++ b/tests/fate/dnxhd.mak @@ -11,9 +11,9 @@ FATE_DNXHD = fate-dnxhd-mbaff \ FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, DNXHD) += $(FATE_DNXHD) fate-dnxhd: $(FATE_DNXHD) $(FATE_VCODEC_DNXHD) -fate-dnxhd-mbaff: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/dnxhd/dnxhd100_cid1260.mov -pix_fmt yuv422p10le -fate-dnxhr-444: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/dnxhd/dnxhr444_cid1270.mov -pix_fmt yuv444p10le -fate-dnxhr-12bit: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/dnxhd/dnxhr_cid1271_12bit.mov -pix_fmt yuv422p12le +fate-dnxhd-mbaff: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/dnxhd/dnxhd100_cid1260.mov -pix_fmt yuv422p10le -vf scale +fate-dnxhr-444: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/dnxhd/dnxhr444_cid1270.mov -pix_fmt yuv444p10le -vf scale +fate-dnxhr-12bit: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/dnxhd/dnxhr_cid1271_12bit.mov -pix_fmt yuv422p12le -vf scale fate-dnxhr-parse: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/dnxhd/dnxhr_cid1274.dnxhr -pix_fmt yuv422p fate-dnxhr-prefix1: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/dnxhd/prefix-256x1536.dnxhr -pix_fmt yuv422p fate-dnxhr-prefix2: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/dnxhd/prefix-256x1716.dnxhr -pix_fmt yuv422p diff --git a/tests/fate/ea.mak b/tests/fate/ea.mak index 9de671ce6..7667102ce 100644 --- a/tests/fate/ea.mak +++ b/tests/fate/ea.mak @@ -1,8 +1,8 @@ FATE_SAMPLES_EA-$(call DEMDEC, EA_CDATA, ADPCM_EA_XAS) += fate-ea-cdata -fate-ea-cdata: CMD = md5 -i $(TARGET_SAMPLES)/ea-cdata/166b084d.46410f77.0009b440.24be960c.cdata -f s16le +fate-ea-cdata: CMD = md5 -i $(TARGET_SAMPLES)/ea-cdata/166b084d.46410f77.0009b440.24be960c.cdata -f s16le -af aresample FATE_SAMPLES_EA-$(call DEMDEC, EA, EACMV) += fate-ea-cmv -fate-ea-cmv: CMD = framecrc -i $(TARGET_SAMPLES)/ea-cmv/TITLE.CMV -pix_fmt rgb24 +fate-ea-cmv: CMD = framecrc -i $(TARGET_SAMPLES)/ea-cmv/TITLE.CMV -pix_fmt rgb24 -vf scale FATE_SAMPLES_EA-$(call DEMDEC, EA, EAMAD) += fate-ea-mad fate-ea-mad: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/NFS6LogoE.mad -an @@ -11,10 +11,10 @@ FATE_SAMPLES_EA-$(call DEMDEC, EA, EATGQ) += fate-ea-tgq fate-ea-tgq: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgq/v27.tgq -an FATE_EA_TGV += fate-ea-tgv-1 -fate-ea-tgv-1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24 -an +fate-ea-tgv-1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24 -an -vf scale FATE_EA_TGV += fate-ea-tgv-2 -fate-ea-tgv-2: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24 -an +fate-ea-tgv-2: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24 -an -vf scale FATE_SAMPLES_EA-$(call DEMDEC, EA, EATGV) += $(FATE_EA_TGV) fate-ea-tgv: $(FATE_EA_TGV) diff --git a/tests/fate/ffmpeg.mak b/tests/fate/ffmpeg.mak index 0b0610f64..4dfb77d25 100644 --- a/tests/fate/ffmpeg.mak +++ b/tests/fate/ffmpeg.mak @@ -4,7 +4,7 @@ fate-mapchan-6ch-extract-2: CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-220 FATE_MAPCHAN-$(CONFIG_CHANNELMAP_FILTER) += fate-mapchan-6ch-extract-2-downmix-mono fate-mapchan-6ch-extract-2-downmix-mono: tests/data/asynth-22050-6.wav -fate-mapchan-6ch-extract-2-downmix-mono: CMD = md5 -i $(TARGET_PATH)/tests/data/asynth-22050-6.wav -map_channel 0.0.1 -map_channel 0.0.0 -ac 1 -fflags +bitexact -f wav +fate-mapchan-6ch-extract-2-downmix-mono: CMD = md5 -auto_conversion_filters -i $(TARGET_PATH)/tests/data/asynth-22050-6.wav -map_channel 0.0.1 -map_channel 0.0.0 -ac 1 -fflags +bitexact -f wav FATE_MAPCHAN-$(CONFIG_CHANNELMAP_FILTER) += fate-mapchan-silent-mono fate-mapchan-silent-mono: tests/data/asynth-22050-1.wav @@ -28,15 +28,15 @@ fate-ffmpeg-filter_complex: CMD = framecrc -filter_complex color=d=1:r=5 -fflags # Ticket 6603 FATE_FFMPEG-$(call ALLYES, AEVALSRC_FILTER ASETNSAMPLES_FILTER AC3_FIXED_ENCODER) += fate-ffmpeg-filter_complex_audio -fate-ffmpeg-filter_complex_audio: CMD = framecrc -filter_complex "aevalsrc=0:d=0.1,asetnsamples=1537" -c ac3_fixed +fate-ffmpeg-filter_complex_audio: CMD = framecrc -auto_conversion_filters -filter_complex "aevalsrc=0:d=0.1,asetnsamples=1537" -c ac3_fixed # Ticket 6375, use case of NoX FATE_SAMPLES_FFMPEG-$(call ALLYES, MOV_DEMUXER PNG_DECODER ALAC_DECODER PCM_S16LE_ENCODER RAWVIDEO_ENCODER) += fate-ffmpeg-attached_pics -fate-ffmpeg-attached_pics: CMD = threads=2 framecrc -i $(TARGET_SAMPLES)/lossless-audio/inside.m4a -c:a pcm_s16le -max_muxing_queue_size 16 +fate-ffmpeg-attached_pics: CMD = threads=2 framecrc -i $(TARGET_SAMPLES)/lossless-audio/inside.m4a -c:a pcm_s16le -max_muxing_queue_size 16 -af aresample FATE_SAMPLES_FFMPEG-$(CONFIG_COLORKEY_FILTER) += fate-ffmpeg-filter_colorkey fate-ffmpeg-filter_colorkey: tests/data/filtergraphs/colorkey -fate-ffmpeg-filter_colorkey: CMD = framecrc -idct simple -fflags +bitexact -flags +bitexact -sws_flags +accurate_rnd+bitexact -i $(TARGET_SAMPLES)/cavs/cavs.mpg -fflags +bitexact -flags +bitexact -sws_flags +accurate_rnd+bitexact -i $(TARGET_SAMPLES)/lena.pnm -an -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/colorkey -sws_flags +accurate_rnd+bitexact -fflags +bitexact -flags +bitexact -qscale 2 -frames:v 10 +fate-ffmpeg-filter_colorkey: CMD = framecrc -auto_conversion_filters -idct simple -fflags +bitexact -flags +bitexact -sws_flags +accurate_rnd+bitexact -i $(TARGET_SAMPLES)/cavs/cavs.mpg -fflags +bitexact -flags +bitexact -sws_flags +accurate_rnd+bitexact -i $(TARGET_SAMPLES)/lena.pnm -an -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/colorkey -sws_flags +accurate_rnd+bitexact -fflags +bitexact -flags +bitexact -qscale 2 -frames:v 10 FATE_FFMPEG-$(CONFIG_COLOR_FILTER) += fate-ffmpeg-lavfi fate-ffmpeg-lavfi: CMD = framecrc -lavfi color=d=1:r=5 -fflags +bitexact @@ -50,7 +50,7 @@ fate-force_key_frames: CMD = enc_dec \ FATE_SAMPLES_FFMPEG-$(call ALLYES, VOBSUB_DEMUXER DVDSUB_DECODER AVFILTER OVERLAY_FILTER DVDSUB_ENCODER) += fate-sub2video fate-sub2video: tests/data/vsynth_lena.yuv -fate-sub2video: CMD = framecrc \ +fate-sub2video: CMD = framecrc -auto_conversion_filters \ -f rawvideo -r 5 -s 352x288 -pix_fmt yuv420p -i $(TARGET_PATH)/tests/data/vsynth_lena.yuv \ -ss 132 -i $(TARGET_SAMPLES)/sub/vobsub.idx \ -filter_complex "sws_flags=+accurate_rnd+bitexact\;[0:0]scale=720:480[v]\;[v][1:0]overlay[v2]" \ @@ -59,7 +59,7 @@ fate-sub2video: CMD = framecrc \ # Very basic sub2video example, decode and convert to AVFrame with sub2video. # Attempt to not touch timestamps. FATE_SAMPLES_FFMPEG-$(call ALLYES, VOBSUB_DEMUXER DVDSUB_DECODER AVFILTER) += fate-sub2video_basic -fate-sub2video_basic: CMD = framecrc \ +fate-sub2video_basic: CMD = framecrc -auto_conversion_filters \ -i $(TARGET_SAMPLES)/sub/vobsub.idx \ -vsync passthrough -copyts \ -filter_complex "sws_flags=+accurate_rnd+bitexact\;[0:s:0]scale" \ @@ -68,7 +68,7 @@ fate-sub2video_basic: CMD = framecrc \ # Time-limited run with a sample that doesn't require seeking and # contains samples within the initial period. FATE_SAMPLES_FFMPEG-$(call ALLYES, SUP_DEMUXER PGSSUB_DECODER AVFILTER) += fate-sub2video_time_limited -fate-sub2video_time_limited: CMD = framecrc \ +fate-sub2video_time_limited: CMD = framecrc -auto_conversion_filters \ -i $(TARGET_SAMPLES)/sub/pgs_sub.sup \ -vsync passthrough -copyts \ -t 15 \ @@ -82,8 +82,8 @@ fate-unknown_layout-pcm: CMD = md5 \ FATE_FFMPEG-$(call ALLYES, PCM_S16LE_DEMUXER AC3_MUXER PCM_S16LE_DECODER AC3_FIXED_ENCODER) += fate-unknown_layout-ac3 fate-unknown_layout-ac3: $(AREF) -fate-unknown_layout-ac3: CMD = md5 \ - -guess_layout_max 0 -f s16le -ac 1 -ar 44100 -i $(TARGET_PATH)/$(AREF) \ +fate-unknown_layout-ac3: CMD = md5 -auto_conversion_filters \ + -guess_layout_max 0 -f s32le -ac 1 -ar 44100 -i $(TARGET_PATH)/$(AREF) \ -f ac3 -flags +bitexact -c ac3_fixed @@ -100,12 +100,12 @@ fate-copy-trac236: CMD = transcode mov $(TARGET_SAMPLES)/mov/fcp_export8-236.mov FATE_STREAMCOPY-$(call ALLYES, MPEGTS_DEMUXER MXF_MUXER PCM_S16LE_ENCODER) += fate-copy-trac4914 fate-copy-trac4914: $(SAMPLES)/mpeg2/xdcam8mp2-1s_small.ts fate-copy-trac4914: CMD = transcode mpegts $(TARGET_SAMPLES)/mpeg2/xdcam8mp2-1s_small.ts\ - mxf "-c:a pcm_s16le -c:v copy" + mxf "-c:a pcm_s16le -af aresample -c:v copy" FATE_STREAMCOPY-$(call ALLYES, MPEGTS_DEMUXER AVI_MUXER) += fate-copy-trac4914-avi fate-copy-trac4914-avi: $(SAMPLES)/mpeg2/xdcam8mp2-1s_small.ts fate-copy-trac4914-avi: CMD = transcode mpegts $(TARGET_SAMPLES)/mpeg2/xdcam8mp2-1s_small.ts\ - avi "-c:a copy -c:v copy" + avi "-c:a copy -c:v copy" "-af aresample" FATE_STREAMCOPY-$(call ALLYES, H264_DEMUXER AVI_MUXER) += fate-copy-trac2211-avi fate-copy-trac2211-avi: $(SAMPLES)/h264/bbc2.sample.h264 diff --git a/tests/fate/fft.mak b/tests/fate/fft.mak index 5da6e687e..76701dcce 100644 --- a/tests/fate/fft.mak +++ b/tests/fate/fft.mak @@ -26,27 +26,7 @@ FATE_FFT_ALL = $(FATE_DCT-yes) $(FATE_FFT-yes) $(FATE_MDCT-yes) $(FATE_RDFT-yes) $(FATE_FFT_ALL): libavcodec/tests/fft$(EXESUF) $(FATE_FFT_ALL): CMD = run libavcodec/tests/fft$(EXESUF) $(CPUFLAGS:%=-c%) $(ARGS) -define DEF_FFT_FIXED -FATE_FFT_FIXED-$(CONFIG_FFT) += fate-fft-fixed-$(1) fate-ifft-fixed-$(1) -FATE_MDCT_FIXED-$(CONFIG_MDCT) += fate-mdct-fixed-$(1) fate-imdct-fixed-$(1) - -fate-fft-fixed-$(1): ARGS = -n$(1) -fate-ifft-fixed-$(1): ARGS = -n$(1) -i -fate-mdct-fixed-$(1): ARGS = -n$(1) -m -fate-imdct-fixed-$(1): ARGS = -n$(1) -m -i -endef - -$(foreach N, 4 5 6 7 8 9 10 11 12, $(eval $(call DEF_FFT_FIXED,$(N)))) - -fate-fft-fixed: $(FATE_FFT_FIXED-yes) -fate-mdct-fixed: $(FATE_MDCT_FIXED-yes) - -FATE_FFT_FIXED_ALL = $(FATE_FFT_FIXED-yes) $(FATE_MDCT_FIXED-yes) - -$(FATE_FFT_FIXED_ALL): libavcodec/tests/fft-fixed$(EXESUF) -$(FATE_FFT_FIXED_ALL): CMD = run libavcodec/tests/fft-fixed$(EXESUF) $(CPUFLAGS:%=-c%) $(ARGS) - -$(FATE_FFT_ALL) $(FATE_FFT_FIXED_ALL): CMP = null +$(FATE_FFT_ALL): CMP = null define DEF_FFT_FIXED32 FATE_FFT_FIXED32 += fate-fft-fixed32-$(1) fate-ifft-fixed32-$(1) \ @@ -95,9 +75,9 @@ $(FATE_AV_FFT_ALL): CMD = run libavcodec/tests/avfft$(EXESUF) $(CPUFLAGS:%=-c%) $(FATE_AV_FFT_ALL): CMP = null fate-dct: fate-dct-float -fate-fft: fate-fft-float fate-fft-fixed fate-fft-fixed32 -fate-mdct: fate-mdct-float fate-mdct-fixed +fate-fft: fate-fft-float fate-fft-fixed32 +fate-mdct: fate-mdct-float fate-rdft: fate-rdft-float -FATE-$(call ALLYES, AVCODEC FFT MDCT) += $(FATE_FFT_ALL) $(FATE_FFT_FIXED_ALL) $(FATE_FFT_FIXED32) $(FATE_AV_FFT_ALL) -fate-fft-all: $(FATE_FFT_ALL) $(FATE_FFT_FIXED_ALL) $(FATE_FFT_FIXED32) $(FATE_AV_FFT_ALL) +FATE-$(call ALLYES, AVCODEC FFT MDCT) += $(FATE_FFT_ALL) $(FATE_FFT_FIXED32) $(FATE_AV_FFT_ALL) +fate-fft-all: $(FATE_FFT_ALL) $(FATE_FFT_FIXED32) $(FATE_AV_FFT_ALL) diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak index 79b1536df..8b38ee5e7 100644 --- a/tests/fate/filter-audio.mak +++ b/tests/fate/filter-audio.mak @@ -1,22 +1,22 @@ FATE_AFILTER-$(call FILTERDEMDECENCMUX, ADELAY, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-adelay fate-filter-adelay: tests/data/asynth-44100-2.wav fate-filter-adelay: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-adelay: CMD = framecrc -i $(SRC) -af adelay=42 +fate-filter-adelay: CMD = framecrc -i $(SRC) -af aresample,adelay=42,aresample FATE_AFILTER-$(call FILTERDEMDECENCMUX, AECHO, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-aecho fate-filter-aecho: tests/data/asynth-44100-2.wav fate-filter-aecho: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-aecho: CMD = framecrc -i $(SRC) -af aecho=0.5:0.5:32:0.5 +fate-filter-aecho: CMD = framecrc -i $(SRC) -af aresample,aecho=0.5:0.5:32:0.5,aresample FATE_FILTER_AEMPHASIS += fate-filter-aemphasis-50fm fate-filter-aemphasis-50fm: tests/data/asynth-44100-2.wav fate-filter-aemphasis-50fm: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-aemphasis-50fm: CMD = framecrc -i $(SRC) -af aemphasis=1:5:reproduction:50fm +fate-filter-aemphasis-50fm: CMD = framecrc -i $(SRC) -af aresample,aemphasis=1:5:reproduction:50fm,aresample FATE_FILTER_AEMPHASIS += fate-filter-aemphasis-75kf fate-filter-aemphasis-75kf: tests/data/asynth-44100-2.wav fate-filter-aemphasis-75kf: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-aemphasis-75kf: CMD = framecrc -i $(SRC) -af aemphasis=2:8:reproduction:75kf +fate-filter-aemphasis-75kf: CMD = framecrc -i $(SRC) -af aresample,aemphasis=2:8:reproduction:75kf,aresample FATE_AFILTER-$(call FILTERDEMDECENCMUX, AEMPHASIS, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_FILTER_AEMPHASIS) @@ -61,12 +61,12 @@ fate-filter-acrossfade: CMD = framecrc -i $(SRC) -i $(SRC2) -filter_complex acro FATE_AFILTER-$(call FILTERDEMDECENCMUX, AFADE, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-agate fate-filter-agate: tests/data/asynth-44100-2.wav fate-filter-agate: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-agate: CMD = framecrc -i $(SRC) -af agate=level_in=10:range=0:threshold=1:ratio=1:attack=1:knee=1:makeup=4 +fate-filter-agate: CMD = framecrc -i $(SRC) -af aresample,agate=level_in=10:range=0:threshold=1:ratio=1:attack=1:knee=1:makeup=4,aresample FATE_AFILTER-$(call FILTERDEMDECENCMUX, AFADE, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-alimiter fate-filter-alimiter: tests/data/asynth-44100-2.wav fate-filter-alimiter: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-alimiter: CMD = framecrc -i $(SRC) -af alimiter=level_in=1:level_out=2:limit=0.2 +fate-filter-alimiter: CMD = framecrc -i $(SRC) -af aresample,alimiter=level_in=1:level_out=2:limit=0.2,aresample FATE_AFILTER-$(call FILTERDEMDECENCMUX, AMERGE, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-amerge fate-filter-amerge: tests/data/asynth-44100-1.wav @@ -82,7 +82,7 @@ FATE_AFILTER-$(call FILTERDEMDECENCMUX, ANEQUALIZER, WAV, PCM_S16LE, PCM_S16LE, fate-filter-anequalizer: tests/data/asynth-44100-2.wav fate-filter-anequalizer: tests/data/filtergraphs/anequalizer fate-filter-anequalizer: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-anequalizer: CMD = framecrc -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/anequalizer +fate-filter-anequalizer: CMD = framecrc -auto_conversion_filters -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/anequalizer FATE_AFILTER-$(call FILTERDEMDECENCMUX, ASETNSAMPLES, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-asetnsamples-pad fate-filter-asetnsamples-pad: tests/data/asynth-44100-2.wav @@ -102,28 +102,28 @@ fate-filter-asetrate: CMD = framecrc -i $(SRC) -frames:a 20 -af asetrate=20000 FATE_AFILTER-$(call FILTERDEMDECENCMUX, CHORUS, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-chorus fate-filter-chorus: tests/data/asynth-22050-1.wav fate-filter-chorus: SRC = $(TARGET_PATH)/tests/data/asynth-22050-1.wav -fate-filter-chorus: CMD = framecrc -i $(SRC) -frames:a 10 -af chorus=0.050001:0.050002:64:0.050001:0.025003:2.00004 +fate-filter-chorus: CMD = framecrc -i $(SRC) -frames:a 10 -af aresample,chorus=0.050001:0.050002:64:0.050001:0.025003:2.00004,aresample FATE_AFILTER-$(call FILTERDEMDECENCMUX, DCSHIFT, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-dcshift fate-filter-dcshift: tests/data/asynth-44100-2.wav fate-filter-dcshift: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-dcshift: CMD = framecrc -i $(SRC) -frames:a 20 -af dcshift=shift=0.25:limitergain=0.05 +fate-filter-dcshift: CMD = framecrc -i $(SRC) -frames:a 20 -af aresample,dcshift=shift=0.25:limitergain=0.05,aresample FATE_AFILTER-$(call FILTERDEMDECENCMUX, EARWAX, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-earwax fate-filter-earwax: tests/data/asynth-44100-2.wav fate-filter-earwax: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-earwax: CMD = framecrc -i $(SRC) -frames:a 20 -af earwax +fate-filter-earwax: CMD = framecrc -i $(SRC) -frames:a 20 -af aresample,earwax,aresample FATE_AFILTER-$(call FILTERDEMDECENCMUX, EXTRASTEREO, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-extrastereo fate-filter-extrastereo: tests/data/asynth-44100-2.wav fate-filter-extrastereo: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-extrastereo: CMD = framecrc -i $(SRC) -frames:a 20 -af extrastereo=m=2 +fate-filter-extrastereo: CMD = framecrc -i $(SRC) -frames:a 20 -af aresample,extrastereo=m=2,aresample FATE_AFILTER-$(call FILTERDEMDECENCMUX, FIREQUALIZER ATRIM VOLUME, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-firequalizer fate-filter-firequalizer: tests/data/asynth-44100-2.wav fate-filter-firequalizer: tests/data/filtergraphs/firequalizer fate-filter-firequalizer: REF = tests/data/asynth-44100-2.wav -fate-filter-firequalizer: CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-44100-2.wav -filter_script $(TARGET_PATH)/tests/data/filtergraphs/firequalizer -f wav -c:a pcm_s16le - +fate-filter-firequalizer: CMD = ffmpeg -auto_conversion_filters -i $(TARGET_PATH)/tests/data/asynth-44100-2.wav -filter_script $(TARGET_PATH)/tests/data/filtergraphs/firequalizer -f wav -c:a pcm_s16le - fate-filter-firequalizer: CMP = oneoff fate-filter-firequalizer: CMP_UNIT = s16 fate-filter-firequalizer: SIZE_TOLERANCE = 1058400 - 1097208 @@ -180,16 +180,16 @@ fate-filter-pan-downmix2: CMD = framecrc -ss 3.14 -i $(SRC) -frames:a 20 -filter FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, SILENCEREMOVE, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-silenceremove fate-filter-silenceremove: SRC = $(TARGET_SAMPLES)/audio-reference/divertimenti_2ch_96kHz_s24.wav -fate-filter-silenceremove: CMD = framecrc -i $(SRC) -frames:a 30 -af silenceremove=start_periods=0:start_duration=0:start_threshold=0:stop_periods=-1:stop_duration=0:stop_threshold=-90dB +fate-filter-silenceremove: CMD = framecrc -i $(SRC) -frames:a 30 -af aresample,silenceremove=start_periods=0:start_duration=0:start_threshold=0:stop_periods=-1:stop_duration=0:stop_threshold=-90dB,aresample FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, STEREOTOOLS, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-stereotools fate-filter-stereotools: SRC = $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -fate-filter-stereotools: CMD = framecrc -i $(SRC) -frames:a 20 -af stereotools=mlev=0.015625 +fate-filter-stereotools: CMD = framecrc -i $(SRC) -frames:a 20 -af aresample,stereotools=mlev=0.015625,aresample FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, TREMOLO, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-tremolo fate-filter-tremolo: tests/data/asynth-44100-2.wav fate-filter-tremolo: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-tremolo: CMD = ffmpeg -i $(SRC) -frames:a 20 -af tremolo -f wav -f s16le - +fate-filter-tremolo: CMD = ffmpeg -auto_conversion_filters -i $(SRC) -frames:a 20 -af tremolo -f wav -f s16le - fate-filter-tremolo: REF = $(SAMPLES)/filter/tremolo.pcm fate-filter-tremolo: CMP = oneoff fate-filter-tremolo: CMP_UNIT = s16 @@ -198,7 +198,7 @@ FATE_AFILTER-$(call FILTERDEMDECENCMUX, COMPAND, WAV, PCM_S16LE, PCM_S16LE, WAV) fate-filter-compand: tests/data/asynth-44100-2.wav fate-filter-compand: tests/data/filtergraphs/compand fate-filter-compand: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-compand: CMD = framecrc -i $(SRC) -frames:a 20 -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/compand +fate-filter-compand: CMD = framecrc -auto_conversion_filters -i $(SRC) -frames:a 20 -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/compand tests/data/hls-list.m3u8: TAG = GEN tests/data/hls-list.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data @@ -208,7 +208,7 @@ tests/data/hls-list.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data FATE_AFILTER-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-filter-hls fate-filter-hls: tests/data/hls-list.m3u8 -fate-filter-hls: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls-list.m3u8 +fate-filter-hls: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls-list.m3u8 -af aresample tests/data/hls-list-append.m3u8: TAG = GEN tests/data/hls-list-append.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data @@ -222,20 +222,20 @@ tests/data/hls-list-append.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data FATE_AFILTER-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-filter-hls-append fate-filter-hls-append: tests/data/hls-list-append.m3u8 -fate-filter-hls-append: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls-list-append.m3u8 -af asetpts=N*23 +fate-filter-hls-append: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls-list-append.m3u8 -af asetpts=N*23,aresample FATE_AMIX += fate-filter-amix-simple -fate-filter-amix-simple: CMD = ffmpeg -filter_complex amix -i $(SRC) -ss 3 -i $(SRC1) -f f32le - +fate-filter-amix-simple: CMD = ffmpeg -auto_conversion_filters -filter_complex amix -i $(SRC) -ss 3 -i $(SRC1) -f f32le - fate-filter-amix-simple: REF = $(SAMPLES)/filter/amix_simple.pcm FATE_AMIX += fate-filter-amix-first -fate-filter-amix-first: CMD = ffmpeg -filter_complex amix=duration=first -ss 4 -i $(SRC) -i $(SRC1) -f f32le - +fate-filter-amix-first: CMD = ffmpeg -auto_conversion_filters -filter_complex amix=duration=first -ss 4 -i $(SRC) -i $(SRC1) -f f32le - fate-filter-amix-first: REF = $(SAMPLES)/filter/amix_first.pcm FATE_AMIX += fate-filter-amix-transition fate-filter-amix-transition: tests/data/asynth-44100-2-3.wav fate-filter-amix-transition: SRC2 = $(TARGET_PATH)/tests/data/asynth-44100-2-3.wav -fate-filter-amix-transition: CMD = ffmpeg -filter_complex amix=inputs=3:dropout_transition=0.5 -i $(SRC) -ss 2 -i $(SRC1) -ss 4 -i $(SRC2) -f f32le - +fate-filter-amix-transition: CMD = ffmpeg -auto_conversion_filters -filter_complex amix=inputs=3:dropout_transition=0.5 -i $(SRC) -ss 2 -i $(SRC1) -ss 4 -i $(SRC2) -f f32le - fate-filter-amix-transition: REF = $(SAMPLES)/filter/amix_transition.pcm FATE_AFILTER_SAMPLES-$(call FILTERDEMDECENCMUX, AMIX, WAV, PCM_S16LE, PCM_F32LE, PCM_F32LE) += $(FATE_AMIX) @@ -271,7 +271,7 @@ FATE_FILTER_CHANNELMAP += fate-filter-channelmap-one-int fate-filter-channelmap-one-int: tests/data/filtergraphs/channelmap_one_int fate-filter-channelmap-one-int: SRC = $(TARGET_PATH)/tests/data/asynth-44100-6.wav fate-filter-channelmap-one-int: tests/data/asynth-44100-6.wav -fate-filter-channelmap-one-int: CMD = md5 -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap_one_int -f wav -fflags +bitexact +fate-filter-channelmap-one-int: CMD = md5 -auto_conversion_filters -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap_one_int -f wav -fflags +bitexact fate-filter-channelmap-one-int: CMP = oneline fate-filter-channelmap-one-int: REF = 8cfe553d65ed4696756d8c1b824fcdd3 @@ -279,7 +279,7 @@ FATE_FILTER_CHANNELMAP += fate-filter-channelmap-one-str fate-filter-channelmap-one-str: tests/data/filtergraphs/channelmap_one_str fate-filter-channelmap-one-str: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav fate-filter-channelmap-one-str: tests/data/asynth-44100-2.wav -fate-filter-channelmap-one-str: CMD = md5 -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap_one_str -f wav -fflags +bitexact +fate-filter-channelmap-one-str: CMD = md5 -auto_conversion_filters -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap_one_str -f wav -fflags +bitexact fate-filter-channelmap-one-str: CMP = oneline fate-filter-channelmap-one-str: REF = 0ea3052e482c95d5d3bd9da6dac1b5fa @@ -288,7 +288,7 @@ FATE_AFILTER-$(call FILTERDEMDECENCMUX, CHANNELMAP, WAV, PCM_S16LE, PCM_S16LE, W FATE_AFILTER-$(call FILTERDEMDECENCMUX, CHANNELSPLIT, WAV, PCM_S16LE, PCM_S16LE, PCM_S16LE) += fate-filter-channelsplit fate-filter-channelsplit: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav fate-filter-channelsplit: tests/data/asynth-44100-2.wav -fate-filter-channelsplit: CMD = md5 -i $(SRC) -filter_complex channelsplit -f s16le +fate-filter-channelsplit: CMD = md5 -auto_conversion_filters -i $(SRC) -filter_complex channelsplit -f s16le fate-filter-channelsplit: CMP = oneline fate-filter-channelsplit: REF = d92988d0fe2dd92236763f47b07ab597 @@ -296,7 +296,7 @@ FATE_AFILTER-$(call FILTERDEMDECENCMUX, JOIN, WAV, PCM_S16LE, PCM_S16LE, PCM_S16 fate-filter-join: SRC1 = $(TARGET_PATH)/tests/data/asynth-44100-2.wav fate-filter-join: SRC2 = $(TARGET_PATH)/tests/data/asynth-44100-3.wav fate-filter-join: tests/data/asynth-44100-2.wav tests/data/asynth-44100-3.wav -fate-filter-join: CMD = md5 -i $(SRC1) -i $(SRC2) -filter_complex join=channel_layout=5c -f s16le +fate-filter-join: CMD = md5 -auto_conversion_filters -i $(SRC1) -i $(SRC2) -filter_complex join=channel_layout=5c -f s16le fate-filter-join: CMP = oneline fate-filter-join: REF = 88b0d24a64717ba8635b29e8dac6ecd8 diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index cfeb53e53..a0d645cc4 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -1,5 +1,5 @@ FATE_FILTER_SAMPLES-$(call ALLYES, SMJPEG_DEMUXER MJPEG_DECODER PERMS_FILTER OWDENOISE_FILTER) += fate-filter-owdenoise-sample -fate-filter-owdenoise-sample: CMD = ffmpeg -idct simple -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -vf "trim=duration=0.5,perms=random,owdenoise=10:20:20:enable=not(between(t\,0.2\,1.2))" -an -f rawvideo - +fate-filter-owdenoise-sample: CMD = ffmpeg -auto_conversion_filters -idct simple -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -vf "trim=duration=0.5,perms=random,owdenoise=10:20:20:enable=not(between(t\,0.2\,1.2))" -an -f rawvideo - fate-filter-owdenoise-sample: REF = $(SAMPLES)/filter-reference/owdenoise-scenwin.raw fate-filter-owdenoise-sample: CMP_TARGET = 1 fate-filter-owdenoise-sample: FUZZ = 3539 @@ -15,10 +15,10 @@ FATE_YADIF += fate-filter-yadif-mode1 fate-filter-yadif-mode1: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -frames:v 59 -vf yadif=1 FATE_YADIF += fate-filter-yadif10 -fate-filter-yadif10: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -flags bitexact -pix_fmt yuv420p10le -frames:v 30 -vf yadif=0 +fate-filter-yadif10: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -flags bitexact -pix_fmt yuv420p10le -frames:v 30 -vf yadif=0,scale FATE_YADIF += fate-filter-yadif16 -fate-filter-yadif16: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -flags bitexact -pix_fmt yuv420p16le -frames:v 30 -vf yadif=0 +fate-filter-yadif16: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -flags bitexact -pix_fmt yuv420p16le -frames:v 30 -vf yadif=0,scale FATE_FILTER_SAMPLES-$(call FILTERDEMDEC, YADIF, MPEGTS, MPEG2VIDEO) += $(FATE_YADIF) @@ -42,25 +42,25 @@ FATE_FILTER_SAMPLES-$(call ALLYES, CODECVIEW_FILTER RM_DEMUXER RV40_DECODER) += fate-filter-codecview-mvs: CMD = framecrc -flags2 +export_mvs -i $(TARGET_SAMPLES)/real/spygames-2MB.rmvb -vf codecview=mv=pf+bf+bb -frames:v 60 -an FATE_FILTER_SAMPLES-$(call ALLYES, SHOWPALETTE_FILTER FLIC_DEMUXER FLIC_DECODER) += fate-filter-showpalette -fate-filter-showpalette: CMD = framecrc -i $(TARGET_SAMPLES)/fli/fli-engines.fli -vf showpalette=3 -pix_fmt bgra +fate-filter-showpalette: CMD = framecrc -i $(TARGET_SAMPLES)/fli/fli-engines.fli -vf showpalette=3,scale -pix_fmt bgra FATE_FILTER_PALETTEGEN += fate-filter-palettegen-1 -fate-filter-palettegen-1: CMD = framecrc -i $(TARGET_SAMPLES)/filter/anim.mkv -vf palettegen -pix_fmt bgra +fate-filter-palettegen-1: CMD = framecrc -i $(TARGET_SAMPLES)/filter/anim.mkv -vf scale,palettegen,scale -pix_fmt bgra FATE_FILTER_PALETTEGEN += fate-filter-palettegen-2 -fate-filter-palettegen-2: CMD = framecrc -i $(TARGET_SAMPLES)/filter/anim.mkv -vf palettegen=max_colors=128:reserve_transparent=0:stats_mode=diff -pix_fmt bgra +fate-filter-palettegen-2: CMD = framecrc -i $(TARGET_SAMPLES)/filter/anim.mkv -vf scale,palettegen=max_colors=128:reserve_transparent=0:stats_mode=diff,scale -pix_fmt bgra fate-filter-palettegen: $(FATE_FILTER_PALETTEGEN) FATE_FILTER_SAMPLES-$(call ALLYES, PALETTEGEN_FILTER MATROSKA_DEMUXER H264_DECODER) += $(FATE_FILTER_PALETTEGEN) FATE_FILTER_PALETTEUSE += fate-filter-paletteuse-nodither -fate-filter-paletteuse-nodither: CMD = framecrc -i $(TARGET_SAMPLES)/filter/anim.mkv -i $(TARGET_SAMPLES)/filter/anim-palette.png -lavfi paletteuse=none -pix_fmt bgra +fate-filter-paletteuse-nodither: CMD = framecrc -auto_conversion_filters -i $(TARGET_SAMPLES)/filter/anim.mkv -i $(TARGET_SAMPLES)/filter/anim-palette.png -lavfi paletteuse=none -pix_fmt bgra FATE_FILTER_PALETTEUSE += fate-filter-paletteuse-bayer -fate-filter-paletteuse-bayer: CMD = framecrc -i $(TARGET_SAMPLES)/filter/anim.mkv -i $(TARGET_SAMPLES)/filter/anim-palette.png -lavfi paletteuse=bayer -pix_fmt bgra +fate-filter-paletteuse-bayer: CMD = framecrc -auto_conversion_filters -i $(TARGET_SAMPLES)/filter/anim.mkv -i $(TARGET_SAMPLES)/filter/anim-palette.png -lavfi paletteuse=bayer -pix_fmt bgra FATE_FILTER_PALETTEUSE += fate-filter-paletteuse-sierra2_4a -fate-filter-paletteuse-sierra2_4a: CMD = framecrc -i $(TARGET_SAMPLES)/filter/anim.mkv -i $(TARGET_SAMPLES)/filter/anim-palette.png -lavfi paletteuse=sierra2_4a:diff_mode=rectangle -pix_fmt bgra +fate-filter-paletteuse-sierra2_4a: CMD = framecrc -auto_conversion_filters -i $(TARGET_SAMPLES)/filter/anim.mkv -i $(TARGET_SAMPLES)/filter/anim-palette.png -lavfi paletteuse=sierra2_4a:diff_mode=rectangle -pix_fmt bgra fate-filter-paletteuse: $(FATE_FILTER_PALETTEUSE) FATE_FILTER_SAMPLES-$(call ALLYES, PALETTEUSE_FILTER MATROSKA_DEMUXER H264_DECODER IMAGE2_DEMUXER PNG_DECODER) += $(FATE_FILTER_PALETTEUSE) @@ -108,7 +108,7 @@ FATE_FILTER-$(call ALLYES, LAVFI_INDEV YUVTESTSRC_FILTER) += fate-filter-yuvtest fate-filter-yuvtestsrc-yuv444p: CMD = framecrc -lavfi yuvtestsrc=rate=5:duration=1 -pix_fmt yuv444p FATE_FILTER-$(call ALLYES, LAVFI_INDEV YUVTESTSRC_FILTER) += fate-filter-yuvtestsrc-yuv444p12 -fate-filter-yuvtestsrc-yuv444p12: CMD = framecrc -lavfi yuvtestsrc=rate=5:duration=1,format=yuv444p12 -pix_fmt yuv444p12le +fate-filter-yuvtestsrc-yuv444p12: CMD = framecrc -lavfi yuvtestsrc=rate=5:duration=1,format=yuv444p12,scale -pix_fmt yuv444p12le FATE_FILTER-$(call ALLYES, AVDEVICE TESTSRC_FILTER FORMAT_FILTER CONCAT_FILTER SCALE_FILTER) += fate-filter-lavd-scalenorm fate-filter-lavd-scalenorm: tests/data/filtergraphs/scalenorm @@ -119,18 +119,18 @@ fate-filter-framerate-up: CMD = framecrc -lavfi testsrc2=r=2:d=10,framerate=fps= fate-filter-framerate-down: CMD = framecrc -lavfi testsrc2=r=2:d=10,framerate=fps=1 -t 1 FATE_FILTER-$(call ALLYES, FRAMERATE_FILTER TESTSRC2_FILTER FORMAT_FILTER) += fate-filter-framerate-12bit-up fate-filter-framerate-12bit-down -fate-filter-framerate-12bit-up: CMD = framecrc -lavfi testsrc2=r=50:d=1,format=pix_fmts=yuv422p12le,framerate=fps=60 -t 1 -pix_fmt yuv422p12le -fate-filter-framerate-12bit-down: CMD = framecrc -lavfi testsrc2=r=60:d=1,format=pix_fmts=yuv422p12le,framerate=fps=50 -t 1 -pix_fmt yuv422p12le +fate-filter-framerate-12bit-up: CMD = framecrc -lavfi testsrc2=r=50:d=1,format=pix_fmts=yuv422p12le,scale,framerate=fps=60,scale -t 1 -pix_fmt yuv422p12le +fate-filter-framerate-12bit-down: CMD = framecrc -lavfi testsrc2=r=60:d=1,format=pix_fmts=yuv422p12le,scale,framerate=fps=50,scale -t 1 -pix_fmt yuv422p12le FATE_FILTER-$(call ALLYES, MINTERPOLATE_FILTER TESTSRC2_FILTER) += fate-filter-minterpolate-up fate-filter-minterpolate-down -fate-filter-minterpolate-up: CMD = framecrc -lavfi testsrc2=r=2:d=10,framerate=fps=10 -t 1 -fate-filter-minterpolate-down: CMD = framecrc -lavfi testsrc2=r=2:d=10,framerate=fps=1 -t 1 +fate-filter-minterpolate-up: CMD = framecrc -lavfi testsrc2=r=2:d=10,minterpolate=fps=10 -t 1 +fate-filter-minterpolate-down: CMD = framecrc -lavfi testsrc2=r=2:d=10,minterpolate=fps=1 -t 1 FATE_FILTER_VSYNTH-$(CONFIG_BOXBLUR_FILTER) += fate-filter-boxblur fate-filter-boxblur: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf boxblur=2:1 FATE_FILTER_VSYNTH-$(call ALLYES, COLORCHANNELMIXER_FILTER FORMAT_FILTER PERMS_FILTER) += fate-filter-colorchannelmixer -fate-filter-colorchannelmixer: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=rgb24,perms=random,colorchannelmixer=.31415927:.4:.31415927:0:.27182818:.8:.27182818:0:.2:.6:.2:0 -flags +bitexact -sws_flags +accurate_rnd+bitexact +fate-filter-colorchannelmixer: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf scale,format=rgb24,perms=random,colorchannelmixer=.31415927:.4:.31415927:0:.27182818:.8:.27182818:0:.2:.6:.2:0 -flags +bitexact -sws_flags +accurate_rnd+bitexact FATE_FILTER_VSYNTH-$(CONFIG_DRAWBOX_FILTER) += fate-filter-drawbox fate-filter-drawbox: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf drawbox=224:24:88:72:red@0.5 @@ -139,7 +139,7 @@ FATE_FILTER_VSYNTH-$(CONFIG_FADE_FILTER) += fate-filter-fade fate-filter-fade: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf fade=in:5:15,fade=out:30:15 FATE_FILTER_VSYNTH-$(call ALLYES, INTERLACE_FILTER FIELDORDER_FILTER) += fate-filter-fieldorder -fate-filter-fieldorder: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace=tff,fieldorder=bff -sws_flags +accurate_rnd+bitexact +fate-filter-fieldorder: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace=tff,scale,fieldorder=bff -sws_flags +accurate_rnd+bitexact define FATE_FPFILTER_SUITE FATE_FILTER_FRAMEPACK += fate-filter-framepack-$(1) @@ -197,7 +197,7 @@ FATE_FILTER_VSYNTH-$(CONFIG_VECTORSCOPE_FILTER) += fate-filter-vectorscope_color fate-filter-vectorscope_color4: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf vectorscope=color4 -sws_flags +accurate_rnd+bitexact -frames:v 3 FATE_FILTER_VSYNTH-$(CONFIG_VECTORSCOPE_FILTER) += fate-filter-vectorscope_xy -fate-filter-vectorscope_xy: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf vectorscope=x=0:y=1 -sws_flags +accurate_rnd+bitexact -frames:v 3 +fate-filter-vectorscope_xy: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -vf vectorscope=x=0:y=1 -sws_flags +accurate_rnd+bitexact -frames:v 3 FATE_FILTER_VSYNTH-$(CONFIG_MERGEPLANES_FILTER) += fate-filter-mergeplanes fate-filter-mergeplanes: tests/data/filtergraphs/mergeplanes @@ -217,46 +217,54 @@ fate-filter-overlay: CMD = framecrc -c:v pgmyuv -i $(SRC) -c:v pgmyuv -i $(SRC) FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_rgb fate-filter-overlay_rgb: tests/data/filtergraphs/overlay_rgb -fate-filter-overlay_rgb: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_rgb +fate-filter-overlay_rgb: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_rgb FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv420 fate-filter-overlay_yuv420: tests/data/filtergraphs/overlay_yuv420 fate-filter-overlay_yuv420: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv420 +FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv420p10 +fate-filter-overlay_yuv420p10: tests/data/filtergraphs/overlay_yuv420p10 +fate-filter-overlay_yuv420p10: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv420p10 -pix_fmt yuv420p10le -frames:v 3 + FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_nv12 fate-filter-overlay_nv12: tests/data/filtergraphs/overlay_nv12 -fate-filter-overlay_nv12: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_nv12 +fate-filter-overlay_nv12: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_nv12 fate-filter-overlay_nv12: REF = $(SRC_PATH)/tests/ref/fate/filter-overlay_yuv420 FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_nv21 fate-filter-overlay_nv21: tests/data/filtergraphs/overlay_nv21 -fate-filter-overlay_nv21: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_nv21 +fate-filter-overlay_nv21: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_nv21 fate-filter-overlay_nv21: REF = $(SRC_PATH)/tests/ref/fate/filter-overlay_yuv420 FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv422 fate-filter-overlay_yuv422: tests/data/filtergraphs/overlay_yuv422 -fate-filter-overlay_yuv422: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv422 +fate-filter-overlay_yuv422: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv422 + +FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv422p10 +fate-filter-overlay_yuv422p10: tests/data/filtergraphs/overlay_yuv422p10 +fate-filter-overlay_yuv422p10: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv422p10 -pix_fmt yuv422p10le -frames:v 3 FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv444 fate-filter-overlay_yuv444: tests/data/filtergraphs/overlay_yuv444 -fate-filter-overlay_yuv444: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv444 +fate-filter-overlay_yuv444: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv444 FATE_FILTER_OVERLAY_ALPHA += fate-filter-overlay_yuv420_yuva420 fate-filter-overlay_yuv422_yuva422 fate-filter-overlay_yuv444_yuva444 fate-filter-overlay_rgb_rgba fate-filter-overlay_gbrp_gbrap FATE_FILTER_OVERLAY_ALPHA += fate-filter-overlay_yuva420_yuva420 fate-filter-overlay_yuva422_yuva422 fate-filter-overlay_yuva444_yuva444 fate-filter-overlay_rgba_rgba fate-filter-overlay_gbrap_gbrap $(FATE_FILTER_OVERLAY_ALPHA): SRC = $(TARGET_SAMPLES)/png1/lena-rgba.png $(FATE_FILTER_OVERLAY_ALPHA): CMD = framecrc -i $(SRC) -sws_flags +accurate_rnd+bitexact -vf $(FILTER) -frames:v 1 -fate-filter-overlay_yuv420_yuva420: FILTER = "format=yuva420p[over];color=black:128x128,format=yuv420p[main];[main][over]overlay=format=yuv420" -fate-filter-overlay_yuv422_yuva422: FILTER = "format=yuva422p[over];color=black:128x128,format=yuv422p[main];[main][over]overlay=format=yuv422" -fate-filter-overlay_yuv444_yuva444: FILTER = "format=yuva444p[over];color=black:128x128,format=yuv444p[main];[main][over]overlay=format=yuv444" -fate-filter-overlay_rgb_rgba: FILTER = "format=rgba[over];color=black:128x128,format=rgb24[main];[main][over]overlay=format=rgb" -fate-filter-overlay_gbrp_gbrap: FILTER = "format=gbrap[over];color=black:128x128,format=gbrp[main];[main][over]overlay=format=gbrp" +fate-filter-overlay_yuv420_yuva420: FILTER = "scale,format=yuva420p[over];color=black:128x128,format=yuv420p[main];[main][over]overlay=format=yuv420" +fate-filter-overlay_yuv422_yuva422: FILTER = "scale,format=yuva422p[over];color=black:128x128,format=yuv422p[main];[main][over]overlay=format=yuv422" +fate-filter-overlay_yuv444_yuva444: FILTER = "scale,format=yuva444p[over];color=black:128x128,format=yuv444p[main];[main][over]overlay=format=yuv444" +fate-filter-overlay_rgb_rgba: FILTER = "scale,format=rgba[over];color=black:128x128,format=rgb24[main];[main][over]overlay=format=rgb" +fate-filter-overlay_gbrp_gbrap: FILTER = "scale,format=gbrap[over];color=black:128x128,format=gbrp[main];[main][over]overlay=format=gbrp" -fate-filter-overlay_yuva420_yuva420: FILTER = "format=yuva420p[over];color=black:128x128,format=yuva420p[main];[main][over]overlay=format=yuv420" -fate-filter-overlay_yuva422_yuva422: FILTER = "format=yuva422p[over];color=black:128x128,format=yuva422p[main];[main][over]overlay=format=yuv422" -fate-filter-overlay_yuva444_yuva444: FILTER = "format=yuva444p[over];color=black:128x128,format=yuva444p[main];[main][over]overlay=format=yuv444" -fate-filter-overlay_rgba_rgba: FILTER = "format=rgba[over];color=black:128x128,format=rgba[main];[main][over]overlay=format=rgb" -fate-filter-overlay_gbrap_gbrap: FILTER = "format=gbrap[over];color=black:128x128,format=gbrap[main];[main][over]overlay=format=gbrp" +fate-filter-overlay_yuva420_yuva420: FILTER = "scale,format=yuva420p[over];color=black:128x128,format=yuva420p[main];[main][over]overlay=format=yuv420" +fate-filter-overlay_yuva422_yuva422: FILTER = "scale,format=yuva422p[over];color=black:128x128,format=yuva422p[main];[main][over]overlay=format=yuv422" +fate-filter-overlay_yuva444_yuva444: FILTER = "scale,format=yuva444p[over];color=black:128x128,format=yuva444p[main];[main][over]overlay=format=yuv444" +fate-filter-overlay_rgba_rgba: FILTER = "scale,format=rgba[over];color=black:128x128,format=rgba[main];[main][over]overlay=format=rgb" +fate-filter-overlay_gbrap_gbrap: FILTER = "scale,format=gbrap[over];color=black:128x128,format=gbrap[main];[main][over]overlay=format=gbrp" FATE_FILTER_SAMPLES-$(call ALLYES, PNG_DECODER APNG_DEMUXER FORMAT_FILTER COLOR_FILTER OVERLAY_FILTER) += $(FATE_FILTER_OVERLAY_ALPHA) @@ -361,7 +369,7 @@ fate-filter-shuffleframes: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf shuffleframe FATE_FILTER_VSYNTH-$(CONFIG_SHUFFLEFRAMES_FILTER) += $(FATE_SHUFFLEFRAMES) FATE_SHUFFLEPLANES += fate-filter-shuffleplanes-dup-luma -fate-filter-shuffleplanes-dup-luma: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=yuva444p,shuffleplanes=0:0:0:0 +fate-filter-shuffleplanes-dup-luma: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf scale,format=yuva444p,shuffleplanes=0:0:0:0 FATE_SHUFFLEPLANES += fate-filter-shuffleplanes-swapuv fate-filter-shuffleplanes-swapuv: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf shuffleplanes=0:2:1:0 @@ -402,26 +410,29 @@ fate-filter-untile: CMD = framecrc -lavfi testsrc2=d=1:r=2,untile=2x2 FATE_FILTER_VSYNTH-$(CONFIG_UNSHARP_FILTER) += fate-filter-unsharp fate-filter-unsharp: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf unsharp=11:11:-1.5:11:11:-1.5 +FATE_FILTER_VSYNTH-$(CONFIG_UNSHARP_FILTER) += fate-filter-unsharp-yuv420p10 +fate-filter-unsharp-yuv420p10: CMD = framecrc -lavfi testsrc2=r=2:d=10,scale,format=yuv420p10,unsharp=11:11:-1.5:11:11:-1.5,scale -pix_fmt yuv420p10le -flags +bitexact -sws_flags +accurate_rnd+bitexact + FATE_FILTER_SAMPLES-$(call ALLYES, SMJPEG_DEMUXER MJPEG_DECODER PERMS_FILTER HQDN3D_FILTER) += fate-filter-hqdn3d-sample fate-filter-hqdn3d-sample: tests/data/filtergraphs/hqdn3d fate-filter-hqdn3d-sample: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/hqdn3d -an FATE_FILTER_SAMPLES-$(call ALLYES, MATROSKA_DEMUXER OVERLAY_FILTER H264_DECODER DVDSUB_DECODER) += fate-filter-overlay-dvdsub-2397 fate-filter-overlay-dvdsub-2397: tests/data/filtergraphs/overlay-dvdsub-2397 -fate-filter-overlay-dvdsub-2397: CMD = framecrc -flags bitexact -i $(TARGET_SAMPLES)/filter/242_4.mkv -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay-dvdsub-2397 -c:a copy +fate-filter-overlay-dvdsub-2397: CMD = framecrc -auto_conversion_filters -flags bitexact -i $(TARGET_SAMPLES)/filter/242_4.mkv -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay-dvdsub-2397 -c:a copy FATE_FILTER_HQX-$(call ALLYES, IMAGE2_DEMUXER PNG_DECODER HQX_FILTER) = fate-filter-hq2x fate-filter-hq3x fate-filter-hq4x FATE_FILTER_SAMPLES-yes += $(FATE_FILTER_HQX-yes) -fate-filter-hq2x: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf hqx=2 -pix_fmt bgra -fate-filter-hq3x: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf hqx=3 -pix_fmt bgra -fate-filter-hq4x: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf hqx=4 -pix_fmt bgra +fate-filter-hq2x: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf scale,format=rgb32,hqx=2,scale,format=bgra +fate-filter-hq3x: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf scale,format=rgb32,hqx=3,scale,format=bgra +fate-filter-hq4x: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf scale,format=rgb32,hqx=4,scale,format=bgra fate-filter-hqx: $(FATE_FILTER_HQX-yes) FATE_FILTER_XBR-$(call ALLYES, IMAGE2_DEMUXER PNG_DECODER XBR_FILTER) = fate-filter-2xbr fate-filter-3xbr fate-filter-4xbr FATE_FILTER_SAMPLES-yes += $(FATE_FILTER_XBR-yes) -fate-filter-2xbr: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf xbr=2 -pix_fmt bgra -fate-filter-3xbr: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf xbr=3 -pix_fmt bgra -fate-filter-4xbr: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf xbr=4 -pix_fmt bgra +fate-filter-2xbr: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf scale,xbr=2,scale -pix_fmt bgra +fate-filter-3xbr: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf scale,xbr=3,scale -pix_fmt bgra +fate-filter-4xbr: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf scale,xbr=4,scale -pix_fmt bgra fate-filter-xbr: $(FATE_FILTER_XBR-yes) FATE_FILTER_SAMPLES-$(call ALLYES, UTVIDEO_DECODER AVI_DEMUXER PERMS_FILTER CURVES_FILTER) += fate-filter-curves @@ -429,7 +440,7 @@ fate-filter-curves: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgb_medi FATE_FILTER_SAMPLES-$(call ALLYES, VMD_DEMUXER VMDVIDEO_DECODER FORMAT_FILTER PERMS_FILTER GRADFUN_FILTER) += fate-filter-gradfun-sample fate-filter-gradfun-sample: tests/data/filtergraphs/gradfun -fate-filter-gradfun-sample: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -filter_script $(TARGET_PATH)/tests/data/filtergraphs/gradfun -an -frames:v 20 +fate-filter-gradfun-sample: CMD = framecrc -auto_conversion_filters -i $(TARGET_SAMPLES)/vmd/12.vmd -filter_script $(TARGET_PATH)/tests/data/filtergraphs/gradfun -an -frames:v 20 FATE_FILTER-$(call ALLYES, TESTSRC_FILTER SINE_FILTER CONCAT_FILTER) += fate-filter-concat fate-filter-concat-vfr fate-filter-concat: tests/data/filtergraphs/concat @@ -452,17 +463,17 @@ fate-filter-fps-start-drop: CMD = framecrc -lavfi testsrc2=r=7:d=3.5,fps=3:start fate-filter-fps-start-fill: CMD = framecrc -lavfi testsrc2=r=7:d=1.5,setpts=PTS+14,fps=3:start_time=1.5 FATE_FILTER_SAMPLES-$(call ALLYES, MOV_DEMUXER FPS_FILTER QTRLE_DECODER) += fate-filter-fps-cfr fate-filter-fps fate-filter-fps-r -fate-filter-fps-cfr: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/apple-animation-variable-fps-bug.mov -r 30 -vsync cfr -pix_fmt yuv420p -fate-filter-fps-r: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/apple-animation-variable-fps-bug.mov -r 30 -vf fps -pix_fmt yuv420p -fate-filter-fps: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/apple-animation-variable-fps-bug.mov -vf fps=30 -pix_fmt yuv420p +fate-filter-fps-cfr: CMD = framecrc -auto_conversion_filters -i $(TARGET_SAMPLES)/qtrle/apple-animation-variable-fps-bug.mov -r 30 -vsync cfr -pix_fmt yuv420p +fate-filter-fps-r: CMD = framecrc -auto_conversion_filters -i $(TARGET_SAMPLES)/qtrle/apple-animation-variable-fps-bug.mov -r 30 -vf fps -pix_fmt yuv420p +fate-filter-fps: CMD = framecrc -auto_conversion_filters -i $(TARGET_SAMPLES)/qtrle/apple-animation-variable-fps-bug.mov -vf fps=30 -pix_fmt yuv420p FATE_FILTER_VSYNTH-$(call ALLYES, FORMAT_FILTER SPLIT_FILTER ALPHAEXTRACT_FILTER ALPHAMERGE_FILTER) += fate-filter-alphaextract_alphamerge_rgb fate-filter-alphaextract_alphamerge_rgb: tests/data/filtergraphs/alphamerge_alphaextract_rgb -fate-filter-alphaextract_alphamerge_rgb: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/alphamerge_alphaextract_rgb +fate-filter-alphaextract_alphamerge_rgb: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/alphamerge_alphaextract_rgb FATE_FILTER_VSYNTH-$(call ALLYES, FORMAT_FILTER SPLIT_FILTER ALPHAEXTRACT_FILTER ALPHAMERGE_FILTER) += fate-filter-alphaextract_alphamerge_yuv fate-filter-alphaextract_alphamerge_yuv: tests/data/filtergraphs/alphamerge_alphaextract_yuv -fate-filter-alphaextract_alphamerge_yuv: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/alphamerge_alphaextract_yuv +fate-filter-alphaextract_alphamerge_yuv: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/alphamerge_alphaextract_yuv FATE_FILTER_VSYNTH-$(CONFIG_CROP_FILTER) += fate-filter-crop fate-filter-crop: CMD = video_filter "crop=iw-100:ih-100:100:100" @@ -497,22 +508,22 @@ FATE_FILTER_VSYNTH-$(CONFIG_VFLIP_FILTER) += fate-filter-vflip fate-filter-vflip: CMD = video_filter "vflip" FATE_FILTER_VSYNTH-$(CONFIG_COLORLEVELS_FILTER) += fate-filter-colorlevels -fate-filter-colorlevels: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=rgb24,colorlevels -flags +bitexact -sws_flags +accurate_rnd+bitexact +fate-filter-colorlevels: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf scale,format=rgb24,colorlevels -flags +bitexact -sws_flags +accurate_rnd+bitexact FATE_FILTER_VSYNTH-$(CONFIG_COLORLEVELS_FILTER) += fate-filter-colorlevels-16 -fate-filter-colorlevels-16: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=rgb48,colorlevels -pix_fmt rgb48le -flags +bitexact -sws_flags +accurate_rnd+bitexact +fate-filter-colorlevels-16: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf scale,format=rgb48,colorlevels,scale -pix_fmt rgb48le -flags +bitexact -sws_flags +accurate_rnd+bitexact FATE_FILTER_VSYNTH-$(CONFIG_COLORBALANCE_FILTER) += fate-filter-colorbalance -fate-filter-colorbalance: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=rgb24,colorbalance=rs=.2 -flags +bitexact -sws_flags +accurate_rnd+bitexact -frames:v 3 +fate-filter-colorbalance: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf scale,format=rgb24,colorbalance=rs=.2 -flags +bitexact -sws_flags +accurate_rnd+bitexact -frames:v 3 FATE_FILTER_VSYNTH-$(CONFIG_COLORBALANCE_FILTER) += fate-filter-colorbalance-gbrap -fate-filter-colorbalance-gbrap: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=gbrap,colorbalance=gh=.2 -flags +bitexact -sws_flags +accurate_rnd+bitexact -frames:v 3 +fate-filter-colorbalance-gbrap: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf scale,format=gbrap,colorbalance=gh=.2 -flags +bitexact -sws_flags +accurate_rnd+bitexact -frames:v 3 FATE_FILTER_VSYNTH-$(CONFIG_COLORBALANCE_FILTER) += fate-filter-colorbalance-rgba64 -fate-filter-colorbalance-rgba64: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=rgba64,colorbalance=rm=.2 -pix_fmt rgba64le -flags +bitexact -sws_flags +accurate_rnd+bitexact -frames:v 3 +fate-filter-colorbalance-rgba64: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf scale,format=rgba64,colorbalance=rm=.2,scale -pix_fmt rgba64le -flags +bitexact -sws_flags +accurate_rnd+bitexact -frames:v 3 FATE_FILTER_VSYNTH-$(CONFIG_COLORBALANCE_FILTER) += fate-filter-colorbalance-gbrap-16 -fate-filter-colorbalance-gbrap-16: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf format=gbrap,colorbalance=bh=.2 -pix_fmt gbrap -flags +bitexact -sws_flags +accurate_rnd+bitexact -frames:v 3 +fate-filter-colorbalance-gbrap-16: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf scale,format=gbrap,colorbalance=bh=.2 -pix_fmt gbrap -flags +bitexact -sws_flags +accurate_rnd+bitexact -frames:v 3 FATE_FILTER_VSYNTH-$(CONFIG_COLORMATRIX_FILTER) += fate-filter-colormatrix1 fate-filter-colormatrix1: CMD = video_filter "colormatrix=bt601:smpte240m,colormatrix=smpte240m:fcc,colormatrix=fcc:bt601,colormatrix=bt601:fcc,colormatrix=fcc:smpte240m,colormatrix=smpte240m:bt709" @@ -527,10 +538,10 @@ FATE_FILTER_VSYNTH-$(CONFIG_VFLIP_FILTER) += fate-filter-vflip_vflip fate-filter-vflip_vflip: CMD = video_filter "vflip,vflip" FATE_FILTER_VSYNTH-$(call ALLYES, FORMAT_FILTER PERMS_FILTER EDGEDETECT_FILTER) += fate-filter-edgedetect -fate-filter-edgedetect: CMD = video_filter "format=gray,perms=random,edgedetect" -frames:v 20 +fate-filter-edgedetect: CMD = video_filter "scale,format=gray,perms=random,edgedetect" -frames:v 20 FATE_FILTER_VSYNTH-$(call ALLYES, FORMAT_FILTER PERMS_FILTER EDGEDETECT_FILTER) += fate-filter-edgedetect-colormix -fate-filter-edgedetect-colormix: CMD = video_filter "format=gbrp,perms=random,edgedetect=mode=colormix" -frames:v 20 +fate-filter-edgedetect-colormix: CMD = video_filter "scale,format=gbrp,perms=random,edgedetect=mode=colormix" -frames:v 20 FATE_FILTER_VSYNTH-$(call ALLYES, PERMS_FILTER HUE_FILTER) += fate-filter-hue1 fate-filter-hue1: CMD = video_filter "perms=random,hue=s=sin(2*PI*t)+1" -frames:v 20 @@ -542,7 +553,7 @@ FATE_FILTER_VSYNTH-$(call ALLYES, PERMS_FILTER HUE_FILTER) += fate-filter-hue3 fate-filter-hue3: CMD = video_filter "perms=random,hue=b=n-10" -frames:v 20 FATE_FILTER_VSYNTH-$(call ALLYES, FORMAT_FILTER PERMS_FILTER HUE_FILTER) += fate-filter-hue4 -fate-filter-hue4: CMD = video_filter "format=yuv422p10,perms=random,hue=h=18*n:s=n/10" -frames:v 20 -pix_fmt yuv422p10le +fate-filter-hue4: CMD = video_filter "scale,format=yuv422p10,perms=random,hue=h=18*n:s=n/10,scale" -frames:v 20 -pix_fmt yuv422p10le FATE_FILTER_VSYNTH-$(CONFIG_IDET_FILTER) += fate-filter-idet fate-filter-idet: CMD = framecrc -flags bitexact -idct simple -i $(SRC) -vf idet -frames:v 25 -flags +bitexact @@ -553,29 +564,30 @@ fate-filter-pad: CMD = video_filter "pad=iw*1.5:ih*1.5:iw*0.3:ih*0.2" FATE_FILTER_PP = fate-filter-pp fate-filter-pp1 fate-filter-pp2 fate-filter-pp3 fate-filter-pp4 fate-filter-pp5 fate-filter-pp6 FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += $(FATE_FILTER_PP) $(FATE_FILTER_PP): fate-vsynth1-mpeg4-qprd +fate-vsynth1-mpeg4-qprd: KEEP_OVERRIDE= -keep -fate-filter-pp: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_PATH)/tests/data/fate/vsynth1-mpeg4-qprd.avi -frames:v 5 -flags +bitexact -vf "pp=be/hb/vb/tn/l5/al" +fate-filter-pp: CMD = framecrc -flags bitexact -export_side_data venc_params -idct simple -i $(TARGET_PATH)/tests/data/fate/vsynth1-mpeg4-qprd.avi -frames:v 5 -flags +bitexact -vf "pp=be/hb/vb/tn/l5/al" fate-filter-pp1: CMD = video_filter "pp=fq|4/be/hb/vb/tn/l5/al" -fate-filter-pp2: CMD = video_filter "qp=x+y,pp=be/h1/v1/lb" -fate-filter-pp3: CMD = video_filter "qp=x+y,pp=be/ha|128|7/va/li" +fate-filter-pp2: CMD = video_filter "qp=2*(x+y),pp=be/h1/v1/lb" +fate-filter-pp3: CMD = video_filter "qp=2*(x+y),pp=be/ha|128|7/va/li" fate-filter-pp4: CMD = video_filter "pp=be/ci" fate-filter-pp5: CMD = video_filter "pp=md" fate-filter-pp6: CMD = video_filter "pp=be/fd" FATE_FILTER_VSYNTH-$(CONFIG_PP7_FILTER) += fate-filter-pp7 fate-filter-pp7: fate-vsynth1-mpeg4-qprd -fate-filter-pp7: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_PATH)/tests/data/fate/vsynth1-mpeg4-qprd.avi -frames:v 5 -flags +bitexact -vf "pp7" +fate-filter-pp7: CMD = framecrc -flags bitexact -export_side_data venc_params -idct simple -i $(TARGET_PATH)/tests/data/fate/vsynth1-mpeg4-qprd.avi -frames:v 5 -flags +bitexact -vf "pp7" FATE_FILTER_VSYNTH-$(CONFIG_SPP_FILTER) += fate-filter-spp fate-filter-spp: fate-vsynth1-mpeg4-qprd -fate-filter-spp: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_PATH)/tests/data/fate/vsynth1-mpeg4-qprd.avi -frames:v 5 -flags +bitexact -vf "spp=idct=simple:dct=int" +fate-filter-spp: CMD = framecrc -flags bitexact -export_side_data venc_params -idct simple -i $(TARGET_PATH)/tests/data/fate/vsynth1-mpeg4-qprd.avi -frames:v 5 -flags +bitexact -vf "spp=idct=simple:dct=int" FATE_FILTER_VSYNTH-$(CONFIG_CODECVIEW_FILTER) += fate-filter-codecview fate-filter-codecview: fate-vsynth1-mpeg4-qprd fate-filter-codecview: CMD = framecrc -flags bitexact -idct simple -flags2 +export_mvs -i $(TARGET_PATH)/tests/data/fate/vsynth1-mpeg4-qprd.avi -frames:v 5 -flags +bitexact -vf codecview=mv=pf+bf+bb FATE_FILTER_VSYNTH-$(call ALLYES, QP_FILTER PP_FILTER) += fate-filter-qp -fate-filter-qp: CMD = video_filter "qp=17,pp=be/hb/vb/tn/l5/al" +fate-filter-qp: CMD = video_filter "qp=34,pp=be/hb/vb/tn/l5/al" FATE_FILTER_VSYNTH-$(CONFIG_SELECT_FILTER) += fate-filter-select fate-filter-select: CMD = framecrc -flags bitexact -idct simple -i $(SRC) -vf "select=not(eq(mod(n\,2)\,0)+eq(mod(n\,3)\,0))" -frames:v 25 -flags +bitexact @@ -587,76 +599,76 @@ FATE_FILTER_VSYNTH-$(CONFIG_SETSAR_FILTER) += fate-filter-setsar fate-filter-setsar: CMD = video_filter "setsar=sar=16/11" FATE_STEREO3D += fate-filter-stereo3d-al-sbsl -fate-filter-stereo3d-al-sbsl: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=al:sbsl +fate-filter-stereo3d-al-sbsl: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=al:sbsl FATE_STEREO3D += fate-filter-stereo3d-ar-abl -fate-filter-stereo3d-ar-abl: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=ar:abl +fate-filter-stereo3d-ar-abl: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=ar:abl FATE_STEREO3D += fate-filter-stereo3d-abr-mr -fate-filter-stereo3d-abr-mr: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=abr:mr +fate-filter-stereo3d-abr-mr: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=abr:mr FATE_STEREO3D += fate-filter-stereo3d-abr-ml -fate-filter-stereo3d-abr-ml: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=abr:ml +fate-filter-stereo3d-abr-ml: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=abr:ml FATE_STEREO3D += fate-filter-stereo3d-sbsl-abl -fate-filter-stereo3d-sbsl-abl: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:abl +fate-filter-stereo3d-sbsl-abl: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:abl FATE_STEREO3D += fate-filter-stereo3d-sbsl-abr -fate-filter-stereo3d-sbsl-abr: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:abr +fate-filter-stereo3d-sbsl-abr: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:abr FATE_STEREO3D += fate-filter-stereo3d-sbsl-al -fate-filter-stereo3d-sbsl-al: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:al +fate-filter-stereo3d-sbsl-al: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:al FATE_STEREO3D += fate-filter-stereo3d-sbsl-sbsr -fate-filter-stereo3d-sbsl-sbsr: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:sbsr +fate-filter-stereo3d-sbsl-sbsr: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:sbsr FATE_STEREO3D += fate-filter-stereo3d-sbsl-agmc -fate-filter-stereo3d-sbsl-agmc: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:agmc +fate-filter-stereo3d-sbsl-agmc: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:agmc FATE_STEREO3D += fate-filter-stereo3d-sbsl-agmd -fate-filter-stereo3d-sbsl-agmd: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:agmd +fate-filter-stereo3d-sbsl-agmd: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:agmd FATE_STEREO3D += fate-filter-stereo3d-sbsl-agmg -fate-filter-stereo3d-sbsl-agmg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:agmg +fate-filter-stereo3d-sbsl-agmg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:agmg FATE_STEREO3D += fate-filter-stereo3d-sbsl-agmh -fate-filter-stereo3d-sbsl-agmh: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:agmh +fate-filter-stereo3d-sbsl-agmh: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:agmh FATE_STEREO3D += fate-filter-stereo3d-sbsl-arbg -fate-filter-stereo3d-sbsl-arbg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:arbg +fate-filter-stereo3d-sbsl-arbg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:arbg FATE_STEREO3D += fate-filter-stereo3d-sbsl-arcc -fate-filter-stereo3d-sbsl-arcc: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:arcc +fate-filter-stereo3d-sbsl-arcc: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:arcc FATE_STEREO3D += fate-filter-stereo3d-sbsl-arcd -fate-filter-stereo3d-sbsl-arcd: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:arcd +fate-filter-stereo3d-sbsl-arcd: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:arcd FATE_STEREO3D += fate-filter-stereo3d-sbsl-arcg -fate-filter-stereo3d-sbsl-arcg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:arcg +fate-filter-stereo3d-sbsl-arcg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:arcg FATE_STEREO3D += fate-filter-stereo3d-sbsl-arch -fate-filter-stereo3d-sbsl-arch: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:arch +fate-filter-stereo3d-sbsl-arch: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:arch FATE_STEREO3D += fate-filter-stereo3d-sbsl-argg -fate-filter-stereo3d-sbsl-argg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:argg +fate-filter-stereo3d-sbsl-argg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:argg FATE_STEREO3D += fate-filter-stereo3d-sbsl-aybc -fate-filter-stereo3d-sbsl-aybc: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:aybc +fate-filter-stereo3d-sbsl-aybc: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:aybc FATE_STEREO3D += fate-filter-stereo3d-sbsl-aybd -fate-filter-stereo3d-sbsl-aybd: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:aybd +fate-filter-stereo3d-sbsl-aybd: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:aybd FATE_STEREO3D += fate-filter-stereo3d-sbsl-aybg -fate-filter-stereo3d-sbsl-aybg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:aybg +fate-filter-stereo3d-sbsl-aybg: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:aybg FATE_STEREO3D += fate-filter-stereo3d-sbsl-aybh -fate-filter-stereo3d-sbsl-aybh: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf stereo3d=sbsl:aybh +fate-filter-stereo3d-sbsl-aybh: CMD = framecrc -c:v pgmyuv -i $(SRC) -frames:v 5 -flags +bitexact -sws_flags +accurate_rnd+bitexact -vf scale,stereo3d=sbsl:aybh fate-filter-stereo3d: $(FATE_STEREO3D) FATE_FILTER_VSYNTH-$(CONFIG_STEREO3D_FILTER) += $(FATE_STEREO3D) FATE_FILTER_VSYNTH-$(CONFIG_THUMBNAIL_FILTER) += fate-filter-thumbnail -fate-filter-thumbnail: CMD = video_filter "thumbnail=10" +fate-filter-thumbnail: CMD = video_filter "scale,thumbnail=10" FATE_FILTER_VSYNTH-$(CONFIG_TILE_FILTER) += fate-filter-tile fate-filter-tile: CMD = video_filter "tile=3x3:nb_frames=5:padding=7:margin=2" @@ -676,7 +688,7 @@ endif define PIXDESC_TEST FATE_FILTER_PIXDESC-$(CONFIG_FORMAT_FILTER) += fate-filter-pixdesc-$(1) -fate-filter-pixdesc-$(1): CMD = video_filter "format=$(1),pixdesctest" -pix_fmt $(1) +fate-filter-pixdesc-$(1): CMD = video_filter "scale,format=$(1),pixdesctest" -pix_fmt $(1) endef $(foreach fmt, $(PIXFMTS), $(eval $(call PIXDESC_TEST,$(fmt)))) @@ -831,7 +843,7 @@ tests/data/file4560-override2rotate0.mov: ffmpeg$(PROGSSUF)$(EXESUF) | tests/dat FATE_FILTER_SAMPLES-$(call ALLYES, MOV_DEMUXER H264_DECODER AAC_FIXED_DECODER PCM_S16LE_ENCODER MOV_MUXER) += fate-filter-meta-4560-rotate0 fate-filter-meta-4560-rotate0: tests/data/file4560-override2rotate0.mov -fate-filter-meta-4560-rotate0: CMD = framecrc -flags +bitexact -c:a aac_fixed -i $(TARGET_PATH)/tests/data/file4560-override2rotate0.mov +fate-filter-meta-4560-rotate0: CMD = framecrc -auto_conversion_filters -flags +bitexact -c:a aac_fixed -i $(TARGET_PATH)/tests/data/file4560-override2rotate0.mov REFCMP_DEPS = FFMPEG LAVFI_INDEV TESTSRC2_FILTER AVGBLUR_FILTER METADATA_FILTER diff --git a/tests/fate/fits.mak b/tests/fate/fits.mak index 113498cf7..8c2995a4c 100644 --- a/tests/fate/fits.mak +++ b/tests/fate/fits.mak @@ -5,6 +5,7 @@ tests/data/fits-multi.fits: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data -y $(TARGET_PATH)/$(@) 2>/dev/null #mapping of fits file formats to png filenames +# TODO: Use an actual 64bit input file and fix the gbrp16 test on big-endian map.tests/data/lena-gray.fits := gray8 map.tests/data/lena-gbrp.fits := rgb24 map.tests/data/lena-gbrp16.fits := rgb48 @@ -18,16 +19,16 @@ tests/data/lena%.fits: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data -y $(TARGET_PATH)/$(@) 2>/dev/null FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-ext_data_min_max -fate-fitsdec-ext_data_min_max: CMD = framecrc -i $(TARGET_SAMPLES)/fits/x0cj010ct_d0h.fit -pix_fmt gray16le +fate-fitsdec-ext_data_min_max: CMD = framecrc -i $(TARGET_SAMPLES)/fits/x0cj010ct_d0h.fit -pix_fmt gray16le -vf scale FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-blank_bitpix32 -fate-fitsdec-blank_bitpix32: CMD = framecrc -blank_value 65535 -i $(TARGET_SAMPLES)/fits/file008.fits -pix_fmt gray16le +fate-fitsdec-blank_bitpix32: CMD = framecrc -blank_value 65535 -i $(TARGET_SAMPLES)/fits/file008.fits -pix_fmt gray16le -vf scale FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-bitpix-32 -fate-fitsdec-bitpix-32: CMD = framecrc -i $(TARGET_SAMPLES)/fits/tst0005.fits -pix_fmt gray16le +fate-fitsdec-bitpix-32: CMD = framecrc -i $(TARGET_SAMPLES)/fits/tst0005.fits -pix_fmt gray16le -vf scale FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-bitpix-64 -fate-fitsdec-bitpix-64: CMD = framecrc -i $(TARGET_SAMPLES)/fits/tst0006.fits -pix_fmt gray16le +fate-fitsdec-bitpix-64: CMD = framecrc -i $(TARGET_SAMPLES)/fits/tst0006.fits -pix_fmt gray16le -vf scale FATE_FITS_DEC-$(call ALLYES, GIF_DEMUXER FITS_DEMUXER GIF_DECODER FITS_DECODER FITS_ENCODER FITS_MUXER) += fate-fitsdec-multi fate-fitsdec-multi: tests/data/fits-multi.fits @@ -46,7 +47,7 @@ fate-fitsdec: $(FATE_FITS_DEC-yes) fate-fitsenc%: PIXFMT = $(word 3, $(subst -, ,$(@))) fate-fitsenc%: SRC = $(TARGET_PATH)/tests/data/fits-multi.fits -fate-fitsenc%: CMD = framecrc -i $(SRC) -c:v fits -pix_fmt $(PIXFMT) +fate-fitsenc%: CMD = framecrc -auto_conversion_filters -i $(SRC) -c:v fits -pix_fmt $(PIXFMT) FATE_FITS_ENC_PIXFMT = gray gray16be gbrp gbrap gbrp16be gbrap16be $(FATE_FITS_ENC_PIXFMT:%=fate-fitsenc-%): tests/data/fits-multi.fits diff --git a/tests/fate/gif.mak b/tests/fate/gif.mak index 16d4286a0..a5147c0e3 100644 --- a/tests/fate/gif.mak +++ b/tests/fate/gif.mak @@ -1,22 +1,22 @@ FATE_GIF += fate-gif-color -fate-gif-color: CMD = framecrc -i $(TARGET_SAMPLES)/gif/tc217.gif -pix_fmt bgra +fate-gif-color: CMD = framecrc -i $(TARGET_SAMPLES)/gif/tc217.gif -pix_fmt bgra -vf scale FATE_GIF += fate-gif-disposal-background -fate-gif-disposal-background: CMD = framecrc -trans_color 0 -i $(TARGET_SAMPLES)/gif/m4nb.gif -pix_fmt bgra +fate-gif-disposal-background: CMD = framecrc -trans_color 0 -i $(TARGET_SAMPLES)/gif/m4nb.gif -pix_fmt bgra -vf scale FATE_GIF += fate-gif-disposal-restore -fate-gif-disposal-restore: CMD = framecrc -i $(TARGET_SAMPLES)/gif/banner2.gif -pix_fmt bgra +fate-gif-disposal-restore: CMD = framecrc -i $(TARGET_SAMPLES)/gif/banner2.gif -pix_fmt bgra -vf scale FATE_GIF += fate-gif-gray -fate-gif-gray: CMD = framecrc -i $(TARGET_SAMPLES)/gif/Newtons_cradle_animation_book_2.gif -pix_fmt bgra +fate-gif-gray: CMD = framecrc -i $(TARGET_SAMPLES)/gif/Newtons_cradle_animation_book_2.gif -pix_fmt bgra -vf scale FATE_GIF += fate-gif-deal -fate-gif-deal: CMD = framecrc -i $(TARGET_SAMPLES)/gif/deal.gif -vsync cfr -pix_fmt bgra +fate-gif-deal: CMD = framecrc -i $(TARGET_SAMPLES)/gif/deal.gif -vsync cfr -pix_fmt bgra -auto_conversion_filters fate-gifenc%: fate-gif-color fate-gifenc%: PIXFMT = $(word 3, $(subst -, ,$(@))) fate-gifenc%: SRC = $(TARGET_SAMPLES)/gif/tc217.gif -fate-gifenc%: CMD = framecrc -i $(SRC) -c:v gif -pix_fmt $(PIXFMT) -sws_flags +accurate_rnd+bitexact +fate-gifenc%: CMD = framecrc -i $(SRC) -c:v gif -pix_fmt $(PIXFMT) -sws_flags +accurate_rnd+bitexact -vf scale FATE_GIF_ENC_PIXFMT = rgb8 bgr8 rgb4_byte bgr4_byte gray pal8 FATE_GIF_ENC-$(call ENCDEC, GIF, GIF) = $(FATE_GIF_ENC_PIXFMT:%=fate-gifenc-%) diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak index 13a596e52..e034e6ae0 100644 --- a/tests/fate/h264.mak +++ b/tests/fate/h264.mak @@ -233,7 +233,7 @@ FATE_SAMPLES_AVCONV += $(FATE_H264-yes) FATE_SAMPLES_FFPROBE += $(FATE_H264_FFPROBE-yes) fate-h264: $(FATE_H264-yes) $(FATE_H264_FFPROBE-yes) -fate-h264-conformance-aud_mw_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/AUD_MW_E.264 +fate-h264-conformance-aud_mw_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/AUD_MW_E.264 #force framerate so that the option is tested, theres no other case that tests it, its not needed at all otherwise here fate-h264-conformance-ba1_ft_c: CMD = framecrc -framerate 19 -i $(TARGET_SAMPLES)/h264-conformance/BA1_FT_C.264 @@ -253,173 +253,173 @@ fate-h264-conformance-caba2_sva_b: CMD = framecrc -i $(TARGET_SAM fate-h264-conformance-caba3_sony_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA3_Sony_C.jsv fate-h264-conformance-caba3_sva_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA3_SVA_B.264 fate-h264-conformance-caba3_toshiba_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA3_TOSHIBA_E.264 -fate-h264-conformance-cabac_mot_fld0_full: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_fld0_full.26l -fate-h264-conformance-cabac_mot_frm0_full: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_frm0_full.26l -fate-h264-conformance-cabac_mot_mbaff0_full: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_mbaff0_full.26l -fate-h264-conformance-cabac_mot_picaff0_full: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_picaff0_full.26l -fate-h264-conformance-cabaci3_sony_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABACI3_Sony_B.jsv -fate-h264-conformance-cabast3_sony_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABAST3_Sony_E.jsv -fate-h264-conformance-cabastbr3_sony_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABASTBR3_Sony_B.jsv -fate-h264-conformance-cabref3_sand_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CABREF3_Sand_D.264 -fate-h264-conformance-cacqp3_sony_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CACQP3_Sony_D.jsv -fate-h264-conformance-cafi1_sva_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAFI1_SVA_C.264 -fate-h264-conformance-cama1_sony_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMA1_Sony_C.jsv -fate-h264-conformance-cama1_toshiba_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMA1_TOSHIBA_B.264 -fate-h264-conformance-cama1_vtc_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cama1_vtc_c.avc -fate-h264-conformance-cama2_vtc_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cama2_vtc_b.avc -fate-h264-conformance-cama3_sand_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMA3_Sand_E.264 -fate-h264-conformance-cama3_vtc_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cama3_vtc_b.avc -fate-h264-conformance-camaci3_sony_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMACI3_Sony_C.jsv -fate-h264-conformance-camanl1_toshiba_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMANL1_TOSHIBA_B.264 -fate-h264-conformance-camanl2_toshiba_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMANL2_TOSHIBA_B.264 -fate-h264-conformance-camanl3_sand_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMANL3_Sand_E.264 -fate-h264-conformance-camasl3_sony_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMASL3_Sony_B.jsv -fate-h264-conformance-camp_mot_mbaff_l30: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L30.26l -fate-h264-conformance-camp_mot_mbaff_l31: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L31.26l -fate-h264-conformance-canl1_sony_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL1_Sony_E.jsv -fate-h264-conformance-canl1_sva_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL1_SVA_B.264 -fate-h264-conformance-canl1_toshiba_g: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL1_TOSHIBA_G.264 -fate-h264-conformance-canl2_sony_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL2_Sony_E.jsv -fate-h264-conformance-canl2_sva_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL2_SVA_B.264 -fate-h264-conformance-canl3_sony_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL3_Sony_C.jsv -fate-h264-conformance-canl3_sva_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL3_SVA_B.264 -fate-h264-conformance-canl4_sva_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANL4_SVA_B.264 -fate-h264-conformance-canlma2_sony_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANLMA2_Sony_C.jsv -fate-h264-conformance-canlma3_sony_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CANLMA3_Sony_C.jsv -fate-h264-conformance-capa1_toshiba_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPA1_TOSHIBA_B.264 -fate-h264-conformance-capama3_sand_f: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPAMA3_Sand_F.264 -fate-h264-conformance-capcm1_sand_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPCM1_Sand_E.264 -fate-h264-conformance-capcmnl1_sand_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPCMNL1_Sand_E.264 -fate-h264-conformance-capm3_sony_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAPM3_Sony_D.jsv -fate-h264-conformance-caqp1_sony_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAQP1_Sony_B.jsv -fate-h264-conformance-cavlc_mot_fld0_full_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_fld0_full_B.26l -fate-h264-conformance-cavlc_mot_frm0_full_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_frm0_full_B.26l -fate-h264-conformance-cavlc_mot_mbaff0_full_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_mbaff0_full_B.26l -fate-h264-conformance-cavlc_mot_picaff0_full_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_picaff0_full_B.26l -fate-h264-conformance-cawp1_toshiba_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAWP1_TOSHIBA_E.264 -fate-h264-conformance-cawp5_toshiba_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CAWP5_TOSHIBA_E.264 -fate-h264-conformance-ci1_ft_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CI1_FT_B.264 -fate-h264-conformance-ci_mw_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CI_MW_D.264 -fate-h264-conformance-cvbs3_sony_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVBS3_Sony_C.jsv -fate-h264-conformance-cvcanlma2_sony_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVCANLMA2_Sony_C.jsv +fate-h264-conformance-cabac_mot_fld0_full: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_fld0_full.26l +fate-h264-conformance-cabac_mot_frm0_full: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_frm0_full.26l +fate-h264-conformance-cabac_mot_mbaff0_full: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_mbaff0_full.26l +fate-h264-conformance-cabac_mot_picaff0_full: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_picaff0_full.26l +fate-h264-conformance-cabaci3_sony_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABACI3_Sony_B.jsv +fate-h264-conformance-cabast3_sony_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABAST3_Sony_E.jsv +fate-h264-conformance-cabastbr3_sony_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABASTBR3_Sony_B.jsv +fate-h264-conformance-cabref3_sand_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABREF3_Sand_D.264 +fate-h264-conformance-cacqp3_sony_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CACQP3_Sony_D.jsv +fate-h264-conformance-cafi1_sva_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAFI1_SVA_C.264 +fate-h264-conformance-cama1_sony_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMA1_Sony_C.jsv +fate-h264-conformance-cama1_toshiba_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMA1_TOSHIBA_B.264 +fate-h264-conformance-cama1_vtc_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cama1_vtc_c.avc +fate-h264-conformance-cama2_vtc_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cama2_vtc_b.avc +fate-h264-conformance-cama3_sand_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMA3_Sand_E.264 +fate-h264-conformance-cama3_vtc_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cama3_vtc_b.avc +fate-h264-conformance-camaci3_sony_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMACI3_Sony_C.jsv +fate-h264-conformance-camanl1_toshiba_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMANL1_TOSHIBA_B.264 +fate-h264-conformance-camanl2_toshiba_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMANL2_TOSHIBA_B.264 +fate-h264-conformance-camanl3_sand_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMANL3_Sand_E.264 +fate-h264-conformance-camasl3_sony_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMASL3_Sony_B.jsv +fate-h264-conformance-camp_mot_mbaff_l30: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L30.26l +fate-h264-conformance-camp_mot_mbaff_l31: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L31.26l +fate-h264-conformance-canl1_sony_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL1_Sony_E.jsv +fate-h264-conformance-canl1_sva_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL1_SVA_B.264 +fate-h264-conformance-canl1_toshiba_g: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL1_TOSHIBA_G.264 +fate-h264-conformance-canl2_sony_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL2_Sony_E.jsv +fate-h264-conformance-canl2_sva_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL2_SVA_B.264 +fate-h264-conformance-canl3_sony_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL3_Sony_C.jsv +fate-h264-conformance-canl3_sva_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL3_SVA_B.264 +fate-h264-conformance-canl4_sva_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL4_SVA_B.264 +fate-h264-conformance-canlma2_sony_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANLMA2_Sony_C.jsv +fate-h264-conformance-canlma3_sony_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANLMA3_Sony_C.jsv +fate-h264-conformance-capa1_toshiba_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPA1_TOSHIBA_B.264 +fate-h264-conformance-capama3_sand_f: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPAMA3_Sand_F.264 +fate-h264-conformance-capcm1_sand_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPCM1_Sand_E.264 +fate-h264-conformance-capcmnl1_sand_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPCMNL1_Sand_E.264 +fate-h264-conformance-capm3_sony_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPM3_Sony_D.jsv +fate-h264-conformance-caqp1_sony_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAQP1_Sony_B.jsv +fate-h264-conformance-cavlc_mot_fld0_full_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_fld0_full_B.26l +fate-h264-conformance-cavlc_mot_frm0_full_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_frm0_full_B.26l +fate-h264-conformance-cavlc_mot_mbaff0_full_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_mbaff0_full_B.26l +fate-h264-conformance-cavlc_mot_picaff0_full_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_picaff0_full_B.26l +fate-h264-conformance-cawp1_toshiba_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAWP1_TOSHIBA_E.264 +fate-h264-conformance-cawp5_toshiba_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAWP5_TOSHIBA_E.264 +fate-h264-conformance-ci1_ft_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CI1_FT_B.264 +fate-h264-conformance-ci_mw_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CI_MW_D.264 +fate-h264-conformance-cvbs3_sony_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVBS3_Sony_C.jsv +fate-h264-conformance-cvcanlma2_sony_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVCANLMA2_Sony_C.jsv fate-h264-conformance-cvfc1_sony_c: CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/h264-conformance/CVFC1_Sony_C.jsv -fate-h264-conformance-cvfi1_sony_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVFI1_Sony_D.jsv -fate-h264-conformance-cvfi1_sva_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVFI1_SVA_C.264 -fate-h264-conformance-cvfi2_sony_h: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVFI2_Sony_H.jsv -fate-h264-conformance-cvfi2_sva_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVFI2_SVA_C.264 -fate-h264-conformance-cvma1_sony_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMA1_Sony_D.jsv -fate-h264-conformance-cvma1_toshiba_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMA1_TOSHIBA_B.264 -fate-h264-conformance-cvmanl1_toshiba_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMANL1_TOSHIBA_B.264 -fate-h264-conformance-cvmanl2_toshiba_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMANL2_TOSHIBA_B.264 -fate-h264-conformance-cvmapaqp3_sony_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMAPAQP3_Sony_E.jsv -fate-h264-conformance-cvmaqp2_sony_g: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMAQP2_Sony_G.jsv -fate-h264-conformance-cvmaqp3_sony_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMAQP3_Sony_D.jsv -fate-h264-conformance-cvmp_mot_fld_l30_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMP_MOT_FLD_L30_B.26l -fate-h264-conformance-cvmp_mot_frm_l31_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVMP_MOT_FRM_L31_B.26l -fate-h264-conformance-cvnlfi1_sony_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVNLFI1_Sony_C.jsv -fate-h264-conformance-cvnlfi2_sony_h: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVNLFI2_Sony_H.jsv -fate-h264-conformance-cvpa1_toshiba_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVPA1_TOSHIBA_B.264 -fate-h264-conformance-cvpcmnl1_sva_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVPCMNL1_SVA_C.264 -fate-h264-conformance-cvpcmnl2_sva_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVPCMNL2_SVA_C.264 -fate-h264-conformance-cvwp1_toshiba_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVWP1_TOSHIBA_E.264 -fate-h264-conformance-cvwp2_toshiba_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVWP2_TOSHIBA_E.264 -fate-h264-conformance-cvwp3_toshiba_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVWP3_TOSHIBA_E.264 -fate-h264-conformance-cvwp5_toshiba_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/CVWP5_TOSHIBA_E.264 -fate-h264-conformance-fi1_sony_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FI1_Sony_E.jsv -fate-h264-conformance-frext-alphaconformanceg: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/test8b43.264 -fate-h264-conformance-frext-bcrm_freh10: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh10.264 -vsync drop -fate-h264-conformance-frext-brcm_freh11: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh11.264 -vsync drop -fate-h264-conformance-frext-brcm_freh3: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh3.264 -fate-h264-conformance-frext-brcm_freh4: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh4.264 -vsync drop -fate-h264-conformance-frext-brcm_freh5: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh5.264 -fate-h264-conformance-frext-brcm_freh8: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh8.264 -fate-h264-conformance-frext-brcm_freh9: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh9.264 -fate-h264-conformance-frext-freh12_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh12_B.264 -fate-h264-conformance-frext-freh1_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh1_B.264 -fate-h264-conformance-frext-freh2_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh2_B.264 -fate-h264-conformance-frext-freh6: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh6.264 -vsync drop -fate-h264-conformance-frext-freh7_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh7_B.264 -vsync drop -fate-h264-conformance-frext-frext01_jvc_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FREXT01_JVC_D.264 -fate-h264-conformance-frext-frext02_jvc_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FREXT02_JVC_C.264 -fate-h264-conformance-frext-frext1_panasonic_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt1_Panasonic.avc -fate-h264-conformance-frext-frext2_panasonic_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt2_Panasonic.avc -vsync 0 -fate-h264-conformance-frext-frext3_panasonic_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt3_Panasonic.avc -fate-h264-conformance-frext-frext4_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt4_Panasonic.avc -fate-h264-conformance-frext-frext_mmco4_sony_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt_MMCO4_Sony_B.264 -fate-h264-conformance-frext-hcaff1_hhi_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFF1_HHI.264 -fate-h264-conformance-frext-hcafr1_hhi_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR1_HHI.264 -fate-h264-conformance-frext-hcafr2_hhi_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR2_HHI.264 -fate-h264-conformance-frext-hcafr3_hhi_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR3_HHI.264 -fate-h264-conformance-frext-hcafr4_hhi_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR4_HHI.264 -fate-h264-conformance-frext-hcamff1_hhi_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAMFF1_HHI.264 -fate-h264-conformance-frext-hi422fr10_sony_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR10_SONY_B.264 -fate-h264-conformance-frext-hi422fr13_sony_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR13_SONY_B.264 -pix_fmt yuv422p10le -fate-h264-conformance-frext-hi422fr1_sony_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR1_SONY_A.jsv -fate-h264-conformance-frext-hi422fr6_sony_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR6_SONY_A.jsv -pix_fmt yuv422p10le -fate-h264-conformance-frext-hpca_brcm_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCA_BRCM_C.264 -fate-h264-conformance-frext-hpcadq_brcm_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCADQ_BRCM_B.264 -fate-h264-conformance-frext-hpcafl_bcrm_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAFL_BRCM_C.264 -vsync drop -fate-h264-conformance-frext-hpcaflnl_bcrm_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAFLNL_BRCM_C.264 -vsync drop -fate-h264-conformance-frext-hpcalq_brcm_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCALQ_BRCM_B.264 -fate-h264-conformance-frext-hpcamapalq_bcrm_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAMAPALQ_BRCM_B.264 -vsync 0 -fate-h264-conformance-frext-hpcamolq_brcm_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAMOLQ_BRCM_B.264 -fate-h264-conformance-frext-hpcanl_brcm_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCANL_BRCM_C.264 -fate-h264-conformance-frext-hpcaq2lq_brcm_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAQ2LQ_BRCM_B.264 -fate-h264-conformance-frext-hpcv_brcm_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCV_BRCM_A.264 -fate-h264-conformance-frext-hpcvfl_bcrm_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVFL_BRCM_A.264 -vsync drop -fate-h264-conformance-frext-hpcvflnl_bcrm_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVFLNL_BRCM_A.264 -vsync drop -fate-h264-conformance-frext-hpcvmolq_brcm_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVMOLQ_BRCM_B.264 -fate-h264-conformance-frext-hpcvnl_brcm_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVNL_BRCM_A.264 -fate-h264-conformance-frext-pph10i1_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I1_Panasonic_A.264 -pix_fmt yuv420p10le -fate-h264-conformance-frext-pph10i2_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I2_Panasonic_A.264 -pix_fmt yuv420p10le -fate-h264-conformance-frext-pph10i3_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I3_Panasonic_A.264 -pix_fmt yuv420p10le -fate-h264-conformance-frext-pph10i4_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I4_Panasonic_A.264 -pix_fmt yuv420p10le -fate-h264-conformance-frext-pph10i5_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I5_Panasonic_A.264 -pix_fmt yuv420p10le -fate-h264-conformance-frext-pph10i6_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I6_Panasonic_A.264 -pix_fmt yuv420p10le -fate-h264-conformance-frext-pph10i7_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I7_Panasonic_A.264 -pix_fmt yuv420p10le -fate-h264-conformance-frext-pph422i1_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I1_Panasonic_A.264 -pix_fmt yuv422p10le -fate-h264-conformance-frext-pph422i2_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I2_Panasonic_A.264 -pix_fmt yuv422p10le -fate-h264-conformance-frext-pph422i3_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I3_Panasonic_A.264 -pix_fmt yuv422p10le -fate-h264-conformance-frext-pph422i4_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I4_Panasonic_A.264 -pix_fmt yuv422p10le -fate-h264-conformance-frext-pph422i5_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I5_Panasonic_A.264 -pix_fmt yuv422p10le -fate-h264-conformance-frext-pph422i6_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I6_Panasonic_A.264 -pix_fmt yuv422p10le -fate-h264-conformance-frext-pph422i7_panasonic_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I7_Panasonic_A.264 -pix_fmt yuv422p10le -fate-h264-conformance-hcbp2_hhi_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/HCBP2_HHI_A.264 -fate-h264-conformance-hcmp1_hhi_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/HCMP1_HHI_A.264 -fate-h264-conformance-ls_sva_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/LS_SVA_D.264 -fate-h264-conformance-midr_mw_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MIDR_MW_D.264 -fate-h264-conformance-mps_mw_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MPS_MW_A.264 -fate-h264-conformance-mr1_bt_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR1_BT_A.h264 -fate-h264-conformance-mr1_mw_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR1_MW_A.264 -fate-h264-conformance-mr2_mw_a: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR2_MW_A.264 -fate-h264-conformance-mr2_tandberg_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR2_TANDBERG_E.264 -fate-h264-conformance-mr3_tandberg_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR3_TANDBERG_B.264 -fate-h264-conformance-mr4_tandberg_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR4_TANDBERG_C.264 -fate-h264-conformance-mr5_tandberg_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR5_TANDBERG_C.264 -fate-h264-conformance-mr6_bt_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR6_BT_B.h264 -fate-h264-conformance-mr7_bt_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR7_BT_B.h264 -fate-h264-conformance-mr8_bt_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR8_BT_B.h264 -fate-h264-conformance-mr9_bt_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/MR9_BT_B.h264 -fate-h264-conformance-mv1_brcm_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/src19td.IBP.264 -fate-h264-conformance-nl1_sony_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NL1_Sony_D.jsv -fate-h264-conformance-nl2_sony_h: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NL2_Sony_H.jsv -fate-h264-conformance-nl3_sva_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NL3_SVA_E.264 -fate-h264-conformance-nlmq1_jvc_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NLMQ1_JVC_C.264 -fate-h264-conformance-nlmq2_jvc_c: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NLMQ2_JVC_C.264 -fate-h264-conformance-nrf_mw_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/NRF_MW_E.264 -fate-h264-conformance-sharp_mp_field_1_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_1_B.jvt -fate-h264-conformance-sharp_mp_field_2_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_2_B.jvt -fate-h264-conformance-sharp_mp_field_3_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_3_B.jvt -fate-h264-conformance-sharp_mp_paff_1r2: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_PAFF_1r2.jvt -fate-h264-conformance-sharp_mp_paff_2r: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_PAFF_2.jvt -fate-h264-conformance-sl1_sva_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SL1_SVA_B.264 -fate-h264-conformance-sva_ba1_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_BA1_B.264 -fate-h264-conformance-sva_ba2_d: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_BA2_D.264 -fate-h264-conformance-sva_base_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_Base_B.264 -fate-h264-conformance-sva_cl1_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_CL1_E.264 -fate-h264-conformance-sva_fm1_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_FM1_E.264 -fate-h264-conformance-sva_nl1_b: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL1_B.264 -fate-h264-conformance-sva_nl2_e: CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL2_E.264 +fate-h264-conformance-cvfi1_sony_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVFI1_Sony_D.jsv +fate-h264-conformance-cvfi1_sva_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVFI1_SVA_C.264 +fate-h264-conformance-cvfi2_sony_h: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVFI2_Sony_H.jsv +fate-h264-conformance-cvfi2_sva_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVFI2_SVA_C.264 +fate-h264-conformance-cvma1_sony_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMA1_Sony_D.jsv +fate-h264-conformance-cvma1_toshiba_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMA1_TOSHIBA_B.264 +fate-h264-conformance-cvmanl1_toshiba_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMANL1_TOSHIBA_B.264 +fate-h264-conformance-cvmanl2_toshiba_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMANL2_TOSHIBA_B.264 +fate-h264-conformance-cvmapaqp3_sony_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMAPAQP3_Sony_E.jsv +fate-h264-conformance-cvmaqp2_sony_g: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMAQP2_Sony_G.jsv +fate-h264-conformance-cvmaqp3_sony_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMAQP3_Sony_D.jsv +fate-h264-conformance-cvmp_mot_fld_l30_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMP_MOT_FLD_L30_B.26l +fate-h264-conformance-cvmp_mot_frm_l31_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMP_MOT_FRM_L31_B.26l +fate-h264-conformance-cvnlfi1_sony_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVNLFI1_Sony_C.jsv +fate-h264-conformance-cvnlfi2_sony_h: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVNLFI2_Sony_H.jsv +fate-h264-conformance-cvpa1_toshiba_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVPA1_TOSHIBA_B.264 +fate-h264-conformance-cvpcmnl1_sva_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVPCMNL1_SVA_C.264 +fate-h264-conformance-cvpcmnl2_sva_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVPCMNL2_SVA_C.264 +fate-h264-conformance-cvwp1_toshiba_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVWP1_TOSHIBA_E.264 +fate-h264-conformance-cvwp2_toshiba_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVWP2_TOSHIBA_E.264 +fate-h264-conformance-cvwp3_toshiba_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVWP3_TOSHIBA_E.264 +fate-h264-conformance-cvwp5_toshiba_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVWP5_TOSHIBA_E.264 +fate-h264-conformance-fi1_sony_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FI1_Sony_E.jsv +fate-h264-conformance-frext-alphaconformanceg: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/test8b43.264 +fate-h264-conformance-frext-bcrm_freh10: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh10.264 +fate-h264-conformance-frext-brcm_freh11: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh11.264 +fate-h264-conformance-frext-brcm_freh3: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh3.264 +fate-h264-conformance-frext-brcm_freh4: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh4.264 +fate-h264-conformance-frext-brcm_freh5: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh5.264 +fate-h264-conformance-frext-brcm_freh8: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh8.264 +fate-h264-conformance-frext-brcm_freh9: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh9.264 +fate-h264-conformance-frext-freh12_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh12_B.264 +fate-h264-conformance-frext-freh1_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh1_B.264 +fate-h264-conformance-frext-freh2_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh2_B.264 +fate-h264-conformance-frext-freh6: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh6.264 +fate-h264-conformance-frext-freh7_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh7_B.264 +fate-h264-conformance-frext-frext01_jvc_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FREXT01_JVC_D.264 +fate-h264-conformance-frext-frext02_jvc_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FREXT02_JVC_C.264 +fate-h264-conformance-frext-frext1_panasonic_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt1_Panasonic.avc +fate-h264-conformance-frext-frext2_panasonic_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt2_Panasonic.avc -vsync 0 +fate-h264-conformance-frext-frext3_panasonic_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt3_Panasonic.avc +fate-h264-conformance-frext-frext4_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt4_Panasonic.avc +fate-h264-conformance-frext-frext_mmco4_sony_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt_MMCO4_Sony_B.264 +fate-h264-conformance-frext-hcaff1_hhi_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFF1_HHI.264 +fate-h264-conformance-frext-hcafr1_hhi_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR1_HHI.264 +fate-h264-conformance-frext-hcafr2_hhi_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR2_HHI.264 +fate-h264-conformance-frext-hcafr3_hhi_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR3_HHI.264 +fate-h264-conformance-frext-hcafr4_hhi_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR4_HHI.264 +fate-h264-conformance-frext-hcamff1_hhi_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAMFF1_HHI.264 +fate-h264-conformance-frext-hi422fr10_sony_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR10_SONY_B.264 +fate-h264-conformance-frext-hi422fr13_sony_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR13_SONY_B.264 -pix_fmt yuv422p10le -vf scale +fate-h264-conformance-frext-hi422fr1_sony_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR1_SONY_A.jsv +fate-h264-conformance-frext-hi422fr6_sony_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Hi422FR6_SONY_A.jsv -pix_fmt yuv422p10le -vf scale +fate-h264-conformance-frext-hpca_brcm_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCA_BRCM_C.264 +fate-h264-conformance-frext-hpcadq_brcm_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCADQ_BRCM_B.264 +fate-h264-conformance-frext-hpcafl_bcrm_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAFL_BRCM_C.264 +fate-h264-conformance-frext-hpcaflnl_bcrm_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAFLNL_BRCM_C.264 +fate-h264-conformance-frext-hpcalq_brcm_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCALQ_BRCM_B.264 +fate-h264-conformance-frext-hpcamapalq_bcrm_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAMAPALQ_BRCM_B.264 -vsync 0 +fate-h264-conformance-frext-hpcamolq_brcm_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAMOLQ_BRCM_B.264 +fate-h264-conformance-frext-hpcanl_brcm_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCANL_BRCM_C.264 +fate-h264-conformance-frext-hpcaq2lq_brcm_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAQ2LQ_BRCM_B.264 +fate-h264-conformance-frext-hpcv_brcm_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCV_BRCM_A.264 +fate-h264-conformance-frext-hpcvfl_bcrm_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVFL_BRCM_A.264 +fate-h264-conformance-frext-hpcvflnl_bcrm_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVFLNL_BRCM_A.264 +fate-h264-conformance-frext-hpcvmolq_brcm_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVMOLQ_BRCM_B.264 +fate-h264-conformance-frext-hpcvnl_brcm_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVNL_BRCM_A.264 +fate-h264-conformance-frext-pph10i1_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I1_Panasonic_A.264 -pix_fmt yuv420p10le -vf scale +fate-h264-conformance-frext-pph10i2_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I2_Panasonic_A.264 -pix_fmt yuv420p10le -vf scale +fate-h264-conformance-frext-pph10i3_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I3_Panasonic_A.264 -pix_fmt yuv420p10le -vf scale +fate-h264-conformance-frext-pph10i4_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I4_Panasonic_A.264 -pix_fmt yuv420p10le -vf scale +fate-h264-conformance-frext-pph10i5_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I5_Panasonic_A.264 -pix_fmt yuv420p10le -vf scale +fate-h264-conformance-frext-pph10i6_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I6_Panasonic_A.264 -pix_fmt yuv420p10le -vf scale +fate-h264-conformance-frext-pph10i7_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I7_Panasonic_A.264 -pix_fmt yuv420p10le -vf scale +fate-h264-conformance-frext-pph422i1_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I1_Panasonic_A.264 -pix_fmt yuv422p10le -vf scale +fate-h264-conformance-frext-pph422i2_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I2_Panasonic_A.264 -pix_fmt yuv422p10le -vf scale +fate-h264-conformance-frext-pph422i3_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I3_Panasonic_A.264 -pix_fmt yuv422p10le -vf scale +fate-h264-conformance-frext-pph422i4_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I4_Panasonic_A.264 -pix_fmt yuv422p10le -vf scale +fate-h264-conformance-frext-pph422i5_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I5_Panasonic_A.264 -pix_fmt yuv422p10le -vf scale +fate-h264-conformance-frext-pph422i6_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I6_Panasonic_A.264 -pix_fmt yuv422p10le -vf scale +fate-h264-conformance-frext-pph422i7_panasonic_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH422I7_Panasonic_A.264 -pix_fmt yuv422p10le -vf scale +fate-h264-conformance-hcbp2_hhi_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/HCBP2_HHI_A.264 +fate-h264-conformance-hcmp1_hhi_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/HCMP1_HHI_A.264 +fate-h264-conformance-ls_sva_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/LS_SVA_D.264 +fate-h264-conformance-midr_mw_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MIDR_MW_D.264 +fate-h264-conformance-mps_mw_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MPS_MW_A.264 +fate-h264-conformance-mr1_bt_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR1_BT_A.h264 +fate-h264-conformance-mr1_mw_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR1_MW_A.264 +fate-h264-conformance-mr2_mw_a: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR2_MW_A.264 +fate-h264-conformance-mr2_tandberg_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR2_TANDBERG_E.264 +fate-h264-conformance-mr3_tandberg_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR3_TANDBERG_B.264 +fate-h264-conformance-mr4_tandberg_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR4_TANDBERG_C.264 +fate-h264-conformance-mr5_tandberg_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR5_TANDBERG_C.264 +fate-h264-conformance-mr6_bt_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR6_BT_B.h264 +fate-h264-conformance-mr7_bt_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR7_BT_B.h264 +fate-h264-conformance-mr8_bt_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR8_BT_B.h264 +fate-h264-conformance-mr9_bt_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR9_BT_B.h264 +fate-h264-conformance-mv1_brcm_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/src19td.IBP.264 +fate-h264-conformance-nl1_sony_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NL1_Sony_D.jsv +fate-h264-conformance-nl2_sony_h: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NL2_Sony_H.jsv +fate-h264-conformance-nl3_sva_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NL3_SVA_E.264 +fate-h264-conformance-nlmq1_jvc_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NLMQ1_JVC_C.264 +fate-h264-conformance-nlmq2_jvc_c: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NLMQ2_JVC_C.264 +fate-h264-conformance-nrf_mw_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NRF_MW_E.264 +fate-h264-conformance-sharp_mp_field_1_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_1_B.jvt +fate-h264-conformance-sharp_mp_field_2_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_2_B.jvt +fate-h264-conformance-sharp_mp_field_3_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_3_B.jvt +fate-h264-conformance-sharp_mp_paff_1r2: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_PAFF_1r2.jvt +fate-h264-conformance-sharp_mp_paff_2r: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_PAFF_2.jvt +fate-h264-conformance-sl1_sva_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SL1_SVA_B.264 +fate-h264-conformance-sva_ba1_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_BA1_B.264 +fate-h264-conformance-sva_ba2_d: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_BA2_D.264 +fate-h264-conformance-sva_base_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_Base_B.264 +fate-h264-conformance-sva_cl1_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_CL1_E.264 +fate-h264-conformance-sva_fm1_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_FM1_E.264 +fate-h264-conformance-sva_nl1_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL1_B.264 +fate-h264-conformance-sva_nl2_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL2_E.264 fate-h264-bsf-mp4toannexb: CMD = md5 -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -c:v copy -f h264 @@ -429,12 +429,12 @@ fate-h264-extradata-reload: CMD = framemd5 -i $(TARGET_SAM fate-h264-extreme-plane-pred: CMD = framemd5 -i $(TARGET_SAMPLES)/h264/extreme-plane-pred.h264 fate-h264-interlace-crop: CMD = framecrc -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -frames:v 3 fate-h264-brokensps-2580: CMD = framecrc -i $(TARGET_SAMPLES)/h264/brokensps.flv -vf format=yuv420p,scale=w=192:h=144 -sws_flags bitexact+bilinear -fate-h264-xavc-4389: CMD = framecrc -i $(TARGET_SAMPLES)/h264/SonyXAVC_LongGOP_green_pixelation_early_Frames.MXF -pix_fmt yuv422p10le +fate-h264-xavc-4389: CMD = framecrc -i $(TARGET_SAMPLES)/h264/SonyXAVC_LongGOP_green_pixelation_early_Frames.MXF -pix_fmt yuv422p10le -vf scale -af aresample fate-h264-attachment-631: CMD = framecrc -i $(TARGET_SAMPLES)/h264/attachment631-small.mp4 -an -max_error_rate 0.96 -fate-h264-skip-nokey: CMD = framecrc -skip_frame nokey -i $(TARGET_SAMPLES)/h264/h264_intra_first-small.ts -fate-h264-skip-nointra: CMD = framecrc -skip_frame nointra -i $(TARGET_SAMPLES)/h264/h264_intra_first-small.ts +fate-h264-skip-nokey: CMD = framecrc -skip_frame nokey -i $(TARGET_SAMPLES)/h264/h264_intra_first-small.ts -vf scale -af aresample +fate-h264-skip-nointra: CMD = framecrc -skip_frame nointra -i $(TARGET_SAMPLES)/h264/h264_intra_first-small.ts -vf scale -af aresample fate-h264-intra-refresh-recovery: CMD = framecrc -i $(TARGET_SAMPLES)/h264/intra_refresh.h264 -frames:v 10 -fate-h264-invalid-ref-mod: CMD = framecrc -i $(TARGET_SAMPLES)/h264/h264refframeregression.mp4 -an -frames 10 -pix_fmt yuv420p10le +fate-h264-invalid-ref-mod: CMD = framecrc -i $(TARGET_SAMPLES)/h264/h264refframeregression.mp4 -an -frames 10 -pix_fmt yuv420p10le -vf scale fate-h264-lossless: CMD = framecrc -i $(TARGET_SAMPLES)/h264/lossless.h264 fate-h264-mixed-nal-coding: CMD = framecrc -i $(TARGET_SAMPLES)/h264/mixed-nal-coding.mp4 fate-h264-ref-pic-mod-overflow: CMD = framecrc -i $(TARGET_SAMPLES)/h264/ref-pic-mod-overflow.h264 @@ -444,7 +444,7 @@ fate-h264-3386: CMD = framecrc -i $(TARGET_SAM fate-h264-missing-frame: CMD = framecrc -i $(TARGET_SAMPLES)/h264/nondeterministic_cut.h264 fate-h264-timecode: CMD = framecrc -i $(TARGET_SAMPLES)/h264/crew_cif_timecode-2.h264 -fate-h264-reinit-%: CMD = framecrc -i $(TARGET_SAMPLES)/h264/$(@:fate-h264-%=%).h264 -vf format=yuv444p10le,scale=w=352:h=288 +fate-h264-reinit-%: CMD = framecrc -i $(TARGET_SAMPLES)/h264/$(@:fate-h264-%=%).h264 -vf scale,format=yuv444p10le,scale=w=352:h=288 fate-h264-dts_5frames: CMD = probeframes $(TARGET_SAMPLES)/h264/dts_5frames.mkv diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index 65c5a262e..f6ea1df9a 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -192,27 +192,27 @@ HEVC_SAMPLES_444_12BIT_LARGE = \ define FATE_HEVC_TEST FATE_HEVC += fate-hevc-conformance-$(1) -fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -vsync drop -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv420p +fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv420p endef define FATE_HEVC_TEST_10BIT FATE_HEVC += fate-hevc-conformance-$(1) -fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv420p10le +fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv420p10le -vf scale endef define FATE_HEVC_TEST_422_10BIT FATE_HEVC += fate-hevc-conformance-$(1) -fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv422p10le +fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv422p10le -vf scale endef define FATE_HEVC_TEST_422_10BIN FATE_HEVC += fate-hevc-conformance-$(1) -fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bin -pix_fmt yuv422p10le +fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bin -pix_fmt yuv422p10le -vf scale endef define FATE_HEVC_TEST_422_10BIN_LARGE FATE_HEVC_LARGE += fate-hevc-conformance-$(1) -fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bin -pix_fmt yuv422p10le +fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bin -pix_fmt yuv422p10le -vf scale endef define FATE_HEVC_TEST_444_8BIT @@ -222,12 +222,12 @@ endef define FATE_HEVC_TEST_444_12BIT FATE_HEVC += fate-hevc-conformance-$(1) -fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv444p12le +fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv444p12le -vf scale endef define FATE_HEVC_TEST_444_12BIT_LARGE FATE_HEVC_LARGE += fate-hevc-conformance-$(1) -fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv444p12le +fate-hevc-conformance-$(1): CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv444p12le -vf scale endef $(foreach N,$(HEVC_SAMPLES),$(eval $(call FATE_HEVC_TEST,$(N)))) @@ -270,12 +270,18 @@ FATE_HEVC_FFPROBE-$(call DEMDEC, HEVC, HEVC) += fate-hevc-paired-fields fate-hevc-monochrome-crop: CMD = probeframes -show_entries frame=width,height:stream=width,height $(TARGET_SAMPLES)/hevc/hevc-monochrome.hevc FATE_HEVC_FFPROBE-$(call DEMDEC, HEVC, HEVC) += fate-hevc-monochrome-crop +fate-hevc-hdr10-plus-metadata: CMD = probeframes -show_entries frame=side_data_list $(TARGET_SAMPLES)/hevc/hdr10_plus_h265_sample.hevc +FATE_HEVC_FFPROBE-$(call DEMDEC, HEVC, HEVC) += fate-hevc-hdr10-plus-metadata + fate-hevc-two-first-slice: CMD = threads=2 framemd5 -i $(TARGET_SAMPLES)/hevc/two_first_slice.mp4 -sws_flags bitexact -t 00:02.00 -an FATE_HEVC-$(call DEMDEC, MOV, HEVC) += fate-hevc-two-first-slice fate-hevc-cabac-tudepth: CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc/cbf_cr_cb_TUDepth_4_circle.h265 -pix_fmt yuv444p FATE_HEVC-$(call DEMDEC, HEVC, HEVC) += fate-hevc-cabac-tudepth +fate-hevc-small422chroma: CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc/food.hevc -pix_fmt yuv422p10le -vf scale +FATE_HEVC-$(call DEMDEC, HEVC, HEVC) += fate-hevc-small422chroma + FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) FATE_SAMPLES_FFPROBE += $(FATE_HEVC_FFPROBE-yes) diff --git a/tests/fate/hlsenc.mak b/tests/fate/hlsenc.mak index 43f93c8c5..aff81a83f 100644 --- a/tests/fate/hlsenc.mak +++ b/tests/fate/hlsenc.mak @@ -50,7 +50,7 @@ tests/data/hls_segment_size.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data FATE_HLSENC-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-hls-segment-size fate-hls-segment-size: tests/data/hls_segment_size.m3u8 -fate-hls-segment-size: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_segment_size.m3u8 -vf setpts=N*23 +fate-hls-segment-size: CMD = framecrc -auto_conversion_filters -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_segment_size.m3u8 -vf setpts=N*23 tests/data/hls_segment_single.m3u8: TAG = GEN tests/data/hls_segment_single.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data @@ -61,7 +61,7 @@ tests/data/hls_segment_single.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data FATE_HLSENC-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-hls-segment-single fate-hls-segment-single: tests/data/hls_segment_single.m3u8 -fate-hls-segment-single: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_segment_single.m3u8 -vf setpts=N*23 +fate-hls-segment-single: CMD = framecrc -auto_conversion_filters -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_segment_single.m3u8 -vf setpts=N*23 tests/data/hls_init_time.m3u8: TAG = GEN tests/data/hls_init_time.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data @@ -72,7 +72,7 @@ tests/data/hls_init_time.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data FATE_HLSENC-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-hls-init-time fate-hls-init-time: tests/data/hls_init_time.m3u8 -fate-hls-init-time: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_init_time.m3u8 -vf setpts=N*23 +fate-hls-init-time: CMD = framecrc -auto_conversion_filters -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_init_time.m3u8 -vf setpts=N*23 tests/data/hls_list_size.m3u8: TAG = GEN tests/data/hls_list_size.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data @@ -83,10 +83,10 @@ tests/data/hls_list_size.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data FATE_HLSENC-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-hls-list-size fate-hls-list-size: tests/data/hls_list_size.m3u8 -fate-hls-list-size: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_list_size.m3u8 -vf setpts=N*23 +fate-hls-list-size: CMD = framecrc -auto_conversion_filters -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_list_size.m3u8 -vf setpts=N*23 -tests/data/hls_segment_type_fmp4.m3u8: TAG = GEN -tests/data/hls_segment_type_fmp4.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data +tests/data/hls_fmp4.m3u8: TAG = GEN +tests/data/hls_fmp4.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ -f lavfi -re -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=5" -map 0 -codec:a mp2fixed \ -hls_segment_type mpegts -hls_fmp4_init_filename now.mp4 -hls_list_size 0 \ @@ -94,8 +94,21 @@ tests/data/hls_segment_type_fmp4.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data $(TARGET_PATH)/tests/data/hls_fmp4.m3u8 2>/dev/null FATE_HLSENC-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-hls-fmp4 -fate-hls-fmp4: tests/data/hls_segment_type_fmp4.m3u8 -fate-hls-fmp4: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_fmp4.m3u8 -vf setpts=N*23 +fate-hls-fmp4: tests/data/hls_fmp4.m3u8 +fate-hls-fmp4: CMD = framecrc -auto_conversion_filters -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_fmp4.m3u8 -vf setpts=N*23 -FATE_FFMPEG += $(FATE_HLSENC-yes) -fate-hlsenc: $(FATE_HLSENC-yes) +tests/data/hls_fmp4_ac3.m3u8: TAG = GEN +tests/data/hls_fmp4_ac3.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data + $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ + -stream_loop 4 -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3 -c copy -map 0 \ + -hls_segment_type fmp4 -hls_fmp4_init_filename now_ac3.mp4 -hls_list_size 0 \ + -hls_time 2 -hls_segment_filename "$(TARGET_PATH)/tests/data/hls_fmp4_ac3_%d.m4s" \ + $(TARGET_PATH)/tests/data/hls_fmp4_ac3.m3u8 2>/dev/null + +FATE_HLSENC_PROBE-$(call ALLYES, HLS_DEMUXER EAC3_DEMUXER) += fate-hls-fmp4_ac3 +fate-hls-fmp4_ac3: tests/data/hls_fmp4_ac3.m3u8 +fate-hls-fmp4_ac3: CMD = probeaudiostream $(TARGET_PATH)/tests/data/now_ac3.mp4 + +FATE_SAMPLES_FFMPEG += $(FATE_HLSENC-yes) +FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_HLSENC_PROBE-yes) +fate-hlsenc: $(FATE_HLSENC-yes) $(FATE_HLSENC_PROBE-yes) diff --git a/tests/fate/image.mak b/tests/fate/image.mak index 44fd06c29..eca8d5ab2 100644 --- a/tests/fate/image.mak +++ b/tests/fate/image.mak @@ -15,10 +15,10 @@ FATE_BRENDERPIX += fate-brenderpix-565 fate-brenderpix-565: CMD = framecrc -c:v brender_pix -i $(TARGET_SAMPLES)/brenderpix/maximafront.pix FATE_BRENDERPIX += fate-brenderpix-defpal -fate-brenderpix-defpal: CMD = framecrc -c:v brender_pix -i $(TARGET_SAMPLES)/brenderpix/rivrock1.pix -pix_fmt rgb24 +fate-brenderpix-defpal: CMD = framecrc -c:v brender_pix -i $(TARGET_SAMPLES)/brenderpix/rivrock1.pix -pix_fmt rgb24 -vf scale FATE_BRENDERPIX += fate-brenderpix-intpal -fate-brenderpix-intpal: CMD = framecrc -c:v brender_pix -i $(TARGET_SAMPLES)/brenderpix/testtex.pix -pix_fmt rgb24 +fate-brenderpix-intpal: CMD = framecrc -c:v brender_pix -i $(TARGET_SAMPLES)/brenderpix/testtex.pix -pix_fmt rgb24 -vf scale FATE_BRENDERPIX += fate-brenderpix-y400a fate-brenderpix-y400a: CMD = framecrc -c:v brender_pix -i $(TARGET_SAMPLES)/brenderpix/gears.pix @@ -28,11 +28,11 @@ FATE_IMAGE += $(FATE_BRENDERPIX-yes) fate-brenderpix: $(FATE_BRENDERPIX-yes) FATE_IMAGE-$(call PARSERDEMDEC, BMP, IMAGE2PIPE, BMP) += fate-bmpparser -fate-bmpparser: CMD = framecrc -f image2pipe -i $(TARGET_SAMPLES)/bmp/numbers.bmp -pix_fmt rgb24 +fate-bmpparser: CMD = framecrc -f image2pipe -i $(TARGET_SAMPLES)/bmp/numbers.bmp -pix_fmt rgb24 -vf scale define FATE_IMGSUITE_DDS FATE_DDS += fate-dds-$(1) -fate-dds-$(1): CMD = framecrc -i $(TARGET_SAMPLES)/dds/fate_$(1).dds $(DDS_OPTS_$(1)) +fate-dds-$(1): CMD = framecrc -i $(TARGET_SAMPLES)/dds/fate_$(1).dds $(DDS_OPTS_$(1)) -vf scale endef DDS_OPTS_pal = -sws_flags +accurate_rnd+bitexact -pix_fmt rgba @@ -97,6 +97,9 @@ fate-dpx: CMD = framecrc -i $(TARGET_SAMPLES)/dpx/lighthouse_rgb48.dpx FATE_SAMPLES_AVCONV-$(call PARSERDEMDEC, DPX, IMAGE2PIPE, DPX) += fate-dpxparser fate-dpxparser: CMD = framecrc -f image2pipe -i $(TARGET_SAMPLES)/dpx/lena_4x_concat.dpx -sws_flags +accurate_rnd+bitexact +FATE_IMAGE_PROBE-$(call DEMDEC, IMAGE2, DPX) += fate-dpx-probe +fate-dpx-probe: CMD = probeframes -show_entries frame=color_transfer,color_range,color_space,color_primaries,sample_aspect_ratio $(TARGET_SAMPLES)/dpx/cyan.dpx + FATE_EXR += fate-exr-slice-raw fate-exr-slice-raw: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgba_slice_raw.exr -pix_fmt gbrapf32le @@ -221,7 +224,7 @@ FATE_EXR += fate-exr-rgb-scanline-pxr24-float-half-l2 fate-exr-rgb-scanline-pxr24-float-half-l2: CMD = framecrc -layer "VRaySamplerInfo" -i $(TARGET_SAMPLES)/exr/rgb_scanline_pxr24_float_half.exr -pix_fmt gbrapf32le FATE_EXR += fate-exr-rgb-scanline-pxr24-half-uint32-13x9 -fate-exr-rgb-scanline-pxr24-half-uint32-13x9: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_pxr24_half_uint32_13x9.exr -pix_fmt rgb48le +fate-exr-rgb-scanline-pxr24-half-uint32-13x9: CMD = framecrc -layer "VRaySamplerInfo" -i $(TARGET_SAMPLES)/exr/rgb_scanline_pxr24_half_uint32_13x9.exr -pix_fmt rgb48le -vf scale FATE_EXR += fate-exr-rgb-scanline-zip-half-float-l1 fate-exr-rgb-scanline-zip-half-float-l1: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_zip_half_float.exr -pix_fmt gbrpf32le @@ -287,13 +290,46 @@ fate-exr-rgb-scanline-half-piz-dw-t08: CMD = framecrc -i $(TARGET_SAMPLES)/exr/r FATE_EXR += fate-exr-rgba-zip16-16x32-flag4 fate-exr-rgba-zip16-16x32-flag4: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgba_zip16_16x32_flag4.exr -pix_fmt gbrapf32le +FATE_EXR += fate-exr-ya-scanline-zip-half-12x8 +fate-exr-ya-scanline-zip-half-12x8: CMD = framecrc -i $(TARGET_SAMPLES)/exr/ya_scanline_zip_half_12x8.exr -pix_fmt gbrapf32le + +FATE_EXR += fate-exr-rgb-tile-half-zip +fate-exr-rgb-tile-half-zip: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_tile_half_zip.exr -pix_fmt gbrpf32le + +FATE_EXR += fate-exr-rgb-scanline-float-zip-dw-large +fate-exr-rgb-scanline-float-zip-dw-large: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_float_zip_dw_large.exr -pix_fmt gbrpf32le + +FATE_EXR += fate-exr-rgb-scanline-half-piz-dw-large +fate-exr-rgb-scanline-half-piz-dw-large: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_half_piz_dw_large.exr -pix_fmt gbrpf32le + +FATE_EXR += fate-exr-rgb-scanline-half-zip-dw-large +fate-exr-rgb-scanline-half-zip-dw-large: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_half_zip_dw_large.exr -pix_fmt gbrpf32le + +FATE_EXR += fate-exr-rgb-scanline-uint32-piz-dw-large +fate-exr-rgb-scanline-uint32-piz-dw-large: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_uint32_piz_dw_large.exr -pix_fmt rgb48le + +FATE_EXR += fate-exr-rgb-tile-half-piz-dw-large +fate-exr-rgb-tile-half-piz-dw-large: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_tile_half_piz_dw_large.exr -pix_fmt gbrpf32le + +FATE_EXR += fate-exr-rgb-tile-uint32-piz-dw-large +fate-exr-rgb-tile-uint32-piz-dw-large: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_tile_uint32_piz_dw_large.exr -pix_fmt rgb48le + +FATE_EXR += fate-exr-rgb-scanline-half-zip-dw-outside +fate-exr-rgb-scanline-half-zip-dw-outside: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_half_zip_dw_outside.exr -pix_fmt gbrpf32le + +FATE_EXR += fate-exr-rgb-tile-half-zip-dw-outside +fate-exr-rgb-tile-half-zip-dw-outside: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_tile_half_zip_dw_outside.exr -pix_fmt gbrpf32le + +FATE_EXR += fate-exr-rgb-scanline-zip-half-0x0-0xFFFF +fate-exr-rgb-scanline-zip-half-0x0-0xFFFF: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_zip_half_float_0x0_to_0xFFFF.exr -pix_fmt gbrpf32le + FATE_EXR-$(call DEMDEC, IMAGE2, EXR) += $(FATE_EXR) FATE_IMAGE += $(FATE_EXR-yes) fate-exr: $(FATE_EXR-yes) FATE_JPG += fate-jpg-12bpp -fate-jpg-12bpp: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/jpg/12bpp.jpg -f rawvideo -pix_fmt gray16le -vf setsar=sar=sar +fate-jpg-12bpp: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/jpg/12bpp.jpg -f rawvideo -pix_fmt gray16le -vf setsar=sar=sar,scale FATE_JPG += fate-jpg-jfif fate-jpg-jfif: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/jpg/20242.jpg @@ -306,32 +342,32 @@ FATE_IMAGE-$(call DEMDEC, IMAGE2, QDRAW) += fate-pict fate-pict: CMD = framecrc -i $(TARGET_SAMPLES)/quickdraw/TRU256.PCT -pix_fmt rgb24 FATE_IMAGE-$(call DEMDEC, IMAGE2, PICTOR) += fate-pictor -fate-pictor: CMD = framecrc -i $(TARGET_SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24 +fate-pictor: CMD = framecrc -i $(TARGET_SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24 -vf scale FATE_IMAGE-$(call PARSERDEMDEC, PNG, IMAGE2PIPE, PNG) += fate-pngparser fate-pngparser: CMD = framecrc -f image2pipe -i $(TARGET_SAMPLES)/png1/feed_4x_concat.png -pix_fmt rgba define FATE_IMGSUITE_PNG FATE_PNG += fate-png-$(1) -fate-png-$(1): CMD = framecrc -i $(TARGET_SAMPLES)/png1/lena-$(1).png -sws_flags +accurate_rnd+bitexact -pix_fmt rgb24 +fate-png-$(1): CMD = framecrc -auto_conversion_filters -i $(TARGET_SAMPLES)/png1/lena-$(1).png -sws_flags +accurate_rnd+bitexact -pix_fmt rgb24 endef PNG_COLORSPACES = gray8 gray16 rgb24 rgb48 rgba rgba64 ya8 ya16 $(foreach CLSP,$(PNG_COLORSPACES),$(eval $(call FATE_IMGSUITE_PNG,$(CLSP)))) FATE_PNG += fate-png-int-rgb24 -fate-png-int-rgb24: CMD = framecrc -i $(TARGET_SAMPLES)/png1/lena-int_rgb24.png -sws_flags +accurate_rnd+bitexact -pix_fmt rgb24 +fate-png-int-rgb24: CMD = framecrc -i $(TARGET_SAMPLES)/png1/lena-int_rgb24.png -sws_flags +accurate_rnd+bitexact FATE_PNG-$(call DEMDEC, IMAGE2, PNG) += $(FATE_PNG) FATE_IMAGE += $(FATE_PNG-yes) fate-png: $(FATE_PNG-yes) FATE_IMAGE-$(call DEMDEC, IMAGE2, PTX) += fate-ptx -fate-ptx: CMD = framecrc -i $(TARGET_SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24 +fate-ptx: CMD = framecrc -i $(TARGET_SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24 -vf scale define FATE_IMGSUITE_PSD FATE_PSD += fate-psd-$(1) -fate-psd-$(1): CMD = framecrc -i $(TARGET_SAMPLES)/psd/lena-$(1).psd -sws_flags +accurate_rnd+bitexact -pix_fmt rgb24 +fate-psd-$(1): CMD = framecrc -i $(TARGET_SAMPLES)/psd/lena-$(1).psd -sws_flags +accurate_rnd+bitexact -pix_fmt rgb24 -vf scale endef PSD_COLORSPACES = gray8 gray16 rgb24 rgb48 rgba rgba64 ya8 ya16 @@ -383,13 +419,13 @@ FATE_SUNRASTER += fate-sunraster-1bit-rle fate-sunraster-1bit-rle: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-1bit-rle.sun FATE_SUNRASTER += fate-sunraster-8bit-raw -fate-sunraster-8bit-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-8bit-raw.sun -pix_fmt rgb24 +fate-sunraster-8bit-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-8bit-raw.sun -pix_fmt rgb24 -vf scale FATE_SUNRASTER += fate-sunraster-8bit_gray-raw fate-sunraster-8bit_gray-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/gray.ras FATE_SUNRASTER += fate-sunraster-8bit-rle -fate-sunraster-8bit-rle: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-8bit-rle.sun -pix_fmt rgb24 +fate-sunraster-8bit-rle: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-8bit-rle.sun -pix_fmt rgb24 -vf scale FATE_SUNRASTER += fate-sunraster-24bit-raw fate-sunraster-24bit-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-24bit-raw.sun @@ -422,12 +458,12 @@ FATE_IMAGE += $(FATE_TARGA-yes) fate-targa: $(FATE_TARGA-yes) fate-targa-conformance-CBW8: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CBW8.TGA -fate-targa-conformance-CCM8: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CCM8.TGA -pix_fmt rgba +fate-targa-conformance-CCM8: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CCM8.TGA -pix_fmt rgba -vf scale fate-targa-conformance-CTC16: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CTC16.TGA -pix_fmt rgb555le fate-targa-conformance-CTC24: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CTC24.TGA fate-targa-conformance-CTC32: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CTC32.TGA -pix_fmt bgra fate-targa-conformance-UBW8: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UBW8.TGA -fate-targa-conformance-UCM8: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UCM8.TGA -pix_fmt rgba +fate-targa-conformance-UCM8: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UCM8.TGA -pix_fmt rgba -vf scale fate-targa-conformance-UTC16: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UTC16.TGA -pix_fmt rgb555le fate-targa-conformance-UTC24: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UTC24.TGA fate-targa-conformance-UTC32: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UTC32.TGA -pix_fmt bgra @@ -452,7 +488,7 @@ FATE_WEBP += fate-webp-rgb-lena-lossless fate-webp-rgb-lena-lossless: CMD = framecrc -i $(TARGET_SAMPLES)/webp/rgb_lena_lossless.webp FATE_WEBP += fate-webp-rgb-lena-lossless-rgb24 -fate-webp-rgb-lena-lossless-rgb24: CMD = framecrc -i $(TARGET_SAMPLES)/webp/rgb_lena_lossless.webp -pix_fmt rgb24 +fate-webp-rgb-lena-lossless-rgb24: CMD = framecrc -i $(TARGET_SAMPLES)/webp/rgb_lena_lossless.webp -pix_fmt rgb24 -vf scale FATE_WEBP += fate-webp-rgba-lossless fate-webp-rgba-lossless: CMD = framecrc -i $(TARGET_SAMPLES)/webp/rgba_lossless.webp @@ -481,6 +517,9 @@ FATE_IMAGE += $(FATE_XBM-yes) fate-xbm: $(FATE_XBM-yes) FATE_IMAGE += $(FATE_IMAGE-yes) +FATE_IMAGE_PROBE += $(FATE_IMAGE_PROBE-yes) FATE_SAMPLES_FFMPEG += $(FATE_IMAGE) -fate-image: $(FATE_IMAGE) +FATE_SAMPLES_FFPROBE += $(FATE_IMAGE_PROBE) + +fate-image: $(FATE_IMAGE) $(FATE_IMAGE_PROBE) diff --git a/tests/fate/lavf-audio.mak b/tests/fate/lavf-audio.mak index 0be7a3a05..a0600491a 100644 --- a/tests/fate/lavf-audio.mak +++ b/tests/fate/lavf-audio.mak @@ -36,3 +36,8 @@ fate-lavf-peak_only.wav: CMD = lavf_audio "" "-write_peak only" FATE_AVCONV += $(FATE_LAVF_AUDIO) fate-lavf-audio fate-lavf: $(FATE_LAVF_AUDIO) + +FATE_WAV_FFPROBE-$(CONFIG_WAV_DEMUXER) += fate-wav-chapters +fate-wav-chapters: CMD = probechapters $(TARGET_SAMPLES)/wav/200828-005.wav + +FATE_SAMPLES_FFPROBE += $(FATE_WAV_FFPROBE-yes) diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak index 747dae370..682296914 100644 --- a/tests/fate/libavcodec.mak +++ b/tests/fate/libavcodec.mak @@ -65,10 +65,6 @@ fate-mpeg12framerate: libavcodec/tests/mpeg12framerate$(EXESUF) fate-mpeg12framerate: CMD = run libavcodec/tests/mpeg12framerate$(EXESUF) fate-mpeg12framerate: REF = /dev/null -FATE_LIBAVCODEC-yes += fate-libavcodec-options -fate-libavcodec-options: libavcodec/tests/options$(EXESUF) -fate-libavcodec-options: CMD = run libavcodec/tests/options$(EXESUF) - FATE_LIBAVCODEC-$(CONFIG_RANGECODER) += fate-rangecoder fate-rangecoder: libavcodec/tests/rangecoder$(EXESUF) fate-rangecoder: CMD = run libavcodec/tests/rangecoder$(EXESUF) diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak index fed481b3d..f2108016a 100644 --- a/tests/fate/libswresample.mak +++ b/tests/fate/libswresample.mak @@ -1089,7 +1089,7 @@ FATE_SWR += $(FATE_SWR_RESAMPLE-yes) FATE_SWR_AUDIOCONVERT-$(call FILTERDEMDECENCMUX, AFORMAT AEVAL, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-swr-audioconvert fate-swr-audioconvert: tests/data/asynth-44100-1.wav fate-swr-audioconvert: REF = tests/data/asynth-44100-1.wav -fate-swr-audioconvert: CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-44100-1.wav -af "aformat=fltp,aeval=val(0)+(random(0)-0.5)/33000,aformat=fltp" -f wav -c:a pcm_s16le - +fate-swr-audioconvert: CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-44100-1.wav -af "aresample,aformat=fltp,aresample,aeval=val(0)+(random(0)-0.5)/33000,aresample,aformat=fltp,aresample" -f wav -c:a pcm_s16le - fate-swr-audioconvert: CMP = stddev fate-swr-audioconvert: FUZZ = 0 diff --git a/tests/fate/libswscale.mak b/tests/fate/libswscale.mak index 68eb159fe..5ec5f34cc 100644 --- a/tests/fate/libswscale.mak +++ b/tests/fate/libswscale.mak @@ -2,6 +2,10 @@ FATE_LIBSWSCALE += fate-sws-pixdesc-query fate-sws-pixdesc-query: libswscale/tests/pixdesc_query$(EXESUF) fate-sws-pixdesc-query: CMD = run libswscale/tests/pixdesc_query$(EXESUF) +FATE_LIBSWSCALE += fate-sws-floatimg-cmp +fate-sws-floatimg-cmp: libswscale/tests/floatimg_cmp$(EXESUF) +fate-sws-floatimg-cmp: CMD = run libswscale/tests/floatimg_cmp$(EXESUF) + FATE_LIBSWSCALE += $(FATE_LIBSWSCALE-yes) FATE-$(CONFIG_SWSCALE) += $(FATE_LIBSWSCALE) fate-libswscale: $(FATE_LIBSWSCALE) diff --git a/tests/fate/lossless-audio.mak b/tests/fate/lossless-audio.mak index 66ac6d897..435119d77 100644 --- a/tests/fate/lossless-audio.mak +++ b/tests/fate/lossless-audio.mak @@ -1,17 +1,17 @@ FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, MOV, ALAC) += fate-lossless-alac -fate-lossless-alac: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/inside.m4a -f s16le +fate-lossless-alac: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/inside.m4a -f s16le -af aresample FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, MLP, MLP) += fate-lossless-meridianaudio fate-lossless-meridianaudio: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.mlp -f s16le FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, RM, RALF) += fate-ralf -fate-ralf: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.rmvb -vn -f s16le +fate-ralf: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.rmvb -vn -f s16le -af aresample FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, SHORTEN, SHORTEN) += fate-lossless-shorten -fate-lossless-shorten: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le +fate-lossless-shorten: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le -af aresample FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, TAK, TAK) += fate-lossless-tak -fate-lossless-tak: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.tak +fate-lossless-tak: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.tak -af aresample FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, TTA, TTA) += fate-lossless-tta fate-lossless-tta: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/inside.tta @@ -20,10 +20,10 @@ FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, TTA, TTA) += fate-lossless-tta-encryp fate-lossless-tta-encrypted: CMD = crc -password ffmpeg -i $(TARGET_SAMPLES)/lossless-audio/encrypted.tta FATE_SAMPLES_LOSSLESS_AUDIO-$(call DEMDEC, ASF, WMALOSSLESS) += fate-lossless-wma fate-lossless-wma24-1 fate-lossless-wma24-2 fate-lossless-wma24-rawtile -fate-lossless-wma: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le -frames 209 -fate-lossless-wma24-1: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/master_audio_2.0_24bit.wma -f s24le -fate-lossless-wma24-2: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/Mega_Weird_Audio_Test_24bit.wma -f s24le -fate-lossless-wma24-rawtile: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/g2_24bit.wma -f s24le +fate-lossless-wma: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le -frames 209 -af aresample +fate-lossless-wma24-1: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/master_audio_2.0_24bit.wma -f s24le -af aresample +fate-lossless-wma24-2: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/Mega_Weird_Audio_Test_24bit.wma -f s24le -af aresample +fate-lossless-wma24-rawtile: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/g2_24bit.wma -f s24le -af aresample fate-lossless-wmall: fate-lossless-wma fate-lossless-wma24-1 fate-lossless-wma24-2 fate-lossless-wma24-rawtile FATE_SAMPLES_LOSSLESS_AUDIO += $(FATE_SAMPLES_LOSSLESS_AUDIO-yes) diff --git a/tests/fate/lossless-video.mak b/tests/fate/lossless-video.mak index 1e2769c20..a81c6e9ab 100644 --- a/tests/fate/lossless-video.mak +++ b/tests/fate/lossless-video.mak @@ -2,7 +2,7 @@ FATE_LAGARITH += fate-lagarith-rgb24 fate-lagarith-rgb24: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-rgb24.avi FATE_LAGARITH += fate-lagarith-rgb32 -fate-lagarith-rgb32: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-rgb32.avi -pix_fmt bgra +fate-lagarith-rgb32: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-rgb32.avi -pix_fmt bgra -vf scale FATE_LAGARITH += fate-lagarith-yuy2 fate-lagarith-yuy2: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-yuy2.avi @@ -13,12 +13,11 @@ fate-lagarith-yv12: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-yv12.avi FATE_LAGARITH += fate-lagarith-red fate-lagarith-red: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lagarith-red.avi -FATE_LAGARITH += fate-lagarith-ticket4119 fate-lagarith-ticket4119-cfr fate-lagarith-ticket4119-vfr fate-lagarith-ticket4119-pass fate-lagarith-ticket4119-drop +FATE_LAGARITH += fate-lagarith-ticket4119 fate-lagarith-ticket4119-cfr fate-lagarith-ticket4119-vfr fate-lagarith-ticket4119-pass fate-lagarith-ticket4119: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lagarith-1.3.27-black-frames-and-off-by-ones.avi fate-lagarith-ticket4119-cfr : CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lagarith-1.3.27-black-frames-and-off-by-ones.avi -vsync cfr fate-lagarith-ticket4119-vfr : CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lagarith-1.3.27-black-frames-and-off-by-ones.avi -vsync vfr fate-lagarith-ticket4119-pass: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lagarith-1.3.27-black-frames-and-off-by-ones.avi -vsync passthrough -fate-lagarith-ticket4119-drop: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lagarith-1.3.27-black-frames-and-off-by-ones.avi -vsync drop FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, LAGARITH) += $(FATE_LAGARITH) fate-lagarith: $(FATE_LAGARITH) @@ -33,7 +32,7 @@ FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, LOCO) += $(FATE_LOCO) fate-loco: $(FATE_LOCO) FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, MSRLE) += fate-msrle-8bit -fate-msrle-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24 +fate-msrle-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24 -vf scale FATE_LOSSLESS_VIDEO-$(call DEMDEC, AVI, MSZH) += fate-mszh fate-mszh: CMD = framecrc -i $(TARGET_SAMPLES)/lcl/mszh-1frame.avi diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak index 17fbf4665..8a46b1f0c 100644 --- a/tests/fate/matroska.mak +++ b/tests/fate/matroska.mak @@ -57,9 +57,62 @@ FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, MATROSKA_DEMUXER OGG_DEMUXER \ += fate-webm-dash-chapters fate-webm-dash-chapters: CMD = transcode ogg $(TARGET_SAMPLES)/vorbis/vorbis_chapter_extension_demo.ogg webm "-c copy -cluster_time_limit 1500 -dash 1 -dash_track_number 124 -reserve_index_space 400" "-c copy -t 0.5" "" -show_chapters +# The input file has a Block whose payload has a size of zero before reversing +# header removal compression; it furthermore uses chained SeekHeads and has +# level 1-elements after the Cluster. This is tested on the demuxer's side. +# For the muxer this tests that it can correctly write huge TrackNumbers and +# that it can expand the Cues element's length field by one byte if necessary. +# It furthermore tests correct propagation of the description tag. +FATE_MATROSKA_FFMPEG_FFPROBE-$(call DEMMUX, MATROSKA, MATROSKA) \ + += fate-matroska-zero-length-block +fate-matroska-zero-length-block: CMD = transcode matroska $(TARGET_SAMPLES)/mkv/zero_length_block.mks matroska "-c:s copy -dash 1 -dash_track_number 2000000000 -reserve_index_space 62 -metadata_header_padding 1" "-c:s copy" "" "-show_entries stream_tags=description" + +# This test the following features of the Matroska muxer: Writing projection +# stream side-data; not setting any track to default if the user requested it; +# and modifying and writing colorspace properties. +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, MATROSKA_DEMUXER MATROSKA_MUXER \ + H264_DECODER H264_PARSER) \ + += fate-matroska-spherical-mono-remux +fate-matroska-spherical-mono-remux: CMD = transcode matroska $(TARGET_SAMPLES)/mkv/spherical.mkv matroska "-map 0 -map 0 -c copy -disposition:0 -default+forced -disposition:1 -default -default_mode passthrough -color_primaries:1 bt709 -color_trc:1 smpte170m -colorspace:1 bt2020c -color_range:1 pc" "-map 0 -c copy -t 0" "" "-show_entries stream_side_data_list:stream_disposition=default,forced:stream=color_range,color_space,color_primaries,color_transfer" + +# The input file of the following test contains Content Light Level as well as +# Mastering Display Metadata and so this test tests correct muxing and demuxing +# of these. It furthermore also tests that this data is correctly propagated +# when reencoding (here to ffv1). +# Both input audio tracks are completely zero, so the noise bsf is used +# to make this test interesting. +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL MXF_DEMUXER \ + PRORES_DECODER PCM_S24LE_DECODER \ + FFV1_ENCODER ARESAMPLE_FILTER \ + PCM_S16BE_ENCODER NOISE_BSF \ + MATROSKA_MUXER MATROSKA_DEMUXER \ + FRAMECRC_MUXER PIPE_PROTOCOL) \ + += fate-matroska-mastering-display-metadata +fate-matroska-mastering-display-metadata: CMD = transcode mxf $(TARGET_SAMPLES)/mxf/Meridian-Apple_ProResProxy-HDR10.mxf matroska "-map 0 -map 0:0 -c:v:0 copy -c:v:1 ffv1 -c:a:0 copy -bsf:a:0 noise=amount=3 -filter:a:1 aresample -c:a:1 pcm_s16be -bsf:a:1 noise=dropamount=4" "-map 0 -c copy" "" "-show_entries stream_side_data_list:stream=index,codec_name" + +# Tests writing BlockAdditional and BlockGroups with ReferenceBlock elements; +# it also tests setting a track as suitable for hearing impaired. +# It also tests the capability of the VP8 parser to set the keyframe flag +# (the input file lacks ReferenceBlock elements making everything a keyframe). +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL MATROSKA_DEMUXER \ + VP8_PARSER MATROSKA_MUXER \ + FRAMECRC_MUXER PIPE_PROTOCOL) \ + += fate-matroska-vp8-alpha-remux +fate-matroska-vp8-alpha-remux: CMD = transcode matroska $(TARGET_SAMPLES)/vp8_alpha/vp8_video_with_alpha.webm matroska "-c copy -disposition +hearing_impaired -cluster_size_limit 100000" "-c copy -t 0.2" "" "-show_entries stream_disposition:stream_side_data_list" + +# The audio stream to be remuxed here has AV_DISPOSITION_VISUAL_IMPAIRED. +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL MPEGTS_DEMUXER \ + AC3_DECODER MATROSKA_MUXER \ + MATROSKA_DEMUXER FRAMECRC_MUXER \ + PIPE_PROTOCOL) \ + += fate-matroska-mpegts-remux +fate-matroska-mpegts-remux: CMD = transcode mpegts $(TARGET_SAMPLES)/mpegts/pmtchange.ts matroska "-map 0:2 -map 0:2 -c copy -disposition:a:1 -visual_impaired+hearing_impaired" "-map 0 -c copy" "" "-show_entries stream_disposition:stream=index" + FATE_MATROSKA_FFPROBE-$(call ALLYES, MATROSKA_DEMUXER) += fate-matroska-spherical-mono fate-matroska-spherical-mono: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mkv/spherical.mkv FATE_SAMPLES_AVCONV += $(FATE_MATROSKA-yes) FATE_SAMPLES_FFPROBE += $(FATE_MATROSKA_FFPROBE-yes) FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MATROSKA_FFMPEG_FFPROBE-yes) + +fate-matroska: $(FATE_MATROSKA-yes) $(FATE_MATROSKA_FFPROBE-yes) $(FATE_MATROSKA_FFMPEG_FFPROBE-yes) diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak index a2c3b626c..639757880 100644 --- a/tests/fate/microsoft.mak +++ b/tests/fate/microsoft.mak @@ -11,10 +11,10 @@ FATE_MSS2 += fate-mss2-pals fate-mss2-pals: CMD = framecrc -i $(TARGET_SAMPLES)/mss2/rlepals.wmv FATE_MSS2 += fate-mss2-rgb555 -fate-mss2-rgb555: CMD = framecrc -i $(TARGET_SAMPLES)/mss2/rle555.wmv -pix_fmt rgb555le +fate-mss2-rgb555: CMD = framecrc -i $(TARGET_SAMPLES)/mss2/rle555.wmv -pix_fmt rgb555le -vf scale FATE_MSS2 += fate-mss2-rgb555s -fate-mss2-rgb555s: CMD = framecrc -i $(TARGET_SAMPLES)/mss2/rle555s.wmv -pix_fmt rgb555le +fate-mss2-rgb555s: CMD = framecrc -i $(TARGET_SAMPLES)/mss2/rle555s.wmv -pix_fmt rgb555le -vf scale FATE_MSS2 += fate-mss2-wmv fate-mss2-wmv: CMD = framecrc -i $(TARGET_SAMPLES)/mss2/msscreencodec.wmv -an -frames 100 @@ -29,10 +29,10 @@ FATE_SAMPLES_AVCONV-$(call DEMDEC, ASF, MTS2) += $(FATE_MTS2) fate-mts2: $(FATE_MTS2) FATE_MSVIDEO1 += fate-msvideo1-8bit -fate-msvideo1-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24 +fate-msvideo1-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24 -vf scale FATE_MSVIDEO1 += fate-msvideo1-16bit -fate-msvideo1-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/cram/clock-cram16.avi -pix_fmt rgb24 +fate-msvideo1-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/cram/clock-cram16.avi -pix_fmt rgb24 -vf scale FATE_MICROSOFT-$(call DEMDEC, AVI, MSVIDEO1) += $(FATE_MSVIDEO1) fate-msvideo1: $(FATE_MSVIDEO1) diff --git a/tests/fate/monkeysaudio.mak b/tests/fate/monkeysaudio.mak index 9ce872a5d..d75937ec0 100644 --- a/tests/fate/monkeysaudio.mak +++ b/tests/fate/monkeysaudio.mak @@ -2,11 +2,11 @@ APE_VERSIONS = 380 388 389b1 391b1 392b2 394b1 define FATE_APE_SUITE FATE_APE += fate-lossless-monkeysaudio-$(1)-normal -fate-lossless-monkeysaudio-$(1)-normal: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/luckynight-mac$(1)-c2000.ape -af atrim=end_sample=73728 +fate-lossless-monkeysaudio-$(1)-normal: CMD = crc -auto_conversion_filters -i $(TARGET_SAMPLES)/lossless-audio/luckynight-mac$(1)-c2000.ape -af atrim=end_sample=73728 fate-lossless-monkeysaudio-$(1)-normal: REF = CRC=0x5d08c17e fate-lossless-monkeysaudio-$(1)-normal: CMP = oneline FATE_APE += fate-lossless-monkeysaudio-$(1)-extrahigh -fate-lossless-monkeysaudio-$(1)-extrahigh: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/luckynight-mac$(1)-c4000.ape -af atrim=end_sample=73728 +fate-lossless-monkeysaudio-$(1)-extrahigh: CMD = crc -auto_conversion_filters -i $(TARGET_SAMPLES)/lossless-audio/luckynight-mac$(1)-c4000.ape -af atrim=end_sample=73728 fate-lossless-monkeysaudio-$(1)-extrahigh: REF = CRC=0x5d08c17e fate-lossless-monkeysaudio-$(1)-extrahigh: CMP = oneline endef @@ -14,7 +14,7 @@ endef $(foreach N,$(APE_VERSIONS),$(eval $(call FATE_APE_SUITE,$(N)))) FATE_APE += fate-lossless-monkeysaudio-399 -fate-lossless-monkeysaudio-399: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le +fate-lossless-monkeysaudio-399: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le -af aresample FATE_SAMPLES_AVCONV-$(call DEMDEC, APE, APE) += $(FATE_APE) fate-lossless-monkeysaudio: $(FATE_APE) diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index 7a721d7c9..957bd5ca4 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -29,6 +29,7 @@ FATE_MOV_FFPROBE = fate-mov-neg-firstpts-discard \ fate-mov-guess-delay-2 \ fate-mov-guess-delay-3 \ fate-mov-mp4-with-mov-in24-ver \ + fate-mov-mp4-extended-atom \ FATE_MOV_FASTSTART = fate-mov-faststart-4gb-overflow \ @@ -68,7 +69,7 @@ fate-mov-2elist-elist1-ends-bframe: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov- fate-mov-elst-ends-betn-b-and-i: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/elst_ends_betn_b_and_i.mp4 # Makes sure that we handle edit lists and start padding correctly. -fate-mov-440hz-10ms: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/440hz-10ms.m4a +fate-mov-440hz-10ms: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/440hz-10ms.m4a -af aresample # Makes sure that we handle invalid edit list entry count correctly. fate-mov-invalid-elst-entry-count: CMD = framemd5 -idct simple -flags +bitexact -i $(TARGET_SAMPLES)/mov/invalid_elst_entry_count.mov @@ -86,7 +87,7 @@ fate-mov-frag-overlap: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/frag_overlap.mp4 # Makes sure that we pick the right frames according to edit list when there is no keyframe with PTS < edit list start. # For example, when video starts on a B-frame, and edit list starts on that B-frame too. # GOP structure : B B I in presentation order. -fate-mov-bbi-elst-starts-b: CMD = framemd5 -flags +bitexact -acodec aac_fixed -i $(TARGET_SAMPLES)/h264/twofields_packet.mp4 +fate-mov-bbi-elst-starts-b: CMD = framemd5 -flags +bitexact -acodec aac_fixed -i $(TARGET_SAMPLES)/h264/twofields_packet.mp4 -af aresample # Makes sure that the stream start_time is not negative when the first packet is a DISCARD packet with negative timestamp. fate-mov-neg-firstpts-discard: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=start_time -bitexact $(TARGET_SAMPLES)/mov/mov_neg_first_pts_discard.mov @@ -113,7 +114,7 @@ fate-mov-spherical-mono: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries str fate-mov-gpmf-remux: CMD = md5 -i $(TARGET_SAMPLES)/mov/fake-gp-media-with-real-gpmf.mp4 -map 0 -c copy -fflags +bitexact -f mp4 fate-mov-gpmf-remux: CMP = oneline -fate-mov-gpmf-remux: REF = 8f48e435ee1f6b7e173ea756141eabf3 +fate-mov-gpmf-remux: REF = 6361cf3c2b9e6962c2eafbda138125f4 fate-mov-guess-delay-1: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_nopyramid_nobsrestriction.mp4 fate-mov-guess-delay-2: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_pyramid_nobsrestriction.mp4 @@ -124,3 +125,5 @@ fate-mov-faststart-4gb-overflow: CMP = oneline fate-mov-faststart-4gb-overflow: REF = bc875921f151871e787c4b4023269b29 fate-mov-mp4-with-mov-in24-ver: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=codec_name -select_streams 1 $(TARGET_SAMPLES)/mov/mp4-with-mov-in24-ver.mp4 + +fate-mov-mp4-extended-atom: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_packets -print_format compact -select_streams v $(TARGET_SAMPLES)/mov/extended_atom_size_probe diff --git a/tests/fate/mp3.mak b/tests/fate/mp3.mak index b8fde55a8..b874e7c7a 100644 --- a/tests/fate/mp3.mak +++ b/tests/fate/mp3.mak @@ -1,33 +1,33 @@ FATE_MP3 += fate-mp3-float-conf-compl -fate-mp3-float-conf-compl: CMD = ffmpeg -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/compl.bit -f f32le - +fate-mp3-float-conf-compl: CMD = ffmpeg -auto_conversion_filters -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/compl.bit -f f32le - fate-mp3-float-conf-compl: REF = $(SAMPLES)/mp3-conformance/compl.f32 FATE_MP3 += fate-mp3-float-conf-he_32khz -fate-mp3-float-conf-he_32khz: CMD = ffmpeg -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_32khz.bit -af atrim=end_sample=171648 -f f32le - +fate-mp3-float-conf-he_32khz: CMD = ffmpeg -auto_conversion_filters -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_32khz.bit -af atrim=end_sample=171648 -f f32le - fate-mp3-float-conf-he_32khz: REF = $(SAMPLES)/mp3-conformance/he_32khz.f32 FATE_MP3 += fate-mp3-float-conf-he_44khz -fate-mp3-float-conf-he_44khz: CMD = ffmpeg -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_44khz.bit -af atrim=end_sample=471168 -f f32le - +fate-mp3-float-conf-he_44khz: CMD = ffmpeg -auto_conversion_filters -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_44khz.bit -af atrim=end_sample=471168 -f f32le - fate-mp3-float-conf-he_44khz: REF = $(SAMPLES)/mp3-conformance/he_44khz.f32 FATE_MP3 += fate-mp3-float-conf-he_48khz -fate-mp3-float-conf-he_48khz: CMD = ffmpeg -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_48khz.bit -af atrim=end_sample=171648 -f f32le - +fate-mp3-float-conf-he_48khz: CMD = ffmpeg -auto_conversion_filters -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_48khz.bit -af atrim=end_sample=171648 -f f32le - fate-mp3-float-conf-he_48khz: REF = $(SAMPLES)/mp3-conformance/he_48khz.f32 FATE_MP3 += fate-mp3-float-conf-hecommon -fate-mp3-float-conf-hecommon: CMD = ffmpeg -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/hecommon.bit -af atrim=end_sample=33408 -f f32le - +fate-mp3-float-conf-hecommon: CMD = ffmpeg -auto_conversion_filters -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/hecommon.bit -af atrim=end_sample=33408 -f f32le - fate-mp3-float-conf-hecommon: REF = $(SAMPLES)/mp3-conformance/hecommon.f32 FATE_MP3 += fate-mp3-float-conf-si -fate-mp3-float-conf-si: CMD = ffmpeg -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si.bit -af atrim=end_sample=134784 -f f32le - +fate-mp3-float-conf-si: CMD = ffmpeg -auto_conversion_filters -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si.bit -af atrim=end_sample=134784 -f f32le - fate-mp3-float-conf-si: REF = $(SAMPLES)/mp3-conformance/si.f32 FATE_MP3 += fate-mp3-float-conf-si_block -fate-mp3-float-conf-si_block: CMD = ffmpeg -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si_block.bit -af atrim=end_sample=72576 -f f32le - +fate-mp3-float-conf-si_block: CMD = ffmpeg -auto_conversion_filters -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si_block.bit -af atrim=end_sample=72576 -f f32le - fate-mp3-float-conf-si_block: REF = $(SAMPLES)/mp3-conformance/si_block.f32 FATE_MP3 += fate-mp3-float-extra_overread -fate-mp3-float-extra_overread: CMD = ffmpeg -c:a mp3float -i $(TARGET_SAMPLES)/mpegaudio/extra_overread.mp3 -f f32le - +fate-mp3-float-extra_overread: CMD = ffmpeg -auto_conversion_filters -c:a mp3float -i $(TARGET_SAMPLES)/mpegaudio/extra_overread.mp3 -f f32le - fate-mp3-float-extra_overread: REF = $(SAMPLES)/mpegaudio/extra_overread.f32 $(FATE_MP3): CMP = oneoff diff --git a/tests/fate/mpc.mak b/tests/fate/mpc.mak index 294dffeab..cde6e5517 100644 --- a/tests/fate/mpc.mak +++ b/tests/fate/mpc.mak @@ -9,5 +9,12 @@ fate-musepack7: CMD = pcm -i $(TARGET_SAMPLES)/musepack/inside-mp7.mpc fate-musepack7: CMP = oneoff fate-musepack7: REF = $(SAMPLES)/musepack/inside-mp7.pcm +FATE_MPC-$(call ALLYES, FILE_PROTOCOL MPC8_DEMUXER MPC8_DECODER \ + ARESAMPLE_FILTER PCM_S16LE_ENCODER \ + FRAMECRC_MUXER PIPE_PROTOCOL) += fate-musepack8 +fate-musepack8: CMD = pcm -i $(TARGET_SAMPLES)/musepack/inside-mp8.mpc -ss 8.4 -af aresample +fate-musepack8: CMP = oneoff +fate-musepack8: REF = $(SAMPLES)/musepack/inside-mp8.pcm + FATE_SAMPLES_AVCONV += $(FATE_MPC-yes) fate-mpc: $(FATE_MPC-yes) diff --git a/tests/fate/mxf.mak b/tests/fate/mxf.mak index 4aafc1f57..3a1096176 100644 --- a/tests/fate/mxf.mak +++ b/tests/fate/mxf.mak @@ -33,6 +33,10 @@ FATE_MXF_PROBE-$(call ENCDEC2, DVVIDEO, PCM_S16LE, MXF) += fate-mxf-probe-dv25 fate-mxf-probe-dv25: SRC = $(TARGET_SAMPLES)/mxf/Avid-00005.mxf fate-mxf-probe-dv25: CMD = run $(PROBE_FORMAT_STREAMS_COMMAND) -i "$(SRC)" +FATE_MXF_PROBE-$(call ENCDEC2, PRORES, PCM_S24LE, MXF) += fate-mxf-probe-applehdr10 +fate-mxf-probe-applehdr10: SRC = $(TARGET_SAMPLES)/mxf/Meridian-Apple_ProResProxy-HDR10.mxf +fate-mxf-probe-applehdr10: CMD = run $(PROBE_FORMAT_STREAMS_COMMAND) -i "$(SRC)" | sed -e "s/yuv422p10../yuv422p10/" + FATE_MXF_REEL_NAME-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += fate-mxf-reel_name fate-mxf-reel_name: $(SAMPLES)/mxf/Sony-00001.mxf fate-mxf-reel_name: CMD = md5 -y -i $(TARGET_SAMPLES)/mxf/Sony-00001.mxf -c copy -timecode 00:00:00:00 -metadata "reel_name=test_reel" -fflags +bitexact -f mxf @@ -41,9 +45,8 @@ FATE_MXF_USER_COMMENTS-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += fate-mxf-u fate-mxf-user-comments: $(SAMPLES)/mxf/Sony-00001.mxf fate-mxf-user-comments: CMD = md5 -y -i $(TARGET_SAMPLES)/mxf/Sony-00001.mxf -c copy -metadata "comment_test=value" -fflags +bitexact -f mxf -FATE_MXF_D10_USER_COMMENTS-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += fate-mxf-d10-user-comments -fate-mxf-d10-user-comments: $(SAMPLES)/mxf/Sony-00001.mxf -fate-mxf-d10-user-comments: CMD = md5 -y -i $(TARGET_SAMPLES)/mxf/Sony-00001.mxf -c copy -metadata "comment_test=value" -store_user_comments 1 -fflags +bitexact -f mxf_d10 +FATE_MXF_D10_USER_COMMENTS-$(call ALLYES, FILE_PROTOCOL MXF_DEMUXER DVVIDEO_DECODER SCALE_FILTER MPEG2VIDEO_ENCODER MXF_D10_MUXER EXTRACT_EXTRADATA_BSF MPEGVIDEO_PARSER PIPE_PROTOCOL FRAMECRC_MUXER) += fate-mxf-d10-user-comments +fate-mxf-d10-user-comments: CMD = transcode mxf $(TARGET_SAMPLES)/mxf/Avid-00005.mxf mxf_d10 "-c:v mpeg2video -b:v 30000k -minrate:v 30000k -maxrate:v 30000k -bufsize:v 30000k -rc_init_occupancy 30000k -vf scale=w=1280:h=720 -an -metadata comment_test=value -metadata company_name=FATE-company -metadata product_name=FATE-test -metadata product_version=3.14159 -store_user_comments 1" "-c copy -frames:v 5" "" "-show_entries format_tags" FATE_MXF_OPATOM_USER_COMMENTS-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += fate-mxf-opatom-user-comments fate-mxf-opatom-user-comments: $(SAMPLES)/mxf/Sony-00001.mxf @@ -52,7 +55,8 @@ fate-mxf-opatom-user-comments: CMD = md5 -y -i $(TARGET_SAMPLES)/mxf/Sony-00001. FATE_MXF-$(CONFIG_MXF_DEMUXER) += $(FATE_MXF) FATE_SAMPLES_AVCONV += $(FATE_MXF-yes) $(FATE_MXF_REEL_NAME-yes) -FATE_SAMPLES_AVCONV += $(FATE_MXF_USER_COMMENTS-yes) $(FATE_MXF_D10_USER_COMMENTS-yes) $(FATE_MXF_OPATOM_USER_COMMENTS-yes) +FATE_SAMPLES_AVCONV += $(FATE_MXF_USER_COMMENTS-yes) $(FATE_MXF_OPATOM_USER_COMMENTS-yes) +FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MXF_D10_USER_COMMENTS-yes) FATE_SAMPLES_FFPROBE += $(FATE_MXF_PROBE-yes) fate-mxf: $(FATE_MXF-yes) $(FATE_MXF_PROBE-yes) $(FATE_MXF_REEL_NAME-yes) $(FATE_MXF_USER_COMMENTS-yes) $(FATE_MXF_D10_USER_COMMENTS-yes) $(FATE_MXF_OPATOM_USER_COMMENTS-yes) diff --git a/tests/fate/opus.mak b/tests/fate/opus.mak index c50d88f5e..cf8eeb555 100644 --- a/tests/fate/opus.mak +++ b/tests/fate/opus.mak @@ -10,7 +10,7 @@ OPUS_SAMPLES = $(addprefix testvector, 07 08 09 10 12) define FATE_OPUS_TEST FATE_OPUS += fate-opus-$(1) FATE_OPUS$(2) += fate-opus-$(1) -fate-opus-$(1): CMD = ffmpeg -i $(TARGET_SAMPLES)/opus/$(1).mka -f s16le - +fate-opus-$(1): CMD = ffmpeg -i $(TARGET_SAMPLES)/opus/$(1).mka -f s16le -af aresample - fate-opus-$(1): REF = $(SAMPLES)/opus/$(1)$(2).dec endef diff --git a/tests/fate/pcm.mak b/tests/fate/pcm.mak index 053f310b2..e3e267403 100644 --- a/tests/fate/pcm.mak +++ b/tests/fate/pcm.mak @@ -1,11 +1,11 @@ FATE_SAMPLES_PCM-$(call DEMDEC, WAV, PCM_U8) += fate-iff-pcm -fate-iff-pcm: CMD = md5 -i $(TARGET_SAMPLES)/iff/Bells -f s16le +fate-iff-pcm: CMD = md5 -i $(TARGET_SAMPLES)/iff/Bells -f s16le -af aresample FATE_SAMPLES_PCM-$(call DEMDEC, MPEGPS, PCM_DVD) += fate-pcm_dvd -fate-pcm_dvd: CMD = framecrc -i $(TARGET_SAMPLES)/pcm-dvd/coolitnow-partial.vob -vn +fate-pcm_dvd: CMD = framecrc -i $(TARGET_SAMPLES)/pcm-dvd/coolitnow-partial.vob -vn -af aresample FATE_SAMPLES_PCM-$(call DEMDEC, EA, PCM_S16LE_PLANAR) += fate-pcm-planar -fate-pcm-planar: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/xeasport.mad -vn +fate-pcm-planar: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/xeasport.mad -vn -af aresample FATE_SAMPLES_PCM-$(call DEMDEC, MOV, PCM_S16BE) += fate-pcm_s16be-stereo fate-pcm_s16be-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-twos.mov -f s16le @@ -14,10 +14,10 @@ FATE_SAMPLES_PCM-$(call DEMDEC, MOV, PCM_S16LE) += fate-pcm_s16le-stereo fate-pcm_s16le-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-sowt.mov -f s16le FATE_SAMPLES_PCM-$(call DEMDEC, MOV, PCM_U8) += fate-pcm_u8-mono -fate-pcm_u8-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-raw.mov -f s16le +fate-pcm_u8-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-raw.mov -f s16le -af aresample FATE_SAMPLES_PCM-$(call DEMDEC, MOV, PCM_U8) += fate-pcm_u8-stereo -fate-pcm_u8-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-raw.mov -f s16le +fate-pcm_u8-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-raw.mov -f s16le -af aresample FATE_SAMPLES_PCM-$(call DEMDEC, W64, PCM_S16LE) += fate-w64 fate-w64: CMD = crc -i $(TARGET_SAMPLES)/w64/w64-pcm16.w64 diff --git a/tests/fate/pixlet.mak b/tests/fate/pixlet.mak index c720f3261..7c4604cc0 100644 --- a/tests/fate/pixlet.mak +++ b/tests/fate/pixlet.mak @@ -1,5 +1,5 @@ FATE_PIXLET += fate-pixlet-rgb -fate-pixlet-rgb: CMD = framecrc -i $(TARGET_SAMPLES)/pixlet/pixlet_rgb.mov -an -pix_fmt yuv420p16le +fate-pixlet-rgb: CMD = framecrc -i $(TARGET_SAMPLES)/pixlet/pixlet_rgb.mov -an -pix_fmt yuv420p16le -vf scale FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PIXLET) += $(FATE_PIXLET) fate-pixlet: $(FATE_PIXLET) diff --git a/tests/fate/prores.mak b/tests/fate/prores.mak index b7fcc7449..f2c11259d 100644 --- a/tests/fate/prores.mak +++ b/tests/fate/prores.mak @@ -11,15 +11,15 @@ FATE_PRORES = fate-prores-422 \ FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PRORES) += $(FATE_PRORES) fate-prores: $(FATE_PRORES) -fate-prores-422: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le -fate-prores-422_hq: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le -fate-prores-422_lt: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le -fate-prores-422_proxy: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le -fate-prores-alpha: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuva444p12le -fate-prores-alpha_skip: CMD = framecrc -flags +bitexact -skip_alpha 1 -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuv444p12le -fate-prores-transparency: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/prores4444_with_transparency.mov -pix_fmt yuva444p12le -fate-prores-transparency_skip: CMD = framecrc -flags +bitexact -skip_alpha 1 -i $(TARGET_SAMPLES)/prores/prores4444_with_transparency.mov -pix_fmt yuv444p12le -fate-prores-gray: CMD = framecrc -flags +bitexact -c:a aac_fixed -i $(TARGET_SAMPLES)/prores/gray.mov -pix_fmt yuv422p10le +fate-prores-422: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le -vf scale +fate-prores-422_hq: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le -vf scale +fate-prores-422_lt: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le -vf scale +fate-prores-422_proxy: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le -vf scale +fate-prores-alpha: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuva444p12le -vf scale +fate-prores-alpha_skip: CMD = framecrc -flags +bitexact -skip_alpha 1 -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuv444p12le -vf scale +fate-prores-transparency: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/prores4444_with_transparency.mov -pix_fmt yuva444p12le -vf scale +fate-prores-transparency_skip: CMD = framecrc -flags +bitexact -skip_alpha 1 -i $(TARGET_SAMPLES)/prores/prores4444_with_transparency.mov -pix_fmt yuv444p12le -vf scale +fate-prores-gray: CMD = framecrc -flags +bitexact -c:a aac_fixed -i $(TARGET_SAMPLES)/prores/gray.mov -pix_fmt yuv422p10le -vf scale -af aresample #Test bsf prores-metadata FATE_PRORES_METADATA_BSF += fate-prores-metadata diff --git a/tests/fate/qt.mak b/tests/fate/qt.mak index c054129f0..6e71f6e4d 100644 --- a/tests/fate/qt.mak +++ b/tests/fate/qt.mak @@ -1,5 +1,5 @@ FATE_QT-$(call DEMDEC, MOV, EIGHTBPS) += fate-8bps -fate-8bps: CMD = framecrc -i $(TARGET_SAMPLES)/8bps/full9iron-partial.mov -pix_fmt rgb24 +fate-8bps: CMD = framecrc -i $(TARGET_SAMPLES)/8bps/full9iron-partial.mov -pix_fmt rgb24 -vf scale -af aresample FATE_QT-$(call DEMDEC, MOV, QDM2) += fate-qdm2 fate-qdm2: CMD = pcm -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.mov @@ -14,22 +14,22 @@ FATE_QT-$(call DEMDEC, MOV, PCM_ALAW) += fate-qt-alaw-stereo fate-qt-alaw-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-alaw.mov -f s16le FATE_QT-$(call DEMDEC, MOV, ADPCM_IMA_QT) += fate-qt-ima4-mono -fate-qt-ima4-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-16-B-ima4.mov -f s16le +fate-qt-ima4-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-16-B-ima4.mov -f s16le -af aresample FATE_QT-$(call DEMDEC, MOV, ADPCM_IMA_QT) += fate-qt-ima4-stereo -fate-qt-ima4-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-ima4.mov -f s16le +fate-qt-ima4-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-ima4.mov -f s16le -af aresample FATE_QT-$(call DEMDEC, MOV, MACE3) += fate-qt-mac3-mono -fate-qt-mac3-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-MAC3.mov -f s16le +fate-qt-mac3-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-MAC3.mov -f s16le -af aresample FATE_QT-$(call DEMDEC, MOV, MACE3) += fate-qt-mac3-stereo -fate-qt-mac3-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-MAC3.mov -f s16le +fate-qt-mac3-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-MAC3.mov -f s16le -af aresample FATE_QT-$(call DEMDEC, MOV, MACE6) += fate-qt-mac6-mono -fate-qt-mac6-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-MAC6.mov -f s16le +fate-qt-mac6-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-MAC6.mov -f s16le -af aresample FATE_QT-$(call DEMDEC, MOV, MACE6) += fate-qt-mac6-stereo -fate-qt-mac6-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-MAC6.mov -f s16le +fate-qt-mac6-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-MAC6.mov -f s16le -af aresample FATE_QT-$(call DEMDEC, MOV, PCM_MULAW) += fate-qt-ulaw-mono fate-qt-ulaw-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-16-B-ulaw.mov -f s16le @@ -38,10 +38,10 @@ FATE_QT-$(call DEMDEC, MOV, PCM_MULAW) += fate-qt-ulaw-stereo fate-qt-ulaw-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-ulaw.mov -f s16le FATE_QT-$(call DEMDEC, MOV, QDRAW) += fate-quickdraw -fate-quickdraw: CMD = framecrc -i $(TARGET_SAMPLES)/quickdraw/Airplane.mov -pix_fmt rgb24 +fate-quickdraw: CMD = framecrc -i $(TARGET_SAMPLES)/quickdraw/Airplane.mov -pix_fmt rgb24 -vf scale FATE_QT-$(call DEMDEC, MOV, RPZA) += fate-rpza -fate-rpza: CMD = framecrc -i $(TARGET_SAMPLES)/rpza/rpza2.mov -t 2 -pix_fmt rgb24 +fate-rpza: CMD = framecrc -i $(TARGET_SAMPLES)/rpza/rpza2.mov -t 2 -pix_fmt rgb24 -vf scale FATE_QT-$(call DEMDEC, MOV, SVQ1) += fate-svq1 fate-svq1: CMD = framecrc -i $(TARGET_SAMPLES)/svq1/marymary-shackles.mov -an -t 10 diff --git a/tests/fate/qtrle.mak b/tests/fate/qtrle.mak index 1f26ffea7..3dd0afbd3 100644 --- a/tests/fate/qtrle.mak +++ b/tests/fate/qtrle.mak @@ -2,22 +2,22 @@ FATE_QTRLE += fate-qtrle-1bit fate-qtrle-1bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-Monochrome.mov -an FATE_QTRLE += fate-qtrle-2bit -fate-qtrle-2bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24 -an +fate-qtrle-2bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24 -an -vf scale FATE_QTRLE += fate-qtrle-4bit -fate-qtrle-4bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-16Greys.mov -pix_fmt rgb24 -an +fate-qtrle-4bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-16Greys.mov -pix_fmt rgb24 -an -vf scale FATE_QTRLE += fate-qtrle-8bit -fate-qtrle-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/criticalpath-credits.mov -pix_fmt rgb24 -an +fate-qtrle-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/criticalpath-credits.mov -pix_fmt rgb24 -an -vf scale FATE_QTRLE += fate-qtrle-16bit -fate-qtrle-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/mr-cork-rle.mov -pix_fmt rgb24 +fate-qtrle-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/mr-cork-rle.mov -pix_fmt rgb24 -vf scale FATE_QTRLE += fate-qtrle-24bit fate-qtrle-24bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/aletrek-rle.mov FATE_QTRLE += fate-qtrle-32bit -fate-qtrle-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/ultra_demo_720_480_32bpp_rle.mov -pix_fmt bgra +fate-qtrle-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/ultra_demo_720_480_32bpp_rle.mov -pix_fmt bgra -vf scale FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, QTRLE) += $(FATE_QTRLE) fate-qtrle: $(FATE_QTRLE) diff --git a/tests/fate/screen.mak b/tests/fate/screen.mak index 68b4f6f97..aa9832688 100644 --- a/tests/fate/screen.mak +++ b/tests/fate/screen.mak @@ -1,6 +1,6 @@ # FIXME dropped frames in this test because of coarse timebase FATE_SCREEN-$(call DEMDEC, AVI, CSCD) += fate-cscd -fate-cscd: CMD = framecrc -i $(TARGET_SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24 +fate-cscd: CMD = framecrc -i $(TARGET_SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24 -vf scale FATE_SCREEN-$(call DEMDEC, AVI, DXTORY) += fate-dxtory fate-dxtory: CMD = framecrc -i $(TARGET_SAMPLES)/dxtory/dxtory_mic.avi -an @@ -27,7 +27,7 @@ FATE_FRAPS += fate-fraps-v2 fate-fraps-v2: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/test3-nosound-partial.avi FATE_FRAPS += fate-fraps-v3 -fate-fraps-v3: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/psclient-partial.avi -pix_fmt rgb24 +fate-fraps-v3: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/psclient-partial.avi -pix_fmt rgb24 -vf scale FATE_FRAPS += fate-fraps-v4 fate-fraps-v4: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/WoW_2006-11-03_14-58-17-19-nosound-partial.avi @@ -54,7 +54,7 @@ FATE_RSCC += fate-iscc fate-iscc: CMD = framecrc -i $(TARGET_SAMPLES)/rscc/pip.avi -an FATE_RSCC += fate-rscc-8bit -fate-rscc-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/rscc/8bpp.avi -an -pix_fmt rgb24 +fate-rscc-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/rscc/8bpp.avi -an -pix_fmt rgb24 -vf scale FATE_RSCC += fate-rscc-16bit fate-rscc-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/rscc/16bpp_555.avi -an @@ -84,10 +84,10 @@ FATE_SAMPLES_AVCONV-$(call DEMDEC, ASF, TDSC) += fate-tdsc fate-tdsc: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/tdsc/tdsc.asf -an -pix_fmt bgr24 FATE_TSCC += fate-tscc-15bit -fate-tscc-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/oneminute.avi -t 15 -pix_fmt rgb24 +fate-tscc-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/oneminute.avi -t 15 -pix_fmt rgb24 -vf scale FATE_TSCC += fate-tscc-32bit -fate-tscc-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an +fate-tscc-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an -vf scale FATE_SCREEN-$(call DEMDEC, AVI, TSCC) += $(FATE_TSCC) fate-tscc: $(FATE_TSCC) @@ -102,25 +102,25 @@ FATE_SAMPLES_AVCONV-$(CONFIG_TSCC2_DECODER) += $(FATE_TSCC2-yes) fate-tscc2: $(FATE_TSCC2-yes) FATE_VMNC += fate-vmnc-16bit -fate-vmnc-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/VMnc/test.avi -pix_fmt rgb24 +fate-vmnc-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/VMnc/test.avi -pix_fmt rgb24 -vf scale FATE_VMNC += fate-vmnc-32bit -fate-vmnc-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24 +fate-vmnc-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24 -vf scale FATE_SCREEN-$(call DEMDEC, AVI, VMNC) += $(FATE_VMNC) fate-vmnc: $(FATE_VMNC) FATE_ZMBV += fate-zmbv-8bit -fate-zmbv-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/wc2_001-partial.avi -an -pix_fmt rgb24 +fate-zmbv-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/wc2_001-partial.avi -an -pix_fmt rgb24 -vf scale FATE_ZMBV += fate-zmbv-15bit -fate-zmbv-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_15bit.avi -pix_fmt rgb24 -t 25 +fate-zmbv-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_15bit.avi -pix_fmt rgb24 -t 25 -vf scale FATE_ZMBV += fate-zmbv-16bit -fate-zmbv-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_16bit.avi -pix_fmt rgb24 -t 25 +fate-zmbv-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_16bit.avi -pix_fmt rgb24 -t 25 -vf scale FATE_ZMBV += fate-zmbv-32bit -fate-zmbv-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25 +fate-zmbv-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25 -vf scale FATE_SCREEN-$(call DEMDEC, AVI, ZMBV) += $(FATE_ZMBV) fate-zmbv: $(FATE_ZMBV) diff --git a/tests/fate/seek.mak b/tests/fate/seek.mak index 98d2b5467..5efec3270 100644 --- a/tests/fate/seek.mak +++ b/tests/fate/seek.mak @@ -270,6 +270,7 @@ FATE_SEEK_EXTRA += $(FATE_SEEK_EXTRA-yes) $(FATE_SEEK) $(FATE_SAMPLES_SEEK) $(FATE_SEEK_EXTRA): libavformat/tests/seek$(EXESUF) $(FATE_SEEK) $(FATE_SAMPLES_SEEK): CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_PATH)/tests/data/$(SRC) $(FATE_SEEK) $(FATE_SAMPLES_SEEK): fate-seek-%: fate-% +$(subst fate-seek-,fate-,$(FATE_SAMPLES_SEEK) $(FATE_SEEK)): KEEP_OVERRIDE = -keep fate-seek-%: REF = $(SRC_PATH)/tests/ref/seek/$(@:fate-seek-%=%) FATE_AVCONV += $(FATE_SEEK) diff --git a/tests/fate/subtitles.mak b/tests/fate/subtitles.mak index 004290216..ee65afe35 100644 --- a/tests/fate/subtitles.mak +++ b/tests/fate/subtitles.mak @@ -103,6 +103,12 @@ fate-sub-charenc: CMD = fmtstdout ass -sub_charenc cp1251 -i $(TARGET_SAMPLES)/s FATE_SUBTITLES-$(call DEMDEC, SCC, CCAPTION) += fate-sub-scc fate-sub-scc: CMD = fmtstdout ass -ss 57 -i $(TARGET_SAMPLES)/sub/witch.scc +FATE_SUBTITLES-$(call ALLYES, MPEGTS_DEMUXER DVBSUB_DECODER DVBSUB_ENCODER) += fate-sub-dvb +fate-sub-dvb: CMD = framecrc -i $(TARGET_SAMPLES)/sub/dvbsubtest_filter.ts -map s:0 -c dvbsub + +FATE_SUBTITLES-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL SRT_DEMUXER SUBRIP_DECODER TTML_ENCODER TTML_MUXER) += fate-sub-ttmlenc +fate-sub-ttmlenc: CMD = fmtstdout ttml -i $(TARGET_SAMPLES)/sub/SubRip_capability_tester.srt + FATE_SUBTITLES-$(call ENCMUX, ASS, ASS) += $(FATE_SUBTITLES_ASS-yes) FATE_SUBTITLES += $(FATE_SUBTITLES-yes) diff --git a/tests/fate/utvideo.mak b/tests/fate/utvideo.mak index 23224718e..9329df538 100644 --- a/tests/fate/utvideo.mak +++ b/tests/fate/utvideo.mak @@ -67,7 +67,7 @@ fate-utvideo_yuv444_709_int_gradient: CMD = framecrc -i $(TARGET_SAMPLES)/utvide FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, UTVIDEO) += $(FATE_UTVIDEO) fate-utvideo: $(FATE_UTVIDEO) -fate-utvideoenc%: CMD = framemd5 -f image2 -c:v pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -c:v utvideo -slices 1 -sws_flags +accurate_rnd+bitexact ${OPTS} +fate-utvideoenc%: CMD = framemd5 -f image2 -c:v pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -c:v utvideo -slices 1 -sws_flags +accurate_rnd+bitexact ${OPTS} -vf scale FATE_UTVIDEOENC += fate-utvideoenc_rgba_left fate-utvideoenc_rgba_left: OPTS = -pix_fmt gbrap -pred left diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak index 1e9c0d564..ef892366e 100644 --- a/tests/fate/vcodec.mak +++ b/tests/fate/vcodec.mak @@ -4,8 +4,8 @@ fate-vsynth_lena-%: SRC = tests/data/vsynth_lena.yuv fate-vsynth3-%: SRC = tests/data/vsynth3.yuv fate-vsynth%: CODEC = $(word 3, $(subst -, ,$(@))) fate-vsynth%: FMT = avi -fate-vsynth%: CMD = enc_dec "rawvideo -s 352x288 -pix_fmt yuv420p $(RAWDECOPTS)" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s 352x288 -pix_fmt yuv420p -vsync 0 $(DECOPTS)" -keep "$(DECINOPTS)" -fate-vsynth3-%: CMD = enc_dec "rawvideo -s $(FATEW)x$(FATEH) -pix_fmt yuv420p $(RAWDECOPTS)" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s $(FATEW)x$(FATEH) -pix_fmt yuv420p -vsync 0 $(DECOPTS)" -keep "$(DECINOPTS)" +fate-vsynth%: CMD = enc_dec "rawvideo -s 352x288 -pix_fmt yuv420p $(RAWDECOPTS)" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s 352x288 -pix_fmt yuv420p -vsync 0 $(DECOPTS)" "$(KEEP_OVERRIDE)" "$(DECINOPTS)" +fate-vsynth3-%: CMD = enc_dec "rawvideo -s $(FATEW)x$(FATEH) -pix_fmt yuv420p $(RAWDECOPTS)" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s $(FATEW)x$(FATEH) -pix_fmt yuv420p -vsync 0 $(DECOPTS)" "" "$(DECINOPTS)" fate-vsynth%: CMP_UNIT = 1 fate-vsynth%: REF = $(SRC_PATH)/tests/ref/vsynth/$(@:fate-%=%) diff --git a/tests/fate/video.mak b/tests/fate/video.mak index d2d43e518..d6b5770ab 100644 --- a/tests/fate/video.mak +++ b/tests/fate/video.mak @@ -1,17 +1,17 @@ FATE_4XM += fate-4xm-1 -fate-4xm-1: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/version1.4xm -pix_fmt rgb24 -an +fate-4xm-1: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/version1.4xm -pix_fmt rgb24 -an -vf scale FATE_4XM += fate-4xm-2 -fate-4xm-2: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/version2.4xm -pix_fmt rgb24 -an +fate-4xm-2: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/version2.4xm -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, FOURXM, FOURXM) += $(FATE_4XM) fate-4xm: $(FATE_4XM) FATE_VIDEO-$(call DEMDEC, AVI, ZERO12V) += fate-012v -fate-012v: CMD = framecrc -i $(TARGET_SAMPLES)/012v/sample.avi -pix_fmt yuv422p16le +fate-012v: CMD = framecrc -i $(TARGET_SAMPLES)/012v/sample.avi -pix_fmt yuv422p16le -vf scale FATE_VIDEO-$(call DEMDEC, AVI, AASC) += fate-aasc -fate-aasc: CMD = framecrc -i $(TARGET_SAMPLES)/aasc/AASC-1.5MB.AVI -pix_fmt rgb24 +fate-aasc: CMD = framecrc -i $(TARGET_SAMPLES)/aasc/AASC-1.5MB.AVI -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, MOV, AIC) += fate-aic fate-aic: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/aic/small_apple_intermediate_codec.mov -an -frames:v 15 @@ -20,19 +20,19 @@ FATE_VIDEO-$(call DEMDEC, MOV, AIC) += fate-aic-oddsize fate-aic-oddsize: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/aic/aic_odd_dimensions.mov FATE_VIDEO-$(call DEMDEC, MM, MMVIDEO) += fate-alg-mm -fate-alg-mm: CMD = framecrc -i $(TARGET_SAMPLES)/alg-mm/ibmlogo.mm -an -pix_fmt rgb24 +fate-alg-mm: CMD = framecrc -i $(TARGET_SAMPLES)/alg-mm/ibmlogo.mm -an -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, AVI, AMV) += fate-amv fate-amv: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -an FATE_VIDEO-$(call DEMDEC, TTY, ANSI) += fate-ansi -fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(TARGET_SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24 +fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(TARGET_SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, TTY, ANSI) += fate-ansi256 -fate-ansi256: CMD = framecrc -chars_per_frame 44100 -i $(TARGET_SAMPLES)/ansi/ansi256.ans -pix_fmt rgb24 +fate-ansi256: CMD = framecrc -chars_per_frame 44100 -i $(TARGET_SAMPLES)/ansi/ansi256.ans -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, RPL, ESCAPE124) += fate-armovie-escape124 -fate-armovie-escape124: CMD = framecrc -i $(TARGET_SAMPLES)/rpl/ESCAPE.RPL -pix_fmt rgb24 +fate-armovie-escape124: CMD = framecrc -i $(TARGET_SAMPLES)/rpl/ESCAPE.RPL -pix_fmt rgb24 -vf scale -af aresample FATE_VIDEO-$(call DEMDEC, RPL, ESCAPE130) += fate-armovie-escape130 fate-armovie-escape130: CMD = framecrc -i $(TARGET_SAMPLES)/rpl/landing.rpl -an @@ -43,11 +43,17 @@ fate-auravision-v1: CMD = framecrc -i $(TARGET_SAMPLES)/auravision/SOUVIDEO.AVI FATE_VIDEO-$(call DEMDEC, AVI, AURA2) += fate-auravision-v2 fate-auravision-v2: CMD = framecrc -i $(TARGET_SAMPLES)/auravision/salma-hayek-in-ugly-betty-partial-avi -an +FATE_VIDEO-$(call DEMDEC, AVI, AVRN) += fate-avid-interlaced +fate-avid-interlaced: CMD = framecrc -i $(TARGET_SAMPLES)/avid/avid_ntsc_interlaced.avi + +FATE_VIDEO-$(call DEMDEC, MOV, MJPEG) += fate-avid-meridian +fate-avid-meridian: CMD = framecrc -i $(TARGET_SAMPLES)/avid/avidmeridianntsc.mov + FATE_VIDEO-$(call DEMDEC, BETHSOFTVID, BETHSOFTVID) += fate-bethsoft-vid -fate-bethsoft-vid: CMD = framecrc -i $(TARGET_SAMPLES)/bethsoft-vid/ANIM0001.VID -t 5 -pix_fmt rgb24 +fate-bethsoft-vid: CMD = framecrc -i $(TARGET_SAMPLES)/bethsoft-vid/ANIM0001.VID -t 5 -pix_fmt rgb24 -vf scale -af aresample FATE_VIDEO-$(call DEMDEC, BFI, BFI) += fate-bfi -fate-bfi: CMD = framecrc -i $(TARGET_SAMPLES)/bfi/2287.bfi -pix_fmt rgb24 +fate-bfi: CMD = framecrc -i $(TARGET_SAMPLES)/bfi/2287.bfi -pix_fmt rgb24 -vf scale -af aresample FATE_BINK_VIDEO += fate-bink-video-b fate-bink-video-b: CMD = framecrc -i $(TARGET_SAMPLES)/bink/RISE.BIK -frames 30 @@ -61,22 +67,22 @@ fate-bink-video-i: CMD = framecrc -i $(TARGET_SAMPLES)/bink/RazOnBull.bik -an FATE_VIDEO-$(call DEMDEC, BINK, BINK) += $(FATE_BINK_VIDEO) FATE_VIDEO-$(call DEMDEC, BMV, BMV_VIDEO) += fate-bmv-video -fate-bmv-video: CMD = framecrc -i $(TARGET_SAMPLES)/bmv/SURFING-partial.BMV -pix_fmt rgb24 -an +fate-bmv-video: CMD = framecrc -i $(TARGET_SAMPLES)/bmv/SURFING-partial.BMV -pix_fmt rgb24 -an -vf scale -vf scale FATE_VIDEO-$(call DEMDEC, MPEGPS, CAVS) += fate-cavs fate-cavs: CMD = framecrc -i $(TARGET_SAMPLES)/cavs/cavs.mpg -an FATE_VIDEO-$(call DEMDEC, CDG, CDGRAPHICS) += fate-cdgraphics -fate-cdgraphics: CMD = framecrc -i $(TARGET_SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgba -t 1 +fate-cdgraphics: CMD = framecrc -i $(TARGET_SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgba -t 1 -vf scale FATE_CFHD-$(CONFIG_AVI_DEMUXER) += fate-cfhd-1 -fate-cfhd-1: CMD = framecrc -i $(TARGET_SAMPLES)/cfhd/cfhd_422.avi -pix_fmt yuv422p10le +fate-cfhd-1: CMD = framecrc -i $(TARGET_SAMPLES)/cfhd/cfhd_422.avi -pix_fmt yuv422p10le -vf scale FATE_CFHD-$(CONFIG_AVI_DEMUXER) += fate-cfhd-2 -fate-cfhd-2: CMD = framecrc -i $(TARGET_SAMPLES)/cfhd/cfhd_444.avi -pix_fmt gbrp12le +fate-cfhd-2: CMD = framecrc -i $(TARGET_SAMPLES)/cfhd/cfhd_444.avi -pix_fmt gbrp12le -vf scale FATE_CFHD-$(CONFIG_MOV_DEMUXER) += fate-cfhd-3 -fate-cfhd-3: CMD = framecrc -i $(TARGET_SAMPLES)/cfhd/cfhd_odd.mov -pix_fmt yuv422p10le +fate-cfhd-3: CMD = framecrc -i $(TARGET_SAMPLES)/cfhd/cfhd_odd.mov -pix_fmt yuv422p10le -vf scale FATE_VIDEO-$(CONFIG_CFHD_DECODER) += $(FATE_CFHD-yes) fate-cfhd: $(FATE_CFHD-yes) @@ -85,16 +91,16 @@ FATE_VIDEO-$(call DEMDEC, AVI, CLJR) += fate-cljr fate-cljr: CMD = framecrc -i $(TARGET_SAMPLES)/cljr/testcljr-partial.avi FATE_VIDEO-$(call DEMDEC, AVI, PNG) += fate-corepng -fate-corepng: CMD = framecrc -i $(TARGET_SAMPLES)/png1/corepng-partial.avi +fate-corepng: CMD = framecrc -i $(TARGET_SAMPLES)/png1/corepng-partial.avi -vf scale -af aresample FATE_VIDEO-$(call DEMDEC, AVI, PNG) += fate-rgbapng-4816 fate-rgbapng-4816: CMD = framecrc -i $(TARGET_SAMPLES)/png1/55c99e750a5fd6_50314226.png FATE_VIDEO-$(call DEMDEC, AVS, AVS) += fate-creatureshock-avs -fate-creatureshock-avs: CMD = framecrc -i $(TARGET_SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24 +fate-creatureshock-avs: CMD = framecrc -i $(TARGET_SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24 -vf scale -af aresample FATE_CVID-$(CONFIG_MOV_DEMUXER) += fate-cvid-palette -fate-cvid-palette: CMD = framecrc -i $(TARGET_SAMPLES)/cvid/catfight-cvid-pal8-partial.mov -pix_fmt rgb24 -an +fate-cvid-palette: CMD = framecrc -i $(TARGET_SAMPLES)/cvid/catfight-cvid-pal8-partial.mov -pix_fmt rgb24 -an -vf scale FATE_CVID-$(CONFIG_AVI_DEMUXER) += fate-cvid-partial fate-cvid-partial: CMD = framecrc -i $(TARGET_SAMPLES)/cvid/laracroft-cinepak-partial.avi -an @@ -106,16 +112,16 @@ FATE_VIDEO-$(CONFIG_CINEPAK_DECODER) += $(FATE_CVID-yes) fate-cvid: $(FATE_CVID-yes) FATE_VIDEO-$(call DEMDEC, C93, C93) += fate-cyberia-c93 -fate-cyberia-c93: CMD = framecrc -i $(TARGET_SAMPLES)/cyberia-c93/intro1.c93 -t 3 -pix_fmt rgb24 +fate-cyberia-c93: CMD = framecrc -i $(TARGET_SAMPLES)/cyberia-c93/intro1.c93 -t 3 -pix_fmt rgb24 -vf scale -af aresample FATE_VIDEO-$(call DEMDEC, AVI, CYUV) += fate-cyuv fate-cyuv: CMD = framecrc -i $(TARGET_SAMPLES)/cyuv/cyuv.avi FATE_VIDEO-$(call DEMDEC, DSICIN, DSICINVIDEO) += fate-delphine-cin-video -fate-delphine-cin-video: CMD = framecrc -i $(TARGET_SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24 -an +fate-delphine-cin-video: CMD = framecrc -i $(TARGET_SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, ANM, ANM) += fate-deluxepaint-anm -fate-deluxepaint-anm: CMD = framecrc -i $(TARGET_SAMPLES)/deluxepaint-anm/INTRO1.ANM -pix_fmt rgb24 +fate-deluxepaint-anm: CMD = framecrc -i $(TARGET_SAMPLES)/deluxepaint-anm/INTRO1.ANM -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, DIRAC, DIRAC) += fate-dirac fate-dirac: CMD = framecrc -i $(TARGET_SAMPLES)/dirac/vts.profile-main.drc @@ -124,10 +130,10 @@ FATE_VIDEO-$(call DEMDEC, DIRAC, DIRAC) += fate-dirac-low-delay fate-dirac-low-delay: CMD = framecrc -i $(TARGET_SAMPLES)/dirac/vts.profile-vc2-low-delay.drc FATE_DXA += fate-dxa-feeble -fate-dxa-feeble: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/meetsquid.dxa -t 2 -pix_fmt rgb24 -an +fate-dxa-feeble: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/meetsquid.dxa -t 2 -pix_fmt rgb24 -an -vf scale FATE_DXA += fate-dxa-scummvm -fate-dxa-scummvm: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/scummvm.dxa -pix_fmt rgb24 +fate-dxa-scummvm: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/scummvm.dxa -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, DXA, DXA) += $(FATE_DXA) fate-dxa: $(FATE_DXA) @@ -151,13 +157,13 @@ FATE_VIDEO-$(call DEMDEC, SEGAFILM, CINEPAK) += fate-film-cvid fate-film-cvid: CMD = framecrc -i $(TARGET_SAMPLES)/film/logo-capcom.cpk -an FATE_FLIC += fate-flic-af11-palette-change -fate-flic-af11-palette-change: CMD = framecrc -i $(TARGET_SAMPLES)/fli/fli-engines.fli -t 3.31 -pix_fmt rgb24 +fate-flic-af11-palette-change: CMD = framecrc -i $(TARGET_SAMPLES)/fli/fli-engines.fli -t 3.31 -pix_fmt rgb24 -vf scale FATE_FLIC += fate-flic-af12 -fate-flic-af12: CMD = framecrc -i $(TARGET_SAMPLES)/fli/jj00c2.fli -pix_fmt rgb24 +fate-flic-af12: CMD = framecrc -i $(TARGET_SAMPLES)/fli/jj00c2.fli -pix_fmt rgb24 -vf scale FATE_FLIC += fate-flic-magiccarpet -fate-flic-magiccarpet: CMD = framecrc -i $(TARGET_SAMPLES)/fli/intel.dat -pix_fmt rgb24 +fate-flic-magiccarpet: CMD = framecrc -i $(TARGET_SAMPLES)/fli/intel.dat -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, FLIC, FLIC) += $(FATE_FLIC) fate-flic: $(FATE_FLIC) @@ -166,40 +172,43 @@ FATE_VIDEO-$(call DEMDEC, AVI, FRWU) += fate-frwu fate-frwu: CMD = framecrc -i $(TARGET_SAMPLES)/frwu/frwu.avi FATE_VIDEO-$(call DEMDEC, IDCIN, IDCIN) += fate-id-cin-video -fate-id-cin-video: CMD = framecrc -i $(TARGET_SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24 +fate-id-cin-video: CMD = framecrc -i $(TARGET_SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call ENCDEC, ROQ PGMYUV, ROQ IMAGE2) += fate-idroq-video-encode -fate-idroq-video-encode: CMD = md5 -f image2 -c:v pgmyuv -i $(TARGET_SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -r 30 -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2 +fate-idroq-video-encode: CMD = md5 -auto_conversion_filters -f image2 -c:v pgmyuv -i $(TARGET_SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -r 30 -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2 FATE_IFF-$(CONFIG_IFF_ILBM_DECODER) += fate-iff-byterun1 -fate-iff-byterun1: CMD = framecrc -i $(TARGET_SAMPLES)/iff/ASH.LBM -pix_fmt rgb24 +fate-iff-byterun1: CMD = framecrc -i $(TARGET_SAMPLES)/iff/ASH.LBM -pix_fmt rgb24 -vf scale FATE_IFF-$(CONFIG_EIGHTSVX_FIB_DECODER) += fate-iff-fibonacci -fate-iff-fibonacci: CMD = md5 -i $(TARGET_SAMPLES)/iff/dasboot-in-compressed -f s16le +fate-iff-fibonacci: CMD = md5 -i $(TARGET_SAMPLES)/iff/dasboot-in-compressed -f s16le -vf scale -af aresample FATE_IFF-$(CONFIG_IFF_ILBM_DECODER) += fate-iff-ilbm -fate-iff-ilbm: CMD = framecrc -i $(TARGET_SAMPLES)/iff/lms-matriks.ilbm -pix_fmt rgb24 +fate-iff-ilbm: CMD = framecrc -i $(TARGET_SAMPLES)/iff/lms-matriks.ilbm -pix_fmt rgb24 -vf scale FATE_VIDEO-$(CONFIG_IFF_DEMUXER) += $(FATE_IFF-yes) fate-iff: $(FATE_IFF-yes) FATE_VIDEO-$(call DEMDEC, IPMOVIE, INTERPLAY_VIDEO) += fate-interplay-mve-8bit -fate-interplay-mve-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/interplay-logo-2MB.mve -pix_fmt rgb24 -an +fate-interplay-mve-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/interplay-logo-2MB.mve -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, IPMOVIE, INTERPLAY_VIDEO) += fate-interplay-mve-16bit -fate-interplay-mve-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24 -an +fate-interplay-mve-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, MXF, JPEG2000) += fate-jpeg2000-dcinema -fate-jpeg2000-dcinema: CMD = framecrc -flags +bitexact -c:v jpeg2000 -i $(TARGET_SAMPLES)/jpeg2000/chiens_dcinema2K.mxf -pix_fmt xyz12le +fate-jpeg2000-dcinema: CMD = framecrc -flags +bitexact -c:v jpeg2000 -i $(TARGET_SAMPLES)/jpeg2000/chiens_dcinema2K.mxf -pix_fmt xyz12le -vf scale FATE_VIDEO-$(call DEMDEC, JV, JV) += fate-jv -fate-jv: CMD = framecrc -i $(TARGET_SAMPLES)/jv/intro.jv -an -pix_fmt rgb24 +fate-jv: CMD = framecrc -i $(TARGET_SAMPLES)/jv/intro.jv -an -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, AVI, KGV1) += fate-kgv1 -fate-kgv1: CMD = framecrc -i $(TARGET_SAMPLES)/kega/kgv1.avi -pix_fmt rgb555le -an +fate-kgv1: CMD = framecrc -i $(TARGET_SAMPLES)/kega/kgv1.avi -pix_fmt rgb555le -an -vf scale FATE_VIDEO-$(call DEMDEC, AVI, KMVC) += fate-kmvc -fate-kmvc: CMD = framecrc -i $(TARGET_SAMPLES)/KMVC/LOGO1.AVI -an -t 3 -pix_fmt rgb24 +fate-kmvc: CMD = framecrc -i $(TARGET_SAMPLES)/KMVC/LOGO1.AVI -an -t 3 -pix_fmt rgb24 -vf scale + +FATE_VIDEO-$(call DEMDEC, AVI, LSCR) += fate-lscr +fate-lscr: CMD = framecrc -i $(TARGET_SAMPLES)/lscr/lscr_compr9_short.avi FATE_MAGICYUV += fate-magicyuv-y4444i \ fate-magicyuv-y400i \ @@ -236,7 +245,7 @@ FATE_VIDEO-$(call DEMDEC, AVI, MJPEG) += fate-mjpeg-ticket3229 fate-mjpeg-ticket3229: CMD = framecrc -idct simple -fflags +bitexact -i $(TARGET_SAMPLES)/mjpeg/mjpeg_field_order.avi -an FATE_VIDEO-$(call DEMDEC, MVI, MOTIONPIXELS) += fate-motionpixels -fate-motionpixels: CMD = framecrc -i $(TARGET_SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -frames:v 111 +fate-motionpixels: CMD = framecrc -i $(TARGET_SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -frames:v 111 -vf scale FATE_VIDEO-$(call DEMDEC, MPEGTS, MPEG2VIDEO) += fate-mpeg2-field-enc fate-mpeg2-ticket186 fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an -frames:v 30 @@ -246,13 +255,13 @@ FATE_VIDEO-$(call DEMDEC, MPEGPS, MPEG2VIDEO) += fate-mpeg2-ticket6024 fate-mpeg2-ticket6024: CMD = framecrc -flags +bitexact -idct simple -flags +truncated -i $(TARGET_SAMPLES)/mpeg2/matrixbench_mpeg2.lq1.mpg -an FATE_VIDEO-$(call DEMDEC, MPEGVIDEO, MPEG2VIDEO) += fate-mpeg2-ticket6677 -fate-mpeg2-ticket6677: CMD = framecrc -flags +bitexact -idct simple -vsync drop -i $(TARGET_SAMPLES)/mpeg2/sony-ct3.bs +fate-mpeg2-ticket6677: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/sony-ct3.bs FATE_VIDEO-$(call DEMDEC, MV, MVC1) += fate-mv-mvc1 -fate-mv-mvc1: CMD = framecrc -i $(TARGET_SAMPLES)/mv/posture.mv -an -frames 25 -pix_fmt rgb555le +fate-mv-mvc1: CMD = framecrc -i $(TARGET_SAMPLES)/mv/posture.mv -an -frames 25 -pix_fmt rgb555le -vf scale FATE_VIDEO-$(call DEMDEC, MV, MVC2) += fate-mv-mvc2 -fate-mv-mvc2: CMD = framecrc -i $(TARGET_SAMPLES)/mv/12345.mv -an -frames 30 -pix_fmt bgra +fate-mv-mvc2: CMD = framecrc -i $(TARGET_SAMPLES)/mv/12345.mv -an -frames 30 -pix_fmt bgra -vf scale FATE_VIDEO-$(call DEMDEC, MV, SGIRLE) += fate-mv-sgirle fate-mv-sgirle: CMD = framecrc -i $(TARGET_SAMPLES)/mv/pet-rle.movie -an @@ -271,43 +280,43 @@ FATE_VIDEO-$(call DEMDEC, NUV, NUV) += $(FATE_NUV) fate-nuv: $(FATE_NUV) FATE_VIDEO-$(call DEMDEC, PAF, PAF_VIDEO) += fate-paf-video -fate-paf-video: CMD = framecrc -i $(TARGET_SAMPLES)/paf/hod1-partial.paf -pix_fmt rgb24 -an +fate-paf-video: CMD = framecrc -i $(TARGET_SAMPLES)/paf/hod1-partial.paf -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, AVI, QPEG) += fate-qpeg -fate-qpeg: CMD = framecrc -i $(TARGET_SAMPLES)/qpeg/Clock.avi -an -pix_fmt rgb24 +fate-qpeg: CMD = framecrc -i $(TARGET_SAMPLES)/qpeg/Clock.avi -an -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, AVI, R210) += fate-r210 -fate-r210: CMD = framecrc -i $(TARGET_SAMPLES)/r210/r210.avi -pix_fmt rgb48le +fate-r210: CMD = framecrc -i $(TARGET_SAMPLES)/r210/r210.avi -pix_fmt rgb48le -vf scale FATE_VIDEO-$(call DEMDEC, RL2, RL2) += fate-rl2 -fate-rl2: CMD = framecrc -i $(TARGET_SAMPLES)/rl2/Z4915300.RL2 -pix_fmt rgb24 -an +fate-rl2: CMD = framecrc -i $(TARGET_SAMPLES)/rl2/Z4915300.RL2 -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, ROQ, ROQ) += fate-roqvideo fate-roqvideo: CMD = framecrc -i $(TARGET_SAMPLES)/idroq/idlogo.roq -an FATE_VIDEO-$(call DEMDEC, SMUSH, SANM) += fate-sanm -fate-sanm: CMD = framecrc -i $(TARGET_SAMPLES)/smush/ronin_part.znm -an -pix_fmt rgb24 +fate-sanm: CMD = framecrc -i $(TARGET_SAMPLES)/smush/ronin_part.znm -an -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, VMD, VMDVIDEO) += fate-sierra-vmd-video -fate-sierra-vmd-video: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -pix_fmt rgb24 -an +fate-sierra-vmd-video: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, SMACKER, SMACKER) += fate-smacker-video -fate-smacker-video: CMD = framecrc -i $(TARGET_SAMPLES)/smacker/wetlogo.smk -pix_fmt rgb24 -an +fate-smacker-video: CMD = framecrc -i $(TARGET_SAMPLES)/smacker/wetlogo.smk -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, MOV, SMC) += fate-smc -fate-smc: CMD = framecrc -i $(TARGET_SAMPLES)/smc/cass_schi.qt -pix_fmt rgb24 +fate-smc: CMD = framecrc -i $(TARGET_SAMPLES)/smc/cass_schi.qt -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, AVI, SP5X) += fate-sp5x -fate-sp5x: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/sp5x/sp5x_problem.avi +fate-sp5x: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/sp5x/sp5x_problem.avi -vf scale -af aresample FATE_VIDEO-$(call DEMDEC, THP, THP) += fate-thp fate-thp: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/thp/pikmin2-opening1-partial.thp -an FATE_VIDEO-$(call DEMDEC, TIERTEXSEQ, TIERTEXSEQVIDEO) += fate-tiertex-seq -fate-tiertex-seq: CMD = framecrc -i $(TARGET_SAMPLES)/tiertex-seq/Gameover.seq -pix_fmt rgb24 +fate-tiertex-seq: CMD = framecrc -i $(TARGET_SAMPLES)/tiertex-seq/Gameover.seq -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, TMV, TMV) += fate-tmv -fate-tmv: CMD = framecrc -i $(TARGET_SAMPLES)/tmv/pop-partial.tmv -pix_fmt rgb24 +fate-tmv: CMD = framecrc -i $(TARGET_SAMPLES)/tmv/pop-partial.tmv -pix_fmt rgb24 -vf scale -af aresample FATE_TXD += fate-txd-16bpp fate-txd-16bpp: CMD = framecrc -i $(TARGET_SAMPLES)/txd/misc.txd -an @@ -316,7 +325,7 @@ FATE_TXD += fate-txd-odd fate-txd-odd: CMD = framecrc -i $(TARGET_SAMPLES)/txd/odd.txd -an FATE_TXD += fate-txd-pal8 -fate-txd-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an +fate-txd-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, TXD, TXD) += $(FATE_TXD) fate-txd: $(FATE_TXD) @@ -325,17 +334,17 @@ FATE_VIDEO-$(call DEMDEC, AVI, ULTI) += fate-ulti fate-ulti: CMD = framecrc -i $(TARGET_SAMPLES)/ulti/hit12w.avi -an FATE_VIDEO-$(call DEMDEC, AVI, V210) += fate-v210 -fate-v210: CMD = framecrc -i $(TARGET_SAMPLES)/v210/v210_720p-partial.avi -pix_fmt yuv422p16be -an +fate-v210: CMD = framecrc -i $(TARGET_SAMPLES)/v210/v210_720p-partial.avi -pix_fmt yuv422p16be -an -vf scale FATE_VIDEO-$(call DEMDEC, MOV, V410) += fate-v410dec -fate-v410dec: CMD = framecrc -i $(TARGET_SAMPLES)/v410/lenav410.mov -pix_fmt yuv444p10le +fate-v410dec: CMD = framecrc -i $(TARGET_SAMPLES)/v410/lenav410.mov -pix_fmt yuv444p10le -vf scale FATE_VIDEO-$(call ENCDEC, V410 PGMYUV, AVI IMAGE2) += fate-v410enc fate-v410enc: $(VREF) -fate-v410enc: CMD = md5 -f image2 -c:v pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -fflags +bitexact -c:v v410 -f avi +fate-v410enc: CMD = md5 -f image2 -c:v pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -fflags +bitexact -c:v v410 -f avi -vf scale FATE_VIDEO-$(call DEMDEC, SIFF, VB) += fate-vb -fate-vb: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24 -an +fate-vb: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, AVI, VCR1) += fate-vcr1 fate-vcr1: CMD = framecrc -i $(TARGET_SAMPLES)/vcr1/VCR1test.avi -an @@ -347,16 +356,16 @@ FATE_VIDEO-$(call DEMDEC, AVI, XL) += fate-videoxl fate-videoxl: CMD = framecrc -i $(TARGET_SAMPLES)/vixl/pig-vixl.avi FATE_VIDEO-$(call DEMDEC, WSVQA, VQA) += fate-vqa-cc -fate-vqa-cc: CMD = framecrc -i $(TARGET_SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24 -an +fate-vqa-cc: CMD = framecrc -i $(TARGET_SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, WC3, XAN_WC3) += fate-wc3movie-xan -fate-wc3movie-xan: CMD = framecrc -i $(TARGET_SAMPLES)/wc3movie/SC_32-part.MVE -pix_fmt rgb24 +fate-wc3movie-xan: CMD = framecrc -i $(TARGET_SAMPLES)/wc3movie/SC_32-part.MVE -pix_fmt rgb24 -vf scale FATE_VIDEO-$(call DEMDEC, AVI, WNV1) += fate-wnv1 fate-wnv1: CMD = framecrc -i $(TARGET_SAMPLES)/wnv1/wnv1-codec.avi -an FATE_VIDEO-$(call DEMDEC, YOP, YOP) += fate-yop -fate-yop: CMD = framecrc -i $(TARGET_SAMPLES)/yop/test1.yop -pix_fmt rgb24 -an +fate-yop: CMD = framecrc -i $(TARGET_SAMPLES)/yop/test1.yop -pix_fmt rgb24 -an -vf scale FATE_VIDEO-$(call DEMDEC, AVI, XAN_WC4) += fate-xxan-wc4 fate-xxan-wc4: CMD = framecrc -i $(TARGET_SAMPLES)/wc4-xan/wc4trailer-partial.avi -an diff --git a/tests/fate/voice.mak b/tests/fate/voice.mak index f3a289239..61a4617b4 100644 --- a/tests/fate/voice.mak +++ b/tests/fate/voice.mak @@ -10,28 +10,28 @@ FATE_VOICE-yes += $(FATE_G722-yes) fate-g722: $(FATE_G722-yes) FATE_G723_1 += fate-g723_1-dec-1 -fate-g723_1-dec-1: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/ineqd53.tco +fate-g723_1-dec-1: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/ineqd53.tco -af aresample FATE_G723_1 += fate-g723_1-dec-2 -fate-g723_1-dec-2: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/overd53.tco +fate-g723_1-dec-2: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/overd53.tco -af aresample FATE_G723_1 += fate-g723_1-dec-3 -fate-g723_1-dec-3: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/overd63p.tco +fate-g723_1-dec-3: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/overd63p.tco -af aresample FATE_G723_1 += fate-g723_1-dec-4 -fate-g723_1-dec-4: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/pathd53.tco +fate-g723_1-dec-4: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/pathd53.tco -af aresample FATE_G723_1 += fate-g723_1-dec-5 -fate-g723_1-dec-5: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/pathd63p.tco +fate-g723_1-dec-5: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/pathd63p.tco -af aresample FATE_G723_1 += fate-g723_1-dec-6 -fate-g723_1-dec-6: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/tamed63p.tco +fate-g723_1-dec-6: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/tamed63p.tco -af aresample FATE_G723_1 += fate-g723_1-dec-7 -fate-g723_1-dec-7: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63b.tco +fate-g723_1-dec-7: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63b.tco -af aresample FATE_G723_1 += fate-g723_1-dec-8 -fate-g723_1-dec-8: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63e.tco +fate-g723_1-dec-8: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63e.tco -af aresample FATE_VOICE-$(call DEMDEC, G723_1, G723_1) += $(FATE_G723_1) fate-g723_1: $(FATE_G723_1) diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak index 88ccc70a5..857a4f2a1 100644 --- a/tests/fate/vpx.mak +++ b/tests/fate/vpx.mak @@ -1,8 +1,8 @@ FATE_TRUEMOTION1 += fate-truemotion1-15 -fate-truemotion1-15: CMD = framecrc -i $(TARGET_SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24 -an +fate-truemotion1-15: CMD = framecrc -i $(TARGET_SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24 -an -vf scale FATE_TRUEMOTION1 += fate-truemotion1-24 -fate-truemotion1-24: CMD = framecrc -i $(TARGET_SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24 -an +fate-truemotion1-24: CMD = framecrc -i $(TARGET_SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24 -an -vf scale FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, TRUEMOTION1) += $(FATE_TRUEMOTION1) fate-truemotion1: $(FATE_TRUEMOTION1) @@ -141,8 +141,8 @@ $(foreach W,$(VP9_SIZE_A),$(eval $(foreach H,$(VP9_SIZE_A),$(eval $(call FATE_VP $(foreach W,$(VP9_SIZE_B),$(eval $(foreach H,$(VP9_SIZE_B),$(eval $(call FATE_VP9_SUITE,03-size-$(W)x$(H)))))) $(eval $(call FATE_VP9_SUITE,03-deltaq)) $(foreach SS,$(VP9_CHROMA_SUBSAMPLE),$(eval $(call FATE_VP9_PROFILE_SUITE,04-yuv$(SS),1,))) -$(foreach BD,$(VP9_HIGH_BITDEPTH),$(eval $(call FATE_VP9_PROFILE_SUITE,20-$(BD)bit-yuv420,2,-pix_fmt yuv420p$(BD)le))) -$(foreach BD,$(VP9_HIGH_BITDEPTH),$(eval $(foreach SS,$(VP9_CHROMA_SUBSAMPLE),$(eval $(call FATE_VP9_PROFILE_SUITE,20-$(BD)bit-yuv$(SS),3,-pix_fmt yuv$(SS)p$(BD)le))))) +$(foreach BD,$(VP9_HIGH_BITDEPTH),$(eval $(call FATE_VP9_PROFILE_SUITE,20-$(BD)bit-yuv420,2,-pix_fmt yuv420p$(BD)le -vf scale))) +$(foreach BD,$(VP9_HIGH_BITDEPTH),$(eval $(foreach SS,$(VP9_CHROMA_SUBSAMPLE),$(eval $(call FATE_VP9_PROFILE_SUITE,20-$(BD)bit-yuv$(SS),3,-pix_fmt yuv$(SS)p$(BD)le -vf scale))))) $(eval $(call FATE_VP9_SUITE,06-bilinear)) $(eval $(call FATE_VP9_SUITE,09-lf_deltas)) $(eval $(call FATE_VP9_SUITE,10-show-existing-frame)) diff --git a/tests/fate/wavpack.mak b/tests/fate/wavpack.mak index 96b4d16bf..03cd8e466 100644 --- a/tests/fate/wavpack.mak +++ b/tests/fate/wavpack.mak @@ -3,90 +3,90 @@ FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += $(FATE_WAVPACK) # lossless FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-8bit -fate-wavpack-lossless-8bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/8bit-partial.wv -f s8 +fate-wavpack-lossless-8bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/8bit-partial.wv -f s8 -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-12bit -fate-wavpack-lossless-12bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/12bit-partial.wv -f s16le +fate-wavpack-lossless-12bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/12bit-partial.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-16bit -fate-wavpack-lossless-16bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/16bit-partial.wv -f s16le +fate-wavpack-lossless-16bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/16bit-partial.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-24bit -fate-wavpack-lossless-24bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/24bit-partial.wv -f s24le +fate-wavpack-lossless-24bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/24bit-partial.wv -f s24le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-32bit -fate-wavpack-lossless-32bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/32bit_int-partial.wv -f s32le +fate-wavpack-lossless-32bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/32bit_int-partial.wv -f s32le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossless-float -fate-wavpack-lossless-float: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/32bit_float-partial.wv -f f32le +fate-wavpack-lossless-float: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/32bit_float-partial.wv -f f32le -af aresample # lossy FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-8bit -fate-wavpack-lossy-8bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_8-bit.wv -f s8 +fate-wavpack-lossy-8bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_8-bit.wv -f s8 -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-16bit -fate-wavpack-lossy-16bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_16-bit.wv -f s16le +fate-wavpack-lossy-16bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_16-bit.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-24bit -fate-wavpack-lossy-24bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_24-bit.wv -f s24le +fate-wavpack-lossy-24bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_24-bit.wv -f s24le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-32bit -fate-wavpack-lossy-32bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_32-bit_int.wv -f s32le +fate-wavpack-lossy-32bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_32-bit_int.wv -f s32le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-lossy-float -fate-wavpack-lossy-float: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/2.0_32-bit_float.wv -f f32le +fate-wavpack-lossy-float: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/2.0_32-bit_float.wv -f f32le -af aresample # channel configurations FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-monofloat -fate-wavpack-channels-monofloat: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_float-partial.wv -f f32le +fate-wavpack-channels-monofloat: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_float-partial.wv -f f32le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-monoint -fate-wavpack-channels-monoint: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -f s16le +fate-wavpack-channels-monoint: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-4.0 -fate-wavpack-channels-4.0: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/edward_4.0_16bit-partial.wv -f s16le +fate-wavpack-channels-4.0: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/edward_4.0_16bit-partial.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-5.1 -fate-wavpack-channels-5.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/panslab_sample_5.1_16bit-partial.wv -f s16le +fate-wavpack-channels-5.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/panslab_sample_5.1_16bit-partial.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-6.1 -fate-wavpack-channels-6.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -f s16le +fate-wavpack-channels-6.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-channels-7.1 -fate-wavpack-channels-7.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/panslab_sample_7.1_16bit-partial.wv -f s16le +fate-wavpack-channels-7.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/panslab_sample_7.1_16bit-partial.wv -f s16le -af aresample # speed modes FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-speed-default -fate-wavpack-speed-default: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/default-partial.wv -f s16le +fate-wavpack-speed-default: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/default-partial.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-speed-fast -fate-wavpack-speed-fast: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/fast-partial.wv -f s16le +fate-wavpack-speed-fast: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/fast-partial.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-speed-high -fate-wavpack-speed-high: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/high-partial.wv -f s16le +fate-wavpack-speed-high: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/high-partial.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-speed-vhigh -fate-wavpack-speed-vhigh: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/vhigh-partial.wv -f s16le +fate-wavpack-speed-vhigh: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/vhigh-partial.wv -f s16le -af aresample # special cases FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-clipping -fate-wavpack-clipping: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/clipping.wv -f s16le +fate-wavpack-clipping: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/clipping.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-cuesheet -fate-wavpack-cuesheet: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/cue_sheet.wv -f s16le +fate-wavpack-cuesheet: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/cue_sheet.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-falsestereo -fate-wavpack-falsestereo: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/false_stereo.wv -f s16le +fate-wavpack-falsestereo: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/false_stereo.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += fate-wavpack-zerolsbs -fate-wavpack-zerolsbs: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/zero_lsbs.wv -f s16le +fate-wavpack-zerolsbs: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/zero_lsbs.wv -f s16le -af aresample FATE_WAVPACK-$(call DEMDEC, MATROSKA, WAVPACK) += fate-wavpack-matroskamode -fate-wavpack-matroskamode: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/matroska_mode.mka -f s16le +fate-wavpack-matroskamode: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/matroska_mode.mka -f s16le -af aresample FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-mono fate-wavpack-matroska_mux-mono: CMD = md5pipe -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -c copy -fflags +bitexact -f matroska diff --git a/tests/filtergraphs/overlay_yuv420p10 b/tests/filtergraphs/overlay_yuv420p10 new file mode 100644 index 000000000..d946d3c52 --- /dev/null +++ b/tests/filtergraphs/overlay_yuv420p10 @@ -0,0 +1,5 @@ +sws_flags=+accurate_rnd+bitexact; +split [main][over]; +[over] scale=88:72, format=yuv420p10, pad=96:80:4:4 [overf]; +[main] format=yuv420p10 [mainf]; +[mainf][overf] overlay=240:16:format=yuv420p10 diff --git a/tests/filtergraphs/overlay_yuv422p10 b/tests/filtergraphs/overlay_yuv422p10 new file mode 100644 index 000000000..5753ba6c9 --- /dev/null +++ b/tests/filtergraphs/overlay_yuv422p10 @@ -0,0 +1,5 @@ +sws_flags=+accurate_rnd+bitexact; +split [main][over]; +[over] scale=88:72, format=yuv420p10, pad=96:80:4:4 [overf]; +[main] format=yuv420p10 [mainf]; +[mainf][overf] overlay=240:16:format=yuv422p10 diff --git a/tests/ref/acodec/adpcm-argo b/tests/ref/acodec/adpcm-argo new file mode 100644 index 000000000..127153c08 --- /dev/null +++ b/tests/ref/acodec/adpcm-argo @@ -0,0 +1,4 @@ +14b2507d14e95c20bb7ae49b4fcbcbf1 *tests/data/fate/acodec-adpcm-argo.argo_asf +281190 tests/data/fate/acodec-adpcm-argo.argo_asf +cc5e5c695adeaebaa2b1f0df5ebd59ee *tests/data/fate/acodec-adpcm-argo.out.wav +stddev: 1542.05 PSNR: 32.57 MAXDIFF:59667 bytes: 1058400/ 1058432 diff --git a/tests/ref/acodec/adpcm-ima_alp b/tests/ref/acodec/adpcm-ima_alp new file mode 100644 index 000000000..a4e714327 --- /dev/null +++ b/tests/ref/acodec/adpcm-ima_alp @@ -0,0 +1,4 @@ +d84466bdfbe6405fa31e44df255f6aad *tests/data/fate/acodec-adpcm-ima_alp.alp +264620 tests/data/fate/acodec-adpcm-ima_alp.alp +d60c48654568a1cf0abd56b565b12f00 *tests/data/fate/acodec-adpcm-ima_alp.out.wav +stddev: 1467.15 PSNR: 33.00 MAXDIFF:33866 bytes: 1058400/ 1058400 diff --git a/tests/ref/acodec/adpcm-ima_apm b/tests/ref/acodec/adpcm-ima_apm new file mode 100644 index 000000000..83bd21f83 --- /dev/null +++ b/tests/ref/acodec/adpcm-ima_apm @@ -0,0 +1,4 @@ +2e795c6c06baabe01ab92864d963e71b *tests/data/fate/acodec-adpcm-ima_apm.apm +264700 tests/data/fate/acodec-adpcm-ima_apm.apm +201607bf7610f062b9a1e6524354c569 *tests/data/fate/acodec-adpcm-ima_apm.out.wav +stddev: 904.76 PSNR: 37.20 MAXDIFF:34029 bytes: 1058400/ 1058400 diff --git a/tests/ref/acodec/adpcm-swf b/tests/ref/acodec/adpcm-swf index 2cb9e905c..61d92da08 100644 --- a/tests/ref/acodec/adpcm-swf +++ b/tests/ref/acodec/adpcm-swf @@ -1,4 +1,4 @@ -42d4639866ed4d692eaf126228a4fa2a *tests/data/fate/acodec-adpcm-swf.flv -269166 tests/data/fate/acodec-adpcm-swf.flv -628089745a7059ae4055c2515b6d668b *tests/data/fate/acodec-adpcm-swf.out.wav -stddev: 933.58 PSNR: 36.93 MAXDIFF:51119 bytes: 1058400/ 1064960 +64aedd1487cb355406dde36d2bba374f *tests/data/fate/acodec-adpcm-swf.flv +267801 tests/data/fate/acodec-adpcm-swf.flv +9d061488fdc1a557bdc454b9d1aba59c *tests/data/fate/acodec-adpcm-swf.out.wav +stddev: 919.82 PSNR: 37.06 MAXDIFF:51119 bytes: 1058400/ 1064960 diff --git a/tests/ref/acodec/adpcm-swf-trellis b/tests/ref/acodec/adpcm-swf-trellis index a2bb565e1..f4c69ca62 100644 --- a/tests/ref/acodec/adpcm-swf-trellis +++ b/tests/ref/acodec/adpcm-swf-trellis @@ -1,4 +1,4 @@ -ec8859b3206ea0c45701fbdcf60dbe48 *tests/data/fate/acodec-adpcm-swf-trellis.flv -269166 tests/data/fate/acodec-adpcm-swf-trellis.flv -29820ce5b95b3b0a2feafa808cc264a7 *tests/data/fate/acodec-adpcm-swf-trellis.out.wav -stddev: 747.92 PSNR: 38.85 MAXDIFF:51119 bytes: 1058400/ 1064960 +fde151ce9b8be0e144e72113508bcff6 *tests/data/fate/acodec-adpcm-swf-trellis.flv +267801 tests/data/fate/acodec-adpcm-swf-trellis.flv +6a0007e42d92a225a8becddedccf9a0f *tests/data/fate/acodec-adpcm-swf-trellis.out.wav +stddev: 731.05 PSNR: 39.05 MAXDIFF:51119 bytes: 1058400/ 1064960 diff --git a/tests/ref/acodec/adpcm-swf-wav b/tests/ref/acodec/adpcm-swf-wav new file mode 100644 index 000000000..80ce287b0 --- /dev/null +++ b/tests/ref/acodec/adpcm-swf-wav @@ -0,0 +1,4 @@ +a21ee5ba531ec89e306d78c861eb6ed1 *tests/data/fate/acodec-adpcm-swf-wav.wav +266624 tests/data/fate/acodec-adpcm-swf-wav.wav +9d061488fdc1a557bdc454b9d1aba59c *tests/data/fate/acodec-adpcm-swf-wav.out.wav +stddev: 919.82 PSNR: 37.06 MAXDIFF:51119 bytes: 1058400/ 1064960 diff --git a/tests/ref/fate/aa-demux b/tests/ref/fate/aa-demux new file mode 100644 index 000000000..89350b880 --- /dev/null +++ b/tests/ref/fate/aa-demux @@ -0,0 +1,283 @@ +#tb 0: 1/1062500 +#media_type 0: audio +#codec_id 0: sipr +#sample_rate 0: 8500 +#channel_layout 0: 4 +#channel_layout_name 0: mono +0, 0, 0, 18000, 19, 0x36e10529 +0, 18000, 18000, 18000, 19, 0x70810a69 +0, 36000, 36000, 18000, 19, 0x618f08a0 +0, 54000, 54000, 18000, 19, 0x65a508bd +0, 72000, 72000, 18000, 19, 0x50420796 +0, 90000, 90000, 18000, 19, 0x6468084f +0, 108000, 108000, 18000, 19, 0x75020a84 +0, 126000, 126000, 18000, 19, 0x68be09ae +0, 144000, 144000, 18000, 19, 0x6cb709b8 +0, 162000, 162000, 18000, 19, 0x3fee061e +0, 180000, 180000, 18000, 19, 0x53220770 +0, 198000, 198000, 18000, 19, 0x57590888 +0, 216000, 216000, 18000, 19, 0x6653089c +0, 234000, 234000, 18000, 19, 0x55eb081f +0, 252000, 252000, 18000, 19, 0x79750ad6 +0, 270000, 270000, 18000, 19, 0x5e340927 +0, 288000, 288000, 18000, 19, 0x60c80974 +0, 306000, 306000, 18000, 19, 0x6c5008f5 +0, 324000, 324000, 18000, 19, 0x6f5609ca +0, 342000, 342000, 18000, 19, 0x79a609f5 +0, 360000, 360000, 18000, 19, 0x6fa308d5 +0, 378000, 378000, 18000, 19, 0x56de0789 +0, 396000, 396000, 18000, 19, 0x567408bf +0, 414000, 414000, 18000, 19, 0x62800968 +0, 432000, 432000, 18000, 19, 0x64ae0a88 +0, 450000, 450000, 18000, 19, 0x73eb0af5 +0, 468000, 468000, 18000, 19, 0x6f1e0ac0 +0, 486000, 486000, 18000, 19, 0x5d0e0a34 +0, 504000, 504000, 18000, 19, 0x61990a70 +0, 522000, 522000, 18000, 19, 0x71e00a8a +0, 540000, 540000, 18000, 19, 0x6c400a3f +0, 558000, 558000, 18000, 19, 0x5f850921 +0, 576000, 576000, 18000, 19, 0x6e7e0a5e +0, 594000, 594000, 18000, 19, 0x4bbe08cd +0, 612000, 612000, 18000, 19, 0x62c407d5 +0, 630000, 630000, 18000, 19, 0x475f07b9 +0, 648000, 648000, 18000, 19, 0x6f480a68 +0, 666000, 666000, 18000, 19, 0x65710a4d +0, 684000, 684000, 18000, 19, 0x4b2d0841 +0, 702000, 702000, 18000, 19, 0x64a80a03 +0, 720000, 720000, 18000, 19, 0x61f608fa +0, 738000, 738000, 18000, 19, 0x6fb70a5e +0, 756000, 756000, 18000, 19, 0x5f4e0a48 +0, 774000, 774000, 18000, 19, 0x5a200919 +0, 792000, 792000, 18000, 19, 0x69af0a1f +0, 810000, 810000, 18000, 19, 0x643d094a +0, 828000, 828000, 18000, 19, 0x56e707f7 +0, 846000, 846000, 18000, 19, 0x60ed0923 +0, 864000, 864000, 18000, 19, 0x6d5d099c +0, 882000, 882000, 18000, 19, 0x736d0abd +0, 900000, 900000, 18000, 19, 0x578d0981 +0, 918000, 918000, 18000, 19, 0x621f0979 +0, 936000, 936000, 18000, 19, 0x690a0938 +0, 954000, 954000, 18000, 19, 0x55df096f +0, 972000, 972000, 18000, 19, 0x5b900945 +0, 990000, 990000, 18000, 19, 0x595e090a +0, 1008000, 1008000, 18000, 19, 0x6f3a0b0d +0, 1026000, 1026000, 18000, 19, 0x5df80902 +0, 1044000, 1044000, 18000, 19, 0x61fa08f6 +0, 1062000, 1062000, 18000, 19, 0x6a8e0a90 +0, 1080000, 1080000, 18000, 19, 0x7ec40b7d +0, 1098000, 1098000, 18000, 19, 0x554707e3 +0, 1116000, 1116000, 18000, 19, 0x5ef9097a +0, 1134000, 1134000, 18000, 19, 0x74d40c65 +0, 1152000, 1152000, 18000, 19, 0x52c909a3 +0, 1170000, 1170000, 18000, 19, 0x79740b0c +0, 1188000, 1188000, 18000, 19, 0x64350b42 +0, 1206000, 1206000, 18000, 19, 0x65f109f4 +0, 1224000, 1224000, 18000, 19, 0x53760920 +0, 1242000, 1242000, 18000, 19, 0x5600091a +0, 1260000, 1260000, 18000, 19, 0x5b4e08c2 +0, 1278000, 1278000, 18000, 19, 0x672d09d0 +0, 1296000, 1296000, 18000, 19, 0x658e09bc +0, 1314000, 1314000, 18000, 19, 0x5a560999 +0, 1332000, 1332000, 18000, 19, 0x69a40ae0 +0, 1350000, 1350000, 18000, 19, 0x602a0855 +0, 1368000, 1368000, 18000, 19, 0x4f8606ed +0, 1386000, 1386000, 18000, 19, 0x78cb0afe +0, 1404000, 1404000, 18000, 19, 0x661609dc +0, 1422000, 1422000, 18000, 19, 0x6ea50b3d +0, 1440000, 1440000, 18000, 19, 0x60a709dd +0, 1458000, 1458000, 18000, 19, 0x55ef082b +0, 1476000, 1476000, 18000, 19, 0x6ab70a57 +0, 1494000, 1494000, 18000, 19, 0x68cb0b92 +0, 1512000, 1512000, 18000, 19, 0x752809f5 +0, 1530000, 1530000, 18000, 19, 0x4e810789 +0, 1548000, 1548000, 18000, 19, 0x60130987 +0, 1566000, 1566000, 18000, 19, 0x5ea40a08 +0, 1584000, 1584000, 18000, 19, 0x628507d4 +0, 1602000, 1602000, 18000, 19, 0x5fc2096c +0, 1620000, 1620000, 18000, 19, 0x52a70775 +0, 1638000, 1638000, 18000, 19, 0x6e4b09af +0, 1656000, 1656000, 18000, 19, 0x79750aab +0, 1674000, 1674000, 18000, 19, 0x5e23085a +0, 1692000, 1692000, 18000, 19, 0x4fb8081b +0, 1710000, 1710000, 18000, 19, 0x574b07fc +0, 1728000, 1728000, 18000, 19, 0x59d407b2 +0, 1746000, 1746000, 18000, 19, 0x56d308d4 +0, 1764000, 1764000, 18000, 19, 0x61310856 +0, 1782000, 1782000, 18000, 19, 0x4df90867 +0, 1800000, 1800000, 18000, 19, 0x3d760522 +0, 1818000, 1818000, 18000, 19, 0x5a0f0917 +0, 1836000, 1836000, 18000, 19, 0x5e8d0939 +0, 1854000, 1854000, 18000, 19, 0x65ee081a +0, 1872000, 1872000, 18000, 19, 0x4665056f +0, 1890000, 1890000, 18000, 19, 0x55c70851 +0, 1908000, 1908000, 18000, 19, 0x6cf00a94 +0, 1926000, 1926000, 18000, 19, 0x698308f0 +0, 1944000, 1944000, 18000, 19, 0x4c9106c9 +0, 1962000, 1962000, 18000, 19, 0x719d0a28 +0, 1980000, 1980000, 18000, 19, 0x491f06cc +0, 1998000, 1998000, 18000, 19, 0x61fa0972 +0, 2016000, 2016000, 18000, 19, 0x49b105cb +0, 2034000, 2034000, 18000, 19, 0x4b5f071f +0, 2052000, 2052000, 18000, 19, 0x5e8e08b3 +0, 2070000, 2070000, 18000, 19, 0x5d2309bb +0, 2088000, 2088000, 18000, 19, 0x4e8806d1 +0, 2106000, 2106000, 18000, 19, 0x566607dc +0, 2124000, 2124000, 18000, 19, 0x4b2506ee +0, 2142000, 2142000, 18000, 19, 0x4d810687 +0, 2160000, 2160000, 18000, 19, 0x51990841 +0, 2178000, 2178000, 18000, 19, 0x5e220870 +0, 2196000, 2196000, 18000, 19, 0x4b2f0787 +0, 2214000, 2214000, 18000, 19, 0x4a4b05f0 +0, 2232000, 2232000, 18000, 19, 0x485106b5 +0, 2250000, 2250000, 18000, 19, 0x58d20755 +0, 2268000, 2268000, 18000, 19, 0x51b807ad +0, 2286000, 2286000, 18000, 19, 0x475b06d0 +0, 2304000, 2304000, 18000, 19, 0x4f93072f +0, 2322000, 2322000, 18000, 19, 0x5841082a +0, 2340000, 2340000, 18000, 19, 0x5e7f08f6 +0, 2358000, 2358000, 18000, 19, 0x4cb7075c +0, 2376000, 2376000, 18000, 19, 0x560807b9 +0, 2394000, 2394000, 18000, 19, 0x49fb0732 +0, 2412000, 2412000, 18000, 19, 0x56790830 +0, 2430000, 2430000, 18000, 19, 0x4962066b +0, 2448000, 2448000, 18000, 19, 0x4f410703 +0, 2466000, 2466000, 18000, 19, 0x517c078f +0, 2484000, 2484000, 18000, 19, 0x594c0850 +0, 2502000, 2502000, 18000, 19, 0x5df7089d +0, 2520000, 2520000, 18000, 19, 0x4b0c0813 +0, 2538000, 2538000, 18000, 19, 0x5b4d08ec +0, 2556000, 2556000, 18000, 19, 0x66840a37 +0, 2574000, 2574000, 18000, 19, 0x60d20942 +0, 2592000, 2592000, 18000, 19, 0x5049082e +0, 2610000, 2610000, 18000, 19, 0x64a60b38 +0, 2628000, 2628000, 18000, 19, 0x49400889 +0, 2646000, 2646000, 18000, 19, 0x598608f6 +0, 2664000, 2664000, 18000, 19, 0x496e0736 +0, 2682000, 2682000, 18000, 19, 0x5c5008af +0, 2700000, 2700000, 18000, 19, 0x633b0aa7 +0, 2718000, 2718000, 18000, 19, 0x58ae0888 +0, 2736000, 2736000, 18000, 19, 0x3da106b3 +0, 2754000, 2754000, 18000, 19, 0x3f7b077b +0, 2772000, 2772000, 18000, 19, 0x4ba60917 +0, 2790000, 2790000, 18000, 19, 0x5637099b +0, 2808000, 2808000, 18000, 19, 0x61e10a50 +0, 2826000, 2826000, 18000, 19, 0x5157078e +0, 2844000, 2844000, 18000, 19, 0x55cf0943 +0, 2862000, 2862000, 18000, 19, 0x59b308cb +0, 2880000, 2880000, 18000, 19, 0x61920a8e +0, 2898000, 2898000, 18000, 19, 0x6ee20b7b +0, 2916000, 2916000, 18000, 19, 0x67620a9a +0, 2934000, 2934000, 18000, 19, 0x57cb0933 +0, 2952000, 2952000, 18000, 19, 0x618209d8 +0, 2970000, 2970000, 18000, 19, 0x65bb0a22 +0, 2988000, 2988000, 18000, 19, 0x55ec0911 +0, 3006000, 3006000, 18000, 19, 0x607e0966 +0, 3024000, 3024000, 18000, 19, 0x40ee05f0 +0, 3042000, 3042000, 18000, 19, 0x5b9308f5 +0, 3060000, 3060000, 18000, 19, 0x5eb3089a +0, 3078000, 3078000, 18000, 19, 0x555a0842 +0, 3096000, 3096000, 18000, 19, 0x66980839 +0, 3114000, 3114000, 18000, 19, 0x532e08d2 +0, 3132000, 3132000, 18000, 19, 0x672d0a76 +0, 3150000, 3150000, 18000, 19, 0x5c780996 +0, 3168000, 3168000, 18000, 19, 0x51d408cc +0, 3186000, 3186000, 18000, 19, 0x6ee10c12 +0, 3204000, 3204000, 18000, 19, 0x463c081d +0, 3222000, 3222000, 18000, 19, 0x65850aa0 +0, 3240000, 3240000, 18000, 19, 0x6d1c0a88 +0, 3258000, 3258000, 18000, 19, 0x5ace08d7 +0, 3276000, 3276000, 18000, 19, 0x5fef096a +0, 3294000, 3294000, 18000, 19, 0x590607e9 +0, 3312000, 3312000, 18000, 19, 0x61bd0a65 +0, 3330000, 3330000, 18000, 19, 0x633808c2 +0, 3348000, 3348000, 18000, 19, 0x3ea2063a +0, 3366000, 3366000, 18000, 19, 0x5ff70a03 +0, 3384000, 3384000, 18000, 19, 0x6c020997 +0, 3402000, 3402000, 18000, 19, 0x82b00c41 +0, 3420000, 3420000, 18000, 19, 0x6b9509d2 +0, 3438000, 3438000, 18000, 19, 0x54af0943 +0, 3456000, 3456000, 18000, 19, 0x49d40802 +0, 3474000, 3474000, 18000, 19, 0x52de08df +0, 3492000, 3492000, 18000, 19, 0x6dae0ad8 +0, 3510000, 3510000, 18000, 19, 0x5fbc0883 +0, 3528000, 3528000, 18000, 19, 0x56620873 +0, 3546000, 3546000, 18000, 19, 0x5203093c +0, 3564000, 3564000, 18000, 19, 0x653d0b5f +0, 3582000, 3582000, 18000, 19, 0x6068097d +0, 3600000, 3600000, 18000, 19, 0x57700810 +0, 3618000, 3618000, 18000, 19, 0x562809ce +0, 3636000, 3636000, 18000, 19, 0x57ad0849 +0, 3654000, 3654000, 18000, 19, 0x5dde099d +0, 3672000, 3672000, 18000, 19, 0x66700947 +0, 3690000, 3690000, 18000, 19, 0x5ca108fb +0, 3708000, 3708000, 18000, 19, 0x53270773 +0, 3726000, 3726000, 18000, 19, 0x63a50a30 +0, 3744000, 3744000, 18000, 19, 0x64f20a63 +0, 3762000, 3762000, 18000, 19, 0x654509e0 +0, 3780000, 3780000, 18000, 19, 0x560207f2 +0, 3798000, 3798000, 18000, 19, 0x54bf0811 +0, 3816000, 3816000, 18000, 19, 0x5bb70a2d +0, 3834000, 3834000, 18000, 19, 0x661d08dd +0, 3852000, 3852000, 18000, 19, 0x4f130960 +0, 3870000, 3870000, 18000, 19, 0x56000920 +0, 3888000, 3888000, 18000, 19, 0x59110a1d +0, 3906000, 3906000, 18000, 19, 0x588009c7 +0, 3924000, 3924000, 18000, 19, 0x60b40a23 +0, 3942000, 3942000, 18000, 19, 0x5ab708dd +0, 3960000, 3960000, 18000, 19, 0x510208b6 +0, 3978000, 3978000, 18000, 19, 0x4cbb07fd +0, 3996000, 3996000, 18000, 19, 0x5a990938 +0, 4014000, 4014000, 18000, 19, 0x671b09f7 +0, 4032000, 4032000, 18000, 19, 0x76d90a8a +0, 4050000, 4050000, 18000, 19, 0x81350b4b +0, 4068000, 4068000, 18000, 19, 0x5eeb08b8 +0, 4086000, 4086000, 18000, 19, 0x538d0a68 +0, 4104000, 4104000, 18000, 19, 0x649a0962 +0, 4122000, 4122000, 18000, 19, 0x64130a0b +0, 4140000, 4140000, 18000, 19, 0x5ef30948 +0, 4158000, 4158000, 18000, 19, 0x585a0824 +0, 4176000, 4176000, 18000, 19, 0x46ce07ff +0, 4194000, 4194000, 18000, 19, 0x50bc08da +0, 4212000, 4212000, 18000, 19, 0x5b1d08a5 +0, 4230000, 4230000, 18000, 19, 0x5da50993 +0, 4248000, 4248000, 18000, 19, 0x4d15087b +0, 4266000, 4266000, 18000, 19, 0x472106a1 +0, 4284000, 4284000, 18000, 19, 0x6713098a +0, 4302000, 4302000, 18000, 19, 0x4bec0881 +0, 4320000, 4320000, 18000, 19, 0x607109d9 +0, 4338000, 4338000, 18000, 19, 0x631a0af3 +0, 4356000, 4356000, 18000, 19, 0x7b020b89 +0, 4374000, 4374000, 18000, 19, 0x6cc80ae5 +0, 4392000, 4392000, 18000, 19, 0x5bce0a35 +0, 4410000, 4410000, 18000, 19, 0x71750a72 +0, 4428000, 4428000, 18000, 19, 0x61330af8 +0, 4446000, 4446000, 18000, 19, 0x80390d10 +0, 4464000, 4464000, 18000, 19, 0x60300a32 +0, 4482000, 4482000, 18000, 19, 0x4bbb0764 +0, 4500000, 4500000, 18000, 19, 0x749c0a92 +0, 4518000, 4518000, 18000, 19, 0x5d0709ce +0, 4536000, 4536000, 18000, 19, 0x75400bd2 +0, 4554000, 4554000, 18000, 19, 0x56b008ed +0, 4572000, 4572000, 18000, 19, 0x5b5309ec +0, 4590000, 4590000, 18000, 19, 0x4f110862 +0, 4608000, 4608000, 18000, 19, 0x574e0869 +0, 4626000, 4626000, 18000, 19, 0x58e409a7 +0, 4644000, 4644000, 18000, 19, 0x636108d7 +0, 4662000, 4662000, 18000, 19, 0x5a8b0862 +0, 4680000, 4680000, 18000, 19, 0x508908ec +0, 4698000, 4698000, 18000, 19, 0x4bdd06d8 +0, 4716000, 4716000, 18000, 19, 0x6abb0a58 +0, 4734000, 4734000, 18000, 19, 0x674b0ab4 +0, 4752000, 4752000, 18000, 19, 0x587d08be +0, 4770000, 4770000, 18000, 19, 0x63f808b9 +0, 4788000, 4788000, 18000, 19, 0x662609e4 +0, 4806000, 4806000, 18000, 19, 0x6c490b07 +0, 4824000, 4824000, 18000, 19, 0x41df075a +0, 4842000, 4842000, 18000, 19, 0x5f870a0f +0, 4860000, 4860000, 18000, 19, 0x600f0a87 +0, 4878000, 4878000, 18000, 19, 0x535f0880 +0, 4896000, 4896000, 18000, 19, 0x5f3a09e5 +0, 4914000, 4914000, 18000, 19, 0x529d08d4 +0, 4932000, 4932000, 18000, 19, 0x67630a76 +0, 4950000, 4950000, 18000, 19, 0x4bc40844 +0, 4968000, 4968000, 18000, 19, 0x5091083a diff --git a/tests/ref/fate/adpcm-ima-amv b/tests/ref/fate/adpcm-ima-amv index eb174dfa8..2f8c0a2cd 100644 --- a/tests/ref/fate/adpcm-ima-amv +++ b/tests/ref/fate/adpcm-ima-amv @@ -8,159 +8,159 @@ 0, 1378, 1378, 1378, 2756, 0x8462443f 0, 2756, 2756, 1378, 2756, 0x9f493ba6 0, 4134, 4134, 1378, 2756, 0x634e5f06 -0, 5512, 5512, 1380, 2760, 0x51f35cd4 -0, 6892, 6892, 1378, 2756, 0x011c51e5 -0, 8270, 8270, 1378, 2756, 0x8c2c198c -0, 9648, 9648, 1378, 2756, 0x2b4a3397 -0, 11026, 11026, 1378, 2756, 0x63794f22 -0, 12404, 12404, 1378, 2756, 0xfc363898 -0, 13782, 13782, 1378, 2756, 0x0da5486e -0, 15160, 15160, 1378, 2756, 0xbae17a5f -0, 16538, 16538, 1380, 2760, 0xba266e1b -0, 17918, 17918, 1378, 2756, 0xdfb61002 -0, 19296, 19296, 1378, 2756, 0x15d029da -0, 20674, 20674, 1378, 2756, 0x7bc82012 -0, 22052, 22052, 1378, 2756, 0x002e6999 -0, 23430, 23430, 1378, 2756, 0x96346ba6 -0, 24808, 24808, 1378, 2756, 0x3d54543b -0, 26186, 26186, 1380, 2760, 0x601786e1 -0, 27566, 27566, 1378, 2756, 0xf22a5793 -0, 28944, 28944, 1378, 2756, 0x21f54d49 -0, 30322, 30322, 1378, 2756, 0x0c6d4399 -0, 31700, 31700, 1378, 2756, 0x17282f8e -0, 33078, 33078, 1378, 2756, 0xeb698f75 -0, 34456, 34456, 1378, 2756, 0x935e1de2 -0, 35834, 35834, 1380, 2760, 0xb6fb4293 -0, 37214, 37214, 1378, 2756, 0x485053dc -0, 38592, 38592, 1378, 2756, 0x24c35027 -0, 39970, 39970, 1378, 2756, 0x09f323ee -0, 41348, 41348, 1378, 2756, 0xbc7d58d5 -0, 42726, 42726, 1378, 2756, 0xaefd487c -0, 44104, 44104, 1378, 2756, 0xaca16cc0 -0, 45482, 45482, 1380, 2760, 0x98a76091 -0, 46862, 46862, 1378, 2756, 0x5d357141 -0, 48240, 48240, 1378, 2756, 0x65ea2657 -0, 49618, 49618, 1378, 2756, 0xb5e1334a -0, 50996, 50996, 1378, 2756, 0x32cd5d91 -0, 52374, 52374, 1378, 2756, 0xdc23722b -0, 53752, 53752, 1378, 2756, 0x2ba34684 -0, 55130, 55130, 1378, 2756, 0xf9755ba8 -0, 56508, 56508, 1380, 2760, 0x24221ddb -0, 57888, 57888, 1378, 2756, 0xef843aa4 -0, 59266, 59266, 1378, 2756, 0x420442fe -0, 60644, 60644, 1378, 2756, 0x5a0933cb -0, 62022, 62022, 1378, 2756, 0xef5f6d61 -0, 63400, 63400, 1378, 2756, 0xe57e6dc0 -0, 64778, 64778, 1378, 2756, 0xc0f0495a -0, 66156, 66156, 1380, 2760, 0x2c3b55df -0, 67536, 67536, 1378, 2756, 0x39c2586c -0, 68914, 68914, 1378, 2756, 0x7ffc46e5 -0, 70292, 70292, 1378, 2756, 0xa2766664 -0, 71670, 71670, 1378, 2756, 0xacb50c6c -0, 73048, 73048, 1378, 2756, 0x7f659084 -0, 74426, 74426, 1378, 2756, 0xc72e6a12 -0, 75804, 75804, 1380, 2760, 0xdb6944df -0, 77184, 77184, 1378, 2756, 0x954f45c1 -0, 78562, 78562, 1378, 2756, 0xa9484240 -0, 79940, 79940, 1378, 2756, 0x1d595349 -0, 81318, 81318, 1378, 2756, 0xcf2a565e -0, 82696, 82696, 1378, 2756, 0x391028d5 -0, 84074, 84074, 1378, 2756, 0x348db7ad -0, 85452, 85452, 1380, 2760, 0xb69b5e3a -0, 86832, 86832, 1378, 2756, 0xe3635fbe -0, 88210, 88210, 1378, 2756, 0xdcad3654 -0, 89588, 89588, 1378, 2756, 0x5c17abef -0, 90966, 90966, 1378, 2756, 0xb3235184 -0, 92344, 92344, 1378, 2756, 0xdabb64a6 -0, 93722, 93722, 1378, 2756, 0xa95dc58d -0, 95100, 95100, 1380, 2760, 0x8e7ac9eb -0, 96480, 96480, 1378, 2756, 0x492b658e -0, 97858, 97858, 1378, 2756, 0x377483ab -0, 99236, 99236, 1378, 2756, 0x2c250279 -0, 100614, 100614, 1378, 2756, 0x704dbdb3 -0, 101992, 101992, 1378, 2756, 0x800d7da2 -0, 103370, 103370, 1378, 2756, 0x872aa32e -0, 104748, 104748, 1378, 2756, 0x2d4837fe -0, 106126, 106126, 1380, 2760, 0xc89ea57e -0, 107506, 107506, 1378, 2756, 0x6447d7ef -0, 108884, 108884, 1378, 2756, 0x144f59cc -0, 110262, 110262, 1378, 2756, 0xc667154e -0, 111640, 111640, 1378, 2756, 0xf0de66ae -0, 113018, 113018, 1378, 2756, 0xeabf3c32 -0, 114396, 114396, 1378, 2756, 0xe98e81d1 -0, 115774, 115774, 1380, 2760, 0x56aa5889 -0, 117154, 117154, 1378, 2756, 0x4fd34c0e -0, 118532, 118532, 1378, 2756, 0x67cf6912 -0, 119910, 119910, 1378, 2756, 0xfa944def -0, 121288, 121288, 1378, 2756, 0xc12f23b2 -0, 122666, 122666, 1378, 2756, 0x5ea325a2 -0, 124044, 124044, 1378, 2756, 0x2b245824 -0, 125422, 125422, 1380, 2760, 0x90ac533e -0, 126802, 126802, 1378, 2756, 0xcca34d26 -0, 128180, 128180, 1378, 2756, 0xb5f820d0 -0, 129558, 129558, 1378, 2756, 0x27f24335 -0, 130936, 130936, 1378, 2756, 0x4a9e87b7 -0, 132314, 132314, 1378, 2756, 0xbd076129 -0, 133692, 133692, 1378, 2756, 0x2e0e3f2e -0, 135070, 135070, 1380, 2760, 0xdf534478 -0, 136450, 136450, 1378, 2756, 0xca000a2e -0, 137828, 137828, 1378, 2756, 0x87472df3 -0, 139206, 139206, 1378, 2756, 0x16733810 -0, 140584, 140584, 1378, 2756, 0xfa0734b4 -0, 141962, 141962, 1378, 2756, 0x5eff3fc4 -0, 143340, 143340, 1378, 2756, 0xf35346bd -0, 144718, 144718, 1378, 2756, 0xac6411c5 -0, 146096, 146096, 1380, 2760, 0x478c3c56 -0, 147476, 147476, 1378, 2756, 0xebd30bdd -0, 148854, 148854, 1378, 2756, 0xaef95a31 -0, 150232, 150232, 1378, 2756, 0x8aad29d1 -0, 151610, 151610, 1378, 2756, 0x626863f0 -0, 152988, 152988, 1378, 2756, 0x68c05707 -0, 154366, 154366, 1378, 2756, 0x437c5e8d -0, 155744, 155744, 1380, 2760, 0x8eca4bdb -0, 157124, 157124, 1378, 2756, 0x62bd4162 -0, 158502, 158502, 1378, 2756, 0x9f744aa4 -0, 159880, 159880, 1378, 2756, 0x0f3f6409 -0, 161258, 161258, 1378, 2756, 0x3fee827a -0, 162636, 162636, 1378, 2756, 0x48a0ac19 -0, 164014, 164014, 1378, 2756, 0x8e4ce0d0 -0, 165392, 165392, 1380, 2760, 0xcda82236 -0, 166772, 166772, 1378, 2756, 0x0e523255 -0, 168150, 168150, 1378, 2756, 0x84103d30 -0, 169528, 169528, 1378, 2756, 0x13941cde -0, 170906, 170906, 1378, 2756, 0x9fc834c5 -0, 172284, 172284, 1378, 2756, 0xc0217a77 -0, 173662, 173662, 1378, 2756, 0x3f643659 -0, 175040, 175040, 1380, 2760, 0x9dbd6002 -0, 176420, 176420, 1378, 2756, 0x94f046fb -0, 177798, 177798, 1378, 2756, 0xab01fb12 -0, 179176, 179176, 1378, 2756, 0x04cffe5c -0, 180554, 180554, 1378, 2756, 0xef661c5e -0, 181932, 181932, 1378, 2756, 0x094c5fc5 -0, 183310, 183310, 1378, 2756, 0xe0c1486a -0, 184688, 184688, 1380, 2760, 0x8c3535b7 -0, 186068, 186068, 1378, 2756, 0x594934aa -0, 187446, 187446, 1378, 2756, 0x74007238 -0, 188824, 188824, 1378, 2756, 0x61f1394d -0, 190202, 190202, 1378, 2756, 0x72584f07 -0, 191580, 191580, 1378, 2756, 0xced9acf9 -0, 192958, 192958, 1378, 2756, 0x7d2e3ea1 -0, 194336, 194336, 1378, 2756, 0x56c06897 -0, 195714, 195714, 1380, 2760, 0x19983bbf -0, 197094, 197094, 1378, 2756, 0x4f884f27 -0, 198472, 198472, 1378, 2756, 0x81ab2f63 -0, 199850, 199850, 1378, 2756, 0x448e681d -0, 201228, 201228, 1378, 2756, 0x0ba9826e -0, 202606, 202606, 1378, 2756, 0x049f36fa -0, 203984, 203984, 1378, 2756, 0x096a2b62 -0, 205362, 205362, 1380, 2760, 0x579e2035 -0, 206742, 206742, 1378, 2756, 0xd13e30e1 -0, 208120, 208120, 1378, 2756, 0x30b6412b -0, 209498, 209498, 1378, 2756, 0xbb1c3268 -0, 210876, 210876, 1378, 2756, 0xbc175b6a -0, 212254, 212254, 1378, 2756, 0xf8d160e2 -0, 213632, 213632, 1378, 2756, 0xc1048154 -0, 215010, 215010, 1380, 2760, 0xb83548f4 -0, 216390, 216390, 1378, 2756, 0x22647962 -0, 217768, 217768, 1378, 2756, 0x14ca54d3 -0, 219146, 219146, 1354, 2708, 0x85e82e8d +0, 5512, 5512, 1379, 2758, 0x983d5ccb +0, 6891, 6891, 1378, 2756, 0x011c51e5 +0, 8269, 8269, 1378, 2756, 0x8c2c198c +0, 9647, 9647, 1378, 2756, 0x2b4a3397 +0, 11025, 11025, 1378, 2756, 0x63794f22 +0, 12403, 12403, 1378, 2756, 0xfc363898 +0, 13781, 13781, 1378, 2756, 0x0da5486e +0, 15159, 15159, 1378, 2756, 0xbae17a5f +0, 16537, 16537, 1379, 2758, 0xdde86dc6 +0, 17916, 17916, 1378, 2756, 0xdfb61002 +0, 19294, 19294, 1378, 2756, 0x15d029da +0, 20672, 20672, 1378, 2756, 0x7bc82012 +0, 22050, 22050, 1378, 2756, 0x002e6999 +0, 23428, 23428, 1378, 2756, 0x96346ba6 +0, 24806, 24806, 1378, 2756, 0x3d54543b +0, 26184, 26184, 1379, 2758, 0x5248862b +0, 27563, 27563, 1378, 2756, 0xf22a5793 +0, 28941, 28941, 1378, 2756, 0x21f54d49 +0, 30319, 30319, 1378, 2756, 0x0c6d4399 +0, 31697, 31697, 1378, 2756, 0x17282f8e +0, 33075, 33075, 1378, 2756, 0xeb698f75 +0, 34453, 34453, 1378, 2756, 0x935e1de2 +0, 35831, 35831, 1379, 2758, 0x31d5425d +0, 37210, 37210, 1378, 2756, 0x485053dc +0, 38588, 38588, 1378, 2756, 0x24c35027 +0, 39966, 39966, 1378, 2756, 0x09f323ee +0, 41344, 41344, 1378, 2756, 0xbc7d58d5 +0, 42722, 42722, 1378, 2756, 0xaefd487c +0, 44100, 44100, 1378, 2756, 0xaca16cc0 +0, 45478, 45478, 1379, 2758, 0xd8745ed3 +0, 46857, 46857, 1378, 2756, 0x5d357141 +0, 48235, 48235, 1378, 2756, 0x65ea2657 +0, 49613, 49613, 1378, 2756, 0xb5e1334a +0, 50991, 50991, 1378, 2756, 0x32cd5d91 +0, 52369, 52369, 1378, 2756, 0xdc23722b +0, 53747, 53747, 1378, 2756, 0x2ba34684 +0, 55125, 55125, 1378, 2756, 0xf9755ba8 +0, 56503, 56503, 1379, 2758, 0xe95c1ca8 +0, 57882, 57882, 1378, 2756, 0xef843aa4 +0, 59260, 59260, 1378, 2756, 0x420442fe +0, 60638, 60638, 1378, 2756, 0x5a0933cb +0, 62016, 62016, 1378, 2756, 0xef5f6d61 +0, 63394, 63394, 1378, 2756, 0xe57e6dc0 +0, 64772, 64772, 1378, 2756, 0xc0f0495a +0, 66150, 66150, 1379, 2758, 0x806e55de +0, 67529, 67529, 1378, 2756, 0x39c2586c +0, 68907, 68907, 1378, 2756, 0x7ffc46e5 +0, 70285, 70285, 1378, 2756, 0xa2766664 +0, 71663, 71663, 1378, 2756, 0xacb50c6c +0, 73041, 73041, 1378, 2756, 0x7f659084 +0, 74419, 74419, 1378, 2756, 0xc72e6a12 +0, 75797, 75797, 1379, 2758, 0x51ab446d +0, 77176, 77176, 1378, 2756, 0x954f45c1 +0, 78554, 78554, 1378, 2756, 0xa9484240 +0, 79932, 79932, 1378, 2756, 0x1d595349 +0, 81310, 81310, 1378, 2756, 0xcf2a565e +0, 82688, 82688, 1378, 2756, 0x391028d5 +0, 84066, 84066, 1378, 2756, 0x348db7ad +0, 85444, 85444, 1379, 2758, 0xfa185e28 +0, 86823, 86823, 1378, 2756, 0xe3635fbe +0, 88201, 88201, 1378, 2756, 0xdcad3654 +0, 89579, 89579, 1378, 2756, 0x5c17abef +0, 90957, 90957, 1378, 2756, 0xb3235184 +0, 92335, 92335, 1378, 2756, 0xdabb64a6 +0, 93713, 93713, 1378, 2756, 0xa95dc58d +0, 95091, 95091, 1379, 2758, 0xfa89c99b +0, 96470, 96470, 1378, 2756, 0x492b658e +0, 97848, 97848, 1378, 2756, 0x377483ab +0, 99226, 99226, 1378, 2756, 0x2c250279 +0, 100604, 100604, 1378, 2756, 0x704dbdb3 +0, 101982, 101982, 1378, 2756, 0x800d7da2 +0, 103360, 103360, 1378, 2756, 0x872aa32e +0, 104738, 104738, 1378, 2756, 0x2d4837fe +0, 106116, 106116, 1379, 2758, 0x7d93a536 +0, 107495, 107495, 1378, 2756, 0x6447d7ef +0, 108873, 108873, 1378, 2756, 0x144f59cc +0, 110251, 110251, 1378, 2756, 0xc667154e +0, 111629, 111629, 1378, 2756, 0xf0de66ae +0, 113007, 113007, 1378, 2756, 0xeabf3c32 +0, 114385, 114385, 1378, 2756, 0xe98e81d1 +0, 115763, 115763, 1379, 2758, 0xa58a57f4 +0, 117142, 117142, 1378, 2756, 0x4fd34c0e +0, 118520, 118520, 1378, 2756, 0x67cf6912 +0, 119898, 119898, 1378, 2756, 0xfa944def +0, 121276, 121276, 1378, 2756, 0xc12f23b2 +0, 122654, 122654, 1378, 2756, 0x5ea325a2 +0, 124032, 124032, 1378, 2756, 0x2b245824 +0, 125410, 125410, 1379, 2758, 0xeb1f5203 +0, 126789, 126789, 1378, 2756, 0xcca34d26 +0, 128167, 128167, 1378, 2756, 0xb5f820d0 +0, 129545, 129545, 1378, 2756, 0x27f24335 +0, 130923, 130923, 1378, 2756, 0x4a9e87b7 +0, 132301, 132301, 1378, 2756, 0xbd076129 +0, 133679, 133679, 1378, 2756, 0x2e0e3f2e +0, 135057, 135057, 1379, 2758, 0x5664442c +0, 136436, 136436, 1378, 2756, 0xca000a2e +0, 137814, 137814, 1378, 2756, 0x87472df3 +0, 139192, 139192, 1378, 2756, 0x16733810 +0, 140570, 140570, 1378, 2756, 0xfa0734b4 +0, 141948, 141948, 1378, 2756, 0x5eff3fc4 +0, 143326, 143326, 1378, 2756, 0xf35346bd +0, 144704, 144704, 1378, 2756, 0xac6411c5 +0, 146082, 146082, 1379, 2758, 0xcfcf3ae7 +0, 147461, 147461, 1378, 2756, 0xebd30bdd +0, 148839, 148839, 1378, 2756, 0xaef95a31 +0, 150217, 150217, 1378, 2756, 0x8aad29d1 +0, 151595, 151595, 1378, 2756, 0x626863f0 +0, 152973, 152973, 1378, 2756, 0x68c05707 +0, 154351, 154351, 1378, 2756, 0x437c5e8d +0, 155729, 155729, 1379, 2758, 0xf7054b53 +0, 157108, 157108, 1378, 2756, 0x62bd4162 +0, 158486, 158486, 1378, 2756, 0x9f744aa4 +0, 159864, 159864, 1378, 2756, 0x0f3f6409 +0, 161242, 161242, 1378, 2756, 0x3fee827a +0, 162620, 162620, 1378, 2756, 0x48a0ac19 +0, 163998, 163998, 1378, 2756, 0x8e4ce0d0 +0, 165376, 165376, 1379, 2758, 0x8a3b207f +0, 166755, 166755, 1378, 2756, 0x0e523255 +0, 168133, 168133, 1378, 2756, 0x84103d30 +0, 169511, 169511, 1378, 2756, 0x13941cde +0, 170889, 170889, 1378, 2756, 0x9fc834c5 +0, 172267, 172267, 1378, 2756, 0xc0217a77 +0, 173645, 173645, 1378, 2756, 0x3f643659 +0, 175023, 175023, 1379, 2758, 0xddac5fc3 +0, 176402, 176402, 1378, 2756, 0x94f046fb +0, 177780, 177780, 1378, 2756, 0xab01fb12 +0, 179158, 179158, 1378, 2756, 0x04cffe5c +0, 180536, 180536, 1378, 2756, 0xef661c5e +0, 181914, 181914, 1378, 2756, 0x094c5fc5 +0, 183292, 183292, 1378, 2756, 0xe0c1486a +0, 184670, 184670, 1379, 2758, 0x21c03448 +0, 186049, 186049, 1378, 2756, 0x594934aa +0, 187427, 187427, 1378, 2756, 0x74007238 +0, 188805, 188805, 1378, 2756, 0x61f1394d +0, 190183, 190183, 1378, 2756, 0x72584f07 +0, 191561, 191561, 1378, 2756, 0xced9acf9 +0, 192939, 192939, 1378, 2756, 0x7d2e3ea1 +0, 194317, 194317, 1378, 2756, 0x56c06897 +0, 195695, 195695, 1379, 2758, 0xa20b3b1b +0, 197074, 197074, 1378, 2756, 0x4f884f27 +0, 198452, 198452, 1378, 2756, 0x81ab2f63 +0, 199830, 199830, 1378, 2756, 0x448e681d +0, 201208, 201208, 1378, 2756, 0x0ba9826e +0, 202586, 202586, 1378, 2756, 0x049f36fa +0, 203964, 203964, 1378, 2756, 0x096a2b62 +0, 205342, 205342, 1379, 2758, 0x17361fbb +0, 206721, 206721, 1378, 2756, 0xd13e30e1 +0, 208099, 208099, 1378, 2756, 0x30b6412b +0, 209477, 209477, 1378, 2756, 0xbb1c3268 +0, 210855, 210855, 1378, 2756, 0xbc175b6a +0, 212233, 212233, 1378, 2756, 0xf8d160e2 +0, 213611, 213611, 1378, 2756, 0xc1048154 +0, 214989, 214989, 1379, 2758, 0x26564885 +0, 216368, 216368, 1378, 2756, 0x22647962 +0, 217746, 217746, 1378, 2756, 0x14ca54d3 +0, 219124, 219124, 1376, 2752, 0x2c374add diff --git a/tests/ref/fate/adpcm-ima-cunning-stereo b/tests/ref/fate/adpcm-ima-cunning-stereo new file mode 100644 index 000000000..7e11c8529 --- /dev/null +++ b/tests/ref/fate/adpcm-ima-cunning-stereo @@ -0,0 +1 @@ +c508235656525c97429153c639dbe8eb diff --git a/tests/ref/fate/adtstoasc_ticket3715 b/tests/ref/fate/adtstoasc_ticket3715 index 49fa3eb8d..fbdeeb058 100644 --- a/tests/ref/fate/adtstoasc_ticket3715 +++ b/tests/ref/fate/adtstoasc_ticket3715 @@ -1,4 +1,4 @@ -4110be924e21846d0e174fac679b062e *tests/data/fate/adtstoasc_ticket3715.mov +29ef0632a8eb5c336bf45a1d5076626e *tests/data/fate/adtstoasc_ticket3715.mov 33324 tests/data/fate/adtstoasc_ticket3715.mov #extradata 0: 2, 0x00340022 #tb 0: 1/44100 diff --git a/tests/ref/fate/apng-dispose-previous b/tests/ref/fate/apng-dispose-previous new file mode 100644 index 000000000..8c456390f --- /dev/null +++ b/tests/ref/fate/apng-dispose-previous @@ -0,0 +1,139 @@ +#tb 0: 1/10 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 85x128 +#sar 0: 0/1 +0, 0, 0, 1, 43520, 0xff012b7c +0, 1, 1, 1, 43520, 0x76842464 +0, 2, 2, 1, 43520, 0xa35de191 +0, 3, 3, 1, 43520, 0x7ece479c +0, 4, 4, 1, 43520, 0xea12fa4a +0, 5, 5, 1, 43520, 0xcb2c2256 +0, 6, 6, 1, 43520, 0x7d225965 +0, 7, 7, 1, 43520, 0xc0d95d3f +0, 8, 8, 1, 43520, 0xee864d84 +0, 9, 9, 1, 43520, 0x1fadbb0e +0, 10, 10, 1, 43520, 0xab89647b +0, 11, 11, 1, 43520, 0x206141bc +0, 12, 12, 1, 43520, 0x6432e720 +0, 13, 13, 1, 43520, 0xe25ab561 +0, 14, 14, 1, 43520, 0xc2df7c6b +0, 15, 15, 1, 43520, 0x372768c3 +0, 16, 16, 1, 43520, 0xfeea0d7b +0, 17, 17, 1, 43520, 0x89c1f76d +0, 18, 18, 1, 43520, 0xae16c8b3 +0, 19, 19, 1, 43520, 0x98949570 +0, 20, 20, 1, 43520, 0x5bb75099 +0, 21, 21, 1, 43520, 0xb4c73263 +0, 22, 22, 1, 43520, 0xcf26f441 +0, 23, 23, 1, 43520, 0xba47d23b +0, 24, 24, 1, 43520, 0x4c3e87da +0, 25, 25, 1, 43520, 0xe95b7398 +0, 26, 26, 1, 43520, 0x00575c74 +0, 27, 27, 1, 43520, 0xea1d59f6 +0, 28, 28, 1, 43520, 0xbede4d2e +0, 29, 29, 1, 43520, 0x9ed736a6 +0, 30, 30, 1, 43520, 0x8b027f56 +0, 31, 31, 1, 43520, 0x1db24f15 +0, 32, 32, 1, 43520, 0x1835a2dd +0, 33, 33, 1, 43520, 0xfda26b24 +0, 34, 34, 1, 43520, 0x52f3e8eb +0, 35, 35, 1, 43520, 0xda01102f +0, 36, 36, 1, 43520, 0x443adff3 +0, 37, 37, 1, 43520, 0x46c72f9a +0, 38, 38, 1, 43520, 0x3ec78642 +0, 39, 39, 1, 43520, 0x12033c40 +0, 40, 40, 1, 43520, 0x41fe0964 +0, 41, 41, 1, 43520, 0xc7a53be5 +0, 42, 42, 1, 43520, 0x4b185aa0 +0, 43, 43, 1, 43520, 0xf45cc1f0 +0, 44, 44, 1, 43520, 0x8bdc77cd +0, 45, 45, 1, 43520, 0x94c5ac41 +0, 46, 46, 1, 43520, 0xfbabeefe +0, 47, 47, 1, 43520, 0x92d657d9 +0, 48, 48, 1, 43520, 0x09dbd475 +0, 49, 49, 1, 43520, 0x5f9926e4 +0, 50, 50, 1, 43520, 0x4fdb5a64 +0, 51, 51, 1, 43520, 0xc0a382f6 +0, 52, 52, 1, 43520, 0x104f9b45 +0, 53, 53, 1, 43520, 0xfaf5d8f7 +0, 54, 54, 1, 43520, 0x2559e38b +0, 55, 55, 1, 43520, 0x82890381 +0, 56, 56, 1, 43520, 0xfe7aec01 +0, 57, 57, 1, 43520, 0x4543f499 +0, 58, 58, 1, 43520, 0x60d7cbd1 +0, 59, 59, 1, 43520, 0x576fc249 +0, 60, 60, 1, 43520, 0xc96d9035 +0, 61, 61, 1, 43520, 0x40857b3a +0, 62, 62, 1, 43520, 0x422a2eef +0, 63, 63, 1, 43520, 0xb1510101 +0, 64, 64, 1, 43520, 0x3f619ad7 +0, 65, 65, 1, 43520, 0x497f42fa +0, 66, 66, 1, 43520, 0x8b4b1ce2 +0, 67, 67, 1, 43520, 0x21f2f75b +0, 68, 68, 1, 43520, 0x8b4b1ce2 +0, 69, 69, 1, 43520, 0x497f42fa +0, 70, 70, 1, 43520, 0x3f619ad7 +0, 71, 71, 1, 43520, 0xb1510101 +0, 72, 72, 1, 43520, 0x422a2eef +0, 73, 73, 1, 43520, 0x40857b3a +0, 74, 74, 1, 43520, 0xc96d9035 +0, 75, 75, 1, 43520, 0x576fc249 +0, 76, 76, 1, 43520, 0x60d7cbd1 +0, 77, 77, 1, 43520, 0x4543f499 +0, 78, 78, 1, 43520, 0xfe7aec01 +0, 79, 79, 1, 43520, 0x82890381 +0, 80, 80, 1, 43520, 0x2559e38b +0, 81, 81, 1, 43520, 0xfaf5d8f7 +0, 82, 82, 1, 43520, 0x104f9b45 +0, 83, 83, 1, 43520, 0xc0a382f6 +0, 84, 84, 1, 43520, 0x4fdb5a64 +0, 85, 85, 1, 43520, 0x5f9926e4 +0, 86, 86, 1, 43520, 0x09dbd475 +0, 87, 87, 1, 43520, 0x92d657d9 +0, 88, 88, 1, 43520, 0xfbabeefe +0, 89, 89, 1, 43520, 0x94c5ac41 +0, 90, 90, 1, 43520, 0x8bdc77cd +0, 91, 91, 1, 43520, 0xf45cc1f0 +0, 92, 92, 1, 43520, 0x4b185aa0 +0, 93, 93, 1, 43520, 0xc7a53be5 +0, 94, 94, 1, 43520, 0x41fe0964 +0, 95, 95, 1, 43520, 0x12033c40 +0, 96, 96, 1, 43520, 0x3ec78642 +0, 97, 97, 1, 43520, 0x46c72f9a +0, 98, 98, 1, 43520, 0x443adff3 +0, 99, 99, 1, 43520, 0xda01102f +0, 100, 100, 1, 43520, 0x52f3e8eb +0, 101, 101, 1, 43520, 0xfda26b24 +0, 102, 102, 1, 43520, 0x1835a2dd +0, 103, 103, 1, 43520, 0x1db24f15 +0, 104, 104, 1, 43520, 0x8b027f56 +0, 105, 105, 1, 43520, 0x9ed736a6 +0, 106, 106, 1, 43520, 0xbede4d2e +0, 107, 107, 1, 43520, 0xea1d59f6 +0, 108, 108, 1, 43520, 0x00575c74 +0, 109, 109, 1, 43520, 0xe95b7398 +0, 110, 110, 1, 43520, 0x4c3e87da +0, 111, 111, 1, 43520, 0xba47d23b +0, 112, 112, 1, 43520, 0xcf26f441 +0, 113, 113, 1, 43520, 0xb4c73263 +0, 114, 114, 1, 43520, 0x5bb75099 +0, 115, 115, 1, 43520, 0x98949570 +0, 116, 116, 1, 43520, 0xae16c8b3 +0, 117, 117, 1, 43520, 0x89c1f76d +0, 118, 118, 1, 43520, 0xfeea0d7b +0, 119, 119, 1, 43520, 0x372768c3 +0, 120, 120, 1, 43520, 0xc2df7c6b +0, 121, 121, 1, 43520, 0xe25ab561 +0, 122, 122, 1, 43520, 0x6432e720 +0, 123, 123, 1, 43520, 0x206141bc +0, 124, 124, 1, 43520, 0xab89647b +0, 125, 125, 1, 43520, 0x1fadbb0e +0, 126, 126, 1, 43520, 0xee864d84 +0, 127, 127, 1, 43520, 0xc0d95d3f +0, 128, 128, 1, 43520, 0x7d225965 +0, 129, 129, 1, 43520, 0xcb2c2256 +0, 130, 130, 1, 43520, 0xea12fa4a +0, 131, 131, 1, 43520, 0x7ece479c +0, 132, 132, 1, 43520, 0xa35de191 +0, 133, 133, 1, 43520, 0x76842464 diff --git a/tests/ref/fate/asf-repldata b/tests/ref/fate/asf-repldata index 94744569f..59eaf0c2a 100644 --- a/tests/ref/fate/asf-repldata +++ b/tests/ref/fate/asf-repldata @@ -3,17 +3,17 @@ #codec_id 0: msmpeg4v3 #dimensions 0: 640x480 #sar 0: 0/1 -0, 0, 0, 0, 23374, 0x8725b3b8 -0, 122, 122, 0, 13732, 0x3ac8531a, F=0x0 -0, 245, 245, 0, 615, 0xd31641b4, F=0x0 -0, 367, 367, 0, 6361, 0xf263af54, F=0x0 -0, 490, 490, 0, 320, 0xd6f2d6b8, F=0x0 -0, 612, 612, 0, 3750, 0xfcf1d501, F=0x0 -0, 735, 735, 0, 2541, 0xd9fc04f9, F=0x0 -0, 857, 857, 0, 205, 0x4d38a947, F=0x0 -0, 980, 980, 0, 2166, 0x2f1e7d74, F=0x0 -0, 1102, 1102, 0, 1667, 0x0cd84b61, F=0x0 -0, 1224, 1224, 0, 13645, 0x543bd032, F=0x0 -0, 1347, 1347, 0, 5953, 0xc3037c73, F=0x0 -0, 1469, 1469, 0, 36169, 0xca9f716d -0, 1592, 1592, 0, 3030, 0x9aba5683, F=0x0 +0, 0, 0, 122, 23374, 0x8725b3b8 +0, 122, 122, 122, 13732, 0x3ac8531a, F=0x0 +0, 245, 245, 122, 615, 0xd31641b4, F=0x0 +0, 367, 367, 122, 6361, 0xf263af54, F=0x0 +0, 490, 490, 122, 320, 0xd6f2d6b8, F=0x0 +0, 612, 612, 122, 3750, 0xfcf1d501, F=0x0 +0, 735, 735, 122, 2541, 0xd9fc04f9, F=0x0 +0, 857, 857, 122, 205, 0x4d38a947, F=0x0 +0, 980, 980, 122, 2166, 0x2f1e7d74, F=0x0 +0, 1102, 1102, 122, 1667, 0x0cd84b61, F=0x0 +0, 1224, 1224, 122, 13645, 0x543bd032, F=0x0 +0, 1347, 1347, 122, 5953, 0xc3037c73, F=0x0 +0, 1469, 1469, 122, 36169, 0xca9f716d +0, 1592, 1592, 122, 3030, 0x9aba5683, F=0x0 diff --git a/tests/ref/fate/av1-annexb-demux b/tests/ref/fate/av1-annexb-demux index 139a893ec..77e0e378a 100644 --- a/tests/ref/fate/av1-annexb-demux +++ b/tests/ref/fate/av1-annexb-demux @@ -3,7 +3,7 @@ #media_type 0: video #codec_id 0: av1 #dimensions 0: 300x300 -#sar 0: 0/1 +#sar 0: 1/1 0, 0, 0, 48000, 12691, 0xf0adcc79 0, 48000, 48000, 48000, 4975, 0x1742a45f, F=0x0 0, 96000, 96000, 48000, 928, 0x7408be1a, F=0x0 diff --git a/tests/ref/fate/avid-interlaced b/tests/ref/fate/avid-interlaced new file mode 100644 index 000000000..2efa5839c --- /dev/null +++ b/tests/ref/fate/avid-interlaced @@ -0,0 +1,7 @@ +#tb 0: 100/2397 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 720x486 +#sar 0: 0/1 +0, 0, 0, 1, 699840, 0xc59a264e +0, 1, 1, 1, 699840, 0x06f13712 diff --git a/tests/ref/fate/avid-meridian b/tests/ref/fate/avid-meridian new file mode 100644 index 000000000..313351ed0 --- /dev/null +++ b/tests/ref/fate/avid-meridian @@ -0,0 +1,15 @@ +#tb 0: 20859/500000 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 0/1 +0, 0, 0, 1, 153600, 0xbfd35869 +0, 1, 1, 1, 153600, 0xbe7c74a0 +0, 2, 2, 1, 153600, 0x9f2524ee +0, 3, 3, 1, 153600, 0x3c8df375 +0, 4, 4, 1, 153600, 0xe0ac5d7d +0, 5, 5, 1, 153600, 0xf0c6da50 +0, 6, 6, 1, 153600, 0xbd50751f +0, 7, 7, 1, 153600, 0x51caf5f7 +0, 8, 8, 1, 153600, 0x27752d4f +0, 9, 9, 1, 153600, 0x63a0d0dc diff --git a/tests/ref/fate/cdxl-bitline-ham6 b/tests/ref/fate/cdxl-bitline-ham6 index 37c14596e..9d30e6621 100644 --- a/tests/ref/fate/cdxl-bitline-ham6 +++ b/tests/ref/fate/cdxl-bitline-ham6 @@ -1,4 +1,4 @@ -#tb 0: 1/50 +#tb 0: 1/15 #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 162x130 diff --git a/tests/ref/fate/cdxl-demux b/tests/ref/fate/cdxl-demux index f1334755a..324a40f2d 100644 --- a/tests/ref/fate/cdxl-demux +++ b/tests/ref/fate/cdxl-demux @@ -1,30 +1,30 @@ -#tb 0: 1/11025 +#tb 0: 628/3675 #media_type 0: video #codec_id 0: cdxl #dimensions 0: 176x128 #sar 0: 0/1 #tb 1: 1/11025 #media_type 1: audio -#codec_id 1: pcm_s8 +#codec_id 1: pcm_s8_planar #sample_rate 1: 11025 #channel_layout 1: 4 #channel_layout_name 1: mono -0, 0, 0, 1884, 22688, 0xc954a244 +0, 0, 0, 1, 22688, 0xc954a244 1, 0, 0, 1884, 1884, 0x06925e3e -0, 1884, 1884, 1884, 22688, 0x3ee4a304 +0, 1, 1, 1, 22688, 0x3ee4a304 1, 1884, 1884, 1884, 1884, 0x1957ab65 -0, 3768, 3768, 1884, 22688, 0x9777a305 +0, 2, 2, 1, 22688, 0x9777a305 1, 3768, 3768, 1884, 1884, 0x7fcd6e47 -0, 5652, 5652, 1884, 22688, 0xf00aa306 +0, 3, 3, 1, 22688, 0xf00aa306 1, 5652, 5652, 1884, 1884, 0xc974878e -0, 7536, 7536, 1884, 22688, 0x48aca307 +0, 4, 4, 1, 22688, 0x48aca307 1, 7536, 7536, 1884, 1884, 0xecb5c4c8 -0, 9420, 9420, 1884, 22688, 0xa13fa308 +0, 5, 5, 1, 22688, 0xa13fa308 1, 9420, 9420, 1884, 1884, 0x87adce5f -0, 11304, 11304, 1884, 22688, 0xf9d2a309 +0, 6, 6, 1, 22688, 0xf9d2a309 1, 11304, 11304, 1884, 1884, 0x3cf097e4 -0, 13188, 13188, 1884, 22688, 0x5274a30a +0, 7, 7, 1, 22688, 0x5274a30a 1, 13188, 13188, 1884, 1884, 0xcc218105 -0, 15072, 15072, 1884, 22688, 0xab07a30b +0, 8, 8, 1, 22688, 0xab07a30b 1, 15072, 15072, 1884, 1884, 0xf685762f -0, 16956, 16956, 1884, 17896, 0x1a696b6e +0, 9, 9, 1, 17896, 0x1a696b6e diff --git a/tests/ref/fate/cdxl-ham6 b/tests/ref/fate/cdxl-ham6 index 1602c8af3..4c2c14be4 100644 --- a/tests/ref/fate/cdxl-ham6 +++ b/tests/ref/fate/cdxl-ham6 @@ -1,4 +1,4 @@ -#tb 0: 52/525 +#tb 0: 12/121 #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 160x120 diff --git a/tests/ref/fate/cdxl-ham8 b/tests/ref/fate/cdxl-ham8 index ab1f76afa..cdd4f59d5 100644 --- a/tests/ref/fate/cdxl-ham8 +++ b/tests/ref/fate/cdxl-ham8 @@ -1,4 +1,4 @@ -#tb 0: 12/281 +#tb 0: 628/3675 #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 176x128 diff --git a/tests/ref/fate/cdxl-pal8 b/tests/ref/fate/cdxl-pal8 index a242b0ce6..71e44bf5d 100644 --- a/tests/ref/fate/cdxl-pal8 +++ b/tests/ref/fate/cdxl-pal8 @@ -1,4 +1,4 @@ -#tb 0: 1/50 +#tb 0: 1/15 #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 176x128 diff --git a/tests/ref/fate/cdxl-pal8-small b/tests/ref/fate/cdxl-pal8-small index 326eef776..34812382d 100644 --- a/tests/ref/fate/cdxl-pal8-small +++ b/tests/ref/fate/cdxl-pal8-small @@ -1,4 +1,4 @@ -#tb 0: 368/11025 +#tb 0: 1001/30000 #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 128x80 diff --git a/tests/ref/fate/cfhd-3 b/tests/ref/fate/cfhd-3 index 59fdc9226..79133a14b 100644 --- a/tests/ref/fate/cfhd-3 +++ b/tests/ref/fate/cfhd-3 @@ -3,13 +3,13 @@ #codec_id 0: rawvideo #dimensions 0: 496x241 #sar 0: 0/1 -0, 0, 0, 1, 478144, 0x48a01dbb -0, 1, 1, 1, 478144, 0x48a01dbb -0, 2, 2, 1, 478144, 0x48a01dbb -0, 3, 3, 1, 478144, 0xb978a72f -0, 4, 4, 1, 478144, 0x7bbb4679 -0, 5, 5, 1, 478144, 0xc3fd3f59 -0, 6, 6, 1, 478144, 0xfd2a4816 -0, 7, 7, 1, 478144, 0x207f65d3 -0, 8, 8, 1, 478144, 0x207f65d3 -0, 9, 9, 1, 478144, 0x207f65d3 +0, 0, 0, 1, 478144, 0x1e5a0d6c +0, 1, 1, 1, 478144, 0x1e5a0d6c +0, 2, 2, 1, 478144, 0x1e5a0d6c +0, 3, 3, 1, 478144, 0x88788c7d +0, 4, 4, 1, 478144, 0x78643db8 +0, 5, 5, 1, 478144, 0x84303909 +0, 6, 6, 1, 478144, 0x8ddd4828 +0, 7, 7, 1, 478144, 0xc0845d58 +0, 8, 8, 1, 478144, 0xc0845d58 +0, 9, 9, 1, 478144, 0xc0845d58 diff --git a/tests/ref/fate/concat-demuxer-extended-lavf-mxf b/tests/ref/fate/concat-demuxer-extended-lavf-mxf index e49915e40..87883217e 100644 --- a/tests/ref/fate/concat-demuxer-extended-lavf-mxf +++ b/tests/ref/fate/concat-demuxer-extended-lavf-mxf @@ -1 +1 @@ -861b9c23587d0a09caa78c3651faf5a0 *tests/data/fate/concat-demuxer-extended-lavf-mxf.ffprobe +c70ba87645ddecc8554036eb83a90e59 *tests/data/fate/concat-demuxer-extended-lavf-mxf.ffprobe diff --git a/tests/ref/fate/concat-demuxer-extended-lavf-mxf_d10 b/tests/ref/fate/concat-demuxer-extended-lavf-mxf_d10 index e3e76f217..2a5589012 100644 --- a/tests/ref/fate/concat-demuxer-extended-lavf-mxf_d10 +++ b/tests/ref/fate/concat-demuxer-extended-lavf-mxf_d10 @@ -1 +1 @@ -d66177ea3922692bc91cd0f8aa907650 *tests/data/fate/concat-demuxer-extended-lavf-mxf_d10.ffprobe +d17d5c3291b408d624205aca9e7ad6b4 *tests/data/fate/concat-demuxer-extended-lavf-mxf_d10.ffprobe diff --git a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf index a590f6f24..3e3e3a522 100644 --- a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf +++ b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf @@ -1,124 +1,124 @@ -video|0|0|0.000000|-1|-0.040000|1|0.040000|N/A|N/A|24801|7168|K_ -audio|1|0|0.000000|0|0.000000|1920|0.040000|N/A|N/A|3840|32256|K_ -video|0|3|0.120000|0|0.000000|1|0.040000|N/A|N/A|16743|36864|__ -audio|1|1920|0.040000|1920|0.040000|1920|0.040000|N/A|N/A|3840|53760|K_ -video|0|1|0.040000|1|0.040000|1|0.040000|N/A|N/A|13812|58368|__ -audio|1|3840|0.080000|3840|0.080000|1920|0.040000|N/A|N/A|3840|72704|K_ -video|0|2|0.080000|2|0.080000|1|0.040000|N/A|N/A|13607|77312|__ -audio|1|5760|0.120000|5760|0.120000|1920|0.040000|N/A|N/A|3840|91136|K_ -video|0|6|0.240000|3|0.120000|1|0.040000|N/A|N/A|16158|95744|__ -audio|1|7680|0.160000|7680|0.160000|1920|0.040000|N/A|N/A|3840|112128|K_ -video|0|4|0.160000|4|0.160000|1|0.040000|N/A|N/A|13943|116736|__ -audio|1|9600|0.200000|9600|0.200000|1920|0.040000|N/A|N/A|3840|131072|K_ -video|0|5|0.200000|5|0.200000|1|0.040000|N/A|N/A|11223|135680|__ -audio|1|11520|0.240000|11520|0.240000|1920|0.040000|N/A|N/A|3840|146944|K_ -video|0|9|0.360000|6|0.240000|1|0.040000|N/A|N/A|20298|151552|__ -audio|1|13440|0.280000|13440|0.280000|1920|0.040000|N/A|N/A|3840|172032|K_ -video|0|7|0.280000|7|0.280000|1|0.040000|N/A|N/A|13341|176640|__ -audio|1|15360|0.320000|15360|0.320000|1920|0.040000|N/A|N/A|3840|190464|K_ -video|0|8|0.320000|8|0.320000|1|0.040000|N/A|N/A|12362|195072|__ -audio|1|17280|0.360000|17280|0.360000|1920|0.040000|N/A|N/A|3840|207872|K_ -video|0|12|0.480000|9|0.360000|1|0.040000|N/A|N/A|24786|212480|K_ -audio|1|19200|0.400000|19200|0.400000|1920|0.040000|N/A|N/A|3840|237568|K_ -video|0|10|0.400000|10|0.400000|1|0.040000|N/A|N/A|13377|242176|__ -audio|1|21120|0.440000|21120|0.440000|1920|0.040000|N/A|N/A|3840|256000|K_ -video|0|11|0.440000|11|0.440000|1|0.040000|N/A|N/A|15624|260608|__ -audio|1|23040|0.480000|23040|0.480000|1920|0.040000|N/A|N/A|3840|276480|K_ -video|0|15|0.600000|12|0.480000|1|0.040000|N/A|N/A|22597|281088|__ -audio|1|24960|0.520000|24960|0.520000|1920|0.040000|N/A|N/A|3840|304128|K_ -video|0|13|0.520000|13|0.520000|1|0.040000|N/A|N/A|15028|308736|__ -audio|1|26880|0.560000|26880|0.560000|1920|0.040000|N/A|N/A|3840|324096|K_ -video|0|14|0.560000|14|0.560000|1|0.040000|N/A|N/A|14014|328704|__ -audio|1|28800|0.600000|28800|0.600000|1920|0.040000|N/A|N/A|3840|343040|K_ -video|0|18|0.720000|15|0.600000|1|0.040000|N/A|N/A|20731|347648|__ -audio|1|30720|0.640000|30720|0.640000|1920|0.040000|N/A|N/A|3840|368640|K_ -video|0|16|0.640000|16|0.640000|1|0.040000|N/A|N/A|11946|373248|__ -audio|1|32640|0.680000|32640|0.680000|1920|0.040000|N/A|N/A|3840|385536|K_ -video|0|17|0.680000|17|0.680000|1|0.040000|N/A|N/A|14464|390144|__ -audio|1|34560|0.720000|34560|0.720000|1920|0.040000|N/A|N/A|3840|404992|K_ -video|0|21|0.840000|18|0.720000|1|0.040000|N/A|N/A|16189|409600|__ -audio|1|36480|0.760000|36480|0.760000|1920|0.040000|N/A|N/A|3840|425984|K_ -video|0|19|0.760000|19|0.760000|1|0.040000|N/A|N/A|10524|430592|__ -audio|1|38400|0.800000|38400|0.800000|1920|0.040000|N/A|N/A|3840|441344|K_ -video|0|20|0.800000|20|0.800000|1|0.040000|N/A|N/A|10599|445952|__ -audio|1|40320|0.840000|40320|0.840000|1920|0.040000|N/A|N/A|3840|456704|K_ -video|0|24|0.960000|21|0.840000|1|0.040000|N/A|N/A|24711|461312|K_ -audio|1|42240|0.880000|42240|0.880000|1920|0.040000|N/A|N/A|3840|486400|K_ -video|0|22|0.880000|22|0.880000|1|0.040000|N/A|N/A|10840|491008|__ -audio|1|44160|0.920000|44160|0.920000|1920|0.040000|N/A|N/A|3840|502272|K_ -video|0|23|0.920000|23|0.920000|1|0.040000|N/A|N/A|13350|506880|__ -audio|1|46080|0.960000|46080|0.960000|1920|0.040000|N/A|N/A|3840|520704|K_ -video|0|17|0.680000|14|0.560000|1|0.040000|N/A|N/A|24786|212480|K_ -audio|1|28800|0.600000|28800|0.600000|1920|0.040000|N/A|N/A|3840|237568|K_ -video|0|15|0.600000|15|0.600000|1|0.040000|N/A|N/A|13377|242176|__ -audio|1|30720|0.640000|30720|0.640000|1920|0.040000|N/A|N/A|3840|256000|K_ -video|0|16|0.640000|16|0.640000|1|0.040000|N/A|N/A|15624|260608|__ -audio|1|32640|0.680000|32640|0.680000|1920|0.040000|N/A|N/A|3840|276480|K_ -video|0|20|0.800000|17|0.680000|1|0.040000|N/A|N/A|22597|281088|__ -audio|1|34560|0.720000|34560|0.720000|1920|0.040000|N/A|N/A|3840|304128|K_ -video|0|18|0.720000|18|0.720000|1|0.040000|N/A|N/A|15028|308736|__ -audio|1|36480|0.760000|36480|0.760000|1920|0.040000|N/A|N/A|3840|324096|K_ -video|0|19|0.760000|19|0.760000|1|0.040000|N/A|N/A|14014|328704|__ -audio|1|38400|0.800000|38400|0.800000|1920|0.040000|N/A|N/A|3840|343040|K_ -video|0|23|0.920000|20|0.800000|1|0.040000|N/A|N/A|20731|347648|__ -audio|1|40320|0.840000|40320|0.840000|1920|0.040000|N/A|N/A|3840|368640|K_ -video|0|21|0.840000|21|0.840000|1|0.040000|N/A|N/A|11946|373248|__ -audio|1|42240|0.880000|42240|0.880000|1920|0.040000|N/A|N/A|3840|385536|K_ -video|0|22|0.880000|22|0.880000|1|0.040000|N/A|N/A|14464|390144|__ -audio|1|44160|0.920000|44160|0.920000|1920|0.040000|N/A|N/A|3840|404992|K_ -video|0|26|1.040000|23|0.920000|1|0.040000|N/A|N/A|16189|409600|__ -audio|1|46080|0.960000|46080|0.960000|1920|0.040000|N/A|N/A|3840|425984|K_ -video|0|24|0.960000|24|0.960000|1|0.040000|N/A|N/A|10524|430592|__ -audio|1|48000|1.000000|48000|1.000000|1920|0.040000|N/A|N/A|3840|441344|K_ -video|0|25|1.000000|25|1.000000|1|0.040000|N/A|N/A|10599|445952|__ -audio|1|49920|1.040000|49920|1.040000|1920|0.040000|N/A|N/A|3840|456704|K_ -video|0|29|1.160000|26|1.040000|1|0.040000|N/A|N/A|24711|461312|K_ -audio|1|51840|1.080000|51840|1.080000|1920|0.040000|N/A|N/A|3840|486400|K_ -video|0|27|1.080000|27|1.080000|1|0.040000|N/A|N/A|10840|491008|__ -audio|1|53760|1.120000|53760|1.120000|1920|0.040000|N/A|N/A|3840|502272|K_ -video|0|28|1.120000|28|1.120000|1|0.040000|N/A|N/A|13350|506880|__ -audio|1|55680|1.160000|55680|1.160000|1920|0.040000|N/A|N/A|3840|520704|K_ -video|0|25|1.000000|24|0.960000|1|0.040000|N/A|N/A|24801|7168|K_|1 +video|0|0|0.000000|-1|-0.040000|1|0.040000|24801|7168|K_ +audio|1|0|0.000000|0|0.000000|1920|0.040000|3840|32256|K_ +video|0|3|0.120000|0|0.000000|1|0.040000|16743|36864|__ +audio|1|1920|0.040000|1920|0.040000|1920|0.040000|3840|53760|K_ +video|0|1|0.040000|1|0.040000|1|0.040000|13812|58368|__ +audio|1|3840|0.080000|3840|0.080000|1920|0.040000|3840|72704|K_ +video|0|2|0.080000|2|0.080000|1|0.040000|13607|77312|__ +audio|1|5760|0.120000|5760|0.120000|1920|0.040000|3840|91136|K_ +video|0|6|0.240000|3|0.120000|1|0.040000|16158|95744|__ +audio|1|7680|0.160000|7680|0.160000|1920|0.040000|3840|112128|K_ +video|0|4|0.160000|4|0.160000|1|0.040000|13943|116736|__ +audio|1|9600|0.200000|9600|0.200000|1920|0.040000|3840|131072|K_ +video|0|5|0.200000|5|0.200000|1|0.040000|11223|135680|__ +audio|1|11520|0.240000|11520|0.240000|1920|0.040000|3840|146944|K_ +video|0|9|0.360000|6|0.240000|1|0.040000|20298|151552|__ +audio|1|13440|0.280000|13440|0.280000|1920|0.040000|3840|172032|K_ +video|0|7|0.280000|7|0.280000|1|0.040000|13341|176640|__ +audio|1|15360|0.320000|15360|0.320000|1920|0.040000|3840|190464|K_ +video|0|8|0.320000|8|0.320000|1|0.040000|12362|195072|__ +audio|1|17280|0.360000|17280|0.360000|1920|0.040000|3840|207872|K_ +video|0|12|0.480000|9|0.360000|1|0.040000|24786|212480|K_ +audio|1|19200|0.400000|19200|0.400000|1920|0.040000|3840|237568|K_ +video|0|10|0.400000|10|0.400000|1|0.040000|13377|242176|__ +audio|1|21120|0.440000|21120|0.440000|1920|0.040000|3840|256000|K_ +video|0|11|0.440000|11|0.440000|1|0.040000|15624|260608|__ +audio|1|23040|0.480000|23040|0.480000|1920|0.040000|3840|276480|K_ +video|0|15|0.600000|12|0.480000|1|0.040000|22597|281088|__ +audio|1|24960|0.520000|24960|0.520000|1920|0.040000|3840|304128|K_ +video|0|13|0.520000|13|0.520000|1|0.040000|15028|308736|__ +audio|1|26880|0.560000|26880|0.560000|1920|0.040000|3840|324096|K_ +video|0|14|0.560000|14|0.560000|1|0.040000|14014|328704|__ +audio|1|28800|0.600000|28800|0.600000|1920|0.040000|3840|343040|K_ +video|0|18|0.720000|15|0.600000|1|0.040000|20731|347648|__ +audio|1|30720|0.640000|30720|0.640000|1920|0.040000|3840|368640|K_ +video|0|16|0.640000|16|0.640000|1|0.040000|11946|373248|__ +audio|1|32640|0.680000|32640|0.680000|1920|0.040000|3840|385536|K_ +video|0|17|0.680000|17|0.680000|1|0.040000|14464|390144|__ +audio|1|34560|0.720000|34560|0.720000|1920|0.040000|3840|404992|K_ +video|0|21|0.840000|18|0.720000|1|0.040000|16189|409600|__ +audio|1|36480|0.760000|36480|0.760000|1920|0.040000|3840|425984|K_ +video|0|19|0.760000|19|0.760000|1|0.040000|10524|430592|__ +audio|1|38400|0.800000|38400|0.800000|1920|0.040000|3840|441344|K_ +video|0|20|0.800000|20|0.800000|1|0.040000|10599|445952|__ +audio|1|40320|0.840000|40320|0.840000|1920|0.040000|3840|456704|K_ +video|0|24|0.960000|21|0.840000|1|0.040000|24711|461312|K_ +audio|1|42240|0.880000|42240|0.880000|1920|0.040000|3840|486400|K_ +video|0|22|0.880000|22|0.880000|1|0.040000|10840|491008|__ +audio|1|44160|0.920000|44160|0.920000|1920|0.040000|3840|502272|K_ +video|0|23|0.920000|23|0.920000|1|0.040000|13350|506880|__ +audio|1|46080|0.960000|46080|0.960000|1920|0.040000|3840|520704|K_ +video|0|17|0.680000|14|0.560000|1|0.040000|24786|212480|K_ +audio|1|28800|0.600000|28800|0.600000|1920|0.040000|3840|237568|K_ +video|0|15|0.600000|15|0.600000|1|0.040000|13377|242176|__ +audio|1|30720|0.640000|30720|0.640000|1920|0.040000|3840|256000|K_ +video|0|16|0.640000|16|0.640000|1|0.040000|15624|260608|__ +audio|1|32640|0.680000|32640|0.680000|1920|0.040000|3840|276480|K_ +video|0|20|0.800000|17|0.680000|1|0.040000|22597|281088|__ +audio|1|34560|0.720000|34560|0.720000|1920|0.040000|3840|304128|K_ +video|0|18|0.720000|18|0.720000|1|0.040000|15028|308736|__ +audio|1|36480|0.760000|36480|0.760000|1920|0.040000|3840|324096|K_ +video|0|19|0.760000|19|0.760000|1|0.040000|14014|328704|__ +audio|1|38400|0.800000|38400|0.800000|1920|0.040000|3840|343040|K_ +video|0|23|0.920000|20|0.800000|1|0.040000|20731|347648|__ +audio|1|40320|0.840000|40320|0.840000|1920|0.040000|3840|368640|K_ +video|0|21|0.840000|21|0.840000|1|0.040000|11946|373248|__ +audio|1|42240|0.880000|42240|0.880000|1920|0.040000|3840|385536|K_ +video|0|22|0.880000|22|0.880000|1|0.040000|14464|390144|__ +audio|1|44160|0.920000|44160|0.920000|1920|0.040000|3840|404992|K_ +video|0|26|1.040000|23|0.920000|1|0.040000|16189|409600|__ +audio|1|46080|0.960000|46080|0.960000|1920|0.040000|3840|425984|K_ +video|0|24|0.960000|24|0.960000|1|0.040000|10524|430592|__ +audio|1|48000|1.000000|48000|1.000000|1920|0.040000|3840|441344|K_ +video|0|25|1.000000|25|1.000000|1|0.040000|10599|445952|__ +audio|1|49920|1.040000|49920|1.040000|1920|0.040000|3840|456704|K_ +video|0|29|1.160000|26|1.040000|1|0.040000|24711|461312|K_ +audio|1|51840|1.080000|51840|1.080000|1920|0.040000|3840|486400|K_ +video|0|27|1.080000|27|1.080000|1|0.040000|10840|491008|__ +audio|1|53760|1.120000|53760|1.120000|1920|0.040000|3840|502272|K_ +video|0|28|1.120000|28|1.120000|1|0.040000|13350|506880|__ +audio|1|55680|1.160000|55680|1.160000|1920|0.040000|3840|520704|K_ +video|0|25|1.000000|24|0.960000|1|0.040000|24801|7168|K_|1 Strings Metadata -audio|1|48000|1.000000|48000|1.000000|1920|0.040000|N/A|N/A|3840|32256|K_|1 +audio|1|48000|1.000000|48000|1.000000|1920|0.040000|3840|32256|K_|1 Strings Metadata -video|0|28|1.120000|25|1.000000|1|0.040000|N/A|N/A|16743|36864|__|1 +video|0|28|1.120000|25|1.000000|1|0.040000|16743|36864|__|1 Strings Metadata -audio|1|49920|1.040000|49920|1.040000|1920|0.040000|N/A|N/A|3840|53760|K_|1 +audio|1|49920|1.040000|49920|1.040000|1920|0.040000|3840|53760|K_|1 Strings Metadata -video|0|26|1.040000|26|1.040000|1|0.040000|N/A|N/A|13812|58368|__|1 +video|0|26|1.040000|26|1.040000|1|0.040000|13812|58368|__|1 Strings Metadata -audio|1|51840|1.080000|51840|1.080000|1920|0.040000|N/A|N/A|3840|72704|K_|1 +audio|1|51840|1.080000|51840|1.080000|1920|0.040000|3840|72704|K_|1 Strings Metadata -video|0|27|1.080000|27|1.080000|1|0.040000|N/A|N/A|13607|77312|__|1 +video|0|27|1.080000|27|1.080000|1|0.040000|13607|77312|__|1 Strings Metadata -audio|1|53760|1.120000|53760|1.120000|1920|0.040000|N/A|N/A|3840|91136|K_|1 +audio|1|53760|1.120000|53760|1.120000|1920|0.040000|3840|91136|K_|1 Strings Metadata -video|0|31|1.240000|28|1.120000|1|0.040000|N/A|N/A|16158|95744|__|1 +video|0|31|1.240000|28|1.120000|1|0.040000|16158|95744|__|1 Strings Metadata -audio|1|55680|1.160000|55680|1.160000|1920|0.040000|N/A|N/A|3840|112128|K_|1 +audio|1|55680|1.160000|55680|1.160000|1920|0.040000|3840|112128|K_|1 Strings Metadata -video|0|29|1.160000|29|1.160000|1|0.040000|N/A|N/A|13943|116736|__|1 +video|0|29|1.160000|29|1.160000|1|0.040000|13943|116736|__|1 Strings Metadata -audio|1|57600|1.200000|57600|1.200000|1920|0.040000|N/A|N/A|3840|131072|K_|1 +audio|1|57600|1.200000|57600|1.200000|1920|0.040000|3840|131072|K_|1 Strings Metadata -video|0|30|1.200000|30|1.200000|1|0.040000|N/A|N/A|11223|135680|__|1 +video|0|30|1.200000|30|1.200000|1|0.040000|11223|135680|__|1 Strings Metadata -audio|1|59520|1.240000|59520|1.240000|1920|0.040000|N/A|N/A|3840|146944|K_|1 +audio|1|59520|1.240000|59520|1.240000|1920|0.040000|3840|146944|K_|1 Strings Metadata -video|0|34|1.360000|31|1.240000|1|0.040000|N/A|N/A|20298|151552|__|1 +video|0|34|1.360000|31|1.240000|1|0.040000|20298|151552|__|1 Strings Metadata -audio|1|61440|1.280000|61440|1.280000|1920|0.040000|N/A|N/A|3840|172032|K_|1 +audio|1|61440|1.280000|61440|1.280000|1920|0.040000|3840|172032|K_|1 Strings Metadata -video|0|32|1.280000|32|1.280000|1|0.040000|N/A|N/A|13341|176640|__|1 +video|0|32|1.280000|32|1.280000|1|0.040000|13341|176640|__|1 Strings Metadata -audio|1|63360|1.320000|63360|1.320000|1920|0.040000|N/A|N/A|3840|190464|K_|1 +audio|1|63360|1.320000|63360|1.320000|1920|0.040000|3840|190464|K_|1 Strings Metadata -video|0|33|1.320000|33|1.320000|1|0.040000|N/A|N/A|12362|195072|__|1 +video|0|33|1.320000|33|1.320000|1|0.040000|12362|195072|__|1 Strings Metadata -audio|1|65280|1.360000|65280|1.360000|1920|0.040000|N/A|N/A|3840|207872|K_|1 +audio|1|65280|1.360000|65280|1.360000|1920|0.040000|3840|207872|K_|1 Strings Metadata -video|0|37|1.480000|34|1.360000|1|0.040000|N/A|N/A|24786|212480|K_|1 +video|0|37|1.480000|34|1.360000|1|0.040000|24786|212480|K_|1 Strings Metadata -0|mpeg2video|4|video|1/25|[0][0][0][0]|0x0000|352|288|0|0|0|1|1:1|11:9|yuv420p|8|tv|unknown|unknown|unknown|left|progressive|N/A|1|N/A|25/1|25/1|1/25|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|51|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 -1|pcm_s16le|unknown|audio|1/48000|[0][0][0][0]|0x0000|s16|48000|1|unknown|16|N/A|0/0|0/0|1/48000|0|0.000000|N/A|N/A|768000|N/A|N/A|N/A|N/A|50|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 +0|mpeg2video|4|video|[0][0][0][0]|0x0000|352|288|0|0|0|1|1:1|11:9|yuv420p|8|tv|unknown|unknown|unknown|left|progressive|1|N/A|25/1|25/1|1/25|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|51|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 +1|pcm_s16le|unknown|audio|[0][0][0][0]|0x0000|s16|48000|1|unknown|16|N/A|0/0|0/0|1/48000|0|0.000000|N/A|N/A|768000|N/A|N/A|N/A|N/A|50|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 diff --git a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf_d10 b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf_d10 index 79ce1e230..f329bba67 100644 --- a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf_d10 +++ b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf_d10 @@ -1,82 +1,82 @@ -video|0|0|0.000000|0|0.000000|1|0.040000|N/A|N/A|150000|7168|K_ -audio|1|0|0.000000|0|0.000000|1920|0.040000|N/A|N/A|7680|157696|K_ -video|0|1|0.040000|1|0.040000|1|0.040000|N/A|N/A|150000|220160|K_ -audio|1|1920|0.040000|1920|0.040000|1920|0.040000|N/A|N/A|7680|370688|K_ -video|0|2|0.080000|2|0.080000|1|0.040000|N/A|N/A|150000|433152|K_ -audio|1|3840|0.080000|3840|0.080000|1920|0.040000|N/A|N/A|7680|583680|K_ -video|0|3|0.120000|3|0.120000|1|0.040000|N/A|N/A|150000|646144|K_ -audio|1|5760|0.120000|5760|0.120000|1920|0.040000|N/A|N/A|7680|796672|K_ -video|0|4|0.160000|4|0.160000|1|0.040000|N/A|N/A|150000|859136|K_ -audio|1|7680|0.160000|7680|0.160000|1920|0.040000|N/A|N/A|7680|1009664|K_ -video|0|5|0.200000|5|0.200000|1|0.040000|N/A|N/A|150000|1072128|K_ -audio|1|9600|0.200000|9600|0.200000|1920|0.040000|N/A|N/A|7680|1222656|K_ -video|0|6|0.240000|6|0.240000|1|0.040000|N/A|N/A|150000|1285120|K_ -audio|1|11520|0.240000|11520|0.240000|1920|0.040000|N/A|N/A|7680|1435648|K_ -video|0|7|0.280000|7|0.280000|1|0.040000|N/A|N/A|150000|1498112|K_ -audio|1|13440|0.280000|13440|0.280000|1920|0.040000|N/A|N/A|7680|1648640|K_ -video|0|8|0.320000|8|0.320000|1|0.040000|N/A|N/A|150000|1711104|K_ -audio|1|15360|0.320000|15360|0.320000|1920|0.040000|N/A|N/A|7680|1861632|K_ -video|0|9|0.360000|9|0.360000|1|0.040000|N/A|N/A|150000|1924096|K_ -audio|1|17280|0.360000|17280|0.360000|1920|0.040000|N/A|N/A|7680|2074624|K_ -video|0|10|0.400000|10|0.400000|1|0.040000|N/A|N/A|150000|2137088|K_ -audio|1|19200|0.400000|19200|0.400000|1920|0.040000|N/A|N/A|7680|2287616|K_ -video|0|11|0.440000|11|0.440000|1|0.040000|N/A|N/A|150000|2350080|K_ -audio|1|21120|0.440000|21120|0.440000|1920|0.040000|N/A|N/A|7680|2500608|K_ -video|0|12|0.480000|12|0.480000|1|0.040000|N/A|N/A|150000|2563072|K_ -audio|1|23040|0.480000|23040|0.480000|1920|0.040000|N/A|N/A|7680|2713600|K_ -video|0|13|0.520000|13|0.520000|1|0.040000|N/A|N/A|150000|2776064|K_ -audio|1|24960|0.520000|24960|0.520000|1920|0.040000|N/A|N/A|7680|2926592|K_ -video|0|14|0.560000|14|0.560000|1|0.040000|N/A|N/A|150000|2989056|K_ -audio|1|26880|0.560000|26880|0.560000|1920|0.040000|N/A|N/A|7680|3139584|K_ -video|0|15|0.600000|15|0.600000|1|0.040000|N/A|N/A|150000|3202048|K_ -audio|1|28800|0.600000|28800|0.600000|1920|0.040000|N/A|N/A|7680|3352576|K_ -video|0|16|0.640000|16|0.640000|1|0.040000|N/A|N/A|150000|3415040|K_ -audio|1|30720|0.640000|30720|0.640000|1920|0.040000|N/A|N/A|7680|3565568|K_ -video|0|17|0.680000|17|0.680000|1|0.040000|N/A|N/A|150000|3628032|K_ -audio|1|32640|0.680000|32640|0.680000|1920|0.040000|N/A|N/A|7680|3778560|K_ -video|0|18|0.720000|18|0.720000|1|0.040000|N/A|N/A|150000|3841024|K_ -audio|1|34560|0.720000|34560|0.720000|1920|0.040000|N/A|N/A|7680|3991552|K_ -video|0|19|0.760000|19|0.760000|1|0.040000|N/A|N/A|150000|4054016|K_ -audio|1|36480|0.760000|36480|0.760000|1920|0.040000|N/A|N/A|7680|4204544|K_ -video|0|20|0.800000|20|0.800000|1|0.040000|N/A|N/A|150000|4267008|K_ -audio|1|38400|0.800000|38400|0.800000|1920|0.040000|N/A|N/A|7680|4417536|K_ -video|0|21|0.840000|21|0.840000|1|0.040000|N/A|N/A|150000|4480000|K_ -audio|1|40320|0.840000|40320|0.840000|1920|0.040000|N/A|N/A|7680|4630528|K_ -video|0|22|0.880000|22|0.880000|1|0.040000|N/A|N/A|150000|4692992|K_ -audio|1|42240|0.880000|42240|0.880000|1920|0.040000|N/A|N/A|7680|4843520|K_ -video|0|23|0.920000|23|0.920000|1|0.040000|N/A|N/A|150000|4905984|K_ -audio|1|44160|0.920000|44160|0.920000|1920|0.040000|N/A|N/A|7680|5056512|K_ -video|0|24|0.960000|24|0.960000|1|0.040000|N/A|N/A|150000|5118976|K_ -audio|1|46080|0.960000|46080|0.960000|1920|0.040000|N/A|N/A|7680|5269504|K_ -video|0|25|1.000000|25|1.000000|1|0.040000|N/A|N/A|150000|4267008|K_ -audio|1|48000|1.000000|48000|1.000000|1920|0.040000|N/A|N/A|7680|4417536|K_ -video|0|26|1.040000|26|1.040000|1|0.040000|N/A|N/A|150000|4480000|K_ -audio|1|49920|1.040000|49920|1.040000|1920|0.040000|N/A|N/A|7680|4630528|K_ -video|0|27|1.080000|27|1.080000|1|0.040000|N/A|N/A|150000|4692992|K_ -audio|1|51840|1.080000|51840|1.080000|1920|0.040000|N/A|N/A|7680|4843520|K_ -video|0|28|1.120000|28|1.120000|1|0.040000|N/A|N/A|150000|4905984|K_ -audio|1|53760|1.120000|53760|1.120000|1920|0.040000|N/A|N/A|7680|5056512|K_ -video|0|29|1.160000|29|1.160000|1|0.040000|N/A|N/A|150000|5118976|K_ -audio|1|55680|1.160000|55680|1.160000|1920|0.040000|N/A|N/A|7680|5269504|K_ -video|0|30|1.200000|30|1.200000|1|0.040000|N/A|N/A|150000|1072128|K_|1 +video|0|0|0.000000|0|0.000000|1|0.040000|150000|7168|K_ +audio|1|0|0.000000|0|0.000000|1920|0.040000|7680|157696|K_ +video|0|1|0.040000|1|0.040000|1|0.040000|150000|220160|K_ +audio|1|1920|0.040000|1920|0.040000|1920|0.040000|7680|370688|K_ +video|0|2|0.080000|2|0.080000|1|0.040000|150000|433152|K_ +audio|1|3840|0.080000|3840|0.080000|1920|0.040000|7680|583680|K_ +video|0|3|0.120000|3|0.120000|1|0.040000|150000|646144|K_ +audio|1|5760|0.120000|5760|0.120000|1920|0.040000|7680|796672|K_ +video|0|4|0.160000|4|0.160000|1|0.040000|150000|859136|K_ +audio|1|7680|0.160000|7680|0.160000|1920|0.040000|7680|1009664|K_ +video|0|5|0.200000|5|0.200000|1|0.040000|150000|1072128|K_ +audio|1|9600|0.200000|9600|0.200000|1920|0.040000|7680|1222656|K_ +video|0|6|0.240000|6|0.240000|1|0.040000|150000|1285120|K_ +audio|1|11520|0.240000|11520|0.240000|1920|0.040000|7680|1435648|K_ +video|0|7|0.280000|7|0.280000|1|0.040000|150000|1498112|K_ +audio|1|13440|0.280000|13440|0.280000|1920|0.040000|7680|1648640|K_ +video|0|8|0.320000|8|0.320000|1|0.040000|150000|1711104|K_ +audio|1|15360|0.320000|15360|0.320000|1920|0.040000|7680|1861632|K_ +video|0|9|0.360000|9|0.360000|1|0.040000|150000|1924096|K_ +audio|1|17280|0.360000|17280|0.360000|1920|0.040000|7680|2074624|K_ +video|0|10|0.400000|10|0.400000|1|0.040000|150000|2137088|K_ +audio|1|19200|0.400000|19200|0.400000|1920|0.040000|7680|2287616|K_ +video|0|11|0.440000|11|0.440000|1|0.040000|150000|2350080|K_ +audio|1|21120|0.440000|21120|0.440000|1920|0.040000|7680|2500608|K_ +video|0|12|0.480000|12|0.480000|1|0.040000|150000|2563072|K_ +audio|1|23040|0.480000|23040|0.480000|1920|0.040000|7680|2713600|K_ +video|0|13|0.520000|13|0.520000|1|0.040000|150000|2776064|K_ +audio|1|24960|0.520000|24960|0.520000|1920|0.040000|7680|2926592|K_ +video|0|14|0.560000|14|0.560000|1|0.040000|150000|2989056|K_ +audio|1|26880|0.560000|26880|0.560000|1920|0.040000|7680|3139584|K_ +video|0|15|0.600000|15|0.600000|1|0.040000|150000|3202048|K_ +audio|1|28800|0.600000|28800|0.600000|1920|0.040000|7680|3352576|K_ +video|0|16|0.640000|16|0.640000|1|0.040000|150000|3415040|K_ +audio|1|30720|0.640000|30720|0.640000|1920|0.040000|7680|3565568|K_ +video|0|17|0.680000|17|0.680000|1|0.040000|150000|3628032|K_ +audio|1|32640|0.680000|32640|0.680000|1920|0.040000|7680|3778560|K_ +video|0|18|0.720000|18|0.720000|1|0.040000|150000|3841024|K_ +audio|1|34560|0.720000|34560|0.720000|1920|0.040000|7680|3991552|K_ +video|0|19|0.760000|19|0.760000|1|0.040000|150000|4054016|K_ +audio|1|36480|0.760000|36480|0.760000|1920|0.040000|7680|4204544|K_ +video|0|20|0.800000|20|0.800000|1|0.040000|150000|4267008|K_ +audio|1|38400|0.800000|38400|0.800000|1920|0.040000|7680|4417536|K_ +video|0|21|0.840000|21|0.840000|1|0.040000|150000|4480000|K_ +audio|1|40320|0.840000|40320|0.840000|1920|0.040000|7680|4630528|K_ +video|0|22|0.880000|22|0.880000|1|0.040000|150000|4692992|K_ +audio|1|42240|0.880000|42240|0.880000|1920|0.040000|7680|4843520|K_ +video|0|23|0.920000|23|0.920000|1|0.040000|150000|4905984|K_ +audio|1|44160|0.920000|44160|0.920000|1920|0.040000|7680|5056512|K_ +video|0|24|0.960000|24|0.960000|1|0.040000|150000|5118976|K_ +audio|1|46080|0.960000|46080|0.960000|1920|0.040000|7680|5269504|K_ +video|0|25|1.000000|25|1.000000|1|0.040000|150000|4267008|K_ +audio|1|48000|1.000000|48000|1.000000|1920|0.040000|7680|4417536|K_ +video|0|26|1.040000|26|1.040000|1|0.040000|150000|4480000|K_ +audio|1|49920|1.040000|49920|1.040000|1920|0.040000|7680|4630528|K_ +video|0|27|1.080000|27|1.080000|1|0.040000|150000|4692992|K_ +audio|1|51840|1.080000|51840|1.080000|1920|0.040000|7680|4843520|K_ +video|0|28|1.120000|28|1.120000|1|0.040000|150000|4905984|K_ +audio|1|53760|1.120000|53760|1.120000|1920|0.040000|7680|5056512|K_ +video|0|29|1.160000|29|1.160000|1|0.040000|150000|5118976|K_ +audio|1|55680|1.160000|55680|1.160000|1920|0.040000|7680|5269504|K_ +video|0|30|1.200000|30|1.200000|1|0.040000|150000|1072128|K_|1 Strings Metadata -audio|1|57600|1.200000|57600|1.200000|1920|0.040000|N/A|N/A|7680|1222656|K_|1 +audio|1|57600|1.200000|57600|1.200000|1920|0.040000|7680|1222656|K_|1 Strings Metadata -video|0|31|1.240000|31|1.240000|1|0.040000|N/A|N/A|150000|1285120|K_|1 +video|0|31|1.240000|31|1.240000|1|0.040000|150000|1285120|K_|1 Strings Metadata -audio|1|59520|1.240000|59520|1.240000|1920|0.040000|N/A|N/A|7680|1435648|K_|1 +audio|1|59520|1.240000|59520|1.240000|1920|0.040000|7680|1435648|K_|1 Strings Metadata -video|0|32|1.280000|32|1.280000|1|0.040000|N/A|N/A|150000|1498112|K_|1 +video|0|32|1.280000|32|1.280000|1|0.040000|150000|1498112|K_|1 Strings Metadata -audio|1|61440|1.280000|61440|1.280000|1920|0.040000|N/A|N/A|7680|1648640|K_|1 +audio|1|61440|1.280000|61440|1.280000|1920|0.040000|7680|1648640|K_|1 Strings Metadata -video|0|33|1.320000|33|1.320000|1|0.040000|N/A|N/A|150000|1711104|K_|1 +video|0|33|1.320000|33|1.320000|1|0.040000|150000|1711104|K_|1 Strings Metadata -audio|1|63360|1.320000|63360|1.320000|1920|0.040000|N/A|N/A|7680|1861632|K_|1 +audio|1|63360|1.320000|63360|1.320000|1920|0.040000|7680|1861632|K_|1 Strings Metadata -video|0|34|1.360000|34|1.360000|1|0.040000|N/A|N/A|150000|1924096|K_|1 +video|0|34|1.360000|34|1.360000|1|0.040000|150000|1924096|K_|1 Strings Metadata -audio|1|65280|1.360000|65280|1.360000|1920|0.040000|N/A|N/A|7680|2074624|K_|1 +audio|1|65280|1.360000|65280|1.360000|1920|0.040000|7680|2074624|K_|1 Strings Metadata -0|mpeg2video|0|video|1/25|[0][0][0][0]|0x0000|720|608|0|0|0|0|1:1|45:38|yuv422p|5|tv|unknown|unknown|unknown|topleft|tt|N/A|1|N/A|25/1|25/1|1/25|0|0.000000|N/A|N/A|30000000|N/A|N/A|N/A|N/A|35|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 -1|pcm_s16le|unknown|audio|1/48000|[0][0][0][0]|0x0000|s16|48000|2|unknown|16|N/A|0/0|0/0|1/48000|0|0.000000|N/A|N/A|1536000|N/A|N/A|N/A|N/A|35|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 +0|mpeg2video|0|video|[0][0][0][0]|0x0000|720|608|0|0|0|0|1:1|45:38|yuv422p|5|tv|unknown|unknown|unknown|topleft|tb|1|N/A|25/1|25/1|1/25|0|0.000000|N/A|N/A|30000000|N/A|N/A|N/A|N/A|35|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 +1|pcm_s16le|unknown|audio|[0][0][0][0]|0x0000|s16|48000|2|unknown|16|N/A|0/0|0/0|1/48000|0|0.000000|N/A|N/A|1536000|N/A|N/A|N/A|N/A|35|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 diff --git a/tests/ref/fate/concat-demuxer-simple2-lavf-ts b/tests/ref/fate/concat-demuxer-simple2-lavf-ts index a364b761d..e99a9aa74 100644 --- a/tests/ref/fate/concat-demuxer-simple2-lavf-ts +++ b/tests/ref/fate/concat-demuxer-simple2-lavf-ts @@ -1,215 +1,215 @@ -video|1|982|0.010911|-2618|-0.029089|3600|0.040000|N/A|N/A|24801|564|K_MPEGTS Stream ID +video|1|982|0.010911|-2618|-0.029089|3600|0.040000|24801|564|K_MPEGTS Stream ID -video|1|4582|0.050911|982|0.010911|3600|0.040000|N/A|N/A|16429|25944|__MPEGTS Stream ID +video|1|4582|0.050911|982|0.010911|3600|0.040000|16429|25944|__MPEGTS Stream ID -video|1|8182|0.090911|4582|0.050911|3600|0.040000|N/A|N/A|14508|42864|__MPEGTS Stream ID +video|1|8182|0.090911|4582|0.050911|3600|0.040000|14508|42864|__MPEGTS Stream ID -video|1|11782|0.130911|8182|0.090911|3600|0.040000|N/A|N/A|12622|58092|__MPEGTS Stream ID +video|1|11782|0.130911|8182|0.090911|3600|0.040000|12622|58092|__MPEGTS Stream ID -video|1|15382|0.170911|11782|0.130911|3600|0.040000|N/A|N/A|13393|71064|__MPEGTS Stream ID +video|1|15382|0.170911|11782|0.130911|3600|0.040000|13393|71064|__MPEGTS Stream ID -video|1|18982|0.210911|15382|0.170911|3600|0.040000|N/A|N/A|13092|84788|__MPEGTS Stream ID +video|1|18982|0.210911|15382|0.170911|3600|0.040000|13092|84788|__MPEGTS Stream ID -video|1|22582|0.250911|18982|0.210911|3600|0.040000|N/A|N/A|12755|98700|__MPEGTS Stream ID +video|1|22582|0.250911|18982|0.210911|3600|0.040000|12755|98700|__MPEGTS Stream ID -video|1|26182|0.290911|22582|0.250911|3600|0.040000|N/A|N/A|12023|111860|__MPEGTS Stream ID +video|1|26182|0.290911|22582|0.250911|3600|0.040000|12023|111860|__MPEGTS Stream ID -audio|0|0|0.000000|0|0.000000|2351|0.026122|N/A|N/A|208|152844|K_MPEGTS Stream ID +audio|0|0|0.000000|0|0.000000|2351|0.026122|208|152844|K_MPEGTS Stream ID -audio|0|2351|0.026122|2351|0.026122|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|4702|0.052244|4702|0.052244|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|7053|0.078367|7053|0.078367|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|9404|0.104489|9404|0.104489|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|11755|0.130611|11755|0.130611|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|14106|0.156733|14106|0.156733|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|16457|0.182856|16457|0.182856|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|18808|0.208978|18808|0.208978|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|21159|0.235100|21159|0.235100|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|23510|0.261222|23510|0.261222|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|25861|0.287344|25861|0.287344|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|28212|0.313467|28212|0.313467|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|30563|0.339589|30563|0.339589|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|29782|0.330911|26182|0.290911|3600|0.040000|N/A|N/A|14098|124268|__MPEGTS Stream ID +audio|0|2351|0.026122|2351|0.026122|2351|0.026122|209|N/A|K_ +audio|0|4702|0.052244|4702|0.052244|2351|0.026122|209|N/A|K_ +audio|0|7053|0.078367|7053|0.078367|2351|0.026122|209|N/A|K_ +audio|0|9404|0.104489|9404|0.104489|2351|0.026122|209|N/A|K_ +audio|0|11755|0.130611|11755|0.130611|2351|0.026122|209|N/A|K_ +audio|0|14106|0.156733|14106|0.156733|2351|0.026122|209|N/A|K_ +audio|0|16457|0.182856|16457|0.182856|2351|0.026122|209|N/A|K_ +audio|0|18808|0.208978|18808|0.208978|2351|0.026122|209|N/A|K_ +audio|0|21159|0.235100|21159|0.235100|2351|0.026122|209|N/A|K_ +audio|0|23510|0.261222|23510|0.261222|2351|0.026122|209|N/A|K_ +audio|0|25861|0.287344|25861|0.287344|2351|0.026122|209|N/A|K_ +audio|0|28212|0.313467|28212|0.313467|2351|0.026122|209|N/A|K_ +audio|0|30563|0.339589|30563|0.339589|2351|0.026122|209|N/A|K_ +video|1|29782|0.330911|26182|0.290911|3600|0.040000|14098|124268|__MPEGTS Stream ID -video|1|33382|0.370911|29782|0.330911|3600|0.040000|N/A|N/A|13329|139120|__MPEGTS Stream ID +video|1|33382|0.370911|29782|0.330911|3600|0.040000|13329|139120|__MPEGTS Stream ID -video|1|36982|0.410911|33382|0.370911|3600|0.040000|N/A|N/A|12135|155852|__MPEGTS Stream ID +video|1|36982|0.410911|33382|0.370911|3600|0.040000|12135|155852|__MPEGTS Stream ID -video|1|40582|0.450911|36982|0.410911|3600|0.040000|N/A|N/A|12282|168448|__MPEGTS Stream ID +video|1|40582|0.450911|36982|0.410911|3600|0.040000|12282|168448|__MPEGTS Stream ID -video|1|44182|0.490911|40582|0.450911|3600|0.040000|N/A|N/A|24786|181420|K_MPEGTS Stream ID +video|1|44182|0.490911|40582|0.450911|3600|0.040000|24786|181420|K_MPEGTS Stream ID -video|1|47782|0.530911|44182|0.490911|3600|0.040000|N/A|N/A|17440|206988|__MPEGTS Stream ID +video|1|47782|0.530911|44182|0.490911|3600|0.040000|17440|206988|__MPEGTS Stream ID -video|1|51382|0.570911|47782|0.530911|3600|0.040000|N/A|N/A|15019|224848|__MPEGTS Stream ID +video|1|51382|0.570911|47782|0.530911|3600|0.040000|15019|224848|__MPEGTS Stream ID -video|1|54982|0.610911|51382|0.570911|3600|0.040000|N/A|N/A|13449|240640|__MPEGTS Stream ID +video|1|54982|0.610911|51382|0.570911|3600|0.040000|13449|240640|__MPEGTS Stream ID -video|1|58582|0.650911|54982|0.610911|3600|0.040000|N/A|N/A|12398|254552|__MPEGTS Stream ID +video|1|58582|0.650911|54982|0.610911|3600|0.040000|12398|254552|__MPEGTS Stream ID -video|1|62182|0.690911|58582|0.650911|3600|0.040000|N/A|N/A|13455|267336|__MPEGTS Stream ID +video|1|62182|0.690911|58582|0.650911|3600|0.040000|13455|267336|__MPEGTS Stream ID -audio|0|32915|0.365722|32915|0.365722|2351|0.026122|N/A|N/A|209|308508|K_MPEGTS Stream ID +audio|0|32915|0.365722|32915|0.365722|2351|0.026122|209|308508|K_MPEGTS Stream ID -audio|0|35266|0.391844|35266|0.391844|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|37617|0.417967|37617|0.417967|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|39968|0.444089|39968|0.444089|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|42319|0.470211|42319|0.470211|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|44670|0.496333|44670|0.496333|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|47021|0.522456|47021|0.522456|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|49372|0.548578|49372|0.548578|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|51723|0.574700|51723|0.574700|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|54074|0.600822|54074|0.600822|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|56425|0.626944|56425|0.626944|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|58776|0.653067|58776|0.653067|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|61127|0.679189|61127|0.679189|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|63478|0.705311|63478|0.705311|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|65782|0.730911|62182|0.690911|3600|0.040000|N/A|N/A|13836|281624|__MPEGTS Stream ID +audio|0|35266|0.391844|35266|0.391844|2351|0.026122|209|N/A|K_ +audio|0|37617|0.417967|37617|0.417967|2351|0.026122|209|N/A|K_ +audio|0|39968|0.444089|39968|0.444089|2351|0.026122|209|N/A|K_ +audio|0|42319|0.470211|42319|0.470211|2351|0.026122|209|N/A|K_ +audio|0|44670|0.496333|44670|0.496333|2351|0.026122|209|N/A|K_ +audio|0|47021|0.522456|47021|0.522456|2351|0.026122|209|N/A|K_ +audio|0|49372|0.548578|49372|0.548578|2351|0.026122|209|N/A|K_ +audio|0|51723|0.574700|51723|0.574700|2351|0.026122|209|N/A|K_ +audio|0|54074|0.600822|54074|0.600822|2351|0.026122|209|N/A|K_ +audio|0|56425|0.626944|56425|0.626944|2351|0.026122|209|N/A|K_ +audio|0|58776|0.653067|58776|0.653067|2351|0.026122|209|N/A|K_ +audio|0|61127|0.679189|61127|0.679189|2351|0.026122|209|N/A|K_ +audio|0|63478|0.705311|63478|0.705311|2351|0.026122|209|N/A|K_ +video|1|65782|0.730911|62182|0.690911|3600|0.040000|13836|281624|__MPEGTS Stream ID -video|1|69382|0.770911|65782|0.730911|3600|0.040000|N/A|N/A|12163|295912|__MPEGTS Stream ID +video|1|69382|0.770911|65782|0.730911|3600|0.040000|12163|295912|__MPEGTS Stream ID -video|1|72982|0.810911|69382|0.770911|3600|0.040000|N/A|N/A|12692|311516|__MPEGTS Stream ID +video|1|72982|0.810911|69382|0.770911|3600|0.040000|12692|311516|__MPEGTS Stream ID -video|1|76582|0.850911|72982|0.810911|3600|0.040000|N/A|N/A|10824|325052|__MPEGTS Stream ID +video|1|76582|0.850911|72982|0.810911|3600|0.040000|10824|325052|__MPEGTS Stream ID -video|1|80182|0.890911|76582|0.850911|3600|0.040000|N/A|N/A|11286|336144|__MPEGTS Stream ID +video|1|80182|0.890911|76582|0.850911|3600|0.040000|11286|336144|__MPEGTS Stream ID -audio|0|65829|0.731433|65829|0.731433|2351|0.026122|N/A|N/A|209|386716|K_MPEGTS Stream ID +audio|0|65829|0.731433|65829|0.731433|2351|0.026122|209|386716|K_MPEGTS Stream ID -audio|0|68180|0.757556|68180|0.757556|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|70531|0.783678|70531|0.783678|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|72882|0.809800|72882|0.809800|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|75233|0.835922|75233|0.835922|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|77584|0.862044|77584|0.862044|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|79935|0.888167|79935|0.888167|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|82286|0.914289|82286|0.914289|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|84637|0.940411|84637|0.940411|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|86988|0.966533|86988|0.966533|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|89339|0.992656|89339|0.992656|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|83782|0.930911|80182|0.890911|3600|0.040000|N/A|N/A|12678|347800|__MPEGTS Stream ID +audio|0|68180|0.757556|68180|0.757556|2351|0.026122|209|N/A|K_ +audio|0|70531|0.783678|70531|0.783678|2351|0.026122|209|N/A|K_ +audio|0|72882|0.809800|72882|0.809800|2351|0.026122|209|N/A|K_ +audio|0|75233|0.835922|75233|0.835922|2351|0.026122|209|N/A|K_ +audio|0|77584|0.862044|77584|0.862044|2351|0.026122|209|N/A|K_ +audio|0|79935|0.888167|79935|0.888167|2351|0.026122|209|N/A|K_ +audio|0|82286|0.914289|82286|0.914289|2351|0.026122|209|N/A|K_ +audio|0|84637|0.940411|84637|0.940411|2351|0.026122|209|N/A|K_ +audio|0|86988|0.966533|86988|0.966533|2351|0.026122|209|N/A|K_ +audio|0|89339|0.992656|89339|0.992656|2351|0.026122|209|N/A|K_ +video|1|83782|0.930911|80182|0.890911|3600|0.040000|12678|347800|__MPEGTS Stream ID -video|1|87382|0.970911|83782|0.930911|3600|0.040000|N/A|N/A|24711|361336|K_ -video|1|91964|1.021822|88364|0.981822|3600|0.040000|N/A|N/A|24801|564|K_MPEGTS Stream ID +video|1|87382|0.970911|83782|0.930911|3600|0.040000|24711|361336|K_ +video|1|91964|1.021822|88364|0.981822|3600|0.040000|24801|564|K_MPEGTS Stream ID -video|1|95564|1.061822|91964|1.021822|3600|0.040000|N/A|N/A|16429|25944|__MPEGTS Stream ID +video|1|95564|1.061822|91964|1.021822|3600|0.040000|16429|25944|__MPEGTS Stream ID -video|1|99164|1.101822|95564|1.061822|3600|0.040000|N/A|N/A|14508|42864|__MPEGTS Stream ID +video|1|99164|1.101822|95564|1.061822|3600|0.040000|14508|42864|__MPEGTS Stream ID -video|1|102764|1.141822|99164|1.101822|3600|0.040000|N/A|N/A|12622|58092|__MPEGTS Stream ID +video|1|102764|1.141822|99164|1.101822|3600|0.040000|12622|58092|__MPEGTS Stream ID -video|1|106364|1.181822|102764|1.141822|3600|0.040000|N/A|N/A|13393|71064|__MPEGTS Stream ID +video|1|106364|1.181822|102764|1.141822|3600|0.040000|13393|71064|__MPEGTS Stream ID -video|1|109964|1.221822|106364|1.181822|3600|0.040000|N/A|N/A|13092|84788|__MPEGTS Stream ID +video|1|109964|1.221822|106364|1.181822|3600|0.040000|13092|84788|__MPEGTS Stream ID -video|1|113564|1.261822|109964|1.221822|3600|0.040000|N/A|N/A|12755|98700|__MPEGTS Stream ID +video|1|113564|1.261822|109964|1.221822|3600|0.040000|12755|98700|__MPEGTS Stream ID -video|1|117164|1.301822|113564|1.261822|3600|0.040000|N/A|N/A|12023|111860|__MPEGTS Stream ID +video|1|117164|1.301822|113564|1.261822|3600|0.040000|12023|111860|__MPEGTS Stream ID -audio|0|90982|1.010911|90982|1.010911|2351|0.026122|N/A|N/A|208|152844|K_MPEGTS Stream ID +audio|0|90982|1.010911|90982|1.010911|2351|0.026122|208|152844|K_MPEGTS Stream ID -audio|0|93333|1.037033|93333|1.037033|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|95684|1.063156|95684|1.063156|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|98035|1.089278|98035|1.089278|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|100386|1.115400|100386|1.115400|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|102737|1.141522|102737|1.141522|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|105088|1.167644|105088|1.167644|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|107439|1.193767|107439|1.193767|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|109790|1.219889|109790|1.219889|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|112141|1.246011|112141|1.246011|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|114492|1.272133|114492|1.272133|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|116843|1.298256|116843|1.298256|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|119194|1.324378|119194|1.324378|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|121545|1.350500|121545|1.350500|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|120764|1.341822|117164|1.301822|3600|0.040000|N/A|N/A|14098|124268|__MPEGTS Stream ID +audio|0|93333|1.037033|93333|1.037033|2351|0.026122|209|N/A|K_ +audio|0|95684|1.063156|95684|1.063156|2351|0.026122|209|N/A|K_ +audio|0|98035|1.089278|98035|1.089278|2351|0.026122|209|N/A|K_ +audio|0|100386|1.115400|100386|1.115400|2351|0.026122|209|N/A|K_ +audio|0|102737|1.141522|102737|1.141522|2351|0.026122|209|N/A|K_ +audio|0|105088|1.167644|105088|1.167644|2351|0.026122|209|N/A|K_ +audio|0|107439|1.193767|107439|1.193767|2351|0.026122|209|N/A|K_ +audio|0|109790|1.219889|109790|1.219889|2351|0.026122|209|N/A|K_ +audio|0|112141|1.246011|112141|1.246011|2351|0.026122|209|N/A|K_ +audio|0|114492|1.272133|114492|1.272133|2351|0.026122|209|N/A|K_ +audio|0|116843|1.298256|116843|1.298256|2351|0.026122|209|N/A|K_ +audio|0|119194|1.324378|119194|1.324378|2351|0.026122|209|N/A|K_ +audio|0|121545|1.350500|121545|1.350500|2351|0.026122|209|N/A|K_ +video|1|120764|1.341822|117164|1.301822|3600|0.040000|14098|124268|__MPEGTS Stream ID -video|1|124364|1.381822|120764|1.341822|3600|0.040000|N/A|N/A|13329|139120|__MPEGTS Stream ID +video|1|124364|1.381822|120764|1.341822|3600|0.040000|13329|139120|__MPEGTS Stream ID -video|1|127964|1.421822|124364|1.381822|3600|0.040000|N/A|N/A|12135|155852|__MPEGTS Stream ID +video|1|127964|1.421822|124364|1.381822|3600|0.040000|12135|155852|__MPEGTS Stream ID -video|1|131564|1.461822|127964|1.421822|3600|0.040000|N/A|N/A|12282|168448|__MPEGTS Stream ID +video|1|131564|1.461822|127964|1.421822|3600|0.040000|12282|168448|__MPEGTS Stream ID -video|1|135164|1.501822|131564|1.461822|3600|0.040000|N/A|N/A|24786|181420|K_MPEGTS Stream ID +video|1|135164|1.501822|131564|1.461822|3600|0.040000|24786|181420|K_MPEGTS Stream ID -video|1|138764|1.541822|135164|1.501822|3600|0.040000|N/A|N/A|17440|206988|__MPEGTS Stream ID +video|1|138764|1.541822|135164|1.501822|3600|0.040000|17440|206988|__MPEGTS Stream ID -video|1|142364|1.581822|138764|1.541822|3600|0.040000|N/A|N/A|15019|224848|__MPEGTS Stream ID +video|1|142364|1.581822|138764|1.541822|3600|0.040000|15019|224848|__MPEGTS Stream ID -video|1|145964|1.621822|142364|1.581822|3600|0.040000|N/A|N/A|13449|240640|__MPEGTS Stream ID +video|1|145964|1.621822|142364|1.581822|3600|0.040000|13449|240640|__MPEGTS Stream ID -video|1|149564|1.661822|145964|1.621822|3600|0.040000|N/A|N/A|12398|254552|__MPEGTS Stream ID +video|1|149564|1.661822|145964|1.621822|3600|0.040000|12398|254552|__MPEGTS Stream ID -video|1|153164|1.701822|149564|1.661822|3600|0.040000|N/A|N/A|13455|267336|__MPEGTS Stream ID +video|1|153164|1.701822|149564|1.661822|3600|0.040000|13455|267336|__MPEGTS Stream ID -audio|0|123897|1.376633|123897|1.376633|2351|0.026122|N/A|N/A|209|308508|K_MPEGTS Stream ID +audio|0|123897|1.376633|123897|1.376633|2351|0.026122|209|308508|K_MPEGTS Stream ID -audio|0|126248|1.402756|126248|1.402756|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|128599|1.428878|128599|1.428878|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|130950|1.455000|130950|1.455000|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|133301|1.481122|133301|1.481122|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|135652|1.507244|135652|1.507244|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|138003|1.533367|138003|1.533367|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|140354|1.559489|140354|1.559489|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|142705|1.585611|142705|1.585611|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|145056|1.611733|145056|1.611733|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|147407|1.637856|147407|1.637856|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|149758|1.663978|149758|1.663978|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|152109|1.690100|152109|1.690100|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|154460|1.716222|154460|1.716222|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|156764|1.741822|153164|1.701822|3600|0.040000|N/A|N/A|13836|281624|__MPEGTS Stream ID +audio|0|126248|1.402756|126248|1.402756|2351|0.026122|209|N/A|K_ +audio|0|128599|1.428878|128599|1.428878|2351|0.026122|209|N/A|K_ +audio|0|130950|1.455000|130950|1.455000|2351|0.026122|209|N/A|K_ +audio|0|133301|1.481122|133301|1.481122|2351|0.026122|209|N/A|K_ +audio|0|135652|1.507244|135652|1.507244|2351|0.026122|209|N/A|K_ +audio|0|138003|1.533367|138003|1.533367|2351|0.026122|209|N/A|K_ +audio|0|140354|1.559489|140354|1.559489|2351|0.026122|209|N/A|K_ +audio|0|142705|1.585611|142705|1.585611|2351|0.026122|209|N/A|K_ +audio|0|145056|1.611733|145056|1.611733|2351|0.026122|209|N/A|K_ +audio|0|147407|1.637856|147407|1.637856|2351|0.026122|209|N/A|K_ +audio|0|149758|1.663978|149758|1.663978|2351|0.026122|209|N/A|K_ +audio|0|152109|1.690100|152109|1.690100|2351|0.026122|209|N/A|K_ +audio|0|154460|1.716222|154460|1.716222|2351|0.026122|209|N/A|K_ +video|1|156764|1.741822|153164|1.701822|3600|0.040000|13836|281624|__MPEGTS Stream ID -video|1|160364|1.781822|156764|1.741822|3600|0.040000|N/A|N/A|12163|295912|__MPEGTS Stream ID +video|1|160364|1.781822|156764|1.741822|3600|0.040000|12163|295912|__MPEGTS Stream ID -video|1|163964|1.821822|160364|1.781822|3600|0.040000|N/A|N/A|12692|311516|__MPEGTS Stream ID +video|1|163964|1.821822|160364|1.781822|3600|0.040000|12692|311516|__MPEGTS Stream ID -video|1|167564|1.861822|163964|1.821822|3600|0.040000|N/A|N/A|10824|325052|__MPEGTS Stream ID +video|1|167564|1.861822|163964|1.821822|3600|0.040000|10824|325052|__MPEGTS Stream ID -video|1|171164|1.901822|167564|1.861822|3600|0.040000|N/A|N/A|11286|336144|__MPEGTS Stream ID +video|1|171164|1.901822|167564|1.861822|3600|0.040000|11286|336144|__MPEGTS Stream ID -audio|0|156811|1.742344|156811|1.742344|2351|0.026122|N/A|N/A|209|386716|K_MPEGTS Stream ID +audio|0|156811|1.742344|156811|1.742344|2351|0.026122|209|386716|K_MPEGTS Stream ID -audio|0|159162|1.768467|159162|1.768467|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|161513|1.794589|161513|1.794589|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|163864|1.820711|163864|1.820711|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|166215|1.846833|166215|1.846833|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|168566|1.872956|168566|1.872956|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|170917|1.899078|170917|1.899078|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|173268|1.925200|173268|1.925200|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|175619|1.951322|175619|1.951322|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|177970|1.977444|177970|1.977444|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|180321|2.003567|180321|2.003567|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|174764|1.941822|171164|1.901822|3600|0.040000|N/A|N/A|12678|347800|__MPEGTS Stream ID +audio|0|159162|1.768467|159162|1.768467|2351|0.026122|209|N/A|K_ +audio|0|161513|1.794589|161513|1.794589|2351|0.026122|209|N/A|K_ +audio|0|163864|1.820711|163864|1.820711|2351|0.026122|209|N/A|K_ +audio|0|166215|1.846833|166215|1.846833|2351|0.026122|209|N/A|K_ +audio|0|168566|1.872956|168566|1.872956|2351|0.026122|209|N/A|K_ +audio|0|170917|1.899078|170917|1.899078|2351|0.026122|209|N/A|K_ +audio|0|173268|1.925200|173268|1.925200|2351|0.026122|209|N/A|K_ +audio|0|175619|1.951322|175619|1.951322|2351|0.026122|209|N/A|K_ +audio|0|177970|1.977444|177970|1.977444|2351|0.026122|209|N/A|K_ +audio|0|180321|2.003567|180321|2.003567|2351|0.026122|209|N/A|K_ +video|1|174764|1.941822|171164|1.901822|3600|0.040000|12678|347800|__MPEGTS Stream ID -video|1|178364|1.981822|174764|1.941822|3600|0.040000|N/A|N/A|24711|361336|K_ -video|1|139582|1.550911|135982|1.510911|3600|0.040000|N/A|N/A|12692|311516|__MPEGTS Stream ID +video|1|178364|1.981822|174764|1.941822|3600|0.040000|24711|361336|K_ +video|1|139582|1.550911|135982|1.510911|3600|0.040000|12692|311516|__MPEGTS Stream ID -video|1|143182|1.590911|139582|1.550911|3600|0.040000|N/A|N/A|10824|325052|__MPEGTS Stream ID +video|1|143182|1.590911|139582|1.550911|3600|0.040000|10824|325052|__MPEGTS Stream ID -video|1|146782|1.630911|143182|1.590911|3600|0.040000|N/A|N/A|11286|336144|__MPEGTS Stream ID +video|1|146782|1.630911|143182|1.590911|3600|0.040000|11286|336144|__MPEGTS Stream ID -audio|0|132429|1.471433|132429|1.471433|2351|0.026122|N/A|N/A|209|386716|K_MPEGTS Stream ID +audio|0|132429|1.471433|132429|1.471433|2351|0.026122|209|386716|K_MPEGTS Stream ID -audio|0|134780|1.497556|134780|1.497556|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|137131|1.523678|137131|1.523678|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|139482|1.549800|139482|1.549800|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|141833|1.575922|141833|1.575922|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|144184|1.602044|144184|1.602044|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|146535|1.628167|146535|1.628167|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|148886|1.654289|148886|1.654289|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|151237|1.680411|151237|1.680411|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|153588|1.706533|153588|1.706533|2351|0.026122|N/A|N/A|209|N/A|K_ -audio|0|155939|1.732656|155939|1.732656|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|150382|1.670911|146782|1.630911|3600|0.040000|N/A|N/A|12678|347800|__MPEGTS Stream ID +audio|0|134780|1.497556|134780|1.497556|2351|0.026122|209|N/A|K_ +audio|0|137131|1.523678|137131|1.523678|2351|0.026122|209|N/A|K_ +audio|0|139482|1.549800|139482|1.549800|2351|0.026122|209|N/A|K_ +audio|0|141833|1.575922|141833|1.575922|2351|0.026122|209|N/A|K_ +audio|0|144184|1.602044|144184|1.602044|2351|0.026122|209|N/A|K_ +audio|0|146535|1.628167|146535|1.628167|2351|0.026122|209|N/A|K_ +audio|0|148886|1.654289|148886|1.654289|2351|0.026122|209|N/A|K_ +audio|0|151237|1.680411|151237|1.680411|2351|0.026122|209|N/A|K_ +audio|0|153588|1.706533|153588|1.706533|2351|0.026122|209|N/A|K_ +audio|0|155939|1.732656|155939|1.732656|2351|0.026122|209|N/A|K_ +video|1|150382|1.670911|146782|1.630911|3600|0.040000|12678|347800|__MPEGTS Stream ID -video|1|153982|1.710911|150382|1.670911|3600|0.040000|N/A|N/A|24711|361336|K_ -video|1|161182|1.790911|157582|1.750911|3600|0.040000|N/A|N/A|12135|155852|__MPEGTS Stream ID +video|1|153982|1.710911|150382|1.670911|3600|0.040000|24711|361336|K_ +video|1|161182|1.790911|157582|1.750911|3600|0.040000|12135|155852|__MPEGTS Stream ID -video|1|164782|1.830911|161182|1.790911|3600|0.040000|N/A|N/A|12282|168448|__MPEGTS Stream ID +video|1|164782|1.830911|161182|1.790911|3600|0.040000|12282|168448|__MPEGTS Stream ID -video|1|168382|1.870911|164782|1.830911|3600|0.040000|N/A|N/A|24786|181420|K_MPEGTS Stream ID +video|1|168382|1.870911|164782|1.830911|3600|0.040000|24786|181420|K_MPEGTS Stream ID -video|1|171982|1.910911|168382|1.870911|3600|0.040000|N/A|N/A|17440|206988|__MPEGTS Stream ID +video|1|171982|1.910911|168382|1.870911|3600|0.040000|17440|206988|__MPEGTS Stream ID -video|1|175582|1.950911|171982|1.910911|3600|0.040000|N/A|N/A|15019|224848|__MPEGTS Stream ID +video|1|175582|1.950911|171982|1.910911|3600|0.040000|15019|224848|__MPEGTS Stream ID -0|mp2|unknown|audio|1/44100|[3][0][0][0]|0x0003|s16p|44100|1|mono|0|N/A|0/0|0/0|1/90000|0|0.000000|N/A|N/A|64000|N/A|N/A|N/A|N/A|89|0|0|0|0|0|0|0|0|0|0|0|0 -1|mpeg2video|4|video|1/25|[2][0][0][0]|0x0002|352|288|0|0|0|1|1:1|11:9|yuv420p|8|tv|unknown|unknown|unknown|left|progressive|N/A|1|N/A|25/1|25/1|1/90000|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|60|0|0|0|0|0|0|0|0|0|0|0|0 +0|mp2|unknown|audio|[3][0][0][0]|0x0003|s16p|44100|1|mono|0|N/A|0/0|0/0|1/90000|0|0.000000|N/A|N/A|64000|N/A|N/A|N/A|N/A|89|0|0|0|0|0|0|0|0|0|0|0|0 +1|mpeg2video|4|video|[2][0][0][0]|0x0002|352|288|0|0|0|1|1:1|11:9|yuv420p|8|tv|unknown|unknown|unknown|left|progressive|1|N/A|25/1|25/1|1/90000|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|60|0|0|0|0|0|0|0|0|0|0|0|0 diff --git a/tests/ref/fate/copy-trac236 b/tests/ref/fate/copy-trac236 index 1583ae570..c34b309b3 100644 --- a/tests/ref/fate/copy-trac236 +++ b/tests/ref/fate/copy-trac236 @@ -1,5 +1,5 @@ -984a33c6292e3d35e2cfdfbf66d8e82b *tests/data/fate/copy-trac236.mov -630860 tests/data/fate/copy-trac236.mov +34b0ad38518b0eb8464aff04e6d0e143 *tests/data/fate/copy-trac236.mov +630878 tests/data/fate/copy-trac236.mov #tb 0: 100/2997 #media_type 0: video #codec_id 0: rawvideo diff --git a/tests/ref/fate/copy-trac3074 b/tests/ref/fate/copy-trac3074 index ff6690025..78b6015ae 100644 --- a/tests/ref/fate/copy-trac3074 +++ b/tests/ref/fate/copy-trac3074 @@ -1,5 +1,5 @@ -f92a201033712bda262f1e071e25544a *tests/data/fate/copy-trac3074.mp4 -333992 tests/data/fate/copy-trac3074.mp4 +da6122873fb83ce4340cf5d0ab8d475e *tests/data/fate/copy-trac3074.mp4 +334012 tests/data/fate/copy-trac3074.mp4 #tb 0: 1/48000 #media_type 0: audio #codec_id 0: eac3 diff --git a/tests/ref/fate/copy-trac4914 b/tests/ref/fate/copy-trac4914 index 7c8d0e915..743dc8c05 100644 --- a/tests/ref/fate/copy-trac4914 +++ b/tests/ref/fate/copy-trac4914 @@ -1,4 +1,4 @@ -b37c4d5693cdb5b9ed9b33501ffb682a *tests/data/fate/copy-trac4914.mxf +f5150fb82c1bb5a90906fce93dcc3f76 *tests/data/fate/copy-trac4914.mxf 561721 tests/data/fate/copy-trac4914.mxf #tb 0: 1001/30000 #media_type 0: video diff --git a/tests/ref/fate/dpx-probe b/tests/ref/fate/dpx-probe new file mode 100644 index 000000000..e116b2f73 --- /dev/null +++ b/tests/ref/fate/dpx-probe @@ -0,0 +1,16 @@ +[FRAME] +sample_aspect_ratio=1:1 +color_range=pc +color_space=gbr +color_primaries=bt709 +color_transfer=unknown +TAG:timecode=00:00:01:18 +TAG:Creator=Apple Compressor +TAG:Input Device= +[SIDE_DATA] +side_data_type=SMPTE 12-1 timecode +[TIMECODE] +value=00:00:01:18 +[/TIMECODE] +[/SIDE_DATA] +[/FRAME] diff --git a/tests/ref/fate/exif-image-embedded b/tests/ref/fate/exif-image-embedded index 392c145ef..9ad073e9e 100644 --- a/tests/ref/fate/exif-image-embedded +++ b/tests/ref/fate/exif-image-embedded @@ -29,12 +29,6 @@ color_transfer=unknown chroma_location=center TAG:UserComment=AppleMark -[SIDE_DATA] -side_data_type=QP table data -[/SIDE_DATA] -[SIDE_DATA] -side_data_type=QP table properties -[/SIDE_DATA] [/FRAME] [FRAME] media_type=audio @@ -44,8 +38,8 @@ pkt_pts=353600 pkt_pts_time=0.025057 pkt_dts=353600 pkt_dts_time=0.025057 -best_effort_timestamp=0 -best_effort_timestamp_time=0.000000 +best_effort_timestamp=353600 +best_effort_timestamp_time=0.025057 pkt_duration=15040 pkt_duration_time=0.001066 pkt_pos=16292 diff --git a/tests/ref/fate/exif-image-jpg b/tests/ref/fate/exif-image-jpg index eb18dede2..b26650119 100644 --- a/tests/ref/fate/exif-image-jpg +++ b/tests/ref/fate/exif-image-jpg @@ -229,10 +229,4 @@ TAG:ExposureMode= 0 TAG:WhiteBalance= 0 TAG:DigitalZoomRatio= 4000:4000 TAG:SceneCaptureType= 0 -[SIDE_DATA] -side_data_type=QP table data -[/SIDE_DATA] -[SIDE_DATA] -side_data_type=QP table properties -[/SIDE_DATA] [/FRAME] diff --git a/tests/ref/fate/exr-rgb-scanline-float-zip-dw-large b/tests/ref/fate/exr-rgb-scanline-float-zip-dw-large new file mode 100644 index 000000000..45fc6182c --- /dev/null +++ b/tests/ref/fate/exr-rgb-scanline-float-zip-dw-large @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 50x50 +#sar 0: 1/1 +0, 0, 0, 1, 30000, 0x947ce379 diff --git a/tests/ref/fate/exr-rgb-scanline-half-piz-dw-large b/tests/ref/fate/exr-rgb-scanline-half-piz-dw-large new file mode 100644 index 000000000..811698074 --- /dev/null +++ b/tests/ref/fate/exr-rgb-scanline-half-piz-dw-large @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 50x50 +#sar 0: 1/1 +0, 0, 0, 1, 30000, 0xb329ee9c diff --git a/tests/ref/fate/exr-rgb-scanline-half-zip-dw-large b/tests/ref/fate/exr-rgb-scanline-half-zip-dw-large new file mode 100644 index 000000000..811698074 --- /dev/null +++ b/tests/ref/fate/exr-rgb-scanline-half-zip-dw-large @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 50x50 +#sar 0: 1/1 +0, 0, 0, 1, 30000, 0xb329ee9c diff --git a/tests/ref/fate/exr-rgb-scanline-half-zip-dw-outside b/tests/ref/fate/exr-rgb-scanline-half-zip-dw-outside new file mode 100644 index 000000000..8c2258838 --- /dev/null +++ b/tests/ref/fate/exr-rgb-scanline-half-zip-dw-outside @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 501x401 +#sar 0: 1/1 +0, 0, 0, 1, 2410812, 0x00000000 diff --git a/tests/ref/fate/exr-rgb-scanline-pxr24-half-uint32-13x9 b/tests/ref/fate/exr-rgb-scanline-pxr24-half-uint32-13x9 index 523ed9c88..2d209d8a6 100644 --- a/tests/ref/fate/exr-rgb-scanline-pxr24-half-uint32-13x9 +++ b/tests/ref/fate/exr-rgb-scanline-pxr24-half-uint32-13x9 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 13x9 #sar 0: 9/10 -0, 0, 0, 1, 702, 0x68c1450d +0, 0, 0, 1, 702, 0x86132f10 diff --git a/tests/ref/fate/exr-rgb-scanline-uint32-piz-dw-large b/tests/ref/fate/exr-rgb-scanline-uint32-piz-dw-large new file mode 100644 index 000000000..60e125494 --- /dev/null +++ b/tests/ref/fate/exr-rgb-scanline-uint32-piz-dw-large @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 50x50 +#sar 0: 1/1 +0, 0, 0, 1, 15000, 0xeeacd171 diff --git a/tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF b/tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF new file mode 100644 index 000000000..b6201116f --- /dev/null +++ b/tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 256x256 +#sar 0: 1/1 +0, 0, 0, 1, 786432, 0x1445e411 diff --git a/tests/ref/fate/exr-rgb-tile-half-piz-dw-large b/tests/ref/fate/exr-rgb-tile-half-piz-dw-large new file mode 100644 index 000000000..811698074 --- /dev/null +++ b/tests/ref/fate/exr-rgb-tile-half-piz-dw-large @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 50x50 +#sar 0: 1/1 +0, 0, 0, 1, 30000, 0xb329ee9c diff --git a/tests/ref/fate/exr-rgb-tile-half-zip b/tests/ref/fate/exr-rgb-tile-half-zip new file mode 100644 index 000000000..7cf760334 --- /dev/null +++ b/tests/ref/fate/exr-rgb-tile-half-zip @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 501x401 +#sar 0: 1/1 +0, 0, 0, 1, 2410812, 0x2dd1b00b diff --git a/tests/ref/fate/exr-rgb-tile-half-zip-dw-outside b/tests/ref/fate/exr-rgb-tile-half-zip-dw-outside new file mode 100644 index 000000000..8c2258838 --- /dev/null +++ b/tests/ref/fate/exr-rgb-tile-half-zip-dw-outside @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 501x401 +#sar 0: 1/1 +0, 0, 0, 1, 2410812, 0x00000000 diff --git a/tests/ref/fate/exr-rgb-tile-uint32-piz-dw-large b/tests/ref/fate/exr-rgb-tile-uint32-piz-dw-large new file mode 100644 index 000000000..60e125494 --- /dev/null +++ b/tests/ref/fate/exr-rgb-tile-uint32-piz-dw-large @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 50x50 +#sar 0: 1/1 +0, 0, 0, 1, 15000, 0xeeacd171 diff --git a/tests/ref/fate/exr-rgba-multiscanline-half-b44 b/tests/ref/fate/exr-rgba-multiscanline-half-b44 index 964bf2e65..24525b92a 100644 --- a/tests/ref/fate/exr-rgba-multiscanline-half-b44 +++ b/tests/ref/fate/exr-rgba-multiscanline-half-b44 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 935x251 #sar 0: 1/1 -0, 0, 0, 1, 3754960, 0x4d48a1b2 +0, 0, 0, 1, 3754960, 0x8d9af112 diff --git a/tests/ref/fate/exr-slice-raw b/tests/ref/fate/exr-slice-raw index c7096e4d2..1e7d3825e 100644 --- a/tests/ref/fate/exr-slice-raw +++ b/tests/ref/fate/exr-slice-raw @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 587x675 #sar 0: 1/1 -0, 0, 0, 1, 6339600, 0x4f2b496b +0, 0, 0, 1, 6339600, 0xda3e31df diff --git a/tests/ref/fate/exr-slice-rle b/tests/ref/fate/exr-slice-rle index c7096e4d2..1e7d3825e 100644 --- a/tests/ref/fate/exr-slice-rle +++ b/tests/ref/fate/exr-slice-rle @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 587x675 #sar 0: 1/1 -0, 0, 0, 1, 6339600, 0x4f2b496b +0, 0, 0, 1, 6339600, 0xda3e31df diff --git a/tests/ref/fate/exr-slice-zip1 b/tests/ref/fate/exr-slice-zip1 index c7096e4d2..1e7d3825e 100644 --- a/tests/ref/fate/exr-slice-zip1 +++ b/tests/ref/fate/exr-slice-zip1 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 587x675 #sar 0: 1/1 -0, 0, 0, 1, 6339600, 0x4f2b496b +0, 0, 0, 1, 6339600, 0xda3e31df diff --git a/tests/ref/fate/exr-slice-zip16 b/tests/ref/fate/exr-slice-zip16 index c7096e4d2..1e7d3825e 100644 --- a/tests/ref/fate/exr-slice-zip16 +++ b/tests/ref/fate/exr-slice-zip16 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 587x675 #sar 0: 1/1 -0, 0, 0, 1, 6339600, 0x4f2b496b +0, 0, 0, 1, 6339600, 0xda3e31df diff --git a/tests/ref/fate/exr-ya-scanline-zip-half-12x8 b/tests/ref/fate/exr-ya-scanline-zip-half-12x8 new file mode 100644 index 000000000..23e1108ed --- /dev/null +++ b/tests/ref/fate/exr-ya-scanline-zip-half-12x8 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 12x8 +#sar 0: 1/1 +0, 0, 0, 1, 1536, 0x9473ee5c diff --git a/tests/ref/fate/ffmpeg-attached_pics b/tests/ref/fate/ffmpeg-attached_pics index ee2f20638..48c7ced36 100644 --- a/tests/ref/fate/ffmpeg-attached_pics +++ b/tests/ref/fate/ffmpeg-attached_pics @@ -9,7 +9,7 @@ #sample_rate 1: 44100 #channel_layout 1: 3 #channel_layout_name 1: stereo -0, 0, 0, 0, 120000, 0x748cc771 +0, 0, 0, 1, 120000, 0x748cc771 1, 0, 0, 4096, 16384, 0x00000000 1, 4096, 4096, 4096, 16384, 0x29cd639d 1, 8192, 8192, 4096, 16384, 0xd52066e5 diff --git a/tests/ref/fate/ffmpeg-streamloop b/tests/ref/fate/ffmpeg-streamloop index d22199d58..705c4646c 100644 --- a/tests/ref/fate/ffmpeg-streamloop +++ b/tests/ref/fate/ffmpeg-streamloop @@ -8,7 +8,7 @@ #dimensions 0: 320x240 #sar 0: 1/1 #stream#, dts, pts, duration, size, hash -0, -80, 0, 0, 5131, fb6a475e53addc2ffa79e1b75de81050 +0, -80, 0, 40, 5131, fb6a475e53addc2ffa79e1b75de81050 0, -40, 160, 40, 2479, fc64a1f7054d22741fffc68891ff4887 0, 0, 80, 40, 1354, 344ee1f5e8f0fe2785639dd530cf85ca 0, 40, 40, 40, 965, cbea2691414063d4e1199b781586cac4 diff --git a/tests/ref/fate/ffprobe_compact b/tests/ref/fate/ffprobe_compact index 03ae21394..ded412ea9 100644 --- a/tests/ref/fate/ffprobe_compact +++ b/tests/ref/fate/ffprobe_compact @@ -1,32 +1,32 @@ -packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=647|flags=K_ +packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1024|duration_time=0.023220|size=2048|pos=647|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=647|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown -packet|codec_type=video|stream_index=1|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=2722|flags=K_ +packet|codec_type=video|stream_index=1|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=2048|duration_time=0.040000|size=230400|pos=2722|flags=K_ frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=2722|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified -packet|codec_type=video|stream_index=2|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=233143|flags=K_ +packet|codec_type=video|stream_index=2|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=2048|duration_time=0.040000|size=30000|pos=233143|flags=K_ frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=233143|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified -packet|codec_type=audio|stream_index=0|pts=1024|pts_time=0.023220|dts=1024|dts_time=0.023220|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=263148|flags=K_ +packet|codec_type=audio|stream_index=0|pts=1024|pts_time=0.023220|dts=1024|dts_time=0.023220|duration=1024|duration_time=0.023220|size=2048|pos=263148|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=1024|pkt_pts_time=0.023220|pkt_dts=1024|pkt_dts_time=0.023220|best_effort_timestamp=1024|best_effort_timestamp_time=0.023220|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=263148|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown -packet|codec_type=video|stream_index=1|pts=2048|pts_time=0.040000|dts=2048|dts_time=0.040000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=265226|flags=K_ +packet|codec_type=video|stream_index=1|pts=2048|pts_time=0.040000|dts=2048|dts_time=0.040000|duration=2048|duration_time=0.040000|size=230400|pos=265226|flags=K_ frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|best_effort_timestamp=2048|best_effort_timestamp_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=265226|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified -packet|codec_type=video|stream_index=2|pts=2048|pts_time=0.040000|dts=2048|dts_time=0.040000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=495650|flags=K_ +packet|codec_type=video|stream_index=2|pts=2048|pts_time=0.040000|dts=2048|dts_time=0.040000|duration=2048|duration_time=0.040000|size=30000|pos=495650|flags=K_ frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|best_effort_timestamp=2048|best_effort_timestamp_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=495650|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified -packet|codec_type=audio|stream_index=0|pts=2048|pts_time=0.046440|dts=2048|dts_time=0.046440|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=525655|flags=K_ +packet|codec_type=audio|stream_index=0|pts=2048|pts_time=0.046440|dts=2048|dts_time=0.046440|duration=1024|duration_time=0.023220|size=2048|pos=525655|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=2048|pkt_pts_time=0.046440|pkt_dts=2048|pkt_dts_time=0.046440|best_effort_timestamp=2048|best_effort_timestamp_time=0.046440|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=525655|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=3072|pts_time=0.069660|dts=3072|dts_time=0.069660|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=527726|flags=K_ +packet|codec_type=audio|stream_index=0|pts=3072|pts_time=0.069660|dts=3072|dts_time=0.069660|duration=1024|duration_time=0.023220|size=2048|pos=527726|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=3072|pkt_pts_time=0.069660|pkt_dts=3072|pkt_dts_time=0.069660|best_effort_timestamp=3072|best_effort_timestamp_time=0.069660|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=527726|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown -packet|codec_type=video|stream_index=1|pts=4096|pts_time=0.080000|dts=4096|dts_time=0.080000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=529804|flags=K_ +packet|codec_type=video|stream_index=1|pts=4096|pts_time=0.080000|dts=4096|dts_time=0.080000|duration=2048|duration_time=0.040000|size=230400|pos=529804|flags=K_ frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|best_effort_timestamp=4096|best_effort_timestamp_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=529804|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified -packet|codec_type=video|stream_index=2|pts=4096|pts_time=0.080000|dts=4096|dts_time=0.080000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=760228|flags=K_ +packet|codec_type=video|stream_index=2|pts=4096|pts_time=0.080000|dts=4096|dts_time=0.080000|duration=2048|duration_time=0.040000|size=30000|pos=760228|flags=K_ frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|best_effort_timestamp=4096|best_effort_timestamp_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=760228|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified -packet|codec_type=audio|stream_index=0|pts=4096|pts_time=0.092880|dts=4096|dts_time=0.092880|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=790233|flags=K_ +packet|codec_type=audio|stream_index=0|pts=4096|pts_time=0.092880|dts=4096|dts_time=0.092880|duration=1024|duration_time=0.023220|size=2048|pos=790233|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=4096|pkt_pts_time=0.092880|pkt_dts=4096|pkt_dts_time=0.092880|best_effort_timestamp=4096|best_effort_timestamp_time=0.092880|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=790233|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=5120|pts_time=0.116100|dts=5120|dts_time=0.116100|duration=393|duration_time=0.008912|convergence_duration=N/A|convergence_duration_time=N/A|size=786|pos=792304|flags=K_ +packet|codec_type=audio|stream_index=0|pts=5120|pts_time=0.116100|dts=5120|dts_time=0.116100|duration=393|duration_time=0.008912|size=786|pos=792304|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=5120|pkt_pts_time=0.116100|pkt_dts=5120|pkt_dts_time=0.116100|best_effort_timestamp=5120|best_effort_timestamp_time=0.116100|pkt_duration=393|pkt_duration_time=0.008912|pkt_pos=792304|pkt_size=786|sample_fmt=s16|nb_samples=393|channels=1|channel_layout=unknown -packet|codec_type=video|stream_index=1|pts=6144|pts_time=0.120000|dts=6144|dts_time=0.120000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=793120|flags=K_ +packet|codec_type=video|stream_index=1|pts=6144|pts_time=0.120000|dts=6144|dts_time=0.120000|duration=2048|duration_time=0.040000|size=230400|pos=793120|flags=K_ frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|best_effort_timestamp=6144|best_effort_timestamp_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=793120|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified -packet|codec_type=video|stream_index=2|pts=6144|pts_time=0.120000|dts=6144|dts_time=0.120000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=1023544|flags=K_ +packet|codec_type=video|stream_index=2|pts=6144|pts_time=0.120000|dts=6144|dts_time=0.120000|duration=2048|duration_time=0.040000|size=30000|pos=1023544|flags=K_ frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|best_effort_timestamp=6144|best_effort_timestamp_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=1023544|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified -stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_time_base=1/44100|codec_tag_string=PSD[16]|codec_tag=0x10445350|sample_fmt=s16|sample_rate=44100|channels=1|channel_layout=unknown|bits_per_sample=16|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=705600|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:E=mc²|tag:encoder=Lavc pcm_s16le -stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/25|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|coded_width=320|coded_height=240|closed_captions=0|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|timecode=N/A|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt|tag:encoder=Lavc rawvideo -stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/25|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|coded_width=100|coded_height=100|closed_captions=0|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|timecode=N/A|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:encoder=Lavc rawvideo +stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_tag_string=PSD[16]|codec_tag=0x10445350|sample_fmt=s16|sample_rate=44100|channels=1|channel_layout=unknown|bits_per_sample=16|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=705600|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:E=mc²|tag:encoder=Lavc pcm_s16le +stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|coded_width=320|coded_height=240|closed_captions=0|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt|tag:encoder=Lavc rawvideo +stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|coded_width=100|coded_height=100|closed_captions=0|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:encoder=Lavc rawvideo format|filename=tests/data/ffprobe-test.nut|nb_streams=3|nb_programs=0|format_name=nut|start_time=0.000000|duration=0.120000|size=1053624|bit_rate=70241600|probe_score=100|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': |tag:comment2=I ♥ Üñîçød€ diff --git a/tests/ref/fate/ffprobe_csv b/tests/ref/fate/ffprobe_csv index 7240d1ee6..d182fde9d 100644 --- a/tests/ref/fate/ffprobe_csv +++ b/tests/ref/fate/ffprobe_csv @@ -1,32 +1,32 @@ -packet,audio,0,0,0.000000,0,0.000000,1024,0.023220,N/A,N/A,2048,647,K_ +packet,audio,0,0,0.000000,0,0.000000,1024,0.023220,2048,647,K_ frame,audio,0,1,0,0.000000,0,0.000000,0,0.000000,1024,0.023220,647,2048,s16,1024,1,unknown -packet,video,1,0,0.000000,0,0.000000,2048,0.040000,N/A,N/A,230400,2722,K_ +packet,video,1,0,0.000000,0,0.000000,2048,0.040000,230400,2722,K_ frame,video,1,1,0,0.000000,0,0.000000,0,0.000000,2048,0.040000,2722,230400,320,240,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified -packet,video,2,0,0.000000,0,0.000000,2048,0.040000,N/A,N/A,30000,233143,K_ +packet,video,2,0,0.000000,0,0.000000,2048,0.040000,30000,233143,K_ frame,video,2,1,0,0.000000,0,0.000000,0,0.000000,2048,0.040000,233143,30000,100,100,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified -packet,audio,0,1024,0.023220,1024,0.023220,1024,0.023220,N/A,N/A,2048,263148,K_ +packet,audio,0,1024,0.023220,1024,0.023220,1024,0.023220,2048,263148,K_ frame,audio,0,1,1024,0.023220,1024,0.023220,1024,0.023220,1024,0.023220,263148,2048,s16,1024,1,unknown -packet,video,1,2048,0.040000,2048,0.040000,2048,0.040000,N/A,N/A,230400,265226,K_ +packet,video,1,2048,0.040000,2048,0.040000,2048,0.040000,230400,265226,K_ frame,video,1,1,2048,0.040000,2048,0.040000,2048,0.040000,2048,0.040000,265226,230400,320,240,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified -packet,video,2,2048,0.040000,2048,0.040000,2048,0.040000,N/A,N/A,30000,495650,K_ +packet,video,2,2048,0.040000,2048,0.040000,2048,0.040000,30000,495650,K_ frame,video,2,1,2048,0.040000,2048,0.040000,2048,0.040000,2048,0.040000,495650,30000,100,100,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified -packet,audio,0,2048,0.046440,2048,0.046440,1024,0.023220,N/A,N/A,2048,525655,K_ +packet,audio,0,2048,0.046440,2048,0.046440,1024,0.023220,2048,525655,K_ frame,audio,0,1,2048,0.046440,2048,0.046440,2048,0.046440,1024,0.023220,525655,2048,s16,1024,1,unknown -packet,audio,0,3072,0.069660,3072,0.069660,1024,0.023220,N/A,N/A,2048,527726,K_ +packet,audio,0,3072,0.069660,3072,0.069660,1024,0.023220,2048,527726,K_ frame,audio,0,1,3072,0.069660,3072,0.069660,3072,0.069660,1024,0.023220,527726,2048,s16,1024,1,unknown -packet,video,1,4096,0.080000,4096,0.080000,2048,0.040000,N/A,N/A,230400,529804,K_ +packet,video,1,4096,0.080000,4096,0.080000,2048,0.040000,230400,529804,K_ frame,video,1,1,4096,0.080000,4096,0.080000,4096,0.080000,2048,0.040000,529804,230400,320,240,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified -packet,video,2,4096,0.080000,4096,0.080000,2048,0.040000,N/A,N/A,30000,760228,K_ +packet,video,2,4096,0.080000,4096,0.080000,2048,0.040000,30000,760228,K_ frame,video,2,1,4096,0.080000,4096,0.080000,4096,0.080000,2048,0.040000,760228,30000,100,100,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified -packet,audio,0,4096,0.092880,4096,0.092880,1024,0.023220,N/A,N/A,2048,790233,K_ +packet,audio,0,4096,0.092880,4096,0.092880,1024,0.023220,2048,790233,K_ frame,audio,0,1,4096,0.092880,4096,0.092880,4096,0.092880,1024,0.023220,790233,2048,s16,1024,1,unknown -packet,audio,0,5120,0.116100,5120,0.116100,393,0.008912,N/A,N/A,786,792304,K_ +packet,audio,0,5120,0.116100,5120,0.116100,393,0.008912,786,792304,K_ frame,audio,0,1,5120,0.116100,5120,0.116100,5120,0.116100,393,0.008912,792304,786,s16,393,1,unknown -packet,video,1,6144,0.120000,6144,0.120000,2048,0.040000,N/A,N/A,230400,793120,K_ +packet,video,1,6144,0.120000,6144,0.120000,2048,0.040000,230400,793120,K_ frame,video,1,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,793120,230400,320,240,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified -packet,video,2,6144,0.120000,6144,0.120000,2048,0.040000,N/A,N/A,30000,1023544,K_ +packet,video,2,6144,0.120000,6144,0.120000,2048,0.040000,30000,1023544,K_ frame,video,2,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,1023544,30000,100,100,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified -stream,0,pcm_s16le,unknown,audio,1/44100,PSD[16],0x10445350,s16,44100,1,unknown,16,N/A,0/0,0/0,1/44100,0,0.000000,N/A,N/A,705600,N/A,N/A,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,0,mc²,Lavc pcm_s16le -stream,1,rawvideo,unknown,video,1/25,RGB[24],0x18424752,320,240,320,240,0,0,1:1,4:3,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,N/A,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt,Lavc rawvideo -stream,2,rawvideo,unknown,video,1/25,RGB[24],0x18424752,100,100,100,100,0,0,1:1,1:1,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,N/A,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo +stream,0,pcm_s16le,unknown,audio,PSD[16],0x10445350,s16,44100,1,unknown,16,N/A,0/0,0/0,1/44100,0,0.000000,N/A,N/A,705600,N/A,N/A,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,0,mc²,Lavc pcm_s16le +stream,1,rawvideo,unknown,video,RGB[24],0x18424752,320,240,320,240,0,0,1:1,4:3,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt,Lavc rawvideo +stream,2,rawvideo,unknown,video,RGB[24],0x18424752,100,100,100,100,0,0,1:1,1:1,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo format,tests/data/ffprobe-test.nut,3,0,nut,0.000000,0.120000,1053624,70241600,100,ffprobe test file,"'A comment with CSV, XML & JSON special chars': ",I ♥ Üñîçød€ diff --git a/tests/ref/fate/ffprobe_default b/tests/ref/fate/ffprobe_default index 0c2908c5a..fd36ecfc5 100644 --- a/tests/ref/fate/ffprobe_default +++ b/tests/ref/fate/ffprobe_default @@ -7,8 +7,6 @@ dts=0 dts_time=0.000000 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=647 flags=K_ @@ -41,8 +39,6 @@ dts=0 dts_time=0.000000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=230400 pos=2722 flags=K_ @@ -86,8 +82,6 @@ dts=0 dts_time=0.000000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=30000 pos=233143 flags=K_ @@ -131,8 +125,6 @@ dts=1024 dts_time=0.023220 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=263148 flags=K_ @@ -165,8 +157,6 @@ dts=2048 dts_time=0.040000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=230400 pos=265226 flags=K_ @@ -210,8 +200,6 @@ dts=2048 dts_time=0.040000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=30000 pos=495650 flags=K_ @@ -255,8 +243,6 @@ dts=2048 dts_time=0.046440 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=525655 flags=K_ @@ -289,8 +275,6 @@ dts=3072 dts_time=0.069660 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=527726 flags=K_ @@ -323,8 +307,6 @@ dts=4096 dts_time=0.080000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=230400 pos=529804 flags=K_ @@ -368,8 +350,6 @@ dts=4096 dts_time=0.080000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=30000 pos=760228 flags=K_ @@ -413,8 +393,6 @@ dts=4096 dts_time=0.092880 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=790233 flags=K_ @@ -447,8 +425,6 @@ dts=5120 dts_time=0.116100 duration=393 duration_time=0.008912 -convergence_duration=N/A -convergence_duration_time=N/A size=786 pos=792304 flags=K_ @@ -481,8 +457,6 @@ dts=6144 dts_time=0.120000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=230400 pos=793120 flags=K_ @@ -526,8 +500,6 @@ dts=6144 dts_time=0.120000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=30000 pos=1023544 flags=K_ @@ -567,7 +539,6 @@ index=0 codec_name=pcm_s16le profile=unknown codec_type=audio -codec_time_base=1/44100 codec_tag_string=PSD[16] codec_tag=0x10445350 sample_fmt=s16 @@ -609,7 +580,6 @@ index=1 codec_name=rawvideo profile=unknown codec_type=video -codec_time_base=1/25 codec_tag_string=RGB[24] codec_tag=0x18424752 width=320 @@ -628,7 +598,6 @@ color_transfer=unknown color_primaries=unknown chroma_location=unspecified field_order=unknown -timecode=N/A refs=1 id=N/A r_frame_rate=25/1 @@ -665,7 +634,6 @@ index=2 codec_name=rawvideo profile=unknown codec_type=video -codec_time_base=1/25 codec_tag_string=RGB[24] codec_tag=0x18424752 width=100 @@ -684,7 +652,6 @@ color_transfer=unknown color_primaries=unknown chroma_location=unspecified field_order=unknown -timecode=N/A refs=1 id=N/A r_frame_rate=25/1 diff --git a/tests/ref/fate/ffprobe_flat b/tests/ref/fate/ffprobe_flat index b2437ce49..8d95cf6cb 100644 --- a/tests/ref/fate/ffprobe_flat +++ b/tests/ref/fate/ffprobe_flat @@ -6,8 +6,6 @@ packets_and_frames.packet.0.dts=0 packets_and_frames.packet.0.dts_time="0.000000" packets_and_frames.packet.0.duration=1024 packets_and_frames.packet.0.duration_time="0.023220" -packets_and_frames.packet.0.convergence_duration="N/A" -packets_and_frames.packet.0.convergence_duration_time="N/A" packets_and_frames.packet.0.size="2048" packets_and_frames.packet.0.pos="647" packets_and_frames.packet.0.flags="K_" @@ -36,8 +34,6 @@ packets_and_frames.packet.1.dts=0 packets_and_frames.packet.1.dts_time="0.000000" packets_and_frames.packet.1.duration=2048 packets_and_frames.packet.1.duration_time="0.040000" -packets_and_frames.packet.1.convergence_duration="N/A" -packets_and_frames.packet.1.convergence_duration_time="N/A" packets_and_frames.packet.1.size="230400" packets_and_frames.packet.1.pos="2722" packets_and_frames.packet.1.flags="K_" @@ -77,8 +73,6 @@ packets_and_frames.packet.2.dts=0 packets_and_frames.packet.2.dts_time="0.000000" packets_and_frames.packet.2.duration=2048 packets_and_frames.packet.2.duration_time="0.040000" -packets_and_frames.packet.2.convergence_duration="N/A" -packets_and_frames.packet.2.convergence_duration_time="N/A" packets_and_frames.packet.2.size="30000" packets_and_frames.packet.2.pos="233143" packets_and_frames.packet.2.flags="K_" @@ -118,8 +112,6 @@ packets_and_frames.packet.3.dts=1024 packets_and_frames.packet.3.dts_time="0.023220" packets_and_frames.packet.3.duration=1024 packets_and_frames.packet.3.duration_time="0.023220" -packets_and_frames.packet.3.convergence_duration="N/A" -packets_and_frames.packet.3.convergence_duration_time="N/A" packets_and_frames.packet.3.size="2048" packets_and_frames.packet.3.pos="263148" packets_and_frames.packet.3.flags="K_" @@ -148,8 +140,6 @@ packets_and_frames.packet.4.dts=2048 packets_and_frames.packet.4.dts_time="0.040000" packets_and_frames.packet.4.duration=2048 packets_and_frames.packet.4.duration_time="0.040000" -packets_and_frames.packet.4.convergence_duration="N/A" -packets_and_frames.packet.4.convergence_duration_time="N/A" packets_and_frames.packet.4.size="230400" packets_and_frames.packet.4.pos="265226" packets_and_frames.packet.4.flags="K_" @@ -189,8 +179,6 @@ packets_and_frames.packet.5.dts=2048 packets_and_frames.packet.5.dts_time="0.040000" packets_and_frames.packet.5.duration=2048 packets_and_frames.packet.5.duration_time="0.040000" -packets_and_frames.packet.5.convergence_duration="N/A" -packets_and_frames.packet.5.convergence_duration_time="N/A" packets_and_frames.packet.5.size="30000" packets_and_frames.packet.5.pos="495650" packets_and_frames.packet.5.flags="K_" @@ -230,8 +218,6 @@ packets_and_frames.packet.6.dts=2048 packets_and_frames.packet.6.dts_time="0.046440" packets_and_frames.packet.6.duration=1024 packets_and_frames.packet.6.duration_time="0.023220" -packets_and_frames.packet.6.convergence_duration="N/A" -packets_and_frames.packet.6.convergence_duration_time="N/A" packets_and_frames.packet.6.size="2048" packets_and_frames.packet.6.pos="525655" packets_and_frames.packet.6.flags="K_" @@ -260,8 +246,6 @@ packets_and_frames.packet.7.dts=3072 packets_and_frames.packet.7.dts_time="0.069660" packets_and_frames.packet.7.duration=1024 packets_and_frames.packet.7.duration_time="0.023220" -packets_and_frames.packet.7.convergence_duration="N/A" -packets_and_frames.packet.7.convergence_duration_time="N/A" packets_and_frames.packet.7.size="2048" packets_and_frames.packet.7.pos="527726" packets_and_frames.packet.7.flags="K_" @@ -290,8 +274,6 @@ packets_and_frames.packet.8.dts=4096 packets_and_frames.packet.8.dts_time="0.080000" packets_and_frames.packet.8.duration=2048 packets_and_frames.packet.8.duration_time="0.040000" -packets_and_frames.packet.8.convergence_duration="N/A" -packets_and_frames.packet.8.convergence_duration_time="N/A" packets_and_frames.packet.8.size="230400" packets_and_frames.packet.8.pos="529804" packets_and_frames.packet.8.flags="K_" @@ -331,8 +313,6 @@ packets_and_frames.packet.9.dts=4096 packets_and_frames.packet.9.dts_time="0.080000" packets_and_frames.packet.9.duration=2048 packets_and_frames.packet.9.duration_time="0.040000" -packets_and_frames.packet.9.convergence_duration="N/A" -packets_and_frames.packet.9.convergence_duration_time="N/A" packets_and_frames.packet.9.size="30000" packets_and_frames.packet.9.pos="760228" packets_and_frames.packet.9.flags="K_" @@ -372,8 +352,6 @@ packets_and_frames.packet.10.dts=4096 packets_and_frames.packet.10.dts_time="0.092880" packets_and_frames.packet.10.duration=1024 packets_and_frames.packet.10.duration_time="0.023220" -packets_and_frames.packet.10.convergence_duration="N/A" -packets_and_frames.packet.10.convergence_duration_time="N/A" packets_and_frames.packet.10.size="2048" packets_and_frames.packet.10.pos="790233" packets_and_frames.packet.10.flags="K_" @@ -402,8 +380,6 @@ packets_and_frames.packet.11.dts=5120 packets_and_frames.packet.11.dts_time="0.116100" packets_and_frames.packet.11.duration=393 packets_and_frames.packet.11.duration_time="0.008912" -packets_and_frames.packet.11.convergence_duration="N/A" -packets_and_frames.packet.11.convergence_duration_time="N/A" packets_and_frames.packet.11.size="786" packets_and_frames.packet.11.pos="792304" packets_and_frames.packet.11.flags="K_" @@ -432,8 +408,6 @@ packets_and_frames.packet.12.dts=6144 packets_and_frames.packet.12.dts_time="0.120000" packets_and_frames.packet.12.duration=2048 packets_and_frames.packet.12.duration_time="0.040000" -packets_and_frames.packet.12.convergence_duration="N/A" -packets_and_frames.packet.12.convergence_duration_time="N/A" packets_and_frames.packet.12.size="230400" packets_and_frames.packet.12.pos="793120" packets_and_frames.packet.12.flags="K_" @@ -473,8 +447,6 @@ packets_and_frames.packet.13.dts=6144 packets_and_frames.packet.13.dts_time="0.120000" packets_and_frames.packet.13.duration=2048 packets_and_frames.packet.13.duration_time="0.040000" -packets_and_frames.packet.13.convergence_duration="N/A" -packets_and_frames.packet.13.convergence_duration_time="N/A" packets_and_frames.packet.13.size="30000" packets_and_frames.packet.13.pos="1023544" packets_and_frames.packet.13.flags="K_" @@ -510,7 +482,6 @@ streams.stream.0.index=0 streams.stream.0.codec_name="pcm_s16le" streams.stream.0.profile="unknown" streams.stream.0.codec_type="audio" -streams.stream.0.codec_time_base="1/44100" streams.stream.0.codec_tag_string="PSD[16]" streams.stream.0.codec_tag="0x10445350" streams.stream.0.sample_fmt="s16" @@ -550,7 +521,6 @@ streams.stream.1.index=1 streams.stream.1.codec_name="rawvideo" streams.stream.1.profile="unknown" streams.stream.1.codec_type="video" -streams.stream.1.codec_time_base="1/25" streams.stream.1.codec_tag_string="RGB[24]" streams.stream.1.codec_tag="0x18424752" streams.stream.1.width=320 @@ -569,7 +539,6 @@ streams.stream.1.color_transfer="unknown" streams.stream.1.color_primaries="unknown" streams.stream.1.chroma_location="unspecified" streams.stream.1.field_order="unknown" -streams.stream.1.timecode="N/A" streams.stream.1.refs=1 streams.stream.1.id="N/A" streams.stream.1.r_frame_rate="25/1" @@ -604,7 +573,6 @@ streams.stream.2.index=2 streams.stream.2.codec_name="rawvideo" streams.stream.2.profile="unknown" streams.stream.2.codec_type="video" -streams.stream.2.codec_time_base="1/25" streams.stream.2.codec_tag_string="RGB[24]" streams.stream.2.codec_tag="0x18424752" streams.stream.2.width=100 @@ -623,7 +591,6 @@ streams.stream.2.color_transfer="unknown" streams.stream.2.color_primaries="unknown" streams.stream.2.chroma_location="unspecified" streams.stream.2.field_order="unknown" -streams.stream.2.timecode="N/A" streams.stream.2.refs=1 streams.stream.2.id="N/A" streams.stream.2.r_frame_rate="25/1" diff --git a/tests/ref/fate/ffprobe_ini b/tests/ref/fate/ffprobe_ini index f2cff7627..16302370c 100644 --- a/tests/ref/fate/ffprobe_ini +++ b/tests/ref/fate/ffprobe_ini @@ -9,8 +9,6 @@ dts=0 dts_time=0.000000 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=647 flags=K_ @@ -43,8 +41,6 @@ dts=0 dts_time=0.000000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=230400 pos=2722 flags=K_ @@ -88,8 +84,6 @@ dts=0 dts_time=0.000000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=30000 pos=233143 flags=K_ @@ -133,8 +127,6 @@ dts=1024 dts_time=0.023220 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=263148 flags=K_ @@ -167,8 +159,6 @@ dts=2048 dts_time=0.040000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=230400 pos=265226 flags=K_ @@ -212,8 +202,6 @@ dts=2048 dts_time=0.040000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=30000 pos=495650 flags=K_ @@ -257,8 +245,6 @@ dts=2048 dts_time=0.046440 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=525655 flags=K_ @@ -291,8 +277,6 @@ dts=3072 dts_time=0.069660 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=527726 flags=K_ @@ -325,8 +309,6 @@ dts=4096 dts_time=0.080000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=230400 pos=529804 flags=K_ @@ -370,8 +352,6 @@ dts=4096 dts_time=0.080000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=30000 pos=760228 flags=K_ @@ -415,8 +395,6 @@ dts=4096 dts_time=0.092880 duration=1024 duration_time=0.023220 -convergence_duration=N/A -convergence_duration_time=N/A size=2048 pos=790233 flags=K_ @@ -449,8 +427,6 @@ dts=5120 dts_time=0.116100 duration=393 duration_time=0.008912 -convergence_duration=N/A -convergence_duration_time=N/A size=786 pos=792304 flags=K_ @@ -483,8 +459,6 @@ dts=6144 dts_time=0.120000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=230400 pos=793120 flags=K_ @@ -528,8 +502,6 @@ dts=6144 dts_time=0.120000 duration=2048 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=30000 pos=1023544 flags=K_ @@ -569,7 +541,6 @@ index=0 codec_name=pcm_s16le profile=unknown codec_type=audio -codec_time_base=1/44100 codec_tag_string=PSD[16] codec_tag=0x10445350 sample_fmt=s16 @@ -615,7 +586,6 @@ index=1 codec_name=rawvideo profile=unknown codec_type=video -codec_time_base=1/25 codec_tag_string=RGB[24] codec_tag=0x18424752 width=320 @@ -634,7 +604,6 @@ color_transfer=unknown color_primaries=unknown chroma_location=unspecified field_order=unknown -timecode=N/A refs=1 id=N/A r_frame_rate=25/1 @@ -675,7 +644,6 @@ index=2 codec_name=rawvideo profile=unknown codec_type=video -codec_time_base=1/25 codec_tag_string=RGB[24] codec_tag=0x18424752 width=100 @@ -694,7 +662,6 @@ color_transfer=unknown color_primaries=unknown chroma_location=unspecified field_order=unknown -timecode=N/A refs=1 id=N/A r_frame_rate=25/1 diff --git a/tests/ref/fate/ffprobe_json b/tests/ref/fate/ffprobe_json index 7b88e1a84..154f2ac58 100644 --- a/tests/ref/fate/ffprobe_json +++ b/tests/ref/fate/ffprobe_json @@ -524,7 +524,6 @@ "index": 0, "codec_name": "pcm_s16le", "codec_type": "audio", - "codec_time_base": "1/44100", "codec_tag_string": "PSD[16]", "codec_tag": "0x10445350", "sample_fmt": "s16", @@ -562,7 +561,6 @@ "index": 1, "codec_name": "rawvideo", "codec_type": "video", - "codec_time_base": "1/25", "codec_tag_string": "RGB[24]", "codec_tag": "0x18424752", "width": 320, @@ -607,7 +605,6 @@ "index": 2, "codec_name": "rawvideo", "codec_type": "video", - "codec_time_base": "1/25", "codec_tag_string": "RGB[24]", "codec_tag": "0x18424752", "width": 100, diff --git a/tests/ref/fate/ffprobe_xml b/tests/ref/fate/ffprobe_xml index ccea2874b..04261ed69 100644 --- a/tests/ref/fate/ffprobe_xml +++ b/tests/ref/fate/ffprobe_xml @@ -32,18 +32,18 @@ - + - + - + @@ -51,7 +51,7 @@ - + diff --git a/tests/ref/fate/filter-colorbalance b/tests/ref/fate/filter-colorbalance index 0be1f1c85..15491fe67 100644 --- a/tests/ref/fate/filter-colorbalance +++ b/tests/ref/fate/filter-colorbalance @@ -3,6 +3,6 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 304128, 0x3451c8eb -0, 1, 1, 1, 304128, 0x2107daa0 -0, 2, 2, 1, 304128, 0xcda7aa33 +0, 0, 0, 1, 304128, 0xf68fadfd +0, 1, 1, 1, 304128, 0xa6302d9a +0, 2, 2, 1, 304128, 0x758d165a diff --git a/tests/ref/fate/filter-colorbalance-gbrap b/tests/ref/fate/filter-colorbalance-gbrap index 2e9960182..2d76c7d08 100644 --- a/tests/ref/fate/filter-colorbalance-gbrap +++ b/tests/ref/fate/filter-colorbalance-gbrap @@ -3,6 +3,6 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 405504, 0xad0f2d82 -0, 1, 1, 1, 405504, 0x81d7d31f -0, 2, 2, 1, 405504, 0x40c5e836 +0, 0, 0, 1, 405504, 0xdcc71df0 +0, 1, 1, 1, 405504, 0x48d56675 +0, 2, 2, 1, 405504, 0x68058bf0 diff --git a/tests/ref/fate/filter-colorbalance-gbrap-16 b/tests/ref/fate/filter-colorbalance-gbrap-16 index 4ce323557..2ab96ad70 100644 --- a/tests/ref/fate/filter-colorbalance-gbrap-16 +++ b/tests/ref/fate/filter-colorbalance-gbrap-16 @@ -3,6 +3,6 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 405504, 0xa97c136c -0, 1, 1, 1, 405504, 0x0a120697 -0, 2, 2, 1, 405504, 0x85b133ff +0, 0, 0, 1, 405504, 0xa497ca1b +0, 1, 1, 1, 405504, 0x92c24b0e +0, 2, 2, 1, 405504, 0x965270bd diff --git a/tests/ref/fate/filter-colorbalance-rgba64 b/tests/ref/fate/filter-colorbalance-rgba64 index f6fcfee25..605860dee 100644 --- a/tests/ref/fate/filter-colorbalance-rgba64 +++ b/tests/ref/fate/filter-colorbalance-rgba64 @@ -3,6 +3,6 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 811008, 0xa67db91d -0, 1, 1, 1, 811008, 0x0846578a -0, 2, 2, 1, 811008, 0x77af61f8 +0, 0, 0, 1, 811008, 0xc5f7e6ba +0, 1, 1, 1, 811008, 0x266955bf +0, 2, 2, 1, 811008, 0x55360c6e diff --git a/tests/ref/fate/filter-earwax b/tests/ref/fate/filter-earwax index 855f579ca..6bfa725b6 100644 --- a/tests/ref/fate/filter-earwax +++ b/tests/ref/fate/filter-earwax @@ -4,23 +4,23 @@ #sample_rate 0: 44100 #channel_layout 0: 3 #channel_layout_name 0: stereo -0, 0, 0, 1024, 4096, 0x900af751 -0, 1024, 1024, 1024, 4096, 0xad570065 -0, 2048, 2048, 1024, 4096, 0x93d5f494 -0, 3072, 3072, 1024, 4096, 0x2c65ef7d -0, 4096, 4096, 1024, 4096, 0xdc8af6d2 -0, 5120, 5120, 1024, 4096, 0x7ae00249 -0, 6144, 6144, 1024, 4096, 0xaab5fdd0 -0, 7168, 7168, 1024, 4096, 0x4373ef39 -0, 8192, 8192, 1024, 4096, 0x0756eb43 -0, 9216, 9216, 1024, 4096, 0x494d06e0 -0, 10240, 10240, 1024, 4096, 0x4393ffae -0, 11264, 11264, 1024, 4096, 0x6972f97e -0, 12288, 12288, 1024, 4096, 0xb834ea05 -0, 13312, 13312, 1024, 4096, 0x39b8f871 -0, 14336, 14336, 1024, 4096, 0xf032fccd -0, 15360, 15360, 1024, 4096, 0xefcd0709 -0, 16384, 16384, 1024, 4096, 0x0590ebc0 -0, 17408, 17408, 1024, 4096, 0x2e75f264 -0, 18432, 18432, 1024, 4096, 0xbea1fd03 -0, 19456, 19456, 1024, 4096, 0x9bbe0434 +0, 0, 0, 1024, 4096, 0xb7e1f437 +0, 1024, 1024, 1024, 4096, 0xa031042a +0, 2048, 2048, 1024, 4096, 0x9b72ed0f +0, 3072, 3072, 1024, 4096, 0xff14ed33 +0, 4096, 4096, 1024, 4096, 0x96eef519 +0, 5120, 5120, 1024, 4096, 0x290d0ca0 +0, 6144, 6144, 1024, 4096, 0x0393fbf5 +0, 7168, 7168, 1024, 4096, 0xed89ef59 +0, 8192, 8192, 1024, 4096, 0xf664e969 +0, 9216, 9216, 1024, 4096, 0x261a05e4 +0, 10240, 10240, 1024, 4096, 0xc334ff5b +0, 11264, 11264, 1024, 4096, 0x030ffa65 +0, 12288, 12288, 1024, 4096, 0xcfb4e835 +0, 13312, 13312, 1024, 4096, 0xd9adf7ff +0, 14336, 14336, 1024, 4096, 0x5e9001ae +0, 15360, 15360, 1024, 4096, 0xbfaf0174 +0, 16384, 16384, 1024, 4096, 0x8cf3f061 +0, 17408, 17408, 1024, 4096, 0x35ffece5 +0, 18432, 18432, 1024, 4096, 0x1de801e2 +0, 19456, 19456, 1024, 4096, 0xa1a40372 diff --git a/tests/ref/fate/filter-edgedetect b/tests/ref/fate/filter-edgedetect index 23c9953e6..e49639afa 100644 --- a/tests/ref/fate/filter-edgedetect +++ b/tests/ref/fate/filter-edgedetect @@ -1 +1 @@ -edgedetect 93ceace33f6636bcdbeb037317c65745 +edgedetect 04ff46bb35edff3dbad4102391516d25 diff --git a/tests/ref/fate/filter-edgedetect-colormix b/tests/ref/fate/filter-edgedetect-colormix index e828c6bd1..0df17344b 100644 --- a/tests/ref/fate/filter-edgedetect-colormix +++ b/tests/ref/fate/filter-edgedetect-colormix @@ -1 +1 @@ -edgedetect-colormix 1b8658252e2f03fbae30e6d63dd24c7c +edgedetect-colormix 9f50c5586f899a8f5a10059154d64bde diff --git a/tests/ref/fate/filter-fps-down b/tests/ref/fate/filter-fps-down index eb8b36898..0b6725f03 100644 --- a/tests/ref/fate/filter-fps-down +++ b/tests/ref/fate/filter-fps-down @@ -13,3 +13,4 @@ 0, 7, 7, 1, 115200, 0xc705ccd9 0, 8, 8, 1, 115200, 0x5635daa5 0, 9, 9, 1, 115200, 0x7161ef8f +0, 10, 10, 1, 115200, 0xccf02fed diff --git a/tests/ref/fate/filter-fps-up b/tests/ref/fate/filter-fps-up index f1a847864..dfb957c63 100644 --- a/tests/ref/fate/filter-fps-up +++ b/tests/ref/fate/filter-fps-up @@ -15,3 +15,5 @@ 0, 9, 9, 1, 115200, 0xb0dfacf8 0, 10, 10, 1, 115200, 0xb0dfacf8 0, 11, 11, 1, 115200, 0xb0dfacf8 +0, 12, 12, 1, 115200, 0x53d5b181 +0, 13, 13, 1, 115200, 0x53d5b181 diff --git a/tests/ref/fate/filter-fps-up-round-down b/tests/ref/fate/filter-fps-up-round-down index daecb125e..b68e4fe97 100644 --- a/tests/ref/fate/filter-fps-up-round-down +++ b/tests/ref/fate/filter-fps-up-round-down @@ -14,3 +14,6 @@ 0, 8, 8, 1, 115200, 0x33f15918 0, 9, 9, 1, 115200, 0xb0dfacf8 0, 10, 10, 1, 115200, 0xb0dfacf8 +0, 11, 11, 1, 115200, 0x53d5b181 +0, 12, 12, 1, 115200, 0x53d5b181 +0, 13, 13, 1, 115200, 0x53d5b181 diff --git a/tests/ref/fate/filter-fps-up-round-up b/tests/ref/fate/filter-fps-up-round-up index d69dbf67f..692c1d6c6 100644 --- a/tests/ref/fate/filter-fps-up-round-up +++ b/tests/ref/fate/filter-fps-up-round-up @@ -15,3 +15,5 @@ 0, 9, 9, 1, 115200, 0x33f15918 0, 10, 10, 1, 115200, 0xb0dfacf8 0, 11, 11, 1, 115200, 0xb0dfacf8 +0, 12, 12, 1, 115200, 0x53d5b181 +0, 13, 13, 1, 115200, 0x53d5b181 diff --git a/tests/ref/fate/filter-minterpolate-up b/tests/ref/fate/filter-minterpolate-up index a276bf660..186299078 100644 --- a/tests/ref/fate/filter-minterpolate-up +++ b/tests/ref/fate/filter-minterpolate-up @@ -4,12 +4,12 @@ #dimensions 0: 320x240 #sar 0: 1/1 0, 0, 0, 1, 115200, 0x3744b3ed -0, 1, 1, 1, 115200, 0xec1fdfa0 -0, 2, 2, 1, 115200, 0xa17f0d74 -0, 3, 3, 1, 115200, 0xd72532a9 -0, 4, 4, 1, 115200, 0x032e60f8 +0, 1, 1, 1, 115200, 0xf54dba9a +0, 2, 2, 1, 115200, 0xd0b30f49 +0, 3, 3, 1, 115200, 0x61720dac +0, 4, 4, 1, 115200, 0xb93a0baa 0, 5, 5, 1, 115200, 0x6e318ba0 -0, 6, 6, 1, 115200, 0x76018292 -0, 7, 7, 1, 115200, 0x89e27599 -0, 8, 8, 1, 115200, 0x68536eac -0, 9, 9, 1, 115200, 0xc3ac62a8 +0, 6, 6, 1, 115200, 0xbce5157a +0, 7, 7, 1, 115200, 0xe16418a3 +0, 8, 8, 1, 115200, 0xdd91079c +0, 9, 9, 1, 115200, 0xdf69f73c diff --git a/tests/ref/fate/filter-mpdecimate b/tests/ref/fate/filter-mpdecimate index 9c1dc3656..d438dacc2 100644 --- a/tests/ref/fate/filter-mpdecimate +++ b/tests/ref/fate/filter-mpdecimate @@ -22,3 +22,4 @@ 0, 24, 24, 1, 115200, 0x056d40ca 0, 26, 26, 1, 115200, 0xa4374737 0, 27, 27, 1, 115200, 0x3eaa3ae8 +0, 29, 29, 1, 115200, 0x7551e9ee diff --git a/tests/ref/fate/filter-overlay_yuv420p10 b/tests/ref/fate/filter-overlay_yuv420p10 new file mode 100644 index 000000000..b431dc6cc --- /dev/null +++ b/tests/ref/fate/filter-overlay_yuv420p10 @@ -0,0 +1,8 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 352x288 +#sar 0: 0/1 +0, 0, 0, 1, 304128, 0x29a6ca86 +0, 1, 1, 1, 304128, 0x82950e6f +0, 2, 2, 1, 304128, 0x8363d1d8 diff --git a/tests/ref/fate/filter-overlay_yuv422p10 b/tests/ref/fate/filter-overlay_yuv422p10 new file mode 100644 index 000000000..393c08169 --- /dev/null +++ b/tests/ref/fate/filter-overlay_yuv422p10 @@ -0,0 +1,8 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 352x288 +#sar 0: 0/1 +0, 0, 0, 1, 405504, 0x11108b36 +0, 1, 1, 1, 405504, 0x9d5f7c2a +0, 2, 2, 1, 405504, 0x25373098 diff --git a/tests/ref/fate/filter-pixdesc-x2rgb10le b/tests/ref/fate/filter-pixdesc-x2rgb10le new file mode 100644 index 000000000..94c8640a5 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-x2rgb10le @@ -0,0 +1 @@ +pixdesc-x2rgb10le 98d697ed4668daf535163d5e08c903bb diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy index 45fe1be21..1d7657c2a 100644 --- a/tests/ref/fate/filter-pixfmts-copy +++ b/tests/ref/fate/filter-pixfmts-copy @@ -80,6 +80,7 @@ rgba b6e1b441c365e03b5ffdf9b7b68d9a0c rgba64be ae2ae04b5efedca3505f47c4dd6ea6ea rgba64le b91e1d77f799eb92241a2d2d28437b15 uyvy422 3bcf3c80047592f2211fae3260b1b65d +x2rgb10le b0a0c8056521beeaa3fea4985ca87176 xyz12be a1ef56bf746d71f59669c28e48fc8450 xyz12le 831ff03c1ba4ef19374686f16a064d8c ya16be 37c07787e544f900c87b853253bfc8dd diff --git a/tests/ref/fate/filter-pixfmts-crop b/tests/ref/fate/filter-pixfmts-crop index 430e90e19..8fc761419 100644 --- a/tests/ref/fate/filter-pixfmts-crop +++ b/tests/ref/fate/filter-pixfmts-crop @@ -77,6 +77,7 @@ rgb8 9b364a8f112ad9459fec47a51cc03b30 rgba 9488ac85abceaf99a9309eac5a87697e rgba64be 89910046972ab3c68e2a348302cc8ca9 rgba64le fea8ebfc869b52adf353778f29eac7a7 +x2rgb10le 5c0789f76a713f343c2ed42a371d441d xyz12be cb4571f9aaa7b59f999ef327276104b7 xyz12le cd6aae8d26b18bdb4b9d068586276d91 ya16be a3d18014454942a96f15a49947c0c55d diff --git a/tests/ref/fate/filter-pixfmts-field b/tests/ref/fate/filter-pixfmts-field index b5f7013af..ce8e53571 100644 --- a/tests/ref/fate/filter-pixfmts-field +++ b/tests/ref/fate/filter-pixfmts-field @@ -80,6 +80,7 @@ rgba ee616262ca6d67b7ecfba4b36c602ce3 rgba64be 23c8c0edaabe3eaec89ce69633fb0048 rgba64le dfdba4de4a7cac9abf08852666c341d3 uyvy422 1c49e44ab3f060e85fc4a3a9464f045e +x2rgb10le a7a5dcdfe1d4b6bd71e40b01c735f144 xyz12be d2fa69ec91d3ed862f2dac3f8e7a3437 xyz12le 02bccd5e0b6824779a1f848b0ea3e3b5 ya16be 40403b5277364777e0671da4d38e01ac diff --git a/tests/ref/fate/filter-pixfmts-fieldorder b/tests/ref/fate/filter-pixfmts-fieldorder index dfc464ff8..90d36add8 100644 --- a/tests/ref/fate/filter-pixfmts-fieldorder +++ b/tests/ref/fate/filter-pixfmts-fieldorder @@ -71,6 +71,7 @@ rgba 1fdf872a087a32cd35b80cc7be399578 rgba64be 5598f44514d122b9a57c5c92c20bbc61 rgba64le b34e6e30621ae579519a2d91a96a0acf uyvy422 75de70e31c435dde878002d3f22b238a +x2rgb10le 636c90498c64abba1cc0624c5209a61f xyz12be 15f5cda71de5fef9cec5e75e3833b6bc xyz12le 7be6c8781f38c21a6b8f602f62ca31e6 ya16be 0f13e0f52586d172aaa07710fa3e8f31 diff --git a/tests/ref/fate/filter-pixfmts-hflip b/tests/ref/fate/filter-pixfmts-hflip index 8b8c659fc..0d40b93e9 100644 --- a/tests/ref/fate/filter-pixfmts-hflip +++ b/tests/ref/fate/filter-pixfmts-hflip @@ -77,6 +77,7 @@ rgb8 68a3a575badadd9e4f90226209f11699 rgba 51961c723ea6707e0a410cd3f21f15d3 rgba64be c910444019f4cfbf4d995227af55da8d rgba64le 0c810d8b3a6bca10321788e1cb145340 +x2rgb10le 9f99dce306383daf25cd1542b2517fef xyz12be 25f90259ff8a226befdaec3dfe82996e xyz12le 926c0791d59aaff61b2778e8ada3316d ya16be d5b342355bdd9e3197e01b13b7c6301e diff --git a/tests/ref/fate/filter-pixfmts-il b/tests/ref/fate/filter-pixfmts-il index 1c7e94643..d1bc86695 100644 --- a/tests/ref/fate/filter-pixfmts-il +++ b/tests/ref/fate/filter-pixfmts-il @@ -79,6 +79,7 @@ rgba 625d8f4bd39c4bdbf61eb5e4713aecc9 rgba64be db70d33aa6c06f3e0a1c77bd11284261 rgba64le a8a2daae04374a27219bc1c890204007 uyvy422 d6ee3ca43356d08c392382b24b22cda5 +x2rgb10le a01ea7dd339e028780e04971012d826d xyz12be 7c7d54c55f136cbbc50b18029f3be0b3 xyz12le 090ba6b1170baf2b1358b43b971d33b0 ya16be 7bc720918bc0132e9717acbde89874e0 diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null index 45fe1be21..1d7657c2a 100644 --- a/tests/ref/fate/filter-pixfmts-null +++ b/tests/ref/fate/filter-pixfmts-null @@ -80,6 +80,7 @@ rgba b6e1b441c365e03b5ffdf9b7b68d9a0c rgba64be ae2ae04b5efedca3505f47c4dd6ea6ea rgba64le b91e1d77f799eb92241a2d2d28437b15 uyvy422 3bcf3c80047592f2211fae3260b1b65d +x2rgb10le b0a0c8056521beeaa3fea4985ca87176 xyz12be a1ef56bf746d71f59669c28e48fc8450 xyz12le 831ff03c1ba4ef19374686f16a064d8c ya16be 37c07787e544f900c87b853253bfc8dd diff --git a/tests/ref/fate/filter-pixfmts-pad b/tests/ref/fate/filter-pixfmts-pad index 56482cf89..9a5db8254 100644 --- a/tests/ref/fate/filter-pixfmts-pad +++ b/tests/ref/fate/filter-pixfmts-pad @@ -28,6 +28,7 @@ nv42 1738ad3c31c6c16e17679f5b09ce4677 rgb0 78d500c8361ab6423a4826a00268c908 rgb24 17f9e2e0c609009acaf2175c42d4a2a5 rgba b157c90191463d34fb3ce77b36c96386 +x2rgb10le c240f8a8dfa647c57c0974d061c9652a xyz12le 85abf80b77a9236a76ba0b00fcbdea2d ya16le 940fafa240b9916de5f73cb20a552f24 ya8 5fc0f471207ddf7aa01b07027d56b672 diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index 1e5c7db3d..f47c9b887 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -19,27 +19,27 @@ bgra d8316272bc3a360ef9dff3ecc84520a3 bgra64be 4e6a1b9f9c18b881c27d76611d45f737 bgra64le efeee0abcc658ebcff049d5e74d74943 gbrap 4a100f750ac846b34bfeef0d6893c3de -gbrap10be 6d89abb9248006c3e9017545e9474654 -gbrap10le cf974e23f485a10740f5de74a5c8c3df -gbrap12be 1d9b57766ba9c2192403f43967cb9af0 -gbrap12le bb1ba1c157717db3dd612a76d38a018e -gbrap16be c72b935a6e57a8e1c37bff08c2db55b1 -gbrap16le 13eb0e62b1ac9c1c86c81521eaefab5f -gbrapf32be 42e53d9edccbd9e09c4cd78780ba92f3 -gbrapf32le eebf3973ef94c841f0a1ceb1ed61621d +gbrap10be dc6aea3559ea4fcdda1ccc4f23d2f2fb +gbrap10le 6e1cba57029fdf0f9d46b5e5cd55112b +gbrap12be dbe3a662c016563529032cd4dfb80262 +gbrap12le 24f5ecb32435b73353517e017c165e31 +gbrap16be 31968e6872a46e8174fb57f8920ed10d +gbrap16le 8c6758f33671b673b6d30969fc05a23d +gbrapf32be 366b804d5697276e8c481c4bdf05a00b +gbrapf32le 558a268e6d6b907449d1056afab78f29 gbrp dc3387f925f972c61aae7eb23cdc19f0 -gbrp10be 0277d4c3a8498d75e2783fb81379e481 -gbrp10le f3d70f8ab845c3c9b8f7452e4a6e285a -gbrp12be fbd4e149c452c351c6d1c11d6b6e176a -gbrp12le c51d51c3b753d735eb22983397262c88 -gbrp14be cd20808592e62cc439786c18a14b3e70 -gbrp14le 456f7d1ff5990aa6379137d84dd63862 -gbrp16be 5fc826cfabebfc1442cb793c4b6303e2 -gbrp16le 1b3e0b63d47a3e1b6b20931316883bf2 -gbrp9be d9c88968001e1452ff31fbc8d16b18a0 -gbrp9le 2ccfed0816bf6bd4bb3a5b7591d9603a -gbrpf32be 4614d32e4417f80e0adcc1bdcf6cde42 -gbrpf32le 1366ee77e5559672260bbe51040e28b2 +gbrp10be a318ea42e53a7b80a55aa7c19c9a0ab5 +gbrp10le 994e8fc6a1e5b230f4c55893fd7618d6 +gbrp12be bfbd419dd18c0a5677d4bce55ab24e2e +gbrp12le 95af1f8495b2a7a7ad67802e3e8bca01 +gbrp14be 9d8113c9a5182c02dbe4576509f59a96 +gbrp14le 952f39881e500ed684c8b216185f4b80 +gbrp16be 5241eee3465096efa111b86b30c3aaaa +gbrp16le 5b8b997378ce31207f37059dbfb40c4a +gbrp9be d7caf58cc3a74a036e11f924f03fc04c +gbrp9le 010f7bcd8b2e17065d01a09f0d483218 +gbrpf32be f3d0cefdf11c861001880772d817aac8 +gbrpf32le 290468205c1c18a0667edfca45061aee gray 221201cc7cfc4964eacd8b3e426fd276 gray10be 9452756d0b37f4f5c7cae7635e22d747 gray10le 37fd2e1ec6b66410212d39a342e864df @@ -80,6 +80,7 @@ rgba 85bb5d03cea1c6e8002ced3373904336 rgba64be ee73e57923af984b31cc7795d13929da rgba64le 783d2779adfafe3548bdb671ec0de69e uyvy422 aeb4ba4f9f003ae21f6d18089198244f +x2rgb10le 591fe7942544c8fc40e5d30e0e589f49 xyz12be c7ba8345998c0141ddc079cdd29b1a40 xyz12le 95f5d3a0de834cc495c9032a14987cde ya16be 20d4842899d61068f5fb6af478bf26a6 diff --git a/tests/ref/fate/filter-pixfmts-transpose b/tests/ref/fate/filter-pixfmts-transpose index e194c335c..0a8542b2a 100644 --- a/tests/ref/fate/filter-pixfmts-transpose +++ b/tests/ref/fate/filter-pixfmts-transpose @@ -76,6 +76,7 @@ rgb8 c90feb30c3c9391ef5f470209d7b7a15 rgba 4d76a9542143752a4ac30f82f88f68f1 rgba64be a60041217f4c0cd796d19d3940a12a41 rgba64le ad47197774858858ae7b0c177dffa459 +x2rgb10le a64d4d901b09bea9d59eda58be5e88ff xyz12be 68e5cba640f6e4ef72dff950e88b5342 xyz12le 8b6b6a6db4d7561e80db88ccaecce7a9 ya16be 3e161cb5f225922a80fefdc9cc02a4f9 diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip index 6d0f9eecc..732db8d33 100644 --- a/tests/ref/fate/filter-pixfmts-vflip +++ b/tests/ref/fate/filter-pixfmts-vflip @@ -80,6 +80,7 @@ rgba c1a5908572737f2ae1e5d8218af65f4b rgba64be 17e6273323b5779b5f3f775f150c1011 rgba64le 48f45b10503b7dd140329c3dd0d54c98 uyvy422 3a237e8376264e0cfa78f8a3fdadec8a +x2rgb10le 332a6f5f5012008a562cb031836da028 xyz12be 810644e008deb231850d779aaa27cc7e xyz12le 829701db461b43533cf9241e0743bc61 ya16be 55b1dbbe4d56ed0d22461685ce85520d diff --git a/tests/ref/fate/filter-thumbnail b/tests/ref/fate/filter-thumbnail index 36f11f297..4d8c5011c 100644 --- a/tests/ref/fate/filter-thumbnail +++ b/tests/ref/fate/filter-thumbnail @@ -1 +1 @@ -thumbnail cd429b3d92c33bcc257e8e6a3284dbf7 +thumbnail 8b54dbc891b9cc05742dd0f5b74c0727 diff --git a/tests/ref/fate/filter-unsharp-yuv420p10 b/tests/ref/fate/filter-unsharp-yuv420p10 new file mode 100644 index 000000000..513ee7894 --- /dev/null +++ b/tests/ref/fate/filter-unsharp-yuv420p10 @@ -0,0 +1,25 @@ +#tb 0: 1/2 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 1/1 +0, 0, 0, 1, 230400, 0x091f3ed7 +0, 1, 1, 1, 230400, 0x4151292d +0, 2, 2, 1, 230400, 0xe7066e96 +0, 3, 3, 1, 230400, 0x57c20d15 +0, 4, 4, 1, 230400, 0x01269a37 +0, 5, 5, 1, 230400, 0xb2b04e5c +0, 6, 6, 1, 230400, 0x98fc479f +0, 7, 7, 1, 230400, 0x561915bb +0, 8, 8, 1, 230400, 0xd60c45f7 +0, 9, 9, 1, 230400, 0x747d8a28 +0, 10, 10, 1, 230400, 0x92505d36 +0, 11, 11, 1, 230400, 0x9476af1f +0, 12, 12, 1, 230400, 0x1382c3d0 +0, 13, 13, 1, 230400, 0x94ea40bd +0, 14, 14, 1, 230400, 0x8d46229a +0, 15, 15, 1, 230400, 0xe5736654 +0, 16, 16, 1, 230400, 0x04bd4db2 +0, 17, 17, 1, 230400, 0x4d721ad2 +0, 18, 18, 1, 230400, 0xebe151a2 +0, 19, 19, 1, 230400, 0xa1263f01 diff --git a/tests/ref/fate/fits-demux b/tests/ref/fate/fits-demux index 85605ab11..de7aa11d5 100644 --- a/tests/ref/fate/fits-demux +++ b/tests/ref/fate/fits-demux @@ -3,8 +3,8 @@ #codec_id 0: fits #dimensions 0: 72x36 #sar 0: 0/1 -0, 0, 0, 1, 14320, 0x0ecf72e0 -0, 1, 1, 1, 14320, 0xd94af6eb -0, 2, 2, 1, 14320, 0x15c21892 -0, 3, 3, 1, 14320, 0xb18adc01 -0, 4, 4, 1, 14320, 0xc2be706d +0, 0, 0, 1, 14320, 0xa9ee75a4 +0, 1, 1, 1, 14320, 0xb9daf9af +0, 2, 2, 1, 14320, 0xf6431b56 +0, 3, 3, 1, 14320, 0x921adec5 +0, 4, 4, 1, 14320, 0xa34e7331 diff --git a/tests/ref/fate/fitsdec-gray b/tests/ref/fate/fitsdec-gray index d08073245..488ee7102 100644 --- a/tests/ref/fate/fitsdec-gray +++ b/tests/ref/fate/fitsdec-gray @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 128x128 #sar 0: 0/1 -0, 0, 0, 1, 16384, 0x353dbacd +0, 0, 0, 1, 16384, 0xeff50901 diff --git a/tests/ref/fate/flcl1905 b/tests/ref/fate/flcl1905 index de4292186..c65128083 100644 --- a/tests/ref/fate/flcl1905 +++ b/tests/ref/fate/flcl1905 @@ -1,4 +1,4 @@ -packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=56|flags=K_ +packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=22528|duration_time=0.510839|size=4092|pos=56|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -10,7 +10,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=22528|pts_time=0.510839|dts=22528|dts_time=0.510839|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=4148|flags=K_ +packet|codec_type=audio|stream_index=0|pts=22528|pts_time=0.510839|dts=22528|dts_time=0.510839|duration=22528|duration_time=0.510839|size=4092|pos=4148|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=22528|pkt_pts_time=0.510839|pkt_dts=22528|pkt_dts_time=0.510839|best_effort_timestamp=22528|best_effort_timestamp_time=0.510839|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=4148|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=4148|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=4148|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -22,7 +22,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=4148|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=4148|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=4148|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=45056|pts_time=1.021678|dts=45056|dts_time=1.021678|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=8240|flags=K_ +packet|codec_type=audio|stream_index=0|pts=45056|pts_time=1.021678|dts=45056|dts_time=1.021678|duration=22528|duration_time=0.510839|size=4092|pos=8240|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=45056|pkt_pts_time=1.021678|pkt_dts=45056|pkt_dts_time=1.021678|best_effort_timestamp=45056|best_effort_timestamp_time=1.021678|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=8240|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=8240|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=8240|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -34,7 +34,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=8240|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=8240|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=8240|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=67584|pts_time=1.532517|dts=67584|dts_time=1.532517|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=12332|flags=K_ +packet|codec_type=audio|stream_index=0|pts=67584|pts_time=1.532517|dts=67584|dts_time=1.532517|duration=22528|duration_time=0.510839|size=4092|pos=12332|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=67584|pkt_pts_time=1.532517|pkt_dts=67584|pkt_dts_time=1.532517|best_effort_timestamp=67584|best_effort_timestamp_time=1.532517|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=12332|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=12332|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=12332|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -46,7 +46,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=12332|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=12332|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=12332|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=90112|pts_time=2.043356|dts=90112|dts_time=2.043356|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=16424|flags=K_ +packet|codec_type=audio|stream_index=0|pts=90112|pts_time=2.043356|dts=90112|dts_time=2.043356|duration=22528|duration_time=0.510839|size=4092|pos=16424|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=90112|pkt_pts_time=2.043356|pkt_dts=90112|pkt_dts_time=2.043356|best_effort_timestamp=90112|best_effort_timestamp_time=2.043356|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=16424|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=16424|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=16424|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -58,7 +58,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=16424|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=16424|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=16424|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=112640|pts_time=2.554195|dts=112640|dts_time=2.554195|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=20516|flags=K_ +packet|codec_type=audio|stream_index=0|pts=112640|pts_time=2.554195|dts=112640|dts_time=2.554195|duration=22528|duration_time=0.510839|size=4092|pos=20516|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=112640|pkt_pts_time=2.554195|pkt_dts=112640|pkt_dts_time=2.554195|best_effort_timestamp=112640|best_effort_timestamp_time=2.554195|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=20516|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=20516|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=20516|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -70,7 +70,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=20516|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=20516|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=20516|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=135168|pts_time=3.065034|dts=135168|dts_time=3.065034|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=24608|flags=K_ +packet|codec_type=audio|stream_index=0|pts=135168|pts_time=3.065034|dts=135168|dts_time=3.065034|duration=22528|duration_time=0.510839|size=4092|pos=24608|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=135168|pkt_pts_time=3.065034|pkt_dts=135168|pkt_dts_time=3.065034|best_effort_timestamp=135168|best_effort_timestamp_time=3.065034|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=24608|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=24608|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=24608|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -82,7 +82,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=24608|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=24608|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=24608|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=157696|pts_time=3.575873|dts=157696|dts_time=3.575873|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=28700|flags=K_ +packet|codec_type=audio|stream_index=0|pts=157696|pts_time=3.575873|dts=157696|dts_time=3.575873|duration=22528|duration_time=0.510839|size=4092|pos=28700|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=157696|pkt_pts_time=3.575873|pkt_dts=157696|pkt_dts_time=3.575873|best_effort_timestamp=157696|best_effort_timestamp_time=3.575873|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=28700|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=28700|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=28700|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -94,7 +94,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=28700|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=28700|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=28700|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=180224|pts_time=4.086712|dts=180224|dts_time=4.086712|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=32792|flags=K_ +packet|codec_type=audio|stream_index=0|pts=180224|pts_time=4.086712|dts=180224|dts_time=4.086712|duration=22528|duration_time=0.510839|size=4092|pos=32792|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=180224|pkt_pts_time=4.086712|pkt_dts=180224|pkt_dts_time=4.086712|best_effort_timestamp=180224|best_effort_timestamp_time=4.086712|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=32792|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=32792|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=32792|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -106,7 +106,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=32792|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=32792|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=32792|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=202752|pts_time=4.597551|dts=202752|dts_time=4.597551|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=36884|flags=K_ +packet|codec_type=audio|stream_index=0|pts=202752|pts_time=4.597551|dts=202752|dts_time=4.597551|duration=22528|duration_time=0.510839|size=4092|pos=36884|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=202752|pkt_pts_time=4.597551|pkt_dts=202752|pkt_dts_time=4.597551|best_effort_timestamp=202752|best_effort_timestamp_time=4.597551|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=36884|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=36884|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=36884|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -118,7 +118,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=36884|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=36884|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=36884|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=225280|pts_time=5.108390|dts=225280|dts_time=5.108390|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=40976|flags=K_ +packet|codec_type=audio|stream_index=0|pts=225280|pts_time=5.108390|dts=225280|dts_time=5.108390|duration=22528|duration_time=0.510839|size=4092|pos=40976|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=225280|pkt_pts_time=5.108390|pkt_dts=225280|pkt_dts_time=5.108390|best_effort_timestamp=225280|best_effort_timestamp_time=5.108390|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=40976|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=40976|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=40976|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -130,7 +130,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=40976|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=40976|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=40976|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=247808|pts_time=5.619229|dts=247808|dts_time=5.619229|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=45068|flags=K_ +packet|codec_type=audio|stream_index=0|pts=247808|pts_time=5.619229|dts=247808|dts_time=5.619229|duration=22528|duration_time=0.510839|size=4092|pos=45068|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=247808|pkt_pts_time=5.619229|pkt_dts=247808|pkt_dts_time=5.619229|best_effort_timestamp=247808|best_effort_timestamp_time=5.619229|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=45068|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=45068|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=45068|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -142,7 +142,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=45068|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=45068|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=45068|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=270336|pts_time=6.130068|dts=270336|dts_time=6.130068|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=49160|flags=K_ +packet|codec_type=audio|stream_index=0|pts=270336|pts_time=6.130068|dts=270336|dts_time=6.130068|duration=22528|duration_time=0.510839|size=4092|pos=49160|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=270336|pkt_pts_time=6.130068|pkt_dts=270336|pkt_dts_time=6.130068|best_effort_timestamp=270336|best_effort_timestamp_time=6.130068|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=49160|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=49160|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=49160|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -154,7 +154,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=49160|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=49160|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=49160|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=292864|pts_time=6.640907|dts=292864|dts_time=6.640907|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=53252|flags=K_ +packet|codec_type=audio|stream_index=0|pts=292864|pts_time=6.640907|dts=292864|dts_time=6.640907|duration=22528|duration_time=0.510839|size=4092|pos=53252|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=292864|pkt_pts_time=6.640907|pkt_dts=292864|pkt_dts_time=6.640907|best_effort_timestamp=292864|best_effort_timestamp_time=6.640907|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=53252|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=53252|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=53252|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -166,7 +166,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=53252|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=53252|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=53252|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=315392|pts_time=7.151746|dts=315392|dts_time=7.151746|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=57344|flags=K_ +packet|codec_type=audio|stream_index=0|pts=315392|pts_time=7.151746|dts=315392|dts_time=7.151746|duration=22528|duration_time=0.510839|size=4092|pos=57344|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=315392|pkt_pts_time=7.151746|pkt_dts=315392|pkt_dts_time=7.151746|best_effort_timestamp=315392|best_effort_timestamp_time=7.151746|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=57344|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=57344|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=57344|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -178,7 +178,7 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=57344|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=57344|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=57344|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=337920|pts_time=7.662585|dts=337920|dts_time=7.662585|duration=22528|duration_time=0.510839|convergence_duration=N/A|convergence_duration_time=N/A|size=4092|pos=61436|flags=K_ +packet|codec_type=audio|stream_index=0|pts=337920|pts_time=7.662585|dts=337920|dts_time=7.662585|duration=22528|duration_time=0.510839|size=4092|pos=61436|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=337920|pkt_pts_time=7.662585|pkt_dts=337920|pkt_dts_time=7.662585|best_effort_timestamp=337920|best_effort_timestamp_time=7.662585|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=61436|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=61436|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=61436|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -190,4 +190,4 @@ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|p frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=61436|pkt_size=1116|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=61436|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=N/A|pkt_pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=61436|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -packet|codec_type=audio|stream_index=0|pts=360448|pts_time=8.173424|dts=360448|dts_time=8.173424|duration=44|duration_time=0.000998|convergence_duration=N/A|convergence_duration_time=N/A|size=8|pos=65528|flags=K_ +packet|codec_type=audio|stream_index=0|pts=360448|pts_time=8.173424|dts=360448|dts_time=8.173424|duration=44|duration_time=0.000998|size=8|pos=65528|flags=K_ diff --git a/tests/ref/fate/g2m2 b/tests/ref/fate/g2m2 index 42b7b6f2e..d939b167e 100644 --- a/tests/ref/fate/g2m2 +++ b/tests/ref/fate/g2m2 @@ -3,163 +3,163 @@ #codec_id 0: rawvideo #dimensions 0: 1024x768 #sar 0: 0/1 -0, 47, 47, 0, 2359296, 0xb4434e4f -0, 62, 62, 0, 2359296, 0x59cb5027 -0, 78, 78, 0, 2359296, 0xe9bc578d -0, 109, 109, 0, 2359296, 0x5d17554f -0, 125, 125, 0, 2359296, 0x6d685457 -0, 437, 437, 0, 2359296, 0x13205420 -0, 438, 438, 0, 2359296, 0xb8e15116 -0, 453, 453, 0, 2359296, 0x2ca55195 -0, 469, 469, 0, 2359296, 0x767d1c45 -0, 484, 484, 0, 2359296, 0x0af42016 -0, 500, 500, 0, 2359296, 0xa2083e69 -0, 516, 516, 0, 2359296, 0xb68a1308 -0, 531, 531, 0, 2359296, 0x4f334c0e -0, 547, 547, 0, 2359296, 0x98b74e4f -0, 562, 562, 0, 2359296, 0xd9de4e4f -0, 578, 578, 0, 2359296, 0xa17c4e4f -0, 594, 594, 0, 2359296, 0xa49a665d -0, 609, 609, 0, 2359296, 0xf5f87360 -0, 781, 781, 0, 2359296, 0x75747360 -0, 797, 797, 0, 2359296, 0x745d7360 -0, 812, 812, 0, 2359296, 0x33047360 -0, 828, 828, 0, 2359296, 0xf19c7360 -0, 844, 844, 0, 2359296, 0xb0437360 -0, 859, 859, 0, 2359296, 0xaf2c7360 -0, 875, 875, 0, 2359296, 0x2ea87360 -0, 891, 891, 0, 2359296, 0xee577360 -0, 953, 953, 0, 2359296, 0x6dd37360 -0, 1078, 1078, 0, 2359296, 0xab327965 -0, 1094, 1094, 0, 2359296, 0x5f8677d0 -0, 1109, 1109, 0, 2359296, 0x02135eb4 -0, 1125, 1125, 0, 2359296, 0x09784e4f -0, 1141, 1141, 0, 2359296, 0xa140a62d -0, 1156, 1156, 0, 2359296, 0xa140a62d -0, 1484, 1484, 0, 2359296, 0xa140a62d -0, 1516, 1516, 0, 2359296, 0xa140a62d -0, 1547, 1547, 0, 2359296, 0xa140a62d -0, 1641, 1641, 0, 2359296, 0xa140a62d -0, 1642, 1642, 0, 2359296, 0xa140a62d -0, 1656, 1656, 0, 2359296, 0xa140a62d -0, 1657, 1657, 0, 2359296, 0xa140a62d -0, 1672, 1672, 0, 2359296, 0xa140a62d -0, 1673, 1673, 0, 2359296, 0x92024e4f -0, 1687, 1687, 0, 2359296, 0xb1754dbe -0, 1688, 1688, 0, 2359296, 0x15ee5eb4 -0, 1703, 1703, 0, 2359296, 0xb1d9746e -0, 1719, 1719, 0, 2359296, 0xabe77360 -0, 1734, 1734, 0, 2359296, 0xaad07360 -0, 1750, 1750, 0, 2359296, 0x2a4c7360 -0, 1766, 1766, 0, 2359296, 0x69777360 -0, 1781, 1781, 0, 2359296, 0xe8e47360 -0, 2328, 2328, 0, 2359296, 0x29357360 -0, 3031, 3031, 0, 2359296, 0x69777360 -0, 3078, 3078, 0, 2359296, 0xa9b97360 -0, 3109, 3109, 0, 2359296, 0xd2697707 -0, 3141, 3141, 0, 2359296, 0x22a07965 -0, 3156, 3156, 0, 2359296, 0xf9327aa7 -0, 3172, 3172, 0, 2359296, 0xa5d277d0 -0, 3203, 3203, 0, 2359296, 0x97b6746e -0, 3328, 3328, 0, 2359296, 0x80bb746e -0, 4562, 4562, 0, 2359296, 0x530b719a -0, 4672, 4672, 0, 2359296, 0x4827665d -0, 4703, 4703, 0, 2359296, 0xc48c5eb4 -0, 5391, 5391, 0, 2359296, 0xe6465eb4 -0, 5578, 5578, 0, 2359296, 0xece455ec -0, 5594, 5594, 0, 2359296, 0xb5344dbe -0, 5609, 5609, 0, 2359296, 0xa140a62d -0, 5625, 5625, 0, 2359296, 0xa140a62d -0, 5641, 5641, 0, 2359296, 0xa140a62d -0, 5642, 5642, 0, 2359296, 0xa140a62d -0, 5656, 5656, 0, 2359296, 0xa140a62d -0, 5672, 5672, 0, 2359296, 0xa140a62d -0, 5703, 5703, 0, 2359296, 0xa140a62d -0, 5750, 5750, 0, 2359296, 0xa140a62d -0, 5766, 5766, 0, 2359296, 0xa140a62d -0, 5781, 5781, 0, 2359296, 0xa140a62d -0, 5797, 5797, 0, 2359296, 0xa140a62d -0, 5812, 5812, 0, 2359296, 0xa140a62d -0, 5875, 5875, 0, 2359296, 0xa140a62d -0, 5922, 5922, 0, 2359296, 0xa140a62d -0, 5984, 5984, 0, 2359296, 0xa140a62d -0, 6031, 6031, 0, 2359296, 0xa140a62d -0, 6047, 6047, 0, 2359296, 0xa140a62d -0, 6062, 6062, 0, 2359296, 0xa140a62d -0, 6406, 6406, 0, 2359296, 0xa140a62d -0, 6453, 6453, 0, 2359296, 0xa140a62d -0, 6469, 6469, 0, 2359296, 0xa140a62d -0, 6484, 6484, 0, 2359296, 0xa140a62d -0, 6500, 6500, 0, 2359296, 0xa140a62d -0, 6516, 6516, 0, 2359296, 0xa140a62d -0, 6531, 6531, 0, 2359296, 0xa140a62d -0, 6547, 6547, 0, 2359296, 0xa140a62d -0, 6562, 6562, 0, 2359296, 0x5c2a4cd9 -0, 6578, 6578, 0, 2359296, 0x28f94e4f -0, 6594, 6594, 0, 2359296, 0x9acb4820 -0, 6609, 6609, 0, 2359296, 0x9ec716e1 -0, 6625, 6625, 0, 2359296, 0xaf5f3fa4 -0, 6641, 6641, 0, 2359296, 0x7d633218 -0, 6642, 6642, 0, 2359296, 0x34fb2016 -0, 6656, 6656, 0, 2359296, 0x61351665 -0, 6812, 6812, 0, 2359296, 0xb23c1039 -0, 6828, 6828, 0, 2359296, 0x59290d69 -0, 6844, 6844, 0, 2359296, 0x639c132d -0, 6859, 6859, 0, 2359296, 0x0b252237 -0, 6875, 6875, 0, 2359296, 0xe66f2fc5 -0, 6891, 6891, 0, 2359296, 0xa8b33761 -0, 6906, 6906, 0, 2359296, 0x81a63f8b -0, 6969, 6969, 0, 2359296, 0x18074843 -0, 6984, 6984, 0, 2359296, 0x434a5195 -0, 7000, 7000, 0, 2359296, 0x6da15116 -0, 7001, 7001, 0, 2359296, 0xca755420 -0, 7016, 7016, 0, 2359296, 0xe6fc5457 -0, 7017, 7017, 0, 2359296, 0x271d53fd -0, 7031, 7031, 0, 2359296, 0xa15b554f -0, 7281, 7281, 0, 2359296, 0x49f6578d -0, 7282, 7282, 0, 2359296, 0x2c0c4e4f -0, 7297, 7297, 0, 2359296, 0x7e924e4f -0, 7298, 7298, 0, 2359296, 0x32ff4e4f -0, 7312, 7312, 0, 2359296, 0x23ad4e4f -0, 7313, 7313, 0, 2359296, 0x7ddc4e4f -0, 7328, 7328, 0, 2359296, 0xd0624e4f -0, 7329, 7329, 0, 2359296, 0x22f74e4f -0, 7781, 7781, 0, 2359296, 0x49fa4e4f -0, 7797, 7797, 0, 2359296, 0x6a5a5027 -0, 7812, 7812, 0, 2359296, 0x9f935027 -0, 7828, 7828, 0, 2359296, 0xc5e55027 -0, 7844, 7844, 0, 2359296, 0xd4cc5027 -0, 8250, 8250, 0, 2359296, 0xd2ab5027 -0, 8266, 8266, 0, 2359296, 0x68f04e4f -0, 8281, 8281, 0, 2359296, 0xd0b44e4f -0, 8297, 8297, 0, 2359296, 0xfced4e4f -0, 8298, 8298, 0, 2359296, 0x8b0d4e4f -0, 8312, 8312, 0, 2359296, 0x09db4e4f -0, 8328, 8328, 0, 2359296, 0x4d0f4e4f -0, 8329, 8329, 0, 2359296, 0xad824dbe -0, 8344, 8344, 0, 2359296, 0x9aca4dbe -0, 8345, 8345, 0, 2359296, 0x755a4dbe -0, 8359, 8359, 0, 2359296, 0xc6824d2d -0, 8360, 8360, 0, 2359296, 0x7c344c0e -0, 8375, 8375, 0, 2359296, 0x50f04c0e -0, 8391, 8391, 0, 2359296, 0xfa594c0e -0, 8406, 8406, 0, 2359296, 0x4d494c0e -0, 8422, 8422, 0, 2359296, 0xf6b24c0e -0, 8437, 8437, 0, 2359296, 0xcb6e4c0e -0, 8453, 8453, 0, 2359296, 0xbd024c0e -0, 8516, 8516, 0, 2359296, 0x245b4dbe -0, 8531, 8531, 0, 2359296, 0x47874e4f -0, 8547, 8547, 0, 2359296, 0xdead4e4f -0, 8562, 8562, 0, 2359296, 0x847e4e4f -0, 9344, 9344, 0, 2359296, 0x1a13e47c -0, 9345, 9345, 0, 2359296, 0x46b3e321 -0, 9876, 9876, 0, 2359296, 0x76c0e35d -0, 9922, 9922, 0, 2359296, 0xf6d9e519 -0, 9938, 9938, 0, 2359296, 0xac0fe4b3 -0, 9954, 9954, 0, 2359296, 0x3a3fe424 -0, 9955, 9955, 0, 2359296, 0xa97ce1a8 -0, 9969, 9969, 0, 2359296, 0x12fae01d -0, 9970, 9970, 0, 2359296, 0x65b4df14 -0, 9985, 9985, 0, 2359296, 0x82d0e032 -0, 9986, 9986, 0, 2359296, 0xa452e0cf -0, 10001, 10001, 0, 2359296, 0x22d6df37 +0, 47, 47, 1, 2359296, 0xb4434e4f +0, 62, 62, 1, 2359296, 0x59cb5027 +0, 78, 78, 1, 2359296, 0xe9bc578d +0, 109, 109, 1, 2359296, 0x5d17554f +0, 125, 125, 1, 2359296, 0x6d685457 +0, 437, 437, 1, 2359296, 0x13205420 +0, 438, 438, 1, 2359296, 0xb8e15116 +0, 453, 453, 1, 2359296, 0x2ca55195 +0, 469, 469, 1, 2359296, 0x767d1c45 +0, 484, 484, 1, 2359296, 0x0af42016 +0, 500, 500, 1, 2359296, 0xa2083e69 +0, 516, 516, 1, 2359296, 0xb68a1308 +0, 531, 531, 1, 2359296, 0x4f334c0e +0, 547, 547, 1, 2359296, 0x98b74e4f +0, 562, 562, 1, 2359296, 0xd9de4e4f +0, 578, 578, 1, 2359296, 0xa17c4e4f +0, 594, 594, 1, 2359296, 0xa49a665d +0, 609, 609, 1, 2359296, 0xf5f87360 +0, 781, 781, 1, 2359296, 0x75747360 +0, 797, 797, 1, 2359296, 0x745d7360 +0, 812, 812, 1, 2359296, 0x33047360 +0, 828, 828, 1, 2359296, 0xf19c7360 +0, 844, 844, 1, 2359296, 0xb0437360 +0, 859, 859, 1, 2359296, 0xaf2c7360 +0, 875, 875, 1, 2359296, 0x2ea87360 +0, 891, 891, 1, 2359296, 0xee577360 +0, 953, 953, 1, 2359296, 0x6dd37360 +0, 1078, 1078, 1, 2359296, 0xab327965 +0, 1094, 1094, 1, 2359296, 0x5f8677d0 +0, 1109, 1109, 1, 2359296, 0x02135eb4 +0, 1125, 1125, 1, 2359296, 0x09784e4f +0, 1141, 1141, 1, 2359296, 0xa140a62d +0, 1156, 1156, 1, 2359296, 0xa140a62d +0, 1484, 1484, 1, 2359296, 0xa140a62d +0, 1516, 1516, 1, 2359296, 0xa140a62d +0, 1547, 1547, 1, 2359296, 0xa140a62d +0, 1641, 1641, 1, 2359296, 0xa140a62d +0, 1642, 1642, 1, 2359296, 0xa140a62d +0, 1656, 1656, 1, 2359296, 0xa140a62d +0, 1657, 1657, 1, 2359296, 0xa140a62d +0, 1672, 1672, 1, 2359296, 0xa140a62d +0, 1673, 1673, 1, 2359296, 0x92024e4f +0, 1687, 1687, 1, 2359296, 0xb1754dbe +0, 1688, 1688, 1, 2359296, 0x15ee5eb4 +0, 1703, 1703, 1, 2359296, 0xb1d9746e +0, 1719, 1719, 1, 2359296, 0xabe77360 +0, 1734, 1734, 1, 2359296, 0xaad07360 +0, 1750, 1750, 1, 2359296, 0x2a4c7360 +0, 1766, 1766, 1, 2359296, 0x69777360 +0, 1781, 1781, 1, 2359296, 0xe8e47360 +0, 2328, 2328, 1, 2359296, 0x29357360 +0, 3031, 3031, 1, 2359296, 0x69777360 +0, 3078, 3078, 1, 2359296, 0xa9b97360 +0, 3109, 3109, 1, 2359296, 0xd2697707 +0, 3141, 3141, 1, 2359296, 0x22a07965 +0, 3156, 3156, 1, 2359296, 0xf9327aa7 +0, 3172, 3172, 1, 2359296, 0xa5d277d0 +0, 3203, 3203, 1, 2359296, 0x97b6746e +0, 3328, 3328, 1, 2359296, 0x80bb746e +0, 4562, 4562, 1, 2359296, 0x530b719a +0, 4672, 4672, 1, 2359296, 0x4827665d +0, 4703, 4703, 1, 2359296, 0xc48c5eb4 +0, 5391, 5391, 1, 2359296, 0xe6465eb4 +0, 5578, 5578, 1, 2359296, 0xece455ec +0, 5594, 5594, 1, 2359296, 0xb5344dbe +0, 5609, 5609, 1, 2359296, 0xa140a62d +0, 5625, 5625, 1, 2359296, 0xa140a62d +0, 5641, 5641, 1, 2359296, 0xa140a62d +0, 5642, 5642, 1, 2359296, 0xa140a62d +0, 5656, 5656, 1, 2359296, 0xa140a62d +0, 5672, 5672, 1, 2359296, 0xa140a62d +0, 5703, 5703, 1, 2359296, 0xa140a62d +0, 5750, 5750, 1, 2359296, 0xa140a62d +0, 5766, 5766, 1, 2359296, 0xa140a62d +0, 5781, 5781, 1, 2359296, 0xa140a62d +0, 5797, 5797, 1, 2359296, 0xa140a62d +0, 5812, 5812, 1, 2359296, 0xa140a62d +0, 5875, 5875, 1, 2359296, 0xa140a62d +0, 5922, 5922, 1, 2359296, 0xa140a62d +0, 5984, 5984, 1, 2359296, 0xa140a62d +0, 6031, 6031, 1, 2359296, 0xa140a62d +0, 6047, 6047, 1, 2359296, 0xa140a62d +0, 6062, 6062, 1, 2359296, 0xa140a62d +0, 6406, 6406, 1, 2359296, 0xa140a62d +0, 6453, 6453, 1, 2359296, 0xa140a62d +0, 6469, 6469, 1, 2359296, 0xa140a62d +0, 6484, 6484, 1, 2359296, 0xa140a62d +0, 6500, 6500, 1, 2359296, 0xa140a62d +0, 6516, 6516, 1, 2359296, 0xa140a62d +0, 6531, 6531, 1, 2359296, 0xa140a62d +0, 6547, 6547, 1, 2359296, 0xa140a62d +0, 6562, 6562, 1, 2359296, 0x5c2a4cd9 +0, 6578, 6578, 1, 2359296, 0x28f94e4f +0, 6594, 6594, 1, 2359296, 0x9acb4820 +0, 6609, 6609, 1, 2359296, 0x9ec716e1 +0, 6625, 6625, 1, 2359296, 0xaf5f3fa4 +0, 6641, 6641, 1, 2359296, 0x7d633218 +0, 6642, 6642, 1, 2359296, 0x34fb2016 +0, 6656, 6656, 1, 2359296, 0x61351665 +0, 6812, 6812, 1, 2359296, 0xb23c1039 +0, 6828, 6828, 1, 2359296, 0x59290d69 +0, 6844, 6844, 1, 2359296, 0x639c132d +0, 6859, 6859, 1, 2359296, 0x0b252237 +0, 6875, 6875, 1, 2359296, 0xe66f2fc5 +0, 6891, 6891, 1, 2359296, 0xa8b33761 +0, 6906, 6906, 1, 2359296, 0x81a63f8b +0, 6969, 6969, 1, 2359296, 0x18074843 +0, 6984, 6984, 1, 2359296, 0x434a5195 +0, 7000, 7000, 1, 2359296, 0x6da15116 +0, 7001, 7001, 1, 2359296, 0xca755420 +0, 7016, 7016, 1, 2359296, 0xe6fc5457 +0, 7017, 7017, 1, 2359296, 0x271d53fd +0, 7031, 7031, 1, 2359296, 0xa15b554f +0, 7281, 7281, 1, 2359296, 0x49f6578d +0, 7282, 7282, 1, 2359296, 0x2c0c4e4f +0, 7297, 7297, 1, 2359296, 0x7e924e4f +0, 7298, 7298, 1, 2359296, 0x32ff4e4f +0, 7312, 7312, 1, 2359296, 0x23ad4e4f +0, 7313, 7313, 1, 2359296, 0x7ddc4e4f +0, 7328, 7328, 1, 2359296, 0xd0624e4f +0, 7329, 7329, 1, 2359296, 0x22f74e4f +0, 7781, 7781, 1, 2359296, 0x49fa4e4f +0, 7797, 7797, 1, 2359296, 0x6a5a5027 +0, 7812, 7812, 1, 2359296, 0x9f935027 +0, 7828, 7828, 1, 2359296, 0xc5e55027 +0, 7844, 7844, 1, 2359296, 0xd4cc5027 +0, 8250, 8250, 1, 2359296, 0xd2ab5027 +0, 8266, 8266, 1, 2359296, 0x68f04e4f +0, 8281, 8281, 1, 2359296, 0xd0b44e4f +0, 8297, 8297, 1, 2359296, 0xfced4e4f +0, 8298, 8298, 1, 2359296, 0x8b0d4e4f +0, 8312, 8312, 1, 2359296, 0x09db4e4f +0, 8328, 8328, 1, 2359296, 0x4d0f4e4f +0, 8329, 8329, 1, 2359296, 0xad824dbe +0, 8344, 8344, 1, 2359296, 0x9aca4dbe +0, 8345, 8345, 1, 2359296, 0x755a4dbe +0, 8359, 8359, 1, 2359296, 0xc6824d2d +0, 8360, 8360, 1, 2359296, 0x7c344c0e +0, 8375, 8375, 1, 2359296, 0x50f04c0e +0, 8391, 8391, 1, 2359296, 0xfa594c0e +0, 8406, 8406, 1, 2359296, 0x4d494c0e +0, 8422, 8422, 1, 2359296, 0xf6b24c0e +0, 8437, 8437, 1, 2359296, 0xcb6e4c0e +0, 8453, 8453, 1, 2359296, 0xbd024c0e +0, 8516, 8516, 1, 2359296, 0x245b4dbe +0, 8531, 8531, 1, 2359296, 0x47874e4f +0, 8547, 8547, 1, 2359296, 0xdead4e4f +0, 8562, 8562, 1, 2359296, 0x847e4e4f +0, 9344, 9344, 1, 2359296, 0x1a13e47c +0, 9345, 9345, 1, 2359296, 0x46b3e321 +0, 9876, 9876, 1, 2359296, 0x76c0e35d +0, 9922, 9922, 1, 2359296, 0xf6d9e519 +0, 9938, 9938, 1, 2359296, 0xac0fe4b3 +0, 9954, 9954, 1, 2359296, 0x3a3fe424 +0, 9955, 9955, 1, 2359296, 0xa97ce1a8 +0, 9969, 9969, 1, 2359296, 0x12fae01d +0, 9970, 9970, 1, 2359296, 0x65b4df14 +0, 9985, 9985, 1, 2359296, 0x82d0e032 +0, 9986, 9986, 1, 2359296, 0xa452e0cf +0, 10001, 10001, 1, 2359296, 0x22d6df37 diff --git a/tests/ref/fate/gaplessenc-itunes-to-ipod-aac b/tests/ref/fate/gaplessenc-itunes-to-ipod-aac index 76cbf2235..95b167bda 100644 --- a/tests/ref/fate/gaplessenc-itunes-to-ipod-aac +++ b/tests/ref/fate/gaplessenc-itunes-to-ipod-aac @@ -5,7 +5,7 @@ duration_ts=103326 [/STREAM] [FORMAT] start_time=0.000000 -duration=2.367000 +duration=2.344000 [/FORMAT] packet|pts=-1024|dts=-1024|duration=1024|flags=KDside_data| diff --git a/tests/ref/fate/gaplessenc-pcm-to-mov-aac b/tests/ref/fate/gaplessenc-pcm-to-mov-aac index 2b17956e2..bfd47be10 100644 --- a/tests/ref/fate/gaplessenc-pcm-to-mov-aac +++ b/tests/ref/fate/gaplessenc-pcm-to-mov-aac @@ -5,7 +5,7 @@ duration_ts=529200 [/STREAM] [FORMAT] start_time=0.000000 -duration=12.024000 +duration=12.000000 [/FORMAT] packet|pts=-1024|dts=-1024|duration=1024|flags=KDside_data| diff --git a/tests/ref/fate/gaplessinfo-itunes1 b/tests/ref/fate/gaplessinfo-itunes1 index bb5c09ad3..c10e4cccf 100644 --- a/tests/ref/fate/gaplessinfo-itunes1 +++ b/tests/ref/fate/gaplessinfo-itunes1 @@ -24,7 +24,7 @@ packet|pts=1291264|dts=1291264|duration=1024|flags=K_ packet|pts=1292288|dts=1292288|duration=1024|flags=K_ packet|pts=1293312|dts=1293312|duration=1024|flags=K_ stream|nb_read_packets=1264 -frame|pkt_pts=2112|pkt_dts=2112|best_effort_timestamp=2048|pkt_duration=960|nb_samples=960 +frame|pkt_pts=2112|pkt_dts=2112|best_effort_timestamp=2112|pkt_duration=960|nb_samples=960 frame|pkt_pts=3072|pkt_dts=3072|best_effort_timestamp=3072|pkt_duration=1024|nb_samples=1024 frame|pkt_pts=4096|pkt_dts=4096|best_effort_timestamp=4096|pkt_duration=1024|nb_samples=1024 frame|pkt_pts=5120|pkt_dts=5120|best_effort_timestamp=5120|pkt_duration=1024|nb_samples=1024 diff --git a/tests/ref/fate/gaplessinfo-itunes2 b/tests/ref/fate/gaplessinfo-itunes2 index 0603ba8bf..752b95319 100644 --- a/tests/ref/fate/gaplessinfo-itunes2 +++ b/tests/ref/fate/gaplessinfo-itunes2 @@ -24,7 +24,7 @@ packet|pts=102400|dts=102400|duration=1024|flags=K_ packet|pts=103424|dts=103424|duration=1024|flags=K_ packet|pts=104448|dts=104448|duration=1024|flags=K_ stream|nb_read_packets=103 -frame|pkt_pts=2112|pkt_dts=2112|best_effort_timestamp=2048|pkt_duration=960|nb_samples=960 +frame|pkt_pts=2112|pkt_dts=2112|best_effort_timestamp=2112|pkt_duration=960|nb_samples=960 frame|pkt_pts=3072|pkt_dts=3072|best_effort_timestamp=3072|pkt_duration=1024|nb_samples=1024 frame|pkt_pts=4096|pkt_dts=4096|best_effort_timestamp=4096|pkt_duration=1024|nb_samples=1024 frame|pkt_pts=5120|pkt_dts=5120|best_effort_timestamp=5120|pkt_duration=1024|nb_samples=1024 diff --git a/tests/ref/fate/h264-conformance-cabac_mot_fld0_full b/tests/ref/fate/h264-conformance-cabac_mot_fld0_full index 8778fef98..62bea9cd9 100644 --- a/tests/ref/fate/h264-conformance-cabac_mot_fld0_full +++ b/tests/ref/fate/h264-conformance-cabac_mot_fld0_full @@ -3,33 +3,33 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0xbf168f4e -0, 1, 1, 1, 518400, 0xeda5e54f -0, 2, 2, 1, 518400, 0xef496d43 -0, 3, 3, 1, 518400, 0x6b68dad5 -0, 4, 4, 1, 518400, 0x9a40a7de -0, 5, 5, 1, 518400, 0x0c21c018 -0, 6, 6, 1, 518400, 0x4ac5a846 -0, 7, 7, 1, 518400, 0x3a1aa817 -0, 8, 8, 1, 518400, 0xcc4eb434 -0, 9, 9, 1, 518400, 0x4368a3c2 -0, 10, 10, 1, 518400, 0xb923682f -0, 11, 11, 1, 518400, 0xd95460a8 -0, 12, 12, 1, 518400, 0x8e8518aa -0, 13, 13, 1, 518400, 0x292a1a80 -0, 14, 14, 1, 518400, 0xbada388e -0, 15, 15, 1, 518400, 0xa67f63c9 -0, 16, 16, 1, 518400, 0x9fc77e21 -0, 17, 17, 1, 518400, 0xe99dc2ac -0, 18, 18, 1, 518400, 0x17d7d080 -0, 19, 19, 1, 518400, 0x41760c0b -0, 20, 20, 1, 518400, 0x3c70f34d -0, 21, 21, 1, 518400, 0x0d640285 -0, 22, 22, 1, 518400, 0x448893e8 -0, 23, 23, 1, 518400, 0x08194490 -0, 24, 24, 1, 518400, 0xcf227031 -0, 25, 25, 1, 518400, 0x8d94587d -0, 26, 26, 1, 518400, 0x696fca01 -0, 27, 27, 1, 518400, 0xe0ab234b -0, 28, 28, 1, 518400, 0x0620153b -0, 29, 29, 1, 518400, 0xb78c146c +0, 1, 1, 1, 518400, 0xbf168f4e +0, 2, 2, 1, 518400, 0xeda5e54f +0, 3, 3, 1, 518400, 0xef496d43 +0, 4, 4, 1, 518400, 0x6b68dad5 +0, 5, 5, 1, 518400, 0x9a40a7de +0, 6, 6, 1, 518400, 0x0c21c018 +0, 7, 7, 1, 518400, 0x4ac5a846 +0, 8, 8, 1, 518400, 0x3a1aa817 +0, 9, 9, 1, 518400, 0xcc4eb434 +0, 10, 10, 1, 518400, 0x4368a3c2 +0, 11, 11, 1, 518400, 0xb923682f +0, 12, 12, 1, 518400, 0xd95460a8 +0, 13, 13, 1, 518400, 0x8e8518aa +0, 14, 14, 1, 518400, 0x292a1a80 +0, 15, 15, 1, 518400, 0xbada388e +0, 16, 16, 1, 518400, 0xa67f63c9 +0, 17, 17, 1, 518400, 0x9fc77e21 +0, 18, 18, 1, 518400, 0xe99dc2ac +0, 19, 19, 1, 518400, 0x17d7d080 +0, 20, 20, 1, 518400, 0x41760c0b +0, 21, 21, 1, 518400, 0x3c70f34d +0, 22, 22, 1, 518400, 0x0d640285 +0, 23, 23, 1, 518400, 0x448893e8 +0, 24, 24, 1, 518400, 0x08194490 +0, 25, 25, 1, 518400, 0xcf227031 +0, 26, 26, 1, 518400, 0x8d94587d +0, 27, 27, 1, 518400, 0x696fca01 +0, 28, 28, 1, 518400, 0xe0ab234b +0, 29, 29, 1, 518400, 0x0620153b +0, 30, 30, 1, 518400, 0xb78c146c diff --git a/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full b/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full index 5651e4b57..465cde761 100644 --- a/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full +++ b/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full @@ -3,33 +3,33 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0xd8b58a23 -0, 1, 1, 1, 518400, 0xe53b4aba -0, 2, 2, 1, 518400, 0x6cbca47a -0, 3, 3, 1, 518400, 0xceb51253 -0, 4, 4, 1, 518400, 0x60cb3cdd -0, 5, 5, 1, 518400, 0x7b633553 -0, 6, 6, 1, 518400, 0x10c012c9 -0, 7, 7, 1, 518400, 0xa340ee20 -0, 8, 8, 1, 518400, 0x574c22c2 -0, 9, 9, 1, 518400, 0xbcdb1bf7 -0, 10, 10, 1, 518400, 0x57811e9a -0, 11, 11, 1, 518400, 0xdd4af748 -0, 12, 12, 1, 518400, 0xb931a637 -0, 13, 13, 1, 518400, 0xcef6ce95 -0, 14, 14, 1, 518400, 0xd28c7085 -0, 15, 15, 1, 518400, 0xae9daf53 -0, 16, 16, 1, 518400, 0xca29d819 -0, 17, 17, 1, 518400, 0x3c4bd7eb -0, 18, 18, 1, 518400, 0x912ee227 -0, 19, 19, 1, 518400, 0xb67d0e27 -0, 20, 20, 1, 518400, 0x8cf7309d -0, 21, 21, 1, 518400, 0x358ad344 -0, 22, 22, 1, 518400, 0x4462c642 -0, 23, 23, 1, 518400, 0x3bb43428 -0, 24, 24, 1, 518400, 0x12d6f8ca -0, 25, 25, 1, 518400, 0x003f13aa -0, 26, 26, 1, 518400, 0x6cd8c432 -0, 27, 27, 1, 518400, 0xee5ff01b -0, 28, 28, 1, 518400, 0xba0616ee -0, 29, 29, 1, 518400, 0x37fa7891 +0, 1, 1, 1, 518400, 0xd8b58a23 +0, 2, 2, 1, 518400, 0xe53b4aba +0, 3, 3, 1, 518400, 0x6cbca47a +0, 4, 4, 1, 518400, 0xceb51253 +0, 5, 5, 1, 518400, 0x60cb3cdd +0, 6, 6, 1, 518400, 0x7b633553 +0, 7, 7, 1, 518400, 0x10c012c9 +0, 8, 8, 1, 518400, 0xa340ee20 +0, 9, 9, 1, 518400, 0x574c22c2 +0, 10, 10, 1, 518400, 0xbcdb1bf7 +0, 11, 11, 1, 518400, 0x57811e9a +0, 12, 12, 1, 518400, 0xdd4af748 +0, 13, 13, 1, 518400, 0xb931a637 +0, 14, 14, 1, 518400, 0xcef6ce95 +0, 15, 15, 1, 518400, 0xd28c7085 +0, 16, 16, 1, 518400, 0xae9daf53 +0, 17, 17, 1, 518400, 0xca29d819 +0, 18, 18, 1, 518400, 0x3c4bd7eb +0, 19, 19, 1, 518400, 0x912ee227 +0, 20, 20, 1, 518400, 0xb67d0e27 +0, 21, 21, 1, 518400, 0x8cf7309d +0, 22, 22, 1, 518400, 0x358ad344 +0, 23, 23, 1, 518400, 0x4462c642 +0, 24, 24, 1, 518400, 0x3bb43428 +0, 25, 25, 1, 518400, 0x12d6f8ca +0, 26, 26, 1, 518400, 0x003f13aa +0, 27, 27, 1, 518400, 0x6cd8c432 +0, 28, 28, 1, 518400, 0xee5ff01b +0, 29, 29, 1, 518400, 0xba0616ee +0, 30, 30, 1, 518400, 0x37fa7891 diff --git a/tests/ref/fate/h264-conformance-cabref3_sand_d b/tests/ref/fate/h264-conformance-cabref3_sand_d index d5cd44587..5dfdfac3a 100644 --- a/tests/ref/fate/h264-conformance-cabref3_sand_d +++ b/tests/ref/fate/h264-conformance-cabref3_sand_d @@ -3,53 +3,53 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x2061bbd0 -0, 1, 1, 1, 152064, 0x41adb750 -0, 2, 2, 1, 152064, 0x6e889e90 -0, 3, 3, 1, 152064, 0xbb5e60f5 -0, 4, 4, 1, 152064, 0x5a32eca7 -0, 5, 5, 1, 152064, 0x5cb05e88 -0, 6, 6, 1, 152064, 0x2fff3e6c -0, 7, 7, 1, 152064, 0xd917c85e -0, 8, 8, 1, 152064, 0x6eac446f -0, 9, 9, 1, 152064, 0x238b24b0 -0, 10, 10, 1, 152064, 0x3f3bd44c -0, 11, 11, 1, 152064, 0x73982bc5 -0, 12, 12, 1, 152064, 0xf6188a82 -0, 13, 13, 1, 152064, 0x818c5b41 -0, 14, 14, 1, 152064, 0x000d1012 -0, 15, 15, 1, 152064, 0xc4a8750e -0, 16, 16, 1, 152064, 0x1689bb77 -0, 17, 17, 1, 152064, 0x8f52f338 -0, 18, 18, 1, 152064, 0xbf5ee06b -0, 19, 19, 1, 152064, 0x89508ad7 -0, 20, 20, 1, 152064, 0x2b1986a6 -0, 21, 21, 1, 152064, 0xe6fd6b0e -0, 22, 22, 1, 152064, 0x883e2e4e -0, 23, 23, 1, 152064, 0xd133db07 -0, 24, 24, 1, 152064, 0x39b3bb22 -0, 25, 25, 1, 152064, 0x8447410a -0, 26, 26, 1, 152064, 0x9c66c6e5 -0, 27, 27, 1, 152064, 0x514de9cc -0, 28, 28, 1, 152064, 0x08d9f1da -0, 29, 29, 1, 152064, 0x8f10f536 -0, 30, 30, 1, 152064, 0x57d4b27b -0, 31, 31, 1, 152064, 0x46f56d3c -0, 32, 32, 1, 152064, 0x5d260230 -0, 33, 33, 1, 152064, 0x4a72aeac -0, 34, 34, 1, 152064, 0x5cfe187f -0, 35, 35, 1, 152064, 0x08e55cb2 -0, 36, 36, 1, 152064, 0x4727f34f -0, 37, 37, 1, 152064, 0xd6a26f1c -0, 38, 38, 1, 152064, 0xcc1fcf9c -0, 39, 39, 1, 152064, 0x3681b775 -0, 40, 40, 1, 152064, 0xf580c7d9 -0, 41, 41, 1, 152064, 0xaa6747fb -0, 42, 42, 1, 152064, 0x2e22f9f9 -0, 43, 43, 1, 152064, 0xb3ee6d81 -0, 44, 44, 1, 152064, 0x930b0145 -0, 45, 45, 1, 152064, 0xae36af99 -0, 46, 46, 1, 152064, 0xeb58fd26 -0, 47, 47, 1, 152064, 0xb9004da3 -0, 48, 48, 1, 152064, 0x2b25e444 -0, 49, 49, 1, 152064, 0xb36927de +0, 1, 1, 1, 152064, 0x2061bbd0 +0, 2, 2, 1, 152064, 0x41adb750 +0, 3, 3, 1, 152064, 0x6e889e90 +0, 4, 4, 1, 152064, 0xbb5e60f5 +0, 5, 5, 1, 152064, 0x5a32eca7 +0, 6, 6, 1, 152064, 0x5cb05e88 +0, 7, 7, 1, 152064, 0x2fff3e6c +0, 8, 8, 1, 152064, 0xd917c85e +0, 9, 9, 1, 152064, 0x6eac446f +0, 10, 10, 1, 152064, 0x238b24b0 +0, 11, 11, 1, 152064, 0x3f3bd44c +0, 12, 12, 1, 152064, 0x73982bc5 +0, 13, 13, 1, 152064, 0xf6188a82 +0, 14, 14, 1, 152064, 0x818c5b41 +0, 15, 15, 1, 152064, 0x000d1012 +0, 16, 16, 1, 152064, 0xc4a8750e +0, 17, 17, 1, 152064, 0x1689bb77 +0, 18, 18, 1, 152064, 0x8f52f338 +0, 19, 19, 1, 152064, 0xbf5ee06b +0, 20, 20, 1, 152064, 0x89508ad7 +0, 21, 21, 1, 152064, 0x2b1986a6 +0, 22, 22, 1, 152064, 0xe6fd6b0e +0, 23, 23, 1, 152064, 0x883e2e4e +0, 24, 24, 1, 152064, 0xd133db07 +0, 25, 25, 1, 152064, 0x39b3bb22 +0, 26, 26, 1, 152064, 0x8447410a +0, 27, 27, 1, 152064, 0x9c66c6e5 +0, 28, 28, 1, 152064, 0x514de9cc +0, 29, 29, 1, 152064, 0x08d9f1da +0, 30, 30, 1, 152064, 0x8f10f536 +0, 31, 31, 1, 152064, 0x57d4b27b +0, 32, 32, 1, 152064, 0x46f56d3c +0, 33, 33, 1, 152064, 0x5d260230 +0, 34, 34, 1, 152064, 0x4a72aeac +0, 35, 35, 1, 152064, 0x5cfe187f +0, 36, 36, 1, 152064, 0x08e55cb2 +0, 37, 37, 1, 152064, 0x4727f34f +0, 38, 38, 1, 152064, 0xd6a26f1c +0, 39, 39, 1, 152064, 0xcc1fcf9c +0, 40, 40, 1, 152064, 0x3681b775 +0, 41, 41, 1, 152064, 0xf580c7d9 +0, 42, 42, 1, 152064, 0xaa6747fb +0, 43, 43, 1, 152064, 0x2e22f9f9 +0, 44, 44, 1, 152064, 0xb3ee6d81 +0, 45, 45, 1, 152064, 0x930b0145 +0, 46, 46, 1, 152064, 0xae36af99 +0, 47, 47, 1, 152064, 0xeb58fd26 +0, 48, 48, 1, 152064, 0xb9004da3 +0, 49, 49, 1, 152064, 0x2b25e444 +0, 50, 50, 1, 152064, 0xb36927de diff --git a/tests/ref/fate/h264-conformance-cafi1_sva_c b/tests/ref/fate/h264-conformance-cafi1_sva_c index 11d958fd4..91ae0fd93 100644 --- a/tests/ref/fate/h264-conformance-cafi1_sva_c +++ b/tests/ref/fate/h264-conformance-cafi1_sva_c @@ -3,36 +3,36 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0x47bd73fa -0, 1, 1, 1, 518400, 0xfe3ea7cc -0, 2, 2, 1, 518400, 0x9bc549ae -0, 3, 3, 1, 518400, 0x7bb7f0a1 -0, 4, 4, 1, 518400, 0x328903d4 -0, 5, 5, 1, 518400, 0x96ab366b -0, 6, 6, 1, 518400, 0xa923eed3 -0, 7, 7, 1, 518400, 0x162b08f6 -0, 8, 8, 1, 518400, 0xe711bd8b -0, 9, 9, 1, 518400, 0x55e2d4ed -0, 10, 10, 1, 518400, 0x7dd3107b -0, 11, 11, 1, 518400, 0x0ed20bcf -0, 12, 12, 1, 518400, 0x352f5743 -0, 13, 13, 1, 518400, 0x0a3aeb5e -0, 14, 14, 1, 518400, 0xc458eda3 -0, 15, 15, 1, 518400, 0xe8d5fec5 -0, 16, 16, 1, 518400, 0x18fc6c37 -0, 17, 17, 1, 518400, 0x448add76 -0, 18, 18, 1, 518400, 0x8741ead7 -0, 19, 19, 1, 518400, 0x7008a751 -0, 20, 20, 1, 518400, 0x4ca0633d -0, 21, 21, 1, 518400, 0x021ab800 -0, 22, 22, 1, 518400, 0xfb91ba57 -0, 23, 23, 1, 518400, 0x90e71dd0 -0, 24, 24, 1, 518400, 0xac859de5 -0, 25, 25, 1, 518400, 0xce9790bd -0, 26, 26, 1, 518400, 0x010ade8b -0, 27, 27, 1, 518400, 0xd0b3a399 -0, 28, 28, 1, 518400, 0x6cafcff3 -0, 29, 29, 1, 518400, 0xc32284c0 -0, 30, 30, 1, 518400, 0x1af8f73e -0, 31, 31, 1, 518400, 0x3babd71e -0, 32, 32, 1, 518400, 0xd77cb86b +0, 1, 1, 1, 518400, 0x47bd73fa +0, 2, 2, 1, 518400, 0xfe3ea7cc +0, 3, 3, 1, 518400, 0x9bc549ae +0, 4, 4, 1, 518400, 0x7bb7f0a1 +0, 5, 5, 1, 518400, 0x328903d4 +0, 6, 6, 1, 518400, 0x96ab366b +0, 7, 7, 1, 518400, 0xa923eed3 +0, 8, 8, 1, 518400, 0x162b08f6 +0, 9, 9, 1, 518400, 0xe711bd8b +0, 10, 10, 1, 518400, 0x55e2d4ed +0, 11, 11, 1, 518400, 0x7dd3107b +0, 12, 12, 1, 518400, 0x0ed20bcf +0, 13, 13, 1, 518400, 0x352f5743 +0, 14, 14, 1, 518400, 0x0a3aeb5e +0, 15, 15, 1, 518400, 0xc458eda3 +0, 16, 16, 1, 518400, 0xe8d5fec5 +0, 17, 17, 1, 518400, 0x18fc6c37 +0, 18, 18, 1, 518400, 0x448add76 +0, 19, 19, 1, 518400, 0x8741ead7 +0, 20, 20, 1, 518400, 0x7008a751 +0, 21, 21, 1, 518400, 0x4ca0633d +0, 22, 22, 1, 518400, 0x021ab800 +0, 23, 23, 1, 518400, 0xfb91ba57 +0, 24, 24, 1, 518400, 0x90e71dd0 +0, 25, 25, 1, 518400, 0xac859de5 +0, 26, 26, 1, 518400, 0xce9790bd +0, 27, 27, 1, 518400, 0x010ade8b +0, 28, 28, 1, 518400, 0xd0b3a399 +0, 29, 29, 1, 518400, 0x6cafcff3 +0, 30, 30, 1, 518400, 0xc32284c0 +0, 31, 31, 1, 518400, 0x1af8f73e +0, 32, 32, 1, 518400, 0x3babd71e +0, 33, 33, 1, 518400, 0xd77cb86b diff --git a/tests/ref/fate/h264-conformance-capa1_toshiba_b b/tests/ref/fate/h264-conformance-capa1_toshiba_b index c88dc547e..8a97a3045 100644 --- a/tests/ref/fate/h264-conformance-capa1_toshiba_b +++ b/tests/ref/fate/h264-conformance-capa1_toshiba_b @@ -3,93 +3,93 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x4040d2fc -0, 1, 1, 1, 152064, 0x0d8f9897 -0, 2, 2, 1, 152064, 0xc23321cd -0, 3, 3, 1, 152064, 0x3c9225eb -0, 4, 4, 1, 152064, 0x8927006f -0, 5, 5, 1, 152064, 0xf706a302 -0, 6, 6, 1, 152064, 0x8219c106 -0, 7, 7, 1, 152064, 0x06c990ea -0, 8, 8, 1, 152064, 0x3a0f1135 -0, 9, 9, 1, 152064, 0x4cff21d3 -0, 10, 10, 1, 152064, 0x6be0e050 -0, 11, 11, 1, 152064, 0x718b6c7b -0, 12, 12, 1, 152064, 0x24b38713 -0, 13, 13, 1, 152064, 0x500553fb -0, 14, 14, 1, 152064, 0x531ae610 -0, 15, 15, 1, 152064, 0x46f4ff1b -0, 16, 16, 1, 152064, 0xe5abe5ff -0, 17, 17, 1, 152064, 0x97daa351 -0, 18, 18, 1, 152064, 0xfbef0a8f -0, 19, 19, 1, 152064, 0xbe76134f -0, 20, 20, 1, 152064, 0xa4bf10ea -0, 21, 21, 1, 152064, 0xb2fb32af -0, 22, 22, 1, 152064, 0xd33027a5 -0, 23, 23, 1, 152064, 0x78e20c2b -0, 24, 24, 1, 152064, 0xefda2d6f -0, 25, 25, 1, 152064, 0xb99126f0 -0, 26, 26, 1, 152064, 0x89d7e465 -0, 27, 27, 1, 152064, 0x6150ff97 -0, 28, 28, 1, 152064, 0xde03d937 -0, 29, 29, 1, 152064, 0xd90ca874 -0, 30, 30, 1, 152064, 0xb120b294 -0, 31, 31, 1, 152064, 0x644eade4 -0, 32, 32, 1, 152064, 0xd1bb004f -0, 33, 33, 1, 152064, 0x99806a8b -0, 34, 34, 1, 152064, 0x8c6b635f -0, 35, 35, 1, 152064, 0xa269fa8b -0, 36, 36, 1, 152064, 0xc11c0e64 -0, 37, 37, 1, 152064, 0xac13f5eb -0, 38, 38, 1, 152064, 0x895799cf -0, 39, 39, 1, 152064, 0x95a9bea1 -0, 40, 40, 1, 152064, 0xe998dfba -0, 41, 41, 1, 152064, 0xc72d8460 -0, 42, 42, 1, 152064, 0xd1cb9b9a -0, 43, 43, 1, 152064, 0xb49aadd3 -0, 44, 44, 1, 152064, 0x8bc38547 -0, 45, 45, 1, 152064, 0x3485984b -0, 46, 46, 1, 152064, 0xdf305c0a -0, 47, 47, 1, 152064, 0x6a1ec990 -0, 48, 48, 1, 152064, 0x595e0de4 -0, 49, 49, 1, 152064, 0xe1baf7c4 -0, 50, 50, 1, 152064, 0xf08b9b47 -0, 51, 51, 1, 152064, 0x6532ba6f -0, 52, 52, 1, 152064, 0x3de67da6 -0, 53, 53, 1, 152064, 0x439ffd04 -0, 54, 54, 1, 152064, 0x6e6c1e97 -0, 55, 55, 1, 152064, 0x8e5aee7a -0, 56, 56, 1, 152064, 0xd634999a -0, 57, 57, 1, 152064, 0xadfa9e8b -0, 58, 58, 1, 152064, 0x1b9090f5 -0, 59, 59, 1, 152064, 0x29094dfc -0, 60, 60, 1, 152064, 0x56748851 -0, 61, 61, 1, 152064, 0x2316719d -0, 62, 62, 1, 152064, 0x2ee0060b -0, 63, 63, 1, 152064, 0x3edb36d4 -0, 64, 64, 1, 152064, 0x9ef437a3 -0, 65, 65, 1, 152064, 0x8d9af72e -0, 66, 66, 1, 152064, 0xab86389c -0, 67, 67, 1, 152064, 0xd3b34576 -0, 68, 68, 1, 152064, 0x9e5b04f4 -0, 69, 69, 1, 152064, 0x6a164c17 -0, 70, 70, 1, 152064, 0xcecf20ab -0, 71, 71, 1, 152064, 0x07c8e273 -0, 72, 72, 1, 152064, 0x9b46fe6a -0, 73, 73, 1, 152064, 0xc1e8002b -0, 74, 74, 1, 152064, 0xdebdbe53 -0, 75, 75, 1, 152064, 0x0d2dfd99 -0, 76, 76, 1, 152064, 0xe8ae925f -0, 77, 77, 1, 152064, 0xe1fe6272 -0, 78, 78, 1, 152064, 0xbb74d5e6 -0, 79, 79, 1, 152064, 0xc7b5d949 -0, 80, 80, 1, 152064, 0x9b15b020 -0, 81, 81, 1, 152064, 0xc8201f44 -0, 82, 82, 1, 152064, 0x30d03303 -0, 83, 83, 1, 152064, 0x9f66fbc2 -0, 84, 84, 1, 152064, 0x482b71ec -0, 85, 85, 1, 152064, 0x1c9e50bf -0, 86, 86, 1, 152064, 0x89f247e4 -0, 87, 87, 1, 152064, 0xaa5f9141 -0, 88, 88, 1, 152064, 0xb816aa8c -0, 89, 89, 1, 152064, 0x3112a619 +0, 1, 1, 1, 152064, 0x4040d2fc +0, 2, 2, 1, 152064, 0x0d8f9897 +0, 3, 3, 1, 152064, 0xc23321cd +0, 4, 4, 1, 152064, 0x3c9225eb +0, 5, 5, 1, 152064, 0x8927006f +0, 6, 6, 1, 152064, 0xf706a302 +0, 7, 7, 1, 152064, 0x8219c106 +0, 8, 8, 1, 152064, 0x06c990ea +0, 9, 9, 1, 152064, 0x3a0f1135 +0, 10, 10, 1, 152064, 0x4cff21d3 +0, 11, 11, 1, 152064, 0x6be0e050 +0, 12, 12, 1, 152064, 0x718b6c7b +0, 13, 13, 1, 152064, 0x24b38713 +0, 14, 14, 1, 152064, 0x500553fb +0, 15, 15, 1, 152064, 0x531ae610 +0, 16, 16, 1, 152064, 0x46f4ff1b +0, 17, 17, 1, 152064, 0xe5abe5ff +0, 18, 18, 1, 152064, 0x97daa351 +0, 19, 19, 1, 152064, 0xfbef0a8f +0, 20, 20, 1, 152064, 0xbe76134f +0, 21, 21, 1, 152064, 0xa4bf10ea +0, 22, 22, 1, 152064, 0xb2fb32af +0, 23, 23, 1, 152064, 0xd33027a5 +0, 24, 24, 1, 152064, 0x78e20c2b +0, 25, 25, 1, 152064, 0xefda2d6f +0, 26, 26, 1, 152064, 0xb99126f0 +0, 27, 27, 1, 152064, 0x89d7e465 +0, 28, 28, 1, 152064, 0x6150ff97 +0, 29, 29, 1, 152064, 0xde03d937 +0, 30, 30, 1, 152064, 0xd90ca874 +0, 31, 31, 1, 152064, 0xb120b294 +0, 32, 32, 1, 152064, 0x644eade4 +0, 33, 33, 1, 152064, 0xd1bb004f +0, 34, 34, 1, 152064, 0x99806a8b +0, 35, 35, 1, 152064, 0x8c6b635f +0, 36, 36, 1, 152064, 0xa269fa8b +0, 37, 37, 1, 152064, 0xc11c0e64 +0, 38, 38, 1, 152064, 0xac13f5eb +0, 39, 39, 1, 152064, 0x895799cf +0, 40, 40, 1, 152064, 0x95a9bea1 +0, 41, 41, 1, 152064, 0xe998dfba +0, 42, 42, 1, 152064, 0xc72d8460 +0, 43, 43, 1, 152064, 0xd1cb9b9a +0, 44, 44, 1, 152064, 0xb49aadd3 +0, 45, 45, 1, 152064, 0x8bc38547 +0, 46, 46, 1, 152064, 0x3485984b +0, 47, 47, 1, 152064, 0xdf305c0a +0, 48, 48, 1, 152064, 0x6a1ec990 +0, 49, 49, 1, 152064, 0x595e0de4 +0, 50, 50, 1, 152064, 0xe1baf7c4 +0, 51, 51, 1, 152064, 0xf08b9b47 +0, 52, 52, 1, 152064, 0x6532ba6f +0, 53, 53, 1, 152064, 0x3de67da6 +0, 54, 54, 1, 152064, 0x439ffd04 +0, 55, 55, 1, 152064, 0x6e6c1e97 +0, 56, 56, 1, 152064, 0x8e5aee7a +0, 57, 57, 1, 152064, 0xd634999a +0, 58, 58, 1, 152064, 0xadfa9e8b +0, 59, 59, 1, 152064, 0x1b9090f5 +0, 60, 60, 1, 152064, 0x29094dfc +0, 61, 61, 1, 152064, 0x56748851 +0, 62, 62, 1, 152064, 0x2316719d +0, 63, 63, 1, 152064, 0x2ee0060b +0, 64, 64, 1, 152064, 0x3edb36d4 +0, 65, 65, 1, 152064, 0x9ef437a3 +0, 66, 66, 1, 152064, 0x8d9af72e +0, 67, 67, 1, 152064, 0xab86389c +0, 68, 68, 1, 152064, 0xd3b34576 +0, 69, 69, 1, 152064, 0x9e5b04f4 +0, 70, 70, 1, 152064, 0x6a164c17 +0, 71, 71, 1, 152064, 0xcecf20ab +0, 72, 72, 1, 152064, 0x07c8e273 +0, 73, 73, 1, 152064, 0x9b46fe6a +0, 74, 74, 1, 152064, 0xc1e8002b +0, 75, 75, 1, 152064, 0xdebdbe53 +0, 76, 76, 1, 152064, 0x0d2dfd99 +0, 77, 77, 1, 152064, 0xe8ae925f +0, 78, 78, 1, 152064, 0xe1fe6272 +0, 79, 79, 1, 152064, 0xbb74d5e6 +0, 80, 80, 1, 152064, 0xc7b5d949 +0, 81, 81, 1, 152064, 0x9b15b020 +0, 82, 82, 1, 152064, 0xc8201f44 +0, 83, 83, 1, 152064, 0x30d03303 +0, 84, 84, 1, 152064, 0x9f66fbc2 +0, 85, 85, 1, 152064, 0x482b71ec +0, 86, 86, 1, 152064, 0x1c9e50bf +0, 87, 87, 1, 152064, 0x89f247e4 +0, 88, 88, 1, 152064, 0xaa5f9141 +0, 89, 89, 1, 152064, 0xb816aa8c +0, 90, 90, 1, 152064, 0x3112a619 diff --git a/tests/ref/fate/h264-conformance-capama3_sand_f b/tests/ref/fate/h264-conformance-capama3_sand_f index b847b9a2b..50d546049 100644 --- a/tests/ref/fate/h264-conformance-capama3_sand_f +++ b/tests/ref/fate/h264-conformance-capama3_sand_f @@ -3,53 +3,53 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0xf772f152 -0, 1, 1, 1, 152064, 0xc416d300 -0, 2, 2, 1, 152064, 0xc2275c94 -0, 3, 3, 1, 152064, 0x1bd35645 -0, 4, 4, 1, 152064, 0x60327bf5 -0, 5, 5, 1, 152064, 0x7f5541bd -0, 6, 6, 1, 152064, 0x52e5ebad -0, 7, 7, 1, 152064, 0xb8e5c1f3 -0, 8, 8, 1, 152064, 0x2b4e3653 -0, 9, 9, 1, 152064, 0x9a8f8499 -0, 10, 10, 1, 152064, 0x32d4e9fb -0, 11, 11, 1, 152064, 0x0bc73d7a -0, 12, 12, 1, 152064, 0xb58a8b87 -0, 13, 13, 1, 152064, 0xddbc5468 -0, 14, 14, 1, 152064, 0xcfa30b64 -0, 15, 15, 1, 152064, 0xad411f36 -0, 16, 16, 1, 152064, 0x2f8c4d9b -0, 17, 17, 1, 152064, 0xc8523359 -0, 18, 18, 1, 152064, 0x86be9861 -0, 19, 19, 1, 152064, 0x7518d731 -0, 20, 20, 1, 152064, 0x425fbfab -0, 21, 21, 1, 152064, 0x4f00250d -0, 22, 22, 1, 152064, 0x12b40617 -0, 23, 23, 1, 152064, 0x65ff925d -0, 24, 24, 1, 152064, 0xc76a94c9 -0, 25, 25, 1, 152064, 0x640170d5 -0, 26, 26, 1, 152064, 0xd338a090 -0, 27, 27, 1, 152064, 0xce715174 -0, 28, 28, 1, 152064, 0x7bded195 -0, 29, 29, 1, 152064, 0x09e7d3b9 -0, 30, 30, 1, 152064, 0x651e1518 -0, 31, 31, 1, 152064, 0x03cadc5f -0, 32, 32, 1, 152064, 0x08906919 -0, 33, 33, 1, 152064, 0x3303ebe0 -0, 34, 34, 1, 152064, 0xa28676c5 -0, 35, 35, 1, 152064, 0x3900ecaf -0, 36, 36, 1, 152064, 0xeb795a05 -0, 37, 37, 1, 152064, 0x870034df -0, 38, 38, 1, 152064, 0x69b0527a -0, 39, 39, 1, 152064, 0xb2b314f9 -0, 40, 40, 1, 152064, 0x1a44ea1a -0, 41, 41, 1, 152064, 0xe6eaec87 -0, 42, 42, 1, 152064, 0xd9ad818e -0, 43, 43, 1, 152064, 0x9c7ff76e -0, 44, 44, 1, 152064, 0x74c45abb -0, 45, 45, 1, 152064, 0x2f4fa5c6 -0, 46, 46, 1, 152064, 0x19620702 -0, 47, 47, 1, 152064, 0xfc9601f3 -0, 48, 48, 1, 152064, 0x33e0d8e7 -0, 49, 49, 1, 152064, 0xdf7f2a80 +0, 1, 1, 1, 152064, 0xf772f152 +0, 2, 2, 1, 152064, 0xc416d300 +0, 3, 3, 1, 152064, 0xc2275c94 +0, 4, 4, 1, 152064, 0x1bd35645 +0, 5, 5, 1, 152064, 0x60327bf5 +0, 6, 6, 1, 152064, 0x7f5541bd +0, 7, 7, 1, 152064, 0x52e5ebad +0, 8, 8, 1, 152064, 0xb8e5c1f3 +0, 9, 9, 1, 152064, 0x2b4e3653 +0, 10, 10, 1, 152064, 0x9a8f8499 +0, 11, 11, 1, 152064, 0x32d4e9fb +0, 12, 12, 1, 152064, 0x0bc73d7a +0, 13, 13, 1, 152064, 0xb58a8b87 +0, 14, 14, 1, 152064, 0xddbc5468 +0, 15, 15, 1, 152064, 0xcfa30b64 +0, 16, 16, 1, 152064, 0xad411f36 +0, 17, 17, 1, 152064, 0x2f8c4d9b +0, 18, 18, 1, 152064, 0xc8523359 +0, 19, 19, 1, 152064, 0x86be9861 +0, 20, 20, 1, 152064, 0x7518d731 +0, 21, 21, 1, 152064, 0x425fbfab +0, 22, 22, 1, 152064, 0x4f00250d +0, 23, 23, 1, 152064, 0x12b40617 +0, 24, 24, 1, 152064, 0x65ff925d +0, 25, 25, 1, 152064, 0xc76a94c9 +0, 26, 26, 1, 152064, 0x640170d5 +0, 27, 27, 1, 152064, 0xd338a090 +0, 28, 28, 1, 152064, 0xce715174 +0, 29, 29, 1, 152064, 0x7bded195 +0, 30, 30, 1, 152064, 0x09e7d3b9 +0, 31, 31, 1, 152064, 0x651e1518 +0, 32, 32, 1, 152064, 0x03cadc5f +0, 33, 33, 1, 152064, 0x08906919 +0, 34, 34, 1, 152064, 0x3303ebe0 +0, 35, 35, 1, 152064, 0xa28676c5 +0, 36, 36, 1, 152064, 0x3900ecaf +0, 37, 37, 1, 152064, 0xeb795a05 +0, 38, 38, 1, 152064, 0x870034df +0, 39, 39, 1, 152064, 0x69b0527a +0, 40, 40, 1, 152064, 0xb2b314f9 +0, 41, 41, 1, 152064, 0x1a44ea1a +0, 42, 42, 1, 152064, 0xe6eaec87 +0, 43, 43, 1, 152064, 0xd9ad818e +0, 44, 44, 1, 152064, 0x9c7ff76e +0, 45, 45, 1, 152064, 0x74c45abb +0, 46, 46, 1, 152064, 0x2f4fa5c6 +0, 47, 47, 1, 152064, 0x19620702 +0, 48, 48, 1, 152064, 0xfc9601f3 +0, 49, 49, 1, 152064, 0x33e0d8e7 +0, 50, 50, 1, 152064, 0xdf7f2a80 diff --git a/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b b/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b index 0ee9a397f..7c5663e62 100644 --- a/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b +++ b/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b @@ -3,33 +3,33 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0x99d0df36 -0, 1, 1, 1, 518400, 0xa8601c1a -0, 2, 2, 1, 518400, 0x4a17d235 -0, 3, 3, 1, 518400, 0x75f23abf -0, 4, 4, 1, 518400, 0x746aad53 -0, 5, 5, 1, 518400, 0xb0b8913e -0, 6, 6, 1, 518400, 0x60a27f57 -0, 7, 7, 1, 518400, 0xfa227f3e -0, 8, 8, 1, 518400, 0x7a1e57c2 -0, 9, 9, 1, 518400, 0xcbbaa84f -0, 10, 10, 1, 518400, 0xf9c1bd13 -0, 11, 11, 1, 518400, 0x9e80caaf -0, 12, 12, 1, 518400, 0x14cc6928 -0, 13, 13, 1, 518400, 0xca0353ef -0, 14, 14, 1, 518400, 0xcad65e5f -0, 15, 15, 1, 518400, 0xd5bc47b3 -0, 16, 16, 1, 518400, 0xa9893d36 -0, 17, 17, 1, 518400, 0x69bd9085 -0, 18, 18, 1, 518400, 0xff33c476 -0, 19, 19, 1, 518400, 0x9538adf7 -0, 20, 20, 1, 518400, 0xd4ff3b62 -0, 21, 21, 1, 518400, 0x021a11fd -0, 22, 22, 1, 518400, 0x293e6f9f -0, 23, 23, 1, 518400, 0x5d38e4c3 -0, 24, 24, 1, 518400, 0xd1f4ad49 -0, 25, 25, 1, 518400, 0xf13dd946 -0, 26, 26, 1, 518400, 0x0359e9ff -0, 27, 27, 1, 518400, 0xb61098ad -0, 28, 28, 1, 518400, 0xa855b11c -0, 29, 29, 1, 518400, 0x7fcf9343 +0, 1, 1, 1, 518400, 0x99d0df36 +0, 2, 2, 1, 518400, 0xa8601c1a +0, 3, 3, 1, 518400, 0x4a17d235 +0, 4, 4, 1, 518400, 0x75f23abf +0, 5, 5, 1, 518400, 0x746aad53 +0, 6, 6, 1, 518400, 0xb0b8913e +0, 7, 7, 1, 518400, 0x60a27f57 +0, 8, 8, 1, 518400, 0xfa227f3e +0, 9, 9, 1, 518400, 0x7a1e57c2 +0, 10, 10, 1, 518400, 0xcbbaa84f +0, 11, 11, 1, 518400, 0xf9c1bd13 +0, 12, 12, 1, 518400, 0x9e80caaf +0, 13, 13, 1, 518400, 0x14cc6928 +0, 14, 14, 1, 518400, 0xca0353ef +0, 15, 15, 1, 518400, 0xcad65e5f +0, 16, 16, 1, 518400, 0xd5bc47b3 +0, 17, 17, 1, 518400, 0xa9893d36 +0, 18, 18, 1, 518400, 0x69bd9085 +0, 19, 19, 1, 518400, 0xff33c476 +0, 20, 20, 1, 518400, 0x9538adf7 +0, 21, 21, 1, 518400, 0xd4ff3b62 +0, 22, 22, 1, 518400, 0x021a11fd +0, 23, 23, 1, 518400, 0x293e6f9f +0, 24, 24, 1, 518400, 0x5d38e4c3 +0, 25, 25, 1, 518400, 0xd1f4ad49 +0, 26, 26, 1, 518400, 0xf13dd946 +0, 27, 27, 1, 518400, 0x0359e9ff +0, 28, 28, 1, 518400, 0xb61098ad +0, 29, 29, 1, 518400, 0xa855b11c +0, 30, 30, 1, 518400, 0x7fcf9343 diff --git a/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b b/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b index c0f6a5ed1..8b63e8b5e 100644 --- a/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b +++ b/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b @@ -3,33 +3,33 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0xf6b83a0e -0, 1, 1, 1, 518400, 0xc5e8b8ee -0, 2, 2, 1, 518400, 0xb3bc6e43 -0, 3, 3, 1, 518400, 0x5b08dc73 -0, 4, 4, 1, 518400, 0x4a7f7690 -0, 5, 5, 1, 518400, 0x8a9f4275 -0, 6, 6, 1, 518400, 0xc7cb92fd -0, 7, 7, 1, 518400, 0xc721e231 -0, 8, 8, 1, 518400, 0xfb31371b -0, 9, 9, 1, 518400, 0xac57f5d9 -0, 10, 10, 1, 518400, 0x92b7debc -0, 11, 11, 1, 518400, 0xfe3e533e -0, 12, 12, 1, 518400, 0x1b3a7a72 -0, 13, 13, 1, 518400, 0x98df2d81 -0, 14, 14, 1, 518400, 0xe0ce9c52 -0, 15, 15, 1, 518400, 0x6a31166d -0, 16, 16, 1, 518400, 0x64ffd4d2 -0, 17, 17, 1, 518400, 0x3ec062ef -0, 18, 18, 1, 518400, 0x3480fae1 -0, 19, 19, 1, 518400, 0xa87ae4b7 -0, 20, 20, 1, 518400, 0xd301319f -0, 21, 21, 1, 518400, 0xa9284989 -0, 22, 22, 1, 518400, 0x3de73b50 -0, 23, 23, 1, 518400, 0x30a79f84 -0, 24, 24, 1, 518400, 0x7d5152d4 -0, 25, 25, 1, 518400, 0x25514095 -0, 26, 26, 1, 518400, 0x1749a05f -0, 27, 27, 1, 518400, 0x598139a7 -0, 28, 28, 1, 518400, 0x3cece862 -0, 29, 29, 1, 518400, 0xe1c27efe +0, 1, 1, 1, 518400, 0xf6b83a0e +0, 2, 2, 1, 518400, 0xc5e8b8ee +0, 3, 3, 1, 518400, 0xb3bc6e43 +0, 4, 4, 1, 518400, 0x5b08dc73 +0, 5, 5, 1, 518400, 0x4a7f7690 +0, 6, 6, 1, 518400, 0x8a9f4275 +0, 7, 7, 1, 518400, 0xc7cb92fd +0, 8, 8, 1, 518400, 0xc721e231 +0, 9, 9, 1, 518400, 0xfb31371b +0, 10, 10, 1, 518400, 0xac57f5d9 +0, 11, 11, 1, 518400, 0x92b7debc +0, 12, 12, 1, 518400, 0xfe3e533e +0, 13, 13, 1, 518400, 0x1b3a7a72 +0, 14, 14, 1, 518400, 0x98df2d81 +0, 15, 15, 1, 518400, 0xe0ce9c52 +0, 16, 16, 1, 518400, 0x6a31166d +0, 17, 17, 1, 518400, 0x64ffd4d2 +0, 18, 18, 1, 518400, 0x3ec062ef +0, 19, 19, 1, 518400, 0x3480fae1 +0, 20, 20, 1, 518400, 0xa87ae4b7 +0, 21, 21, 1, 518400, 0xd301319f +0, 22, 22, 1, 518400, 0xa9284989 +0, 23, 23, 1, 518400, 0x3de73b50 +0, 24, 24, 1, 518400, 0x30a79f84 +0, 25, 25, 1, 518400, 0x7d5152d4 +0, 26, 26, 1, 518400, 0x25514095 +0, 27, 27, 1, 518400, 0x1749a05f +0, 28, 28, 1, 518400, 0x598139a7 +0, 29, 29, 1, 518400, 0x3cece862 +0, 30, 30, 1, 518400, 0xe1c27efe diff --git a/tests/ref/fate/h264-conformance-cvfi1_sony_d b/tests/ref/fate/h264-conformance-cvfi1_sony_d index bf998bcf8..bcb2a1506 100644 --- a/tests/ref/fate/h264-conformance-cvfi1_sony_d +++ b/tests/ref/fate/h264-conformance-cvfi1_sony_d @@ -3,20 +3,20 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0xd9444d71 -0, 1, 1, 1, 518400, 0x5d8928cd -0, 2, 2, 1, 518400, 0xea5bc08b -0, 3, 3, 1, 518400, 0xb4465d31 -0, 4, 4, 1, 518400, 0x983b5dbb -0, 5, 5, 1, 518400, 0x54936746 -0, 6, 6, 1, 518400, 0x7ae38b02 -0, 7, 7, 1, 518400, 0xc2a0dd83 -0, 8, 8, 1, 518400, 0x61cac7a6 -0, 9, 9, 1, 518400, 0xb0038443 -0, 10, 10, 1, 518400, 0x16514296 -0, 11, 11, 1, 518400, 0xa68dd470 -0, 12, 12, 1, 518400, 0x2572f868 -0, 13, 13, 1, 518400, 0x770a3239 -0, 14, 14, 1, 518400, 0xdd04f6d2 -0, 15, 15, 1, 518400, 0xa5e5d01e -0, 16, 16, 1, 518400, 0x5fe25c86 +0, 1, 1, 1, 518400, 0xd9444d71 +0, 2, 2, 1, 518400, 0x5d8928cd +0, 3, 3, 1, 518400, 0xea5bc08b +0, 4, 4, 1, 518400, 0xb4465d31 +0, 5, 5, 1, 518400, 0x983b5dbb +0, 6, 6, 1, 518400, 0x54936746 +0, 7, 7, 1, 518400, 0x7ae38b02 +0, 8, 8, 1, 518400, 0xc2a0dd83 +0, 9, 9, 1, 518400, 0x61cac7a6 +0, 10, 10, 1, 518400, 0xb0038443 +0, 11, 11, 1, 518400, 0x16514296 +0, 12, 12, 1, 518400, 0xa68dd470 +0, 13, 13, 1, 518400, 0x2572f868 +0, 14, 14, 1, 518400, 0x770a3239 +0, 15, 15, 1, 518400, 0xdd04f6d2 +0, 16, 16, 1, 518400, 0xa5e5d01e +0, 17, 17, 1, 518400, 0x5fe25c86 diff --git a/tests/ref/fate/h264-conformance-cvfi1_sva_c b/tests/ref/fate/h264-conformance-cvfi1_sva_c index 55628842f..1a4841a37 100644 --- a/tests/ref/fate/h264-conformance-cvfi1_sva_c +++ b/tests/ref/fate/h264-conformance-cvfi1_sva_c @@ -3,10 +3,10 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0x8f022263 -0, 1, 1, 1, 518400, 0x02692654 -0, 2, 2, 1, 518400, 0x55eff579 -0, 3, 3, 1, 518400, 0x6c1bdf1d -0, 4, 4, 1, 518400, 0xbbedf5e4 -0, 5, 5, 1, 518400, 0xb90d740d -0, 6, 6, 1, 518400, 0x81300adb +0, 1, 1, 1, 518400, 0x8f022263 +0, 2, 2, 1, 518400, 0x02692654 +0, 3, 3, 1, 518400, 0x55eff579 +0, 4, 4, 1, 518400, 0x6c1bdf1d +0, 5, 5, 1, 518400, 0xbbedf5e4 +0, 6, 6, 1, 518400, 0xb90d740d +0, 7, 7, 1, 518400, 0x81300adb diff --git a/tests/ref/fate/h264-conformance-cvfi2_sony_h b/tests/ref/fate/h264-conformance-cvfi2_sony_h index deb9b38ad..f86d077f0 100644 --- a/tests/ref/fate/h264-conformance-cvfi2_sony_h +++ b/tests/ref/fate/h264-conformance-cvfi2_sony_h @@ -3,20 +3,20 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0xd9444d71 -0, 1, 1, 1, 518400, 0x491faf75 -0, 2, 2, 1, 518400, 0xf8b4d15c -0, 3, 3, 1, 518400, 0x99d9f60c -0, 4, 4, 1, 518400, 0x46c17a6d -0, 5, 5, 1, 518400, 0x30b9447d -0, 6, 6, 1, 518400, 0x135d0c76 -0, 7, 7, 1, 518400, 0x1b831a3c -0, 8, 8, 1, 518400, 0x5910def8 -0, 9, 9, 1, 518400, 0x8db90147 -0, 10, 10, 1, 518400, 0x6a2b79c7 -0, 11, 11, 1, 518400, 0xc8d302e5 -0, 12, 12, 1, 518400, 0x515bb024 -0, 13, 13, 1, 518400, 0xedf7836c -0, 14, 14, 1, 518400, 0x7e247b9d -0, 15, 15, 1, 518400, 0x10c9bb10 -0, 16, 16, 1, 518400, 0xe38e2807 +0, 1, 1, 1, 518400, 0xd9444d71 +0, 2, 2, 1, 518400, 0x491faf75 +0, 3, 3, 1, 518400, 0xf8b4d15c +0, 4, 4, 1, 518400, 0x99d9f60c +0, 5, 5, 1, 518400, 0x46c17a6d +0, 6, 6, 1, 518400, 0x30b9447d +0, 7, 7, 1, 518400, 0x135d0c76 +0, 8, 8, 1, 518400, 0x1b831a3c +0, 9, 9, 1, 518400, 0x5910def8 +0, 10, 10, 1, 518400, 0x8db90147 +0, 11, 11, 1, 518400, 0x6a2b79c7 +0, 12, 12, 1, 518400, 0xc8d302e5 +0, 13, 13, 1, 518400, 0x515bb024 +0, 14, 14, 1, 518400, 0xedf7836c +0, 15, 15, 1, 518400, 0x7e247b9d +0, 16, 16, 1, 518400, 0x10c9bb10 +0, 17, 17, 1, 518400, 0xe38e2807 diff --git a/tests/ref/fate/h264-conformance-cvfi2_sva_c b/tests/ref/fate/h264-conformance-cvfi2_sva_c index e2a0b6da7..5fe4546d1 100644 --- a/tests/ref/fate/h264-conformance-cvfi2_sva_c +++ b/tests/ref/fate/h264-conformance-cvfi2_sva_c @@ -3,16 +3,16 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0x4073cc0b -0, 1, 1, 1, 518400, 0x5f599a48 -0, 2, 2, 1, 518400, 0xc6fe555a -0, 3, 3, 1, 518400, 0xe63ac345 -0, 4, 4, 1, 518400, 0x9b4f0c5c -0, 5, 5, 1, 518400, 0x98aaba2d -0, 6, 6, 1, 518400, 0xd629bd09 -0, 7, 7, 1, 518400, 0xe9796c37 -0, 8, 8, 1, 518400, 0xba54d16e -0, 9, 9, 1, 518400, 0xe396c3eb -0, 10, 10, 1, 518400, 0x63ee4b81 -0, 11, 11, 1, 518400, 0x68ac6986 -0, 12, 12, 1, 518400, 0xe0d53000 +0, 1, 1, 1, 518400, 0x4073cc0b +0, 2, 2, 1, 518400, 0x5f599a48 +0, 3, 3, 1, 518400, 0xc6fe555a +0, 4, 4, 1, 518400, 0xe63ac345 +0, 5, 5, 1, 518400, 0x9b4f0c5c +0, 6, 6, 1, 518400, 0x98aaba2d +0, 7, 7, 1, 518400, 0xd629bd09 +0, 8, 8, 1, 518400, 0xe9796c37 +0, 9, 9, 1, 518400, 0xba54d16e +0, 10, 10, 1, 518400, 0xe396c3eb +0, 11, 11, 1, 518400, 0x63ee4b81 +0, 12, 12, 1, 518400, 0x68ac6986 +0, 13, 13, 1, 518400, 0xe0d53000 diff --git a/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e b/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e index 8cc81e62a..d29adc899 100644 --- a/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e +++ b/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e @@ -4,10 +4,10 @@ #dimensions 0: 720x480 #sar 0: 0/1 0, 0, 0, 1, 518400, 0x80dffda2 -0, 1, 1, 1, 518400, 0x9450183b -0, 2, 2, 1, 518400, 0x85d429a7 -0, 3, 3, 1, 518400, 0xe1f3b686 -0, 4, 4, 1, 518400, 0x2180c761 -0, 5, 5, 1, 518400, 0x30269c7c -0, 6, 6, 1, 518400, 0xe9aa575a -0, 7, 7, 1, 518400, 0x7b815a0a +0, 2, 2, 1, 518400, 0x9450183b +0, 3, 3, 1, 518400, 0x85d429a7 +0, 4, 4, 1, 518400, 0xe1f3b686 +0, 5, 5, 1, 518400, 0x2180c761 +0, 6, 6, 1, 518400, 0x30269c7c +0, 7, 7, 1, 518400, 0xe9aa575a +0, 8, 8, 1, 518400, 0x7b815a0a diff --git a/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b b/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b index 94d4dff0b..2f3f50dc9 100644 --- a/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b +++ b/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b @@ -3,33 +3,33 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0xe9c7643e -0, 1, 1, 1, 518400, 0xba7456ec -0, 2, 2, 1, 518400, 0xdeb96749 -0, 3, 3, 1, 518400, 0xa101a986 -0, 4, 4, 1, 518400, 0x3db7baa5 -0, 5, 5, 1, 518400, 0xf3dfcec7 -0, 6, 6, 1, 518400, 0x79b4f537 -0, 7, 7, 1, 518400, 0x9e64fe68 -0, 8, 8, 1, 518400, 0x0e810b53 -0, 9, 9, 1, 518400, 0x20baf3b8 -0, 10, 10, 1, 518400, 0x0a49d341 -0, 11, 11, 1, 518400, 0xa8304ab5 -0, 12, 12, 1, 518400, 0x2600e98f -0, 13, 13, 1, 518400, 0x9253e3e8 -0, 14, 14, 1, 518400, 0xd6e12783 -0, 15, 15, 1, 518400, 0x6894fc79 -0, 16, 16, 1, 518400, 0xfb60d3e3 -0, 17, 17, 1, 518400, 0x523602be -0, 18, 18, 1, 518400, 0x4979f409 -0, 19, 19, 1, 518400, 0x50d4e2ab -0, 20, 20, 1, 518400, 0xa8c2140a -0, 21, 21, 1, 518400, 0x45c0bc15 -0, 22, 22, 1, 518400, 0xaef78cab -0, 23, 23, 1, 518400, 0xec539d02 -0, 24, 24, 1, 518400, 0x602585ea -0, 25, 25, 1, 518400, 0xda263463 -0, 26, 26, 1, 518400, 0xa03d8922 -0, 27, 27, 1, 518400, 0x43ea1c1d -0, 28, 28, 1, 518400, 0xb1e055a6 -0, 29, 29, 1, 518400, 0x6fff9398 +0, 1, 1, 1, 518400, 0xe9c7643e +0, 2, 2, 1, 518400, 0xba7456ec +0, 3, 3, 1, 518400, 0xdeb96749 +0, 4, 4, 1, 518400, 0xa101a986 +0, 5, 5, 1, 518400, 0x3db7baa5 +0, 6, 6, 1, 518400, 0xf3dfcec7 +0, 7, 7, 1, 518400, 0x79b4f537 +0, 8, 8, 1, 518400, 0x9e64fe68 +0, 9, 9, 1, 518400, 0x0e810b53 +0, 10, 10, 1, 518400, 0x20baf3b8 +0, 11, 11, 1, 518400, 0x0a49d341 +0, 12, 12, 1, 518400, 0xa8304ab5 +0, 13, 13, 1, 518400, 0x2600e98f +0, 14, 14, 1, 518400, 0x9253e3e8 +0, 15, 15, 1, 518400, 0xd6e12783 +0, 16, 16, 1, 518400, 0x6894fc79 +0, 17, 17, 1, 518400, 0xfb60d3e3 +0, 18, 18, 1, 518400, 0x523602be +0, 19, 19, 1, 518400, 0x4979f409 +0, 20, 20, 1, 518400, 0x50d4e2ab +0, 21, 21, 1, 518400, 0xa8c2140a +0, 22, 22, 1, 518400, 0x45c0bc15 +0, 23, 23, 1, 518400, 0xaef78cab +0, 24, 24, 1, 518400, 0xec539d02 +0, 25, 25, 1, 518400, 0x602585ea +0, 26, 26, 1, 518400, 0xda263463 +0, 27, 27, 1, 518400, 0xa03d8922 +0, 28, 28, 1, 518400, 0x43ea1c1d +0, 29, 29, 1, 518400, 0xb1e055a6 +0, 30, 30, 1, 518400, 0x6fff9398 diff --git a/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b b/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b index fc6b1b7d5..25d46c4bb 100644 --- a/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b +++ b/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b @@ -3,33 +3,33 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0x7b2475e3 -0, 1, 1, 1, 518400, 0xda786a87 -0, 2, 2, 1, 518400, 0xb1dd8108 -0, 3, 3, 1, 518400, 0x760ed65d -0, 4, 4, 1, 518400, 0x8632d20c -0, 5, 5, 1, 518400, 0xdd81e625 -0, 6, 6, 1, 518400, 0x853f1c41 -0, 7, 7, 1, 518400, 0x20191585 -0, 8, 8, 1, 518400, 0x0367e357 -0, 9, 9, 1, 518400, 0x60521167 -0, 10, 10, 1, 518400, 0xa887d4cc -0, 11, 11, 1, 518400, 0x9a450f9e -0, 12, 12, 1, 518400, 0xe9620841 -0, 13, 13, 1, 518400, 0xb482fb0e -0, 14, 14, 1, 518400, 0x7b79f670 -0, 15, 15, 1, 518400, 0x9d37f1d1 -0, 16, 16, 1, 518400, 0xe358d323 -0, 17, 17, 1, 518400, 0x62ade59c -0, 18, 18, 1, 518400, 0xdd78da66 -0, 19, 19, 1, 518400, 0xd97b867b -0, 20, 20, 1, 518400, 0x8a90cf8c -0, 21, 21, 1, 518400, 0x9d386610 -0, 22, 22, 1, 518400, 0x2c590f46 -0, 23, 23, 1, 518400, 0x92662861 -0, 24, 24, 1, 518400, 0x6979f563 -0, 25, 25, 1, 518400, 0xdd0fa1b2 -0, 26, 26, 1, 518400, 0xccbf1c1c -0, 27, 27, 1, 518400, 0x7e358112 -0, 28, 28, 1, 518400, 0xb7c0d89d -0, 29, 29, 1, 518400, 0xc6b03973 +0, 1, 1, 1, 518400, 0x7b2475e3 +0, 2, 2, 1, 518400, 0xda786a87 +0, 3, 3, 1, 518400, 0xb1dd8108 +0, 4, 4, 1, 518400, 0x760ed65d +0, 5, 5, 1, 518400, 0x8632d20c +0, 6, 6, 1, 518400, 0xdd81e625 +0, 7, 7, 1, 518400, 0x853f1c41 +0, 8, 8, 1, 518400, 0x20191585 +0, 9, 9, 1, 518400, 0x0367e357 +0, 10, 10, 1, 518400, 0x60521167 +0, 11, 11, 1, 518400, 0xa887d4cc +0, 12, 12, 1, 518400, 0x9a450f9e +0, 13, 13, 1, 518400, 0xe9620841 +0, 14, 14, 1, 518400, 0xb482fb0e +0, 15, 15, 1, 518400, 0x7b79f670 +0, 16, 16, 1, 518400, 0x9d37f1d1 +0, 17, 17, 1, 518400, 0xe358d323 +0, 18, 18, 1, 518400, 0x62ade59c +0, 19, 19, 1, 518400, 0xdd78da66 +0, 20, 20, 1, 518400, 0xd97b867b +0, 21, 21, 1, 518400, 0x8a90cf8c +0, 22, 22, 1, 518400, 0x9d386610 +0, 23, 23, 1, 518400, 0x2c590f46 +0, 24, 24, 1, 518400, 0x92662861 +0, 25, 25, 1, 518400, 0x6979f563 +0, 26, 26, 1, 518400, 0xdd0fa1b2 +0, 27, 27, 1, 518400, 0xccbf1c1c +0, 28, 28, 1, 518400, 0x7e358112 +0, 29, 29, 1, 518400, 0xb7c0d89d +0, 30, 30, 1, 518400, 0xc6b03973 diff --git a/tests/ref/fate/h264-conformance-cvnlfi1_sony_c b/tests/ref/fate/h264-conformance-cvnlfi1_sony_c index 02a6b5375..47b1a4b2a 100644 --- a/tests/ref/fate/h264-conformance-cvnlfi1_sony_c +++ b/tests/ref/fate/h264-conformance-cvnlfi1_sony_c @@ -3,20 +3,20 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0x0fbb4e71 -0, 1, 1, 1, 518400, 0x4b816734 -0, 2, 2, 1, 518400, 0x0c350f19 -0, 3, 3, 1, 518400, 0xda049cb6 -0, 4, 4, 1, 518400, 0x1f3e7bb9 -0, 5, 5, 1, 518400, 0x995cbe66 -0, 6, 6, 1, 518400, 0x07f7e65c -0, 7, 7, 1, 518400, 0xfcb7487f -0, 8, 8, 1, 518400, 0xb080f48a -0, 9, 9, 1, 518400, 0x3ef5b7e4 -0, 10, 10, 1, 518400, 0xa1518e1c -0, 11, 11, 1, 518400, 0xb36f1cc9 -0, 12, 12, 1, 518400, 0x86ea48af -0, 13, 13, 1, 518400, 0xe42373b7 -0, 14, 14, 1, 518400, 0xa8435828 -0, 15, 15, 1, 518400, 0xc942ea0e -0, 16, 16, 1, 518400, 0xcc597514 +0, 1, 1, 1, 518400, 0x0fbb4e71 +0, 2, 2, 1, 518400, 0x4b816734 +0, 3, 3, 1, 518400, 0x0c350f19 +0, 4, 4, 1, 518400, 0xda049cb6 +0, 5, 5, 1, 518400, 0x1f3e7bb9 +0, 6, 6, 1, 518400, 0x995cbe66 +0, 7, 7, 1, 518400, 0x07f7e65c +0, 8, 8, 1, 518400, 0xfcb7487f +0, 9, 9, 1, 518400, 0xb080f48a +0, 10, 10, 1, 518400, 0x3ef5b7e4 +0, 11, 11, 1, 518400, 0xa1518e1c +0, 12, 12, 1, 518400, 0xb36f1cc9 +0, 13, 13, 1, 518400, 0x86ea48af +0, 14, 14, 1, 518400, 0xe42373b7 +0, 15, 15, 1, 518400, 0xa8435828 +0, 16, 16, 1, 518400, 0xc942ea0e +0, 17, 17, 1, 518400, 0xcc597514 diff --git a/tests/ref/fate/h264-conformance-cvnlfi2_sony_h b/tests/ref/fate/h264-conformance-cvnlfi2_sony_h index c7128ba33..48d625e1c 100644 --- a/tests/ref/fate/h264-conformance-cvnlfi2_sony_h +++ b/tests/ref/fate/h264-conformance-cvnlfi2_sony_h @@ -3,20 +3,20 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0x0fbb4e71 -0, 1, 1, 1, 518400, 0xc46bec04 -0, 2, 2, 1, 518400, 0xc50ffc1d -0, 3, 3, 1, 518400, 0x684b07b7 -0, 4, 4, 1, 518400, 0xde799af0 -0, 5, 5, 1, 518400, 0xed497b27 -0, 6, 6, 1, 518400, 0x3e9d1e3a -0, 7, 7, 1, 518400, 0x154d3c5c -0, 8, 8, 1, 518400, 0x5257e37c -0, 9, 9, 1, 518400, 0x6e15139a -0, 10, 10, 1, 518400, 0x5dc39c59 -0, 11, 11, 1, 518400, 0xe1803100 -0, 12, 12, 1, 518400, 0xb4d4d535 -0, 13, 13, 1, 518400, 0x7a97a25d -0, 14, 14, 1, 518400, 0xf86b8923 -0, 15, 15, 1, 518400, 0x3355be98 -0, 16, 16, 1, 518400, 0x8f555830 +0, 1, 1, 1, 518400, 0x0fbb4e71 +0, 2, 2, 1, 518400, 0xc46bec04 +0, 3, 3, 1, 518400, 0xc50ffc1d +0, 4, 4, 1, 518400, 0x684b07b7 +0, 5, 5, 1, 518400, 0xde799af0 +0, 6, 6, 1, 518400, 0xed497b27 +0, 7, 7, 1, 518400, 0x3e9d1e3a +0, 8, 8, 1, 518400, 0x154d3c5c +0, 9, 9, 1, 518400, 0x5257e37c +0, 10, 10, 1, 518400, 0x6e15139a +0, 11, 11, 1, 518400, 0x5dc39c59 +0, 12, 12, 1, 518400, 0xe1803100 +0, 13, 13, 1, 518400, 0xb4d4d535 +0, 14, 14, 1, 518400, 0x7a97a25d +0, 15, 15, 1, 518400, 0xf86b8923 +0, 16, 16, 1, 518400, 0x3355be98 +0, 17, 17, 1, 518400, 0x8f555830 diff --git a/tests/ref/fate/h264-conformance-cvpa1_toshiba_b b/tests/ref/fate/h264-conformance-cvpa1_toshiba_b index 6bf9ee393..fb4104f18 100644 --- a/tests/ref/fate/h264-conformance-cvpa1_toshiba_b +++ b/tests/ref/fate/h264-conformance-cvpa1_toshiba_b @@ -3,93 +3,93 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x128cd77a -0, 1, 1, 1, 152064, 0x565b9fc1 -0, 2, 2, 1, 152064, 0xbe322679 -0, 3, 3, 1, 152064, 0x0ea4238f -0, 4, 4, 1, 152064, 0x1e08fb3c -0, 5, 5, 1, 152064, 0x6da3a93c -0, 6, 6, 1, 152064, 0x75e5b181 -0, 7, 7, 1, 152064, 0xa0b39334 -0, 8, 8, 1, 152064, 0xa0d10d6d -0, 9, 9, 1, 152064, 0x33842bcb -0, 10, 10, 1, 152064, 0x9a74e1e4 -0, 11, 11, 1, 152064, 0xc2037244 -0, 12, 12, 1, 152064, 0x364b8ae4 -0, 13, 13, 1, 152064, 0x18c04971 -0, 14, 14, 1, 152064, 0x7234ecb5 -0, 15, 15, 1, 152064, 0x3719f8bc -0, 16, 16, 1, 152064, 0x1285ead1 -0, 17, 17, 1, 152064, 0xd3bfab18 -0, 18, 18, 1, 152064, 0x898111e2 -0, 19, 19, 1, 152064, 0x681c15fc -0, 20, 20, 1, 152064, 0x8e501572 -0, 21, 21, 1, 152064, 0xd7c838be -0, 22, 22, 1, 152064, 0xede424b2 -0, 23, 23, 1, 152064, 0xcfc20240 -0, 24, 24, 1, 152064, 0x13992e86 -0, 25, 25, 1, 152064, 0x56fb251a -0, 26, 26, 1, 152064, 0xee9be320 -0, 27, 27, 1, 152064, 0xea650153 -0, 28, 28, 1, 152064, 0x2cb6dabe -0, 29, 29, 1, 152064, 0xf44fa4b5 -0, 30, 30, 1, 152064, 0xdac2adff -0, 31, 31, 1, 152064, 0x9e15a1dc -0, 32, 32, 1, 152064, 0x28d00970 -0, 33, 33, 1, 152064, 0xe4277347 -0, 34, 34, 1, 152064, 0xebd25ad1 -0, 35, 35, 1, 152064, 0x029402da -0, 36, 36, 1, 152064, 0x1a2311ef -0, 37, 37, 1, 152064, 0xb86bf96a -0, 38, 38, 1, 152064, 0x67d7a5b0 -0, 39, 39, 1, 152064, 0x573abc2d -0, 40, 40, 1, 152064, 0xbe97dec0 -0, 41, 41, 1, 152064, 0x592b91a4 -0, 42, 42, 1, 152064, 0x9adda65e -0, 43, 43, 1, 152064, 0x0354b2cb -0, 44, 44, 1, 152064, 0x91e27ff9 -0, 45, 45, 1, 152064, 0x389f8625 -0, 46, 46, 1, 152064, 0x90175850 -0, 47, 47, 1, 152064, 0x2d36c427 -0, 48, 48, 1, 152064, 0xc0dd14ab -0, 49, 49, 1, 152064, 0xd49bf131 -0, 50, 50, 1, 152064, 0x0d4a9b92 -0, 51, 51, 1, 152064, 0xae9bb2f1 -0, 52, 52, 1, 152064, 0x36847ade -0, 53, 53, 1, 152064, 0x74810382 -0, 54, 54, 1, 152064, 0xc56d1d9f -0, 55, 55, 1, 152064, 0xcfefe3ae -0, 56, 56, 1, 152064, 0xeaa39353 -0, 57, 57, 1, 152064, 0x14289aef -0, 58, 58, 1, 152064, 0x74ba8f3b -0, 59, 59, 1, 152064, 0xdcaa518d -0, 60, 60, 1, 152064, 0x6e4881c2 -0, 61, 61, 1, 152064, 0xa4db767d -0, 62, 62, 1, 152064, 0x239b0b19 -0, 63, 63, 1, 152064, 0x5d054236 -0, 64, 64, 1, 152064, 0x6f392d7c -0, 65, 65, 1, 152064, 0x5c2af146 -0, 66, 66, 1, 152064, 0x26b439af -0, 67, 67, 1, 152064, 0xba7043ab -0, 68, 68, 1, 152064, 0x0816000c -0, 69, 69, 1, 152064, 0x3a713c05 -0, 70, 70, 1, 152064, 0xb3111f6d -0, 71, 71, 1, 152064, 0xdbf8dae2 -0, 72, 72, 1, 152064, 0x09ddf22e -0, 73, 73, 1, 152064, 0x8871fa7e -0, 74, 74, 1, 152064, 0x9f5db7a1 -0, 75, 75, 1, 152064, 0xcc38f225 -0, 76, 76, 1, 152064, 0xa1d18df9 -0, 77, 77, 1, 152064, 0x9b1c5d6a -0, 78, 78, 1, 152064, 0x9f2bc696 -0, 79, 79, 1, 152064, 0xc39bd11a -0, 80, 80, 1, 152064, 0x4ceca7d0 -0, 81, 81, 1, 152064, 0x63a60f1d -0, 82, 82, 1, 152064, 0x4cd31f28 -0, 83, 83, 1, 152064, 0x9c9af5d1 -0, 84, 84, 1, 152064, 0x6def65fc -0, 85, 85, 1, 152064, 0x1011466d -0, 86, 86, 1, 152064, 0xfeca406d -0, 87, 87, 1, 152064, 0xd1ca8a1e -0, 88, 88, 1, 152064, 0x30caa195 -0, 89, 89, 1, 152064, 0x31a09a48 +0, 1, 1, 1, 152064, 0x128cd77a +0, 2, 2, 1, 152064, 0x565b9fc1 +0, 3, 3, 1, 152064, 0xbe322679 +0, 4, 4, 1, 152064, 0x0ea4238f +0, 5, 5, 1, 152064, 0x1e08fb3c +0, 6, 6, 1, 152064, 0x6da3a93c +0, 7, 7, 1, 152064, 0x75e5b181 +0, 8, 8, 1, 152064, 0xa0b39334 +0, 9, 9, 1, 152064, 0xa0d10d6d +0, 10, 10, 1, 152064, 0x33842bcb +0, 11, 11, 1, 152064, 0x9a74e1e4 +0, 12, 12, 1, 152064, 0xc2037244 +0, 13, 13, 1, 152064, 0x364b8ae4 +0, 14, 14, 1, 152064, 0x18c04971 +0, 15, 15, 1, 152064, 0x7234ecb5 +0, 16, 16, 1, 152064, 0x3719f8bc +0, 17, 17, 1, 152064, 0x1285ead1 +0, 18, 18, 1, 152064, 0xd3bfab18 +0, 19, 19, 1, 152064, 0x898111e2 +0, 20, 20, 1, 152064, 0x681c15fc +0, 21, 21, 1, 152064, 0x8e501572 +0, 22, 22, 1, 152064, 0xd7c838be +0, 23, 23, 1, 152064, 0xede424b2 +0, 24, 24, 1, 152064, 0xcfc20240 +0, 25, 25, 1, 152064, 0x13992e86 +0, 26, 26, 1, 152064, 0x56fb251a +0, 27, 27, 1, 152064, 0xee9be320 +0, 28, 28, 1, 152064, 0xea650153 +0, 29, 29, 1, 152064, 0x2cb6dabe +0, 30, 30, 1, 152064, 0xf44fa4b5 +0, 31, 31, 1, 152064, 0xdac2adff +0, 32, 32, 1, 152064, 0x9e15a1dc +0, 33, 33, 1, 152064, 0x28d00970 +0, 34, 34, 1, 152064, 0xe4277347 +0, 35, 35, 1, 152064, 0xebd25ad1 +0, 36, 36, 1, 152064, 0x029402da +0, 37, 37, 1, 152064, 0x1a2311ef +0, 38, 38, 1, 152064, 0xb86bf96a +0, 39, 39, 1, 152064, 0x67d7a5b0 +0, 40, 40, 1, 152064, 0x573abc2d +0, 41, 41, 1, 152064, 0xbe97dec0 +0, 42, 42, 1, 152064, 0x592b91a4 +0, 43, 43, 1, 152064, 0x9adda65e +0, 44, 44, 1, 152064, 0x0354b2cb +0, 45, 45, 1, 152064, 0x91e27ff9 +0, 46, 46, 1, 152064, 0x389f8625 +0, 47, 47, 1, 152064, 0x90175850 +0, 48, 48, 1, 152064, 0x2d36c427 +0, 49, 49, 1, 152064, 0xc0dd14ab +0, 50, 50, 1, 152064, 0xd49bf131 +0, 51, 51, 1, 152064, 0x0d4a9b92 +0, 52, 52, 1, 152064, 0xae9bb2f1 +0, 53, 53, 1, 152064, 0x36847ade +0, 54, 54, 1, 152064, 0x74810382 +0, 55, 55, 1, 152064, 0xc56d1d9f +0, 56, 56, 1, 152064, 0xcfefe3ae +0, 57, 57, 1, 152064, 0xeaa39353 +0, 58, 58, 1, 152064, 0x14289aef +0, 59, 59, 1, 152064, 0x74ba8f3b +0, 60, 60, 1, 152064, 0xdcaa518d +0, 61, 61, 1, 152064, 0x6e4881c2 +0, 62, 62, 1, 152064, 0xa4db767d +0, 63, 63, 1, 152064, 0x239b0b19 +0, 64, 64, 1, 152064, 0x5d054236 +0, 65, 65, 1, 152064, 0x6f392d7c +0, 66, 66, 1, 152064, 0x5c2af146 +0, 67, 67, 1, 152064, 0x26b439af +0, 68, 68, 1, 152064, 0xba7043ab +0, 69, 69, 1, 152064, 0x0816000c +0, 70, 70, 1, 152064, 0x3a713c05 +0, 71, 71, 1, 152064, 0xb3111f6d +0, 72, 72, 1, 152064, 0xdbf8dae2 +0, 73, 73, 1, 152064, 0x09ddf22e +0, 74, 74, 1, 152064, 0x8871fa7e +0, 75, 75, 1, 152064, 0x9f5db7a1 +0, 76, 76, 1, 152064, 0xcc38f225 +0, 77, 77, 1, 152064, 0xa1d18df9 +0, 78, 78, 1, 152064, 0x9b1c5d6a +0, 79, 79, 1, 152064, 0x9f2bc696 +0, 80, 80, 1, 152064, 0xc39bd11a +0, 81, 81, 1, 152064, 0x4ceca7d0 +0, 82, 82, 1, 152064, 0x63a60f1d +0, 83, 83, 1, 152064, 0x4cd31f28 +0, 84, 84, 1, 152064, 0x9c9af5d1 +0, 85, 85, 1, 152064, 0x6def65fc +0, 86, 86, 1, 152064, 0x1011466d +0, 87, 87, 1, 152064, 0xfeca406d +0, 88, 88, 1, 152064, 0xd1ca8a1e +0, 89, 89, 1, 152064, 0x30caa195 +0, 90, 90, 1, 152064, 0x31a09a48 diff --git a/tests/ref/fate/h264-conformance-fi1_sony_e b/tests/ref/fate/h264-conformance-fi1_sony_e index c48306679..4b3dedce5 100644 --- a/tests/ref/fate/h264-conformance-fi1_sony_e +++ b/tests/ref/fate/h264-conformance-fi1_sony_e @@ -3,20 +3,20 @@ #codec_id 0: rawvideo #dimensions 0: 192x128 #sar 0: 0/1 -0, 0, 0, 1, 36864, 0x3d54d3e3 -0, 1, 1, 1, 36864, 0xa9573ef0 -0, 2, 2, 1, 36864, 0x0ea5f263 -0, 3, 3, 1, 36864, 0x5a849fb9 -0, 4, 4, 1, 36864, 0x7ddb1eff -0, 5, 5, 1, 36864, 0x5e73e3b7 -0, 6, 6, 1, 36864, 0x7d50d329 -0, 7, 7, 1, 36864, 0xf2c2cd27 -0, 8, 8, 1, 36864, 0xdf4f4628 -0, 9, 9, 1, 36864, 0xddd6d5be -0, 10, 10, 1, 36864, 0xb530e1aa -0, 11, 11, 1, 36864, 0xeca42470 -0, 12, 12, 1, 36864, 0xa5701caf -0, 13, 13, 1, 36864, 0x6f5d28fc -0, 14, 14, 1, 36864, 0xd4ab4ab2 -0, 15, 15, 1, 36864, 0xf2dfcc22 -0, 16, 16, 1, 36864, 0xcaa87e79 +0, 1, 1, 1, 36864, 0x3d54d3e3 +0, 2, 2, 1, 36864, 0xa9573ef0 +0, 3, 3, 1, 36864, 0x0ea5f263 +0, 4, 4, 1, 36864, 0x5a849fb9 +0, 5, 5, 1, 36864, 0x7ddb1eff +0, 6, 6, 1, 36864, 0x5e73e3b7 +0, 7, 7, 1, 36864, 0x7d50d329 +0, 8, 8, 1, 36864, 0xf2c2cd27 +0, 9, 9, 1, 36864, 0xdf4f4628 +0, 10, 10, 1, 36864, 0xddd6d5be +0, 11, 11, 1, 36864, 0xb530e1aa +0, 12, 12, 1, 36864, 0xeca42470 +0, 13, 13, 1, 36864, 0xa5701caf +0, 14, 14, 1, 36864, 0x6f5d28fc +0, 15, 15, 1, 36864, 0xd4ab4ab2 +0, 16, 16, 1, 36864, 0xf2dfcc22 +0, 17, 17, 1, 36864, 0xcaa87e79 diff --git a/tests/ref/fate/h264-conformance-frext-bcrm_freh10 b/tests/ref/fate/h264-conformance-frext-bcrm_freh10 index 7592f6c51..4e41aa6cd 100644 --- a/tests/ref/fate/h264-conformance-frext-bcrm_freh10 +++ b/tests/ref/fate/h264-conformance-frext-bcrm_freh10 @@ -3,103 +3,103 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0xbdc2b880 -0, 1, 1, 1, 152064, 0x4ebf93fe -0, 2, 2, 1, 152064, 0xe30d6871 -0, 3, 3, 1, 152064, 0x04f46b9b -0, 4, 4, 1, 152064, 0xd7dd219a -0, 5, 5, 1, 152064, 0x02fc6511 -0, 6, 6, 1, 152064, 0x98868faa -0, 7, 7, 1, 152064, 0x54b94f92 -0, 8, 8, 1, 152064, 0xe3b6be4b -0, 9, 9, 1, 152064, 0xf148cf10 -0, 10, 10, 1, 152064, 0xda3239b8 -0, 11, 11, 1, 152064, 0x6c5d7331 -0, 12, 12, 1, 152064, 0x825f1fea -0, 13, 13, 1, 152064, 0x47791056 -0, 14, 14, 1, 152064, 0xc08e8a58 -0, 15, 15, 1, 152064, 0x020299f3 -0, 16, 16, 1, 152064, 0x0dfd4457 -0, 17, 17, 1, 152064, 0xcf005e68 -0, 18, 18, 1, 152064, 0x1f9e2c32 -0, 19, 19, 1, 152064, 0xa8359324 -0, 20, 20, 1, 152064, 0x4b03752d -0, 21, 21, 1, 152064, 0xd6281621 -0, 22, 22, 1, 152064, 0xc97ac928 -0, 23, 23, 1, 152064, 0xded90dcd -0, 24, 24, 1, 152064, 0xd6883255 -0, 25, 25, 1, 152064, 0x6edb4d4f -0, 26, 26, 1, 152064, 0xd6f93a80 -0, 27, 27, 1, 152064, 0x163d6153 -0, 28, 28, 1, 152064, 0x04b90c06 -0, 29, 29, 1, 152064, 0xee8730c1 -0, 30, 30, 1, 152064, 0xd5f5c669 -0, 31, 31, 1, 152064, 0xcc600b1f -0, 32, 32, 1, 152064, 0x15ddde03 -0, 33, 33, 1, 152064, 0xd0388dd0 -0, 34, 34, 1, 152064, 0xa292ab7d -0, 35, 35, 1, 152064, 0xacf584e9 -0, 36, 36, 1, 152064, 0xcef42714 -0, 37, 37, 1, 152064, 0xeb162f35 -0, 38, 38, 1, 152064, 0x0a07de7b -0, 39, 39, 1, 152064, 0x7ae76c81 -0, 40, 40, 1, 152064, 0x139c8fda -0, 41, 41, 1, 152064, 0x43724411 -0, 42, 42, 1, 152064, 0x07b2ddea -0, 43, 43, 1, 152064, 0x831a1cc7 -0, 44, 44, 1, 152064, 0x092f5073 -0, 45, 45, 1, 152064, 0xe5b6d380 -0, 46, 46, 1, 152064, 0xdd30d69e -0, 47, 47, 1, 152064, 0x887020b2 -0, 48, 48, 1, 152064, 0x84436510 -0, 49, 49, 1, 152064, 0x49f63606 -0, 50, 50, 1, 152064, 0x6b96e959 -0, 51, 51, 1, 152064, 0xc6247cc7 -0, 52, 52, 1, 152064, 0x7a67c532 -0, 53, 53, 1, 152064, 0x93f4c476 -0, 54, 54, 1, 152064, 0x3c119654 -0, 55, 55, 1, 152064, 0xa45f7c72 -0, 56, 56, 1, 152064, 0x2ac50cb0 -0, 57, 57, 1, 152064, 0x9bf16d06 -0, 58, 58, 1, 152064, 0xfa0750d9 -0, 59, 59, 1, 152064, 0x02197630 -0, 60, 60, 1, 152064, 0x6d44f9b5 -0, 61, 61, 1, 152064, 0x86b211f5 -0, 62, 62, 1, 152064, 0xf4fda5d0 -0, 63, 63, 1, 152064, 0x36f840a7 -0, 64, 64, 1, 152064, 0x42412992 -0, 65, 65, 1, 152064, 0xd0c9ba37 -0, 66, 66, 1, 152064, 0xc40eba62 -0, 67, 67, 1, 152064, 0x2d093b53 -0, 68, 68, 1, 152064, 0xee39c69c -0, 69, 69, 1, 152064, 0xcbbf8968 -0, 70, 70, 1, 152064, 0xfddc1704 -0, 71, 71, 1, 152064, 0x8dc47c61 -0, 72, 72, 1, 152064, 0xf15580bf -0, 73, 73, 1, 152064, 0x9c71a8b0 -0, 74, 74, 1, 152064, 0x19b90b9f -0, 75, 75, 1, 152064, 0xb65ae287 -0, 76, 76, 1, 152064, 0xf265693d -0, 77, 77, 1, 152064, 0x721714a1 -0, 78, 78, 1, 152064, 0x383e8ac5 -0, 79, 79, 1, 152064, 0x02558677 -0, 80, 80, 1, 152064, 0xdaab3cdf -0, 81, 81, 1, 152064, 0xc939a2f6 -0, 82, 82, 1, 152064, 0x977afa7f -0, 83, 83, 1, 152064, 0xe5e65f35 -0, 84, 84, 1, 152064, 0x247546fa -0, 85, 85, 1, 152064, 0x49ff2094 -0, 86, 86, 1, 152064, 0x9fd58cda -0, 87, 87, 1, 152064, 0x3e31b6e3 -0, 88, 88, 1, 152064, 0x75c6d796 -0, 89, 89, 1, 152064, 0x4ab3e7bb -0, 90, 90, 1, 152064, 0x393935ea -0, 91, 91, 1, 152064, 0xc8e62905 -0, 92, 92, 1, 152064, 0xbb149e61 -0, 93, 93, 1, 152064, 0x2553c4c5 -0, 94, 94, 1, 152064, 0x7f82a8b4 -0, 95, 95, 1, 152064, 0x26ef31e6 -0, 96, 96, 1, 152064, 0xf029744a -0, 97, 97, 1, 152064, 0x0a6f191a -0, 98, 98, 1, 152064, 0x55808643 -0, 99, 99, 1, 152064, 0x27576172 +0, 1, 1, 1, 152064, 0xbdc2b880 +0, 2, 2, 1, 152064, 0x4ebf93fe +0, 3, 3, 1, 152064, 0xe30d6871 +0, 4, 4, 1, 152064, 0x04f46b9b +0, 5, 5, 1, 152064, 0xd7dd219a +0, 6, 6, 1, 152064, 0x02fc6511 +0, 7, 7, 1, 152064, 0x98868faa +0, 8, 8, 1, 152064, 0x54b94f92 +0, 9, 9, 1, 152064, 0xe3b6be4b +0, 10, 10, 1, 152064, 0xf148cf10 +0, 11, 11, 1, 152064, 0xda3239b8 +0, 12, 12, 1, 152064, 0x6c5d7331 +0, 13, 13, 1, 152064, 0x825f1fea +0, 14, 14, 1, 152064, 0x47791056 +0, 15, 15, 1, 152064, 0xc08e8a58 +0, 16, 16, 1, 152064, 0x020299f3 +0, 17, 17, 1, 152064, 0x0dfd4457 +0, 18, 18, 1, 152064, 0xcf005e68 +0, 19, 19, 1, 152064, 0x1f9e2c32 +0, 20, 20, 1, 152064, 0xa8359324 +0, 21, 21, 1, 152064, 0x4b03752d +0, 22, 22, 1, 152064, 0xd6281621 +0, 23, 23, 1, 152064, 0xc97ac928 +0, 24, 24, 1, 152064, 0xded90dcd +0, 25, 25, 1, 152064, 0xd6883255 +0, 26, 26, 1, 152064, 0x6edb4d4f +0, 27, 27, 1, 152064, 0xd6f93a80 +0, 28, 28, 1, 152064, 0x163d6153 +0, 29, 29, 1, 152064, 0x04b90c06 +0, 30, 30, 1, 152064, 0xee8730c1 +0, 31, 31, 1, 152064, 0xd5f5c669 +0, 32, 32, 1, 152064, 0xcc600b1f +0, 33, 33, 1, 152064, 0x15ddde03 +0, 34, 34, 1, 152064, 0xd0388dd0 +0, 35, 35, 1, 152064, 0xa292ab7d +0, 36, 36, 1, 152064, 0xacf584e9 +0, 37, 37, 1, 152064, 0xcef42714 +0, 38, 38, 1, 152064, 0xeb162f35 +0, 39, 39, 1, 152064, 0x0a07de7b +0, 40, 40, 1, 152064, 0x7ae76c81 +0, 41, 41, 1, 152064, 0x139c8fda +0, 42, 42, 1, 152064, 0x43724411 +0, 43, 43, 1, 152064, 0x07b2ddea +0, 44, 44, 1, 152064, 0x831a1cc7 +0, 45, 45, 1, 152064, 0x092f5073 +0, 46, 46, 1, 152064, 0xe5b6d380 +0, 47, 47, 1, 152064, 0xdd30d69e +0, 48, 48, 1, 152064, 0x887020b2 +0, 49, 49, 1, 152064, 0x84436510 +0, 50, 50, 1, 152064, 0x49f63606 +0, 51, 51, 1, 152064, 0x6b96e959 +0, 52, 52, 1, 152064, 0xc6247cc7 +0, 53, 53, 1, 152064, 0x7a67c532 +0, 54, 54, 1, 152064, 0x93f4c476 +0, 55, 55, 1, 152064, 0x3c119654 +0, 56, 56, 1, 152064, 0xa45f7c72 +0, 57, 57, 1, 152064, 0x2ac50cb0 +0, 58, 58, 1, 152064, 0x9bf16d06 +0, 59, 59, 1, 152064, 0xfa0750d9 +0, 60, 60, 1, 152064, 0x02197630 +0, 61, 61, 1, 152064, 0x6d44f9b5 +0, 62, 62, 1, 152064, 0x86b211f5 +0, 63, 63, 1, 152064, 0xf4fda5d0 +0, 64, 64, 1, 152064, 0x36f840a7 +0, 65, 65, 1, 152064, 0x42412992 +0, 66, 66, 1, 152064, 0xd0c9ba37 +0, 67, 67, 1, 152064, 0xc40eba62 +0, 68, 68, 1, 152064, 0x2d093b53 +0, 69, 69, 1, 152064, 0xee39c69c +0, 70, 70, 1, 152064, 0xcbbf8968 +0, 71, 71, 1, 152064, 0xfddc1704 +0, 72, 72, 1, 152064, 0x8dc47c61 +0, 73, 73, 1, 152064, 0xf15580bf +0, 74, 74, 1, 152064, 0x9c71a8b0 +0, 75, 75, 1, 152064, 0x19b90b9f +0, 76, 76, 1, 152064, 0xb65ae287 +0, 77, 77, 1, 152064, 0xf265693d +0, 78, 78, 1, 152064, 0x721714a1 +0, 79, 79, 1, 152064, 0x383e8ac5 +0, 80, 80, 1, 152064, 0x02558677 +0, 81, 81, 1, 152064, 0xdaab3cdf +0, 82, 82, 1, 152064, 0xc939a2f6 +0, 83, 83, 1, 152064, 0x977afa7f +0, 84, 84, 1, 152064, 0xe5e65f35 +0, 85, 85, 1, 152064, 0x247546fa +0, 86, 86, 1, 152064, 0x49ff2094 +0, 87, 87, 1, 152064, 0x9fd58cda +0, 88, 88, 1, 152064, 0x3e31b6e3 +0, 89, 89, 1, 152064, 0x75c6d796 +0, 90, 90, 1, 152064, 0x4ab3e7bb +0, 91, 91, 1, 152064, 0x393935ea +0, 92, 92, 1, 152064, 0xc8e62905 +0, 93, 93, 1, 152064, 0xbb149e61 +0, 94, 94, 1, 152064, 0x2553c4c5 +0, 95, 95, 1, 152064, 0x7f82a8b4 +0, 96, 96, 1, 152064, 0x26ef31e6 +0, 97, 97, 1, 152064, 0xf029744a +0, 98, 98, 1, 152064, 0x0a6f191a +0, 99, 99, 1, 152064, 0x55808643 +0, 100, 100, 1, 152064, 0x27576172 diff --git a/tests/ref/fate/h264-conformance-frext-brcm_freh11 b/tests/ref/fate/h264-conformance-frext-brcm_freh11 index 5bb9aa447..1ba3b7e18 100644 --- a/tests/ref/fate/h264-conformance-frext-brcm_freh11 +++ b/tests/ref/fate/h264-conformance-frext-brcm_freh11 @@ -3,103 +3,103 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x9744ac59 -0, 1, 1, 1, 152064, 0x3eba88bf -0, 2, 2, 1, 152064, 0xd4105c5a -0, 3, 3, 1, 152064, 0x452966a3 -0, 4, 4, 1, 152064, 0x30071add -0, 5, 5, 1, 152064, 0x0eb75245 -0, 6, 6, 1, 152064, 0x4daa80fa -0, 7, 7, 1, 152064, 0xf53a43a1 -0, 8, 8, 1, 152064, 0xa55ab43d -0, 9, 9, 1, 152064, 0x915ec82e -0, 10, 10, 1, 152064, 0xadce2f9a -0, 11, 11, 1, 152064, 0xf7a25715 -0, 12, 12, 1, 152064, 0x90c91c7d -0, 13, 13, 1, 152064, 0x4f0df4ef -0, 14, 14, 1, 152064, 0xf6e0783c -0, 15, 15, 1, 152064, 0x417c8ca8 -0, 16, 16, 1, 152064, 0xd33d29d8 -0, 17, 17, 1, 152064, 0xc9723fa3 -0, 18, 18, 1, 152064, 0x3e4f22f4 -0, 19, 19, 1, 152064, 0xd5aa7bd8 -0, 20, 20, 1, 152064, 0x2a425b54 -0, 21, 21, 1, 152064, 0x2d400788 -0, 22, 22, 1, 152064, 0x12fab3a4 -0, 23, 23, 1, 152064, 0x5544f881 -0, 24, 24, 1, 152064, 0xd0612cc5 -0, 25, 25, 1, 152064, 0x157b3654 -0, 26, 26, 1, 152064, 0x04b61fe0 -0, 27, 27, 1, 152064, 0x897d600a -0, 28, 28, 1, 152064, 0x0d94fa29 -0, 29, 29, 1, 152064, 0xc0fe249d -0, 30, 30, 1, 152064, 0x65abc1d6 -0, 31, 31, 1, 152064, 0x2bd5f09d -0, 32, 32, 1, 152064, 0xd3eebd28 -0, 33, 33, 1, 152064, 0x93458649 -0, 34, 34, 1, 152064, 0x55e793a6 -0, 35, 35, 1, 152064, 0x9fc378ce -0, 36, 36, 1, 152064, 0x24c32731 -0, 37, 37, 1, 152064, 0x3c321c50 -0, 38, 38, 1, 152064, 0xcef3ca8b -0, 39, 39, 1, 152064, 0x97116676 -0, 40, 40, 1, 152064, 0x73ae78f6 -0, 41, 41, 1, 152064, 0xdeec219e -0, 42, 42, 1, 152064, 0xc061d584 -0, 43, 43, 1, 152064, 0xcf47f6c9 -0, 44, 44, 1, 152064, 0x280d3a2d -0, 45, 45, 1, 152064, 0xb660c846 -0, 46, 46, 1, 152064, 0xe167c588 -0, 47, 47, 1, 152064, 0x08f808de -0, 48, 48, 1, 152064, 0x9de65c0b -0, 49, 49, 1, 152064, 0xc52a1937 -0, 50, 50, 1, 152064, 0xf5a4d86f -0, 51, 51, 1, 152064, 0xbef86d37 -0, 52, 52, 1, 152064, 0xa227b21b -0, 53, 53, 1, 152064, 0x0601ad35 -0, 54, 54, 1, 152064, 0x15198730 -0, 55, 55, 1, 152064, 0x9af764c6 -0, 56, 56, 1, 152064, 0x1a95e99a -0, 57, 57, 1, 152064, 0x6bef5aa8 -0, 58, 58, 1, 152064, 0x92f03267 -0, 59, 59, 1, 152064, 0x0a3d56cb -0, 60, 60, 1, 152064, 0xd9c9f62e -0, 61, 61, 1, 152064, 0xcd81ea16 -0, 62, 62, 1, 152064, 0x8ed789c0 -0, 63, 63, 1, 152064, 0x5a5e356f -0, 64, 64, 1, 152064, 0x2f260ebf -0, 65, 65, 1, 152064, 0xa0379c89 -0, 66, 66, 1, 152064, 0x100cb40c -0, 67, 67, 1, 152064, 0xaad2220a -0, 68, 68, 1, 152064, 0xec82aa8d -0, 69, 69, 1, 152064, 0x91088303 -0, 70, 70, 1, 152064, 0x0cce0e9e -0, 71, 71, 1, 152064, 0xf3bc716a -0, 72, 72, 1, 152064, 0x989879c5 -0, 73, 73, 1, 152064, 0x491297a0 -0, 74, 74, 1, 152064, 0xdc16f30d -0, 75, 75, 1, 152064, 0xb9bfdd57 -0, 76, 76, 1, 152064, 0x5fba59c2 -0, 77, 77, 1, 152064, 0x89c40529 -0, 78, 78, 1, 152064, 0x1b3e7b54 -0, 79, 79, 1, 152064, 0x5d0d7903 -0, 80, 80, 1, 152064, 0x2e3434e1 -0, 81, 81, 1, 152064, 0x1f47a276 -0, 82, 82, 1, 152064, 0xa22de2b1 -0, 83, 83, 1, 152064, 0x77344844 -0, 84, 84, 1, 152064, 0x6a6b3fce -0, 85, 85, 1, 152064, 0x82660651 -0, 86, 86, 1, 152064, 0x51e67cc9 -0, 87, 87, 1, 152064, 0xb790ae51 -0, 88, 88, 1, 152064, 0x906bc6b6 -0, 89, 89, 1, 152064, 0x55c5dc21 -0, 90, 90, 1, 152064, 0xb51f3004 -0, 91, 91, 1, 152064, 0x68500a25 -0, 92, 92, 1, 152064, 0x5dbc812e -0, 93, 93, 1, 152064, 0x895eb6ed -0, 94, 94, 1, 152064, 0x2f5594fc -0, 95, 95, 1, 152064, 0x04a222a9 -0, 96, 96, 1, 152064, 0x90036f6a -0, 97, 97, 1, 152064, 0x8b8b064c -0, 98, 98, 1, 152064, 0xd47c7334 -0, 99, 99, 1, 152064, 0x13f06213 +0, 1, 1, 1, 152064, 0x9744ac59 +0, 2, 2, 1, 152064, 0x3eba88bf +0, 3, 3, 1, 152064, 0xd4105c5a +0, 4, 4, 1, 152064, 0x452966a3 +0, 5, 5, 1, 152064, 0x30071add +0, 6, 6, 1, 152064, 0x0eb75245 +0, 7, 7, 1, 152064, 0x4daa80fa +0, 8, 8, 1, 152064, 0xf53a43a1 +0, 9, 9, 1, 152064, 0xa55ab43d +0, 10, 10, 1, 152064, 0x915ec82e +0, 11, 11, 1, 152064, 0xadce2f9a +0, 12, 12, 1, 152064, 0xf7a25715 +0, 13, 13, 1, 152064, 0x90c91c7d +0, 14, 14, 1, 152064, 0x4f0df4ef +0, 15, 15, 1, 152064, 0xf6e0783c +0, 16, 16, 1, 152064, 0x417c8ca8 +0, 17, 17, 1, 152064, 0xd33d29d8 +0, 18, 18, 1, 152064, 0xc9723fa3 +0, 19, 19, 1, 152064, 0x3e4f22f4 +0, 20, 20, 1, 152064, 0xd5aa7bd8 +0, 21, 21, 1, 152064, 0x2a425b54 +0, 22, 22, 1, 152064, 0x2d400788 +0, 23, 23, 1, 152064, 0x12fab3a4 +0, 24, 24, 1, 152064, 0x5544f881 +0, 25, 25, 1, 152064, 0xd0612cc5 +0, 26, 26, 1, 152064, 0x157b3654 +0, 27, 27, 1, 152064, 0x04b61fe0 +0, 28, 28, 1, 152064, 0x897d600a +0, 29, 29, 1, 152064, 0x0d94fa29 +0, 30, 30, 1, 152064, 0xc0fe249d +0, 31, 31, 1, 152064, 0x65abc1d6 +0, 32, 32, 1, 152064, 0x2bd5f09d +0, 33, 33, 1, 152064, 0xd3eebd28 +0, 34, 34, 1, 152064, 0x93458649 +0, 35, 35, 1, 152064, 0x55e793a6 +0, 36, 36, 1, 152064, 0x9fc378ce +0, 37, 37, 1, 152064, 0x24c32731 +0, 38, 38, 1, 152064, 0x3c321c50 +0, 39, 39, 1, 152064, 0xcef3ca8b +0, 40, 40, 1, 152064, 0x97116676 +0, 41, 41, 1, 152064, 0x73ae78f6 +0, 42, 42, 1, 152064, 0xdeec219e +0, 43, 43, 1, 152064, 0xc061d584 +0, 44, 44, 1, 152064, 0xcf47f6c9 +0, 45, 45, 1, 152064, 0x280d3a2d +0, 46, 46, 1, 152064, 0xb660c846 +0, 47, 47, 1, 152064, 0xe167c588 +0, 48, 48, 1, 152064, 0x08f808de +0, 49, 49, 1, 152064, 0x9de65c0b +0, 50, 50, 1, 152064, 0xc52a1937 +0, 51, 51, 1, 152064, 0xf5a4d86f +0, 52, 52, 1, 152064, 0xbef86d37 +0, 53, 53, 1, 152064, 0xa227b21b +0, 54, 54, 1, 152064, 0x0601ad35 +0, 55, 55, 1, 152064, 0x15198730 +0, 56, 56, 1, 152064, 0x9af764c6 +0, 57, 57, 1, 152064, 0x1a95e99a +0, 58, 58, 1, 152064, 0x6bef5aa8 +0, 59, 59, 1, 152064, 0x92f03267 +0, 60, 60, 1, 152064, 0x0a3d56cb +0, 61, 61, 1, 152064, 0xd9c9f62e +0, 62, 62, 1, 152064, 0xcd81ea16 +0, 63, 63, 1, 152064, 0x8ed789c0 +0, 64, 64, 1, 152064, 0x5a5e356f +0, 65, 65, 1, 152064, 0x2f260ebf +0, 66, 66, 1, 152064, 0xa0379c89 +0, 67, 67, 1, 152064, 0x100cb40c +0, 68, 68, 1, 152064, 0xaad2220a +0, 69, 69, 1, 152064, 0xec82aa8d +0, 70, 70, 1, 152064, 0x91088303 +0, 71, 71, 1, 152064, 0x0cce0e9e +0, 72, 72, 1, 152064, 0xf3bc716a +0, 73, 73, 1, 152064, 0x989879c5 +0, 74, 74, 1, 152064, 0x491297a0 +0, 75, 75, 1, 152064, 0xdc16f30d +0, 76, 76, 1, 152064, 0xb9bfdd57 +0, 77, 77, 1, 152064, 0x5fba59c2 +0, 78, 78, 1, 152064, 0x89c40529 +0, 79, 79, 1, 152064, 0x1b3e7b54 +0, 80, 80, 1, 152064, 0x5d0d7903 +0, 81, 81, 1, 152064, 0x2e3434e1 +0, 82, 82, 1, 152064, 0x1f47a276 +0, 83, 83, 1, 152064, 0xa22de2b1 +0, 84, 84, 1, 152064, 0x77344844 +0, 85, 85, 1, 152064, 0x6a6b3fce +0, 86, 86, 1, 152064, 0x82660651 +0, 87, 87, 1, 152064, 0x51e67cc9 +0, 88, 88, 1, 152064, 0xb790ae51 +0, 89, 89, 1, 152064, 0x906bc6b6 +0, 90, 90, 1, 152064, 0x55c5dc21 +0, 91, 91, 1, 152064, 0xb51f3004 +0, 92, 92, 1, 152064, 0x68500a25 +0, 93, 93, 1, 152064, 0x5dbc812e +0, 94, 94, 1, 152064, 0x895eb6ed +0, 95, 95, 1, 152064, 0x2f5594fc +0, 96, 96, 1, 152064, 0x04a222a9 +0, 97, 97, 1, 152064, 0x90036f6a +0, 98, 98, 1, 152064, 0x8b8b064c +0, 99, 99, 1, 152064, 0xd47c7334 +0, 100, 100, 1, 152064, 0x13f06213 diff --git a/tests/ref/fate/h264-conformance-frext-brcm_freh4 b/tests/ref/fate/h264-conformance-frext-brcm_freh4 index 9898def9f..019df15b1 100644 --- a/tests/ref/fate/h264-conformance-frext-brcm_freh4 +++ b/tests/ref/fate/h264-conformance-frext-brcm_freh4 @@ -3,103 +3,103 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x9744ac59 -0, 1, 1, 1, 152064, 0xe1c69d97 -0, 2, 2, 1, 152064, 0x9ae85f93 -0, 3, 3, 1, 152064, 0x452966a3 -0, 4, 4, 1, 152064, 0xe8192823 -0, 5, 5, 1, 152064, 0x58b764eb -0, 6, 6, 1, 152064, 0x51b686b1 -0, 7, 7, 1, 152064, 0x4bca5822 -0, 8, 8, 1, 152064, 0x29abc41c -0, 9, 9, 1, 152064, 0x850ec94f -0, 10, 10, 1, 152064, 0xac2c34f8 -0, 11, 11, 1, 152064, 0x080c6e67 -0, 12, 12, 1, 152064, 0x5e4e14d2 -0, 13, 13, 1, 152064, 0x978b054c -0, 14, 14, 1, 152064, 0x861d8c3c -0, 15, 15, 1, 152064, 0xe0818918 -0, 16, 16, 1, 152064, 0x8b834511 -0, 17, 17, 1, 152064, 0x223f567c -0, 18, 18, 1, 152064, 0x6d61298d -0, 19, 19, 1, 152064, 0xfe30826e -0, 20, 20, 1, 152064, 0x4bad4f98 -0, 21, 21, 1, 152064, 0x69d5fdca -0, 22, 22, 1, 152064, 0xe45bba1b -0, 23, 23, 1, 152064, 0xa6d81298 -0, 24, 24, 1, 152064, 0x7f3f2c91 -0, 25, 25, 1, 152064, 0x658754b9 -0, 26, 26, 1, 152064, 0x2c6d3eba -0, 27, 27, 1, 152064, 0x4500600c -0, 28, 28, 1, 152064, 0xa745f74b -0, 29, 29, 1, 152064, 0x2bf21fca -0, 30, 30, 1, 152064, 0x08b8bdb3 -0, 31, 31, 1, 152064, 0x5a9d0a8b -0, 32, 32, 1, 152064, 0x3a57d523 -0, 33, 33, 1, 152064, 0x3606826e -0, 34, 34, 1, 152064, 0x3b91a8fb -0, 35, 35, 1, 152064, 0x37c28959 -0, 36, 36, 1, 152064, 0xb51d1e75 -0, 37, 37, 1, 152064, 0x13be3f58 -0, 38, 38, 1, 152064, 0x0ed0e7cf -0, 39, 39, 1, 152064, 0x298560d4 -0, 40, 40, 1, 152064, 0x62b68373 -0, 41, 41, 1, 152064, 0xf8bb4520 -0, 42, 42, 1, 152064, 0x90dfd6af -0, 43, 43, 1, 152064, 0xf4770d20 -0, 44, 44, 1, 152064, 0x0d9549a0 -0, 45, 45, 1, 152064, 0x004eccb1 -0, 46, 46, 1, 152064, 0x3146d46b -0, 47, 47, 1, 152064, 0x078d1808 -0, 48, 48, 1, 152064, 0x5d8d60cd -0, 49, 49, 1, 152064, 0x8ff52dd8 -0, 50, 50, 1, 152064, 0x5aa3ccf7 -0, 51, 51, 1, 152064, 0x5bec6c39 -0, 52, 52, 1, 152064, 0xd44cae9d -0, 53, 53, 1, 152064, 0xa1b0a151 -0, 54, 54, 1, 152064, 0xe3be7bb2 -0, 55, 55, 1, 152064, 0x50096775 -0, 56, 56, 1, 152064, 0xdffff851 -0, 57, 57, 1, 152064, 0x1d7250eb -0, 58, 58, 1, 152064, 0x69663ca7 -0, 59, 59, 1, 152064, 0x62f77fc7 -0, 60, 60, 1, 152064, 0xbab8f471 -0, 61, 61, 1, 152064, 0x6af31785 -0, 62, 62, 1, 152064, 0xcbb2a9aa -0, 63, 63, 1, 152064, 0xc57c32b9 -0, 64, 64, 1, 152064, 0xecbe2ce0 -0, 65, 65, 1, 152064, 0x2fbebf81 -0, 66, 66, 1, 152064, 0xa168af68 -0, 67, 67, 1, 152064, 0x1e5631ac -0, 68, 68, 1, 152064, 0xe69fc927 -0, 69, 69, 1, 152064, 0x8e5c81d8 -0, 70, 70, 1, 152064, 0x42402010 -0, 71, 71, 1, 152064, 0xd7267482 -0, 72, 72, 1, 152064, 0x64b280df -0, 73, 73, 1, 152064, 0xc4cbafcc -0, 74, 74, 1, 152064, 0xcf2f1e8b -0, 75, 75, 1, 152064, 0x4d6fdb3f -0, 76, 76, 1, 152064, 0xf22d6fed -0, 77, 77, 1, 152064, 0x625b167c -0, 78, 78, 1, 152064, 0x41348089 -0, 79, 79, 1, 152064, 0x6db2779b -0, 80, 80, 1, 152064, 0xe87030a8 -0, 81, 81, 1, 152064, 0x91b29cdd -0, 82, 82, 1, 152064, 0xe824f242 -0, 83, 83, 1, 152064, 0xac995380 -0, 84, 84, 1, 152064, 0x7efe361b -0, 85, 85, 1, 152064, 0xe10c0c26 -0, 86, 86, 1, 152064, 0x93108260 -0, 87, 87, 1, 152064, 0xbf4caed7 -0, 88, 88, 1, 152064, 0xb6a4d826 -0, 89, 89, 1, 152064, 0x78beea4e -0, 90, 90, 1, 152064, 0xdf612df9 -0, 91, 91, 1, 152064, 0xa9ef2830 -0, 92, 92, 1, 152064, 0x06448895 -0, 93, 93, 1, 152064, 0x332eb6d5 -0, 94, 94, 1, 152064, 0x935ba2c5 -0, 95, 95, 1, 152064, 0x62a22656 -0, 96, 96, 1, 152064, 0x06a670a7 -0, 97, 97, 1, 152064, 0xf60b1af0 -0, 98, 98, 1, 152064, 0x85177c10 -0, 99, 99, 1, 152064, 0x5e4e5c4b +0, 1, 1, 1, 152064, 0x9744ac59 +0, 2, 2, 1, 152064, 0xe1c69d97 +0, 3, 3, 1, 152064, 0x9ae85f93 +0, 4, 4, 1, 152064, 0x452966a3 +0, 5, 5, 1, 152064, 0xe8192823 +0, 6, 6, 1, 152064, 0x58b764eb +0, 7, 7, 1, 152064, 0x51b686b1 +0, 8, 8, 1, 152064, 0x4bca5822 +0, 9, 9, 1, 152064, 0x29abc41c +0, 10, 10, 1, 152064, 0x850ec94f +0, 11, 11, 1, 152064, 0xac2c34f8 +0, 12, 12, 1, 152064, 0x080c6e67 +0, 13, 13, 1, 152064, 0x5e4e14d2 +0, 14, 14, 1, 152064, 0x978b054c +0, 15, 15, 1, 152064, 0x861d8c3c +0, 16, 16, 1, 152064, 0xe0818918 +0, 17, 17, 1, 152064, 0x8b834511 +0, 18, 18, 1, 152064, 0x223f567c +0, 19, 19, 1, 152064, 0x6d61298d +0, 20, 20, 1, 152064, 0xfe30826e +0, 21, 21, 1, 152064, 0x4bad4f98 +0, 22, 22, 1, 152064, 0x69d5fdca +0, 23, 23, 1, 152064, 0xe45bba1b +0, 24, 24, 1, 152064, 0xa6d81298 +0, 25, 25, 1, 152064, 0x7f3f2c91 +0, 26, 26, 1, 152064, 0x658754b9 +0, 27, 27, 1, 152064, 0x2c6d3eba +0, 28, 28, 1, 152064, 0x4500600c +0, 29, 29, 1, 152064, 0xa745f74b +0, 30, 30, 1, 152064, 0x2bf21fca +0, 31, 31, 1, 152064, 0x08b8bdb3 +0, 32, 32, 1, 152064, 0x5a9d0a8b +0, 33, 33, 1, 152064, 0x3a57d523 +0, 34, 34, 1, 152064, 0x3606826e +0, 35, 35, 1, 152064, 0x3b91a8fb +0, 36, 36, 1, 152064, 0x37c28959 +0, 37, 37, 1, 152064, 0xb51d1e75 +0, 38, 38, 1, 152064, 0x13be3f58 +0, 39, 39, 1, 152064, 0x0ed0e7cf +0, 40, 40, 1, 152064, 0x298560d4 +0, 41, 41, 1, 152064, 0x62b68373 +0, 42, 42, 1, 152064, 0xf8bb4520 +0, 43, 43, 1, 152064, 0x90dfd6af +0, 44, 44, 1, 152064, 0xf4770d20 +0, 45, 45, 1, 152064, 0x0d9549a0 +0, 46, 46, 1, 152064, 0x004eccb1 +0, 47, 47, 1, 152064, 0x3146d46b +0, 48, 48, 1, 152064, 0x078d1808 +0, 49, 49, 1, 152064, 0x5d8d60cd +0, 50, 50, 1, 152064, 0x8ff52dd8 +0, 51, 51, 1, 152064, 0x5aa3ccf7 +0, 52, 52, 1, 152064, 0x5bec6c39 +0, 53, 53, 1, 152064, 0xd44cae9d +0, 54, 54, 1, 152064, 0xa1b0a151 +0, 55, 55, 1, 152064, 0xe3be7bb2 +0, 56, 56, 1, 152064, 0x50096775 +0, 57, 57, 1, 152064, 0xdffff851 +0, 58, 58, 1, 152064, 0x1d7250eb +0, 59, 59, 1, 152064, 0x69663ca7 +0, 60, 60, 1, 152064, 0x62f77fc7 +0, 61, 61, 1, 152064, 0xbab8f471 +0, 62, 62, 1, 152064, 0x6af31785 +0, 63, 63, 1, 152064, 0xcbb2a9aa +0, 64, 64, 1, 152064, 0xc57c32b9 +0, 65, 65, 1, 152064, 0xecbe2ce0 +0, 66, 66, 1, 152064, 0x2fbebf81 +0, 67, 67, 1, 152064, 0xa168af68 +0, 68, 68, 1, 152064, 0x1e5631ac +0, 69, 69, 1, 152064, 0xe69fc927 +0, 70, 70, 1, 152064, 0x8e5c81d8 +0, 71, 71, 1, 152064, 0x42402010 +0, 72, 72, 1, 152064, 0xd7267482 +0, 73, 73, 1, 152064, 0x64b280df +0, 74, 74, 1, 152064, 0xc4cbafcc +0, 75, 75, 1, 152064, 0xcf2f1e8b +0, 76, 76, 1, 152064, 0x4d6fdb3f +0, 77, 77, 1, 152064, 0xf22d6fed +0, 78, 78, 1, 152064, 0x625b167c +0, 79, 79, 1, 152064, 0x41348089 +0, 80, 80, 1, 152064, 0x6db2779b +0, 81, 81, 1, 152064, 0xe87030a8 +0, 82, 82, 1, 152064, 0x91b29cdd +0, 83, 83, 1, 152064, 0xe824f242 +0, 84, 84, 1, 152064, 0xac995380 +0, 85, 85, 1, 152064, 0x7efe361b +0, 86, 86, 1, 152064, 0xe10c0c26 +0, 87, 87, 1, 152064, 0x93108260 +0, 88, 88, 1, 152064, 0xbf4caed7 +0, 89, 89, 1, 152064, 0xb6a4d826 +0, 90, 90, 1, 152064, 0x78beea4e +0, 91, 91, 1, 152064, 0xdf612df9 +0, 92, 92, 1, 152064, 0xa9ef2830 +0, 93, 93, 1, 152064, 0x06448895 +0, 94, 94, 1, 152064, 0x332eb6d5 +0, 95, 95, 1, 152064, 0x935ba2c5 +0, 96, 96, 1, 152064, 0x62a22656 +0, 97, 97, 1, 152064, 0x06a670a7 +0, 98, 98, 1, 152064, 0xf60b1af0 +0, 99, 99, 1, 152064, 0x85177c10 +0, 100, 100, 1, 152064, 0x5e4e5c4b diff --git a/tests/ref/fate/h264-conformance-frext-freh6 b/tests/ref/fate/h264-conformance-frext-freh6 index 57ac26180..a5264d61d 100644 --- a/tests/ref/fate/h264-conformance-frext-freh6 +++ b/tests/ref/fate/h264-conformance-frext-freh6 @@ -3,103 +3,103 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x3b21d6cd -0, 1, 1, 1, 152064, 0xc32088c6 -0, 2, 2, 1, 152064, 0x65a64cee -0, 3, 3, 1, 152064, 0x0bd45a5b -0, 4, 4, 1, 152064, 0xb2210d4d -0, 5, 5, 1, 152064, 0xf5b15527 -0, 6, 6, 1, 152064, 0x806572ad -0, 7, 7, 1, 152064, 0x6ecb1fc8 -0, 8, 8, 1, 152064, 0xc25e96d5 -0, 9, 9, 1, 152064, 0x5593b825 -0, 10, 10, 1, 152064, 0xf3be1cff -0, 11, 11, 1, 152064, 0xa9155072 -0, 12, 12, 1, 152064, 0xd5552e26 -0, 13, 13, 1, 152064, 0x7bf0dbee -0, 14, 14, 1, 152064, 0x998b4911 -0, 15, 15, 1, 152064, 0xcc71bbe0 -0, 16, 16, 1, 152064, 0x602415b8 -0, 17, 17, 1, 152064, 0xcfff37cf -0, 18, 18, 1, 152064, 0x7cf824a8 -0, 19, 19, 1, 152064, 0x34816ee5 -0, 20, 20, 1, 152064, 0x1480540c -0, 21, 21, 1, 152064, 0xc2351aaf -0, 22, 22, 1, 152064, 0x3b8eac9f -0, 23, 23, 1, 152064, 0x92a8faf8 -0, 24, 24, 1, 152064, 0x7b6121c8 -0, 25, 25, 1, 152064, 0xe73a3bac -0, 26, 26, 1, 152064, 0xcd6e1e36 -0, 27, 27, 1, 152064, 0xb24660b1 -0, 28, 28, 1, 152064, 0xa290ec25 -0, 29, 29, 1, 152064, 0x308915ff -0, 30, 30, 1, 152064, 0x1e8dd4db -0, 31, 31, 1, 152064, 0x1372f2e0 -0, 32, 32, 1, 152064, 0xa07cc1d0 -0, 33, 33, 1, 152064, 0x34bb872c -0, 34, 34, 1, 152064, 0x59e6a565 -0, 35, 35, 1, 152064, 0x9a097932 -0, 36, 36, 1, 152064, 0x938f2e20 -0, 37, 37, 1, 152064, 0x59a8157d -0, 38, 38, 1, 152064, 0x5cacd404 -0, 39, 39, 1, 152064, 0xdad068f5 -0, 40, 40, 1, 152064, 0x7ba67d47 -0, 41, 41, 1, 152064, 0xc2a11e2d -0, 42, 42, 1, 152064, 0xd37fdef7 -0, 43, 43, 1, 152064, 0x19a3f80a -0, 44, 44, 1, 152064, 0x7ec7426a -0, 45, 45, 1, 152064, 0x8ffedb61 -0, 46, 46, 1, 152064, 0x82aebdd0 -0, 47, 47, 1, 152064, 0xdfc920cc -0, 48, 48, 1, 152064, 0x2a467698 -0, 49, 49, 1, 152064, 0xd08a37d5 -0, 50, 50, 1, 152064, 0xe606e66a -0, 51, 51, 1, 152064, 0x0e7b8bd8 -0, 52, 52, 1, 152064, 0xf983c732 -0, 53, 53, 1, 152064, 0x9b82c2e7 -0, 54, 54, 1, 152064, 0xa990a47e -0, 55, 55, 1, 152064, 0x2d5679f1 -0, 56, 56, 1, 152064, 0x7f1c0201 -0, 57, 57, 1, 152064, 0xc38b709d -0, 58, 58, 1, 152064, 0x040246d8 -0, 59, 59, 1, 152064, 0xbc856021 -0, 60, 60, 1, 152064, 0x81e01a78 -0, 61, 61, 1, 152064, 0xaff1e7f1 -0, 62, 62, 1, 152064, 0x1fee7715 -0, 63, 63, 1, 152064, 0x65053711 -0, 64, 64, 1, 152064, 0x238a0118 -0, 65, 65, 1, 152064, 0x563491b4 -0, 66, 66, 1, 152064, 0x5974a6cc -0, 67, 67, 1, 152064, 0xd8682c35 -0, 68, 68, 1, 152064, 0x85c49e96 -0, 69, 69, 1, 152064, 0x29486faa -0, 70, 70, 1, 152064, 0x1a4f0579 -0, 71, 71, 1, 152064, 0x6ab86c2f -0, 72, 72, 1, 152064, 0x36a36d2b -0, 73, 73, 1, 152064, 0x3bd77543 -0, 74, 74, 1, 152064, 0x8fbddc41 -0, 75, 75, 1, 152064, 0xccc6e0a5 -0, 76, 76, 1, 152064, 0x00a9539e -0, 77, 77, 1, 152064, 0x07ba0714 -0, 78, 78, 1, 152064, 0xbab2735d -0, 79, 79, 1, 152064, 0x79cb5ba0 -0, 80, 80, 1, 152064, 0xdbcc1c92 -0, 81, 81, 1, 152064, 0xffec952c -0, 82, 82, 1, 152064, 0xc31ac68e -0, 83, 83, 1, 152064, 0x24293eb9 -0, 84, 84, 1, 152064, 0x7b9b2cb4 -0, 85, 85, 1, 152064, 0x9dd4fe95 -0, 86, 86, 1, 152064, 0xb62e8baf -0, 87, 87, 1, 152064, 0x9fefc174 -0, 88, 88, 1, 152064, 0xe027c24e -0, 89, 89, 1, 152064, 0xe38adc70 -0, 90, 90, 1, 152064, 0xc7bf536f -0, 91, 91, 1, 152064, 0x4448f330 -0, 92, 92, 1, 152064, 0x4dad5339 -0, 93, 93, 1, 152064, 0x48fbab15 -0, 94, 94, 1, 152064, 0xe6c97b2c -0, 95, 95, 1, 152064, 0x3c3829ee -0, 96, 96, 1, 152064, 0x927772c0 -0, 97, 97, 1, 152064, 0xbb0f0ef4 -0, 98, 98, 1, 152064, 0xe65780a7 -0, 99, 99, 1, 152064, 0xaf8f6d72 +0, 1, 1, 1, 152064, 0x3b21d6cd +0, 2, 2, 1, 152064, 0xc32088c6 +0, 3, 3, 1, 152064, 0x65a64cee +0, 4, 4, 1, 152064, 0x0bd45a5b +0, 5, 5, 1, 152064, 0xb2210d4d +0, 6, 6, 1, 152064, 0xf5b15527 +0, 7, 7, 1, 152064, 0x806572ad +0, 8, 8, 1, 152064, 0x6ecb1fc8 +0, 9, 9, 1, 152064, 0xc25e96d5 +0, 10, 10, 1, 152064, 0x5593b825 +0, 11, 11, 1, 152064, 0xf3be1cff +0, 12, 12, 1, 152064, 0xa9155072 +0, 13, 13, 1, 152064, 0xd5552e26 +0, 14, 14, 1, 152064, 0x7bf0dbee +0, 15, 15, 1, 152064, 0x998b4911 +0, 16, 16, 1, 152064, 0xcc71bbe0 +0, 17, 17, 1, 152064, 0x602415b8 +0, 18, 18, 1, 152064, 0xcfff37cf +0, 19, 19, 1, 152064, 0x7cf824a8 +0, 20, 20, 1, 152064, 0x34816ee5 +0, 21, 21, 1, 152064, 0x1480540c +0, 22, 22, 1, 152064, 0xc2351aaf +0, 23, 23, 1, 152064, 0x3b8eac9f +0, 24, 24, 1, 152064, 0x92a8faf8 +0, 25, 25, 1, 152064, 0x7b6121c8 +0, 26, 26, 1, 152064, 0xe73a3bac +0, 27, 27, 1, 152064, 0xcd6e1e36 +0, 28, 28, 1, 152064, 0xb24660b1 +0, 29, 29, 1, 152064, 0xa290ec25 +0, 30, 30, 1, 152064, 0x308915ff +0, 31, 31, 1, 152064, 0x1e8dd4db +0, 32, 32, 1, 152064, 0x1372f2e0 +0, 33, 33, 1, 152064, 0xa07cc1d0 +0, 34, 34, 1, 152064, 0x34bb872c +0, 35, 35, 1, 152064, 0x59e6a565 +0, 36, 36, 1, 152064, 0x9a097932 +0, 37, 37, 1, 152064, 0x938f2e20 +0, 38, 38, 1, 152064, 0x59a8157d +0, 39, 39, 1, 152064, 0x5cacd404 +0, 40, 40, 1, 152064, 0xdad068f5 +0, 41, 41, 1, 152064, 0x7ba67d47 +0, 42, 42, 1, 152064, 0xc2a11e2d +0, 43, 43, 1, 152064, 0xd37fdef7 +0, 44, 44, 1, 152064, 0x19a3f80a +0, 45, 45, 1, 152064, 0x7ec7426a +0, 46, 46, 1, 152064, 0x8ffedb61 +0, 47, 47, 1, 152064, 0x82aebdd0 +0, 48, 48, 1, 152064, 0xdfc920cc +0, 49, 49, 1, 152064, 0x2a467698 +0, 50, 50, 1, 152064, 0xd08a37d5 +0, 51, 51, 1, 152064, 0xe606e66a +0, 52, 52, 1, 152064, 0x0e7b8bd8 +0, 53, 53, 1, 152064, 0xf983c732 +0, 54, 54, 1, 152064, 0x9b82c2e7 +0, 55, 55, 1, 152064, 0xa990a47e +0, 56, 56, 1, 152064, 0x2d5679f1 +0, 57, 57, 1, 152064, 0x7f1c0201 +0, 58, 58, 1, 152064, 0xc38b709d +0, 59, 59, 1, 152064, 0x040246d8 +0, 60, 60, 1, 152064, 0xbc856021 +0, 61, 61, 1, 152064, 0x81e01a78 +0, 62, 62, 1, 152064, 0xaff1e7f1 +0, 63, 63, 1, 152064, 0x1fee7715 +0, 64, 64, 1, 152064, 0x65053711 +0, 65, 65, 1, 152064, 0x238a0118 +0, 66, 66, 1, 152064, 0x563491b4 +0, 67, 67, 1, 152064, 0x5974a6cc +0, 68, 68, 1, 152064, 0xd8682c35 +0, 69, 69, 1, 152064, 0x85c49e96 +0, 70, 70, 1, 152064, 0x29486faa +0, 71, 71, 1, 152064, 0x1a4f0579 +0, 72, 72, 1, 152064, 0x6ab86c2f +0, 73, 73, 1, 152064, 0x36a36d2b +0, 74, 74, 1, 152064, 0x3bd77543 +0, 75, 75, 1, 152064, 0x8fbddc41 +0, 76, 76, 1, 152064, 0xccc6e0a5 +0, 77, 77, 1, 152064, 0x00a9539e +0, 78, 78, 1, 152064, 0x07ba0714 +0, 79, 79, 1, 152064, 0xbab2735d +0, 80, 80, 1, 152064, 0x79cb5ba0 +0, 81, 81, 1, 152064, 0xdbcc1c92 +0, 82, 82, 1, 152064, 0xffec952c +0, 83, 83, 1, 152064, 0xc31ac68e +0, 84, 84, 1, 152064, 0x24293eb9 +0, 85, 85, 1, 152064, 0x7b9b2cb4 +0, 86, 86, 1, 152064, 0x9dd4fe95 +0, 87, 87, 1, 152064, 0xb62e8baf +0, 88, 88, 1, 152064, 0x9fefc174 +0, 89, 89, 1, 152064, 0xe027c24e +0, 90, 90, 1, 152064, 0xe38adc70 +0, 91, 91, 1, 152064, 0xc7bf536f +0, 92, 92, 1, 152064, 0x4448f330 +0, 93, 93, 1, 152064, 0x4dad5339 +0, 94, 94, 1, 152064, 0x48fbab15 +0, 95, 95, 1, 152064, 0xe6c97b2c +0, 96, 96, 1, 152064, 0x3c3829ee +0, 97, 97, 1, 152064, 0x927772c0 +0, 98, 98, 1, 152064, 0xbb0f0ef4 +0, 99, 99, 1, 152064, 0xe65780a7 +0, 100, 100, 1, 152064, 0xaf8f6d72 diff --git a/tests/ref/fate/h264-conformance-frext-freh7_b b/tests/ref/fate/h264-conformance-frext-freh7_b index b078cf1b3..cb56f627c 100644 --- a/tests/ref/fate/h264-conformance-frext-freh7_b +++ b/tests/ref/fate/h264-conformance-frext-freh7_b @@ -3,103 +3,103 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x89f2e8d5 -0, 1, 1, 1, 152064, 0x35b99397 -0, 2, 2, 1, 152064, 0x6ef46744 -0, 3, 3, 1, 152064, 0xec4d6c1c -0, 4, 4, 1, 152064, 0xad6e0c70 -0, 5, 5, 1, 152064, 0x2db534b3 -0, 6, 6, 1, 152064, 0xcbd25ddd -0, 7, 7, 1, 152064, 0xd90708b4 -0, 8, 8, 1, 152064, 0xc2aa52df -0, 9, 9, 1, 152064, 0xbcfc84dc -0, 10, 10, 1, 152064, 0xa5a6d269 -0, 11, 11, 1, 152064, 0x27220ce9 -0, 12, 12, 1, 152064, 0xf075ee6d -0, 13, 13, 1, 152064, 0x9fd3c2ac -0, 14, 14, 1, 152064, 0xcba24c2d -0, 15, 15, 1, 152064, 0x41cd9441 -0, 16, 16, 1, 152064, 0x0126efa3 -0, 17, 17, 1, 152064, 0xf62112af -0, 18, 18, 1, 152064, 0x35aff50f -0, 19, 19, 1, 152064, 0xcb0b276f -0, 20, 20, 1, 152064, 0xc7ef0214 -0, 21, 21, 1, 152064, 0x7f78d387 -0, 22, 22, 1, 152064, 0x266c673d -0, 23, 23, 1, 152064, 0x1d39c073 -0, 24, 24, 1, 152064, 0x6a3ae455 -0, 25, 25, 1, 152064, 0xe4ce0230 -0, 26, 26, 1, 152064, 0x7f95e87b -0, 27, 27, 1, 152064, 0x7c552236 -0, 28, 28, 1, 152064, 0x24c799b9 -0, 29, 29, 1, 152064, 0x5042d974 -0, 30, 30, 1, 152064, 0xe934a5b8 -0, 31, 31, 1, 152064, 0x6d59c884 -0, 32, 32, 1, 152064, 0xd00f7fdb -0, 33, 33, 1, 152064, 0x62ac3ebd -0, 34, 34, 1, 152064, 0xb40a6c25 -0, 35, 35, 1, 152064, 0x8706188c -0, 36, 36, 1, 152064, 0x7682e339 -0, 37, 37, 1, 152064, 0x1061d943 -0, 38, 38, 1, 152064, 0x50fa684a -0, 39, 39, 1, 152064, 0xab4b1975 -0, 40, 40, 1, 152064, 0x2d043acb -0, 41, 41, 1, 152064, 0xe3c2ec0a -0, 42, 42, 1, 152064, 0xb9bc99dc -0, 43, 43, 1, 152064, 0x051fb857 -0, 44, 44, 1, 152064, 0x71d1fe52 -0, 45, 45, 1, 152064, 0x4230c694 -0, 46, 46, 1, 152064, 0xb412a137 -0, 47, 47, 1, 152064, 0x2f50f90d -0, 48, 48, 1, 152064, 0x68a1466f -0, 49, 49, 1, 152064, 0x77e3f47b -0, 50, 50, 1, 152064, 0x4d08de2b -0, 51, 51, 1, 152064, 0x1fc663be -0, 52, 52, 1, 152064, 0x2c8ba712 -0, 53, 53, 1, 152064, 0xd50d85b9 -0, 54, 54, 1, 152064, 0xe8483437 -0, 55, 55, 1, 152064, 0x4e331e4c -0, 56, 56, 1, 152064, 0x0f64a7a0 -0, 57, 57, 1, 152064, 0x797b0b8c -0, 58, 58, 1, 152064, 0x1b91e6d8 -0, 59, 59, 1, 152064, 0xf3a1f3b6 -0, 60, 60, 1, 152064, 0x2b94bd52 -0, 61, 61, 1, 152064, 0x1f30962e -0, 62, 62, 1, 152064, 0x853321cf -0, 63, 63, 1, 152064, 0x8266c0ac -0, 64, 64, 1, 152064, 0x25498be0 -0, 65, 65, 1, 152064, 0x0f653af9 -0, 66, 66, 1, 152064, 0x0a025f7e -0, 67, 67, 1, 152064, 0x1cfbae04 -0, 68, 68, 1, 152064, 0x3a874757 -0, 69, 69, 1, 152064, 0x2c67006e -0, 70, 70, 1, 152064, 0x1d409bce -0, 71, 71, 1, 152064, 0xfe43121f -0, 72, 72, 1, 152064, 0x43411830 -0, 73, 73, 1, 152064, 0x536d26ca -0, 74, 74, 1, 152064, 0x9eb873ea -0, 75, 75, 1, 152064, 0x093f93ec -0, 76, 76, 1, 152064, 0xdf6f0381 -0, 77, 77, 1, 152064, 0xa9f4b5e5 -0, 78, 78, 1, 152064, 0x08f71ef8 -0, 79, 79, 1, 152064, 0x7a68f820 -0, 80, 80, 1, 152064, 0xae0c73e7 -0, 81, 81, 1, 152064, 0x886ae6c7 -0, 82, 82, 1, 152064, 0x9357f433 -0, 83, 83, 1, 152064, 0xcc335068 -0, 84, 84, 1, 152064, 0x2ea108ab -0, 85, 85, 1, 152064, 0x06d7dcb0 -0, 86, 86, 1, 152064, 0x81dc81bc -0, 87, 87, 1, 152064, 0xfb32b626 -0, 88, 88, 1, 152064, 0x2787d1c7 -0, 89, 89, 1, 152064, 0x69e51118 -0, 90, 90, 1, 152064, 0xba15d94d -0, 91, 91, 1, 152064, 0xc41c09cf -0, 92, 92, 1, 152064, 0x7e50e12f -0, 93, 93, 1, 152064, 0x0763ddbe -0, 94, 94, 1, 152064, 0x8a09bb88 -0, 95, 95, 1, 152064, 0x530752b7 -0, 96, 96, 1, 152064, 0x9b159923 -0, 97, 97, 1, 152064, 0xcbb83ed3 -0, 98, 98, 1, 152064, 0xdeb5ac0e -0, 99, 99, 1, 152064, 0x189299d4 +0, 1, 1, 1, 152064, 0x89f2e8d5 +0, 2, 2, 1, 152064, 0x35b99397 +0, 3, 3, 1, 152064, 0x6ef46744 +0, 4, 4, 1, 152064, 0xec4d6c1c +0, 5, 5, 1, 152064, 0xad6e0c70 +0, 6, 6, 1, 152064, 0x2db534b3 +0, 7, 7, 1, 152064, 0xcbd25ddd +0, 8, 8, 1, 152064, 0xd90708b4 +0, 9, 9, 1, 152064, 0xc2aa52df +0, 10, 10, 1, 152064, 0xbcfc84dc +0, 11, 11, 1, 152064, 0xa5a6d269 +0, 12, 12, 1, 152064, 0x27220ce9 +0, 13, 13, 1, 152064, 0xf075ee6d +0, 14, 14, 1, 152064, 0x9fd3c2ac +0, 15, 15, 1, 152064, 0xcba24c2d +0, 16, 16, 1, 152064, 0x41cd9441 +0, 17, 17, 1, 152064, 0x0126efa3 +0, 18, 18, 1, 152064, 0xf62112af +0, 19, 19, 1, 152064, 0x35aff50f +0, 20, 20, 1, 152064, 0xcb0b276f +0, 21, 21, 1, 152064, 0xc7ef0214 +0, 22, 22, 1, 152064, 0x7f78d387 +0, 23, 23, 1, 152064, 0x266c673d +0, 24, 24, 1, 152064, 0x1d39c073 +0, 25, 25, 1, 152064, 0x6a3ae455 +0, 26, 26, 1, 152064, 0xe4ce0230 +0, 27, 27, 1, 152064, 0x7f95e87b +0, 28, 28, 1, 152064, 0x7c552236 +0, 29, 29, 1, 152064, 0x24c799b9 +0, 30, 30, 1, 152064, 0x5042d974 +0, 31, 31, 1, 152064, 0xe934a5b8 +0, 32, 32, 1, 152064, 0x6d59c884 +0, 33, 33, 1, 152064, 0xd00f7fdb +0, 34, 34, 1, 152064, 0x62ac3ebd +0, 35, 35, 1, 152064, 0xb40a6c25 +0, 36, 36, 1, 152064, 0x8706188c +0, 37, 37, 1, 152064, 0x7682e339 +0, 38, 38, 1, 152064, 0x1061d943 +0, 39, 39, 1, 152064, 0x50fa684a +0, 40, 40, 1, 152064, 0xab4b1975 +0, 41, 41, 1, 152064, 0x2d043acb +0, 42, 42, 1, 152064, 0xe3c2ec0a +0, 43, 43, 1, 152064, 0xb9bc99dc +0, 44, 44, 1, 152064, 0x051fb857 +0, 45, 45, 1, 152064, 0x71d1fe52 +0, 46, 46, 1, 152064, 0x4230c694 +0, 47, 47, 1, 152064, 0xb412a137 +0, 48, 48, 1, 152064, 0x2f50f90d +0, 49, 49, 1, 152064, 0x68a1466f +0, 50, 50, 1, 152064, 0x77e3f47b +0, 51, 51, 1, 152064, 0x4d08de2b +0, 52, 52, 1, 152064, 0x1fc663be +0, 53, 53, 1, 152064, 0x2c8ba712 +0, 54, 54, 1, 152064, 0xd50d85b9 +0, 55, 55, 1, 152064, 0xe8483437 +0, 56, 56, 1, 152064, 0x4e331e4c +0, 57, 57, 1, 152064, 0x0f64a7a0 +0, 58, 58, 1, 152064, 0x797b0b8c +0, 59, 59, 1, 152064, 0x1b91e6d8 +0, 60, 60, 1, 152064, 0xf3a1f3b6 +0, 61, 61, 1, 152064, 0x2b94bd52 +0, 62, 62, 1, 152064, 0x1f30962e +0, 63, 63, 1, 152064, 0x853321cf +0, 64, 64, 1, 152064, 0x8266c0ac +0, 65, 65, 1, 152064, 0x25498be0 +0, 66, 66, 1, 152064, 0x0f653af9 +0, 67, 67, 1, 152064, 0x0a025f7e +0, 68, 68, 1, 152064, 0x1cfbae04 +0, 69, 69, 1, 152064, 0x3a874757 +0, 70, 70, 1, 152064, 0x2c67006e +0, 71, 71, 1, 152064, 0x1d409bce +0, 72, 72, 1, 152064, 0xfe43121f +0, 73, 73, 1, 152064, 0x43411830 +0, 74, 74, 1, 152064, 0x536d26ca +0, 75, 75, 1, 152064, 0x9eb873ea +0, 76, 76, 1, 152064, 0x093f93ec +0, 77, 77, 1, 152064, 0xdf6f0381 +0, 78, 78, 1, 152064, 0xa9f4b5e5 +0, 79, 79, 1, 152064, 0x08f71ef8 +0, 80, 80, 1, 152064, 0x7a68f820 +0, 81, 81, 1, 152064, 0xae0c73e7 +0, 82, 82, 1, 152064, 0x886ae6c7 +0, 83, 83, 1, 152064, 0x9357f433 +0, 84, 84, 1, 152064, 0xcc335068 +0, 85, 85, 1, 152064, 0x2ea108ab +0, 86, 86, 1, 152064, 0x06d7dcb0 +0, 87, 87, 1, 152064, 0x81dc81bc +0, 88, 88, 1, 152064, 0xfb32b626 +0, 89, 89, 1, 152064, 0x2787d1c7 +0, 90, 90, 1, 152064, 0x69e51118 +0, 91, 91, 1, 152064, 0xba15d94d +0, 92, 92, 1, 152064, 0xc41c09cf +0, 93, 93, 1, 152064, 0x7e50e12f +0, 94, 94, 1, 152064, 0x0763ddbe +0, 95, 95, 1, 152064, 0x8a09bb88 +0, 96, 96, 1, 152064, 0x530752b7 +0, 97, 97, 1, 152064, 0x9b159923 +0, 98, 98, 1, 152064, 0xcbb83ed3 +0, 99, 99, 1, 152064, 0xdeb5ac0e +0, 100, 100, 1, 152064, 0x189299d4 diff --git a/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b b/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b index 67badb6c2..f54113592 100644 --- a/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b +++ b/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b @@ -3,13 +3,13 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0xb055a9bd -0, 1, 1, 1, 152064, 0x9e1eadb6 -0, 2, 2, 1, 152064, 0x48f117d2 -0, 3, 3, 1, 152064, 0x3e3ff049 -0, 4, 4, 1, 152064, 0x2ff80943 -0, 5, 5, 1, 152064, 0xc5ee16a6 -0, 6, 6, 1, 152064, 0x38c33f28 -0, 7, 7, 1, 152064, 0x3e8444c7 -0, 8, 8, 1, 152064, 0x14ca4ab2 -0, 9, 9, 1, 152064, 0xe20e78f7 +0, 1, 1, 1, 152064, 0xb055a9bd +0, 2, 2, 1, 152064, 0x9e1eadb6 +0, 3, 3, 1, 152064, 0x48f117d2 +0, 4, 4, 1, 152064, 0x3e3ff049 +0, 5, 5, 1, 152064, 0x2ff80943 +0, 6, 6, 1, 152064, 0xc5ee16a6 +0, 7, 7, 1, 152064, 0x38c33f28 +0, 8, 8, 1, 152064, 0x3e8444c7 +0, 9, 9, 1, 152064, 0x14ca4ab2 +0, 10, 10, 1, 152064, 0xe20e78f7 diff --git a/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c b/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c index 0febed6d6..25551fb02 100644 --- a/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c +++ b/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c @@ -3,303 +3,303 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x502ec077 -0, 1, 1, 1, 152064, 0x84807243 -0, 2, 2, 1, 152064, 0xd7474a6e -0, 3, 3, 1, 152064, 0x793469bb -0, 4, 4, 1, 152064, 0xb7a0faf7 -0, 5, 5, 1, 152064, 0x1d3d3cba -0, 6, 6, 1, 152064, 0xb62583de -0, 7, 7, 1, 152064, 0xc8422fb1 -0, 8, 8, 1, 152064, 0x321dc699 -0, 9, 9, 1, 152064, 0x7a34d350 -0, 10, 10, 1, 152064, 0xaa4c302d -0, 11, 11, 1, 152064, 0x45fa7ab0 -0, 12, 12, 1, 152064, 0xc7262e41 -0, 13, 13, 1, 152064, 0x3550000c -0, 14, 14, 1, 152064, 0xf4bab54b -0, 15, 15, 1, 152064, 0xaccf9c1a -0, 16, 16, 1, 152064, 0x9bee20e9 -0, 17, 17, 1, 152064, 0x47fb7720 -0, 18, 18, 1, 152064, 0x12c63ffb -0, 19, 19, 1, 152064, 0xfa2b8b4d -0, 20, 20, 1, 152064, 0x279964bd -0, 21, 21, 1, 152064, 0xb8b01c7e -0, 22, 22, 1, 152064, 0x816fa010 -0, 23, 23, 1, 152064, 0x59fe1c8c -0, 24, 24, 1, 152064, 0x13393fad -0, 25, 25, 1, 152064, 0x991a50a4 -0, 26, 26, 1, 152064, 0x57df3eb7 -0, 27, 27, 1, 152064, 0x744371df -0, 28, 28, 1, 152064, 0xe9f6d3ff -0, 29, 29, 1, 152064, 0xc506fba0 -0, 30, 30, 1, 152064, 0x6295b90e -0, 31, 31, 1, 152064, 0xa19cee2d -0, 32, 32, 1, 152064, 0xf8c1b3ca -0, 33, 33, 1, 152064, 0x69f68ce0 -0, 34, 34, 1, 152064, 0x80558bb6 -0, 35, 35, 1, 152064, 0x27824fa5 -0, 36, 36, 1, 152064, 0x27c929a1 -0, 37, 37, 1, 152064, 0xc0fe06d1 -0, 38, 38, 1, 152064, 0xc52bc58c -0, 39, 39, 1, 152064, 0x0a5363c7 -0, 40, 40, 1, 152064, 0xd0f45a0d -0, 41, 41, 1, 152064, 0x274710f9 -0, 42, 42, 1, 152064, 0x89d2d390 -0, 43, 43, 1, 152064, 0x12a9bfb0 -0, 44, 44, 1, 152064, 0x04501a93 -0, 45, 45, 1, 152064, 0xf92cbbf4 -0, 46, 46, 1, 152064, 0xf6d1b27d -0, 47, 47, 1, 152064, 0xe3e904c3 -0, 48, 48, 1, 152064, 0x58f8516d -0, 49, 49, 1, 152064, 0x70370c2b -0, 50, 50, 1, 152064, 0xfeebc88c -0, 51, 51, 1, 152064, 0x974c6ed6 -0, 52, 52, 1, 152064, 0x401bdcf2 -0, 53, 53, 1, 152064, 0xfe61e278 -0, 54, 54, 1, 152064, 0x96ba8bb9 -0, 55, 55, 1, 152064, 0x988492fd -0, 56, 56, 1, 152064, 0xd1d913a9 -0, 57, 57, 1, 152064, 0x6bc46f0e -0, 58, 58, 1, 152064, 0x695ef706 -0, 59, 59, 1, 152064, 0x142045c9 -0, 60, 60, 1, 152064, 0xb390ed87 -0, 61, 61, 1, 152064, 0xb9e6d2e5 -0, 62, 62, 1, 152064, 0xe348797f -0, 63, 63, 1, 152064, 0x1cbd29d6 -0, 64, 64, 1, 152064, 0xbd7dd694 -0, 65, 65, 1, 152064, 0x516873c3 -0, 66, 66, 1, 152064, 0x27bba182 -0, 67, 67, 1, 152064, 0x7541f920 -0, 68, 68, 1, 152064, 0xfdf67042 -0, 69, 69, 1, 152064, 0x6c3c7896 -0, 70, 70, 1, 152064, 0xed86c467 -0, 71, 71, 1, 152064, 0x4ea83ca2 -0, 72, 72, 1, 152064, 0xa3e6725b -0, 73, 73, 1, 152064, 0x917f5f16 -0, 74, 74, 1, 152064, 0x8cf2d2e1 -0, 75, 75, 1, 152064, 0x57a8d116 -0, 76, 76, 1, 152064, 0x0db267d4 -0, 77, 77, 1, 152064, 0xce782ac5 -0, 78, 78, 1, 152064, 0x1c9d8518 -0, 79, 79, 1, 152064, 0x47598ac7 -0, 80, 80, 1, 152064, 0xc5033d97 -0, 81, 81, 1, 152064, 0xd7aaa3a4 -0, 82, 82, 1, 152064, 0x078afc96 -0, 83, 83, 1, 152064, 0xc9fe673d -0, 84, 84, 1, 152064, 0xe9284066 -0, 85, 85, 1, 152064, 0xbc570982 -0, 86, 86, 1, 152064, 0x0aac8574 -0, 87, 87, 1, 152064, 0x098cbeee -0, 88, 88, 1, 152064, 0x19c36a9d -0, 89, 89, 1, 152064, 0x8fe4a893 -0, 90, 90, 1, 152064, 0x0b652f17 -0, 91, 91, 1, 152064, 0x10f2e6bf -0, 92, 92, 1, 152064, 0x7ce5634e -0, 93, 93, 1, 152064, 0x8fe4ac6c -0, 94, 94, 1, 152064, 0xcaba749e -0, 95, 95, 1, 152064, 0x5f8a0d5c -0, 96, 96, 1, 152064, 0xcaa66bbc -0, 97, 97, 1, 152064, 0xc87ae617 -0, 98, 98, 1, 152064, 0xe8ef4dd7 -0, 99, 99, 1, 152064, 0xdfca5a07 -0, 100, 100, 1, 152064, 0x5f7eab7d -0, 101, 101, 1, 152064, 0x8a65ebbb -0, 102, 102, 1, 152064, 0x4beab4a0 -0, 103, 103, 1, 152064, 0xb5e6ab30 -0, 104, 104, 1, 152064, 0x8fe4f4d4 -0, 105, 105, 1, 152064, 0x95bde1ca -0, 106, 106, 1, 152064, 0xcc5e3a53 -0, 107, 107, 1, 152064, 0xf09f1dd7 -0, 108, 108, 1, 152064, 0x10179672 -0, 109, 109, 1, 152064, 0x4ad16184 -0, 110, 110, 1, 152064, 0x9efa0e23 -0, 111, 111, 1, 152064, 0x22f59522 -0, 112, 112, 1, 152064, 0x4d38f09d -0, 113, 113, 1, 152064, 0x4c5ebf56 -0, 114, 114, 1, 152064, 0xb19d5077 -0, 115, 115, 1, 152064, 0xa98576b9 -0, 116, 116, 1, 152064, 0x65324239 -0, 117, 117, 1, 152064, 0x709e4031 -0, 118, 118, 1, 152064, 0xf8e81681 -0, 119, 119, 1, 152064, 0x058514e5 -0, 120, 120, 1, 152064, 0xd1d1c806 -0, 121, 121, 1, 152064, 0x0e4dde57 -0, 122, 122, 1, 152064, 0x49e9c2bb -0, 123, 123, 1, 152064, 0x01417ce6 -0, 124, 124, 1, 152064, 0xda7ebbf1 -0, 125, 125, 1, 152064, 0xa22906b7 -0, 126, 126, 1, 152064, 0x32e2df87 -0, 127, 127, 1, 152064, 0x69917c8f -0, 128, 128, 1, 152064, 0xea8ed2cc -0, 129, 129, 1, 152064, 0x0b8d57f1 -0, 130, 130, 1, 152064, 0x5f683bcd -0, 131, 131, 1, 152064, 0x5162fe2f -0, 132, 132, 1, 152064, 0x49c052f8 -0, 133, 133, 1, 152064, 0x990b69ba -0, 134, 134, 1, 152064, 0xa6d4f99f -0, 135, 135, 1, 152064, 0xe79ef4da -0, 136, 136, 1, 152064, 0x5e8a3847 -0, 137, 137, 1, 152064, 0x38b1e75f -0, 138, 138, 1, 152064, 0xf5c91bed -0, 139, 139, 1, 152064, 0xd59a6d26 -0, 140, 140, 1, 152064, 0xc361de06 -0, 141, 141, 1, 152064, 0x63ed2229 -0, 142, 142, 1, 152064, 0xb8229205 -0, 143, 143, 1, 152064, 0x7c6619af -0, 144, 144, 1, 152064, 0x4126b02f -0, 145, 145, 1, 152064, 0x9250b99b -0, 146, 146, 1, 152064, 0x589778f9 -0, 147, 147, 1, 152064, 0xed1fa45b -0, 148, 148, 1, 152064, 0x700b6f32 -0, 149, 149, 1, 152064, 0x0590df55 -0, 150, 150, 1, 152064, 0x3e9c4018 -0, 151, 151, 1, 152064, 0x957b8860 -0, 152, 152, 1, 152064, 0x56161560 -0, 153, 153, 1, 152064, 0xbc43bc3b -0, 154, 154, 1, 152064, 0x508d8632 -0, 155, 155, 1, 152064, 0xbc5736d8 -0, 156, 156, 1, 152064, 0xed7d3aef -0, 157, 157, 1, 152064, 0x1dcdda9f -0, 158, 158, 1, 152064, 0x8ef6d5c9 -0, 159, 159, 1, 152064, 0x15466acc -0, 160, 160, 1, 152064, 0x45d4cf67 -0, 161, 161, 1, 152064, 0x8c900b9d -0, 162, 162, 1, 152064, 0x747006e0 -0, 163, 163, 1, 152064, 0xac920a0c -0, 164, 164, 1, 152064, 0xb8210c27 -0, 165, 165, 1, 152064, 0x7dbb873a -0, 166, 166, 1, 152064, 0x0d4d7584 -0, 167, 167, 1, 152064, 0xefb3fe60 -0, 168, 168, 1, 152064, 0x905e2644 -0, 169, 169, 1, 152064, 0x7c04e534 -0, 170, 170, 1, 152064, 0x8889972a -0, 171, 171, 1, 152064, 0x21c7d8ad -0, 172, 172, 1, 152064, 0x1c641176 -0, 173, 173, 1, 152064, 0xf71489a4 -0, 174, 174, 1, 152064, 0xd7ac5555 -0, 175, 175, 1, 152064, 0xb4609c6d -0, 176, 176, 1, 152064, 0xf5b2bd5e -0, 177, 177, 1, 152064, 0x9f43ce57 -0, 178, 178, 1, 152064, 0x77642dd3 -0, 179, 179, 1, 152064, 0x3e79565c -0, 180, 180, 1, 152064, 0x95f40b8e -0, 181, 181, 1, 152064, 0x3c8ca4d4 -0, 182, 182, 1, 152064, 0xa02ac497 -0, 183, 183, 1, 152064, 0x4c93b377 -0, 184, 184, 1, 152064, 0x55f5ac68 -0, 185, 185, 1, 152064, 0xf8652eca -0, 186, 186, 1, 152064, 0x56e94574 -0, 187, 187, 1, 152064, 0x6d8302e1 -0, 188, 188, 1, 152064, 0x29a57061 -0, 189, 189, 1, 152064, 0x24e4cfdc -0, 190, 190, 1, 152064, 0xf5a5d62a -0, 191, 191, 1, 152064, 0x998870c1 -0, 192, 192, 1, 152064, 0xa15b1f4e -0, 193, 193, 1, 152064, 0xb0ccb51f -0, 194, 194, 1, 152064, 0xeaaf59ab -0, 195, 195, 1, 152064, 0x7e2b4fe6 -0, 196, 196, 1, 152064, 0x72299fea -0, 197, 197, 1, 152064, 0x769da8b2 -0, 198, 198, 1, 152064, 0xefad7ef8 -0, 199, 199, 1, 152064, 0x24819983 -0, 200, 200, 1, 152064, 0x2aad32ab -0, 201, 201, 1, 152064, 0xc80cac79 -0, 202, 202, 1, 152064, 0x1659d628 -0, 203, 203, 1, 152064, 0xef941f66 -0, 204, 204, 1, 152064, 0x0d7fcdb5 -0, 205, 205, 1, 152064, 0x7c1853fa -0, 206, 206, 1, 152064, 0xb94c4d3c -0, 207, 207, 1, 152064, 0xc47adfc2 -0, 208, 208, 1, 152064, 0x366a6729 -0, 209, 209, 1, 152064, 0x7eb37b70 -0, 210, 210, 1, 152064, 0xafd54c27 -0, 211, 211, 1, 152064, 0x67b18636 -0, 212, 212, 1, 152064, 0x93b22dcf -0, 213, 213, 1, 152064, 0xa64991f1 -0, 214, 214, 1, 152064, 0xd32a7102 -0, 215, 215, 1, 152064, 0xff665d1c -0, 216, 216, 1, 152064, 0xf107cc31 -0, 217, 217, 1, 152064, 0xf5b25652 -0, 218, 218, 1, 152064, 0x8caf783d -0, 219, 219, 1, 152064, 0x72f3eb00 -0, 220, 220, 1, 152064, 0xb5aea5f8 -0, 221, 221, 1, 152064, 0xee70e870 -0, 222, 222, 1, 152064, 0x7c3a0156 -0, 223, 223, 1, 152064, 0x871b6383 -0, 224, 224, 1, 152064, 0x48d831ff -0, 225, 225, 1, 152064, 0xca233913 -0, 226, 226, 1, 152064, 0xe14bc5eb -0, 227, 227, 1, 152064, 0x9b1d27e7 -0, 228, 228, 1, 152064, 0xfb9637f7 -0, 229, 229, 1, 152064, 0x0c022157 -0, 230, 230, 1, 152064, 0x16d35fc9 -0, 231, 231, 1, 152064, 0x6d935f71 -0, 232, 232, 1, 152064, 0xae4066fa -0, 233, 233, 1, 152064, 0xcef94fdc -0, 234, 234, 1, 152064, 0xc234edb9 -0, 235, 235, 1, 152064, 0x26a4f2e2 -0, 236, 236, 1, 152064, 0xd29ac23e -0, 237, 237, 1, 152064, 0xb7604395 -0, 238, 238, 1, 152064, 0x408084f6 -0, 239, 239, 1, 152064, 0x0a02026c -0, 240, 240, 1, 152064, 0x78b33c7c -0, 241, 241, 1, 152064, 0xcb02b874 -0, 242, 242, 1, 152064, 0xf566513b -0, 243, 243, 1, 152064, 0xb34e52b1 -0, 244, 244, 1, 152064, 0xf55ff493 -0, 245, 245, 1, 152064, 0xb0e8282a -0, 246, 246, 1, 152064, 0xe9510bbe -0, 247, 247, 1, 152064, 0x292e8c5a -0, 248, 248, 1, 152064, 0x62b9d2b0 -0, 249, 249, 1, 152064, 0x3a8cc827 -0, 250, 250, 1, 152064, 0x25cc465e -0, 251, 251, 1, 152064, 0xf2bc32e2 -0, 252, 252, 1, 152064, 0x6141f914 -0, 253, 253, 1, 152064, 0x1171256f -0, 254, 254, 1, 152064, 0x13cb2ded -0, 255, 255, 1, 152064, 0x3d4ca557 -0, 256, 256, 1, 152064, 0xf2b9e72e -0, 257, 257, 1, 152064, 0x03f7547a -0, 258, 258, 1, 152064, 0xc7302955 -0, 259, 259, 1, 152064, 0xe78a46d3 -0, 260, 260, 1, 152064, 0x3726a270 -0, 261, 261, 1, 152064, 0x2f65722a -0, 262, 262, 1, 152064, 0x55acce40 -0, 263, 263, 1, 152064, 0xf6fa9db2 -0, 264, 264, 1, 152064, 0x70a36937 -0, 265, 265, 1, 152064, 0x9313742d -0, 266, 266, 1, 152064, 0x2eb14e53 -0, 267, 267, 1, 152064, 0x3d47c9c3 -0, 268, 268, 1, 152064, 0xd0a90348 -0, 269, 269, 1, 152064, 0x6ad48088 -0, 270, 270, 1, 152064, 0x68e64738 -0, 271, 271, 1, 152064, 0x04c3735a -0, 272, 272, 1, 152064, 0x51d0593f -0, 273, 273, 1, 152064, 0x42cf2b48 -0, 274, 274, 1, 152064, 0xa5496a0c -0, 275, 275, 1, 152064, 0x84c25549 -0, 276, 276, 1, 152064, 0x96691600 -0, 277, 277, 1, 152064, 0x423135db -0, 278, 278, 1, 152064, 0x8d2e08b6 -0, 279, 279, 1, 152064, 0xaeb4c840 -0, 280, 280, 1, 152064, 0xf3e71780 -0, 281, 281, 1, 152064, 0x8858228b -0, 282, 282, 1, 152064, 0xf28613f8 -0, 283, 283, 1, 152064, 0xb5327882 -0, 284, 284, 1, 152064, 0xbb60bb85 -0, 285, 285, 1, 152064, 0x345ab1c9 -0, 286, 286, 1, 152064, 0x8aac2cba -0, 287, 287, 1, 152064, 0x7ce15b4c -0, 288, 288, 1, 152064, 0xc09c55c0 -0, 289, 289, 1, 152064, 0x8482ddd6 -0, 290, 290, 1, 152064, 0xab222a13 -0, 291, 291, 1, 152064, 0xd39b0dea -0, 292, 292, 1, 152064, 0x6dab6e06 -0, 293, 293, 1, 152064, 0xec0891bd -0, 294, 294, 1, 152064, 0x88bd9701 -0, 295, 295, 1, 152064, 0xdf13072a -0, 296, 296, 1, 152064, 0x23b33081 -0, 297, 297, 1, 152064, 0x63943137 -0, 298, 298, 1, 152064, 0xab6a9052 -0, 299, 299, 1, 152064, 0x05485494 +0, 1, 1, 1, 152064, 0x502ec077 +0, 2, 2, 1, 152064, 0x84807243 +0, 3, 3, 1, 152064, 0xd7474a6e +0, 4, 4, 1, 152064, 0x793469bb +0, 5, 5, 1, 152064, 0xb7a0faf7 +0, 6, 6, 1, 152064, 0x1d3d3cba +0, 7, 7, 1, 152064, 0xb62583de +0, 8, 8, 1, 152064, 0xc8422fb1 +0, 9, 9, 1, 152064, 0x321dc699 +0, 10, 10, 1, 152064, 0x7a34d350 +0, 11, 11, 1, 152064, 0xaa4c302d +0, 12, 12, 1, 152064, 0x45fa7ab0 +0, 13, 13, 1, 152064, 0xc7262e41 +0, 14, 14, 1, 152064, 0x3550000c +0, 15, 15, 1, 152064, 0xf4bab54b +0, 16, 16, 1, 152064, 0xaccf9c1a +0, 17, 17, 1, 152064, 0x9bee20e9 +0, 18, 18, 1, 152064, 0x47fb7720 +0, 19, 19, 1, 152064, 0x12c63ffb +0, 20, 20, 1, 152064, 0xfa2b8b4d +0, 21, 21, 1, 152064, 0x279964bd +0, 22, 22, 1, 152064, 0xb8b01c7e +0, 23, 23, 1, 152064, 0x816fa010 +0, 24, 24, 1, 152064, 0x59fe1c8c +0, 25, 25, 1, 152064, 0x13393fad +0, 26, 26, 1, 152064, 0x991a50a4 +0, 27, 27, 1, 152064, 0x57df3eb7 +0, 28, 28, 1, 152064, 0x744371df +0, 29, 29, 1, 152064, 0xe9f6d3ff +0, 30, 30, 1, 152064, 0xc506fba0 +0, 31, 31, 1, 152064, 0x6295b90e +0, 32, 32, 1, 152064, 0xa19cee2d +0, 33, 33, 1, 152064, 0xf8c1b3ca +0, 34, 34, 1, 152064, 0x69f68ce0 +0, 35, 35, 1, 152064, 0x80558bb6 +0, 36, 36, 1, 152064, 0x27824fa5 +0, 37, 37, 1, 152064, 0x27c929a1 +0, 38, 38, 1, 152064, 0xc0fe06d1 +0, 39, 39, 1, 152064, 0xc52bc58c +0, 40, 40, 1, 152064, 0x0a5363c7 +0, 41, 41, 1, 152064, 0xd0f45a0d +0, 42, 42, 1, 152064, 0x274710f9 +0, 43, 43, 1, 152064, 0x89d2d390 +0, 44, 44, 1, 152064, 0x12a9bfb0 +0, 45, 45, 1, 152064, 0x04501a93 +0, 46, 46, 1, 152064, 0xf92cbbf4 +0, 47, 47, 1, 152064, 0xf6d1b27d +0, 48, 48, 1, 152064, 0xe3e904c3 +0, 49, 49, 1, 152064, 0x58f8516d +0, 50, 50, 1, 152064, 0x70370c2b +0, 51, 51, 1, 152064, 0xfeebc88c +0, 52, 52, 1, 152064, 0x974c6ed6 +0, 53, 53, 1, 152064, 0x401bdcf2 +0, 54, 54, 1, 152064, 0xfe61e278 +0, 55, 55, 1, 152064, 0x96ba8bb9 +0, 56, 56, 1, 152064, 0x988492fd +0, 57, 57, 1, 152064, 0xd1d913a9 +0, 58, 58, 1, 152064, 0x6bc46f0e +0, 59, 59, 1, 152064, 0x695ef706 +0, 60, 60, 1, 152064, 0x142045c9 +0, 61, 61, 1, 152064, 0xb390ed87 +0, 62, 62, 1, 152064, 0xb9e6d2e5 +0, 63, 63, 1, 152064, 0xe348797f +0, 64, 64, 1, 152064, 0x1cbd29d6 +0, 65, 65, 1, 152064, 0xbd7dd694 +0, 66, 66, 1, 152064, 0x516873c3 +0, 67, 67, 1, 152064, 0x27bba182 +0, 68, 68, 1, 152064, 0x7541f920 +0, 69, 69, 1, 152064, 0xfdf67042 +0, 70, 70, 1, 152064, 0x6c3c7896 +0, 71, 71, 1, 152064, 0xed86c467 +0, 72, 72, 1, 152064, 0x4ea83ca2 +0, 73, 73, 1, 152064, 0xa3e6725b +0, 74, 74, 1, 152064, 0x917f5f16 +0, 75, 75, 1, 152064, 0x8cf2d2e1 +0, 76, 76, 1, 152064, 0x57a8d116 +0, 77, 77, 1, 152064, 0x0db267d4 +0, 78, 78, 1, 152064, 0xce782ac5 +0, 79, 79, 1, 152064, 0x1c9d8518 +0, 80, 80, 1, 152064, 0x47598ac7 +0, 81, 81, 1, 152064, 0xc5033d97 +0, 82, 82, 1, 152064, 0xd7aaa3a4 +0, 83, 83, 1, 152064, 0x078afc96 +0, 84, 84, 1, 152064, 0xc9fe673d +0, 85, 85, 1, 152064, 0xe9284066 +0, 86, 86, 1, 152064, 0xbc570982 +0, 87, 87, 1, 152064, 0x0aac8574 +0, 88, 88, 1, 152064, 0x098cbeee +0, 89, 89, 1, 152064, 0x19c36a9d +0, 90, 90, 1, 152064, 0x8fe4a893 +0, 91, 91, 1, 152064, 0x0b652f17 +0, 92, 92, 1, 152064, 0x10f2e6bf +0, 93, 93, 1, 152064, 0x7ce5634e +0, 94, 94, 1, 152064, 0x8fe4ac6c +0, 95, 95, 1, 152064, 0xcaba749e +0, 96, 96, 1, 152064, 0x5f8a0d5c +0, 97, 97, 1, 152064, 0xcaa66bbc +0, 98, 98, 1, 152064, 0xc87ae617 +0, 99, 99, 1, 152064, 0xe8ef4dd7 +0, 100, 100, 1, 152064, 0xdfca5a07 +0, 101, 101, 1, 152064, 0x5f7eab7d +0, 102, 102, 1, 152064, 0x8a65ebbb +0, 103, 103, 1, 152064, 0x4beab4a0 +0, 104, 104, 1, 152064, 0xb5e6ab30 +0, 105, 105, 1, 152064, 0x8fe4f4d4 +0, 106, 106, 1, 152064, 0x95bde1ca +0, 107, 107, 1, 152064, 0xcc5e3a53 +0, 108, 108, 1, 152064, 0xf09f1dd7 +0, 109, 109, 1, 152064, 0x10179672 +0, 110, 110, 1, 152064, 0x4ad16184 +0, 111, 111, 1, 152064, 0x9efa0e23 +0, 112, 112, 1, 152064, 0x22f59522 +0, 113, 113, 1, 152064, 0x4d38f09d +0, 114, 114, 1, 152064, 0x4c5ebf56 +0, 115, 115, 1, 152064, 0xb19d5077 +0, 116, 116, 1, 152064, 0xa98576b9 +0, 117, 117, 1, 152064, 0x65324239 +0, 118, 118, 1, 152064, 0x709e4031 +0, 119, 119, 1, 152064, 0xf8e81681 +0, 120, 120, 1, 152064, 0x058514e5 +0, 121, 121, 1, 152064, 0xd1d1c806 +0, 122, 122, 1, 152064, 0x0e4dde57 +0, 123, 123, 1, 152064, 0x49e9c2bb +0, 124, 124, 1, 152064, 0x01417ce6 +0, 125, 125, 1, 152064, 0xda7ebbf1 +0, 126, 126, 1, 152064, 0xa22906b7 +0, 127, 127, 1, 152064, 0x32e2df87 +0, 128, 128, 1, 152064, 0x69917c8f +0, 129, 129, 1, 152064, 0xea8ed2cc +0, 130, 130, 1, 152064, 0x0b8d57f1 +0, 131, 131, 1, 152064, 0x5f683bcd +0, 132, 132, 1, 152064, 0x5162fe2f +0, 133, 133, 1, 152064, 0x49c052f8 +0, 134, 134, 1, 152064, 0x990b69ba +0, 135, 135, 1, 152064, 0xa6d4f99f +0, 136, 136, 1, 152064, 0xe79ef4da +0, 137, 137, 1, 152064, 0x5e8a3847 +0, 138, 138, 1, 152064, 0x38b1e75f +0, 139, 139, 1, 152064, 0xf5c91bed +0, 140, 140, 1, 152064, 0xd59a6d26 +0, 141, 141, 1, 152064, 0xc361de06 +0, 142, 142, 1, 152064, 0x63ed2229 +0, 143, 143, 1, 152064, 0xb8229205 +0, 144, 144, 1, 152064, 0x7c6619af +0, 145, 145, 1, 152064, 0x4126b02f +0, 146, 146, 1, 152064, 0x9250b99b +0, 147, 147, 1, 152064, 0x589778f9 +0, 148, 148, 1, 152064, 0xed1fa45b +0, 149, 149, 1, 152064, 0x700b6f32 +0, 150, 150, 1, 152064, 0x0590df55 +0, 151, 151, 1, 152064, 0x3e9c4018 +0, 152, 152, 1, 152064, 0x957b8860 +0, 153, 153, 1, 152064, 0x56161560 +0, 154, 154, 1, 152064, 0xbc43bc3b +0, 155, 155, 1, 152064, 0x508d8632 +0, 156, 156, 1, 152064, 0xbc5736d8 +0, 157, 157, 1, 152064, 0xed7d3aef +0, 158, 158, 1, 152064, 0x1dcdda9f +0, 159, 159, 1, 152064, 0x8ef6d5c9 +0, 160, 160, 1, 152064, 0x15466acc +0, 161, 161, 1, 152064, 0x45d4cf67 +0, 162, 162, 1, 152064, 0x8c900b9d +0, 163, 163, 1, 152064, 0x747006e0 +0, 164, 164, 1, 152064, 0xac920a0c +0, 165, 165, 1, 152064, 0xb8210c27 +0, 166, 166, 1, 152064, 0x7dbb873a +0, 167, 167, 1, 152064, 0x0d4d7584 +0, 168, 168, 1, 152064, 0xefb3fe60 +0, 169, 169, 1, 152064, 0x905e2644 +0, 170, 170, 1, 152064, 0x7c04e534 +0, 171, 171, 1, 152064, 0x8889972a +0, 172, 172, 1, 152064, 0x21c7d8ad +0, 173, 173, 1, 152064, 0x1c641176 +0, 174, 174, 1, 152064, 0xf71489a4 +0, 175, 175, 1, 152064, 0xd7ac5555 +0, 176, 176, 1, 152064, 0xb4609c6d +0, 177, 177, 1, 152064, 0xf5b2bd5e +0, 178, 178, 1, 152064, 0x9f43ce57 +0, 179, 179, 1, 152064, 0x77642dd3 +0, 180, 180, 1, 152064, 0x3e79565c +0, 181, 181, 1, 152064, 0x95f40b8e +0, 182, 182, 1, 152064, 0x3c8ca4d4 +0, 183, 183, 1, 152064, 0xa02ac497 +0, 184, 184, 1, 152064, 0x4c93b377 +0, 185, 185, 1, 152064, 0x55f5ac68 +0, 186, 186, 1, 152064, 0xf8652eca +0, 187, 187, 1, 152064, 0x56e94574 +0, 188, 188, 1, 152064, 0x6d8302e1 +0, 189, 189, 1, 152064, 0x29a57061 +0, 190, 190, 1, 152064, 0x24e4cfdc +0, 191, 191, 1, 152064, 0xf5a5d62a +0, 192, 192, 1, 152064, 0x998870c1 +0, 193, 193, 1, 152064, 0xa15b1f4e +0, 194, 194, 1, 152064, 0xb0ccb51f +0, 195, 195, 1, 152064, 0xeaaf59ab +0, 196, 196, 1, 152064, 0x7e2b4fe6 +0, 197, 197, 1, 152064, 0x72299fea +0, 198, 198, 1, 152064, 0x769da8b2 +0, 199, 199, 1, 152064, 0xefad7ef8 +0, 200, 200, 1, 152064, 0x24819983 +0, 201, 201, 1, 152064, 0x2aad32ab +0, 202, 202, 1, 152064, 0xc80cac79 +0, 203, 203, 1, 152064, 0x1659d628 +0, 204, 204, 1, 152064, 0xef941f66 +0, 205, 205, 1, 152064, 0x0d7fcdb5 +0, 206, 206, 1, 152064, 0x7c1853fa +0, 207, 207, 1, 152064, 0xb94c4d3c +0, 208, 208, 1, 152064, 0xc47adfc2 +0, 209, 209, 1, 152064, 0x366a6729 +0, 210, 210, 1, 152064, 0x7eb37b70 +0, 211, 211, 1, 152064, 0xafd54c27 +0, 212, 212, 1, 152064, 0x67b18636 +0, 213, 213, 1, 152064, 0x93b22dcf +0, 214, 214, 1, 152064, 0xa64991f1 +0, 215, 215, 1, 152064, 0xd32a7102 +0, 216, 216, 1, 152064, 0xff665d1c +0, 217, 217, 1, 152064, 0xf107cc31 +0, 218, 218, 1, 152064, 0xf5b25652 +0, 219, 219, 1, 152064, 0x8caf783d +0, 220, 220, 1, 152064, 0x72f3eb00 +0, 221, 221, 1, 152064, 0xb5aea5f8 +0, 222, 222, 1, 152064, 0xee70e870 +0, 223, 223, 1, 152064, 0x7c3a0156 +0, 224, 224, 1, 152064, 0x871b6383 +0, 225, 225, 1, 152064, 0x48d831ff +0, 226, 226, 1, 152064, 0xca233913 +0, 227, 227, 1, 152064, 0xe14bc5eb +0, 228, 228, 1, 152064, 0x9b1d27e7 +0, 229, 229, 1, 152064, 0xfb9637f7 +0, 230, 230, 1, 152064, 0x0c022157 +0, 231, 231, 1, 152064, 0x16d35fc9 +0, 232, 232, 1, 152064, 0x6d935f71 +0, 233, 233, 1, 152064, 0xae4066fa +0, 234, 234, 1, 152064, 0xcef94fdc +0, 235, 235, 1, 152064, 0xc234edb9 +0, 236, 236, 1, 152064, 0x26a4f2e2 +0, 237, 237, 1, 152064, 0xd29ac23e +0, 238, 238, 1, 152064, 0xb7604395 +0, 239, 239, 1, 152064, 0x408084f6 +0, 240, 240, 1, 152064, 0x0a02026c +0, 241, 241, 1, 152064, 0x78b33c7c +0, 242, 242, 1, 152064, 0xcb02b874 +0, 243, 243, 1, 152064, 0xf566513b +0, 244, 244, 1, 152064, 0xb34e52b1 +0, 245, 245, 1, 152064, 0xf55ff493 +0, 246, 246, 1, 152064, 0xb0e8282a +0, 247, 247, 1, 152064, 0xe9510bbe +0, 248, 248, 1, 152064, 0x292e8c5a +0, 249, 249, 1, 152064, 0x62b9d2b0 +0, 250, 250, 1, 152064, 0x3a8cc827 +0, 251, 251, 1, 152064, 0x25cc465e +0, 252, 252, 1, 152064, 0xf2bc32e2 +0, 253, 253, 1, 152064, 0x6141f914 +0, 254, 254, 1, 152064, 0x1171256f +0, 255, 255, 1, 152064, 0x13cb2ded +0, 256, 256, 1, 152064, 0x3d4ca557 +0, 257, 257, 1, 152064, 0xf2b9e72e +0, 258, 258, 1, 152064, 0x03f7547a +0, 259, 259, 1, 152064, 0xc7302955 +0, 260, 260, 1, 152064, 0xe78a46d3 +0, 261, 261, 1, 152064, 0x3726a270 +0, 262, 262, 1, 152064, 0x2f65722a +0, 263, 263, 1, 152064, 0x55acce40 +0, 264, 264, 1, 152064, 0xf6fa9db2 +0, 265, 265, 1, 152064, 0x70a36937 +0, 266, 266, 1, 152064, 0x9313742d +0, 267, 267, 1, 152064, 0x2eb14e53 +0, 268, 268, 1, 152064, 0x3d47c9c3 +0, 269, 269, 1, 152064, 0xd0a90348 +0, 270, 270, 1, 152064, 0x6ad48088 +0, 271, 271, 1, 152064, 0x68e64738 +0, 272, 272, 1, 152064, 0x04c3735a +0, 273, 273, 1, 152064, 0x51d0593f +0, 274, 274, 1, 152064, 0x42cf2b48 +0, 275, 275, 1, 152064, 0xa5496a0c +0, 276, 276, 1, 152064, 0x84c25549 +0, 277, 277, 1, 152064, 0x96691600 +0, 278, 278, 1, 152064, 0x423135db +0, 279, 279, 1, 152064, 0x8d2e08b6 +0, 280, 280, 1, 152064, 0xaeb4c840 +0, 281, 281, 1, 152064, 0xf3e71780 +0, 282, 282, 1, 152064, 0x8858228b +0, 283, 283, 1, 152064, 0xf28613f8 +0, 284, 284, 1, 152064, 0xb5327882 +0, 285, 285, 1, 152064, 0xbb60bb85 +0, 286, 286, 1, 152064, 0x345ab1c9 +0, 287, 287, 1, 152064, 0x8aac2cba +0, 288, 288, 1, 152064, 0x7ce15b4c +0, 289, 289, 1, 152064, 0xc09c55c0 +0, 290, 290, 1, 152064, 0x8482ddd6 +0, 291, 291, 1, 152064, 0xab222a13 +0, 292, 292, 1, 152064, 0xd39b0dea +0, 293, 293, 1, 152064, 0x6dab6e06 +0, 294, 294, 1, 152064, 0xec0891bd +0, 295, 295, 1, 152064, 0x88bd9701 +0, 296, 296, 1, 152064, 0xdf13072a +0, 297, 297, 1, 152064, 0x23b33081 +0, 298, 298, 1, 152064, 0x63943137 +0, 299, 299, 1, 152064, 0xab6a9052 +0, 300, 300, 1, 152064, 0x05485494 diff --git a/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c b/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c index 9958f1616..d6c41dd64 100644 --- a/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c +++ b/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c @@ -3,303 +3,303 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x3e39c08b -0, 1, 1, 1, 152064, 0xabc67990 -0, 2, 2, 1, 152064, 0x19614e74 -0, 3, 3, 1, 152064, 0xa3776beb -0, 4, 4, 1, 152064, 0xcce6ffdf -0, 5, 5, 1, 152064, 0xb0e94746 -0, 6, 6, 1, 152064, 0xdb1a84ef -0, 7, 7, 1, 152064, 0xb2624509 -0, 8, 8, 1, 152064, 0x32e2d826 -0, 9, 9, 1, 152064, 0xb3bddf0b -0, 10, 10, 1, 152064, 0x2e273ce3 -0, 11, 11, 1, 152064, 0x67af7e4d -0, 12, 12, 1, 152064, 0x505c3261 -0, 13, 13, 1, 152064, 0xa43d015e -0, 14, 14, 1, 152064, 0xad41c1f6 -0, 15, 15, 1, 152064, 0x633ba55f -0, 16, 16, 1, 152064, 0xe80634f0 -0, 17, 17, 1, 152064, 0x80a07dc9 -0, 18, 18, 1, 152064, 0x0e7a3bbf -0, 19, 19, 1, 152064, 0xcb099196 -0, 20, 20, 1, 152064, 0x57c96db5 -0, 21, 21, 1, 152064, 0xccd422fa -0, 22, 22, 1, 152064, 0x0850b7a7 -0, 23, 23, 1, 152064, 0x30e33156 -0, 24, 24, 1, 152064, 0x34e13f9a -0, 25, 25, 1, 152064, 0x03d36000 -0, 26, 26, 1, 152064, 0xbf7d49da -0, 27, 27, 1, 152064, 0x77336d09 -0, 28, 28, 1, 152064, 0xca8be5a9 -0, 29, 29, 1, 152064, 0xe57c0b08 -0, 30, 30, 1, 152064, 0xbe77c093 -0, 31, 31, 1, 152064, 0x6bf1ff05 -0, 32, 32, 1, 152064, 0x9142babf -0, 33, 33, 1, 152064, 0x08db8e67 -0, 34, 34, 1, 152064, 0x69ac8cb6 -0, 35, 35, 1, 152064, 0xaa3b5c88 -0, 36, 36, 1, 152064, 0x9bd32638 -0, 37, 37, 1, 152064, 0x7972115a -0, 38, 38, 1, 152064, 0x5c1dd47b -0, 39, 39, 1, 152064, 0x8a196e02 -0, 40, 40, 1, 152064, 0xa89672bc -0, 41, 41, 1, 152064, 0x27b220e4 -0, 42, 42, 1, 152064, 0xfa38dc4a -0, 43, 43, 1, 152064, 0x4784c639 -0, 44, 44, 1, 152064, 0xa5e4229a -0, 45, 45, 1, 152064, 0xa986bdfc -0, 46, 46, 1, 152064, 0x2951b47b -0, 47, 47, 1, 152064, 0x4df404a6 -0, 48, 48, 1, 152064, 0xc75155e8 -0, 49, 49, 1, 152064, 0xfc05248c -0, 50, 50, 1, 152064, 0x5d53da10 -0, 51, 51, 1, 152064, 0x284376ec -0, 52, 52, 1, 152064, 0x19fce380 -0, 53, 53, 1, 152064, 0x876be6c9 -0, 54, 54, 1, 152064, 0x39eb8ff9 -0, 55, 55, 1, 152064, 0x289c9543 -0, 56, 56, 1, 152064, 0x24dd2356 -0, 57, 57, 1, 152064, 0x1dc17d3c -0, 58, 58, 1, 152064, 0xd17c00ac -0, 59, 59, 1, 152064, 0xc2ad54de -0, 60, 60, 1, 152064, 0xbe11ee2f -0, 61, 61, 1, 152064, 0x3db9dc89 -0, 62, 62, 1, 152064, 0xac0d7bc2 -0, 63, 63, 1, 152064, 0x8dab2dde -0, 64, 64, 1, 152064, 0x566ad225 -0, 65, 65, 1, 152064, 0x587c7853 -0, 66, 66, 1, 152064, 0x601c9c80 -0, 67, 67, 1, 152064, 0x2afaf751 -0, 68, 68, 1, 152064, 0x1c9f7e3a -0, 69, 69, 1, 152064, 0x899475bf -0, 70, 70, 1, 152064, 0x0d65c7d9 -0, 71, 71, 1, 152064, 0xafd63d12 -0, 72, 72, 1, 152064, 0x162e62b9 -0, 73, 73, 1, 152064, 0x5c9554be -0, 74, 74, 1, 152064, 0x35fbdaa2 -0, 75, 75, 1, 152064, 0x6438cbd8 -0, 76, 76, 1, 152064, 0xde0772c9 -0, 77, 77, 1, 152064, 0x79f82854 -0, 78, 78, 1, 152064, 0x86957840 -0, 79, 79, 1, 152064, 0xd9468cbf -0, 80, 80, 1, 152064, 0x23e74609 -0, 81, 81, 1, 152064, 0x3919a146 -0, 82, 82, 1, 152064, 0xd641078b -0, 83, 83, 1, 152064, 0x24397220 -0, 84, 84, 1, 152064, 0xe7fc3a7c -0, 85, 85, 1, 152064, 0x3997154a -0, 86, 86, 1, 152064, 0x2af3952c -0, 87, 87, 1, 152064, 0x274ac07a -0, 88, 88, 1, 152064, 0x288f7b09 -0, 89, 89, 1, 152064, 0xe6f9b022 -0, 90, 90, 1, 152064, 0xf09e2fbb -0, 91, 91, 1, 152064, 0x7244e477 -0, 92, 92, 1, 152064, 0x0dfc72eb -0, 93, 93, 1, 152064, 0x0322b21f -0, 94, 94, 1, 152064, 0x18b08205 -0, 95, 95, 1, 152064, 0x6606153e -0, 96, 96, 1, 152064, 0x85186272 -0, 97, 97, 1, 152064, 0x3369f064 -0, 98, 98, 1, 152064, 0xbe0d5a44 -0, 99, 99, 1, 152064, 0x320258bb -0, 100, 100, 1, 152064, 0x4d6fb091 -0, 101, 101, 1, 152064, 0xc9bbf5e7 -0, 102, 102, 1, 152064, 0x0aa1b69b -0, 103, 103, 1, 152064, 0x85b9ac11 -0, 104, 104, 1, 152064, 0xb25ff818 -0, 105, 105, 1, 152064, 0xa155dc25 -0, 106, 106, 1, 152064, 0xa8e03bfd -0, 107, 107, 1, 152064, 0x0a862956 -0, 108, 108, 1, 152064, 0x11b49264 -0, 109, 109, 1, 152064, 0xa94e664e -0, 110, 110, 1, 152064, 0x330e0fa2 -0, 111, 111, 1, 152064, 0xaf3d9518 -0, 112, 112, 1, 152064, 0x0836f2e8 -0, 113, 113, 1, 152064, 0xbf6dc578 -0, 114, 114, 1, 152064, 0x7b524d20 -0, 115, 115, 1, 152064, 0x9ef7677f -0, 116, 116, 1, 152064, 0xeacf3f34 -0, 117, 117, 1, 152064, 0xfb4e3dbe -0, 118, 118, 1, 152064, 0xb46e25cb -0, 119, 119, 1, 152064, 0x363c1603 -0, 120, 120, 1, 152064, 0x263fc542 -0, 121, 121, 1, 152064, 0xf106e548 -0, 122, 122, 1, 152064, 0xde43c56a -0, 123, 123, 1, 152064, 0xc2c4770a -0, 124, 124, 1, 152064, 0x122fce19 -0, 125, 125, 1, 152064, 0x3ba01434 -0, 126, 126, 1, 152064, 0x0e8ce5ee -0, 127, 127, 1, 152064, 0x6ceb82e1 -0, 128, 128, 1, 152064, 0xa23ee21c -0, 129, 129, 1, 152064, 0xc6d960f9 -0, 130, 130, 1, 152064, 0x0de15258 -0, 131, 131, 1, 152064, 0x187b0333 -0, 132, 132, 1, 152064, 0x92e6582f -0, 133, 133, 1, 152064, 0xb9586ce0 -0, 134, 134, 1, 152064, 0xefd803b5 -0, 135, 135, 1, 152064, 0x24eafb29 -0, 136, 136, 1, 152064, 0x20c73b14 -0, 137, 137, 1, 152064, 0xbd7ceaaa -0, 138, 138, 1, 152064, 0x775216c8 -0, 139, 139, 1, 152064, 0xa08971c7 -0, 140, 140, 1, 152064, 0xef0ee865 -0, 141, 141, 1, 152064, 0x9ac61c2f -0, 142, 142, 1, 152064, 0x52ae8ea9 -0, 143, 143, 1, 152064, 0x06571c14 -0, 144, 144, 1, 152064, 0x6e78ad33 -0, 145, 145, 1, 152064, 0xad01c627 -0, 146, 146, 1, 152064, 0xbfe074d3 -0, 147, 147, 1, 152064, 0x9357a183 -0, 148, 148, 1, 152064, 0x8de7767f -0, 149, 149, 1, 152064, 0xa5e6e76e -0, 150, 150, 1, 152064, 0xa6f646fe -0, 151, 151, 1, 152064, 0x132e99f8 -0, 152, 152, 1, 152064, 0xb79f27de -0, 153, 153, 1, 152064, 0x36d3cdcf -0, 154, 154, 1, 152064, 0xdc938336 -0, 155, 155, 1, 152064, 0xacaa3a7f -0, 156, 156, 1, 152064, 0xc61a37fd -0, 157, 157, 1, 152064, 0x4fe1ddf0 -0, 158, 158, 1, 152064, 0xc0f7d660 -0, 159, 159, 1, 152064, 0xd72458ea -0, 160, 160, 1, 152064, 0x6978d123 -0, 161, 161, 1, 152064, 0x64e60ccf -0, 162, 162, 1, 152064, 0xaa07004c -0, 163, 163, 1, 152064, 0x07cd1064 -0, 164, 164, 1, 152064, 0xa82320e5 -0, 165, 165, 1, 152064, 0xaedd8d30 -0, 166, 166, 1, 152064, 0x79b082ea -0, 167, 167, 1, 152064, 0x9ed800ab -0, 168, 168, 1, 152064, 0xde592bb4 -0, 169, 169, 1, 152064, 0xd966df88 -0, 170, 170, 1, 152064, 0xf921988a -0, 171, 171, 1, 152064, 0x557ad9ae -0, 172, 172, 1, 152064, 0xc3f31a9a -0, 173, 173, 1, 152064, 0x65248561 -0, 174, 174, 1, 152064, 0x63df4aa6 -0, 175, 175, 1, 152064, 0x618da0a9 -0, 176, 176, 1, 152064, 0xe6f1c435 -0, 177, 177, 1, 152064, 0x9f90c38f -0, 178, 178, 1, 152064, 0xd2853e14 -0, 179, 179, 1, 152064, 0x6e0268a9 -0, 180, 180, 1, 152064, 0x393712d1 -0, 181, 181, 1, 152064, 0x470da25f -0, 182, 182, 1, 152064, 0xaf55cb3d -0, 183, 183, 1, 152064, 0x6935b8b9 -0, 184, 184, 1, 152064, 0x5409a15f -0, 185, 185, 1, 152064, 0x09073fee -0, 186, 186, 1, 152064, 0xfb274e82 -0, 187, 187, 1, 152064, 0x1a770581 -0, 188, 188, 1, 152064, 0x17277d0d -0, 189, 189, 1, 152064, 0xd4dcd982 -0, 190, 190, 1, 152064, 0x6b04eaf3 -0, 191, 191, 1, 152064, 0x8a3d822e -0, 192, 192, 1, 152064, 0x1b971ec9 -0, 193, 193, 1, 152064, 0x14e0c0f6 -0, 194, 194, 1, 152064, 0x00667450 -0, 195, 195, 1, 152064, 0xd2385902 -0, 196, 196, 1, 152064, 0x905da6ab -0, 197, 197, 1, 152064, 0xa3ffb18b -0, 198, 198, 1, 152064, 0x10d48b19 -0, 199, 199, 1, 152064, 0xb2c7a3bd -0, 200, 200, 1, 152064, 0x45593e96 -0, 201, 201, 1, 152064, 0x47a0b60c -0, 202, 202, 1, 152064, 0x68c6d1b9 -0, 203, 203, 1, 152064, 0xbc881fcc -0, 204, 204, 1, 152064, 0x422cc6f2 -0, 205, 205, 1, 152064, 0x9b686410 -0, 206, 206, 1, 152064, 0x35dc5e86 -0, 207, 207, 1, 152064, 0x247bedaa -0, 208, 208, 1, 152064, 0x22b76fd1 -0, 209, 209, 1, 152064, 0x67cc7a75 -0, 210, 210, 1, 152064, 0xa197521e -0, 211, 211, 1, 152064, 0x428c8662 -0, 212, 212, 1, 152064, 0x33dc2c73 -0, 213, 213, 1, 152064, 0x5b538903 -0, 214, 214, 1, 152064, 0x3c4176b6 -0, 215, 215, 1, 152064, 0x774364ba -0, 216, 216, 1, 152064, 0xf237d03e -0, 217, 217, 1, 152064, 0xac8746fb -0, 218, 218, 1, 152064, 0x6b306a84 -0, 219, 219, 1, 152064, 0xa2ace513 -0, 220, 220, 1, 152064, 0x709c9be7 -0, 221, 221, 1, 152064, 0x2403f373 -0, 222, 222, 1, 152064, 0x147bf717 -0, 223, 223, 1, 152064, 0xe58964c8 -0, 224, 224, 1, 152064, 0xa0da36fc -0, 225, 225, 1, 152064, 0x1ac1355c -0, 226, 226, 1, 152064, 0x8a31c9f2 -0, 227, 227, 1, 152064, 0x42ba205c -0, 228, 228, 1, 152064, 0xa11b3575 -0, 229, 229, 1, 152064, 0xcb35207c -0, 230, 230, 1, 152064, 0x528f6189 -0, 231, 231, 1, 152064, 0x34f05bd7 -0, 232, 232, 1, 152064, 0x72317356 -0, 233, 233, 1, 152064, 0xaabd5028 -0, 234, 234, 1, 152064, 0x13dbeb7b -0, 235, 235, 1, 152064, 0x62f1e8a8 -0, 236, 236, 1, 152064, 0x1723bfcd -0, 237, 237, 1, 152064, 0x5c083c00 -0, 238, 238, 1, 152064, 0x52137894 -0, 239, 239, 1, 152064, 0xef1e082c -0, 240, 240, 1, 152064, 0x664b3d53 -0, 241, 241, 1, 152064, 0x2eb9b296 -0, 242, 242, 1, 152064, 0xd0ca511e -0, 243, 243, 1, 152064, 0x012d4724 -0, 244, 244, 1, 152064, 0xa847f5af -0, 245, 245, 1, 152064, 0x483a2fde -0, 246, 246, 1, 152064, 0xd1ab0257 -0, 247, 247, 1, 152064, 0x414692c7 -0, 248, 248, 1, 152064, 0x0b79df88 -0, 249, 249, 1, 152064, 0xdaa2c4a3 -0, 250, 250, 1, 152064, 0xd1b44500 -0, 251, 251, 1, 152064, 0xfd3d2cf3 -0, 252, 252, 1, 152064, 0xfdc0f748 -0, 253, 253, 1, 152064, 0xce762a2a -0, 254, 254, 1, 152064, 0x08b63572 -0, 255, 255, 1, 152064, 0x5a46a38d -0, 256, 256, 1, 152064, 0x03cee9c0 -0, 257, 257, 1, 152064, 0x9ee45473 -0, 258, 258, 1, 152064, 0x5a432386 -0, 259, 259, 1, 152064, 0x54c83d87 -0, 260, 260, 1, 152064, 0xc9caa1de -0, 261, 261, 1, 152064, 0xa28367f1 -0, 262, 262, 1, 152064, 0x2607cdf1 -0, 263, 263, 1, 152064, 0x06baa8de -0, 264, 264, 1, 152064, 0xf5346e32 -0, 265, 265, 1, 152064, 0x6d3e732b -0, 266, 266, 1, 152064, 0x798c584b -0, 267, 267, 1, 152064, 0x4076c948 -0, 268, 268, 1, 152064, 0x868cf63a -0, 269, 269, 1, 152064, 0x23107ac5 -0, 270, 270, 1, 152064, 0x306f3fe2 -0, 271, 271, 1, 152064, 0xbd1d71d6 -0, 272, 272, 1, 152064, 0x1429545f -0, 273, 273, 1, 152064, 0xaded29aa -0, 274, 274, 1, 152064, 0x9b455a94 -0, 275, 275, 1, 152064, 0xb3774ce7 -0, 276, 276, 1, 152064, 0x92580986 -0, 277, 277, 1, 152064, 0x0eae2f95 -0, 278, 278, 1, 152064, 0x599208b2 -0, 279, 279, 1, 152064, 0x4804c04c -0, 280, 280, 1, 152064, 0x5f730e8f -0, 281, 281, 1, 152064, 0x3e501d1e -0, 282, 282, 1, 152064, 0x32100740 -0, 283, 283, 1, 152064, 0x62226ff8 -0, 284, 284, 1, 152064, 0x7683b622 -0, 285, 285, 1, 152064, 0xc3e0aec1 -0, 286, 286, 1, 152064, 0xfac12608 -0, 287, 287, 1, 152064, 0xb21a5781 -0, 288, 288, 1, 152064, 0x8f1e4964 -0, 289, 289, 1, 152064, 0x0f62dd6e -0, 290, 290, 1, 152064, 0xac062ac4 -0, 291, 291, 1, 152064, 0x1b320f7a -0, 292, 292, 1, 152064, 0x346e7211 -0, 293, 293, 1, 152064, 0xe47592f3 -0, 294, 294, 1, 152064, 0xa3a7919c -0, 295, 295, 1, 152064, 0xa3580fa6 -0, 296, 296, 1, 152064, 0xc73430c1 -0, 297, 297, 1, 152064, 0x994a2c18 -0, 298, 298, 1, 152064, 0x0b5d8d45 -0, 299, 299, 1, 152064, 0x9eed5109 +0, 1, 1, 1, 152064, 0x3e39c08b +0, 2, 2, 1, 152064, 0xabc67990 +0, 3, 3, 1, 152064, 0x19614e74 +0, 4, 4, 1, 152064, 0xa3776beb +0, 5, 5, 1, 152064, 0xcce6ffdf +0, 6, 6, 1, 152064, 0xb0e94746 +0, 7, 7, 1, 152064, 0xdb1a84ef +0, 8, 8, 1, 152064, 0xb2624509 +0, 9, 9, 1, 152064, 0x32e2d826 +0, 10, 10, 1, 152064, 0xb3bddf0b +0, 11, 11, 1, 152064, 0x2e273ce3 +0, 12, 12, 1, 152064, 0x67af7e4d +0, 13, 13, 1, 152064, 0x505c3261 +0, 14, 14, 1, 152064, 0xa43d015e +0, 15, 15, 1, 152064, 0xad41c1f6 +0, 16, 16, 1, 152064, 0x633ba55f +0, 17, 17, 1, 152064, 0xe80634f0 +0, 18, 18, 1, 152064, 0x80a07dc9 +0, 19, 19, 1, 152064, 0x0e7a3bbf +0, 20, 20, 1, 152064, 0xcb099196 +0, 21, 21, 1, 152064, 0x57c96db5 +0, 22, 22, 1, 152064, 0xccd422fa +0, 23, 23, 1, 152064, 0x0850b7a7 +0, 24, 24, 1, 152064, 0x30e33156 +0, 25, 25, 1, 152064, 0x34e13f9a +0, 26, 26, 1, 152064, 0x03d36000 +0, 27, 27, 1, 152064, 0xbf7d49da +0, 28, 28, 1, 152064, 0x77336d09 +0, 29, 29, 1, 152064, 0xca8be5a9 +0, 30, 30, 1, 152064, 0xe57c0b08 +0, 31, 31, 1, 152064, 0xbe77c093 +0, 32, 32, 1, 152064, 0x6bf1ff05 +0, 33, 33, 1, 152064, 0x9142babf +0, 34, 34, 1, 152064, 0x08db8e67 +0, 35, 35, 1, 152064, 0x69ac8cb6 +0, 36, 36, 1, 152064, 0xaa3b5c88 +0, 37, 37, 1, 152064, 0x9bd32638 +0, 38, 38, 1, 152064, 0x7972115a +0, 39, 39, 1, 152064, 0x5c1dd47b +0, 40, 40, 1, 152064, 0x8a196e02 +0, 41, 41, 1, 152064, 0xa89672bc +0, 42, 42, 1, 152064, 0x27b220e4 +0, 43, 43, 1, 152064, 0xfa38dc4a +0, 44, 44, 1, 152064, 0x4784c639 +0, 45, 45, 1, 152064, 0xa5e4229a +0, 46, 46, 1, 152064, 0xa986bdfc +0, 47, 47, 1, 152064, 0x2951b47b +0, 48, 48, 1, 152064, 0x4df404a6 +0, 49, 49, 1, 152064, 0xc75155e8 +0, 50, 50, 1, 152064, 0xfc05248c +0, 51, 51, 1, 152064, 0x5d53da10 +0, 52, 52, 1, 152064, 0x284376ec +0, 53, 53, 1, 152064, 0x19fce380 +0, 54, 54, 1, 152064, 0x876be6c9 +0, 55, 55, 1, 152064, 0x39eb8ff9 +0, 56, 56, 1, 152064, 0x289c9543 +0, 57, 57, 1, 152064, 0x24dd2356 +0, 58, 58, 1, 152064, 0x1dc17d3c +0, 59, 59, 1, 152064, 0xd17c00ac +0, 60, 60, 1, 152064, 0xc2ad54de +0, 61, 61, 1, 152064, 0xbe11ee2f +0, 62, 62, 1, 152064, 0x3db9dc89 +0, 63, 63, 1, 152064, 0xac0d7bc2 +0, 64, 64, 1, 152064, 0x8dab2dde +0, 65, 65, 1, 152064, 0x566ad225 +0, 66, 66, 1, 152064, 0x587c7853 +0, 67, 67, 1, 152064, 0x601c9c80 +0, 68, 68, 1, 152064, 0x2afaf751 +0, 69, 69, 1, 152064, 0x1c9f7e3a +0, 70, 70, 1, 152064, 0x899475bf +0, 71, 71, 1, 152064, 0x0d65c7d9 +0, 72, 72, 1, 152064, 0xafd63d12 +0, 73, 73, 1, 152064, 0x162e62b9 +0, 74, 74, 1, 152064, 0x5c9554be +0, 75, 75, 1, 152064, 0x35fbdaa2 +0, 76, 76, 1, 152064, 0x6438cbd8 +0, 77, 77, 1, 152064, 0xde0772c9 +0, 78, 78, 1, 152064, 0x79f82854 +0, 79, 79, 1, 152064, 0x86957840 +0, 80, 80, 1, 152064, 0xd9468cbf +0, 81, 81, 1, 152064, 0x23e74609 +0, 82, 82, 1, 152064, 0x3919a146 +0, 83, 83, 1, 152064, 0xd641078b +0, 84, 84, 1, 152064, 0x24397220 +0, 85, 85, 1, 152064, 0xe7fc3a7c +0, 86, 86, 1, 152064, 0x3997154a +0, 87, 87, 1, 152064, 0x2af3952c +0, 88, 88, 1, 152064, 0x274ac07a +0, 89, 89, 1, 152064, 0x288f7b09 +0, 90, 90, 1, 152064, 0xe6f9b022 +0, 91, 91, 1, 152064, 0xf09e2fbb +0, 92, 92, 1, 152064, 0x7244e477 +0, 93, 93, 1, 152064, 0x0dfc72eb +0, 94, 94, 1, 152064, 0x0322b21f +0, 95, 95, 1, 152064, 0x18b08205 +0, 96, 96, 1, 152064, 0x6606153e +0, 97, 97, 1, 152064, 0x85186272 +0, 98, 98, 1, 152064, 0x3369f064 +0, 99, 99, 1, 152064, 0xbe0d5a44 +0, 100, 100, 1, 152064, 0x320258bb +0, 101, 101, 1, 152064, 0x4d6fb091 +0, 102, 102, 1, 152064, 0xc9bbf5e7 +0, 103, 103, 1, 152064, 0x0aa1b69b +0, 104, 104, 1, 152064, 0x85b9ac11 +0, 105, 105, 1, 152064, 0xb25ff818 +0, 106, 106, 1, 152064, 0xa155dc25 +0, 107, 107, 1, 152064, 0xa8e03bfd +0, 108, 108, 1, 152064, 0x0a862956 +0, 109, 109, 1, 152064, 0x11b49264 +0, 110, 110, 1, 152064, 0xa94e664e +0, 111, 111, 1, 152064, 0x330e0fa2 +0, 112, 112, 1, 152064, 0xaf3d9518 +0, 113, 113, 1, 152064, 0x0836f2e8 +0, 114, 114, 1, 152064, 0xbf6dc578 +0, 115, 115, 1, 152064, 0x7b524d20 +0, 116, 116, 1, 152064, 0x9ef7677f +0, 117, 117, 1, 152064, 0xeacf3f34 +0, 118, 118, 1, 152064, 0xfb4e3dbe +0, 119, 119, 1, 152064, 0xb46e25cb +0, 120, 120, 1, 152064, 0x363c1603 +0, 121, 121, 1, 152064, 0x263fc542 +0, 122, 122, 1, 152064, 0xf106e548 +0, 123, 123, 1, 152064, 0xde43c56a +0, 124, 124, 1, 152064, 0xc2c4770a +0, 125, 125, 1, 152064, 0x122fce19 +0, 126, 126, 1, 152064, 0x3ba01434 +0, 127, 127, 1, 152064, 0x0e8ce5ee +0, 128, 128, 1, 152064, 0x6ceb82e1 +0, 129, 129, 1, 152064, 0xa23ee21c +0, 130, 130, 1, 152064, 0xc6d960f9 +0, 131, 131, 1, 152064, 0x0de15258 +0, 132, 132, 1, 152064, 0x187b0333 +0, 133, 133, 1, 152064, 0x92e6582f +0, 134, 134, 1, 152064, 0xb9586ce0 +0, 135, 135, 1, 152064, 0xefd803b5 +0, 136, 136, 1, 152064, 0x24eafb29 +0, 137, 137, 1, 152064, 0x20c73b14 +0, 138, 138, 1, 152064, 0xbd7ceaaa +0, 139, 139, 1, 152064, 0x775216c8 +0, 140, 140, 1, 152064, 0xa08971c7 +0, 141, 141, 1, 152064, 0xef0ee865 +0, 142, 142, 1, 152064, 0x9ac61c2f +0, 143, 143, 1, 152064, 0x52ae8ea9 +0, 144, 144, 1, 152064, 0x06571c14 +0, 145, 145, 1, 152064, 0x6e78ad33 +0, 146, 146, 1, 152064, 0xad01c627 +0, 147, 147, 1, 152064, 0xbfe074d3 +0, 148, 148, 1, 152064, 0x9357a183 +0, 149, 149, 1, 152064, 0x8de7767f +0, 150, 150, 1, 152064, 0xa5e6e76e +0, 151, 151, 1, 152064, 0xa6f646fe +0, 152, 152, 1, 152064, 0x132e99f8 +0, 153, 153, 1, 152064, 0xb79f27de +0, 154, 154, 1, 152064, 0x36d3cdcf +0, 155, 155, 1, 152064, 0xdc938336 +0, 156, 156, 1, 152064, 0xacaa3a7f +0, 157, 157, 1, 152064, 0xc61a37fd +0, 158, 158, 1, 152064, 0x4fe1ddf0 +0, 159, 159, 1, 152064, 0xc0f7d660 +0, 160, 160, 1, 152064, 0xd72458ea +0, 161, 161, 1, 152064, 0x6978d123 +0, 162, 162, 1, 152064, 0x64e60ccf +0, 163, 163, 1, 152064, 0xaa07004c +0, 164, 164, 1, 152064, 0x07cd1064 +0, 165, 165, 1, 152064, 0xa82320e5 +0, 166, 166, 1, 152064, 0xaedd8d30 +0, 167, 167, 1, 152064, 0x79b082ea +0, 168, 168, 1, 152064, 0x9ed800ab +0, 169, 169, 1, 152064, 0xde592bb4 +0, 170, 170, 1, 152064, 0xd966df88 +0, 171, 171, 1, 152064, 0xf921988a +0, 172, 172, 1, 152064, 0x557ad9ae +0, 173, 173, 1, 152064, 0xc3f31a9a +0, 174, 174, 1, 152064, 0x65248561 +0, 175, 175, 1, 152064, 0x63df4aa6 +0, 176, 176, 1, 152064, 0x618da0a9 +0, 177, 177, 1, 152064, 0xe6f1c435 +0, 178, 178, 1, 152064, 0x9f90c38f +0, 179, 179, 1, 152064, 0xd2853e14 +0, 180, 180, 1, 152064, 0x6e0268a9 +0, 181, 181, 1, 152064, 0x393712d1 +0, 182, 182, 1, 152064, 0x470da25f +0, 183, 183, 1, 152064, 0xaf55cb3d +0, 184, 184, 1, 152064, 0x6935b8b9 +0, 185, 185, 1, 152064, 0x5409a15f +0, 186, 186, 1, 152064, 0x09073fee +0, 187, 187, 1, 152064, 0xfb274e82 +0, 188, 188, 1, 152064, 0x1a770581 +0, 189, 189, 1, 152064, 0x17277d0d +0, 190, 190, 1, 152064, 0xd4dcd982 +0, 191, 191, 1, 152064, 0x6b04eaf3 +0, 192, 192, 1, 152064, 0x8a3d822e +0, 193, 193, 1, 152064, 0x1b971ec9 +0, 194, 194, 1, 152064, 0x14e0c0f6 +0, 195, 195, 1, 152064, 0x00667450 +0, 196, 196, 1, 152064, 0xd2385902 +0, 197, 197, 1, 152064, 0x905da6ab +0, 198, 198, 1, 152064, 0xa3ffb18b +0, 199, 199, 1, 152064, 0x10d48b19 +0, 200, 200, 1, 152064, 0xb2c7a3bd +0, 201, 201, 1, 152064, 0x45593e96 +0, 202, 202, 1, 152064, 0x47a0b60c +0, 203, 203, 1, 152064, 0x68c6d1b9 +0, 204, 204, 1, 152064, 0xbc881fcc +0, 205, 205, 1, 152064, 0x422cc6f2 +0, 206, 206, 1, 152064, 0x9b686410 +0, 207, 207, 1, 152064, 0x35dc5e86 +0, 208, 208, 1, 152064, 0x247bedaa +0, 209, 209, 1, 152064, 0x22b76fd1 +0, 210, 210, 1, 152064, 0x67cc7a75 +0, 211, 211, 1, 152064, 0xa197521e +0, 212, 212, 1, 152064, 0x428c8662 +0, 213, 213, 1, 152064, 0x33dc2c73 +0, 214, 214, 1, 152064, 0x5b538903 +0, 215, 215, 1, 152064, 0x3c4176b6 +0, 216, 216, 1, 152064, 0x774364ba +0, 217, 217, 1, 152064, 0xf237d03e +0, 218, 218, 1, 152064, 0xac8746fb +0, 219, 219, 1, 152064, 0x6b306a84 +0, 220, 220, 1, 152064, 0xa2ace513 +0, 221, 221, 1, 152064, 0x709c9be7 +0, 222, 222, 1, 152064, 0x2403f373 +0, 223, 223, 1, 152064, 0x147bf717 +0, 224, 224, 1, 152064, 0xe58964c8 +0, 225, 225, 1, 152064, 0xa0da36fc +0, 226, 226, 1, 152064, 0x1ac1355c +0, 227, 227, 1, 152064, 0x8a31c9f2 +0, 228, 228, 1, 152064, 0x42ba205c +0, 229, 229, 1, 152064, 0xa11b3575 +0, 230, 230, 1, 152064, 0xcb35207c +0, 231, 231, 1, 152064, 0x528f6189 +0, 232, 232, 1, 152064, 0x34f05bd7 +0, 233, 233, 1, 152064, 0x72317356 +0, 234, 234, 1, 152064, 0xaabd5028 +0, 235, 235, 1, 152064, 0x13dbeb7b +0, 236, 236, 1, 152064, 0x62f1e8a8 +0, 237, 237, 1, 152064, 0x1723bfcd +0, 238, 238, 1, 152064, 0x5c083c00 +0, 239, 239, 1, 152064, 0x52137894 +0, 240, 240, 1, 152064, 0xef1e082c +0, 241, 241, 1, 152064, 0x664b3d53 +0, 242, 242, 1, 152064, 0x2eb9b296 +0, 243, 243, 1, 152064, 0xd0ca511e +0, 244, 244, 1, 152064, 0x012d4724 +0, 245, 245, 1, 152064, 0xa847f5af +0, 246, 246, 1, 152064, 0x483a2fde +0, 247, 247, 1, 152064, 0xd1ab0257 +0, 248, 248, 1, 152064, 0x414692c7 +0, 249, 249, 1, 152064, 0x0b79df88 +0, 250, 250, 1, 152064, 0xdaa2c4a3 +0, 251, 251, 1, 152064, 0xd1b44500 +0, 252, 252, 1, 152064, 0xfd3d2cf3 +0, 253, 253, 1, 152064, 0xfdc0f748 +0, 254, 254, 1, 152064, 0xce762a2a +0, 255, 255, 1, 152064, 0x08b63572 +0, 256, 256, 1, 152064, 0x5a46a38d +0, 257, 257, 1, 152064, 0x03cee9c0 +0, 258, 258, 1, 152064, 0x9ee45473 +0, 259, 259, 1, 152064, 0x5a432386 +0, 260, 260, 1, 152064, 0x54c83d87 +0, 261, 261, 1, 152064, 0xc9caa1de +0, 262, 262, 1, 152064, 0xa28367f1 +0, 263, 263, 1, 152064, 0x2607cdf1 +0, 264, 264, 1, 152064, 0x06baa8de +0, 265, 265, 1, 152064, 0xf5346e32 +0, 266, 266, 1, 152064, 0x6d3e732b +0, 267, 267, 1, 152064, 0x798c584b +0, 268, 268, 1, 152064, 0x4076c948 +0, 269, 269, 1, 152064, 0x868cf63a +0, 270, 270, 1, 152064, 0x23107ac5 +0, 271, 271, 1, 152064, 0x306f3fe2 +0, 272, 272, 1, 152064, 0xbd1d71d6 +0, 273, 273, 1, 152064, 0x1429545f +0, 274, 274, 1, 152064, 0xaded29aa +0, 275, 275, 1, 152064, 0x9b455a94 +0, 276, 276, 1, 152064, 0xb3774ce7 +0, 277, 277, 1, 152064, 0x92580986 +0, 278, 278, 1, 152064, 0x0eae2f95 +0, 279, 279, 1, 152064, 0x599208b2 +0, 280, 280, 1, 152064, 0x4804c04c +0, 281, 281, 1, 152064, 0x5f730e8f +0, 282, 282, 1, 152064, 0x3e501d1e +0, 283, 283, 1, 152064, 0x32100740 +0, 284, 284, 1, 152064, 0x62226ff8 +0, 285, 285, 1, 152064, 0x7683b622 +0, 286, 286, 1, 152064, 0xc3e0aec1 +0, 287, 287, 1, 152064, 0xfac12608 +0, 288, 288, 1, 152064, 0xb21a5781 +0, 289, 289, 1, 152064, 0x8f1e4964 +0, 290, 290, 1, 152064, 0x0f62dd6e +0, 291, 291, 1, 152064, 0xac062ac4 +0, 292, 292, 1, 152064, 0x1b320f7a +0, 293, 293, 1, 152064, 0x346e7211 +0, 294, 294, 1, 152064, 0xe47592f3 +0, 295, 295, 1, 152064, 0xa3a7919c +0, 296, 296, 1, 152064, 0xa3580fa6 +0, 297, 297, 1, 152064, 0xc73430c1 +0, 298, 298, 1, 152064, 0x994a2c18 +0, 299, 299, 1, 152064, 0x0b5d8d45 +0, 300, 300, 1, 152064, 0x9eed5109 diff --git a/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b b/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b index 1b03e88a1..72b15b11e 100644 --- a/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b +++ b/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b @@ -3,78 +3,78 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0xf8248ceb -0, 1, 1, 1, 152064, 0xb6204c81 +0, 1, 1, 1, 152064, 0xf8248ceb +0, 2, 2, 1, 152064, 0xb6204c81 0, 2, 2, 1, 152064, 0x22fb1737 0, 3, 3, 1, 152064, 0xce8c3fd7 -0, 4, 4, 1, 152064, 0xee88cedc +0, 5, 5, 1, 152064, 0xee88cedc 0, 5, 5, 1, 152064, 0x1d4209ca -0, 6, 6, 1, 152064, 0x6fb15238 -0, 7, 7, 1, 152064, 0x505200c2 +0, 7, 7, 1, 152064, 0x6fb15238 +0, 8, 8, 1, 152064, 0x505200c2 0, 8, 8, 1, 152064, 0xb73574ba 0, 9, 9, 1, 152064, 0x0586a097 -0, 10, 10, 1, 152064, 0xed50fe02 +0, 11, 11, 1, 152064, 0xed50fe02 0, 11, 11, 1, 152064, 0x222221ab 0, 12, 12, 1, 152064, 0x8afefd46 -0, 13, 13, 1, 152064, 0x6832c5cc -0, 14, 14, 1, 152064, 0xba4c8110 +0, 14, 14, 1, 152064, 0x6832c5cc +0, 15, 15, 1, 152064, 0xba4c8110 0, 15, 15, 1, 152064, 0x95c07e1e 0, 16, 16, 1, 152064, 0xc5d6fde9 -0, 17, 17, 1, 152064, 0xe75a4921 -0, 18, 18, 1, 152064, 0x53b61688 +0, 18, 18, 1, 152064, 0xe75a4921 +0, 19, 19, 1, 152064, 0x53b61688 0, 19, 19, 1, 152064, 0x0335424b -0, 20, 20, 1, 152064, 0x621742c7 -0, 21, 21, 1, 152064, 0x4f69f41b +0, 21, 21, 1, 152064, 0x621742c7 +0, 22, 22, 1, 152064, 0x4f69f41b 0, 22, 22, 1, 152064, 0x6b3f65d7 -0, 23, 23, 1, 152064, 0x8dfde04f +0, 24, 24, 1, 152064, 0x8dfde04f 0, 24, 24, 1, 152064, 0x30750ff5 -0, 25, 25, 1, 152064, 0xe3d70f3c +0, 26, 26, 1, 152064, 0xe3d70f3c 0, 26, 26, 1, 152064, 0x0c1af825 -0, 27, 27, 1, 152064, 0x58a53935 +0, 28, 28, 1, 152064, 0x58a53935 0, 28, 28, 1, 152064, 0xc63d9e98 -0, 29, 29, 1, 152064, 0xa85fdc48 +0, 30, 30, 1, 152064, 0xa85fdc48 0, 30, 30, 1, 152064, 0x01bb9784 -0, 31, 31, 1, 152064, 0xdd5cb509 +0, 32, 32, 1, 152064, 0xdd5cb509 0, 32, 32, 1, 152064, 0x29ae7d2b -0, 33, 33, 1, 152064, 0xdb08593e -0, 34, 34, 1, 152064, 0x372d5d4e -0, 35, 35, 1, 152064, 0x31522664 -0, 36, 36, 1, 152064, 0x3f13f335 +0, 34, 34, 1, 152064, 0xdb08593e +0, 35, 35, 1, 152064, 0x372d5d4e +0, 36, 36, 1, 152064, 0x31522664 +0, 37, 37, 1, 152064, 0x3f13f335 0, 37, 37, 1, 152064, 0xfd10c19a -0, 38, 38, 1, 152064, 0xef728975 -0, 39, 39, 1, 152064, 0x8e79234d -0, 40, 40, 1, 152064, 0x47022791 +0, 39, 39, 1, 152064, 0xef728975 +0, 40, 40, 1, 152064, 0x8e79234d +0, 41, 41, 1, 152064, 0x47022791 0, 41, 41, 1, 152064, 0x1ef9d297 0, 42, 42, 1, 152064, 0x77bf9738 0, 43, 43, 1, 152064, 0xd6bc8f03 -0, 44, 44, 1, 152064, 0x283ded4a -0, 45, 45, 1, 152064, 0xd87098d1 +0, 45, 45, 1, 152064, 0x283ded4a +0, 46, 46, 1, 152064, 0xd87098d1 0, 46, 46, 1, 152064, 0x300077a2 0, 47, 47, 1, 152064, 0x30ffbea4 -0, 48, 48, 1, 152064, 0x5dc5356b +0, 49, 49, 1, 152064, 0x5dc5356b 0, 49, 49, 1, 152064, 0x31cce185 0, 50, 50, 1, 152064, 0x47fc9148 -0, 51, 51, 1, 152064, 0x1641491e +0, 52, 52, 1, 152064, 0x1641491e 0, 52, 52, 1, 152064, 0x2184937d -0, 53, 53, 1, 152064, 0x126eb74a +0, 54, 54, 1, 152064, 0x126eb74a 0, 54, 54, 1, 152064, 0x25c07593 0, 55, 55, 1, 152064, 0xb1294e7e -0, 56, 56, 1, 152064, 0x8b35f45d -0, 57, 57, 1, 152064, 0x54765025 +0, 57, 57, 1, 152064, 0x8b35f45d +0, 58, 58, 1, 152064, 0x54765025 0, 58, 58, 1, 152064, 0x1d17e901 -0, 59, 59, 1, 152064, 0xaeab358d -0, 60, 60, 1, 152064, 0xf682c91f +0, 60, 60, 1, 152064, 0xaeab358d +0, 61, 61, 1, 152064, 0xf682c91f 0, 61, 61, 1, 152064, 0x0b4c9b06 0, 62, 62, 1, 152064, 0x45f326dc -0, 63, 63, 1, 152064, 0x132eeda3 +0, 64, 64, 1, 152064, 0x132eeda3 0, 64, 64, 1, 152064, 0x3c9b8e16 0, 65, 65, 1, 152064, 0x1be133c1 0, 66, 66, 1, 152064, 0xfa876720 -0, 67, 67, 1, 152064, 0x1666cdb8 +0, 68, 68, 1, 152064, 0x1666cdb8 0, 68, 68, 1, 152064, 0x362f418f 0, 69, 69, 1, 152064, 0x926b4a96 0, 70, 70, 1, 152064, 0xee3da1df -0, 71, 71, 1, 152064, 0xc11f025d +0, 72, 72, 1, 152064, 0xc11f025d 0, 72, 72, 1, 152064, 0x9ba62c19 0, 73, 73, 1, 152064, 0x0d66194f 0, 74, 74, 1, 152064, 0x2fd09340 @@ -82,224 +82,224 @@ 0, 76, 76, 1, 152064, 0xa3192ce6 0, 77, 77, 1, 152064, 0x6bfce0e1 0, 78, 78, 1, 152064, 0x3b7c5286 -0, 79, 79, 1, 152064, 0xb52f4bf5 -0, 80, 80, 1, 152064, 0x30870027 +0, 80, 80, 1, 152064, 0xb52f4bf5 +0, 81, 81, 1, 152064, 0x30870027 0, 81, 81, 1, 152064, 0x6f8e71c3 0, 82, 82, 1, 152064, 0x8d41b09a 0, 83, 83, 1, 152064, 0xc1ff1d05 0, 84, 84, 1, 152064, 0xca54125c 0, 85, 85, 1, 152064, 0x3342d823 -0, 86, 86, 1, 152064, 0xcc4a7542 -0, 87, 87, 1, 152064, 0x21fc9a9d +0, 87, 87, 1, 152064, 0xcc4a7542 +0, 88, 88, 1, 152064, 0x21fc9a9d 0, 88, 88, 1, 152064, 0x91587574 0, 89, 89, 1, 152064, 0x30929cc2 0, 90, 90, 1, 152064, 0xf07606b7 -0, 91, 91, 1, 152064, 0x0476b876 -0, 92, 92, 1, 152064, 0x213333dc +0, 92, 92, 1, 152064, 0x0476b876 +0, 93, 93, 1, 152064, 0x213333dc 0, 93, 93, 1, 152064, 0x87c67597 -0, 94, 94, 1, 152064, 0x05434641 -0, 95, 95, 1, 152064, 0x959eeffc +0, 95, 95, 1, 152064, 0x05434641 +0, 96, 96, 1, 152064, 0x959eeffc 0, 96, 96, 1, 152064, 0x92a130b4 -0, 97, 97, 1, 152064, 0x53d0b544 -0, 98, 98, 1, 152064, 0xaf8c233e -0, 99, 99, 1, 152064, 0xd3d4259a -0, 100, 100, 1, 152064, 0xa0287753 +0, 98, 98, 1, 152064, 0x53d0b544 +0, 99, 99, 1, 152064, 0xaf8c233e +0, 100, 100, 1, 152064, 0xd3d4259a +0, 101, 101, 1, 152064, 0xa0287753 0, 101, 101, 1, 152064, 0xfa23972a 0, 102, 102, 1, 152064, 0xacae756d -0, 103, 103, 1, 152064, 0xd8b58b5c +0, 104, 104, 1, 152064, 0xd8b58b5c 0, 104, 104, 1, 152064, 0x7db2c755 -0, 105, 105, 1, 152064, 0x31e7b79a -0, 106, 106, 1, 152064, 0xd8660d98 +0, 106, 106, 1, 152064, 0x31e7b79a +0, 107, 107, 1, 152064, 0xd8660d98 0, 107, 107, 1, 152064, 0xdcf0d10d 0, 108, 108, 1, 152064, 0x3e6567e6 -0, 109, 109, 1, 152064, 0xec3530fd +0, 110, 110, 1, 152064, 0xec3530fd 0, 110, 110, 1, 152064, 0xf686c61a 0, 111, 111, 1, 152064, 0x6e706804 -0, 112, 112, 1, 152064, 0x5fd4a1a3 -0, 113, 113, 1, 152064, 0xbb3384f7 +0, 113, 113, 1, 152064, 0x5fd4a1a3 +0, 114, 114, 1, 152064, 0xbb3384f7 0, 114, 114, 1, 152064, 0x8ffb14dd -0, 115, 115, 1, 152064, 0x01253a73 -0, 116, 116, 1, 152064, 0xf89c15df +0, 116, 116, 1, 152064, 0x01253a73 +0, 117, 117, 1, 152064, 0xf89c15df 0, 117, 117, 1, 152064, 0xda2b0b4c -0, 118, 118, 1, 152064, 0xfc9dfcc1 -0, 119, 119, 1, 152064, 0xfef4f0fa +0, 119, 119, 1, 152064, 0xfc9dfcc1 +0, 120, 120, 1, 152064, 0xfef4f0fa 0, 120, 120, 1, 152064, 0x91669bea -0, 121, 121, 1, 152064, 0x3664a565 +0, 122, 122, 1, 152064, 0x3664a565 0, 122, 122, 1, 152064, 0x32dd7923 0, 123, 123, 1, 152064, 0x26825231 0, 124, 124, 1, 152064, 0x5f81896e -0, 125, 125, 1, 152064, 0x0c64ca2f +0, 126, 126, 1, 152064, 0x0c64ca2f 0, 126, 126, 1, 152064, 0x488bb665 -0, 127, 127, 1, 152064, 0x4d183a0f +0, 128, 128, 1, 152064, 0x4d183a0f 0, 128, 128, 1, 152064, 0xed169321 0, 129, 129, 1, 152064, 0xcec22917 0, 130, 130, 1, 152064, 0xbe04ea6c -0, 131, 131, 1, 152064, 0x32b8bf9f -0, 132, 132, 1, 152064, 0x9c7c2e13 -0, 133, 133, 1, 152064, 0x232e3016 -0, 134, 134, 1, 152064, 0x1b76c08e -0, 135, 135, 1, 152064, 0x7425d821 +0, 132, 132, 1, 152064, 0x32b8bf9f +0, 133, 133, 1, 152064, 0x9c7c2e13 +0, 134, 134, 1, 152064, 0x232e3016 +0, 135, 135, 1, 152064, 0x1b76c08e +0, 136, 136, 1, 152064, 0x7425d821 0, 136, 136, 1, 152064, 0x0818ff3c 0, 137, 137, 1, 152064, 0xb4f2c42b 0, 138, 138, 1, 152064, 0xe029f979 -0, 139, 139, 1, 152064, 0x97c54c2f -0, 140, 140, 1, 152064, 0xd101c3b5 +0, 140, 140, 1, 152064, 0x97c54c2f +0, 141, 141, 1, 152064, 0xd101c3b5 0, 141, 141, 1, 152064, 0x5ed1f5d4 -0, 142, 142, 1, 152064, 0xc28264d1 +0, 143, 143, 1, 152064, 0xc28264d1 0, 143, 143, 1, 152064, 0xa162dd31 0, 144, 144, 1, 152064, 0x2ee872ce -0, 145, 145, 1, 152064, 0x809a8fce +0, 146, 146, 1, 152064, 0x809a8fce 0, 146, 146, 1, 152064, 0xcfcc3ef9 -0, 147, 147, 1, 152064, 0xa5be6ce3 +0, 148, 148, 1, 152064, 0xa5be6ce3 0, 148, 148, 1, 152064, 0xd75930a0 -0, 149, 149, 1, 152064, 0x28acb80f -0, 150, 150, 1, 152064, 0x223f2152 -0, 151, 151, 1, 152064, 0x0cf070cb +0, 150, 150, 1, 152064, 0x28acb80f +0, 151, 151, 1, 152064, 0x223f2152 +0, 152, 152, 1, 152064, 0x0cf070cb 0, 152, 152, 1, 152064, 0xcc7d011e -0, 153, 153, 1, 152064, 0xb2c2a63c +0, 154, 154, 1, 152064, 0xb2c2a63c 0, 154, 154, 1, 152064, 0x15514caa -0, 155, 155, 1, 152064, 0x0c6d18ee +0, 156, 156, 1, 152064, 0x0c6d18ee 0, 156, 156, 1, 152064, 0x33b4265d 0, 157, 157, 1, 152064, 0xb4abaaaf -0, 158, 158, 1, 152064, 0x26a7a856 +0, 159, 159, 1, 152064, 0x26a7a856 0, 159, 159, 1, 152064, 0xc75249cc -0, 160, 160, 1, 152064, 0x59ccb0e1 -0, 161, 161, 1, 152064, 0xc613f202 -0, 162, 162, 1, 152064, 0xd1c0e171 +0, 161, 161, 1, 152064, 0x59ccb0e1 +0, 162, 162, 1, 152064, 0xc613f202 +0, 163, 163, 1, 152064, 0xd1c0e171 0, 163, 163, 1, 152064, 0xa195da2b 0, 164, 164, 1, 152064, 0xbc7ed475 0, 165, 165, 1, 152064, 0x99206e2c -0, 166, 166, 1, 152064, 0x0ef04e03 -0, 167, 167, 1, 152064, 0x68cbc6a1 +0, 167, 167, 1, 152064, 0x0ef04e03 +0, 168, 168, 1, 152064, 0x68cbc6a1 0, 168, 168, 1, 152064, 0x2a5304b1 0, 169, 169, 1, 152064, 0xf017978b 0, 170, 170, 1, 152064, 0x94f5641a -0, 171, 171, 1, 152064, 0xd681bd8f +0, 172, 172, 1, 152064, 0xd681bd8f 0, 172, 172, 1, 152064, 0x16e1e3a3 -0, 173, 173, 1, 152064, 0xe4486c7e -0, 174, 174, 1, 152064, 0xa1bd394e +0, 174, 174, 1, 152064, 0xe4486c7e +0, 175, 175, 1, 152064, 0xa1bd394e 0, 175, 175, 1, 152064, 0x49ad5959 -0, 176, 176, 1, 152064, 0x82219b70 -0, 177, 177, 1, 152064, 0x64e2abcf -0, 178, 178, 1, 152064, 0x6d7d05d8 -0, 179, 179, 1, 152064, 0xd9ac2251 +0, 177, 177, 1, 152064, 0x82219b70 +0, 178, 178, 1, 152064, 0x64e2abcf +0, 179, 179, 1, 152064, 0x6d7d05d8 +0, 180, 180, 1, 152064, 0xd9ac2251 0, 180, 180, 1, 152064, 0xf477eee5 -0, 181, 181, 1, 152064, 0xb9826a78 +0, 182, 182, 1, 152064, 0xb9826a78 0, 182, 182, 1, 152064, 0x97828a37 -0, 183, 183, 1, 152064, 0x12099b1f +0, 184, 184, 1, 152064, 0x12099b1f 0, 184, 184, 1, 152064, 0x1ec45fa7 -0, 185, 185, 1, 152064, 0xfd5501c9 +0, 186, 186, 1, 152064, 0xfd5501c9 0, 186, 186, 1, 152064, 0x6a8b26a3 -0, 187, 187, 1, 152064, 0xae58ff40 -0, 188, 188, 1, 152064, 0xc0f47aa1 +0, 188, 188, 1, 152064, 0xae58ff40 +0, 189, 189, 1, 152064, 0xc0f47aa1 0, 189, 189, 1, 152064, 0x08bfa548 0, 190, 190, 1, 152064, 0x7f2ff5ef -0, 191, 191, 1, 152064, 0x5efa94a3 -0, 192, 192, 1, 152064, 0xf786f970 -0, 193, 193, 1, 152064, 0xab6bc712 +0, 192, 192, 1, 152064, 0x5efa94a3 +0, 193, 193, 1, 152064, 0xf786f970 +0, 194, 194, 1, 152064, 0xab6bc712 0, 194, 194, 1, 152064, 0x25647bee -0, 195, 195, 1, 152064, 0x54333ad5 -0, 196, 196, 1, 152064, 0xb3a99413 +0, 196, 196, 1, 152064, 0x54333ad5 +0, 197, 197, 1, 152064, 0xb3a99413 0, 197, 197, 1, 152064, 0xe7a78a0d -0, 198, 198, 1, 152064, 0xa5054abc -0, 199, 199, 1, 152064, 0xb94896ea +0, 199, 199, 1, 152064, 0xa5054abc +0, 200, 200, 1, 152064, 0xb94896ea 0, 200, 200, 1, 152064, 0x9f641bca -0, 201, 201, 1, 152064, 0x7363901c +0, 202, 202, 1, 152064, 0x7363901c 0, 202, 202, 1, 152064, 0xd340a000 0, 203, 203, 1, 152064, 0x0217f413 0, 204, 204, 1, 152064, 0xbbdba6e6 0, 205, 205, 1, 152064, 0xabc42617 -0, 206, 206, 1, 152064, 0xa3442925 -0, 207, 207, 1, 152064, 0x7d06c7e9 +0, 207, 207, 1, 152064, 0xa3442925 +0, 208, 208, 1, 152064, 0x7d06c7e9 0, 208, 208, 1, 152064, 0xa45e32df 0, 209, 209, 1, 152064, 0xf5ed407f -0, 210, 210, 1, 152064, 0x5ec235d5 -0, 211, 211, 1, 152064, 0xa5706635 -0, 212, 212, 1, 152064, 0xa44a209b -0, 213, 213, 1, 152064, 0xf2137e37 -0, 214, 214, 1, 152064, 0x5220508f +0, 211, 211, 1, 152064, 0x5ec235d5 +0, 212, 212, 1, 152064, 0xa5706635 +0, 213, 213, 1, 152064, 0xa44a209b +0, 214, 214, 1, 152064, 0xf2137e37 +0, 215, 215, 1, 152064, 0x5220508f 0, 215, 215, 1, 152064, 0xae6b37da -0, 216, 216, 1, 152064, 0xdf09b6cd +0, 217, 217, 1, 152064, 0xdf09b6cd 0, 217, 217, 1, 152064, 0x2d39e1c0 -0, 218, 218, 1, 152064, 0xc8284a76 -0, 219, 219, 1, 152064, 0x7d7bbe76 +0, 219, 219, 1, 152064, 0xc8284a76 +0, 220, 220, 1, 152064, 0x7d7bbe76 0, 220, 220, 1, 152064, 0xcfed7416 0, 221, 221, 1, 152064, 0x81caaedd 0, 222, 222, 1, 152064, 0x9dcdd771 -0, 223, 223, 1, 152064, 0x46c1331b -0, 224, 224, 1, 152064, 0xace60efa +0, 224, 224, 1, 152064, 0x46c1331b +0, 225, 225, 1, 152064, 0xace60efa 0, 225, 225, 1, 152064, 0x9e0909f7 -0, 226, 226, 1, 152064, 0x72f5a321 +0, 227, 227, 1, 152064, 0x72f5a321 0, 227, 227, 1, 152064, 0x68f8cdcc 0, 228, 228, 1, 152064, 0xcc59fdd9 -0, 229, 229, 1, 152064, 0xc0a700c6 -0, 230, 230, 1, 152064, 0xf4254dcf +0, 230, 230, 1, 152064, 0xc0a700c6 +0, 231, 231, 1, 152064, 0xf4254dcf 0, 231, 231, 1, 152064, 0xc59b46d1 -0, 232, 232, 1, 152064, 0x2e5b2524 -0, 233, 233, 1, 152064, 0x46051293 +0, 233, 233, 1, 152064, 0x2e5b2524 +0, 234, 234, 1, 152064, 0x46051293 0, 234, 234, 1, 152064, 0x3cbcd1cd 0, 235, 235, 1, 152064, 0x9f308587 -0, 236, 236, 1, 152064, 0x6b91633f +0, 237, 237, 1, 152064, 0x6b91633f 0, 237, 237, 1, 152064, 0xb7191012 -0, 238, 238, 1, 152064, 0xd2fd030f -0, 239, 239, 1, 152064, 0x15a0ae2e -0, 240, 240, 1, 152064, 0xac3920d0 +0, 239, 239, 1, 152064, 0xd2fd030f +0, 240, 240, 1, 152064, 0x15a0ae2e +0, 241, 241, 1, 152064, 0xac3920d0 0, 241, 241, 1, 152064, 0x0eef80aa 0, 242, 242, 1, 152064, 0x319008f1 -0, 243, 243, 1, 152064, 0x7734450c +0, 244, 244, 1, 152064, 0x7734450c 0, 244, 244, 1, 152064, 0xf112df62 0, 245, 245, 1, 152064, 0x1dd8ffae -0, 246, 246, 1, 152064, 0x655ef429 +0, 247, 247, 1, 152064, 0x655ef429 0, 247, 247, 1, 152064, 0x27026213 -0, 248, 248, 1, 152064, 0x5c14b015 -0, 249, 249, 1, 152064, 0x9512abeb -0, 250, 250, 1, 152064, 0x961812b2 +0, 249, 249, 1, 152064, 0x5c14b015 +0, 250, 250, 1, 152064, 0x9512abeb +0, 251, 251, 1, 152064, 0x961812b2 0, 251, 251, 1, 152064, 0xb8890aea 0, 252, 252, 1, 152064, 0x4519db9a 0, 253, 253, 1, 152064, 0xf358034a -0, 254, 254, 1, 152064, 0x45d9f2ab +0, 255, 255, 1, 152064, 0x45d9f2ab 0, 255, 255, 1, 152064, 0xebd47e7d 0, 256, 256, 1, 152064, 0x15578be9 -0, 257, 257, 1, 152064, 0x1b373b2d +0, 258, 258, 1, 152064, 0x1b373b2d 0, 258, 258, 1, 152064, 0xbbe707e5 0, 259, 259, 1, 152064, 0x5bf62385 -0, 260, 260, 1, 152064, 0x832e6ef5 -0, 261, 261, 1, 152064, 0x761e5968 +0, 261, 261, 1, 152064, 0x832e6ef5 +0, 262, 262, 1, 152064, 0x761e5968 0, 262, 262, 1, 152064, 0x251f984d -0, 263, 263, 1, 152064, 0xbda48899 +0, 264, 264, 1, 152064, 0xbda48899 0, 264, 264, 1, 152064, 0x3fd843b9 -0, 265, 265, 1, 152064, 0x00485425 -0, 266, 266, 1, 152064, 0x4e282b39 -0, 267, 267, 1, 152064, 0x2630a8ea -0, 268, 268, 1, 152064, 0x5ea5c973 -0, 269, 269, 1, 152064, 0xfc436d21 -0, 270, 270, 1, 152064, 0x69852ef5 -0, 271, 271, 1, 152064, 0x44cb5589 -0, 272, 272, 1, 152064, 0x32f32725 -0, 273, 273, 1, 152064, 0x54d50aca -0, 274, 274, 1, 152064, 0xe7a639bb -0, 275, 275, 1, 152064, 0x01be2ad5 -0, 276, 276, 1, 152064, 0x5c63eca4 -0, 277, 277, 1, 152064, 0x94e91116 +0, 266, 266, 1, 152064, 0x00485425 +0, 267, 267, 1, 152064, 0x4e282b39 +0, 268, 268, 1, 152064, 0x2630a8ea +0, 269, 269, 1, 152064, 0x5ea5c973 +0, 270, 270, 1, 152064, 0xfc436d21 +0, 271, 271, 1, 152064, 0x69852ef5 +0, 272, 272, 1, 152064, 0x44cb5589 +0, 273, 273, 1, 152064, 0x32f32725 +0, 274, 274, 1, 152064, 0x54d50aca +0, 275, 275, 1, 152064, 0xe7a639bb +0, 276, 276, 1, 152064, 0x01be2ad5 +0, 277, 277, 1, 152064, 0x5c63eca4 +0, 278, 278, 1, 152064, 0x94e91116 0, 278, 278, 1, 152064, 0x9a8be637 0, 279, 279, 1, 152064, 0x165d9a12 -0, 280, 280, 1, 152064, 0x8c25ca0a -0, 281, 281, 1, 152064, 0x4ee2ed32 -0, 282, 282, 1, 152064, 0x4b2fe0c6 -0, 283, 283, 1, 152064, 0x521e434e -0, 284, 284, 1, 152064, 0x97679d7e -0, 285, 285, 1, 152064, 0x886b9506 +0, 281, 281, 1, 152064, 0x8c25ca0a +0, 282, 282, 1, 152064, 0x4ee2ed32 +0, 283, 283, 1, 152064, 0x4b2fe0c6 +0, 284, 284, 1, 152064, 0x521e434e +0, 285, 285, 1, 152064, 0x97679d7e +0, 286, 286, 1, 152064, 0x886b9506 0, 286, 286, 1, 152064, 0x4283eda8 -0, 287, 287, 1, 152064, 0xef793c49 +0, 288, 288, 1, 152064, 0xef793c49 0, 288, 288, 1, 152064, 0x68ac2afe -0, 289, 289, 1, 152064, 0x3d1ab510 +0, 290, 290, 1, 152064, 0x3d1ab510 0, 290, 290, 1, 152064, 0x98d3ec95 0, 291, 291, 1, 152064, 0x09f7e512 -0, 292, 292, 1, 152064, 0x801355dd -0, 293, 293, 1, 152064, 0xf2e87a11 +0, 293, 293, 1, 152064, 0x801355dd +0, 294, 294, 1, 152064, 0xf2e87a11 0, 294, 294, 1, 152064, 0x16757601 0, 295, 295, 1, 152064, 0x3074d74a -0, 296, 296, 1, 152064, 0xec8c1290 -0, 297, 297, 1, 152064, 0x46fb1877 +0, 297, 297, 1, 152064, 0xec8c1290 +0, 298, 298, 1, 152064, 0x46fb1877 0, 298, 298, 1, 152064, 0xf0b662c4 0, 299, 299, 1, 152064, 0xf8683940 diff --git a/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a b/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a index 0febed6d6..25551fb02 100644 --- a/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a +++ b/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a @@ -3,303 +3,303 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x502ec077 -0, 1, 1, 1, 152064, 0x84807243 -0, 2, 2, 1, 152064, 0xd7474a6e -0, 3, 3, 1, 152064, 0x793469bb -0, 4, 4, 1, 152064, 0xb7a0faf7 -0, 5, 5, 1, 152064, 0x1d3d3cba -0, 6, 6, 1, 152064, 0xb62583de -0, 7, 7, 1, 152064, 0xc8422fb1 -0, 8, 8, 1, 152064, 0x321dc699 -0, 9, 9, 1, 152064, 0x7a34d350 -0, 10, 10, 1, 152064, 0xaa4c302d -0, 11, 11, 1, 152064, 0x45fa7ab0 -0, 12, 12, 1, 152064, 0xc7262e41 -0, 13, 13, 1, 152064, 0x3550000c -0, 14, 14, 1, 152064, 0xf4bab54b -0, 15, 15, 1, 152064, 0xaccf9c1a -0, 16, 16, 1, 152064, 0x9bee20e9 -0, 17, 17, 1, 152064, 0x47fb7720 -0, 18, 18, 1, 152064, 0x12c63ffb -0, 19, 19, 1, 152064, 0xfa2b8b4d -0, 20, 20, 1, 152064, 0x279964bd -0, 21, 21, 1, 152064, 0xb8b01c7e -0, 22, 22, 1, 152064, 0x816fa010 -0, 23, 23, 1, 152064, 0x59fe1c8c -0, 24, 24, 1, 152064, 0x13393fad -0, 25, 25, 1, 152064, 0x991a50a4 -0, 26, 26, 1, 152064, 0x57df3eb7 -0, 27, 27, 1, 152064, 0x744371df -0, 28, 28, 1, 152064, 0xe9f6d3ff -0, 29, 29, 1, 152064, 0xc506fba0 -0, 30, 30, 1, 152064, 0x6295b90e -0, 31, 31, 1, 152064, 0xa19cee2d -0, 32, 32, 1, 152064, 0xf8c1b3ca -0, 33, 33, 1, 152064, 0x69f68ce0 -0, 34, 34, 1, 152064, 0x80558bb6 -0, 35, 35, 1, 152064, 0x27824fa5 -0, 36, 36, 1, 152064, 0x27c929a1 -0, 37, 37, 1, 152064, 0xc0fe06d1 -0, 38, 38, 1, 152064, 0xc52bc58c -0, 39, 39, 1, 152064, 0x0a5363c7 -0, 40, 40, 1, 152064, 0xd0f45a0d -0, 41, 41, 1, 152064, 0x274710f9 -0, 42, 42, 1, 152064, 0x89d2d390 -0, 43, 43, 1, 152064, 0x12a9bfb0 -0, 44, 44, 1, 152064, 0x04501a93 -0, 45, 45, 1, 152064, 0xf92cbbf4 -0, 46, 46, 1, 152064, 0xf6d1b27d -0, 47, 47, 1, 152064, 0xe3e904c3 -0, 48, 48, 1, 152064, 0x58f8516d -0, 49, 49, 1, 152064, 0x70370c2b -0, 50, 50, 1, 152064, 0xfeebc88c -0, 51, 51, 1, 152064, 0x974c6ed6 -0, 52, 52, 1, 152064, 0x401bdcf2 -0, 53, 53, 1, 152064, 0xfe61e278 -0, 54, 54, 1, 152064, 0x96ba8bb9 -0, 55, 55, 1, 152064, 0x988492fd -0, 56, 56, 1, 152064, 0xd1d913a9 -0, 57, 57, 1, 152064, 0x6bc46f0e -0, 58, 58, 1, 152064, 0x695ef706 -0, 59, 59, 1, 152064, 0x142045c9 -0, 60, 60, 1, 152064, 0xb390ed87 -0, 61, 61, 1, 152064, 0xb9e6d2e5 -0, 62, 62, 1, 152064, 0xe348797f -0, 63, 63, 1, 152064, 0x1cbd29d6 -0, 64, 64, 1, 152064, 0xbd7dd694 -0, 65, 65, 1, 152064, 0x516873c3 -0, 66, 66, 1, 152064, 0x27bba182 -0, 67, 67, 1, 152064, 0x7541f920 -0, 68, 68, 1, 152064, 0xfdf67042 -0, 69, 69, 1, 152064, 0x6c3c7896 -0, 70, 70, 1, 152064, 0xed86c467 -0, 71, 71, 1, 152064, 0x4ea83ca2 -0, 72, 72, 1, 152064, 0xa3e6725b -0, 73, 73, 1, 152064, 0x917f5f16 -0, 74, 74, 1, 152064, 0x8cf2d2e1 -0, 75, 75, 1, 152064, 0x57a8d116 -0, 76, 76, 1, 152064, 0x0db267d4 -0, 77, 77, 1, 152064, 0xce782ac5 -0, 78, 78, 1, 152064, 0x1c9d8518 -0, 79, 79, 1, 152064, 0x47598ac7 -0, 80, 80, 1, 152064, 0xc5033d97 -0, 81, 81, 1, 152064, 0xd7aaa3a4 -0, 82, 82, 1, 152064, 0x078afc96 -0, 83, 83, 1, 152064, 0xc9fe673d -0, 84, 84, 1, 152064, 0xe9284066 -0, 85, 85, 1, 152064, 0xbc570982 -0, 86, 86, 1, 152064, 0x0aac8574 -0, 87, 87, 1, 152064, 0x098cbeee -0, 88, 88, 1, 152064, 0x19c36a9d -0, 89, 89, 1, 152064, 0x8fe4a893 -0, 90, 90, 1, 152064, 0x0b652f17 -0, 91, 91, 1, 152064, 0x10f2e6bf -0, 92, 92, 1, 152064, 0x7ce5634e -0, 93, 93, 1, 152064, 0x8fe4ac6c -0, 94, 94, 1, 152064, 0xcaba749e -0, 95, 95, 1, 152064, 0x5f8a0d5c -0, 96, 96, 1, 152064, 0xcaa66bbc -0, 97, 97, 1, 152064, 0xc87ae617 -0, 98, 98, 1, 152064, 0xe8ef4dd7 -0, 99, 99, 1, 152064, 0xdfca5a07 -0, 100, 100, 1, 152064, 0x5f7eab7d -0, 101, 101, 1, 152064, 0x8a65ebbb -0, 102, 102, 1, 152064, 0x4beab4a0 -0, 103, 103, 1, 152064, 0xb5e6ab30 -0, 104, 104, 1, 152064, 0x8fe4f4d4 -0, 105, 105, 1, 152064, 0x95bde1ca -0, 106, 106, 1, 152064, 0xcc5e3a53 -0, 107, 107, 1, 152064, 0xf09f1dd7 -0, 108, 108, 1, 152064, 0x10179672 -0, 109, 109, 1, 152064, 0x4ad16184 -0, 110, 110, 1, 152064, 0x9efa0e23 -0, 111, 111, 1, 152064, 0x22f59522 -0, 112, 112, 1, 152064, 0x4d38f09d -0, 113, 113, 1, 152064, 0x4c5ebf56 -0, 114, 114, 1, 152064, 0xb19d5077 -0, 115, 115, 1, 152064, 0xa98576b9 -0, 116, 116, 1, 152064, 0x65324239 -0, 117, 117, 1, 152064, 0x709e4031 -0, 118, 118, 1, 152064, 0xf8e81681 -0, 119, 119, 1, 152064, 0x058514e5 -0, 120, 120, 1, 152064, 0xd1d1c806 -0, 121, 121, 1, 152064, 0x0e4dde57 -0, 122, 122, 1, 152064, 0x49e9c2bb -0, 123, 123, 1, 152064, 0x01417ce6 -0, 124, 124, 1, 152064, 0xda7ebbf1 -0, 125, 125, 1, 152064, 0xa22906b7 -0, 126, 126, 1, 152064, 0x32e2df87 -0, 127, 127, 1, 152064, 0x69917c8f -0, 128, 128, 1, 152064, 0xea8ed2cc -0, 129, 129, 1, 152064, 0x0b8d57f1 -0, 130, 130, 1, 152064, 0x5f683bcd -0, 131, 131, 1, 152064, 0x5162fe2f -0, 132, 132, 1, 152064, 0x49c052f8 -0, 133, 133, 1, 152064, 0x990b69ba -0, 134, 134, 1, 152064, 0xa6d4f99f -0, 135, 135, 1, 152064, 0xe79ef4da -0, 136, 136, 1, 152064, 0x5e8a3847 -0, 137, 137, 1, 152064, 0x38b1e75f -0, 138, 138, 1, 152064, 0xf5c91bed -0, 139, 139, 1, 152064, 0xd59a6d26 -0, 140, 140, 1, 152064, 0xc361de06 -0, 141, 141, 1, 152064, 0x63ed2229 -0, 142, 142, 1, 152064, 0xb8229205 -0, 143, 143, 1, 152064, 0x7c6619af -0, 144, 144, 1, 152064, 0x4126b02f -0, 145, 145, 1, 152064, 0x9250b99b -0, 146, 146, 1, 152064, 0x589778f9 -0, 147, 147, 1, 152064, 0xed1fa45b -0, 148, 148, 1, 152064, 0x700b6f32 -0, 149, 149, 1, 152064, 0x0590df55 -0, 150, 150, 1, 152064, 0x3e9c4018 -0, 151, 151, 1, 152064, 0x957b8860 -0, 152, 152, 1, 152064, 0x56161560 -0, 153, 153, 1, 152064, 0xbc43bc3b -0, 154, 154, 1, 152064, 0x508d8632 -0, 155, 155, 1, 152064, 0xbc5736d8 -0, 156, 156, 1, 152064, 0xed7d3aef -0, 157, 157, 1, 152064, 0x1dcdda9f -0, 158, 158, 1, 152064, 0x8ef6d5c9 -0, 159, 159, 1, 152064, 0x15466acc -0, 160, 160, 1, 152064, 0x45d4cf67 -0, 161, 161, 1, 152064, 0x8c900b9d -0, 162, 162, 1, 152064, 0x747006e0 -0, 163, 163, 1, 152064, 0xac920a0c -0, 164, 164, 1, 152064, 0xb8210c27 -0, 165, 165, 1, 152064, 0x7dbb873a -0, 166, 166, 1, 152064, 0x0d4d7584 -0, 167, 167, 1, 152064, 0xefb3fe60 -0, 168, 168, 1, 152064, 0x905e2644 -0, 169, 169, 1, 152064, 0x7c04e534 -0, 170, 170, 1, 152064, 0x8889972a -0, 171, 171, 1, 152064, 0x21c7d8ad -0, 172, 172, 1, 152064, 0x1c641176 -0, 173, 173, 1, 152064, 0xf71489a4 -0, 174, 174, 1, 152064, 0xd7ac5555 -0, 175, 175, 1, 152064, 0xb4609c6d -0, 176, 176, 1, 152064, 0xf5b2bd5e -0, 177, 177, 1, 152064, 0x9f43ce57 -0, 178, 178, 1, 152064, 0x77642dd3 -0, 179, 179, 1, 152064, 0x3e79565c -0, 180, 180, 1, 152064, 0x95f40b8e -0, 181, 181, 1, 152064, 0x3c8ca4d4 -0, 182, 182, 1, 152064, 0xa02ac497 -0, 183, 183, 1, 152064, 0x4c93b377 -0, 184, 184, 1, 152064, 0x55f5ac68 -0, 185, 185, 1, 152064, 0xf8652eca -0, 186, 186, 1, 152064, 0x56e94574 -0, 187, 187, 1, 152064, 0x6d8302e1 -0, 188, 188, 1, 152064, 0x29a57061 -0, 189, 189, 1, 152064, 0x24e4cfdc -0, 190, 190, 1, 152064, 0xf5a5d62a -0, 191, 191, 1, 152064, 0x998870c1 -0, 192, 192, 1, 152064, 0xa15b1f4e -0, 193, 193, 1, 152064, 0xb0ccb51f -0, 194, 194, 1, 152064, 0xeaaf59ab -0, 195, 195, 1, 152064, 0x7e2b4fe6 -0, 196, 196, 1, 152064, 0x72299fea -0, 197, 197, 1, 152064, 0x769da8b2 -0, 198, 198, 1, 152064, 0xefad7ef8 -0, 199, 199, 1, 152064, 0x24819983 -0, 200, 200, 1, 152064, 0x2aad32ab -0, 201, 201, 1, 152064, 0xc80cac79 -0, 202, 202, 1, 152064, 0x1659d628 -0, 203, 203, 1, 152064, 0xef941f66 -0, 204, 204, 1, 152064, 0x0d7fcdb5 -0, 205, 205, 1, 152064, 0x7c1853fa -0, 206, 206, 1, 152064, 0xb94c4d3c -0, 207, 207, 1, 152064, 0xc47adfc2 -0, 208, 208, 1, 152064, 0x366a6729 -0, 209, 209, 1, 152064, 0x7eb37b70 -0, 210, 210, 1, 152064, 0xafd54c27 -0, 211, 211, 1, 152064, 0x67b18636 -0, 212, 212, 1, 152064, 0x93b22dcf -0, 213, 213, 1, 152064, 0xa64991f1 -0, 214, 214, 1, 152064, 0xd32a7102 -0, 215, 215, 1, 152064, 0xff665d1c -0, 216, 216, 1, 152064, 0xf107cc31 -0, 217, 217, 1, 152064, 0xf5b25652 -0, 218, 218, 1, 152064, 0x8caf783d -0, 219, 219, 1, 152064, 0x72f3eb00 -0, 220, 220, 1, 152064, 0xb5aea5f8 -0, 221, 221, 1, 152064, 0xee70e870 -0, 222, 222, 1, 152064, 0x7c3a0156 -0, 223, 223, 1, 152064, 0x871b6383 -0, 224, 224, 1, 152064, 0x48d831ff -0, 225, 225, 1, 152064, 0xca233913 -0, 226, 226, 1, 152064, 0xe14bc5eb -0, 227, 227, 1, 152064, 0x9b1d27e7 -0, 228, 228, 1, 152064, 0xfb9637f7 -0, 229, 229, 1, 152064, 0x0c022157 -0, 230, 230, 1, 152064, 0x16d35fc9 -0, 231, 231, 1, 152064, 0x6d935f71 -0, 232, 232, 1, 152064, 0xae4066fa -0, 233, 233, 1, 152064, 0xcef94fdc -0, 234, 234, 1, 152064, 0xc234edb9 -0, 235, 235, 1, 152064, 0x26a4f2e2 -0, 236, 236, 1, 152064, 0xd29ac23e -0, 237, 237, 1, 152064, 0xb7604395 -0, 238, 238, 1, 152064, 0x408084f6 -0, 239, 239, 1, 152064, 0x0a02026c -0, 240, 240, 1, 152064, 0x78b33c7c -0, 241, 241, 1, 152064, 0xcb02b874 -0, 242, 242, 1, 152064, 0xf566513b -0, 243, 243, 1, 152064, 0xb34e52b1 -0, 244, 244, 1, 152064, 0xf55ff493 -0, 245, 245, 1, 152064, 0xb0e8282a -0, 246, 246, 1, 152064, 0xe9510bbe -0, 247, 247, 1, 152064, 0x292e8c5a -0, 248, 248, 1, 152064, 0x62b9d2b0 -0, 249, 249, 1, 152064, 0x3a8cc827 -0, 250, 250, 1, 152064, 0x25cc465e -0, 251, 251, 1, 152064, 0xf2bc32e2 -0, 252, 252, 1, 152064, 0x6141f914 -0, 253, 253, 1, 152064, 0x1171256f -0, 254, 254, 1, 152064, 0x13cb2ded -0, 255, 255, 1, 152064, 0x3d4ca557 -0, 256, 256, 1, 152064, 0xf2b9e72e -0, 257, 257, 1, 152064, 0x03f7547a -0, 258, 258, 1, 152064, 0xc7302955 -0, 259, 259, 1, 152064, 0xe78a46d3 -0, 260, 260, 1, 152064, 0x3726a270 -0, 261, 261, 1, 152064, 0x2f65722a -0, 262, 262, 1, 152064, 0x55acce40 -0, 263, 263, 1, 152064, 0xf6fa9db2 -0, 264, 264, 1, 152064, 0x70a36937 -0, 265, 265, 1, 152064, 0x9313742d -0, 266, 266, 1, 152064, 0x2eb14e53 -0, 267, 267, 1, 152064, 0x3d47c9c3 -0, 268, 268, 1, 152064, 0xd0a90348 -0, 269, 269, 1, 152064, 0x6ad48088 -0, 270, 270, 1, 152064, 0x68e64738 -0, 271, 271, 1, 152064, 0x04c3735a -0, 272, 272, 1, 152064, 0x51d0593f -0, 273, 273, 1, 152064, 0x42cf2b48 -0, 274, 274, 1, 152064, 0xa5496a0c -0, 275, 275, 1, 152064, 0x84c25549 -0, 276, 276, 1, 152064, 0x96691600 -0, 277, 277, 1, 152064, 0x423135db -0, 278, 278, 1, 152064, 0x8d2e08b6 -0, 279, 279, 1, 152064, 0xaeb4c840 -0, 280, 280, 1, 152064, 0xf3e71780 -0, 281, 281, 1, 152064, 0x8858228b -0, 282, 282, 1, 152064, 0xf28613f8 -0, 283, 283, 1, 152064, 0xb5327882 -0, 284, 284, 1, 152064, 0xbb60bb85 -0, 285, 285, 1, 152064, 0x345ab1c9 -0, 286, 286, 1, 152064, 0x8aac2cba -0, 287, 287, 1, 152064, 0x7ce15b4c -0, 288, 288, 1, 152064, 0xc09c55c0 -0, 289, 289, 1, 152064, 0x8482ddd6 -0, 290, 290, 1, 152064, 0xab222a13 -0, 291, 291, 1, 152064, 0xd39b0dea -0, 292, 292, 1, 152064, 0x6dab6e06 -0, 293, 293, 1, 152064, 0xec0891bd -0, 294, 294, 1, 152064, 0x88bd9701 -0, 295, 295, 1, 152064, 0xdf13072a -0, 296, 296, 1, 152064, 0x23b33081 -0, 297, 297, 1, 152064, 0x63943137 -0, 298, 298, 1, 152064, 0xab6a9052 -0, 299, 299, 1, 152064, 0x05485494 +0, 1, 1, 1, 152064, 0x502ec077 +0, 2, 2, 1, 152064, 0x84807243 +0, 3, 3, 1, 152064, 0xd7474a6e +0, 4, 4, 1, 152064, 0x793469bb +0, 5, 5, 1, 152064, 0xb7a0faf7 +0, 6, 6, 1, 152064, 0x1d3d3cba +0, 7, 7, 1, 152064, 0xb62583de +0, 8, 8, 1, 152064, 0xc8422fb1 +0, 9, 9, 1, 152064, 0x321dc699 +0, 10, 10, 1, 152064, 0x7a34d350 +0, 11, 11, 1, 152064, 0xaa4c302d +0, 12, 12, 1, 152064, 0x45fa7ab0 +0, 13, 13, 1, 152064, 0xc7262e41 +0, 14, 14, 1, 152064, 0x3550000c +0, 15, 15, 1, 152064, 0xf4bab54b +0, 16, 16, 1, 152064, 0xaccf9c1a +0, 17, 17, 1, 152064, 0x9bee20e9 +0, 18, 18, 1, 152064, 0x47fb7720 +0, 19, 19, 1, 152064, 0x12c63ffb +0, 20, 20, 1, 152064, 0xfa2b8b4d +0, 21, 21, 1, 152064, 0x279964bd +0, 22, 22, 1, 152064, 0xb8b01c7e +0, 23, 23, 1, 152064, 0x816fa010 +0, 24, 24, 1, 152064, 0x59fe1c8c +0, 25, 25, 1, 152064, 0x13393fad +0, 26, 26, 1, 152064, 0x991a50a4 +0, 27, 27, 1, 152064, 0x57df3eb7 +0, 28, 28, 1, 152064, 0x744371df +0, 29, 29, 1, 152064, 0xe9f6d3ff +0, 30, 30, 1, 152064, 0xc506fba0 +0, 31, 31, 1, 152064, 0x6295b90e +0, 32, 32, 1, 152064, 0xa19cee2d +0, 33, 33, 1, 152064, 0xf8c1b3ca +0, 34, 34, 1, 152064, 0x69f68ce0 +0, 35, 35, 1, 152064, 0x80558bb6 +0, 36, 36, 1, 152064, 0x27824fa5 +0, 37, 37, 1, 152064, 0x27c929a1 +0, 38, 38, 1, 152064, 0xc0fe06d1 +0, 39, 39, 1, 152064, 0xc52bc58c +0, 40, 40, 1, 152064, 0x0a5363c7 +0, 41, 41, 1, 152064, 0xd0f45a0d +0, 42, 42, 1, 152064, 0x274710f9 +0, 43, 43, 1, 152064, 0x89d2d390 +0, 44, 44, 1, 152064, 0x12a9bfb0 +0, 45, 45, 1, 152064, 0x04501a93 +0, 46, 46, 1, 152064, 0xf92cbbf4 +0, 47, 47, 1, 152064, 0xf6d1b27d +0, 48, 48, 1, 152064, 0xe3e904c3 +0, 49, 49, 1, 152064, 0x58f8516d +0, 50, 50, 1, 152064, 0x70370c2b +0, 51, 51, 1, 152064, 0xfeebc88c +0, 52, 52, 1, 152064, 0x974c6ed6 +0, 53, 53, 1, 152064, 0x401bdcf2 +0, 54, 54, 1, 152064, 0xfe61e278 +0, 55, 55, 1, 152064, 0x96ba8bb9 +0, 56, 56, 1, 152064, 0x988492fd +0, 57, 57, 1, 152064, 0xd1d913a9 +0, 58, 58, 1, 152064, 0x6bc46f0e +0, 59, 59, 1, 152064, 0x695ef706 +0, 60, 60, 1, 152064, 0x142045c9 +0, 61, 61, 1, 152064, 0xb390ed87 +0, 62, 62, 1, 152064, 0xb9e6d2e5 +0, 63, 63, 1, 152064, 0xe348797f +0, 64, 64, 1, 152064, 0x1cbd29d6 +0, 65, 65, 1, 152064, 0xbd7dd694 +0, 66, 66, 1, 152064, 0x516873c3 +0, 67, 67, 1, 152064, 0x27bba182 +0, 68, 68, 1, 152064, 0x7541f920 +0, 69, 69, 1, 152064, 0xfdf67042 +0, 70, 70, 1, 152064, 0x6c3c7896 +0, 71, 71, 1, 152064, 0xed86c467 +0, 72, 72, 1, 152064, 0x4ea83ca2 +0, 73, 73, 1, 152064, 0xa3e6725b +0, 74, 74, 1, 152064, 0x917f5f16 +0, 75, 75, 1, 152064, 0x8cf2d2e1 +0, 76, 76, 1, 152064, 0x57a8d116 +0, 77, 77, 1, 152064, 0x0db267d4 +0, 78, 78, 1, 152064, 0xce782ac5 +0, 79, 79, 1, 152064, 0x1c9d8518 +0, 80, 80, 1, 152064, 0x47598ac7 +0, 81, 81, 1, 152064, 0xc5033d97 +0, 82, 82, 1, 152064, 0xd7aaa3a4 +0, 83, 83, 1, 152064, 0x078afc96 +0, 84, 84, 1, 152064, 0xc9fe673d +0, 85, 85, 1, 152064, 0xe9284066 +0, 86, 86, 1, 152064, 0xbc570982 +0, 87, 87, 1, 152064, 0x0aac8574 +0, 88, 88, 1, 152064, 0x098cbeee +0, 89, 89, 1, 152064, 0x19c36a9d +0, 90, 90, 1, 152064, 0x8fe4a893 +0, 91, 91, 1, 152064, 0x0b652f17 +0, 92, 92, 1, 152064, 0x10f2e6bf +0, 93, 93, 1, 152064, 0x7ce5634e +0, 94, 94, 1, 152064, 0x8fe4ac6c +0, 95, 95, 1, 152064, 0xcaba749e +0, 96, 96, 1, 152064, 0x5f8a0d5c +0, 97, 97, 1, 152064, 0xcaa66bbc +0, 98, 98, 1, 152064, 0xc87ae617 +0, 99, 99, 1, 152064, 0xe8ef4dd7 +0, 100, 100, 1, 152064, 0xdfca5a07 +0, 101, 101, 1, 152064, 0x5f7eab7d +0, 102, 102, 1, 152064, 0x8a65ebbb +0, 103, 103, 1, 152064, 0x4beab4a0 +0, 104, 104, 1, 152064, 0xb5e6ab30 +0, 105, 105, 1, 152064, 0x8fe4f4d4 +0, 106, 106, 1, 152064, 0x95bde1ca +0, 107, 107, 1, 152064, 0xcc5e3a53 +0, 108, 108, 1, 152064, 0xf09f1dd7 +0, 109, 109, 1, 152064, 0x10179672 +0, 110, 110, 1, 152064, 0x4ad16184 +0, 111, 111, 1, 152064, 0x9efa0e23 +0, 112, 112, 1, 152064, 0x22f59522 +0, 113, 113, 1, 152064, 0x4d38f09d +0, 114, 114, 1, 152064, 0x4c5ebf56 +0, 115, 115, 1, 152064, 0xb19d5077 +0, 116, 116, 1, 152064, 0xa98576b9 +0, 117, 117, 1, 152064, 0x65324239 +0, 118, 118, 1, 152064, 0x709e4031 +0, 119, 119, 1, 152064, 0xf8e81681 +0, 120, 120, 1, 152064, 0x058514e5 +0, 121, 121, 1, 152064, 0xd1d1c806 +0, 122, 122, 1, 152064, 0x0e4dde57 +0, 123, 123, 1, 152064, 0x49e9c2bb +0, 124, 124, 1, 152064, 0x01417ce6 +0, 125, 125, 1, 152064, 0xda7ebbf1 +0, 126, 126, 1, 152064, 0xa22906b7 +0, 127, 127, 1, 152064, 0x32e2df87 +0, 128, 128, 1, 152064, 0x69917c8f +0, 129, 129, 1, 152064, 0xea8ed2cc +0, 130, 130, 1, 152064, 0x0b8d57f1 +0, 131, 131, 1, 152064, 0x5f683bcd +0, 132, 132, 1, 152064, 0x5162fe2f +0, 133, 133, 1, 152064, 0x49c052f8 +0, 134, 134, 1, 152064, 0x990b69ba +0, 135, 135, 1, 152064, 0xa6d4f99f +0, 136, 136, 1, 152064, 0xe79ef4da +0, 137, 137, 1, 152064, 0x5e8a3847 +0, 138, 138, 1, 152064, 0x38b1e75f +0, 139, 139, 1, 152064, 0xf5c91bed +0, 140, 140, 1, 152064, 0xd59a6d26 +0, 141, 141, 1, 152064, 0xc361de06 +0, 142, 142, 1, 152064, 0x63ed2229 +0, 143, 143, 1, 152064, 0xb8229205 +0, 144, 144, 1, 152064, 0x7c6619af +0, 145, 145, 1, 152064, 0x4126b02f +0, 146, 146, 1, 152064, 0x9250b99b +0, 147, 147, 1, 152064, 0x589778f9 +0, 148, 148, 1, 152064, 0xed1fa45b +0, 149, 149, 1, 152064, 0x700b6f32 +0, 150, 150, 1, 152064, 0x0590df55 +0, 151, 151, 1, 152064, 0x3e9c4018 +0, 152, 152, 1, 152064, 0x957b8860 +0, 153, 153, 1, 152064, 0x56161560 +0, 154, 154, 1, 152064, 0xbc43bc3b +0, 155, 155, 1, 152064, 0x508d8632 +0, 156, 156, 1, 152064, 0xbc5736d8 +0, 157, 157, 1, 152064, 0xed7d3aef +0, 158, 158, 1, 152064, 0x1dcdda9f +0, 159, 159, 1, 152064, 0x8ef6d5c9 +0, 160, 160, 1, 152064, 0x15466acc +0, 161, 161, 1, 152064, 0x45d4cf67 +0, 162, 162, 1, 152064, 0x8c900b9d +0, 163, 163, 1, 152064, 0x747006e0 +0, 164, 164, 1, 152064, 0xac920a0c +0, 165, 165, 1, 152064, 0xb8210c27 +0, 166, 166, 1, 152064, 0x7dbb873a +0, 167, 167, 1, 152064, 0x0d4d7584 +0, 168, 168, 1, 152064, 0xefb3fe60 +0, 169, 169, 1, 152064, 0x905e2644 +0, 170, 170, 1, 152064, 0x7c04e534 +0, 171, 171, 1, 152064, 0x8889972a +0, 172, 172, 1, 152064, 0x21c7d8ad +0, 173, 173, 1, 152064, 0x1c641176 +0, 174, 174, 1, 152064, 0xf71489a4 +0, 175, 175, 1, 152064, 0xd7ac5555 +0, 176, 176, 1, 152064, 0xb4609c6d +0, 177, 177, 1, 152064, 0xf5b2bd5e +0, 178, 178, 1, 152064, 0x9f43ce57 +0, 179, 179, 1, 152064, 0x77642dd3 +0, 180, 180, 1, 152064, 0x3e79565c +0, 181, 181, 1, 152064, 0x95f40b8e +0, 182, 182, 1, 152064, 0x3c8ca4d4 +0, 183, 183, 1, 152064, 0xa02ac497 +0, 184, 184, 1, 152064, 0x4c93b377 +0, 185, 185, 1, 152064, 0x55f5ac68 +0, 186, 186, 1, 152064, 0xf8652eca +0, 187, 187, 1, 152064, 0x56e94574 +0, 188, 188, 1, 152064, 0x6d8302e1 +0, 189, 189, 1, 152064, 0x29a57061 +0, 190, 190, 1, 152064, 0x24e4cfdc +0, 191, 191, 1, 152064, 0xf5a5d62a +0, 192, 192, 1, 152064, 0x998870c1 +0, 193, 193, 1, 152064, 0xa15b1f4e +0, 194, 194, 1, 152064, 0xb0ccb51f +0, 195, 195, 1, 152064, 0xeaaf59ab +0, 196, 196, 1, 152064, 0x7e2b4fe6 +0, 197, 197, 1, 152064, 0x72299fea +0, 198, 198, 1, 152064, 0x769da8b2 +0, 199, 199, 1, 152064, 0xefad7ef8 +0, 200, 200, 1, 152064, 0x24819983 +0, 201, 201, 1, 152064, 0x2aad32ab +0, 202, 202, 1, 152064, 0xc80cac79 +0, 203, 203, 1, 152064, 0x1659d628 +0, 204, 204, 1, 152064, 0xef941f66 +0, 205, 205, 1, 152064, 0x0d7fcdb5 +0, 206, 206, 1, 152064, 0x7c1853fa +0, 207, 207, 1, 152064, 0xb94c4d3c +0, 208, 208, 1, 152064, 0xc47adfc2 +0, 209, 209, 1, 152064, 0x366a6729 +0, 210, 210, 1, 152064, 0x7eb37b70 +0, 211, 211, 1, 152064, 0xafd54c27 +0, 212, 212, 1, 152064, 0x67b18636 +0, 213, 213, 1, 152064, 0x93b22dcf +0, 214, 214, 1, 152064, 0xa64991f1 +0, 215, 215, 1, 152064, 0xd32a7102 +0, 216, 216, 1, 152064, 0xff665d1c +0, 217, 217, 1, 152064, 0xf107cc31 +0, 218, 218, 1, 152064, 0xf5b25652 +0, 219, 219, 1, 152064, 0x8caf783d +0, 220, 220, 1, 152064, 0x72f3eb00 +0, 221, 221, 1, 152064, 0xb5aea5f8 +0, 222, 222, 1, 152064, 0xee70e870 +0, 223, 223, 1, 152064, 0x7c3a0156 +0, 224, 224, 1, 152064, 0x871b6383 +0, 225, 225, 1, 152064, 0x48d831ff +0, 226, 226, 1, 152064, 0xca233913 +0, 227, 227, 1, 152064, 0xe14bc5eb +0, 228, 228, 1, 152064, 0x9b1d27e7 +0, 229, 229, 1, 152064, 0xfb9637f7 +0, 230, 230, 1, 152064, 0x0c022157 +0, 231, 231, 1, 152064, 0x16d35fc9 +0, 232, 232, 1, 152064, 0x6d935f71 +0, 233, 233, 1, 152064, 0xae4066fa +0, 234, 234, 1, 152064, 0xcef94fdc +0, 235, 235, 1, 152064, 0xc234edb9 +0, 236, 236, 1, 152064, 0x26a4f2e2 +0, 237, 237, 1, 152064, 0xd29ac23e +0, 238, 238, 1, 152064, 0xb7604395 +0, 239, 239, 1, 152064, 0x408084f6 +0, 240, 240, 1, 152064, 0x0a02026c +0, 241, 241, 1, 152064, 0x78b33c7c +0, 242, 242, 1, 152064, 0xcb02b874 +0, 243, 243, 1, 152064, 0xf566513b +0, 244, 244, 1, 152064, 0xb34e52b1 +0, 245, 245, 1, 152064, 0xf55ff493 +0, 246, 246, 1, 152064, 0xb0e8282a +0, 247, 247, 1, 152064, 0xe9510bbe +0, 248, 248, 1, 152064, 0x292e8c5a +0, 249, 249, 1, 152064, 0x62b9d2b0 +0, 250, 250, 1, 152064, 0x3a8cc827 +0, 251, 251, 1, 152064, 0x25cc465e +0, 252, 252, 1, 152064, 0xf2bc32e2 +0, 253, 253, 1, 152064, 0x6141f914 +0, 254, 254, 1, 152064, 0x1171256f +0, 255, 255, 1, 152064, 0x13cb2ded +0, 256, 256, 1, 152064, 0x3d4ca557 +0, 257, 257, 1, 152064, 0xf2b9e72e +0, 258, 258, 1, 152064, 0x03f7547a +0, 259, 259, 1, 152064, 0xc7302955 +0, 260, 260, 1, 152064, 0xe78a46d3 +0, 261, 261, 1, 152064, 0x3726a270 +0, 262, 262, 1, 152064, 0x2f65722a +0, 263, 263, 1, 152064, 0x55acce40 +0, 264, 264, 1, 152064, 0xf6fa9db2 +0, 265, 265, 1, 152064, 0x70a36937 +0, 266, 266, 1, 152064, 0x9313742d +0, 267, 267, 1, 152064, 0x2eb14e53 +0, 268, 268, 1, 152064, 0x3d47c9c3 +0, 269, 269, 1, 152064, 0xd0a90348 +0, 270, 270, 1, 152064, 0x6ad48088 +0, 271, 271, 1, 152064, 0x68e64738 +0, 272, 272, 1, 152064, 0x04c3735a +0, 273, 273, 1, 152064, 0x51d0593f +0, 274, 274, 1, 152064, 0x42cf2b48 +0, 275, 275, 1, 152064, 0xa5496a0c +0, 276, 276, 1, 152064, 0x84c25549 +0, 277, 277, 1, 152064, 0x96691600 +0, 278, 278, 1, 152064, 0x423135db +0, 279, 279, 1, 152064, 0x8d2e08b6 +0, 280, 280, 1, 152064, 0xaeb4c840 +0, 281, 281, 1, 152064, 0xf3e71780 +0, 282, 282, 1, 152064, 0x8858228b +0, 283, 283, 1, 152064, 0xf28613f8 +0, 284, 284, 1, 152064, 0xb5327882 +0, 285, 285, 1, 152064, 0xbb60bb85 +0, 286, 286, 1, 152064, 0x345ab1c9 +0, 287, 287, 1, 152064, 0x8aac2cba +0, 288, 288, 1, 152064, 0x7ce15b4c +0, 289, 289, 1, 152064, 0xc09c55c0 +0, 290, 290, 1, 152064, 0x8482ddd6 +0, 291, 291, 1, 152064, 0xab222a13 +0, 292, 292, 1, 152064, 0xd39b0dea +0, 293, 293, 1, 152064, 0x6dab6e06 +0, 294, 294, 1, 152064, 0xec0891bd +0, 295, 295, 1, 152064, 0x88bd9701 +0, 296, 296, 1, 152064, 0xdf13072a +0, 297, 297, 1, 152064, 0x23b33081 +0, 298, 298, 1, 152064, 0x63943137 +0, 299, 299, 1, 152064, 0xab6a9052 +0, 300, 300, 1, 152064, 0x05485494 diff --git a/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a b/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a index 9958f1616..d6c41dd64 100644 --- a/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a +++ b/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a @@ -3,303 +3,303 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x3e39c08b -0, 1, 1, 1, 152064, 0xabc67990 -0, 2, 2, 1, 152064, 0x19614e74 -0, 3, 3, 1, 152064, 0xa3776beb -0, 4, 4, 1, 152064, 0xcce6ffdf -0, 5, 5, 1, 152064, 0xb0e94746 -0, 6, 6, 1, 152064, 0xdb1a84ef -0, 7, 7, 1, 152064, 0xb2624509 -0, 8, 8, 1, 152064, 0x32e2d826 -0, 9, 9, 1, 152064, 0xb3bddf0b -0, 10, 10, 1, 152064, 0x2e273ce3 -0, 11, 11, 1, 152064, 0x67af7e4d -0, 12, 12, 1, 152064, 0x505c3261 -0, 13, 13, 1, 152064, 0xa43d015e -0, 14, 14, 1, 152064, 0xad41c1f6 -0, 15, 15, 1, 152064, 0x633ba55f -0, 16, 16, 1, 152064, 0xe80634f0 -0, 17, 17, 1, 152064, 0x80a07dc9 -0, 18, 18, 1, 152064, 0x0e7a3bbf -0, 19, 19, 1, 152064, 0xcb099196 -0, 20, 20, 1, 152064, 0x57c96db5 -0, 21, 21, 1, 152064, 0xccd422fa -0, 22, 22, 1, 152064, 0x0850b7a7 -0, 23, 23, 1, 152064, 0x30e33156 -0, 24, 24, 1, 152064, 0x34e13f9a -0, 25, 25, 1, 152064, 0x03d36000 -0, 26, 26, 1, 152064, 0xbf7d49da -0, 27, 27, 1, 152064, 0x77336d09 -0, 28, 28, 1, 152064, 0xca8be5a9 -0, 29, 29, 1, 152064, 0xe57c0b08 -0, 30, 30, 1, 152064, 0xbe77c093 -0, 31, 31, 1, 152064, 0x6bf1ff05 -0, 32, 32, 1, 152064, 0x9142babf -0, 33, 33, 1, 152064, 0x08db8e67 -0, 34, 34, 1, 152064, 0x69ac8cb6 -0, 35, 35, 1, 152064, 0xaa3b5c88 -0, 36, 36, 1, 152064, 0x9bd32638 -0, 37, 37, 1, 152064, 0x7972115a -0, 38, 38, 1, 152064, 0x5c1dd47b -0, 39, 39, 1, 152064, 0x8a196e02 -0, 40, 40, 1, 152064, 0xa89672bc -0, 41, 41, 1, 152064, 0x27b220e4 -0, 42, 42, 1, 152064, 0xfa38dc4a -0, 43, 43, 1, 152064, 0x4784c639 -0, 44, 44, 1, 152064, 0xa5e4229a -0, 45, 45, 1, 152064, 0xa986bdfc -0, 46, 46, 1, 152064, 0x2951b47b -0, 47, 47, 1, 152064, 0x4df404a6 -0, 48, 48, 1, 152064, 0xc75155e8 -0, 49, 49, 1, 152064, 0xfc05248c -0, 50, 50, 1, 152064, 0x5d53da10 -0, 51, 51, 1, 152064, 0x284376ec -0, 52, 52, 1, 152064, 0x19fce380 -0, 53, 53, 1, 152064, 0x876be6c9 -0, 54, 54, 1, 152064, 0x39eb8ff9 -0, 55, 55, 1, 152064, 0x289c9543 -0, 56, 56, 1, 152064, 0x24dd2356 -0, 57, 57, 1, 152064, 0x1dc17d3c -0, 58, 58, 1, 152064, 0xd17c00ac -0, 59, 59, 1, 152064, 0xc2ad54de -0, 60, 60, 1, 152064, 0xbe11ee2f -0, 61, 61, 1, 152064, 0x3db9dc89 -0, 62, 62, 1, 152064, 0xac0d7bc2 -0, 63, 63, 1, 152064, 0x8dab2dde -0, 64, 64, 1, 152064, 0x566ad225 -0, 65, 65, 1, 152064, 0x587c7853 -0, 66, 66, 1, 152064, 0x601c9c80 -0, 67, 67, 1, 152064, 0x2afaf751 -0, 68, 68, 1, 152064, 0x1c9f7e3a -0, 69, 69, 1, 152064, 0x899475bf -0, 70, 70, 1, 152064, 0x0d65c7d9 -0, 71, 71, 1, 152064, 0xafd63d12 -0, 72, 72, 1, 152064, 0x162e62b9 -0, 73, 73, 1, 152064, 0x5c9554be -0, 74, 74, 1, 152064, 0x35fbdaa2 -0, 75, 75, 1, 152064, 0x6438cbd8 -0, 76, 76, 1, 152064, 0xde0772c9 -0, 77, 77, 1, 152064, 0x79f82854 -0, 78, 78, 1, 152064, 0x86957840 -0, 79, 79, 1, 152064, 0xd9468cbf -0, 80, 80, 1, 152064, 0x23e74609 -0, 81, 81, 1, 152064, 0x3919a146 -0, 82, 82, 1, 152064, 0xd641078b -0, 83, 83, 1, 152064, 0x24397220 -0, 84, 84, 1, 152064, 0xe7fc3a7c -0, 85, 85, 1, 152064, 0x3997154a -0, 86, 86, 1, 152064, 0x2af3952c -0, 87, 87, 1, 152064, 0x274ac07a -0, 88, 88, 1, 152064, 0x288f7b09 -0, 89, 89, 1, 152064, 0xe6f9b022 -0, 90, 90, 1, 152064, 0xf09e2fbb -0, 91, 91, 1, 152064, 0x7244e477 -0, 92, 92, 1, 152064, 0x0dfc72eb -0, 93, 93, 1, 152064, 0x0322b21f -0, 94, 94, 1, 152064, 0x18b08205 -0, 95, 95, 1, 152064, 0x6606153e -0, 96, 96, 1, 152064, 0x85186272 -0, 97, 97, 1, 152064, 0x3369f064 -0, 98, 98, 1, 152064, 0xbe0d5a44 -0, 99, 99, 1, 152064, 0x320258bb -0, 100, 100, 1, 152064, 0x4d6fb091 -0, 101, 101, 1, 152064, 0xc9bbf5e7 -0, 102, 102, 1, 152064, 0x0aa1b69b -0, 103, 103, 1, 152064, 0x85b9ac11 -0, 104, 104, 1, 152064, 0xb25ff818 -0, 105, 105, 1, 152064, 0xa155dc25 -0, 106, 106, 1, 152064, 0xa8e03bfd -0, 107, 107, 1, 152064, 0x0a862956 -0, 108, 108, 1, 152064, 0x11b49264 -0, 109, 109, 1, 152064, 0xa94e664e -0, 110, 110, 1, 152064, 0x330e0fa2 -0, 111, 111, 1, 152064, 0xaf3d9518 -0, 112, 112, 1, 152064, 0x0836f2e8 -0, 113, 113, 1, 152064, 0xbf6dc578 -0, 114, 114, 1, 152064, 0x7b524d20 -0, 115, 115, 1, 152064, 0x9ef7677f -0, 116, 116, 1, 152064, 0xeacf3f34 -0, 117, 117, 1, 152064, 0xfb4e3dbe -0, 118, 118, 1, 152064, 0xb46e25cb -0, 119, 119, 1, 152064, 0x363c1603 -0, 120, 120, 1, 152064, 0x263fc542 -0, 121, 121, 1, 152064, 0xf106e548 -0, 122, 122, 1, 152064, 0xde43c56a -0, 123, 123, 1, 152064, 0xc2c4770a -0, 124, 124, 1, 152064, 0x122fce19 -0, 125, 125, 1, 152064, 0x3ba01434 -0, 126, 126, 1, 152064, 0x0e8ce5ee -0, 127, 127, 1, 152064, 0x6ceb82e1 -0, 128, 128, 1, 152064, 0xa23ee21c -0, 129, 129, 1, 152064, 0xc6d960f9 -0, 130, 130, 1, 152064, 0x0de15258 -0, 131, 131, 1, 152064, 0x187b0333 -0, 132, 132, 1, 152064, 0x92e6582f -0, 133, 133, 1, 152064, 0xb9586ce0 -0, 134, 134, 1, 152064, 0xefd803b5 -0, 135, 135, 1, 152064, 0x24eafb29 -0, 136, 136, 1, 152064, 0x20c73b14 -0, 137, 137, 1, 152064, 0xbd7ceaaa -0, 138, 138, 1, 152064, 0x775216c8 -0, 139, 139, 1, 152064, 0xa08971c7 -0, 140, 140, 1, 152064, 0xef0ee865 -0, 141, 141, 1, 152064, 0x9ac61c2f -0, 142, 142, 1, 152064, 0x52ae8ea9 -0, 143, 143, 1, 152064, 0x06571c14 -0, 144, 144, 1, 152064, 0x6e78ad33 -0, 145, 145, 1, 152064, 0xad01c627 -0, 146, 146, 1, 152064, 0xbfe074d3 -0, 147, 147, 1, 152064, 0x9357a183 -0, 148, 148, 1, 152064, 0x8de7767f -0, 149, 149, 1, 152064, 0xa5e6e76e -0, 150, 150, 1, 152064, 0xa6f646fe -0, 151, 151, 1, 152064, 0x132e99f8 -0, 152, 152, 1, 152064, 0xb79f27de -0, 153, 153, 1, 152064, 0x36d3cdcf -0, 154, 154, 1, 152064, 0xdc938336 -0, 155, 155, 1, 152064, 0xacaa3a7f -0, 156, 156, 1, 152064, 0xc61a37fd -0, 157, 157, 1, 152064, 0x4fe1ddf0 -0, 158, 158, 1, 152064, 0xc0f7d660 -0, 159, 159, 1, 152064, 0xd72458ea -0, 160, 160, 1, 152064, 0x6978d123 -0, 161, 161, 1, 152064, 0x64e60ccf -0, 162, 162, 1, 152064, 0xaa07004c -0, 163, 163, 1, 152064, 0x07cd1064 -0, 164, 164, 1, 152064, 0xa82320e5 -0, 165, 165, 1, 152064, 0xaedd8d30 -0, 166, 166, 1, 152064, 0x79b082ea -0, 167, 167, 1, 152064, 0x9ed800ab -0, 168, 168, 1, 152064, 0xde592bb4 -0, 169, 169, 1, 152064, 0xd966df88 -0, 170, 170, 1, 152064, 0xf921988a -0, 171, 171, 1, 152064, 0x557ad9ae -0, 172, 172, 1, 152064, 0xc3f31a9a -0, 173, 173, 1, 152064, 0x65248561 -0, 174, 174, 1, 152064, 0x63df4aa6 -0, 175, 175, 1, 152064, 0x618da0a9 -0, 176, 176, 1, 152064, 0xe6f1c435 -0, 177, 177, 1, 152064, 0x9f90c38f -0, 178, 178, 1, 152064, 0xd2853e14 -0, 179, 179, 1, 152064, 0x6e0268a9 -0, 180, 180, 1, 152064, 0x393712d1 -0, 181, 181, 1, 152064, 0x470da25f -0, 182, 182, 1, 152064, 0xaf55cb3d -0, 183, 183, 1, 152064, 0x6935b8b9 -0, 184, 184, 1, 152064, 0x5409a15f -0, 185, 185, 1, 152064, 0x09073fee -0, 186, 186, 1, 152064, 0xfb274e82 -0, 187, 187, 1, 152064, 0x1a770581 -0, 188, 188, 1, 152064, 0x17277d0d -0, 189, 189, 1, 152064, 0xd4dcd982 -0, 190, 190, 1, 152064, 0x6b04eaf3 -0, 191, 191, 1, 152064, 0x8a3d822e -0, 192, 192, 1, 152064, 0x1b971ec9 -0, 193, 193, 1, 152064, 0x14e0c0f6 -0, 194, 194, 1, 152064, 0x00667450 -0, 195, 195, 1, 152064, 0xd2385902 -0, 196, 196, 1, 152064, 0x905da6ab -0, 197, 197, 1, 152064, 0xa3ffb18b -0, 198, 198, 1, 152064, 0x10d48b19 -0, 199, 199, 1, 152064, 0xb2c7a3bd -0, 200, 200, 1, 152064, 0x45593e96 -0, 201, 201, 1, 152064, 0x47a0b60c -0, 202, 202, 1, 152064, 0x68c6d1b9 -0, 203, 203, 1, 152064, 0xbc881fcc -0, 204, 204, 1, 152064, 0x422cc6f2 -0, 205, 205, 1, 152064, 0x9b686410 -0, 206, 206, 1, 152064, 0x35dc5e86 -0, 207, 207, 1, 152064, 0x247bedaa -0, 208, 208, 1, 152064, 0x22b76fd1 -0, 209, 209, 1, 152064, 0x67cc7a75 -0, 210, 210, 1, 152064, 0xa197521e -0, 211, 211, 1, 152064, 0x428c8662 -0, 212, 212, 1, 152064, 0x33dc2c73 -0, 213, 213, 1, 152064, 0x5b538903 -0, 214, 214, 1, 152064, 0x3c4176b6 -0, 215, 215, 1, 152064, 0x774364ba -0, 216, 216, 1, 152064, 0xf237d03e -0, 217, 217, 1, 152064, 0xac8746fb -0, 218, 218, 1, 152064, 0x6b306a84 -0, 219, 219, 1, 152064, 0xa2ace513 -0, 220, 220, 1, 152064, 0x709c9be7 -0, 221, 221, 1, 152064, 0x2403f373 -0, 222, 222, 1, 152064, 0x147bf717 -0, 223, 223, 1, 152064, 0xe58964c8 -0, 224, 224, 1, 152064, 0xa0da36fc -0, 225, 225, 1, 152064, 0x1ac1355c -0, 226, 226, 1, 152064, 0x8a31c9f2 -0, 227, 227, 1, 152064, 0x42ba205c -0, 228, 228, 1, 152064, 0xa11b3575 -0, 229, 229, 1, 152064, 0xcb35207c -0, 230, 230, 1, 152064, 0x528f6189 -0, 231, 231, 1, 152064, 0x34f05bd7 -0, 232, 232, 1, 152064, 0x72317356 -0, 233, 233, 1, 152064, 0xaabd5028 -0, 234, 234, 1, 152064, 0x13dbeb7b -0, 235, 235, 1, 152064, 0x62f1e8a8 -0, 236, 236, 1, 152064, 0x1723bfcd -0, 237, 237, 1, 152064, 0x5c083c00 -0, 238, 238, 1, 152064, 0x52137894 -0, 239, 239, 1, 152064, 0xef1e082c -0, 240, 240, 1, 152064, 0x664b3d53 -0, 241, 241, 1, 152064, 0x2eb9b296 -0, 242, 242, 1, 152064, 0xd0ca511e -0, 243, 243, 1, 152064, 0x012d4724 -0, 244, 244, 1, 152064, 0xa847f5af -0, 245, 245, 1, 152064, 0x483a2fde -0, 246, 246, 1, 152064, 0xd1ab0257 -0, 247, 247, 1, 152064, 0x414692c7 -0, 248, 248, 1, 152064, 0x0b79df88 -0, 249, 249, 1, 152064, 0xdaa2c4a3 -0, 250, 250, 1, 152064, 0xd1b44500 -0, 251, 251, 1, 152064, 0xfd3d2cf3 -0, 252, 252, 1, 152064, 0xfdc0f748 -0, 253, 253, 1, 152064, 0xce762a2a -0, 254, 254, 1, 152064, 0x08b63572 -0, 255, 255, 1, 152064, 0x5a46a38d -0, 256, 256, 1, 152064, 0x03cee9c0 -0, 257, 257, 1, 152064, 0x9ee45473 -0, 258, 258, 1, 152064, 0x5a432386 -0, 259, 259, 1, 152064, 0x54c83d87 -0, 260, 260, 1, 152064, 0xc9caa1de -0, 261, 261, 1, 152064, 0xa28367f1 -0, 262, 262, 1, 152064, 0x2607cdf1 -0, 263, 263, 1, 152064, 0x06baa8de -0, 264, 264, 1, 152064, 0xf5346e32 -0, 265, 265, 1, 152064, 0x6d3e732b -0, 266, 266, 1, 152064, 0x798c584b -0, 267, 267, 1, 152064, 0x4076c948 -0, 268, 268, 1, 152064, 0x868cf63a -0, 269, 269, 1, 152064, 0x23107ac5 -0, 270, 270, 1, 152064, 0x306f3fe2 -0, 271, 271, 1, 152064, 0xbd1d71d6 -0, 272, 272, 1, 152064, 0x1429545f -0, 273, 273, 1, 152064, 0xaded29aa -0, 274, 274, 1, 152064, 0x9b455a94 -0, 275, 275, 1, 152064, 0xb3774ce7 -0, 276, 276, 1, 152064, 0x92580986 -0, 277, 277, 1, 152064, 0x0eae2f95 -0, 278, 278, 1, 152064, 0x599208b2 -0, 279, 279, 1, 152064, 0x4804c04c -0, 280, 280, 1, 152064, 0x5f730e8f -0, 281, 281, 1, 152064, 0x3e501d1e -0, 282, 282, 1, 152064, 0x32100740 -0, 283, 283, 1, 152064, 0x62226ff8 -0, 284, 284, 1, 152064, 0x7683b622 -0, 285, 285, 1, 152064, 0xc3e0aec1 -0, 286, 286, 1, 152064, 0xfac12608 -0, 287, 287, 1, 152064, 0xb21a5781 -0, 288, 288, 1, 152064, 0x8f1e4964 -0, 289, 289, 1, 152064, 0x0f62dd6e -0, 290, 290, 1, 152064, 0xac062ac4 -0, 291, 291, 1, 152064, 0x1b320f7a -0, 292, 292, 1, 152064, 0x346e7211 -0, 293, 293, 1, 152064, 0xe47592f3 -0, 294, 294, 1, 152064, 0xa3a7919c -0, 295, 295, 1, 152064, 0xa3580fa6 -0, 296, 296, 1, 152064, 0xc73430c1 -0, 297, 297, 1, 152064, 0x994a2c18 -0, 298, 298, 1, 152064, 0x0b5d8d45 -0, 299, 299, 1, 152064, 0x9eed5109 +0, 1, 1, 1, 152064, 0x3e39c08b +0, 2, 2, 1, 152064, 0xabc67990 +0, 3, 3, 1, 152064, 0x19614e74 +0, 4, 4, 1, 152064, 0xa3776beb +0, 5, 5, 1, 152064, 0xcce6ffdf +0, 6, 6, 1, 152064, 0xb0e94746 +0, 7, 7, 1, 152064, 0xdb1a84ef +0, 8, 8, 1, 152064, 0xb2624509 +0, 9, 9, 1, 152064, 0x32e2d826 +0, 10, 10, 1, 152064, 0xb3bddf0b +0, 11, 11, 1, 152064, 0x2e273ce3 +0, 12, 12, 1, 152064, 0x67af7e4d +0, 13, 13, 1, 152064, 0x505c3261 +0, 14, 14, 1, 152064, 0xa43d015e +0, 15, 15, 1, 152064, 0xad41c1f6 +0, 16, 16, 1, 152064, 0x633ba55f +0, 17, 17, 1, 152064, 0xe80634f0 +0, 18, 18, 1, 152064, 0x80a07dc9 +0, 19, 19, 1, 152064, 0x0e7a3bbf +0, 20, 20, 1, 152064, 0xcb099196 +0, 21, 21, 1, 152064, 0x57c96db5 +0, 22, 22, 1, 152064, 0xccd422fa +0, 23, 23, 1, 152064, 0x0850b7a7 +0, 24, 24, 1, 152064, 0x30e33156 +0, 25, 25, 1, 152064, 0x34e13f9a +0, 26, 26, 1, 152064, 0x03d36000 +0, 27, 27, 1, 152064, 0xbf7d49da +0, 28, 28, 1, 152064, 0x77336d09 +0, 29, 29, 1, 152064, 0xca8be5a9 +0, 30, 30, 1, 152064, 0xe57c0b08 +0, 31, 31, 1, 152064, 0xbe77c093 +0, 32, 32, 1, 152064, 0x6bf1ff05 +0, 33, 33, 1, 152064, 0x9142babf +0, 34, 34, 1, 152064, 0x08db8e67 +0, 35, 35, 1, 152064, 0x69ac8cb6 +0, 36, 36, 1, 152064, 0xaa3b5c88 +0, 37, 37, 1, 152064, 0x9bd32638 +0, 38, 38, 1, 152064, 0x7972115a +0, 39, 39, 1, 152064, 0x5c1dd47b +0, 40, 40, 1, 152064, 0x8a196e02 +0, 41, 41, 1, 152064, 0xa89672bc +0, 42, 42, 1, 152064, 0x27b220e4 +0, 43, 43, 1, 152064, 0xfa38dc4a +0, 44, 44, 1, 152064, 0x4784c639 +0, 45, 45, 1, 152064, 0xa5e4229a +0, 46, 46, 1, 152064, 0xa986bdfc +0, 47, 47, 1, 152064, 0x2951b47b +0, 48, 48, 1, 152064, 0x4df404a6 +0, 49, 49, 1, 152064, 0xc75155e8 +0, 50, 50, 1, 152064, 0xfc05248c +0, 51, 51, 1, 152064, 0x5d53da10 +0, 52, 52, 1, 152064, 0x284376ec +0, 53, 53, 1, 152064, 0x19fce380 +0, 54, 54, 1, 152064, 0x876be6c9 +0, 55, 55, 1, 152064, 0x39eb8ff9 +0, 56, 56, 1, 152064, 0x289c9543 +0, 57, 57, 1, 152064, 0x24dd2356 +0, 58, 58, 1, 152064, 0x1dc17d3c +0, 59, 59, 1, 152064, 0xd17c00ac +0, 60, 60, 1, 152064, 0xc2ad54de +0, 61, 61, 1, 152064, 0xbe11ee2f +0, 62, 62, 1, 152064, 0x3db9dc89 +0, 63, 63, 1, 152064, 0xac0d7bc2 +0, 64, 64, 1, 152064, 0x8dab2dde +0, 65, 65, 1, 152064, 0x566ad225 +0, 66, 66, 1, 152064, 0x587c7853 +0, 67, 67, 1, 152064, 0x601c9c80 +0, 68, 68, 1, 152064, 0x2afaf751 +0, 69, 69, 1, 152064, 0x1c9f7e3a +0, 70, 70, 1, 152064, 0x899475bf +0, 71, 71, 1, 152064, 0x0d65c7d9 +0, 72, 72, 1, 152064, 0xafd63d12 +0, 73, 73, 1, 152064, 0x162e62b9 +0, 74, 74, 1, 152064, 0x5c9554be +0, 75, 75, 1, 152064, 0x35fbdaa2 +0, 76, 76, 1, 152064, 0x6438cbd8 +0, 77, 77, 1, 152064, 0xde0772c9 +0, 78, 78, 1, 152064, 0x79f82854 +0, 79, 79, 1, 152064, 0x86957840 +0, 80, 80, 1, 152064, 0xd9468cbf +0, 81, 81, 1, 152064, 0x23e74609 +0, 82, 82, 1, 152064, 0x3919a146 +0, 83, 83, 1, 152064, 0xd641078b +0, 84, 84, 1, 152064, 0x24397220 +0, 85, 85, 1, 152064, 0xe7fc3a7c +0, 86, 86, 1, 152064, 0x3997154a +0, 87, 87, 1, 152064, 0x2af3952c +0, 88, 88, 1, 152064, 0x274ac07a +0, 89, 89, 1, 152064, 0x288f7b09 +0, 90, 90, 1, 152064, 0xe6f9b022 +0, 91, 91, 1, 152064, 0xf09e2fbb +0, 92, 92, 1, 152064, 0x7244e477 +0, 93, 93, 1, 152064, 0x0dfc72eb +0, 94, 94, 1, 152064, 0x0322b21f +0, 95, 95, 1, 152064, 0x18b08205 +0, 96, 96, 1, 152064, 0x6606153e +0, 97, 97, 1, 152064, 0x85186272 +0, 98, 98, 1, 152064, 0x3369f064 +0, 99, 99, 1, 152064, 0xbe0d5a44 +0, 100, 100, 1, 152064, 0x320258bb +0, 101, 101, 1, 152064, 0x4d6fb091 +0, 102, 102, 1, 152064, 0xc9bbf5e7 +0, 103, 103, 1, 152064, 0x0aa1b69b +0, 104, 104, 1, 152064, 0x85b9ac11 +0, 105, 105, 1, 152064, 0xb25ff818 +0, 106, 106, 1, 152064, 0xa155dc25 +0, 107, 107, 1, 152064, 0xa8e03bfd +0, 108, 108, 1, 152064, 0x0a862956 +0, 109, 109, 1, 152064, 0x11b49264 +0, 110, 110, 1, 152064, 0xa94e664e +0, 111, 111, 1, 152064, 0x330e0fa2 +0, 112, 112, 1, 152064, 0xaf3d9518 +0, 113, 113, 1, 152064, 0x0836f2e8 +0, 114, 114, 1, 152064, 0xbf6dc578 +0, 115, 115, 1, 152064, 0x7b524d20 +0, 116, 116, 1, 152064, 0x9ef7677f +0, 117, 117, 1, 152064, 0xeacf3f34 +0, 118, 118, 1, 152064, 0xfb4e3dbe +0, 119, 119, 1, 152064, 0xb46e25cb +0, 120, 120, 1, 152064, 0x363c1603 +0, 121, 121, 1, 152064, 0x263fc542 +0, 122, 122, 1, 152064, 0xf106e548 +0, 123, 123, 1, 152064, 0xde43c56a +0, 124, 124, 1, 152064, 0xc2c4770a +0, 125, 125, 1, 152064, 0x122fce19 +0, 126, 126, 1, 152064, 0x3ba01434 +0, 127, 127, 1, 152064, 0x0e8ce5ee +0, 128, 128, 1, 152064, 0x6ceb82e1 +0, 129, 129, 1, 152064, 0xa23ee21c +0, 130, 130, 1, 152064, 0xc6d960f9 +0, 131, 131, 1, 152064, 0x0de15258 +0, 132, 132, 1, 152064, 0x187b0333 +0, 133, 133, 1, 152064, 0x92e6582f +0, 134, 134, 1, 152064, 0xb9586ce0 +0, 135, 135, 1, 152064, 0xefd803b5 +0, 136, 136, 1, 152064, 0x24eafb29 +0, 137, 137, 1, 152064, 0x20c73b14 +0, 138, 138, 1, 152064, 0xbd7ceaaa +0, 139, 139, 1, 152064, 0x775216c8 +0, 140, 140, 1, 152064, 0xa08971c7 +0, 141, 141, 1, 152064, 0xef0ee865 +0, 142, 142, 1, 152064, 0x9ac61c2f +0, 143, 143, 1, 152064, 0x52ae8ea9 +0, 144, 144, 1, 152064, 0x06571c14 +0, 145, 145, 1, 152064, 0x6e78ad33 +0, 146, 146, 1, 152064, 0xad01c627 +0, 147, 147, 1, 152064, 0xbfe074d3 +0, 148, 148, 1, 152064, 0x9357a183 +0, 149, 149, 1, 152064, 0x8de7767f +0, 150, 150, 1, 152064, 0xa5e6e76e +0, 151, 151, 1, 152064, 0xa6f646fe +0, 152, 152, 1, 152064, 0x132e99f8 +0, 153, 153, 1, 152064, 0xb79f27de +0, 154, 154, 1, 152064, 0x36d3cdcf +0, 155, 155, 1, 152064, 0xdc938336 +0, 156, 156, 1, 152064, 0xacaa3a7f +0, 157, 157, 1, 152064, 0xc61a37fd +0, 158, 158, 1, 152064, 0x4fe1ddf0 +0, 159, 159, 1, 152064, 0xc0f7d660 +0, 160, 160, 1, 152064, 0xd72458ea +0, 161, 161, 1, 152064, 0x6978d123 +0, 162, 162, 1, 152064, 0x64e60ccf +0, 163, 163, 1, 152064, 0xaa07004c +0, 164, 164, 1, 152064, 0x07cd1064 +0, 165, 165, 1, 152064, 0xa82320e5 +0, 166, 166, 1, 152064, 0xaedd8d30 +0, 167, 167, 1, 152064, 0x79b082ea +0, 168, 168, 1, 152064, 0x9ed800ab +0, 169, 169, 1, 152064, 0xde592bb4 +0, 170, 170, 1, 152064, 0xd966df88 +0, 171, 171, 1, 152064, 0xf921988a +0, 172, 172, 1, 152064, 0x557ad9ae +0, 173, 173, 1, 152064, 0xc3f31a9a +0, 174, 174, 1, 152064, 0x65248561 +0, 175, 175, 1, 152064, 0x63df4aa6 +0, 176, 176, 1, 152064, 0x618da0a9 +0, 177, 177, 1, 152064, 0xe6f1c435 +0, 178, 178, 1, 152064, 0x9f90c38f +0, 179, 179, 1, 152064, 0xd2853e14 +0, 180, 180, 1, 152064, 0x6e0268a9 +0, 181, 181, 1, 152064, 0x393712d1 +0, 182, 182, 1, 152064, 0x470da25f +0, 183, 183, 1, 152064, 0xaf55cb3d +0, 184, 184, 1, 152064, 0x6935b8b9 +0, 185, 185, 1, 152064, 0x5409a15f +0, 186, 186, 1, 152064, 0x09073fee +0, 187, 187, 1, 152064, 0xfb274e82 +0, 188, 188, 1, 152064, 0x1a770581 +0, 189, 189, 1, 152064, 0x17277d0d +0, 190, 190, 1, 152064, 0xd4dcd982 +0, 191, 191, 1, 152064, 0x6b04eaf3 +0, 192, 192, 1, 152064, 0x8a3d822e +0, 193, 193, 1, 152064, 0x1b971ec9 +0, 194, 194, 1, 152064, 0x14e0c0f6 +0, 195, 195, 1, 152064, 0x00667450 +0, 196, 196, 1, 152064, 0xd2385902 +0, 197, 197, 1, 152064, 0x905da6ab +0, 198, 198, 1, 152064, 0xa3ffb18b +0, 199, 199, 1, 152064, 0x10d48b19 +0, 200, 200, 1, 152064, 0xb2c7a3bd +0, 201, 201, 1, 152064, 0x45593e96 +0, 202, 202, 1, 152064, 0x47a0b60c +0, 203, 203, 1, 152064, 0x68c6d1b9 +0, 204, 204, 1, 152064, 0xbc881fcc +0, 205, 205, 1, 152064, 0x422cc6f2 +0, 206, 206, 1, 152064, 0x9b686410 +0, 207, 207, 1, 152064, 0x35dc5e86 +0, 208, 208, 1, 152064, 0x247bedaa +0, 209, 209, 1, 152064, 0x22b76fd1 +0, 210, 210, 1, 152064, 0x67cc7a75 +0, 211, 211, 1, 152064, 0xa197521e +0, 212, 212, 1, 152064, 0x428c8662 +0, 213, 213, 1, 152064, 0x33dc2c73 +0, 214, 214, 1, 152064, 0x5b538903 +0, 215, 215, 1, 152064, 0x3c4176b6 +0, 216, 216, 1, 152064, 0x774364ba +0, 217, 217, 1, 152064, 0xf237d03e +0, 218, 218, 1, 152064, 0xac8746fb +0, 219, 219, 1, 152064, 0x6b306a84 +0, 220, 220, 1, 152064, 0xa2ace513 +0, 221, 221, 1, 152064, 0x709c9be7 +0, 222, 222, 1, 152064, 0x2403f373 +0, 223, 223, 1, 152064, 0x147bf717 +0, 224, 224, 1, 152064, 0xe58964c8 +0, 225, 225, 1, 152064, 0xa0da36fc +0, 226, 226, 1, 152064, 0x1ac1355c +0, 227, 227, 1, 152064, 0x8a31c9f2 +0, 228, 228, 1, 152064, 0x42ba205c +0, 229, 229, 1, 152064, 0xa11b3575 +0, 230, 230, 1, 152064, 0xcb35207c +0, 231, 231, 1, 152064, 0x528f6189 +0, 232, 232, 1, 152064, 0x34f05bd7 +0, 233, 233, 1, 152064, 0x72317356 +0, 234, 234, 1, 152064, 0xaabd5028 +0, 235, 235, 1, 152064, 0x13dbeb7b +0, 236, 236, 1, 152064, 0x62f1e8a8 +0, 237, 237, 1, 152064, 0x1723bfcd +0, 238, 238, 1, 152064, 0x5c083c00 +0, 239, 239, 1, 152064, 0x52137894 +0, 240, 240, 1, 152064, 0xef1e082c +0, 241, 241, 1, 152064, 0x664b3d53 +0, 242, 242, 1, 152064, 0x2eb9b296 +0, 243, 243, 1, 152064, 0xd0ca511e +0, 244, 244, 1, 152064, 0x012d4724 +0, 245, 245, 1, 152064, 0xa847f5af +0, 246, 246, 1, 152064, 0x483a2fde +0, 247, 247, 1, 152064, 0xd1ab0257 +0, 248, 248, 1, 152064, 0x414692c7 +0, 249, 249, 1, 152064, 0x0b79df88 +0, 250, 250, 1, 152064, 0xdaa2c4a3 +0, 251, 251, 1, 152064, 0xd1b44500 +0, 252, 252, 1, 152064, 0xfd3d2cf3 +0, 253, 253, 1, 152064, 0xfdc0f748 +0, 254, 254, 1, 152064, 0xce762a2a +0, 255, 255, 1, 152064, 0x08b63572 +0, 256, 256, 1, 152064, 0x5a46a38d +0, 257, 257, 1, 152064, 0x03cee9c0 +0, 258, 258, 1, 152064, 0x9ee45473 +0, 259, 259, 1, 152064, 0x5a432386 +0, 260, 260, 1, 152064, 0x54c83d87 +0, 261, 261, 1, 152064, 0xc9caa1de +0, 262, 262, 1, 152064, 0xa28367f1 +0, 263, 263, 1, 152064, 0x2607cdf1 +0, 264, 264, 1, 152064, 0x06baa8de +0, 265, 265, 1, 152064, 0xf5346e32 +0, 266, 266, 1, 152064, 0x6d3e732b +0, 267, 267, 1, 152064, 0x798c584b +0, 268, 268, 1, 152064, 0x4076c948 +0, 269, 269, 1, 152064, 0x868cf63a +0, 270, 270, 1, 152064, 0x23107ac5 +0, 271, 271, 1, 152064, 0x306f3fe2 +0, 272, 272, 1, 152064, 0xbd1d71d6 +0, 273, 273, 1, 152064, 0x1429545f +0, 274, 274, 1, 152064, 0xaded29aa +0, 275, 275, 1, 152064, 0x9b455a94 +0, 276, 276, 1, 152064, 0xb3774ce7 +0, 277, 277, 1, 152064, 0x92580986 +0, 278, 278, 1, 152064, 0x0eae2f95 +0, 279, 279, 1, 152064, 0x599208b2 +0, 280, 280, 1, 152064, 0x4804c04c +0, 281, 281, 1, 152064, 0x5f730e8f +0, 282, 282, 1, 152064, 0x3e501d1e +0, 283, 283, 1, 152064, 0x32100740 +0, 284, 284, 1, 152064, 0x62226ff8 +0, 285, 285, 1, 152064, 0x7683b622 +0, 286, 286, 1, 152064, 0xc3e0aec1 +0, 287, 287, 1, 152064, 0xfac12608 +0, 288, 288, 1, 152064, 0xb21a5781 +0, 289, 289, 1, 152064, 0x8f1e4964 +0, 290, 290, 1, 152064, 0x0f62dd6e +0, 291, 291, 1, 152064, 0xac062ac4 +0, 292, 292, 1, 152064, 0x1b320f7a +0, 293, 293, 1, 152064, 0x346e7211 +0, 294, 294, 1, 152064, 0xe47592f3 +0, 295, 295, 1, 152064, 0xa3a7919c +0, 296, 296, 1, 152064, 0xa3580fa6 +0, 297, 297, 1, 152064, 0xc73430c1 +0, 298, 298, 1, 152064, 0x994a2c18 +0, 299, 299, 1, 152064, 0x0b5d8d45 +0, 300, 300, 1, 152064, 0x9eed5109 diff --git a/tests/ref/fate/h264-conformance-mr3_tandberg_b b/tests/ref/fate/h264-conformance-mr3_tandberg_b index b0948448c..e86d72183 100644 --- a/tests/ref/fate/h264-conformance-mr3_tandberg_b +++ b/tests/ref/fate/h264-conformance-mr3_tandberg_b @@ -12,294 +12,294 @@ 0, 6, 6, 1, 38016, 0x7cc17319 0, 7, 7, 1, 38016, 0x0f7e8cab 0, 8, 8, 1, 38016, 0x1876abee -0, 9, 9, 1, 38016, 0xda748c2f -0, 10, 10, 1, 38016, 0x7b4dbff0 -0, 11, 11, 1, 38016, 0xd4a1b24a -0, 12, 12, 1, 38016, 0x714cb4cc -0, 13, 13, 1, 38016, 0x2c6d80f0 -0, 14, 14, 1, 38016, 0x92266151 -0, 15, 15, 1, 38016, 0x6b766a23 -0, 16, 16, 1, 38016, 0xb24f7efe -0, 17, 17, 1, 38016, 0x8410838e -0, 18, 18, 1, 38016, 0x67fe872a -0, 19, 19, 1, 38016, 0x55b49d36 -0, 20, 20, 1, 38016, 0x7a1c9c41 -0, 21, 21, 1, 38016, 0xb4818e0e -0, 22, 22, 1, 38016, 0x25f6683c -0, 23, 23, 1, 38016, 0xe4d141a4 -0, 24, 24, 1, 38016, 0x808216ad -0, 25, 25, 1, 38016, 0x2acf0baf -0, 26, 26, 1, 38016, 0xf3de13c4 -0, 27, 27, 1, 38016, 0x5f412187 -0, 28, 28, 1, 38016, 0xb31a340a -0, 29, 29, 1, 38016, 0x019d42d1 -0, 30, 30, 1, 38016, 0xeeb94b9b -0, 31, 31, 1, 38016, 0xef55472e -0, 32, 32, 1, 38016, 0xdb5e3697 -0, 33, 33, 1, 38016, 0x8565303e -0, 34, 34, 1, 38016, 0x5f9c2c1b -0, 35, 35, 1, 38016, 0xeb3d27f4 -0, 36, 36, 1, 38016, 0x9a43282d -0, 37, 37, 1, 38016, 0xe04720c6 -0, 38, 38, 1, 38016, 0x19cc0eba -0, 39, 39, 1, 38016, 0x218efeb6 -0, 40, 40, 1, 38016, 0x7733f491 -0, 41, 41, 1, 38016, 0x7f3bede9 -0, 42, 42, 1, 38016, 0x49c5ec0d -0, 43, 43, 1, 38016, 0x803cf19e -0, 44, 44, 1, 38016, 0x31de0d3f -0, 45, 45, 1, 38016, 0xa7e30426 -0, 46, 46, 1, 38016, 0xba37f068 -0, 47, 47, 1, 38016, 0x2842bdf8 -0, 48, 48, 1, 38016, 0x76df97dc -0, 49, 49, 1, 38016, 0xf3246d26 -0, 50, 50, 1, 38016, 0x0a384d72 -0, 51, 51, 1, 38016, 0x40964f41 -0, 52, 52, 1, 38016, 0x46364324 -0, 53, 53, 1, 38016, 0x7cbf3db4 -0, 54, 54, 1, 38016, 0x7a223bec -0, 55, 55, 1, 38016, 0x458651c1 -0, 56, 56, 1, 38016, 0xb82d7e3c -0, 57, 57, 1, 38016, 0x0f50a55d -0, 58, 58, 1, 38016, 0xc306cae4 -0, 59, 59, 1, 38016, 0x9d6ddfcb -0, 60, 60, 1, 38016, 0xb602e8e9 -0, 61, 61, 1, 38016, 0xbf0ae386 -0, 62, 62, 1, 38016, 0x0a8bd46e -0, 63, 63, 1, 38016, 0xd437c5c1 -0, 64, 64, 1, 38016, 0xd61d9959 -0, 65, 65, 1, 38016, 0x70639b56 -0, 66, 66, 1, 38016, 0x36fd407b -0, 67, 67, 1, 38016, 0x58ce3ddd -0, 68, 68, 1, 38016, 0x86cc1d8c -0, 69, 69, 1, 38016, 0xee422dc2 -0, 70, 70, 1, 38016, 0xab475639 -0, 71, 71, 1, 38016, 0xc1327ad8 -0, 72, 72, 1, 38016, 0x63d196d4 -0, 73, 73, 1, 38016, 0x1aba8ebd -0, 74, 74, 1, 38016, 0x74a269ac -0, 75, 75, 1, 38016, 0x267f3563 -0, 76, 76, 1, 38016, 0xa18ff180 -0, 77, 77, 1, 38016, 0x70c9c9fd -0, 78, 78, 1, 38016, 0xa6c59f9c -0, 79, 79, 1, 38016, 0xd7cd8927 -0, 80, 80, 1, 38016, 0xd30b7345 -0, 81, 81, 1, 38016, 0x679a4dda -0, 82, 82, 1, 38016, 0xeb0562de -0, 83, 83, 1, 38016, 0xdd7d6cdb -0, 84, 84, 1, 38016, 0xd6e26b73 -0, 85, 85, 1, 38016, 0xa65a860f -0, 86, 86, 1, 38016, 0xae95c71e -0, 87, 87, 1, 38016, 0x1a89ca86 -0, 88, 88, 1, 38016, 0xa33ecee6 -0, 89, 89, 1, 38016, 0x821da6cb -0, 90, 90, 1, 38016, 0xf0e1612f -0, 91, 91, 1, 38016, 0x67b8516b -0, 92, 92, 1, 38016, 0x62f965bc -0, 93, 93, 1, 38016, 0xd1917aa6 -0, 94, 94, 1, 38016, 0xe72db54d -0, 95, 95, 1, 38016, 0x9b64e721 -0, 96, 96, 1, 38016, 0xa819efda -0, 97, 97, 1, 38016, 0xeacfdacb -0, 98, 98, 1, 38016, 0x52f235e1 -0, 99, 99, 1, 38016, 0x2b512cb8 -0, 100, 100, 1, 38016, 0xaac73fb3 -0, 101, 101, 1, 38016, 0x7d2d504f -0, 102, 102, 1, 38016, 0x396d503a -0, 103, 103, 1, 38016, 0x97905235 -0, 104, 104, 1, 38016, 0xf0056693 -0, 105, 105, 1, 38016, 0x728a6a9e -0, 106, 106, 1, 38016, 0x0eed7824 -0, 107, 107, 1, 38016, 0x59506237 -0, 108, 108, 1, 38016, 0xd4304c93 -0, 109, 109, 1, 38016, 0x7e663ee8 -0, 110, 110, 1, 38016, 0x0ebc2d11 -0, 111, 111, 1, 38016, 0x52db2112 -0, 112, 112, 1, 38016, 0x74aa1815 -0, 113, 113, 1, 38016, 0x57a60dc6 -0, 114, 114, 1, 38016, 0x86e9fa32 -0, 115, 115, 1, 38016, 0x67e8ff09 -0, 116, 116, 1, 38016, 0x26e8f7ea -0, 117, 117, 1, 38016, 0x183dff56 -0, 118, 118, 1, 38016, 0xa470af8d -0, 119, 119, 1, 38016, 0xe017d594 -0, 120, 120, 1, 38016, 0xb899d48b -0, 121, 121, 1, 38016, 0x0d3bc5f7 -0, 122, 122, 1, 38016, 0xd68bbb0d -0, 123, 123, 1, 38016, 0x8bf5b4cb -0, 124, 124, 1, 38016, 0x6bfcaa47 -0, 125, 125, 1, 38016, 0x29a9b01b -0, 126, 126, 1, 38016, 0xcdedbdb7 -0, 127, 127, 1, 38016, 0xdb5ad9c3 -0, 128, 128, 1, 38016, 0x468aeef6 -0, 129, 129, 1, 38016, 0xdc2b143e -0, 130, 130, 1, 38016, 0x6776277c -0, 131, 131, 1, 38016, 0xb78d5294 -0, 132, 132, 1, 38016, 0x1dfb63ab -0, 133, 133, 1, 38016, 0xbd1f99bc -0, 134, 134, 1, 38016, 0xde16b89a -0, 135, 135, 1, 38016, 0xbf46edca -0, 136, 136, 1, 38016, 0x6306e8c4 -0, 137, 137, 1, 38016, 0x7b09d224 -0, 138, 138, 1, 38016, 0xfea1aff6 -0, 139, 139, 1, 38016, 0x183686b0 -0, 140, 140, 1, 38016, 0x665a61ff -0, 141, 141, 1, 38016, 0xc8af42d1 -0, 142, 142, 1, 38016, 0xe2326bc1 -0, 143, 143, 1, 38016, 0x56dbde82 -0, 144, 144, 1, 38016, 0xa0254f97 -0, 145, 145, 1, 38016, 0x3b74a0b4 -0, 146, 146, 1, 38016, 0x9aee9b7f -0, 147, 147, 1, 38016, 0xd94b6133 -0, 148, 148, 1, 38016, 0x5819f795 -0, 149, 149, 1, 38016, 0xc45a8c02 -0, 150, 150, 1, 38016, 0x2f9204a0 -0, 151, 151, 1, 38016, 0xbe09e051 -0, 152, 152, 1, 38016, 0xb542badd -0, 153, 153, 1, 38016, 0x23bd9e00 -0, 154, 154, 1, 38016, 0x4f338d3d -0, 155, 155, 1, 38016, 0x8c91e8f3 -0, 156, 156, 1, 38016, 0xa7347d57 -0, 157, 157, 1, 38016, 0x6d91de4d -0, 158, 158, 1, 38016, 0x3443d936 -0, 159, 159, 1, 38016, 0x9d25b4e2 -0, 160, 160, 1, 38016, 0xd93cd4b3 -0, 161, 161, 1, 38016, 0xa1c9e9a0 -0, 162, 162, 1, 38016, 0x1482f220 -0, 163, 163, 1, 38016, 0x1295f270 -0, 164, 164, 1, 38016, 0x399ae9da -0, 165, 165, 1, 38016, 0x85dcdf28 -0, 166, 166, 1, 38016, 0x4207b9e5 -0, 167, 167, 1, 38016, 0xad1c9d75 -0, 168, 168, 1, 38016, 0x4a266c14 -0, 169, 169, 1, 38016, 0x3afc4508 -0, 170, 170, 1, 38016, 0x2b1b2385 -0, 171, 171, 1, 38016, 0x738f005f -0, 172, 172, 1, 38016, 0xfec3d833 -0, 173, 173, 1, 38016, 0x3f7f6ae9 -0, 174, 174, 1, 38016, 0xd8551823 -0, 175, 175, 1, 38016, 0x6df03570 -0, 176, 176, 1, 38016, 0x767c3054 -0, 177, 177, 1, 38016, 0x89bd342c -0, 178, 178, 1, 38016, 0x77ba806c -0, 179, 179, 1, 38016, 0x1c98005c -0, 180, 180, 1, 38016, 0xa13ce2a3 -0, 181, 181, 1, 38016, 0x1be59915 -0, 182, 182, 1, 38016, 0x279c6027 -0, 183, 183, 1, 38016, 0x96ac11a2 -0, 184, 184, 1, 38016, 0x3ae95131 -0, 185, 185, 1, 38016, 0xae19f7fe -0, 186, 186, 1, 38016, 0xcde4efe6 -0, 187, 187, 1, 38016, 0x5ecc3f7a -0, 188, 188, 1, 38016, 0x79645152 -0, 189, 189, 1, 38016, 0x1ee2e89f -0, 190, 190, 1, 38016, 0x91d34bb4 -0, 191, 191, 1, 38016, 0xf019d464 -0, 192, 192, 1, 38016, 0x8eb07205 -0, 193, 193, 1, 38016, 0x5399bb5b -0, 194, 194, 1, 38016, 0x61f0c77a -0, 195, 195, 1, 38016, 0xb2bd8726 -0, 196, 196, 1, 38016, 0x47b89243 -0, 197, 197, 1, 38016, 0xebfe4d76 -0, 198, 198, 1, 38016, 0xe8f87d91 -0, 199, 199, 1, 38016, 0x5e9fb239 -0, 200, 200, 1, 38016, 0x357ca1f8 -0, 201, 201, 1, 38016, 0x757d2e02 -0, 202, 202, 1, 38016, 0x40672e7c -0, 203, 203, 1, 38016, 0xd966abca -0, 204, 204, 1, 38016, 0xe98d0d47 -0, 205, 205, 1, 38016, 0x341babf5 -0, 206, 206, 1, 38016, 0xd12d5a0c -0, 207, 207, 1, 38016, 0xea2f99ab -0, 208, 208, 1, 38016, 0x14bce88e -0, 209, 209, 1, 38016, 0xe4bda9e8 -0, 210, 210, 1, 38016, 0x2c57ec89 -0, 211, 211, 1, 38016, 0x28bbb83e -0, 212, 212, 1, 38016, 0xf8444b54 -0, 213, 213, 1, 38016, 0x3aba03cd -0, 214, 214, 1, 38016, 0x373daa20 -0, 215, 215, 1, 38016, 0x69586597 -0, 216, 216, 1, 38016, 0xc0c70d53 -0, 217, 217, 1, 38016, 0x76a5df5a -0, 218, 218, 1, 38016, 0x1afde8f0 -0, 219, 219, 1, 38016, 0x9638285a -0, 220, 220, 1, 38016, 0x9f0686c0 -0, 221, 221, 1, 38016, 0xc65b2238 -0, 222, 222, 1, 38016, 0x0d61b610 -0, 223, 223, 1, 38016, 0x78e14e1f -0, 224, 224, 1, 38016, 0xcf80ac4a -0, 225, 225, 1, 38016, 0xe094083d -0, 226, 226, 1, 38016, 0xee5e612e -0, 227, 227, 1, 38016, 0x51cdad9d -0, 228, 228, 1, 38016, 0xae41100e -0, 229, 229, 1, 38016, 0x77558f58 -0, 230, 230, 1, 38016, 0xb9503b95 -0, 231, 231, 1, 38016, 0xb71dffeb -0, 232, 232, 1, 38016, 0x1872e3e6 -0, 233, 233, 1, 38016, 0x29c3d252 -0, 234, 234, 1, 38016, 0x1c77c6ec -0, 235, 235, 1, 38016, 0x26feb194 -0, 236, 236, 1, 38016, 0x3307c3c4 -0, 237, 237, 1, 38016, 0x8e5a8080 -0, 238, 238, 1, 38016, 0x933472f7 -0, 239, 239, 1, 38016, 0xd4768d84 -0, 240, 240, 1, 38016, 0x3324485f -0, 241, 241, 1, 38016, 0xd50af078 -0, 242, 242, 1, 38016, 0x53820752 -0, 243, 243, 1, 38016, 0xbe7f1c47 -0, 244, 244, 1, 38016, 0xe43d3a34 -0, 245, 245, 1, 38016, 0x57194b82 -0, 246, 246, 1, 38016, 0x68a052ed -0, 247, 247, 1, 38016, 0x5c898052 -0, 248, 248, 1, 38016, 0x7104a6ad -0, 249, 249, 1, 38016, 0x1676b5e8 -0, 250, 250, 1, 38016, 0xe1cfd375 -0, 251, 251, 1, 38016, 0x16fede04 -0, 252, 252, 1, 38016, 0xca49dd4a -0, 253, 253, 1, 38016, 0x7b98d9d1 -0, 254, 254, 1, 38016, 0x4020d210 -0, 255, 255, 1, 38016, 0x62c5d1e4 -0, 256, 256, 1, 38016, 0x756abdb4 -0, 257, 257, 1, 38016, 0x558fb00f -0, 258, 258, 1, 38016, 0x4ab0b1f1 -0, 259, 259, 1, 38016, 0x7c9fb0c2 -0, 260, 260, 1, 38016, 0xcecfbdd0 -0, 261, 261, 1, 38016, 0x70e6d174 -0, 262, 262, 1, 38016, 0x83d7ddde -0, 263, 263, 1, 38016, 0xbbcde2d9 -0, 264, 264, 1, 38016, 0xc89eeaef -0, 265, 265, 1, 38016, 0x8565e15c -0, 266, 266, 1, 38016, 0x28e0db24 -0, 267, 267, 1, 38016, 0x1d9dd334 -0, 268, 268, 1, 38016, 0xce02c452 -0, 269, 269, 1, 38016, 0xe29dbd0c -0, 270, 270, 1, 38016, 0x4aa3b638 -0, 271, 271, 1, 38016, 0x5533c135 -0, 272, 272, 1, 38016, 0x6c57b65f -0, 273, 273, 1, 38016, 0x23d3b851 -0, 274, 274, 1, 38016, 0xd8cbb960 -0, 275, 275, 1, 38016, 0x02edb916 -0, 276, 276, 1, 38016, 0xa622bd42 -0, 277, 277, 1, 38016, 0x4ba5be1c -0, 278, 278, 1, 38016, 0xe69bb625 -0, 279, 279, 1, 38016, 0xbca5b292 -0, 280, 280, 1, 38016, 0xde38b1c8 -0, 281, 281, 1, 38016, 0xe9e3b617 -0, 282, 282, 1, 38016, 0x216cc574 -0, 283, 283, 1, 38016, 0x3780c5ad -0, 284, 284, 1, 38016, 0x5531e3f9 -0, 285, 285, 1, 38016, 0xe2c5f5d4 -0, 286, 286, 1, 38016, 0x24cefc6e -0, 287, 287, 1, 38016, 0xa3ce003d -0, 288, 288, 1, 38016, 0x42d01c9e -0, 289, 289, 1, 38016, 0xbfc13689 -0, 290, 290, 1, 38016, 0x122647a9 -0, 291, 291, 1, 38016, 0xe45254da -0, 292, 292, 1, 38016, 0xad955b0c -0, 293, 293, 1, 38016, 0x4b086abb -0, 294, 294, 1, 38016, 0xd4857b8c -0, 295, 295, 1, 38016, 0xa71594ce -0, 296, 296, 1, 38016, 0x04e4a73d -0, 297, 297, 1, 38016, 0x295abf63 -0, 298, 298, 1, 38016, 0xbe4ed5dd -0, 299, 299, 1, 38016, 0x087bcf64 +0, 10, 10, 1, 38016, 0xda748c2f +0, 11, 11, 1, 38016, 0x7b4dbff0 +0, 12, 12, 1, 38016, 0xd4a1b24a +0, 13, 13, 1, 38016, 0x714cb4cc +0, 14, 14, 1, 38016, 0x2c6d80f0 +0, 15, 15, 1, 38016, 0x92266151 +0, 16, 16, 1, 38016, 0x6b766a23 +0, 17, 17, 1, 38016, 0xb24f7efe +0, 18, 18, 1, 38016, 0x8410838e +0, 19, 19, 1, 38016, 0x67fe872a +0, 20, 20, 1, 38016, 0x55b49d36 +0, 21, 21, 1, 38016, 0x7a1c9c41 +0, 22, 22, 1, 38016, 0xb4818e0e +0, 23, 23, 1, 38016, 0x25f6683c +0, 24, 24, 1, 38016, 0xe4d141a4 +0, 25, 25, 1, 38016, 0x808216ad +0, 26, 26, 1, 38016, 0x2acf0baf +0, 27, 27, 1, 38016, 0xf3de13c4 +0, 28, 28, 1, 38016, 0x5f412187 +0, 29, 29, 1, 38016, 0xb31a340a +0, 30, 30, 1, 38016, 0x019d42d1 +0, 31, 31, 1, 38016, 0xeeb94b9b +0, 32, 32, 1, 38016, 0xef55472e +0, 33, 33, 1, 38016, 0xdb5e3697 +0, 34, 34, 1, 38016, 0x8565303e +0, 35, 35, 1, 38016, 0x5f9c2c1b +0, 36, 36, 1, 38016, 0xeb3d27f4 +0, 37, 37, 1, 38016, 0x9a43282d +0, 38, 38, 1, 38016, 0xe04720c6 +0, 39, 39, 1, 38016, 0x19cc0eba +0, 40, 40, 1, 38016, 0x218efeb6 +0, 41, 41, 1, 38016, 0x7733f491 +0, 42, 42, 1, 38016, 0x7f3bede9 +0, 43, 43, 1, 38016, 0x49c5ec0d +0, 44, 44, 1, 38016, 0x803cf19e +0, 45, 45, 1, 38016, 0x31de0d3f +0, 46, 46, 1, 38016, 0xa7e30426 +0, 47, 47, 1, 38016, 0xba37f068 +0, 48, 48, 1, 38016, 0x2842bdf8 +0, 49, 49, 1, 38016, 0x76df97dc +0, 50, 50, 1, 38016, 0xf3246d26 +0, 51, 51, 1, 38016, 0x0a384d72 +0, 52, 52, 1, 38016, 0x40964f41 +0, 53, 53, 1, 38016, 0x46364324 +0, 54, 54, 1, 38016, 0x7cbf3db4 +0, 55, 55, 1, 38016, 0x7a223bec +0, 56, 56, 1, 38016, 0x458651c1 +0, 57, 57, 1, 38016, 0xb82d7e3c +0, 58, 58, 1, 38016, 0x0f50a55d +0, 59, 59, 1, 38016, 0xc306cae4 +0, 60, 60, 1, 38016, 0x9d6ddfcb +0, 61, 61, 1, 38016, 0xb602e8e9 +0, 62, 62, 1, 38016, 0xbf0ae386 +0, 63, 63, 1, 38016, 0x0a8bd46e +0, 64, 64, 1, 38016, 0xd437c5c1 +0, 65, 65, 1, 38016, 0xd61d9959 +0, 66, 66, 1, 38016, 0x70639b56 +0, 67, 67, 1, 38016, 0x36fd407b +0, 68, 68, 1, 38016, 0x58ce3ddd +0, 69, 69, 1, 38016, 0x86cc1d8c +0, 70, 70, 1, 38016, 0xee422dc2 +0, 71, 71, 1, 38016, 0xab475639 +0, 72, 72, 1, 38016, 0xc1327ad8 +0, 73, 73, 1, 38016, 0x63d196d4 +0, 74, 74, 1, 38016, 0x1aba8ebd +0, 75, 75, 1, 38016, 0x74a269ac +0, 76, 76, 1, 38016, 0x267f3563 +0, 77, 77, 1, 38016, 0xa18ff180 +0, 78, 78, 1, 38016, 0x70c9c9fd +0, 79, 79, 1, 38016, 0xa6c59f9c +0, 80, 80, 1, 38016, 0xd7cd8927 +0, 81, 81, 1, 38016, 0xd30b7345 +0, 82, 82, 1, 38016, 0x679a4dda +0, 83, 83, 1, 38016, 0xeb0562de +0, 84, 84, 1, 38016, 0xdd7d6cdb +0, 85, 85, 1, 38016, 0xd6e26b73 +0, 86, 86, 1, 38016, 0xa65a860f +0, 87, 87, 1, 38016, 0xae95c71e +0, 88, 88, 1, 38016, 0x1a89ca86 +0, 89, 89, 1, 38016, 0xa33ecee6 +0, 90, 90, 1, 38016, 0x821da6cb +0, 91, 91, 1, 38016, 0xf0e1612f +0, 92, 92, 1, 38016, 0x67b8516b +0, 93, 93, 1, 38016, 0x62f965bc +0, 94, 94, 1, 38016, 0xd1917aa6 +0, 95, 95, 1, 38016, 0xe72db54d +0, 96, 96, 1, 38016, 0x9b64e721 +0, 97, 97, 1, 38016, 0xa819efda +0, 98, 98, 1, 38016, 0xeacfdacb +0, 99, 99, 1, 38016, 0x52f235e1 +0, 100, 100, 1, 38016, 0x2b512cb8 +0, 101, 101, 1, 38016, 0xaac73fb3 +0, 102, 102, 1, 38016, 0x7d2d504f +0, 103, 103, 1, 38016, 0x396d503a +0, 104, 104, 1, 38016, 0x97905235 +0, 105, 105, 1, 38016, 0xf0056693 +0, 106, 106, 1, 38016, 0x728a6a9e +0, 107, 107, 1, 38016, 0x0eed7824 +0, 108, 108, 1, 38016, 0x59506237 +0, 109, 109, 1, 38016, 0xd4304c93 +0, 110, 110, 1, 38016, 0x7e663ee8 +0, 111, 111, 1, 38016, 0x0ebc2d11 +0, 112, 112, 1, 38016, 0x52db2112 +0, 113, 113, 1, 38016, 0x74aa1815 +0, 114, 114, 1, 38016, 0x57a60dc6 +0, 115, 115, 1, 38016, 0x86e9fa32 +0, 116, 116, 1, 38016, 0x67e8ff09 +0, 117, 117, 1, 38016, 0x26e8f7ea +0, 118, 118, 1, 38016, 0x183dff56 +0, 119, 119, 1, 38016, 0xa470af8d +0, 120, 120, 1, 38016, 0xe017d594 +0, 121, 121, 1, 38016, 0xb899d48b +0, 122, 122, 1, 38016, 0x0d3bc5f7 +0, 123, 123, 1, 38016, 0xd68bbb0d +0, 124, 124, 1, 38016, 0x8bf5b4cb +0, 125, 125, 1, 38016, 0x6bfcaa47 +0, 126, 126, 1, 38016, 0x29a9b01b +0, 127, 127, 1, 38016, 0xcdedbdb7 +0, 128, 128, 1, 38016, 0xdb5ad9c3 +0, 129, 129, 1, 38016, 0x468aeef6 +0, 130, 130, 1, 38016, 0xdc2b143e +0, 131, 131, 1, 38016, 0x6776277c +0, 132, 132, 1, 38016, 0xb78d5294 +0, 133, 133, 1, 38016, 0x1dfb63ab +0, 134, 134, 1, 38016, 0xbd1f99bc +0, 135, 135, 1, 38016, 0xde16b89a +0, 136, 136, 1, 38016, 0xbf46edca +0, 137, 137, 1, 38016, 0x6306e8c4 +0, 138, 138, 1, 38016, 0x7b09d224 +0, 139, 139, 1, 38016, 0xfea1aff6 +0, 140, 140, 1, 38016, 0x183686b0 +0, 141, 141, 1, 38016, 0x665a61ff +0, 142, 142, 1, 38016, 0xc8af42d1 +0, 143, 143, 1, 38016, 0xe2326bc1 +0, 144, 144, 1, 38016, 0x56dbde82 +0, 145, 145, 1, 38016, 0xa0254f97 +0, 146, 146, 1, 38016, 0x3b74a0b4 +0, 147, 147, 1, 38016, 0x9aee9b7f +0, 148, 148, 1, 38016, 0xd94b6133 +0, 149, 149, 1, 38016, 0x5819f795 +0, 150, 150, 1, 38016, 0xc45a8c02 +0, 151, 151, 1, 38016, 0x2f9204a0 +0, 152, 152, 1, 38016, 0xbe09e051 +0, 153, 153, 1, 38016, 0xb542badd +0, 154, 154, 1, 38016, 0x23bd9e00 +0, 155, 155, 1, 38016, 0x4f338d3d +0, 156, 156, 1, 38016, 0x8c91e8f3 +0, 157, 157, 1, 38016, 0xa7347d57 +0, 158, 158, 1, 38016, 0x6d91de4d +0, 159, 159, 1, 38016, 0x3443d936 +0, 160, 160, 1, 38016, 0x9d25b4e2 +0, 161, 161, 1, 38016, 0xd93cd4b3 +0, 162, 162, 1, 38016, 0xa1c9e9a0 +0, 163, 163, 1, 38016, 0x1482f220 +0, 164, 164, 1, 38016, 0x1295f270 +0, 165, 165, 1, 38016, 0x399ae9da +0, 166, 166, 1, 38016, 0x85dcdf28 +0, 167, 167, 1, 38016, 0x4207b9e5 +0, 168, 168, 1, 38016, 0xad1c9d75 +0, 169, 169, 1, 38016, 0x4a266c14 +0, 170, 170, 1, 38016, 0x3afc4508 +0, 171, 171, 1, 38016, 0x2b1b2385 +0, 172, 172, 1, 38016, 0x738f005f +0, 173, 173, 1, 38016, 0xfec3d833 +0, 174, 174, 1, 38016, 0x3f7f6ae9 +0, 175, 175, 1, 38016, 0xd8551823 +0, 176, 176, 1, 38016, 0x6df03570 +0, 177, 177, 1, 38016, 0x767c3054 +0, 178, 178, 1, 38016, 0x89bd342c +0, 179, 179, 1, 38016, 0x77ba806c +0, 180, 180, 1, 38016, 0x1c98005c +0, 181, 181, 1, 38016, 0xa13ce2a3 +0, 182, 182, 1, 38016, 0x1be59915 +0, 183, 183, 1, 38016, 0x279c6027 +0, 184, 184, 1, 38016, 0x96ac11a2 +0, 185, 185, 1, 38016, 0x3ae95131 +0, 186, 186, 1, 38016, 0xae19f7fe +0, 187, 187, 1, 38016, 0xcde4efe6 +0, 188, 188, 1, 38016, 0x5ecc3f7a +0, 189, 189, 1, 38016, 0x79645152 +0, 190, 190, 1, 38016, 0x1ee2e89f +0, 191, 191, 1, 38016, 0x91d34bb4 +0, 192, 192, 1, 38016, 0xf019d464 +0, 193, 193, 1, 38016, 0x8eb07205 +0, 194, 194, 1, 38016, 0x5399bb5b +0, 195, 195, 1, 38016, 0x61f0c77a +0, 196, 196, 1, 38016, 0xb2bd8726 +0, 197, 197, 1, 38016, 0x47b89243 +0, 198, 198, 1, 38016, 0xebfe4d76 +0, 199, 199, 1, 38016, 0xe8f87d91 +0, 200, 200, 1, 38016, 0x5e9fb239 +0, 201, 201, 1, 38016, 0x357ca1f8 +0, 202, 202, 1, 38016, 0x757d2e02 +0, 203, 203, 1, 38016, 0x40672e7c +0, 204, 204, 1, 38016, 0xd966abca +0, 205, 205, 1, 38016, 0xe98d0d47 +0, 206, 206, 1, 38016, 0x341babf5 +0, 207, 207, 1, 38016, 0xd12d5a0c +0, 208, 208, 1, 38016, 0xea2f99ab +0, 209, 209, 1, 38016, 0x14bce88e +0, 210, 210, 1, 38016, 0xe4bda9e8 +0, 211, 211, 1, 38016, 0x2c57ec89 +0, 212, 212, 1, 38016, 0x28bbb83e +0, 213, 213, 1, 38016, 0xf8444b54 +0, 214, 214, 1, 38016, 0x3aba03cd +0, 215, 215, 1, 38016, 0x373daa20 +0, 216, 216, 1, 38016, 0x69586597 +0, 217, 217, 1, 38016, 0xc0c70d53 +0, 218, 218, 1, 38016, 0x76a5df5a +0, 219, 219, 1, 38016, 0x1afde8f0 +0, 220, 220, 1, 38016, 0x9638285a +0, 221, 221, 1, 38016, 0x9f0686c0 +0, 222, 222, 1, 38016, 0xc65b2238 +0, 223, 223, 1, 38016, 0x0d61b610 +0, 224, 224, 1, 38016, 0x78e14e1f +0, 225, 225, 1, 38016, 0xcf80ac4a +0, 226, 226, 1, 38016, 0xe094083d +0, 227, 227, 1, 38016, 0xee5e612e +0, 228, 228, 1, 38016, 0x51cdad9d +0, 229, 229, 1, 38016, 0xae41100e +0, 230, 230, 1, 38016, 0x77558f58 +0, 231, 231, 1, 38016, 0xb9503b95 +0, 232, 232, 1, 38016, 0xb71dffeb +0, 233, 233, 1, 38016, 0x1872e3e6 +0, 234, 234, 1, 38016, 0x29c3d252 +0, 235, 235, 1, 38016, 0x1c77c6ec +0, 236, 236, 1, 38016, 0x26feb194 +0, 237, 237, 1, 38016, 0x3307c3c4 +0, 238, 238, 1, 38016, 0x8e5a8080 +0, 239, 239, 1, 38016, 0x933472f7 +0, 240, 240, 1, 38016, 0xd4768d84 +0, 241, 241, 1, 38016, 0x3324485f +0, 242, 242, 1, 38016, 0xd50af078 +0, 243, 243, 1, 38016, 0x53820752 +0, 244, 244, 1, 38016, 0xbe7f1c47 +0, 245, 245, 1, 38016, 0xe43d3a34 +0, 246, 246, 1, 38016, 0x57194b82 +0, 247, 247, 1, 38016, 0x68a052ed +0, 248, 248, 1, 38016, 0x5c898052 +0, 249, 249, 1, 38016, 0x7104a6ad +0, 250, 250, 1, 38016, 0x1676b5e8 +0, 251, 251, 1, 38016, 0xe1cfd375 +0, 252, 252, 1, 38016, 0x16fede04 +0, 253, 253, 1, 38016, 0xca49dd4a +0, 254, 254, 1, 38016, 0x7b98d9d1 +0, 255, 255, 1, 38016, 0x4020d210 +0, 256, 256, 1, 38016, 0x62c5d1e4 +0, 257, 257, 1, 38016, 0x756abdb4 +0, 258, 258, 1, 38016, 0x558fb00f +0, 259, 259, 1, 38016, 0x4ab0b1f1 +0, 260, 260, 1, 38016, 0x7c9fb0c2 +0, 261, 261, 1, 38016, 0xcecfbdd0 +0, 262, 262, 1, 38016, 0x70e6d174 +0, 263, 263, 1, 38016, 0x83d7ddde +0, 264, 264, 1, 38016, 0xbbcde2d9 +0, 265, 265, 1, 38016, 0xc89eeaef +0, 266, 266, 1, 38016, 0x8565e15c +0, 267, 267, 1, 38016, 0x28e0db24 +0, 268, 268, 1, 38016, 0x1d9dd334 +0, 269, 269, 1, 38016, 0xce02c452 +0, 270, 270, 1, 38016, 0xe29dbd0c +0, 271, 271, 1, 38016, 0x4aa3b638 +0, 272, 272, 1, 38016, 0x5533c135 +0, 273, 273, 1, 38016, 0x6c57b65f +0, 274, 274, 1, 38016, 0x23d3b851 +0, 275, 275, 1, 38016, 0xd8cbb960 +0, 276, 276, 1, 38016, 0x02edb916 +0, 277, 277, 1, 38016, 0xa622bd42 +0, 278, 278, 1, 38016, 0x4ba5be1c +0, 279, 279, 1, 38016, 0xe69bb625 +0, 280, 280, 1, 38016, 0xbca5b292 +0, 281, 281, 1, 38016, 0xde38b1c8 +0, 282, 282, 1, 38016, 0xe9e3b617 +0, 283, 283, 1, 38016, 0x216cc574 +0, 284, 284, 1, 38016, 0x3780c5ad +0, 285, 285, 1, 38016, 0x5531e3f9 +0, 286, 286, 1, 38016, 0xe2c5f5d4 +0, 287, 287, 1, 38016, 0x24cefc6e +0, 288, 288, 1, 38016, 0xa3ce003d +0, 289, 289, 1, 38016, 0x42d01c9e +0, 290, 290, 1, 38016, 0xbfc13689 +0, 291, 291, 1, 38016, 0x122647a9 +0, 292, 292, 1, 38016, 0xe45254da +0, 293, 293, 1, 38016, 0xad955b0c +0, 294, 294, 1, 38016, 0x4b086abb +0, 295, 295, 1, 38016, 0xd4857b8c +0, 296, 296, 1, 38016, 0xa71594ce +0, 297, 297, 1, 38016, 0x04e4a73d +0, 298, 298, 1, 38016, 0x295abf63 +0, 299, 299, 1, 38016, 0xbe4ed5dd +0, 300, 300, 1, 38016, 0x087bcf64 diff --git a/tests/ref/fate/h264-conformance-mr6_bt_b b/tests/ref/fate/h264-conformance-mr6_bt_b index 34aa8bfd4..ddfc3d98e 100644 --- a/tests/ref/fate/h264-conformance-mr6_bt_b +++ b/tests/ref/fate/h264-conformance-mr6_bt_b @@ -3,63 +3,63 @@ #codec_id 0: rawvideo #dimensions 0: 192x128 #sar 0: 0/1 -0, 0, 0, 1, 36864, 0x954464be -0, 1, 1, 1, 36864, 0xace1d90b -0, 2, 2, 1, 36864, 0x8f149f03 -0, 3, 3, 1, 36864, 0xea9b21eb -0, 4, 4, 1, 36864, 0xb51d9fe3 -0, 5, 5, 1, 36864, 0x61bd11d7 -0, 6, 6, 1, 36864, 0x9d36980f -0, 7, 7, 1, 36864, 0xa4192c5e -0, 8, 8, 1, 36864, 0x11006433 -0, 9, 9, 1, 36864, 0x4a243e46 -0, 10, 10, 1, 36864, 0x1807b5e8 -0, 11, 11, 1, 36864, 0xbe37743c -0, 12, 12, 1, 36864, 0x82491319 -0, 13, 13, 1, 36864, 0x006e9914 -0, 14, 14, 1, 36864, 0xa5261884 -0, 15, 15, 1, 36864, 0x2030c9d6 -0, 16, 16, 1, 36864, 0xc80eb1ce -0, 17, 17, 1, 36864, 0x4d559791 -0, 18, 18, 1, 36864, 0xf5f900ee -0, 19, 19, 1, 36864, 0x2cc9c0d7 -0, 20, 20, 1, 36864, 0x5ba14186 -0, 21, 21, 1, 36864, 0x47a46865 -0, 22, 22, 1, 36864, 0x5ba180b7 -0, 23, 23, 1, 36864, 0xc67c4876 -0, 24, 24, 1, 36864, 0x4311d75d -0, 25, 25, 1, 36864, 0x56edb851 -0, 26, 26, 1, 36864, 0x7e5aa3e0 -0, 27, 27, 1, 36864, 0x8df8283a -0, 28, 28, 1, 36864, 0xb8583ddf -0, 29, 29, 1, 36864, 0xf33fb779 -0, 30, 30, 1, 36864, 0xe9942ddc -0, 31, 31, 1, 36864, 0x2bc5f7fa -0, 32, 32, 1, 36864, 0xc7b66c65 -0, 33, 33, 1, 36864, 0x1a524319 -0, 34, 34, 1, 36864, 0xf60c6141 -0, 35, 35, 1, 36864, 0x113f41f2 -0, 36, 36, 1, 36864, 0xad191a31 -0, 37, 37, 1, 36864, 0x3898264a -0, 38, 38, 1, 36864, 0x3c2f34a4 -0, 39, 39, 1, 36864, 0xd0fc76aa -0, 40, 40, 1, 36864, 0x2870b546 -0, 41, 41, 1, 36864, 0x7d326fb4 -0, 42, 42, 1, 36864, 0xd7ed14e1 -0, 43, 43, 1, 36864, 0x205174aa -0, 44, 44, 1, 36864, 0xa3a88be9 -0, 45, 45, 1, 36864, 0xd6f01751 -0, 46, 46, 1, 36864, 0x5420bb80 -0, 47, 47, 1, 36864, 0xe14518f9 -0, 48, 48, 1, 36864, 0x931db61e -0, 49, 49, 1, 36864, 0x052ecfae -0, 50, 50, 1, 36864, 0x29b1b0f5 -0, 51, 51, 1, 36864, 0xa3057117 -0, 52, 52, 1, 36864, 0x954464be -0, 53, 53, 1, 36864, 0xace1d90b -0, 54, 54, 1, 36864, 0x8f149f03 -0, 55, 55, 1, 36864, 0x485722c5 -0, 56, 56, 1, 36864, 0x534b18f9 -0, 57, 57, 1, 36864, 0xc893a0a6 -0, 58, 58, 1, 36864, 0x8b04e1dd -0, 59, 59, 1, 36864, 0xaf536964 +0, 1, 1, 1, 36864, 0x954464be +0, 2, 2, 1, 36864, 0xace1d90b +0, 3, 3, 1, 36864, 0x8f149f03 +0, 4, 4, 1, 36864, 0xea9b21eb +0, 5, 5, 1, 36864, 0xb51d9fe3 +0, 6, 6, 1, 36864, 0x61bd11d7 +0, 7, 7, 1, 36864, 0x9d36980f +0, 8, 8, 1, 36864, 0xa4192c5e +0, 9, 9, 1, 36864, 0x11006433 +0, 10, 10, 1, 36864, 0x4a243e46 +0, 11, 11, 1, 36864, 0x1807b5e8 +0, 12, 12, 1, 36864, 0xbe37743c +0, 13, 13, 1, 36864, 0x82491319 +0, 14, 14, 1, 36864, 0x006e9914 +0, 15, 15, 1, 36864, 0xa5261884 +0, 16, 16, 1, 36864, 0x2030c9d6 +0, 17, 17, 1, 36864, 0xc80eb1ce +0, 18, 18, 1, 36864, 0x4d559791 +0, 19, 19, 1, 36864, 0xf5f900ee +0, 20, 20, 1, 36864, 0x2cc9c0d7 +0, 21, 21, 1, 36864, 0x5ba14186 +0, 22, 22, 1, 36864, 0x47a46865 +0, 23, 23, 1, 36864, 0x5ba180b7 +0, 24, 24, 1, 36864, 0xc67c4876 +0, 25, 25, 1, 36864, 0x4311d75d +0, 26, 26, 1, 36864, 0x56edb851 +0, 27, 27, 1, 36864, 0x7e5aa3e0 +0, 28, 28, 1, 36864, 0x8df8283a +0, 29, 29, 1, 36864, 0xb8583ddf +0, 30, 30, 1, 36864, 0xf33fb779 +0, 31, 31, 1, 36864, 0xe9942ddc +0, 32, 32, 1, 36864, 0x2bc5f7fa +0, 33, 33, 1, 36864, 0xc7b66c65 +0, 34, 34, 1, 36864, 0x1a524319 +0, 35, 35, 1, 36864, 0xf60c6141 +0, 36, 36, 1, 36864, 0x113f41f2 +0, 37, 37, 1, 36864, 0xad191a31 +0, 38, 38, 1, 36864, 0x3898264a +0, 39, 39, 1, 36864, 0x3c2f34a4 +0, 40, 40, 1, 36864, 0xd0fc76aa +0, 41, 41, 1, 36864, 0x2870b546 +0, 42, 42, 1, 36864, 0x7d326fb4 +0, 43, 43, 1, 36864, 0xd7ed14e1 +0, 44, 44, 1, 36864, 0x205174aa +0, 45, 45, 1, 36864, 0xa3a88be9 +0, 46, 46, 1, 36864, 0xd6f01751 +0, 47, 47, 1, 36864, 0x5420bb80 +0, 48, 48, 1, 36864, 0xe14518f9 +0, 49, 49, 1, 36864, 0x931db61e +0, 50, 50, 1, 36864, 0x052ecfae +0, 51, 51, 1, 36864, 0x29b1b0f5 +0, 52, 52, 1, 36864, 0xa3057117 +0, 53, 53, 1, 36864, 0x954464be +0, 54, 54, 1, 36864, 0xace1d90b +0, 55, 55, 1, 36864, 0x8f149f03 +0, 56, 56, 1, 36864, 0x485722c5 +0, 57, 57, 1, 36864, 0x534b18f9 +0, 58, 58, 1, 36864, 0xc893a0a6 +0, 59, 59, 1, 36864, 0x8b04e1dd +0, 60, 60, 1, 36864, 0xaf536964 diff --git a/tests/ref/fate/h264-conformance-mr7_bt_b b/tests/ref/fate/h264-conformance-mr7_bt_b index 551767ce1..becd797c8 100644 --- a/tests/ref/fate/h264-conformance-mr7_bt_b +++ b/tests/ref/fate/h264-conformance-mr7_bt_b @@ -13,53 +13,53 @@ 0, 7, 7, 1, 36864, 0xf2f324dd 0, 8, 8, 1, 36864, 0x592b5a01 0, 9, 9, 1, 36864, 0x4c2f2d91 -0, 10, 10, 1, 36864, 0x8baeb610 -0, 11, 11, 1, 36864, 0x86d47617 -0, 12, 12, 1, 36864, 0xf11011cc -0, 13, 13, 1, 36864, 0xe56a9daa -0, 14, 14, 1, 36864, 0xd57119d6 -0, 15, 15, 1, 36864, 0xe28fcde7 -0, 16, 16, 1, 36864, 0x9aeeba86 -0, 17, 17, 1, 36864, 0xa518a7c5 -0, 18, 18, 1, 36864, 0x9af410be -0, 19, 19, 1, 36864, 0x1fedd12f -0, 20, 20, 1, 36864, 0xa8032e03 -0, 21, 21, 1, 36864, 0x579e6274 -0, 22, 22, 1, 36864, 0x99846ef6 -0, 23, 23, 1, 36864, 0xb5ad3ca7 -0, 24, 24, 1, 36864, 0x7845cb90 -0, 25, 25, 1, 36864, 0x569fae24 -0, 26, 26, 1, 36864, 0x8a3c9f98 -0, 27, 27, 1, 36864, 0x0b7722af -0, 28, 28, 1, 36864, 0x699c2dd8 -0, 29, 29, 1, 36864, 0xd477af13 -0, 30, 30, 1, 36864, 0x17b62d7c -0, 31, 31, 1, 36864, 0xb1ecf6a7 -0, 32, 32, 1, 36864, 0xf9c17e4c -0, 33, 33, 1, 36864, 0xe7c44618 -0, 34, 34, 1, 36864, 0x7e23654e -0, 35, 35, 1, 36864, 0xd8a0457c -0, 36, 36, 1, 36864, 0x57e11df1 -0, 37, 37, 1, 36864, 0xd54d2a43 -0, 38, 38, 1, 36864, 0xc6f03950 -0, 39, 39, 1, 36864, 0x687e750e -0, 40, 40, 1, 36864, 0x2870b546 -0, 41, 41, 1, 36864, 0xda0370d0 -0, 42, 42, 1, 36864, 0x5a2e0bff -0, 43, 43, 1, 36864, 0xe1f07533 -0, 44, 44, 1, 36864, 0x3de892b9 -0, 45, 45, 1, 36864, 0xe5c31505 -0, 46, 46, 1, 36864, 0x96b8c082 -0, 47, 47, 1, 36864, 0x55391423 -0, 48, 48, 1, 36864, 0xc285bd71 -0, 49, 49, 1, 36864, 0xf702d9f3 -0, 50, 50, 1, 36864, 0x7afbadf8 -0, 51, 51, 1, 36864, 0xd9b568f7 -0, 52, 52, 1, 36864, 0x579e6274 -0, 53, 53, 1, 36864, 0x8650c61c -0, 54, 54, 1, 36864, 0xbc359647 -0, 55, 55, 1, 36864, 0x5522328c -0, 56, 56, 1, 36864, 0x02821fd6 -0, 57, 57, 1, 36864, 0xb4ee9562 -0, 58, 58, 1, 36864, 0xcefedb68 -0, 59, 59, 1, 36864, 0xd959782e +0, 11, 11, 1, 36864, 0x8baeb610 +0, 12, 12, 1, 36864, 0x86d47617 +0, 13, 13, 1, 36864, 0xf11011cc +0, 14, 14, 1, 36864, 0xe56a9daa +0, 15, 15, 1, 36864, 0xd57119d6 +0, 16, 16, 1, 36864, 0xe28fcde7 +0, 17, 17, 1, 36864, 0x9aeeba86 +0, 18, 18, 1, 36864, 0xa518a7c5 +0, 19, 19, 1, 36864, 0x9af410be +0, 20, 20, 1, 36864, 0x1fedd12f +0, 21, 21, 1, 36864, 0xa8032e03 +0, 22, 22, 1, 36864, 0x579e6274 +0, 23, 23, 1, 36864, 0x99846ef6 +0, 24, 24, 1, 36864, 0xb5ad3ca7 +0, 25, 25, 1, 36864, 0x7845cb90 +0, 26, 26, 1, 36864, 0x569fae24 +0, 27, 27, 1, 36864, 0x8a3c9f98 +0, 28, 28, 1, 36864, 0x0b7722af +0, 29, 29, 1, 36864, 0x699c2dd8 +0, 30, 30, 1, 36864, 0xd477af13 +0, 31, 31, 1, 36864, 0x17b62d7c +0, 32, 32, 1, 36864, 0xb1ecf6a7 +0, 33, 33, 1, 36864, 0xf9c17e4c +0, 34, 34, 1, 36864, 0xe7c44618 +0, 35, 35, 1, 36864, 0x7e23654e +0, 36, 36, 1, 36864, 0xd8a0457c +0, 37, 37, 1, 36864, 0x57e11df1 +0, 38, 38, 1, 36864, 0xd54d2a43 +0, 39, 39, 1, 36864, 0xc6f03950 +0, 40, 40, 1, 36864, 0x687e750e +0, 41, 41, 1, 36864, 0x2870b546 +0, 42, 42, 1, 36864, 0xda0370d0 +0, 43, 43, 1, 36864, 0x5a2e0bff +0, 44, 44, 1, 36864, 0xe1f07533 +0, 45, 45, 1, 36864, 0x3de892b9 +0, 46, 46, 1, 36864, 0xe5c31505 +0, 47, 47, 1, 36864, 0x96b8c082 +0, 48, 48, 1, 36864, 0x55391423 +0, 49, 49, 1, 36864, 0xc285bd71 +0, 50, 50, 1, 36864, 0xf702d9f3 +0, 51, 51, 1, 36864, 0x7afbadf8 +0, 52, 52, 1, 36864, 0xd9b568f7 +0, 53, 53, 1, 36864, 0x579e6274 +0, 54, 54, 1, 36864, 0x8650c61c +0, 55, 55, 1, 36864, 0xbc359647 +0, 56, 56, 1, 36864, 0x5522328c +0, 57, 57, 1, 36864, 0x02821fd6 +0, 58, 58, 1, 36864, 0xb4ee9562 +0, 59, 59, 1, 36864, 0xcefedb68 +0, 60, 60, 1, 36864, 0xd959782e diff --git a/tests/ref/fate/h264-conformance-mr8_bt_b b/tests/ref/fate/h264-conformance-mr8_bt_b index 7981c4224..40373e698 100644 --- a/tests/ref/fate/h264-conformance-mr8_bt_b +++ b/tests/ref/fate/h264-conformance-mr8_bt_b @@ -3,61 +3,61 @@ #codec_id 0: rawvideo #dimensions 0: 192x128 #sar 0: 0/1 -0, 0, 0, 1, 36864, 0x36df68f4 -0, 1, 1, 1, 36864, 0x52d4c6d9 -0, 2, 2, 1, 36864, 0xad16b0be -0, 3, 3, 1, 36864, 0xf8c72556 -0, 4, 4, 1, 36864, 0x70aaad30 -0, 5, 5, 1, 36864, 0x53cffd5e -0, 6, 6, 1, 36864, 0xb3fa8abc -0, 7, 7, 1, 36864, 0x9c894009 -0, 8, 8, 1, 36864, 0xfbc08050 -0, 9, 9, 1, 36864, 0x9d5b2d65 -0, 10, 10, 1, 36864, 0x3bd8bb5d -0, 11, 11, 1, 36864, 0x8d976ecf -0, 12, 12, 1, 36864, 0x25010368 -0, 13, 13, 1, 36864, 0xb6e6a11c -0, 14, 14, 1, 36864, 0x595a3967 -0, 15, 15, 1, 36864, 0x4fbcb9a8 -0, 16, 16, 1, 36864, 0xc7c5c16b -0, 17, 17, 1, 36864, 0x661ae1eb -0, 18, 18, 1, 36864, 0x169f04a7 -0, 19, 19, 1, 36864, 0xd124c93a -0, 20, 20, 1, 36864, 0x3f642dba -0, 21, 21, 1, 36864, 0xe7ad6956 -0, 22, 22, 1, 36864, 0x47dc76d3 -0, 23, 23, 1, 36864, 0x496a3917 -0, 24, 24, 1, 36864, 0xa976d5f3 -0, 25, 25, 1, 36864, 0x507bb685 -0, 26, 26, 1, 36864, 0x2f61ac12 -0, 27, 27, 1, 36864, 0x527818d8 -0, 28, 28, 1, 36864, 0xa4983396 -0, 29, 29, 1, 36864, 0x3ec9b07b -0, 30, 30, 1, 36864, 0x7db52d99 -0, 31, 31, 1, 36864, 0xe974fd00 -0, 32, 32, 1, 36864, 0x9c677a4f -0, 33, 33, 1, 36864, 0x108f3a05 -0, 34, 34, 1, 36864, 0x23a56ba2 -0, 35, 35, 1, 36864, 0x4c8d47e8 -0, 36, 36, 1, 36864, 0x9e0b0f09 -0, 37, 37, 1, 36864, 0x4d262b16 -0, 38, 38, 1, 36864, 0x6122402e -0, 39, 39, 1, 36864, 0xed037036 -0, 40, 40, 1, 36864, 0x62b3ba08 -0, 41, 41, 1, 36864, 0x7f876930 -0, 42, 42, 1, 36864, 0x4a6c0983 -0, 43, 43, 1, 36864, 0xf9787086 -0, 44, 44, 1, 36864, 0x01d1b1b5 -0, 45, 45, 1, 36864, 0xc1622655 -0, 46, 46, 1, 36864, 0x27e8e0f7 -0, 47, 47, 1, 36864, 0xc1622655 -0, 48, 48, 1, 36864, 0x12c2b7e9 -0, 49, 49, 1, 36864, 0xd752d2ef -0, 50, 50, 1, 36864, 0xcbb1c3a7 -0, 51, 51, 1, 36864, 0x18c56fba -0, 52, 52, 1, 36864, 0xb1b3771c -0, 53, 53, 1, 36864, 0x284ef3c4 -0, 54, 54, 1, 36864, 0xda6eb5a0 -0, 55, 55, 1, 36864, 0x17ad337c -0, 56, 56, 1, 36864, 0xe2801e4f -0, 57, 57, 1, 36864, 0x6c33bd17 +0, 1, 1, 1, 36864, 0x36df68f4 +0, 2, 2, 1, 36864, 0x52d4c6d9 +0, 3, 3, 1, 36864, 0xad16b0be +0, 4, 4, 1, 36864, 0xf8c72556 +0, 5, 5, 1, 36864, 0x70aaad30 +0, 6, 6, 1, 36864, 0x53cffd5e +0, 7, 7, 1, 36864, 0xb3fa8abc +0, 8, 8, 1, 36864, 0x9c894009 +0, 9, 9, 1, 36864, 0xfbc08050 +0, 10, 10, 1, 36864, 0x9d5b2d65 +0, 11, 11, 1, 36864, 0x3bd8bb5d +0, 12, 12, 1, 36864, 0x8d976ecf +0, 13, 13, 1, 36864, 0x25010368 +0, 14, 14, 1, 36864, 0xb6e6a11c +0, 15, 15, 1, 36864, 0x595a3967 +0, 16, 16, 1, 36864, 0x4fbcb9a8 +0, 17, 17, 1, 36864, 0xc7c5c16b +0, 18, 18, 1, 36864, 0x661ae1eb +0, 19, 19, 1, 36864, 0x169f04a7 +0, 20, 20, 1, 36864, 0xd124c93a +0, 21, 21, 1, 36864, 0x3f642dba +0, 22, 22, 1, 36864, 0xe7ad6956 +0, 23, 23, 1, 36864, 0x47dc76d3 +0, 24, 24, 1, 36864, 0x496a3917 +0, 25, 25, 1, 36864, 0xa976d5f3 +0, 26, 26, 1, 36864, 0x507bb685 +0, 27, 27, 1, 36864, 0x2f61ac12 +0, 28, 28, 1, 36864, 0x527818d8 +0, 29, 29, 1, 36864, 0xa4983396 +0, 30, 30, 1, 36864, 0x3ec9b07b +0, 31, 31, 1, 36864, 0x7db52d99 +0, 32, 32, 1, 36864, 0xe974fd00 +0, 33, 33, 1, 36864, 0x9c677a4f +0, 34, 34, 1, 36864, 0x108f3a05 +0, 35, 35, 1, 36864, 0x23a56ba2 +0, 36, 36, 1, 36864, 0x4c8d47e8 +0, 37, 37, 1, 36864, 0x9e0b0f09 +0, 38, 38, 1, 36864, 0x4d262b16 +0, 39, 39, 1, 36864, 0x6122402e +0, 40, 40, 1, 36864, 0xed037036 +0, 41, 41, 1, 36864, 0x62b3ba08 +0, 42, 42, 1, 36864, 0x7f876930 +0, 43, 43, 1, 36864, 0x4a6c0983 +0, 44, 44, 1, 36864, 0xf9787086 +0, 45, 45, 1, 36864, 0x01d1b1b5 +0, 46, 46, 1, 36864, 0xc1622655 +0, 47, 47, 1, 36864, 0x27e8e0f7 +0, 48, 48, 1, 36864, 0xc1622655 +0, 49, 49, 1, 36864, 0x12c2b7e9 +0, 50, 50, 1, 36864, 0xd752d2ef +0, 51, 51, 1, 36864, 0xcbb1c3a7 +0, 52, 52, 1, 36864, 0x18c56fba +0, 53, 53, 1, 36864, 0xb1b3771c +0, 54, 54, 1, 36864, 0x284ef3c4 +0, 55, 55, 1, 36864, 0xda6eb5a0 +0, 56, 56, 1, 36864, 0x17ad337c +0, 57, 57, 1, 36864, 0xe2801e4f +0, 58, 58, 1, 36864, 0x6c33bd17 diff --git a/tests/ref/fate/h264-conformance-mr9_bt_b b/tests/ref/fate/h264-conformance-mr9_bt_b index bbd90e67f..99dd0dc32 100644 --- a/tests/ref/fate/h264-conformance-mr9_bt_b +++ b/tests/ref/fate/h264-conformance-mr9_bt_b @@ -13,51 +13,51 @@ 0, 7, 7, 1, 36864, 0x75122807 0, 8, 8, 1, 36864, 0x27036a2b 0, 9, 9, 1, 36864, 0x00072654 -0, 10, 10, 1, 36864, 0x49fab4fd -0, 11, 11, 1, 36864, 0x975a7545 -0, 12, 12, 1, 36864, 0x9b080a2f -0, 13, 13, 1, 36864, 0x78db960e -0, 14, 14, 1, 36864, 0xd7a928d4 -0, 15, 15, 1, 36864, 0x0a83ba1b -0, 16, 16, 1, 36864, 0xad6bb30c -0, 17, 17, 1, 36864, 0xf6addb0d -0, 18, 18, 1, 36864, 0x00540a0a -0, 19, 19, 1, 36864, 0x049cc748 -0, 20, 20, 1, 36864, 0x5b1e2291 -0, 21, 21, 1, 36864, 0x2367706e -0, 22, 22, 1, 36864, 0x88ef6b11 -0, 23, 23, 1, 36864, 0x85b73230 -0, 24, 24, 1, 36864, 0xe46cd522 -0, 25, 25, 1, 36864, 0x98489c05 -0, 26, 26, 1, 36864, 0x7e439564 -0, 27, 27, 1, 36864, 0x71330799 -0, 28, 28, 1, 36864, 0x81a6239e -0, 29, 29, 1, 36864, 0x8005a302 -0, 30, 30, 1, 36864, 0xdf132e3f -0, 31, 31, 1, 36864, 0x2a1d00de -0, 32, 32, 1, 36864, 0x7bb57e14 -0, 33, 33, 1, 36864, 0xf2a637cf -0, 34, 34, 1, 36864, 0xae6f6916 -0, 35, 35, 1, 36864, 0x2f1d4763 -0, 36, 36, 1, 36864, 0xa4e1145e -0, 37, 37, 1, 36864, 0xc1644392 -0, 38, 38, 1, 36864, 0x21853537 -0, 39, 39, 1, 36864, 0x0bc45bac -0, 40, 40, 1, 36864, 0x84ccb8ee -0, 41, 41, 1, 36864, 0x65de651c -0, 42, 42, 1, 36864, 0x33ff027e -0, 43, 43, 1, 36864, 0xefe47056 -0, 44, 44, 1, 36864, 0x8952b47c -0, 45, 45, 1, 36864, 0x78730fcf -0, 46, 46, 1, 36864, 0x14bae79f -0, 47, 47, 1, 36864, 0x53230fbe -0, 48, 48, 1, 36864, 0x15b0b245 -0, 49, 49, 1, 36864, 0x45fbd155 -0, 50, 50, 1, 36864, 0x41cfbac4 -0, 51, 51, 1, 36864, 0x0d635d61 -0, 52, 52, 1, 36864, 0x55aa8d3c -0, 53, 53, 1, 36864, 0x8f02fbaf -0, 54, 54, 1, 36864, 0xb17fac3f -0, 55, 55, 1, 36864, 0xc12627f9 -0, 56, 56, 1, 36864, 0xa5971e4a -0, 57, 57, 1, 36864, 0x3677abfe +0, 11, 11, 1, 36864, 0x49fab4fd +0, 12, 12, 1, 36864, 0x975a7545 +0, 13, 13, 1, 36864, 0x9b080a2f +0, 14, 14, 1, 36864, 0x78db960e +0, 15, 15, 1, 36864, 0xd7a928d4 +0, 16, 16, 1, 36864, 0x0a83ba1b +0, 17, 17, 1, 36864, 0xad6bb30c +0, 18, 18, 1, 36864, 0xf6addb0d +0, 19, 19, 1, 36864, 0x00540a0a +0, 20, 20, 1, 36864, 0x049cc748 +0, 21, 21, 1, 36864, 0x5b1e2291 +0, 22, 22, 1, 36864, 0x2367706e +0, 23, 23, 1, 36864, 0x88ef6b11 +0, 24, 24, 1, 36864, 0x85b73230 +0, 25, 25, 1, 36864, 0xe46cd522 +0, 26, 26, 1, 36864, 0x98489c05 +0, 27, 27, 1, 36864, 0x7e439564 +0, 28, 28, 1, 36864, 0x71330799 +0, 29, 29, 1, 36864, 0x81a6239e +0, 30, 30, 1, 36864, 0x8005a302 +0, 31, 31, 1, 36864, 0xdf132e3f +0, 32, 32, 1, 36864, 0x2a1d00de +0, 33, 33, 1, 36864, 0x7bb57e14 +0, 34, 34, 1, 36864, 0xf2a637cf +0, 35, 35, 1, 36864, 0xae6f6916 +0, 36, 36, 1, 36864, 0x2f1d4763 +0, 37, 37, 1, 36864, 0xa4e1145e +0, 38, 38, 1, 36864, 0xc1644392 +0, 39, 39, 1, 36864, 0x21853537 +0, 40, 40, 1, 36864, 0x0bc45bac +0, 41, 41, 1, 36864, 0x84ccb8ee +0, 42, 42, 1, 36864, 0x65de651c +0, 43, 43, 1, 36864, 0x33ff027e +0, 44, 44, 1, 36864, 0xefe47056 +0, 45, 45, 1, 36864, 0x8952b47c +0, 46, 46, 1, 36864, 0x78730fcf +0, 47, 47, 1, 36864, 0x14bae79f +0, 48, 48, 1, 36864, 0x53230fbe +0, 49, 49, 1, 36864, 0x15b0b245 +0, 50, 50, 1, 36864, 0x45fbd155 +0, 51, 51, 1, 36864, 0x41cfbac4 +0, 52, 52, 1, 36864, 0x0d635d61 +0, 53, 53, 1, 36864, 0x55aa8d3c +0, 54, 54, 1, 36864, 0x8f02fbaf +0, 55, 55, 1, 36864, 0xb17fac3f +0, 56, 56, 1, 36864, 0xc12627f9 +0, 57, 57, 1, 36864, 0xa5971e4a +0, 58, 58, 1, 36864, 0x3677abfe diff --git a/tests/ref/fate/h264-conformance-sharp_mp_field_1_b b/tests/ref/fate/h264-conformance-sharp_mp_field_1_b index cdabcceca..688cd2a39 100644 --- a/tests/ref/fate/h264-conformance-sharp_mp_field_1_b +++ b/tests/ref/fate/h264-conformance-sharp_mp_field_1_b @@ -3,18 +3,18 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0xc93c7c47 -0, 1, 1, 1, 518400, 0xa3f2e502 -0, 2, 2, 1, 518400, 0xb98920a4 -0, 3, 3, 1, 518400, 0xad098ec1 -0, 4, 4, 1, 518400, 0x3009b7aa -0, 5, 5, 1, 518400, 0xcf514018 -0, 6, 6, 1, 518400, 0xd869038d -0, 7, 7, 1, 518400, 0x3ce5e188 -0, 8, 8, 1, 518400, 0x029b4c14 -0, 9, 9, 1, 518400, 0xd2224afc -0, 10, 10, 1, 518400, 0xbbca027c -0, 11, 11, 1, 518400, 0x1f3fa0ac -0, 12, 12, 1, 518400, 0x823b0125 -0, 13, 13, 1, 518400, 0xaaa27cfb -0, 14, 14, 1, 518400, 0x5e926a4a +0, 1, 1, 1, 518400, 0xc93c7c47 +0, 2, 2, 1, 518400, 0xa3f2e502 +0, 3, 3, 1, 518400, 0xb98920a4 +0, 4, 4, 1, 518400, 0xad098ec1 +0, 5, 5, 1, 518400, 0x3009b7aa +0, 6, 6, 1, 518400, 0xcf514018 +0, 7, 7, 1, 518400, 0xd869038d +0, 8, 8, 1, 518400, 0x3ce5e188 +0, 9, 9, 1, 518400, 0x029b4c14 +0, 10, 10, 1, 518400, 0xd2224afc +0, 11, 11, 1, 518400, 0xbbca027c +0, 12, 12, 1, 518400, 0x1f3fa0ac +0, 13, 13, 1, 518400, 0x823b0125 +0, 14, 14, 1, 518400, 0xaaa27cfb +0, 15, 15, 1, 518400, 0x5e926a4a diff --git a/tests/ref/fate/h264-conformance-sharp_mp_field_2_b b/tests/ref/fate/h264-conformance-sharp_mp_field_2_b index 0574f8ff8..aa21e0146 100644 --- a/tests/ref/fate/h264-conformance-sharp_mp_field_2_b +++ b/tests/ref/fate/h264-conformance-sharp_mp_field_2_b @@ -3,18 +3,18 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0xc93c7c47 -0, 1, 1, 1, 518400, 0xf0c4b44a -0, 2, 2, 1, 518400, 0x3f5dc91c -0, 3, 3, 1, 518400, 0x03dc8453 -0, 4, 4, 1, 518400, 0x5e5227af -0, 5, 5, 1, 518400, 0x9e7136af -0, 6, 6, 1, 518400, 0x963a2e3a -0, 7, 7, 1, 518400, 0xa544be6c -0, 8, 8, 1, 518400, 0xefa1f63a -0, 9, 9, 1, 518400, 0x62155ff1 -0, 10, 10, 1, 518400, 0x253eb857 -0, 11, 11, 1, 518400, 0x73530327 -0, 12, 12, 1, 518400, 0x8920c9a3 -0, 13, 13, 1, 518400, 0x4bdd038c -0, 14, 14, 1, 518400, 0xea6016dd +0, 1, 1, 1, 518400, 0xc93c7c47 +0, 2, 2, 1, 518400, 0xf0c4b44a +0, 3, 3, 1, 518400, 0x3f5dc91c +0, 4, 4, 1, 518400, 0x03dc8453 +0, 5, 5, 1, 518400, 0x5e5227af +0, 6, 6, 1, 518400, 0x9e7136af +0, 7, 7, 1, 518400, 0x963a2e3a +0, 8, 8, 1, 518400, 0xa544be6c +0, 9, 9, 1, 518400, 0xefa1f63a +0, 10, 10, 1, 518400, 0x62155ff1 +0, 11, 11, 1, 518400, 0x253eb857 +0, 12, 12, 1, 518400, 0x73530327 +0, 13, 13, 1, 518400, 0x8920c9a3 +0, 14, 14, 1, 518400, 0x4bdd038c +0, 15, 15, 1, 518400, 0xea6016dd diff --git a/tests/ref/fate/h264-conformance-sharp_mp_field_3_b b/tests/ref/fate/h264-conformance-sharp_mp_field_3_b index 6a92245f2..45792a1b2 100644 --- a/tests/ref/fate/h264-conformance-sharp_mp_field_3_b +++ b/tests/ref/fate/h264-conformance-sharp_mp_field_3_b @@ -3,18 +3,18 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -0, 0, 0, 1, 518400, 0xc93c7c47 -0, 1, 1, 1, 518400, 0x7112ac25 -0, 2, 2, 1, 518400, 0x28bc28d2 -0, 3, 3, 1, 518400, 0x6fc36875 -0, 4, 4, 1, 518400, 0x3de99be0 -0, 5, 5, 1, 518400, 0x97125499 -0, 6, 6, 1, 518400, 0xb96fca3a -0, 7, 7, 1, 518400, 0x1ec56c0f -0, 8, 8, 1, 518400, 0xc65901d0 -0, 9, 9, 1, 518400, 0x2baa1bfa -0, 10, 10, 1, 518400, 0x244fc6b7 -0, 11, 11, 1, 518400, 0xc3536383 -0, 12, 12, 1, 518400, 0xbcf40d5a -0, 13, 13, 1, 518400, 0x955f4734 -0, 14, 14, 1, 518400, 0xe1b0275e +0, 1, 1, 1, 518400, 0xc93c7c47 +0, 2, 2, 1, 518400, 0x7112ac25 +0, 3, 3, 1, 518400, 0x28bc28d2 +0, 4, 4, 1, 518400, 0x6fc36875 +0, 5, 5, 1, 518400, 0x3de99be0 +0, 6, 6, 1, 518400, 0x97125499 +0, 7, 7, 1, 518400, 0xb96fca3a +0, 8, 8, 1, 518400, 0x1ec56c0f +0, 9, 9, 1, 518400, 0xc65901d0 +0, 10, 10, 1, 518400, 0x2baa1bfa +0, 11, 11, 1, 518400, 0x244fc6b7 +0, 12, 12, 1, 518400, 0xc3536383 +0, 13, 13, 1, 518400, 0xbcf40d5a +0, 14, 14, 1, 518400, 0x955f4734 +0, 15, 15, 1, 518400, 0xe1b0275e diff --git a/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2 b/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2 index 8a7aa249f..35168666c 100644 --- a/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2 +++ b/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2 @@ -5,16 +5,16 @@ #sar 0: 0/1 0, 0, 0, 1, 518400, 0xc93c7c47 0, 1, 1, 1, 518400, 0xfb452a9c -0, 2, 2, 1, 518400, 0x2f7a35bd -0, 3, 3, 1, 518400, 0xe63e30b9 -0, 4, 4, 1, 518400, 0x39628205 -0, 5, 5, 1, 518400, 0x17fa1ea4 -0, 6, 6, 1, 518400, 0xd5ee83e2 -0, 7, 7, 1, 518400, 0x611ee98d -0, 8, 8, 1, 518400, 0x07c1eeb8 -0, 9, 9, 1, 518400, 0x9dff3418 -0, 10, 10, 1, 518400, 0x87cd2f56 -0, 11, 11, 1, 518400, 0x88675628 -0, 12, 12, 1, 518400, 0x9bb8c9a0 -0, 13, 13, 1, 518400, 0xe6c1df00 -0, 14, 14, 1, 518400, 0xfcaab7a7 +0, 3, 3, 1, 518400, 0x2f7a35bd +0, 4, 4, 1, 518400, 0xe63e30b9 +0, 5, 5, 1, 518400, 0x39628205 +0, 6, 6, 1, 518400, 0x17fa1ea4 +0, 7, 7, 1, 518400, 0xd5ee83e2 +0, 8, 8, 1, 518400, 0x611ee98d +0, 9, 9, 1, 518400, 0x07c1eeb8 +0, 10, 10, 1, 518400, 0x9dff3418 +0, 11, 11, 1, 518400, 0x87cd2f56 +0, 12, 12, 1, 518400, 0x88675628 +0, 13, 13, 1, 518400, 0x9bb8c9a0 +0, 14, 14, 1, 518400, 0xe6c1df00 +0, 15, 15, 1, 518400, 0xfcaab7a7 diff --git a/tests/ref/fate/h264-conformance-sharp_mp_paff_2r b/tests/ref/fate/h264-conformance-sharp_mp_paff_2r index ded91a9be..9fb88701f 100644 --- a/tests/ref/fate/h264-conformance-sharp_mp_paff_2r +++ b/tests/ref/fate/h264-conformance-sharp_mp_paff_2r @@ -5,16 +5,16 @@ #sar 0: 0/1 0, 0, 0, 1, 518400, 0xc93c7c47 0, 1, 1, 1, 518400, 0xfb452a9c -0, 2, 2, 1, 518400, 0x2f7a35bd -0, 3, 3, 1, 518400, 0xe63e30b9 -0, 4, 4, 1, 518400, 0x39628205 -0, 5, 5, 1, 518400, 0x17fa1ea4 -0, 6, 6, 1, 518400, 0xd5ee83e2 -0, 7, 7, 1, 518400, 0x4fd6d5c9 -0, 8, 8, 1, 518400, 0x8703c999 -0, 9, 9, 1, 518400, 0x1a87e2d3 -0, 10, 10, 1, 518400, 0xa27fc4d0 -0, 11, 11, 1, 518400, 0x6effab5d -0, 12, 12, 1, 518400, 0x51ea02c9 -0, 13, 13, 1, 518400, 0xbcf84c88 -0, 14, 14, 1, 518400, 0x1d41076b +0, 3, 3, 1, 518400, 0x2f7a35bd +0, 4, 4, 1, 518400, 0xe63e30b9 +0, 5, 5, 1, 518400, 0x39628205 +0, 6, 6, 1, 518400, 0x17fa1ea4 +0, 7, 7, 1, 518400, 0xd5ee83e2 +0, 8, 8, 1, 518400, 0x4fd6d5c9 +0, 9, 9, 1, 518400, 0x8703c999 +0, 10, 10, 1, 518400, 0x1a87e2d3 +0, 11, 11, 1, 518400, 0xa27fc4d0 +0, 12, 12, 1, 518400, 0x6effab5d +0, 13, 13, 1, 518400, 0x51ea02c9 +0, 14, 14, 1, 518400, 0xbcf84c88 +0, 15, 15, 1, 518400, 0x1d41076b diff --git a/tests/ref/fate/hapqa-extract-nosnappy-to-hapalphaonly-mov b/tests/ref/fate/hapqa-extract-nosnappy-to-hapalphaonly-mov index 61af08aa2..d0374635c 100644 --- a/tests/ref/fate/hapqa-extract-nosnappy-to-hapalphaonly-mov +++ b/tests/ref/fate/hapqa-extract-nosnappy-to-hapalphaonly-mov @@ -7,8 +7,6 @@ dts=0 dts_time=0.000000 duration=512 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=4612 pos=36 flags=K_ @@ -19,7 +17,6 @@ index=0 codec_name=hap profile=unknown codec_type=video -codec_time_base=1/25 codec_tag_string=HapA codec_tag=0x41706148 width=127 @@ -38,7 +35,6 @@ color_transfer=unknown color_primaries=unknown chroma_location=unspecified field_order=unknown -timecode=N/A refs=1 id=N/A r_frame_rate=25/1 @@ -69,5 +65,6 @@ DISPOSITION:attached_pic=0 DISPOSITION:timed_thumbnails=0 TAG:language=eng TAG:handler_name=Module de gestion video +TAG:vendor_id=FFMP TAG:encoder=HAPAlpha Only [/STREAM] diff --git a/tests/ref/fate/hapqa-extract-nosnappy-to-hapq-mov b/tests/ref/fate/hapqa-extract-nosnappy-to-hapq-mov index 1fb31ec7f..818041988 100644 --- a/tests/ref/fate/hapqa-extract-nosnappy-to-hapq-mov +++ b/tests/ref/fate/hapqa-extract-nosnappy-to-hapq-mov @@ -7,8 +7,6 @@ dts=0 dts_time=0.000000 duration=512 duration_time=0.040000 -convergence_duration=N/A -convergence_duration_time=N/A size=9220 pos=36 flags=K_ @@ -19,7 +17,6 @@ index=0 codec_name=hap profile=unknown codec_type=video -codec_time_base=1/25 codec_tag_string=HapY codec_tag=0x59706148 width=127 @@ -38,7 +35,6 @@ color_transfer=unknown color_primaries=unknown chroma_location=unspecified field_order=unknown -timecode=N/A refs=1 id=N/A r_frame_rate=25/1 @@ -69,5 +65,6 @@ DISPOSITION:attached_pic=0 DISPOSITION:timed_thumbnails=0 TAG:language=eng TAG:handler_name=Module de gestion video +TAG:vendor_id=FFMP TAG:encoder=HAPQ [/STREAM] diff --git a/tests/ref/fate/hevc-conformance-BUMPING_A_ericsson_1 b/tests/ref/fate/hevc-conformance-BUMPING_A_ericsson_1 index fe890040e..046b1846f 100644 --- a/tests/ref/fate/hevc-conformance-BUMPING_A_ericsson_1 +++ b/tests/ref/fate/hevc-conformance-BUMPING_A_ericsson_1 @@ -7,48 +7,48 @@ 0, 1, 1, 1, 149760, 0x73610669 0, 2, 2, 1, 149760, 0xc01620f4 0, 3, 3, 1, 149760, 0x847a4297 -0, 4, 4, 1, 149760, 0x8b2db700 -0, 5, 5, 1, 149760, 0x17b1d77c -0, 6, 6, 1, 149760, 0xc31ee8a5 -0, 7, 7, 1, 149760, 0x19541295 -0, 8, 8, 1, 149760, 0xd050be45 -0, 9, 9, 1, 149760, 0x45cf8e84 -0, 10, 10, 1, 149760, 0x0dd3e4d4 -0, 11, 11, 1, 149760, 0xc8347a7c -0, 12, 12, 1, 149760, 0x24089674 -0, 13, 13, 1, 149760, 0xdf2c44e4 -0, 14, 14, 1, 149760, 0x83f5100b -0, 15, 15, 1, 149760, 0x9a060faf -0, 16, 16, 1, 149760, 0x4cdc6101 -0, 17, 17, 1, 149760, 0xe492ad68 -0, 18, 18, 1, 149760, 0x35b73887 -0, 19, 19, 1, 149760, 0x259f898a -0, 20, 20, 1, 149760, 0x21df021b -0, 21, 21, 1, 149760, 0xdddc1cfe -0, 22, 22, 1, 149760, 0x53841bf5 -0, 23, 23, 1, 149760, 0x16745d74 -0, 24, 24, 1, 149760, 0x66e79e6a -0, 25, 25, 1, 149760, 0x35f04b5a -0, 26, 26, 1, 149760, 0x1472eee7 -0, 27, 27, 1, 149760, 0x42d0147c -0, 28, 28, 1, 149760, 0x57c9bdc2 -0, 29, 29, 1, 149760, 0x20ad4cc7 -0, 30, 30, 1, 149760, 0x1617ef6c -0, 31, 31, 1, 149760, 0xccdf4da2 -0, 32, 32, 1, 149760, 0xc173b762 -0, 33, 33, 1, 149760, 0xe7390c69 -0, 34, 34, 1, 149760, 0xfd0c97d3 -0, 35, 35, 1, 149760, 0xaeb2d61f -0, 36, 36, 1, 149760, 0xe7b114d2 -0, 37, 37, 1, 149760, 0x1b771de4 -0, 38, 38, 1, 149760, 0xd3e03840 -0, 39, 39, 1, 149760, 0x702ef44b -0, 40, 40, 1, 149760, 0xe96f848b -0, 41, 41, 1, 149760, 0xa0ae24d9 -0, 42, 42, 1, 149760, 0x1b9efdfb -0, 43, 43, 1, 149760, 0xceac9bc7 -0, 44, 44, 1, 149760, 0x73078700 -0, 45, 45, 1, 149760, 0xa736637e -0, 46, 46, 1, 149760, 0xbd353c9d -0, 47, 47, 1, 149760, 0x750a23ba -0, 48, 48, 1, 149760, 0x4144c56e +0, 8, 8, 1, 149760, 0x8b2db700 +0, 9, 9, 1, 149760, 0x17b1d77c +0, 10, 10, 1, 149760, 0xc31ee8a5 +0, 11, 11, 1, 149760, 0x19541295 +0, 12, 12, 1, 149760, 0xd050be45 +0, 13, 13, 1, 149760, 0x45cf8e84 +0, 14, 14, 1, 149760, 0x0dd3e4d4 +0, 16, 16, 1, 149760, 0xc8347a7c +0, 17, 17, 1, 149760, 0x24089674 +0, 18, 18, 1, 149760, 0xdf2c44e4 +0, 19, 19, 1, 149760, 0x83f5100b +0, 20, 20, 1, 149760, 0x9a060faf +0, 24, 24, 1, 149760, 0x4cdc6101 +0, 25, 25, 1, 149760, 0xe492ad68 +0, 26, 26, 1, 149760, 0x35b73887 +0, 27, 27, 1, 149760, 0x259f898a +0, 28, 28, 1, 149760, 0x21df021b +0, 29, 29, 1, 149760, 0xdddc1cfe +0, 32, 32, 1, 149760, 0x53841bf5 +0, 33, 33, 1, 149760, 0x16745d74 +0, 34, 34, 1, 149760, 0x66e79e6a +0, 35, 35, 1, 149760, 0x35f04b5a +0, 40, 40, 1, 149760, 0x1472eee7 +0, 41, 41, 1, 149760, 0x42d0147c +0, 42, 42, 1, 149760, 0x57c9bdc2 +0, 43, 43, 1, 149760, 0x20ad4cc7 +0, 44, 44, 1, 149760, 0x1617ef6c +0, 45, 45, 1, 149760, 0xccdf4da2 +0, 46, 46, 1, 149760, 0xc173b762 +0, 47, 47, 1, 149760, 0xe7390c69 +0, 48, 48, 1, 149760, 0xfd0c97d3 +0, 49, 49, 1, 149760, 0xaeb2d61f +0, 50, 50, 1, 149760, 0xe7b114d2 +0, 51, 51, 1, 149760, 0x1b771de4 +0, 52, 52, 1, 149760, 0xd3e03840 +0, 53, 53, 1, 149760, 0x702ef44b +0, 57, 57, 1, 149760, 0xe96f848b +0, 58, 58, 1, 149760, 0xa0ae24d9 +0, 59, 59, 1, 149760, 0x1b9efdfb +0, 60, 60, 1, 149760, 0xceac9bc7 +0, 61, 61, 1, 149760, 0x73078700 +0, 62, 62, 1, 149760, 0xa736637e +0, 63, 63, 1, 149760, 0xbd353c9d +0, 64, 64, 1, 149760, 0x750a23ba +0, 65, 65, 1, 149760, 0x4144c56e diff --git a/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3 b/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3 index 3adef2f36..ebe0f676d 100644 --- a/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3 +++ b/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3 @@ -3,5 +3,5 @@ #codec_id 0: rawvideo #dimensions 0: 416x240 #sar 0: 0/1 -0, 0, 0, 1, 149760, 0x6e1f16d0 -0, 1, 1, 1, 149760, 0x5be5bde9 +0, 2, 2, 1, 149760, 0x6e1f16d0 +0, 3, 3, 1, 149760, 0x5be5bde9 diff --git a/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2 b/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2 index 8e6c681cf..74f7f8cd7 100644 --- a/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2 +++ b/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2 @@ -3,5 +3,5 @@ #codec_id 0: rawvideo #dimensions 0: 416x240 #sar 0: 0/1 -0, 0, 0, 1, 149760, 0xcd1019b2 -0, 1, 1, 1, 149760, 0xeb39efeb +0, 2, 2, 1, 149760, 0xcd1019b2 +0, 3, 3, 1, 149760, 0xeb39efeb diff --git a/tests/ref/fate/hevc-conformance-DELTAQP_A_BRCM_4 b/tests/ref/fate/hevc-conformance-DELTAQP_A_BRCM_4 index 2abd58b64..5ca3faf58 100644 --- a/tests/ref/fate/hevc-conformance-DELTAQP_A_BRCM_4 +++ b/tests/ref/fate/hevc-conformance-DELTAQP_A_BRCM_4 @@ -98,4 +98,4 @@ 0, 92, 92, 1, 3133440, 0x761571be 0, 93, 93, 1, 3133440, 0x34dc14a1 0, 94, 94, 1, 3133440, 0xbb94c2d4 -0, 95, 95, 1, 3133440, 0x5300e459 +0, 96, 96, 1, 3133440, 0x5300e459 diff --git a/tests/ref/fate/hevc-conformance-NUT_A_ericsson_5 b/tests/ref/fate/hevc-conformance-NUT_A_ericsson_5 index 7ac223ef7..a375c4806 100644 --- a/tests/ref/fate/hevc-conformance-NUT_A_ericsson_5 +++ b/tests/ref/fate/hevc-conformance-NUT_A_ericsson_5 @@ -25,15 +25,15 @@ 0, 19, 19, 1, 149760, 0x0580f2be 0, 20, 20, 1, 149760, 0x8e4cea96 0, 21, 21, 1, 149760, 0x6c98d019 -0, 22, 22, 1, 149760, 0x842803c8 -0, 23, 23, 1, 149760, 0xddc196ee -0, 24, 24, 1, 149760, 0x89e45523 -0, 25, 25, 1, 149760, 0x2a36b008 -0, 26, 26, 1, 149760, 0x14a319f7 -0, 27, 27, 1, 149760, 0x7394854c -0, 28, 28, 1, 149760, 0x26dcf933 -0, 29, 29, 1, 149760, 0x5b000b7e -0, 30, 30, 1, 149760, 0x6e76bded -0, 31, 31, 1, 149760, 0x0284d92d -0, 32, 32, 1, 149760, 0xf14a25e0 -0, 33, 33, 1, 149760, 0x10c03d98 +0, 24, 24, 1, 149760, 0x842803c8 +0, 25, 25, 1, 149760, 0xddc196ee +0, 26, 26, 1, 149760, 0x89e45523 +0, 27, 27, 1, 149760, 0x2a36b008 +0, 28, 28, 1, 149760, 0x14a319f7 +0, 29, 29, 1, 149760, 0x7394854c +0, 30, 30, 1, 149760, 0x26dcf933 +0, 31, 31, 1, 149760, 0x5b000b7e +0, 32, 32, 1, 149760, 0x6e76bded +0, 33, 33, 1, 149760, 0x0284d92d +0, 34, 34, 1, 149760, 0xf14a25e0 +0, 35, 35, 1, 149760, 0x10c03d98 diff --git a/tests/ref/fate/hevc-conformance-NoOutPrior_A_Qualcomm_1 b/tests/ref/fate/hevc-conformance-NoOutPrior_A_Qualcomm_1 index 5de9da9a3..0c930f655 100644 --- a/tests/ref/fate/hevc-conformance-NoOutPrior_A_Qualcomm_1 +++ b/tests/ref/fate/hevc-conformance-NoOutPrior_A_Qualcomm_1 @@ -25,21 +25,21 @@ 0, 19, 19, 1, 599040, 0x4227009b 0, 20, 20, 1, 599040, 0x1bda8be4 0, 21, 21, 1, 599040, 0xd1d5dcb4 -0, 22, 22, 1, 599040, 0x00a0249f -0, 23, 23, 1, 599040, 0x7263f7cf -0, 24, 24, 1, 599040, 0x47054be4 -0, 25, 25, 1, 599040, 0xda083f52 -0, 26, 26, 1, 599040, 0xf2906ab1 -0, 27, 27, 1, 599040, 0x20936797 -0, 28, 28, 1, 599040, 0x644d7c3e -0, 29, 29, 1, 599040, 0x7c00e8bf -0, 30, 30, 1, 599040, 0x041f8a48 -0, 31, 31, 1, 599040, 0xcef6e936 -0, 32, 32, 1, 599040, 0x361461e9 -0, 33, 33, 1, 599040, 0xf663ba0a -0, 34, 34, 1, 599040, 0x4d3371d3 -0, 35, 35, 1, 599040, 0xed6b5c92 -0, 36, 36, 1, 599040, 0xdec67f6e -0, 37, 37, 1, 599040, 0xbafa50c0 -0, 38, 38, 1, 599040, 0xc9181637 -0, 39, 39, 1, 599040, 0x95834e17 +0, 32, 32, 1, 599040, 0x00a0249f +0, 33, 33, 1, 599040, 0x7263f7cf +0, 34, 34, 1, 599040, 0x47054be4 +0, 35, 35, 1, 599040, 0xda083f52 +0, 36, 36, 1, 599040, 0xf2906ab1 +0, 37, 37, 1, 599040, 0x20936797 +0, 38, 38, 1, 599040, 0x644d7c3e +0, 39, 39, 1, 599040, 0x7c00e8bf +0, 40, 40, 1, 599040, 0x041f8a48 +0, 41, 41, 1, 599040, 0xcef6e936 +0, 42, 42, 1, 599040, 0x361461e9 +0, 43, 43, 1, 599040, 0xf663ba0a +0, 44, 44, 1, 599040, 0x4d3371d3 +0, 45, 45, 1, 599040, 0xed6b5c92 +0, 46, 46, 1, 599040, 0xdec67f6e +0, 47, 47, 1, 599040, 0xbafa50c0 +0, 48, 48, 1, 599040, 0xc9181637 +0, 49, 49, 1, 599040, 0x95834e17 diff --git a/tests/ref/fate/hevc-conformance-NoOutPrior_B_Qualcomm_1 b/tests/ref/fate/hevc-conformance-NoOutPrior_B_Qualcomm_1 index f107e937d..83fd3bc31 100644 --- a/tests/ref/fate/hevc-conformance-NoOutPrior_B_Qualcomm_1 +++ b/tests/ref/fate/hevc-conformance-NoOutPrior_B_Qualcomm_1 @@ -25,28 +25,28 @@ 0, 19, 19, 1, 599040, 0x4227009b 0, 20, 20, 1, 599040, 0x1bda8be4 0, 21, 21, 1, 599040, 0xd1d5dcb4 -0, 22, 22, 1, 599040, 0x00d87745 -0, 23, 23, 1, 599040, 0x9b689b16 -0, 24, 24, 1, 599040, 0x40ae530a -0, 25, 25, 1, 599040, 0x8284f649 -0, 26, 26, 1, 599040, 0x37423ae4 -0, 27, 27, 1, 599040, 0xb3f72b02 -0, 28, 28, 1, 599040, 0xc0cc5860 -0, 29, 29, 1, 599040, 0x00a0249f -0, 30, 30, 1, 599040, 0x7263f7cf -0, 31, 31, 1, 599040, 0x47054be4 -0, 32, 32, 1, 599040, 0xda083f52 -0, 33, 33, 1, 599040, 0xf2906ab1 -0, 34, 34, 1, 599040, 0x20936797 -0, 35, 35, 1, 599040, 0x644d7c3e -0, 36, 36, 1, 599040, 0x7c00e8bf -0, 37, 37, 1, 599040, 0x041f8a48 -0, 38, 38, 1, 599040, 0xcef6e936 -0, 39, 39, 1, 599040, 0x361461e9 -0, 40, 40, 1, 599040, 0xf663ba0a -0, 41, 41, 1, 599040, 0x4d3371d3 -0, 42, 42, 1, 599040, 0xed6b5c92 -0, 43, 43, 1, 599040, 0xdec67f6e -0, 44, 44, 1, 599040, 0xbafa50c0 -0, 45, 45, 1, 599040, 0xc9181637 -0, 46, 46, 1, 599040, 0x95834e17 +0, 25, 25, 1, 599040, 0x00d87745 +0, 26, 26, 1, 599040, 0x9b689b16 +0, 27, 27, 1, 599040, 0x40ae530a +0, 28, 28, 1, 599040, 0x8284f649 +0, 29, 29, 1, 599040, 0x37423ae4 +0, 30, 30, 1, 599040, 0xb3f72b02 +0, 31, 31, 1, 599040, 0xc0cc5860 +0, 32, 32, 1, 599040, 0x00a0249f +0, 33, 33, 1, 599040, 0x7263f7cf +0, 34, 34, 1, 599040, 0x47054be4 +0, 35, 35, 1, 599040, 0xda083f52 +0, 36, 36, 1, 599040, 0xf2906ab1 +0, 37, 37, 1, 599040, 0x20936797 +0, 38, 38, 1, 599040, 0x644d7c3e +0, 39, 39, 1, 599040, 0x7c00e8bf +0, 40, 40, 1, 599040, 0x041f8a48 +0, 41, 41, 1, 599040, 0xcef6e936 +0, 42, 42, 1, 599040, 0x361461e9 +0, 43, 43, 1, 599040, 0xf663ba0a +0, 44, 44, 1, 599040, 0x4d3371d3 +0, 45, 45, 1, 599040, 0xed6b5c92 +0, 46, 46, 1, 599040, 0xdec67f6e +0, 47, 47, 1, 599040, 0xbafa50c0 +0, 48, 48, 1, 599040, 0xc9181637 +0, 49, 49, 1, 599040, 0x95834e17 diff --git a/tests/ref/fate/hevc-conformance-OPFLAG_B_Qualcomm_1 b/tests/ref/fate/hevc-conformance-OPFLAG_B_Qualcomm_1 index cc4a22f92..e71e3131a 100644 --- a/tests/ref/fate/hevc-conformance-OPFLAG_B_Qualcomm_1 +++ b/tests/ref/fate/hevc-conformance-OPFLAG_B_Qualcomm_1 @@ -42,62 +42,62 @@ 0, 36, 36, 1, 599040, 0xd2152e6b 0, 37, 37, 1, 599040, 0xe4c37cc7 0, 38, 38, 1, 599040, 0xec3393c3 -0, 39, 39, 1, 599040, 0x1fe16574 -0, 40, 40, 1, 599040, 0xa3a8c14d -0, 41, 41, 1, 599040, 0x32eb90aa -0, 42, 42, 1, 599040, 0xebca8310 -0, 43, 43, 1, 599040, 0x7888627f -0, 44, 44, 1, 599040, 0xe048335c -0, 45, 45, 1, 599040, 0xe2262b9c -0, 46, 46, 1, 599040, 0xb8c2b115 -0, 47, 47, 1, 599040, 0x2ff4194b -0, 48, 48, 1, 599040, 0x3a9b5520 -0, 49, 49, 1, 599040, 0xbd8c0486 -0, 50, 50, 1, 599040, 0xc8b8f29e -0, 51, 51, 1, 599040, 0xbc12f62c -0, 52, 52, 1, 599040, 0x04bb6438 -0, 53, 53, 1, 599040, 0x07971646 -0, 54, 54, 1, 599040, 0x0193dabe -0, 55, 55, 1, 599040, 0x20f41d9e -0, 56, 56, 1, 599040, 0x04b40718 -0, 57, 57, 1, 599040, 0x75d2c51c -0, 58, 58, 1, 599040, 0x9b8c2c50 -0, 59, 59, 1, 599040, 0x970e39ea -0, 60, 60, 1, 599040, 0x7c4264aa -0, 61, 61, 1, 599040, 0xe939a6fd -0, 62, 62, 1, 599040, 0xc8b95f8d -0, 63, 63, 1, 599040, 0x9e2f384a -0, 64, 64, 1, 599040, 0x7dc74724 -0, 65, 65, 1, 599040, 0x7e93bc5f -0, 66, 66, 1, 599040, 0x99b2c09d -0, 67, 67, 1, 599040, 0x284e436f -0, 68, 68, 1, 599040, 0xaa303eee -0, 69, 69, 1, 599040, 0x65e54342 -0, 70, 70, 1, 599040, 0x2fe183cd -0, 71, 71, 1, 599040, 0x5953c191 -0, 72, 72, 1, 599040, 0x0fc9a701 -0, 73, 73, 1, 599040, 0x0eea5327 -0, 74, 74, 1, 599040, 0x118752f1 -0, 75, 75, 1, 599040, 0x778c7711 -0, 76, 76, 1, 599040, 0x6f3ad6a5 -0, 77, 77, 1, 599040, 0xf70fcd3d -0, 78, 78, 1, 599040, 0x85a366cb -0, 79, 79, 1, 599040, 0xdda47432 -0, 80, 80, 1, 599040, 0x86379004 -0, 81, 81, 1, 599040, 0xfc539512 -0, 82, 82, 1, 599040, 0x04e70786 -0, 83, 83, 1, 599040, 0x7dddc8f7 -0, 84, 84, 1, 599040, 0xa76a3b6e -0, 85, 85, 1, 599040, 0x44183060 -0, 86, 86, 1, 599040, 0x6f691c5a -0, 87, 87, 1, 599040, 0x39d25e12 -0, 88, 88, 1, 599040, 0xfe3aad0d -0, 89, 89, 1, 599040, 0x57f76928 -0, 90, 90, 1, 599040, 0x4e68eed5 -0, 91, 91, 1, 599040, 0x3a589d50 -0, 92, 92, 1, 599040, 0x92ec69b8 -0, 93, 93, 1, 599040, 0x9f78926e -0, 94, 94, 1, 599040, 0xa1ca1b1d -0, 95, 95, 1, 599040, 0x140240eb -0, 96, 96, 1, 599040, 0x61fa01af -0, 97, 97, 1, 599040, 0x79f9e3ae +0, 40, 40, 1, 599040, 0x1fe16574 +0, 41, 41, 1, 599040, 0xa3a8c14d +0, 42, 42, 1, 599040, 0x32eb90aa +0, 43, 43, 1, 599040, 0xebca8310 +0, 44, 44, 1, 599040, 0x7888627f +0, 45, 45, 1, 599040, 0xe048335c +0, 46, 46, 1, 599040, 0xe2262b9c +0, 47, 47, 1, 599040, 0xb8c2b115 +0, 48, 48, 1, 599040, 0x2ff4194b +0, 49, 49, 1, 599040, 0x3a9b5520 +0, 50, 50, 1, 599040, 0xbd8c0486 +0, 51, 51, 1, 599040, 0xc8b8f29e +0, 52, 52, 1, 599040, 0xbc12f62c +0, 53, 53, 1, 599040, 0x04bb6438 +0, 54, 54, 1, 599040, 0x07971646 +0, 55, 55, 1, 599040, 0x0193dabe +0, 56, 56, 1, 599040, 0x20f41d9e +0, 57, 57, 1, 599040, 0x04b40718 +0, 58, 58, 1, 599040, 0x75d2c51c +0, 59, 59, 1, 599040, 0x9b8c2c50 +0, 60, 60, 1, 599040, 0x970e39ea +0, 61, 61, 1, 599040, 0x7c4264aa +0, 62, 62, 1, 599040, 0xe939a6fd +0, 63, 63, 1, 599040, 0xc8b95f8d +0, 64, 64, 1, 599040, 0x9e2f384a +0, 65, 65, 1, 599040, 0x7dc74724 +0, 66, 66, 1, 599040, 0x7e93bc5f +0, 67, 67, 1, 599040, 0x99b2c09d +0, 68, 68, 1, 599040, 0x284e436f +0, 69, 69, 1, 599040, 0xaa303eee +0, 70, 70, 1, 599040, 0x65e54342 +0, 71, 71, 1, 599040, 0x2fe183cd +0, 72, 72, 1, 599040, 0x5953c191 +0, 74, 74, 1, 599040, 0x0fc9a701 +0, 75, 75, 1, 599040, 0x0eea5327 +0, 76, 76, 1, 599040, 0x118752f1 +0, 77, 77, 1, 599040, 0x778c7711 +0, 78, 78, 1, 599040, 0x6f3ad6a5 +0, 79, 79, 1, 599040, 0xf70fcd3d +0, 80, 80, 1, 599040, 0x85a366cb +0, 81, 81, 1, 599040, 0xdda47432 +0, 82, 82, 1, 599040, 0x86379004 +0, 83, 83, 1, 599040, 0xfc539512 +0, 84, 84, 1, 599040, 0x04e70786 +0, 85, 85, 1, 599040, 0x7dddc8f7 +0, 86, 86, 1, 599040, 0xa76a3b6e +0, 87, 87, 1, 599040, 0x44183060 +0, 88, 88, 1, 599040, 0x6f691c5a +0, 89, 89, 1, 599040, 0x39d25e12 +0, 90, 90, 1, 599040, 0xfe3aad0d +0, 91, 91, 1, 599040, 0x57f76928 +0, 92, 92, 1, 599040, 0x4e68eed5 +0, 93, 93, 1, 599040, 0x3a589d50 +0, 94, 94, 1, 599040, 0x92ec69b8 +0, 95, 95, 1, 599040, 0x9f78926e +0, 96, 96, 1, 599040, 0xa1ca1b1d +0, 97, 97, 1, 599040, 0x140240eb +0, 98, 98, 1, 599040, 0x61fa01af +0, 99, 99, 1, 599040, 0x79f9e3ae diff --git a/tests/ref/fate/hevc-conformance-OPFLAG_C_Qualcomm_1 b/tests/ref/fate/hevc-conformance-OPFLAG_C_Qualcomm_1 index 233b04267..ffc4f5177 100644 --- a/tests/ref/fate/hevc-conformance-OPFLAG_C_Qualcomm_1 +++ b/tests/ref/fate/hevc-conformance-OPFLAG_C_Qualcomm_1 @@ -18,84 +18,84 @@ 0, 12, 12, 1, 599040, 0x1991f1f9 0, 13, 13, 1, 599040, 0x36e54ba2 0, 14, 14, 1, 599040, 0x698ce0c6 -0, 15, 15, 1, 599040, 0xc6dd131e -0, 16, 16, 1, 599040, 0x0a22f4c5 -0, 17, 17, 1, 599040, 0xd6a0c196 -0, 18, 18, 1, 599040, 0x699a3e69 -0, 19, 19, 1, 599040, 0x4227009b -0, 20, 20, 1, 599040, 0xd1d5dcb4 -0, 21, 21, 1, 599040, 0x58b2edb3 -0, 22, 22, 1, 599040, 0xd1f795d8 -0, 23, 23, 1, 599040, 0x3331d5e6 -0, 24, 24, 1, 599040, 0x5e5ec2c9 -0, 25, 25, 1, 599040, 0x3b907bf5 -0, 26, 26, 1, 599040, 0xefcbf471 -0, 27, 27, 1, 599040, 0x2769a578 -0, 28, 28, 1, 599040, 0x812ce986 -0, 29, 29, 1, 599040, 0xf07c212c -0, 30, 30, 1, 599040, 0x00a0249f -0, 31, 31, 1, 599040, 0x7263f7cf -0, 32, 32, 1, 599040, 0x47054be4 -0, 33, 33, 1, 599040, 0xda083f52 -0, 34, 34, 1, 599040, 0xf2906ab1 -0, 35, 35, 1, 599040, 0x20936797 -0, 36, 36, 1, 599040, 0x644d7c3e -0, 37, 37, 1, 599040, 0x7c00e8bf -0, 38, 38, 1, 599040, 0x041f8a48 -0, 39, 39, 1, 599040, 0xcef6e936 -0, 40, 40, 1, 599040, 0x361461e9 -0, 41, 41, 1, 599040, 0xf663ba0a -0, 42, 42, 1, 599040, 0x4d3371d3 -0, 43, 43, 1, 599040, 0xed6b5c92 -0, 44, 44, 1, 599040, 0xdec67f6e -0, 45, 45, 1, 599040, 0xbafa50c0 -0, 46, 46, 1, 599040, 0xc9181637 -0, 47, 47, 1, 599040, 0x29eadcac -0, 48, 48, 1, 599040, 0xb258430f -0, 49, 49, 1, 599040, 0x49dc8716 -0, 50, 50, 1, 599040, 0x80b0a3b3 -0, 51, 51, 1, 599040, 0x5d8275a7 -0, 52, 52, 1, 599040, 0xe236242d -0, 53, 53, 1, 599040, 0x3e14bb43 -0, 54, 54, 1, 599040, 0x20e6e2d7 -0, 55, 55, 1, 599040, 0x19cad4ee -0, 56, 56, 1, 599040, 0x13fd16f1 -0, 57, 57, 1, 599040, 0x98e56b95 -0, 58, 58, 1, 599040, 0x028e4c6a -0, 59, 59, 1, 599040, 0x5bd1131d -0, 60, 60, 1, 599040, 0x0afe3873 -0, 61, 61, 1, 599040, 0xea93e425 -0, 62, 62, 1, 599040, 0xeb301be1 -0, 63, 63, 1, 599040, 0x443ca0a3 -0, 64, 64, 1, 599040, 0xb68b40a1 -0, 65, 65, 1, 599040, 0xf58f75b9 -0, 66, 66, 1, 599040, 0xefa27c52 -0, 67, 67, 1, 599040, 0xac676fa5 -0, 68, 68, 1, 599040, 0x688d1582 -0, 69, 69, 1, 599040, 0x9067a4ef -0, 70, 70, 1, 599040, 0xdc753d6c -0, 71, 71, 1, 599040, 0x6f6da304 -0, 72, 72, 1, 599040, 0xa7606f97 -0, 73, 73, 1, 599040, 0xb53c8c18 -0, 74, 74, 1, 599040, 0x3572d550 -0, 75, 75, 1, 599040, 0x123d5423 -0, 76, 76, 1, 599040, 0x89f11e50 -0, 77, 77, 1, 599040, 0x702649cc -0, 78, 78, 1, 599040, 0x2b4767c4 -0, 79, 79, 1, 599040, 0xf18b9628 -0, 80, 80, 1, 599040, 0x1ef72a6b -0, 81, 81, 1, 599040, 0x0a8c9641 -0, 82, 82, 1, 599040, 0xf2fa0233 -0, 83, 83, 1, 599040, 0x99385e51 -0, 84, 84, 1, 599040, 0x77b413cf -0, 85, 85, 1, 599040, 0x6360c9e3 -0, 86, 86, 1, 599040, 0xe216b383 -0, 87, 87, 1, 599040, 0x54df8826 -0, 88, 88, 1, 599040, 0x6691e1ee -0, 89, 89, 1, 599040, 0x37bebd20 -0, 90, 90, 1, 599040, 0xf05184e4 -0, 91, 91, 1, 599040, 0xbd7fab4f -0, 92, 92, 1, 599040, 0x70211cdc -0, 93, 93, 1, 599040, 0x4f4c375b -0, 94, 94, 1, 599040, 0x2d645b5a -0, 95, 95, 1, 599040, 0x475d263f +0, 16, 16, 1, 599040, 0xc6dd131e +0, 17, 17, 1, 599040, 0x0a22f4c5 +0, 18, 18, 1, 599040, 0xd6a0c196 +0, 19, 19, 1, 599040, 0x699a3e69 +0, 20, 20, 1, 599040, 0x4227009b +0, 21, 21, 1, 599040, 0xd1d5dcb4 +0, 22, 22, 1, 599040, 0x58b2edb3 +0, 23, 23, 1, 599040, 0xd1f795d8 +0, 24, 24, 1, 599040, 0x3331d5e6 +0, 25, 25, 1, 599040, 0x5e5ec2c9 +0, 26, 26, 1, 599040, 0x3b907bf5 +0, 27, 27, 1, 599040, 0xefcbf471 +0, 28, 28, 1, 599040, 0x2769a578 +0, 30, 30, 1, 599040, 0x812ce986 +0, 31, 31, 1, 599040, 0xf07c212c +0, 32, 32, 1, 599040, 0x00a0249f +0, 33, 33, 1, 599040, 0x7263f7cf +0, 34, 34, 1, 599040, 0x47054be4 +0, 35, 35, 1, 599040, 0xda083f52 +0, 36, 36, 1, 599040, 0xf2906ab1 +0, 37, 37, 1, 599040, 0x20936797 +0, 38, 38, 1, 599040, 0x644d7c3e +0, 39, 39, 1, 599040, 0x7c00e8bf +0, 40, 40, 1, 599040, 0x041f8a48 +0, 41, 41, 1, 599040, 0xcef6e936 +0, 42, 42, 1, 599040, 0x361461e9 +0, 43, 43, 1, 599040, 0xf663ba0a +0, 44, 44, 1, 599040, 0x4d3371d3 +0, 45, 45, 1, 599040, 0xed6b5c92 +0, 47, 47, 1, 599040, 0xdec67f6e +0, 48, 48, 1, 599040, 0xbafa50c0 +0, 49, 49, 1, 599040, 0xc9181637 +0, 50, 50, 1, 599040, 0x29eadcac +0, 51, 51, 1, 599040, 0xb258430f +0, 52, 52, 1, 599040, 0x49dc8716 +0, 53, 53, 1, 599040, 0x80b0a3b3 +0, 54, 54, 1, 599040, 0x5d8275a7 +0, 55, 55, 1, 599040, 0xe236242d +0, 56, 56, 1, 599040, 0x3e14bb43 +0, 57, 57, 1, 599040, 0x20e6e2d7 +0, 58, 58, 1, 599040, 0x19cad4ee +0, 59, 59, 1, 599040, 0x13fd16f1 +0, 60, 60, 1, 599040, 0x98e56b95 +0, 61, 61, 1, 599040, 0x028e4c6a +0, 63, 63, 1, 599040, 0x5bd1131d +0, 64, 64, 1, 599040, 0x0afe3873 +0, 65, 65, 1, 599040, 0xea93e425 +0, 66, 66, 1, 599040, 0xeb301be1 +0, 67, 67, 1, 599040, 0x443ca0a3 +0, 68, 68, 1, 599040, 0xb68b40a1 +0, 69, 69, 1, 599040, 0xf58f75b9 +0, 70, 70, 1, 599040, 0xefa27c52 +0, 71, 71, 1, 599040, 0xac676fa5 +0, 72, 72, 1, 599040, 0x688d1582 +0, 73, 73, 1, 599040, 0x9067a4ef +0, 74, 74, 1, 599040, 0xdc753d6c +0, 75, 75, 1, 599040, 0x6f6da304 +0, 76, 76, 1, 599040, 0xa7606f97 +0, 77, 77, 1, 599040, 0xb53c8c18 +0, 78, 78, 1, 599040, 0x3572d550 +0, 79, 79, 1, 599040, 0x123d5423 +0, 80, 80, 1, 599040, 0x89f11e50 +0, 81, 81, 1, 599040, 0x702649cc +0, 82, 82, 1, 599040, 0x2b4767c4 +0, 83, 83, 1, 599040, 0xf18b9628 +0, 84, 84, 1, 599040, 0x1ef72a6b +0, 85, 85, 1, 599040, 0x0a8c9641 +0, 86, 86, 1, 599040, 0xf2fa0233 +0, 87, 87, 1, 599040, 0x99385e51 +0, 88, 88, 1, 599040, 0x77b413cf +0, 89, 89, 1, 599040, 0x6360c9e3 +0, 90, 90, 1, 599040, 0xe216b383 +0, 91, 91, 1, 599040, 0x54df8826 +0, 92, 92, 1, 599040, 0x6691e1ee +0, 93, 93, 1, 599040, 0x37bebd20 +0, 94, 94, 1, 599040, 0xf05184e4 +0, 95, 95, 1, 599040, 0xbd7fab4f +0, 96, 96, 1, 599040, 0x70211cdc +0, 97, 97, 1, 599040, 0x4f4c375b +0, 98, 98, 1, 599040, 0x2d645b5a +0, 99, 99, 1, 599040, 0x475d263f diff --git a/tests/ref/fate/hevc-conformance-RAP_A_docomo_4 b/tests/ref/fate/hevc-conformance-RAP_A_docomo_4 index 51ea08b58..fbbedb236 100644 --- a/tests/ref/fate/hevc-conformance-RAP_A_docomo_4 +++ b/tests/ref/fate/hevc-conformance-RAP_A_docomo_4 @@ -3,89 +3,89 @@ #codec_id 0: rawvideo #dimensions 0: 416x240 #sar 0: 0/1 -0, 0, 0, 1, 149760, 0x1ae5f13d -0, 1, 1, 1, 149760, 0x0a6ad0e3 -0, 2, 2, 1, 149760, 0x2415af05 -0, 3, 3, 1, 149760, 0xf50f6eef -0, 4, 4, 1, 149760, 0xef65835c -0, 5, 5, 1, 149760, 0x4929b5cb -0, 6, 6, 1, 149760, 0x165c6f55 -0, 7, 7, 1, 149760, 0x9caaa249 -0, 8, 8, 1, 149760, 0x6c25c4cf -0, 9, 9, 1, 149760, 0x4678cef0 -0, 10, 10, 1, 149760, 0x72e04433 -0, 11, 11, 1, 149760, 0x36f8aa9d -0, 12, 12, 1, 149760, 0x255189ad -0, 13, 13, 1, 149760, 0x712d7f7f -0, 14, 14, 1, 149760, 0x4d088988 -0, 15, 15, 1, 149760, 0xc0da3925 -0, 16, 16, 1, 149760, 0x9990db7c -0, 17, 17, 1, 149760, 0xb02cc0e8 -0, 18, 18, 1, 149760, 0x3e859d8f -0, 19, 19, 1, 149760, 0xce786bc1 -0, 20, 20, 1, 149760, 0x87555e5f -0, 21, 21, 1, 149760, 0x3c95fb7e -0, 22, 22, 1, 149760, 0xf092b65e -0, 23, 23, 1, 149760, 0x7db2c04c -0, 24, 24, 1, 149760, 0x7d39eb21 -0, 25, 25, 1, 149760, 0x2cfd7d57 -0, 26, 26, 1, 149760, 0xb1902c06 -0, 27, 27, 1, 149760, 0xe0eae1d7 -0, 28, 28, 1, 149760, 0xf8212977 -0, 29, 29, 1, 149760, 0x6cb31328 -0, 30, 30, 1, 149760, 0x862ab736 -0, 31, 31, 1, 149760, 0xc7a87f44 -0, 32, 32, 1, 149760, 0x8ff7a1a1 -0, 33, 33, 1, 149760, 0xd7bee49b -0, 34, 34, 1, 149760, 0x1925db84 -0, 35, 35, 1, 149760, 0xf32a7dc6 -0, 36, 36, 1, 149760, 0x02a1e3b6 -0, 37, 37, 1, 149760, 0xb6398aad -0, 38, 38, 1, 149760, 0xa3756e2d -0, 39, 39, 1, 149760, 0xf90f3732 -0, 40, 40, 1, 149760, 0x3b05115a -0, 41, 41, 1, 149760, 0x81ca9bdb -0, 42, 42, 1, 149760, 0xa75ee938 -0, 43, 43, 1, 149760, 0x9e5c232f -0, 44, 44, 1, 149760, 0x64cb04e9 -0, 45, 45, 1, 149760, 0x4064df52 -0, 46, 46, 1, 149760, 0x47fa0afc -0, 47, 47, 1, 149760, 0xd209252e -0, 48, 48, 1, 149760, 0x2f811f02 -0, 49, 49, 1, 149760, 0x733b6721 -0, 50, 50, 1, 149760, 0x30b12427 -0, 51, 51, 1, 149760, 0xdf58d3e2 -0, 52, 52, 1, 149760, 0xc144d7be -0, 53, 53, 1, 149760, 0x48f0ac79 -0, 54, 54, 1, 149760, 0xb8d8a2c6 -0, 55, 55, 1, 149760, 0x2a7d916d -0, 56, 56, 1, 149760, 0xd9d38cd5 -0, 57, 57, 1, 149760, 0xd7c7f9a6 -0, 58, 58, 1, 149760, 0x64d0df7a -0, 59, 59, 1, 149760, 0x4e365cff -0, 60, 60, 1, 149760, 0x74bc2a8b -0, 61, 61, 1, 149760, 0x70a7cd2b -0, 62, 62, 1, 149760, 0x0836b51e -0, 63, 63, 1, 149760, 0xbc37b5d7 -0, 64, 64, 1, 149760, 0xb6d651e5 -0, 65, 65, 1, 149760, 0x7aa0e35f -0, 66, 66, 1, 149760, 0x0fbc89a3 -0, 67, 67, 1, 149760, 0x2ca2f2a6 -0, 68, 68, 1, 149760, 0xf742c5c5 -0, 69, 69, 1, 149760, 0x4117208f -0, 70, 70, 1, 149760, 0xec392efb -0, 71, 71, 1, 149760, 0xbfba5063 -0, 72, 72, 1, 149760, 0xb2499f48 -0, 73, 73, 1, 149760, 0xf1183244 -0, 74, 74, 1, 149760, 0x364a6400 -0, 75, 75, 1, 149760, 0xfcfddf36 -0, 76, 76, 1, 149760, 0xbcc1b37e -0, 77, 77, 1, 149760, 0xab364748 -0, 78, 78, 1, 149760, 0xebb27fcd -0, 79, 79, 1, 149760, 0xe2e7a723 -0, 80, 80, 1, 149760, 0xf671b5e0 -0, 81, 81, 1, 149760, 0xbf0cc349 -0, 82, 82, 1, 149760, 0xf195d868 -0, 83, 83, 1, 149760, 0xe0097460 -0, 84, 84, 1, 149760, 0x3d4c1812 -0, 85, 85, 1, 149760, 0x133cd867 +0, 7, 7, 1, 149760, 0x1ae5f13d +0, 8, 8, 1, 149760, 0x0a6ad0e3 +0, 9, 9, 1, 149760, 0x2415af05 +0, 10, 10, 1, 149760, 0xf50f6eef +0, 11, 11, 1, 149760, 0xef65835c +0, 12, 12, 1, 149760, 0x4929b5cb +0, 13, 13, 1, 149760, 0x165c6f55 +0, 14, 14, 1, 149760, 0x9caaa249 +0, 15, 15, 1, 149760, 0x6c25c4cf +0, 16, 16, 1, 149760, 0x4678cef0 +0, 17, 17, 1, 149760, 0x72e04433 +0, 18, 18, 1, 149760, 0x36f8aa9d +0, 19, 19, 1, 149760, 0x255189ad +0, 20, 20, 1, 149760, 0x712d7f7f +0, 21, 21, 1, 149760, 0x4d088988 +0, 22, 22, 1, 149760, 0xc0da3925 +0, 23, 23, 1, 149760, 0x9990db7c +0, 24, 24, 1, 149760, 0xb02cc0e8 +0, 25, 25, 1, 149760, 0x3e859d8f +0, 26, 26, 1, 149760, 0xce786bc1 +0, 27, 27, 1, 149760, 0x87555e5f +0, 28, 28, 1, 149760, 0x3c95fb7e +0, 29, 29, 1, 149760, 0xf092b65e +0, 30, 30, 1, 149760, 0x7db2c04c +0, 31, 31, 1, 149760, 0x7d39eb21 +0, 32, 32, 1, 149760, 0x2cfd7d57 +0, 33, 33, 1, 149760, 0xb1902c06 +0, 34, 34, 1, 149760, 0xe0eae1d7 +0, 35, 35, 1, 149760, 0xf8212977 +0, 36, 36, 1, 149760, 0x6cb31328 +0, 37, 37, 1, 149760, 0x862ab736 +0, 38, 38, 1, 149760, 0xc7a87f44 +0, 39, 39, 1, 149760, 0x8ff7a1a1 +0, 40, 40, 1, 149760, 0xd7bee49b +0, 41, 41, 1, 149760, 0x1925db84 +0, 42, 42, 1, 149760, 0xf32a7dc6 +0, 43, 43, 1, 149760, 0x02a1e3b6 +0, 44, 44, 1, 149760, 0xb6398aad +0, 45, 45, 1, 149760, 0xa3756e2d +0, 46, 46, 1, 149760, 0xf90f3732 +0, 47, 47, 1, 149760, 0x3b05115a +0, 48, 48, 1, 149760, 0x81ca9bdb +0, 49, 49, 1, 149760, 0xa75ee938 +0, 50, 50, 1, 149760, 0x9e5c232f +0, 51, 51, 1, 149760, 0x64cb04e9 +0, 52, 52, 1, 149760, 0x4064df52 +0, 53, 53, 1, 149760, 0x47fa0afc +0, 54, 54, 1, 149760, 0xd209252e +0, 55, 55, 1, 149760, 0x2f811f02 +0, 56, 56, 1, 149760, 0x733b6721 +0, 57, 57, 1, 149760, 0x30b12427 +0, 58, 58, 1, 149760, 0xdf58d3e2 +0, 59, 59, 1, 149760, 0xc144d7be +0, 60, 60, 1, 149760, 0x48f0ac79 +0, 61, 61, 1, 149760, 0xb8d8a2c6 +0, 62, 62, 1, 149760, 0x2a7d916d +0, 63, 63, 1, 149760, 0xd9d38cd5 +0, 64, 64, 1, 149760, 0xd7c7f9a6 +0, 65, 65, 1, 149760, 0x64d0df7a +0, 66, 66, 1, 149760, 0x4e365cff +0, 67, 67, 1, 149760, 0x74bc2a8b +0, 68, 68, 1, 149760, 0x70a7cd2b +0, 69, 69, 1, 149760, 0x0836b51e +0, 70, 70, 1, 149760, 0xbc37b5d7 +0, 71, 71, 1, 149760, 0xb6d651e5 +0, 72, 72, 1, 149760, 0x7aa0e35f +0, 73, 73, 1, 149760, 0x0fbc89a3 +0, 74, 74, 1, 149760, 0x2ca2f2a6 +0, 75, 75, 1, 149760, 0xf742c5c5 +0, 76, 76, 1, 149760, 0x4117208f +0, 77, 77, 1, 149760, 0xec392efb +0, 78, 78, 1, 149760, 0xbfba5063 +0, 79, 79, 1, 149760, 0xb2499f48 +0, 80, 80, 1, 149760, 0xf1183244 +0, 81, 81, 1, 149760, 0x364a6400 +0, 82, 82, 1, 149760, 0xfcfddf36 +0, 83, 83, 1, 149760, 0xbcc1b37e +0, 84, 84, 1, 149760, 0xab364748 +0, 85, 85, 1, 149760, 0xebb27fcd +0, 86, 86, 1, 149760, 0xe2e7a723 +0, 87, 87, 1, 149760, 0xf671b5e0 +0, 88, 88, 1, 149760, 0xbf0cc349 +0, 89, 89, 1, 149760, 0xf195d868 +0, 90, 90, 1, 149760, 0xe0097460 +0, 91, 91, 1, 149760, 0x3d4c1812 +0, 92, 92, 1, 149760, 0x133cd867 diff --git a/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1 b/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1 index 53e733bd7..e661ff245 100644 --- a/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1 +++ b/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1 @@ -70,16 +70,16 @@ 0, 64, 64, 1, 149760, 0x3362678b 0, 65, 65, 1, 149760, 0x6e7fc851 0, 66, 66, 1, 149760, 0x33f96449 -0, 67, 67, 1, 149760, 0xb3ba8cfb -0, 68, 68, 1, 149760, 0x64787995 -0, 69, 69, 1, 149760, 0xc10de4c4 -0, 70, 70, 1, 149760, 0x18dd343f -0, 71, 71, 1, 149760, 0xa1c51358 -0, 72, 72, 1, 149760, 0x91fe6361 -0, 73, 73, 1, 149760, 0xeec85f94 -0, 74, 74, 1, 149760, 0x00a57402 -0, 75, 75, 1, 149760, 0x4e88cc16 -0, 76, 76, 1, 149760, 0xdbd51976 -0, 77, 77, 1, 149760, 0xfebf6b1a -0, 78, 78, 1, 149760, 0x052546d2 -0, 79, 79, 1, 149760, 0x046cd73b +0, 77, 77, 1, 149760, 0xb3ba8cfb +0, 78, 78, 1, 149760, 0x64787995 +0, 79, 79, 1, 149760, 0xc10de4c4 +0, 80, 80, 1, 149760, 0x18dd343f +0, 81, 81, 1, 149760, 0xa1c51358 +0, 82, 82, 1, 149760, 0x91fe6361 +0, 83, 83, 1, 149760, 0xeec85f94 +0, 84, 84, 1, 149760, 0x00a57402 +0, 85, 85, 1, 149760, 0x4e88cc16 +0, 86, 86, 1, 149760, 0xdbd51976 +0, 87, 87, 1, 149760, 0xfebf6b1a +0, 88, 88, 1, 149760, 0x052546d2 +0, 89, 89, 1, 149760, 0x046cd73b diff --git a/tests/ref/fate/hevc-conformance-SDH_A_Orange_3 b/tests/ref/fate/hevc-conformance-SDH_A_Orange_3 index f3ef192c6..e5bc4f812 100644 --- a/tests/ref/fate/hevc-conformance-SDH_A_Orange_3 +++ b/tests/ref/fate/hevc-conformance-SDH_A_Orange_3 @@ -3,5 +3,5 @@ #codec_id 0: rawvideo #dimensions 0: 1920x1080 #sar 0: 0/1 -0, 0, 0, 1, 3110400, 0x0117aa5d -0, 1, 1, 1, 3110400, 0xa737bc56 +0, 2, 2, 1, 3110400, 0x0117aa5d +0, 3, 3, 1, 3110400, 0xa737bc56 diff --git a/tests/ref/fate/hevc-hdr10-plus-metadata b/tests/ref/fate/hevc-hdr10-plus-metadata new file mode 100644 index 000000000..f226cd8c7 --- /dev/null +++ b/tests/ref/fate/hevc-hdr10-plus-metadata @@ -0,0 +1,62 @@ +[FRAME] +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=13250/50000 +red_y=34500/50000 +green_x=7500/50000 +green_y=3000/50000 +blue_x=34000/50000 +blue_y=16000/50000 +white_point_x=15635/50000 +white_point_y=16450/50000 +min_luminance=50/10000 +max_luminance=10000000/10000 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=200 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=HDR Dynamic Metadata SMPTE2094-40 (HDR10+) +application version=1 +num_windows=1 +targeted_system_display_maximum_luminance=400/1 +maxscl=3340/100000 +maxscl=2870/100000 +maxscl=2720/100000 +average_maxrgb=510/100000 +num_distribution_maxrgb_percentiles=9 +distribution_maxrgb_percentage=1 +distribution_maxrgb_percentile=30/100000 +distribution_maxrgb_percentage=5 +distribution_maxrgb_percentile=2940/100000 +distribution_maxrgb_percentage=10 +distribution_maxrgb_percentile=255/100000 +distribution_maxrgb_percentage=25 +distribution_maxrgb_percentile=70/100000 +distribution_maxrgb_percentage=50 +distribution_maxrgb_percentile=1340/100000 +distribution_maxrgb_percentage=75 +distribution_maxrgb_percentile=1600/100000 +distribution_maxrgb_percentage=90 +distribution_maxrgb_percentile=1850/100000 +distribution_maxrgb_percentage=95 +distribution_maxrgb_percentile=1950/100000 +distribution_maxrgb_percentage=99 +distribution_maxrgb_percentile=2940/100000 +fraction_bright_pixels=1/1000 +knee_point_x=0/4095 +knee_point_y=0/4095 +num_bezier_curve_anchors=9 +bezier_curve_anchors=102/1023 +bezier_curve_anchors=205/1023 +bezier_curve_anchors=307/1023 +bezier_curve_anchors=410/1023 +bezier_curve_anchors=512/1023 +bezier_curve_anchors=614/1023 +bezier_curve_anchors=717/1023 +bezier_curve_anchors=819/1023 +bezier_curve_anchors=922/1023 +[/SIDE_DATA] +[/FRAME] diff --git a/tests/ref/fate/hevc-monochrome-crop b/tests/ref/fate/hevc-monochrome-crop index 4e45412ac..384404da6 100644 --- a/tests/ref/fate/hevc-monochrome-crop +++ b/tests/ref/fate/hevc-monochrome-crop @@ -1,6 +1,9 @@ [FRAME] width=384 height=240 +[SIDE_DATA] +side_data_type=H.26[45] User Data Unregistered SEI message +[/SIDE_DATA] [/FRAME] [STREAM] width=384 diff --git a/tests/ref/fate/hevc-small422chroma b/tests/ref/fate/hevc-small422chroma new file mode 100644 index 000000000..954829a0a --- /dev/null +++ b/tests/ref/fate/hevc-small422chroma @@ -0,0 +1,6 @@ +#tb 0: 1/50 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 3840x2160 +#sar 0: 1/1 +0, 11, 11, 1, 33177600, 0x53015e18 diff --git a/tests/ref/fate/hls-fmp4_ac3 b/tests/ref/fate/hls-fmp4_ac3 new file mode 100644 index 000000000..caccd70fa --- /dev/null +++ b/tests/ref/fate/hls-fmp4_ac3 @@ -0,0 +1,8 @@ +[STREAM] +codec_name=ac3 +sample_fmt=fltp +channels=6 +channel_layout=5.1(side) +[SIDE_DATA] +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/iff-byterun1 b/tests/ref/fate/iff-byterun1 index 8e6f949f6..ccb852fb0 100644 --- a/tests/ref/fate/iff-byterun1 +++ b/tests/ref/fate/iff-byterun1 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 320x240 #sar 0: 5/6 -0, 0, 0, 0, 230400, 0x35e51c62 +0, 0, 0, 1, 230400, 0x35e51c62 diff --git a/tests/ref/fate/iff-ilbm b/tests/ref/fate/iff-ilbm index 38c43eb58..93e026da9 100644 --- a/tests/ref/fate/iff-ilbm +++ b/tests/ref/fate/iff-ilbm @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 320x240 #sar 0: 1/1 -0, 0, 0, 0, 230400, 0x0929e342 +0, 0, 0, 1, 230400, 0x0929e342 diff --git a/tests/ref/fate/imgutils b/tests/ref/fate/imgutils index aba482221..c968ea0e8 100644 --- a/tests/ref/fate/imgutils +++ b/tests/ref/fate/imgutils @@ -53,3 +53,186 @@ 0000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000 + +yuv420p planes: 3, linesizes: 64 32 32 0, plane_sizes: 3072 768 768 0, plane_offsets: 3072 768 0, total_size: 4608 +yuyv422 planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +rgb24 planes: 1, linesizes: 192 0 0 0, plane_sizes: 9216 0 0 0, plane_offsets: 0 0 0, total_size: 9216 +bgr24 planes: 1, linesizes: 192 0 0 0, plane_sizes: 9216 0 0 0, plane_offsets: 0 0 0, total_size: 9216 +yuv422p planes: 3, linesizes: 64 32 32 0, plane_sizes: 3072 1536 1536 0, plane_offsets: 3072 1536 0, total_size: 6144 +yuv444p planes: 3, linesizes: 64 64 64 0, plane_sizes: 3072 3072 3072 0, plane_offsets: 3072 3072 0, total_size: 9216 +yuv410p planes: 3, linesizes: 64 16 16 0, plane_sizes: 3072 192 192 0, plane_offsets: 3072 192 0, total_size: 3456 +yuv411p planes: 3, linesizes: 64 16 16 0, plane_sizes: 3072 768 768 0, plane_offsets: 3072 768 0, total_size: 4608 +gray planes: 2, linesizes: 64 0 0 0, plane_sizes: 3072 1024 0 0, plane_offsets: 3072 0 0, total_size: 4096 +monow planes: 1, linesizes: 8 0 0 0, plane_sizes: 384 0 0 0, plane_offsets: 0 0 0, total_size: 384 +monob planes: 1, linesizes: 8 0 0 0, plane_sizes: 384 0 0 0, plane_offsets: 0 0 0, total_size: 384 +pal8 planes: 2, linesizes: 64 0 0 0, plane_sizes: 3072 1024 0 0, plane_offsets: 3072 0 0, total_size: 4096 +yuvj420p planes: 3, linesizes: 64 32 32 0, plane_sizes: 3072 768 768 0, plane_offsets: 3072 768 0, total_size: 4608 +yuvj422p planes: 3, linesizes: 64 32 32 0, plane_sizes: 3072 1536 1536 0, plane_offsets: 3072 1536 0, total_size: 6144 +yuvj444p planes: 3, linesizes: 64 64 64 0, plane_sizes: 3072 3072 3072 0, plane_offsets: 3072 3072 0, total_size: 9216 +uyvy422 planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +uyyvyy411 planes: 1, linesizes: 96 0 0 0, plane_sizes: 4608 0 0 0, plane_offsets: 0 0 0, total_size: 4608 +bgr8 planes: 2, linesizes: 64 0 0 0, plane_sizes: 3072 1024 0 0, plane_offsets: 3072 0 0, total_size: 4096 +bgr4 planes: 1, linesizes: 32 0 0 0, plane_sizes: 1536 0 0 0, plane_offsets: 0 0 0, total_size: 1536 +bgr4_byte planes: 2, linesizes: 64 0 0 0, plane_sizes: 3072 1024 0 0, plane_offsets: 3072 0 0, total_size: 4096 +rgb8 planes: 2, linesizes: 64 0 0 0, plane_sizes: 3072 1024 0 0, plane_offsets: 3072 0 0, total_size: 4096 +rgb4 planes: 1, linesizes: 32 0 0 0, plane_sizes: 1536 0 0 0, plane_offsets: 0 0 0, total_size: 1536 +rgb4_byte planes: 2, linesizes: 64 0 0 0, plane_sizes: 3072 1024 0 0, plane_offsets: 3072 0 0, total_size: 4096 +nv12 planes: 2, linesizes: 64 64 0 0, plane_sizes: 3072 1536 0 0, plane_offsets: 3072 0 0, total_size: 4608 +nv21 planes: 2, linesizes: 64 64 0 0, plane_sizes: 3072 1536 0 0, plane_offsets: 3072 0 0, total_size: 4608 +argb planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +rgba planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +abgr planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +bgra planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +gray16be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +gray16le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +yuv440p planes: 3, linesizes: 64 64 64 0, plane_sizes: 3072 1536 1536 0, plane_offsets: 3072 1536 0, total_size: 6144 +yuvj440p planes: 3, linesizes: 64 64 64 0, plane_sizes: 3072 1536 1536 0, plane_offsets: 3072 1536 0, total_size: 6144 +yuva420p planes: 4, linesizes: 64 32 32 64, plane_sizes: 3072 768 768 3072, plane_offsets: 3072 768 768, total_size: 7680 +rgb48be planes: 1, linesizes: 384 0 0 0, plane_sizes: 18432 0 0 0, plane_offsets: 0 0 0, total_size: 18432 +rgb48le planes: 1, linesizes: 384 0 0 0, plane_sizes: 18432 0 0 0, plane_offsets: 0 0 0, total_size: 18432 +rgb565be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +rgb565le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +rgb555be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +rgb555le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bgr565be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bgr565le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bgr555be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bgr555le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +yuv420p16le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv420p16be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv422p16le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv422p16be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv444p16le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuv444p16be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +rgb444le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +rgb444be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bgr444le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bgr444be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +ya8 planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bgr48be planes: 1, linesizes: 384 0 0 0, plane_sizes: 18432 0 0 0, plane_offsets: 0 0 0, total_size: 18432 +bgr48le planes: 1, linesizes: 384 0 0 0, plane_sizes: 18432 0 0 0, plane_offsets: 0 0 0, total_size: 18432 +yuv420p9be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv420p9le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv420p10be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv420p10le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv422p10be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv422p10le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv444p9be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuv444p9le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuv444p10be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuv444p10le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuv422p9be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv422p9le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +gbrp planes: 3, linesizes: 64 64 64 0, plane_sizes: 3072 3072 3072 0, plane_offsets: 3072 3072 0, total_size: 9216 +gbrp9be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +gbrp9le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +gbrp10be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +gbrp10le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +gbrp16be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +gbrp16le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuva422p planes: 4, linesizes: 64 32 32 64, plane_sizes: 3072 1536 1536 3072, plane_offsets: 3072 1536 1536, total_size: 9216 +yuva444p planes: 4, linesizes: 64 64 64 64, plane_sizes: 3072 3072 3072 3072, plane_offsets: 3072 3072 3072, total_size: 12288 +yuva420p9be planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 1536 1536 6144, plane_offsets: 6144 1536 1536, total_size: 15360 +yuva420p9le planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 1536 1536 6144, plane_offsets: 6144 1536 1536, total_size: 15360 +yuva422p9be planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 3072 3072 6144, plane_offsets: 6144 3072 3072, total_size: 18432 +yuva422p9le planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 3072 3072 6144, plane_offsets: 6144 3072 3072, total_size: 18432 +yuva444p9be planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +yuva444p9le planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +yuva420p10be planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 1536 1536 6144, plane_offsets: 6144 1536 1536, total_size: 15360 +yuva420p10le planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 1536 1536 6144, plane_offsets: 6144 1536 1536, total_size: 15360 +yuva422p10be planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 3072 3072 6144, plane_offsets: 6144 3072 3072, total_size: 18432 +yuva422p10le planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 3072 3072 6144, plane_offsets: 6144 3072 3072, total_size: 18432 +yuva444p10be planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +yuva444p10le planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +yuva420p16be planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 1536 1536 6144, plane_offsets: 6144 1536 1536, total_size: 15360 +yuva420p16le planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 1536 1536 6144, plane_offsets: 6144 1536 1536, total_size: 15360 +yuva422p16be planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 3072 3072 6144, plane_offsets: 6144 3072 3072, total_size: 18432 +yuva422p16le planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 3072 3072 6144, plane_offsets: 6144 3072 3072, total_size: 18432 +yuva444p16be planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +yuva444p16le planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +xyz12le planes: 1, linesizes: 384 0 0 0, plane_sizes: 18432 0 0 0, plane_offsets: 0 0 0, total_size: 18432 +xyz12be planes: 1, linesizes: 384 0 0 0, plane_sizes: 18432 0 0 0, plane_offsets: 0 0 0, total_size: 18432 +nv16 planes: 2, linesizes: 64 64 0 0, plane_sizes: 3072 3072 0 0, plane_offsets: 3072 0 0, total_size: 6144 +nv20le planes: 2, linesizes: 128 128 0 0, plane_sizes: 6144 6144 0 0, plane_offsets: 6144 0 0, total_size: 12288 +nv20be planes: 2, linesizes: 128 128 0 0, plane_sizes: 6144 6144 0 0, plane_offsets: 6144 0 0, total_size: 12288 +rgba64be planes: 1, linesizes: 512 0 0 0, plane_sizes: 24576 0 0 0, plane_offsets: 0 0 0, total_size: 24576 +rgba64le planes: 1, linesizes: 512 0 0 0, plane_sizes: 24576 0 0 0, plane_offsets: 0 0 0, total_size: 24576 +bgra64be planes: 1, linesizes: 512 0 0 0, plane_sizes: 24576 0 0 0, plane_offsets: 0 0 0, total_size: 24576 +bgra64le planes: 1, linesizes: 512 0 0 0, plane_sizes: 24576 0 0 0, plane_offsets: 0 0 0, total_size: 24576 +yvyu422 planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +ya16be planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +ya16le planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +gbrap planes: 4, linesizes: 64 64 64 64, plane_sizes: 3072 3072 3072 3072, plane_offsets: 3072 3072 3072, total_size: 12288 +gbrap16be planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +gbrap16le planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +0rgb planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +rgb0 planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +0bgr planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +bgr0 planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +yuv420p12be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv420p12le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv420p14be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv420p14le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 1536 1536 0, plane_offsets: 6144 1536 0, total_size: 9216 +yuv422p12be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv422p12le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv422p14be planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv422p14le planes: 3, linesizes: 128 64 64 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv444p12be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuv444p12le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuv444p14be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuv444p14le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +gbrp12be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +gbrp12le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +gbrp14be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +gbrp14le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +yuvj411p planes: 3, linesizes: 64 16 16 0, plane_sizes: 3072 768 768 0, plane_offsets: 3072 768 0, total_size: 4608 +bayer_bggr8 planes: 1, linesizes: 64 0 0 0, plane_sizes: 3072 0 0 0, plane_offsets: 0 0 0, total_size: 3072 +bayer_rggb8 planes: 1, linesizes: 64 0 0 0, plane_sizes: 3072 0 0 0, plane_offsets: 0 0 0, total_size: 3072 +bayer_gbrg8 planes: 1, linesizes: 64 0 0 0, plane_sizes: 3072 0 0 0, plane_offsets: 0 0 0, total_size: 3072 +bayer_grbg8 planes: 1, linesizes: 64 0 0 0, plane_sizes: 3072 0 0 0, plane_offsets: 0 0 0, total_size: 3072 +bayer_bggr16le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bayer_bggr16be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bayer_rggb16le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bayer_rggb16be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bayer_gbrg16le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bayer_gbrg16be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bayer_grbg16le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +bayer_grbg16be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +yuv440p10le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv440p10be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv440p12le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +yuv440p12be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 3072 3072 0, plane_offsets: 6144 3072 0, total_size: 12288 +ayuv64le planes: 1, linesizes: 512 0 0 0, plane_sizes: 24576 0 0 0, plane_offsets: 0 0 0, total_size: 24576 +ayuv64be planes: 1, linesizes: 512 0 0 0, plane_sizes: 24576 0 0 0, plane_offsets: 0 0 0, total_size: 24576 +p010le planes: 2, linesizes: 128 128 0 0, plane_sizes: 6144 3072 0 0, plane_offsets: 6144 0 0, total_size: 9216 +p010be planes: 2, linesizes: 128 128 0 0, plane_sizes: 6144 3072 0 0, plane_offsets: 6144 0 0, total_size: 9216 +gbrap12be planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +gbrap12le planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +gbrap10be planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +gbrap10le planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +gray12be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +gray12le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +gray10be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +gray10le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +p016le planes: 2, linesizes: 128 128 0 0, plane_sizes: 6144 3072 0 0, plane_offsets: 6144 0 0, total_size: 9216 +p016be planes: 2, linesizes: 128 128 0 0, plane_sizes: 6144 3072 0 0, plane_offsets: 6144 0 0, total_size: 9216 +gray9be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +gray9le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +gbrpf32be planes: 3, linesizes: 256 256 256 0, plane_sizes: 12288 12288 12288 0, plane_offsets: 12288 12288 0, total_size: 36864 +gbrpf32le planes: 3, linesizes: 256 256 256 0, plane_sizes: 12288 12288 12288 0, plane_offsets: 12288 12288 0, total_size: 36864 +gbrapf32be planes: 4, linesizes: 256 256 256 256, plane_sizes: 12288 12288 12288 12288, plane_offsets: 12288 12288 12288, total_size: 49152 +gbrapf32le planes: 4, linesizes: 256 256 256 256, plane_sizes: 12288 12288 12288 12288, plane_offsets: 12288 12288 12288, total_size: 49152 +gray14be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +gray14le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144 +grayf32be planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +grayf32le planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +yuva422p12be planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 3072 3072 6144, plane_offsets: 6144 3072 3072, total_size: 18432 +yuva422p12le planes: 4, linesizes: 128 64 64 128, plane_sizes: 6144 3072 3072 6144, plane_offsets: 6144 3072 3072, total_size: 18432 +yuva444p12be planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +yuva444p12le planes: 4, linesizes: 128 128 128 128, plane_sizes: 6144 6144 6144 6144, plane_offsets: 6144 6144 6144, total_size: 24576 +nv24 planes: 2, linesizes: 64 128 0 0, plane_sizes: 3072 6144 0 0, plane_offsets: 3072 0 0, total_size: 9216 +nv42 planes: 2, linesizes: 64 128 0 0, plane_sizes: 3072 6144 0 0, plane_offsets: 3072 0 0, total_size: 9216 +y210be planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +y210le planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +x2rgb10le planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 +x2rgb10be planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288 diff --git a/tests/ref/fate/iv8-demux b/tests/ref/fate/iv8-demux index 518f3de97..5b4cf0d4b 100644 --- a/tests/ref/fate/iv8-demux +++ b/tests/ref/fate/iv8-demux @@ -4,28 +4,28 @@ #codec_id 0: mpeg4 #dimensions 0: 704x576 #sar 0: 1/1 -0, 0, 0, 0, 20883, 0x347191e2 -0, 3600, 3600, 0, 20882, 0xe1573905 -0, 7200, 7200, 0, 20894, 0xd54f516a -0, 10800, 10800, 0, 20891, 0x1b5c5039 -0, 14400, 14400, 0, 20883, 0x8e785b4d -0, 18000, 18000, 0, 20870, 0xd26ca1f6 -0, 21600, 21600, 0, 21448, 0x946f5b2b -0, 25200, 25200, 0, 21433, 0xb18687c5 -0, 28800, 28800, 0, 20865, 0xc0eb3fce -0, 32399, 32399, 0, 20842, 0x9d0728ba -0, 35999, 35999, 0, 20878, 0xf60f5dee -0, 39600, 39600, 0, 20866, 0x3bde568f -0, 43200, 43200, 0, 20884, 0x22736993 -0, 46800, 46800, 0, 20860, 0xf56f2fca -0, 50400, 50400, 0, 20872, 0xf39e3cb3 -0, 53999, 53999, 0, 20835, 0xa3c4363b -0, 57600, 57600, 0, 20905, 0x552853d1 -0, 61200, 61200, 0, 20874, 0xed0b91ec -0, 64799, 64799, 0, 20877, 0xe1623e01 -0, 68399, 68399, 0, 20933, 0x19906564 -0, 72000, 72000, 0, 20891, 0x3d064fd3 -0, 75600, 75600, 0, 20834, 0xcb774dbc -0, 79200, 79200, 0, 20870, 0xbc536589 -0, 82800, 82800, 0, 21421, 0xc99a68e4 -0, 86400, 86400, 0, 12869, 0x5684e304 +0, 0, 0, 3600, 20883, 0x347191e2 +0, 3600, 3600, 3600, 20882, 0xe1573905 +0, 7200, 7200, 3600, 20894, 0xd54f516a +0, 10800, 10800, 3600, 20891, 0x1b5c5039 +0, 14400, 14400, 3600, 20883, 0x8e785b4d +0, 18000, 18000, 3600, 20870, 0xd26ca1f6 +0, 21600, 21600, 3600, 21448, 0x946f5b2b +0, 25200, 25200, 3600, 21433, 0xb18687c5 +0, 28800, 28800, 3600, 20865, 0xc0eb3fce +0, 32399, 32399, 3600, 20842, 0x9d0728ba +0, 35999, 35999, 3600, 20878, 0xf60f5dee +0, 39600, 39600, 3600, 20866, 0x3bde568f +0, 43200, 43200, 3600, 20884, 0x22736993 +0, 46800, 46800, 3600, 20860, 0xf56f2fca +0, 50400, 50400, 3600, 20872, 0xf39e3cb3 +0, 53999, 53999, 3600, 20835, 0xa3c4363b +0, 57600, 57600, 3600, 20905, 0x552853d1 +0, 61200, 61200, 3600, 20874, 0xed0b91ec +0, 64799, 64799, 3600, 20877, 0xe1623e01 +0, 68399, 68399, 3600, 20933, 0x19906564 +0, 72000, 72000, 3600, 20891, 0x3d064fd3 +0, 75600, 75600, 3600, 20834, 0xcb774dbc +0, 79200, 79200, 3600, 20870, 0xbc536589 +0, 82800, 82800, 3600, 21421, 0xc99a68e4 +0, 86400, 86400, 3600, 12869, 0x5684e304 diff --git a/tests/ref/fate/lscr b/tests/ref/fate/lscr new file mode 100644 index 000000000..3b3fd4ce5 --- /dev/null +++ b/tests/ref/fate/lscr @@ -0,0 +1,21 @@ +#tb 0: 100/2397 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 0/1 +0, 0, 0, 1, 230400, 0x07c93bd9 +0, 1, 1, 1, 230400, 0xdcacc274 +0, 2, 2, 1, 230400, 0x6115dc34 +0, 3, 3, 1, 230400, 0x7317f35c +0, 4, 4, 1, 230400, 0xca18d9a6 +0, 5, 5, 1, 230400, 0x0c104d49 +0, 6, 6, 1, 230400, 0xc4c415cf +0, 7, 7, 1, 230400, 0xd1e4149f +0, 8, 8, 1, 230400, 0x5973ae25 +0, 9, 9, 1, 230400, 0xd77893e6 +0, 10, 10, 1, 230400, 0x7f9cac97 +0, 11, 11, 1, 230400, 0xc8f81940 +0, 12, 12, 1, 230400, 0xa2b6f5d4 +0, 13, 13, 1, 230400, 0x620c3222 +0, 14, 14, 1, 230400, 0x60d097a0 +0, 15, 15, 1, 230400, 0x47201c65 diff --git a/tests/ref/fate/matroska-mastering-display-metadata b/tests/ref/fate/matroska-mastering-display-metadata new file mode 100644 index 000000000..f9fb54abb --- /dev/null +++ b/tests/ref/fate/matroska-mastering-display-metadata @@ -0,0 +1,97 @@ +542ababe5c088ab925ee49373d8b8a85 *tests/data/fate/matroska-mastering-display-metadata.matroska +1669695 tests/data/fate/matroska-mastering-display-metadata.matroska +#extradata 0: 4, 0x040901a3 +#extradata 3: 200, 0x506463a8 +#tb 0: 1/1000 +#media_type 0: video +#codec_id 0: prores +#dimensions 0: 1280x720 +#sar 0: 1/1 +#tb 1: 1/1000 +#media_type 1: audio +#codec_id 1: pcm_s24le +#sample_rate 1: 48000 +#channel_layout 1: 4 +#channel_layout_name 1: mono +#tb 2: 1/1000 +#media_type 2: audio +#codec_id 2: pcm_s16be +#sample_rate 2: 48000 +#channel_layout 2: 4 +#channel_layout_name 2: mono +#tb 3: 1/1000 +#media_type 3: video +#codec_id 3: ffv1 +#dimensions 3: 1280x720 +#sar 3: 1/1 +0, 0, 0, 16, 57008, 0x43416399, S=2, 8, 0x08e5014f, 88, 0xd65a04db +1, 0, 0, 16, 2403, 0xaa818522 +3, 0, 0, 16, 274117, 0xc439610f, S=2, 8, 0x08e5014f, 88, 0xd65a04db +0, 17, 17, 16, 57248, 0xa06cd7b5 +1, 17, 17, 16, 2403, 0xe1a991e5 +2, 17, 17, 16, 1602, 0x5d868171 +3, 17, 17, 16, 273691, 0x5a3b88a5, F=0x0 +0, 33, 33, 16, 57200, 0x5623da10 +1, 33, 33, 16, 2400, 0x6650907f +2, 33, 33, 16, 1600, 0xa90f0044 +3, 33, 33, 16, 272987, 0x48c443e7, F=0x0 +0, 50, 50, 16, 57152, 0x52d89d3f +1, 50, 50, 16, 2403, 0x43398a08 +2, 50, 50, 16, 1602, 0x3a350084 +3, 50, 50, 16, 271465, 0x251b9cbe, F=0x0 +0, 67, 67, 16, 56960, 0x431d5189 +1, 67, 67, 16, 2403, 0x61cd96cb +2, 67, 67, 16, 1602, 0xd74800c6 +3, 67, 67, 16, 270800, 0x8fb2e217, F=0x0 +[STREAM] +index=0 +codec_name=prores +[SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=100 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=17/25 +red_y=8/25 +green_x=53/200 +green_y=69/100 +blue_x=3/20 +blue_y=3/50 +white_point_x=3127/10000 +white_point_y=329/1000 +min_luminance=0/1 +max_luminance=1000/1 +[/SIDE_DATA] +[/STREAM] +[STREAM] +index=1 +codec_name=pcm_s24le +[/STREAM] +[STREAM] +index=2 +codec_name=pcm_s16be +[/STREAM] +[STREAM] +index=3 +codec_name=ffv1 +[SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=100 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=17/25 +red_y=8/25 +green_x=53/200 +green_y=69/100 +blue_x=3/20 +blue_y=3/50 +white_point_x=3127/10000 +white_point_y=329/1000 +min_luminance=0/1 +max_luminance=1000/1 +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/matroska-mpegts-remux b/tests/ref/fate/matroska-mpegts-remux new file mode 100644 index 000000000..3c0b41cca --- /dev/null +++ b/tests/ref/fate/matroska-mpegts-remux @@ -0,0 +1,52 @@ +4e6253c1f5f96ff64ae855dea426547d *tests/data/fate/matroska-mpegts-remux.matroska +6509 tests/data/fate/matroska-mpegts-remux.matroska +#tb 0: 1/1000 +#media_type 0: audio +#codec_id 0: ac3 +#sample_rate 0: 48000 +#channel_layout 0: 3 +#channel_layout_name 0: stereo +#tb 1: 1/1000 +#media_type 1: audio +#codec_id 1: ac3 +#sample_rate 1: 48000 +#channel_layout 1: 3 +#channel_layout_name 1: stereo +0, 0, 0, 32, 768, 0xa63778d4 +1, 0, 0, 32, 768, 0xa63778d4 +0, 32, 32, 32, 768, 0x7d577f3f +1, 32, 32, 32, 768, 0x7d577f3f +0, 64, 64, 32, 768, 0xd86b7c8f +1, 64, 64, 32, 768, 0xd86b7c8f +0, 96, 96, 32, 626, 0x09f4382f +1, 96, 96, 32, 626, 0x09f4382f +[STREAM] +index=0 +DISPOSITION:default=1 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=1 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +[/STREAM] +[STREAM] +index=1 +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=1 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +[/STREAM] diff --git a/tests/ref/fate/matroska-spherical-mono-remux b/tests/ref/fate/matroska-spherical-mono-remux new file mode 100644 index 000000000..e0e5f40aa --- /dev/null +++ b/tests/ref/fate/matroska-spherical-mono-remux @@ -0,0 +1,66 @@ +9176856edc1ff2b401e323f422fd8e78 *tests/data/fate/matroska-spherical-mono-remux.matroska +161583 tests/data/fate/matroska-spherical-mono-remux.matroska +#extradata 0: 43, 0x2b0e0d7b +#extradata 1: 43, 0x2b0e0d7b +#tb 0: 1/1000 +#media_type 0: video +#codec_id 0: h264 +#dimensions 0: 1920x1080 +#sar 0: 0/1 +#tb 1: 1/1000 +#media_type 1: video +#codec_id 1: h264 +#dimensions 1: 1920x1080 +#sar 1: 0/1 +0, -80, 0, 40, 69118, 0x73cb52f0, S=2, 12, 0x00000000, 36, 0x2cf8035c +1, -80, 0, 40, 69118, 0x73cb52f0, S=2, 12, 0x00000000, 36, 0x2cf8035c +0, -40, 160, 40, 1103, 0x082a059f, F=0x0 +1, -40, 160, 40, 1103, 0x082a059f, F=0x0 +[STREAM] +color_range=unknown +color_space=unknown +color_transfer=unknown +color_primaries=unknown +DISPOSITION:default=0 +DISPOSITION:forced=1 +[SIDE_DATA] +side_data_type=Stereo 3D +type=2D +inverted=0 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Spherical Mapping +projection=tiled equirectangular +bound_left=148 +bound_top=73 +bound_right=147 +bound_bottom=72 +yaw=45 +pitch=30 +roll=15 +[/SIDE_DATA] +[/STREAM] +[STREAM] +color_range=pc +color_space=bt2020c +color_transfer=smpte170m +color_primaries=bt709 +DISPOSITION:default=0 +DISPOSITION:forced=0 +[SIDE_DATA] +side_data_type=Stereo 3D +type=2D +inverted=0 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Spherical Mapping +projection=tiled equirectangular +bound_left=148 +bound_top=73 +bound_right=147 +bound_bottom=72 +yaw=45 +pitch=30 +roll=15 +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/matroska-vp8-alpha-remux b/tests/ref/fate/matroska-vp8-alpha-remux new file mode 100644 index 000000000..0b6c77932 --- /dev/null +++ b/tests/ref/fate/matroska-vp8-alpha-remux @@ -0,0 +1,33 @@ +d06be833da8e8d9d00bf334e0dfe8a58 *tests/data/fate/matroska-vp8-alpha-remux.matroska +237192 tests/data/fate/matroska-vp8-alpha-remux.matroska +#tb 0: 1/1000 +#media_type 0: video +#codec_id 0: vp8 +#dimensions 0: 320x213 +#sar 0: 1/1 +0, 0, 0, 33, 2108, 0x59b92a34, S=2, 1900, 0x8fb3adc5, 12, 0x00000000 +0, 32, 32, 33, 142, 0x2f2a3fed, F=0x0, S=1, 160, 0xa13346af +0, 65, 65, 33, 157, 0x17804767, F=0x0, S=1, 209, 0x64115f15 +0, 99, 99, 33, 206, 0x537262ca, F=0x0, S=1, 317, 0x44a09dd0 +0, 132, 132, 33, 259, 0x73ff74b6, F=0x0, S=1, 384, 0x2ee2c588 +0, 165, 165, 33, 320, 0x0fcf8ce4, F=0x0, S=1, 415, 0xff68c953 +0, 199, 199, 33, 377, 0x8fffb5f5, F=0x0, S=1, 475, 0x4166f3eb +[STREAM] +DISPOSITION:default=1 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=1 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +[SIDE_DATA] +side_data_type=Stereo 3D +type=2D +inverted=0 +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/matroska-zero-length-block b/tests/ref/fate/matroska-zero-length-block new file mode 100644 index 000000000..e8c5decb3 --- /dev/null +++ b/tests/ref/fate/matroska-zero-length-block @@ -0,0 +1,10 @@ +ba78b3e846d57002711bc481fa806717 *tests/data/fate/matroska-zero-length-block.matroska +643 tests/data/fate/matroska-zero-length-block.matroska +#tb 0: 1/1000 +#media_type 0: subtitle +#codec_id 0: subrip +0, 1000, 1000, 2000, 5, 0x05b801df +0, 3300, 3300, 3700, 16, 0x300705b2 +[STREAM] +TAG:DESCRIPTION=This track uses header removal compression and has a Block of size zero before reversing it. +[/STREAM] diff --git a/tests/ref/fate/mimic b/tests/ref/fate/mimic index e36e6a8c9..06209481a 100644 --- a/tests/ref/fate/mimic +++ b/tests/ref/fate/mimic @@ -3,79 +3,79 @@ #codec_id 0: rawvideo #dimensions 0: 320x240 #sar 0: 0/1 -0, 0, 0, 0, 115200, 0xa974d407 -0, 548, 548, 0, 115200, 0x72618b84 -0, 1088, 1088, 0, 115200, 0x87768573 -0, 1759, 1759, 0, 115200, 0x5d218e3e -0, 2437, 2437, 0, 115200, 0x0c0db41c -0, 3076, 3076, 0, 115200, 0xb777fd48 -0, 3908, 3908, 0, 115200, 0x40765de7 -0, 4545, 4545, 0, 115200, 0x370a3c90 -0, 5092, 5092, 0, 115200, 0xc605785a -0, 6016, 6016, 0, 115200, 0x49468b23 -0, 6560, 6560, 0, 115200, 0x986b6fd4 -0, 7648, 7648, 0, 115200, 0x30f22ef8 -0, 8164, 8164, 0, 115200, 0xa90bd608 -0, 8836, 8836, 0, 115200, 0x9cf36518 -0, 9632, 9632, 0, 115200, 0x4ef1a679 -0, 9922, 9922, 0, 115200, 0x0df65873 -0, 10316, 10316, 0, 115200, 0xfecd4233 -0, 11104, 11104, 0, 115200, 0xee2f26cb -0, 11776, 11776, 0, 115200, 0x795f612d -0, 12321, 12321, 0, 115200, 0xbbb90125 -0, 12992, 12992, 0, 115200, 0x9230fb6e -0, 13805, 13805, 0, 115200, 0x11869996 -0, 14468, 14468, 0, 115200, 0x6b5c892b -0, 15136, 15136, 0, 115200, 0x88bdb9cd -0, 15937, 15937, 0, 115200, 0x364bc5a0 -0, 16608, 16608, 0, 115200, 0x6b66d817 -0, 17281, 17281, 0, 115200, 0xd3a41252 -0, 18089, 18089, 0, 115200, 0x0cf5612f -0, 18754, 18754, 0, 115200, 0x9752d055 -0, 19808, 19808, 0, 115200, 0x486e9f6f -0, 20484, 20484, 0, 115200, 0x3eab62f8 -0, 21031, 21031, 0, 115200, 0xa7f52762 -0, 21957, 21957, 0, 115200, 0xfd4c4bbc -0, 22498, 22498, 0, 115200, 0x194023f6 -0, 22880, 22880, 0, 115200, 0xd4668dad -0, 23680, 23680, 0, 115200, 0x6b20d64b -0, 24353, 24353, 0, 115200, 0xf2572aae -0, 24901, 24901, 0, 115200, 0xc3554f25 -0, 25695, 25695, 0, 115200, 0xeeb5073a -0, 26495, 26495, 0, 115200, 0xbd46291f -0, 27040, 27040, 0, 115200, 0x0526838d -0, 28107, 28107, 0, 115200, 0x85b2e864 -0, 28778, 28778, 0, 115200, 0xcfd894bc -0, 29316, 29316, 0, 115200, 0x644f10fb -0, 30240, 30240, 0, 115200, 0x556e4d88 -0, 30786, 30786, 0, 115200, 0x93243614 -0, 31983, 31983, 0, 115200, 0x754275c5 -0, 32929, 32929, 0, 115200, 0x7f648bf3 -0, 33600, 33600, 0, 115200, 0xece18c9b -0, 34271, 34271, 0, 115200, 0x385d52c1 -0, 35201, 35201, 0, 115200, 0xafc58e4a -0, 35743, 35743, 0, 115200, 0x50daf750 -0, 36384, 36384, 0, 115200, 0xf6bc67d1 -0, 37344, 37344, 0, 115200, 0xb64b6e07 -0, 38028, 38028, 0, 115200, 0x8751ed15 -0, 38657, 38657, 0, 115200, 0x329ce803 -0, 39334, 39334, 0, 115200, 0x40b2cb05 -0, 40129, 40129, 0, 115200, 0x60f3517d -0, 40802, 40802, 0, 115200, 0xe0d46fdf -0, 41472, 41472, 0, 115200, 0x204529fa -0, 42276, 42276, 0, 115200, 0xd5afaf22 -0, 42944, 42944, 0, 115200, 0xd3cb3d4c -0, 43616, 43616, 0, 115200, 0x87973a79 -0, 44421, 44421, 0, 115200, 0xe3b2f917 -0, 45092, 45092, 0, 115200, 0xf1923238 -0, 45632, 45632, 0, 115200, 0x51494d71 -0, 46561, 46561, 0, 115200, 0x58bc59bb -0, 47105, 47105, 0, 115200, 0xd0273fdb -0, 47776, 47776, 0, 115200, 0x6cc79700 -0, 48294, 48294, 0, 115200, 0xc8172d31 -0, 48960, 48960, 0, 115200, 0x8eb037ef -0, 49504, 49504, 0, 115200, 0xc0bc2d76 -0, 50053, 50053, 0, 115200, 0x663c467a -0, 50597, 50597, 0, 115200, 0xd085e950 -0, 51520, 51520, 0, 115200, 0x7d198d72 -0, 52092, 52092, 0, 115200, 0x6ebacda0 +0, 0, 0, 1, 115200, 0xa974d407 +0, 548, 548, 1, 115200, 0x72618b84 +0, 1088, 1088, 1, 115200, 0x87768573 +0, 1759, 1759, 1, 115200, 0x5d218e3e +0, 2437, 2437, 1, 115200, 0x0c0db41c +0, 3076, 3076, 1, 115200, 0xb777fd48 +0, 3908, 3908, 1, 115200, 0x40765de7 +0, 4545, 4545, 1, 115200, 0x370a3c90 +0, 5092, 5092, 1, 115200, 0xc605785a +0, 6016, 6016, 1, 115200, 0x49468b23 +0, 6560, 6560, 1, 115200, 0x986b6fd4 +0, 7648, 7648, 1, 115200, 0x30f22ef8 +0, 8164, 8164, 1, 115200, 0xa90bd608 +0, 8836, 8836, 1, 115200, 0x9cf36518 +0, 9632, 9632, 1, 115200, 0x4ef1a679 +0, 9922, 9922, 1, 115200, 0x0df65873 +0, 10316, 10316, 1, 115200, 0xfecd4233 +0, 11104, 11104, 1, 115200, 0xee2f26cb +0, 11776, 11776, 1, 115200, 0x795f612d +0, 12321, 12321, 1, 115200, 0xbbb90125 +0, 12992, 12992, 1, 115200, 0x9230fb6e +0, 13805, 13805, 1, 115200, 0x11869996 +0, 14468, 14468, 1, 115200, 0x6b5c892b +0, 15136, 15136, 1, 115200, 0x88bdb9cd +0, 15937, 15937, 1, 115200, 0x364bc5a0 +0, 16608, 16608, 1, 115200, 0x6b66d817 +0, 17281, 17281, 1, 115200, 0xd3a41252 +0, 18089, 18089, 1, 115200, 0x0cf5612f +0, 18754, 18754, 1, 115200, 0x9752d055 +0, 19808, 19808, 1, 115200, 0x486e9f6f +0, 20484, 20484, 1, 115200, 0x3eab62f8 +0, 21031, 21031, 1, 115200, 0xa7f52762 +0, 21957, 21957, 1, 115200, 0xfd4c4bbc +0, 22498, 22498, 1, 115200, 0x194023f6 +0, 22880, 22880, 1, 115200, 0xd4668dad +0, 23680, 23680, 1, 115200, 0x6b20d64b +0, 24353, 24353, 1, 115200, 0xf2572aae +0, 24901, 24901, 1, 115200, 0xc3554f25 +0, 25695, 25695, 1, 115200, 0xeeb5073a +0, 26495, 26495, 1, 115200, 0xbd46291f +0, 27040, 27040, 1, 115200, 0x0526838d +0, 28107, 28107, 1, 115200, 0x85b2e864 +0, 28778, 28778, 1, 115200, 0xcfd894bc +0, 29316, 29316, 1, 115200, 0x644f10fb +0, 30240, 30240, 1, 115200, 0x556e4d88 +0, 30786, 30786, 1, 115200, 0x93243614 +0, 31983, 31983, 1, 115200, 0x754275c5 +0, 32929, 32929, 1, 115200, 0x7f648bf3 +0, 33600, 33600, 1, 115200, 0xece18c9b +0, 34271, 34271, 1, 115200, 0x385d52c1 +0, 35201, 35201, 1, 115200, 0xafc58e4a +0, 35743, 35743, 1, 115200, 0x50daf750 +0, 36384, 36384, 1, 115200, 0xf6bc67d1 +0, 37344, 37344, 1, 115200, 0xb64b6e07 +0, 38028, 38028, 1, 115200, 0x8751ed15 +0, 38657, 38657, 1, 115200, 0x329ce803 +0, 39334, 39334, 1, 115200, 0x40b2cb05 +0, 40129, 40129, 1, 115200, 0x60f3517d +0, 40802, 40802, 1, 115200, 0xe0d46fdf +0, 41472, 41472, 1, 115200, 0x204529fa +0, 42276, 42276, 1, 115200, 0xd5afaf22 +0, 42944, 42944, 1, 115200, 0xd3cb3d4c +0, 43616, 43616, 1, 115200, 0x87973a79 +0, 44421, 44421, 1, 115200, 0xe3b2f917 +0, 45092, 45092, 1, 115200, 0xf1923238 +0, 45632, 45632, 1, 115200, 0x51494d71 +0, 46561, 46561, 1, 115200, 0x58bc59bb +0, 47105, 47105, 1, 115200, 0xd0273fdb +0, 47776, 47776, 1, 115200, 0x6cc79700 +0, 48294, 48294, 1, 115200, 0xc8172d31 +0, 48960, 48960, 1, 115200, 0x8eb037ef +0, 49504, 49504, 1, 115200, 0xc0bc2d76 +0, 50053, 50053, 1, 115200, 0x663c467a +0, 50597, 50597, 1, 115200, 0xd085e950 +0, 51520, 51520, 1, 115200, 0x7d198d72 +0, 52092, 52092, 1, 115200, 0x6ebacda0 diff --git a/tests/ref/fate/mov-aac-2048-priming b/tests/ref/fate/mov-aac-2048-priming index 2616944de..5c6361558 100644 --- a/tests/ref/fate/mov-aac-2048-priming +++ b/tests/ref/fate/mov-aac-2048-priming @@ -1,218 +1,218 @@ -packet|codec_type=audio|stream_index=0|pts=-2048|pts_time=-0.046440|dts=-2048|dts_time=-0.046440|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=258|pos=36|flags=KDside_data|side_data_type=Skip Samples|skip_samples=2048|discard_padding=0|skip_reason=0|discard_reason=0 +packet|codec_type=audio|stream_index=0|pts=-2048|pts_time=-0.046440|dts=-2048|dts_time=-0.046440|duration=1024|duration_time=0.023220|size=258|pos=36|flags=KDside_data|side_data_type=Skip Samples|skip_samples=2048|discard_padding=0|skip_reason=0|discard_reason=0 -packet|codec_type=audio|stream_index=0|pts=-1024|pts_time=-0.023220|dts=-1024|dts_time=-0.023220|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=258|pos=294|flags=KD -packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=146|pos=552|flags=K_ -packet|codec_type=audio|stream_index=0|pts=1024|pts_time=0.023220|dts=1024|dts_time=0.023220|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=186|pos=698|flags=K_ -packet|codec_type=audio|stream_index=0|pts=2048|pts_time=0.046440|dts=2048|dts_time=0.046440|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=222|pos=884|flags=K_ -packet|codec_type=audio|stream_index=0|pts=3072|pts_time=0.069660|dts=3072|dts_time=0.069660|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=186|pos=1106|flags=K_ -packet|codec_type=audio|stream_index=0|pts=4096|pts_time=0.092880|dts=4096|dts_time=0.092880|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=206|pos=1292|flags=K_ -packet|codec_type=audio|stream_index=0|pts=5120|pts_time=0.116100|dts=5120|dts_time=0.116100|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=199|pos=1498|flags=K_ -packet|codec_type=audio|stream_index=0|pts=6144|pts_time=0.139320|dts=6144|dts_time=0.139320|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=236|pos=1697|flags=K_ -packet|codec_type=audio|stream_index=0|pts=7168|pts_time=0.162540|dts=7168|dts_time=0.162540|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=208|pos=1933|flags=K_ -packet|codec_type=audio|stream_index=0|pts=8192|pts_time=0.185760|dts=8192|dts_time=0.185760|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=238|pos=2141|flags=K_ -packet|codec_type=audio|stream_index=0|pts=9216|pts_time=0.208980|dts=9216|dts_time=0.208980|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=222|pos=2379|flags=K_ -packet|codec_type=audio|stream_index=0|pts=10240|pts_time=0.232200|dts=10240|dts_time=0.232200|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=211|pos=2601|flags=K_ -packet|codec_type=audio|stream_index=0|pts=11264|pts_time=0.255420|dts=11264|dts_time=0.255420|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=153|pos=2812|flags=K_ -packet|codec_type=audio|stream_index=0|pts=12288|pts_time=0.278639|dts=12288|dts_time=0.278639|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=191|pos=2965|flags=K_ -packet|codec_type=audio|stream_index=0|pts=13312|pts_time=0.301859|dts=13312|dts_time=0.301859|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=208|pos=3156|flags=K_ -packet|codec_type=audio|stream_index=0|pts=14336|pts_time=0.325079|dts=14336|dts_time=0.325079|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=188|pos=3364|flags=K_ -packet|codec_type=audio|stream_index=0|pts=15360|pts_time=0.348299|dts=15360|dts_time=0.348299|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=170|pos=3552|flags=K_ -packet|codec_type=audio|stream_index=0|pts=16384|pts_time=0.371519|dts=16384|dts_time=0.371519|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=221|pos=3722|flags=K_ -packet|codec_type=audio|stream_index=0|pts=17408|pts_time=0.394739|dts=17408|dts_time=0.394739|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=247|pos=3943|flags=K_ -packet|codec_type=audio|stream_index=0|pts=18432|pts_time=0.417959|dts=18432|dts_time=0.417959|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=202|pos=4190|flags=K_ -packet|codec_type=audio|stream_index=0|pts=19456|pts_time=0.441179|dts=19456|dts_time=0.441179|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=186|pos=4392|flags=K_ -packet|codec_type=audio|stream_index=0|pts=20480|pts_time=0.464399|dts=20480|dts_time=0.464399|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=196|pos=4578|flags=K_ -packet|codec_type=audio|stream_index=0|pts=21504|pts_time=0.487619|dts=21504|dts_time=0.487619|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=4774|flags=K_ -packet|codec_type=audio|stream_index=0|pts=22528|pts_time=0.510839|dts=22528|dts_time=0.510839|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=170|pos=4974|flags=K_ -packet|codec_type=audio|stream_index=0|pts=23552|pts_time=0.534059|dts=23552|dts_time=0.534059|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=172|pos=5144|flags=K_ -packet|codec_type=audio|stream_index=0|pts=24576|pts_time=0.557279|dts=24576|dts_time=0.557279|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=206|pos=5316|flags=K_ -packet|codec_type=audio|stream_index=0|pts=25600|pts_time=0.580499|dts=25600|dts_time=0.580499|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=208|pos=5522|flags=K_ -packet|codec_type=audio|stream_index=0|pts=26624|pts_time=0.603719|dts=26624|dts_time=0.603719|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=217|pos=5730|flags=K_ -packet|codec_type=audio|stream_index=0|pts=27648|pts_time=0.626939|dts=27648|dts_time=0.626939|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=252|pos=5947|flags=K_ -packet|codec_type=audio|stream_index=0|pts=28672|pts_time=0.650159|dts=28672|dts_time=0.650159|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=171|pos=6199|flags=K_ -packet|codec_type=audio|stream_index=0|pts=29696|pts_time=0.673379|dts=29696|dts_time=0.673379|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=206|pos=6370|flags=K_ -packet|codec_type=audio|stream_index=0|pts=30720|pts_time=0.696599|dts=30720|dts_time=0.696599|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=237|pos=6576|flags=K_ -packet|codec_type=audio|stream_index=0|pts=31744|pts_time=0.719819|dts=31744|dts_time=0.719819|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=210|pos=6813|flags=K_ -packet|codec_type=audio|stream_index=0|pts=32768|pts_time=0.743039|dts=32768|dts_time=0.743039|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=166|pos=7023|flags=K_ -packet|codec_type=audio|stream_index=0|pts=33792|pts_time=0.766259|dts=33792|dts_time=0.766259|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=166|pos=7189|flags=K_ -packet|codec_type=audio|stream_index=0|pts=34816|pts_time=0.789478|dts=34816|dts_time=0.789478|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=177|pos=7355|flags=K_ -packet|codec_type=audio|stream_index=0|pts=35840|pts_time=0.812698|dts=35840|dts_time=0.812698|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=188|pos=7532|flags=K_ -packet|codec_type=audio|stream_index=0|pts=36864|pts_time=0.835918|dts=36864|dts_time=0.835918|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=193|pos=7720|flags=K_ -packet|codec_type=audio|stream_index=0|pts=37888|pts_time=0.859138|dts=37888|dts_time=0.859138|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=7913|flags=K_ -packet|codec_type=audio|stream_index=0|pts=38912|pts_time=0.882358|dts=38912|dts_time=0.882358|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=211|pos=8108|flags=K_ -packet|codec_type=audio|stream_index=0|pts=39936|pts_time=0.905578|dts=39936|dts_time=0.905578|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=249|pos=8319|flags=K_ -packet|codec_type=audio|stream_index=0|pts=40960|pts_time=0.928798|dts=40960|dts_time=0.928798|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=223|pos=8568|flags=K_ -packet|codec_type=audio|stream_index=0|pts=41984|pts_time=0.952018|dts=41984|dts_time=0.952018|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=230|pos=8791|flags=K_ -packet|codec_type=audio|stream_index=0|pts=43008|pts_time=0.975238|dts=43008|dts_time=0.975238|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=203|pos=9021|flags=K_ -packet|codec_type=audio|stream_index=0|pts=44032|pts_time=0.998458|dts=44032|dts_time=0.998458|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=180|pos=9224|flags=K_ -packet|codec_type=audio|stream_index=0|pts=45056|pts_time=1.021678|dts=45056|dts_time=1.021678|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=172|pos=9404|flags=K_ -packet|codec_type=audio|stream_index=0|pts=46080|pts_time=1.044898|dts=46080|dts_time=1.044898|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=240|pos=9576|flags=K_ -packet|codec_type=audio|stream_index=0|pts=47104|pts_time=1.068118|dts=47104|dts_time=1.068118|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=179|pos=9816|flags=K_ -packet|codec_type=audio|stream_index=0|pts=48128|pts_time=1.091338|dts=48128|dts_time=1.091338|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=191|pos=9995|flags=K_ -packet|codec_type=audio|stream_index=0|pts=49152|pts_time=1.114558|dts=49152|dts_time=1.114558|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=184|pos=10186|flags=K_ -packet|codec_type=audio|stream_index=0|pts=50176|pts_time=1.137778|dts=50176|dts_time=1.137778|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=214|pos=10370|flags=K_ -packet|codec_type=audio|stream_index=0|pts=51200|pts_time=1.160998|dts=51200|dts_time=1.160998|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=194|pos=10584|flags=K_ -packet|codec_type=audio|stream_index=0|pts=52224|pts_time=1.184218|dts=52224|dts_time=1.184218|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=235|pos=10778|flags=K_ -packet|codec_type=audio|stream_index=0|pts=53248|pts_time=1.207438|dts=53248|dts_time=1.207438|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=11013|flags=K_ -packet|codec_type=audio|stream_index=0|pts=54272|pts_time=1.230658|dts=54272|dts_time=1.230658|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=220|pos=11208|flags=K_ -packet|codec_type=audio|stream_index=0|pts=55296|pts_time=1.253878|dts=55296|dts_time=1.253878|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=187|pos=11428|flags=K_ -packet|codec_type=audio|stream_index=0|pts=56320|pts_time=1.277098|dts=56320|dts_time=1.277098|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=238|pos=11615|flags=K_ -packet|codec_type=audio|stream_index=0|pts=57344|pts_time=1.300317|dts=57344|dts_time=1.300317|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=175|pos=11853|flags=K_ -packet|codec_type=audio|stream_index=0|pts=58368|pts_time=1.323537|dts=58368|dts_time=1.323537|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=178|pos=12028|flags=K_ -packet|codec_type=audio|stream_index=0|pts=59392|pts_time=1.346757|dts=59392|dts_time=1.346757|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=219|pos=12206|flags=K_ -packet|codec_type=audio|stream_index=0|pts=60416|pts_time=1.369977|dts=60416|dts_time=1.369977|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=179|pos=12425|flags=K_ -packet|codec_type=audio|stream_index=0|pts=61440|pts_time=1.393197|dts=61440|dts_time=1.393197|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=193|pos=12604|flags=K_ -packet|codec_type=audio|stream_index=0|pts=62464|pts_time=1.416417|dts=62464|dts_time=1.416417|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=12797|flags=K_ -packet|codec_type=audio|stream_index=0|pts=63488|pts_time=1.439637|dts=63488|dts_time=1.439637|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=218|pos=12997|flags=K_ -packet|codec_type=audio|stream_index=0|pts=64512|pts_time=1.462857|dts=64512|dts_time=1.462857|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=215|pos=13215|flags=K_ -packet|codec_type=audio|stream_index=0|pts=65536|pts_time=1.486077|dts=65536|dts_time=1.486077|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=209|pos=13430|flags=K_ -packet|codec_type=audio|stream_index=0|pts=66560|pts_time=1.509297|dts=66560|dts_time=1.509297|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=171|pos=13639|flags=K_ -packet|codec_type=audio|stream_index=0|pts=67584|pts_time=1.532517|dts=67584|dts_time=1.532517|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=179|pos=13810|flags=K_ -packet|codec_type=audio|stream_index=0|pts=68608|pts_time=1.555737|dts=68608|dts_time=1.555737|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=185|pos=13989|flags=K_ -packet|codec_type=audio|stream_index=0|pts=69632|pts_time=1.578957|dts=69632|dts_time=1.578957|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=225|pos=14174|flags=K_ -packet|codec_type=audio|stream_index=0|pts=70656|pts_time=1.602177|dts=70656|dts_time=1.602177|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=221|pos=14399|flags=K_ -packet|codec_type=audio|stream_index=0|pts=71680|pts_time=1.625397|dts=71680|dts_time=1.625397|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=201|pos=14620|flags=K_ -packet|codec_type=audio|stream_index=0|pts=72704|pts_time=1.648617|dts=72704|dts_time=1.648617|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=206|pos=14821|flags=K_ -packet|codec_type=audio|stream_index=0|pts=73728|pts_time=1.671837|dts=73728|dts_time=1.671837|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=182|pos=15027|flags=K_ -packet|codec_type=audio|stream_index=0|pts=74752|pts_time=1.695057|dts=74752|dts_time=1.695057|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=176|pos=15209|flags=K_ -packet|codec_type=audio|stream_index=0|pts=75776|pts_time=1.718277|dts=75776|dts_time=1.718277|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=233|pos=15385|flags=K_ -packet|codec_type=audio|stream_index=0|pts=76800|pts_time=1.741497|dts=76800|dts_time=1.741497|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=199|pos=15618|flags=K_ -packet|codec_type=audio|stream_index=0|pts=77824|pts_time=1.764717|dts=77824|dts_time=1.764717|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=220|pos=15817|flags=K_ -packet|codec_type=audio|stream_index=0|pts=78848|pts_time=1.787937|dts=78848|dts_time=1.787937|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=190|pos=16037|flags=K_ -packet|codec_type=audio|stream_index=0|pts=79872|pts_time=1.811156|dts=79872|dts_time=1.811156|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=210|pos=16227|flags=K_ -packet|codec_type=audio|stream_index=0|pts=80896|pts_time=1.834376|dts=80896|dts_time=1.834376|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=204|pos=16437|flags=K_ -packet|codec_type=audio|stream_index=0|pts=81920|pts_time=1.857596|dts=81920|dts_time=1.857596|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=171|pos=16641|flags=K_ -packet|codec_type=audio|stream_index=0|pts=82944|pts_time=1.880816|dts=82944|dts_time=1.880816|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=167|pos=16812|flags=K_ -packet|codec_type=audio|stream_index=0|pts=83968|pts_time=1.904036|dts=83968|dts_time=1.904036|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=16979|flags=K_ -packet|codec_type=audio|stream_index=0|pts=84992|pts_time=1.927256|dts=84992|dts_time=1.927256|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=254|pos=17179|flags=K_ -packet|codec_type=audio|stream_index=0|pts=86016|pts_time=1.950476|dts=86016|dts_time=1.950476|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=205|pos=17433|flags=K_ -packet|codec_type=audio|stream_index=0|pts=87040|pts_time=1.973696|dts=87040|dts_time=1.973696|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=196|pos=17638|flags=K_ -packet|codec_type=audio|stream_index=0|pts=88064|pts_time=1.996916|dts=88064|dts_time=1.996916|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=190|pos=17834|flags=K_ -packet|codec_type=audio|stream_index=0|pts=89088|pts_time=2.020136|dts=89088|dts_time=2.020136|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=197|pos=18024|flags=K_ -packet|codec_type=audio|stream_index=0|pts=90112|pts_time=2.043356|dts=90112|dts_time=2.043356|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=186|pos=18221|flags=K_ -packet|codec_type=audio|stream_index=0|pts=91136|pts_time=2.066576|dts=91136|dts_time=2.066576|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=194|pos=18407|flags=K_ -packet|codec_type=audio|stream_index=0|pts=92160|pts_time=2.089796|dts=92160|dts_time=2.089796|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=227|pos=18601|flags=K_ -packet|codec_type=audio|stream_index=0|pts=93184|pts_time=2.113016|dts=93184|dts_time=2.113016|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=18828|flags=K_ -packet|codec_type=audio|stream_index=0|pts=94208|pts_time=2.136236|dts=94208|dts_time=2.136236|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=228|pos=19023|flags=K_ -packet|codec_type=audio|stream_index=0|pts=95232|pts_time=2.159456|dts=95232|dts_time=2.159456|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=196|pos=19251|flags=K_ -packet|codec_type=audio|stream_index=0|pts=96256|pts_time=2.182676|dts=96256|dts_time=2.182676|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=197|pos=19447|flags=K_ -packet|codec_type=audio|stream_index=0|pts=97280|pts_time=2.205896|dts=97280|dts_time=2.205896|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=186|pos=19644|flags=K_ -packet|codec_type=audio|stream_index=0|pts=98304|pts_time=2.229116|dts=98304|dts_time=2.229116|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=191|pos=19830|flags=K_ -packet|codec_type=audio|stream_index=0|pts=99328|pts_time=2.252336|dts=99328|dts_time=2.252336|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=215|pos=20021|flags=K_ -packet|codec_type=audio|stream_index=0|pts=100352|pts_time=2.275556|dts=100352|dts_time=2.275556|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=203|pos=20236|flags=K_ -packet|codec_type=audio|stream_index=0|pts=101376|pts_time=2.298776|dts=101376|dts_time=2.298776|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=205|pos=20439|flags=K_ -packet|codec_type=audio|stream_index=0|pts=102400|pts_time=2.321995|dts=102400|dts_time=2.321995|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=205|pos=20644|flags=K_ -packet|codec_type=audio|stream_index=0|pts=103424|pts_time=2.345215|dts=103424|dts_time=2.345215|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=213|pos=20849|flags=K_ -packet|codec_type=audio|stream_index=0|pts=104448|pts_time=2.368435|dts=104448|dts_time=2.368435|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=198|pos=21062|flags=K_ -packet|codec_type=audio|stream_index=0|pts=105472|pts_time=2.391655|dts=105472|dts_time=2.391655|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=178|pos=21260|flags=K_ -packet|codec_type=audio|stream_index=0|pts=106496|pts_time=2.414875|dts=106496|dts_time=2.414875|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=21438|flags=K_ -packet|codec_type=audio|stream_index=0|pts=107520|pts_time=2.438095|dts=107520|dts_time=2.438095|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=227|pos=21633|flags=K_ -packet|codec_type=audio|stream_index=0|pts=108544|pts_time=2.461315|dts=108544|dts_time=2.461315|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=185|pos=21860|flags=K_ -packet|codec_type=audio|stream_index=0|pts=109568|pts_time=2.484535|dts=109568|dts_time=2.484535|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=206|pos=22045|flags=K_ -packet|codec_type=audio|stream_index=0|pts=110592|pts_time=2.507755|dts=110592|dts_time=2.507755|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=183|pos=22251|flags=K_ -packet|codec_type=audio|stream_index=0|pts=111616|pts_time=2.530975|dts=111616|dts_time=2.530975|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=208|pos=22434|flags=K_ -packet|codec_type=audio|stream_index=0|pts=112640|pts_time=2.554195|dts=112640|dts_time=2.554195|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=204|pos=22642|flags=K_ -packet|codec_type=audio|stream_index=0|pts=113664|pts_time=2.577415|dts=113664|dts_time=2.577415|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=192|pos=22846|flags=K_ -packet|codec_type=audio|stream_index=0|pts=114688|pts_time=2.600635|dts=114688|dts_time=2.600635|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=190|pos=23038|flags=K_ -packet|codec_type=audio|stream_index=0|pts=115712|pts_time=2.623855|dts=115712|dts_time=2.623855|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=199|pos=23228|flags=K_ -packet|codec_type=audio|stream_index=0|pts=116736|pts_time=2.647075|dts=116736|dts_time=2.647075|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=229|pos=23427|flags=K_ -packet|codec_type=audio|stream_index=0|pts=117760|pts_time=2.670295|dts=117760|dts_time=2.670295|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=208|pos=23656|flags=K_ -packet|codec_type=audio|stream_index=0|pts=118784|pts_time=2.693515|dts=118784|dts_time=2.693515|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=23864|flags=K_ -packet|codec_type=audio|stream_index=0|pts=119808|pts_time=2.716735|dts=119808|dts_time=2.716735|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=190|pos=24059|flags=K_ -packet|codec_type=audio|stream_index=0|pts=120832|pts_time=2.739955|dts=120832|dts_time=2.739955|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=190|pos=24249|flags=K_ -packet|codec_type=audio|stream_index=0|pts=121856|pts_time=2.763175|dts=121856|dts_time=2.763175|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=192|pos=24439|flags=K_ -packet|codec_type=audio|stream_index=0|pts=122880|pts_time=2.786395|dts=122880|dts_time=2.786395|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=226|pos=24631|flags=K_ -packet|codec_type=audio|stream_index=0|pts=123904|pts_time=2.809615|dts=123904|dts_time=2.809615|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=24857|flags=K_ -packet|codec_type=audio|stream_index=0|pts=124928|pts_time=2.832834|dts=124928|dts_time=2.832834|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=230|pos=25052|flags=K_ -packet|codec_type=audio|stream_index=0|pts=125952|pts_time=2.856054|dts=125952|dts_time=2.856054|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=198|pos=25282|flags=K_ -packet|codec_type=audio|stream_index=0|pts=126976|pts_time=2.879274|dts=126976|dts_time=2.879274|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=183|pos=25480|flags=K_ -packet|codec_type=audio|stream_index=0|pts=128000|pts_time=2.902494|dts=128000|dts_time=2.902494|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=199|pos=25663|flags=K_ -packet|codec_type=audio|stream_index=0|pts=129024|pts_time=2.925714|dts=129024|dts_time=2.925714|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=196|pos=25862|flags=K_ -packet|codec_type=audio|stream_index=0|pts=130048|pts_time=2.948934|dts=130048|dts_time=2.948934|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=186|pos=26058|flags=K_ -packet|codec_type=audio|stream_index=0|pts=131072|pts_time=2.972154|dts=131072|dts_time=2.972154|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=26244|flags=K_ -packet|codec_type=audio|stream_index=0|pts=132096|pts_time=2.995374|dts=132096|dts_time=2.995374|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=210|pos=26444|flags=K_ -packet|codec_type=audio|stream_index=0|pts=133120|pts_time=3.018594|dts=133120|dts_time=3.018594|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=196|pos=26654|flags=K_ -packet|codec_type=audio|stream_index=0|pts=134144|pts_time=3.041814|dts=134144|dts_time=3.041814|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=214|pos=26850|flags=K_ -packet|codec_type=audio|stream_index=0|pts=135168|pts_time=3.065034|dts=135168|dts_time=3.065034|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=185|pos=27064|flags=K_ -packet|codec_type=audio|stream_index=0|pts=136192|pts_time=3.088254|dts=136192|dts_time=3.088254|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=198|pos=27249|flags=K_ -packet|codec_type=audio|stream_index=0|pts=137216|pts_time=3.111474|dts=137216|dts_time=3.111474|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=27447|flags=K_ -packet|codec_type=audio|stream_index=0|pts=138240|pts_time=3.134694|dts=138240|dts_time=3.134694|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=208|pos=27647|flags=K_ -packet|codec_type=audio|stream_index=0|pts=139264|pts_time=3.157914|dts=139264|dts_time=3.157914|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=212|pos=27855|flags=K_ -packet|codec_type=audio|stream_index=0|pts=140288|pts_time=3.181134|dts=140288|dts_time=3.181134|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=208|pos=28067|flags=K_ -packet|codec_type=audio|stream_index=0|pts=141312|pts_time=3.204354|dts=141312|dts_time=3.204354|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=192|pos=28275|flags=K_ -packet|codec_type=audio|stream_index=0|pts=142336|pts_time=3.227574|dts=142336|dts_time=3.227574|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=192|pos=28467|flags=K_ -packet|codec_type=audio|stream_index=0|pts=143360|pts_time=3.250794|dts=143360|dts_time=3.250794|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=211|pos=28659|flags=K_ -packet|codec_type=audio|stream_index=0|pts=144384|pts_time=3.274014|dts=144384|dts_time=3.274014|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=28870|flags=K_ -packet|codec_type=audio|stream_index=0|pts=145408|pts_time=3.297234|dts=145408|dts_time=3.297234|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=208|pos=29065|flags=K_ -packet|codec_type=audio|stream_index=0|pts=146432|pts_time=3.320454|dts=146432|dts_time=3.320454|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=29273|flags=K_ -packet|codec_type=audio|stream_index=0|pts=147456|pts_time=3.343673|dts=147456|dts_time=3.343673|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=204|pos=29468|flags=K_ -packet|codec_type=audio|stream_index=0|pts=148480|pts_time=3.366893|dts=148480|dts_time=3.366893|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=209|pos=29672|flags=K_ -packet|codec_type=audio|stream_index=0|pts=149504|pts_time=3.390113|dts=149504|dts_time=3.390113|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=29881|flags=K_ -packet|codec_type=audio|stream_index=0|pts=150528|pts_time=3.413333|dts=150528|dts_time=3.413333|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=191|pos=30076|flags=K_ -packet|codec_type=audio|stream_index=0|pts=151552|pts_time=3.436553|dts=151552|dts_time=3.436553|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=210|pos=30267|flags=K_ -packet|codec_type=audio|stream_index=0|pts=152576|pts_time=3.459773|dts=152576|dts_time=3.459773|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=209|pos=30477|flags=K_ -packet|codec_type=audio|stream_index=0|pts=153600|pts_time=3.482993|dts=153600|dts_time=3.482993|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=175|pos=30686|flags=K_ -packet|codec_type=audio|stream_index=0|pts=154624|pts_time=3.506213|dts=154624|dts_time=3.506213|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=244|pos=30861|flags=K_ -packet|codec_type=audio|stream_index=0|pts=155648|pts_time=3.529433|dts=155648|dts_time=3.529433|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=177|pos=31105|flags=K_ -packet|codec_type=audio|stream_index=0|pts=156672|pts_time=3.552653|dts=156672|dts_time=3.552653|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=217|pos=31282|flags=K_ -packet|codec_type=audio|stream_index=0|pts=157696|pts_time=3.575873|dts=157696|dts_time=3.575873|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=182|pos=31499|flags=K_ -packet|codec_type=audio|stream_index=0|pts=158720|pts_time=3.599093|dts=158720|dts_time=3.599093|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=181|pos=31681|flags=K_ -packet|codec_type=audio|stream_index=0|pts=159744|pts_time=3.622313|dts=159744|dts_time=3.622313|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=203|pos=31862|flags=K_ -packet|codec_type=audio|stream_index=0|pts=160768|pts_time=3.645533|dts=160768|dts_time=3.645533|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=198|pos=32065|flags=K_ -packet|codec_type=audio|stream_index=0|pts=161792|pts_time=3.668753|dts=161792|dts_time=3.668753|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=217|pos=32263|flags=K_ -packet|codec_type=audio|stream_index=0|pts=162816|pts_time=3.691973|dts=162816|dts_time=3.691973|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=32480|flags=K_ -packet|codec_type=audio|stream_index=0|pts=163840|pts_time=3.715193|dts=163840|dts_time=3.715193|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=198|pos=32675|flags=K_ -packet|codec_type=audio|stream_index=0|pts=164864|pts_time=3.738413|dts=164864|dts_time=3.738413|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=202|pos=32873|flags=K_ -packet|codec_type=audio|stream_index=0|pts=165888|pts_time=3.761633|dts=165888|dts_time=3.761633|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=185|pos=33075|flags=K_ -packet|codec_type=audio|stream_index=0|pts=166912|pts_time=3.784853|dts=166912|dts_time=3.784853|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=196|pos=33260|flags=K_ -packet|codec_type=audio|stream_index=0|pts=167936|pts_time=3.808073|dts=167936|dts_time=3.808073|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=226|pos=33456|flags=K_ -packet|codec_type=audio|stream_index=0|pts=168960|pts_time=3.831293|dts=168960|dts_time=3.831293|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=187|pos=33682|flags=K_ -packet|codec_type=audio|stream_index=0|pts=169984|pts_time=3.854512|dts=169984|dts_time=3.854512|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=193|pos=33869|flags=K_ -packet|codec_type=audio|stream_index=0|pts=171008|pts_time=3.877732|dts=171008|dts_time=3.877732|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=218|pos=34062|flags=K_ -packet|codec_type=audio|stream_index=0|pts=172032|pts_time=3.900952|dts=172032|dts_time=3.900952|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=34280|flags=K_ -packet|codec_type=audio|stream_index=0|pts=173056|pts_time=3.924172|dts=173056|dts_time=3.924172|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=34480|flags=K_ -packet|codec_type=audio|stream_index=0|pts=174080|pts_time=3.947392|dts=174080|dts_time=3.947392|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=198|pos=34680|flags=K_ -packet|codec_type=audio|stream_index=0|pts=175104|pts_time=3.970612|dts=175104|dts_time=3.970612|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=34878|flags=K_ -packet|codec_type=audio|stream_index=0|pts=176128|pts_time=3.993832|dts=176128|dts_time=3.993832|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=197|pos=35078|flags=K_ -packet|codec_type=audio|stream_index=0|pts=177152|pts_time=4.017052|dts=177152|dts_time=4.017052|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=209|pos=35275|flags=K_ -packet|codec_type=audio|stream_index=0|pts=178176|pts_time=4.040272|dts=178176|dts_time=4.040272|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=205|pos=35484|flags=K_ -packet|codec_type=audio|stream_index=0|pts=179200|pts_time=4.063492|dts=179200|dts_time=4.063492|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=199|pos=35689|flags=K_ -packet|codec_type=audio|stream_index=0|pts=180224|pts_time=4.086712|dts=180224|dts_time=4.086712|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=192|pos=35888|flags=K_ -packet|codec_type=audio|stream_index=0|pts=181248|pts_time=4.109932|dts=181248|dts_time=4.109932|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=201|pos=36080|flags=K_ -packet|codec_type=audio|stream_index=0|pts=182272|pts_time=4.133152|dts=182272|dts_time=4.133152|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=36281|flags=K_ -packet|codec_type=audio|stream_index=0|pts=183296|pts_time=4.156372|dts=183296|dts_time=4.156372|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=202|pos=36481|flags=K_ -packet|codec_type=audio|stream_index=0|pts=184320|pts_time=4.179592|dts=184320|dts_time=4.179592|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=196|pos=36683|flags=K_ -packet|codec_type=audio|stream_index=0|pts=185344|pts_time=4.202812|dts=185344|dts_time=4.202812|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=36879|flags=K_ -packet|codec_type=audio|stream_index=0|pts=186368|pts_time=4.226032|dts=186368|dts_time=4.226032|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=209|pos=37079|flags=K_ -packet|codec_type=audio|stream_index=0|pts=187392|pts_time=4.249252|dts=187392|dts_time=4.249252|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=201|pos=37288|flags=K_ -packet|codec_type=audio|stream_index=0|pts=188416|pts_time=4.272472|dts=188416|dts_time=4.272472|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=201|pos=37489|flags=K_ -packet|codec_type=audio|stream_index=0|pts=189440|pts_time=4.295692|dts=189440|dts_time=4.295692|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=201|pos=37690|flags=K_ -packet|codec_type=audio|stream_index=0|pts=190464|pts_time=4.318912|dts=190464|dts_time=4.318912|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=199|pos=37891|flags=K_ -packet|codec_type=audio|stream_index=0|pts=191488|pts_time=4.342132|dts=191488|dts_time=4.342132|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=198|pos=38090|flags=K_ -packet|codec_type=audio|stream_index=0|pts=192512|pts_time=4.365351|dts=192512|dts_time=4.365351|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=205|pos=38288|flags=K_ -packet|codec_type=audio|stream_index=0|pts=193536|pts_time=4.388571|dts=193536|dts_time=4.388571|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=190|pos=38493|flags=K_ -packet|codec_type=audio|stream_index=0|pts=194560|pts_time=4.411791|dts=194560|dts_time=4.411791|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=207|pos=38683|flags=K_ -packet|codec_type=audio|stream_index=0|pts=195584|pts_time=4.435011|dts=195584|dts_time=4.435011|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=204|pos=38890|flags=K_ -packet|codec_type=audio|stream_index=0|pts=196608|pts_time=4.458231|dts=196608|dts_time=4.458231|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=192|pos=39094|flags=K_ -packet|codec_type=audio|stream_index=0|pts=197632|pts_time=4.481451|dts=197632|dts_time=4.481451|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=211|pos=39286|flags=K_ -packet|codec_type=audio|stream_index=0|pts=198656|pts_time=4.504671|dts=198656|dts_time=4.504671|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=39497|flags=K_ -packet|codec_type=audio|stream_index=0|pts=199680|pts_time=4.527891|dts=199680|dts_time=4.527891|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=214|pos=39692|flags=K_ -packet|codec_type=audio|stream_index=0|pts=200704|pts_time=4.551111|dts=200704|dts_time=4.551111|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=195|pos=39906|flags=K_ -packet|codec_type=audio|stream_index=0|pts=201728|pts_time=4.574331|dts=201728|dts_time=4.574331|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=199|pos=40101|flags=K_ -packet|codec_type=audio|stream_index=0|pts=202752|pts_time=4.597551|dts=202752|dts_time=4.597551|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=183|pos=40300|flags=K_ -packet|codec_type=audio|stream_index=0|pts=203776|pts_time=4.620771|dts=203776|dts_time=4.620771|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=211|pos=40483|flags=K_ -packet|codec_type=audio|stream_index=0|pts=204800|pts_time=4.643991|dts=204800|dts_time=4.643991|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=200|pos=40694|flags=K_ -packet|codec_type=audio|stream_index=0|pts=205824|pts_time=4.667211|dts=205824|dts_time=4.667211|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=199|pos=40894|flags=K_ -packet|codec_type=audio|stream_index=0|pts=206848|pts_time=4.690431|dts=206848|dts_time=4.690431|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=213|pos=41093|flags=K_ -packet|codec_type=audio|stream_index=0|pts=207872|pts_time=4.713651|dts=207872|dts_time=4.713651|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=191|pos=41306|flags=K_ -packet|codec_type=audio|stream_index=0|pts=208896|pts_time=4.736871|dts=208896|dts_time=4.736871|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=211|pos=41497|flags=K_ -packet|codec_type=audio|stream_index=0|pts=209920|pts_time=4.760091|dts=209920|dts_time=4.760091|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=198|pos=41708|flags=K_ -packet|codec_type=audio|stream_index=0|pts=210944|pts_time=4.783311|dts=210944|dts_time=4.783311|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=203|pos=41906|flags=K_ -packet|codec_type=audio|stream_index=0|pts=211968|pts_time=4.806531|dts=211968|dts_time=4.806531|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=196|pos=42109|flags=K_ -packet|codec_type=audio|stream_index=0|pts=212992|pts_time=4.829751|dts=212992|dts_time=4.829751|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=197|pos=42305|flags=K_ -packet|codec_type=audio|stream_index=0|pts=214016|pts_time=4.852971|dts=214016|dts_time=4.852971|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=190|pos=42502|flags=K_ -packet|codec_type=audio|stream_index=0|pts=215040|pts_time=4.876190|dts=215040|dts_time=4.876190|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=208|pos=42692|flags=K_ -packet|codec_type=audio|stream_index=0|pts=216064|pts_time=4.899410|dts=216064|dts_time=4.899410|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=203|pos=42900|flags=K_ -packet|codec_type=audio|stream_index=0|pts=217088|pts_time=4.922630|dts=217088|dts_time=4.922630|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=198|pos=43103|flags=K_ -packet|codec_type=audio|stream_index=0|pts=218112|pts_time=4.945850|dts=218112|dts_time=4.945850|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=284|pos=43301|flags=K_ -packet|codec_type=audio|stream_index=0|pts=219136|pts_time=4.969070|dts=219136|dts_time=4.969070|duration=1364|duration_time=0.030930|convergence_duration=N/A|convergence_duration_time=N/A|size=5|pos=43585|flags=K_ +packet|codec_type=audio|stream_index=0|pts=-1024|pts_time=-0.023220|dts=-1024|dts_time=-0.023220|duration=1024|duration_time=0.023220|size=258|pos=294|flags=KD +packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1024|duration_time=0.023220|size=146|pos=552|flags=K_ +packet|codec_type=audio|stream_index=0|pts=1024|pts_time=0.023220|dts=1024|dts_time=0.023220|duration=1024|duration_time=0.023220|size=186|pos=698|flags=K_ +packet|codec_type=audio|stream_index=0|pts=2048|pts_time=0.046440|dts=2048|dts_time=0.046440|duration=1024|duration_time=0.023220|size=222|pos=884|flags=K_ +packet|codec_type=audio|stream_index=0|pts=3072|pts_time=0.069660|dts=3072|dts_time=0.069660|duration=1024|duration_time=0.023220|size=186|pos=1106|flags=K_ +packet|codec_type=audio|stream_index=0|pts=4096|pts_time=0.092880|dts=4096|dts_time=0.092880|duration=1024|duration_time=0.023220|size=206|pos=1292|flags=K_ +packet|codec_type=audio|stream_index=0|pts=5120|pts_time=0.116100|dts=5120|dts_time=0.116100|duration=1024|duration_time=0.023220|size=199|pos=1498|flags=K_ +packet|codec_type=audio|stream_index=0|pts=6144|pts_time=0.139320|dts=6144|dts_time=0.139320|duration=1024|duration_time=0.023220|size=236|pos=1697|flags=K_ +packet|codec_type=audio|stream_index=0|pts=7168|pts_time=0.162540|dts=7168|dts_time=0.162540|duration=1024|duration_time=0.023220|size=208|pos=1933|flags=K_ +packet|codec_type=audio|stream_index=0|pts=8192|pts_time=0.185760|dts=8192|dts_time=0.185760|duration=1024|duration_time=0.023220|size=238|pos=2141|flags=K_ +packet|codec_type=audio|stream_index=0|pts=9216|pts_time=0.208980|dts=9216|dts_time=0.208980|duration=1024|duration_time=0.023220|size=222|pos=2379|flags=K_ +packet|codec_type=audio|stream_index=0|pts=10240|pts_time=0.232200|dts=10240|dts_time=0.232200|duration=1024|duration_time=0.023220|size=211|pos=2601|flags=K_ +packet|codec_type=audio|stream_index=0|pts=11264|pts_time=0.255420|dts=11264|dts_time=0.255420|duration=1024|duration_time=0.023220|size=153|pos=2812|flags=K_ +packet|codec_type=audio|stream_index=0|pts=12288|pts_time=0.278639|dts=12288|dts_time=0.278639|duration=1024|duration_time=0.023220|size=191|pos=2965|flags=K_ +packet|codec_type=audio|stream_index=0|pts=13312|pts_time=0.301859|dts=13312|dts_time=0.301859|duration=1024|duration_time=0.023220|size=208|pos=3156|flags=K_ +packet|codec_type=audio|stream_index=0|pts=14336|pts_time=0.325079|dts=14336|dts_time=0.325079|duration=1024|duration_time=0.023220|size=188|pos=3364|flags=K_ +packet|codec_type=audio|stream_index=0|pts=15360|pts_time=0.348299|dts=15360|dts_time=0.348299|duration=1024|duration_time=0.023220|size=170|pos=3552|flags=K_ +packet|codec_type=audio|stream_index=0|pts=16384|pts_time=0.371519|dts=16384|dts_time=0.371519|duration=1024|duration_time=0.023220|size=221|pos=3722|flags=K_ +packet|codec_type=audio|stream_index=0|pts=17408|pts_time=0.394739|dts=17408|dts_time=0.394739|duration=1024|duration_time=0.023220|size=247|pos=3943|flags=K_ +packet|codec_type=audio|stream_index=0|pts=18432|pts_time=0.417959|dts=18432|dts_time=0.417959|duration=1024|duration_time=0.023220|size=202|pos=4190|flags=K_ +packet|codec_type=audio|stream_index=0|pts=19456|pts_time=0.441179|dts=19456|dts_time=0.441179|duration=1024|duration_time=0.023220|size=186|pos=4392|flags=K_ +packet|codec_type=audio|stream_index=0|pts=20480|pts_time=0.464399|dts=20480|dts_time=0.464399|duration=1024|duration_time=0.023220|size=196|pos=4578|flags=K_ +packet|codec_type=audio|stream_index=0|pts=21504|pts_time=0.487619|dts=21504|dts_time=0.487619|duration=1024|duration_time=0.023220|size=200|pos=4774|flags=K_ +packet|codec_type=audio|stream_index=0|pts=22528|pts_time=0.510839|dts=22528|dts_time=0.510839|duration=1024|duration_time=0.023220|size=170|pos=4974|flags=K_ +packet|codec_type=audio|stream_index=0|pts=23552|pts_time=0.534059|dts=23552|dts_time=0.534059|duration=1024|duration_time=0.023220|size=172|pos=5144|flags=K_ +packet|codec_type=audio|stream_index=0|pts=24576|pts_time=0.557279|dts=24576|dts_time=0.557279|duration=1024|duration_time=0.023220|size=206|pos=5316|flags=K_ +packet|codec_type=audio|stream_index=0|pts=25600|pts_time=0.580499|dts=25600|dts_time=0.580499|duration=1024|duration_time=0.023220|size=208|pos=5522|flags=K_ +packet|codec_type=audio|stream_index=0|pts=26624|pts_time=0.603719|dts=26624|dts_time=0.603719|duration=1024|duration_time=0.023220|size=217|pos=5730|flags=K_ +packet|codec_type=audio|stream_index=0|pts=27648|pts_time=0.626939|dts=27648|dts_time=0.626939|duration=1024|duration_time=0.023220|size=252|pos=5947|flags=K_ +packet|codec_type=audio|stream_index=0|pts=28672|pts_time=0.650159|dts=28672|dts_time=0.650159|duration=1024|duration_time=0.023220|size=171|pos=6199|flags=K_ +packet|codec_type=audio|stream_index=0|pts=29696|pts_time=0.673379|dts=29696|dts_time=0.673379|duration=1024|duration_time=0.023220|size=206|pos=6370|flags=K_ +packet|codec_type=audio|stream_index=0|pts=30720|pts_time=0.696599|dts=30720|dts_time=0.696599|duration=1024|duration_time=0.023220|size=237|pos=6576|flags=K_ +packet|codec_type=audio|stream_index=0|pts=31744|pts_time=0.719819|dts=31744|dts_time=0.719819|duration=1024|duration_time=0.023220|size=210|pos=6813|flags=K_ +packet|codec_type=audio|stream_index=0|pts=32768|pts_time=0.743039|dts=32768|dts_time=0.743039|duration=1024|duration_time=0.023220|size=166|pos=7023|flags=K_ +packet|codec_type=audio|stream_index=0|pts=33792|pts_time=0.766259|dts=33792|dts_time=0.766259|duration=1024|duration_time=0.023220|size=166|pos=7189|flags=K_ +packet|codec_type=audio|stream_index=0|pts=34816|pts_time=0.789478|dts=34816|dts_time=0.789478|duration=1024|duration_time=0.023220|size=177|pos=7355|flags=K_ +packet|codec_type=audio|stream_index=0|pts=35840|pts_time=0.812698|dts=35840|dts_time=0.812698|duration=1024|duration_time=0.023220|size=188|pos=7532|flags=K_ +packet|codec_type=audio|stream_index=0|pts=36864|pts_time=0.835918|dts=36864|dts_time=0.835918|duration=1024|duration_time=0.023220|size=193|pos=7720|flags=K_ +packet|codec_type=audio|stream_index=0|pts=37888|pts_time=0.859138|dts=37888|dts_time=0.859138|duration=1024|duration_time=0.023220|size=195|pos=7913|flags=K_ +packet|codec_type=audio|stream_index=0|pts=38912|pts_time=0.882358|dts=38912|dts_time=0.882358|duration=1024|duration_time=0.023220|size=211|pos=8108|flags=K_ +packet|codec_type=audio|stream_index=0|pts=39936|pts_time=0.905578|dts=39936|dts_time=0.905578|duration=1024|duration_time=0.023220|size=249|pos=8319|flags=K_ +packet|codec_type=audio|stream_index=0|pts=40960|pts_time=0.928798|dts=40960|dts_time=0.928798|duration=1024|duration_time=0.023220|size=223|pos=8568|flags=K_ +packet|codec_type=audio|stream_index=0|pts=41984|pts_time=0.952018|dts=41984|dts_time=0.952018|duration=1024|duration_time=0.023220|size=230|pos=8791|flags=K_ +packet|codec_type=audio|stream_index=0|pts=43008|pts_time=0.975238|dts=43008|dts_time=0.975238|duration=1024|duration_time=0.023220|size=203|pos=9021|flags=K_ +packet|codec_type=audio|stream_index=0|pts=44032|pts_time=0.998458|dts=44032|dts_time=0.998458|duration=1024|duration_time=0.023220|size=180|pos=9224|flags=K_ +packet|codec_type=audio|stream_index=0|pts=45056|pts_time=1.021678|dts=45056|dts_time=1.021678|duration=1024|duration_time=0.023220|size=172|pos=9404|flags=K_ +packet|codec_type=audio|stream_index=0|pts=46080|pts_time=1.044898|dts=46080|dts_time=1.044898|duration=1024|duration_time=0.023220|size=240|pos=9576|flags=K_ +packet|codec_type=audio|stream_index=0|pts=47104|pts_time=1.068118|dts=47104|dts_time=1.068118|duration=1024|duration_time=0.023220|size=179|pos=9816|flags=K_ +packet|codec_type=audio|stream_index=0|pts=48128|pts_time=1.091338|dts=48128|dts_time=1.091338|duration=1024|duration_time=0.023220|size=191|pos=9995|flags=K_ +packet|codec_type=audio|stream_index=0|pts=49152|pts_time=1.114558|dts=49152|dts_time=1.114558|duration=1024|duration_time=0.023220|size=184|pos=10186|flags=K_ +packet|codec_type=audio|stream_index=0|pts=50176|pts_time=1.137778|dts=50176|dts_time=1.137778|duration=1024|duration_time=0.023220|size=214|pos=10370|flags=K_ +packet|codec_type=audio|stream_index=0|pts=51200|pts_time=1.160998|dts=51200|dts_time=1.160998|duration=1024|duration_time=0.023220|size=194|pos=10584|flags=K_ +packet|codec_type=audio|stream_index=0|pts=52224|pts_time=1.184218|dts=52224|dts_time=1.184218|duration=1024|duration_time=0.023220|size=235|pos=10778|flags=K_ +packet|codec_type=audio|stream_index=0|pts=53248|pts_time=1.207438|dts=53248|dts_time=1.207438|duration=1024|duration_time=0.023220|size=195|pos=11013|flags=K_ +packet|codec_type=audio|stream_index=0|pts=54272|pts_time=1.230658|dts=54272|dts_time=1.230658|duration=1024|duration_time=0.023220|size=220|pos=11208|flags=K_ +packet|codec_type=audio|stream_index=0|pts=55296|pts_time=1.253878|dts=55296|dts_time=1.253878|duration=1024|duration_time=0.023220|size=187|pos=11428|flags=K_ +packet|codec_type=audio|stream_index=0|pts=56320|pts_time=1.277098|dts=56320|dts_time=1.277098|duration=1024|duration_time=0.023220|size=238|pos=11615|flags=K_ +packet|codec_type=audio|stream_index=0|pts=57344|pts_time=1.300317|dts=57344|dts_time=1.300317|duration=1024|duration_time=0.023220|size=175|pos=11853|flags=K_ +packet|codec_type=audio|stream_index=0|pts=58368|pts_time=1.323537|dts=58368|dts_time=1.323537|duration=1024|duration_time=0.023220|size=178|pos=12028|flags=K_ +packet|codec_type=audio|stream_index=0|pts=59392|pts_time=1.346757|dts=59392|dts_time=1.346757|duration=1024|duration_time=0.023220|size=219|pos=12206|flags=K_ +packet|codec_type=audio|stream_index=0|pts=60416|pts_time=1.369977|dts=60416|dts_time=1.369977|duration=1024|duration_time=0.023220|size=179|pos=12425|flags=K_ +packet|codec_type=audio|stream_index=0|pts=61440|pts_time=1.393197|dts=61440|dts_time=1.393197|duration=1024|duration_time=0.023220|size=193|pos=12604|flags=K_ +packet|codec_type=audio|stream_index=0|pts=62464|pts_time=1.416417|dts=62464|dts_time=1.416417|duration=1024|duration_time=0.023220|size=200|pos=12797|flags=K_ +packet|codec_type=audio|stream_index=0|pts=63488|pts_time=1.439637|dts=63488|dts_time=1.439637|duration=1024|duration_time=0.023220|size=218|pos=12997|flags=K_ +packet|codec_type=audio|stream_index=0|pts=64512|pts_time=1.462857|dts=64512|dts_time=1.462857|duration=1024|duration_time=0.023220|size=215|pos=13215|flags=K_ +packet|codec_type=audio|stream_index=0|pts=65536|pts_time=1.486077|dts=65536|dts_time=1.486077|duration=1024|duration_time=0.023220|size=209|pos=13430|flags=K_ +packet|codec_type=audio|stream_index=0|pts=66560|pts_time=1.509297|dts=66560|dts_time=1.509297|duration=1024|duration_time=0.023220|size=171|pos=13639|flags=K_ +packet|codec_type=audio|stream_index=0|pts=67584|pts_time=1.532517|dts=67584|dts_time=1.532517|duration=1024|duration_time=0.023220|size=179|pos=13810|flags=K_ +packet|codec_type=audio|stream_index=0|pts=68608|pts_time=1.555737|dts=68608|dts_time=1.555737|duration=1024|duration_time=0.023220|size=185|pos=13989|flags=K_ +packet|codec_type=audio|stream_index=0|pts=69632|pts_time=1.578957|dts=69632|dts_time=1.578957|duration=1024|duration_time=0.023220|size=225|pos=14174|flags=K_ +packet|codec_type=audio|stream_index=0|pts=70656|pts_time=1.602177|dts=70656|dts_time=1.602177|duration=1024|duration_time=0.023220|size=221|pos=14399|flags=K_ +packet|codec_type=audio|stream_index=0|pts=71680|pts_time=1.625397|dts=71680|dts_time=1.625397|duration=1024|duration_time=0.023220|size=201|pos=14620|flags=K_ +packet|codec_type=audio|stream_index=0|pts=72704|pts_time=1.648617|dts=72704|dts_time=1.648617|duration=1024|duration_time=0.023220|size=206|pos=14821|flags=K_ +packet|codec_type=audio|stream_index=0|pts=73728|pts_time=1.671837|dts=73728|dts_time=1.671837|duration=1024|duration_time=0.023220|size=182|pos=15027|flags=K_ +packet|codec_type=audio|stream_index=0|pts=74752|pts_time=1.695057|dts=74752|dts_time=1.695057|duration=1024|duration_time=0.023220|size=176|pos=15209|flags=K_ +packet|codec_type=audio|stream_index=0|pts=75776|pts_time=1.718277|dts=75776|dts_time=1.718277|duration=1024|duration_time=0.023220|size=233|pos=15385|flags=K_ +packet|codec_type=audio|stream_index=0|pts=76800|pts_time=1.741497|dts=76800|dts_time=1.741497|duration=1024|duration_time=0.023220|size=199|pos=15618|flags=K_ +packet|codec_type=audio|stream_index=0|pts=77824|pts_time=1.764717|dts=77824|dts_time=1.764717|duration=1024|duration_time=0.023220|size=220|pos=15817|flags=K_ +packet|codec_type=audio|stream_index=0|pts=78848|pts_time=1.787937|dts=78848|dts_time=1.787937|duration=1024|duration_time=0.023220|size=190|pos=16037|flags=K_ +packet|codec_type=audio|stream_index=0|pts=79872|pts_time=1.811156|dts=79872|dts_time=1.811156|duration=1024|duration_time=0.023220|size=210|pos=16227|flags=K_ +packet|codec_type=audio|stream_index=0|pts=80896|pts_time=1.834376|dts=80896|dts_time=1.834376|duration=1024|duration_time=0.023220|size=204|pos=16437|flags=K_ +packet|codec_type=audio|stream_index=0|pts=81920|pts_time=1.857596|dts=81920|dts_time=1.857596|duration=1024|duration_time=0.023220|size=171|pos=16641|flags=K_ +packet|codec_type=audio|stream_index=0|pts=82944|pts_time=1.880816|dts=82944|dts_time=1.880816|duration=1024|duration_time=0.023220|size=167|pos=16812|flags=K_ +packet|codec_type=audio|stream_index=0|pts=83968|pts_time=1.904036|dts=83968|dts_time=1.904036|duration=1024|duration_time=0.023220|size=200|pos=16979|flags=K_ +packet|codec_type=audio|stream_index=0|pts=84992|pts_time=1.927256|dts=84992|dts_time=1.927256|duration=1024|duration_time=0.023220|size=254|pos=17179|flags=K_ +packet|codec_type=audio|stream_index=0|pts=86016|pts_time=1.950476|dts=86016|dts_time=1.950476|duration=1024|duration_time=0.023220|size=205|pos=17433|flags=K_ +packet|codec_type=audio|stream_index=0|pts=87040|pts_time=1.973696|dts=87040|dts_time=1.973696|duration=1024|duration_time=0.023220|size=196|pos=17638|flags=K_ +packet|codec_type=audio|stream_index=0|pts=88064|pts_time=1.996916|dts=88064|dts_time=1.996916|duration=1024|duration_time=0.023220|size=190|pos=17834|flags=K_ +packet|codec_type=audio|stream_index=0|pts=89088|pts_time=2.020136|dts=89088|dts_time=2.020136|duration=1024|duration_time=0.023220|size=197|pos=18024|flags=K_ +packet|codec_type=audio|stream_index=0|pts=90112|pts_time=2.043356|dts=90112|dts_time=2.043356|duration=1024|duration_time=0.023220|size=186|pos=18221|flags=K_ +packet|codec_type=audio|stream_index=0|pts=91136|pts_time=2.066576|dts=91136|dts_time=2.066576|duration=1024|duration_time=0.023220|size=194|pos=18407|flags=K_ +packet|codec_type=audio|stream_index=0|pts=92160|pts_time=2.089796|dts=92160|dts_time=2.089796|duration=1024|duration_time=0.023220|size=227|pos=18601|flags=K_ +packet|codec_type=audio|stream_index=0|pts=93184|pts_time=2.113016|dts=93184|dts_time=2.113016|duration=1024|duration_time=0.023220|size=195|pos=18828|flags=K_ +packet|codec_type=audio|stream_index=0|pts=94208|pts_time=2.136236|dts=94208|dts_time=2.136236|duration=1024|duration_time=0.023220|size=228|pos=19023|flags=K_ +packet|codec_type=audio|stream_index=0|pts=95232|pts_time=2.159456|dts=95232|dts_time=2.159456|duration=1024|duration_time=0.023220|size=196|pos=19251|flags=K_ +packet|codec_type=audio|stream_index=0|pts=96256|pts_time=2.182676|dts=96256|dts_time=2.182676|duration=1024|duration_time=0.023220|size=197|pos=19447|flags=K_ +packet|codec_type=audio|stream_index=0|pts=97280|pts_time=2.205896|dts=97280|dts_time=2.205896|duration=1024|duration_time=0.023220|size=186|pos=19644|flags=K_ +packet|codec_type=audio|stream_index=0|pts=98304|pts_time=2.229116|dts=98304|dts_time=2.229116|duration=1024|duration_time=0.023220|size=191|pos=19830|flags=K_ +packet|codec_type=audio|stream_index=0|pts=99328|pts_time=2.252336|dts=99328|dts_time=2.252336|duration=1024|duration_time=0.023220|size=215|pos=20021|flags=K_ +packet|codec_type=audio|stream_index=0|pts=100352|pts_time=2.275556|dts=100352|dts_time=2.275556|duration=1024|duration_time=0.023220|size=203|pos=20236|flags=K_ +packet|codec_type=audio|stream_index=0|pts=101376|pts_time=2.298776|dts=101376|dts_time=2.298776|duration=1024|duration_time=0.023220|size=205|pos=20439|flags=K_ +packet|codec_type=audio|stream_index=0|pts=102400|pts_time=2.321995|dts=102400|dts_time=2.321995|duration=1024|duration_time=0.023220|size=205|pos=20644|flags=K_ +packet|codec_type=audio|stream_index=0|pts=103424|pts_time=2.345215|dts=103424|dts_time=2.345215|duration=1024|duration_time=0.023220|size=213|pos=20849|flags=K_ +packet|codec_type=audio|stream_index=0|pts=104448|pts_time=2.368435|dts=104448|dts_time=2.368435|duration=1024|duration_time=0.023220|size=198|pos=21062|flags=K_ +packet|codec_type=audio|stream_index=0|pts=105472|pts_time=2.391655|dts=105472|dts_time=2.391655|duration=1024|duration_time=0.023220|size=178|pos=21260|flags=K_ +packet|codec_type=audio|stream_index=0|pts=106496|pts_time=2.414875|dts=106496|dts_time=2.414875|duration=1024|duration_time=0.023220|size=195|pos=21438|flags=K_ +packet|codec_type=audio|stream_index=0|pts=107520|pts_time=2.438095|dts=107520|dts_time=2.438095|duration=1024|duration_time=0.023220|size=227|pos=21633|flags=K_ +packet|codec_type=audio|stream_index=0|pts=108544|pts_time=2.461315|dts=108544|dts_time=2.461315|duration=1024|duration_time=0.023220|size=185|pos=21860|flags=K_ +packet|codec_type=audio|stream_index=0|pts=109568|pts_time=2.484535|dts=109568|dts_time=2.484535|duration=1024|duration_time=0.023220|size=206|pos=22045|flags=K_ +packet|codec_type=audio|stream_index=0|pts=110592|pts_time=2.507755|dts=110592|dts_time=2.507755|duration=1024|duration_time=0.023220|size=183|pos=22251|flags=K_ +packet|codec_type=audio|stream_index=0|pts=111616|pts_time=2.530975|dts=111616|dts_time=2.530975|duration=1024|duration_time=0.023220|size=208|pos=22434|flags=K_ +packet|codec_type=audio|stream_index=0|pts=112640|pts_time=2.554195|dts=112640|dts_time=2.554195|duration=1024|duration_time=0.023220|size=204|pos=22642|flags=K_ +packet|codec_type=audio|stream_index=0|pts=113664|pts_time=2.577415|dts=113664|dts_time=2.577415|duration=1024|duration_time=0.023220|size=192|pos=22846|flags=K_ +packet|codec_type=audio|stream_index=0|pts=114688|pts_time=2.600635|dts=114688|dts_time=2.600635|duration=1024|duration_time=0.023220|size=190|pos=23038|flags=K_ +packet|codec_type=audio|stream_index=0|pts=115712|pts_time=2.623855|dts=115712|dts_time=2.623855|duration=1024|duration_time=0.023220|size=199|pos=23228|flags=K_ +packet|codec_type=audio|stream_index=0|pts=116736|pts_time=2.647075|dts=116736|dts_time=2.647075|duration=1024|duration_time=0.023220|size=229|pos=23427|flags=K_ +packet|codec_type=audio|stream_index=0|pts=117760|pts_time=2.670295|dts=117760|dts_time=2.670295|duration=1024|duration_time=0.023220|size=208|pos=23656|flags=K_ +packet|codec_type=audio|stream_index=0|pts=118784|pts_time=2.693515|dts=118784|dts_time=2.693515|duration=1024|duration_time=0.023220|size=195|pos=23864|flags=K_ +packet|codec_type=audio|stream_index=0|pts=119808|pts_time=2.716735|dts=119808|dts_time=2.716735|duration=1024|duration_time=0.023220|size=190|pos=24059|flags=K_ +packet|codec_type=audio|stream_index=0|pts=120832|pts_time=2.739955|dts=120832|dts_time=2.739955|duration=1024|duration_time=0.023220|size=190|pos=24249|flags=K_ +packet|codec_type=audio|stream_index=0|pts=121856|pts_time=2.763175|dts=121856|dts_time=2.763175|duration=1024|duration_time=0.023220|size=192|pos=24439|flags=K_ +packet|codec_type=audio|stream_index=0|pts=122880|pts_time=2.786395|dts=122880|dts_time=2.786395|duration=1024|duration_time=0.023220|size=226|pos=24631|flags=K_ +packet|codec_type=audio|stream_index=0|pts=123904|pts_time=2.809615|dts=123904|dts_time=2.809615|duration=1024|duration_time=0.023220|size=195|pos=24857|flags=K_ +packet|codec_type=audio|stream_index=0|pts=124928|pts_time=2.832834|dts=124928|dts_time=2.832834|duration=1024|duration_time=0.023220|size=230|pos=25052|flags=K_ +packet|codec_type=audio|stream_index=0|pts=125952|pts_time=2.856054|dts=125952|dts_time=2.856054|duration=1024|duration_time=0.023220|size=198|pos=25282|flags=K_ +packet|codec_type=audio|stream_index=0|pts=126976|pts_time=2.879274|dts=126976|dts_time=2.879274|duration=1024|duration_time=0.023220|size=183|pos=25480|flags=K_ +packet|codec_type=audio|stream_index=0|pts=128000|pts_time=2.902494|dts=128000|dts_time=2.902494|duration=1024|duration_time=0.023220|size=199|pos=25663|flags=K_ +packet|codec_type=audio|stream_index=0|pts=129024|pts_time=2.925714|dts=129024|dts_time=2.925714|duration=1024|duration_time=0.023220|size=196|pos=25862|flags=K_ +packet|codec_type=audio|stream_index=0|pts=130048|pts_time=2.948934|dts=130048|dts_time=2.948934|duration=1024|duration_time=0.023220|size=186|pos=26058|flags=K_ +packet|codec_type=audio|stream_index=0|pts=131072|pts_time=2.972154|dts=131072|dts_time=2.972154|duration=1024|duration_time=0.023220|size=200|pos=26244|flags=K_ +packet|codec_type=audio|stream_index=0|pts=132096|pts_time=2.995374|dts=132096|dts_time=2.995374|duration=1024|duration_time=0.023220|size=210|pos=26444|flags=K_ +packet|codec_type=audio|stream_index=0|pts=133120|pts_time=3.018594|dts=133120|dts_time=3.018594|duration=1024|duration_time=0.023220|size=196|pos=26654|flags=K_ +packet|codec_type=audio|stream_index=0|pts=134144|pts_time=3.041814|dts=134144|dts_time=3.041814|duration=1024|duration_time=0.023220|size=214|pos=26850|flags=K_ +packet|codec_type=audio|stream_index=0|pts=135168|pts_time=3.065034|dts=135168|dts_time=3.065034|duration=1024|duration_time=0.023220|size=185|pos=27064|flags=K_ +packet|codec_type=audio|stream_index=0|pts=136192|pts_time=3.088254|dts=136192|dts_time=3.088254|duration=1024|duration_time=0.023220|size=198|pos=27249|flags=K_ +packet|codec_type=audio|stream_index=0|pts=137216|pts_time=3.111474|dts=137216|dts_time=3.111474|duration=1024|duration_time=0.023220|size=200|pos=27447|flags=K_ +packet|codec_type=audio|stream_index=0|pts=138240|pts_time=3.134694|dts=138240|dts_time=3.134694|duration=1024|duration_time=0.023220|size=208|pos=27647|flags=K_ +packet|codec_type=audio|stream_index=0|pts=139264|pts_time=3.157914|dts=139264|dts_time=3.157914|duration=1024|duration_time=0.023220|size=212|pos=27855|flags=K_ +packet|codec_type=audio|stream_index=0|pts=140288|pts_time=3.181134|dts=140288|dts_time=3.181134|duration=1024|duration_time=0.023220|size=208|pos=28067|flags=K_ +packet|codec_type=audio|stream_index=0|pts=141312|pts_time=3.204354|dts=141312|dts_time=3.204354|duration=1024|duration_time=0.023220|size=192|pos=28275|flags=K_ +packet|codec_type=audio|stream_index=0|pts=142336|pts_time=3.227574|dts=142336|dts_time=3.227574|duration=1024|duration_time=0.023220|size=192|pos=28467|flags=K_ +packet|codec_type=audio|stream_index=0|pts=143360|pts_time=3.250794|dts=143360|dts_time=3.250794|duration=1024|duration_time=0.023220|size=211|pos=28659|flags=K_ +packet|codec_type=audio|stream_index=0|pts=144384|pts_time=3.274014|dts=144384|dts_time=3.274014|duration=1024|duration_time=0.023220|size=195|pos=28870|flags=K_ +packet|codec_type=audio|stream_index=0|pts=145408|pts_time=3.297234|dts=145408|dts_time=3.297234|duration=1024|duration_time=0.023220|size=208|pos=29065|flags=K_ +packet|codec_type=audio|stream_index=0|pts=146432|pts_time=3.320454|dts=146432|dts_time=3.320454|duration=1024|duration_time=0.023220|size=195|pos=29273|flags=K_ +packet|codec_type=audio|stream_index=0|pts=147456|pts_time=3.343673|dts=147456|dts_time=3.343673|duration=1024|duration_time=0.023220|size=204|pos=29468|flags=K_ +packet|codec_type=audio|stream_index=0|pts=148480|pts_time=3.366893|dts=148480|dts_time=3.366893|duration=1024|duration_time=0.023220|size=209|pos=29672|flags=K_ +packet|codec_type=audio|stream_index=0|pts=149504|pts_time=3.390113|dts=149504|dts_time=3.390113|duration=1024|duration_time=0.023220|size=195|pos=29881|flags=K_ +packet|codec_type=audio|stream_index=0|pts=150528|pts_time=3.413333|dts=150528|dts_time=3.413333|duration=1024|duration_time=0.023220|size=191|pos=30076|flags=K_ +packet|codec_type=audio|stream_index=0|pts=151552|pts_time=3.436553|dts=151552|dts_time=3.436553|duration=1024|duration_time=0.023220|size=210|pos=30267|flags=K_ +packet|codec_type=audio|stream_index=0|pts=152576|pts_time=3.459773|dts=152576|dts_time=3.459773|duration=1024|duration_time=0.023220|size=209|pos=30477|flags=K_ +packet|codec_type=audio|stream_index=0|pts=153600|pts_time=3.482993|dts=153600|dts_time=3.482993|duration=1024|duration_time=0.023220|size=175|pos=30686|flags=K_ +packet|codec_type=audio|stream_index=0|pts=154624|pts_time=3.506213|dts=154624|dts_time=3.506213|duration=1024|duration_time=0.023220|size=244|pos=30861|flags=K_ +packet|codec_type=audio|stream_index=0|pts=155648|pts_time=3.529433|dts=155648|dts_time=3.529433|duration=1024|duration_time=0.023220|size=177|pos=31105|flags=K_ +packet|codec_type=audio|stream_index=0|pts=156672|pts_time=3.552653|dts=156672|dts_time=3.552653|duration=1024|duration_time=0.023220|size=217|pos=31282|flags=K_ +packet|codec_type=audio|stream_index=0|pts=157696|pts_time=3.575873|dts=157696|dts_time=3.575873|duration=1024|duration_time=0.023220|size=182|pos=31499|flags=K_ +packet|codec_type=audio|stream_index=0|pts=158720|pts_time=3.599093|dts=158720|dts_time=3.599093|duration=1024|duration_time=0.023220|size=181|pos=31681|flags=K_ +packet|codec_type=audio|stream_index=0|pts=159744|pts_time=3.622313|dts=159744|dts_time=3.622313|duration=1024|duration_time=0.023220|size=203|pos=31862|flags=K_ +packet|codec_type=audio|stream_index=0|pts=160768|pts_time=3.645533|dts=160768|dts_time=3.645533|duration=1024|duration_time=0.023220|size=198|pos=32065|flags=K_ +packet|codec_type=audio|stream_index=0|pts=161792|pts_time=3.668753|dts=161792|dts_time=3.668753|duration=1024|duration_time=0.023220|size=217|pos=32263|flags=K_ +packet|codec_type=audio|stream_index=0|pts=162816|pts_time=3.691973|dts=162816|dts_time=3.691973|duration=1024|duration_time=0.023220|size=195|pos=32480|flags=K_ +packet|codec_type=audio|stream_index=0|pts=163840|pts_time=3.715193|dts=163840|dts_time=3.715193|duration=1024|duration_time=0.023220|size=198|pos=32675|flags=K_ +packet|codec_type=audio|stream_index=0|pts=164864|pts_time=3.738413|dts=164864|dts_time=3.738413|duration=1024|duration_time=0.023220|size=202|pos=32873|flags=K_ +packet|codec_type=audio|stream_index=0|pts=165888|pts_time=3.761633|dts=165888|dts_time=3.761633|duration=1024|duration_time=0.023220|size=185|pos=33075|flags=K_ +packet|codec_type=audio|stream_index=0|pts=166912|pts_time=3.784853|dts=166912|dts_time=3.784853|duration=1024|duration_time=0.023220|size=196|pos=33260|flags=K_ +packet|codec_type=audio|stream_index=0|pts=167936|pts_time=3.808073|dts=167936|dts_time=3.808073|duration=1024|duration_time=0.023220|size=226|pos=33456|flags=K_ +packet|codec_type=audio|stream_index=0|pts=168960|pts_time=3.831293|dts=168960|dts_time=3.831293|duration=1024|duration_time=0.023220|size=187|pos=33682|flags=K_ +packet|codec_type=audio|stream_index=0|pts=169984|pts_time=3.854512|dts=169984|dts_time=3.854512|duration=1024|duration_time=0.023220|size=193|pos=33869|flags=K_ +packet|codec_type=audio|stream_index=0|pts=171008|pts_time=3.877732|dts=171008|dts_time=3.877732|duration=1024|duration_time=0.023220|size=218|pos=34062|flags=K_ +packet|codec_type=audio|stream_index=0|pts=172032|pts_time=3.900952|dts=172032|dts_time=3.900952|duration=1024|duration_time=0.023220|size=200|pos=34280|flags=K_ +packet|codec_type=audio|stream_index=0|pts=173056|pts_time=3.924172|dts=173056|dts_time=3.924172|duration=1024|duration_time=0.023220|size=200|pos=34480|flags=K_ +packet|codec_type=audio|stream_index=0|pts=174080|pts_time=3.947392|dts=174080|dts_time=3.947392|duration=1024|duration_time=0.023220|size=198|pos=34680|flags=K_ +packet|codec_type=audio|stream_index=0|pts=175104|pts_time=3.970612|dts=175104|dts_time=3.970612|duration=1024|duration_time=0.023220|size=200|pos=34878|flags=K_ +packet|codec_type=audio|stream_index=0|pts=176128|pts_time=3.993832|dts=176128|dts_time=3.993832|duration=1024|duration_time=0.023220|size=197|pos=35078|flags=K_ +packet|codec_type=audio|stream_index=0|pts=177152|pts_time=4.017052|dts=177152|dts_time=4.017052|duration=1024|duration_time=0.023220|size=209|pos=35275|flags=K_ +packet|codec_type=audio|stream_index=0|pts=178176|pts_time=4.040272|dts=178176|dts_time=4.040272|duration=1024|duration_time=0.023220|size=205|pos=35484|flags=K_ +packet|codec_type=audio|stream_index=0|pts=179200|pts_time=4.063492|dts=179200|dts_time=4.063492|duration=1024|duration_time=0.023220|size=199|pos=35689|flags=K_ +packet|codec_type=audio|stream_index=0|pts=180224|pts_time=4.086712|dts=180224|dts_time=4.086712|duration=1024|duration_time=0.023220|size=192|pos=35888|flags=K_ +packet|codec_type=audio|stream_index=0|pts=181248|pts_time=4.109932|dts=181248|dts_time=4.109932|duration=1024|duration_time=0.023220|size=201|pos=36080|flags=K_ +packet|codec_type=audio|stream_index=0|pts=182272|pts_time=4.133152|dts=182272|dts_time=4.133152|duration=1024|duration_time=0.023220|size=200|pos=36281|flags=K_ +packet|codec_type=audio|stream_index=0|pts=183296|pts_time=4.156372|dts=183296|dts_time=4.156372|duration=1024|duration_time=0.023220|size=202|pos=36481|flags=K_ +packet|codec_type=audio|stream_index=0|pts=184320|pts_time=4.179592|dts=184320|dts_time=4.179592|duration=1024|duration_time=0.023220|size=196|pos=36683|flags=K_ +packet|codec_type=audio|stream_index=0|pts=185344|pts_time=4.202812|dts=185344|dts_time=4.202812|duration=1024|duration_time=0.023220|size=200|pos=36879|flags=K_ +packet|codec_type=audio|stream_index=0|pts=186368|pts_time=4.226032|dts=186368|dts_time=4.226032|duration=1024|duration_time=0.023220|size=209|pos=37079|flags=K_ +packet|codec_type=audio|stream_index=0|pts=187392|pts_time=4.249252|dts=187392|dts_time=4.249252|duration=1024|duration_time=0.023220|size=201|pos=37288|flags=K_ +packet|codec_type=audio|stream_index=0|pts=188416|pts_time=4.272472|dts=188416|dts_time=4.272472|duration=1024|duration_time=0.023220|size=201|pos=37489|flags=K_ +packet|codec_type=audio|stream_index=0|pts=189440|pts_time=4.295692|dts=189440|dts_time=4.295692|duration=1024|duration_time=0.023220|size=201|pos=37690|flags=K_ +packet|codec_type=audio|stream_index=0|pts=190464|pts_time=4.318912|dts=190464|dts_time=4.318912|duration=1024|duration_time=0.023220|size=199|pos=37891|flags=K_ +packet|codec_type=audio|stream_index=0|pts=191488|pts_time=4.342132|dts=191488|dts_time=4.342132|duration=1024|duration_time=0.023220|size=198|pos=38090|flags=K_ +packet|codec_type=audio|stream_index=0|pts=192512|pts_time=4.365351|dts=192512|dts_time=4.365351|duration=1024|duration_time=0.023220|size=205|pos=38288|flags=K_ +packet|codec_type=audio|stream_index=0|pts=193536|pts_time=4.388571|dts=193536|dts_time=4.388571|duration=1024|duration_time=0.023220|size=190|pos=38493|flags=K_ +packet|codec_type=audio|stream_index=0|pts=194560|pts_time=4.411791|dts=194560|dts_time=4.411791|duration=1024|duration_time=0.023220|size=207|pos=38683|flags=K_ +packet|codec_type=audio|stream_index=0|pts=195584|pts_time=4.435011|dts=195584|dts_time=4.435011|duration=1024|duration_time=0.023220|size=204|pos=38890|flags=K_ +packet|codec_type=audio|stream_index=0|pts=196608|pts_time=4.458231|dts=196608|dts_time=4.458231|duration=1024|duration_time=0.023220|size=192|pos=39094|flags=K_ +packet|codec_type=audio|stream_index=0|pts=197632|pts_time=4.481451|dts=197632|dts_time=4.481451|duration=1024|duration_time=0.023220|size=211|pos=39286|flags=K_ +packet|codec_type=audio|stream_index=0|pts=198656|pts_time=4.504671|dts=198656|dts_time=4.504671|duration=1024|duration_time=0.023220|size=195|pos=39497|flags=K_ +packet|codec_type=audio|stream_index=0|pts=199680|pts_time=4.527891|dts=199680|dts_time=4.527891|duration=1024|duration_time=0.023220|size=214|pos=39692|flags=K_ +packet|codec_type=audio|stream_index=0|pts=200704|pts_time=4.551111|dts=200704|dts_time=4.551111|duration=1024|duration_time=0.023220|size=195|pos=39906|flags=K_ +packet|codec_type=audio|stream_index=0|pts=201728|pts_time=4.574331|dts=201728|dts_time=4.574331|duration=1024|duration_time=0.023220|size=199|pos=40101|flags=K_ +packet|codec_type=audio|stream_index=0|pts=202752|pts_time=4.597551|dts=202752|dts_time=4.597551|duration=1024|duration_time=0.023220|size=183|pos=40300|flags=K_ +packet|codec_type=audio|stream_index=0|pts=203776|pts_time=4.620771|dts=203776|dts_time=4.620771|duration=1024|duration_time=0.023220|size=211|pos=40483|flags=K_ +packet|codec_type=audio|stream_index=0|pts=204800|pts_time=4.643991|dts=204800|dts_time=4.643991|duration=1024|duration_time=0.023220|size=200|pos=40694|flags=K_ +packet|codec_type=audio|stream_index=0|pts=205824|pts_time=4.667211|dts=205824|dts_time=4.667211|duration=1024|duration_time=0.023220|size=199|pos=40894|flags=K_ +packet|codec_type=audio|stream_index=0|pts=206848|pts_time=4.690431|dts=206848|dts_time=4.690431|duration=1024|duration_time=0.023220|size=213|pos=41093|flags=K_ +packet|codec_type=audio|stream_index=0|pts=207872|pts_time=4.713651|dts=207872|dts_time=4.713651|duration=1024|duration_time=0.023220|size=191|pos=41306|flags=K_ +packet|codec_type=audio|stream_index=0|pts=208896|pts_time=4.736871|dts=208896|dts_time=4.736871|duration=1024|duration_time=0.023220|size=211|pos=41497|flags=K_ +packet|codec_type=audio|stream_index=0|pts=209920|pts_time=4.760091|dts=209920|dts_time=4.760091|duration=1024|duration_time=0.023220|size=198|pos=41708|flags=K_ +packet|codec_type=audio|stream_index=0|pts=210944|pts_time=4.783311|dts=210944|dts_time=4.783311|duration=1024|duration_time=0.023220|size=203|pos=41906|flags=K_ +packet|codec_type=audio|stream_index=0|pts=211968|pts_time=4.806531|dts=211968|dts_time=4.806531|duration=1024|duration_time=0.023220|size=196|pos=42109|flags=K_ +packet|codec_type=audio|stream_index=0|pts=212992|pts_time=4.829751|dts=212992|dts_time=4.829751|duration=1024|duration_time=0.023220|size=197|pos=42305|flags=K_ +packet|codec_type=audio|stream_index=0|pts=214016|pts_time=4.852971|dts=214016|dts_time=4.852971|duration=1024|duration_time=0.023220|size=190|pos=42502|flags=K_ +packet|codec_type=audio|stream_index=0|pts=215040|pts_time=4.876190|dts=215040|dts_time=4.876190|duration=1024|duration_time=0.023220|size=208|pos=42692|flags=K_ +packet|codec_type=audio|stream_index=0|pts=216064|pts_time=4.899410|dts=216064|dts_time=4.899410|duration=1024|duration_time=0.023220|size=203|pos=42900|flags=K_ +packet|codec_type=audio|stream_index=0|pts=217088|pts_time=4.922630|dts=217088|dts_time=4.922630|duration=1024|duration_time=0.023220|size=198|pos=43103|flags=K_ +packet|codec_type=audio|stream_index=0|pts=218112|pts_time=4.945850|dts=218112|dts_time=4.945850|duration=1024|duration_time=0.023220|size=284|pos=43301|flags=K_ +packet|codec_type=audio|stream_index=0|pts=219136|pts_time=4.969070|dts=219136|dts_time=4.969070|duration=1364|duration_time=0.030930|size=5|pos=43585|flags=K_ diff --git a/tests/ref/fate/mov-init-nonkeyframe b/tests/ref/fate/mov-init-nonkeyframe index 0e8184643..438f3973f 100644 --- a/tests/ref/fate/mov-init-nonkeyframe +++ b/tests/ref/fate/mov-init-nonkeyframe @@ -1,120 +1,120 @@ -packet|codec_type=video|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=599|pos=48|flags=__ -packet|codec_type=video|stream_index=0|pts=2002|pts_time=0.066733|dts=1001|dts_time=0.033367|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2944|pos=1674|flags=__ -packet|codec_type=video|stream_index=0|pts=7007|pts_time=0.233567|dts=2002|dts_time=0.066733|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=21987|pos=5335|flags=__ -packet|codec_type=video|stream_index=0|pts=5005|pts_time=0.166833|dts=3003|dts_time=0.100100|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4145|pos=28605|flags=__ -packet|codec_type=video|stream_index=0|pts=4004|pts_time=0.133467|dts=4004|dts_time=0.133467|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3093|pos=33425|flags=__ -packet|codec_type=video|stream_index=0|pts=6006|pts_time=0.200200|dts=5005|dts_time=0.166833|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=572|pos=37769|flags=__ -packet|codec_type=video|stream_index=0|pts=11011|pts_time=0.367033|dts=6006|dts_time=0.200200|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=21599|pos=38999|flags=__ -packet|codec_type=video|stream_index=0|pts=9009|pts_time=0.300300|dts=7007|dts_time=0.233567|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=6287|pos=61922|flags=__ -packet|codec_type=video|stream_index=0|pts=8008|pts_time=0.266933|dts=8008|dts_time=0.266933|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2720|pos=68909|flags=__ -packet|codec_type=video|stream_index=0|pts=10010|pts_time=0.333667|dts=9009|dts_time=0.300300|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2715|pos=72301|flags=__ -packet|codec_type=video|stream_index=0|pts=15015|pts_time=0.500500|dts=10010|dts_time=0.333667|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=20221|pos=76433|flags=__ -packet|codec_type=video|stream_index=0|pts=13013|pts_time=0.433767|dts=11011|dts_time=0.367033|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=9505|pos=97381|flags=__ -packet|codec_type=video|stream_index=0|pts=12012|pts_time=0.400400|dts=12012|dts_time=0.400400|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=522|pos=108391|flags=__ -packet|codec_type=video|stream_index=0|pts=14014|pts_time=0.467133|dts=13013|dts_time=0.433767|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2360|pos=109683|flags=__ -packet|codec_type=video|stream_index=0|pts=17017|pts_time=0.567233|dts=14014|dts_time=0.467133|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=22156|pos=113572|flags=__ -packet|codec_type=video|stream_index=0|pts=16016|pts_time=0.533867|dts=15015|dts_time=0.500500|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1801|pos=136496|flags=__ -packet|codec_type=video|stream_index=0|pts=21021|pts_time=0.700700|dts=16016|dts_time=0.533867|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=20181|pos=139074|flags=__ -packet|codec_type=video|stream_index=0|pts=19019|pts_time=0.633967|dts=17017|dts_time=0.567233|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3608|pos=160959|flags=__ -packet|codec_type=video|stream_index=0|pts=18018|pts_time=0.600600|dts=18018|dts_time=0.600600|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=368|pos=165305|flags=__ -packet|codec_type=video|stream_index=0|pts=20020|pts_time=0.667333|dts=19019|dts_time=0.633967|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2989|pos=167054|flags=__ -packet|codec_type=video|stream_index=0|pts=25025|pts_time=0.834167|dts=20020|dts_time=0.667333|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=24475|pos=170801|flags=__ -packet|codec_type=video|stream_index=0|pts=23023|pts_time=0.767433|dts=21021|dts_time=0.700700|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=10682|pos=196732|flags=__ -packet|codec_type=video|stream_index=0|pts=22022|pts_time=0.734067|dts=22022|dts_time=0.734067|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3198|pos=208151|flags=__ -packet|codec_type=video|stream_index=0|pts=24024|pts_time=0.800800|dts=23023|dts_time=0.767433|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=479|pos=212958|flags=__ -packet|codec_type=video|stream_index=0|pts=29029|pts_time=0.967633|dts=24024|dts_time=0.800800|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=21240|pos=214384|flags=__ -packet|codec_type=video|stream_index=0|pts=27027|pts_time=0.900900|dts=25025|dts_time=0.834167|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4409|pos=236946|flags=__ -packet|codec_type=video|stream_index=0|pts=26026|pts_time=0.867533|dts=26026|dts_time=0.867533|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3106|pos=242647|flags=__ -packet|codec_type=video|stream_index=0|pts=28028|pts_time=0.934267|dts=27027|dts_time=0.900900|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=453|pos=246428|flags=__ -packet|codec_type=video|stream_index=0|pts=33033|pts_time=1.101100|dts=28028|dts_time=0.934267|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=20668|pos=248308|flags=__ -packet|codec_type=video|stream_index=0|pts=31031|pts_time=1.034367|dts=29029|dts_time=0.967633|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=6668|pos=269708|flags=__ -packet|codec_type=video|stream_index=0|pts=30030|pts_time=1.001000|dts=30030|dts_time=1.001000|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3027|pos=277789|flags=__ -packet|codec_type=video|stream_index=0|pts=32032|pts_time=1.067733|dts=31031|dts_time=1.034367|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2884|pos=281613|flags=__ -packet|codec_type=video|stream_index=0|pts=37037|pts_time=1.234567|dts=32032|dts_time=1.067733|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=21313|pos=285261|flags=__ -packet|codec_type=video|stream_index=0|pts=35035|pts_time=1.167833|dts=33033|dts_time=1.101100|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=9890|pos=308303|flags=__ -packet|codec_type=video|stream_index=0|pts=34034|pts_time=1.134467|dts=34034|dts_time=1.134467|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=501|pos=318919|flags=__ -packet|codec_type=video|stream_index=0|pts=36036|pts_time=1.201200|dts=35035|dts_time=1.167833|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3123|pos=320824|flags=__ -packet|codec_type=video|stream_index=0|pts=39039|pts_time=1.301300|dts=36036|dts_time=1.201200|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=21768|pos=324664|flags=__ -packet|codec_type=video|stream_index=0|pts=38038|pts_time=1.267933|dts=37037|dts_time=1.234567|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2664|pos=347922|flags=__ -packet|codec_type=video|stream_index=0|pts=43043|pts_time=1.434767|dts=38038|dts_time=1.267933|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=19144|pos=351354|flags=__ -packet|codec_type=video|stream_index=0|pts=41041|pts_time=1.368033|dts=39039|dts_time=1.301300|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4118|pos=371991|flags=__ -packet|codec_type=video|stream_index=0|pts=40040|pts_time=1.334667|dts=40040|dts_time=1.334667|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=423|pos=376899|flags=__ -packet|codec_type=video|stream_index=0|pts=42042|pts_time=1.401400|dts=41041|dts_time=1.368033|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2785|pos=378037|flags=__ -packet|codec_type=video|stream_index=0|pts=45045|pts_time=1.501500|dts=42042|dts_time=1.401400|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=24489|pos=382144|flags=__ -packet|codec_type=video|stream_index=0|pts=44044|pts_time=1.468133|dts=43043|dts_time=1.434767|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2984|pos=407344|flags=__ -packet|codec_type=video|stream_index=0|pts=49049|pts_time=1.634967|dts=44044|dts_time=1.468133|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=19174|pos=411791|flags=__ -packet|codec_type=video|stream_index=0|pts=47047|pts_time=1.568233|dts=45045|dts_time=1.501500|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4905|pos=431740|flags=__ -packet|codec_type=video|stream_index=0|pts=46046|pts_time=1.534867|dts=46046|dts_time=1.534867|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=412|pos=438183|flags=__ -packet|codec_type=video|stream_index=0|pts=48048|pts_time=1.601600|dts=47047|dts_time=1.568233|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3215|pos=439373|flags=__ -packet|codec_type=video|stream_index=0|pts=51051|pts_time=1.701700|dts=48048|dts_time=1.601600|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=21572|pos=443371|flags=__ -packet|codec_type=video|stream_index=0|pts=50050|pts_time=1.668333|dts=49049|dts_time=1.634967|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2644|pos=466486|flags=__ -packet|codec_type=video|stream_index=0|pts=55055|pts_time=1.835167|dts=50050|dts_time=1.668333|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=19417|pos=470462|flags=__ -packet|codec_type=video|stream_index=0|pts=53053|pts_time=1.768433|dts=51051|dts_time=1.701700|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3685|pos=491335|flags=__ -packet|codec_type=video|stream_index=0|pts=52052|pts_time=1.735067|dts=52052|dts_time=1.735067|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=355|pos=495771|flags=__ -packet|codec_type=video|stream_index=0|pts=54054|pts_time=1.801800|dts=53053|dts_time=1.768433|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3021|pos=497714|flags=__ -packet|codec_type=video|stream_index=0|pts=59059|pts_time=1.968633|dts=54054|dts_time=1.801800|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=21464|pos=501431|flags=__ -packet|codec_type=video|stream_index=0|pts=57057|pts_time=1.901900|dts=55055|dts_time=1.835167|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=9340|pos=524392|flags=__ -packet|codec_type=video|stream_index=0|pts=56056|pts_time=1.868533|dts=56056|dts_time=1.868533|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=406|pos=534504|flags=__ -packet|codec_type=video|stream_index=0|pts=58058|pts_time=1.935267|dts=57057|dts_time=1.901900|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3277|pos=535694|flags=__ -packet|codec_type=video|stream_index=0|pts=63063|pts_time=2.102100|dts=58058|dts_time=1.935267|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=21388|pos=541090|flags=__ -packet|codec_type=video|stream_index=0|pts=61061|pts_time=2.035367|dts=59059|dts_time=1.968633|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4466|pos=563132|flags=__ -packet|codec_type=video|stream_index=0|pts=60060|pts_time=2.002000|dts=60060|dts_time=2.002000|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3467|pos=569245|flags=__ -packet|codec_type=video|stream_index=0|pts=62062|pts_time=2.068733|dts=61061|dts_time=2.035367|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=499|pos=573478|flags=__ -packet|codec_type=video|stream_index=0|pts=67067|pts_time=2.235567|dts=62062|dts_time=2.068733|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=25972|pos=575469|flags=__ -packet|codec_type=video|stream_index=0|pts=65065|pts_time=2.168833|dts=63063|dts_time=2.102100|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=6643|pos=602163|flags=__ -packet|codec_type=video|stream_index=0|pts=64064|pts_time=2.135467|dts=64064|dts_time=2.135467|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3069|pos=609558|flags=__ -packet|codec_type=video|stream_index=0|pts=66066|pts_time=2.202200|dts=65065|dts_time=2.168833|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3049|pos=614133|flags=__ -packet|codec_type=video|stream_index=0|pts=68068|pts_time=2.268933|dts=66066|dts_time=2.202200|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4559|pos=618551|flags=__ -packet|codec_type=video|stream_index=0|pts=72072|pts_time=2.402400|dts=67067|dts_time=2.235567|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=21251|pos=624621|flags=__ -packet|codec_type=video|stream_index=0|pts=70070|pts_time=2.335667|dts=68068|dts_time=2.268933|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=7108|pos=646657|flags=__ -packet|codec_type=video|stream_index=0|pts=69069|pts_time=2.302300|dts=69069|dts_time=2.302300|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3250|pos=655299|flags=__ -packet|codec_type=video|stream_index=0|pts=71071|pts_time=2.369033|dts=70070|dts_time=2.335667|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3365|pos=659310|flags=__ -packet|codec_type=video|stream_index=0|pts=73073|pts_time=2.435767|dts=71071|dts_time=2.369033|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=24803|pos=664201|flags=__ -packet|codec_type=video|stream_index=0|pts=77077|pts_time=2.569233|dts=72072|dts_time=2.402400|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=22185|pos=689763|flags=__ -packet|codec_type=video|stream_index=0|pts=75075|pts_time=2.502500|dts=73073|dts_time=2.435767|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=5088|pos=712679|flags=__ -packet|codec_type=video|stream_index=0|pts=74074|pts_time=2.469133|dts=74074|dts_time=2.469133|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=537|pos=719128|flags=__ -packet|codec_type=video|stream_index=0|pts=76076|pts_time=2.535867|dts=75075|dts_time=2.502500|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3765|pos=720413|flags=__ -packet|codec_type=video|stream_index=0|pts=81081|pts_time=2.702700|dts=76076|dts_time=2.535867|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=20654|pos=725583|flags=__ -packet|codec_type=video|stream_index=0|pts=79079|pts_time=2.635967|dts=77077|dts_time=2.569233|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=10202|pos=746999|flags=__ -packet|codec_type=video|stream_index=0|pts=78078|pts_time=2.602600|dts=78078|dts_time=2.602600|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3970|pos=758705|flags=__ -packet|codec_type=video|stream_index=0|pts=80080|pts_time=2.669333|dts=79079|dts_time=2.635967|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=421|pos=763442|flags=__ -packet|codec_type=video|stream_index=0|pts=84084|pts_time=2.802800|dts=80080|dts_time=2.669333|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=25685|pos=764653|flags=__ -packet|codec_type=video|stream_index=0|pts=82082|pts_time=2.736067|dts=81081|dts_time=2.702700|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4077|pos=791911|flags=__ -packet|codec_type=video|stream_index=0|pts=83083|pts_time=2.769433|dts=82082|dts_time=2.736067|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3049|pos=796780|flags=__ -packet|codec_type=video|stream_index=0|pts=88088|pts_time=2.936267|dts=83083|dts_time=2.769433|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=8924|pos=801473|flags=__ -packet|codec_type=video|stream_index=0|pts=86086|pts_time=2.869533|dts=84084|dts_time=2.802800|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2512|pos=811078|flags=__ -packet|codec_type=video|stream_index=0|pts=85085|pts_time=2.836167|dts=85085|dts_time=2.836167|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=163|pos=815033|flags=__ -packet|codec_type=video|stream_index=0|pts=87087|pts_time=2.902900|dts=86086|dts_time=2.869533|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1734|pos=815934|flags=__ -packet|codec_type=video|stream_index=0|pts=90090|pts_time=3.003000|dts=87087|dts_time=2.902900|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=11505|pos=819088|flags=__ -packet|codec_type=video|stream_index=0|pts=89089|pts_time=2.969633|dts=88088|dts_time=2.936267|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1431|pos=831367|flags=__ -packet|codec_type=video|stream_index=0|pts=92092|pts_time=3.069733|dts=89089|dts_time=2.969633|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=5269|pos=833580|flags=__ -packet|codec_type=video|stream_index=0|pts=91091|pts_time=3.036367|dts=90090|dts_time=3.003000|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=199|pos=840352|flags=__ -packet|codec_type=video|stream_index=0|pts=93093|pts_time=3.103100|dts=91091|dts_time=3.036367|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=85650|pos=841722|flags=K_ -packet|codec_type=video|stream_index=0|pts=95095|pts_time=3.169833|dts=92092|dts_time=3.069733|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=13261|pos=928747|flags=__ -packet|codec_type=video|stream_index=0|pts=94094|pts_time=3.136467|dts=93093|dts_time=3.103100|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1667|pos=942741|flags=__ -packet|codec_type=video|stream_index=0|pts=99099|pts_time=3.303300|dts=94094|dts_time=3.136467|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=20143|pos=945841|flags=__ -packet|codec_type=video|stream_index=0|pts=97097|pts_time=3.236567|dts=95095|dts_time=3.169833|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2484|pos=966681|flags=__ -packet|codec_type=video|stream_index=0|pts=96096|pts_time=3.203200|dts=96096|dts_time=3.203200|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=278|pos=969887|flags=__ -packet|codec_type=video|stream_index=0|pts=98098|pts_time=3.269933|dts=97097|dts_time=3.236567|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1539|pos=971696|flags=__ -packet|codec_type=video|stream_index=0|pts=101101|pts_time=3.370033|dts=98098|dts_time=3.269933|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=20270|pos=974088|flags=__ -packet|codec_type=video|stream_index=0|pts=100100|pts_time=3.336667|dts=99099|dts_time=3.303300|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1754|pos=995975|flags=__ -packet|codec_type=video|stream_index=0|pts=105105|pts_time=3.503500|dts=100100|dts_time=3.336667|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=19154|pos=998420|flags=__ -packet|codec_type=video|stream_index=0|pts=103103|pts_time=3.436767|dts=101101|dts_time=3.370033|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3359|pos=1019010|flags=__ -packet|codec_type=video|stream_index=0|pts=102102|pts_time=3.403400|dts=102102|dts_time=3.403400|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=287|pos=1023138|flags=__ -packet|codec_type=video|stream_index=0|pts=104104|pts_time=3.470133|dts=103103|dts_time=3.436767|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2111|pos=1024928|flags=__ -packet|codec_type=video|stream_index=0|pts=109109|pts_time=3.636967|dts=104104|dts_time=3.470133|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=17178|pos=1027833|flags=__ -packet|codec_type=video|stream_index=0|pts=107107|pts_time=3.570233|dts=105105|dts_time=3.503500|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=7205|pos=1045716|flags=__ -packet|codec_type=video|stream_index=0|pts=106106|pts_time=3.536867|dts=106106|dts_time=3.536867|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2209|pos=1054354|flags=__ -packet|codec_type=video|stream_index=0|pts=108108|pts_time=3.603600|dts=107107|dts_time=3.570233|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=359|pos=1057226|flags=__ -packet|codec_type=video|stream_index=0|pts=113113|pts_time=3.770433|dts=108108|dts_time=3.603600|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=18469|pos=1059024|flags=__ -packet|codec_type=video|stream_index=0|pts=111111|pts_time=3.703700|dts=109109|dts_time=3.636967|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3314|pos=1078213|flags=__ -packet|codec_type=video|stream_index=0|pts=110110|pts_time=3.670333|dts=110110|dts_time=3.670333|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2556|pos=1083059|flags=__ -packet|codec_type=video|stream_index=0|pts=112112|pts_time=3.737067|dts=111111|dts_time=3.703700|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=437|pos=1086388|flags=__ -packet|codec_type=video|stream_index=0|pts=117117|pts_time=3.903900|dts=112112|dts_time=3.737067|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=19707|pos=1087610|flags=__ -packet|codec_type=video|stream_index=0|pts=115115|pts_time=3.837167|dts=113113|dts_time=3.770433|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=5917|pos=1108845|flags=__ -packet|codec_type=video|stream_index=0|pts=114114|pts_time=3.803800|dts=114114|dts_time=3.803800|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2613|pos=1115495|flags=__ -packet|codec_type=video|stream_index=0|pts=116116|pts_time=3.870533|dts=115115|dts_time=3.837167|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2672|pos=1119530|flags=__ -packet|codec_type=video|stream_index=0|pts=121121|pts_time=4.037367|dts=116116|dts_time=3.870533|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=19091|pos=1122970|flags=_D -packet|codec_type=video|stream_index=0|pts=119119|pts_time=3.970633|dts=117117|dts_time=3.903900|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=9244|pos=1143585|flags=__ -packet|codec_type=video|stream_index=0|pts=118118|pts_time=3.937267|dts=118118|dts_time=3.937267|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=284|pos=1153587|flags=__ -packet|codec_type=video|stream_index=0|pts=120120|pts_time=4.004000|dts=119119|dts_time=3.970633|duration=1001|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2381|pos=1155393|flags=_D +packet|codec_type=video|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1001|duration_time=0.033367|size=599|pos=48|flags=__ +packet|codec_type=video|stream_index=0|pts=2002|pts_time=0.066733|dts=1001|dts_time=0.033367|duration=1001|duration_time=0.033367|size=2944|pos=1674|flags=__ +packet|codec_type=video|stream_index=0|pts=7007|pts_time=0.233567|dts=2002|dts_time=0.066733|duration=1001|duration_time=0.033367|size=21987|pos=5335|flags=__ +packet|codec_type=video|stream_index=0|pts=5005|pts_time=0.166833|dts=3003|dts_time=0.100100|duration=1001|duration_time=0.033367|size=4145|pos=28605|flags=__ +packet|codec_type=video|stream_index=0|pts=4004|pts_time=0.133467|dts=4004|dts_time=0.133467|duration=1001|duration_time=0.033367|size=3093|pos=33425|flags=__ +packet|codec_type=video|stream_index=0|pts=6006|pts_time=0.200200|dts=5005|dts_time=0.166833|duration=1001|duration_time=0.033367|size=572|pos=37769|flags=__ +packet|codec_type=video|stream_index=0|pts=11011|pts_time=0.367033|dts=6006|dts_time=0.200200|duration=1001|duration_time=0.033367|size=21599|pos=38999|flags=__ +packet|codec_type=video|stream_index=0|pts=9009|pts_time=0.300300|dts=7007|dts_time=0.233567|duration=1001|duration_time=0.033367|size=6287|pos=61922|flags=__ +packet|codec_type=video|stream_index=0|pts=8008|pts_time=0.266933|dts=8008|dts_time=0.266933|duration=1001|duration_time=0.033367|size=2720|pos=68909|flags=__ +packet|codec_type=video|stream_index=0|pts=10010|pts_time=0.333667|dts=9009|dts_time=0.300300|duration=1001|duration_time=0.033367|size=2715|pos=72301|flags=__ +packet|codec_type=video|stream_index=0|pts=15015|pts_time=0.500500|dts=10010|dts_time=0.333667|duration=1001|duration_time=0.033367|size=20221|pos=76433|flags=__ +packet|codec_type=video|stream_index=0|pts=13013|pts_time=0.433767|dts=11011|dts_time=0.367033|duration=1001|duration_time=0.033367|size=9505|pos=97381|flags=__ +packet|codec_type=video|stream_index=0|pts=12012|pts_time=0.400400|dts=12012|dts_time=0.400400|duration=1001|duration_time=0.033367|size=522|pos=108391|flags=__ +packet|codec_type=video|stream_index=0|pts=14014|pts_time=0.467133|dts=13013|dts_time=0.433767|duration=1001|duration_time=0.033367|size=2360|pos=109683|flags=__ +packet|codec_type=video|stream_index=0|pts=17017|pts_time=0.567233|dts=14014|dts_time=0.467133|duration=1001|duration_time=0.033367|size=22156|pos=113572|flags=__ +packet|codec_type=video|stream_index=0|pts=16016|pts_time=0.533867|dts=15015|dts_time=0.500500|duration=1001|duration_time=0.033367|size=1801|pos=136496|flags=__ +packet|codec_type=video|stream_index=0|pts=21021|pts_time=0.700700|dts=16016|dts_time=0.533867|duration=1001|duration_time=0.033367|size=20181|pos=139074|flags=__ +packet|codec_type=video|stream_index=0|pts=19019|pts_time=0.633967|dts=17017|dts_time=0.567233|duration=1001|duration_time=0.033367|size=3608|pos=160959|flags=__ +packet|codec_type=video|stream_index=0|pts=18018|pts_time=0.600600|dts=18018|dts_time=0.600600|duration=1001|duration_time=0.033367|size=368|pos=165305|flags=__ +packet|codec_type=video|stream_index=0|pts=20020|pts_time=0.667333|dts=19019|dts_time=0.633967|duration=1001|duration_time=0.033367|size=2989|pos=167054|flags=__ +packet|codec_type=video|stream_index=0|pts=25025|pts_time=0.834167|dts=20020|dts_time=0.667333|duration=1001|duration_time=0.033367|size=24475|pos=170801|flags=__ +packet|codec_type=video|stream_index=0|pts=23023|pts_time=0.767433|dts=21021|dts_time=0.700700|duration=1001|duration_time=0.033367|size=10682|pos=196732|flags=__ +packet|codec_type=video|stream_index=0|pts=22022|pts_time=0.734067|dts=22022|dts_time=0.734067|duration=1001|duration_time=0.033367|size=3198|pos=208151|flags=__ +packet|codec_type=video|stream_index=0|pts=24024|pts_time=0.800800|dts=23023|dts_time=0.767433|duration=1001|duration_time=0.033367|size=479|pos=212958|flags=__ +packet|codec_type=video|stream_index=0|pts=29029|pts_time=0.967633|dts=24024|dts_time=0.800800|duration=1001|duration_time=0.033367|size=21240|pos=214384|flags=__ +packet|codec_type=video|stream_index=0|pts=27027|pts_time=0.900900|dts=25025|dts_time=0.834167|duration=1001|duration_time=0.033367|size=4409|pos=236946|flags=__ +packet|codec_type=video|stream_index=0|pts=26026|pts_time=0.867533|dts=26026|dts_time=0.867533|duration=1001|duration_time=0.033367|size=3106|pos=242647|flags=__ +packet|codec_type=video|stream_index=0|pts=28028|pts_time=0.934267|dts=27027|dts_time=0.900900|duration=1001|duration_time=0.033367|size=453|pos=246428|flags=__ +packet|codec_type=video|stream_index=0|pts=33033|pts_time=1.101100|dts=28028|dts_time=0.934267|duration=1001|duration_time=0.033367|size=20668|pos=248308|flags=__ +packet|codec_type=video|stream_index=0|pts=31031|pts_time=1.034367|dts=29029|dts_time=0.967633|duration=1001|duration_time=0.033367|size=6668|pos=269708|flags=__ +packet|codec_type=video|stream_index=0|pts=30030|pts_time=1.001000|dts=30030|dts_time=1.001000|duration=1001|duration_time=0.033367|size=3027|pos=277789|flags=__ +packet|codec_type=video|stream_index=0|pts=32032|pts_time=1.067733|dts=31031|dts_time=1.034367|duration=1001|duration_time=0.033367|size=2884|pos=281613|flags=__ +packet|codec_type=video|stream_index=0|pts=37037|pts_time=1.234567|dts=32032|dts_time=1.067733|duration=1001|duration_time=0.033367|size=21313|pos=285261|flags=__ +packet|codec_type=video|stream_index=0|pts=35035|pts_time=1.167833|dts=33033|dts_time=1.101100|duration=1001|duration_time=0.033367|size=9890|pos=308303|flags=__ +packet|codec_type=video|stream_index=0|pts=34034|pts_time=1.134467|dts=34034|dts_time=1.134467|duration=1001|duration_time=0.033367|size=501|pos=318919|flags=__ +packet|codec_type=video|stream_index=0|pts=36036|pts_time=1.201200|dts=35035|dts_time=1.167833|duration=1001|duration_time=0.033367|size=3123|pos=320824|flags=__ +packet|codec_type=video|stream_index=0|pts=39039|pts_time=1.301300|dts=36036|dts_time=1.201200|duration=1001|duration_time=0.033367|size=21768|pos=324664|flags=__ +packet|codec_type=video|stream_index=0|pts=38038|pts_time=1.267933|dts=37037|dts_time=1.234567|duration=1001|duration_time=0.033367|size=2664|pos=347922|flags=__ +packet|codec_type=video|stream_index=0|pts=43043|pts_time=1.434767|dts=38038|dts_time=1.267933|duration=1001|duration_time=0.033367|size=19144|pos=351354|flags=__ +packet|codec_type=video|stream_index=0|pts=41041|pts_time=1.368033|dts=39039|dts_time=1.301300|duration=1001|duration_time=0.033367|size=4118|pos=371991|flags=__ +packet|codec_type=video|stream_index=0|pts=40040|pts_time=1.334667|dts=40040|dts_time=1.334667|duration=1001|duration_time=0.033367|size=423|pos=376899|flags=__ +packet|codec_type=video|stream_index=0|pts=42042|pts_time=1.401400|dts=41041|dts_time=1.368033|duration=1001|duration_time=0.033367|size=2785|pos=378037|flags=__ +packet|codec_type=video|stream_index=0|pts=45045|pts_time=1.501500|dts=42042|dts_time=1.401400|duration=1001|duration_time=0.033367|size=24489|pos=382144|flags=__ +packet|codec_type=video|stream_index=0|pts=44044|pts_time=1.468133|dts=43043|dts_time=1.434767|duration=1001|duration_time=0.033367|size=2984|pos=407344|flags=__ +packet|codec_type=video|stream_index=0|pts=49049|pts_time=1.634967|dts=44044|dts_time=1.468133|duration=1001|duration_time=0.033367|size=19174|pos=411791|flags=__ +packet|codec_type=video|stream_index=0|pts=47047|pts_time=1.568233|dts=45045|dts_time=1.501500|duration=1001|duration_time=0.033367|size=4905|pos=431740|flags=__ +packet|codec_type=video|stream_index=0|pts=46046|pts_time=1.534867|dts=46046|dts_time=1.534867|duration=1001|duration_time=0.033367|size=412|pos=438183|flags=__ +packet|codec_type=video|stream_index=0|pts=48048|pts_time=1.601600|dts=47047|dts_time=1.568233|duration=1001|duration_time=0.033367|size=3215|pos=439373|flags=__ +packet|codec_type=video|stream_index=0|pts=51051|pts_time=1.701700|dts=48048|dts_time=1.601600|duration=1001|duration_time=0.033367|size=21572|pos=443371|flags=__ +packet|codec_type=video|stream_index=0|pts=50050|pts_time=1.668333|dts=49049|dts_time=1.634967|duration=1001|duration_time=0.033367|size=2644|pos=466486|flags=__ +packet|codec_type=video|stream_index=0|pts=55055|pts_time=1.835167|dts=50050|dts_time=1.668333|duration=1001|duration_time=0.033367|size=19417|pos=470462|flags=__ +packet|codec_type=video|stream_index=0|pts=53053|pts_time=1.768433|dts=51051|dts_time=1.701700|duration=1001|duration_time=0.033367|size=3685|pos=491335|flags=__ +packet|codec_type=video|stream_index=0|pts=52052|pts_time=1.735067|dts=52052|dts_time=1.735067|duration=1001|duration_time=0.033367|size=355|pos=495771|flags=__ +packet|codec_type=video|stream_index=0|pts=54054|pts_time=1.801800|dts=53053|dts_time=1.768433|duration=1001|duration_time=0.033367|size=3021|pos=497714|flags=__ +packet|codec_type=video|stream_index=0|pts=59059|pts_time=1.968633|dts=54054|dts_time=1.801800|duration=1001|duration_time=0.033367|size=21464|pos=501431|flags=__ +packet|codec_type=video|stream_index=0|pts=57057|pts_time=1.901900|dts=55055|dts_time=1.835167|duration=1001|duration_time=0.033367|size=9340|pos=524392|flags=__ +packet|codec_type=video|stream_index=0|pts=56056|pts_time=1.868533|dts=56056|dts_time=1.868533|duration=1001|duration_time=0.033367|size=406|pos=534504|flags=__ +packet|codec_type=video|stream_index=0|pts=58058|pts_time=1.935267|dts=57057|dts_time=1.901900|duration=1001|duration_time=0.033367|size=3277|pos=535694|flags=__ +packet|codec_type=video|stream_index=0|pts=63063|pts_time=2.102100|dts=58058|dts_time=1.935267|duration=1001|duration_time=0.033367|size=21388|pos=541090|flags=__ +packet|codec_type=video|stream_index=0|pts=61061|pts_time=2.035367|dts=59059|dts_time=1.968633|duration=1001|duration_time=0.033367|size=4466|pos=563132|flags=__ +packet|codec_type=video|stream_index=0|pts=60060|pts_time=2.002000|dts=60060|dts_time=2.002000|duration=1001|duration_time=0.033367|size=3467|pos=569245|flags=__ +packet|codec_type=video|stream_index=0|pts=62062|pts_time=2.068733|dts=61061|dts_time=2.035367|duration=1001|duration_time=0.033367|size=499|pos=573478|flags=__ +packet|codec_type=video|stream_index=0|pts=67067|pts_time=2.235567|dts=62062|dts_time=2.068733|duration=1001|duration_time=0.033367|size=25972|pos=575469|flags=__ +packet|codec_type=video|stream_index=0|pts=65065|pts_time=2.168833|dts=63063|dts_time=2.102100|duration=1001|duration_time=0.033367|size=6643|pos=602163|flags=__ +packet|codec_type=video|stream_index=0|pts=64064|pts_time=2.135467|dts=64064|dts_time=2.135467|duration=1001|duration_time=0.033367|size=3069|pos=609558|flags=__ +packet|codec_type=video|stream_index=0|pts=66066|pts_time=2.202200|dts=65065|dts_time=2.168833|duration=1001|duration_time=0.033367|size=3049|pos=614133|flags=__ +packet|codec_type=video|stream_index=0|pts=68068|pts_time=2.268933|dts=66066|dts_time=2.202200|duration=1001|duration_time=0.033367|size=4559|pos=618551|flags=__ +packet|codec_type=video|stream_index=0|pts=72072|pts_time=2.402400|dts=67067|dts_time=2.235567|duration=1001|duration_time=0.033367|size=21251|pos=624621|flags=__ +packet|codec_type=video|stream_index=0|pts=70070|pts_time=2.335667|dts=68068|dts_time=2.268933|duration=1001|duration_time=0.033367|size=7108|pos=646657|flags=__ +packet|codec_type=video|stream_index=0|pts=69069|pts_time=2.302300|dts=69069|dts_time=2.302300|duration=1001|duration_time=0.033367|size=3250|pos=655299|flags=__ +packet|codec_type=video|stream_index=0|pts=71071|pts_time=2.369033|dts=70070|dts_time=2.335667|duration=1001|duration_time=0.033367|size=3365|pos=659310|flags=__ +packet|codec_type=video|stream_index=0|pts=73073|pts_time=2.435767|dts=71071|dts_time=2.369033|duration=1001|duration_time=0.033367|size=24803|pos=664201|flags=__ +packet|codec_type=video|stream_index=0|pts=77077|pts_time=2.569233|dts=72072|dts_time=2.402400|duration=1001|duration_time=0.033367|size=22185|pos=689763|flags=__ +packet|codec_type=video|stream_index=0|pts=75075|pts_time=2.502500|dts=73073|dts_time=2.435767|duration=1001|duration_time=0.033367|size=5088|pos=712679|flags=__ +packet|codec_type=video|stream_index=0|pts=74074|pts_time=2.469133|dts=74074|dts_time=2.469133|duration=1001|duration_time=0.033367|size=537|pos=719128|flags=__ +packet|codec_type=video|stream_index=0|pts=76076|pts_time=2.535867|dts=75075|dts_time=2.502500|duration=1001|duration_time=0.033367|size=3765|pos=720413|flags=__ +packet|codec_type=video|stream_index=0|pts=81081|pts_time=2.702700|dts=76076|dts_time=2.535867|duration=1001|duration_time=0.033367|size=20654|pos=725583|flags=__ +packet|codec_type=video|stream_index=0|pts=79079|pts_time=2.635967|dts=77077|dts_time=2.569233|duration=1001|duration_time=0.033367|size=10202|pos=746999|flags=__ +packet|codec_type=video|stream_index=0|pts=78078|pts_time=2.602600|dts=78078|dts_time=2.602600|duration=1001|duration_time=0.033367|size=3970|pos=758705|flags=__ +packet|codec_type=video|stream_index=0|pts=80080|pts_time=2.669333|dts=79079|dts_time=2.635967|duration=1001|duration_time=0.033367|size=421|pos=763442|flags=__ +packet|codec_type=video|stream_index=0|pts=84084|pts_time=2.802800|dts=80080|dts_time=2.669333|duration=1001|duration_time=0.033367|size=25685|pos=764653|flags=__ +packet|codec_type=video|stream_index=0|pts=82082|pts_time=2.736067|dts=81081|dts_time=2.702700|duration=1001|duration_time=0.033367|size=4077|pos=791911|flags=__ +packet|codec_type=video|stream_index=0|pts=83083|pts_time=2.769433|dts=82082|dts_time=2.736067|duration=1001|duration_time=0.033367|size=3049|pos=796780|flags=__ +packet|codec_type=video|stream_index=0|pts=88088|pts_time=2.936267|dts=83083|dts_time=2.769433|duration=1001|duration_time=0.033367|size=8924|pos=801473|flags=__ +packet|codec_type=video|stream_index=0|pts=86086|pts_time=2.869533|dts=84084|dts_time=2.802800|duration=1001|duration_time=0.033367|size=2512|pos=811078|flags=__ +packet|codec_type=video|stream_index=0|pts=85085|pts_time=2.836167|dts=85085|dts_time=2.836167|duration=1001|duration_time=0.033367|size=163|pos=815033|flags=__ +packet|codec_type=video|stream_index=0|pts=87087|pts_time=2.902900|dts=86086|dts_time=2.869533|duration=1001|duration_time=0.033367|size=1734|pos=815934|flags=__ +packet|codec_type=video|stream_index=0|pts=90090|pts_time=3.003000|dts=87087|dts_time=2.902900|duration=1001|duration_time=0.033367|size=11505|pos=819088|flags=__ +packet|codec_type=video|stream_index=0|pts=89089|pts_time=2.969633|dts=88088|dts_time=2.936267|duration=1001|duration_time=0.033367|size=1431|pos=831367|flags=__ +packet|codec_type=video|stream_index=0|pts=92092|pts_time=3.069733|dts=89089|dts_time=2.969633|duration=1001|duration_time=0.033367|size=5269|pos=833580|flags=__ +packet|codec_type=video|stream_index=0|pts=91091|pts_time=3.036367|dts=90090|dts_time=3.003000|duration=1001|duration_time=0.033367|size=199|pos=840352|flags=__ +packet|codec_type=video|stream_index=0|pts=93093|pts_time=3.103100|dts=91091|dts_time=3.036367|duration=1001|duration_time=0.033367|size=85650|pos=841722|flags=K_ +packet|codec_type=video|stream_index=0|pts=95095|pts_time=3.169833|dts=92092|dts_time=3.069733|duration=1001|duration_time=0.033367|size=13261|pos=928747|flags=__ +packet|codec_type=video|stream_index=0|pts=94094|pts_time=3.136467|dts=93093|dts_time=3.103100|duration=1001|duration_time=0.033367|size=1667|pos=942741|flags=__ +packet|codec_type=video|stream_index=0|pts=99099|pts_time=3.303300|dts=94094|dts_time=3.136467|duration=1001|duration_time=0.033367|size=20143|pos=945841|flags=__ +packet|codec_type=video|stream_index=0|pts=97097|pts_time=3.236567|dts=95095|dts_time=3.169833|duration=1001|duration_time=0.033367|size=2484|pos=966681|flags=__ +packet|codec_type=video|stream_index=0|pts=96096|pts_time=3.203200|dts=96096|dts_time=3.203200|duration=1001|duration_time=0.033367|size=278|pos=969887|flags=__ +packet|codec_type=video|stream_index=0|pts=98098|pts_time=3.269933|dts=97097|dts_time=3.236567|duration=1001|duration_time=0.033367|size=1539|pos=971696|flags=__ +packet|codec_type=video|stream_index=0|pts=101101|pts_time=3.370033|dts=98098|dts_time=3.269933|duration=1001|duration_time=0.033367|size=20270|pos=974088|flags=__ +packet|codec_type=video|stream_index=0|pts=100100|pts_time=3.336667|dts=99099|dts_time=3.303300|duration=1001|duration_time=0.033367|size=1754|pos=995975|flags=__ +packet|codec_type=video|stream_index=0|pts=105105|pts_time=3.503500|dts=100100|dts_time=3.336667|duration=1001|duration_time=0.033367|size=19154|pos=998420|flags=__ +packet|codec_type=video|stream_index=0|pts=103103|pts_time=3.436767|dts=101101|dts_time=3.370033|duration=1001|duration_time=0.033367|size=3359|pos=1019010|flags=__ +packet|codec_type=video|stream_index=0|pts=102102|pts_time=3.403400|dts=102102|dts_time=3.403400|duration=1001|duration_time=0.033367|size=287|pos=1023138|flags=__ +packet|codec_type=video|stream_index=0|pts=104104|pts_time=3.470133|dts=103103|dts_time=3.436767|duration=1001|duration_time=0.033367|size=2111|pos=1024928|flags=__ +packet|codec_type=video|stream_index=0|pts=109109|pts_time=3.636967|dts=104104|dts_time=3.470133|duration=1001|duration_time=0.033367|size=17178|pos=1027833|flags=__ +packet|codec_type=video|stream_index=0|pts=107107|pts_time=3.570233|dts=105105|dts_time=3.503500|duration=1001|duration_time=0.033367|size=7205|pos=1045716|flags=__ +packet|codec_type=video|stream_index=0|pts=106106|pts_time=3.536867|dts=106106|dts_time=3.536867|duration=1001|duration_time=0.033367|size=2209|pos=1054354|flags=__ +packet|codec_type=video|stream_index=0|pts=108108|pts_time=3.603600|dts=107107|dts_time=3.570233|duration=1001|duration_time=0.033367|size=359|pos=1057226|flags=__ +packet|codec_type=video|stream_index=0|pts=113113|pts_time=3.770433|dts=108108|dts_time=3.603600|duration=1001|duration_time=0.033367|size=18469|pos=1059024|flags=__ +packet|codec_type=video|stream_index=0|pts=111111|pts_time=3.703700|dts=109109|dts_time=3.636967|duration=1001|duration_time=0.033367|size=3314|pos=1078213|flags=__ +packet|codec_type=video|stream_index=0|pts=110110|pts_time=3.670333|dts=110110|dts_time=3.670333|duration=1001|duration_time=0.033367|size=2556|pos=1083059|flags=__ +packet|codec_type=video|stream_index=0|pts=112112|pts_time=3.737067|dts=111111|dts_time=3.703700|duration=1001|duration_time=0.033367|size=437|pos=1086388|flags=__ +packet|codec_type=video|stream_index=0|pts=117117|pts_time=3.903900|dts=112112|dts_time=3.737067|duration=1001|duration_time=0.033367|size=19707|pos=1087610|flags=__ +packet|codec_type=video|stream_index=0|pts=115115|pts_time=3.837167|dts=113113|dts_time=3.770433|duration=1001|duration_time=0.033367|size=5917|pos=1108845|flags=__ +packet|codec_type=video|stream_index=0|pts=114114|pts_time=3.803800|dts=114114|dts_time=3.803800|duration=1001|duration_time=0.033367|size=2613|pos=1115495|flags=__ +packet|codec_type=video|stream_index=0|pts=116116|pts_time=3.870533|dts=115115|dts_time=3.837167|duration=1001|duration_time=0.033367|size=2672|pos=1119530|flags=__ +packet|codec_type=video|stream_index=0|pts=121121|pts_time=4.037367|dts=116116|dts_time=3.870533|duration=1001|duration_time=0.033367|size=19091|pos=1122970|flags=_D +packet|codec_type=video|stream_index=0|pts=119119|pts_time=3.970633|dts=117117|dts_time=3.903900|duration=1001|duration_time=0.033367|size=9244|pos=1143585|flags=__ +packet|codec_type=video|stream_index=0|pts=118118|pts_time=3.937267|dts=118118|dts_time=3.937267|duration=1001|duration_time=0.033367|size=284|pos=1153587|flags=__ +packet|codec_type=video|stream_index=0|pts=120120|pts_time=4.004000|dts=119119|dts_time=3.970633|duration=1001|duration_time=0.033367|size=2381|pos=1155393|flags=_D diff --git a/tests/ref/fate/mov-mp4-extended-atom b/tests/ref/fate/mov-mp4-extended-atom new file mode 100644 index 000000000..9d01abb2f --- /dev/null +++ b/tests/ref/fate/mov-mp4-extended-atom @@ -0,0 +1 @@ +packet|codec_type=video|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1001|duration_time=0.033367|size=14798|pos=16|flags=K_ diff --git a/tests/ref/fate/mov-zombie b/tests/ref/fate/mov-zombie index 445f92128..f4415febc 100644 --- a/tests/ref/fate/mov-zombie +++ b/tests/ref/fate/mov-zombie @@ -1,133 +1,198 @@ -packet|codec_type=video|stream_index=0|pts=0|pts_time=0.000000|dts=-3004|dts_time=-0.033378|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4133|pos=11309|flags=K_ -packet|codec_type=video|stream_index=0|pts=5440|pts_time=0.060444|dts=-567|dts_time=-0.006300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1077|pos=15442|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=-567|pkt_dts_time=-0.006300|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=11309|pkt_size=4133|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=2437|pts_time=0.027078|dts=2436|dts_time=0.027067|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=355|pos=16519|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=2437|pkt_pts_time=0.027078|pkt_dts=2436|pkt_dts_time=0.027067|best_effort_timestamp=2437|best_effort_timestamp_time=0.027078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16519|pkt_size=355|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=2|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=11446|pts_time=0.127178|dts=5439|dts_time=0.060433|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1110|pos=16874|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=5440|pkt_pts_time=0.060444|pkt_dts=5439|pkt_dts_time=0.060433|best_effort_timestamp=5440|best_effort_timestamp_time=0.060444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=15442|pkt_size=1077|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=1|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=8443|pts_time=0.093811|dts=8442|dts_time=0.093800|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=430|pos=17984|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=8443|pkt_pts_time=0.093811|pkt_dts=8442|pkt_dts_time=0.093800|best_effort_timestamp=8443|best_effort_timestamp_time=0.093811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=17984|pkt_size=430|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=4|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=17452|pts_time=0.193911|dts=11445|dts_time=0.127167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1485|pos=18414|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=11446|pkt_pts_time=0.127178|pkt_dts=11445|pkt_dts_time=0.127167|best_effort_timestamp=11446|best_effort_timestamp_time=0.127178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16874|pkt_size=1110|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=3|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=14449|pts_time=0.160544|dts=14448|dts_time=0.160533|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1005|pos=19899|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=14449|pkt_pts_time=0.160544|pkt_dts=14448|pkt_dts_time=0.160533|best_effort_timestamp=14449|best_effort_timestamp_time=0.160544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=19899|pkt_size=1005|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=6|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=23458|pts_time=0.260644|dts=17451|dts_time=0.193900|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1976|pos=20904|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=17452|pkt_pts_time=0.193911|pkt_dts=17451|pkt_dts_time=0.193900|best_effort_timestamp=17452|best_effort_timestamp_time=0.193911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=18414|pkt_size=1485|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=5|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=20455|pts_time=0.227278|dts=20454|dts_time=0.227267|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=904|pos=22880|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=20455|pkt_pts_time=0.227278|pkt_dts=20454|pkt_dts_time=0.227267|best_effort_timestamp=20455|best_effort_timestamp_time=0.227278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=22880|pkt_size=904|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=8|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=29464|pts_time=0.327378|dts=23457|dts_time=0.260633|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1254|pos=23784|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=23458|pkt_pts_time=0.260644|pkt_dts=23457|pkt_dts_time=0.260633|best_effort_timestamp=23458|best_effort_timestamp_time=0.260644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=20904|pkt_size=1976|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=7|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=26461|pts_time=0.294011|dts=26460|dts_time=0.294000|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=700|pos=25038|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=26461|pkt_pts_time=0.294011|pkt_dts=26460|pkt_dts_time=0.294000|best_effort_timestamp=26461|best_effort_timestamp_time=0.294011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25038|pkt_size=700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=10|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=35470|pts_time=0.394111|dts=29463|dts_time=0.327367|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1311|pos=25738|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=29464|pkt_pts_time=0.327378|pkt_dts=29463|pkt_dts_time=0.327367|best_effort_timestamp=29464|best_effort_timestamp_time=0.327378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=23784|pkt_size=1254|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=9|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=32467|pts_time=0.360744|dts=32466|dts_time=0.360733|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=631|pos=27049|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=32467|pkt_pts_time=0.360744|pkt_dts=32466|pkt_dts_time=0.360733|best_effort_timestamp=32467|best_effort_timestamp_time=0.360744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27049|pkt_size=631|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=12|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=41476|pts_time=0.460844|dts=35469|dts_time=0.394100|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1296|pos=27680|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=35470|pkt_pts_time=0.394111|pkt_dts=35469|pkt_dts_time=0.394100|best_effort_timestamp=35470|best_effort_timestamp_time=0.394111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25738|pkt_size=1311|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=11|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=38473|pts_time=0.427478|dts=38472|dts_time=0.427467|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=466|pos=28976|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=38473|pkt_pts_time=0.427478|pkt_dts=38472|pkt_dts_time=0.427467|best_effort_timestamp=38473|best_effort_timestamp_time=0.427478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=28976|pkt_size=466|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=14|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=47482|pts_time=0.527578|dts=41475|dts_time=0.460833|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1638|pos=29442|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=41476|pkt_pts_time=0.460844|pkt_dts=41475|pkt_dts_time=0.460833|best_effort_timestamp=41476|best_effort_timestamp_time=0.460844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27680|pkt_size=1296|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=13|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=44479|pts_time=0.494211|dts=44478|dts_time=0.494200|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=907|pos=31080|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=44479|pkt_pts_time=0.494211|pkt_dts=44478|pkt_dts_time=0.494200|best_effort_timestamp=44479|best_effort_timestamp_time=0.494211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31080|pkt_size=907|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=16|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=53488|pts_time=0.594311|dts=47481|dts_time=0.527567|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1362|pos=31987|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=47482|pkt_pts_time=0.527578|pkt_dts=47481|pkt_dts_time=0.527567|best_effort_timestamp=47482|best_effort_timestamp_time=0.527578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=29442|pkt_size=1638|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=15|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=50485|pts_time=0.560944|dts=50484|dts_time=0.560933|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=682|pos=33349|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=50485|pkt_pts_time=0.560944|pkt_dts=50484|pkt_dts_time=0.560933|best_effort_timestamp=50485|best_effort_timestamp_time=0.560944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=33349|pkt_size=682|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=18|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=59494|pts_time=0.661044|dts=53487|dts_time=0.594300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2917|pos=34031|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=53488|pkt_pts_time=0.594311|pkt_dts=53487|pkt_dts_time=0.594300|best_effort_timestamp=53488|best_effort_timestamp_time=0.594311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31987|pkt_size=1362|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=17|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=56491|pts_time=0.627678|dts=56490|dts_time=0.627667|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1174|pos=36948|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=56491|pkt_pts_time=0.627678|pkt_dts=56490|pkt_dts_time=0.627667|best_effort_timestamp=56491|best_effort_timestamp_time=0.627678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=36948|pkt_size=1174|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=20|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=65500|pts_time=0.727778|dts=59493|dts_time=0.661033|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1748|pos=38122|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=59494|pkt_pts_time=0.661044|pkt_dts=59493|pkt_dts_time=0.661033|best_effort_timestamp=59494|best_effort_timestamp_time=0.661044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=34031|pkt_size=2917|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=19|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=62497|pts_time=0.694411|dts=62496|dts_time=0.694400|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=926|pos=39870|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=62497|pkt_pts_time=0.694411|pkt_dts=62496|pkt_dts_time=0.694400|best_effort_timestamp=62497|best_effort_timestamp_time=0.694411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=39870|pkt_size=926|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=22|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=68503|pts_time=0.761144|dts=65499|dts_time=0.727767|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=918|pos=40796|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=65500|pkt_pts_time=0.727778|pkt_dts=65499|pkt_dts_time=0.727767|best_effort_timestamp=65500|best_effort_timestamp_time=0.727778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=38122|pkt_size=1748|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=21|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=71506|pts_time=0.794511|dts=68502|dts_time=0.761133|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3846|pos=41714|flags=K_ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=68503|pkt_pts_time=0.761144|pkt_dts=68502|pkt_dts_time=0.761133|best_effort_timestamp=68503|best_effort_timestamp_time=0.761144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=40796|pkt_size=918|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=23|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=77512|pts_time=0.861244|dts=71505|dts_time=0.794500|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1932|pos=45560|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=71506|pkt_pts_time=0.794511|pkt_dts=71505|pkt_dts_time=0.794500|best_effort_timestamp=71506|best_effort_timestamp_time=0.794511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=41714|pkt_size=3846|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=24|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=74509|pts_time=0.827878|dts=74508|dts_time=0.827867|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1159|pos=47492|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=74509|pkt_pts_time=0.827878|pkt_dts=74508|pkt_dts_time=0.827867|best_effort_timestamp=74509|best_effort_timestamp_time=0.827878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=47492|pkt_size=1159|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=26|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=83518|pts_time=0.927978|dts=77511|dts_time=0.861233|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1522|pos=48651|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=77512|pkt_pts_time=0.861244|pkt_dts=77511|pkt_dts_time=0.861233|best_effort_timestamp=77512|best_effort_timestamp_time=0.861244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=45560|pkt_size=1932|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=25|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=80515|pts_time=0.894611|dts=80514|dts_time=0.894600|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=719|pos=50173|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=80515|pkt_pts_time=0.894611|pkt_dts=80514|pkt_dts_time=0.894600|best_effort_timestamp=80515|best_effort_timestamp_time=0.894611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50173|pkt_size=719|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=28|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=89524|pts_time=0.994711|dts=83517|dts_time=0.927967|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1700|pos=50892|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=83518|pkt_pts_time=0.927978|pkt_dts=83517|pkt_dts_time=0.927967|best_effort_timestamp=83518|best_effort_timestamp_time=0.927978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=48651|pkt_size=1522|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=27|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=86521|pts_time=0.961344|dts=86520|dts_time=0.961333|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1099|pos=52592|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=86521|pkt_pts_time=0.961344|pkt_dts=86520|pkt_dts_time=0.961333|best_effort_timestamp=86521|best_effort_timestamp_time=0.961344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=52592|pkt_size=1099|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=30|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=95530|pts_time=1.061444|dts=89523|dts_time=0.994700|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2558|pos=53691|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=89524|pkt_pts_time=0.994711|pkt_dts=89523|pkt_dts_time=0.994700|best_effort_timestamp=89524|best_effort_timestamp_time=0.994711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50892|pkt_size=1700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=29|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=92527|pts_time=1.028078|dts=92526|dts_time=1.028067|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1008|pos=56249|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=92527|pkt_pts_time=1.028078|pkt_dts=92526|pkt_dts_time=1.028067|best_effort_timestamp=92527|best_effort_timestamp_time=1.028078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=56249|pkt_size=1008|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=32|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=101536|pts_time=1.128178|dts=95529|dts_time=1.061433|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1236|pos=57257|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=95530|pkt_pts_time=1.061444|pkt_dts=95529|pkt_dts_time=1.061433|best_effort_timestamp=95530|best_effort_timestamp_time=1.061444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=53691|pkt_size=2558|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=31|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=98533|pts_time=1.094811|dts=98532|dts_time=1.094800|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=607|pos=58493|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=98533|pkt_pts_time=1.094811|pkt_dts=98532|pkt_dts_time=1.094800|best_effort_timestamp=98533|best_effort_timestamp_time=1.094811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=58493|pkt_size=607|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=34|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=107542|pts_time=1.194911|dts=101535|dts_time=1.128167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1883|pos=59100|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=101536|pkt_pts_time=1.128178|pkt_dts=101535|pkt_dts_time=1.128167|best_effort_timestamp=101536|best_effort_timestamp_time=1.128178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=57257|pkt_size=1236|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=33|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=104539|pts_time=1.161544|dts=104538|dts_time=1.161533|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=893|pos=60983|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=104539|pkt_pts_time=1.161544|pkt_dts=104538|pkt_dts_time=1.161533|best_effort_timestamp=104539|best_effort_timestamp_time=1.161544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=60983|pkt_size=893|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=36|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=113548|pts_time=1.261644|dts=107541|dts_time=1.194900|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1305|pos=61876|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=107542|pkt_pts_time=1.194911|pkt_dts=107541|pkt_dts_time=1.194900|best_effort_timestamp=107542|best_effort_timestamp_time=1.194911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=59100|pkt_size=1883|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=35|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=110545|pts_time=1.228278|dts=110544|dts_time=1.228267|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=472|pos=63181|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=110545|pkt_pts_time=1.228278|pkt_dts=110544|pkt_dts_time=1.228267|best_effort_timestamp=110545|best_effort_timestamp_time=1.228278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63181|pkt_size=472|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=38|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=119554|pts_time=1.328378|dts=113547|dts_time=1.261633|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1411|pos=63653|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=113548|pkt_pts_time=1.261644|pkt_dts=113547|pkt_dts_time=1.261633|best_effort_timestamp=113548|best_effort_timestamp_time=1.261644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=61876|pkt_size=1305|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=37|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=116551|pts_time=1.295011|dts=116550|dts_time=1.295000|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=616|pos=65064|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=116551|pkt_pts_time=1.295011|pkt_dts=116550|pkt_dts_time=1.295000|best_effort_timestamp=116551|best_effort_timestamp_time=1.295011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65064|pkt_size=616|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=40|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=125560|pts_time=1.395111|dts=119553|dts_time=1.328367|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1291|pos=65680|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=119554|pkt_pts_time=1.328378|pkt_dts=119553|pkt_dts_time=1.328367|best_effort_timestamp=119554|best_effort_timestamp_time=1.328378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63653|pkt_size=1411|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=39|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=122557|pts_time=1.361744|dts=122556|dts_time=1.361733|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=470|pos=66971|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=122557|pkt_pts_time=1.361744|pkt_dts=122556|pkt_dts_time=1.361733|best_effort_timestamp=122557|best_effort_timestamp_time=1.361744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=66971|pkt_size=470|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=42|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=131566|pts_time=1.461844|dts=125559|dts_time=1.395100|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1977|pos=67441|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=125560|pkt_pts_time=1.395111|pkt_dts=125559|pkt_dts_time=1.395100|best_effort_timestamp=125560|best_effort_timestamp_time=1.395111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65680|pkt_size=1291|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=41|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=128563|pts_time=1.428478|dts=128562|dts_time=1.428467|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=436|pos=69418|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=128563|pkt_pts_time=1.428478|pkt_dts=128562|pkt_dts_time=1.428467|best_effort_timestamp=128563|best_effort_timestamp_time=1.428478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69418|pkt_size=436|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=44|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=137572|pts_time=1.528578|dts=131565|dts_time=1.461833|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2566|pos=69854|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=131566|pkt_pts_time=1.461844|pkt_dts=131565|pkt_dts_time=1.461833|best_effort_timestamp=131566|best_effort_timestamp_time=1.461844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=67441|pkt_size=1977|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=43|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=134569|pts_time=1.495211|dts=134568|dts_time=1.495200|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=886|pos=72420|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=134569|pkt_pts_time=1.495211|pkt_dts=134568|pkt_dts_time=1.495200|best_effort_timestamp=134569|best_effort_timestamp_time=1.495211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=72420|pkt_size=886|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=46|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=140575|pts_time=1.561944|dts=137571|dts_time=1.528567|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1330|pos=73306|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=137572|pkt_pts_time=1.528578|pkt_dts=137571|pkt_dts_time=1.528567|best_effort_timestamp=137572|best_effort_timestamp_time=1.528578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69854|pkt_size=2566|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=45|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=143578|pts_time=1.595311|dts=140574|dts_time=1.561933|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2227|pos=74636|flags=K_ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=140575|pkt_pts_time=1.561944|pkt_dts=140574|pkt_dts_time=1.561933|best_effort_timestamp=140575|best_effort_timestamp_time=1.561944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=73306|pkt_size=1330|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=47|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=149584|pts_time=1.662044|dts=143577|dts_time=1.595300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2210|pos=76863|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=143578|pkt_pts_time=1.595311|pkt_dts=143577|pkt_dts_time=1.595300|best_effort_timestamp=143578|best_effort_timestamp_time=1.595311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=74636|pkt_size=2227|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=48|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=146581|pts_time=1.628678|dts=146580|dts_time=1.628667|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1498|pos=79073|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=146581|pkt_pts_time=1.628678|pkt_dts=146580|pkt_dts_time=1.628667|best_effort_timestamp=146581|best_effort_timestamp_time=1.628678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=79073|pkt_size=1498|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=50|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=155590|pts_time=1.728778|dts=149583|dts_time=1.662033|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1721|pos=80571|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=149584|pkt_pts_time=1.662044|pkt_dts=149583|pkt_dts_time=1.662033|best_effort_timestamp=149584|best_effort_timestamp_time=1.662044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=76863|pkt_size=2210|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=49|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=152587|pts_time=1.695411|dts=152586|dts_time=1.695400|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1238|pos=82292|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=152587|pkt_pts_time=1.695411|pkt_dts=152586|pkt_dts_time=1.695400|best_effort_timestamp=152587|best_effort_timestamp_time=1.695411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=82292|pkt_size=1238|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=52|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=161596|pts_time=1.795511|dts=155589|dts_time=1.728767|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1753|pos=83530|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=155590|pkt_pts_time=1.728778|pkt_dts=155589|pkt_dts_time=1.728767|best_effort_timestamp=155590|best_effort_timestamp_time=1.728778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=80571|pkt_size=1721|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=51|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=158593|pts_time=1.762144|dts=158592|dts_time=1.762133|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1014|pos=85283|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=158593|pkt_pts_time=1.762144|pkt_dts=158592|pkt_dts_time=1.762133|best_effort_timestamp=158593|best_effort_timestamp_time=1.762144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=85283|pkt_size=1014|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=54|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=167602|pts_time=1.862244|dts=161595|dts_time=1.795500|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2408|pos=86297|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=161596|pkt_pts_time=1.795511|pkt_dts=161595|pkt_dts_time=1.795500|best_effort_timestamp=161596|best_effort_timestamp_time=1.795511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=83530|pkt_size=1753|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=53|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=164599|pts_time=1.828878|dts=164598|dts_time=1.828867|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1727|pos=88705|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=164599|pkt_pts_time=1.828878|pkt_dts=164598|pkt_dts_time=1.828867|best_effort_timestamp=164599|best_effort_timestamp_time=1.828878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=88705|pkt_size=1727|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=56|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=173608|pts_time=1.928978|dts=167601|dts_time=1.862233|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1504|pos=90432|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=167602|pkt_pts_time=1.862244|pkt_dts=167601|pkt_dts_time=1.862233|best_effort_timestamp=167602|best_effort_timestamp_time=1.862244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=86297|pkt_size=2408|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=55|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=170605|pts_time=1.895611|dts=170604|dts_time=1.895600|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=957|pos=91936|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=170605|pkt_pts_time=1.895611|pkt_dts=170604|pkt_dts_time=1.895600|best_effort_timestamp=170605|best_effort_timestamp_time=1.895611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=91936|pkt_size=957|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=58|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=179614|pts_time=1.995711|dts=173607|dts_time=1.928967|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1890|pos=92893|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=173608|pkt_pts_time=1.928978|pkt_dts=173607|pkt_dts_time=1.928967|best_effort_timestamp=173608|best_effort_timestamp_time=1.928978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=90432|pkt_size=1504|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=57|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=176611|pts_time=1.962344|dts=176610|dts_time=1.962333|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1239|pos=94783|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=176611|pkt_pts_time=1.962344|pkt_dts=176610|pkt_dts_time=1.962333|best_effort_timestamp=176611|best_effort_timestamp_time=1.962344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=94783|pkt_size=1239|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=60|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=185620|pts_time=2.062444|dts=179613|dts_time=1.995700|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1856|pos=96022|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=179614|pkt_pts_time=1.995711|pkt_dts=179613|pkt_dts_time=1.995700|best_effort_timestamp=179614|best_effort_timestamp_time=1.995711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=92893|pkt_size=1890|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=59|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=182617|pts_time=2.029078|dts=182616|dts_time=2.029067|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1302|pos=97878|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=182617|pkt_pts_time=2.029078|pkt_dts=182616|pkt_dts_time=2.029067|best_effort_timestamp=182617|best_effort_timestamp_time=2.029078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=97878|pkt_size=1302|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=62|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=191626|pts_time=2.129178|dts=185619|dts_time=2.062433|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1666|pos=99180|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=185620|pkt_pts_time=2.062444|pkt_dts=185619|pkt_dts_time=2.062433|best_effort_timestamp=185620|best_effort_timestamp_time=2.062444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=96022|pkt_size=1856|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=61|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=188623|pts_time=2.095811|dts=188622|dts_time=2.095800|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=974|pos=100846|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=188623|pkt_pts_time=2.095811|pkt_dts=188622|pkt_dts_time=2.095800|best_effort_timestamp=188623|best_effort_timestamp_time=2.095811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=100846|pkt_size=974|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=64|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -packet|codec_type=video|stream_index=0|pts=197632|pts_time=2.195911|dts=191625|dts_time=2.129167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=580|pos=101820|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=191626|pkt_pts_time=2.129178|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=191626|best_effort_timestamp_time=2.129178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=99180|pkt_size=1666|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=63|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft -stream|index=0|codec_name=h264|profile=77|codec_type=video|codec_time_base=212521/12744000|codec_tag_string=avc1|codec_tag=0x31637661|width=160|height=240|coded_width=160|coded_height=240|closed_captions=0|has_b_frames=1|sample_aspect_ratio=2:1|display_aspect_ratio=4:3|pix_fmt=yuv420p|level=12|color_range=tv|color_space=smpte170m|color_transfer=bt709|color_primaries=smpte170m|chroma_location=topleft|field_order=unknown|timecode=N/A|refs=2|is_avc=true|nal_length_size=4|id=N/A|r_frame_rate=30000/1001|avg_frame_rate=6372000/212521|time_base=1/90000|start_pts=0|start_time=0.000000|duration_ts=2125200|duration=23.613333|bit_rate=333874|max_bit_rate=N/A|bits_per_raw_sample=8|nb_frames=708|nb_read_frames=65|nb_read_packets=66|disposition:default=1|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:rotate=0|tag:creation_time=2008-05-12T20:59:27.000000Z|tag:language=eng|tag:handler_name=Apple Video Media Handler|tag:encoder=H.264 +packet|codec_type=video|stream_index=0|pts=0|pts_time=0.000000|dts=-3004|dts_time=-0.033378|duration=3003|duration_time=0.033367|size=4133|pos=11309|flags=K_ +packet|codec_type=video|stream_index=0|pts=5440|pts_time=0.060444|dts=-567|dts_time=-0.006300|duration=3003|duration_time=0.033367|size=1077|pos=15442|flags=__ +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=-567|pkt_dts_time=-0.006300|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=11309|pkt_size=4133|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=2437|pts_time=0.027078|dts=2436|dts_time=0.027067|duration=3003|duration_time=0.033367|size=355|pos=16519|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=2437|pkt_pts_time=0.027078|pkt_dts=2436|pkt_dts_time=0.027067|best_effort_timestamp=2437|best_effort_timestamp_time=0.027078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16519|pkt_size=355|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=2|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=11446|pts_time=0.127178|dts=5439|dts_time=0.060433|duration=3003|duration_time=0.033367|size=1110|pos=16874|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=5440|pkt_pts_time=0.060444|pkt_dts=5439|pkt_dts_time=0.060433|best_effort_timestamp=5440|best_effort_timestamp_time=0.060444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=15442|pkt_size=1077|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=1|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=8443|pts_time=0.093811|dts=8442|dts_time=0.093800|duration=3003|duration_time=0.033367|size=430|pos=17984|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=8443|pkt_pts_time=0.093811|pkt_dts=8442|pkt_dts_time=0.093800|best_effort_timestamp=8443|best_effort_timestamp_time=0.093811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=17984|pkt_size=430|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=4|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=17452|pts_time=0.193911|dts=11445|dts_time=0.127167|duration=3003|duration_time=0.033367|size=1485|pos=18414|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=11446|pkt_pts_time=0.127178|pkt_dts=11445|pkt_dts_time=0.127167|best_effort_timestamp=11446|best_effort_timestamp_time=0.127178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16874|pkt_size=1110|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=3|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=14449|pts_time=0.160544|dts=14448|dts_time=0.160533|duration=3003|duration_time=0.033367|size=1005|pos=19899|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=14449|pkt_pts_time=0.160544|pkt_dts=14448|pkt_dts_time=0.160533|best_effort_timestamp=14449|best_effort_timestamp_time=0.160544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=19899|pkt_size=1005|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=6|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=23458|pts_time=0.260644|dts=17451|dts_time=0.193900|duration=3003|duration_time=0.033367|size=1976|pos=20904|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=17452|pkt_pts_time=0.193911|pkt_dts=17451|pkt_dts_time=0.193900|best_effort_timestamp=17452|best_effort_timestamp_time=0.193911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=18414|pkt_size=1485|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=5|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=20455|pts_time=0.227278|dts=20454|dts_time=0.227267|duration=3003|duration_time=0.033367|size=904|pos=22880|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=20455|pkt_pts_time=0.227278|pkt_dts=20454|pkt_dts_time=0.227267|best_effort_timestamp=20455|best_effort_timestamp_time=0.227278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=22880|pkt_size=904|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=8|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=29464|pts_time=0.327378|dts=23457|dts_time=0.260633|duration=3003|duration_time=0.033367|size=1254|pos=23784|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=23458|pkt_pts_time=0.260644|pkt_dts=23457|pkt_dts_time=0.260633|best_effort_timestamp=23458|best_effort_timestamp_time=0.260644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=20904|pkt_size=1976|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=7|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=26461|pts_time=0.294011|dts=26460|dts_time=0.294000|duration=3003|duration_time=0.033367|size=700|pos=25038|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=26461|pkt_pts_time=0.294011|pkt_dts=26460|pkt_dts_time=0.294000|best_effort_timestamp=26461|best_effort_timestamp_time=0.294011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25038|pkt_size=700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=10|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=35470|pts_time=0.394111|dts=29463|dts_time=0.327367|duration=3003|duration_time=0.033367|size=1311|pos=25738|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=29464|pkt_pts_time=0.327378|pkt_dts=29463|pkt_dts_time=0.327367|best_effort_timestamp=29464|best_effort_timestamp_time=0.327378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=23784|pkt_size=1254|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=9|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=32467|pts_time=0.360744|dts=32466|dts_time=0.360733|duration=3003|duration_time=0.033367|size=631|pos=27049|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=32467|pkt_pts_time=0.360744|pkt_dts=32466|pkt_dts_time=0.360733|best_effort_timestamp=32467|best_effort_timestamp_time=0.360744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27049|pkt_size=631|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=12|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=41476|pts_time=0.460844|dts=35469|dts_time=0.394100|duration=3003|duration_time=0.033367|size=1296|pos=27680|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=35470|pkt_pts_time=0.394111|pkt_dts=35469|pkt_dts_time=0.394100|best_effort_timestamp=35470|best_effort_timestamp_time=0.394111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25738|pkt_size=1311|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=11|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=38473|pts_time=0.427478|dts=38472|dts_time=0.427467|duration=3003|duration_time=0.033367|size=466|pos=28976|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=38473|pkt_pts_time=0.427478|pkt_dts=38472|pkt_dts_time=0.427467|best_effort_timestamp=38473|best_effort_timestamp_time=0.427478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=28976|pkt_size=466|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=14|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=47482|pts_time=0.527578|dts=41475|dts_time=0.460833|duration=3003|duration_time=0.033367|size=1638|pos=29442|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=41476|pkt_pts_time=0.460844|pkt_dts=41475|pkt_dts_time=0.460833|best_effort_timestamp=41476|best_effort_timestamp_time=0.460844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27680|pkt_size=1296|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=13|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=44479|pts_time=0.494211|dts=44478|dts_time=0.494200|duration=3003|duration_time=0.033367|size=907|pos=31080|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=44479|pkt_pts_time=0.494211|pkt_dts=44478|pkt_dts_time=0.494200|best_effort_timestamp=44479|best_effort_timestamp_time=0.494211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31080|pkt_size=907|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=16|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=53488|pts_time=0.594311|dts=47481|dts_time=0.527567|duration=3003|duration_time=0.033367|size=1362|pos=31987|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=47482|pkt_pts_time=0.527578|pkt_dts=47481|pkt_dts_time=0.527567|best_effort_timestamp=47482|best_effort_timestamp_time=0.527578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=29442|pkt_size=1638|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=15|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=50485|pts_time=0.560944|dts=50484|dts_time=0.560933|duration=3003|duration_time=0.033367|size=682|pos=33349|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=50485|pkt_pts_time=0.560944|pkt_dts=50484|pkt_dts_time=0.560933|best_effort_timestamp=50485|best_effort_timestamp_time=0.560944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=33349|pkt_size=682|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=18|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=59494|pts_time=0.661044|dts=53487|dts_time=0.594300|duration=3003|duration_time=0.033367|size=2917|pos=34031|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=53488|pkt_pts_time=0.594311|pkt_dts=53487|pkt_dts_time=0.594300|best_effort_timestamp=53488|best_effort_timestamp_time=0.594311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31987|pkt_size=1362|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=17|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=56491|pts_time=0.627678|dts=56490|dts_time=0.627667|duration=3003|duration_time=0.033367|size=1174|pos=36948|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=56491|pkt_pts_time=0.627678|pkt_dts=56490|pkt_dts_time=0.627667|best_effort_timestamp=56491|best_effort_timestamp_time=0.627678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=36948|pkt_size=1174|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=20|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=65500|pts_time=0.727778|dts=59493|dts_time=0.661033|duration=3003|duration_time=0.033367|size=1748|pos=38122|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=59494|pkt_pts_time=0.661044|pkt_dts=59493|pkt_dts_time=0.661033|best_effort_timestamp=59494|best_effort_timestamp_time=0.661044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=34031|pkt_size=2917|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=19|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=62497|pts_time=0.694411|dts=62496|dts_time=0.694400|duration=3003|duration_time=0.033367|size=926|pos=39870|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=62497|pkt_pts_time=0.694411|pkt_dts=62496|pkt_dts_time=0.694400|best_effort_timestamp=62497|best_effort_timestamp_time=0.694411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=39870|pkt_size=926|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=22|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=68503|pts_time=0.761144|dts=65499|dts_time=0.727767|duration=3003|duration_time=0.033367|size=918|pos=40796|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=65500|pkt_pts_time=0.727778|pkt_dts=65499|pkt_dts_time=0.727767|best_effort_timestamp=65500|best_effort_timestamp_time=0.727778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=38122|pkt_size=1748|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=21|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=71506|pts_time=0.794511|dts=68502|dts_time=0.761133|duration=3003|duration_time=0.033367|size=3846|pos=41714|flags=K_ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=68503|pkt_pts_time=0.761144|pkt_dts=68502|pkt_dts_time=0.761133|best_effort_timestamp=68503|best_effort_timestamp_time=0.761144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=40796|pkt_size=918|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=23|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=77512|pts_time=0.861244|dts=71505|dts_time=0.794500|duration=3003|duration_time=0.033367|size=1932|pos=45560|flags=__ +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=71506|pkt_pts_time=0.794511|pkt_dts=71505|pkt_dts_time=0.794500|best_effort_timestamp=71506|best_effort_timestamp_time=0.794511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=41714|pkt_size=3846|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=24|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=74509|pts_time=0.827878|dts=74508|dts_time=0.827867|duration=3003|duration_time=0.033367|size=1159|pos=47492|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=74509|pkt_pts_time=0.827878|pkt_dts=74508|pkt_dts_time=0.827867|best_effort_timestamp=74509|best_effort_timestamp_time=0.827878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=47492|pkt_size=1159|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=26|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=83518|pts_time=0.927978|dts=77511|dts_time=0.861233|duration=3003|duration_time=0.033367|size=1522|pos=48651|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=77512|pkt_pts_time=0.861244|pkt_dts=77511|pkt_dts_time=0.861233|best_effort_timestamp=77512|best_effort_timestamp_time=0.861244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=45560|pkt_size=1932|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=25|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=80515|pts_time=0.894611|dts=80514|dts_time=0.894600|duration=3003|duration_time=0.033367|size=719|pos=50173|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=80515|pkt_pts_time=0.894611|pkt_dts=80514|pkt_dts_time=0.894600|best_effort_timestamp=80515|best_effort_timestamp_time=0.894611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50173|pkt_size=719|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=28|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=89524|pts_time=0.994711|dts=83517|dts_time=0.927967|duration=3003|duration_time=0.033367|size=1700|pos=50892|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=83518|pkt_pts_time=0.927978|pkt_dts=83517|pkt_dts_time=0.927967|best_effort_timestamp=83518|best_effort_timestamp_time=0.927978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=48651|pkt_size=1522|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=27|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=86521|pts_time=0.961344|dts=86520|dts_time=0.961333|duration=3003|duration_time=0.033367|size=1099|pos=52592|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=86521|pkt_pts_time=0.961344|pkt_dts=86520|pkt_dts_time=0.961333|best_effort_timestamp=86521|best_effort_timestamp_time=0.961344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=52592|pkt_size=1099|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=30|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=95530|pts_time=1.061444|dts=89523|dts_time=0.994700|duration=3003|duration_time=0.033367|size=2558|pos=53691|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=89524|pkt_pts_time=0.994711|pkt_dts=89523|pkt_dts_time=0.994700|best_effort_timestamp=89524|best_effort_timestamp_time=0.994711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50892|pkt_size=1700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=29|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=92527|pts_time=1.028078|dts=92526|dts_time=1.028067|duration=3003|duration_time=0.033367|size=1008|pos=56249|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=92527|pkt_pts_time=1.028078|pkt_dts=92526|pkt_dts_time=1.028067|best_effort_timestamp=92527|best_effort_timestamp_time=1.028078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=56249|pkt_size=1008|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=32|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=101536|pts_time=1.128178|dts=95529|dts_time=1.061433|duration=3003|duration_time=0.033367|size=1236|pos=57257|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=95530|pkt_pts_time=1.061444|pkt_dts=95529|pkt_dts_time=1.061433|best_effort_timestamp=95530|best_effort_timestamp_time=1.061444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=53691|pkt_size=2558|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=31|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=98533|pts_time=1.094811|dts=98532|dts_time=1.094800|duration=3003|duration_time=0.033367|size=607|pos=58493|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=98533|pkt_pts_time=1.094811|pkt_dts=98532|pkt_dts_time=1.094800|best_effort_timestamp=98533|best_effort_timestamp_time=1.094811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=58493|pkt_size=607|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=34|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=107542|pts_time=1.194911|dts=101535|dts_time=1.128167|duration=3003|duration_time=0.033367|size=1883|pos=59100|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=101536|pkt_pts_time=1.128178|pkt_dts=101535|pkt_dts_time=1.128167|best_effort_timestamp=101536|best_effort_timestamp_time=1.128178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=57257|pkt_size=1236|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=33|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=104539|pts_time=1.161544|dts=104538|dts_time=1.161533|duration=3003|duration_time=0.033367|size=893|pos=60983|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=104539|pkt_pts_time=1.161544|pkt_dts=104538|pkt_dts_time=1.161533|best_effort_timestamp=104539|best_effort_timestamp_time=1.161544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=60983|pkt_size=893|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=36|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=113548|pts_time=1.261644|dts=107541|dts_time=1.194900|duration=3003|duration_time=0.033367|size=1305|pos=61876|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=107542|pkt_pts_time=1.194911|pkt_dts=107541|pkt_dts_time=1.194900|best_effort_timestamp=107542|best_effort_timestamp_time=1.194911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=59100|pkt_size=1883|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=35|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=110545|pts_time=1.228278|dts=110544|dts_time=1.228267|duration=3003|duration_time=0.033367|size=472|pos=63181|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=110545|pkt_pts_time=1.228278|pkt_dts=110544|pkt_dts_time=1.228267|best_effort_timestamp=110545|best_effort_timestamp_time=1.228278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63181|pkt_size=472|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=38|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=119554|pts_time=1.328378|dts=113547|dts_time=1.261633|duration=3003|duration_time=0.033367|size=1411|pos=63653|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=113548|pkt_pts_time=1.261644|pkt_dts=113547|pkt_dts_time=1.261633|best_effort_timestamp=113548|best_effort_timestamp_time=1.261644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=61876|pkt_size=1305|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=37|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=116551|pts_time=1.295011|dts=116550|dts_time=1.295000|duration=3003|duration_time=0.033367|size=616|pos=65064|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=116551|pkt_pts_time=1.295011|pkt_dts=116550|pkt_dts_time=1.295000|best_effort_timestamp=116551|best_effort_timestamp_time=1.295011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65064|pkt_size=616|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=40|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=125560|pts_time=1.395111|dts=119553|dts_time=1.328367|duration=3003|duration_time=0.033367|size=1291|pos=65680|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=119554|pkt_pts_time=1.328378|pkt_dts=119553|pkt_dts_time=1.328367|best_effort_timestamp=119554|best_effort_timestamp_time=1.328378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63653|pkt_size=1411|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=39|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=122557|pts_time=1.361744|dts=122556|dts_time=1.361733|duration=3003|duration_time=0.033367|size=470|pos=66971|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=122557|pkt_pts_time=1.361744|pkt_dts=122556|pkt_dts_time=1.361733|best_effort_timestamp=122557|best_effort_timestamp_time=1.361744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=66971|pkt_size=470|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=42|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=131566|pts_time=1.461844|dts=125559|dts_time=1.395100|duration=3003|duration_time=0.033367|size=1977|pos=67441|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=125560|pkt_pts_time=1.395111|pkt_dts=125559|pkt_dts_time=1.395100|best_effort_timestamp=125560|best_effort_timestamp_time=1.395111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65680|pkt_size=1291|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=41|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=128563|pts_time=1.428478|dts=128562|dts_time=1.428467|duration=3003|duration_time=0.033367|size=436|pos=69418|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=128563|pkt_pts_time=1.428478|pkt_dts=128562|pkt_dts_time=1.428467|best_effort_timestamp=128563|best_effort_timestamp_time=1.428478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69418|pkt_size=436|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=44|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=137572|pts_time=1.528578|dts=131565|dts_time=1.461833|duration=3003|duration_time=0.033367|size=2566|pos=69854|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=131566|pkt_pts_time=1.461844|pkt_dts=131565|pkt_dts_time=1.461833|best_effort_timestamp=131566|best_effort_timestamp_time=1.461844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=67441|pkt_size=1977|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=43|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=134569|pts_time=1.495211|dts=134568|dts_time=1.495200|duration=3003|duration_time=0.033367|size=886|pos=72420|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=134569|pkt_pts_time=1.495211|pkt_dts=134568|pkt_dts_time=1.495200|best_effort_timestamp=134569|best_effort_timestamp_time=1.495211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=72420|pkt_size=886|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=46|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=140575|pts_time=1.561944|dts=137571|dts_time=1.528567|duration=3003|duration_time=0.033367|size=1330|pos=73306|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=137572|pkt_pts_time=1.528578|pkt_dts=137571|pkt_dts_time=1.528567|best_effort_timestamp=137572|best_effort_timestamp_time=1.528578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69854|pkt_size=2566|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=45|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=143578|pts_time=1.595311|dts=140574|dts_time=1.561933|duration=3003|duration_time=0.033367|size=2227|pos=74636|flags=K_ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=140575|pkt_pts_time=1.561944|pkt_dts=140574|pkt_dts_time=1.561933|best_effort_timestamp=140575|best_effort_timestamp_time=1.561944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=73306|pkt_size=1330|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=47|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=149584|pts_time=1.662044|dts=143577|dts_time=1.595300|duration=3003|duration_time=0.033367|size=2210|pos=76863|flags=__ +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=143578|pkt_pts_time=1.595311|pkt_dts=143577|pkt_dts_time=1.595300|best_effort_timestamp=143578|best_effort_timestamp_time=1.595311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=74636|pkt_size=2227|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=48|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=146581|pts_time=1.628678|dts=146580|dts_time=1.628667|duration=3003|duration_time=0.033367|size=1498|pos=79073|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=146581|pkt_pts_time=1.628678|pkt_dts=146580|pkt_dts_time=1.628667|best_effort_timestamp=146581|best_effort_timestamp_time=1.628678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=79073|pkt_size=1498|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=50|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=155590|pts_time=1.728778|dts=149583|dts_time=1.662033|duration=3003|duration_time=0.033367|size=1721|pos=80571|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=149584|pkt_pts_time=1.662044|pkt_dts=149583|pkt_dts_time=1.662033|best_effort_timestamp=149584|best_effort_timestamp_time=1.662044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=76863|pkt_size=2210|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=49|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=152587|pts_time=1.695411|dts=152586|dts_time=1.695400|duration=3003|duration_time=0.033367|size=1238|pos=82292|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=152587|pkt_pts_time=1.695411|pkt_dts=152586|pkt_dts_time=1.695400|best_effort_timestamp=152587|best_effort_timestamp_time=1.695411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=82292|pkt_size=1238|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=52|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=161596|pts_time=1.795511|dts=155589|dts_time=1.728767|duration=3003|duration_time=0.033367|size=1753|pos=83530|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=155590|pkt_pts_time=1.728778|pkt_dts=155589|pkt_dts_time=1.728767|best_effort_timestamp=155590|best_effort_timestamp_time=1.728778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=80571|pkt_size=1721|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=51|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=158593|pts_time=1.762144|dts=158592|dts_time=1.762133|duration=3003|duration_time=0.033367|size=1014|pos=85283|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=158593|pkt_pts_time=1.762144|pkt_dts=158592|pkt_dts_time=1.762133|best_effort_timestamp=158593|best_effort_timestamp_time=1.762144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=85283|pkt_size=1014|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=54|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=167602|pts_time=1.862244|dts=161595|dts_time=1.795500|duration=3003|duration_time=0.033367|size=2408|pos=86297|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=161596|pkt_pts_time=1.795511|pkt_dts=161595|pkt_dts_time=1.795500|best_effort_timestamp=161596|best_effort_timestamp_time=1.795511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=83530|pkt_size=1753|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=53|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=164599|pts_time=1.828878|dts=164598|dts_time=1.828867|duration=3003|duration_time=0.033367|size=1727|pos=88705|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=164599|pkt_pts_time=1.828878|pkt_dts=164598|pkt_dts_time=1.828867|best_effort_timestamp=164599|best_effort_timestamp_time=1.828878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=88705|pkt_size=1727|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=56|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=173608|pts_time=1.928978|dts=167601|dts_time=1.862233|duration=3003|duration_time=0.033367|size=1504|pos=90432|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=167602|pkt_pts_time=1.862244|pkt_dts=167601|pkt_dts_time=1.862233|best_effort_timestamp=167602|best_effort_timestamp_time=1.862244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=86297|pkt_size=2408|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=55|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=170605|pts_time=1.895611|dts=170604|dts_time=1.895600|duration=3003|duration_time=0.033367|size=957|pos=91936|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=170605|pkt_pts_time=1.895611|pkt_dts=170604|pkt_dts_time=1.895600|best_effort_timestamp=170605|best_effort_timestamp_time=1.895611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=91936|pkt_size=957|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=58|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=179614|pts_time=1.995711|dts=173607|dts_time=1.928967|duration=3003|duration_time=0.033367|size=1890|pos=92893|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=173608|pkt_pts_time=1.928978|pkt_dts=173607|pkt_dts_time=1.928967|best_effort_timestamp=173608|best_effort_timestamp_time=1.928978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=90432|pkt_size=1504|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=57|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=176611|pts_time=1.962344|dts=176610|dts_time=1.962333|duration=3003|duration_time=0.033367|size=1239|pos=94783|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=176611|pkt_pts_time=1.962344|pkt_dts=176610|pkt_dts_time=1.962333|best_effort_timestamp=176611|best_effort_timestamp_time=1.962344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=94783|pkt_size=1239|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=60|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=185620|pts_time=2.062444|dts=179613|dts_time=1.995700|duration=3003|duration_time=0.033367|size=1856|pos=96022|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=179614|pkt_pts_time=1.995711|pkt_dts=179613|pkt_dts_time=1.995700|best_effort_timestamp=179614|best_effort_timestamp_time=1.995711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=92893|pkt_size=1890|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=59|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=182617|pts_time=2.029078|dts=182616|dts_time=2.029067|duration=3003|duration_time=0.033367|size=1302|pos=97878|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=182617|pkt_pts_time=2.029078|pkt_dts=182616|pkt_dts_time=2.029067|best_effort_timestamp=182617|best_effort_timestamp_time=2.029078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=97878|pkt_size=1302|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=62|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=191626|pts_time=2.129178|dts=185619|dts_time=2.062433|duration=3003|duration_time=0.033367|size=1666|pos=99180|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=185620|pkt_pts_time=2.062444|pkt_dts=185619|pkt_dts_time=2.062433|best_effort_timestamp=185620|best_effort_timestamp_time=2.062444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=96022|pkt_size=1856|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=61|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=188623|pts_time=2.095811|dts=188622|dts_time=2.095800|duration=3003|duration_time=0.033367|size=974|pos=100846|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=188623|pkt_pts_time=2.095811|pkt_dts=188622|pkt_dts_time=2.095800|best_effort_timestamp=188623|best_effort_timestamp_time=2.095811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=100846|pkt_size=974|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=64|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +packet|codec_type=video|stream_index=0|pts=197632|pts_time=2.195911|dts=191625|dts_time=2.129167|duration=3003|duration_time=0.033367|size=580|pos=101820|flags=__ +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=191626|pkt_pts_time=2.129178|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=191626|best_effort_timestamp_time=2.129178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=99180|pkt_size=1666|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=63|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + +stream|index=0|codec_name=h264|profile=77|codec_type=video|codec_tag_string=avc1|codec_tag=0x31637661|width=160|height=240|coded_width=160|coded_height=240|closed_captions=0|has_b_frames=1|sample_aspect_ratio=2:1|display_aspect_ratio=4:3|pix_fmt=yuv420p|level=12|color_range=tv|color_space=smpte170m|color_transfer=bt709|color_primaries=smpte170m|chroma_location=topleft|field_order=unknown|refs=2|is_avc=true|nal_length_size=4|id=N/A|r_frame_rate=30000/1001|avg_frame_rate=6372000/212521|time_base=1/90000|start_pts=0|start_time=0.000000|duration_ts=2125200|duration=23.613333|bit_rate=333874|max_bit_rate=N/A|bits_per_raw_sample=8|nb_frames=708|nb_read_frames=65|nb_read_packets=66|disposition:default=1|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:rotate=0|tag:creation_time=2008-05-12T20:59:27.000000Z|tag:language=eng|tag:handler_name=Apple Video Media Handler|tag:vendor_id=appl|tag:encoder=H.264 side_data|side_data_type=Display Matrix|displaymatrix=\n00000000: 131072 0 0\n00000001: 0 65536 0\n00000002: 0 0 1073741824\n|rotation=0 diff --git a/tests/ref/fate/movenc b/tests/ref/fate/movenc index fb39b9816..81ea75f37 100644 --- a/tests/ref/fate/movenc +++ b/tests/ref/fate/movenc @@ -1,18 +1,18 @@ write_data len 36, time nopts, type header atom ftyp -write_data len 2389, time nopts, type header atom - +write_data len 2429, time nopts, type header atom - write_data len 788, time 1000000, type sync atom moof write_data len 110, time nopts, type trailer atom - -5f401347fc3c771b819e2449d69d4861 3323 non-empty-moov +6f06e338c71468d56580df40ff265066 3363 non-empty-moov write_data len 36, time nopts, type header atom ftyp -write_data len 2721, time nopts, type header atom - +write_data len 2761, time nopts, type header atom - write_data len 908, time 966667, type sync atom moof write_data len 110, time nopts, type trailer atom - -4267feee527adf8cd4f7b36ac0fc0872 3775 non-empty-moov-elst +caf0876986b5f033efc0958c338289cc 3815 non-empty-moov-elst write_data len 36, time nopts, type header atom ftyp -write_data len 2629, time nopts, type header atom - +write_data len 2669, time nopts, type header atom - write_data len 908, time 1000000, type sync atom moof write_data len 110, time nopts, type trailer atom - -44077b9ad45f3e16fafe4e5ada54e9b0 3683 non-empty-moov-no-elst +e106084014ed245ed7c4a30f1d11a3ac 3723 non-empty-moov-no-elst write_data len 24, time nopts, type header atom ftyp write_data len 1171, time nopts, type header atom - write_data len 728, time 0, type sync atom moof diff --git a/tests/ref/fate/mpeg2-ticket6677 b/tests/ref/fate/mpeg2-ticket6677 index e963e32f2..2079a08c2 100644 --- a/tests/ref/fate/mpeg2-ticket6677 +++ b/tests/ref/fate/mpeg2-ticket6677 @@ -3,10 +3,10 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 8/9 -0, 0, 0, 1, 518400, 0xc1866f5f -0, 1, 1, 1, 518400, 0x9ba32764 -0, 2, 2, 1, 518400, 0xa9031bb8 -0, 3, 3, 1, 518400, 0x5e2c3502 -0, 4, 4, 1, 518400, 0xe860027a -0, 5, 5, 1, 518400, 0xa9152430 -0, 6, 6, 1, 518400, 0xb98dd9f7 +0, 1, 1, 1, 518400, 0xc1866f5f +0, 2, 2, 1, 518400, 0x9ba32764 +0, 4, 4, 1, 518400, 0xa9031bb8 +0, 5, 5, 1, 518400, 0x5e2c3502 +0, 6, 6, 1, 518400, 0xe860027a +0, 7, 7, 1, 518400, 0xa9152430 +0, 9, 9, 1, 518400, 0xb98dd9f7 diff --git a/tests/ref/fate/mss2-pal b/tests/ref/fate/mss2-pal index a2fb12fdf..ae5de4ec1 100644 --- a/tests/ref/fate/mss2-pal +++ b/tests/ref/fate/mss2-pal @@ -3,5 +3,5 @@ #codec_id 0: rawvideo #dimensions 0: 64x48 #sar 0: 0/1 -0, 0, 0, 0, 9216, 0xd3c106ef -0, 100, 100, 0, 9216, 0x8871f7c2 +0, 0, 0, 1, 9216, 0xd3c106ef +0, 100, 100, 1, 9216, 0x8871f7c2 diff --git a/tests/ref/fate/mss2-pals b/tests/ref/fate/mss2-pals index a2fb12fdf..ae5de4ec1 100644 --- a/tests/ref/fate/mss2-pals +++ b/tests/ref/fate/mss2-pals @@ -3,5 +3,5 @@ #codec_id 0: rawvideo #dimensions 0: 64x48 #sar 0: 0/1 -0, 0, 0, 0, 9216, 0xd3c106ef -0, 100, 100, 0, 9216, 0x8871f7c2 +0, 0, 0, 1, 9216, 0xd3c106ef +0, 100, 100, 1, 9216, 0x8871f7c2 diff --git a/tests/ref/fate/mss2-rgb555 b/tests/ref/fate/mss2-rgb555 index 10f1f03e7..95661e776 100644 --- a/tests/ref/fate/mss2-rgb555 +++ b/tests/ref/fate/mss2-rgb555 @@ -3,5 +3,5 @@ #codec_id 0: rawvideo #dimensions 0: 64x48 #sar 0: 0/1 -0, 0, 0, 0, 6144, 0x4145b7ae -0, 100, 100, 0, 6144, 0x3b2b38de +0, 0, 0, 1, 6144, 0x4145b7ae +0, 100, 100, 1, 6144, 0x3b2b38de diff --git a/tests/ref/fate/mss2-rgb555s b/tests/ref/fate/mss2-rgb555s index 10f1f03e7..95661e776 100644 --- a/tests/ref/fate/mss2-rgb555s +++ b/tests/ref/fate/mss2-rgb555s @@ -3,5 +3,5 @@ #codec_id 0: rawvideo #dimensions 0: 64x48 #sar 0: 0/1 -0, 0, 0, 0, 6144, 0x4145b7ae -0, 100, 100, 0, 6144, 0x3b2b38de +0, 0, 0, 1, 6144, 0x4145b7ae +0, 100, 100, 1, 6144, 0x3b2b38de diff --git a/tests/ref/fate/mxf-d10-user-comments b/tests/ref/fate/mxf-d10-user-comments index e78765020..13761fb0c 100644 --- a/tests/ref/fate/mxf-d10-user-comments +++ b/tests/ref/fate/mxf-d10-user-comments @@ -1 +1,28 @@ -b659c1204f8d04e2a5607af083590dca +6dc13ae283257e898e069e5041ac8435 *tests/data/fate/mxf-d10-user-comments.mxf_d10 +3782189 tests/data/fate/mxf-d10-user-comments.mxf_d10 +#extradata 0: 34, 0x716b05c4 +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: mpeg2video +#dimensions 0: 1280x720 +#sar 0: 3/4 +0, -1, 0, 1, 150000, 0x0547870d, S=1, 24, 0x5aa90ad0 +0, 0, 1, 1, 150000, 0xe80a1612, F=0x0 +0, 1, 2, 1, 150000, 0xc5c50e2f, F=0x0 +0, 2, 3, 1, 150000, 0x51e28a04, F=0x0 +0, 3, 4, 1, 150000, 0x9bbe6feb, F=0x0 +[FORMAT] +TAG:operational_pattern_ul=060e2b34.04010101.0d010201.01010900 +TAG:uid=adab4424-2f25-4dc7-92ff-29bd000c0000 +TAG:generation_uid=adab4424-2f25-4dc7-92ff-29bd000c0001 +TAG:company_name=FATE-company +TAG:product_name=FATE-test +TAG:product_version_num=0.0.0.0.0 +TAG:product_version=3.14159 +TAG:application_platform=Lavf +TAG:product_uid=adab4424-2f25-4dc7-92ff-29bd000c0002 +TAG:toolkit_version_num=0.0.0.0.0 +TAG:material_package_umid=0x060A2B340101010501010D001300000000000000000000000000000000000000 +TAG:comment_test=value +TAG:timecode=01:00:00:00 +[/FORMAT] diff --git a/tests/ref/fate/mxf-opatom-user-comments b/tests/ref/fate/mxf-opatom-user-comments index 1834b9e07..ec4fdff42 100644 --- a/tests/ref/fate/mxf-opatom-user-comments +++ b/tests/ref/fate/mxf-opatom-user-comments @@ -1 +1 @@ -892cf02e44bf7d61b6d6f01e41db9375 +8475bebf3448a972ae89ba59309fd7d6 diff --git a/tests/ref/fate/mxf-probe-applehdr10 b/tests/ref/fate/mxf-probe-applehdr10 new file mode 100644 index 000000000..49ca72cd1 --- /dev/null +++ b/tests/ref/fate/mxf-probe-applehdr10 @@ -0,0 +1,166 @@ +[STREAM] +index=0 +codec_name=prores +profile=0 +codec_type=video +codec_tag_string=apco +codec_tag=0x6f637061 +width=1280 +height=720 +coded_width=1280 +coded_height=720 +closed_captions=0 +has_b_frames=0 +sample_aspect_ratio=1:1 +display_aspect_ratio=16:9 +pix_fmt=yuv422p10 +level=-99 +color_range=tv +color_space=bt2020nc +color_transfer=smpte2084 +color_primaries=bt2020 +chroma_location=unspecified +field_order=progressive +refs=1 +id=N/A +r_frame_rate=60000/1001 +avg_frame_rate=0/0 +time_base=1001/60000 +start_pts=0 +start_time=0.000000 +duration_ts=5 +duration=0.083417 +bit_rate=N/A +max_bit_rate=N/A +bits_per_raw_sample=10 +nb_frames=N/A +nb_read_frames=N/A +nb_read_packets=N/A +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +TAG:file_package_umid=0x060A2B340101010501010D201300000040ECCE167353449C92D6F2693A9F1D75 +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=34000/50000 +red_y=16000/50000 +green_x=13250/50000 +green_y=34500/50000 +blue_x=7500/50000 +blue_y=3000/50000 +white_point_x=15635/50000 +white_point_y=16450/50000 +min_luminance=0/10000 +max_luminance=10000000/10000 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=100 +[/SIDE_DATA] +[/STREAM] +[STREAM] +index=1 +codec_name=pcm_s24le +profile=unknown +codec_type=audio +codec_tag_string=[0][0][0][0] +codec_tag=0x0000 +sample_fmt=s32 +sample_rate=48000 +channels=1 +channel_layout=unknown +bits_per_sample=24 +id=N/A +r_frame_rate=0/0 +avg_frame_rate=0/0 +time_base=1/48000 +start_pts=0 +start_time=0.000000 +duration_ts=4004 +duration=0.083417 +bit_rate=1152000 +max_bit_rate=N/A +bits_per_raw_sample=24 +nb_frames=N/A +nb_read_frames=N/A +nb_read_packets=N/A +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +TAG:file_package_umid=0x060A2B340101010501010D201300000040ECCE167353449C92D6F2693A9F1D75 +[/STREAM] +[STREAM] +index=2 +codec_name=pcm_s24le +profile=unknown +codec_type=audio +codec_tag_string=[0][0][0][0] +codec_tag=0x0000 +sample_fmt=s32 +sample_rate=48000 +channels=1 +channel_layout=unknown +bits_per_sample=24 +id=N/A +r_frame_rate=0/0 +avg_frame_rate=0/0 +time_base=1/48000 +start_pts=0 +start_time=0.000000 +duration_ts=4004 +duration=0.083417 +bit_rate=1152000 +max_bit_rate=N/A +bits_per_raw_sample=24 +nb_frames=N/A +nb_read_frames=N/A +nb_read_packets=N/A +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +TAG:file_package_umid=0x060A2B340101010501010D201300000040ECCE167353449C92D6F2693A9F1D75 +[/STREAM] +[FORMAT] +format_name=mxf +duration=0.083417 +bit_rate=30913698 +TAG:operational_pattern_ul=060e2b34.04010101.0d010201.01010900 +TAG:uid=0002475a-49e3-430b-85d9-3b35d180e3b5 +TAG:generation_uid=240f15ec-50ee-4285-83bf-7c17122fac0c +TAG:company_name=Apple Inc. +TAG:product_name=Compressor +TAG:product_version=4.4.7 (4.4.7) +TAG:product_uid=00000000-0000-0000-0000-000000000000 +TAG:modification_date=2020-09-08T16:18:57.036000Z +TAG:toolkit_version_num=3.8.0.171.1 +TAG:material_package_umid=0x060A2B340101010501010D201300000045843C9FE69D4B8FA90DDAAA1602A2E8 +TAG:timecode=00:01:15;26 +[/FORMAT] diff --git a/tests/ref/fate/mxf-probe-d10 b/tests/ref/fate/mxf-probe-d10 index b59fe4b59..4958c40b9 100644 --- a/tests/ref/fate/mxf-probe-d10 +++ b/tests/ref/fate/mxf-probe-d10 @@ -3,7 +3,6 @@ index=0 codec_name=mpeg2video profile=0 codec_type=video -codec_time_base=1/25 codec_tag_string=[0][0][0][0] codec_tag=0x0000 width=720 @@ -18,11 +17,10 @@ pix_fmt=yuv422p level=5 color_range=tv color_space=unknown -color_transfer=unknown +color_transfer=bt470m color_primaries=unknown chroma_location=topleft field_order=tt -timecode=N/A refs=1 id=N/A r_frame_rate=25/1 @@ -60,7 +58,6 @@ index=1 codec_name=pcm_s16le profile=unknown codec_type=audio -codec_time_base=1/48000 codec_tag_string=[0][0][0][0] codec_tag=0x0000 sample_fmt=s16 diff --git a/tests/ref/fate/mxf-probe-dnxhd b/tests/ref/fate/mxf-probe-dnxhd index 5d385e8a0..f4c198873 100644 --- a/tests/ref/fate/mxf-probe-dnxhd +++ b/tests/ref/fate/mxf-probe-dnxhd @@ -111,7 +111,6 @@ index=3 codec_name=dnxhd profile=1 codec_type=video -codec_time_base=0/1 codec_tag_string=[0][0][0][0] codec_tag=0x0000 width=640 @@ -124,13 +123,12 @@ sample_aspect_ratio=1:1 display_aspect_ratio=4:3 pix_fmt=yuv422p level=-99 -color_range=unknown +color_range=tv color_space=bt709 -color_transfer=unknown -color_primaries=unknown +color_transfer=bt709 +color_primaries=bt709 chroma_location=unspecified field_order=progressive -timecode=N/A refs=1 id=N/A r_frame_rate=24000/1001 @@ -173,9 +171,11 @@ TAG:project_name=UHD TAG:uid=784c8132-ae36-ed4d-b0ff-2edf1f3f2d92 TAG:generation_uid=b6bcfcab-70ff-7331-c47c-478869de11d2 TAG:application_platform=AAFSDK (MacOS X) +TAG:toolkit_version_num=1.1.0.0.0 TAG:modification_date=2016-09-18T19:25:25.000000Z TAG:product_uid=acfbf03a-4f42-a231-d0b7-c06ecd3d4ad7 TAG:product_version=Unknown version +TAG:product_version_num=8.6.0.0.1 TAG:product_name=Avid Media Composer 8.6.3.43955 TAG:company_name=Avid Technology, Inc. TAG:material_package_umid=0x060A2B340101010101010F001300000057DEEA1570665313060E2B347F7F2A80 diff --git a/tests/ref/fate/mxf-probe-dv25 b/tests/ref/fate/mxf-probe-dv25 index d0fb308c1..7cc4c88cf 100644 --- a/tests/ref/fate/mxf-probe-dv25 +++ b/tests/ref/fate/mxf-probe-dv25 @@ -3,7 +3,6 @@ index=0 codec_name=dvvideo profile=unknown codec_type=video -codec_time_base=1/25 codec_tag_string=[0][0][0][0] codec_tag=0x0000 width=720 @@ -16,13 +15,12 @@ sample_aspect_ratio=16:15 display_aspect_ratio=4:3 pix_fmt=yuv420p level=-99 -color_range=unknown +color_range=tv color_space=unknown -color_transfer=unknown +color_transfer=bt470m color_primaries=unknown chroma_location=topleft field_order=bb -timecode=N/A refs=1 id=N/A r_frame_rate=25/1 @@ -57,7 +55,6 @@ index=1 codec_name=pcm_s16le profile=unknown codec_type=audio -codec_time_base=1/48000 codec_tag_string=[0][0][0][0] codec_tag=0x0000 sample_fmt=s16 @@ -98,7 +95,6 @@ index=2 codec_name=pcm_s16le profile=unknown codec_type=audio -codec_time_base=1/48000 codec_tag_string=[0][0][0][0] codec_tag=0x0000 sample_fmt=s16 diff --git a/tests/ref/fate/mxf-reel_name b/tests/ref/fate/mxf-reel_name index cfe62dfdb..d50f0f699 100644 --- a/tests/ref/fate/mxf-reel_name +++ b/tests/ref/fate/mxf-reel_name @@ -1 +1 @@ -a788589c14f343dcc6d75aaaec0f0266 +ce49a0361d3f79106e1952d387eace51 diff --git a/tests/ref/fate/mxf-user-comments b/tests/ref/fate/mxf-user-comments index e91b23baa..5fcdc5806 100644 --- a/tests/ref/fate/mxf-user-comments +++ b/tests/ref/fate/mxf-user-comments @@ -1 +1 @@ -c6469c0ae2aaee602eacbc009080ae8e +956f653cd75e1a319569caec9df81b4f diff --git a/tests/ref/fate/nuv-rtjpeg b/tests/ref/fate/nuv-rtjpeg index b6f3b080d..bc5af1ca2 100644 --- a/tests/ref/fate/nuv-rtjpeg +++ b/tests/ref/fate/nuv-rtjpeg @@ -3,11 +3,11 @@ #codec_id 0: rawvideo #dimensions 0: 640x480 #sar 0: 1/1 -0, 118, 118, 0, 460800, 0x54aedafe -0, 152, 152, 0, 460800, 0xb7aa8b56 -0, 177, 177, 0, 460800, 0x283ea3b5 -0, 202, 202, 0, 460800, 0x283ea3b5 -0, 235, 235, 0, 460800, 0x10e577de -0, 269, 269, 0, 460800, 0x4e091ee2 -0, 302, 302, 0, 460800, 0x2ea88828 -0, 335, 335, 0, 460800, 0x4b7f4df0 +0, 118, 118, 1, 460800, 0x54aedafe +0, 152, 152, 1, 460800, 0xb7aa8b56 +0, 177, 177, 1, 460800, 0x283ea3b5 +0, 202, 202, 1, 460800, 0x283ea3b5 +0, 235, 235, 1, 460800, 0x10e577de +0, 269, 269, 1, 460800, 0x4e091ee2 +0, 302, 302, 1, 460800, 0x2ea88828 +0, 335, 335, 1, 460800, 0x4b7f4df0 diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt index 46ea0652f..aac3fa0e7 100644 --- a/tests/ref/fate/opt +++ b/tests/ref/fate/opt @@ -18,33 +18,33 @@ num64=1 flt=0.333333 dbl=0.333333 TestContext AVOptions: - -num E......... set num (from 0 to 100) (default 0) - -toggle E......... set toggle (from 0 to 1) (default 1) - -rational E......... set rational (from 0 to 10) (default 1/1) - -string E......... set string (default "default") - -escape E......... set escape str (default "\=,") - -flags E......... set flags (default cool) - cool E......... set cool flag - lame E......... set lame flag - mu E......... set mu flag - -size E......... set size (default "200x300") - -pix_fmt E......... set pixfmt (default 0bgr) - -sample_fmt E......... set samplefmt (default s16) - -video_rate E......... set videorate (default "25") - -duration E......... set duration (default 0.001) - -color E......... set color (default "pink") - -cl E......... set channel layout (default 0x137) - -bin E......... set binary value - -bin1 E......... set binary value - -bin2 E......... set binary value - -num64 E......... set num 64bit (from 0 to 100) (default 1) - -flt E......... set float (from 0 to 100) (default 0.333333) - -dbl E......... set double (from 0 to 100) (default 0.333333) - -bool1 E......... set boolean value (default auto) - -bool2 E......... set boolean value (default true) - -bool3 E......... set boolean value (default false) - -dict1 E......... set dictionary value - -dict2 E......... set dictionary value (default "happy=':-)'") + -num E.......... set num (from 0 to 100) (default 0) + -toggle E.......... set toggle (from 0 to 1) (default 1) + -rational E.......... set rational (from 0 to 10) (default 1/1) + -string E.......... set string (default "default") + -escape E.......... set escape str (default "\=,") + -flags E.......... set flags (default cool) + cool E.......... set cool flag + lame E.......... set lame flag + mu E.......... set mu flag + -size E.......... set size (default "200x300") + -pix_fmt E.......... set pixfmt (default 0bgr) + -sample_fmt E.......... set samplefmt (default s16) + -video_rate E.......... set videorate (default "25") + -duration E.......... set duration (default 0.001) + -color E.......... set color (default "pink") + -cl E.......... set channel layout (default 0x137) + -bin E.......... set binary value + -bin1 E.......... set binary value + -bin2 E.......... set binary value + -num64 E.......... set num 64bit (from 0 to 100) (default 1) + -flt E.......... set float (from 0 to 100) (default 0.333333) + -dbl E.......... set double (from 0 to 100) (default 0.333333) + -bool1 E.......... set boolean value (default auto) + -bool2 E.......... set boolean value (default true) + -bool3 E.......... set boolean value (default false) + -dict1 E.......... set dictionary value + -dict2 E.......... set dictionary value (default "happy=':-)'") Testing av_opt_is_set_to_default() name: num default:1 error: diff --git a/tests/ref/fate/psd-rgb48 b/tests/ref/fate/psd-rgb48 index f60cbab07..139b3c1df 100644 --- a/tests/ref/fate/psd-rgb48 +++ b/tests/ref/fate/psd-rgb48 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 128x128 #sar 0: 0/1 -0, 0, 0, 1, 49152, 0x0bc6503a +0, 0, 0, 1, 49152, 0x9fb6903c diff --git a/tests/ref/fate/psd-rgba64 b/tests/ref/fate/psd-rgba64 index e51686767..ed36c339d 100644 --- a/tests/ref/fate/psd-rgba64 +++ b/tests/ref/fate/psd-rgba64 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 128x128 #sar 0: 0/1 -0, 0, 0, 1, 49152, 0xb847fd73 +0, 0, 0, 1, 49152, 0x05856a20 diff --git a/tests/ref/fate/rgb24-mkv b/tests/ref/fate/rgb24-mkv index 34d028cbf..1ef70349b 100644 --- a/tests/ref/fate/rgb24-mkv +++ b/tests/ref/fate/rgb24-mkv @@ -1,5 +1,5 @@ -fdc02d700dbe99315a9f0d928a9b935e *tests/data/fate/rgb24-mkv.matroska -58213 tests/data/fate/rgb24-mkv.matroska +6244b8750d4155d3c9357bab26396ef9 *tests/data/fate/rgb24-mkv.matroska +58245 tests/data/fate/rgb24-mkv.matroska #tb 0: 1/10 #media_type 0: video #codec_id 0: rawvideo diff --git a/tests/ref/fate/segment-mp4-to-ts b/tests/ref/fate/segment-mp4-to-ts index 847c1a297..dfefb0af2 100644 --- a/tests/ref/fate/segment-mp4-to-ts +++ b/tests/ref/fate/segment-mp4-to-ts @@ -4,35 +4,35 @@ #codec_id 0: h264 #dimensions 0: 640x360 #sar 0: 1/1 -0, -7200, 0, 0, 22630, 0x9b109541, S=1, 1, 0x00e000e0 -0, -3600, 14400, 0, 4021, 0xbf7cdb02, F=0x0, S=1, 1, 0x00e000e0 -0, 0, 7200, 0, 1096, 0x4f162690, F=0x0, S=1, 1, 0x00e000e0 -0, 3600, 3600, 0, 687, 0x00394b95, F=0x0, S=1, 1, 0x00e000e0 -0, 7200, 10800, 0, 445, 0x08c3d065, F=0x0, S=1, 1, 0x00e000e0 -0, 10800, 28800, 0, 4212, 0x56d12b8f, F=0x0, S=1, 1, 0x00e000e0 -0, 14400, 21600, 0, 1117, 0xd521260b, F=0x0, S=1, 1, 0x00e000e0 -0, 18000, 18000, 0, 892, 0x4262bdbc, F=0x0, S=1, 1, 0x00e000e0 -0, 21600, 25200, 0, 480, 0x3be1ef0b, F=0x0, S=1, 1, 0x00e000e0 -0, 25200, 43200, 0, 4065, 0x40dee237, F=0x0, S=1, 1, 0x00e000e0 -0, 28800, 36000, 0, 962, 0x31a4ceb1, F=0x0, S=1, 1, 0x00e000e0 -0, 32400, 32400, 0, 651, 0xb2aa317a, F=0x0, S=1, 1, 0x00e000e0 -0, 36000, 39600, 0, 543, 0x9c4e0024, F=0x0, S=1, 1, 0x00e000e0 -0, 39600, 57600, 0, 4221, 0x77c23977, F=0x0, S=1, 1, 0x00e000e0 -0, 43200, 50400, 0, 1040, 0x482cfa34, F=0x0, S=1, 1, 0x00e000e0 -0, 46800, 46800, 0, 576, 0x2686136a, F=0x0, S=1, 1, 0x00e000e0 -0, 50400, 54000, 0, 607, 0xc53c2339, F=0x0, S=1, 1, 0x00e000e0 -0, 54000, 72000, 0, 4755, 0x2f642b58, F=0x0, S=1, 1, 0x00e000e0 -0, 57600, 64800, 0, 1182, 0xbe1a4847, F=0x0, S=1, 1, 0x00e000e0 -0, 61200, 61200, 0, 809, 0x8d948a4e, F=0x0, S=1, 1, 0x00e000e0 -0, 64800, 68400, 0, 656, 0x4fa03c2b, F=0x0, S=1, 1, 0x00e000e0 -0, 68400, 86400, 0, 26555, 0x5629b584, S=1, 1, 0x00e000e0 -0, 72000, 79200, 0, 1141, 0x761b31e8, F=0x0, S=1, 1, 0x00e000e0 -0, 75600, 75600, 0, 717, 0x57746351, F=0x0, S=1, 1, 0x00e000e0 -0, 79200, 82800, 0, 693, 0x78b24263, F=0x0, S=1, 1, 0x00e000e0 -0, 82800, 100800, 0, 3417, 0x560dbc89, F=0x0, S=1, 1, 0x00e000e0 -0, 86400, 93600, 0, 1128, 0xc0f1383c, F=0x0, S=1, 1, 0x00e000e0 -0, 90000, 90000, 0, 650, 0xc3ad485e, F=0x0, S=1, 1, 0x00e000e0 -0, 93600, 97200, 0, 766, 0xd3e9757d, F=0x0, S=1, 1, 0x00e000e0 +0, -7200, 0, 3600, 22630, 0x9b109541, S=1, 1, 0x00e000e0 +0, -3600, 14400, 3600, 4021, 0xbf7cdb02, F=0x0, S=1, 1, 0x00e000e0 +0, 0, 7200, 3600, 1096, 0x4f162690, F=0x0, S=1, 1, 0x00e000e0 +0, 3600, 3600, 3600, 687, 0x00394b95, F=0x0, S=1, 1, 0x00e000e0 +0, 7200, 10800, 3600, 445, 0x08c3d065, F=0x0, S=1, 1, 0x00e000e0 +0, 10800, 28800, 3600, 4212, 0x56d12b8f, F=0x0, S=1, 1, 0x00e000e0 +0, 14400, 21600, 3600, 1117, 0xd521260b, F=0x0, S=1, 1, 0x00e000e0 +0, 18000, 18000, 3600, 892, 0x4262bdbc, F=0x0, S=1, 1, 0x00e000e0 +0, 21600, 25200, 3600, 480, 0x3be1ef0b, F=0x0, S=1, 1, 0x00e000e0 +0, 25200, 43200, 3600, 4065, 0x40dee237, F=0x0, S=1, 1, 0x00e000e0 +0, 28800, 36000, 3600, 962, 0x31a4ceb1, F=0x0, S=1, 1, 0x00e000e0 +0, 32400, 32400, 3600, 651, 0xb2aa317a, F=0x0, S=1, 1, 0x00e000e0 +0, 36000, 39600, 3600, 543, 0x9c4e0024, F=0x0, S=1, 1, 0x00e000e0 +0, 39600, 57600, 3600, 4221, 0x77c23977, F=0x0, S=1, 1, 0x00e000e0 +0, 43200, 50400, 3600, 1040, 0x482cfa34, F=0x0, S=1, 1, 0x00e000e0 +0, 46800, 46800, 3600, 576, 0x2686136a, F=0x0, S=1, 1, 0x00e000e0 +0, 50400, 54000, 3600, 607, 0xc53c2339, F=0x0, S=1, 1, 0x00e000e0 +0, 54000, 72000, 3600, 4755, 0x2f642b58, F=0x0, S=1, 1, 0x00e000e0 +0, 57600, 64800, 3600, 1182, 0xbe1a4847, F=0x0, S=1, 1, 0x00e000e0 +0, 61200, 61200, 3600, 809, 0x8d948a4e, F=0x0, S=1, 1, 0x00e000e0 +0, 64800, 68400, 3600, 656, 0x4fa03c2b, F=0x0, S=1, 1, 0x00e000e0 +0, 68400, 86400, 3600, 26555, 0x5629b584, S=1, 1, 0x00e000e0 +0, 72000, 79200, 3600, 1141, 0x761b31e8, F=0x0, S=1, 1, 0x00e000e0 +0, 75600, 75600, 3600, 717, 0x57746351, F=0x0, S=1, 1, 0x00e000e0 +0, 79200, 82800, 3600, 693, 0x78b24263, F=0x0, S=1, 1, 0x00e000e0 +0, 82800, 100800, 3600, 3417, 0x560dbc89, F=0x0, S=1, 1, 0x00e000e0 +0, 86400, 93600, 3600, 1128, 0xc0f1383c, F=0x0, S=1, 1, 0x00e000e0 +0, 90000, 90000, 3600, 650, 0xc3ad485e, F=0x0, S=1, 1, 0x00e000e0 +0, 93600, 97200, 3600, 766, 0xd3e9757d, F=0x0, S=1, 1, 0x00e000e0 0, 97200, 115200, 3600, 4268, 0xec1235b5, F=0x0, S=1, 1, 0x00e000e0 0, 100800, 108000, 3600, 1119, 0x65f51fb7, F=0x0, S=1, 1, 0x00e000e0 0, 104400, 104400, 3600, 766, 0x213b78d3, F=0x0, S=1, 1, 0x00e000e0 diff --git a/tests/ref/fate/smjpeg-demux b/tests/ref/fate/smjpeg-demux index 042f9ff9e..cb2da6909 100644 --- a/tests/ref/fate/smjpeg-demux +++ b/tests/ref/fate/smjpeg-demux @@ -9,239 +9,239 @@ #sample_rate 1: 22050 #channel_layout 1: 4 #channel_layout_name 1: mono -0, 0, 0, 0, 734, 0x5a042c2c +0, 0, 0, 111, 734, 0x5a042c2c 1, 0, 0, 23, 260, 0x00000000 1, 23, 23, 23, 260, 0x00000000 1, 46, 46, 23, 260, 0xac9e0a9b 1, 69, 69, 23, 260, 0x89256f5b 1, 92, 92, 23, 260, 0x8e646e36 -0, 111, 111, 0, 763, 0xb5893f2f +0, 111, 111, 111, 763, 0xb5893f2f 1, 116, 116, 23, 260, 0x3ab972fc 1, 139, 139, 23, 260, 0xaea86bb2 1, 162, 162, 23, 260, 0x2366447a 1, 185, 185, 23, 260, 0x82c14f9c 1, 208, 208, 23, 260, 0xcdcf6fa8 -0, 222, 222, 0, 3023, 0x0f3907d3 +0, 222, 222, 111, 3023, 0x0f3907d3 1, 232, 232, 23, 260, 0xb3ed64bd 1, 255, 255, 23, 260, 0xac304b92 1, 278, 278, 23, 260, 0xc8bc553b 1, 301, 301, 23, 260, 0xd35572b4 1, 325, 325, 23, 260, 0x182f6190 -0, 333, 333, 0, 4800, 0x22e6e18a +0, 333, 333, 111, 4800, 0x22e6e18a 1, 348, 348, 23, 260, 0xbf9145c0 1, 371, 371, 23, 260, 0x0ec85a7e 1, 394, 394, 23, 260, 0x3684720e 1, 417, 417, 23, 260, 0xe985616a 1, 441, 441, 23, 260, 0x12b147dc -0, 444, 444, 0, 6417, 0x427adde5 +0, 444, 444, 111, 6417, 0x427adde5 1, 464, 464, 23, 260, 0xb8b55dd9 1, 487, 487, 23, 260, 0xfd4a7007 1, 510, 510, 23, 260, 0xfcc05c9a 1, 534, 534, 23, 260, 0x20f74aea -0, 555, 555, 0, 6776, 0x7a74c6ad +0, 555, 555, 111, 6776, 0x7a74c6ad 1, 557, 557, 23, 260, 0x025359ca 1, 580, 580, 23, 260, 0xace44ba1 1, 603, 603, 23, 260, 0x03506929 1, 626, 626, 23, 260, 0x8a926f17 1, 650, 650, 23, 260, 0x4a7061e7 -0, 666, 666, 0, 6808, 0x1f6eb7c3 +0, 666, 666, 111, 6808, 0x1f6eb7c3 1, 673, 673, 23, 260, 0xf8b66cc9 1, 696, 696, 23, 260, 0xe8c96dec 1, 719, 719, 23, 260, 0x672a54a6 1, 743, 743, 23, 260, 0xe97b5698 1, 766, 766, 23, 260, 0x377f684d -0, 777, 777, 0, 6726, 0x452087e6 +0, 777, 777, 111, 6726, 0x452087e6 1, 789, 789, 23, 260, 0xe9a66786 1, 812, 812, 23, 260, 0xf8e17080 1, 835, 835, 23, 260, 0x65eb662a 1, 859, 859, 23, 260, 0xd8d361e9 1, 882, 882, 23, 260, 0xb8115a0b -0, 888, 888, 0, 6829, 0xee82b109 +0, 888, 888, 111, 6829, 0xee82b109 1, 905, 905, 23, 260, 0xa5a85461 1, 928, 928, 23, 260, 0xf401663b 1, 952, 952, 23, 260, 0x042f714e 1, 975, 975, 23, 260, 0xdf195820 1, 998, 998, 23, 260, 0x0a67653c -0, 999, 999, 0, 7055, 0xf41f1108 +0, 999, 999, 111, 7055, 0xf41f1108 1, 1021, 1021, 23, 260, 0xe9b44d02 1, 1044, 1044, 23, 260, 0xbd4747b9 1, 1068, 1068, 23, 260, 0x3ef66738 1, 1091, 1091, 23, 260, 0x0f4a6e44 -0, 1111, 1111, 0, 6977, 0xf8fe1ede +0, 1111, 1111, 111, 6977, 0xf8fe1ede 1, 1114, 1114, 23, 260, 0xaa3d6eb6 1, 1137, 1137, 23, 260, 0xb9a46c4a 1, 1160, 1160, 23, 260, 0x4f974c2e 1, 1184, 1184, 23, 260, 0x9e714a00 1, 1207, 1207, 23, 260, 0x601a7152 -0, 1222, 1222, 0, 6942, 0x9ad105c6 +0, 1222, 1222, 111, 6942, 0x9ad105c6 1, 1230, 1230, 23, 260, 0xaf317064 1, 1253, 1253, 23, 260, 0x163d4829 1, 1277, 1277, 23, 260, 0xc56b4f1a 1, 1300, 1300, 23, 260, 0x7623729c 1, 1323, 1323, 23, 260, 0xa514694f -0, 1333, 1333, 0, 6926, 0xe239dad6 +0, 1333, 1333, 111, 6926, 0xe239dad6 1, 1346, 1346, 23, 260, 0x93ee4ad8 1, 1369, 1369, 23, 260, 0x6d8e573f 1, 1393, 1393, 23, 260, 0x13256d68 1, 1416, 1416, 23, 260, 0x187761a2 1, 1439, 1439, 23, 260, 0x426045e7 -0, 1444, 1444, 0, 6966, 0x81dcfab1 +0, 1444, 1444, 111, 6966, 0x81dcfab1 1, 1462, 1462, 23, 260, 0x7e7e5891 1, 1486, 1486, 23, 260, 0xd6926dcc 1, 1509, 1509, 23, 260, 0xf0196061 1, 1532, 1532, 23, 260, 0x7cac49a3 -0, 1555, 1555, 0, 6896, 0x31e6cc02 +0, 1555, 1555, 111, 6896, 0x31e6cc02 1, 1555, 1555, 23, 260, 0x24f4549a 1, 1578, 1578, 23, 260, 0x937f551d 1, 1602, 1602, 23, 260, 0x9bf462c5 1, 1625, 1625, 23, 260, 0xd1e07436 1, 1648, 1648, 23, 260, 0xdab36215 -0, 1666, 1666, 0, 6889, 0x1cc1006e +0, 1666, 1666, 111, 6889, 0x1cc1006e 1, 1671, 1671, 23, 260, 0xabc5662b 1, 1695, 1695, 23, 260, 0xa24f6bf1 1, 1718, 1718, 23, 260, 0x39e664b2 1, 1741, 1741, 23, 260, 0xf5dc54ca 1, 1764, 1764, 23, 260, 0xc3b16974 -0, 1777, 1777, 0, 6933, 0xc303f87f +0, 1777, 1777, 111, 6933, 0xc303f87f 1, 1787, 1787, 23, 260, 0x6cf46bca 1, 1811, 1811, 23, 260, 0x7a6b69b9 1, 1834, 1834, 23, 260, 0xc02f69b9 1, 1857, 1857, 23, 260, 0x7fc764a9 1, 1880, 1880, 23, 260, 0xd9705b09 -0, 1888, 1888, 0, 7034, 0xb4970a20 +0, 1888, 1888, 111, 7034, 0xb4970a20 1, 1904, 1904, 23, 260, 0x17b05f49 1, 1927, 1927, 23, 260, 0x10ad647c 1, 1950, 1950, 23, 260, 0xf9636d69 1, 1973, 1973, 23, 260, 0x622b5ad9 1, 1996, 1996, 23, 260, 0x175b646d -0, 1999, 1999, 0, 6961, 0xf064095d +0, 1999, 1999, 111, 6961, 0xf064095d 1, 2020, 2020, 23, 260, 0x722b5827 1, 2043, 2043, 23, 260, 0x83614974 1, 2066, 2066, 23, 260, 0x80366587 1, 2089, 2089, 23, 260, 0x050f6bf9 -0, 2111, 2111, 0, 7089, 0x5ba350f9 +0, 2111, 2111, 111, 7089, 0x5ba350f9 1, 2113, 2113, 23, 260, 0x949d6735 1, 2136, 2136, 23, 260, 0x62cd7184 1, 2159, 2159, 23, 260, 0x21e45713 1, 2182, 2182, 23, 260, 0x56314509 1, 2205, 2205, 23, 260, 0x7a1570d3 -0, 2222, 2222, 0, 7078, 0xa83f3e88 +0, 2222, 2222, 111, 7078, 0xa83f3e88 1, 2229, 2229, 23, 260, 0x205a6ffb 1, 2252, 2252, 23, 260, 0xead94483 1, 2275, 2275, 23, 260, 0x93c84f10 1, 2298, 2298, 23, 260, 0xdf45726f 1, 2321, 2321, 23, 260, 0x35016f1e -0, 2333, 2333, 0, 7147, 0xcda66cfc +0, 2333, 2333, 111, 7147, 0xcda66cfc 1, 2345, 2345, 23, 260, 0xa8114bcd 1, 2368, 2368, 23, 260, 0x14c45130 1, 2391, 2391, 23, 260, 0x97b07052 1, 2414, 2414, 23, 260, 0x039b6c77 1, 2438, 2438, 23, 260, 0x46f74635 -0, 2444, 2444, 0, 7173, 0xb7455859 +0, 2444, 2444, 111, 7173, 0xb7455859 1, 2461, 2461, 23, 260, 0x4116540d 1, 2484, 2484, 23, 260, 0x26747067 1, 2507, 2507, 23, 260, 0x37f16485 1, 2530, 2530, 23, 260, 0x631d4a33 1, 2554, 2554, 23, 260, 0x14ed598d -0, 2555, 2555, 0, 7213, 0x97b89994 +0, 2555, 2555, 111, 7213, 0x97b89994 1, 2577, 2577, 23, 260, 0x3f9349e7 1, 2600, 2600, 23, 260, 0x91295757 1, 2623, 2623, 23, 260, 0x95de72bc 1, 2647, 2647, 23, 260, 0xc7ee5ddb -0, 2666, 2666, 0, 7170, 0xca8b2948 +0, 2666, 2666, 111, 7170, 0xca8b2948 1, 2670, 2670, 23, 260, 0x38e965cd 1, 2693, 2693, 23, 260, 0xfae169e9 1, 2716, 2716, 23, 260, 0x9c226143 1, 2739, 2739, 23, 260, 0x1a804dbe 1, 2763, 2763, 23, 260, 0x4aeb633c -0, 2777, 2777, 0, 7174, 0xc7cc6bbb +0, 2777, 2777, 111, 7174, 0xc7cc6bbb 1, 2786, 2786, 23, 260, 0xa66e6bbb 1, 2809, 2809, 23, 260, 0x51d17109 1, 2832, 2832, 23, 260, 0x2bc86b9b 1, 2856, 2856, 23, 260, 0xe56e6378 1, 2879, 2879, 23, 260, 0x95665b47 -0, 2888, 2888, 0, 7235, 0xc2e68d2b +0, 2888, 2888, 111, 7235, 0xc2e68d2b 1, 2902, 2902, 23, 260, 0x1c255fdb 1, 2925, 2925, 23, 260, 0x3a2456cb 1, 2948, 2948, 23, 260, 0xe18e7270 1, 2972, 2972, 23, 260, 0x55b65c60 1, 2995, 2995, 23, 260, 0x62be6515 -0, 3000, 3000, 0, 7261, 0x8204a423 +0, 3000, 3000, 111, 7261, 0x8204a423 1, 3018, 3018, 23, 260, 0xdba25d09 1, 3041, 3041, 23, 260, 0xd7cc4e40 1, 3065, 3065, 23, 260, 0x335661be 1, 3088, 3088, 23, 260, 0xc3286de3 -0, 3111, 3111, 0, 7353, 0xacc7e7c0 +0, 3111, 3111, 111, 7353, 0xacc7e7c0 1, 3111, 3111, 23, 260, 0x47e76e35 1, 3134, 3134, 23, 260, 0x4b716f77 1, 3157, 3157, 23, 260, 0x0716519e 1, 3181, 3181, 23, 260, 0x032b4490 1, 3204, 3204, 23, 260, 0x15f067e8 -0, 3222, 3222, 0, 7065, 0x45035c5c +0, 3222, 3222, 111, 7065, 0x45035c5c 1, 3227, 3227, 23, 260, 0x16766ffa 1, 3250, 3250, 23, 260, 0xc94154ac 1, 3274, 3274, 23, 260, 0x74764bcd 1, 3297, 3297, 23, 260, 0x3fad6f8f 1, 3320, 3320, 23, 260, 0x5fa972a9 -0, 3333, 3333, 0, 7269, 0x72edbb76 +0, 3333, 3333, 111, 7269, 0x72edbb76 1, 3343, 3343, 23, 260, 0xde2a4b7b 1, 3366, 3366, 23, 260, 0xd8494408 1, 3390, 3390, 23, 260, 0x843d71a6 1, 3413, 3413, 23, 260, 0x87fd6b60 1, 3436, 3436, 23, 260, 0x1cc04a39 -0, 3444, 3444, 0, 7220, 0xb926772f +0, 3444, 3444, 111, 7220, 0xb926772f 1, 3459, 3459, 23, 260, 0x9ca24d94 1, 3482, 3482, 23, 260, 0x820a7087 1, 3506, 3506, 23, 260, 0x631166b2 1, 3529, 3529, 23, 260, 0x2f20492a 1, 3552, 3552, 23, 260, 0x932156d0 -0, 3555, 3555, 0, 7326, 0x0a66c632 +0, 3555, 3555, 111, 7326, 0x0a66c632 1, 3575, 3575, 23, 260, 0xdad54c90 1, 3599, 3599, 23, 260, 0xcce84fc9 1, 3622, 3622, 23, 260, 0xba317486 1, 3645, 3645, 23, 260, 0xf5a4626a -0, 3666, 3666, 0, 7225, 0xe39076ab +0, 3666, 3666, 111, 7225, 0xe39076ab 1, 3668, 3668, 23, 260, 0x324669fd 1, 3691, 3691, 23, 260, 0xc7d37113 1, 3715, 3715, 23, 260, 0xc6e0644f 1, 3738, 3738, 23, 260, 0x1b91522e 1, 3761, 3761, 23, 260, 0x9b84667d -0, 3777, 3777, 0, 7265, 0xe0209036 +0, 3777, 3777, 111, 7265, 0xe0209036 1, 3784, 3784, 23, 260, 0xed7e66eb 1, 3808, 3808, 23, 260, 0xaf806d1f 1, 3831, 3831, 23, 260, 0x13a66941 1, 3854, 3854, 23, 260, 0x13095a41 1, 3877, 3877, 23, 260, 0x5ba05491 -0, 3888, 3888, 0, 7337, 0x7a5dc093 +0, 3888, 3888, 111, 7337, 0x7a5dc093 1, 3900, 3900, 23, 260, 0xbf785887 1, 3924, 3924, 23, 260, 0x21965973 1, 3947, 3947, 23, 260, 0xd9aa7134 1, 3970, 3970, 23, 260, 0x3add62bc 1, 3993, 3993, 23, 260, 0xb9626260 -0, 4000, 4000, 0, 7246, 0x519a7a3c +0, 4000, 4000, 111, 7246, 0x519a7a3c 1, 4017, 4017, 23, 260, 0x5b08629f 1, 4040, 4040, 23, 260, 0x43a34659 1, 4063, 4063, 23, 260, 0x68575bda 1, 4086, 4086, 23, 260, 0xd98b715a 1, 4109, 4109, 23, 260, 0x7d816a77 -0, 4111, 4111, 0, 7266, 0x352c8078 +0, 4111, 4111, 111, 7266, 0x352c8078 1, 4133, 4133, 23, 260, 0x16af6ff1 1, 4156, 4156, 23, 260, 0x6d4557a7 1, 4179, 4179, 23, 260, 0x0743401a 1, 4202, 4202, 23, 260, 0x410563d8 -0, 4222, 4222, 0, 7323, 0xcaf69d7c +0, 4222, 4222, 111, 7323, 0xcaf69d7c 1, 4226, 4226, 23, 260, 0x561371d1 1, 4249, 4249, 23, 260, 0x3ef15872 1, 4272, 4272, 23, 260, 0x1dd04972 1, 4295, 4295, 23, 260, 0xed226c62 1, 4318, 4318, 23, 260, 0x20857046 -0, 4333, 4333, 0, 7309, 0x98c1e6f7 +0, 4333, 4333, 111, 7309, 0x98c1e6f7 1, 4342, 4342, 23, 260, 0xed7f4724 1, 4365, 4365, 23, 260, 0x7a7445cf 1, 4388, 4388, 23, 260, 0x06ad6a93 1, 4411, 4411, 23, 260, 0xdd1b6c91 1, 4435, 4435, 23, 260, 0x05b94d27 -0, 4444, 4444, 0, 7121, 0x913d5bd6 +0, 4444, 4444, 111, 7121, 0x913d5bd6 1, 4458, 4458, 23, 260, 0x12cc5062 1, 4481, 4481, 23, 260, 0x44526d0f 1, 4504, 4504, 23, 260, 0xf2ac6d95 diff --git a/tests/ref/fate/smvjpeg b/tests/ref/fate/smvjpeg index 360fad659..0ab4f2130 100644 --- a/tests/ref/fate/smvjpeg +++ b/tests/ref/fate/smvjpeg @@ -2,7 +2,7 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 128x160 -#sar 0: 0/1 +#sar 0: 72/72 0, 0, 0, 1, 30720, 0x3a821807 0, 1, 1, 1, 30720, 0x95168e5d 0, 2, 2, 1, 30720, 0xd4d98e45 diff --git a/tests/ref/fate/sub-dvb b/tests/ref/fate/sub-dvb new file mode 100644 index 000000000..cbd1801d6 --- /dev/null +++ b/tests/ref/fate/sub-dvb @@ -0,0 +1,75 @@ +#tb 0: 1/1000000 +#media_type 0: subtitle +#codec_id 0: dvb_subtitle +0, 15600000, 15600000, 159000, 1168, 0xd0f89d82 +0, 15759000, 15759000, 159000, 14, 0x064900eb +0, 15760000, 15760000, 239000, 1544, 0xe60f1751 +0, 15999000, 15999000, 239000, 14, 0x0729010b +0, 16000000, 16000000, 339000, 1658, 0xbe343093 +0, 16339000, 16339000, 339000, 14, 0x0809012b +0, 16340000, 16340000, 599000, 2343, 0xc68f07ef +0, 16939000, 16939000, 599000, 14, 0x08e9014b +0, 16940000, 16940000, 459000, 2568, 0x0ee657b1 +0, 17399000, 17399000, 459000, 14, 0x09c9016b +0, 17400000, 17400000, 359000, 3422, 0xba5b63ce +0, 17759000, 17759000, 359000, 14, 0x0aa9018b +0, 17760000, 17760000, 219000, 5078, 0x95b19902 +0, 17979000, 17979000, 219000, 14, 0x0b8901ab +0, 17980000, 17980000, 959000, 5808, 0xc9717b89 +0, 18939000, 18939000, 959000, 14, 0x0c6901cb +0, 18940000, 18940000, 219000, 6015, 0x0becbfac +0, 19159000, 19159000, 219000, 14, 0x064900eb +0, 19160000, 19160000, 259000, 6519, 0xfcd24d26 +0, 19419000, 19419000, 259000, 14, 0x0729010b +0, 19420000, 19420000, 99000, 7061, 0xf0320408 +0, 19519000, 19519000, 99000, 14, 0x0809012b +0, 19520000, 19520000, 219000, 4773, 0x66c93074 +0, 19739000, 19739000, 219000, 14, 0x08e9014b +0, 19740000, 19740000, 219000, 5546, 0x06052c81 +0, 19959000, 19959000, 219000, 14, 0x09c9016b +0, 19960000, 19960000, 239000, 5754, 0x904f7325 +0, 20199000, 20199000, 239000, 14, 0x0aa9018b +0, 20200000, 20200000, 139000, 6099, 0xe30cde07 +0, 20339000, 20339000, 139000, 14, 0x0b8901ab +0, 20340000, 20340000, 799000, 6839, 0x770fcb6c +0, 21139000, 21139000, 799000, 14, 0x0c6901cb +0, 21140000, 21140000, 239000, 4744, 0xa91e1b41 +0, 21379000, 21379000, 239000, 14, 0x064900eb +0, 21380000, 21380000, 339000, 5824, 0xcf6d782b +0, 21719000, 21719000, 339000, 14, 0x0729010b +0, 21720000, 21720000, 1439000, 6212, 0xabf8f7cf +0, 23159000, 23159000, 1439000, 14, 0x0809012b +0, 23160000, 23160000, 1319000, 7082, 0xd7ca10f2 +0, 24479000, 24479000, 1319000, 14, 0x08e9014b +0, 24480000, 24480000, 219000, 5345, 0x12b2cae0 +0, 24699000, 24699000, 219000, 14, 0x09c9016b +0, 24700000, 24700000, 219000, 5765, 0xc7d46192 +0, 24919000, 24919000, 219000, 14, 0x0aa9018b +0, 24920000, 24920000, 599000, 6557, 0xcb995d30 +0, 25519000, 25519000, 599000, 14, 0x0b8901ab +0, 25520000, 25520000, 219000, 7091, 0xe6ea0559 +0, 25739000, 25739000, 219000, 14, 0x0c6901cb +0, 25740000, 25740000, 239000, 7305, 0xb66c404e +0, 25979000, 25979000, 239000, 14, 0x064900eb +0, 25980000, 25980000, 359000, 7590, 0x0cc2a481 +0, 26339000, 26339000, 359000, 14, 0x0729010b +0, 26340000, 26340000, 219000, 4629, 0xe18cfea8 +0, 26559000, 26559000, 219000, 14, 0x0809012b +0, 26560000, 26560000, 719000, 4785, 0x82043fc0 +0, 27279000, 27279000, 719000, 14, 0x08e9014b +0, 27280000, 27280000, 459000, 6061, 0xbde7d245 +0, 27739000, 27739000, 459000, 14, 0x09c9016b +0, 27740000, 27740000, 239000, 6301, 0x92d01a51 +0, 27979000, 27979000, 239000, 14, 0x0aa9018b +0, 27980000, 27980000, 99000, 6736, 0xbd25a134 +0, 28079000, 28079000, 99000, 14, 0x0b8901ab +0, 28080000, 28080000, 219000, 7214, 0x7ef93c13 +0, 28299000, 28299000, 219000, 14, 0x0c6901cb +0, 28300000, 28300000, 239000, 7366, 0x5bed7fcd +0, 28539000, 28539000, 239000, 14, 0x064900eb +0, 28540000, 28540000, 599000, 4564, 0x7f4c014b +0, 29139000, 29139000, 599000, 14, 0x0729010b +0, 29140000, 29140000, 219000, 4637, 0x682626b7 +0, 29359000, 29359000, 219000, 14, 0x0809012b +0, 29360000, 29360000, 1679000, 5358, 0x29e30c48 +0, 31039000, 31039000, 1679000, 14, 0x08e9014b diff --git a/tests/ref/fate/sub-ttmlenc b/tests/ref/fate/sub-ttmlenc new file mode 100644 index 000000000..51eab9781 --- /dev/null +++ b/tests/ref/fate/sub-ttmlenc @@ -0,0 +1,122 @@ + + + +
+

Don't show this text it may be used to insert hidden data

+

SubRip subtitles capability tester 1.3o by ale5000
Use VLC 1.1 or higher as reference for most things and MPC Home Cinema for others
This text should be blue
This text should be red
This text should be black
If you see this with the normal font, the player don't (fully) support font face

+

Hidden

+

This text should be small
This text should be normal
This text should be big

+

This should be an E with an accent: È
日本語
This text should be bold, italics and underline
This text should be small and green
This text should be small and red
This text should be big and brown

+

This line should be bold
This line should be italics
This line should be underline
This line should be strikethrough
Both lines
should be underline

+

>
It would be a good thing to
hide invalid html tags that are closed and show the text in them
but show un-closed invalid html tags
Show not opened tags
<

+

and also
hide invalid html tags with parameters that are closed and show the text in them
but show un-closed invalid html tags
This text should be showed underlined without problems also: 2<3,5>1,4<6
This shouldn't be underlined

+

This text should be in the normal position...

+

This text should NOT be in the normal position

+

Implementation is the same of the ASS tag
This text should be at the
top and horizontally centered

+

This text should be at the
middle and horizontally centered

+

This text should be at the
bottom and horizontally centered

+

This text should be at the
top and horizontally at the left

+

This text should be at the
middle and horizontally at the left
(The second position must be ignored)

+

This text should be at the
bottom and horizontally at the left

+

This text should be at the
top and horizontally at the right

+

This text should be at the
middle and horizontally at the right

+

This text should be at the
bottom and horizontally at the right

+

This could be the most difficult thing to implement

+

First text

+

Second, it shouldn't overlap first

+

Third, it should replace second

+

Fourth, it shouldn't overlap first and third

+

Fifth, it should replace third

+

Sixth, it shouldn't be
showed overlapped

+

TEXT 1 (bottom)

+

text 2

+

Hide these tags:
also hide these tags:
but show this: {normal text}

+


\ N is a forced line break
\ h is a hard space
Normal spaces at the start and at the end of the line are trimmed while hard spaces are not trimmed.
The\hline\hwill\hnever\hbreak\hautomatically\hright\hbefore\hor\hafter\ha\hhard\hspace.\h:-D

+


\h\h\h\h\hA (05 hard spaces followed by a letter)
A (Normal spaces followed by a letter)
A (No hard spaces followed by a letter)

+

\h\h\h\h\hA (05 hard spaces followed by a letter)
A (Normal spaces followed by a letter)
A (No hard spaces followed by a letter)
Show this: \TEST and this: \-)

+


A letter followed by 05 hard spaces: A\h\h\h\h\h
A letter followed by normal spaces: A
A letter followed by no hard spaces: A
05 hard spaces between letters: A\h\h\h\h\hA
5 normal spaces between letters: A A

^--Forced line break

+

Both line should be strikethrough,
yes.
Correctly closed tags
should be hidden.

+

It shouldn't be strikethrough,
not opened tag showed as text.
Not opened tag showed as text.

+

Three lines should be strikethrough,
yes.
Not closed tags showed as text

+

Both line should be strikethrough but
the wrong closing tag should be showed

+
+ +
diff --git a/tests/ref/fate/sws-floatimg-cmp b/tests/ref/fate/sws-floatimg-cmp new file mode 100644 index 000000000..251042f1c --- /dev/null +++ b/tests/ref/fate/sws-floatimg-cmp @@ -0,0 +1,120 @@ +gbrpf32le -> yuv444p16le -> gbrpf32le +avg diff: 0.000125 +min diff: 0.000000 +max diff: 0.000501 +gbrpf32le -> yuv444p -> gbrpf32le +avg diff: 0.001804 +min diff: 0.000000 +max diff: 0.006399 +gbrpf32le -> yuv444p9le -> gbrpf32le +avg diff: 0.000906 +min diff: 0.000000 +max diff: 0.003313 +gbrpf32le -> yuv444p10le -> gbrpf32le +avg diff: 0.000467 +min diff: 0.000000 +max diff: 0.001912 +gbrpf32le -> yuv444p12le -> gbrpf32le +avg diff: 0.000166 +min diff: 0.000000 +max diff: 0.000802 +gbrpf32le -> yuv444p14le -> gbrpf32le +avg diff: 0.000127 +min diff: 0.000000 +max diff: 0.000524 +gbrpf32le -> rgb24 -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> bgr24 -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> rgba -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> bgra -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> argb -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> abgr -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> 0rgb -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> 0bgr -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> rgb0 -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> bgr0 -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> rgb48le -> gbrpf32le +avg diff: 0.000249 +min diff: 0.000000 +max diff: 0.000990 +gbrpf32le -> bgr48le -> gbrpf32le +avg diff: 0.000249 +min diff: 0.000000 +max diff: 0.000990 +gbrpf32le -> rgba64le -> gbrpf32le +avg diff: 0.000249 +min diff: 0.000000 +max diff: 0.000990 +gbrpf32le -> bgra64le -> gbrpf32le +avg diff: 0.000249 +min diff: 0.000000 +max diff: 0.000990 +gbrpf32le -> gbrp -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> gbrap -> gbrpf32le +avg diff: 0.001011 +min diff: 0.000000 +max diff: 0.004229 +gbrpf32le -> gbrp9le -> gbrpf32le +avg diff: 0.000545 +min diff: 0.000000 +max diff: 0.002245 +gbrpf32le -> gbrp10le -> gbrpf32le +avg diff: 0.000350 +min diff: 0.000000 +max diff: 0.001475 +gbrpf32le -> gbrap10le -> gbrpf32le +avg diff: 0.000350 +min diff: 0.000000 +max diff: 0.001475 +gbrpf32le -> gbrp12le -> gbrpf32le +avg diff: 0.000260 +min diff: 0.000000 +max diff: 0.001135 +gbrpf32le -> gbrap12le -> gbrpf32le +avg diff: 0.000260 +min diff: 0.000000 +max diff: 0.001135 +gbrpf32le -> gbrp14le -> gbrpf32le +avg diff: 0.000253 +min diff: 0.000000 +max diff: 0.001068 +gbrpf32le -> gbrp16le -> gbrpf32le +avg diff: 0.000249 +min diff: 0.000000 +max diff: 0.000990 +gbrpf32le -> gbrap16le -> gbrpf32le +avg diff: 0.000249 +min diff: 0.000000 +max diff: 0.000990 diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index bc9a0d874..c3cccfa49 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -57,6 +57,8 @@ isNBPS: nv20le p010be p010le + x2rgb10be + x2rgb10le xyz12be xyz12le y210be @@ -141,6 +143,7 @@ isBE: rgb555be rgb565be rgba64be + x2rgb10be xyz12be y210be ya16be @@ -436,6 +439,8 @@ isRGB: rgb8 rgba64be rgba64le + x2rgb10be + x2rgb10le Gray: gray @@ -582,6 +587,8 @@ AnyRGB: rgb8 rgba64be rgba64le + x2rgb10be + x2rgb10le ALPHA: ayuv64be @@ -689,6 +696,8 @@ Packed: rgba64le uyvy422 uyyvyy411 + x2rgb10be + x2rgb10le xyz12be xyz12le y210be @@ -853,6 +862,8 @@ PackedRGB: rgb8 rgba64be rgba64le + x2rgb10be + x2rgb10le PlanarRGB: gbrap diff --git a/tests/ref/fate/time_base b/tests/ref/fate/time_base index 710fde100..28815d082 100644 --- a/tests/ref/fate/time_base +++ b/tests/ref/fate/time_base @@ -1 +1 @@ -42863a53f6c63efbc8c5a2eb76f13f5f +78ac0348027b75d73acb8bea14e67a59 diff --git a/tests/ref/fate/unknown_layout-ac3 b/tests/ref/fate/unknown_layout-ac3 index d332efcec..719a44aac 100644 --- a/tests/ref/fate/unknown_layout-ac3 +++ b/tests/ref/fate/unknown_layout-ac3 @@ -1 +1 @@ -bbb7550d6d93973c10f4ee13c87cf799 +febdb165cfd6cba375aa086195e61213 diff --git a/tests/ref/fate/url b/tests/ref/fate/url index 08e80def7..8489d1096 100644 --- a/tests/ref/fate/url +++ b/tests/ref/fate/url @@ -79,6 +79,26 @@ Testing ff_make_absolute_url: http://server/foo/bar ..doubledotfile => http://server/foo/..doubledotfile http://server/foo/bar double..dotfile => http://server/foo/double..dotfile http://server/foo/bar doubledotfile.. => http://server/foo/doubledotfile.. + file1 file2 => file2 + dir/file1 file2 => dir/file2 + dir/file1 ../file2 => dir/../file2 + dir\file1 file2 => file2 + dir\file1 file2 DOS dir\file2 + \\srv\shr\file ..\..\dummy => ..\..\dummy + \\srv\shr\file ..\..\dummy DOS \\srv\shr\..\..\dummy + \\srv\shr\file dummy => dummy + \\srv\shr\file dummy DOS \\srv\shr\dummy + \\srv\shr\file \\srv2\shr2\file2 => \\srv2\shr2\file2 + \\srv\shr\file d:/file => d:/file + C:\dir\a ..\file => C:..\file + C:\dir\a ..\file DOS C:\dir\..\file + C:\dir\a \\srv\shr\file => C:\\srv\shr\file + C:\dir\a \\srv\shr\file DOS \\srv\shr\file + C:\dir\a d:\file => d:\file + http://a/b \\srv\shr\file => http://a/\\srv\shr\file + http://a/b //srv/shr/file => http://srv/shr/file + http://a/b d:\file => d:\file + http://a/b C:/file => C:/file http://a/b/c/d;p?q g:h => g:h http://a/b/c/d;p?q g => http://a/b/c/g http://a/b/c/d;p?q ./g => http://a/b/c/g diff --git a/tests/ref/fate/vp9-tiling-pedestrian b/tests/ref/fate/vp9-tiling-pedestrian index 4b25a2914..173869faa 100644 --- a/tests/ref/fate/vp9-tiling-pedestrian +++ b/tests/ref/fate/vp9-tiling-pedestrian @@ -7,5 +7,5 @@ #dimensions 0: 1920x1080 #sar 0: 1/1 #stream#, dts, pts, duration, size, hash -0, 0, 0, 0, 3110400, 1e6c2e768a5107e57e6d626f0511193a -0, 40, 40, 0, 3110400, 972d3e2b5ee2e3b0907218a243e4cb7d +0, 0, 0, 1, 3110400, 1e6c2e768a5107e57e6d626f0511193a +0, 40, 40, 1, 3110400, 972d3e2b5ee2e3b0907218a243e4cb7d diff --git a/tests/ref/fate/wav-chapters b/tests/ref/fate/wav-chapters new file mode 100644 index 000000000..b47c56078 --- /dev/null +++ b/tests/ref/fate/wav-chapters @@ -0,0 +1,45 @@ +[CHAPTER] +id=1 +time_base=1/48000 +start=148992 +start_time=3.104000 +end=226560 +end_time=4.720000 +TAG:title=01 +[/CHAPTER] +[CHAPTER] +id=2 +time_base=1/48000 +start=226560 +start_time=4.720000 +end=301728 +end_time=6.286000 +TAG:title=02 +[/CHAPTER] +[CHAPTER] +id=3 +time_base=1/48000 +start=301728 +start_time=6.286000 +end=314016 +end_time=6.542000 +TAG:title=03 +[/CHAPTER] +[CHAPTER] +id=4 +time_base=1/48000 +start=314016 +start_time=6.542000 +end=396528 +end_time=8.261000 +TAG:title=04 +[/CHAPTER] +[CHAPTER] +id=5 +time_base=1/48000 +start=396528 +start_time=8.261000 +end=614464 +end_time=12.801333 +TAG:title=05 +[/CHAPTER] diff --git a/tests/ref/lavf-fate/av1.mkv b/tests/ref/lavf-fate/av1.mkv index bc568a600..2c0c6d31f 100644 --- a/tests/ref/lavf-fate/av1.mkv +++ b/tests/ref/lavf-fate/av1.mkv @@ -1,3 +1,3 @@ -bd676bfc89422755920099ec6ebdebe6 *tests/data/lavf-fate/lavf.av1.mkv -55657 tests/data/lavf-fate/lavf.av1.mkv +77138a0e07ebd1c6ff2f69305e2f5c79 *tests/data/lavf-fate/lavf.av1.mkv +55653 tests/data/lavf-fate/lavf.av1.mkv tests/data/lavf-fate/lavf.av1.mkv CRC=0x7c27cc15 diff --git a/tests/ref/lavf-fate/av1.mp4 b/tests/ref/lavf-fate/av1.mp4 index 38d2a80af..ef174589b 100644 --- a/tests/ref/lavf-fate/av1.mp4 +++ b/tests/ref/lavf-fate/av1.mp4 @@ -1,3 +1,3 @@ -0388467214421a19ba65d10a74dc35c0 *tests/data/lavf-fate/lavf.av1.mp4 -55936 tests/data/lavf-fate/lavf.av1.mp4 +d6afef355cf1bcf1a71b9cfb98c32fba *tests/data/lavf-fate/lavf.av1.mp4 +55976 tests/data/lavf-fate/lavf.av1.mp4 tests/data/lavf-fate/lavf.av1.mp4 CRC=0x7c27cc15 diff --git a/tests/ref/lavf-fate/h264.mp4 b/tests/ref/lavf-fate/h264.mp4 index bb52f4575..a9c3823c2 100644 --- a/tests/ref/lavf-fate/h264.mp4 +++ b/tests/ref/lavf-fate/h264.mp4 @@ -1,3 +1,3 @@ -6d158b25efe7391c803f6f61c7a80aa0 *tests/data/lavf-fate/lavf.h264.mp4 -547908 tests/data/lavf-fate/lavf.h264.mp4 +fe299ea5205b71a48281f917b1256a5d *tests/data/lavf-fate/lavf.h264.mp4 +547928 tests/data/lavf-fate/lavf.h264.mp4 tests/data/lavf-fate/lavf.h264.mp4 CRC=0x9da2c999 diff --git a/tests/ref/lavf-fate/vp8.ogg b/tests/ref/lavf-fate/vp8.ogg index 1a4082556..06240160b 100644 --- a/tests/ref/lavf-fate/vp8.ogg +++ b/tests/ref/lavf-fate/vp8.ogg @@ -1,3 +1,3 @@ -c56d8dce728d46d4f0ab4c7cc9f86abc *tests/data/lavf-fate/lavf.vp8.ogg +20f1e9b1714513a0ba85ca636e818784 *tests/data/lavf-fate/lavf.vp8.ogg 95009 tests/data/lavf-fate/lavf.vp8.ogg -tests/data/lavf-fate/lavf.vp8.ogg CRC=0x8c067a66 +tests/data/lavf-fate/lavf.vp8.ogg CRC=0xa5857a66 diff --git a/tests/ref/lavf/gbrap.fits b/tests/ref/lavf/gbrap.fits index 57c71e179..4662c3e6c 100644 --- a/tests/ref/lavf/gbrap.fits +++ b/tests/ref/lavf/gbrap.fits @@ -1,3 +1,3 @@ -28eb102547b82acca57ef097a6c639d8 *tests/data/lavf/lavf.gbrap.fits +d953a6a2c719de9d922d0624a7eb796b *tests/data/lavf/lavf.gbrap.fits 10224000 tests/data/lavf/lavf.gbrap.fits tests/data/lavf/lavf.gbrap.fits CRC=0x883af247 diff --git a/tests/ref/lavf/gbrap16be.fits b/tests/ref/lavf/gbrap16be.fits index 030a6d90e..7206d242c 100644 --- a/tests/ref/lavf/gbrap16be.fits +++ b/tests/ref/lavf/gbrap16be.fits @@ -1,3 +1,3 @@ -ff5fb24a67aeabd4f56088ca8b03d8b0 *tests/data/lavf/lavf.gbrap16be.fits +e9a04d25104fc43ddc62b58eb33ecd08 *tests/data/lavf/lavf.gbrap16be.fits 20376000 tests/data/lavf/lavf.gbrap16be.fits tests/data/lavf/lavf.gbrap16be.fits CRC=0xa981271b diff --git a/tests/ref/lavf/gbrp.fits b/tests/ref/lavf/gbrp.fits index 2b60ddb33..54c239687 100644 --- a/tests/ref/lavf/gbrp.fits +++ b/tests/ref/lavf/gbrp.fits @@ -1,3 +1,3 @@ -dae49b5f6eb58981ba91e3e108355717 *tests/data/lavf/lavf.gbrp.fits +3952247f7f9669f968826c909852bbd7 *tests/data/lavf/lavf.gbrp.fits 7704000 tests/data/lavf/lavf.gbrp.fits tests/data/lavf/lavf.gbrp.fits CRC=0x80745c5e diff --git a/tests/ref/lavf/gbrp16be.fits b/tests/ref/lavf/gbrp16be.fits index 9aa9db60a..5bec5e80f 100644 --- a/tests/ref/lavf/gbrp16be.fits +++ b/tests/ref/lavf/gbrp16be.fits @@ -1,3 +1,3 @@ -693ea80c33eb9b348db27a0bc4a5cc8a *tests/data/lavf/lavf.gbrp16be.fits +caf72fec125df9c7a1d59c9d1bc70b80 *tests/data/lavf/lavf.gbrp16be.fits 15336000 tests/data/lavf/lavf.gbrp16be.fits tests/data/lavf/lavf.gbrp16be.fits CRC=0x9573fb2b diff --git a/tests/ref/lavf/gray.fits b/tests/ref/lavf/gray.fits index ce6783b7c..410467506 100644 --- a/tests/ref/lavf/gray.fits +++ b/tests/ref/lavf/gray.fits @@ -1,3 +1,3 @@ -d76b46a5a336b56f73451817cdf3897c *tests/data/lavf/lavf.gray.fits +e690dc6db533b87f5f843737007ed070 *tests/data/lavf/lavf.gray.fits 2664000 tests/data/lavf/lavf.gray.fits tests/data/lavf/lavf.gray.fits CRC=0x7aa0122f diff --git a/tests/ref/lavf/gray16be.fits b/tests/ref/lavf/gray16be.fits index 058fa4ad1..a0526f3db 100644 --- a/tests/ref/lavf/gray16be.fits +++ b/tests/ref/lavf/gray16be.fits @@ -1,3 +1,3 @@ -15e85a553bbd07783f92377ed369308b *tests/data/lavf/lavf.gray16be.fits +262658f437a256cd843db2b401bc20a9 *tests/data/lavf/lavf.gray16be.fits 5184000 tests/data/lavf/lavf.gray16be.fits -tests/data/lavf/lavf.gray16be.fits CRC=0x8cdcbeb2 +tests/data/lavf/lavf.gray16be.fits CRC=0x737e8998 diff --git a/tests/ref/lavf/ismv b/tests/ref/lavf/ismv index e7361705f..ac7f72ba3 100644 --- a/tests/ref/lavf/ismv +++ b/tests/ref/lavf/ismv @@ -1,9 +1,9 @@ -4c6bc5ac805a76bbbd886a69d2e61554 *tests/data/lavf/lavf.ismv +48fb8d7a5d19bd60f3a49ccf4b7d6593 *tests/data/lavf/lavf.ismv 313169 tests/data/lavf/lavf.ismv tests/data/lavf/lavf.ismv CRC=0x9d9a638a -18678627921460328ea3fed238d0d57d *tests/data/lavf/lavf.ismv +d19cd8e310a2e94fe0a0d11c5dc29217 *tests/data/lavf/lavf.ismv 322075 tests/data/lavf/lavf.ismv tests/data/lavf/lavf.ismv CRC=0xe8130120 -b9a858caf55b1eff2273e746e9f72dc4 *tests/data/lavf/lavf.ismv +3b6023766845b51b075aed474c00f73c *tests/data/lavf/lavf.ismv 312546 tests/data/lavf/lavf.ismv tests/data/lavf/lavf.ismv CRC=0x9d9a638a diff --git a/tests/ref/lavf/mp4 b/tests/ref/lavf/mp4 index 848281238..0becfd34f 100644 --- a/tests/ref/lavf/mp4 +++ b/tests/ref/lavf/mp4 @@ -1,9 +1,9 @@ -ebca72c186a4f3ba9bb17d9cb5b74fef *tests/data/lavf/lavf.mp4 -312457 tests/data/lavf/lavf.mp4 +71c4ff2e747fe6f8169ff29244fe181d *tests/data/lavf/lavf.mp4 +312477 tests/data/lavf/lavf.mp4 tests/data/lavf/lavf.mp4 CRC=0x9d9a638a -9944512475d82d2d601f3c96101bdf9c *tests/data/lavf/lavf.mp4 -321343 tests/data/lavf/lavf.mp4 +3c5734ad6d05e4afc2ccefef1385e882 *tests/data/lavf/lavf.mp4 +321363 tests/data/lavf/lavf.mp4 tests/data/lavf/lavf.mp4 CRC=0xe8130120 -7b3e71f294901067046c09f03a426bdc *tests/data/lavf/lavf.mp4 -312001 tests/data/lavf/lavf.mp4 +07348e31d11d92396e1eedc48ea14802 *tests/data/lavf/lavf.mp4 +312021 tests/data/lavf/lavf.mp4 tests/data/lavf/lavf.mp4 CRC=0x9d9a638a diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf index 5b16496f0..21bf2be51 100644 --- a/tests/ref/lavf/mxf +++ b/tests/ref/lavf/mxf @@ -1,9 +1,9 @@ -27b98795036b334e100c15c7e06d948f *tests/data/lavf/lavf.mxf +8938d5c4a396ff1b24d10d4f917ae1c9 *tests/data/lavf/lavf.mxf 526393 tests/data/lavf/lavf.mxf tests/data/lavf/lavf.mxf CRC=0x8dddfaab -783b475a818602f54e947094d57e2981 *tests/data/lavf/lavf.mxf +93ea2cfdf5dda7fffdc0d2fdcfb6a9a4 *tests/data/lavf/lavf.mxf 561721 tests/data/lavf/lavf.mxf tests/data/lavf/lavf.mxf CRC=0x96ff1b48 -02bf8f0cd8951a49e277306691cb1538 *tests/data/lavf/lavf.mxf +87bdf844ae34bcc758e44419e80177a0 *tests/data/lavf/lavf.mxf 526393 tests/data/lavf/lavf.mxf tests/data/lavf/lavf.mxf CRC=0x8dddfaab diff --git a/tests/ref/lavf/mxf_d10 b/tests/ref/lavf/mxf_d10 index aea469bb5..47ef244cb 100644 --- a/tests/ref/lavf/mxf_d10 +++ b/tests/ref/lavf/mxf_d10 @@ -1,3 +1,3 @@ -e597f73ef9c9819710d2f815813eb91f *tests/data/lavf/lavf.mxf_d10 +7f16902e28718c2a92bc082400a1c6ee *tests/data/lavf/lavf.mxf_d10 5332013 tests/data/lavf/lavf.mxf_d10 tests/data/lavf/lavf.mxf_d10 CRC=0x6c74d488 diff --git a/tests/ref/lavf/mxf_dv25 b/tests/ref/lavf/mxf_dv25 index db6b76c6f..92509cf1f 100644 --- a/tests/ref/lavf/mxf_dv25 +++ b/tests/ref/lavf/mxf_dv25 @@ -1,3 +1,3 @@ -0fc964fa22bc8b3a389b81b9a2efccb3 *tests/data/lavf/lavf.mxf_dv25 +106e33eb1634595623f0334e92204b65 *tests/data/lavf/lavf.mxf_dv25 3834413 tests/data/lavf/lavf.mxf_dv25 tests/data/lavf/lavf.mxf_dv25 CRC=0xbdaf7f52 diff --git a/tests/ref/lavf/mxf_dvcpro50 b/tests/ref/lavf/mxf_dvcpro50 index 09999914b..2d569b055 100644 --- a/tests/ref/lavf/mxf_dvcpro50 +++ b/tests/ref/lavf/mxf_dvcpro50 @@ -1,3 +1,3 @@ -aa81ea83af44a69e73849e327cc4bd12 *tests/data/lavf/lavf.mxf_dvcpro50 +3d5a303c22666996700f0e8f6e4cb938 *tests/data/lavf/lavf.mxf_dvcpro50 7431213 tests/data/lavf/lavf.mxf_dvcpro50 tests/data/lavf/lavf.mxf_dvcpro50 CRC=0xe3bbe4b4 diff --git a/tests/ref/lavf/mxf_opatom b/tests/ref/lavf/mxf_opatom index 05794a4e5..61e755550 100644 --- a/tests/ref/lavf/mxf_opatom +++ b/tests/ref/lavf/mxf_opatom @@ -1,3 +1,3 @@ -06a1816aa91c733e1ef7e45d82e4f1d3 *tests/data/lavf/lavf.mxf_opatom +5d235c127ace64b1f4fe6c79a7ca8be6 *tests/data/lavf/lavf.mxf_opatom 4717625 tests/data/lavf/lavf.mxf_opatom tests/data/lavf/lavf.mxf_opatom CRC=0xf55aa22a diff --git a/tests/ref/lavf/mxf_opatom_audio b/tests/ref/lavf/mxf_opatom_audio index 2b9306f1d..97362e7aa 100644 --- a/tests/ref/lavf/mxf_opatom_audio +++ b/tests/ref/lavf/mxf_opatom_audio @@ -1,3 +1,3 @@ -c45bb140605339556a77e751fda2c449 *tests/data/lavf/lavf.mxf_opatom_audio +c356a3fdd49a1e015961678e837c12bb *tests/data/lavf/lavf.mxf_opatom_audio 102969 tests/data/lavf/lavf.mxf_opatom_audio tests/data/lavf/lavf.mxf_opatom_audio CRC=0xd155c6ff diff --git a/tests/ref/lavf/rm b/tests/ref/lavf/rm index 43ea4c789..fc2a6564a 100644 --- a/tests/ref/lavf/rm +++ b/tests/ref/lavf/rm @@ -1,2 +1,2 @@ -e30681d05d6f3d24108d3614600bf116 *tests/data/lavf/lavf.rm +8dfb8d4556d61d3615e0d0012ffe540c *tests/data/lavf/lavf.rm 346424 tests/data/lavf/lavf.rm diff --git a/tests/ref/lavf/xbm b/tests/ref/lavf/xbm index bc157834f..e54d6bc22 100644 --- a/tests/ref/lavf/xbm +++ b/tests/ref/lavf/xbm @@ -1,3 +1,3 @@ -0629055fd82366317c651a0af4bb82d7 *tests/data/images/xbm/02.xbm +83ed197cc88f382d9253365ffef70ec5 *tests/data/images/xbm/02.xbm tests/data/images/xbm/%02d.xbm CRC=0xc9a20204 -76411 tests/data/images/xbm/02.xbm +76410 tests/data/images/xbm/02.xbm diff --git a/tests/ref/seek/acodec-adpcm-swf b/tests/ref/seek/acodec-adpcm-swf index 5905b33b6..7f9111d6b 100644 --- a/tests/ref/seek/acodec-adpcm-swf +++ b/tests/ref/seek/acodec-adpcm-swf @@ -1,49 +1,49 @@ -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st:-1 flags:0 ts:-1.000000 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st:-1 flags:1 ts: 1.894167 -ret: 0 st: 0 flags:1 dts: 1.858000 pts: 1.858000 pos: 82956 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.858000 pts: 1.858000 pos: 82536 size: 4101 ret: 0 st: 0 flags:0 ts: 0.788000 -ret: 0 st: 0 flags:1 dts: 0.789000 pts: 0.789000 pos: 35369 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.836000 pts: 0.836000 pos: 37249 size: 4101 ret:-1 st: 0 flags:1 ts:-0.317000 ret: 0 st:-1 flags:0 ts: 2.576668 -ret: 0 st: 0 flags:1 dts: 2.601000 pts: 2.601000 pos: 116060 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.601000 pts: 2.601000 pos: 115472 size: 4101 ret: 0 st:-1 flags:1 ts: 1.470835 -ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 64335 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.393000 pts: 1.393000 pos: 61951 size: 4101 ret: 0 st: 0 flags:0 ts: 0.365000 -ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 16748 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 16664 size: 4101 ret:-1 st: 0 flags:1 ts:-0.741000 ret: 0 st:-1 flags:0 ts: 2.153336 -ret: 0 st: 0 flags:1 dts: 2.183000 pts: 2.183000 pos: 97439 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.229000 pts: 2.229000 pos: 99004 size: 4101 ret: 0 st:-1 flags:1 ts: 1.047503 -ret: 0 st: 0 flags:1 dts: 1.022000 pts: 1.022000 pos: 45714 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.022000 pts: 1.022000 pos: 45483 size: 4101 ret: 0 st: 0 flags:0 ts:-0.058000 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st: 0 flags:1 ts: 2.836000 -ret: 0 st: 0 flags:1 dts: 2.833000 pts: 2.833000 pos: 126405 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.786000 pts: 2.786000 pos: 123706 size: 4101 ret: 0 st:-1 flags:0 ts: 1.730004 -ret: 0 st: 0 flags:1 dts: 1.765000 pts: 1.765000 pos: 78818 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.765000 pts: 1.765000 pos: 78419 size: 4101 ret: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 0 flags:1 dts: 0.604000 pts: 0.604000 pos: 27093 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.557000 pts: 0.557000 pos: 24898 size: 4101 ret: 0 st: 0 flags:0 ts:-0.482000 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st: 0 flags:1 ts: 2.413000 -ret: 0 st: 0 flags:1 dts: 2.368000 pts: 2.368000 pos: 105715 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.322000 pts: 2.322000 pos: 103121 size: 4101 ret: 0 st:-1 flags:0 ts: 1.306672 -ret: 0 st: 0 flags:1 dts: 1.347000 pts: 1.347000 pos: 60197 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.393000 pts: 1.393000 pos: 61951 size: 4101 ret: 0 st:-1 flags:1 ts: 0.200839 -ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 8472 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 8430 size: 4101 ret: 0 st: 0 flags:0 ts:-0.905000 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st: 0 flags:1 ts: 1.989000 -ret: 0 st: 0 flags:1 dts: 1.950000 pts: 1.950000 pos: 87094 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.950000 pts: 1.950000 pos: 86653 size: 4101 ret: 0 st:-1 flags:0 ts: 0.883340 -ret: 0 st: 0 flags:1 dts: 0.929000 pts: 0.929000 pos: 41576 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.929000 pts: 0.929000 pos: 41366 size: 4101 ret:-1 st:-1 flags:1 ts:-0.222493 ret: 0 st: 0 flags:0 ts: 2.672000 -ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 120198 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 119589 size: 4101 ret: 0 st: 0 flags:1 ts: 1.566000 -ret: 0 st: 0 flags:1 dts: 1.533000 pts: 1.533000 pos: 68473 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.486000 pts: 1.486000 pos: 66068 size: 4101 ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 20886 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 20781 size: 4101 ret:-1 st:-1 flags:1 ts:-0.645825 diff --git a/tests/ref/seek/acodec-adpcm-swf-trellis b/tests/ref/seek/acodec-adpcm-swf-trellis index 5905b33b6..7f9111d6b 100644 --- a/tests/ref/seek/acodec-adpcm-swf-trellis +++ b/tests/ref/seek/acodec-adpcm-swf-trellis @@ -1,49 +1,49 @@ -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st:-1 flags:0 ts:-1.000000 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st:-1 flags:1 ts: 1.894167 -ret: 0 st: 0 flags:1 dts: 1.858000 pts: 1.858000 pos: 82956 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.858000 pts: 1.858000 pos: 82536 size: 4101 ret: 0 st: 0 flags:0 ts: 0.788000 -ret: 0 st: 0 flags:1 dts: 0.789000 pts: 0.789000 pos: 35369 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.836000 pts: 0.836000 pos: 37249 size: 4101 ret:-1 st: 0 flags:1 ts:-0.317000 ret: 0 st:-1 flags:0 ts: 2.576668 -ret: 0 st: 0 flags:1 dts: 2.601000 pts: 2.601000 pos: 116060 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.601000 pts: 2.601000 pos: 115472 size: 4101 ret: 0 st:-1 flags:1 ts: 1.470835 -ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 64335 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.393000 pts: 1.393000 pos: 61951 size: 4101 ret: 0 st: 0 flags:0 ts: 0.365000 -ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 16748 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 16664 size: 4101 ret:-1 st: 0 flags:1 ts:-0.741000 ret: 0 st:-1 flags:0 ts: 2.153336 -ret: 0 st: 0 flags:1 dts: 2.183000 pts: 2.183000 pos: 97439 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.229000 pts: 2.229000 pos: 99004 size: 4101 ret: 0 st:-1 flags:1 ts: 1.047503 -ret: 0 st: 0 flags:1 dts: 1.022000 pts: 1.022000 pos: 45714 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.022000 pts: 1.022000 pos: 45483 size: 4101 ret: 0 st: 0 flags:0 ts:-0.058000 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st: 0 flags:1 ts: 2.836000 -ret: 0 st: 0 flags:1 dts: 2.833000 pts: 2.833000 pos: 126405 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.786000 pts: 2.786000 pos: 123706 size: 4101 ret: 0 st:-1 flags:0 ts: 1.730004 -ret: 0 st: 0 flags:1 dts: 1.765000 pts: 1.765000 pos: 78818 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.765000 pts: 1.765000 pos: 78419 size: 4101 ret: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 0 flags:1 dts: 0.604000 pts: 0.604000 pos: 27093 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.557000 pts: 0.557000 pos: 24898 size: 4101 ret: 0 st: 0 flags:0 ts:-0.482000 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st: 0 flags:1 ts: 2.413000 -ret: 0 st: 0 flags:1 dts: 2.368000 pts: 2.368000 pos: 105715 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.322000 pts: 2.322000 pos: 103121 size: 4101 ret: 0 st:-1 flags:0 ts: 1.306672 -ret: 0 st: 0 flags:1 dts: 1.347000 pts: 1.347000 pos: 60197 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.393000 pts: 1.393000 pos: 61951 size: 4101 ret: 0 st:-1 flags:1 ts: 0.200839 -ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 8472 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 8430 size: 4101 ret: 0 st: 0 flags:0 ts:-0.905000 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 196 size: 4101 ret: 0 st: 0 flags:1 ts: 1.989000 -ret: 0 st: 0 flags:1 dts: 1.950000 pts: 1.950000 pos: 87094 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.950000 pts: 1.950000 pos: 86653 size: 4101 ret: 0 st:-1 flags:0 ts: 0.883340 -ret: 0 st: 0 flags:1 dts: 0.929000 pts: 0.929000 pos: 41576 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.929000 pts: 0.929000 pos: 41366 size: 4101 ret:-1 st:-1 flags:1 ts:-0.222493 ret: 0 st: 0 flags:0 ts: 2.672000 -ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 120198 size: 2053 +ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 119589 size: 4101 ret: 0 st: 0 flags:1 ts: 1.566000 -ret: 0 st: 0 flags:1 dts: 1.533000 pts: 1.533000 pos: 68473 size: 2053 +ret: 0 st: 0 flags:1 dts: 1.486000 pts: 1.486000 pos: 66068 size: 4101 ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 20886 size: 2053 +ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 20781 size: 4101 ret:-1 st:-1 flags:1 ts:-0.645825 diff --git a/tests/ref/seek/lavf-al b/tests/ref/seek/lavf-al index 8d517fa2b..5a4085af4 100644 --- a/tests/ref/seek/lavf-al +++ b/tests/ref/seek/lavf-al @@ -7,22 +7,20 @@ ret: 0 st: 0 flags:0 ts: 0.788345 ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 17383 size: 882 ret: 0 st: 0 flags:1 ts:-0.317506 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 -ret: 0 st:-1 flags:0 ts: 2.576668 -ret:-EOF +ret:-1 st:-1 flags:0 ts: 2.576668 ret: 0 st:-1 flags:1 ts: 1.470835 ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 32432 size: 882 ret: 0 st: 0 flags:0 ts: 0.364989 ret: 0 st: 0 flags:1 dts: 0.364989 pts: 0.364989 pos: 8048 size: 882 ret: 0 st: 0 flags:1 ts:-0.740816 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 -ret: 0 st:-1 flags:0 ts: 2.153336 -ret:-EOF +ret:-1 st:-1 flags:0 ts: 2.153336 ret: 0 st:-1 flags:1 ts: 1.047503 ret: 0 st: 0 flags:1 dts: 1.047483 pts: 1.047483 pos: 23097 size: 882 ret: 0 st: 0 flags:0 ts:-0.058322 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 ret: 0 st: 0 flags:1 ts: 2.835828 -ret:-EOF +ret: 0 st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 43218 size: 882 ret: 0 st:-1 flags:0 ts: 1.730004 ret: 0 st: 0 flags:1 dts: 1.730023 pts: 1.730023 pos: 38147 size: 882 ret: 0 st:-1 flags:1 ts: 0.624171 @@ -30,7 +28,7 @@ ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 13763 size: 882 ret: 0 st: 0 flags:0 ts:-0.481678 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 ret: 0 st: 0 flags:1 ts: 2.412517 -ret:-EOF +ret: 0 st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 43218 size: 882 ret: 0 st:-1 flags:0 ts: 1.306672 ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 28812 size: 882 ret: 0 st:-1 flags:1 ts: 0.200839 @@ -43,8 +41,7 @@ ret: 0 st:-1 flags:0 ts: 0.883340 ret: 0 st: 0 flags:1 dts: 0.883356 pts: 0.883356 pos: 19478 size: 882 ret: 0 st:-1 flags:1 ts:-0.222493 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 -ret: 0 st: 0 flags:0 ts: 2.671655 -ret:-EOF +ret:-1 st: 0 flags:0 ts: 2.671655 ret: 0 st: 0 flags:1 ts: 1.565850 ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 34527 size: 882 ret: 0 st:-1 flags:0 ts: 0.460008 diff --git a/tests/ref/seek/lavf-dv b/tests/ref/seek/lavf-dv index 0000ff5ab..f63e4460b 100644 --- a/tests/ref/seek/lavf-dv +++ b/tests/ref/seek/lavf-dv @@ -7,9 +7,9 @@ ret: 0 st: 0 flags:0 ts: 0.800000 ret: 0 st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:2880000 size:144000 ret: 0 st: 0 flags:1 ts:-0.320000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:144000 -ret: 0 st: 1 flags:0 ts: 2.576667 +ret: 0 st: 1 flags:0 ts: 2.560000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 -ret: 0 st: 1 flags:1 ts: 1.470833 +ret: 0 st: 1 flags:1 ts: 1.480000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 ret: 0 st:-1 flags:0 ts: 0.365002 ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:1296000 size:144000 @@ -19,9 +19,9 @@ ret: 0 st: 0 flags:0 ts: 2.160000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 ret: 0 st: 0 flags:1 ts: 1.040000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 -ret: 0 st: 1 flags:0 ts:-0.058333 +ret: 0 st: 1 flags:0 ts:-0.040000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:144000 -ret: 0 st: 1 flags:1 ts: 2.835833 +ret: 0 st: 1 flags:1 ts: 2.840000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 ret: 0 st:-1 flags:0 ts: 1.730004 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 @@ -31,10 +31,10 @@ ret: 0 st: 0 flags:0 ts:-0.480000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:144000 ret: 0 st: 0 flags:1 ts: 2.400000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 -ret: 0 st: 1 flags:0 ts: 1.306667 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 -ret: 0 st: 1 flags:1 ts: 0.200833 +ret: 0 st: 1 flags:0 ts: 1.320000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 +ret: 0 st: 1 flags:1 ts: 0.200000 +ret: 0 st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos: 720000 size:144000 ret: 0 st:-1 flags:0 ts:-0.904994 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:144000 ret: 0 st:-1 flags:1 ts: 1.989173 @@ -43,9 +43,9 @@ ret: 0 st: 0 flags:0 ts: 0.880000 ret: 0 st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:3168000 size:144000 ret: 0 st: 0 flags:1 ts:-0.240000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:144000 -ret: 0 st: 1 flags:0 ts: 2.671667 +ret: 0 st: 1 flags:0 ts: 2.680000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 -ret: 0 st: 1 flags:1 ts: 1.565833 +ret: 0 st: 1 flags:1 ts: 1.560000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000 ret: 0 st:-1 flags:0 ts: 0.460008 ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:1728000 size:144000 diff --git a/tests/ref/seek/lavf-ul b/tests/ref/seek/lavf-ul index 8d517fa2b..5a4085af4 100644 --- a/tests/ref/seek/lavf-ul +++ b/tests/ref/seek/lavf-ul @@ -7,22 +7,20 @@ ret: 0 st: 0 flags:0 ts: 0.788345 ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 17383 size: 882 ret: 0 st: 0 flags:1 ts:-0.317506 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 -ret: 0 st:-1 flags:0 ts: 2.576668 -ret:-EOF +ret:-1 st:-1 flags:0 ts: 2.576668 ret: 0 st:-1 flags:1 ts: 1.470835 ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 32432 size: 882 ret: 0 st: 0 flags:0 ts: 0.364989 ret: 0 st: 0 flags:1 dts: 0.364989 pts: 0.364989 pos: 8048 size: 882 ret: 0 st: 0 flags:1 ts:-0.740816 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 -ret: 0 st:-1 flags:0 ts: 2.153336 -ret:-EOF +ret:-1 st:-1 flags:0 ts: 2.153336 ret: 0 st:-1 flags:1 ts: 1.047503 ret: 0 st: 0 flags:1 dts: 1.047483 pts: 1.047483 pos: 23097 size: 882 ret: 0 st: 0 flags:0 ts:-0.058322 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 ret: 0 st: 0 flags:1 ts: 2.835828 -ret:-EOF +ret: 0 st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 43218 size: 882 ret: 0 st:-1 flags:0 ts: 1.730004 ret: 0 st: 0 flags:1 dts: 1.730023 pts: 1.730023 pos: 38147 size: 882 ret: 0 st:-1 flags:1 ts: 0.624171 @@ -30,7 +28,7 @@ ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 13763 size: 882 ret: 0 st: 0 flags:0 ts:-0.481678 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 ret: 0 st: 0 flags:1 ts: 2.412517 -ret:-EOF +ret: 0 st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 43218 size: 882 ret: 0 st:-1 flags:0 ts: 1.306672 ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 28812 size: 882 ret: 0 st:-1 flags:1 ts: 0.200839 @@ -43,8 +41,7 @@ ret: 0 st:-1 flags:0 ts: 0.883340 ret: 0 st: 0 flags:1 dts: 0.883356 pts: 0.883356 pos: 19478 size: 882 ret: 0 st:-1 flags:1 ts:-0.222493 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 882 -ret: 0 st: 0 flags:0 ts: 2.671655 -ret:-EOF +ret:-1 st: 0 flags:0 ts: 2.671655 ret: 0 st: 0 flags:1 ts: 1.565850 ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 34527 size: 882 ret: 0 st:-1 flags:0 ts: 0.460008 diff --git a/tests/ref/vsynth/vsynth1-dv-hd b/tests/ref/vsynth/vsynth1-dv-hd index 6b6d6e815..3f2f9cc84 100644 --- a/tests/ref/vsynth/vsynth1-dv-hd +++ b/tests/ref/vsynth/vsynth1-dv-hd @@ -1,4 +1,4 @@ -22d1d62a834fe8416fe79c51760012c1 *tests/data/fate/vsynth1-dv-hd.dv +b2bcafc74dec5f9ca516cb25dd07459b *tests/data/fate/vsynth1-dv-hd.dv 14400000 tests/data/fate/vsynth1-dv-hd.dv 34b78cf725346c7f819c9d6209b8299a *tests/data/fate/vsynth1-dv-hd.out.rawvideo stddev: 4.30 PSNR: 35.45 MAXDIFF: 74 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-ffv1-v3-rgb48 b/tests/ref/vsynth/vsynth1-ffv1-v3-rgb48 index 5c4448831..6f67de82b 100644 --- a/tests/ref/vsynth/vsynth1-ffv1-v3-rgb48 +++ b/tests/ref/vsynth/vsynth1-ffv1-v3-rgb48 @@ -1,4 +1,4 @@ f457dba7d58f0c28aedcfef518758d23 *tests/data/fate/vsynth1-ffv1-v3-rgb48.avi 16858304 tests/data/fate/vsynth1-ffv1-v3-rgb48.avi -b91ddc45eb70b4377dc7439e16733232 *tests/data/fate/vsynth1-ffv1-v3-rgb48.out.rawvideo -stddev: 3.58 PSNR: 37.04 MAXDIFF: 75 bytes: 7603200/ 7603200 +e2542b84193de462b04da530ab941f31 *tests/data/fate/vsynth1-ffv1-v3-rgb48.out.rawvideo +stddev: 3.52 PSNR: 37.19 MAXDIFF: 74 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-jpeg2000 b/tests/ref/vsynth/vsynth1-jpeg2000 index 48accf500..f8e987f95 100644 --- a/tests/ref/vsynth/vsynth1-jpeg2000 +++ b/tests/ref/vsynth/vsynth1-jpeg2000 @@ -1,4 +1,4 @@ -d2a06ad916711d29b30977a06335bb76 *tests/data/fate/vsynth1-jpeg2000.avi -2265698 tests/data/fate/vsynth1-jpeg2000.avi -15a8e49f6fd014193bbafd72f84936c7 *tests/data/fate/vsynth1-jpeg2000.out.rawvideo -stddev: 5.36 PSNR: 33.55 MAXDIFF: 61 bytes: 7603200/ 7603200 +95add005faf68fcf8f16e86eab079ca2 *tests/data/fate/vsynth1-jpeg2000.avi +2263192 tests/data/fate/vsynth1-jpeg2000.avi +b7f48a8965f78011c76483277befc6fc *tests/data/fate/vsynth1-jpeg2000.out.rawvideo +stddev: 5.35 PSNR: 33.56 MAXDIFF: 59 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-jpeg2000-97 b/tests/ref/vsynth/vsynth1-jpeg2000-97 index 33b3299ad..6ab5aa423 100644 --- a/tests/ref/vsynth/vsynth1-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth1-jpeg2000-97 @@ -1,4 +1,4 @@ -8bb707e596f97451fd325dec2dd610a7 *tests/data/fate/vsynth1-jpeg2000-97.avi -3654620 tests/data/fate/vsynth1-jpeg2000-97.avi -5073771a78e1f5366a7eb0df341662fc *tests/data/fate/vsynth1-jpeg2000-97.out.rawvideo +e4d03b2e3c03e56c7f831b1e662c4031 *tests/data/fate/vsynth1-jpeg2000-97.avi +3643928 tests/data/fate/vsynth1-jpeg2000-97.avi +a2262f1da2f49bc196b780a6b47ec4e8 *tests/data/fate/vsynth1-jpeg2000-97.out.rawvideo stddev: 4.23 PSNR: 35.59 MAXDIFF: 53 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-mpeg4 b/tests/ref/vsynth/vsynth1-mpeg4 index 4e9b4bd03..e5abc146b 100644 --- a/tests/ref/vsynth/vsynth1-mpeg4 +++ b/tests/ref/vsynth/vsynth1-mpeg4 @@ -1,4 +1,4 @@ -b4e8871c504a22c8c874c7e845b73da7 *tests/data/fate/vsynth1-mpeg4.mp4 -540085 tests/data/fate/vsynth1-mpeg4.mp4 +a7e57333c57e0f8a551374b063a41d9e *tests/data/fate/vsynth1-mpeg4.mp4 +540105 tests/data/fate/vsynth1-mpeg4.mp4 f80ec173d37f2f91add031e95579a220 *tests/data/fate/vsynth1-mpeg4.out.rawvideo stddev: 7.97 PSNR: 30.10 MAXDIFF: 105 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-r210 b/tests/ref/vsynth/vsynth1-r210 index 110330806..2c62ef977 100644 --- a/tests/ref/vsynth/vsynth1-r210 +++ b/tests/ref/vsynth/vsynth1-r210 @@ -1,4 +1,4 @@ 1a522a30ddd8c2865a731a5659001717 *tests/data/fate/vsynth1-r210.avi 22125252 tests/data/fate/vsynth1-r210.avi -b6444935d6c4d8c75fe63d5978f5b457 *tests/data/fate/vsynth1-r210.out.rawvideo -stddev: 3.73 PSNR: 36.68 MAXDIFF: 48 bytes: 7603200/ 7603200 +d118531accba75fb3b6ebf2a3a4a2e8e *tests/data/fate/vsynth1-r210.out.rawvideo +stddev: 3.70 PSNR: 36.77 MAXDIFF: 47 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-dv-hd b/tests/ref/vsynth/vsynth2-dv-hd index c6dcb5a95..0a5046e4e 100644 --- a/tests/ref/vsynth/vsynth2-dv-hd +++ b/tests/ref/vsynth/vsynth2-dv-hd @@ -1,4 +1,4 @@ -4270e5d552e0a05193f44bff75c2d271 *tests/data/fate/vsynth2-dv-hd.dv +a9a4c750f7720e83d538d36c318be787 *tests/data/fate/vsynth2-dv-hd.dv 14400000 tests/data/fate/vsynth2-dv-hd.dv 15dbe911532aca81c67bdd2846419027 *tests/data/fate/vsynth2-dv-hd.out.rawvideo stddev: 1.75 PSNR: 43.26 MAXDIFF: 34 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-ffv1-v3-rgb48 b/tests/ref/vsynth/vsynth2-ffv1-v3-rgb48 index 983c381e9..82b03bbe9 100644 --- a/tests/ref/vsynth/vsynth2-ffv1-v3-rgb48 +++ b/tests/ref/vsynth/vsynth2-ffv1-v3-rgb48 @@ -1,4 +1,4 @@ 99b39b0286428ccf9c788545dfccb49f *tests/data/fate/vsynth2-ffv1-v3-rgb48.avi 15089212 tests/data/fate/vsynth2-ffv1-v3-rgb48.avi -b7278d99ea84fe8becf02de773fee0a5 *tests/data/fate/vsynth2-ffv1-v3-rgb48.out.rawvideo -stddev: 1.43 PSNR: 44.97 MAXDIFF: 28 bytes: 7603200/ 7603200 +370aa3829b8e828e97ec777f04375b26 *tests/data/fate/vsynth2-ffv1-v3-rgb48.out.rawvideo +stddev: 1.24 PSNR: 46.23 MAXDIFF: 28 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-jpeg2000 b/tests/ref/vsynth/vsynth2-jpeg2000 index 094f41688..d0df0099e 100644 --- a/tests/ref/vsynth/vsynth2-jpeg2000 +++ b/tests/ref/vsynth/vsynth2-jpeg2000 @@ -1,4 +1,4 @@ -6c2f979e4a33a36f36aec86f2d464143 *tests/data/fate/vsynth2-jpeg2000.avi -1494516 tests/data/fate/vsynth2-jpeg2000.avi -36afd96d6e55bc83166fd615351ba366 *tests/data/fate/vsynth2-jpeg2000.out.rawvideo -stddev: 5.00 PSNR: 34.15 MAXDIFF: 59 bytes: 7603200/ 7603200 +8c8a68ca748190c71b3ea43e5ab7f502 *tests/data/fate/vsynth2-jpeg2000.avi +1538736 tests/data/fate/vsynth2-jpeg2000.avi +64fadc87447268cf90503cb294db7f61 *tests/data/fate/vsynth2-jpeg2000.out.rawvideo +stddev: 4.91 PSNR: 34.29 MAXDIFF: 55 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-jpeg2000-97 b/tests/ref/vsynth/vsynth2-jpeg2000-97 index 38153ea0e..33c1fb242 100644 --- a/tests/ref/vsynth/vsynth2-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth2-jpeg2000-97 @@ -1,4 +1,4 @@ -2e43f004a55f4a55a19c4b79fc8e8743 *tests/data/fate/vsynth2-jpeg2000-97.avi -2448706 tests/data/fate/vsynth2-jpeg2000-97.avi -a6e2453118a0de135836a868b2ca0e60 *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo -stddev: 3.23 PSNR: 37.94 MAXDIFF: 29 bytes: 7603200/ 7603200 +c8f76055f59804ca72dbd66eb4db83a2 *tests/data/fate/vsynth2-jpeg2000-97.avi +2464138 tests/data/fate/vsynth2-jpeg2000-97.avi +1f63c8b065e847e4c63d57ce23442ea8 *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo +stddev: 3.21 PSNR: 37.99 MAXDIFF: 26 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-mpeg4 b/tests/ref/vsynth/vsynth2-mpeg4 index 85899ff88..7857d4580 100644 --- a/tests/ref/vsynth/vsynth2-mpeg4 +++ b/tests/ref/vsynth/vsynth2-mpeg4 @@ -1,4 +1,4 @@ -adbd883d1701beabd04522d003dafab6 *tests/data/fate/vsynth2-mpeg4.mp4 -159310 tests/data/fate/vsynth2-mpeg4.mp4 +b751a2d3b4e693ca39d4fafa0175fc9d *tests/data/fate/vsynth2-mpeg4.mp4 +159330 tests/data/fate/vsynth2-mpeg4.mp4 2645405bc5350acc85ad72f3352f5135 *tests/data/fate/vsynth2-mpeg4.out.rawvideo stddev: 6.02 PSNR: 32.53 MAXDIFF: 89 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-r210 b/tests/ref/vsynth/vsynth2-r210 index 5efd87d6f..288664d69 100644 --- a/tests/ref/vsynth/vsynth2-r210 +++ b/tests/ref/vsynth/vsynth2-r210 @@ -1,4 +1,4 @@ 9a27c0c96f9e658d610d2590b61416a1 *tests/data/fate/vsynth2-r210.avi 22125252 tests/data/fate/vsynth2-r210.avi -d43196c64fd611f6e9c046e0ef3e570e *tests/data/fate/vsynth2-r210.out.rawvideo -stddev: 1.37 PSNR: 45.34 MAXDIFF: 14 bytes: 7603200/ 7603200 +8c370aac5d744c870049aed0741e20a3 *tests/data/fate/vsynth2-r210.out.rawvideo +stddev: 1.20 PSNR: 46.54 MAXDIFF: 14 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth3-dv-hd b/tests/ref/vsynth/vsynth3-dv-hd index d069e6980..11a51b18b 100644 --- a/tests/ref/vsynth/vsynth3-dv-hd +++ b/tests/ref/vsynth/vsynth3-dv-hd @@ -1,4 +1,4 @@ -2f81f3ccec178ba2fd9d3e3b46f33670 *tests/data/fate/vsynth3-dv-hd.dv +63512193a0da09e15815c1be1b9c4fa5 *tests/data/fate/vsynth3-dv-hd.dv 14400000 tests/data/fate/vsynth3-dv-hd.dv a038ad7c3c09f776304ef7accdea9c74 *tests/data/fate/vsynth3-dv-hd.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-ffv1-v3-rgb48 b/tests/ref/vsynth/vsynth3-ffv1-v3-rgb48 index 9a7b6f536..6964197e3 100644 --- a/tests/ref/vsynth/vsynth3-ffv1-v3-rgb48 +++ b/tests/ref/vsynth/vsynth3-ffv1-v3-rgb48 @@ -1,4 +1,4 @@ 3bec2f4381dc362c24d1bbc304d0af58 *tests/data/fate/vsynth3-ffv1-v3-rgb48.avi 244742 tests/data/fate/vsynth3-ffv1-v3-rgb48.avi -d37e1507abd3233e27b0b00441149ddc *tests/data/fate/vsynth3-ffv1-v3-rgb48.out.rawvideo -stddev: 3.52 PSNR: 37.19 MAXDIFF: 59 bytes: 86700/ 86700 +a3dd456a61aa1abcf4fc2bc9ffd0617a *tests/data/fate/vsynth3-ffv1-v3-rgb48.out.rawvideo +stddev: 3.48 PSNR: 37.30 MAXDIFF: 59 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-jpeg2000 b/tests/ref/vsynth/vsynth3-jpeg2000 index a1e3a8090..ecc286b9a 100644 --- a/tests/ref/vsynth/vsynth3-jpeg2000 +++ b/tests/ref/vsynth/vsynth3-jpeg2000 @@ -1,4 +1,4 @@ -0b8aa8113c10772cffff60f9c8ffd902 *tests/data/fate/vsynth3-jpeg2000.avi -65548 tests/data/fate/vsynth3-jpeg2000.avi -2d8bd94d558755c47d7e23fd9556e164 *tests/data/fate/vsynth3-jpeg2000.out.rawvideo -stddev: 5.48 PSNR: 33.34 MAXDIFF: 47 bytes: 86700/ 86700 +776bf3234cbf25002f129b89baab42ea *tests/data/fate/vsynth3-jpeg2000.avi +67400 tests/data/fate/vsynth3-jpeg2000.avi +098f5980667e1fcd50452b1dc1a74f61 *tests/data/fate/vsynth3-jpeg2000.out.rawvideo +stddev: 5.47 PSNR: 33.36 MAXDIFF: 48 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-jpeg2000-97 b/tests/ref/vsynth/vsynth3-jpeg2000-97 index 191956f58..df10f4327 100644 --- a/tests/ref/vsynth/vsynth3-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth3-jpeg2000-97 @@ -1,4 +1,4 @@ -b6c88a623c3296ca945346d2203f0af0 *tests/data/fate/vsynth3-jpeg2000-97.avi -83870 tests/data/fate/vsynth3-jpeg2000-97.avi -0cd707bfb1bbe5312b00c094f695b1fa *tests/data/fate/vsynth3-jpeg2000-97.out.rawvideo -stddev: 4.52 PSNR: 35.02 MAXDIFF: 47 bytes: 86700/ 86700 +cd023db503f03ef72dd83e4617a90c7b *tests/data/fate/vsynth3-jpeg2000-97.avi +85606 tests/data/fate/vsynth3-jpeg2000-97.avi +8def36ad1413ab3a5c2af2e1af4603f9 *tests/data/fate/vsynth3-jpeg2000-97.out.rawvideo +stddev: 4.51 PSNR: 35.04 MAXDIFF: 47 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-mpeg4 b/tests/ref/vsynth/vsynth3-mpeg4 index 02cf68d55..a241e929c 100644 --- a/tests/ref/vsynth/vsynth3-mpeg4 +++ b/tests/ref/vsynth/vsynth3-mpeg4 @@ -1,4 +1,4 @@ -ddcff996543900496f0b374a2d5cae74 *tests/data/fate/vsynth3-mpeg4.mp4 -26017 tests/data/fate/vsynth3-mpeg4.mp4 +7ca3bbb8bed55d558346d258f5bea440 *tests/data/fate/vsynth3-mpeg4.mp4 +26037 tests/data/fate/vsynth3-mpeg4.mp4 fc0d8c1e58d254031e6207dfcae8f867 *tests/data/fate/vsynth3-mpeg4.out.rawvideo stddev: 9.66 PSNR: 28.43 MAXDIFF: 79 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-r210 b/tests/ref/vsynth/vsynth3-r210 index 253657cd8..ba5bb0b41 100644 --- a/tests/ref/vsynth/vsynth3-r210 +++ b/tests/ref/vsynth/vsynth3-r210 @@ -1,4 +1,4 @@ fd12f6dde75d0872ccf9012b342208de *tests/data/fate/vsynth3-r210.avi 442052 tests/data/fate/vsynth3-r210.avi -a2c4e460ebede1109bd794b1b7b05a1f *tests/data/fate/vsynth3-r210.out.rawvideo -stddev: 4.10 PSNR: 35.87 MAXDIFF: 48 bytes: 86700/ 86700 +e09fcdcbbd4a247c7ad16b74eecb1ec7 *tests/data/fate/vsynth3-r210.out.rawvideo +stddev: 4.07 PSNR: 35.93 MAXDIFF: 47 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth_lena-dv-hd b/tests/ref/vsynth/vsynth_lena-dv-hd index aba756c5f..8711b6fa2 100644 --- a/tests/ref/vsynth/vsynth_lena-dv-hd +++ b/tests/ref/vsynth/vsynth_lena-dv-hd @@ -1,4 +1,4 @@ -01a61c53943a421fa6a5e03dbc205972 *tests/data/fate/vsynth_lena-dv-hd.dv +f17abb38ed2f416d57f3b956fae5dc82 *tests/data/fate/vsynth_lena-dv-hd.dv 14400000 tests/data/fate/vsynth_lena-dv-hd.dv 4db4175c80ea1f16b7ec303611b8873a *tests/data/fate/vsynth_lena-dv-hd.out.rawvideo stddev: 1.49 PSNR: 44.66 MAXDIFF: 27 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-ffv1-v3-rgb48 b/tests/ref/vsynth/vsynth_lena-ffv1-v3-rgb48 index 629d6850a..e1b0885ec 100644 --- a/tests/ref/vsynth/vsynth_lena-ffv1-v3-rgb48 +++ b/tests/ref/vsynth/vsynth_lena-ffv1-v3-rgb48 @@ -1,4 +1,4 @@ 294d4f9fdf53ba0fe9d224d28ba700f0 *tests/data/fate/vsynth_lena-ffv1-v3-rgb48.avi 13795036 tests/data/fate/vsynth_lena-ffv1-v3-rgb48.avi -7bd82d1860095ae1e10ec0ace9cb04b6 *tests/data/fate/vsynth_lena-ffv1-v3-rgb48.out.rawvideo -stddev: 0.91 PSNR: 48.91 MAXDIFF: 21 bytes: 7603200/ 7603200 +832a42fafb18d52b35422ae0f34fe48c *tests/data/fate/vsynth_lena-ffv1-v3-rgb48.out.rawvideo +stddev: 0.66 PSNR: 51.63 MAXDIFF: 21 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-jpeg2000 b/tests/ref/vsynth/vsynth_lena-jpeg2000 index 72550eb81..88629add2 100644 --- a/tests/ref/vsynth/vsynth_lena-jpeg2000 +++ b/tests/ref/vsynth/vsynth_lena-jpeg2000 @@ -1,4 +1,4 @@ -1f2cf6061c78905b8011091a9a7c425f *tests/data/fate/vsynth_lena-jpeg2000.avi -1138054 tests/data/fate/vsynth_lena-jpeg2000.avi -955653ca7a08447e7b1501b444f24562 *tests/data/fate/vsynth_lena-jpeg2000.out.rawvideo -stddev: 4.40 PSNR: 35.25 MAXDIFF: 58 bytes: 7603200/ 7603200 +b8aaa45236f77a2a626791d462fd8ac1 *tests/data/fate/vsynth_lena-jpeg2000.avi +1188886 tests/data/fate/vsynth_lena-jpeg2000.avi +39a2c5b61cd0cf2821c6fb4cceba2fa8 *tests/data/fate/vsynth_lena-jpeg2000.out.rawvideo +stddev: 4.30 PSNR: 35.45 MAXDIFF: 45 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-jpeg2000-97 b/tests/ref/vsynth/vsynth_lena-jpeg2000-97 index 5c12665b6..b6f5f75f7 100644 --- a/tests/ref/vsynth/vsynth_lena-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth_lena-jpeg2000-97 @@ -1,4 +1,4 @@ -e5a756e97910420c90e76259c56261cb *tests/data/fate/vsynth_lena-jpeg2000-97.avi -1918956 tests/data/fate/vsynth_lena-jpeg2000-97.avi -93a4ba0c230f2430a813df594676e58a *tests/data/fate/vsynth_lena-jpeg2000-97.out.rawvideo -stddev: 2.84 PSNR: 39.04 MAXDIFF: 28 bytes: 7603200/ 7603200 +b2d9525433c6300674f504922d762437 *tests/data/fate/vsynth_lena-jpeg2000-97.avi +1937232 tests/data/fate/vsynth_lena-jpeg2000-97.avi +1b97333a8dc115a5ba609b0070d89d4d *tests/data/fate/vsynth_lena-jpeg2000-97.out.rawvideo +stddev: 2.82 PSNR: 39.10 MAXDIFF: 24 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-mpeg4 b/tests/ref/vsynth/vsynth_lena-mpeg4 index 8d8cccef4..375c3fc65 100644 --- a/tests/ref/vsynth/vsynth_lena-mpeg4 +++ b/tests/ref/vsynth/vsynth_lena-mpeg4 @@ -1,4 +1,4 @@ -4a029747434d24d128b078a5e6aa1e88 *tests/data/fate/vsynth_lena-mpeg4.mp4 -119722 tests/data/fate/vsynth_lena-mpeg4.mp4 +a0d0edee19f6658d0e93d294e32a1a6f *tests/data/fate/vsynth_lena-mpeg4.mp4 +119742 tests/data/fate/vsynth_lena-mpeg4.mp4 9a1e085d9e488c5ead0c940c9612a37a *tests/data/fate/vsynth_lena-mpeg4.out.rawvideo stddev: 5.34 PSNR: 33.57 MAXDIFF: 83 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-r210 b/tests/ref/vsynth/vsynth_lena-r210 index 0a113dc69..f57d64db6 100644 --- a/tests/ref/vsynth/vsynth_lena-r210 +++ b/tests/ref/vsynth/vsynth_lena-r210 @@ -1,4 +1,4 @@ 61fd53566d99b725e75212747b35893f *tests/data/fate/vsynth_lena-r210.avi 22125252 tests/data/fate/vsynth_lena-r210.avi -4b7425191bb6a7fc4ca0dc649d9ba202 *tests/data/fate/vsynth_lena-r210.out.rawvideo -stddev: 0.93 PSNR: 48.72 MAXDIFF: 11 bytes: 7603200/ 7603200 +8ecccadf5147bd5e7158afef5e155413 *tests/data/fate/vsynth_lena-r210.out.rawvideo +stddev: 0.75 PSNR: 50.57 MAXDIFF: 12 bytes: 7603200/ 7603200 diff --git a/tools/Makefile b/tools/Makefile index 001093105..82baa8ead 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,4 +1,4 @@ -TOOLS = qt-faststart trasher uncoded_frame +TOOLS = enum_options qt-faststart trasher uncoded_frame TOOLS-$(CONFIG_LIBMYSOFA) += sofa2wavs TOOLS-$(CONFIG_ZLIB) += cws2fws @@ -8,8 +8,14 @@ tools/target_dec_%_fuzzer.o: tools/target_dec_fuzzer.c tools/target_bsf_%_fuzzer.o: tools/target_bsf_fuzzer.c $(COMPILE_C) -DFFMPEG_BSF=$* +tools/target_dem_%_fuzzer.o: tools/target_dem_fuzzer.c + $(COMPILE_C) -DFFMPEG_DEMUXER=$* -DIO_FLAT=0 + tools/target_dem_fuzzer.o: tools/target_dem_fuzzer.c - $(COMPILE_C) + $(COMPILE_C) -DIO_FLAT=1 + +tools/target_io_dem_fuzzer.o: tools/target_dem_fuzzer.c + $(COMPILE_C) -DIO_FLAT=0 OUTDIRS += tools diff --git a/tools/enum_options.c b/tools/enum_options.c index 548e427b7..bedebd4c6 100644 --- a/tools/enum_options.c +++ b/tools/enum_options.c @@ -40,14 +40,14 @@ static void print_option(const AVClass *class, const AVOption *o) { printf("@item -%s @var{", o->name); switch (o->type) { - case FF_OPT_TYPE_BINARY: printf("hexadecimal string"); break; - case FF_OPT_TYPE_STRING: printf("string"); break; - case FF_OPT_TYPE_INT: - case FF_OPT_TYPE_INT64: printf("integer"); break; - case FF_OPT_TYPE_FLOAT: - case FF_OPT_TYPE_DOUBLE: printf("float"); break; - case FF_OPT_TYPE_RATIONAL: printf("rational number"); break; - case FF_OPT_TYPE_FLAGS: printf("flags"); break; + case AV_OPT_TYPE_BINARY: printf("hexadecimal string"); break; + case AV_OPT_TYPE_STRING: printf("string"); break; + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: printf("integer"); break; + case AV_OPT_TYPE_FLOAT: + case AV_OPT_TYPE_DOUBLE: printf("float"); break; + case AV_OPT_TYPE_RATIONAL: printf("rational number"); break; + case AV_OPT_TYPE_FLAGS: printf("flags"); break; default: printf("value"); break; } printf("} (@emph{"); @@ -68,8 +68,8 @@ static void print_option(const AVClass *class, const AVOption *o) const AVOption *u = NULL; printf("\nPossible values:\n@table @samp\n"); - while ((u = av_next_option(&class, u))) - if (u->type == FF_OPT_TYPE_CONST && u->unit && !strcmp(u->unit, o->unit)) + while ((u = av_opt_next(&class, u))) + if (u->type == AV_OPT_TYPE_CONST && u->unit && !strcmp(u->unit, o->unit)) printf("@item %s\n%s\n", u->name, u->help ? u->help : ""); printf("@end table\n"); } @@ -80,8 +80,8 @@ static void show_opts(const AVClass *class) const AVOption *o = NULL; printf("@table @option\n"); - while ((o = av_next_option(&class, o))) - if (o->type != FF_OPT_TYPE_CONST) + while ((o = av_opt_next(&class, o))) + if (o->type != AV_OPT_TYPE_CONST) print_option(class, o); printf("@end table\n"); } @@ -114,7 +114,7 @@ static void show_format_opts(void) static void show_codec_opts(void) { void *iter = NULL; - AVCodec *c = NULL; + const AVCodec *c; printf("@section Generic codec AVOptions\n"); show_opts(avcodec_get_class()); diff --git a/tools/ffescape.c b/tools/ffescape.c index 0530d28c6..1ed8daa80 100644 --- a/tools/ffescape.c +++ b/tools/ffescape.c @@ -78,8 +78,10 @@ int main(int argc, char **argv) infilename = optarg; break; case 'f': - if (!strcmp(optarg, "whitespace")) escape_flags |= AV_ESCAPE_FLAG_WHITESPACE; - else if (!strcmp(optarg, "strict")) escape_flags |= AV_ESCAPE_FLAG_STRICT; + if (!strcmp(optarg, "whitespace")) escape_flags |= AV_ESCAPE_FLAG_WHITESPACE; + else if (!strcmp(optarg, "strict")) escape_flags |= AV_ESCAPE_FLAG_STRICT; + else if (!strcmp(optarg, "xml_single_quotes")) escape_flags |= AV_ESCAPE_FLAG_XML_SINGLE_QUOTES; + else if (!strcmp(optarg, "xml_double_quotes")) escape_flags |= AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES; else { av_log(NULL, AV_LOG_ERROR, "Invalid value '%s' for option -f, " @@ -104,6 +106,7 @@ int main(int argc, char **argv) if (!strcmp(optarg, "auto")) escape_mode = AV_ESCAPE_MODE_AUTO; else if (!strcmp(optarg, "backslash")) escape_mode = AV_ESCAPE_MODE_BACKSLASH; else if (!strcmp(optarg, "quote")) escape_mode = AV_ESCAPE_MODE_QUOTE; + else if (!strcmp(optarg, "xml")) escape_mode = AV_ESCAPE_MODE_XML; else { av_log(NULL, AV_LOG_ERROR, "Invalid value '%s' for option -m, " diff --git a/tools/pktdumper.c b/tools/pktdumper.c index 16a965b75..c51f5c892 100644 --- a/tools/pktdumper.c +++ b/tools/pktdumper.c @@ -54,7 +54,7 @@ int main(int argc, char **argv) char fntemplate[FILENAME_BUF_SIZE]; char pktfilename[FILENAME_BUF_SIZE]; AVFormatContext *fctx = NULL; - AVPacket pkt; + AVPacket *pkt; int64_t pktnum = 0; int64_t maxpkts = 0; int donotquit = 0; @@ -101,30 +101,35 @@ int main(int argc, char **argv) return 1; } - av_init_packet(&pkt); + pkt = av_packet_alloc(); + if (!pkt) { + fprintf(stderr, "av_packet_alloc: error %d\n", AVERROR(ENOMEM)); + return 1; + } - while ((err = av_read_frame(fctx, &pkt)) >= 0) { + while ((err = av_read_frame(fctx, pkt)) >= 0) { int fd; snprintf(pktfilename, sizeof(pktfilename), fntemplate, pktnum, - pkt.stream_index, pkt.pts, pkt.size, - (pkt.flags & AV_PKT_FLAG_KEY) ? 'K' : '_'); - printf(PKTFILESUFF "\n", pktnum, pkt.stream_index, pkt.pts, pkt.size, - (pkt.flags & AV_PKT_FLAG_KEY) ? 'K' : '_'); + pkt->stream_index, pkt->pts, pkt->size, + (pkt->flags & AV_PKT_FLAG_KEY) ? 'K' : '_'); + printf(PKTFILESUFF "\n", pktnum, pkt->stream_index, pkt->pts, pkt->size, + (pkt->flags & AV_PKT_FLAG_KEY) ? 'K' : '_'); if (!nowrite) { fd = open(pktfilename, O_WRONLY | O_CREAT, 0644); - err = write(fd, pkt.data, pkt.size); + err = write(fd, pkt->data, pkt->size); if (err < 0) { fprintf(stderr, "write: error %d\n", err); return 1; } close(fd); } - av_packet_unref(&pkt); + av_packet_unref(pkt); pktnum++; if (maxpkts && (pktnum >= maxpkts)) break; } + av_packet_free(&pkt); avformat_close_input(&fctx); while (donotquit) diff --git a/tools/python/convert_from_tensorflow.py b/tools/python/convert_from_tensorflow.py index 8c0a9be7b..1a5d93fbb 100644 --- a/tools/python/convert_from_tensorflow.py +++ b/tools/python/convert_from_tensorflow.py @@ -48,9 +48,9 @@ class Operand(object): self.used_count = self.used_count + 1 def __str__(self): - return "{}: (name: {}, iotype: {}, dtype: {}, dims: ({},{},{},{}) used_count: {})".format(self.index, + return "{}: (name: {}, iotype: {}, dtype: {}, dims: {}, used_count: {})".format(self.index, self.name, self.iotype2str[self.iotype], self.dtype2str[self.dtype], - self.dims[0], self.dims[1], self.dims[2], self.dims[3], self.used_count) + self.dims, self.used_count) def __lt__(self, other): return self.index < other.index @@ -67,12 +67,18 @@ class TFConverter: self.edges = {} self.conv_activations = {'Relu':0, 'Tanh':1, 'Sigmoid':2, 'None':3, 'LeakyRelu':4} self.conv_paddings = {'VALID':0, 'SAME':1} + self.pool_paddings = {'VALID':0, 'SAME':1} self.converted_nodes = set() self.conv2d_scope_names = set() self.conv2d_scopename_inputname_dict = {} - self.op2code = {'Conv2D':1, 'DepthToSpace':2, 'MirrorPad':3, 'Maximum':4, 'MathBinary':5, 'MathUnary':6} - self.mathbin2code = {'Sub':0, 'Add':1, 'Mul':2, 'RealDiv':3, 'Minimum':4} - self.mathun2code = {'Abs':0} + self.dense_scope_names = set() + self.dense_scopename_inputname_dict = {} + self.op2code = {'Conv2D':1, 'DepthToSpace':2, 'MirrorPad':3, 'Maximum':4, + 'MathBinary':5, 'MathUnary':6, 'AvgPool':7, 'MatMul':8} + self.mathbin2code = {'Sub':0, 'Add':1, 'Mul':2, 'RealDiv':3, 'Minimum':4, 'FloorMod':5} + self.mathun2code = {'Abs':0, 'Sin':1, 'Cos':2, 'Tan':3, 'Asin':4, + 'Acos':5, 'Atan':6, 'Sinh':7, 'Cosh':8, 'Tanh':9, 'Asinh':10, + 'Acosh':11, 'Atanh':12, 'Ceil':13, 'Floor':14, 'Round':15} self.mirrorpad_mode = {'CONSTANT':0, 'REFLECT':1, 'SYMMETRIC':2} self.name_operand_dict = {} @@ -122,6 +128,22 @@ class TFConverter: return knode, bnode, dnode, anode + def get_dense_params(self, dense_scope_name): + knode = self.name_node_dict[dense_scope_name + '/kernel'] + bnode = self.name_node_dict.get(dense_scope_name + '/bias') + # the BiasAdd name is possible be changed into the output name, + # if activation is None, and BiasAdd.next is the last op which is Identity + anode = None + if bnode: + if dense_scope_name + '/BiasAdd' in self.edges: + anode = self.edges[dense_scope_name + '/BiasAdd'][0] + if anode.op not in self.conv_activations: + anode = None + else: + anode = None + return knode, bnode, anode + + def dump_complex_conv2d_to_file(self, node, f): assert(node.op == 'Conv2D') self.layer_number = self.layer_number + 1 @@ -177,6 +199,57 @@ class TFConverter: output_operand_index = self.add_operand(self.edges[bnode.name][0].name, Operand.IOTYPE_OUTPUT) np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f) + def dump_dense_to_file(self, node, f): + assert(node.op == 'MatMul') + self.layer_number = self.layer_number + 1 + self.converted_nodes.add(node.name) + + scope_name = TFConverter.get_scope_name(node.name) + #knode for kernel, bnode for bias, anode for activation + knode, bnode, anode = self.get_dense_params(scope_name.split('/')[0]) + + if bnode is not None: + has_bias = 1 + btensor = bnode.attr['value'].tensor + if btensor.tensor_shape.dim[0].size == 1: + bias = struct.pack("f", btensor.float_val[0]) + else: + bias = btensor.tensor_content + else: + has_bias = 0 + + if anode is not None: + activation = anode.op + else: + activation = 'None' + + ktensor = knode.attr['value'].tensor + in_channels = ktensor.tensor_shape.dim[0].size + out_channels = ktensor.tensor_shape.dim[1].size + if in_channels * out_channels == 1: + kernel = np.float32(ktensor.float_val[0]) + else: + kernel = np.frombuffer(ktensor.tensor_content, dtype=np.float32) + kernel = kernel.reshape(in_channels, out_channels) + kernel = np.transpose(kernel, [1, 0]) + + np.array([self.op2code[node.op], self.conv_activations[activation], in_channels, out_channels, has_bias], dtype=np.uint32).tofile(f) + kernel.tofile(f) + if has_bias: + f.write(bias) + + input_name = self.dense_scopename_inputname_dict[scope_name.split('/')[0]] + input_operand_index = self.add_operand(input_name, Operand.IOTYPE_INPUT) + + if anode is not None: + output_operand_index = self.add_operand(anode.name, Operand.IOTYPE_OUTPUT) + else: + if bnode is not None: + output_operand_index = self.add_operand(self.edges[bnode.name][0].name, Operand.IOTYPE_OUTPUT) + else: + output_operand_index = self.add_operand(self.edges[scope_name+'/concat_1'][0].name, Operand.IOTYPE_OUTPUT) + np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f) + def dump_simple_conv2d_to_file(self, node, f): assert(node.op == 'Conv2D') @@ -298,6 +371,37 @@ class TFConverter: np.array([output_operand_index],dtype=np.uint32).tofile(f) + def dump_avg_pool_to_file(self, node, f): + assert(node.op == 'AvgPool') + self.layer_number = self.layer_number + 1 + self.converted_nodes.add(node.name) + node0 = self.name_node_dict[node.input[0]] + strides = node.attr['strides'] + + # Tensorflow do not support pooling strides in batch dimension and + # current native NN do not support pooling strides in channel dimension, added assert() here. + assert(strides.list.i[1]==strides.list.i[2]) + assert(strides.list.i[0]==1) + assert(strides.list.i[3]==1) + strides = strides.list.i[1] + filter_node = node.attr['ksize'] + input_name = node.input[0] + + # Tensorflow do not support pooling ksize in batch dimension and channel dimension. + assert(filter_node.list.i[0]==1) + assert(filter_node.list.i[3]==1) + filter_height = filter_node.list.i[1] + filter_width = filter_node.list.i[2] + + padding = node.attr['padding'].s.decode("utf-8") + np.array([self.op2code[node.op], strides, self.pool_paddings[padding], filter_height], + dtype=np.uint32).tofile(f) + + input_operand_index = self.add_operand(input_name, Operand.IOTYPE_INPUT) + output_operand_index = self.add_operand(node.name, Operand.IOTYPE_OUTPUT) + np.array([input_operand_index, output_operand_index],dtype=np.uint32).tofile(f) + + def dump_layers_to_file(self, f): for node in self.nodes: if node.name in self.converted_nodes: @@ -308,9 +412,21 @@ class TFConverter: if node.op == 'Conv2D': self.dump_complex_conv2d_to_file(node, f) continue + if self.in_dense_scope(node.name): + if node.op == 'MatMul': + self.dump_dense_to_file(node, f) + continue + if node.op == 'Conv2D': self.dump_simple_conv2d_to_file(node, f) + continue + if node.name in self.output_names: + input_name = self.id_different_scope_dict[node.name] + if TFConverter.get_scope_name(input_name)!=TFConverter.get_scope_name(node.name): + continue + if node.op == 'AvgPool': + self.dump_avg_pool_to_file(node, f) elif node.op == 'DepthToSpace': self.dump_depth2space_to_file(node, f) elif node.op == 'MirrorPad': @@ -330,7 +446,7 @@ class TFConverter: np.array([operand.index, len(operand.name)], dtype=np.uint32).tofile(f) f.write(operand.name.encode('utf-8')) np.array([operand.iotype, operand.dtype], dtype=np.uint32).tofile(f) - np.array([operand.dims[0], operand.dims[1], operand.dims[2], operand.dims[3]], dtype=np.uint32).tofile(f) + np.array(operand.dims, dtype=np.uint32).tofile(f) def dump_to_file(self): @@ -359,6 +475,7 @@ class TFConverter: def remove_identity(self): + self.id_different_scope_dict = {} id_nodes = [] id_dict = {} for node in self.nodes: @@ -371,6 +488,7 @@ class TFConverter: self.name_node_dict[input].name = name self.name_node_dict[name] = self.name_node_dict[input] del self.name_node_dict[input] + self.id_different_scope_dict[name] = input else: id_dict[name] = input @@ -412,8 +530,18 @@ class TFConverter: return False - def generate_conv2d_scope_info(self): - # mostly, conv2d is a sub block in graph, get the scope name + def in_dense_scope(self, name): + inner_scope = TFConverter.get_scope_name(name) + if inner_scope == "": + return False; + for scope in self.dense_scope_names: + index = inner_scope.find(scope) + if index == 0: + return True + return False + + def generate_sub_block_op_scope_info(self): + # mostly, conv2d/dense is a sub block in graph, get the scope name for node in self.nodes: if node.op == 'Conv2D': scope = TFConverter.get_scope_name(node.name) @@ -424,8 +552,17 @@ class TFConverter: if scope + '/kernel' not in self.name_node_dict: continue self.conv2d_scope_names.add(scope) + elif node.op == 'MatMul': + scope = TFConverter.get_scope_name(node.name) + # for the case tf.nn.dense is called directly + if scope == '': + continue + # for the case tf.nn.dense is called within a scope + if scope + '/kernel' not in self.name_node_dict and scope.split('/Tensordot')[0] + '/kernel' not in self.name_node_dict: + continue + self.dense_scope_names.add(scope.split('/Tensordot')[0]) - # get the input name to the conv2d sub block + # get the input name to the conv2d/dense sub block for node in self.nodes: scope = TFConverter.get_scope_name(node.name) if scope in self.conv2d_scope_names: @@ -433,6 +570,16 @@ class TFConverter: for inp in node.input: if TFConverter.get_scope_name(inp) != scope: self.conv2d_scopename_inputname_dict[scope] = inp + elif scope in self.dense_scope_names: + if node.op == 'MatMul' or node.op == 'Shape': + for inp in node.input: + if TFConverter.get_scope_name(inp) != scope: + self.dense_scopename_inputname_dict[scope] = inp + elif scope.split('/Tensordot')[0] in self.dense_scope_names: + if node.op == 'Transpose': + for inp in node.input: + if TFConverter.get_scope_name(inp).find(scope)<0 and TFConverter.get_scope_name(inp).find(scope.split('/')[0])<0: + self.dense_scopename_inputname_dict[scope.split('/Tensordot')[0]] = inp def run(self): @@ -440,7 +587,7 @@ class TFConverter: self.generate_output_names() self.remove_identity() self.generate_edges() - self.generate_conv2d_scope_info() + self.generate_sub_block_op_scope_info() if self.dump4tb: self.dump_for_tensorboard() diff --git a/tools/python/convert_header.py b/tools/python/convert_header.py index ad4491729..782a6341f 100644 --- a/tools/python/convert_header.py +++ b/tools/python/convert_header.py @@ -23,4 +23,4 @@ str = 'FFMPEGDNNNATIVE' major = 1 # increase minor when we don't have to re-convert the model file -minor = 6 +minor = 22 diff --git a/tools/target_bsf_fuzzer.c b/tools/target_bsf_fuzzer.c index 5d9f90075..bab809162 100644 --- a/tools/target_bsf_fuzzer.c +++ b/tools/target_bsf_fuzzer.c @@ -18,6 +18,7 @@ #include "config.h" #include "libavutil/imgutils.h" +#include "libavutil/opt.h" #include "libavcodec/avcodec.h" #include "libavcodec/bsf_internal.h" @@ -41,8 +42,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { const uint8_t *last = data; const uint8_t *end = data + size; AVBSFContext *bsf = NULL; - AVPacket in, out; + AVPacket *in, *out; uint64_t keyframes = 0; + uint64_t flushpattern = -1; int res; if (!f) { @@ -65,6 +67,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (size > 1024) { GetByteContext gbc; int extradata_size; + int flags; size -= 1024; bytestream2_init(&gbc, data + size, 1024); bsf->par_in->width = bytestream2_get_le32(&gbc); @@ -86,6 +89,17 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { bsf->par_in->channels = (unsigned)bytestream2_get_le32(&gbc) % FF_SANE_NB_CHANNELS; bsf->par_in->block_align = bytestream2_get_le32(&gbc); keyframes = bytestream2_get_le64(&gbc); + flushpattern = bytestream2_get_le64(&gbc); + flags = bytestream2_get_byte(&gbc); + + if (flags & 0x20) { + if (!strcmp(f->name, "av1_metadata")) + av_opt_set_int(bsf->priv_data, "td", bytestream2_get_byte(&gbc) % 3, 0); + else if (!strcmp(f->name, "h264_metadata") || !strcmp(f->name, "h265_metadata")) + av_opt_set_int(bsf->priv_data, "aud", bytestream2_get_byte(&gbc) % 3, 0); + else if (!strcmp(f->name, "extract_extradata")) + av_opt_set_int(bsf->priv_data, "remove", bytestream2_get_byte(&gbc) & 1, 0); + } if (extradata_size < size) { bsf->par_in->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); @@ -105,10 +119,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; // Failure of av_bsf_init() does not imply that a issue was found } - av_init_packet(&in); - av_init_packet(&out); - out.data = NULL; - out.size = 0; + in = av_packet_alloc(); + out = av_packet_alloc(); + if (!in || !out) + error("Failed memory allocation"); + while (data < end) { // Search for the TAG while (data + sizeof(fuzz_tag) < end) { @@ -119,35 +134,41 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (data + sizeof(fuzz_tag) > end) data = end; - res = av_new_packet(&in, data - last); + res = av_new_packet(in, data - last); if (res < 0) error("Failed memory allocation"); - memcpy(in.data, last, data - last); - in.flags = (keyframes & 1) * AV_PKT_FLAG_DISCARD + (!!(keyframes & 2)) * AV_PKT_FLAG_KEY; + memcpy(in->data, last, data - last); + in->flags = (keyframes & 1) * AV_PKT_FLAG_DISCARD + (!!(keyframes & 2)) * AV_PKT_FLAG_KEY; keyframes = (keyframes >> 2) + (keyframes<<62); data += sizeof(fuzz_tag); last = data; - while (in.size) { - res = av_bsf_send_packet(bsf, &in); + if (!(flushpattern & 7)) + av_bsf_flush(bsf); + flushpattern = (flushpattern >> 3) + (flushpattern << 61); + + while (in->size) { + res = av_bsf_send_packet(bsf, in); if (res < 0 && res != AVERROR(EAGAIN)) break; - res = av_bsf_receive_packet(bsf, &out); + res = av_bsf_receive_packet(bsf, out); if (res < 0) break; - av_packet_unref(&out); + av_packet_unref(out); } - av_packet_unref(&in); + av_packet_unref(in); } res = av_bsf_send_packet(bsf, NULL); while (!res) { - res = av_bsf_receive_packet(bsf, &out); + res = av_bsf_receive_packet(bsf, out); if (res < 0) break; - av_packet_unref(&out); + av_packet_unref(out); } + av_packet_free(&in); + av_packet_free(&out); av_bsf_free(&bsf); return 0; } diff --git a/tools/target_dec_fuzzer.c b/tools/target_dec_fuzzer.c index 66ee99a91..9e15216e5 100644 --- a/tools/target_dec_fuzzer.c +++ b/tools/target_dec_fuzzer.c @@ -88,9 +88,17 @@ static int subtitle_handler(AVCodecContext *avctx, void *frame, return ret; } +static int audio_video_handler(AVCodecContext *avctx, AVFrame *frame, + int *got_frame, const AVPacket *dummy) +{ + int ret = avcodec_receive_frame(avctx, frame); + *got_frame = ret >= 0; + return ret; +} + // Ensure we don't loop forever const uint32_t maxiteration = 8096; -const uint64_t maxpixels_per_frame = 4096 * 4096; +uint64_t maxpixels_per_frame = 4096 * 4096; uint64_t maxpixels; uint64_t maxsamples_per_frame = 256*1024*32; @@ -110,6 +118,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { const AVPacket *avpkt) = NULL; AVCodecParserContext *parser = NULL; uint64_t keyframes = 0; + uint64_t flushpattern = -1; AVDictionary *opts = NULL; if (!c) { @@ -118,25 +127,22 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { #define DECODER_SYMBOL(CODEC) DECODER_SYMBOL0(CODEC) extern AVCodec DECODER_SYMBOL(FFMPEG_DECODER); codec_list[0] = &DECODER_SYMBOL(FFMPEG_DECODER); - avcodec_register(&DECODER_SYMBOL(FFMPEG_DECODER)); #if FFMPEG_DECODER == tiff || FFMPEG_DECODER == tdsc extern AVCodec DECODER_SYMBOL(mjpeg); codec_list[1] = &DECODER_SYMBOL(mjpeg); - avcodec_register(&DECODER_SYMBOL(mjpeg)); #endif c = &DECODER_SYMBOL(FFMPEG_DECODER); #else - avcodec_register_all(); c = AVCodecInitialize(FFMPEG_CODEC); // Done once. #endif av_log_set_level(AV_LOG_PANIC); } switch (c->type) { - case AVMEDIA_TYPE_AUDIO : decode_handler = avcodec_decode_audio4; break; - case AVMEDIA_TYPE_VIDEO : decode_handler = avcodec_decode_video2; break; + case AVMEDIA_TYPE_AUDIO : + case AVMEDIA_TYPE_VIDEO : decode_handler = audio_video_handler ; break; case AVMEDIA_TYPE_SUBTITLE: decode_handler = subtitle_handler ; break; } switch (c->id) { @@ -145,26 +151,34 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { maxpixels = maxpixels_per_frame * maxiteration; maxsamples = maxsamples_per_frame * maxiteration; switch (c->id) { + case AV_CODEC_ID_AGM: maxpixels /= 1024; break; case AV_CODEC_ID_BINKVIDEO: maxpixels /= 32; break; case AV_CODEC_ID_CFHD: maxpixels /= 128; break; + case AV_CODEC_ID_COOK: maxsamples /= 1<<20; break; case AV_CODEC_ID_DIRAC: maxpixels /= 8192; break; - case AV_CODEC_ID_DST: maxsamples /= 8192; break; + case AV_CODEC_ID_DST: maxsamples /= 1<<20; break; case AV_CODEC_ID_DXV: maxpixels /= 32; break; case AV_CODEC_ID_FFWAVESYNTH: maxsamples /= 16384; break; - case AV_CODEC_ID_G2M: maxpixels /= 64; break; + case AV_CODEC_ID_FLV1: maxpixels /= 1024; break; + case AV_CODEC_ID_G2M: maxpixels /= 1024; break; case AV_CODEC_ID_GDV: maxpixels /= 512; break; case AV_CODEC_ID_GIF: maxpixels /= 16; break; + case AV_CODEC_ID_H264: maxpixels /= 256; break; case AV_CODEC_ID_HAP: maxpixels /= 128; break; case AV_CODEC_ID_HEVC: maxpixels /= 16384; break; case AV_CODEC_ID_HNM4_VIDEO: maxpixels /= 128; break; case AV_CODEC_ID_IFF_ILBM: maxpixels /= 128; break; case AV_CODEC_ID_INDEO4: maxpixels /= 128; break; + case AV_CODEC_ID_INTERPLAY_ACM: maxsamples /= 16384; break; + case AV_CODEC_ID_LAGARITH: maxpixels /= 1024; break; case AV_CODEC_ID_LSCR: maxpixels /= 16; break; case AV_CODEC_ID_MOTIONPIXELS:maxpixels /= 256; break; case AV_CODEC_ID_MP4ALS: maxsamples /= 65536; break; + case AV_CODEC_ID_MSA1: maxpixels /= 16384; break; case AV_CODEC_ID_MSRLE: maxpixels /= 16; break; case AV_CODEC_ID_MSS2: maxpixels /= 16384; break; case AV_CODEC_ID_MSZH: maxpixels /= 128; break; + case AV_CODEC_ID_OPUS: maxsamples /= 16384; break; case AV_CODEC_ID_PNG: maxpixels /= 128; break; case AV_CODEC_ID_APNG: maxpixels /= 128; break; case AV_CODEC_ID_QTRLE: maxpixels /= 16; break; @@ -175,12 +189,21 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { case AV_CODEC_ID_SMACKVIDEO: maxpixels /= 64; break; case AV_CODEC_ID_SNOW: maxpixels /= 128; break; case AV_CODEC_ID_TGV: maxpixels /= 32; break; + case AV_CODEC_ID_THEORA: maxpixels /= 1024; break; case AV_CODEC_ID_TRUEMOTION2: maxpixels /= 1024; break; + case AV_CODEC_ID_VC1IMAGE: maxpixels /= 8192; break; + case AV_CODEC_ID_VMNC: maxpixels /= 8192; break; case AV_CODEC_ID_VP7: maxpixels /= 256; break; case AV_CODEC_ID_VP9: maxpixels /= 4096; break; + case AV_CODEC_ID_WAVPACK: maxsamples /= 1024; break; + case AV_CODEC_ID_WMV3IMAGE: maxpixels /= 8192; break; + case AV_CODEC_ID_WS_VQA: maxpixels /= 16384; break; + case AV_CODEC_ID_WMALOSSLESS: maxsamples /= 1024; break; case AV_CODEC_ID_ZEROCODEC: maxpixels /= 128; break; } + maxsamples_per_frame = FFMIN(maxsamples_per_frame, maxsamples); + maxpixels_per_frame = FFMIN(maxpixels_per_frame , maxpixels); AVCodecContext* ctx = avcodec_alloc_context3(c); AVCodecContext* parser_avctx = avcodec_alloc_context3(NULL); @@ -189,7 +212,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (ctx->max_pixels == 0 || ctx->max_pixels > maxpixels_per_frame) ctx->max_pixels = maxpixels_per_frame; //To reduce false positive OOM and hangs - ctx->refcounted_frames = 1; //To reduce false positive timeouts and focus testing on the refcounted API ctx->max_samples = maxsamples_per_frame; @@ -235,6 +257,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ctx->request_channel_layout = bytestream2_get_le64(&gbc); ctx->idct_algo = bytestream2_get_byte(&gbc) % 25; + flushpattern = bytestream2_get_le64(&gbc); if (flags & 0x20) { switch (ctx->codec_id) { @@ -273,13 +296,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int got_frame; AVFrame *frame = av_frame_alloc(); - if (!frame) + AVPacket *avpkt = av_packet_alloc(); + AVPacket *parsepkt = av_packet_alloc(); + if (!frame || !avpkt || !parsepkt) error("Failed memory allocation"); // Read very simple container - AVPacket avpkt, parsepkt; - av_init_packet(&avpkt); - av_init_packet(&parsepkt); while (data < end && it < maxiteration) { // Search for the TAG while (data + sizeof(fuzz_tag) < end) { @@ -290,48 +312,65 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (data + sizeof(fuzz_tag) > end) data = end; - res = av_new_packet(&parsepkt, data - last); + res = av_new_packet(parsepkt, data - last); if (res < 0) error("Failed memory allocation"); - memcpy(parsepkt.data, last, data - last); - parsepkt.flags = (keyframes & 1) * AV_PKT_FLAG_DISCARD + (!!(keyframes & 2)) * AV_PKT_FLAG_KEY; + memcpy(parsepkt->data, last, data - last); + parsepkt->flags = (keyframes & 1) * AV_PKT_FLAG_DISCARD + (!!(keyframes & 2)) * AV_PKT_FLAG_KEY; keyframes = (keyframes >> 2) + (keyframes<<62); data += sizeof(fuzz_tag); last = data; - while (parsepkt.size > 0) { + while (parsepkt->size > 0) { + int decode_more; if (parser) { - av_init_packet(&avpkt); - int ret = av_parser_parse2(parser, parser_avctx, &avpkt.data, &avpkt.size, - parsepkt.data, parsepkt.size, - parsepkt.pts, parsepkt.dts, parsepkt.pos); - if (avpkt.data == parsepkt.data) { - avpkt.buf = av_buffer_ref(parsepkt.buf); - if (!avpkt.buf) + int ret = av_parser_parse2(parser, parser_avctx, &avpkt->data, &avpkt->size, + parsepkt->data, parsepkt->size, + parsepkt->pts, parsepkt->dts, parsepkt->pos); + if (avpkt->data == parsepkt->data) { + avpkt->buf = av_buffer_ref(parsepkt->buf); + if (!avpkt->buf) error("Failed memory allocation"); } else { - if (av_packet_make_refcounted(&avpkt) < 0) + if (av_packet_make_refcounted(avpkt) < 0) error("Failed memory allocation"); } - parsepkt.data += ret; - parsepkt.size -= ret; - parsepkt.pos += ret; - avpkt.pts = parser->pts; - avpkt.dts = parser->dts; - avpkt.pos = parser->pos; + parsepkt->data += ret; + parsepkt->size -= ret; + parsepkt->pos += ret; + avpkt->pts = parser->pts; + avpkt->dts = parser->dts; + avpkt->pos = parser->pos; if ( parser->key_frame == 1 || (parser->key_frame == -1 && parser->pict_type == AV_PICTURE_TYPE_I)) - avpkt.flags |= AV_PKT_FLAG_KEY; - avpkt.flags |= parsepkt.flags & AV_PKT_FLAG_DISCARD; + avpkt->flags |= AV_PKT_FLAG_KEY; + avpkt->flags |= parsepkt->flags & AV_PKT_FLAG_DISCARD; } else { - av_packet_move_ref(&avpkt, &parsepkt); + av_packet_move_ref(avpkt, parsepkt); } + if (!(flushpattern & 7)) + avcodec_flush_buffers(ctx); + flushpattern = (flushpattern >> 3) + (flushpattern << 61); + + if (ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { + int ret = avcodec_send_packet(ctx, avpkt); + decode_more = ret >= 0; + if(!decode_more) { + ec_pixels += (ctx->width + 32LL) * (ctx->height + 32LL); + if (it > 20 || ec_pixels > 4 * ctx->max_pixels) + ctx->error_concealment = 0; + if (ec_pixels > maxpixels) + goto maximums_reached; + } + } else + decode_more = 1; + // Iterate through all data - while (avpkt.size > 0 && it++ < maxiteration) { + while (decode_more && it++ < maxiteration) { av_frame_unref(frame); - int ret = decode_handler(ctx, frame, &got_frame, &avpkt); + int ret = decode_handler(ctx, frame, &got_frame, avpkt); ec_pixels += (ctx->width + 32LL) * (ctx->height + 32LL); if (it > 20 || ec_pixels > 4 * ctx->max_pixels) @@ -339,29 +378,40 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (ec_pixels > maxpixels) goto maximums_reached; + if (ctx->codec_type == AVMEDIA_TYPE_AUDIO && + frame->nb_samples == 0 && !got_frame && + (avpkt->flags & AV_PKT_FLAG_DISCARD)) + nb_samples += ctx->max_samples; + nb_samples += frame->nb_samples; if (nb_samples > maxsamples) goto maximums_reached; - if (ret <= 0 || ret > avpkt.size) + if (ret <= 0 || ret > avpkt->size) break; - if (ctx->codec_type != AVMEDIA_TYPE_AUDIO) - ret = avpkt.size; - avpkt.data += ret; - avpkt.size -= ret; + + if (ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) { + avpkt->data += ret; + avpkt->size -= ret; + decode_more = avpkt->size > 0; + } else + decode_more = ret >= 0; } - av_packet_unref(&avpkt); + av_packet_unref(avpkt); } - av_packet_unref(&parsepkt); + av_packet_unref(parsepkt); } maximums_reached: - av_packet_unref(&avpkt); + av_packet_unref(avpkt); + + if (ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) + avcodec_send_packet(ctx, NULL); do { got_frame = 0; av_frame_unref(frame); - decode_handler(ctx, frame, &got_frame, &avpkt); + decode_handler(ctx, frame, &got_frame, avpkt); } while (got_frame == 1 && it++ < maxiteration); fprintf(stderr, "pixels decoded: %"PRId64", samples decoded: %"PRId64", iterations: %d\n", ec_pixels, nb_samples, it); @@ -370,7 +420,8 @@ maximums_reached: avcodec_free_context(&ctx); avcodec_free_context(&parser_avctx); av_parser_close(parser); - av_packet_unref(&parsepkt); + av_packet_free(&avpkt); + av_packet_free(&parsepkt); av_dict_free(&opts); return 0; } diff --git a/tools/target_dem_fuzzer.c b/tools/target_dem_fuzzer.c index cc097da0d..3c03c8d17 100644 --- a/tools/target_dem_fuzzer.c +++ b/tools/target_dem_fuzzer.c @@ -18,6 +18,7 @@ #include "config.h" #include "libavutil/avassert.h" +#include "libavutil/avstring.h" #include "libavcodec/avcodec.h" #include "libavcodec/bytestream.h" @@ -48,6 +49,8 @@ static int io_read(void *opaque, uint8_t *buf, int buf_size) c->filesize = FFMIN(c->pos, c->filesize); return AVERROR_EOF; } + if (c->pos > INT64_MAX - size) + return AVERROR(EIO); memcpy(buf, c->fuzz, size); c->fuzz += size; @@ -75,12 +78,17 @@ static int64_t io_seek(void *opaque, int64_t offset, int whence) } if (offset < 0 || offset > c->filesize) return -1; + if (IO_FLAT) { + c->fuzz += offset - c->pos; + c->fuzz_size -= offset - c->pos; + } c->pos = offset; return 0; } // Ensure we don't loop forever const uint32_t maxiteration = 8096; +const int maxblocks= 50000; static const uint64_t FUZZ_TAG = 0x4741542D5A5A5546ULL; @@ -88,7 +96,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { const uint64_t fuzz_tag = FUZZ_TAG; uint32_t it = 0; AVFormatContext *avfmt = avformat_alloc_context(); - AVPacket pkt; + AVPacket *pkt; char filename[1025] = {0}; AVIOContext *fuzzed_pb = NULL; uint8_t *io_buffer; @@ -98,10 +106,15 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { static int c; int seekable = 0; int ret; + AVInputFormat *fmt = NULL; +#ifdef FFMPEG_DEMUXER +#define DEMUXER_SYMBOL0(DEMUXER) ff_##DEMUXER##_demuxer +#define DEMUXER_SYMBOL(DEMUXER) DEMUXER_SYMBOL0(DEMUXER) + extern AVInputFormat DEMUXER_SYMBOL(FFMPEG_DEMUXER); + fmt = &DEMUXER_SYMBOL(FFMPEG_DEMUXER); +#endif if (!c) { - av_register_all(); - avcodec_register_all(); av_log_set_level(AV_LOG_PANIC); c=1; } @@ -109,16 +122,53 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (!avfmt) error("Failed avformat_alloc_context()"); - if (size > 2048) { + if (IO_FLAT) { + seekable = 1; + io_buffer_size = size; + } else if (size > 2048) { + int flags; + char extension[64]; + GetByteContext gbc; memcpy (filename, data + size - 1024, 1024); bytestream2_init(&gbc, data + size - 2048, 1024); size -= 2048; io_buffer_size = bytestream2_get_le32(&gbc) & 0xFFFFFFF; - seekable = bytestream2_get_byte(&gbc) & 1; + flags = bytestream2_get_byte(&gbc); + seekable = flags & 1; filesize = bytestream2_get_le64(&gbc) & 0x7FFFFFFFFFFFFFFF; + + if ((flags & 2) && strlen(filename) < sizeof(filename) / 2) { + const AVInputFormat *avif = NULL; + void *avif_iter = NULL; + int avif_count = 0; + while ((avif = av_demuxer_iterate(&avif_iter))) { + if (avif->extensions) + avif_count ++; + } + avif_count = bytestream2_get_le32(&gbc) % avif_count; + + avif_iter = NULL; + while ((avif = av_demuxer_iterate(&avif_iter))) { + if (avif->extensions) + if (!avif_count--) + break; + } + av_strlcpy(extension, avif->extensions, sizeof(extension)); + if (strchr(extension, ',')) + *strchr(extension, ',') = 0; + av_strlcatf(filename, sizeof(filename), ".%s", extension); + } } + + if (!io_buffer_size || size / io_buffer_size > maxblocks) + io_buffer_size = size; + + pkt = av_packet_alloc(); + if (!pkt) + error("Failed to allocate pkt"); + io_buffer = av_malloc(io_buffer_size); if (!io_buffer) error("Failed to allocate io_buffer"); @@ -134,30 +184,28 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { avfmt->pb = fuzzed_pb; - ret = avformat_open_input(&avfmt, filename, NULL, NULL); + ret = avformat_open_input(&avfmt, filename, fmt, NULL); if (ret < 0) { - av_freep(&fuzzed_pb->buffer); - av_freep(&fuzzed_pb); - avformat_free_context(avfmt); - return 0; + goto fail; } ret = avformat_find_stream_info(avfmt, NULL); - av_init_packet(&pkt); - //TODO, test seeking for(it = 0; it < maxiteration; it++) { - ret = av_read_frame(avfmt, &pkt); + ret = av_read_frame(avfmt, pkt); if (ret < 0) break; - av_packet_unref(&pkt); + av_packet_unref(pkt); } -end: + +fail: + av_packet_free(&pkt); av_freep(&fuzzed_pb->buffer); - av_freep(&fuzzed_pb); + avio_context_free(&fuzzed_pb); avformat_close_input(&avfmt); return 0; + }